22 var CodeEditor = CodeEditor || {};
24 if (typeof DesktopContent ==
'undefined')
25 throw(
'ERROR: DesktopContent is undefined! Must include DesktopContent.js before CodeEditor.js');
28 CodeEditor.MENU_PRIMARY_COLOR =
"rgb(220, 187, 165)";
29 CodeEditor.MENU_SECONDARY_COLOR =
"rgb(130, 51, 51)";
42 function htmlOpen(tag,attObj,innerHTML,doCloseTag)
45 var attKeys = attObj?Object.keys(attObj):[];
46 str +=
"<" + tag +
" ";
47 for(var i=0;i<attKeys.length;++i)
48 str +=
" " + attKeys[i] +
"='" +
49 attObj[attKeys[i]] +
"' ";
51 if(innerHTML) str += innerHTML;
53 str +=
"</" + tag +
">";
59 function htmlClearDiv()
61 return "<div id='clearDiv'></div>";
70 if (1 || !Element.prototype.scrollIntoViewIfNeeded)
72 Element.prototype.scrollIntoViewIfNeeded =
function (centerIfNeeded)
74 centerIfNeeded = arguments.length === 0 ?
true : !!centerIfNeeded;
76 var parent = this.parentNode,
77 tdParent = parent.parentNode,
78 editorParent = parent.parentNode.parentNode.parentNode.parentNode.parentNode,
79 parentComputedStyle = window.getComputedStyle(parent, null),
80 parentBorderTopWidth = parseInt(parentComputedStyle.getPropertyValue(
'border-top-width')),
81 parentBorderLeftWidth = parseInt(parentComputedStyle.getPropertyValue(
'border-left-width')),
82 overTop = this.offsetTop - tdParent.offsetTop < editorParent.scrollTop,
83 overBottom = (
this.offsetTop - tdParent.offsetTop +
this.clientHeight - parentBorderTopWidth) > (editorParent.scrollTop + editorParent.clientHeight),
84 overLeft = this.offsetLeft - tdParent.offsetLeft < editorParent.scrollLeft,
85 overRight = (
this.offsetLeft + tdParent.offsetLeft +
this.clientWidth - parentBorderLeftWidth) > (editorParent.scrollLeft + editorParent.clientWidth),
86 alignWithTop = overTop && !overBottom;
88 if ((overTop || overBottom) && centerIfNeeded)
90 editorParent.scrollTop = this.offsetTop - tdParent.offsetTop - editorParent.clientHeight / 2 - parentBorderTopWidth + this.clientHeight / 2;
94 if ((overLeft || overRight) && centerIfNeeded)
96 editorParent.scrollLeft = this.offsetLeft + tdParent.offsetLeft - editorParent.clientWidth / 2 - parentBorderLeftWidth + this.clientWidth / 2;
100 if ((overTop || overBottom || overLeft || overRight) && !centerIfNeeded)
102 this.scrollIntoView(alignWithTop);
110 var windowTooltip =
"Welcome to the Code Editor user interface. " +
111 "Edit your code, save it, and compile!\n\n" +
112 "Hover your mouse over the icons and buttons to see what they do. " +
113 "If you hover your mouse over the filename additional icons will appear for changing the filename, downloading, uploading, undo, and redo. The buttons in the top corners are described below followed by hot-keys:\n\n" +
115 "<b>Open a file:</b>\n<INDENT>Use the folder icon in the top-left to navigate to a code file to edit.</INDENT>\n" +
116 "<b>Toggle view:</b>\n<INDENT>Use the split-pane icon in the top-right to toggle another code editor in the same window.</INDENT>\n" +
117 "<b>Save:</b>\n<INDENT>Use the save icon in the top-left to save your changes.</INDENT>\n" +
118 "<b>Compile:</b>\n<INDENT>Use the Incremmental Build or Clean Build icons in the top-right.</INDENT>\n" +
120 "<b>Global Hot Keys:</b>\n<INDENT>" +
122 "<table border=0 cellspacing=0 cellpadding=0 style='border: 1px solid grey;'>" +
123 "<tr style='background-color: rgb(106, 102, 119);'><td style='white-space: nowrap; padding:5px;'> " +
124 "Ctrl + B </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Incremental Build</td></tr>" +
125 "<tr><td style='white-space: nowrap; padding:5px;'> " +
126 "Ctrl + N </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Clean Build</td></tr>" +
127 "<tr style='background-color: rgb(106, 102, 119);'><td style='white-space: nowrap; padding:5px;'> " +
128 "Ctrl + 2 </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Toggle Split-View Mode (single, dual-vertical, dual-horizontal)</td></tr>" +
129 "</table></INDENT>\n" +
132 "<b>Editor Pane Hot Keys:</b>\n<INDENT>" +
134 "<table border=0 cellspacing=0 cellpadding=0 style='border: 1px solid grey;'>" +
136 "<tr style='background-color: rgb(106, 102, 119);'><td style='white-space: nowrap; padding:5px;'> " +
137 "Ctrl + S </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Save File</td></tr>" +
139 "<tr><td style='white-space: nowrap; padding:5px;'> " +
140 "Ctrl + D </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Toggle Directory Navigation</td></tr>" +
142 "<tr style='background-color: rgb(106, 102, 119);'><td style='white-space: nowrap; padding:5px;'> " +
143 "Ctrl + F </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Find & Replace</td></tr>" +
145 "<tr><td style='white-space: nowrap; padding:5px;'> " +
146 "Ctrl + U </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Undo Text Editing</td></tr>" +
148 "<tr style='background-color: rgb(106, 102, 119);'><td style='white-space: nowrap; padding:5px;'> " +
149 "Shift + Ctrl + U </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Redo Text Editing</td></tr>" +
151 "<tr><td style='white-space: nowrap; padding:5px;'> " +
152 "Ctrl + L or G </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Goto Line Number</td></tr>" +
154 "<tr style='background-color: rgb(106, 102, 119);'><td style='white-space: nowrap; padding:5px;'> " +
155 "Ctrl + 1 or ; </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Switch to Related File (associated .h or .cc)</td></tr>" +
157 "<tr><td style='white-space: nowrap; padding:5px;'> " +
158 "Ctrl + 0 or ' </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Reload Current File from Server</td></tr>" +
160 "</table></INDENT>\n" +
163 "<b>Selected-Text Hot Keys:</b>\n<INDENT>" +
165 "<table border=0 cellspacing=0 cellpadding=0 style='border: 1px solid grey;'>" +
166 "<tr style='background-color: rgb(106, 102, 119);'><td style='white-space: nowrap; padding:5px;'> TAB</td><td style='padding:5px'> ==> </td><td style='padding:5px'> Add leading TAB character to all highlighted lines.</td></tr>" +
167 "<tr><td style='white-space: nowrap; padding:5px;'> Shift + TAB </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Remove leading TAB character from all highlighted lines.</td></tr>" +
168 "<tr style='background-color: rgb(106, 102, 119);'><td style='white-space: nowrap; padding:5px;'> Ctrl + T or Y </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Add TAB character at starting cursor position of all highlighted line (i.e. Block Tab effect).</td></tr>" +
169 "<tr><td style='white-space: nowrap; padding:5px;'> Shift + Ctrl + T or Y</td><td style='padding:5px'> ==> </td><td style='padding:5px'> Remove TAB character from starting cursor position of all highlighted line (i.e. reverse Block Tab effect).</td></tr>" +
170 "<tr style='background-color: rgb(106, 102, 119);'><td style='white-space: nowrap; padding:5px;'> Ctrl + / </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Add leading comment character(s) to all highlighted lines.</td></tr>" +
171 "<tr><td style='white-space: nowrap; padding:5px;'> Shift + Ctrl + / </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Remove leading comment character(s) to all highlighted lines.</td></tr>" +
172 "<tr style='background-color: rgb(106, 102, 119);'><td style='white-space: nowrap; padding:5px;'> Ctrl + I </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Auto-indent all highlighted lines.</td></tr>" +
173 "</table></INDENT>\n" +
174 "If you are an admin and want to set Code Editor in viewer mode for other users i,e. 'Code Viewer,' go to 'Desktop Icon Table' in Configure to set the parameter 'readOnlyMode.'" +
178 var windowViewModeTooltip =
"Welcome to the Code Viewer user interface. " +
179 "You will only be able to view codes without modifying. Your text inputs won't be saved. " +
180 "Contact your administrator if you think you should have modification access."+
182 "<b>Open a file:</b>\n<INDENT>Use the folder icon in the top-left to navigate to a code file to edit.</INDENT>\n" +
183 "<b>Toggle view:</b>\n<INDENT>Use the split-pane icon in the top-right to toggle another code editor in the same window.</INDENT>\n" +
185 "<b>Viewer Hot Keys:</b>\n<INDENT>" +
187 "<table border=0 cellspacing=0 cellpadding=0 style='border: 1px solid grey;'>" +
189 "<tr style='background-color: rgb(106, 102, 119);'><td style='white-space: nowrap; padding:5px;'> " +
190 "Ctrl + 2 </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Toggle Split-View Mode (single, dual-vertical, dual-horizontal)</td></tr>" +
192 "<tr><td style='white-space: nowrap; padding:5px;'> " +
193 "Ctrl + L or G </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Goto Line Number</td></tr>" +
195 "<tr style='background-color: rgb(106, 102, 119);'><td style='white-space: nowrap; padding:5px;'> " +
196 "Ctrl + F </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Find</td></tr>" +
197 "</table></INDENT>\n" +
201 appMode =
"Code Editor";
203 CodeEditor.showTooltip =
function(alwaysShow)
205 DesktopContent.tooltip(
206 (alwaysShow?
"ALWAYS" : appMode), windowTooltip);
208 DesktopContent.setWindowTooltip(windowTooltip);
218 CodeEditor.create =
function(standAlone) {
222 console.log(
"standAlone",standAlone);
223 var _STAND_ALONE = standAlone;
287 var _WINDOW_MIN_SZ = 525;
289 var _ALLOWED_FILE_EXTENSIONS = [];
291 var _needEventListeners =
true;
294 var _navMode = [0,0];
295 var _filePath = [
"",
""];
296 var _fileExtension = [
"",
""];
297 var _fileLastSave = [0,0];
298 var _fileWasModified = [
false,
false];
299 var _numberOfLines = [0,0];
301 var _eel = [undefined,undefined];
303 var _updateTimerHandle = 0;
304 var _updateHandlerTargetPane = [
false,
false];
305 var _commandKeyDown =
false;
306 var _lastPageUpDownLine = -1;
307 var _startPageUpDownLine = -1;
308 var _startPageUpDownNodeIndex = -1;
309 var _startPageUpDownPos = -1;
311 var _fileNameMouseMoveTimerHandle = 0;
312 var _fileNameEditing = [
false,
false];
313 var _fileUploadString;
315 var _activePaneIsPrimary = 1;
317 var _undoStackLatestIndex = [-1,-1];
318 var _undoStack_MAX_SIZE = 10;
319 var _undoStack = [[],[]];
321 var _fileHistoryStack = {};
323 var _findAndReplaceCursorInContent = [undefined,undefined];
325 var _fileStringHoverEl = 0;
326 var _fileStringHoverTimeout = 0;
328 var _UPDATE_DECOR_TIMEOUT = 2000;
332 var _READ_ONLY =
false;
333 var _requestPreamble =
"";
338 CodeEditor.editor =
this;
339 Debug.log(
"CodeEditor.editor constructed");
343 this.findAndReplaceFind = [
"",
""];
344 this.findAndReplaceReplace = [
"",
""];
345 this.findAndReplaceScope = [0,0];
346 this.findAndReplaceDirection = [0,0];
347 this.findAndReplaceCaseSensitive = [0,0];
348 this.findAndReplaceWholeWord = [1,1];
349 this.findAndReplaceLastButton = [-1,-1];
353 Debug.log(
"CodeEditor.editor initialized");
360 Debug.log(
"Code Editor init ");
363 var parameterStartFile = [
369 DesktopContent.getParameter(0,
"startFilePrimary"),
370 DesktopContent.getParameter(0,
"startFileSecondary")
372 var parameterGotoLine = [
373 DesktopContent.getParameter(0,
"gotoLinePrimary"),
374 DesktopContent.getParameter(0,
"gotoLineSecondary")
376 var parameterOpenDirectory = [
377 DesktopContent.getParameter(0,
"openDirectoryPrimary"),
378 DesktopContent.getParameter(0,
"openDirectorySecondary")
380 if(parameterOpenDirectory[0] === undefined)
381 parameterOpenDirectory[0] =
"/";
382 if(parameterOpenDirectory[1] === undefined)
383 parameterOpenDirectory[1] =
"/";
385 var parameterViewMode = DesktopContent.getParameter(0,
"startViewMode");
386 if(parameterViewMode !== undefined)
388 _viewMode = parameterViewMode|0;
392 var readOnlyMode = DesktopContent.getParameter(0,
"readOnlyMode");
393 if (readOnlyMode !== undefined)
395 Debug.log(
"Launching readonly mode to true!");
400 console.log(
"parameterStartFile",parameterStartFile);
401 console.log(
"parameterGotoLine",parameterGotoLine);
402 console.log(
"parameterViewMode",parameterViewMode);
403 console.log(
"parameterOpenDirectory", parameterOpenDirectory);
404 console.log(
"_READ_ONLY", _READ_ONLY);
406 if(_READ_ONLY ==
true)
408 _requestPreamble =
"readOnly";
409 appMode =
"Code Viewer";
410 windowTooltip = windowViewModeTooltip;
417 CodeEditor.showTooltip(_STAND_ALONE);
424 if(_needEventListeners)
426 window.addEventListener(
"resize",redrawWindow);
427 _needEventListeners =
false;
439 Debug.log(
"CodeEditor stand alone setup...");
440 CodeEditor.editor.toggleDirectoryNav(
true ,
false );
443 CodeEditor.editor.upload(
true );
450 DesktopContent.XMLHttpRequest(
"Request?RequestType=" + _requestPreamble +
452 "&option=getAllowedExtensions"
454 function(req, reqParam, errStr)
456 console.log(
"getAllowedExtensions",req,errStr);
458 if(!_READ_ONLY && !req)
460 if(DesktopContent._sequence)
461 Debug.log(
"Assuming invalid permissions (remember the wiz mode sequence access code must be at least 8 characters to allow write access)!\n\nReverting to read-only mode.", Debug.WARN_PRIORITY);
463 Debug.log(
"Assuming invalid permissions (remember only named users can have write access, not the anonymous admin user)!\n\nReverting to read-only mode.", Debug.WARN_PRIORITY);
469 if(errStr && errStr !=
"")
470 Debug.log(errStr,Debug.HIGH_PRIORITY);
474 Debug.log(
"Does the Code Editor Supervisor exist? You must connect the web editor to a valid Code Editor Supervisor application (please check your Configuration Tree and then restart ots).",Debug.HIGH_PRIORITY);
479 if(!errStr || errStr ==
"")
480 errStr = DesktopContent.getXMLValue(req,
"Error");
482 if(errStr && errStr !=
"")
484 Debug.log(errStr,Debug.HIGH_PRIORITY);
485 Debug.log(
"Does the Code Editor Supervisor exist? You must connect the web editor to a valid Code Editor Supervisor application (please check your Configuration Tree and then restart ots).",Debug.HIGH_PRIORITY);
490 _ALLOWED_FILE_EXTENSIONS = DesktopContent.getXMLValue(req,
"AllowedExtensions");
491 console.log(
"_ALLOWED_FILE_EXTENSIONS",_ALLOWED_FILE_EXTENSIONS);
492 _ALLOWED_FILE_EXTENSIONS = _ALLOWED_FILE_EXTENSIONS.split(
',');
493 console.log(
"_ALLOWED_FILE_EXTENSIONS",_ALLOWED_FILE_EXTENSIONS);
495 DesktopContent.XMLHttpRequest(
"Request?RequestType=" + _requestPreamble +
497 "&option=getDirectoryContent" +
507 CodeEditor.editor.handleDirectoryContent(1 , req);
508 CodeEditor.editor.handleDirectoryContent(0 , req);
512 if(parameterStartFile[0] && parameterStartFile[0] !=
"")
513 fileSplit = parameterStartFile[0].split(
'.');
517 if(fileSplit.length == 2)
518 CodeEditor.editor.openFile(
523 parameterGotoLine[0 ] );
526 CodeEditor.editor.openDirectory(
528 parameterOpenDirectory[0] ,
536 if(parameterStartFile[1] && parameterStartFile[1] !=
"")
537 fileSplit = parameterStartFile[1].split(
'.');
539 if(fileSplit.length == 2)
540 CodeEditor.editor.openFile(
545 parameterGotoLine[1 ] );
549 CodeEditor.editor.openDirectory(
551 parameterOpenDirectory[1] ,
558 _activePaneIsPrimary = 1;
574 function createElements()
576 Debug.log(
"createElements");
588 var cel,el,al,sl,str;
590 cel = document.getElementById(
"content");
593 cel = document.createElement(
"div");
594 cel.setAttribute(
"id",
"content");
605 for(forPrimary=1;forPrimary >= 0;--forPrimary)
607 el = document.createElement(
"div");
608 el.setAttribute(
"class",
"editorPane");
609 el.setAttribute(
"id",
"editorPane" + forPrimary);
612 str += createTextEditor(forPrimary);
613 str += createDirectoryNav(forPrimary);
614 str += localCreatePaneControls(forPrimary);
621 function localCreatePaneControls(forPrimary)
629 str += htmlOpen(
"div",
631 "class":
"controlsPane",
635 str += htmlOpen(
"div",
637 "id":
"directoryNavToggle",
638 "class":
"controlsButton",
639 "style":
"float:left;" +
642 "onclick":
"CodeEditor.editor.toggleDirectoryNav(" + forPrimary +
");",
643 "title":
"Open a file... (Ctrl + D)",
646 str += htmlOpen(
"div",
648 "id":
"directoryNavToggleTop",
651 str += htmlOpen(
"div",
653 "id":
"directoryNavToggleBottom",
660 str += htmlOpen(
"div",
663 "class":
"controlsButton",
664 "style":
"float:left;" +
665 ((_STAND_ALONE || _READ_ONLY)?
667 "onclick":
"CodeEditor.editor.saveFile(" + forPrimary +
");",
668 "title":
"Click to Save the File (Ctrl + S)\nUndo changes (Ctrl + U)\nRedo changes (Shift + Ctrl + U)",
671 str += htmlOpen(
"div",
676 str += htmlOpen(
"div",
678 "id":
"saveFileMainTop",
681 str += htmlOpen(
"div",
683 "id":
"saveFileMainBottom",
697 el = document.createElement(
"div");
698 el.setAttribute(
"class",
"controlsPane");
706 str += htmlOpen(
"div",
710 "class":
"controlsButton",
711 "style":
"float:right",
712 "onclick":
"CodeEditor.editor.toggleView();",
713 "title":
"Toggle Verical/Horizontal Split-view (Ctrl + W)",
718 str += htmlOpen(
"div",
720 "id":
"viewToggleRight",
723 str += htmlOpen(
"div",
725 "id":
"viewToggleLeftTop",
728 str += htmlOpen(
"div",
730 "id":
"viewToggleLeftBottom",
738 str += htmlOpen(
"div",
740 "id":
"incrementalBuild",
741 "class":
"controlsButton",
742 "style":
"float:right;" +
743 ((_STAND_ALONE || _READ_ONLY)?
745 "onclick":
"CodeEditor.editor.build(0 /*cleanBuild*/);",
746 "title":
"Incremental Build... (Ctrl + B)",
750 str += htmlOpen(
"div",
752 "style":
"margin:11px 0 0 13px;",
758 str += htmlOpen(
"div",
761 "class":
"controlsButton",
762 "style":
"float:right;" +
763 ((_STAND_ALONE || _READ_ONLY)?
765 "onclick":
"CodeEditor.editor.build(1 /*cleanBuild*/);",
766 "title":
"Clean Build... (Ctrl + N)",
770 str += htmlOpen(
"div",
772 "style":
"margin:10px 0 0 13px;",
785 document.body.appendChild(cel);
786 _eel = [document.getElementById(
"editableBox" + 0),
787 document.getElementById(
"editableBox" + 1)];
795 _eel[i].addEventListener(
"input",
800 var forPrimary = this.
id[this.
id.length-1]|0;
801 forPrimary = forPrimary?1:0;
803 Debug.log(
"input forPrimary=" + forPrimary);
805 _fileWasModified[forPrimary] =
true;
806 CodeEditor.editor.updateLastSave(forPrimary);
808 CodeEditor.editor.startUpdateHandling(forPrimary);
812 _eel[i].addEventListener(
"keydown",
815 if(e.keyCode == 91 || e.keyCode == 93 ||
817 _commandKeyDown =
true;
819 var forPrimary =
this.id[
this.id.length-1]|0;
820 forPrimary = forPrimary?1:0;
823 CodeEditor.editor.keyDownHandler(e,forPrimary);
827 _eel[i].addEventListener(
"keyup",
830 if(e.keyCode == 91 || e.keyCode == 93 ||
832 _commandKeyDown =
false;
835 _eel[i].addEventListener(
"click",
841 Debug.log(
"Special mouse click handling");
851 _eel[i].addEventListener(
"dblclick",
855 var forPrimary = this.
id[this.
id.length-1]|0;
856 forPrimary = forPrimary?1:0;
858 Debug.log(
"dblclick handler for editor" + forPrimary);
861 CodeEditor.editor.doubleClickHandler(forPrimary);
864 _eel[i].addEventListener(
"contextmenu",
870 Debug.log(
"Special context menu handling");
879 _eel[i].addEventListener(
"mousedown",
884 Debug.log(
"Special mouse down handling");
891 CodeEditor.editor.stopUpdateHandling(e);
893 var forPrimary = this.
id[this.
id.length-1]|0;
894 forPrimary = forPrimary?1:0;
896 Debug.log(
"mousedown handler for editor" + forPrimary +
" " + e.which);
899 if(_activePaneIsPrimary != forPrimary)
900 CodeEditor.editor.updateDualView(!forPrimary);
902 _activePaneIsPrimary = forPrimary;
907 _eel[i].addEventListener(
"mouseup",
910 var forPrimary = this.
id[this.
id.length-1]|0;
911 forPrimary = forPrimary?1:0;
913 Debug.log(
"mouseup handler for editor" + forPrimary);
917 Debug.log(
"Special mouse up handling");
924 CodeEditor.editor.startUpdateHandling(forPrimary);
928 _eel[i].addEventListener(
'paste',
931 Debug.log(
"paste handler() for editor" + forPrimary);
932 var paste = (e.clipboardData || window.clipboardData).getData(
'text');
934 var selection = window.getSelection();
935 if (!selection.rangeCount)
return false;
936 selection.deleteFromDocument();
937 selection.getRangeAt(0).insertNode(document.createTextNode(paste));
943 box = document.getElementById(
"editorPane" + i);
944 box.addEventListener(
"click",
947 var forPrimary = this.
id[this.
id.length-1]|0;
948 forPrimary = forPrimary?1:0;
950 Debug.log(
"click handler for pane" + forPrimary);
954 if(_activePaneIsPrimary != forPrimary)
955 CodeEditor.editor.updateDualView(!forPrimary);
957 _activePaneIsPrimary = forPrimary;
960 CodeEditor.editor.showFindAndReplaceSelection(forPrimary);
963 var el = document.getElementById(
"textEditorBody" + forPrimary);
964 var scrollLeft = el.scrollLeft;
965 var scrollTop = el.scrollTop;
967 _eel[forPrimary].focus();
969 el.scrollLeft = scrollLeft;
970 el.scrollTop = scrollTop;
979 box.addEventListener(
"keydown",
982 if(e.keyCode == 91 || e.keyCode == 93 ||
984 _commandKeyDown =
true;
986 var forPrimary = _activePaneIsPrimary;
987 Debug.log(
"keydown handler for body" + forPrimary);
988 CodeEditor.editor.keyDownHandler(e,forPrimary,
true );
991 box.addEventListener(
"keyup",
994 if(e.keyCode == 91 || e.keyCode == 93 ||
996 _commandKeyDown =
false;
998 box.addEventListener(
"mouseover",
1002 if(_fileStringHoverEl.parentNode)
1004 Debug.log(
"body removing string hover");
1005 window.clearTimeout(_fileStringHoverTimeout);
1006 _fileStringHoverTimeout = window.setTimeout(
1009 Debug.log(
"body removed string hover");
1012 _fileStringHoverEl.parentNode.removeChild(_fileStringHoverEl);
1025 function createTextEditor(forPrimary)
1027 forPrimary = forPrimary?1:0;
1029 Debug.log(
"createTextEditor forPrimary=" + forPrimary);
1033 str += htmlOpen(
"div",
1035 "class":
"textEditor",
1036 "id":
"textEditor" + forPrimary,
1037 "style":
"overflow:hidden;",
1046 str += htmlOpen(
"div",
1048 "class":
"textEditorHeader",
1049 "id":
"textEditorHeader" + forPrimary,
1053 str += htmlOpen(
"div",
1055 "class":
"textEditorBody",
1056 "id":
"textEditorBody" + forPrimary,
1059 str +=
"<table class='editableBoxTable' style='margin-bottom:200px'>" +
1060 "<tr><td valign='top'>";
1061 str += htmlOpen(
"div",
1063 "class":
"editableBoxLeftMargin",
1064 "id":
"editableBoxLeftMargin" + forPrimary,
1065 },
"0\n1\n2" ,
true );
1066 str +=
"</td><td valign='top'>";
1067 str += htmlOpen(
"div",
1069 "class":
"editableBox",
1070 "id":
"editableBox" + forPrimary,
1071 "contenteditable":
"true",
1072 "autocomplete":
"off",
1073 "autocorrect":
"off",
1074 "autocapitalize":
"off",
1075 "spellcheck":
"false",
1077 str +=
"</td></tr></table>";
1088 function createDirectoryNav(forPrimary)
1090 forPrimary = forPrimary?1:0;
1092 Debug.log(
"createDirectoryNav forPrimary=" + forPrimary);
1096 str += htmlOpen(
"div",
1098 "class":
"directoryNav",
1099 "id":
"directoryNav" + forPrimary,
1100 },
"Directory" , 1 );
1109 function redrawWindow()
1114 var w = window.innerWidth | 0;
1115 var h = window.innerHeight | 0;
1117 if(w < _WINDOW_MIN_SZ)
1119 if(h < _WINDOW_MIN_SZ)
1122 Debug.log(
"redrawWindow to " + w +
" - " + h);
1124 var eps = document.getElementsByClassName(
"editorPane");
1125 var epHdrs = document.getElementsByClassName(
"textEditorHeader");
1126 var epBdys = document.getElementsByClassName(
"textEditorBody");
1127 var dns = document.getElementsByClassName(
"directoryNav");
1131 eps[0].style.position =
"absolute";
1132 eps[1].style.position =
"absolute";
1134 var DIR_NAV_MARGIN = 50;
1135 var EDITOR_MARGIN = 20;
1136 var EDITOR_HDR_H = 56;
1141 rect = [{
"left":0,
"top":0,
"w":w,
"h":h},
1146 rect = [{
"left":0,
"top":0,
"w":((w/2)|0),
"h":h},
1147 {
"left":((w/2)|0),
"top":0,
"w":(w-((w/2)|0)),
"h":h}];
1152 rect = [{
"left":0,
"top":0,
"h":((h/2)|0),
"w":w},
1153 {
"top":((h/2)|0),
"left":0,
"h":(h-((h/2)|0)),
"w":w}];
1157 Debug.log(
"Invalid view mode encountered: " + _viewMode);
1161 for(var i=0;i<2;++i)
1165 eps[i].style.display =
"none";
1169 dns[i].style.left = (DIR_NAV_MARGIN) +
"px";
1170 dns[i].style.top = (DIR_NAV_MARGIN) +
"px";
1171 dns[i].style.width = (rect[i].w - 2*DIR_NAV_MARGIN) +
"px";
1172 dns[i].style.height = (rect[i].h - 2*DIR_NAV_MARGIN) +
"px";
1174 eps[i].style.left = rect[i].left +
"px";
1175 eps[i].style.top = rect[i].top +
"px";
1176 eps[i].style.height = rect[i].h +
"px";
1177 eps[i].style.width = rect[i].w +
"px";
1179 epHdrs[i].style.left = EDITOR_MARGIN +
"px";
1180 epHdrs[i].style.top = (DIR_NAV_MARGIN - 2*EDITOR_MARGIN) +
"px";
1181 epHdrs[i].style.height = (EDITOR_HDR_H + 2*EDITOR_MARGIN) +
"px";
1182 epHdrs[i].style.width = (rect[i].w - 2*EDITOR_MARGIN) +
"px";
1185 epBdys[i].style.left = 0 +
"px";
1186 epBdys[i].style.top = (DIR_NAV_MARGIN + EDITOR_HDR_H) +
"px";
1187 epBdys[i].style.height = (rect[i].h - DIR_NAV_MARGIN - EDITOR_HDR_H) +
"px";
1188 epBdys[i].style.width = (rect[i].w - 0) +
"px";
1190 eps[i].style.display =
"block";
1199 this.toggleView =
function(v)
1204 _viewMode = (_viewMode+1)%3;
1205 Debug.log(
"toggleView _viewMode=" + _viewMode);
1212 this.toggleDirectoryNav =
function(forPrimary, v)
1214 forPrimary = forPrimary?1:0;
1215 _activePaneIsPrimary = forPrimary;
1217 Debug.log(
"toggleDirectoryNav forPrimary=" + forPrimary);
1220 _navMode[forPrimary] = v?1:0;
1222 _navMode[forPrimary] = _navMode[forPrimary]?0:1;
1223 Debug.log(
"toggleDirectoryNav _navMode=" + _navMode[forPrimary]);
1225 var el = document.getElementById(
"directoryNav" + forPrimary);
1226 var wasHidden = el.style.display ==
"none";
1228 _navMode[forPrimary]?
"block":
"none";
1230 if(_navMode[forPrimary] && wasHidden)
1232 var paths = document.getElementById(
"directoryNav" +
1233 forPrimary).getElementsByClassName(
"dirNavPath");
1234 var buildPath =
"/";
1235 for(var i=1;i<paths.length;++i)
1236 buildPath += (i>1?
"/":
"") + paths[i].textContent;
1237 Debug.log(
"refresh " + buildPath);
1239 CodeEditor.editor.openDirectory(forPrimary,buildPath);
1246 this.saveFile =
function(forPrimary, quiet)
1248 forPrimary = forPrimary?1:0;
1250 Debug.log(
"saveFile forPrimary=" + forPrimary);
1252 Debug.log(
"saveFile _filePath=" + _filePath[forPrimary]);
1253 Debug.log(
"saveFile _fileExtension=" + _fileExtension[forPrimary]);
1255 if(_filePath[forPrimary] ==
"")
1257 Debug.log(
"Error, can not save to empty file name!",
1258 Debug.HIGH_PRIORITY);
1264 DesktopContent.popUpVerification(
1265 "Are you sure you want to save...<br>" +
1266 _filePath[forPrimary] +
"." + _fileExtension[forPrimary] +
"?",
1268 undefined,undefined,undefined,
1269 undefined,undefined,
1277 function localDoIt()
1281 var textObj = {
"text":
1282 _eel[forPrimary].innerText,
1289 textObj.text = textObj.text.replace(/%20%20/g,
"%20%20").replace(/%20/g,
1290 "%20").replace(/%20/g,
"%20").replace(/%20/g,
"%20");
1294 DesktopContent.XMLHttpRequest(
"Request?RequestType=codeEditor" +
1295 "&option=saveFileContent" +
1296 "&path=" + _filePath[forPrimary] +
1297 "&ext=" + _fileExtension[forPrimary]
1298 ,
"content=" + encodeURIComponent(textObj.text) ,
1301 Debug.log(
"Successfully saved " +
1302 _filePath[forPrimary] +
"." +
1303 _fileExtension[forPrimary],quiet?Debug.LOW_PRIORITY:Debug.INFO_PRIORITY);
1305 _fileWasModified[forPrimary] =
false;
1306 textObj.time = Date.now();
1307 _fileLastSave[forPrimary] = textObj.time;
1310 CodeEditor.editor.updateLastSave(forPrimary);
1312 if(_filePath[0] == _filePath[1] &&
1313 _fileExtension[0] == _fileExtension[1])
1315 CodeEditor.editor.updateDualView(forPrimary);
1317 CodeEditor.editor.updateFileSnapshot(!forPrimary,
1323 CodeEditor.editor.updateFileSnapshot(forPrimary,
1335 this.build =
function(cleanBuild)
1337 cleanBuild = cleanBuild?1:0;
1339 Debug.log(
"build cleanBuild=" + cleanBuild);
1343 DesktopContent.popUpVerification(
1344 "Are you sure you want to do a clean build?!",
1352 function localDoIt()
1354 DesktopContent.XMLHttpRequest(
"Request?RequestType=codeEditor" +
1356 "&clean=" + (cleanBuild?1:0)
1360 Debug.log(
"Build was launched! Check " +
1361 "<a onclick='DesktopContent.openNewBrowserTab(" +
1363 "title='Click to open the Console web app in a new browser tab.'>" +
1364 "console</a> for result!", Debug.INFO_PRIORITY);
1374 this.undo =
function(forPrimary,redo)
1376 DesktopContent.showLoading(localDoIt);
1379 function localDoIt()
1381 forPrimary = forPrimary?1:0;
1383 Debug.log(
"undo() forPrimary=" + forPrimary +
" redo=" + redo);
1384 console.log(
"undo stack index",_undoStackLatestIndex[forPrimary]);
1385 console.log(
"undo stack length",_undoStack[forPrimary].length);
1387 console.log(
"undo stack",_undoStack[forPrimary]);
1389 var el = _eel[forPrimary];
1392 CodeEditor.editor.updateFileSnapshot(forPrimary,
1393 {
"text":el.textContent,
1397 var newIndex = _undoStackLatestIndex[forPrimary];
1398 newIndex += redo?1:-1;
1399 if(newIndex >= _undoStack_MAX_SIZE)
1401 else if(newIndex < 0)
1402 newIndex = _undoStack[forPrimary].length-1;
1404 console.log(
"new stack index",newIndex);
1408 _undoStack[forPrimary][newIndex][1] >=
1409 _undoStack[forPrimary][_undoStackLatestIndex[forPrimary]][1])
1411 Debug.log(
"Reached end of undo history...",Debug.WARN_PRIORITY);
1415 (newIndex >= _undoStack[forPrimary].length ||
1416 _undoStack[forPrimary][newIndex][1] <=
1417 _undoStack[forPrimary][_undoStackLatestIndex[forPrimary]][1]))
1419 Debug.log(
"Reached end of redo history...",Debug.WARN_PRIORITY);
1424 _undoStackLatestIndex[forPrimary] = newIndex;
1425 console.log(
"result stack index",newIndex);
1427 var cursor = CodeEditor.editor.getCursor(el);
1430 _undoStack[forPrimary][_undoStackLatestIndex[forPrimary]][0];
1431 _fileWasModified[forPrimary] =
true;
1433 CodeEditor.editor.updateDecorations(forPrimary,
1437 CodeEditor.editor.setCursor(el,cursor,
true );
1444 this.handleDirectoryContent =
function(forPrimary,req)
1446 forPrimary = forPrimary?1:0;
1448 Debug.log(
"handleDirectoryContent forPrimary=" + forPrimary);
1451 var path = DesktopContent.getXMLValue(req,
"path");
1452 if(path ==
"/") path =
"";
1454 var specials = req.responseXML.getElementsByTagName(
"special");
1455 var dirs = req.responseXML.getElementsByTagName(
"directory");
1456 var files = req.responseXML.getElementsByTagName(
"file");
1457 var specialFiles = req.responseXML.getElementsByTagName(
"specialFile");
1459 Debug.log(
"handleDirectoryContent path=" + path);
1460 console.log(dirs);console.log(files);
1465 str += htmlOpen(
"div",
1467 "style":
"margin:20px;" +
1468 "white-space: nowrap;",
1474 var pathSplit = path.split(
'/');
1478 str +=
"Path: <a class='dirNavPath' onclick='CodeEditor.editor.openDirectory(" +
1479 forPrimary +
",\"" +
1485 for(i=0;i<pathSplit.length;++i)
1487 pathSplitName = pathSplit[i].trim();
1488 if(pathSplitName ==
"")
continue;
1489 Debug.log(
"pathSplitName " + pathSplitName);
1490 name = pathSplitName;
1492 buildPath +=
"/" + pathSplitName;
1495 str +=
"<a class='dirNavPath' onclick='CodeEditor.editor.openDirectory(" +
1496 forPrimary +
",\"" +
1498 ")' title='Open folder: \nsrcs" + buildPath +
1500 pathSplitName +
"</a>";
1506 str += htmlOpen(
"a",
1508 "title":
"Open folder in the other editor pane of the split-view: \n" +
1510 "onclick":
"CodeEditor.editor.openDirectory(" +
1511 (!forPrimary) +
",\"" +
1514 "<img class='dirNavFileNewWindowImgNewPane' " +
1515 "src='/WebPath/images/windowContentImages/CodeEditor-openInOtherPane.png'>"
1519 str += htmlOpen(
"a",
1521 "title":
"Open folder in a new browser tab: \n" +
1523 "onclick":
"DesktopContent.openNewBrowserTab(" +
1524 "\"" + name +
"\",\"\"," +
1525 "\"/WebPath/html/CodeEditor.html?urn=" +
1526 DesktopContent._localUrnLid +
"&" +
1527 "openDirectoryPrimary=" +
1528 buildPath +
"\",0 /*unique*/);' ",
1530 "<img class='dirNavFileNewWindowImgNewWindow' " +
1531 "src='/WebPath/images/windowContentImages/CodeEditor-openInNewWindow.png'>"
1540 for(i=0;i<specials.length;++i)
1542 name = specials[i].getAttribute(
'value');
1545 str += htmlOpen(
"a",
1547 "title":
"Open folder in a new browser tab: \n" +
1548 "srcs" + path +
"/" + name,
1549 "onclick":
"DesktopContent.openNewBrowserTab(" +
1550 "\"" + name +
"\",\"\"," +
1551 "\"/WebPath/html/CodeEditor.html?urn=" +
1552 DesktopContent._localUrnLid +
"&" +
1553 "openDirectoryPrimary=" +
1554 path +
"/" + name +
"\",0 /*unique*/);' ",
1556 "<img class='dirNavFileNewWindowImgNewWindow' " +
1557 "src='/WebPath/images/windowContentImages/CodeEditor-openInNewWindow.png'>"
1561 str += htmlOpen(
"a",
1563 "title":
"Open folder in the other editor pane of the split-view: \n" +
1564 "srcs" + path +
"/" + name,
1565 "onclick":
"CodeEditor.editor.openDirectory(" +
1566 (!forPrimary) +
",\"" +
1567 path +
"/" + name +
"\");",
1569 "<img class='dirNavFileNewWindowImgNewPane' " +
1570 "src='/WebPath/images/windowContentImages/CodeEditor-openInOtherPane.png'>"
1574 str +=
"<a class='dirNavSpecial' onclick='CodeEditor.editor.openDirectory(" +
1575 forPrimary +
",\"" +
1576 path +
"/" + name +
"\"" +
1577 ")' title='Open folder: \nsrcs" + path +
"/" + name +
"' >" +
1587 if(specialFiles.length)
1590 str +=
"<tr><th>" + path.substr(1,path.length-2) +
" Files</th><th style='padding-left:20px'>Repository</th></tr>";
1592 for(i=0;i<specialFiles.length;++i)
1594 name = specialFiles[i].getAttribute(
'value');
1595 nameSplit = name.split(
'/');
1600 str += htmlOpen(
"a",
1602 "title":
"Open file in a new browser tab: \n" +
1604 "onclick":
"DesktopContent.openNewBrowserTab(" +
1605 "\"" + nameSplit[nameSplit.length-1] +
"\",\"\"," +
1606 "\"/WebPath/html/CodeEditor.html?urn=" +
1607 DesktopContent._localUrnLid +
"&" +
1608 "startFilePrimary=" +
1609 name +
"\",0 /*unique*/);' ",
1611 "<img class='dirNavFileNewWindowImgNewWindow' " +
1612 "src='/WebPath/images/windowContentImages/CodeEditor-openInNewWindow.png'>"
1616 str += htmlOpen(
"a",
1618 "title":
"Open file in the other editor pane of the split-view: \n" +
1620 "onclick":
"CodeEditor.editor.openFile(" +
1621 (!forPrimary) +
",\"" +
1623 name.substr(name.lastIndexOf(
'.')+1) +
"\"" +
1626 "<img class='dirNavFileNewWindowImgNewPane' " +
1627 "src='/WebPath/images/windowContentImages/CodeEditor-openInOtherPane.png'>"
1631 str +=
"<a class='dirNavFile' onclick='CodeEditor.editor.openFile(" +
1632 forPrimary +
",\"" +
1634 name.substr(name.lastIndexOf(
'.')+1) +
"\"" +
1635 ")' title='Open file: \nsrcs" + name +
"' >";
1637 str += nameSplit[nameSplit.length-1] +
"</a>";
1641 str +=
"</td><td style='padding-left:20px'>" + nameSplit[1] +
"</td></tr>";
1644 if(specialFiles.length)
1650 for(i=0;i<dirs.length;++i)
1652 name = dirs[i].getAttribute(
'value');
1655 str += htmlOpen(
"a",
1657 "title":
"Open folder in a new browser tab: \n" +
1658 "srcs" + path +
"/" + name,
1659 "onclick":
"DesktopContent.openNewBrowserTab(" +
1660 "\"" + name +
"\",\"\"," +
1661 "\"/WebPath/html/CodeEditor.html?urn=" +
1662 DesktopContent._localUrnLid +
"&" +
1663 "openDirectoryPrimary=" +
1664 path +
"/" + name +
"\",0 /*unique*/);' ",
1666 "<img class='dirNavFileNewWindowImgNewWindow' " +
1667 "src='/WebPath/images/windowContentImages/CodeEditor-openInNewWindow.png'>"
1671 str += htmlOpen(
"a",
1673 "title":
"Open folder in the other editor pane of the split-view: \n" +
1674 "srcs" + path +
"/" + name,
1675 "onclick":
"CodeEditor.editor.openDirectory(" +
1676 (!forPrimary) +
",\"" +
1677 path +
"/" + name +
"\");",
1679 "<img class='dirNavFileNewWindowImgNewPane' " +
1680 "src='/WebPath/images/windowContentImages/CodeEditor-openInOtherPane.png'>"
1684 str +=
"<a class='dirNavFolder' onclick='CodeEditor.editor.openDirectory(" +
1685 forPrimary +
",\"" +
1686 path +
"/" + name +
"\"" +
1687 ")' title='Open folder: \nsrcs" + path +
"/" + name +
"' >" +
1696 for(i=0;i<files.length;++i)
1698 name = files[i].getAttribute(
'value');
1701 str += htmlOpen(
"a",
1703 "title":
"Open file in a new browser tab: \n" +
1704 "srcs" + path +
"/" + name,
1705 "onclick":
"DesktopContent.openNewBrowserTab(" +
1706 "\"" + name +
"\",\"\"," +
1707 "\"/WebPath/html/CodeEditor.html?urn=" +
1708 DesktopContent._localUrnLid +
"&" +
1709 "startFilePrimary=" +
1710 path +
"/" + name +
"\",0 /*unique*/);' ",
1712 "<img class='dirNavFileNewWindowImgNewWindow' " +
1713 "src='/WebPath/images/windowContentImages/CodeEditor-openInNewWindow.png'>"
1717 str += htmlOpen(
"a",
1719 "title":
"Open file in the other editor pane of the split-view: \n" +
1720 "srcs" + path +
"/" + name,
1721 "onclick":
"CodeEditor.editor.openFile(" +
1722 (!forPrimary) +
",\"" +
1723 path +
"/" + name +
"\", \"" +
1724 name.substr(name.lastIndexOf(
'.')+1) +
"\"" +
1727 "<img class='dirNavFileNewWindowImgNewPane' " +
1728 "src='/WebPath/images/windowContentImages/CodeEditor-openInOtherPane.png'>"
1733 str +=
"<a class='dirNavFile' onclick='CodeEditor.editor.openFile(" +
1734 forPrimary +
",\"" +
1735 path +
"/" + name +
"\", \"" +
1736 name.substr(name.lastIndexOf(
'.')+1) +
"\"" +
1737 ")' title='Open file: \nsrcs" + path +
"/" + name +
"' >" +
1746 document.getElementById(
"directoryNav" + forPrimary).innerHTML = str;
1752 this.openDirectory =
function(forPrimary,path,doNotOpenPane)
1754 forPrimary = forPrimary?1:0;
1756 if(!path || path ==
"") path =
"/";
1757 Debug.log(
"openDirectory forPrimary=" + forPrimary +
1760 DesktopContent.XMLHttpRequest(
"Request?RequestType=" + _requestPreamble +
1762 "&option=getDirectoryContent" +
1767 CodeEditor.editor.handleDirectoryContent(forPrimary, req);
1768 CodeEditor.editor.toggleDirectoryNav(forPrimary,1 );
1772 if(!doNotOpenPane && !forPrimary && _viewMode == 0)
1773 CodeEditor.editor.toggleView();
1781 this.openRelatedFile =
function(forPrimary,inOtherPane)
1783 Debug.log(
"openRelatedFile forPrimary=" + forPrimary +
1784 " path=" + _filePath[forPrimary]);
1786 var relatedPath = _filePath[forPrimary];
1787 var relatedExtension = _fileExtension[forPrimary];
1788 var targetPane = inOtherPane?!forPrimary:forPrimary;
1791 var altExtensions = [];
1793 if(relatedExtension ==
"html")
1795 relatedExtension =
"js";
1796 var i = relatedPath.indexOf(
"/html/");
1799 altPaths.push(relatedPath.substr(0,i) +
"/css/" +
1800 relatedPath.substr(i + (
"/html/").length));
1801 altExtensions.push(
"css");
1803 relatedPath = relatedPath.substr(0,i) +
"/js/" +
1804 relatedPath.substr(i + (
"/html/").length);
1808 altPaths.push(relatedPath);
1809 altExtensions.push(
"css");
1812 CodeEditor.editor.openFile(targetPane,relatedPath,relatedExtension,
1813 undefined , undefined,
1814 altPaths , altExtensions);
1817 else if(relatedExtension[0] ==
"h")
1819 relatedExtension =
"cc";
1821 altPaths.push(relatedPath);
1822 altExtensions.push(
"cc");
1824 altPaths.push(relatedPath+
"_interface");
1825 altExtensions.push(
"cc");
1826 altPaths.push(relatedPath+
"_processor");
1827 altExtensions.push(
"cc");
1828 altPaths.push(relatedPath+
"_slowcontrols");
1829 altExtensions.push(
"cc");
1830 altPaths.push(relatedPath+
"_table");
1831 altExtensions.push(
"cc");
1833 altPaths.push(relatedPath);
1834 altExtensions.push(
"cpp");
1835 altPaths.push(relatedPath);
1836 altExtensions.push(
"CC");
1837 altPaths.push(relatedPath);
1838 altExtensions.push(
"cxx");
1839 altPaths.push(relatedPath);
1840 altExtensions.push(
"c");
1841 altPaths.push(relatedPath);
1842 altExtensions.push(
"C");
1843 altPaths.push(relatedPath);
1844 altExtensions.push(
"icc");
1847 if(relatedPath.indexOf(
"Interface") >= 0)
1848 relatedPath +=
"_interface";
1849 else if(relatedPath.indexOf(
"Processor") >= 0)
1850 relatedPath +=
"_processor";
1851 else if(relatedPath.indexOf(
"Consumer") >= 0)
1852 relatedPath +=
"_processor";
1853 else if(relatedPath.indexOf(
"Producer") >= 0)
1854 relatedPath +=
"_processor";
1855 else if(relatedPath.indexOf(
"Controls") >= 0)
1856 relatedPath +=
"_slowcontrols";
1857 else if(relatedPath.indexOf(
"Table") >= 0)
1858 relatedPath +=
"_table";
1860 CodeEditor.editor.openFile(targetPane,relatedPath,relatedExtension,
1861 undefined , undefined,
1862 altPaths , altExtensions);
1865 else if(relatedExtension ==
"css")
1867 relatedExtension =
"js";
1868 var i = relatedPath.indexOf(
"/css/");
1872 altPaths.push(relatedPath.substr(0,i) +
"/html/" +
1873 relatedPath.substr(i + (
"/css/").length));
1874 altExtensions.push(
"html");
1876 relatedPath = relatedPath.substr(0,i) +
"/js/" +
1877 relatedPath.substr(i + (
"/css/").length);
1881 altPaths.push(relatedPath);
1882 altExtensions.push(
"html");
1885 CodeEditor.editor.openFile(targetPane,relatedPath,relatedExtension,
1886 undefined , undefined,
1887 altPaths , altExtensions);
1890 else if(relatedExtension[0] ==
'c' ||
1891 relatedExtension[0] ==
'C' ||
1892 relatedExtension ==
"icc")
1894 relatedExtension =
"h";
1896 altPaths.push(relatedPath);
1897 altExtensions.push(
"h");
1900 if((i = relatedPath.indexOf(
"_interface")) > 0 &&
1901 i == relatedPath.length-(
"_interface").length)
1902 relatedPath = relatedPath.substr(0,i);
1903 if((i = relatedPath.indexOf(
"_processor")) > 0 &&
1904 i == relatedPath.length-(
"_processor").length)
1905 relatedPath = relatedPath.substr(0,i);
1906 if((i = relatedPath.indexOf(
"_slowcontrols")) > 0 &&
1907 i == relatedPath.length-(
"_slowcontrols").length)
1908 relatedPath = relatedPath.substr(0,i);
1909 if((i = relatedPath.indexOf(
"_table")) > 0 &&
1910 i == relatedPath.length-(
"_table").length)
1911 relatedPath = relatedPath.substr(0,i);
1913 altPaths.push(relatedPath);
1914 altExtensions.push(
"hh");
1915 altPaths.push(relatedPath);
1916 altExtensions.push(
"hpp");
1917 altPaths.push(relatedPath);
1918 altExtensions.push(
"hxx");
1919 altPaths.push(relatedPath);
1920 altExtensions.push(
"H");
1922 CodeEditor.editor.openFile(targetPane,relatedPath,relatedExtension,
1923 undefined , undefined,
1924 altPaths , altExtensions);
1927 else if(relatedExtension ==
"js")
1929 relatedExtension =
"css";
1930 var i = relatedPath.indexOf(
"/js/");
1934 altPaths.push(relatedPath.substr(0,i) +
"/html/" +
1935 relatedPath.substr(i + (
"/js/").length));
1936 altExtensions.push(
"html");
1938 relatedPath = relatedPath.substr(0,i) +
"/css/" +
1939 relatedPath.substr(i + (
"/js/").length);
1943 altPaths.push(relatedPath);
1944 altExtensions.push(
"html");
1947 CodeEditor.editor.openFile(targetPane,relatedPath,relatedExtension,
1948 undefined , undefined,
1949 altPaths , altExtensions);
1953 Debug.log(
"Giving up on attempt to open a related file for " +
1954 relatedPath +
"." + relatedExtension +
1955 "... no known related file.", Debug.HIGH_PRIORITY);
1966 this.openFile =
function(forPrimary,path,extension,doConfirm,gotoLine,
1967 altPaths,altExtensions,propagateErr)
1969 forPrimary = forPrimary?1:0;
1971 Debug.log(
"openFile forPrimary=" + forPrimary +
1973 var i = path.lastIndexOf(
'.');
1975 path = path.substr(0,i);
1977 if(!propagateErr) propagateErr =
"";
1981 DesktopContent.popUpVerification(
1982 "Do you want to reload the file from the server (and discard your changes)?",
1990 var keys = Object.keys(_fileHistoryStack);
1991 var filename = path +
"." + extension;
1992 for(i;i<keys.length;++i)
1993 if(filename == keys[i])
1995 Debug.log(
"Found " + filename +
" in file history.");
2000 fileObj.path = path;
2001 fileObj.extension = extension;
2002 fileObj.text = _fileHistoryStack[filename][0];
2003 fileObj.fileWasModified = _fileHistoryStack[filename][2];
2004 fileObj.fileLastSave = _fileHistoryStack[filename][3];
2006 console.log(
"fileObj",fileObj);
2008 CodeEditor.editor.handleFileContent(forPrimary,0,fileObj);
2010 CodeEditor.editor.toggleDirectoryNav(forPrimary,
false );
2013 if(!forPrimary && _viewMode == 0)
2014 CodeEditor.editor.toggleView();
2022 function localDoIt()
2024 CodeEditor.editor.toggleDirectoryNav(forPrimary,
false );
2026 DesktopContent.XMLHttpRequest(
"Request?RequestType=" + _requestPreamble +
2028 "&option=getFileContent" +
2035 var err = DesktopContent.getXMLValue(req,
"Error");
2038 if(altPaths && altPaths.length &&
2039 altExtensions && altExtensions.length)
2042 CodeEditor.editor.openFile(forPrimary,
2043 altPaths.splice(0,1)[0],
2044 altExtensions.splice(0,1)[0],
2045 undefined , undefined,
2046 altPaths , altExtensions,
2047 propagateErr + err );
2050 Debug.log(propagateErr + err,Debug.HIGH_PRIORITY);
2059 CodeEditor.editor.toggleDirectoryNav(forPrimary,0 );
2060 CodeEditor.editor.handleFileContent(forPrimary, req);
2063 if(!forPrimary && _viewMode == 0)
2064 CodeEditor.editor.toggleView();
2066 if(gotoLine !== undefined)
2067 CodeEditor.editor.gotoLine(forPrimary,gotoLine);
2071 Debug.log(
"Ignoring error handling file open:[" + DesktopContent.getExceptionLineNumber(e) +
"]: " + e);
2073 console.log(DesktopContent._loadBox.style.display);
2083 this.getLine =
function(forPrimary)
2085 Debug.log(
"getLine() forPrimary=" + forPrimary);
2088 var el = _eel[forPrimary];
2089 var cursor = CodeEditor.editor.getCursor(el);
2091 if(cursor.startNodeIndex === undefined)
2093 Debug.log(
"No cursor, so defaulting to top");
2099 for(n=0; n<el.childNodes.length; ++n)
2101 node = el.childNodes[n];
2102 val = node.textContent;
2105 for(i=0;i<val.length;++i)
2108 if(!cursor.focusAtEnd &&
2109 n == cursor.startNodeIndex &&
2110 i == cursor.startPos)
2112 else if(cursor.focusAtEnd &&
2113 n == cursor.endNodeIndex &&
2122 if(!cursor.focusAtEnd &&
2123 n == cursor.startNodeIndex)
2125 Debug.log(
"Found cursor at line " + cursor.line);
2128 else if(cursor.focusAtEnd &&
2129 n == cursor.endNodeIndex)
2131 Debug.log(
"Found cursor at line " + cursor.line);
2141 this.gotoLine =
function(forPrimary,line,selectionCursor,topOfView)
2144 if(line < 1) line = 1;
2145 if(line > _numberOfLines[forPrimary])
2146 line = _numberOfLines[forPrimary];
2147 console.log(
"Goto line number ",line,selectionCursor);
2150 window.location.href =
"#" + forPrimary +
"L" + line;
2156 var el = _eel[forPrimary];
2163 "startNodeIndex": 0,
2172 cursor.endNodeIndex = selectionCursor.startNodeIndex;
2173 cursor.endPos = selectionCursor.startPos;
2174 cursor.focusAtEnd = selectionCursor.focusAtEnd;
2176 CodeEditor.editor.setCursor(el,cursor,
true );
2181 var i,n,node,el,val;
2184 var newLine =
false;
2188 for(n=0; n<el.childNodes.length; ++n)
2190 node = el.childNodes[n];
2191 val = node.textContent;
2194 for(i=0;i<val.length;++i)
2203 if(line == lineCount)
2206 Debug.log(
"Found line " + line);
2224 "startNodeIndex":lastNode,
2226 "endNodeIndex":lastNode,
2234 cursor.focusAtEnd = selectionCursor.focusAtEnd;
2236 if(lastNode < selectionCursor.startNodeIndex ||
2237 ( lastNode == selectionCursor.startNodeIndex &&
2238 lastPos < selectionCursor.startPos))
2240 cursor.endNodeIndex = selectionCursor.startNodeIndex;
2241 cursor.endPos = selectionCursor.startPos;
2245 cursor.startNodeIndex = selectionCursor.startNodeIndex;
2246 cursor.startPos = selectionCursor.startPos;
2250 CodeEditor.editor.setCursor(el,cursor,
2256 CodeEditor.editor.setCursor(el,cursor,
true );
2268 this.handleFileContent =
function(forPrimary,req,fileObj)
2270 forPrimary = forPrimary?1:0;
2272 Debug.log(
"handleFileContent forPrimary=" + forPrimary);
2278 var fileWasModified, fileLastSave;
2282 path = DesktopContent.getXMLValue(req,
"path");
2283 extension = DesktopContent.getXMLValue(req,
"ext");
2284 text = DesktopContent.getXMLValue(req,
"content");
2285 fileWasModified =
false;
2290 path = fileObj.path;
2291 extension = fileObj.extension;
2292 text = fileObj.text;
2293 fileWasModified = fileObj.fileWasModified;
2294 fileLastSave = fileObj.fileLastSave;
2299 text = text.replace(
new RegExp(
2300 String.fromCharCode(160),
'g'),
' ');
2304 _filePath[forPrimary] = path;
2305 _fileExtension[forPrimary] = extension;
2306 _fileWasModified[forPrimary] = fileWasModified;
2307 _fileLastSave[forPrimary] = fileLastSave;
2309 _undoStack[forPrimary] = [];
2310 _undoStackLatestIndex[forPrimary] = -1;
2312 var el = _eel[forPrimary];
2315 DesktopContent.showLoading(
function()
2319 el.textContent = text;
2320 CodeEditor.editor.displayFileHeader(forPrimary);
2323 { Debug.log(
"Ignoring error:[" + DesktopContent.getExceptionLineNumber(e) +
"]: " + e); }
2330 this.setCursor =
function(el,inCursor,scrollIntoView)
2332 if(inCursor.startNodeIndex !== undefined)
2336 "startNodeIndex": inCursor.startNodeIndex,
2337 "startPos": inCursor.startPos,
2338 "endNodeIndex": inCursor.endNodeIndex,
2339 "endPos": inCursor.endPos,
2340 "focusAtEnd": inCursor.focusAtEnd,
2344 var scrollEndIntoView = cursor.focusAtEnd?
true:
false;
2348 console.log(
"set cursor",cursor,
"scrollIntoView=",scrollIntoView,
2349 "scrollEndIntoView=",scrollEndIntoView);
2351 var range = document.createRange();
2353 var firstEl = el.childNodes[cursor.startNodeIndex];
2357 var secondEl = el.childNodes[cursor.endNodeIndex];
2363 Debug.log(
"scrollIntoView");
2372 Debug.log(
"inserting scroll 2nd element");
2376 var val = secondEl.textContent;
2377 if(cursor.endPos < val.length)
2379 var newNode1 = document.createTextNode(
2380 val.substr(0,cursor.endPos));
2381 el.insertBefore(newNode1,secondEl);
2383 var newNode = document.createElement(
"label");
2384 newNode.textContent = val[cursor.endPos];
2385 el.insertBefore(newNode,secondEl);
2387 if(cursor.endPos+1 < val.length)
2388 secondEl.textContent = val.substr(cursor.endPos+1);
2390 secondEl.textContent =
"";
2392 newNode.scrollIntoViewIfNeeded();
2394 el.removeChild(newNode);
2395 el.removeChild(newNode1);
2396 secondEl.textContent = val;
2400 el.childNodes[cursor.endNodeIndex+1].scrollIntoViewIfNeeded();
2406 Debug.log(
"Failed to scroll to inserted 2nd element:[" + DesktopContent.getExceptionLineNumber(e) +
"]: " + e);
2409 secondEl.scrollIntoViewIfNeeded();
2413 Debug.log(
"Failed to scroll 2nd element:[" + DesktopContent.getExceptionLineNumber(e) +
"]: " + e);
2418 Debug.log(
"inserting scroll 1st element");
2423 if(!scrollEndIntoView)
2426 firstEl = el.childNodes[cursor.startNodeIndex];
2427 var val = firstEl.textContent;
2428 var newNode1 = document.createTextNode(
2429 val.substr(0,cursor.startPos));
2431 el.insertBefore(newNode1,firstEl);
2433 var newNode = document.createElement(
"label");
2434 newNode.textContent = val[cursor.startPos];
2435 el.insertBefore(newNode,firstEl);
2437 firstEl.textContent = val.substr(cursor.startPos+1);
2439 newNode.scrollIntoViewIfNeeded();
2442 el.removeChild(newNode);
2443 el.removeChild(newNode1);
2444 firstEl.textContent = val;
2447 Debug.log(
"scrollEndIntoView only");
2451 Debug.log(
"Failed to scroll to inserted 1st element:[" + DesktopContent.getExceptionLineNumber(e) +
"]: " + e);
2454 firstEl.scrollIntoViewIfNeeded();
2458 Debug.log(
"Failed to scroll 1st element:[" + DesktopContent.getExceptionLineNumber(e) +
"]: " + e);
2467 if(firstEl.firstChild)
2468 firstEl = firstEl.firstChild;
2469 if(secondEl.firstChild)
2470 secondEl = secondEl.firstChild;
2472 range.setStart(firstEl,
2474 range.setEnd(secondEl,
2478 var selection = window.getSelection();
2479 selection.removeAllRanges();
2480 selection.addRange(range);
2483 if(scrollEndIntoView)
2484 selection.extend(secondEl,cursor.endPos);
2496 console.log(
"set cursor err:",err);
2503 this.createCursorFromContentPosition =
function(el,startPos,endPos)
2507 "startNodeIndex":undefined,
2508 "startPos":undefined,
2509 "endNodeIndex":undefined,
2520 for(i=0;i<el.childNodes.length;++i)
2522 sum += el.childNodes[i].textContent.length;
2524 if(cursor.startNodeIndex === undefined &&
2525 startPos >= oldSum &&
2529 cursor.startNodeIndex = i;
2530 cursor.startPos = startPos - oldSum;
2532 if(endPos >= oldSum &&
2536 cursor.endNodeIndex = i;
2537 cursor.endPos = endPos - oldSum;
2544 console.log(
"createCursorFromContentPosition:",cursor);
2549 console.log(
"get cursor err:",err);
2557 this.getCursor =
function(el)
2561 "startNodeIndex":undefined,
2562 "startPos":undefined,
2563 "endNodeIndex":undefined,
2565 "startPosInContent":undefined,
2566 "endPosInContent":undefined,
2567 "focusAtEnd":undefined
2573 var selection = window.getSelection();
2574 var range = selection.getRangeAt(0);
2575 var focusNode = selection.focusNode;
2576 var extentNode = selection.extentNode;
2578 cursor.startPos = range.startOffset;
2579 cursor.endPos = range.endOffset;
2582 for(i=0;i<el.childNodes.length;++i)
2584 if(cursor.startNodeIndex === undefined &&
2586 el.childNodes[i] == range.startContainer ||
2587 el.childNodes[i] == range.startContainer.parentNode ||
2588 el.childNodes[i] == range.startContainer.parentNode.parentNode ||
2589 el.childNodes[i] == range.startContainer.parentNode.parentNode.parentNode) )
2591 cursor.startNodeIndex = i;
2592 cursor.startPosInContent = sum + cursor.startPos;
2594 if(focusNode == range.startContainer ||
2595 extentNode == range.startContainer)
2596 cursor.focusAtEnd =
false;
2599 if(el.childNodes[i] == range.endContainer ||
2600 el.childNodes[i] == range.endContainer.parentNode ||
2601 el.childNodes[i] == range.endContainer.parentNode.parentNode ||
2602 el.childNodes[i] == range.startContainer.parentNode.parentNode.parentNode)
2604 cursor.endNodeIndex = i;
2605 cursor.endPosInContent = sum + cursor.endPos;
2607 if(cursor.focusAtEnd == undefined &&
2608 (focusNode == range.endContainer ||
2609 extentNode == range.endContainer))
2610 cursor.focusAtEnd =
true;
2615 sum += el.childNodes[i].textContent.length;
2624 console.log(
"get cursor err:",err);
2632 var _DECORATION_RED =
"rgb(202, 52, 52)";
2633 var _DECORATION_BLUE =
"rgb(64, 86, 206)";
2634 var _DECORATION_GREEN =
"rgb(33, 175, 60)";
2635 var _DECORATION_BLACK =
"rgb(5, 5, 5)";
2636 var _DECORATION_GRAY =
"rgb(162, 179, 158)";
2637 var _DECORATIONS = {
2639 "ADD_SUBDIRECTORY" : _DECORATION_RED,
2640 "include_directories" : _DECORATION_RED,
2641 "simple_plugin" : _DECORATION_RED,
2642 "set" : _DECORATION_RED,
2643 "install_headers" : _DECORATION_RED,
2644 "install_source" : _DECORATION_RED,
2645 "enable_testing" : _DECORATION_RED,
2646 "CMAKE_MINIMUM_REQUIRED": _DECORATION_RED,
2647 "include" : _DECORATION_RED,
2648 "create_doxygen_documentation": _DECORATION_RED,
2651 "#define" : _DECORATION_RED,
2652 "#undef" : _DECORATION_RED,
2653 "#include" : _DECORATION_RED,
2654 "#ifndef" : _DECORATION_RED,
2655 "#if" : _DECORATION_RED,
2656 "#else" : _DECORATION_RED,
2657 "#endif" : _DECORATION_RED,
2658 "using" : _DECORATION_RED,
2659 "namespace" : _DECORATION_RED,
2660 "class" : _DECORATION_RED,
2661 "public" : _DECORATION_RED,
2662 "private" : _DECORATION_RED,
2663 "protected" : _DECORATION_RED,
2664 "static" : _DECORATION_RED,
2665 "virtual" : _DECORATION_RED,
2666 "override" : _DECORATION_RED,
2667 "const" : _DECORATION_RED,
2668 "void" : _DECORATION_RED,
2669 "bool" : _DECORATION_RED,
2670 "unsigned" : _DECORATION_RED,
2671 "int" : _DECORATION_RED,
2672 "uint64_t" : _DECORATION_RED,
2673 "uint32_t" : _DECORATION_RED,
2674 "uint16_t" : _DECORATION_RED,
2675 "uint8_t" : _DECORATION_RED,
2676 "size_t" : _DECORATION_RED,
2677 "time_t" : _DECORATION_RED,
2678 "long" : _DECORATION_RED,
2679 "float" : _DECORATION_RED,
2680 "double" : _DECORATION_RED,
2681 "return" : _DECORATION_RED,
2682 "char" : _DECORATION_RED,
2683 "if" : _DECORATION_RED,
2684 "else" : _DECORATION_RED,
2685 "for" : _DECORATION_RED,
2686 "while" : _DECORATION_RED,
2687 "do" : _DECORATION_RED,
2688 "switch" : _DECORATION_RED,
2689 "case" : _DECORATION_RED,
2690 "default" : _DECORATION_RED,
2691 "try" : _DECORATION_RED,
2692 "catch" : _DECORATION_RED,
2693 "this" : _DECORATION_RED,
2694 "true" : _DECORATION_RED,
2695 "false" : _DECORATION_RED,
2696 "auto" : _DECORATION_RED,
2698 "fstream" : _DECORATION_GREEN,
2699 "sstream" : _DECORATION_GREEN,
2700 "istream" : _DECORATION_GREEN,
2701 "ostream" : _DECORATION_GREEN,
2703 "std" : _DECORATION_GREEN,
2704 "ots" : _DECORATION_GREEN,
2705 "ConfigurationTree" : _DECORATION_GREEN,
2706 "string" : _DECORATION_GREEN,
2707 "set" : _DECORATION_GREEN,
2708 "vector" : _DECORATION_GREEN,
2709 "array" : _DECORATION_GREEN,
2710 "pair" : _DECORATION_GREEN,
2711 "get" : _DECORATION_GREEN,
2712 "map" : _DECORATION_GREEN,
2713 "endl" : _DECORATION_GREEN,
2714 "runtime_error" : _DECORATION_GREEN,
2715 "memcpy" : _DECORATION_GREEN,
2716 "cout" : _DECORATION_GREEN,
2719 "this" : _DECORATION_RED,
2720 "var" : _DECORATION_RED,
2721 "return" : _DECORATION_RED,
2722 "function" : _DECORATION_RED,
2723 "if" : _DECORATION_RED,
2724 "else" : _DECORATION_RED,
2725 "for" : _DECORATION_RED,
2726 "while" : _DECORATION_RED,
2727 "do" : _DECORATION_RED,
2728 "switch" : _DECORATION_RED,
2729 "case" : _DECORATION_RED,
2730 "default" : _DECORATION_RED,
2731 "try" : _DECORATION_RED,
2732 "catch" : _DECORATION_RED,
2733 "new" : _DECORATION_RED,
2734 "instanceof" : _DECORATION_RED,
2735 "true" : _DECORATION_RED,
2736 "false" : _DECORATION_RED,
2738 "Debug" : _DECORATION_GREEN,
2739 "DesktopContent" : _DECORATION_GREEN,
2740 "HIGH_PRIORITY" : _DECORATION_GREEN,
2741 "WARN_PRIORITY" : _DECORATION_GREEN,
2742 "INFO_PRIORITY" : _DECORATION_GREEN,
2743 "LOW_PRIORITY" : _DECORATION_GREEN,
2745 "Math" : _DECORATION_GREEN,
2746 "String" : _DECORATION_GREEN,
2747 "window" : _DECORATION_GREEN,
2748 "document" : _DECORATION_GREEN,
2749 "textContent" : _DECORATION_GREEN,
2750 "innerHTML" : _DECORATION_GREEN,
2753 "if" : _DECORATION_RED,
2754 "then" : _DECORATION_RED,
2755 "else" : _DECORATION_RED,
2756 "fi" : _DECORATION_RED,
2757 "for" : _DECORATION_RED,
2758 "in" : _DECORATION_RED,
2759 "while" : _DECORATION_RED,
2760 "do" : _DECORATION_RED,
2761 "done" : _DECORATION_RED,
2762 "switch" : _DECORATION_RED,
2763 "case" : _DECORATION_RED,
2764 "default" : _DECORATION_RED,
2765 "export" : _DECORATION_RED,
2767 "echo" : _DECORATION_GREEN,
2768 "cd" : _DECORATION_GREEN,
2769 "cp" : _DECORATION_GREEN,
2770 "rm" : _DECORATION_GREEN,
2771 "cat" : _DECORATION_GREEN,
2772 "wget" : _DECORATION_GREEN,
2773 "chmod" : _DECORATION_GREEN,
2774 "sleep" : _DECORATION_GREEN,
2777 this.updateDecorations =
function(forPrimary,forceDisplayComplete,forceDecorations)
2779 forPrimary = forPrimary?1:0;
2781 Debug.log(
"updateDecorations forPrimary=" + forPrimary +
" forceDisplayComplete=" + forceDisplayComplete);
2783 var el = _eel[forPrimary];
2784 var elTextObj = {
"text":el.textContent,
"time":Date.now()};
2785 var wasSnapshot = CodeEditor.editor.updateFileSnapshot(forPrimary,
2788 if(wasSnapshot || forceDisplayComplete)
2789 CodeEditor.editor.updateOutline(forPrimary,elTextObj);
2791 if(!forceDecorations && !wasSnapshot)
2793 Debug.log(
"unchanged, skipping decorations");
2803 var cursor = CodeEditor.editor.getCursor(el);
2807 CodeEditor.editor.updateLastSave(forPrimary);
2811 var decor, fontWeight;
2813 var commentString =
"#";
2816 if(_fileExtension[forPrimary][0] ==
'c' ||
2817 _fileExtension[forPrimary][0] ==
'C' ||
2818 _fileExtension[forPrimary][0] ==
'h' ||
2819 _fileExtension[forPrimary][0] ==
'j' ||
2820 _fileExtension[forPrimary] ==
"icc")
2822 commentString =
"//";
2835 var fileDecorType =
"txt";
2836 if( _fileExtension[forPrimary] ==
"html" ||
2837 _fileExtension[forPrimary] ==
"js")
2838 fileDecorType =
"js";
2839 else if(_fileExtension[forPrimary][0] ==
'c' ||
2840 _fileExtension[forPrimary][0] ==
'C' ||
2841 _fileExtension[forPrimary][0] ==
'h' ||
2842 _fileExtension[forPrimary][0] ==
'j' ||
2843 _fileExtension[forPrimary] ==
"icc")
2844 fileDecorType =
"c++";
2845 else if(_fileExtension[forPrimary] ==
'sh' ||
2846 _fileExtension[forPrimary] ==
'py')
2847 fileDecorType =
"sh";
2852 var startOfWord = -1;
2853 var startOfString = -1;
2854 var stringQuoteChar;
2856 var startOfComment = -1;
2857 var firstSpecialStringStartHandling =
true;
2858 var firstSpecialStringEndHandling =
true;
2859 var endPositionCache;
2870 function localInsertLabel(startPos, isQuote)
2874 newNode = document.createTextNode(val.substr(0,startPos));
2875 el.insertBefore(newNode,node);
2877 newNode = document.createElement(
"label");
2878 newNode.style.fontWeight = fontWeight;
2879 newNode.style.color = decor;
2880 newNode.textContent = specialString;
2882 el.insertBefore(newNode,node);
2886 var str = newNode.textContent;
2887 str = str.substr(str.lastIndexOf(
'.')+1);
2890 if(str.length > 0 && str.length <= 4 && (
2894 str.substr(0,3) ==
"txt" ||
2895 str.substr(0,2) ==
"py" ||
2896 str.substr(0,2) ==
"sh" ||
2900 Debug.log(
"is quote " + str);
2902 newNode.onmouseover =
function(e)
2904 window.clearTimeout(_fileStringHoverTimeout);
2906 var x = this.offsetWidth + this.offsetLeft + 64;
2907 var y = this.offsetTop;
2908 e.stopPropagation();
2911 if(_fileStringHoverEl.parentNode)
2913 _fileStringHoverEl.parentNode.removeChild(_fileStringHoverEl);
2918 _fileStringHoverEl = document.createElement(
"div");
2919 _fileStringHoverEl.setAttribute(
"id",
"fileStringHoverEl");
2920 _fileStringHoverEl.setAttribute(
"contentEditable",
"false");
2921 _fileStringHoverEl.onmouseover =
function(e)
2923 window.clearTimeout(_fileStringHoverTimeout);
2924 e.stopPropagation();
2928 _fileStringHoverEl.style.display =
'none';
2931 var name = this.textContent;
2934 name = name.substr(1,name.length-2);
2935 var nameArr = name.split(
'/');
2936 if(nameArr.length == 0)
2938 Debug.log(
"empty name array, error! name = " + name);
2941 else if(nameArr.length > 1 && nameArr[0] ==
"" &&
2942 nameArr[1] ==
"WebPath")
2944 name =
"/otsdaq_utilities/WebGUI" +
2945 name.substr((
"/WebPath").length);
2947 else if(nameArr[0] !=
"")
2950 var i = nameArr[0].indexOf(
'-');
2954 if(nameArr[0] !=
"otsdaq-core")
2956 nameArr[0] = nameArr[0].substr(0,i) +
'_'
2957 + nameArr[0].substr(i+1);
2960 nameArr[0] =
"otsdaq";
2965 name =
"/" + nameArr[0] +
"/" + name;
2969 Debug.log(
"name " + name);
2973 str += htmlOpen(
"a",
2975 "title":
"Open file in this editor pane: \n" +
2977 "onclick":
"CodeEditor.editor.openFile(" +
2978 (forPrimary) +
",\"" +
2980 name.substr(name.lastIndexOf(
'.')+1) +
"\"" +
2984 "style='float: left; padding: 1px 0 1px 6px;'>" +
2986 "style='border:1px solid rgb(99, 98, 98); border-radius: 2px; width: 9px;" +
2987 "height: 9px; '></div></div>"
2990 str += htmlOpen(
"a",
2992 "title":
"Open file in the other editor pane of the split-view: \n" +
2994 "onclick":
"CodeEditor.editor.openFile(" +
2995 (!forPrimary) +
",\"" +
2997 name.substr(name.lastIndexOf(
'.')+1) +
"\"" +
3001 "style='float: left; padding: 0;'>" +
3002 "<img class='dirNavFileNewWindowImgNewPane' " +
3003 "src='/WebPath/images/windowContentImages/CodeEditor-openInOtherPane.png'></div>"
3006 str += htmlOpen(
"a",
3008 "title":
"Open file in a new browser tab: \n" +
3010 "onclick":
"DesktopContent.openNewBrowserTab(" +
3011 "\"" + nameArr[nameArr.length-1] +
"\",\"\"," +
3012 "\"/WebPath/html/CodeEditor.html?urn=" +
3013 DesktopContent._localUrnLid +
"&" +
3014 "startFilePrimary=" +
3015 name +
"\",0 /*unique*/);' ",
3018 "style='float: left; padding: 0 6px 0 0;'>" +
3019 "<img class='dirNavFileNewWindowImgNewWindow' " +
3020 "src='/WebPath/images/windowContentImages/CodeEditor-openInNewWindow.png'></div>"
3023 _fileStringHoverEl.innerHTML = str;
3025 this.parentNode.appendChild(_fileStringHoverEl);
3028 _fileStringHoverEl.style.left = x +
"px";
3029 _fileStringHoverEl.style.top = y +
"px";
3031 _fileStringHoverEl.style.display =
'block';
3038 node.textContent = val.substr(i);
3042 if(cursor.startNodeIndex !== undefined)
3044 if(n < cursor.startNodeIndex)
3047 cursor.startNodeIndex += 2;
3048 cursor.endNodeIndex += 2;
3055 if(n == cursor.startNodeIndex)
3058 if(cursor.startPos < startPos)
3063 else if(cursor.startPos < i)
3066 ++cursor.startNodeIndex;
3067 cursor.startPos -= startPos;
3072 cursor.startNodeIndex += 2;
3073 if(val[cursor.startPos-1] ==
'\r') --cursor.startPos;
3074 cursor.startPos -= i;
3079 if(n == cursor.endNodeIndex)
3082 if(cursor.endPos < startPos)
3087 else if(cursor.endPos < i)
3090 ++cursor.endNodeIndex;
3091 cursor.endPos -= startPos;
3096 cursor.endNodeIndex += 2;
3097 if(val[cursor.endPos-1] ==
'\r') --cursor.endPos;
3102 else if(n < cursor.endNodeIndex)
3104 cursor.endNodeIndex += 2;
3114 for(n=0;!done && n<el.childNodes.length;++n)
3116 node = el.childNodes[n];
3117 val = node.textContent;
3119 if(node.nodeName ==
"LABEL" ||
3120 node.nodeName ==
"FONT" ||
3121 node.nodeName ==
"SPAN" ||
3122 node.nodeName ==
"PRE")
3127 if((_DECORATIONS[fileDecorType][val] === undefined &&
3128 (val[0] != commentString[0] ||
3129 val.indexOf(
'\n') >= 0) &&
3132 (n+1 >= cursor.startNodeIndex && n-1 <= cursor.endNodeIndex))
3137 newNode = document.createTextNode(val);
3138 el.insertBefore(newNode,node);
3139 el.removeChild(node);
3148 else if(node.nodeName ==
"DIV" ||
3149 node.nodeName ==
"BR")
3153 eatVal = node.innerHTML;
3157 if(node.nodeName ==
"DIV")
3161 specialString = el.childNodes[n-1].textContent;
3162 if(specialString[specialString.length-1] ==
'\n')
3166 if(eatVal.indexOf(
"<br>") == 0 ||
3178 newNode = document.createTextNode(val);
3179 el.insertBefore(newNode,node);
3180 el.removeChild(node);
3183 if(n == cursor.startNodeIndex)
3184 cursor.startPos += i;
3185 if(n == cursor.endNodeIndex)
3192 else if(node.nodeName ==
"#text")
3195 el.childNodes[n-1].nodeName ==
"#text")
3203 if(n + 1 < el.childNodes.length &&
3204 el.childNodes[n+1].nodeName ==
"#text")
3211 if(cursor.startNodeIndex !== undefined)
3213 if(n+1 < cursor.startNodeIndex)
3216 cursor.startNodeIndex -= 1;
3217 cursor.endNodeIndex -= 1;
3224 if(n+1 == cursor.startNodeIndex)
3227 --cursor.startNodeIndex;
3228 cursor.startPos += val.length;
3232 if(n+1 == cursor.endNodeIndex)
3235 --cursor.endNodeIndex;
3236 cursor.endPos += val.length;
3238 else if(n+1 < cursor.endNodeIndex)
3241 --cursor.endNodeIndex;
3247 newNode = el.childNodes[n+1];
3248 val += newNode.textContent;
3249 newNode.textContent = val;
3250 el.removeChild(node);
3258 for(i=0;i<val.length;++i)
3265 if(startOfComment == -1 && (
3266 startOfString != -1 ||
3267 (prevChar !=
'\\' && val[i] ==
'"') ||
3268 (prevChar !=
'\\' && val[i] ==
"'")
3271 if(startOfString == -1 &&
3272 (val[i] ==
'"' || val[i] ==
"'"))
3275 stringQuoteChar = val[i];
3277 firstSpecialStringStartHandling =
true;
3278 firstSpecialStringEndHandling =
true;
3280 else if(prevChar !=
'\\' && val[i] == stringQuoteChar)
3283 specialString = val.substr(startOfString,i-startOfString);
3286 decor = _DECORATION_BLUE;
3287 fontWeight =
"normal";
3288 localInsertLabel(startOfString,
true );
3294 else if(startOfString == -1 && (
3295 startOfComment != -1 ||
3296 (i+commentString.length-1 < val.length &&
3297 val.substr(i,commentString.length) ==
3300 if(startOfComment == -1 && val[i] == commentString[0])
3303 firstSpecialStringStartHandling =
true;
3304 firstSpecialStringEndHandling =
true;
3306 else if(val[i] ==
'\n')
3309 specialString = val.substr(startOfComment,i-startOfComment);
3312 decor = _DECORATION_GRAY;
3313 fontWeight =
"normal";
3314 localInsertLabel(startOfComment);
3315 startOfComment = -1;
3321 (val[i] >=
'a' && val[i] <=
'z') ||
3322 (val[i] >=
'A' && val[i] <=
'Z') ||
3323 (val[i] >=
'0' && val[i] <=
'9') ||
3324 (val[i] ==
'_' || val[i] ==
'-') ||
3327 if(startOfWord == -1)
3331 else if(startOfWord != -1)
3333 specialString = val.substr(startOfWord,i-startOfWord);
3334 decor = _DECORATIONS[fileDecorType][specialString];
3340 fontWeight =
"bold";
3341 localInsertLabel(startOfWord);
3351 if(prevChar ==
'\\' && val[i] ==
'\\')
3354 if(escapeCount%2 == 0)
3372 if(startOfString != -1 || startOfComment != -1)
3374 console.log(
"In string/comment crossing Nodes!");
3377 closedString =
false;
3378 for(++n;n<el.childNodes.length;++n)
3380 eatNode = el.childNodes[n];
3381 eatVal = eatNode.textContent;
3385 if(cursor.startNodeIndex !== undefined)
3387 if(firstSpecialStringStartHandling)
3388 firstSpecialStringStartHandling =
false;
3390 if(firstSpecialStringEndHandling)
3394 endPositionCache = cursor.endPos;
3395 firstSpecialStringEndHandling =
false;
3398 if(n < cursor.startNodeIndex)
3401 cursor.startNodeIndex -= 1;
3402 cursor.endNodeIndex -= 1;
3409 if(n == cursor.startNodeIndex)
3412 --cursor.startNodeIndex;
3413 cursor.startPos += val.length;
3417 if(n == cursor.endNodeIndex)
3420 --cursor.endNodeIndex;
3421 cursor.endPos += val.length;
3423 else if(n < cursor.endNodeIndex)
3426 --cursor.endNodeIndex;
3502 el.removeChild(eatNode);
3507 for(i;i<val.length;++i)
3510 if(startOfString != -1 &&
3511 (prevChar !=
'\\' && val[i] ==
'"'))
3513 Debug.log(
"Closing node crossed string.");
3516 specialString = val.substr(startOfString,i-startOfString);
3519 decor = _DECORATION_BLUE;
3520 fontWeight =
"normal";
3521 localInsertLabel(startOfString,
true );
3523 closedString =
true;
3528 if(startOfComment != -1 && val[i] ==
'\n')
3530 Debug.log(
"Closing node crossed comment.");
3534 specialString = val.substr(startOfComment,i-startOfComment);
3537 decor = _DECORATION_GRAY;
3538 fontWeight =
"normal";
3539 localInsertLabel(startOfComment);
3540 startOfComment = -1;
3542 closedString =
true;
3548 if(prevChar ==
'\\' && val[i] ==
'\\')
3551 if(escapeCount%2 == 0)
3564 if(closedString)
break;
3568 if(!closedString && startOfString != -1)
3570 Debug.log(
"String is never closed!");
3571 specialString = val.substr(startOfString,i-startOfString);
3574 decor = _DECORATION_BLUE;
3576 localInsertLabel(startOfString,
true );
3579 if(!closedString && startOfComment != -1)
3581 Debug.log(
"Comment is never closed!");
3582 specialString = val.substr(startOfComment,i-startOfComment);
3585 decor = _DECORATION_GRAY;
3587 localInsertLabel(startOfComment);
3588 startOfComment = -1;
3591 if(n < cursor.endNodeIndex)
3595 firstSpecialStringEndHandling =
true;
3596 cursor.endPos = endPositionCache;
3605 console.log(
"unknown node.nodeName",node.nodeName);
3606 throw(
"node error!");
3611 CodeEditor.editor.setCursor(el,cursor);
3613 CodeEditor.editor.updateDualView(forPrimary);
3619 this.autoIndent =
function(forPrimary, cursor)
3621 if(!cursor || cursor.startNodeIndex === undefined)
3623 Debug.log(
"Invalid text selection for auto-indent. Please select text in the text editor.",
3624 Debug.HIGH_PRIORITY);
3627 forPrimary = forPrimary?1:0;
3629 Debug.log(
"autoIndent " + forPrimary);
3631 DesktopContent.showLoading(localDoIt);
3640 function localDoIt()
3650 var el = _eel[forPrimary];
3656 for(n=cursor.startNodeIndex;n>=0; --n)
3658 node = el.childNodes[n];
3659 val = node.textContent;
3661 for(i=(n==cursor.startNodeIndex?cursor.startPos-1:
3662 val.length-1); i>=0; --i)
3675 console.log(
"at leading newline - n",n,
"i",i);
3681 cursor.startNodeIndex = n;
3682 cursor.startPos = i;
3690 for(n=0; n<el.childNodes.length; ++n)
3692 val = el.childNodes[n].textContent;
3693 if(n < cursor.startNodeIndex)
3695 else if(n == cursor.startNodeIndex)
3697 preText += val.substr(0,cursor.startPos);
3699 if(n < cursor.endNodeIndex)
3700 text += val.substr(cursor.startPos);
3703 text += val.substr(cursor.startPos,
3704 cursor.endPos-cursor.startPos);
3705 postText += val.substr(cursor.endPos);
3708 else if(n < cursor.endNodeIndex)
3710 else if(n == cursor.endNodeIndex)
3712 text += val.substr(0,cursor.endPos);
3713 postText += val.substr(cursor.endPos);
3723 var fileExtension = _fileExtension[forPrimary];
3734 for(i=0;i<text.length;++i)
3737 else if(text[i] ==
'\t')
3738 x += _TAB_SIZE - (x+_TAB_SIZE)%_TAB_SIZE;
3741 Debug.log(
"Whitespace size =" + x +
" tabs=" + ((x/_TAB_SIZE)|0));
3745 for(n=0;n<((x/_TAB_SIZE)|0);++n)
3754 var lastChar,firstChar;
3755 var prevLastChar,prevFirstChar;
3757 var inCmdTabStr =
"";
3758 var nextInCmdTabStr =
"";
3759 var isCmdTabStr =
"";
3760 var nextIsCmdTabStr =
"";
3765 var firstColonCommand =
false;
3766 var lastColonCommand =
false;
3767 var foundDoubleQuote,foundSingleQuote;
3768 var tradeInCmdStack = [];
3769 var tradeIsCmdStack = [];
3779 foundComment =
false;
3780 foundDoubleQuote =
false;
3781 foundSingleQuote =
false;
3783 for(n=i+1;n<text.length;++n)
3791 if(!foundSingleQuote && text[n] ==
'"')
3792 foundDoubleQuote = !foundDoubleQuote;
3793 else if(!foundDoubleQuote && text[n] ==
"'")
3794 foundSingleQuote = !foundSingleQuote;
3795 else if(text[n] ==
'/' && n+1 < text.length &&
3798 foundComment =
true;
3802 if(foundDoubleQuote || foundSingleQuote)
3805 if(text[n] !=
' ' && text[n] !=
'\t')
3809 firstChar = text[n];
3814 inCmdTabStr +=
'\t';
3815 else if(text[n] ==
')')
3816 inCmdTabStr = inCmdTabStr.substr(0, inCmdTabStr.length-1);
3817 else if(inCmdTabStr.length == 0 &&
3822 firstColonCommand =
false;
3823 lastColonCommand =
false;
3828 nextTabStr = tabStr;
3831 if(firstChar ==
'}')
3833 nextIsCmdTabStr =
"";
3836 if(tradeInCmdStack.length &&
3837 tradeInCmdStack[tradeInCmdStack.length-1][0] ==
3841 inCmdTabStr = tradeInCmdStack.pop()[1];
3842 nextInCmdTabStr = inCmdTabStr;
3843 isCmdTabStr = tradeIsCmdStack.pop();
3844 tabStr = tabStr.substr(0,tabStr.length-1);
3849 firstColonCommand =
false;
3851 tabStr = tabStr.substr(0,tabStr.length-1);
3852 nextTabStr = tabStr;
3854 else if(lastChar ==
':' &&
3855 (firstChar ==
'p' ||
3859 nextIsCmdTabStr =
"";
3863 firstColonCommand =
false;
3864 lastColonCommand =
false;
3865 nextTabStr = tabStr.substr(0,tabStr.length-1);
3867 else if(firstChar ==
':')
3870 nextIsCmdTabStr =
"";
3872 firstColonCommand =
true;
3874 else if(firstChar ==
'#' ||
3878 if(lastColonCommand)
3879 tabStr = tabStr.substr(0,tabStr.length-1);
3883 if(nextInCmdTabStr.length != 0 ||
3884 nextIsCmdTabStr.length != 1 ||
3885 prevLastChar !=
',')
3888 nextIsCmdTabStr =
"";
3892 else if(!firstColonCommand &&
3893 !lastColonCommand &&
3899 else if(lastColonCommand &&
3900 prevLastChar ==
',' &&
3901 inCmdTabStr.length == 0)
3904 lastColonCommand =
false;
3905 tabStr = tabStr.substr(0,tabStr.length-1);
3907 nextIsCmdTabStr =
"\t";
3910 firstColonCommand =
false;
3917 firstColonCommand =
false;
3918 lastColonCommand =
false;
3922 "firstChar = " + firstChar +
3923 "lastChar = " + lastChar +
3924 "prevFirstChar = " + prevFirstChar +
3925 "prevLastChar = " + prevLastChar +
3929 inCmdTabStr.length +
3931 isCmdTabStr.length +
3935 nextInCmdTabStr.length +
3937 nextIsCmdTabStr.length +
3939 tradeInCmdStack.length +
3940 " " + firstColonCommand +
3941 " " + lastColonCommand);
3945 newText += nextTabStr + nextInCmdTabStr + nextIsCmdTabStr;
3947 newText += text.substr(i+1,n-(i+1)).trimLeft();
3956 if(inCmdTabStr.length)
3960 tradeInCmdStack.push([tabStr.length,inCmdTabStr]);
3961 tradeIsCmdStack.push(isCmdTabStr);
3977 nextInCmdTabStr = inCmdTabStr;
3978 nextIsCmdTabStr = isCmdTabStr;
3981 prevLastChar = lastChar;
3983 prevFirstChar = firstChar;
3987 }
while(i+1<text.length);
3991 if(text[i] ==
'\n') newText +=
'\n';
3997 Debug.log(
"Unknown operation to auto-indent file with extension " +
3998 fileExtension,Debug.HIGH_PRIORITY);
4003 el.textContent = preText + newText + postText;
4005 _fileWasModified[forPrimary] =
true;
4007 CodeEditor.editor.updateDecorations(forPrimary,
4016 this.updateDualView =
function(forPrimary)
4018 forPrimary = forPrimary?1:0;
4020 Debug.log(
"updateDualView " + forPrimary);
4024 if(_filePath[0] == _filePath[1] &&
4025 _fileExtension[0] == _fileExtension[1])
4027 var val,node, newNode;
4028 var el = _eel[forPrimary];
4030 Debug.log(
"Update dual view");
4032 _fileLastSave[(!forPrimary)?1:0] = _fileLastSave[forPrimary];
4033 _fileWasModified[(!forPrimary)?1:0] = _fileWasModified[forPrimary];
4034 CodeEditor.editor.updateLastSave(!forPrimary);
4038 var elAlt = _eel[(!forPrimary)?1:0];
4039 elAlt.innerHTML =
"";
4040 for(i=0;i<el.childNodes.length;++i)
4042 node = el.childNodes[i];
4043 val = node.textContent;
4044 if(node.nodeName ==
"LABEL")
4046 newNode = document.createElement(
"label");
4047 newNode.style.fontWeight = node.style.fontWeight;
4048 newNode.style.color = node.style.color;
4049 newNode.textContent = val;
4051 else if(node.nodeName ==
"#text")
4053 newNode = document.createTextNode(val);
4056 Debug.log(
"Skipping unknown node " + node.nodeName);
4057 elAlt.appendChild(newNode);
4066 this.updateOutline =
function(forPrimary,elTextObj)
4068 forPrimary = forPrimary?1:0;
4070 Debug.log(
"updateOutline " + forPrimary);
4076 var endPi, startCi, lastWhiteSpacei;
4078 var localNewLineCount;
4080 var newLineCount = 0;
4082 outline.push([1,
"Top"]);
4086 var isCcSource = _fileExtension[forPrimary][0] ==
'c' ||
4087 _fileExtension[forPrimary][0] ==
'C' ||
4088 _fileExtension[forPrimary] ==
"icc";
4089 var isJsSource = _fileExtension[forPrimary] ==
"js" ||
4090 _fileExtension[forPrimary] ==
"html";
4092 var indicatorIndex = 0;
4094 if(isCcSource) indicator =
"::";
4095 if(isJsSource) indicator =
"function";
4097 var inComment =
false;
4098 var inBlockComment =
false;
4100 for(i=0;i<elTextObj.text.length;++i)
4102 if(elTextObj.text[i] ==
'\n')
4109 else if(inBlockComment && i+1 < elTextObj.text.length &&
4110 elTextObj.text[i] ==
'*' &&
4111 elTextObj.text[i+1] ==
'/')
4112 inBlockComment =
false;
4113 else if(inComment || inBlockComment)
continue;
4114 else if(i+1 < elTextObj.text.length)
4116 if(elTextObj.text[i] ==
'/' &&
4117 elTextObj.text[i+1] ==
'*')
4119 inBlockComment =
true;
4122 else if(elTextObj.text[i] ==
'/' &&
4123 elTextObj.text[i+1] ==
'/')
4131 if(elTextObj.text[i] == indicator[indicatorIndex])
4134 if(indicatorIndex == indicator.length)
4141 str = localHandleCcOutline();
4143 str = localHandleJsOutline();
4148 outline.push([newLineCount+1,
4155 inBlockComment =
false;
4166 Debug.log(
"Number of lines " + newLineCount);
4167 console.log(
"Done with outline", outline);
4171 for(i=0;i<newLineCount;++i)
4173 str +=
"<a name='" + forPrimary +
"L" + (i+1) +
"'></a>";
4177 document.getElementById(
"editableBoxLeftMargin" + forPrimary).innerHTML = str;
4179 _numberOfLines[forPrimary] = newLineCount;
4182 if(!isCcSource && !isJsSource)
4185 i = (newLineCount/2)|0;
4188 outline.push([i,
"Middle"]);
4191 outline.push([newLineCount,
"Bottom"]);
4197 str +=
"<table><td>"
4200 str += htmlOpen(
"select",
4202 "class":
"textEditorOutlineSelect",
4203 "id":
"textEditorOutlineSelect" + forPrimary,
4204 "style":
"text-align-last: center; width: 100%;",
4205 "title":
"Jump to a section of code.",
4207 "CodeEditor.editor.handleOutlineSelect(" + forPrimary +
");",
4209 "CodeEditor.editor.stopUpdateHandling(event);",
4211 str +=
"<option value='0'>Jump to a Line Number (Ctrl + L)</option>";
4214 for(i=0;i<outline.length;++i)
4216 str +=
"<option value='" + (outline[i][0]-2) +
"'>";
4217 text =
"#" + outline[i][0];
4221 found = (outline[i][1].indexOf(
"local") == 0);
4223 for(j=text.length;j<(found?20:12);++j)
4225 str += outline[i][1];
4229 str +=
"</td></table>";
4233 document.getElementById(
"textEditorOutline" + forPrimary).innerHTML = str;
4237 Debug.log(
"Ignoring missing outline element. Assuming header not shown.");
4243 function localHandleCcOutline()
4245 if(startCi && i < startCi)
4253 lastWhiteSpacei = -1;
4260 for(j=i+2;j<elTextObj.text.length;++j)
4262 if(inComment && elTextObj.text[j] ==
'\n')
4264 else if(inBlockComment && j+1 < elTextObj.text.length &&
4265 elTextObj.text[j] ==
'*' &&
4266 elTextObj.text[j+1] ==
'/')
4267 inBlockComment =
false;
4268 else if(inComment || inBlockComment)
continue;
4269 else if(j+1 < elTextObj.text.length)
4271 if(elTextObj.text[j] ==
'/' &&
4272 elTextObj.text[j+1] ==
'*')
4274 inBlockComment =
true;
4277 else if(elTextObj.text[j] ==
'/' &&
4278 elTextObj.text[j+1] ==
'/')
4285 if(elTextObj.text[j] ==
';' ||
4286 elTextObj.text[j] ==
'+' ||
4287 elTextObj.text[j] ==
'"' ||
4288 elTextObj.text[j] ==
"'" ||
4289 elTextObj.text[j] ==
"!" ||
4290 elTextObj.text[j] ==
"|")
4297 if(elTextObj.text[j] ==
'(')
4301 if(elTextObj.text[j] ==
')')
4305 if(elTextObj.text[j] ==
' ' ||
4306 elTextObj.text[j] ==
'\t' ||
4307 elTextObj.text[j] ==
'\n')
4308 lastWhiteSpacei = j;
4309 else if(lastWhiteSpacei != -1 &&
4310 elTextObj.text[j] ==
':')
4319 else if(startCi < 0)
4321 if(elTextObj.text[j] ==
'{')
4331 if(endi < 0 || startCi < 0)
4340 if(elTextObj.text[j] ==
')')
4354 return elTextObj.text.substr(starti+2,endi-starti-2).replace(/\s+/g,
'');
4360 function localHandleJsOutline()
4362 if(elTextObj.text[i + 1] ==
'(')
4369 for(j=i-1-(
"function").length;j>=0;--j)
4371 if(elTextObj.text[j] ==
'=')
4377 else if(!(elTextObj.text[j] ==
' ' || elTextObj.text[j] ==
'\t' ||
4378 (elTextObj.text[j] ==
'=' && !found)))
4387 if(elTextObj.text[j] ==
' ' || elTextObj.text[j] ==
'\t' ||
4388 elTextObj.text[j] ==
'\n')
4391 return elTextObj.text.substr(j+1,k-j-1).trim();
4401 for(j=i+2;j<elTextObj.text.length;++j)
4403 if(elTextObj.text[j] ==
'\n')
4405 else if(elTextObj.text[j] ==
'(')
4408 return elTextObj.text.substr(i+2,j-(i+2)).trim();
4420 this.handleOutlineSelect =
function(forPrimary)
4422 forPrimary = forPrimary?1:0;
4424 Debug.log(
"handleOutlineSelect() " + forPrimary);
4426 var val = document.getElementById(
"textEditorOutlineSelect" + forPrimary).value | 0;
4427 if(val < 1) val = 1;
4428 console.log(
"line val",val);
4430 CodeEditor.editor.gotoLine(forPrimary,val,
4440 this.keyDownHandler =
function(e,forPrimary,shortcutsOnly)
4442 forPrimary = forPrimary?1:0;
4444 var keyCode = e.keyCode;
4446 CodeEditor.editor.stopUpdateHandling();
4457 Debug.log(
"keydown c=" + keyCode +
" " + c +
" shift=" + e.shiftKey +
4458 " ctrl=" + e.ctrlKey +
" command=" + _commandKeyDown);
4461 CodeEditor.editor.startUpdateHandling(forPrimary);
4463 var el = _eel[forPrimary];
4465 var cursorSelection =
false;
4471 cursor = CodeEditor.editor.getCursor(el);
4473 cursorSelection = (cursor.startNodeIndex !== undefined &&
4474 (cursor.startNodeIndex != cursor.endNodeIndex ||
4475 cursor.startPos != cursor.endPos));
4477 if(!cursorSelection)
4478 _lastPageUpDownLine = -1;
4481 function localInsertCharacter(c)
4483 Debug.log(
"Inserting character... " + c);
4496 if(cursor.endNodeIndex > cursor.startNodeIndex)
4499 val = el.childNodes[cursor.endNodeIndex].textContent;
4500 val = val.substr(cursor.endPos);
4501 el.childNodes[cursor.endNodeIndex].textContent = val;
4502 --cursor.endNodeIndex;
4503 while(cursor.endNodeIndex > cursor.startNodeIndex)
4506 el.removeChild(el.childNodes[cursor.endNodeIndex]);
4507 --cursor.endNodeIndex;
4510 cursor.endPos = el.childNodes[cursor.startNodeIndex].textContent.length;
4513 var whiteSpaceString =
"";
4514 var postWhiteSpaceString =
"";
4515 var text = el.childNodes[cursor.startNodeIndex].textContent;
4516 var preCharString = text.substr(0,cursor.startPos);
4517 var cursorPosDelta = 0;
4528 for(n=cursor.startNodeIndex;n>=0; --n)
4530 node = el.childNodes[n];
4531 val = node.textContent;
4533 for(i=(n==cursor.startNodeIndex?cursor.startPos-1:
4534 val.length-1); i>=0; --i)
4542 else if(firstChar ==
'' &&
4543 val[i] !=
'\t' && val[i] !=
' ')
4550 console.log(
"at leading newline - n",n,
"i",i,
"firstChar",firstChar);
4557 for(n; n<el.childNodes.length; ++n)
4559 node = el.childNodes[n];
4560 val = node.textContent;
4562 for(i;i<val.length;++i)
4565 if((val[i] !=
'\t' && val[i] !=
' ') ||
4566 (n == cursor.startNodeIndex &&
4567 i >= cursor.startPos))
4573 whiteSpaceString += val[i];
4576 if(found || n == cursor.startNodeIndex)
break;
4581 if(firstChar ==
'{')
4583 postWhiteSpaceString +=
"\n" + whiteSpaceString +
"}";
4584 whiteSpaceString +=
'\t';
4585 postWhiteSpaceString += text.substr(cursor.endPos);
4589 val = text.substr(cursor.endPos);
4590 i = val.indexOf(
'\n');
4594 postWhiteSpaceString += val.substr(0,
4596 postWhiteSpaceString += val.substr(i);
4599 postWhiteSpaceString += val.trimLeft();
4610 var foundFirstNewLine =
false;
4614 for(n=cursor.startNodeIndex;n>=0; --n)
4616 node = el.childNodes[n];
4617 val = node.textContent;
4619 for(i=(n==cursor.startNodeIndex?cursor.startPos-1:
4620 val.length-1); i>=0; --i)
4629 Debug.log(
"Found matching bracket n=" + n +
4636 else if(val[i] ==
'}')
4638 else if(!foundFirstNewLine &&
4641 foundFirstNewLine =
true;
4643 Debug.log(
"pre-deleted white space preCharString=" +
4644 preCharString.length +
" " + preCharString);
4649 for(nn;nn<el.childNodes.length;++nn)
4651 if(nn < cursor.startNodeIndex)
4654 el.childNodes[nn].textContent =
"";
4656 else if(nn == cursor.startNodeIndex)
4659 preCharString = el.childNodes[nn].textContent.substr(
4666 Debug.log(
"deleted white space preCharString=" +
4667 preCharString.length +
" " + preCharString);
4669 else if(!foundFirstNewLine && val[i] !=
' ' &&
4672 Debug.log(
"Found character between } and new line, so doing nothing.");
4681 console.log(
"at closing bracket - n",n,
"i",i);
4684 preCharString = preCharString.trimRight();
4688 var matchingWhiteSpace =
"";
4690 var firstTime =
true;
4694 node = el.childNodes[n];
4695 val = node.textContent;
4698 val.length-1); i>=0; --i)
4706 else if(val[i] ==
' ' ||
4708 matchingWhiteSpace += val[i];
4710 matchingWhiteSpace =
"";
4719 preCharString += matchingWhiteSpace;
4720 Debug.log(
"matching white space preCharString=" +
4721 preCharString.length +
" " + preCharString);
4723 postWhiteSpaceString += text.substr(cursor.endPos);
4727 postWhiteSpaceString += text.substr(cursor.endPos);
4729 val = preCharString + c +
4731 postWhiteSpaceString;
4733 el.childNodes[cursor.startNodeIndex].textContent = val;
4736 console.log(
"cursorPosDelta",cursorPosDelta);
4738 cursor.startPos = c.length + preCharString.length + whiteSpaceString.length;
4739 cursor.endNodeIndex = cursor.startNodeIndex;
4740 cursor.endPos = cursor.startPos;
4742 console.log(
"cursor after newline",cursor);
4744 CodeEditor.editor.setCursor(el,cursor,
true );
4746 _fileWasModified[forPrimary] =
true;
4761 localInsertCharacter(
'\n');
4767 else if(keyCode == 36)
4781 var lastNonWhitespacePos = cursor.startPos;
4782 var lastNonWhitespaceNodeIndex = cursor.startNodeIndex;
4783 var lastPos = cursor.startPos;
4784 var lastNodeIndex = cursor.startNodeIndex;
4787 for(n=cursor.startNodeIndex; n>=0; --n)
4789 node = el.childNodes[n];
4790 val = node.textContent;
4792 for(i=(n==cursor.startNodeIndex?
4793 cursor.startPos-1:val.length-1);i>=0;--i)
4800 else if(!(val[i] ==
' ' ||
4803 lastNonWhitespacePos = i;
4804 lastNonWhitespaceNodeIndex = n;
4812 console.log(
"lastNonWhitespacePos",lastNonWhitespacePos);
4813 console.log(
"lastNonWhitespaceNodeIndex",lastNonWhitespaceNodeIndex);
4815 if(lastNonWhitespacePos == cursor.startPos &&
4816 lastNonWhitespaceNodeIndex == cursor.startNodeIndex)
4819 lastNonWhitespacePos = lastPos;
4820 lastNonWhitespaceNodeIndex = lastNodeIndex;
4824 if(lastNonWhitespacePos == lastPos &&
4825 lastNonWhitespaceNodeIndex == lastNodeIndex)
4826 document.getElementById(
"textEditorBody" + forPrimary).scrollLeft = 0;
4828 cursor.startNodeIndex = lastNonWhitespaceNodeIndex
4829 cursor.startPos = lastNonWhitespacePos;
4833 cursor.endNodeIndex = cursor.startNodeIndex;
4834 cursor.endPos = cursor.startPos;
4838 CodeEditor.editor.setCursor(el,cursor,
true );
4842 else if(keyCode == 35)
4858 var wantNext =
false;
4859 var lastNonWhitespacePos = cursor.startPos;
4860 var lastNonWhitespaceNodeIndex = cursor.startNodeIndex;
4863 for(n=cursor.startNodeIndex; n<el.childNodes.length; ++n)
4865 node = el.childNodes[n];
4866 val = node.textContent;
4868 for(i=(n==cursor.startNodeIndex?
4869 cursor.startPos:0);i<val.length;++i)
4873 lastNonWhitespacePos = i;
4874 lastNonWhitespaceNodeIndex = n;
4882 else if(!(val[i] ==
' ' ||
4890 console.log(
"lastNonWhitespacePos",lastNonWhitespacePos);
4891 console.log(
"lastNonWhitespaceNodeIndex",lastNonWhitespaceNodeIndex);
4893 if(lastNonWhitespacePos == cursor.startPos &&
4894 lastNonWhitespaceNodeIndex == cursor.startNodeIndex)
4897 lastNonWhitespacePos = i;
4898 lastNonWhitespaceNodeIndex = n;
4901 cursor.endNodeIndex = lastNonWhitespaceNodeIndex
4902 cursor.endPos = lastNonWhitespacePos;
4906 cursor.startNodeIndex = cursor.endNodeIndex;
4907 cursor.startPos = cursor.endPos;
4911 CodeEditor.editor.setCursor(el,cursor,
true );
4922 e.stopPropagation();
4931 var gotoLineCursor = {};
4934 if(_lastPageUpDownLine == -1)
4936 var cursorWithLine = CodeEditor.editor.getLine(forPrimary);
4938 _startPageUpDownNodeIndex = cursorWithLine.startNodeIndex;
4939 _startPageUpDownPos = cursorWithLine.startPos;
4941 _startPageUpDownLine = cursorWithLine.line;
4942 _lastPageUpDownLine = _startPageUpDownLine;
4945 gotoLineCursor.startNodeIndex = _startPageUpDownNodeIndex;
4946 gotoLineCursor.startPos = _startPageUpDownPos;
4949 _lastPageUpDownLine -= N;
4950 gotoLineCursor.focusAtEnd = (_lastPageUpDownLine > _startPageUpDownLine);
4952 Debug.log(
"Page up to line " + _lastPageUpDownLine +
" dir=" +
4953 gotoLineCursor.focusAtEnd);
4955 _lastPageUpDownLine = CodeEditor.editor.gotoLine(forPrimary,_lastPageUpDownLine,
4956 e.shiftKey?gotoLineCursor:undefined);
4960 else if(keyCode == 34)
4964 e.stopPropagation();
4973 var gotoLineCursor = {};
4976 if(_lastPageUpDownLine == -1)
4978 var cursorWithLine = CodeEditor.editor.getLine(forPrimary);
4980 _startPageUpDownNodeIndex = cursorWithLine.startNodeIndex;
4981 _startPageUpDownPos = cursorWithLine.startPos;
4983 _startPageUpDownLine = cursorWithLine.line;
4984 _lastPageUpDownLine = _startPageUpDownLine;
4987 gotoLineCursor.startNodeIndex = _startPageUpDownNodeIndex;
4988 gotoLineCursor.startPos = _startPageUpDownPos;
4991 _lastPageUpDownLine += N;
4992 gotoLineCursor.focusAtEnd = (_lastPageUpDownLine > _startPageUpDownLine);
4994 Debug.log(
"Page down to line " + _lastPageUpDownLine +
" dir=" +
4995 gotoLineCursor.focusAtEnd);
4997 _lastPageUpDownLine = CodeEditor.editor.gotoLine(forPrimary,_lastPageUpDownLine,
4998 e.shiftKey?gotoLineCursor:undefined);
5002 else if(keyCode == 13)
5008 if(CodeEditor.editor.findAndReplaceLastButton[forPrimary] > 0)
5011 e.stopPropagation();
5013 Debug.log(
"Launch find and replace action " +
5014 CodeEditor.editor.findAndReplaceLastButton[forPrimary]);
5015 CodeEditor.editor.doFindAndReplaceAction(forPrimary,
5016 CodeEditor.editor.findAndReplaceLastButton[forPrimary]);
5020 else if(keyCode == 27)
5026 if(CodeEditor.editor.findAndReplaceLastButton[forPrimary] > 0)
5029 e.stopPropagation();
5032 CodeEditor.editor.displayFileHeader(forPrimary);
5044 if (!_STAND_ALONE && !_READ_ONLY) {
5045 CodeEditor.editor.saveFile(forPrimary,
true );
5050 else if(keyCode == 68)
5052 if (!_STAND_ALONE) {
5053 CodeEditor.editor.toggleDirectoryNav(forPrimary);
5058 else if(keyCode == 66)
5060 if (!_STAND_ALONE && !_READ_ONLY) {
5061 CodeEditor.editor.build();
5066 else if(keyCode == 70)
5068 CodeEditor.editor.showFindAndReplace(forPrimary);
5072 else if(keyCode == 73)
5074 CodeEditor.editor.autoIndent(forPrimary, cursor);
5078 else if(keyCode == 78)
5080 if (!_STAND_ALONE && !_READ_ONLY) {
5081 CodeEditor.editor.build(
true );
5086 else if(keyCode == 222 ||
5089 CodeEditor.editor.openFile(forPrimary,
5090 _filePath[forPrimary],
5091 _fileExtension[forPrimary],
5096 else if(keyCode == 50)
5098 CodeEditor.editor.toggleView();
5102 else if(keyCode == 85)
5104 CodeEditor.editor.undo(forPrimary, e.shiftKey );
5108 else if(keyCode == 76 ||
5111 DesktopContent.popUpVerification(
5112 "Goto line number: ",
5116 Debug.log(
"Going to line... " + line);
5117 CodeEditor.editor.gotoLine(forPrimary,line);
5130 else if(keyCode == 186 ||
5133 CodeEditor.editor.openRelatedFile(forPrimary);
5144 var rectangularTAB =
false;
5145 var blockCOMMENT =
false;
5156 rectangularTAB =
true;
5160 else if(keyCode == 191)
5162 blockCOMMENT =
true;
5173 if(keyCode == TABKEY ||
5174 (cursorSelection && keyCode == SPACEKEY) ||
5178 _fileWasModified[forPrimary] =
true;
5179 CodeEditor.editor.updateLastSave(forPrimary);
5191 Debug.log(
"special key selected lines " + cursor.startNodeIndex +
" - " +
5192 cursor.endNodeIndex);
5199 Debug.log(
"Rectangular TAB");
5214 for(n=cursor.startNodeIndex;n>=0; --n)
5216 node = el.childNodes[n];
5217 val = node.textContent;
5219 for(i=(n==cursor.startNodeIndex?cursor.startPos-1:
5220 val.length-1); i>=0; --i)
5232 console.log(
"at leading newline - n",n,
"i",i);
5236 for(n; n<el.childNodes.length; ++n)
5238 node = el.childNodes[n];
5239 val = node.textContent;
5241 for(i;i<val.length;++i)
5244 if(n == cursor.startNodeIndex &&
5245 i == cursor.startPos)
5250 var prelength = val.length;
5254 if(i-1 >= 0 && val[i-1] ==
'\t')
5255 node.textContent = val.substr(0,i-1) + val.substr(i);
5259 node.textContent = val.substr(0,i) +
"\t" + val.substr(i);
5265 cursor.startPos += node.textContent.length - prelength;
5271 x += _TAB_SIZE - (x+_TAB_SIZE)%_TAB_SIZE;
5287 for(n=cursor.startNodeIndex; n<el.childNodes.length; ++n)
5289 node = el.childNodes[n];
5290 val = node.textContent;
5292 for(i=(n==cursor.startNodeIndex?cursor.startPos:
5295 (n==cursor.endNodeIndex?cursor.endPos:
5312 if(i-1 < val.length && val[i-1] ==
'\t')
5314 val = val.substr(0,i-1) + val.substr(i);
5315 node.textContent = val;
5316 if(n == cursor.endNodeIndex) --cursor.endPos;
5321 val = val.substr(0,i) +
"\t" + val.substr(i);
5322 node.textContent = val;
5323 if(n == cursor.endNodeIndex) ++cursor.endPos;
5330 xcnt += _TAB_SIZE - (xcnt+_TAB_SIZE)%_TAB_SIZE;
5336 if(n == cursor.endNodeIndex)
5343 CodeEditor.editor.setCursor(el,cursor,
true );
5361 var specialStr = keyCode == SPACEKEY?
' ':
'\t';
5364 if(_fileExtension[forPrimary][0] ==
'c' ||
5365 _fileExtension[forPrimary][0] ==
'C' ||
5366 _fileExtension[forPrimary][0] ==
'h' ||
5367 _fileExtension[forPrimary][0] ==
'H' ||
5368 _fileExtension[forPrimary][0] ==
'j')
5374 for(n=cursor.startNodeIndex; n>=0; --n)
5376 node = el.childNodes[n];
5377 val = node.textContent;
5379 for(i=(n==cursor.startNodeIndex?cursor.startPos-1:
5380 val.length-1); i>=0; --i)
5396 var prevCharIsNewLine =
false;
5397 var lookForNewLineIndex;
5399 for(; n<el.childNodes.length &&
5400 n <= cursor.endNodeIndex; ++n)
5402 node = el.childNodes[n];
5403 val = node.textContent;
5405 lookForNewLineIndex = 0;
5406 for(;i<val.length;++i)
5408 if(n == cursor.endNodeIndex && i >= cursor.endPos)
5415 if(val[i] ==
'\n' ||
5416 (i == 0 && prevCharIsNewLine))
5418 if(i == 0 && prevCharIsNewLine) --i;
5422 var didDelete =
false;
5423 if(i + specialStr.length < val.length &&
5427 (j=val.indexOf(specialStr,i+1)) == i+1 ||
5430 (k=val.indexOf(
'\n',i+1)) < 0 ||
5435 val.substr(i+1,j-(i+1)).trim().length == 0
5441 val = val.substr(0,j) +
5442 val.substr(j+specialStr.length);
5443 node.textContent = val;
5445 lookForNewLineIndex = j+specialStr.length;
5447 else if(specialStr ==
'\t')
5450 if((specialStr =
" ") &&
5451 i + specialStr.length < val.length &&
5452 val.indexOf(specialStr,i+1) == i+1)
5454 val = val.substr(0,i+1) +
5455 val.substr(i+1+specialStr.length);
5456 node.textContent = val;
5459 else if((specialStr =
" ") &&
5460 i + specialStr.length < val.length &&
5461 val.indexOf(specialStr,i+1) == i+1)
5463 val = val.substr(0,i+1) +
5464 val.substr(i+1+specialStr.length);
5465 node.textContent = val;
5468 else if((specialStr =
" ") &&
5469 i + specialStr.length < val.length &&
5470 val.indexOf(specialStr,i+1) == i+1)
5472 val = val.substr(0,i+1) +
5473 val.substr(i+1+specialStr.length);
5474 node.textContent = val;
5477 else if((specialStr =
" ") &&
5478 i + specialStr.length < val.length &&
5479 val.indexOf(specialStr,i+1) == i+1)
5481 val = val.substr(0,i+1) +
5482 val.substr(i+1+specialStr.length);
5483 node.textContent = val;
5494 if(n == cursor.startNodeIndex &&
5495 i < cursor.startPos)
5497 cursor.startPos -= specialStr.length;
5499 if(n == cursor.endNodeIndex &&
5502 cursor.endPos -= specialStr.length;
5507 if(n == cursor.endNodeIndex &&
5508 cursor.endPos >= val.length)
5510 ++cursor.endNodeIndex;
5529 if(specialStr ==
' ')
5533 while(ii < val.length &&
5534 (val[ii] ==
' ' || val[ii] ==
'\t' || val[ii] ==
'\n'))
5536 val = val.substr(0,ii) + specialStr + val.substr(ii);
5537 prevCharIsNewLine = (val[ii] ==
'\n');
5541 val = val.substr(0,i+1) + specialStr + val.substr(i+1);
5542 node.textContent = val;
5545 if(i == -1 && prevCharIsNewLine) ++i;
5555 j = val.lastIndexOf(
'\n');
5556 if(j >= lookForNewLineIndex &&
5558 j == val[val.length-1] ||
5559 val.substr(j+1).trim().length == 0
5561 prevCharIsNewLine =
true;
5562 else if(j < 0 && prevCharIsNewLine &&
5563 val.trim().length == 0)
5564 prevCharIsNewLine =
true;
5566 prevCharIsNewLine =
false;
5569 prevCharIsNewLine = (val.length &&
5570 val[val.length-1] ==
'\n');
5574 CodeEditor.editor.setCursor(el,cursor,
true );
5576 else if(!blockCOMMENT)
5580 if(cursor.startNodeIndex !== undefined)
5585 i = cursor.startPos;
5586 node = el.childNodes[cursor.startNodeIndex];
5587 val = node.textContent;
5591 if(val[i-1] ==
'\t')
5593 node.textContent = val.substr(0,i-1) + val.substr(i);
5596 var range = document.createRange();
5597 range.setStart(node,i-1);
5598 range.setEnd(node,i-1);
5600 var selection = window.getSelection();
5601 selection.removeAllRanges();
5602 selection.addRange(range);
5612 Debug.log(
"No cursor for reverse tab.");
5615 document.execCommand(
'insertHTML',
false,
'	');
5621 else if(cursorSelection)
5623 Debug.log(
"cursorSelection handling for speed-up");
5633 console.log(
"cursorSelection char",keyCode,c);
5635 if(e.key.length > 1)
5637 if( keyCode != 46 &&
5644 e.stopPropagation();
5645 localInsertCharacter(c);
5651 if(localInsertCharacter(c))
5655 e.stopPropagation();
5665 this.updateLastSave =
function(forPrimary)
5667 forPrimary = forPrimary?1:0;
5669 var el = document.getElementById(
"textEditorLastSave" + forPrimary);
5672 Debug.log(
"updateLastSave() forPrimary=" + forPrimary);
5674 if(_fileWasModified[forPrimary])
5675 str +=
"<label style='color:red'>Unsaved changes!</label> ";
5677 str +=
"Unmodified. ";
5679 if(_fileLastSave[forPrimary])
5681 var now =
new Date();
5682 var d =
new Date(_fileLastSave[forPrimary]);
5683 var tstr = d.toLocaleTimeString();
5684 tstr = tstr.substring(0,tstr.lastIndexOf(
' ')) +
5685 (tstr[tstr.length-2]==
'A'?
"am":
"pm");
5687 var diff = ((now.getTime() - d.getTime())/1000)|0;
5691 diffStr =
"(just now) ";
5693 diffStr =
"(5 seconds ago) ";
5695 diffStr =
"(15 seconds ago) ";
5697 diffStr =
"(30 seconds ago) ";
5699 diffStr =
"(45 seconds ago) ";
5701 diffStr =
"(one minute ago) ";
5702 else if(diff < 15*60)
5703 diffStr =
"(" + ((diff/60)|0) +
" minutes ago) ";
5704 else if(diff < 20*60)
5705 diffStr =
"(15 minutes ago) ";
5706 else if(diff < 40*60)
5707 diffStr =
"(30 minutes ago) ";
5708 else if(diff < 50*60)
5709 diffStr =
"(45 minutes ago) ";
5710 else if(diff < 90*60)
5711 diffStr =
"(an hour ago) ";
5713 diffStr =
"(" + (Math.round(diff/60/60)) +
" hours ago) ";
5716 str +=
"Last save was " + diffStr + tstr;
5723 this.handleFileNameMouseMove =
function(forPrimary,doNotStartTimer)
5725 forPrimary = forPrimary?1:0;
5729 if(_fileNameEditing[forPrimary])
return;
5731 var el = document.getElementById(
"fileButtonContainerShowHide" + forPrimary);
5732 el.style.display =
"block";
5734 window.clearTimeout(_fileNameMouseMoveTimerHandle);
5736 if(doNotStartTimer)
return;
5738 _fileNameMouseMoveTimerHandle = window.setTimeout(
5741 el.style.display =
"none";
5749 this.startEditFileName =
function(forPrimary)
5751 forPrimary = forPrimary?1:0;
5753 if(_fileNameEditing[forPrimary])
return;
5754 _fileNameEditing[forPrimary] =
true;
5757 document.getElementById(
"fileButtonContainerShowHide" + forPrimary).style.display =
"none";
5760 console.log(
"startEditFileName " + forPrimary);
5762 var el = document.getElementById(
"fileNameDiv" + forPrimary);
5764 var keys = Object.keys(_fileHistoryStack);
5765 var initVal = keys[document.getElementById(
"fileNameHistorySelect" +
5766 forPrimary).value|0].trim();
5768 var _OK_CANCEL_DIALOG_STR =
"";
5770 _OK_CANCEL_DIALOG_STR +=
"<div title='' style='padding:5px;background-color:#eeeeee;border:1px solid #555555;position:relative;z-index:2000;" +
5771 "width:105px;height:20px;margin: 4px -122px -32px -120px; font-size: 16px; white-space:nowrap; text-align:center;'>";
5772 _OK_CANCEL_DIALOG_STR +=
"<a class='popUpOkCancel' onclick='" +
5773 "CodeEditor.editor.editCellOK(" + forPrimary +
5774 "); event.stopPropagation();' onmouseup='event.stopPropagation();' title='Accept Changes' style='color:green'>" +
5775 "<b style='color:green;font-size: 16px;'>OK</b></a> | " +
5776 "<a class='popUpOkCancel' onclick='" +
5777 "CodeEditor.editor.editCellCancel(" + forPrimary +
5778 "); event.stopPropagation();' onmouseup='event.stopPropagation();' title='Discard Changes' style='color:red'>" +
5779 "<b style='color:red;font-size: 16px;'>Cancel</b></a>";
5780 _OK_CANCEL_DIALOG_STR +=
"</div>";
5784 str += htmlOpen(
"input",
5787 "style":
"text-align:center;margin:-4px -2px -4px -1px;width:90%;" +
5788 " height:" + (el.offsetHeight>20?el.offsetHeight:20) +
"px",
5790 "onclick":
"event.stopPropagation();",
5799 str += _OK_CANCEL_DIALOG_STR;
5804 el = el.getElementsByTagName(
"input")[0];
5805 var startPos = initVal.lastIndexOf(
'/')+1;
5806 var endPos = initVal.lastIndexOf(
'.');
5807 if(endPos < 0) endPos = initVal.length;
5808 el.setSelectionRange(startPos, endPos);
5815 this.editCellOK =
function(forPrimary)
5817 forPrimary = forPrimary?1:0;
5819 var val = document.getElementById(
"fileNameDiv" + forPrimary).getElementsByTagName(
"input")[0].value;
5820 console.log(
"editCellOK " + forPrimary +
" = " + val);
5821 _fileNameEditing[forPrimary] =
false;
5823 var extPos = val.lastIndexOf(
'.');
5827 _filePath[forPrimary] = val.substr(0,extPos);
5828 _fileExtension[forPrimary] = extPos > 0?val.substr(extPos+1):
"";
5843 _fileWasModified[forPrimary] =
true;
5844 _fileLastSave[forPrimary] = 0;
5845 CodeEditor.editor.updateLastSave(forPrimary);
5856 _fileHistoryStack[_filePath[forPrimary] +
"." +
5857 _fileExtension[forPrimary]] = [
5858 _eel[forPrimary].textContent,
5860 _fileWasModified[forPrimary],
5861 _fileLastSave[forPrimary]];
5862 console.log(
"_fileHistoryStack",_fileHistoryStack);
5864 CodeEditor.editor.updateFileHistoryDropdowns();
5870 this.editCellCancel =
function(forPrimary)
5872 forPrimary = forPrimary?1:0;
5874 Debug.log(
"editCellCancel " + forPrimary);
5875 _fileNameEditing[forPrimary] =
false;
5878 CodeEditor.editor.updateFileHistoryDropdowns(forPrimary);
5887 this.updateFileHistoryDropdowns =
function(forPrimarySelect)
5889 Debug.log(
"updateFileHistoryDropdowns forPrimarySelect=" + forPrimarySelect);
5896 var keys = Object.keys(_fileHistoryStack);
5899 for(var forPrimary=0;forPrimary<2;++forPrimary)
5901 if(forPrimarySelect !== undefined &&
5902 forPrimarySelect != forPrimary)
continue;
5904 currentFile = _filePath[forPrimary] +
"." + _fileExtension[forPrimary];
5906 str += htmlOpen(
"select",
5908 "class":
"fileNameHistorySelect",
5909 "id":
"fileNameHistorySelect" + forPrimary,
5910 "style":
"width:100%;" +
5911 "text-align-last: center;",
5912 "title":
"The current file is\n" + currentFile,
5914 "CodeEditor.editor.handleFileNameHistorySelect(" +
5916 "onclick":
"CodeEditor.editor.stopUpdateHandling(event);",
5924 for(i=0;i<keys.length;++i)
5928 str +=
"<option value='" + i +
"' ";
5929 if(currentFile == keys[i])
5932 if(_fileHistoryStack[keys[i]][2])
5933 str +=
"*MODIFIED* ";
5942 el = document.getElementById(
"fileNameDiv" + forPrimary);
5947 Debug.log(
"Ignoring error since file forPrimary=" +
5948 forPrimary +
" is probably not opened:[" + DesktopContent.getExceptionLineNumber(e) +
"]: " +
5958 this.handleFileNameHistorySelect =
function(forPrimary)
5960 forPrimary = forPrimary?1:0;
5962 var selectedFileIndex = document.getElementById(
"fileNameHistorySelect" + forPrimary).value | 0;
5963 Debug.log(
"updateFileHistoryDropdowns " + forPrimary +
5964 "selected=" + selectedFileIndex);
5966 var keys = Object.keys(_fileHistoryStack);
5967 var selectedFileName = keys[selectedFileIndex];
5969 Debug.log(
"selectedFileName " + selectedFileName);
5975 var fileArr = selectedFileName.split(
'.');
5978 if(fileArr[0] == _filePath[forPrimary] &&
5979 fileArr[1] == _fileExtension[forPrimary])
5981 CodeEditor.editor.openFile(forPrimary,
5982 _filePath[forPrimary],
5983 _fileExtension[forPrimary],
5988 fileObj.path = fileArr[0];
5989 fileObj.extension = fileArr[1];
5990 fileObj.text = _fileHistoryStack[selectedFileName][0];
5991 fileObj.fileWasModified = _fileHistoryStack[selectedFileName][2];
5992 fileObj.fileLastSave = _fileHistoryStack[selectedFileName][3];
5994 console.log(
"fileObj",fileObj);
5996 CodeEditor.editor.handleFileContent(forPrimary,0,fileObj);
6003 this.showFindAndReplace =
function(forPrimary)
6005 forPrimary = forPrimary?1:0;
6006 _activePaneIsPrimary = forPrimary;
6008 Debug.log(
"showFindAndReplace forPrimary=" + forPrimary +
" activePane=" + _activePaneIsPrimary);
6010 CodeEditor.editor.findAndReplaceLastButton[forPrimary] = 1;
6013 var el = _eel[forPrimary];
6014 var cursor = _findAndReplaceCursorInContent[forPrimary] =
6015 CodeEditor.editor.getCursor(el);
6018 el = document.getElementById(
"textEditorHeader" + forPrimary);
6023 str +=
"<table style='margin-top: 2px;'>";
6027 str +=
"<tr><td style='text-align:right'>";
6030 str += htmlOpen(
"input",
6033 "id":
"findAndReplaceFind" + forPrimary,
6034 "style":
"text-align:left; width:90%;" +
6035 " height:" + (20) +
"px",
6036 "value": CodeEditor.editor.findAndReplaceFind[forPrimary],
6037 "onclick":
"event.stopPropagation();",
6038 "onchange":
"CodeEditor.editor.findAndReplaceFind[" +
6039 forPrimary +
"] = this.value;" +
6040 "CodeEditor.editor.showFindAndReplaceSelection(" +
6047 str += htmlOpen(
"select",
6049 "id":
"findAndReplaceScope" + forPrimary,
6050 "style":
"width:100%;" +
6051 "text-align-last: center;",
6052 "title":
"Choose the scope for Replace All",
6053 "onclick":
"event.stopPropagation();" ,
6054 "onchange":
"CodeEditor.editor.findAndReplaceScope[" +
6055 forPrimary +
"] = this.value;" +
6056 "CodeEditor.editor.showFindAndReplaceSelection(" +
6060 str +=
"<option value='0'>All Lines</option>";
6061 str +=
"<option value='1' " + (CodeEditor.editor.findAndReplaceScope[forPrimary] ==
6062 1?
"selected":
"") +
">Selected Lines</option>";
6068 str += htmlOpen(
"input",
6071 "id":
"findAndReplaceCaseSensitive" + forPrimary,
6072 "title":
"Toggle case sensitive search",
6073 "onclick":
"event.stopPropagation();",
6074 "style":
"margin-left:10px;",
6075 "onchange":
"CodeEditor.editor.findAndReplaceCaseSensitive[" +
6076 forPrimary +
"] = this.checked;" +
6077 "CodeEditor.editor.showFindAndReplaceSelection(" +
6083 "title":
"Toggle case sensitive search",
6084 "style":
"margin-left:5px;",
6085 "onclick":
"event.stopPropagation();" +
6086 "var el = document.getElementById(\"findAndReplaceCaseSensitive" +
6087 forPrimary +
"\"); el.checked = !el.checked;" +
6088 "CodeEditor.editor.findAndReplaceCaseSensitive[" +
6089 forPrimary +
"] = el.checked;" +
6090 "CodeEditor.editor.showFindAndReplaceSelection(" +
6094 "Case sensitive" ,
true
6097 str +=
"</td></tr>";
6100 str +=
"<tr><td style='text-align:right'>";
6101 str +=
"Replace with:";
6103 str += htmlOpen(
"input",
6106 "id":
"findAndReplaceReplace" + forPrimary,
6107 "style":
"text-align:left; width:90%;" +
6108 " height:" + (20) +
"px",
6109 "value": CodeEditor.editor.findAndReplaceReplace[forPrimary],
6110 "onclick":
"event.stopPropagation();",
6111 "onchange":
"CodeEditor.editor.findAndReplaceReplace[" +
6112 forPrimary +
"] = this.value; " +
6113 "CodeEditor.editor.showFindAndReplaceSelection(" +
6120 str += htmlOpen(
"select",
6122 "id":
"findAndReplaceDirection" + forPrimary,
6123 "style":
"width:100%;" +
6124 "text-align-last: center;",
6125 "title":
"Choose the search direction for the Find & Replace",
6126 "onclick":
"event.stopPropagation();",
6127 "onchange":
"CodeEditor.editor.findAndReplaceDirection[" +
6128 forPrimary +
"] = this.value;" +
6129 "CodeEditor.editor.showFindAndReplaceSelection(" +
6133 str +=
"<option value='0'>Search Forward</option>";
6134 str +=
"<option value='1' " + (CodeEditor.editor.findAndReplaceDirection[forPrimary] ==
6136 ">Search Backward</option>";
6142 str += htmlOpen(
"input",
6145 "id":
"findAndReplaceWholeWord" + forPrimary,
6146 "title":
"Toggle whole word search",
6147 "onclick":
"event.stopPropagation();",
6148 "style":
"margin-left:10px;",
6149 "onchange":
"CodeEditor.editor.findAndReplaceWholeWord[" +
6150 forPrimary +
"] = this.checked;" +
6151 "CodeEditor.editor.showFindAndReplaceSelection(" +
6157 "style":
"margin-left:5px;",
6158 "title":
"Toggle whole word search",
6159 "onclick":
"event.stopPropagation();" +
6160 "var el = document.getElementById(\"findAndReplaceWholeWord" +
6161 forPrimary +
"\"); el.checked = !el.checked;" +
6162 "CodeEditor.editor.findAndReplaceWholeWord[" +
6163 forPrimary +
"] = el.checked;" +
6164 "CodeEditor.editor.showFindAndReplaceSelection(" +
6170 str +=
"</td></tr>";
6174 str +=
"<tr><td colspan='4' style='text-align:center'>";
6175 str += htmlOpen(
"div",
6177 "id":
"findAndReplaceWrapped" + forPrimary,
6178 "style":
"text-align:right; margin: 4px; width:115px;" +
6179 "color: red; float: left;",
6181 str +=
"<div style='float:left;'>";
6182 str += htmlOpen(
"input",
6187 "style":
"text-align:center; margin: 4px;" ,
6188 "onclick":
"event.stopPropagation();" +
6189 "CodeEditor.editor.doFindAndReplaceAction(" + forPrimary +
",1)",
6192 str += htmlOpen(
"input",
6197 "style":
"text-align:center; margin: 4px;" ,
6198 "onclick":
"event.stopPropagation();" +
6199 "CodeEditor.editor.doFindAndReplaceAction(" + forPrimary +
",2)",
6202 str += htmlOpen(
"input",
6205 "value":
"Replace & Find",
6207 "style":
"text-align:center; margin: 4px;" ,
6208 "onclick":
"event.stopPropagation();" +
6209 "CodeEditor.editor.doFindAndReplaceAction(" + forPrimary +
",3)",
6212 str += htmlOpen(
"input",
6215 "value":
"Replace All",
6217 "style":
"text-align:center; margin: 4px;" ,
6218 "onclick":
"event.stopPropagation();" +
6219 "CodeEditor.editor.doFindAndReplaceAction(" + forPrimary +
",4)",
6222 str += htmlOpen(
"input",
6226 "title":
"Close find and replace controls.",
6227 "style":
"text-align:center; margin: 4px;" ,
6229 "onclick":
"event.stopPropagation();" +
6230 "CodeEditor.editor.displayFileHeader(" + forPrimary +
")",
6234 str +=
"</td></tr>";
6241 el = document.getElementById(
"findAndReplaceFind" + forPrimary);
6242 el.setSelectionRange(0, el.value.length);
6245 el = document.getElementById(
"findAndReplaceCaseSensitive" + forPrimary);
6246 el.checked = CodeEditor.editor.findAndReplaceCaseSensitive[forPrimary];
6248 el = document.getElementById(
"findAndReplaceWholeWord" + forPrimary);
6249 el.checked = CodeEditor.editor.findAndReplaceWholeWord[forPrimary];
6256 this.showFindAndReplaceSelection =
function(forPrimary)
6258 forPrimary = forPrimary?1:0;
6259 Debug.log(
"showFindAndReplaceSelection forPrimary=" + forPrimary);
6261 var el = _eel[forPrimary];
6262 var cursor = CodeEditor.editor.getCursor(el);
6264 if(cursor.startPosInContent !== undefined)
6265 CodeEditor.editor.setCursor(el,
6269 CodeEditor.editor.findAndReplaceLastButton[forPrimary] > 0 &&
6270 _findAndReplaceCursorInContent[forPrimary] !== undefined)
6271 CodeEditor.editor.setCursor(el,
6272 _findAndReplaceCursorInContent[forPrimary],
6285 this.doFindAndReplaceAction =
function(forPrimary,action)
6287 forPrimary = forPrimary?1:0;
6288 action = action | 0;
6290 CodeEditor.editor.findAndReplaceLastButton[forPrimary] = action;
6292 var find = document.getElementById(
"findAndReplaceFind" + forPrimary).value;
6293 var originalFind = find;
6294 if(!find || find ==
"")
6296 Debug.log(
"Illegal empty string to find.", Debug.HIGH_PRIORITY);
6299 var replace = CodeEditor.editor.findAndReplaceReplace[forPrimary];
6300 var scope = CodeEditor.editor.findAndReplaceScope[forPrimary]|0;
6301 var direction = CodeEditor.editor.findAndReplaceDirection[forPrimary]|0;
6304 var caseSensitive = CodeEditor.editor.findAndReplaceCaseSensitive[forPrimary]?1:0;
6305 var wholeWord = CodeEditor.editor.findAndReplaceWholeWord[forPrimary]?1:0;
6307 Debug.log(
"doFindAndReplaceAction forPrimary=" + forPrimary +
6308 " action=" + action +
6310 " replace=" + replace +
6312 " direction=" + direction +
6313 " caseSensitive=" + caseSensitive +
6314 " wholeWord=" + wholeWord);
6325 var el = _eel[forPrimary];
6326 var originalText = el.textContent;
6329 text = originalText;
6332 text = originalText.toLowerCase();
6333 find = find.toLowerCase();
6336 var i = direction?text.length:-1;
6337 var j = text.length-1;
6339 var cursor = CodeEditor.editor.getCursor(el);
6342 if(cursor.startPosInContent !== undefined &&
6344 document.getElementById(
"findAndReplaceWrapped" + forPrimary).textContent ==
""))
6345 i = cursor.startPosInContent;
6346 else if(_findAndReplaceCursorInContent[forPrimary] !== undefined &&
6347 _findAndReplaceCursorInContent[forPrimary].startPosInContent !== undefined &&
6348 _findAndReplaceCursorInContent[forPrimary].startPosInContent >= 0 &&
6350 document.getElementById(
"findAndReplaceWrapped" + forPrimary).textContent ==
""))
6352 i = _findAndReplaceCursorInContent[forPrimary].startPosInContent;
6355 CodeEditor.editor.setCursor(el,
6356 _findAndReplaceCursorInContent[forPrimary],
6361 document.getElementById(
"findAndReplaceWrapped" + forPrimary).innerHTML =
"";
6363 Debug.log(
"Starting position: " + i);
6367 if(cursor.endPosInContent !== undefined)
6368 j = cursor.endPosInContent;
6369 else if(_findAndReplaceCursorInContent[forPrimary] !== undefined &&
6370 _findAndReplaceCursorInContent[forPrimary].endPosInContent != undefined &&
6371 _findAndReplaceCursorInContent[forPrimary].endPosInContent >= 0)
6372 j = _findAndReplaceCursorInContent[forPrimary].endPosInContent;
6374 Debug.log(
"Ending position: " + j);
6376 else if(action == 4)
6379 var replaceCount = 0;
6392 if(i > 0 && i + find.length <= text.length)
6398 Debug.log(
"Replacing");
6403 originalText.substr(0,i) +
6405 originalText.substr(i+find.length);
6409 text = originalText;
6411 text = originalText.toLowerCase();
6418 Debug.log(
"Unrecognized action! " + action, Debug.HIGH_PRIORITY);
6432 i = text.indexOf(find,i+1);
6433 else if(direction == 1)
6434 i = text.lastIndexOf(find,i-1);
6440 (text[i-1] >=
'a' && text[i-1] <=
'z') ||
6441 (text[i-1] >=
'A' && text[i-1] <=
'Z') ||
6442 (text[i-1] >=
'0' && text[i-1] <=
'9') ||
6449 else if(i>0 && i+find.length<text.length && (
6450 (text[i+find.length] >=
'a' && text[i+find.length] <=
'z') ||
6451 (text[i+find.length] >=
'A' && text[i+find.length] <=
'Z') ||
6452 (text[i+find.length] >=
'0' && text[i+find.length] <=
'9') ||
6453 text[i+find.length] ==
'_'
6473 if(i + find.length < j)
6481 document.getElementById(
"findAndReplaceWrapped" + forPrimary).innerHTML =
"Reached end";
6491 Debug.log(
"Unrecognized action! " + action, Debug.HIGH_PRIORITY);
6509 el.textContent = originalText;
6510 CodeEditor.editor.updateDecorations(forPrimary);
6515 _findAndReplaceCursorInContent[forPrimary] =
6516 CodeEditor.editor.createCursorFromContentPosition(el,
6517 i, i + find.length);
6518 CodeEditor.editor.setCursor(
6520 _findAndReplaceCursorInContent[forPrimary],
6529 _findAndReplaceCursorInContent[forPrimary] =
6530 CodeEditor.editor.createCursorFromContentPosition(el,
6532 CodeEditor.editor.setCursor(
6534 _findAndReplaceCursorInContent[forPrimary],
6539 Debug.log(
"Unrecognized action! " + action, Debug.HIGH_PRIORITY);
6547 document.getElementById(
"findAndReplaceWrapped" + forPrimary).innerHTML =
6548 replaceCount +
" Replaced";
6555 this.displayFileHeader =
function(forPrimary)
6557 forPrimary = forPrimary?1:0;
6559 var forceDisplayComplete =
false;
6560 if(CodeEditor.editor.findAndReplaceLastButton[forPrimary] != -1)
6562 CodeEditor.editor.findAndReplaceLastButton[forPrimary] = -1;
6563 forceDisplayComplete =
true;
6566 Debug.log(
"displayFileHeader forPrimary=" + forPrimary);
6569 var el = document.getElementById(
"textEditorHeader" + forPrimary);
6572 var path = _filePath[forPrimary];
6573 var extension = _fileExtension[forPrimary];
6580 str += htmlOpen(
"div",
6583 "CodeEditor.editor.handleFileNameMouseMove(" + forPrimary +
");",
6588 str += htmlOpen(
"div",
6591 "style":
"width: 172px;",
6592 "class":
"fileButtonContainer",
6593 "id":
"fileButtonContainer" + forPrimary,
6597 str += htmlOpen(
"div",
6599 "class":
"fileButtonContainerShowHide",
6600 "id":
"fileButtonContainerShowHide" + forPrimary,
6602 "event.stopPropagation(); " +
6603 "CodeEditor.editor.handleFileNameMouseMove(" + forPrimary +
6604 ",1 /*doNotStartTimer*/);",
6611 str += htmlOpen(
"div",
6613 "class":
"fileButton",
6614 "id":
"fileRenameButton" + forPrimary,
6615 "title":
"Change the filename\n" + path +
"." + extension,
6617 "event.stopPropagation(); " +
6618 "CodeEditor.editor.startEditFileName(" + forPrimary +
");",
6621 str += htmlOpen(
"div",
6623 "class":
"fileButton",
6624 "id":
"fileDownloadButton" + forPrimary,
6625 "title":
"Download the file content from\n" + path +
"." + extension,
6627 "event.stopPropagation(); " +
6628 "CodeEditor.editor.download(" + forPrimary +
");",
6631 "<div class='fileDownloadButtonBgChild' style='display: ; margin-left: 0px; margin-top: 1px; height:7px; width: 6px; background-color: rgb(202, 204, 210);'></div>" +
6632 "<div class='fileDownloadButtonBorderChild' style='display: block; width: 0; height: 0; border-left: 6px solid transparent; border-right: 6px solid transparent; border-top: 8px solid rgb(202, 204, 210);'></div>" +
6633 "<div class='fileDownloadButtonBgChild' style='position: relative; top: 2px; width: 12px; height: 2px; display: block; background-color: rgb(202, 204, 210);'></div>"
6636 str += htmlOpen(
"div",
6638 "class":
"fileButton",
6639 "id":
"fileUploadButton" + forPrimary,
6640 "title":
"Upload file content to\n" + path +
"." + extension,
6642 "event.stopPropagation(); " +
6643 "CodeEditor.editor.upload(" + forPrimary +
");",
6647 "<div class='fileDownloadButtonBorderChild' style='display: block; width: 0; height: 0; border-left: 6px solid transparent; border-right: 6px solid transparent; border-bottom: 8px solid rgb(202, 204, 210);'></div>" +
6648 "<div class='fileDownloadButtonBgChild' style='display: block; margin-left: 0px; height:7px; width: 6px; background-color: rgb(202, 204, 210);'></div>" +
6649 "<div class='fileDownloadButtonBgChild' style='position: relative; top: 3px; width: 12px; height: 2px; display: block; background-color: rgb(202, 204, 210);'></div>"
6653 str += htmlOpen(
"div",
6655 "class":
"fileButton fileUndoButton",
6656 "id":
"fileUndoButton" + forPrimary,
6657 "title":
"Undo to rewind to last recorded checkpoint for\n" + path +
"." + extension,
6658 "style":
"color: rgb(202, 204, 210);" +
6659 "padding: 0 5px 0;" +
6660 "font-size: 17px;" +
6661 "font-weight: bold;",
6663 "event.stopPropagation(); " +
6664 "CodeEditor.editor.undo(" + forPrimary +
");",
6670 str += htmlOpen(
"div",
6672 "class":
"fileButton fileUndoButton",
6673 "id":
"fileRedoButton" + forPrimary,
6674 "title":
"Redo to fast-forward to last recorded checkpoint for\n" + path +
"." + extension,
6675 "style":
"color: rgb(202, 204, 210);" +
6676 "padding: 0 5px 0;" +
6677 "font-size: 17px;" +
6678 "font-weight: bold;",
6680 "event.stopPropagation(); " +
6681 "CodeEditor.editor.undo(" + forPrimary +
",1 /*redo*/);",
6688 str += htmlOpen(
"div",
6690 "class":
"fileButton openRelatedFileButton",
6691 "id":
"openRelatedFileButton" + forPrimary,
6692 "title":
"Open related file in other pane for\n" + path +
"." + extension,
6693 "style":
"color: rgb(202, 204, 210);" +
6694 "padding: 0 5px 0;" +
6695 "font-size: 17px;" +
6696 "font-weight: bold;",
6698 "event.stopPropagation(); " +
6699 "CodeEditor.editor.openRelatedFile(" + forPrimary +
6700 ", true /*inOtherPane*/);",
6706 str += htmlOpen(
"div",
6708 "class":
"fileButton refreshFileButton",
6709 "id":
"refreshFileButton" + forPrimary,
6710 "title":
"Refresh file \n" + path +
"." + extension,
6711 "style":
"color: rgb(202, 204, 210);" +
6712 "padding: 0 5px 0;" +
6713 (Debug.BROWSER_TYPE == Debug.BROWSER_TYPE_FIREFOX?
6714 "font-size: 28px;margin-top:-6px;":
"font-size: 17px;font-weight:bold;"),
6716 "event.stopPropagation(); " +
6717 "CodeEditor.editor.openFile(" + forPrimary +
6718 ",\"" + path +
"\",\"" +
6719 extension +
"\", true /*doConfirm*/);",
6730 str += htmlClearDiv();
6732 var nameArr = path.split(
'/');
6735 str +=
"<table><tr><td>";
6737 str += htmlOpen(
"a",
6739 "title":
"Open file in a new browser tab: \n" +
6740 "srcs" + path +
"." + extension,
6741 "onclick":
"DesktopContent.openNewBrowserTab(" +
6742 "\"" + nameArr[nameArr.length-1] +
"." + extension +
"\",\"\"," +
6743 "\"/WebPath/html/CodeEditor.html?urn=" +
6744 DesktopContent._localUrnLid +
"&" +
6745 "startFilePrimary=" +
6746 path +
"." + extension +
"\",0 /*unique*/);' ",
6748 "<img class='dirNavFileNewWindowImgNewWindow' " +
6749 "src='/WebPath/images/windowContentImages/CodeEditor-openInNewWindow.png'>"
6753 str += htmlOpen(
"a",
6755 "title":
"Open file in the other editor pane of the split-view: \n" +
6756 "srcs" + path +
"." + extension,
6757 "onclick":
"CodeEditor.editor.openFile(" +
6758 (!forPrimary) +
",\"" +
6763 "<img class='dirNavFileNewWindowImgNewPane' " +
6764 "src='/WebPath/images/windowContentImages/CodeEditor-openInOtherPane.png'>"
6769 str += htmlOpen(
"div",
6771 "class":
"fileNameDiv",
6772 "id":
"fileNameDiv" + forPrimary,
6773 "style":
"margin: 0 5px 0 5px",
6775 str +=
"<a onclick='CodeEditor.editor.openFile(" + forPrimary +
6776 ",\"" + path +
"\",\"" + extension +
"\",true /*doConfirm*/);' " +
6777 "title='Click to reload \n" + path +
"." + extension +
"' " +
6779 path +
"." + extension +
"</a>";
6782 str +=
"</td></tr></table>";
6786 str += htmlClearDiv();
6789 str +=
"<div class='textEditorLastSave' id='textEditorLastSave" +
6790 forPrimary +
"'>Unmodified</div>";
6792 str += htmlClearDiv();
6794 str +=
"<div class='textEditorOutline' id='textEditorOutline" +
6795 forPrimary +
"'>Outline:</div>";
6799 CodeEditor.editor.updateDecorations(forPrimary,forceDisplayComplete);
6800 CodeEditor.editor.updateFileHistoryDropdowns();
6810 this.updateFileSnapshot =
function(forPrimary,textObj , ignoreTimeDelta)
6812 forPrimary = forPrimary?1:0;
6814 Debug.log(
"updateFileSnapshot forPrimary=" + forPrimary);
6817 var addSnapshot =
false;
6819 if(_undoStackLatestIndex[forPrimary] != -1)
6823 if((ignoreTimeDelta ||
6824 2*1000 < textObj.time - _undoStack[forPrimary][_undoStackLatestIndex[forPrimary]][1]) &&
6825 _undoStack[forPrimary][_undoStackLatestIndex[forPrimary]][0] != textObj.text)
6834 ++_undoStackLatestIndex[forPrimary];
6835 if(_undoStackLatestIndex[forPrimary] >= _undoStack_MAX_SIZE)
6836 _undoStackLatestIndex[forPrimary] = 0;
6838 _undoStack[forPrimary][_undoStackLatestIndex[forPrimary]] =
6842 console.log(
"snapshot added to stack",_undoStack[forPrimary]);
6850 _fileHistoryStack[_filePath[forPrimary] +
"." +
6851 _fileExtension[forPrimary]] = [
6854 _fileWasModified[forPrimary],
6855 _fileLastSave[forPrimary]];
6856 console.log(
"_fileHistoryStack",_fileHistoryStack);
6858 CodeEditor.editor.updateFileHistoryDropdowns();
6868 this.startUpdateHandling =
function(forPrimary)
6870 _updateHandlerTargetPane[forPrimary] =
true;
6872 window.clearTimeout(_updateTimerHandle);
6873 _updateTimerHandle = window.setTimeout(
6874 CodeEditor.editor.updateTimeoutHandler,
6875 _UPDATE_DECOR_TIMEOUT );
6882 this.stopUpdateHandling =
function(event)
6884 if(event)
event.stopPropagation();
6885 window.clearTimeout(_updateTimerHandle);
6891 this.updateTimeoutHandler =
function()
6893 if(_updateHandlerTargetPane[0])
6895 CodeEditor.editor.updateDecorations(0 );
6896 _updateHandlerTargetPane[0] =
false;
6898 if(_updateHandlerTargetPane[1])
6900 CodeEditor.editor.updateDecorations(1 );
6901 _updateHandlerTargetPane[1] =
false;
6908 this.doubleClickHandler =
function(forPrimary)
6910 forPrimary = forPrimary?1:0;
6912 Debug.log(
"doubleClickHandler forPrimary=" + forPrimary);
6918 var el = _eel[forPrimary];
6919 var cursor = CodeEditor.editor.getCursor(el);
6921 if(!cursor || cursor.startNodeIndex === undefined)
6924 var n = cursor.startNodeIndex;
6925 var c = el.childNodes[n].textContent[
6930 if(c !=
'{' && c !=
'}')
6932 if(cursor.startPos == 0)
6938 }
while(n >= 0 && el.childNodes[n].textContent.length);
6941 c = el.childNodes[n].textContent[
6942 el.childNodes[n].textContent.length-1];
6945 c = el.childNodes[n].textContent[
6952 Debug.log(
"character before cursor " + c);
6954 if(c !=
'{' && c !=
'}')
return;
6958 var foundDoubleQuote =
false;
6959 var foundSingleQuote =
false;
6960 var foundComment =
false;
6965 cursor.endNodeIndex = -1;
6972 var openCountSave = openCount;
6973 var prelimFound =
false;
6977 node = el.childNodes[n];
6978 val = node.textContent;
6979 for(i=(n==cursor.startNodeIndex?cursor.startPos-1:
6980 val.length-1); i>=0; --i)
6982 if(cursor.endNodeIndex == -1)
6984 cursor.endNodeIndex = n;
6990 foundSingleQuote =
false;
6991 foundDoubleQuote =
false;
6992 openCountSave = openCount;
6996 Debug.log(
"confirmed found open count match ni " + n +
" " + i);
7002 if(!foundSingleQuote && val[i] ==
'"')
7003 foundDoubleQuote = !foundDoubleQuote;
7004 else if(!foundDoubleQuote && val[i] ==
"'")
7005 foundSingleQuote = !foundSingleQuote;
7006 else if(val[i]==
'/' && i-1 >= 0 &&
7010 openCount = openCountSave;
7012 prelimFound =
false;
7018 if(foundDoubleQuote || foundSingleQuote ||
7024 else if(val[i] ==
'{')
7030 Debug.log(
"found open count match ni " + n +
" " + i);
7037 cursor.startNodeIndex = n;
7038 cursor.startPos = i;
7049 i = cursor.startPos;
7050 for(n=cursor.startNodeIndex;n<el.childNodes.length; ++n)
7052 node = el.childNodes[n];
7053 val = node.textContent;
7055 for(; i<val.length; ++i)
7059 foundSingleQuote =
false;
7060 foundDoubleQuote =
false;
7061 foundComment =
false;
7067 if(!foundSingleQuote && val[i] ==
'"')
7068 foundDoubleQuote = !foundDoubleQuote;
7069 else if(!foundDoubleQuote && val[i] ==
"'")
7070 foundSingleQuote = !foundSingleQuote;
7071 else if(val[i]==
'/' && i+1 < val.length &&
7074 foundComment =
true;
7078 if(foundDoubleQuote || foundSingleQuote)
7083 else if(val[i] ==
'}')
7089 Debug.log(
"found open count match ni " + n +
" " + i);
7094 cursor.endNodeIndex = n;
7106 CodeEditor.editor.setCursor(el,cursor);
7113 this.download =
function(forPrimary)
7115 forPrimary = forPrimary?1:0;
7117 Debug.log(
"download forPrimary=" + forPrimary);
7119 var dataStr =
"data:text/plain;charset=utf-8," +
7120 encodeURIComponent(_eel[forPrimary].textContent);
7122 var filename = _filePath[forPrimary];
7123 var i = filename.lastIndexOf(
'/');
7125 filename = filename.substr(i+1);
7126 filename +=
"." + _fileExtension[forPrimary];
7128 Debug.log(
"Downloading to filename " + filename);
7130 var link = document.createElement(
"a");
7131 link.setAttribute(
"href", dataStr);
7132 link.setAttribute(
"style",
"display:none");
7133 link.setAttribute(
"download", filename);
7134 document.body.appendChild(link);
7138 link.parentNode.removeChild(link);
7144 this.upload =
function(forPrimary)
7146 forPrimary = forPrimary?1:0;
7148 Debug.log(
"upload forPrimary=" + forPrimary);
7150 _fileUploadString =
"";
7154 var el = document.getElementById(
"popUpDialog");
7157 el = document.createElement(
"div");
7158 el.setAttribute(
"id",
"popUpDialog");
7160 el.style.display =
"none";
7165 DesktopContent.setPopUpPosition(el,w ,h );
7167 var str =
"<a id='" +
7169 "-header' onclick='var el = document.getElementById(" +
7170 "\"popUpDialog\"); if(el) el.parentNode.removeChild(el); return false;'>Cancel</a><br><br>";
7172 str +=
"<div id='popUpDialog-div'>";
7174 str +=
"Please choose the file to upload which has the text content to place in the open source file:<br><br>" +
7175 _filePath[forPrimary] +
"." + _fileExtension[forPrimary] +
7180 str +=
"<input type='file' id='popUpDialog-fileUpload' " +
7182 for(var i=0;i<_ALLOWED_FILE_EXTENSIONS.length;++i)
7183 str += (i?
", ":
"") +
"." + _ALLOWED_FILE_EXTENSIONS[i];
7184 str +=
"' enctype='multipart/form-data' />";
7187 var onmouseupJS =
"";
7188 onmouseupJS +=
"document.getElementById(\"popUpDialog-submitButton\").disabled = true;";
7189 onmouseupJS +=
"CodeEditor.editor.uploadTextFromFile(" + forPrimary +
");";
7191 str +=
"<input id='popUpDialog-submitButton' disabled type='button' onmouseup='" +
7192 onmouseupJS +
"' " +
7193 "value='Upload File' title='" +
7194 "Upload the chosen file text content to\n" +
7195 _filePath[forPrimary] +
"." + _fileExtension[forPrimary] +
7199 document.body.appendChild(el);
7200 el.style.display =
"block";
7202 document.getElementById(
'popUpDialog-fileUpload').addEventListener(
7203 'change',
function(evt) {
7204 var files = evt.target.files;
7205 var file = files[0];
7206 var reader =
new FileReader();
7207 reader.onload =
function() {
7209 _fileUploadString = this.result;
7210 Debug.log(
"_fileUploadString = " + _fileUploadString);
7211 document.getElementById(
'popUpDialog-submitButton').disabled =
false;
7215 var i=file.name.lastIndexOf(
'.');
7216 _filePath[forPrimary] = file.name.substr(0,i);
7217 _fileExtension[forPrimary] = file.name.substr(i+1);
7220 reader.readAsText(file);
7226 this.uploadTextFromFile =
function(forPrimary)
7228 forPrimary = forPrimary?1:0;
7230 Debug.log(
"uploadTextFromFile forPrimary=" + forPrimary);
7233 document.getElementById(
'popUpDialog-submitButton').disabled =
false;
7235 Debug.log(
"uploadTextFromFile _fileUploadString = " + _fileUploadString);
7239 DesktopContent.showLoading(
function()
7245 _fileUploadString = _fileUploadString.replace(
new RegExp(
7246 String.fromCharCode(160),
'g'),
' ');
7248 var el = _eel[forPrimary];
7249 el.textContent = _fileUploadString;
7250 CodeEditor.editor.displayFileHeader(forPrimary);
7254 Debug.log(
"There was an error uploading the text:[" + DesktopContent.getExceptionLineNumber(e) +
"]: " + e,
7255 Debug.HIGH_PRIORITY);
7258 Debug.log(
"Source upload complete! (You can use undo to go back) ",
7259 Debug.INFO_PRIORITY);
7262 var el = document.getElementById(
"popUpDialog");
7263 if(el) el.parentNode.removeChild(el);