Permalink
Browse files

undock/dock commands

  • Loading branch information...
1 parent 1a77752 commit af79f2eee81d8f4beb62f33729e79359938199bd @paulrouget committed Jul 22, 2012
Showing with 147 additions and 31 deletions.
  1. +73 −26 bootstrap.js
  2. +59 −5 chrome/jsterm.js
  3. +14 −0 chrome/jsterm.xul
  4. BIN jsterm.xpi
  5. +1 −0 locale/en-US/jsterm.dtd
View
@@ -76,6 +76,7 @@ function uninstall() {}
let JSTermManager = {
_map: new WeakMap(),
_listeners: new WeakMap(),
+ where: "in_browser",
addControlsToWindow: function(aWindow) {
let strings = Services.strings.createBundle("chrome://jsterm/locale/jsterm.properties");
@@ -186,6 +187,19 @@ let JSTermManager = {
this._map.delete(aBrowser);
this.updateCheckboxStatus(aBrowser.ownerDocument.defaultView);
},
+ moveTermTo: function(aBrowser, aWhere) {
+ this.where = aWhere;
+ let term = this._map.get(aBrowser);
+ if (!term)
+ return;
+ term.rebuildUI();
+ },
+
+ isTermDocked: function(aBrowser) {
+ let term = this._map.get(aBrowser);
+ return term.docked;
+ },
+
updateCheckboxStatus: function(aWindow) {
let selectedBrowser = aWindow.gBrowser.selectedBrowser;
let checked = this.isOpenForBrowser(selectedBrowser);
@@ -197,46 +211,79 @@ let JSTermManager = {
},
}
-function JSTerm(aBrowser, aManager) {
+function JSTerm(aBrowser) {
this.browser = aBrowser;
this.chromeDoc = aBrowser.ownerDocument;
this.chromeWin = this.chromeDoc.defaultView;
this.buildUI();
+ this.savedContent = null;
}
JSTerm.prototype = {
buildUI: function() {
- let nbox = this.chromeWin.gBrowser.getNotificationBox(this.browser);
+ const CHROME_URL = "chrome://jsterm/content/jsterm.xul";
+ const CHROME_WINDOW_FLAGS = "chrome,centerscreen,resizable,dialog=no";
+
+ let termWindow;
let doc = this.chromeDoc;
- let splitter = doc.createElement("splitter");
- splitter.className = "devtools-horizontal-splitter jsterm-splitter";
-
- let container = doc.createElement("vbox");
- container.setAttribute("flex", "1");
- container.className = "jsterm-container";
- container.height = 200;
-
- let iframe = doc.createElement("iframe");
- iframe.setAttribute("src", "chrome://jsterm/content/jsterm.xul");
- iframe.setAttribute("flex", "1")
- container.appendChild(iframe);
- nbox.appendChild(splitter);
- nbox.appendChild(container);
-
- iframe.contentWindow.onload = function() {
- iframe.contentWindow.JSTermUI.init(JSTermManager,
- this.browser,
- this.browser.contentWindow,
- this.chromeWin);
+ this.docked = (JSTermManager.where == "in_browser");
+
+ if (this.docked) {
+ let nbox = this.chromeWin.gBrowser.getNotificationBox(this.browser);
+ let splitter = doc.createElement("splitter");
+ splitter.className = "devtools-horizontal-splitter jsterm-splitter";
+
+ let container = doc.createElement("vbox");
+ container.setAttribute("flex", "1");
+ container.className = "jsterm-container";
+ container.height = 200;
+
+ let iframe = doc.createElement("iframe");
+ iframe.setAttribute("src", CHROME_URL);
+ iframe.setAttribute("flex", "1")
+
+ container.appendChild(iframe);
+ nbox.appendChild(splitter);
+ nbox.appendChild(container);
+
+ termWindow = iframe.contentWindow;
+ } else {
+ termWindow = Services.ww.openWindow(null, CHROME_URL, "_blank", CHROME_WINDOW_FLAGS, {});
+ }
+
+ termWindow.onload = function() {
+ termWindow.JSTermUI.init(JSTermManager,
+ this.browser,
+ this.browser.contentWindow,
+ this.chromeWin,
+ this.savedContent);
}.bind(this);
+
+ this.termWindow = termWindow;
},
- destroy: function() {
+
+ rebuildUI: function() {
+ this.savedContent = this.termWindow.JSTermUI.getContent();
+ this.destroyUI();
+ this.buildUI();
+ },
+
+ destroyUI: function() {
let nbox = this.chromeWin.gBrowser.getNotificationBox(this.browser);
let container = nbox.querySelector(".jsterm-container");
- let splitter = nbox.querySelector(".jsterm-splitter");
- splitter.parentNode.removeChild(splitter);
- container.parentNode.removeChild(container);
+ if (container) {
+ let splitter = nbox.querySelector(".jsterm-splitter");
+ splitter.parentNode.removeChild(splitter);
+ container.parentNode.removeChild(container);
+ } else {
+ this.termWindow.close()
+ }
+ },
+
+ destroy: function() {
+ this.destroyUI();
+ this.termWindow = null;
this.browser = null;
this.chromeDoc = null;
this.chromeWin = null;
View
@@ -5,6 +5,9 @@ Cu.import("resource:///modules/WebConsoleUtils.jsm");
/**
* Todo
+ * . ctrl-w & keybinding doesn't work in window mode
+ * . using the close button doesn't uncheck the button
+ * . keybindings for linux & windows
* . print() is slow
* . undock
* . save history and share it
@@ -21,9 +24,17 @@ let JSTermUI = {
objects: new Map(),
close: function() {
+ if (this.closing) return;
+ this.closing = true;
this.manager.closeForBrowser(this.browser);
},
+ closeIfInWindow: function() {
+ if (!this.closing && !this.manager.isTermDocked(this.browser)) {
+ this.close();
+ }
+ },
+
registerCommands: function() {
this.commands = [
{name: ":close", help: "close terminal",
@@ -36,6 +47,10 @@ let JSTermUI = {
exec: this.switchToContentMode.bind(this)},
{name: ":chrome", help: "switch to Chrome mode",
exec: this.switchToChromeMode.bind(this)},
+ {name: ":undock", help: "Move the terminal into its own window",
+ exec: this.undock.bind(this)},
+ {name: ":dock", help: "Move the terminal in browser",
+ exec: this.dock.bind(this)},
];
},
@@ -54,7 +69,7 @@ let JSTermUI = {
this.input.focus();
},
- init: function(aManager, aBrowser, aContent, aChrome) {
+ init: function(aManager, aBrowser, aContent, aChrome, aDefaultContent) {
this.manager = aManager;
this.browser = aBrowser;
this.content = aContent;
@@ -67,16 +82,29 @@ let JSTermUI = {
this.focus = this.focus.bind(this);
this.container = document.querySelector("#editors-container");
+ let defaultInputText, defaultOutputText;
+
+ if (aDefaultContent) {
+ defaultInputText = aDefaultContent.input;
+ defaultOutputText = aDefaultContent.output;
+ this.history.init(aDefaultContent.history);
+ } else {
+ defaultInputText = "";
+ defaultOutputText = "// type ':help' for help\n// Report bug here: https://github.com/paulrouget/firefox-jsterm";
+ this.history.init();
+ }
+
let outputContainer = document.querySelector("#output-container");
this.inputContainer = document.querySelector("#input-container");
this.output.init(outputContainer, {
- initialText: "// type ':help' for help\n// Report bug here: https://github.com/paulrouget/firefox-jsterm",
+ initialText: defaultOutputText,
mode: SourceEditor.MODES.JAVASCRIPT,
readOnly: true,
theme: "chrome://jsterm/content/orion.css",
}, this.initOutput.bind(this));
this.input.init(this.inputContainer, {
+ initialText: defaultInputText,
mode: SourceEditor.MODES.JAVASCRIPT,
theme: "chrome://jsterm/content/orion.css",
}, this.initInput.bind(this));
@@ -90,6 +118,7 @@ let JSTermUI = {
if (this.completion) this.completion.destroy();
this.completion = new JSCompletion(this.input, label, this.sb);
this.inputContainer.classList.add("chrome");
+ window.document.title = "JSTerm: (chrome) " + this.chrome.location;
},
switchToContentMode: function() {
@@ -102,6 +131,7 @@ let JSTermUI = {
this.output.setText(" // Switched to content mode.", this.output.getCharCount());
}
this.inputContainer.classList.remove("chrome");
+ window.document.title = "JSTerm: " + this.content.location;
},
buildSandbox: function(win) {
@@ -123,7 +153,6 @@ let JSTermUI = {
},
initInput: function() {
- this.history.init();
this.switchToContentMode();
this.makeEditorFitContent(this.input);
@@ -163,11 +192,16 @@ let JSTermUI = {
_entries: [],
cursor: 0,
browsing: false,
- init: function() {
+ init: function(entries) {
JSTermUI.input.addEventListener(SourceEditor.EVENTS.SELECTION, function() {
this.browsing = false;
}.bind(this));
-
+ if (entries) {
+ this._entries = entries;
+ }
+ },
+ copy: function() {
+ return this._entries.concat();
},
add: function(entry) {
if (!entry) return;
@@ -462,6 +496,26 @@ let JSTermUI = {
filterObjInspector: function(input) {
this.treeview.filter(input.value);
},
+
+ getContent: function() {
+ return {
+ input: this.input.getText(),
+ output: this.output.getText(),
+ history: this.history.copy(),
+ };
+ },
+
+ undock: function() {
+ if (this.manager.isTermDocked(this.browser)) {
+ this.manager.moveTermTo(this.browser, "own_window");
+ }
+ },
+
+ dock: function() {
+ if (!this.manager.isTermDocked(this.browser)) {
+ this.manager.moveTermTo(this.browser, "in_browser");
+ }
+ },
}
View
@@ -2,16 +2,30 @@
<?xml-stylesheet href="chrome://browser/skin/devtools/common.css" type="text/css"?>
<?xml-stylesheet href="chrome://jsterm/content/jsterm.css" type="text/css"?>
+<!DOCTYPE window [
+<!ENTITY % JSTermDTD SYSTEM "chrome://jsterm/locale/jsterm.dtd" >
+ %JSTermDTD;
+]>
+
<window id="jsterm-window"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="JSTerm"
windowtype="devtools:jsterm"
macanimationtype="document"
screenX="4" screenY="4"
width="640" height="480"
+ onunload="JSTermUI.closeIfInWindow()"
persist="screenX screenY width height sizemode">
<script type="application/javascript" src="jsterm.js"/>
+
+ <keyset id="jsterm-keyset">
+ <key id="jsterm-key-close"
+ key="&JSTerm.closeKey;"
+ oncommand="JSTermUI.closeIfInWindow()"
+ modifiers="accel"/>
+ </keyset>
+
<hbox flex="1">
<vbox flex="1">
<vbox id="editors-container" flex="1" onclick="JSTermUI.focus()">
View
Binary file not shown.
View
@@ -1,3 +1,4 @@
<!ENTITY JSTerm.menu.label "JSTerm">
<!ENTITY JSTerm.key "J">
+<!ENTITY JSTerm.closeKey "w">

0 comments on commit af79f2e

Please sign in to comment.