22 var CodeEditor = CodeEditor || {};
24 if (typeof DesktopContent ==
'undefined')
25 throw(
'ERROR: DesktopContent is undefined! Must include DesktopWindowContentCode.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) {
71 Element.prototype.scrollIntoViewIfNeeded =
function (centerIfNeeded) {
72 centerIfNeeded = arguments.length === 0 ?
true : !!centerIfNeeded;
74 var parent = this.parentNode,
75 tdParent = parent.parentNode,
76 editorParent = parent.parentNode.parentNode.parentNode.parentNode.parentNode,
77 parentComputedStyle = window.getComputedStyle(parent, null),
78 parentBorderTopWidth = parseInt(parentComputedStyle.getPropertyValue(
'border-top-width')),
79 parentBorderLeftWidth = parseInt(parentComputedStyle.getPropertyValue(
'border-left-width')),
80 overTop = this.offsetTop - tdParent.offsetTop < editorParent.scrollTop,
81 overBottom = (
this.offsetTop - tdParent.offsetTop +
this.clientHeight - parentBorderTopWidth) > (editorParent.scrollTop + editorParent.clientHeight),
82 overLeft = this.offsetLeft - tdParent.offsetLeft < editorParent.scrollLeft,
83 overRight = (
this.offsetLeft + tdParent.offsetLeft +
this.clientWidth - parentBorderLeftWidth) > (editorParent.scrollLeft + editorParent.clientWidth),
84 alignWithTop = overTop && !overBottom;
86 if ((overTop || overBottom) && centerIfNeeded) {
87 editorParent.scrollTop = this.offsetTop - tdParent.offsetTop - editorParent.clientHeight / 2 - parentBorderTopWidth + this.clientHeight / 2;
91 if ((overLeft || overRight) && centerIfNeeded) {
92 editorParent.scrollLeft = this.offsetLeft + tdParent.offsetLeft - editorParent.clientWidth / 2 - parentBorderLeftWidth + this.clientWidth / 2;
96 if ((overTop || overBottom || overLeft || overRight) && !centerIfNeeded) {
97 this.scrollIntoView(alignWithTop);
105 var windowTooltip =
"Welcome to the Code Editor user interface. " +
106 "Edit your code, save it, and compile!\n\n" +
107 "Hover your mouse over the icons and buttons to see what they do. " +
108 "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" +
110 "<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" +
111 "<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" +
112 "<b>Save:</b>\n<INDENT>Use the save icon in the top-left to save your changes.</INDENT>\n" +
113 "<b>Compile:</b>\n<INDENT>Use the Incremmental Build or Clean Build icons in the top-right.</INDENT>\n" +
115 "<b>Global Hot Keys:</b>\n<INDENT>" +
117 "<table border=0 cellspacing=0 cellpadding=0 style='border: 1px solid grey;'>" +
118 "<tr style='background-color: rgb(106, 102, 119);'><td style='white-space: nowrap; padding:5px;'> " +
119 "Ctrl + B </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Incremental Build</td></tr>" +
120 "<tr><td style='white-space: nowrap; padding:5px;'> " +
121 "Ctrl + N </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Clean Build</td></tr>" +
122 "<tr style='background-color: rgb(106, 102, 119);'><td style='white-space: nowrap; padding:5px;'> " +
123 "Ctrl + 2 </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Toggle Split-View Mode (single, dual-vertical, dual-horizontal)</td></tr>" +
124 "</table></INDENT>\n" +
127 "<b>Editor Pane Hot Keys:</b>\n<INDENT>" +
129 "<table border=0 cellspacing=0 cellpadding=0 style='border: 1px solid grey;'>" +
131 "<tr style='background-color: rgb(106, 102, 119);'><td style='white-space: nowrap; padding:5px;'> " +
132 "Ctrl + S </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Save File</td></tr>" +
134 "<tr><td style='white-space: nowrap; padding:5px;'> " +
135 "Ctrl + D </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Toggle Directory Navigation</td></tr>" +
137 "<tr style='background-color: rgb(106, 102, 119);'><td style='white-space: nowrap; padding:5px;'> " +
138 "Ctrl + F </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Find & Replace</td></tr>" +
140 "<tr><td style='white-space: nowrap; padding:5px;'> " +
141 "Ctrl + U </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Undo Text Editing</td></tr>" +
143 "<tr style='background-color: rgb(106, 102, 119);'><td style='white-space: nowrap; padding:5px;'> " +
144 "Shift + Ctrl + U </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Redo Text Editing</td></tr>" +
146 "<tr><td style='white-space: nowrap; padding:5px;'> " +
147 "Ctrl + L or G </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Goto Line Number</td></tr>" +
149 "<tr style='background-color: rgb(106, 102, 119);'><td style='white-space: nowrap; padding:5px;'> " +
150 "Ctrl + 1 or ; </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Switch to Related File (associated .h or .cc)</td></tr>" +
152 "<tr><td style='white-space: nowrap; padding:5px;'> " +
153 "Ctrl + 0 or ' </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Reload Current File from Server</td></tr>" +
155 "</table></INDENT>\n" +
158 "<b>Selected-Text Hot Keys:</b>\n<INDENT>" +
160 "<table border=0 cellspacing=0 cellpadding=0 style='border: 1px solid grey;'>" +
161 "<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>" +
162 "<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>" +
163 "<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>" +
164 "<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>" +
165 "<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>" +
166 "<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>" +
167 "<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>" +
168 "</table></INDENT>\n" +
169 "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.'" +
173 var windowViewModeTooltip =
"Welcome to the Code Viewer user interface. " +
174 "You will only be able to view codes without modifying. Your text inputs won't be saved. " +
175 "Contact your administrator if you think you should have modification access."+
177 "<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" +
178 "<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" +
180 "<b>Viewer Hot Keys:</b>\n<INDENT>" +
182 "<table border=0 cellspacing=0 cellpadding=0 style='border: 1px solid grey;'>" +
184 "<tr style='background-color: rgb(106, 102, 119);'><td style='white-space: nowrap; padding:5px;'> " +
185 "Ctrl + 2 </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Toggle Split-View Mode (single, dual-vertical, dual-horizontal)</td></tr>" +
187 "<tr><td style='white-space: nowrap; padding:5px;'> " +
188 "Ctrl + L or G </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Goto Line Number</td></tr>" +
190 "<tr style='background-color: rgb(106, 102, 119);'><td style='white-space: nowrap; padding:5px;'> " +
191 "Ctrl + F </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Find</td></tr>" +
192 "</table></INDENT>\n" +
196 appMode =
"Code Editor";
198 CodeEditor.showTooltip =
function(alwaysShow)
200 DesktopContent.tooltip(
201 (alwaysShow ?
"ALWAYS" : appMode), windowTooltip);
203 DesktopContent.setWindowTooltip(windowTooltip);
213 CodeEditor.create =
function() {
280 var _WINDOW_MIN_SZ = 525;
282 var _ALLOWED_FILE_EXTENSIONS = [];
284 var _needEventListeners =
true;
287 var _navMode = [0,0];
288 var _filePath = [
"",
""];
289 var _fileExtension = [
"",
""];
290 var _fileLastSave = [0,0];
291 var _fileWasModified = [
false,
false];
292 var _numberOfLines = [0,0];
294 var _eel = [undefined,undefined];
296 var _updateTimerHandle = 0;
297 var _updateHandlerTargetPane = [
false,
false];
298 var _commandKeyDown =
false;
299 var _lastPageUpDownLine = -1;
300 var _startPageUpDownLine = -1;
301 var _startPageUpDownNodeIndex = -1;
302 var _startPageUpDownPos = -1;
304 var _fileNameMouseMoveTimerHandle = 0;
305 var _fileNameEditing = [
false,
false];
306 var _fileUploadString;
308 var _activePaneIsPrimary = 1;
310 var _undoStackLatestIndex = [-1,-1];
311 var _undoStack_MAX_SIZE = 10;
312 var _undoStack = [[],[]];
314 var _fileHistoryStack = {};
316 var _findAndReplaceCursorInContent = [undefined,undefined];
318 var _fileStringHoverEl = 0;
319 var _fileStringHoverTimeout = 0;
321 var _UPDATE_DECOR_TIMEOUT = 2000;
325 var _READ_ONLY =
false;
326 var _requestPreamble =
"";
331 CodeEditor.editor =
this;
332 Debug.log(
"CodeEditor.editor constructed");
335 this.lastFileNameHistorySelectIndex = -1;
336 this.findAndReplaceFind = [
"",
""];
337 this.findAndReplaceReplace = [
"",
""];
338 this.findAndReplaceScope = [0,0];
339 this.findAndReplaceDirection = [0,0];
340 this.findAndReplaceCaseSensitive = [0,0];
341 this.findAndReplaceWholeWord = [1,1];
342 this.findAndReplaceLastButton = [-1,-1];
346 Debug.log(
"CodeEditor.editor initialized");
353 Debug.log(
"Code Editor init ");
356 var parameterStartFile = [
362 DesktopContent.getParameter(0,
"startFilePrimary"),
363 DesktopContent.getParameter(0,
"startFileSecondary")
365 var parameterGotoLine = [
366 DesktopContent.getParameter(0,
"gotoLinePrimary"),
367 DesktopContent.getParameter(0,
"gotoLineSecondary")
369 var parameterOpenDirectory = [
370 DesktopContent.getParameter(0,
"openDirectoryPrimary"),
371 DesktopContent.getParameter(0,
"openDirectorySecondary")
373 if(parameterOpenDirectory[0] === undefined)
374 parameterOpenDirectory[0] =
"/";
375 if(parameterOpenDirectory[1] === undefined)
376 parameterOpenDirectory[1] =
"/";
378 var parameterViewMode = DesktopContent.getParameter(0,
"startViewMode");
379 if(parameterViewMode !== undefined)
381 _viewMode = parameterViewMode|0;
385 var readOnlyMode = DesktopContent.getParameter(0,
"readOnlyMode");
386 if (readOnlyMode !== undefined)
388 console.log(
"Print Print");
393 console.log(
"parameterStartFile",parameterStartFile);
394 console.log(
"parameterGotoLine",parameterGotoLine);
395 console.log(
"parameterViewMode",parameterViewMode);
396 console.log(
"parameterOpenDirectory", parameterOpenDirectory);
397 console.log(
"_READ_ONLY", _READ_ONLY);
399 if(_READ_ONLY ==
true)
401 _requestPreamble =
"readOnly";
402 appMode =
"Code Viewer";
403 windowTooltip = windowViewModeTooltip;
410 CodeEditor.showTooltip();
417 if(_needEventListeners)
419 window.addEventListener(
"resize",redrawWindow);
420 _needEventListeners =
false;
425 DesktopContent.XMLHttpRequest(
"Request?RequestType=" + _requestPreamble +
427 "&option=getAllowedExtensions"
431 console.log(
"getAllowedExtensions",req);
433 _ALLOWED_FILE_EXTENSIONS = DesktopContent.getXMLValue(req,
"AllowedExtensions");
434 console.log(
"_ALLOWED_FILE_EXTENSIONS",_ALLOWED_FILE_EXTENSIONS);
435 _ALLOWED_FILE_EXTENSIONS = _ALLOWED_FILE_EXTENSIONS.split(
',');
436 console.log(
"_ALLOWED_FILE_EXTENSIONS",_ALLOWED_FILE_EXTENSIONS);
438 DesktopContent.XMLHttpRequest(
"Request?RequestType=" +
440 "&option=getDirectoryContent" +
450 CodeEditor.editor.handleDirectoryContent(1 , req);
451 CodeEditor.editor.handleDirectoryContent(0 , req);
455 if(parameterStartFile[0] && parameterStartFile[0] !=
"")
456 fileSplit = parameterStartFile[0].split(
'.');
460 if(fileSplit.length == 2)
461 CodeEditor.editor.openFile(
466 parameterGotoLine[0 ] );
469 CodeEditor.editor.openDirectory(
471 parameterOpenDirectory[0] ,
479 if(parameterStartFile[1] && parameterStartFile[1] !=
"")
480 fileSplit = parameterStartFile[1].split(
'.');
482 if(fileSplit.length == 2)
483 CodeEditor.editor.openFile(
488 parameterGotoLine[1 ] );
492 CodeEditor.editor.openDirectory(
494 parameterOpenDirectory[1] ,
501 _activePaneIsPrimary = 1;
511 function createElements()
513 Debug.log(
"createElements");
525 var cel,el,al,sl,str;
527 cel = document.getElementById(
"content");
530 cel = document.createElement(
"div");
531 cel.setAttribute(
"id",
"content");
542 for(forPrimary=1;forPrimary >= 0;--forPrimary)
544 el = document.createElement(
"div");
545 el.setAttribute(
"class",
"editorPane");
546 el.setAttribute(
"id",
"editorPane" + forPrimary);
549 str += createTextEditor(forPrimary);
550 str += createDirectoryNav(forPrimary);
551 str += localCreatePaneControls(forPrimary);
558 function localCreatePaneControls(forPrimary)
566 str += htmlOpen(
"div",
568 "class":
"controlsPane",
572 str += htmlOpen(
"div",
574 "id":
"directoryNavToggle",
575 "class":
"controlsButton",
576 "style":
"float:left;",
577 "onclick":
"CodeEditor.editor.toggleDirectoryNav(" + forPrimary +
");",
578 "title":
"Open a file... (Ctrl + D)",
581 str += htmlOpen(
"div",
583 "id":
"directoryNavToggleTop",
586 str += htmlOpen(
"div",
588 "id":
"directoryNavToggleBottom",
595 if (_requestPreamble ==
"readOnly"){
597 str += htmlOpen(
"div",
600 "class":
"controlsButton",
601 "style":
"float:left; display:none;",
602 "onclick":
"CodeEditor.editor.saveFile(" + forPrimary +
");",
603 "title":
"Click to Save the File (Ctrl + S)\nUndo changes (Ctrl + U)\nRedo changes (Shift + Ctrl + U)",
607 str += htmlOpen(
"div",
610 "class":
"controlsButton",
611 "style":
"float:left;",
612 "onclick":
"CodeEditor.editor.saveFile(" + forPrimary +
");",
613 "title":
"Click to Save the File (Ctrl + S)\nUndo changes (Ctrl + U)\nRedo changes (Shift + Ctrl + U)",
617 str += htmlOpen(
"div",
622 str += htmlOpen(
"div",
624 "id":
"saveFileMainTop",
627 str += htmlOpen(
"div",
629 "id":
"saveFileMainBottom",
643 el = document.createElement(
"div");
644 el.setAttribute(
"class",
"controlsPane");
652 str += htmlOpen(
"div",
656 "class":
"controlsButton",
657 "style":
"float:right",
658 "onclick":
"CodeEditor.editor.toggleView();",
659 "title":
"Toggle Verical/Horizontal Split-view (Ctrl + W)",
664 str += htmlOpen(
"div",
666 "id":
"viewToggleRight",
669 str += htmlOpen(
"div",
671 "id":
"viewToggleLeftTop",
674 str += htmlOpen(
"div",
676 "id":
"viewToggleLeftBottom",
683 if (_requestPreamble ==
"readOnly") {
684 str += htmlOpen(
"div",
686 "id":
"incrementalBuild",
687 "class":
"controlsButton",
688 "style":
"float:right; display: none;",
689 "onclick":
"CodeEditor.editor.build(0 /*cleanBuild*/);",
690 "title":
"Incremental Build... (Ctrl + B)",
694 str += htmlOpen(
"div",
696 "id":
"incrementalBuild",
697 "class":
"controlsButton",
698 "style":
"float:right",
699 "onclick":
"CodeEditor.editor.build(0 /*cleanBuild*/);",
700 "title":
"Incremental Build... (Ctrl + B)",
705 str += htmlOpen(
"div",
707 "style":
"margin:11px 0 0 13px;",
713 if (_requestPreamble ==
"readOnly") {
714 str += htmlOpen(
"div",
717 "class":
"controlsButton",
718 "style":
"float:right; display: none;",
719 "onclick":
"CodeEditor.editor.build(1 /*cleanBuild*/);",
720 "title":
"Clean Build... (Ctrl + N)",
724 str += htmlOpen(
"div",
727 "class":
"controlsButton",
728 "style":
"float:right",
729 "onclick":
"CodeEditor.editor.build(1 /*cleanBuild*/);",
730 "title":
"Clean Build... (Ctrl + N)",
735 str += htmlOpen(
"div",
737 "style":
"margin:10px 0 0 13px;",
750 document.body.appendChild(cel);
751 _eel = [document.getElementById(
"editableBox" + 0),
752 document.getElementById(
"editableBox" + 1)];
760 _eel[i].addEventListener(
"input",
765 var forPrimary = this.
id[this.
id.length-1]|0;
766 forPrimary = forPrimary?1:0;
768 Debug.log(
"input forPrimary=" + forPrimary);
770 _fileWasModified[forPrimary] =
true;
771 CodeEditor.editor.updateLastSave(forPrimary);
773 CodeEditor.editor.startUpdateHandling(forPrimary);
777 _eel[i].addEventListener(
"keydown",
780 if(e.keyCode == 91 || e.keyCode == 93 ||
782 _commandKeyDown =
true;
784 var forPrimary =
this.id[
this.id.length-1]|0;
785 forPrimary = forPrimary?1:0;
788 CodeEditor.editor.keyDownHandler(e,forPrimary);
792 _eel[i].addEventListener(
"keyup",
795 if(e.keyCode == 91 || e.keyCode == 93 ||
797 _commandKeyDown =
false;
800 _eel[i].addEventListener(
"click",
806 Debug.log(
"Special mouse click handling");
816 _eel[i].addEventListener(
"dblclick",
820 var forPrimary = this.
id[this.
id.length-1]|0;
821 forPrimary = forPrimary?1:0;
823 Debug.log(
"dblclick handler for editor" + forPrimary);
826 CodeEditor.editor.doubleClickHandler(forPrimary);
829 _eel[i].addEventListener(
"contextmenu",
835 Debug.log(
"Special context menu handling");
844 _eel[i].addEventListener(
"mousedown",
849 Debug.log(
"Special mouse down handling");
856 CodeEditor.editor.stopUpdateHandling(e);
858 var forPrimary = this.
id[this.
id.length-1]|0;
859 forPrimary = forPrimary?1:0;
861 Debug.log(
"mousedown handler for editor" + forPrimary +
" " + e.which);
864 if(_activePaneIsPrimary != forPrimary)
865 CodeEditor.editor.updateDualView(!forPrimary);
867 _activePaneIsPrimary = forPrimary;
872 _eel[i].addEventListener(
"mouseup",
875 var forPrimary = this.
id[this.
id.length-1]|0;
876 forPrimary = forPrimary?1:0;
878 Debug.log(
"mouseup handler for editor" + forPrimary);
882 Debug.log(
"Special mouse up handling");
889 CodeEditor.editor.startUpdateHandling(forPrimary);
894 box = document.getElementById(
"editorPane" + i);
895 box.addEventListener(
"click",
898 var forPrimary = this.
id[this.
id.length-1]|0;
899 forPrimary = forPrimary?1:0;
901 Debug.log(
"click handler for pane" + forPrimary);
905 if(_activePaneIsPrimary != forPrimary)
906 CodeEditor.editor.updateDualView(!forPrimary);
908 _activePaneIsPrimary = forPrimary;
911 CodeEditor.editor.showFindAndReplaceSelection(forPrimary);
914 var el = document.getElementById(
"textEditorBody" + forPrimary);
915 var scrollLeft = el.scrollLeft;
916 var scrollTop = el.scrollTop;
918 _eel[forPrimary].focus();
920 el.scrollLeft = scrollLeft;
921 el.scrollTop = scrollTop;
930 box.addEventListener(
"keydown",
933 if(e.keyCode == 91 || e.keyCode == 93 ||
935 _commandKeyDown =
true;
937 var forPrimary = _activePaneIsPrimary;
938 Debug.log(
"keydown handler for body" + forPrimary);
939 CodeEditor.editor.keyDownHandler(e,forPrimary,
true );
942 box.addEventListener(
"keyup",
945 if(e.keyCode == 91 || e.keyCode == 93 ||
947 _commandKeyDown =
false;
949 box.addEventListener(
"mouseover",
953 if(_fileStringHoverEl.parentNode)
955 Debug.log(
"body removing string hover");
956 window.clearTimeout(_fileStringHoverTimeout);
957 _fileStringHoverTimeout = window.setTimeout(
960 Debug.log(
"body removed string hover");
963 _fileStringHoverEl.parentNode.removeChild(_fileStringHoverEl);
976 function createTextEditor(forPrimary)
978 forPrimary = forPrimary?1:0;
980 Debug.log(
"createTextEditor forPrimary=" + forPrimary);
984 str += htmlOpen(
"div",
986 "class":
"textEditor",
987 "id":
"textEditor" + forPrimary,
988 "style":
"overflow:hidden;",
997 str += htmlOpen(
"div",
999 "class":
"textEditorHeader",
1000 "id":
"textEditorHeader" + forPrimary,
1004 str += htmlOpen(
"div",
1006 "class":
"textEditorBody",
1007 "id":
"textEditorBody" + forPrimary,
1010 str +=
"<table class='editableBoxTable' style='margin-bottom:200px'>" +
1011 "<tr><td valign='top'>";
1012 str += htmlOpen(
"div",
1014 "class":
"editableBoxLeftMargin",
1015 "id":
"editableBoxLeftMargin" + forPrimary,
1016 },
"0\n1\n2" ,
true );
1017 str +=
"</td><td valign='top'>";
1018 str += htmlOpen(
"div",
1020 "class":
"editableBox",
1021 "id":
"editableBox" + forPrimary,
1022 "contenteditable":
"true",
1023 "autocomplete":
"off",
1024 "autocorrect":
"off",
1025 "autocapitalize":
"off",
1026 "spellcheck":
"false",
1028 str +=
"</td></tr></table>";
1039 function createDirectoryNav(forPrimary)
1041 forPrimary = forPrimary?1:0;
1043 Debug.log(
"createDirectoryNav forPrimary=" + forPrimary);
1047 str += htmlOpen(
"div",
1049 "class":
"directoryNav",
1050 "id":
"directoryNav" + forPrimary,
1051 },
"Directory" , 1 );
1060 function redrawWindow()
1065 var w = window.innerWidth | 0;
1066 var h = window.innerHeight | 0;
1068 if(w < _WINDOW_MIN_SZ)
1070 if(h < _WINDOW_MIN_SZ)
1073 Debug.log(
"redrawWindow to " + w +
" - " + h);
1075 var eps = document.getElementsByClassName(
"editorPane");
1076 var epHdrs = document.getElementsByClassName(
"textEditorHeader");
1077 var epBdys = document.getElementsByClassName(
"textEditorBody");
1078 var dns = document.getElementsByClassName(
"directoryNav");
1082 eps[0].style.position =
"absolute";
1083 eps[1].style.position =
"absolute";
1085 var DIR_NAV_MARGIN = 50;
1086 var EDITOR_MARGIN = 20;
1087 var EDITOR_HDR_H = 56;
1092 rect = [{
"left":0,
"top":0,
"w":w,
"h":h},
1097 rect = [{
"left":0,
"top":0,
"w":((w/2)|0),
"h":h},
1098 {
"left":((w/2)|0),
"top":0,
"w":(w-((w/2)|0)),
"h":h}];
1103 rect = [{
"left":0,
"top":0,
"h":((h/2)|0),
"w":w},
1104 {
"top":((h/2)|0),
"left":0,
"h":(h-((h/2)|0)),
"w":w}];
1108 Debug.log(
"Invalid view mode encountered: " + _viewMode);
1112 for(var i=0;i<2;++i)
1116 eps[i].style.display =
"none";
1120 dns[i].style.left = (DIR_NAV_MARGIN) +
"px";
1121 dns[i].style.top = (DIR_NAV_MARGIN) +
"px";
1122 dns[i].style.width = (rect[i].w - 2*DIR_NAV_MARGIN) +
"px";
1123 dns[i].style.height = (rect[i].h - 2*DIR_NAV_MARGIN) +
"px";
1125 eps[i].style.left = rect[i].left +
"px";
1126 eps[i].style.top = rect[i].top +
"px";
1127 eps[i].style.height = rect[i].h +
"px";
1128 eps[i].style.width = rect[i].w +
"px";
1130 epHdrs[i].style.left = EDITOR_MARGIN +
"px";
1131 epHdrs[i].style.top = (DIR_NAV_MARGIN - 2*EDITOR_MARGIN) +
"px";
1132 epHdrs[i].style.height = (EDITOR_HDR_H + 2*EDITOR_MARGIN) +
"px";
1133 epHdrs[i].style.width = (rect[i].w - 2*EDITOR_MARGIN) +
"px";
1136 epBdys[i].style.left = 0 +
"px";
1137 epBdys[i].style.top = (DIR_NAV_MARGIN + EDITOR_HDR_H) +
"px";
1138 epBdys[i].style.height = (rect[i].h - DIR_NAV_MARGIN - EDITOR_HDR_H) +
"px";
1139 epBdys[i].style.width = (rect[i].w - 0) +
"px";
1141 eps[i].style.display =
"block";
1150 this.toggleView =
function(v)
1155 _viewMode = (_viewMode+1)%3;
1156 Debug.log(
"toggleView _viewMode=" + _viewMode);
1163 this.toggleDirectoryNav =
function(forPrimary, v)
1165 forPrimary = forPrimary?1:0;
1166 _activePaneIsPrimary = forPrimary;
1168 Debug.log(
"toggleDirectoryNav forPrimary=" + forPrimary);
1171 _navMode[forPrimary] = v?1:0;
1173 _navMode[forPrimary] = _navMode[forPrimary]?0:1;
1174 Debug.log(
"toggleDirectoryNav _navMode=" + _navMode[forPrimary]);
1176 var el = document.getElementById(
"directoryNav" + forPrimary);
1177 var wasHidden = el.style.display ==
"none";
1179 _navMode[forPrimary]?
"block":
"none";
1181 if(_navMode[forPrimary] && wasHidden)
1183 var paths = document.getElementById(
"directoryNav" +
1184 forPrimary).getElementsByClassName(
"dirNavPath");
1185 var buildPath =
"/";
1186 for(var i=1;i<paths.length;++i)
1187 buildPath += (i>1?
"/":
"") + paths[i].textContent;
1188 Debug.log(
"refresh " + buildPath);
1190 CodeEditor.editor.openDirectory(forPrimary,buildPath);
1197 this.saveFile =
function(forPrimary, quiet)
1199 forPrimary = forPrimary?1:0;
1201 Debug.log(
"saveFile forPrimary=" + forPrimary);
1203 Debug.log(
"saveFile _filePath=" + _filePath[forPrimary]);
1204 Debug.log(
"saveFile _fileExtension=" + _fileExtension[forPrimary]);
1206 if(_filePath[forPrimary] ==
"")
1208 Debug.log(
"Error, can not save to empty file name!",
1209 Debug.HIGH_PRIORITY);
1215 DesktopContent.popUpVerification(
1216 "Are you sure you want to save...<br>" +
1217 _filePath[forPrimary] +
"." + _fileExtension[forPrimary] +
"?",
1219 undefined,undefined,undefined,
1220 undefined,undefined,
1228 function localDoIt()
1232 var textObj = {
"text":
1233 _eel[forPrimary].innerText,
1240 textObj.text = textObj.text.replace(/%20%20/g,
"%20%20").replace(/%20/g,
1241 "%20").replace(/%20/g,
"%20").replace(/%20/g,
"%20");
1245 DesktopContent.XMLHttpRequest(
"Request?RequestType=codeEditor" +
1246 "&option=saveFileContent" +
1247 "&path=" + _filePath[forPrimary] +
1248 "&ext=" + _fileExtension[forPrimary]
1249 ,
"content=" + encodeURIComponent(textObj.text) ,
1252 Debug.log(
"Successfully saved " +
1253 _filePath[forPrimary] +
"." +
1254 _fileExtension[forPrimary],quiet?Debug.LOW_PRIORITY:Debug.INFO_PRIORITY);
1256 _fileWasModified[forPrimary] =
false;
1257 textObj.time = Date.now();
1258 _fileLastSave[forPrimary] = textObj.time;
1261 CodeEditor.editor.updateLastSave(forPrimary);
1263 if(_filePath[0] == _filePath[1] &&
1264 _fileExtension[0] == _fileExtension[1])
1266 CodeEditor.editor.updateDualView(forPrimary);
1268 CodeEditor.editor.updateFileSnapshot(!forPrimary,
1274 CodeEditor.editor.updateFileSnapshot(forPrimary,
1286 this.build =
function(cleanBuild)
1288 cleanBuild = cleanBuild?1:0;
1290 Debug.log(
"build cleanBuild=" + cleanBuild);
1294 DesktopContent.popUpVerification(
1295 "Are you sure you want to do a clean build?!",
1303 function localDoIt()
1305 DesktopContent.XMLHttpRequest(
"Request?RequestType=codeEditor" +
1307 "&clean=" + (cleanBuild?1:0)
1311 Debug.log(
"Build was launched! Check " +
1312 "<a onclick='DesktopContent.openNewBrowserTab(" +
1314 "title='Click to open the Console web app in a new browser tab.'>" +
1315 "console</a> for result!", Debug.INFO_PRIORITY);
1325 this.undo =
function(forPrimary,redo)
1327 DesktopContent.showLoading(localDoIt);
1330 function localDoIt()
1332 forPrimary = forPrimary?1:0;
1334 Debug.log(
"undo() forPrimary=" + forPrimary +
" redo=" + redo);
1335 console.log(
"undo stack index",_undoStackLatestIndex[forPrimary]);
1336 console.log(
"undo stack length",_undoStack[forPrimary].length);
1338 console.log(
"undo stack",_undoStack[forPrimary]);
1340 var el = _eel[forPrimary];
1343 CodeEditor.editor.updateFileSnapshot(forPrimary,
1344 {
"text":el.textContent,
1348 var newIndex = _undoStackLatestIndex[forPrimary];
1349 newIndex += redo?1:-1;
1350 if(newIndex >= _undoStack_MAX_SIZE)
1352 else if(newIndex < 0)
1353 newIndex = _undoStack[forPrimary].length-1;
1355 console.log(
"new stack index",newIndex);
1359 _undoStack[forPrimary][newIndex][1] >=
1360 _undoStack[forPrimary][_undoStackLatestIndex[forPrimary]][1])
1362 Debug.log(
"Reached end of undo history...",Debug.WARN_PRIORITY);
1366 (newIndex >= _undoStack[forPrimary].length ||
1367 _undoStack[forPrimary][newIndex][1] <=
1368 _undoStack[forPrimary][_undoStackLatestIndex[forPrimary]][1]))
1370 Debug.log(
"Reached end of redo history...",Debug.WARN_PRIORITY);
1375 _undoStackLatestIndex[forPrimary] = newIndex;
1376 console.log(
"result stack index",newIndex);
1378 var cursor = CodeEditor.editor.getCursor(el);
1381 _undoStack[forPrimary][_undoStackLatestIndex[forPrimary]][0];
1382 _fileWasModified[forPrimary] =
true;
1384 CodeEditor.editor.updateDecorations(forPrimary,
1388 CodeEditor.editor.setCursor(el,cursor,
true );
1395 this.handleDirectoryContent =
function(forPrimary,req)
1397 forPrimary = forPrimary?1:0;
1399 Debug.log(
"handleDirectoryContent forPrimary=" + forPrimary);
1402 var path = DesktopContent.getXMLValue(req,
"path");
1403 if(path ==
"/") path =
"";
1405 var specials = req.responseXML.getElementsByTagName(
"special");
1406 var dirs = req.responseXML.getElementsByTagName(
"directory");
1407 var files = req.responseXML.getElementsByTagName(
"file");
1408 var specialFiles = req.responseXML.getElementsByTagName(
"specialFile");
1410 Debug.log(
"handleDirectoryContent path=" + path);
1411 console.log(dirs);console.log(files);
1416 str += htmlOpen(
"div",
1418 "style":
"margin:20px;" +
1419 "white-space: nowrap;",
1425 var pathSplit = path.split(
'/');
1429 str +=
"Path: <a class='dirNavPath' onclick='CodeEditor.editor.openDirectory(" +
1430 forPrimary +
",\"" +
1436 for(i=0;i<pathSplit.length;++i)
1438 pathSplitName = pathSplit[i].trim();
1439 if(pathSplitName ==
"")
continue;
1440 Debug.log(
"pathSplitName " + pathSplitName);
1442 buildPath +=
"/" + pathSplitName;
1445 str +=
"<a class='dirNavPath' onclick='CodeEditor.editor.openDirectory(" +
1446 forPrimary +
",\"" +
1448 ")' title='Open folder: \nsrcs" + buildPath +
1450 pathSplitName +
"</a>";
1456 str += htmlOpen(
"a",
1458 "title":
"Open folder in the other editor pane of the split-view: \n" +
1460 "onclick":
"CodeEditor.editor.openDirectory(" +
1461 (!forPrimary) +
",\"" +
1464 "<img class='dirNavFileNewWindowImgNewPane' " +
1465 "src='/WebPath/images/windowContentImages/CodeEditor-openInOtherPane.png'>"
1469 str += htmlOpen(
"a",
1471 "title":
"Open folder in a new browser tab: \n" +
1473 "onclick":
"DesktopContent.openNewBrowserTab(" +
1474 "\"Code Editor\",\"\"," +
1475 "\"/WebPath/html/CodeEditor.html?urn=" +
1476 DesktopContent._localUrnLid +
"&" +
1477 "openDirectoryPrimary=" +
1478 buildPath +
"\",0 /*unique*/);' ",
1480 "<img class='dirNavFileNewWindowImgNewWindow' " +
1481 "src='/WebPath/images/windowContentImages/CodeEditor-openInNewWindow.png'>"
1490 for(i=0;i<specials.length;++i)
1492 name = specials[i].getAttribute(
'value');
1495 str += htmlOpen(
"a",
1497 "title":
"Open folder in a new browser tab: \n" +
1498 "srcs" + path +
"/" + name,
1499 "onclick":
"DesktopContent.openNewBrowserTab(" +
1500 "\"Code Editor\",\"\"," +
1501 "\"/WebPath/html/CodeEditor.html?urn=" +
1502 DesktopContent._localUrnLid +
"&" +
1503 "openDirectoryPrimary=" +
1504 path +
"/" + name +
"\",0 /*unique*/);' ",
1506 "<img class='dirNavFileNewWindowImgNewWindow' " +
1507 "src='/WebPath/images/windowContentImages/CodeEditor-openInNewWindow.png'>"
1511 str += htmlOpen(
"a",
1513 "title":
"Open folder in the other editor pane of the split-view: \n" +
1514 "srcs" + path +
"/" + name,
1515 "onclick":
"CodeEditor.editor.openDirectory(" +
1516 (!forPrimary) +
",\"" +
1517 path +
"/" + name +
"\");",
1519 "<img class='dirNavFileNewWindowImgNewPane' " +
1520 "src='/WebPath/images/windowContentImages/CodeEditor-openInOtherPane.png'>"
1524 str +=
"<a class='dirNavSpecial' onclick='CodeEditor.editor.openDirectory(" +
1525 forPrimary +
",\"" +
1526 path +
"/" + name +
"\"" +
1527 ")' title='Open folder: \nsrcs" + path +
"/" + name +
"' >" +
1537 if(specialFiles.length)
1540 str +=
"<tr><th>" + path.substr(1,path.length-2) +
" Files</th><th style='padding-left:20px'>Repository</th></tr>";
1542 for(i=0;i<specialFiles.length;++i)
1544 name = specialFiles[i].getAttribute(
'value');
1549 str += htmlOpen(
"a",
1551 "title":
"Open file in a new browser tab: \n" +
1553 "onclick":
"DesktopContent.openNewBrowserTab(" +
1554 "\"Code Editor\",\"\"," +
1555 "\"/WebPath/html/CodeEditor.html?urn=" +
1556 DesktopContent._localUrnLid +
"&" +
1557 "startFilePrimary=" +
1558 name +
"\",0 /*unique*/);' ",
1560 "<img class='dirNavFileNewWindowImgNewWindow' " +
1561 "src='/WebPath/images/windowContentImages/CodeEditor-openInNewWindow.png'>"
1565 str += htmlOpen(
"a",
1567 "title":
"Open file in the other editor pane of the split-view: \n" +
1569 "onclick":
"CodeEditor.editor.openFile(" +
1570 (!forPrimary) +
",\"" +
1572 name.substr(name.lastIndexOf(
'.')+1) +
"\"" +
1575 "<img class='dirNavFileNewWindowImgNewPane' " +
1576 "src='/WebPath/images/windowContentImages/CodeEditor-openInOtherPane.png'>"
1580 str +=
"<a class='dirNavFile' onclick='CodeEditor.editor.openFile(" +
1581 forPrimary +
",\"" +
1583 name.substr(name.lastIndexOf(
'.')+1) +
"\"" +
1584 ")' title='Open file: \nsrcs" + name +
"' >";
1585 nameSplit = name.split(
'/');
1586 str += nameSplit[nameSplit.length-1] +
"</a>";
1590 str +=
"</td><td style='padding-left:20px'>" + nameSplit[1] +
"</td></tr>";
1593 if(specialFiles.length)
1599 for(i=0;i<dirs.length;++i)
1601 name = dirs[i].getAttribute(
'value');
1604 str += htmlOpen(
"a",
1606 "title":
"Open file in a new browser tab: \n" +
1607 "srcs" + path +
"/" + name,
1608 "onclick":
"DesktopContent.openNewBrowserTab(" +
1609 "\"Code Editor\",\"\"," +
1610 "\"/WebPath/html/CodeEditor.html?urn=" +
1611 DesktopContent._localUrnLid +
"&" +
1612 "openDirectoryPrimary=" +
1613 path +
"/" + name +
"\",0 /*unique*/);' ",
1615 "<img class='dirNavFileNewWindowImgNewWindow' " +
1616 "src='/WebPath/images/windowContentImages/CodeEditor-openInNewWindow.png'>"
1620 str += htmlOpen(
"a",
1622 "title":
"Open folder in the other editor pane of the split-view: \n" +
1623 "srcs" + path +
"/" + name,
1624 "onclick":
"CodeEditor.editor.openDirectory(" +
1625 (!forPrimary) +
",\"" +
1626 path +
"/" + name +
"\");",
1628 "<img class='dirNavFileNewWindowImgNewPane' " +
1629 "src='/WebPath/images/windowContentImages/CodeEditor-openInOtherPane.png'>"
1633 str +=
"<a class='dirNavFolder' onclick='CodeEditor.editor.openDirectory(" +
1634 forPrimary +
",\"" +
1635 path +
"/" + name +
"\"" +
1636 ")' title='Open folder: \nsrcs" + path +
"/" + name +
"' >" +
1645 for(i=0;i<files.length;++i)
1647 name = files[i].getAttribute(
'value');
1650 str += htmlOpen(
"a",
1652 "title":
"Open file in a new browser tab: \n" +
1653 "srcs" + path +
"/" + name,
1654 "onclick":
"DesktopContent.openNewBrowserTab(" +
1655 "\"Code Editor\",\"\"," +
1656 "\"/WebPath/html/CodeEditor.html?urn=" +
1657 DesktopContent._localUrnLid +
"&" +
1658 "startFilePrimary=" +
1659 path +
"/" + name +
"\",0 /*unique*/);' ",
1661 "<img class='dirNavFileNewWindowImgNewWindow' " +
1662 "src='/WebPath/images/windowContentImages/CodeEditor-openInNewWindow.png'>"
1666 str += htmlOpen(
"a",
1668 "title":
"Open file in the other editor pane of the split-view: \n" +
1669 "srcs" + path +
"/" + name,
1670 "onclick":
"CodeEditor.editor.openFile(" +
1671 (!forPrimary) +
",\"" +
1672 path +
"/" + name +
"\", \"" +
1673 name.substr(name.lastIndexOf(
'.')+1) +
"\"" +
1676 "<img class='dirNavFileNewWindowImgNewPane' " +
1677 "src='/WebPath/images/windowContentImages/CodeEditor-openInOtherPane.png'>"
1682 str +=
"<a class='dirNavFile' onclick='CodeEditor.editor.openFile(" +
1683 forPrimary +
",\"" +
1684 path +
"/" + name +
"\", \"" +
1685 name.substr(name.lastIndexOf(
'.')+1) +
"\"" +
1686 ")' title='Open file: \nsrcs" + path +
"/" + name +
"' >" +
1695 document.getElementById(
"directoryNav" + forPrimary).innerHTML = str;
1701 this.openDirectory =
function(forPrimary,path,doNotOpenPane)
1703 forPrimary = forPrimary?1:0;
1705 if(!path || path ==
"") path =
"/";
1706 Debug.log(
"openDirectory forPrimary=" + forPrimary +
1710 DesktopContent.XMLHttpRequest(
"Request?RequestType=codeEditor" +
1711 "&option=getDirectoryContent" +
1716 CodeEditor.editor.handleDirectoryContent(forPrimary, req);
1717 CodeEditor.editor.toggleDirectoryNav(forPrimary,1 );
1721 if(!doNotOpenPane && !forPrimary && _viewMode == 0)
1722 CodeEditor.editor.toggleView();
1730 this.openRelatedFile =
function(forPrimary,inOtherPane)
1732 Debug.log(
"openRelatedFile forPrimary=" + forPrimary +
1733 " path=" + _filePath[forPrimary]);
1735 var relatedPath = _filePath[forPrimary];
1736 var relatedExtension = _fileExtension[forPrimary];
1737 var targetPane = inOtherPane?!forPrimary:forPrimary;
1740 var altExtensions = [];
1742 if(relatedExtension ==
"html")
1744 relatedExtension =
"js";
1745 var i = relatedPath.indexOf(
"/html/");
1748 altPaths.push(relatedPath.substr(0,i) +
"/css/" +
1749 relatedPath.substr(i + (
"/html/").length));
1750 altExtensions.push(
"css");
1752 relatedPath = relatedPath.substr(0,i) +
"/js/" +
1753 relatedPath.substr(i + (
"/html/").length);
1757 altPaths.push(relatedPath);
1758 altExtensions.push(
"css");
1761 CodeEditor.editor.openFile(targetPane,relatedPath,relatedExtension,
1762 undefined , undefined,
1763 altPaths , altExtensions);
1766 else if(relatedExtension[0] ==
"h")
1768 relatedExtension =
"cc";
1770 altPaths.push(relatedPath);
1771 altExtensions.push(
"cc");
1773 altPaths.push(relatedPath+
"_interface");
1774 altExtensions.push(
"cc");
1775 altPaths.push(relatedPath+
"_processor");
1776 altExtensions.push(
"cc");
1777 altPaths.push(relatedPath+
"_controls");
1778 altExtensions.push(
"cc");
1779 altPaths.push(relatedPath+
"_table");
1781 altPaths.push(relatedPath);
1782 altExtensions.push(
"cpp");
1783 altPaths.push(relatedPath);
1784 altExtensions.push(
"CC");
1785 altPaths.push(relatedPath);
1786 altExtensions.push(
"cxx");
1787 altPaths.push(relatedPath);
1788 altExtensions.push(
"c");
1789 altPaths.push(relatedPath);
1790 altExtensions.push(
"C");
1791 altPaths.push(relatedPath);
1792 altExtensions.push(
"icc");
1795 if(relatedPath.indexOf(
"Interface") >= 0)
1796 relatedPath +=
"_interface";
1797 else if(relatedPath.indexOf(
"Processor") >= 0)
1798 relatedPath +=
"_processor";
1799 else if(relatedPath.indexOf(
"Consumer") >= 0)
1800 relatedPath +=
"_processor";
1801 else if(relatedPath.indexOf(
"Producer") >= 0)
1802 relatedPath +=
"_processor";
1803 else if(relatedPath.indexOf(
"Controls") >= 0)
1804 relatedPath +=
"_controls";
1805 else if(relatedPath.indexOf(
"Table") >= 0)
1806 relatedPath +=
"_table";
1808 CodeEditor.editor.openFile(targetPane,relatedPath,relatedExtension,
1809 undefined , undefined,
1810 altPaths , altExtensions);
1813 else if(relatedExtension ==
"css")
1815 relatedExtension =
"js";
1816 var i = relatedPath.indexOf(
"/css/");
1820 altPaths.push(relatedPath.substr(0,i) +
"/html/" +
1821 relatedPath.substr(i + (
"/css/").length));
1822 altExtensions.push(
"html");
1824 relatedPath = relatedPath.substr(0,i) +
"/js/" +
1825 relatedPath.substr(i + (
"/css/").length);
1829 altPaths.push(relatedPath);
1830 altExtensions.push(
"html");
1833 CodeEditor.editor.openFile(targetPane,relatedPath,relatedExtension,
1834 undefined , undefined,
1835 altPaths , altExtensions);
1838 else if(relatedExtension[0] ==
'c' ||
1839 relatedExtension[0] ==
'C' ||
1840 relatedExtension ==
"icc")
1842 relatedExtension =
"h";
1844 altPaths.push(relatedPath);
1845 altExtensions.push(
"h");
1848 if((i = relatedPath.indexOf(
"_interface")) > 0 &&
1849 i == relatedPath.length-(
"_interface").length)
1850 relatedPath = relatedPath.substr(0,i);
1851 if((i = relatedPath.indexOf(
"_processor")) > 0 &&
1852 i == relatedPath.length-(
"_processor").length)
1853 relatedPath = relatedPath.substr(0,i);
1854 if((i = relatedPath.indexOf(
"_controls")) > 0 &&
1855 i == relatedPath.length-(
"_controls").length)
1856 relatedPath = relatedPath.substr(0,i);
1857 if((i = relatedPath.indexOf(
"_table")) > 0 &&
1858 i == relatedPath.length-(
"_table").length)
1859 relatedPath = relatedPath.substr(0,i);
1861 altPaths.push(relatedPath);
1862 altExtensions.push(
"hh");
1863 altPaths.push(relatedPath);
1864 altExtensions.push(
"hpp");
1865 altPaths.push(relatedPath);
1866 altExtensions.push(
"hxx");
1867 altPaths.push(relatedPath);
1868 altExtensions.push(
"H");
1870 CodeEditor.editor.openFile(targetPane,relatedPath,relatedExtension,
1871 undefined , undefined,
1872 altPaths , altExtensions);
1875 else if(relatedExtension ==
"js")
1877 relatedExtension =
"css";
1878 var i = relatedPath.indexOf(
"/js/");
1882 altPaths.push(relatedPath.substr(0,i) +
"/html/" +
1883 relatedPath.substr(i + (
"/js/").length));
1884 altExtensions.push(
"html");
1886 relatedPath = relatedPath.substr(0,i) +
"/css/" +
1887 relatedPath.substr(i + (
"/js/").length);
1891 altPaths.push(relatedPath);
1892 altExtensions.push(
"html");
1895 CodeEditor.editor.openFile(targetPane,relatedPath,relatedExtension,
1896 undefined , undefined,
1897 altPaths , altExtensions);
1901 Debug.log(
"Giving up on attempt to open a related file for " +
1902 relatedPath +
"." + relatedExtension +
1903 "... no known related file.", Debug.HIGH_PRIORITY);
1914 this.openFile =
function(forPrimary,path,extension,doConfirm,gotoLine,
1915 altPaths,altExtensions,propagateErr)
1917 forPrimary = forPrimary?1:0;
1919 Debug.log(
"openFile forPrimary=" + forPrimary +
1921 var i = path.lastIndexOf(
'.');
1923 path = path.substr(0,i);
1925 if(!propagateErr) propagateErr =
"";
1929 DesktopContent.popUpVerification(
1930 "Do you want to reload the file from the server (and discard your changes)?",
1938 var keys = Object.keys(_fileHistoryStack);
1939 var filename = path +
"." + extension;
1940 for(i;i<keys.length;++i)
1941 if(filename == keys[i])
1943 Debug.log(
"Found " + filename +
" in file history.");
1948 fileObj.path = path;
1949 fileObj.extension = extension;
1950 fileObj.text = _fileHistoryStack[filename][0];
1951 fileObj.fileWasModified = _fileHistoryStack[filename][2];
1952 fileObj.fileLastSave = _fileHistoryStack[filename][3];
1954 console.log(
"fileObj",fileObj);
1956 CodeEditor.editor.handleFileContent(forPrimary,0,fileObj);
1958 CodeEditor.editor.toggleDirectoryNav(forPrimary,
false );
1961 if(!forPrimary && _viewMode == 0)
1962 CodeEditor.editor.toggleView();
1970 function localDoIt()
1972 CodeEditor.editor.toggleDirectoryNav(forPrimary,
false );
1974 DesktopContent.XMLHttpRequest(
"Request?RequestType=codeEditor" +
1975 "&option=getFileContent" +
1982 var err = DesktopContent.getXMLValue(req,
"Error");
1985 if(altPaths && altPaths.length &&
1986 altExtensions && altExtensions.length)
1989 CodeEditor.editor.openFile(forPrimary,
1990 altPaths.splice(0,1)[0],
1991 altExtensions.splice(0,1)[0],
1992 undefined , undefined,
1993 altPaths , altExtensions,
1994 propagateErr + err );
1997 Debug.log(propagateErr + err,Debug.HIGH_PRIORITY);
2006 CodeEditor.editor.toggleDirectoryNav(forPrimary,0 );
2007 CodeEditor.editor.handleFileContent(forPrimary, req);
2010 if(!forPrimary && _viewMode == 0)
2011 CodeEditor.editor.toggleView();
2013 if(gotoLine !== undefined)
2014 CodeEditor.editor.gotoLine(forPrimary,gotoLine);
2018 Debug.log(
"Ignoring error handling file open: " + e);
2020 console.log(DesktopContent._loadBox.style.display);
2030 this.getLine =
function(forPrimary)
2032 Debug.log(
"getLine() forPrimary=" + forPrimary);
2035 var el = _eel[forPrimary];
2036 var cursor = CodeEditor.editor.getCursor(el);
2038 if(cursor.startNodeIndex === undefined)
2040 Debug.log(
"No cursor, so defaulting to top");
2046 for(n=0; n<el.childNodes.length; ++n)
2048 node = el.childNodes[n];
2049 val = node.textContent;
2052 for(i=0;i<val.length;++i)
2055 if(!cursor.focusAtEnd &&
2056 n == cursor.startNodeIndex &&
2057 i == cursor.startPos)
2059 else if(cursor.focusAtEnd &&
2060 n == cursor.endNodeIndex &&
2069 if(!cursor.focusAtEnd &&
2070 n == cursor.startNodeIndex)
2072 Debug.log(
"Found cursor at line " + cursor.line);
2075 else if(cursor.focusAtEnd &&
2076 n == cursor.endNodeIndex)
2078 Debug.log(
"Found cursor at line " + cursor.line);
2088 this.gotoLine =
function(forPrimary,line,selectionCursor,topOfView)
2091 if(line < 1) line = 1;
2092 if(line > _numberOfLines[forPrimary])
2093 line = _numberOfLines[forPrimary];
2094 console.log(
"Goto line number ",line,selectionCursor);
2097 window.location.href =
"#" + forPrimary +
"L" + line;
2103 var el = _eel[forPrimary];
2110 "startNodeIndex": 0,
2119 cursor.endNodeIndex = selectionCursor.startNodeIndex;
2120 cursor.endPos = selectionCursor.startPos;
2121 cursor.focusAtEnd = selectionCursor.focusAtEnd;
2123 CodeEditor.editor.setCursor(el,cursor,
true );
2128 var i,n,node,el,val;
2131 var newLine =
false;
2135 for(n=0; n<el.childNodes.length; ++n)
2137 node = el.childNodes[n];
2138 val = node.textContent;
2141 for(i=0;i<val.length;++i)
2150 if(line == lineCount)
2153 Debug.log(
"Found line " + line);
2171 "startNodeIndex":lastNode,
2173 "endNodeIndex":lastNode,
2181 cursor.focusAtEnd = selectionCursor.focusAtEnd;
2183 if(lastNode < selectionCursor.startNodeIndex ||
2184 ( lastNode == selectionCursor.startNodeIndex &&
2185 lastPos < selectionCursor.startPos))
2187 cursor.endNodeIndex = selectionCursor.startNodeIndex;
2188 cursor.endPos = selectionCursor.startPos;
2192 cursor.startNodeIndex = selectionCursor.startNodeIndex;
2193 cursor.startPos = selectionCursor.startPos;
2197 CodeEditor.editor.setCursor(el,cursor,
2203 CodeEditor.editor.setCursor(el,cursor,
true );
2215 this.handleFileContent =
function(forPrimary,req,fileObj)
2217 forPrimary = forPrimary?1:0;
2219 Debug.log(
"handleFileContent forPrimary=" + forPrimary);
2225 var fileWasModified, fileLastSave;
2229 path = DesktopContent.getXMLValue(req,
"path");
2230 extension = DesktopContent.getXMLValue(req,
"ext");
2231 text = DesktopContent.getXMLValue(req,
"content");
2232 fileWasModified =
false;
2237 path = fileObj.path;
2238 extension = fileObj.extension;
2239 text = fileObj.text;
2240 fileWasModified = fileObj.fileWasModified;
2241 fileLastSave = fileObj.fileLastSave;
2246 text = text.replace(
new RegExp(
2247 String.fromCharCode(160),
'g'),
' ');
2251 _filePath[forPrimary] = path;
2252 _fileExtension[forPrimary] = extension;
2253 _fileWasModified[forPrimary] = fileWasModified;
2254 _fileLastSave[forPrimary] = fileLastSave;
2256 _undoStack[forPrimary] = [];
2257 _undoStackLatestIndex[forPrimary] = -1;
2259 var el = _eel[forPrimary];
2262 DesktopContent.showLoading(
function()
2266 el.textContent = text;
2267 CodeEditor.editor.displayFileHeader(forPrimary);
2270 { Debug.log(
"Ignoring error: " + e); }
2277 this.setCursor =
function(el,inCursor,scrollIntoView)
2279 if(inCursor.startNodeIndex !== undefined)
2283 "startNodeIndex": inCursor.startNodeIndex,
2284 "startPos": inCursor.startPos,
2285 "endNodeIndex": inCursor.endNodeIndex,
2286 "endPos": inCursor.endPos,
2287 "focusAtEnd": inCursor.focusAtEnd,
2291 var scrollEndIntoView = cursor.focusAtEnd?
true:
false;
2295 console.log(
"set cursor",cursor,
"scrollIntoView=",scrollIntoView,
2296 "scrollEndIntoView=",scrollEndIntoView);
2298 var range = document.createRange();
2300 var firstEl = el.childNodes[cursor.startNodeIndex];
2304 var secondEl = el.childNodes[cursor.endNodeIndex];
2310 Debug.log(
"scrollIntoView");
2319 Debug.log(
"inserting scroll 2nd element");
2323 var val = secondEl.textContent;
2324 var newNode1 = document.createTextNode(
2325 val.substr(0,cursor.endPos));
2327 el.insertBefore(newNode1,secondEl);
2329 var newNode = document.createElement(
"label");
2330 newNode.textContent = val[cursor.endPos];
2331 el.insertBefore(newNode,secondEl);
2333 secondEl.textContent = val.substr(cursor.endPos+1);
2335 newNode.scrollIntoViewIfNeeded();
2337 el.removeChild(newNode);
2338 el.removeChild(newNode1);
2339 secondEl.textContent = val;
2343 Debug.log(
"Failed to scroll to inserted 2nd element: " + e);
2346 secondEl.scrollIntoViewIfNeeded();
2350 Debug.log(
"Failed to scroll 2nd element: " + e);
2355 Debug.log(
"inserting scroll 1st element");
2360 if(!scrollEndIntoView)
2363 firstEl = el.childNodes[cursor.startNodeIndex];
2364 var val = firstEl.textContent;
2365 var newNode1 = document.createTextNode(
2366 val.substr(0,cursor.startPos));
2368 el.insertBefore(newNode1,firstEl);
2370 var newNode = document.createElement(
"label");
2371 newNode.textContent = val[cursor.startPos];
2372 el.insertBefore(newNode,firstEl);
2374 firstEl.textContent = val.substr(cursor.startPos+1);
2376 newNode.scrollIntoViewIfNeeded();
2379 el.removeChild(newNode);
2380 el.removeChild(newNode1);
2381 firstEl.textContent = val;
2384 Debug.log(
"scrollEndIntoView only");
2388 Debug.log(
"Failed to scroll to inserted 1st element: " + e);
2391 firstEl.scrollIntoViewIfNeeded();
2395 Debug.log(
"Failed to scroll 1st element: " + e);
2404 if(firstEl.firstChild)
2405 firstEl = firstEl.firstChild;
2406 if(secondEl.firstChild)
2407 secondEl = secondEl.firstChild;
2409 range.setStart(firstEl,
2411 range.setEnd(secondEl,
2415 var selection = window.getSelection();
2416 selection.removeAllRanges();
2417 selection.addRange(range);
2420 if(scrollEndIntoView)
2421 selection.extend(secondEl,cursor.endPos);
2433 console.log(
"set cursor err:",err);
2440 this.createCursorFromContentPosition =
function(el,startPos,endPos)
2444 "startNodeIndex":undefined,
2445 "startPos":undefined,
2446 "endNodeIndex":undefined,
2457 for(i=0;i<el.childNodes.length;++i)
2459 sum += el.childNodes[i].textContent.length;
2461 if(cursor.startNodeIndex === undefined &&
2462 startPos >= oldSum &&
2466 cursor.startNodeIndex = i;
2467 cursor.startPos = startPos - oldSum;
2469 if(endPos >= oldSum &&
2473 cursor.endNodeIndex = i;
2474 cursor.endPos = endPos - oldSum;
2481 console.log(
"createCursorFromContentPosition:",cursor);
2486 console.log(
"get cursor err:",err);
2494 this.getCursor =
function(el)
2498 "startNodeIndex":undefined,
2499 "startPos":undefined,
2500 "endNodeIndex":undefined,
2502 "startPosInContent":undefined,
2503 "endPosInContent":undefined,
2504 "focusAtEnd":undefined
2510 var selection = window.getSelection();
2511 var range = selection.getRangeAt(0);
2512 var focusNode = selection.focusNode;
2513 var extentNode = selection.extentNode;
2515 cursor.startPos = range.startOffset;
2516 cursor.endPos = range.endOffset;
2519 for(i=0;i<el.childNodes.length;++i)
2521 if(cursor.startNodeIndex === undefined &&
2523 el.childNodes[i] == range.startContainer ||
2524 el.childNodes[i] == range.startContainer.parentNode ||
2525 el.childNodes[i] == range.startContainer.parentNode.parentNode ||
2526 el.childNodes[i] == range.startContainer.parentNode.parentNode.parentNode) )
2528 cursor.startNodeIndex = i;
2529 cursor.startPosInContent = sum + cursor.startPos;
2531 if(focusNode == range.startContainer ||
2532 extentNode == range.startContainer)
2533 cursor.focusAtEnd =
false;
2536 if(el.childNodes[i] == range.endContainer ||
2537 el.childNodes[i] == range.endContainer.parentNode ||
2538 el.childNodes[i] == range.endContainer.parentNode.parentNode ||
2539 el.childNodes[i] == range.startContainer.parentNode.parentNode.parentNode)
2541 cursor.endNodeIndex = i;
2542 cursor.endPosInContent = sum + cursor.endPos;
2544 if(cursor.focusAtEnd == undefined &&
2545 (focusNode == range.endContainer ||
2546 extentNode == range.endContainer))
2547 cursor.focusAtEnd =
true;
2552 sum += el.childNodes[i].textContent.length;
2561 console.log(
"get cursor err:",err);
2569 var _DECORATION_RED =
"rgb(202, 52, 52)";
2570 var _DECORATION_BLUE =
"rgb(64, 86, 206)";
2571 var _DECORATION_GREEN =
"rgb(33, 175, 60)";
2572 var _DECORATION_BLACK =
"rgb(5, 5, 5)";
2573 var _DECORATION_GRAY =
"rgb(162, 179, 158)";
2574 var _DECORATIONS = {
2576 "ADD_SUBDIRECTORY" : _DECORATION_RED,
2577 "include_directories" : _DECORATION_RED,
2578 "simple_plugin" : _DECORATION_RED,
2579 "set" : _DECORATION_RED,
2580 "install_headers" : _DECORATION_RED,
2581 "install_source" : _DECORATION_RED,
2582 "enable_testing" : _DECORATION_RED,
2583 "CMAKE_MINIMUM_REQUIRED": _DECORATION_RED,
2584 "include" : _DECORATION_RED,
2585 "create_doxygen_documentation": _DECORATION_RED,
2588 "#define" : _DECORATION_RED,
2589 "#undef" : _DECORATION_RED,
2590 "#include" : _DECORATION_RED,
2591 "#ifndef" : _DECORATION_RED,
2592 "#else" : _DECORATION_RED,
2593 "#endif" : _DECORATION_RED,
2594 "using" : _DECORATION_RED,
2595 "namespace" : _DECORATION_RED,
2596 "class" : _DECORATION_RED,
2597 "public" : _DECORATION_RED,
2598 "private" : _DECORATION_RED,
2599 "protected" : _DECORATION_RED,
2600 "static" : _DECORATION_RED,
2601 "virtual" : _DECORATION_RED,
2602 "override" : _DECORATION_RED,
2603 "const" : _DECORATION_RED,
2604 "void" : _DECORATION_RED,
2605 "bool" : _DECORATION_RED,
2606 "unsigned" : _DECORATION_RED,
2607 "int" : _DECORATION_RED,
2608 "uint64_t" : _DECORATION_RED,
2609 "uint32_t" : _DECORATION_RED,
2610 "uint16_t" : _DECORATION_RED,
2611 "uint8_t" : _DECORATION_RED,
2612 "long" : _DECORATION_RED,
2613 "float" : _DECORATION_RED,
2614 "double" : _DECORATION_RED,
2615 "return" : _DECORATION_RED,
2616 "char" : _DECORATION_RED,
2617 "if" : _DECORATION_RED,
2618 "else" : _DECORATION_RED,
2619 "for" : _DECORATION_RED,
2620 "while" : _DECORATION_RED,
2621 "do" : _DECORATION_RED,
2622 "switch" : _DECORATION_RED,
2623 "case" : _DECORATION_RED,
2624 "default" : _DECORATION_RED,
2625 "try" : _DECORATION_RED,
2626 "catch" : _DECORATION_RED,
2627 "this" : _DECORATION_RED,
2628 "true" : _DECORATION_RED,
2629 "false" : _DECORATION_RED,
2633 "std" : _DECORATION_GREEN,
2634 "ots" : _DECORATION_GREEN,
2635 "string" : _DECORATION_GREEN,
2636 "set" : _DECORATION_GREEN,
2637 "vector" : _DECORATION_GREEN,
2638 "pair" : _DECORATION_GREEN,
2639 "get" : _DECORATION_GREEN,
2640 "map" : _DECORATION_GREEN,
2641 "endl" : _DECORATION_GREEN,
2642 "runtime_error" : _DECORATION_GREEN,
2643 "memcpy" : _DECORATION_GREEN,
2644 "cout" : _DECORATION_GREEN,
2647 "this" : _DECORATION_RED,
2648 "var" : _DECORATION_RED,
2649 "return" : _DECORATION_RED,
2650 "function" : _DECORATION_RED,
2651 "if" : _DECORATION_RED,
2652 "else" : _DECORATION_RED,
2653 "for" : _DECORATION_RED,
2654 "while" : _DECORATION_RED,
2655 "do" : _DECORATION_RED,
2656 "switch" : _DECORATION_RED,
2657 "case" : _DECORATION_RED,
2658 "default" : _DECORATION_RED,
2659 "try" : _DECORATION_RED,
2660 "catch" : _DECORATION_RED,
2661 "new" : _DECORATION_RED,
2662 "instanceof" : _DECORATION_RED,
2663 "true" : _DECORATION_RED,
2664 "false" : _DECORATION_RED,
2666 "Debug" : _DECORATION_GREEN,
2667 "DesktopContent" : _DECORATION_GREEN,
2668 "HIGH_PRIORITY" : _DECORATION_GREEN,
2669 "WARN_PRIORITY" : _DECORATION_GREEN,
2670 "INFO_PRIORITY" : _DECORATION_GREEN,
2671 "LOW_PRIORITY" : _DECORATION_GREEN,
2673 "Math" : _DECORATION_GREEN,
2674 "String" : _DECORATION_GREEN,
2675 "window" : _DECORATION_GREEN,
2676 "document" : _DECORATION_GREEN,
2677 "textContent" : _DECORATION_GREEN,
2678 "innerHTML" : _DECORATION_GREEN,
2681 "if" : _DECORATION_RED,
2682 "then" : _DECORATION_RED,
2683 "else" : _DECORATION_RED,
2684 "fi" : _DECORATION_RED,
2685 "for" : _DECORATION_RED,
2686 "in" : _DECORATION_RED,
2687 "while" : _DECORATION_RED,
2688 "do" : _DECORATION_RED,
2689 "done" : _DECORATION_RED,
2690 "switch" : _DECORATION_RED,
2691 "case" : _DECORATION_RED,
2692 "default" : _DECORATION_RED,
2693 "export" : _DECORATION_RED,
2695 "echo" : _DECORATION_GREEN,
2696 "cd" : _DECORATION_GREEN,
2697 "cp" : _DECORATION_GREEN,
2698 "rm" : _DECORATION_GREEN,
2699 "cat" : _DECORATION_GREEN,
2700 "wget" : _DECORATION_GREEN,
2701 "chmod" : _DECORATION_GREEN,
2702 "sleep" : _DECORATION_GREEN,
2705 this.updateDecorations =
function(forPrimary,forceDisplayComplete,forceDecorations)
2707 forPrimary = forPrimary?1:0;
2709 Debug.log(
"updateDecorations forPrimary=" + forPrimary +
" forceDisplayComplete=" + forceDisplayComplete);
2711 var el = _eel[forPrimary];
2712 var elTextObj = {
"text":el.textContent,
"time":Date.now()};
2713 var wasSnapshot = CodeEditor.editor.updateFileSnapshot(forPrimary,
2716 if(wasSnapshot || forceDisplayComplete)
2717 CodeEditor.editor.updateOutline(forPrimary,elTextObj);
2719 if(!forceDecorations && !wasSnapshot)
2721 Debug.log(
"unchanged, skipping decorations");
2731 var cursor = CodeEditor.editor.getCursor(el);
2735 CodeEditor.editor.updateLastSave(forPrimary);
2739 var decor, fontWeight;
2741 var commentString =
"#";
2742 if(_fileExtension[forPrimary][0] ==
'c' ||
2743 _fileExtension[forPrimary][0] ==
'C' ||
2744 _fileExtension[forPrimary][0] ==
'h' ||
2745 _fileExtension[forPrimary][0] ==
'j' ||
2746 _fileExtension[forPrimary] ==
"icc")
2747 commentString =
"//";
2749 var fileDecorType =
"txt";
2750 if( _fileExtension[forPrimary] ==
"html" ||
2751 _fileExtension[forPrimary] ==
"js")
2752 fileDecorType =
"js";
2753 else if(_fileExtension[forPrimary][0] ==
'c' ||
2754 _fileExtension[forPrimary][0] ==
'C' ||
2755 _fileExtension[forPrimary][0] ==
'h' ||
2756 _fileExtension[forPrimary][0] ==
'j' ||
2757 _fileExtension[forPrimary] ==
"icc")
2758 fileDecorType =
"c++";
2759 else if(_fileExtension[forPrimary] ==
'sh' ||
2760 _fileExtension[forPrimary] ==
'py')
2761 fileDecorType =
"sh";
2766 var startOfWord = -1;
2767 var startOfString = -1;
2768 var stringQuoteChar;
2770 var startOfComment = -1;
2771 var firstSpecialStringStartHandling =
true;
2772 var firstSpecialStringEndHandling =
true;
2773 var endPositionCache;
2784 function localInsertLabel(startPos, isQuote)
2788 newNode = document.createTextNode(val.substr(0,startPos));
2789 el.insertBefore(newNode,node);
2791 newNode = document.createElement(
"label");
2792 newNode.style.fontWeight = fontWeight;
2793 newNode.style.color = decor;
2794 newNode.textContent = specialString;
2796 el.insertBefore(newNode,node);
2800 var str = newNode.textContent;
2801 str = str.substr(str.lastIndexOf(
'.')+1);
2804 if(str.length > 0 && str.length <= 4 &&
2815 Debug.log(
"is quote " + str);
2817 newNode.onmouseover =
function(e)
2819 window.clearTimeout(_fileStringHoverTimeout);
2821 var x = this.offsetWidth + this.offsetLeft + 64;
2822 var y = this.offsetTop;
2823 e.stopPropagation();
2826 if(_fileStringHoverEl.parentNode)
2828 _fileStringHoverEl.parentNode.removeChild(_fileStringHoverEl);
2833 _fileStringHoverEl = document.createElement(
"div");
2834 _fileStringHoverEl.setAttribute(
"id",
"fileStringHoverEl");
2835 _fileStringHoverEl.setAttribute(
"contentEditable",
"false");
2836 _fileStringHoverEl.onmouseover =
function(e)
2838 window.clearTimeout(_fileStringHoverTimeout);
2839 e.stopPropagation();
2843 _fileStringHoverEl.style.display =
'none';
2846 var name = this.textContent;
2849 name = name.substr(1,name.length-2);
2850 var nameArr = name.split(
'/');
2851 if(nameArr.length == 0)
2853 Debug.log(
"empty name array, error! name = " + name);
2856 else if(nameArr.length > 1 && nameArr[0] ==
"" &&
2857 nameArr[1] ==
"WebPath")
2859 name =
"/otsdaq_utilities/WebGUI" +
2860 name.substr((
"/WebPath").length);
2862 else if(nameArr[0] !=
"")
2865 var i = nameArr[0].indexOf(
'-');
2869 if(nameArr[0] !=
"otsdaq-core")
2871 nameArr[0] = nameArr[0].substr(0,i) +
'_'
2872 + nameArr[0].substr(i+1);
2875 nameArr[0] =
"otsdaq";
2877 name =
"/" + nameArr[0] +
"/" + name;
2881 Debug.log(
"Confused by name array, error! name = " + name);
2887 Debug.log(
"name " + name);
2891 str += htmlOpen(
"a",
2893 "title":
"Open file in this editor pane: \n" +
2895 "onclick":
"CodeEditor.editor.openFile(" +
2896 (forPrimary) +
",\"" +
2898 name.substr(name.lastIndexOf(
'.')+1) +
"\"" +
2902 "style='float: left; padding: 1px 0 1px 6px;'>" +
2904 "style='border:1px solid rgb(99, 98, 98); border-radius: 2px; width: 9px;" +
2905 "height: 9px; '></div></div>"
2908 str += htmlOpen(
"a",
2910 "title":
"Open file in the other editor pane of the split-view: \n" +
2912 "onclick":
"CodeEditor.editor.openFile(" +
2913 (!forPrimary) +
",\"" +
2915 name.substr(name.lastIndexOf(
'.')+1) +
"\"" +
2919 "style='float: left; padding: 0;'>" +
2920 "<img class='dirNavFileNewWindowImgNewPane' " +
2921 "src='/WebPath/images/windowContentImages/CodeEditor-openInOtherPane.png'></div>"
2924 str += htmlOpen(
"a",
2926 "title":
"Open file in a new browser tab: \n" +
2928 "onclick":
"DesktopContent.openNewBrowserTab(" +
2929 "\"Code Editor\",\"\"," +
2930 "\"/WebPath/html/CodeEditor.html?urn=" +
2931 DesktopContent._localUrnLid +
"&" +
2932 "startFilePrimary=" +
2933 name +
"\",0 /*unique*/);' ",
2936 "style='float: left; padding: 0 6px 0 0;'>" +
2937 "<img class='dirNavFileNewWindowImgNewWindow' " +
2938 "src='/WebPath/images/windowContentImages/CodeEditor-openInNewWindow.png'></div>"
2941 _fileStringHoverEl.innerHTML = str;
2943 this.parentNode.appendChild(_fileStringHoverEl);
2946 _fileStringHoverEl.style.left = x +
"px";
2947 _fileStringHoverEl.style.top = y +
"px";
2949 _fileStringHoverEl.style.display =
'block';
2956 node.textContent = val.substr(i);
2960 if(cursor.startNodeIndex !== undefined)
2962 if(n < cursor.startNodeIndex)
2965 cursor.startNodeIndex += 2;
2966 cursor.endNodeIndex += 2;
2973 if(n == cursor.startNodeIndex)
2976 if(cursor.startPos < startPos)
2981 else if(cursor.startPos < i)
2984 ++cursor.startNodeIndex;
2985 cursor.startPos -= startPos;
2990 cursor.startNodeIndex += 2;
2991 if(val[cursor.startPos-1] ==
'\r') --cursor.startPos;
2992 cursor.startPos -= i;
2997 if(n == cursor.endNodeIndex)
3000 if(cursor.endPos < startPos)
3005 else if(cursor.endPos < i)
3008 ++cursor.endNodeIndex;
3009 cursor.endPos -= startPos;
3014 cursor.endNodeIndex += 2;
3015 if(val[cursor.endPos-1] ==
'\r') --cursor.endPos;
3020 else if(n < cursor.endNodeIndex)
3022 cursor.endNodeIndex += 2;
3032 for(n=0;!done && n<el.childNodes.length;++n)
3034 node = el.childNodes[n];
3035 val = node.textContent;
3037 if(node.nodeName ==
"LABEL" ||
3038 node.nodeName ==
"FONT" ||
3039 node.nodeName ==
"SPAN" ||
3040 node.nodeName ==
"PRE")
3045 if((_DECORATIONS[fileDecorType][val] === undefined &&
3046 (val[0] != commentString[0] ||
3047 val.indexOf(
'\n') >= 0) &&
3050 (n+1 >= cursor.startNodeIndex && n-1 <= cursor.endNodeIndex))
3055 newNode = document.createTextNode(val);
3056 el.insertBefore(newNode,node);
3057 el.removeChild(node);
3066 else if(node.nodeName ==
"DIV" ||
3067 node.nodeName ==
"BR")
3071 eatVal = node.innerHTML;
3075 if(node.nodeName ==
"DIV")
3079 specialString = el.childNodes[n-1].textContent;
3080 if(specialString[specialString.length-1] ==
'\n')
3084 if(eatVal.indexOf(
"<br>") == 0 ||
3096 newNode = document.createTextNode(val);
3097 el.insertBefore(newNode,node);
3098 el.removeChild(node);
3101 if(n == cursor.startNodeIndex)
3102 cursor.startPos += i;
3103 if(n == cursor.endNodeIndex)
3110 else if(node.nodeName ==
"#text")
3113 el.childNodes[n-1].nodeName ==
"#text")
3121 if(n + 1 < el.childNodes.length &&
3122 el.childNodes[n+1].nodeName ==
"#text")
3129 if(cursor.startNodeIndex !== undefined)
3131 if(n+1 < cursor.startNodeIndex)
3134 cursor.startNodeIndex -= 1;
3135 cursor.endNodeIndex -= 1;
3142 if(n+1 == cursor.startNodeIndex)
3145 --cursor.startNodeIndex;
3146 cursor.startPos += val.length;
3150 if(n+1 == cursor.endNodeIndex)
3153 --cursor.endNodeIndex;
3154 cursor.endPos += val.length;
3156 else if(n+1 < cursor.endNodeIndex)
3159 --cursor.endNodeIndex;
3165 newNode = el.childNodes[n+1];
3166 val += newNode.textContent;
3167 newNode.textContent = val;
3168 el.removeChild(node);
3176 for(i=0;i<val.length;++i)
3183 if(startOfComment == -1 && (
3184 startOfString != -1 ||
3185 (prevChar !=
'\\' && val[i] ==
'"') ||
3186 (prevChar !=
'\\' && val[i] ==
"'")
3189 if(startOfString == -1 &&
3190 (val[i] ==
'"' || val[i] ==
"'"))
3193 stringQuoteChar = val[i];
3195 firstSpecialStringStartHandling =
true;
3196 firstSpecialStringEndHandling =
true;
3198 else if(prevChar !=
'\\' && val[i] == stringQuoteChar)
3201 specialString = val.substr(startOfString,i-startOfString);
3204 decor = _DECORATION_BLUE;
3205 fontWeight =
"normal";
3206 localInsertLabel(startOfString,
true );
3212 else if(startOfString == -1 && (
3213 startOfComment != -1 ||
3214 (i+commentString.length-1 < val.length &&
3215 val.substr(i,commentString.length) ==
3218 if(startOfComment == -1 && val[i] == commentString[0])
3221 firstSpecialStringStartHandling =
true;
3222 firstSpecialStringEndHandling =
true;
3224 else if(val[i] ==
'\n')
3227 specialString = val.substr(startOfComment,i-startOfComment);
3230 decor = _DECORATION_GRAY;
3231 fontWeight =
"normal";
3232 localInsertLabel(startOfComment);
3233 startOfComment = -1;
3239 (val[i] >=
'a' && val[i] <=
'z') ||
3240 (val[i] >=
'A' && val[i] <=
'Z') ||
3241 (val[i] >=
'0' && val[i] <=
'9') ||
3242 (val[i] ==
'_' || val[i] ==
'-') ||
3245 if(startOfWord == -1)
3249 else if(startOfWord != -1)
3251 specialString = val.substr(startOfWord,i-startOfWord);
3252 decor = _DECORATIONS[fileDecorType][specialString];
3258 fontWeight =
"bold";
3259 localInsertLabel(startOfWord);
3269 if(prevChar ==
'\\' && val[i] ==
'\\')
3272 if(escapeCount%2 == 0)
3290 if(startOfString != -1 || startOfComment != -1)
3292 console.log(
"In string/comment crossing Nodes!");
3295 closedString =
false;
3296 for(++n;n<el.childNodes.length;++n)
3298 eatNode = el.childNodes[n];
3299 eatVal = eatNode.textContent;
3303 if(cursor.startNodeIndex !== undefined)
3305 if(firstSpecialStringStartHandling)
3306 firstSpecialStringStartHandling =
false;
3308 if(firstSpecialStringEndHandling)
3312 endPositionCache = cursor.endPos;
3313 firstSpecialStringEndHandling =
false;
3316 if(n < cursor.startNodeIndex)
3319 cursor.startNodeIndex -= 1;
3320 cursor.endNodeIndex -= 1;
3327 if(n == cursor.startNodeIndex)
3330 --cursor.startNodeIndex;
3331 cursor.startPos += val.length;
3335 if(n == cursor.endNodeIndex)
3338 --cursor.endNodeIndex;
3339 cursor.endPos += val.length;
3341 else if(n < cursor.endNodeIndex)
3344 --cursor.endNodeIndex;
3420 el.removeChild(eatNode);
3425 for(i;i<val.length;++i)
3428 if(startOfString != -1 &&
3429 (prevChar !=
'\\' && val[i] ==
'"'))
3431 Debug.log(
"Closing node crossed string.");
3434 specialString = val.substr(startOfString,i-startOfString);
3437 decor = _DECORATION_BLUE;
3438 fontWeight =
"normal";
3439 localInsertLabel(startOfString,
true );
3441 closedString =
true;
3446 if(startOfComment != -1 && val[i] ==
'\n')
3448 Debug.log(
"Closing node crossed comment.");
3452 specialString = val.substr(startOfComment,i-startOfComment);
3455 decor = _DECORATION_GRAY;
3456 fontWeight =
"normal";
3457 localInsertLabel(startOfComment);
3458 startOfComment = -1;
3460 closedString =
true;
3466 if(prevChar ==
'\\' && val[i] ==
'\\')
3469 if(escapeCount%2 == 0)
3482 if(closedString)
break;
3486 if(!closedString && startOfString != -1)
3488 Debug.log(
"String is never closed!");
3489 specialString = val.substr(startOfString,i-startOfString);
3492 decor = _DECORATION_BLUE;
3494 localInsertLabel(startOfString,
true );
3497 if(!closedString && startOfComment != -1)
3499 Debug.log(
"Comment is never closed!");
3500 specialString = val.substr(startOfComment,i-startOfComment);
3503 decor = _DECORATION_GRAY;
3505 localInsertLabel(startOfComment);
3506 startOfComment = -1;
3509 if(n < cursor.endNodeIndex)
3513 firstSpecialStringEndHandling =
true;
3514 cursor.endPos = endPositionCache;
3523 console.log(
"unknown node.nodeName",node.nodeName);
3524 throw(
"node error!");
3529 CodeEditor.editor.setCursor(el,cursor);
3531 CodeEditor.editor.updateDualView(forPrimary);
3537 this.autoIndent =
function(forPrimary, cursor)
3539 if(!cursor || cursor.startNodeIndex === undefined)
3541 Debug.log(
"Invalid text selection for auto-indent. Please select text in the text editor.",
3542 Debug.HIGH_PRIORITY);
3545 forPrimary = forPrimary?1:0;
3547 Debug.log(
"autoIndent " + forPrimary);
3549 DesktopContent.showLoading(localDoIt);
3558 function localDoIt()
3568 var el = _eel[forPrimary];
3574 for(n=cursor.startNodeIndex;n>=0; --n)
3576 node = el.childNodes[n];
3577 val = node.textContent;
3579 for(i=(n==cursor.startNodeIndex?cursor.startPos-1:
3580 val.length-1); i>=0; --i)
3593 console.log(
"at leading newline - n",n,
"i",i);
3599 cursor.startNodeIndex = n;
3600 cursor.startPos = i;
3608 for(n=0; n<el.childNodes.length; ++n)
3610 val = el.childNodes[n].textContent;
3611 if(n < cursor.startNodeIndex)
3613 else if(n == cursor.startNodeIndex)
3615 preText += val.substr(0,cursor.startPos);
3617 if(n < cursor.endNodeIndex)
3618 text += val.substr(cursor.startPos);
3621 text += val.substr(cursor.startPos,
3622 cursor.endPos-cursor.startPos);
3623 postText += val.substr(cursor.endPos);
3626 else if(n < cursor.endNodeIndex)
3628 else if(n == cursor.endNodeIndex)
3630 text += val.substr(0,cursor.endPos);
3631 postText += val.substr(cursor.endPos);
3641 var fileExtension = _fileExtension[forPrimary];
3652 for(i=0;i<text.length;++i)
3655 else if(text[i] ==
'\t')
3656 x += _TAB_SIZE - (x+_TAB_SIZE)%_TAB_SIZE;
3659 Debug.log(
"Whitespace size =" + x +
" tabs=" + ((x/_TAB_SIZE)|0));
3663 for(n=0;n<((x/_TAB_SIZE)|0);++n)
3672 var lastChar,firstChar;
3673 var prevLastChar,prevFirstChar;
3675 var inCmdTabStr =
"";
3676 var nextInCmdTabStr =
"";
3677 var isCmdTabStr =
"";
3678 var nextIsCmdTabStr =
"";
3683 var firstColonCommand =
false;
3684 var lastColonCommand =
false;
3685 var foundDoubleQuote,foundSingleQuote;
3686 var tradeInCmdStack = [];
3687 var tradeIsCmdStack = [];
3697 foundComment =
false;
3698 foundDoubleQuote =
false;
3699 foundSingleQuote =
false;
3701 for(n=i+1;n<text.length;++n)
3709 if(!foundSingleQuote && text[n] ==
'"')
3710 foundDoubleQuote = !foundDoubleQuote;
3711 else if(!foundDoubleQuote && text[n] ==
"'")
3712 foundSingleQuote = !foundSingleQuote;
3713 else if(text[n] ==
'/' && n+1 < text.length &&
3716 foundComment =
true;
3720 if(foundDoubleQuote || foundSingleQuote)
3723 if(text[n] !=
' ' && text[n] !=
'\t')
3727 firstChar = text[n];
3732 inCmdTabStr +=
'\t';
3733 else if(text[n] ==
')')
3734 inCmdTabStr = inCmdTabStr.substr(0, inCmdTabStr.length-1);
3735 else if(inCmdTabStr.length == 0 &&
3740 firstColonCommand =
false;
3741 lastColonCommand =
false;
3746 nextTabStr = tabStr;
3749 if(firstChar ==
'}')
3751 nextIsCmdTabStr =
"";
3754 if(tradeInCmdStack.length &&
3755 tradeInCmdStack[tradeInCmdStack.length-1][0] ==
3759 inCmdTabStr = tradeInCmdStack.pop()[1];
3760 nextInCmdTabStr = inCmdTabStr;
3761 isCmdTabStr = tradeIsCmdStack.pop();
3762 tabStr = tabStr.substr(0,tabStr.length-1);
3767 firstColonCommand =
false;
3769 tabStr = tabStr.substr(0,tabStr.length-1);
3770 nextTabStr = tabStr;
3772 else if(lastChar ==
':' &&
3773 (firstChar ==
'p' ||
3777 nextIsCmdTabStr =
"";
3781 firstColonCommand =
false;
3782 lastColonCommand =
false;
3783 nextTabStr = tabStr.substr(0,tabStr.length-1);
3785 else if(firstChar ==
':')
3788 nextIsCmdTabStr =
"";
3790 firstColonCommand =
true;
3792 else if(firstChar ==
'#' ||
3796 if(lastColonCommand)
3797 tabStr = tabStr.substr(0,tabStr.length-1);
3801 if(nextInCmdTabStr.length != 0 ||
3802 nextIsCmdTabStr.length != 1 ||
3803 prevLastChar !=
',')
3806 nextIsCmdTabStr =
"";
3810 else if(!firstColonCommand &&
3811 !lastColonCommand &&
3817 else if(lastColonCommand &&
3818 prevLastChar ==
',' &&
3819 inCmdTabStr.length == 0)
3822 lastColonCommand =
false;
3823 tabStr = tabStr.substr(0,tabStr.length-1);
3825 nextIsCmdTabStr =
"\t";
3828 firstColonCommand =
false;
3835 firstColonCommand =
false;
3836 lastColonCommand =
false;
3840 "firstChar = " + firstChar +
3841 "lastChar = " + lastChar +
3842 "prevFirstChar = " + prevFirstChar +
3843 "prevLastChar = " + prevLastChar +
3847 inCmdTabStr.length +
3849 isCmdTabStr.length +
3853 nextInCmdTabStr.length +
3855 nextIsCmdTabStr.length +
3857 tradeInCmdStack.length +
3858 " " + firstColonCommand +
3859 " " + lastColonCommand);
3863 newText += nextTabStr + nextInCmdTabStr + nextIsCmdTabStr;
3865 newText += text.substr(i+1,n-(i+1)).trimLeft();
3874 if(inCmdTabStr.length)
3878 tradeInCmdStack.push([tabStr.length,inCmdTabStr]);
3879 tradeIsCmdStack.push(isCmdTabStr);
3895 nextInCmdTabStr = inCmdTabStr;
3896 nextIsCmdTabStr = isCmdTabStr;
3899 prevLastChar = lastChar;
3901 prevFirstChar = firstChar;
3905 }
while(i+1<text.length);
3909 if(text[i] ==
'\n') newText +=
'\n';
3915 Debug.log(
"Unknown operation to auto-indent file with extension " +
3916 fileExtension,Debug.HIGH_PRIORITY);
3921 el.textContent = preText + newText + postText;
3923 _fileWasModified[forPrimary] =
true;
3925 CodeEditor.editor.updateDecorations(forPrimary,
3934 this.updateDualView =
function(forPrimary)
3936 forPrimary = forPrimary?1:0;
3938 Debug.log(
"updateDualView " + forPrimary);
3942 if(_filePath[0] == _filePath[1] &&
3943 _fileExtension[0] == _fileExtension[1])
3945 var val,node, newNode;
3946 var el = _eel[forPrimary];
3948 Debug.log(
"Update dual view");
3950 _fileLastSave[(!forPrimary)?1:0] = _fileLastSave[forPrimary];
3951 _fileWasModified[(!forPrimary)?1:0] = _fileWasModified[forPrimary];
3952 CodeEditor.editor.updateLastSave(!forPrimary);
3956 var elAlt = _eel[(!forPrimary)?1:0];
3957 elAlt.innerHTML =
"";
3958 for(i=0;i<el.childNodes.length;++i)
3960 node = el.childNodes[i];
3961 val = node.textContent;
3962 if(node.nodeName ==
"LABEL")
3964 newNode = document.createElement(
"label");
3965 newNode.style.fontWeight = node.style.fontWeight;
3966 newNode.style.color = node.style.color;
3967 newNode.textContent = val;
3969 else if(node.nodeName ==
"#text")
3971 newNode = document.createTextNode(val);
3974 Debug.log(
"Skipping unknown node " + node.nodeName);
3975 elAlt.appendChild(newNode);
3984 this.updateOutline =
function(forPrimary,elTextObj)
3986 forPrimary = forPrimary?1:0;
3988 Debug.log(
"updateOutline " + forPrimary);
3996 var localNewLineCount;
3998 var newLineCount = 0;
4000 outline.push([1,
"Top"]);
4004 var isCcSource = _fileExtension[forPrimary][0] ==
'c' ||
4005 _fileExtension[forPrimary][0] ==
'C' ||
4006 _fileExtension[forPrimary] ==
"icc";
4007 var isJsSource = _fileExtension[forPrimary] ==
"js" ||
4008 _fileExtension[forPrimary] ==
"html";
4010 var indicatorIndex = 0;
4012 if(isCcSource) indicator =
"::";
4013 if(isJsSource) indicator =
"function";
4015 for(i=0;i<elTextObj.text.length;++i)
4017 if(elTextObj.text[i] ==
'\n')
4025 if(elTextObj.text[i] == indicator[indicatorIndex])
4028 if(indicatorIndex == indicator.length)
4035 str = localHandleCcOutline();
4037 str = localHandleJsOutline();
4042 outline.push([newLineCount+1,
4055 Debug.log(
"Number of lines " + newLineCount);
4056 console.log(
"Done with outline", outline);
4060 for(i=0;i<newLineCount;++i)
4062 str +=
"<a name='" + forPrimary +
"L" + (i+1) +
"'></a>";
4066 document.getElementById(
"editableBoxLeftMargin" + forPrimary).innerHTML = str;
4068 _numberOfLines[forPrimary] = newLineCount;
4071 if(!isCcSource && !isJsSource)
4074 i = (newLineCount/2)|0;
4077 outline.push([i,
"Middle"]);
4080 outline.push([newLineCount,
"Bottom"]);
4086 str +=
"<table><td>"
4089 str += htmlOpen(
"select",
4091 "class":
"textEditorOutlineSelect",
4092 "id":
"textEditorOutlineSelect" + forPrimary,
4093 "style":
"text-align-last: center; width: 100%;",
4094 "title":
"Jump to a section of code.",
4096 "CodeEditor.editor.handleOutlineSelect(" + forPrimary +
");",
4098 "CodeEditor.editor.stopUpdateHandling(event);",
4100 str +=
"<option value='0'>Jump to a Line Number (Ctrl + L)</option>";
4103 for(i=0;i<outline.length;++i)
4105 str +=
"<option value='" + (outline[i][0]-2) +
"'>";
4106 text =
"#" + outline[i][0];
4110 found = (outline[i][1].indexOf(
"local") == 0);
4112 for(j=text.length;j<(found?20:12);++j)
4114 str += outline[i][1];
4118 str +=
"</td></table>";
4122 document.getElementById(
"textEditorOutline" + forPrimary).innerHTML = str;
4126 Debug.log(
"Ignoring missing outline element. Assuming header not shown.");
4132 function localHandleCcOutline()
4134 if(startCi && i < startCi)
4148 for(j=i+2;j<elTextObj.text.length;++j)
4150 if(elTextObj.text[j] ==
';' ||
4151 elTextObj.text[j] ==
'+' ||
4152 elTextObj.text[j] ==
'"' ||
4153 elTextObj.text[j] ==
"'")
4157 if(elTextObj.text[j] ==
'(')
4160 else if(startCi < 0)
4162 if(elTextObj.text[j] ==
'{')
4172 if(endi < 0 || startCi < 0)
4181 if(elTextObj.text[j] ==
')')
4195 return elTextObj.text.substr(starti+2,endi-starti-2).replace(/\s+/g,
'');
4201 function localHandleJsOutline()
4203 if(elTextObj.text[i + 1] ==
'(')
4210 for(j=i-1-(
"function").length;j>=0;--j)
4212 if(elTextObj.text[j] ==
'=')
4218 else if(!(elTextObj.text[j] ==
' ' || elTextObj.text[j] ==
'\t' ||
4219 (elTextObj.text[j] ==
'=' && !found)))
4228 if(elTextObj.text[j] ==
' ' || elTextObj.text[j] ==
'\t' ||
4229 elTextObj.text[j] ==
'\n')
4232 return elTextObj.text.substr(j+1,k-j-1).trim();
4242 for(j=i+2;j<elTextObj.text.length;++j)
4244 if(elTextObj.text[j] ==
'\n')
4246 else if(elTextObj.text[j] ==
'(')
4249 return elTextObj.text.substr(i+2,j-(i+2)).trim();
4261 this.handleOutlineSelect =
function(forPrimary)
4263 forPrimary = forPrimary?1:0;
4265 Debug.log(
"handleOutlineSelect() " + forPrimary);
4267 var val = document.getElementById(
"textEditorOutlineSelect" + forPrimary).value | 0;
4268 if(val < 1) val = 1;
4269 console.log(
"line val",val);
4271 CodeEditor.editor.gotoLine(forPrimary,val,
4280 this.keyDownHandler =
function(e,forPrimary,shortcutsOnly)
4282 forPrimary = forPrimary?1:0;
4284 var keyCode = e.keyCode;
4286 CodeEditor.editor.stopUpdateHandling();
4297 Debug.log(
"keydown c=" + keyCode +
" " + c +
" shift=" + e.shiftKey +
4298 " ctrl=" + e.ctrlKey +
" command=" + _commandKeyDown);
4301 CodeEditor.editor.startUpdateHandling(forPrimary);
4303 var el = _eel[forPrimary];
4305 var cursorSelection =
false;
4311 cursor = CodeEditor.editor.getCursor(el);
4313 cursorSelection = (cursor.startNodeIndex !== undefined &&
4314 (cursor.startNodeIndex != cursor.endNodeIndex ||
4315 cursor.startPos != cursor.endPos));
4317 if(!cursorSelection)
4318 _lastPageUpDownLine = -1;
4321 function localInsertCharacter(c)
4323 Debug.log(
"Inserting character... " + c);
4336 if(cursor.endNodeIndex > cursor.startNodeIndex)
4339 val = el.childNodes[cursor.endNodeIndex].textContent;
4340 val = val.substr(cursor.endPos);
4341 el.childNodes[cursor.endNodeIndex].textContent = val;
4342 --cursor.endNodeIndex;
4343 while(cursor.endNodeIndex > cursor.startNodeIndex)
4346 el.removeChild(el.childNodes[cursor.endNodeIndex]);
4347 --cursor.endNodeIndex;
4350 cursor.endPos = el.childNodes[cursor.startNodeIndex].textContent.length;
4353 var whiteSpaceString =
"";
4354 var postWhiteSpaceString =
"";
4355 var text = el.childNodes[cursor.startNodeIndex].textContent;
4356 var preCharString = text.substr(0,cursor.startPos);
4357 var cursorPosDelta = 0;
4368 for(n=cursor.startNodeIndex;n>=0; --n)
4370 node = el.childNodes[n];
4371 val = node.textContent;
4373 for(i=(n==cursor.startNodeIndex?cursor.startPos-1:
4374 val.length-1); i>=0; --i)
4382 else if(firstChar ==
'' &&
4383 val[i] !=
'\t' && val[i] !=
' ')
4390 console.log(
"at leading newline - n",n,
"i",i,
"firstChar",firstChar);
4397 for(n; n<el.childNodes.length; ++n)
4399 node = el.childNodes[n];
4400 val = node.textContent;
4402 for(i;i<val.length;++i)
4405 if((val[i] !=
'\t' && val[i] !=
' ') ||
4406 (n == cursor.startNodeIndex &&
4407 i >= cursor.startPos))
4413 whiteSpaceString += val[i];
4416 if(found || n == cursor.startNodeIndex)
break;
4421 if(firstChar ==
'{')
4423 postWhiteSpaceString +=
"\n" + whiteSpaceString +
"}";
4424 whiteSpaceString +=
'\t';
4425 postWhiteSpaceString += text.substr(cursor.endPos);
4429 val = text.substr(cursor.endPos);
4430 i = val.indexOf(
'\n');
4434 postWhiteSpaceString += val.substr(0,
4436 postWhiteSpaceString += val.substr(i);
4439 postWhiteSpaceString += val.trimLeft();
4450 var foundFirstNewLine =
false;
4454 for(n=cursor.startNodeIndex;n>=0; --n)
4456 node = el.childNodes[n];
4457 val = node.textContent;
4459 for(i=(n==cursor.startNodeIndex?cursor.startPos-1:
4460 val.length-1); i>=0; --i)
4469 Debug.log(
"Found matching bracket n=" + n +
4476 else if(val[i] ==
'}')
4478 else if(!foundFirstNewLine &&
4481 foundFirstNewLine =
true;
4483 Debug.log(
"pre-deleted white space preCharString=" +
4484 preCharString.length +
" " + preCharString);
4489 for(nn;nn<el.childNodes.length;++nn)
4491 if(nn < cursor.startNodeIndex)
4494 el.childNodes[nn].textContent =
"";
4496 else if(nn == cursor.startNodeIndex)
4499 preCharString = el.childNodes[nn].textContent.substr(
4506 Debug.log(
"deleted white space preCharString=" +
4507 preCharString.length +
" " + preCharString);
4509 else if(!foundFirstNewLine && val[i] !=
' ' &&
4512 Debug.log(
"Found character between } and new line, so doing nothing.");
4521 console.log(
"at closing bracket - n",n,
"i",i);
4524 preCharString = preCharString.trimRight();
4528 var matchingWhiteSpace =
"";
4530 var firstTime =
true;
4534 node = el.childNodes[n];
4535 val = node.textContent;
4538 val.length-1); i>=0; --i)
4546 else if(val[i] ==
' ' ||
4548 matchingWhiteSpace += val[i];
4550 matchingWhiteSpace =
"";
4559 preCharString += matchingWhiteSpace;
4560 Debug.log(
"matching white space preCharString=" +
4561 preCharString.length +
" " + preCharString);
4563 postWhiteSpaceString += text.substr(cursor.endPos);
4567 postWhiteSpaceString += text.substr(cursor.endPos);
4569 val = preCharString + c +
4571 postWhiteSpaceString;
4573 el.childNodes[cursor.startNodeIndex].textContent = val;
4576 console.log(
"cursorPosDelta",cursorPosDelta);
4578 cursor.startPos = c.length + preCharString.length + whiteSpaceString.length;
4579 cursor.endNodeIndex = cursor.startNodeIndex;
4580 cursor.endPos = cursor.startPos;
4582 console.log(
"cursor after newline",cursor);
4584 CodeEditor.editor.setCursor(el,cursor,
true );
4586 _fileWasModified[forPrimary] =
true;
4601 localInsertCharacter(
'\n');
4607 else if(keyCode == 36)
4621 var lastNonWhitespacePos = cursor.startPos;
4622 var lastNonWhitespaceNodeIndex = cursor.startNodeIndex;
4623 var lastPos = cursor.startPos;
4624 var lastNodeIndex = cursor.startNodeIndex;
4627 for(n=cursor.startNodeIndex; n>=0; --n)
4629 node = el.childNodes[n];
4630 val = node.textContent;
4632 for(i=(n==cursor.startNodeIndex?
4633 cursor.startPos-1:val.length-1);i>=0;--i)
4640 else if(!(val[i] ==
' ' ||
4643 lastNonWhitespacePos = i;
4644 lastNonWhitespaceNodeIndex = n;
4652 console.log(
"lastNonWhitespacePos",lastNonWhitespacePos);
4653 console.log(
"lastNonWhitespaceNodeIndex",lastNonWhitespaceNodeIndex);
4655 if(lastNonWhitespacePos == cursor.startPos &&
4656 lastNonWhitespaceNodeIndex == cursor.startNodeIndex)
4659 lastNonWhitespacePos = lastPos;
4660 lastNonWhitespaceNodeIndex = lastNodeIndex;
4664 if(lastNonWhitespacePos == lastPos &&
4665 lastNonWhitespaceNodeIndex == lastNodeIndex)
4666 document.getElementById(
"textEditorBody" + forPrimary).scrollLeft = 0;
4668 cursor.startNodeIndex = lastNonWhitespaceNodeIndex
4669 cursor.startPos = lastNonWhitespacePos;
4673 cursor.endNodeIndex = cursor.startNodeIndex;
4674 cursor.endPos = cursor.startPos;
4678 CodeEditor.editor.setCursor(el,cursor,
true );
4682 else if(keyCode == 35)
4698 var wantNext =
false;
4699 var lastNonWhitespacePos = cursor.startPos;
4700 var lastNonWhitespaceNodeIndex = cursor.startNodeIndex;
4703 for(n=cursor.startNodeIndex; n<el.childNodes.length; ++n)
4705 node = el.childNodes[n];
4706 val = node.textContent;
4708 for(i=(n==cursor.startNodeIndex?
4709 cursor.startPos:0);i<val.length;++i)
4713 lastNonWhitespacePos = i;
4714 lastNonWhitespaceNodeIndex = n;
4722 else if(!(val[i] ==
' ' ||
4730 console.log(
"lastNonWhitespacePos",lastNonWhitespacePos);
4731 console.log(
"lastNonWhitespaceNodeIndex",lastNonWhitespaceNodeIndex);
4733 if(lastNonWhitespacePos == cursor.startPos &&
4734 lastNonWhitespaceNodeIndex == cursor.startNodeIndex)
4737 lastNonWhitespacePos = i;
4738 lastNonWhitespaceNodeIndex = n;
4741 cursor.endNodeIndex = lastNonWhitespaceNodeIndex
4742 cursor.endPos = lastNonWhitespacePos;
4746 cursor.startNodeIndex = cursor.endNodeIndex;
4747 cursor.startPos = cursor.endPos;
4751 CodeEditor.editor.setCursor(el,cursor,
true );
4762 e.stopPropagation();
4771 var gotoLineCursor = {};
4774 if(_lastPageUpDownLine == -1)
4776 var cursorWithLine = CodeEditor.editor.getLine(forPrimary);
4778 _startPageUpDownNodeIndex = cursorWithLine.startNodeIndex;
4779 _startPageUpDownPos = cursorWithLine.startPos;
4781 _startPageUpDownLine = cursorWithLine.line;
4782 _lastPageUpDownLine = _startPageUpDownLine;
4785 gotoLineCursor.startNodeIndex = _startPageUpDownNodeIndex;
4786 gotoLineCursor.startPos = _startPageUpDownPos;
4789 _lastPageUpDownLine -= N;
4790 gotoLineCursor.focusAtEnd = (_lastPageUpDownLine > _startPageUpDownLine);
4792 Debug.log(
"Page up to line " + _lastPageUpDownLine +
" dir=" +
4793 gotoLineCursor.focusAtEnd);
4795 _lastPageUpDownLine = CodeEditor.editor.gotoLine(forPrimary,_lastPageUpDownLine,
4796 e.shiftKey?gotoLineCursor:undefined);
4800 else if(keyCode == 34)
4804 e.stopPropagation();
4813 var gotoLineCursor = {};
4816 if(_lastPageUpDownLine == -1)
4818 var cursorWithLine = CodeEditor.editor.getLine(forPrimary);
4820 _startPageUpDownNodeIndex = cursorWithLine.startNodeIndex;
4821 _startPageUpDownPos = cursorWithLine.startPos;
4823 _startPageUpDownLine = cursorWithLine.line;
4824 _lastPageUpDownLine = _startPageUpDownLine;
4827 gotoLineCursor.startNodeIndex = _startPageUpDownNodeIndex;
4828 gotoLineCursor.startPos = _startPageUpDownPos;
4831 _lastPageUpDownLine += N;
4832 gotoLineCursor.focusAtEnd = (_lastPageUpDownLine > _startPageUpDownLine);
4834 Debug.log(
"Page down to line " + _lastPageUpDownLine +
" dir=" +
4835 gotoLineCursor.focusAtEnd);
4837 _lastPageUpDownLine = CodeEditor.editor.gotoLine(forPrimary,_lastPageUpDownLine,
4838 e.shiftKey?gotoLineCursor:undefined);
4842 else if(keyCode == 13)
4848 if(CodeEditor.editor.findAndReplaceLastButton[forPrimary] > 0)
4851 e.stopPropagation();
4853 Debug.log(
"Launch find and replace action " +
4854 CodeEditor.editor.findAndReplaceLastButton[forPrimary]);
4855 CodeEditor.editor.doFindAndReplaceAction(forPrimary,
4856 CodeEditor.editor.findAndReplaceLastButton[forPrimary]);
4860 else if(keyCode == 27)
4866 if(CodeEditor.editor.findAndReplaceLastButton[forPrimary] > 0)
4869 e.stopPropagation();
4872 CodeEditor.editor.displayFileHeader(forPrimary);
4884 if (_requestPreamble !==
"readOnly") {
4885 CodeEditor.editor.saveFile(forPrimary,
true );
4890 else if(keyCode == 68)
4892 CodeEditor.editor.toggleDirectoryNav(forPrimary);
4896 else if(keyCode == 66)
4898 if (_requestPreamble !==
"readOnly") {
4899 CodeEditor.editor.build();
4904 else if(keyCode == 70)
4906 CodeEditor.editor.showFindAndReplace(forPrimary);
4910 else if(keyCode == 73)
4912 CodeEditor.editor.autoIndent(forPrimary, cursor);
4916 else if(keyCode == 78)
4918 if (_requestPreamble !==
"readOnly") {
4919 CodeEditor.editor.build(
true );
4924 else if(keyCode == 222 ||
4927 CodeEditor.editor.openFile(forPrimary,
4928 _filePath[forPrimary],
4929 _fileExtension[forPrimary],
4934 else if(keyCode == 50)
4936 CodeEditor.editor.toggleView();
4940 else if(keyCode == 85)
4942 CodeEditor.editor.undo(forPrimary, e.shiftKey );
4946 else if(keyCode == 76 ||
4949 DesktopContent.popUpVerification(
4950 "Goto line number: ",
4954 Debug.log(
"Going to line... " + line);
4955 CodeEditor.editor.gotoLine(forPrimary,line);
4968 else if(keyCode == 186 ||
4971 CodeEditor.editor.openRelatedFile(forPrimary);
4982 var rectangularTAB =
false;
4983 var blockCOMMENT =
false;
4994 rectangularTAB =
true;
4998 else if(keyCode == 191)
5000 blockCOMMENT =
true;
5011 if(keyCode == TABKEY || rectangularTAB ||
5014 _fileWasModified[forPrimary] =
true;
5015 CodeEditor.editor.updateLastSave(forPrimary);
5027 Debug.log(
"special key selected lines " + cursor.startNodeIndex +
" - " +
5028 cursor.endNodeIndex);
5035 Debug.log(
"Rectangular TAB");
5050 for(n=cursor.startNodeIndex;n>=0; --n)
5052 node = el.childNodes[n];
5053 val = node.textContent;
5055 for(i=(n==cursor.startNodeIndex?cursor.startPos-1:
5056 val.length-1); i>=0; --i)
5068 console.log(
"at leading newline - n",n,
"i",i);
5072 for(n; n<el.childNodes.length; ++n)
5074 node = el.childNodes[n];
5075 val = node.textContent;
5077 for(i;i<val.length;++i)
5080 if(n == cursor.startNodeIndex &&
5081 i == cursor.startPos)
5086 var prelength = val.length;
5090 if(i-1 >= 0 && val[i-1] ==
'\t')
5091 node.textContent = val.substr(0,i-1) + val.substr(i);
5095 node.textContent = val.substr(0,i) +
"\t" + val.substr(i);
5101 cursor.startPos += node.textContent.length - prelength;
5107 x += _TAB_SIZE - (x+_TAB_SIZE)%_TAB_SIZE;
5123 for(n=cursor.startNodeIndex; n<el.childNodes.length; ++n)
5125 node = el.childNodes[n];
5126 val = node.textContent;
5128 for(i=(n==cursor.startNodeIndex?cursor.startPos:
5129 0);i<val.length;++i)
5144 if(i-1 < val.length && val[i-1] ==
'\t')
5146 val = val.substr(0,i-1) + val.substr(i);
5147 node.textContent = val;
5152 val = val.substr(0,i) +
"\t" + val.substr(i);
5153 node.textContent = val;
5160 xcnt += _TAB_SIZE - (xcnt+_TAB_SIZE)%_TAB_SIZE;
5166 if(n == cursor.endNodeIndex)
5173 CodeEditor.editor.setCursor(el,cursor,
true );
5218 var specialStr =
'\t';
5221 if(_fileExtension[forPrimary][0] ==
'c' ||
5222 _fileExtension[forPrimary][0] ==
'C' ||
5223 _fileExtension[forPrimary][0] ==
'h' ||
5224 _fileExtension[forPrimary][0] ==
'H' ||
5225 _fileExtension[forPrimary][0] ==
'j')
5231 for(n=cursor.startNodeIndex; n>=0; --n)
5233 node = el.childNodes[n];
5234 val = node.textContent;
5236 for(i=(n==cursor.startNodeIndex?cursor.startPos-1:
5237 val.length-1); i>=0; --i)
5253 var prevCharIsNewLine =
false;
5254 var lookForNewLineIndex;
5256 for(; n<el.childNodes.length &&
5257 n <= cursor.endNodeIndex; ++n)
5259 node = el.childNodes[n];
5260 val = node.textContent;
5262 lookForNewLineIndex = 0;
5263 for(;i<val.length;++i)
5265 if(n == cursor.endNodeIndex && i >= cursor.endPos)
5272 if(val[i] ==
'\n' ||
5273 (i == 0 && prevCharIsNewLine))
5275 if(i == 0 && prevCharIsNewLine) --i;
5279 var didDelete =
false;
5280 if(i + specialStr.length < val.length &&
5284 (j=val.indexOf(specialStr,i+1)) == i+1 ||
5287 (k=val.indexOf(
'\n',i+1)) < 0 ||
5292 val.substr(i+1,j-(i+1)).trim().length == 0
5298 val = val.substr(0,j) +
5299 val.substr(j+specialStr.length);
5300 node.textContent = val;
5302 lookForNewLineIndex = j+specialStr.length;
5304 else if(specialStr ==
'\t')
5307 if((specialStr =
" ") &&
5308 i + specialStr.length < val.length &&
5309 val.indexOf(specialStr,i+1) == i+1)
5311 val = val.substr(0,i+1) +
5312 val.substr(i+1+specialStr.length);
5313 node.textContent = val;
5316 else if((specialStr =
" ") &&
5317 i + specialStr.length < val.length &&
5318 val.indexOf(specialStr,i+1) == i+1)
5320 val = val.substr(0,i+1) +
5321 val.substr(i+1+specialStr.length);
5322 node.textContent = val;
5325 else if((specialStr =
" ") &&
5326 i + specialStr.length < val.length &&
5327 val.indexOf(specialStr,i+1) == i+1)
5329 val = val.substr(0,i+1) +
5330 val.substr(i+1+specialStr.length);
5331 node.textContent = val;
5334 else if((specialStr =
" ") &&
5335 i + specialStr.length < val.length &&
5336 val.indexOf(specialStr,i+1) == i+1)
5338 val = val.substr(0,i+1) +
5339 val.substr(i+1+specialStr.length);
5340 node.textContent = val;
5351 if(n == cursor.startNodeIndex &&
5352 i < cursor.startPos)
5354 cursor.startPos -= specialStr.length;
5356 if(n == cursor.endNodeIndex &&
5359 cursor.endPos -= specialStr.length;
5364 if(n == cursor.endNodeIndex &&
5365 cursor.endPos >= val.length)
5367 ++cursor.endNodeIndex;
5386 val = val.substr(0,i+1) + specialStr + val.substr(i+1);
5387 node.textContent = val;
5390 if(i == -1 && prevCharIsNewLine) ++i;
5400 j = val.lastIndexOf(
'\n');
5401 if(j >= lookForNewLineIndex &&
5403 j == val[val.length-1] ||
5404 val.substr(j+1).trim().length == 0
5406 prevCharIsNewLine =
true;
5407 else if(j < 0 && prevCharIsNewLine &&
5408 val.trim().length == 0)
5409 prevCharIsNewLine =
true;
5411 prevCharIsNewLine =
false;
5414 prevCharIsNewLine = (val.length &&
5415 val[val.length-1] ==
'\n');
5419 CodeEditor.editor.setCursor(el,cursor,
true );
5449 else if(!blockCOMMENT)
5453 if(cursor.startNodeIndex !== undefined)
5458 i = cursor.startPos;
5459 node = el.childNodes[cursor.startNodeIndex];
5460 val = node.textContent;
5464 if(val[i-1] ==
'\t')
5466 node.textContent = val.substr(0,i-1) + val.substr(i);
5469 var range = document.createRange();
5470 range.setStart(node,i-1);
5471 range.setEnd(node,i-1);
5473 var selection = window.getSelection();
5474 selection.removeAllRanges();
5475 selection.addRange(range);
5485 Debug.log(
"No cursor for reverse tab.");
5488 document.execCommand(
'insertHTML',
false,
'	');
5494 else if(cursorSelection)
5496 Debug.log(
"cursorSelection handling for speed-up");
5506 console.log(
"cursorSelection char",keyCode,c);
5508 if(e.key.length > 1)
5510 if( keyCode != 46 &&
5517 e.stopPropagation();
5518 localInsertCharacter(c);
5524 if(localInsertCharacter(c))
5528 e.stopPropagation();
5538 this.updateLastSave =
function(forPrimary)
5540 forPrimary = forPrimary?1:0;
5542 var el = document.getElementById(
"textEditorLastSave" + forPrimary);
5545 Debug.log(
"updateLastSave() forPrimary=" + forPrimary);
5547 if(_fileWasModified[forPrimary])
5548 str +=
"<label style='color:red'>Unsaved changes!</label> ";
5550 str +=
"Unmodified. ";
5552 if(_fileLastSave[forPrimary])
5554 var now =
new Date();
5555 var d =
new Date(_fileLastSave[forPrimary]);
5556 var tstr = d.toLocaleTimeString();
5557 tstr = tstr.substring(0,tstr.lastIndexOf(
' ')) +
5558 (tstr[tstr.length-2]==
'A'?
"am":
"pm");
5560 var diff = ((now.getTime() - d.getTime())/1000)|0;
5564 diffStr =
"(just now) ";
5566 diffStr =
"(5 seconds ago) ";
5568 diffStr =
"(15 seconds ago) ";
5570 diffStr =
"(30 seconds ago) ";
5572 diffStr =
"(45 seconds ago) ";
5574 diffStr =
"(one minute ago) ";
5575 else if(diff < 15*60)
5576 diffStr =
"(" + ((diff/60)|0) +
" minutes ago) ";
5577 else if(diff < 20*60)
5578 diffStr =
"(15 minutes ago) ";
5579 else if(diff < 40*60)
5580 diffStr =
"(30 minutes ago) ";
5581 else if(diff < 50*60)
5582 diffStr =
"(45 minutes ago) ";
5583 else if(diff < 90*60)
5584 diffStr =
"(an hour ago) ";
5586 diffStr =
"(" + (Math.round(diff/60/60)) +
" hours ago) ";
5589 str +=
"Last save was " + diffStr + tstr;
5596 this.handleFileNameMouseMove =
function(forPrimary,doNotStartTimer)
5598 forPrimary = forPrimary?1:0;
5602 if(_fileNameEditing[forPrimary])
return;
5604 var el = document.getElementById(
"fileButtonContainerShowHide" + forPrimary);
5605 el.style.display =
"block";
5607 window.clearTimeout(_fileNameMouseMoveTimerHandle);
5609 if(doNotStartTimer)
return;
5611 _fileNameMouseMoveTimerHandle = window.setTimeout(
5614 el.style.display =
"none";
5622 this.startEditFileName =
function(forPrimary)
5624 forPrimary = forPrimary?1:0;
5626 if(_fileNameEditing[forPrimary])
return;
5627 _fileNameEditing[forPrimary] =
true;
5630 document.getElementById(
"fileButtonContainerShowHide" + forPrimary).style.display =
"none";
5633 console.log(
"startEditFileName " + forPrimary);
5635 var el = document.getElementById(
"fileNameDiv" + forPrimary);
5637 var keys = Object.keys(_fileHistoryStack);
5638 var initVal = keys[document.getElementById(
"fileNameHistorySelect" +
5639 forPrimary).value|0].trim();
5641 var _OK_CANCEL_DIALOG_STR =
"";
5643 _OK_CANCEL_DIALOG_STR +=
"<div title='' style='padding:5px;background-color:#eeeeee;border:1px solid #555555;position:relative;z-index:2000;" +
5644 "width:105px;height:20px;margin: 4px -122px -32px -120px; font-size: 16px; white-space:nowrap; text-align:center;'>";
5645 _OK_CANCEL_DIALOG_STR +=
"<a class='popUpOkCancel' onclick='" +
5646 "CodeEditor.editor.editCellOK(" + forPrimary +
5647 "); event.stopPropagation();' onmouseup='event.stopPropagation();' title='Accept Changes' style='color:green'>" +
5648 "<b style='color:green;font-size: 16px;'>OK</b></a> | " +
5649 "<a class='popUpOkCancel' onclick='" +
5650 "CodeEditor.editor.editCellCancel(" + forPrimary +
5651 "); event.stopPropagation();' onmouseup='event.stopPropagation();' title='Discard Changes' style='color:red'>" +
5652 "<b style='color:red;font-size: 16px;'>Cancel</b></a>";
5653 _OK_CANCEL_DIALOG_STR +=
"</div>";
5657 str += htmlOpen(
"input",
5660 "style":
"text-align:center;margin:-4px -2px -4px -1px;width:90%;" +
5661 " height:" + (el.offsetHeight>20?el.offsetHeight:20) +
"px",
5663 "onclick":
"event.stopPropagation();",
5672 str += _OK_CANCEL_DIALOG_STR;
5677 el = el.getElementsByTagName(
"input")[0];
5678 var startPos = initVal.lastIndexOf(
'/')+1;
5679 var endPos = initVal.lastIndexOf(
'.');
5680 if(endPos < 0) endPos = initVal.length;
5681 el.setSelectionRange(startPos, endPos);
5688 this.editCellOK =
function(forPrimary)
5690 forPrimary = forPrimary?1:0;
5692 var val = document.getElementById(
"fileNameDiv" + forPrimary).getElementsByTagName(
"input")[0].value;
5693 console.log(
"editCellOK " + forPrimary +
" = " + val);
5694 _fileNameEditing[forPrimary] =
false;
5696 var extPos = val.lastIndexOf(
'.');
5700 _filePath[forPrimary] = val.substr(0,extPos);
5701 _fileExtension[forPrimary] = extPos > 0?val.substr(extPos+1):
"";
5716 _fileWasModified[forPrimary] =
true;
5717 _fileLastSave[forPrimary] = 0;
5718 CodeEditor.editor.updateLastSave(forPrimary);
5729 _fileHistoryStack[_filePath[forPrimary] +
"." +
5730 _fileExtension[forPrimary]] = [
5731 _eel[forPrimary].textContent,
5733 _fileWasModified[forPrimary],
5734 _fileLastSave[forPrimary]];
5735 console.log(
"_fileHistoryStack",_fileHistoryStack);
5737 CodeEditor.editor.updateFileHistoryDropdowns();
5743 this.editCellCancel =
function(forPrimary)
5745 forPrimary = forPrimary?1:0;
5747 Debug.log(
"editCellCancel " + forPrimary);
5748 _fileNameEditing[forPrimary] =
false;
5751 CodeEditor.editor.updateFileHistoryDropdowns(forPrimary);
5760 this.updateFileHistoryDropdowns =
function(forPrimarySelect)
5762 Debug.log(
"updateFileHistoryDropdowns forPrimarySelect=" + forPrimarySelect);
5769 var keys = Object.keys(_fileHistoryStack);
5772 for(var forPrimary=0;forPrimary<2;++forPrimary)
5774 if(forPrimarySelect !== undefined &&
5775 forPrimarySelect != forPrimary)
continue;
5777 currentFile = _filePath[forPrimary] +
"." + _fileExtension[forPrimary];
5779 str += htmlOpen(
"select",
5781 "class":
"fileNameHistorySelect",
5782 "id":
"fileNameHistorySelect" + forPrimary,
5783 "style":
"width:100%;" +
5784 "text-align-last: center;",
5785 "title":
"The current file is\n" + currentFile,
5787 "CodeEditor.editor.handleFileNameHistorySelect(" +
5789 "onclick":
"CodeEditor.editor.stopUpdateHandling(event);",
5790 "onfocus":
"CodeEditor.editor.lastFileNameHistorySelectIndex = this.value;" +
5792 "onblur":
"this.value = CodeEditor.editor.lastFileNameHistorySelectIndex;",
5797 for(i=0;i<keys.length;++i)
5801 str +=
"<option value='" + i +
"' ";
5802 if(currentFile == keys[i])
5805 if(_fileHistoryStack[keys[i]][2])
5806 str +=
"*MODIFIED* ";
5815 el = document.getElementById(
"fileNameDiv" + forPrimary);
5820 Debug.log(
"Ignoring error since file forPrimary=" +
5821 forPrimary +
" is probably not opened: " +
5831 this.handleFileNameHistorySelect =
function(forPrimary)
5833 forPrimary = forPrimary?1:0;
5835 var selectedFileIndex = document.getElementById(
"fileNameHistorySelect" + forPrimary).value | 0;
5836 Debug.log(
"updateFileHistoryDropdowns " + forPrimary +
5837 "selected=" + selectedFileIndex);
5839 var keys = Object.keys(_fileHistoryStack);
5840 var selectedFileName = keys[selectedFileIndex];
5842 Debug.log(
"selectedFileName " + selectedFileName);
5848 var fileArr = selectedFileName.split(
'.');
5851 if(fileArr[0] == _filePath[forPrimary] &&
5852 fileArr[1] == _fileExtension[forPrimary])
5854 CodeEditor.editor.openFile(forPrimary,
5855 _filePath[forPrimary],
5856 _fileExtension[forPrimary],
5861 fileObj.path = fileArr[0];
5862 fileObj.extension = fileArr[1];
5863 fileObj.text = _fileHistoryStack[selectedFileName][0];
5864 fileObj.fileWasModified = _fileHistoryStack[selectedFileName][2];
5865 fileObj.fileLastSave = _fileHistoryStack[selectedFileName][3];
5867 console.log(
"fileObj",fileObj);
5869 CodeEditor.editor.handleFileContent(forPrimary,0,fileObj);
5876 this.showFindAndReplace =
function(forPrimary)
5878 forPrimary = forPrimary?1:0;
5879 _activePaneIsPrimary = forPrimary;
5881 Debug.log(
"showFindAndReplace forPrimary=" + forPrimary +
" activePane=" + _activePaneIsPrimary);
5883 CodeEditor.editor.findAndReplaceLastButton[forPrimary] = 1;
5886 var el = _eel[forPrimary];
5887 var cursor = _findAndReplaceCursorInContent[forPrimary] =
5888 CodeEditor.editor.getCursor(el);
5891 el = document.getElementById(
"textEditorHeader" + forPrimary);
5896 str +=
"<table style='margin-top: 2px;'>";
5900 str +=
"<tr><td style='text-align:right'>";
5903 str += htmlOpen(
"input",
5906 "id":
"findAndReplaceFind" + forPrimary,
5907 "style":
"text-align:left; width:90%;" +
5908 " height:" + (20) +
"px",
5909 "value": CodeEditor.editor.findAndReplaceFind[forPrimary],
5910 "onclick":
"event.stopPropagation();",
5911 "onchange":
"CodeEditor.editor.findAndReplaceFind[" +
5912 forPrimary +
"] = this.value;" +
5913 "CodeEditor.editor.showFindAndReplaceSelection(" +
5920 str += htmlOpen(
"select",
5922 "id":
"findAndReplaceScope" + forPrimary,
5923 "style":
"width:100%;" +
5924 "text-align-last: center;",
5925 "title":
"Choose the scope for Replace All",
5926 "onclick":
"event.stopPropagation();" ,
5927 "onchange":
"CodeEditor.editor.findAndReplaceScope[" +
5928 forPrimary +
"] = this.value;" +
5929 "CodeEditor.editor.showFindAndReplaceSelection(" +
5933 str +=
"<option value='0'>All Lines</option>";
5934 str +=
"<option value='1' " + (CodeEditor.editor.findAndReplaceScope[forPrimary] ==
5935 1?
"selected":
"") +
">Selected Lines</option>";
5941 str += htmlOpen(
"input",
5944 "id":
"findAndReplaceCaseSensitive" + forPrimary,
5945 "title":
"Toggle case sensitive search",
5946 "onclick":
"event.stopPropagation();",
5947 "style":
"margin-left:10px;",
5948 "onchange":
"CodeEditor.editor.findAndReplaceCaseSensitive[" +
5949 forPrimary +
"] = this.checked;" +
5950 "CodeEditor.editor.showFindAndReplaceSelection(" +
5956 "title":
"Toggle case sensitive search",
5957 "style":
"margin-left:5px;",
5958 "onclick":
"event.stopPropagation();" +
5959 "var el = document.getElementById(\"findAndReplaceCaseSensitive" +
5960 forPrimary +
"\"); el.checked = !el.checked;" +
5961 "CodeEditor.editor.findAndReplaceCaseSensitive[" +
5962 forPrimary +
"] = el.checked;" +
5963 "CodeEditor.editor.showFindAndReplaceSelection(" +
5967 "Case sensitive" ,
true
5970 str +=
"</td></tr>";
5973 str +=
"<tr><td style='text-align:right'>";
5974 str +=
"Replace with:";
5976 str += htmlOpen(
"input",
5979 "id":
"findAndReplaceReplace" + forPrimary,
5980 "style":
"text-align:left; width:90%;" +
5981 " height:" + (20) +
"px",
5982 "value": CodeEditor.editor.findAndReplaceReplace[forPrimary],
5983 "onclick":
"event.stopPropagation();",
5984 "onchange":
"CodeEditor.editor.findAndReplaceReplace[" +
5985 forPrimary +
"] = this.value; " +
5986 "CodeEditor.editor.showFindAndReplaceSelection(" +
5993 str += htmlOpen(
"select",
5995 "id":
"findAndReplaceDirection" + forPrimary,
5996 "style":
"width:100%;" +
5997 "text-align-last: center;",
5998 "title":
"Choose the search direction for the Find & Replace",
5999 "onclick":
"event.stopPropagation();",
6000 "onchange":
"CodeEditor.editor.findAndReplaceDirection[" +
6001 forPrimary +
"] = this.value;" +
6002 "CodeEditor.editor.showFindAndReplaceSelection(" +
6006 str +=
"<option value='0'>Search Forward</option>";
6007 str +=
"<option value='1' " + (CodeEditor.editor.findAndReplaceDirection[forPrimary] ==
6009 ">Search Backward</option>";
6015 str += htmlOpen(
"input",
6018 "id":
"findAndReplaceWholeWord" + forPrimary,
6019 "title":
"Toggle whole word search",
6020 "onclick":
"event.stopPropagation();",
6021 "style":
"margin-left:10px;",
6022 "onchange":
"CodeEditor.editor.findAndReplaceWholeWord[" +
6023 forPrimary +
"] = this.checked;" +
6024 "CodeEditor.editor.showFindAndReplaceSelection(" +
6030 "style":
"margin-left:5px;",
6031 "title":
"Toggle whole word search",
6032 "onclick":
"event.stopPropagation();" +
6033 "var el = document.getElementById(\"findAndReplaceWholeWord" +
6034 forPrimary +
"\"); el.checked = !el.checked;" +
6035 "CodeEditor.editor.findAndReplaceWholeWord[" +
6036 forPrimary +
"] = el.checked;" +
6037 "CodeEditor.editor.showFindAndReplaceSelection(" +
6043 str +=
"</td></tr>";
6047 str +=
"<tr><td colspan='4' style='text-align:center'>";
6048 str += htmlOpen(
"div",
6050 "id":
"findAndReplaceWrapped" + forPrimary,
6051 "style":
"text-align:right; margin: 4px; width:115px;" +
6052 "color: red; float: left;",
6054 str +=
"<div style='float:left;'>";
6055 str += htmlOpen(
"input",
6060 "style":
"text-align:center; margin: 4px;" ,
6061 "onclick":
"event.stopPropagation();" +
6062 "CodeEditor.editor.doFindAndReplaceAction(" + forPrimary +
",1)",
6065 str += htmlOpen(
"input",
6070 "style":
"text-align:center; margin: 4px;" ,
6071 "onclick":
"event.stopPropagation();" +
6072 "CodeEditor.editor.doFindAndReplaceAction(" + forPrimary +
",2)",
6075 str += htmlOpen(
"input",
6078 "value":
"Replace & Find",
6080 "style":
"text-align:center; margin: 4px;" ,
6081 "onclick":
"event.stopPropagation();" +
6082 "CodeEditor.editor.doFindAndReplaceAction(" + forPrimary +
",3)",
6085 str += htmlOpen(
"input",
6088 "value":
"Replace All",
6090 "style":
"text-align:center; margin: 4px;" ,
6091 "onclick":
"event.stopPropagation();" +
6092 "CodeEditor.editor.doFindAndReplaceAction(" + forPrimary +
",4)",
6095 str += htmlOpen(
"input",
6099 "title":
"Close find and replace controls.",
6100 "style":
"text-align:center; margin: 4px;" ,
6102 "onclick":
"event.stopPropagation();" +
6103 "CodeEditor.editor.displayFileHeader(" + forPrimary +
")",
6107 str +=
"</td></tr>";
6114 el = document.getElementById(
"findAndReplaceFind" + forPrimary);
6115 el.setSelectionRange(0, el.value.length);
6118 el = document.getElementById(
"findAndReplaceCaseSensitive" + forPrimary);
6119 el.checked = CodeEditor.editor.findAndReplaceCaseSensitive[forPrimary];
6121 el = document.getElementById(
"findAndReplaceWholeWord" + forPrimary);
6122 el.checked = CodeEditor.editor.findAndReplaceWholeWord[forPrimary];
6129 this.showFindAndReplaceSelection =
function(forPrimary)
6131 forPrimary = forPrimary?1:0;
6132 Debug.log(
"showFindAndReplaceSelection forPrimary=" + forPrimary);
6134 var el = _eel[forPrimary];
6135 var cursor = CodeEditor.editor.getCursor(el);
6137 if(cursor.startPosInContent !== undefined)
6138 CodeEditor.editor.setCursor(el,
6142 CodeEditor.editor.findAndReplaceLastButton[forPrimary] > 0 &&
6143 _findAndReplaceCursorInContent[forPrimary] !== undefined)
6144 CodeEditor.editor.setCursor(el,
6145 _findAndReplaceCursorInContent[forPrimary],
6158 this.doFindAndReplaceAction =
function(forPrimary,action)
6160 forPrimary = forPrimary?1:0;
6161 action = action | 0;
6163 CodeEditor.editor.findAndReplaceLastButton[forPrimary] = action;
6165 var find = document.getElementById(
"findAndReplaceFind" + forPrimary).value;
6166 var originalFind = find;
6167 if(!find || find ==
"")
6169 Debug.log(
"Illegal empty string to find.", Debug.HIGH_PRIORITY);
6172 var replace = CodeEditor.editor.findAndReplaceReplace[forPrimary];
6173 var scope = CodeEditor.editor.findAndReplaceScope[forPrimary]|0;
6174 var direction = CodeEditor.editor.findAndReplaceDirection[forPrimary]|0;
6177 var caseSensitive = CodeEditor.editor.findAndReplaceCaseSensitive[forPrimary]?1:0;
6178 var wholeWord = CodeEditor.editor.findAndReplaceWholeWord[forPrimary]?1:0;
6180 Debug.log(
"doFindAndReplaceAction forPrimary=" + forPrimary +
6181 " action=" + action +
6183 " replace=" + replace +
6185 " direction=" + direction +
6186 " caseSensitive=" + caseSensitive +
6187 " wholeWord=" + wholeWord);
6198 var el = _eel[forPrimary];
6199 var originalText = el.textContent;
6202 text = originalText;
6205 text = originalText.toLowerCase();
6206 find = find.toLowerCase();
6209 var i = direction?text.length:-1;
6210 var j = text.length-1;
6212 var cursor = CodeEditor.editor.getCursor(el);
6215 if(cursor.startPosInContent !== undefined &&
6217 document.getElementById(
"findAndReplaceWrapped" + forPrimary).textContent ==
""))
6218 i = cursor.startPosInContent;
6219 else if(_findAndReplaceCursorInContent[forPrimary] !== undefined &&
6220 _findAndReplaceCursorInContent[forPrimary].startPosInContent !== undefined &&
6221 _findAndReplaceCursorInContent[forPrimary].startPosInContent >= 0 &&
6223 document.getElementById(
"findAndReplaceWrapped" + forPrimary).textContent ==
""))
6225 i = _findAndReplaceCursorInContent[forPrimary].startPosInContent;
6228 CodeEditor.editor.setCursor(el,
6229 _findAndReplaceCursorInContent[forPrimary],
6234 document.getElementById(
"findAndReplaceWrapped" + forPrimary).innerHTML =
"";
6236 Debug.log(
"Starting position: " + i);
6240 if(cursor.endPosInContent !== undefined)
6241 j = cursor.endPosInContent;
6242 else if(_findAndReplaceCursorInContent[forPrimary] !== undefined &&
6243 _findAndReplaceCursorInContent[forPrimary].endPosInContent != undefined &&
6244 _findAndReplaceCursorInContent[forPrimary].endPosInContent >= 0)
6245 j = _findAndReplaceCursorInContent[forPrimary].endPosInContent;
6247 Debug.log(
"Ending position: " + j);
6249 else if(action == 4)
6252 var replaceCount = 0;
6265 if(i > 0 && i + find.length <= text.length)
6271 Debug.log(
"Replacing");
6276 originalText.substr(0,i) +
6278 originalText.substr(i+find.length);
6282 text = originalText;
6284 text = originalText.toLowerCase();
6291 Debug.log(
"Unrecognized action! " + action, Debug.HIGH_PRIORITY);
6305 i = text.indexOf(find,i+1);
6306 else if(direction == 1)
6307 i = text.lastIndexOf(find,i-1);
6313 (text[i-1] >=
'a' && text[i-1] <=
'z') ||
6314 (text[i-1] >=
'A' && text[i-1] <=
'Z') ||
6315 (text[i-1] >=
'0' && text[i-1] <=
'9') ||
6322 else if(i>0 && i+find.length<text.length && (
6323 (text[i+find.length] >=
'a' && text[i+find.length] <=
'z') ||
6324 (text[i+find.length] >=
'A' && text[i+find.length] <=
'Z') ||
6325 (text[i+find.length] >=
'0' && text[i+find.length] <=
'9') ||
6326 text[i+find.length] ==
'_'
6346 if(i + find.length < j)
6354 document.getElementById(
"findAndReplaceWrapped" + forPrimary).innerHTML =
"Reached end";
6364 Debug.log(
"Unrecognized action! " + action, Debug.HIGH_PRIORITY);
6382 el.textContent = originalText;
6383 CodeEditor.editor.updateDecorations(forPrimary);
6388 _findAndReplaceCursorInContent[forPrimary] =
6389 CodeEditor.editor.createCursorFromContentPosition(el,
6390 i, i + find.length);
6391 CodeEditor.editor.setCursor(
6393 _findAndReplaceCursorInContent[forPrimary],
6402 _findAndReplaceCursorInContent[forPrimary] =
6403 CodeEditor.editor.createCursorFromContentPosition(el,
6405 CodeEditor.editor.setCursor(
6407 _findAndReplaceCursorInContent[forPrimary],
6412 Debug.log(
"Unrecognized action! " + action, Debug.HIGH_PRIORITY);
6420 document.getElementById(
"findAndReplaceWrapped" + forPrimary).innerHTML =
6421 replaceCount +
" Replaced";
6428 this.displayFileHeader =
function(forPrimary)
6430 forPrimary = forPrimary?1:0;
6432 var forceDisplayComplete =
false;
6433 if(CodeEditor.editor.findAndReplaceLastButton[forPrimary] != -1)
6435 CodeEditor.editor.findAndReplaceLastButton[forPrimary] = -1;
6436 forceDisplayComplete =
true;
6439 Debug.log(
"displayFileHeader forPrimary=" + forPrimary);
6442 var el = document.getElementById(
"textEditorHeader" + forPrimary);
6445 var path = _filePath[forPrimary];
6446 var extension = _fileExtension[forPrimary];
6453 str += htmlOpen(
"div",
6456 "CodeEditor.editor.handleFileNameMouseMove(" + forPrimary +
");",
6461 if (_requestPreamble ==
"readOnly") {
6462 str += htmlOpen(
"div",
6464 "class":
"fileButtonContainer",
6465 "style":
"width: 48px;",
6466 "id":
"fileButtonContainer" + forPrimary,
6471 str += htmlOpen(
"div",
6474 "style":
"width: 148px;",
6475 "class":
"fileButtonContainer",
6476 "id":
"fileButtonContainer" + forPrimary,
6480 str += htmlOpen(
"div",
6482 "class":
"fileButtonContainerShowHide",
6483 "id":
"fileButtonContainerShowHide" + forPrimary,
6485 "event.stopPropagation(); " +
6486 "CodeEditor.editor.handleFileNameMouseMove(" + forPrimary +
6487 ",1 /*doNotStartTimer*/);",
6490 if (_requestPreamble !==
"readOnly") {
6491 str += htmlOpen(
"div",
6493 "class":
"fileButton",
6494 "id":
"fileRenameButton" + forPrimary,
6495 "title":
"Change the filename\n" + path +
"." + extension,
6497 "event.stopPropagation(); " +
6498 "CodeEditor.editor.startEditFileName(" + forPrimary +
");",
6501 str += htmlOpen(
"div",
6503 "class":
"fileButton",
6504 "id":
"fileDownloadButton" + forPrimary,
6505 "title":
"Download the file content from\n" + path +
"." + extension,
6507 "event.stopPropagation(); " +
6508 "CodeEditor.editor.download(" + forPrimary +
");",
6511 "<div class='fileDownloadButtonBgChild' style='display: ; margin-left: 0px; margin-top: 1px; height:7px; width: 6px; background-color: rgb(202, 204, 210);'></div>" +
6512 "<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>" +
6513 "<div class='fileDownloadButtonBgChild' style='position: relative; top: 2px; width: 12px; height: 2px; display: block; background-color: rgb(202, 204, 210);'></div>"
6515 if (_requestPreamble !==
"readOnly") {
6516 str += htmlOpen(
"div",
6518 "class":
"fileButton",
6519 "id":
"fileUploadButton" + forPrimary,
6520 "title":
"Upload file content to\n" + path +
"." + extension,
6522 "event.stopPropagation(); " +
6523 "CodeEditor.editor.upload(" + forPrimary +
");",
6527 "<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>" +
6528 "<div class='fileDownloadButtonBgChild' style='display: block; margin-left: 0px; height:7px; width: 6px; background-color: rgb(202, 204, 210);'></div>" +
6529 "<div class='fileDownloadButtonBgChild' style='position: relative; top: 3px; width: 12px; height: 2px; display: block; background-color: rgb(202, 204, 210);'></div>"
6532 if (_requestPreamble !==
"readOnly") {
6533 str += htmlOpen(
"div",
6535 "class":
"fileButton fileUndoButton",
6536 "id":
"fileUndoButton" + forPrimary,
6537 "title":
"Undo to rewind to last recorded checkpoint for\n" + path +
"." + extension,
6538 "style":
"color: rgb(202, 204, 210);" +
6539 "padding: 0 5px 0;" +
6540 "font-size: 17px;" +
6541 "font-weight: bold;",
6543 "event.stopPropagation(); " +
6544 "CodeEditor.editor.undo(" + forPrimary +
");",
6550 str += htmlOpen(
"div",
6552 "class":
"fileButton fileUndoButton",
6553 "id":
"fileRedoButton" + forPrimary,
6554 "title":
"Redo to fast-forward to last recorded checkpoint for\n" + path +
"." + extension,
6555 "style":
"color: rgb(202, 204, 210);" +
6556 "padding: 0 5px 0;" +
6557 "font-size: 17px;" +
6558 "font-weight: bold;",
6560 "event.stopPropagation(); " +
6561 "CodeEditor.editor.undo(" + forPrimary +
",1 /*redo*/);",
6568 str += htmlOpen(
"div",
6570 "class":
"fileButton openRelatedFileButton",
6571 "id":
"openRelatedFileButton" + forPrimary,
6572 "title":
"Open related file in other pane for\n" + path +
"." + extension,
6573 "style":
"color: rgb(202, 204, 210);" +
6574 "padding: 0 5px 0;" +
6575 "font-size: 17px;" +
6576 "font-weight: bold;",
6578 "event.stopPropagation(); " +
6579 "CodeEditor.editor.openRelatedFile(" + forPrimary +
6580 ", true /*inOtherPane*/);",
6591 str += htmlClearDiv();
6594 str +=
"<table><tr><td>";
6596 str += htmlOpen(
"a",
6598 "title":
"Open file in a new browser tab: \n" +
6599 "srcs" + path +
"." + extension,
6600 "onclick":
"DesktopContent.openNewBrowserTab(" +
6601 "\"Code Editor\",\"\"," +
6602 "\"/WebPath/html/CodeEditor.html?urn=" +
6603 DesktopContent._localUrnLid +
"&" +
6604 "startFilePrimary=" +
6605 path +
"." + extension +
"\",0 /*unique*/);' ",
6607 "<img class='dirNavFileNewWindowImgNewWindow' " +
6608 "src='/WebPath/images/windowContentImages/CodeEditor-openInNewWindow.png'>"
6612 str += htmlOpen(
"a",
6614 "title":
"Open file in the other editor pane of the split-view: \n" +
6615 "srcs" + path +
"." + extension,
6616 "onclick":
"CodeEditor.editor.openFile(" +
6617 (!forPrimary) +
",\"" +
6622 "<img class='dirNavFileNewWindowImgNewPane' " +
6623 "src='/WebPath/images/windowContentImages/CodeEditor-openInOtherPane.png'>"
6628 str += htmlOpen(
"div",
6630 "class":
"fileNameDiv",
6631 "id":
"fileNameDiv" + forPrimary,
6632 "style":
"margin: 0 5px 0 5px",
6634 str +=
"<a onclick='CodeEditor.editor.openFile(" + forPrimary +
6635 ",\"" + path +
"\",\"" + extension +
"\",true /*doConfirm*/);' " +
6636 "title='Click to reload \n" + path +
"." + extension +
"' " +
6638 path +
"." + extension +
"</a>";
6641 str +=
"</td></tr></table>";
6645 str += htmlClearDiv();
6648 str +=
"<div class='textEditorLastSave' id='textEditorLastSave" +
6649 forPrimary +
"'>Unmodified</div>";
6651 str += htmlClearDiv();
6653 str +=
"<div class='textEditorOutline' id='textEditorOutline" +
6654 forPrimary +
"'>Outline:</div>";
6658 CodeEditor.editor.updateDecorations(forPrimary,forceDisplayComplete);
6659 CodeEditor.editor.updateFileHistoryDropdowns();
6669 this.updateFileSnapshot =
function(forPrimary,textObj , ignoreTimeDelta)
6671 forPrimary = forPrimary?1:0;
6673 Debug.log(
"updateFileSnapshot forPrimary=" + forPrimary);
6676 var addSnapshot =
false;
6678 if(_undoStackLatestIndex[forPrimary] != -1)
6682 if((ignoreTimeDelta ||
6683 2*1000 < textObj.time - _undoStack[forPrimary][_undoStackLatestIndex[forPrimary]][1]) &&
6684 _undoStack[forPrimary][_undoStackLatestIndex[forPrimary]][0] != textObj.text)
6693 ++_undoStackLatestIndex[forPrimary];
6694 if(_undoStackLatestIndex[forPrimary] >= _undoStack_MAX_SIZE)
6695 _undoStackLatestIndex[forPrimary] = 0;
6697 _undoStack[forPrimary][_undoStackLatestIndex[forPrimary]] =
6701 console.log(
"snapshot added to stack",_undoStack[forPrimary]);
6709 _fileHistoryStack[_filePath[forPrimary] +
"." +
6710 _fileExtension[forPrimary]] = [
6713 _fileWasModified[forPrimary],
6714 _fileLastSave[forPrimary]];
6715 console.log(
"_fileHistoryStack",_fileHistoryStack);
6717 CodeEditor.editor.updateFileHistoryDropdowns();
6727 this.startUpdateHandling =
function(forPrimary)
6729 _updateHandlerTargetPane[forPrimary] =
true;
6731 window.clearTimeout(_updateTimerHandle);
6732 _updateTimerHandle = window.setTimeout(
6733 CodeEditor.editor.updateTimeoutHandler,
6734 _UPDATE_DECOR_TIMEOUT );
6741 this.stopUpdateHandling =
function(event)
6743 if(event)
event.stopPropagation();
6744 window.clearTimeout(_updateTimerHandle);
6750 this.updateTimeoutHandler =
function()
6752 if(_updateHandlerTargetPane[0])
6754 CodeEditor.editor.updateDecorations(0 );
6755 _updateHandlerTargetPane[0] =
false;
6757 if(_updateHandlerTargetPane[1])
6759 CodeEditor.editor.updateDecorations(1 );
6760 _updateHandlerTargetPane[1] =
false;
6767 this.doubleClickHandler =
function(forPrimary)
6769 forPrimary = forPrimary?1:0;
6771 Debug.log(
"doubleClickHandler forPrimary=" + forPrimary);
6777 var el = _eel[forPrimary];
6778 var cursor = CodeEditor.editor.getCursor(el);
6780 if(!cursor || cursor.startNodeIndex === undefined)
6783 var n = cursor.startNodeIndex;
6784 var c = el.childNodes[n].textContent[
6789 if(c !=
'{' && c !=
'}')
6791 if(cursor.startPos == 0)
6797 }
while(n >= 0 && el.childNodes[n].textContent.length);
6800 c = el.childNodes[n].textContent[
6801 el.childNodes[n].textContent.length-1];
6804 c = el.childNodes[n].textContent[
6811 Debug.log(
"character before cursor " + c);
6813 if(c !=
'{' && c !=
'}')
return;
6817 var foundDoubleQuote =
false;
6818 var foundSingleQuote =
false;
6819 var foundComment =
false;
6824 cursor.endNodeIndex = -1;
6831 var openCountSave = openCount;
6832 var prelimFound =
false;
6836 node = el.childNodes[n];
6837 val = node.textContent;
6838 for(i=(n==cursor.startNodeIndex?cursor.startPos-1:
6839 val.length-1); i>=0; --i)
6841 if(cursor.endNodeIndex == -1)
6843 cursor.endNodeIndex = n;
6849 foundSingleQuote =
false;
6850 foundDoubleQuote =
false;
6851 openCountSave = openCount;
6855 Debug.log(
"confirmed found open count match ni " + n +
" " + i);
6861 if(!foundSingleQuote && val[i] ==
'"')
6862 foundDoubleQuote = !foundDoubleQuote;
6863 else if(!foundDoubleQuote && val[i] ==
"'")
6864 foundSingleQuote = !foundSingleQuote;
6865 else if(val[i]==
'/' && i-1 >= 0 &&
6869 openCount = openCountSave;
6871 prelimFound =
false;
6877 if(foundDoubleQuote || foundSingleQuote ||
6883 else if(val[i] ==
'{')
6889 Debug.log(
"found open count match ni " + n +
" " + i);
6896 cursor.startNodeIndex = n;
6897 cursor.startPos = i;
6908 i = cursor.startPos;
6909 for(n=cursor.startNodeIndex;n<el.childNodes.length; ++n)
6911 node = el.childNodes[n];
6912 val = node.textContent;
6914 for(; i<val.length; ++i)
6918 foundSingleQuote =
false;
6919 foundDoubleQuote =
false;
6920 foundComment =
false;
6926 if(!foundSingleQuote && val[i] ==
'"')
6927 foundDoubleQuote = !foundDoubleQuote;
6928 else if(!foundDoubleQuote && val[i] ==
"'")
6929 foundSingleQuote = !foundSingleQuote;
6930 else if(val[i]==
'/' && i+1 < val.length &&
6933 foundComment =
true;
6937 if(foundDoubleQuote || foundSingleQuote)
6942 else if(val[i] ==
'}')
6948 Debug.log(
"found open count match ni " + n +
" " + i);
6953 cursor.endNodeIndex = n;
6965 CodeEditor.editor.setCursor(el,cursor);
6972 this.download =
function(forPrimary)
6974 forPrimary = forPrimary?1:0;
6976 Debug.log(
"download forPrimary=" + forPrimary);
6978 var dataStr =
"data:text/plain;charset=utf-8," +
6979 encodeURIComponent(_eel[forPrimary].textContent);
6981 var filename = _filePath[forPrimary];
6982 var i = filename.lastIndexOf(
'/');
6984 filename = filename.substr(i+1);
6985 filename +=
"." + _fileExtension[forPrimary];
6987 Debug.log(
"Downloading to filename " + filename);
6989 var link = document.createElement(
"a");
6990 link.setAttribute(
"href", dataStr);
6991 link.setAttribute(
"style",
"display:none");
6992 link.setAttribute(
"download", filename);
6993 document.body.appendChild(link);
6997 link.parentNode.removeChild(link);
7003 this.upload =
function(forPrimary)
7005 forPrimary = forPrimary?1:0;
7007 Debug.log(
"upload forPrimary=" + forPrimary);
7009 _fileUploadString =
"";
7013 var el = document.getElementById(
"popUpDialog");
7016 el = document.createElement(
"div");
7017 el.setAttribute(
"id",
"popUpDialog");
7019 el.style.display =
"none";
7024 DesktopContent.setPopUpPosition(el,w ,h );
7026 var str =
"<a id='" +
7028 "-header' onclick='var el = document.getElementById(" +
7029 "\"popUpDialog\"); if(el) el.parentNode.removeChild(el); return false;'>Cancel</a><br><br>";
7031 str +=
"<div id='popUpDialog-div'>";
7033 str +=
"Please choose the file to upload which has the text content to place in the open source file:<br><br>" +
7034 _filePath[forPrimary] +
"." + _fileExtension[forPrimary] +
7039 str +=
"<input type='file' id='popUpDialog-fileUpload' " +
7041 for(var i=0;i<_ALLOWED_FILE_EXTENSIONS.length;++i)
7042 str += (i?
", ":
"") +
"." + _ALLOWED_FILE_EXTENSIONS[i];
7043 str +=
"' enctype='multipart/form-data' />";
7046 var onmouseupJS =
"";
7047 onmouseupJS +=
"document.getElementById(\"popUpDialog-submitButton\").disabled = true;";
7048 onmouseupJS +=
"CodeEditor.editor.uploadTextFromFile(" + forPrimary +
");";
7050 str +=
"<input id='popUpDialog-submitButton' disabled type='button' onmouseup='" +
7051 onmouseupJS +
"' " +
7052 "value='Upload File' title='" +
7053 "Upload the chosen file text content to\n" +
7054 _filePath[forPrimary] +
"." + _fileExtension[forPrimary] +
7058 document.body.appendChild(el);
7059 el.style.display =
"block";
7061 document.getElementById(
'popUpDialog-fileUpload').addEventListener(
7062 'change',
function(evt) {
7063 var files = evt.target.files;
7064 var file = files[0];
7065 var reader =
new FileReader();
7066 reader.onload =
function() {
7068 _fileUploadString = this.result;
7069 Debug.log(
"_fileUploadString = " + _fileUploadString);
7070 document.getElementById(
'popUpDialog-submitButton').disabled =
false;
7072 reader.readAsText(file);
7078 this.uploadTextFromFile =
function(forPrimary)
7080 forPrimary = forPrimary?1:0;
7082 Debug.log(
"uploadTextFromFile forPrimary=" + forPrimary);
7085 document.getElementById(
'popUpDialog-submitButton').disabled =
false;
7087 Debug.log(
"uploadTextFromFile _fileUploadString = " + _fileUploadString);
7091 DesktopContent.showLoading(
function()
7097 _fileUploadString = _fileUploadString.replace(
new RegExp(
7098 String.fromCharCode(160),
'g'),
' ');
7099 _fileUploadString =
"hi";
7100 var el = _eel[forPrimary];
7101 el.textContent = _fileUploadString;
7102 CodeEditor.editor.displayFileHeader(forPrimary);
7106 Debug.log(
"There was an error uploading the text: " + e,
7107 Debug.HIGH_PRIORITY);
7110 Debug.log(
"Source upload complete! (You can use undo to go back) ",
7111 Debug.INFO_PRIORITY);
7114 var el = document.getElementById(
"popUpDialog");
7115 if(el) el.parentNode.removeChild(el);