tinymce-rails 4.0.28 → 4.0.28.1

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.
@@ -13363,394 +13363,394 @@ define("tinymce/dom/RangeUtils", [
13363
13363
 
13364
13364
  // Included from: js/tinymce/classes/dom/BookmarkManager.js
13365
13365
 
13366
- /**
13367
- * BookmarkManager.js
13368
- *
13369
- * Copyright, Moxiecode Systems AB
13370
- * Released under LGPL License.
13371
- *
13372
- * License: http://www.tinymce.com/license
13373
- * Contributing: http://www.tinymce.com/contributing
13374
- */
13375
-
13376
- /**
13377
- * This class handles selection bookmarks.
13378
- *
13379
- * @class tinymce.dom.BookmarkManager
13380
- */
13381
- define("tinymce/dom/BookmarkManager", [
13382
- "tinymce/Env",
13383
- "tinymce/util/Tools"
13384
- ], function(Env, Tools) {
13385
- /**
13386
- * Constructs a new BookmarkManager instance for a specific selection instance.
13387
- *
13388
- * @constructor
13389
- * @method BookmarkManager
13390
- * @param {tinymce.dom.Selection} selection Selection instance to handle bookmarks for.
13391
- */
13392
- function BookmarkManager(selection) {
13393
- var dom = selection.dom;
13394
-
13395
- /**
13396
- * Returns a bookmark location for the current selection. This bookmark object
13397
- * can then be used to restore the selection after some content modification to the document.
13398
- *
13399
- * @method getBookmark
13400
- * @param {Number} type Optional state if the bookmark should be simple or not. Default is complex.
13401
- * @param {Boolean} normalized Optional state that enables you to get a position that it would be after normalization.
13402
- * @return {Object} Bookmark object, use moveToBookmark with this object to restore the selection.
13403
- * @example
13404
- * // Stores a bookmark of the current selection
13405
- * var bm = tinymce.activeEditor.selection.getBookmark();
13406
- *
13407
- * tinymce.activeEditor.setContent(tinymce.activeEditor.getContent() + 'Some new content');
13408
- *
13409
- * // Restore the selection bookmark
13410
- * tinymce.activeEditor.selection.moveToBookmark(bm);
13411
- */
13412
- this.getBookmark = function(type, normalized) {
13413
- var rng, rng2, id, collapsed, name, element, chr = '', styles;
13414
-
13415
- function findIndex(name, element) {
13416
- var index = 0;
13417
-
13418
- Tools.each(dom.select(name), function(node, i) {
13419
- if (node == element) {
13420
- index = i;
13421
- }
13422
- });
13423
-
13424
- return index;
13425
- }
13426
-
13427
- function normalizeTableCellSelection(rng) {
13428
- function moveEndPoint(start) {
13429
- var container, offset, childNodes, prefix = start ? 'start' : 'end';
13430
-
13431
- container = rng[prefix + 'Container'];
13432
- offset = rng[prefix + 'Offset'];
13433
-
13434
- if (container.nodeType == 1 && container.nodeName == "TR") {
13435
- childNodes = container.childNodes;
13436
- container = childNodes[Math.min(start ? offset : offset - 1, childNodes.length - 1)];
13437
- if (container) {
13438
- offset = start ? 0 : container.childNodes.length;
13439
- rng['set' + (start ? 'Start' : 'End')](container, offset);
13440
- }
13441
- }
13442
- }
13443
-
13444
- moveEndPoint(true);
13445
- moveEndPoint();
13446
-
13447
- return rng;
13448
- }
13449
-
13450
- function getLocation() {
13451
- var rng = selection.getRng(true), root = dom.getRoot(), bookmark = {};
13452
-
13453
- function getPoint(rng, start) {
13454
- var container = rng[start ? 'startContainer' : 'endContainer'],
13455
- offset = rng[start ? 'startOffset' : 'endOffset'], point = [], node, childNodes, after = 0;
13456
-
13457
- if (container.nodeType == 3) {
13458
- if (normalized) {
13459
- for (node = container.previousSibling; node && node.nodeType == 3; node = node.previousSibling) {
13460
- offset += node.nodeValue.length;
13461
- }
13462
- }
13463
-
13464
- point.push(offset);
13465
- } else {
13466
- childNodes = container.childNodes;
13467
-
13468
- if (offset >= childNodes.length && childNodes.length) {
13469
- after = 1;
13470
- offset = Math.max(0, childNodes.length - 1);
13471
- }
13472
-
13473
- point.push(dom.nodeIndex(childNodes[offset], normalized) + after);
13474
- }
13475
-
13476
- for (; container && container != root; container = container.parentNode) {
13477
- point.push(dom.nodeIndex(container, normalized));
13478
- }
13479
-
13480
- return point;
13481
- }
13482
-
13483
- bookmark.start = getPoint(rng, true);
13484
-
13485
- if (!selection.isCollapsed()) {
13486
- bookmark.end = getPoint(rng);
13487
- }
13488
-
13489
- return bookmark;
13490
- }
13491
-
13492
- if (type == 2) {
13493
- element = selection.getNode();
13494
- name = element ? element.nodeName : null;
13495
-
13496
- if (name == 'IMG') {
13497
- return {name: name, index: findIndex(name, element)};
13498
- }
13499
-
13500
- if (selection.tridentSel) {
13501
- return selection.tridentSel.getBookmark(type);
13502
- }
13503
-
13504
- return getLocation();
13505
- }
13506
-
13507
- // Handle simple range
13508
- if (type) {
13509
- return {rng: selection.getRng()};
13510
- }
13511
-
13512
- rng = selection.getRng();
13513
- id = dom.uniqueId();
13514
- collapsed = selection.isCollapsed();
13515
- styles = 'overflow:hidden;line-height:0px';
13516
-
13517
- // Explorer method
13518
- if (rng.duplicate || rng.item) {
13519
- // Text selection
13520
- if (!rng.item) {
13521
- rng2 = rng.duplicate();
13522
-
13523
- try {
13524
- // Insert start marker
13525
- rng.collapse();
13526
- rng.pasteHTML('<span data-mce-type="bookmark" id="' + id + '_start" style="' + styles + '">' + chr + '</span>');
13527
-
13528
- // Insert end marker
13529
- if (!collapsed) {
13530
- rng2.collapse(false);
13531
-
13532
- // Detect the empty space after block elements in IE and move the
13533
- // end back one character <p></p>] becomes <p>]</p>
13534
- rng.moveToElementText(rng2.parentElement());
13535
- if (rng.compareEndPoints('StartToEnd', rng2) === 0) {
13536
- rng2.move('character', -1);
13537
- }
13538
-
13539
- rng2.pasteHTML('<span data-mce-type="bookmark" id="' + id + '_end" style="' + styles + '">' + chr + '</span>');
13540
- }
13541
- } catch (ex) {
13542
- // IE might throw unspecified error so lets ignore it
13543
- return null;
13544
- }
13545
- } else {
13546
- // Control selection
13547
- element = rng.item(0);
13548
- name = element.nodeName;
13549
-
13550
- return {name: name, index: findIndex(name, element)};
13551
- }
13552
- } else {
13553
- element = selection.getNode();
13554
- name = element.nodeName;
13555
- if (name == 'IMG') {
13556
- return {name: name, index: findIndex(name, element)};
13557
- }
13558
-
13559
- // W3C method
13560
- rng2 = normalizeTableCellSelection(rng.cloneRange());
13561
-
13562
- // Insert end marker
13563
- if (!collapsed) {
13564
- rng2.collapse(false);
13565
- rng2.insertNode(dom.create('span', {'data-mce-type': "bookmark", id: id + '_end', style: styles}, chr));
13566
- }
13567
-
13568
- rng = normalizeTableCellSelection(rng);
13569
- rng.collapse(true);
13570
- rng.insertNode(dom.create('span', {'data-mce-type': "bookmark", id: id + '_start', style: styles}, chr));
13571
- }
13572
-
13573
- selection.moveToBookmark({id: id, keep: 1});
13574
-
13575
- return {id: id};
13576
- };
13577
-
13578
- /**
13579
- * Restores the selection to the specified bookmark.
13580
- *
13581
- * @method moveToBookmark
13582
- * @param {Object} bookmark Bookmark to restore selection from.
13583
- * @return {Boolean} true/false if it was successful or not.
13584
- * @example
13585
- * // Stores a bookmark of the current selection
13586
- * var bm = tinymce.activeEditor.selection.getBookmark();
13587
- *
13588
- * tinymce.activeEditor.setContent(tinymce.activeEditor.getContent() + 'Some new content');
13589
- *
13590
- * // Restore the selection bookmark
13591
- * tinymce.activeEditor.selection.moveToBookmark(bm);
13592
- */
13593
- this.moveToBookmark = function(bookmark) {
13594
- var rng, root, startContainer, endContainer, startOffset, endOffset;
13595
-
13596
- function setEndPoint(start) {
13597
- var point = bookmark[start ? 'start' : 'end'], i, node, offset, children;
13598
-
13599
- if (point) {
13600
- offset = point[0];
13601
-
13602
- // Find container node
13603
- for (node = root, i = point.length - 1; i >= 1; i--) {
13604
- children = node.childNodes;
13605
-
13606
- if (point[i] > children.length - 1) {
13607
- return;
13608
- }
13609
-
13610
- node = children[point[i]];
13611
- }
13612
-
13613
- // Move text offset to best suitable location
13614
- if (node.nodeType === 3) {
13615
- offset = Math.min(point[0], node.nodeValue.length);
13616
- }
13617
-
13618
- // Move element offset to best suitable location
13619
- if (node.nodeType === 1) {
13620
- offset = Math.min(point[0], node.childNodes.length);
13621
- }
13622
-
13623
- // Set offset within container node
13624
- if (start) {
13625
- rng.setStart(node, offset);
13626
- } else {
13627
- rng.setEnd(node, offset);
13628
- }
13629
- }
13630
-
13631
- return true;
13632
- }
13633
-
13634
- function restoreEndPoint(suffix) {
13635
- var marker = dom.get(bookmark.id + '_' + suffix), node, idx, next, prev, keep = bookmark.keep;
13636
-
13637
- if (marker) {
13638
- node = marker.parentNode;
13639
-
13640
- if (suffix == 'start') {
13641
- if (!keep) {
13642
- idx = dom.nodeIndex(marker);
13643
- } else {
13644
- node = marker.firstChild;
13645
- idx = 1;
13646
- }
13647
-
13648
- startContainer = endContainer = node;
13649
- startOffset = endOffset = idx;
13650
- } else {
13651
- if (!keep) {
13652
- idx = dom.nodeIndex(marker);
13653
- } else {
13654
- node = marker.firstChild;
13655
- idx = 1;
13656
- }
13657
-
13658
- endContainer = node;
13659
- endOffset = idx;
13660
- }
13661
-
13662
- if (!keep) {
13663
- prev = marker.previousSibling;
13664
- next = marker.nextSibling;
13665
-
13666
- // Remove all marker text nodes
13667
- Tools.each(Tools.grep(marker.childNodes), function(node) {
13668
- if (node.nodeType == 3) {
13669
- node.nodeValue = node.nodeValue.replace(/\uFEFF/g, '');
13670
- }
13671
- });
13672
-
13673
- // Remove marker but keep children if for example contents where inserted into the marker
13674
- // Also remove duplicated instances of the marker for example by a
13675
- // split operation or by WebKit auto split on paste feature
13676
- while ((marker = dom.get(bookmark.id + '_' + suffix))) {
13677
- dom.remove(marker, 1);
13678
- }
13679
-
13680
- // If siblings are text nodes then merge them unless it's Opera since it some how removes the node
13681
- // and we are sniffing since adding a lot of detection code for a browser with 3% of the market
13682
- // isn't worth the effort. Sorry, Opera but it's just a fact
13683
- if (prev && next && prev.nodeType == next.nodeType && prev.nodeType == 3 && !Env.opera) {
13684
- idx = prev.nodeValue.length;
13685
- prev.appendData(next.nodeValue);
13686
- dom.remove(next);
13687
-
13688
- if (suffix == 'start') {
13689
- startContainer = endContainer = prev;
13690
- startOffset = endOffset = idx;
13691
- } else {
13692
- endContainer = prev;
13693
- endOffset = idx;
13694
- }
13695
- }
13696
- }
13697
- }
13698
- }
13699
-
13700
- function addBogus(node) {
13701
- // Adds a bogus BR element for empty block elements
13702
- if (dom.isBlock(node) && !node.innerHTML && !Env.ie) {
13703
- node.innerHTML = '<br data-mce-bogus="1" />';
13704
- }
13705
-
13706
- return node;
13707
- }
13708
-
13709
- if (bookmark) {
13710
- if (bookmark.start) {
13711
- rng = dom.createRng();
13712
- root = dom.getRoot();
13713
-
13714
- if (selection.tridentSel) {
13715
- return selection.tridentSel.moveToBookmark(bookmark);
13716
- }
13717
-
13718
- if (setEndPoint(true) && setEndPoint()) {
13719
- selection.setRng(rng);
13720
- }
13721
- } else if (bookmark.id) {
13722
- // Restore start/end points
13723
- restoreEndPoint('start');
13724
- restoreEndPoint('end');
13725
-
13726
- if (startContainer) {
13727
- rng = dom.createRng();
13728
- rng.setStart(addBogus(startContainer), startOffset);
13729
- rng.setEnd(addBogus(endContainer), endOffset);
13730
- selection.setRng(rng);
13731
- }
13732
- } else if (bookmark.name) {
13733
- selection.select(dom.select(bookmark.name)[bookmark.index]);
13734
- } else if (bookmark.rng) {
13735
- selection.setRng(bookmark.rng);
13736
- }
13737
- }
13738
- };
13739
- }
13740
-
13741
- /**
13742
- * Returns true/false if the specified node is a bookmark node or not.
13743
- *
13744
- * @static
13745
- * @method isBookmarkNode
13746
- * @param {DOMNode} node DOM Node to check if it's a bookmark node or not.
13747
- * @return {Boolean} true/false if the node is a bookmark node or not.
13748
- */
13749
- BookmarkManager.isBookmarkNode = function(node) {
13750
- return node && node.tagName === 'SPAN' && node.getAttribute('data-mce-type') === 'bookmark';
13751
- };
13752
-
13753
- return BookmarkManager;
13366
+ /**
13367
+ * BookmarkManager.js
13368
+ *
13369
+ * Copyright, Moxiecode Systems AB
13370
+ * Released under LGPL License.
13371
+ *
13372
+ * License: http://www.tinymce.com/license
13373
+ * Contributing: http://www.tinymce.com/contributing
13374
+ */
13375
+
13376
+ /**
13377
+ * This class handles selection bookmarks.
13378
+ *
13379
+ * @class tinymce.dom.BookmarkManager
13380
+ */
13381
+ define("tinymce/dom/BookmarkManager", [
13382
+ "tinymce/Env",
13383
+ "tinymce/util/Tools"
13384
+ ], function(Env, Tools) {
13385
+ /**
13386
+ * Constructs a new BookmarkManager instance for a specific selection instance.
13387
+ *
13388
+ * @constructor
13389
+ * @method BookmarkManager
13390
+ * @param {tinymce.dom.Selection} selection Selection instance to handle bookmarks for.
13391
+ */
13392
+ function BookmarkManager(selection) {
13393
+ var dom = selection.dom;
13394
+
13395
+ /**
13396
+ * Returns a bookmark location for the current selection. This bookmark object
13397
+ * can then be used to restore the selection after some content modification to the document.
13398
+ *
13399
+ * @method getBookmark
13400
+ * @param {Number} type Optional state if the bookmark should be simple or not. Default is complex.
13401
+ * @param {Boolean} normalized Optional state that enables you to get a position that it would be after normalization.
13402
+ * @return {Object} Bookmark object, use moveToBookmark with this object to restore the selection.
13403
+ * @example
13404
+ * // Stores a bookmark of the current selection
13405
+ * var bm = tinymce.activeEditor.selection.getBookmark();
13406
+ *
13407
+ * tinymce.activeEditor.setContent(tinymce.activeEditor.getContent() + 'Some new content');
13408
+ *
13409
+ * // Restore the selection bookmark
13410
+ * tinymce.activeEditor.selection.moveToBookmark(bm);
13411
+ */
13412
+ this.getBookmark = function(type, normalized) {
13413
+ var rng, rng2, id, collapsed, name, element, chr = '&#xFEFF;', styles;
13414
+
13415
+ function findIndex(name, element) {
13416
+ var index = 0;
13417
+
13418
+ Tools.each(dom.select(name), function(node, i) {
13419
+ if (node == element) {
13420
+ index = i;
13421
+ }
13422
+ });
13423
+
13424
+ return index;
13425
+ }
13426
+
13427
+ function normalizeTableCellSelection(rng) {
13428
+ function moveEndPoint(start) {
13429
+ var container, offset, childNodes, prefix = start ? 'start' : 'end';
13430
+
13431
+ container = rng[prefix + 'Container'];
13432
+ offset = rng[prefix + 'Offset'];
13433
+
13434
+ if (container.nodeType == 1 && container.nodeName == "TR") {
13435
+ childNodes = container.childNodes;
13436
+ container = childNodes[Math.min(start ? offset : offset - 1, childNodes.length - 1)];
13437
+ if (container) {
13438
+ offset = start ? 0 : container.childNodes.length;
13439
+ rng['set' + (start ? 'Start' : 'End')](container, offset);
13440
+ }
13441
+ }
13442
+ }
13443
+
13444
+ moveEndPoint(true);
13445
+ moveEndPoint();
13446
+
13447
+ return rng;
13448
+ }
13449
+
13450
+ function getLocation() {
13451
+ var rng = selection.getRng(true), root = dom.getRoot(), bookmark = {};
13452
+
13453
+ function getPoint(rng, start) {
13454
+ var container = rng[start ? 'startContainer' : 'endContainer'],
13455
+ offset = rng[start ? 'startOffset' : 'endOffset'], point = [], node, childNodes, after = 0;
13456
+
13457
+ if (container.nodeType == 3) {
13458
+ if (normalized) {
13459
+ for (node = container.previousSibling; node && node.nodeType == 3; node = node.previousSibling) {
13460
+ offset += node.nodeValue.length;
13461
+ }
13462
+ }
13463
+
13464
+ point.push(offset);
13465
+ } else {
13466
+ childNodes = container.childNodes;
13467
+
13468
+ if (offset >= childNodes.length && childNodes.length) {
13469
+ after = 1;
13470
+ offset = Math.max(0, childNodes.length - 1);
13471
+ }
13472
+
13473
+ point.push(dom.nodeIndex(childNodes[offset], normalized) + after);
13474
+ }
13475
+
13476
+ for (; container && container != root; container = container.parentNode) {
13477
+ point.push(dom.nodeIndex(container, normalized));
13478
+ }
13479
+
13480
+ return point;
13481
+ }
13482
+
13483
+ bookmark.start = getPoint(rng, true);
13484
+
13485
+ if (!selection.isCollapsed()) {
13486
+ bookmark.end = getPoint(rng);
13487
+ }
13488
+
13489
+ return bookmark;
13490
+ }
13491
+
13492
+ if (type == 2) {
13493
+ element = selection.getNode();
13494
+ name = element ? element.nodeName : null;
13495
+
13496
+ if (name == 'IMG') {
13497
+ return {name: name, index: findIndex(name, element)};
13498
+ }
13499
+
13500
+ if (selection.tridentSel) {
13501
+ return selection.tridentSel.getBookmark(type);
13502
+ }
13503
+
13504
+ return getLocation();
13505
+ }
13506
+
13507
+ // Handle simple range
13508
+ if (type) {
13509
+ return {rng: selection.getRng()};
13510
+ }
13511
+
13512
+ rng = selection.getRng();
13513
+ id = dom.uniqueId();
13514
+ collapsed = selection.isCollapsed();
13515
+ styles = 'overflow:hidden;line-height:0px';
13516
+
13517
+ // Explorer method
13518
+ if (rng.duplicate || rng.item) {
13519
+ // Text selection
13520
+ if (!rng.item) {
13521
+ rng2 = rng.duplicate();
13522
+
13523
+ try {
13524
+ // Insert start marker
13525
+ rng.collapse();
13526
+ rng.pasteHTML('<span data-mce-type="bookmark" id="' + id + '_start" style="' + styles + '">' + chr + '</span>');
13527
+
13528
+ // Insert end marker
13529
+ if (!collapsed) {
13530
+ rng2.collapse(false);
13531
+
13532
+ // Detect the empty space after block elements in IE and move the
13533
+ // end back one character <p></p>] becomes <p>]</p>
13534
+ rng.moveToElementText(rng2.parentElement());
13535
+ if (rng.compareEndPoints('StartToEnd', rng2) === 0) {
13536
+ rng2.move('character', -1);
13537
+ }
13538
+
13539
+ rng2.pasteHTML('<span data-mce-type="bookmark" id="' + id + '_end" style="' + styles + '">' + chr + '</span>');
13540
+ }
13541
+ } catch (ex) {
13542
+ // IE might throw unspecified error so lets ignore it
13543
+ return null;
13544
+ }
13545
+ } else {
13546
+ // Control selection
13547
+ element = rng.item(0);
13548
+ name = element.nodeName;
13549
+
13550
+ return {name: name, index: findIndex(name, element)};
13551
+ }
13552
+ } else {
13553
+ element = selection.getNode();
13554
+ name = element.nodeName;
13555
+ if (name == 'IMG') {
13556
+ return {name: name, index: findIndex(name, element)};
13557
+ }
13558
+
13559
+ // W3C method
13560
+ rng2 = normalizeTableCellSelection(rng.cloneRange());
13561
+
13562
+ // Insert end marker
13563
+ if (!collapsed) {
13564
+ rng2.collapse(false);
13565
+ rng2.insertNode(dom.create('span', {'data-mce-type': "bookmark", id: id + '_end', style: styles}, chr));
13566
+ }
13567
+
13568
+ rng = normalizeTableCellSelection(rng);
13569
+ rng.collapse(true);
13570
+ rng.insertNode(dom.create('span', {'data-mce-type': "bookmark", id: id + '_start', style: styles}, chr));
13571
+ }
13572
+
13573
+ selection.moveToBookmark({id: id, keep: 1});
13574
+
13575
+ return {id: id};
13576
+ };
13577
+
13578
+ /**
13579
+ * Restores the selection to the specified bookmark.
13580
+ *
13581
+ * @method moveToBookmark
13582
+ * @param {Object} bookmark Bookmark to restore selection from.
13583
+ * @return {Boolean} true/false if it was successful or not.
13584
+ * @example
13585
+ * // Stores a bookmark of the current selection
13586
+ * var bm = tinymce.activeEditor.selection.getBookmark();
13587
+ *
13588
+ * tinymce.activeEditor.setContent(tinymce.activeEditor.getContent() + 'Some new content');
13589
+ *
13590
+ * // Restore the selection bookmark
13591
+ * tinymce.activeEditor.selection.moveToBookmark(bm);
13592
+ */
13593
+ this.moveToBookmark = function(bookmark) {
13594
+ var rng, root, startContainer, endContainer, startOffset, endOffset;
13595
+
13596
+ function setEndPoint(start) {
13597
+ var point = bookmark[start ? 'start' : 'end'], i, node, offset, children;
13598
+
13599
+ if (point) {
13600
+ offset = point[0];
13601
+
13602
+ // Find container node
13603
+ for (node = root, i = point.length - 1; i >= 1; i--) {
13604
+ children = node.childNodes;
13605
+
13606
+ if (point[i] > children.length - 1) {
13607
+ return;
13608
+ }
13609
+
13610
+ node = children[point[i]];
13611
+ }
13612
+
13613
+ // Move text offset to best suitable location
13614
+ if (node.nodeType === 3) {
13615
+ offset = Math.min(point[0], node.nodeValue.length);
13616
+ }
13617
+
13618
+ // Move element offset to best suitable location
13619
+ if (node.nodeType === 1) {
13620
+ offset = Math.min(point[0], node.childNodes.length);
13621
+ }
13622
+
13623
+ // Set offset within container node
13624
+ if (start) {
13625
+ rng.setStart(node, offset);
13626
+ } else {
13627
+ rng.setEnd(node, offset);
13628
+ }
13629
+ }
13630
+
13631
+ return true;
13632
+ }
13633
+
13634
+ function restoreEndPoint(suffix) {
13635
+ var marker = dom.get(bookmark.id + '_' + suffix), node, idx, next, prev, keep = bookmark.keep;
13636
+
13637
+ if (marker) {
13638
+ node = marker.parentNode;
13639
+
13640
+ if (suffix == 'start') {
13641
+ if (!keep) {
13642
+ idx = dom.nodeIndex(marker);
13643
+ } else {
13644
+ node = marker.firstChild;
13645
+ idx = 1;
13646
+ }
13647
+
13648
+ startContainer = endContainer = node;
13649
+ startOffset = endOffset = idx;
13650
+ } else {
13651
+ if (!keep) {
13652
+ idx = dom.nodeIndex(marker);
13653
+ } else {
13654
+ node = marker.firstChild;
13655
+ idx = 1;
13656
+ }
13657
+
13658
+ endContainer = node;
13659
+ endOffset = idx;
13660
+ }
13661
+
13662
+ if (!keep) {
13663
+ prev = marker.previousSibling;
13664
+ next = marker.nextSibling;
13665
+
13666
+ // Remove all marker text nodes
13667
+ Tools.each(Tools.grep(marker.childNodes), function(node) {
13668
+ if (node.nodeType == 3) {
13669
+ node.nodeValue = node.nodeValue.replace(/\uFEFF/g, '');
13670
+ }
13671
+ });
13672
+
13673
+ // Remove marker but keep children if for example contents where inserted into the marker
13674
+ // Also remove duplicated instances of the marker for example by a
13675
+ // split operation or by WebKit auto split on paste feature
13676
+ while ((marker = dom.get(bookmark.id + '_' + suffix))) {
13677
+ dom.remove(marker, 1);
13678
+ }
13679
+
13680
+ // If siblings are text nodes then merge them unless it's Opera since it some how removes the node
13681
+ // and we are sniffing since adding a lot of detection code for a browser with 3% of the market
13682
+ // isn't worth the effort. Sorry, Opera but it's just a fact
13683
+ if (prev && next && prev.nodeType == next.nodeType && prev.nodeType == 3 && !Env.opera) {
13684
+ idx = prev.nodeValue.length;
13685
+ prev.appendData(next.nodeValue);
13686
+ dom.remove(next);
13687
+
13688
+ if (suffix == 'start') {
13689
+ startContainer = endContainer = prev;
13690
+ startOffset = endOffset = idx;
13691
+ } else {
13692
+ endContainer = prev;
13693
+ endOffset = idx;
13694
+ }
13695
+ }
13696
+ }
13697
+ }
13698
+ }
13699
+
13700
+ function addBogus(node) {
13701
+ // Adds a bogus BR element for empty block elements
13702
+ if (dom.isBlock(node) && !node.innerHTML && !Env.ie) {
13703
+ node.innerHTML = '<br data-mce-bogus="1" />';
13704
+ }
13705
+
13706
+ return node;
13707
+ }
13708
+
13709
+ if (bookmark) {
13710
+ if (bookmark.start) {
13711
+ rng = dom.createRng();
13712
+ root = dom.getRoot();
13713
+
13714
+ if (selection.tridentSel) {
13715
+ return selection.tridentSel.moveToBookmark(bookmark);
13716
+ }
13717
+
13718
+ if (setEndPoint(true) && setEndPoint()) {
13719
+ selection.setRng(rng);
13720
+ }
13721
+ } else if (bookmark.id) {
13722
+ // Restore start/end points
13723
+ restoreEndPoint('start');
13724
+ restoreEndPoint('end');
13725
+
13726
+ if (startContainer) {
13727
+ rng = dom.createRng();
13728
+ rng.setStart(addBogus(startContainer), startOffset);
13729
+ rng.setEnd(addBogus(endContainer), endOffset);
13730
+ selection.setRng(rng);
13731
+ }
13732
+ } else if (bookmark.name) {
13733
+ selection.select(dom.select(bookmark.name)[bookmark.index]);
13734
+ } else if (bookmark.rng) {
13735
+ selection.setRng(bookmark.rng);
13736
+ }
13737
+ }
13738
+ };
13739
+ }
13740
+
13741
+ /**
13742
+ * Returns true/false if the specified node is a bookmark node or not.
13743
+ *
13744
+ * @static
13745
+ * @method isBookmarkNode
13746
+ * @param {DOMNode} node DOM Node to check if it's a bookmark node or not.
13747
+ * @return {Boolean} true/false if the node is a bookmark node or not.
13748
+ */
13749
+ BookmarkManager.isBookmarkNode = function(node) {
13750
+ return node && node.tagName === 'SPAN' && node.getAttribute('data-mce-type') === 'bookmark';
13751
+ };
13752
+
13753
+ return BookmarkManager;
13754
13754
  });
13755
13755
 
13756
13756
  // Included from: js/tinymce/classes/dom/Selection.js