Skip to content
Browse files

Merge remote-tracking branch 'origin/master' into lib_updates

Conflicts:
	plugins-client/lib.apf/www/apf-packaged/apf_release.js
  • Loading branch information...
2 parents d95cd53 + 6492214 commit 4e635b26829c14c58895d69fa0efaa0bb0fe00a0 @mikedeboer mikedeboer committed Nov 20, 2012
View
2 plugins-client/ext.console/console.js
@@ -445,6 +445,8 @@ module.exports = ext.register("ext/console/console", {
this.createProcessLog(message.pid, lang[1]);
return;
+ } else if ((lang = /^([\w-]+)-web-start$/.exec(message.type)) && runners.indexOf(lang[1]) >= 0) {
+ require("ext/preview/preview").preview(message.url);
} else if ((lang = /^(\w+)-data$/.exec(message.type)) && runners.indexOf(lang[1]) >= 0) {
if (message.extra && message.extra.tip) {
message.data = "\u001b[1;32;40m" + message.data;
View
2 plugins-client/ext.console/logger.js
@@ -45,7 +45,7 @@ var createItem = module.exports.test.createItem = function(line, ide) {
.replace(wsRe, html.replace("___", workspaceDir + "/"));
}
else if (line.search(RE_URL) !== -1) {
- line = line.replace(RE_URL, "<a href='$1' target='_blank'>$1</a>");
+ line = line.replace(RE_URL, "<a onclick='require(\"ext/preview/preview\").preview(\"$1\"); return false;' href='$1' target='_blank'>$1</a>");
}
// escape HTML/ XML, but preserve the links
View
3 plugins-client/ext.dockpanel/libdock.js
@@ -827,7 +827,8 @@ var DockableLayout = module.exports = function(parentHBox, cbFindPage, cbStorePa
bar.show();
bar.vbox.hide();
- bar.parentNode.removeChild(bar.vbox);
+ if (bar.parentNode)
+ bar.parentNode.removeChild(bar.vbox);
bar.vbox.expanded = false;
bar.splitter.hide();
}
View
9 plugins-client/ext.editors/editors.js
@@ -1083,10 +1083,11 @@ module.exports = ext.register("ext/editors/editors", {
}
function focus() {
- if (!_self.currentEditor.amlEditor)
+ var editor = _self.currentEditor.amlEditor;
+ if (!editor)
return;
- var ace = _self.currentEditor.amlEditor.$editor;
- if (!ace.$isFocused) {
+ var ace = editor.$editor;
+ if (ace && !ace.$isFocused) {
setTimeout(f = function() {
ace.focus();
ide.dispatchEvent("aftereditorfocus");
@@ -1139,4 +1140,4 @@ module.exports = ext.register("ext/editors/editors", {
}
});
-});
+});
View
6 plugins-client/ext.language/complete.js
@@ -288,7 +288,7 @@ module.exports = {
var docHead;
if (match.type) {
- var shortType = _self.$guidToShortString(match.type)
+ var shortType = _self.$guidToShortString(match.type);
if (shortType) {
match.meta = shortType;
docHead = match.name + " : " + _self.$guidToLongString(match.type) + "</div>";
@@ -377,7 +377,9 @@ module.exports = {
txtCompleterDoc.parentNode.hide();
}
if (selected && selected.docUrl)
- this.docElement.innerHTML += '<p><a href="' + selected.docUrl + '" target="c9doc">(more)</a></p>';
+ this.docElement.innerHTML += '<p><a' +
+ ' onclick="require(\'ext/preview/preview\').preview(\'' + selected.docUrl + '\'); return false;"' +
+ ' href="' + selected.docUrl + '" target="c9doc">(more)</a></p>';
this.docElement.innerHTML += '</span>';
},
View
BIN plugins-client/ext.main/style/images/sidebar_preview_icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
153 plugins-client/ext.preview/preview.js
@@ -1,60 +1,155 @@
/**
- * HTML Editor for the Cloud9 IDE
+ * App or HTML previewer in Cloud9 IDE
*
* @copyright 2010, Ajax.org B.V.
* @license GPLv3 <http://www.gnu.org/licenses/gpl.txt>
*/
-
define(function(require, exports, module) {
var ide = require("core/ide");
var ext = require("core/ext");
-var code = require("ext/code/code");
+var util = require("core/util");
var menus = require("ext/menus/menus");
+var dock = require("ext/dockpanel/dockpanel");
+var editors = require("ext/editors/editors");
+var markup = require("text!ext/preview/preview.xml");
+var skin = require("text!ext/preview/skin.xml");
+var css = require("text!ext/preview/style/style.css");
+
+var _name = "ext/preview/preview";
-module.exports = ext.register("ext/html/html", {
- name : "HTML Editor",
- dev : "Ajax.org",
- type : ext.GENERAL,
- alone : true,
- deps : [code],
- nodes : [],
+module.exports = ext.register(_name, {
+ name : "Preview",
+ dev : "Ajax.org",
+ type : ext.GENERAL,
+ alone : true,
+ markup : markup,
+ _name : _name,
+ skin : {
+ id : "previewskin",
+ data : skin,
+ "media-path" : ide.staticPrefix + "/ext/preview/style/images/",
+ "icon-path" : ide.staticPrefix + "/ext/preview/style/icons/"
+ },
+ css : util.replaceStaticPrefix(css),
+ deps : [editors],
autodisable : ext.ONLINE | ext.LOCAL,
-
disableLut: {
"terminal": true
},
-
- init : function(){
- var _self = this;
+ nodes : [],
+
+ _getDockButton: function() {
+ var buttons = dock.getButtons(this._name);
+ if (buttons)
+ return buttons[0].cache;
+ },
+
+ _getDockBar: function () {
+ return dock.getBars(this._name, "pgPreview")[0];
+ },
+
+ onLoad: function () {
+ },
+
+ hook : function() {
+ var _self = this;
+
this.nodes.push(
menus.$insertByIndex(barTools, new apf.button({
skin : "c9-toolbarbutton-glossy",
- //icon : "preview.png" ,
+ //icon : "preview.png",
"class" : "preview",
tooltip : "Preview in browser",
caption : "Preview",
disabled : true,
- onclick : function(){
- var file = tabEditors.getPage().$model.data;
- window.open(location.protocol + "//"
- + location.host + file.getAttribute("path"), "_blank");
+ onclick : function() {
+ var page = tabEditors.getPage();
+ if (page.$editor === _self)
+ return;
+ var file = page.$model.data;
+ var url = location.protocol + "//" + location.host + file.getAttribute("path");
+ _self.preview(url);
}
}), 10)
);
-
- ide.addEventListener("init.ext/editors/editors", function(e) {
- ide.addEventListener("tab.afterswitch", function(e){
- _self.enable();
- });
- ide.addEventListener("closefile", function(e){
- if (tabEditors.getPages().length == 1)
- _self.disable();
- });
+
+ dock.addDockable({
+ expanded : -1,
+ width : 400,
+ "min-width" : 400,
+ barNum: 2,
+ sections : [{
+ width : 360,
+ height: 300,
+ buttons : [{
+ caption: "Preview Apps",
+ ext : [this._name, "pgPreview"],
+ hidden : false
+ }]
+ }]
+ });
+
+ dock.register(this._name, "pgPreview", {
+ menu : "Preview Apps",
+ primary : {
+ backgroundImage: ide.staticPrefix + "/ext/main/style/images/sidebar_preview_icon.png",
+ defaultState: { x: -11, y: -10 },
+ activeState: { x: -11, y: -46 }
+ }
+ }, function() {
+ ext.initExtension(_self);
+ return pgPreview;
});
- this.enabled = false;
+ ide.addEventListener("tab.afterswitch", function(e){
+ _self.enable();
+ });
+
+ ide.addEventListener("closefile", function(e){
+ if (tabEditors.getPages().length == 1)
+ _self.disable();
+ });
+
+ ext.initExtension(this);
+ },
+
+ preview : function (url) {
+ // window.open(url, "_blank");
+ pgPreview.setCaption(apf.getFilename(url));
+ var bar = this._getDockBar();
+ dock.showBar(bar);
+ dock.expandBar(bar);
+ dock.showSection(this._name, "pgPreview");
+ var frmPreview = this.getIframe();
+ if (frmPreview.$ext.src !== url)
+ this.refresh(url);
+ },
+
+ popup: function (url) {
+ url = url || txtPreview.getValue();
+ var w = window.open(url, "_blank");
+ },
+
+ refresh: function (url) {
+ var frmPreview = this.getIframe();
+ url = url || txtPreview.getValue();
+ pgPreview.setAttribute("class", "loading_active");
+ frmPreview.$ext.src = url;
+ txtPreview.setValue(url);
+ },
+
+ close: function () {
+ dock.hideSection(this._name, "pgPreview");
+ },
+
+ init : function() {
+ apf.importCssString(this.css || "");
+ },
+
+ getIframe: function(editor) {
+ return pgPreview.selectSingleNode("iframe");
},
enable : function() {
View
22 plugins-client/ext.preview/preview.xml
@@ -0,0 +1,22 @@
+<a:application xmlns:a="http://ajax.org/2005/aml">
+ <a:tab skin="docktab" visible="false">
+ <a:page id="pgPreview" caption="Preview">
+ <a:bar border="0 0 0 0">
+ <a:hbox class="previewbar" height="36" align="center" edge="4 5 4" padding="5">
+ <a:textbox id="txtPreview" style="width:100%" class="ace_searchbox tb_textbox searchbox searchTxt tb_console"
+ flex="1" value=""
+ onkeydown="if (event.keyCode == 13) require('ext/preview/preview').refresh()" />
+ <a:button onclick="require('ext/preview/preview').refresh()" skin="btn-preview-nav" skinset="previewskin" class="refresh"></a:button>
+ <a:divider skin="c9-divider" />
+ <a:button onclick="require('ext/preview/preview').popup()" skin="btn-preview-nav" skinset="previewskin" class="popup"></a:button>
+ <a:divider skin="c9-divider" />
+ <a:button onclick="require('ext/preview/preview').close()" skin="btn-preview-nav" skinset="previewskin" class="close"></a:button>
+ </a:hbox>
+ </a:bar>
+ <iframe
+ class="preview_iframe"
+ onload="require('ext/preview/preview').onLoad()"
+ src="" />
+ </a:page>
+ </a:tab>
+</a:application>
View
80 plugins-client/ext.preview/skin.xml
@@ -0,0 +1,80 @@
+<?xml version='1.0'?>
+<a:skin xmlns:a="http://ajax.org/2005/aml">
+<a:button name="btn-preview-nav">
+ <a:style><![CDATA[
+ .btn-preview-nav {
+ height : 24px;
+ overflow : hidden;
+ cursor : default;
+ position : relative;
+ background-repeat:no-repeat;
+ background-position: 0 0;
+ -moz-user-select: -moz-none;
+ -khtml-user-select : none;
+ -webkit-user-select: none;
+ -o-user-select: none;
+ user-select : none;
+
+ background: url(images/c9-preview-repeat.png) repeat-x 0 100px;
+ border-radius: 3px;
+
+ border: 1px solid transparent;
+ }
+
+ .btn-preview-navOver {
+ background-position : 0 0;
+ border-color: #010910;
+ }
+
+ .btn-preview-navDown {
+ background-position : 0 -33px;
+ border-color: #010910;
+ }
+
+ .btn-preview-nav .icon {
+ width : 24px;
+ height : 23px;
+ -webkit-border-radius : 3px;
+ -moz-border-radius : 3px;
+ border-radius : 3px;
+ margin-left: 1px;
+ }
+
+ .btn-preview-nav.close .icon {
+ background: url(images/c9-preview-repeat.png) no-repeat 0 -66px;
+ }
+
+ .btn-preview-nav.refresh .icon {
+ background: url(images/c9-preview-repeat.png) no-repeat 0 -89px;
+ }
+
+ .btn-preview-nav.popup .icon {
+ background: url(images/c9-preview-repeat.png) no-repeat 0 -114px;
+ }
+
+ .btn-preview-nav.goforward .icon {
+ background: url(images/c9-preview-repeat.png) no-repeat 0 -186px;
+ }
+
+ .btn-preview-navDisabled.goforward .icon {
+ background: url(images/c9-preview-repeat.png) no-repeat 0 -210px;
+ }
+
+ .btn-preview-nav.goback .icon {
+ background: url(images/c9-preview-repeat.png) no-repeat 0 -138px;
+ }
+
+ .btn-preview-navDisabled.goback .icon {
+ background: url(images/c9-preview-repeat.png) no-repeat 0 -162px;
+ }
+ ]]></a:style>
+
+ <a:presentation>
+ <a:main caption="div" label="div" background="." icon="div">
+ <div class="btn-preview-nav">
+ <div class="icon"/>
+ </div>
+ </a:main>
+ </a:presentation>
+</a:button>
+</a:skin>
View
BIN plugins-client/ext.preview/style/images/c9-preview-repeat.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
10 plugins-client/ext.preview/style/style.css
@@ -0,0 +1,10 @@
+.previewbar {
+ position : relative;
+ background: url("{ide.staticPrefix}/ext/preview/style/images/c9-preview-repeat.png") repeat-x 0 -244px;
+ border-bottom: 1px solid #000000;
+}
+.preview_iframe {
+ border: none;
+ width:100%;
+ height:100%;
+}
View
7 plugins-client/ext.splitview/splitview.js
@@ -25,6 +25,7 @@ var mnuCloneView, mnuSplitAlign;
var restoring = false;
var restoreQueue = [];
+var SUPPORTED_EDITORS = ["ext/code/code", "ext/preview/preview"];
module.exports = ext.register("ext/splitview/splitview", {
name : "Split View",
@@ -549,8 +550,6 @@ module.exports = ext.register("ext/splitview/splitview", {
},
updateSplitView: function(previous, next) {
- //if (restoring)
- // return;
var editor;
var doc = next.$doc;
var at = next.$at;
@@ -590,7 +589,7 @@ module.exports = ext.register("ext/splitview/splitview", {
editor.show();
return;
}
-
+console.log("showing split?");
Splits.show(split);
mnuSplitAlign.setAttribute("checked", split.gridLayout == "3rows");
@@ -791,7 +790,7 @@ module.exports = ext.register("ext/splitview/splitview", {
var editor;
for (var i = 0, l = arguments.length; i < l; ++i) {
editor = arguments[i];
- if (!editor || editor.path != "ext/code/code")
+ if (!editor || SUPPORTED_EDITORS.indexOf(editor.path) === -1)
return false;
}
return true;
View
42 plugins-client/lib.apf/www/apf/elements/codeeditor.js
@@ -254,7 +254,7 @@ apf.codeeditor = module.exports = function(struct, tagName) {
this.$propHandlers["showinvisibles"] = function(value, prop, initial) {
this.$editor.setShowInvisibles(value);
};
-
+
this.$propHandlers["showindentguides"] = function(value, prop, initial) {
this.$editor.setDisplayIndentGuides(value);
};
@@ -502,7 +502,7 @@ apf.codeeditor = module.exports = function(struct, tagName) {
this.scrollspeed = ed.getScrollSpeed();
if (this.selectstyle === undefined)
this.selectstyle = ed.getSelectionStyle();//"line";
-
+
//@todo this is a workaround for a bug in handling boolean properties in apf.$setDynamicProperty
this.activeline = ed.getHighlightActiveLine();//true;
this.gutterline = ed.getHighlightGutterLine();//true;
@@ -577,19 +577,19 @@ apf.codebox = function(struct, tagName) {
this.$input.style.textShadow = "none";
var ace = this.createSingleLineAceEditor(this.$input);
-
+
// disable unneded commands
ace.commands.removeCommands(["find", "replace", "replaceall", "gotoline", "findnext", "findprevious"]);
// todo is there a property for these?
ace.commands.removeCommands(["indent", "outdent"])
-
+
this.$editor = this.ace = ace;
ace.renderer.setPadding(0);
this.ace.codebox = this;
-
+
ace.on("focus", function() {
dom.removeCssClass(ace.codebox.$ext, "tb_textboxInitial");
-
+
if (ace.renderer.initialMessageNode) {
ace.renderer.scroller.removeChild(ace.renderer.initialMessageNode);
ace.renderer.initialMessageNode = null;
@@ -600,7 +600,7 @@ apf.codebox = function(struct, tagName) {
if (ace.$isFocused || ace.session.getValue())
return;
dom.addCssClass(ace.codebox.$ext, "tb_textboxInitial");
-
+
if (ace.renderer.initialMessageNode)
return;
ace.renderer.initialMessageNode = document.createTextNode(ace.codebox["initial-message"]);
@@ -641,14 +641,14 @@ apf.codebox = function(struct, tagName) {
this.ace.commands.exec(command, this.ace);
};
- this.createSingleLineAceEditor = function(el) {
+ this.createSingleLineAceEditor = function(el) {
var renderer = new VirtualRenderer(el);
el.style.overflow = "hidden";
renderer.scrollBar.element.style.top = "0";
renderer.scrollBar.element.style.display = "none";
renderer.scrollBar.orginalWidth = renderer.scrollBar.width;
renderer.scrollBar.width = 0;
- renderer.content.style.height = "auto";
+ renderer.content.style.height = "auto";
renderer.screenToTextCoordinates = function(x, y) {
var pos = this.pixelToScreenCoordinates(x, y);
@@ -657,44 +657,44 @@ apf.codebox = function(struct, tagName) {
Math.max(pos.column, 0)
);
};
-
+
renderer.maxLines = 4;
renderer.$computeLayerConfigWithScroll = renderer.$computeLayerConfig;
renderer.$computeLayerConfig = function() {
var config = this.layerConfig;
var height = this.session.getScreenLength() * this.lineHeight;
if (config.height != height) {
var vScroll = height > this.maxLines * this.lineHeight;
-
+
if (vScroll != this.$vScroll) {
if (vScroll) {
this.scrollBar.element.style.display = "";
- this.scrollBar.width = this.scrollBar.orginalWidth;
+ this.scrollBar.width = this.scrollBar.orginalWidth;
this.container.style.height = config.height + "px";
height = config.height;
this.scrollTop = height - this.maxLines * this.lineHeight;
} else {
this.scrollBar.element.style.display = "none";
this.scrollBar.width = 0;
}
-
+
this.onResize();
this.$vScroll = vScroll;
- }
-
+ }
+
if (this.$vScroll)
return renderer.$computeLayerConfigWithScroll();
-
+
this.container.style.height = height + "px";
this.scroller.style.height = height + "px";
this.content.style.height = height + "px";
this._emit("resize");
}
-
+
var longestLine = this.$getLongestLine();
var lastRow = this.session.getLength();
- this.scrollTop = 0;
+ this.scrollTop = 0;
config.width = longestLine;
config.padding = this.$padding;
config.firstRow = 0;
@@ -704,7 +704,7 @@ apf.codebox = function(struct, tagName) {
config.characterWidth = this.characterWidth;
config.minHeight = height;
config.maxHeight = height;
- config.offset = 0;
+ config.offset = 0;
config.height = height;
this.$gutterLayer.element.style.marginTop = 0 + "px";
@@ -722,9 +722,9 @@ apf.codebox = function(struct, tagName) {
editor.setShowPrintMargin(false);
editor.renderer.setShowGutter(false);
editor.renderer.setHighlightGutterLine(false);
-
+
editor.$mouseHandler.$focusWaitTimout = 0;
-
+
return editor;
},
View
5 plugins-server/cloud9.process-manager/process-manager-ext.js
@@ -18,10 +18,7 @@ module.exports = function setup(options, imports, register) {
callback(null, pm.ps());
},
runnerTypes: function(callback) {
- var exclude = ["npm", "shell", "run-npm"];
- callback(null, Object.keys(runners).filter(function(runner) {
- return exclude.indexOf(runner) === -1;
- }));
+ callback(null, pm.runnerTypes());
},
debug: pm.debug.bind(pm),
spawn: pm.spawn.bind(pm),
View
41 plugins-server/cloud9.process-manager/process_manager.js
@@ -61,10 +61,51 @@ var ProcessManager = module.exports = function(runners, eventEmitter) {
self.processes[child.pid] = child;
callback(null, child.pid, child);
+ self.tcpChecker(runnerId, child, eventName);
});
});
};
+ this.tcpChecker = function (runnerId, child, eventName) {
+ if (this.runnerTypes().indexOf(runnerId) === -1)
+ return;
+
+ var self = this;
+ var i = 0;
+ var tcpIntervals = [500, 1000, 2000, 4000, 8000];
+ function checkTCP() {
+ self.exec("shell", {
+ command: "lsof",
+ args: ["-i", ":8080"]
+ }, function(err, pid) {
+ }, function(code, stdout, stderr) {
+ if (code)
+ return;
+ // If an app is consuming the port 8080,
+ // then it must be the user-app is a server and it has started
+ if (stdout) {
+ var msg = {
+ "type": runnerId + "-web-start",
+ "pid": child.pid,
+ "url": child.url
+ };
+ self.eventEmitter.emit(eventName, msg);
+ }
+ else if (++i < tcpIntervals.length) {
+ setTimeout(checkTCP, tcpIntervals[i]);
+ }
+ });
+ }
+ setTimeout(checkTCP, tcpIntervals[i]);
+ };
+
+ this.runnerTypes = function() {
+ var exclude = ["npm", "shell", "run-npm"];
+ return Object.keys(this.runners).filter(function(runner) {
+ return exclude.indexOf(runner) === -1;
+ });
+ };
+
/**
* execute process and wait for completion. stdout and stderr are returned
* in the callback.
View
4 plugins-server/cloud9.run.apache/apache-runner.js
@@ -60,6 +60,9 @@ var Runner = exports.Runner = function(vfs, options, callback) {
self.scriptArgs = options.args || [];
self.apacheArgs = [];
+ var suffix = DIRECT_OPEN_FILES.test(this.file) ? "/" + this.file : "";
+ options.url += suffix;
+
startProcess(options.url);
function startProcess (url) {
@@ -73,7 +76,6 @@ var Runner = exports.Runner = function(vfs, options, callback) {
}
if (msg.type === "apache-start") {
- var suffix = DIRECT_OPEN_FILES.test(self.file) ? "/" + self.file : "";
var info = [
"Your page is running at '" + url + suffix + "'."
];
View
2 plugins-server/cloud9.run.node/node-runner.js
@@ -87,7 +87,7 @@ var Runner = exports.Runner = function(vfs, options, callback) {
if (err) return console.error(err);
var url = "http://" + host + ":" + port;
-
+ options.url = url;
startProcess(url, port);
});
}
View
2 plugins-server/cloud9.run.php/php-runner.js
@@ -64,7 +64,7 @@ var Runner = exports.Runner = function(vfs, options, callback) {
if (err) return console.error(err);
var url = "http://" + host + ":" + port;
-
+ options.url = url;
startProcess(url, port);
});
}
View
2 plugins-server/cloud9.run.python/python-runner.js
@@ -67,7 +67,7 @@ var Runner = exports.Runner = function(vfs, options, callback) {
if (err) return console.error(err);
var url = "http://" + host + ":" + port;
-
+ options.url = url;
startProcess(url, port);
});
}
View
2 plugins-server/cloud9.run.ruby/ruby-runner.js
@@ -83,7 +83,7 @@ var Runner = exports.Runner = function(vfs, options, callback) {
if (err) return console.error(err);
var url = "http://" + host + ":" + port;
-
+ options.url = url;
startProcess(url, port);
});
}
View
1 plugins-server/cloud9.run.shell/shell.js
@@ -36,6 +36,7 @@ var Runner = exports.Runner = function(vfs, options, callback) {
this.uid = options.uid;
this.command = options.command;
this.args = options.args || [];
+ this.url = options.url;
this.extra = options.extra;
this.encoding = options.encoding;

0 comments on commit 4e635b2

Please sign in to comment.
Something went wrong with that request. Please try again.