envjs19 0.3.8.20101029121421
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.jslintrbrc +30 -0
- data/.project +17 -0
- data/CHANGELOG.rdoc +57 -0
- data/DTD/xhtml-lat1.ent +196 -0
- data/DTD/xhtml-special.ent +80 -0
- data/DTD/xhtml-symbol.ent +237 -0
- data/DTD/xhtml.soc +14 -0
- data/DTD/xhtml1-frameset.dtd +1235 -0
- data/DTD/xhtml1-strict.dtd +978 -0
- data/DTD/xhtml1-transitional.dtd +1201 -0
- data/DTD/xhtml1.dcl +192 -0
- data/Makefile +7 -0
- data/Manifest.txt +280 -0
- data/README.rdoc +65 -0
- data/Rakefile +196 -0
- data/Wakefile +11 -0
- data/bin/envjsrb +257 -0
- data/build.properties +9 -0
- data/build.xml +247 -0
- data/gm/jquery.js +6002 -0
- data/gm/mainx.js +2648 -0
- data/gm/sensx.js +135 -0
- data/gm/t.js +6 -0
- data/gm/x.html +76 -0
- data/htmlparser/BrowserTreeBuilder.java +456 -0
- data/htmlparser/README +34 -0
- data/htmlparser/build.sh +38 -0
- data/jsl/jsl +0 -0
- data/jsl/jsl.default.conf +129 -0
- data/jsl/jsl.exe +0 -0
- data/lib/envjs.rb +35 -0
- data/lib/envjs/event_loop.js +206 -0
- data/lib/envjs/net.rb +3 -0
- data/lib/envjs/net/cgi.rb +94 -0
- data/lib/envjs/net/file.rb +69 -0
- data/lib/envjs/options.rb +11 -0
- data/lib/envjs/runtime.rb +346 -0
- data/lib/envjs/tempfile.rb +24 -0
- data/licenses/GPL-LICENSE.txt +278 -0
- data/licenses/MIT-LICENSE.txt +20 -0
- data/src/base64.js +80 -0
- data/src/build.js +6 -0
- data/src/cruft/bad.html +24 -0
- data/src/cruft/dom.js +606 -0
- data/src/cruft/element.js +297 -0
- data/src/cruft/good.html +30 -0
- data/src/cruft/good.js +32 -0
- data/src/cruft/internal.js +81 -0
- data/src/cruft/parser.js +458 -0
- data/src/css/properties.js +293 -0
- data/src/css/rule.js +22 -0
- data/src/css/sizzle.js +717 -0
- data/src/css/stylesheet.js +52 -0
- data/src/dom/attr.js +55 -0
- data/src/dom/cdatasection.js +31 -0
- data/src/dom/characterdata.js +119 -0
- data/src/dom/comment.js +30 -0
- data/src/dom/doctype.js +9 -0
- data/src/dom/document.js +1023 -0
- data/src/dom/dom.js +134 -0
- data/src/dom/element.js +217 -0
- data/src/dom/entities.js +273 -0
- data/src/dom/exception.js +28 -0
- data/src/dom/fragment.js +37 -0
- data/src/dom/implementation.js +140 -0
- data/src/dom/instruction.js +51 -0
- data/src/dom/namednodemap.js +374 -0
- data/src/dom/namespace.js +50 -0
- data/src/dom/node.js +618 -0
- data/src/dom/nodelist.js +195 -0
- data/src/dom/parser.js +1207 -0
- data/src/dom/text.js +73 -0
- data/src/event/event.js +47 -0
- data/src/event/mouseevent.js +4 -0
- data/src/event/uievent.js +8 -0
- data/src/html/a.js +110 -0
- data/src/html/anchor.js +80 -0
- data/src/html/area.js +57 -0
- data/src/html/base.js +26 -0
- data/src/html/blockquote-q.js +19 -0
- data/src/html/body.js +19 -0
- data/src/html/button.js +21 -0
- data/src/html/canvas.js +14 -0
- data/src/html/col-colgroup.js +49 -0
- data/src/html/collection.js +72 -0
- data/src/html/cookie.js +153 -0
- data/src/html/del-ins.js +25 -0
- data/src/html/div.js +28 -0
- data/src/html/document.js +364 -0
- data/src/html/element.js +382 -0
- data/src/html/fieldset.js +19 -0
- data/src/html/form.js +484 -0
- data/src/html/frame.js +89 -0
- data/src/html/frameset.js +25 -0
- data/src/html/head.js +44 -0
- data/src/html/html.js +0 -0
- data/src/html/htmlparser.js +340 -0
- data/src/html/iframe.js +26 -0
- data/src/html/image.js +0 -0
- data/src/html/img.js +62 -0
- data/src/html/input-elements.js +307 -0
- data/src/html/input.js +65 -0
- data/src/html/label.js +26 -0
- data/src/html/legend.js +19 -0
- data/src/html/link.js +82 -0
- data/src/html/map.js +22 -0
- data/src/html/meta.js +37 -0
- data/src/html/object.js +89 -0
- data/src/html/optgroup.js +25 -0
- data/src/html/option.js +103 -0
- data/src/html/param.js +38 -0
- data/src/html/script.js +122 -0
- data/src/html/select.js +132 -0
- data/src/html/style.js +31 -0
- data/src/html/table.js +199 -0
- data/src/html/tbody-thead-tfoot.js +92 -0
- data/src/html/td-th.js +18 -0
- data/src/html/textarea.js +31 -0
- data/src/html/title.js +20 -0
- data/src/html/tr.js +114 -0
- data/src/intro.js +141 -0
- data/src/outro.js +70 -0
- data/src/parser/html5.detailed.js +10762 -0
- data/src/parser/html5.min.js +503 -0
- data/src/parser/html5.pretty.js +10815 -0
- data/src/parser/intro.js +42 -0
- data/src/parser/outro.js +9 -0
- data/src/platform/core.js +323 -0
- data/src/platform/johnson.js +484 -0
- data/src/platform/rhino.js +327 -0
- data/src/platform/static/intro.js +41 -0
- data/src/platform/static/outro.js +30 -0
- data/src/profile/aop.js +238 -0
- data/src/profile/profile.js +402 -0
- data/src/serializer/xml.js +21 -0
- data/src/svg/animatedstring.js +25 -0
- data/src/svg/document.js +25 -0
- data/src/svg/element.js +22 -0
- data/src/svg/locatable.js +17 -0
- data/src/svg/rect.js +18 -0
- data/src/svg/rectelement.js +24 -0
- data/src/svg/stylable.js +49 -0
- data/src/svg/svgelement.js +22 -0
- data/src/svg/transformable.js +15 -0
- data/src/window/css.js +15 -0
- data/src/window/dialog.js +16 -0
- data/src/window/document.js +28 -0
- data/src/window/event.js +265 -0
- data/src/window/history.js +62 -0
- data/src/window/location.js +156 -0
- data/src/window/navigator.js +48 -0
- data/src/window/screen.js +53 -0
- data/src/window/timer.js +21 -0
- data/src/window/window.js +284 -0
- data/src/window/xhr.js +135 -0
- data/src/xpath/expression.js +49 -0
- data/src/xpath/implementation.js +2505 -0
- data/src/xpath/result.js +67 -0
- data/src/xpath/util.js +551 -0
- data/src/xpath/xmltoken.js +149 -0
- data/src/xslt/COPYING +34 -0
- data/src/xslt/ajaxslt-0.8.1/AUTHORS +1 -0
- data/src/xslt/ajaxslt-0.8.1/ChangeLog +136 -0
- data/src/xslt/ajaxslt-0.8.1/Makefile +49 -0
- data/src/xslt/ajaxslt-0.8.1/README +102 -0
- data/src/xslt/ajaxslt-0.8.1/TODO +15 -0
- data/src/xslt/ajaxslt-0.8.1/dom.js +566 -0
- data/src/xslt/ajaxslt-0.8.1/dom_unittest.html +24 -0
- data/src/xslt/ajaxslt-0.8.1/dom_unittest.js +131 -0
- data/src/xslt/ajaxslt-0.8.1/simplelog.js +79 -0
- data/src/xslt/ajaxslt-0.8.1/test/xpath.html +18 -0
- data/src/xslt/ajaxslt-0.8.1/test/xpath_script.js +45 -0
- data/src/xslt/ajaxslt-0.8.1/test/xslt.html +58 -0
- data/src/xslt/ajaxslt-0.8.1/test/xslt_script.js +33 -0
- data/src/xslt/ajaxslt-0.8.1/unittestsuite.html +26 -0
- data/src/xslt/ajaxslt-0.8.1/xmltoken.js +149 -0
- data/src/xslt/ajaxslt-0.8.1/xmltoken_unittest.html +18 -0
- data/src/xslt/ajaxslt-0.8.1/xmltoken_unittest.js +811 -0
- data/src/xslt/ajaxslt-0.8.1/xpath_unittest.html +39 -0
- data/src/xslt/ajaxslt-0.8.1/xpath_unittest.js +557 -0
- data/src/xslt/ajaxslt-0.8.1/xpathdebug.js +234 -0
- data/src/xslt/ajaxslt-0.8.1/xslt_unittest.html +138 -0
- data/src/xslt/ajaxslt-0.8.1/xslt_unittest.js +68 -0
- data/src/xslt/implementation.js +625 -0
- data/src/xslt/processor.js +37 -0
- data/src/xslt/util.js +449 -0
- data/test/base64.js +80 -0
- data/test/call-load-test.js +15 -0
- data/test/data.js +45 -0
- data/test/debug.js +53 -0
- data/test/firebug/errorIcon.png +0 -0
- data/test/firebug/firebug.css +209 -0
- data/test/firebug/firebug.html +23 -0
- data/test/firebug/firebug.js +672 -0
- data/test/firebug/firebugx.js +10 -0
- data/test/firebug/infoIcon.png +0 -0
- data/test/firebug/warningIcon.png +0 -0
- data/test/fixtures/html/events.html +171 -0
- data/test/fixtures/html/iframe1.html +46 -0
- data/test/fixtures/html/iframe1a.html +46 -0
- data/test/fixtures/html/iframe2.html +45 -0
- data/test/fixtures/html/iframe3.html +28 -0
- data/test/fixtures/html/iframeN.html +57 -0
- data/test/fixtures/html/malformed.html +181 -0
- data/test/fixtures/html/scope.html +81 -0
- data/test/fixtures/html/trivial.html +19 -0
- data/test/fixtures/html/with_js.html +26 -0
- data/test/fixtures/images/icon-blue.png +0 -0
- data/test/fixtures/js/external_script.js +1 -0
- data/test/fixtures/js/script.js +1 -0
- data/test/fixtures/js/script_error.js +2 -0
- data/test/foo.html +8 -0
- data/test/foo.js +40 -0
- data/test/html/events.html +171 -0
- data/test/html/iframe1.html +46 -0
- data/test/html/iframe1a.html +46 -0
- data/test/html/iframe2.html +45 -0
- data/test/html/iframe3.html +30 -0
- data/test/html/iframeN.html +57 -0
- data/test/html/malformed.html +181 -0
- data/test/html/scope.html +87 -0
- data/test/html/script.js +1 -0
- data/test/html/trivial.html +19 -0
- data/test/html/with_js.html +26 -0
- data/test/index.html +328 -0
- data/test/java-prototype.js +9 -0
- data/test/jquery.js +6002 -0
- data/test/primary-tests.js +26 -0
- data/test/prototype-test.js +13 -0
- data/test/qunit.js +61 -0
- data/test/qunit/qunit/qunit.css +17 -0
- data/test/qunit/qunit/qunit.js +997 -0
- data/test/scope.html +19 -0
- data/test/scope.rb +24 -0
- data/test/smp/dmathieu/index.html +8 -0
- data/test/specs/dist/env.spec.js +1534 -0
- data/test/specs/envjs.spec.css +46 -0
- data/test/specs/parser/html.js +31 -0
- data/test/specs/parser/spec.html +40 -0
- data/test/specs/parser/xml.js +31 -0
- data/test/specs/qunit.bdd.js +210 -0
- data/test/specs/qunit.css +17 -0
- data/test/specs/qunit.js +997 -0
- data/test/specs/template/spec-0.js +31 -0
- data/test/specs/template/spec-1.js +31 -0
- data/test/specs/template/spec.html +40 -0
- data/test/specs/window/css.js +23 -0
- data/test/specs/window/dialog.js +25 -0
- data/test/specs/window/document.js +23 -0
- data/test/specs/window/event.js +25 -0
- data/test/specs/window/history.js +34 -0
- data/test/specs/window/location.js +34 -0
- data/test/specs/window/navigator.js +71 -0
- data/test/specs/window/screen.js +42 -0
- data/test/specs/window/spec.html +48 -0
- data/test/specs/window/timer.js +26 -0
- data/test/specs/window/window.js +53 -0
- data/test/specs/xhr/spec.html +47 -0
- data/test/specs/xhr/xhr.js +31 -0
- data/test/test.js +10 -0
- data/test/unit/dom.js +44 -0
- data/test/unit/elementmembers.js +92 -0
- data/test/unit/events.js +195 -0
- data/test/unit/fixtures/external_script.js +1 -0
- data/test/unit/form.js +40 -0
- data/test/unit/iframe.js +234 -0
- data/test/unit/insertion.js +23 -0
- data/test/unit/multi-window.js +212 -0
- data/test/unit/nu.validator.js +34 -0
- data/test/unit/onload.js +90 -0
- data/test/unit/parser.js +122 -0
- data/test/unit/prototypecompat.js +22 -0
- data/test/unit/proxy.js +6 -0
- data/test/unit/scope.js +209 -0
- data/test/unit/timer.js +115 -0
- data/test/unit/window.js +57 -0
- data/test/x.js +1 -0
- data/test/y.js +1 -0
- metadata +367 -0
@@ -0,0 +1,50 @@
|
|
1
|
+
|
2
|
+
/**
|
3
|
+
* @class DOMNamespace - The Namespace interface represents an namespace in an Element object
|
4
|
+
*
|
5
|
+
* @extends DOMNode
|
6
|
+
* @author Jon van Noort (jon@webarcana.com.au)
|
7
|
+
* @param ownerDocument : DOMDocument - The Document object associated with this node.
|
8
|
+
*/
|
9
|
+
var DOMNamespace = function(ownerDocument) {
|
10
|
+
this.DOMNode = DOMNode;
|
11
|
+
this.DOMNode(ownerDocument);
|
12
|
+
|
13
|
+
this.name = ""; // the name of this attribute
|
14
|
+
|
15
|
+
// If this attribute was explicitly given a value in the original document, this is true; otherwise, it is false.
|
16
|
+
// Note that the implementation is in charge of this attribute, not the user.
|
17
|
+
// If the user changes the value of the attribute (even if it ends up having the same value as the default value)
|
18
|
+
// then the specified flag is automatically flipped to true
|
19
|
+
this.specified = false;
|
20
|
+
};
|
21
|
+
DOMNamespace.prototype = new DOMNode;
|
22
|
+
__extend__(DOMNamespace.prototype, {
|
23
|
+
get value(){
|
24
|
+
// the value of the attribute is returned as a string
|
25
|
+
return this.nodeValue;
|
26
|
+
},
|
27
|
+
set value(value){
|
28
|
+
this.nodeValue = value+'';
|
29
|
+
},
|
30
|
+
get nodeType(){
|
31
|
+
return DOMNode.NAMESPACE_NODE;
|
32
|
+
},
|
33
|
+
get xml(){
|
34
|
+
var ret = "";
|
35
|
+
|
36
|
+
// serialize Namespace Declaration
|
37
|
+
if (this.name != "") {
|
38
|
+
ret += this.name +"=\""+ __escapeXML__(this.nodeValue) +"\"";
|
39
|
+
}
|
40
|
+
else { // handle default namespace
|
41
|
+
ret += "xmlns=\""+ __escapeXML__(this.nodeValue) +"\"";
|
42
|
+
}
|
43
|
+
|
44
|
+
return ret;
|
45
|
+
},
|
46
|
+
toString: function(){
|
47
|
+
return "Namespace " + this.name + "=" + this.value;
|
48
|
+
}
|
49
|
+
});
|
50
|
+
|
data/src/dom/node.js
ADDED
@@ -0,0 +1,618 @@
|
|
1
|
+
$debug("Defining Node");
|
2
|
+
/*
|
3
|
+
* Node - DOM Level 2
|
4
|
+
*/
|
5
|
+
/**
|
6
|
+
* @class DOMNode - The Node interface is the primary datatype for the entire Document Object Model.
|
7
|
+
* It represents a single node in the document tree.
|
8
|
+
* @author Jon van Noort (jon@webarcana.com.au), David Joham (djoham@yahoo.com) and Scott Severtson
|
9
|
+
* @param ownerDocument : DOMDocument - The Document object associated with this node.
|
10
|
+
*/
|
11
|
+
var DOMNode = function(ownerDocument) {
|
12
|
+
if (ownerDocument) {
|
13
|
+
this._id = ownerDocument._genId(); // generate unique internal id
|
14
|
+
}
|
15
|
+
|
16
|
+
this.namespaceURI = ""; // The namespace URI of this node (Level 2)
|
17
|
+
this.prefix = ""; // The namespace prefix of this node (Level 2)
|
18
|
+
this.localName = ""; // The localName of this node (Level 2)
|
19
|
+
|
20
|
+
this.nodeName = ""; // The name of this node
|
21
|
+
this.nodeValue = null; // The value of this node
|
22
|
+
//this.className = ""; // The CSS class name of this node.
|
23
|
+
|
24
|
+
// The parent of this node. All nodes, except Document, DocumentFragment, and Attr may have a parent.
|
25
|
+
// However, if a node has just been created and not yet added to the tree, or if it has been removed from the tree, this is null
|
26
|
+
this.parentNode = null;
|
27
|
+
|
28
|
+
// A NodeList that contains all children of this node. If there are no children, this is a NodeList containing no nodes.
|
29
|
+
// The content of the returned NodeList is "live" in the sense that, for instance, changes to the children of the node object
|
30
|
+
// that it was created from are immediately reflected in the nodes returned by the NodeList accessors;
|
31
|
+
// it is not a static snapshot of the content of the node. This is true for every NodeList, including the ones returned by the getElementsByTagName method.
|
32
|
+
this.childNodes = new DOMNodeList(ownerDocument, this);
|
33
|
+
|
34
|
+
this.firstChild = null; // The first child of this node. If there is no such node, this is null
|
35
|
+
this.lastChild = null; // The last child of this node. If there is no such node, this is null.
|
36
|
+
this.previousSibling = null; // The node immediately preceding this node. If there is no such node, this is null.
|
37
|
+
this.nextSibling = null; // The node immediately following this node. If there is no such node, this is null.
|
38
|
+
|
39
|
+
this.ownerDocument = ownerDocument; // The Document object associated with this node
|
40
|
+
this.attributes = new DOMNamedNodeMap(this.ownerDocument, this);
|
41
|
+
this._namespaces = new DOMNamespaceNodeMap(ownerDocument, this); // The namespaces in scope for this node
|
42
|
+
this._readonly = false;
|
43
|
+
};
|
44
|
+
|
45
|
+
// nodeType constants
|
46
|
+
DOMNode.ELEMENT_NODE = 1;
|
47
|
+
DOMNode.ATTRIBUTE_NODE = 2;
|
48
|
+
DOMNode.TEXT_NODE = 3;
|
49
|
+
DOMNode.CDATA_SECTION_NODE = 4;
|
50
|
+
DOMNode.ENTITY_REFERENCE_NODE = 5;
|
51
|
+
DOMNode.ENTITY_NODE = 6;
|
52
|
+
DOMNode.PROCESSING_INSTRUCTION_NODE = 7;
|
53
|
+
DOMNode.COMMENT_NODE = 8;
|
54
|
+
DOMNode.DOCUMENT_NODE = 9;
|
55
|
+
DOMNode.DOCUMENT_TYPE_NODE = 10;
|
56
|
+
DOMNode.DOCUMENT_FRAGMENT_NODE = 11;
|
57
|
+
DOMNode.NOTATION_NODE = 12;
|
58
|
+
DOMNode.NAMESPACE_NODE = 13;
|
59
|
+
|
60
|
+
__extend__(DOMNode.prototype, {
|
61
|
+
hasAttributes : function() {
|
62
|
+
if (this.attributes.length == 0) {
|
63
|
+
return false;
|
64
|
+
}else{
|
65
|
+
return true;
|
66
|
+
}
|
67
|
+
},
|
68
|
+
insertBefore : function(newChild, refChild) {
|
69
|
+
var prevNode;
|
70
|
+
|
71
|
+
if(newChild==null){
|
72
|
+
return newChild;
|
73
|
+
}
|
74
|
+
if(refChild==null){
|
75
|
+
this.appendChild(newChild);
|
76
|
+
return this.newChild;
|
77
|
+
}
|
78
|
+
|
79
|
+
// test for exceptions
|
80
|
+
if (__ownerDocument__(this).implementation.errorChecking) {
|
81
|
+
// throw Exception if DOMNode is readonly
|
82
|
+
if (this._readonly) {
|
83
|
+
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
|
84
|
+
}
|
85
|
+
|
86
|
+
// throw Exception if newChild was not created by this Document
|
87
|
+
if (__ownerDocument__(this) != __ownerDocument__(newChild)) {
|
88
|
+
throw(new DOMException(DOMException.WRONG_DOCUMENT_ERR));
|
89
|
+
}
|
90
|
+
|
91
|
+
// throw Exception if the node is an ancestor
|
92
|
+
if (__isAncestor__(this, newChild)) {
|
93
|
+
throw(new DOMException(DOMException.HIERARCHY_REQUEST_ERR));
|
94
|
+
}
|
95
|
+
}
|
96
|
+
|
97
|
+
if (refChild) { // if refChild is specified, insert before it
|
98
|
+
// find index of refChild
|
99
|
+
var itemIndex = __findItemIndex__(this.childNodes, refChild._id);
|
100
|
+
// throw Exception if there is no child node with this id
|
101
|
+
if (__ownerDocument__(this).implementation.errorChecking && (itemIndex < 0)) {
|
102
|
+
throw(new DOMException(DOMException.NOT_FOUND_ERR));
|
103
|
+
}
|
104
|
+
|
105
|
+
// if the newChild is already in the tree,
|
106
|
+
var newChildParent = newChild.parentNode;
|
107
|
+
if (newChildParent) {
|
108
|
+
// remove it
|
109
|
+
newChildParent.removeChild(newChild);
|
110
|
+
}
|
111
|
+
|
112
|
+
// insert newChild into childNodes
|
113
|
+
__insertBefore__(this.childNodes, newChild, itemIndex);
|
114
|
+
|
115
|
+
// do node pointer surgery
|
116
|
+
prevNode = refChild.previousSibling;
|
117
|
+
|
118
|
+
// handle DocumentFragment
|
119
|
+
if (newChild.nodeType == DOMNode.DOCUMENT_FRAGMENT_NODE) {
|
120
|
+
if (newChild.childNodes.length > 0) {
|
121
|
+
// set the parentNode of DocumentFragment's children
|
122
|
+
for (var ind = 0; ind < newChild.childNodes.length; ind++) {
|
123
|
+
newChild.childNodes[ind].parentNode = this;
|
124
|
+
}
|
125
|
+
|
126
|
+
// link refChild to last child of DocumentFragment
|
127
|
+
refChild.previousSibling = newChild.childNodes[newChild.childNodes.length-1];
|
128
|
+
}
|
129
|
+
}else {
|
130
|
+
newChild.parentNode = this; // set the parentNode of the newChild
|
131
|
+
refChild.previousSibling = newChild; // link refChild to newChild
|
132
|
+
}
|
133
|
+
|
134
|
+
}else { // otherwise, append to end
|
135
|
+
prevNode = this.lastChild;
|
136
|
+
this.appendChild(newChild);
|
137
|
+
}
|
138
|
+
|
139
|
+
if (newChild.nodeType == DOMNode.DOCUMENT_FRAGMENT_NODE) {
|
140
|
+
// do node pointer surgery for DocumentFragment
|
141
|
+
if (newChild.childNodes.length > 0) {
|
142
|
+
if (prevNode) {
|
143
|
+
prevNode.nextSibling = newChild.childNodes[0];
|
144
|
+
}else { // this is the first child in the list
|
145
|
+
this.firstChild = newChild.childNodes[0];
|
146
|
+
}
|
147
|
+
|
148
|
+
newChild.childNodes[0].previousSibling = prevNode;
|
149
|
+
newChild.childNodes[newChild.childNodes.length-1].nextSibling = refChild;
|
150
|
+
}
|
151
|
+
}else {
|
152
|
+
// do node pointer surgery for newChild
|
153
|
+
if (prevNode) {
|
154
|
+
prevNode.nextSibling = newChild;
|
155
|
+
}else { // this is the first child in the list
|
156
|
+
this.firstChild = newChild;
|
157
|
+
}
|
158
|
+
|
159
|
+
newChild.previousSibling = prevNode;
|
160
|
+
newChild.nextSibling = refChild;
|
161
|
+
}
|
162
|
+
|
163
|
+
return newChild;
|
164
|
+
},
|
165
|
+
replaceChild : function(newChild, oldChild) {
|
166
|
+
var ret = null;
|
167
|
+
|
168
|
+
if(newChild==null || oldChild==null){
|
169
|
+
return oldChild;
|
170
|
+
}
|
171
|
+
|
172
|
+
// test for exceptions
|
173
|
+
if (__ownerDocument__(this).implementation.errorChecking) {
|
174
|
+
// throw Exception if DOMNode is readonly
|
175
|
+
if (this._readonly) {
|
176
|
+
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
|
177
|
+
}
|
178
|
+
|
179
|
+
// throw Exception if newChild was not created by this Document
|
180
|
+
if (__ownerDocument__(this) != __ownerDocument__(newChild)) {
|
181
|
+
throw(new DOMException(DOMException.WRONG_DOCUMENT_ERR));
|
182
|
+
}
|
183
|
+
|
184
|
+
// throw Exception if the node is an ancestor
|
185
|
+
if (__isAncestor__(this, newChild)) {
|
186
|
+
throw(new DOMException(DOMException.HIERARCHY_REQUEST_ERR));
|
187
|
+
}
|
188
|
+
}
|
189
|
+
|
190
|
+
// get index of oldChild
|
191
|
+
var index = __findItemIndex__(this.childNodes, oldChild._id);
|
192
|
+
|
193
|
+
// throw Exception if there is no child node with this id
|
194
|
+
if (__ownerDocument__(this).implementation.errorChecking && (index < 0)) {
|
195
|
+
throw(new DOMException(DOMException.NOT_FOUND_ERR));
|
196
|
+
}
|
197
|
+
|
198
|
+
// if the newChild is already in the tree,
|
199
|
+
var newChildParent = newChild.parentNode;
|
200
|
+
if (newChildParent) {
|
201
|
+
// remove it
|
202
|
+
newChildParent.removeChild(newChild);
|
203
|
+
}
|
204
|
+
|
205
|
+
// add newChild to childNodes
|
206
|
+
ret = __replaceChild__(this.childNodes,newChild, index);
|
207
|
+
|
208
|
+
|
209
|
+
if (newChild.nodeType == DOMNode.DOCUMENT_FRAGMENT_NODE) {
|
210
|
+
// do node pointer surgery for Document Fragment
|
211
|
+
if (newChild.childNodes.length > 0) {
|
212
|
+
for (var ind = 0; ind < newChild.childNodes.length; ind++) {
|
213
|
+
newChild.childNodes[ind].parentNode = this;
|
214
|
+
}
|
215
|
+
|
216
|
+
if (oldChild.previousSibling) {
|
217
|
+
oldChild.previousSibling.nextSibling = newChild.childNodes[0];
|
218
|
+
} else {
|
219
|
+
this.firstChild = newChild.childNodes[0];
|
220
|
+
}
|
221
|
+
|
222
|
+
if (oldChild.nextSibling) {
|
223
|
+
oldChild.nextSibling.previousSibling = newChild;
|
224
|
+
} else {
|
225
|
+
this.lastChild = newChild.childNodes[newChild.childNodes.length-1];
|
226
|
+
}
|
227
|
+
|
228
|
+
newChild.childNodes[0].previousSibling = oldChild.previousSibling;
|
229
|
+
newChild.childNodes[newChild.childNodes.length-1].nextSibling = oldChild.nextSibling;
|
230
|
+
}
|
231
|
+
} else {
|
232
|
+
// do node pointer surgery for newChild
|
233
|
+
newChild.parentNode = this;
|
234
|
+
|
235
|
+
if (oldChild.previousSibling) {
|
236
|
+
oldChild.previousSibling.nextSibling = newChild;
|
237
|
+
}else{
|
238
|
+
this.firstChild = newChild;
|
239
|
+
}
|
240
|
+
if (oldChild.nextSibling) {
|
241
|
+
oldChild.nextSibling.previousSibling = newChild;
|
242
|
+
}else{
|
243
|
+
this.lastChild = newChild;
|
244
|
+
}
|
245
|
+
newChild.previousSibling = oldChild.previousSibling;
|
246
|
+
newChild.nextSibling = oldChild.nextSibling;
|
247
|
+
}
|
248
|
+
|
249
|
+
return ret;
|
250
|
+
},
|
251
|
+
removeChild : function(oldChild) {
|
252
|
+
if(!oldChild){
|
253
|
+
return null;
|
254
|
+
}
|
255
|
+
// throw Exception if DOMNamedNodeMap is readonly
|
256
|
+
if (__ownerDocument__(this).implementation.errorChecking && (this._readonly || oldChild._readonly)) {
|
257
|
+
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
|
258
|
+
}
|
259
|
+
|
260
|
+
// get index of oldChild
|
261
|
+
var itemIndex = __findItemIndex__(this.childNodes, oldChild._id);
|
262
|
+
|
263
|
+
// throw Exception if there is no child node with this id
|
264
|
+
if (__ownerDocument__(this).implementation.errorChecking && (itemIndex < 0)) {
|
265
|
+
throw(new DOMException(DOMException.NOT_FOUND_ERR));
|
266
|
+
}
|
267
|
+
|
268
|
+
// remove oldChild from childNodes
|
269
|
+
__removeChild__(this.childNodes, itemIndex);
|
270
|
+
|
271
|
+
// do node pointer surgery
|
272
|
+
oldChild.parentNode = null;
|
273
|
+
|
274
|
+
if (oldChild.previousSibling) {
|
275
|
+
oldChild.previousSibling.nextSibling = oldChild.nextSibling;
|
276
|
+
}else {
|
277
|
+
this.firstChild = oldChild.nextSibling;
|
278
|
+
}
|
279
|
+
if (oldChild.nextSibling) {
|
280
|
+
oldChild.nextSibling.previousSibling = oldChild.previousSibling;
|
281
|
+
}else {
|
282
|
+
this.lastChild = oldChild.previousSibling;
|
283
|
+
}
|
284
|
+
|
285
|
+
oldChild.previousSibling = null;
|
286
|
+
oldChild.nextSibling = null;
|
287
|
+
|
288
|
+
return oldChild;
|
289
|
+
},
|
290
|
+
appendChild : function(newChild) {
|
291
|
+
if(!newChild){
|
292
|
+
return null;
|
293
|
+
}
|
294
|
+
// test for exceptions
|
295
|
+
if (__ownerDocument__(this).implementation.errorChecking) {
|
296
|
+
// throw Exception if Node is readonly
|
297
|
+
if (this._readonly) {
|
298
|
+
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
|
299
|
+
}
|
300
|
+
|
301
|
+
// throw Exception if arg was not created by this Document
|
302
|
+
if (__ownerDocument__(this) != __ownerDocument__(this)) {
|
303
|
+
throw(new DOMException(DOMException.WRONG_DOCUMENT_ERR));
|
304
|
+
}
|
305
|
+
|
306
|
+
// throw Exception if the node is an ancestor
|
307
|
+
if (__isAncestor__(this, newChild)) {
|
308
|
+
throw(new DOMException(DOMException.HIERARCHY_REQUEST_ERR));
|
309
|
+
}
|
310
|
+
}
|
311
|
+
|
312
|
+
// if the newChild is already in the tree,
|
313
|
+
var newChildParent = newChild.parentNode;
|
314
|
+
if (newChildParent) {
|
315
|
+
// remove it
|
316
|
+
newChildParent.removeChild(newChild);
|
317
|
+
}
|
318
|
+
|
319
|
+
// add newChild to childNodes
|
320
|
+
__appendChild__(this.childNodes, newChild);
|
321
|
+
|
322
|
+
if (newChild.nodeType == DOMNode.DOCUMENT_FRAGMENT_NODE) {
|
323
|
+
// do node pointer surgery for DocumentFragment
|
324
|
+
if (newChild.childNodes.length > 0) {
|
325
|
+
for (var ind = 0; ind < newChild.childNodes.length; ind++) {
|
326
|
+
newChild.childNodes[ind].parentNode = this;
|
327
|
+
}
|
328
|
+
|
329
|
+
if (this.lastChild) {
|
330
|
+
this.lastChild.nextSibling = newChild.childNodes[0];
|
331
|
+
newChild.childNodes[0].previousSibling = this.lastChild;
|
332
|
+
this.lastChild = newChild.childNodes[newChild.childNodes.length-1];
|
333
|
+
}
|
334
|
+
else {
|
335
|
+
this.lastChild = newChild.childNodes[newChild.childNodes.length-1];
|
336
|
+
this.firstChild = newChild.childNodes[0];
|
337
|
+
}
|
338
|
+
}
|
339
|
+
}
|
340
|
+
else {
|
341
|
+
// do node pointer surgery for newChild
|
342
|
+
newChild.parentNode = this;
|
343
|
+
if (this.lastChild) {
|
344
|
+
this.lastChild.nextSibling = newChild;
|
345
|
+
newChild.previousSibling = this.lastChild;
|
346
|
+
this.lastChild = newChild;
|
347
|
+
}
|
348
|
+
else {
|
349
|
+
this.lastChild = newChild;
|
350
|
+
this.firstChild = newChild;
|
351
|
+
}
|
352
|
+
}
|
353
|
+
return newChild;
|
354
|
+
},
|
355
|
+
hasChildNodes : function() {
|
356
|
+
return (this.childNodes.length > 0);
|
357
|
+
},
|
358
|
+
cloneNode: function(deep) {
|
359
|
+
// use importNode to clone this Node
|
360
|
+
//do not throw any exceptions
|
361
|
+
try {
|
362
|
+
return __ownerDocument__(this).importNode(this, deep);
|
363
|
+
} catch (e) {
|
364
|
+
//there shouldn't be any exceptions, but if there are, return null
|
365
|
+
// may want to warn: $debug("could not clone node: "+e.code);
|
366
|
+
return null;
|
367
|
+
}
|
368
|
+
},
|
369
|
+
normalize : function() {
|
370
|
+
var inode;
|
371
|
+
var nodesToRemove = new DOMNodeList();
|
372
|
+
|
373
|
+
if (this.nodeType == DOMNode.ELEMENT_NODE || this.nodeType == DOMNode.DOCUMENT_NODE) {
|
374
|
+
var adjacentTextNode = null;
|
375
|
+
|
376
|
+
// loop through all childNodes
|
377
|
+
for(var i = 0; i < this.childNodes.length; i++) {
|
378
|
+
inode = this.childNodes.item(i);
|
379
|
+
|
380
|
+
if (inode.nodeType == DOMNode.TEXT_NODE) { // this node is a text node
|
381
|
+
if (inode.length < 1) { // this text node is empty
|
382
|
+
__appendChild__(nodesToRemove, inode); // add this node to the list of nodes to be remove
|
383
|
+
}else {
|
384
|
+
if (adjacentTextNode) { // if previous node was also text
|
385
|
+
adjacentTextNode.appendData(inode.data); // merge the data in adjacent text nodes
|
386
|
+
__appendChild__(nodesToRemove, inode); // add this node to the list of nodes to be removed
|
387
|
+
}else {
|
388
|
+
adjacentTextNode = inode; // remember this node for next cycle
|
389
|
+
}
|
390
|
+
}
|
391
|
+
} else {
|
392
|
+
adjacentTextNode = null; // (soon to be) previous node is not a text node
|
393
|
+
inode.normalize(); // normalise non Text childNodes
|
394
|
+
}
|
395
|
+
}
|
396
|
+
|
397
|
+
// remove redundant Text Nodes
|
398
|
+
for(var i = 0; i < nodesToRemove.length; i++) {
|
399
|
+
inode = nodesToRemove.item(i);
|
400
|
+
inode.parentNode.removeChild(inode);
|
401
|
+
}
|
402
|
+
}
|
403
|
+
},
|
404
|
+
isSupported : function(feature, version) {
|
405
|
+
// use Implementation.hasFeature to determin if this feature is supported
|
406
|
+
return __ownerDocument__(this).implementation.hasFeature(feature, version);
|
407
|
+
},
|
408
|
+
getElementsByTagName : function(tagname) {
|
409
|
+
// delegate to _getElementsByTagNameRecursive
|
410
|
+
// recurse childNodes
|
411
|
+
var nodelist = new DOMNodeList(__ownerDocument__(this));
|
412
|
+
for(var i = 0; i < this.childNodes.length; i++) {
|
413
|
+
nodeList = __getElementsByTagNameRecursive__(this.childNodes.item(i), tagname, nodelist);
|
414
|
+
}
|
415
|
+
return nodelist;
|
416
|
+
},
|
417
|
+
getElementsByTagNameNS : function(namespaceURI, localName) {
|
418
|
+
// delegate to _getElementsByTagNameNSRecursive
|
419
|
+
return __getElementsByTagNameNSRecursive__(this, namespaceURI, localName,
|
420
|
+
new DOMNodeList(__ownerDocument__(this)));
|
421
|
+
},
|
422
|
+
importNode : function(importedNode, deep) {
|
423
|
+
|
424
|
+
var importNode;
|
425
|
+
|
426
|
+
// debug("importing node " + importedNode.nodeName + "(" + importedNode.nodeType + ")" + "(?deep = "+deep+")");
|
427
|
+
|
428
|
+
//there is no need to perform namespace checks since everything has already gone through them
|
429
|
+
//in order to have gotten into the DOM in the first place. The following line
|
430
|
+
//turns namespace checking off in ._isValidNamespace
|
431
|
+
__ownerDocument__(this)._performingImportNodeOperation = true;
|
432
|
+
|
433
|
+
if (importedNode.nodeType == DOMNode.ELEMENT_NODE) {
|
434
|
+
if (!__ownerDocument__(this).implementation.namespaceAware) {
|
435
|
+
// create a local Element (with the name of the importedNode)
|
436
|
+
importNode = __ownerDocument__(this).createElement(importedNode.tagName);
|
437
|
+
|
438
|
+
// create attributes matching those of the importedNode
|
439
|
+
for(var i = 0; i < importedNode.attributes.length; i++) {
|
440
|
+
importNode.setAttribute(importedNode.attributes.item(i).name, importedNode.getAttribute(importedNode.attributes.item(i).name));
|
441
|
+
}
|
442
|
+
}else {
|
443
|
+
// create a local Element (with the name & namespaceURI of the importedNode)
|
444
|
+
importNode = __ownerDocument__(this).createElementNS(importedNode.namespaceURI, importedNode.nodeName);
|
445
|
+
|
446
|
+
// create attributes matching those of the importedNode
|
447
|
+
for(var i = 0; i < importedNode.attributes.length; i++) {
|
448
|
+
importNode.setAttributeNS(importedNode.attributes.item(i).namespaceURI,
|
449
|
+
importedNode.attributes.item(i).name, importedNode.getAttribute(importedNode.attributes.item(i).name));
|
450
|
+
}
|
451
|
+
|
452
|
+
// create namespace definitions matching those of the importedNode
|
453
|
+
for(var i = 0; i < importedNode._namespaces.length; i++) {
|
454
|
+
importNode._namespaces[i] = __ownerDocument__(this).createNamespace(importedNode._namespaces.item(i).name);
|
455
|
+
importNode._namespaces[i].value = importedNode._namespaces.item(i).value;
|
456
|
+
}
|
457
|
+
importNode._namespaces.length = importedNode._namespaces.length;
|
458
|
+
}
|
459
|
+
} else if (importedNode.nodeType == DOMNode.ATTRIBUTE_NODE) {
|
460
|
+
if (!__ownerDocument__(this).implementation.namespaceAware) {
|
461
|
+
// create a local Attribute (with the name of the importedAttribute)
|
462
|
+
importNode = __ownerDocument__(this).createAttribute(importedNode.name);
|
463
|
+
} else {
|
464
|
+
// create a local Attribute (with the name & namespaceURI of the importedAttribute)
|
465
|
+
importNode = __ownerDocument__(this).createAttributeNS(importedNode.namespaceURI, importedNode.nodeName);
|
466
|
+
|
467
|
+
|
468
|
+
/*
|
469
|
+
// create namespace definitions matching those of the importedAttribute
|
470
|
+
for(var i = 0; i < importedNode._namespaces.length; i++) {
|
471
|
+
importNode._namespaces[i] = __ownerDocument__(this).createNamespace(importedNode._namespaces.item(i).localName);
|
472
|
+
importNode._namespaces[i].value = importedNode._namespaces.item(i).value;
|
473
|
+
}
|
474
|
+
*/
|
475
|
+
|
476
|
+
|
477
|
+
}
|
478
|
+
|
479
|
+
// set the value of the local Attribute to match that of the importedAttribute
|
480
|
+
importNode.value = importedNode.value;
|
481
|
+
|
482
|
+
} else if (importedNode.nodeType == DOMNode.DOCUMENT_FRAGMENT_NODE) {
|
483
|
+
// create a local DocumentFragment
|
484
|
+
importNode = __ownerDocument__(this).createDocumentFragment();
|
485
|
+
} else if (importedNode.nodeType == DOMNode.NAMESPACE_NODE) {
|
486
|
+
// create a local NamespaceNode (with the same name & value as the importedNode)
|
487
|
+
importNode = __ownerDocument__(this).createNamespace(importedNode.name);
|
488
|
+
importNode.value = importedNode.value;
|
489
|
+
} else if (importedNode.nodeType == DOMNode.TEXT_NODE) {
|
490
|
+
// create a local TextNode (with the same data as the importedNode)
|
491
|
+
importNode = __ownerDocument__(this).createTextNode(importedNode.data);
|
492
|
+
} else if (importedNode.nodeType == DOMNode.CDATA_SECTION_NODE) {
|
493
|
+
// create a local CDATANode (with the same data as the importedNode)
|
494
|
+
importNode = __ownerDocument__(this).createCDATASection(importedNode.data);
|
495
|
+
} else if (importedNode.nodeType == DOMNode.PROCESSING_INSTRUCTION_NODE) {
|
496
|
+
// create a local ProcessingInstruction (with the same target & data as the importedNode)
|
497
|
+
importNode = __ownerDocument__(this).createProcessingInstruction(importedNode.target, importedNode.data);
|
498
|
+
} else if (importedNode.nodeType == DOMNode.COMMENT_NODE) {
|
499
|
+
// create a local Comment (with the same data as the importedNode)
|
500
|
+
importNode = __ownerDocument__(this).createComment(importedNode.data);
|
501
|
+
} else { // throw Exception if nodeType is not supported
|
502
|
+
throw(new DOMException(DOMException.NOT_SUPPORTED_ERR));
|
503
|
+
}
|
504
|
+
|
505
|
+
if (deep) { // recurse childNodes
|
506
|
+
for(var i = 0; i < importedNode.childNodes.length; i++) {
|
507
|
+
importNode.appendChild(__ownerDocument__(this).importNode(importedNode.childNodes.item(i), true));
|
508
|
+
}
|
509
|
+
}
|
510
|
+
|
511
|
+
//reset _performingImportNodeOperation
|
512
|
+
__ownerDocument__(this)._performingImportNodeOperation = false;
|
513
|
+
return importNode;
|
514
|
+
|
515
|
+
},
|
516
|
+
contains : function(node){
|
517
|
+
while(node && node != this ){
|
518
|
+
node = node.parentNode;
|
519
|
+
}
|
520
|
+
return !!node;
|
521
|
+
},
|
522
|
+
compareDocumentPosition : function(b){
|
523
|
+
var a = this;
|
524
|
+
var number = (a != b && a.contains(b) && 16) + (a != b && b.contains(a) && 8);
|
525
|
+
//find position of both
|
526
|
+
var all = this.ownerDocument.getElementsByTagName("*");
|
527
|
+
var my_location = 0, node_location = 0;
|
528
|
+
for(var i=0; i < all.length; i++){
|
529
|
+
if(all[i] == a) my_location = i;
|
530
|
+
if(all[i] == b) node_location = i;
|
531
|
+
if(my_location && node_location) break;
|
532
|
+
}
|
533
|
+
number += (my_location < node_location && 4);
|
534
|
+
number += (my_location > node_location && 2);
|
535
|
+
return number;
|
536
|
+
}
|
537
|
+
|
538
|
+
});
|
539
|
+
|
540
|
+
|
541
|
+
|
542
|
+
/**
|
543
|
+
* @method DOMNode._getElementsByTagNameRecursive - implements getElementsByTagName()
|
544
|
+
* @param elem : DOMElement - The element which are checking and then recursing into
|
545
|
+
* @param tagname : string - The name of the tag to match on. The special value "*" matches all tags
|
546
|
+
* @param nodeList : DOMNodeList - The accumulating list of matching nodes
|
547
|
+
*
|
548
|
+
* @return : DOMNodeList
|
549
|
+
*/
|
550
|
+
var __getElementsByTagNameRecursive__ = function (elem, tagname, nodeList) {
|
551
|
+
|
552
|
+
if (elem.nodeType == DOMNode.ELEMENT_NODE || elem.nodeType == DOMNode.DOCUMENT_NODE) {
|
553
|
+
|
554
|
+
if(elem.nodeType !== DOMNode.DOCUMENT_NODE &&
|
555
|
+
((elem.nodeName.toUpperCase() == tagname.toUpperCase()) ||
|
556
|
+
(tagname == "*")) ){
|
557
|
+
__appendChild__(nodeList, elem); // add matching node to nodeList
|
558
|
+
}
|
559
|
+
|
560
|
+
// recurse childNodes
|
561
|
+
for(var i = 0; i < elem.childNodes.length; i++) {
|
562
|
+
nodeList = __getElementsByTagNameRecursive__(elem.childNodes.item(i), tagname, nodeList);
|
563
|
+
}
|
564
|
+
}
|
565
|
+
|
566
|
+
return nodeList;
|
567
|
+
};
|
568
|
+
|
569
|
+
/**
|
570
|
+
* @method DOMNode._getElementsByTagNameNSRecursive - implements getElementsByTagName()
|
571
|
+
*
|
572
|
+
* @param elem : DOMElement - The element which are checking and then recursing into
|
573
|
+
* @param namespaceURI : string - the namespace URI of the required node
|
574
|
+
* @param localName : string - the local name of the required node
|
575
|
+
* @param nodeList : DOMNodeList - The accumulating list of matching nodes
|
576
|
+
*
|
577
|
+
* @return : DOMNodeList
|
578
|
+
*/
|
579
|
+
var __getElementsByTagNameNSRecursive__ = function(elem, namespaceURI, localName, nodeList) {
|
580
|
+
if (elem.nodeType == DOMNode.ELEMENT_NODE || elem.nodeType == DOMNode.DOCUMENT_NODE) {
|
581
|
+
|
582
|
+
if (((elem.namespaceURI == namespaceURI) || (namespaceURI == "*")) && ((elem.localName == localName) || (localName == "*"))) {
|
583
|
+
__appendChild__(nodeList, elem); // add matching node to nodeList
|
584
|
+
}
|
585
|
+
|
586
|
+
// recurse childNodes
|
587
|
+
for(var i = 0; i < elem.childNodes.length; i++) {
|
588
|
+
nodeList = __getElementsByTagNameNSRecursive__(elem.childNodes.item(i), namespaceURI, localName, nodeList);
|
589
|
+
}
|
590
|
+
}
|
591
|
+
|
592
|
+
return nodeList;
|
593
|
+
};
|
594
|
+
|
595
|
+
/**
|
596
|
+
* @method DOMNode._isAncestor - returns true if node is ancestor of target
|
597
|
+
* @param target : DOMNode - The node we are using as context
|
598
|
+
* @param node : DOMNode - The candidate ancestor node
|
599
|
+
* @return : boolean
|
600
|
+
*/
|
601
|
+
var __isAncestor__ = function(target, node) {
|
602
|
+
// if this node matches, return true,
|
603
|
+
// otherwise recurse up (if there is a parentNode)
|
604
|
+
return ((target == node) || ((target.parentNode) && (__isAncestor__(target.parentNode, node))));
|
605
|
+
};
|
606
|
+
|
607
|
+
var __ownerDocument__ = function(node){
|
608
|
+
return (node.nodeType == DOMNode.DOCUMENT_NODE)?node:node.ownerDocument;
|
609
|
+
};
|
610
|
+
|
611
|
+
// $w.Node = DOMNode;
|
612
|
+
|
613
|
+
// Local Variables:
|
614
|
+
// espresso-indent-level:4
|
615
|
+
// c-basic-offset:4
|
616
|
+
// tab-width:4
|
617
|
+
// mode:auto-revert
|
618
|
+
// End:
|