1var oEditor;
2var oRange = {};
3
4
5FCK.breakDelObject = function(editor) {
6    oEditor = editor;
7    this.replaceStack = new Array();
8    this.nodes = oRange.getElementsFromSelection();
9
10}
11
12FCK.breakDelObject.prototype.debug = function() {
13
14      var doc = oEditor.FCK.EditorDocument;
15      var buf=[];
16       var nodes = this.nodes;
17       if(nodes) {
18         for(var ii=0; ii<nodes.length; ii++) {
19           var text = FCK.paraDelObject.getData(nodes[ii]);
20           if(nodes[ii].nodeName.match(/body/i)) continue;
21           if(nodes[ii].nodeName.toUpperCase() == 'BR') {
22                this.setBreakToPara(nodes[ii]);
23           }
24           buf[buf.length]=nodes[ii].nodeName+"&lt;"+text+"&gt";
25         }
26
27
28         return buf.join(", ");
29       }
30      return  "";
31     };
32FCK.breakDelObject.prototype.replace = function() {
33
34   var doc = oEditor.FCK.EditorDocument;
35      for(var i=0; i <  this.replaceStack.length; i++) {
36        var df = this.replaceStack[i].df;
37        var parent = this.replaceStack[i].parent;
38        var n = this.replaceStack[i].replace;
39
40        parent.replaceChild(df,n);
41      }
42
43
44};
45
46
47FCK.breakDelObject.prototype.setBreakToPara= function(n) {
48  var doc = oEditor.FCK.EditorDocument;
49  var para = doc.createElement('p');
50  var f = doc.createDocumentFragment();
51   for(var m=n.firstChild; m != null; m = m.nextSibling) {
52        var clone = m.cloneNode(true);
53        f.appendChild(clone);
54
55 }
56    f.appendChild(para);
57    this.replaceStack.push({ df:f, parent: n.parentNode, replace: n });
58
59}
60
61
62FCK.breakDelObject.getData= function(n) {
63
64 var data = "";
65 if(n.nodeType == 3) data += n.data;
66 for(var m=n.firstChild; m != null; m = m.nextSibling) {
67
68     if(m.nodeType == 3) {
69          data += m.data;
70     }
71 }
72 return data;
73};
74
75FCK.paraDelObject = function(editor) {
76    oEditor = editor;
77    this.replaceStack = new Array();
78    this.nodes = oRange.getElementsFromSelection();
79
80}
81
82// parent.replaceChild(new,old);
83FCK.paraDelObject.prototype.debug = function() {
84      var doc = oEditor.FCK.EditorDocument;
85      var buf=[];
86       var nodes = this.nodes;
87       if(nodes) {
88         for(var ii=0; ii<nodes.length; ii++) {
89           var text = FCK.paraDelObject.getData(nodes[ii]);
90           if(nodes[ii].nodeName.match(/body/i)) continue;
91           if(nodes[ii].nodeName.toUpperCase() == 'P') {
92                this.setParaToBR(nodes[ii]);
93           }
94           buf[buf.length]=nodes[ii].nodeName+"&lt;"+text+"&gt";
95         }
96
97
98         return buf.join(", ");
99       }
100      return  "";
101     };
102
103FCK.paraDelObject.prototype.replace = function() {
104
105   var doc = oEditor.FCK.EditorDocument;
106      for(var i=0; i <  this.replaceStack.length; i++) {
107        var df = this.replaceStack[i].df;
108        var parent = this.replaceStack[i].parent;
109        var n = this.replaceStack[i].replace;
110
111        parent.replaceChild(df,n);
112      }
113
114
115};
116
117
118FCK.paraDelObject.prototype.setParaToBR= function(n) {
119  var doc = oEditor.FCK.EditorDocument;
120  var br = doc.createElement('br');
121  var f = doc.createDocumentFragment();
122   for(var m=n.firstChild; m != null; m = m.nextSibling) {
123        var clone = m.cloneNode(true);
124        f.appendChild(clone);
125
126 }
127    f.appendChild(br);
128    this.replaceStack.push({ df:f, parent: n.parentNode, replace: n });
129
130}
131
132
133FCK.paraDelObject.getData= function(n) {
134
135 var data = "";
136 if(n.nodeType == 3) data += n.data;
137 for(var m=n.firstChild; m != null; m = m.nextSibling) {
138
139     if(m.nodeType == 3) {
140          data += m.data;
141     }
142 }
143 return data;
144};
145
146
147FCK.rangeObject = function(editor) {
148    oEditor = editor;
149    this.nodes = oRange.getElementsFromSelection();
150
151    this.blockquote = oRange.getBlockQoteElement(this.nodes);
152
153	if (document.selection) {													// IE
154    	this.text = oEditor.FCK.EditorDocument.selection.createRange().htmlText;
155	}
156    else {
157       this.text = oRange.getRangeText(this.blockquote);
158    }
159    this.replaceStack = new Array();
160}
161
162FCK.rangeObject.prototype.debug = function() {
163
164       var buf=[];
165       var kids = this.blockquote.childNodes;
166       if(kids) {
167         for(var ii=0; ii<kids.length; ii++) {
168           var data = FCK.rangeObject.getNodeData(kids[ii]);
169           buf[buf.length]=kids[ii].nodeName+"&lt;"+ data +"&gt";
170         }
171         return (buf.join(", "));
172       }
173    return "";
174};
175
176
177//  BlockQ_Attr = { background: "#ffffff", textcolor: "#000000", width:"80%" };
178
179FCK.rangeObject.prototype.createIndents = function(attrs) {
180
181       this.background = attrs.background;
182       this.textcolor = attrs.textcolor;
183
184       var buf=[];
185       var kids = this.blockquote.childNodes;
186       if(kids) {
187         for(var ii=0; ii<kids.length; ii++) {
188           var data = this.insertIndent(kids[ii]);
189
190         }
191
192       }
193
194
195      for(var i=0; i <  this.replaceStack.length; i++) {
196        var df = this.replaceStack[i].df;
197        var parent = this.replaceStack[i].parent;
198        var n = this.replaceStack[i].replace;
199        parent.replaceChild(df,n);
200      }
201};
202
203
204
205
206FCK.rangeObject.setNodeColors = function (node, fg_color, bg_color) {
207   node.style.cssText ="";
208   var style =  "color: " + fg_color  +  ";  background-color: " + bg_color + ";";
209
210  node.style.cssText = style;
211
212  return style;
213};
214
215FCK.rangeObject.prototype.insertIndent = function(n) {
216  var data = "";
217  var doc = oEditor.FCK.EditorDocument;
218
219    if(n.nodeType == 3) {
220           var str = "";
221           var parent_tag = n.parentNode.nodeName.toLowerCase();
222           var parentNode = n.parentNode;
223           if(/[\xA0\ufffd\xb7]/.test(n.data)) {
224               var df = doc.createDocumentFragment();
225               var regex = new RegExp(/([^\xA0\ufffd\xb7]*)([\xA0\ufffd\xb7]+)([^\xA0\ufffd\xb7]*)/g);
226                var str = n.data;
227               // var output = "";
228                while(result = regex.exec(str)) {
229
230                    for(i in result) {
231
232                        var type = "parent: " + n.parentNode.nodeName + " this node: " + n.nodeName + " " + i;
233                        switch (i) {
234                            case '1':
235                            case '3':
236
237                              if(result[i].length) {
238                                 //output+= "<" +type + ">" + result[i] + '</' + parent_tag + ">\n";
239                                   var textnode = doc.createTextNode(result[i]);
240                                   df.appendChild(textnode);
241                              }
242                               break;
243
244                            case '2':
245                              if(result[i].length) {
246                                   if(parent_tag == 'indent') {
247                                     var style=FCK.rangeObject.setNodeColors (parentNode, this.background, this.background);
248                                    // output+='<indent style ="'+style+'">'+result[i]+'</indent>';
249                                     break;
250                                   }
251                                   var indent = doc.createElement('fck:indent');
252                                   var style = FCK.rangeObject.setNodeColors (indent, this.background, this.background);
253                                   var textnode = doc.createTextNode(result[i]);
254                                   indent.appendChild(textnode);
255                                   df.appendChild(indent);
256
257                                  // output+='<indent style ="'+style + '" ' + type + ' >'+result[i]+'</indent>';
258                              }
259                               break;
260
261                            default:
262                              type = null;
263                        }
264                    }
265               }
266
267              this.replaceStack.push({ df:df, parent: n.parentNode, replace: n });
268
269          // alert(output);
270           }
271
272
273     }
274     else {
275       var kids = n.childNodes;
276       for(var i = 0; i < kids.length; i++) {
277          data += this.insertIndent(kids[i]);
278       }
279    }
280
281   return data;
282
283};
284
285FCK.rangeObject.getNodeData = function (n) {
286  var data = "";
287
288    if(n.nodeType == 3) {
289           var str = "";
290           for(var i=0; i < n.data.length; i++) {
291
292             var c = n.data.charCodeAt(i);
293             str += c.toString(16) + ",";
294           }
295           return '[['+n.data+ ' {' + str + '} ]]';
296     }
297     else {
298       var kids = n.childNodes;
299       for(var i = 0; i < kids.length; i++) {
300          data += "  " + kids[i].nodeName + ": ";
301          data += FCK.rangeObject.getNodeData(kids[i]);
302       }
303    }
304
305   return data;
306};
307
308
309oRange.getElementsFromSelection = function() {
310
311   var nodes=null, candidates=[], children, el, parent, rng;
312
313   // Main
314   rng=getSelectionRange();
315   if(rng) {
316     parent=getCommonAncestor(rng);
317     if(parent) {
318       // adjust from text node to element, if needed
319       while(parent.nodeType!=1) parent=parent.parentNode;
320
321       // obtain all candidates from parent (excluded)
322       // up to BODY (included)
323       if(parent.nodeName.toLowerCase()!="body") {
324         el=parent;
325         do {
326           el=el.parentNode;
327           candidates[candidates.length]=el;
328         } while(el.nodeName.toLowerCase()!="body");
329       }
330
331       // obtain all candidates down to all children
332       children=parent.all||parent.getElementsByTagName("*");
333       for(var j=0; j<children.length; j++)
334         candidates[candidates.length]=children[j];
335
336       // proceed - keep element when range touches it
337       nodes=[parent];
338       for(var ii=0, r2; ii<candidates.length; ii++) {
339         r2=createRangeFromElement(candidates[ii]);
340         if(r2 && rangeContact(rng, r2))
341           nodes[nodes.length]=candidates[ii];
342       }
343     }
344   };
345
346   return nodes;
347
348   // Helpers
349
350   function getSelectionRange () {
351     var win = oEditor.FCK.EditorWindow;
352     var doc = oEditor.FCK.EditorDocument;
353     var rng=null;
354     if(win.getSelection) {
355       rng=win.getSelection();
356       if(rng && rng.rangeCount && rng.getRangeAt) {
357         rng=rng.getRangeAt(0);
358       }
359     } else if(doc.selection && doc.selection.type=="Text") {
360       rng=doc.selection.createRange();
361     }
362
363     return rng;
364   };
365
366
367   function getCommonAncestor(rng) {
368     return rng.parentElement ?
369              rng.parentElement() : rng.commonAncestorContainer;
370   }
371
372   function rangeContact(r1, r2) {
373     var p=null;
374     if(r1.compareEndPoints) {
375       p={
376         method:"compareEndPoints",
377         StartToStart:"StartToStart",
378         StartToEnd:"StartToEnd",
379         EndToEnd:"EndToEnd",
380         EndToStart:"EndToStart"
381       }
382     } else if(r1.compareBoundaryPoints) {
383       p={
384         method:"compareBoundaryPoints",
385         StartToStart:0,
386         StartToEnd:1,
387         EndToEnd:2,
388         EndToStart:3
389       }
390     }
391     return p && !(
392           r2[p.method](p.StartToStart, r1)==1 &&
393           r2[p.method](p.EndToEnd, r1)==1 &&
394           r2[p.method](p.StartToEnd, r1)==1 &&
395           r2[p.method](p.EndToStart, r1)==1
396           ||
397           r2[p.method](p.StartToStart, r1)==-1 &&
398           r2[p.method](p.EndToEnd, r1)==-1 &&
399           r2[p.method](p.StartToEnd, r1)==-1 &&
400           r2[p.method](p.EndToStart, r1)==-1
401         );
402   }
403
404
405   function createRangeFromElement(el) {
406
407     var win = oEditor.FCK.EditorWindow;
408     var doc = oEditor.FCK.EditorDocument;
409
410     var rng=null;
411     if(doc.body.createTextRange) {
412       rng=doc.body.createTextRange();
413       rng.moveToElementText(el);
414     } else if(doc.createRange) {
415       rng=doc.createRange();
416       rng.selectNodeContents(el);
417     }
418     return rng;
419   }
420
421};
422
423
424
425
426// Firefox, Safari
427oRange.getRangeText = function(node) {
428    var doc = oEditor.FCK.EditorDocument;
429    var oRange1 = doc.createRange();
430
431    oRange1.selectNodeContents(node);
432    var text = oRange1.toString();
433
434    text = text.replace(/\n/g,"<BR />");
435
436    return text;
437};
438
439
440oRange.getBlockQoteElement = function(nodes) {
441var blockq;
442       if(!nodes) nodes=oRange.getElementsFromSelection();
443
444       if(nodes) {
445         for(var ii=0; ii<nodes.length; ii++) {
446               if(nodes[ii].nodeName.toUpperCase() == 'BLOCKQUOTE') {
447                 return nodes[ii];
448                }
449           }
450       }
451
452   return blockq;
453
454};
455
456
457
458
459