comparison 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
comparison
equal deleted inserted replaced
3:6356e78ccf5c 4:6979313586cf
1 var Range; 1 // Generated by CoffeeScript 1.3.3
2 var Range,
3 __hasProp = {}.hasOwnProperty,
4 __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; };
2 5
3 Range = {}; 6 Range = {};
4 7
5 Range.sniff = function(r) { 8 Range.sniff = function(r) {
6 if (r.commonAncestorContainer != null) { 9 if (r.commonAncestorContainer != null) {
13 console.error(_t("Could not sniff range type")); 16 console.error(_t("Could not sniff range type"));
14 return false; 17 return false;
15 } 18 }
16 }; 19 };
17 20
21 Range.nodeFromXPath = function(xpath, root) {
22 var customResolver, evaluateXPath, namespace, node, segment;
23 if (root == null) {
24 root = document;
25 }
26 evaluateXPath = function(xp, nsResolver) {
27 if (nsResolver == null) {
28 nsResolver = null;
29 }
30 return document.evaluate('.' + xp, root, nsResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
31 };
32 if (!$.isXMLDoc(document.documentElement)) {
33 return evaluateXPath(xpath);
34 } else {
35 customResolver = document.createNSResolver(document.ownerDocument === null ? document.documentElement : document.ownerDocument.documentElement);
36 node = evaluateXPath(xpath, customResolver);
37 if (!node) {
38 xpath = ((function() {
39 var _i, _len, _ref, _results;
40 _ref = xpath.split('/');
41 _results = [];
42 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
43 segment = _ref[_i];
44 if (segment && segment.indexOf(':') === -1) {
45 _results.push(segment.replace(/^([a-z]+)/, 'xhtml:$1'));
46 } else {
47 _results.push(segment);
48 }
49 }
50 return _results;
51 })()).join('/');
52 namespace = document.lookupNamespaceURI(null);
53 customResolver = function(ns) {
54 if (ns === 'xhtml') {
55 return namespace;
56 } else {
57 return document.documentElement.getAttribute('xmlns:' + ns);
58 }
59 };
60 node = evaluateXPath(xpath, customResolver);
61 }
62 return node;
63 }
64 };
65
66 Range.RangeError = (function(_super) {
67
68 __extends(RangeError, _super);
69
70 function RangeError(type, message, parent) {
71 this.type = type;
72 this.message = message;
73 this.parent = parent != null ? parent : null;
74 RangeError.__super__.constructor.call(this, this.message);
75 }
76
77 return RangeError;
78
79 })(Error);
80
18 Range.BrowserRange = (function() { 81 Range.BrowserRange = (function() {
19 82
20 function BrowserRange(obj) { 83 function BrowserRange(obj) {
21 this.commonAncestorContainer = obj.commonAncestorContainer; 84 this.commonAncestorContainer = obj.commonAncestorContainer;
22 this.startContainer = obj.startContainer; 85 this.startContainer = obj.startContainer;
38 _ref = ['start', 'end']; 101 _ref = ['start', 'end'];
39 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 102 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
40 p = _ref[_i]; 103 p = _ref[_i];
41 node = this[p + 'Container']; 104 node = this[p + 'Container'];
42 offset = this[p + 'Offset']; 105 offset = this[p + 'Offset'];
43 if (!((node != null) && (offset != null))) return false; 106 if (!((node != null) && (offset != null))) {
107 return false;
108 }
44 if (node.nodeType === 1) { 109 if (node.nodeType === 1) {
45 it = node.childNodes[offset]; 110 it = node.childNodes[offset];
46 node = it || node.childNodes[offset - 1]; 111 node = it || node.childNodes[offset - 1];
47 if (node.nodeType === 1 && !node.firstChild) { 112 if (node.nodeType === 1 && !node.firstChild) {
48 it = null; 113 it = null;
61 if ((r.endOffset - r.startOffset) < nr.start.nodeValue.length) { 126 if ((r.endOffset - r.startOffset) < nr.start.nodeValue.length) {
62 nr.start.splitText(r.endOffset - r.startOffset); 127 nr.start.splitText(r.endOffset - r.startOffset);
63 } 128 }
64 nr.end = nr.start; 129 nr.end = nr.start;
65 } else { 130 } else {
66 if (r.endOffset < r.end.nodeValue.length) r.end.splitText(r.endOffset); 131 if (r.endOffset < r.end.nodeValue.length) {
132 r.end.splitText(r.endOffset);
133 }
67 nr.end = r.end; 134 nr.end = r.end;
68 } 135 }
69 nr.commonAncestor = this.commonAncestorContainer; 136 nr.commonAncestor = this.commonAncestorContainer;
70 while (nr.commonAncestor.nodeType !== 1) { 137 while (nr.commonAncestor.nodeType !== 1) {
71 nr.commonAncestor = nr.commonAncestor.parentNode; 138 nr.commonAncestor = nr.commonAncestor.parentNode;
96 NormalizedRange.prototype.limit = function(bounds) { 163 NormalizedRange.prototype.limit = function(bounds) {
97 var nodes, parent, startParents, _i, _len, _ref; 164 var nodes, parent, startParents, _i, _len, _ref;
98 nodes = $.grep(this.textNodes(), function(node) { 165 nodes = $.grep(this.textNodes(), function(node) {
99 return node.parentNode === bounds || $.contains(bounds, node.parentNode); 166 return node.parentNode === bounds || $.contains(bounds, node.parentNode);
100 }); 167 });
101 if (!nodes.length) return null; 168 if (!nodes.length) {
169 return null;
170 }
102 this.start = nodes[0]; 171 this.start = nodes[0];
103 this.end = nodes[nodes.length - 1]; 172 this.end = nodes[nodes.length - 1];
104 startParents = $(this.start).parents(); 173 startParents = $(this.start).parents();
105 _ref = $(this.end).parents(); 174 _ref = $(this.end).parents();
106 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 175 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
186 this.startOffset = obj.startOffset; 255 this.startOffset = obj.startOffset;
187 this.end = obj.end; 256 this.end = obj.end;
188 this.endOffset = obj.endOffset; 257 this.endOffset = obj.endOffset;
189 } 258 }
190 259
191 SerializedRange.prototype._nodeFromXPath = function(xpath) { 260 SerializedRange.prototype.normalize = function(root) {
192 var customResolver, evaluateXPath, namespace, node, segment; 261 var contains, length, node, p, range, tn, _i, _j, _len, _len1, _ref, _ref1;
193 evaluateXPath = function(xp, nsResolver) { 262 range = {};
194 if (nsResolver == null) nsResolver = null; 263 _ref = ['start', 'end'];
195 return document.evaluate(xp, document, nsResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; 264 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
196 }; 265 p = _ref[_i];
197 if (!$.isXMLDoc(document.documentElement)) { 266 try {
198 return evaluateXPath(xpath); 267 node = Range.nodeFromXPath(this[p], root);
199 } else { 268 } catch (e) {
200 customResolver = document.createNSResolver(document.ownerDocument === null ? document.documentElement : document.ownerDocument.documentElement); 269 throw new Range.RangeError(p, ("Error while finding " + p + " node: " + this[p] + ": ") + e, e);
201 node = evaluateXPath(xpath, customResolver); 270 }
202 if (!node) { 271 if (!node) {
203 xpath = ((function() { 272 throw new Range.RangeError(p, "Couldn't find " + p + " node: " + this[p]);
204 var _i, _len, _ref, _results; 273 }
205 _ref = xpath.split('/');
206 _results = [];
207 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
208 segment = _ref[_i];
209 if (segment && segment.indexOf(':') === -1) {
210 _results.push(segment.replace(/^([a-z]+)/, 'xhtml:$1'));
211 } else {
212 _results.push(segment);
213 }
214 }
215 return _results;
216 })()).join('/');
217 namespace = document.lookupNamespaceURI(null);
218 customResolver = function(ns) {
219 if (ns === 'xhtml') {
220 return namespace;
221 } else {
222 return document.documentElement.getAttribute('xmlns:' + ns);
223 }
224 };
225 node = evaluateXPath(xpath, customResolver);
226 }
227 return node;
228 }
229 };
230
231 SerializedRange.prototype.normalize = function(root) {
232 var cacXPath, common, endAncestry, i, length, p, parentXPath, range, startAncestry, tn, _i, _j, _len, _len2, _ref, _ref2, _ref3;
233 parentXPath = $(root).xpath()[0];
234 startAncestry = this.start.split("/");
235 endAncestry = this.end.split("/");
236 common = [];
237 range = {};
238 for (i = 0, _ref = startAncestry.length; 0 <= _ref ? i < _ref : i > _ref; 0 <= _ref ? i++ : i--) {
239 if (startAncestry[i] === endAncestry[i]) {
240 common.push(startAncestry[i]);
241 } else {
242 break;
243 }
244 }
245 cacXPath = parentXPath + common.join("/");
246 range.commonAncestorContainer = this._nodeFromXPath(cacXPath);
247 if (!range.commonAncestorContainer) {
248 console.error(_t("Error deserializing range: can't find XPath '") + cacXPath + _t("'. Is this the right document?"));
249 return null;
250 }
251 _ref2 = ['start', 'end'];
252 for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
253 p = _ref2[_i];
254 length = 0; 274 length = 0;
255 _ref3 = $(this._nodeFromXPath(parentXPath + this[p])).textNodes(); 275 _ref1 = $(node).textNodes();
256 for (_j = 0, _len2 = _ref3.length; _j < _len2; _j++) { 276 for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
257 tn = _ref3[_j]; 277 tn = _ref1[_j];
258 if (length + tn.nodeValue.length >= this[p + 'Offset']) { 278 if (length + tn.nodeValue.length >= this[p + 'Offset']) {
259 range[p + 'Container'] = tn; 279 range[p + 'Container'] = tn;
260 range[p + 'Offset'] = this[p + 'Offset'] - length; 280 range[p + 'Offset'] = this[p + 'Offset'] - length;
261 break; 281 break;
262 } else { 282 } else {
263 length += tn.nodeValue.length; 283 length += tn.nodeValue.length;
264 } 284 }
265 } 285 }
266 } 286 if (!(range[p + 'Offset'] != null)) {
287 throw new Range.RangeError("" + p + "offset", "Couldn't find offset " + this[p + 'Offset'] + " in element " + this[p]);
288 }
289 }
290 contains = !(document.compareDocumentPosition != null) ? function(a, b) {
291 return a.contains(b);
292 } : function(a, b) {
293 return a.compareDocumentPosition(b) & 16;
294 };
295 $(range.startContainer).parents().reverse().each(function() {
296 if (contains(this, range.endContainer)) {
297 range.commonAncestorContainer = this;
298 return false;
299 }
300 });
267 return new Range.BrowserRange(range).normalize(root); 301 return new Range.BrowserRange(range).normalize(root);
268 }; 302 };
269 303
270 SerializedRange.prototype.serialize = function(root, ignoreSelector) { 304 SerializedRange.prototype.serialize = function(root, ignoreSelector) {
271 return this.normalize(root).serialize(root, ignoreSelector); 305 return this.normalize(root).serialize(root, ignoreSelector);