private void init(Reach src, Tag parent, bool xml) { isRelevant = true; type = src.upto(0); //AttGeTr: type was null in new Tag("", false) ctn = src.upto(0); //AttGeTr: ctn was null in some TestCase ... isXmlTag = xml; _tags = new Pile <Tag>(); this.parent = parent; def = src; if (parent == null) { root = this; all = new Pile <Tag>(); int done = 0; while (done < def.len) { all.Add(new Tag(def.after(done), this, xml)); if (all[-1].isWhiteSpace()) { all[-1].isRelevant = false; } if (all.Len == 1) { all[-1].parent = this; } else { if (all[-1].type.startsWith("/")) { for (int i = all.Len - 1; i > 0; i--) { if ((all[-1].type.Equals("/" + all[i].type.text)) && (all[i].closingTag == null)) { all[i].closingTag = all[-1]; all[-1].parent = all[i].parent; break; } } if (all[-1].parent == null) { all[-1].parent = all[-2].parent; // orphaned closing tag } } else { if ((all[-1].type.len == 0) && (!all[-2].type.startsWith("/"))) // new definition: a "plain text tag" may be contained in any tag but may not always be relevant ... { if (!all[-2].mayContain(all[-1].type.text)) { all[-1].isRelevant = false; } if (all[-2].closingTag == null) { all[-1].parent = all[-2]; } else { all[-1].parent = all[-2].parent; } } else { if ((all[-2].mayContain(all[-1].type.text))) { all[-1].parent = all[-2]; } else { all[-1].parent = all[-2].parent; if (all[-2].closingTag == null) { all[-2].closingTag = all[-2]; } } } } } done = done + all[-1]._htm.len; } for (int i = 1; i <= all.Len; i++) { if ((all[i].isRelevant) && (!all[i].type.startsWith("/"))) { all[i].parent._tags.Add(all[i]); } } } else { root = parent.root; if (def.startsWith("<")) { def = def.upto(1, ">"); type = def.after(1).before(-1).before(1, " "); if (type.startsWith("!")) { if (type.startsWith("!--")) { type = type.upto(3); } else { type = type.upto(1); } } if (type.endsWith("/")) { type = type.before(-1); } if (type.Equals("!--")) { closingTag = this; type = type.upto(1); def = root.def.from(def).upto(1, "-->"); ctn = def.after(-1).upto(0); _htm = def; attrib = def.after(type).upto(-2).lTrim().rTrim(); if (attrib.endsWith("/")) { closingTag = this; attrib = attrib.before(-1); } } else { if (type.startsWith("!")) { closingTag = this; type = type.upto(1); } if (type.Equals("script")) { ctn = root.def.from(def).Before(1, "</script"); _htm = ctn.upto(-1); //htm = def + ctn + root.def.after(ctn).upto(1, ">"); attrib = def.after(type).upto(-2).lTrim().rTrim(); if (attrib.endsWith("/")) { closingTag = this; attrib = attrib.before(-1); } } else { ctn = root.def.after(def).upto(0); _htm = def.upto(-1); //_htm = def.plus(ctn); attrib = def.after(type).upto(-2).lTrim().rTrim(); if (attrib.endsWith("/")) { closingTag = this; attrib = attrib.before(-1); } } } } else { closingTag = this; ctn = def.before(1, "<"); type = def.upto(0); def = def.upto(0); attrib = def.upto(0); _htm = ctn.upto(-1); } } }