onBeforeDrop: function(e) { if (!(window.File && window.FileReader/* && window.FormData*/)) { util.alert( "Could not upload file(s)", "An error occurred while dropping this file(s)", "Your browser does not offer support for drag and drop for file uploads. " + "Please try with a recent version of Chrome or Firefox." ); return false; } /** Dropped item is a folder */ if (e.dataTransfer.files.length == 0) { ext.initExtension(this); winNoFolderSupport.show(); if (!apf.isWebkit) btnNoFolderSupportOpenDialog.hide(); return false; } var files = e.dataTransfer.files; if (!(this.checkUploadSize(files) && this.checkNumberOfFiles(files))) return false; if (e.dataTransfer.files.length < 1) return false; this.onDrop(e); return true; },
showInput : function(temporary){ if (!this.hiddenInput) return; ext.initExtension(this); this.$collapsedHeight = this.collapsedHeight; if (this.hidden) winDbgConsole.setAttribute("height", this.collapsedHeight + "px") txtConsoleInput.parentNode.show(); apf.layout.forceResize(); if (temporary) { var _self = this; txtConsoleInput.addEventListener("blur", function(){ if (_self.hiddenInput) _self.hideInput(true); txtConsoleInput.removeEventListener("blur", arguments.callee); }); txtConsoleInput.focus() } else { settings.model.setQueryValue("auto/console/@showinput", true); this.hiddenInput = false; } },
hook: function() { var mnuView = menus.addItemByPath("View"); this.nodes.push(mnuView.appendChild(new apf.item({ caption: 'GPanel', onclick: __bind(function() { this.gpanel(); }, this) }))); // Trying this location as well commands.addCommand({ name: "gpanelShow", bindKey : { mac : "Ctrl-Shift-G", win : "Ctrl-Shift-G" }, exec: function(e){ gpanelWindow.show(); } }); commands.addCommand({ name: "studentBuild", exec: __bind(function() { this.nativeCompile(); }, this) }); ext.initExtension(this); },
saveas : function(page, callback){ if (!page || !page.$at) page = tabEditors.getPage(); if (!page) return; var path = page ? page.$model.data.getAttribute("path") : false; if (!path) return; ext.initExtension(this); if (callback) { var doc = page.$doc; ide.addEventListener("afterfilesave", function(e){ if (e.doc == doc) { callback(); this.removeEventListener("afterfilesave", arguments.callee); } }); } var fooPath = path.split('/'); txtSaveAs.setValue(fooPath.pop()); lblPath.setProperty('caption', fooPath.join('/') + '/'); winSaveAs.show(); },
onDrop: function(e) { ext.initExtension(this); var dt = e.dataTransfer; var files = dt.files; this.startUpload(files); },
activate : function(){ ext.initExtension(this); this.nodes.each(function(item){ if (item.show) item.show(); }); },
hook : function () { // when unloading the window window.onbeforeunload = this.onBeforeUnloadHandler; require("ext/settings/settings").addSettings("General", markupSettings ); // init extension ext.initExtension(this); },
toggleDialog: function(forceShow) { ext.initExtension(this); if (!winGoToFile.visible || forceShow) winGoToFile.show(); else winGoToFile.hide(); return false; },
exec: function () { if (!_self.isGeneric) _self.toggleDialog(1); else { ext.initExtension(_self); winGoToFile.visible = true; winGoToFile.hide(); winBlockGotoFile.show(); } }
toggle: function() { if (editors.currentEditor.path !== "ext/code/code") return; ext.initExtension(this); if (this.panel.visible) this.hide(); else this.show(); },
tabEditors.addEventListener("close", this.$close = function(e) { var at = e.page.$at; if (!at.undo_ptr) at.undo_ptr = at.$undostack[0]; var node = e.page.$doc.getNode(); if (node && at.undo_ptr && at.$undostack[at.$undostack.length-1] !== at.undo_ptr || !at.undo_ptr && node.getAttribute("changed") == 1 && e.page.$doc.getValue()) { ext.initExtension(_self); var pages = tabEditors.getPages(), currIdx = pages.indexOf(e.page); tabEditors.set(pages[currIdx].id); //jump to file var filename = node.getAttribute("path").replace(ide.workspaceDir, "").replace(ide.davPrefix, ""); winCloseConfirm.page = e.page; winCloseConfirm.all = -100; winCloseConfirm.show(); fileDesc.replaceMarkup("<div><h3>Save " + apf.escapeXML(filename) + "?</h3><div>This file has unsaved changes. Your changes will be lost if you don't save them.</div></div>", {"noLoadingMsg": false}); winCloseConfirm.addEventListener("hide", function(){ if (winCloseConfirm.all != -100) { var f = function(resetUndo){ var page; if (!(page=winCloseConfirm.page)) return; tabEditors.remove(page, true, page.noAnim); delete page.noAnim; if (resetUndo) page.$at.undo(-1); delete winCloseConfirm.page; page.dispatchEvent("aftersavedialogclosed"); }; if (winCloseConfirm.all == -200) _self.quicksave(winCloseConfirm.page, f); else f(true); /*winSaveAs.page = winCloseConfirm.page;*/ } else tabEditors.dispatchEvent("aftersavedialogcancel"); winCloseConfirm.removeEventListener("hide", arguments.callee); }); btnYesAll.hide(); btnNoAll.hide(); e.preventDefault(); } });
}, function(type) { ext.initExtension(_self); // Why is this code here? This is super hacky and has lots of // unwanted side effects (Ruben) // when visible -> make sure to refresh the grid dbgVariable.addEventListener("prop.visible", function(e) { if (e.value && self.dgVars) { dgVars.reload(); } }); return dbgVariable; });
ide.addEventListener("afteropenfile", function(event){ if (!event.node) return; if (!editors.currentEditor || !editors.currentEditor.amlEditor) // No editor, for some reason return; ext.initExtension(_self); var path = event.node.getAttribute("path"); worker.call("switchFile", [path, editors.currentEditor.amlEditor.syntax, event.doc.getValue()]); event.doc.addEventListener("close", function() { worker.emit("documentClose", {data: path}); }); // This is necessary to know which file was opened last, for some reason the afteropenfile events happen out of sequence deferred.cancel().schedule(100); });
initEditor : function(editor){ //Create Page Element var editorPage = new apf.page({ id : editor.path, mimeTypes : editor.contentTypes, visible : false, realtime : false }); tabEditors.appendChild(editorPage); //Initialize Content of the page ext.initExtension(editor, editorPage); return editorPage; },
showOutline: function(makeVisible, ignoreInputText) { ext.initExtension(outline); ext.initExtension(gotofile); if (makeVisible) { gotofile.toggleDialog(1); txtGoToFile.focus(); this.showOutline(); if (txtGoToFile.value.length > 0) txtGoToFile.$input.selectionStart = 1; this.scrollToTop(); } gotofile.setEventsEnabled(false); if (!dgGoToFile.getProperty("visible")) return; if (!txtGoToFile.value.match(/^@/) && !ignoreInputText) { this.lastGoToFileText = txtGoToFile.value; txtGoToFile.setValue(this.lastOutlineText); } this.ignoreSelectOnce = true; dgGoToFile.hide(); treeOutline.show(); if (makeVisible) txtGoToFile.$input.selectionStart = 1; },
activate : function(panelExt, noButton, noAnim){ if (this.currentPanel == panelExt) return; ext.initExtension(panelExt); lastPanel = this.currentPanel; if (this.currentPanel && (this.currentPanel != this)) this.deactivate(); var width = settings.model.queryValue("auto/panels/panel[@path=" + util.escapeXpathString(panelExt.path) + "]/@width") || panelExt.defaultWidth; colLeft.show(); if (noAnim || !apf.isTrue(settings.model.queryValue('general/@animateui'))) { panelExt.panel.show(); colLeft.show(); colLeft.setAttribute("minwidth", panelExt.panel.minwidth); colLeft.setWidth(width); ide.dispatchEvent("panels.animate", {noanim : true, toWidth: width}); apf.layout.forceResize(); } else if (!noAnim) { var _self = this; setTimeout(function(){ _self.animate(lastPanel && lastPanel.panel, panelExt.panel, width); }, 10); } if (!noButton && panelExt.button) panelExt.button.setValue(true); this.currentPanel = panelExt; this.lastPanel = panelExt; this.currentPanel.panel.setTitle(this.currentPanel.button.caption); settings.model.setQueryValue("auto/panels/@active", panelExt.path); ide.dispatchEvent("showpanel." + panelExt.path); this.mnuPanelsNone.setAttribute("selected", false); panelExt.mnuItem.select(); //Will set setting too },
show: function() { var page = ide.getActivePage(); if (!CoreUtil.pageIsCode(page)) { return; } ext.initExtension(this); settings.model.setQueryValue("general/@revisionsvisible", true); if (!this.panel.visible) { if (ide.dispatchEvent("ext.revisions.show", { barWidth: BAR_WIDTH }) !== false) Code.amlEditor.$ext.style.right = BAR_WIDTH + "px"; page.$showRevisions = true; this.panel.show(); ide.dispatchEvent("revisions.visibility", { visibility: "shown", width: BAR_WIDTH }); beautify.disable(); statusbar.offsetWidth = BAR_WIDTH; statusbar.setPosition(); stripws.disable(); language.disable(); } var model = page.$mdlRevisions; if (model) { if (lstRevisions && (lstRevisions.getModel() !== model)) { lstRevisions.setModel(model); } // If there is no revision object for the current doc, we should // retrieve if it is not being retrieved right now. After retrieval, // `populateModel` will take care of setting model.data. var docPath = CoreUtil.getDocPath(); var currentDocRevision = this.rawRevisions[docPath]; if (!currentDocRevision && !this.waitingForRevisionHistory) { this.model = model; this.getRevisionHistory({ path: docPath }); } else { this.populateModel(currentDocRevision, model); this.$restoreSelection(page, model); } } },
onMouseClick: function(e){ var _self = this; var pos = e.getDocumentPosition(); var r = this.authorToken.range; var editor = this.$editor; editor.renderer.content.style.cursor = "pointer"; if(r.inside(pos.row, pos.column)) { // Are we protected from tab switching? editor.session.removeMarker(this.authorHoverMarker); // This marker will be more obvious than ace_selection this.editStepMarker = editor.session.addMarker(r, "ace_selection", "text"); event.removeListener(editor.renderer.scroller, "mousemove", this.onAuthorMouseMove); event.removeListener(editor.renderer.content, "mouseout", this.onAuthorMouseOut); if(!codeTour.winTourText) { ext.initExtension(codeTour); setTimeout(function(){return _self.summonBubble.call(_self, e)}, 300); } else this.summonBubble(e); } },
hook: function () { var _self = this; var menuItem = new apf.item({ id : "beautify_selection", disabled : "true", onclick: function () { _self.beautify(); } }); menus.addItemByPath("Tools/Beautify Selection", menuItem, 100); this.hotitems.beautify = [menuItem]; code.commandManager.addCommand({ name: "beautify", exec: function () { _self.beautify(); } }); require("ext/settings/settings").addSettings("JS Beautify", markupSettings ); ide.addEventListener("loadsettings", function(e){ var model = e.model; if (!model.queryNode("beautify/jsbeautify")) { model.setQueryValue("beautify/jsbeautify/@preserveempty", "true"); model.setQueryValue("beautify/jsbeautify/@keeparrayindentation", "false"); model.setQueryValue("beautify/jsbeautify/@jslinthappy", "false"); model.setQueryValue("beautify/jsbeautify/@braces", "end-expand"); model.setQueryValue("editors/code/@tabsize", "4"); model.setQueryValue("editors/code/@softtabs", "true"); } }); ext.initExtension(this); },
var enableVim = function enableVim() { if (editors.currentEditor && editors.currentEditor.ceEditor) { ext.initExtension(this); var editor = editors.currentEditor.ceEditor.$editor; addCommands(editor, commands); editor.renderer.container.addEventListener("click", onCursorMove, false); if (!OLD_HANDLER) OLD_HANDLER = editor.getKeyboardHandler(); // Set Vim's own keyboard handle editor.setKeyboardHandler(handler); if (util.currentMode !== "insert") { commands.stop.exec(editor); } VIM_ENABLED = true; ide.dispatchEvent("track_action", {type: "vim", action: "enable"}); } };
ide.addEventListener("afteropenfile", function(event){ if (!event.node) return; if (!editors.currentEditor || !editors.currentEditor.amlEditor) // No editor, for some reason return; ext.initExtension(_self); var path = event.node.getAttribute("path"); var editor = editors.currentEditor.amlEditor; // background tabs=open document, foreground tab=switch to file // this is needed because with concorde changeSession event is fired when document is still empty var isVisible = editor.xmlRoot == event.node; var data = [ util.stripWSFromPath(path), editor.syntax, event.doc.getValue(), null, ide.workspaceDir ]; worker.call("documentOpen", data); if (isVisible) worker.call("switchFile", data); });
saveAllInteractive : function(pages, callback){ ext.initExtension(this); winCloseConfirm.all = 0; var _self = this; apf.asyncForEach(pages, function(item, next) { var at = item.$at; if (at.undo_ptr && at.$undostack[at.$undostack.length-1] !== at.undo_ptr) { if (winCloseConfirm.all == 1) _self.quicksave(item); if (winCloseConfirm.all) return next(); tabEditors.set(item); winCloseConfirm.page = item; winCloseConfirm.show(); winCloseConfirm.addEventListener("hide", function(){ if (winCloseConfirm.all == 1) _self.quicksave(item); winCloseConfirm.removeEventListener("hide", arguments.callee); next(); }); btnYesAll.setProperty("visible", pages.length > 1); btnNoAll.setProperty("visible", pages.length > 1); } else next(); }, function() { callback(winCloseConfirm.all); }); },
renderOutline: function(ignoreFilter) { var editor = editors.currentEditor; if (!editor || !editor.ceEditor) return; ext.initExtension(gotofile); var filter = ignoreFilter ? "" : txtGoToFile.value.substr(1); this.isDirty = ignoreFilter; this.isKeyDownAfterDirty = false; var outline = this.filteredOutline = search.treeSearch(this.fullOutline, filter, true); /* TODO: set "empty" message if (outline.length === 0) treeOutline.clear(treeOutline["empty-message"], "empty"); else treeOutline.$removeClearMessage(); */ var ace = editor.ceEditor.$editor; var selected = this.findCursorInOutline(outline, ace.getCursorPosition()); mdlOutline.load(apf.getXml('<data>' + this.outlineJsonToXml(outline, selected, 'entries') + '</data>')); return selected; },
toggleDialog: function(force, noanim, callback) { if (!self.winGoToFile || !force && !winGoToFile.visible || force > 0) { if (self.winGoToFile && winGoToFile.visible) return; ext.initExtension(this); ide.dispatchEvent("closepopup", {element: this}); winGoToFile.show(); if (dgGoToFile.$model != this.model) dgGoToFile.setModel(this.model); //Hide window until the list is loaded, unless we don't have data yet if (!dgGoToFile.xmlRoot) { dgGoToFile.$setClearMessage(dgGoToFile["loading-message"], "loading"); apf.setOpacity(winGoToFile.$ext, 1); } else { apf.setOpacity(winGoToFile.$ext, 1); } if (!txtGoToFile.inited) { setTimeout(function(){ txtGoToFile.inited = true; txtGoToFile.focus(); }); } else { txtGoToFile.focus(); } // If we had a filter and new content, lets refilter if (this.lastSearch) { var search = this.lastSearch; this.lastSearch = null; //invalidate cache this.filter(search); } else { this.filter(""); } } else if (self.winGoToFile && winGoToFile.visible) { if (!noanim) { winGoToFile.visible = false; //Animate anims.animate(winGoToFile, { opacity: "0", timingFunction: "linear", duration : 0.025 }, function(){ winGoToFile.visible = true; winGoToFile.hide(); setTimeout(function() { if (editors.currentEditor && editors.currentEditor.ceEditor) editors.currentEditor.ceEditor.focus(); }, 0); callback && callback(); }); } else { winGoToFile.hide(); callback && callback(); } } return false; },
dock.registerPage(this.section, null, function() { ext.initExtension(_self); return aceAnnotations; }, {
showAbout: function() { ext.initExtension(this); aboutDialog.show(); document.getElementById("c9Version").innerHTML = apf.escapeXML("Version " + window.cloud9config.version); },
toggleDialog: function(force) { ext.initExtension(this); if (this.control && this.control.stop) this.control.stop(); var editorPage = tabEditors.getPage(); if (!editorPage) return; var editor = editors.currentEditor; if (!editor || !editor.ceEditor) return; var _self = this; if (!force && !winQuickSearch.visible || force > 0) { this.position = -1; var sel = editor.getSelection(); var doc = editor.getDocument(); var range = sel.getRange(); var value = doc.getTextRange(range); if (!value && editor.ceEditor) value = editor.ceEditor.getLastSearchOptions().needle; if (value) txtQuickSearch.setValue(value); winQuickSearch.$ext.style.top = "-30px"; winQuickSearch.show(); txtQuickSearch.focus(); txtQuickSearch.select(); //Animate apf.tween.single(winQuickSearch, { type : "top", anim : apf.tween.easeInOutCubic, from : -27, to : 2, steps : 8, interval : 10, control : (this.control = {}), onfinish : function() { _self.updateCounter(); } }); } else if (winQuickSearch.visible) { txtQuickSearch.focus(); txtQuickSearch.select(); //Animate apf.tween.single(winQuickSearch, { type : "top", anim : apf.tween.NORMAL, from : winQuickSearch.$ext.offsetTop, to : -30, steps : 8, interval : 10, control : (this.control = {}), onfinish : function(){ winQuickSearch.hide(); editor.ceEditor.focus(); } }); var ace = this.$getAce(); if (ace) { ace.selection.clearSelection(); } } return false; },
show: function(immediate) { ext.initExtension(this); this._show(true, immediate); },
onclick : function(){ ext.initExtension(_self); _self.winExtensionTemplate.show(); }
hook : function(){ // Register this panel on the left-side panels panels.register(this, { position : 1000, caption: "Project Files", "class": "project_files" }); var _self = this; /** * Wait for the filesystem extension to load before we set up our * model */ ide.addEventListener("init.ext/filesystem/filesystem", function(e) { _self.model = e.ext.model; // loadedSettings is set after "loadsettings" is dispatched. // Thus if we have our model setup and we have the cached expanded // folders, then we can load the project tree if (_self.loadedSettings > 0 && _self.inited) _self.onReady(); }); ide.addEventListener("loadsettings", function(e){ var model = e.model; (davProject.realWebdav || davProject).setAttribute("showhidden", apf.isTrue(model.queryValue('auto/projecttree/@showhidden'))); _self.scrollPos = model.queryValue('auto/projecttree/@scrollpos'); // auto/projecttree contains the saved expanded nodes var strSettings = model.queryValue("auto/projecttree"); if (strSettings) { try { _self.expandedNodes = JSON.parse(strSettings); } catch (ex) { _self.expandedNodes = [ide.davPrefix]; } // Get the last selected tree node var savedTreeSelection = model.queryNode("auto/tree_selection"); if (savedTreeSelection) { _self.treeSelection.path = model.queryValue('auto/tree_selection/@path'); _self.treeSelection.type = model.queryValue('auto/tree_selection/@type'); } _self.loadedSettings = 1; // Please see note above about waiting for both the model and // the settings to be loaded before loading the project tree if (_self.model && _self.inited) _self.onReady(); } else { _self.loadedSettings = 2; if (_self.model && _self.inited) _self.onReady(); } }); ide.addEventListener("savesettings", function(e){ if (!_self.changed) return; var expandedNodes = apf.createNodeFromXpath(e.model.data, "auto/projecttree/text()"); _self.expandedNodes = []; var path, id; // expandedList keeps an active record of all the expanded nodes // so that on each save this gets serialized into the auto/projecttree // settings node for (id in _self.expandedList) { path = _self.expandedList[id].getAttribute("path"); if (!path) { delete _self.expandedList[id]; } else { _self.expandedNodes.push(path); } } expandedNodes.nodeValue = JSON.stringify(_self.expandedNodes); _self.changed = false; return true; }); /** * This receives updates from the tree watcher on the backend * I haven't looked deeply at this code, but it looks like it removes * and adds nodes */ ide.addEventListener("treechange", function(e) { var path = e.path.replace(/\/([^/]*)/g, "/node()[@name=\"$1\"]") .replace(/\[@name="workspace"\]/, "") .replace(/\//, ""); var parent = trFiles.getModel().data.selectSingleNode(path); if (!parent) return; var nodes = parent.childNodes; var files = e.files; var removed = []; for (var i = 0; i < nodes.length; ++i) { var node = nodes[i], name = node.getAttribute("name"); if (files && files[name]) delete files[name]; else removed.push(node); } removed.forEach(function (node) { apf.xmldb.removeNode(node); }); path = parent.getAttribute("path"); for (var filename in files) { var file = files[filename]; var xmlNode = "<" + file.type + " type='" + file.type + "'" + " name='" + filename + "'" + " path='" + path + "/" + filename + "'" + "/>"; trFiles.add(xmlNode, parent); } }); ext.initExtension(this); },