diff --git a/lib/ice-coder.js b/lib/ice-coder.js index 8f4be48..f2f35a7 100644 --- a/lib/ice-coder.js +++ b/lib/ice-coder.js @@ -51,11 +51,14 @@ var ICEcoder = { 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 + splitPane: false, // Single or split pane editing + debounce: "", // Contains debounce timeout object + editorFocusInstance: "", // Name of editor instance that has focus 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"]; + var aliasArray = ["header","files", "fileOptions", "optionsFile", "optionsEdit", "optionsRemote", "optionsHelp", "filesFrame","editor","tabsBar","findBar","content","footer","nestValid","nestDisplay","splitPaneControls","charDisplay","byteDisplay"]; // Create our ID aliases for (var i=0;i -1 ? top.ICEcoder.prevLineDiff : top.ICEcoder.prevLine; + if (thisCMPrevLine != thisCM.getCursor().line && + thisCM.getLine(thisCMPrevLine) && + thisCM.getLine(thisCMPrevLine).length > 0 && + thisCM.getLine(thisCMPrevLine).replace(/\s/g, '').length == 0) { + thisCM.replaceRange("",{line: thisCMPrevLine, ch: 0},{line: thisCMPrevLine, ch: 1000000}); + } + }, + + // On change + cMonChange: function(thisCM,cMinstance,changeObj) { + var filepath, filename, fileExt; + + // If we're not loading the file, it's a change, so update tab + if (!top.ICEcoder.loadingFile) { + top.ICEcoder.redoTabHighlight(top.ICEcoder.selectedTab); + } + top.ICEcoder.getCaretPosition(); + top.ICEcoder.dontUpdateNest = false; + top.ICEcoder.updateCharDisplay(); + top.ICEcoder.updateByteDisplay(); + top.ICEcoder.updateNestingIndicator(); + if (top.ICEcoder.findMode) { + top.ICEcoder.results.splice(top.ICEcoder.findResult,1); + top.document.getElementById('results').innerHTML = top.ICEcoder.results.length + " " + top.t['results']; + top.ICEcoder.findMode = false; + } + filepath = top.ICEcoder.openFiles[top.ICEcoder.selectedTab-1]; + if (filepath) { + filename = filepath.substr(filepath.lastIndexOf("/")+1); + fileExt = filename.substr(filename.lastIndexOf(".")+1); + for (var i=changeObj.from.line; i-1 ? "brace" : "xml" ,null ,"+" ,"-", true, thisCM, i); + } + if (changeObj.text[0] == "}" || changeObj.removed && changeObj.removed[0] == "}") { + cursor = thisCM.getSearchCursor("{",thisCM.getCursor(),false); + cursor.findPrevious(); + for (var i=cursor.from().line; i-1 ? "brace" : "xml" ,null ,"+" ,"-", true, thisCM, i); + } + } + } + if (top.ICEcoder.splitPane) { + top.ICEcoder.updateDiffs(); + } + // Update HTML edited files live + if (filepath && top.ICEcoder.previewWindow.location) { + top.ICEcoder.updatePreviewWindow(thisCM,filepath,filename,fileExt); + } + // Update the title tag to indicate any changes + top.ICEcoder.indicateChanges(); + }, + + // On input read + cMonInputRead: function(thisCM,cMinstance) { + if (top.ICEcoder.autoComplete == "keypress" && top.ICEcoder.codeAssist) { + clearTimeout(top.ICEcoder.debounce); + if (!thisCM.state.completionActive) { + top.ICEcoder.debounce = setTimeout(function() { + CodeMirror.commands.autocomplete(thisCM); + },200); + } + } + }, + + updateDiffs: function() { + var cM, cMdiff, mainText, diffText, sm, opcodes, cMmarks, markColor; + + cM = top.ICEcoder.getcMInstance(); + cMdiff = top.ICEcoder.getcMdiffInstance(); + + // Get the baseText and newText values from the two textboxes, and split them into lines + mainText = difflib.stringAsLines(cM.getValue()); + diffText = difflib.stringAsLines(cMdiff.getValue()); + + // Create a SequenceMatcher instance that diffs the two sets of lines + sm = new difflib.SequenceMatcher(mainText, diffText); + + // Get the opcodes from the SequenceMatcher instance + // Opcodes is a list of 3-tuples describing what changes should be made to the base text in order to yield the new text + opcodes = sm.get_opcodes(); + + cMmarks = cM.getAllMarks(); + for (var i=0; i -1) { + top.ICEcoder.previewWindow.document.documentElement.innerHTML = thisCM.getValue(); + } else if (["md"].indexOf(fileExt) > -1) { + top.ICEcoder.previewWindow.document.documentElement.innerHTML = mmd(thisCM.getValue()); + } + } else if (["css"].indexOf(fileExt) > -1) { + if (top.ICEcoder.previewWindow.document.documentElement.innerHTML.indexOf(filename) > -1) { + var css = thisCM.getValue(); + var style = document.createElement('style'); + style.type = 'text/css'; + style.id = "ICEcoder"+filepath.replace(/\//g,"_"); + if (style.styleSheet){ + style.styleSheet.cssText = css; + } else { + style.appendChild(document.createTextNode(css)); + } + if (top.ICEcoder.previewWindow.document.getElementById(style.id)) { + top.ICEcoder.previewWindow.document.documentElement.removeChild(top.ICEcoder.previewWindow.document.getElementById(style.id)); + } + top.ICEcoder.previewWindow.document.documentElement.appendChild(style); + } + } + // Do the pesticide plugin if it exists + try {top.ICEcoder.doPesticide();} catch(err) {}; + }, + // Clean up our loaded code contentCleanUp: function() { - var cM, content; + var cM, cMdiff, thisCM, content; // Replace any temp /textarea value cM = ICEcoder.getcMInstance(); - content = cM.getValue(); + cMdiff = ICEcoder.getcMdiffInstance(); + thisCM = top.ICEcoder.editorFocusInstance.indexOf('diff') > -1 ? cMdiff : cM; + content = thisCM.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(); + thisCM.setValue(content); + thisCM.clearHistory(); + top.ICEcoder.savedPoints[top.ICEcoder.selectedTab-1] = thisCM.changeGeneration(); }, // Undo last change undo: function() { - var cM; + var cM, cMdiff, thisCM; cM = ICEcoder.getcMInstance(); - cM.undo(); + cMdiff = ICEcoder.getcMdiffInstance(); + thisCM = top.ICEcoder.editorFocusInstance.indexOf('diff') > -1 ? cMdiff : cM; + thisCM.undo(); }, // Redo change redo: function() { - var cM; + var cM, cMdiff, thisCM; cM = ICEcoder.getcMInstance(); - cM.redo(); + cMdiff = ICEcoder.getcMdiffInstance(); + thisCM = top.ICEcoder.editorFocusInstance.indexOf('diff') > -1 ? cMdiff : cM; + thisCM.redo(); }, // Indent more/less indent: function(moreLess) { - var cM; + var cM, cMdiff, thisCM; cM = ICEcoder.getcMInstance(); + cMdiff = ICEcoder.getcMdiffInstance(); + thisCM = top.ICEcoder.editorFocusInstance.indexOf('diff') > -1 ? cMdiff : cM; if (moreLess=="more") { - top.ICEcoder.content.contentWindow.CodeMirror.commands.indentMore(cM); + top.ICEcoder.content.contentWindow.CodeMirror.commands.indentMore(thisCM); } else { - top.ICEcoder.content.contentWindow.CodeMirror.commands.indentLess(cM); + top.ICEcoder.content.contentWindow.CodeMirror.commands.indentLess(thisCM); } }, // Move current line up/down moveLines: function(dir) { - var cM, lineStart, lineEnd, swapLineNo, swapLine; + var cM, cMdiff, thisCM, lineStart, lineEnd, swapLineNo, swapLine; cM = top.ICEcoder.getcMInstance(); + cMdiff = top.ICEcoder.getcMdiffInstance(); + thisCM = top.ICEcoder.editorFocusInstance.indexOf('diff') > -1 ? cMdiff : cM; // Get start & end lines plus the line we'll swap with - lineStart = cM.getCursor('start'); - lineEnd = cM.getCursor('end'); + lineStart = thisCM.getCursor('start'); + lineEnd = thisCM.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}); + thisCM.replaceRange(thisCM.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}); + thisCM.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( + thisCM.setSelection( {line: lineStart.line+(dir=="up" ? -1 : 1), ch: lineStart.ch}, {line: lineEnd.line+(dir=="up" ? -1 : 1), ch: lineEnd.ch} ); @@ -271,46 +472,56 @@ var ICEcoder = { // Highlight specified line highlightLine: function(line) { - var cM; + var cM, cMdiff, thisCM; cM = top.ICEcoder.getcMInstance(); - cM.setSelection({line:line,ch:0}, {line:line,ch:cM.lineInfo(line).text.length}); + cMdiff = top.ICEcoder.getcMdiffInstance(); + thisCM = top.ICEcoder.editorFocusInstance.indexOf('diff') > -1 ? cMdiff : cM; + thisCM.setSelection({line:line,ch:0}, {line:line,ch:thisCM.lineInfo(line).text.length}); }, // Focus the editor - focus: function() { - var cM; + focus: function(diff) { + var cM, cMdiff, thisCM; if (!(/iPhone|iPad|iPod/i.test(navigator.userAgent))) { cM = top.ICEcoder.getcMInstance(); - if (cM) { - cM.focus(); + cMdiff = top.ICEcoder.getcMdiffInstance(); + thisCM = diff ? cMdiff : cM; + if (thisCM) { + thisCM.focus(); } } }, // Go to a specific line number goToLine: function(lineNo) { - var cM; + var cM, cMdiff, thisCM; cM = ICEcoder.getcMInstance(); - cM.setCursor(lineNo ? lineNo-1 : top.get('goToLineNo').value-1); + cMdiff = ICEcoder.getcMdiffInstance(); + thisCM = top.ICEcoder.editorFocusInstance.indexOf('diff') > -1 ? cMdiff : cM; + + thisCM.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; + var cM, cMdiff, thisCM, cursorPos, linePos, lineContent, lCLen, adjustCursor; cM = ICEcoder.getcMInstance(); - cursorPos = cM.getCursor().ch; - linePos = cM.getCursor().line; - lineContent = cM.getLine(linePos); + cMdiff = ICEcoder.getcMdiffInstance(); + thisCM = top.ICEcoder.editorFocusInstance.indexOf('diff') > -1 ? cMdiff : cM; + + cursorPos = thisCM.getCursor().ch; + linePos = thisCM.getCursor().line; + lineContent = thisCM.getLine(linePos); lCLen = lineContent.length; adjustCursor = 2; - ICEcoder.lineCommentToggleSub(cM, cursorPos, linePos, lineContent, lCLen, adjustCursor); + ICEcoder.lineCommentToggleSub(thisCM, cursorPos, linePos, lineContent, lCLen, adjustCursor); }, // Highlight or hide block upon roll over/out of nest positions @@ -388,116 +599,130 @@ var ICEcoder = { // Wrap our selected text/cursor with tags tagWrapper: function(tag) { - var cM, tagStart, tagEnd, startLine, endLine; + var cM, cMdiff, thisCM, tagStart, tagEnd, startLine, endLine; cM = ICEcoder.getcMInstance(); + cMdiff = ICEcoder.getcMdiffInstance(); + thisCM = top.ICEcoder.editorFocusInstance.indexOf('diff') > -1 ? cMdiff : cM; 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"); + startLine = thisCM.getCursor('start').line; + endLine = thisCM.getCursor().line; + thisCM.operation(function() { + thisCM.replaceSelection("
\n"+thisCM.getSelection()+"\n
","around"); for (var i=startLine+1; i<=endLine+1; i++) { - cM.indentLine(i); + thisCM.indentLine(i); } - cM.indentLine(endLine+2,'prev'); - cM.indentLine(endLine+2,'subtract'); + thisCM.indentLine(endLine+2,'prev'); + thisCM.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)) == "") { + thisCM.getSelection().substr(0,tag.length+1) == "<"+tagStart && + thisCM.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"); + thisCM.replaceSelection(thisCM.getSelection().substr(thisCM.getSelection().indexOf(">")+1,thisCM.getSelection().length-thisCM.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})} + thisCM.replaceSelection("<"+tagStart+">"+thisCM.getSelection()+"","around"); + if (tag=='a') {thisCM.setCursor({line:thisCM.getCursor('start').line,ch:thisCM.getCursor('start').ch+9})} } } }, // Add a line break at end of current or specified line addLineBreakAtEnd: function(line) { - var cM; + var cM,cMdiff, thisCM; cM = ICEcoder.getcMInstance(); - if (!line) {line = cM.getCursor().line}; - cM.replaceRange(cM.getLine(line)+"
",{line:line,ch:0},{line:line,ch:1000000}); + cMdiff = ICEcoder.getcMdiffInstance(); + thisCM = top.ICEcoder.editorFocusInstance.indexOf('diff') > -1 ? cMdiff : cM; + if (!line) {line = thisCM.getCursor().line}; + thisCM.replaceRange(thisCM.getLine(line)+"
",{line:line,ch:0},{line:line,ch:1000000}); }, // Insert a line before and auto-indent insertLineBefore: function(line) { - var cM; + var cM, cMdiff, thisCM; 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'); + cMdiff = ICEcoder.getcMdiffInstance(); + thisCM = top.ICEcoder.editorFocusInstance.indexOf('diff') > -1 ? cMdiff : cM; + if (!line) {line = thisCM.getCursor().line}; + thisCM.operation(function() { + thisCM.replaceRange("\n"+thisCM.getLine(line),{line:line,ch:0},{line:line,ch:1000000}); + thisCM.setCursor({line: thisCM.getCursor().line-1, ch: 0}); + thisCM.execCommand('indentAuto'); }); }, // Insert a line after and auto-indent insertLineAfter: function(line) { - var cM; + var cM, cMdiff, thisCM; 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'); + cMdiff = ICEcoder.getcMdiffInstance(); + thisCM = top.ICEcoder.editorFocusInstance.indexOf('diff') > -1 ? cMdiff : cM; + if (!line) {line = thisCM.getCursor().line}; + thisCM.operation(function() { + thisCM.replaceRange(thisCM.getLine(line)+"\n",{line:line,ch:0},{line:line,ch:1000000}); + thisCM.execCommand('indentAuto'); }); }, // Duplicate line duplicateLines: function(line) { - var cM, ch, lineExtra, userSelStart, userSelEnd, lineBreak; + var cM, cMdiff, thisCM, 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); + cMdiff = ICEcoder.getcMdiffInstance(); + thisCM = top.ICEcoder.editorFocusInstance.indexOf('diff') > -1 ? cMdiff : cM; + if (!line && thisCM.somethingSelected()) { + userSelStart = thisCM.getCursor('start'); + userSelEnd = thisCM.getCursor('end'); + lineExtra = userSelStart.line != userSelEnd.line && userSelEnd.ch == thisCM.getLine(userSelEnd.line).length ? "\n" : ""; + thisCM.replaceSelection(thisCM.getSelection()+lineExtra+thisCM.getSelection(), "end"); + thisCM.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); + if (!line) {line = thisCM.getCursor().line}; + ch = thisCM.getCursor().ch; + thisCM.replaceRange(thisCM.getLine(line)+"\n"+thisCM.getLine(line),{line:line,ch:0},{line:line,ch:1000000}); + thisCM.setCursor(line+1,ch); } }, // Remove line removeLines: function(line) { - var cM, ch; + var cM, cMdiff, thisCM, ch; cM = ICEcoder.getcMInstance(); - if (!line && cM.somethingSelected()) { - cM.replaceSelection("","end"); + cMdiff = ICEcoder.getcMdiffInstance(); + thisCM = top.ICEcoder.editorFocusInstance.indexOf('diff') > -1 ? cMdiff : cM; + if (!line && thisCM.somethingSelected()) { + thisCM.replaceSelection("","end"); } else { - if (!line) {line = cM.getCursor().line}; - ch = cM.getCursor().ch; - cM.execCommand('deleteLine'); - cM.setCursor(line-1,ch); + if (!line) {line = thisCM.getCursor().line}; + ch = thisCM.getCursor().ch; + thisCM.execCommand('deleteLine'); + thisCM.setCursor(line-1,ch); } }, // Jump to and highlight the function definition current token jumpToDefinition: function() { - var cM, tokenString, defVars; + var cM, cMdiff, thisCM, tokenString, defVars; cM = ICEcoder.getcMInstance(); - tokenString = cM.getTokenAt(cM.getCursor()).string; + cMdiff = ICEcoder.getcMdiffInstance(); + thisCM = top.ICEcoder.editorFocusInstance.indexOf('diff') > -1 ? cMdiff : cM; + tokenString = thisCM.getTokenAt(thisCM.getCursor()).string; - if (cM.somethingSelected() && top.ICEcoder.origCurorPos) { - cM.setCursor(top.ICEcoder.origCurorPos); + if (thisCM.somethingSelected() && top.ICEcoder.origCurorPos) { + thisCM.setCursor(top.ICEcoder.origCurorPos); } else { - top.ICEcoder.origCurorPos = cM.getCursor(); + top.ICEcoder.origCurorPos = thisCM.getCursor(); defVars = [ "var "+tokenString, "function "+tokenString, @@ -518,32 +743,41 @@ var ICEcoder = { // Autocomplete autocomplete: function() { - var cM; + var cM, cMdiff, thisCM; cM = ICEcoder.getcMInstance(); - top.ICEcoder.content.contentWindow.CodeMirror.commands.autocomplete(cM); + cMdiff = ICEcoder.getcMdiffInstance(); + thisCM = top.ICEcoder.editorFocusInstance.indexOf('diff') > -1 ? cMdiff : cM; + top.ICEcoder.content.contentWindow.CodeMirror.commands.autocomplete(thisCM); }, // Paste a URL, locally or absolutely if CTRL/Cmd key down pasteURL: function(url) { - var cM; + var cM, cMdiff, thisCM; - cM = ICEcoder.getcMInstance(); + cM = top.ICEcoder.getcMInstance(); + cMdiff = top.ICEcoder.getcMdiffInstance(); + thisCM = top.ICEcoder.editorFocusInstance.indexOf('diff') > -1 ? cMdiff : cM; if(top.ICEcoder.draggingWithKey == "CTRL") { url = window.location.protocol + "//" + window.location.hostname + url; } - cM.replaceSelection(url,"around"); + thisCM.replaceSelection(url,"around"); }, // Search for selected text online searchForSelected: function() { + var cM, cMdiff, thisCM; + + cM = top.ICEcoder.getcMInstance(); + cMdiff = top.ICEcoder.getcMdiffInstance(); + thisCM = top.ICEcoder.editorFocusInstance.indexOf('diff') > -1 ? cMdiff : cM; if (top.ICEcoder.caretLocType) { - if (top.ICEcoder.getcMInstance().getSelection() != "") { + if (thisCM.getSelection() != "") { var searchPrefix = top.ICEcoder.caretLocType.toLowerCase()+" "; if (top.ICEcoder.caretLocType=="Content") { searchPrefix = ""; } - window.open("http://www.google.com/#output=search&q="+searchPrefix+top.ICEcoder.getcMInstance().getSelection()); + window.open("http://www.google.com/#output=search&q="+searchPrefix+thisCM.getSelection()); } else { top.ICEcoder.message(top.t['No text selected...']); } @@ -1176,7 +1410,7 @@ var ICEcoder = { // 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; + var find, replace, results, cM, cMdiff, thisCM, content, scrollBarVisible, cursor, avgBlockH, addPadding, rBlocks, blockColor, replaceQS, targetQS, filesQS; // Determine our find & replace strings and results display find = findString.toLowerCase(); @@ -1185,20 +1419,22 @@ var ICEcoder = { // If we have something to find in currrent document cM = ICEcoder.getcMInstance(); - if (cM && find.length>0 && document.findAndReplace.target.value==top.t['this document']) { - content = cM.getValue().toLowerCase(); + cMdiff = ICEcoder.getcMdiffInstance(); + thisCM = top.ICEcoder.editorFocusInstance.indexOf('diff') > -1 ? cMdiff : cM; + if (thisCM && find.length>0 && document.findAndReplace.target.value==top.t['this document']) { + content = thisCM.getValue().toLowerCase(); // Find & replace the next instance, or all? if (document.findAndReplace.connector.value==top.t['and'] && buttonClick) { - if (document.findAndReplace.replaceAction.value==top.t['replace'] && cM.getSelection().toLowerCase()==find) { - cM.replaceSelection(replace,"around"); + if (document.findAndReplace.replaceAction.value==top.t['replace'] && thisCM.getSelection().toLowerCase()==find) { + thisCM.replaceSelection(replace,"around"); } else if (document.findAndReplace.replaceAction.value==top.t['replace all']) { var rExp = new RegExp(find,"gi"); - cM.setValue(cM.getValue().replace(rExp,replace)); + thisCM.setValue(thisCM.getValue().replace(rExp,replace)); } } // Get the content again, as it might of changed - content = cM.getValue().toLowerCase(); + content = thisCM.getValue().toLowerCase(); if (!top.ICEcoder.findMode||find!=top.ICEcoder.lastsearch) { ICEcoder.results = []; ICEcoder.resultsLines = []; @@ -1206,8 +1442,8 @@ var ICEcoder = { for (var i=0;i0) { // Detect if we have a scrollbar - scrollBarVisible = cM.getScrollInfo().height > cM.getScrollInfo().clientHeight; + scrollBarVisible = thisCM.getScrollInfo().height > thisCM.getScrollInfo().clientHeight; // Show results only if (resultsOnly) { @@ -1229,7 +1465,7 @@ var ICEcoder = { // Find our cursor position relative to results ICEcoder.findResult = 0; for (var i=0;i-1 ? cM.getCursor().line+1 == i ? "#b00" : "#888" : "transparent" + for (var i=1; i<=thisCM.lineCount(); i++) { + blockColor = ICEcoder.resultsLines.indexOf(i)>-1 ? thisCM.getCursor().line+1 == i ? "#b00" : "#888" : "transparent" rBlocks += '
'; } top.ICEcoder.content.contentWindow.document.getElementById('resultsBar').innerHTML = rBlocks; @@ -1312,14 +1548,17 @@ var ICEcoder = { // Work out the nesting depth location on demand and update our display if required getNestLocation: function(updateNestDisplay) { - var cM, nestCheck, state, cx, startPos, fileName; + var cM, cMdiff, thisCM, nestCheck, state, cx, startPos, fileName; cM = ICEcoder.getcMInstance(); - if (cM) { - nestCheck = cM.getValue(); + cMdiff = ICEcoder.getcMdiffInstance(); + thisCM = top.ICEcoder.editorFocusInstance.indexOf('diff') > -1 ? cMdiff : cM; + + if (thisCM) { + nestCheck = thisCM.getValue(); // Get the token state at our cursor - state = cM.getTokenAt(cM.getCursor()).state; + state = thisCM.getTokenAt(thisCM.getCursor()).state; cx = false; // XML @@ -1360,14 +1599,17 @@ var ICEcoder = { // Get the caret position getCaretPosition: function() { - var cM, line, ch, chPos; + var cM, cMdiff, thisCM, line, ch, chPos; cM = ICEcoder.getcMInstance(); - line = cM.getCursor().line; - ch = cM.getCursor().ch; + cMdiff = ICEcoder.getcMdiffInstance(); + thisCM = top.ICEcoder.editorFocusInstance.indexOf('diff') > -1 ? cMdiff : cM; + + line = thisCM.getCursor().line; + ch = thisCM.getCursor().ch; chPos = 0; for (var i=0;i -1 ? cMdiff : cM; ICEcoder.caretLocationType(); - ICEcoder.charDisplay.innerHTML = ICEcoder.caretLocType + ", Line: " + (cM.getCursor().line+1) + ", Char: " + cM.getCursor().ch; + ICEcoder.charDisplay.innerHTML = ICEcoder.caretLocType + ", Line: " + (thisCM.getCursor().line+1) + ", Char: " + thisCM.getCursor().ch; }, // Update the byte display updateByteDisplay: function() { - ICEcoder.byteDisplay.innerHTML = ICEcoder.getcMInstance().getValue().length.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") + " bytes"; + var cM, cMdiff, thisCM; + + cM = ICEcoder.getcMInstance(); + cMdiff = ICEcoder.getcMdiffInstance(); + thisCM = top.ICEcoder.editorFocusInstance.indexOf('diff') > -1 ? cMdiff : cM; + ICEcoder.byteDisplay.innerHTML = thisCM.getValue().length.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") + " bytes"; }, // Toggle the char/byte display @@ -1412,6 +1661,21 @@ var ICEcoder = { ]; }, + // Determine the CodeMirror instance we're using + getcMdiffInstance: function(tab) { + return top.ICEcoder.content.contentWindow[ + (// target specific tab + !isNaN(tab) + ? 'cM'+ICEcoder.cMInstances[tab-1] + // new tab or selected tab + : tab=="new"||(tab!="new" && ICEcoder.openFiles.length>0) + ? 'cM'+ICEcoder.cMInstances[ICEcoder.selectedTab-1] + // fallback to first tab + : 'cM1') + + 'diff' + ]; + }, + // Get the mouse position getMouseXY: function(e,area) { var tempX, tempY; @@ -1475,14 +1739,17 @@ var ICEcoder = { // Show a CSS color block next to our text cursor cssColorPreview: function() { - var cM, string, rx, match, oldBlock, newBlock; + var cM, cMdiff, thisCM, string, rx, match, oldBlock, newBlock; cM = ICEcoder.getcMInstance(); - if (cM) { - string = cM.getLine(cM.getCursor().line); + cMdiff = ICEcoder.getcMdiffInstance(); + thisCM = top.ICEcoder.editorFocusInstance.indexOf('diff') > -1 ? cMdiff : cM; + + if (thisCM) { + string = thisCM.getLine(thisCM.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); + while((match = rx.exec(string)) && thisCM.getCursor().ch > match.index+match[0].length); oldBlock = top.get('content').contentWindow.document.getElementById('cssColor'); if (oldBlock) {oldBlock.parentNode.removeChild(oldBlock)}; @@ -1498,7 +1765,7 @@ var ICEcoder = { 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); + thisCM.addWidget(thisCM.getCursor(), top.get('cssColor'), true); } } }, @@ -1574,11 +1841,13 @@ var ICEcoder = { // Insert new color value insertColorValue: function(color) { - var cM, cursor; + var cM, cMdiff, thisCM, 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}); + cMdiff = ICEcoder.getcMdiffInstance(); + thisCM = top.ICEcoder.editorFocusInstance.indexOf('diff') > -1 ? cMdiff : cM; + cursor = thisCM.getTokenAt(thisCM.getCursor()); + thisCM.replaceRange(color,{line:thisCM.getCursor().line,ch:cursor.start},{line:thisCM.getCursor().line,ch:1000000}); }, // Change opacity of the file manager icons @@ -1844,10 +2113,18 @@ var ICEcoder = { top.ICEcoder.indentWithTabs = indentWithTabs; top.ICEcoder.indentSize = indentSize; for (var i=0;i0) { - var cM, filepath, filename, fileExt; + var cM, cMdiff, thisCM, 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(); + cMdiff = ICEcoder.getcMdiffInstance(); + thisCM = top.ICEcoder.editorFocusInstance.indexOf('diff') > -1 ? cMdiff : cM; 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())}; + top.ICEcoder.previewWindow.onload = function() {top.ICEcoder.previewWindow.document.documentElement.innerHTML = mmd(thisCM.getValue())}; } else { top.ICEcoder.previewWindow.onload = function() { // Do the pesticide plugin if it exists @@ -2093,16 +2372,18 @@ var ICEcoder = { // Print code of current tab printCode: function() { - var cM, printIFrame; + var cM, cMdiff, thisCM, printIFrame; cM = top.ICEcoder.getcMInstance(); + cMdiff = top.ICEcoder.getcMdiffInstance(); + thisCM = top.ICEcoder.editorFocusInstance.indexOf('diff') > -1 ? cMdiff : cM; 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.window.document.body.innerHTML = 'ICEcoder code output
'+top.ICEcoder.xssClean(thisCM.getValue())+'
'; printIFrame.focus(); printIFrame.print(); // Focus back on code - cM.focus(); + thisCM.focus(); }, // Update the title tag to indicate any changes @@ -2128,26 +2409,32 @@ var ICEcoder = { // Change tabs by switching visibility of instances switchTab: function(newTab,noFocus) { - var cM; + var cM, cMdiff, thisCM; // Identify tab that's currently selected & get the instance ICEcoder.selectedTab = newTab; cM = ICEcoder.getcMInstance(); + cMdiff = ICEcoder.getcMdiffInstance(); + thisCM = top.ICEcoder.editorFocusInstance.indexOf('diff') > -1 ? cMdiff : cM; - if (cM) { + if (thisCM) { // 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 -1 ? true : false); } return false; @@ -2718,13 +3007,15 @@ var ICEcoder = { // Add snippet code completion addSnippet: function() { - var cM, lineNo, whiteSpace, content; + var cM, cMdiff, thisCM, 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); + cMdiff = ICEcoder.getcMdiffInstance(); + thisCM = top.ICEcoder.editorFocusInstance.indexOf('diff') > -1 ? cMdiff : cM; + lineNo = thisCM.getCursor().line; + whiteSpace = thisCM.getLine(lineNo).length - thisCM.getLine(lineNo).replace(/^\s\s*/, '').length; + content = thisCM.getLine(lineNo).slice(whiteSpace); // function snippet if (content.slice(0,8)=="function") { top.ICEcoder.doSnippet('function','function VAR() {\nINDENT\tCURSOR\nINDENT}'); @@ -2739,26 +3030,28 @@ var ICEcoder = { // Action a snippet doSnippet: function(tgtString,replaceString) { - var cM, lineNo, lineContents, remainder, strPos, replacedLine, whiteSpace, curPos, sPos, lineNoCount; + var cM, cMdiff, thisCM, lineNo, lineContents, remainder, strPos, replacedLine, whiteSpace, curPos, sPos, lineNoCount; // Get line contents - cM = top.ICEcoder.getcMInstance(); - lineNo = cM.getCursor().line; - lineContents = cM.getLine(lineNo); + cM = ICEcoder.getcMInstance(); + cMdiff = ICEcoder.getcMdiffInstance(); + thisCM = top.ICEcoder.editorFocusInstance.indexOf('diff') > -1 ? cMdiff : cM; + lineNo = thisCM.getCursor().line; + lineContents = thisCM.getLine(lineNo); // Find our target string if (lineContents.indexOf(tgtString)>-1) { // Get text on the line from our target to the end - remainder = cM.getLine(lineNo); + remainder = thisCM.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); + replacedLine = thisCM.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); + whiteSpace = thisCM.getLine(lineNo).length - thisCM.getLine(lineNo).replace(/^\s\s*/, '').length; + whiteSpace = thisCM.getLine(lineNo).slice(0,whiteSpace); // Replace indent with whatever whitespace we have replaceString = replaceString.replace(/INDENT/g,whiteSpace); replacedLine += replaceString; @@ -2773,10 +3066,10 @@ var ICEcoder = { } } // Clear the cursor string and set the cursor there - cM.replaceRange(replacedLine.replace("CURSOR",""),{line:lineNo,ch:0},{line:lineNo,ch:1000000}); - cM.setCursor(lineNoCount,curPos); + thisCM.replaceRange(replacedLine.replace("CURSOR",""),{line:lineNo,ch:0},{line:lineNo,ch:1000000}); + thisCM.setCursor(lineNoCount,curPos); // Finally, focus on the editor - top.ICEcoder.focus(); + top.ICEcoder.focus(top.ICEcoder.editorFocusInstance.indexOf('diff') > -1 ? true : false); } } }; \ No newline at end of file