rangy-rails 1.3alpha.804.0 → 1.3.1.pre.dev

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.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rangy-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3alpha.804.0
4
+ version: 1.3.1.pre.dev
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mario Zigliotto
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-04 00:00:00.000000000 Z
11
+ date: 2015-10-05 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |-
14
14
  A simple Rails asset pipeline wrapper
@@ -31,7 +31,6 @@ files:
31
31
  - vendor/assets/javascripts/rangy-core.js
32
32
  - vendor/assets/javascripts/rangy-cssclassapplier.js
33
33
  - vendor/assets/javascripts/rangy-highlighter.js
34
- - vendor/assets/javascripts/rangy-position.js
35
34
  - vendor/assets/javascripts/rangy-selectionsaverestore.js
36
35
  - vendor/assets/javascripts/rangy-serializer.js
37
36
  - vendor/assets/javascripts/rangy-textrange.js
@@ -54,9 +53,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
54
53
  version: 1.3.1
55
54
  requirements: []
56
55
  rubyforge_project:
57
- rubygems_version: 2.2.2
56
+ rubygems_version: 2.4.8
58
57
  signing_key:
59
58
  specification_version: 4
60
59
  summary: Rails asset pipeline wrapper for the Rangy library
61
60
  test_files: []
62
- has_rdoc:
@@ -1,524 +0,0 @@
1
- rangy.createModule("Position", ["WrappedSelection"], function(api, module) {
2
- //var log = log4javascript.getLogger("rangy.position");
3
-
4
- var NUMBER = "number", UNDEF = "undefined";
5
- var WrappedRange = api.WrappedRange;
6
- var WrappedTextRange = api.WrappedTextRange;
7
- var dom = api.dom, util = api.util, DomPosition = dom.DomPosition;
8
-
9
- // Feature detection
10
-
11
- //var caretPositionFromPointSupported = (typeof document.caretPositionFromPoint != UNDEF);
12
-
13
- // Since Rangy can deal with multiple documents which could be in different modes, we have to do the checks every
14
- // time, unless we cache a getScrollPosition function in each document. This would necessarily pollute the
15
- // document's global namespace, which I'm choosing to view as a greater evil than a slight performance hit.
16
- function getScrollPosition(win) {
17
- var x = 0, y = 0;
18
- if (typeof win.pageXOffset == NUMBER && typeof win.pageYOffset == NUMBER) {
19
- x = win.pageXOffset;
20
- y = win.pageYOffset;
21
- } else {
22
- var doc = win.document;
23
- var docEl = doc.documentElement;
24
- var compatMode = doc.compatMode;
25
- var scrollEl = (typeof compatMode == "string" && compatMode.indexOf("CSS") >= 0 && docEl)
26
- ? docEl : dom.getBody(doc);
27
-
28
- if (scrollEl && typeof scrollEl.scrollLeft == NUMBER && typeof scrollEl.scrollTop == NUMBER) {
29
- try {
30
- x = scrollEl.scrollLeft;
31
- y = scrollEl.scrollTop;
32
- } catch (ex) {}
33
- }
34
- }
35
- return { x: x, y: y };
36
- }
37
-
38
- function getAncestorElement(node, tagName) {
39
- tagName = tagName.toLowerCase();
40
- while (node) {
41
- if (node.nodeType == 1 && node.tagName.toLowerCase() == tagName) {
42
- return node;
43
- }
44
- node = node.parentNode;
45
- }
46
- return null;
47
- }
48
-
49
- function Rect(top, right, bottom, left) {
50
- this.top = top;
51
- this.right = right;
52
- this.bottom = bottom;
53
- this.left = left;
54
- this.width = right - left;
55
- this.height = bottom - top;
56
- }
57
-
58
- function createRelativeRect(rect, dx, dy) {
59
- return new Rect(rect.top + dy, rect.right + dx, rect.bottom + dy, rect.left + dx);
60
- }
61
-
62
- function adjustClientRect(rect, doc) {
63
- // Older IEs have an issue with a two pixel margin on the body element
64
- var dx = 0, dy = 0;
65
- var docEl = doc.documentElement, body = dom.getBody(doc);
66
- var container = (docEl.clientWidth === 0 && typeof body.clientTop == NUMBER) ? body : docEl;
67
- var clientLeft = container.clientLeft, clientTop = container.clientTop;
68
- if (clientLeft) {
69
- dx = -clientLeft;
70
- }
71
- if (clientTop) {
72
- dy = -clientTop;
73
- }
74
- return createRelativeRect(rect, dx, dy);
75
- }
76
-
77
- function mergeRects(rects) {
78
- var tops = [], bottoms = [], lefts = [], rights = [];
79
- for (var i = 0, len = rects.length, rect; i < len; ++i) {
80
- rect = rects[i];
81
- if (rect) {
82
- tops.push(rect.top);
83
- bottoms.push(rect.bottom);
84
- lefts.push(rect.left);
85
- rights.push(rect.right);
86
- }
87
- }
88
- return new Rect(
89
- Math.min.apply(Math, tops),
90
- Math.max.apply(Math, rights),
91
- Math.max.apply(Math, bottoms),
92
- Math.min.apply(Math, lefts)
93
- );
94
- }
95
-
96
- function getTextRangePosition(doc, x, y) {
97
- var textRange = dom.getBody(doc).createTextRange();
98
- textRange.moveToPoint(x, y);
99
- var range = new api.WrappedTextRange(textRange);
100
- return new DomPosition(range.startContainer, range.startOffset);
101
- }
102
-
103
- function caretPositionFromPoint(doc, x, y) {
104
- var pos = doc.caretPositionFromPoint(x, y);
105
- return new DomPosition(pos.offsetNode, pos.offset);
106
- }
107
-
108
- function caretRangeFromPoint(doc, x, y) {
109
- var range = doc.caretRangeFromPoint(x, y);
110
- return new DomPosition(range.startContainer, range.startOffset);
111
- }
112
-
113
- function getLastRangeRect(range) {
114
- var rects = (range.nativeRange || range).getClientRects();
115
- return (rects.length > 0) ? rects[rects.length - 1] : null;
116
- }
117
-
118
- function pointIsInOrAboveRect(x, y, rect) {
119
- console.log("pointIsInOrAboveRect", x, y, Math.floor(rect.top), Math.floor(rect.right), Math.floor(rect.bottom), Math.floor(rect.left))
120
- return y < rect.bottom && x >= rect.left && x <= rect.right;
121
- }
122
-
123
- function positionFromPoint(doc, x, y, favourPrecedingPosition) {
124
- var el = doc.elementFromPoint(x, y);
125
-
126
- console.log("elementFromPoint is ", el);
127
-
128
- var range = api.createRange(doc);
129
- range.selectNodeContents(el);
130
- range.collapse(true);
131
-
132
- var node = el.firstChild, offset, rect, textLen;
133
-
134
- if (!node) {
135
- node = el.parentNode;
136
- offset = dom.getNodeIndex(el);
137
- if (!favourPrecedingPosition) {
138
- ++offset;
139
- }
140
- } else {
141
- // Search through the text node children of el
142
- main: while (node) {
143
- console.log(node);
144
- if (node.nodeType == 3) {
145
- // Go through the text node character by character
146
- for (offset = 0, textLen = node.length; offset <= textLen; ++offset) {
147
- range.setEnd(node, offset);
148
- rect = getLastRangeRect(range);
149
- if (rect && pointIsInOrAboveRect(x, y, rect)) {
150
- // We've gone past the point. Now we check which side (left or right) of the character the point is nearer to
151
- if (rect.right - x > x - rect.left) {
152
- --offset;
153
- }
154
- break main;
155
- }
156
- }
157
- } else {
158
- // Handle elements
159
- range.setEndAfter(node);
160
- rect = getLastRangeRect(range);
161
- if (rect && pointIsInOrAboveRect(x, y, rect)) {
162
- offset = dom.getNodeIndex(node);
163
- node = el.parentNode;
164
- if (!favourPrecedingPosition) {
165
- ++offset;
166
- }
167
- break;
168
- }
169
- }
170
-
171
- node = node.nextSibling;
172
- }
173
- if (!node) {
174
- node = el;
175
- offset = el.childNodes.length;
176
- }
177
- }
178
-
179
- return new DomPosition(node, offset);
180
- }
181
-
182
- function createCaretPositionFromPointGetter(doc) {
183
- if (api.features.implementsTextRange) {
184
- return getTextRangePosition;
185
- } else if (typeof doc.caretPositionFromPoint != UNDEF) {
186
- return caretPositionFromPoint;
187
- } else if (typeof doc.caretRangeFromPoint != UNDEF) {
188
- return caretRangeFromPoint;
189
- } else if (typeof doc.elementFromPoint != UNDEF && rangeSupportsGetClientRects) {
190
- return positionFromPoint;
191
- } else {
192
- throw module.createError("createCaretPositionFromPointGetter(): Browser does not provide a recognised method to create a selection from pixel coordinates");
193
- }
194
- }
195
-
196
- function createRangeFromPoints(startX, startY, endX, endY, doc) {
197
- doc = dom.getContentDocument(doc, module, "createRangeFromPoints");
198
- var positionFinder = createCaretPositionFromPointGetter(doc);
199
- var startPos = positionFinder(doc, startX, startY, false);
200
- var endPos = positionFinder(doc, endX, endY, true);
201
- console.log(startPos.node, startPos.offset, endPos.node, endPos.offset);
202
- var range = api.createRange(doc);
203
- range.setStartAndEnd(startPos.node, startPos.offset, endPos.node, endPos.offset);
204
- return range;
205
- }
206
-
207
- function moveSelectionToPoints(anchorX, anchorY, focusX, focusY, doc) {
208
- var startX, startY, endX, endY;
209
-
210
- // Detect backward selection for coordinates and flip start and end coordinates if necessary
211
- var backward = focusY < anchorY || (anchorY == focusY && focusX < anchorX);
212
-
213
- if (backward) {
214
- startX = focusX;
215
- startY = focusY;
216
- endX = anchorX;
217
- endY = anchorY;
218
- } else {
219
- startX = anchorX;
220
- startY = anchorY;
221
- endX = focusX;
222
- endY = focusY;
223
- }
224
-
225
- var sel = rangy.getSelection(doc);
226
- var range = createRangeFromPoints(startX, startY, endX, endY, doc);
227
- sel.setSingleRange(range);
228
- return sel;
229
- }
230
-
231
- // Test that <span> elements support getBoundingClientRect
232
- var span = document.createElement("span");
233
- var elementSupportsGetBoundingClientRect = util.isHostMethod(span, "getBoundingClientRect");
234
- span = null;
235
-
236
- // Test for getBoundingClientRect support in Range
237
- var rangeSupportsGetClientRects = false, rangeSupportsGetBoundingClientRect = false;
238
- if (api.features.implementsDomRange) {
239
- var testRange = api.createNativeRange();
240
- rangeSupportsGetClientRects = util.isHostMethod(testRange, "getClientRects");
241
- rangeSupportsGetBoundingClientRect = util.isHostMethod(testRange, "getBoundingClientRect");
242
- testRange.detach();
243
- }
244
-
245
- util.extend(api.features, {
246
- rangeSupportsGetBoundingClientRect: rangeSupportsGetBoundingClientRect,
247
- rangeSupportsGetClientRects: rangeSupportsGetClientRects,
248
- elementSupportsGetBoundingClientRect: elementSupportsGetBoundingClientRect
249
- });
250
-
251
- var createClientBoundaryPosGetter = function(isStart) {
252
- return function() {
253
- var boundaryRange = this.cloneRange();
254
- boundaryRange.collapse(isStart);
255
- var rect = boundaryRange.getBoundingClientRect();
256
- return {
257
- x: rect[isStart ? "left" : "right"],
258
- y: rect[isStart ? "top" : "bottom"]
259
- };
260
- };
261
- };
262
-
263
- var rangeProto = api.rangePrototype;
264
-
265
- if (api.features.implementsTextRange && elementSupportsGetBoundingClientRect) {
266
- rangeProto.getBoundingClientRect = function() {
267
- // We need a TextRange
268
- var textRange = WrappedTextRange.rangeToTextRange(this);
269
-
270
- // Work around table problems (table cell bounding rects seem not to count if TextRange spans cells)
271
- var cells = this.getNodes([1], function(el) {
272
- return /^t[dh]$/i.test(el.tagName);
273
- });
274
-
275
- // Merge rects for each cell selected by the range into overall rect
276
- var rect, rects = [];
277
- if (cells.length > 0) {
278
- var lastTable = getAncestorElement(this.startContainer, "table");
279
-
280
- for (var i = 0, cell, tempTextRange, table, subRange, subRect; cell = cells[i]; ++i) {
281
- // Handle non-table sections of the range
282
- table = getAncestorElement(cell, "table");
283
- if (!lastTable || table != lastTable) {
284
- // There is a section of the range prior to the current table, or lying between tables.
285
- // Merge in its rect
286
- subRange = this.cloneRange();
287
- if (lastTable) {
288
- subRange.setStartAfter(lastTable);
289
- }
290
- subRange.setEndBefore(table);
291
- rects.push(WrappedTextRange.rangeToTextRange(subRange).getBoundingClientRect());
292
- }
293
-
294
- if (this.containsNode(cell)) {
295
- rects.push(cell.getBoundingClientRect());
296
- } else {
297
- tempTextRange = textRange.duplicate();
298
- tempTextRange.moveToElementText(cell);
299
- if (tempTextRange.compareEndPoints("StartToStart", textRange) == -1) {
300
- tempTextRange.setEndPoint("StartToStart", textRange);
301
- } else if (tempTextRange.compareEndPoints("EndToEnd", textRange) == 1) {
302
- tempTextRange.setEndPoint("EndToEnd", textRange);
303
- }
304
- rects.push(tempTextRange.getBoundingClientRect());
305
- }
306
- lastTable = table;
307
- }
308
-
309
- // Merge in the rect for any content lying after the final table
310
- var endTable = getAncestorElement(this.endContainer, "table");
311
- if (!endTable && lastTable) {
312
- subRange = this.cloneRange();
313
- subRange.setStartAfter(lastTable);
314
- rects.push(WrappedTextRange.rangeToTextRange(subRange).getBoundingClientRect());
315
- }
316
- rect = mergeRects(rects);
317
- } else {
318
- rect = textRange.getBoundingClientRect();
319
- }
320
-
321
- return adjustClientRect(rect, dom.getDocument(this.startContainer));
322
- };
323
- } else if (api.features.implementsDomRange) {
324
- var createWrappedRange = function(range) {
325
- return (range instanceof WrappedRange) ? range : new WrappedRange(range);
326
- };
327
-
328
- if (rangeSupportsGetBoundingClientRect) {
329
- rangeProto.getBoundingClientRect = function() {
330
- var nativeRange = createWrappedRange(this).nativeRange;
331
- // Test for WebKit getBoundingClientRect bug (https://bugs.webkit.org/show_bug.cgi?id=65324)
332
- var rect = nativeRange.getBoundingClientRect() || nativeRange.getClientRects()[0];
333
- return adjustClientRect(rect, dom.getDocument(this.startContainer));
334
- };
335
-
336
- if (rangeSupportsGetClientRects) {
337
- var getElementRectsForPosition = function(node, offset) {
338
- var children = node.childNodes;
339
- //if (offset < children.length)
340
- };
341
-
342
- createClientBoundaryPosGetter = function(isStart) {
343
- return function() {
344
- var rect, nativeRange = createWrappedRange(this).nativeRange;
345
- var rects = nativeRange.getClientRects();
346
-
347
- if (rects.length == 0 && elementSupportsGetBoundingClientRect) {
348
- if (isStart) {
349
-
350
-
351
- }
352
-
353
- console.log(nativeRange, nativeRange.getClientRects(), nativeRange.getBoundingClientRect());
354
- if (this.collapsed
355
- && this.startContainer.nodeType == 1
356
- && this.startOffset < this.startContainer.childNodes.length) {
357
- var n = this.startContainer.childNodes[this.startOffset];
358
- if (n.getClientRects) {
359
- console.log(n, n.getClientRects(), this.startContainer.getClientRects())
360
- }
361
-
362
- }
363
- }
364
-
365
- if (rects.length > 0) {
366
- if (isStart) {
367
- rect = rects[0];
368
- return { x: rect.left, y: rect.top };
369
- } else {
370
- rect = rects[rects.length - 1];
371
- return { x: rect.right, y: rect.bottom };
372
- }
373
- } else {
374
- throw module.createError("Cannot get position for range " + this.inspect());
375
- }
376
- };
377
- }
378
- }
379
- } else {
380
- var getElementBoundingClientRect = elementSupportsGetBoundingClientRect ?
381
- function(el) {
382
- return adjustClientRect(el.getBoundingClientRect(), dom.getDocument(el));
383
- } :
384
-
385
- // This implementation is very naive. There are many browser quirks that make it extremely
386
- // difficult to get accurate element coordinates in all situations
387
- function(el) {
388
- var x = 0, y = 0, offsetEl = el, width = el.offsetWidth, height = el.offsetHeight;
389
- while (offsetEl) {
390
- x += offsetEl.offsetLeft;
391
- y += offsetEl.offsetTop;
392
- offsetEl = offsetEl.offsetParent;
393
- }
394
-
395
- return adjustClientRect(new Rect(y, x + width, y + height, x), dom.getDocument(el));
396
- };
397
-
398
- var getRectFromBoundaries = function(range) {
399
- var rect;
400
- range.splitBoundaries();
401
- var span = document.createElement("span");
402
-
403
- if (range.collapsed) {
404
- range.insertNode(span);
405
- rect = getElementBoundingClientRect(span);
406
- span.parentNode.removeChild(span);
407
- } else {
408
- // TODO: This isn't right. I'm not sure it can be made right sensibly. Consider what to do.
409
- // This doesn't consider all the line boxes it needs to consider.
410
- var workingRange = range.cloneRange();
411
-
412
- // Get the start rectangle
413
- workingRange.collapse(true);
414
- workingRange.insertNode(span);
415
- var startRect = getElementBoundingClientRect(span);
416
- span.parentNode.removeChild(span);
417
-
418
- // Get the end rectangle
419
- workingRange.collapseToPoint(range.endContainer, range.endOffset);
420
- workingRange.insertNode(span);
421
- var endRect = getElementBoundingClientRect(span);
422
- span.parentNode.removeChild(span);
423
-
424
- // Merge the start and end rects
425
- var rects = [startRect, endRect];
426
-
427
- // Merge in rectangles for all elements in the range
428
- var elements = range.getNodes([1], function(el) {
429
- return range.containsNode(el);
430
- });
431
-
432
- for (var i = 0, len = elements.length; i < len; ++i) {
433
- rects.push(getElementBoundingClientRect(elements[i]));
434
- }
435
- rect = mergeRects(rects)
436
- }
437
-
438
- // Clean up
439
- range.normalizeBoundaries();
440
- return rect;
441
- };
442
-
443
- rangeProto.getBoundingClientRect = function(range) {
444
- return getRectFromBoundaries(createWrappedRange(range));
445
- };
446
- }
447
-
448
- function createDocumentBoundaryPosGetter(isStart) {
449
- return function() {
450
- var pos = this["get" + (isStart ? "Start" : "End") + "ClientPos"]();
451
- var scrollPos = getScrollPosition( dom.getWindow(this.startContainer) );
452
- return { x: pos.x + scrollPos.x, y: pos.y + scrollPos.y };
453
- };
454
- }
455
- }
456
-
457
- util.extend(rangeProto, {
458
- getBoundingDocumentRect: function() {
459
- var scrollPos = getScrollPosition( dom.getWindow(this.startContainer) );
460
- return createRelativeRect(this.getBoundingClientRect(), scrollPos.x, scrollPos.y);
461
- },
462
-
463
- getStartClientPos: createClientBoundaryPosGetter(true),
464
- getEndClientPos: createClientBoundaryPosGetter(false),
465
-
466
- getStartDocumentPos: createDocumentBoundaryPosGetter(true),
467
- getEndDocumentPos: createDocumentBoundaryPosGetter(false)
468
- });
469
-
470
- // Add Selection methods
471
- function compareRanges(r1, r2) {
472
- return r1.compareBoundaryPoints(r2.START_TO_START, r2);
473
- }
474
-
475
- function createSelectionRectGetter(isDocument) {
476
- return function() {
477
- var rangeMethodName = "getBounding" + (isDocument ? "Document" : "Client") + "Rect";
478
- var rects = [];
479
- for (var i = 0, rect = null, rangeRect; i < this.rangeCount; ++i) {
480
- rects.push(this.getRangeAt(i)[rangeMethodName]());
481
- }
482
- return mergeRects(rects);
483
- };
484
- }
485
-
486
- function createSelectionBoundaryPosGetter(isStart, isDocument) {
487
- return function() {
488
- if (this.rangeCount == 0) {
489
- return null;
490
- }
491
-
492
- var posType = isDocument ? "Document" : "Client";
493
-
494
- var ranges = this.getAllRanges();
495
- if (ranges.length > 1) {
496
- // Order the ranges by position within the DOM
497
- ranges.sort(compareRanges);
498
- }
499
-
500
- return isStart ?
501
- ranges[0]["getStart" + posType + "Pos"]() :
502
- ranges[ranges.length - 1]["getEnd" + posType + "Pos"]();
503
- };
504
- }
505
-
506
- util.extend(api.selectionPrototype, {
507
- getBoundingClientRect: createSelectionRectGetter(false),
508
- getBoundingDocumentRect: createSelectionRectGetter(true),
509
-
510
- getStartClientPos: createSelectionBoundaryPosGetter(true, false),
511
- getEndClientPos: createSelectionBoundaryPosGetter(false, false),
512
-
513
- getStartDocumentPos: createSelectionBoundaryPosGetter(true, true),
514
- getEndDocumentPos: createSelectionBoundaryPosGetter(false, true)
515
- });
516
-
517
- api.positionFromPoint = function(x, y, doc) {
518
- doc = dom.getContentDocument(doc, module, "positionFromPoint");
519
- return createCaretPositionFromPointGetter(doc)(doc, x, y);
520
- };
521
-
522
- api.createRangeFromPoints = createRangeFromPoints;
523
- api.moveSelectionToPoints = moveSelectionToPoints;
524
- });