wigjs
Version:
Minimalistic, scalable, extensible, dependency-less Front-end factory for HTML5 applications
100 lines (80 loc) • 2.71 kB
JavaScript
var Selection = module.Selection = Class.extend({
constructor: function (DOM) {
this.DOM = DOM;
this.id = undefined;
this.path = undefined;
this.start = 0;
this.end = 0;
},
preserveSelection: function () {
var node = wig.env.getFocusedElement();
this.start = node.selectionStart;
this.end = node.selectionEnd;
},
getIndexOfNode: function (node, viewNode) {
var path = [];
do {
path.push(node.classList[0] ||
arrayIndexOf.call(node.parentNode.children, node));
node = node.parentNode;
} while (node !== viewNode);
return path;
},
preserveSelectionInView: function (updatingView) {
var node = wig.env.getFocusedElement(),
focusedViewID = this.DOM.findClosestViewNode(node, VIEW_DATA_ATTRIBUTE),
updatingViewID = updatingView.getID(),
viewNode;
if (focusedViewID && focusedViewID === updatingViewID) {
try {
this.preserveSelection();
} catch (e) {}
viewNode = updatingView.getNode();
this.id = updatingViewID;
if (node !== viewNode) {
this.path = (node.id || this.getIndexOfNode(node, viewNode));
}
}
},
restoreSelection: function (node) {
if (typeof node.setSelectionRange !== 'function') {
return;
}
node.setSelectionRange(this.start, this.end);
},
findNodeByIndex: function (index, node) {
if (typeof index === 'number') {
node = node.children[index];
} else {
node = node.children[0];
if (node.classList[0] !== index) {
do {
node = node.nextSibling;
} while (node.classList[0] !== index);
}
}
return node;
},
restoreSelectionInView: function (view) {
// place focus in the node
var node = view.getNode(),
path = this.path,
index;
if (this.id && this.id === view.getID()) {
if (path && path.length > 0) {
do {
// dig down to find focused node
index = path.pop();
node = this.findNodeByIndex(index, node);
} while (path.length !== 0);
}
// restore selection if node is an editable element
try {
this.restoreSelection(node);
} catch (e) {}
node.focus();
this.id = undefined;
this.path = undefined;
}
}
});