source: Dev/branches/rest-dojo-ui/client/dojox/drawing/tools/TextBlock.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

  • Property svn:executable set to *
File size: 22.6 KB
Line 
1dojo.provide("dojox.drawing.tools.TextBlock");
2dojo.require("dojox.drawing.stencil.Text");
3
4(function(){
5        var conEdit;
6        dojo.addOnLoad(function(){
7                //              In order to use VML in IE, it's necessary to remove the
8                //              DOCTYPE. But this has the side effect that causes a bug
9                //              where contenteditable divs cannot be made dynamically.
10                //              The solution is to include one in the main document
11                //              that can be appended and removed as necessary:
12                //              <div id="conEdit" contenteditable="true"></div>
13                //
14                // console.log("Removing conedit");
15                conEdit = dojo.byId("conEdit");
16                if(!conEdit){
17                        console.error("A contenteditable div is missing from the main document. See 'dojox.drawing.tools.TextBlock'")
18                }else{
19                        conEdit.parentNode.removeChild(conEdit);
20                }
21        });
22       
23        dojox.drawing.tools.TextBlock = dojox.drawing.util.oo.declare(
24                // summary:
25                //              A tool to create text fields on a canvas.
26                // description:
27                //              Extends stencil.Text by adding an HTML layer that
28                //              can be dragged out to a certain size, and accept
29                //              a text entry. Will wrap text to the width of the
30                //              html field.
31                //              When created programmtically, use 'auto' to shrink
32                //              the width to the size of the text. Use line breaks
33                //              ( \n ) to create new lines.
34                //
35                // TODO - disable zoom while showing?
36                //
37                // FIXME:
38                //              Handles width: auto, align:middle, etc. but for
39                //              display only, edit is out of whack
40                //
41                dojox.drawing.stencil.Text,
42                function(options){
43                        // summary: constructor
44                        //
45                        if(options.data){
46                                var d = options.data;
47                                var text = d.text ? this.typesetter(d.text) : d.text;
48                                var w = !d.width ? this.style.text.minWidth : d.width=="auto" ? "auto" : Math.max(d.width, this.style.text.minWidth);
49                                var h = this._lineHeight;
50                               
51                                if(text && w=="auto"){
52                                        var o = this.measureText(this.cleanText(text, false), w);
53                                        w = o.w;
54                                        h = o.h;
55                                }else{
56                                        //      w = this.style.text.minWidth;
57                                        this._text = "";
58                                }
59                               
60                                this.points = [
61                                        {x:d.x, y:d.y},
62                                        {x:d.x+w, y:d.y},
63                                        {x:d.x+w, y:d.y+h},
64                                        {x:d.x, y:d.y+h}
65                                ];
66                               
67                                if(d.showEmpty || text){
68                                        this.editMode = true;
69                                       
70                               
71                                        dojo.disconnect(this._postRenderCon);
72                                        this._postRenderCon = null;
73                                        this.connect(this, "render", this, "onRender", true);
74                                       
75                                        if(d.showEmpty){
76                                                this._text = text || "";
77                                                this.edit();
78                                        }else if(text && d.editMode){
79                                                this._text = "";
80                                                this.edit();
81                                        }else if(text){
82                                                this.render(text);
83                                        }
84                                        setTimeout(dojo.hitch(this, function(){
85                                                this.editMode = false;
86                                        }),100)
87                                       
88                                }else{
89                                        // Why make it if it won't render...
90                                        this.render();
91                                }
92                               
93                        }else{
94                                this.connectMouse();
95                                this._postRenderCon = dojo.connect(this, "render", this, "_onPostRender");
96                        }
97                        //console.log("TextBlock:", this.id)
98                },
99                {
100                        draws:true,
101                        baseRender:false,
102                        type:"dojox.drawing.tools.TextBlock",
103                        _caretStart: 0,
104                        _caretEnd: 0,
105                        _blockExec: false,
106                       
107/*=====
108StencilData: {
109        // summary:
110        //              The data used to create the dojox.gfx Text
111        //      x: Number
112        //              Left point x
113        //      y: Number
114        //              Top point y
115        //      width: ? Number|String
116        //              Optional width of Text. Not required but reccommended.
117        //              for auto-sizing, use 'auto'
118        //      height: ? Number
119        //              Optional height of Text. If not provided, _lineHeight is used.
120        //      text: String
121        //              The string content. If not provided, may auto-delete depending on defaults.
122},
123=====*/
124                       
125                        // selectOnExec: Boolean
126                        //              Whether the Stencil is selected when the text field
127                        //              is executed or not
128                        selectOnExec:true,
129                        //
130                        // showEmpty: Boolean
131                        //              If true and there is no text in the data, the TextBlock
132                        //              Is displayed and focused and awaits input.
133                        showEmpty: false,
134                       
135                        onDrag: function(/*EventObject*/obj){
136                                // summary: See stencil._Base.onDrag
137                                //
138                                if(!this.parentNode){
139                                        this.showParent(obj);
140                                }
141                                var s = this._startdrag, e = obj.page;
142                                this._box.left = (s.x < e.x ? s.x : e.x);
143                                this._box.top = s.y;
144                                this._box.width = (s.x < e.x ? e.x-s.x : s.x-e.x) + this.style.text.pad;
145                               
146                                dojo.style(this.parentNode, this._box.toPx());
147                        },
148                       
149                        onUp: function(/*EventObject*/obj){
150                                // summary: See stencil._Base.onUp
151                                //
152
153                                if(!this._downOnCanvas){ return; }
154                                this._downOnCanvas = false;
155                               
156                                var c = dojo.connect(this, "render", this, function(){
157                                        dojo.disconnect(c);
158                                        this.onRender(this);
159                                       
160                                });
161                                this.editMode = true;
162                                this.showParent(obj);
163                                this.created = true;
164                                this.createTextField();
165                                this.connectTextField();
166                        },
167                       
168                        showParent: function(/*EventObject*/obj){
169                                // summary:
170                                //              Internal. Builds the parent node for the
171                                //              contenteditable HTML node.
172                                //
173                                if(this.parentNode){ return; }
174                                var x = obj.pageX || 10;
175                                var y = obj.pageY || 10;
176                                this.parentNode = dojo.doc.createElement("div");
177                                this.parentNode.id = this.id;
178                                var d = this.style.textMode.create;
179                                this._box = {
180                                        left:x,
181                                        top:y,
182                                        width:obj.width || 1,
183                                        height:obj.height && obj.height>8 ? obj.height : this._lineHeight,
184                                        border:d.width+"px "+d.style+" "+d.color,
185                                        position:"absolute",
186                                        zIndex:500,
187                                        toPx: function(){
188                                                var o = {};
189                                                for(var nm in this){
190                                                        o[nm] = typeof(this[nm])=="number" && nm!="zIndex" ? this[nm] + "px" : this[nm];
191                                                }
192                                                return o;
193                                        }
194                                };
195                               
196                                dojo.style(this.parentNode, this._box);
197                               
198                                document.body.appendChild(this.parentNode);
199                        },
200                        createTextField: function(/*String*/txt){
201                                // summary:
202                                //              Internal. Inserts the contenteditable HTML node
203                                //              into its parent node, and styles it.
204                                //
205                                // style parent
206                                var d = this.style.textMode.edit;
207                                this._box.border = d.width+"px "+d.style+" "+d.color;
208                                this._box.height = "auto";
209                                this._box.width = Math.max(this._box.width, this.style.text.minWidth*this.mouse.zoom);
210                                dojo.style(this.parentNode, this._box.toPx());
211                                // style input
212                                this.parentNode.appendChild(conEdit);
213                                dojo.style(conEdit, {
214                                        height: txt ? "auto" : this._lineHeight+"px",
215                                        fontSize:(this.textSize/this.mouse.zoom)+"px",
216                                        fontFamily:this.style.text.family
217                                });
218                                // FIXME:
219                                // In Safari, if the txt ends with '&' it gets stripped
220                                conEdit.innerHTML = txt || "";
221                               
222                                return conEdit; //HTMLNode
223                        },
224                        connectTextField: function(){
225                                // summary:
226                                //              Internal. Creates the connections to the
227                                //              contenteditable HTML node.
228                                //
229                                if(this._textConnected){ return; } // good ol' IE and its double events
230                                // FIXME:
231                                // Ouch-getting greekPalette by id.  At the minimum this should
232                                // be from the plugin manager
233                                var greekPalette = dijit.byId("greekPalette");
234                                var greekHelp = greekPalette==undefined ? false : true;
235                                if(greekHelp){
236                                        //set it up
237                                        dojo.mixin(greekPalette,{
238                                                _pushChangeTo: conEdit,
239                                                _textBlock: this
240                                        });
241                                };
242                               
243                                this._textConnected = true;
244                                this._dropMode = false;
245                                this.mouse.setEventMode("TEXT");
246                                this.keys.editMode(true);
247                                var kc1, kc2, kc3, kc4, self = this, _autoSet = false,
248                                        exec = function(){
249                                                if(self._dropMode){ return; }
250                                                dojo.forEach([kc1,kc2,kc3,kc4], function(c){
251                                                        dojo.disconnect(c)
252                                                });
253                                                self._textConnected = false;
254                                                self.keys.editMode(false);
255                                                self.mouse.setEventMode();
256                                                self.execText();
257                                        };
258                                       
259                                kc1 = dojo.connect(conEdit, "keyup", this, function(evt){
260                                        //      if text is empty, we need a height so the field's height
261                                        //      doesn't collapse
262                                        if(dojo.trim(conEdit.innerHTML) && !_autoSet){
263                                                dojo.style(conEdit, "height", "auto"); _autoSet = true;
264                                        }else if(dojo.trim(conEdit.innerHTML).length<2 && _autoSet){
265                                                dojo.style(conEdit, "height", this._lineHeight+"px"); _autoSet = false;
266                                        }
267                                       
268                                        if(!this._blockExec){
269                                                if(evt.keyCode==13 || evt.keyCode==27){
270                                                        dojo.stopEvent(evt);
271                                                        exec();
272                                                }
273                                        } else {
274                                                if(evt.keyCode==dojo.keys.SPACE){
275                                                        dojo.stopEvent(evt);
276                                                        greekHelp && greekPalette.onCancel();
277                                                }
278                                        }
279                                });
280                                kc2 = dojo.connect(conEdit, "keydown", this, function(evt){
281                                        if(evt.keyCode==13 || evt.keyCode==27){ // TODO: make escape an option
282                                                dojo.stopEvent(evt);
283                                        }
284                                        //      if backslash, user is inputting a special character
285                                        //      This gives popup help.
286                                        if(evt.keyCode==220){
287                                                if(!greekHelp){
288                                                        console.info("For greek letter assistance instantiate: dojox.drawing.plugins.drawing.GreekPalette");
289                                                        return;
290                                                }
291                                                dojo.stopEvent(evt);
292                                                this.getSelection(conEdit);
293                                                // Differences in how browsers handle events made it necessary
294                                                // to stop the evt and add the backslash here.
295                                                this.insertText(conEdit,"\\");
296                                                this._dropMode = true;
297                                                this._blockExec = true;
298                                                greekPalette.show({
299                                                        around:this.parentNode,
300                                                        orient:{'BL':'TL'}
301                                                });
302                                        }
303                                        if(!this._dropMode){
304                                                this._blockExec = false;
305                                        } else {
306                                                // Controls for when we have a character helper and it's active
307                                                switch(evt.keyCode){
308                                                        case dojo.keys.UP_ARROW:
309                                                        case dojo.keys.DOWN_ARROW:
310                                                        case dojo.keys.LEFT_ARROW:
311                                                        case dojo.keys.RIGHT_ARROW:
312                                                                dojo.stopEvent(evt);
313                                                                greekPalette._navigateByArrow(evt);
314                                                                break;
315                                                        case dojo.keys.ENTER:
316                                                                dojo.stopEvent(evt);
317                                                                greekPalette._onCellClick(evt);
318                                                                break;
319                                                        case dojo.keys.BACKSPACE:
320                                                        case dojo.keys.DELETE:
321                                                                dojo.stopEvent(evt);
322                                                                greekPalette.onCancel();
323                                                                break;
324                                                }
325                                        }
326                                       
327                                });
328                               
329                                kc3 = dojo.connect(document, "mouseup", this, function(evt){
330                                        // note: _onAnchor means an anchor has been clicked upon
331                                        if(!this._onAnchor && evt.target.id != "conEdit"){
332                                                dojo.stopEvent(evt);
333                                                exec();
334                                        }else if(evt.target.id == "conEdit" && conEdit.innerHTML == ""){
335                                                // wonky stuff happens when you click on the
336                                                // field when its empty.
337                                                conEdit.blur();
338                                                setTimeout(function(){
339                                                        conEdit.focus();
340                                                },200)
341                                        }
342                                });
343                               
344                                this.createAnchors();
345                               
346                                kc4 = dojo.connect(this.mouse, "setZoom", this, function(evt){
347                                        exec();
348                                });
349                               
350                               
351                                conEdit.focus();
352                               
353                                this.onDown = function(){};
354                                this.onDrag = function(){};
355                               
356                                setTimeout(dojo.hitch(this, function(){
357                                        // once again for Silverlight:
358                                        conEdit.focus();
359                                       
360                                        // this is a pretty odd chunk of code here.
361                                        // specifcally need to overwrite old onUp
362                                        // however, this still gets called. its
363                                        // not disconnecting.
364                                        this.onUp = function(){
365                                                if(!self._onAnchor && this.parentNode){
366                                                        self.disconnectMouse();
367                                                        exec();
368                                                        self.onUp = function(){}
369                                                }
370                                        }
371                                }), 500);
372                        },
373                       
374                       
375                        execText: function(){
376                                // summary:
377                                //              Internal. Method fired when text is executed,
378                                //              via mouse-click-off, ESC key or Enter key.
379                                //
380                                var d = dojo.marginBox(this.parentNode);
381                                var w = Math.max(d.w, this.style.text.minWidth);
382                               
383                                var txt = this.cleanText(conEdit.innerHTML, true);
384                                conEdit.innerHTML = "";
385                                conEdit.blur();
386                                this.destroyAnchors();
387
388                                // need to convert characters before measuring width.
389                                txt = this.typesetter(txt);
390                               
391                                var o = this.measureText(txt, w);
392                                var sc = this.mouse.scrollOffset();
393                                var org = this.mouse.origin;
394                               
395                                var x = this._box.left + sc.left - org.x;
396                                var y = this._box.top + sc.top - org.y;
397                               
398                                x *= this.mouse.zoom;
399                                y *= this.mouse.zoom;
400                                w *= this.mouse.zoom;
401                                o.h *= this.mouse.zoom;
402                               
403                               
404                                this.points = [
405                                        {x:x, y:y},
406                                        {x:x+w, y:y},
407                                        {x:x+w, y:y+o.h},
408                                        {x:x, y:y+o.h}
409                                ];
410                                this.editMode = false;
411                               
412                               
413                                console.log("EXEC TEXT::::", this._postRenderCon);
414                               
415                                if(!o.text){
416                                        this._text = "";
417                                        this._textArray = [];
418                                }
419                                // Only for Combo objects (vectors, rectangle, or ellipse).
420                                this.render(o.text);
421                                this.onChangeText(this.getText());
422                        },
423                       
424                        edit: function(){
425                                // summary:
426                                //              Internal?
427                                //              Method used to instantiate the contenteditable HTML node.
428                                //
429                                this.editMode = true;
430                                var text = this.getText() || "";
431                                console.log("EDIT TEXT:",text, " ",text.replace("/n", " "));
432                                // NOTE: no mouse obj
433                                if(this.parentNode || !this.points){ return; }
434                                var d = this.pointsToData();
435                               
436                                var sc = this.mouse.scrollOffset();
437                                var org = this.mouse.origin;
438                               
439                                var obj = {
440                                        pageX: (d.x  ) / this.mouse.zoom - sc.left + org.x,
441                                        pageY: (d.y  ) / this.mouse.zoom- sc.top + org.y,
442                                        width:d.width / this.mouse.zoom,
443                                        height:d.height / this.mouse.zoom
444                                };
445                               
446                                this.remove(this.shape, this.hit);
447                                this.showParent(obj);
448                                this.createTextField(text.replace("/n", " "));
449                                this.connectTextField();
450                                if(text){
451                                        //setTimeout(dojo.hitch(this, function(){
452                                        this.setSelection(conEdit, "end");
453                                        //}), 500)
454                                }
455                        },
456                        cleanText: function(/*String*/txt, /*Boolean*/removeBreaks){
457                                // summary:
458                                //              Cleans text. Strings HTML chars and double spaces
459                                //      and optionally removes line breaks.
460                                var replaceHtmlCodes = function(str){
461                                        var chars = {
462                                                "&lt;":"<",
463                                                "&gt;":">",
464                                                "&amp;":"&"
465                                        };
466                                        for(var nm in chars){
467                                                str = str.replace(new RegExp(nm, "gi"), chars[nm])
468                                        }
469                                        return str
470                                };
471
472                                if(removeBreaks){
473                                        dojo.forEach(['<br>', '<br/>', '<br />', '\\n', '\\r'], function(br){
474                                                txt = txt.replace(new RegExp(br, 'gi'), " ");
475                                        });
476                                }
477                                txt = txt.replace(/&nbsp;/g, " ");
478                                txt = replaceHtmlCodes(txt);
479                                txt = dojo.trim(txt);
480                                // remove double spaces, since SVG doesn't show them anyway
481                                txt = txt.replace(/\s{2,}/g, " ");
482                                return txt; //String
483                        },
484                       
485                        measureText: function(/* String */ str, /* ? Number */width){
486                                // summary:
487                                //              Mechanism for measuring text.
488                                //              SVG nor VML have a way of determining the width or
489                                //              height of a block of text. This method creates an
490                                //              HTML text block and those measurements are used for
491                                //              displaying the SVG/VML text.
492                                // arguments:
493                                //              str: String
494                                //                      The text to display and measure.
495                                //              width: [optional] Number
496                                //                      If the width is not provided, it will be assumed
497                                //                      that the text is one line and the width will be
498                                //                      measured and the _lineHeight used for th height.
499                                //                      If width is provided, word-wrap is assumed, and
500                                //                      line breaks will be inserted into the text at each
501                                //                      point where a word wraps in the HTML. The height is
502                                //                      then measured.
503                                //
504                                var r = "(<br\\s*/*>)|(\\n)|(\\r)";
505                                this.showParent({width:width || "auto", height:"auto"});
506                                this.createTextField(str);
507                                var txt = "";
508                                var el = conEdit;
509                                el.innerHTML = "X";
510                                var h = dojo.marginBox(el).h;
511                               
512                                el.innerHTML = str;
513                               
514                                if(!width || new RegExp(r, "gi").test(str)){
515                                        // has line breaks in text
516                                        txt = str.replace(new RegExp(r, "gi"), "\n");
517                                        el.innerHTML = str.replace(new RegExp(r, "gi"), "<br/>");
518                               
519                                }else if(dojo.marginBox(el).h == h){
520                                        // one line
521                                        txt = str;
522                                       
523                                }else{
524                                        // text wraps
525                                        var ar = str.split(" ");
526                                        var strAr = [[]];
527                                        var line = 0;
528                                        el.innerHTML = "";
529                                        while(ar.length){
530                                                var word = ar.shift();
531                                                el.innerHTML += word+" "; //urk, always an extra space
532                                                if(dojo.marginBox(el).h > h){
533                                                        line++;
534                                                        strAr[line] = [];
535                                                        el.innerHTML = word+" ";
536                                                }
537                                                strAr[line].push(word)
538                                        }
539                                       
540                                        dojo.forEach(strAr, function(ar, i){
541                                                strAr[i] = ar.join(" ");
542                                        });
543                                        txt = strAr.join("\n");
544                                       
545                                        // get the resultant height
546                                        el.innerHTML = txt.replace("\n", "<br/>");
547                                       
548                                }
549                               
550                                var dim = dojo.marginBox(el);
551                               
552                                conEdit.parentNode.removeChild(conEdit);
553                                dojo.destroy(this.parentNode);
554                                this.parentNode = null;
555                               
556                                return {h:dim.h, w:dim.w, text:txt}; //Object
557                        },
558                       
559                        _downOnCanvas:false,
560                        onDown: function(/*EventObject*/obj){
561                                // summary: See stencil._Base.onDown
562                                //
563                                this._startdrag = {
564                                        x: obj.pageX,
565                                        y: obj.pageY
566                                };
567                                dojo.disconnect(this._postRenderCon);
568                                this._postRenderCon = null;
569                                this._downOnCanvas = true;
570                        },
571                       
572                        createAnchors: function(){
573                                // summary:
574                                //              Internal. Creates HTML nodes at each corner
575                                //              of the contenteditable div. These nodes are
576                                //              draggable and will resize the div horizontally.
577                                //
578                                this._anchors = {};
579                                var self = this;
580                                var d = this.style.anchors,
581                                        b = d.width,
582                                        w = d.size-b*2,
583                                        h = d.size-b*2,
584                                        p = (d.size)/2*-1 + "px";
585                               
586                                var s = {
587                                        position:"absolute",
588                                        width:w+"px",
589                                        height:h+"px",
590                                        backgroundColor:d.fill,
591                                        border:b+"px " + d.style + " "+d.color
592                                };
593                                if(dojo.isIE){
594                                        s.paddingLeft = w + "px";
595                                        s.fontSize = w + "px"
596                                }
597                                var ss = [
598                                        {top: p, left:p},
599                                        {top:p, right:p},
600                                        {bottom:p, right:p},
601                                        {bottom:p,left:p}
602                                ];
603                                for(var i=0;i<4;i++){
604                                        var isLeft = (i==0) || (i==3);
605                                        var id = this.util.uid(isLeft ? "left_anchor" : "right_anchor");
606                                       
607                                        var a = dojo.create("div", {id:id}, this.parentNode);
608                                        dojo.style(a, dojo.mixin(dojo.clone(s), ss[i]));
609                                       
610                                        var md, mm, mu;
611                                        var md = dojo.connect(a, "mousedown", this, function(evt){
612                                                isLeft = evt.target.id.indexOf("left")>-1;
613                                                self._onAnchor = true;
614                                                var orgX = evt.pageX;
615                                                var orgW = this._box.width;
616                                                dojo.stopEvent(evt);
617                                               
618                                                       
619                                                mm = dojo.connect(document, "mousemove", this, function(evt){
620                                                        var x = evt.pageX;
621                                                        if(isLeft){
622                                                                this._box.left = x;
623                                                                this._box.width = orgW + orgX - x;
624                                                        }else{
625                                                                this._box.width = x + orgW - orgX;
626                                                        }
627                                                        dojo.style(this.parentNode, this._box.toPx());
628                                                });
629                                               
630                                                mu = dojo.connect(document, "mouseup", this, function(evt){
631                                                        orgX = this._box.left;
632                                                        orgW = this._box.width;
633                                                        dojo.disconnect(mm);
634                                                        dojo.disconnect(mu);
635                                                        self._onAnchor = false;
636                                                        conEdit.focus();
637                                                        dojo.stopEvent(evt);
638                                                });
639                                        });
640                                       
641                                        this._anchors[id] = {
642                                                a:a,
643                                                cons:[md]
644                                        }
645                                }
646                        },
647                       
648                        destroyAnchors: function(){
649                                // summary:
650                                //              Internal. Destroys HTML anchors.
651                                for(var n in this._anchors){
652                                        dojo.forEach(this._anchors[n].con, dojo.disconnect, dojo);
653                                        dojo.destroy(this._anchors[n].a);
654                                };
655                        },
656                       
657                        setSavedCaret: function(val){
658                                // summary:
659                                //              Internal, called when caret needs to
660                                //              be moved into position after text is added
661                                this._caretStart = this._caretEnd = val;
662                        },
663                       
664                        getSavedCaret: function(){
665                                return {start: this._caretStart, end: this._caretEnd}
666                        },
667                       
668                        insertText: function(node,val){
669                                // summary:
670                                //              Uses saved caret position to insert text
671                                //              into position and place caret at the end of
672                                //              insertion
673                                //
674                                var t, text = node.innerHTML;
675                                var caret = this.getSavedCaret();
676                               
677                                text = text.replace(/&nbsp;/g, " ");
678                                t = text.substr(0,caret.start) + val + text.substr(caret.end);
679                                t = this.cleanText(t,true);
680                                this.setSavedCaret(Math.min(t.length,(caret.end + val.length)));
681                                node.innerHTML = t;
682                                this.setSelection(node,"stored");
683                        },
684                       
685                        getSelection: function(node){
686                                // summary:
687                                //              This gets and stores the caret position
688                                //              in the contentEditable div (conEdit).
689                                //              NOTE: Doesn't work with html nodes inside
690                                //              the div.
691                                //
692                                var start, end;
693                                if(dojo.doc.selection){
694                                        //debugger;
695                                        var r = dojo.doc.selection.createRange();
696                                        var rs = dojo.body().createTextRange();
697                                        rs.moveToElementText(node);
698                                        var re = rs.duplicate();
699                                        rs.moveToBookmark(r.getBookmark());
700                                        re.setEndPoint('EndToStart', rs);
701                                        start = this._caretStart = re.text.length;
702                                        end = this._caretEnd = re.text.length+r.text.length;
703                                        console.warn("Caret start: ",start," end: ",end," length: ",re.text.length," text: ",re.text);
704                                } else {
705                                        this._caretStart = dojo.global.getSelection().getRangeAt(node).startOffset;
706                                        this._caretEnd = dojo.global.getSelection().getRangeAt(node).endOffset;
707                                        console.log("Caret start: ", this._caretStart," end: ", this._caretEnd);
708                                }
709                        },
710                       
711                        setSelection: function(node, what){
712                                // summary:
713                                //              Used for placing the cursor during edits and character help.
714                                //              Takes the values: end, beg, start, all or any numerical value
715                                //              (in which case the number will constitute the caret position)
716                                //
717                                console.warn("setSelection:");
718                                if(dojo.doc.selection){ // IE
719                                        //debugger;
720                                        var rs = dojo.body().createTextRange();
721                                        rs.moveToElementText(node);
722                                       
723                                        switch(what){
724                                                case "end":
725                                                        rs.collapse(false);
726                                                        break;
727                                                case "beg" || "start":
728                                                        rs.collapse();
729                                                        break;
730                                                case "all":
731                                                        rs.collapse();
732                                                        rs.moveStart("character", 0);
733                                                        rs.moveEnd("character",node.text.length);
734                                                        break;
735                                                case "stored":
736                                                        rs.collapse();
737                                                        var dif = this._caretStart-this._caretEnd;
738                                                        //console.log("start: ",this._caretStart, " end: ",this._caretEnd," dif: ",dif);
739                                                        rs.moveStart("character",this._caretStart);
740                                                        rs.moveEnd("character",dif);
741                                                        break;
742                                        };
743                                        rs.select();
744                                       
745                                }else{
746                                        var getAllChildren = function(node, children){
747                                                children = children || [];
748                                                for(var i=0;i<node.childNodes.length; i++){
749                                                        var n = node.childNodes[i];
750                                                        if(n.nodeType==3){
751                                                                children.push(n);
752                                                        }else if(n.tagName && n.tagName.toLowerCase()=="img"){
753                                                                children.push(n);
754                                                        };
755                                                               
756                                                        if(n.childNodes && n.childNodes.length){
757                                                                getAllChildren(n, children);
758                                                        };
759                                                }
760                                                return children;
761                                        };
762                                        console.log("ff node:", node)
763                                        node.focus();
764                                        var selection = dojo.global.getSelection();
765                                        selection.removeAllRanges();
766                                        var r = dojo.doc.createRange();
767                                        var nodes = getAllChildren(node);
768                                        switch(what){
769                                                case "end":
770                                                        console.log("len:", nodes[nodes.length - 1].textContent.length);
771                                                        r.setStart(nodes[nodes.length - 1], nodes[nodes.length - 1].textContent.length);
772                                                        r.setEnd(nodes[nodes.length - 1], nodes[nodes.length - 1].textContent.length);
773                                                        break;
774                                                case "beg" || "start":
775                                                        r.setStart(nodes[0], 0);
776                                                        r.setEnd(nodes[0], 0);
777                                                        break;
778                                                case "all":
779                                                        r.setStart(nodes[0], 0);
780                                                        r.setEnd(nodes[nodes.length - 1], nodes[nodes.length - 1].textContent.length);
781                                                        break;
782                                                case "stored":
783                                                        console.log("Caret start: ",this._caretStart," caret end: ",this._caretEnd);
784                                                        r.setStart(nodes[0], this._caretStart);
785                                                        r.setEnd(nodes[0], this._caretEnd);
786                                        }
787                                        selection.addRange(r);
788                                        console.log("sel ", what, " on ", node);
789                                }
790                        }
791                }
792        );
793       
794        dojox.drawing.tools.TextBlock.setup = {
795                // summary: See stencil._Base ToolsSetup
796                //
797                name:"dojox.drawing.tools.TextBlock",
798                tooltip:"Text Tool",
799                iconClass:"iconText"
800        };
801        dojox.drawing.register(dojox.drawing.tools.TextBlock.setup, "tool");
802       
803})();
Note: See TracBrowser for help on using the repository browser.