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);
   };