jquerypp-rails 1.0.1.1.rc3 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (26) hide show
  1. data/README.markdown +28 -31
  2. data/lib/jquerypp/rails/version.rb +1 -1
  3. metadata +2 -25
  4. data/vendor/assets/javascripts/lib/jquery.animate.js +0 -326
  5. data/vendor/assets/javascripts/lib/jquery.compare.js +0 -75
  6. data/vendor/assets/javascripts/lib/jquery.cookie.js +0 -118
  7. data/vendor/assets/javascripts/lib/jquery.dimensions.js +0 -191
  8. data/vendor/assets/javascripts/lib/jquery.event.default.js +0 -115
  9. data/vendor/assets/javascripts/lib/jquery.event.destroyed.js +0 -23
  10. data/vendor/assets/javascripts/lib/jquery.event.drag.js +0 -727
  11. data/vendor/assets/javascripts/lib/jquery.event.drop.js +0 -457
  12. data/vendor/assets/javascripts/lib/jquery.event.fastfix.js +0 -95
  13. data/vendor/assets/javascripts/lib/jquery.event.hover.js +0 -266
  14. data/vendor/assets/javascripts/lib/jquery.event.key.js +0 -156
  15. data/vendor/assets/javascripts/lib/jquery.event.livehack.js +0 -174
  16. data/vendor/assets/javascripts/lib/jquery.event.pause.js +0 -92
  17. data/vendor/assets/javascripts/lib/jquery.event.resize.js +0 -47
  18. data/vendor/assets/javascripts/lib/jquery.event.swipe.js +0 -133
  19. data/vendor/assets/javascripts/lib/jquery.fills.js +0 -249
  20. data/vendor/assets/javascripts/lib/jquery.form_params.js +0 -167
  21. data/vendor/assets/javascripts/lib/jquery.lang.json.js +0 -196
  22. data/vendor/assets/javascripts/lib/jquery.lang.vector.js +0 -214
  23. data/vendor/assets/javascripts/lib/jquery.range.js +0 -861
  24. data/vendor/assets/javascripts/lib/jquery.selection.js +0 -232
  25. data/vendor/assets/javascripts/lib/jquery.styles.js +0 -103
  26. data/vendor/assets/javascripts/lib/jquery.within.js +0 -94
@@ -1,861 +0,0 @@
1
- // Dependencies:
2
- //
3
- // - jquery.range.js
4
- // - jquery.compare.js
5
-
6
- (function($){
7
-
8
- $.fn.range =
9
- /**
10
- * @function jQuery.fn.range
11
- * @parent jQuery.Range
12
- *
13
- * `$.fn.range` returns a new [jQuery.Range] instance for the first selected element.
14
- *
15
- * $('#content').range() //-> range
16
- *
17
- * @return {$.Range} A $.Range instance for the selected element
18
- */
19
- function(){
20
- return $.Range(this[0])
21
- }
22
-
23
- var convertType = function(type){
24
- return type.replace(/([a-z])([a-z]+)/gi, function(all,first, next){
25
- return first+next.toLowerCase()
26
- }).replace(/_/g,"");
27
- },
28
- // reverses things like START_TO_END into END_TO_START
29
- reverse = function(type){
30
- return type.replace(/^([a-z]+)_TO_([a-z]+)/i, function(all, first, last){
31
- return last+"_TO_"+first;
32
- });
33
- },
34
- getWindow = function( element ) {
35
- return element ? element.ownerDocument.defaultView || element.ownerDocument.parentWindow : window
36
- },
37
- bisect = function(el, start, end){
38
- //split the start and end ... figure out who is touching ...
39
- if(end-start == 1){
40
- return
41
- }
42
- },
43
- support = {};
44
- /**
45
- * @Class jQuery.Range
46
- * @parent jQuery.Range
47
- *
48
- * Depending on the object passed, the selected text will be different.
49
- *
50
- * @param {TextRange|HTMLElement|Point} [range] An object specifiying a
51
- * range. Depending on the object, the selected text will be different. $.Range supports the
52
- * following types
53
- *
54
- * - __undefined or null__ - returns a range with nothing selected
55
- * - __HTMLElement__ - returns a range with the node's text selected
56
- * - __Point__ - returns a range at the point on the screen. The point can be specified like:
57
- *
58
- * //client coordinates
59
- * {clientX: 200, clientY: 300}
60
- *
61
- * //page coordinates
62
- * {pageX: 200, pageY: 300}
63
- * {top: 200, left: 300}
64
- *
65
- * - __TextRange__ a raw text range object.
66
- */
67
- $.Range = function(range){
68
- // If it's called w/o new, call it with new!
69
- if(this.constructor !== $.Range){
70
- return new $.Range(range);
71
- }
72
- // If we are passed a jQuery-wrapped element, get the raw element
73
- if(range && range.jquery){
74
- range = range[0];
75
- }
76
- // If we have an element, or nothing
77
- if(!range || range.nodeType){
78
- // create a range
79
- this.win = getWindow(range)
80
- if(this.win.document.createRange){
81
- this.range = this.win.document.createRange()
82
- }else{
83
- this.range = this.win.document.body.createTextRange()
84
- }
85
- // if we have an element, make the range select it
86
- if(range){
87
- this.select(range)
88
- }
89
- }
90
- // if we are given a point
91
- else if (range.clientX != null || range.pageX != null || range.left != null) {
92
- this.moveToPoint(range);
93
- }
94
- // if we are given a touch event
95
- else if (range.originalEvent && range.originalEvent.touches && range.originalEvent.touches.length) {
96
- this.moveToPoint(range.originalEvent.touches[0])
97
-
98
- }
99
- // if we are a normal event
100
- else if (range.originalEvent && range.originalEvent.changedTouches && range.originalEvent.changedTouches.length) {
101
- this.moveToPoint(range.originalEvent.changedTouches[0])
102
- }
103
- // given a TextRange or something else?
104
- else {
105
- this.range = range;
106
- }
107
- };
108
- /**
109
- * @static
110
- */
111
- $.Range.
112
- /**
113
- * `$.Range.current([element])` returns the currently selected range
114
- * (using [window.getSelection](https://developer.mozilla.org/en/nsISelection)).
115
- *
116
- * var range = $.Range.current()
117
- * range.start().offset // -> selection start offset
118
- * range.end().offset // -> selection end offset
119
- *
120
- * @param {HTMLElement} [el] an optional element used to get selection for a given window.
121
- * @return {jQuery.Range} The range instance.
122
- */
123
- current = function(el){
124
- var win = getWindow(el),
125
- selection;
126
- if(win.getSelection){
127
- // If we can get the selection
128
- selection = win.getSelection()
129
- return new $.Range( selection.rangeCount ? selection.getRangeAt(0) : win.document.createRange())
130
- } else {
131
- // Otherwise use document.selection
132
- return new $.Range( win.document.selection.createRange() );
133
- }
134
- };
135
-
136
-
137
-
138
-
139
- $.extend($.Range.prototype,
140
- /** @prototype **/
141
- {
142
- /**
143
- * `range.moveToPoint(point)` moves the range end and start position to a specific point.
144
- * A point can be specified like:
145
- *
146
- * //client coordinates
147
- * {clientX: 200, clientY: 300}
148
- *
149
- * //page coordinates
150
- * {pageX: 200, pageY: 300}
151
- * {top: 200, left: 300}
152
- *
153
- * @param point The point to move the range to
154
- * @return {$.Range}
155
- */
156
- moveToPoint : function(point){
157
- var clientX = point.clientX, clientY = point.clientY
158
- if(!clientX){
159
- var off = scrollOffset();
160
- clientX = (point.pageX || point.left || 0 ) - off.left;
161
- clientY = (point.pageY || point.top || 0 ) - off.top;
162
- }
163
- if(support.moveToPoint){
164
- this.range = $.Range().range
165
- this.range.moveToPoint(clientX, clientY);
166
- return this;
167
- }
168
-
169
-
170
- // it's some text node in this range ...
171
- var parent = document.elementFromPoint(clientX, clientY);
172
-
173
- //typically it will be 'on' text
174
- for(var n=0; n < parent.childNodes.length; n++){
175
- var node = parent.childNodes[n];
176
- if(node.nodeType === 3 || node.nodeType === 4){
177
- var range = $.Range(node),
178
- length = range.toString().length;
179
-
180
-
181
- // now lets start moving the end until the boundingRect is within our range
182
- for(var i = 1; i < length+1; i++){
183
- var rect = range.end(i).rect();
184
- if(rect.left <= clientX && rect.left+rect.width >= clientX &&
185
- rect.top <= clientY && rect.top+rect.height >= clientY ){
186
- range.start(i-1);
187
- this.range = range.range;
188
- return this;
189
- }
190
- }
191
- }
192
- }
193
-
194
- // if not 'on' text, recursively go through and find out when we shift to next
195
- // 'line'
196
- var previous;
197
- iterate(parent.childNodes, function(textNode){
198
- var range = $.Range(textNode);
199
- if(range.rect().top > point.clientY){
200
- return false;
201
- }else{
202
- previous = range;
203
- }
204
- });
205
-
206
- if(previous){
207
- previous.start(previous.toString().length);
208
- this.range = previous.range;
209
- }else{
210
- this.range = $.Range(parent).range
211
- }
212
- },
213
-
214
- window : function(){
215
- return this.win || window;
216
- },
217
- /**
218
- * `range.overlaps([elRange])` returns `true` if any portion of these two ranges overlap.
219
- *
220
- * var foo = document.getElementById('foo');
221
- *
222
- * $.Range(foo.childNodes[0]).overlaps(foo.childNodes[1]) //-> false
223
- *
224
- * @param {jQuery.Range} elRange The range to compare
225
- * @return {Boolean} true if part of the ranges overlap, false if otherwise.
226
- */
227
- overlaps : function(elRange){
228
- if(elRange.nodeType){
229
- elRange = $.Range(elRange).select(elRange);
230
- }
231
- //if the start is within the element ...
232
- var startToStart = this.compare("START_TO_START", elRange),
233
- endToEnd = this.compare("END_TO_END", elRange)
234
-
235
- // if we wrap elRange
236
- if(startToStart <=0 && endToEnd >=0){
237
- return true;
238
- }
239
- // if our start is inside of it
240
- if( startToStart >= 0 &&
241
- this.compare("START_TO_END", elRange) <= 0 ) {
242
- return true;
243
- }
244
- // if our end is inside of elRange
245
- if(this.compare("END_TO_START", elRange) >= 0 &&
246
- endToEnd <= 0 ) {
247
- return true;
248
- }
249
- return false;
250
- },
251
- /**
252
- * `range.collapse([toStart])` collapses a range to one of its boundary points.
253
- * See [range.collapse](https://developer.mozilla.org/en/DOM/range.collapse).
254
- *
255
- * $('#foo').range().collapse()
256
- *
257
- * @param {Boolean} [toStart] true if to the start of the range, false if to the
258
- * end. Defaults to false.
259
- * @return {jQuery.Range} returns the range for chaining.
260
- */
261
- collapse : function(toStart){
262
- this.range.collapse(toStart === undefined ? true : toStart);
263
- return this;
264
- },
265
- /**
266
- * `range.toString()` returns the text of the range.
267
- *
268
- * currentText = $.Range.current().toString()
269
- *
270
- * @return {String} The text content of this range
271
- */
272
- toString : function(){
273
- return typeof this.range.text == "string" ? this.range.text : this.range.toString();
274
- },
275
- /**
276
- * `range.start([start])` gets or sets the start of the range.
277
- *
278
- * If a value is not provided, start returns the range's starting container and offset like:
279
- *
280
- * $('#foo').range().start()
281
- * //-> {container: fooElement, offset: 0 }
282
- *
283
- * If a set value is provided, it can set the range. The start of the range is set differently
284
- * depending on the type of set value:
285
- *
286
- * - __Object__ - an object with the new starting container and offset like
287
- *
288
- * $.Range().start({container: $('#foo')[0], offset: 20})
289
- *
290
- * - __Number__ - the new offset value. The container is kept the same.
291
- *
292
- * - __String__ - adjusts the offset by converting the string offset to a number and adding it to the current
293
- * offset. For example, the following moves the offset forward four characters:
294
- *
295
- * $('#foo').range().start("+4")
296
- *
297
- * Note that `start` can return a text node. To get the containing element use this:
298
- *
299
- * var startNode = range.start().container;
300
- * if( startNode.nodeType === Node.TEXT_NODE ||
301
- * startNode.nodeType === Node.CDATA_SECTION_NODE ) {
302
- * startNode = startNode.parentNode;
303
- * }
304
- * $(startNode).addClass('highlight');
305
- *
306
- * @param {Object|String|Number} [set] a set value if setting the start of the range or nothing if reading it.
307
- * @return {jQuery.Range|Object} if setting the start, the range is returned for chaining, otherwise, the
308
- * start offset and container are returned.
309
- */
310
- start : function(set){
311
- // return start
312
- if(set === undefined){
313
- if(this.range.startContainer){
314
- return {
315
- container : this.range.startContainer,
316
- offset : this.range.startOffset
317
- }
318
- }else{
319
- // Get the start parent element
320
- var start = this.clone().collapse().parent();
321
- // used to get the start element offset
322
- var startRange = $.Range(start).select(start).collapse();
323
- startRange.move("END_TO_START", this);
324
- return {
325
- container : start,
326
- offset : startRange.toString().length
327
- }
328
- }
329
- } else {
330
- if (this.range.setStart) {
331
- // supports setStart
332
- if(typeof set == 'number'){
333
- this.range.setStart(this.range.startContainer, set)
334
- } else if(typeof set == 'string') {
335
- var res = callMove(this.range.startContainer, this.range.startOffset, parseInt(set,10))
336
- this.range.setStart(res.node, res.offset );
337
- } else {
338
- this.range.setStart(set.container, set.offset)
339
- }
340
- } else {
341
- if(typeof set == "string"){
342
- this.range.moveStart('character', parseInt(set,10))
343
- } else {
344
- // get the current end container
345
- var container = this.start().container,
346
- offset
347
- if(typeof set == "number") {
348
- offset = set
349
- } else {
350
- container = set.container
351
- offset = set.offset
352
- }
353
- var newPoint = $.Range(container).collapse();
354
- //move it over offset characters
355
- newPoint.range.move(offset);
356
- this.move("START_TO_START",newPoint);
357
- }
358
- }
359
- return this;
360
- }
361
-
362
-
363
- },
364
- /**
365
- * `range.end([end])` gets or sets the end of the range.
366
- * It takes similar options as [jQuery.Range::start start]:
367
- *
368
- * - __Object__ - an object with the new end container and offset like
369
- *
370
- * $.Range().end({container: $('#foo')[0], offset: 20})
371
- *
372
- * - __Number__ - the new offset value. The container is kept the same.
373
- *
374
- * - __String__ - adjusts the offset by converting the string offset to a number and adding it to the current
375
- * offset. For example, the following moves the offset forward four characters:
376
- *
377
- * $('#foo').range().end("+4")
378
- *
379
- * Note that `end` can return a text node. To get the containing element use this:
380
- *
381
- * var startNode = range.end().container;
382
- * if( startNode.nodeType === Node.TEXT_NODE ||
383
- * startNode.nodeType === Node.CDATA_SECTION_NODE ) {
384
- * startNode = startNode.parentNode;
385
- * }
386
- * $(startNode).addClass('highlight');
387
- *
388
- * @param {Object|String|Number} [set] a set value if setting the end of the range or nothing if reading it.
389
- */
390
- end : function(set){
391
- // read end
392
- if (set === undefined) {
393
- if (this.range.startContainer) {
394
- return {
395
- container: this.range.endContainer,
396
- offset: this.range.endOffset
397
- }
398
- }
399
- else {
400
- var
401
- // Get the end parent element
402
- end = this.clone().collapse(false).parent(),
403
- // used to get the end elements offset
404
- endRange = $.Range(end).select(end).collapse();
405
- endRange.move("END_TO_END", this);
406
- return {
407
- container: end,
408
- offset: endRange.toString().length
409
- }
410
- }
411
- } else {
412
- if (this.range.setEnd) {
413
- if(typeof set == 'number'){
414
- this.range.setEnd(this.range.endContainer, set)
415
- } else if(typeof set == 'string') {
416
- var res = callMove(this.range.endContainer, this.range.endOffset, parseInt(set,10))
417
- this.range.setEnd(res.node, res.offset );
418
- } else {
419
- this.range.setEnd(set.container, set.offset)
420
- }
421
- } else {
422
- if(typeof set == "string"){
423
- this.range.moveEnd('character', parseInt(set,10));
424
- } else {
425
- // get the current end container
426
- var container = this.end().container,
427
- offset
428
- if(typeof set == "number") {
429
- offset = set
430
- } else {
431
- container = set.container
432
- offset = set.offset
433
- }
434
- var newPoint = $.Range(container).collapse();
435
- //move it over offset characters
436
- newPoint.range.move(offset);
437
- this.move("END_TO_START",newPoint);
438
- }
439
- }
440
- return this;
441
- }
442
- },
443
- /**
444
- * `range.parent()` returns the most common ancestor element of
445
- * the endpoints in the range. This will return a text element if the range is
446
- * within a text element. In this case, to get the containing element use this:
447
- *
448
- * var parent = range.parent();
449
- * if( parent.nodeType === Node.TEXT_NODE ||
450
- * parent.nodeType === Node.CDATA_SECTION_NODE ) {
451
- * parent = startNode.parentNode;
452
- * }
453
- * $(parent).addClass('highlight');
454
- *
455
- * @return {HTMLNode} the TextNode or HTMLElement
456
- * that fully contains the range
457
- */
458
- parent : function(){
459
- if(this.range.commonAncestorContainer){
460
- return this.range.commonAncestorContainer;
461
- } else {
462
-
463
- var parentElement = this.range.parentElement(),
464
- range = this.range;
465
-
466
- // IE's parentElement will always give an element, we want text ranges
467
- iterate(parentElement.childNodes, function(txtNode){
468
- if($.Range(txtNode).range.inRange( range ) ){
469
- // swap out the parentElement
470
- parentElement = txtNode;
471
- return false;
472
- }
473
- });
474
-
475
- return parentElement;
476
- }
477
- },
478
- /**
479
- * `range.rect([from])` returns the bounding rectangle of this range.
480
- *
481
- * @param {String} [from] - where the coordinates should be
482
- * positioned from. By default, coordinates are given from the client viewport.
483
- * But if 'page' is given, they are provided relative to the page.
484
- *
485
- * @return {TextRectangle} - The client rects.
486
- */
487
- rect : function(from){
488
- var rect = this.range.getBoundingClientRect();
489
- // for some reason in webkit this gets a better value
490
- if(!rect.height && !rect.width){
491
- rect = this.range.getClientRects()[0]
492
- }
493
- if(from === 'page'){
494
- // Add the scroll offset
495
- var off = scrollOffset();
496
- rect = $.extend({}, rect);
497
- rect.top += off.top;
498
- rect.left += off.left;
499
- }
500
- return rect;
501
- },
502
- /**
503
- * `range.rects(from)` returns the client rects.
504
- *
505
- * @param {String} [from] how the rects coordinates should be given (viewport or page). Provide 'page' for
506
- * rect coordinates from the page.
507
- * @return {Array} The client rects
508
- */
509
- rects : function(from){
510
- // order rects by size
511
- var rects = $.map($.makeArray( this.range.getClientRects() ).sort(function(rect1, rect2){
512
- return rect2.width*rect2.height - rect1.width*rect1.height;
513
- }), function(rect){
514
- return $.extend({}, rect)
515
- }),
516
- i=0,j,
517
- len = rects.length;
518
-
519
- // safari returns overlapping client rects
520
- //
521
- // - big rects can contain 2 smaller rects
522
- // - some rects can contain 0 - width rects
523
- // - we don't want these 0 width rects
524
- while(i < rects.length){
525
- var cur = rects[i],
526
- found = false;
527
-
528
- j = i+1;
529
- while( j < rects.length ){
530
- if( withinRect( cur, rects[j] ) ) {
531
- if(!rects[j].width){
532
- rects.splice(j,1)
533
- } else {
534
- found = rects[j];
535
- break;
536
- }
537
- } else {
538
- j++;
539
- }
540
- }
541
-
542
-
543
- if(found){
544
- rects.splice(i,1)
545
- }else{
546
- i++;
547
- }
548
-
549
- }
550
- // safari will be return overlapping ranges ...
551
- if(from == 'page'){
552
- var off = scrollOffset();
553
- return $.each(rects, function(ith, item){
554
- item.top += off.top;
555
- item.left += off.left;
556
- })
557
- }
558
-
559
-
560
- return rects;
561
- }
562
-
563
- });
564
- (function(){
565
- //method branching ....
566
- var fn = $.Range.prototype,
567
- range = $.Range().range;
568
-
569
- /**
570
- * @function compare
571
- *
572
- * `range.compare(type, compareRange)` compares one range to another range.
573
- *
574
- * ## Example
575
- *
576
- * // compare the highlight element's start position
577
- * // to the start of the current range
578
- * $('#highlight')
579
- * .range()
580
- * .compare('START_TO_START', $.Range.current())
581
- *
582
- *
583
- *
584
- * @param {String} type Specifies the boundary of the
585
- * range and the <code>compareRange</code> to compare.
586
- *
587
- * - `"START_TO_START"` - the start of the range and the start of compareRange
588
- * - `"START_TO_END"` - the start of the range and the end of compareRange
589
- * - `"END_TO_END"` - the end of the range and the end of compareRange
590
- * - `"END_TO_START"` - the end of the range and the start of compareRange
591
- *
592
- * @param {$.Range} compareRange The other range
593
- * to compare against.
594
- * @return {Number} a number indicating if the range
595
- * boundary is before,
596
- * after, or equal to <code>compareRange</code>'s
597
- * boundary where:
598
- *
599
- * - -1 - the range boundary comes before the compareRange boundary
600
- * - 0 - the boundaries are equal
601
- * - 1 - the range boundary comes after the compareRange boundary
602
- */
603
- fn.compare = range.compareBoundaryPoints ?
604
- function(type, range){
605
- return this.range.compareBoundaryPoints(this.window().Range[reverse( type )], range.range)
606
- }:
607
- function(type, range){
608
- return this.range.compareEndPoints(convertType(type), range.range)
609
- }
610
-
611
- /**
612
- * @function move
613
- *
614
- * `range.move([referenceRange])` moves the endpoints of a range relative to another range.
615
- *
616
- * // Move the current selection's end to the
617
- * // end of the #highlight element
618
- * $.Range.current().move('END_TO_END',
619
- * $('#highlight').range() )
620
- *
621
- *
622
- * @param {String} type a string indicating the ranges boundary point
623
- * to move to which referenceRange boundary point where:
624
- *
625
- * - `"START_TO_START"` - the start of the range moves to the start of referenceRange
626
- * - `"START\_TO\_END"` - the start of the range move to the end of referenceRange
627
- * - `"END_TO_END"` - the end of the range moves to the end of referenceRange
628
- * - `"END_TO_START"` - the end of the range moves to the start of referenceRange
629
- *
630
- * @param {jQuery.Range} referenceRange
631
- * @return {jQuery.Range} the original range for chaining
632
- */
633
- fn.move = range.setStart ?
634
- function(type, range){
635
-
636
- var rangesRange = range.range;
637
- switch(type){
638
- case "START_TO_END" :
639
- this.range.setStart(rangesRange.endContainer, rangesRange.endOffset)
640
- break;
641
- case "START_TO_START" :
642
- this.range.setStart(rangesRange.startContainer, rangesRange.startOffset)
643
- break;
644
- case "END_TO_END" :
645
- this.range.setEnd(rangesRange.endContainer, rangesRange.endOffset)
646
- break;
647
- case "END_TO_START" :
648
- this.range.setEnd(rangesRange.startContainer, rangesRange.startOffset)
649
- break;
650
- }
651
-
652
- return this;
653
- }:
654
- function(type, range){
655
- this.range.setEndPoint(convertType(type), range.range)
656
- return this;
657
- };
658
- var cloneFunc = range.cloneRange ? "cloneRange" : "duplicate",
659
- selectFunc = range.selectNodeContents ? "selectNodeContents" : "moveToElementText";
660
-
661
- fn.
662
- /**
663
- * `range.clone()` clones the range and returns a new $.Range
664
- * object:
665
- *
666
- * var range = new $.Range(document.getElementById('text'));
667
- * var newRange = range.clone();
668
- * range.start('+2');
669
- * range.select();
670
- *
671
- * @return {jQuery.Range} returns the range as a $.Range.
672
- */
673
- clone = function(){
674
- return $.Range( this.range[cloneFunc]() );
675
- };
676
-
677
- fn.
678
- /**
679
- * @function
680
- *
681
- * `range.select([el])` selects an element with this range. If nothing
682
- * is provided, makes the current range appear as if the user has selected it.
683
- *
684
- * This works with text nodes. For example with:
685
- *
686
- * <div id="text">This is a text</div>
687
- *
688
- * $.Range can select `is a` like this:
689
- *
690
- * var range = new $.Range(document.getElementById('text'));
691
- * range.start('+5');
692
- * range.end('-5');
693
- * range.select();
694
- *
695
- * @param {HTMLElement} [el] The element in which this range should be selected
696
- * @return {jQuery.Range} the range for chaining.
697
- */
698
- select = range.selectNodeContents ? function(el){
699
- if(!el){
700
- var selection = this.window().getSelection();
701
- selection.removeAllRanges();
702
- selection.addRange(this.range);
703
- }else {
704
- this.range.selectNodeContents(el);
705
- }
706
- return this;
707
- } : function(el){
708
- if(!el){
709
- this.range.select()
710
- } else if(el.nodeType === 3){
711
- //select this node in the element ...
712
- var parent = el.parentNode,
713
- start = 0,
714
- end;
715
- iterate(parent.childNodes, function(txtNode){
716
- if(txtNode === el){
717
- end = start + txtNode.nodeValue.length;
718
- return false;
719
- } else {
720
- start = start + txtNode.nodeValue.length
721
- }
722
- })
723
- this.range.moveToElementText(parent);
724
-
725
- this.range.moveEnd('character', end - this.range.text.length)
726
- this.range.moveStart('character', start);
727
- } else {
728
- this.range.moveToElementText(el);
729
- }
730
- return this;
731
- };
732
-
733
- })();
734
-
735
-
736
- // helpers -----------------
737
-
738
- // iterates through a list of elements, calls cb on every text node
739
- // if cb returns false, exits the iteration
740
- var iterate = function(elems, cb){
741
- var elem, start;
742
- for (var i = 0; elems[i]; i++) {
743
- elem = elems[i];
744
- // Get the text from text nodes and CDATA nodes
745
- if (elem.nodeType === 3 || elem.nodeType === 4) {
746
- if (cb(elem) === false) {
747
- return false;
748
- }
749
- // Traverse everything else, except comment nodes
750
- }
751
- else
752
- if (elem.nodeType !== 8) {
753
- if (iterate(elem.childNodes, cb) === false) {
754
- return false;
755
- }
756
- }
757
- }
758
-
759
- },
760
- isText = function(node){
761
- return node.nodeType === 3 || node.nodeType === 4
762
- },
763
- iteratorMaker = function(toChildren, toNext){
764
- return function( node, mustMoveRight ) {
765
- // first try down
766
- if(node[toChildren] && !mustMoveRight){
767
- return isText(node[toChildren]) ?
768
- node[toChildren] :
769
- arguments.callee(node[toChildren])
770
- } else if(node[toNext]) {
771
- return isText(node[toNext]) ?
772
- node[toNext] :
773
- arguments.callee(node[toNext])
774
- } else if(node.parentNode){
775
- return arguments.callee(node.parentNode, true)
776
- }
777
- }
778
- },
779
- getNextTextNode = iteratorMaker("firstChild","nextSibling"),
780
- getPrevTextNode = iteratorMaker("lastChild","previousSibling"),
781
- callMove = function(container, offset, howMany){
782
- if(isText(container)){
783
- return move(container, offset+howMany)
784
- } else {
785
- return container.childNodes[offset] ?
786
- move(container.childNodes[offset] , howMany) :
787
- move(container.lastChild, howMany , true)
788
- return
789
- }
790
- },
791
- move = function(from, howMany){
792
- var mover = howMany < 0 ?
793
- getPrevTextNode : getNextTextNode;
794
-
795
- howMany = Math.abs(howMany);
796
-
797
- if(!isText(from)){
798
- from = mover(from)
799
- }
800
- while(from && howMany >= from.nodeValue.length){
801
- hasMany = howMany- from.nodeValue.length;
802
- from = mover(from)
803
- }
804
- return {
805
- node: from,
806
- offset: mover === getNextTextNode ?
807
- howMany :
808
- from.nodeValue.length - howMany
809
- }
810
- },
811
- supportWhitespace,
812
- isWhitespace = function(el){
813
- if(supportWhitespace == null){
814
- supportWhitespace = 'isElementContentWhitespace' in el;
815
- }
816
- return (supportWhitespace? el.isElementContentWhitespace :
817
- (el.nodeType === 3 && '' == el.data.trim()));
818
-
819
- },
820
- // if a point is within a rectangle
821
- within = function(rect, point){
822
-
823
- return rect.left <= point.clientX && rect.left + rect.width >= point.clientX &&
824
- rect.top <= point.clientY &&
825
- rect.top + rect.height >= point.clientY
826
- },
827
- // if a rectangle is within another rectangle
828
- withinRect = function(outer, inner){
829
- return within(outer, {
830
- clientX: inner.left,
831
- clientY: inner.top
832
- }) && //top left
833
- within(outer, {
834
- clientX: inner.left + inner.width,
835
- clientY: inner.top
836
- }) && //top right
837
- within(outer, {
838
- clientX: inner.left,
839
- clientY: inner.top + inner.height
840
- }) && //bottom left
841
- within(outer, {
842
- clientX: inner.left + inner.width,
843
- clientY: inner.top + inner.height
844
- }) //bottom right
845
- },
846
- // gets the scroll offset from a window
847
- scrollOffset = function( win){
848
- var win = win ||window;
849
- doc = win.document.documentElement, body = win.document.body;
850
-
851
- return {
852
- left: (doc && doc.scrollLeft || body && body.scrollLeft || 0) + (doc.clientLeft || 0),
853
- top: (doc && doc.scrollTop || body && body.scrollTop || 0) + (doc.clientTop || 0)
854
- };
855
- };
856
-
857
-
858
- support.moveToPoint = !!$.Range().range.moveToPoint
859
-
860
-
861
- })(jQuery)