laya.html.js 55 KB

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