laya.html.js 54 KB

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