diff options
Diffstat (limited to 'includes/js/dijit/_editor/selection.js')
-rw-r--r-- | includes/js/dijit/_editor/selection.js | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/includes/js/dijit/_editor/selection.js b/includes/js/dijit/_editor/selection.js new file mode 100644 index 0000000..9b403aa --- /dev/null +++ b/includes/js/dijit/_editor/selection.js @@ -0,0 +1,246 @@ +if(!dojo._hasResource["dijit._editor.selection"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit._editor.selection"] = true; +dojo.provide("dijit._editor.selection"); + +// FIXME: +// all of these methods branch internally for IE. This is probably +// sub-optimal in terms of runtime performance. We should investigate the +// size difference for differentiating at definition time. + +dojo.mixin(dijit._editor.selection, { + getType: function(){ + // summary: Get the selection type (like dojo.doc.select.type in IE). + if(dojo.doc.selection){ //IE + return dojo.doc.selection.type.toLowerCase(); + }else{ + var stype = "text"; + + // Check if the actual selection is a CONTROL (IMG, TABLE, HR, etc...). + var oSel; + try{ + oSel = dojo.global.getSelection(); + }catch(e){ /*squelch*/ } + + if(oSel && oSel.rangeCount==1){ + var oRange = oSel.getRangeAt(0); + if( (oRange.startContainer == oRange.endContainer) && + ((oRange.endOffset - oRange.startOffset) == 1) && + (oRange.startContainer.nodeType != 3 /* text node*/) + ){ + stype = "control"; + } + } + return stype; + } + }, + + getSelectedText: function(){ + // summary: + // Return the text (no html tags) included in the current selection or null if no text is selected + if(dojo.doc.selection){ //IE + if(dijit._editor.selection.getType() == 'control'){ + return null; + } + return dojo.doc.selection.createRange().text; + }else{ + var selection = dojo.global.getSelection(); + if(selection){ + return selection.toString(); + } + } + return '' + }, + + getSelectedHtml: function(){ + // summary: + // Return the html of the current selection or null if unavailable + if(dojo.doc.selection){ //IE + if(dijit._editor.selection.getType() == 'control'){ + return null; + } + return dojo.doc.selection.createRange().htmlText; + }else{ + var selection = dojo.global.getSelection(); + if(selection && selection.rangeCount){ + var frag = selection.getRangeAt(0).cloneContents(); + var div = dojo.doc.createElement("div"); + div.appendChild(frag); + return div.innerHTML; + } + return null; + } + }, + + getSelectedElement: function(){ + // summary: + // Retrieves the selected element (if any), just in the case that + // a single element (object like and image or a table) is + // selected. + if(this.getType() == "control"){ + if(dojo.doc.selection){ //IE + var range = dojo.doc.selection.createRange(); + if(range && range.item){ + return dojo.doc.selection.createRange().item(0); + } + }else{ + var selection = dojo.global.getSelection(); + return selection.anchorNode.childNodes[ selection.anchorOffset ]; + } + } + return null; + }, + + getParentElement: function(){ + // summary: + // Get the parent element of the current selection + if(this.getType() == "control"){ + var p = this.getSelectedElement(); + if(p){ return p.parentNode; } + }else{ + if(dojo.doc.selection){ //IE + return dojo.doc.selection.createRange().parentElement(); + }else{ + var selection = dojo.global.getSelection(); + if(selection){ + var node = selection.anchorNode; + + while(node && (node.nodeType != 1)){ // not an element + node = node.parentNode; + } + + return node; + } + } + } + return null; + }, + + hasAncestorElement: function(/*String*/tagName /* ... */){ + // summary: + // Check whether current selection has a parent element which is + // of type tagName (or one of the other specified tagName) + return this.getAncestorElement.apply(this, arguments) != null; + }, + + getAncestorElement: function(/*String*/tagName /* ... */){ + // summary: + // Return the parent element of the current selection which is of + // type tagName (or one of the other specified tagName) + + var node = this.getSelectedElement() || this.getParentElement(); + return this.getParentOfType(node, arguments); + }, + + isTag: function(/*DomNode*/node, /*Array*/tags){ + if(node && node.tagName){ + var _nlc = node.tagName.toLowerCase(); + for(var i=0; i<tags.length; i++){ + var _tlc = String(tags[i]).toLowerCase(); + if(_nlc == _tlc){ + return _tlc; + } + } + } + return ""; + }, + + getParentOfType: function(/*DomNode*/node, /*Array*/tags){ + while(node){ + if(this.isTag(node, tags).length){ + return node; + } + node = node.parentNode; + } + return null; + }, + + collapse: function(/*Boolean*/beginning) { + // summary: clear current selection + if(window['getSelection']){ + var selection = dojo.global.getSelection(); + if(selection.removeAllRanges){ // Mozilla + if(beginning){ + selection.collapseToStart(); + }else{ + selection.collapseToEnd(); + } + }else{ // Safari + // pulled from WebCore/ecma/kjs_window.cpp, line 2536 + selection.collapse(beginning); + } + }else if(dojo.doc.selection){ // IE + var range = dojo.doc.selection.createRange(); + range.collapse(beginning); + range.select(); + } + }, + + remove: function(){ + // summary: delete current selection + var _s = dojo.doc.selection; + if(_s){ //IE + if(_s.type.toLowerCase() != "none"){ + _s.clear(); + } + return _s; + }else{ + _s = dojo.global.getSelection(); + _s.deleteFromDocument(); + return _s; + } + }, + + selectElementChildren: function(/*DomNode*/element,/*Boolean?*/nochangefocus){ + // summary: + // clear previous selection and select the content of the node + // (excluding the node itself) + var _window = dojo.global; + var _document = dojo.doc; + element = dojo.byId(element); + if(_document.selection && dojo.body().createTextRange){ // IE + var range = element.ownerDocument.body.createTextRange(); + range.moveToElementText(element); + if(!nochangefocus){ + try{ + range.select(); // IE throws an exception here if the widget is hidden. See #5439 + }catch(e){ /* squelch */} + } + }else if(_window.getSelection){ + var selection = _window.getSelection(); + if(selection.setBaseAndExtent){ // Safari + selection.setBaseAndExtent(element, 0, element, element.innerText.length - 1); + }else if(selection.selectAllChildren){ // Mozilla + selection.selectAllChildren(element); + } + } + }, + + selectElement: function(/*DomNode*/element,/*Boolean?*/nochangefocus){ + // summary: + // clear previous selection and select element (including all its children) + var range, _document = dojo.doc; + element = dojo.byId(element); + if(_document.selection && dojo.body().createTextRange){ // IE + try{ + range = dojo.body().createControlRange(); + range.addElement(element); + if(!nochangefocus){ + range.select(); + } + }catch(e){ + this.selectElementChildren(element,nochangefocus); + } + }else if(dojo.global.getSelection){ + var selection = dojo.global.getSelection(); + // FIXME: does this work on Safari? + if(selection.removeAllRanges){ // Mozilla + range = _document.createRange(); + range.selectNode(element); + selection.removeAllRanges(); + selection.addRange(range); + } + } + } +}); + +} |