laya.html.js 46 KB

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