mirror of https://github.com/roytam1/boc-uxp.git
15 changed files with 1903 additions and 4 deletions
@ -0,0 +1,11 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public |
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this |
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function toScratchpad() { |
||||
toOpenWindowByType("devtools:scratchpad", |
||||
"chrome://communicator/content/devtools/scratchpad.xul", |
||||
"resizable"); |
||||
} |
||||
|
||||
|
@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public |
||||
License, v. 2.0. If a copy of the MPL was not distributed with this |
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/. --> |
||||
|
||||
<!DOCTYPE overlay [ |
||||
<!ENTITY % overlayDTD SYSTEM "chrome://communicator/locale/devtools/devtoolsOverlay.dtd"> |
||||
%overlayDTD; |
||||
]> |
||||
|
||||
<overlay id="devtools-overlay" |
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> |
||||
|
||||
<script type="application/javascript" src="chrome://communicator/content/devtools/devtoolsOverlay.js" /> |
||||
|
||||
<menupopup id="devtoolsPopup"> |
||||
<menuitem id="cmd_scratchpad" |
||||
insertafter="menu_inspector,javascriptConsole" |
||||
oncommand="toScratchpad();" |
||||
label="&scratchpad.label;"/> |
||||
</menupopup> |
||||
|
||||
<menupopup id="toolsPopup"> |
||||
<menuitem id="cmd_scratchpad" |
||||
insertafter="menu_inspector,javascriptConsolemenu_inspector" |
||||
oncommand="toScratchpad();" |
||||
label="&scratchpad.label;"/> |
||||
</menupopup> |
||||
</overlay> |
||||
|
@ -0,0 +1,694 @@
|
||||
/* vim:set ts=2 sw=2 sts=2 et: |
||||
* ***** BEGIN LICENSE BLOCK ***** |
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
||||
* |
||||
* The contents of this file are subject to the Mozilla Public License Version |
||||
* 1.1 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* http://www.mozilla.org/MPL/
|
||||
* |
||||
* Software distributed under the License is distributed on an "AS IS" basis, |
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
||||
* for the specific language governing rights and limitations under the |
||||
* License. |
||||
* |
||||
* The Original Code is Scratchpad. |
||||
* |
||||
* The Initial Developer of the Original Code is |
||||
* The Mozilla Foundation. |
||||
* Portions created by the Initial Developer are Copyright (C) 2011 |
||||
* the Initial Developer. All Rights Reserved. |
||||
* |
||||
* Contributor(s): |
||||
* Rob Campbell <robcee@mozilla.com> (original author) |
||||
* Erik Vold <erikvvold@gmail.com> |
||||
* David Dahl <ddahl@mozilla.com> |
||||
* Mihai Sucan <mihai.sucan@gmail.com> |
||||
* |
||||
* Alternatively, the contents of this file may be used under the terms of |
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or |
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), |
||||
* in which case the provisions of the GPL or the LGPL are applicable instead |
||||
* of those above. If you wish to allow use of your version of this file only |
||||
* under the terms of either the GPL or the LGPL, and not to allow others to |
||||
* use your version of this file under the terms of the MPL, indicate your |
||||
* decision by deleting the provisions above and replace them with the notice |
||||
* and other provisions required by the GPL or the LGPL. If you do not delete |
||||
* the provisions above, a recipient may use your version of this file under |
||||
* the terms of any one of the MPL, the GPL or the LGPL. |
||||
* |
||||
* ***** END LICENSE BLOCK *****/ |
||||
|
||||
/* |
||||
* Original version history can be found here: |
||||
* https://github.com/mozilla/workspace
|
||||
* |
||||
* Copied and relicensed from the Public Domain. |
||||
* See bug 653934 for details. |
||||
* https://bugzilla.mozilla.org/show_bug.cgi?id=653934
|
||||
*/ |
||||
|
||||
const Cc = Components.classes; |
||||
const Ci = Components.interfaces; |
||||
const Cu = Components.utils; |
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm"); |
||||
Cu.import("resource://gre/modules/Services.jsm"); |
||||
Cu.import("resource://gre/modules/NetUtil.jsm"); |
||||
Cu.import("resource:///modules/communicator/devtools/PropertyPanel.jsm"); |
||||
|
||||
const SCRATCHPAD_CONTEXT_CONTENT = 1; |
||||
const SCRATCHPAD_CONTEXT_BROWSER = 2; |
||||
const SCRATCHPAD_WINDOW_URL = "chrome://communicator/content/devtools/scratchpad.xul"; |
||||
const SCRATCHPAD_L10N = "chrome://communicator/locale/devtools/scratchpad.properties"; |
||||
const SCRATCHPAD_WINDOW_FEATURES = "chrome,titlebar,toolbar,centerscreen,resizable,dialog=no"; |
||||
const DEVTOOLS_CHROME_ENABLED = "devtools.chrome.enabled"; |
||||
|
||||
const PREF_TABSIZE = "devtools.editor.tabsize"; |
||||
const PREF_EXPANDTAB = "devtools.editor.expandtab"; |
||||
|
||||
/** |
||||
* The scratchpad object handles the Scratchpad window functionality. |
||||
*/ |
||||
var Scratchpad = { |
||||
/** |
||||
* The script execution context. This tells Scratchpad in which context the |
||||
* script shall execute. |
||||
* |
||||
* Possible values: |
||||
* - SCRATCHPAD_CONTEXT_CONTENT to execute code in the context of the current |
||||
* tab content window object. |
||||
* - SCRATCHPAD_CONTEXT_BROWSER to execute code in the context of the |
||||
* currently active chrome window object. |
||||
*/ |
||||
executionContext: SCRATCHPAD_CONTEXT_CONTENT, |
||||
|
||||
/** |
||||
* Retrieve the xul:textbox DOM element. This element holds the source code |
||||
* the user writes and executes. |
||||
*/ |
||||
get textbox() document.getElementById("scratchpad-textbox"), |
||||
|
||||
/** |
||||
* Retrieve the xul:statusbarpanel DOM element. The status bar tells the |
||||
* current code execution context. |
||||
*/ |
||||
get statusbarStatus() document.getElementById("scratchpad-status"), |
||||
|
||||
/** |
||||
* Get the selected text from the textbox. |
||||
*/ |
||||
get selectedText() |
||||
{ |
||||
return this.textbox.value.substring(this.textbox.selectionStart, |
||||
this.textbox.selectionEnd); |
||||
}, |
||||
|
||||
/** |
||||
* Get the most recent chrome window of type navigator:browser. |
||||
*/ |
||||
get browserWindow() Services.wm.getMostRecentWindow("navigator:browser"), |
||||
|
||||
/** |
||||
* Reference to the last chrome window of type navigator:browser. We use this |
||||
* to check if the chrome window changed since the last code evaluation. |
||||
*/ |
||||
_previousWindow: null, |
||||
|
||||
/** |
||||
* Get the gBrowser object of the most recent browser window. |
||||
*/ |
||||
get gBrowser() |
||||
{ |
||||
let recentWin = this.browserWindow; |
||||
return recentWin ? recentWin.gBrowser : null; |
||||
}, |
||||
|
||||
insertIntro: function SP_insertIntro() |
||||
{ |
||||
this.textbox.value = this.strings.GetStringFromName("scratchpadIntro"); |
||||
}, |
||||
|
||||
/** |
||||
* Cached Cu.Sandbox object for the active tab content window object. |
||||
*/ |
||||
_contentSandbox: null, |
||||
|
||||
/** |
||||
* Get the Cu.Sandbox object for the active tab content window object. Note |
||||
* that the returned object is cached for later reuse. The cached object is |
||||
* kept only for the current location in the current tab of the current |
||||
* browser window and it is reset for each context switch, |
||||
* navigator:browser window switch, tab switch or navigation. |
||||
*/ |
||||
get contentSandbox() |
||||
{ |
||||
if (!this.browserWindow) { |
||||
Cu.reportError(this.strings. |
||||
GetStringFromName("browserWindow.unavailable")); |
||||
return; |
||||
} |
||||
|
||||
if (!this._contentSandbox || |
||||
this.browserWindow != this._previousBrowserWindow || |
||||
this._previousBrowser != this.gBrowser.selectedBrowser || |
||||
this._previousLocation != this.gBrowser.contentWindow.location.href) { |
||||
let contentWindow = this.gBrowser.selectedBrowser.contentWindow; |
||||
this._contentSandbox = new Cu.Sandbox(contentWindow, |
||||
{ sandboxPrototype: contentWindow, wantXrays: false }); |
||||
|
||||
this._previousBrowserWindow = this.browserWindow; |
||||
this._previousBrowser = this.gBrowser.selectedBrowser; |
||||
this._previousLocation = contentWindow.location.href; |
||||
} |
||||
|
||||
return this._contentSandbox; |
||||
}, |
||||
|
||||
/** |
||||
* Cached Cu.Sandbox object for the most recently active navigator:browser |
||||
* chrome window object. |
||||
*/ |
||||
_chromeSandbox: null, |
||||
|
||||
/** |
||||
* Get the Cu.Sandbox object for the most recently active navigator:browser |
||||
* chrome window object. Note that the returned object is cached for later |
||||
* reuse. The cached object is kept only for the current browser window and it |
||||
* is reset for each context switch or navigator:browser window switch. |
||||
*/ |
||||
get chromeSandbox() |
||||
{ |
||||
if (!this.browserWindow) { |
||||
Cu.reportError(this.strings. |
||||
GetStringFromName("browserWindow.unavailable")); |
||||
return; |
||||
} |
||||
|
||||
if (!this._chromeSandbox || |
||||
this.browserWindow != this._previousBrowserWindow) { |
||||
this._chromeSandbox = new Cu.Sandbox(this.browserWindow, |
||||
{ sandboxPrototype: this.browserWindow, wantXrays: false }); |
||||
|
||||
this._previousBrowserWindow = this.browserWindow; |
||||
} |
||||
|
||||
return this._chromeSandbox; |
||||
}, |
||||
|
||||
/** |
||||
* Drop the textbox selection. |
||||
*/ |
||||
deselect: function SP_deselect() |
||||
{ |
||||
this.textbox.selectionEnd = this.textbox.selectionStart; |
||||
}, |
||||
|
||||
/** |
||||
* Select a specific range in the Scratchpad xul:textbox. |
||||
* |
||||
* @param number aStart |
||||
* Selection range start. |
||||
* @param number aEnd |
||||
* Selection range end. |
||||
*/ |
||||
selectRange: function SP_selectRange(aStart, aEnd) |
||||
{ |
||||
this.textbox.selectionStart = aStart; |
||||
this.textbox.selectionEnd = aEnd; |
||||
}, |
||||
|
||||
/** |
||||
* Evaluate a string in the active tab content window. |
||||
* |
||||
* @param string aString |
||||
* The script you want evaluated. |
||||
* @return mixed |
||||
* The script evaluation result. |
||||
*/ |
||||
evalInContentSandbox: function SP_evalInContentSandbox(aString) |
||||
{ |
||||
let result; |
||||
try { |
||||
result = Cu.evalInSandbox(aString, this.contentSandbox, "1.8", |
||||
"Scratchpad", 1); |
||||
} |
||||
catch (ex) { |
||||
this.openWebConsole(); |
||||
|
||||
let contentWindow = this.gBrowser.selectedBrowser.contentWindow; |
||||
|
||||
let scriptError = Cc["@mozilla.org/scripterror;1"]. |
||||
createInstance(Ci.nsIScriptError2); |
||||
|
||||
scriptError.initWithWindowID(ex.message + "\n" + ex.stack, ex.fileName, |
||||
"", ex.lineNumber, 0, scriptError.errorFlag, |
||||
"content javascript", |
||||
this.getWindowId(contentWindow)); |
||||
|
||||
Services.console.logMessage(scriptError); |
||||
} |
||||
|
||||
return result; |
||||
}, |
||||
|
||||
/** |
||||
* Evaluate a string in the most recent navigator:browser chrome window. |
||||
* |
||||
* @param string aString |
||||
* The script you want evaluated. |
||||
* @return mixed |
||||
* The script evaluation result. |
||||
*/ |
||||
evalInChromeSandbox: function SP_evalInChromeSandbox(aString) |
||||
{ |
||||
let result; |
||||
try { |
||||
result = Cu.evalInSandbox(aString, this.chromeSandbox, "1.8", |
||||
"Scratchpad", 1); |
||||
} |
||||
catch (ex) { |
||||
Cu.reportError(ex); |
||||
Cu.reportError(ex.stack); |
||||
this.openErrorConsole(); |
||||
} |
||||
|
||||
return result; |
||||
}, |
||||
|
||||
/** |
||||
* Evaluate a string in the currently desired context, that is either the |
||||
* chrome window or the tab content window object. |
||||
* |
||||
* @param string aString |
||||
* The script you want to evaluate. |
||||
* @return mixed |
||||
* The script evaluation result. |
||||
*/ |
||||
evalForContext: function SP_evaluateForContext(aString) |
||||
{ |
||||
return this.executionContext == SCRATCHPAD_CONTEXT_CONTENT ? |
||||
this.evalInContentSandbox(aString) : |
||||
this.evalInChromeSandbox(aString); |
||||
}, |
||||
|
||||
/** |
||||
* Execute the selected text (if any) or the entire textbox content in the |
||||
* current context. |
||||
*/ |
||||
run: function SP_run() |
||||
{ |
||||
let selection = this.selectedText || this.textbox.value; |
||||
let result = this.evalForContext(selection); |
||||
this.deselect(); |
||||
return [selection, result]; |
||||
}, |
||||
|
||||
/** |
||||
* Execute the selected text (if any) or the entire textbox content in the |
||||
* current context. The resulting object is opened up in the Property Panel |
||||
* for inspection. |
||||
*/ |
||||
inspect: function SP_inspect() |
||||
{ |
||||
let [selection, result] = this.run(); |
||||
|
||||
if (result) { |
||||
this.openPropertyPanel(selection, result); |
||||
} |
||||
}, |
||||
|
||||
/** |
||||
* Execute the selected text (if any) or the entire textbox content in the |
||||
* current context. The evaluation result is inserted into the textbox after |
||||
* the selected text, or at the end of the textbox value if there is no |
||||
* selected text. |
||||
*/ |
||||
display: function SP_display() |
||||
{ |
||||
let selectionStart = this.textbox.selectionStart; |
||||
let selectionEnd = this.textbox.selectionEnd; |
||||
if (selectionStart == selectionEnd) { |
||||
selectionEnd = this.textbox.value.length; |
||||
} |
||||
|
||||
let [selection, result] = this.run(); |
||||
if (!result) { |
||||
return; |
||||
} |
||||
|
||||
let firstPiece = this.textbox.value.slice(0, selectionEnd); |
||||
let lastPiece = this.textbox.value. |
||||
slice(selectionEnd, this.textbox.value.length); |
||||
|
||||
let newComment = "/*\n" + result.toString() + "\n*/"; |
||||
|
||||
this.textbox.value = firstPiece + newComment + lastPiece; |
||||
|
||||
// Select the added comment.
|
||||
this.selectRange(firstPiece.length, firstPiece.length + newComment.length); |
||||
}, |
||||
|
||||
/** |
||||
* Open the Property Panel to inspect the given object. |
||||
* |
||||
* @param string aEvalString |
||||
* The string that was evaluated. This is re-used when the user updates |
||||
* the properties list, by clicking the Update button. |
||||
* @param object aOutputObject |
||||
* The object to inspect, which is the aEvalString evaluation result. |
||||
* @return object |
||||
* The PropertyPanel object instance. |
||||
*/ |
||||
openPropertyPanel: function SP_openPropertyPanel(aEvalString, aOutputObject) |
||||
{ |
||||
let self = this; |
||||
let propPanel; |
||||
// The property panel has a button:
|
||||
// `Update`: reexecutes the string executed on the command line. The
|
||||
// result will be inspected by this panel.
|
||||
let buttons = []; |
||||
|
||||
// If there is a evalString passed to this function, then add a `Update`
|
||||
// button to the panel so that the evalString can be reexecuted to update
|
||||
// the content of the panel.
|
||||
if (aEvalString !== null) { |
||||
buttons.push({ |
||||
label: this.strings. |
||||
GetStringFromName("propertyPanel.updateButton.label"), |
||||
accesskey: this.strings. |
||||
GetStringFromName("propertyPanel.updateButton.accesskey"), |
||||
oncommand: function () { |
||||
try { |
||||
let result = self.evalForContext(aEvalString); |
||||
|
||||
if (result !== undefined) { |
||||
propPanel.treeView.data = result; |
||||
} |
||||
} |
||||
catch (ex) { } |
||||
} |
||||
}); |
||||
} |
||||
|
||||
let doc = this.browserWindow.document; |
||||
let parent = doc.getElementById("mainPopupSet"); |
||||
let title = aOutputObject.toString(); |
||||
propPanel = new PropertyPanel(parent, doc, title, aOutputObject, buttons); |
||||
|
||||
let panel = propPanel.panel; |
||||
panel.setAttribute("class", "scratchpad_propertyPanel"); |
||||
panel.openPopup(null, "after_pointer", 0, 0, false, false); |
||||
panel.sizeTo(200, 400); |
||||
|
||||
return propPanel; |
||||
}, |
||||
|
||||
// Menu Operations
|
||||
|
||||
/** |
||||
* Open a new Scratchpad window. |
||||
*/ |
||||
openScratchpad: function SP_openScratchpad() |
||||
{ |
||||
Services.ww.openWindow(null, SCRATCHPAD_WINDOW_URL, "_blank", |
||||
SCRATCHPAD_WINDOW_FEATURES, null); |
||||
}, |
||||
|
||||
/** |
||||
* Export the textbox content to a file. |
||||
* |
||||
* @param nsILocalFile aFile |
||||
* The file where you want to save the textbox content. |
||||
* @param boolean aNoConfirmation |
||||
* If the file already exists, ask for confirmation? |
||||
* @param boolean aSilentError |
||||
* True if you do not want to display an error when file save fails, |
||||
* false otherwise. |
||||
* @param function aCallback |
||||
* Optional function you want to call when file save completes. It will |
||||
* get the following arguments: |
||||
* 1) the nsresult status code for the export operation. |
||||
*/ |
||||
exportToFile: function SP_exportToFile(aFile, aNoConfirmation, aSilentError, |
||||
aCallback) |
||||
{ |
||||
if (!aNoConfirmation && aFile.exists() && |
||||
!window.confirm(this.strings. |
||||
GetStringFromName("export.fileOverwriteConfirmation"))) { |
||||
return; |
||||
} |
||||
|
||||
let fs = Cc["@mozilla.org/network/file-output-stream;1"]. |
||||
createInstance(Ci.nsIFileOutputStream); |
||||
let modeFlags = 0x02 | 0x08 | 0x20; |
||||
fs.init(aFile, modeFlags, 0644, fs.DEFER_OPEN); |
||||
|
||||
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]. |
||||
createInstance(Ci.nsIScriptableUnicodeConverter); |
||||
converter.charset = "UTF-8"; |
||||
let input = converter.convertToInputStream(this.textbox.value); |
||||
|
||||
let self = this; |
||||
NetUtil.asyncCopy(input, fs, function(aStatus) { |
||||
if (!aSilentError && !Components.isSuccessCode(aStatus)) { |
||||
window.alert(self.strings.GetStringFromName("saveFile.failed")); |
||||
} |
||||
|
||||
if (aCallback) { |
||||
aCallback.call(self, aStatus); |
||||
} |
||||
}); |
||||
}, |
||||
|
||||
/** |
||||
* Read the content of a file and put it into the textbox. |
||||
* |
||||
* @param nsILocalFile aFile |
||||
* The file you want to save the textbox content into. |
||||
* @param boolean aSilentError |
||||
* True if you do not want to display an error when file load fails, |
||||
* false otherwise. |
||||
* @param function aCallback |
||||
* Optional function you want to call when file load completes. It will |
||||
* get the following arguments: |
||||
* 1) the nsresult status code for the import operation. |
||||
* 2) the data that was read from the file, if any. |
||||
*/ |
||||
importFromFile: function SP_importFromFile(aFile, aSilentError, aCallback) |
||||
{ |
||||
// Prevent file type detection.
|
||||
let channel = NetUtil.newChannel(aFile); |
||||
channel.contentType = "application/javascript"; |
||||
|
||||
let self = this; |
||||
NetUtil.asyncFetch(channel, function(aInputStream, aStatus) { |
||||
let content = null; |
||||
|
||||
if (Components.isSuccessCode(aStatus)) { |
||||
content = NetUtil.readInputStreamToString(aInputStream, |
||||
aInputStream.available()); |
||||
self.textbox.value = content; |
||||
} |
||||
else if (!aSilentError) { |
||||
window.alert(self.strings.GetStringFromName("openFile.failed")); |
||||
} |
||||
|
||||
if (aCallback) { |
||||
aCallback.call(self, aStatus, content); |
||||
} |
||||
}); |
||||
}, |
||||
|
||||
/** |
||||
* Open a file to edit in the Scratchpad. |
||||
*/ |
||||
openFile: function SP_openFile() |
||||
{ |
||||
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); |
||||
fp.init(window, this.strings.GetStringFromName("openFile.title"), |
||||
Ci.nsIFilePicker.modeOpen); |
||||
fp.defaultString = ""; |
||||
if (fp.show() != Ci.nsIFilePicker.returnCancel) { |
||||
document.title = this.filename = fp.file.path; |
||||
this.importFromFile(fp.file); |
||||
} |
||||
}, |
||||
|
||||
/** |
||||
* Save the textbox content to the currently open file. |
||||
*/ |
||||
saveFile: function SP_saveFile() |
||||
{ |
||||
if (!this.filename) { |
||||
return this.saveFileAs(); |
||||
} |
||||
|
||||
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile); |
||||
file.initWithPath(this.filename); |
||||
this.exportToFile(file, true); |
||||
}, |
||||
|
||||
/** |
||||
* Save the textbox content to a new file. |
||||
*/ |
||||
saveFileAs: function SP_saveFileAs() |
||||
{ |
||||
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); |
||||
fp.init(window, this.strings.GetStringFromName("saveFileAs"), |
||||
Ci.nsIFilePicker.modeSave); |
||||
fp.defaultString = "scratchpad.js"; |
||||
if (fp.show() != Ci.nsIFilePicker.returnCancel) { |
||||
document.title = this.filename = fp.file.path; |
||||
this.exportToFile(fp.file, true); |
||||
} |
||||
}, |
||||
|
||||
/** |
||||
* Open the Error Console. |
||||
*/ |
||||
openErrorConsole: function SP_openErrorConsole() |
||||
{ |
||||
this.browserWindow.toJavaScriptConsole(); |
||||
}, |
||||
|
||||
/** |
||||
* Open the Web Console. |
||||
*/ |
||||
openWebConsole: function SP_openWebConsole() |
||||
{ |
||||
if (!this.browserWindow.HUDConsoleUI.getOpenHUD()) { |
||||
this.browserWindow.HUDConsoleUI.toggleHUD(); |
||||
} |
||||
this.browserWindow.focus(); |
||||
}, |
||||
|
||||
/** |
||||
* Set the current execution context to be the active tab content window. |
||||
*/ |
||||
setContentContext: function SP_setContentContext() |
||||
{ |
||||
let content = document.getElementById("sp-menu-content"); |
||||
document.getElementById("sp-menu-browser").removeAttribute("checked"); |
||||
content.setAttribute("checked", true); |
||||
this.executionContext = SCRATCHPAD_CONTEXT_CONTENT; |
||||
this.statusbarStatus.label = content.getAttribute("label"); |
||||
this.resetContext(); |
||||
}, |
||||
|
||||
/** |
||||
* Set the current execution context to be the most recent chrome window. |
||||
*/ |
||||
setBrowserContext: function SP_setBrowserContext() |
||||
{ |
||||
let browser = document.getElementById("sp-menu-browser"); |
||||
document.getElementById("sp-menu-content").removeAttribute("checked"); |
||||
browser.setAttribute("checked", true); |
||||
this.executionContext = SCRATCHPAD_CONTEXT_BROWSER; |
||||
this.statusbarStatus.label = browser.getAttribute("label"); |
||||
this.resetContext(); |
||||
}, |
||||
|
||||
/** |
||||
* Reset the cached Cu.Sandbox object for the current context. |
||||
*/ |
||||
resetContext: function SP_resetContext() |
||||
{ |
||||
this._chromeSandbox = null; |
||||
this._contentSandbox = null; |
||||
this._previousWindow = null; |
||||
this._previousBrowser = null; |
||||
this._previousLocation = null; |
||||
}, |
||||
|
||||
/** |
||||
* Gets the ID of the outer window of the given DOM window object. |
||||
* |
||||
* @param nsIDOMWindow aWindow |
||||
* @return integer |
||||
* the outer window ID |
||||
*/ |
||||
getWindowId: function SP_getWindowId(aWindow) |
||||
{ |
||||
return aWindow.QueryInterface(Ci.nsIInterfaceRequestor). |
||||
getInterface(Ci.nsIDOMWindowUtils).outerWindowID; |
||||
}, |
||||
|
||||
/** |
||||
* The Scratchpad window DOMContentLoaded event handler. |
||||
*/ |
||||
onLoad: function SP_onLoad() |
||||
{ |
||||
let chromeContextMenu = document.getElementById("sp-menu-browser"); |
||||
let errorConsoleMenu = document.getElementById("sp-menu-errorConsole"); |
||||
let errorConsoleCommand = document.getElementById("sp-cmd-errorConsole"); |
||||
let chromeContextCommand = document.getElementById("sp-cmd-browserContext"); |
||||
|
||||
let chrome = Services.prefs.getBoolPref(DEVTOOLS_CHROME_ENABLED, true); |
||||
if (chrome) { |
||||
chromeContextMenu.removeAttribute("hidden"); |
||||
errorConsoleMenu.removeAttribute("hidden"); |
||||
errorConsoleCommand.removeAttribute("disabled"); |
||||
chromeContextCommand.removeAttribute("disabled"); |
||||
} |
||||
|
||||
let tabsize = Services.prefs.getIntPref(PREF_TABSIZE, 2); |
||||
if (tabsize < 1) { |
||||
// tabsize is invalid, clear back to the default value.
|
||||
Services.prefs.clearUserPref(PREF_TABSIZE); |
||||
tabsize = Services.prefs.getIntPref(PREF_TABSIZE, 2); |
||||
} |
||||
|
||||
let expandtab = Services.prefs.getBoolPref(PREF_EXPANDTAB, true); |
||||
this._tabCharacter = expandtab ? (new Array(tabsize + 1)).join(" ") : "\t"; |
||||
this.textbox.style.MozTabSize = tabsize; |
||||
|
||||
// Force LTR direction (otherwise the textbox inherits the locale direction)
|
||||
this.textbox.style.direction = "ltr"; |
||||
|
||||
this.textbox.style.border = "none"; |
||||
|
||||
this.insertIntro(); |
||||
|
||||
// Make the Tab key work.
|
||||
this.textbox.addEventListener("keypress", this.onKeypress.bind(this), false); |
||||
|
||||
this.textbox.focus(); |
||||
}, |
||||
|
||||
/** |
||||
* The textbox keypress event handler which allows users to indent code using |
||||
* the Tab key. |
||||
* |
||||
* @param nsIDOMEvent aEvent |
||||
*/ |
||||
onKeypress: function SP_onKeypress(aEvent) |
||||
{ |
||||
if (aEvent.keyCode == aEvent.DOM_VK_TAB) { |
||||
this.insertTextAtCaret(this._tabCharacter); |
||||
aEvent.preventDefault(); |
||||
} |
||||
}, |
||||
|
||||
/** |
||||
* Insert text at the current caret location. |
||||
* |
||||
* @param string aText |
||||
*/ |
||||
insertTextAtCaret: function SP_insertTextAtCaret(aText) |
||||
{ |
||||
let firstPiece = this.textbox.value.substring(0, this.textbox.selectionStart); |
||||
let lastPiece = this.textbox.value.substring(this.textbox.selectionEnd); |
||||
this.textbox.value = firstPiece + aText + lastPiece; |
||||
|
||||
let newCaretPosition = firstPiece.length + aText.length; |
||||
this.selectRange(newCaretPosition, newCaretPosition); |
||||
}, |
||||
}; |
||||
|
||||
XPCOMUtils.defineLazyGetter(Scratchpad, "strings", function () { |
||||
return Services.strings.createBundle(SCRATCHPAD_L10N); |
||||
}); |
||||
|
||||
addEventListener("DOMContentLoaded", Scratchpad.onLoad.bind(Scratchpad), false); |
||||
|
@ -0,0 +1,352 @@
|
||||
<?xml version="1.0"?> |
||||
<!-- ***** BEGIN LICENSE BLOCK ***** |
||||
- Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
||||
- |
||||
- The contents of this file are subject to the Mozilla Public License Version |
||||
- 1.1 (the "License"); you may not use this file except in compliance with |
||||
- the License. You may obtain a copy of the License at |
||||
- http://www.mozilla.org/MPL/ |
||||
- |
||||
- Software distributed under the License is distributed on an "AS IS" basis, |
||||
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
||||
- for the specific language governing rights and limitations under the |
||||
- License. |
||||
- |
||||
- The Original Code is Scratchpad. |
||||
- |
||||
- The Initial Developer of the Original Code is |
||||
- The Mozilla Foundation. |
||||
- Portions created by the Initial Developer are Copyright (C) 2011 |
||||
- the Initial Developer. All Rights Reserved. |
||||
- |
||||
- Contributor(s): |
||||
- Rob Campbell <robcee@mozilla.com> (original author) |
||||
- Mihai Sucan <mihai.sucan@gmail.com> |
||||
- Erik Vold <erikvvold@gmail.com> |
||||
- |
||||
- Alternatively, the contents of this file may be used under the terms of |
||||
- either the GNU General Public License Version 2 or later (the "GPL"), or |
||||
- the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), |
||||
- in which case the provisions of the GPL or the LGPL are applicable instead |
||||
- of those above. If you wish to allow use of your version of this file only |
||||
- under the terms of either the GPL or the LGPL, and not to allow others to |
||||
- use your version of this file under the terms of the MPL, indicate your |
||||
- decision by deleting the provisions above and replace them with the notice |
||||
- and other provisions required by the GPL or the LGPL. If you do not delete |
||||
- the provisions above, a recipient may use your version of this file under |
||||
- the terms of any one of the MPL, the GPL or the LGPL. |
||||
- |
||||
- ***** END LICENSE BLOCK ***** --> |
||||
|
||||
<!DOCTYPE window [ |
||||
<!ENTITY % scratchpadDTD SYSTEM "chrome://communicator/locale/devtools/scratchpad.dtd" > |
||||
%scratchpadDTD; |
||||
]> |
||||
|
||||
<?xml-stylesheet href="chrome://communicator/skin/communicator.css" type="text/css"?> |
||||
<?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?> |
||||
|
||||
<window id="main-window" |
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" |
||||
title="&window.title;" |
||||
windowtype="devtools:scratchpad" |
||||
screenX="4" screenY="4" |
||||
width="640" height="480" |
||||
persist="screenX screenY width height sizemode"> |
||||
|
||||
<script type="application/javascript" src="chrome://global/content/globalOverlay.js"/> |
||||
<script type="application/javascript" src="chrome://communicator/content/devtools/scratchpad.js"/> |
||||
|
||||
<commandset id="editMenuCommands"/> |
||||
|
||||
<commandset id="sp-commandset"> |
||||
<command id="sp-cmd-newWindow" oncommand="Scratchpad.openScratchpad();"/> |
||||
<command id="sp-cmd-openFile" oncommand="Scratchpad.openFile();"/> |
||||
<command id="sp-cmd-save" oncommand="Scratchpad.saveFile();"/> |
||||
<command id="sp-cmd-saveas" oncommand="Scratchpad.saveFileAs();"/> |
||||
|
||||
<!-- TODO: bug 650340 - implement printFile() |
||||
<command id="sp-cmd-printFile" oncommand="Scratchpad.printFile();" disabled="true"/> |
||||
--> |
||||
|
||||
<command id="sp-cmd-close" oncommand="window.close();"/> |
||||
<command id="sp-cmd-run" oncommand="Scratchpad.run();"/> |
||||
<command id="sp-cmd-inspect" oncommand="Scratchpad.inspect();"/> |
||||
<command id="sp-cmd-display" oncommand="Scratchpad.display();"/> |
||||
<command id="sp-cmd-contentContext" oncommand="Scratchpad.setContentContext();"/> |
||||
<command id="sp-cmd-browserContext" oncommand="Scratchpad.setBrowserContext();" disabled="true"/> |
||||
<command id="sp-cmd-resetContext" oncommand="Scratchpad.resetContext();"/> |
||||
<command id="sp-cmd-errorConsole" oncommand="Scratchpad.openErrorConsole();" disabled="true"/> |
||||
<command id="sp-cmd-webConsole" oncommand="Scratchpad.openWebConsole();"/> |
||||
</commandset> |
||||
|
||||
<keyset id="sp-keyset"> |
||||
<key id="sp-key-window" |
||||
key="&newWindowCmd.commandkey;" |
||||
command="sp-cmd-newWindow" |
||||
modifiers="accel"/> |
||||
<key id="sp-key-open" |
||||
key="&openFileCmd.commandkey;" |
||||
command="sp-cmd-openFile" |
||||
modifiers="accel"/> |
||||
<key id="sp-key-save" |
||||
key="&saveFileCmd.commandkey;" |
||||
command="sp-cmd-save" |
||||
modifiers="accel"/> |
||||
<key id="sp-key-close" |
||||
key="&closeCmd.key;" |
||||
command="sp-cmd-close" |
||||
modifiers="accel"/> |
||||
|
||||
<!-- TODO: bug 650340 - implement printFile |
||||
<key id="sp-key-printFile" |
||||
key="&printCmd.commandkey;" |
||||
command="sp-cmd-printFile" |
||||
modifiers="accel"/> |
||||
--> |
||||
|
||||
<key id="key_cut" |
||||
key="&cutCmd.key;" |
||||
modifiers="accel"/> |
||||
|
||||
<key id="key_copy" |
||||
key="©Cmd.key;" |
||||
modifiers="accel"/> |
||||
<key id="key_paste" |
||||
key="&pasteCmd.key;" |
||||
modifiers="accel"/> |
||||
<key id="key_selectAll" key="&selectAllCmd.key;" modifiers="accel"/> |
||||
<key id="key_undo" key="&undoCmd.key;" modifiers="accel"/> |
||||
<key id="key_redo" key="&undoCmd.key;" modifiers="accel,shift"/> |
||||
<key id="sp-key-run" |
||||
key="&run.key;" |
||||
command="sp-cmd-run" |
||||
modifiers="accel"/> |
||||
<!-- |
||||
<key id="sp-key-inspect" |
||||
key="&inspect.key;" |
||||
command="sp-cmd-inspect" |
||||
modifiers="accel"/> |
||||
<key id="sp-key-display" |
||||
key="&display.key;" |
||||
command="sp-cmd-display" |
||||
modifiers="accel"/> |
||||
--> |
||||
<key id="sp-key-errorConsole" |
||||
key="&errorConsoleCmd.commandkey;" |
||||
command="sp-cmd-errorConsole" |
||||
modifiers="accel,shift"/> |
||||
<key id="sp-key-webConsole" |
||||
key="&webConsoleCmd.commandkey;" |
||||
command="sp-cmd-webConsole" |
||||
modifiers="accel,shift"/> |
||||
</keyset> |
||||
|
||||
|
||||
<menubar id="sp-menubar" xpfe="false"> |
||||
<menu id="sp-file-menu" label="&fileMenu.label;" |
||||
accesskey="&fileMenu.accesskey;"> |
||||
<menupopup id="sp-menu-filepopup"> |
||||
<menuitem id="sp-menu-newscratchpad" |
||||
label="&newWindowCmd.label;" |
||||
accesskey="&newWindowCmd.accesskey;" |
||||
key="sp-key-window" |
||||
command="sp-cmd-newWindow"/> |
||||
<menuseparator/> |
||||
<menuitem id="sp-menu-open" |
||||
label="&openFileCmd.label;" |
||||
command="sp-cmd-openFile" |
||||
key="sp-key-open" |
||||
accesskey="&openFileCmd.accesskey;"/> |
||||
<menuitem id="sp-menu-save" |
||||
label="&saveFileCmd.label;" |
||||
accesskey="&saveFileCmd.accesskey;" |
||||
key="sp-key-save" |
||||
command="sp-cmd-save"/> |
||||
<menuitem id="sp-menu-saveas" |
||||
label="&saveFileAsCmd.label;" |
||||
accesskey="&saveFileAsCmd.accesskey;" |
||||
command="sp-cmd-saveas"/> |
||||
<menuseparator/> |
||||
|
||||
<!-- TODO: bug 650340 - implement printFile |
||||
<menuitem id="sp-menu-print" |
||||
label="&printCmd.label;" |
||||
accesskey="&printCmd.accesskey;" |
||||
command="sp-cmd-printFile"/> |
||||
<menuseparator/> |
||||
--> |
||||
|
||||
<menuitem id="sp-menu-close" |
||||
label="&closeCmd.label;" |
||||
key="sp-key-close" |
||||
accesskey="&closeCmd.accesskey;" |
||||
command="sp-cmd-close"/> |
||||
</menupopup> |
||||
</menu> |
||||
|
||||
<menu id="sp-edit-menu" label="&editMenu.label;" |
||||
accesskey="&editMenu.accesskey;"> |
||||
<menupopup id="sp-menu_editpopup"> |
||||
<menuitem id="sp-menu-undo" |
||||
label="&undoCmd.label;" |
||||
key="key_undo" |
||||
accesskey="&undoCmd.accesskey;" |
||||
disabled="true" |
||||
command="cmd_undo"/> |
||||
<menuitem id="sp-menu-redo" |
||||
label="&redoCmd.label;" |
||||
key="key_redo" |
||||
disabled="true" |
||||
accesskey="&redoCmd.accesskey;" |
||||
command="cmd_redo"/> |
||||
<menuseparator/> |
||||
<menuitem id="sp-menu-cut" |
||||
label="&cutCmd.label;" |
||||
key="key_cut" |
||||
accesskey="&cutCmd.accesskey;" |
||||
command="cmd_cut"/> |
||||
<menuitem id="sp-menu-copy" |
||||
label="©Cmd.label;" |
||||
key="key_copy" |
||||
accesskey="©Cmd.accesskey;" |
||||
command="cmd_copy"/> |
||||
<menuitem id="sp-menu-paste" |
||||
label="&pasteCmd.label;" |
||||
key="key_paste" |
||||
accesskey="&pasteCmd.accesskey;" |
||||
command="cmd_paste"/> |
||||
<menuseparator/> |
||||
<menuitem id="sp-menu-selectAll" |
||||
label="&selectAllCmd.label;" |
||||
key="key_selectAll" |
||||
accesskey="&selectAllCmd.accesskey;" |
||||
command="cmd_selectAll"/> |
||||
|
||||
<!-- TODO: bug 650345 - implement search and replace |
||||
<menuitem id="sp-menu-find" |
||||
label="&findOnCmd.label;" |
||||
accesskey="&findOnCmd.accesskey;" |
||||
key="key_find" |
||||
disabled="true" |
||||
command="cmd_find"/> |
||||
<menuitem id="sp-menu-findAgain" |
||||
label="&findAgainCmd.label;" |
||||
accesskey="&findAgainCmd.accesskey;" |
||||
key="key_findAgain" |
||||
disabled="true" |
||||
command="cmd_findAgain"/> |
||||
<menuseparator id="sp-execute-separator"/> |
||||
--> |
||||
|
||||
</menupopup> |
||||
</menu> |
||||
|
||||
<menu id="sp-execute-menu" label="&executeMenu.label;" |
||||
accesskey="&executeMenu.accesskey;"> |
||||
<menupopup id="sp-menu_executepopup"> |
||||
<menuitem id="sp-text-run" |
||||
label="&run.label;" |
||||
accesskey="&run.accesskey;" |
||||
key="sp-key-run" |
||||
command="sp-cmd-run"/> |
||||
<!-- |
||||
<menuitem id="sp-text-inspect" |
||||
label="&inspect.label;" |
||||
accesskey="&inspect.accesskey;" |
||||
key="sp-key-inspect" |
||||
command="sp-cmd-inspect"/> |
||||
<menuitem id="sp-text-display" |
||||
label="&display.label;" |
||||
accesskey="&display.accesskey;" |
||||
key="sp-key-display" |
||||
command="sp-cmd-display"/> |
||||
--> |
||||
</menupopup> |
||||
</menu> |
||||
|
||||
<menu id="sp-environment-menu" |
||||
label="&environmentMenu.label;" |
||||
accesskey="&environmentMenu.accesskey;"> |
||||
<menupopup id="sp-menu-environment"> |
||||
<menuitem id="sp-menu-content" |
||||
label="&contentContext.label;" |
||||
accesskey="&contentContext.accesskey;" |
||||
command="sp-cmd-contentContext" |
||||
checked="true" |
||||
type="radio"/> |
||||
<menuitem id="sp-menu-browser" hidden="true" |
||||
command="sp-cmd-browserContext" |
||||
label="&browserContext.label;" |
||||
accesskey="&browserContext.accesskey;" |
||||
type="radio"/> |
||||
<menuseparator/> |
||||
<menuitem id="sp-menu-resetContext" |
||||
command="sp-cmd-resetContext" |
||||
label="&resetContext.label;" |
||||
accesskey="&resetContext.accesskey;"/> |
||||
</menupopup> |
||||
</menu> |
||||
|
||||
<menu id="sp-tools-menu" |
||||
label="&toolsMenu.label;" |
||||
accesskey="&toolsMenu.accesskey;"> |
||||
<menupopup id="sp-menu-tools"> |
||||
<menuitem id="sp-menu-errorConsole" hidden="true" |
||||
label="&errorConsoleCmd.label;" |
||||
accesskey="&errorConsoleCmd.accesskey;" |
||||
key="sp-key-errorConsole" |
||||
command="sp-cmd-errorConsole"/> |
||||
<!-- |
||||
<menuitem id="sp-menu-webConsole" |
||||
label="&webConsoleCmd.label;" |
||||
accesskey="&webConsoleCmd.accesskey;" |
||||
key="sp-key-webConsole" |
||||
command="sp-cmd-webConsole"/> |
||||
--> |
||||
</menupopup> |
||||
</menu> |
||||
</menubar> |
||||
|
||||
<popupset id="scratchpad-popups"> |
||||
<menupopup id="scratchpad-text-popup"> |
||||
<menuitem id="menu_cut"/> |
||||
<menuitem id="menu_copy"/> |
||||
<menuitem id="menu_paste"/> |
||||
<menuitem id="menu_delete"/> |
||||
<menuseparator/> |
||||
<menuitem id="menu_selectAll"/> |
||||
<menuseparator/> |
||||
<menuitem id="sp-text-run" |
||||
label="&run.label;" |
||||
accesskey="&run.accesskey;" |
||||
key="sp-key-run" |
||||
command="sp-cmd-run"/> |
||||
<!-- |
||||
<menuitem id="sp-text-inspect" |
||||
label="&inspect.label;" |
||||
accesskey="&inspect.accesskey;" |
||||
key="sp-key-inspect" |
||||
command="sp-cmd-inspect"/> |
||||
<menuitem id="sp-text-display" |
||||
label="&display.label;" |
||||
accesskey="&display.accesskey;" |
||||
key="sp-key-display" |
||||
command="sp-cmd-display"/> |
||||
--> |
||||
</menupopup> |
||||
</popupset> |
||||
|
||||
<textbox id="scratchpad-textbox" |
||||
class="monospace" |
||||
multiline="true" |
||||
flex="1" |
||||
context="scratchpad-text-popup" |
||||
placeholder="&textbox.placeholder1;" /> |
||||
<statusbar id="scratchpad-statusbar" align="end"> |
||||
<statusbarpanel id="scratchpad-status" |
||||
label="&contentContext.label;" |
||||
class="statusbarpanel-iconic-text"/> |
||||
<spacer flex="1"/> |
||||
</statusbar> |
||||
</window> |
@ -0,0 +1,8 @@
|
||||
/* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
||||
/* This Source Code Form is subject to the terms of the Mozilla Public |
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this |
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
pref("devtools.chrome.enabled", true); |
||||
pref("devtools.editor.tabsize", 2); |
||||
pref("devtools.editor.expandtab", true); |
@ -0,0 +1,14 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public |
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this |
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/. |
||||
|
||||
comm.jar: |
||||
content/communicator/devtools/devtoolsOverlay.js (content/devtoolsOverlay.js) |
||||
content/communicator/devtools/devtoolsOverlay.xul (content/devtoolsOverlay.xul) |
||||
content/communicator/devtools/scratchpad.js (content/scratchpad/scratchpad.js) |
||||
content/communicator/devtools/scratchpad.xul (content/scratchpad/scratchpad.xul) |
||||
|
||||
en-US.jar: |
||||
locale/en-US/communicator/devtools/devtoolsOverlay.dtd (locale/devtoolsOverlay.dtd) |
||||
locale/en-US/communicator/devtools/scratchpad.dtd (locale/scratchpad.dtd) |
||||
locale/en-US/communicator/devtools/scratchpad.properties (locale/scratchpad.properties) |
@ -0,0 +1,6 @@
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public |
||||
License, v. 2.0. If a copy of the MPL was not distributed with this |
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/. --> |
||||
|
||||
<!ENTITY scratchpad.label "Scratchpad"> |
||||
|
@ -0,0 +1,123 @@
|
||||
<!-- LOCALIZATION NOTE : FILE This file contains the Scratchpad window strings --> |
||||
<!-- LOCALIZATION NOTE : FILE Do not translate commandkeys --> |
||||
|
||||
<!-- LOCALIZATION NOTE (scratchpad.title): |
||||
- The Scratchpad is intended to provide a simple text editor for creating |
||||
- and evaluating bits of JavaScript code for the purposes of function |
||||
- prototyping, experimentation and convenient scripting. |
||||
- |
||||
- It's quite possible that you won't have a good analogue for the word |
||||
- "Scratchpad" in your locale. You should feel free to find a close |
||||
- approximation to it or choose a word (or words) that means |
||||
- "simple discardable text editor". --> |
||||
<!ENTITY window.title "Scratchpad"> |
||||
|
||||
<!ENTITY fileMenu.label "File"> |
||||
<!ENTITY fileMenu.accesskey "F"> |
||||
|
||||
<!ENTITY newWindowCmd.label "New Window"> |
||||
<!ENTITY newWindowCmd.accesskey "N"> |
||||
<!ENTITY newWindowCmd.commandkey "n"> |
||||
|
||||
<!ENTITY openFileCmd.label "Open Fileโฆ"> |
||||
<!ENTITY openFileCmd.accesskey "O"> |
||||
<!ENTITY openFileCmd.commandkey "o"> |
||||
|
||||
<!ENTITY saveFileCmd.label "Save"> |
||||
<!ENTITY saveFileCmd.accesskey "S"> |
||||
<!ENTITY saveFileCmd.commandkey "s"> |
||||
|
||||
<!ENTITY saveFileAsCmd.label "Save Asโฆ"> |
||||
<!ENTITY saveFileAsCmd.accesskey "A"> |
||||
|
||||
<!ENTITY closeCmd.label "Close"> |
||||
<!ENTITY closeCmd.key "W"> |
||||
<!ENTITY closeCmd.accesskey "C"> |
||||
|
||||
<!ENTITY editMenu.label "Edit"> |
||||
<!ENTITY editMenu.accesskey "E"> |
||||
|
||||
<!ENTITY undoCmd.label "Undo"> |
||||
<!ENTITY undoCmd.key "Z"> |
||||
<!ENTITY undoCmd.accesskey "U"> |
||||
|
||||
<!ENTITY redoCmd.label "Redo"> |
||||
<!ENTITY redoCmd.key "Y"> |
||||
<!ENTITY redoCmd.accesskey "R"> |
||||
|
||||
<!ENTITY cutCmd.label "Cut"> |
||||
<!ENTITY cutCmd.key "X"> |
||||
<!ENTITY cutCmd.accesskey "t"> |
||||
|
||||
<!ENTITY copyCmd.label "Copy"> |
||||
<!ENTITY copyCmd.key "C"> |
||||
<!ENTITY copyCmd.accesskey "C"> |
||||
|
||||
<!ENTITY pasteCmd.label "Paste"> |
||||
<!ENTITY pasteCmd.key "V"> |
||||
<!ENTITY pasteCmd.accesskey "P"> |
||||
|
||||
<!ENTITY selectAllCmd.label "Select All"> |
||||
<!ENTITY selectAllCmd.key "A"> |
||||
<!ENTITY selectAllCmd.accesskey "A"> |
||||
|
||||
<!ENTITY run.label "Run"> |
||||
<!ENTITY run.accesskey "R"> |
||||
<!ENTITY run.key "r"> |
||||
|
||||
<!ENTITY inspect.label "Inspect"> |
||||
<!ENTITY inspect.accesskey "I"> |
||||
<!ENTITY inspect.key "i"> |
||||
|
||||
<!ENTITY display.label "Display"> |
||||
<!ENTITY display.accesskey "D"> |
||||
<!ENTITY display.key "l"> |
||||
|
||||
<!-- LOCALIZATION NOTE (environmentMenu.label, accesskey): This menu item was |
||||
- renamed from "Context" to avoid confusion with the right-click context |
||||
- menu in the text area. It refers to the JavaScript Environment (or context) |
||||
- the user is evaluating against. I.e., Content (current tab) or Chrome |
||||
- (browser). |
||||
--> |
||||
<!ENTITY environmentMenu.label "Environment"> |
||||
<!ENTITY environmentMenu.accesskey "N"> |
||||
|
||||
|
||||
<!ENTITY contentContext.label "Content"> |
||||
<!ENTITY contentContext.accesskey "C"> |
||||
|
||||
<!-- LOCALIZATION NOTE (browserContext.label, accesskey): This menu item is used |
||||
- to select an execution environment for the browser window itself as opposed |
||||
- to content. This is a feature for browser and addon developers and only |
||||
- enabled via the devtools.chrome.enabled preference. Formerly, this label |
||||
- was called "Chrome". |
||||
--> |
||||
<!ENTITY browserContext.label "Browser"> |
||||
<!ENTITY browserContext.accesskey "B"> |
||||
|
||||
<!-- LOCALIZATION NOTE (resetContext.label): This command allows the developer |
||||
- to reset/clear the global object of the environment where the code executes. |
||||
--> |
||||
<!ENTITY resetContext.label "Reset"> |
||||
<!ENTITY resetContext.accesskey "R"> |
||||
|
||||
<!ENTITY executeMenu.label "Execute"> |
||||
<!ENTITY executeMenu.accesskey "X"> |
||||
|
||||
<!ENTITY toolsMenu.label "Tools"> |
||||
<!ENTITY toolsMenu.accesskey "T"> |
||||
|
||||
<!ENTITY errorConsoleCmd.label "Error Console"> |
||||
<!ENTITY errorConsoleCmd.accesskey "C"> |
||||
<!ENTITY errorConsoleCmd.commandkey "j"> |
||||
|
||||
<!ENTITY webConsoleCmd.label "Web Console"> |
||||
<!ENTITY webConsoleCmd.accesskey "W"> |
||||
<!ENTITY webConsoleCmd.commandkey "k"> |
||||
|
||||
<!-- LOCALIZATION NOTE (textbox.placeholder1): This is some placeholder text |
||||
- that appears when the Scratchpad's text area is empty and unfocused. |
||||
- It should be a one-line JavaScript comment, i.e., preceded by '//' |
||||
--> |
||||
<!ENTITY textbox.placeholder1 "// Enter some JavaScript, select it, right click and select Run, Inspect or Display."> |
||||
|
@ -0,0 +1,35 @@
|
||||
# LOCALIZATION NOTE (propertyPanel.updateButton.label): Used in the Property |
||||
# Panel that is opened by the Scratchpad window when inspecting an object. This |
||||
# is the Update button label. |
||||
propertyPanel.updateButton.label=Update |
||||
propertyPanel.updateButton.accesskey=U |
||||
|
||||
# LOCALIZATION NOTE (export.fileOverwriteConfirmation): This is displayed when |
||||
# the user attempts to save to an already existing file. |
||||
export.fileOverwriteConfirmation=File exists. Overwrite? |
||||
|
||||
# LOCALIZATION NOTE (browserWindow.unavailable): This error message is shown |
||||
# when Scratchpad does not find any recently active window of navigator:browser |
||||
# type. |
||||
browserWindow.unavailable=Scratchpad cannot find any browser window to execute the code in. |
||||
|
||||
# LOCALIZATION NOTE (openFile.title): This is the file picker title, when you |
||||
# open a file from Scratchpad. |
||||
openFile.title=Open File |
||||
|
||||
# LOCALIZATION NOTE (openFile.failed): This is the message displayed when file |
||||
# open fails. |
||||
openFile.failed=Failed to read the file. |
||||
|
||||
# LOCALIZATION NOTE (saveFileAs): This is the file picker title, when you save |
||||
# a file in Scratchpad. |
||||
saveFileAs=Save File As |
||||
|
||||
# LOCALIZATION NOTE (saveFile.failed): This is the message displayed when file |
||||
# save fails. |
||||
saveFile.failed=The file save operation failed. |
||||
|
||||
# LOCALIZATION NOTE (scratchpadIntro): This is a multi-line comment explaining |
||||
# how to use the Scratchpad. Note that this should be a valid JavaScript |
||||
# comment inside /* and */. |
||||
scratchpadIntro=/*\n * This is a JavaScript Scratchpad.\n *\n * Enter some JavaScript, then Right Click or choose from the Execute Menu:\n * 1. Run to evaluate the selected text,\n * 2. Inspect to bring up an Object Inspector on the result, or,\n * 3. Display to insert the result in a comment after the selection.\n */\n\n |
@ -0,0 +1,612 @@
|
||||
/* -*- Mode: js2; js2-basic-offset: 2; indent-tabs-mode: nil; -*- */ |
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ |
||||
/* ***** BEGIN LICENSE BLOCK ***** |
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
||||
* |
||||
* The contents of this file are subject to the Mozilla Public License Version |
||||
* 1.1 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* http://www.mozilla.org/MPL/
|
||||
* |
||||
* Software distributed under the License is distributed on an "AS IS" basis, |
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
||||
* for the specific language governing rights and limitations under the |
||||
* License. |
||||
* |
||||
* The Original Code is DevTools (HeadsUpDisplay) Console Code |
||||
* |
||||
* The Initial Developer of the Original Code is |
||||
* the Mozilla Foundation. |
||||
* Portions created by the Initial Developer are Copyright (C) 2010 |
||||
* the Initial Developer. All Rights Reserved. |
||||
* |
||||
* Contributor(s): |
||||
* Rob Campbell <rcampbell@mozilla.com> |
||||
* Julian Viereck <jviereck@mozilla.com> |
||||
* |
||||
* Alternatively, the contents of this file may be used under the terms of |
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or |
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), |
||||
* in which case the provisions of the GPL or the LGPL are applicable instead |
||||
* of those above. If you wish to allow use of your version of this file only |
||||
* under the terms of either the GPL or the LGPL, and not to allow others to |
||||
* use your version of this file under the terms of the MPL, indicate your |
||||
* decision by deleting the provisions above and replace them with the notice |
||||
* and other provisions required by the GPL or the LGPL. If you do not delete |
||||
* the provisions above, a recipient may use your version of this file under |
||||
* the terms of any one of the MPL, the GPL or the LGPL. |
||||
* |
||||
* ***** END LICENSE BLOCK ***** */ |
||||
|
||||
const Cc = Components.classes; |
||||
const Ci = Components.interfaces; |
||||
const Cu = Components.utils; |
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm"); |
||||
Cu.import("resource://gre/modules/Services.jsm"); |
||||
|
||||
var EXPORTED_SYMBOLS = ["PropertyPanel", "PropertyTreeView", |
||||
"namesAndValuesOf", "isNonNativeGetter"]; |
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//// Helper for PropertyTreeView
|
||||
|
||||
const TYPE_OBJECT = 0, TYPE_FUNCTION = 1, TYPE_ARRAY = 2, TYPE_OTHER = 3; |
||||
|
||||
/** |
||||
* Figures out the type of aObject and the string to display in the tree. |
||||
* |
||||
* @param object aObject |
||||
* The object to operate on. |
||||
* @returns object |
||||
* A object with the form: |
||||
* { |
||||
* type: TYPE_OBJECT || TYPE_FUNCTION || TYPE_ARRAY || TYPE_OTHER, |
||||
* display: string for displaying the object in the tree |
||||
* } |
||||
*/ |
||||
function presentableValueFor(aObject) |
||||
{ |
||||
if (aObject === null || aObject === undefined) { |
||||
return { |
||||
type: TYPE_OTHER, |
||||
display: aObject === undefined ? "undefined" : "null" |
||||
}; |
||||
} |
||||
|
||||
let presentable; |
||||
switch (aObject.constructor && aObject.constructor.name) { |
||||
case "Array": |
||||
return { |
||||
type: TYPE_ARRAY, |
||||
display: "Array" |
||||
}; |
||||
|
||||
case "String": |
||||
return { |
||||
type: TYPE_OTHER, |
||||
display: "\"" + aObject + "\"" |
||||
}; |
||||
|
||||
case "Date": |
||||
case "RegExp": |
||||
case "Number": |
||||
case "Boolean": |
||||
return { |
||||
type: TYPE_OTHER, |
||||
display: aObject |
||||
}; |
||||
|
||||
case "Iterator": |
||||
return { |
||||
type: TYPE_OTHER, |
||||
display: "Iterator" |
||||
}; |
||||
|
||||
case "Function": |
||||
presentable = aObject.toString(); |
||||
return { |
||||
type: TYPE_FUNCTION, |
||||
display: presentable.substring(0, presentable.indexOf(')') + 1) |
||||
}; |
||||
|
||||
default: |
||||
presentable = aObject.toString(); |
||||
let m = /^\[object (\S+)\]/.exec(presentable); |
||||
|
||||
try { |
||||
if (typeof aObject == "object" && typeof aObject.next == "function" && |
||||
m && m[1] == "Generator") { |
||||
return { |
||||
type: TYPE_OTHER, |
||||
display: m[1] |
||||
}; |
||||
} |
||||
} |
||||
catch (ex) { |
||||
// window.history.next throws in the typeof check above.
|
||||
return { |
||||
type: TYPE_OBJECT, |
||||
display: m ? m[1] : "Object" |
||||
}; |
||||