Mercurial > hg > OKFNAnnotator
diff annotator_files/lib/range.js @ 4:6979313586cf
new version of annotator.
author | casties |
---|---|
date | Mon, 27 Aug 2012 19:05:38 +0200 |
parents | 6356e78ccf5c |
children |
line wrap: on
line diff
--- a/annotator_files/lib/range.js Thu Apr 05 19:37:27 2012 +0200 +++ b/annotator_files/lib/range.js Mon Aug 27 19:05:38 2012 +0200 @@ -1,4 +1,7 @@ -var Range; +// Generated by CoffeeScript 1.3.3 +var Range, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; Range = {}; @@ -15,6 +18,66 @@ } }; +Range.nodeFromXPath = function(xpath, root) { + var customResolver, evaluateXPath, namespace, node, segment; + if (root == null) { + root = document; + } + evaluateXPath = function(xp, nsResolver) { + if (nsResolver == null) { + nsResolver = null; + } + return document.evaluate('.' + xp, root, nsResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; + }; + if (!$.isXMLDoc(document.documentElement)) { + return evaluateXPath(xpath); + } else { + customResolver = document.createNSResolver(document.ownerDocument === null ? document.documentElement : document.ownerDocument.documentElement); + node = evaluateXPath(xpath, customResolver); + if (!node) { + xpath = ((function() { + var _i, _len, _ref, _results; + _ref = xpath.split('/'); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + segment = _ref[_i]; + if (segment && segment.indexOf(':') === -1) { + _results.push(segment.replace(/^([a-z]+)/, 'xhtml:$1')); + } else { + _results.push(segment); + } + } + return _results; + })()).join('/'); + namespace = document.lookupNamespaceURI(null); + customResolver = function(ns) { + if (ns === 'xhtml') { + return namespace; + } else { + return document.documentElement.getAttribute('xmlns:' + ns); + } + }; + node = evaluateXPath(xpath, customResolver); + } + return node; + } +}; + +Range.RangeError = (function(_super) { + + __extends(RangeError, _super); + + function RangeError(type, message, parent) { + this.type = type; + this.message = message; + this.parent = parent != null ? parent : null; + RangeError.__super__.constructor.call(this, this.message); + } + + return RangeError; + +})(Error); + Range.BrowserRange = (function() { function BrowserRange(obj) { @@ -40,7 +103,9 @@ p = _ref[_i]; node = this[p + 'Container']; offset = this[p + 'Offset']; - if (!((node != null) && (offset != null))) return false; + if (!((node != null) && (offset != null))) { + return false; + } if (node.nodeType === 1) { it = node.childNodes[offset]; node = it || node.childNodes[offset - 1]; @@ -63,7 +128,9 @@ } nr.end = nr.start; } else { - if (r.endOffset < r.end.nodeValue.length) r.end.splitText(r.endOffset); + if (r.endOffset < r.end.nodeValue.length) { + r.end.splitText(r.endOffset); + } nr.end = r.end; } nr.commonAncestor = this.commonAncestorContainer; @@ -98,7 +165,9 @@ nodes = $.grep(this.textNodes(), function(node) { return node.parentNode === bounds || $.contains(bounds, node.parentNode); }); - if (!nodes.length) return null; + if (!nodes.length) { + return null; + } this.start = nodes[0]; this.end = nodes[nodes.length - 1]; startParents = $(this.start).parents(); @@ -188,73 +257,24 @@ this.endOffset = obj.endOffset; } - SerializedRange.prototype._nodeFromXPath = function(xpath) { - var customResolver, evaluateXPath, namespace, node, segment; - evaluateXPath = function(xp, nsResolver) { - if (nsResolver == null) nsResolver = null; - return document.evaluate(xp, document, nsResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; - }; - if (!$.isXMLDoc(document.documentElement)) { - return evaluateXPath(xpath); - } else { - customResolver = document.createNSResolver(document.ownerDocument === null ? document.documentElement : document.ownerDocument.documentElement); - node = evaluateXPath(xpath, customResolver); + SerializedRange.prototype.normalize = function(root) { + var contains, length, node, p, range, tn, _i, _j, _len, _len1, _ref, _ref1; + range = {}; + _ref = ['start', 'end']; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + p = _ref[_i]; + try { + node = Range.nodeFromXPath(this[p], root); + } catch (e) { + throw new Range.RangeError(p, ("Error while finding " + p + " node: " + this[p] + ": ") + e, e); + } if (!node) { - xpath = ((function() { - var _i, _len, _ref, _results; - _ref = xpath.split('/'); - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - segment = _ref[_i]; - if (segment && segment.indexOf(':') === -1) { - _results.push(segment.replace(/^([a-z]+)/, 'xhtml:$1')); - } else { - _results.push(segment); - } - } - return _results; - })()).join('/'); - namespace = document.lookupNamespaceURI(null); - customResolver = function(ns) { - if (ns === 'xhtml') { - return namespace; - } else { - return document.documentElement.getAttribute('xmlns:' + ns); - } - }; - node = evaluateXPath(xpath, customResolver); + throw new Range.RangeError(p, "Couldn't find " + p + " node: " + this[p]); } - return node; - } - }; - - SerializedRange.prototype.normalize = function(root) { - var cacXPath, common, endAncestry, i, length, p, parentXPath, range, startAncestry, tn, _i, _j, _len, _len2, _ref, _ref2, _ref3; - parentXPath = $(root).xpath()[0]; - startAncestry = this.start.split("/"); - endAncestry = this.end.split("/"); - common = []; - range = {}; - for (i = 0, _ref = startAncestry.length; 0 <= _ref ? i < _ref : i > _ref; 0 <= _ref ? i++ : i--) { - if (startAncestry[i] === endAncestry[i]) { - common.push(startAncestry[i]); - } else { - break; - } - } - cacXPath = parentXPath + common.join("/"); - range.commonAncestorContainer = this._nodeFromXPath(cacXPath); - if (!range.commonAncestorContainer) { - console.error(_t("Error deserializing range: can't find XPath '") + cacXPath + _t("'. Is this the right document?")); - return null; - } - _ref2 = ['start', 'end']; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - p = _ref2[_i]; length = 0; - _ref3 = $(this._nodeFromXPath(parentXPath + this[p])).textNodes(); - for (_j = 0, _len2 = _ref3.length; _j < _len2; _j++) { - tn = _ref3[_j]; + _ref1 = $(node).textNodes(); + for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { + tn = _ref1[_j]; if (length + tn.nodeValue.length >= this[p + 'Offset']) { range[p + 'Container'] = tn; range[p + 'Offset'] = this[p + 'Offset'] - length; @@ -263,7 +283,21 @@ length += tn.nodeValue.length; } } + if (!(range[p + 'Offset'] != null)) { + throw new Range.RangeError("" + p + "offset", "Couldn't find offset " + this[p + 'Offset'] + " in element " + this[p]); + } } + contains = !(document.compareDocumentPosition != null) ? function(a, b) { + return a.contains(b); + } : function(a, b) { + return a.compareDocumentPosition(b) & 16; + }; + $(range.startContainer).parents().reverse().each(function() { + if (contains(this, range.endContainer)) { + range.commonAncestorContainer = this; + return false; + } + }); return new Range.BrowserRange(range).normalize(root); };