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.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/app/assets/source/tinymce/tinymce.jquery.js +388 -388
- data/app/assets/source/tinymce/tinymce.js +388 -388
- data/lib/tinymce/rails/engine.rb +19 -5
- data/lib/tinymce/rails/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bbb5b0491068647580afdb55641b93c7e91934d3
|
4
|
+
data.tar.gz: 34adddab7097e20a69eafbb5a1d54c65cd66d8c0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3ce49cdff4a6fc645ee7db3274bb96ff164def6a64b3cc1ba1543d17a364cb17bc49a2d39a762185af7b110076679be9153fa1fdac05647cb534a533555d73fb
|
7
|
+
data.tar.gz: 74ccf99309c13c99b3b25cbbb3edebfd20b0e0125383a93811a6739b1df8dbfee279dfce8c3fe7e4b9733e28946d37fa7b1b9267536c0c38c89f403de0e5ebc7
|
data/LICENSE
CHANGED
@@ -10725,394 +10725,394 @@ define("tinymce/dom/RangeUtils", [
|
|
10725
10725
|
|
10726
10726
|
// Included from: js/tinymce/classes/dom/BookmarkManager.js
|
10727
10727
|
|
10728
|
-
/**
|
10729
|
-
* BookmarkManager.js
|
10730
|
-
*
|
10731
|
-
* Copyright, Moxiecode Systems AB
|
10732
|
-
* Released under LGPL License.
|
10733
|
-
*
|
10734
|
-
* License: http://www.tinymce.com/license
|
10735
|
-
* Contributing: http://www.tinymce.com/contributing
|
10736
|
-
*/
|
10737
|
-
|
10738
|
-
/**
|
10739
|
-
* This class handles selection bookmarks.
|
10740
|
-
*
|
10741
|
-
* @class tinymce.dom.BookmarkManager
|
10742
|
-
*/
|
10743
|
-
define("tinymce/dom/BookmarkManager", [
|
10744
|
-
"tinymce/Env",
|
10745
|
-
"tinymce/util/Tools"
|
10746
|
-
], function(Env, Tools) {
|
10747
|
-
/**
|
10748
|
-
* Constructs a new BookmarkManager instance for a specific selection instance.
|
10749
|
-
*
|
10750
|
-
* @constructor
|
10751
|
-
* @method BookmarkManager
|
10752
|
-
* @param {tinymce.dom.Selection} selection Selection instance to handle bookmarks for.
|
10753
|
-
*/
|
10754
|
-
function BookmarkManager(selection) {
|
10755
|
-
var dom = selection.dom;
|
10756
|
-
|
10757
|
-
/**
|
10758
|
-
* Returns a bookmark location for the current selection. This bookmark object
|
10759
|
-
* can then be used to restore the selection after some content modification to the document.
|
10760
|
-
*
|
10761
|
-
* @method getBookmark
|
10762
|
-
* @param {Number} type Optional state if the bookmark should be simple or not. Default is complex.
|
10763
|
-
* @param {Boolean} normalized Optional state that enables you to get a position that it would be after normalization.
|
10764
|
-
* @return {Object} Bookmark object, use moveToBookmark with this object to restore the selection.
|
10765
|
-
* @example
|
10766
|
-
* // Stores a bookmark of the current selection
|
10767
|
-
* var bm = tinymce.activeEditor.selection.getBookmark();
|
10768
|
-
*
|
10769
|
-
* tinymce.activeEditor.setContent(tinymce.activeEditor.getContent() + 'Some new content');
|
10770
|
-
*
|
10771
|
-
* // Restore the selection bookmark
|
10772
|
-
* tinymce.activeEditor.selection.moveToBookmark(bm);
|
10773
|
-
*/
|
10774
|
-
this.getBookmark = function(type, normalized) {
|
10775
|
-
var rng, rng2, id, collapsed, name, element, chr = '', styles;
|
10776
|
-
|
10777
|
-
function findIndex(name, element) {
|
10778
|
-
var index = 0;
|
10779
|
-
|
10780
|
-
Tools.each(dom.select(name), function(node, i) {
|
10781
|
-
if (node == element) {
|
10782
|
-
index = i;
|
10783
|
-
}
|
10784
|
-
});
|
10785
|
-
|
10786
|
-
return index;
|
10787
|
-
}
|
10788
|
-
|
10789
|
-
function normalizeTableCellSelection(rng) {
|
10790
|
-
function moveEndPoint(start) {
|
10791
|
-
var container, offset, childNodes, prefix = start ? 'start' : 'end';
|
10792
|
-
|
10793
|
-
container = rng[prefix + 'Container'];
|
10794
|
-
offset = rng[prefix + 'Offset'];
|
10795
|
-
|
10796
|
-
if (container.nodeType == 1 && container.nodeName == "TR") {
|
10797
|
-
childNodes = container.childNodes;
|
10798
|
-
container = childNodes[Math.min(start ? offset : offset - 1, childNodes.length - 1)];
|
10799
|
-
if (container) {
|
10800
|
-
offset = start ? 0 : container.childNodes.length;
|
10801
|
-
rng['set' + (start ? 'Start' : 'End')](container, offset);
|
10802
|
-
}
|
10803
|
-
}
|
10804
|
-
}
|
10805
|
-
|
10806
|
-
moveEndPoint(true);
|
10807
|
-
moveEndPoint();
|
10808
|
-
|
10809
|
-
return rng;
|
10810
|
-
}
|
10811
|
-
|
10812
|
-
function getLocation() {
|
10813
|
-
var rng = selection.getRng(true), root = dom.getRoot(), bookmark = {};
|
10814
|
-
|
10815
|
-
function getPoint(rng, start) {
|
10816
|
-
var container = rng[start ? 'startContainer' : 'endContainer'],
|
10817
|
-
offset = rng[start ? 'startOffset' : 'endOffset'], point = [], node, childNodes, after = 0;
|
10818
|
-
|
10819
|
-
if (container.nodeType == 3) {
|
10820
|
-
if (normalized) {
|
10821
|
-
for (node = container.previousSibling; node && node.nodeType == 3; node = node.previousSibling) {
|
10822
|
-
offset += node.nodeValue.length;
|
10823
|
-
}
|
10824
|
-
}
|
10825
|
-
|
10826
|
-
point.push(offset);
|
10827
|
-
} else {
|
10828
|
-
childNodes = container.childNodes;
|
10829
|
-
|
10830
|
-
if (offset >= childNodes.length && childNodes.length) {
|
10831
|
-
after = 1;
|
10832
|
-
offset = Math.max(0, childNodes.length - 1);
|
10833
|
-
}
|
10834
|
-
|
10835
|
-
point.push(dom.nodeIndex(childNodes[offset], normalized) + after);
|
10836
|
-
}
|
10837
|
-
|
10838
|
-
for (; container && container != root; container = container.parentNode) {
|
10839
|
-
point.push(dom.nodeIndex(container, normalized));
|
10840
|
-
}
|
10841
|
-
|
10842
|
-
return point;
|
10843
|
-
}
|
10844
|
-
|
10845
|
-
bookmark.start = getPoint(rng, true);
|
10846
|
-
|
10847
|
-
if (!selection.isCollapsed()) {
|
10848
|
-
bookmark.end = getPoint(rng);
|
10849
|
-
}
|
10850
|
-
|
10851
|
-
return bookmark;
|
10852
|
-
}
|
10853
|
-
|
10854
|
-
if (type == 2) {
|
10855
|
-
element = selection.getNode();
|
10856
|
-
name = element ? element.nodeName : null;
|
10857
|
-
|
10858
|
-
if (name == 'IMG') {
|
10859
|
-
return {name: name, index: findIndex(name, element)};
|
10860
|
-
}
|
10861
|
-
|
10862
|
-
if (selection.tridentSel) {
|
10863
|
-
return selection.tridentSel.getBookmark(type);
|
10864
|
-
}
|
10865
|
-
|
10866
|
-
return getLocation();
|
10867
|
-
}
|
10868
|
-
|
10869
|
-
// Handle simple range
|
10870
|
-
if (type) {
|
10871
|
-
return {rng: selection.getRng()};
|
10872
|
-
}
|
10873
|
-
|
10874
|
-
rng = selection.getRng();
|
10875
|
-
id = dom.uniqueId();
|
10876
|
-
collapsed = selection.isCollapsed();
|
10877
|
-
styles = 'overflow:hidden;line-height:0px';
|
10878
|
-
|
10879
|
-
// Explorer method
|
10880
|
-
if (rng.duplicate || rng.item) {
|
10881
|
-
// Text selection
|
10882
|
-
if (!rng.item) {
|
10883
|
-
rng2 = rng.duplicate();
|
10884
|
-
|
10885
|
-
try {
|
10886
|
-
// Insert start marker
|
10887
|
-
rng.collapse();
|
10888
|
-
rng.pasteHTML('<span data-mce-type="bookmark" id="' + id + '_start" style="' + styles + '">' + chr + '</span>');
|
10889
|
-
|
10890
|
-
// Insert end marker
|
10891
|
-
if (!collapsed) {
|
10892
|
-
rng2.collapse(false);
|
10893
|
-
|
10894
|
-
// Detect the empty space after block elements in IE and move the
|
10895
|
-
// end back one character <p></p>] becomes <p>]</p>
|
10896
|
-
rng.moveToElementText(rng2.parentElement());
|
10897
|
-
if (rng.compareEndPoints('StartToEnd', rng2) === 0) {
|
10898
|
-
rng2.move('character', -1);
|
10899
|
-
}
|
10900
|
-
|
10901
|
-
rng2.pasteHTML('<span data-mce-type="bookmark" id="' + id + '_end" style="' + styles + '">' + chr + '</span>');
|
10902
|
-
}
|
10903
|
-
} catch (ex) {
|
10904
|
-
// IE might throw unspecified error so lets ignore it
|
10905
|
-
return null;
|
10906
|
-
}
|
10907
|
-
} else {
|
10908
|
-
// Control selection
|
10909
|
-
element = rng.item(0);
|
10910
|
-
name = element.nodeName;
|
10911
|
-
|
10912
|
-
return {name: name, index: findIndex(name, element)};
|
10913
|
-
}
|
10914
|
-
} else {
|
10915
|
-
element = selection.getNode();
|
10916
|
-
name = element.nodeName;
|
10917
|
-
if (name == 'IMG') {
|
10918
|
-
return {name: name, index: findIndex(name, element)};
|
10919
|
-
}
|
10920
|
-
|
10921
|
-
// W3C method
|
10922
|
-
rng2 = normalizeTableCellSelection(rng.cloneRange());
|
10923
|
-
|
10924
|
-
// Insert end marker
|
10925
|
-
if (!collapsed) {
|
10926
|
-
rng2.collapse(false);
|
10927
|
-
rng2.insertNode(dom.create('span', {'data-mce-type': "bookmark", id: id + '_end', style: styles}, chr));
|
10928
|
-
}
|
10929
|
-
|
10930
|
-
rng = normalizeTableCellSelection(rng);
|
10931
|
-
rng.collapse(true);
|
10932
|
-
rng.insertNode(dom.create('span', {'data-mce-type': "bookmark", id: id + '_start', style: styles}, chr));
|
10933
|
-
}
|
10934
|
-
|
10935
|
-
selection.moveToBookmark({id: id, keep: 1});
|
10936
|
-
|
10937
|
-
return {id: id};
|
10938
|
-
};
|
10939
|
-
|
10940
|
-
/**
|
10941
|
-
* Restores the selection to the specified bookmark.
|
10942
|
-
*
|
10943
|
-
* @method moveToBookmark
|
10944
|
-
* @param {Object} bookmark Bookmark to restore selection from.
|
10945
|
-
* @return {Boolean} true/false if it was successful or not.
|
10946
|
-
* @example
|
10947
|
-
* // Stores a bookmark of the current selection
|
10948
|
-
* var bm = tinymce.activeEditor.selection.getBookmark();
|
10949
|
-
*
|
10950
|
-
* tinymce.activeEditor.setContent(tinymce.activeEditor.getContent() + 'Some new content');
|
10951
|
-
*
|
10952
|
-
* // Restore the selection bookmark
|
10953
|
-
* tinymce.activeEditor.selection.moveToBookmark(bm);
|
10954
|
-
*/
|
10955
|
-
this.moveToBookmark = function(bookmark) {
|
10956
|
-
var rng, root, startContainer, endContainer, startOffset, endOffset;
|
10957
|
-
|
10958
|
-
function setEndPoint(start) {
|
10959
|
-
var point = bookmark[start ? 'start' : 'end'], i, node, offset, children;
|
10960
|
-
|
10961
|
-
if (point) {
|
10962
|
-
offset = point[0];
|
10963
|
-
|
10964
|
-
// Find container node
|
10965
|
-
for (node = root, i = point.length - 1; i >= 1; i--) {
|
10966
|
-
children = node.childNodes;
|
10967
|
-
|
10968
|
-
if (point[i] > children.length - 1) {
|
10969
|
-
return;
|
10970
|
-
}
|
10971
|
-
|
10972
|
-
node = children[point[i]];
|
10973
|
-
}
|
10974
|
-
|
10975
|
-
// Move text offset to best suitable location
|
10976
|
-
if (node.nodeType === 3) {
|
10977
|
-
offset = Math.min(point[0], node.nodeValue.length);
|
10978
|
-
}
|
10979
|
-
|
10980
|
-
// Move element offset to best suitable location
|
10981
|
-
if (node.nodeType === 1) {
|
10982
|
-
offset = Math.min(point[0], node.childNodes.length);
|
10983
|
-
}
|
10984
|
-
|
10985
|
-
// Set offset within container node
|
10986
|
-
if (start) {
|
10987
|
-
rng.setStart(node, offset);
|
10988
|
-
} else {
|
10989
|
-
rng.setEnd(node, offset);
|
10990
|
-
}
|
10991
|
-
}
|
10992
|
-
|
10993
|
-
return true;
|
10994
|
-
}
|
10995
|
-
|
10996
|
-
function restoreEndPoint(suffix) {
|
10997
|
-
var marker = dom.get(bookmark.id + '_' + suffix), node, idx, next, prev, keep = bookmark.keep;
|
10998
|
-
|
10999
|
-
if (marker) {
|
11000
|
-
node = marker.parentNode;
|
11001
|
-
|
11002
|
-
if (suffix == 'start') {
|
11003
|
-
if (!keep) {
|
11004
|
-
idx = dom.nodeIndex(marker);
|
11005
|
-
} else {
|
11006
|
-
node = marker.firstChild;
|
11007
|
-
idx = 1;
|
11008
|
-
}
|
11009
|
-
|
11010
|
-
startContainer = endContainer = node;
|
11011
|
-
startOffset = endOffset = idx;
|
11012
|
-
} else {
|
11013
|
-
if (!keep) {
|
11014
|
-
idx = dom.nodeIndex(marker);
|
11015
|
-
} else {
|
11016
|
-
node = marker.firstChild;
|
11017
|
-
idx = 1;
|
11018
|
-
}
|
11019
|
-
|
11020
|
-
endContainer = node;
|
11021
|
-
endOffset = idx;
|
11022
|
-
}
|
11023
|
-
|
11024
|
-
if (!keep) {
|
11025
|
-
prev = marker.previousSibling;
|
11026
|
-
next = marker.nextSibling;
|
11027
|
-
|
11028
|
-
// Remove all marker text nodes
|
11029
|
-
Tools.each(Tools.grep(marker.childNodes), function(node) {
|
11030
|
-
if (node.nodeType == 3) {
|
11031
|
-
node.nodeValue = node.nodeValue.replace(/\uFEFF/g, '');
|
11032
|
-
}
|
11033
|
-
});
|
11034
|
-
|
11035
|
-
// Remove marker but keep children if for example contents where inserted into the marker
|
11036
|
-
// Also remove duplicated instances of the marker for example by a
|
11037
|
-
// split operation or by WebKit auto split on paste feature
|
11038
|
-
while ((marker = dom.get(bookmark.id + '_' + suffix))) {
|
11039
|
-
dom.remove(marker, 1);
|
11040
|
-
}
|
11041
|
-
|
11042
|
-
// If siblings are text nodes then merge them unless it's Opera since it some how removes the node
|
11043
|
-
// and we are sniffing since adding a lot of detection code for a browser with 3% of the market
|
11044
|
-
// isn't worth the effort. Sorry, Opera but it's just a fact
|
11045
|
-
if (prev && next && prev.nodeType == next.nodeType && prev.nodeType == 3 && !Env.opera) {
|
11046
|
-
idx = prev.nodeValue.length;
|
11047
|
-
prev.appendData(next.nodeValue);
|
11048
|
-
dom.remove(next);
|
11049
|
-
|
11050
|
-
if (suffix == 'start') {
|
11051
|
-
startContainer = endContainer = prev;
|
11052
|
-
startOffset = endOffset = idx;
|
11053
|
-
} else {
|
11054
|
-
endContainer = prev;
|
11055
|
-
endOffset = idx;
|
11056
|
-
}
|
11057
|
-
}
|
11058
|
-
}
|
11059
|
-
}
|
11060
|
-
}
|
11061
|
-
|
11062
|
-
function addBogus(node) {
|
11063
|
-
// Adds a bogus BR element for empty block elements
|
11064
|
-
if (dom.isBlock(node) && !node.innerHTML && !Env.ie) {
|
11065
|
-
node.innerHTML = '<br data-mce-bogus="1" />';
|
11066
|
-
}
|
11067
|
-
|
11068
|
-
return node;
|
11069
|
-
}
|
11070
|
-
|
11071
|
-
if (bookmark) {
|
11072
|
-
if (bookmark.start) {
|
11073
|
-
rng = dom.createRng();
|
11074
|
-
root = dom.getRoot();
|
11075
|
-
|
11076
|
-
if (selection.tridentSel) {
|
11077
|
-
return selection.tridentSel.moveToBookmark(bookmark);
|
11078
|
-
}
|
11079
|
-
|
11080
|
-
if (setEndPoint(true) && setEndPoint()) {
|
11081
|
-
selection.setRng(rng);
|
11082
|
-
}
|
11083
|
-
} else if (bookmark.id) {
|
11084
|
-
// Restore start/end points
|
11085
|
-
restoreEndPoint('start');
|
11086
|
-
restoreEndPoint('end');
|
11087
|
-
|
11088
|
-
if (startContainer) {
|
11089
|
-
rng = dom.createRng();
|
11090
|
-
rng.setStart(addBogus(startContainer), startOffset);
|
11091
|
-
rng.setEnd(addBogus(endContainer), endOffset);
|
11092
|
-
selection.setRng(rng);
|
11093
|
-
}
|
11094
|
-
} else if (bookmark.name) {
|
11095
|
-
selection.select(dom.select(bookmark.name)[bookmark.index]);
|
11096
|
-
} else if (bookmark.rng) {
|
11097
|
-
selection.setRng(bookmark.rng);
|
11098
|
-
}
|
11099
|
-
}
|
11100
|
-
};
|
11101
|
-
}
|
11102
|
-
|
11103
|
-
/**
|
11104
|
-
* Returns true/false if the specified node is a bookmark node or not.
|
11105
|
-
*
|
11106
|
-
* @static
|
11107
|
-
* @method isBookmarkNode
|
11108
|
-
* @param {DOMNode} node DOM Node to check if it's a bookmark node or not.
|
11109
|
-
* @return {Boolean} true/false if the node is a bookmark node or not.
|
11110
|
-
*/
|
11111
|
-
BookmarkManager.isBookmarkNode = function(node) {
|
11112
|
-
return node && node.tagName === 'SPAN' && node.getAttribute('data-mce-type') === 'bookmark';
|
11113
|
-
};
|
11114
|
-
|
11115
|
-
return BookmarkManager;
|
10728
|
+
/**
|
10729
|
+
* BookmarkManager.js
|
10730
|
+
*
|
10731
|
+
* Copyright, Moxiecode Systems AB
|
10732
|
+
* Released under LGPL License.
|
10733
|
+
*
|
10734
|
+
* License: http://www.tinymce.com/license
|
10735
|
+
* Contributing: http://www.tinymce.com/contributing
|
10736
|
+
*/
|
10737
|
+
|
10738
|
+
/**
|
10739
|
+
* This class handles selection bookmarks.
|
10740
|
+
*
|
10741
|
+
* @class tinymce.dom.BookmarkManager
|
10742
|
+
*/
|
10743
|
+
define("tinymce/dom/BookmarkManager", [
|
10744
|
+
"tinymce/Env",
|
10745
|
+
"tinymce/util/Tools"
|
10746
|
+
], function(Env, Tools) {
|
10747
|
+
/**
|
10748
|
+
* Constructs a new BookmarkManager instance for a specific selection instance.
|
10749
|
+
*
|
10750
|
+
* @constructor
|
10751
|
+
* @method BookmarkManager
|
10752
|
+
* @param {tinymce.dom.Selection} selection Selection instance to handle bookmarks for.
|
10753
|
+
*/
|
10754
|
+
function BookmarkManager(selection) {
|
10755
|
+
var dom = selection.dom;
|
10756
|
+
|
10757
|
+
/**
|
10758
|
+
* Returns a bookmark location for the current selection. This bookmark object
|
10759
|
+
* can then be used to restore the selection after some content modification to the document.
|
10760
|
+
*
|
10761
|
+
* @method getBookmark
|
10762
|
+
* @param {Number} type Optional state if the bookmark should be simple or not. Default is complex.
|
10763
|
+
* @param {Boolean} normalized Optional state that enables you to get a position that it would be after normalization.
|
10764
|
+
* @return {Object} Bookmark object, use moveToBookmark with this object to restore the selection.
|
10765
|
+
* @example
|
10766
|
+
* // Stores a bookmark of the current selection
|
10767
|
+
* var bm = tinymce.activeEditor.selection.getBookmark();
|
10768
|
+
*
|
10769
|
+
* tinymce.activeEditor.setContent(tinymce.activeEditor.getContent() + 'Some new content');
|
10770
|
+
*
|
10771
|
+
* // Restore the selection bookmark
|
10772
|
+
* tinymce.activeEditor.selection.moveToBookmark(bm);
|
10773
|
+
*/
|
10774
|
+
this.getBookmark = function(type, normalized) {
|
10775
|
+
var rng, rng2, id, collapsed, name, element, chr = '', styles;
|
10776
|
+
|
10777
|
+
function findIndex(name, element) {
|
10778
|
+
var index = 0;
|
10779
|
+
|
10780
|
+
Tools.each(dom.select(name), function(node, i) {
|
10781
|
+
if (node == element) {
|
10782
|
+
index = i;
|
10783
|
+
}
|
10784
|
+
});
|
10785
|
+
|
10786
|
+
return index;
|
10787
|
+
}
|
10788
|
+
|
10789
|
+
function normalizeTableCellSelection(rng) {
|
10790
|
+
function moveEndPoint(start) {
|
10791
|
+
var container, offset, childNodes, prefix = start ? 'start' : 'end';
|
10792
|
+
|
10793
|
+
container = rng[prefix + 'Container'];
|
10794
|
+
offset = rng[prefix + 'Offset'];
|
10795
|
+
|
10796
|
+
if (container.nodeType == 1 && container.nodeName == "TR") {
|
10797
|
+
childNodes = container.childNodes;
|
10798
|
+
container = childNodes[Math.min(start ? offset : offset - 1, childNodes.length - 1)];
|
10799
|
+
if (container) {
|
10800
|
+
offset = start ? 0 : container.childNodes.length;
|
10801
|
+
rng['set' + (start ? 'Start' : 'End')](container, offset);
|
10802
|
+
}
|
10803
|
+
}
|
10804
|
+
}
|
10805
|
+
|
10806
|
+
moveEndPoint(true);
|
10807
|
+
moveEndPoint();
|
10808
|
+
|
10809
|
+
return rng;
|
10810
|
+
}
|
10811
|
+
|
10812
|
+
function getLocation() {
|
10813
|
+
var rng = selection.getRng(true), root = dom.getRoot(), bookmark = {};
|
10814
|
+
|
10815
|
+
function getPoint(rng, start) {
|
10816
|
+
var container = rng[start ? 'startContainer' : 'endContainer'],
|
10817
|
+
offset = rng[start ? 'startOffset' : 'endOffset'], point = [], node, childNodes, after = 0;
|
10818
|
+
|
10819
|
+
if (container.nodeType == 3) {
|
10820
|
+
if (normalized) {
|
10821
|
+
for (node = container.previousSibling; node && node.nodeType == 3; node = node.previousSibling) {
|
10822
|
+
offset += node.nodeValue.length;
|
10823
|
+
}
|
10824
|
+
}
|
10825
|
+
|
10826
|
+
point.push(offset);
|
10827
|
+
} else {
|
10828
|
+
childNodes = container.childNodes;
|
10829
|
+
|
10830
|
+
if (offset >= childNodes.length && childNodes.length) {
|
10831
|
+
after = 1;
|
10832
|
+
offset = Math.max(0, childNodes.length - 1);
|
10833
|
+
}
|
10834
|
+
|
10835
|
+
point.push(dom.nodeIndex(childNodes[offset], normalized) + after);
|
10836
|
+
}
|
10837
|
+
|
10838
|
+
for (; container && container != root; container = container.parentNode) {
|
10839
|
+
point.push(dom.nodeIndex(container, normalized));
|
10840
|
+
}
|
10841
|
+
|
10842
|
+
return point;
|
10843
|
+
}
|
10844
|
+
|
10845
|
+
bookmark.start = getPoint(rng, true);
|
10846
|
+
|
10847
|
+
if (!selection.isCollapsed()) {
|
10848
|
+
bookmark.end = getPoint(rng);
|
10849
|
+
}
|
10850
|
+
|
10851
|
+
return bookmark;
|
10852
|
+
}
|
10853
|
+
|
10854
|
+
if (type == 2) {
|
10855
|
+
element = selection.getNode();
|
10856
|
+
name = element ? element.nodeName : null;
|
10857
|
+
|
10858
|
+
if (name == 'IMG') {
|
10859
|
+
return {name: name, index: findIndex(name, element)};
|
10860
|
+
}
|
10861
|
+
|
10862
|
+
if (selection.tridentSel) {
|
10863
|
+
return selection.tridentSel.getBookmark(type);
|
10864
|
+
}
|
10865
|
+
|
10866
|
+
return getLocation();
|
10867
|
+
}
|
10868
|
+
|
10869
|
+
// Handle simple range
|
10870
|
+
if (type) {
|
10871
|
+
return {rng: selection.getRng()};
|
10872
|
+
}
|
10873
|
+
|
10874
|
+
rng = selection.getRng();
|
10875
|
+
id = dom.uniqueId();
|
10876
|
+
collapsed = selection.isCollapsed();
|
10877
|
+
styles = 'overflow:hidden;line-height:0px';
|
10878
|
+
|
10879
|
+
// Explorer method
|
10880
|
+
if (rng.duplicate || rng.item) {
|
10881
|
+
// Text selection
|
10882
|
+
if (!rng.item) {
|
10883
|
+
rng2 = rng.duplicate();
|
10884
|
+
|
10885
|
+
try {
|
10886
|
+
// Insert start marker
|
10887
|
+
rng.collapse();
|
10888
|
+
rng.pasteHTML('<span data-mce-type="bookmark" id="' + id + '_start" style="' + styles + '">' + chr + '</span>');
|
10889
|
+
|
10890
|
+
// Insert end marker
|
10891
|
+
if (!collapsed) {
|
10892
|
+
rng2.collapse(false);
|
10893
|
+
|
10894
|
+
// Detect the empty space after block elements in IE and move the
|
10895
|
+
// end back one character <p></p>] becomes <p>]</p>
|
10896
|
+
rng.moveToElementText(rng2.parentElement());
|
10897
|
+
if (rng.compareEndPoints('StartToEnd', rng2) === 0) {
|
10898
|
+
rng2.move('character', -1);
|
10899
|
+
}
|
10900
|
+
|
10901
|
+
rng2.pasteHTML('<span data-mce-type="bookmark" id="' + id + '_end" style="' + styles + '">' + chr + '</span>');
|
10902
|
+
}
|
10903
|
+
} catch (ex) {
|
10904
|
+
// IE might throw unspecified error so lets ignore it
|
10905
|
+
return null;
|
10906
|
+
}
|
10907
|
+
} else {
|
10908
|
+
// Control selection
|
10909
|
+
element = rng.item(0);
|
10910
|
+
name = element.nodeName;
|
10911
|
+
|
10912
|
+
return {name: name, index: findIndex(name, element)};
|
10913
|
+
}
|
10914
|
+
} else {
|
10915
|
+
element = selection.getNode();
|
10916
|
+
name = element.nodeName;
|
10917
|
+
if (name == 'IMG') {
|
10918
|
+
return {name: name, index: findIndex(name, element)};
|
10919
|
+
}
|
10920
|
+
|
10921
|
+
// W3C method
|
10922
|
+
rng2 = normalizeTableCellSelection(rng.cloneRange());
|
10923
|
+
|
10924
|
+
// Insert end marker
|
10925
|
+
if (!collapsed) {
|
10926
|
+
rng2.collapse(false);
|
10927
|
+
rng2.insertNode(dom.create('span', {'data-mce-type': "bookmark", id: id + '_end', style: styles}, chr));
|
10928
|
+
}
|
10929
|
+
|
10930
|
+
rng = normalizeTableCellSelection(rng);
|
10931
|
+
rng.collapse(true);
|
10932
|
+
rng.insertNode(dom.create('span', {'data-mce-type': "bookmark", id: id + '_start', style: styles}, chr));
|
10933
|
+
}
|
10934
|
+
|
10935
|
+
selection.moveToBookmark({id: id, keep: 1});
|
10936
|
+
|
10937
|
+
return {id: id};
|
10938
|
+
};
|
10939
|
+
|
10940
|
+
/**
|
10941
|
+
* Restores the selection to the specified bookmark.
|
10942
|
+
*
|
10943
|
+
* @method moveToBookmark
|
10944
|
+
* @param {Object} bookmark Bookmark to restore selection from.
|
10945
|
+
* @return {Boolean} true/false if it was successful or not.
|
10946
|
+
* @example
|
10947
|
+
* // Stores a bookmark of the current selection
|
10948
|
+
* var bm = tinymce.activeEditor.selection.getBookmark();
|
10949
|
+
*
|
10950
|
+
* tinymce.activeEditor.setContent(tinymce.activeEditor.getContent() + 'Some new content');
|
10951
|
+
*
|
10952
|
+
* // Restore the selection bookmark
|
10953
|
+
* tinymce.activeEditor.selection.moveToBookmark(bm);
|
10954
|
+
*/
|
10955
|
+
this.moveToBookmark = function(bookmark) {
|
10956
|
+
var rng, root, startContainer, endContainer, startOffset, endOffset;
|
10957
|
+
|
10958
|
+
function setEndPoint(start) {
|
10959
|
+
var point = bookmark[start ? 'start' : 'end'], i, node, offset, children;
|
10960
|
+
|
10961
|
+
if (point) {
|
10962
|
+
offset = point[0];
|
10963
|
+
|
10964
|
+
// Find container node
|
10965
|
+
for (node = root, i = point.length - 1; i >= 1; i--) {
|
10966
|
+
children = node.childNodes;
|
10967
|
+
|
10968
|
+
if (point[i] > children.length - 1) {
|
10969
|
+
return;
|
10970
|
+
}
|
10971
|
+
|
10972
|
+
node = children[point[i]];
|
10973
|
+
}
|
10974
|
+
|
10975
|
+
// Move text offset to best suitable location
|
10976
|
+
if (node.nodeType === 3) {
|
10977
|
+
offset = Math.min(point[0], node.nodeValue.length);
|
10978
|
+
}
|
10979
|
+
|
10980
|
+
// Move element offset to best suitable location
|
10981
|
+
if (node.nodeType === 1) {
|
10982
|
+
offset = Math.min(point[0], node.childNodes.length);
|
10983
|
+
}
|
10984
|
+
|
10985
|
+
// Set offset within container node
|
10986
|
+
if (start) {
|
10987
|
+
rng.setStart(node, offset);
|
10988
|
+
} else {
|
10989
|
+
rng.setEnd(node, offset);
|
10990
|
+
}
|
10991
|
+
}
|
10992
|
+
|
10993
|
+
return true;
|
10994
|
+
}
|
10995
|
+
|
10996
|
+
function restoreEndPoint(suffix) {
|
10997
|
+
var marker = dom.get(bookmark.id + '_' + suffix), node, idx, next, prev, keep = bookmark.keep;
|
10998
|
+
|
10999
|
+
if (marker) {
|
11000
|
+
node = marker.parentNode;
|
11001
|
+
|
11002
|
+
if (suffix == 'start') {
|
11003
|
+
if (!keep) {
|
11004
|
+
idx = dom.nodeIndex(marker);
|
11005
|
+
} else {
|
11006
|
+
node = marker.firstChild;
|
11007
|
+
idx = 1;
|
11008
|
+
}
|
11009
|
+
|
11010
|
+
startContainer = endContainer = node;
|
11011
|
+
startOffset = endOffset = idx;
|
11012
|
+
} else {
|
11013
|
+
if (!keep) {
|
11014
|
+
idx = dom.nodeIndex(marker);
|
11015
|
+
} else {
|
11016
|
+
node = marker.firstChild;
|
11017
|
+
idx = 1;
|
11018
|
+
}
|
11019
|
+
|
11020
|
+
endContainer = node;
|
11021
|
+
endOffset = idx;
|
11022
|
+
}
|
11023
|
+
|
11024
|
+
if (!keep) {
|
11025
|
+
prev = marker.previousSibling;
|
11026
|
+
next = marker.nextSibling;
|
11027
|
+
|
11028
|
+
// Remove all marker text nodes
|
11029
|
+
Tools.each(Tools.grep(marker.childNodes), function(node) {
|
11030
|
+
if (node.nodeType == 3) {
|
11031
|
+
node.nodeValue = node.nodeValue.replace(/\uFEFF/g, '');
|
11032
|
+
}
|
11033
|
+
});
|
11034
|
+
|
11035
|
+
// Remove marker but keep children if for example contents where inserted into the marker
|
11036
|
+
// Also remove duplicated instances of the marker for example by a
|
11037
|
+
// split operation or by WebKit auto split on paste feature
|
11038
|
+
while ((marker = dom.get(bookmark.id + '_' + suffix))) {
|
11039
|
+
dom.remove(marker, 1);
|
11040
|
+
}
|
11041
|
+
|
11042
|
+
// If siblings are text nodes then merge them unless it's Opera since it some how removes the node
|
11043
|
+
// and we are sniffing since adding a lot of detection code for a browser with 3% of the market
|
11044
|
+
// isn't worth the effort. Sorry, Opera but it's just a fact
|
11045
|
+
if (prev && next && prev.nodeType == next.nodeType && prev.nodeType == 3 && !Env.opera) {
|
11046
|
+
idx = prev.nodeValue.length;
|
11047
|
+
prev.appendData(next.nodeValue);
|
11048
|
+
dom.remove(next);
|
11049
|
+
|
11050
|
+
if (suffix == 'start') {
|
11051
|
+
startContainer = endContainer = prev;
|
11052
|
+
startOffset = endOffset = idx;
|
11053
|
+
} else {
|
11054
|
+
endContainer = prev;
|
11055
|
+
endOffset = idx;
|
11056
|
+
}
|
11057
|
+
}
|
11058
|
+
}
|
11059
|
+
}
|
11060
|
+
}
|
11061
|
+
|
11062
|
+
function addBogus(node) {
|
11063
|
+
// Adds a bogus BR element for empty block elements
|
11064
|
+
if (dom.isBlock(node) && !node.innerHTML && !Env.ie) {
|
11065
|
+
node.innerHTML = '<br data-mce-bogus="1" />';
|
11066
|
+
}
|
11067
|
+
|
11068
|
+
return node;
|
11069
|
+
}
|
11070
|
+
|
11071
|
+
if (bookmark) {
|
11072
|
+
if (bookmark.start) {
|
11073
|
+
rng = dom.createRng();
|
11074
|
+
root = dom.getRoot();
|
11075
|
+
|
11076
|
+
if (selection.tridentSel) {
|
11077
|
+
return selection.tridentSel.moveToBookmark(bookmark);
|
11078
|
+
}
|
11079
|
+
|
11080
|
+
if (setEndPoint(true) && setEndPoint()) {
|
11081
|
+
selection.setRng(rng);
|
11082
|
+
}
|
11083
|
+
} else if (bookmark.id) {
|
11084
|
+
// Restore start/end points
|
11085
|
+
restoreEndPoint('start');
|
11086
|
+
restoreEndPoint('end');
|
11087
|
+
|
11088
|
+
if (startContainer) {
|
11089
|
+
rng = dom.createRng();
|
11090
|
+
rng.setStart(addBogus(startContainer), startOffset);
|
11091
|
+
rng.setEnd(addBogus(endContainer), endOffset);
|
11092
|
+
selection.setRng(rng);
|
11093
|
+
}
|
11094
|
+
} else if (bookmark.name) {
|
11095
|
+
selection.select(dom.select(bookmark.name)[bookmark.index]);
|
11096
|
+
} else if (bookmark.rng) {
|
11097
|
+
selection.setRng(bookmark.rng);
|
11098
|
+
}
|
11099
|
+
}
|
11100
|
+
};
|
11101
|
+
}
|
11102
|
+
|
11103
|
+
/**
|
11104
|
+
* Returns true/false if the specified node is a bookmark node or not.
|
11105
|
+
*
|
11106
|
+
* @static
|
11107
|
+
* @method isBookmarkNode
|
11108
|
+
* @param {DOMNode} node DOM Node to check if it's a bookmark node or not.
|
11109
|
+
* @return {Boolean} true/false if the node is a bookmark node or not.
|
11110
|
+
*/
|
11111
|
+
BookmarkManager.isBookmarkNode = function(node) {
|
11112
|
+
return node && node.tagName === 'SPAN' && node.getAttribute('data-mce-type') === 'bookmark';
|
11113
|
+
};
|
11114
|
+
|
11115
|
+
return BookmarkManager;
|
11116
11116
|
});
|
11117
11117
|
|
11118
11118
|
// Included from: js/tinymce/classes/dom/Selection.js
|