]>
git.wh0rd.org - tt-rss.git/blob - lib/dijit/_editor/selection.js.uncompressed.js
1 define("dijit/_editor/selection", [
2 "dojo/dom", // dom.byId
4 "dojo/_base/sniff", // has("ie") has("opera")
5 "dojo/_base/window", // win.body win.doc win.doc.createElement win.doc.selection win.doc.selection.createRange win.doc.selection.type.toLowerCase win.global win.global.getSelection
6 ".." // for exporting symbols to dijit._editor.selection (TODO: remove in 2.0)
7 ], function(dom
, lang
, has
, win
, dijit
){
10 // dijit/_editor/selection
15 lang
.getObject("_editor.selection", true, dijit
);
18 // all of these methods branch internally for IE. This is probably
19 // sub-optimal in terms of runtime performance. We should investigate the
20 // size difference for differentiating at definition time.
22 lang
.mixin(dijit
._editor
.selection
, {
25 // Get the selection type (like win.doc.select.type in IE).
27 return win
.doc
.selection
.type
.toLowerCase();
31 // Check if the actual selection is a CONTROL (IMG, TABLE, HR, etc...).
34 oSel
= win
.global
.getSelection();
35 }catch(e
){ /*squelch*/ }
37 if(oSel
&& oSel
.rangeCount
== 1){
38 var oRange
= oSel
.getRangeAt(0);
39 if( (oRange
.startContainer
== oRange
.endContainer
) &&
40 ((oRange
.endOffset
- oRange
.startOffset
) == 1) &&
41 (oRange
.startContainer
.nodeType
!= 3 /* text node*/)
46 return stype
; //String
50 getSelectedText: function(){
52 // Return the text (no html tags) included in the current selection or null if no text is selected
54 if(dijit
._editor
.selection
.getType() == 'control'){
57 return win
.doc
.selection
.createRange().text
;
59 var selection
= win
.global
.getSelection();
61 return selection
.toString(); //String
67 getSelectedHtml: function(){
69 // Return the html text of the current selection or null if unavailable
71 if(dijit
._editor
.selection
.getType() == 'control'){
74 return win
.doc
.selection
.createRange().htmlText
;
76 var selection
= win
.global
.getSelection();
77 if(selection
&& selection
.rangeCount
){
80 for(i
= 0; i
< selection
.rangeCount
; i
++){
81 //Handle selections spanning ranges, such as Opera
82 var frag
= selection
.getRangeAt(i
).cloneContents();
83 var div
= win
.doc
.createElement("div");
84 div
.appendChild(frag
);
85 html
+= div
.innerHTML
;
93 getSelectedElement: function(){
95 // Retrieves the selected element (if any), just in the case that
96 // a single element (object like and image or a table) is
98 if(dijit
._editor
.selection
.getType() == "control"){
100 var range
= win
.doc
.selection
.createRange();
101 if(range
&& range
.item
){
102 return win
.doc
.selection
.createRange().item(0);
105 var selection
= win
.global
.getSelection();
106 return selection
.anchorNode
.childNodes
[ selection
.anchorOffset
];
112 getParentElement: function(){
114 // Get the parent element of the current selection
115 if(dijit
._editor
.selection
.getType() == "control"){
116 var p
= this.getSelectedElement();
117 if(p
){ return p
.parentNode
; }
120 var r
= win
.doc
.selection
.createRange();
122 return r
.parentElement();
124 var selection
= win
.global
.getSelection();
126 var node
= selection
.anchorNode
;
127 while(node
&& (node
.nodeType
!= 1)){ // not an element
128 node
= node
.parentNode
;
137 hasAncestorElement: function(/*String*/tagName
/* ... */){
139 // Check whether current selection has a parent element which is
140 // of type tagName (or one of the other specified tagName)
142 // The tag name to determine if it has an ancestor of.
143 return this.getAncestorElement
.apply(this, arguments
) != null; //Boolean
146 getAncestorElement: function(/*String*/tagName
/* ... */){
148 // Return the parent element of the current selection which is of
149 // type tagName (or one of the other specified tagName)
151 // The tag name to determine if it has an ancestor of.
152 var node
= this.getSelectedElement() || this.getParentElement();
153 return this.getParentOfType(node
, arguments
); //DOMNode
156 isTag: function(/*DomNode*/ node
, /*String[]*/ tags
){
158 // Function to determine if a node is one of an array of tags.
160 // The node to inspect.
162 // An array of tag name strings to check to see if the node matches.
163 if(node
&& node
.tagName
){
164 var _nlc
= node
.tagName
.toLowerCase();
165 for(var i
=0; i
<tags
.length
; i
++){
166 var _tlc
= String(tags
[i
]).toLowerCase();
168 return _tlc
; // String
175 getParentOfType: function(/*DomNode*/ node
, /*String[]*/ tags
){
177 // Function to locate a parent node that matches one of a set of tags
179 // The node to inspect.
181 // An array of tag name strings to check to see if the node matches.
183 if(this.isTag(node
, tags
).length
){
184 return node
; // DOMNode
186 node
= node
.parentNode
;
191 collapse: function(/*Boolean*/beginning
){
193 // Function to collapse (clear), the current selection
194 // beginning: Boolean
195 // Boolean to indicate whether to collapse the cursor to the beginning of the selection or end.
196 if(window
.getSelection
){
197 var selection
= win
.global
.getSelection();
198 if(selection
.removeAllRanges
){ // Mozilla
200 selection
.collapseToStart();
202 selection
.collapseToEnd();
205 // pulled from WebCore/ecma/kjs_window.cpp, line 2536
206 selection
.collapse(beginning
);
208 }else if(has("ie")){ // IE
209 var range
= win
.doc
.selection
.createRange();
210 range
.collapse(beginning
);
217 // Function to delete the currently selected content from the document.
218 var sel
= win
.doc
.selection
;
220 if(sel
.type
.toLowerCase() != "none"){
223 return sel
; //Selection
225 sel
= win
.global
.getSelection();
226 sel
.deleteFromDocument();
227 return sel
; //Selection
231 selectElementChildren: function(/*DomNode*/element
,/*Boolean?*/nochangefocus
){
233 // clear previous selection and select the content of the node
234 // (excluding the node itself)
236 // The element you wish to select the children content of.
237 // nochangefocus: Boolean
238 // Boolean to indicate if the foxus should change or not.
239 var global
= win
.global
;
242 element
= dom
.byId(element
);
243 if(doc
.selection
&& has("ie") < 9 && win
.body().createTextRange
){ // IE
244 range
= element
.ownerDocument
.body
.createTextRange();
245 range
.moveToElementText(element
);
248 range
.select(); // IE throws an exception here if the widget is hidden. See #5439
249 }catch(e
){ /* squelch */}
251 }else if(global
.getSelection
){
252 var selection
= win
.global
.getSelection();
254 //Opera's selectAllChildren doesn't seem to work right
255 //against <body> nodes and possibly others ... so
256 //we use the W3C range API
257 if(selection
.rangeCount
){
258 range
= selection
.getRangeAt(0);
260 range
= doc
.createRange();
262 range
.setStart(element
, 0);
263 range
.setEnd(element
,(element
.nodeType
== 3)?element
.length
:element
.childNodes
.length
);
264 selection
.addRange(range
);
266 selection
.selectAllChildren(element
);
271 selectElement: function(/*DomNode*/element
,/*Boolean?*/nochangefocus
){
273 // clear previous selection and select element (including all its children)
275 // The element to select.
276 // nochangefocus: Boolean
277 // Boolean indicating if the focus should be changed. IE only.
280 var global
= win
.global
;
281 element
= dom
.byId(element
);
282 if(has("ie") < 9 && win
.body().createTextRange
){
284 var tg
= element
.tagName
? element
.tagName
.toLowerCase() : "";
285 if(tg
=== "img" || tg
=== "table"){
286 range
= win
.body().createControlRange();
288 range
= win
.body().createRange();
290 range
.addElement(element
);
295 this.selectElementChildren(element
,nochangefocus
);
297 }else if(global
.getSelection
){
298 var selection
= global
.getSelection();
299 range
= doc
.createRange();
300 if(selection
.removeAllRanges
){ // Mozilla
301 // FIXME: does this work on Safari?
303 //Opera works if you use the current range on
304 //the selection if present.
305 if(selection
.getRangeAt(0)){
306 range
= selection
.getRangeAt(0);
309 range
.selectNode(element
);
310 selection
.removeAllRanges();
311 selection
.addRange(range
);
316 inSelection: function(node
){
318 // This function determines if 'node' is
319 // in the current selection.
327 if(win
.global
.getSelection
){
329 var sel
= win
.global
.getSelection();
330 if(sel
&& sel
.rangeCount
> 0){
331 range
= sel
.getRangeAt(0);
333 if(range
&& range
.compareBoundaryPoints
&& doc
.createRange
){
335 newRange
= doc
.createRange();
336 newRange
.setStart(node
, 0);
337 if(range
.compareBoundaryPoints(range
.START_TO_END
, newRange
) === 1){
340 }catch(e
){ /* squelch */}
342 }else if(doc
.selection
){
343 // Probably IE, so we can't use the range object as the pseudo
344 // range doesn't implement the boundry checking, we have to
345 // use IE specific crud.
346 range
= doc
.selection
.createRange();
348 newRange
= node
.ownerDocument
.body
.createControlRange();
350 newRange
.addElement(node
);
354 newRange
= node
.ownerDocument
.body
.createTextRange();
355 newRange
.moveToElementText(node
);
356 }catch(e2
){/* squelch */}
358 if(range
&& newRange
){
359 // We can finally compare similar to W3C
360 if(range
.compareEndPoints("EndToStart", newRange
) === 1){
366 return false; // boolean
371 return dijit
._editor
.selection
;