TEST
Simple Implementation of DOM Range in JavaScript
最終更新:
eriax
-
view
制限
- なし。無理矢理 1200 行内に収める。
ソースコード
/*@cc_on@*/
if ('undefined' === typeof Array.prototype.map) {
Array.prototype.map = function (callbackfn) {
var thisArg = arguments[1];
if ('function' !== typeof callbackfn) {
throw new Error; // TypeError
}
var count = this.length;
var result = new Array(count);
var i;
for (i = 0; i < count; i++) {
if (i in this) {
result[i] = callbackfn.call(thisArg, this[i], i, this);
}
}
return result;
};
}
if ('undefined' === typeof Array.map) {
Array.map = function (call, map) {
return function (arg, callbackfn) {
return call.apply(map, arguments);
};
}(
Function.prototype.call,
Array.prototype.map);
}
////////////////////////////////////////////////////////////////////////
function As_DOM_Object(arg) {
if (arguments.length > 0) {
var name;
for (name in arg) {
if (arg.hasOwnProperty(name)) {
this[name] = arg[name];
}
}
}
}
(function () {
this.constructor = As_DOM_Object;
}).call(As_DOM_Object.prototype);
////////////////////////////////////////////////////////////////////////
(function () {
// RangeExceptionCode
this.BAD_BOUNDARYPOINTS_ERR = 1;
this.INVALID_NODE_TYPE_ERR = 2;
}).call(As_DOM_RangeException);
function As_DOM_RangeException(code) {
if (arguments.length > 0) {
if (arg) {
As_DOM_Object.apply(this, arguments);
}
}
}
As_DOM_RangeException.prototype = new As_DOM_Object;
(function () {
this.constructor = As_DOM_RangeException;
this.code = null;
}).call(As_DOM_RangeException.prototype);
////////////////////////////////////////////////////////////////////////
(function () {
// CompareHow
this.START_TO_START = 0;
this.START_TO_END = 1;
this.END_TO_END = 2;
this.END_TO_START = 3;
// NodeType
this.ELEMENT_NODE = 1;
this.ATTRIBUTE_NODE = 2;
this.TEXT_NODE = 3;
this.CDATA_SECTION_NODE = 4;
this.ENTITY_REFERENCE_NODE = 5;
this.ENTITY_NODE = 6;
this.PROCESSING_INSTRUCTION_NODE = 7;
this.COMMENT_NODE = 8;
this.DOCUMENT_NODE = 9;
this.DOCUMENT_TYPE_NODE = 10;
this.DOCUMENT_FRAGMENT_NODE = 11;
this.NOTATION_NODE = 12;
// DocumentPosition
this.DOCUMENT_POSITION_DISCONNECTED = 0x01;
this.DOCUMENT_POSITION_PRECEDING = 0x02;
this.DOCUMENT_POSITION_FOLLOWING = 0x04;
this.DOCUMENT_POSITION_CONTAINS = 0x08;
this.DOCUMENT_POSITION_CONTAINED_BY = 0x10;
this.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20;
}).call(As_DOM_Range);
function As_DOM_Range(arg) {
if (arguments.length > 0) {
if (arg) {
As_DOM_Object.apply(this, arguments);
}
}
}
(function () {
this.constructor = As_DOM_Range;
this.startContainer = null;
this.startOffset = null;
this.endContainer = null;
this.endOffset = null;
this.collapsed = null;
this.commonAncestorContainer = null;
// extension
this.detached = false;
this.ownerDocument = null;
}).call(As_DOM_Range.prototype);
(function () {
var XML_S = /^[\u0009\u000A\u000D\u0020]*$/;
this['[NodeGetTextContent:1]'] = function (node) {
var txt;
if ('undefined' !== typeof (txt = node.textContent)) {
return txt;
}
switch (node.nodeType) {
case As_DOM_Range.ELEMENT_NODE:
/*@{if('undefined'!==typeof(s=node.innerText)||'undefined'!==typeof(s=node.innerHTML)){return s}}@*/
case As_DOM_Range.ATTRIBUTE_NODE:
case As_DOM_Range.ENTITY_REFERENCE_NODE:
case As_DOM_Range.ENTITY_NODE:
case As_DOM_Range.DOCUMENT_FRAGMENT_NODE:
var doc = node.ownerDocument;
var impl = doc.implementation;
/*@{if(impl.hasFeature('MS-DOM','1.0')){if('undefined'!==typeof(s=node.text)){return s}}}@*/
if (impl.hasFeature('Range', '2.0')) {
var range = doc.createRange();
range.selectNodeContents(node);
txt = range.toString();
range.detach();
return txt;
}
return this['[NodeGetTextContent:2]'](node);
case As_DOM_Range.TEXT_NODE:
try {
if (!node.isElementContentWhitespace()) {
return node.data;
}
return '';
}
catch (err) {
if (!XML_S.test(node.data)) {
return node.data;
}
return '';
}
case As_DOM_Range.CDATA_SECTION_NODE:
case As_DOM_Range.PROCESSING_INSTRUCTION_NODE:
case As_DOM_Range.COMMENT_NODE:
return node.nodeValue;
case As_DOM_Range.DOCUMENT_NODE:
case As_DOM_Range.DOCUMENT_TYPE_NODE:
case As_DOM_Range.NOTATION_NODE:
default:
return null;
}
};
this['[NodeGetTextContent:2]'] = function (node) {
switch (node.nodeType) {
case As_DOM_Range.TEXT_NODE:
case As_DOM_Range.CDATA_SECTION_NODE:
return node.nodeValue;
case As_DOM_Range.ELEMENT_NODE:
case As_DOM_Range.ATTRIBUTE_NODE:
case As_DOM_Range.ENTITY_REFERENCE_NODE:
case As_DOM_Range.ENTITY_NODE:
case As_DOM_Range.DOCUMENT_FRAGMENT_NODE:
if (node.hasChildNodes()) {
return Array.prototype.concat.apply([], Array.map(node.childNodes, arguments.callee)).join('');
}
case As_DOM_Range.PROCESSING_INSTRUCTION_NODE:
case As_DOM_Range.COMMENT_NODE:
case As_DOM_Range.DOCUMENT_NODE:
case As_DOM_Range.DOCUMENT_TYPE_NODE:
case As_DOM_Range.NOTATION_NODE:
default:
return '';
}
};
this['[NodeGetContextRoot]'] = function (node) {
var n;
do {
n = node;
} while ((node = node.parentNode));
return n;
};
this['[NodeGetChildIndex]'] = function (node) {
var i = 0;
for (i = 0; node = node.previousSibling; i += 1);
return i;
};
this['[NodeGetMaxOffset]'] = function (node) {
switch (node.nodeType) {
case As_DOM_Range.ELEMENT_NODE:
case As_DOM_Range.ATTRIBUTE_NODE:
case As_DOM_Range.ENTITY_REFERENCE_NODE:
case As_DOM_Range.DOCUMENT_NODE:
case As_DOM_Range.DOCUMENT_FRAGMENT_NODE:
return node.childNodes.length;
case As_DOM_Range.TEXT_NODE:
case As_DOM_Range.CDATA_SECTION_NODE:
case As_DOM_Range.COMMENT_NODE:
return node.length;
case As_DOM_Range.PROCESSING_INSTRUCTION_NODE:
return node.data.length;
case As_DOM_Range.ENTITY_NODE:
case As_DOM_Range.DOCUMENT_TYPE_NODE:
case As_DOM_Range.NOTATION_NODE:
default:
throw new Error;
}
};
this['[NodeContainsOther]'] = function (node, other) {
/*@{if('undefined'!==typeof node.contains&&'undefined'!==typeof other.contains){return node.contains(other)}}@*/
if (node === other) {
return false;
}
try {
return (0 !== (node.compareDocumentPosition(other) & Node.DOCUMENT_POSITION_CONTAINED_BY));
}
catch (err) {
while ((other = other.parentNode)) {
if (node === other) {
break;
}
}
return Boolean(other);
}
};
this['[NodeCompareDocumentPosition:1]'] = function (node, other) {
if (node === other) {
return 0;
}
if (this['[NodeGetContextRoot]'](node) !== this['[NodeGetContextRoot]'](other)) {
return As_DOM_Range.DOCUMENT_POSITION_DISCONNECTED | As_DOM_Range.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC;
}
/*@{if('undefined'!==typeof node.contains&&'undefined'!==typeof other.contains){if(node.contains(other)){return 0x04|0x10}if(other.contains(node)){return 0x02|0x08}}if('undefined'!==typeof node.sourceIndex&&'undefined'!==typeof other.sourceIndex){if(node.sourceIndex<other.sourceIndex){return 0x04}if(node.sourceIndex>other.sourceIndex){return 0x02}}}@*/
return this['[NodeCompareDocumentPosition:2]'](node, other);
};
this['[NodeCompareDocumentPosition:2]'] = function (node, other) {
var path1 = this['[NodeGetSnapshotOffsets]'](node);
var path2 = this['[NodeGetSnapshotOffsets]'](other);
var p1;
var p2;
while (true) {
p1 = path1.pop();
p2 = path2.pop();
if (p1 < p2) {
return As_DOM_Range.DOCUMENT_POSITION_FOLLOWING;
}
if (p1 > p2) {
return As_DOM_Range.DOCUMENT_POSITION_PRECEDING;
}
if (path1.length === 0) {
return As_DOM_Range.DOCUMENT_POSITION_FOLLOWING | As_DOM_Range.DOCUMENT_POSITION_CONTAINED_BY;
}
if (path2.length === 0) {
return As_DOM_Range.DOCUMENT_POSITION_PRECEDING | As_DOM_Range.DOCUMENT_POSITION_CONTAINS;
}
}
};
this['[NodeGetSnapshotOffsets]'] = function (node, from) {
var root = from || this.ownerDocument;
var path = [];
for (; node; node = node.parentNode) {
if (node === root) {
return path;
}
path[path.length] = this['[NodeGetChildIndex]'](node);
}
throw new Error;
};
this['[NodeGetOrderedSnapshotOffsets]'] = function (node, from) {
return this['[NodeGetSnapshotOffsets]'](node, from).reverse();
};
this['[NodeIsValidContainer]'] = function (node) {
switch (node.nodeType) {
case As_DOM_Range.ELEMENT_NODE:
case As_DOM_Range.ATTRIBUTE_NODE:
case As_DOM_Range.TEXT_NODE:
case As_DOM_Range.CDATA_SECTION_NODE:
case As_DOM_Range.ENTITY_REFERENCE_NODE:
case As_DOM_Range.PROCESSING_INSTRUCTION_NODE:
case As_DOM_Range.COMMENT_NODE:
case As_DOM_Range.DOCUMENT_NODE:
case As_DOM_Range.DOCUMENT_FRAGMENT_NODE:
return true;
case As_DOM_Range.ENTITY_NODE:
case As_DOM_Range.DOCUMENT_TYPE_NODE:
case As_DOM_Range.NOTATION_NODE:
return false;
default:
throw new Error; // RangeException.INVALID_NODEYPE_ERR(2)
}
};
this['[NodeIsContextual]'] = function (node) {
switch (node.nodeType) {
case As_DOM_Range.ELEMENT_NODE:
case As_DOM_Range.TEXT_NODE:
case As_DOM_Range.CDATA_SECTION_NODE:
case As_DOM_Range.ENTITY_REFERENCE_NODE:
case As_DOM_Range.PROCESSING_INSTRUCTION_NODE:
case As_DOM_Range.COMMENT_NODE:
case As_DOM_Range.DOCUMENT_TYPE_NODE:
return true;
case As_DOM_Range.ATTRIBUTE_NODE:
case As_DOM_Range.ENTITY_NODE:
case As_DOM_Range.DOCUMENT_NODE:
case As_DOM_Range.DOCUMENT_FRAGMENT_NODE:
case As_DOM_Range.NOTATION_NODE:
return false;
default:
throw new Error; // RangeException.INVALID_NODEYPE_ERR(2)
}
};
this['[OffsetIsValid]'] = function (node, offset) {
return (offset >= 0) && (offset <= this['[NodeGetMaxOffset]'](node));
};
this['[NodeHasValidRoot]'] = function (node) {
switch (this['[NodeGetContextRoot]'](node).nodeType) {
case As_DOM_Range.ATTRIBUTE_NODE:
case As_DOM_Range.DOCUMENT_NODE:
case As_DOM_Range.DOCUMENT_FRAGMENT_NODE:
return true;
case As_DOM_Range.ELEMENT_NODE:
case As_DOM_Range.TEXT_NODE:
case As_DOM_Range.CDATA_SECTION_NODE:
case As_DOM_Range.ENTITY_REFERENCE_NODE:
case As_DOM_Range.ENTITY_NODE:
case As_DOM_Range.PROCESSING_INSTRUCTION_NODE:
case As_DOM_Range.COMMENT_NODE:
case As_DOM_Range.DOCUMENT_TYPE_NODE:
case As_DOM_Range.NOTATION_NODE:
return false;
default:
throw new Error; // RangeException.INVALID_NODE_TYPE_ERR(2)
}
};
this['[ComparePoints]'] = function (compareOffsets, getAncestorOffset) {
return function (container1, offset1, container2, offset2) {
var k;
if (container1 === container2) {
return compareOffsets.call(this, offset1, offset2);
}
try {
k = container1.compareDocumentPosition(container2);
}
catch (err) {
k = this['[NodeCompareDocumentPosition:1]'](container1, container2);
}
if (0 !== (k & As_DOM_Range.DOCUMENT_POSITION_CONTAINED_BY)) {
return compareOffsets.call(this, offset1, getAncestorOffset.call(this, container2, container1)) || -1;
}
if (0 !== (k & As_DOM_Range.DOCUMENT_POSITION_CONTAINS)) {
return compareOffsets.call(this, getAncestorOffset.call(this, container1, container2), offset2) || 1;
}
if (0 !== (k & As_DOM_Range.DOCUMENT_POSITION_FOLLOWING)) {
return -1;
}
if (0 !== (k & As_DOM_Range.DOCUMENT_POSITION_PRECEDING)) {
return 1;
}
throw new Error; // DOMException.WRONG_DOCUMENT_ERR(4)
};
}(
function (n1, n2) {
if (n1 < n2) {
return -1;
}
if (n1 > n2) {
return 1;
}
return 0;
},
function (n1, n2) {
while (n1.parentNode !== n2) {
n1 = n1.parentNode;
}
return this['[NodeGetChildIndex]'](n1);
});
this['[CollapseBoundary]'] = function () {
var node = this.startContainer;
if (this['[NodeGetMaxOffset]'](node) !== this.startOffset) {
this.collapse(true);
}
do {
if (!node || node === this.commonAncestorContainer) {
this.collapse(true);
return;
}
if (node.nextSibling) {
this.setStartAfter(node);
this.collapse(true);
return;
}
}
while ((node = node.parentNode));
};
this['[GetCommonAncestorContainer]'] = function () {
if (this.detached) {
throw new Error; // DOMException.INVALID_STATE_ERR(11)
}
if (this.startContainer === this.endContainer) {
return this.startContainer;
}
if (this['[NodeContainsOther]'](this.startContainer, this.endContainer)) {
return this.startContainer;
}
if (this['[NodeContainsOther]'](this.endContainer, this.startContainer)) {
return this.endContainer;
}
var endContainer = this.endContainer;
var node = this.startContainer;
while (!this['[NodeContainsOther]'](node, endContainer)) {
node = node.parentNode;
}
return node;
};
this['[SetCommonAncestorContainer]'] = function (node) {
this.commonAncestorContainer = node;
};
this['[NodeAppendContents]'] = function (node, arg) {
switch (node.nodeType) {
case As_DOM_Range.ELEMENT_NODE:
case As_DOM_Range.ATTRIBUTE_NODE:
case As_DOM_Range.ENTITY_REFERENCE_NODE:
case As_DOM_Range.DOCUMENT_NODE:
case As_DOM_Range.DOCUMENT_FRAGMENT_NODE:
return node.appendChild(arg);
case As_DOM_Range.TEXT_NODE:
case As_DOM_Range.CDATA_SECTION_NODE:
case As_DOM_Range.PROCESSING_INSTRUCTION_NODE:
case As_DOM_Range.COMMENT_NODE:
return this['[NodeReplaceBy]'](node, arg);
case As_DOM_Range.ENTITY_NODE:
case As_DOM_Range.DOCUMENT_TYPE_NODE:
case As_DOM_Range.NOTATION_NODE:
default:
throw new Error; // RangeException.INVALID_NODE_TYPE_ERR(2)
}
};
this['[NodeReplaceBy]'] = function (node, newNode) {
/*@{if('undefined'!==typeof node.replaceNode){return node.replaceNode(newNode)}}@*/
var n;
if ((n = node.parentNode)) {
return n.replaceChild(newNode, node);
}
if ((n = newNode.parentNode)) {
n.removeChild(newNode);
}
return node;
};
this.setStart = function (refNode, offset) {
if (this.detached) {
throw new Error; // DOMException.INVALID_STATE_ERR(11)
}
if (!this['[NodeIsValidContainer]'](refNode)) {
throw new Error; // RangeException.INVALID_NODE_TYPE_ERR(2)
}
if (!this['[OffsetIsValid]'](refNode, offset)) {
throw new Error; // DOMException.INDEX_SIZE_ERR(1)
}
this['[SetStart:1]'](refNode, offset);
};
this['[SetStart:1]'] = function (refNode, offset) {
this['[SetStart:2]'](refNode, offset);
this['[SetStart:3]']();
};
this['[SetStart:2]'] = function (refNode, offset) {
this.startContainer = refNode;
this.startOffset = offset;
};
this['[SetStart:3]'] = function (range) {
if (this.compareBoundaryPoints(As_DOM_Range.END_TO_START, this) >= 0) {
this.collapse(true);
}
else {
this.collapsed = false;
this['[SetCommonAncestorContainer]'](this['[GetCommonAncestorContainer]']());
}
};
this.setEnd = function (refNode, offset) {
if (this.detached) {
throw new Error; // DOMException.INVALID_STATE_ERR(11)
}
if (!this['[NodeIsValidContainer]'](refNode)) {
throw new Error; // RangeException.INVALID_NODE_TYPE_ERR(2)
}
if (!this['[OffsetIsValid]'](refNode, offset)) {
throw new Error; // DOMException.INDEX_SIZE_ERR(1)
}
this['[SetEnd:1]'](refNode, offset);
};
this['[SetEnd:1]'] = function (refNode, offset) {
this['[SetEnd:2]'](refNode, offset);
this['[SetEnd:3]']();
};
this['[SetEnd:2]'] = function (refNode, offset) {
this.endContainer = refNode;
this.endOffset = offset;
};
this['[SetEnd:3]'] = function () {
if (this.compareBoundaryPoints(As_DOM_Range.START_TO_END, this) <= 0) {
this.collapse(false);
}
else {
this.collapsed = false;
this['[SetCommonAncestorContainer]'](this['[GetCommonAncestorContainer]']());
}
};
this.setStartBefore = function (refNode) {
if (this.detached) {
throw new Error; // DOMException.INVALID_STATE_ERR(11)
}
if (!this['[NodeHasValidRoot]'](refNode) || !this['[NodeIsContextual]'](refNode)) {
throw new Error; // RangeException.INVALID_NODE_TYPE_ERR(2)
}
this['[SetStart:1]'](refNode.parentNode, this['[NodeGetChildIndex]'](refNode));
};
this.setStartAfter = function (refNode) {
if (this.detached) {
throw new Error; // DOMException.INVALID_STATE_ERR(11)
}
if (!this['[NodeHasValidRoot]'](refNode) || !this['[NodeIsContextual]'](refNode)) {
throw new Error; // RangeException.INVALID_NODE_TYPE_ERR(2)
}
this['[SetStart:1]'](refNode.parentNode, this['[NodeGetChildIndex]'](refNode) + 1);
};
this.setEndBefore = function (refNode) {
if (this.detached) {
throw new Error; // DOMException.INVALID_STATE_ERR(11)
}
if (!this['[NodeHasValidRoot]'](refNode) || !this['[NodeIsContextual]'](refNode)) {
throw new Error; // RangeException.INVALID_NODE_TYPE_ERR(2)
}
this['[SetEnd:1]'](refNode.parentNode, this['[NodeGetChildIndex]'](refNode));
};
this.setEndAfter = function (refNode) {
if (this.detached) {
throw new Error; // DOMException.INVALID_STATE_ERR(11)
}
if (!this['[NodeHasValidRoot]'](refNode) || !this['[NodeIsContextual]'](refNode)) {
throw new Error; // RangeException.INVALID_NODE_TYPE_ERR(2)
}
this['[SetEnd:1]'](refNode.parentNode, this['[NodeGetChildIndex]'](refNode) + 1);
};
this.collapse = function (toStart) {
this.collapsed = true;
if (toStart) {
this.endContainer = this.startContainer;
this.endOffset = this.startOffset;
}
else {
this.startContainer = this.endContainer;
this.startOffset = this.endOffset;
}
this.commonAncestorContainer = this.startContainer;
};
this.selectNode = function (refNode) {
if (this.detached) {
throw new Error; // DOMException.INVALID_STATE_ERR(11)
}
if (!this['[NodeHasValidRoot]'](refNode) || !this['[NodeIsContextual]'](refNode)) {
throw new Error; // RangeException.INVALID_NODE_TYPE_ERR(2)
}
this['[SetStart:2]'](refNode.parentNode, this['[NodeGetChildIndex]'](refNode));
this['[SetEnd:1]'](refNode.parentNode, this['[NodeGetChildIndex]'](refNode) + 1);
};
this.selectNodeContents = function (refNode) {
if (this.detached) {
throw new Error; // DOMException.INVALID_STATE_ERR(11)
}
if (!this['[NodeHasValidRoot]'](refNode)) {
throw new Error; // RangeException.INVALID_NODE_TYPE_ERR(2)
}
this['[SetStart:2]'](refNode, 0);
this['[SetEnd:1]'](refNode, this['[NodeGetMaxOffset]'](refNode));
};
this.compareBoundaryPoints = function (how, sourceRange) {
switch (how) {
case As_DOM_Range.START_TO_START:
return this['[ComparePoints]'](this.startContainer, this.startOffset, sourceRange.startContainer, sourceRange.startOffset);
case As_DOM_Range.START_TO_END:
return this['[ComparePoints]'](this.endContainer, this.endOffset, sourceRange.startContainer, sourceRange.startOffset);
case As_DOM_Range.END_TO_END:
return this['[ComparePoints]'](this.endContainer, this.endOffset, sourceRange.endContainer, sourceRange.endOffset);
case As_DOM_Range.END_TO_START:
return this['[ComparePoints]'](this.startContainer, this.startOffset, sourceRange.endContainer, sourceRange.endOffset);
default:
throw new Error; // DOMException.NOT_SUPPORTED_ERR(9)
}
};
this.detach = function () {
if (this.detached) {
throw new Error; // DOMException.INVALID_STATE_ERR(11)
}
this.commonAncestorContainer = null;
this.detached = true;
};
this.extractContents = function () {
if (this.detached) {
throw new Error; // DOMException.INVALID_STATE_ERR(11)
}
var df = this['[ExtractContents:1]']();
this['[CollapseBoundary]']();
return df;
};
this['[ExtractContents:1]'] = function () {
return function () {
if (this.commonAncestorContainer === this.startContainer) {
if (this.commonAncestorContainer === this.endContainer) {
return this['[ExtractNodeContents]'](this.commonAncestorContainer, this.startOffset, this.endOffset);
}
var df = this.ownerDocument.createDocumentFragment();
var offsets2 = this['[NodeGetOrderedSnapshotOffsets]'](this.endContainer, this.commonAncestorContainer);
df.appendChild(this['[ExtractNodeContents]'](this.commonAncestorContainer, this.startOffset, offsets2[0]));
processRight.call(this, df, offsets2[0], offsets2); // different from cloneContents
return df;
}
if (this.commonAncestorContainer === this.endContainer) {
var df = this.ownerDocument.createDocumentFragment();
var offsets1 = this['[NodeGetOrderedSnapshotOffsets]'](this.startContainer, this.commonAncestorContainer);
processLeft.call(this, df, offsets1, this.endOffset);
return df;
}
var df = this.ownerDocument.createDocumentFragment();
var offsets1 = this['[NodeGetOrderedSnapshotOffsets]'](this.startContainer, this.commonAncestorContainer);
var offsets2 = this['[NodeGetOrderedSnapshotOffsets]'](this.endContainer, this.commonAncestorContainer);
processLeft.call(this, df, offsets1, offsets2[0]);
processRight.call(this, df, offsets1[0] + 1, offsets2); // different from cloneContents
return df;
};
function processLeft(df, offsets1, endOffset) {
var oldContent = this.commonAncestorContainer.childNodes[offsets1[0]];
var newContent = df.appendChild(oldContent.cloneNode(false));
var offset1Count = offsets1.length;
var offset;
var child;
var i;
for (i = 1; i < offset1Count; i++) {
offset = offsets1[i];
child = oldContent.childNodes[offset];
newContent.appendChild(child.cloneNode(false));
newContent.appendChild(this['[ExtractNodeContents]'](oldContent, offset + 1));
newContent = newContent.firstChild;
oldContent = child;
}
this['[NodeAppendContents]'](newContent, this['[ExtractNodeContents]'](this.startContainer, this.startOffset));
df.appendChild(this['[ExtractNodeContents]'](this.commonAncestorContainer, offsets1[0] + 1, endOffset));
}
function processRight(df, startOffset, offsets2) {
var oldContent = this.commonAncestorContainer.childNodes[startOffset];
var newContent = df.appendChild(oldContent.cloneNode(false));
var offset2Count = offsets2.length;
var offset;
var child;
var i;
for (i = 1; i < offset2Count; i++) {
offset = offsets2[i];
child = oldContent.childNodes[offset];
newContent.appendChild(this['[ExtractNodeContents]'](oldContent, 0, offset));
newContent.appendChild(child.cloneNode(false));
newContent = newContent.lastChild;
oldContent = child;
}
this['[NodeAppendContents]'](newContent, this['[ExtractNodeContents]'](this.endContainer, 0, this.endOffset));
}
}();
this['[ExtractNodeContents]'] = function (node, startOffset, endOffset) {
switch (node.nodeType) {
case As_DOM_Range.ELEMENT_NODE:
case As_DOM_Range.ATTRIBUTE_NODE:
case As_DOM_Range.ENTITY_REFERENCE_NODE:
case As_DOM_Range.DOCUMENT_NODE:
case As_DOM_Range.DOCUMENT_FRAGMENT_NODE:
var childNodes = node.childNodes;
if (isNaN(startOffset)) {
startOffset = 0;
}
if (isNaN(endOffset)) {
endOffset = childNodes.length;
}
var count = endOffset - startOffset;
var type = As_DOM_Range.DOCUMENT_TYPE_NODE;
var df = this.ownerDocument.createDocumentFragment();
var n;
var i;
for (i = 0; i < count; i++) {
n = childNodes[startOffset];
if (n.nodeType === type) {
throw new Error; // DOMException.HIERARCHY_REQUEST_ERR(3)
}
df.appendChild(node.removeChild(n));
}
return df;
case As_DOM_Range.TEXT_NODE:
case As_DOM_Range.CDATA_SECTION_NODE:
case As_DOM_Range.PROCESSING_INSTRUCTION_NODE:
case As_DOM_Range.COMMENT_NODE:
var cnt = this['[CloneNodeContents]'](node, startOffset, endOffset);
this['[DeleteNodeContents]'](node, startOffset, endOffset);
return cnt;
case As_DOM_Range.ENTITY_NODE:
case As_DOM_Range.DOCUMENT_TYPE_NODE:
case As_DOM_Range.NOTATION_NODE:
default:
throw new Error; // RangeException.INVALID_NODE_TYPE_ERR(2)
}
};
this.cloneContents = function () {
if (this.detached) {
throw new Error; // DOMException.INVALID_STATE_ERR(11)
}
var df = this['CloneContents:1']();
return df;
};
this['CloneContents:1'] = function () {
return function () {
if (this.commonAncestorContainer === this.startContainer) {
if (this.commonAncestorContainer === this.endContainer) {
return this['[CloneNodeContents]'](this.commonAncestorContainer, this.startOffset, this.endOffset);
}
var df = this.ownerDocument.createDocumentFragment();
var offsets2 = this['[NodeGetOrderedSnapshotOffsets]'](this.endContainer, this.commonAncestorContainer);
df.appendChild(this['[CloneNodeContents]'](this.commonAncestorContainer, this.startOffset, offsets2[0]));
processRight.call(this, df, offsets2[0], offsets2); // different from extractContents
return df;
}
if (this.commonAncestorContainer === this.endContainer) {
var df = this.ownerDocument.createDocumentFragment();
var offsets1 = this['[NodeGetOrderedSnapshotOffsets]'](this.startContainer, this.commonAncestorContainer);
processLeft.call(this, df, offsets1, this.endOffset);
return df;
}
var df = this.ownerDocument.createDocumentFragment();
var offsets1 = this['[NodeGetOrderedSnapshotOffsets]'](this.startContainer, this.commonAncestorContainer);
var offsets2 = this['[NodeGetOrderedSnapshotOffsets]'](this.endContainer, this.commonAncestorContainer);
processLeft.call(this, df, offsets1, offsets2[0]);
processRight.call(this, df, offsets2[0], offsets2); // different from extractContents
return df;
};
function processLeft(df, offsets1, endOffset) {
var oldContent = this.commonAncestorContainer.childNodes[offsets1[0]];
var newContent = df.appendChild(oldContent.cloneNode(false));
var offset1Count = offsets1.length;
var offset;
var child;
var i;
for (i = 1; i < offset1Count; i++) {
offset = offsets1[i];
child = oldContent.childNodes[offset];
newContent.appendChild(child.cloneNode(false));
newContent.appendChild(this['[CloneNodeContents]'](oldContent, offset + 1));
newContent = newContent.firstChild;
oldContent = child;
}
this['[NodeAppendContents]'](newContent, this['[CloneNodeContents]'](this.startContainer, this.startOffset));
df.appendChild(this['[CloneNodeContents]'](this.commonAncestorContainer, offsets1[0] + 1, endOffset));
}
function processRight(df, startOffset, offsets2) {
var oldContent = this.commonAncestorContainer.childNodes[startOffset];
var newContent = df.appendChild(oldContent.cloneNode(false));
var offset2Count = offsets2.length;
var offset;
var child;
var i;
for (i = 1; i < offset2Count; i++) {
offset = offsets2[i];
child = oldContent.childNodes[offset];
newContent.appendChild(this['[CloneNodeContents]'](oldContent, 0, offset));
newContent.appendChild(child.cloneNode(false));
newContent = newContent.lastChild;
oldContent = child;
}
this['[NodeAppendContents]'](newContent, this['[CloneNodeContents]'](this.endContainer, 0, this.endOffset));
}
}();
this['[CloneNodeContents]'] = function (node, startOffset, endOffset) {
switch (node.nodeType) {
case As_DOM_Range.ELEMENT_NODE:
case As_DOM_Range.ATTRIBUTE_NODE:
case As_DOM_Range.ENTITY_REFERENCE_NODE:
case As_DOM_Range.DOCUMENT_NODE:
case As_DOM_Range.DOCUMENT_FRAGMENT_NODE:
var childNodes = node.childNodes;
if (isNaN(startOffset)) {
startOffset = 0;
}
if (isNaN(endOffset)) {
endOffset = childNodes.length;
}
var count = endOffset;
var type = As_DOM_Range.DOCUMENT_TYPE_NODE;
var df = this.ownerDocument.createDocumentFragment();
var i;
var n;
for (i = startOffset; i < count; i++) {
n = childNodes[i];
if (n.nodeType === type) {
throw new Error; // DOMException.HIERARCHY_REQUEST_ERR(3)
}
df.appendChild(n.cloneNode(true));
}
return df;
case As_DOM_Range.TEXT_NODE:
case As_DOM_Range.CDATA_SECTION_NODE:
case As_DOM_Range.PROCESSING_INSTRUCTION_NODE:
case As_DOM_Range.COMMENT_NODE:
var cnt = node.cloneNode(false);
var txt = cnt.data;
if (isNaN(startOffset)) {
startOffset = 0;
}
if (isNaN(endOffset)) {
endOffset = txt.length;
}
cnt.data = txt.substring(startOffset, endOffset);
return cnt;
case As_DOM_Range.ENTITY_NODE:
case As_DOM_Range.DOCUMENT_TYPE_NODE:
case As_DOM_Range.NOTATION_NODE:
default:
throw new Error; // RangeException.INVALID_NODE_TYPE_ERR(2)
}
};
this.deleteContents = function () {
if (this.detached) {
throw new Error; // DOMException.INVALID_STATE_ERR(11)
}
this['[DeleteContents:1]']();
this['[CollapseBoundary]']();
};
this['[DeleteContents:1]'] = function () {
return function () {
if (this.commonAncestorContainer === this.startContainer) {
if (this.commonAncestorContainer === this.endContainer) {
this['[DeleteNodeContents]'](this.commonAncestorContainer, this.startOffset, this.endOffset);
return;
}
var offsets2 = this['[NodeGetOrderedSnapshotOffsets]'](this.endContainer, this.commonAncestorContainer);
this['[DeleteNodeContents]'] (this.commonAncestorContainer, this.startOffset, offsets2[0]);
processRight.call(this, offsets2[0], offsets2);
return;
}
if (this.commonAncestorContainer === this.endContainer) {
var offsets1 = this['[NodeGetOrderedSnapshotOffsets]'](this.startContainer, this.commonAncestorContainer);
processLeft.call(this, offsets1, this.endOffset);
return;
}
var offsets1 = this['[NodeGetOrderedSnapshotOffsets]'](this.startContainer, this.commonAncestorContainer);
var offsets2 = this['[NodeGetOrderedSnapshotOffsets]'](this.endContainer, this.commonAncestorContainer);
processLeft.call(this, offsets1, offsets2[0]);
processRight.call(this, offsets1[0] + 1, offsets2);
return;
};
function processLeft(offsets1, endOffset) {
var child = this.commonAncestorContainer.childNodes[offsets1[0]];
var offset1Count = offsets1.length;
var offset;
var i;
for (i = 1; i < offset1Count; i++) {
offset = offsets1[i];
this['[DeleteNodeContents]'](child, offset + 1);
child = child.childNodes[offset];
}
this['[DeleteNodeContents]'](this.startContainer, this.startOffset);
this['[DeleteNodeContents]'](this.commonAncestorContainer, offsets1[0] + 1, endOffset);
}
function processRight(startOffset, offsets2) {
var child = this.commonAncestorContainer.childNodes[startOffset];
var offset2Count = offsets2.length;
var offset;
var i;
for (i = 1; i < offset2Count; i++) {
offset = offsets2[i];
this['[DeleteNodeContents]'](child, 0, offset);
child = child.childNodes[offset];
}
this['[DeleteNodeContents]'](this.endContainer, 0, this.endOffset);
}
}();
this['[DeleteNodeContents]'] = function (node, startOffset, endOffset) {
switch (node.nodeType) {
case As_DOM_Range.ELEMENT_NODE:
case As_DOM_Range.ATTRIBUTE_NODE:
case As_DOM_Range.ENTITY_REFERENCE_NODE:
case As_DOM_Range.DOCUMENT_NODE:
case As_DOM_Range.DOCUMENT_FRAGMENT_NODE:
var childNodes = node.childNodes;
if (isNaN(startOffset)) {
startOffset = 0;
}
if (isNaN(endOffset)) {
endOffset = childNodes.length;
}
var count = endOffset - startOffset;
var i;
for (i = 0; i < count; i++) {
node.removeChild(childNodes[startOffset]);
}
return;
case As_DOM_Range.TEXT_NODE:
case As_DOM_Range.CDATA_SECTION_NODE:
case As_DOM_Range.PROCESSING_INSTRUCTION_NODE:
case As_DOM_Range.COMMENT_NODE:
var cnt = node.cloneNode(false);
var txt = cnt.data;
if (isNaN(startOffset)) {
startOffset = 0;
}
if (isNaN(endOffset)) {
endOffset = txt.length;
}
node.data = txt.substring(0, startOffset) + txt.substring(endOffset);
return;
case As_DOM_Range.ENTITY_NODE:
case As_DOM_Range.DOCUMENT_TYPE_NODE:
case As_DOM_Range.NOTATION_NODE:
default:
throw new Error; // RangeException.INVALID_NODE_TYPE_ERR(2)
}
};
this.toString = function () {
if (this.detached) {
throw new Error; // DOMException.INVALID_STATE_ERR(11)
}
var result = this['[ToString:1]']();
return result;
};
this['[ToString:1]'] = function () {
return function () {
if (this.commonAncestorContainer === this.startContainer) {
if (this.commonAncestorContainer === this.endContainer) {
return this['[NodeGetString]'](this.commonAncestorContainer, this.startOffset, this.endOffset);
}
var offsets2 = this['[NodeGetOrderedSnapshotOffsets]'](this.endContainer, this.commonAncestorContainer);
var result = [];
result[result.length] = this['[NodeGetString]'](this.commonAncestorContainer, this.startOffset, offsets2[0]);
processRight.call(this, result, offsets2[0], offsets2);
return result.join('');
}
if (this.commonAncestorContainer === this.endContainer) {
var offsets1 = this['[NodeGetSnapshotOffsets]'](this.startContainer, this.commonAncestorContainer);
var result = [];
processLeft.call(this, result, offsets1, this.endOffset);
return result.join('');
}
var offsets1 = this['[NodeGetSnapshotOffsets]'](this.startContainer, this.commonAncestorContainer);
var offsets2 = this['[NodeGetOrderedSnapshotOffsets]'](this.endContainer, this.commonAncestorContainer);
var result = [];
processLeft.call(this, result, offsets1, offsets2[0]);
processRight.call(this, result, this.startOffset, offsets2);
return result.join('');
};
function processLeft(result, offsets1, endOffset) {
var parent = this.startContainer;
var offset1Count = offsets1.length - 1;
var offset;
var i;
result[result.length] = this['[NodeGetString]'](parent, this.startOffset);
for (i = 0; i < offset1Count; i++) {
offset = offsets1[i];
parent = parent.parentNode;
result[result.length] = this['[NodeGetString]'](parent, offset + 1);
}
result[result.length] = this['[NodeGetString]'](this.commonAncestorContainer, offsets1[offset1Count] + 1, endOffset);
}
function processRight(result, startOffset, offsets2) {
var child = this.commonAncestorContainer.childNodes[offsets2[0]];
var offset2Count = offsets2.length;
var offset;
var i;
for (i = 1; i < offset2Count; i++) {
offset = offsets2[i];
result[result.length] = this['[NodeGetString]'](child, 0, offset);
child = child.childNodes[offset];
}
result[result.length] = this['[NodeGetString]'](this.endContainer, 0, this.endOffset);
}
}();
this['[NodeGetString]'] = function (node, startOffset, endOffset) {
switch (node.nodeType) {
case As_DOM_Range.ELEMENT_NODE:
case As_DOM_Range.ATTRIBUTE_NODE:
case As_DOM_Range.ENTITY_REFERENCE_NODE:
case As_DOM_Range.DOCUMENT_NODE:
case As_DOM_Range.DOCUMENT_FRAGMENT_NODE:
var childNodes = node.childNodes;
if (isNaN(startOffset)) {
startOffset = 0;
}
if (isNaN(endOffset)) {
endOffset = childNodes.length;
}
var count = endOffset;
var type1 = As_DOM_Range.PROCESSING_INSTRUCTION_NODE;
var type2 = As_DOM_Range.COMMENT_NODE;
var txt = [];
var n;
var i;
for (i = startOffset; i < count; i++) {
n = childNodes[i];
switch (node.nodeType) {
case type1:
case type2:
break;
default:
txt[txt.length] = this['[NodeGetTextContent:1]'](n);
}
}
return txt.join('');
case As_DOM_Range.TEXT_NODE:
case As_DOM_Range.CDATA_SECTION_NODE:
case As_DOM_Range.PROCESSING_INSTRUCTION_NODE:
case As_DOM_Range.COMMENT_NODE:
var txt = node.data;
if (isNaN(startOffset)) {
startOffset = 0;
}
if (isNaN(endOffset)) {
endOffset = txt.length;
}
return txt.substring(startOffset, endOffset);
case As_DOM_Range.ENTITY_NODE:
case As_DOM_Range.DOCUMENT_TYPE_NODE:
case As_DOM_Range.NOTATION_NODE:
default:
throw new Error; // RangeException.INVALID_NODE_TYPE_ERR(2)
}
};
this.insertNode = function (newNode) {
if (this.detached) {
throw new Error; // DOMException.INVALID_STATE_ERR(11)
}
switch (newNode.nodeType) {
case As_DOM_Range.ELEMENT_NODE:
case As_DOM_Range.TEXT_NODE:
case As_DOM_Range.CDATA_SECTION_NODE:
case As_DOM_Range.ENTITY_REFERENCE_NODE:
case As_DOM_Range.PROCESSING_INSTRUCTION_NODE:
case As_DOM_Range.COMMENT_NODE:
case As_DOM_Range.DOCUMENT_TYPE_NODE:
case As_DOM_Range.DOCUMENT_FRAGMENT_NODE:
break;
case As_DOM_Range.ATTRIBUTE_NODE:
case As_DOM_Range.ENTITY_NODE:
case As_DOM_Range.DOCUMENT_NODE:
case As_DOM_Range.NOTATION_NODE:
default:
throw new Error; // RangeException.INVALID_NODEYPE_ERR(2)
}
if (newNode.ownerDocument !== this.ownerDocument) {
throw new Error; // DOMException.WRONG_DOCUMENT_ERR(4)
}
if (this['[NodeContainsOther]'](newNode, this.startContainer)) {
throw new Error; // DOMException.HIERARCHY_REQUEST_ERR(3)
}
return this['[InsertNode:1]'](newNode);
};
this['[InsertNode:1]'] = function (newNode) {
var startContainer = this.startContainer;
switch (startContainer.nodeType) {
case As_DOM_Range.ELEMENT_NODE:
case As_DOM_Range.ATTRIBUTE_NODE:
case As_DOM_Range.ENTITY_REFERENCE_NODE:
case As_DOM_Range.ENTITY_NODE:
case As_DOM_Range.DOCUMENT_NODE:
case As_DOM_Range.DOCUMENT_FRAGMENT_NODE:
var target = startContainer.childNodes[this.startOffset]; /*@{ if (! target) target = null; }@*/
var endContainer = this.endContainer;
if (startContainer === endContainer) {
var childNodes = endContainer.childNodes;
var childCount = childNodes.length;
startContainer.insertBefore(newNode, target);
this.endOffset += childNodes.length - childCount;
}
else {
startContainer.insertBefore(newNode, target);
}
return;
case As_DOM_Range.TEXT_NODE:
case As_DOM_Range.CDATA_SECTION_NODE:
var startOffset = this.startOffset;
var endContainer = this.endContainer;
var cnt = startContainer.splitText(startOffset);
if (startContainer === endContainer) {
this.endContainer = cnt;
this.endOffset -= startOffset;
}
cnt.parentNode.insertBefore(newNode, cnt);
return;
case As_DOM_Range.PROCESSING_INSTRUCTION_NODE:
case As_DOM_Range.COMMENT_NODE:
case As_DOM_Range.DOCUMENT_TYPE_NODE:
case As_DOM_Range.NOTATION_NODE:
default:
throw new Error; // RangeException.HIERARCHY_REQUEST_ERR(3)
}
};
this.surroundContents = function (newParent) {
if (this.detached) {
throw new Error; // DOMException.INVALID_STATE_ERR(11)
}
switch (newParent.nodeType) {
case As_DOM_Range.ELEMENT_NODE:
case As_DOM_Range.TEXT_NODE:
case As_DOM_Range.CDATA_SECTION_NODE:
case As_DOM_Range.ENTITY_REFERENCE_NODE:
case As_DOM_Range.PROCESSING_INSTRUCTION_NODE:
case As_DOM_Range.COMMENT_NODE:
break;
case As_DOM_Range.ATTRIBUTE_NODE:
case As_DOM_Range.ENTITY_NODE:
case As_DOM_Range.DOCUMENT_TYPE_NODE:
case As_DOM_Range.DOCUMENT_NODE:
case As_DOM_Range.DOCUMENT_FRAGMENT_NODE:
case As_DOM_Range.NOTATION_NODE:
default:
throw new Error; // RangeException.INVALID_NODEYPE_ERR(2)
}
if (newParent.ownerDocument !== this.ownerDocument) {
throw new Error; // DOMException.WRONG_DOCUMENT_ERR(4)
}
if (this['[NodeContainsOther]'](newParent, this.startContainer)) {
throw new Error; // DOMException.HIERARCHY_REQUEST_ERR(3)
}
return this['[SurroundContents:1]'](newParent);
};
this['[SurroundContents:1]'] = function (newParent) {
if (this['[NodeContainsOther]'](newParent, this.endContainer)) {
this.endContainer = newParent;
this.endOffset = 0;
}
while (newParent.hasChildNodes()) {
newParent.removeChild(newParent.lastChild);
}
//
var df = this.extractContents();
this.insertNode(newParent);
newParent.appendChild(df);
this.selectNode(newParent);
};
this.cloneRange = function () {
if (this.detached) {
throw new Error; // DOMException.INVALID_STATE_ERR(11)
}
//
var range = new this.constructor(null);
As_DOM_Object.call(range, this);
return range;
};
}).call(As_DOM_Range.prototype);
////////////////////////////////////////////////////////////////////////
var as_DOM_DocumentRange_createRange = function (doc) {
return new As_DOM_Range({
startContainer: doc,
startOffset: 0,
endContainer: doc,
endOffset: 0,
collapsed: true,
commonAncestorContainer: doc,
ownerDocument: doc,
detached: false
});
};
- 初出 2011-08-25/26/27