diff --git a/lib/ice-coder.js b/lib/ice-coder.js index 1387d69..7b98a85 100644 --- a/lib/ice-coder.js +++ b/lib/ice-coder.js @@ -28,6 +28,7 @@ var ICEcoder = { scrollbarVisible: false, // Indicates if the main pane has a scrollbar mouseDown: false, // If the mouse is down mouseDownInCM: false, // If the mouse is down within CodeMirror instance (can be false, 'editor' or 'gutter') + mouseDownMinimap: false, // If the mouse is down on Minimap nav box 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 @@ -42,6 +43,8 @@ var ICEcoder = { tabFGnormalFile: '#eee', // FG of normal file tabFGnormalTab: '#888', // FG of normal tab serverQueueItems: [], // Array of URLs to call in order + miniMapBoxTop: 0, // Top of the minimap box highlighter + miniMapBoxHeight: 0, // Height of the minimap box highlighter previewWindow: false, // Target variable for the preview window previewWindowLoading: false, // Loading state of preview window pluginIntervalRefs: [], // Array of plugin interval refs @@ -66,7 +69,7 @@ var ICEcoder = { // Set our aliases initAliases: function() { - var aliasArray = ["header","files", "fileOptions", "optionsFile", "optionsEdit", "optionsSource", "optionsHelp", "filesFrame", "editor", "tabsBar", "findBar", "content", "footer", "nestValid", "versionsDisplay", "splitPaneControls", "splitPaneNamesMain", "splitPaneNamesDiff", "charDisplay", "byteDisplay"]; + var aliasArray = ["header","files", "fileOptions", "optionsFile", "optionsEdit", "optionsSource", "optionsHelp", "filesFrame", "editor", "tabsBar", "findBar", "content", "footer", "nestValid", "versionsDisplay", "splitPaneControls", "splitPaneNamesMain", "splitPaneNamesDiff", "charDisplay", "byteDisplay", "docExplorer", "miniMap", "miniMapContainer", "miniMapContent", "functionClassList"]; // Create our ID aliases for (var i=0;i parseInt(get('docExplorer').style.height,10)) { + // Set the minimap container to same height + get('miniMapContainer').style.height = parseInt(get('docExplorer').style.height,10)+"px"; + // Set box height relative to font height + top.ICEcoder.miniMapBoxHeight = parseInt(get('docExplorer').style.height,10)/cM.defaultTextHeight()*2; + get('miniMapBox').style.height = top.ICEcoder.miniMapBoxHeight + "px"; + // Set top position of it according to percentage through document and account for height of nav box + top.ICEcoder.miniMapBoxTop = (percThru*parseInt(get('docExplorer').style.height,10)) - (percThru*top.ICEcoder.miniMapBoxHeight); + // Set the minimap position according to scroll position (used if we move cursor in document) + get('miniMapContent').style.marginTop = (-(parseInt(get('miniMapContent').getBoundingClientRect().height,10) - parseInt(get('docExplorer').style.height,10))*percThru) + "px"; + // If less than the docExplorer height + } else { + // Set height of container to that of the content + get('miniMapContainer').style.height = parseInt(get('miniMapContent').getBoundingClientRect().height,10)+"px"; + // Set box height relative to font height + top.ICEcoder.miniMapBoxHeight = parseInt(get('docExplorer').style.height,10)/cM.defaultTextHeight()*2; + get('miniMapBox').style.height = top.ICEcoder.miniMapBoxHeight + "px"; + // Set top position of it according to percentage through minimap and account for height of nav box + top.ICEcoder.miniMapBoxTop = (percThru*parseInt(get('miniMap').getBoundingClientRect().height,10)) - (percThru*top.ICEcoder.miniMapBoxHeight); + // Set the minimap position to 0 + get('miniMapContent').style.marginTop = 0; + } + // Can set the Minimap nav position if not dragging it (let Draggabilly handle that) + if (!top.ICEcoder.mouseDownMinimap) { + get('miniMapBox').style.top = top.ICEcoder.miniMapBoxTop + "px"; + } + } + }, + // On scroll cMonScroll: function(thisCM,cMinstance) { var cM, cMdiff, otherCM; @@ -531,8 +600,7 @@ var ICEcoder = { // Scroll other pane x & y to match this one we're scrolling, after a 0ms tickover to avoid judder setTimeout(function(){otherCM.scrollTo(thisCM.getScrollInfo().left, thisCM.getScrollInfo().top);},0); } - } - + } }, // On input read @@ -1053,6 +1121,115 @@ var ICEcoder = { } } } + }, + + // Update function & class list { + updateFunctionClassList: function() { + var cM, functionClassList; + + cM = ICEcoder.getcMInstance(); + top.ICEcoder.functionClassList = []; + + if(cM) { + // For each line, establish if there's a function or class item on it + cM.doc.eachLine(function(handle){top.ICEcoder.updateFunctionClassListItems(handle)}); + // Update the list displayed + setTimeout(function() { + functionClassList = ''; + // For each of the items in our array, if it's verified, add it into string + for (var i=0; i'+top.ICEcoder.functionClassList[i]['name']+'
'+top.ICEcoder.functionClassList[i]['params']+''; + } + } + // Update our list + get('functionClassList').innerHTML = functionClassList; + },0); + } + }, + + setMinimap: function() { + var cM; + + cM = ICEcoder.getcMInstance(); + top.ICEcoder.functionClassList = []; + + if(cM) { + top.ICEcoder.content.contentWindow.CodeMirror.runMode(cM.getValue(),"application/x-httpd-php",get('miniMapContent')); + // white-space: pre; vs pre-wrap + get('miniMapContent').innerHTML = '
'+get('miniMapContent').innerHTML+'
'; + get('miniMapContent').innerHTML = get('miniMapContent').innerHTML.replace(/\'; + + if (!top.ICEcoder.minimapNav) { + + var elem = get('miniMapBox'); + var draggie = new Draggabilly( elem, { + axis: 'y', + containment: true + }); + + draggie.on( 'dragMove', function( event, pointer, moveVector ) { + yPos = this.position.y; + maxHeight = parseInt(get('docExplorer').style.height,10) <= parseInt(get('miniMapContent').getBoundingClientRect().height,10) + ? parseInt(get('docExplorer').style.height,10) + : parseInt(get('miniMapContent').getBoundingClientRect().height,10); + newPerc = (this.position.y/(maxHeight-top.ICEcoder.miniMapBoxHeight)); + yPos = (cM.getScrollInfo().height-cM.getScrollInfo().clientHeight)*newPerc; + cM.scrollTo(0,yPos); // this.position.y + }); + draggie.on( 'pointerDown', function( event, pointer ) { + top.ICEcoder.mouseDownMinimap = true; + }); + draggie.on( 'pointerUp', function( event, pointer ) { + top.ICEcoder.mouseDownMinimap = false; + }); + top.ICEcoder.minimapNav = true; + } + } + }, + + updateFunctionClassListItems: function(x) { + var cM; + + cM = ICEcoder.getcMInstance(); + functionClassText = ""; + if (x.text.indexOf("function ") > -1 && x.text.replace(/\$function/g,"").indexOf("function ") > -1) { + functionClassText = x.text.substring(x.text.indexOf("function ") + 9); + } + if (x.text.indexOf("class ") > -1 && x.text.replace(/\$class/g,"").indexOf("class ") > -1) { + functionClassText = x.text.substring(x.text.indexOf("class ") + 6); + } + functionClassText = functionClassText.trim().split("{")[0].split("("); + + if (functionClassText[0] != "") { + top.ICEcoder.functionClassList.push({ + line: cM.getLineNumber(x), + name: functionClassText[0], + params: "("+functionClassText[1], + verified: false + }); + setTimeout(function() { + if (!x.styles || (x.styles && x.styles.indexOf('def') > -1 && cM.getLineNumber(x))) { + //if (x.styles && x.styles.indexOf('def') > -1 && cM.getLineNumber(x)) { + for (var i=0; i< top.ICEcoder.functionClassList.length; i++) { + if (top.ICEcoder.functionClassList[i]['line'] == cM.getLineNumber(x)) { + top.ICEcoder.functionClassList[i]['verified'] = true; + } + }; + } + + + },0); + } + + + + }, // Autocomplete @@ -2957,6 +3134,11 @@ var ICEcoder = { styleNode.setAttribute('type', 'text/css'); styleNode.setAttribute('href', themeURL); top.ICEcoder.content.contentWindow.document.getElementsByTagName('head')[0].appendChild(styleNode); + styleNode = document.createElement('link'); + styleNode.setAttribute('rel', 'stylesheet'); + styleNode.setAttribute('type', 'text/css'); + styleNode.setAttribute('href', themeURL); + top.document.getElementsByTagName('head')[0].appendChild(styleNode); if (["3024-day","base16-light","eclipse","elegant","mdn-like","neat","neo","paraiso-light","solarized","the-matrix","xq-light"].indexOf(top.ICEcoder.theme)>-1) { activeLineBG = "#ccc"; } else if (["3024-night","blackboard","colorforth","liquibyte","night","tomorrow-night-bright","tomorrow-night-eighties","vibrant-ink"].indexOf(top.ICEcoder.theme)>-1) { @@ -3381,6 +3563,15 @@ var ICEcoder = { cM.refresh(); cMdiff.refresh(); + top.ICEcoder.updateFunctionClassList(); + // Update the minimap nav + if ("undefined" != typeof top.doMiniNav) { + clearTimeout(top.doMiniNav); + } + top.doMiniNav = setTimeout(function() { + top.ICEcoder.setMinimap(); + },top.ICEcoder.loadingFile ? 0 : 100); + // Highlight the selected tab ICEcoder.redoTabHighlight(ICEcoder.selectedTab);