laya.html.js 55 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544
  1. (function (exports, Laya) {
  2. 'use strict';
  3. class HTMLExtendStyle {
  4. constructor() {
  5. this.reset();
  6. }
  7. reset() {
  8. this.stroke = 0;
  9. this.strokeColor = "#000000";
  10. this.leading = 0;
  11. this.lineHeight = 0;
  12. this.letterSpacing = 0;
  13. this.href = null;
  14. return this;
  15. }
  16. recover() {
  17. if (this == HTMLExtendStyle.EMPTY)
  18. return;
  19. Laya.Pool.recover("HTMLExtendStyle", this.reset());
  20. }
  21. static create() {
  22. return Laya.Pool.getItemByClass("HTMLExtendStyle", HTMLExtendStyle);
  23. }
  24. }
  25. HTMLExtendStyle.EMPTY = new HTMLExtendStyle();
  26. Laya.ClassUtils.regClass("laya.html.utils.HTMLExtendStyle", HTMLExtendStyle);
  27. Laya.ClassUtils.regClass("Laya.HTMLExtendStyle", HTMLExtendStyle);
  28. class HTMLStyle {
  29. constructor() {
  30. this.padding = HTMLStyle._PADDING;
  31. this.reset();
  32. }
  33. _getExtendStyle() {
  34. if (this._extendStyle === HTMLExtendStyle.EMPTY)
  35. this._extendStyle = HTMLExtendStyle.create();
  36. return this._extendStyle;
  37. }
  38. get href() {
  39. return this._extendStyle.href;
  40. }
  41. set href(value) {
  42. if (value === this._extendStyle.href)
  43. return;
  44. this._getExtendStyle().href = value;
  45. }
  46. get stroke() {
  47. return this._extendStyle.stroke;
  48. }
  49. set stroke(value) {
  50. if (this._extendStyle.stroke === value)
  51. return;
  52. this._getExtendStyle().stroke = value;
  53. }
  54. get strokeColor() {
  55. return this._extendStyle.strokeColor;
  56. }
  57. set strokeColor(value) {
  58. if (this._extendStyle.strokeColor === value)
  59. return;
  60. this._getExtendStyle().strokeColor = value;
  61. }
  62. get leading() {
  63. return this._extendStyle.leading;
  64. }
  65. set leading(value) {
  66. if (this._extendStyle.leading === value)
  67. return;
  68. this._getExtendStyle().leading = value;
  69. }
  70. get lineHeight() {
  71. return this._extendStyle.lineHeight;
  72. }
  73. set lineHeight(value) {
  74. if (this._extendStyle.lineHeight === value)
  75. return;
  76. this._getExtendStyle().lineHeight = value;
  77. }
  78. set align(v) {
  79. if (!(v in HTMLStyle.alignVDic))
  80. return;
  81. this._type &= (~HTMLStyle._ALIGN);
  82. this._type |= HTMLStyle.alignVDic[v];
  83. }
  84. get align() {
  85. var v = this._type & HTMLStyle._ALIGN;
  86. return HTMLStyle.align_Value[v];
  87. }
  88. set valign(v) {
  89. if (!(v in HTMLStyle.alignVDic))
  90. return;
  91. this._type &= (~HTMLStyle._VALIGN);
  92. this._type |= HTMLStyle.alignVDic[v];
  93. }
  94. get valign() {
  95. var v = this._type & HTMLStyle._VALIGN;
  96. return HTMLStyle.vAlign_Value[v];
  97. }
  98. set font(value) {
  99. var strs = value.split(' ');
  100. for (var i = 0, n = strs.length; i < n; i++) {
  101. var str = strs[i];
  102. switch (str) {
  103. case 'italic':
  104. this.italic = true;
  105. continue;
  106. case 'bold':
  107. this.bold = true;
  108. continue;
  109. }
  110. if (str.indexOf('px') > 0) {
  111. this.fontSize = parseInt(str);
  112. this.family = strs[i + 1];
  113. i++;
  114. continue;
  115. }
  116. }
  117. }
  118. get font() {
  119. return (this.italic ? "italic " : "") + (this.bold ? "bold " : "") + this.fontSize + "px " + (Laya.ILaya.Browser.onIPhone ? (Laya.ILaya.Text.fontFamilyMap[this.family] || this.family) : this.family);
  120. }
  121. set block(value) {
  122. value ? (this._type |= HTMLStyle._CSS_BLOCK) : (this._type &= (~HTMLStyle._CSS_BLOCK));
  123. }
  124. get block() {
  125. return (this._type & HTMLStyle._CSS_BLOCK) != 0;
  126. }
  127. reset() {
  128. this.ower = null;
  129. this._type = 0;
  130. this.wordWrap = true;
  131. this.fontSize = Laya.ILaya.Text.defaultFontSize;
  132. this.family = Laya.ILaya.Text.defaultFont;
  133. this.color = "#000000";
  134. this.valign = HTMLStyle.VALIGN_TOP;
  135. this.padding = HTMLStyle._PADDING;
  136. this.bold = false;
  137. this.italic = false;
  138. this.align = HTMLStyle.ALIGN_LEFT;
  139. this.textDecoration = null;
  140. this.bgColor = null;
  141. this.borderColor = null;
  142. if (this._extendStyle)
  143. this._extendStyle.recover();
  144. this._extendStyle = HTMLExtendStyle.EMPTY;
  145. return this;
  146. }
  147. recover() {
  148. Laya.Pool.recover("HTMLStyle", this.reset());
  149. }
  150. static create() {
  151. return Laya.Pool.getItemByClass("HTMLStyle", HTMLStyle);
  152. }
  153. inherit(src) {
  154. var i, len;
  155. var props;
  156. props = HTMLStyle._inheritProps;
  157. len = props.length;
  158. var key;
  159. for (i = 0; i < len; i++) {
  160. key = props[i];
  161. this[key] = src[key];
  162. }
  163. }
  164. get wordWrap() {
  165. return (this._type & HTMLStyle._NOWARP) === 0;
  166. }
  167. set wordWrap(value) {
  168. value ? (this._type &= ~HTMLStyle._NOWARP) : (this._type |= HTMLStyle._NOWARP);
  169. }
  170. get bold() {
  171. return (this._type & HTMLStyle._BOLD) != 0;
  172. }
  173. set bold(value) {
  174. value ? (this._type |= HTMLStyle._BOLD) : (this._type &= ~HTMLStyle._BOLD);
  175. }
  176. get italic() {
  177. return (this._type & HTMLStyle._ITALIC) != 0;
  178. }
  179. set italic(value) {
  180. value ? (this._type |= HTMLStyle._ITALIC) : (this._type &= ~HTMLStyle._ITALIC);
  181. }
  182. _widthAuto() {
  183. return (this._type & HTMLStyle._WIDTHAUTO) !== 0;
  184. }
  185. widthed(sprite) {
  186. return (this._type & HTMLStyle._WIDTH_SET) != 0;
  187. }
  188. set whiteSpace(type) {
  189. type === "nowrap" && (this._type |= HTMLStyle._NOWARP);
  190. type === "none" && (this._type &= ~HTMLStyle._NOWARP);
  191. }
  192. get whiteSpace() {
  193. return (this._type & HTMLStyle._NOWARP) ? "nowrap" : "";
  194. }
  195. _calculation(type, value) {
  196. return false;
  197. }
  198. set width(w) {
  199. this._type |= HTMLStyle._WIDTH_SET;
  200. if (typeof (w) == 'string') {
  201. var offset = w.indexOf('auto');
  202. if (offset >= 0) {
  203. this._type |= HTMLStyle._WIDTHAUTO;
  204. w = w.substr(0, offset);
  205. }
  206. if (this._calculation("width", w))
  207. return;
  208. w = parseInt(w);
  209. }
  210. this.size(w, -1);
  211. }
  212. set height(h) {
  213. this._type |= HTMLStyle._HEIGHT_SET;
  214. if (typeof (h) == 'string') {
  215. if (this._calculation("height", h))
  216. return;
  217. h = parseInt(h);
  218. }
  219. this.size(-1, h);
  220. }
  221. heighted(sprite) {
  222. return (this._type & HTMLStyle._HEIGHT_SET) != 0;
  223. }
  224. size(w, h) {
  225. var ower = this.ower;
  226. var resize = false;
  227. if (w !== -1 && w != ower.width) {
  228. this._type |= HTMLStyle._WIDTH_SET;
  229. ower.width = w;
  230. resize = true;
  231. }
  232. if (h !== -1 && h != ower.height) {
  233. this._type |= HTMLStyle._HEIGHT_SET;
  234. ower.height = h;
  235. resize = true;
  236. }
  237. if (resize) {
  238. ower._layoutLater();
  239. }
  240. }
  241. getLineElement() {
  242. return (this._type & HTMLStyle._LINE_ELEMENT) != 0;
  243. }
  244. setLineElement(value) {
  245. value ? (this._type |= HTMLStyle._LINE_ELEMENT) : (this._type &= (~HTMLStyle._LINE_ELEMENT));
  246. }
  247. _enableLayout() {
  248. return (this._type & HTMLStyle._DISPLAY_NONE) === 0 && (this._type & HTMLStyle._ABSOLUTE) === 0;
  249. }
  250. get letterSpacing() {
  251. return this._extendStyle.letterSpacing;
  252. }
  253. set letterSpacing(d) {
  254. (typeof (d) == 'string') && (d = parseInt(d + ""));
  255. if (d == this._extendStyle.letterSpacing)
  256. return;
  257. this._getExtendStyle().letterSpacing = d;
  258. }
  259. cssText(text) {
  260. this.attrs(HTMLStyle.parseOneCSS(text, ';'));
  261. }
  262. attrs(attrs) {
  263. if (attrs) {
  264. for (var i = 0, n = attrs.length; i < n; i++) {
  265. var attr = attrs[i];
  266. this[attr[0]] = attr[1];
  267. }
  268. }
  269. }
  270. set position(value) {
  271. value === "absolute" ? (this._type |= HTMLStyle._ABSOLUTE) : (this._type &= ~HTMLStyle._ABSOLUTE);
  272. }
  273. get position() {
  274. return (this._type & HTMLStyle._ABSOLUTE) ? "absolute" : "";
  275. }
  276. get absolute() {
  277. return (this._type & HTMLStyle._ABSOLUTE) !== 0;
  278. }
  279. get paddingLeft() {
  280. return this.padding[3];
  281. }
  282. get paddingTop() {
  283. return this.padding[0];
  284. }
  285. static parseOneCSS(text, clipWord) {
  286. var out = [];
  287. var attrs = text.split(clipWord);
  288. var valueArray;
  289. for (var i = 0, n = attrs.length; i < n; i++) {
  290. var attr = attrs[i];
  291. var ofs = attr.indexOf(':');
  292. var name = attr.substr(0, ofs).replace(/^\s+|\s+$/g, '');
  293. if (name.length === 0)
  294. continue;
  295. var value = attr.substr(ofs + 1).replace(/^\s+|\s+$/g, '');
  296. var one = [name, value];
  297. switch (name) {
  298. case 'italic':
  299. case 'bold':
  300. one[1] = value == "true";
  301. break;
  302. case "font-weight":
  303. if (value == "bold") {
  304. one[1] = true;
  305. one[0] = "bold";
  306. }
  307. break;
  308. case 'line-height':
  309. one[0] = 'lineHeight';
  310. one[1] = parseInt(value);
  311. break;
  312. case 'font-size':
  313. one[0] = 'fontSize';
  314. one[1] = parseInt(value);
  315. break;
  316. case 'stroke':
  317. one[0] = 'stroke';
  318. one[1] = parseInt(value);
  319. break;
  320. case 'padding':
  321. valueArray = value.split(' ');
  322. valueArray.length > 1 || (valueArray[1] = valueArray[2] = valueArray[3] = valueArray[0]);
  323. one[1] = [parseInt(valueArray[0]), parseInt(valueArray[1]), parseInt(valueArray[2]), parseInt(valueArray[3])];
  324. break;
  325. default:
  326. (one[0] = HTMLStyle._CSSTOVALUE[name]) || (one[0] = name);
  327. }
  328. out.push(one);
  329. }
  330. return out;
  331. }
  332. static parseCSS(text, uri) {
  333. var one;
  334. while ((one = HTMLStyle._parseCSSRegExp.exec(text)) != null) {
  335. HTMLStyle.styleSheets[one[1]] = HTMLStyle.parseOneCSS(one[2], ';');
  336. }
  337. }
  338. }
  339. HTMLStyle._CSSTOVALUE = { 'letter-spacing': 'letterSpacing', 'white-space': 'whiteSpace', 'line-height': 'lineHeight', 'font-family': 'family', 'vertical-align': 'valign', 'text-decoration': 'textDecoration', 'background-color': 'bgColor', 'border-color': 'borderColor' };
  340. HTMLStyle._parseCSSRegExp = new RegExp("([\.\#]\\w+)\\s*{([\\s\\S]*?)}", "g");
  341. HTMLStyle._inheritProps = ["italic", "align", "valign", "leading", "stroke", "strokeColor", "bold", "fontSize", "lineHeight", "wordWrap", "color"];
  342. HTMLStyle.ALIGN_LEFT = "left";
  343. HTMLStyle.ALIGN_CENTER = "center";
  344. HTMLStyle.ALIGN_RIGHT = "right";
  345. HTMLStyle.VALIGN_TOP = "top";
  346. HTMLStyle.VALIGN_MIDDLE = "middle";
  347. HTMLStyle.VALIGN_BOTTOM = "bottom";
  348. HTMLStyle.styleSheets = {};
  349. HTMLStyle.ADDLAYOUTED = 0x200;
  350. HTMLStyle._PADDING = [0, 0, 0, 0];
  351. HTMLStyle._HEIGHT_SET = 0x2000;
  352. HTMLStyle._LINE_ELEMENT = 0x10000;
  353. HTMLStyle._NOWARP = 0x20000;
  354. HTMLStyle._WIDTHAUTO = 0x40000;
  355. HTMLStyle._BOLD = 0x400;
  356. HTMLStyle._ITALIC = 0x800;
  357. HTMLStyle._CSS_BLOCK = 0x1;
  358. HTMLStyle._DISPLAY_NONE = 0x2;
  359. HTMLStyle._ABSOLUTE = 0x4;
  360. HTMLStyle._WIDTH_SET = 0x8;
  361. HTMLStyle.alignVDic = { "left": 0, "center": 0x10, "right": 0x20, "top": 0, "middle": 0x40, "bottom": 0x80 };
  362. HTMLStyle.align_Value = { 0: "left", 0x10: "center", 0x20: "right" };
  363. HTMLStyle.vAlign_Value = { 0: "top", 0x40: "middle", 0x80: "bottom" };
  364. HTMLStyle._ALIGN = 0x30;
  365. HTMLStyle._VALIGN = 0xc0;
  366. Laya.ClassUtils.regClass("laya.html.utils.HTMLStyle", HTMLStyle);
  367. Laya.ClassUtils.regClass("Laya.HTMLStyle", HTMLStyle);
  368. class HTMLDocument {
  369. constructor() {
  370. this.all = [];
  371. this.styleSheets = HTMLStyle.styleSheets;
  372. }
  373. getElementById(id) {
  374. return this.all[id];
  375. }
  376. setElementById(id, e) {
  377. this.all[id] = e;
  378. }
  379. }
  380. HTMLDocument.document = new HTMLDocument();
  381. Laya.ClassUtils.regClass("laya.html.dom.HTMLDocument", HTMLDocument);
  382. Laya.ClassUtils.regClass("Laya.HTMLDocument", HTMLDocument);
  383. class HTMLHitRect {
  384. constructor() {
  385. this.rec = new Laya.Rectangle();
  386. this.reset();
  387. }
  388. reset() {
  389. this.rec.reset();
  390. this.href = null;
  391. return this;
  392. }
  393. recover() {
  394. Laya.Pool.recover("HTMLHitRect", this.reset());
  395. }
  396. static create() {
  397. return Laya.Pool.getItemByClass("HTMLHitRect", HTMLHitRect);
  398. }
  399. }
  400. Laya.ClassUtils.regClass("laya.html.dom.HTMLHitRect", HTMLHitRect);
  401. Laya.ClassUtils.regClass("Laya.HTMLHitRect", HTMLHitRect);
  402. class IHtml {
  403. }
  404. IHtml.HTMLDivElement = null;
  405. IHtml.HTMLImageElement = null;
  406. IHtml.HTMLBrElement = null;
  407. IHtml.HTMLDivParser = null;
  408. IHtml.HTMLParse = null;
  409. IHtml.HTMLElementType = null;
  410. class LayoutLine {
  411. constructor() {
  412. this.elements = [];
  413. this.x = 0;
  414. this.y = 0;
  415. this.w = 0;
  416. this.h = 0;
  417. this.wordStartIndex = 0;
  418. this.minTextHeight = 99999;
  419. this.mWidth = 0;
  420. }
  421. updatePos(left, width, lineNum, dy, align, valign, lineHeight) {
  422. var w = 0;
  423. var one;
  424. if (this.elements.length > 0) {
  425. one = this.elements[this.elements.length - 1];
  426. w = one.x + one.width - this.elements[0].x;
  427. }
  428. lineHeight = lineHeight || this.h;
  429. var dx = 0, ddy;
  430. if (align === HTMLStyle.ALIGN_CENTER)
  431. dx = (width - w) / 2;
  432. if (align === HTMLStyle.ALIGN_RIGHT)
  433. dx = (width - w);
  434. for (var i = 0, n = this.elements.length; i < n; i++) {
  435. one = this.elements[i];
  436. var tCSSStyle = one._getCSSStyle();
  437. dx !== 0 && (one.x += dx);
  438. switch (tCSSStyle.valign) {
  439. case "top":
  440. one.y = dy;
  441. break;
  442. case "middle":
  443. var tMinTextHeight = 0;
  444. if (this.minTextHeight != 99999)
  445. tMinTextHeight = this.minTextHeight;
  446. var tBottomLineY = (tMinTextHeight + lineHeight) / 2;
  447. tBottomLineY = Math.max(tBottomLineY, this.h);
  448. if (one.eletype == IHtml.HTMLElementType.IMAGE)
  449. ddy = dy + tBottomLineY - one.height;
  450. else
  451. ddy = dy + tBottomLineY - one.height;
  452. one.y = ddy;
  453. break;
  454. case "bottom":
  455. one.y = dy + (lineHeight - one.height);
  456. break;
  457. }
  458. }
  459. }
  460. }
  461. Laya.ClassUtils.regClass("laya.html.utils.LayoutLine", LayoutLine);
  462. Laya.ClassUtils.regClass("Laya.LayoutLine", LayoutLine);
  463. class Layout {
  464. static later(element) {
  465. if (Layout._will == null) {
  466. Layout._will = [];
  467. Laya.ILaya.stage.frameLoop(1, null, function () {
  468. if (Layout._will.length < 1)
  469. return;
  470. for (var i = 0; i < Layout._will.length; i++) {
  471. Layout.layout(Layout._will[i]);
  472. }
  473. Layout._will.length = 0;
  474. });
  475. }
  476. Layout._will.push(element);
  477. }
  478. static layout(element) {
  479. if (!element || !element._style)
  480. return null;
  481. var style = element._style;
  482. if ((style._type & HTMLStyle.ADDLAYOUTED) === 0)
  483. return null;
  484. element.style._type &= ~HTMLStyle.ADDLAYOUTED;
  485. var arr = Layout._multiLineLayout(element);
  486. return arr;
  487. }
  488. static _multiLineLayout(element) {
  489. var elements = [];
  490. element._addChildsToLayout(elements);
  491. var i, n = elements.length;
  492. var style = element._getCSSStyle();
  493. var letterSpacing = style.letterSpacing;
  494. var leading = style.leading;
  495. var lineHeight = style.lineHeight;
  496. var widthAuto = style._widthAuto() || !style.wordWrap;
  497. var width = widthAuto ? 999999 : element.width;
  498. var height = element.height;
  499. var maxWidth = 0;
  500. var exWidth = style.italic ? style.fontSize / 3 : 0;
  501. var align = style.align;
  502. var valign = style.valign;
  503. var endAdjust = valign !== HTMLStyle.VALIGN_TOP || align !== HTMLStyle.ALIGN_LEFT || lineHeight != 0;
  504. var oneLayout;
  505. var x = 0;
  506. var y = 0;
  507. var w = 0;
  508. var h = 0;
  509. var lines = [];
  510. var curStyle;
  511. var curPadding;
  512. var curLine = lines[0] = new LayoutLine();
  513. var newLine, nextNewline = false;
  514. var htmlWord;
  515. var sprite;
  516. curLine.h = 0;
  517. if (style.italic)
  518. width -= style.fontSize / 3;
  519. var tWordWidth = 0;
  520. var tLineFirstKey = true;
  521. function addLine() {
  522. curLine.y = y;
  523. y += curLine.h + leading;
  524. curLine.mWidth = tWordWidth;
  525. tWordWidth = 0;
  526. curLine = new LayoutLine();
  527. lines.push(curLine);
  528. curLine.h = 0;
  529. x = 0;
  530. tLineFirstKey = true;
  531. newLine = false;
  532. }
  533. for (i = 0; i < n; i++) {
  534. oneLayout = elements[i];
  535. if (oneLayout == null) {
  536. if (!tLineFirstKey) {
  537. x += Layout.DIV_ELEMENT_PADDING;
  538. }
  539. curLine.wordStartIndex = curLine.elements.length;
  540. continue;
  541. }
  542. tLineFirstKey = false;
  543. if (oneLayout instanceof IHtml.HTMLBrElement) {
  544. addLine();
  545. curLine.y = y;
  546. curLine.h = lineHeight;
  547. continue;
  548. }
  549. else if (oneLayout._isChar()) {
  550. htmlWord = oneLayout;
  551. if (!htmlWord.isWord) {
  552. if (lines.length > 0 && (x + w) > width && curLine.wordStartIndex > 0) {
  553. var tLineWord = 0;
  554. tLineWord = curLine.elements.length - curLine.wordStartIndex + 1;
  555. curLine.elements.length = curLine.wordStartIndex;
  556. i -= tLineWord;
  557. addLine();
  558. continue;
  559. }
  560. newLine = false;
  561. tWordWidth += htmlWord.width;
  562. }
  563. else {
  564. newLine = nextNewline || (htmlWord.char === '\n');
  565. curLine.wordStartIndex = curLine.elements.length;
  566. }
  567. w = htmlWord.width + htmlWord.style.letterSpacing;
  568. h = htmlWord.height;
  569. nextNewline = false;
  570. newLine = newLine || ((x + w) > width);
  571. newLine && addLine();
  572. curLine.minTextHeight = Math.min(curLine.minTextHeight, oneLayout.height);
  573. }
  574. else {
  575. curStyle = oneLayout._getCSSStyle();
  576. sprite = oneLayout;
  577. curPadding = curStyle.padding;
  578. newLine = nextNewline || curStyle.getLineElement();
  579. w = sprite.width + curPadding[1] + curPadding[3] + curStyle.letterSpacing;
  580. h = sprite.height + curPadding[0] + curPadding[2];
  581. nextNewline = curStyle.getLineElement();
  582. newLine = newLine || ((x + w) > width && curStyle.wordWrap);
  583. newLine && addLine();
  584. }
  585. curLine.elements.push(oneLayout);
  586. curLine.h = Math.max(curLine.h, h);
  587. oneLayout.x = x;
  588. oneLayout.y = y;
  589. x += w;
  590. curLine.w = x - letterSpacing;
  591. curLine.y = y;
  592. maxWidth = Math.max(x + exWidth, maxWidth);
  593. }
  594. y = curLine.y + curLine.h;
  595. if (endAdjust) {
  596. var tY = 0;
  597. var tWidth = width;
  598. if (widthAuto && element.width > 0) {
  599. tWidth = element.width;
  600. }
  601. for (i = 0, n = lines.length; i < n; i++) {
  602. lines[i].updatePos(0, tWidth, i, tY, align, valign, lineHeight);
  603. tY += Math.max(lineHeight, lines[i].h + leading);
  604. }
  605. y = tY;
  606. }
  607. widthAuto && (element.width = maxWidth);
  608. (y > element.height) && (element.height = y);
  609. return [maxWidth, y];
  610. }
  611. }
  612. Layout.DIV_ELEMENT_PADDING = 0;
  613. Laya.ClassUtils.regClass("laya.html.utils.Layout", Layout);
  614. Laya.ClassUtils.regClass("Laya.Layout", Layout);
  615. (function (HTMLElementType) {
  616. HTMLElementType[HTMLElementType["BASE"] = 0] = "BASE";
  617. HTMLElementType[HTMLElementType["IMAGE"] = 1] = "IMAGE";
  618. })(exports.HTMLElementType || (exports.HTMLElementType = {}));
  619. class HTMLElement {
  620. constructor() {
  621. this.eletype = exports.HTMLElementType.BASE;
  622. this._creates();
  623. this.reset();
  624. }
  625. static formatURL1(url, basePath = null) {
  626. if (!url)
  627. return "null path";
  628. if (!basePath)
  629. basePath = Laya.URL.basePath;
  630. if (url.indexOf(":") > 0)
  631. return url;
  632. if (Laya.URL.customFormat != null)
  633. url = Laya.URL.customFormat(url);
  634. if (url.indexOf(":") > 0)
  635. return url;
  636. var char1 = url.charAt(0);
  637. if (char1 === ".") {
  638. return Laya.URL._formatRelativePath(basePath + url);
  639. }
  640. else if (char1 === '~') {
  641. return Laya.URL.rootPath + url.substring(1);
  642. }
  643. else if (char1 === "d") {
  644. if (url.indexOf("data:image") === 0)
  645. return url;
  646. }
  647. else if (char1 === "/") {
  648. return url;
  649. }
  650. return basePath + url;
  651. }
  652. _creates() {
  653. this._style = HTMLStyle.create();
  654. }
  655. reset() {
  656. this.URI = null;
  657. this.parent = null;
  658. this._style.reset();
  659. this._style.ower = this;
  660. this._style.valign = "middle";
  661. if (this._text && this._text.words) {
  662. var words = this._text.words;
  663. var i, len;
  664. len = words.length;
  665. var tChar;
  666. for (i = 0; i < len; i++) {
  667. tChar = words[i];
  668. if (tChar)
  669. tChar.recover();
  670. }
  671. }
  672. this._text = HTMLElement._EMPTYTEXT;
  673. if (this._children)
  674. this._children.length = 0;
  675. this._x = this._y = this._width = this._height = 0;
  676. return this;
  677. }
  678. _getCSSStyle() {
  679. return this._style;
  680. }
  681. _addChildsToLayout(out) {
  682. var words = this._getWords();
  683. if (words == null && (!this._children || this._children.length == 0))
  684. return false;
  685. if (words) {
  686. for (var i = 0, n = words.length; i < n; i++) {
  687. out.push(words[i]);
  688. }
  689. }
  690. if (this._children)
  691. this._children.forEach(function (o, index, array) {
  692. var _style = o._style;
  693. _style._enableLayout && _style._enableLayout() && o._addToLayout(out);
  694. });
  695. return true;
  696. }
  697. _addToLayout(out) {
  698. if (!this._style)
  699. return;
  700. var style = this._style;
  701. if (style.absolute)
  702. return;
  703. style.block ? out.push(this) : (this._addChildsToLayout(out) && (this.x = this.y = 0));
  704. }
  705. set id(value) {
  706. HTMLDocument.document.setElementById(value, this);
  707. }
  708. repaint(recreate = false) {
  709. this.parentRepaint(recreate);
  710. }
  711. parentRepaint(recreate = false) {
  712. if (this.parent)
  713. this.parent.repaint(recreate);
  714. }
  715. set innerTEXT(value) {
  716. if (this._text === HTMLElement._EMPTYTEXT) {
  717. this._text = { text: value, words: null };
  718. }
  719. else {
  720. this._text.text = value;
  721. this._text.words && (this._text.words.length = 0);
  722. }
  723. this.repaint();
  724. }
  725. get innerTEXT() {
  726. return this._text.text;
  727. }
  728. _setParent(value) {
  729. if (value instanceof HTMLElement) {
  730. var p = value;
  731. this.URI || (this.URI = p.URI);
  732. if (this.style)
  733. this.style.inherit(p.style);
  734. }
  735. }
  736. appendChild(c) {
  737. return this.addChild(c);
  738. }
  739. addChild(c) {
  740. if (c.parent)
  741. c.parent.removeChild(c);
  742. if (!this._children)
  743. this._children = [];
  744. this._children.push(c);
  745. c.parent = this;
  746. c._setParent(this);
  747. this.repaint();
  748. return c;
  749. }
  750. removeChild(c) {
  751. if (!this._children)
  752. return null;
  753. var i, len;
  754. len = this._children.length;
  755. for (i = 0; i < len; i++) {
  756. if (this._children[i] == c) {
  757. this._children.splice(i, 1);
  758. return c;
  759. }
  760. }
  761. return null;
  762. }
  763. static getClassName(tar) {
  764. if (tar instanceof Function)
  765. return tar.name;
  766. return tar["constructor"].name;
  767. }
  768. destroy() {
  769. if (this._children) {
  770. this.destroyChildren();
  771. this._children.length = 0;
  772. }
  773. Laya.Pool.recover(HTMLElement.getClassName(this), this.reset());
  774. }
  775. destroyChildren() {
  776. if (this._children) {
  777. for (var i = this._children.length - 1; i > -1; i--) {
  778. this._children[i].destroy();
  779. }
  780. this._children.length = 0;
  781. }
  782. }
  783. get style() {
  784. return this._style;
  785. }
  786. _getWords() {
  787. if (!this._text)
  788. return null;
  789. var txt = this._text.text;
  790. if (!txt || txt.length === 0)
  791. return null;
  792. var words = this._text.words;
  793. if (words && words.length === txt.length)
  794. return words;
  795. words === null && (this._text.words = words = []);
  796. words.length = txt.length;
  797. var size;
  798. var style = this.style;
  799. var fontStr = style.font;
  800. for (var i = 0, n = txt.length; i < n; i++) {
  801. size = Laya.ILaya.Browser.measureText(txt.charAt(i), fontStr);
  802. words[i] = Laya.HTMLChar.create().setData(txt.charAt(i), size.width, size.height || style.fontSize, style);
  803. }
  804. return words;
  805. }
  806. _isChar() {
  807. return false;
  808. }
  809. _layoutLater() {
  810. var style = this.style;
  811. if ((style._type & HTMLStyle.ADDLAYOUTED))
  812. return;
  813. if (style.widthed(this) && ((this._children && this._children.length > 0) || this._getWords() != null) && style.block) {
  814. Layout.later(this);
  815. style._type |= HTMLStyle.ADDLAYOUTED;
  816. }
  817. else {
  818. this.parent && this.parent._layoutLater();
  819. }
  820. }
  821. set x(v) {
  822. if (this._x != v) {
  823. this._x = v;
  824. this.parentRepaint();
  825. }
  826. }
  827. get x() {
  828. return this._x;
  829. }
  830. set y(v) {
  831. if (this._y != v) {
  832. this._y = v;
  833. this.parentRepaint();
  834. }
  835. }
  836. get y() {
  837. return this._y;
  838. }
  839. get width() {
  840. return this._width;
  841. }
  842. set width(value) {
  843. if (this._width !== value) {
  844. this._width = value;
  845. this.repaint();
  846. }
  847. }
  848. get height() {
  849. return this._height;
  850. }
  851. set height(value) {
  852. if (this._height !== value) {
  853. this._height = value;
  854. this.repaint();
  855. }
  856. }
  857. _setAttributes(name, value) {
  858. switch (name) {
  859. case 'style':
  860. this.style.cssText(value);
  861. break;
  862. case 'class':
  863. this.className = value;
  864. break;
  865. case 'x':
  866. this.x = parseFloat(value);
  867. break;
  868. case 'y':
  869. this.y = parseFloat(value);
  870. break;
  871. case 'width':
  872. this.width = parseFloat(value);
  873. break;
  874. case 'height':
  875. this.height = parseFloat(value);
  876. break;
  877. default:
  878. this[name] = value;
  879. }
  880. }
  881. set href(url) {
  882. if (!this._style)
  883. return;
  884. if (url != this._style.href) {
  885. this._style.href = url;
  886. this.repaint();
  887. }
  888. }
  889. get href() {
  890. if (!this._style)
  891. return null;
  892. return this._style.href;
  893. }
  894. formatURL(url) {
  895. if (!this.URI)
  896. return url;
  897. return HTMLElement.formatURL1(url, this.URI ? this.URI.path : null);
  898. }
  899. set color(value) {
  900. this.style.color = value;
  901. }
  902. set className(value) {
  903. this.style.attrs(HTMLDocument.document.styleSheets['.' + value]);
  904. }
  905. drawToGraphic(graphic, gX, gY, recList) {
  906. gX += this.x;
  907. gY += this.y;
  908. var cssStyle = this.style;
  909. if (cssStyle.paddingLeft) {
  910. gX += cssStyle.paddingLeft;
  911. }
  912. if (cssStyle.paddingTop) {
  913. gY += cssStyle.paddingTop;
  914. }
  915. if (cssStyle.bgColor != null || cssStyle.borderColor) {
  916. graphic.drawRect(gX, gY, this.width, this.height, cssStyle.bgColor, cssStyle.borderColor, 1);
  917. }
  918. this.renderSelfToGraphic(graphic, gX, gY, recList);
  919. var i, len;
  920. var tChild;
  921. if (this._children && this._children.length > 0) {
  922. len = this._children.length;
  923. for (i = 0; i < len; i++) {
  924. tChild = this._children[i];
  925. if (tChild.drawToGraphic != null)
  926. tChild.drawToGraphic(graphic, gX, gY, recList);
  927. }
  928. }
  929. }
  930. renderSelfToGraphic(graphic, gX, gY, recList) {
  931. var cssStyle = this.style;
  932. var words = this._getWords();
  933. var len;
  934. if (words) {
  935. len = words.length;
  936. if (cssStyle) {
  937. var font = cssStyle.font;
  938. var color = cssStyle.color;
  939. if (cssStyle.stroke) {
  940. var stroke = cssStyle.stroke;
  941. stroke = parseInt(stroke);
  942. var strokeColor = cssStyle.strokeColor;
  943. graphic.fillBorderWords(words, gX, gY, font, color, strokeColor, stroke);
  944. }
  945. else {
  946. graphic.fillWords(words, gX, gY, font, color);
  947. }
  948. if (this.href) {
  949. var lastIndex = words.length - 1;
  950. var lastWords = words[lastIndex];
  951. var lineY = lastWords.y + lastWords.height;
  952. if (lastWords.y == words[0].y) {
  953. if (cssStyle.textDecoration != "none")
  954. graphic.drawLine(words[0].x, lineY, lastWords.x + lastWords.width, lineY, color, 1);
  955. var hitRec = HTMLHitRect.create();
  956. hitRec.rec.setTo(words[0].x, lastWords.y, lastWords.x + lastWords.width - words[0].x, lastWords.height);
  957. hitRec.href = this.href;
  958. recList.push(hitRec);
  959. }
  960. else {
  961. this.workLines(words, graphic, recList);
  962. }
  963. }
  964. }
  965. }
  966. }
  967. workLines(wordList, g, recList) {
  968. var cssStyle = this.style;
  969. var hasLine;
  970. hasLine = cssStyle.textDecoration != "none";
  971. var i, len;
  972. len = wordList.length;
  973. var tStartWord;
  974. tStartWord = wordList[i];
  975. var tEndWord;
  976. tEndWord = tStartWord;
  977. if (!tStartWord)
  978. return;
  979. var tword;
  980. for (i = 1; i < len; i++) {
  981. tword = wordList[i];
  982. if (tword.y != tStartWord.y) {
  983. this.createOneLine(tStartWord, tEndWord, hasLine, g, recList);
  984. tStartWord = tword;
  985. tEndWord = tword;
  986. }
  987. else {
  988. tEndWord = tword;
  989. }
  990. }
  991. this.createOneLine(tStartWord, tEndWord, hasLine, g, recList);
  992. }
  993. createOneLine(startWord, lastWords, hasLine, graphic, recList) {
  994. var lineY = lastWords.y + lastWords.height;
  995. if (hasLine)
  996. graphic.drawLine(startWord.x, lineY, lastWords.x + lastWords.width, lineY, this.style.color, 1);
  997. var hitRec = HTMLHitRect.create();
  998. hitRec.rec.setTo(startWord.x, lastWords.y, lastWords.x + lastWords.width - startWord.x, lastWords.height);
  999. hitRec.href = this.href;
  1000. recList.push(hitRec);
  1001. }
  1002. }
  1003. HTMLElement._EMPTYTEXT = { text: null, words: null };
  1004. Laya.ILaya.regClass(HTMLElement);
  1005. IHtml.HTMLElementType = exports.HTMLElementType;
  1006. Laya.ClassUtils.regClass("laya.html.dom.HTMLElement", HTMLElement);
  1007. Laya.ClassUtils.regClass("Laya.HTMLElement", HTMLElement);
  1008. class HTMLBrElement {
  1009. _addToLayout(out) {
  1010. out.push(this);
  1011. }
  1012. reset() {
  1013. return this;
  1014. }
  1015. destroy() {
  1016. Laya.Pool.recover(HTMLElement.getClassName(this), this.reset());
  1017. }
  1018. _setParent(value) {
  1019. }
  1020. set parent(value) {
  1021. }
  1022. set URI(value) {
  1023. }
  1024. set href(value) {
  1025. }
  1026. _getCSSStyle() {
  1027. if (!HTMLBrElement.brStyle) {
  1028. HTMLBrElement.brStyle = new HTMLStyle();
  1029. HTMLBrElement.brStyle.setLineElement(true);
  1030. HTMLBrElement.brStyle.block = true;
  1031. }
  1032. return HTMLBrElement.brStyle;
  1033. }
  1034. renderSelfToGraphic(graphic, gX, gY, recList) {
  1035. }
  1036. }
  1037. IHtml.HTMLBrElement = HTMLBrElement;
  1038. Laya.ILaya.regClass(HTMLBrElement);
  1039. Laya.ClassUtils.regClass("laya.html.dom.HTMLBrElement", HTMLBrElement);
  1040. Laya.ClassUtils.regClass("Laya.HTMLBrElement", HTMLBrElement);
  1041. class HTMLStyleElement extends HTMLElement {
  1042. _creates() {
  1043. }
  1044. drawToGraphic(graphic, gX, gY, recList) {
  1045. }
  1046. reset() {
  1047. return this;
  1048. }
  1049. set innerTEXT(value) {
  1050. HTMLStyle.parseCSS(value, null);
  1051. }
  1052. get innerTEXT() {
  1053. return super.innerTEXT;
  1054. }
  1055. }
  1056. Laya.ILaya.regClass(HTMLStyleElement);
  1057. Laya.ClassUtils.regClass("laya.html.dom.HTMLStyleElement", HTMLStyleElement);
  1058. Laya.ClassUtils.regClass("Laya.HTMLStyleElement", HTMLStyleElement);
  1059. class HTMLLinkElement extends HTMLElement {
  1060. _creates() {
  1061. }
  1062. drawToGraphic(graphic, gX, gY, recList) {
  1063. }
  1064. reset() {
  1065. if (this._loader)
  1066. this._loader.off(Laya.Event.COMPLETE, this, this._onload);
  1067. this._loader = null;
  1068. return this;
  1069. }
  1070. _onload(data) {
  1071. if (this._loader)
  1072. this._loader = null;
  1073. switch (this.type) {
  1074. case 'text/css':
  1075. HTMLStyle.parseCSS(data, this.URI);
  1076. break;
  1077. }
  1078. this.repaint(true);
  1079. }
  1080. set href(url) {
  1081. if (!url)
  1082. return;
  1083. url = this.formatURL(url);
  1084. this.URI = new Laya.URL(url);
  1085. if (this._loader)
  1086. this._loader.off(Laya.Event.COMPLETE, this, this._onload);
  1087. if (Laya.Loader.getRes(url)) {
  1088. if (this.type == "text/css") {
  1089. HTMLStyle.parseCSS(Laya.Loader.getRes(url), this.URI);
  1090. }
  1091. return;
  1092. }
  1093. this._loader = new Laya.Loader();
  1094. this._loader.once(Laya.Event.COMPLETE, this, this._onload);
  1095. this._loader.load(url, Laya.Loader.TEXT);
  1096. }
  1097. get href() {
  1098. return super.href;
  1099. }
  1100. }
  1101. HTMLLinkElement._cuttingStyle = new RegExp("((@keyframes[\\s\\t]+|)(.+))[\\t\\n\\r\\\s]*{", "g");
  1102. Laya.ILaya.regClass(HTMLLinkElement);
  1103. Laya.ClassUtils.regClass("laya.html.dom.HTMLLinkElement", HTMLLinkElement);
  1104. Laya.ClassUtils.regClass("Laya.HTMLLinkElement", HTMLLinkElement);
  1105. class HTMLDivParser extends HTMLElement {
  1106. constructor() {
  1107. super(...arguments);
  1108. this.repaintHandler = null;
  1109. }
  1110. reset() {
  1111. super.reset();
  1112. this._style.block = true;
  1113. this._style.setLineElement(true);
  1114. this._style.width = 200;
  1115. this._style.height = 200;
  1116. this.repaintHandler = null;
  1117. this.contextHeight = 0;
  1118. this.contextWidth = 0;
  1119. return this;
  1120. }
  1121. set innerHTML(text) {
  1122. this.destroyChildren();
  1123. this.appendHTML(text);
  1124. }
  1125. set width(value) {
  1126. var changed;
  1127. if (value === 0) {
  1128. changed = value != this._width;
  1129. }
  1130. else {
  1131. changed = value != this.width;
  1132. }
  1133. super.width = value;
  1134. if (changed)
  1135. this.layout();
  1136. }
  1137. appendHTML(text) {
  1138. IHtml.HTMLParse.parse(this, text, this.URI);
  1139. this.layout();
  1140. }
  1141. _addChildsToLayout(out) {
  1142. var words = this._getWords();
  1143. if (words == null && (!this._children || this._children.length == 0))
  1144. return false;
  1145. words && words.forEach(function (o) {
  1146. out.push(o);
  1147. });
  1148. var tFirstKey = true;
  1149. for (var i = 0, len = this._children.length; i < len; i++) {
  1150. var o = this._children[i];
  1151. if (tFirstKey) {
  1152. tFirstKey = false;
  1153. }
  1154. else {
  1155. out.push(null);
  1156. }
  1157. o._addToLayout(out);
  1158. }
  1159. return true;
  1160. }
  1161. _addToLayout(out) {
  1162. this.layout();
  1163. !this.style.absolute && out.push(this);
  1164. }
  1165. getBounds() {
  1166. if (!this._htmlBounds)
  1167. return null;
  1168. if (!this._boundsRec)
  1169. this._boundsRec = Laya.Rectangle.create();
  1170. return this._boundsRec.copyFrom(this._htmlBounds);
  1171. }
  1172. parentRepaint(recreate = false) {
  1173. super.parentRepaint();
  1174. if (this.repaintHandler)
  1175. this.repaintHandler.runWith(recreate);
  1176. }
  1177. layout() {
  1178. this.style._type |= HTMLStyle.ADDLAYOUTED;
  1179. var tArray = Layout.layout(this);
  1180. if (tArray) {
  1181. if (!this._htmlBounds)
  1182. this._htmlBounds = Laya.Rectangle.create();
  1183. var tRectangle = this._htmlBounds;
  1184. tRectangle.x = tRectangle.y = 0;
  1185. tRectangle.width = this.contextWidth = tArray[0];
  1186. tRectangle.height = this.contextHeight = tArray[1];
  1187. }
  1188. }
  1189. get height() {
  1190. if (this._height)
  1191. return this._height;
  1192. return this.contextHeight;
  1193. }
  1194. set height(value) {
  1195. super.height = value;
  1196. }
  1197. get width() {
  1198. if (this._width)
  1199. return this._width;
  1200. return this.contextWidth;
  1201. }
  1202. }
  1203. IHtml.HTMLDivParser = HTMLDivParser;
  1204. Laya.ILaya.regClass(HTMLDivParser);
  1205. Laya.ClassUtils.regClass("laya.html.dom.HTMLDivParser", HTMLDivParser);
  1206. Laya.ClassUtils.regClass("Laya.HTMLDivParser", HTMLDivParser);
  1207. class HTMLImageElement extends HTMLElement {
  1208. constructor() {
  1209. super();
  1210. this.eletype = exports.HTMLElementType.IMAGE;
  1211. }
  1212. reset() {
  1213. super.reset();
  1214. if (this._tex) {
  1215. this._tex.off(Laya.Event.LOADED, this, this.onloaded);
  1216. }
  1217. this._tex = null;
  1218. this._url = null;
  1219. return this;
  1220. }
  1221. set src(url) {
  1222. url = this.formatURL(url);
  1223. if (this._url === url)
  1224. return;
  1225. this._url = url;
  1226. var tex = this._tex = Laya.Loader.getRes(url);
  1227. if (!tex) {
  1228. this._tex = tex = new Laya.Texture();
  1229. tex.load(url);
  1230. Laya.Loader.cacheTexture(url, tex);
  1231. }
  1232. tex.getIsReady() ? this.onloaded() : tex.once(Laya.Event.READY, this, this.onloaded);
  1233. }
  1234. onloaded() {
  1235. if (!this._style)
  1236. return;
  1237. var style = this._style;
  1238. var w = style.widthed(this) ? -1 : this._tex.width;
  1239. var h = style.heighted(this) ? -1 : this._tex.height;
  1240. if (!style.widthed(this) && this._width != this._tex.width) {
  1241. this.width = this._tex.width;
  1242. this.parent && this.parent._layoutLater();
  1243. }
  1244. if (!style.heighted(this) && this._height != this._tex.height) {
  1245. this.height = this._tex.height;
  1246. this.parent && this.parent._layoutLater();
  1247. }
  1248. this.repaint();
  1249. }
  1250. _addToLayout(out) {
  1251. var style = this._style;
  1252. !style.absolute && out.push(this);
  1253. }
  1254. renderSelfToGraphic(graphic, gX, gY, recList) {
  1255. if (!this._tex)
  1256. return;
  1257. graphic.drawImage(this._tex, gX, gY, this.width || this._tex.width, this.height || this._tex.height);
  1258. }
  1259. }
  1260. IHtml.HTMLImageElement = HTMLImageElement;
  1261. Laya.ILaya.regClass(HTMLImageElement);
  1262. Laya.ClassUtils.regClass("laya.html.dom.HTMLImageElement", HTMLImageElement);
  1263. Laya.ClassUtils.regClass("Laya.HTMLImageElement", HTMLImageElement);
  1264. class HTMLParse {
  1265. static getInstance(type) {
  1266. var rst = Laya.Pool.getItem(HTMLParse._htmlClassMapShort[type]);
  1267. if (!rst) {
  1268. rst = Laya.ClassUtils.getInstance(type);
  1269. }
  1270. return rst;
  1271. }
  1272. static parse(ower, xmlString, url) {
  1273. xmlString = xmlString.replace(/<br>/g, "<br/>");
  1274. xmlString = "<root>" + xmlString + "</root>";
  1275. xmlString = xmlString.replace(HTMLParse.spacePattern, HTMLParse.char255);
  1276. var xml = Laya.Utils.parseXMLFromString(xmlString);
  1277. HTMLParse._parseXML(ower, xml.childNodes[0].childNodes, url);
  1278. }
  1279. static _parseXML(parent, xml, url, href = null) {
  1280. var i, n;
  1281. if (xml.join || xml.item) {
  1282. for (i = 0, n = xml.length; i < n; ++i) {
  1283. HTMLParse._parseXML(parent, xml[i], url, href);
  1284. }
  1285. }
  1286. else {
  1287. var node;
  1288. var nodeName;
  1289. if (xml.nodeType == 3) {
  1290. var txt;
  1291. if (parent instanceof IHtml.HTMLDivParser) {
  1292. if (xml.nodeName == null) {
  1293. xml.nodeName = "#text";
  1294. }
  1295. nodeName = xml.nodeName.toLowerCase();
  1296. txt = xml.textContent.replace(/^\s+|\s+$/g, '');
  1297. if (txt.length > 0) {
  1298. node = HTMLParse.getInstance(nodeName);
  1299. if (node) {
  1300. parent.addChild(node);
  1301. (node.innerTEXT = txt.replace(HTMLParse.char255AndOneSpacePattern, " "));
  1302. }
  1303. }
  1304. }
  1305. else {
  1306. txt = xml.textContent.replace(/^\s+|\s+$/g, '');
  1307. if (txt.length > 0) {
  1308. var containNode = parent;
  1309. if (parent instanceof HTMLElement && parent.innerTEXT && parent.innerTEXT.length > 0) {
  1310. let cnode = HTMLParse.getInstance('p');
  1311. if (cnode) {
  1312. parent.addChild(cnode);
  1313. containNode = cnode;
  1314. }
  1315. }
  1316. containNode.innerTEXT = txt.replace(HTMLParse.char255AndOneSpacePattern, " ");
  1317. }
  1318. }
  1319. return;
  1320. }
  1321. else {
  1322. nodeName = xml.nodeName.toLowerCase();
  1323. if (nodeName == "#comment")
  1324. return;
  1325. node = HTMLParse.getInstance(nodeName);
  1326. if (node) {
  1327. if (nodeName == "p") {
  1328. parent.addChild(HTMLParse.getInstance("br"));
  1329. node = parent.addChild(node);
  1330. parent.addChild(HTMLParse.getInstance("br"));
  1331. }
  1332. else {
  1333. node = parent.addChild(node);
  1334. }
  1335. node.URI = url;
  1336. node.href = href;
  1337. var attributes = xml.attributes;
  1338. if (attributes && attributes.length > 0) {
  1339. for (i = 0, n = attributes.length; i < n; ++i) {
  1340. var attribute = attributes[i];
  1341. var attrName = attribute.nodeName;
  1342. var value = attribute.value;
  1343. node._setAttributes(attrName, value);
  1344. }
  1345. }
  1346. HTMLParse._parseXML(node, xml.childNodes, url, node.href);
  1347. }
  1348. else {
  1349. HTMLParse._parseXML(parent, xml.childNodes, url, href);
  1350. }
  1351. }
  1352. }
  1353. }
  1354. }
  1355. HTMLParse.char255 = String.fromCharCode(255);
  1356. HTMLParse.spacePattern = /&nbsp;|&#160;/g;
  1357. HTMLParse.char255AndOneSpacePattern = new RegExp(String.fromCharCode(255) + "|(\\s+)", "g");
  1358. HTMLParse._htmlClassMapShort = {
  1359. 'div': HTMLDivParser,
  1360. 'p': HTMLElement,
  1361. 'img': HTMLImageElement,
  1362. 'span': HTMLElement,
  1363. 'br': HTMLBrElement,
  1364. 'style': HTMLStyleElement,
  1365. 'font': HTMLElement,
  1366. 'a': HTMLElement,
  1367. '#text': HTMLElement,
  1368. 'link': HTMLLinkElement
  1369. };
  1370. IHtml.HTMLParse = HTMLParse;
  1371. Laya.ClassUtils.regClass('div', HTMLDivParser);
  1372. Laya.ClassUtils.regClass('p', HTMLElement);
  1373. Laya.ClassUtils.regClass('img', HTMLImageElement);
  1374. Laya.ClassUtils.regClass('span', HTMLElement);
  1375. Laya.ClassUtils.regClass('br', HTMLBrElement);
  1376. Laya.ClassUtils.regClass('style', HTMLStyleElement);
  1377. Laya.ClassUtils.regClass('font', HTMLElement);
  1378. Laya.ClassUtils.regClass('a', HTMLElement);
  1379. Laya.ClassUtils.regClass('#text', HTMLElement);
  1380. Laya.ClassUtils.regClass('link', HTMLLinkElement);
  1381. Laya.ClassUtils.regClass("laya.html.utils.HTMLParse", HTMLParse);
  1382. Laya.ClassUtils.regClass("Laya.HTMLParse", HTMLParse);
  1383. class HTMLDivElement extends Laya.Sprite {
  1384. constructor() {
  1385. super();
  1386. this._recList = [];
  1387. this._repaintState = 0;
  1388. this._element = new HTMLDivParser();
  1389. this._element.repaintHandler = new Laya.Handler(this, this._htmlDivRepaint);
  1390. this.mouseEnabled = true;
  1391. this.on(Laya.Event.CLICK, this, this._onMouseClick);
  1392. }
  1393. destroy(destroyChild = true) {
  1394. if (this._element)
  1395. this._element.reset();
  1396. this._element = null;
  1397. this._doClears();
  1398. super.destroy(destroyChild);
  1399. }
  1400. _htmlDivRepaint(recreate = false) {
  1401. if (recreate) {
  1402. if (this._repaintState < 2)
  1403. this._repaintState = 2;
  1404. }
  1405. else {
  1406. if (this._repaintState < 1)
  1407. this._repaintState = 1;
  1408. }
  1409. if (this._repaintState > 0)
  1410. this._setGraphicDirty();
  1411. }
  1412. _updateGraphicWork() {
  1413. switch (this._repaintState) {
  1414. case 1:
  1415. this._updateGraphic();
  1416. break;
  1417. case 2:
  1418. this._refresh();
  1419. break;
  1420. }
  1421. }
  1422. _setGraphicDirty() {
  1423. this.callLater(this._updateGraphicWork);
  1424. }
  1425. _doClears() {
  1426. if (!this._recList)
  1427. return;
  1428. var i, len = this._recList.length;
  1429. var tRec;
  1430. for (i = 0; i < len; i++) {
  1431. tRec = this._recList[i];
  1432. tRec.recover();
  1433. }
  1434. this._recList.length = 0;
  1435. }
  1436. _updateGraphic() {
  1437. this._doClears();
  1438. this.graphics.clear(true);
  1439. this._repaintState = 0;
  1440. this._element.drawToGraphic(this.graphics, -this._element.x, -this._element.y, this._recList);
  1441. var bounds = this._element.getBounds();
  1442. if (bounds)
  1443. this.setSelfBounds(bounds);
  1444. this.size(bounds.width, bounds.height);
  1445. }
  1446. get style() {
  1447. return this._element.style;
  1448. }
  1449. set innerHTML(text) {
  1450. if (this._innerHTML == text)
  1451. return;
  1452. this._repaintState = 1;
  1453. this._innerHTML = text;
  1454. this._element.innerHTML = text;
  1455. this._setGraphicDirty();
  1456. }
  1457. _refresh() {
  1458. this._repaintState = 1;
  1459. if (this._innerHTML)
  1460. this._element.innerHTML = this._innerHTML;
  1461. this._setGraphicDirty();
  1462. }
  1463. get contextWidth() {
  1464. return this._element.contextWidth;
  1465. }
  1466. get contextHeight() {
  1467. return this._element.contextHeight;
  1468. }
  1469. _onMouseClick() {
  1470. var tX = this.mouseX;
  1471. var tY = this.mouseY;
  1472. var i, len;
  1473. var tHit;
  1474. len = this._recList.length;
  1475. for (i = 0; i < len; i++) {
  1476. tHit = this._recList[i];
  1477. if (tHit.rec.contains(tX, tY)) {
  1478. this._eventLink(tHit.href);
  1479. }
  1480. }
  1481. }
  1482. _eventLink(href) {
  1483. this.event(Laya.Event.LINK, [href]);
  1484. }
  1485. }
  1486. IHtml.HTMLDivElement = HTMLDivElement;
  1487. IHtml.HTMLParse = HTMLParse;
  1488. Laya.ClassUtils.regClass("laya.html.dom.HTMLDivElement", HTMLDivElement);
  1489. Laya.ClassUtils.regClass("Laya.HTMLDivElement", HTMLDivElement);
  1490. class HTMLIframeElement extends HTMLDivElement {
  1491. constructor() {
  1492. super();
  1493. this._element._getCSSStyle().valign = "middle";
  1494. }
  1495. set href(url) {
  1496. url = this._element.formatURL(url);
  1497. var l = new Laya.Loader();
  1498. l.once(Laya.Event.COMPLETE, null, (data) => {
  1499. var pre = this._element.URI;
  1500. this._element.URI = new Laya.URL(url);
  1501. this.innerHTML = data;
  1502. !pre || (this._element.URI = pre);
  1503. });
  1504. l.load(url, Laya.Loader.TEXT);
  1505. }
  1506. }
  1507. Laya.ClassUtils.regClass("laya.html.dom.HTMLIframeElement", HTMLIframeElement);
  1508. Laya.ClassUtils.regClass("Laya.HTMLIframeElement", HTMLIframeElement);
  1509. exports.HTMLBrElement = HTMLBrElement;
  1510. exports.HTMLDivElement = HTMLDivElement;
  1511. exports.HTMLDivParser = HTMLDivParser;
  1512. exports.HTMLDocument = HTMLDocument;
  1513. exports.HTMLElement = HTMLElement;
  1514. exports.HTMLExtendStyle = HTMLExtendStyle;
  1515. exports.HTMLHitRect = HTMLHitRect;
  1516. exports.HTMLIframeElement = HTMLIframeElement;
  1517. exports.HTMLImageElement = HTMLImageElement;
  1518. exports.HTMLLinkElement = HTMLLinkElement;
  1519. exports.HTMLParse = HTMLParse;
  1520. exports.HTMLStyle = HTMLStyle;
  1521. exports.HTMLStyleElement = HTMLStyleElement;
  1522. exports.IHtml = IHtml;
  1523. exports.Layout = Layout;
  1524. exports.LayoutLine = LayoutLine;
  1525. }(window.Laya = window.Laya|| {}, Laya));