// Get any elem by ID var get = function(elem) { return top.document.getElementById(elem); }; // Main ICEcoder object var ICEcoder = { // ============== // INIT // ============== // Define settings filesW: 250, // Width of files pane minFilesW: 14, // Min width of files pane maxFilesW: 250, // Max width of files pane selectedTab: 0, // The tab that's currently selected savedPoints: [], // Ints array to indicate save points for docs canSwitchTabs: true, // Stops switching of tabs when trying to close openFiles: [], // Array of open file URLs openFileMDTs: [], // Array of open file modification datetimes cMInstances: [], // List of CodeMirror instance no's nextcMInstance: 1, // Next available CodeMirror instance no selectedFiles: [], // Array of selected files findMode: false, // States if we're in find/replace mode lockedNav: true, // Nav is locked or not htmlTagArray: [], // Array storing the nest of tags mouseDown: false, // If the mouse is down draggingFilesW: false, // If we're dragging the file manager width draggingTab: false, // If we're dragging a tab draggingWithKey: false, // The key that's down while dragging, false if no key tabLeftPos: [], // Array of left positions of tabs inside content area tabBGcurrent: '#141414', // BG of current tab tabBGselected: '#49d', // BG of selected tab tabBGopen: '#c3c3c3', // BG of open tab tabBGnormal: 'transparent', // BG of normal tab tabFGcurrent: '#fff', // FG of selected tab tabFGselected: '#fff', // FG of selected tab tabFGopenFile: '#000', // FG of open file tabFGnormalFile: '#eee', // FG of normal file tabFGnormalTab: '#888', // FG of normal tab serverQueueItems: [], // Array of URLs to call in order previewWindow: false, // Target variable for the preview window pluginIntervalRefs: [], // Array of plugin interval refs overPopup: false, // Indicates if we're over a popup or not cmdKey: false, // Tracking apple Command key up/down state fmReady: false, // Indicates if the file manager is ready for action bugReportStatus: "off", // Values of: off, error, ok, bugs bugReportPath: "", // Bug report file path bugFilesSizesSeen: [], // Array of last seen sizes of bug files bugFilesSizesActual: [], // Array of actual sizes of bug files githubDiff: false, // Toggle for viewing GitHub/FM diff view githubAuthTokenSet: false, // Has the user set their GitHub token yet ready: false, // Indicates if ICEcoder is ready for action // Set our aliases initAliases: function() { var aliasArray = ["header","files", "fileOptions", "optionsFile", "optionsEdit", "optionsRemote", "optionsHelp", "filesFrame","editor","tabsBar","findBar","content","footer","nestValid","nestDisplay","charDisplay","byteDisplay"]; // Create our ID aliases for (var i=0;i ICEcoder.minFilesW+1 ? ICEcoder.filesW -= Math.ceil((ICEcoder.filesW-ICEcoder.minFilesW)/2) : ICEcoder.filesW = ICEcoder.minFilesW; } if ((expandContract=="expand" && ICEcoder.filesW == ICEcoder.maxFilesW)||(expandContract=="contract" && ICEcoder.filesW == ICEcoder.minFilesW)) { clearInterval(ICEcoder.changeFilesInt); } // Redo the layout to match ICEcoder.setLayout(); }, // Can click-drag file manager width? canResizeFilesW: function() { // If we have the cursor set we must be able! if (top.ICEcoder.ready && top.document.body.style.cursor == "w-resize") { // If our mouse is down and we're within a 250-400px range if (top.ICEcoder.mouseDown) { top.ICEcoder.filesW = top.ICEcoder.maxFilesW = top.ICEcoder.mouseX >=250 && top.ICEcoder.mouseX <= 400 ? top.ICEcoder.mouseX : top.ICEcoder.mouseX <250 ? 250 : 400; // Set various widths based on the new width top.ICEcoder.files.style.width = top.ICEcoder.filesFrame.style.width = top.ICEcoder.filesW + "px"; top.ICEcoder.setLayout(); top.ICEcoder.draggingFilesW = true; } } else { top.ICEcoder.draggingFilesW = false; } }, // Lock & unlock the file manager navigation on demand lockUnlockNav: function() { var lockIcon; lockIcon = top.filesFrame.contentWindow.document.getElementById('fmLock'); ICEcoder.lockedNav = !ICEcoder.lockedNav; lockIcon.style.backgroundPosition = ICEcoder.lockedNav ? "0 0" : "-16px 0"; }, // Show/hide the plugins on demand showHidePlugins: function(showHide) { get('plugins').style.width = showHide=="show" ? '55px' : '3px'; get('plugins').style.background = showHide=="show" ? '#333' : 'transparent'; if (showHide=="show") { ICEcoder.changeFilesW('expand'); } }, // ============== // EDITOR // ============== // Clean up our loaded code contentCleanUp: function() { var cM, content; // Replace any temp /textarea value cM = ICEcoder.getcMInstance(); content = cM.getValue(); content = content.replace(//g,'<\/textarea>'); // Then set the content in the editor & clear the history cM.setValue(content); cM.clearHistory(); top.ICEcoder.savedPoints[top.ICEcoder.selectedTab-1] = cM.changeGeneration(); }, // Undo last change undo: function() { var cM; cM = ICEcoder.getcMInstance(); cM.undo(); }, // Redo change redo: function() { var cM; cM = ICEcoder.getcMInstance(); cM.redo(); }, // Indent more/less indent: function(moreLess) { var cM; cM = ICEcoder.getcMInstance(); if (moreLess=="more") { top.ICEcoder.content.contentWindow.CodeMirror.commands.indentMore(cM); } else { top.ICEcoder.content.contentWindow.CodeMirror.commands.indentLess(cM); } }, // Move current line up/down moveLines: function(dir) { var cM, lineStart, lineEnd, swapLineNo, swapLine; cM = top.ICEcoder.getcMInstance(); // Get start & end lines plus the line we'll swap with lineStart = cM.getCursor('start'); lineEnd = cM.getCursor('end'); if (dir=="up" && lineStart.line>0) {swapLineNo = lineStart.line-1} if (dir=="down" && lineEnd.line=lineStart.line; i--) { cM.replaceRange(cM.getLine(i),{line:i+1,ch:0},{line:i+1,ch:1000000}); } } // Now swap our final line with the swap line to complete the move cM.replaceRange(swapLine,{line: dir=="up" ? lineEnd.line : lineStart.line, ch: 0},{line: dir=="up" ? lineEnd.line : lineStart.line, ch:1000000}); // Finally set the moved selection cM.setSelection( {line: lineStart.line+(dir=="up" ? -1 : 1), ch: lineStart.ch}, {line: lineEnd.line+(dir=="up" ? -1 : 1), ch: lineEnd.ch} ); }); } }, // Highlight specified line highlightLine: function(line) { var cM; cM = top.ICEcoder.getcMInstance(); cM.setSelection({line:line,ch:0}, {line:line,ch:cM.lineInfo(line).text.length}); }, // Focus the editor focus: function() { var cM; if (!(/iPhone|iPad|iPod/i.test(navigator.userAgent))) { cM = top.ICEcoder.getcMInstance(); if (cM) { cM.focus(); } } }, // Go to a specific line number goToLine: function(lineNo) { var cM; cM = ICEcoder.getcMInstance(); cM.setCursor(lineNo ? lineNo-1 : top.get('goToLineNo').value-1); top.ICEcoder.focus(); return false; }, // Comment/uncomment line or selected range on keypress lineCommentToggle: function() { var cM, cursorPos, linePos, lineContent, lCLen, adjustCursor; cM = ICEcoder.getcMInstance(); cursorPos = cM.getCursor().ch; linePos = cM.getCursor().line; lineContent = cM.getLine(linePos); lCLen = lineContent.length; adjustCursor = 2; ICEcoder.lineCommentToggleSub(cM, cursorPos, linePos, lineContent, lCLen, adjustCursor); }, // Highlight or hide block upon roll over/out of nest positions highlightBlock: function(nestPos,hide) { var cM, searchPos, cursor, cursorTemp, startPos, endPos; cM = top.ICEcoder.getcMInstance(); // Hiding the block if (hide) { // Set cursor back to orig pos if we haven't clicked, or redo nest display if we have top.ICEcoder.dontUpdateNest ? cM.setCursor(top.ICEcoder.cursorOrigLine,top.ICEcoder.cursorOrigCh) : top.ICEcoder.getNestLocation('updateNestDisplay'); top.ICEcoder.dontUpdateNest = false; } else { // Showing the block, set orig cursor position top.ICEcoder.cursorOrigCh = cM.getCursor().ch; top.ICEcoder.cursorOrigLine = cM.getCursor().line; top.ICEcoder.dontUpdateNest = true; // Set a cursor position object to begin with searchPos = new Object(); searchPos.ch = cM.getCursor().ch; searchPos.line = cM.getCursor().line; // Then find our cursor position for our target nest depth for (var i=top.ICEcoder.htmlTagArray.length-1;i>=nestPos;i--) { cursor = cM.getSearchCursor("<"+top.ICEcoder.htmlTagArray[i],searchPos); cursor.findPrevious(); searchPos.ch = cursor.from().ch; searchPos.line = cursor.from().line; if (i==nestPos) { cursorTemp = cM.getSearchCursor(">",searchPos); cursorTemp.findNext(); cM.setCursor(cursorTemp.from().line, cursorTemp.from().ch+1); top.ICEcoder.getNestLocation(); if (ICEcoder.htmlTagArray.length-1 != nestPos) { i++; } } } // Once we've found our tag if (cursor.from()) { // Set our vars to match the start position startPos = new Object(); top.ICEcoder.startPosLine = startPos.line = cursor.from().line; top.ICEcoder.startPosCh = startPos.ch = cursor.from().ch; // Now set an end position object that matches this start tag endPos = new Object(); endPos.line = top.ICEcoder.content.contentWindow.CodeMirror.fold.xml(cM,startPos) || startPos.line; endPos.line = endPos.line.to ? endPos.line.to.line : endPos.line; endPos.ch = cM.getLine(endPos.line).indexOf("")+top.ICEcoder.htmlTagArray[nestPos].length+3; // Set the selection or escape out of not selecting !top.ICEcoder.dontSelect ? cM.setSelection(startPos,endPos) : top.ICEcoder.dontSelect = false; cM.scrollIntoView(startPos); } } }, // Set our cursor position upon mouse click of the nest position setPosition: function(nestPos,line,tag) { var cM, ch, chPos; cM = ICEcoder.getcMInstance(); // Set our ch position just after the tag, and refocus on the editor ch = cM.getLine(line).indexOf(">",cM.getLine(line).indexOf("<"+tag))+1; cM.setCursor(line,ch); top.ICEcoder.focus(); // Now update nest display to this nest depth & without any HTML tags to kill further interactivity chPos = 0; for (var i=0;i<=nestPos;i++) { chPos = ICEcoder.nestDisplay.innerHTML.indexOf(">",chPos+1); } ICEcoder.nestDisplay.innerHTML = ICEcoder.nestDisplay.innerHTML.substr(0,chPos).replace(/<(?:.|\n)*?>/gm, ''); top.ICEcoder.dontUpdateNest = false; top.ICEcoder.dontSelect = true; }, // Wrap our selected text/cursor with tags tagWrapper: function(tag) { var cM, tagStart, tagEnd, startLine, endLine; cM = ICEcoder.getcMInstance(); tagStart = tag; tagEnd = tag; if (tag=='div') { startLine = cM.getCursor('start').line; endLine = cM.getCursor().line; cM.operation(function() { cM.replaceSelection("
\n"+cM.getSelection()+"\n
","around"); for (var i=startLine+1; i<=endLine+1; i++) { cM.indentLine(i); } cM.indentLine(endLine+2,'prev'); cM.indentLine(endLine+2,'subtract'); }); } else { if ( ['p','a','b','i','strong','em','h1','h2','h3','li'].indexOf(tag)>-1 && cM.getSelection().substr(0,tag.length+1) == "<"+tagStart && cM.getSelection().substr(-(tag.length+3)) == "") { // Undo wrapper cM.replaceSelection(cM.getSelection().substr(cM.getSelection().indexOf(">")+1,cM.getSelection().length-cM.getSelection().indexOf(">")-1-tag.length-3),"around"); } else { if (tag=='a') {tagStart='a href=""';} // Do wrapper cM.replaceSelection("<"+tagStart+">"+cM.getSelection()+"","around"); if (tag=='a') {cM.setCursor({line:cM.getCursor('start').line,ch:cM.getCursor('start').ch+9})} } } }, // Add a line break at end of current or specified line addLineBreakAtEnd: function(line) { var cM; cM = ICEcoder.getcMInstance(); if (!line) {line = cM.getCursor().line}; cM.replaceRange(cM.getLine(line)+"
",{line:line,ch:0},{line:line,ch:1000000}); }, // Insert a line before and auto-indent insertLineBefore: function(line) { var cM; cM = ICEcoder.getcMInstance(); if (!line) {line = cM.getCursor().line}; cM.operation(function() { cM.replaceRange("\n"+cM.getLine(line),{line:line,ch:0},{line:line,ch:1000000}); cM.setCursor({line: cM.getCursor().line-1, ch: 0}); cM.execCommand('indentAuto'); }); }, // Insert a line after and auto-indent insertLineAfter: function(line) { var cM; cM = ICEcoder.getcMInstance(); if (!line) {line = cM.getCursor().line}; cM.operation(function() { cM.replaceRange(cM.getLine(line)+"\n",{line:line,ch:0},{line:line,ch:1000000}); cM.execCommand('indentAuto'); }); }, // Duplicate line duplicateLines: function(line) { var cM, ch, lineExtra, userSelStart, userSelEnd, lineBreak; cM = ICEcoder.getcMInstance(); if (!line && cM.somethingSelected()) { userSelStart = cM.getCursor('start'); userSelEnd = cM.getCursor('end'); lineExtra = userSelStart.line != userSelEnd.line && userSelEnd.ch == cM.getLine(userSelEnd.line).length ? "\n" : ""; cM.replaceSelection(cM.getSelection()+lineExtra+cM.getSelection(), "end"); cM.setSelection(userSelStart, userSelEnd); } else { if (!line) {line = cM.getCursor().line}; ch = cM.getCursor().ch; cM.replaceRange(cM.getLine(line)+"\n"+cM.getLine(line),{line:line,ch:0},{line:line,ch:1000000}); cM.setCursor(line+1,ch); } }, // Remove line removeLines: function(line) { var cM, ch; cM = ICEcoder.getcMInstance(); if (!line && cM.somethingSelected()) { cM.replaceSelection("","end"); } else { if (!line) {line = cM.getCursor().line}; ch = cM.getCursor().ch; cM.execCommand('deleteLine'); cM.setCursor(line-1,ch); } }, // Jump to and highlight the function definition current token jumpToDefinition: function() { var cM, tokenString, defVars; cM = ICEcoder.getcMInstance(); tokenString = cM.getTokenAt(cM.getCursor()).string; if (cM.somethingSelected() && top.ICEcoder.origCurorPos) { cM.setCursor(top.ICEcoder.origCurorPos); } else { top.ICEcoder.origCurorPos = cM.getCursor(); defVars = [ "var "+tokenString, "function "+tokenString, tokenString+"=function", tokenString+"= function", tokenString+" =function", tokenString+" = function", tokenString+"=new function", tokenString+"= new function", tokenString+" =new function", tokenString+" = new function", "window['"+tokenString+"']", "window[\""+tokenString+"\"]", "this['"+tokenString+"']", "this[\""+tokenString+"\"]", tokenString+":", tokenString+" :", "def "+tokenString, "class "+tokenString]; for (var i=0; i-1) { ICEcoder.selectDeselectFile('deselect',tgtFile); top.ICEcoder.selectedFiles.splice(top.ICEcoder.selectedFiles.indexOf(shortURL),1); } else { ICEcoder.selectDeselectFile('select',tgtFile); top.ICEcoder.selectedFiles.push(shortURL); } // Select from last click to this one } else if (evt.shiftKey) { selecting = false; dirList = tgtFile.parentNode.parentNode.parentNode; lastFileClicked = top.ICEcoder.selectedFiles[top.ICEcoder.selectedFiles.length-1]; // Prefix numbers with up to 20 leading zeros // This is so we can have some kind of natural comparison on the regex below function prefixer(match, p1, offset, string) { return ('00000000000000000000'+match).substr(-20); } startFile = shortURL.replace(/\d+/g, prefixer) < lastFileClicked.replace(/\d+/g, prefixer) ? shortURL : lastFileClicked; endFile = shortURL.replace(/\d+/g, prefixer) > lastFileClicked.replace(/\d+/g, prefixer) ? shortURL : lastFileClicked; if (top.ICEcoder.selectedFiles.length > 0 && startFile.substr(0,startFile.lastIndexOf("|")) == endFile.substr(0,endFile.lastIndexOf("|"))) { for (var i=0; i<1000000; i+=2) { if(dirList.childNodes[i].nodeName != "LI") {i++;}; thisFileObj = dirList.childNodes[i].childNodes[0].childNodes[1]; if (thisFileObj.id == startFile) { selecting = true; } if (selecting==true && top.ICEcoder.selectedFiles.indexOf(thisFileObj.id)==-1) { ICEcoder.selectDeselectFile('select',thisFileObj); top.ICEcoder.selectedFiles.push(thisFileObj.id); } if (thisFileObj.id == endFile) { break; } } } else { ICEcoder.selectDeselectFile('select',tgtFile); top.ICEcoder.selectedFiles.push(shortURL); } // We are single clicking } else { top.ICEcoder.deselectAllFiles(); // Add our URL and highlight the file ICEcoder.selectDeselectFile('select',tgtFile); top.ICEcoder.selectedFiles.push(shortURL); } } // If in GitHub mode, update the selected count and button colours if (top.ICEcoder.githubDiff) { top.get('githubNavSelectedCount').innerHTML = "Selected: " + top.ICEcoder.selectedFiles.length; top.get('githubNavCommit').style.color = top.ICEcoder.selectedFiles.length > 0 ? "#fff" : "#333"; top.get('githubNavCommit').style.background = top.ICEcoder.selectedFiles.length > 0 ? "#2187e7" : "#555"; top.get('githubNavSelectedCount').style.color = top.ICEcoder.selectedFiles.length > 0 ? "#fff" : "#333"; top.get('githubNavPull').style.color = top.ICEcoder.selectedFiles.length > 0 ? "#fff" : "#333"; top.get('githubNavPull').style.background = top.ICEcoder.selectedFiles.length > 0 ? "#2187e7" : "#555"; } // Adjust the file & replace select dropdown values accordingly document.findAndReplace.target[2].innerHTML = !top.ICEcoder.selectedFiles[0] ? "all files" : "selected files"; document.findAndReplace.target[3].innerHTML = !top.ICEcoder.selectedFiles[0] ? "all filenames" : "selected filenames"; // Hide the file menu incase it's showing top.ICEcoder.hideFileMenu(); }, // Deselect all files deselectAllFiles: function() { var tgtFile; for (var i=0;i -1 ? true : false; if (top.ICEcoder.openFiles[top.ICEcoder.selectedTab-1] == file.id.replace(/\|/g,"/")) { file.style.backgroundColor = action=="select" ? top.ICEcoder.tabBGselected : top.ICEcoder.tabBGcurrent; } else { file.style.backgroundColor = action=="select" ? top.ICEcoder.tabBGselected : file.style.backgroundColor = isOpen ? top.ICEcoder.tabBGopen : top.ICEcoder.tabBGnormal; } file.style.color = action=="select" ? top.ICEcoder.tabFGselected : top.ICEcoder.tabFGnormalFile; } }, // Create a new file (start & instant save) newFile: function() { top.ICEcoder.newTab(); top.ICEcoder.saveFile(); }, // Create a new folder newFolder: function() { var shortURL, newFolder; shortURL = top.ICEcoder.selectedFiles[top.ICEcoder.selectedFiles.length-1].replace(/\|/g,"/"); newFolder = top.ICEcoder.getInput('Enter new folder name at '+shortURL,''); if (newFolder) { newFolder = (shortURL + "/" + newFolder).replace(/\/\//,"/"); top.ICEcoder.serverQueue("add","lib/file-control.php?action=newFolder&file="+newFolder.replace(/\//g,"|")+"&csrf="+top.ICEcoder.csrf); top.ICEcoder.serverMessage(''+top.t['Creating Folder']+'
'+newFolder); } }, // Open a file openFile: function(fileLink) { var shortURL, canOpenFile; if (fileLink) { top.ICEcoder.thisFileFolderLink=fileLink; top.ICEcoder.thisFileFolderType="file"; } if (top.ICEcoder.thisFileFolderLink != "/[NEW]" && top.ICEcoder.isOpen(top.ICEcoder.thisFileFolderLink)!==false) { top.ICEcoder.switchTab(top.ICEcoder.isOpen(top.ICEcoder.thisFileFolderLink)+1); } else if (top.ICEcoder.thisFileFolderLink!="" && top.ICEcoder.thisFileFolderType=="file") { // work out a shortened URL for the file shortURL = top.ICEcoder.thisFileFolderLink.replace(/\|/g,"/"); // No reason why we can't open a file (so far) canOpenFile = true; // Limit to 100 files open at a time if (top.ICEcoder.openFiles.length>=100) { top.ICEcoder.message(top.t['Sorry you can...']); canOpenFile = false; } // if we're still OK to open it... if (canOpenFile) { top.ICEcoder.shortURL = shortURL; if (shortURL!="/[NEW]") { top.ICEcoder.thisFileFolderLink = top.ICEcoder.thisFileFolderLink.replace(/\//g,"|"); top.ICEcoder.serverQueue("add","lib/file-control.php?action=load&file="+top.ICEcoder.thisFileFolderLink+"&csrf="+top.ICEcoder.csrf); top.ICEcoder.serverMessage(''+top.t['Opening File']+'
'+top.ICEcoder.shortURL); } else { top.ICEcoder.createNewTab(); } top.ICEcoder.fMIconVis('fMView',1); } } }, // Open selected files openFilesFromList: function(fileList) { for (var i=0;i-1 ? top.ICEcoder.getRemoteFile(fileLink) : top.ICEcoder.openFile(fileLink); } }, // Get remote file contents getRemoteFile: function(remoteFile) { top.ICEcoder.serverQueue("add","lib/file-control.php?action=getRemoteFile&file="+remoteFile+"&csrf="+top.ICEcoder.csrf); top.ICEcoder.serverMessage(''+top.t['Getting']+'
'+remoteFile); }, // Save a file saveFile: function(saveAs) { var saveType, filePath, pathPrefix; saveType = saveAs ? "saveAs" : "save"; filePath = ICEcoder.openFiles[ICEcoder.selectedTab-1].replace(top.iceRoot,"").replace(/\//g,"|"); if (filePath=="|[NEW]" && top.ICEcoder.selectedFiles.length>0) { pathPrefix = top.ICEcoder.selectedFiles[0]; filePath = pathPrefix.lastIndexOf(".") == -1 || pathPrefix.lastIndexOf(".") < pathPrefix.lastIndexOf("|") ? pathPrefix+filePath : "|[NEW]"; } filePath = filePath.replace("||","|"); top.ICEcoder.serverQueue("add","lib/file-control.php?action=save&file="+filePath+"&fileMDT="+ICEcoder.openFileMDTs[ICEcoder.selectedTab-1]+"&saveType="+saveType+"&csrf="+top.ICEcoder.csrf); top.ICEcoder.serverMessage(''+top.t['Saving']+'
'+ICEcoder.openFiles[ICEcoder.selectedTab-1].replace(top.iceRoot,"")); }, // Prompt a rename dialog renameFile: function(oldName,newName) { var shortURL, fileName, i; if (!oldName) { shortURL = top.ICEcoder.selectedFiles[top.ICEcoder.selectedFiles.length-1].replace(/\|/g,"/"); oldName = top.ICEcoder.selectedFiles[top.ICEcoder.selectedFiles.length-1].replace(/\|/g,"/"); } else { shortURL = oldName.replace(/\|/g,"/"); } if (!newName) { newName = top.ICEcoder.getInput(top.t['Please enter the...'],shortURL); } if (newName) { i = top.ICEcoder.openFiles.indexOf(shortURL.replace(/\|/g,"/")); if(i>-1) { // rename array item and the tab top.ICEcoder.openFiles[i] = newName; closeTabLink = ''; fileName = top.ICEcoder.openFiles[i]; top.get('tab'+(i+1)).innerHTML = closeTabLink + " " + fileName.slice(fileName.lastIndexOf("/")).replace(/\//,""); top.get('tab'+(i+1)).title = newName; } top.ICEcoder.serverQueue("add","lib/file-control.php?action=rename&file="+newName+"&oldFileName="+oldName.replace(/\|/g,"/")+"&csrf="+top.ICEcoder.csrf); top.ICEcoder.serverMessage(''+top.t['Renaming to']+'
'+newName); top.ICEcoder.setPreviousFiles(); } }, // Move a file from old location to new moveFile: function(oldName,newName) { var fileName, i; if (newName) { i = top.ICEcoder.openFiles.indexOf(oldName.replace(/\|/g,"/")); if(i>-1) { // rename array item and the tab top.ICEcoder.openFiles[i] = newName; closeTabLink = ''; fileName = top.ICEcoder.openFiles[i]; top.get('tab'+(i+1)).innerHTML = closeTabLink + " " + fileName.slice(fileName.lastIndexOf("/")).replace(/\//,""); top.get('tab'+(i+1)).title = newName; } top.ICEcoder.serverQueue("add","lib/file-control.php?action=move&file="+newName+"&oldFileName="+oldName.replace(/\|/g,"/")+"&csrf="+top.ICEcoder.csrf); top.ICEcoder.serverMessage(''+top.t['Moving to']+'
'+newName); top.ICEcoder.setPreviousFiles(); } }, // Delete a file deleteFiles: function(fileList) { var tgtFiles, tgtListDisplay; tgtFiles = fileList ? fileList : top.ICEcoder.selectedFiles; tgtListDisplay = tgtFiles.toString().replace(/\|/g,"/").replace(/,/g,"\n"); if (tgtFiles.length>0 && top.ICEcoder.ask('Delete:\n\n'+tgtListDisplay+'?')) { top.ICEcoder.serverQueue("add","lib/file-control.php?action=delete&file="+tgtFiles.join(";")+"&csrf="+top.ICEcoder.csrf); top.ICEcoder.serverMessage(''+top.t['Deleting File']+'
'+tgtListDisplay); }; }, // Copy files copyFiles: function(fileList,dontShowPaste,dontHide) { top.ICEcoder.copiedFiles = []; for (var i=0; i'+top.t['Pasting File']+'
'+top.ICEcoder.copiedFiles[i].toString().replace(/\|/g,"/").replace(/,/g,"\n")); } else { top.ICEcoder.message(top.t['Sorry cannot paste...']); } } } else { top.ICEcoder.message(top.t['Nothing to paste...']); } }, // Duplicate (copy & paste) files duplicateFiles: function(fileList) { var copiedFiles, location; // Take a snapshot of copied files if (top.ICEcoder.copiedFiles) { copiedFiles = top.ICEcoder.copiedFiles; } top.ICEcoder.copyFiles(fileList,'dontShowPaste','dontHide'); location = fileList[0].substr(0,fileList[0].lastIndexOf("|")); top.ICEcoder.pasteFiles(location); // Restore copied files back to the snapshot if ("undefined" != typeof copiedFiles) { top.ICEcoder.copiedFiles = copiedFiles; } }, // Upload file(s) - select & submit uploadFilesSelect: function(location) { top.get('uploadDir').value = location; top.get("fileInput").click(); }, uploadFilesSubmit: function(obj) { if (top.get('fileInput').value!="") { top.ICEcoder.showHide('show',top.get('loadingMask')); top.get('uploadFilesForm').submit(); event.preventDefault(); } }, // Show/hide file manager nav options showHideFileNav: function(vis,elem) { var options = ["optionsFile","optionsEdit","optionsRemote","optionsHelp"]; if (vis=="hide") { fileNavInt = setTimeout(function() { for (var i=0; i-1 ? "file" : "folder"; top.get('folderMenuItems').style.display = menuType == "folder" && top.ICEcoder.selectedFiles.length == 1 ? "block" : "none"; if (menuType == "folder" && top.ICEcoder.selectedFiles.length == 1) { menuHeight += 20+20+1+23+1+2; // new file, new folder, hr, upload files(s), hr, padding if (top.get('fmMenuPasteOption').style.display == "block") { menuHeight += 19; } } top.get('singleFileMenuItems').style.display = top.ICEcoder.selectedFiles.length > 1 ? "none" : "block"; if (top.ICEcoder.selectedFiles.length == 1) { menuHeight += 43; } top.get('fileMenu').style.display = "inline-block"; setTimeout(function() {top.get('fileMenu').style.opacity = "1"},4); top.get('fileMenu').style.left = (top.ICEcoder.mouseX+20) + "px"; fmYPos = top.ICEcoder.mouseY-top.ICEcoder.filesFrame.contentWindow.document.body.scrollTop-10; if (fmYPos+menuHeight > winH) { fmYPos -= (fmYPos+menuHeight-winH); } top.get('fileMenu').style.top = fmYPos + "px"; } return false; }, // Continue to show the file manager showFileMenu: function() { top.get('fileMenu').style.display='inline-block'; setTimeout(function() {top.get('fileMenu').style.opacity = "1"},4); }, // Hide the file manager hideFileMenu: function() { top.get('fileMenu').style.display='none'; top.get('fileMenu').style.opacity = "0"; }, // Update the file manager tree list on demand updateFileManagerList: function(action,location,file,perms,oldName,uploaded,fileOrFolder) { var actionElemType, cssStyle, perms, targetElem, locNest, newText, innerLI, newUL, newLI, elemType, nameLI, shortURL, newMouseOver; // Adding files if (action=="add" && !top.get('filesFrame').contentWindow.document.getElementById(location.replace(top.iceRoot,"").replace(/\/$/, "").replace(/\//g,"|")+"|"+file)) { // Is this is a file or folder and based on that, set the CSS styling & link actionElemType = fileOrFolder; cssStyle = actionElemType=="file" ? "pft-file ext-" + file.substr(file.indexOf(".")+1) : "pft-directory"; perms = actionElemType=="file" ? 664 : 705; // Identify our target element & the first child element in it's location if (!location) {location=""} location = location.replace(top.iceRoot,"/"); targetElem = top.get('filesFrame').contentWindow.document.getElementById(location.replace(/\//g,"|")); locNest = targetElem.parentNode.parentNode.nextSibling; newText = document.createTextNode("\n"); innerLI = '        '+file+' '+perms+''; // If we don't have at least 3 DOM items in here, it's an empty folder if(locNest.childNodes.length<3) { // We now need to begin a new UL list newUL = document.createElement("ul"); locNest = targetElem.parentNode.parentNode; locNest.parentNode.insertBefore(newUL,locNest.nextSibling); // Now we can add the first LI for this file/folder we're adding newLI = document.createElement("li"); newLI.className = cssStyle; newLI.draggable = true; newLI.ondrag = function(event) {top.ICEcoder.draggingWithKeyTest(event);if(top.ICEcoder.getcMInstance()){top.ICEcoder.getcMInstance().focus()}}; newLI.ondragend = function() {top.ICEcoder.dropFile(this)}; newLI.innerHTML = innerLI locNest.nextSibling.appendChild(newLI); locNest.nextSibling.appendChild(newText); // There are items in that location, so add our new item in the right position } else { for (var i=0;i0 ? "folder" : "file"; // Get the name of the item nameLI = locNest.childNodes[i].getElementsByTagName('span')[0].innerHTML; // If it's of the same type & the name is greater, or we're adding a folder and it's a file or if we're at the end of the list if ((elemType==actionElemType && nameLI > file) || (actionElemType=="folder" && elemType=="file") || i==locNest.childNodes.length-1) { newLI = document.createElement("li"); newLI.className = cssStyle; newLI.draggable = true; newLI.ondrag = function(event) {top.ICEcoder.draggingWithKeyTest(event);if(top.ICEcoder.getcMInstance()){top.ICEcoder.getcMInstance().focus()}}; newLI.ondragend = function() {top.ICEcoder.dropFile(this)}; newLI.innerHTML = innerLI; // Append or insert depending on which of the above if statements is true if (i==locNest.childNodes.length-1) { locNest.appendChild(newLI); locNest.appendChild(newText); } else { locNest.insertBefore(newLI,locNest.childNodes[i]); locNest.insertBefore(newText,locNest.childNodes[i+1]); } break; } } } } // If we added a new file, we've saved it under a new filename, so set that if (actionElemType=="file" && !uploaded) { top.ICEcoder.openFiles[top.ICEcoder.selectedTab-1]=location+file; } } // Renaming files if (action=="rename") { // Get short URL of our right clicked file and get target elem based on this shortURL = oldName.replace(/\//g,"|"); targetElem = top.get('filesFrame').contentWindow.document.getElementById(shortURL); // Set the name to be as per our new file/folder name targetElem.innerHTML = file; // Finally, update the ID of the target & set a new title and perms ID targetElem.id = location.replace(/\//g,"|") + "|" + file; targetElem.parentNode.title = targetElem.id.replace(/\|/g,"/"); targetElemPerms = top.get('filesFrame').contentWindow.document.getElementById(shortURL+"_perms"); targetElemPerms.id = location.replace(/\//g,"|") + "|" + file + "_perms"; } // Moving files if (action=="move") { top.ICEcoder.updateFileManagerList("add",location,file,false,false,false,fileOrFolder); top.ICEcoder.updateFileManagerList("delete",oldName.substr(0,oldName.lastIndexOf("/")),file); } // Chmod on files if (action=="chmod") { // Get short URL for our file and get our target elem based on this shortURL = top.ICEcoder.selectedFiles[top.ICEcoder.selectedFiles.length-1].replace(/\|/g,"/"); targetElem = top.get('filesFrame').contentWindow.document.getElementById(shortURL.replace(/\//g,"|")+"_perms"); // Set the new perms targetElem.innerHTML = perms; } // Deleting files if (action=="delete") { // Simply get our target and make it dissapear targetElem = top.get('filesFrame').contentWindow.document.getElementById( (top.iceRoot == "" ? location.replace(/\/$/, "").replace(/\//g,"|") : "") +"|"+file).parentNode.parentNode; top.ICEcoder.openCloseDir(targetElem.childNodes[0],false); targetElem.parentNode.removeChild(targetElem); } }, // Refresh file manager refreshFileManager: function() { top.ICEcoder.showHide('show',top.get('loadingMask')); top.ICEcoder.filesFrame.contentWindow.location.reload(); top.ICEcoder.filesFrame.style.opacity="0"; top.ICEcoder.filesFrame.onload = function() { top.ICEcoder.filesFrame.style.opacity="1"; top.ICEcoder.showHide('hide',top.get('loadingMask')); } }, // Detect CTRL/Cmd key whilst dragging files draggingWithKeyTest: function(evt) { var key; key = evt.keyCode ? evt.keyCode : evt.which ? evt.which : evt.charCode; // Mac command key handling (224 = Moz, 91/93 = Webkit Left/Right Apple) if (key==224 || key==91 || key==93) { top.ICEcoder.cmdKey = true; } top.ICEcoder.draggingWithKey = evt.ctrlKey||top.ICEcoder.cmdKey ? "CTRL" : false; }, // On dropping a file, do something dropFile: function(elem) { var filePath, tgtPath; filePath = elem.childNodes[0].childNodes[1].id.replace(/\|/g,"/"); fileName = filePath.substr(filePath.lastIndexOf("/")+1); if (top.ICEcoder.area=='editor') { top.ICEcoder.pasteURL(filePath); }; if (top.ICEcoder.area=='files') { setTimeout(function() { tgtPath = ICEcoder.thisFileFolderType == "folder" ? ICEcoder.thisFileFolderLink : ICEcoder.thisFileFolderLink.substr(0,ICEcoder.thisFileFolderLink.lastIndexOf("|")); if(top.ICEcoder.draggingWithKey == "CTRL") { top.ICEcoder.copyFiles(top.ICEcoder.selectedFiles); top.ICEcoder.pasteFiles(tgtPath); } else { top.ICEcoder.moveFile(filePath,tgtPath.replace(/\|/g,"/") + "/" + fileName); } },4); }; top.ICEcoder.mouseDown=false; }, // ============== // FIND & REPLACE // ============== // Update find & replace options based on user selection findReplaceOptions: function() { top.get('rText').style.display = top.get('replace').style.display = top.get('rTarget').style.display = document.findAndReplace.connector.value=="and" ? "inline-block" : "none"; }, // Find & replace text according to user selections findReplace: function(findString,resultsOnly,buttonClick) { var find, replace, results, cM, content, scrollBarVisible, cursor, avgBlockH, addPadding, rBlocks, blockColor, replaceQS, targetQS, filesQS; // Determine our find & replace strings and results display find = findString.toLowerCase(); replace = top.get('replace').value; results = top.get('results'); // If we have something to find in currrent document cM = ICEcoder.getcMInstance(); if (cM && find.length>0 && document.findAndReplace.target.value=="this document") { content = cM.getValue().toLowerCase(); // Find & replace the next instance, or all? if (document.findAndReplace.connector.value=="and" && buttonClick) { if (document.findAndReplace.replaceAction.value=="replace" && cM.getSelection().toLowerCase()==find) { cM.replaceSelection(replace,"around"); } else if (document.findAndReplace.replaceAction.value=="replace all") { var rExp = new RegExp(find,"gi"); cM.setValue(cM.getValue().replace(rExp,replace)); } } // Get the content again, as it might of changed content = cM.getValue().toLowerCase(); if (!top.ICEcoder.findMode||find!=top.ICEcoder.lastsearch) { ICEcoder.results = []; ICEcoder.resultsLines = []; for (var i=0;i0) { // Detect if we have a scrollbar scrollBarVisible = cM.getScrollInfo().height > cM.getScrollInfo().clientHeight; // Show results only if (resultsOnly) { results.innerHTML = ICEcoder.results.length + " results"; // We need to take action instead } else { // Find our cursor position relative to results ICEcoder.findResult = 0; for (var i=0;iICEcoder.results.length-1) {ICEcoder.findResult=0}; // Update results display results.innerHTML = "Highlighted result "+(ICEcoder.findResult+1)+" of "+ICEcoder.results.length+" results"; cursor = cM.getSearchCursor(find,cM.getCursor(),true); cursor.findNext(); if (!cursor.from()) { cursor = cM.getSearchCursor(find,{line:0,ch:0},true); cursor.findNext(); } // Finally, highlight our selection cM.setSelection(cursor.from(), cursor.to()); top.ICEcoder.focus(); top.ICEcoder.findMode = true; } // Display the find results bar // The avg block is either line height or fraction of space available avgBlockH = !scrollBarVisible ? cM.defaultTextHeight() : parseInt(top.ICEcoder.content.style.height,10)/cM.lineCount(); // Need to add padding if there's no scrollbar, so current line highlighting lines up with it addPadding = !scrollBarVisible ? cM.heightAtLine(0) : 0; // Place to edge of screen or scrollbar top.ICEcoder.content.contentWindow.document.getElementById('resultsBar').style.right = !scrollBarVisible ? "0" : "17px"; rBlocks = ""; for (var i=1; i<=cM.lineCount(); i++) { blockColor = ICEcoder.resultsLines.indexOf(i)>-1 ? cM.getCursor().line+1 == i ? "#b00" : "#888" : "transparent" rBlocks += '
'; } top.ICEcoder.content.contentWindow.document.getElementById('resultsBar').innerHTML = rBlocks; top.ICEcoder.content.contentWindow.document.getElementById('resultsBar').style.display = "inline-block"; return true; } else { results.innerHTML = "No results"; top.ICEcoder.content.contentWindow.document.getElementById('resultsBar').innerHTML = ""; top.ICEcoder.content.contentWindow.document.getElementById('resultsBar').style.display = "none"; return false; } } else { // Show the relevant multiple results popup if (find != "" && buttonClick) { replaceQS = ""; targetQS = ""; filesQS = ""; if (document.findAndReplace.connector.value=="and") { replaceQS = "&replace="+replace; } if (document.findAndReplace.target.value.indexOf("file")>=0) { targetQS = "&target="+document.findAndReplace.target.value.replace(/ /g,"-"); } if (document.findAndReplace.target.value=="selected files") { filesQS = "&selectedFiles="+top.ICEcoder.selectedFiles.join(":"); } find = find.replace(/\'/g, '\''); find != encodeURIComponent(find) ? find = 'ICEcoder:'+encodeURIComponent(find) : find; top.ICEcoder.showHide('show',top.get('loadingMask')); top.get('mediaContainer').innerHTML = ''; // We have nothing to search for, blank it all out } else { results.innerHTML = "No results"; top.ICEcoder.content.contentWindow.document.getElementById('resultsBar').innerHTML = ""; top.ICEcoder.content.contentWindow.document.getElementById('resultsBar').style.display = "none"; } } }, // Replace text in a file replaceInFile: function(fileRef,find,replace) { top.ICEcoder.serverQueue("add","lib/file-control.php?action=replaceText&fileRef="+fileRef.replace(/\//g,"|")+"&find="+find+"&replace="+replace+"&csrf="+top.ICEcoder.csrf); top.ICEcoder.serverMessage(''+top.t['Replacing text in']+'
'+fileRef); }, // ============== // INFO & DISPLAY // ============== // Work out the nesting depth location on demand and update our display if required getNestLocation: function(updateNestDisplay) { var cM, nestCheck, state, cx, startPos, fileName; cM = ICEcoder.getcMInstance(); if (cM) { nestCheck = cM.getValue(); // Get the token state at our cursor state = cM.getTokenAt(cM.getCursor()).state; cx = false; // XML if ("undefined" != typeof state) { cx = state.context; } // HTML if ("undefined" != typeof state.curState && "undefined" != typeof state.curState.htmlState) { cx = state.curState.htmlState.context; } // Set up array to store nest data ICEcoder.htmlTagArray = []; if (cx) { for (cx = cx; cx; cx = cx.prev) { if ("undefined" != typeof cx.tagName) { ICEcoder.htmlTagArray.unshift(cx.tagName); } } } ICEcoder.tagString = ICEcoder.htmlTagArray[ICEcoder.htmlTagArray.length-1]; if (ICEcoder.caretLocType=="JavaScript") { ICEcoder.tagString = "script"; } // Now we've built up our nest depth array, if we're due to show it in the display if (updateNestDisplay && !top.ICEcoder.dontUpdateNest) { // Clear the display ICEcoder.nestDisplay.innerHTML = ""; if ("undefined" != typeof ICEcoder.openFiles[ICEcoder.selectedTab-1]) { fileName = ICEcoder.openFiles[ICEcoder.selectedTab-1]; ICEcoder.getNestLocationSub(nestCheck, fileName); } } } }, // Get the caret position getCaretPosition: function() { var cM, line, ch, chPos; cM = ICEcoder.getcMInstance(); line = cM.getCursor().line; ch = cM.getCursor().ch; chPos = 0; for (var i=0;i0) ? 'cM'+ICEcoder.cMInstances[ICEcoder.selectedTab-1] // fallback to first tab : 'cM1' ]; }, // Get the mouse position getMouseXY: function(e,area) { var tempX, tempY; top.ICEcoder.mouseX = e.pageX ? e.pageX : e.clientX + document.body.scrollLeft; top.ICEcoder.mouseY = e.pageY ? e.pageY : e.clientY + document.body.scrollTop; top.ICEcoder.area = area; if (area!="top") { top.ICEcoder.mouseY += 25 + 45; } if (area=="editor") { top.ICEcoder.mouseX += top.ICEcoder.filesW; } top.ICEcoder.dragCursorTest(); if (top.ICEcoder.mouseY>62) {top.ICEcoder.setTabWidths();}; }, // Test if we need to show a drag cursor or not dragCursorTest: function() { var diffX, winH, cursorName, zone; // Dragging tabs, started after dragging for 10px from origin diffX = top.ICEcoder.mouseX - top.ICEcoder.diffStartX; if (top.ICEcoder.draggingTab!==false && top.ICEcoder.diffStartX && (diffX <= -10 || diffX >= 10)) { if (top.ICEcoder.mouseX > parseInt(top.ICEcoder.files.style.width,10)) { top.ICEcoder.tabDragMouseX = top.ICEcoder.mouseX - parseInt(top.ICEcoder.files.style.width,10) - top.ICEcoder.tabDragMouseXStart; top.ICEcoder.tabDragMove(); } } // Dragging file manager, possible within 7px of file manager edge if (top.ICEcoder.ready) { winH = window.innerHeight; if (!top.ICEcoder.mouseDown) {top.ICEcoder.draggingFilesW = false}; cursorName = (!ICEcoder.draggingTab && ((top.ICEcoder.mouseX > top.ICEcoder.filesW-7 && top.ICEcoder.mouseX < top.ICEcoder.filesW+7) || top.ICEcoder.draggingFilesW)) ? "w-resize" : "auto"; if (top.ICEcoder.content.contentWindow.document && top.ICEcoder.filesFrame.contentWindow) { top.document.body.style.cursor = cursorName; if (zone = top.ICEcoder.content.contentWindow.document.body) {zone.style.cursor = cursorName}; if (zone = top.ICEcoder.filesFrame.contentWindow.document.body) {zone.style.cursor = cursorName}; } } }, // Show or hide a server message serverMessage: function(message) { var serverMessage; serverMessage = top.get('serverMessage'); if (message) { serverMessage.innerHTML = top.ICEcoder.xssClean(message).replace(/\<b\>/g,"").replace(/\<\/b\>/g,"").replace(/\<br\>/g,"
"); serverMessage.style.left = "0"; } else { setTimeout(function() {serverMessage.style.left = "2000px";},200); } serverMessage.style.opacity = message ? 1 : 0; }, // Show a CSS color block next to our text cursor cssColorPreview: function() { var cM, string, rx, match, oldBlock, newBlock; cM = ICEcoder.getcMInstance(); if (cM) { string = cM.getLine(cM.getCursor().line); rx = /(#[\da-f]{3}(?:[\da-f]{3})?\b|\b(?:rgb|hsl)a?\([\s\d%,.-]+\)|\b[a-z]+\b)/gi; while((match = rx.exec(string)) && cM.getCursor().ch > match.index+match[0].length); oldBlock = top.get('content').contentWindow.document.getElementById('cssColor'); if (oldBlock) {oldBlock.parentNode.removeChild(oldBlock)}; if (top.ICEcoder.codeAssist && top.ICEcoder.caretLocType=="CSS") { newBlock = top.document.createElement("div"); newBlock.id = "cssColor"; newBlock.style.position = "absolute"; newBlock.style.display = "block"; newBlock.style.width = newBlock.style.height = "20px"; newBlock.style.zIndex = "1000"; newBlock.style.background = match ? match[0] : ''; newBlock.style.cursor = "pointer"; newBlock.onclick = function() {top.ICEcoder.showColorPicker(match[0])}; if (newBlock.style.backgroundColor=="") {newBlock.style.display = "none"}; top.get('header').appendChild(newBlock); cM.addWidget(cM.getCursor(), top.get('cssColor'), true); } } }, // Show color picker showColorPicker: function(color) { top.get('blackMask').style.visibility = "visible"; top.get('mediaContainer').innerHTML = '


'+ ''+ '
'+ ''+ ''; farbtastic('picker','color'); if (color) { top.get('picker').farbtastic.setColor(color); } }, // Draw a canvas image based on actual img node image src drawCanvasImage: function (imgThis) { var canvas, img, x, y, imgData, R, G, B, rgb, hex, textColor; canvas = top.get('canvasPicker').getContext('2d'); img = new Image(); img.src = imgThis.src; img.onload = function() { top.get('canvasPicker').width = imgThis.width; top.get('canvasPicker').height = imgThis.height; canvas.drawImage(img,0,0,imgThis.width,imgThis.height); } // Show pointer colors on mouse move over canvas top.get('canvasPicker').onmousemove = function(event) { // get mouse x & y x = event.pageX - this.offsetLeft; y = event.pageY - this.offsetTop; // get image data & then RGB values imgData = canvas.getImageData(x, y, 1, 1).data; R = imgData[0]; G = imgData[1]; B = imgData[2]; rgb = R+','+G+','+B; // Get hex from RGB value hex = top.ICEcoder.rgbToHex(R,G,B); // set the values & BG colours of the input boxes top.get('rgbMouseXY').value = rgb; top.get('hexMouseXY').value = '#' + hex; top.get('hexMouseXY').style.backgroundColor = top.get('rgbMouseXY').style.backgroundColor = '#' + hex; textColor = R<128 || G<128 || B<128 && (R<200 && G<200 && B>50) ? '#fff' : '#000'; top.get('hexMouseXY').style.color = top.get('rgbMouseXY').style.color = textColor; }; // Set pointer colors on clicking canvas top.get('canvasPicker').onclick = function() { top.get('rgb').value = top.get('rgbMouseXY').value; top.get('hex').value = top.get('hexMouseXY').value; top.get('hex').style.backgroundColor = top.get('rgb').style.backgroundColor = top.get('hex').value; top.get('hex').style.color = top.get('rgb').style.color = textColor; } }, // Convert RGB values to Hex rgbToHex: function(R,G,B) { return top.ICEcoder.toHex(R)+top.ICEcoder.toHex(G)+top.ICEcoder.toHex(B); }, // Return numbers as hex equivalent toHex: function(n) { n = parseInt(n,10); if (isNaN(n)) return "00"; n = Math.max(0,Math.min(n,255)); return "0123456789abcdef".charAt((n-n%16)/16) + "0123456789abcdef".charAt(n%16); }, // Insert new color value insertColorValue: function(color) { var cM, cursor; cM = ICEcoder.getcMInstance(); cursor = cM.getTokenAt(cM.getCursor()); cM.replaceRange(color,{line:cM.getCursor().line,ch:cursor.start},{line:cM.getCursor().line,ch:1000000}); }, // Change opacity of the file manager icons fMIconVis: function(icon, vis) { var i; if (i = top.get(icon)) { i.style.opacity = vis; } }, // Check if a file is already open isOpen: function(file) { var i; file = file.replace(/\|/g, "/").replace(top.docRoot+top.iceRoot,""); i = top.ICEcoder.openFiles.indexOf(file); // return the array position or false return i!=-1 ? i : false; }, // ============== // SYSTEM // ============== // Start running plugin intervals according to given specifics startPluginIntervals: function(plugRef,plugURL,plugTarget,plugTimer) { // Add CSRF to URL if it has QS params if (plugURL.indexOf("?") > -1) { plugURL = plugURL+"&csrf="+top.ICEcoder.csrf; } top.ICEcoder['plugTimer'+plugRef] = // This window instances ["_parent","_top","_self",""].indexOf(plugTarget) > -1 ? top.ICEcoder['plugTimer'+plugRef] = setInterval('window.location=\''+plugURL+'\'',plugTimer*1000*60) // fileControl iframe instances : plugTarget.indexOf("fileControl") == 0 ? top.ICEcoder['plugTimer'+plugRef] = setInterval(function() { top.ICEcoder.serverQueue("add",plugURL);top.ICEcoder.serverMessage(plugTarget.split(":")[1]); },plugTimer*1000*60) // _blank or named target window instances : top.ICEcoder['plugTimer'+plugRef] = setInterval('window.open(\''+plugURL+'\',\''+plugTarget+'\')',plugTimer*1000*60); // push the plugin ref into our array top.ICEcoder.pluginIntervalRefs.push(plugRef); }, // Turning on/off the Code Assist codeAssistToggle: function() { var cM; cM = ICEcoder.getcMInstance(); top.ICEcoder.codeAssist = !top.ICEcoder.codeAssist; top.get('codeAssistDisplay').style.backgroundPosition = top.ICEcoder.codeAssist ? "0 0" : "-16px 0"; top.ICEcoder.cssColorPreview(); top.ICEcoder.focus(); for (i=0;i-1) { cM = top.ICEcoder.content.contentWindow['cM'+top.ICEcoder.cMInstances[i]]; if (!top.ICEcoder.codeAssist) { cM.clearGutter("CodeMirror-lint-markers"); cM.setOption("lintWith",false); } else { cM.setOption("lintWith",top.ICEcoder.content.contentWindow.CodeMirror.javascriptValidator); } } } }, // Queue items up for processing in turn serverQueue: function(action,item) { var cM, nextSaveID, txtArea, topSaveID, element; cM = ICEcoder.getcMInstance(); // Firstly, work out how many saves we have to carry out nextSaveID=0; for (var i=0;i0) { nextSaveID++; } } nextSaveID++; // Add to end of array or remove from beginning on demand, plus add or remove if necessary if (action=="add") { ICEcoder.serverQueueItems.push(item); if (item.indexOf('action=save')>0) { txtArea = document.createElement('textarea'); txtArea.setAttribute('id', 'saveTemp'+nextSaveID); document.body.appendChild(txtArea); top.get('saveTemp'+nextSaveID).value = cM.getValue(); } } else if (action=="del") { if (ICEcoder.serverQueueItems[0] && ICEcoder.serverQueueItems[0].indexOf('action=save')>0) { topSaveID = nextSaveID-1; for (var i=1;i=1 || ICEcoder.serverQueueItems.length==1) { setTimeout(function() {top.ICEcoder.filesFrame.contentWindow.frames['fileControl'].location.href=ICEcoder.serverQueueItems[0]},1); } }, // Cancel all actions on pressing Esc in non content areas cancelAllActions: function() { // Stop whatever the parent may be loading and clear tasks other than the current one window.stop(); if (ICEcoder.serverQueueItems.length>0) { ICEcoder.serverQueueItems.splice(1,ICEcoder.serverQueueItems.length); } top.ICEcoder.showHide('hide',top.get('loadingMask')); top.ICEcoder.serverMessage(''+top.t['Cancelled tasks']+''); setTimeout(function() {top.ICEcoder.serverMessage();},2000); }, // Set the current previousFiles in the settings file setPreviousFiles: function() { var previousFiles; previousFiles = top.ICEcoder.openFiles.join(',').replace(/\//g,"|").replace(/(\|\[NEW\])|(,\|\[NEW\])/g,"").replace(/(^,)|(,$)/g,""); if (previousFiles=="") {previousFiles="CLEAR"}; // Then send through to the settings page to update setting top.ICEcoder.serverQueue("add","lib/settings.php?saveFiles="+previousFiles+"&csrf="+top.ICEcoder.csrf); }, // Opens the last files we had open autoOpenFiles: function() { if (top.ICEcoder.previousFiles.length>0 && top.ICEcoder.ask(top.t['Open previous files']+'\n\n'+top.ICEcoder.previousFiles.length+' files:\n'+top.ICEcoder.previousFiles.join('\n').replace(/\|/g,"/").replace(new RegExp(top.docRoot+top.iceRoot,'gi'),""))) { for (var i=0;i'; top.ICEcoder.showHide('show',top.get('blackMask')); }, // Show the properties screen propertiesScreen: function(fileName) { top.get('mediaContainer').innerHTML = ''; top.ICEcoder.showHide('show',top.get('blackMask')); }, // Show the plugins manager pluginsManager: function() { top.get('mediaContainer').innerHTML = ''; top.ICEcoder.showHide('show',top.get('blackMask')); }, // Show the GitHub commit screen gitHubAction: function(action) { top.get('mediaContainer').innerHTML = ''; top.ICEcoder.showHide('show',top.get('blackMask')); }, // Ask user for GitHub token githubTokenAsk: function(goNext) { if (githubAuthToken = top.ICEcoder.getInput(top.t['Please enter your...'],'')) { top.ICEcoder.filesFrame.contentWindow.frames['fileControl'].location.href = "lib/github.php?action=auth&token="+githubAuthToken+"&goNext="+goNext+"&csrf="+top.ICEcoder.csrf; // Clear the token from the var for security githubAuthToken = ""; } }, // Show/Hide the GitHub file nav showHideGithubNav: function(vis) { top.get('githubNav').style.display = vis == "show" ? "block" : "none"; top.get('fileNav').style.display = vis == "show" ? "none" : "block"; }, // Show the GitHub manager githubManager: function() { var githubAuthToken; if (top.ICEcoder.githubAuthTokenSet) { top.get('mediaContainer').innerHTML = ''; top.ICEcoder.showHide('show',top.get('blackMask')); } else { top.ICEcoder.githubTokenAsk('showManager'); } }, // Toggle the GitHub diff on/off view githubDiffToggle: function() { var gHDiff; if (!top.ICEcoder.githubAuthTokenSet) { top.ICEcoder.githubTokenAsk('loadFiles'); } else if (top.ICEcoder.githubDiff || top.ICEcoder.ask(top.t['This will compare...'])) { top.ICEcoder.githubDiff = !top.ICEcoder.githubDiff; gHDiff = top.ICEcoder.githubDiff ? "true" : "false"; top.ICEcoder.filesFrame.src = "files.php?githubDiff="+gHDiff+"&csrf="+top.ICEcoder.csrf; } }, // Update the settings used when we make a change to them useNewSettings: function(themeURL,codeAssist,lockedNav,tagWrapperCommand,autoComplete,visibleTabs,fontSize,lineWrapping,indentWithTabs,indentSize,pluginPanelAligned,bugFilePaths,bugFileCheckTimer,bugFileMaxLines,githubAuthTokenSet,refreshFM) { var styleNode, strCSS, cMCSS, activeLineBG; // Add new stylesheet for selected theme top.ICEcoder.theme = themeURL.slice(themeURL.lastIndexOf("/")+1,themeURL.lastIndexOf(".")); if (top.ICEcoder.theme=="editor") {top.ICEcoder.theme="icecoder"}; styleNode = document.createElement('link'); styleNode.setAttribute('rel', 'stylesheet'); styleNode.setAttribute('type', 'text/css'); styleNode.setAttribute('href', themeURL); top.ICEcoder.content.contentWindow.document.getElementsByTagName('head')[0].appendChild(styleNode); activeLineBG = ["3024-day","base16-light","eclipse","elegant","neat","paraiso-light","solarized","xq-light"].indexOf(top.ICEcoder.theme)>-1 ? "#ccc": "#000"; top.ICEcoder.switchTab(top.ICEcoder.selectedTab); // Check/uncheck Code Assist setting if (codeAssist != top.ICEcoder.codeAssist) { top.get('codeAssist').checked = codeAssist; top.ICEcoder.codeAssistToggle(); } // Unlock/lock the file manager if (lockedNav != top.ICEcoder.lockedNav) {top.ICEcoder.lockUnlockNav()}; if (!lockedNav) { ICEcoder.changeFilesW('contract'); top.ICEcoder.hideFileMenu(); } cMCSS = ICEcoder.content.contentWindow.document.styleSheets[4]; strCSS = cMCSS.rules ? 'rules' : 'cssRules'; cMCSS[strCSS][0].style['fontSize'] = fontSize; cMCSS[strCSS][4].style['border-left-width'] = visibleTabs ? '1px' : '0'; cMCSS[strCSS][4].style['margin-left'] = visibleTabs ? '-1px' : '0'; cMCSS[strCSS][2].style.cssText = "background-color: " + activeLineBG + " !important"; top.ICEcoder.lineWrapping = lineWrapping; top.ICEcoder.indentWithTabs = indentWithTabs; top.ICEcoder.indentSize = indentSize; for (var i=0;ichMod '+perms+' on
'+file); }, // Open/show the preview window openPreviewWindow: function() { if (top.ICEcoder.openFiles.length>0) { var cM, filepath, filename, fileExt; filepath = top.ICEcoder.openFiles[top.ICEcoder.selectedTab-1]; filename = filepath.substr(filepath.lastIndexOf("/")+1); fileExt = filename.substr(filename.lastIndexOf(".")+1); cM = ICEcoder.getcMInstance(); top.ICEcoder.previewWindow = window.open(filepath,"previewWindow"); if (["md"].indexOf(fileExt) > -1) { top.ICEcoder.previewWindow.onload = function() {top.ICEcoder.previewWindow.document.documentElement.innerHTML = mmd(cM.getValue())}; } else { top.ICEcoder.previewWindow.onload = function() { // Do the pesticide plugin if it exists try {top.ICEcoder.doPesticide();} catch(err) {}; } } } }, // Logout of ICEcoder logout: function() { window.location = window.location + "?logout&csrf="+top.ICEcoder.csrf; }, // Show a message message: function(msg) { alert(msg); }, // Ask for confirmation ask: function(question) { return confirm(question); }, // Get the users input getInput: function(question,defaultValue) { return prompt(question,defaultValue); }, // Show a data screen message dataMessage: function(message) { var dM; dM = top.ICEcoder.content.contentWindow.document.getElementById('dataMessage'); dM.style.display = "block"; dM.innerHTML = message; }, // Update ICEcoder update: function() { var autoUpdate; autoUpdate = confirm(top.t['Please note for...']); if (autoUpdate) { top.ICEcoder.showHide('show',top.get('loadingMask')); window.location = "lib/updater.php"; } else { window.open("https://icecoder.net"); } }, // XHR object xhrObj: function(){ try {return new XMLHttpRequest();}catch(e){} try {return new ActiveXObject("Msxml3.XMLHTTP");}catch(e){} try {return new ActiveXObject("Msxml2.XMLHTTP.6.0");}catch(e){} try {return new ActiveXObject("Msxml2.XMLHTTP.3.0");}catch(e){} try {return new ActiveXObject("Msxml2.XMLHTTP");}catch(e){} try {return new ActiveXObject("Microsoft.XMLHTTP");}catch(e){} return null; }, // Open bug report openBugReport: function() { var bugReportOpenFilePos; if(top.ICEcoder.bugReportStatus=="off") { top.ICEcoder.message(top.t['You can start...']); } if(top.ICEcoder.bugReportStatus=="error") { top.ICEcoder.message(top.t['Error cannot find...']); } if(top.ICEcoder.bugReportStatus=="ok") { top.ICEcoder.message(top.t['No new errors...']); } if(top.ICEcoder.bugReportStatus=="bugs") { // Close bug-report without saving previousFiles and without confirming close if we made changes on the bug report var bugReportOpenFilePos = top.ICEcoder.openFiles.indexOf(top.ICEcoder.bugReportPath.replace(/\|/g,"/")); if (bugReportOpenFilePos > -1) { top.ICEcoder.closeTab(bugReportOpenFilePos+1,'dontSetPV','dontAsk'); } top.ICEcoder.openFile(top.ICEcoder.bugReportPath); top.ICEcoder.bugFilesSizesSeen = top.ICEcoder.bugFilesSizesActual; } }, // Start bug checking by looking in bug file paths on a timer startBugChecking: function() { var bugCheckURL; if (top.ICEcoder.bugFileCheckTimer !== 0) { // Clear any existing interval if ("undefined" != typeof top.ICEcoder.bugFileCheckInt) { clearInterval(top.ICEcoder.bugFileCheckInt); } // Start a new timer top.ICEcoder.bugFilesSizesSeen = []; top.ICEcoder.bugFileCheckInt = setInterval(function() { bugCheckURL = "lib/bug-files-check.php?"; bugCheckURL += "files="+(top.ICEcoder.bugFilePaths[0] !== "" ? top.ICEcoder.bugFilePaths.join() : "null").replace(/\//g,"|"); bugCheckURL += "&filesSizesSeen="; if (top.ICEcoder.bugFilesSizesSeen.length != top.ICEcoder.bugFilePaths.length) { // Fill the array with nulls for (var i=0; i/g, ">") .replace(/"/g, """) .replace(/'/g, "'"); }, // Print code of current tab printCode: function() { var cM, printIFrame; cM = top.ICEcoder.getcMInstance(); printIFrame = top.ICEcoder.filesFrame.contentWindow.frames['fileControl']; // Print page content injected into iFrame, escaped with pre and xssClean printIFrame.window.document.body.innerHTML = 'ICEcoder code output
'+top.ICEcoder.xssClean(cM.getValue())+'
'; printIFrame.focus(); printIFrame.print(); // Focus back on code cM.focus(); }, // Update the title tag to indicate any changes indicateChanges: function() { var winTitle; if (!top.ICEcoder.loadingFile) { winTitle = "ICEcoder v "+top.ICEcoder.versionNo; for(var i=1;i<=top.ICEcoder.savedPoints.length;i++) { if (top.ICEcoder.savedPoints[i-1]!=top.ICEcoder.getcMInstance(i).changeGeneration()) { // We have an unsaved tab, indicate that in the title winTitle += " \u2744"; break; } } top.document.title = winTitle; } }, // ============== // TABS // ============== // Change tabs by switching visibility of instances switchTab: function(newTab,noFocus) { var cM; // Identify tab that's currently selected & get the instance ICEcoder.selectedTab = newTab; cM = ICEcoder.getcMInstance(); if (cM) { // Switch mode to HTML, PHP, CSS etc ICEcoder.switchMode(); // Set all cM instances to be hidden, then make our selected instance visible for (var i=0;i'; top.get('tab'+(top.ICEcoder.openFiles.length)).style.display = "inline-block"; fileName = top.ICEcoder.openFiles[top.ICEcoder.openFiles.length-1]; top.get('tab'+(top.ICEcoder.openFiles.length)).innerHTML = closeTabLink + " " + fileName.slice(fileName.lastIndexOf("/")).replace(/\//,""); top.get('tab'+(top.ICEcoder.openFiles.length)).title = "/" + top.ICEcoder.openFiles[top.ICEcoder.openFiles.length-1].replace(/\//,""); // Set the widths top.ICEcoder.setTabWidths(); // Highlight it and state it's selected top.ICEcoder.redoTabHighlight(top.ICEcoder.openFiles.length); top.ICEcoder.selectedTab=top.ICEcoder.openFiles.length; // Add a new value ready to indicate if this content has been changed top.ICEcoder.savedPoints.push(0); top.ICEcoder.setPreviousFiles(); }, // Cycle to next tab nextTab: function() { var goToTab; goToTab = top.ICEcoder.selectedTab+1 <= top.ICEcoder.openFiles.length ? top.ICEcoder.selectedTab+1 : 1; top.ICEcoder.switchTab(goToTab,'noFocus'); }, // Cycle to next tab previousTab: function() { var goToTab; goToTab = top.ICEcoder.selectedTab-1 >= 1 ? top.ICEcoder.selectedTab-1 : top.ICEcoder.openFiles.length; top.ICEcoder.switchTab(goToTab,'noFocus'); }, // Create a new tab for a file renameTab: function(tabNum,newName) { var closeTabLink, fileName; // Push new file into array top.ICEcoder.openFiles[tabNum-1] = newName; // Setup a new tab closeTabLink = ''; fileName = top.ICEcoder.openFiles[tabNum-1]; top.get('tab'+tabNum).innerHTML = closeTabLink + " " + fileName.slice(fileName.lastIndexOf("/")).replace(/\//,""); top.get('tab'+tabNum).title = "/" + top.ICEcoder.openFiles[tabNum-1].replace(/\//,""); }, // Reset all tabs to be without a highlight and then highlight the selected redoTabHighlight: function(selectedTab) { var tColor, fileLink; for(var i=1;i<=ICEcoder.savedPoints.length;i++) { if (top.get('tab'+i).childNodes[0]) { top.get('tab'+i).childNodes[0].childNodes[0].style.backgroundColor = ICEcoder.savedPoints[i-1]!=top.ICEcoder.getcMInstance(i).changeGeneration() ? "#b00" : "transparent"; } tColor = i==selectedTab ? top.ICEcoder.tabFGselected : top.ICEcoder.tabFGnormalTab; if ("undefined" != typeof top.ICEcoder.openFiles[i-1] && top.ICEcoder.openFiles[i-1] != "/[NEW]") { fileLink = top.ICEcoder.filesFrame.contentWindow.document.getElementById(top.ICEcoder.openFiles[i-1].replace(/\//g,"|")); if (fileLink) { fileLink.style.backgroundColor = i==selectedTab ? top.ICEcoder.tabBGcurrent : top.ICEcoder.tabBGopen; fileLink.style.color = i==selectedTab ? top.ICEcoder.tabFGcurrent : top.ICEcoder.tabFGopenFile; }; } top.get('tab'+i).style.color = tColor; top.get('tab'+i).style.background = i==selectedTab ? top.ICEcoder.tabBGcurrent : top.ICEcoder.tabBGopen; } }, // Close the tab upon request closeTab: function(closeTabNum, dontSetPV, dontAsk) { var cM, okToRemove, closeFileName; // If we haven't specified, close current tab if (!closeTabNum) {closeTabNum = top.ICEcoder.selectedTab}; cM = ICEcoder.getcMInstance(); okToRemove = true; if (!dontAsk && ICEcoder.savedPoints[closeTabNum-1]!=top.ICEcoder.getcMInstance(closeTabNum).changeGeneration()) { okToRemove = top.ICEcoder.ask(top.t['You have made...']); } if (okToRemove) { // Get the filename of tab we're closing closeFileName = top.ICEcoder.openFiles[closeTabNum-1]; // recursively copy over all tabs & data from the tab to the right, if there is one for (var i=closeTabNum;i0 ? ICEcoder.selectedTab-=1 : ICEcoder.selectedTab = 0; } if (ICEcoder.openFiles.length>0 && ICEcoder.selectedTab==0) {ICEcoder.selectedTab=1}; // grey out the view icon if (ICEcoder.openFiles.length==0) { top.ICEcoder.fMIconVis('fMView',0.3); } else { // Switch the mode & the tab ICEcoder.switchMode(); ICEcoder.switchTab(ICEcoder.selectedTab); } // Highlight the selected tab after splicing the change state out of the array top.ICEcoder.savedPoints.splice(closeTabNum-1,1); top.ICEcoder.redoTabHighlight(ICEcoder.selectedTab); // Update the nesting indicator top.ICEcoder.getNestLocation('update'); // Remove any highlighting from the file manager top.ICEcoder.selectDeselectFile('deselect',top.ICEcoder.filesFrame.contentWindow.document.getElementById(closeFileName.replace(/\//g,"|"))); if (!dontSetPV) { top.ICEcoder.setPreviousFiles(); } // Update the title tag to indicate any changes top.ICEcoder.indicateChanges(); } // Lastly, stop it from trying to also switch tab top.ICEcoder.canSwitchTabs=false; // and set the widths top.ICEcoder.setTabWidths('posOnlyNewTab'); setTimeout(function() {top.ICEcoder.canSwitchTabs=true;},100); }, // Close all tabs closeAllTabs: function() { if (top.ICEcoder.cMInstances.length>0 && ICEcoder.ask(top.t['Close all tabs'])) { for (var i=top.ICEcoder.cMInstances.length; i>0; i--) { top.ICEcoder.closeTab(i, i>1? true:false); } } // Update the title tag to indicate any changes top.ICEcoder.indicateChanges(); }, // Set the tabs width setTabWidths: function(posOnlyNewTab) { var availWidth, avgWidth, tabWidth, lastLeft, lastWidth; if (top.ICEcoder.ready) { availWidth = parseInt(top.ICEcoder.content.style.width,10)-53-22-10; // - left margin - new tab - right margin avgWidth = (availWidth/top.ICEcoder.openFiles.length)-18; tabWidth = -18; // Incl 18px offset lastLeft = 53; lastWidth = 0; top.ICEcoder.tabLeftPos = []; for (var i=0;i availWidth ? parseInt(avgWidth*i,10) - parseInt(avgWidth*(i-1),10) : 150; lastLeft = i==0 ? 53 : parseInt(top.get('tab'+(i)).style.left,10); lastWidth = i==0 ? 0 : parseInt(top.get('tab'+(i)).style.width,10)+18; if (!posOnlyNewTab) { top.get('tab'+(i+1)).style.left = (lastLeft+lastWidth) + "px"; top.get('tab'+(i+1)).style.width = tabWidth + "px"; } else { tabWidth = -18; } top.ICEcoder.tabLeftPos.push(lastLeft+lastWidth); } top.get('newTab').style.left = (lastLeft+lastWidth+tabWidth+18) + "px"; } }, // Tab dragging start tabDragStart: function(tab) { top.ICEcoder.draggingTab = tab; top.ICEcoder.diffStartX = top.ICEcoder.mouseX; top.ICEcoder.tabDragMouseXStart = (top.ICEcoder.mouseX - (parseInt(top.ICEcoder.files.style.width,10)+53+18)) % 150; // Put tab we're dragging over others top.get('tab'+tab).style.zIndex = 2; // Set classes for other tabs (tabSlide) and the one we're dragging (tabDrag) for (var i=1; i<=top.ICEcoder.openFiles.length; i++) { top.get('tab'+i).className = i!==tab ? "tab tabSlide" : "tab tabDrag"; } }, // Tab dragging tabDragMove: function() { var lastTabWidth, thisLeft, dragTabNo, tabWidth; lastTabWidth = parseInt(top.get('tab'+top.ICEcoder.openFiles.length).style.width,10)+18; // Set the left position but stay within left side (53) and new tab top.ICEcoder.thisLeft = thisLeft = top.ICEcoder.tabDragMouseX >= 53 ? top.ICEcoder.tabDragMouseX <= parseInt(top.get('newTab').style.left,10) - lastTabWidth ? top.ICEcoder.tabDragMouseX : (parseInt(top.get('newTab').style.left,10) - lastTabWidth) : 53; top.get('tab'+top.ICEcoder.draggingTab).style.left = thisLeft + "px"; top.ICEcoder.dragTabNo = dragTabNo = top.ICEcoder.draggingTab; // Set the opacities of tabs then positions of tabs we're not dragging for (var i=1; i<=top.ICEcoder.openFiles.length; i++) { top.get('tab'+i).style.opacity = i == top.ICEcoder.draggingTab ? 1 : 0.5; tabWidth = top.ICEcoder.tabLeftPos[i] ? top.ICEcoder.tabLeftPos[i] - top.ICEcoder.tabLeftPos[i-1] : tabWidth; if (i!=top.ICEcoder.draggingTab) { if (i < top.ICEcoder.draggingTab) { top.get('tab'+i).style.left = thisLeft <= top.ICEcoder.tabLeftPos[i-1] ? top.ICEcoder.tabLeftPos[i-1]+tabWidth : top.ICEcoder.tabLeftPos[i-1]; } else { top.get('tab'+i).style.left = thisLeft >= top.ICEcoder.tabLeftPos[i-1] ? top.ICEcoder.tabLeftPos[i-1]-tabWidth : top.ICEcoder.tabLeftPos[i-1]; } } } }, // Tab dragging end tabDragEnd: function() { var swapWith, tempArray; // Set the tab widths top.ICEcoder.setTabWidths(); // Determin what tabs we've swapped and reset classname, opacity & z-index for all for (var i=1; i<=top.ICEcoder.openFiles.length; i++) { if (top.ICEcoder.thisLeft >= top.ICEcoder.tabLeftPos[i-1]) { swapWith = top.ICEcoder.thisLeft == top.ICEcoder.tabLeftPos[0] ? 1 : top.ICEcoder.dragTabNo > i ? i+1 : i; } top.get('tab'+i).className = "tab"; top.get('tab'+i).style.opacity = 1; if (i!=top.ICEcoder.dragTabNo) { top.get('tab'+i).style.zIndex = 1; } else { setTimeout(function() { top.get('tab'+i).style.zIndex = 1; },150); } } if (top.ICEcoder.thisLeft && top.ICEcoder.thisLeft!==false) { // Make a number ascending array tempArray = []; for (var i=1;i<=top.ICEcoder.openFiles.length;i++) { tempArray.push(i); } // Then swap our tab numbers tempArray.splice(top.ICEcoder.dragTabNo-1,1); tempArray.splice(swapWith-1,0,top.ICEcoder.dragTabNo); // Now we have an order to sort against ICEcoder.sortTabs(tempArray); } top.ICEcoder.setTabWidths(); top.ICEcoder.draggingTab = false; top.ICEcoder.thisLeft = false; }, // Sort tabs into new order sortTabs: function(newOrder) { var a, b, savedPoints = [], openFiles = [], openFileMDTs = [], cMInstances = [], selectedTabWillBe; // Setup an array of our actual arrays and the blank ones a = [ICEcoder.savedPoints, ICEcoder.openFiles, ICEcoder.openFileMDTs, ICEcoder.cMInstances]; b = [savedPoints, openFiles, openFileMDTs, cMInstances]; // Push the new order values into array b then set into array a for (var i=0;i0) { var currentArray, currentArrayFull, alphaArray, nextValue, nextPos; currentArray = []; currentArrayFull = []; alphaArray = []; // Get filenames, full paths and set classname for sliding for (var i=0;i0) { nextValue = currentArray[0]; nextValueFull = currentArrayFull[0]; nextPos = 0; for (var i=0;i-1 ? top.contentFrame.codeFoldBrace(cM, line) : top.contentFrame.codeFoldTag(cM, line); return false; // ESC in content area (Comment/Uncomment line) } else if(key==27 && area == "content") { top.ICEcoder.lineCommentToggle(); return false; // ESC not in content area (Cancel all actions) } else if(key==27 && area != "content") { top.ICEcoder.cancelAllActions(); return false; // Any other key } else { return key; } } }, // Reset the state of keys back to the normal state resetKeys: function(evt) { top.ICEcoder.cmdKey = false; }, // Add snippet code completion addSnippet: function() { var cM, lineNo, whiteSpace, content; // Get line content after trimming whitespace cM = ICEcoder.getcMInstance(); lineNo = cM.getCursor().line; whiteSpace = cM.getLine(lineNo).length - cM.getLine(lineNo).replace(/^\s\s*/, '').length; content = cM.getLine(lineNo).slice(whiteSpace); // function snippet if (content.slice(0,8)=="function") { top.ICEcoder.doSnippet('function','function VAR() {\nINDENT\tCURSOR\nINDENT}'); // if snippet } else if (content.slice(0,2)=="if") { top.ICEcoder.doSnippet('if','if (CURSOR) {\nINDENT\t\nINDENT}'); // for snippet } else if (content.slice(0,3)=="for") { top.ICEcoder.doSnippet('for','for (var i=0; i-1) { // Get text on the line from our target to the end remainder = cM.getLine(lineNo); strPos = remainder.indexOf(tgtString); remainder = remainder.slice(remainder.indexOf(tgtString)+tgtString.length+1); // Replace the function name if any replaceString = replaceString.replace(/VAR/g,remainder); // Get replaced string from start to our strPos replacedLine = cM.getLine(lineNo).slice(0,strPos); // Trim whitespace from start whiteSpace = cM.getLine(lineNo).length - cM.getLine(lineNo).replace(/^\s\s*/, '').length; whiteSpace = cM.getLine(lineNo).slice(0,whiteSpace); // Replace indent with whatever whitespace we have replaceString = replaceString.replace(/INDENT/g,whiteSpace); replacedLine += replaceString; // Get cursor position curPos = replacedLine.indexOf("CURSOR"); sPos = 0; lineNoCount = lineNo; for (i=0;i