mirror of
https://github.com/UnickSoft/graphonline.git
synced 2026-06-17 06:11:37 +00:00
first commit
This commit is contained in:
Executable
+166
@@ -0,0 +1,166 @@
|
||||
(function() {
|
||||
|
||||
var exports = this, Bookmark;
|
||||
|
||||
Bookmark = function(env, range, keepOldBookmarks) {
|
||||
|
||||
this.env = env;
|
||||
this.element = env.element;
|
||||
this.selection = this.env.selection;
|
||||
|
||||
// Remove all bookmarks?
|
||||
if (!keepOldBookmarks) {
|
||||
this.removeBookmarks(this.element);
|
||||
}
|
||||
|
||||
var currRange = range || this.selection.getRangeAt(0);
|
||||
range = currRange.cloneRange();
|
||||
var startContainer = range.startContainer;
|
||||
var endContainer = range.endContainer;
|
||||
var startOffset = range.startOffset;
|
||||
var endOffset = range.endOffset;
|
||||
var tmp;
|
||||
|
||||
// Collapse to the end of range.
|
||||
range.collapse(false);
|
||||
|
||||
var endBookmark = this.env.document.createElement('span');
|
||||
endBookmark.style.display = 'none';
|
||||
ice.dom.setHtml(endBookmark, ' ');
|
||||
ice.dom.addClass(endBookmark, 'iceBookmark iceBookmark_end');
|
||||
endBookmark.setAttribute('iceBookmark', 'end');
|
||||
range.insertNode(endBookmark);
|
||||
if(!ice.dom.isChildOf(endBookmark, this.element)) {
|
||||
this.element.appendChild(endBookmark);
|
||||
}
|
||||
|
||||
// Move the range to where it was before.
|
||||
range.setStart(startContainer, startOffset);
|
||||
range.collapse(true);
|
||||
|
||||
// Create the start bookmark.
|
||||
var startBookmark = this.env.document.createElement('span');
|
||||
startBookmark.style.display = 'none';
|
||||
ice.dom.addClass(startBookmark, 'iceBookmark iceBookmark_start');
|
||||
ice.dom.setHtml(startBookmark, ' ');
|
||||
startBookmark.setAttribute('iceBookmark', 'start');
|
||||
try {
|
||||
range.insertNode(startBookmark);
|
||||
|
||||
// Make sure start and end are in correct position.
|
||||
if (startBookmark.previousSibling === endBookmark) {
|
||||
// Reverse..
|
||||
tmp = startBookmark;
|
||||
startBookmark = endBookmark;
|
||||
endBookmark = tmp;
|
||||
}
|
||||
} catch (e) {
|
||||
// NS_ERROR_UNEXPECTED: I believe this is a Firefox bug.
|
||||
// It seems like if the range is collapsed and the text node is empty
|
||||
// (i.e. length = 0) then Firefox tries to split the node for no reason and fails...
|
||||
ice.dom.insertBefore(endBookmark, startBookmark);
|
||||
}
|
||||
|
||||
if (ice.dom.isChildOf(startBookmark, this.element) === false) {
|
||||
if (this.element.firstChild) {
|
||||
ice.dom.insertBefore(this.element.firstChild, startBookmark);
|
||||
} else {
|
||||
// Should not happen...
|
||||
this.element.appendChild(startBookmark);
|
||||
}
|
||||
}
|
||||
|
||||
if (!endBookmark.previousSibling) {
|
||||
tmp = this.env.document.createTextNode('');
|
||||
ice.dom.insertBefore(endBookmark, tmp);
|
||||
}
|
||||
|
||||
// The original range object must be changed.
|
||||
if (!startBookmark.nextSibling) {
|
||||
tmp = this.env.document.createTextNode('');
|
||||
ice.dom.insertAfter(startBookmark, tmp);
|
||||
}
|
||||
|
||||
currRange.setStart(startBookmark.nextSibling, 0);
|
||||
currRange.setEnd(endBookmark.previousSibling, (endBookmark.previousSibling.length || 0));
|
||||
|
||||
this.start = startBookmark;
|
||||
this.end = endBookmark;
|
||||
};
|
||||
|
||||
Bookmark.prototype = {
|
||||
|
||||
selectBookmark: function() {
|
||||
var range = this.selection.getRangeAt(0);
|
||||
var startPos = null;
|
||||
var endPos = null;
|
||||
var startOffset = 0;
|
||||
var endOffset = null;
|
||||
if (this.start.nextSibling === this.end || ice.dom.getElementsBetween(this.start, this.end).length === 0) {
|
||||
// Bookmark is collapsed.
|
||||
if (this.end.nextSibling) {
|
||||
startPos = ice.dom.getFirstChild(this.end.nextSibling);
|
||||
} else if (this.start.previousSibling) {
|
||||
startPos = ice.dom.getFirstChild(this.start.previousSibling);
|
||||
if (startPos.nodeType === ice.dom.TEXT_NODE) {
|
||||
startOffset = startPos.length;
|
||||
}
|
||||
} else {
|
||||
// Create a text node in parent.
|
||||
this.end.parentNode.appendChild(this.env.document.createTextNode(''));
|
||||
startPos = ice.dom.getFirstChild(this.end.nextSibling);
|
||||
}
|
||||
} else {
|
||||
if (this.start.nextSibling) {
|
||||
startPos = ice.dom.getFirstChild(this.start.nextSibling);
|
||||
} else {
|
||||
if (!this.start.previousSibling) {
|
||||
var tmp = this.env.document.createTextNode('');
|
||||
ice.dom.insertBefore(this.start, tmp);
|
||||
}
|
||||
|
||||
startPos = ice.dom.getLastChild(this.start.previousSibling);
|
||||
startOffset = startPos.length;
|
||||
}
|
||||
|
||||
if (this.end.previousSibling) {
|
||||
endPos = ice.dom.getLastChild(this.end.previousSibling);
|
||||
} else {
|
||||
endPos = ice.dom.getFirstChild(this.end.nextSibling || this.end);
|
||||
endOffset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ice.dom.remove([this.start, this.end]);
|
||||
|
||||
if (endPos === null) {
|
||||
range.setEnd(startPos, startOffset);
|
||||
range.collapse(false);
|
||||
} else {
|
||||
range.setStart(startPos, startOffset);
|
||||
if (endOffset === null) {
|
||||
endOffset = (endPos.length || 0);
|
||||
}
|
||||
range.setEnd(endPos, endOffset);
|
||||
}
|
||||
|
||||
try {
|
||||
this.selection.addRange(range);
|
||||
} catch (e) {
|
||||
// IE may throw exception for hidden elements..
|
||||
}
|
||||
},
|
||||
|
||||
getBookmark: function(parent, type) {
|
||||
var elem = ice.dom.getClass('iceBookmark_' + type, parent)[0];
|
||||
return elem;
|
||||
},
|
||||
|
||||
removeBookmarks: function(elem) {
|
||||
ice.dom.remove(ice.dom.getClass('iceBookmark', elem, 'span'));
|
||||
}
|
||||
};
|
||||
|
||||
exports.Bookmark = Bookmark;
|
||||
|
||||
}).call(this.ice);
|
||||
Reference in New Issue
Block a user