tinymce-rails 4.0.28 → 4.0.28.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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