source: branches/1.2/workflow/js/phpeditor/editor.js @ 1349

Revision 1349, 46.2 KB checked in by niltonneto, 15 years ago (diff)

Ticket #561 - Inclusão do módulo Workflow faltante nessa versão.

  • Property svn:executable set to *
Line 
1
2   /******************************************************************
3     editor.js                                              Muze Helene
4     ------------------------------------------------------------------
5     Author: Muze (info@muze.nl)
6     Date: 28 februari 2004
7
8     Copyright 2002 Muze
9
10     This file is part of Helene.
11
12     Helene is free software; you can redistribute it and/or modify
13     it under the terms of the GNU General Public License as published
14     by the Free Software Foundation; either version 2 of the License,
15     or (at your option) any later version.
16 
17     Helene is distributed in the hope that it will be useful,
18     but WITHOUT ANY WARRANTY; without even the implied warranty of
19     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20     GNU General Public License for more details.
21
22     You should have received a copy of the GNU General Public License
23     along with Helene; if not, write to the Free Software
24     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 
25     02111-1307  USA
26
27    -------------------------------------------------------------------
28
29     This file contains the basic editor functionality.
30
31    ******************************************************************/
32
33        var currentLine  = 1;
34        var previousLine = 1;
35        var lastLine     = 0;
36        var screenWidth  = 0;
37        var lineHeight   = 16;
38        var contentDiv;
39        var lines;
40        var inputLine;
41        var inputLineEntry;
42        var oldpos=-1;
43        var isDirty=false;
44        var winW = 630;
45        var winH = 460;
46        var inputLineHasFocus = false;
47        var offsetLine = 0;
48        var currInputHeight = lineHeight;
49        var letterWidth = 9;
50        var clickPosOffsetLeft = 0;
51        var longestLine = 0;
52        var adjustTop = 0;
53        var minInputWidth = 0;
54        var addedSpaces=0;
55        var userSelecting = false;
56        var selectIni=-1;
57        var selectLineIni=-1;
58        var keyBinding = new Array();
59        var keyBindings = new Array();
60        var cancelKey = false;
61        var autoIndent = true;
62        var startcoordinate = false;
63        /* Undo/Redo vars */
64        var undoBuffer = [];
65        var redoBuffer = [];
66        var startCursorPos = -1; // Cursor position before text alteration
67        var saveUndo = true;
68        var isMoz = false;
69        var checkPastedReturns = false;
70        var unsaved = false;
71
72        /* states */
73        var holdingdownkey = false;
74        var holdingupkey = false;
75        var holdingdeletekey = false;
76        var holdingbackkey = false;
77        var holdingenterkey = false;
78        var holdingpgdownkey = false;
79        var holdingpgupkey = false;
80
81        /* search variables */
82
83        var str_search = 'texto';
84
85        /* keybindings */
86        keyBindings["default"]            = new Array();                       
87        keyBindings["default"]["default"] = do_Default;                 // Default action for unrecognized keys
88        keyBindings["default"]["40"]      = do_Down;                    // down
89        keyBindings["default"]["s40"]     = do_SelectDown;              // shift-down
90        keyBindings["default"]["38"]      = do_Up;                              // up
91        keyBindings["default"]["s38"]     = do_SelectUp;                // shift-up
92        keyBindings["default"]["37"]      = do_Left;                    // left
93        keyBindings["default"]["s37"]     = do_SelectLeft;              // shift-left   
94        keyBindings["default"]["39"]      = do_Right;                   // right
95        keyBindings["default"]["s39"]     = do_SelectRight;             // shift-right
96        keyBindings["default"]["8"]       = do_Backspace;               // backspace
97        keyBindings["default"]["46"]      = do_Delete;                  // delete
98        keyBindings["default"]["13"]      = do_Linebreak;               // enter
99        keyBindings["default"]["34"]      = do_PageDown;                // page-down
100        keyBindings["default"]["s34"]     = do_SelectPageDown;  // shift-page-down
101        keyBindings["default"]["33"]      = do_PageUp;                  // page-up
102        keyBindings["default"]["s33"]     = do_SelectPageUp;    // shift-page-up
103        keyBindings["default"]["36"]      = do_Home;                    // home
104        keyBindings["default"]["c36"]     = do_BeginCode;               // ctrl-home
105        keyBindings["default"]["35"]      = do_End;                             // End
106        keyBindings["default"]["c35"]     = do_EndCode;                 // ctrl-end
107        keyBindings["default"]["9"]       = do_Tab;                             // Tab
108        keyBindings["default"]["c86"]     = do_Paste;                   // ctrl-v
109        keyBindings["default"]["c90"]     = do_Undo;                    // ctrl-z
110        keyBindings["default"]["c89"]     = do_Redo;                    // ctrl-y
111        keyBindings["default"]["cs90"]    = do_Redo;                    // ctrl-shift-z
112        //keyBindings["default"]["c67"]     = do_Copy;                  //      ctrl-c
113
114        /* joe bindings */
115        keyBindings["joe"] = new Array();                       
116        keyBindings["joe"]["c65"]     = do_Home;                        // ctrl-e
117        keyBindings["joe"]["c69"]     = do_End;                         // ctrl-a
118        keyBindings["joe"]["c88"]     = do_skipCharsRight;      // ctrl-x
119        keyBindings["joe"]["c90"]     = do_skipCharsLeft;       // ctrl-z
120        keyBindings["joe"]["c75"]     = joe_Ctrlk;                      // ctrl-k
121        keyBindings["joe"]["cs189"]   = do_Undo;                        // ctrl shift -
122        keyBindings["joe"]["cs54"]    = do_Redo;                        // ctrl shift 6
123        keyBindings["joe"]["default"] = joe_Default;
124
125        /* joe ctrl-k bindings */
126        keyBindings["joe"]["ctrl-k"]            = new Array();
127        keyBindings["joe"]["ctrl-k"]["85"]          = joe_ScrollHome;   // ctrl-k u
128        keyBindings["joe"]["ctrl-k"]["86"]          = joe_ScrollEnd;    // ctrl-k v
129        keyBindings["joe"]["ctrl-k"]["default"] = joe_Default_Ctrlk;
130
131        /* keybinding to use */
132        keyBinding = keyBindings["default"];
133
134       
135        /* undo buffer constants */
136        var undo = { CHANGE_TEXT: 1, LINE_AFTER: 2, DELETE_LINE: 3 };
137        var window_title;
138
139        function handleMouseWheel(e)
140        {
141                if (!e) e = window.event;
142
143                if ( e.wheelDelta <= 0 || e.detail > 0)
144                {
145                        window.scrollBy(0,30);
146                }
147                else
148                {
149                        window.scrollBy(0,-30);
150                }
151        }
152
153
154
155        function setInputFocus()
156        {
157                inputLineEntry.focus();
158        }
159
160        function init() {
161                contentDiv      = document.getElementById('content');   
162                codeframeDiv    = document.getElementById('codeframe');
163                lines           = document.getElementById('lines');
164                lineHeight      = lines.childNodes[0].offsetHeight;
165                currInputHeight = lineHeight;
166                lastLine        = lines.childNodes.length;
167                inputLine       = document.getElementById('inputLine');
168                inputLineEntry  = document.getElementById('inputLineEntry');
169                window_title    = window.parent.document.title;
170
171                if (parseInt(navigator.appVersion) > 3)
172                {
173                        if (navigator.appName == "Netscape")
174                        {
175                                isMoz = true;
176                                winW = window.innerWidth-42;
177                                winH = window.innerHeight-2;
178                                minInputWidth = winW-16;
179                                document.onkeypress = moz_onKeyPress;
180                                document.onkeydown  = keyDownHandler;
181                                document.onkeyup    = keyUpHandler;
182                                init_mozilla_compat();
183                                window.addEventListener("DOMMouseScroll", handleMouseWheel, false);
184                                /* do some w3c dom magic to get the current font size */
185                                var vw         = document.defaultView;
186                                var currStyle  = vw.getComputedStyle(lines,"");
187                                var fontSize   = currStyle.getPropertyValue("font-size");
188                                var fontFamily = currStyle.getPropertyValue("font-family");
189                        }
190                        else
191                        if (navigator.appName.indexOf("Microsoft")!=-1)
192                        {
193                                winW = document.body.offsetWidth;
194                                winH = document.body.offsetHeight;
195                                document.onkeydown = keyDownHandler;
196                                document.onkeyup   = keyUpHandler;
197                                /* get current font size */
198                                var fontSize       = lines.currentStyle.fontSize;
199                                var fontFamily     = lines.currentStyle.fontFamily;
200                                clickPosOffsetLeft = 44;
201                                minInputWidth      = winW-60;
202                                // To handle clipboard paste
203                                inputLineEntry.onpaste = pasteText;
204                        }
205                        else
206                        {
207                                document.onkeydown = keyDownHandler;
208                                /* do some w3c dom magic to get the current font size */
209                                var vw         = document.defaultView;
210                                var currStyle  = vw.getComputedStyle(lines,"");
211                                var fontSize   = currStyle.getPropertyValue("font-size");
212                                var fontFamily = currStyle.getPropertyValue("font-family");
213                        }
214
215                }
216
217                /* if the user closes the editor without saving his work, a confirmation is required to do so */
218                window.onbeforeunload = confirmExit;
219                function confirmExit()
220                {
221                        if (unsaved)
222                                return "Existem alterações neste arquivo que serão perdidas caso esta janela seja fechada.";
223                }
224
225                document.getElementById('linenumbers').style.height = winH;
226                updateLineNumbers();
227                inputLine.style.width  = minInputWidth;
228                inputLine.style.height = lineHeight;
229                inputLineEntry.onfocus = inputFocus;
230                inputLineEntry.onblur  = inputBlur;             
231                inputLineEntry.style.fontSize   = fontSize;
232                inputLineEntry.style.fontFamily = fontFamily;
233                inputLineEntry.style.height     = lineHeight;
234                inputLineEntry.style.overflow   = 'hidden';
235
236                // this is needed because MSIE sometimes shifts the textarea a bit...
237                adjustTop = -inputLineEntry.offsetTop;
238
239                /* calculate width, height of one letter, fix padding if needed */
240                var templine = lines.childNodes[0].innerHTML;
241                lines.childNodes[0].innerHTML='<span id="editorLetterWidth">m</span>';
242                letterWidth=document.getElementById("editorLetterWidth").offsetWidth;
243                spanHeight=document.getElementById("editorLetterWidth").offsetHeight;
244                spanTopPadding=document.getElementById("editorLetterWidth").offsetTop;
245                if (lineHeight>spanHeight) {
246                        // this is to make background colors span the entire height of the line
247                        spanBottomPadding=(lineHeight-spanHeight)-spanTopPadding;
248                } else {
249                        spanBottomPadding=0;
250                }
251                if (spanTopPadding || spanBottomPadding) {
252                        // get the stylesheet and apply this padding to each span
253                        var editorStylesheet=document.styleSheets[0];
254                        if (navigator.appName.indexOf("Microsoft")!=-1) {               
255                                editorStylesheet.addRule("SPAN", "padding-top: "+spanTopPadding+"px; padding-bottom: "+spanBottomPadding+"px;", 0);
256                        } else {
257                                editorStylesheet.insertRule("SPAN { padding-top: "+spanTopPadding+"px; padding-bottom: "+spanBottomPadding+"px; }", 0);
258                        }
259                }
260                lines.childNodes[0].innerHTML=templine;
261                document.onmousedown = mouseDownHandler;
262                document.onmouseup = mouseUpHandler;
263                window.onresize  = resizeHandler;;
264               
265                var _temp='';
266                for (var i=0; i<lines.childNodes.length; i++) {
267                        // need to remove trailing ' ', which IE puts there.
268                        _temp=getLineContent(i+1);
269                        if (navigator.appName.indexOf("Microsoft")!=-1) {
270                                _temp=_temp.substr(0, _temp.length-1);
271                        }
272                        if (_temp.length>longestLine) {
273                                longestLine=_temp.length;
274                        }
275                        currLine=new hLine(i, _temp);
276                        currLine.doHighlight(applyHighlightedLine);
277                }
278                if ((longestLine*letterWidth)>minInputWidth) {
279                        inputLine.style.width=longestLine*letterWidth+4;
280                }
281
282                redrawInputLine();
283        }
284
285        function pasteText() {
286                var content = clipboardData.getData('text');
287                var re = /^([^\n\r]*)(\r\n|\r|\n)/;
288                var match;
289                var lines;
290                var cur = currentLine;
291       
292                if (document.selection) { // For IE only
293                        var tr = document.selection.createRange();
294                        tr.text = content;
295                        content = inputLineEntry.value;
296                } else { // There is nothing to do in Mozilla
297                        return;
298                }
299/*
300                match = re.exec(content);
301                if( match && match[1] != null ) {
302                        inputLineEntry.value = match[1];
303                        isDirty = true;
304                        checkDirty();
305                        updateLine(currentLine,match[1]);
306                        content = content.substr(match[0].length);
307                } else {
308                        isDirty = true;
309                        checkDirty();
310                        updateLine(currentLine,content);
311                        content = false;
312                }
313                if(content != false) {
314                        while( content != false ) {
315                                var trans;
316                                match = re.exec(content);
317                                if( match && match[1] != null ) {
318                                        trans = match[1];
319                                        content = content.substr(match[0].length);
320                                } else {
321                                        trans = content;
322                                        content = false;
323                                }
324                                insertLineAfter(cur++,trans);
325                        }
326                }
327*/             
328
329                content = content.replace(/\r\n/g, "\n");
330                content = content.replace(/\r/g, "\n");
331
332                lines = content.split('\n');
333                inputLineEntry.value = lines[0];       
334                isDirty = true;
335                checkDirty();
336                updateLine(currentLine,lines[0]);
337       
338                for (i = 1; i<lines.length; i++) {
339                        insertLineAfter(cur++,lines[i]);
340                }
341
342                event.returnValue=false;
343        }
344
345        function init_mozilla_compat() {
346                HTMLElement.prototype.insertAdjacentHTML = function (sWhere, sText) {
347                        var r = document.createRange();
348                        safewhere = sWhere.toLowerCase();
349                        switch (safewhere) {
350                                case "beforebegin":
351                                        r.setStartBefore(this);
352                                        this.parentNode.insertBefore(r.createContextualFragment(sText), this);
353                                        break;
354
355                                case "afterbegin":
356                                        r.setStartBefore(this.firstChild);
357                                        this.insertBefore(r.createContextualFragment(sText), this.firstChild);
358                                        break;
359
360                                case "beforeend":
361                                        r.setStartAfter(this.lastChild);
362                                        this.appendChild(r.createContextualFragment(sText));
363                                        break;
364
365                                case "afterend":
366                                        r.setStartAfter(this);
367                                        this.parentNode.insertBefore(r.createContextualFragment(sText),
368                                                this.nextSibling);
369                                        break;
370                        }
371                };
372                Node.prototype.removeNode = function( removeChildren ) {
373                        var self = this;
374                        if ( Boolean( removeChildren ) )
375                        {
376                                return this.parentNode.removeChild( self );
377                        }
378                        else
379                        {
380                                var range = document.createRange();
381                                range.selectNodeContents( self );
382                                return this.parentNode.replaceChild( range.extractContents(), self );
383                        }
384                };
385        }
386
387        function inputFocus() {
388                inputLineHasFocus=true;
389        }
390
391        function inputBlur() {
392                inputLineHasFocus=false;
393        }
394
395        function applyHighlightedLine(lineNo, highlightedLine) {
396                // the extra span is to correctly calculate the offset of the content
397                // to position the input line
398                setLineContent(lineNo+1, '<span><nobr>'+highlightedLine+'</nobr></span>');
399        }
400
401        function moveDown(amount) {
402                //FIXME: start made with selections
403                //  change moveUp as well
404                //  and change textarea size back again in stopselect
405                if (userSelecting) {
406                        if( (currentLine + offsetLine) < lastLine ) { // Don't select past the last line...
407                                currInputHeight+=lineHeight;
408                                inputLine.style.height=currInputHeight;
409                                inputLineEntry.style.height=currInputHeight;
410                                inputLineEntry.value+='\n'+getLineContent(currentLine+offsetLine+1);
411
412                                offsetLine = inputLineEntry.value.split('\n').length - 1;
413                            window.scrollBy(0,lineHeight);     
414                                setCursorPos(selectIni,getCursorPos());
415                                return !isMoz;
416                        } else {
417                                return false;
418                        }
419                } else {
420                        checkDirty();
421                        if (currentLine<lastLine) {
422                                previousLine = currentLine;
423                                currentLine+=amount;
424                                if (currentLine>lastLine) {
425                                        currentLine=lastLine;
426                                }
427                                redrawInputLine();
428                        }
429                        return !isMoz;
430                }
431        }
432
433        function moveUp(amount) {
434                if( userSelecting) {
435                        if( offsetLine > 0 ) { // Don't select smaller than 1 line
436                                currInputHeight            -= lineHeight;
437                                inputLine.style.height      = currInputHeight;
438                                inputLineEntry.style.height = currInputHeight;
439                               
440                                var myValue = inputLineEntry.value;
441                                var lines;
442
443                                if (isMoz) {
444                                        myValue = myValue.replace(/(.*)\n(.*[\n]?)$/,"$1"); //remove last line
445                                } else {
446                                        myValue = myValue.replace(/(.*)\r\n(.*)$/,"$1"); //remove last line
447                                }
448                               
449                                inputLineEntry.value = myValue;
450                                offsetLine = inputLineEntry.value.split('\n').length - 1;
451                            window.scrollBy(0,-lineHeight);     
452                                setCursorPos(selectIni,getCursorPos());
453                                return !isMoz;
454                        } else {
455                                return false;
456                        }
457                } else {
458                        checkDirty();
459                        if (currentLine>1) {
460                                previousLine = currentLine;
461                                currentLine-=amount;
462                                if (currentLine<1) {
463                                        currentLine=1;
464                                }
465                                redrawInputLine();
466                        }
467                        return !isMoz;
468                }
469        }
470
471        function redrawInputLine(dontfocus) {
472                var pos;
473                if (!dontfocus) {
474                        var oldline;
475                        oldpos = getCursorPos();
476                        /*
477                         * we are gona calculate the real old pos by counting tabs for 8
478                         */
479                        //oldline = getLineContent(previousLine);
480                        newline = getLineContent(currentLine);
481                        if (newline.length < oldpos)
482                                oldpos = newline.length;
483                }
484                // mozilla sometimes jumps the lines offset around, so we need to get the
485                // offset of the content of the line, not the line itself
486                var mytop=lines.childNodes[currentLine-1].firstChild.offsetTop+adjustTop;
487                //inputLine.style.top = mytop;
488                inputLine.style.top = (currentLine - 1)*lineHeight;
489               
490                var value=getLineContent(currentLine);
491                inputLineEntry.value=value;
492                if (!dontfocus) {
493                        pos = oldpos;
494                        setCursorPos(pos);
495//                      I don't think this is needed anymore
496//                      inputLineEntry.focus(); // scroll into view pls..
497                }
498                startCursorPos = -1;
499                /* update the informatin panel */
500                parent.document.getElementById('info').innerHTML = currentLine + " / " + lines.childNodes.length;
501        }
502
503        function getCursorPos() {
504                // don't set the focus to the input line here, or the screen
505                // will 'dance' around. Its not needed anyway.
506                if (document.selection) {
507                        var mtext=document.selection.createRange();
508                        var count=0;
509                        var moved=0;
510                        while (moved=mtext.moveStart('character', -100)) {
511                                count-=moved;
512                        }
513                        chars=mtext.text.length;
514                        return chars;
515                } else {
516                        var selection=window.getSelection();
517                        if (selection.anchorNode) {
518                                var len = inputLineEntry.selectionEnd;
519                                return len;
520                        }
521                }
522        }
523
524
525        function setCursorPos(cursorstart, cursorend, clicked) {
526                var counter;
527                var contents=new String(inputLineEntry.value);
528                if (cursorstart==-1) {
529                        cursorstart=contents.length;
530                }
531
532                /*
533                counter = cursorstart;
534                cursorstart = 0;
535                while(counter > 0){
536                        if(contents.charAt(cursorstart) == "\t"){
537                                counter -= 7;
538                        }
539                        cursorstart++;
540                        counter--;
541                }
542                cursorstart = cursorstart;
543                */
544
545                if (contents.length<cursorstart && !clicked) {
546                        addedSpaces=cursorstart-contents.length+1;
547                        for (i=0; i<addedSpaces; i++ ){
548                                contents+=' ';
549                        }
550                        inputLineEntry.value=contents;
551                } else if (clicked) {
552                        if (cursorstart>contents.length) {
553                                cursorstart=contents.length;
554                        }
555                        addedSpaces=0;
556                } else {
557                        addedSpaces=0;
558                }
559                if (document.selection) {
560                        var mtext=inputLineEntry.createTextRange();
561                        mtext.collapse(true);
562                        mtext.moveStart('character', cursorstart);
563                        mtext.collapse(true);
564                        if (cursorend) {
565                                mtext.moveEnd('character', (cursorend-cursorstart));
566                        }
567                        mtext.select();
568                } else {
569                        // do something Mozilla style
570                        if (!cursorend) {
571                                cursorend=cursorstart;
572                        }
573                        // for mozilla, set the focus to scroll the input line into view
574                        inputLineEntry.focus();
575                        inputLineEntry.setSelectionRange(cursorstart, cursorend);
576               
577/*
578                        var selection=window.getSelection();
579                        if (selection.anchorNode) {
580                                inputLineEntry.selectionStart = cursorstart;
581                                if (cursorend) {
582                                        inputLineEntry.selectionEnd = cursorend;
583                                } else {
584                                        inputLineEntry.selectionEnd = cursorstart;
585                                }
586                        }
587*/
588                }
589
590                // calculate cursor position in px
591                if (cursorend) {
592                        var scrollToChar=cursorend;
593                } else {
594                        var scrollToChar=cursorstart;
595                }
596                cursorpx=letterWidth*(scrollToChar+10);
597                if (cursorpx>150) { //(winW-44)) {
598//                      don't do this, let IE and mozilla handle it themselves
599//                      document.body.scrollLeft=cursorpx+44;
600                } else {
601                        document.body.scrollLeft=0;
602                }
603                return false;
604        }
605
606        function removeAddedSpaces() {
607                if (addedSpaces) {
608                        var _temp=new String(inputLineEntry.value);
609                        _temp=_temp.substr(0, _temp.length-addedSpaces);
610                        inputLineEntry.value=_temp;
611                        addedSpaces=0;
612                }
613        }
614
615        function getLineContent(lineNo) {
616                var myString = new String();
617                if(lines.childNodes[lineNo-1]){
618                        if( typeof(lines.childNodes[lineNo-1].originalInnerText)!="undefined" ) {
619                                return lines.childNodes[lineNo-1].originalInnerText;
620                        }
621                        if (lines.childNodes[lineNo-1].innerText) {
622                                return lines.childNodes[lineNo-1].innerText;
623                        } else if (document.createRange) {
624                                var html = document.createRange();
625                                var myLine = lineNo-1;
626                                while( lines.childNodes[myLine].tagName != 'LI' ) {
627                                        myLine++;
628                                }
629                                html.selectNodeContents(lines.childNodes[myLine]);
630                                myString = html.toString();
631                                myString = myString.replace(/\n/g, '');
632                                myString = myString.replace(/\r/g, '');
633                                return myString;
634                        }
635                }
636                return "";
637        }
638
639        function getContents() {
640                var i=1;
641                var myContent='';
642                checkDirty();
643                while( lines.childNodes[i-1] ) {
644                        myContent = myContent + getLineContent(i) + '\n';
645                        i++;
646                }
647                return myContent;
648        }
649
650        function setContents(content) {
651                var myHead;
652        var re = /^([^\n\r]*)(\r\n|\r|\n)/;
653                var match;
654                var originalArray = new Array();
655
656                deleteContents();
657
658                match = re.exec(content);
659                if( match && match[1] != null ) {
660                        updateLine(1,match[1]);
661                        originalArray[lastLine] = match[1];
662                      content = content.substr(match[0].length);
663                } else {
664                        updateLine(1,content);
665                        originalArray[lastLine] = content;
666                        content = false;
667                }
668                if(content != false) {
669                        var htmlcontent = '';
670                        while( content != false ) {
671                                var trans;
672                                match = re.exec(content);
673                                if( match && match[1] != null ) {
674                                        trans = match[1];
675                                      content = content.substr(match[0].length);
676                                } else {
677                                        trans = content;
678                                        content = false;
679                                }
680                                lastLine++;
681                                originalArray[lastLine] = trans;
682                                trans = trans.replace(/[&]/g,"&amp;");
683                                trans = trans.replace(/[<]/g,"&lt;");
684                                trans = trans.replace(/[>]/g,"&gt;");
685                                trans = trans.replace(/[ ]/g,"&nbsp;");
686                                trans = trans.replace(/["]/g,"&quot;");
687                                htmlcontent += "<li>"+trans+"\n</li>";
688                        }
689                        if(htmlcontent){
690                                lines.childNodes[0].insertAdjacentHTML("AfterEnd",htmlcontent);
691                        }
692                }
693                var _temp='';
694                for (var i=1; i<lines.childNodes.length; i++) {
695                        lines.childNodes[i].originalInnerText = originalArray[i+1];
696                        _temp=getLineContent(i+1);
697                        if (_temp.length>longestLine) {
698                                longestLine=_temp.length;
699                        }
700                       
701                        currLine=new hLine(i, _temp);
702                        currLine.doHighlight(applyHighlightedLine);
703                }
704                if ((longestLine*letterWidth)>minInputWidth) {
705                        inputLine.style.width=longestLine*letterWidth+4;
706                }
707                currentLine=1;
708                updateLineNumbers();
709                redrawInputLine();
710                undoBuffer = [];
711                redoBuffer = [];
712
713                //inputLine.style.display = 'none';
714                //document.getElementById('editor').contentWindow.document.designMode = "on";
715        }
716
717        function setKeyBinding(keybind) {
718                if( keyBindings[keybind] ) {
719                        keyBinding = keyBindings[keybind];
720                }
721        }
722
723
724        function setAutoIndent(indentvalue) {
725                if( indentvalue == "on" ) {
726                        autoIndent = true;
727                } else {
728                        autoIndent = false;
729                }
730        }
731
732        function keyUpHandler(evt) {
733
734                var charCode;
735                var iniDelLine;
736
737                if (isMoz) {
738                        charCode = (evt.charCode ? evt.charCode : ((evt.keyCode) ? evt.keyCode : evt.which));
739                } else {
740                        charCode = window.event.keyCode;
741                        evt = window.event;
742                }
743               
744                charCode = parseInt(charCode);
745               
746                holdingupkey     = false;
747                holdingdownkey   = false;
748                holdingdeletekey = false;
749                holdingbackkey   = false;
750                holdingpgupkey   = false;
751                holdingpgdownkey = false;
752
753                if ( holdingenterkey ) {
754                        redrawInputLine();
755                        holdingenterkey = false;
756                }
757
758                if( isMoz && checkPastedReturns ) {
759                        fixPastedReturns();
760                        checkPastedReturns = false;
761                }
762
763                if ( ( ( evt.ctrlKey ) && ( charCode != 88 ) ) || ( charCode == 67 ) )
764                        return false;
765       
766                if (userSelecting &&
767                      (
768                                 isNormalKey(charCode)
769                         || ( charCode == 46 ) /*delete key*/
770                                 || ( charCode == 8  ) /*bakspace key*/
771                          )
772                        ) {
773                               
774                       
775                        iniDelLine = currentLine + 1;
776                       
777                        isDirty = true;
778                        checkDirty();
779
780                        deleteMultipleLines(iniDelLine,currentLine+offsetLine);
781                        //for (i=iniDelLine;i<=currentLine+offsetLine;i++)
782                        //      deleteLine(iniDelLine);
783
784                        stopSelect();
785                        //redrawInputLine(true);
786                }
787
788                if (
789                         isNormalKey(charCode)
790                         || ( charCode == 46 ) /*delete key*/
791                         || ( charCode == 8  ) /*bakspace key*/
792                         || ( charCode == 13 ) /*enter key*/
793                        )
794                {
795                        window.parent.document.title = window_title + ' (+)';
796                        unsaved = true;
797                }
798
799                if ( ( charCode == 38 ) && userSelecting ) {
800                        //inputLineEntry.setSelectionRange(selectIni, inputLineEntry.value.length);
801                        setCursorPos(selectIni,inputLineEntry.value.length);
802                }
803               
804                if (isMoz) {
805                        if ( ( charCode == 37 ) && userSelecting ) {
806                                if (inputHasLineEnd())
807                                        fixLineGap();
808                        }
809                }
810                window.status = 'L: '+currentLine+' C: '+(getCursorPos()+1);
811        }
812
813
814        function fixPastedReturns(mousepaste) {
815                var re = /^([^\n\r]*)(\r\n|\r|\n)/;
816                var match;
817                var content = inputLineEntry.value;
818                var cur = currentLine;
819                var lines;
820               
821                if (isMoz) {
822                        if (mousepaste) {
823                                content = content.replace(/#/g, ""); //remove # from mozilla browsers!!
824                        } else {
825                                content = content.replace(/^#/g, ""); //remove # from mozilla browsers!!       
826                        }
827                        /*
828                        content = content.replace(/\r\n/g, "\n");
829                        content = content.replace(/\r/g, "\n");
830                        */
831                }
832
833               
834                match = re.exec(content);
835                if( match && match[1] != null ) {
836                        inputLineEntry.value = match[1];
837                        isDirty = true;
838                        checkDirty();
839                        updateLine(currentLine,match[1]);
840                        content = content.substr(match[0].length);
841                } else {
842                        content = false;
843                }
844                while( content != false ) {
845                        var trans;
846                        match = re.exec(content);
847                        if( match && match[1] != null ) {
848                                trans = match[1];
849                                content = content.substr(match[0].length);
850                        } else {
851                                trans = content;
852                                content = false;
853                        }
854                        insertLineAfter(cur++,trans);
855                }
856       
857                inputLineEntry.focus();
858       
859                /*
860                lines = content.split('\n');
861                inputLineEntry.value = lines[0];       
862                isDirty = true;
863                checkDirty();
864                updateLine(currentLine,lines[0]);
865       
866                for (i = 1; i<lines.length; i++) {
867                        insertLineAfter(cur++,lines[i]);
868                }
869                */
870        }
871
872
873        function moz_onKeyPress(evt) {
874                // Mozilla has a lot of trouble canceling events
875                // an onkeydown event can not be cancelled
876                // so we cancel the onkeypress...
877                if( cancelKey ) {
878                        cancelKey = false;
879                        return false;
880                } else {
881                        if (holdingdownkey) {
882                                moveDown(1);
883                        }
884                        if (holdingupkey) {
885                                moveUp(1);
886                        }
887                        if (holdingpgupkey) {
888                                do_PageUp();
889                        }
890                        if (holdingpgdownkey) {
891                                do_PageDown();
892                        }
893                        if (holdingdeletekey)
894                                do_Delete();
895                        if (holdingbackkey)
896                                do_Backspace();
897                        if (holdingenterkey) {
898                                //insertLineAfter(currentLine, new String(getLineContent(currentLine)));
899                                //updateLine(currentLine-1, '');
900                                //setCursorPos(0);
901                                //inputLineEntry.focus();
902                                insertLineAfter(currentLine, '');
903                                //isDirty = true;
904                                //checkDirty();
905                                //inputLineEntry.focus();
906                                //breakCurrentLine();
907                        }
908                        return true;
909                }
910        }
911       
912        function keyDownHandler(evt) {
913                var charCode;
914                var charString = '';
915                var keyResult;
916
917               
918                evt = (evt) ? evt : ((event) ? event : null );
919                if( evt ) {
920                        // Get the key pressed
921                       
922                        charCode = (evt.charCode ? evt.charCode : ((evt.keyCode) ? evt.keyCode : evt.which));
923
924                        // Create the encoded character string
925
926                        charString = charCode;
927                        if( evt.shiftKey ) {
928                                charString = 's' + charString;
929                        }       
930                        if( evt.ctrlKey ) {
931                                charString = 'c' + charString;
932                        }                       
933                        if( evt.altKey ) {
934                                charString = 'a' + charString;
935                        }
936
937
938                        if( keyBinding[charString] ) {
939                                keyResult = keyBinding[charString]();
940                        } else {
941                                keyResult = keyBinding["default"](charString);
942                        }
943
944                        if( ! keyResult ) {
945                                cancelKey = true;
946                                if( evt.preventDefault ) {
947                                        // This is the DOM way to cancel it but somehow
948                                        // Mozilla refuses. Maybe another DOM browser will
949                                        // make use of it :)
950                                        evt.preventDefault();
951                                }
952                        }
953
954                        return keyResult;
955                }
956        }
957
958
959        function joe_Ctrlk(charString) {
960                keyBinding = keyBindings["joe"]["ctrl-k"];
961                window.status = "ctrl-k ";
962                return false;
963        }
964
965        function joe_Default_Ctrlk(charString) {
966                keyBinding = keyBindings["joe"];
967                window.status = "ctrl-k " + charString;
968                return false;
969        }
970
971        function joe_Default(charString) {
972                var keyBinding;
973                keyBinding = keyBindings["default"];
974                if( keyBinding[charString] ) {
975                        return keyBinding[charString]();
976                } else {
977                        window.status = charString;
978                        return keyBinding["default"](charString);
979                }
980        }
981
982        function joe_ScrollEnd() {
983                keyBinding = keyBindings["joe"];
984                window.status = "ctrl-k v";
985                currentLine = lastLine;
986                redrawInputLine();
987                //window.scroll(800,inputLine.style.top);
988                //window.scroll(0,0);
989                do_End();               
990                return false;
991        }
992       
993        function joe_ScrollHome() {
994                keyBinding = keyBindings["joe"];
995                window.status = "ctrl-k u";
996                currentLine = 1;
997                redrawInputLine();
998                do_Home();
999                return false;
1000        }
1001
1002        function do_Default(charString) {
1003                removeAddedSpaces();
1004                oldpos=-1;
1005                isDirty=true;
1006                if(startCursorPos<0) startCursorPos = getCursorPos();
1007                return true;
1008        }
1009       
1010        function do_SelectUp() {
1011                startSelect();
1012                return do_Up(true);
1013        }
1014       
1015        function do_SelectDown() {
1016                startSelect();
1017                return do_Down(true);
1018        }
1019       
1020        function do_Down(selecting) {
1021                if( !selecting ) {
1022                        stopSelect();
1023                        if ( inputHasLineEnd() ) {
1024                                redrawInputLine();
1025                        }
1026                }
1027                holdingdownkey = true;
1028                return moveDown(1);
1029        }
1030       
1031        function do_Up(selecting) {
1032                if( !selecting ) {
1033                        stopSelect();
1034                        if ( inputHasLineEnd() )
1035                                redrawInputLine();
1036                }
1037                holdingupkey = true;
1038                return moveUp(1);
1039        }
1040       
1041        function do_SelectLeft() {
1042                startSelect();
1043                return do_Left(true);
1044        }
1045
1046        function do_Left(selecting) {
1047                var result=true;
1048                var content;
1049
1050                //if (isMoz) {
1051                        //checkDirty();
1052                //}
1053
1054                if( !selecting ) {
1055                        stopSelect();
1056                        if ( inputHasLineEnd() )
1057                                redrawInputLine();
1058                } else {
1059                        if (!isMoz) {
1060                                content = inputLineEntry.value;
1061                                if (content.charAt(getCursorPos()) == '\r') {
1062                                        fixLineGap();
1063                                }
1064                        }
1065                }
1066                if (addedSpaces) {
1067                        removeAddedSpaces();
1068                        result=false;
1069                }
1070                oldpos=-1;
1071                return result;
1072        }
1073
1074        function do_SelectRight() {
1075                startSelect();
1076                return do_Right(true);
1077        }
1078
1079        function do_Right(selecting) {
1080                var result=true;
1081       
1082                //if (isMoz) {
1083                //      checkDirty();
1084                //}
1085               
1086                if( !selecting ) {
1087                        stopSelect();
1088                        if ( inputHasLineEnd() )
1089                                redrawInputLine();
1090                }
1091                //if (currentLine<lastLine) {
1092                //      var _currline=getLineContent(currentLine);
1093                //      if (getCursorPos()>=_currline.length) {
1094                //              moveDown(1);
1095                //              setCursorPos(0);
1096                //              result=false;
1097                //      }
1098                //}
1099                oldpos=-1;
1100                if ( isMoz && ( getCursorPos() == ( inputLineEntry.value.length - 1 ) ) )
1101                {
1102                        setCursorPos(inputLineEntry.value.length);
1103                }
1104                return result;
1105        }
1106
1107        function do_Backspace() {
1108                var result=true;
1109                holdingbackkey = true;
1110
1111                if (addedSpaces) {
1112                        removeAddedSpaces();
1113                        result=false;
1114                } else {
1115                        oldpos=-1;
1116                        if (getCursorPos()==0) {
1117                                checkDirty();
1118                                glueCurrentLine(-1);
1119                                result=false;
1120                        }
1121                        isDirty=true;
1122                }
1123                return result;
1124        }
1125
1126        function do_Delete() {
1127                var result=true;
1128       
1129                holdingdeletekey = true;
1130
1131                if (addedSpaces) {
1132                        removeAddedSpaces();
1133                        result=false;
1134                } else {
1135                        oldpos=-1;
1136                        if (currentLine<lastLine) {
1137                                var _editline=inputLineEntry.value;
1138                                if (getCursorPos()==_editline.length) {
1139                                        if (!isMoz) {
1140                                                document.selection.createRange().text = "";
1141                                        } else {
1142                                                inputLineEntry.value = inputLineEntry.value.substring(0,inputLineEntry.selectionStart) +
1143                                                                                           inputLineEntry.value.substring(inputLineEntry.selectionEnd,inputLineEntry.value.length);
1144                                        }
1145                                        checkDirty();
1146                                        if (offsetLine == 0)
1147                                                glueCurrentLine(1);
1148                                        result = false;
1149                                }
1150                        }
1151                        isDirty=true;
1152                }
1153                return result;
1154        }
1155
1156        function do_Linebreak() {
1157                if (userSelecting)
1158                        return false;
1159                holdingenterkey = true;
1160                removeAddedSpaces();
1161                oldpos=-1;
1162                breakCurrentLine();
1163                return false;
1164        }
1165
1166        function do_SelectPageDown() {
1167                startSelect();
1168                return do_PageDown();
1169        }
1170
1171        function do_PageDown() {
1172                holdingpgdownkey = true;
1173                moveDown(20);
1174                return false;
1175        }
1176
1177        function do_SelectPageUp() {
1178                startSelect();
1179                return do_PageUp();
1180        }
1181
1182        function do_PageUp() {
1183                holdingpgupkey = true;
1184                moveUp(20);
1185                return false;
1186        }
1187
1188        function do_Home() {
1189                if (userSelecting)
1190                        return false;
1191                removeAddedSpaces();
1192                setCursorPos(0);
1193                window.parent.scrollBy(-2000,0);
1194                oldpos = -1;
1195                return false;
1196        }
1197
1198        function do_End() {
1199                if (userSelecting)
1200                        return false;
1201                removeAddedSpaces();
1202                setCursorPos(inputLineEntry.value.length);
1203                if (getCursorPos()*letterWidth + linenumbers.style.width > window.parent.innerWidth) {
1204                        window.parent.scrollBy(getCursorPos()*letterWidth,0);
1205                }
1206                oldpos = -1;
1207                return false;
1208        }
1209
1210        function do_Tab() {
1211                var line = inputLineEntry.value;
1212                var cursor = getCursorPos();
1213                if (userSelecting)
1214                        return false;
1215                line = line.substr(0,cursor) + "\t" + line.substr(cursor);
1216                inputLineEntry.value = line;
1217                setCursorPos(cursor + 1);
1218                isDirty=true;
1219                return false;
1220        }
1221
1222        function do_skipCharsRight() {
1223                return skipChars(1);
1224        }
1225
1226        function do_skipCharsLeft() {
1227                return skipChars(-1);
1228        }
1229
1230        function do_Paste() {
1231                if( isMoz ) {
1232                        checkPastedReturns = true;
1233                }
1234                isDirty = true;
1235                return true;
1236        }
1237       
1238        function do_Undo() {
1239                checkDirty();
1240                if(undoBuffer.length<1) {
1241                        return false;
1242                }
1243                var u = undoBuffer.pop();
1244                UndoIt(u,redoBuffer);
1245                return false;
1246        }
1247       
1248        function do_Redo() {
1249                if(redoBuffer.length<1) {
1250                        return false;
1251                }
1252                var u = redoBuffer.pop();
1253                UndoIt(u,undoBuffer);
1254                return false;
1255        }
1256               
1257        function UndoIt(u,redoBuffer) {
1258                saveUndo = false;
1259                switch(u.type) {
1260                        case undo.CHANGE_TEXT:
1261                                updateLine(u.line,u.text);
1262                                redoBuffer.push({ type: u.type, line: u.line, text: u.newText, newText: u.text, cursor: u.newCursor, newCursor: u.cursor });
1263                          break;
1264                        case undo.LINE_AFTER:
1265                                deleteLine(u.line);
1266                                redoBuffer.push({ type: undo.DELETE_LINE, line: u.line, text: u.text, cursor: u.newCursor, newCursor: u.cursor });
1267                          break;
1268                        case undo.DELETE_LINE:
1269                                insertLineAfter(u.line-1,u.text);
1270                                redoBuffer.push({ type: undo.LINE_AFTER, line: u.line, text: u.text, cursor: u.newCursor, newCursor: u.cursor });
1271                          break;
1272                        default:
1273                                saveUndo = true;
1274                                return false;
1275                }               
1276                currentLine = u.line;
1277                inputLineEntry.value = getLineContent(currentLine);
1278                redrawInputLine();
1279                setCursorPos(u.cursor);
1280                saveUndo = true;
1281                return true;
1282        }
1283       
1284        function addUndo(ob) {
1285                undoBuffer.push(ob);
1286                redoBuffer = [];
1287        }
1288
1289        function skipChars(dir) {
1290                var cursor, curstate, curchar;
1291                function is_letter (l) {
1292                        if (l >= 'a' && l <= 'z' ||
1293                                l >= 'A' && l <= 'Z') {
1294                                        return true;
1295                        } else {
1296                                        return false;
1297                        }
1298                }
1299
1300                removeAddedSpaces();
1301                cursor = getCursorPos();
1302                if (dir < 0) {
1303                        cursor--;
1304                }
1305                curstate = is_letter(inputLineEntry.value.charAt(cursor));
1306                if (!curstate) {
1307                        /* forward over current state */
1308                        while (curstate == is_letter(inputLineEntry.value.charAt(cursor+=dir))
1309                                && cursor > 0 && cursor < inputLineEntry.value.length){};
1310                } else {
1311                        cursor += dir;
1312                }
1313
1314                curstate = is_letter(inputLineEntry.value.charAt(cursor));
1315                /* forward over next state */
1316                while (curstate == is_letter(inputLineEntry.value.charAt(cursor+=dir))
1317                                && cursor > 0 && cursor < inputLineEntry.value.length);
1318
1319                if (dir < 0) {
1320                        cursor++;
1321                }
1322
1323                if (cursor < 0) {
1324                        cursor = 0;
1325                } else if (cursor >= inputLineEntry.value.length) {
1326                        cursor = inputLineEntry.value.length;
1327                }
1328
1329                setCursorPos(cursor);
1330                oldpos = -1;
1331                return false;
1332        }
1333
1334
1335        function KeyUpHandler() {
1336        }
1337
1338
1339        function Coordinate(x, y) {
1340                this.x=x;
1341                this.y=y;
1342        }
1343
1344        function mouseGetCoordinates(evt) {
1345                var target = (evt.target) ? evt.target : evt.srcElement;
1346                var clickX = -1;
1347                var clickY = -1;
1348                if( target && target.nodeName!='HTML' && target.nodeName!='BODY' ) { // HTML(moz) and BODY(IE) means clicked outside of our code..
1349                        while (target && target.nodeName!='LI' && target.nodeName!='TEXTAREA' && target.nodeName!='DIV') {
1350                                if( target.parentElement ) {
1351                                        target=target.parentElement;
1352                                } else {
1353                                        // mozilla style
1354                                        target =  target.parentNode;
1355                                }
1356                        }
1357                        if( target ) {
1358                                // get click position
1359                                if (evt.pageX) {
1360                                        var offsetX=evt.pageX - ((target.offsetLeft) ? target.offsetLeft : target.left);
1361                                        var offsetY=evt.pageY - ((target.offsetTop) ? target.offsetTop : target.top);                           
1362                                } else if (evt.offsetX || evt.offsetY) {
1363                                        var offsetX = evt.offsetX;
1364                                        var offsetY = evt.offsetY;     
1365                                } else if (evt.clientX || evt.clientY) {
1366                                        var offsetX = evt.clientX - ((target.offsetLeft) ? target.offsetLeft : 0);
1367                                        var offsetY = evt.clientY - ((target.offsetTop) ? target.offsetTop : 0);
1368                                }
1369                                offsetX-=clickPosOffsetLeft;
1370                                var clickX=Math.round(offsetX/letterWidth);
1371       
1372                                // find a known container of the mouseclick
1373                                if (target.nodeName=='LI') {
1374                                        clickY=1;
1375                                        while (target=target.previousSibling) {
1376                                                clickY++;
1377                                        }
1378                                } else if (target.nodeName=='INPUT') {
1379                                } else if (target.nodeName=='TEXTAREA') {
1380                                } else if (target.nodeName=='DIV') {
1381                                } else {
1382                                        clickY=Math.round(offsetY/lineHeight)+1;
1383                                }
1384                        }
1385                }
1386                if (clickX>-1 && clickY>-1) {
1387                        return new Coordinate(clickX, clickY);         
1388                } else {
1389                        return false;
1390                }
1391        }
1392
1393
1394
1395        function mouseUpHandler(evt) {
1396       
1397                evt = (evt) ? evt : event;
1398                var coordinate=mouseGetCoordinates(evt);
1399                if (coordinate) {
1400                        checkDirty();
1401                        if (startcoordinate &&
1402                                        (!(startcoordinate.x==coordinate.x) ||
1403                                         !(startcoordinate.y==coordinate.y)) ) {
1404                                if (startcoordinate.y==coordinate.y) {
1405                                        // single line selection
1406                                        if (startcoordinate.x>coordinate.x) {
1407                                                var _temp=coordinate;
1408                                                coordinate=startcoordinate;
1409                                                startcoordinate=_temp;
1410                                        }
1411                                        currentLine=coordinate.y;
1412                                        redrawInputLine(true);
1413                                        setCursorPos(startcoordinate.x, coordinate.x, true);
1414                                        oldpos=-1;
1415                                        evt.cancelBubble=true;
1416                                        return false;
1417                                } else {
1418                                        // multi line selection
1419                                        if (startcoordinate.y>coordinate.y) {
1420                                                var _temp=coordinate;
1421                                                coordinate=startcoordinate;
1422                                                startcoordinate=_temp;
1423                                        }
1424                                       
1425                                }
1426                        } else {
1427                                // no selection
1428                                currentLine=coordinate.y;
1429                                redrawInputLine(true);
1430                                setCursorPos(coordinate.x, 0, true);
1431                                oldpos=-1;
1432                                evt.cancelBubble=true;
1433                                return false;
1434                        }
1435                }
1436
1437                if (isMoz && (evt.button == 1))
1438                {
1439                        checkPastedReturns = true;
1440                        setTimeout("fixmousepaste()",200);
1441                }
1442
1443               
1444        }
1445
1446        function mouseDownHandler(evt) {
1447                evt = (evt) ? evt : event;
1448                startcoordinate=mouseGetCoordinates(evt);
1449
1450                stopSelect();
1451                if ( inputHasLineEnd() )
1452                        redrawInputLine();
1453        }
1454
1455        function startSelect() {
1456                userSelecting=true;
1457                if (selectIni == -1) {
1458                        selectIni=getCursorPos();
1459                }
1460                if (selectLineIni == -1) {
1461                        selectLineIni=currentLine;
1462                }
1463        }
1464
1465        function stopSelect() {
1466                // Return the inputline to it's original size
1467                inputLine.style.height=lineHeight;
1468                inputLineEntry.style.height=lineHeight;
1469                currInputHeight = lineHeight;
1470                offsetLine=0;
1471                selectIni = -1;
1472                userSelecting=false;
1473                // get selected contents, put them in a buffer or something
1474        }
1475
1476        function updateLine(lineNo, lineContent) {
1477                lines.childNodes[lineNo-1].originalInnerText = lineContent;
1478                highlightUpdateLine(lineNo-1, lineContent, applyHighlightedLine);
1479                if (lineContent.length>longestLine) {
1480                        longestLine=lineContent.length;
1481                        if( (longestLine*letterWidth) > minInputWidth ) {
1482                                inputLine.style.width=longestLine*letterWidth+4;
1483                        }
1484                }
1485        }
1486
1487        function setLineContent(lineNo, lineContent) {
1488                if(lines.childNodes[lineNo-1]){
1489                        lines.childNodes[lineNo-1].innerHTML=lineContent;
1490                       
1491                        lines.childNodes[lineNo-1].originalInnerHTML=lineContent;
1492                }
1493        }
1494
1495        function insertLineAfter(lineNo, lineContent) {
1496                var oldCursor = getCursorPos();
1497                lines.childNodes[lineNo-1].insertAdjacentHTML("AfterEnd","<li>");
1498                highlightAppendLine(lineNo-1, lineContent, false); // do not display this yet
1499                currentLine=lineNo+1;
1500                updateLine(currentLine, lineContent);
1501                oldpos=-1;
1502                redrawInputLine(true);
1503                updateLineNumbers();
1504                lastLine++;
1505                if(saveUndo) {
1506                        undoBuffer.push({type: undo.LINE_AFTER, line: currentLine, text: lineContent, cursor: getCursorPos(), newCursor: oldCursor });
1507                }
1508        }
1509
1510        function deleteLine(lineNo) {
1511                if(saveUndo) {
1512                        var content = getLineContent(lineNo);
1513                        undoBuffer.push({type: undo.DELETE_LINE, line: lineNo, text: content, cursor: getCursorPos() , newCursor: content.length });
1514                }
1515                lines.childNodes[lineNo-1].removeNode(true);
1516                highlightDeleteLine(lineNo-1, applyHighlightedLine);
1517                updateLineNumbers();
1518                lastLine--;
1519        }
1520
1521        function deleteMultipleLines(lineIni,lineCount)
1522        {
1523                var i;
1524               
1525                for (i = lineIni; i <= lineCount; i++)
1526                {
1527                        if(saveUndo) {
1528                                var content = getLineContent(lineIni);
1529                                undoBuffer.push({type: undo.DELETE_LINE, line: lineIni, text: content, cursor: getCursorPos() , newCursor: content.length });
1530                        }
1531                        lines.childNodes[lineIni-1].removeNode(true);
1532                        highlightDeleteLine(lineIni-1, applyHighlightedLine);
1533                        lastLine--;
1534                }
1535                updateLineNumbers();
1536                if ( (currentLine-1)*lineHeight < window.pageYOffset )
1537                {
1538                window.scrollTo(0,(currentLine-1)*lineHeight); 
1539                }
1540        }
1541
1542        function deleteContents() {
1543                var len = lines.childNodes.length;
1544                for (var i=len-1; i>0; i--) {
1545                        lines.childNodes[i].removeNode(true);
1546                }
1547                setCursorPos(0);
1548                highlightReset();
1549                updateLineNumbers();
1550                lastLine=1;
1551                undoBuffer = [];
1552                redoBuffer = [];
1553        }
1554
1555
1556        function updateLineNumbers() {
1557                if (contentDiv.offsetHeight>winH) {
1558                        document.getElementById('linenumbers').style.height=contentDiv.offsetHeight;
1559                }
1560                alignLineNumbers(); //fix mozilla align
1561        }
1562
1563
1564        function checkDirty() {
1565                if (isDirty) {
1566                        var newContents = inputLineEntry.value;
1567                        var oldContents = getLineContent(currentLine);
1568
1569                       
1570                        if(newContents != oldContents) {
1571                                undoBuffer.push({ type: undo.CHANGE_TEXT, line: currentLine, text: oldContents, newText: newContents,
1572                                        cursor: startCursorPos, newCursor: getCursorPos() });
1573                                updateLine(currentLine, newContents);
1574                                isDirty=false;
1575                                startCursorPos = -1;
1576                                return true;
1577                        }
1578                } else {
1579                }
1580                return false;
1581        }
1582
1583        function getLineHead() {
1584                var _line = new String(getLineContent(currentLine));
1585                var _pos  = getCursorPos();
1586                if (_pos == 0) {
1587                        return '\t';
1588                } else {
1589                        return _line.substr(0, _pos);
1590                }
1591        }
1592
1593        function getLineTail() {
1594                var _line=new String(getLineContent(currentLine));
1595                var _pos=getCursorPos();
1596                return _line.substr(_pos);
1597        }
1598
1599        function breakCurrentLine() {
1600                checkDirty();
1601                var head=getLineHead();
1602                var tail=getLineTail();
1603                var re = /([\t ]+)/;
1604                var match = re.exec(head);
1605                var newCursor = 0;
1606       
1607                if( autoIndent && match ) {
1608                        tail = match[1] + tail;
1609                        newCursor = match[1].length;
1610                }
1611                insertLineAfter(currentLine, tail);
1612                updateLine(currentLine-1, head);
1613                setCursorPos(newCursor);
1614                inputLineEntry.focus();
1615        }
1616
1617        function glueCurrentLine(direction) {
1618                checkDirty();
1619                if (direction==-1) {
1620                        if (currentLine>1) {
1621                                var tail=getLineContent(currentLine);
1622                                var head=getLineContent(currentLine-1);
1623                                updateLine(currentLine-1, head+tail);
1624                                deleteLine(currentLine);
1625                                currentLine--;
1626                                redrawInputLine();
1627                                setCursorPos(head.length);
1628                        }                       
1629                } else {
1630                        if (currentLine<lastLine) {
1631                                var tail=getLineContent(currentLine+1);
1632                                var head=getLineContent(currentLine);
1633                                updateLine(currentLine, head+tail);
1634                                deleteLine(currentLine+1);
1635                                redrawInputLine();
1636                        }
1637                }
1638                updateLineNumbers();
1639        }
1640
1641        function jumpToLine(lineNo) {
1642                if(lineNo<=lastLine) {
1643                        currentLine=lineNo;
1644                        oldpos=-1;
1645                        redrawInputLine(true);
1646                        updateLineNumbers();
1647                } else {
1648                        oldpos=-1;
1649                        redrawInputLine(true);
1650                        updateLineNumbers();
1651                }
1652        }
1653
1654        function fixmousepaste()
1655        {
1656                fixPastedReturns(true);
1657                checkPastedReturns = false;
1658        }
1659
1660        function do_Copy()
1661        {
1662        }
1663
1664        function isNormalKey(charCode)
1665        {
1666                return ( ( parseInt( charCode ) >= 48 ) && ( parseInt( charCode ) <= 90 ) )  ||
1667                           ( ( parseInt( charCode ) >= 96 ) && ( parseInt( charCode ) <= 111 ) ) ||
1668                           ( parseInt( charCode ) == 32 ) ||
1669                           ( ( parseInt( charCode ) >= 186 ) && ( parseInt( charCode ) <= 222 ) );
1670        }
1671
1672        function inputHasLineEnd()
1673        {
1674                var re = /\n/;
1675                var match;
1676                var content;
1677               
1678                content = inputLineEntry.value;
1679                match   = re.exec(content);
1680                if( match ) {
1681                        return true;
1682                } else {
1683                        return false;
1684                }
1685        }
1686
1687        function alignLineNumbers()
1688        {
1689                if (isMoz) {
1690                        document.getElementById('lines').style.listStyleType='decimal-leading-zero';
1691                        document.getElementById('lines').style.listStyleType='decimal';
1692                }
1693        }
1694
1695        function fixLineGap() {
1696                /* synchronize line end with cursor position */
1697               
1698                var gap;
1699                var nlines;
1700                var old_cursor_pos = getCursorPos();
1701                var newEntry;
1702
1703                gap    = inputLineEntry.value;
1704                gap    = gap.substr(getCursorPos());
1705                nlines = gap.split('\n');
1706       
1707                currInputHeight = currInputHeight - lineHeight*(nlines.length-1);
1708                inputLine.style.height      = currInputHeight;
1709                inputLineEntry.style.height = currInputHeight;
1710               
1711                newEntry = inputLineEntry.value;
1712                for (i=0; i < nlines.length - 1; i++) {
1713                        if (isMoz) {
1714                                newEntry = newEntry.replace(/(.*)\n(.*[\n]?)$/,"$1"); //remove last line
1715                        } else {
1716                                newEntry = newEntry.replace(/(.*)\r\n(.*)$/,"$1"); //remove last line
1717                        }
1718                }
1719                inputLineEntry.value = newEntry;
1720                setCursorPos(selectIni,old_cursor_pos);
1721                offsetLine = newEntry.split('\n').length - 1;
1722        }
1723
1724        function do_BeginCode() {
1725                jumpToLine(1);
1726                inputLineEntry.focus();
1727        }
1728
1729        function do_EndCode() {
1730                jumpToLine(lines.childNodes.length);
1731                inputLineEntry.focus();
1732        }
1733
1734        function do_Indent() {
1735                var old_text = inputLineEntry.value;
1736                var old_pos;
1737               
1738                inputLineEntry.focus();
1739
1740                if (userSelecting) {
1741                        for (i = currentLine; i <= (currentLine+offsetLine); i++ ) {
1742                                old_text = getLineContent(i);
1743                                old_text = old_text.replace(/^/,"\t"); //add tabs
1744                                updateLine(i,old_text);
1745                        }
1746                        stopSelect();
1747                        if ( inputHasLineEnd() ) {
1748                                redrawInputLine();
1749                        }
1750                } else {
1751                        old_pos  = getCursorPos();
1752                        old_text = inputLineEntry.value;
1753                        old_text = old_text.replace(/^/,"\t"); //add tabs
1754                        inputLineEntry.value = old_text;
1755                        setCursorPos(old_pos+1);
1756                }
1757        }
1758               
1759        function do_Unindent() {
1760                var old_text = inputLineEntry.value;
1761                var old_pos;
1762               
1763                inputLineEntry.focus();
1764
1765                if (userSelecting) {
1766                        for (i = currentLine; i <= (currentLine+offsetLine); i++ ) {
1767                                old_text = getLineContent(i);
1768                                old_text = old_text.replace(/^\t/,""); //del tabs
1769                                updateLine(i,old_text);
1770                        }
1771                        stopSelect();
1772                        if ( inputHasLineEnd() ) {
1773                                redrawInputLine();
1774                        }
1775                } else {
1776                        old_pos  = getCursorPos();
1777                        old_text = inputLineEntry.value;
1778                        old_text = old_text.replace(/^\t/,""); //add tabs
1779                        inputLineEntry.value = old_text;
1780                        setCursorPos(old_pos-1);
1781                }
1782
1783        }
1784
1785        function do_Find(text) {
1786                               
1787                var idx;
1788               
1789                str_search = text;
1790               
1791                if( userSelecting ) {
1792                        stopSelect();
1793                        if ( inputHasLineEnd() )
1794                                redrawInputLine();
1795                }
1796
1797                str_search.toLowerCase();
1798                for (var i=currentLine; i<=lines.childNodes.length; i++) {
1799                        // need to remove trailing ' ', which IE puts there.
1800                        _temp = getLineContent(i);
1801                        _temp.toLowerCase();
1802                        idx = _temp.indexOf(str_search);
1803                        if (idx >= 0) {
1804                                jumpToLine(i);
1805                                inputLineEntry.focus();
1806                                setCursorPos(idx,idx+str_search.length);
1807                                break;
1808                        }
1809                }
1810               
1811        }
1812
1813        function do_FindNext(text) {
1814                var idx;
1815       
1816                str_search = text;
1817       
1818                if( userSelecting ) {
1819                        stopSelect();
1820                        if ( inputHasLineEnd() )
1821                                redrawInputLine();
1822                }
1823
1824                str_search = str_search.toLowerCase();
1825                for (var i=currentLine+1; i<=lines.childNodes.length; i++) {
1826                        // need to remove trailing ' ', which IE puts there.
1827                        _temp = getLineContent(i);
1828                        _temp = _temp.toLowerCase();
1829                        idx = _temp.indexOf(str_search);
1830                        if (idx >= 0) {
1831                                jumpToLine(i);
1832                                inputLineEntry.focus();
1833                                setCursorPos(idx,idx+str_search.length);
1834                                break;
1835                        }
1836                }
1837        }
1838
1839
1840        function do_Replace() {
1841                var idx;
1842                var inicio      = false;
1843                var ini_line    = currentLine;
1844                var str_search;
1845                var str_replace;
1846                var contents;
1847                var reg_exp;
1848       
1849                if ( str_search == null ) {
1850                        str_search = 'texto';
1851                }
1852       
1853                if( userSelecting ) {
1854                        stopSelect();
1855                        if ( inputHasLineEnd() )
1856                                redrawInputLine();
1857                }
1858
1859                if ( !( str_search  = prompt('Digite o texto a ser substituido:',str_search) ) ) return;
1860                if ( !( str_replace = prompt('Digite o novo texto:','') ) ) return;
1861
1862                reg_exp = new RegExp(str_search,'ig');
1863
1864                contents = getContents();
1865                setContents(contents.replace(reg_exp, str_replace));
1866        }
1867
1868
1869        function resizeHandler()
1870        {
1871                if (parseInt(navigator.appVersion) > 3)
1872                {
1873                        if (navigator.appName == "Netscape")
1874                        {
1875                                winW = window.innerWidth-42;
1876                                winH = window.innerHeight-2;
1877                                minInputWidth = winW-16;
1878                        }
1879                        else
1880                        if (navigator.appName.indexOf("Microsoft")!=-1)
1881                        {
1882                                winW = document.body.offsetWidth;
1883                                winH = document.body.offsetHeight;
1884                                minInputWidth      = winW-60;
1885                                // To handle clipboard paste
1886                        }
1887                }
1888
1889                document.getElementById('linenumbers').style.height = winH;
1890                updateLineNumbers();
1891
1892        }
Note: See TracBrowser for help on using the repository browser.