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>";
68 if (!Element.prototype.scrollIntoViewIfNeeded) {
69 Element.prototype.scrollIntoViewIfNeeded =
function (centerIfNeeded) {
70 centerIfNeeded = arguments.length === 0 ?
true : !!centerIfNeeded;
72 var parent = this.parentNode,
73 tdParent = parent.parentNode,
74 editorParent = parent.parentNode.parentNode.parentNode.parentNode.parentNode,
75 parentComputedStyle = window.getComputedStyle(parent, null),
76 parentBorderTopWidth = parseInt(parentComputedStyle.getPropertyValue(
'border-top-width')),
77 parentBorderLeftWidth = parseInt(parentComputedStyle.getPropertyValue(
'border-left-width')),
78 overTop = this.offsetTop - tdParent.offsetTop < editorParent.scrollTop,
79 overBottom = (
this.offsetTop - tdParent.offsetTop +
this.clientHeight - parentBorderTopWidth) > (editorParent.scrollTop + editorParent.clientHeight),
80 overLeft = this.offsetLeft - tdParent.offsetLeft < editorParent.scrollLeft,
81 overRight = (
this.offsetLeft + tdParent.offsetLeft +
this.clientWidth - parentBorderLeftWidth) > (editorParent.scrollLeft + editorParent.clientWidth),
82 alignWithTop = overTop && !overBottom;
84 if ((overTop || overBottom) && centerIfNeeded) {
85 editorParent.scrollTop = this.offsetTop - tdParent.offsetTop - editorParent.clientHeight / 2 - parentBorderTopWidth + this.clientHeight / 2;
89 if ((overLeft || overRight) && centerIfNeeded) {
90 editorParent.scrollLeft = this.offsetLeft + tdParent.offsetLeft - editorParent.clientWidth / 2 - parentBorderLeftWidth + this.clientWidth / 2;
94 if ((overTop || overBottom || overLeft || overRight) && !centerIfNeeded) {
95 this.scrollIntoView(alignWithTop);
103 CodeEditor.showTooltip =
function(alwaysShow)
105 DesktopContent.tooltip(
106 (alwaysShow?
"ALWAYS":
"Code Editor"),
107 "Welcome to the Code Editor user interface. "+
108 "Edit your code, save it, and compile!\n\n" +
109 "Hover your mouse over the icons and buttons to see what they do. " +
110 "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" +
112 "<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" +
113 "<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" +
114 "<b>Save:</b>\n<INDENT>Use the save icon in the top-left to save your changes.</INDENT>\n" +
115 "<b>Compile:</b>\n<INDENT>Use the Incremmental Build or Clean Build icons in the top-right.</INDENT>\n" +
117 "<b>Global Hot Keys:</b>\n<INDENT>" +
119 "<table border=0 cellspacing=0 cellpadding=0 style='border: 1px solid grey;'>" +
120 "<tr style='background-color: rgb(106, 102, 119);'><td style='white-space: nowrap; padding:5px;'> " +
121 "Ctrl + B </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Incremental Build</td></tr>" +
122 "<tr><td style='white-space: nowrap; padding:5px;'> " +
123 "Ctrl + N </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Clean Build</td></tr>" +
124 "<tr style='background-color: rgb(106, 102, 119);'><td style='white-space: nowrap; padding:5px;'> " +
125 "Ctrl + 2 </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Toggle Split-View Mode (single, dual-vertical, dual-horizontal)</td></tr>" +
126 "</table></INDENT>\n" +
129 "<b>Editor Pane Hot Keys:</b>\n<INDENT>" +
131 "<table border=0 cellspacing=0 cellpadding=0 style='border: 1px solid grey;'>" +
133 "<tr style='background-color: rgb(106, 102, 119);'><td style='white-space: nowrap; padding:5px;'> " +
134 "Ctrl + S </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Save File</td></tr>" +
136 "<tr><td style='white-space: nowrap; padding:5px;'> " +
137 "Ctrl + D </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Toggle Directory Navigation</td></tr>" +
139 "<tr style='background-color: rgb(106, 102, 119);'><td style='white-space: nowrap; padding:5px;'> " +
140 "Ctrl + F </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Find & Replace</td></tr>" +
142 "<tr><td style='white-space: nowrap; padding:5px;'> " +
143 "Ctrl + U </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Undo Text Editing</td></tr>" +
145 "<tr style='background-color: rgb(106, 102, 119);'><td style='white-space: nowrap; padding:5px;'> " +
146 "Shift + Ctrl + U </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Redo Text Editing</td></tr>" +
148 "<tr><td style='white-space: nowrap; padding:5px;'> " +
149 "Ctrl + L or G </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Goto Line Number</td></tr>" +
151 "<tr style='background-color: rgb(106, 102, 119);'><td style='white-space: nowrap; padding:5px;'> " +
152 "Ctrl + 1 or ; </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Switch to Related File (associated .h or .cc)</td></tr>" +
154 "<tr><td style='white-space: nowrap; padding:5px;'> " +
155 "Ctrl + 0 or ' </td><td style='padding:5px'> ==> </td><td style='padding:5px'> Reload Current File from Server</td></tr>" +
157 "</table></INDENT>\n" +
160 "<b>Selected-Text Hot Keys:</b>\n<INDENT>" +
162 "<table border=0 cellspacing=0 cellpadding=0 style='border: 1px solid grey;'>" +
163 "<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>" +
164 "<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>" +
165 "<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>" +
166 "<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>" +
167 "<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>" +
168 "<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>" +
169 "<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>" +
170 "</table></INDENT>\n" +
181 CodeEditor.create =
function() {
185 CodeEditor.showTooltip();
249 var _WINDOW_MIN_SZ = 525;
251 var _ALLOWED_FILE_EXTENSIONS = [];
253 var _needEventListeners =
true;
256 var _navMode = [0,0];
257 var _filePath = [
"",
""];
258 var _fileExtension = [
"",
""];
259 var _fileLastSave = [0,0];
260 var _fileWasModified = [
false,
false];
261 var _numberOfLines = [0,0];
263 var _eel = [undefined,undefined];
265 var _updateTimerHandle = 0;
266 var _updateHandlerTargetPane = [
false,
false];
267 var _commandKeyDown =
false;
268 var _lastPageUpDownLine = -1;
269 var _startPageUpDownLine = -1;
270 var _startPageUpDownNodeIndex = -1;
271 var _startPageUpDownPos = -1;
273 var _fileNameMouseMoveTimerHandle = 0;
274 var _fileNameEditing = [
false,
false];
275 var _fileUploadString;
277 var _activePaneIsPrimary = 1;
279 var _undoStackLatestIndex = [-1,-1];
280 var _undoStack_MAX_SIZE = 10;
281 var _undoStack = [[],[]];
283 var _fileHistoryStack = {};
285 var _findAndReplaceCursorInContent = [undefined,undefined];
287 var _fileStringHoverEl = 0;
288 var _fileStringHoverTimeout = 0;
290 var _UPDATE_DECOR_TIMEOUT = 2000;
297 CodeEditor.editor =
this;
298 Debug.log(
"CodeEditor.editor constructed");
301 this.lastFileNameHistorySelectIndex = -1;
302 this.findAndReplaceFind = [
"",
""];
303 this.findAndReplaceReplace = [
"",
""];
304 this.findAndReplaceScope = [0,0];
305 this.findAndReplaceDirection = [0,0];
306 this.findAndReplaceCaseSensitive = [0,0];
307 this.findAndReplaceWholeWord = [1,1];
308 this.findAndReplaceLastButton = [-1,-1];
312 Debug.log(
"CodeEditor.editor initialized");
319 Debug.log(
"Code Editor init ");
322 var parameterStartFile = [
328 DesktopContent.getParameter(0,
"startFilePrimary"),
329 DesktopContent.getParameter(0,
"startFileSecondary")
331 var parameterGotoLine = [
332 DesktopContent.getParameter(0,
"gotoLinePrimary"),
333 DesktopContent.getParameter(0,
"gotoLineSecondary")
335 var parameterOpenDirectory = [
336 DesktopContent.getParameter(0,
"openDirectoryPrimary"),
337 DesktopContent.getParameter(0,
"openDirectorySecondary")
339 if(parameterOpenDirectory[0] === undefined)
340 parameterOpenDirectory[0] =
"/";
341 if(parameterOpenDirectory[1] === undefined)
342 parameterOpenDirectory[1] =
"/";
344 var parameterViewMode = DesktopContent.getParameter(0,
"startViewMode");
345 if(parameterViewMode !== undefined)
347 _viewMode = parameterViewMode|0;
349 console.log(
"parameterStartFile",parameterStartFile);
350 console.log(
"parameterGotoLine",parameterGotoLine);
351 console.log(
"parameterViewMode",parameterViewMode);
352 console.log(
"parameterOpenDirectory",parameterOpenDirectory);
361 if(_needEventListeners)
363 window.addEventListener(
"resize",redrawWindow);
364 _needEventListeners =
false;
369 DesktopContent.XMLHttpRequest(
"Request?RequestType=codeEditor" +
370 "&option=getAllowedExtensions"
374 console.log(
"getAllowedExtensions",req);
376 _ALLOWED_FILE_EXTENSIONS = DesktopContent.getXMLValue(req,
"AllowedExtensions");
377 console.log(
"_ALLOWED_FILE_EXTENSIONS",_ALLOWED_FILE_EXTENSIONS);
378 _ALLOWED_FILE_EXTENSIONS = _ALLOWED_FILE_EXTENSIONS.split(
',');
379 console.log(
"_ALLOWED_FILE_EXTENSIONS",_ALLOWED_FILE_EXTENSIONS);
381 DesktopContent.XMLHttpRequest(
"Request?RequestType=codeEditor" +
382 "&option=getDirectoryContent" +
392 CodeEditor.editor.handleDirectoryContent(1 , req);
393 CodeEditor.editor.handleDirectoryContent(0 , req);
397 if(parameterStartFile[0] && parameterStartFile[0] !=
"")
398 fileSplit = parameterStartFile[0].split(
'.');
402 if(fileSplit.length == 2)
403 CodeEditor.editor.openFile(
408 parameterGotoLine[0 ] );
411 CodeEditor.editor.openDirectory(
413 parameterOpenDirectory[0] ,
421 if(parameterStartFile[1] && parameterStartFile[1] !=
"")
422 fileSplit = parameterStartFile[1].split(
'.');
424 if(fileSplit.length == 2)
425 CodeEditor.editor.openFile(
430 parameterGotoLine[1 ] );
434 CodeEditor.editor.openDirectory(
436 parameterOpenDirectory[1] ,
443 _activePaneIsPrimary = 1;
453 function createElements()
455 Debug.log(
"createElements");
465 var cel,el,al,sl,str;
467 cel = document.getElementById(
"content");
470 cel = document.createElement(
"div");
471 cel.setAttribute(
"id",
"content");
482 for(forPrimary=1;forPrimary >= 0;--forPrimary)
484 el = document.createElement(
"div");
485 el.setAttribute(
"class",
"editorPane");
486 el.setAttribute(
"id",
"editorPane" + forPrimary);
489 str += createTextEditor(forPrimary);
490 str += createDirectoryNav(forPrimary);
491 str += localCreatePaneControls(forPrimary);
498 function localCreatePaneControls(forPrimary)
506 str += htmlOpen(
"div",
508 "class":
"controlsPane",
512 str += htmlOpen(
"div",
514 "id":
"directoryNavToggle",
515 "class":
"controlsButton",
516 "style":
"float:left",
517 "onclick":
"CodeEditor.editor.toggleDirectoryNav(" + forPrimary +
");",
518 "title":
"Open a file... (Ctrl + D)",
521 str += htmlOpen(
"div",
523 "id":
"directoryNavToggleTop",
526 str += htmlOpen(
"div",
528 "id":
"directoryNavToggleBottom",
535 str += htmlOpen(
"div",
538 "class":
"controlsButton",
539 "style":
"float:left;",
540 "onclick":
"CodeEditor.editor.saveFile(" + forPrimary +
");",
541 "title":
"Click to Save the File (Ctrl + S)\nUndo changes (Ctrl + U)\nRedo changes (Shift + Ctrl + U)",
544 str += htmlOpen(
"div",
549 str += htmlOpen(
"div",
551 "id":
"saveFileMainTop",
554 str += htmlOpen(
"div",
556 "id":
"saveFileMainBottom",
571 el = document.createElement(
"div");
572 el.setAttribute(
"class",
"controlsPane");
579 str += htmlOpen(
"div",
582 "class":
"controlsButton",
583 "style":
"float:right",
584 "onclick":
"CodeEditor.editor.toggleView();",
585 "title":
"Toggle Verical/Horizontal Split-view (Ctrl + W)",
589 str += htmlOpen(
"div",
591 "id":
"viewToggleRight",
594 str += htmlOpen(
"div",
596 "id":
"viewToggleLeftTop",
599 str += htmlOpen(
"div",
601 "id":
"viewToggleLeftBottom",
608 str += htmlOpen(
"div",
610 "id":
"incrementalBuild",
611 "class":
"controlsButton",
612 "style":
"float:right",
613 "onclick":
"CodeEditor.editor.build(0 /*cleanBuild*/);",
614 "title":
"Incremental Build... (Ctrl + B)",
618 str += htmlOpen(
"div",
620 "style":
"margin:11px 0 0 13px;",
626 str += htmlOpen(
"div",
629 "class":
"controlsButton",
630 "style":
"float:right",
631 "onclick":
"CodeEditor.editor.build(1 /*cleanBuild*/);",
632 "title":
"Clean Build... (Ctrl + N)",
636 str += htmlOpen(
"div",
638 "style":
"margin:10px 0 0 13px;",
644 str += htmlOpen(
"div",
647 "class":
"controlsButton",
648 "style":
"float:right",
649 "onclick":
"CodeEditor.showTooltip(1 /*alwaysShow*/);",
650 "title":
"Click for help, short-cuts, etc.",
654 str += htmlOpen(
"div",
656 "style":
"margin:12px 0 0 13px;",
667 document.body.appendChild(cel);
668 _eel = [document.getElementById(
"editableBox" + 0),
669 document.getElementById(
"editableBox" + 1)];
677 _eel[i].addEventListener(
"input",
682 var forPrimary = this.
id[this.
id.length-1]|0;
683 forPrimary = forPrimary?1:0;
685 Debug.log(
"input forPrimary=" + forPrimary);
687 _fileWasModified[forPrimary] =
true;
688 CodeEditor.editor.updateLastSave(forPrimary);
690 CodeEditor.editor.startUpdateHandling(forPrimary);
694 _eel[i].addEventListener(
"keydown",
697 if(e.keyCode == 91 || e.keyCode == 93 ||
699 _commandKeyDown =
true;
701 var forPrimary =
this.id[
this.id.length-1]|0;
702 forPrimary = forPrimary?1:0;
705 CodeEditor.editor.keyDownHandler(e,forPrimary);
709 _eel[i].addEventListener(
"keyup",
712 if(e.keyCode == 91 || e.keyCode == 93 ||
714 _commandKeyDown =
false;
717 _eel[i].addEventListener(
"click",
723 Debug.log(
"Special mouse click handling");
733 _eel[i].addEventListener(
"dblclick",
737 var forPrimary = this.
id[this.
id.length-1]|0;
738 forPrimary = forPrimary?1:0;
740 Debug.log(
"dblclick handler for editor" + forPrimary);
743 CodeEditor.editor.doubleClickHandler(forPrimary);
746 _eel[i].addEventListener(
"contextmenu",
752 Debug.log(
"Special context menu handling");
761 _eel[i].addEventListener(
"mousedown",
766 Debug.log(
"Special mouse down handling");
773 CodeEditor.editor.stopUpdateHandling(e);
775 var forPrimary = this.
id[this.
id.length-1]|0;
776 forPrimary = forPrimary?1:0;
778 Debug.log(
"mousedown handler for editor" + forPrimary +
" " + e.which);
781 if(_activePaneIsPrimary != forPrimary)
782 CodeEditor.editor.updateDualView(!forPrimary);
784 _activePaneIsPrimary = forPrimary;
789 _eel[i].addEventListener(
"mouseup",
792 var forPrimary = this.
id[this.
id.length-1]|0;
793 forPrimary = forPrimary?1:0;
795 Debug.log(
"mouseup handler for editor" + forPrimary);
799 Debug.log(
"Special mouse up handling");
806 CodeEditor.editor.startUpdateHandling(forPrimary);
811 box = document.getElementById(
"editorPane" + i);
812 box.addEventListener(
"click",
815 var forPrimary = this.
id[this.
id.length-1]|0;
816 forPrimary = forPrimary?1:0;
818 Debug.log(
"click handler for pane" + forPrimary);
822 if(_activePaneIsPrimary != forPrimary)
823 CodeEditor.editor.updateDualView(!forPrimary);
825 _activePaneIsPrimary = forPrimary;
828 CodeEditor.editor.showFindAndReplaceSelection(forPrimary);
831 var el = document.getElementById(
"textEditorBody" + forPrimary);
832 var scrollLeft = el.scrollLeft;
833 var scrollTop = el.scrollTop;
835 _eel[forPrimary].focus();
837 el.scrollLeft = scrollLeft;
838 el.scrollTop = scrollTop;
847 box.addEventListener(
"keydown",
850 if(e.keyCode == 91 || e.keyCode == 93 ||
852 _commandKeyDown =
true;
854 var forPrimary = _activePaneIsPrimary;
855 Debug.log(
"keydown handler for body" + forPrimary);
856 CodeEditor.editor.keyDownHandler(e,forPrimary,
true );
859 box.addEventListener(
"keyup",
862 if(e.keyCode == 91 || e.keyCode == 93 ||
864 _commandKeyDown =
false;
866 box.addEventListener(
"mouseover",
870 if(_fileStringHoverEl.parentNode)
872 Debug.log(
"body removing string hover");
873 window.clearTimeout(_fileStringHoverTimeout);
874 _fileStringHoverTimeout = window.setTimeout(
877 Debug.log(
"body removed string hover");
880 _fileStringHoverEl.parentNode.removeChild(_fileStringHoverEl);
893 function createTextEditor(forPrimary)
895 forPrimary = forPrimary?1:0;
897 Debug.log(
"createTextEditor forPrimary=" + forPrimary);
901 str += htmlOpen(
"div",
903 "class":
"textEditor",
904 "id":
"textEditor" + forPrimary,
905 "style":
"overflow:hidden;",
914 str += htmlOpen(
"div",
916 "class":
"textEditorHeader",
917 "id":
"textEditorHeader" + forPrimary,
921 str += htmlOpen(
"div",
923 "class":
"textEditorBody",
924 "id":
"textEditorBody" + forPrimary,
927 str +=
"<table class='editableBoxTable' style='margin-bottom:200px'>" +
928 "<tr><td valign='top'>";
929 str += htmlOpen(
"div",
931 "class":
"editableBoxLeftMargin",
932 "id":
"editableBoxLeftMargin" + forPrimary,
934 str +=
"</td><td valign='top'>";
935 str += htmlOpen(
"div",
937 "class":
"editableBox",
938 "id":
"editableBox" + forPrimary,
939 "contenteditable":
"true",
940 "autocomplete":
"off",
942 "autocapitalize":
"off",
943 "spellcheck":
"false",
945 str +=
"</td></tr></table>";
956 function createDirectoryNav(forPrimary)
958 forPrimary = forPrimary?1:0;
960 Debug.log(
"createDirectoryNav forPrimary=" + forPrimary);
964 str += htmlOpen(
"div",
966 "class":
"directoryNav",
967 "id":
"directoryNav" + forPrimary,
977 function redrawWindow()
982 var w = window.innerWidth | 0;
983 var h = window.innerHeight | 0;
985 if(w < _WINDOW_MIN_SZ)
987 if(h < _WINDOW_MIN_SZ)
990 Debug.log(
"redrawWindow to " + w +
" - " + h);
992 var eps = document.getElementsByClassName(
"editorPane");
993 var epHdrs = document.getElementsByClassName(
"textEditorHeader");
994 var epBdys = document.getElementsByClassName(
"textEditorBody");
995 var dns = document.getElementsByClassName(
"directoryNav");
999 eps[0].style.position =
"absolute";
1000 eps[1].style.position =
"absolute";
1002 var DIR_NAV_MARGIN = 50;
1003 var EDITOR_MARGIN = 20;
1004 var EDITOR_HDR_H = 56;
1009 rect = [{
"left":0,
"top":0,
"w":w,
"h":h},
1014 rect = [{
"left":0,
"top":0,
"w":((w/2)|0),
"h":h},
1015 {
"left":((w/2)|0),
"top":0,
"w":(w-((w/2)|0)),
"h":h}];
1020 rect = [{
"left":0,
"top":0,
"h":((h/2)|0),
"w":w},
1021 {
"top":((h/2)|0),
"left":0,
"h":(h-((h/2)|0)),
"w":w}];
1025 Debug.log(
"Invalid view mode encountered: " + _viewMode);
1029 for(var i=0;i<2;++i)
1033 eps[i].style.display =
"none";
1037 dns[i].style.left = (DIR_NAV_MARGIN) +
"px";
1038 dns[i].style.top = (DIR_NAV_MARGIN) +
"px";
1039 dns[i].style.width = (rect[i].w - 2*DIR_NAV_MARGIN) +
"px";
1040 dns[i].style.height = (rect[i].h - 2*DIR_NAV_MARGIN) +
"px";
1042 eps[i].style.left = rect[i].left +
"px";
1043 eps[i].style.top = rect[i].top +
"px";
1044 eps[i].style.height = rect[i].h +
"px";
1045 eps[i].style.width = rect[i].w +
"px";
1047 epHdrs[i].style.left = EDITOR_MARGIN +
"px";
1048 epHdrs[i].style.top = (DIR_NAV_MARGIN - 2*EDITOR_MARGIN) +
"px";
1049 epHdrs[i].style.height = (EDITOR_HDR_H + 2*EDITOR_MARGIN) +
"px";
1050 epHdrs[i].style.width = (rect[i].w - 2*EDITOR_MARGIN) +
"px";
1053 epBdys[i].style.left = 0 +
"px";
1054 epBdys[i].style.top = (DIR_NAV_MARGIN + EDITOR_HDR_H) +
"px";
1055 epBdys[i].style.height = (rect[i].h - DIR_NAV_MARGIN - EDITOR_HDR_H) +
"px";
1056 epBdys[i].style.width = (rect[i].w - 0) +
"px";
1058 eps[i].style.display =
"block";
1067 this.toggleView =
function(v)
1072 _viewMode = (_viewMode+1)%3;
1073 Debug.log(
"toggleView _viewMode=" + _viewMode);
1080 this.toggleDirectoryNav =
function(forPrimary, v)
1082 forPrimary = forPrimary?1:0;
1083 _activePaneIsPrimary = forPrimary;
1085 Debug.log(
"toggleDirectoryNav forPrimary=" + forPrimary);
1088 _navMode[forPrimary] = v?1:0;
1090 _navMode[forPrimary] = _navMode[forPrimary]?0:1;
1091 Debug.log(
"toggleDirectoryNav _navMode=" + _navMode[forPrimary]);
1093 var el = document.getElementById(
"directoryNav" + forPrimary);
1094 var wasHidden = el.style.display ==
"none";
1096 _navMode[forPrimary]?
"block":
"none";
1098 if(_navMode[forPrimary] && wasHidden)
1100 var paths = document.getElementById(
"directoryNav" +
1101 forPrimary).getElementsByClassName(
"dirNavPath");
1102 var buildPath =
"/";
1103 for(var i=1;i<paths.length;++i)
1104 buildPath += (i>1?
"/":
"") + paths[i].textContent;
1105 Debug.log(
"refresh " + buildPath);
1107 CodeEditor.editor.openDirectory(forPrimary,buildPath);
1114 this.saveFile =
function(forPrimary, quiet)
1116 forPrimary = forPrimary?1:0;
1118 Debug.log(
"saveFile forPrimary=" + forPrimary);
1120 Debug.log(
"saveFile _filePath=" + _filePath[forPrimary]);
1121 Debug.log(
"saveFile _fileExtension=" + _fileExtension[forPrimary]);
1123 if(_filePath[forPrimary] ==
"")
1125 Debug.log(
"Error, can not save to empty file name!",
1126 Debug.HIGH_PRIORITY);
1132 DesktopContent.popUpVerification(
1133 "Are you sure you want to save...<br>" +
1134 _filePath[forPrimary] +
"." + _fileExtension[forPrimary] +
"?",
1136 undefined,undefined,undefined,
1137 undefined,undefined,
1145 function localDoIt()
1149 var textObj = {
"text":
1150 _eel[forPrimary].innerText,
1157 textObj.text = textObj.text.replace(/%C2%A0%C2%A0/g,
"%20%20").replace(/%C2%A0/g,
1158 "%20").replace(/%C2/g,
"%20").replace(/%A0/g,
"%20");
1162 DesktopContent.XMLHttpRequest(
"Request?RequestType=codeEditor" +
1163 "&option=saveFileContent" +
1164 "&path=" + _filePath[forPrimary] +
1165 "&ext=" + _fileExtension[forPrimary]
1166 ,
"content=" + encodeURIComponent(textObj.text) ,
1169 Debug.log(
"Successfully saved " +
1170 _filePath[forPrimary] +
"." +
1171 _fileExtension[forPrimary],quiet?Debug.LOW_PRIORITY:Debug.INFO_PRIORITY);
1173 _fileWasModified[forPrimary] =
false;
1174 textObj.time = Date.now();
1175 _fileLastSave[forPrimary] = textObj.time;
1178 CodeEditor.editor.updateLastSave(forPrimary);
1180 if(_filePath[0] == _filePath[1] &&
1181 _fileExtension[0] == _fileExtension[1])
1183 CodeEditor.editor.updateDualView(forPrimary);
1185 CodeEditor.editor.updateFileSnapshot(!forPrimary,
1191 CodeEditor.editor.updateFileSnapshot(forPrimary,
1203 this.build =
function(cleanBuild)
1205 cleanBuild = cleanBuild?1:0;
1207 Debug.log(
"build cleanBuild=" + cleanBuild);
1211 DesktopContent.popUpVerification(
1212 "Are you sure you want to do a clean build?!",
1220 function localDoIt()
1222 DesktopContent.XMLHttpRequest(
"Request?RequestType=codeEditor" +
1224 "&clean=" + (cleanBuild?1:0)
1228 Debug.log(
"Build was launched! Check " +
1229 "<a onclick='DesktopContent.openNewBrowserTab(" +
1231 "title='Click to open the Console web app in a new browser tab.'>" +
1232 "console</a> for result!", Debug.INFO_PRIORITY);
1242 this.undo =
function(forPrimary,redo)
1244 DesktopContent.showLoading(localDoIt);
1247 function localDoIt()
1249 forPrimary = forPrimary?1:0;
1251 Debug.log(
"undo() forPrimary=" + forPrimary +
" redo=" + redo);
1252 console.log(
"undo stack index",_undoStackLatestIndex[forPrimary]);
1253 console.log(
"undo stack length",_undoStack[forPrimary].length);
1255 console.log(
"undo stack",_undoStack[forPrimary]);
1257 var el = _eel[forPrimary];
1260 CodeEditor.editor.updateFileSnapshot(forPrimary,
1261 {
"text":el.textContent,
1265 var newIndex = _undoStackLatestIndex[forPrimary];
1266 newIndex += redo?1:-1;
1267 if(newIndex >= _undoStack_MAX_SIZE)
1269 else if(newIndex < 0)
1270 newIndex = _undoStack[forPrimary].length-1;
1272 console.log(
"new stack index",newIndex);
1276 _undoStack[forPrimary][newIndex][1] >=
1277 _undoStack[forPrimary][_undoStackLatestIndex[forPrimary]][1])
1279 Debug.log(
"Reached end of undo history...",Debug.WARN_PRIORITY);
1283 (newIndex >= _undoStack[forPrimary].length ||
1284 _undoStack[forPrimary][newIndex][1] <=
1285 _undoStack[forPrimary][_undoStackLatestIndex[forPrimary]][1]))
1287 Debug.log(
"Reached end of redo history...",Debug.WARN_PRIORITY);
1292 _undoStackLatestIndex[forPrimary] = newIndex;
1293 console.log(
"result stack index",newIndex);
1295 var cursor = CodeEditor.editor.getCursor(el);
1298 _undoStack[forPrimary][_undoStackLatestIndex[forPrimary]][0];
1299 _fileWasModified[forPrimary] =
true;
1301 CodeEditor.editor.updateDecorations(forPrimary,
1305 CodeEditor.editor.setCursor(el,cursor,
true );
1312 this.handleDirectoryContent =
function(forPrimary,req)
1314 forPrimary = forPrimary?1:0;
1316 Debug.log(
"handleDirectoryContent forPrimary=" + forPrimary);
1319 var path = DesktopContent.getXMLValue(req,
"path");
1320 if(path ==
"/") path =
"";
1322 var specials = req.responseXML.getElementsByTagName(
"special");
1323 var dirs = req.responseXML.getElementsByTagName(
"directory");
1324 var files = req.responseXML.getElementsByTagName(
"file");
1325 var specialFiles = req.responseXML.getElementsByTagName(
"specialFile");
1327 Debug.log(
"handleDirectoryContent path=" + path);
1328 console.log(dirs);console.log(files);
1333 str += htmlOpen(
"div",
1335 "style":
"margin:20px;" +
1336 "white-space: nowrap;",
1342 var pathSplit = path.split(
'/');
1346 str +=
"Path: <a class='dirNavPath' onclick='CodeEditor.editor.openDirectory(" +
1347 forPrimary +
",\"" +
1354 for(i=0;i<pathSplit.length;++i)
1356 pathSplitName = pathSplit[i].trim();
1357 if(pathSplitName ==
"")
continue;
1358 Debug.log(
"pathSplitName " + pathSplitName);
1360 buildPath +=
"/" + pathSplitName;
1363 str +=
"<a class='dirNavPath' onclick='CodeEditor.editor.openDirectory(" +
1364 forPrimary +
",\"" +
1366 ")' title='Open folder: \nsrcs" + buildPath +
1368 pathSplitName +
"</a>";
1374 str += htmlOpen(
"a",
1376 "title":
"Open folder in the other editor pane of the split-view: \n" +
1378 "onclick":
"CodeEditor.editor.openDirectory(" +
1379 (!forPrimary) +
",\"" +
1382 "<img class='dirNavFileNewWindowImgNewPane' " +
1383 "src='/WebPath/images/windowContentImages/CodeEditor-openInOtherPane.png'>"
1387 str += htmlOpen(
"a",
1389 "title":
"Open folder in a new browser tab: \n" +
1391 "onclick":
"DesktopContent.openNewBrowserTab(" +
1392 "\"Code Editor\",\"\"," +
1393 "\"/WebPath/html/CodeEditor.html?urn=" +
1394 DesktopContent._localUrnLid +
"&" +
1395 "openDirectoryPrimary=" +
1396 buildPath +
"\",0 /*unique*/);' ",
1398 "<img class='dirNavFileNewWindowImgNewWindow' " +
1399 "src='/WebPath/images/windowContentImages/CodeEditor-openInNewWindow.png'>"
1408 for(i=0;i<specials.length;++i)
1410 name = specials[i].getAttribute(
'value');
1413 str += htmlOpen(
"a",
1415 "title":
"Open folder in a new browser tab: \n" +
1416 "srcs" + path +
"/" + name,
1417 "onclick":
"DesktopContent.openNewBrowserTab(" +
1418 "\"Code Editor\",\"\"," +
1419 "\"/WebPath/html/CodeEditor.html?urn=" +
1420 DesktopContent._localUrnLid +
"&" +
1421 "openDirectoryPrimary=" +
1422 path +
"/" + name +
"\",0 /*unique*/);' ",
1424 "<img class='dirNavFileNewWindowImgNewWindow' " +
1425 "src='/WebPath/images/windowContentImages/CodeEditor-openInNewWindow.png'>"
1429 str += htmlOpen(
"a",
1431 "title":
"Open folder in the other editor pane of the split-view: \n" +
1432 "srcs" + path +
"/" + name,
1433 "onclick":
"CodeEditor.editor.openDirectory(" +
1434 (!forPrimary) +
",\"" +
1435 path +
"/" + name +
"\");",
1437 "<img class='dirNavFileNewWindowImgNewPane' " +
1438 "src='/WebPath/images/windowContentImages/CodeEditor-openInOtherPane.png'>"
1442 str +=
"<a class='dirNavSpecial' onclick='CodeEditor.editor.openDirectory(" +
1443 forPrimary +
",\"" +
1444 path +
"/" + name +
"\"" +
1445 ")' title='Open folder: \nsrcs" + path +
"/" + name +
"' >" +
1455 if(specialFiles.length)
1458 str +=
"<tr><th>" + path.substr(1,path.length-2) +
" Files</th><th style='padding-left:20px'>Repository</th></tr>";
1460 for(i=0;i<specialFiles.length;++i)
1462 name = specialFiles[i].getAttribute(
'value');
1467 str += htmlOpen(
"a",
1469 "title":
"Open file in a new browser tab: \n" +
1471 "onclick":
"DesktopContent.openNewBrowserTab(" +
1472 "\"Code Editor\",\"\"," +
1473 "\"/WebPath/html/CodeEditor.html?urn=" +
1474 DesktopContent._localUrnLid +
"&" +
1475 "startFilePrimary=" +
1476 name +
"\",0 /*unique*/);' ",
1478 "<img class='dirNavFileNewWindowImgNewWindow' " +
1479 "src='/WebPath/images/windowContentImages/CodeEditor-openInNewWindow.png'>"
1483 str += htmlOpen(
"a",
1485 "title":
"Open file in the other editor pane of the split-view: \n" +
1487 "onclick":
"CodeEditor.editor.openFile(" +
1488 (!forPrimary) +
",\"" +
1490 name.substr(name.lastIndexOf(
'.')+1) +
"\"" +
1493 "<img class='dirNavFileNewWindowImgNewPane' " +
1494 "src='/WebPath/images/windowContentImages/CodeEditor-openInOtherPane.png'>"
1498 str +=
"<a class='dirNavFile' onclick='CodeEditor.editor.openFile(" +
1499 forPrimary +
",\"" +
1501 name.substr(name.lastIndexOf(
'.')+1) +
"\"" +
1502 ")' title='Open file: \nsrcs" + name +
"' >";
1503 nameSplit = name.split(
'/');
1504 str += nameSplit[nameSplit.length-1] +
"</a>";
1508 str +=
"</td><td style='padding-left:20px'>" + nameSplit[1] +
"</td></tr>";
1511 if(specialFiles.length)
1517 for(i=0;i<dirs.length;++i)
1519 name = dirs[i].getAttribute(
'value');
1522 str += htmlOpen(
"a",
1524 "title":
"Open file in a new browser tab: \n" +
1525 "srcs" + path +
"/" + name,
1526 "onclick":
"DesktopContent.openNewBrowserTab(" +
1527 "\"Code Editor\",\"\"," +
1528 "\"/WebPath/html/CodeEditor.html?urn=" +
1529 DesktopContent._localUrnLid +
"&" +
1530 "openDirectoryPrimary=" +
1531 path +
"/" + name +
"\",0 /*unique*/);' ",
1533 "<img class='dirNavFileNewWindowImgNewWindow' " +
1534 "src='/WebPath/images/windowContentImages/CodeEditor-openInNewWindow.png'>"
1538 str += htmlOpen(
"a",
1540 "title":
"Open folder in the other editor pane of the split-view: \n" +
1541 "srcs" + path +
"/" + name,
1542 "onclick":
"CodeEditor.editor.openDirectory(" +
1543 (!forPrimary) +
",\"" +
1544 path +
"/" + name +
"\");",
1546 "<img class='dirNavFileNewWindowImgNewPane' " +
1547 "src='/WebPath/images/windowContentImages/CodeEditor-openInOtherPane.png'>"
1551 str +=
"<a class='dirNavFolder' onclick='CodeEditor.editor.openDirectory(" +
1552 forPrimary +
",\"" +
1553 path +
"/" + name +
"\"" +
1554 ")' title='Open folder: \nsrcs" + path +
"/" + name +
"' >" +
1563 for(i=0;i<files.length;++i)
1565 name = files[i].getAttribute(
'value');
1568 str += htmlOpen(
"a",
1570 "title":
"Open file in a new browser tab: \n" +
1571 "srcs" + path +
"/" + name,
1572 "onclick":
"DesktopContent.openNewBrowserTab(" +
1573 "\"Code Editor\",\"\"," +
1574 "\"/WebPath/html/CodeEditor.html?urn=" +
1575 DesktopContent._localUrnLid +
"&" +
1576 "startFilePrimary=" +
1577 path +
"/" + name +
"\",0 /*unique*/);' ",
1579 "<img class='dirNavFileNewWindowImgNewWindow' " +
1580 "src='/WebPath/images/windowContentImages/CodeEditor-openInNewWindow.png'>"
1584 str += htmlOpen(
"a",
1586 "title":
"Open file in the other editor pane of the split-view: \n" +
1587 "srcs" + path +
"/" + name,
1588 "onclick":
"CodeEditor.editor.openFile(" +
1589 (!forPrimary) +
",\"" +
1590 path +
"/" + name +
"\", \"" +
1591 name.substr(name.lastIndexOf(
'.')+1) +
"\"" +
1594 "<img class='dirNavFileNewWindowImgNewPane' " +
1595 "src='/WebPath/images/windowContentImages/CodeEditor-openInOtherPane.png'>"
1600 str +=
"<a class='dirNavFile' onclick='CodeEditor.editor.openFile(" +
1601 forPrimary +
",\"" +
1602 path +
"/" + name +
"\", \"" +
1603 name.substr(name.lastIndexOf(
'.')+1) +
"\"" +
1604 ")' title='Open file: \nsrcs" + path +
"/" + name +
"' >" +
1613 document.getElementById(
"directoryNav" + forPrimary).innerHTML = str;
1619 this.openDirectory =
function(forPrimary,path,doNotOpenPane)
1621 forPrimary = forPrimary?1:0;
1623 if(!path || path ==
"") path =
"/";
1624 Debug.log(
"openDirectory forPrimary=" + forPrimary +
1628 DesktopContent.XMLHttpRequest(
"Request?RequestType=codeEditor" +
1629 "&option=getDirectoryContent" +
1634 CodeEditor.editor.handleDirectoryContent(forPrimary, req);
1635 CodeEditor.editor.toggleDirectoryNav(forPrimary,1 );
1639 if(!doNotOpenPane && !forPrimary && _viewMode == 0)
1640 CodeEditor.editor.toggleView();
1648 this.openRelatedFile =
function(forPrimary,inOtherPane)
1650 Debug.log(
"openRelatedFile forPrimary=" + forPrimary +
1651 " path=" + _filePath[forPrimary]);
1653 var relatedPath = _filePath[forPrimary];
1654 var relatedExtension = _fileExtension[forPrimary];
1655 var targetPane = inOtherPane?!forPrimary:forPrimary;
1658 var altExtensions = [];
1660 if(relatedExtension ==
"html")
1662 relatedExtension =
"js";
1663 var i = relatedPath.indexOf(
"/html/");
1666 altPaths.push(relatedPath.substr(0,i) +
"/css/" +
1667 relatedPath.substr(i + (
"/html/").length));
1668 altExtensions.push(
"css");
1670 relatedPath = relatedPath.substr(0,i) +
"/js/" +
1671 relatedPath.substr(i + (
"/html/").length);
1675 altPaths.push(relatedPath);
1676 altExtensions.push(
"css");
1679 CodeEditor.editor.openFile(targetPane,relatedPath,relatedExtension,
1680 undefined , undefined,
1681 altPaths , altExtensions);
1684 else if(relatedExtension[0] ==
"h")
1686 relatedExtension =
"cc";
1688 altPaths.push(relatedPath);
1689 altExtensions.push(
"cc");
1691 altPaths.push(relatedPath+
"_interface");
1692 altExtensions.push(
"cc");
1693 altPaths.push(relatedPath+
"_processor");
1694 altExtensions.push(
"cc");
1695 altPaths.push(relatedPath+
"_controls");
1696 altExtensions.push(
"cc");
1697 altPaths.push(relatedPath+
"_table");
1699 altPaths.push(relatedPath);
1700 altExtensions.push(
"cpp");
1701 altPaths.push(relatedPath);
1702 altExtensions.push(
"CC");
1703 altPaths.push(relatedPath);
1704 altExtensions.push(
"cxx");
1705 altPaths.push(relatedPath);
1706 altExtensions.push(
"c");
1707 altPaths.push(relatedPath);
1708 altExtensions.push(
"C");
1711 if(relatedPath.indexOf(
"Interface") >= 0)
1712 relatedPath +=
"_interface";
1713 else if(relatedPath.indexOf(
"Processor") >= 0)
1714 relatedPath +=
"_processor";
1715 else if(relatedPath.indexOf(
"Consumer") >= 0)
1716 relatedPath +=
"_processor";
1717 else if(relatedPath.indexOf(
"Producer") >= 0)
1718 relatedPath +=
"_processor";
1719 else if(relatedPath.indexOf(
"Controls") >= 0)
1720 relatedPath +=
"_controls";
1721 else if(relatedPath.indexOf(
"Table") >= 0)
1722 relatedPath +=
"_table";
1724 CodeEditor.editor.openFile(targetPane,relatedPath,relatedExtension,
1725 undefined , undefined,
1726 altPaths , altExtensions);
1729 else if(relatedExtension ==
"css")
1731 relatedExtension =
"js";
1732 var i = relatedPath.indexOf(
"/css/");
1736 altPaths.push(relatedPath.substr(0,i) +
"/html/" +
1737 relatedPath.substr(i + (
"/css/").length));
1738 altExtensions.push(
"html");
1740 relatedPath = relatedPath.substr(0,i) +
"/js/" +
1741 relatedPath.substr(i + (
"/css/").length);
1745 altPaths.push(relatedPath);
1746 altExtensions.push(
"html");
1749 CodeEditor.editor.openFile(targetPane,relatedPath,relatedExtension,
1750 undefined , undefined,
1751 altPaths , altExtensions);
1754 else if(relatedExtension[0] ==
'c' ||
1755 relatedExtension[0] ==
'C')
1757 relatedExtension =
"h";
1759 altPaths.push(relatedPath);
1760 altExtensions.push(
"h");
1763 if((i = relatedPath.indexOf(
"_interface")) > 0 &&
1764 i == relatedPath.length-(
"_interface").length)
1765 relatedPath = relatedPath.substr(0,i);
1766 if((i = relatedPath.indexOf(
"_processor")) > 0 &&
1767 i == relatedPath.length-(
"_processor").length)
1768 relatedPath = relatedPath.substr(0,i);
1769 if((i = relatedPath.indexOf(
"_controls")) > 0 &&
1770 i == relatedPath.length-(
"_controls").length)
1771 relatedPath = relatedPath.substr(0,i);
1772 if((i = relatedPath.indexOf(
"_table")) > 0 &&
1773 i == relatedPath.length-(
"_table").length)
1774 relatedPath = relatedPath.substr(0,i);
1776 altPaths.push(relatedPath);
1777 altExtensions.push(
"hh");
1778 altPaths.push(relatedPath);
1779 altExtensions.push(
"hpp");
1780 altPaths.push(relatedPath);
1781 altExtensions.push(
"hxx");
1782 altPaths.push(relatedPath);
1783 altExtensions.push(
"H");
1785 CodeEditor.editor.openFile(targetPane,relatedPath,relatedExtension,
1786 undefined , undefined,
1787 altPaths , altExtensions);
1790 else if(relatedExtension ==
"js")
1792 relatedExtension =
"css";
1793 var i = relatedPath.indexOf(
"/js/");
1797 altPaths.push(relatedPath.substr(0,i) +
"/html/" +
1798 relatedPath.substr(i + (
"/js/").length));
1799 altExtensions.push(
"html");
1801 relatedPath = relatedPath.substr(0,i) +
"/css/" +
1802 relatedPath.substr(i + (
"/js/").length);
1806 altPaths.push(relatedPath);
1807 altExtensions.push(
"html");
1810 CodeEditor.editor.openFile(targetPane,relatedPath,relatedExtension,
1811 undefined , undefined,
1812 altPaths , altExtensions);
1816 Debug.log(
"Giving up on attempt to open a related file for " +
1817 relatedPath +
"." + relatedExtension +
1818 "... no known related file.", Debug.HIGH_PRIORITY);
1829 this.openFile =
function(forPrimary,path,extension,doConfirm,gotoLine,
1830 altPaths,altExtensions,propagateErr)
1832 forPrimary = forPrimary?1:0;
1834 Debug.log(
"openFile forPrimary=" + forPrimary +
1836 var i = path.lastIndexOf(
'.');
1838 path = path.substr(0,i);
1840 if(!propagateErr) propagateErr =
"";
1844 DesktopContent.popUpVerification(
1845 "Do you want to reload the file from the server (and discard your changes)?",
1853 var keys = Object.keys(_fileHistoryStack);
1854 var filename = path +
"." + extension;
1855 for(i;i<keys.length;++i)
1856 if(filename == keys[i])
1858 Debug.log(
"Found " + filename +
" in file history.");
1863 fileObj.path = path;
1864 fileObj.extension = extension;
1865 fileObj.text = _fileHistoryStack[filename][0];
1866 fileObj.fileWasModified = _fileHistoryStack[filename][2];
1867 fileObj.fileLastSave = _fileHistoryStack[filename][3];
1869 console.log(
"fileObj",fileObj);
1871 CodeEditor.editor.handleFileContent(forPrimary,0,fileObj);
1873 CodeEditor.editor.toggleDirectoryNav(forPrimary,
false );
1876 if(!forPrimary && _viewMode == 0)
1877 CodeEditor.editor.toggleView();
1885 function localDoIt()
1887 CodeEditor.editor.toggleDirectoryNav(forPrimary,
false );
1889 DesktopContent.XMLHttpRequest(
"Request?RequestType=codeEditor" +
1890 "&option=getFileContent" +
1897 var err = DesktopContent.getXMLValue(req,
"Error");
1900 if(altPaths && altPaths.length &&
1901 altExtensions && altExtensions.length)
1904 CodeEditor.editor.openFile(forPrimary,
1905 altPaths.splice(0,1)[0],
1906 altExtensions.splice(0,1)[0],
1907 undefined , undefined,
1908 altPaths , altExtensions,
1909 propagateErr + err );
1912 Debug.log(propagateErr + err,Debug.HIGH_PRIORITY);
1921 CodeEditor.editor.toggleDirectoryNav(forPrimary,0 );
1922 CodeEditor.editor.handleFileContent(forPrimary, req);
1925 if(!forPrimary && _viewMode == 0)
1926 CodeEditor.editor.toggleView();
1928 if(gotoLine !== undefined)
1929 CodeEditor.editor.gotoLine(forPrimary,gotoLine);
1933 Debug.log(
"Ignoring error handling file open: " + e);
1935 console.log(DesktopContent._loadBox.style.display);
1945 this.getLine =
function(forPrimary)
1947 Debug.log(
"getLine() forPrimary=" + forPrimary);
1950 var el = _eel[forPrimary];
1951 var cursor = CodeEditor.editor.getCursor(el);
1953 if(cursor.startNodeIndex === undefined)
1955 Debug.log(
"No cursor, so defaulting to top");
1961 for(n=0; n<el.childNodes.length; ++n)
1963 node = el.childNodes[n];
1964 val = node.textContent;
1967 for(i=0;i<val.length;++i)
1970 if(!cursor.focusAtEnd &&
1971 n == cursor.startNodeIndex &&
1972 i == cursor.startPos)
1974 else if(cursor.focusAtEnd &&
1975 n == cursor.endNodeIndex &&
1984 if(!cursor.focusAtEnd &&
1985 n == cursor.startNodeIndex)
1987 Debug.log(
"Found cursor at line " + cursor.line);
1990 else if(cursor.focusAtEnd &&
1991 n == cursor.endNodeIndex)
1993 Debug.log(
"Found cursor at line " + cursor.line);
2003 this.gotoLine =
function(forPrimary,line,selectionCursor,topOfView)
2006 if(line < 1) line = 1;
2007 if(line > _numberOfLines[forPrimary])
2008 line = _numberOfLines[forPrimary];
2009 console.log(
"Goto line number ",line,selectionCursor);
2012 window.location.href =
"#" + forPrimary +
"L" + line;
2018 var el = _eel[forPrimary];
2025 "startNodeIndex": 0,
2034 cursor.endNodeIndex = selectionCursor.startNodeIndex;
2035 cursor.endPos = selectionCursor.startPos;
2036 cursor.focusAtEnd = selectionCursor.focusAtEnd;
2038 CodeEditor.editor.setCursor(el,cursor,
true );
2043 var i,n,node,el,val;
2046 var newLine =
false;
2050 for(n=0; n<el.childNodes.length; ++n)
2052 node = el.childNodes[n];
2053 val = node.textContent;
2056 for(i=0;i<val.length;++i)
2065 if(line == lineCount)
2068 Debug.log(
"Found line " + line);
2086 "startNodeIndex":lastNode,
2088 "endNodeIndex":lastNode,
2096 cursor.focusAtEnd = selectionCursor.focusAtEnd;
2098 if(lastNode < selectionCursor.startNodeIndex ||
2099 ( lastNode == selectionCursor.startNodeIndex &&
2100 lastPos < selectionCursor.startPos))
2102 cursor.endNodeIndex = selectionCursor.startNodeIndex;
2103 cursor.endPos = selectionCursor.startPos;
2107 cursor.startNodeIndex = selectionCursor.startNodeIndex;
2108 cursor.startPos = selectionCursor.startPos;
2112 CodeEditor.editor.setCursor(el,cursor,
2118 CodeEditor.editor.setCursor(el,cursor,
true );
2130 this.handleFileContent =
function(forPrimary,req,fileObj)
2132 forPrimary = forPrimary?1:0;
2134 Debug.log(
"handleFileContent forPrimary=" + forPrimary);
2140 var fileWasModified, fileLastSave;
2144 path = DesktopContent.getXMLValue(req,
"path");
2145 extension = DesktopContent.getXMLValue(req,
"ext");
2146 text = DesktopContent.getXMLValue(req,
"content");
2147 fileWasModified =
false;
2152 path = fileObj.path;
2153 extension = fileObj.extension;
2154 text = fileObj.text;
2155 fileWasModified = fileObj.fileWasModified;
2156 fileLastSave = fileObj.fileLastSave;
2161 text = text.replace(
new RegExp(
2162 String.fromCharCode(160),
'g'),
' ');
2166 _filePath[forPrimary] = path;
2167 _fileExtension[forPrimary] = extension;
2168 _fileWasModified[forPrimary] = fileWasModified;
2169 _fileLastSave[forPrimary] = fileLastSave;
2171 _undoStack[forPrimary] = [];
2172 _undoStackLatestIndex[forPrimary] = -1;
2174 var el = _eel[forPrimary];
2177 DesktopContent.showLoading(
function()
2181 el.textContent = text;
2182 CodeEditor.editor.displayFileHeader(forPrimary);
2185 { Debug.log(
"Ignoring error: " + e); }
2192 this.setCursor =
function(el,inCursor,scrollIntoView)
2194 if(inCursor.startNodeIndex !== undefined)
2198 "startNodeIndex": inCursor.startNodeIndex,
2199 "startPos": inCursor.startPos,
2200 "endNodeIndex": inCursor.endNodeIndex,
2201 "endPos": inCursor.endPos,
2202 "focusAtEnd": inCursor.focusAtEnd,
2206 var scrollEndIntoView = cursor.focusAtEnd?
true:
false;
2210 console.log(
"set cursor",cursor,
"scrollIntoView=",scrollIntoView,
2211 "scrollEndIntoView=",scrollEndIntoView);
2213 var range = document.createRange();
2215 var firstEl = el.childNodes[cursor.startNodeIndex];
2219 var secondEl = el.childNodes[cursor.endNodeIndex];
2225 Debug.log(
"scrollIntoView");
2234 Debug.log(
"inserting scroll 2nd element");
2238 var val = secondEl.textContent;
2239 var newNode1 = document.createTextNode(
2240 val.substr(0,cursor.endPos));
2242 el.insertBefore(newNode1,secondEl);
2244 var newNode = document.createElement(
"label");
2245 newNode.textContent = val[cursor.endPos];
2246 el.insertBefore(newNode,secondEl);
2248 secondEl.textContent = val.substr(cursor.endPos+1);
2250 newNode.scrollIntoViewIfNeeded();
2252 el.removeChild(newNode);
2253 el.removeChild(newNode1);
2254 secondEl.textContent = val;
2258 Debug.log(
"Failed to scroll to inserted 2nd element: " + e);
2261 secondEl.scrollIntoViewIfNeeded();
2265 Debug.log(
"Failed to scroll 2nd element: " + e);
2270 Debug.log(
"inserting scroll 1st element");
2275 if(!scrollEndIntoView)
2278 firstEl = el.childNodes[cursor.startNodeIndex];
2279 var val = firstEl.textContent;
2280 var newNode1 = document.createTextNode(
2281 val.substr(0,cursor.startPos));
2283 el.insertBefore(newNode1,firstEl);
2285 var newNode = document.createElement(
"label");
2286 newNode.textContent = val[cursor.startPos];
2287 el.insertBefore(newNode,firstEl);
2289 firstEl.textContent = val.substr(cursor.startPos+1);
2291 newNode.scrollIntoViewIfNeeded();
2294 el.removeChild(newNode);
2295 el.removeChild(newNode1);
2296 firstEl.textContent = val;
2299 Debug.log(
"scrollEndIntoView only");
2303 Debug.log(
"Failed to scroll to inserted 1st element: " + e);
2306 firstEl.scrollIntoViewIfNeeded();
2310 Debug.log(
"Failed to scroll 1st element: " + e);
2319 if(firstEl.firstChild)
2320 firstEl = firstEl.firstChild;
2321 if(secondEl.firstChild)
2322 secondEl = secondEl.firstChild;
2324 range.setStart(firstEl,
2326 range.setEnd(secondEl,
2330 var selection = window.getSelection();
2331 selection.removeAllRanges();
2332 selection.addRange(range);
2335 if(scrollEndIntoView)
2336 selection.extend(secondEl,cursor.endPos);
2348 console.log(
"set cursor err:",err);
2355 this.createCursorFromContentPosition =
function(el,startPos,endPos)
2359 "startNodeIndex":undefined,
2360 "startPos":undefined,
2361 "endNodeIndex":undefined,
2372 for(i=0;i<el.childNodes.length;++i)
2374 sum += el.childNodes[i].textContent.length;
2376 if(cursor.startNodeIndex === undefined &&
2377 startPos >= oldSum &&
2381 cursor.startNodeIndex = i;
2382 cursor.startPos = startPos - oldSum;
2384 if(endPos >= oldSum &&
2388 cursor.endNodeIndex = i;
2389 cursor.endPos = endPos - oldSum;
2396 console.log(
"createCursorFromContentPosition:",cursor);
2401 console.log(
"get cursor err:",err);
2409 this.getCursor =
function(el)
2413 "startNodeIndex":undefined,
2414 "startPos":undefined,
2415 "endNodeIndex":undefined,
2417 "startPosInContent":undefined,
2418 "endPosInContent":undefined,
2419 "focusAtEnd":undefined
2425 var selection = window.getSelection();
2426 var range = selection.getRangeAt(0);
2427 var focusNode = selection.focusNode;
2428 var extentNode = selection.extentNode;
2430 cursor.startPos = range.startOffset;
2431 cursor.endPos = range.endOffset;
2434 for(i=0;i<el.childNodes.length;++i)
2436 if(cursor.startNodeIndex === undefined &&
2438 el.childNodes[i] == range.startContainer ||
2439 el.childNodes[i] == range.startContainer.parentNode ||
2440 el.childNodes[i] == range.startContainer.parentNode.parentNode ||
2441 el.childNodes[i] == range.startContainer.parentNode.parentNode.parentNode) )
2443 cursor.startNodeIndex = i;
2444 cursor.startPosInContent = sum + cursor.startPos;
2446 if(focusNode == range.startContainer ||
2447 extentNode == range.startContainer)
2448 cursor.focusAtEnd =
false;
2451 if(el.childNodes[i] == range.endContainer ||
2452 el.childNodes[i] == range.endContainer.parentNode ||
2453 el.childNodes[i] == range.endContainer.parentNode.parentNode ||
2454 el.childNodes[i] == range.startContainer.parentNode.parentNode.parentNode)
2456 cursor.endNodeIndex = i;
2457 cursor.endPosInContent = sum + cursor.endPos;
2459 if(cursor.focusAtEnd == undefined &&
2460 (focusNode == range.endContainer ||
2461 extentNode == range.endContainer))
2462 cursor.focusAtEnd =
true;
2467 sum += el.childNodes[i].textContent.length;
2476 console.log(
"get cursor err:",err);
2484 var _DECORATION_RED =
"rgb(202, 52, 52)";
2485 var _DECORATION_BLUE =
"rgb(64, 86, 206)";
2486 var _DECORATION_GREEN =
"rgb(33, 175, 60)";
2487 var _DECORATION_BLACK =
"rgb(5, 5, 5)";
2488 var _DECORATION_GRAY =
"rgb(162, 179, 158)";
2489 var _DECORATIONS = {
2491 "ADD_SUBDIRECTORY" : _DECORATION_RED,
2492 "include_directories" : _DECORATION_RED,
2493 "simple_plugin" : _DECORATION_RED,
2494 "set" : _DECORATION_RED,
2495 "install_headers" : _DECORATION_RED,
2496 "install_source" : _DECORATION_RED,
2497 "enable_testing" : _DECORATION_RED,
2498 "CMAKE_MINIMUM_REQUIRED": _DECORATION_RED,
2499 "include" : _DECORATION_RED,
2500 "create_doxygen_documentation": _DECORATION_RED,
2503 "#define" : _DECORATION_RED,
2504 "#undef" : _DECORATION_RED,
2505 "#include" : _DECORATION_RED,
2506 "#ifndef" : _DECORATION_RED,
2507 "#else" : _DECORATION_RED,
2508 "#endif" : _DECORATION_RED,
2509 "using" : _DECORATION_RED,
2510 "namespace" : _DECORATION_RED,
2511 "class" : _DECORATION_RED,
2512 "public" : _DECORATION_RED,
2513 "private" : _DECORATION_RED,
2514 "protected" : _DECORATION_RED,
2515 "static" : _DECORATION_RED,
2516 "virtual" : _DECORATION_RED,
2517 "override" : _DECORATION_RED,
2518 "const" : _DECORATION_RED,
2519 "void" : _DECORATION_RED,
2520 "bool" : _DECORATION_RED,
2521 "unsigned" : _DECORATION_RED,
2522 "int" : _DECORATION_RED,
2523 "uint64_t" : _DECORATION_RED,
2524 "uint32_t" : _DECORATION_RED,
2525 "uint16_t" : _DECORATION_RED,
2526 "uint8_t" : _DECORATION_RED,
2527 "long" : _DECORATION_RED,
2528 "float" : _DECORATION_RED,
2529 "double" : _DECORATION_RED,
2530 "return" : _DECORATION_RED,
2531 "char" : _DECORATION_RED,
2532 "if" : _DECORATION_RED,
2533 "else" : _DECORATION_RED,
2534 "for" : _DECORATION_RED,
2535 "while" : _DECORATION_RED,
2536 "do" : _DECORATION_RED,
2537 "switch" : _DECORATION_RED,
2538 "case" : _DECORATION_RED,
2539 "default" : _DECORATION_RED,
2540 "try" : _DECORATION_RED,
2541 "catch" : _DECORATION_RED,
2542 "this" : _DECORATION_RED,
2543 "true" : _DECORATION_RED,
2544 "false" : _DECORATION_RED,
2548 "std" : _DECORATION_GREEN,
2549 "ots" : _DECORATION_GREEN,
2550 "string" : _DECORATION_GREEN,
2551 "set" : _DECORATION_GREEN,
2552 "vector" : _DECORATION_GREEN,
2553 "pair" : _DECORATION_GREEN,
2554 "get" : _DECORATION_GREEN,
2555 "map" : _DECORATION_GREEN,
2556 "endl" : _DECORATION_GREEN,
2557 "runtime_error" : _DECORATION_GREEN,
2558 "memcpy" : _DECORATION_GREEN,
2559 "cout" : _DECORATION_GREEN,
2562 "this" : _DECORATION_RED,
2563 "var" : _DECORATION_RED,
2564 "return" : _DECORATION_RED,
2565 "function" : _DECORATION_RED,
2566 "if" : _DECORATION_RED,
2567 "else" : _DECORATION_RED,
2568 "for" : _DECORATION_RED,
2569 "while" : _DECORATION_RED,
2570 "do" : _DECORATION_RED,
2571 "switch" : _DECORATION_RED,
2572 "case" : _DECORATION_RED,
2573 "default" : _DECORATION_RED,
2574 "try" : _DECORATION_RED,
2575 "catch" : _DECORATION_RED,
2576 "new" : _DECORATION_RED,
2577 "instanceof" : _DECORATION_RED,
2578 "true" : _DECORATION_RED,
2579 "false" : _DECORATION_RED,
2581 "Debug" : _DECORATION_GREEN,
2582 "DesktopContent" : _DECORATION_GREEN,
2583 "HIGH_PRIORITY" : _DECORATION_GREEN,
2584 "WARN_PRIORITY" : _DECORATION_GREEN,
2585 "INFO_PRIORITY" : _DECORATION_GREEN,
2586 "LOW_PRIORITY" : _DECORATION_GREEN,
2588 "Math" : _DECORATION_GREEN,
2589 "String" : _DECORATION_GREEN,
2590 "window" : _DECORATION_GREEN,
2591 "document" : _DECORATION_GREEN,
2592 "textContent" : _DECORATION_GREEN,
2593 "innerHTML" : _DECORATION_GREEN,
2596 "if" : _DECORATION_RED,
2597 "then" : _DECORATION_RED,
2598 "else" : _DECORATION_RED,
2599 "fi" : _DECORATION_RED,
2600 "for" : _DECORATION_RED,
2601 "in" : _DECORATION_RED,
2602 "while" : _DECORATION_RED,
2603 "do" : _DECORATION_RED,
2604 "done" : _DECORATION_RED,
2605 "switch" : _DECORATION_RED,
2606 "case" : _DECORATION_RED,
2607 "default" : _DECORATION_RED,
2608 "export" : _DECORATION_RED,
2610 "echo" : _DECORATION_GREEN,
2611 "cd" : _DECORATION_GREEN,
2612 "cp" : _DECORATION_GREEN,
2613 "rm" : _DECORATION_GREEN,
2614 "cat" : _DECORATION_GREEN,
2615 "wget" : _DECORATION_GREEN,
2616 "chmod" : _DECORATION_GREEN,
2617 "sleep" : _DECORATION_GREEN,
2620 this.updateDecorations =
function(forPrimary,forceDisplayComplete,forceDecorations)
2622 forPrimary = forPrimary?1:0;
2624 Debug.log(
"updateDecorations forPrimary=" + forPrimary +
" forceDisplayComplete=" + forceDisplayComplete);
2626 var el = _eel[forPrimary];
2627 var elTextObj = {
"text":el.textContent,
"time":Date.now()};
2628 var wasSnapshot = CodeEditor.editor.updateFileSnapshot(forPrimary,
2631 if(wasSnapshot || forceDisplayComplete)
2632 CodeEditor.editor.updateOutline(forPrimary,elTextObj);
2634 if(!forceDecorations && !wasSnapshot)
2636 Debug.log(
"unchanged, skipping decorations");
2646 var cursor = CodeEditor.editor.getCursor(el);
2650 CodeEditor.editor.updateLastSave(forPrimary);
2654 var decor, fontWeight;
2656 var commentString =
"#";
2657 if(_fileExtension[forPrimary][0] ==
'c' ||
2658 _fileExtension[forPrimary][0] ==
'C' ||
2659 _fileExtension[forPrimary][0] ==
'h' ||
2660 _fileExtension[forPrimary][0] ==
'j')
2661 commentString =
"//";
2663 var fileDecorType =
"txt";
2664 if( _fileExtension[forPrimary] ==
'html' ||
2665 _fileExtension[forPrimary] ==
'js')
2666 fileDecorType =
"js";
2667 else if(_fileExtension[forPrimary][0] ==
'c' ||
2668 _fileExtension[forPrimary][0] ==
'C' ||
2669 _fileExtension[forPrimary][0] ==
'h' ||
2670 _fileExtension[forPrimary][0] ==
'j')
2671 fileDecorType =
"c++";
2672 else if(_fileExtension[forPrimary] ==
'sh' ||
2673 _fileExtension[forPrimary] ==
'py')
2674 fileDecorType =
"sh";
2679 var startOfWord = -1;
2680 var startOfString = -1;
2681 var stringQuoteChar;
2683 var startOfComment = -1;
2684 var firstSpecialStringStartHandling =
true;
2685 var firstSpecialStringEndHandling =
true;
2686 var endPositionCache;
2697 function localInsertLabel(startPos, isQuote)
2701 newNode = document.createTextNode(val.substr(0,startPos));
2702 el.insertBefore(newNode,node);
2704 newNode = document.createElement(
"label");
2705 newNode.style.fontWeight = fontWeight;
2706 newNode.style.color = decor;
2707 newNode.textContent = specialString;
2709 el.insertBefore(newNode,node);
2713 var str = newNode.textContent;
2714 str = str.substr(str.lastIndexOf(
'.')+1);
2717 if(str.length > 0 && str.length <= 4 &&
2727 Debug.log(
"is quote " + str);
2729 newNode.onmouseover =
function(e)
2731 window.clearTimeout(_fileStringHoverTimeout);
2733 var x = this.offsetWidth + this.offsetLeft + 64;
2734 var y = this.offsetTop;
2735 e.stopPropagation();
2738 if(_fileStringHoverEl.parentNode)
2740 _fileStringHoverEl.parentNode.removeChild(_fileStringHoverEl);
2745 _fileStringHoverEl = document.createElement(
"div");
2746 _fileStringHoverEl.setAttribute(
"id",
"fileStringHoverEl");
2747 _fileStringHoverEl.setAttribute(
"contentEditable",
"false");
2748 _fileStringHoverEl.onmouseover =
function(e)
2750 window.clearTimeout(_fileStringHoverTimeout);
2751 e.stopPropagation();
2755 _fileStringHoverEl.style.display =
'none';
2758 var name = this.textContent;
2761 name = name.substr(1,name.length-2);
2762 var nameArr = name.split(
'/');
2763 if(nameArr.length == 0)
2765 Debug.log(
"empty name array, error! name = " + name);
2768 else if(nameArr.length > 1 && nameArr[0] ==
"" &&
2769 nameArr[1] ==
"WebPath")
2771 name =
"/otsdaq_utilities/WebGUI" +
2772 name.substr((
"/WebPath").length);
2774 else if(nameArr[0] !=
"")
2777 var i = nameArr[0].indexOf(
'-');
2781 if(nameArr[0] !=
"otsdaq-core")
2783 nameArr[0] = nameArr[0].substr(0,i) +
'_'
2784 + nameArr[0].substr(i+1);
2787 nameArr[0] =
"otsdaq";
2789 name =
"/" + nameArr[0] +
"/" + name;
2793 Debug.log(
"Confused by name array, error! name = " + name);
2799 Debug.log(
"name " + name);
2803 str += htmlOpen(
"a",
2805 "title":
"Open file in this editor pane: \n" +
2807 "onclick":
"CodeEditor.editor.openFile(" +
2808 (forPrimary) +
",\"" +
2810 name.substr(name.lastIndexOf(
'.')+1) +
"\"" +
2814 "style='float: left; padding: 1px 0 1px 6px;'>" +
2816 "style='border:1px solid rgb(99, 98, 98); border-radius: 2px; width: 9px;" +
2817 "height: 9px; '></div></div>"
2820 str += htmlOpen(
"a",
2822 "title":
"Open file in the other editor pane of the split-view: \n" +
2824 "onclick":
"CodeEditor.editor.openFile(" +
2825 (!forPrimary) +
",\"" +
2827 name.substr(name.lastIndexOf(
'.')+1) +
"\"" +
2831 "style='float: left; padding: 0;'>" +
2832 "<img class='dirNavFileNewWindowImgNewPane' " +
2833 "src='/WebPath/images/windowContentImages/CodeEditor-openInOtherPane.png'></div>"
2836 str += htmlOpen(
"a",
2838 "title":
"Open file in a new browser tab: \n" +
2840 "onclick":
"DesktopContent.openNewBrowserTab(" +
2841 "\"Code Editor\",\"\"," +
2842 "\"/WebPath/html/CodeEditor.html?urn=" +
2843 DesktopContent._localUrnLid +
"&" +
2844 "startFilePrimary=" +
2845 name +
"\",0 /*unique*/);' ",
2848 "style='float: left; padding: 0 6px 0 0;'>" +
2849 "<img class='dirNavFileNewWindowImgNewWindow' " +
2850 "src='/WebPath/images/windowContentImages/CodeEditor-openInNewWindow.png'></div>"
2853 _fileStringHoverEl.innerHTML = str;
2855 this.parentNode.appendChild(_fileStringHoverEl);
2858 _fileStringHoverEl.style.left = x +
"px";
2859 _fileStringHoverEl.style.top = y +
"px";
2861 _fileStringHoverEl.style.display =
'block';
2868 node.textContent = val.substr(i);
2872 if(cursor.startNodeIndex !== undefined)
2874 if(n < cursor.startNodeIndex)
2877 cursor.startNodeIndex += 2;
2878 cursor.endNodeIndex += 2;
2885 if(n == cursor.startNodeIndex)
2888 if(cursor.startPos < startPos)
2893 else if(cursor.startPos < i)
2896 ++cursor.startNodeIndex;
2897 cursor.startPos -= startPos;
2902 cursor.startNodeIndex += 2;
2903 if(val[cursor.startPos-1] ==
'\r') --cursor.startPos;
2904 cursor.startPos -= i;
2909 if(n == cursor.endNodeIndex)
2912 if(cursor.endPos < startPos)
2917 else if(cursor.endPos < i)
2920 ++cursor.endNodeIndex;
2921 cursor.endPos -= startPos;
2926 cursor.endNodeIndex += 2;
2927 if(val[cursor.endPos-1] ==
'\r') --cursor.endPos;
2932 else if(n < cursor.endNodeIndex)
2934 cursor.endNodeIndex += 2;
2944 for(n=0;!done && n<el.childNodes.length;++n)
2946 node = el.childNodes[n];
2947 val = node.textContent;
2949 if(node.nodeName ==
"LABEL" ||
2950 node.nodeName ==
"FONT" ||
2951 node.nodeName ==
"SPAN" ||
2952 node.nodeName ==
"PRE")
2957 if((_DECORATIONS[fileDecorType][val] === undefined &&
2958 (val[0] != commentString[0] ||
2959 val.indexOf(
'\n') >= 0) &&
2962 (n+1 >= cursor.startNodeIndex && n-1 <= cursor.endNodeIndex))
2967 newNode = document.createTextNode(val);
2968 el.insertBefore(newNode,node);
2969 el.removeChild(node);
2978 else if(node.nodeName ==
"DIV" ||
2979 node.nodeName ==
"BR")
2983 eatVal = node.innerHTML;
2987 if(node.nodeName ==
"DIV")
2991 specialString = el.childNodes[n-1].textContent;
2992 if(specialString[specialString.length-1] ==
'\n')
2996 if(eatVal.indexOf(
"<br>") == 0 ||
3008 newNode = document.createTextNode(val);
3009 el.insertBefore(newNode,node);
3010 el.removeChild(node);
3013 if(n == cursor.startNodeIndex)
3014 cursor.startPos += i;
3015 if(n == cursor.endNodeIndex)
3022 else if(node.nodeName ==
"#text")
3025 el.childNodes[n-1].nodeName ==
"#text")
3033 if(n + 1 < el.childNodes.length &&
3034 el.childNodes[n+1].nodeName ==
"#text")
3041 if(cursor.startNodeIndex !== undefined)
3043 if(n+1 < cursor.startNodeIndex)
3046 cursor.startNodeIndex -= 1;
3047 cursor.endNodeIndex -= 1;
3054 if(n+1 == cursor.startNodeIndex)
3057 --cursor.startNodeIndex;
3058 cursor.startPos += val.length;
3062 if(n+1 == cursor.endNodeIndex)
3065 --cursor.endNodeIndex;
3066 cursor.endPos += val.length;
3068 else if(n+1 < cursor.endNodeIndex)
3071 --cursor.endNodeIndex;
3077 newNode = el.childNodes[n+1];
3078 val += newNode.textContent;
3079 newNode.textContent = val;
3080 el.removeChild(node);
3088 for(i=0;i<val.length;++i)
3095 if(startOfComment == -1 && (
3096 startOfString != -1 ||
3097 (prevChar !=
'\\' && val[i] ==
'"') ||
3098 (prevChar !=
'\\' && val[i] ==
"'")
3101 if(startOfString == -1 &&
3102 (val[i] ==
'"' || val[i] ==
"'"))
3105 stringQuoteChar = val[i];
3107 firstSpecialStringStartHandling =
true;
3108 firstSpecialStringEndHandling =
true;
3110 else if(prevChar !=
'\\' && val[i] == stringQuoteChar)
3113 specialString = val.substr(startOfString,i-startOfString);
3116 decor = _DECORATION_BLUE;
3117 fontWeight =
"normal";
3118 localInsertLabel(startOfString,
true );
3124 else if(startOfString == -1 && (
3125 startOfComment != -1 ||
3126 (i+commentString.length-1 < val.length &&
3127 val.substr(i,commentString.length) ==
3130 if(startOfComment == -1 && val[i] == commentString[0])
3133 firstSpecialStringStartHandling =
true;
3134 firstSpecialStringEndHandling =
true;
3136 else if(val[i] ==
'\n')
3139 specialString = val.substr(startOfComment,i-startOfComment);
3142 decor = _DECORATION_GRAY;
3143 fontWeight =
"normal";
3144 localInsertLabel(startOfComment);
3145 startOfComment = -1;
3151 (val[i] >=
'a' && val[i] <=
'z') ||
3152 (val[i] >=
'A' && val[i] <=
'Z') ||
3153 (val[i] >=
'0' && val[i] <=
'9') ||
3154 (val[i] ==
'_' || val[i] ==
'-') ||
3157 if(startOfWord == -1)
3161 else if(startOfWord != -1)
3163 specialString = val.substr(startOfWord,i-startOfWord);
3164 decor = _DECORATIONS[fileDecorType][specialString];
3170 fontWeight =
"bold";
3171 localInsertLabel(startOfWord);
3181 if(prevChar ==
'\\' && val[i] ==
'\\')
3184 if(escapeCount%2 == 0)
3202 if(startOfString != -1 || startOfComment != -1)
3204 console.log(
"In string/comment crossing Nodes!");
3207 closedString =
false;
3208 for(++n;n<el.childNodes.length;++n)
3210 eatNode = el.childNodes[n];
3211 eatVal = eatNode.textContent;
3215 if(cursor.startNodeIndex !== undefined)
3217 if(firstSpecialStringStartHandling)
3218 firstSpecialStringStartHandling =
false;
3220 if(firstSpecialStringEndHandling)
3224 endPositionCache = cursor.endPos;
3225 firstSpecialStringEndHandling =
false;
3228 if(n < cursor.startNodeIndex)
3231 cursor.startNodeIndex -= 1;
3232 cursor.endNodeIndex -= 1;
3239 if(n == cursor.startNodeIndex)
3242 --cursor.startNodeIndex;
3243 cursor.startPos += val.length;
3247 if(n == cursor.endNodeIndex)
3250 --cursor.endNodeIndex;
3251 cursor.endPos += val.length;
3253 else if(n < cursor.endNodeIndex)
3256 --cursor.endNodeIndex;
3332 el.removeChild(eatNode);
3337 for(i;i<val.length;++i)
3340 if(startOfString != -1 &&
3341 (prevChar !=
'\\' && val[i] ==
'"'))
3343 Debug.log(
"Closing node crossed string.");
3346 specialString = val.substr(startOfString,i-startOfString);
3349 decor = _DECORATION_BLUE;
3350 fontWeight =
"normal";
3351 localInsertLabel(startOfString,
true );
3353 closedString =
true;
3358 if(startOfComment != -1 && val[i] ==
'\n')
3360 Debug.log(
"Closing node crossed comment.");
3364 specialString = val.substr(startOfComment,i-startOfComment);
3367 decor = _DECORATION_GRAY;
3368 fontWeight =
"normal";
3369 localInsertLabel(startOfComment);
3370 startOfComment = -1;
3372 closedString =
true;
3378 if(prevChar ==
'\\' && val[i] ==
'\\')
3381 if(escapeCount%2 == 0)
3394 if(closedString)
break;
3398 if(!closedString && startOfString != -1)
3400 Debug.log(
"String is never closed!");
3401 specialString = val.substr(startOfString,i-startOfString);
3404 decor = _DECORATION_BLUE;
3406 localInsertLabel(startOfString,
true );
3409 if(!closedString && startOfComment != -1)
3411 Debug.log(
"Comment is never closed!");
3412 specialString = val.substr(startOfComment,i-startOfComment);
3415 decor = _DECORATION_GRAY;
3417 localInsertLabel(startOfComment);
3418 startOfComment = -1;
3421 if(n < cursor.endNodeIndex)
3425 firstSpecialStringEndHandling =
true;
3426 cursor.endPos = endPositionCache;
3435 console.log(
"unknown node.nodeName",node.nodeName);
3436 throw(
"node error!");
3441 CodeEditor.editor.setCursor(el,cursor);
3443 CodeEditor.editor.updateDualView(forPrimary);
3449 this.autoIndent =
function(forPrimary, cursor)
3451 if(!cursor || cursor.startNodeIndex === undefined)
3453 Debug.log(
"Invalid text selection for auto-indent. Please select text in the text editor.",
3454 Debug.HIGH_PRIORITY);
3457 forPrimary = forPrimary?1:0;
3459 Debug.log(
"autoIndent " + forPrimary);
3461 DesktopContent.showLoading(localDoIt);
3470 function localDoIt()
3480 var el = _eel[forPrimary];
3486 for(n=cursor.startNodeIndex;n>=0; --n)
3488 node = el.childNodes[n];
3489 val = node.textContent;
3491 for(i=(n==cursor.startNodeIndex?cursor.startPos-1:
3492 val.length-1); i>=0; --i)
3505 console.log(
"at leading newline - n",n,
"i",i);
3511 cursor.startNodeIndex = n;
3512 cursor.startPos = i;
3520 for(n=0; n<el.childNodes.length; ++n)
3522 val = el.childNodes[n].textContent;
3523 if(n < cursor.startNodeIndex)
3525 else if(n == cursor.startNodeIndex)
3527 preText += val.substr(0,cursor.startPos);
3529 if(n < cursor.endNodeIndex)
3530 text += val.substr(cursor.startPos);
3533 text += val.substr(cursor.startPos,
3534 cursor.endPos-cursor.startPos);
3535 postText += val.substr(cursor.endPos);
3538 else if(n < cursor.endNodeIndex)
3540 else if(n == cursor.endNodeIndex)
3542 text += val.substr(0,cursor.endPos);
3543 postText += val.substr(cursor.endPos);
3553 var fileExtension = _fileExtension[forPrimary];
3564 for(i=0;i<text.length;++i)
3567 else if(text[i] ==
'\t')
3568 x += _TAB_SIZE - (x+_TAB_SIZE)%_TAB_SIZE;
3571 Debug.log(
"Whitespace size =" + x +
" tabs=" + ((x/_TAB_SIZE)|0));
3575 for(n=0;n<((x/_TAB_SIZE)|0);++n)
3584 var lastChar,firstChar;
3585 var prevLastChar,prevFirstChar;
3587 var inCmdTabStr =
"";
3588 var nextInCmdTabStr =
"";
3589 var isCmdTabStr =
"";
3590 var nextIsCmdTabStr =
"";
3595 var firstColonCommand =
false;
3596 var lastColonCommand =
false;
3597 var foundDoubleQuote,foundSingleQuote;
3598 var tradeInCmdStack = [];
3599 var tradeIsCmdStack = [];
3609 foundComment =
false;
3610 foundDoubleQuote =
false;
3611 foundSingleQuote =
false;
3613 for(n=i+1;n<text.length;++n)
3621 if(!foundSingleQuote && text[n] ==
'"')
3622 foundDoubleQuote = !foundDoubleQuote;
3623 else if(!foundDoubleQuote && text[n] ==
"'")
3624 foundSingleQuote = !foundSingleQuote;
3625 else if(text[n] ==
'/' && n+1 < text.length &&
3628 foundComment =
true;
3632 if(foundDoubleQuote || foundSingleQuote)
3635 if(text[n] !=
' ' && text[n] !=
'\t')
3639 firstChar = text[n];
3644 inCmdTabStr +=
'\t';
3645 else if(text[n] ==
')')
3646 inCmdTabStr = inCmdTabStr.substr(0, inCmdTabStr.length-1);
3647 else if(inCmdTabStr.length == 0 &&
3652 firstColonCommand =
false;
3653 lastColonCommand =
false;
3658 nextTabStr = tabStr;
3661 if(firstChar ==
'}')
3663 nextIsCmdTabStr =
"";
3666 if(tradeInCmdStack.length &&
3667 tradeInCmdStack[tradeInCmdStack.length-1][0] ==
3671 inCmdTabStr = tradeInCmdStack.pop()[1];
3672 nextInCmdTabStr = inCmdTabStr;
3673 isCmdTabStr = tradeIsCmdStack.pop();
3674 tabStr = tabStr.substr(0,tabStr.length-1);
3679 firstColonCommand =
false;
3681 tabStr = tabStr.substr(0,tabStr.length-1);
3682 nextTabStr = tabStr;
3684 else if(lastChar ==
':' &&
3685 (firstChar ==
'p' ||
3689 nextIsCmdTabStr =
"";
3693 firstColonCommand =
false;
3694 lastColonCommand =
false;
3695 nextTabStr = tabStr.substr(0,tabStr.length-1);
3697 else if(firstChar ==
':')
3700 nextIsCmdTabStr =
"";
3702 firstColonCommand =
true;
3704 else if(firstChar ==
'#' ||
3708 if(lastColonCommand)
3709 tabStr = tabStr.substr(0,tabStr.length-1);
3713 if(nextInCmdTabStr.length != 0 ||
3714 nextIsCmdTabStr.length != 1 ||
3715 prevLastChar !=
',')
3718 nextIsCmdTabStr =
"";
3722 else if(!firstColonCommand &&
3723 !lastColonCommand &&
3729 else if(lastColonCommand &&
3730 prevLastChar ==
',' &&
3731 inCmdTabStr.length == 0)
3734 lastColonCommand =
false;
3735 tabStr = tabStr.substr(0,tabStr.length-1);
3737 nextIsCmdTabStr =
"\t";
3740 firstColonCommand =
false;
3747 firstColonCommand =
false;
3748 lastColonCommand =
false;
3752 "firstChar = " + firstChar +
3753 "lastChar = " + lastChar +
3754 "prevFirstChar = " + prevFirstChar +
3755 "prevLastChar = " + prevLastChar +
3759 inCmdTabStr.length +
3761 isCmdTabStr.length +
3765 nextInCmdTabStr.length +
3767 nextIsCmdTabStr.length +
3769 tradeInCmdStack.length +
3770 " " + firstColonCommand +
3771 " " + lastColonCommand);
3775 newText += nextTabStr + nextInCmdTabStr + nextIsCmdTabStr;
3777 newText += text.substr(i+1,n-(i+1)).trimLeft();
3786 if(inCmdTabStr.length)
3790 tradeInCmdStack.push([tabStr.length,inCmdTabStr]);
3791 tradeIsCmdStack.push(isCmdTabStr);
3807 nextInCmdTabStr = inCmdTabStr;
3808 nextIsCmdTabStr = isCmdTabStr;
3811 prevLastChar = lastChar;
3813 prevFirstChar = firstChar;
3817 }
while(i+1<text.length);
3821 if(text[i] ==
'\n') newText +=
'\n';
3827 Debug.log(
"Unknown operation to auto-indent file with extension " +
3828 fileExtension,Debug.HIGH_PRIORITY);
3833 el.textContent = preText + newText + postText;
3835 _fileWasModified[forPrimary] =
true;
3837 CodeEditor.editor.updateDecorations(forPrimary,
3846 this.updateDualView =
function(forPrimary)
3848 forPrimary = forPrimary?1:0;
3850 Debug.log(
"updateDualView " + forPrimary);
3854 if(_filePath[0] == _filePath[1] &&
3855 _fileExtension[0] == _fileExtension[1])
3857 var val,node, newNode;
3858 var el = _eel[forPrimary];
3860 Debug.log(
"Update dual view");
3862 _fileLastSave[(!forPrimary)?1:0] = _fileLastSave[forPrimary];
3863 _fileWasModified[(!forPrimary)?1:0] = _fileWasModified[forPrimary];
3864 CodeEditor.editor.updateLastSave(!forPrimary);
3868 var elAlt = _eel[(!forPrimary)?1:0];
3869 elAlt.innerHTML =
"";
3870 for(i=0;i<el.childNodes.length;++i)
3872 node = el.childNodes[i];
3873 val = node.textContent;
3874 if(node.nodeName ==
"LABEL")
3876 newNode = document.createElement(
"label");
3877 newNode.style.fontWeight = node.style.fontWeight;
3878 newNode.style.color = node.style.color;
3879 newNode.textContent = val;
3881 else if(node.nodeName ==
"#text")
3883 newNode = document.createTextNode(val);
3886 Debug.log(
"Skipping unknown node " + node.nodeName);
3887 elAlt.appendChild(newNode);
3896 this.updateOutline =
function(forPrimary,elTextObj)
3898 forPrimary = forPrimary?1:0;
3900 Debug.log(
"updateOutline " + forPrimary);
3908 var localNewLineCount;
3910 var newLineCount = 0;
3912 outline.push([1,
"Top"]);
3916 var isCcSource = _fileExtension[forPrimary][0] ==
'c' ||
3917 _fileExtension[forPrimary][0] ==
'C';
3918 var isJsSource = _fileExtension[forPrimary] ==
"js" ||
3919 _fileExtension[forPrimary] ==
"html";
3921 var indicatorIndex = 0;
3923 if(isCcSource) indicator =
"::";
3924 if(isJsSource) indicator =
"function";
3926 for(i=0;i<elTextObj.text.length;++i)
3928 if(elTextObj.text[i] ==
'\n')
3936 if(elTextObj.text[i] == indicator[indicatorIndex])
3939 if(indicatorIndex == indicator.length)
3946 str = localHandleCcOutline();
3948 str = localHandleJsOutline();
3953 outline.push([newLineCount+1,
3966 Debug.log(
"Number of lines " + newLineCount);
3967 console.log(
"Done with outline", outline);
3971 for(i=0;i<newLineCount;++i)
3973 str +=
"<a name='" + forPrimary +
"L" + (i+1) +
"'></a>";
3977 document.getElementById(
"editableBoxLeftMargin" + forPrimary).innerHTML = str;
3979 _numberOfLines[forPrimary] = newLineCount;
3982 if(!isCcSource && !isJsSource)
3985 i = (newLineCount/2)|0;
3988 outline.push([i,
"Middle"]);
3991 outline.push([newLineCount,
"Bottom"]);
3997 str +=
"<table><td>"
4000 str += htmlOpen(
"select",
4002 "class":
"textEditorOutlineSelect",
4003 "id":
"textEditorOutlineSelect" + forPrimary,
4004 "style":
"text-align-last: center; width: 100%;",
4005 "title":
"Jump to a section of code.",
4007 "CodeEditor.editor.handleOutlineSelect(" + forPrimary +
");",
4009 "CodeEditor.editor.stopUpdateHandling(event);",
4011 str +=
"<option value='0'>Jump to a Line Number (Ctrl + L)</option>";
4014 for(i=0;i<outline.length;++i)
4016 str +=
"<option value='" + (outline[i][0]-2) +
"'>";
4017 text =
"#" + outline[i][0];
4021 found = (outline[i][1].indexOf(
"local") == 0);
4023 for(j=text.length;j<(found?20:12);++j)
4025 str += outline[i][1];
4029 str +=
"</td></table>";
4033 document.getElementById(
"textEditorOutline" + forPrimary).innerHTML = str;
4037 Debug.log(
"Ignoring missing outline element. Assuming header not shown.");
4043 function localHandleCcOutline()
4045 if(startCi && i < startCi)
4059 for(j=i+2;j<elTextObj.text.length;++j)
4061 if(elTextObj.text[j] ==
';' ||
4062 elTextObj.text[j] ==
'+' ||
4063 elTextObj.text[j] ==
'"' ||
4064 elTextObj.text[j] ==
"'")
4068 if(elTextObj.text[j] ==
'(')
4071 else if(startCi < 0)
4073 if(elTextObj.text[j] ==
'{')
4083 if(endi < 0 || startCi < 0)
4092 if(elTextObj.text[j] ==
')')
4106 return elTextObj.text.substr(starti+2,endi-starti-2).replace(/\s+/g,
'');
4112 function localHandleJsOutline()
4114 if(elTextObj.text[i + 1] ==
'(')
4121 for(j=i-1-(
"function").length;j>=0;--j)
4123 if(elTextObj.text[j] ==
'=')
4129 else if(!(elTextObj.text[j] ==
' ' || elTextObj.text[j] ==
'\t' ||
4130 (elTextObj.text[j] ==
'=' && !found)))
4139 if(elTextObj.text[j] ==
' ' || elTextObj.text[j] ==
'\t' ||
4140 elTextObj.text[j] ==
'\n')
4143 return elTextObj.text.substr(j+1,k-j-1).trim();
4153 for(j=i+2;j<elTextObj.text.length;++j)
4155 if(elTextObj.text[j] ==
'\n')
4157 else if(elTextObj.text[j] ==
'(')
4160 return elTextObj.text.substr(i+2,j-(i+2)).trim();
4172 this.handleOutlineSelect =
function(forPrimary)
4174 forPrimary = forPrimary?1:0;
4176 Debug.log(
"handleOutlineSelect() " + forPrimary);
4178 var val = document.getElementById(
"textEditorOutlineSelect" + forPrimary).value | 0;
4179 if(val < 1) val = 1;
4180 console.log(
"line val",val);
4182 CodeEditor.editor.gotoLine(forPrimary,val,
4191 this.keyDownHandler =
function(e,forPrimary,shortcutsOnly)
4193 forPrimary = forPrimary?1:0;
4195 var keyCode = e.keyCode;
4197 CodeEditor.editor.stopUpdateHandling();
4208 Debug.log(
"keydown c=" + keyCode +
" " + c +
" shift=" + e.shiftKey +
4209 " ctrl=" + e.ctrlKey +
" command=" + _commandKeyDown);
4212 CodeEditor.editor.startUpdateHandling(forPrimary);
4214 var el = _eel[forPrimary];
4216 var cursorSelection =
false;
4222 cursor = CodeEditor.editor.getCursor(el);
4224 cursorSelection = (cursor.startNodeIndex !== undefined &&
4225 (cursor.startNodeIndex != cursor.endNodeIndex ||
4226 cursor.startPos != cursor.endPos));
4228 if(!cursorSelection)
4229 _lastPageUpDownLine = -1;
4232 function localInsertCharacter(c)
4234 Debug.log(
"Inserting character... " + c);
4247 if(cursor.endNodeIndex > cursor.startNodeIndex)
4250 val = el.childNodes[cursor.endNodeIndex].textContent;
4251 val = val.substr(cursor.endPos);
4252 el.childNodes[cursor.endNodeIndex].textContent = val;
4253 --cursor.endNodeIndex;
4254 while(cursor.endNodeIndex > cursor.startNodeIndex)
4257 el.removeChild(el.childNodes[cursor.endNodeIndex]);
4258 --cursor.endNodeIndex;
4261 cursor.endPos = el.childNodes[cursor.startNodeIndex].textContent.length;
4264 var whiteSpaceString =
"";
4265 var postWhiteSpaceString =
"";
4266 var text = el.childNodes[cursor.startNodeIndex].textContent;
4267 var preCharString = text.substr(0,cursor.startPos);
4268 var cursorPosDelta = 0;
4279 for(n=cursor.startNodeIndex;n>=0; --n)
4281 node = el.childNodes[n];
4282 val = node.textContent;
4284 for(i=(n==cursor.startNodeIndex?cursor.startPos-1:
4285 val.length-1); i>=0; --i)
4293 else if(firstChar ==
'' &&
4294 val[i] !=
'\t' && val[i] !=
' ')
4301 console.log(
"at leading newline - n",n,
"i",i,
"firstChar",firstChar);
4308 for(n; n<el.childNodes.length; ++n)
4310 node = el.childNodes[n];
4311 val = node.textContent;
4313 for(i;i<val.length;++i)
4316 if((val[i] !=
'\t' && val[i] !=
' ') ||
4317 (n == cursor.startNodeIndex &&
4318 i >= cursor.startPos))
4324 whiteSpaceString += val[i];
4327 if(found || n == cursor.startNodeIndex)
break;
4332 if(firstChar ==
'{')
4334 postWhiteSpaceString +=
"\n" + whiteSpaceString +
"}";
4335 whiteSpaceString +=
'\t';
4336 postWhiteSpaceString += text.substr(cursor.endPos);
4340 val = text.substr(cursor.endPos);
4341 i = val.indexOf(
'\n');
4345 postWhiteSpaceString += val.substr(0,
4347 postWhiteSpaceString += val.substr(i);
4350 postWhiteSpaceString += val.trimLeft();
4361 var foundFirstNewLine =
false;
4365 for(n=cursor.startNodeIndex;n>=0; --n)
4367 node = el.childNodes[n];
4368 val = node.textContent;
4370 for(i=(n==cursor.startNodeIndex?cursor.startPos-1:
4371 val.length-1); i>=0; --i)
4380 Debug.log(
"Found matching bracket n=" + n +
4387 else if(val[i] ==
'}')
4389 else if(!foundFirstNewLine &&
4392 foundFirstNewLine =
true;
4394 Debug.log(
"pre-deleted white space preCharString=" +
4395 preCharString.length +
" " + preCharString);
4400 for(nn;nn<el.childNodes.length;++nn)
4402 if(nn < cursor.startNodeIndex)
4405 el.childNodes[nn].textContent =
"";
4407 else if(nn == cursor.startNodeIndex)
4410 preCharString = el.childNodes[nn].textContent.substr(
4417 Debug.log(
"deleted white space preCharString=" +
4418 preCharString.length +
" " + preCharString);
4420 else if(!foundFirstNewLine && val[i] !=
' ' &&
4423 Debug.log(
"Found character between } and new line, so doing nothing.");
4432 console.log(
"at closing bracket - n",n,
"i",i);
4435 preCharString = preCharString.trimRight();
4439 var matchingWhiteSpace =
"";
4441 var firstTime =
true;
4445 node = el.childNodes[n];
4446 val = node.textContent;
4449 val.length-1); i>=0; --i)
4457 else if(val[i] ==
' ' ||
4459 matchingWhiteSpace += val[i];
4461 matchingWhiteSpace =
"";
4470 preCharString += matchingWhiteSpace;
4471 Debug.log(
"matching white space preCharString=" +
4472 preCharString.length +
" " + preCharString);
4474 postWhiteSpaceString += text.substr(cursor.endPos);
4478 postWhiteSpaceString += text.substr(cursor.endPos);
4480 val = preCharString + c +
4482 postWhiteSpaceString;
4484 el.childNodes[cursor.startNodeIndex].textContent = val;
4487 console.log(
"cursorPosDelta",cursorPosDelta);
4489 cursor.startPos = c.length + preCharString.length + whiteSpaceString.length;
4490 cursor.endNodeIndex = cursor.startNodeIndex;
4491 cursor.endPos = cursor.startPos;
4493 console.log(
"cursor after newline",cursor);
4495 CodeEditor.editor.setCursor(el,cursor,
true );
4497 _fileWasModified[forPrimary] =
true;
4512 localInsertCharacter(
'\n');
4518 else if(keyCode == 36)
4532 var lastNonWhitespacePos = cursor.startPos;
4533 var lastNonWhitespaceNodeIndex = cursor.startNodeIndex;
4534 var lastPos = cursor.startPos;
4535 var lastNodeIndex = cursor.startNodeIndex;
4538 for(n=cursor.startNodeIndex; n>=0; --n)
4540 node = el.childNodes[n];
4541 val = node.textContent;
4543 for(i=(n==cursor.startNodeIndex?
4544 cursor.startPos-1:val.length-1);i>=0;--i)
4551 else if(!(val[i] ==
' ' ||
4554 lastNonWhitespacePos = i;
4555 lastNonWhitespaceNodeIndex = n;
4563 console.log(
"lastNonWhitespacePos",lastNonWhitespacePos);
4564 console.log(
"lastNonWhitespaceNodeIndex",lastNonWhitespaceNodeIndex);
4566 if(lastNonWhitespacePos == cursor.startPos &&
4567 lastNonWhitespaceNodeIndex == cursor.startNodeIndex)
4570 lastNonWhitespacePos = lastPos;
4571 lastNonWhitespaceNodeIndex = lastNodeIndex;
4575 if(lastNonWhitespacePos == lastPos &&
4576 lastNonWhitespaceNodeIndex == lastNodeIndex)
4577 document.getElementById(
"textEditorBody" + forPrimary).scrollLeft = 0;
4579 cursor.startNodeIndex = lastNonWhitespaceNodeIndex
4580 cursor.startPos = lastNonWhitespacePos;
4584 cursor.endNodeIndex = cursor.startNodeIndex;
4585 cursor.endPos = cursor.startPos;
4589 CodeEditor.editor.setCursor(el,cursor,
true );
4593 else if(keyCode == 35)
4609 var wantNext =
false;
4610 var lastNonWhitespacePos = cursor.startPos;
4611 var lastNonWhitespaceNodeIndex = cursor.startNodeIndex;
4614 for(n=cursor.startNodeIndex; n<el.childNodes.length; ++n)
4616 node = el.childNodes[n];
4617 val = node.textContent;
4619 for(i=(n==cursor.startNodeIndex?
4620 cursor.startPos:0);i<val.length;++i)
4624 lastNonWhitespacePos = i;
4625 lastNonWhitespaceNodeIndex = n;
4633 else if(!(val[i] ==
' ' ||
4641 console.log(
"lastNonWhitespacePos",lastNonWhitespacePos);
4642 console.log(
"lastNonWhitespaceNodeIndex",lastNonWhitespaceNodeIndex);
4644 if(lastNonWhitespacePos == cursor.startPos &&
4645 lastNonWhitespaceNodeIndex == cursor.startNodeIndex)
4648 lastNonWhitespacePos = i;
4649 lastNonWhitespaceNodeIndex = n;
4652 cursor.endNodeIndex = lastNonWhitespaceNodeIndex
4653 cursor.endPos = lastNonWhitespacePos;
4657 cursor.startNodeIndex = cursor.endNodeIndex;
4658 cursor.startPos = cursor.endPos;
4662 CodeEditor.editor.setCursor(el,cursor,
true );
4673 e.stopPropagation();
4682 var gotoLineCursor = {};
4685 if(_lastPageUpDownLine == -1)
4687 var cursorWithLine = CodeEditor.editor.getLine(forPrimary);
4689 _startPageUpDownNodeIndex = cursorWithLine.startNodeIndex;
4690 _startPageUpDownPos = cursorWithLine.startPos;
4692 _startPageUpDownLine = cursorWithLine.line;
4693 _lastPageUpDownLine = _startPageUpDownLine;
4696 gotoLineCursor.startNodeIndex = _startPageUpDownNodeIndex;
4697 gotoLineCursor.startPos = _startPageUpDownPos;
4700 _lastPageUpDownLine -= N;
4701 gotoLineCursor.focusAtEnd = (_lastPageUpDownLine > _startPageUpDownLine);
4703 Debug.log(
"Page up to line " + _lastPageUpDownLine +
" dir=" +
4704 gotoLineCursor.focusAtEnd);
4706 _lastPageUpDownLine = CodeEditor.editor.gotoLine(forPrimary,_lastPageUpDownLine,
4707 e.shiftKey?gotoLineCursor:undefined);
4711 else if(keyCode == 34)
4715 e.stopPropagation();
4724 var gotoLineCursor = {};
4727 if(_lastPageUpDownLine == -1)
4729 var cursorWithLine = CodeEditor.editor.getLine(forPrimary);
4731 _startPageUpDownNodeIndex = cursorWithLine.startNodeIndex;
4732 _startPageUpDownPos = cursorWithLine.startPos;
4734 _startPageUpDownLine = cursorWithLine.line;
4735 _lastPageUpDownLine = _startPageUpDownLine;
4738 gotoLineCursor.startNodeIndex = _startPageUpDownNodeIndex;
4739 gotoLineCursor.startPos = _startPageUpDownPos;
4742 _lastPageUpDownLine += N;
4743 gotoLineCursor.focusAtEnd = (_lastPageUpDownLine > _startPageUpDownLine);
4745 Debug.log(
"Page down to line " + _lastPageUpDownLine +
" dir=" +
4746 gotoLineCursor.focusAtEnd);
4748 _lastPageUpDownLine = CodeEditor.editor.gotoLine(forPrimary,_lastPageUpDownLine,
4749 e.shiftKey?gotoLineCursor:undefined);
4753 else if(keyCode == 13)
4759 if(CodeEditor.editor.findAndReplaceLastButton[forPrimary] > 0)
4762 e.stopPropagation();
4764 Debug.log(
"Launch find and replace action " +
4765 CodeEditor.editor.findAndReplaceLastButton[forPrimary]);
4766 CodeEditor.editor.doFindAndReplaceAction(forPrimary,
4767 CodeEditor.editor.findAndReplaceLastButton[forPrimary]);
4771 else if(keyCode == 27)
4777 if(CodeEditor.editor.findAndReplaceLastButton[forPrimary] > 0)
4780 e.stopPropagation();
4783 CodeEditor.editor.displayFileHeader(forPrimary);
4796 CodeEditor.editor.saveFile(forPrimary,
true );
4800 else if(keyCode == 68)
4802 CodeEditor.editor.toggleDirectoryNav(forPrimary);
4806 else if(keyCode == 66)
4808 CodeEditor.editor.build();
4812 else if(keyCode == 70)
4814 CodeEditor.editor.showFindAndReplace(forPrimary);
4818 else if(keyCode == 73)
4820 CodeEditor.editor.autoIndent(forPrimary, cursor);
4824 else if(keyCode == 78)
4826 CodeEditor.editor.build(
true );
4830 else if(keyCode == 222 ||
4833 CodeEditor.editor.openFile(forPrimary,
4834 _filePath[forPrimary],
4835 _fileExtension[forPrimary],
4840 else if(keyCode == 50)
4842 CodeEditor.editor.toggleView();
4846 else if(keyCode == 85)
4848 CodeEditor.editor.undo(forPrimary, e.shiftKey );
4852 else if(keyCode == 76 ||
4855 DesktopContent.popUpVerification(
4856 "Goto line number: ",
4860 Debug.log(
"Going to line... " + line);
4861 CodeEditor.editor.gotoLine(forPrimary,line);
4874 else if(keyCode == 186 ||
4877 CodeEditor.editor.openRelatedFile(forPrimary);
4888 var rectangularTAB =
false;
4889 var blockCOMMENT =
false;
4900 rectangularTAB =
true;
4904 else if(keyCode == 191)
4906 blockCOMMENT =
true;
4917 if(keyCode == TABKEY || rectangularTAB ||
4920 _fileWasModified[forPrimary] =
true;
4921 CodeEditor.editor.updateLastSave(forPrimary);
4933 Debug.log(
"special key selected lines " + cursor.startNodeIndex +
" - " +
4934 cursor.endNodeIndex);
4941 Debug.log(
"Rectangular TAB");
4956 for(n=cursor.startNodeIndex;n>=0; --n)
4958 node = el.childNodes[n];
4959 val = node.textContent;
4961 for(i=(n==cursor.startNodeIndex?cursor.startPos-1:
4962 val.length-1); i>=0; --i)
4974 console.log(
"at leading newline - n",n,
"i",i);
4978 for(n; n<el.childNodes.length; ++n)
4980 node = el.childNodes[n];
4981 val = node.textContent;
4983 for(i;i<val.length;++i)
4986 if(n == cursor.startNodeIndex &&
4987 i == cursor.startPos)
4992 var prelength = val.length;
4996 if(i-1 >= 0 && val[i-1] ==
'\t')
4997 node.textContent = val.substr(0,i-1) + val.substr(i);
5001 node.textContent = val.substr(0,i) +
"\t" + val.substr(i);
5007 cursor.startPos += node.textContent.length - prelength;
5013 x += _TAB_SIZE - (x+_TAB_SIZE)%_TAB_SIZE;
5029 for(n=cursor.startNodeIndex; n<el.childNodes.length; ++n)
5031 node = el.childNodes[n];
5032 val = node.textContent;
5034 for(i=(n==cursor.startNodeIndex?cursor.startPos:
5035 0);i<val.length;++i)
5050 if(i-1 < val.length && val[i-1] ==
'\t')
5052 val = val.substr(0,i-1) + val.substr(i);
5053 node.textContent = val;
5058 val = val.substr(0,i) +
"\t" + val.substr(i);
5059 node.textContent = val;
5066 xcnt += _TAB_SIZE - (xcnt+_TAB_SIZE)%_TAB_SIZE;
5072 if(n == cursor.endNodeIndex)
5079 CodeEditor.editor.setCursor(el,cursor,
true );
5124 var specialStr =
'\t';
5127 if(_fileExtension[forPrimary][0] ==
'c' ||
5128 _fileExtension[forPrimary][0] ==
'C' ||
5129 _fileExtension[forPrimary][0] ==
'h' ||
5130 _fileExtension[forPrimary][0] ==
'H' ||
5131 _fileExtension[forPrimary][0] ==
'j')
5137 for(n=cursor.startNodeIndex; n>=0; --n)
5139 node = el.childNodes[n];
5140 val = node.textContent;
5142 for(i=(n==cursor.startNodeIndex?cursor.startPos-1:
5143 val.length-1); i>=0; --i)
5159 var prevCharIsNewLine =
false;
5160 var lookForNewLineIndex;
5162 for(; n<el.childNodes.length &&
5163 n <= cursor.endNodeIndex; ++n)
5165 node = el.childNodes[n];
5166 val = node.textContent;
5168 lookForNewLineIndex = 0;
5169 for(;i<val.length;++i)
5171 if(n == cursor.endNodeIndex && i >= cursor.endPos)
5178 if(val[i] ==
'\n' ||
5179 (i == 0 && prevCharIsNewLine))
5181 if(i == 0 && prevCharIsNewLine) --i;
5185 var didDelete =
false;
5186 if(i + specialStr.length < val.length &&
5190 (j=val.indexOf(specialStr,i+1)) == i+1 ||
5193 (k=val.indexOf(
'\n',i+1)) < 0 ||
5198 val.substr(i+1,j-(i+1)).trim().length == 0
5204 val = val.substr(0,j) +
5205 val.substr(j+specialStr.length);
5206 node.textContent = val;
5208 lookForNewLineIndex = j+specialStr.length;
5210 else if(specialStr ==
'\t')
5213 if((specialStr =
" ") &&
5214 i + specialStr.length < val.length &&
5215 val.indexOf(specialStr,i+1) == i+1)
5217 val = val.substr(0,i+1) +
5218 val.substr(i+1+specialStr.length);
5219 node.textContent = val;
5222 else if((specialStr =
" ") &&
5223 i + specialStr.length < val.length &&
5224 val.indexOf(specialStr,i+1) == i+1)
5226 val = val.substr(0,i+1) +
5227 val.substr(i+1+specialStr.length);
5228 node.textContent = val;
5231 else if((specialStr =
" ") &&
5232 i + specialStr.length < val.length &&
5233 val.indexOf(specialStr,i+1) == i+1)
5235 val = val.substr(0,i+1) +
5236 val.substr(i+1+specialStr.length);
5237 node.textContent = val;
5240 else if((specialStr =
" ") &&
5241 i + specialStr.length < val.length &&
5242 val.indexOf(specialStr,i+1) == i+1)
5244 val = val.substr(0,i+1) +
5245 val.substr(i+1+specialStr.length);
5246 node.textContent = val;
5257 if(n == cursor.startNodeIndex &&
5258 i < cursor.startPos)
5260 cursor.startPos -= specialStr.length;
5262 if(n == cursor.endNodeIndex &&
5265 cursor.endPos -= specialStr.length;
5270 if(n == cursor.endNodeIndex &&
5271 cursor.endPos >= val.length)
5273 ++cursor.endNodeIndex;
5292 val = val.substr(0,i+1) + specialStr + val.substr(i+1);
5293 node.textContent = val;
5296 if(i == -1 && prevCharIsNewLine) ++i;
5306 j = val.lastIndexOf(
'\n');
5307 if(j >= lookForNewLineIndex &&
5309 j == val[val.length-1] ||
5310 val.substr(j+1).trim().length == 0
5312 prevCharIsNewLine =
true;
5313 else if(j < 0 && prevCharIsNewLine &&
5314 val.trim().length == 0)
5315 prevCharIsNewLine =
true;
5317 prevCharIsNewLine =
false;
5320 prevCharIsNewLine = (val.length &&
5321 val[val.length-1] ==
'\n');
5325 CodeEditor.editor.setCursor(el,cursor,
true );
5355 else if(!blockCOMMENT)
5359 if(cursor.startNodeIndex !== undefined)
5364 i = cursor.startPos;
5365 node = el.childNodes[cursor.startNodeIndex];
5366 val = node.textContent;
5370 if(val[i-1] ==
'\t')
5372 node.textContent = val.substr(0,i-1) + val.substr(i);
5375 var range = document.createRange();
5376 range.setStart(node,i-1);
5377 range.setEnd(node,i-1);
5379 var selection = window.getSelection();
5380 selection.removeAllRanges();
5381 selection.addRange(range);
5391 Debug.log(
"No cursor for reverse tab.");
5394 document.execCommand(
'insertHTML',
false,
'	');
5400 else if(cursorSelection)
5402 Debug.log(
"cursorSelection handling for speed-up");
5412 console.log(
"cursorSelection char",keyCode,c);
5414 if(e.key.length > 1)
5416 if( keyCode != 46 &&
5423 e.stopPropagation();
5424 localInsertCharacter(c);
5430 if(localInsertCharacter(c))
5434 e.stopPropagation();
5444 this.updateLastSave =
function(forPrimary)
5446 forPrimary = forPrimary?1:0;
5448 var el = document.getElementById(
"textEditorLastSave" + forPrimary);
5451 Debug.log(
"updateLastSave() forPrimary=" + forPrimary);
5453 if(_fileWasModified[forPrimary])
5454 str +=
"<label style='color:red'>Unsaved changes!</label> ";
5456 str +=
"Unmodified. ";
5458 if(_fileLastSave[forPrimary])
5460 var now =
new Date();
5461 var d =
new Date(_fileLastSave[forPrimary]);
5462 var tstr = d.toLocaleTimeString();
5463 tstr = tstr.substring(0,tstr.lastIndexOf(
' ')) +
5464 (tstr[tstr.length-2]==
'A'?
"am":
"pm");
5466 var diff = ((now.getTime() - d.getTime())/1000)|0;
5470 diffStr =
"(just now) ";
5472 diffStr =
"(5 seconds ago) ";
5474 diffStr =
"(15 seconds ago) ";
5476 diffStr =
"(30 seconds ago) ";
5478 diffStr =
"(45 seconds ago) ";
5480 diffStr =
"(one minute ago) ";
5481 else if(diff < 15*60)
5482 diffStr =
"(" + ((diff/60)|0) +
" minutes ago) ";
5483 else if(diff < 20*60)
5484 diffStr =
"(15 minutes ago) ";
5485 else if(diff < 40*60)
5486 diffStr =
"(30 minutes ago) ";
5487 else if(diff < 50*60)
5488 diffStr =
"(45 minutes ago) ";
5489 else if(diff < 90*60)
5490 diffStr =
"(an hour ago) ";
5492 diffStr =
"(" + (Math.round(diff/60/60)) +
" hours ago) ";
5495 str +=
"Last save was " + diffStr + tstr;
5502 this.handleFileNameMouseMove =
function(forPrimary,doNotStartTimer)
5504 forPrimary = forPrimary?1:0;
5508 if(_fileNameEditing[forPrimary])
return;
5510 var el = document.getElementById(
"fileButtonContainerShowHide" + forPrimary);
5511 el.style.display =
"block";
5513 window.clearTimeout(_fileNameMouseMoveTimerHandle);
5515 if(doNotStartTimer)
return;
5517 _fileNameMouseMoveTimerHandle = window.setTimeout(
5520 el.style.display =
"none";
5528 this.startEditFileName =
function(forPrimary)
5530 forPrimary = forPrimary?1:0;
5532 if(_fileNameEditing[forPrimary])
return;
5533 _fileNameEditing[forPrimary] =
true;
5536 document.getElementById(
"fileButtonContainerShowHide" + forPrimary).style.display =
"none";
5539 console.log(
"startEditFileName " + forPrimary);
5541 var el = document.getElementById(
"fileNameDiv" + forPrimary);
5543 var keys = Object.keys(_fileHistoryStack);
5544 var initVal = keys[document.getElementById(
"fileNameHistorySelect" +
5545 forPrimary).value|0].trim();
5547 var _OK_CANCEL_DIALOG_STR =
"";
5549 _OK_CANCEL_DIALOG_STR +=
"<div title='' style='padding:5px;background-color:#eeeeee;border:1px solid #555555;position:relative;z-index:2000;" +
5550 "width:105px;height:20px;margin: 4px -122px -32px -120px; font-size: 16px; white-space:nowrap; text-align:center;'>";
5551 _OK_CANCEL_DIALOG_STR +=
"<a class='popUpOkCancel' onclick='" +
5552 "CodeEditor.editor.editCellOK(" + forPrimary +
5553 "); event.stopPropagation();' onmouseup='event.stopPropagation();' title='Accept Changes' style='color:green'>" +
5554 "<b style='color:green;font-size: 16px;'>OK</b></a> | " +
5555 "<a class='popUpOkCancel' onclick='" +
5556 "CodeEditor.editor.editCellCancel(" + forPrimary +
5557 "); event.stopPropagation();' onmouseup='event.stopPropagation();' title='Discard Changes' style='color:red'>" +
5558 "<b style='color:red;font-size: 16px;'>Cancel</b></a>";
5559 _OK_CANCEL_DIALOG_STR +=
"</div>";
5563 str += htmlOpen(
"input",
5566 "style":
"text-align:center;margin:-4px -2px -4px -1px;width:90%;" +
5567 " height:" + (el.offsetHeight>20?el.offsetHeight:20) +
"px",
5569 "onclick":
"event.stopPropagation();",
5578 str += _OK_CANCEL_DIALOG_STR;
5583 el = el.getElementsByTagName(
"input")[0];
5584 var startPos = initVal.lastIndexOf(
'/')+1;
5585 var endPos = initVal.lastIndexOf(
'.');
5586 if(endPos < 0) endPos = initVal.length;
5587 el.setSelectionRange(startPos, endPos);
5594 this.editCellOK =
function(forPrimary)
5596 forPrimary = forPrimary?1:0;
5598 var val = document.getElementById(
"fileNameDiv" + forPrimary).getElementsByTagName(
"input")[0].value;
5599 console.log(
"editCellOK " + forPrimary +
" = " + val);
5600 _fileNameEditing[forPrimary] =
false;
5602 var extPos = val.lastIndexOf(
'.');
5606 _filePath[forPrimary] = val.substr(0,extPos);
5607 _fileExtension[forPrimary] = extPos > 0?val.substr(extPos+1):
"";
5622 _fileWasModified[forPrimary] =
true;
5623 _fileLastSave[forPrimary] = 0;
5624 CodeEditor.editor.updateLastSave(forPrimary);
5635 _fileHistoryStack[_filePath[forPrimary] +
"." +
5636 _fileExtension[forPrimary]] = [
5637 _eel[forPrimary].textContent,
5639 _fileWasModified[forPrimary],
5640 _fileLastSave[forPrimary]];
5641 console.log(
"_fileHistoryStack",_fileHistoryStack);
5643 CodeEditor.editor.updateFileHistoryDropdowns();
5649 this.editCellCancel =
function(forPrimary)
5651 forPrimary = forPrimary?1:0;
5653 Debug.log(
"editCellCancel " + forPrimary);
5654 _fileNameEditing[forPrimary] =
false;
5657 CodeEditor.editor.updateFileHistoryDropdowns(forPrimary);
5666 this.updateFileHistoryDropdowns =
function(forPrimarySelect)
5668 Debug.log(
"updateFileHistoryDropdowns forPrimarySelect=" + forPrimarySelect);
5675 var keys = Object.keys(_fileHistoryStack);
5678 for(var forPrimary=0;forPrimary<2;++forPrimary)
5680 if(forPrimarySelect !== undefined &&
5681 forPrimarySelect != forPrimary)
continue;
5683 currentFile = _filePath[forPrimary] +
"." + _fileExtension[forPrimary];
5685 str += htmlOpen(
"select",
5687 "class":
"fileNameHistorySelect",
5688 "id":
"fileNameHistorySelect" + forPrimary,
5689 "style":
"width:100%;" +
5690 "text-align-last: center;",
5691 "title":
"The current file is\n" + currentFile,
5693 "CodeEditor.editor.handleFileNameHistorySelect(" +
5695 "onclick":
"CodeEditor.editor.stopUpdateHandling(event);",
5696 "onfocus":
"CodeEditor.editor.lastFileNameHistorySelectIndex = this.value;" +
5698 "onblur":
"this.value = CodeEditor.editor.lastFileNameHistorySelectIndex;",
5703 for(i=0;i<keys.length;++i)
5707 str +=
"<option value='" + i +
"' ";
5708 if(currentFile == keys[i])
5711 if(_fileHistoryStack[keys[i]][2])
5712 str +=
"*MODIFIED* ";
5721 el = document.getElementById(
"fileNameDiv" + forPrimary);
5726 Debug.log(
"Ignoring error since file forPrimary=" +
5727 forPrimary +
" is probably not opened: " +
5737 this.handleFileNameHistorySelect =
function(forPrimary)
5739 forPrimary = forPrimary?1:0;
5741 var selectedFileIndex = document.getElementById(
"fileNameHistorySelect" + forPrimary).value | 0;
5742 Debug.log(
"updateFileHistoryDropdowns " + forPrimary +
5743 "selected=" + selectedFileIndex);
5745 var keys = Object.keys(_fileHistoryStack);
5746 var selectedFileName = keys[selectedFileIndex];
5748 Debug.log(
"selectedFileName " + selectedFileName);
5754 var fileArr = selectedFileName.split(
'.');
5757 if(fileArr[0] == _filePath[forPrimary] &&
5758 fileArr[1] == _fileExtension[forPrimary])
5760 CodeEditor.editor.openFile(forPrimary,
5761 _filePath[forPrimary],
5762 _fileExtension[forPrimary],
5767 fileObj.path = fileArr[0];
5768 fileObj.extension = fileArr[1];
5769 fileObj.text = _fileHistoryStack[selectedFileName][0];
5770 fileObj.fileWasModified = _fileHistoryStack[selectedFileName][2];
5771 fileObj.fileLastSave = _fileHistoryStack[selectedFileName][3];
5773 console.log(
"fileObj",fileObj);
5775 CodeEditor.editor.handleFileContent(forPrimary,0,fileObj);
5782 this.showFindAndReplace =
function(forPrimary)
5784 forPrimary = forPrimary?1:0;
5785 _activePaneIsPrimary = forPrimary;
5787 Debug.log(
"showFindAndReplace forPrimary=" + forPrimary +
" activePane=" + _activePaneIsPrimary);
5789 CodeEditor.editor.findAndReplaceLastButton[forPrimary] = 1;
5792 var el = _eel[forPrimary];
5793 var cursor = _findAndReplaceCursorInContent[forPrimary] =
5794 CodeEditor.editor.getCursor(el);
5797 el = document.getElementById(
"textEditorHeader" + forPrimary);
5802 str +=
"<table style='margin-top: 2px;'>";
5806 str +=
"<tr><td style='text-align:right'>";
5809 str += htmlOpen(
"input",
5812 "id":
"findAndReplaceFind" + forPrimary,
5813 "style":
"text-align:left; width:90%;" +
5814 " height:" + (20) +
"px",
5815 "value": CodeEditor.editor.findAndReplaceFind[forPrimary],
5816 "onclick":
"event.stopPropagation();",
5817 "onchange":
"CodeEditor.editor.findAndReplaceFind[" +
5818 forPrimary +
"] = this.value;" +
5819 "CodeEditor.editor.showFindAndReplaceSelection(" +
5826 str += htmlOpen(
"select",
5828 "id":
"findAndReplaceScope" + forPrimary,
5829 "style":
"width:100%;" +
5830 "text-align-last: center;",
5831 "title":
"Choose the scope for Replace All",
5832 "onclick":
"event.stopPropagation();" ,
5833 "onchange":
"CodeEditor.editor.findAndReplaceScope[" +
5834 forPrimary +
"] = this.value;" +
5835 "CodeEditor.editor.showFindAndReplaceSelection(" +
5839 str +=
"<option value='0'>All Lines</option>";
5840 str +=
"<option value='1' " + (CodeEditor.editor.findAndReplaceScope[forPrimary] ==
5841 1?
"selected":
"") +
">Selected Lines</option>";
5847 str += htmlOpen(
"input",
5850 "id":
"findAndReplaceCaseSensitive" + forPrimary,
5851 "title":
"Toggle case sensitive search",
5852 "onclick":
"event.stopPropagation();",
5853 "style":
"margin-left:10px;",
5854 "onchange":
"CodeEditor.editor.findAndReplaceCaseSensitive[" +
5855 forPrimary +
"] = this.checked;" +
5856 "CodeEditor.editor.showFindAndReplaceSelection(" +
5862 "title":
"Toggle case sensitive search",
5863 "style":
"margin-left:5px;",
5864 "onclick":
"event.stopPropagation();" +
5865 "var el = document.getElementById(\"findAndReplaceCaseSensitive" +
5866 forPrimary +
"\"); el.checked = !el.checked;" +
5867 "CodeEditor.editor.findAndReplaceCaseSensitive[" +
5868 forPrimary +
"] = el.checked;" +
5869 "CodeEditor.editor.showFindAndReplaceSelection(" +
5873 "Case sensitive" ,
true
5876 str +=
"</td></tr>";
5879 str +=
"<tr><td style='text-align:right'>";
5880 str +=
"Replace with:";
5882 str += htmlOpen(
"input",
5885 "id":
"findAndReplaceReplace" + forPrimary,
5886 "style":
"text-align:left; width:90%;" +
5887 " height:" + (20) +
"px",
5888 "value": CodeEditor.editor.findAndReplaceReplace[forPrimary],
5889 "onclick":
"event.stopPropagation();",
5890 "onchange":
"CodeEditor.editor.findAndReplaceReplace[" +
5891 forPrimary +
"] = this.value; " +
5892 "CodeEditor.editor.showFindAndReplaceSelection(" +
5899 str += htmlOpen(
"select",
5901 "id":
"findAndReplaceDirection" + forPrimary,
5902 "style":
"width:100%;" +
5903 "text-align-last: center;",
5904 "title":
"Choose the search direction for the Find & Replace",
5905 "onclick":
"event.stopPropagation();",
5906 "onchange":
"CodeEditor.editor.findAndReplaceDirection[" +
5907 forPrimary +
"] = this.value;" +
5908 "CodeEditor.editor.showFindAndReplaceSelection(" +
5912 str +=
"<option value='0'>Search Forward</option>";
5913 str +=
"<option value='1' " + (CodeEditor.editor.findAndReplaceDirection[forPrimary] ==
5915 ">Search Backward</option>";
5921 str += htmlOpen(
"input",
5924 "id":
"findAndReplaceWholeWord" + forPrimary,
5925 "title":
"Toggle whole word search",
5926 "onclick":
"event.stopPropagation();",
5927 "style":
"margin-left:10px;",
5928 "onchange":
"CodeEditor.editor.findAndReplaceWholeWord[" +
5929 forPrimary +
"] = this.checked;" +
5930 "CodeEditor.editor.showFindAndReplaceSelection(" +
5936 "style":
"margin-left:5px;",
5937 "title":
"Toggle whole word search",
5938 "onclick":
"event.stopPropagation();" +
5939 "var el = document.getElementById(\"findAndReplaceWholeWord" +
5940 forPrimary +
"\"); el.checked = !el.checked;" +
5941 "CodeEditor.editor.findAndReplaceWholeWord[" +
5942 forPrimary +
"] = el.checked;" +
5943 "CodeEditor.editor.showFindAndReplaceSelection(" +
5949 str +=
"</td></tr>";
5953 str +=
"<tr><td colspan='4' style='text-align:center'>";
5954 str += htmlOpen(
"div",
5956 "id":
"findAndReplaceWrapped" + forPrimary,
5957 "style":
"text-align:right; margin: 4px; width:115px;" +
5958 "color: red; float: left;",
5960 str +=
"<div style='float:left;'>";
5961 str += htmlOpen(
"input",
5966 "style":
"text-align:center; margin: 4px;" ,
5967 "onclick":
"event.stopPropagation();" +
5968 "CodeEditor.editor.doFindAndReplaceAction(" + forPrimary +
",1)",
5971 str += htmlOpen(
"input",
5976 "style":
"text-align:center; margin: 4px;" ,
5977 "onclick":
"event.stopPropagation();" +
5978 "CodeEditor.editor.doFindAndReplaceAction(" + forPrimary +
",2)",
5981 str += htmlOpen(
"input",
5984 "value":
"Replace & Find",
5986 "style":
"text-align:center; margin: 4px;" ,
5987 "onclick":
"event.stopPropagation();" +
5988 "CodeEditor.editor.doFindAndReplaceAction(" + forPrimary +
",3)",
5991 str += htmlOpen(
"input",
5994 "value":
"Replace All",
5996 "style":
"text-align:center; margin: 4px;" ,
5997 "onclick":
"event.stopPropagation();" +
5998 "CodeEditor.editor.doFindAndReplaceAction(" + forPrimary +
",4)",
6001 str += htmlOpen(
"input",
6005 "title":
"Close find and replace controls.",
6006 "style":
"text-align:center; margin: 4px;" ,
6008 "onclick":
"event.stopPropagation();" +
6009 "CodeEditor.editor.displayFileHeader(" + forPrimary +
")",
6013 str +=
"</td></tr>";
6020 el = document.getElementById(
"findAndReplaceFind" + forPrimary);
6021 el.setSelectionRange(0, el.value.length);
6024 el = document.getElementById(
"findAndReplaceCaseSensitive" + forPrimary);
6025 el.checked = CodeEditor.editor.findAndReplaceCaseSensitive[forPrimary];
6027 el = document.getElementById(
"findAndReplaceWholeWord" + forPrimary);
6028 el.checked = CodeEditor.editor.findAndReplaceWholeWord[forPrimary];
6035 this.showFindAndReplaceSelection =
function(forPrimary)
6037 forPrimary = forPrimary?1:0;
6038 Debug.log(
"showFindAndReplaceSelection forPrimary=" + forPrimary);
6040 var el = _eel[forPrimary];
6041 var cursor = CodeEditor.editor.getCursor(el);
6043 if(cursor.startPosInContent !== undefined)
6044 CodeEditor.editor.setCursor(el,
6048 CodeEditor.editor.findAndReplaceLastButton[forPrimary] > 0 &&
6049 _findAndReplaceCursorInContent[forPrimary] !== undefined)
6050 CodeEditor.editor.setCursor(el,
6051 _findAndReplaceCursorInContent[forPrimary],
6064 this.doFindAndReplaceAction =
function(forPrimary,action)
6066 forPrimary = forPrimary?1:0;
6067 action = action | 0;
6069 CodeEditor.editor.findAndReplaceLastButton[forPrimary] = action;
6071 var find = document.getElementById(
"findAndReplaceFind" + forPrimary).value;
6072 var originalFind = find;
6073 if(!find || find ==
"")
6075 Debug.log(
"Illegal empty string to find.", Debug.HIGH_PRIORITY);
6078 var replace = CodeEditor.editor.findAndReplaceReplace[forPrimary];
6079 var scope = CodeEditor.editor.findAndReplaceScope[forPrimary]|0;
6080 var direction = CodeEditor.editor.findAndReplaceDirection[forPrimary]|0;
6083 var caseSensitive = CodeEditor.editor.findAndReplaceCaseSensitive[forPrimary]?1:0;
6084 var wholeWord = CodeEditor.editor.findAndReplaceWholeWord[forPrimary]?1:0;
6086 Debug.log(
"doFindAndReplaceAction forPrimary=" + forPrimary +
6087 " action=" + action +
6089 " replace=" + replace +
6091 " direction=" + direction +
6092 " caseSensitive=" + caseSensitive +
6093 " wholeWord=" + wholeWord);
6104 var el = _eel[forPrimary];
6105 var originalText = el.textContent;
6108 text = originalText;
6111 text = originalText.toLowerCase();
6112 find = find.toLowerCase();
6115 var i = direction?text.length:-1;
6116 var j = text.length-1;
6118 var cursor = CodeEditor.editor.getCursor(el);
6121 if(cursor.startPosInContent !== undefined &&
6123 document.getElementById(
"findAndReplaceWrapped" + forPrimary).textContent ==
""))
6124 i = cursor.startPosInContent;
6125 else if(_findAndReplaceCursorInContent[forPrimary] !== undefined &&
6126 _findAndReplaceCursorInContent[forPrimary].startPosInContent !== undefined &&
6127 _findAndReplaceCursorInContent[forPrimary].startPosInContent >= 0 &&
6129 document.getElementById(
"findAndReplaceWrapped" + forPrimary).textContent ==
""))
6131 i = _findAndReplaceCursorInContent[forPrimary].startPosInContent;
6134 CodeEditor.editor.setCursor(el,
6135 _findAndReplaceCursorInContent[forPrimary],
6140 document.getElementById(
"findAndReplaceWrapped" + forPrimary).innerHTML =
"";
6142 Debug.log(
"Starting position: " + i);
6146 if(cursor.endPosInContent !== undefined)
6147 j = cursor.endPosInContent;
6148 else if(_findAndReplaceCursorInContent[forPrimary] !== undefined &&
6149 _findAndReplaceCursorInContent[forPrimary].endPosInContent != undefined &&
6150 _findAndReplaceCursorInContent[forPrimary].endPosInContent >= 0)
6151 j = _findAndReplaceCursorInContent[forPrimary].endPosInContent;
6153 Debug.log(
"Ending position: " + j);
6155 else if(action == 4)
6158 var replaceCount = 0;
6171 if(i > 0 && i + find.length <= text.length)
6177 Debug.log(
"Replacing");
6182 originalText.substr(0,i) +
6184 originalText.substr(i+find.length);
6188 text = originalText;
6190 text = originalText.toLowerCase();
6197 Debug.log(
"Unrecognized action! " + action, Debug.HIGH_PRIORITY);
6211 i = text.indexOf(find,i+1);
6212 else if(direction == 1)
6213 i = text.lastIndexOf(find,i-1);
6219 (text[i-1] >=
'a' && text[i-1] <=
'z') ||
6220 (text[i-1] >=
'A' && text[i-1] <=
'Z') ||
6221 (text[i-1] >=
'0' && text[i-1] <=
'9') ||
6228 else if(i>0 && i+find.length<text.length && (
6229 (text[i+find.length] >=
'a' && text[i+find.length] <=
'z') ||
6230 (text[i+find.length] >=
'A' && text[i+find.length] <=
'Z') ||
6231 (text[i+find.length] >=
'0' && text[i+find.length] <=
'9') ||
6232 text[i+find.length] ==
'_'
6252 if(i + find.length < j)
6260 document.getElementById(
"findAndReplaceWrapped" + forPrimary).innerHTML =
"Reached end";
6270 Debug.log(
"Unrecognized action! " + action, Debug.HIGH_PRIORITY);
6288 el.textContent = originalText;
6289 CodeEditor.editor.updateDecorations(forPrimary);
6294 _findAndReplaceCursorInContent[forPrimary] =
6295 CodeEditor.editor.createCursorFromContentPosition(el,
6296 i, i + find.length);
6297 CodeEditor.editor.setCursor(
6299 _findAndReplaceCursorInContent[forPrimary],
6308 _findAndReplaceCursorInContent[forPrimary] =
6309 CodeEditor.editor.createCursorFromContentPosition(el,
6311 CodeEditor.editor.setCursor(
6313 _findAndReplaceCursorInContent[forPrimary],
6318 Debug.log(
"Unrecognized action! " + action, Debug.HIGH_PRIORITY);
6326 document.getElementById(
"findAndReplaceWrapped" + forPrimary).innerHTML =
6327 replaceCount +
" Replaced";
6334 this.displayFileHeader =
function(forPrimary)
6336 forPrimary = forPrimary?1:0;
6338 var forceDisplayComplete =
false;
6339 if(CodeEditor.editor.findAndReplaceLastButton[forPrimary] != -1)
6341 CodeEditor.editor.findAndReplaceLastButton[forPrimary] = -1;
6342 forceDisplayComplete =
true;
6345 Debug.log(
"displayFileHeader forPrimary=" + forPrimary);
6348 var el = document.getElementById(
"textEditorHeader" + forPrimary);
6351 var path = _filePath[forPrimary];
6352 var extension = _fileExtension[forPrimary];
6359 str += htmlOpen(
"div",
6362 "CodeEditor.editor.handleFileNameMouseMove(" + forPrimary +
");",
6367 str += htmlOpen(
"div",
6369 "class":
"fileButtonContainer",
6370 "id":
"fileButtonContainer" + forPrimary,
6373 str += htmlOpen(
"div",
6375 "class":
"fileButtonContainerShowHide",
6376 "id":
"fileButtonContainerShowHide" + forPrimary,
6378 "event.stopPropagation(); " +
6379 "CodeEditor.editor.handleFileNameMouseMove(" + forPrimary +
6380 ",1 /*doNotStartTimer*/);",
6383 str += htmlOpen(
"div",
6385 "class":
"fileButton",
6386 "id":
"fileRenameButton" + forPrimary,
6387 "title":
"Change the filename\n" + path +
"." + extension,
6389 "event.stopPropagation(); " +
6390 "CodeEditor.editor.startEditFileName(" + forPrimary +
");",
6392 str += htmlOpen(
"div",
6394 "class":
"fileButton",
6395 "id":
"fileDownloadButton" + forPrimary,
6396 "title":
"Download the file content from\n" + path +
"." + extension,
6398 "event.stopPropagation(); " +
6399 "CodeEditor.editor.download(" + forPrimary +
");",
6402 "<div class='fileDownloadButtonBgChild' style='display: block; margin-left: 0px; margin-top: 1px; height:7px; width: 6px; background-color: rgb(202, 204, 210);'></div>" +
6403 "<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>" +
6404 "<div class='fileDownloadButtonBgChild' style='position: relative; top: 2px; width: 12px; height: 2px; display: block; background-color: rgb(202, 204, 210);'></div>"
6406 str += htmlOpen(
"div",
6408 "class":
"fileButton",
6409 "id":
"fileUploadButton" + forPrimary,
6410 "title":
"Upload file content to\n" + path +
"." + extension,
6412 "event.stopPropagation(); " +
6413 "CodeEditor.editor.upload(" + forPrimary +
");",
6416 "<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>" +
6417 "<div class='fileDownloadButtonBgChild' style='display: block; margin-left: 0px; height:7px; width: 6px; background-color: rgb(202, 204, 210);'></div>" +
6418 "<div class='fileDownloadButtonBgChild' style='position: relative; top: 3px; width: 12px; height: 2px; display: block; background-color: rgb(202, 204, 210);'></div>"
6420 str += htmlOpen(
"div",
6422 "class":
"fileButton fileUndoButton",
6423 "id":
"fileUndoButton" + forPrimary,
6424 "title":
"Undo to rewind to last recorded checkpoint for\n" + path +
"." + extension,
6425 "style":
"color: rgb(202, 204, 210);" +
6426 "padding: 0 5px 0;" +
6427 "font-size: 17px;" +
6428 "font-weight: bold;",
6430 "event.stopPropagation(); " +
6431 "CodeEditor.editor.undo(" + forPrimary +
");",
6436 str += htmlOpen(
"div",
6438 "class":
"fileButton fileUndoButton",
6439 "id":
"fileRedoButton" + forPrimary,
6440 "title":
"Redo to fast-forward to last recorded checkpoint for\n" + path +
"." + extension,
6441 "style":
"color: rgb(202, 204, 210);" +
6442 "padding: 0 5px 0;" +
6443 "font-size: 17px;" +
6444 "font-weight: bold;",
6446 "event.stopPropagation(); " +
6447 "CodeEditor.editor.undo(" + forPrimary +
",1 /*redo*/);",
6453 str += htmlOpen(
"div",
6455 "class":
"fileButton openRelatedFileButton",
6456 "id":
"openRelatedFileButton" + forPrimary,
6457 "title":
"Open related file in other pane for\n" + path +
"." + extension,
6458 "style":
"color: rgb(202, 204, 210);" +
6459 "padding: 0 5px 0;" +
6460 "font-size: 17px;" +
6461 "font-weight: bold;",
6463 "event.stopPropagation(); " +
6464 "CodeEditor.editor.openRelatedFile(" + forPrimary +
6465 ", true /*inOtherPane*/);",
6476 str += htmlClearDiv();
6479 str +=
"<table><tr><td>";
6481 str += htmlOpen(
"a",
6483 "title":
"Open file in a new browser tab: \n" +
6484 "srcs" + path +
"." + extension,
6485 "onclick":
"DesktopContent.openNewBrowserTab(" +
6486 "\"Code Editor\",\"\"," +
6487 "\"/WebPath/html/CodeEditor.html?urn=" +
6488 DesktopContent._localUrnLid +
"&" +
6489 "startFilePrimary=" +
6490 path +
"." + extension +
"\",0 /*unique*/);' ",
6492 "<img class='dirNavFileNewWindowImgNewWindow' " +
6493 "src='/WebPath/images/windowContentImages/CodeEditor-openInNewWindow.png'>"
6497 str += htmlOpen(
"a",
6499 "title":
"Open file in the other editor pane of the split-view: \n" +
6500 "srcs" + path +
"." + extension,
6501 "onclick":
"CodeEditor.editor.openFile(" +
6502 (!forPrimary) +
",\"" +
6507 "<img class='dirNavFileNewWindowImgNewPane' " +
6508 "src='/WebPath/images/windowContentImages/CodeEditor-openInOtherPane.png'>"
6513 str += htmlOpen(
"div",
6515 "class":
"fileNameDiv",
6516 "id":
"fileNameDiv" + forPrimary,
6517 "style":
"margin: 0 5px 0 5px",
6519 str +=
"<a onclick='CodeEditor.editor.openFile(" + forPrimary +
6520 ",\"" + path +
"\",\"" + extension +
"\",true /*doConfirm*/);' " +
6521 "title='Click to reload \n" + path +
"." + extension +
"' " +
6523 path +
"." + extension +
"</a>";
6526 str +=
"</td></tr></table>";
6530 str += htmlClearDiv();
6533 str +=
"<div class='textEditorLastSave' id='textEditorLastSave" +
6534 forPrimary +
"'>Unmodified</div>";
6536 str += htmlClearDiv();
6538 str +=
"<div class='textEditorOutline' id='textEditorOutline" +
6539 forPrimary +
"'>Outline:</div>";
6543 CodeEditor.editor.updateDecorations(forPrimary,forceDisplayComplete);
6544 CodeEditor.editor.updateFileHistoryDropdowns();
6554 this.updateFileSnapshot =
function(forPrimary,textObj , ignoreTimeDelta)
6556 forPrimary = forPrimary?1:0;
6558 Debug.log(
"updateFileSnapshot forPrimary=" + forPrimary);
6561 var addSnapshot =
false;
6563 if(_undoStackLatestIndex[forPrimary] != -1)
6567 if((ignoreTimeDelta ||
6568 2*1000 < textObj.time - _undoStack[forPrimary][_undoStackLatestIndex[forPrimary]][1]) &&
6569 _undoStack[forPrimary][_undoStackLatestIndex[forPrimary]][0] != textObj.text)
6578 ++_undoStackLatestIndex[forPrimary];
6579 if(_undoStackLatestIndex[forPrimary] >= _undoStack_MAX_SIZE)
6580 _undoStackLatestIndex[forPrimary] = 0;
6582 _undoStack[forPrimary][_undoStackLatestIndex[forPrimary]] =
6586 console.log(
"snapshot added to stack",_undoStack[forPrimary]);
6594 _fileHistoryStack[_filePath[forPrimary] +
"." +
6595 _fileExtension[forPrimary]] = [
6598 _fileWasModified[forPrimary],
6599 _fileLastSave[forPrimary]];
6600 console.log(
"_fileHistoryStack",_fileHistoryStack);
6602 CodeEditor.editor.updateFileHistoryDropdowns();
6612 this.startUpdateHandling =
function(forPrimary)
6614 _updateHandlerTargetPane[forPrimary] =
true;
6616 window.clearTimeout(_updateTimerHandle);
6617 _updateTimerHandle = window.setTimeout(
6618 CodeEditor.editor.updateTimeoutHandler,
6619 _UPDATE_DECOR_TIMEOUT );
6626 this.stopUpdateHandling =
function(event)
6628 if(event)
event.stopPropagation();
6629 window.clearTimeout(_updateTimerHandle);
6635 this.updateTimeoutHandler =
function()
6637 if(_updateHandlerTargetPane[0])
6639 CodeEditor.editor.updateDecorations(0 );
6640 _updateHandlerTargetPane[0] =
false;
6642 if(_updateHandlerTargetPane[1])
6644 CodeEditor.editor.updateDecorations(1 );
6645 _updateHandlerTargetPane[1] =
false;
6652 this.doubleClickHandler =
function(forPrimary)
6654 forPrimary = forPrimary?1:0;
6656 Debug.log(
"doubleClickHandler forPrimary=" + forPrimary);
6662 var el = _eel[forPrimary];
6663 var cursor = CodeEditor.editor.getCursor(el);
6665 if(!cursor || cursor.startNodeIndex === undefined)
6668 var n = cursor.startNodeIndex;
6669 var c = el.childNodes[n].textContent[
6674 if(c !=
'{' && c !=
'}')
6676 if(cursor.startPos == 0)
6682 }
while(n >= 0 && el.childNodes[n].textContent.length);
6685 c = el.childNodes[n].textContent[
6686 el.childNodes[n].textContent.length-1];
6689 c = el.childNodes[n].textContent[
6696 Debug.log(
"character before cursor " + c);
6698 if(c !=
'{' && c !=
'}')
return;
6702 var foundDoubleQuote =
false;
6703 var foundSingleQuote =
false;
6704 var foundComment =
false;
6709 cursor.endNodeIndex = -1;
6716 var openCountSave = openCount;
6717 var prelimFound =
false;
6721 node = el.childNodes[n];
6722 val = node.textContent;
6723 for(i=(n==cursor.startNodeIndex?cursor.startPos-1:
6724 val.length-1); i>=0; --i)
6726 if(cursor.endNodeIndex == -1)
6728 cursor.endNodeIndex = n;
6734 foundSingleQuote =
false;
6735 foundDoubleQuote =
false;
6736 openCountSave = openCount;
6740 Debug.log(
"confirmed found open count match ni " + n +
" " + i);
6746 if(!foundSingleQuote && val[i] ==
'"')
6747 foundDoubleQuote = !foundDoubleQuote;
6748 else if(!foundDoubleQuote && val[i] ==
"'")
6749 foundSingleQuote = !foundSingleQuote;
6750 else if(val[i]==
'/' && i-1 >= 0 &&
6754 openCount = openCountSave;
6756 prelimFound =
false;
6762 if(foundDoubleQuote || foundSingleQuote ||
6768 else if(val[i] ==
'{')
6774 Debug.log(
"found open count match ni " + n +
" " + i);
6781 cursor.startNodeIndex = n;
6782 cursor.startPos = i;
6793 i = cursor.startPos;
6794 for(n=cursor.startNodeIndex;n<el.childNodes.length; ++n)
6796 node = el.childNodes[n];
6797 val = node.textContent;
6799 for(; i<val.length; ++i)
6803 foundSingleQuote =
false;
6804 foundDoubleQuote =
false;
6805 foundComment =
false;
6811 if(!foundSingleQuote && val[i] ==
'"')
6812 foundDoubleQuote = !foundDoubleQuote;
6813 else if(!foundDoubleQuote && val[i] ==
"'")
6814 foundSingleQuote = !foundSingleQuote;
6815 else if(val[i]==
'/' && i+1 < val.length &&
6818 foundComment =
true;
6822 if(foundDoubleQuote || foundSingleQuote)
6827 else if(val[i] ==
'}')
6833 Debug.log(
"found open count match ni " + n +
" " + i);
6838 cursor.endNodeIndex = n;
6850 CodeEditor.editor.setCursor(el,cursor);
6857 this.download =
function(forPrimary)
6859 forPrimary = forPrimary?1:0;
6861 Debug.log(
"download forPrimary=" + forPrimary);
6863 var dataStr =
"data:text/plain;charset=utf-8," +
6864 encodeURIComponent(_eel[forPrimary].textContent);
6866 var filename = _filePath[forPrimary];
6867 var i = filename.lastIndexOf(
'/');
6869 filename = filename.substr(i+1);
6870 filename +=
"." + _fileExtension[forPrimary];
6872 Debug.log(
"Downloading to filename " + filename);
6874 var link = document.createElement(
"a");
6875 link.setAttribute(
"href", dataStr);
6876 link.setAttribute(
"style",
"display:none");
6877 link.setAttribute(
"download", filename);
6878 document.body.appendChild(link);
6882 link.parentNode.removeChild(link);
6888 this.upload =
function(forPrimary)
6890 forPrimary = forPrimary?1:0;
6892 Debug.log(
"upload forPrimary=" + forPrimary);
6894 _fileUploadString =
"";
6898 var el = document.getElementById(
"popUpDialog");
6901 el = document.createElement(
"div");
6902 el.setAttribute(
"id",
"popUpDialog");
6904 el.style.display =
"none";
6909 DesktopContent.setPopUpPosition(el,w ,h );
6911 var str =
"<a id='" +
6913 "-header' onclick='var el = document.getElementById(" +
6914 "\"popUpDialog\"); if(el) el.parentNode.removeChild(el); return false;'>Cancel</a><br><br>";
6916 str +=
"<div id='popUpDialog-div'>";
6918 str +=
"Please choose the file to upload which has the text content to place in the open source file:<br><br>" +
6919 _filePath[forPrimary] +
"." + _fileExtension[forPrimary] +
6924 str +=
"<input type='file' id='popUpDialog-fileUpload' " +
6926 for(var i=0;i<_ALLOWED_FILE_EXTENSIONS.length;++i)
6927 str += (i?
", ":
"") +
"." + _ALLOWED_FILE_EXTENSIONS[i];
6928 str +=
"' enctype='multipart/form-data' />";
6931 var onmouseupJS =
"";
6932 onmouseupJS +=
"document.getElementById(\"popUpDialog-submitButton\").disabled = true;";
6933 onmouseupJS +=
"CodeEditor.editor.uploadTextFromFile(" + forPrimary +
");";
6935 str +=
"<input id='popUpDialog-submitButton' disabled type='button' onmouseup='" +
6936 onmouseupJS +
"' " +
6937 "value='Upload File' title='" +
6938 "Upload the chosen file text content to\n" +
6939 _filePath[forPrimary] +
"." + _fileExtension[forPrimary] +
6943 document.body.appendChild(el);
6944 el.style.display =
"block";
6946 document.getElementById(
'popUpDialog-fileUpload').addEventListener(
6947 'change',
function(evt) {
6948 var files = evt.target.files;
6949 var file = files[0];
6950 var reader =
new FileReader();
6951 reader.onload =
function() {
6953 _fileUploadString = this.result;
6954 Debug.log(
"_fileUploadString = " + _fileUploadString);
6955 document.getElementById(
'popUpDialog-submitButton').disabled =
false;
6957 reader.readAsText(file);
6963 this.uploadTextFromFile =
function(forPrimary)
6965 forPrimary = forPrimary?1:0;
6967 Debug.log(
"uploadTextFromFile forPrimary=" + forPrimary);
6970 document.getElementById(
'popUpDialog-submitButton').disabled =
false;
6972 Debug.log(
"uploadTextFromFile _fileUploadString = " + _fileUploadString);
6976 DesktopContent.showLoading(
function()
6982 _fileUploadString = _fileUploadString.replace(
new RegExp(
6983 String.fromCharCode(160),
'g'),
' ');
6984 _fileUploadString =
"hi";
6985 var el = _eel[forPrimary];
6986 el.textContent = _fileUploadString;
6987 CodeEditor.editor.displayFileHeader(forPrimary);
6991 Debug.log(
"There was an error uploading the text: " + e,
6992 Debug.HIGH_PRIORITY);
6995 Debug.log(
"Source upload complete! (You can use undo to go back) ",
6996 Debug.INFO_PRIORITY);
6999 var el = document.getElementById(
"popUpDialog");
7000 if(el) el.parentNode.removeChild(el);