diff --git a/source/newxml/cursor.d b/source/newxml/cursor.d
index 7612d66..7aa9ff5 100644
--- a/source/newxml/cursor.d
+++ b/source/newxml/cursor.d
@@ -9,6 +9,7 @@
+ Authors:
+ Lodovico Giaretta
+ László Szerémi
++ Robert Schadek
+
+ License:
+ Boost License 1.0.
@@ -31,18 +32,23 @@ import std.range.primitives;
import std.typecons;
import std.string;
-public class CursorException : XMLException {
- @nogc @safe pure nothrow this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable nextInChain = null)
+@safe:
+
+public class CursorException : XMLException
+{
+ @nogc @safe pure nothrow this(string msg, string file = __FILE__,
+ size_t line = __LINE__, Throwable nextInChain = null)
{
super(msg, file, line, nextInChain);
}
- @nogc @safe pure nothrow this(string msg, Throwable nextInChain, string file = __FILE__, size_t line = __LINE__)
+ @nogc @safe pure nothrow this(string msg, Throwable nextInChain,
+ string file = __FILE__, size_t line = __LINE__)
{
super(msg, file, line, nextInChain);
}
}
-@safe:
+
package struct Attribute(StringType)
{
StringType value;
@@ -52,33 +58,34 @@ package struct Attribute(StringType)
this(StringType qualifiedName, StringType value)
{
this.value = value;
- name = qualifiedName;
+ this.name = qualifiedName;
}
@property auto name() inout
{
- return _name;
+ return this._name;
}
+
@property void name(StringType _name)
{
this._name = _name;
- auto i = _name.indexOf(':');
- colon = i > 0
- ? i
- : 0;
+ auto i = this._name.indexOf(':');
+ this.colon = i > 0 ? i : 0;
}
+
@property auto prefix() inout
{
- return name[0..colon];
+ return this.name[0 .. this.colon];
}
+
@property StringType localName()
{
- return colon
- ? name[colon+1..$]
- : name;
+ return this.colon != 0 ? this.name[this.colon + 1 .. $] : this.name;
}
- StringType toString() {
- return name ~ " = \"" ~ value ~ "\"";
+
+ StringType toString()
+ {
+ return this.name ~ " = \"" ~ this.value ~ "\"";
}
}
@@ -95,12 +102,13 @@ package struct Attribute(StringType)
+ process the document. Otherwise it'll throw an appropriate exception if an error is encountered.
+/
struct Cursor(P, Flag!"conflateCDATA" conflateCDATA = Yes.conflateCDATA,
- Flag!"processBadDocument" processBadDocument = No.processBadDocument)
- if (isLowLevelParser!P)
+ Flag!"processBadDocument" processBadDocument = No.processBadDocument)
+ if (isLowLevelParser!P)
{
- class AttributeException : XMLException {
- @nogc @safe pure nothrow this(string msg, string file = __FILE__, size_t line = __LINE__,
- Throwable nextInChain = null)
+ class AttributeException : XMLException
+ {
+ @nogc @safe pure nothrow this(string msg, string file = __FILE__,
+ size_t line = __LINE__, Throwable nextInChain = null)
{
super(msg, file, line, nextInChain);
}
@@ -115,21 +123,21 @@ struct Cursor(P, Flag!"conflateCDATA" conflateCDATA = Yes.conflateCDATA,
private this(StringType str, ref Cursor cur) @system nothrow
{
- content = str;
- cursor = &cur;
+ this.content = str;
+ this.cursor = &cur;
}
bool empty() @safe
{
- if (error)
+ if (this.error)
{
return true;
}
- auto i = content.indexOfNeither(" \r\n\t");
+ auto i = this.content.indexOfNeither(" \r\n\t");
if (i >= 0)
{
- content = content[i..$];
+ this.content = this.content[i .. $];
return false;
}
return true;
@@ -137,13 +145,13 @@ struct Cursor(P, Flag!"conflateCDATA" conflateCDATA = Yes.conflateCDATA,
auto front() @safe
{
- if (attr == attr.init)
+ if (this.attr == attr.init)
{
auto i = content.indexOfNeither(" \r\n\t");
enforce!AttributeException(i >= 0, "No more attributes...");
- content = content[i..$];
+ this.content = this.content[i .. $];
- auto sep = indexOf(content[0..$], '=');
+ auto sep = indexOf(this.content[0 .. $], '=');
if (sep == -1)
{
// attribute without value???
@@ -153,18 +161,17 @@ struct Cursor(P, Flag!"conflateCDATA" conflateCDATA = Yes.conflateCDATA,
}
else
{
- error = true;
+ this.error = true;
return attr.init;
}
}
- auto name = content[0..sep];
-
+ auto name = this.content[0 .. sep];
auto delta = indexOfAny(name, " \r\n\t");
if (delta >= 0)
{
- auto j = name[delta..$].indexOfNeither(" \r\n\t");
+ auto j = name[delta .. $].indexOfNeither(" \r\n\t");
if (j != -1)
{
// attribute name contains spaces???
@@ -174,11 +181,11 @@ struct Cursor(P, Flag!"conflateCDATA" conflateCDATA = Yes.conflateCDATA,
}
else
{
- error = true;
+ this.error = true;
return attr.init;
}
}
- name = name[0..delta];
+ name = name[0 .. delta];
}
if (!isValidXMLName(name))
{
@@ -188,31 +195,35 @@ struct Cursor(P, Flag!"conflateCDATA" conflateCDATA = Yes.conflateCDATA,
}
else
{
- error = true;
+ this.error = true;
}
}
attr.name = name;
size_t attEnd;
size_t quote;
- delta = (sep + 1 < content.length) ? indexOfNeither(content[sep + 1..$], " \r\n\t") : -1;
+
+ delta = (sep + 1 < content.length) ? indexOfNeither(
+ this.content[sep + 1 .. $], " \r\n\t") : -1;
+
if (delta >= 0)
{
quote = sep + 1 + delta;
if (content[quote] == '"' || content[quote] == '\'')
{
- delta = indexOf(content[(quote + 1)..$], content[quote]);
+ delta = indexOf(content[(quote + 1) .. $], content[quote]);
if (delta == -1)
{
// attribute quotes never closed???
- static if (processBadDocument == No.processBadDocument)
+ static if (processBadDocument == No
+ .processBadDocument)
{
throw new CursorException("Invalid attribute syntax!");
}
else
{
- error = true;
- return attr.init;
+ this.error = true;
+ return this.attr.init;
}
}
attEnd = quote + 1 + delta;
@@ -225,8 +236,8 @@ struct Cursor(P, Flag!"conflateCDATA" conflateCDATA = Yes.conflateCDATA,
}
else
{
- error = true;
- return attr.init;
+ this.error = true;
+ return this.attr.init;
}
}
}
@@ -239,28 +250,31 @@ struct Cursor(P, Flag!"conflateCDATA" conflateCDATA = Yes.conflateCDATA,
}
else
{
- error = true;
- return attr.init;
+ this.error = true;
+ return this.attr.init;
}
}
//attr.value = content[(quote + 1)..attEnd];
static if (processBadDocument == No.processBadDocument)
{
- attr.value = xmlUnescape(content[(quote + 1)..attEnd], cursor.chrEntities);
+ this.attr.value = xmlUnescape(content[(quote + 1) .. attEnd], cursor
+ .chrEntities);
}
else
{
- attr.value = xmlUnescape!No.strict(content[(quote + 1)..attEnd], cursor.chrEntities);
+ this.attr.value = xmlUnescape!No.strict(
+ content[(quote + 1) .. attEnd], cursor.chrEntities);
}
- content = content[attEnd+1..$];
+
+ this.content = this.content[attEnd + 1 .. $];
}
- return attr;
+ return this.attr;
}
- auto popFront() @safe
+ void popFront() @safe
{
- front();
- attr = attr.init;
+ this.front();
+ this.attr = this.attr.init;
}
}
/++ The type of characters in the input, as returned by the underlying low level parser. +/
@@ -288,8 +302,8 @@ struct Cursor(P, Flag!"conflateCDATA" conflateCDATA = Yes.conflateCDATA,
/++ Generic constructor; forwards its arguments to the parser constructor +/
this(Args...)(Args args)
{
- parser = P(args);
- chrEntities = xmlPredefinedEntities!CharacterType();
+ this.parser = P(args);
+ this.chrEntities = xmlPredefinedEntities!CharacterType();
}
static if (isSaveableLowLevelParser!P)
@@ -297,14 +311,14 @@ struct Cursor(P, Flag!"conflateCDATA" conflateCDATA = Yes.conflateCDATA,
public auto save()
{
auto result = this;
- result.parser = parser.save;
+ result.parser = this.parser.save;
return result;
}
}
///Returns true if XML declaration was not found.
public @property bool xmlDeclNotFound() @nogc @safe pure nothrow
{
- return _xmlDeclNotFound;
+ return this._xmlDeclNotFound;
}
/+
/**
@@ -375,19 +389,18 @@ struct Cursor(P, Flag!"conflateCDATA" conflateCDATA = Yes.conflateCDATA,
private bool advanceInput()
{
- colon = colon.max;
- nameEnd = 0;
- parser.popFront();
- if (!parser.empty)
+ this.colon = colon.max;
+ this.nameEnd = 0;
+ this.parser.popFront();
+ if (!this.parser.empty)
{
- currentNode = parser.front;
+ this.currentNode = this.parser.front;
return true;
}
- _documentEnd = true;
+ this._documentEnd = true;
return false;
}
-
static if (needSource!P)
{
/++
@@ -401,48 +414,48 @@ struct Cursor(P, Flag!"conflateCDATA" conflateCDATA = Yes.conflateCDATA,
+/
void setSource(InputType input)
{
- parser.setSource(input);
- initialize();
+ this.parser.setSource(input);
+ this.initialize();
}
}
private void initialize()
{
// reset private fields
- nextFailed = false;
- _xmlDeclNotFound = false;
- colon = colon.max;
- nameEnd = 0;
+ this.nextFailed = false;
+ this._xmlDeclNotFound = false;
+ this.colon = colon.max;
+ this.nameEnd = 0;
if (!parser.empty)
{
- if (parser.front.kind == XMLKind.processingInstruction &&
- parser.front.content.length >= 3 &&
- equal(parser.front.content[0..3], "xml"))
+ if (this.parser.front.kind == XMLKind.processingInstruction
+ && this.parser.front.content.length >= 3
+ && equal(this.parser.front.content[0 .. 3], "xml"))
{
- currentNode = parser.front;
+ this.currentNode = this.parser.front;
}
else
{
// document without xml declaration???
// It turns out XML declaration is not mandatory, just assume UTF-8 and XML version 1.0 if it's missing!
- currentNode.kind = XMLKind.processingInstruction;
- currentNode.content = "xml version = \"1.0\" encoding = \"UTF-8\"";
- _xmlDeclNotFound = true;
+ this.currentNode.kind = XMLKind.processingInstruction;
+ this.currentNode.content = "xml version = \"1.0\" encoding = \"UTF-8\"";
+ this._xmlDeclNotFound = true;
}
- starting = true;
- _documentEnd = false;
+ this.starting = true;
+ this._documentEnd = false;
}
else
{
- _documentEnd = true;
+ this._documentEnd = true;
}
}
/++ Returns whether the cursor is at the end of the document. +/
bool documentEnd()
{
- return _documentEnd;
+ return this._documentEnd;
}
/++
@@ -452,7 +465,7 @@ struct Cursor(P, Flag!"conflateCDATA" conflateCDATA = Yes.conflateCDATA,
+/
bool atBeginning()
{
- return starting;
+ return this.starting;
}
/++
@@ -463,29 +476,30 @@ struct Cursor(P, Flag!"conflateCDATA" conflateCDATA = Yes.conflateCDATA,
+/
bool enter()
{
- if (starting)
+ if (this.starting)
{
- starting = false;
- if (currentNode.content is parser.front.content)
+ this.starting = false;
+ if (this.currentNode.content is this.parser.front.content)
{
- return advanceInput();
+ return this.advanceInput();
}
else
{
- nameEnd = 0;
- nameBegin = 0;
+ this.nameEnd = 0;
+ this.nameBegin = 0;
}
- currentNode = parser.front;
+ this.currentNode = this.parser.front;
return true;
}
- else if (currentNode.kind == XMLKind.elementStart)
+ else if (this.currentNode.kind == XMLKind.elementStart)
{
- return advanceInput() && currentNode.kind != XMLKind.elementEnd;
+ return this.advanceInput() && this.currentNode.kind != XMLKind
+ .elementEnd;
}
- else if (currentNode.kind == XMLKind.dtdStart)
+ else if (this.currentNode.kind == XMLKind.dtdStart)
{
- return advanceInput() && currentNode.kind != XMLKind.dtdEnd;
+ return this.advanceInput() && this.currentNode.kind != XMLKind.dtdEnd;
}
else
{
@@ -496,14 +510,14 @@ struct Cursor(P, Flag!"conflateCDATA" conflateCDATA = Yes.conflateCDATA,
/++ Advances to the end of the parent of the current node. +/
void exit()
{
- if (!nextFailed)
+ if (!this.nextFailed)
{
- while (next())
+ while (this.next())
{
}
}
- nextFailed = false;
+ this.nextFailed = false;
}
/++
@@ -513,50 +527,51 @@ struct Cursor(P, Flag!"conflateCDATA" conflateCDATA = Yes.conflateCDATA,
+/
bool next()
{
- if (parser.empty || starting || nextFailed)
+ if (this.parser.empty || this.starting || this.nextFailed)
{
return false;
}
- else if (currentNode.kind == XMLKind.dtdStart)
+ else if (this.currentNode.kind == XMLKind.dtdStart)
{
/+while (advanceInput && currentNode.kind != XMLKind.dtdEnd)
{
}+/
}
- else if (currentNode.kind == XMLKind.elementStart)
+ else if (this.currentNode.kind == XMLKind.elementStart)
{
int count = 1;
static if (processBadDocument == No.processBadDocument)
{
- StringType currName = name;
+ StringType currName = this.name;
}
- while (count > 0 && !parser.empty)
+ while (count > 0 && !this.parser.empty)
{
- if (!advanceInput)
+ if (!this.advanceInput)
{
return false;
}
- if (currentNode.kind == XMLKind.elementStart)
+ if (this.currentNode.kind == XMLKind.elementStart)
{
count++;
}
- else if (currentNode.kind == XMLKind.elementEnd)
+ else if (this.currentNode.kind == XMLKind.elementEnd)
{
count--;
}
}
static if (processBadDocument == No.processBadDocument)
{
- enforce!CursorException(count == 0 && currName == name,
+ enforce!CursorException(count == 0 && currName == this.name,
"Document is malformed!");
}
}
- if (!advanceInput || currentNode.kind == XMLKind.elementEnd || currentNode.kind == XMLKind.dtdEnd)
+ if (!this.advanceInput || this.currentNode.kind == XMLKind.elementEnd
+ || this.currentNode.kind == XMLKind.dtdEnd)
{
- nextFailed = true;
+ this.nextFailed = true;
return false;
}
return true;
@@ -565,20 +580,20 @@ struct Cursor(P, Flag!"conflateCDATA" conflateCDATA = Yes.conflateCDATA,
/++ Returns the _kind of the current node. +/
XMLKind kind() const
{
- if (starting)
+ if (this.starting)
{
return XMLKind.document;
}
static if (conflateCDATA == Yes.conflateCDATA)
{
- if (currentNode.kind == XMLKind.cdata)
+ if (this.currentNode.kind == XMLKind.cdata)
{
return XMLKind.text;
}
}
- return currentNode.kind;
+ return this.currentNode.kind;
}
/++
@@ -588,32 +603,33 @@ struct Cursor(P, Flag!"conflateCDATA" conflateCDATA = Yes.conflateCDATA,
+/
StringType name()
{
- switch (currentNode.kind)
+ switch (this.currentNode.kind)
{
- case XMLKind.document:
- case XMLKind.text:
- case XMLKind.cdata:
- case XMLKind.comment:
- case XMLKind.declaration:
- case XMLKind.conditional:
- case XMLKind.dtdStart:
- case XMLKind.dtdEmpty:
- case XMLKind.dtdEnd:
- return [];
- default:
- if (!nameEnd)
+ case XMLKind.document:
+ case XMLKind.text:
+ case XMLKind.cdata:
+ case XMLKind.comment:
+ case XMLKind.declaration:
+ case XMLKind.conditional:
+ case XMLKind.dtdStart:
+ case XMLKind.dtdEmpty:
+ case XMLKind.dtdEnd:
+ return [];
+ default:
+ if (!this.nameEnd)
+ {
+ ptrdiff_t i, j;
+ if ((j = indexOfNeither(this.currentNode.content, " \r\n\t")) >= 0)
{
- ptrdiff_t i, j;
- if ((j = indexOfNeither(currentNode.content, " \r\n\t")) >= 0)
- {
- nameBegin = j;
- }
-
- nameEnd = ((i = indexOfAny(currentNode.content[nameBegin..$], " \r\n\t")) >= 0)
- ? i + nameBegin
- : currentNode.content.length;
+ this.nameBegin = j;
}
- return currentNode.content[nameBegin..nameEnd];
+
+ this.nameEnd = ((
+ i = indexOfAny(this.currentNode.content[this.nameBegin .. $],
+ " \r\n\t")) >= 0) ? i + this.nameBegin : this.currentNode
+ .content.length;
+ }
+ return this.currentNode.content[this.nameBegin .. this.nameEnd];
}
}
@@ -623,14 +639,15 @@ struct Cursor(P, Flag!"conflateCDATA" conflateCDATA = Yes.conflateCDATA,
+/
StringType localName()
{
- auto name = name();
- if (currentNode.kind == XMLKind.elementStart || currentNode.kind == XMLKind.elementEnd)
+ auto name = this.name();
+ if (this.currentNode.kind == XMLKind.elementStart
+ || this.currentNode.kind == XMLKind.elementEnd)
{
- if (colon == colon.max)
+ if (this.colon == colon.max)
{
- colon = indexOf(name, ':');
+ this.colon = indexOf(name, ':');
}
- return name[(colon+1)..$];
+ return name[this.colon + 1 .. $];
}
return name;
}
@@ -641,17 +658,16 @@ struct Cursor(P, Flag!"conflateCDATA" conflateCDATA = Yes.conflateCDATA,
+/
StringType prefix()
{
- if (currentNode.kind == XMLKind.elementStart || currentNode.kind == XMLKind.elementEnd)
+ if (this.currentNode.kind == XMLKind.elementStart
+ || this.currentNode.kind == XMLKind.elementEnd)
{
- auto name = name;
- if (colon == colon.max)
+ auto name = this.name();
+ if (this.colon == colon.max)
{
- colon = indexOf(name, ':');
+ this.colon = indexOf(name, ':');
}
- return colon >= 0
- ? name[0..colon]
- : [];
+ return this.colon >= 0 ? name[0 .. this.colon] : [];
}
return [];
}
@@ -663,13 +679,12 @@ struct Cursor(P, Flag!"conflateCDATA" conflateCDATA = Yes.conflateCDATA,
+/
auto attributes() @trusted
{
-
-
- auto kind = currentNode.kind;
- if (kind == XMLKind.elementStart || kind == XMLKind.elementEmpty || kind == XMLKind.processingInstruction)
+ auto kind = this.currentNode.kind;
+ if (kind == XMLKind.elementStart || kind == XMLKind.elementEmpty
+ || kind == XMLKind.processingInstruction)
{
- name();
- return AttributesRange(currentNode.content[nameEnd..$], this);
+ this.name();
+ return AttributesRange(this.currentNode.content[this.nameEnd .. $], this);
}
else
{
@@ -685,15 +700,18 @@ struct Cursor(P, Flag!"conflateCDATA" conflateCDATA = Yes.conflateCDATA,
{
switch (currentNode.kind)
{
- case XMLKind.entityDecl:
+ case XMLKind.entityDecl:
{
- sizediff_t b = indexOfAny(currentNode.content[nameEnd..$], "\"\'");
- sizediff_t e = lastIndexOf(currentNode.content[nameEnd..$], currentNode.content[b + nameEnd]);
+ sizediff_t b = indexOfAny(this.currentNode.content[this.nameEnd .. $],
+ "\"\'");
+ sizediff_t e = lastIndexOf(
+ this.currentNode.content[this.nameEnd .. $],
+ this.currentNode.content[b + this.nameEnd]);
+
if (b > 0 && e > 0)
{
- return b + 1 <= e
- ? currentNode.content[nameEnd + b + 1..nameEnd + e]
- : null;
+ return b + 1 <= e ? this.currentNode.content[this.nameEnd + b
+ + 1 .. this.nameEnd + e] : null;
}
else
{
@@ -707,9 +725,10 @@ struct Cursor(P, Flag!"conflateCDATA" conflateCDATA = Yes.conflateCDATA,
}
}
}
- case XMLKind.dtdStart, XMLKind.dtdEmpty:
+ case XMLKind.dtdStart, XMLKind.dtdEmpty:
{
- sizediff_t b = indexOfNeither(currentNode.content[nameEnd..$], " \r\n\t");
+ sizediff_t b = indexOfNeither(this.currentNode.content[this
+ .nameEnd .. $], " \r\n\t");
static if (processBadDocument == No.processBadDocument)
{
enforce!CursorException(b >= 0, "Document Type Declaration lacks name.");
@@ -721,42 +740,43 @@ struct Cursor(P, Flag!"conflateCDATA" conflateCDATA = Yes.conflateCDATA,
return null;
}
}
- sizediff_t e = indexOfAny(currentNode.content[nameEnd + b..$], " \r\n\t");
- if (e <= 0)
- {
- e = currentNode.content.length;
- }
- else
- {
- e++;
- }
- return currentNode.content[nameEnd + b..e];
+ sizediff_t e = indexOfAny(this.currentNode.content[this.nameEnd + b .. $],
+ " \r\n\t");
+
+ e = e <= 0 ? this.currentNode.content.length : e + 1;
+
+ return this.currentNode.content[nameEnd + b .. e];
}
- case XMLKind.text:
- { //TO DO: This might have a performance impact if called multiple times.
+ case XMLKind.text:
+ { //TO DO: This might have a performance impact if called multiple times.
static if (processBadDocument == No.processBadDocument)
{
- StringType result = xmlUnescape(currentNode.content[nameEnd..$], chrEntities);
- if (xmlVersion == XMLVersion.XML1_0)
+ StringType result = xmlUnescape(
+ this.currentNode.content[this.nameEnd .. $],
+ this.chrEntities);
+ if (this.xmlVersion == XMLVersion.XML1_0)
{
- enforce!CursorException(isValidXMLText10(currentNode.content),
+ enforce!CursorException(
+ isValidXMLText10(this.currentNode.content),
"Text contains invalid characters!");
}
else
{
- enforce!CursorException(isValidXMLText11(currentNode.content),
+ enforce!CursorException(
+ isValidXMLText11(this.currentNode.content),
"Text contains invalid characters!");
}
return result;
}
else
{
- return xmlUnescape!(No.strict)(currentNode.content[nameEnd..$], chrEntities);
+ return xmlUnescape!(No.strict)(
+ this.currentNode.content[this.nameEnd .. $], chrEntities);
}
}
- default:
+ default:
{
- return currentNode.content[nameEnd..$];
+ return this.currentNode.content[this.nameEnd .. $];
}
}
}
@@ -764,7 +784,7 @@ struct Cursor(P, Flag!"conflateCDATA" conflateCDATA = Yes.conflateCDATA,
/++ Returns the entire text of the current node. +/
StringType wholeContent() const
{
- return currentNode.content;
+ return this.currentNode.content;
}
}
@@ -779,8 +799,7 @@ template cursor(Flag!"conflateCDATA" conflateCDATA = Yes.conflateCDATA)
{
return cursor(parser);
} */
- auto cursor(T)(auto ref T parser)
- if(isLowLevelParser!T)
+ auto cursor(T)(auto ref T parser) if (isLowLevelParser!T)
{
auto cursor = Cursor!(T, conflateCDATA)();
cursor.parser = parser;
@@ -792,7 +811,7 @@ template cursor(Flag!"conflateCDATA" conflateCDATA = Yes.conflateCDATA)
}
}
-unittest
+pure unittest
{
import newxml.lexers;
import newxml.parser;
@@ -830,111 +849,115 @@ unittest
assert(cursor.name() == "xml");
assert(cursor.prefix() == "");
assert(cursor.localName() == "xml");
- assert(cursor.attributes().array == [Attribute!wstring("encoding", "utf-8")]);
+ assert(cursor.attributes().array == [
+ Attribute!wstring("encoding", "utf-8")
+ ]);
assert(cursor.content() == " encoding = \"utf-8\" ");
assert(cursor.enter());
- assert(!cursor.atBeginning);
+ assert(!cursor.atBeginning);
- //
- assert(cursor.kind == XMLKind.elementDecl);
- assert(cursor.wholeContent == " myelem ANY");
+ assert(cursor.enter);
+ //
+ assert(cursor.kind == XMLKind.elementDecl);
+ assert(cursor.wholeContent == " myelem ANY");
+
+ assert(cursor.next);
+ //
+ assert(cursor.kind == XMLKind.entityDecl);
+ assert(cursor.wholeContent == " myent \"replacement text\"");
+ assert(cursor.name == "myent");
+ assert(cursor.content == "replacement text", to!string(cursor.content));
+
+ assert(cursor.next);
+ //
+ assert(cursor.kind == XMLKind.attlistDecl);
+ assert(cursor.wholeContent == " myelem foo cdata #REQUIRED ");
+
+ assert(cursor.next);
+ //
+ assert(cursor.kind == XMLKind.notationDecl);
+ assert(cursor.wholeContent == " PUBLIC 'h'");
+
+ assert(cursor.next);
+ //
+ assert(cursor.kind == XMLKind.declaration);
+ assert(cursor.wholeContent == "FOODECL asdffdsa ");
+
+ assert(!cursor.next);
+
+ //assert(cursor.parser._chrEntities["myent"] == "replacement text");
+ cursor.exit;
- assert(cursor.next);
- //
- assert(cursor.kind == XMLKind.entityDecl);
- assert(cursor.wholeContent == " myent \"replacement text\"");
- assert(cursor.name == "myent");
- assert(cursor.content == "replacement text", to!string(cursor.content));
+ // ]>
+ assert(cursor.kind == XMLKind.dtdEnd);
+ assert(!cursor.wholeContent);
+ assert(cursor.next);
- assert(cursor.next);
- //
- assert(cursor.kind == XMLKind.attlistDecl);
- assert(cursor.wholeContent == " myelem foo cdata #REQUIRED ");
+ //
+ assert(cursor.kind() == XMLKind.elementStart);
+ assert(cursor.name() == "aaa");
+ assert(cursor.prefix() == "");
+ assert(cursor.localName() == "aaa");
+ assert(cursor.attributes().array == [
+ Attribute!wstring("xmlns:myns", "something")
+ ]);
+ assert(cursor.content() == " xmlns:myns=\"something\"");
- assert(cursor.next);
- //
- assert(cursor.kind == XMLKind.notationDecl);
- assert(cursor.wholeContent == " PUBLIC 'h'");
+ assert(cursor.enter());
+ //
+ assert(cursor.kind() == XMLKind.elementStart);
+ assert(cursor.name() == "myns:bbb");
+ assert(cursor.prefix() == "myns");
+ assert(cursor.localName() == "bbb");
+ assert(cursor.attributes().array == [Attribute!wstring("myns:att", ">")]);
+ assert(cursor.content() == " myns:att='>'");
- assert(cursor.next);
- //
- assert(cursor.kind == XMLKind.declaration);
- assert(cursor.wholeContent == "FOODECL asdffdsa ");
+ assert(cursor.enter());
+ cursor.exit();
- assert(!cursor.next);
+ //
+ assert(cursor.kind() == XMLKind.elementEnd);
+ assert(cursor.name() == "myns:bbb");
+ assert(cursor.prefix() == "myns");
+ assert(cursor.localName() == "bbb");
+ assert(cursor.attributes().empty);
+ assert(cursor.content() == []);
+
+ assert(cursor.next());
+ //
+ assert(cursor.kind() == XMLKind.text);
+ assert(cursor.name() == "");
+ assert(cursor.prefix() == "");
+ assert(cursor.localName() == "");
+ assert(cursor.attributes().empty);
+ assert(cursor.content() == " Ciaone! ");
+
+ assert(cursor.next());
+ //
+ assert(cursor.kind() == XMLKind.elementEmpty);
+ assert(cursor.name() == "ccc");
+ assert(cursor.prefix() == "");
+ assert(cursor.localName() == "ccc");
+ assert(cursor.attributes().empty);
+ assert(cursor.content() == []);
- //assert(cursor.parser._chrEntities["myent"] == "replacement text");
- cursor.exit;
+ assert(!cursor.next());
+ cursor.exit();
- // ]>
- assert(cursor.kind == XMLKind.dtdEnd);
- assert(!cursor.wholeContent);
- assert(cursor.next);
+ //
+ assert(cursor.kind() == XMLKind.elementEnd);
+ assert(cursor.name() == "aaa");
+ assert(cursor.prefix() == "");
+ assert(cursor.localName() == "aaa");
+ assert(cursor.attributes().empty);
+ assert(cursor.content() == []);
- //
- assert(cursor.kind() == XMLKind.elementStart);
- assert(cursor.name() == "aaa");
- assert(cursor.prefix() == "");
- assert(cursor.localName() == "aaa");
- assert(cursor.attributes().array == [Attribute!wstring("xmlns:myns", "something")]);
- assert(cursor.content() == " xmlns:myns=\"something\"");
-
- assert(cursor.enter());
- //
- assert(cursor.kind() == XMLKind.elementStart);
- assert(cursor.name() == "myns:bbb");
- assert(cursor.prefix() == "myns");
- assert(cursor.localName() == "bbb");
- assert(cursor.attributes().array == [Attribute!wstring("myns:att", ">")]);
- assert(cursor.content() == " myns:att='>'");
-
- assert(cursor.enter());
- cursor.exit();
-
- //
- assert(cursor.kind() == XMLKind.elementEnd);
- assert(cursor.name() == "myns:bbb");
- assert(cursor.prefix() == "myns");
- assert(cursor.localName() == "bbb");
- assert(cursor.attributes().empty);
- assert(cursor.content() == []);
-
- assert(cursor.next());
- //
- assert(cursor.kind() == XMLKind.text);
- assert(cursor.name() == "");
- assert(cursor.prefix() == "");
- assert(cursor.localName() == "");
- assert(cursor.attributes().empty);
- assert(cursor.content() == " Ciaone! ");
-
- assert(cursor.next());
- //
- assert(cursor.kind() == XMLKind.elementEmpty);
- assert(cursor.name() == "ccc");
- assert(cursor.prefix() == "");
- assert(cursor.localName() == "ccc");
- assert(cursor.attributes().empty);
- assert(cursor.content() == []);
-
- assert(!cursor.next());
- cursor.exit();
-
- //
- assert(cursor.kind() == XMLKind.elementEnd);
- assert(cursor.name() == "aaa");
- assert(cursor.prefix() == "");
- assert(cursor.localName() == "aaa");
- assert(cursor.attributes().empty);
- assert(cursor.content() == []);
-
- assert(!cursor.next());
+ assert(!cursor.next());
cursor.exit();
assert(cursor.documentEnd);
@@ -947,27 +970,38 @@ unittest
+ Advancing the range returned by this function also advances `cursor`. It is thus
+ not recommended to interleave usage of this function with raw usage of `cursor`.
+/
-auto children(T)(ref T cursor) @trusted
- if (isCursor!T)
+auto children(T)(ref T cursor) @trusted if (isCursor!T)
{
struct XMLRange
{
T* cursor;
bool endReached;
- bool empty() const { return endReached; }
- void popFront() { endReached = !cursor.next(); }
- ref T front() { return *cursor; }
+ bool empty() const
+ {
+ return this.endReached;
+ }
- ~this() { cursor.exit; }
- }
- auto workaround() @system {
- return XMLRange(&cursor, cursor.enter);
+ void popFront()
+ {
+ this.endReached = !this.cursor.next();
+ }
+
+ ref T front()
+ {
+ return *this.cursor;
+ }
+
+ ~this()
+ {
+ this.cursor.exit;
+ }
}
- return workaround();
+
+ return XMLRange(&cursor, cursor.enter);
}
-unittest
+pure unittest
{
import newxml.lexers;
import newxml.parser;
@@ -1062,7 +1096,9 @@ unittest
assert(range3.front.localName() == "");
assert(range3.front.attributes().empty);
// split and strip so the unittest does not depend on the newline policy or indentation of this file
- static immutable linesArr = ["Lots of Text!", " On multiple lines!", " "];
+ static immutable linesArr = [
+ "Lots of Text!", " On multiple lines!", " "
+ ];
assert(range3.front.content().lineSplitter.equal(linesArr));
range3.popFront;
@@ -1125,18 +1161,16 @@ import std.traits : isArray;
+ `copyingCursor`.
+/
struct CopyingCursor(CursorType, Flag!"intern" intern = No.intern)
- if (isCursor!CursorType && isArray!(CursorType.StringType))
+ if (isCursor!CursorType && isArray!(CursorType.StringType))
{
alias StringType = CursorType.StringType;
- //mixin UsesAllocator!Alloc;
-
CursorType cursor;
alias cursor this;
static if (intern == Yes.intern)
{
- import std.typecons: Rebindable;
+ import std.typecons : Rebindable;
Rebindable!(immutable StringType)[const StringType] interned;
}
@@ -1145,7 +1179,7 @@ struct CopyingCursor(CursorType, Flag!"intern" intern = No.intern)
{
static if (intern == Yes.intern)
{
- auto match = str in interned;
+ auto match = str in this.interned;
if (match)
{
return *match;
@@ -1153,14 +1187,12 @@ struct CopyingCursor(CursorType, Flag!"intern" intern = No.intern)
}
import std.traits : Unqual;
- import std.experimental.allocator;//import stdx.allocator;
+ import std.experimental.allocator; //import stdx.allocator;
import std.range.primitives : ElementEncodingType;
import core.stdc.string : memcpy;
alias ElemType = ElementEncodingType!StringType;
- ElemType[] cp;//auto cp = cast(ElemType[]) allocator.makeArray!(Unqual!ElemType)(str.length);
- cp.length = str.length;
- memcpy(cast(void*)cp.ptr, cast(void*)str.ptr, str.length * ElemType.sizeof);
+ ElemType[] cp = str.dup;
static if (intern == Yes.intern)
{
@@ -1172,23 +1204,27 @@ struct CopyingCursor(CursorType, Flag!"intern" intern = No.intern)
auto name() @trusted
{
- return copy(cursor.name);
+ return copy(this.cursor.name);
}
+
auto localName() @trusted
{
- return copy(cursor.localName);
+ return copy(this.cursor.localName);
}
+
auto prefix() @trusted
{
- return copy(cursor.prefix);
+ return copy(this.cursor.prefix);
}
+
auto content() @trusted
{
- return copy(cursor.content);
+ return copy(this.cursor.content);
}
+
auto wholeContent() @trusted
{
- return copy(cursor.wholeContent);
+ return copy(this.cursor.wholeContent);
}
auto attributes() @trusted
@@ -1202,14 +1238,13 @@ struct CopyingCursor(CursorType, Flag!"intern" intern = No.intern)
auto front()
{
- auto attr = attrs.front;
- return Attribute!StringType(
- parent.copy(attr.name),
- parent.copy(attr.value),
- );
+ auto attr = this.attrs.front;
+ return Attribute!StringType(parent.copy(attr.name), parent.copy(attr
+ .value),);
}
}
- return CopyRange(cursor.attributes, &this);
+
+ return CopyRange(this.cursor.attributes, &this);
}
}
@@ -1223,12 +1258,11 @@ auto copyingCursor(Flag!"intern" intern = No.intern, CursorType)(auto ref Cursor
return res;
}
-unittest
+pure unittest
{
import newxml.lexers;
import newxml.parser;
-
wstring xml = q{
@@ -1240,9 +1274,7 @@ unittest
};
- auto cursor =
- xml
- .lexer
+ auto cursor = xml.lexer
.parser
.cursor!(Yes.conflateCDATA)
.copyingCursor!(Yes.intern)();
diff --git a/source/newxml/dom.d b/source/newxml/dom.d
index 5e74b5b..7f9791b 100644
--- a/source/newxml/dom.d
+++ b/source/newxml/dom.d
@@ -27,7 +27,6 @@
module newxml.dom;
import newxml.interfaces;
-public import newxml.domstring;
import std.typecons : BitFlags;
import std.variant : Variant;
@@ -43,7 +42,7 @@ alias UserData = Variant;
+ the application to implement various behaviors regarding the data it associates
+ to the DOM nodes.
+/
-alias UserDataHandler = void delegate(UserDataOperation, DOMString, UserData, Node, Node) @safe;
+alias UserDataHandler = void delegate(UserDataOperation, string, UserData, Node, Node) @safe;
/++
+ An integer indicating which type of node this is.
@@ -51,7 +50,7 @@ alias UserDataHandler = void delegate(UserDataOperation, DOMString, UserData, No
+ Note:
+ Numeric codes up to 200 are reserved to W3C for possible future use.
+/
-enum NodeType: ushort
+enum NodeType : ushort
{
element = 1,
attribute,
@@ -71,18 +70,18 @@ enum NodeType: ushort
+ A bitmask indicating the relative document position of a node with respect to another node.
+ Returned by `Node.compareDocumentPosition`.
+/
-enum DocumentPosition: ushort
+enum DocumentPosition : ushort
{
/// Set when the two nodes are in fact the same
- none = 0,
+ none = 0,
/// Set when the two nodes are not in the same tree
disconnected = 1,
/// Set when the second node precedes the first
- preceding = 2,
+ preceding = 2,
/// Set when the second node follows the first
- following = 4,
+ following = 4,
/// Set when the second node _contains the first
- contains = 8,
+ contains = 8,
/// Set when the second node is contained by the first
containedBy = 16,
/++
@@ -98,7 +97,7 @@ enum DocumentPosition: ushort
/++
+ An integer indicating the type of operation being performed on a node.
+/
-enum UserDataOperation: ushort
+enum UserDataOperation : ushort
{
/// The node is cloned, using `Node.cloneNode()`.
nodeCloned = 1,
@@ -124,11 +123,11 @@ enum UserDataOperation: ushort
+ Note:
+ Other numeric codes are reserved for W3C for possible future use.
+/
-enum ExceptionCode: ushort
+enum ExceptionCode : ushort
{
/// If index or size is negative, or greater than the allowed value.
indexSize,
- /// If the specified range of text does not fit into a `DOMString`.
+ /// If the specified range of text does not fit into a `string`.
domStringSize,
/// If any `Node` is inserted somewhere it doesn't belong.
hierarchyRequest,
@@ -163,7 +162,7 @@ enum ExceptionCode: ushort
}
/// An integer indicating the severity of a `DOMError`.
-enum ErrorSeverity: ushort
+enum ErrorSeverity : ushort
{
/++
+ The severity of the error described by the `DOMError` is warning. A `WARNING`
@@ -186,13 +185,14 @@ enum ErrorSeverity: ushort
fatalError,
}
-enum DerivationMethod: ulong
+enum DerivationMethod : ulong
{
restriction = 0x00000001,
- extension = 0x00000002,
- union_ = 0x00000004,
- list = 0x00000008,
+ extension = 0x00000002,
+ union_ = 0x00000004,
+ list = 0x00000008,
}
+
@safe:
/++
+ DOM operations only raise exceptions in "exceptional" circumstances, i.e.,
@@ -205,35 +205,37 @@ enum DerivationMethod: ulong
+ example, implementations should raise an implementation-dependent exception
+ if a `null` argument is passed when `null` was not expected.
+/
-abstract class DOMException: XMLException
+abstract class DOMException : XMLException
{
///
@property ExceptionCode code();
///
- @nogc @safe pure nothrow this(string msg, string file = __FILE__, size_t line = __LINE__,
- Throwable nextInChain = null)
+ @nogc @safe pure nothrow this(string msg, string file = __FILE__,
+ size_t line = __LINE__, Throwable nextInChain = null)
{
super(msg, file, line, nextInChain);
}
- @nogc @safe pure nothrow this(string msg, Throwable nextInChain, string file = __FILE__, size_t line = __LINE__)
+ @nogc @safe pure nothrow this(string msg, Throwable nextInChain,
+ string file = __FILE__, size_t line = __LINE__)
{
super(msg, file, line, nextInChain);
}
}
/++
-+ The `DOMStringList` interface provides the abstraction of an ordered collection
-+ of `DOMString` values, without defining or constraining how this collection is
-+ implemented. The items in the DOMStringList are accessible via an integral index,
++ The `stringList` interface provides the abstraction of an ordered collection
++ of `string` values, without defining or constraining how this collection is
++ implemented. The items in the stringList are accessible via an integral index,
+ starting from `0`.
+/
-interface DOMStringList {
- DOMString item(size_t index);
+interface stringList
+{
+ string item(size_t index);
@property size_t length();
- bool contains(DOMString str);
-};
+ bool contains(string str);
+}
/++
+ The `DOMImplementationList` interface provides the abstraction of an ordered
@@ -241,44 +243,53 @@ interface DOMStringList {
+ collection is implemented. The items in the `DOMImplementationList` are accessible
+ via an integral index, starting from `0`.
+/
-interface DOMImplementationList {
+interface DOMImplementationList
+{
DOMImplementation item(size_t index);
@property size_t length();
}
/++
-+ This interface permits a DOM implementer to supply one or more implementations,
-+ based upon requested features and versions, as specified in DOM Features.
-+ Each implemented DOMImplementationSource object is listed in the binding-specific
-+ list of available sources so that its `DOMImplementation` objects are made available.
++ This interface permits a DOM implementer to supply one or more
++ implementations, based upon requested features and versions, as specified in
++ DOM Features. Each implemented DOMImplementationSource object is listed in
++ the binding-specific list of available sources so that its
++ `DOMImplementation` objects are made available.
+/
-interface DOMImplementationSource {
- /// A method to request the first DOM implementation that supports the specified features.
- DOMImplementation getDOMImplementation(DOMString features);
- /// A method to request a list of DOM implementations that support the specified features and versions, as specified in DOM Features.
- DOMImplementationList getDOMImplementationList(DOMString features);
+interface DOMImplementationSource
+{
+ /// A method to request the first DOM implementation that supports the
+ /// specified features.
+ DOMImplementation getDOMImplementation(string features);
+ /// A method to request a list of DOM implementations that support the
+ /// specified features and versions, as specified in DOM Features.
+ DOMImplementationList getDOMImplementationList(string features);
}
/++
+ The DOMImplementation interface provides a number of methods for performing
-+ operations that are independent of any particular instance of the document object model.
++ operations that are independent of any particular instance of the document
++ object model.
+/
-interface DOMImplementation {
+interface DOMImplementation
+{
/++
- + Creates an empty DocumentType node. Entity declarations and notations are not
- + made available. Entity reference expansions and default attribute additions do not occur.
+ + Creates an empty DocumentType node. Entity declarations and notations
+ + are not made available. Entity reference expansions and default
+ + attribute additions do not occur.
+/
- DocumentType createDocumentType(DOMString qualifiedName, DOMString publicId, DOMString systemId);
+ DocumentType createDocumentType(string qualifiedName, string publicId, string systemId);
/++
+ Creates a DOM Document object of the specified type with its document element.
+
- + Note that based on the DocumentType given to create the document, the implementation
- + may instantiate specialized Document objects that support additional features than the "Core",
- + such as "HTML". On the other hand, setting the DocumentType after the document
- + was created makes this very unlikely to happen.
+ + Note that based on the DocumentType given to create the document, the
+ + implementation may instantiate specialized Document objects that support
+ + additional features than the "Core", such as "HTML". On the other hand,
+ + setting the DocumentType after the document was created makes this very
+ + unlikely to happen.
+/
- Document createDocument(DOMString namespaceURI, DOMString qualifiedName, DocumentType doctype);
+ Document createDocument(string namespaceURI, string qualifiedName, DocumentType doctype);
bool hasFeature(string feature, string version_);
Object getFeature(string feature, string version_);
@@ -314,7 +325,8 @@ interface DOMImplementation {
+ acts as the parent of these nodes so that the user can use the standard methods
+ from the `Node` interface, such as `Node.insertBefore` and `Node.appendChild`.
+/
-interface DocumentFragment : Node {
+interface DocumentFragment : Node
+{
}
/++
@@ -327,7 +339,8 @@ interface DocumentFragment : Node {
+ a `ownerDocument` attribute which associates them with the `Document` within
+ whose context they were created.
+/
-interface Document : Node {
+interface Document : Node
+{
/++
+ The `DocumentType` associated with this document. For XML documents without a
+ document type declaration this returns `null`.
@@ -356,53 +369,53 @@ interface Document : Node {
+ To create an `Element` with a qualified name and namespace URI, use the
+ `createElementNS` method.
+/
- Element createElement(DOMString tagName);
+ Element createElement(string tagName);
/++
+ Creates an `Element` of the given qualified name and namespace URI.
+ Per the XML Namespaces specification, applications must use the value `null`
+ as the `namespaceURI` parameter for methods if they wish to have no namespace.
+/
- Element createElementNS(DOMString namespaceURI, DOMString qualifiedName);
+ Element createElementNS(string namespaceURI, string qualifiedName);
/// Creates an empty `DocumentFragment` object.
DocumentFragment createDocumentFragment();
/// Creates a `Text` node given the specified string.
- Text createTextNode(DOMString data);
+ Text createTextNode(string data);
/// Creates a `Comment` node given the specified string.
- Comment createComment(DOMString data);
+ Comment createComment(string data);
/// Creates a `CDATASection` node whose value is the specified string.
- CDATASection createCDATASection(DOMString data);
+ CDATASection createCDATASection(string data);
/// Creates a `ProcessingInstruction` node given the specified name and data strings.
- ProcessingInstruction createProcessingInstruction(DOMString target, DOMString data);
+ ProcessingInstruction createProcessingInstruction(string target, string data);
/++
+ Creates an `Attr` of the given name. Note that the `Attr` instance can
+ then be set on an `Element` using the `setAttributeNode` method.
+ To create an attribute with a qualified name and namespace URI, use the
+ `createAttributeNS` method.
+/
- Attr createAttribute(DOMString name);
+ Attr createAttribute(string name);
/++
+ Creates an attribute of the given qualified name and namespace URI.
+ Per the XML Namespaces specification, applications must use the value `null`
+ as the `namespaceURI` parameter for methods if they wish to have no namespace.
+/
- Attr createAttributeNS(DOMString namespaceURI, DOMString qualifiedName);
+ Attr createAttributeNS(string namespaceURI, string qualifiedName);
/++
+ Creates an `EntityReference` object. In addition, if the referenced entity
+ is known, the child list of the `EntityReference` node is made the same as
+ that of the corresponding `Entity` node.
+/
- EntityReference createEntityReference(DOMString name);
+ EntityReference createEntityReference(string name);
/++
+ Returns a `NodeList` of all the `Element`s in document order with a given
+ tag name and are contained in the document.
+/
- NodeList getElementsByTagName(DOMString tagname);
+ NodeList getElementsByTagName(string tagname);
/++
+ Returns a `NodeList` of all the `Element`s with a given local name and
+ namespace URI in document order.
+/
- NodeList getElementsByTagNameNS(DOMString namespaceURI, DOMString localName);
+ NodeList getElementsByTagNameNS(string namespaceURI, string localName);
/++
+ Returns the `Element` that has an ID attribute with the given value. If no
+ such element exists, this returns `null`. If more than one element has an
@@ -412,7 +425,7 @@ interface Document : Node {
+
+ Note: Attributes with the name "ID" or "id" are not of type ID unless so defined.
+/
- Element getElementById(DOMString elementId);
+ Element getElementById(string elementId);
/++
+ Imports a node from another document to this document, without altering or
@@ -440,13 +453,13 @@ interface Document : Node {
+ the parsing. This is `null` when it is not known, such as when the `Document`
+ was created in memory.
+/
- @property DOMString inputEncoding();
+ @property string inputEncoding();
/++
+ An attribute specifying, as part of the XML declaration, the encoding of
+ this document. This is `null` when unspecified or when it is not known,
+ such as when the Document was created in memory.
+/
- @property DOMString xmlEncoding();
+ @property string xmlEncoding();
/++
+ An attribute specifying, as part of the XML declaration, whether this document
@@ -462,9 +475,9 @@ interface Document : Node {
+ the "XML" feature, the value is "1.0". If this document does not support
+ the "XML" feature, the value is always `null`.
+/
- @property DOMString xmlVersion();
+ @property string xmlVersion();
/// ditto
- @property void xmlVersion(DOMString);
+ @property void xmlVersion(string);
/++
+ An attribute specifying whether error checking is enforced or not.
@@ -483,9 +496,9 @@ interface Document : Node {
+ is performed when setting this attribute; this could result in a `null`
+ value returned when using `Node.baseURI`.
+/
- @property DOMString documentURI();
+ @property string documentURI();
/// ditto
- @property void documentURI(DOMString);
+ @property void documentURI(string);
/// The configuration used when `Document.normalizeDocument()` is invoked.
@property DOMConfiguration domConfig();
@@ -512,7 +525,7 @@ interface Document : Node {
+ nodes list if it has one, the user data that was attached to the old node
+ is attached to the new node.
+/
- Node renameNode(Node n, DOMString namespaceURI, DOMString qualifiedName);
+ Node renameNode(Node n, string namespaceURI, string qualifiedName);
}
/++
@@ -530,18 +543,19 @@ interface Document : Node {
+ Note that the specialized interfaces may contain additional and more convenient
+ mechanisms to get and set the relevant information.
+/
-interface Node {
+interface Node
+{
/// A code representing the type of the underlying object.
@property NodeType nodeType();
/// The name of this node, depending on its type.
- @property DOMString nodeName();
+ @property string nodeName();
/++
+ Returns the local part of the qualified name of this node.
+
+ For nodes of any type other than `ELEMENT` and `ATTRIBUTE` and nodes created
+ with a DOM Level 1 method, such as `Document.createElement`, this is always `null`.
+/
- @property DOMString localName();
+ @property string localName();
/++
+ The namespace prefix of this node, or `null` if it is unspecified.
+ When it is defined to be `null`, setting it has no effect, including if
@@ -558,9 +572,9 @@ interface Node {
+ with a DOM Level 1 method, such as `createElement` from the `Document`
+ interface, this is always `null`.
+/
- @property DOMString prefix();
+ @property string prefix();
/// ditto
- @property void prefix(DOMString);
+ @property void prefix(string);
/++
+ The namespace URI of this node, or `null` if it is unspecified.
+ This is not a computed value that is the result of a namespace lookup based
@@ -569,18 +583,18 @@ interface Node {
+ For nodes of any type other than `ELEMENT` and `ATTRIBUTE` and nodes created
+ with a DOM Level 1 method, such as `Document.createElement`, this is always `null`.
+/
- @property DOMString namespaceURI();
+ @property string namespaceURI();
/// The absolute base URI of this node or null if the implementation wasn't able to obtain an absolute URI
- @property DOMString baseURI();
+ @property string baseURI();
/// The value of this node, depending on its type.
- @property DOMString nodeValue();
+ @property string nodeValue();
/// ditto
- @property void nodeValue(DOMString);
+ @property void nodeValue(string);
/// Returns the text content, if there's any.
- @property DOMString textContent();
+ @property string textContent();
/// Sets the text content, it there's any.
- @property void textContent(DOMString);
+ @property void textContent(string);
/++
+ The parent of this node. All nodes, except `Attr`, `Document`, `DocumentFragment`,
@@ -663,12 +677,12 @@ interface Node {
+ Retrieves the object associated to a key on a this node. The object must
+ first have been set to this node by calling `setUserData` with the same key.
+/
- UserData getUserData(string key) @trusted ;
+ UserData getUserData(string key) @trusted;
/++
+ Associate an object to a key on this node.
+ The object can later be retrieved from this node by calling `getUserData` with the same key.
+/
- UserData setUserData(string key, UserData data, UserDataHandler handler) @trusted ;
+ UserData setUserData(string key, UserData data, UserDataHandler handler) @trusted;
/++
+ Compares the reference node, i.e. the node on which this method is being
@@ -681,11 +695,11 @@ interface Node {
+ Look up the prefix associated to the given namespace URI, starting from this node.
+ The default namespace declarations are ignored by this method.
+/
- DOMString lookupPrefix(DOMString namespaceURI);
+ string lookupPrefix(string namespaceURI);
/// Look up the namespace URI associated to the given `prefix`, starting from this node.
- DOMString lookupNamespaceURI(DOMString prefix);
+ string lookupNamespaceURI(string prefix);
/// This method checks if the specified `namespaceURI` is the default namespace or not.
- bool isDefaultNamespace(DOMString namespaceURI);
+ bool isDefaultNamespace(string namespaceURI);
}
/++
@@ -695,7 +709,8 @@ interface Node {
+
+ The items in the `NodeList` are accessible via an integral index, starting from `0`.
+/
-interface NodeList {
+interface NodeList
+{
/++
+ Returns the `index`th item in the collection. If `index` is greater than
+ or equal to the number of nodes in the list, this returns `null`.
@@ -732,7 +747,8 @@ interface NodeList {
+
+ `NamedNodeMap` objects in the DOM are live.
+/
-interface NamedNodeMap {
+interface NamedNodeMap
+{
/++
+ Returns the `index`th item in the collection. If `index` is greater than
+ or equal to the number of nodes in the list, this returns `null`.
@@ -757,12 +773,13 @@ interface NamedNodeMap {
return 0;
}
- final Node opIndex(size_t index) {
+ final Node opIndex(size_t index)
+ {
return item(index);
}
/// Retrieves a node specified by name.
- Node getNamedItem(DOMString name);
+ Node getNamedItem(string name);
/++
+ Adds a node using its `nodeName` attribute. If a node with that name is
+ already present in this map, it is replaced by the new one. Replacing a
@@ -779,14 +796,14 @@ interface NamedNodeMap {
+ value, an attribute immediately appears containing the default value as
+ well as the corresponding namespace URI, local name, and prefix when applicable.
+/
- Node removeNamedItem(DOMString name);
+ Node removeNamedItem(string name);
/++
+ Retrieves a node specified by local name and namespace URI.
+ Per the XML Namespaces specification, applications must use the value `null`
+ as the `namespaceURI` parameter for methods if they wish to have no namespace.
+/
- Node getNamedItemNS(DOMString namespaceURI, DOMString localName);
+ Node getNamedItemNS(string namespaceURI, string localName);
/++
+ Adds a node using its `namespaceURI` and `localName`. If a node with that
+ namespace URI and that local name is already present in this map, it is
@@ -804,7 +821,7 @@ interface NamedNodeMap {
+ Per the XML Namespaces specification, applications must use the value `null`
+ as the `namespaceURI` parameter for methods if they wish to have no namespace.
+/
- Node removeNamedItemNS(DOMString namespaceURI, DOMString localName);
+ Node removeNamedItemNS(string namespaceURI, string localName);
}
/++
@@ -814,25 +831,26 @@ interface NamedNodeMap {
+ correspond directly to `CharacterData`, though `Text` and others do inherit
+ the interface from it. All offsets in this interface start from `0`.
+/
-interface CharacterData : Node {
- @property DOMString data();
- @property void data(DOMString);
+interface CharacterData : Node
+{
+ @property string data();
+ @property void data(string);
@property size_t length();
/// Extracts a substring of `data` starting at `offset`, with length `count`.
- DOMString substringData(size_t offset, size_t count);
+ string substringData(size_t offset, size_t count);
/++
+ Append the string to the end of the character data of the node. Upon success,
- + data provides access to the concatenation of data and the DOMString specified.
+ + data provides access to the concatenation of data and the string specified.
+/
- void appendData(DOMString arg);
+ void appendData(string arg);
/// Insert a string at the specified offset.
- void insertData(size_t offset, DOMString arg);
+ void insertData(size_t offset, string arg);
/// Remove a range of characters from the node. Upon success, `data` and `length` reflect the change.
void deleteData(size_t offset, size_t count);
/// Replace `count` characters starting at the specified offset with the specified string.
- void replaceData(size_t offset, size_t count, DOMString arg);
+ void replaceData(size_t offset, size_t count, string arg);
}
/++
@@ -852,12 +870,13 @@ interface CharacterData : Node {
+ DOM need to be aware that `Attr` nodes have some things in common with other
+ objects inheriting the `Node` interface, but they also are quite distinct.
+/
-interface Attr : Node {
+interface Attr : Node
+{
/++
+ Returns the _name of this attribute. If `Node.localName` is different from
+ `null`, this attribute is a qualified name.
+/
- @property DOMString name();
+ @property string name();
/++
+ `true` if this attribute was explicitly given a value in the instance document,
+ `false` otherwise. If the application changed the value of this attribute
@@ -868,7 +887,7 @@ interface Attr : Node {
+/
@property bool specified();
/++
- + On retrieval, the value of the attribute is returned as a `DOMString`.
+ + On retrieval, the value of the attribute is returned as a `string`.
+ Character and general entity references are replaced with their values.
+ See also the method `getAttribute` on the `Element` interface.
+ On setting, this creates a `Text` node with the unparsed contents of the
@@ -876,9 +895,9 @@ interface Attr : Node {
+ are instead treated as literal text.
+ See also the method `Element.setAttribute`.
+/
- @property DOMString value();
+ @property string value();
/// ditto
- @property void value(DOMString);
+ @property void value(string);
/// The `Element` node this attribute is attached to or `null` if this attribute is not in use.
@property Element ownerElement();
@@ -897,16 +916,18 @@ interface Attr : Node {
+/
@property bool isId();
}
+
/**
* Elements are the main building block of an XML document. They have a name, an associated namespace, attributes,
* text, and child elements.
*/
-interface Element : Node {
+interface Element : Node
+{
/// The name of the element. If `Node.localName` is different from `null`, this attribute is a qualified name.
- @property DOMString tagName();
+ @property string tagName();
/// Retrieves an attribute value by name.
- DOMString getAttribute(DOMString name);
+ string getAttribute(string name);
/++
+ Adds a new attribute. If an attribute with that name is already present in
+ the element, its value is changed to be that of the value parameter. This
@@ -919,7 +940,8 @@ interface Element : Node {
+ to assign it as the value of an attribute.
+ To set an attribute with a qualified name and namespace URI, use the `setAttributeNS` method.
+/
- void setAttribute(DOMString name, DOMString value);
+ void setAttribute(string name, string value);
+
/++
+ Removes an attribute by name. If a default value for the removed attribute
+ is defined in the DTD, a new attribute immediately appears with the default
@@ -927,10 +949,11 @@ interface Element : Node {
+ when applicable.
+ To remove an attribute by local name and namespace URI, use the `removeAttributeNS` method.
+/
- void removeAttribute(DOMString name);
+ void removeAttribute(string name);
/// Retrieves an attribute node by name.
- Attr getAttributeNode(DOMString name);
+ Attr getAttributeNode(string name);
+
/++
+ Adds a new attribute node. If an attribute with that name (`nodeName`) is
+ already present in the element, it is replaced by the new one. Replacing an
@@ -939,6 +962,7 @@ interface Element : Node {
+ the `setAttributeNodeNS` method.
+/
Attr setAttributeNode(Attr newAttr);
+
/++
+ Removes the specified attribute node. If a default value for the removed attribute
+ is defined in the DTD, a new attribute immediately appears with the default
@@ -952,7 +976,8 @@ interface Element : Node {
+ Per the XML Namespaces specification, applications must use the value `null`
+ as the `namespaceURI` parameter for methods if they wish to have no namespace.
+/
- DOMString getAttributeNS(DOMString namespaceURI, DOMString localName);
+ string getAttributeNS(string namespaceURI, string localName);
+
/++
+ Adds a new attribute. If an attribute with the same local name and namespace
+ URI is already present on the element, its prefix is changed to be the prefix
@@ -967,7 +992,8 @@ interface Element : Node {
+ Per the XML Namespaces specification, applications must use the value `null`
+ as the `namespaceURI` parameter for methods if they wish to have no namespace.
+/
- void setAttributeNS(DOMString namespaceURI, DOMString qualifiedName, DOMString value);
+ void setAttributeNS(string namespaceURI, string qualifiedName, string value);
+
/++
+ Removes an attribute by local name and namespace URI. If a default value
+ for the removed attribute is defined in the DTD, a new attribute immediately
@@ -976,14 +1002,15 @@ interface Element : Node {
+ Per the XML Namespaces specification, applications must use the value `null`
+ as the `namespaceURI` parameter for methods if they wish to have no namespace.
+/
- void removeAttributeNS(DOMString namespaceURI, DOMString localName);
+ void removeAttributeNS(string namespaceURI, string localName);
/++
+ Retrieves an `Attr` node by local name and namespace URI.
+ Per the XML Namespaces specification, applications must use the value `null`
+ as the `namespaceURI` parameter for methods if they wish to have no namespace.
+/
- Attr getAttributeNodeNS(DOMString namespaceURI, DOMString localName);
+ Attr getAttributeNodeNS(string namespaceURI, string localName);
+
/++
+ Adds a new attribute. If an attribute with that local name and that namespace
+ URI is already present in the element, it is replaced by the new one. Replacing
@@ -994,14 +1021,15 @@ interface Element : Node {
Attr setAttributeNodeNS(Attr newAttr);
/// Returns `true` when an attribute with a given `name` is specified on this element or has a default value, `false` otherwise.
- bool hasAttribute(DOMString name);
+ bool hasAttribute(string name);
+
/++
+ Returns `true` when an attribute with a given `localName` and `namespaceURI`
+ is specified on this element or has a default value, `false` otherwise.
+ Per the XML Namespaces specification, applications must use the value `null`
+ as the `namespaceURI` parameter for methods if they wish to have no namespace.
+/
- bool hasAttributeNS(DOMString namespaceURI, DOMString localName);
+ bool hasAttributeNS(string namespaceURI, string localName);
/++
+ If the parameter `isId` is `true`, this method declares the specified
@@ -1011,16 +1039,19 @@ interface Element : Node {
+ the `Attr.schemaTypeInfo` of the specified `Attr` node. Use the value `false`
+ for the parameter `isId` to undeclare an attribute for being a user-determined ID attribute.
+/
- void setIdAttribute(DOMString name, bool isId);
+ void setIdAttribute(string name, bool isId);
+
/// ditto
- void setIdAttributeNS(DOMString namespaceURI, DOMString localName, bool isId);
+ void setIdAttributeNS(string namespaceURI, string localName, bool isId);
+
/// ditto
void setIdAttributeNode(Attr idAttr, bool isId);
/// Returns a `NodeList` of all descendant `Element`s with a given tag name, in document order.
- NodeList getElementsByTagName(DOMString name);
+ NodeList getElementsByTagName(string name);
+
/// Returns a `NodeList` of all the descendant `Element`s with a given local name and namespace URI in document order.
- NodeList getElementsByTagNameNS(DOMString namespaceURI, DOMString localName);
+ NodeList getElementsByTagNameNS(string namespaceURI, string localName);
/// The type information associated with this element.
@property XMLTypeInfo schemaTypeInfo();
@@ -1034,7 +1065,8 @@ interface Element : Node {
+ there is markup, it is parsed into the information items (elements, comments,
+ etc.) and `Text` nodes that form the list of children of the element.
+/
-interface Text : CharacterData {
+interface Text : CharacterData
+{
/++
+ Breaks this node into two nodes at the specified `offset`, keeping both
+ in the tree as siblings. After being split, this node will contain all
@@ -1048,17 +1080,20 @@ interface Text : CharacterData {
/// Returns whether this text node contains element content whitespace, often abusively called "ignorable whitespace".
@property bool isElementContentWhitespace();
+
/// Returns the combined data of all direct text node siblings.
- @property DOMString wholeText();
+ @property string wholeText();
+
/// Couldn't find in DOM documentation, but leavint it there.
- Text replaceWholeText(DOMString content);
+ Text replaceWholeText(string content);
}
/++
+ This interface inherits from `CharacterData` and represents the content of a
+ comment, i.e., all the characters between the starting ''.
+/
-interface Comment : CharacterData {
+interface Comment : CharacterData
+{
}
/++
@@ -1066,30 +1101,34 @@ interface Comment : CharacterData {
+ nodes, specified in the schemas associated with the document. The type is a
+ pair of a namespace URI and name properties, and depends on the document's schema.
+/
-interface XMLTypeInfo {
- @property DOMString typeName();
- @property DOMString typeNamespace();
+interface XMLTypeInfo
+{
+ @property string typeName();
+ @property string typeNamespace();
- bool isDerivedFrom(DOMString typeNamespaceArg, DOMString typeNameArg, DerivationMethod derivationMethod);
+ bool isDerivedFrom(string typeNamespaceArg, string typeNameArg,
+ DerivationMethod derivationMethod);
}
/// DOMError is an interface that describes an error.
-interface DOMError {
+interface DOMError
+{
@property ErrorSeverity severity();
- @property DOMString message();
- @property DOMString type();
+ @property string message();
+ @property string type();
@property Object relatedException();
@property Object relatedData();
@property DOMLocator location();
}
/// `DOMLocator` is an interface that describes a location (e.g. where an error occurred).
-interface DOMLocator {
+interface DOMLocator
+{
@property long lineNumber();
@property long columnNumber();
@property long byteOffset();
@property Node relatedNode();
- @property DOMString uri();
+ @property string uri();
}
/++
@@ -1099,11 +1138,12 @@ interface DOMLocator {
+ the `CDATASection` nodes with `Text` nodes or specifying the type of the schema
+ that must be used when the validation of the `Document` is requested.
+/
-interface DOMConfiguration {
+interface DOMConfiguration
+{
void setParameter(string name, UserData value) @trusted;
UserData getParameter(string name) @trusted;
bool canSetParameter(string name, UserData value) @trusted;
- @property DOMStringList parameterNames();
+ @property stringList parameterNames();
}
/++
@@ -1117,7 +1157,8 @@ interface DOMConfiguration {
+ the `Text` interface. Adjacent `CDATASection` nodes are not merged by use of the
+ normalize method of the `Node` interface.
+/
-interface CDATASection : Text {
+interface CDATASection : Text
+{
}
/++
@@ -1129,23 +1170,29 @@ interface CDATASection : Text {
+
+ DOM Level 3 doesn't support editing `DocumentType` nodes. `DocumentType` nodes are read-only.
+/
-interface DocumentType : Node {
+interface DocumentType : Node
+{
/// The name of DTD; i.e., the name immediately following the `DOCTYPE` keyword.
- @property DOMString name();
+ @property string name();
+
/++
+ A `NamedNodeMap` containing the general entities, both external and internal,
+ declared in the DTD. Parameter entities are not contained. Duplicates are discarded.
+/
@property NamedNodeMap entities();
+
/++
+ A `NamedNodeMap` containing the notations declared in the DTD. Duplicates are discarded.
+ Every node in this map also implements the `Notation` interface.
+/
@property NamedNodeMap notations();
+
/// The public identifier of the external subset.
- @property DOMString publicId();
+ @property string publicId();
+
/// The system identifier of the external subset. This may be an absolute URI or not.
- @property DOMString systemId();
+ @property string systemId();
+
/++
+ The internal subset as a string, or `null` if there is none.
+ This is does not contain the delimiting square brackets.
@@ -1155,7 +1202,7 @@ interface DocumentType : Node {
+ to the implementation. This may vary depending on various parameters,
+ including the XML processor used to build the document.
+/
- @property DOMString internalSubset();
+ @property string internalSubset();
}
/++
@@ -1168,14 +1215,16 @@ interface DocumentType : Node {
+
+ A `Notation` node does not have any parent.
+/
-interface Notation : Node {
+interface Notation : Node
+{
/// The public identifier of this notation. If the public identifier was not specified, this is `null`.
- @property DOMString publicId();
+ @property string publicId();
+
/++
+ The system identifier of this notation. If the system identifier was not
+ specified, this is `null`. This may be an absolute URI or not.
+/
- @property DOMString systemId();
+ @property string systemId();
}
/++
@@ -1198,33 +1247,39 @@ interface Notation : Node {
+
+ An `Entity` node does not have any parent.
+/
-interface Entity : Node {
+interface Entity : Node
+{
/// The public identifier associated with the entity if specified, and `null` otherwise.
- @property DOMString publicId();
+ @property string publicId();
+
/++
+ The system identifier associated with the entity if specified, and `null` otherwise.
+ This may be an absolute URI or not.
+/
- @property DOMString systemId();
+ @property string systemId();
+
/// For unparsed entities, the name of the `Notation` for the entity. For parsed entities, this is `null`.
- @property DOMString notationName();
+ @property string notationName();
+
/++
+ An attribute specifying the encoding used for this entity at the time of
+ parsing, when it is an external parsed entity. This is `null` if it an
+ entity from the internal subset or if it is not known.
+/
- @property DOMString inputEncoding();
+ @property string inputEncoding();
+
/++
+ An attribute specifying, as part of the text declaration, the encoding of
+ this entity, when it is an external parsed entity. This is `null` otherwise.
+/
- @property DOMString xmlEncoding();
+ @property string xmlEncoding();
+
/++
+ An attribute specifying, as part of the text declaration, the version
+ number of this entity, when it is an external parsed entity. This is
+ `null` otherwise.
+/
- @property DOMString xmlVersion();
+ @property string xmlVersion();
}
/++
@@ -1234,24 +1289,28 @@ interface Entity : Node {
+
+ As for `Entity` nodes, `EntityReference` nodes and all their descendants are readonly.
+/
-interface EntityReference : Node {
+interface EntityReference : Node
+{
}
/++
+ The `ProcessingInstruction` interface represents a "processing instruction",
+ used in XML as a way to keep processor-specific information in the text of the document.
+/
-interface ProcessingInstruction : Node {
+interface ProcessingInstruction : Node
+{
/++
+ The target of this processing instruction. XML defines this as being the
+ first token following the markup that begins the processing instruction.
+/
- @property DOMString target();
+ @property string target();
+
/++
+ The content of this processing instruction. This is from the first non white
+ space character after the target to the character immediately preceding the `?>`.
+/
- @property DOMString data();
+ @property string data();
+
/// ditto
- @property void data(DOMString);
+ @property void data(string);
}
diff --git a/source/newxml/domimpl.d b/source/newxml/domimpl.d
index e9c40ef..1c30627 100644
--- a/source/newxml/domimpl.d
+++ b/source/newxml/domimpl.d
@@ -11,6 +11,7 @@
+ Authors:
+ Lodovico Giaretta
+ László Szerémi
++ Robert Schadek
+
+ License:
+ Boost License 1.0.
@@ -22,7 +23,6 @@
module newxml.domimpl;
import newxml.interfaces;
-import newxml.domstring;
import dom = newxml.dom;
@@ -30,7 +30,6 @@ import std.range.primitives;
import std.string;
import std.typecons : rebindable, Flag, BitFlags;
-
/++
+ An implementation of $(LINK2 ../dom/DOMImplementation, `newxml.dom.DOMImplementation`).
+
@@ -42,13 +41,14 @@ import std.typecons : rebindable, Flag, BitFlags;
class DOMImplementation : dom.DOMImplementation
{
@safe:
- //mixin UsesAllocator!(Alloc, true);
- this() @nogc @safe pure nothrow {
+ this() @nogc @safe pure nothrow
+ {
}
- void enforce(Ex,T)(T cond, dom.ExceptionCode ec) {
- if(!cond)
+ void enforce(Ex, T)(T cond, dom.ExceptionCode ec)
+ {
+ if (!cond)
{
throw new Ex(ec);
}
@@ -60,7 +60,7 @@ class DOMImplementation : dom.DOMImplementation
+ Implementation of $(LINK2 ../dom/DOMImplementation.createDocumentType,
+ `newxml.dom.DOMImplementation.createDocumentType`).
+/
- DocumentType createDocumentType(DOMString qualifiedName, DOMString publicId, DOMString systemId)
+ DocumentType createDocumentType(string qualifiedName, string publicId, string systemId)
{
DocumentType res = new DocumentType();
res._name = qualifiedName;
@@ -72,11 +72,12 @@ class DOMImplementation : dom.DOMImplementation
+ Implementation of $(LINK2 ../dom/DOMImplementation.createDocument,
+ `newxml.dom.DOMImplementation.createDocument`).
+/
- Document createDocument(DOMString namespaceURI, DOMString qualifiedName, dom.DocumentType _doctype)
+ Document createDocument(string namespaceURI, string qualifiedName,
+ dom.DocumentType _doctype)
{
- DocumentType doctype = cast(DocumentType)_doctype;
- enforce!DOMException(!(_doctype && !doctype),
- dom.ExceptionCode.wrongDocument);
+ DocumentType doctype = cast(DocumentType) _doctype;
+ enforce!DOMException(!(_doctype && !doctype), dom.ExceptionCode
+ .wrongDocument);
Document doc = new Document();
doc._ownerDocument = doc;
@@ -104,7 +105,8 @@ class DOMImplementation : dom.DOMImplementation
+/
bool hasFeature(string feature, string version_)
{
- import std.uni: sicmp;
+ import std.uni : sicmp;
+
return (!sicmp(feature, "Core") || !sicmp(feature, "XML"))
&& (version_ == "1.0" || version_ == "2.0" || version_ == "3.0");
}
@@ -117,9 +119,7 @@ class DOMImplementation : dom.DOMImplementation
+/
DOMImplementation getFeature(string feature, string version_)
{
- return hasFeature(feature, version_)
- ? this
- : null;
+ return hasFeature(feature, version_) ? this : null;
}
}
@@ -127,46 +127,64 @@ class DOMImplementation : dom.DOMImplementation
+ The implementation of $(LINK2 ../dom/DOMException, `newxml.dom.DOMException`)
+ thrown by this DOM implementation.
+/
- class DOMException: dom.DOMException
+ class DOMException : dom.DOMException
{
/// Constructs a `DOMException` with a specific `dom.ExceptionCode`.
- pure nothrow @nogc @safe this(dom.ExceptionCode code, string file = __FILE__, size_t line = __LINE__,
- Throwable nextInChain = null)
+ pure nothrow @nogc @safe this(dom.ExceptionCode code,
+ string file = __FILE__,
+ size_t line = __LINE__, Throwable nextInChain = null)
{
- _code = code;
+ this._code = code;
super("", file, line);
}
- @nogc @safe pure nothrow this(string msg, Throwable nextInChain, string file = __FILE__, size_t line = __LINE__)
+
+ @nogc @safe pure nothrow this(string msg, Throwable nextInChain,
+ string file = __FILE__, size_t line = __LINE__)
{
super(msg, file, line, nextInChain);
}
/// Implementation of $(LINK2 ../dom/DOMException.code, `newxml.dom.DOMException.code`).
override @property dom.ExceptionCode code()
{
- return _code;
+ return this._code;
}
+
private dom.ExceptionCode _code;
}
/// Implementation of $(LINK2 ../dom/Node, `newxml.dom.Node`)
abstract class Node : dom.Node
{
- package this() {
+ package this()
+ {
}
+
override
{
/// Implementation of $(LINK2 ../dom/Node.ownerDocument, `newxml.dom.Node.ownerDocument`).
- @property Document ownerDocument() { return _ownerDocument; }
+ @property Document ownerDocument()
+ {
+ return this._ownerDocument;
+ }
/// Implementation of $(LINK2 ../dom/Node.parentNode, `newxml.dom.Node.parentNode`).
- @property Node parentNode() { return _parentNode; }
+ @property Node parentNode()
+ {
+ return this._parentNode;
+ }
/++
+ Implementation of $(LINK2 ../dom/Node.previousSibling,
+ `newxml.dom.Node.previousSibling`).
+/
- @property Node previousSibling() { return _previousSibling; }
+ @property Node previousSibling()
+ {
+ return this._previousSibling;
+ }
/// Implementation of $(LINK2 ../dom/Node.nextSibling, `newxml.dom.Node.nextSibling`).
- @property Node nextSibling() { return _nextSibling; }
+ @property Node nextSibling()
+ {
+ return this._nextSibling;
+ }
/++
+ Implementation of $(LINK2 ../dom/Node.isSameNode, `newxml.dom.Node.isSameNode`).
@@ -180,15 +198,15 @@ class DOMImplementation : dom.DOMImplementation
/// Implementation of $(LINK2 ../dom/Node.isEqualNode, `newxml.dom.Node.isEqualNode`).
bool isEqualNode(dom.Node other)
{
- import std.meta: AliasSeq;
+ import std.meta : AliasSeq;
- if (!other || nodeType != other.nodeType)
+ if (!other || this.nodeType != other.nodeType)
{
return false;
}
- foreach (field; AliasSeq!("nodeName", "localName"
- , "namespaceURI", "prefix", "nodeValue"))
+ foreach (field; AliasSeq!("nodeName", "localName",
+ "namespaceURI", "prefix", "nodeValue"))
{
mixin("auto a = " ~ field ~ ";\n");
mixin("auto b = other." ~ field ~ ";\n");
@@ -199,7 +217,7 @@ class DOMImplementation : dom.DOMImplementation
}
}
- auto thisWithChildren = cast(NodeWithChildren)this;
+ auto thisWithChildren = cast(NodeWithChildren) this;
if (thisWithChildren)
{
auto otherChild = other.firstChild;
@@ -221,21 +239,22 @@ class DOMImplementation : dom.DOMImplementation
}
/// Implementation of $(LINK2 ../dom/Node.setUserData, `newxml.dom.Node.setUserData`).
- dom.UserData setUserData(string key, dom.UserData data, dom.UserDataHandler handler) @trusted
+ dom.UserData setUserData(string key, dom.UserData data,
+ dom.UserDataHandler handler) @trusted
{
- userData[key] = data;
+ this.userData[key] = data;
if (handler)
{
- userDataHandlers[key] = handler;
+ this.userDataHandlers[key] = handler;
}
return data;
}
/// Implementation of $(LINK2 ../dom/Node.getUserData, `newxml.dom.Node.getUserData`).
dom.UserData getUserData(string key) const @trusted
{
- if (key in userData)
+ if (key in this.userData)
{
- return userData[key];
+ return this.userData[key];
}
return dom.UserData(null);
}
@@ -249,8 +268,7 @@ class DOMImplementation : dom.DOMImplementation
bool isSupported(string feature, string version_)
{
return (feature == "Core" || feature == "XML")
- && (version_ == "1.0" || version_ == "2.0"
- || version_ == "3.0");
+ && (version_ == "1.0" || version_ == "2.0" || version_ == "3.0");
}
/++
+ Implementation of $(LINK2 ../dom/Node.getFeature, `newxml.dom.Node.getFeature`).
@@ -260,9 +278,7 @@ class DOMImplementation : dom.DOMImplementation
+/
Node getFeature(string feature, string version_)
{
- return isSupported(feature, version_)
- ? this
- : null;
+ return isSupported(feature, version_) ? this : null;
}
/++
@@ -271,9 +287,10 @@ class DOMImplementation : dom.DOMImplementation
+/
BitFlags!(dom.DocumentPosition) compareDocumentPosition(dom.Node _other) @trusted
{
- enum Ret(dom.DocumentPosition flag) = cast(BitFlags!(dom.DocumentPosition)) flag;
+ enum Ret(dom.DocumentPosition flag) = cast(BitFlags!(dom
+ .DocumentPosition)) flag;
- Node other = cast(Node)_other;
+ Node other = cast(Node) _other;
if (!other)
{
return Ret!(dom.DocumentPosition.disconnected);
@@ -286,8 +303,8 @@ class DOMImplementation : dom.DOMImplementation
Node node1 = other;
Node node2 = this;
- Attr attr1 = cast(Attr)node1;
- Attr attr2 = cast(Attr)node2;
+ Attr attr1 = cast(Attr) node1;
+ Attr attr2 = cast(Attr) node2;
if (attr1 && attr1.ownerElement)
{
@@ -299,17 +316,18 @@ class DOMImplementation : dom.DOMImplementation
node2 = attr2.ownerElement;
if (attr1 && node2 is node1)
{
- foreach (attr; (cast(Element)node2).attributes) with (dom.DocumentPosition)
- {
- if (attr is attr1)
+ foreach (attr; (cast(Element) node2).attributes)
+ with (dom.DocumentPosition)
{
- return Ret!implementationSpecific | Ret!preceding;
+ if (attr is attr1)
+ {
+ return Ret!implementationSpecific | Ret!preceding;
+ }
+ else if (attr is attr2)
+ {
+ return Ret!implementationSpecific | Ret!following;
+ }
}
- else if (attr is attr2)
- {
- return Ret!implementationSpecific | Ret!following;
- }
- }
}
}
void rootAndDepth(ref Node node, out int depth)
@@ -320,22 +338,23 @@ class DOMImplementation : dom.DOMImplementation
depth++;
}
}
+
Node root1 = node1, root2 = node2;
int depth1, depth2;
rootAndDepth(root1, depth1);
rootAndDepth(root2, depth2);
- if (root1 !is root2) with (dom.DocumentPosition)
- {
- return (cast(void*)root1 < cast(void*)root2)
- ? Ret!disconnected | Ret!implementationSpecific | Ret!preceding
- : Ret!disconnected | Ret!implementationSpecific | Ret!following;
- }
+ if (root1 !is root2)
+ with (dom.DocumentPosition)
+ {
+ return (cast(void*) root1 < cast(void*) root2) ? Ret!disconnected | Ret!implementationSpecific | Ret!preceding : Ret!disconnected | Ret!implementationSpecific | Ret!following;
+ }
bool swapped = depth1 < depth2;
if (swapped)
{
- import std.algorithm: swap;
+ import std.algorithm : swap;
+
swap(depth1, depth2);
swap(node1, node2);
swapped = true;
@@ -346,14 +365,14 @@ class DOMImplementation : dom.DOMImplementation
node1 = node1.parentNode;
}
- if (node1 is node2) with (dom.DocumentPosition)
- {
- return swapped
- ? Ret!contains | Ret!preceding
- : Ret!containedBy | Ret!following;
- }
+ if (node1 is node2)
+ with (dom.DocumentPosition)
+ {
+ return swapped ? Ret!contains | Ret!preceding
+ : Ret!containedBy | Ret!following;
+ }
- while(true)
+ while (true)
{
if (node1.parentNode is node2.parentNode)
{
@@ -384,28 +403,28 @@ class DOMImplementation : dom.DOMImplementation
// internal methods
Element parentElement()
{
- auto parent = parentNode;
+ auto parent = this.parentNode;
while (parent && parent.nodeType != dom.NodeType.element)
{
parent = parent.parentNode;
}
- return cast(Element)parent;
+ return cast(Element) parent;
}
+
void performClone(Node dest, bool deep) @trusted
{
- foreach (data; userDataHandlers.byKeyValue)
+ foreach (data; this.userDataHandlers.byKeyValue)
{
auto value = data.value;
// putting data.value directly in the following line causes an error; should investigate further
- value(dom.UserDataOperation.nodeCloned
- , new DOMString(data.key), userData[data.key], this
- , dest);
+ value(dom.UserDataOperation.nodeCloned, data.key,
+ userData[data.key], this, dest);
}
}
}
// method that must be overridden
// just because otherwise it doesn't work [bugzilla 16318]
- abstract override DOMString nodeName();
+ abstract override string nodeName();
// methods specialized in NodeWithChildren
override
{
@@ -419,8 +438,16 @@ class DOMImplementation : dom.DOMImplementation
}
return emptyList;
}
- @property Node firstChild() { return null; }
- @property Node lastChild() { return null; }
+
+ @property Node firstChild()
+ {
+ return null;
+ }
+
+ @property Node lastChild()
+ {
+ return null;
+ }
Node insertBefore(dom.Node _newChild, dom.Node _refChild)
{
@@ -442,42 +469,81 @@ class DOMImplementation : dom.DOMImplementation
throw new DOMException(dom.ExceptionCode.hierarchyRequest);
}
- bool hasChildNodes() const { return false; }
+ bool hasChildNodes() const
+ {
+ return false;
+ }
}
// methods specialized in Element
override
{
- @property Element.Map attributes() { return null; }
- bool hasAttributes() { return false; }
+ @property Element.Map attributes()
+ {
+ return null;
+ }
+
+ bool hasAttributes()
+ {
+ return false;
+ }
}
// methods specialized in various subclasses
override
{
- @property DOMString nodeValue() { return null; }
- @property void nodeValue(DOMString) {}
- @property DOMString textContent() { return null; }
- @property void textContent(DOMString) {}
- @property DOMString baseURI()
+ @property string nodeValue()
+ {
+ return null;
+ }
+
+ @property void nodeValue(string)
{
- return parentNode
- ? parentNode.baseURI
- : null;
}
- Node cloneNode(bool deep) { return null; }
+ @property string textContent()
+ {
+ return null;
+ }
+
+ @property void textContent(string)
+ {
+ }
+
+ @property string baseURI()
+ {
+ return parentNode ? parentNode.baseURI : null;
+ }
+
+ Node cloneNode(bool deep)
+ {
+ return null;
+ }
}
// methods specialized in Element and Attribute
override
{
- @property DOMString localName() { return null; }
- @property DOMString prefix() { return null; }
- @property void prefix(DOMString) { }
- @property DOMString namespaceURI() { return null; }
+ @property string localName()
+ {
+ return null;
+ }
+
+ @property string prefix()
+ {
+ return null;
+ }
+
+ @property void prefix(string)
+ {
+ }
+
+ @property string namespaceURI()
+ {
+ return null;
+ }
}
// methods specialized in Document, Element and Attribute
override
{
- DOMString lookupPrefix(DOMString namespaceURI)
+ string lookupPrefix(string namespaceURI)
{
if (!namespaceURI)
{
@@ -486,76 +552,75 @@ class DOMImplementation : dom.DOMImplementation
switch (nodeType) with (dom.NodeType)
{
- case entity:
- case notation:
- case documentFragment:
- case documentType:
- return null;
- case attribute:
- Attr attr = cast(Attr)this;
- return attr.ownerElement
- ? attr.ownerElement.lookupNamespacePrefix(namespaceURI, attr.ownerElement)
- : null;
- default:
- auto parentElement = parentElement();
- return parentElement
- ? parentElement.lookupNamespacePrefix(namespaceURI, parentElement)
- : null;
+ case entity:
+ case notation:
+ case documentFragment:
+ case documentType:
+ return null;
+ case attribute:
+ Attr attr = cast(Attr) this;
+ return attr.ownerElement
+ ? attr.ownerElement.lookupNamespacePrefix(namespaceURI,
+ attr.ownerElement) : null;
+ default:
+ auto parentElement = this.parentElement();
+ return parentElement ? parentElement.lookupNamespacePrefix(
+ namespaceURI, parentElement) : null;
}
}
- DOMString lookupNamespaceURI(DOMString prefix)
+
+ string lookupNamespaceURI(string prefix)
{
switch (nodeType) with (dom.NodeType)
{
- case entity:
- case notation:
- case documentType:
- case documentFragment:
- return null;
- case attribute:
- auto attr = cast(Attr)this;
- return attr.ownerElement
- ? attr.ownerElement.lookupNamespaceURI(prefix)
- : null;
- default:
- auto parentElement = parentElement();
- return parentElement
- ? parentElement.lookupNamespaceURI(prefix)
- : null;
+ case entity:
+ case notation:
+ case documentType:
+ case documentFragment:
+ return null;
+ case attribute:
+ auto attr = cast(Attr) this;
+ return attr.ownerElement ? attr.ownerElement
+ .lookupNamespaceURI(prefix) : null;
+ default:
+ auto parentElement = this.parentElement();
+ return parentElement ? parentElement.lookupNamespaceURI(prefix) : null;
}
}
- bool isDefaultNamespace(DOMString namespaceURI)
+
+ bool isDefaultNamespace(string namespaceURI)
{
switch (nodeType) with (dom.NodeType)
{
- case entity:
- case notation:
- case documentType:
- case documentFragment:
- return false;
- case attribute:
- auto attr = cast(Attr)this;
- return attr.ownerElement
- ? attr.ownerElement.isDefaultNamespace(namespaceURI)
- : false;
- default:
- auto parentElement = parentElement();
- return parentElement
- ? parentElement.isDefaultNamespace(namespaceURI)
- : false;
+ case entity:
+ case notation:
+ case documentType:
+ case documentFragment:
+ return false;
+ case attribute:
+ auto attr = cast(Attr) this;
+ return attr.ownerElement
+ ? attr.ownerElement.isDefaultNamespace(
+ namespaceURI) : false;
+ default:
+ auto parentElement = parentElement();
+ return parentElement ? parentElement.isDefaultNamespace(namespaceURI) : false;
}
}
}
// TODO methods
override
{
- void normalize() {}
+ void normalize()
+ {
+ }
}
// inner class for use in NodeWithChildren
class ChildList : dom.NodeList
{
private Node currentChild;
- package this() {
+ package this()
+ {
}
// methods specific to NodeList
@@ -570,6 +635,7 @@ class DOMImplementation : dom.DOMImplementation
}
return result;
}
+
@property size_t length()
{
auto child = rebindable(this.outer.firstChild);
@@ -582,18 +648,35 @@ class DOMImplementation : dom.DOMImplementation
return result;
}
}
+
// more idiomatic methods
auto opIndex(size_t i)
{
- return item(i);
+ return this.item(i);
}
// range interface
- auto front() { return currentChild; }
- void popFront() { currentChild = currentChild.nextSibling; }
- bool empty() { return currentChild is null; }
+ auto front()
+ {
+ return this.currentChild;
+ }
+
+ void popFront()
+ {
+ this.currentChild = this.currentChild.nextSibling;
+ }
+
+ bool empty()
+ {
+ return this.currentChild is null;
+ }
}
+
// method not required by the spec, specialized in NodeWithChildren
- bool isAncestor(Node other) { return false; }
+ bool isAncestor(Node other)
+ {
+ return false;
+ }
+
/++
+ `true` if and only if this node is _readonly.
+
@@ -606,13 +689,19 @@ class DOMImplementation : dom.DOMImplementation
+ are always readonly.
+/
// method not required by the spec, specialized in varous subclasses
- @property bool readonly() { return _readonly; }
+ @property bool readonly()
+ {
+ return this._readonly;
+ }
}
+
private abstract class NodeWithChildren : Node
{
- package this() {
+ package this()
+ {
}
+
override
{
@property ChildList childNodes()
@@ -621,43 +710,49 @@ class DOMImplementation : dom.DOMImplementation
res.currentChild = firstChild;
return res;
}
+
@property Node firstChild()
{
- return _firstChild;
+ return this._firstChild;
}
+
@property Node lastChild()
{
- return _lastChild;
+ return this._lastChild;
}
Node insertBefore(dom.Node _newChild, dom.Node _refChild)
{
- enforce!DOMException(!readonly, dom.ExceptionCode.noModificationAllowed);
+ enforce!DOMException(!readonly, dom.ExceptionCode
+ .noModificationAllowed);
if (!_refChild)
{
return appendChild(_newChild);
}
- Node newChild = cast(Node)_newChild;
- Node refChild = cast(Node)_refChild;
+ Node newChild = cast(Node) _newChild;
+ Node refChild = cast(Node) _refChild;
enforce!DOMException(!(!newChild || !refChild
- || newChild.ownerDocument !is ownerDocument)
- , dom.ExceptionCode.wrongDocument);
- enforce!DOMException(!(this is newChild || newChild.isAncestor(this)
- || newChild is refChild)
- , dom.ExceptionCode.hierarchyRequest);
- enforce!DOMException(!(refChild.parentNode !is this)
- , dom.ExceptionCode.notFound);
- enforce!DOMException(!(this is newChild || newChild.isAncestor(this) || newChild is refChild)
- , dom.ExceptionCode.hierarchyRequest);
- enforce!DOMException(!(refChild.parentNode !is this)
- , dom.ExceptionCode.notFound);
+ || newChild.ownerDocument !is ownerDocument),
+ dom.ExceptionCode.wrongDocument);
+ enforce!DOMException(!(this is newChild
+ || newChild.isAncestor(this)
+ || newChild is refChild), dom.ExceptionCode
+ .hierarchyRequest);
+ enforce!DOMException(!(refChild.parentNode !is this), dom
+ .ExceptionCode.notFound);
+ enforce!DOMException(!(this is newChild
+ || newChild.isAncestor(this)
+ || newChild is refChild), dom.ExceptionCode
+ .hierarchyRequest);
+ enforce!DOMException(!(refChild.parentNode !is this), dom
+ .ExceptionCode.notFound);
if (newChild.nodeType == dom.NodeType.documentFragment)
{
- for (auto child = rebindable(newChild); child !is null
- ; child = child.nextSibling)
+ for (auto child = rebindable(newChild); child !is null; child = child
+ .nextSibling)
{
insertBefore(child, refChild);
}
@@ -683,40 +778,44 @@ class DOMImplementation : dom.DOMImplementation
if (firstChild is refChild)
{
- _firstChild = newChild;
+ this._firstChild = newChild;
}
return newChild;
}
+
Node replaceChild(dom.Node newChild, dom.Node oldChild)
{
- insertBefore(newChild, oldChild);
- return removeChild(oldChild);
+ this.insertBefore(newChild, oldChild);
+ return this.removeChild(oldChild);
}
+
Node removeChild(dom.Node _oldChild)
{
- enforce!DOMException(!readonly, dom.ExceptionCode.noModificationAllowed);
- Node oldChild = cast(Node)_oldChild;
+ enforce!DOMException(!this.readonly, dom.ExceptionCode
+ .noModificationAllowed);
+ Node oldChild = cast(Node) _oldChild;
enforce!DOMException(!(!oldChild
- || oldChild.parentNode !is this)
- , dom.ExceptionCode.noModificationAllowed);
+ || oldChild.parentNode !is this),
+ dom.ExceptionCode.noModificationAllowed);
if (oldChild is firstChild)
{
- _firstChild = oldChild.nextSibling;
+ this._firstChild = oldChild.nextSibling;
}
else
{
oldChild.previousSibling._nextSibling = oldChild.nextSibling;
}
- if (oldChild is lastChild)
+ if (oldChild is this.lastChild)
{
_lastChild = oldChild.previousSibling;
}
else
{
- oldChild.nextSibling._previousSibling = oldChild.previousSibling;
+ oldChild.nextSibling._previousSibling = oldChild
+ .previousSibling;
}
oldChild._parentNode = null;
@@ -724,14 +823,18 @@ class DOMImplementation : dom.DOMImplementation
oldChild._nextSibling = null;
return oldChild;
}
+
Node appendChild(dom.Node _newChild)
{
- enforce!DOMException(!readonly, dom.ExceptionCode.noModificationAllowed);
- Node newChild = cast(Node)_newChild;
- enforce!DOMException(!(!newChild || newChild.ownerDocument !is ownerDocument)
- , dom.ExceptionCode.wrongDocument);
- enforce!DOMException(!(this is newChild || newChild.isAncestor(this))
- , dom.ExceptionCode.hierarchyRequest);
+ enforce!DOMException(!readonly, dom.ExceptionCode
+ .noModificationAllowed);
+ Node newChild = cast(Node) _newChild;
+ enforce!DOMException(!(!newChild
+ || newChild.ownerDocument !is ownerDocument),
+ dom.ExceptionCode.wrongDocument);
+ enforce!DOMException(!(this is newChild
+ || newChild.isAncestor(this)),
+ dom.ExceptionCode.hierarchyRequest);
if (newChild.parentNode !is null)
{
newChild.parentNode.removeChild(newChild);
@@ -739,8 +842,8 @@ class DOMImplementation : dom.DOMImplementation
if (newChild.nodeType == dom.NodeType.documentFragment)
{
- for (auto node = rebindable(newChild.firstChild)
- ; node !is null; node = node.nextSibling)
+ for (auto node = rebindable(newChild.firstChild); node !is null;
+ node = node.nextSibling)
{
appendChild(node);
}
@@ -748,25 +851,28 @@ class DOMImplementation : dom.DOMImplementation
}
newChild._parentNode = this;
- if (lastChild)
+ if (this.lastChild)
{
newChild._previousSibling = lastChild;
- lastChild._nextSibling = newChild;
+ this.lastChild._nextSibling = newChild;
}
else
{
- _firstChild = newChild;
+ this._firstChild = newChild;
}
- _lastChild = newChild;
+ this._lastChild = newChild;
return newChild;
}
+
bool hasChildNodes() const
{
- return _firstChild !is null;
+ return this._firstChild !is null;
}
+
bool isAncestor(Node other)
{
- for (auto child = rebindable(firstChild); child !is null; child = child.nextSibling)
+ for (auto child = rebindable(this.firstChild); child !is null; child = child
+ .nextSibling)
{
if (child is other)
{
@@ -781,44 +887,48 @@ class DOMImplementation : dom.DOMImplementation
return false;
}
- @property DOMString textContent()
+ @property string textContent()
{
- //import newxml.appender;
- DOMString result;
- //auto result = Appender!(typeof(this.textContent()[0]), typeof(*allocator))(allocator);
- for (auto child = rebindable(firstChild); child !is null; child = child.nextSibling)
+ string result;
+ for (auto child = rebindable(this.firstChild); child !is null; child = child
+ .nextSibling)
{
- if (child.nodeType != dom.NodeType.comment &&
- child.nodeType != dom.NodeType.processingInstruction)
+ if (child.nodeType != dom.NodeType.comment
+ && child.nodeType != dom.NodeType
+ .processingInstruction)
{
- result ~= child.textContent();//result.put(child.textContent);
+ result ~= child.textContent(); //result.put(child.textContent);
}
}
return result;
}
- @property void textContent(DOMString newVal)
+
+ @property void textContent(string newVal)
{
- enforce!DOMException(readonly
- , dom.ExceptionCode.noModificationAllowed);
+ enforce!DOMException(this.readonly, dom.ExceptionCode
+ .noModificationAllowed);
- while (firstChild)
+ while (this.firstChild)
{
- removeChild(firstChild);
+ this.removeChild(this.firstChild);
}
- _firstChild = _lastChild = ownerDocument.createTextNode(newVal);
+ this._lastChild = ownerDocument.createTextNode(newVal);
+ this._firstChild = this._lastChild;
}
}
private
{
- Node _firstChild, _lastChild;
+ Node _firstChild;
+ Node _lastChild;
void performClone(NodeWithChildren dest, bool deep)
{
super.performClone(dest, deep);
+
if (deep)
{
- foreach (child; childNodes)
+ foreach (child; this.childNodes)
{
auto childClone = child.cloneNode(true);
dest.appendChild(childClone);
@@ -830,78 +940,106 @@ class DOMImplementation : dom.DOMImplementation
/// Implementation of $(LINK2 ../dom/DocumentFragment, `newxml.dom.DocumentFragment`)
class DocumentFragment : NodeWithChildren, dom.DocumentFragment
{
- package this() {
+ package this()
+ {
}
// inherited from Node
override
{
- @property dom.NodeType nodeType() { return dom.NodeType.documentFragment; }
- @property DOMString nodeName() { return new DOMString("#document-fragment"w); }
+ @property dom.NodeType nodeType()
+ {
+ return dom.NodeType.documentFragment;
+ }
+
+ @property string nodeName()
+ {
+ return "#document-fragment";
+ }
}
}
/// Implementation of $(LINK2 ../dom/Document, `newxml.dom.Document`)
class Document : NodeWithChildren, dom.Document
{
- package this() {
+ package this()
+ {
}
+
package @property void doctype(DocumentType _doctype)
{
this._doctype = _doctype;
}
+
// specific to Document
override
{
- @property DocumentType doctype() { return _doctype; }
- @property DOMImplementation implementation() { return this.outer; }
- @property Element documentElement() { return _root; }
+ @property DocumentType doctype()
+ {
+ return this._doctype;
+ }
- Element createElement(DOMString tagName)
+ @property DOMImplementation implementation()
+ {
+ return this.outer;
+ }
+
+ @property Element documentElement()
+ {
+ return this._root;
+ }
+
+ Element createElement(string tagName)
{
Element res = new Element();
res._name = tagName;
res._ownerDocument = this;
- res._attrs = res.createMap();//new Element.Map();
+ res._attrs = res.createMap();
return res;
}
- Element createElementNS(DOMString namespaceURI, DOMString qualifiedName)
+
+ Element createElementNS(string namespaceURI, string qualifiedName)
{
Element res = new Element();
res.setQualifiedName(qualifiedName);
res._namespaceURI = namespaceURI;
res._ownerDocument = this;
- res._attrs = res.createMap();//res._attrs = new Element.Map();
+ res._attrs = res.createMap();
return res;
}
+
DocumentFragment createDocumentFragment()
{
DocumentFragment res = new DocumentFragment();
res._ownerDocument = this;
return res;
}
- Text createTextNode(DOMString data)
+
+ Text createTextNode(string data)
{
Text res = new Text();
res._data = data;
res._ownerDocument = this;
return res;
}
- Comment createComment(DOMString data)
+
+ Comment createComment(string data)
{
Comment res = new Comment();
res._data = data;
res._ownerDocument = this;
return res;
}
- CDATASection createCDATASection(DOMString data)
+
+ CDATASection createCDATASection(string data)
{
CDATASection res = new CDATASection();
res._data = data;
res._ownerDocument = this;
return res;
}
- ProcessingInstruction createProcessingInstruction(DOMString target, DOMString data)
+
+ ProcessingInstruction createProcessingInstruction(string target, string data)
{
ProcessingInstruction res = new ProcessingInstruction();
res._target = target;
@@ -909,14 +1047,16 @@ class DOMImplementation : dom.DOMImplementation
res._ownerDocument = this;
return res;
}
- Attr createAttribute(DOMString name)
+
+ Attr createAttribute(string name)
{
Attr res = new Attr();
res._name = name;
res._ownerDocument = this;
return res;
}
- Attr createAttributeNS(DOMString namespaceURI, DOMString qualifiedName)
+
+ Attr createAttributeNS(string namespaceURI, string qualifiedName)
{
Attr res = new Attr();
res.setQualifiedName(qualifiedName);
@@ -924,9 +1064,13 @@ class DOMImplementation : dom.DOMImplementation
res._ownerDocument = this;
return res;
}
- EntityReference createEntityReference(DOMString name) { return null; }
- ElementsByTagName getElementsByTagName(DOMString tagname)
+ EntityReference createEntityReference(string name)
+ {
+ return null;
+ }
+
+ ElementsByTagName getElementsByTagName(string tagname)
{
ElementsByTagName res = new ElementsByTagName();
res.root = this;
@@ -934,7 +1078,8 @@ class DOMImplementation : dom.DOMImplementation
res.current = res.item(0);
return res;
}
- ElementsByTagNameNS getElementsByTagNameNS(DOMString namespaceURI, DOMString localName)
+
+ ElementsByTagNameNS getElementsByTagNameNS(string namespaceURI, string localName)
{
ElementsByTagNameNS res = new ElementsByTagNameNS();
res.root = this;
@@ -943,16 +1088,18 @@ class DOMImplementation : dom.DOMImplementation
res.current = res.item(0);
return res;
}
- Element getElementById(DOMString elementId)
+
+ Element getElementById(string elementId)
{
Element find(dom.Node node) @safe
{
- if (node.nodeType == dom.NodeType.element && node.hasAttributes)
+ if (node.nodeType == dom.NodeType.element && node
+ .hasAttributes)
{
foreach (attr; node.attributes)
{
- if ((cast(Attr)attr).isId && attr.nodeValue == elementId)
- return cast(Element)node;
+ if ((cast(Attr) attr).isId && attr.nodeValue == elementId)
+ return cast(Element) node;
}
}
foreach (child; node.childNodes)
@@ -965,6 +1112,7 @@ class DOMImplementation : dom.DOMImplementation
}
return null;
}
+
return find(_root);
}
@@ -972,70 +1120,91 @@ class DOMImplementation : dom.DOMImplementation
{
switch (node.nodeType) with (dom.NodeType)
{
- case attribute:
- Attr result;
- result = node.prefix
- ? createAttributeNS(node.namespaceURI, node.nodeName)
- : createAttribute(node.nodeName);
+ case attribute:
+ Attr result;
+ result = node.prefix ? createAttributeNS(node.namespaceURI,
+ node.nodeName) : createAttribute(node.nodeName);
+ auto children = node.childNodes;
+ foreach (i; 0 .. children.length)
+ {
+ result.appendChild(importNode(children.item(i), true));
+ }
+ return result;
+ case documentFragment:
+ auto result = createDocumentFragment();
+ if (deep)
+ {
auto children = node.childNodes;
- foreach (i; 0..children.length)
+ foreach (i; 0 .. children.length)
{
- result.appendChild(importNode(children.item(i), true));
- }
- return result;
- case documentFragment:
- auto result = createDocumentFragment();
- if (deep)
- {
- auto children = node.childNodes;
- foreach (i; 0..children.length)
- {
- result.appendChild(importNode(children.item(i), deep));
- }
+ result.appendChild(importNode(children.item(i), deep));
}
- return result;
- case element:
- Element result;
- result = node.prefix
- ? createElementNS(node.namespaceURI, node.nodeName)
- : createElement(node.nodeName);
+ }
+ return result;
+ case element:
+ Element result;
+ result = node.prefix ? createElementNS(node.namespaceURI,
+ node.nodeName) : createElement(node.nodeName);
- if (node.hasAttributes)
+ if (node.hasAttributes)
+ {
+ auto attributes = node.attributes;
+ foreach (i; 0 .. attributes.length)
{
- auto attributes = node.attributes;
- foreach (i; 0..attributes.length)
- {
- auto attr = cast(Attr)(importNode(attributes.item(i), deep));
- assert(attr);
- result.setAttributeNode(attr);
- }
+ auto attr = cast(Attr)(importNode(attributes.item(i), deep));
+ assert(attr);
+ result.setAttributeNode(attr);
}
- if (deep)
+ }
+ if (deep)
+ {
+ auto children = node.childNodes;
+ foreach (i; 0 .. children.length)
{
- auto children = node.childNodes;
- foreach (i; 0..children.length)
- {
- result.appendChild(importNode(children.item(i), true));
- }
+ result.appendChild(importNode(children.item(i), true));
}
- return result;
- case processingInstruction:
- return createProcessingInstruction(node.nodeName, node.nodeValue);
- default:
- throw new DOMException(dom.ExceptionCode.notSupported);
+ }
+ return result;
+ case processingInstruction:
+ return createProcessingInstruction(node.nodeName, node
+ .nodeValue);
+ default:
+ throw new DOMException(dom.ExceptionCode.notSupported);
}
}
- Node adoptNode(dom.Node source) { return null; }
- @property DOMString inputEncoding() { return null; }
- @property DOMString xmlEncoding() { return null; }
+ Node adoptNode(dom.Node source)
+ {
+ return null;
+ }
+
+ @property string inputEncoding()
+ {
+ return null;
+ }
- @property bool xmlStandalone() { return _standalone; }
- @property void xmlStandalone(bool b) { _standalone = b; }
+ @property string xmlEncoding()
+ {
+ return null;
+ }
- @property DOMString xmlVersion() { return _xmlVersion; }
- @property void xmlVersion(DOMString ver)
+ @property bool xmlStandalone()
+ {
+ return _standalone;
+ }
+
+ @property void xmlStandalone(bool b)
+ {
+ _standalone = b;
+ }
+
+ @property string xmlVersion()
+ {
+ return _xmlVersion;
+ }
+
+ @property void xmlVersion(string ver)
{
if (ver == "1.0" || ver == "1.1")
{
@@ -1047,58 +1216,91 @@ class DOMImplementation : dom.DOMImplementation
}
}
- @property bool strictErrorChecking() { return _strictErrorChecking; }
- @property void strictErrorChecking(bool b) { _strictErrorChecking = b; }
+ @property bool strictErrorChecking()
+ {
+ return _strictErrorChecking;
+ }
+
+ @property void strictErrorChecking(bool b)
+ {
+ _strictErrorChecking = b;
+ }
+
+ @property string documentURI()
+ {
+ return _documentURI;
+ }
+
+ @property void documentURI(string uri)
+ {
+ _documentURI = uri;
+ }
- @property DOMString documentURI() { return _documentURI; }
- @property void documentURI(DOMString uri) { _documentURI = uri; }
+ @property DOMConfiguration domConfig()
+ {
+ return _config;
+ }
- @property DOMConfiguration domConfig() { return _config; }
- void normalizeDocument() { }
- Node renameNode(dom.Node n, DOMString namespaceURI, DOMString qualifiedName)
+ void normalizeDocument()
{
- auto node = cast(Node)n;
- enforce!DOMException(!(!node || node.ownerDocument !is this)
- , dom.ExceptionCode.wrongDocument);
+ }
+
+ Node renameNode(dom.Node n, string namespaceURI, string qualifiedName)
+ {
+ auto node = cast(Node) n;
+ enforce!DOMException(!(!node || node.ownerDocument !is this),
+ dom.ExceptionCode.wrongDocument);
auto type = node.nodeType;
enforce!DOMException(!(type != dom.NodeType.element
- && type != dom.NodeType.attribute)
- , dom.ExceptionCode.notSupported);
+ && type != dom.NodeType.attribute),
+ dom.ExceptionCode.notSupported);
- auto withNs = (cast(NodeWithNamespace)node);
+ auto withNs = (cast(NodeWithNamespace) node);
withNs.setQualifiedName(qualifiedName);
withNs._namespaceURI = namespaceURI;
return node;
}
}
+
private
{
- DOMString _documentURI, _xmlVersion = new DOMString("1.0"w);
+ string _documentURI, _xmlVersion = "1.0";
DocumentType _doctype;
Element _root;
DOMConfiguration _config;
bool _strictErrorChecking = true, _standalone = false;
}
+
// inherited from Node
override
{
- @property dom.NodeType nodeType() { return dom.NodeType.document; }
- @property DOMString nodeName() { return new DOMString("#document"w); }
+ @property dom.NodeType nodeType()
+ {
+ return dom.NodeType.document;
+ }
- DOMString lookupPrefix(DOMString namespaceURI)
+ @property string nodeName()
+ {
+ return "#document";
+ }
+
+ string lookupPrefix(string namespaceURI)
{
return documentElement.lookupPrefix(namespaceURI);
}
- DOMString lookupNamespaceURI(DOMString prefix)
+
+ string lookupNamespaceURI(string prefix)
{
return documentElement.lookupNamespaceURI(prefix);
}
- bool isDefaultNamespace(DOMString namespaceURI)
+
+ bool isDefaultNamespace(string namespaceURI)
{
return documentElement.isDefaultNamespace(namespaceURI);
}
}
+
// inherited from NodeWithChildren
override
{
@@ -1106,24 +1308,25 @@ class DOMImplementation : dom.DOMImplementation
{
if (newChild.nodeType == dom.NodeType.element)
{
- enforce!DOMException(!_root
- , dom.ExceptionCode.hierarchyRequest);
+ enforce!DOMException(!_root, dom.ExceptionCode
+ .hierarchyRequest);
auto res = super.insertBefore(newChild, refChild);
- _root = cast(Element)newChild;
+ _root = cast(Element) newChild;
return res;
}
else if (newChild.nodeType == dom.NodeType.documentType)
{
- enforce!DOMException(!_doctype
- , dom.ExceptionCode.hierarchyRequest);
+ enforce!DOMException(!_doctype, dom.ExceptionCode
+ .hierarchyRequest);
auto res = super.insertBefore(newChild, refChild);
- _doctype = cast(DocumentType)newChild;
+ _doctype = cast(DocumentType) newChild;
return res;
}
- else if (newChild.nodeType != dom.NodeType.comment &&
- newChild.nodeType != dom.NodeType.processingInstruction)
+ else if (newChild.nodeType != dom.NodeType.comment
+ && newChild.nodeType != dom.NodeType
+ .processingInstruction)
{
throw new DOMException(dom.ExceptionCode.hierarchyRequest);
}
@@ -1132,28 +1335,30 @@ class DOMImplementation : dom.DOMImplementation
return super.insertBefore(newChild, refChild);
}
}
+
Node replaceChild(dom.Node newChild, dom.Node oldChild)
{
if (newChild.nodeType == dom.NodeType.element)
{
- enforce!DOMException(!(oldChild !is _root)
- , dom.ExceptionCode.hierarchyRequest);
+ enforce!DOMException(!(oldChild !is _root), dom.ExceptionCode
+ .hierarchyRequest);
auto res = super.replaceChild(newChild, oldChild);
- _root = cast(Element)newChild;
+ _root = cast(Element) newChild;
return res;
}
else if (newChild.nodeType == dom.NodeType.documentType)
{
- enforce!DOMException(!(oldChild !is _doctype)
- , dom.ExceptionCode.hierarchyRequest);
+ enforce!DOMException(!(oldChild !is _doctype),
+ dom.ExceptionCode.hierarchyRequest);
auto res = super.replaceChild(newChild, oldChild);
- _doctype = cast(DocumentType)newChild;
+ _doctype = cast(DocumentType) newChild;
return res;
}
- else if (newChild.nodeType != dom.NodeType.comment &&
- newChild.nodeType != dom.NodeType.processingInstruction)
+ else if (newChild.nodeType != dom.NodeType.comment
+ && newChild.nodeType != dom.NodeType
+ .processingInstruction)
{
throw new DOMException(dom.ExceptionCode.hierarchyRequest);
}
@@ -1162,6 +1367,7 @@ class DOMImplementation : dom.DOMImplementation
return super.replaceChild(newChild, oldChild);
}
}
+
Node removeChild(dom.Node oldChild)
{
if (oldChild.nodeType == dom.NodeType.element)
@@ -1181,24 +1387,25 @@ class DOMImplementation : dom.DOMImplementation
return super.removeChild(oldChild);
}
}
+
Node appendChild(dom.Node newChild)
{
if (newChild.nodeType == dom.NodeType.element)
{
- enforce!DOMException(!(_root)
- , dom.ExceptionCode.hierarchyRequest);
+ enforce!DOMException(!(_root), dom.ExceptionCode
+ .hierarchyRequest);
auto res = super.appendChild(newChild);
- _root = cast(Element)newChild;
+ this._root = cast(Element) newChild;
return res;
}
else if (newChild.nodeType == dom.NodeType.documentType)
{
- enforce!DOMException(!(_doctype)
- , dom.ExceptionCode.hierarchyRequest);
+ enforce!DOMException(!(_doctype), dom.ExceptionCode
+ .hierarchyRequest);
auto res = super.appendChild(newChild);
- _doctype = cast(DocumentType)newChild;
+ this._doctype = cast(DocumentType) newChild;
return res;
}
else
@@ -1208,22 +1415,27 @@ class DOMImplementation : dom.DOMImplementation
}
}
}
+
alias ElementsByTagName = ElementsByTagNameImpl!false;
alias ElementsByTagNameNS = ElementsByTagNameImpl!true;
+
static class ElementsByTagNameImpl(bool ns) : dom.NodeList
{
- package this() {
+ package this()
+ {
}
+
private Node root;
private Element current;
static if (ns)
{
- private DOMString namespaceURI, localName;
+ private string namespaceURI;
+ private string localName;
}
else
{
- private DOMString tagname;
+ private string tagname;
}
private bool check(Node node)
@@ -1232,7 +1444,7 @@ class DOMImplementation : dom.DOMImplementation
{
if (node.nodeType == dom.NodeType.element)
{
- Element elem = cast(Element)node;
+ Element elem = cast(Element) node;
return elem.namespaceURI == namespaceURI && elem.localName == localName;
}
else
@@ -1248,32 +1460,17 @@ class DOMImplementation : dom.DOMImplementation
private Element findNext(Node node)
{
- if (node.firstChild)
- {
- auto item = node.firstChild;
- if (check(item))
- {
- return cast(Element)item;
- }
- else
- {
- return findNext(item);
- }
- }
- else
- {
- return findNextBack(node);
- }
+ return node.firstChild ? check(node.firstChild)
+ ? cast(Element) node.firstChild
+ : findNext(node.firstChild) : findNextBack(node);
}
+
private Element findNextBack(Node node)
{
if (node.nextSibling)
{
- auto item = node.nextSibling;
-
- return check(item)
- ? cast(Element)item
- : findNext(item);
+ return check(node.nextSibling) ? cast(Element) node
+ .nextSibling : findNext(node.nextSibling);
}
else if (node.parentNode && node.parentNode !is node.ownerDocument)
{
@@ -1300,6 +1497,7 @@ class DOMImplementation : dom.DOMImplementation
}
return res;
}
+
Element item(size_t i)
{
auto res = findNext(root);
@@ -1312,110 +1510,145 @@ class DOMImplementation : dom.DOMImplementation
}
}
// more idiomatic methods
- auto opIndex(size_t i) { return item(i); }
+ auto opIndex(size_t i)
+ {
+ return item(i);
+ }
// range interface
- bool empty() { return current is null; }
- void popFront() { current = findNext(current); }
- auto front() { return current; }
+ bool empty()
+ {
+ return current is null;
+ }
+
+ void popFront()
+ {
+ current = findNext(current);
+ }
+
+ auto front()
+ {
+ return current;
+ }
}
+
/// Implementation of $(LINK2 ../dom/CharacterData, `newxml.dom.CharacterData`)
abstract class CharacterData : Node, dom.CharacterData
{
// specific to CharacterData
override
{
- @property DOMString data() { return _data; }
- @property void data(DOMString newVal) { _data = newVal; }
- @property size_t length() { return _data.length; }
+ @property string data()
+ {
+ return this._data;
+ }
- DOMString substringData(size_t offset, size_t count)
+ @property void data(string newVal)
{
- enforce!DOMException(!(offset > length)
- , dom.ExceptionCode.indexSize);
+ this._data = newVal;
+ }
- import std.algorithm : min;
- return _data[offset..min(offset + count, length)];
+ @property size_t length()
+ {
+ return this._data.length;
}
- void appendData(DOMString arg)
+
+ string substringData(size_t offset, size_t count)
{
- import std.traits : Unqual;
+ enforce!DOMException(!(offset > length), dom.ExceptionCode
+ .indexSize);
- //auto newData = allocator.makeArray!(Unqual!(typeof(_data[0])))(_data.length + arg.length);
+ import std.algorithm.comparison : min;
- _data ~= arg;
+ return this._data[offset .. min(offset + count, length)];
}
- void insertData(size_t offset, DOMString arg)
- {
- import std.traits : Unqual;
- enforce!DOMException(!(offset > length)
- , dom.ExceptionCode.indexSize);
+ void appendData(string arg)
+ {
+ this._data ~= arg;
+ }
- //auto newData = allocator.makeArray!(Unqual!(typeof(_data[0])))(_data.length + arg.length);
- /+CharType[] newData;
- newData.reserve = _data.length + arg.length;
- newData = _data[0 .. offset];
- newData[offset .. (offset + arg.length)] = arg;
- newData[(offset + arg.length) .. $] = _data[offset .. $];
+ void insertData(size_t offset, string arg)
+ {
+ enforce!DOMException(!(offset > length), dom.ExceptionCode
+ .indexSize);
- _data = cast(typeof(_data))newData;+/
- _data.insertData(offset, arg);
+ this._data = this._data[0 .. offset] ~ arg ~ this._data[offset .. $];
}
+
void deleteData(size_t offset, size_t count)
{
- _data.deleteData(offset, count);
+ this._data = this._data[0 .. offset] ~ this._data[offset + count .. $];
}
- void replaceData(size_t offset, size_t count, DOMString arg)
+
+ void replaceData(size_t offset, size_t count, string arg)
{
- _data.deleteData(offset, count);
- _data.insertData(offset, arg);
+ this._data = this._data[0 .. offset] ~ this._data[offset + count .. $];
+ //this._data.deleteData(offset, count);
+ this._data = this._data[0 .. offset] ~ arg ~ this._data[offset .. $];
+ //this._data.insertData(offset, arg);
}
}
+
// inherited from Node
override
{
- @property DOMString nodeValue() { return data; }
- @property void nodeValue(DOMString newVal)
+ @property string nodeValue()
+ {
+ return this.data;
+ }
+
+ @property void nodeValue(string newVal)
+ {
+ enforce!DOMException(!this.readonly, dom.ExceptionCode
+ .noModificationAllowed);
+ this.data = newVal;
+ }
+
+ @property string textContent()
{
- enforce!DOMException(!(readonly)
- , dom.ExceptionCode.noModificationAllowed);
- data = newVal;
+ return this.data;
}
- @property DOMString textContent() { return data; }
- @property void textContent(DOMString newVal)
+
+ @property void textContent(string newVal)
{
- enforce!DOMException(!(readonly)
- , dom.ExceptionCode.noModificationAllowed);
- data = newVal;
+ enforce!DOMException(!this.readonly, dom.ExceptionCode
+ .noModificationAllowed);
+ this.data = newVal;
}
}
private
{
- DOMString _data;
+ string _data;
// internal method
void performClone(CharacterData dest, bool deep)
{
super.performClone(dest, deep);
- dest._data = _data;
+ dest._data = this._data;
}
}
}
+
private abstract class NodeWithNamespace : NodeWithChildren
{
private
{
- DOMString _name, _namespaceURI;
+ string _name;
+ string _namespaceURI;
size_t _colon;
- void setQualifiedName(DOMString name)
+ void setQualifiedName(string name)
{
- _name = name;
- ptrdiff_t i = name.getDString.indexOf(':');
+ this._name = name;
+ ptrdiff_t i = name.indexOf(':');
+
if (i > 0)
+ {
_colon = i;
+ }
}
+
void performClone(NodeWithNamespace dest, bool deep)
{
super.performClone(dest, deep);
@@ -1427,212 +1660,245 @@ class DOMImplementation : dom.DOMImplementation
// inherited from Node
override
{
- @property DOMString nodeName() { return _name; }
-
- @property DOMString localName()
+ @property string nodeName()
{
- return !_colon
- ? null
- : _name[(_colon+1)..$];
+ return this._name;
}
- @property DOMString prefix()
+
+ @property string localName()
{
- return _name[0.._colon];
+ return !this._colon ? null : _name[this._colon + 1 .. $];
}
- @property void prefix(DOMString pre)
+
+ @property string prefix()
{
- enforce!DOMException(!(readonly)
- , dom.ExceptionCode.noModificationAllowed);
+ return this._name[0 .. this._colon];
+ }
- import std.traits : Unqual;
+ @property void prefix(string pre)
+ {
+ enforce!DOMException(!readonly, dom.ExceptionCode
+ .noModificationAllowed);
_name ~= pre;
_name ~= "w";
_name ~= localName;
_colon = pre.length;
}
- @property DOMString namespaceURI() { return _namespaceURI; }
+
+ @property string namespaceURI()
+ {
+ return this._namespaceURI;
+ }
}
}
+
/// Implementation of $(LINK2 ../dom/Attr, `newxml.dom.Attr`)
class Attr : NodeWithNamespace, dom.Attr
{
- package this() {
- //_namespaceURI = new DOMString();
- }
// specific to Attr
override
{
/// Implementation of $(LINK2 ../dom/Attr.name, `newxml.dom.Attr.name`).
- @property DOMString name() { return _name; }
+ @property string name()
+ {
+ return _name;
+ }
/// Implementation of $(LINK2 ../dom/Attr.specified, `newxml.dom.Attr.specified`).
- @property bool specified() { return _specified; }
+ @property bool specified()
+ {
+ return _specified;
+ }
/// Implementation of $(LINK2 ../dom/Attr.value, `newxml.dom.Attr.value`).
- @property DOMString value()
+
+ @property string value()
{
- //auto result = Appender!(typeof(_name[0]), typeof(*allocator))(allocator);
- /* DOMString result = new DOMString();
- auto child = rebindable(firstChild);
- while (child)
- {
- result ~= child.textContent;//result.put(child.textContent);
- child = child.nextSibling;
- }
- return result; */
- Text result = cast(Text)firstChild;
+ Text result = cast(Text) firstChild;
return result.textContent();
}
/// ditto
- @property void value(DOMString newVal)
+ @property void value(string newVal)
{
- while (firstChild)
+ while (this.firstChild)
{
- removeChild(firstChild);
+ this.removeChild(this.firstChild);
}
- appendChild(ownerDocument.createTextNode(newVal));
+ this.appendChild(this.ownerDocument.createTextNode(newVal));
}
/// Implementation of $(LINK2 ../dom/Attr.ownerElement, `newxml.dom.Attr.ownerElement`).
- @property Element ownerElement() { return _ownerElement; }
+ @property Element ownerElement()
+ {
+ return this._ownerElement;
+ }
/// Implementation of $(LINK2 ../dom/Attr.schemaTypeInfo, `newxml.dom.Attr.schemaTypeInfo`).
- @property dom.XMLTypeInfo schemaTypeInfo() { return null; }
+ @property dom.XMLTypeInfo schemaTypeInfo()
+ {
+ return null;
+ }
/// Implementation of $(LINK2 ../dom/Attr.isId, `newxml.dom.Attr.isId`).
- @property bool isId() { return _isId; }
+ @property bool isId()
+ {
+ return this._isId;
+ }
}
private
{
Element _ownerElement;
- bool _specified = true, _isId = false;
- @property Attr _nextAttr() { return cast(Attr)_nextSibling; }
- @property Attr _previousAttr() { return cast(Attr)_previousSibling; }
+ bool _specified = true;
+ bool _isId = false;
+
+ @property Attr _nextAttr()
+ {
+ return cast(Attr) this._nextSibling;
+ }
+
+ @property Attr _previousAttr()
+ {
+ return cast(Attr) this._previousSibling;
+ }
}
+
// inherited from Node
override
{
- @property dom.NodeType nodeType() { return dom.NodeType.attribute; }
+ @property dom.NodeType nodeType()
+ {
+ return dom.NodeType.attribute;
+ }
- @property DOMString nodeValue() { return value; }
- @property void nodeValue(DOMString newVal)
+ @property string nodeValue()
{
- enforce!DOMException(!(readonly)
- , dom.ExceptionCode.noModificationAllowed);
+ return value;
+ }
+
+ @property void nodeValue(string newVal)
+ {
+ enforce!DOMException(!(readonly), dom.ExceptionCode
+ .noModificationAllowed);
value = newVal;
}
// overridden because we reuse _nextSibling and _previousSibling with another meaning
- @property Attr nextSibling() { return null; }
- @property Attr previousSibling() { return null; }
+ @property Attr nextSibling()
+ {
+ return null;
+ }
+
+ @property Attr previousSibling()
+ {
+ return null;
+ }
Attr cloneNode(bool deep)
{
Attr cloned = new Attr();
- cloned._ownerDocument = _ownerDocument;
+ cloned._ownerDocument = this._ownerDocument;
super.performClone(cloned, true);
cloned._specified = true;
return cloned;
}
- DOMString lookupPrefix(DOMString namespaceURI)
+ string lookupPrefix(string namespaceURI)
{
- return ownerElement
- ? ownerElement.lookupPrefix(namespaceURI)
- : null;
+ return ownerElement ? ownerElement.lookupPrefix(namespaceURI) : null;
}
- DOMString lookupNamespaceURI(DOMString prefix)
+
+ string lookupNamespaceURI(string prefix)
{
- return ownerElement
- ? ownerElement.lookupNamespaceURI(prefix)
- : null;
+ return ownerElement ? ownerElement.lookupNamespaceURI(prefix) : null;
}
- bool isDefaultNamespace(DOMString namespaceURI)
+
+ bool isDefaultNamespace(string namespaceURI)
{
- return ownerElement
- ? ownerElement.isDefaultNamespace(namespaceURI)
- : false;
+ return ownerElement ? ownerElement.isDefaultNamespace(namespaceURI) : false;
}
}
}
/// Implementation of $(LINK2 ../dom/Element, `newxml.dom.Element`)
class Element : NodeWithNamespace, dom.Element
{
- package this() {
+ package this()
+ {
}
///Created as a workaround to a common D compiler bug/artifact.
- package Map createMap() {
+ package Map createMap()
+ {
return new Map();
}
// specific to Element
override
{
/// Implementation of $(LINK2 ../dom/Element.tagName, `newxml.dom.Element.tagName`).
- @property DOMString tagName() { return _name; }
+ @property string tagName()
+ {
+ return _name;
+ }
/++
+ Implementation of $(LINK2 ../dom/Element.getAttribute,
+ `newxml.dom.Element.getAttribute`).
+/
- DOMString getAttribute(DOMString name)
+ string getAttribute(string name)
{
auto result = _attrs.getNamedItem(name);
- if (result)
- {
- return result.value;
- }
- else
- {
- return null;
- }
+ return result ? result.value : null;
}
+
/++
+ Implementation of $(LINK2 ../dom/Element.setAttribute,
+ `newxml.dom.Element.setAttribute`).
+/
- void setAttribute(DOMString name, DOMString value)
+ void setAttribute(string name, string value)
{
auto attr = ownerDocument.createAttribute(name);
attr.nodeValue = value;
attr._ownerElement = this;
- _attrs.setNamedItem(attr);
+ this._attrs.setNamedItem(attr);
}
+
/++
+ Implementation of $(LINK2 ../dom/Element.removeAttribute,
+ `newxml.dom.Element.removeAttribute`).
+/
- void removeAttribute(DOMString name)
+ void removeAttribute(string name)
{
- _attrs.removeNamedItem(name);
+ this._attrs.removeNamedItem(name);
}
/++
+ Implementation of $(LINK2 ../dom/Element.getAttributeNode,
+ `newxml.dom.Element.getAttributeNode`).
+/
- Attr getAttributeNode(DOMString name)
+ Attr getAttributeNode(string name)
{
- return _attrs.getNamedItem(name);
+ return this._attrs.getNamedItem(name);
}
+
/++
+ Implementation of $(LINK2 ../dom/Element.setAttributeNode,
+ `newxml.dom.Element.setAttributeNode`).
+/
Attr setAttributeNode(dom.Attr newAttr)
{
- return _attrs.setNamedItem(newAttr);
+ return this._attrs.setNamedItem(newAttr);
}
+
/++
+ Implementation of $(LINK2 ../dom/Element.removeAttributeNode,
+ `newxml.dom.Element.removeAttributeNode`).
+/
Attr removeAttributeNode(dom.Attr oldAttr)
{
- if (_attrs.getNamedItemNS(oldAttr.namespaceURI, oldAttr.name) is oldAttr)
+ if (this._attrs.getNamedItemNS(oldAttr.namespaceURI, oldAttr.name) is oldAttr)
{
- return _attrs.removeNamedItemNS(oldAttr.namespaceURI, oldAttr.name);
+ return this._attrs.removeNamedItemNS(oldAttr.namespaceURI, oldAttr
+ .name);
}
- else if (_attrs.getNamedItem(oldAttr.name) is oldAttr)
+ else if (this._attrs.getNamedItem(oldAttr.name) is oldAttr)
{
- return _attrs.removeNamedItem(oldAttr.name);
+ return this._attrs.removeNamedItem(oldAttr.name);
}
throw new DOMException(dom.ExceptionCode.notFound);
@@ -1642,48 +1908,44 @@ class DOMImplementation : dom.DOMImplementation
+ Implementation of $(LINK2 ../dom/Element.getAttributeNS,
+ `newxml.dom.Element.getAttributeNS`).
+/
- DOMString getAttributeNS(DOMString namespaceURI, DOMString localName)
+ string getAttributeNS(string namespaceURI, string localName)
{
- auto result = _attrs.getNamedItemNS(namespaceURI, localName);
- if (result)
- {
- return result.value;
- }
- else
- {
- return null;
- }
+ auto result = this._attrs.getNamedItemNS(namespaceURI, localName);
+ return result ? result.value : null;
}
/++
+ Implementation of $(LINK2 ../dom/Element.setAttributeNS,
+ `newxml.dom.Element.setAttributeNS`).
+/
- void setAttributeNS(DOMString namespaceURI, DOMString qualifiedName, DOMString value)
+ void setAttributeNS(string namespaceURI, string qualifiedName, string value)
{
+ import std.exception : enforce;
+
auto attr = ownerDocument.createAttributeNS(namespaceURI, qualifiedName);
attr.nodeValue = value;
attr._ownerElement = this;
- assert(attr.nodeValue == value);
- _attrs.setNamedItemNS(attr);
- assert(_attrs.getNamedItemNS(namespaceURI, qualifiedName));
- assert(_attrs.getNamedItemNS(namespaceURI, qualifiedName).nodeValue);
+ enforce(attr.nodeValue == value);
+ this._attrs.setNamedItemNS(attr);
+ enforce(this._attrs.getNamedItemNS(namespaceURI, qualifiedName));
+ enforce(this._attrs.getNamedItemNS(namespaceURI, qualifiedName)
+ .nodeValue);
}
/++
+ Implementation of $(LINK2 ../dom/Element.removeAttributeNS,
+ `newxml.dom.Element.removeAttributeNS`).
+/
- void removeAttributeNS(DOMString namespaceURI, DOMString localName)
+ void removeAttributeNS(string namespaceURI, string localName)
{
- _attrs.removeNamedItemNS(namespaceURI, localName);
+ this._attrs.removeNamedItemNS(namespaceURI, localName);
}
/++
+ Implementation of $(LINK2 ../dom/Element.getAttributeNodeNS,
+ `newxml.dom.Element.getAttributeNodeNS`).
+/
- Attr getAttributeNodeNS(DOMString namespaceURI, DOMString localName)
+ Attr getAttributeNodeNS(string namespaceURI, string localName)
{
- return _attrs.getNamedItemNS(namespaceURI, localName);
+ return this._attrs.getNamedItemNS(namespaceURI, localName);
}
/++
+ Implementation of $(LINK2 ../dom/Element.setAttributeNodeNS,
@@ -1691,58 +1953,48 @@ class DOMImplementation : dom.DOMImplementation
+/
Attr setAttributeNodeNS(dom.Attr newAttr)
{
- return _attrs.setNamedItemNS(newAttr);
+ return this._attrs.setNamedItemNS(newAttr);
}
/++
+ Implementation of $(LINK2 ../dom/Element.hasAttribute,
+ `newxml.dom.Element.hasAttribute`).
+/
- bool hasAttribute(DOMString name)
+ bool hasAttribute(string name)
{
- return _attrs.getNamedItem(name) !is null;
+ return this._attrs.getNamedItem(name) !is null;
}
/++
+ Implementation of $(LINK2 ../dom/Element.hasAttributeNS,
+ `newxml.dom.Element.hasAttributeNS`).
+/
- bool hasAttributeNS(DOMString namespaceURI, DOMString localName)
+ bool hasAttributeNS(string namespaceURI, string localName)
{
- return _attrs.getNamedItemNS(namespaceURI, localName) !is null;
+ return this._attrs.getNamedItemNS(namespaceURI, localName) !is null;
}
/++
+ Implementation of $(LINK2 ../dom/Element.setIdAttribute,
+ `newxml.dom.Element.setIdAttribute`).
+/
- void setIdAttribute(DOMString name, bool isId)
+ void setIdAttribute(string name, bool isId)
{
auto attr = _attrs.getNamedItem(name);
- if (attr)
- {
- attr._isId = isId;
- }
- else
- {
- throw new DOMException(dom.ExceptionCode.notFound);
- }
+ enforce!(DOMException)(attr !is null, dom.ExceptionCode.notFound);
+ attr._isId = isId;
}
+
/++
+ Implementation of $(LINK2 ../dom/Element.setIdAttributeNS,
+ `newxml.dom.Element.setIdAttributeNS`).
+/
- void setIdAttributeNS(DOMString namespaceURI, DOMString localName, bool isId)
+ void setIdAttributeNS(string namespaceURI, string localName, bool isId)
{
auto attr = _attrs.getNamedItemNS(namespaceURI, localName);
- if (attr)
- {
- attr._isId = isId;
- }
- else
- {
- throw new DOMException(dom.ExceptionCode.notFound);
- }
+ enforce!(DOMException)(attr !is null, dom.ExceptionCode.notFound);
+ attr._isId = isId;
}
+
/++
+ Implementation of $(LINK2 ../dom/Element.getAttribute,
+ `newxml.dom.Element.getAttribute`).
@@ -1751,11 +2003,11 @@ class DOMImplementation : dom.DOMImplementation
{
if (_attrs.getNamedItemNS(idAttr.namespaceURI, idAttr.name) is idAttr)
{
- (cast(Attr)idAttr)._isId = isId;
+ (cast(Attr) idAttr)._isId = isId;
}
else if (_attrs.getNamedItem(idAttr.name) is idAttr)
{
- (cast(Attr)idAttr)._isId = isId;
+ (cast(Attr) idAttr)._isId = isId;
}
else
{
@@ -1767,7 +2019,7 @@ class DOMImplementation : dom.DOMImplementation
+ Implementation of $(LINK2 ../dom/Element.getElementsByTagName,
+ `newxml.dom.Element.getElementsByTagName`).
+/
- ElementsByTagName getElementsByTagName(DOMString tagname)
+ ElementsByTagName getElementsByTagName(string tagname)
{
ElementsByTagName res = new ElementsByTagName();
res.root = this;
@@ -1775,11 +2027,12 @@ class DOMImplementation : dom.DOMImplementation
res.current = res.item(0);
return res;
}
+
/++
+ Implementation of $(LINK2 ../dom/Element.getElementsByTagNameNS,
+ `newxml.dom.Element.getElementsByTagNameNS`).
+/
- ElementsByTagNameNS getElementsByTagNameNS(DOMString namespaceURI, DOMString localName)
+ ElementsByTagNameNS getElementsByTagNameNS(string namespaceURI, string localName)
{
ElementsByTagNameNS res = new ElementsByTagNameNS();
res.root = this;
@@ -1793,45 +2046,60 @@ class DOMImplementation : dom.DOMImplementation
+ Implementation of $(LINK2 ../dom/Element.schemaTypeInfo,
+ `newxml.dom.Element.schemaTypeInfo`).
+/
- @property dom.XMLTypeInfo schemaTypeInfo() { return null; }
+ @property dom.XMLTypeInfo schemaTypeInfo()
+ {
+ return null;
+ }
}
private
{
Map _attrs;
// internal methods
- DOMString lookupNamespacePrefix(DOMString namespaceURI, Element originalElement)
+ string lookupNamespacePrefix(string namespaceURI, Element originalElement)
{
if (this.namespaceURI && this.namespaceURI == namespaceURI
- && this.prefix && originalElement.lookupNamespaceURI(this.prefix) == namespaceURI)
+ && this.prefix && originalElement.lookupNamespaceURI(
+ this.prefix) == namespaceURI)
{
return this.prefix;
}
- if (hasAttributes)
+ if (this.hasAttributes)
{
foreach (attr; attributes)
{
- if (attr.prefix == "xmlns" && attr.nodeValue == namespaceURI &&
- originalElement.lookupNamespaceURI(attr.localName) == namespaceURI)
+ if (attr.prefix == "xmlns"
+ && attr.nodeValue == namespaceURI
+ && originalElement.lookupNamespaceURI(
+ attr.localName) == namespaceURI)
{
return attr.localName;
}
}
}
auto parentElement = parentElement();
- return parentElement
- ? parentElement.lookupNamespacePrefix(namespaceURI, originalElement)
- : null;
+ return parentElement ? parentElement.lookupNamespacePrefix(
+ namespaceURI, originalElement) : null;
}
}
// inherited from Node
override
{
- @property dom.NodeType nodeType() { return dom.NodeType.element; }
+ @property dom.NodeType nodeType()
+ {
+ return dom.NodeType.element;
+ }
+
+ @property Map attributes()
+ {
+ return this._attrs.length > 0 ? _attrs : null;
+ }
- @property Map attributes() { return _attrs.length > 0 ? _attrs : null; }
- bool hasAttributes() { return _attrs.length > 0; }
+ bool hasAttributes()
+ {
+ return this._attrs.length > 0;
+ }
Element cloneNode(bool deep)
{
@@ -1842,20 +2110,21 @@ class DOMImplementation : dom.DOMImplementation
return cloned;
}
- DOMString lookupPrefix(DOMString namespaceURI)
+ string lookupPrefix(string namespaceURI)
{
return lookupNamespacePrefix(namespaceURI, this);
}
- DOMString lookupNamespaceURI(DOMString prefix)
+
+ string lookupNamespaceURI(string prefix)
{
if (namespaceURI && prefix == prefix)
{
return namespaceURI;
}
- if (hasAttributes)
+ if (this.hasAttributes)
{
- foreach (attr; attributes)
+ foreach (attr; this.attributes)
{
if (attr.prefix == "xmlns" && attr.localName == prefix)
{
@@ -1867,14 +2136,12 @@ class DOMImplementation : dom.DOMImplementation
}
}
}
- auto parentElement = parentElement();
- if (parentElement)
- {
- return parentElement.lookupNamespaceURI(prefix);
- }
- return null;
+
+ auto parentElement = this.parentElement();
+ return parentElement ? parentElement.lookupNamespaceURI(prefix) : null;
}
- bool isDefaultNamespace(DOMString namespaceURI)
+
+ bool isDefaultNamespace(string namespaceURI)
{
if (!prefix)
{
@@ -1891,16 +2158,16 @@ class DOMImplementation : dom.DOMImplementation
}
}
}
+
auto parentElement = parentElement();
- return parentElement
- ? parentElement.isDefaultNamespace(namespaceURI)
- : false;
+ return parentElement ? parentElement.isDefaultNamespace(namespaceURI) : false;
}
}
class Map : dom.NamedNodeMap
{
- package this() {
+ package this()
+ {
}
// specific to NamedNodeMap
@@ -1909,7 +2176,7 @@ class DOMImplementation : dom.DOMImplementation
size_t length()
{
size_t res = 0;
- auto attr = firstAttr;
+ auto attr = this.firstAttr;
while (attr)
{
res++;
@@ -1917,10 +2184,11 @@ class DOMImplementation : dom.DOMImplementation
}
return res;
}
+
Attr item(size_t index)
{
size_t count = 0;
- auto res = firstAttr;
+ auto res = this.firstAttr;
while (res && count < index)
{
count++;
@@ -1929,23 +2197,25 @@ class DOMImplementation : dom.DOMImplementation
return res;
}
- Attr getNamedItem(DOMString name)
+ Attr getNamedItem(string name)
{
- Attr res = firstAttr;
+ Attr res = this.firstAttr;
while (res && res.nodeName != name)
{
res = res._nextAttr;
}
return res;
}
+
Attr setNamedItem(dom.Node arg)
{
- enforce!DOMException(!(arg.ownerDocument !is this.outer.ownerDocument)
- , dom.ExceptionCode.wrongDocument);
+ enforce!DOMException(
+ arg.ownerDocument is this.outer.ownerDocument,
+ dom.ExceptionCode.wrongDocument);
- Attr attr = cast(Attr)arg;
- enforce!DOMException(!(!attr)
- , dom.ExceptionCode.hierarchyRequest);
+ Attr attr = cast(Attr) arg;
+ enforce!DOMException(attr !is null, dom.ExceptionCode
+ .hierarchyRequest);
if (attr._previousAttr)
{
@@ -1957,7 +2227,7 @@ class DOMImplementation : dom.DOMImplementation
attr._nextAttr._previousSibling = attr._previousAttr;
}
- auto res = firstAttr;
+ auto res = this.firstAttr;
while (res && res.nodeName != attr.nodeName)
{
res = res._nextAttr;
@@ -1967,21 +2237,25 @@ class DOMImplementation : dom.DOMImplementation
{
attr._previousSibling = res._previousAttr;
attr._nextSibling = res._nextAttr;
- if (res is firstAttr) firstAttr = attr;
+ if (res is firstAttr)
+ {
+ firstAttr = attr;
+ }
}
else
{
- attr._nextSibling = firstAttr;
- firstAttr = attr;
+ attr._nextSibling = this.firstAttr;
+ this.firstAttr = attr;
attr._previousSibling = null;
- currentAttr = firstAttr;
+ currentAttr = this.firstAttr;
}
return res;
}
- Attr removeNamedItem(DOMString name)
+
+ Attr removeNamedItem(string name)
{
- auto res = firstAttr;
+ auto res = this.firstAttr;
while (res && res.nodeName != name)
{
res = res._nextAttr;
@@ -2005,25 +2279,26 @@ class DOMImplementation : dom.DOMImplementation
}
}
- Attr getNamedItemNS(DOMString namespaceURI, DOMString localName)
+ Attr getNamedItemNS(string namespaceURI, string localName)
{
- Attr res = firstAttr;
+ Attr res = this.firstAttr;
while (res && (res.localName != localName || res.namespaceURI != namespaceURI))
{
assert(res.localName != localName || res.namespaceURI != namespaceURI);
res = res._nextAttr;
}
return res;
-
}
+
Attr setNamedItemNS(dom.Node arg)
{
- enforce!DOMException(!(arg.ownerDocument !is this.outer.ownerDocument)
- , dom.ExceptionCode.wrongDocument);
+ enforce!DOMException(
+ !(arg.ownerDocument !is this.outer.ownerDocument),
+ dom.ExceptionCode.wrongDocument);
- Attr attr = cast(Attr)arg;
- enforce!DOMException(!(!attr)
- , dom.ExceptionCode.hierarchyRequest);
+ Attr attr = cast(Attr) arg;
+ enforce!DOMException(!attr, dom.ExceptionCode
+ .hierarchyRequest);
if (attr._previousAttr)
{
@@ -2034,9 +2309,9 @@ class DOMImplementation : dom.DOMImplementation
attr._nextAttr._previousSibling = attr._previousAttr;
}
- auto res = firstAttr;
+ auto res = this.firstAttr;
while (res && (res.localName != attr.localName
- || res.namespaceURI != attr.namespaceURI))
+ || res.namespaceURI != attr.namespaceURI))
{
res = res._nextAttr;
}
@@ -2045,7 +2320,10 @@ class DOMImplementation : dom.DOMImplementation
{
attr._previousSibling = res._previousAttr;
attr._nextSibling = res._nextAttr;
- if (res is firstAttr) firstAttr = attr;
+ if (res is firstAttr)
+ {
+ firstAttr = attr;
+ }
}
else
{
@@ -2057,41 +2335,41 @@ class DOMImplementation : dom.DOMImplementation
return res;
}
- Attr removeNamedItemNS(DOMString namespaceURI, DOMString localName)
+
+ Attr removeNamedItemNS(string namespaceURI, string localName)
{
auto res = firstAttr;
- while (res && (res.localName != localName
- || res.namespaceURI != namespaceURI))
+ while (res && (res.localName != localName || res.namespaceURI != namespaceURI))
{
res = res._nextAttr;
}
- if (res)
+ enforce!(DOMException)(!res, dom.ExceptionCode.notFound);
+
+ if (res._previousAttr)
{
- if (res._previousAttr)
- {
- res._previousAttr._nextSibling = res._nextAttr;
- }
- if (res._nextAttr)
- {
- res._nextAttr._previousSibling = res._previousAttr;
- }
- return res;
+ res._previousAttr._nextSibling = res._nextAttr;
}
- else
+ if (res._nextAttr)
{
- throw new DOMException(dom.ExceptionCode.notFound);
+ res._nextAttr._previousSibling = res._previousAttr;
}
+ return res;
}
}
+
private
{
Attr firstAttr;
Attr currentAttr;
}
+
// better methods
- auto opIndex(size_t i) { return item(i); }
-
+ auto opIndex(size_t i)
+ {
+ return item(i);
+ }
+
// range interface
auto opSlice()
{
@@ -2099,77 +2377,89 @@ class DOMImplementation : dom.DOMImplementation
{
Attr currentAttr;
- auto front() { return currentAttr; }
- void popFront() { currentAttr = currentAttr._nextAttr; }
- bool empty() { return currentAttr is null; }
+ auto front()
+ {
+ return this.currentAttr;
+ }
+
+ void popFront()
+ {
+ this.currentAttr = this.currentAttr._nextAttr;
+ }
+
+ bool empty()
+ {
+ return this.currentAttr is null;
+ }
}
- return Range(firstAttr);
+
+ return Range(this.firstAttr);
}
}
}
/// Implementation of $(LINK2 ../dom/Text, `newxml.dom.Text`)
- class Text: CharacterData, dom.Text
+ class Text : CharacterData, dom.Text
{
- package this() {
-
- }
// specific to Text
override
{
/// Implementation of $(LINK2 ../dom/Text.splitText, `newxml.dom.Text.splitText`).
Text splitText(size_t offset)
{
- enforce!DOMException(!(offset > data.length)
- , dom.ExceptionCode.indexSize);
- auto second = ownerDocument.createTextNode(data[offset..$]);
- data = data[0..offset];
+ enforce!DOMException(!(offset > data.length), dom.ExceptionCode
+ .indexSize);
+ auto second = ownerDocument.createTextNode(this.data[offset .. $]);
+ data = this.data[0 .. offset];
+
if (parentNode)
{
if (nextSibling)
{
- parentNode.insertBefore(second, nextSibling);
+ this.parentNode.insertBefore(second, nextSibling);
}
else
{
- parentNode.appendChild(second);
+ this.parentNode.appendChild(second);
}
}
return second;
}
+
/++
+ Implementation of $(LINK2 ../dom/Text.isElementContentWhitespace,
+ `newxml.dom.Text.isElementContentWhitespace`).
+/
@property bool isElementContentWhitespace()
{
- return _data.getDString.indexOfNeither(" \r\n\t") == -1;
+ return this._data.indexOfNeither(" \r\n\t") == -1;
}
+
/// Implementation of $(LINK2 ../dom/Text.wholeText, `newxml.dom.Text.wholeText`).
- @property DOMString wholeText()
+ @property string wholeText()
{
Text findPreviousText(Text text)
{
Node node = text;
do
{
- if (node.previousSibling)
- switch (node.previousSibling.nodeType) with (dom.NodeType)
- {
- case text:
- case cdataSection:
- return cast(Text) node.previousSibling;
- case entityReference:
- return cast(Text)(node.previousSibling.lastChild)
- ? cast(Text) node.previousSibling.lastChild
- : null;
- default:
- return null;
- }
+ if (node.previousSibling) switch (node.previousSibling
+ .nodeType) with (dom.NodeType)
+ {
+ case text:
+ case cdataSection:
+ return cast(Text) node.previousSibling;
+ case entityReference:
+ return cast(Text)(node.previousSibling.lastChild) ? cast(
+ Text) node.previousSibling.lastChild : null;
+ default:
+ return null;
+ }
node = node.parentNode;
}
while (node && node.nodeType == dom.NodeType.entityReference);
return null;
}
+
Text findNextText(Text text)
{
Node node = text;
@@ -2179,15 +2469,14 @@ class DOMImplementation : dom.DOMImplementation
{
switch (node.nextSibling.nodeType) with (dom.NodeType)
{
- case text:
- case cdataSection:
- return cast(Text) node.nextSibling;
- case entityReference:
- return cast(Text)(node.nextSibling.firstChild)
- ? cast(Text) node.nextSibling.firstChild
- : null;
- default:
- return null;
+ case text:
+ case cdataSection:
+ return cast(Text) node.nextSibling;
+ case entityReference:
+ return cast(Text)(node.nextSibling.firstChild) ? cast(
+ Text) node.nextSibling.firstChild : null;
+ default:
+ return null;
}
}
node = node.parentNode;
@@ -2197,10 +2486,10 @@ class DOMImplementation : dom.DOMImplementation
return null;
}
- //import newxml.appender;
- DOMString result;//auto result = Appender!(typeof(_data[0]), typeof(*allocator))(allocator);
+ string result;
- Text node, prev = this;
+ Text node;
+ Text prev = this;
do
{
node = prev;
@@ -2215,12 +2504,13 @@ class DOMImplementation : dom.DOMImplementation
}
return result;
}
+
/++
+ Implementation of $(LINK2 ../dom/Text.replaceWholeText,
+ `newxml.dom.Text.replaceWholeText`).
+/
// the W3C DOM spec explains the details of this
- @property Text replaceWholeText(DOMString newText)
+ @property Text replaceWholeText(string newText)
{
bool hasOnlyText(Node reference) @safe
{
@@ -2228,19 +2518,20 @@ class DOMImplementation : dom.DOMImplementation
{
switch (child.nodeType) with (dom.NodeType)
{
- case text:
- case cdataSection:
- break;
- case entityReference:
- if (!hasOnlyText(reference))
- return false;
- break;
- default:
+ case text:
+ case cdataSection:
+ break;
+ case entityReference:
+ if (!hasOnlyText(reference))
return false;
+ break;
+ default:
+ return false;
}
}
return false;
}
+
bool startsWithText(Node reference)
{
if (!reference.firstChild)
@@ -2250,15 +2541,16 @@ class DOMImplementation : dom.DOMImplementation
switch (reference.firstChild.nodeType) with (dom.NodeType)
{
- case text:
- case cdataSection:
- return true;
- case entityReference:
- return startsWithText(reference.firstChild);
- default:
- return false;
+ case text:
+ case cdataSection:
+ return true;
+ case entityReference:
+ return startsWithText(reference.firstChild);
+ default:
+ return false;
}
}
+
bool endsWithText(Node reference)
{
if (!reference.lastChild)
@@ -2267,39 +2559,42 @@ class DOMImplementation : dom.DOMImplementation
}
switch (reference.lastChild.nodeType) with (dom.NodeType)
{
- case text:
- case cdataSection:
- return true;
- case entityReference:
- return endsWithText(reference.lastChild);
- default:
- return false;
+ case text:
+ case cdataSection:
+ return true;
+ case entityReference:
+ return endsWithText(reference.lastChild);
+ default:
+ return false;
}
}
Node current;
- if (parentNode && parentNode.nodeType == dom.NodeType.entityReference)
+ if (parentNode && parentNode.nodeType == dom.NodeType
+ .entityReference)
{
current = parentNode;
- while (current.parentNode
- && current.parentNode.nodeType == dom.NodeType.entityReference)
+ while (current.parentNode && current.parentNode.nodeType
+ == dom.NodeType.entityReference)
{
current = current.parentNode;
}
- enforce!DOMException(!(!hasOnlyText(current))
- , dom.ExceptionCode.noModificationAllowed);
+ enforce!DOMException(!hasOnlyText(current),
+ dom.ExceptionCode.noModificationAllowed);
}
- else if (readonly)
+ else if (this.readonly)
{
- throw new DOMException(dom.ExceptionCode.noModificationAllowed);
+ throw new DOMException(dom.ExceptionCode
+ .noModificationAllowed);
}
else
{
current = this;
}
- size_t previousToKill, nextToKill;
+ size_t previousToKill;
+ size_t nextToKill;
auto node = current.previousSibling;
while (node)
{
@@ -2307,15 +2602,15 @@ class DOMImplementation : dom.DOMImplementation
{
if (endsWithText(node))
{
- enforce!DOMException(!(!hasOnlyText(node))
- , dom.ExceptionCode.noModificationAllowed);
+ enforce!DOMException(!(!hasOnlyText(node)),
+ dom.ExceptionCode.noModificationAllowed);
}
else
{
break;
}
}
- else if (!cast(Text)node)
+ else if (!cast(Text) node)
{
break;
}
@@ -2323,6 +2618,7 @@ class DOMImplementation : dom.DOMImplementation
previousToKill++;
node = node.previousSibling;
}
+
node = current.nextSibling;
while (node)
{
@@ -2330,15 +2626,15 @@ class DOMImplementation : dom.DOMImplementation
{
if (startsWithText(node))
{
- enforce!DOMException(!(!hasOnlyText(node))
- , dom.ExceptionCode.noModificationAllowed);
+ enforce!DOMException(!(!hasOnlyText(node)),
+ dom.ExceptionCode.noModificationAllowed);
}
else
{
break;
}
}
- else if (!cast(Text)node)
+ else if (!cast(Text) node)
{
break;
}
@@ -2347,12 +2643,12 @@ class DOMImplementation : dom.DOMImplementation
node = node.nextSibling;
}
- foreach (i; 0..previousToKill)
+ foreach (i; 0 .. previousToKill)
{
current.parentNode.removeChild(current.previousSibling);
}
- foreach (i; 0..nextToKill)
+ foreach (i; 0 .. nextToKill)
{
current.parentNode.removeChild(current.nextSibling);
}
@@ -2371,19 +2667,25 @@ class DOMImplementation : dom.DOMImplementation
current.removeChild(current);
}
- return !newText
- ? null
- : ownerDocument.createTextNode(newText);
+ return !newText ? null : ownerDocument.createTextNode(newText);
}
- _data = newText;
+
+ this._data = newText;
return this;
}
}
// inherited from Node
override
{
- @property dom.NodeType nodeType() { return dom.NodeType.text; }
- @property DOMString nodeName() { return new DOMString("#text"); }
+ @property dom.NodeType nodeType()
+ {
+ return dom.NodeType.text;
+ }
+
+ @property string nodeName()
+ {
+ return "#text";
+ }
Text cloneNode(bool deep)
{
@@ -2397,14 +2699,22 @@ class DOMImplementation : dom.DOMImplementation
/// Implementation of $(LINK2 ../dom/Comment, `newxml.dom.Comment`)
class Comment : CharacterData, dom.Comment
{
- package this() {
+ package this()
+ {
}
// inherited from Node
override
{
- @property dom.NodeType nodeType() { return dom.NodeType.comment; }
- @property DOMString nodeName() { return new DOMString("#comment"); }
+ @property dom.NodeType nodeType()
+ {
+ return dom.NodeType.comment;
+ }
+
+ @property string nodeName()
+ {
+ return "#comment";
+ }
Comment cloneNode(bool deep)
{
@@ -2419,84 +2729,122 @@ class DOMImplementation : dom.DOMImplementation
class DocumentType : Node, dom.DocumentType
{
package dom.NamedNodeMap _entities;
- package this() {
+ package this()
+ {
_entities = new NamedNodeMap();
}
- package void createEntity(DOMString _name, DOMString content) {
+
+ package void createEntity(string _name, string content)
+ {
_entities.setNamedItem(new Entity(_name, content, null));
}
// specific to DocumentType
override
{
/// Implementation of $(LINK2 ../dom/DocumentType.name, `newxml.dom.DocumentType.name`).
- @property DOMString name() { return _name; }
+ @property string name()
+ {
+ return this._name;
+ }
/++
+ Implementation of $(LINK2 ../dom/DocumentType.entities,
+ `newxml.dom.DocumentType.entities`).
+/
- @property dom.NamedNodeMap entities() { return _entities; }
+ @property dom.NamedNodeMap entities()
+ {
+ return this._entities;
+ }
/++
+ Implementation of $(LINK2 ../dom/DocumentType.notations,
+ `newxml.dom.DocumentType.notations`).
+/
- @property dom.NamedNodeMap notations() { return null; }
+ @property dom.NamedNodeMap notations()
+ {
+ return null;
+ }
/++
+ Implementation of $(LINK2 ../dom/DocumentType.publicId,
+ `newxml.dom.DocumentType.publicId`).
+/
- @property DOMString publicId() { return _publicId; }
+ @property string publicId()
+ {
+ return this._publicId;
+ }
/++
+ Implementation of $(LINK2 ../dom/DocumentType.systemId,
+ `newxml.dom.DocumentType.systemId`).
+/
- @property DOMString systemId() { return _systemId; }
+ @property string systemId()
+ {
+ return this._systemId;
+ }
/++
+ Implementation of $(LINK2 ../dom/DocumentType.internalSubset,
+ `newxml.dom.DocumentType.internalSubset`).
+/
- @property DOMString internalSubset() { return _internalSubset; }
+ @property string internalSubset()
+ {
+ return this._internalSubset;
+ }
+ }
+
+ private
+ {
+ string _name;
+ string _publicId;
+ string _systemId;
+ string _internalSubset;
}
- private DOMString _name, _publicId, _systemId, _internalSubset;
+
// inherited from Node
override
{
- @property dom.NodeType nodeType() { return dom.NodeType.documentType; }
- @property DOMString nodeName() { return _name; }
+ @property dom.NodeType nodeType()
+ {
+ return dom.NodeType.documentType;
+ }
+
+ @property string nodeName()
+ {
+ return this._name;
+ }
}
- class NamedNodeMap : dom.NamedNodeMap
+
+ class NamedNodeMap : dom.NamedNodeMap
{
package dom.Node[] nodes;
- package this()
- {
- }
/++
+ Returns the `index`th item in the collection. If `index` is greater than
+ or equal to the number of nodes in the list, this returns `null`.
+/
dom.Node item(size_t index)
{
- return nodes[index];
+ return this.nodes[index];
}
+
/++
+ The number of nodes in the list. The range of valid child node indices is
+ `0` to `length-1` inclusive.
+/
@property size_t length()
{
- return nodes.length;
+ return this.nodes.length;
}
+
/// Retrieves a node specified by name.
- dom.Node getNamedItem(DOMString name)
+ dom.Node getNamedItem(string name)
{
- foreach (dom.Node key; nodes) {
- if (key.nodeName == name)
+ foreach (dom.Node key; this.nodes)
+ {
+ if (key.nodeName == name)
{
return key;
}
}
return null;
}
+
/++
+ Adds a node using its `nodeName` attribute. If a node with that name is
+ already present in this map, it is replaced by the new one. Replacing a
@@ -2508,30 +2856,31 @@ class DOMImplementation : dom.DOMImplementation
+/
dom.Node setNamedItem(dom.Node arg)
{
- foreach (size_t i, dom.Node key; nodes) {
- if (key.nodeName == name)
+ foreach (size_t i, dom.Node key; this.nodes)
+ {
+ if (key.nodeName == name)
{
- nodes[i] = arg;
- //cast(Node)(key)._parentNode = null;
+ this.nodes[i] = arg;
return arg;
}
}
nodes ~= arg;
return arg;
}
+
/++
+ Removes a node specified by name. When this map contains the attributes
+ attached to an element, if the removed attribute is known to have a default
+ value, an attribute immediately appears containing the default value as
+ well as the corresponding namespace URI, local name, and prefix when applicable.
+/
- dom.Node removeNamedItem(DOMString name)
+ dom.Node removeNamedItem(string name)
{
- foreach (size_t i, dom.Node key; nodes) {
- if (key.nodeName == name)
+ foreach (size_t i, dom.Node key; this.nodes)
+ {
+ if (key.nodeName == name)
{
- nodes = nodes[0..i] ~ nodes[i+1..$];
- //cast(Node)(key)._parentNode = null;
+ this.nodes = this.nodes[0 .. i] ~ this.nodes[i + 1 .. $];
return key;
}
}
@@ -2543,10 +2892,11 @@ class DOMImplementation : dom.DOMImplementation
+ Per the XML Namespaces specification, applications must use the value `null`
+ as the `namespaceURI` parameter for methods if they wish to have no namespace.
+/
- Node getNamedItemNS(DOMString namespaceURI, DOMString localName)
+ Node getNamedItemNS(string namespaceURI, string localName)
{
return null;
}
+
/++
+ Adds a node using its `namespaceURI` and `localName`. If a node with that
+ namespace URI and that local name is already present in this map, it is
@@ -2558,6 +2908,7 @@ class DOMImplementation : dom.DOMImplementation
{
return null;
}
+
/++
+ Removes a node specified by local name and namespace URI. A removed attribute
+ may be known to have a default value when this map contains the attributes attached
@@ -2567,7 +2918,7 @@ class DOMImplementation : dom.DOMImplementation
+ Per the XML Namespaces specification, applications must use the value `null`
+ as the `namespaceURI` parameter for methods if they wish to have no namespace.
+/
- Node removeNamedItemNS(DOMString namespaceURI, DOMString localName)
+ Node removeNamedItemNS(string namespaceURI, string localName)
{
return null;
}
@@ -2576,19 +2927,23 @@ class DOMImplementation : dom.DOMImplementation
/// Implementation of $(LINK2 ../dom/CDATASection, `newxml.dom.CDATASection`)
class CDATASection : Text, dom.CDATASection
{
- package this() {
-
- }
// inherited from Node
override
{
- @property dom.NodeType nodeType() { return dom.NodeType.cdataSection; }
- @property DOMString nodeName() { return new DOMString("#cdata-section"); }
+ @property dom.NodeType nodeType()
+ {
+ return dom.NodeType.cdataSection;
+ }
+
+ @property string nodeName()
+ {
+ return "#cdata-section";
+ }
CDATASection cloneNode(bool deep)
{
CDATASection cloned = new CDATASection();
- cloned._ownerDocument = _ownerDocument;
+ cloned._ownerDocument = this._ownerDocument;
super.performClone(cloned, deep);
return cloned;
}
@@ -2597,9 +2952,6 @@ class DOMImplementation : dom.DOMImplementation
/// Implementation of $(LINK2 ../dom/ProcessingInstruction, `newxml.dom.ProcessingInstruction`)
class ProcessingInstruction : Node, dom.ProcessingInstruction
{
- package this() {
-
- }
// specific to ProcessingInstruction
override
{
@@ -2607,44 +2959,71 @@ class DOMImplementation : dom.DOMImplementation
+ Implementation of $(LINK2 ../dom/ProcessingInstruction.target,
+ `newxml.dom.ProcessingInstruction.target`).
+/
- @property DOMString target() { return _target; }
+ @property string target()
+ {
+ return this._target;
+ }
/++
+ Implementation of $(LINK2 ../dom/ProcessingInstruction.data,
+ `newxml.dom.ProcessingInstruction.data`).
+/
- @property DOMString data() { return _data; }
+ @property string data()
+ {
+ return this._data;
+ }
/// ditto
- @property void data(DOMString newVal) { _data = newVal; }
+ @property void data(string newVal)
+ {
+ this._data = newVal;
+ }
}
- private DOMString _target, _data;
+ private string _target;
+ private string _data;
+
// inherited from Node
override
{
- @property dom.NodeType nodeType() { return dom.NodeType.processingInstruction; }
- @property DOMString nodeName() { return target; }
- @property DOMString nodeValue() { return _data; }
- @property void nodeValue(DOMString newVal)
+ @property dom.NodeType nodeType()
+ {
+ return dom.NodeType.processingInstruction;
+ }
+
+ @property string nodeName()
+ {
+ return target;
+ }
+
+ @property string nodeValue()
+ {
+ return _data;
+ }
+
+ @property void nodeValue(string newVal)
{
- enforce!DOMException(!(readonly)
- , dom.ExceptionCode.noModificationAllowed);
- _data = newVal;
+ enforce!DOMException(!(readonly), dom.ExceptionCode
+ .noModificationAllowed);
+ this._data = newVal;
}
- @property DOMString textContent() { return _data; }
- @property void textContent(DOMString newVal)
+ @property string textContent()
{
- enforce!DOMException(!(readonly)
- , dom.ExceptionCode.noModificationAllowed);
- _data = newVal;
+ return _data;
+ }
+
+ @property void textContent(string newVal)
+ {
+ enforce!DOMException(!(readonly), dom.ExceptionCode
+ .noModificationAllowed);
+ this._data = newVal;
}
ProcessingInstruction cloneNode(bool deep)
{
auto cloned = new ProcessingInstruction();
- cloned._ownerDocument = _ownerDocument;
+ cloned._ownerDocument = this._ownerDocument;
super.performClone(cloned, deep);
- cloned._target = _target;
- cloned._data = _data;
+ cloned._target = this._target;
+ cloned._data = this._data;
return cloned;
}
}
@@ -2653,108 +3032,129 @@ class DOMImplementation : dom.DOMImplementation
///Currently external (system) entities are not supported.
class Entity : Node, dom.Entity
{
- private DOMString _publicId;
- private DOMString _systemId;
- private DOMString content;
- package this(DOMString _publicId, DOMString content, Document _ownerDocument)
+ private string _publicId;
+ private string _systemId;
+ private string content;
+
+ package this(string publicId, string content, Document ownerDocument)
{
- this._publicId = _publicId;
+ this._publicId = publicId;
this.content = content;
- this._ownerDocument = _ownerDocument;
+ this._ownerDocument = ownerDocument;
}
- package this(DOMString _publicId, DOMString _systemId, DOMString content, Document _ownerDocument)
+
+ package this(string publicId, string systemId, string content, Document ownerDocument)
{
- this._publicId = _publicId;
- this._systemId = _systemId;
+ this._publicId = publicId;
+ this._systemId = systemId;
this.content = content;
- this._ownerDocument = _ownerDocument;
+ this._ownerDocument = ownerDocument;
}
+
/// The text substituted by this entity.
- override @property DOMString nodeValue()
+ override @property string nodeValue()
{
return content;
}
+
/// The text substituted by this entity.
- override @property DOMString textContent()
+ override @property string textContent()
{
return content;
}
- override @property DOMString nodeName()
+
+ override @property string nodeName()
{
return _publicId;
}
+
override @property dom.NodeType nodeType()
{
return dom.NodeType.entity;
}
+
/// The public identifier associated with the entity if specified, and `null` otherwise.
- @property DOMString publicId()
+ @property string publicId()
{
- return _publicId;
+ return this._publicId;
}
+
/++
+ The system identifier associated with the entity if specified, and `null` otherwise.
+ This may be an absolute URI or not.
+/
- @property DOMString systemId()
+ @property string systemId()
{
- return _systemId;
+ return this._systemId;
}
+
/// For unparsed entities, the name of the `Notation` for the entity. For parsed entities, this is `null`.
- @property DOMString notationName()
+ @property string notationName()
{
return null;
}
+
/++
+ An attribute specifying the encoding used for this entity at the time of
+ parsing, when it is an external parsed entity. This is `null` if it an
+ entity from the internal subset or if it is not known.
+/
- @property DOMString inputEncoding()
+ @property string inputEncoding()
{
return null;
}
+
/++
+ An attribute specifying, as part of the text declaration, the encoding of
+ this entity, when it is an external parsed entity. This is `null` otherwise.
+/
- @property DOMString xmlEncoding()
+ @property string xmlEncoding()
{
return null;
}
+
/++
+ An attribute specifying, as part of the text declaration, the version
+ number of this entity, when it is an external parsed entity. This is
+ `null` otherwise.
+/
- @property DOMString xmlVersion()
+ @property string xmlVersion()
{
return null;
}
}
+
/// Implementation of $(LINK2 ../dom/EntityReference, `newxml.dom.EntityReference`)
class EntityReference : NodeWithChildren, dom.EntityReference
{
- package this() {
-
- }
// inherited from Node
override
{
- @property dom.NodeType nodeType() { return dom.NodeType.entityReference; }
- @property DOMString nodeName() { return _ent_name; }
- @property bool readonly() { return true; }
+ @property dom.NodeType nodeType()
+ {
+ return dom.NodeType.entityReference;
+ }
+
+ @property string nodeName()
+ {
+ return this._ent_name;
+ }
+
+ @property bool readonly()
+ {
+ return true;
+ }
}
- private DOMString _ent_name;
+
+ private string _ent_name;
}
+
/// Implementation of $(LINK2 ../dom/DOMConfiguration, `newxml.dom.DOMConfiguration`)
class DOMConfiguration : dom.DOMConfiguration
{
import std.meta;
import std.traits;
- package this() {
- }
private
{
enum string always = "((x) => true)";
@@ -2775,18 +3175,23 @@ class DOMImplementation : dom.DOMImplementation
@Config("namespace-declarations", "bool", always) bool namespace_declarations;
@Config("split-cdata-sections", "bool", always) bool split_cdata_sections;
}
+
Params params;
void assign(string field, string type)(dom.UserData val) @trusted
{
- mixin("if (val.convertsTo!(" ~ type ~ ")) params." ~ field ~ " = val.get!(" ~ type ~ "); \n");
+ mixin("if (val.convertsTo!(" ~ type ~ ")) params." ~ field
+ ~ " = val.get!(" ~ type ~ "); \n");
}
+
bool canSet(string type, string settable)(dom.UserData val) @trusted
{
- mixin("if (val.convertsTo!(" ~ type ~ ")) return " ~ settable ~ "(val.get!(" ~ type ~ ")); \n");
+ mixin("if (val.convertsTo!(" ~ type ~ ")) return " ~ settable
+ ~ "(val.get!(" ~ type ~ ")); \n");
return false;
}
}
+
// specific to DOMConfiguration
override
{
@@ -2801,12 +3206,14 @@ class DOMImplementation : dom.DOMImplementation
foreach (field; AliasSeq!(__traits(allMembers, Params)))
{
mixin("enum type = getUDAs!(Params." ~ field ~ ", Config)[0].type; \n");
- mixin("case getUDAs!(Params." ~ field ~ ", Config)[0].name: assign!(field, type)(value); \n");
+ mixin("case getUDAs!(Params." ~ field
+ ~ ", Config)[0].name: assign!(field, type)(value); \n");
}
- default:
- throw new DOMException(dom.ExceptionCode.notFound);
+ default:
+ throw new DOMException(dom.ExceptionCode.notFound);
}
}
+
/++
+ Implementation of $(LINK2 ../dom/DOMConfiguration.getParameter,
+ `newxml.dom.DOMConfiguration.getParameter`).
@@ -2817,13 +3224,15 @@ class DOMImplementation : dom.DOMImplementation
{
foreach (field; AliasSeq!(__traits(allMembers, Params)))
{
- mixin("case getUDAs!(Params." ~ field ~ ", Config)[0].name: \n" ~
- "return dom.UserData(params." ~ field ~ "); \n");
+ mixin("case getUDAs!(Params." ~ field
+ ~ ", Config)[0].name: \n"
+ ~ "return dom.UserData(params." ~ field ~ "); \n");
}
- default:
- throw new DOMException(dom.ExceptionCode.notFound);
+ default:
+ throw new DOMException(dom.ExceptionCode.notFound);
}
}
+
/++
+ Implementation of $(LINK2 ../dom/DOMConfiguration.canSetParameter,
+ `newxml.dom.DOMConfiguration.canSetParameter`).
@@ -2835,56 +3244,65 @@ class DOMImplementation : dom.DOMImplementation
foreach (field; AliasSeq!(__traits(allMembers, Params)))
{
mixin("enum type = getUDAs!(Params." ~ field ~ ", Config)[0].type; \n");
- mixin("enum settable = getUDAs!(Params." ~ field ~ ", Config)[0].settable; \n");
- mixin("case getUDAs!(Params." ~ field ~ ", Config)[0].name: \n" ~
- "return canSet!(type, settable)(value); \n");
+ mixin("enum settable = getUDAs!(Params." ~ field
+ ~ ", Config)[0].settable; \n");
+ mixin("case getUDAs!(Params." ~ field
+ ~ ", Config)[0].name: \n"
+ ~ "return canSet!(type, settable)(value); \n");
}
- default:
- return false;
+ default:
+ return false;
}
}
+
/++
+ Implementation of $(LINK2 ../dom/DOMConfiguration.parameterNames,
+ `newxml.dom.DOMConfiguration.parameterNames`).
+/
- @property dom.DOMStringList parameterNames()
+ @property dom.stringList parameterNames()
{
return new StringList();
}
}
- class StringList : dom.DOMStringList
+ class StringList : dom.stringList
{
- package this() {
-
- }
private template MapToConfigName(Members...)
{
static if (Members.length > 0)
{
- mixin("alias MapToConfigName = AliasSeq!(getUDAs!(Params." ~ Members[0] ~
- ", Config)[0].name, MapToConfigName!(Members[1..$])); \n");
+ mixin("alias MapToConfigName = AliasSeq!(getUDAs!(Params." ~ Members[0] ~ ", Config)[0].name, MapToConfigName!(Members[1..$])); \n");
}
else
{
alias MapToConfigName = AliasSeq!();
}
}
- static immutable string[] arr = [MapToConfigName!(__traits(allMembers, Params))];
- // specific to DOMStringList
+ static immutable string[] arr = [
+ MapToConfigName!(__traits(allMembers, Params))
+ ];
+
+ // specific to stringList
override
{
- DOMString item(size_t index) { return new DOMString(arr[index]); }
- size_t length() { return arr.length; }
+ string item(size_t index)
+ {
+ return arr[index];
+ }
- bool contains(DOMString str)
+ size_t length()
+ {
+ return arr.length;
+ }
+
+ bool contains(string str)
{
- import std.algorithm: canFind;
+ import std.algorithm : canFind;
+
return arr.canFind(str);
}
}
- //alias arr this;
}
}
}
@@ -2895,9 +3313,9 @@ class DOMImplementation : dom.DOMImplementation
+/
auto domBuilder(CursorType)(auto ref CursorType cursor)
{
- //import std.experimental.allocator.gc_allocator;//import stdx.allocator.gc_allocator;
import dompar = newxml.domparser;
- return dompar.domBuilder(cursor, new DOMImplementation());//return dompar.domBuilder(cursor, new DOMImplementation!(CursorType.StringType, shared(GCAllocator))());
+
+ return dompar.domBuilder(cursor, new DOMImplementation());
}
unittest
@@ -2905,64 +3323,65 @@ unittest
DOMImplementation impl = new DOMImplementation();
- auto doc = impl.createDocument(new DOMString("myNamespaceURI"), new DOMString("myPrefix:myRootElement"), null);
+ auto doc = impl.createDocument("myNamespaceURI", "myPrefix:myRootElement", null);
auto root = doc.documentElement;
assert(root.prefix == "myPrefix");
- auto attr = doc.createAttributeNS(new DOMString("myAttrNamespace"), new DOMString("myAttrPrefix:myAttrName"));
- attr.value = new DOMString("something");
+ auto attr = doc.createAttributeNS("myAttrNamespace", "myAttrPrefix:myAttrName");
+ attr.value = "something";
root.setAttributeNode(attr);
assert(attr.value);
assert(attr.value == "something");
assert(root.attributes.length == 1);
- assert(root.getAttributeNodeNS(new DOMString("myAttrNamespace"), new DOMString("myAttrName")) is attr);
+ assert(root.getAttributeNodeNS("myAttrNamespace", "myAttrName") is attr);
- attr.nodeValue = new DOMString("myAttrValue");
+ attr.nodeValue = "myAttrValue";
assert(attr.childNodes.length == 1);
assert(attr.firstChild.nodeType == dom.NodeType.text);
assert(attr.firstChild.nodeValue == attr.nodeValue);
- auto elem = doc.createElementNS(new DOMString("myOtherNamespace"), new DOMString("myOtherPrefix:myOtherElement"));
+ auto elem = doc.createElementNS("myOtherNamespace", "myOtherPrefix:myOtherElement");
assert(root.ownerDocument is doc);
assert(elem.ownerDocument is doc);
root.appendChild(elem);
assert(root.firstChild is elem);
assert(root.firstChild.namespaceURI == "myOtherNamespace");
- /* elem.setAttributeNS(new DOMString("xxx"), new DOMString("yyy"), new DOMString("zzz"));
- assert(elem.getAttributeNS(new DOMString("xxx"), new DOMString("yyy")));
- assert(elem.getAttributeNS(new DOMString("xxx"), new DOMString("yyy")) == "zzz"); */
+ /* elem.setAttributeNS("xxx", "yyy", "zzz");
+ assert(elem.getAttributeNS("xxx", "yyy"));
+ assert(elem.getAttributeNS("xxx", "yyy") == "zzz"); */
- auto comm = doc.createComment(new DOMString("myWonderfulComment"));
+ auto comm = doc.createComment("myWonderfulComment");
doc.insertBefore(comm, root);
assert(doc.childNodes.length == 2);
assert(doc.firstChild is comm);
assert(comm.substringData(1, 4) == "yWon");
- comm.replaceData(0, 2, new DOMString("your"));
+ comm.replaceData(0, 2, "your");
comm.deleteData(4, 9);
- comm.insertData(4, new DOMString("Questionable"));
+ comm.insertData(4, "Questionable");
assert(comm.data == "yourQuestionableComment");
- auto pi = doc.createProcessingInstruction(new DOMString("myPITarget"), new DOMString("myPIData"));
+ auto pi = doc.createProcessingInstruction("myPITarget", "myPIData");
elem.appendChild(pi);
assert(elem.lastChild is pi);
- auto cdata = doc.createCDATASection(new DOMString("mycdataContent"));
+ auto cdata = doc.createCDATASection("mycdataContent");
elem.replaceChild(cdata, pi);
assert(elem.lastChild is cdata);
elem.removeChild(cdata);
assert(elem.childNodes.length == 0);
- assert(doc.getElementsByTagNameNS(new DOMString("myOtherNamespace"), new DOMString("myOtherElement")).item(0) is elem);
+ assert(doc.getElementsByTagNameNS("myOtherNamespace", "myOtherElement").item(
+ 0) is elem);
doc.setUserData("userDataKey1", dom.UserData(3.14), null);
doc.setUserData("userDataKey2", dom.UserData(new Object()), null);
doc.setUserData("userDataKey3", dom.UserData(null), null);
assert(doc.getUserData("userDataKey1") == 3.14);
assert(doc.getUserData("userDataKey2").type == typeid(Object));
- assert(doc.getUserData("userDataKey3").peek!long is null);
+ assert(doc.getUserData("userDataKey3").peek!long is null);
- assert(elem.lookupNamespaceURI(new DOMString("myOtherPrefix")) == "myOtherNamespace");
- assert(doc.lookupPrefix(new DOMString("myNamespaceURI")) == "myPrefix");
+ assert(elem.lookupNamespaceURI("myOtherPrefix") == "myOtherNamespace");
+ assert(doc.lookupPrefix("myNamespaceURI") == "myPrefix");
assert(elem.isEqualNode(elem.cloneNode(false)));
assert(root.isEqualNode(root.cloneNode(true)));
@@ -2970,7 +3389,7 @@ unittest
assert(pi.isEqualNode(pi.cloneNode(false)));
}
-unittest
+@safe unittest
{
import newxml.lexers;
import newxml.parser;
@@ -2995,25 +3414,20 @@ unittest
}";
- auto builder =
- xml
- .lexer
- .parser
- .cursor
- .domBuilder;
+ auto builder = xml.lexer.parser.cursor.domBuilder;
builder.setSource(xml);
builder.buildRecursive;
auto doc = builder.getDocument;
- auto books = doc.getElementsByTagName(new DOMString("book"));
- auto authors = doc.getElementsByTagName(new DOMString("author"));
- auto titles = doc.getElementsByTagName(new DOMString("title"));
+ auto books = doc.getElementsByTagName("book");
+ auto authors = doc.getElementsByTagName("author");
+ auto titles = doc.getElementsByTagName("title");
assert(doc.xmlVersion == "1.0");
assert(doc.xmlStandalone);
- enum Pos(dom.DocumentPosition pos) = cast(BitFlags!(dom.DocumentPosition))pos;
+ enum Pos(dom.DocumentPosition pos) = cast(BitFlags!(dom.DocumentPosition)) pos;
with (dom.DocumentPosition)
{
assert(books[1].compareDocumentPosition(authors[2]) == Pos!following);
@@ -3021,28 +3435,29 @@ unittest
assert(books[1].compareDocumentPosition(titles[1]) == (Pos!containedBy | Pos!following));
assert(authors[0].compareDocumentPosition(books[0]) == (Pos!contains | Pos!preceding));
assert(titles[2].compareDocumentPosition(titles[2]) == Pos!none);
- assert(books[2].attributes[0].compareDocumentPosition(books[2].attributes[1])
- == (Pos!implementationSpecific | Pos!following));
- assert(books[2].attributes[1].compareDocumentPosition(books[2].attributes[0])
- == (Pos!implementationSpecific | Pos!preceding));
+ assert(books[2].attributes[0].compareDocumentPosition(
+ books[2].attributes[1]) == (
+ Pos!implementationSpecific | Pos!following));
+ assert(books[2].attributes[1].compareDocumentPosition(
+ books[2].attributes[0]) == (
+ Pos!implementationSpecific | Pos!preceding));
}
assert(books[1].cloneNode(true).childNodes[1].isEqualNode(authors[1]));
books[2].setIdAttributeNode(books[2].attributes[1], true);
assert(books[2].attributes[1].isId);
- assert(doc.getElementById(new DOMString("978-0201704310")) is books[2]);
+ assert(doc.getElementById("978-0201704310") is books[2]);
alias Text = typeof(doc.implementation).Text;
- titles[1].appendChild(doc.createTextNode(new DOMString(" for Dummies")));
+ titles[1].appendChild(doc.createTextNode(" for Dummies"));
/+
TODO this test starts segfaulting with the next line
- TODO creating a DOMString to call these functions seems wrong
+ TODO creating a string to call these functions seems wrong
assert((cast(Text)(titles[1].firstChild)).wholeText == "Programming in D for Dummies");
(cast(Text)(titles[1].lastChild)).replaceWholeText(titles[1].firstChild.textContent);
assert(titles[1].textContent == "Programming in D");
assert(titles[1].childNodes.length == 1);
+/
}
-
diff --git a/source/newxml/domparser.d b/source/newxml/domparser.d
index 041cf8b..d9e37da 100644
--- a/source/newxml/domparser.d
+++ b/source/newxml/domparser.d
@@ -25,7 +25,6 @@ import newxml.cursor;
import dom = newxml.dom;
import newxml.domimpl;
-import newxml.domstring;
/++
+ Built on top of Cursor, the DOM builder adds to it the ability to
@@ -36,8 +35,7 @@ import newxml.domstring;
+ This type should not be instantiated directly. Instead, the helper function
+ `domBuilder` should be used.
+/
-struct DOMBuilder(T)
- if (isCursor!T)
+struct DOMBuilder(T) if (isCursor!T)
{
import std.traits : ReturnType;
@@ -75,22 +73,23 @@ struct DOMBuilder(T)
{
switch (attr.name)
{
- case "version":
- document.xmlVersion = new DOMString(attr.value);
- switch (attr.value) {
- case "1.1":
- cursor.xmlVersion = XMLVersion.XML1_1;
- break;
- default:
- cursor.xmlVersion = XMLVersion.XML1_0;
- break;
- }
- break;
- case "standalone":
- document.xmlStandalone = attr.value == "yes";
+ case "version":
+ document.xmlVersion = attr.value;
+ switch (attr.value)
+ {
+ case "1.1":
+ cursor.xmlVersion = XMLVersion.XML1_1;
break;
default:
+ cursor.xmlVersion = XMLVersion.XML1_0;
break;
+ }
+ break;
+ case "standalone":
+ document.xmlStandalone = attr.value == "yes";
+ break;
+ default:
+ break;
}
}
}
@@ -180,7 +179,9 @@ struct DOMBuilder(T)
auto cur = createCurrent;
if (cur)
+ {
currentNode.appendChild(createCurrent);
+ }
already_built = true;
}
@@ -207,65 +208,68 @@ struct DOMBuilder(T)
return next();
}
- private NodeType createCurrent()
- // TODO: handling of system (external) entities
+ private NodeType createCurrent() // TODO: handling of system (external) entities
{
switch (cursor.kind)
{
// XMLKind.elementEnd is needed for empty tags:
- case XMLKind.elementEnd:
- case XMLKind.elementStart:
- case XMLKind.elementEmpty:
- /* DOMImplementation.Element elem = cursor.prefix.length ?
- document.createElementNS(new DOMString(cursor.prefix), new DOMString(cursor.localName)) :
- document.createElement(new DOMString(cursor.name)); */
- DOMImplementation.Element elem = document.createElement(new DOMString(cursor.name));
- foreach (attr; cursor.attributes)
- {
- /*if (attr.prefix.length)
+ case XMLKind.elementEnd:
+ case XMLKind.elementStart:
+ case XMLKind.elementEmpty:
+ /* DOMImplementation.Element elem = cursor.prefix.length ?
+ document.createElementNS(cursor.prefix, cursor.localName) :
+ document.createElement(cursor.name); */
+ DOMImplementation.Element elem = document.createElement(cursor.name);
+ foreach (attr; cursor.attributes)
+ {
+ /*if (attr.prefix.length)
{
- elem.setAttributeNS(new DOMString(attr.prefix), new DOMString(attr.localName),
- new DOMString(attr.value));
+ elem.setAttributeNS(attr.prefix, attr.localName,
+ attr.value);
}
else
{*/
- elem.setAttribute(new DOMString(attr.name), new DOMString(attr.value));
- //}
- }
- return elem;
- case XMLKind.text:
- return document.createTextNode(new DOMString(cursor.content));
- case XMLKind.cdata:
- return document.createCDATASection(new DOMString(cursor.content));
- case XMLKind.processingInstruction:
- return document.createProcessingInstruction(new DOMString(cursor.name), new DOMString(cursor.content));
- case XMLKind.comment:
- return document.createComment(new DOMString(cursor.content));
- case XMLKind.dtdStart, XMLKind.dtdEmpty:
- docType = domImpl.createDocumentType(new DOMString(cursor.name), new DOMString(), new DOMString());
- document.doctype = docType;
- return null;
- case XMLKind.entityDecl:
- docType.createEntity(new DOMString(cursor.name), new DOMString(cursor.content));
- cursor.chrEntities[cursor.name] = cursor.content;
- return null;
- default:
- return null;
+ elem.setAttribute(attr.name, attr.value);
+ //}
+ }
+ return elem;
+ case XMLKind.text:
+ return document.createTextNode(cursor.content);
+ case XMLKind.cdata:
+ return document.createCDATASection(cursor.content);
+ case XMLKind.processingInstruction:
+ return document.createProcessingInstruction(cursor.name,
+ cursor.content);
+ case XMLKind.comment:
+ return document.createComment(cursor.content);
+ case XMLKind.dtdStart, XMLKind.dtdEmpty:
+ docType = domImpl.createDocumentType(cursor.name, "", "");
+ document.doctype = docType;
+ return null;
+ case XMLKind.entityDecl:
+ docType.createEntity(cursor.name, cursor.content);
+ cursor.chrEntities[cursor.name] = cursor.content;
+ return null;
+ default:
+ return null;
}
}
/++
+ Returns the Document being built by this builder.
+/
- auto getDocument() { return document; }
+ auto getDocument()
+ {
+ return document;
+ }
}
/++
+ Instantiates a suitable `DOMBuilder` on top of the given `cursor` and `DOMImplementation`.
+/
auto domBuilder(CursorType)(auto ref CursorType cursor, DOMImplementation domimpl)
- if (isCursor!CursorType)
+ if (isCursor!CursorType)
{
auto res = DOMBuilder!(CursorType)(domimpl);
res.cursor = cursor;
@@ -282,7 +286,6 @@ unittest
import newxml.parser;
import newxml.cursor;
import domimpl = newxml.domimpl;
-
alias DOMImpl = domimpl.DOMImplementation;
@@ -299,30 +302,25 @@ unittest
};
- auto builder =
- xml
- .lexer
- .parser
- .cursor
- .domBuilder(new DOMImpl());
+ auto builder = xml.lexer.parser.cursor.domBuilder(new DOMImpl());
builder.setSource(xml);
builder.buildRecursive;
dom.Document doc = builder.getDocument;
- assert(doc.getElementsByTagName(new DOMString("ccc")).length == 1);
- assert(doc.documentElement.getAttribute(new DOMString("myattr")));
- assert(doc.documentElement.getAttribute(new DOMString("myattr")) == "something");
- assert(doc.documentElement.getAttribute(new DOMString("xmlns:myns")));
- assert(doc.documentElement.getAttribute(new DOMString("xmlns:myns")) == "something");
- dom.Element e1 = cast(dom.Element)doc.firstChild;
+ assert(doc.getElementsByTagName("ccc").length == 1);
+ assert(doc.documentElement.getAttribute("myattr"));
+ assert(doc.documentElement.getAttribute("myattr") == "something");
+ assert(doc.documentElement.getAttribute("xmlns:myns"));
+ assert(doc.documentElement.getAttribute("xmlns:myns") == "something");
+ dom.Element e1 = cast(dom.Element) doc.firstChild;
assert(e1.nodeName == "aaa");
- dom.Element e2 = cast(dom.Element)e1.firstChild();
+ dom.Element e2 = cast(dom.Element) e1.firstChild();
assert(e2.nodeName == "myns:bbb");
- dom.Comment c1 = cast(dom.Comment)e2.firstChild;
+ dom.Comment c1 = cast(dom.Comment) e2.firstChild;
assert(c1.data == " lol ");
- dom.Text t1 = cast(dom.Text)e2.lastChild;
- //Issue: Extra whitespace isn't dropped between and after words when dropWhiteSpace is enabled in
+ dom.Text t1 = cast(dom.Text) e2.lastChild;
+ //Issue: Extra whitespace isn't dropped between and after words when dropWhiteSpace is enabled in
//assert(t1.data == "Lots of Text! On multiple lines!", t1.data.transcodeToUTF8);
}
@@ -337,13 +335,7 @@ unittest
alias DOMImplType = domimpl.DOMImplementation;
auto xml = ``;
- auto builder =
- xml
- .lexer
- .parser
- .cursor
- .copyingCursor
- .domBuilder(new DOMImplType());
+ auto builder = xml.lexer.parser.cursor.copyingCursor.domBuilder(new DOMImplType());
builder.setSource(xml);
builder.buildRecursive;
diff --git a/source/newxml/domstring.d b/source/newxml/domstring.d
deleted file mode 100644
index fd5b26d..0000000
--- a/source/newxml/domstring.d
+++ /dev/null
@@ -1,471 +0,0 @@
-module newxml.domstring;
-
-import std.algorithm.comparison : equal;
-import std.exception : enforce;
-import std.range;
-import std.string;
-import std.utf;
-
-import newxml.faststrings;
-import newxml.interfaces;
-
-version (newxml_force_utf8) {
- alias XMLCh = immutable(char);
-} else version (newxml_force_utf32) {
- alias XMLCh = immutable(dchar);
-} else {
- alias XMLCh = immutable(wchar);
-}
-/**
- * Proper DOMString implementation, with some added range capabilities.
- * Authors:
- * László Szerémi
- * Contains UTF-16 strings by default, but can be configured to either UTF-8 or UTF-32 with version labels.
- */
-public class DOMString : RandomAccessFinite!XMLCh {
- ///Stores the character data.
- private XMLCh[] buffer;
- ///Front and rear positions.
- private size_t frontPos, backPos;
- /**`foreach` iteration uses opApply, since one delegate call per loop
- * iteration is faster than three virtual function calls.
- * TO DO: Use metaprogramming to make it able to be used in all sorts of context.
- */
- int opApply(scope int delegate(XMLCh) deleg) {
- for (size_t i ; i < buffer.length ; i++) {
- int result = deleg(buffer[i]);
- if (result)
- {
- return result;
- }
- }
- return 0;
- }
-
- /// Ditto
- int opApply(scope int delegate(size_t, XMLCh) deleg) {
- for (size_t i ; i < buffer.length ; i++) {
- int result = deleg(i, buffer[i]);
- if (result)
- {
- return result;
- }
- }
- return 0;
- }
-@safe:
- /**
- * Default constructor for DOMString. The resulting DOMString object refers to no string at all
- * Difference from C++ implementation: Does not compare with 0
- */
- this() @nogc nothrow pure {
-
- }
- ///Copy constructor.
- this(const(DOMString) other) nothrow pure {
- buffer = other.buffer.dup;
- backPos = buffer.length;
- }
- ///Constructor to build a DOMString from an XML character array. (XMLCh is a UTF-16 character by default, can be configured with version labels)
- this(XMLCh* other) @nogc @trusted nothrow pure {
- buffer = fromStringz(other);
- backPos = buffer.length;
- }
- /**
- * Constructor to build a DOMString from a character array of given length.
- * Params:
- * other = The character array to be imported into the DOMString
- * length = The length of the character array to be imported
- */
- this(XMLCh* other, size_t length) @nogc @system nothrow pure {
- buffer = other[0..length];
- backPos = buffer.length;
- }
- version (newxml_force_utf8) {
-
- } else {
- /**
- * Constructor to build a DOMString from an 8 bit character array.
- * Params:
- * other = The character array to be imported into the DOMString
- */
- this(const(char)* other) @trusted nothrow pure {
- version (newxml_force_utf32) {
- buffer = toUTF32(fromStringz(other));
- } else {
- buffer = toUTF16(fromStringz(other));
- }
- backPos = buffer.length;
- }
- }
- ///Creates DOMString objects from standard D strings.
- this(T)(T[] other) nothrow pure {
- version (newxml_force_utf8) {
- buffer = toUTF8(other);
- } else version (newxml_force_utf32) {
- buffer = toUTF32(other);
- } else {
- buffer = toUTF16(other);
- }
- backPos = buffer.length;
- }
- /**
- * Append a null-terminated XMLCh * (Unicode) string to this string.
- * Params:
- * other = The object to be appended
- */
- void appendData(XMLCh* other) @trusted nothrow pure {
- buffer ~= fromStringz(other);
- backPos = buffer.length;
- }
- /**
- * Append a single Unicode character to this string.
- * Params:
- * ch = The single character to be appended
- */
- void appendData(XMLCh ch) nothrow pure {
- buffer ~= ch;
- backPos = buffer.length;
- }
- /**
- * Appends the content of another DOMString to this string.
- * Params:
- * other = The object to be appended
- */
- void appendData(DOMString other) nothrow pure {
- buffer ~= other.buffer;
- backPos = buffer.length;
- }
- /**
- * Appends a D string to this string.
- * Params:
- * other = The D string (string/wstring/dstring) as an array
- */
- void appendData(T)(T[] other) nothrow pure {
- version (newxml_force_utf8) {
- buffer ~= toUTF8(other);
- } else version (newxml_force_utf32) {
- buffer ~= toUTF32(other);
- } else {
- buffer ~= toUTF16(other);
- }
- backPos = buffer.length;
- }
- /**
- * Returns the character at the specified position.
- * Params:
- * index = The position at which the character is being requested
- * Returns: Returns the character at the specified position.
- */
- XMLCh charAt(size_t index) @nogc nothrow pure {
- return buffer[index];
- }
- /**
- * Makes a clone of a the DOMString.
- * Returns: The object to be cloned.
- */
- DOMString clone() nothrow pure const {
- return new DOMString(this);
- }
- //TO DO:read up on how this works
- int compareString(DOMString other) {
- return int.init;
- }
- /**
- * Clears the data of this DOMString.
- * Params:
- * offset = The position from the beginning from which the data must be deleted
- * count = The count of characters from the offset that must be deleted
- */
- void deleteData(size_t offset, size_t count) pure {
- enforce!XMLException(offset + count <= buffer.length
- , "offset + count larger than buffer length!");
- buffer = buffer[0..offset] ~ buffer[offset+count..$];
- backPos = buffer.length;
- }
- /**
- * Compare a DOMString with a null-terminated raw 16-bit character string.
- * Params:
- * other = The character string to be compared with.
- * Returns: True if the strings are the same, false otherwise.
- */
- bool equals(XMLCh* other) @trusted pure const {
- auto str = fromStringz(other);
- return equal(buffer, str);
- }
- /**
- * Tells if a DOMString contains the same character data as another.
- * Params:
- * other = The DOMString to be compared with.
- * Returns: True if the two DOMStrings are same, false otherwise.
- */
- bool equals(DOMString other) pure const {
- if (!other) return false;
- return equal(buffer, other.buffer);
- }
- /**
- * Compares the content of a D string against a DOMString.
- * Params:
- * other = The D string to be compared with.
- * Returns: True if their textual data are the same, false otherwise.
- */
- bool equals(T)(T other) pure const {
- XMLCh[] o;
- version (newxml_force_utf8)
- {
- o = toUTF8(other);
- }
- else version (newxml_force_utf32)
- {
- o = toUTF32(other);
- }
- else
- {
- o = toUTF16(other);
- }
-
- return equal(buffer, o);
- }
- /**
- * Inserts a string within the existing DOMString at an arbitrary position.
- * Params:
- * offset = The offset from the beginning at which the insertion needs to be done in this object
- * data = The DOMString containing the data that needs to be inserted
- */
- void insertData(size_t offset, DOMString data) pure nothrow {
- buffer = buffer[0..offset] ~ data.buffer ~ buffer[offset..$];
- }
- /**
- * Inserts a string of type XMLCh within the existing DOMString at an arbitrary position
- * Params:
- * offset = The offset from the beginning at which the insertion needs to be done in this object
- * other = The DOMString containing the data that needs to be inserted
- */
- void insertData(size_t offset, XMLCh[] other) pure nothrow {
- buffer = buffer[0..offset] ~ other ~ buffer[offset..$];
- }
- /**
- * Compares the string against various other types or itself using the `==` and `!=` operators.
- * Params:
- * other = The instance of the type to be tested against.
- * Returns: True if they have the same textual data, false otherwise.
- */
- bool opEquals(R)(R other) pure const {
- return equals(other);
- }
- T opCast(T)() const {
- static if (is(T == string)) {
- return transcodeToUTF8;
- } else static if (is(T == wstring)) {
- return transcodeToUTF16;
- } else static if (is(T == dstring)) {
- return transcodeToUTF32;
- }
- }
- /**
- * Implements easy array appending with operator overloading.
- * Params:
- * rhs = The data to be appended to the string.
- */
- auto opOpAssign(string op, R)(R rhs) {
- static if(op == "+" || op == "~"){
- appendData(rhs);
- }
- }
- ///Dumps the DOMString on the console.
- void print() const {
- import std.stdio;
- write(buffer);
- }
- ///Dumps the DOMString on the console with a line feed at the end.
- void println() const {
- import std.stdio;
- writeln(buffer);
- }
- ///Returns a handle to the raw buffer in the DOMString.
- XMLCh* rawBuffer() @system @nogc nothrow pure const {
- return buffer.ptr;
- }
- alias ptr = rawBuffer;
- ///Returns the underlying array (string).
- XMLCh[] getDString() @nogc nothrow pure const {
- return buffer;
- }
- /**
- * Preallocate storage in the string to hold a given number of characters. A DOMString will grow its buffer on
- * demand, as characters are added, but it can be more efficient to allocate once in advance, if the size is known.
- * Params:
- * size = The number of characters to reserve.
- */
- void reserve(size_t size) nothrow pure {
- buffer.reserve(size);
- }
- /**
- * Returns a sub-string of the DOMString starting at a specified position.
- * Params:
- * offset = The offset from the beginning from which the sub-string is being requested.
- * count = The count of characters in the requested sub-string
- * Returns: The sub-string of the DOMString being requested
- */
- DOMString substringData(size_t offset, size_t count) nothrow pure const {
- return new DOMString(buffer[offset..offset + count]);
- }
- /**
- * Returns a copy of the string, transcoded to the local code page. The caller owns the (char *) string that is
- * returned, and is responsible for deleting it.
- * Returns: A pointer to a newly allocated buffer of char elements, which represents the original string, but in
- * the local encoding.
- * Note: This function is using the `toStringz` function, and rules of that apply here too.
- */
- immutable(char)* transcode() @trusted pure nothrow const {
- return toStringz(toUTF8(buffer));
- }
- /**
- * Transcodes the string as a UTF-8 string
- * Returns: The content of this string as UTF-8 data.
- */
- string transcodeToUTF8() pure nothrow const {
- return toUTF8(buffer);
- }
- /**
- * Transcodes the string as a UTF-16 string
- * Returns: The content of this string as UTF-16 data.
- */
- wstring transcodeToUTF16() pure nothrow const {
- return toUTF16(buffer);
- }
- /**
- * Transcodes the string as a UTF-32 string
- * Returns: The content of this string as UTF-32 data.
- */
- dstring transcodeToUTF32() pure nothrow const {
- return toUTF32(buffer);
- }
- ///Templated transcoder.
- T transcodeTo(T)() pure nothrow const {
- static if (is(T == string))
- {
- return transcodeToUTF8;
- }
- else static if (is(T == wstring))
- {
- return transcodeToUTF16;
- }
- else static if (is(T == dstring))
- {
- return transcodeToUTF32;
- }
- else
- {
- static assert(false, "Template parameter `" ~ T.stringof ~ "` not "
- ~ "supported for function `DOMString.transcodeTo(T)()`");
- }
- }
- //range stuff begins here
- ///Returns the front element of the range.
- @property XMLCh front() @nogc nothrow pure {
- return buffer[frontPos];
-
- }
- /**Calls $(REF moveFront, std, range, primitives) on the wrapped range, if
- * possible. Otherwise, throws an $(LREF UnsupportedRangeMethod) exception.
- */
- XMLCh moveFront() {
- if (frontPos + 1 < backPos)
- {
- frontPos++;
- }
-
- return buffer[frontPos];
- }
-
- ///Moves the front pointer up by one.
- void popFront() {
- if (frontPos + 1 < backPos)
- {
- frontPos++;
- }
- }
-
- ///Returns true if all content of the string have been consumed.
- @property bool empty() {
- return !(frontPos + 1 < backPos);
- }
- ///Returns the back element of the range.
- @property XMLCh back() {
- return buffer[backPos - 1];
- }
-
- /**Calls $(REF moveBack, std, range, primitives) on the wrapped range, if
- * possible. Otherwise, throws an $(LREF UnsupportedRangeMethod) exception
- */
- XMLCh moveBack() {
- if (backPos > 1)
- {
- backPos--;
- }
- return buffer[backPos];
- }
- ///Moves the back pointer down by one.
- void popBack() {
- if (backPos > 1)
- {
- backPos--;
- }
- }
- ///Returns a copy of the DOMString.
- @property RandomAccessFinite!XMLCh save() {
- return new DOMString(this);
- }
- ///Allows the characters to be accessed in an array-like fashion.
- XMLCh opIndex(size_t index) @nogc nothrow pure const {
- return buffer[index];
- }
- /**
- * Returns a slice of the string.
- * Params:
- * from = The beginning point.
- * to = The ending point + 1.
- * Returns: The content of the slice as a DOMString.
- */
- DOMString opSlice(size_t from, size_t to) nothrow pure const {
- return new DOMString(buffer[from..to]);
- }
- ///Moves the front pointer to the given position.
- XMLCh moveAt(size_t pos) @nogc nothrow pure {
- frontPos = pos;
- return buffer[frontPos];
- }
- ///Returns the length of the string.
- @property size_t length() @nogc nothrow pure const {
- return buffer.length;
- }
-
- ///
- alias opDollar = length;
-}
-unittest {
- DOMString test0 = new DOMString("Hello World!"), test1 = new DOMString("Hello World!"w),
- test2 = new DOMString("Hello World!"d);
- assert(test0 == "Hello World!"w);
- assert(test1 == "Hello World!"w);
- assert(test2 == "Hello World!"w);
- assert(test1 == test2);
- assert(test0.length == 12);
- assert(test1.length == 12);
- assert(test2.length == 12);
- assert(test0[3..5].getDString == "lo");
-
- DOMString test3 = new DOMString("test");
- assert(test0 != test3);
- test3.insertData(2, "te");
- assert(test3 == "tetest");
- test3.deleteData(2, 2);
- assert(test3 == "test");
- foreach (size_t i, XMLCh c; test3) {
- assert(c == "test"[i]);
- }
-
- DOMString test4 = new DOMString("Hello World!"w);
- assert(test1 == test4);
-}
diff --git a/source/newxml/faststrings.d b/source/newxml/faststrings.d
index ebb9674..c256351 100644
--- a/source/newxml/faststrings.d
+++ b/source/newxml/faststrings.d
@@ -22,13 +22,12 @@ import newxml.interfaces : XMLException;
package bool checkStringBeforeChr(T, S)(T[] haysack, S[] needle, S before) @nogc @safe pure nothrow
{
- for (sizediff_t i ; i < haysack.length ; i++)
+ for (sizediff_t i; i < haysack.length; i++)
{
if (haysack[i] == needle[0])
{
- return (cast(sizediff_t)(haysack.length) - i > needle.length)
- ? equal(haysack[i..i + needle.length], needle)
- : false;
+ return (cast(sizediff_t)(haysack.length) - i > needle.length) ? equal(
+ haysack[i .. i + needle.length], needle) : false;
}
else if (haysack[i] == before)
{
@@ -37,9 +36,11 @@ package bool checkStringBeforeChr(T, S)(T[] haysack, S[] needle, S before) @nogc
}
return false;
}
-unittest
+
+@safe pure unittest
{
- assert(checkStringBeforeChr("extentity SYSTEM \"someexternalentity.file\"", "SYSTEM", '"'));
+ assert(checkStringBeforeChr("extentity SYSTEM \"someexternalentity.file\"", "SYSTEM",
+ '"'));
assert(!checkStringBeforeChr("extentity SYST", "SYSTEM", '"'));
assert(!checkStringBeforeChr("intentity \"Some internal entity\"", "SYSTEM", '"'));
}
@@ -71,6 +72,7 @@ T[] xmlEscape(T)(T[] str)
void xmlEscapedWrite(Out, T)(ref Out output, T[] str)
{
import std.conv : to;
+
static immutable amp = to!(T[])("&");
static immutable lt = to!(T[])("<");
static immutable gt = to!(T[])(">");
@@ -80,7 +82,7 @@ void xmlEscapedWrite(Out, T)(ref Out output, T[] str)
ptrdiff_t i;
while ((i = str.indexOfAny("&<>'\"")) >= 0)
{
- output ~= str[0..i];
+ output ~= str[0 .. i];
if (str[i] == '&')
{
@@ -103,12 +105,13 @@ void xmlEscapedWrite(Out, T)(ref Out output, T[] str)
output ~= quot;
}
- str = str[i+1..$];
+ str = str[i + 1 .. $];
}
output ~= str;
}
-auto xmlPredefinedEntities(T)() {
+auto xmlPredefinedEntities(T)()
+{
alias STR = T[];
STR[STR] result;
result["amp"] = "&";
@@ -120,7 +123,7 @@ auto xmlPredefinedEntities(T)() {
return result;
}
-import std.typecons: Flag, Yes;
+import std.typecons : Flag, Yes;
/++
+ Returns a copy of the input string, after unescaping all known entity references.
@@ -137,7 +140,7 @@ T[] xmlUnescape(Flag!"strict" strict = Yes.strict, T, U)(T[] str, U replacements
{
//import newxml.appender;
- T[] app;//auto app = Appender!(T, Alloc)(alloc);
+ T[] app; //auto app = Appender!(T, Alloc)(alloc);
app.reserve(str.length);
app.xmlUnescapedWrite!strict(str, replacements);
@@ -145,13 +148,14 @@ T[] xmlUnescape(Flag!"strict" strict = Yes.strict, T, U)(T[] str, U replacements
}
return str;
}
+
T[] xmlUnescape(Flag!"strict" strict = Yes.strict, T)(T[] str)
{
if (str.indexOf('&') >= 0)
{
//import newxml.appender;
- T[] app;//auto app = Appender!(T, Alloc)(alloc);
+ T[] app; //auto app = Appender!(T, Alloc)(alloc);
app.reserve(str.length);
app.xmlUnescapedWrite!strict(str, xmlPredefinedEntities!T());
@@ -166,15 +170,15 @@ T[] xmlUnescape(Flag!"strict" strict = Yes.strict, T)(T[] str)
+ The set of known entities can be specified with the last parameter, which must support
+ the `in` operator (it is treated as an associative array).
+/
-void xmlUnescapedWrite(Flag!"strict" strict = Yes.strict, Out, T, U)
- (ref Out output, T[] str, U replacements)
+void xmlUnescapedWrite(Flag!"strict" strict = Yes.strict, Out, T, U)(
+ ref Out output, T[] str, U replacements)
{
ptrdiff_t i;
while ((i = str.indexOf('&')) >= 0)
{
- output ~= str[0..i];
+ output ~= str[0 .. i];
- ptrdiff_t j = str[(i+1)..$].indexOf(';');
+ ptrdiff_t j = str[(i + 1) .. $].indexOf(';');
static if (strict == Yes.strict)
{
enforce!XMLException(j >= 0, "Missing ';' ending XML entity!");
@@ -186,7 +190,7 @@ void xmlUnescapedWrite(Flag!"strict" strict = Yes.strict, Out, T, U)
continue;
}
}
- auto ent = str[(i+1)..(i+j+1)];
+ auto ent = str[(i + 1) .. (i + j + 1)];
static if (strict == Yes.strict)
{
enforce!XMLException(ent.length, "Character replacement entity not found!");
@@ -209,11 +213,10 @@ void xmlUnescapedWrite(Flag!"strict" strict = Yes.strict, Out, T, U)
{
static if (strict == Yes.strict)
{
- enforce!XMLException(ent.length <= 10
- , "Number escape value is too large!");
+ enforce!XMLException(ent.length <= 10, "Number escape value is too large!");
}
// TODO this should likely be a call to some phobos function
- foreach(digit; ent[2..$])
+ foreach (digit; ent[2 .. $])
{
if ('0' <= digit && digit <= '9')
{
@@ -241,14 +244,14 @@ void xmlUnescapedWrite(Flag!"strict" strict = Yes.strict, Out, T, U)
}
}
// decimal number
- else
+ else
{
static if (strict == Yes.strict)
{
enforce!XMLException(ent.length <= 12, "Number escape value is too large!");
}
// TODO this should likely be a call to some phobos function
- foreach(digit; ent[1..$])
+ foreach (digit; ent[1 .. $])
{
if ('0' <= digit && digit <= '9')
{
@@ -269,11 +272,10 @@ void xmlUnescapedWrite(Flag!"strict" strict = Yes.strict, Out, T, U)
}
static if (strict == Yes.strict)
{
- enforce!XMLException(num <= 0x10FFFF
- , "Number escape value is too large!");
+ enforce!XMLException(num <= 0x10FFFF, "Number escape value is too large!");
}
- output ~= cast(dchar)num;
+ output ~= cast(dchar) num;
}
// named entities
else
@@ -281,22 +283,21 @@ void xmlUnescapedWrite(Flag!"strict" strict = Yes.strict, Out, T, U)
auto repl = replacements.get(ent, null);
static if (strict == Yes.strict)
{
- enforce!XMLException(repl
- , "Character replacement entity not found!");
+ enforce!XMLException(repl, "Character replacement entity not found!");
}
else
{
if (!repl)
{
output ~= str[i];
- str = str[(i+1)..$];
+ str = str[(i + 1) .. $];
continue;
}
}
output ~= repl;
}
- str = str[(i+j+2)..$];
+ str = str[(i + j + 2) .. $];
}
output ~= str;
}
@@ -306,21 +307,24 @@ unittest
//import std.experimental.allocator.mallocator;//import stdx.allocator.mallocator;
//auto alloc = Mallocator.instance;
assert(xmlEscape("some standard string"d) == "some standard string"d);
- assert(xmlEscape("& \"some\" 'string'") ==
- "& "some" <standard> 'string'");
- assert(xmlEscape("<&'>>>\"'\"<&&"w) ==
- "<&'>>>"'"<&&"w);
+ assert(xmlEscape("& \"some\" 'string'")
+ == "& "some" <standard> 'string'");
+ assert(xmlEscape("<&'>>>\"'\"<&&"w)
+ == "<&'>>>"'"<&&"w);
}
unittest
{
import std.exception : assertThrown;
+
assert(xmlUnescape("some standard string"d) == "some standard string"d);
assert(xmlUnescape("some strange string") == "some strange string");
- assert(xmlUnescape("& "some" <standard> 'string'")
- == "& \"some\" 'string'");
- assert(xmlUnescape("<&'>>>"'"<&&"w)
- == "<&'>>>\"'\"<&&"w);
+ assert(xmlUnescape(
+ "& "some" <standard> 'string'")
+ == "& \"some\" 'string'");
+ assert(xmlUnescape(
+ "<&'>>>"'"<&&"w)
+ == "<&'>>>\"'\"<&&"w);
assert(xmlUnescape("Illegal markup (<% ... %>)") == "Illegal markup (<% ... %>)");
assertThrown!XMLException(xmlUnescape("Fail"));
assertThrown!XMLException(xmlUnescape("Fail"));
diff --git a/source/newxml/interfaces.d b/source/newxml/interfaces.d
index e2565a0..6db09c7 100644
--- a/source/newxml/interfaces.d
+++ b/source/newxml/interfaces.d
@@ -131,25 +131,23 @@ import std.traits;
+/
template isLexer(L)
{
- enum bool isLexer = is(typeof(
- (inout int = 0)
- {
- alias C = L.CharacterType;
-
- L lexer;
- char c;
- bool b;
- string s;
- C[] cs;
-
- b = lexer.empty;
- lexer.start();
- cs = lexer.get();
- b = lexer.testAndAdvance(c);
- lexer.advanceUntil(c, b);
- lexer.advanceUntilAny(s, b);
- lexer.dropWhile(s);
- }));
+ enum bool isLexer = is(typeof((inout int = 0) {
+ alias C = L.CharacterType;
+
+ L lexer;
+ char c;
+ bool b;
+ string s;
+ C[] cs;
+
+ b = lexer.empty;
+ lexer.start();
+ cs = lexer.get();
+ b = lexer.testAndAdvance(c);
+ lexer.advanceUntil(c, b);
+ lexer.advanceUntilAny(s, b);
+ lexer.dropWhile(s);
+ }));
}
/++
@@ -177,12 +175,10 @@ template isLexer(L)
+/
template isSaveableLexer(L)
{
- enum bool isSaveableLexer = isLexer!L && is(typeof(
- (inout int = 0)
- {
- L lexer1;
- L lexer2 = lexer1.save();
- }));
+ enum bool isSaveableLexer = isLexer!L && is(typeof((inout int = 0) {
+ L lexer1;
+ L lexer2 = lexer1.save();
+ }));
}
// LEVEL 2: PARSERS
@@ -274,8 +270,9 @@ enum XMLKind
+/
template isLowLevelParser(P)
{
- enum bool isLowLevelParser = isInputRange!P && is(typeof(ElementType!P.kind) == XMLKind)
- && is(typeof(ElementType!P.content) == P.CharacterType[]);
+ enum bool isLowLevelParser = isInputRange!P
+ && is(typeof(ElementType!P.kind) == XMLKind)
+ && is(typeof(ElementType!P.content) == P.CharacterType[]);
}
/++
@@ -417,32 +414,29 @@ template isSaveableLowLevelParser(P)
+/
template isCursor(CursorType)
{
- enum bool isCursor = is(typeof(
- (inout int = 0)
- {
- alias S = CursorType.StringType;
-
- CursorType cursor;
- bool b;
-
- b = cursor.atBeginning;
- b = cursor.documentEnd;
- b = cursor.next;
- b = cursor.enter;
- cursor.exit;
- XMLKind kind = cursor.kind;
- auto s = cursor.name;
- s = cursor.localName;
- s = cursor.prefix;
- s = cursor.content;
- s = cursor.wholeContent;
- auto attrs = cursor.attributes;
- s = attrs.front.prefix;
- s = attrs.front.localName;
- s = attrs.front.name;
- s = attrs.front.value;
- }
- ));
+ enum bool isCursor = is(typeof((inout int = 0) {
+ alias S = CursorType.StringType;
+
+ CursorType cursor;
+ bool b;
+
+ b = cursor.atBeginning;
+ b = cursor.documentEnd;
+ b = cursor.next;
+ b = cursor.enter;
+ cursor.exit;
+ XMLKind kind = cursor.kind;
+ auto s = cursor.name;
+ s = cursor.localName;
+ s = cursor.prefix;
+ s = cursor.content;
+ s = cursor.wholeContent;
+ auto attrs = cursor.attributes;
+ s = attrs.front.prefix;
+ s = attrs.front.localName;
+ s = attrs.front.name;
+ s = attrs.front.value;
+ }));
}
/++
@@ -470,12 +464,10 @@ template isCursor(CursorType)
+/
template isSaveableCursor(CursorType)
{
- enum bool isSaveableCursor = isCursor!CursorType && is(typeof(
- (inout int = 0)
- {
- CursorType cursor1;
- CursorType cursor2 = cursor1.save();
- }));
+ enum bool isSaveableCursor = isCursor!CursorType && is(typeof((inout int = 0) {
+ CursorType cursor1;
+ CursorType cursor2 = cursor1.save();
+ }));
}
// WRITERS
@@ -484,39 +476,35 @@ template isSaveableCursor(CursorType)
+/
template isWriter(WriterType)
{
- enum bool isWriter = is(typeof(
- (inout int = 0)
- {
- alias StringType = WriterType.StringType;
-
- WriterType writer;
- StringType s;
-
- writer.writeXMLDeclaration(10, s, true);
- writer.writeComment(s);
- writer.writeText(s);
- writer.writeCDATA(s);
- writer.writeProcessingInstruction(s, s);
- writer.startElement(s);
- writer.closeElement(s);
- writer.writeAttribute(s, s);
- }));
+ enum bool isWriter = is(typeof((inout int = 0) {
+ alias StringType = WriterType.StringType;
+
+ WriterType writer;
+ StringType s;
+
+ writer.writeXMLDeclaration(10, s, true);
+ writer.writeComment(s);
+ writer.writeText(s);
+ writer.writeCDATA(s);
+ writer.writeProcessingInstruction(s, s);
+ writer.startElement(s);
+ writer.closeElement(s);
+ writer.writeAttribute(s, s);
+ }));
}
// COMMON
template needSource(T)
{
- enum bool needSource = is(typeof(
- (inout int = 0)
- {
- alias InputType = T.InputType;
+ enum bool needSource = is(typeof((inout int = 0) {
+ alias InputType = T.InputType;
- T component;
- InputType input;
+ T component;
+ InputType input;
- component.setSource(input);
- }));
+ component.setSource(input);
+ }));
}
/++
@@ -525,13 +513,14 @@ template needSource(T)
+/
class XMLException : Exception
{
- @nogc @safe pure nothrow this(string msg, string file = __FILE__, size_t line = __LINE__,
- Throwable nextInChain = null)
+ @nogc @safe pure nothrow this(string msg, string file = __FILE__,
+ size_t line = __LINE__, Throwable nextInChain = null)
{
super(msg, file, line, nextInChain);
}
- @nogc @safe pure nothrow this(string msg, Throwable nextInChain, string file = __FILE__, size_t line = __LINE__)
+ @nogc @safe pure nothrow this(string msg, Throwable nextInChain,
+ string file = __FILE__, size_t line = __LINE__)
{
super(msg, file, line, nextInChain);
}
@@ -540,7 +529,8 @@ class XMLException : Exception
/**
* Defines the document's XML version.
*/
-enum XMLVersion {
+enum XMLVersion
+{
XML1_0,
XML1_1,
}
diff --git a/source/newxml/lexers.d b/source/newxml/lexers.d
index 01e7688..394bbe0 100644
--- a/source/newxml/lexers.d
+++ b/source/newxml/lexers.d
@@ -42,17 +42,21 @@ import std.typecons : Flag, Yes;
/**
* Thrown on lexing errors.
*/
-public class LexerException : Exception {
- @nogc @safe pure nothrow this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable nextInChain = null)
+public class LexerException : Exception
+{
+ @nogc @safe pure nothrow this(string msg, string file = __FILE__,
+ size_t line = __LINE__, Throwable nextInChain = null)
{
super(msg, file, line, nextInChain);
}
- @nogc @safe pure nothrow this(string msg, Throwable nextInChain, string file = __FILE__, size_t line = __LINE__)
+ @nogc @safe pure nothrow this(string msg, Throwable nextInChain,
+ string file = __FILE__, size_t line = __LINE__)
{
super(msg, file, line, nextInChain);
}
}
+
@safe:
/++
+ A lexer that takes a sliceable input.
@@ -93,7 +97,7 @@ struct SliceLexer(T)
pos = 0;
}
- static if(isForwardRange!T)
+ static if (isForwardRange!T)
{
auto save()
{
@@ -118,7 +122,7 @@ struct SliceLexer(T)
/// ditto
CharacterType[] get() const
{
- return input[begin..pos];
+ return input[begin .. pos];
}
/// ditto
@@ -134,7 +138,7 @@ struct SliceLexer(T)
bool testAndAdvance(char c)
{
enforce!LexerException(!empty, "No more characters are found!");
- //handler();
+ //handler();
if (input[pos] == c)
{
pos++;
@@ -147,13 +151,13 @@ struct SliceLexer(T)
void advanceUntil(char c, bool included)
{
enforce!LexerException(!empty, "No more characters are found!");
- //handler();
- auto adv = indexOf(input[pos..$], c);
+ //handler();
+ auto adv = indexOf(input[pos .. $], c);
if (adv != -1)
{
pos += adv;
enforce!LexerException(!empty, "No more characters are found!");
- //handler();
+ //handler();
}
else
{
@@ -163,7 +167,7 @@ struct SliceLexer(T)
if (included)
{
enforce!LexerException(!empty, "No more characters are found!");
- //handler();
+ //handler();
pos++;
}
}
@@ -176,8 +180,7 @@ struct SliceLexer(T)
ptrdiff_t res;
while ((res = indexOf(s, input[pos])) == -1)
{
- enforce!LexerException(++pos < input.length
- , "No more characters are found!");
+ enforce!LexerException(++pos < input.length, "No more characters are found!");
}
if (included)
@@ -203,8 +206,7 @@ struct SliceLexer(T)
+ Params:
+ T = the InputRange to be used as input for this lexer
+/
-struct RangeLexer(T)
- if (isInputRange!T)
+struct RangeLexer(T) if (isInputRange!T)
{
//import newxml.appender;
@@ -222,7 +224,8 @@ struct RangeLexer(T)
//private Appender!(CharacterType, Alloc) app;
private CharacterType[] buffer;
- import std.string: representation;
+ import std.string : representation;
+
static if (is(typeof(representation!CharacterType(""))))
{
private typeof(representation!CharacterType("")) input;
@@ -278,7 +281,7 @@ struct RangeLexer(T)
/// ditto
CharacterType[] get() const
{
- return buffer;//app.data;
+ return buffer; //app.data;
}
/// ditto
@@ -293,11 +296,10 @@ struct RangeLexer(T)
/// ditto
bool testAndAdvance(char c)
{
- enforce!LexerException(!input.empty
- , "No more characters are found!");//handler();
+ enforce!LexerException(!input.empty, "No more characters are found!"); //handler();
if (input.front == c)
{
- buffer ~= input.front;//app.put(input.front);
+ buffer ~= input.front; //app.put(input.front);
input.popFront();
return true;
}
@@ -307,19 +309,17 @@ struct RangeLexer(T)
/// ditto
void advanceUntil(char c, bool included)
{
- enforce!LexerException(!input.empty
- , "No more characters are found!");//handler();
+ enforce!LexerException(!input.empty, "No more characters are found!"); //handler();
while (input.front != c)
{
- buffer ~= input.front;//app.put(input.front);
+ buffer ~= input.front; //app.put(input.front);
input.popFront();
- enforce!LexerException(!input.empty
- , "No more characters are found!");//handler();
+ enforce!LexerException(!input.empty, "No more characters are found!"); //handler();
}
if (included)
{
- buffer ~= input.front;//app.put(input.front);
+ buffer ~= input.front; //app.put(input.front);
input.popFront();
}
}
@@ -327,20 +327,18 @@ struct RangeLexer(T)
/// ditto
size_t advanceUntilAny(string s, bool included)
{
- enforce!LexerException(!input.empty
- , "No more characters are found!");//handler();
+ enforce!LexerException(!input.empty, "No more characters are found!"); //handler();
size_t res;
while ((res = indexOf(s, input.front)) == -1)
{
- buffer ~= input.front;//app.put(input.front);
+ buffer ~= input.front; //app.put(input.front);
input.popFront;
- enforce!LexerException(!input.empty
- , "No more characters are found!");//handler();
+ enforce!LexerException(!input.empty, "No more characters are found!"); //handler();
}
if (included)
{
- buffer ~= input.front;// app.put(input.front);
+ buffer ~= input.front; // app.put(input.front);
input.popFront;
}
return res;
@@ -360,8 +358,7 @@ struct RangeLexer(T)
+ Params:
+ T = the InputRange to be used as input for this lexer
+/
-struct ForwardLexer(T)
- if (isForwardRange!T)
+struct ForwardLexer(T) if (isForwardRange!T)
{
/++
@@ -376,16 +373,17 @@ struct ForwardLexer(T)
//mixin UsesErrorHandler!ErrorHandler;
private size_t count;
- private CharacterType[] buffer;//private Appender!(CharacterType, Alloc) app;
+ private CharacterType[] buffer; //private Appender!(CharacterType, Alloc) app;
+
+ import std.string : representation;
- import std.string: representation;
static if (is(typeof(representation!CharacterType(""))))
{
private typeof(representation!CharacterType("")) input;
private typeof(input) input_start;
void setSource(T input)
{
- buffer.length = 0;//app = typeof(app)(allocator);
+ buffer.length = 0; //app = typeof(app)(allocator);
this.input = input.representation;
this.input_start = this.input;
}
@@ -396,7 +394,7 @@ struct ForwardLexer(T)
private T input_start;
void setSource(T input)
{
- buffer.length = 0;//app = typeof(app)(allocator);
+ buffer.length = 0; //app = typeof(app)(allocator);
this.input = input;
this.input_start = input;
}
@@ -407,7 +405,7 @@ struct ForwardLexer(T)
ForwardLexer result;
result.input = input.save();
result.input_start = input.save();
- result.buffer.length = 0;//result.app = typeof(app)(allocator);
+ result.buffer.length = 0; //result.app = typeof(app)(allocator);
result.count = count;
return result;
}
@@ -433,12 +431,13 @@ struct ForwardLexer(T)
/// ditto
CharacterType[] get()
{
- import std.range: take;
+ import std.range : take;
+
auto diff = count - buffer.length;
if (diff)
{
buffer.reserve(diff);
- buffer ~= input_start.take(diff);//app.put(input_start.take(diff));
+ buffer ~= input_start.take(diff); //app.put(input_start.take(diff));
}
return buffer;
}
@@ -456,7 +455,7 @@ struct ForwardLexer(T)
/// ditto
bool testAndAdvance(char c)
{
- enforce!LexerException(!input.empty , "No data found!");
+ enforce!LexerException(!input.empty, "No data found!");
if (input.front == c)
{
count++;
@@ -469,14 +468,12 @@ struct ForwardLexer(T)
/// ditto
void advanceUntil(char c, bool included)
{
- enforce!LexerException(!input.empty
- , "No data found!");
+ enforce!LexerException(!input.empty, "No data found!");
while (input.front != c)
{
count++;
input.popFront();
- enforce!LexerException(!input.empty
- , "No data found!");
+ enforce!LexerException(!input.empty, "No data found!");
}
if (included)
{
@@ -488,15 +485,13 @@ struct ForwardLexer(T)
/// ditto
size_t advanceUntilAny(string s, bool included)
{
- enforce!LexerException(!input.empty
- , "No more characters are found!");
+ enforce!LexerException(!input.empty, "No more characters are found!");
size_t res;
while ((res = indexOf(s, input.front)) == -1)
{
count++;
input.popFront;
- enforce!LexerException(!input.empty
- , "No more characters are found!");
+ enforce!LexerException(!input.empty, "No more characters are found!");
}
if (included)
{
@@ -523,8 +518,7 @@ struct ForwardLexer(T)
+ Params:
+ T = the InputRange to be used as input for this lexer
+/
-struct BufferedLexer(T)
- if (isInputRange!T && isArray!(ElementType!T))
+struct BufferedLexer(T) if (isInputRange!T && isArray!(ElementType!T))
{
//import newxml.appender;
@@ -542,7 +536,7 @@ struct BufferedLexer(T)
private size_t pos;
private size_t begin;
- private CharacterType[] outBuf;//private Appender!(CharacterType, Alloc) app;
+ private CharacterType[] outBuf; //private Appender!(CharacterType, Alloc) app;
private bool onEdge;
private BufferType buffer;
@@ -572,7 +566,7 @@ struct BufferedLexer(T)
result.buffer = buffer;
result.pos = pos;
result.begin = begin;
- result.outBuf.length = 0;//app = typeof(app)(allocator);
+ result.outBuf.length = 0; //app = typeof(app)(allocator);
return result;
}
}
@@ -601,17 +595,16 @@ struct BufferedLexer(T)
private void advance()
{
- enforce!LexerException(!empty
- , "No more characters are found!");
+ enforce!LexerException(!empty, "No more characters are found!");
if (pos + 1 >= buffer.length)
{
if (onEdge)
{
- outBuf ~= buffer[pos];//app.put(buffer[pos]);
+ outBuf ~= buffer[pos]; //app.put(buffer[pos]);
}
else
{
- outBuf ~= buffer[begin..$];//app.put(buffer[begin..$]);
+ outBuf ~= buffer[begin .. $]; //app.put(buffer[begin..$]);
onEdge = true;
}
popBuffer;
@@ -620,31 +613,32 @@ struct BufferedLexer(T)
}
else if (onEdge)
{
- outBuf ~= buffer[pos++];//app.put(buffer[pos++]);
+ outBuf ~= buffer[pos++]; //app.put(buffer[pos++]);
}
else
{
pos++;
}
}
+
private void advance(ptrdiff_t n)
{
- foreach(i; 0..n)
+ foreach (i; 0 .. n)
{
advance();
}
}
+
private void advanceNextBuffer()
{
- enforce!LexerException(!empty
- , "No more characters are found!");
+ enforce!LexerException(!empty, "No more characters are found!");
if (onEdge)
{
- outBuf ~= buffer[pos..$]; //app.put(buffer[pos..$]);
+ outBuf ~= buffer[pos .. $]; //app.put(buffer[pos..$]);
}
else
{
- outBuf ~= buffer[begin..$];//app.put(buffer[begin..$]);
+ outBuf ~= buffer[begin .. $]; //app.put(buffer[begin..$]);
onEdge = true;
}
popBuffer;
@@ -660,17 +654,17 @@ struct BufferedLexer(T)
{
if (onEdge)
{
- return outBuf;//app.data;
+ return outBuf; //app.data;
}
else
{
static if (is(typeof(representation!CharacterType(""))))
{
- return cast(CharacterType[])buffer[begin..pos];
+ return cast(CharacterType[]) buffer[begin .. pos];
}
else
{
- return buffer[begin..pos];
+ return buffer[begin .. pos];
}
}
}
@@ -702,7 +696,7 @@ struct BufferedLexer(T)
{
enforce!LexerException(!empty, "No data found!");
ptrdiff_t adv;
- while ((adv = indexOf(buffer[pos..$], c)) == -1)
+ while ((adv = indexOf(buffer[pos .. $], c)) == -1)
{
advanceNextBuffer();
}
@@ -776,7 +770,7 @@ template lexer()
}
}
-version(unittest)
+version (unittest)
{
struct DumbBufferedReader
{
@@ -785,16 +779,15 @@ version(unittest)
void popFront() @nogc
{
- content = content.length > chunk_size
- ? content[chunk_size..$]
- : [];
+ content = content.length > chunk_size ? content[chunk_size .. $] : [
+ ];
}
+
string front() const @nogc
{
- return content.length >= chunk_size
- ? content[0..chunk_size]
- : content[0..$];
+ return content.length >= chunk_size ? content[0 .. chunk_size] : content[0 .. $];
}
+
bool empty() const @nogc
{
return !content.length;
@@ -853,4 +846,3 @@ unittest
testLexer!(ForwardLexer!(string))(x => x);
testLexer!(BufferedLexer!(DumbBufferedReader))(x => DumbBufferedReader(x, 10));
}
-
diff --git a/source/newxml/package.d b/source/newxml/package.d
index e052237..1340036 100644
--- a/source/newxml/package.d
+++ b/source/newxml/package.d
@@ -3,7 +3,6 @@ module newxml;
public import newxml.dom;
public import domimpl = newxml.domimpl;
public import newxml.domparser;
-public import newxml.domstring;
public import newxml.sax;
public import newxml.writer;
public import newxml.cursor;
@@ -21,12 +20,8 @@ public import newxml.parser;
+/
Document parseXMLString(string input)
{
- auto builder =
- input
- .lexer
- .parser
- .cursor
- .domBuilder(new domimpl.DOMImplementation());
+ auto builder = input.lexer.parser.cursor.domBuilder(new domimpl
+ .DOMImplementation());
builder.setSource(input);
builder.buildRecursive();
@@ -34,7 +29,8 @@ Document parseXMLString(string input)
}
///
-unittest {
+unittest
+{
import std.format;
string xml = q"{
@@ -49,5 +45,5 @@ unittest {
Document doc = parseXMLString(xml);
assert(doc !is null);
- assert(doc.doctype.entities.getNamedItem(new DOMString("myent")).nodeValue == "replacement text");
+ assert(doc.doctype.entities.getNamedItem("myent").nodeValue == "replacement text");
}
diff --git a/source/newxml/parser.d b/source/newxml/parser.d
index 3006946..95131a2 100644
--- a/source/newxml/parser.d
+++ b/source/newxml/parser.d
@@ -32,17 +32,21 @@ import std.algorithm.comparison : equal;
import std.exception : enforce;
import std.typecons : Flag, Yes, No;
-public class ParserException : XMLException {
- @nogc @safe pure nothrow this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable nextInChain = null)
+public class ParserException : XMLException
+{
+ @nogc @safe pure nothrow this(string msg, string file = __FILE__,
+ size_t line = __LINE__, Throwable nextInChain = null)
{
super(msg, file, line, nextInChain);
}
- @nogc @safe pure nothrow this(string msg, Throwable nextInChain, string file = __FILE__, size_t line = __LINE__)
+ @nogc @safe pure nothrow this(string msg, Throwable nextInChain,
+ string file = __FILE__, size_t line = __LINE__)
{
super(msg, file, line, nextInChain);
}
}
+
@safe:
/++
+ A low level XML parser.
@@ -55,8 +59,8 @@ public class ParserException : XMLException {
+ preserveWhitespace = if set to `Yes` (default is `No`), the parser will not remove element content whitespace
+ (i.e. the whitespace that separates tags), but will report it as text.
+/
-struct Parser(L, Flag!"preserveWhitespace" preserveWhitespace = No.preserveWhitespace)
- if (isLexer!L)
+struct Parser(L, Flag!"preserveWhitespace" preserveWhitespace = No
+ .preserveWhitespace) if (isLexer!L)
{
import std.meta : staticIndexOf;
@@ -89,7 +93,8 @@ struct Parser(L, Flag!"preserveWhitespace" preserveWhitespace = No.preserveWhite
//mixin UsesErrorHandler!ErrorHandler;
- this(L lexer) {
+ this(L lexer)
+ {
this.lexer = lexer;
//chrEntities = xmlPredefinedEntities!CharacterType();
}
@@ -129,7 +134,7 @@ struct Parser(L, Flag!"preserveWhitespace" preserveWhitespace = No.preserveWhite
private CharacterType[] fetchContent(size_t start = 0, size_t stop = 0)
{
- return lexer.get[start..($ - stop)];
+ return lexer.get[start .. ($ - stop)];
}
/++
@@ -139,7 +144,9 @@ struct Parser(L, Flag!"preserveWhitespace" preserveWhitespace = No.preserveWhite
bool empty()
{
static if (preserveWhitespace == No.preserveWhitespace)
+ {
lexer.dropWhile(" \r\n\t");
+ }
return !ready && lexer.empty;
}
@@ -169,7 +176,7 @@ struct Parser(L, Flag!"preserveWhitespace" preserveWhitespace = No.preserveWhite
lexer.dropWhile(" \r\n\t");
}
- assert(!lexer.empty);
+ enforce!ParserException(!lexer.empty, "Lexer must not be empty");
lexer.start();
@@ -177,8 +184,8 @@ struct Parser(L, Flag!"preserveWhitespace" preserveWhitespace = No.preserveWhite
if (insideDTD && lexer.testAndAdvance(']'))
{
lexer.dropWhile(" \r\n\t");
- enforce!ParserException(lexer.testAndAdvance('>')
- , "No \">\" character have been found after an \"<\"!");
+ enforce!ParserException(lexer.testAndAdvance('>'),
+ "No \">\" character have been found after an \"<\"!");
next.kind = XMLKind.dtdEnd;
next.content = null;
insideDTD = false;
@@ -252,13 +259,13 @@ struct Parser(L, Flag!"preserveWhitespace" preserveWhitespace = No.preserveWhite
{
lexer.advanceUntil('[', true);
// cdata
- if (lexer.get.length == 9 && equal(lexer.get()[3..$], "CDATA["))
+ if (lexer.get.length == 9 && equal(lexer.get()[3 .. $], "CDATA["))
{
do
{
lexer.advanceUntil('>', true);
}
- while (!equal(lexer.get()[($-3)..$], "]]>"));
+ while (!equal(lexer.get()[($ - 3) .. $], "]]>"));
next.content = fetchContent(9, 3);
next.kind = XMLKind.cdata;
}
@@ -268,11 +275,11 @@ struct Parser(L, Flag!"preserveWhitespace" preserveWhitespace = No.preserveWhite
do
{
lexer.advanceUntilAny("[>", true);
- if (lexer.get()[($-3)..$] == "]]>")
+ if (lexer.get()[($ - 3) .. $] == "]]>")
{
count--;
}
- else if (lexer.get()[($-3)..$] == "', true);
}
- while (!equal(lexer.get()[($-3)..$], "-->"));
+ while (!equal(lexer.get()[($ - 3) .. $], "-->"));
next.content = fetchContent(4, 3);
next.kind = XMLKind.comment;
}
@@ -309,7 +316,7 @@ struct Parser(L, Flag!"preserveWhitespace" preserveWhitespace = No.preserveWhite
}
// doctype
- if (lexer.get.length>= 9 && equal(lexer.get()[2..9], "DOCTYPE"))
+ if (lexer.get.length >= 9 && equal(lexer.get()[2 .. 9], "DOCTYPE"))
{
next.content = fetchContent(9, 1);
if (c == 2)
@@ -340,22 +347,22 @@ struct Parser(L, Flag!"preserveWhitespace" preserveWhitespace = No.preserveWhite
}
}
auto len = lexer.get().length;
- if (len > 8 && equal(lexer.get()[2..9], "ATTLIST"))
+ if (len > 8 && equal(lexer.get()[2 .. 9], "ATTLIST"))
{
next.content = fetchContent(9, 1);
next.kind = XMLKind.attlistDecl;
}
- else if (len > 8 && equal(lexer.get()[2..9], "ELEMENT"))
+ else if (len > 8 && equal(lexer.get()[2 .. 9], "ELEMENT"))
{
next.content = fetchContent(9, 1);
next.kind = XMLKind.elementDecl;
}
- else if (len > 9 && equal(lexer.get()[2..10], "NOTATION"))
+ else if (len > 9 && equal(lexer.get()[2 .. 10], "NOTATION"))
{
next.content = fetchContent(10, 1);
next.kind = XMLKind.notationDecl;
}
- else if (len > 7 && equal(lexer.get()[2..8], "ENTITY"))
+ else if (len > 7 && equal(lexer.get()[2 .. 8], "ENTITY"))
{
next.content = fetchContent(8, 1);
next.kind = XMLKind.entityDecl;
@@ -383,8 +390,8 @@ struct Parser(L, Flag!"preserveWhitespace" preserveWhitespace = No.preserveWhite
+ Returns:
+ A `Parser` instance initialized with the given lexer
+/
-auto parser(Flag!"preserveWhitespace" preserveWhitespace = No.preserveWhitespace, T)(T lexer)
- if (isLexer!T)
+auto parser(Flag!"preserveWhitespace" preserveWhitespace = No.preserveWhitespace, T)(
+ T lexer) if (isLexer!T)
{
auto parser = Parser!(T, preserveWhitespace)();
//parser.errorHandler = handler;
@@ -393,7 +400,7 @@ auto parser(Flag!"preserveWhitespace" preserveWhitespace = No.preserveWhitespace
}
import newxml.lexers;
-import std.experimental.allocator.gc_allocator;//import stdx.allocator.gc_allocator;
+import std.experimental.allocator.gc_allocator; //import stdx.allocator.gc_allocator;
/++
+ Instantiates a parser suitable for the given `InputType`.
@@ -405,13 +412,13 @@ import std.experimental.allocator.gc_allocator;//import stdx.allocator.gc_alloca
+ .parser!(preserveWhitespace)(handler)
+ ---
+/
-auto chooseParser(InputType, Flag!"preserveWhitespace" preserveWhitespace = No.preserveWhitespace)()
+auto chooseParser(InputType, Flag!"preserveWhitespace" preserveWhitespace = No
+ .preserveWhitespace)()
{
- return chooseLexer!(InputType)()
- .parser!(preserveWhitespace)();
+ return chooseLexer!(InputType)().parser!(preserveWhitespace)();
}
-unittest
+@safe pure unittest
{
import newxml.lexers;
import std.algorithm : find;
diff --git a/source/newxml/sax.d b/source/newxml/sax.d
index 0e77b50..9d87927 100644
--- a/source/newxml/sax.d
+++ b/source/newxml/sax.d
@@ -11,6 +11,7 @@
+ Authors:
+ Lodovico Giaretta
+ László Szerémi
++ Robert Schadek
+
+ License:
+ Boost License 1.0.
@@ -24,6 +25,7 @@ module newxml.sax;
import newxml.interfaces;
import newxml.cursor;
import newxml.faststrings;
+
@safe:
/++
+ A SAX parser built on top of a cursor.
@@ -31,8 +33,7 @@ import newxml.faststrings;
+ Delegates are called when certain events are encountered, then it passes the necessary data to process the
+ element.
+/
-struct SAXParser(T)
- if (isCursor!T)
+struct SAXParser(T) if (isCursor!T)
{
public T cursor;
alias StringType = T.StringType;
@@ -82,68 +83,91 @@ struct SAXParser(T)
void processDocument()
{
import std.traits : hasMember;
+
while (!cursor.documentEnd)
{
switch (cursor.kind)
{
- case XMLKind.document:
- if (onDocument !is null)
- onDocument(createAArray(cursor.attributes));
- break;
- case XMLKind.dtdStart:
- if (onDocTypeDecl !is null)
- onDocTypeDecl(cursor.content, false);
- break;
- case XMLKind.entityDecl:
- if (checkStringBeforeChr(cursor.wholeContent, "SYSTEM", '"') ||
- checkStringBeforeChr(cursor.wholeContent, "SYSTEM", '\''))
- {
- if (cursor.sysEntityLoader !is null)
- {
- cursor.chrEntities[cursor.name] = cursor.sysEntityLoader(cursor.content);
- }
- }
- else
+ case XMLKind.document:
+ if (onDocument !is null)
+ {
+ onDocument(createAArray(cursor.attributes));
+ }
+ break;
+ case XMLKind.dtdStart:
+ if (onDocTypeDecl !is null)
+ {
+ onDocTypeDecl(cursor.content, false);
+ }
+ break;
+ case XMLKind.entityDecl:
+ if (checkStringBeforeChr(cursor.wholeContent, "SYSTEM", '"')
+ || checkStringBeforeChr(cursor.wholeContent, "SYSTEM", '\''))
+ {
+ if (cursor.sysEntityLoader !is null)
{
- cursor.chrEntities[cursor.name] = cursor.content;
+ cursor.chrEntities[cursor.name] = cursor.sysEntityLoader(
+ cursor.content);
}
- break;
+ }
+ else
+ {
+ cursor.chrEntities[cursor.name] = cursor.content;
+ }
+ break;
/* case XMLKind.dtdEnd:
break; */
- case XMLKind.dtdEmpty:
- if (onDocTypeDecl !is null)
- onDocTypeDecl(cursor.content, true);
- break;
- case XMLKind.elementStart:
- if (onElementStart !is null)
- onElementStart(cursor.name, createAArray(cursor.attributes));
- break;
- case XMLKind.elementEnd:
- if (onElementEnd !is null)
- onElementEnd(cursor.name);
- break;
- case XMLKind.elementEmpty:
- if (onElementEmpty !is null)
- onElementEmpty(cursor.name, createAArray(cursor.attributes));
- break;
- case XMLKind.text:
- if (onText !is null)
- onText(cursor.content);
- break;
- case XMLKind.comment:
- if (onComment !is null)
- onComment(cursor.content);
- break;
- case XMLKind.processingInstruction:
- if (onProcessingInstruction !is null)
- onProcessingInstruction(cursor.name, cursor.content);
- break;
- case XMLKind.cdata:
- if (onCDataSection !is null)
- onCDataSection(cursor.content);
- break;
-
- default: break;
+ case XMLKind.dtdEmpty:
+ if (onDocTypeDecl !is null)
+ {
+ onDocTypeDecl(cursor.content, true);
+ }
+ break;
+ case XMLKind.elementStart:
+ if (onElementStart !is null)
+ {
+ onElementStart(cursor.name, createAArray(cursor.attributes));
+ }
+ break;
+ case XMLKind.elementEnd:
+ if (onElementEnd !is null)
+ {
+ onElementEnd(cursor.name);
+ }
+ break;
+ case XMLKind.elementEmpty:
+ if (onElementEmpty !is null)
+ {
+ onElementEmpty(cursor.name, createAArray(cursor.attributes));
+ }
+ break;
+ case XMLKind.text:
+ if (onText !is null)
+ {
+ onText(cursor.content);
+ }
+ break;
+ case XMLKind.comment:
+ if (onComment !is null)
+ {
+ onComment(cursor.content);
+ }
+ break;
+ case XMLKind.processingInstruction:
+ if (onProcessingInstruction !is null)
+ {
+ onProcessingInstruction(cursor.name, cursor.content);
+ }
+ break;
+ case XMLKind.cdata:
+ if (onCDataSection !is null)
+ {
+ onCDataSection(cursor.content);
+ }
+ break;
+
+ default:
+ break;
}
if (cursor.enter)
@@ -155,7 +179,9 @@ struct SAXParser(T)
}
}
}
- protected StringType[StringType] createAArray(AttrRange source) {
+
+ protected StringType[StringType] createAArray(AttrRange source)
+ {
StringType[StringType] result;
foreach (key; source)
{
@@ -168,15 +194,14 @@ struct SAXParser(T)
/++
+ Instantiates a suitable SAX parser from the given `cursor` and `handler`.
+/
-auto saxParser(CursorType)(auto ref CursorType cursor)
- if (isCursor!CursorType)
+auto saxParser(CursorType)(auto ref CursorType cursor) if (isCursor!CursorType)
{
auto res = SAXParser!(CursorType)();
res.cursor = cursor;
return res;
}
-unittest
+@safe unittest
{
import newxml.parser;
import newxml.lexers;
@@ -198,6 +223,8 @@ unittest
struct MyHandler
{
+ @safe:
+
int max_nesting;
int current_nesting;
int total_invocations;
@@ -211,38 +238,49 @@ unittest
max_nesting = current_nesting;
}
}
+
void onElementEnd(dstring name)
{
total_invocations++;
current_nesting--;
}
- void onElementEmpty(dstring name, dstring[dstring] attributes) { total_invocations++; }
- void onProcessingInstruction(dstring name, dstring content) { total_invocations++; }
- void onText(dstring content) { total_invocations++; }
+
+ void onElementEmpty(dstring name, dstring[dstring] attributes)
+ {
+ total_invocations++;
+ }
+
+ void onProcessingInstruction(dstring name, dstring content)
+ {
+ total_invocations++;
+ }
+
+ void onText(dstring content)
+ {
+ total_invocations++;
+ }
+
void onDocument(dstring[dstring] attribute)
{
assert(attribute["encoding"] == "utf-8");
total_invocations++;
}
+
void onComment(dstring content)
{
assert(content == " lol ");
total_invocations++;
}
- void onDocTypeDecl(dstring type, bool empty) {
+
+ void onDocTypeDecl(dstring type, bool empty)
+ {
assert(type == "somekindofdoc", type.to!string);
assert(empty);
}
}
-
MyHandler handler;
- auto parser =
- xml
- .lexer
- .parser
- .cursor
- .saxParser;
+ auto parser = xml.lexer.parser.cursor.saxParser;
parser.setSource(xml);
parser.onDocument = &handler.onDocument;
@@ -260,7 +298,7 @@ unittest
assert(handler.total_invocations == 9, to!string(handler.total_invocations));
}
-unittest
+@safe unittest
{
import newxml.parser;
import newxml.lexers;
@@ -279,6 +317,8 @@ unittest
struct MyHandler
{
+ @safe:
+
int max_nesting;
int current_nesting;
int total_invocations;
@@ -292,20 +332,26 @@ unittest
max_nesting = current_nesting;
}
}
+
void onElementEnd(dstring name)
{
total_invocations++;
current_nesting--;
}
- void onText(dstring content) {
- assert (content == "replacement text");
- total_invocations++;
+
+ void onText(dstring content)
+ {
+ assert(content == "replacement text");
+ total_invocations++;
}
- void onDocTypeDecl(dstring type, bool empty) {
+
+ void onDocTypeDecl(dstring type, bool empty)
+ {
assert(type == "mydoc", type.to!string);
assert(!empty);
total_invocations++;
}
+
void onDocument(dstring[dstring] attribute)
{
assert(attribute["encoding"] == "utf-8");
@@ -314,12 +360,7 @@ unittest
}
MyHandler handler;
- auto parser =
- xml
- .lexer
- .parser
- .cursor
- .saxParser;
+ auto parser = xml.lexer.parser.cursor.saxParser;
parser.setSource(xml);
parser.onElementStart = &handler.onElementStart;
parser.onElementEnd = &handler.onElementEnd;
@@ -331,4 +372,4 @@ unittest
assert(handler.max_nesting == 1, to!string(handler.max_nesting));
assert(handler.current_nesting == 0, to!string(handler.current_nesting));
assert(handler.total_invocations == 5, to!string(handler.total_invocations));
-}
\ No newline at end of file
+}
diff --git a/source/newxml/validation.d b/source/newxml/validation.d
index ae3f1af..374b810 100644
--- a/source/newxml/validation.d
+++ b/source/newxml/validation.d
@@ -29,10 +29,8 @@ import newxml.interfaces;
*/
pure nothrow @nogc @safe bool isValidXMLCharacter10(dchar c)
{
- return c == '\r' || c == '\n' || c == '\t'
- || (0x20 <= c && c <= 0xD7FF)
- || (0xE000 <= c && c <= 0xFFFD)
- || (0x10000 <= c && c <= 0x10FFFF);
+ return c == '\r' || c == '\n' || c == '\t' || (0x20 <= c && c <= 0xD7FF)
+ || (0xE000 <= c && c <= 0xFFFD) || (0x10000 <= c && c <= 0x10FFFF);
}
/**
@@ -40,9 +38,7 @@ pure nothrow @nogc @safe bool isValidXMLCharacter10(dchar c)
*/
pure nothrow @nogc @safe bool isValidXMLCharacter11(dchar c)
{
- return (1 <= c && c <= 0xD7FF)
- || (0xE000 <= c && c <= 0xFFFD)
- || (0x10000 <= c && c <= 0x10FFFF);
+ return (1 <= c && c <= 0xD7FF) || (0xE000 <= c && c <= 0xFFFD) || (0x10000 <= c && c <= 0x10FFFF);
}
/**
* Checks whether a text contains invalid characters for an XML 1.0 document.
@@ -54,7 +50,10 @@ pure nothrow @nogc @safe bool isValidXMLText10(T)(T[] input)
{
foreach (elem; input)
{
- if (!isValidXMLCharacter10(elem)) return false;
+ if (!isValidXMLCharacter10(elem))
+ {
+ return false;
+ }
}
return true;
}
@@ -68,7 +67,10 @@ pure nothrow @nogc @safe bool isValidXMLText11(T)(T[] input)
{
foreach (elem; input)
{
- if (!isValidXMLCharacter11(elem)) return false;
+ if (!isValidXMLCharacter11(elem))
+ {
+ return false;
+ }
}
return true;
}
@@ -78,19 +80,13 @@ pure nothrow @nogc @safe bool isValidXMLText11(T)(T[] input)
*/
pure nothrow @nogc @safe bool isValidXMLNameStart(dchar c)
{
- return c == ':'
- || ('A' <= c && c <= 'Z')
- || c == '_'
- || ('a' <= c && c <= 'z')
- || (0xC0 <= c && c <= 0x2FF && c != 0xD7 && c != 0xF7)
- || (0x370 <= c && c <= 0x1FFF && c != 0x37E)
- || c == 0x200C
- || c == 0x200D
- || (0x2070 <= c && c <= 0x218F)
- || (0x2C00 <= c && c <= 0x2FEF)
- || (0x3001 <= c && c <= 0xD7FF)
- || (0xF900 <= c && c <= 0xFDCF)
- || (0xFDF0 <= c && c <= 0xEFFFF && c != 0xFFFE && c != 0xFFFF);
+ return c == ':' || ('A' <= c && c <= 'Z') || c == '_' || ('a' <= c && c <= 'z')
+ || (0xC0 <= c && c <= 0x2FF && c != 0xD7 && c != 0xF7) || (0x370 <= c
+ && c <= 0x1FFF
+ && c != 0x37E) || c == 0x200C || c == 0x200D || (0x2070 <= c
+ && c <= 0x218F) || (0x2C00 <= c && c <= 0x2FEF) || (0x3001 <= c
+ && c <= 0xD7FF) || (0xF900 <= c && c <= 0xFDCF) || (0xFDF0 <= c
+ && c <= 0xEFFFF && c != 0xFFFE && c != 0xFFFF);
}
/**
@@ -98,13 +94,8 @@ pure nothrow @nogc @safe bool isValidXMLNameStart(dchar c)
*/
pure nothrow @nogc @safe bool isValidXMLNameChar(dchar c)
{
- return isValidXMLNameStart(c)
- || c == '-'
- || c == '.'
- || ('0' <= c && c <= '9')
- || c == 0xB7
- || (0x300 <= c && c <= 0x36F)
- || (0x203F <= c && c <= 2040);
+ return isValidXMLNameStart(c) || c == '-' || c == '.' || ('0' <= c && c <= '9')
+ || c == 0xB7 || (0x300 <= c && c <= 0x36F) || (0x203F <= c && c <= 2040);
}
/**
@@ -113,7 +104,8 @@ pure nothrow @nogc @safe bool isValidXMLNameChar(dchar c)
* input = The input string.
* Returns: True if XML name is valid.
*/
-pure nothrow @nogc @safe bool isValidXMLName(T)(T[] input) {
+pure nothrow @nogc @safe bool isValidXMLName(T)(T[] input)
+{
if (!input.length)
{
return false;
@@ -123,7 +115,7 @@ pure nothrow @nogc @safe bool isValidXMLName(T)(T[] input) {
return false;
}
- for (sizediff_t i = 1 ; i < input.length; i++)
+ for (sizediff_t i = 1; i < input.length; i++)
{
if (!isValidXMLNameChar(input[i]))
{
@@ -139,17 +131,14 @@ pure nothrow @nogc @safe bool isValidXMLName(T)(T[] input) {
*/
pure nothrow @nogc @safe bool isValidXMLPublicIdCharacter(dchar c)
{
- import std.string: indexOf;
- return c == ' '
- || c == '\n'
- || c == '\r'
- || ('a' <= c && c <= 'z')
- || ('A' <= c && c <= 'Z')
- || ('0' <= c && c <= '9')
- || "-'()+,./:=?;!*#@$_%".indexOf(c) != -1;
+ import std.string : indexOf;
+
+ return c == ' ' || c == '\n' || c == '\r' || ('a' <= c && c <= 'z') || ('A' <= c
+ && c <= 'Z') || ('0' <= c && c <= '9') || "-'()+,./:=?;!*#@$_%"
+ .indexOf(c) != -1;
}
-unittest
+@safe pure unittest
{
assert(isValidXMLName("foo"));
assert(isValidXMLName("bar"));
@@ -182,8 +171,8 @@ struct ValidationStack(StringType)
{
if (stack.length)
{
- StringType top = stack[$-1];
- stack = stack[0..$-1];
+ StringType top = stack[$ - 1];
+ stack = stack[0 .. $ - 1];
return top == input;
}
else
diff --git a/source/newxml/writer.d b/source/newxml/writer.d
index 0c562f1..5076663 100644
--- a/source/newxml/writer.d
+++ b/source/newxml/writer.d
@@ -22,10 +22,12 @@ private string ifCompiles(string code)
{
return "static if (__traits(compiles, " ~ code ~ ")) " ~ code ~ ";\n";
}
+
private string ifCompilesElse(string code, string fallback)
{
return "static if (__traits(compiles, " ~ code ~ ")) " ~ code ~ "; else " ~ fallback ~ ";\n";
}
+
private string ifAnyCompiles(string code, string[] codes...)
{
if (codes.length == 0)
@@ -34,8 +36,8 @@ private string ifAnyCompiles(string code, string[] codes...)
}
else
{
- return "static if (__traits(compiles, " ~ code ~ ")) " ~ code ~
- "; else " ~ ifAnyCompiles(codes[0], codes[1..$]);
+ return "static if (__traits(compiles, " ~ code ~ ")) " ~ code ~ "; else "
+ ~ ifAnyCompiles(codes[0], codes[1 .. $]);
}
}
@@ -46,14 +48,14 @@ private auto xmlDeclarationAttributes(StringType, Args...)(Args args)
// version specification
static if (is(Args[0] == int))
{
- assert(args[0] == 10 || args[0] == 11, "Invalid xml version specified");
+ enforce(args[0] == 10 || args[0] == 11, "Invalid xml version specified");
StringType versionString = args[0] == 10 ? "1.0" : "1.1";
- auto args1 = args[1..$];
+ auto args1 = args[1 .. $];
}
else static if (is(Args[0] == StringType))
{
StringType versionString = args[0];
- auto args1 = args[1..$];
+ auto args1 = args[1 .. $];
}
else
{
@@ -65,7 +67,7 @@ private auto xmlDeclarationAttributes(StringType, Args...)(Args args)
static if (is(typeof(args1[0]) == StringType))
{
auto encodingString = args1[0];
- auto args2 = args1[1..$];
+ auto args2 = args1[1 .. $];
}
else
{
@@ -77,7 +79,7 @@ private auto xmlDeclarationAttributes(StringType, Args...)(Args args)
static if (is(typeof(args2[0]) == bool))
{
StringType standaloneString = args2[0] ? "yes" : "no";
- auto args3 = args2[1..$];
+ auto args3 = args2[1 .. $];
}
else
{
@@ -87,8 +89,8 @@ private auto xmlDeclarationAttributes(StringType, Args...)(Args args)
// catch other erroneous parameters
static assert(typeof(args3).length == 0,
- "Unrecognized attribute type for xml declaration: "
- ~ typeof(args3[0]).stringof);
+ "Unrecognized attribute type for xml declaration: " ~ typeof(args3[0])
+ .stringof);
return tuple(versionString, encodingString, standaloneString);
}
@@ -123,12 +125,19 @@ struct PrettyPrinters
uint indentation;
enum StringType tab = "\t";
- void decreaseLevel() { indentation--; }
- void increaseLevel() { indentation++; }
+ void decreaseLevel()
+ {
+ indentation--;
+ }
+
+ void increaseLevel()
+ {
+ indentation++;
+ }
void beforeNode(Out)(ref Out output)
{
- foreach (i; 0..indentation)
+ foreach (i; 0 .. indentation)
{
output ~= tab;
}
@@ -193,7 +202,7 @@ struct PrettyPrinters
+ validateTagOrder = If set to `Yes`, then tag order will be validated during writing.
+/
struct Writer(_StringType, alias PrettyPrinter = PrettyPrinters.Minimalizer)
- if(is(_StringType == string) || is(_StringType == wstring) || is(_StringType == dstring))
+ if (is(_StringType == string) || is(_StringType == wstring) || is(_StringType == dstring))
{
alias StringType = _StringType;
@@ -207,35 +216,38 @@ struct Writer(_StringType, alias PrettyPrinter = PrettyPrinters.Minimalizer)
}
else
{
- static assert(0, "Invalid pretty printer type for string type " ~ StringType.stringof);
+ static assert(0, "Invalid pretty printer type for string type " ~ StringType
+ .stringof);
}
StringType output;
- bool startingTag = false, insideDTD = false;
+ bool startingTag = false;
+ bool insideDTD = false;
this(typeof(prettyPrinter) pretty)
{
- prettyPrinter = pretty;
+ this.prettyPrinter = pretty;
}
private template expand(string methodName)
{
import std.meta : AliasSeq;
- alias expand = AliasSeq!(
- "prettyPrinter." ~ methodName ~ "(output)",
- "output ~= prettyPrinter." ~ methodName
- );
+
+ alias expand = AliasSeq!("prettyPrinter." ~ methodName ~ "(output)",
+ "output ~= prettyPrinter." ~ methodName);
}
+
private template formatAttribute(string attribute)
{
import std.meta : AliasSeq;
+
alias formatAttribute = AliasSeq!(
- "prettyPrinter.formatAttribute(output, " ~ attribute ~ ")",
- "output ~= prettyPrinter.formatAttribute(" ~ attribute ~ ")",
- "defaultFormatAttribute(" ~ attribute ~ ", prettyPrinter.attributeDelimiter)",
- "defaultFormatAttribute(" ~ attribute ~ ")"
- );
+ "prettyPrinter.formatAttribute(output, " ~ attribute ~ ")",
+ "output ~= prettyPrinter.formatAttribute(" ~ attribute ~ ")",
+ "defaultFormatAttribute("
+ ~ attribute ~ ", prettyPrinter.attributeDelimiter)",
+ "defaultFormatAttribute(" ~ attribute ~ ")");
}
private void defaultFormatAttribute(StringType attribute, StringType delimiter = "'")
@@ -293,6 +305,7 @@ struct Writer(_StringType, alias PrettyPrinter = PrettyPrinters.Minimalizer)
output ~= "?>";
mixin(ifAnyCompiles(expand!"afterNode"));
}
+
void writeXMLDeclaration(StringType version_, StringType encoding, StringType standalone)
{
output ~= "";
@@ -358,10 +368,7 @@ struct Writer(_StringType, alias PrettyPrinter = PrettyPrinters.Minimalizer)
closeOpenThings;
mixin(ifAnyCompiles(expand!"beforeNode"));
- mixin(ifCompilesElse(
- "prettyPrinter.formatText(output, comment)",
- "output ~= text"
- ));
+ mixin(ifCompilesElse("prettyPrinter.formatText(output, comment)", "output ~= text"));
mixin(ifAnyCompiles(expand!"afterNode"));
}
/++
@@ -417,13 +424,11 @@ struct Writer(_StringType, alias PrettyPrinter = PrettyPrinters.Minimalizer)
output ~= tagName;
startingTag = true;
}
+
void closeElement(StringType tagName)
{
bool selfClose;
- mixin(ifCompilesElse(
- "selfClose = prettyPrinter.selfClosingElements",
- "selfClose = true"
- ));
+ mixin(ifCompilesElse("selfClose = prettyPrinter.selfClosingElements", "selfClose = true"));
if (selfClose && startingTag)
{
@@ -444,6 +449,7 @@ struct Writer(_StringType, alias PrettyPrinter = PrettyPrinters.Minimalizer)
}
mixin(ifAnyCompiles(expand!"afterNode"));
}
+
void writeAttribute(StringType name, StringType value)
{
assert(startingTag, "Cannot write attribute outside element start");
@@ -469,6 +475,7 @@ struct Writer(_StringType, alias PrettyPrinter = PrettyPrinters.Minimalizer)
mixin(ifAnyCompiles(expand!"afterNode"));
mixin(ifCompiles("prettyPrinter.increaseLevel"));
}
+
void closeDoctype()
{
assert(insideDTD);
@@ -479,9 +486,10 @@ struct Writer(_StringType, alias PrettyPrinter = PrettyPrinters.Minimalizer)
output ~= "]>";
mixin(ifAnyCompiles(expand!"afterNode"));
}
+
void writeDeclaration(StringType decl, StringType content)
{
- //assert(insideDTD);
+ assert(insideDTD);
mixin(ifAnyCompiles(expand!"beforeNode"));
output ~= "", writer.output);
-
- //static assert(isWriter!(typeof(writer)));
+ assert(writer.output == "",
+ writer.output);
}
-unittest
+@safe unittest
{
import std.array : Appender;
import std.typecons : refCounted;
@@ -526,6 +531,7 @@ unittest
writer.closeElement("elem");
import std.string : lineSplitter;
+
auto splitter = writer.output.lineSplitter;
assert(splitter.front == "", splitter.front);
@@ -546,7 +552,6 @@ unittest
}
import dom = newxml.dom;
-import newxml.domstring;
/++
+ Outputs the entire DOM tree rooted at `node` using the given `writer`.
@@ -554,75 +559,82 @@ import newxml.domstring;
void writeDOM(WriterType)(auto ref WriterType writer, dom.Node node)
{
import std.traits : ReturnType;
+ import std.conv : to;
import newxml.faststrings;
+
alias Document = typeof(node.ownerDocument);
alias Element = ReturnType!(Document.documentElement);
alias StringType = writer.StringType;
switch (node.nodeType) with (dom.NodeType)
{
- case document:
- auto doc = cast(Document)node;
- DOMString xmlVersion = doc.xmlVersion, xmlEncoding = doc.xmlEncoding;
- writer.writeXMLDeclaration(xmlVersion ? xmlVersion.transcodeTo!StringType() : null,
- xmlEncoding ? xmlEncoding.transcodeTo!StringType() : null, doc.xmlStandalone);
- foreach (child; doc.childNodes)
- {
- writer.writeDOM(child);
- }
- break;
- case element:
- auto elem = cast(Element)node;
- writer.startElement(elem.tagName.transcodeTo!StringType);
- if (elem.hasAttributes)
- {
- foreach (attr; elem.attributes)
- {
- writer.writeAttribute(attr.nodeName.transcodeTo!StringType,
- xmlEscape(attr.nodeValue.transcodeTo!StringType));
- }
- }
- foreach (child; elem.childNodes)
+ case document:
+ auto doc = cast(Document) node;
+ string xmlVersion = doc.xmlVersion;
+ string xmlEncoding = doc.xmlEncoding;
+ writer.writeXMLDeclaration(xmlVersion
+ ? xmlVersion.to!StringType() : null,
+ xmlEncoding ? xmlEncoding.to!StringType() : null, doc
+ .xmlStandalone);
+ foreach (child; doc.childNodes)
+ {
+ writer.writeDOM(child);
+ }
+ break;
+ case element:
+ auto elem = cast(Element) node;
+ writer.startElement(elem.tagName.to!StringType);
+ if (elem.hasAttributes)
+ {
+ foreach (attr; elem.attributes)
{
- writer.writeDOM(child);
+ writer.writeAttribute(attr.nodeName.to!StringType,
+ xmlEscape(attr.nodeValue.to!StringType));
}
- writer.closeElement(elem.tagName.transcodeTo!StringType);
- break;
- case text:
- writer.writeText(xmlEscape(node.nodeValue.transcodeTo!StringType));
- break;
- case cdataSection:
- writer.writeCDATA(xmlEscape(node.nodeValue.transcodeTo!StringType));
- break;
- case comment:
- writer.writeComment(node.nodeValue.transcodeTo!StringType);
- break;
- default:
- break;
+ }
+ foreach (child; elem.childNodes)
+ {
+ writer.writeDOM(child);
+ }
+ writer.closeElement(elem.tagName.to!StringType);
+ break;
+ case text:
+ writer.writeText(xmlEscape(node.nodeValue.to!StringType));
+ break;
+ case cdataSection:
+ writer.writeCDATA(xmlEscape(node.nodeValue.to!StringType));
+ break;
+ case comment:
+ writer.writeComment(node.nodeValue.to!StringType);
+ break;
+ default:
+ break;
}
}
-unittest
+@safe unittest
{
import newxml.domimpl;
- Writer!(string, PrettyPrinters.Minimalizer) wrt = Writer!(string)(PrettyPrinters.Minimalizer!string());
+
+ Writer!(string, PrettyPrinters.Minimalizer) wrt = Writer!(string)(
+ PrettyPrinters.Minimalizer!string());
dom.DOMImplementation domimpl = new DOMImplementation;
- dom.Document doc = domimpl.createDocument(null, new DOMString("doc"), null);
- dom.Element e0 = doc.createElement(new DOMString("text"));
+ dom.Document doc = domimpl.createDocument(null, "doc", null);
+ dom.Element e0 = doc.createElement("text");
doc.firstChild.appendChild(e0);
- e0.setAttribute(new DOMString("something"), new DOMString("other thing"));
- e0.appendChild(doc.createTextNode(new DOMString("Some text ")));
- dom.Element e1 = doc.createElement(new DOMString("b"));
- e1.appendChild(doc.createTextNode(new DOMString("with")));
+ e0.setAttribute("something", "other thing");
+ e0.appendChild(doc.createTextNode("Some text "));
+ dom.Element e1 = doc.createElement("b");
+ e1.appendChild(doc.createTextNode("with"));
e0.appendChild(e1);
- e0.appendChild(doc.createTextNode(new DOMString(" markup.")));
+ e0.appendChild(doc.createTextNode(" markup."));
wrt.writeDOM(doc);
assert(wrt.output == "Some text with markup."
- , wrt.output);
+ ~ "something='other thing'>Some text with markup.",
+ wrt.output);
}
import std.typecons : Flag, No, Yes;
@@ -638,8 +650,8 @@ import std.typecons : Flag, No, Yes;
+ has to wait for other nodes to be ready (e.g. if the cursor input is generated
+ programmatically).
+/
-auto writeCursor(Flag!"useFiber" useFiber = No.useFiber, WriterType, CursorType)
- (auto ref WriterType writer, auto ref CursorType cursor)
+auto writeCursor(Flag!"useFiber" useFiber = No.useFiber, WriterType, CursorType)(
+ auto ref WriterType writer, auto ref CursorType cursor)
{
alias StringType = WriterType.StringType;
void inspectOneLevel() @safe
@@ -648,87 +660,87 @@ auto writeCursor(Flag!"useFiber" useFiber = No.useFiber, WriterType, CursorType)
{
switch (cursor.kind) with (XMLKind)
{
- case document:
- StringType version_;
- StringType encoding;
- StringType standalone;
- foreach (attr; cursor.attributes)
- {
- if (attr.name == "version")
- {
- version_ = attr.value;
- }
- else if (attr.name == "encoding")
- {
- encoding = attr.value;
- }
- else if (attr.name == "standalone")
- {
- standalone = attr.value;
- }
- }
- writer.writeXMLDeclaration(version_, encoding, standalone);
- if (cursor.enter)
- {
- inspectOneLevel();
- cursor.exit;
- }
- break;
- case dtdEmpty:
- case dtdStart:
- writer.startDoctype(cursor.wholeContent);
- if (cursor.enter)
+ case document:
+ StringType version_;
+ StringType encoding;
+ StringType standalone;
+ foreach (attr; cursor.attributes)
+ {
+ if (attr.name == "version")
{
- inspectOneLevel();
- cursor.exit;
+ version_ = attr.value;
}
- writer.closeDoctype();
- break;
- case attlistDecl:
- writer.writeDeclaration("ATTLIST", cursor.wholeContent);
- break;
- case elementDecl:
- writer.writeDeclaration("ELEMENT", cursor.wholeContent);
- break;
- case entityDecl:
- writer.writeDeclaration("ENTITY", cursor.wholeContent);
- break;
- case notationDecl:
- writer.writeDeclaration("NOTATION", cursor.wholeContent);
- break;
- case declaration:
- writer.writeDeclaration(cursor.name, cursor.content);
- break;
- case text:
- writer.writeText(cursor.content);
- break;
- case cdata:
- writer.writeCDATA(cursor.content);
- break;
- case comment:
- writer.writeComment(cursor.content);
- break;
- case processingInstruction:
- writer.writeProcessingInstruction(cursor.name, cursor.content);
- break;
- case elementStart:
- case elementEmpty:
- writer.startElement(cursor.name);
- for (auto attrs = cursor.attributes; !attrs.empty; attrs.popFront)
+ else if (attr.name == "encoding")
{
- auto attr = attrs.front;
- writer.writeAttribute(attr.name, attr.value);
+ encoding = attr.value;
}
- if (cursor.enter)
+ else if (attr.name == "standalone")
{
- inspectOneLevel();
- cursor.exit;
+ standalone = attr.value;
}
- writer.closeElement(cursor.name);
- break;
- default:
- break;
- //assert(0);
+ }
+ writer.writeXMLDeclaration(version_, encoding, standalone);
+ if (cursor.enter)
+ {
+ inspectOneLevel();
+ cursor.exit;
+ }
+ break;
+ case dtdEmpty:
+ case dtdStart:
+ writer.startDoctype(cursor.wholeContent);
+ if (cursor.enter)
+ {
+ inspectOneLevel();
+ cursor.exit;
+ }
+ writer.closeDoctype();
+ break;
+ case attlistDecl:
+ writer.writeDeclaration("ATTLIST", cursor.wholeContent);
+ break;
+ case elementDecl:
+ writer.writeDeclaration("ELEMENT", cursor.wholeContent);
+ break;
+ case entityDecl:
+ writer.writeDeclaration("ENTITY", cursor.wholeContent);
+ break;
+ case notationDecl:
+ writer.writeDeclaration("NOTATION", cursor.wholeContent);
+ break;
+ case declaration:
+ writer.writeDeclaration(cursor.name, cursor.content);
+ break;
+ case text:
+ writer.writeText(cursor.content);
+ break;
+ case cdata:
+ writer.writeCDATA(cursor.content);
+ break;
+ case comment:
+ writer.writeComment(cursor.content);
+ break;
+ case processingInstruction:
+ writer.writeProcessingInstruction(cursor.name, cursor.content);
+ break;
+ case elementStart:
+ case elementEmpty:
+ writer.startElement(cursor.name);
+ for (auto attrs = cursor.attributes; !attrs.empty; attrs.popFront)
+ {
+ auto attr = attrs.front;
+ writer.writeAttribute(attr.name, attr.value);
+ }
+ if (cursor.enter)
+ {
+ inspectOneLevel();
+ cursor.exit;
+ }
+ writer.closeElement(cursor.name);
+ break;
+ default:
+ break;
+ //assert(0);
}
}
while (cursor.next);
@@ -736,16 +748,19 @@ auto writeCursor(Flag!"useFiber" useFiber = No.useFiber, WriterType, CursorType)
static if (useFiber)
{
- import core.thread: Fiber;
+ import core.thread : Fiber;
+
auto fiber = new Fiber(&inspectOneLevel);
fiber.call;
return fiber;
}
else
+ {
inspectOneLevel();
+ }
}
-unittest
+@safe unittest
{
import std.array : Appender;
import newxml.parser;
@@ -753,15 +768,10 @@ unittest
import newxml.lexers;
import std.typecons : refCounted;
- string xml =
- "\n" ~
- "\n" ~
- "\t\n" ~
- "\t\n" ~
- "\t\n" ~
- "\t\n" ~
- "]>\n";
+ string xml = "\n" ~ "\n" ~ "\t\n"
+ ~ "\t\n" ~ "\t\n"
+ ~ "\t\n" ~ "]>\n";
auto cursor = xml.lexer.parser.cursor;
cursor.setSource(xml);
@@ -781,10 +791,12 @@ unittest
+ `withValidation`.
+/
struct CheckedWriter(WriterType, CursorType = void)
- if (isWriter!(WriterType) && (is(CursorType == void) ||
- (isCursor!CursorType && is(WriterType.StringType == CursorType.StringType))))
+ if (isWriter!(WriterType) && (is(CursorType == void)
+ || (isCursor!CursorType
+ && is(WriterType.StringType == CursorType.StringType))))
{
import core.thread : Fiber;
+
private Fiber fiber;
private bool startingTag = false;
@@ -797,7 +809,7 @@ struct CheckedWriter(WriterType, CursorType = void)
{
struct Cursor
{
- import newxml.cursor: Attribute;
+ import newxml.cursor : Attribute;
import std.container.array;
alias StringType = WriterType.StringType;
@@ -811,23 +823,28 @@ struct CheckedWriter(WriterType, CursorType = void)
void _setName(StringType name)
{
import newxml.faststrings;
+
_name = name;
auto i = name.indexOf(':');
- colon = (i > 0)
- ? i
- : 0;
+ colon = (i > 0) ? i : 0;
}
+
void _addAttribute(StringType name, StringType value)
{
attrs.insertBack(Attribute!StringType(name, value));
}
+
void _setKind(XMLKind kind)
{
_kind = kind;
initialized = true;
attrs.clear;
}
- void _setContent(StringType content) { _content = content; }
+
+ void _setContent(StringType content)
+ {
+ _content = content;
+ }
auto kind()
{
@@ -838,15 +855,30 @@ struct CheckedWriter(WriterType, CursorType = void)
return _kind;
}
- auto name() { return _name; }
- auto prefix() { return _name[0..colon]; }
- auto content() { return _content; }
- auto attributes() { return attrs[]; }
+
+ auto name()
+ {
+ return _name;
+ }
+
+ auto prefix()
+ {
+ return _name[0 .. colon];
+ }
+
+ auto content()
+ {
+ return _content;
+ }
+
+ auto attributes()
+ {
+ return attrs[];
+ }
+
StringType localName()
{
- return colon
- ? _name[colon+1..$]
- : [];
+ return colon ? _name[colon + 1 .. $] : [];
}
bool enter()
@@ -865,28 +897,39 @@ struct CheckedWriter(WriterType, CursorType = void)
Fiber.yield;
return _kind != XMLKind.elementEnd;
}
+
bool next()
{
Fiber.yield;
return _kind != XMLKind.elementEnd;
}
- void exit() {}
+
+ void exit()
+ {
+ }
+
bool atBeginning()
{
return !initialized || _kind == XMLKind.document;
}
- bool documentEnd() { return false; }
+
+ bool documentEnd()
+ {
+ return false;
+ }
alias InputType = void*;
StringType wholeContent()
{
enforce(false, "Cannot call wholeContent on this type of cursor");
}
+
void setSource(InputType)
{
enforce(false, "Cannot set the source of this type of cursor");
}
}
+
Cursor cursor;
}
else
@@ -912,6 +955,7 @@ struct CheckedWriter(WriterType, CursorType = void)
}
fiber.call;
}
+
void writeXMLDeclaration(StringType version_, StringType encoding, StringType standalone)
{
cursor._setKind(XMLKind.document);
@@ -929,6 +973,7 @@ struct CheckedWriter(WriterType, CursorType = void)
}
fiber.call;
}
+
void writeComment(StringType text)
{
if (startingTag)
@@ -940,6 +985,7 @@ struct CheckedWriter(WriterType, CursorType = void)
cursor._setContent(text);
fiber.call;
}
+
void writeText(StringType text)
{
if (startingTag)
@@ -951,6 +997,7 @@ struct CheckedWriter(WriterType, CursorType = void)
cursor._setContent(text);
fiber.call;
}
+
void writeCDATA(StringType text)
{
if (startingTag)
@@ -962,6 +1009,7 @@ struct CheckedWriter(WriterType, CursorType = void)
cursor._setContent(text);
fiber.call;
}
+
void writeProcessingInstruction(StringType target, StringType data)
{
if (startingTag)
@@ -974,6 +1022,7 @@ struct CheckedWriter(WriterType, CursorType = void)
cursor._setContent(data);
fiber.call;
}
+
void startElement(StringType tag)
{
if (startingTag)
@@ -985,6 +1034,7 @@ struct CheckedWriter(WriterType, CursorType = void)
cursor._setKind(XMLKind.elementStart);
cursor._setName(tag);
}
+
void closeElement(StringType tag)
{
if (startingTag)
@@ -996,6 +1046,7 @@ struct CheckedWriter(WriterType, CursorType = void)
cursor._setName(tag);
fiber.call;
}
+
void writeAttribute(StringType name, StringType value)
{
assert(startingTag);
diff --git a/testsource/test.d b/testsource/test.d
index fc7dc92..98ca991 100644
--- a/testsource/test.d
+++ b/testsource/test.d
@@ -16,7 +16,7 @@ import std.path;
import std.stdio: write, writeln;
import std.utf: UTFException;
-auto indexes =
+auto indexes =
[
"tests/sun/sun-valid.xml",
"tests/sun/sun-error.xml",
@@ -44,7 +44,7 @@ struct Results
{
int[string] totals;
int[string] wrong;
-
+
static Results opCall()
{
Results result;
@@ -52,7 +52,7 @@ struct Results
result.wrong = ["valid": 0, "linted":0, "invalid": 0, "not-wf": 0, "error": 0];
return result;
}
-
+
void opOpAssign(string op)(Results other)
{
static if (op == "+")
@@ -106,7 +106,7 @@ Results handleTestcases(T)(string directory, ref T cursor, int depth)
if (att.name == "PROFILE")
write(" -- ", att.value);
writeln();
-
+
if (cursor.enter())
{
results += handleTestcases(directory, cursor, depth + 1);
@@ -127,7 +127,7 @@ Results handleTestcases(T)(string directory, ref T cursor, int depth)
Results handleTest(T)(string directory, ref T cursor, int depth)
{
auto result = Results();
-
+
string file, kind;
foreach (att; cursor.attributes)
if (att.name == "ENTITIES" && att.value != "none")
@@ -139,9 +139,9 @@ Results handleTest(T)(string directory, ref T cursor, int depth)
kind = att.value;
else if (att.name == "URI")
file = att.value;
-
+
result.totals[kind]++;
-
+
bool passed = true, linted = false, linted_ok = false;
try
{
@@ -193,7 +193,7 @@ Results handleTest(T)(string directory, ref T cursor, int depth)
}
}
}
-
+
return result;
}
@@ -218,22 +218,22 @@ void uselessCallback(CursorError err)
+/
void main()
{
- auto cursor =
+ auto cursor =
chooseLexer!string
.parser
.cursor(); // If an index is not well-formed, just tell us but continue parsing
-
+
auto results = Results();
foreach (i, index; indexes)
{
writeln(i, " -- ", index);
-
+
cursor.setSource(readText(index));
cursor.enter();
-
+
results += handleTestcases(dirName(index), cursor, 1);
}
-
+
printResults(results, 0);
writeln();
}
@@ -249,7 +249,7 @@ bool parseFile(string filename, ref bool lint)
inspectOneLevel(cursor);
cursor.exit();
}
-
+
}
while (cursor.next());
}+/
@@ -265,7 +265,7 @@ bool parseFile(string filename, ref bool lint)
{
auto raw = read(filename);
auto bytes = cast(ubyte[])raw;
-
+
if(bytes.length > 1 && bytes[0] == 0xFF && bytes[1] == 0xFE)
{
auto shorts = cast(ushort[])raw;
@@ -279,28 +279,28 @@ bool parseFile(string filename, ref bool lint)
throw new MyException("AAAAHHHHH");
}
}
-
+
auto something = parseXMLString(text);
//auto cursor = text.lexer.parser.cursor; // lots of tests do not have an xml declaration
//auto dombuilder = domBuilder(cursor, new domimpl.DOMImplementation);
-
+
//cursor.setSource(text);
-
+
//lint = false;
/+foreach (attr; cursor.attributes)
if (attr.name == "version" && attr.value == "1.0")
lint = true;+/
-
+
//dombuilder.build;
//inspectOneLevel(cursor);
-
+
/+if (lint)
{
import std.process, std.stdio, std.array;
import newxml.writer;
-
+
lint = false;
bool result = false;
auto xmllint = executeShell("xmllint --pretty 2 --c14n11 " ~ filename ~ " > linted_input.xml");
@@ -313,12 +313,12 @@ bool parseFile(string filename, ref bool lint)
auto writer = Writer!(string)();
writer.writeDOM(dombuilder.getDocument);
file.write(writer.output);
-
+
//writer.setSink(ltw);
//writer.writeCursor(cursor);
}
-
+
xmllint = executeShell("xmllint --pretty 2 --c14n11 output.xml > linted_output.xml");
if (xmllint.status == 0)
{