// 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 the files pane minFilesW: 14, // Min width of the files pane maxFilesW: 250, // Max width of the files pane selectedTab: 0, // The tab that's currently selected changedContent: [], // Binary array to indicate which tabs have changed 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 codeAssist: true, // Assist user with their coding mouseDown: false, // If the mouse is down or not draggingFilesW: false, // If we're dragging the file manager width or not draggingTab: false, // If we're dragging a tab tabLeftPos: [], // Left position of tabs inside content area tabBGcurrent: '#141414', // BG of current tab tabBGselected: '#49d', // BG of selected tab tabBGopen: '#aaa', // 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: '#000', // 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 ready: false, // Indicates if ICEcoder is ready for action // Set our aliases initAliases: function() { var aliasArray = ["header","files","account","fmLock","filesFrame","editor","tabsBar","findBar","content","footer","system","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.account.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.get('fmLock'); ICEcoder.lockedNav = ICEcoder.lockedNav ? false : true; lockIcon.style.backgroundPosition = ICEcoder.lockedNav ? "-64px -16px" : "-80px -16px"; }, // ============== // EDITOR // ============== // Clean up our loaded code contentCleanUp: function() { var fileName, cM, content; // If it's not a JS, CoffeeScript, CSS or LESS file, replace our temp /textarea value fileName = ICEcoder.openFiles[ICEcoder.selectedTab-1]; if (["js","coffee","css","less"].indexOf(fileName.split(".")[1])<0) { 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(); } }, // Move current line up/down moveLine: function(dir) { var cM, line, swapLineNo, swapLine; cM = top.ICEcoder.getcMInstance(); line = cM.getCursor().line; if (dir=="up" && line>0) {swapLineNo = line-1} if (dir=="down" && line0 ? cM.setOption("mode","javascript") : fileName.indexOf('.coffee')>0 ? cM.setOption("mode","coffeescript") : fileName.indexOf('.rb')>0 ? cM.setOption("mode","ruby") : fileName.indexOf('.py')>0 ? cM.setOption("mode","python") : fileName.indexOf('.css')>0 ? cM.setOption("mode","css") : fileName.indexOf('.less')>0 ? cM.setOption("mode","less") : fileName.indexOf('.md')>0 ? cM.setOption("mode","markdown") : cM.setOption("mode","application/x-httpd-php"); } }, // Comment/uncomment line or selected range on keypress lineCommentToggle: function() { var cM, cursorPos, linePos, lineContent, lCLen, adjustCursor, startLine, endLine; cM = ICEcoder.getcMInstance(); cursorPos = cM.getCursor().ch; linePos = cM.getCursor().line; lineContent = cM.getLine(linePos); lCLen = lineContent.length; adjustCursor = 2; if (["JavaScript","CoffeeScript","PHP","Python","Ruby","CSS"].indexOf(ICEcoder.caretLocType)>-1) { if (cM.somethingSelected()) { if (ICEcoder.caretLocType=="Ruby"||ICEcoder.caretLocType=="Python") { startLine = cM.getCursor(true).line; endLine = cM.getCursor().line; for (var i=startLine; i<=endLine; i++) { cM.setLine(i, cM.getLine(i).slice(0,1)!="#" ? "#" + cM.getLine(i) : cM.getLine(i).slice(1,cM.getLine(i).length)); } } else { cM.replaceSelection(cM.getSelection().slice(0,2)!="/*" ? "/*" + cM.getSelection() + "*/" : cM.getSelection().slice(2,cM.getSelection().length-2)); } } else { if (["CoffeeScript","CSS"].indexOf(ICEcoder.caretLocType)>-1) { cM.setLine(linePos, lineContent.slice(0,2)!="/*" ? "/*" + lineContent + "*/" : lineContent.slice(2,lCLen).slice(0,lCLen-4)); if (lineContent.slice(0,2)=="/*") {adjustCursor = -adjustCursor}; } else if (ICEcoder.caretLocType=="Ruby") { cM.setLine(linePos, lineContent.slice(0,1)!="#" ? "#" + lineContent : lineContent.slice(1,lCLen)); if (lineContent.slice(0,1)=="#") {adjustCursor = -adjustCursor}; } else { cM.setLine(linePos, lineContent.slice(0,2)!="//" ? "//" + lineContent : lineContent.slice(2,lCLen)); if (lineContent.slice(0,2)=="//") {adjustCursor = -adjustCursor}; } } } else { if (cM.somethingSelected()) { cM.replaceSelection(cM.getSelection().slice(0,4)!="<\!--" ? "<\!--" + cM.getSelection() + "//-->" : cM.getSelection().slice(4,cM.getSelection().length-5)); } else { cM.setLine(linePos, lineContent.slice(0,4)!="<\!--" ? "<\!--" + lineContent + "//-->" : lineContent.slice(4,lCLen).slice(0,lCLen-9)); adjustCursor = lineContent.slice(0,4)=="<\!--" ? -4 : 4; } } if (!cM.somethingSelected()) {cM.setCursor(linePos, cursorPos+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.tagRangeFinder(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); cM.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
"); for (var i=startLine+1; i<=endLine+1; i++) { cM.indentLine(i); } cM.indentLine(endLine+2,'prev'); cM.indentLine(endLine+2,'subtract'); }); } else { if (tag=='a') {tagStart='a href=""';} cM.replaceSelection("<"+tagStart+">"+cM.getSelection()+""); } 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.setLine(line,cM.getLine(line)+"
"); }, // Duplicate line duplicateLine: function(line) { var cM, ch; cM = ICEcoder.getcMInstance(); if (!line) {line = cM.getCursor().line}; ch = cM.getCursor().ch; cM.setLine(line,cM.getLine(line)+"\n"+cM.getLine(line)); cM.setCursor(line+1,ch); }, // Remove line removeLine: function(line) { var cM, ch; cM = ICEcoder.getcMInstance(); if (!line) {line = cM.getCursor().line}; ch = cM.getCursor().ch; cM.removeLine(line); 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]; startFile = shortURL < lastFileClicked ? shortURL : lastFileClicked; endFile = shortURL > lastFileClicked ? 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); } } // 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"; // Finally, show or grey out the relevant file manager icons top.ICEcoder.fMIconVis('fMOpen',top.ICEcoder.selectedFiles.length == 1 ? 1 : 0.3); top.ICEcoder.fMIconVis('fMNewFile',top.ICEcoder.selectedFiles.length == 1 && top.ICEcoder.thisFileFolderType == "folder" ? 1 : 0.3); top.ICEcoder.fMIconVis('fMNewFolder',top.ICEcoder.selectedFiles.length == 1 && top.ICEcoder.thisFileFolderType == "folder" ? 1 : 0.3); top.ICEcoder.fMIconVis('fMDelete',top.ICEcoder.selectedFiles.length > 0 ? 1 : 0.3); top.ICEcoder.fMIconVis('fMRename',top.ICEcoder.selectedFiles.length == 1 ? 1 : 0.3); // 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.rightClickedFile.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,"|")); top.ICEcoder.serverMessage('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.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) { // check if we've already got it in our array if (top.ICEcoder.openFiles.indexOf(shortURL)>-1 && shortURL!="/[NEW]") { // we have, so instead, switch to that tab canOpenFile = false; top.ICEcoder.switchTab(i+1); } } else { // show a message because we have 100 files open top.ICEcoder.message('Sorry, you can only have 100 files open at a time!'); 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); top.ICEcoder.serverMessage('Opening File
'+top.ICEcoder.shortURL); } else { top.ICEcoder.createNewTab(); } top.ICEcoder.fMIconVis('fMView',1); } } }, // Show file prompt to open file openPrompt: function() { var fileLink; if(fileLink = top.ICEcoder.getInput('Enter relative file path (prefixed with /) or remote URL','')) { fileLink.indexOf("://")>-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); top.ICEcoder.serverMessage('Getting
'+remoteFile); }, // Save a file saveFile: function(saveAs) { var saveType, filePath; saveType = saveAs ? "saveAs" : "save"; filePath = ICEcoder.openFiles[ICEcoder.selectedTab-1].replace(top.iceRoot,"").replace(/\//g,"|"); if (filePath=="|[NEW]" && top.ICEcoder.selectedFiles.length>0) { filePath = top.ICEcoder.selectedFiles[0]+filePath; } filePath = filePath.replace("||","|"); top.ICEcoder.serverQueue("add","lib/file-control.php?action=save&file="+filePath+"&fileMDT="+ICEcoder.openFileMDTs[ICEcoder.selectedTab-1]+"&saveType="+saveType); top.ICEcoder.serverMessage('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.rightClickedFile.replace(/\|/g,"/"); oldName = top.ICEcoder.rightClickedFile.replace(/\|/g,"/"); } else { shortURL = oldName.replace(/\|/g,"/"); } if (!newName) { newName = top.ICEcoder.getInput('Please enter the new name for',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,"/")); top.ICEcoder.serverMessage('Renaming to
'+newName); top.ICEcoder.setPreviousFiles(); } }, // Delete a file deleteFile: function() { var delFiles, selectedFilesList; if (top.ICEcoder.selectedFiles.length>0) { delFiles = top.ICEcoder.ask('Delete:\n\n'+top.ICEcoder.selectedFiles.toString().replace(/\|/g,"/").replace(/,/g,"\n")+'?'); } if (delFiles) { selectedFilesList = ""; for (var i=0;iDeleting File
'+top.ICEcoder.selectedFiles.toString().replace(/\|/g,"/").replace(/,/g,"\n")); }; }, // Copy a file copyFile: function(selFile) { top.ICEcoder.copiedFiles = []; for (var i=0; iPasting File
'+top.ICEcoder.copiedFiles[i].toString().replace(/\|/g,"/").replace(/,/g,"\n")); } } else { top.ICEcoder.message("Nothing to paste, copy a file/folder first!"); } }, // 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')); document.getElementById('uploadFilesForm').submit(); event.preventDefault(); } }, // Show menu on right clicking in file manager showMenu: function(evt) { var menuType, folderMenuItems; if ( top.ICEcoder.selectedFiles.length == 0 || top.ICEcoder.selectedFiles.indexOf(top.ICEcoder.rightClickedFile.replace(/\//g,"|")) == -1) { top.ICEcoder.selectFileFolder(evt); } if ("undefined" != typeof top.ICEcoder.thisFileFolderLink && top.ICEcoder.thisFileFolderLink!="") { menuType = top.ICEcoder.selectedFiles[0].indexOf(".")>-1 ? "file" : "folder"; folderMenuItems = top.get('folderMenuItems'); folderMenuItems.style.display = menuType == "folder" && top.ICEcoder.selectedFiles.length == 1 ? "block" : "none"; singleFileMenuItems.style.display = top.ICEcoder.selectedFiles.length > 1 ? "none" : "block"; document.getElementById('fileMenu').style.display = "inline-block"; setTimeout(function() {document.getElementById('fileMenu').style.opacity = "1"},4); document.getElementById('fileMenu').style.left = (top.ICEcoder.mouseX+20) + "px"; document.getElementById('fileMenu').style.top = (top.ICEcoder.mouseY-top.ICEcoder.filesFrame.contentWindow.document.body.scrollTop-10) + "px"; } return false; }, // Continue to show the file manager showFileMenu: function() { document.getElementById('fileMenu').style.display='inline-block'; setTimeout(function() {document.getElementById('fileMenu').style.opacity = "1"},4); }, // Hide the file manager hideFileMenu: function() { document.getElementById('fileMenu').style.display='none'; document.getElementById('fileMenu').style.opacity = "0"; }, // Update the file manager tree list on demand updateFileManagerList: function(action,location,file,perms,oldName,uploaded) { var actionElemType, cssStyle, perms, targetElem, locNest, newText, innerLI, newUL, newLI, elemType, nameLI, shortURL, newMouseOver; // Adding files if (action=="add" && !document.getElementById('filesFrame').contentWindow.document.getElementById(location.replace(/\/$/, "").replace(/\//g,"|")+"|"+file)) { // Is this is a file or folder and based on that, set the CSS styling & link actionElemType = file.indexOf(".")>-1 ? "file" : "folder"; 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 = document.getElementById('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.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;i<=locNest.childNodes.length-1;i++) { if (locNest.childNodes[i].className) { // Identify if the item we're considering is a file or folder elemType = locNest.childNodes[i].className.indexOf('directory')>0 ? "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.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 = document.getElementById('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 = document.getElementById('filesFrame').contentWindow.document.getElementById(shortURL+"_perms"); targetElemPerms.id = location.replace(/\//g,"|") + "|" + file + "_perms"; } // Chmod on files if (action=="chmod") { // Get short URL for our file and get our target elem based on this shortURL = top.ICEcoder.rightClickedFile.replace(/\|/g,"/"); targetElem = document.getElementById('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 = document.getElementById('filesFrame').contentWindow.document.getElementById(location.replace(/\/$/, "").replace(/\//g,"|")+"|"+file).parentNode.parentNode; targetElem.parentNode.removeChild(targetElem); } }, // Carry out actions when clicking icons above file manager fMIcon: function(action) { if (action=="save" && ICEcoder.openFiles.length>0) { top.ICEcoder.saveFile(); } if (ICEcoder.selectedFiles.length==1) { top.ICEcoder.rightClickedFile=top.ICEcoder.thisFileFolderLink=top.ICEcoder.selectedFiles[0].replace('|','/'); if (action=="open" && ICEcoder.selectedFiles[0].indexOf(".")>-1) { top.ICEcoder.thisFileFolderType='file'; top.ICEcoder.openFile(); } else if (action=="newFile") {top.ICEcoder.newFile();} else if (action=="newFolder") {top.ICEcoder.newFolder();} else if (action=="rename") {top.ICEcoder.renameFile(top.ICEcoder.rightClickedFile);} } if (action=="delete" && ICEcoder.selectedFiles.length>0) { top.ICEcoder.deleteFile(); } if (action=="view" && ICEcoder.openFiles.length>0) { window.open(top.ICEcoder.openFiles[top.ICEcoder.selectedTab-1]); } }, // Refresh file manager refreshFileManager: function() { top.ICEcoder.showHide('show',top.get('loadingMask')); top.ICEcoder.filesFrame.src="files.php"; top.ICEcoder.filesFrame.style.opacity="0"; top.ICEcoder.filesFrame.onload = function() { top.ICEcoder.filesFrame.style.opacity="1"; top.ICEcoder.showHide('hide',top.get('loadingMask')); } }, // ============== // 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, lineCount, numChars, charsToCursor, charCount, cursor, replaceQS, targetQS; // Determine our find & replace strings and the length of them 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") { if (document.findAndReplace.replaceAction.value=="replace" && cM.getSelection().toLowerCase()==find) { cM.replaceSelection(replace); } else if (document.findAndReplace.replaceAction.value=="replace all" && buttonClick) { 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 = []; for (var i=0;i0) { // Show results only if (resultsOnly) { results.innerHTML = ICEcoder.results.length + " results"; // We need to take action instead } else { lineCount=1; numChars=0; // Count the no of chars & lines previous to our cursor's line for (var i=0;iICEcoder.results.length-1) {ICEcoder.findResult=0}; results.innerHTML = "Highlighted result "+(ICEcoder.findResult+1)+" of "+ICEcoder.results.length+" results"; lineCount=0; for (var i=0;i=0) { targetQS = "&target="+document.findAndReplace.target.value.replace(/ /g,"-"); } if (document.findAndReplace.target.value=="selected files") { filesQS = "&selectedFiles="; for(i=0;i'; } } }, // 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); top.ICEcoder.serverMessage('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, events; cM = ICEcoder.getcMInstance(); if (cM) { nestCheck = cM.getValue(); // Set up array to store nest data state = cM.getTokenAt(cM.getCursor()).state; if ("undefined" != typeof state.curState && "undefined" != typeof state.curState.htmlState) { ICEcoder.htmlTagArray = []; for (cx = state.curState.htmlState.context; 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]; if (["js","coffee","css","less"].indexOf(fileName.split(".")[1])<0 && (nestCheck.indexOf("include(")==-1)&&(nestCheck.indexOf("include_once(")==-1)&& (nestCheck.indexOf("-1||nestCheck.indexOf("-1)) { // Then for all the array items, output as the nest display for (var i=0;i'}; ICEcoder.nestDisplay.innerHTML += ''+ICEcoder.htmlTagArray[i]+''; ICEcoder.nestDisplay.innerHTML += i' : '
'; } if ("undefined" != typeof state.curState && ICEcoder.htmlTagArray.length > 0) { ICEcoder.nestDisplay.innerHTML += ''+(state.curState.tagName ? state.curState.tagName : 'content')+''; } } } } } }, // Indicate if the nesting structure of the code is OK updateNestingIndicator: function () { var cM, nestOK, fileName; cM = ICEcoder.getcMInstance(); nestOK = true; fileName = ICEcoder.openFiles[ICEcoder.selectedTab-1]; if (cM && fileName && ["js","coffee","css","less"].indexOf(fileName.split(".")[1])==-1) { nestOK = cM.getTokenAt({line:cM.lineCount(),ch:cM.lineInfo(cM.lineCount()-1).text.length}).className != "error" ? true : false; } ICEcoder.nestValid.style.background = nestOK ? "#0b0" : "#f00"; ICEcoder.nestValid.title = nestOK ? "Nesting OK" : "Nesting Broken"; }, // Get the caret position getCaretPosition: function() { var cM, content, line, ch, chPos, chCount; cM = ICEcoder.getcMInstance(); content = cM.getValue(); line = cM.getCursor().line; ch = cM.getCursor().ch; chPos = 0; for (var i=0;icaretChunk.lastIndexOf("")&&caretLocType=="Unknown") {caretLocType = "JavaScript"} else if (caretChunk.lastIndexOf("caretChunk.lastIndexOf("?>")&&caretLocType=="Unknown") {caretLocType = "PHP"} else if (caretChunk.lastIndexOf("<%")>caretChunk.lastIndexOf("%>")&&caretLocType=="Unknown") {caretLocType = "Ruby"} else if (caretChunk.lastIndexOf("<")>caretChunk.lastIndexOf(">")&&caretLocType=="Unknown") {caretLocType = "HTML"} else if (caretLocType=="Unknown") {caretLocType = "Content"}; fileName = ICEcoder.openFiles[ICEcoder.selectedTab-1]; if (fileName) { if (fileName.indexOf(".js")>0) {caretLocType="JavaScript"} else if (fileName.indexOf(".coffee")>0) {caretLocType="CoffeeScript"} else if (fileName.indexOf(".py")>0) {caretLocType="Python"} else if (fileName.indexOf(".rb")>0) {caretLocType="Ruby"} else if (fileName.indexOf(".css")>0) {caretLocType="CSS"} else if (fileName.indexOf(".less")>0) {caretLocType="LESS"} else if (fileName.indexOf(".md")>0) {caretLocType="Markdown"}; } ICEcoder.caretLocType = caretLocType; }, // Alter array indicating which files have changed redoChangedContent: function(evt) { var cM, key; cM = ICEcoder.getcMInstance(); key = evt.keyCode ? evt.keyCode : evt.which ? evt.which : evt.charCode; // Exclude a few keys... // Escape (27), Caps Lock (20), Shift, CTRL, Alt, Pause/Break (16-19), Left, Up, Right, Down (37-40), Num Lock, Scroll Lock (144-145), // Insert, Delete (45,46), Page Up, Page Down, End, Home (33-36), Left Win Key, Right Win Key (91-92), F1-F12 (112-123) if (!evt.ctrlKey && key!=27 && key!=20 && (key<16||key>19) && (key<37||key>40) && (key!=144||key!=145) && (key!=45||key!=46) && (key<33||key>36) && (key!=91||key!=92) && (key<112||key>123)) { ICEcoder.changedContent[ICEcoder.selectedTab-1] = cM.historySize().undo > 0 ? 1 : 0; ICEcoder.redoTabHighlight(ICEcoder.selectedTab); } }, // Show & hide target element showHide: function(doVis,elem) { elem.style.visibility = doVis=="show" ? 'visible' : 'hidden'; }, // Determine the CodeMirror instance we're using getcMInstance: function(newTab) { return top.ICEcoder.content.contentWindow[ newTab=="new"||(newTab!="new" && ICEcoder.openFiles.length>0) ? 'cM'+ICEcoder.cMInstances[ICEcoder.selectedTab-1] : 'cM1' ]; }, // Get the mouse position getMouseXY: function(e,area) { var tempX, tempY, scrollTop; top.ICEcoder.mouseX = e.pageX ? e.pageX : e.clientX + document.body.scrollLeft; top.ICEcoder.mouseY = e.pageY ? e.pageY : e.clientY + document.body.scrollTop; if (area!="top") { top.ICEcoder.mouseY += 40 + 50; } 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 winH, cursorName, diffX, zone; 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(); } } if (top.ICEcoder.ready) { winH = window.innerWidth ? window.innerHeight : document.body.clientHeight; 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.mouseY > 40 && top.ICEcoder.mouseY < (winH-30)) || 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 = document.getElementById('serverMessage'); if (message) { serverMessage.innerHTML = message; 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(); 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 = document.getElementById('canvasPicker').getContext('2d'); img = new Image(); img.src = imgThis.src; img.onload = function() { document.getElementById('canvasPicker').width = imgThis.width; document.getElementById('canvasPicker').height = imgThis.height; canvas.drawImage(img,0,0,imgThis.width,imgThis.height); } // Show pointer colors on mouse move over canvas document.getElementById('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 document.getElementById('rgbMouseXY').value = rgb; document.getElementById('hexMouseXY').value = '#' + hex; document.getElementById('hexMouseXY').style.backgroundColor = document.getElementById('rgbMouseXY').style.backgroundColor = '#' + hex; textColor = R<128 || G<128 || B<128 && (R<200 && G<200 && B>50) ? '#fff' : '#000'; document.getElementById('hexMouseXY').style.color = document.getElementById('rgbMouseXY').style.color = textColor; }; // Set pointer colors on clicking canvas document.getElementById('canvasPicker').onclick = function() { document.getElementById('rgb').value = document.getElementById('rgbMouseXY').value; document.getElementById('hex').value = document.getElementById('hexMouseXY').value; document.getElementById('hex').style.backgroundColor = document.getElementById('rgb').style.backgroundColor = document.getElementById('hex').value; document.getElementById('hex').style.color = document.getElementById('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:cursor.end}); }, // 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 i!=-1 ? i : false; }, // Show JS Hint errors updateHints: function() { var cM; if ("undefined" != typeof JSHINT && top.ICEcoder.openFiles[top.ICEcoder.selectedTab-1].indexOf('.js')>-1) { cM = ICEcoder.getcMInstance(); cM.operation(function(){ var widgets = top.ICEcoder['cM'+top.ICEcoder.cMInstances[top.ICEcoder.selectedTab-1]+'widgets']; for (var i=0; i -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.ICEcoder.cssColorPreview(); cM.focus(); if (!top.ICEcoder.codeAssist) { for (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); document.getElementById('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('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); }, // Opens the last files we had open autoOpenFiles: function() { if (top.ICEcoder.previousFiles.length>0 && top.ICEcoder.ask('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')); }, // Update the settings used when we make a change to them useNewSettings: function(themeURL,codeAssist,lockedNav,visibleTabs,fontSize,lineWrapping,indentWithTabs,indentSize,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 = ["eclipse","elegant","neat"].indexOf(top.ICEcoder.theme)>-1 ? "#ccc": "#000"; top.ICEcoder.switchTab(top.ICEcoder.selectedTab); // Check/uncheck Code Assist setting top.get('codeAssist').checked = codeAssist; // 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[3]; strCSS = cMCSS.rules ? 'rules' : 'cssRules'; cMCSS[strCSS][0].style['fontSize'] = fontSize; cMCSS[strCSS][5].style['content'] = visibleTabs ? '"\\21e5"' : '" "'; cMCSS[strCSS][2].style.cssText = "background: " + activeLineBG + " !important"; top.ICEcoder.lineWrapping = lineWrapping; top.ICEcoder.indentWithTabs = indentWithTabs; top.ICEcoder.indentSize = indentSize; for (var i=0;ichMod '+perms+' on
'+file.replace(top.iceRoot,"")); }, // 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())}; } } }, // Open a new terminal window openTerminal: function() { top.ICEcoder.demoMode ? top.ICEcoder.message('Sorry, you need to be logged in to use the terminal') : window.open('terminal'); }, // Logout of ICEcoder logout: function() { window.location = window.location + "?logout"; }, // 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; }, // ============== // 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.changedContent.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.changedContent.length;i++) { if (document.getElementById('tab'+i).childNodes[0]) { document.getElementById('tab'+i).childNodes[0].childNodes[0].style.backgroundColor = ICEcoder.changedContent[i-1]==1 ? "#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; }; } document.getElementById('tab'+i).style.color = tColor; document.getElementById('tab'+i).style.background = i==selectedTab ? top.ICEcoder.tabBGcurrent : top.ICEcoder.tabBGopen; } top.ICEcoder.fMIconVis('fMSave',ICEcoder.changedContent[selectedTab-1]==1 ? 1 : 0.3); }, // Close the tab upon request closeTab: function(closeTabNum, dontSetPV, dontAsk) { var cM, okToRemove, closeFileName; cM = ICEcoder.getcMInstance(); okToRemove = true; if (!dontAsk && ICEcoder.changedContent[closeTabNum-1]==1) { okToRemove = top.ICEcoder.ask('You have made changes.\n\nAre you sure you want to close without saving?'); } 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.changedContent.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(); } } // 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("Close all tabs?")) { for (var i=top.ICEcoder.cMInstances.length; i>0; i--) { top.ICEcoder.closeTab(i, i>1? true:false); } } }, // 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)-41-24-10; // - left margin - new tab - right margin avgWidth = (availWidth/top.ICEcoder.openFiles.length)-18; tabWidth = -18; // Incl 18px offset lastLeft = 41; lastWidth = 0; top.ICEcoder.tabLeftPos = []; for (var i=0;i availWidth ? parseInt(avgWidth*i,10) - parseInt(avgWidth*(i-1),10) : 150; lastLeft = i==0 ? 41 : 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)+41+18)) % 150; top.get('tab'+tab).style.zIndex = 2; 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; top.ICEcoder.thisLeft = thisLeft = top.ICEcoder.tabDragMouseX >= 41 ? top.ICEcoder.tabDragMouseX <= parseInt(top.get('newTab').style.left,10) - lastTabWidth ? top.ICEcoder.tabDragMouseX : (parseInt(top.get('newTab').style.left,10) - lastTabWidth) : 41; top.get('tab'+top.ICEcoder.draggingTab).style.left = thisLeft + "px"; top.ICEcoder.dragTabNo = dragTabNo = top.ICEcoder.draggingTab; 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; top.ICEcoder.setTabWidths(); 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) { tempArray = []; for (var i=1;i<=top.ICEcoder.openFiles.length;i++) { tempArray.push(i); } tempArray.splice(top.ICEcoder.dragTabNo-1,1); tempArray.splice(swapWith-1,0,top.ICEcoder.dragTabNo); 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, changedContent = [], openFiles = [], openFileMDTs = [], cMInstances = [], selectedTabWillBe; a = [ICEcoder.changedContent, ICEcoder.openFiles, ICEcoder.openFileMDTs, ICEcoder.cMInstances]; b = [changedContent, openFiles, openFileMDTs, cMInstances]; for (var i=0;i0) { var currentArray, currentArrayFull, alphaArray, nextValue, nextPos; currentArray = []; currentArrayFull = []; alphaArray = []; for (var i=0;i0) { nextValue = currentArray[0]; nextValueFull = currentArrayFull[0]; nextPos = 0; for (var i=0;i-1) { remainder = cM.getLine(lineNo); strPos = remainder.indexOf(tgtString); remainder = remainder.slice(remainder.indexOf(tgtString)+tgtString.length); replaceString = replaceString.replace(/VAR/g,remainder); replacedLine = cM.getLine(lineNo).slice(0,strPos); whiteSpace = cM.getLine(lineNo).length - cM.getLine(lineNo).replace(/^\s\s*/, '').length; whiteSpace = cM.getLine(lineNo).slice(0,whiteSpace); replaceString = replaceString.replace(/INDENT/g,whiteSpace); replacedLine += replaceString; curPos = replacedLine.indexOf("CURSOR"); sPos = 0; lineNoCount = lineNo; for (i=0;i