specialized XmlDocument and various

This commit is contained in:
Adam D. Ruppe 2012-03-20 10:27:47 -04:00
parent 0c94c232a4
commit 5f5c157ded
1 changed files with 39 additions and 20 deletions

59
dom.d
View File

@ -38,7 +38,7 @@ import std.uri;
import std.array; import std.array;
import std.range; import std.range;
import std.stdio; //import std.stdio;
// tag soup works for most the crap I know now! If you have two bad closing tags back to back, it might erase one, but meh // tag soup works for most the crap I know now! If you have two bad closing tags back to back, it might erase one, but meh
// that's rarer than the flipped closing tags that hack fixes so I'm ok with it. (Odds are it should be erased anyway; it's // that's rarer than the flipped closing tags that hack fixes so I'm ok with it. (Odds are it should be erased anyway; it's
@ -654,13 +654,18 @@ class Element {
/** /**
Removes the given attribute from the element. Removes the given attribute from the element.
*/ */
void removeAttribute(string name) { Element removeAttribute(string name)
out(ret) {
assert(ret is this);
}
body {
if(parentDocument && parentDocument.loose) if(parentDocument && parentDocument.loose)
name = name.toLower(); name = name.toLower();
if(name in attributes) if(name in attributes)
attributes.remove(name); attributes.remove(name);
sendObserverEvent(DomMutationOperations.removeAttribute, name); sendObserverEvent(DomMutationOperations.removeAttribute, name);
return this;
} }
/** /**
@ -956,7 +961,6 @@ class Element {
///. ///.
Element addChild(string tagName, Element firstChild) Element addChild(string tagName, Element firstChild)
in { in {
assert(parentDocument !is null);
assert(firstChild !is null); assert(firstChild !is null);
} }
out(ret) { out(ret) {
@ -965,10 +969,10 @@ class Element {
assert(firstChild.parentNode is ret); assert(firstChild.parentNode is ret);
assert(ret.parentDocument is this.parentDocument); assert(ret.parentDocument is this.parentDocument);
assert(firstChild.parentDocument is this.parentDocument); //assert(firstChild.parentDocument is this.parentDocument);
} }
body { body {
auto e = parentDocument.createElement(tagName); auto e = Element.make(tagName);
e.appendChild(firstChild); e.appendChild(firstChild);
this.appendChild(e); this.appendChild(e);
return e; return e;
@ -1131,8 +1135,8 @@ class Element {
assert(parentNode !is null); assert(parentNode !is null);
} }
out { out {
assert(this.parentNode == newParent); assert(this.parentNode is newParent);
assert(isInArray(this, newParent.children)); //assert(isInArray(this, newParent.children));
} }
body { body {
parentNode.removeChild(this); parentNode.removeChild(this);
@ -1146,13 +1150,13 @@ class Element {
assert(where !is null); assert(where !is null);
assert(where.parentNode is this); assert(where.parentNode is this);
assert(!selfClosed); assert(!selfClosed);
assert(isInArray(where, children)); //assert(isInArray(where, children));
} }
out { out {
assert(child.parentNode is this); assert(child.parentNode is this);
assert(where.parentNode is this); assert(where.parentNode is this);
assert(isInArray(where, children)); //assert(isInArray(where, children));
assert(isInArray(child, children)); //assert(isInArray(child, children));
} }
body { body {
foreach(i, c; children) { foreach(i, c; children) {
@ -1171,8 +1175,8 @@ class Element {
in { in {
assert(!selfClosed); assert(!selfClosed);
assert(e !is null); assert(e !is null);
if(position !is null) //if(position !is null)
assert(isInArray(position, children)); //assert(isInArray(position, children));
} }
out (ret) { out (ret) {
assert(e.children.length == 0); assert(e.children.length == 0);
@ -1634,12 +1638,15 @@ class Element {
/// This is a full clone of the element /// This is a full clone of the element
@property Element cloned() @property Element cloned()
/+
out(ret) { out(ret) {
// FIXME: not sure why these fail... // FIXME: not sure why these fail...
// assert(ret.children.length == this.children.length); assert(ret.children.length == this.children.length, format("%d %d", ret.children.length, this.children.length));
// assert(ret.tagName == this.tagName); assert(ret.tagName == this.tagName);
} }
body { body {
+/
{
auto e = new Element(parentDocument, tagName, attributes.dup, selfClosed); auto e = new Element(parentDocument, tagName, attributes.dup, selfClosed);
foreach(child; children) { foreach(child; children) {
e.appendChild(child.cloned); e.appendChild(child.cloned);
@ -2003,7 +2010,8 @@ class TextNode : Element {
///. ///.
override @property Element cloned() { override @property Element cloned() {
return new TextNode(parentDocument, contents); auto n = new TextNode(parentDocument, contents);
return n;
} }
///. ///.
@ -2468,13 +2476,12 @@ class Table : Element {
foreach(e; children) { foreach(e; children) {
if(e.tagName == "tbody") { if(e.tagName == "tbody") {
e.appendChild(row); e.appendChild(row);
goto done; return row;
} }
} }
appendChild(row); appendChild(row);
done:
return row; return row;
} }
@ -2679,8 +2686,7 @@ struct Html {
string source; string source;
} }
/// The main document interface, including a html parser.
///.
class Document : FileResource { class Document : FileResource {
///. ///.
this(string data, bool caseSensitive = false, bool strict = false) { this(string data, bool caseSensitive = false, bool strict = false) {
@ -3508,6 +3514,19 @@ class Document : FileResource {
} }
} }
/// Specializes Document for handling generic XML. (always uses strict mode, uses xml mime type and file header)
class XmlDocument : Document {
this(string data) {
contentType = "text/xml; charset=utf-8";
prolog = `<?xml version="1.0" encoding="UTF-8"?>` ~ "\n";
parse(data, true, true);
}
}
// for the observers // for the observers
enum DomMutationOperations { enum DomMutationOperations {
setAttribute, setAttribute,
@ -4326,7 +4345,7 @@ class CssStyle {
return (property.value = value); return (property.value = value);
} else { } else {
if(name == "display") if(name == "display")
writeln("Not setting ", name, " to ", value, " because ", newSpecificity.score, " < ", property.specificity.score); {}//writeln("Not setting ", name, " to ", value, " because ", newSpecificity.score, " < ", property.specificity.score);
return value; // do nothing - the specificity is too low return value; // do nothing - the specificity is too low
} }
} }