mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-07 08:18:41 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
13
devtools/client/scratchpad/moz.build
Normal file
13
devtools/client/scratchpad/moz.build
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
||||
DevToolsModules(
|
||||
'scratchpad-commands.js',
|
||||
'scratchpad-manager.jsm',
|
||||
'scratchpad-panel.js',
|
||||
)
|
||||
|
||||
BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
|
||||
22
devtools/client/scratchpad/scratchpad-commands.js
Normal file
22
devtools/client/scratchpad/scratchpad-commands.js
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const l10n = require("gcli/l10n");
|
||||
const {Cu} = require("chrome");
|
||||
|
||||
exports.items = [{
|
||||
item: "command",
|
||||
runAt: "client",
|
||||
name: "scratchpad",
|
||||
buttonId: "command-button-scratchpad",
|
||||
buttonClass: "command-button command-button-invertable",
|
||||
tooltipText: l10n.lookup("scratchpadOpenTooltip"),
|
||||
hidden: true,
|
||||
exec: function (args, context) {
|
||||
const {ScratchpadManager} = Cu.import("resource://devtools/client/scratchpad/scratchpad-manager.jsm", {});
|
||||
ScratchpadManager.openScratchpad();
|
||||
}
|
||||
}];
|
||||
185
devtools/client/scratchpad/scratchpad-manager.jsm
Normal file
185
devtools/client/scratchpad/scratchpad-manager.jsm
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
/* vim:set ts=2 sw=2 sts=2 et tw=80:
|
||||
* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["ScratchpadManager"];
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
const SCRATCHPAD_WINDOW_URL = "chrome://devtools/content/scratchpad/scratchpad.xul";
|
||||
const SCRATCHPAD_WINDOW_FEATURES = "chrome,titlebar,toolbar,centerscreen,resizable,dialog=no";
|
||||
|
||||
const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
const Services = require("Services");
|
||||
const Telemetry = require("devtools/client/shared/telemetry");
|
||||
|
||||
|
||||
/**
|
||||
* The ScratchpadManager object opens new Scratchpad windows and manages the state
|
||||
* of open scratchpads for session restore. There's only one ScratchpadManager in
|
||||
* the life of the browser.
|
||||
*/
|
||||
this.ScratchpadManager = {
|
||||
|
||||
_nextUid: 1,
|
||||
_scratchpads: [],
|
||||
|
||||
_telemetry: new Telemetry(),
|
||||
|
||||
/**
|
||||
* Get the saved states of open scratchpad windows. Called by
|
||||
* session restore.
|
||||
*
|
||||
* @return array
|
||||
* The array of scratchpad states.
|
||||
*/
|
||||
getSessionState: function SPM_getSessionState()
|
||||
{
|
||||
return this._scratchpads;
|
||||
},
|
||||
|
||||
/**
|
||||
* Restore scratchpad windows from the scratchpad session store file.
|
||||
* Called by session restore.
|
||||
*
|
||||
* @param function aSession
|
||||
* The session object with scratchpad states.
|
||||
*
|
||||
* @return array
|
||||
* The restored scratchpad windows.
|
||||
*/
|
||||
restoreSession: function SPM_restoreSession(aSession)
|
||||
{
|
||||
if (!Array.isArray(aSession)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
let wins = [];
|
||||
aSession.forEach(function (state) {
|
||||
let win = this.openScratchpad(state);
|
||||
wins.push(win);
|
||||
}, this);
|
||||
|
||||
return wins;
|
||||
},
|
||||
|
||||
/**
|
||||
* Iterate through open scratchpad windows and save their states.
|
||||
*/
|
||||
saveOpenWindows: function SPM_saveOpenWindows() {
|
||||
this._scratchpads = [];
|
||||
|
||||
function clone(src) {
|
||||
let dest = {};
|
||||
|
||||
for (let key in src) {
|
||||
if (src.hasOwnProperty(key)) {
|
||||
dest[key] = src[key];
|
||||
}
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
// We need to clone objects we get from Scratchpad instances
|
||||
// because such (cross-window) objects have a property 'parent'
|
||||
// that holds on to a ChromeWindow instance. This means that
|
||||
// such objects are not primitive-values-only anymore so they
|
||||
// can leak.
|
||||
|
||||
let enumerator = Services.wm.getEnumerator("devtools:scratchpad");
|
||||
while (enumerator.hasMoreElements()) {
|
||||
let win = enumerator.getNext();
|
||||
if (!win.closed && win.Scratchpad.initialized) {
|
||||
this._scratchpads.push(clone(win.Scratchpad.getState()));
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Open a new scratchpad window with an optional initial state.
|
||||
*
|
||||
* @param object aState
|
||||
* Optional. The initial state of the scratchpad, an object
|
||||
* with properties filename, text, and executionContext.
|
||||
*
|
||||
* @return nsIDomWindow
|
||||
* The opened scratchpad window.
|
||||
*/
|
||||
openScratchpad: function SPM_openScratchpad(aState)
|
||||
{
|
||||
let params = Cc["@mozilla.org/embedcomp/dialogparam;1"]
|
||||
.createInstance(Ci.nsIDialogParamBlock);
|
||||
|
||||
params.SetNumberStrings(2);
|
||||
params.SetString(0, this.createUid());
|
||||
|
||||
if (aState) {
|
||||
if (typeof aState != "object") {
|
||||
return;
|
||||
}
|
||||
|
||||
params.SetString(1, JSON.stringify(aState));
|
||||
}
|
||||
|
||||
let win = Services.ww.openWindow(null, SCRATCHPAD_WINDOW_URL, "_blank",
|
||||
SCRATCHPAD_WINDOW_FEATURES, params);
|
||||
|
||||
this._telemetry.toolOpened("scratchpad-window");
|
||||
let onClose = () => {
|
||||
this._telemetry.toolClosed("scratchpad-window");
|
||||
};
|
||||
win.addEventListener("unload", onClose);
|
||||
|
||||
// Only add the shutdown observer if we've opened a scratchpad window.
|
||||
ShutdownObserver.init();
|
||||
|
||||
return win;
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a unique ID for a new Scratchpad.
|
||||
*/
|
||||
createUid: function SPM_createUid()
|
||||
{
|
||||
return JSON.stringify(this._nextUid++);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The ShutdownObserver listens for app shutdown and saves the current state
|
||||
* of the scratchpads for session restore.
|
||||
*/
|
||||
var ShutdownObserver = {
|
||||
_initialized: false,
|
||||
|
||||
init: function SDO_init()
|
||||
{
|
||||
if (this._initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
Services.obs.addObserver(this, "quit-application-granted", false);
|
||||
|
||||
this._initialized = true;
|
||||
},
|
||||
|
||||
observe: function SDO_observe(aMessage, aTopic, aData)
|
||||
{
|
||||
if (aTopic == "quit-application-granted") {
|
||||
ScratchpadManager.saveOpenWindows();
|
||||
this.uninit();
|
||||
}
|
||||
},
|
||||
|
||||
uninit: function SDO_uninit()
|
||||
{
|
||||
Services.obs.removeObserver(this, "quit-application-granted");
|
||||
}
|
||||
};
|
||||
56
devtools/client/scratchpad/scratchpad-panel.js
Normal file
56
devtools/client/scratchpad/scratchpad-panel.js
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
"use strict";
|
||||
|
||||
const {Cu} = require("chrome");
|
||||
const EventEmitter = require("devtools/shared/event-emitter");
|
||||
const promise = require("promise");
|
||||
|
||||
|
||||
function ScratchpadPanel(iframeWindow, toolbox) {
|
||||
let { Scratchpad } = iframeWindow;
|
||||
this._toolbox = toolbox;
|
||||
this.panelWin = iframeWindow;
|
||||
this.scratchpad = Scratchpad;
|
||||
|
||||
Scratchpad.target = this.target;
|
||||
Scratchpad.hideMenu();
|
||||
|
||||
let deferred = promise.defer();
|
||||
this._readyObserver = deferred.promise;
|
||||
Scratchpad.addObserver({
|
||||
onReady: function () {
|
||||
Scratchpad.removeObserver(this);
|
||||
deferred.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
EventEmitter.decorate(this);
|
||||
}
|
||||
exports.ScratchpadPanel = ScratchpadPanel;
|
||||
|
||||
ScratchpadPanel.prototype = {
|
||||
/**
|
||||
* Open is effectively an asynchronous constructor. For the ScratchpadPanel,
|
||||
* by the time this is called, the Scratchpad will already be ready.
|
||||
*/
|
||||
open: function () {
|
||||
return this._readyObserver.then(() => {
|
||||
this.isReady = true;
|
||||
this.emit("ready");
|
||||
return this;
|
||||
});
|
||||
},
|
||||
|
||||
get target() {
|
||||
return this._toolbox.target;
|
||||
},
|
||||
|
||||
destroy: function () {
|
||||
this.emit("destroyed");
|
||||
return promise.resolve();
|
||||
}
|
||||
};
|
||||
2480
devtools/client/scratchpad/scratchpad.js
Normal file
2480
devtools/client/scratchpad/scratchpad.js
Normal file
File diff suppressed because it is too large
Load diff
412
devtools/client/scratchpad/scratchpad.xul
Normal file
412
devtools/client/scratchpad/scratchpad.xul
Normal file
|
|
@ -0,0 +1,412 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<!-- 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 window [
|
||||
<!ENTITY % scratchpadDTD SYSTEM "chrome://devtools/locale/scratchpad.dtd" >
|
||||
%scratchpadDTD;
|
||||
<!ENTITY % editMenuStrings SYSTEM "chrome://global/locale/editMenuOverlay.dtd">
|
||||
%editMenuStrings;
|
||||
<!ENTITY % sourceEditorStrings SYSTEM "chrome://devtools/locale/sourceeditor.dtd">
|
||||
%sourceEditorStrings;
|
||||
]>
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin/global.css"?>
|
||||
<?xml-stylesheet href="chrome://devtools/skin/scratchpad.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"
|
||||
macanimationtype="document"
|
||||
fullscreenbutton="true"
|
||||
screenX="4" screenY="4"
|
||||
width="640" height="480"
|
||||
persist="screenX screenY width height sizemode">
|
||||
|
||||
<script type="application/javascript;version=1.8"
|
||||
src="chrome://devtools/content/shared/theme-switching.js"/>
|
||||
<script type="application/javascript" src="chrome://global/content/globalOverlay.js"/>
|
||||
<script type="application/javascript" src="chrome://devtools/content/scratchpad/scratchpad.js"/>
|
||||
|
||||
<commandset id="editMenuCommands"/>
|
||||
|
||||
<commandset id="sourceEditorCommands">
|
||||
<command id="cmd_find" oncommand=";"/>
|
||||
<command id="cmd_findAgain" oncommand=";"/>
|
||||
<command id="cmd_gotoLine" oncommand=";"/>
|
||||
</commandset>
|
||||
|
||||
<commandset id="sp-commandset">
|
||||
<command id="sp-cmd-newWindow" oncommand=";"/>
|
||||
<command id="sp-cmd-openFile" oncommand=";"/>
|
||||
<command id="sp-cmd-clearRecentFiles" oncommand=";"/>
|
||||
<command id="sp-cmd-save" oncommand=";"/>
|
||||
<command id="sp-cmd-saveas" oncommand=";"/>
|
||||
<command id="sp-cmd-revert" oncommand=";" disabled="true"/>
|
||||
<command id="sp-cmd-close" oncommand=";"/>
|
||||
<command id="sp-cmd-line-numbers" oncommand=";"/>
|
||||
<command id="sp-cmd-wrap-text" oncommand=";"/>
|
||||
<command id="sp-cmd-highlight-trailing-space" oncommand=";"/>
|
||||
<command id="sp-cmd-larger-font" oncommand=";"/>
|
||||
<command id="sp-cmd-smaller-font" oncommand=";"/>
|
||||
<command id="sp-cmd-normal-font" oncommand=";"/>
|
||||
<command id="sp-cmd-run" oncommand=";"/>
|
||||
<command id="sp-cmd-inspect" oncommand=";"/>
|
||||
<command id="sp-cmd-display" oncommand=";"/>
|
||||
<command id="sp-cmd-pprint" oncommand=";"/>
|
||||
<command id="sp-cmd-contentContext" oncommand=";"/>
|
||||
<command id="sp-cmd-browserContext" oncommand=";" disabled="true"/>
|
||||
<command id="sp-cmd-reloadAndRun" oncommand=";"/>
|
||||
<command id="sp-cmd-evalFunction" oncommand=";"/>
|
||||
<command id="sp-cmd-errorConsole" oncommand=";" disabled="true"/>
|
||||
<command id="sp-cmd-webConsole" oncommand=";"/>
|
||||
<command id="sp-cmd-documentationLink" oncommand=";"/>
|
||||
<command id="sp-cmd-hideSidebar" oncommand=";"/>
|
||||
</commandset>
|
||||
|
||||
<keyset id="editMenuKeys"/>
|
||||
|
||||
<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"/>
|
||||
<key id="sp-key-larger-font"
|
||||
key="&largerFont.commandkey;"
|
||||
command="sp-cmd-larger-font"
|
||||
modifiers="accel"/>
|
||||
<key key="&largerFont.commandkey2;"
|
||||
command="sp-cmd-larger-font"
|
||||
modifiers="accel"/>
|
||||
<key id="sp-key-smaller-font"
|
||||
key="&smallerFont.commandkey;"
|
||||
command="sp-cmd-smaller-font"
|
||||
modifiers="accel"/>
|
||||
<key id="sp-key-normal-size-font"
|
||||
key="&normalSize.commandkey;"
|
||||
command="sp-cmd-normal-font"
|
||||
modifiers="accel"/>
|
||||
<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-pprint"
|
||||
key="&pprint.key;"
|
||||
command="sp-cmd-pprint"
|
||||
modifiers="accel"/>
|
||||
<key id="sp-key-reloadAndRun"
|
||||
key="&reloadAndRun.key;"
|
||||
command="sp-cmd-reloadAndRun"
|
||||
modifiers="accel,shift"/>
|
||||
<key id="sp-key-evalFunction"
|
||||
key="&evalFunction.key;"
|
||||
command="sp-cmd-evalFunction"
|
||||
modifiers="accel"/>
|
||||
<key id="sp-key-errorConsole"
|
||||
key="&errorConsoleCmd.commandkey;"
|
||||
command="sp-cmd-errorConsole"
|
||||
modifiers="accel,shift"/>
|
||||
<key id="sp-key-hideSidebar"
|
||||
keycode="VK_ESCAPE"
|
||||
command="sp-cmd-hideSidebar"/>
|
||||
<key id="key_openHelp"
|
||||
keycode="VK_F1"
|
||||
command="sp-cmd-documentationLink"/>
|
||||
<key id="key_gotoLine"
|
||||
key="&gotoLineCmd.key;"
|
||||
command="key_gotoLine"
|
||||
modifiers="accel"/>
|
||||
|
||||
</keyset>
|
||||
|
||||
<menubar id="sp-menubar">
|
||||
<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;"/>
|
||||
|
||||
<menu id="sp-open_recent-menu" label="&openRecentMenu.label;"
|
||||
accesskey="&openRecentMenu.accesskey;"
|
||||
disabled="true">
|
||||
<menupopup id="sp-menu-open_recentPopup"/>
|
||||
</menu>
|
||||
|
||||
<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"/>
|
||||
<menuitem id="sp-menu-revert"
|
||||
label="&revertCmd.label;"
|
||||
accesskey="&revertCmd.accesskey;"
|
||||
command="sp-cmd-revert"/>
|
||||
<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="menu_undo"/>
|
||||
<menuitem id="menu_redo"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="menu_cut"/>
|
||||
<menuitem id="menu_copy"/>
|
||||
<menuitem id="menu_paste"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="menu_selectAll"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="menu_find"/>
|
||||
<menuitem id="menu_findAgain"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="se-menu-gotoLine"
|
||||
label="&gotoLineCmd.label;"
|
||||
accesskey="&gotoLineCmd.accesskey;"
|
||||
key="key_gotoLine"
|
||||
command="cmd_gotoLine"/>
|
||||
<menuitem id="sp-menu-pprint"
|
||||
label="&pprint.label;"
|
||||
accesskey="&pprint.accesskey;"
|
||||
key="sp-key-pprint"
|
||||
command="sp-cmd-pprint"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
|
||||
<menu id="sp-view-menu" label="&viewMenu.label;" accesskey="&viewMenu.accesskey;">
|
||||
<menupopup id="sp-menu-viewpopup">
|
||||
<menuitem id="sp-menu-line-numbers"
|
||||
label="&lineNumbers.label;"
|
||||
accesskey="&lineNumbers.accesskey;"
|
||||
type="checkbox"
|
||||
command="sp-cmd-line-numbers"/>
|
||||
<menuitem id="sp-menu-word-wrap"
|
||||
label="&wordWrap.label;"
|
||||
accesskey="&wordWrap.accesskey;"
|
||||
type="checkbox"
|
||||
command="sp-cmd-wrap-text"/>
|
||||
<menuitem id="sp-menu-highlight-trailing-space"
|
||||
label="&highlightTrailingSpace.label;"
|
||||
accesskey="&highlightTrailingSpace.accesskey;"
|
||||
type="checkbox"
|
||||
command="sp-cmd-highlight-trailing-space"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="sp-menu-larger-font"
|
||||
label="&largerFont.label;"
|
||||
key="sp-key-larger-font"
|
||||
accesskey="&largerFont.accesskey;"
|
||||
command="sp-cmd-larger-font"/>
|
||||
<menuitem id="sp-menu-smaller-font"
|
||||
label="&smallerFont.label;"
|
||||
key="sp-key-smaller-font"
|
||||
accesskey="&smallerFont.accesskey;"
|
||||
command="sp-cmd-smaller-font"/>
|
||||
<menuitem id="sp-menu-normal-size-font"
|
||||
label="&normalSize.label;"
|
||||
key="sp-menu-normal-font"
|
||||
accesskey="&normalSize.accesskey;"
|
||||
command="sp-cmd-normal-font"/>
|
||||
</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"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="sp-text-reloadAndRun"
|
||||
label="&reloadAndRun.label;"
|
||||
key="sp-key-reloadAndRun"
|
||||
accesskey="&reloadAndRun.accesskey;"
|
||||
command="sp-cmd-reloadAndRun"/>
|
||||
<menuitem id="sp-text-evalFunction"
|
||||
label="&evalFunction.label;"
|
||||
key="sp-key-evalFunction"
|
||||
accesskey="&evalFunction.accesskey;"
|
||||
command="sp-cmd-evalFunction"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
|
||||
<menu id="sp-environment-menu"
|
||||
label="&environmentMenu.label;"
|
||||
accesskey="&environmentMenu.accesskey;"
|
||||
hidden="true">
|
||||
<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"
|
||||
command="sp-cmd-browserContext"
|
||||
label="&browserContext.label;"
|
||||
accesskey="&browserContext.accesskey;"
|
||||
type="radio"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
|
||||
#ifdef XP_WIN
|
||||
<menu id="sp-help-menu"
|
||||
label="&helpMenu.label;"
|
||||
accesskey="&helpMenuWin.accesskey;">
|
||||
#else
|
||||
<menu id="sp-help-menu"
|
||||
label="&helpMenu.label;"
|
||||
accesskey="&helpMenu.accesskey;">
|
||||
#endif
|
||||
<menupopup id="sp-menu-help">
|
||||
<menuitem id="sp-menu-documentation"
|
||||
label="&documentationLink.label;"
|
||||
accesskey="&documentationLink.accesskey;"
|
||||
command="sp-cmd-documentationLink"
|
||||
key="key_openHelp"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</menubar>
|
||||
|
||||
<toolbar id="sp-toolbar"
|
||||
class="devtools-toolbar">
|
||||
<toolbarbutton id="sp-toolbar-open"
|
||||
class="devtools-toolbarbutton"
|
||||
label="&openFileCmd.label;"
|
||||
command="sp-cmd-openFile"/>
|
||||
<toolbarbutton id="sp-toolbar-save"
|
||||
class="devtools-toolbarbutton"
|
||||
label="&saveFileCmd.label;"
|
||||
command="sp-cmd-save"/>
|
||||
<toolbarbutton id="sp-toolbar-saveAs"
|
||||
class="devtools-toolbarbutton"
|
||||
label="&saveFileAsCmd.label;"
|
||||
command="sp-cmd-saveas"/>
|
||||
<toolbarspacer/>
|
||||
<toolbarbutton id="sp-toolbar-run"
|
||||
class="devtools-toolbarbutton"
|
||||
label="&run.label;"
|
||||
command="sp-cmd-run"/>
|
||||
<toolbarbutton id="sp-toolbar-inspect"
|
||||
class="devtools-toolbarbutton"
|
||||
label="&inspect.label;"
|
||||
command="sp-cmd-inspect"/>
|
||||
<toolbarbutton id="sp-toolbar-display"
|
||||
class="devtools-toolbarbutton"
|
||||
label="&display.label;"
|
||||
command="sp-cmd-display"/>
|
||||
<toolbarspacer/>
|
||||
<toolbarbutton id="sp-toolbar-pprint"
|
||||
class="devtools-toolbarbutton"
|
||||
label="&pprint.label;"
|
||||
command="sp-cmd-pprint"/>
|
||||
</toolbar>
|
||||
|
||||
|
||||
<popupset id="scratchpad-popups">
|
||||
<menupopup id="scratchpad-text-popup">
|
||||
<menuitem id="cMenu_cut"/>
|
||||
<menuitem id="cMenu_copy"/>
|
||||
<menuitem id="cMenu_paste"/>
|
||||
<menuitem id="cMenu_delete"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="cMenu_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"/>
|
||||
<menuitem id="sp-text-evalFunction"
|
||||
label="&evalFunction.label;"
|
||||
key="sp-key-evalFunction"
|
||||
accesskey="&evalFunction.accesskey;"
|
||||
command="sp-cmd-evalFunction"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="sp-text-reloadAndRun"
|
||||
label="&reloadAndRun.label;"
|
||||
key="sp-key-reloadAndRun"
|
||||
accesskey="&reloadAndRun.accesskey;"
|
||||
command="sp-cmd-reloadAndRun"/>
|
||||
</menupopup>
|
||||
</popupset>
|
||||
|
||||
<notificationbox id="scratchpad-notificationbox" flex="1">
|
||||
<hbox flex="1">
|
||||
<vbox id="scratchpad-editor" flex="1"/>
|
||||
<splitter class="devtools-side-splitter"/>
|
||||
<tabbox id="scratchpad-sidebar" class="devtools-sidebar-tabs"
|
||||
width="300"
|
||||
hidden="true">
|
||||
<tabs/>
|
||||
<tabpanels flex="1"/>
|
||||
</tabbox>
|
||||
</hbox>
|
||||
<toolbar id="statusbar-line-col" class="devtools-toolbar"/>
|
||||
</notificationbox>
|
||||
|
||||
</window>
|
||||
6
devtools/client/scratchpad/test/.eslintrc.js
Normal file
6
devtools/client/scratchpad/test/.eslintrc.js
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
// Extend from the shared list of defined globals for mochitests.
|
||||
"extends": "../../../.eslintrc.mochitests.js"
|
||||
};
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
Typ Datum Uhrzeit Quelle Kategorie Ereignis Benutzer Computer
|
||||
Informationen 10.08.2012 16:07:11 MSDTC Datenträger 2444 Nicht zutreffend
|
||||
46
devtools/client/scratchpad/test/browser.ini
Normal file
46
devtools/client/scratchpad/test/browser.ini
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
[DEFAULT]
|
||||
tags = devtools
|
||||
subsuite = devtools
|
||||
support-files = head.js
|
||||
|
||||
[browser_scratchpad_autocomplete.js]
|
||||
[browser_scratchpad_browser_last_window_closing.js]
|
||||
[browser_scratchpad_reset_undo.js]
|
||||
[browser_scratchpad_display_outputs_errors.js]
|
||||
[browser_scratchpad_eval_func.js]
|
||||
[browser_scratchpad_goto_line_ui.js]
|
||||
[browser_scratchpad_reload_and_run.js]
|
||||
[browser_scratchpad_display_non_error_exceptions.js]
|
||||
[browser_scratchpad_modeline.js]
|
||||
[browser_scratchpad_chrome_context_pref.js]
|
||||
[browser_scratchpad_help_key.js]
|
||||
[browser_scratchpad_recent_files.js]
|
||||
# [browser_scratchpad_confirm_close.js]
|
||||
# Disable test due to bug 807234 becoming basically permanent
|
||||
[browser_scratchpad_tab.js]
|
||||
[browser_scratchpad_wrong_window_focus.js]
|
||||
[browser_scratchpad_unsaved.js]
|
||||
[browser_scratchpad_falsy.js]
|
||||
[browser_scratchpad_edit_ui_updates.js]
|
||||
[browser_scratchpad_revert_to_saved.js]
|
||||
[browser_scratchpad_run_error_goto_line.js]
|
||||
[browser_scratchpad_contexts.js]
|
||||
[browser_scratchpad_execute_print.js]
|
||||
[browser_scratchpad_files.js]
|
||||
[browser_scratchpad_initialization.js]
|
||||
[browser_scratchpad_inspect.js]
|
||||
[browser_scratchpad_inspect_primitives.js]
|
||||
[browser_scratchpad_long_string.js]
|
||||
[browser_scratchpad_open.js]
|
||||
support-files = NS_ERROR_ILLEGAL_INPUT.txt
|
||||
[browser_scratchpad_open_error_console.js]
|
||||
[browser_scratchpad_throw_output.js]
|
||||
[browser_scratchpad_pprint-02.js]
|
||||
[browser_scratchpad_pprint.js]
|
||||
[browser_scratchpad_pprint_error_goto_line.js]
|
||||
[browser_scratchpad_restore.js]
|
||||
[browser_scratchpad_tab_switch.js]
|
||||
[browser_scratchpad_ui.js]
|
||||
[browser_scratchpad_close_toolbox.js]
|
||||
[browser_scratchpad_remember_view_options.js]
|
||||
[browser_scratchpad_disable_view_menu_items.js]
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* Bug 968896 */
|
||||
|
||||
// Test the completions using numbers.
|
||||
const source = "0x1.";
|
||||
const completions = ["toExponential", "toFixed", "toString"];
|
||||
const { Task } = require("devtools/shared/task");
|
||||
|
||||
function test() {
|
||||
const options = { tabContent: "test scratchpad autocomplete" };
|
||||
openTabAndScratchpad(options)
|
||||
.then(Task.async(runTests))
|
||||
.then(finish, console.error);
|
||||
}
|
||||
|
||||
|
||||
function* runTests([win, sp]) {
|
||||
const {editor} = sp;
|
||||
const editorWin = editor.container.contentWindow;
|
||||
|
||||
// Show the completions popup.
|
||||
sp.setText(source);
|
||||
sp.editor.setCursor({ line: 0, ch: source.length });
|
||||
yield keyOnce("suggestion-entered", " ", { ctrlKey: true });
|
||||
|
||||
// Get the hints popup container.
|
||||
const hints = editorWin.document.querySelector(".CodeMirror-hints");
|
||||
|
||||
ok(hints,
|
||||
"The hint container should exist.");
|
||||
is(hints.childNodes.length, 3,
|
||||
"The hint container should have the completions.");
|
||||
|
||||
let i = 0;
|
||||
for (let completion of completions) {
|
||||
let active = hints.querySelector(".CodeMirror-hint-active");
|
||||
is(active.textContent, completion,
|
||||
"Check that completion " + i++ + " is what is expected.");
|
||||
yield keyOnce("suggestion-entered", "VK_DOWN");
|
||||
}
|
||||
|
||||
// We should have looped around to the first suggestion again. Accept it.
|
||||
yield keyOnce("after-suggest", "VK_RETURN");
|
||||
|
||||
is(sp.getText(), source + completions[0],
|
||||
"Autocompletion should work and select the right element.");
|
||||
|
||||
// Check that the information tooltips work.
|
||||
sp.setText("5");
|
||||
yield keyOnce("show-information", " ", { ctrlKey: true, shiftKey: true });
|
||||
|
||||
// Get the information container.
|
||||
const info = editorWin.document.querySelector(".CodeMirror-Tern-information");
|
||||
ok(info,
|
||||
"Info tooltip should appear.");
|
||||
is(info.textContent.slice(0, 6), "number",
|
||||
"Info tooltip should have expected contents.");
|
||||
|
||||
function keyOnce(event, key, opts = {}) {
|
||||
const p = editor.once(event);
|
||||
EventUtils.synthesizeKey(key, opts, editorWin);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const BUTTON_POSITION_CANCEL = 1;
|
||||
const BUTTON_POSITION_DONT_SAVE = 2;
|
||||
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
// Observer must be attached *before* Scratchpad is opened.
|
||||
CloseObserver.init();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onTabLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onTabLoad, true);
|
||||
openScratchpad(runTests);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html;charset=utf8,<p>test browser last window closing</p>";
|
||||
}
|
||||
|
||||
|
||||
|
||||
function runTests({ Scratchpad })
|
||||
{
|
||||
let browser = Services.wm.getEnumerator("navigator:browser").getNext();
|
||||
let oldPrompt = Services.prompt;
|
||||
let button;
|
||||
|
||||
Services.prompt = {
|
||||
confirmEx: () => button
|
||||
};
|
||||
|
||||
|
||||
Scratchpad.dirty = true;
|
||||
|
||||
// Test canceling close.
|
||||
button = BUTTON_POSITION_CANCEL;
|
||||
CloseObserver.expectedValue = true;
|
||||
browser.BrowserTryToCloseWindow();
|
||||
|
||||
// Test accepting close.
|
||||
button = BUTTON_POSITION_DONT_SAVE;
|
||||
CloseObserver.expectedValue = false;
|
||||
browser.BrowserTryToCloseWindow();
|
||||
|
||||
// Test closing without prompt needed.
|
||||
Scratchpad.dirty = false;
|
||||
browser.BrowserTryToCloseWindow();
|
||||
|
||||
Services.prompt = oldPrompt;
|
||||
CloseObserver.uninit();
|
||||
finish();
|
||||
}
|
||||
|
||||
|
||||
var CloseObserver = {
|
||||
expectedValue: null,
|
||||
init: function ()
|
||||
{
|
||||
Services.obs.addObserver(this, "browser-lastwindow-close-requested", false);
|
||||
},
|
||||
|
||||
observe: function (aSubject)
|
||||
{
|
||||
aSubject.QueryInterface(Ci.nsISupportsPRBool);
|
||||
let message = this.expectedValue ? "close" : "stay open";
|
||||
ok(this.expectedValue === aSubject.data, "Expected browser to " + message);
|
||||
aSubject.data = true;
|
||||
},
|
||||
|
||||
uninit: function ()
|
||||
{
|
||||
Services.obs.removeObserver(this, "browser-lastwindow-close-requested", false);
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* Bug 646070 */
|
||||
|
||||
var DEVTOOLS_CHROME_ENABLED = "devtools.chrome.enabled";
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
Services.prefs.setBoolPref(DEVTOOLS_CHROME_ENABLED, true);
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
|
||||
|
||||
openScratchpad(runTests);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,Scratchpad test for bug 646070 - chrome context preference";
|
||||
}
|
||||
|
||||
function runTests()
|
||||
{
|
||||
let sp = gScratchpadWindow.Scratchpad;
|
||||
ok(sp, "Scratchpad object exists in new window");
|
||||
|
||||
let environmentMenu = gScratchpadWindow.document.
|
||||
getElementById("sp-environment-menu");
|
||||
ok(environmentMenu, "Environment menu element exists");
|
||||
ok(!environmentMenu.hasAttribute("hidden"),
|
||||
"Environment menu is visible");
|
||||
|
||||
let errorConsoleCommand = gScratchpadWindow.document.
|
||||
getElementById("sp-cmd-errorConsole");
|
||||
ok(errorConsoleCommand, "Error console command element exists");
|
||||
ok(!errorConsoleCommand.hasAttribute("disabled"),
|
||||
"Error console command is enabled");
|
||||
|
||||
let chromeContextCommand = gScratchpadWindow.document.
|
||||
getElementById("sp-cmd-browserContext");
|
||||
ok(chromeContextCommand, "Chrome context command element exists");
|
||||
ok(!chromeContextCommand.hasAttribute("disabled"),
|
||||
"Chrome context command is disabled");
|
||||
|
||||
Services.prefs.clearUserPref(DEVTOOLS_CHROME_ENABLED);
|
||||
|
||||
finish();
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test that closing the toolbox after having opened a scratchpad leaves the
|
||||
// latter in a functioning state.
|
||||
|
||||
var {Task} = require("devtools/shared/task");
|
||||
var {TargetFactory} = require("devtools/client/framework/target");
|
||||
|
||||
function test() {
|
||||
const options = {
|
||||
tabContent: "test closing toolbox and then reusing scratchpad"
|
||||
};
|
||||
openTabAndScratchpad(options)
|
||||
.then(Task.async(runTests))
|
||||
.then(finish, console.error);
|
||||
}
|
||||
|
||||
function* runTests([win, sp]) {
|
||||
// Use the scratchpad before opening the toolbox.
|
||||
const source = "window.foobar = 7;";
|
||||
sp.setText(source);
|
||||
let [,, result] = yield sp.display();
|
||||
is(result, 7, "Display produced the expected output.");
|
||||
|
||||
// Now open the toolbox and close it again.
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
let toolbox = yield gDevTools.showToolbox(target, "webconsole");
|
||||
ok(toolbox, "Toolbox was opened.");
|
||||
let closed = yield gDevTools.closeToolbox(target);
|
||||
is(closed, true, "Toolbox was closed.");
|
||||
|
||||
// Now see if using the scratcphad works as expected.
|
||||
sp.setText(source);
|
||||
let [,, result2] = yield sp.display();
|
||||
is(result2, 7,
|
||||
"Display produced the expected output after the toolbox was gone.");
|
||||
}
|
||||
|
|
@ -0,0 +1,230 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* Bug 653427 */
|
||||
|
||||
var tempScope = {};
|
||||
Cu.import("resource://gre/modules/NetUtil.jsm", tempScope);
|
||||
Cu.import("resource://gre/modules/FileUtils.jsm", tempScope);
|
||||
var NetUtil = tempScope.NetUtil;
|
||||
var FileUtils = tempScope.FileUtils;
|
||||
|
||||
// only finish() when correct number of tests are done
|
||||
const expected = 9;
|
||||
var count = 0;
|
||||
function done()
|
||||
{
|
||||
if (++count == expected) {
|
||||
cleanup();
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
var gFile;
|
||||
|
||||
var oldPrompt = Services.prompt;
|
||||
var promptButton = -1;
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
gFile = createTempFile("fileForBug653427.tmp");
|
||||
writeFile(gFile, "text", testUnsaved.call(this));
|
||||
|
||||
Services.prompt = {
|
||||
confirmEx: function () {
|
||||
return promptButton;
|
||||
}
|
||||
};
|
||||
|
||||
testNew();
|
||||
testSavedFile();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
content.location = "data:text/html,<p>test scratchpad save file prompt on closing";
|
||||
}
|
||||
|
||||
function testNew()
|
||||
{
|
||||
openScratchpad(function (win) {
|
||||
win.Scratchpad.close(function () {
|
||||
ok(win.closed, "new scratchpad window should close without prompting");
|
||||
done();
|
||||
});
|
||||
}, {noFocus: true});
|
||||
}
|
||||
|
||||
function testSavedFile()
|
||||
{
|
||||
openScratchpad(function (win) {
|
||||
win.Scratchpad.filename = "test.js";
|
||||
win.Scratchpad.editor.dirty = false;
|
||||
win.Scratchpad.close(function () {
|
||||
ok(win.closed, "scratchpad from file with no changes should close");
|
||||
done();
|
||||
});
|
||||
}, {noFocus: true});
|
||||
}
|
||||
|
||||
function testUnsaved()
|
||||
{
|
||||
function setFilename(aScratchpad, aFile) {
|
||||
aScratchpad.setFilename(aFile);
|
||||
}
|
||||
|
||||
testUnsavedFileCancel(setFilename);
|
||||
testUnsavedFileSave(setFilename);
|
||||
testUnsavedFileDontSave(setFilename);
|
||||
testCancelAfterLoad();
|
||||
|
||||
function mockSaveFile(aScratchpad) {
|
||||
let SaveFileStub = function (aCallback) {
|
||||
/*
|
||||
* An argument for aCallback must pass Components.isSuccessCode
|
||||
*
|
||||
* A version of isSuccessCode in JavaScript:
|
||||
* function isSuccessCode(returnCode) {
|
||||
* return (returnCode & 0x80000000) == 0;
|
||||
* }
|
||||
*/
|
||||
aCallback(1);
|
||||
};
|
||||
|
||||
aScratchpad.saveFile = SaveFileStub;
|
||||
}
|
||||
|
||||
// Run these tests again but this time without setting a filename to
|
||||
// test that Scratchpad always asks for confirmation on dirty editor.
|
||||
testUnsavedFileCancel(mockSaveFile);
|
||||
testUnsavedFileSave(mockSaveFile);
|
||||
testUnsavedFileDontSave();
|
||||
}
|
||||
|
||||
function testUnsavedFileCancel(aCallback = function () {})
|
||||
{
|
||||
openScratchpad(function (win) {
|
||||
aCallback(win.Scratchpad, "test.js");
|
||||
win.Scratchpad.editor.dirty = true;
|
||||
|
||||
promptButton = win.BUTTON_POSITION_CANCEL;
|
||||
|
||||
win.Scratchpad.close(function () {
|
||||
ok(!win.closed, "cancelling dialog shouldn't close scratchpad");
|
||||
win.close();
|
||||
done();
|
||||
});
|
||||
}, {noFocus: true});
|
||||
}
|
||||
|
||||
// Test a regression where our confirmation dialog wasn't appearing
|
||||
// after openFile calls. See bug 801982.
|
||||
function testCancelAfterLoad()
|
||||
{
|
||||
openScratchpad(function (win) {
|
||||
win.Scratchpad.setRecentFile(gFile);
|
||||
win.Scratchpad.openFile(0);
|
||||
win.Scratchpad.editor.dirty = true;
|
||||
promptButton = win.BUTTON_POSITION_CANCEL;
|
||||
|
||||
let EventStub = {
|
||||
called: false,
|
||||
preventDefault: function () {
|
||||
EventStub.called = true;
|
||||
}
|
||||
};
|
||||
|
||||
win.Scratchpad.onClose(EventStub, function () {
|
||||
ok(!win.closed, "cancelling dialog shouldn't close scratchpad");
|
||||
ok(EventStub.called, "aEvent.preventDefault was called");
|
||||
|
||||
win.Scratchpad.editor.dirty = false;
|
||||
win.close();
|
||||
done();
|
||||
});
|
||||
}, {noFocus: true});
|
||||
}
|
||||
|
||||
function testUnsavedFileSave(aCallback = function () {})
|
||||
{
|
||||
openScratchpad(function (win) {
|
||||
win.Scratchpad.importFromFile(gFile, true, function (status, content) {
|
||||
aCallback(win.Scratchpad, gFile.path);
|
||||
|
||||
let text = "new text";
|
||||
win.Scratchpad.setText(text);
|
||||
|
||||
promptButton = win.BUTTON_POSITION_SAVE;
|
||||
|
||||
win.Scratchpad.close(function () {
|
||||
ok(win.closed, 'pressing "Save" in dialog should close scratchpad');
|
||||
readFile(gFile, function (savedContent) {
|
||||
is(savedContent, text, 'prompted "Save" worked when closing scratchpad');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
}, {noFocus: true});
|
||||
}
|
||||
|
||||
function testUnsavedFileDontSave(aCallback = function () {})
|
||||
{
|
||||
openScratchpad(function (win) {
|
||||
aCallback(win.Scratchpad, gFile.path);
|
||||
win.Scratchpad.editor.dirty = true;
|
||||
|
||||
promptButton = win.BUTTON_POSITION_DONT_SAVE;
|
||||
|
||||
win.Scratchpad.close(function () {
|
||||
ok(win.closed, 'pressing "Don\'t Save" in dialog should close scratchpad');
|
||||
done();
|
||||
});
|
||||
}, {noFocus: true});
|
||||
}
|
||||
|
||||
function cleanup()
|
||||
{
|
||||
Services.prompt = oldPrompt;
|
||||
gFile.remove(false);
|
||||
gFile = null;
|
||||
}
|
||||
|
||||
function createTempFile(name)
|
||||
{
|
||||
let file = FileUtils.getFile("TmpD", [name]);
|
||||
file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
|
||||
file.QueryInterface(Ci.nsILocalFile);
|
||||
return file;
|
||||
}
|
||||
|
||||
function writeFile(file, content, callback)
|
||||
{
|
||||
let fout = Cc["@mozilla.org/network/file-output-stream;1"].
|
||||
createInstance(Ci.nsIFileOutputStream);
|
||||
fout.init(file.QueryInterface(Ci.nsILocalFile), 0x02 | 0x08 | 0x20,
|
||||
0o644, fout.DEFER_OPEN);
|
||||
|
||||
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
|
||||
createInstance(Ci.nsIScriptableUnicodeConverter);
|
||||
converter.charset = "UTF-8";
|
||||
let fileContentStream = converter.convertToInputStream(content);
|
||||
|
||||
NetUtil.asyncCopy(fileContentStream, fout, callback);
|
||||
}
|
||||
|
||||
function readFile(file, callback)
|
||||
{
|
||||
let channel = NetUtil.newChannel({
|
||||
uri: NetUtil.newURI(file),
|
||||
loadUsingSystemPrincipal: true});
|
||||
channel.contentType = "application/javascript";
|
||||
|
||||
NetUtil.asyncFetch(channel, function (inputStream, status) {
|
||||
ok(Components.isSuccessCode(status),
|
||||
"file was read successfully");
|
||||
|
||||
let content = NetUtil.readInputStreamToString(inputStream,
|
||||
inputStream.available());
|
||||
callback(content);
|
||||
});
|
||||
}
|
||||
149
devtools/client/scratchpad/test/browser_scratchpad_contexts.js
Normal file
149
devtools/client/scratchpad/test/browser_scratchpad_contexts.js
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
"use strict";
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
|
||||
openScratchpad(runTests);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,test context switch in Scratchpad";
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
let sp = gScratchpadWindow.Scratchpad;
|
||||
let contentMenu = gScratchpadWindow.document.getElementById("sp-menu-content");
|
||||
let chromeMenu = gScratchpadWindow.document.getElementById("sp-menu-browser");
|
||||
let notificationBox = sp.notificationBox;
|
||||
|
||||
ok(contentMenu, "found #sp-menu-content");
|
||||
ok(chromeMenu, "found #sp-menu-browser");
|
||||
ok(notificationBox, "found Scratchpad.notificationBox");
|
||||
|
||||
let tests = [{
|
||||
method: "run",
|
||||
prepare: function* () {
|
||||
sp.setContentContext();
|
||||
|
||||
is(sp.executionContext, gScratchpadWindow.SCRATCHPAD_CONTEXT_CONTENT,
|
||||
"executionContext is content");
|
||||
|
||||
is(contentMenu.getAttribute("checked"), "true",
|
||||
"content menuitem is checked");
|
||||
|
||||
isnot(chromeMenu.getAttribute("checked"), "true",
|
||||
"chrome menuitem is not checked");
|
||||
|
||||
ok(!notificationBox.currentNotification,
|
||||
"there is no notification in content context");
|
||||
|
||||
sp.editor.setText("window.foobarBug636725 = 'aloha';");
|
||||
|
||||
let pageResult = yield inContent(function* () {
|
||||
return content.wrappedJSObject.foobarBug636725;
|
||||
});
|
||||
ok(!pageResult, "no content.foobarBug636725");
|
||||
},
|
||||
then: function* () {
|
||||
is(content.wrappedJSObject.foobarBug636725, "aloha",
|
||||
"content.foobarBug636725 has been set");
|
||||
}
|
||||
}, {
|
||||
method: "run",
|
||||
prepare: function* () {
|
||||
sp.setBrowserContext();
|
||||
|
||||
is(sp.executionContext, gScratchpadWindow.SCRATCHPAD_CONTEXT_BROWSER,
|
||||
"executionContext is chrome");
|
||||
|
||||
is(chromeMenu.getAttribute("checked"), "true",
|
||||
"chrome menuitem is checked");
|
||||
|
||||
isnot(contentMenu.getAttribute("checked"), "true",
|
||||
"content menuitem is not checked");
|
||||
|
||||
ok(notificationBox.currentNotification,
|
||||
"there is a notification in browser context");
|
||||
|
||||
let [ from, to ] = sp.editor.getPosition(31, 32);
|
||||
sp.editor.replaceText("2'", from, to);
|
||||
|
||||
is(sp.getText(), "window.foobarBug636725 = 'aloha2';",
|
||||
"setText() worked");
|
||||
},
|
||||
then: function* () {
|
||||
is(window.foobarBug636725, "aloha2",
|
||||
"window.foobarBug636725 has been set");
|
||||
|
||||
delete window.foobarBug636725;
|
||||
ok(!window.foobarBug636725, "no window.foobarBug636725");
|
||||
}
|
||||
}, {
|
||||
method: "run",
|
||||
prepare: function* () {
|
||||
sp.editor.replaceText("gBrowser", sp.editor.getPosition(7));
|
||||
|
||||
is(sp.getText(), "window.gBrowser",
|
||||
"setText() worked with no end for the replace range");
|
||||
},
|
||||
then: function* ([, , result]) {
|
||||
is(result.class, "XULElement",
|
||||
"chrome context has access to chrome objects");
|
||||
}
|
||||
}, {
|
||||
method: "run",
|
||||
prepare: function* () {
|
||||
// Check that the sandbox is cached.
|
||||
sp.editor.setText("typeof foobarBug636725cache;");
|
||||
},
|
||||
then: function* ([, , result]) {
|
||||
is(result, "undefined", "global variable does not exist");
|
||||
}
|
||||
}, {
|
||||
method: "run",
|
||||
prepare: function* () {
|
||||
sp.editor.setText("window.foobarBug636725cache = 'foo';" +
|
||||
"typeof foobarBug636725cache;");
|
||||
},
|
||||
then: function* ([, , result]) {
|
||||
is(result, "string",
|
||||
"global variable exists across two different executions");
|
||||
}
|
||||
}, {
|
||||
method: "run",
|
||||
prepare: function* () {
|
||||
sp.editor.setText("window.foobarBug636725cache2 = 'foo';" +
|
||||
"typeof foobarBug636725cache2;");
|
||||
},
|
||||
then: function* ([, , result]) {
|
||||
is(result, "string",
|
||||
"global variable exists across two different executions");
|
||||
}
|
||||
}, {
|
||||
method: "run",
|
||||
prepare: function* () {
|
||||
sp.setContentContext();
|
||||
|
||||
is(sp.executionContext, gScratchpadWindow.SCRATCHPAD_CONTEXT_CONTENT,
|
||||
"executionContext is content");
|
||||
|
||||
sp.editor.setText("typeof foobarBug636725cache2;");
|
||||
},
|
||||
then: function* ([, , result]) {
|
||||
is(result, "undefined",
|
||||
"global variable no longer exists after changing the context");
|
||||
}
|
||||
}];
|
||||
|
||||
runAsyncCallbackTests(sp, tests).then(() => {
|
||||
sp.setBrowserContext();
|
||||
sp.editor.setText("delete foobarBug636725cache;" +
|
||||
"delete foobarBug636725cache2;");
|
||||
sp.run().then(finish);
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test if the view menu items "Larger Font" and "Smaller Font" are disabled
|
||||
// when the font size reaches the maximum/minimum values.
|
||||
|
||||
var {Task} = require("devtools/shared/task");
|
||||
|
||||
function test() {
|
||||
const options = {
|
||||
tabContent: 'test if view menu items "Larger Font" and "Smaller Font" are enabled/disabled.'
|
||||
};
|
||||
openTabAndScratchpad(options)
|
||||
.then(Task.async(runTests))
|
||||
.then(finish, console.error);
|
||||
}
|
||||
|
||||
function* runTests([win, sp]) {
|
||||
yield testMaximumFontSize(win, sp);
|
||||
|
||||
yield testMinimumFontSize(win, sp);
|
||||
}
|
||||
|
||||
const MAXIMUM_FONT_SIZE = 96;
|
||||
const MINIMUM_FONT_SIZE = 6;
|
||||
const NORMAL_FONT_SIZE = 12;
|
||||
|
||||
var testMaximumFontSize = Task.async(function* (win, sp) {
|
||||
let doc = win.document;
|
||||
|
||||
Services.prefs.clearUserPref("devtools.scratchpad.editorFontSize");
|
||||
|
||||
let menu = doc.getElementById("sp-menu-larger-font");
|
||||
|
||||
for (let i = NORMAL_FONT_SIZE; i <= MAXIMUM_FONT_SIZE; i++) {
|
||||
menu.doCommand();
|
||||
}
|
||||
|
||||
let cmd = doc.getElementById("sp-cmd-larger-font");
|
||||
ok(cmd.getAttribute("disabled") === "true", 'Command "sp-cmd-larger-font" is disabled.');
|
||||
|
||||
menu = doc.getElementById("sp-menu-smaller-font");
|
||||
menu.doCommand();
|
||||
|
||||
ok(cmd.hasAttribute("disabled") === false, 'Command "sp-cmd-larger-font" is enabled.');
|
||||
});
|
||||
|
||||
var testMinimumFontSize = Task.async(function* (win, sp) {
|
||||
let doc = win.document;
|
||||
|
||||
let menu = doc.getElementById("sp-menu-smaller-font");
|
||||
|
||||
for (let i = MAXIMUM_FONT_SIZE; i >= MINIMUM_FONT_SIZE; i--) {
|
||||
menu.doCommand();
|
||||
}
|
||||
|
||||
let cmd = doc.getElementById("sp-cmd-smaller-font");
|
||||
ok(cmd.getAttribute("disabled") === "true", 'Command "sp-cmd-smaller-font" is disabled.');
|
||||
|
||||
menu = doc.getElementById("sp-menu-larger-font");
|
||||
menu.doCommand();
|
||||
|
||||
ok(cmd.hasAttribute("disabled") === false, 'Command "sp-cmd-smaller-font" is enabled.');
|
||||
|
||||
Services.prefs.clearUserPref("devtools.scratchpad.editorFontSize");
|
||||
});
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* Bug 756681 */
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function browserLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", browserLoad, true);
|
||||
openScratchpad(runTests, {"state":{"text":""}});
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html, test that exceptions are output as " +
|
||||
"comments correctly in Scratchpad";
|
||||
}
|
||||
|
||||
function runTests()
|
||||
{
|
||||
var scratchpad = gScratchpadWindow.Scratchpad;
|
||||
|
||||
var message = "\"Hello World!\"";
|
||||
var openComment = "\n/*\n";
|
||||
var closeComment = "\n*/";
|
||||
var error1 = "throw new Error(\"Ouch!\")";
|
||||
var error2 = "throw \"A thrown string\"";
|
||||
var error3 = "throw {}";
|
||||
var error4 = "document.body.appendChild(document.body)";
|
||||
|
||||
let tests = [{
|
||||
// Display message
|
||||
method: "display",
|
||||
code: message,
|
||||
result: message + openComment + "Hello World!" + closeComment,
|
||||
label: "message display output"
|
||||
},
|
||||
{
|
||||
// Display error1, throw new Error("Ouch")
|
||||
method: "display",
|
||||
code: error1,
|
||||
result: error1 + openComment +
|
||||
"Exception: Error: Ouch!\n@" + scratchpad.uniqueName + ":1:7" + closeComment,
|
||||
label: "error display output"
|
||||
},
|
||||
{
|
||||
// Display error2, throw "A thrown string"
|
||||
method: "display",
|
||||
code: error2,
|
||||
result: error2 + openComment + "Exception: A thrown string" + closeComment,
|
||||
label: "thrown string display output"
|
||||
},
|
||||
{
|
||||
// Display error3, throw {}
|
||||
method: "display",
|
||||
code: error3,
|
||||
result: error3 + openComment + "Exception: [object Object]" + closeComment,
|
||||
label: "thrown object display output"
|
||||
},
|
||||
{
|
||||
// Display error4, document.body.appendChild(document.body)
|
||||
method: "display",
|
||||
code: error4,
|
||||
result: error4 + openComment + "Exception: HierarchyRequestError: Node cannot be inserted " +
|
||||
"at the specified point in the hierarchy\n@" +
|
||||
scratchpad.uniqueName + ":1:0" + closeComment,
|
||||
label: "Alternative format error display output"
|
||||
},
|
||||
{
|
||||
// Run message
|
||||
method: "run",
|
||||
code: message,
|
||||
result: message,
|
||||
label: "message run output"
|
||||
},
|
||||
{
|
||||
// Run error1, throw new Error("Ouch")
|
||||
method: "run",
|
||||
code: error1,
|
||||
result: error1 + openComment +
|
||||
"Exception: Error: Ouch!\n@" + scratchpad.uniqueName + ":1:7" + closeComment,
|
||||
label: "error run output"
|
||||
},
|
||||
{
|
||||
// Run error2, throw "A thrown string"
|
||||
method: "run",
|
||||
code: error2,
|
||||
result: error2 + openComment + "Exception: A thrown string" + closeComment,
|
||||
label: "thrown string run output"
|
||||
},
|
||||
{
|
||||
// Run error3, throw {}
|
||||
method: "run",
|
||||
code: error3,
|
||||
result: error3 + openComment + "Exception: [object Object]" + closeComment,
|
||||
label: "thrown object run output"
|
||||
},
|
||||
{
|
||||
// Run error4, document.body.appendChild(document.body)
|
||||
method: "run",
|
||||
code: error4,
|
||||
result: error4 + openComment + "Exception: HierarchyRequestError: Node cannot be inserted " +
|
||||
"at the specified point in the hierarchy\n@" +
|
||||
scratchpad.uniqueName + ":1:0" + closeComment,
|
||||
label: "Alternative format error run output"
|
||||
}];
|
||||
|
||||
runAsyncTests(scratchpad, tests).then(finish);
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* Bug 690552 */
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function browserLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", browserLoad, true);
|
||||
openScratchpad(runTests, {"state":{"text":""}});
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,<p>test that exceptions are output as " +
|
||||
"comments for 'display' and not sent to the console in Scratchpad";
|
||||
}
|
||||
|
||||
function runTests()
|
||||
{
|
||||
let scratchpad = gScratchpadWindow.Scratchpad;
|
||||
|
||||
let message = "\"Hello World!\"";
|
||||
let openComment = "\n/*\n";
|
||||
let closeComment = "\n*/";
|
||||
let error = "throw new Error(\"Ouch!\")";
|
||||
let syntaxError = "(";
|
||||
|
||||
let tests = [{
|
||||
method: "display",
|
||||
code: message,
|
||||
result: message + openComment + "Hello World!" + closeComment,
|
||||
label: "message display output"
|
||||
},
|
||||
{
|
||||
method: "display",
|
||||
code: error,
|
||||
result: error + openComment + "Exception: Error: Ouch!\n@" +
|
||||
scratchpad.uniqueName + ":1:7" + closeComment,
|
||||
label: "error display output",
|
||||
},
|
||||
{
|
||||
method: "display",
|
||||
code: syntaxError,
|
||||
result: syntaxError + openComment + "Exception: SyntaxError: expected expression, got end of script\n@" +
|
||||
scratchpad.uniqueName + ":1" + closeComment,
|
||||
label: "syntaxError display output",
|
||||
},
|
||||
{
|
||||
method: "run",
|
||||
code: message,
|
||||
result: message,
|
||||
label: "message run output",
|
||||
},
|
||||
{
|
||||
method: "run",
|
||||
code: error,
|
||||
result: error + openComment + "Exception: Error: Ouch!\n@" +
|
||||
scratchpad.uniqueName + ":1:7" + closeComment,
|
||||
label: "error run output",
|
||||
},
|
||||
{
|
||||
method: "run",
|
||||
code: syntaxError,
|
||||
result: syntaxError + openComment + "Exception: SyntaxError: expected expression, got end of script\n@" +
|
||||
scratchpad.uniqueName + ":1" + closeComment,
|
||||
label: "syntaxError run output",
|
||||
}];
|
||||
|
||||
runAsyncTests(scratchpad, tests).then(finish);
|
||||
}
|
||||
|
|
@ -0,0 +1,206 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* Bug 699130 */
|
||||
|
||||
"use strict";
|
||||
|
||||
var WebConsoleUtils = require("devtools/client/webconsole/utils").Utils;
|
||||
var DEVTOOLS_CHROME_ENABLED = "devtools.chrome.enabled";
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
Services.prefs.setBoolPref(DEVTOOLS_CHROME_ENABLED, false);
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
|
||||
openScratchpad(runTests);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,test Edit menu updates Scratchpad - bug 699130";
|
||||
}
|
||||
|
||||
function runTests()
|
||||
{
|
||||
let sp = gScratchpadWindow.Scratchpad;
|
||||
let doc = gScratchpadWindow.document;
|
||||
let winUtils = gScratchpadWindow.QueryInterface(Ci.nsIInterfaceRequestor).
|
||||
getInterface(Ci.nsIDOMWindowUtils);
|
||||
let OS = Services.appinfo.OS;
|
||||
|
||||
info("will test the Edit menu");
|
||||
|
||||
let pass = 0;
|
||||
|
||||
sp.setText("bug 699130: hello world! (edit menu)");
|
||||
|
||||
let editMenu = doc.getElementById("sp-edit-menu");
|
||||
ok(editMenu, "the Edit menu");
|
||||
let menubar = editMenu.parentNode;
|
||||
ok(menubar, "menubar found");
|
||||
|
||||
let editMenuIndex = -1;
|
||||
for (let i = 0; i < menubar.children.length; i++) {
|
||||
if (menubar.children[i] === editMenu) {
|
||||
editMenuIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
isnot(editMenuIndex, -1, "Edit menu index is correct");
|
||||
|
||||
let menuPopup = editMenu.menupopup;
|
||||
ok(menuPopup, "the Edit menupopup");
|
||||
let cutItem = doc.getElementById("menu_cut");
|
||||
ok(cutItem, "the Cut menuitem");
|
||||
let pasteItem = doc.getElementById("menu_paste");
|
||||
ok(pasteItem, "the Paste menuitem");
|
||||
|
||||
let anchor = doc.documentElement;
|
||||
let isContextMenu = false;
|
||||
|
||||
let oldVal = sp.editor.getText();
|
||||
|
||||
let testSelfXss = function (oldVal) {
|
||||
// Self xss prevention tests (bug 994134)
|
||||
info("Self xss paste tests");
|
||||
is(WebConsoleUtils.usageCount, 0, "Test for usage count getter");
|
||||
let notificationbox = doc.getElementById("scratchpad-notificationbox");
|
||||
let notification = notificationbox.getNotificationWithValue("selfxss-notification");
|
||||
ok(notification, "Self-xss notification shown");
|
||||
is(oldVal, sp.editor.getText(), "Paste blocked by self-xss prevention");
|
||||
Services.prefs.setIntPref("devtools.selfxss.count", 10);
|
||||
notificationbox.removeAllNotifications(true);
|
||||
openMenu(10, 10, firstShow);
|
||||
};
|
||||
|
||||
let openMenu = function (aX, aY, aCallback) {
|
||||
if (!editMenu || OS != "Darwin") {
|
||||
menuPopup.addEventListener("popupshown", function onPopupShown() {
|
||||
menuPopup.removeEventListener("popupshown", onPopupShown, false);
|
||||
executeSoon(aCallback);
|
||||
}, false);
|
||||
}
|
||||
|
||||
executeSoon(function () {
|
||||
if (editMenu) {
|
||||
if (OS == "Darwin") {
|
||||
winUtils.forceUpdateNativeMenuAt(editMenuIndex);
|
||||
executeSoon(aCallback);
|
||||
} else {
|
||||
editMenu.open = true;
|
||||
}
|
||||
} else {
|
||||
menuPopup.openPopup(anchor, "overlap", aX, aY, isContextMenu, false);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
let closeMenu = function (aCallback) {
|
||||
if (!editMenu || OS != "Darwin") {
|
||||
menuPopup.addEventListener("popuphidden", function onPopupHidden() {
|
||||
menuPopup.removeEventListener("popuphidden", onPopupHidden, false);
|
||||
executeSoon(aCallback);
|
||||
}, false);
|
||||
}
|
||||
|
||||
executeSoon(function () {
|
||||
if (editMenu) {
|
||||
if (OS == "Darwin") {
|
||||
winUtils.forceUpdateNativeMenuAt(editMenuIndex);
|
||||
executeSoon(aCallback);
|
||||
} else {
|
||||
editMenu.open = false;
|
||||
}
|
||||
} else {
|
||||
menuPopup.hidePopup();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
let firstShow = function () {
|
||||
ok(!cutItem.hasAttribute("disabled"), "cut menuitem is enabled");
|
||||
closeMenu(firstHide);
|
||||
};
|
||||
|
||||
let firstHide = function () {
|
||||
sp.editor.setSelection({ line: 0, ch: 0 }, { line: 0, ch: 10 });
|
||||
openMenu(11, 11, showAfterSelect);
|
||||
};
|
||||
|
||||
let showAfterSelect = function () {
|
||||
ok(!cutItem.hasAttribute("disabled"), "cut menuitem is enabled after select");
|
||||
closeMenu(hideAfterSelect);
|
||||
};
|
||||
|
||||
let hideAfterSelect = function () {
|
||||
sp.editor.on("change", onCut);
|
||||
waitForFocus(function () {
|
||||
let selectedText = sp.editor.getSelection();
|
||||
ok(selectedText.length > 0, "non-empty selected text will be cut");
|
||||
|
||||
EventUtils.synthesizeKey("x", {accelKey: true}, gScratchpadWindow);
|
||||
}, gScratchpadWindow);
|
||||
};
|
||||
|
||||
let onCut = function () {
|
||||
sp.editor.off("change", onCut);
|
||||
openMenu(12, 12, showAfterCut);
|
||||
};
|
||||
|
||||
let showAfterCut = function () {
|
||||
ok(!cutItem.hasAttribute("disabled"), "cut menuitem is enabled after cut");
|
||||
ok(!pasteItem.hasAttribute("disabled"), "paste menuitem is enabled after cut");
|
||||
closeMenu(hideAfterCut);
|
||||
};
|
||||
|
||||
let hideAfterCut = function () {
|
||||
waitForFocus(function () {
|
||||
sp.editor.on("change", onPaste);
|
||||
EventUtils.synthesizeKey("v", {accelKey: true}, gScratchpadWindow);
|
||||
}, gScratchpadWindow);
|
||||
};
|
||||
|
||||
let onPaste = function () {
|
||||
sp.editor.off("change", onPaste);
|
||||
openMenu(13, 13, showAfterPaste);
|
||||
};
|
||||
|
||||
let showAfterPaste = function () {
|
||||
ok(!cutItem.hasAttribute("disabled"), "cut menuitem is enabled after paste");
|
||||
ok(!pasteItem.hasAttribute("disabled"), "paste menuitem is enabled after paste");
|
||||
closeMenu(hideAfterPaste);
|
||||
};
|
||||
|
||||
let hideAfterPaste = function () {
|
||||
if (pass == 0) {
|
||||
pass++;
|
||||
testContextMenu();
|
||||
} else {
|
||||
Services.prefs.clearUserPref(DEVTOOLS_CHROME_ENABLED);
|
||||
finish();
|
||||
}
|
||||
};
|
||||
|
||||
let testContextMenu = function () {
|
||||
info("will test the context menu");
|
||||
|
||||
editMenu = null;
|
||||
isContextMenu = true;
|
||||
|
||||
menuPopup = doc.getElementById("scratchpad-text-popup");
|
||||
ok(menuPopup, "the context menupopup");
|
||||
cutItem = doc.getElementById("cMenu_cut");
|
||||
ok(cutItem, "the Cut menuitem");
|
||||
pasteItem = doc.getElementById("cMenu_paste");
|
||||
ok(pasteItem, "the Paste menuitem");
|
||||
|
||||
sp.setText("bug 699130: hello world! (context menu)");
|
||||
openMenu(10, 10, firstShow);
|
||||
};
|
||||
waitForFocus(function () {
|
||||
WebConsoleUtils.usageCount = 0;
|
||||
EventUtils.synthesizeKey("v", {accelKey: true}, gScratchpadWindow);
|
||||
testSelfXss(oldVal);
|
||||
}, gScratchpadWindow);
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
|
||||
openScratchpad(runTests);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html;charset=utf8,test Scratchpad eval function.";
|
||||
}
|
||||
|
||||
function reportErrorAndQuit(error) {
|
||||
DevToolsUtils.reportException("browser_scratchpad_eval_func.js", error);
|
||||
ok(false);
|
||||
finish();
|
||||
}
|
||||
|
||||
function runTests(sw)
|
||||
{
|
||||
const sp = sw.Scratchpad;
|
||||
|
||||
let foo = "" + function main() { console.log(1); };
|
||||
let bar = "var bar = " + (() => { console.log(2); });
|
||||
|
||||
const fullText =
|
||||
foo + "\n" +
|
||||
"\n" +
|
||||
bar + "\n";
|
||||
|
||||
sp.setText(fullText);
|
||||
|
||||
// On the function declaration.
|
||||
sp.editor.setCursor({ line: 0, ch: 18 });
|
||||
sp.evalTopLevelFunction()
|
||||
.then(([text, error, result]) => {
|
||||
is(text, foo, "Should re-eval foo.");
|
||||
ok(!error, "Should not have got an error.");
|
||||
ok(result, "Should have got a result.");
|
||||
})
|
||||
|
||||
// On the arrow function.
|
||||
.then(() => {
|
||||
sp.editor.setCursor({ line: 2, ch: 18 });
|
||||
return sp.evalTopLevelFunction();
|
||||
})
|
||||
.then(([text, error, result]) => {
|
||||
is(text, bar.replace("var ", ""), "Should re-eval bar.");
|
||||
ok(!error, "Should not have got an error.");
|
||||
ok(result, "Should have got a result.");
|
||||
})
|
||||
|
||||
// On the empty line.
|
||||
.then(() => {
|
||||
sp.editor.setCursor({ line: 1, ch: 0 });
|
||||
return sp.evalTopLevelFunction();
|
||||
})
|
||||
.then(([text, error, result]) => {
|
||||
is(text, fullText,
|
||||
"Should get full text back since we didn't find a specific function.");
|
||||
ok(!error, "Should not have got an error.");
|
||||
ok(!result, "Should not have got a result.");
|
||||
})
|
||||
|
||||
// Syntax error.
|
||||
.then(() => {
|
||||
sp.setText("function {}");
|
||||
sp.editor.setCursor({ line: 0, ch: 9 });
|
||||
return sp.evalTopLevelFunction();
|
||||
})
|
||||
.then(([text, error, result]) => {
|
||||
is(text, "function {}",
|
||||
"Should get the full text back since there was a parse error.");
|
||||
ok(!error, "Should not have got an error");
|
||||
ok(!result, "Should not have got a result");
|
||||
ok(sp.getText().includes("SyntaxError"),
|
||||
"We should have written the syntax error to the scratchpad.");
|
||||
})
|
||||
|
||||
.then(finish, reportErrorAndQuit);
|
||||
}
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
"use strict";
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onTabLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onTabLoad, true);
|
||||
openScratchpad(runTests);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,<p>test run() and display() in Scratchpad";
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
let sp = gScratchpadWindow.Scratchpad;
|
||||
let tests = [{
|
||||
method: "run",
|
||||
prepare: function* () {
|
||||
yield inContent(function* () {
|
||||
content.wrappedJSObject.foobarBug636725 = 1;
|
||||
});
|
||||
sp.editor.setText("++window.foobarBug636725");
|
||||
},
|
||||
then: function* ([code, , result]) {
|
||||
is(code, sp.getText(), "code is correct");
|
||||
|
||||
let pageResult = yield inContent(function* () {
|
||||
return content.wrappedJSObject.foobarBug636725;
|
||||
});
|
||||
is(result, pageResult,
|
||||
"result is correct");
|
||||
|
||||
is(sp.getText(), "++window.foobarBug636725",
|
||||
"run() does not change the editor content");
|
||||
|
||||
is(pageResult, 2, "run() updated window.foobarBug636725");
|
||||
}
|
||||
}, {
|
||||
method: "display",
|
||||
prepare: function* () {},
|
||||
then: function* () {
|
||||
let pageResult = yield inContent(function* () {
|
||||
return content.wrappedJSObject.foobarBug636725;
|
||||
});
|
||||
is(pageResult, 3, "display() updated window.foobarBug636725");
|
||||
|
||||
is(sp.getText(), "++window.foobarBug636725\n/*\n3\n*/",
|
||||
"display() shows evaluation result in the textbox");
|
||||
|
||||
is(sp.editor.getSelection(), "\n/*\n3\n*/", "getSelection is correct");
|
||||
}
|
||||
}, {
|
||||
method: "run",
|
||||
prepare: function* () {
|
||||
sp.editor.setText("window.foobarBug636725 = 'a';\n" +
|
||||
"window.foobarBug636725 = 'b';");
|
||||
sp.editor.setSelection({ line: 0, ch: 0 }, { line: 0, ch: 29 });
|
||||
},
|
||||
then: function* ([code, , result]) {
|
||||
is(code, "window.foobarBug636725 = 'a';", "code is correct");
|
||||
is(result, "a", "result is correct");
|
||||
|
||||
is(sp.getText(), "window.foobarBug636725 = 'a';\n" +
|
||||
"window.foobarBug636725 = 'b';",
|
||||
"run() does not change the textbox value");
|
||||
|
||||
let pageResult = yield inContent(function* () {
|
||||
return content.wrappedJSObject.foobarBug636725;
|
||||
});
|
||||
is(pageResult, "a", "run() worked for the selected range");
|
||||
}
|
||||
}, {
|
||||
method: "display",
|
||||
prepare: function* () {
|
||||
sp.editor.setText("window.foobarBug636725 = 'c';\n" +
|
||||
"window.foobarBug636725 = 'b';");
|
||||
sp.editor.setSelection({ line: 0, ch: 0 }, { line: 0, ch: 22 });
|
||||
},
|
||||
then: function* () {
|
||||
let pageResult = yield inContent(function* () {
|
||||
return content.wrappedJSObject.foobarBug636725;
|
||||
});
|
||||
is(pageResult, "a", "display() worked for the selected range");
|
||||
|
||||
is(sp.getText(), "window.foobarBug636725" +
|
||||
"\n/*\na\n*/" +
|
||||
" = 'c';\n" +
|
||||
"window.foobarBug636725 = 'b';",
|
||||
"display() shows evaluation result in the textbox");
|
||||
|
||||
is(sp.editor.getSelection(), "\n/*\na\n*/", "getSelection is correct");
|
||||
}
|
||||
}];
|
||||
|
||||
runAsyncCallbackTests(sp, tests).then(function () {
|
||||
ok(sp.editor.somethingSelected(), "something is selected");
|
||||
sp.editor.dropSelection();
|
||||
ok(!sp.editor.somethingSelected(), "something is no longer selected");
|
||||
ok(!sp.editor.getSelection(), "getSelection is empty");
|
||||
|
||||
// Test undo/redo.
|
||||
sp.editor.setText("foo1");
|
||||
sp.editor.setText("foo2");
|
||||
is(sp.getText(), "foo2", "editor content updated");
|
||||
sp.undo();
|
||||
is(sp.getText(), "foo1", "undo() works");
|
||||
sp.redo();
|
||||
is(sp.getText(), "foo2", "redo() works");
|
||||
|
||||
finish();
|
||||
});
|
||||
}
|
||||
69
devtools/client/scratchpad/test/browser_scratchpad_falsy.js
Normal file
69
devtools/client/scratchpad/test/browser_scratchpad_falsy.js
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* Bug 679467 */
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
|
||||
openScratchpad(testFalsy);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,<p>test falsy display() values in Scratchpad";
|
||||
}
|
||||
|
||||
function testFalsy()
|
||||
{
|
||||
let scratchpad = gScratchpadWindow.Scratchpad;
|
||||
verifyFalsies(scratchpad).then(function () {
|
||||
scratchpad.setBrowserContext();
|
||||
verifyFalsies(scratchpad).then(finish);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function verifyFalsies(scratchpad)
|
||||
{
|
||||
let tests = [{
|
||||
method: "display",
|
||||
code: "undefined",
|
||||
result: "undefined\n/*\nundefined\n*/",
|
||||
label: "undefined is displayed"
|
||||
},
|
||||
{
|
||||
method: "display",
|
||||
code: "false",
|
||||
result: "false\n/*\nfalse\n*/",
|
||||
label: "false is displayed"
|
||||
},
|
||||
{
|
||||
method: "display",
|
||||
code: "0",
|
||||
result: "0\n/*\n0\n*/",
|
||||
label: "0 is displayed"
|
||||
},
|
||||
{
|
||||
method: "display",
|
||||
code: "null",
|
||||
result: "null\n/*\nnull\n*/",
|
||||
label: "null is displayed"
|
||||
},
|
||||
{
|
||||
method: "display",
|
||||
code: "NaN",
|
||||
result: "NaN\n/*\nNaN\n*/",
|
||||
label: "NaN is displayed"
|
||||
},
|
||||
{
|
||||
method: "display",
|
||||
code: "''",
|
||||
result: "''\n/*\n\n*/",
|
||||
label: "the empty string is displayed"
|
||||
}];
|
||||
|
||||
return runAsyncTests(scratchpad, tests);
|
||||
}
|
||||
119
devtools/client/scratchpad/test/browser_scratchpad_files.js
Normal file
119
devtools/client/scratchpad/test/browser_scratchpad_files.js
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Reference to the Scratchpad object.
|
||||
var gScratchpad;
|
||||
|
||||
// Reference to the temporary nsIFile we will work with.
|
||||
var gFile;
|
||||
|
||||
// The temporary file content.
|
||||
var gFileContent = "hello.world('bug636725');";
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
|
||||
openScratchpad(runTests);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,<p>test file open and save in Scratchpad";
|
||||
}
|
||||
|
||||
function runTests()
|
||||
{
|
||||
gScratchpad = gScratchpadWindow.Scratchpad;
|
||||
|
||||
createTempFile("fileForBug636725.tmp", gFileContent, function (aStatus, aFile) {
|
||||
ok(Components.isSuccessCode(aStatus),
|
||||
"The temporary file was saved successfully");
|
||||
|
||||
gFile = aFile;
|
||||
gScratchpad.importFromFile(gFile.QueryInterface(Ci.nsILocalFile), true,
|
||||
fileImported);
|
||||
});
|
||||
}
|
||||
|
||||
function fileImported(aStatus, aFileContent)
|
||||
{
|
||||
ok(Components.isSuccessCode(aStatus),
|
||||
"the temporary file was imported successfully with Scratchpad");
|
||||
|
||||
is(aFileContent, gFileContent,
|
||||
"received data is correct");
|
||||
|
||||
is(gScratchpad.getText(), gFileContent,
|
||||
"the editor content is correct");
|
||||
|
||||
is(gScratchpad.dirty, false,
|
||||
"the editor marks imported file as saved");
|
||||
|
||||
// Save the file after changes.
|
||||
gFileContent += "// omg, saved!";
|
||||
gScratchpad.editor.setText(gFileContent);
|
||||
|
||||
gScratchpad.exportToFile(gFile.QueryInterface(Ci.nsILocalFile), true, true,
|
||||
fileExported);
|
||||
}
|
||||
|
||||
function fileExported(aStatus)
|
||||
{
|
||||
ok(Components.isSuccessCode(aStatus),
|
||||
"the temporary file was exported successfully with Scratchpad");
|
||||
|
||||
let oldContent = gFileContent;
|
||||
|
||||
// Attempt another file save, with confirmation which returns false.
|
||||
gFileContent += "// omg, saved twice!";
|
||||
gScratchpad.editor.setText(gFileContent);
|
||||
|
||||
let oldConfirm = gScratchpadWindow.confirm;
|
||||
let askedConfirmation = false;
|
||||
gScratchpadWindow.confirm = function () {
|
||||
askedConfirmation = true;
|
||||
return false;
|
||||
};
|
||||
|
||||
gScratchpad.exportToFile(gFile.QueryInterface(Ci.nsILocalFile), false, true,
|
||||
fileExported2);
|
||||
|
||||
gScratchpadWindow.confirm = oldConfirm;
|
||||
|
||||
ok(askedConfirmation, "exportToFile() asked for overwrite confirmation");
|
||||
|
||||
gFileContent = oldContent;
|
||||
|
||||
let channel = NetUtil.newChannel({
|
||||
uri: NetUtil.newURI(gFile),
|
||||
loadUsingSystemPrincipal: true});
|
||||
channel.contentType = "application/javascript";
|
||||
|
||||
// Read back the temporary file.
|
||||
NetUtil.asyncFetch(channel, fileRead);
|
||||
}
|
||||
|
||||
function fileExported2()
|
||||
{
|
||||
ok(false, "exportToFile() did not cancel file overwrite");
|
||||
}
|
||||
|
||||
function fileRead(aInputStream, aStatus)
|
||||
{
|
||||
ok(Components.isSuccessCode(aStatus),
|
||||
"the temporary file was read back successfully");
|
||||
|
||||
let updatedContent =
|
||||
NetUtil.readInputStreamToString(aInputStream, aInputStream.available());
|
||||
|
||||
is(updatedContent, gFileContent, "file properly updated");
|
||||
|
||||
// Done!
|
||||
gFile.remove(false);
|
||||
gFile = null;
|
||||
gScratchpad = null;
|
||||
finish();
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* Bug 714942 */
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function browserLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", browserLoad, true);
|
||||
openScratchpad(runTests);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,<p>test the 'Jump to line' feature in Scratchpad";
|
||||
}
|
||||
|
||||
function runTests(aWindow, aScratchpad)
|
||||
{
|
||||
let editor = aScratchpad.editor;
|
||||
let text = "foobar bug650345\nBug650345 bazbaz\nfoobar omg\ntest";
|
||||
editor.setText(text);
|
||||
editor.setCursor({ line: 0, ch: 0 });
|
||||
|
||||
let oldPrompt = editor.openDialog;
|
||||
let desiredValue;
|
||||
|
||||
editor.openDialog = function (text, cb) {
|
||||
cb(desiredValue);
|
||||
};
|
||||
|
||||
desiredValue = 3;
|
||||
EventUtils.synthesizeKey("J", {accelKey: true}, aWindow);
|
||||
is(editor.getCursor().line, 2, "line is correct");
|
||||
|
||||
desiredValue = 2;
|
||||
EventUtils.synthesizeKey("J", {accelKey: true}, aWindow);
|
||||
is(editor.getCursor().line, 1, "line is correct (again)");
|
||||
|
||||
editor.openDialog = oldPrompt;
|
||||
finish();
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* Bug 650760 */
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
content.location = "data:text/html,Test keybindings for opening Scratchpad MDN Documentation, bug 650760";
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onTabLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onTabLoad, true);
|
||||
|
||||
openScratchpad(runTest);
|
||||
}, true);
|
||||
}
|
||||
|
||||
function runTest()
|
||||
{
|
||||
let sp = gScratchpadWindow.Scratchpad;
|
||||
ok(sp, "Scratchpad object exists in new window");
|
||||
ok(sp.editor.hasFocus(), "the editor has focus");
|
||||
|
||||
let keyid = gScratchpadWindow.document.getElementById("key_openHelp");
|
||||
let modifiers = keyid.getAttribute("modifiers");
|
||||
|
||||
let key = null;
|
||||
if (keyid.getAttribute("keycode"))
|
||||
key = keyid.getAttribute("keycode");
|
||||
|
||||
else if (keyid.getAttribute("key"))
|
||||
key = keyid.getAttribute("key");
|
||||
|
||||
isnot(key, null, "Successfully retrieved keycode/key");
|
||||
|
||||
var aEvent = {
|
||||
shiftKey: modifiers.match("shift"),
|
||||
ctrlKey: modifiers.match("ctrl"),
|
||||
altKey: modifiers.match("alt"),
|
||||
metaKey: modifiers.match("meta"),
|
||||
accelKey: modifiers.match("accel")
|
||||
};
|
||||
|
||||
info("check that the MDN page is opened on \"F1\"");
|
||||
let linkClicked = false;
|
||||
sp.openDocumentationPage = function (event) { linkClicked = true; };
|
||||
|
||||
EventUtils.synthesizeKey(key, aEvent, gScratchpadWindow);
|
||||
|
||||
is(linkClicked, true, "MDN page will open");
|
||||
finishTest();
|
||||
}
|
||||
|
||||
function finishTest()
|
||||
{
|
||||
gScratchpadWindow.close();
|
||||
finish();
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
var DEVTOOLS_CHROME_ENABLED = "devtools.chrome.enabled";
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
Services.prefs.setBoolPref(DEVTOOLS_CHROME_ENABLED, false);
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
|
||||
|
||||
openScratchpad(runTests);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,initialization test for Scratchpad";
|
||||
}
|
||||
|
||||
function runTests()
|
||||
{
|
||||
let sp = gScratchpadWindow.Scratchpad;
|
||||
ok(sp, "Scratchpad object exists in new window");
|
||||
is(typeof sp.run, "function", "Scratchpad.run() exists");
|
||||
is(typeof sp.inspect, "function", "Scratchpad.inspect() exists");
|
||||
is(typeof sp.display, "function", "Scratchpad.display() exists");
|
||||
|
||||
let environmentMenu = gScratchpadWindow.document.
|
||||
getElementById("sp-environment-menu");
|
||||
ok(environmentMenu, "Environment menu element exists");
|
||||
ok(environmentMenu.hasAttribute("hidden"),
|
||||
"Environment menu is not visible");
|
||||
|
||||
let errorConsoleCommand = gScratchpadWindow.document.
|
||||
getElementById("sp-cmd-errorConsole");
|
||||
ok(errorConsoleCommand, "Error console command element exists");
|
||||
is(errorConsoleCommand.getAttribute("disabled"), "true",
|
||||
"Error console command is disabled");
|
||||
|
||||
let chromeContextCommand = gScratchpadWindow.document.
|
||||
getElementById("sp-cmd-browserContext");
|
||||
ok(chromeContextCommand, "Chrome context command element exists");
|
||||
is(chromeContextCommand.getAttribute("disabled"), "true",
|
||||
"Chrome context command is disabled");
|
||||
|
||||
Services.prefs.clearUserPref(DEVTOOLS_CHROME_ENABLED);
|
||||
finish();
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
|
||||
openScratchpad(runTests);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html;charset=utf8,<p>test inspect() in Scratchpad</p>";
|
||||
}
|
||||
|
||||
function runTests()
|
||||
{
|
||||
let sp = gScratchpadWindow.Scratchpad;
|
||||
|
||||
sp.setText("({ a: 'foobarBug636725' })");
|
||||
|
||||
sp.inspect().then(function () {
|
||||
let sidebar = sp.sidebar;
|
||||
ok(sidebar.visible, "sidebar is open");
|
||||
|
||||
|
||||
let found = false;
|
||||
|
||||
outer: for (let scope of sidebar.variablesView) {
|
||||
for (let [, obj] of scope) {
|
||||
for (let [, prop] of obj) {
|
||||
if (prop.name == "a" && prop.value == "foobarBug636725") {
|
||||
found = true;
|
||||
break outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ok(found, "found the property");
|
||||
|
||||
let tabbox = sidebar._sidebar._tabbox;
|
||||
is(tabbox.width, 300, "Scratchpad sidebar width is correct");
|
||||
ok(!tabbox.hasAttribute("hidden"), "Scratchpad sidebar visible");
|
||||
sidebar.hide();
|
||||
ok(tabbox.hasAttribute("hidden"), "Scratchpad sidebar hidden");
|
||||
sp.inspect().then(function () {
|
||||
is(tabbox.width, 300, "Scratchpad sidebar width is still correct");
|
||||
ok(!tabbox.hasAttribute("hidden"), "Scratchpad sidebar visible again");
|
||||
finish();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test that inspecting primitive values uses the object inspector, not an
|
||||
// inline comment.
|
||||
|
||||
var {Task} = require("devtools/shared/task");
|
||||
|
||||
function test() {
|
||||
const options = {
|
||||
tabContent: "test inspecting primitive values"
|
||||
};
|
||||
openTabAndScratchpad(options)
|
||||
.then(Task.async(runTests))
|
||||
.then(finish, console.error);
|
||||
}
|
||||
|
||||
function* runTests([win, sp]) {
|
||||
// Inspect a number.
|
||||
yield checkResults(sp, 7);
|
||||
|
||||
// Inspect a string.
|
||||
yield checkResults(sp, "foobar", true);
|
||||
|
||||
// Inspect a boolean.
|
||||
yield checkResults(sp, true);
|
||||
}
|
||||
|
||||
// Helper function that does the actual testing.
|
||||
var checkResults = Task.async(function* (sp, value, isString = false) {
|
||||
let sourceValue = value;
|
||||
if (isString) {
|
||||
sourceValue = '"' + value + '"';
|
||||
}
|
||||
let source = "var foobar = " + sourceValue + "; foobar";
|
||||
sp.setText(source);
|
||||
yield sp.inspect();
|
||||
|
||||
let sidebar = sp.sidebar;
|
||||
ok(sidebar.visible, "sidebar is open");
|
||||
|
||||
let found = false;
|
||||
|
||||
outer: for (let scope of sidebar.variablesView) {
|
||||
for (let [, obj] of scope) {
|
||||
for (let [, prop] of obj) {
|
||||
if (prop.name == "value" && prop.value == value) {
|
||||
found = true;
|
||||
break outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ok(found, "found the value of " + value);
|
||||
|
||||
let tabbox = sidebar._sidebar._tabbox;
|
||||
ok(!tabbox.hasAttribute("hidden"), "Scratchpad sidebar visible");
|
||||
sidebar.hide();
|
||||
ok(tabbox.hasAttribute("hidden"), "Scratchpad sidebar hidden");
|
||||
});
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
|
||||
openScratchpad(runTests);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html;charset=utf8,<p>test long string in Scratchpad</p>";
|
||||
}
|
||||
|
||||
function runTests()
|
||||
{
|
||||
let sp = gScratchpadWindow.Scratchpad;
|
||||
|
||||
sp.setText("'0'.repeat(10000)");
|
||||
|
||||
sp.display().then(() => {
|
||||
is(sp.getText(), "'0'.repeat(10000)\n" +
|
||||
"/*\n" + "0".repeat(10000) + "\n*/",
|
||||
"display()ing a long string works");
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* Bug 644413 */
|
||||
|
||||
var gScratchpad; // Reference to the Scratchpad object.
|
||||
var gFile; // Reference to the temporary nsIFile we will work with.
|
||||
var DEVTOOLS_CHROME_ENABLED = "devtools.chrome.enabled";
|
||||
|
||||
// The temporary file content.
|
||||
var gFileContent = "function main() { return 0; }";
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
Services.prefs.setBoolPref(DEVTOOLS_CHROME_ENABLED, false);
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
|
||||
openScratchpad(runTests);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,<p>test file open and save in Scratchpad";
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
gScratchpad = gScratchpadWindow.Scratchpad;
|
||||
function size(obj) { return Object.keys(obj).length; }
|
||||
|
||||
// Test Scratchpad._scanModeLine method.
|
||||
let obj = gScratchpad._scanModeLine();
|
||||
is(size(obj), 0, "Mode-line object has no properties");
|
||||
|
||||
obj = gScratchpad._scanModeLine("/* This is not a mode-line comment */");
|
||||
is(size(obj), 0, "Mode-line object has no properties");
|
||||
|
||||
obj = gScratchpad._scanModeLine("/* -sp-context:browser */");
|
||||
is(size(obj), 1, "Mode-line object has one property");
|
||||
is(obj["-sp-context"], "browser");
|
||||
|
||||
obj = gScratchpad._scanModeLine("/* -sp-context: browser */");
|
||||
is(size(obj), 1, "Mode-line object has one property");
|
||||
is(obj["-sp-context"], "browser");
|
||||
|
||||
obj = gScratchpad._scanModeLine("// -sp-context: browser");
|
||||
is(size(obj), 1, "Mode-line object has one property");
|
||||
is(obj["-sp-context"], "browser");
|
||||
|
||||
obj = gScratchpad._scanModeLine("/* -sp-context:browser, other:true */");
|
||||
is(size(obj), 2, "Mode-line object has two properties");
|
||||
is(obj["-sp-context"], "browser");
|
||||
is(obj["other"], "true");
|
||||
|
||||
// Test importing files with a mode-line in them.
|
||||
let content = "/* -sp-context:browser */\n" + gFileContent;
|
||||
createTempFile("fileForBug644413.tmp", content, function (aStatus, aFile) {
|
||||
ok(Components.isSuccessCode(aStatus), "File was saved successfully");
|
||||
|
||||
gFile = aFile;
|
||||
gScratchpad.importFromFile(gFile.QueryInterface(Ci.nsILocalFile), true, fileImported);
|
||||
});
|
||||
}
|
||||
|
||||
function fileImported(status, content) {
|
||||
ok(Components.isSuccessCode(status), "File was imported successfully");
|
||||
|
||||
// Since devtools.chrome.enabled is off, Scratchpad should still be in
|
||||
// the content context.
|
||||
is(gScratchpad.executionContext, gScratchpadWindow.SCRATCHPAD_CONTEXT_CONTENT);
|
||||
|
||||
// Set the pref and try again.
|
||||
Services.prefs.setBoolPref(DEVTOOLS_CHROME_ENABLED, true);
|
||||
|
||||
gScratchpad.importFromFile(gFile.QueryInterface(Ci.nsILocalFile), true, function (status, content) {
|
||||
ok(Components.isSuccessCode(status), "File was imported successfully");
|
||||
is(gScratchpad.executionContext, gScratchpadWindow.SCRATCHPAD_CONTEXT_BROWSER);
|
||||
|
||||
gFile.remove(false);
|
||||
gFile = null;
|
||||
gScratchpad = null;
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
Services.prefs.clearUserPref(DEVTOOLS_CHROME_ENABLED);
|
||||
});
|
||||
101
devtools/client/scratchpad/test/browser_scratchpad_open.js
Normal file
101
devtools/client/scratchpad/test/browser_scratchpad_open.js
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// only finish() when correct number of tests are done
|
||||
const expected = 4;
|
||||
var count = 0;
|
||||
var lastUniqueName = null;
|
||||
|
||||
function done()
|
||||
{
|
||||
if (++count == expected) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
testOpen();
|
||||
testOpenWithState();
|
||||
testOpenInvalidState();
|
||||
testOpenTestFile();
|
||||
}
|
||||
|
||||
function testUniqueName(name)
|
||||
{
|
||||
ok(name, "Scratchpad has a uniqueName");
|
||||
|
||||
if (lastUniqueName === null) {
|
||||
lastUniqueName = name;
|
||||
return;
|
||||
}
|
||||
|
||||
ok(name !== lastUniqueName,
|
||||
"Unique name for this instance differs from the last one.");
|
||||
}
|
||||
|
||||
function testOpen()
|
||||
{
|
||||
openScratchpad(function (win) {
|
||||
is(win.Scratchpad.filename, undefined, "Default filename is undefined");
|
||||
isnot(win.Scratchpad.getText(), null, "Default text should not be null");
|
||||
is(win.Scratchpad.executionContext, win.SCRATCHPAD_CONTEXT_CONTENT,
|
||||
"Default execution context is content");
|
||||
testUniqueName(win.Scratchpad.uniqueName);
|
||||
|
||||
win.close();
|
||||
done();
|
||||
}, {noFocus: true});
|
||||
}
|
||||
|
||||
function testOpenWithState()
|
||||
{
|
||||
let state = {
|
||||
filename: "testfile",
|
||||
executionContext: 2,
|
||||
text: "test text"
|
||||
};
|
||||
|
||||
openScratchpad(function (win) {
|
||||
is(win.Scratchpad.filename, state.filename, "Filename loaded from state");
|
||||
is(win.Scratchpad.executionContext, state.executionContext, "Execution context loaded from state");
|
||||
is(win.Scratchpad.getText(), state.text, "Content loaded from state");
|
||||
testUniqueName(win.Scratchpad.uniqueName);
|
||||
|
||||
win.close();
|
||||
done();
|
||||
}, {state: state, noFocus: true});
|
||||
}
|
||||
|
||||
function testOpenInvalidState()
|
||||
{
|
||||
let win = openScratchpad(null, {state: 7});
|
||||
ok(!win, "no scratchpad opened if state is not an object");
|
||||
done();
|
||||
}
|
||||
|
||||
function testOpenTestFile()
|
||||
{
|
||||
let win = openScratchpad(function (win) {
|
||||
ok(win, "scratchpad opened for file open");
|
||||
try {
|
||||
win.Scratchpad.importFromFile(
|
||||
"http://example.com/browser/devtools/client/scratchpad/test/NS_ERROR_ILLEGAL_INPUT.txt",
|
||||
"silent",
|
||||
function (aStatus, content) {
|
||||
let nb = win.document.querySelector("#scratchpad-notificationbox");
|
||||
is(nb.querySelectorAll("notification").length, 1, "There is just one notification");
|
||||
let cn = nb.currentNotification;
|
||||
is(cn.priority, nb.PRIORITY_WARNING_HIGH, "notification priority is correct");
|
||||
is(cn.value, "file-import-convert-failed", "notification value is corrent");
|
||||
is(cn.type, "warning", "notification type is correct");
|
||||
done();
|
||||
});
|
||||
ok(true, "importFromFile does not cause exception");
|
||||
} catch (exception) {
|
||||
ok(false, "importFromFile causes exception " + DevToolsUtils.safeErrorString(exception));
|
||||
}
|
||||
}, {noFocus: true});
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const HUDService = require("devtools/client/webconsole/hudservice");
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
|
||||
openScratchpad(runTests);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html;charset=utf8,test Scratchpad." +
|
||||
"openErrorConsole()";
|
||||
}
|
||||
|
||||
function runTests()
|
||||
{
|
||||
Services.obs.addObserver(function observer(aSubject) {
|
||||
Services.obs.removeObserver(observer, "web-console-created");
|
||||
aSubject.QueryInterface(Ci.nsISupportsString);
|
||||
|
||||
let hud = HUDService.getBrowserConsole();
|
||||
ok(hud, "browser console is open");
|
||||
is(aSubject.data, hud.hudId, "notification hudId is correct");
|
||||
|
||||
HUDService.toggleBrowserConsole().then(finish);
|
||||
}, "web-console-created", false);
|
||||
|
||||
let hud = HUDService.getBrowserConsole();
|
||||
ok(!hud, "browser console is not open");
|
||||
info("wait for the browser console to open from Scratchpad");
|
||||
|
||||
gScratchpadWindow.Scratchpad.openErrorConsole();
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
|
||||
openScratchpad(runTests);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html;charset=utf8,test Scratchpad pretty print.";
|
||||
}
|
||||
|
||||
var gTabsize;
|
||||
|
||||
function runTests(sw)
|
||||
{
|
||||
gTabsize = Services.prefs.getIntPref("devtools.editor.tabsize");
|
||||
Services.prefs.setIntPref("devtools.editor.tabsize", 6);
|
||||
const space = " ".repeat(6);
|
||||
|
||||
const sp = sw.Scratchpad;
|
||||
sp.setText("function main() { console.log(5); }");
|
||||
sp.prettyPrint().then(() => {
|
||||
const prettyText = sp.getText();
|
||||
ok(prettyText.includes(space));
|
||||
finish();
|
||||
}).then(null, error => {
|
||||
ok(false, error);
|
||||
});
|
||||
}
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
Services.prefs.setIntPref("devtools.editor.tabsize", gTabsize);
|
||||
gTabsize = null;
|
||||
});
|
||||
29
devtools/client/scratchpad/test/browser_scratchpad_pprint.js
Normal file
29
devtools/client/scratchpad/test/browser_scratchpad_pprint.js
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
|
||||
openScratchpad(runTests);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html;charset=utf8,test Scratchpad pretty print.";
|
||||
}
|
||||
|
||||
function runTests(sw)
|
||||
{
|
||||
const sp = sw.Scratchpad;
|
||||
sp.setText("function main() { console.log(5); }");
|
||||
sp.prettyPrint().then(() => {
|
||||
const prettyText = sp.getText();
|
||||
ok(prettyText.includes("\n"));
|
||||
finish();
|
||||
}).then(null, error => {
|
||||
ok(false, error);
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2; fill-column: 80 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
|
||||
openScratchpad(runTests);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html;charset=utf8,"
|
||||
+ "test Scratchpad pretty print error goto line.";
|
||||
}
|
||||
|
||||
function testJumpToPrettyPrintError(sp, error, remark) {
|
||||
info("will test jumpToLine after prettyPrint error" + remark);
|
||||
|
||||
// CodeMirror lines and columns are 0-based, Scratchpad UI and error
|
||||
// stack are 1-based.
|
||||
is(/Invalid regular expression flag \(3:10\)/.test(error), true,
|
||||
"prettyPrint expects error in editor text:\n" + error);
|
||||
|
||||
sp.editor.jumpToLine();
|
||||
|
||||
const editorDoc = sp.editor.container.contentDocument;
|
||||
const lineInput = editorDoc.querySelector("input");
|
||||
const errorLocation = lineInput.value;
|
||||
const [ inputLine, inputColumn ] = errorLocation.split(":");
|
||||
const errorLine = 3, errorColumn = 10;
|
||||
|
||||
is(inputLine, errorLine,
|
||||
"jumpToLine input field is set from editor selection (line)");
|
||||
is(inputColumn, errorColumn,
|
||||
"jumpToLine input field is set from editor selection (column)");
|
||||
|
||||
EventUtils.synthesizeKey("VK_RETURN", { }, editorDoc.defaultView);
|
||||
|
||||
// CodeMirror lines and columns are 0-based, Scratchpad UI and error
|
||||
// stack are 1-based.
|
||||
const cursor = sp.editor.getCursor();
|
||||
is(inputLine, cursor.line + 1, "jumpToLine goto error location (line)");
|
||||
is(inputColumn, cursor.ch + 1, "jumpToLine goto error location (column)");
|
||||
}
|
||||
|
||||
function runTests(sw, sp)
|
||||
{
|
||||
sp.setText([
|
||||
"// line 1",
|
||||
"// line 2",
|
||||
"var re = /a bad /regexp/; // line 3 is an obvious syntax error!",
|
||||
"// line 4",
|
||||
"// line 5",
|
||||
""
|
||||
].join("\n"));
|
||||
|
||||
sp.prettyPrint().then(aFulfill => {
|
||||
ok(false, "Expecting Invalid regexp flag (3:10)");
|
||||
finish();
|
||||
}, error => {
|
||||
testJumpToPrettyPrintError(sp, error, " (Bug 1005471, first time)");
|
||||
});
|
||||
|
||||
sp.prettyPrint().then(aFulfill => {
|
||||
ok(false, "Expecting Invalid regexp flag (3:10)");
|
||||
finish();
|
||||
}, error => {
|
||||
// Second time verifies bug in earlier implementation fixed.
|
||||
testJumpToPrettyPrintError(sp, error, " (second time)");
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,350 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* Bug 651942 */
|
||||
|
||||
// Reference to the Scratchpad object.
|
||||
var gScratchpad;
|
||||
|
||||
// References to the temporary nsIFiles.
|
||||
var gFile01;
|
||||
var gFile02;
|
||||
var gFile03;
|
||||
var gFile04;
|
||||
|
||||
// lists of recent files.
|
||||
var lists = {
|
||||
recentFiles01: null,
|
||||
recentFiles02: null,
|
||||
recentFiles03: null,
|
||||
recentFiles04: null,
|
||||
};
|
||||
|
||||
// Temporary file names.
|
||||
var gFileName01 = "file01_ForBug651942.tmp";
|
||||
var gFileName02 = "☕"; // See bug 783858 for more information
|
||||
var gFileName03 = "file03_ForBug651942.tmp";
|
||||
var gFileName04 = "file04_ForBug651942.tmp";
|
||||
|
||||
// Content for the temporary files.
|
||||
var gFileContent;
|
||||
var gFileContent01 = "hello.world.01('bug651942');";
|
||||
var gFileContent02 = "hello.world.02('bug651942');";
|
||||
var gFileContent03 = "hello.world.03('bug651942');";
|
||||
var gFileContent04 = "hello.world.04('bug651942');";
|
||||
|
||||
function startTest()
|
||||
{
|
||||
gScratchpad = gScratchpadWindow.Scratchpad;
|
||||
|
||||
gFile01 = createAndLoadTemporaryFile(gFile01, gFileName01, gFileContent01);
|
||||
gFile02 = createAndLoadTemporaryFile(gFile02, gFileName02, gFileContent02);
|
||||
gFile03 = createAndLoadTemporaryFile(gFile03, gFileName03, gFileContent03);
|
||||
}
|
||||
|
||||
// Test to see if the three files we created in the 'startTest()'-method have
|
||||
// been added to the list of recent files.
|
||||
function testAddedToRecent()
|
||||
{
|
||||
lists.recentFiles01 = gScratchpad.getRecentFiles();
|
||||
|
||||
is(lists.recentFiles01.length, 3,
|
||||
"Temporary files created successfully and added to list of recent files.");
|
||||
|
||||
// Create a 4th file, this should clear the oldest file.
|
||||
gFile04 = createAndLoadTemporaryFile(gFile04, gFileName04, gFileContent04);
|
||||
}
|
||||
|
||||
// We have opened a 4th file. Test to see if the oldest recent file was removed,
|
||||
// and that the other files were reordered successfully.
|
||||
function testOverwriteRecent()
|
||||
{
|
||||
lists.recentFiles02 = gScratchpad.getRecentFiles();
|
||||
|
||||
is(lists.recentFiles02[0], lists.recentFiles01[1],
|
||||
"File02 was reordered successfully in the 'recent files'-list.");
|
||||
is(lists.recentFiles02[1], lists.recentFiles01[2],
|
||||
"File03 was reordered successfully in the 'recent files'-list.");
|
||||
isnot(lists.recentFiles02[2], lists.recentFiles01[2],
|
||||
"File04: was added successfully.");
|
||||
|
||||
// Open the oldest recent file.
|
||||
gScratchpad.openFile(0);
|
||||
}
|
||||
|
||||
// We have opened the "oldest"-recent file. Test to see if it is now the most
|
||||
// recent file, and that the other files were reordered successfully.
|
||||
function testOpenOldestRecent()
|
||||
{
|
||||
lists.recentFiles03 = gScratchpad.getRecentFiles();
|
||||
|
||||
is(lists.recentFiles02[0], lists.recentFiles03[2],
|
||||
"File04 was reordered successfully in the 'recent files'-list.");
|
||||
is(lists.recentFiles02[1], lists.recentFiles03[0],
|
||||
"File03 was reordered successfully in the 'recent files'-list.");
|
||||
is(lists.recentFiles02[2], lists.recentFiles03[1],
|
||||
"File02 was reordered successfully in the 'recent files'-list.");
|
||||
|
||||
Services.prefs.setIntPref("devtools.scratchpad.recentFilesMax", 0);
|
||||
}
|
||||
|
||||
// The "devtools.scratchpad.recentFilesMax"-preference was set to zero (0).
|
||||
// This should disable the "Open Recent"-menu by hiding it (this should not
|
||||
// remove any files from the list). Test to see if it's been hidden.
|
||||
function testHideMenu()
|
||||
{
|
||||
let menu = gScratchpadWindow.document.getElementById("sp-open_recent-menu");
|
||||
ok(menu.hasAttribute("hidden"), "The menu was hidden successfully.");
|
||||
|
||||
Services.prefs.setIntPref("devtools.scratchpad.recentFilesMax", 2);
|
||||
}
|
||||
|
||||
// We have set the recentFilesMax-pref to one (1), this enables the feature,
|
||||
// removes the two oldest files, rebuilds the menu and removes the
|
||||
// "hidden"-attribute from it. Test to see if this works.
|
||||
function testChangedMaxRecent()
|
||||
{
|
||||
let menu = gScratchpadWindow.document.getElementById("sp-open_recent-menu");
|
||||
ok(!menu.hasAttribute("hidden"), "The menu is visible. \\o/");
|
||||
|
||||
lists.recentFiles04 = gScratchpad.getRecentFiles();
|
||||
|
||||
is(lists.recentFiles04.length, 2,
|
||||
"Two recent files were successfully removed from the 'recent files'-list");
|
||||
|
||||
let doc = gScratchpadWindow.document;
|
||||
let popup = doc.getElementById("sp-menu-open_recentPopup");
|
||||
|
||||
let menuitemLabel = popup.children[0].getAttribute("label");
|
||||
let correctMenuItem = false;
|
||||
if (menuitemLabel === lists.recentFiles03[2] &&
|
||||
menuitemLabel === lists.recentFiles04[1]) {
|
||||
correctMenuItem = true;
|
||||
}
|
||||
|
||||
is(correctMenuItem, true,
|
||||
"Two recent files were successfully removed from the 'Open Recent'-menu");
|
||||
|
||||
// We now remove one file from the harddrive and use the recent-menuitem for
|
||||
// it to make sure the user is notified that the file no longer exists.
|
||||
// This is tested in testOpenDeletedFile().
|
||||
gFile04.remove(false);
|
||||
|
||||
// Make sure the file has been deleted before continuing to avoid
|
||||
// intermittent oranges.
|
||||
waitForFileDeletion();
|
||||
}
|
||||
|
||||
function waitForFileDeletion() {
|
||||
if (gFile04.exists()) {
|
||||
executeSoon(waitForFileDeletion);
|
||||
return;
|
||||
}
|
||||
|
||||
gFile04 = null;
|
||||
gScratchpad.openFile(0);
|
||||
}
|
||||
|
||||
// By now we should have two recent files stored in the list but one of the
|
||||
// files should be missing on the harddrive.
|
||||
function testOpenDeletedFile() {
|
||||
let doc = gScratchpadWindow.document;
|
||||
let popup = doc.getElementById("sp-menu-open_recentPopup");
|
||||
|
||||
is(gScratchpad.getRecentFiles().length, 1,
|
||||
"The missing file was successfully removed from the list.");
|
||||
// The number of recent files stored, plus the separator and the
|
||||
// clearRecentMenuItems-item.
|
||||
is(popup.children.length, 3,
|
||||
"The missing file was successfully removed from the menu.");
|
||||
ok(gScratchpad.notificationBox.currentNotification,
|
||||
"The notification was successfully displayed.");
|
||||
is(gScratchpad.notificationBox.currentNotification.label,
|
||||
gScratchpad.strings.GetStringFromName("fileNoLongerExists.notification"),
|
||||
"The notification label is correct.");
|
||||
|
||||
gScratchpad.clearRecentFiles();
|
||||
}
|
||||
|
||||
// We have cleared the last file. Test to see if the last file was removed,
|
||||
// the menu is empty and was disabled successfully.
|
||||
function testClearedAll()
|
||||
{
|
||||
let doc = gScratchpadWindow.document;
|
||||
let menu = doc.getElementById("sp-open_recent-menu");
|
||||
let popup = doc.getElementById("sp-menu-open_recentPopup");
|
||||
|
||||
is(gScratchpad.getRecentFiles().length, 0,
|
||||
"All recent files removed successfully.");
|
||||
is(popup.children.length, 0, "All menuitems removed successfully.");
|
||||
ok(menu.hasAttribute("disabled"),
|
||||
"No files in the menu, it was disabled successfully.");
|
||||
|
||||
finishTest();
|
||||
}
|
||||
|
||||
function createAndLoadTemporaryFile(aFile, aFileName, aFileContent)
|
||||
{
|
||||
// Create a temporary file.
|
||||
aFile = FileUtils.getFile("TmpD", [aFileName]);
|
||||
aFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
|
||||
|
||||
// Write the temporary file.
|
||||
let fout = Cc["@mozilla.org/network/file-output-stream;1"].
|
||||
createInstance(Ci.nsIFileOutputStream);
|
||||
fout.init(aFile.QueryInterface(Ci.nsILocalFile), 0x02 | 0x08 | 0x20,
|
||||
0o644, fout.DEFER_OPEN);
|
||||
|
||||
gScratchpad.setFilename(aFile.path);
|
||||
gScratchpad.importFromFile(aFile.QueryInterface(Ci.nsILocalFile), true,
|
||||
fileImported);
|
||||
gScratchpad.saveFile(fileSaved);
|
||||
|
||||
return aFile;
|
||||
}
|
||||
|
||||
function fileImported(aStatus)
|
||||
{
|
||||
ok(Components.isSuccessCode(aStatus),
|
||||
"the temporary file was imported successfully with Scratchpad");
|
||||
}
|
||||
|
||||
function fileSaved(aStatus)
|
||||
{
|
||||
ok(Components.isSuccessCode(aStatus),
|
||||
"the temporary file was saved successfully with Scratchpad");
|
||||
|
||||
checkIfMenuIsPopulated();
|
||||
}
|
||||
|
||||
function checkIfMenuIsPopulated()
|
||||
{
|
||||
let doc = gScratchpadWindow.document;
|
||||
let expectedMenuitemCount = doc.getElementById("sp-menu-open_recentPopup").
|
||||
children.length;
|
||||
// The number of recent files stored, plus the separator and the
|
||||
// clearRecentMenuItems-item.
|
||||
let recentFilesPlusExtra = gScratchpad.getRecentFiles().length + 2;
|
||||
|
||||
if (expectedMenuitemCount > 2) {
|
||||
is(expectedMenuitemCount, recentFilesPlusExtra,
|
||||
"the recent files menu was populated successfully.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The PreferenceObserver listens for preference changes while Scratchpad is
|
||||
* running.
|
||||
*/
|
||||
var PreferenceObserver = {
|
||||
_initialized: false,
|
||||
|
||||
_timesFired: 0,
|
||||
set timesFired(aNewValue) {
|
||||
this._timesFired = aNewValue;
|
||||
},
|
||||
get timesFired() {
|
||||
return this._timesFired;
|
||||
},
|
||||
|
||||
init: function PO_init()
|
||||
{
|
||||
if (this._initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.branch = Services.prefs.getBranch("devtools.scratchpad.");
|
||||
this.branch.addObserver("", this, false);
|
||||
this._initialized = true;
|
||||
},
|
||||
|
||||
observe: function PO_observe(aMessage, aTopic, aData)
|
||||
{
|
||||
if (aTopic != "nsPref:changed") {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (this.timesFired) {
|
||||
case 0:
|
||||
this.timesFired = 1;
|
||||
break;
|
||||
case 1:
|
||||
this.timesFired = 2;
|
||||
break;
|
||||
case 2:
|
||||
this.timesFired = 3;
|
||||
testAddedToRecent();
|
||||
break;
|
||||
case 3:
|
||||
this.timesFired = 4;
|
||||
testOverwriteRecent();
|
||||
break;
|
||||
case 4:
|
||||
this.timesFired = 5;
|
||||
testOpenOldestRecent();
|
||||
break;
|
||||
case 5:
|
||||
this.timesFired = 6;
|
||||
testHideMenu();
|
||||
break;
|
||||
case 6:
|
||||
this.timesFired = 7;
|
||||
testChangedMaxRecent();
|
||||
break;
|
||||
case 7:
|
||||
this.timesFired = 8;
|
||||
testOpenDeletedFile();
|
||||
break;
|
||||
case 8:
|
||||
this.timesFired = 9;
|
||||
testClearedAll();
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
uninit: function PO_uninit() {
|
||||
this.branch.removeObserver("", this);
|
||||
}
|
||||
};
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
gFile01.remove(false);
|
||||
gFile01 = null;
|
||||
gFile02.remove(false);
|
||||
gFile02 = null;
|
||||
gFile03.remove(false);
|
||||
gFile03 = null;
|
||||
// gFile04 was removed earlier.
|
||||
lists.recentFiles01 = null;
|
||||
lists.recentFiles02 = null;
|
||||
lists.recentFiles03 = null;
|
||||
lists.recentFiles04 = null;
|
||||
gScratchpad = null;
|
||||
|
||||
PreferenceObserver.uninit();
|
||||
Services.prefs.clearUserPref("devtools.scratchpad.recentFilesMax");
|
||||
});
|
||||
|
||||
Services.prefs.setIntPref("devtools.scratchpad.recentFilesMax", 3);
|
||||
|
||||
// Initiate the preference observer after we have set the temporary recent
|
||||
// files max for this test.
|
||||
PreferenceObserver.init();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
|
||||
openScratchpad(startTest);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,<p>test recent files in Scratchpad";
|
||||
}
|
||||
|
||||
function finishTest()
|
||||
{
|
||||
finish();
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* Bug 740948 */
|
||||
|
||||
var DEVTOOLS_CHROME_ENABLED = "devtools.chrome.enabled";
|
||||
var EDITOR_TEXT = [
|
||||
"var evt = new CustomEvent('foo', { bubbles: true });",
|
||||
"document.body.innerHTML = 'Modified text';",
|
||||
"window.dispatchEvent(evt);"
|
||||
].join("\n");
|
||||
|
||||
function test()
|
||||
{
|
||||
requestLongerTimeout(2);
|
||||
waitForExplicitFinish();
|
||||
Services.prefs.setBoolPref(DEVTOOLS_CHROME_ENABLED, true);
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
|
||||
openScratchpad(runTests);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,Scratchpad test for bug 740948";
|
||||
}
|
||||
|
||||
function runTests()
|
||||
{
|
||||
let sp = gScratchpadWindow.Scratchpad;
|
||||
ok(sp, "Scratchpad object exists in new window");
|
||||
|
||||
// Test that Reload And Run command is enabled in the content
|
||||
// context and disabled in the browser context.
|
||||
|
||||
let reloadAndRun = gScratchpadWindow.document.
|
||||
getElementById("sp-cmd-reloadAndRun");
|
||||
ok(reloadAndRun, "Reload And Run command exists");
|
||||
ok(!reloadAndRun.hasAttribute("disabled"),
|
||||
"Reload And Run command is enabled");
|
||||
|
||||
sp.setBrowserContext();
|
||||
ok(reloadAndRun.hasAttribute("disabled"),
|
||||
"Reload And Run command is disabled in the browser context.");
|
||||
|
||||
// Switch back to the content context and run our predefined
|
||||
// code. This code modifies the body of our document and dispatches
|
||||
// a custom event 'foo'. We listen to that event and check the
|
||||
// body to make sure that the page has been reloaded and Scratchpad
|
||||
// code has been executed.
|
||||
|
||||
sp.setContentContext();
|
||||
sp.setText(EDITOR_TEXT);
|
||||
|
||||
let browser = gBrowser.selectedBrowser;
|
||||
|
||||
let deferred = promise.defer();
|
||||
browser.addEventListener("DOMWindowCreated", function onWindowCreated() {
|
||||
browser.removeEventListener("DOMWindowCreated", onWindowCreated, true);
|
||||
|
||||
browser.contentWindow.addEventListener("foo", function onFoo() {
|
||||
browser.contentWindow.removeEventListener("foo", onFoo, true);
|
||||
|
||||
is(browser.contentWindow.document.body.innerHTML, "Modified text",
|
||||
"After reloading, HTML is different.");
|
||||
|
||||
Services.prefs.clearUserPref(DEVTOOLS_CHROME_ENABLED);
|
||||
deferred.resolve();
|
||||
}, true);
|
||||
}, true);
|
||||
|
||||
ok(browser.contentWindow.document.body.innerHTML !== "Modified text",
|
||||
"Before reloading, HTML is intact.");
|
||||
sp.reloadAndRun().then(deferred.promise).then(finish);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* Bug 1140839 */
|
||||
|
||||
// Test that view menu items are remembered across scratchpad invocations.
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
// To test for this bug we open a Scratchpad window and change all
|
||||
// view menu options. After each change we compare the correspondent
|
||||
// preference value with the expected value.
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
|
||||
openScratchpad(runTests);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,<title>Bug 1140839</title>" +
|
||||
"<p>test Scratchpad should remember View options";
|
||||
}
|
||||
|
||||
function runTests()
|
||||
{
|
||||
let sp = gScratchpadWindow.Scratchpad;
|
||||
let doc = gScratchpadWindow.document;
|
||||
|
||||
let testData = [
|
||||
{itemMenuId: "sp-menu-line-numbers", prefId: "devtools.scratchpad.lineNumbers", expectedVal: false},
|
||||
{itemMenuId: "sp-menu-word-wrap", prefId: "devtools.scratchpad.wrapText", expectedVal: true},
|
||||
{itemMenuId: "sp-menu-highlight-trailing-space", prefId: "devtools.scratchpad.showTrailingSpace", expectedVal: true},
|
||||
{itemMenuId: "sp-menu-larger-font", prefId: "devtools.scratchpad.editorFontSize", expectedVal: 13},
|
||||
{itemMenuId: "sp-menu-normal-size-font", prefId: "devtools.scratchpad.editorFontSize", expectedVal: 12},
|
||||
{itemMenuId: "sp-menu-smaller-font", prefId: "devtools.scratchpad.editorFontSize", expectedVal: 11},
|
||||
];
|
||||
|
||||
testData.forEach(function (data) {
|
||||
let getPref = getPrefFunction(data.prefId);
|
||||
|
||||
try {
|
||||
let menu = doc.getElementById(data.itemMenuId);
|
||||
menu.doCommand();
|
||||
let newPreferenceValue = getPref(data.prefId);
|
||||
ok(newPreferenceValue === data.expectedVal, newPreferenceValue + " !== " + data.expectedVal);
|
||||
Services.prefs.clearUserPref(data.prefId);
|
||||
}
|
||||
catch (exception) {
|
||||
ok(false, "Exception thrown while executing the command of menuitem #" + data.itemMenuId);
|
||||
}
|
||||
});
|
||||
|
||||
finish();
|
||||
}
|
||||
|
||||
function getPrefFunction(preferenceId)
|
||||
{
|
||||
let preferenceType = Services.prefs.getPrefType(preferenceId);
|
||||
if (preferenceType === Services.prefs.PREF_INT) {
|
||||
return Services.prefs.getIntPref;
|
||||
} else if (preferenceType === Services.prefs.PREF_BOOL) {
|
||||
return Services.prefs.getBoolPref;
|
||||
}
|
||||
}
|
||||
155
devtools/client/scratchpad/test/browser_scratchpad_reset_undo.js
Normal file
155
devtools/client/scratchpad/test/browser_scratchpad_reset_undo.js
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* Bug 684546 */
|
||||
|
||||
// Reference to the Scratchpad chrome window object.
|
||||
var gScratchpadWindow;
|
||||
|
||||
// Reference to the Scratchpad object.
|
||||
var gScratchpad;
|
||||
|
||||
// Reference to the temporary nsIFile we will work with.
|
||||
var gFileA;
|
||||
var gFileB;
|
||||
|
||||
// The temporary file content.
|
||||
var gFileAContent = "// File A ** Hello World!";
|
||||
var gFileBContent = "// File B ** Goodbye All";
|
||||
|
||||
// Help track if one or both files are saved
|
||||
var gFirstFileSaved = false;
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function browserLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", browserLoad, true);
|
||||
openScratchpad(runTests);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,<p>test that undo get's reset after file load in Scratchpad";
|
||||
}
|
||||
|
||||
function runTests()
|
||||
{
|
||||
gScratchpad = gScratchpadWindow.Scratchpad;
|
||||
|
||||
// Create a temporary file.
|
||||
gFileA = FileUtils.getFile("TmpD", ["fileAForBug684546.tmp"]);
|
||||
gFileA.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
|
||||
|
||||
gFileB = FileUtils.getFile("TmpD", ["fileBForBug684546.tmp"]);
|
||||
gFileB.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
|
||||
|
||||
// Write the temporary file.
|
||||
let foutA = Cc["@mozilla.org/network/file-output-stream;1"].
|
||||
createInstance(Ci.nsIFileOutputStream);
|
||||
foutA.init(gFileA.QueryInterface(Ci.nsILocalFile), 0x02 | 0x08 | 0x20,
|
||||
0o644, foutA.DEFER_OPEN);
|
||||
|
||||
let foutB = Cc["@mozilla.org/network/file-output-stream;1"].
|
||||
createInstance(Ci.nsIFileOutputStream);
|
||||
foutB.init(gFileB.QueryInterface(Ci.nsILocalFile), 0x02 | 0x08 | 0x20,
|
||||
0o644, foutB.DEFER_OPEN);
|
||||
|
||||
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
|
||||
createInstance(Ci.nsIScriptableUnicodeConverter);
|
||||
converter.charset = "UTF-8";
|
||||
let fileContentStreamA = converter.convertToInputStream(gFileAContent);
|
||||
let fileContentStreamB = converter.convertToInputStream(gFileBContent);
|
||||
|
||||
NetUtil.asyncCopy(fileContentStreamA, foutA, tempFileSaved);
|
||||
NetUtil.asyncCopy(fileContentStreamB, foutB, tempFileSaved);
|
||||
}
|
||||
|
||||
function tempFileSaved(aStatus)
|
||||
{
|
||||
let success = Components.isSuccessCode(aStatus);
|
||||
|
||||
ok(success, "a temporary file was saved successfully");
|
||||
|
||||
if (!success)
|
||||
{
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
if (gFirstFileSaved && success)
|
||||
{
|
||||
ok((gFirstFileSaved && success), "Both files loaded");
|
||||
// Import the file A into Scratchpad.
|
||||
gScratchpad.importFromFile(gFileA.QueryInterface(Ci.nsILocalFile), true,
|
||||
fileAImported);
|
||||
}
|
||||
gFirstFileSaved = success;
|
||||
}
|
||||
|
||||
function fileAImported(aStatus, aFileContent)
|
||||
{
|
||||
ok(Components.isSuccessCode(aStatus),
|
||||
"the temporary file A was imported successfully with Scratchpad");
|
||||
|
||||
is(aFileContent, gFileAContent, "received data is correct");
|
||||
|
||||
is(gScratchpad.getText(), gFileAContent, "the editor content is correct");
|
||||
|
||||
gScratchpad.editor.replaceText("new text",
|
||||
gScratchpad.editor.getPosition(gScratchpad.getText().length));
|
||||
|
||||
is(gScratchpad.getText(), gFileAContent + "new text", "text updated correctly");
|
||||
gScratchpad.undo();
|
||||
is(gScratchpad.getText(), gFileAContent, "undo works");
|
||||
gScratchpad.redo();
|
||||
is(gScratchpad.getText(), gFileAContent + "new text", "redo works");
|
||||
|
||||
// Import the file B into Scratchpad.
|
||||
gScratchpad.importFromFile(gFileB.QueryInterface(Ci.nsILocalFile), true,
|
||||
fileBImported);
|
||||
}
|
||||
|
||||
function fileBImported(aStatus, aFileContent)
|
||||
{
|
||||
ok(Components.isSuccessCode(aStatus),
|
||||
"the temporary file B was imported successfully with Scratchpad");
|
||||
|
||||
is(aFileContent, gFileBContent, "received data is correct");
|
||||
|
||||
is(gScratchpad.getText(), gFileBContent, "the editor content is correct");
|
||||
|
||||
ok(!gScratchpad.editor.canUndo(), "editor cannot undo after load");
|
||||
|
||||
gScratchpad.undo();
|
||||
is(gScratchpad.getText(), gFileBContent,
|
||||
"the editor content is still correct after undo");
|
||||
|
||||
gScratchpad.editor.replaceText("new text",
|
||||
gScratchpad.editor.getPosition(gScratchpad.getText().length));
|
||||
is(gScratchpad.getText(), gFileBContent + "new text", "text updated correctly");
|
||||
|
||||
gScratchpad.undo();
|
||||
is(gScratchpad.getText(), gFileBContent, "undo works");
|
||||
ok(!gScratchpad.editor.canUndo(), "editor cannot undo after load (again)");
|
||||
|
||||
gScratchpad.redo();
|
||||
is(gScratchpad.getText(), gFileBContent + "new text", "redo works");
|
||||
|
||||
// Done!
|
||||
finish();
|
||||
}
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
if (gFileA && gFileA.exists())
|
||||
{
|
||||
gFileA.remove(false);
|
||||
gFileA = null;
|
||||
}
|
||||
if (gFileB && gFileB.exists())
|
||||
{
|
||||
gFileB.remove(false);
|
||||
gFileB = null;
|
||||
}
|
||||
gScratchpad = null;
|
||||
});
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/* Call the iterator for each item in the list,
|
||||
calling the final callback with all the results
|
||||
after every iterator call has sent its result */
|
||||
function asyncMap(items, iterator, callback)
|
||||
{
|
||||
let expected = items.length;
|
||||
let results = [];
|
||||
|
||||
items.forEach(function (item) {
|
||||
iterator(item, function (result) {
|
||||
results.push(result);
|
||||
if (results.length == expected) {
|
||||
callback(results);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
testRestore();
|
||||
}
|
||||
|
||||
function testRestore()
|
||||
{
|
||||
let states = [
|
||||
{
|
||||
filename: "testfile",
|
||||
text: "test1",
|
||||
executionContext: 2
|
||||
},
|
||||
{
|
||||
text: "text2",
|
||||
executionContext: 1
|
||||
},
|
||||
{
|
||||
text: "text3",
|
||||
executionContext: 1
|
||||
}
|
||||
];
|
||||
|
||||
asyncMap(states, function (state, done) {
|
||||
// Open some scratchpad windows
|
||||
openScratchpad(done, {state: state, noFocus: true});
|
||||
}, function (wins) {
|
||||
// Then save the windows to session store
|
||||
ScratchpadManager.saveOpenWindows();
|
||||
|
||||
// Then get their states
|
||||
let session = ScratchpadManager.getSessionState();
|
||||
|
||||
// Then close them
|
||||
wins.forEach(function (win) {
|
||||
win.close();
|
||||
});
|
||||
|
||||
// Clear out session state for next tests
|
||||
ScratchpadManager.saveOpenWindows();
|
||||
|
||||
// Then restore them
|
||||
let restoredWins = ScratchpadManager.restoreSession(session);
|
||||
|
||||
is(restoredWins.length, 3, "Three scratchad windows restored");
|
||||
|
||||
asyncMap(restoredWins, function (restoredWin, done) {
|
||||
openScratchpad(function (aWin) {
|
||||
let state = aWin.Scratchpad.getState();
|
||||
aWin.close();
|
||||
done(state);
|
||||
}, {window: restoredWin, noFocus: true});
|
||||
}, function (restoredStates) {
|
||||
// Then make sure they were restored with the right states
|
||||
ok(statesMatch(restoredStates, states),
|
||||
"All scratchpad window states restored correctly");
|
||||
|
||||
// Yay, we're done!
|
||||
finish();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function statesMatch(restoredStates, states)
|
||||
{
|
||||
return states.every(function (state) {
|
||||
return restoredStates.some(function (restoredState) {
|
||||
return state.filename == restoredState.filename
|
||||
&& state.text == restoredState.text
|
||||
&& state.executionContext == restoredState.executionContext;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* Bug 751744 */
|
||||
|
||||
// Reference to the Scratchpad object.
|
||||
var gScratchpad;
|
||||
|
||||
// Reference to the temporary nsIFiles.
|
||||
var gFile;
|
||||
|
||||
// Temporary file name.
|
||||
var gFileName = "testFileForBug751744.tmp";
|
||||
|
||||
|
||||
// Content for the temporary file.
|
||||
var gFileContent = "/* this file is already saved */\n" +
|
||||
"function foo() { alert('bar') }";
|
||||
var gLength = gFileContent.length;
|
||||
|
||||
// Reference to the menu entry.
|
||||
var menu;
|
||||
|
||||
function startTest()
|
||||
{
|
||||
gScratchpad = gScratchpadWindow.Scratchpad;
|
||||
menu = gScratchpadWindow.document.getElementById("sp-cmd-revert");
|
||||
createAndLoadTemporaryFile();
|
||||
}
|
||||
|
||||
function testAfterSaved() {
|
||||
// Check if the revert menu is disabled as the file is at saved state.
|
||||
ok(menu.hasAttribute("disabled"), "The revert menu entry is disabled.");
|
||||
|
||||
// chancging the text in the file
|
||||
gScratchpad.setText(gScratchpad.getText() + "\nfoo();");
|
||||
// Checking the text got changed
|
||||
is(gScratchpad.getText(), gFileContent + "\nfoo();",
|
||||
"The text changed the first time.");
|
||||
|
||||
// Revert menu now should be enabled.
|
||||
ok(!menu.hasAttribute("disabled"),
|
||||
"The revert menu entry is enabled after changing text first time");
|
||||
|
||||
// reverting back to last saved state.
|
||||
gScratchpad.revertFile(testAfterRevert);
|
||||
}
|
||||
|
||||
function testAfterRevert() {
|
||||
// Check if the file's text got reverted
|
||||
is(gScratchpad.getText(), gFileContent,
|
||||
"The text reverted back to original text.");
|
||||
// The revert menu should be disabled again.
|
||||
ok(menu.hasAttribute("disabled"),
|
||||
"The revert menu entry is disabled after reverting.");
|
||||
|
||||
// chancging the text in the file again
|
||||
gScratchpad.setText(gScratchpad.getText() + "\nalert(foo.toSource());");
|
||||
// Saving the file.
|
||||
gScratchpad.saveFile(testAfterSecondSave);
|
||||
}
|
||||
|
||||
function testAfterSecondSave() {
|
||||
// revert menu entry should be disabled.
|
||||
ok(menu.hasAttribute("disabled"),
|
||||
"The revert menu entry is disabled after saving.");
|
||||
|
||||
// changing the text.
|
||||
gScratchpad.setText(gScratchpad.getText() + "\nfoo();");
|
||||
|
||||
// revert menu entry should get enabled yet again.
|
||||
ok(!menu.hasAttribute("disabled"),
|
||||
"The revert menu entry is enabled after changing text third time");
|
||||
|
||||
// reverting back to last saved state.
|
||||
gScratchpad.revertFile(testAfterSecondRevert);
|
||||
}
|
||||
|
||||
function testAfterSecondRevert() {
|
||||
// Check if the file's text got reverted
|
||||
is(gScratchpad.getText(), gFileContent + "\nalert(foo.toSource());",
|
||||
"The text reverted back to the changed saved text.");
|
||||
// The revert menu should be disabled again.
|
||||
ok(menu.hasAttribute("disabled"),
|
||||
"Revert menu entry is disabled after reverting to changed saved state.");
|
||||
gFile.remove(false);
|
||||
gFile = gScratchpad = menu = null;
|
||||
finish();
|
||||
}
|
||||
|
||||
function createAndLoadTemporaryFile()
|
||||
{
|
||||
// Create a temporary file.
|
||||
gFile = FileUtils.getFile("TmpD", [gFileName]);
|
||||
gFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
|
||||
|
||||
// Write the temporary file.
|
||||
let fout = Cc["@mozilla.org/network/file-output-stream;1"].
|
||||
createInstance(Ci.nsIFileOutputStream);
|
||||
fout.init(gFile.QueryInterface(Ci.nsILocalFile), 0x02 | 0x08 | 0x20,
|
||||
0o644, fout.DEFER_OPEN);
|
||||
|
||||
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
|
||||
createInstance(Ci.nsIScriptableUnicodeConverter);
|
||||
converter.charset = "UTF-8";
|
||||
let fileContentStream = converter.convertToInputStream(gFileContent);
|
||||
|
||||
NetUtil.asyncCopy(fileContentStream, fout, tempFileSaved);
|
||||
}
|
||||
|
||||
function tempFileSaved(aStatus)
|
||||
{
|
||||
ok(Components.isSuccessCode(aStatus),
|
||||
"the temporary file was saved successfully");
|
||||
|
||||
// Import the file into Scratchpad.
|
||||
gScratchpad.setFilename(gFile.path);
|
||||
gScratchpad.importFromFile(gFile.QueryInterface(Ci.nsILocalFile), true,
|
||||
testAfterSaved);
|
||||
}
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
|
||||
openScratchpad(startTest);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,<p>test reverting to last saved state of" +
|
||||
" a file </p>";
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2; fill-column: 80 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
|
||||
openScratchpad(runTests);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html;charset=utf8,test Scratchpad pretty print.";
|
||||
}
|
||||
|
||||
function runTests(sw)
|
||||
{
|
||||
const sp = sw.Scratchpad;
|
||||
sp.setText([
|
||||
"// line 1",
|
||||
"// line 2",
|
||||
"var re = /a bad /regexp/; // line 3 is an obvious syntax error!",
|
||||
"// line 4",
|
||||
"// line 5",
|
||||
""
|
||||
].join("\n"));
|
||||
sp.run().then(() => {
|
||||
// CodeMirror lines and columns are 0-based, Scratchpad UI and error
|
||||
// stack are 1-based.
|
||||
let errorLine = 3;
|
||||
let editorDoc = sp.editor.container.contentDocument;
|
||||
sp.editor.jumpToLine();
|
||||
let lineInput = editorDoc.querySelector("input");
|
||||
let inputLine = lineInput.value;
|
||||
is(inputLine, errorLine, "jumpToLine input field is set from editor selection");
|
||||
EventUtils.synthesizeKey("VK_RETURN", { }, editorDoc.defaultView);
|
||||
// CodeMirror lines and columns are 0-based, Scratchpad UI and error
|
||||
// stack are 1-based.
|
||||
let cursor = sp.editor.getCursor();
|
||||
is(cursor.line + 1, inputLine, "jumpToLine goto error location (line)");
|
||||
is(cursor.ch + 1, 1, "jumpToLine goto error location (column)");
|
||||
}, error => {
|
||||
ok(false, error);
|
||||
finish();
|
||||
}).then(() => {
|
||||
var statusBarField = sp.editor.container.ownerDocument.querySelector("#statusbar-line-col");
|
||||
let { line, ch } = sp.editor.getCursor();
|
||||
is(statusBarField.textContent, sp.strings.formatStringFromName(
|
||||
"scratchpad.statusBarLineCol", [ line + 1, ch + 1], 2), "statusbar text is correct (" + statusBarField.textContent + ")");
|
||||
finish();
|
||||
}, error => {
|
||||
ok(false, error);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
75
devtools/client/scratchpad/test/browser_scratchpad_tab.js
Normal file
75
devtools/client/scratchpad/test/browser_scratchpad_tab.js
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* Bug 660560 */
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onTabLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onTabLoad, true);
|
||||
|
||||
Services.prefs.setIntPref("devtools.editor.tabsize", 5);
|
||||
|
||||
openScratchpad(runTests);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,Scratchpad test for the Tab key, bug 660560";
|
||||
}
|
||||
|
||||
function runTests()
|
||||
{
|
||||
let sp = gScratchpadWindow.Scratchpad;
|
||||
ok(sp, "Scratchpad object exists in new window");
|
||||
|
||||
ok(sp.editor.hasFocus(), "the editor has focus");
|
||||
|
||||
sp.setText("window.foo;");
|
||||
sp.editor.setCursor({ line: 0, ch: 0 });
|
||||
|
||||
EventUtils.synthesizeKey("VK_TAB", {}, gScratchpadWindow);
|
||||
|
||||
is(sp.getText(), " window.foo;", "Tab key added 5 spaces");
|
||||
|
||||
is(sp.editor.getCursor().line, 0, "line is correct");
|
||||
is(sp.editor.getCursor().ch, 5, "character is correct");
|
||||
|
||||
sp.editor.setCursor({ line: 0, ch: 6 });
|
||||
|
||||
EventUtils.synthesizeKey("VK_TAB", {}, gScratchpadWindow);
|
||||
|
||||
is(sp.getText(), " w indow.foo;",
|
||||
"Tab key added 4 spaces");
|
||||
|
||||
is(sp.editor.getCursor().line, 0, "line is correct");
|
||||
is(sp.editor.getCursor().ch, 10, "character is correct");
|
||||
|
||||
gScratchpadWindow.close();
|
||||
|
||||
Services.prefs.setIntPref("devtools.editor.tabsize", 6);
|
||||
Services.prefs.setBoolPref("devtools.editor.expandtab", false);
|
||||
|
||||
openScratchpad(runTests2);
|
||||
}
|
||||
|
||||
function runTests2()
|
||||
{
|
||||
let sp = gScratchpadWindow.Scratchpad;
|
||||
|
||||
sp.setText("window.foo;");
|
||||
sp.editor.setCursor({ line: 0, ch: 0 });
|
||||
|
||||
EventUtils.synthesizeKey("VK_TAB", {}, gScratchpadWindow);
|
||||
|
||||
is(sp.getText(), "\twindow.foo;", "Tab key added the tab character");
|
||||
|
||||
is(sp.editor.getCursor().line, 0, "line is correct");
|
||||
is(sp.editor.getCursor().ch, 1, "character is correct");
|
||||
|
||||
Services.prefs.clearUserPref("devtools.editor.tabsize");
|
||||
Services.prefs.clearUserPref("devtools.editor.expandtab");
|
||||
|
||||
finish();
|
||||
}
|
||||
103
devtools/client/scratchpad/test/browser_scratchpad_tab_switch.js
Normal file
103
devtools/client/scratchpad/test/browser_scratchpad_tab_switch.js
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
var tab1;
|
||||
var tab2;
|
||||
var sp;
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
tab1 = gBrowser.addTab();
|
||||
gBrowser.selectedTab = tab1;
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad1() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onLoad1, true);
|
||||
|
||||
tab2 = gBrowser.addTab();
|
||||
gBrowser.selectedTab = tab2;
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad2() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onLoad2, true);
|
||||
openScratchpad(runTests);
|
||||
}, true);
|
||||
content.location = "data:text/html,test context switch in Scratchpad tab 2";
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,test context switch in Scratchpad tab 1";
|
||||
}
|
||||
|
||||
function runTests()
|
||||
{
|
||||
sp = gScratchpadWindow.Scratchpad;
|
||||
|
||||
let contentMenu = gScratchpadWindow.document.getElementById("sp-menu-content");
|
||||
let browserMenu = gScratchpadWindow.document.getElementById("sp-menu-browser");
|
||||
let notificationBox = sp.notificationBox;
|
||||
|
||||
ok(contentMenu, "found #sp-menu-content");
|
||||
ok(browserMenu, "found #sp-menu-browser");
|
||||
ok(notificationBox, "found Scratchpad.notificationBox");
|
||||
|
||||
sp.setContentContext();
|
||||
|
||||
is(sp.executionContext, gScratchpadWindow.SCRATCHPAD_CONTEXT_CONTENT,
|
||||
"executionContext is content");
|
||||
|
||||
is(contentMenu.getAttribute("checked"), "true",
|
||||
"content menuitem is checked");
|
||||
|
||||
isnot(browserMenu.getAttribute("checked"), "true",
|
||||
"chrome menuitem is not checked");
|
||||
|
||||
is(notificationBox.currentNotification, null,
|
||||
"there is no notification currently shown for content context");
|
||||
|
||||
sp.setText("window.foosbug653108 = 'aloha';");
|
||||
|
||||
ok(!content.wrappedJSObject.foosbug653108,
|
||||
"no content.foosbug653108");
|
||||
|
||||
sp.run().then(function () {
|
||||
is(content.wrappedJSObject.foosbug653108, "aloha",
|
||||
"content.foosbug653108 has been set");
|
||||
|
||||
gBrowser.tabContainer.addEventListener("TabSelect", runTests2, true);
|
||||
gBrowser.selectedTab = tab1;
|
||||
});
|
||||
}
|
||||
|
||||
function runTests2() {
|
||||
gBrowser.tabContainer.removeEventListener("TabSelect", runTests2, true);
|
||||
|
||||
ok(!window.foosbug653108, "no window.foosbug653108");
|
||||
|
||||
sp.setText("window.foosbug653108");
|
||||
sp.run().then(function ([, , result]) {
|
||||
isnot(result, "aloha", "window.foosbug653108 is not aloha");
|
||||
|
||||
sp.setText("window.foosbug653108 = 'ahoyhoy';");
|
||||
sp.run().then(function () {
|
||||
is(content.wrappedJSObject.foosbug653108, "ahoyhoy",
|
||||
"content.foosbug653108 has been set 2");
|
||||
|
||||
gBrowser.selectedBrowser.addEventListener("load", runTests3, true);
|
||||
content.location = "data:text/html,test context switch in Scratchpad location 2";
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function runTests3() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", runTests3, true);
|
||||
// Check that the sandbox is not cached.
|
||||
|
||||
sp.setText("typeof foosbug653108;");
|
||||
sp.run().then(function ([, , result]) {
|
||||
is(result, "undefined", "global variable does not exist");
|
||||
|
||||
tab1 = null;
|
||||
tab2 = null;
|
||||
sp = null;
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
|
||||
openScratchpad(testThrowOutput);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html;charset=utf8,<p>Test throw outputs in Scratchpad</p>";
|
||||
}
|
||||
|
||||
function testThrowOutput()
|
||||
{
|
||||
let scratchpad = gScratchpadWindow.Scratchpad, tests = [];
|
||||
|
||||
let falsyValues = ["false", "0", "-0", "null", "undefined", "Infinity",
|
||||
"-Infinity", "NaN"];
|
||||
falsyValues.forEach(function (value) {
|
||||
tests.push({
|
||||
method: "display",
|
||||
code: "throw " + value + ";",
|
||||
result: "throw " + value + ";\n/*\nException: " + value + "\n*/",
|
||||
label: "Correct exception message for '" + value + "' is shown"
|
||||
});
|
||||
});
|
||||
|
||||
let { DebuggerServer } = require("devtools/server/main");
|
||||
|
||||
let longLength = DebuggerServer.LONG_STRING_LENGTH + 1;
|
||||
let longString = new Array(longLength).join("a");
|
||||
let shortedString = longString.substring(0,
|
||||
DebuggerServer.LONG_STRING_INITIAL_LENGTH) + "\u2026";
|
||||
|
||||
tests.push({
|
||||
method: "display",
|
||||
code: "throw (new Array(" + longLength + ").join('a'));",
|
||||
result: "throw (new Array(" + longLength + ").join('a'));\n" +
|
||||
"/*\nException: " + shortedString + "\n*/",
|
||||
label: "Correct exception message for a longString is shown"
|
||||
});
|
||||
|
||||
runAsyncTests(scratchpad, tests).then(function () {
|
||||
finish();
|
||||
});
|
||||
}
|
||||
74
devtools/client/scratchpad/test/browser_scratchpad_ui.js
Normal file
74
devtools/client/scratchpad/test/browser_scratchpad_ui.js
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
|
||||
openScratchpad(runTests);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,<title>foobarBug636725</title>" +
|
||||
"<p>test inspect() in Scratchpad";
|
||||
}
|
||||
|
||||
function runTests()
|
||||
{
|
||||
let sp = gScratchpadWindow.Scratchpad;
|
||||
let doc = gScratchpadWindow.document;
|
||||
|
||||
let methodsAndItems = {
|
||||
"sp-menu-newscratchpad": "openScratchpad",
|
||||
"sp-menu-open": "openFile",
|
||||
"sp-menu-save": "saveFile",
|
||||
"sp-menu-saveas": "saveFileAs",
|
||||
"sp-text-run": "run",
|
||||
"sp-text-inspect": "inspect",
|
||||
"sp-text-display": "display",
|
||||
"sp-text-reloadAndRun": "reloadAndRun",
|
||||
"sp-menu-content": "setContentContext",
|
||||
"sp-menu-browser": "setBrowserContext",
|
||||
"sp-menu-pprint": "prettyPrint",
|
||||
"sp-menu-line-numbers": "toggleEditorOption",
|
||||
"sp-menu-word-wrap": "toggleEditorOption",
|
||||
"sp-menu-highlight-trailing-space": "toggleEditorOption",
|
||||
"sp-menu-larger-font": "increaseFontSize",
|
||||
"sp-menu-smaller-font": "decreaseFontSize",
|
||||
"sp-menu-normal-size-font": "normalFontSize",
|
||||
};
|
||||
|
||||
let lastMethodCalled = null;
|
||||
|
||||
for (let id in methodsAndItems) {
|
||||
lastMethodCalled = null;
|
||||
|
||||
let methodName = methodsAndItems[id];
|
||||
let oldMethod = sp[methodName];
|
||||
ok(oldMethod, "found method " + methodName + " in Scratchpad object");
|
||||
|
||||
sp[methodName] = () => {
|
||||
lastMethodCalled = methodName;
|
||||
};
|
||||
|
||||
let menu = doc.getElementById(id);
|
||||
ok(menu, "found menuitem #" + id);
|
||||
|
||||
try {
|
||||
menu.doCommand();
|
||||
}
|
||||
catch (ex) {
|
||||
ok(false, "exception thrown while executing the command of menuitem #" + id);
|
||||
}
|
||||
|
||||
ok(lastMethodCalled == methodName,
|
||||
"method " + methodName + " invoked by the associated menuitem");
|
||||
|
||||
sp[methodName] = oldMethod;
|
||||
}
|
||||
|
||||
finish();
|
||||
}
|
||||
119
devtools/client/scratchpad/test/browser_scratchpad_unsaved.js
Normal file
119
devtools/client/scratchpad/test/browser_scratchpad_unsaved.js
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* Bug 669612 */
|
||||
|
||||
// only finish() when correct number of tests are done
|
||||
const expected = 4;
|
||||
var count = 0;
|
||||
function done()
|
||||
{
|
||||
if (++count == expected) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
testListeners();
|
||||
testRestoreNotFromFile();
|
||||
testRestoreFromFileSaved();
|
||||
testRestoreFromFileUnsaved();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
content.location = "data:text/html,<p>test star* UI for unsaved file changes";
|
||||
}
|
||||
|
||||
function testListeners()
|
||||
{
|
||||
openScratchpad(function (aWin, aScratchpad) {
|
||||
aScratchpad.setText("new text");
|
||||
ok(isStar(aWin), "show star if scratchpad text changes");
|
||||
|
||||
aScratchpad.dirty = false;
|
||||
ok(!isStar(aWin), "no star before changing text");
|
||||
|
||||
aScratchpad.setFilename("foo.js");
|
||||
aScratchpad.setText("new text2");
|
||||
ok(isStar(aWin), "shows star if scratchpad text changes");
|
||||
|
||||
aScratchpad.dirty = false;
|
||||
ok(!isStar(aWin), "no star if scratchpad was just saved");
|
||||
|
||||
aScratchpad.setText("new text3");
|
||||
ok(isStar(aWin), "shows star if scratchpad has more changes");
|
||||
|
||||
aScratchpad.undo();
|
||||
ok(!isStar(aWin), "no star if scratchpad undo to save point");
|
||||
|
||||
aScratchpad.undo();
|
||||
ok(isStar(aWin), "star if scratchpad undo past save point");
|
||||
|
||||
aWin.close();
|
||||
done();
|
||||
}, {noFocus: true});
|
||||
}
|
||||
|
||||
function testRestoreNotFromFile()
|
||||
{
|
||||
let session = [{
|
||||
text: "test1",
|
||||
executionContext: 1
|
||||
}];
|
||||
|
||||
let [win] = ScratchpadManager.restoreSession(session);
|
||||
openScratchpad(function (aWin, aScratchpad) {
|
||||
aScratchpad.setText("new text");
|
||||
ok(isStar(win), "show star if restored scratchpad isn't from a file");
|
||||
|
||||
win.close();
|
||||
done();
|
||||
}, {window: win, noFocus: true});
|
||||
}
|
||||
|
||||
function testRestoreFromFileSaved()
|
||||
{
|
||||
let session = [{
|
||||
filename: "test.js",
|
||||
text: "test1",
|
||||
executionContext: 1,
|
||||
saved: true
|
||||
}];
|
||||
|
||||
let [win] = ScratchpadManager.restoreSession(session);
|
||||
openScratchpad(function (aWin, aScratchpad) {
|
||||
ok(!isStar(win), "no star before changing text in scratchpad restored from file");
|
||||
|
||||
aScratchpad.setText("new text");
|
||||
ok(isStar(win), "star when text changed from scratchpad restored from file");
|
||||
|
||||
win.close();
|
||||
done();
|
||||
}, {window: win, noFocus: true});
|
||||
}
|
||||
|
||||
function testRestoreFromFileUnsaved()
|
||||
{
|
||||
let session = [{
|
||||
filename: "test.js",
|
||||
text: "test1",
|
||||
executionContext: 1,
|
||||
saved: false
|
||||
}];
|
||||
|
||||
let [win] = ScratchpadManager.restoreSession(session);
|
||||
openScratchpad(function () {
|
||||
ok(isStar(win), "star with scratchpad restored with unsaved text");
|
||||
|
||||
win.close();
|
||||
done();
|
||||
}, {window: win, noFocus: true});
|
||||
}
|
||||
|
||||
function isStar(win)
|
||||
{
|
||||
return win.document.title.match(/^\*[^\*]/);
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* Bug 661762 */
|
||||
|
||||
// Use the old webconsole since scratchpad focus isn't working on new one (Bug 1304794)
|
||||
Services.prefs.setBoolPref("devtools.webconsole.new-frontend-enabled", false);
|
||||
registerCleanupFunction(function* () {
|
||||
Services.prefs.clearUserPref("devtools.webconsole.new-frontend-enabled");
|
||||
});
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
// To test for this bug we open a Scratchpad window, save its
|
||||
// reference and then open another one. This way the first window
|
||||
// loses its focus.
|
||||
//
|
||||
// Then we open a web console and execute a console.log statement
|
||||
// from the first Scratch window (that's why we needed to save its
|
||||
// reference).
|
||||
//
|
||||
// Then we wait for our message to appear in the console and click
|
||||
// on the location link. After that we check which Scratchpad window
|
||||
// is currently active (it should be the older one).
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
|
||||
|
||||
openScratchpad(function () {
|
||||
let sw = gScratchpadWindow;
|
||||
let {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
let {TargetFactory} = require("devtools/client/framework/target");
|
||||
|
||||
openScratchpad(function () {
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
gDevTools.showToolbox(target, "webconsole").then((toolbox) => {
|
||||
let hud = toolbox.getCurrentPanel().hud;
|
||||
hud.jsterm.clearOutput(true);
|
||||
testFocus(sw, hud);
|
||||
});
|
||||
});
|
||||
});
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html;charset=utf8,<p>test window focus for Scratchpad.";
|
||||
}
|
||||
|
||||
function testFocus(sw, hud) {
|
||||
let sp = sw.Scratchpad;
|
||||
|
||||
function onMessage(event, messages) {
|
||||
let msg = [...messages][0];
|
||||
let node = msg.node;
|
||||
|
||||
var loc = node.querySelector(".frame-link");
|
||||
ok(loc, "location element exists");
|
||||
is(loc.getAttribute("data-url"), sw.Scratchpad.uniqueName, "location value is correct");
|
||||
is(loc.getAttribute("data-line"), "1", "line value is correct");
|
||||
is(loc.getAttribute("data-column"), "1", "column value is correct");
|
||||
|
||||
sw.addEventListener("focus", function onFocus() {
|
||||
sw.removeEventListener("focus", onFocus, true);
|
||||
|
||||
let win = Services.wm.getMostRecentWindow("devtools:scratchpad");
|
||||
|
||||
ok(win, "there are active Scratchpad windows");
|
||||
is(win.Scratchpad.uniqueName, sw.Scratchpad.uniqueName,
|
||||
"correct window is in focus");
|
||||
|
||||
// gScratchpadWindow will be closed automatically but we need to
|
||||
// close the second window ourselves.
|
||||
sw.close();
|
||||
finish();
|
||||
}, true);
|
||||
|
||||
// Simulate a click on the "Scratchpad/N:1" link.
|
||||
EventUtils.synthesizeMouse(loc, 2, 2, {}, hud.iframeWindow);
|
||||
}
|
||||
|
||||
// Sending messages to web console is an asynchronous operation. That's
|
||||
// why we have to setup an observer here.
|
||||
hud.ui.once("new-messages", onMessage);
|
||||
|
||||
sp.setText("console.log('foo');");
|
||||
sp.run().then(function ([selection, error, result]) {
|
||||
is(selection, "console.log('foo');", "selection is correct");
|
||||
is(error, undefined, "error is correct");
|
||||
is(result.type, "undefined", "result is correct");
|
||||
});
|
||||
}
|
||||
221
devtools/client/scratchpad/test/head.js
Normal file
221
devtools/client/scratchpad/test/head.js
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {NetUtil} = Cu.import("resource://gre/modules/NetUtil.jsm", {});
|
||||
const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm", {});
|
||||
const {console} = Cu.import("resource://gre/modules/Console.jsm", {});
|
||||
const {ScratchpadManager} = Cu.import("resource://devtools/client/scratchpad/scratchpad-manager.jsm", {});
|
||||
const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
const Services = require("Services");
|
||||
const DevToolsUtils = require("devtools/shared/DevToolsUtils");
|
||||
const flags = require("devtools/shared/flags");
|
||||
const promise = require("promise");
|
||||
|
||||
|
||||
var gScratchpadWindow; // Reference to the Scratchpad chrome window object
|
||||
|
||||
flags.testing = true;
|
||||
SimpleTest.registerCleanupFunction(() => {
|
||||
flags.testing = false;
|
||||
});
|
||||
|
||||
/**
|
||||
* Open a Scratchpad window.
|
||||
*
|
||||
* @param function aReadyCallback
|
||||
* Optional. The function you want invoked when the Scratchpad instance
|
||||
* is ready.
|
||||
* @param object aOptions
|
||||
* Optional. Options for opening the scratchpad:
|
||||
* - window
|
||||
* Provide this if there's already a Scratchpad window you want to wait
|
||||
* loading for.
|
||||
* - state
|
||||
* Scratchpad state object. This is used when Scratchpad is open.
|
||||
* - noFocus
|
||||
* Boolean that tells you do not want the opened window to receive
|
||||
* focus.
|
||||
* @return nsIDOMWindow
|
||||
* The new window object that holds Scratchpad. Note that the
|
||||
* gScratchpadWindow global is also updated to reference the new window
|
||||
* object.
|
||||
*/
|
||||
function openScratchpad(aReadyCallback, aOptions = {})
|
||||
{
|
||||
let win = aOptions.window ||
|
||||
ScratchpadManager.openScratchpad(aOptions.state);
|
||||
if (!win) {
|
||||
return;
|
||||
}
|
||||
|
||||
let onLoad = function () {
|
||||
win.removeEventListener("load", onLoad, false);
|
||||
|
||||
win.Scratchpad.addObserver({
|
||||
onReady: function (aScratchpad) {
|
||||
aScratchpad.removeObserver(this);
|
||||
|
||||
if (aOptions.noFocus) {
|
||||
aReadyCallback(win, aScratchpad);
|
||||
} else {
|
||||
waitForFocus(aReadyCallback.bind(null, win, aScratchpad), win);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if (aReadyCallback) {
|
||||
win.addEventListener("load", onLoad, false);
|
||||
}
|
||||
|
||||
gScratchpadWindow = win;
|
||||
return gScratchpadWindow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a new tab and then open a scratchpad.
|
||||
* @param object aOptions
|
||||
* Optional. Options for opening the tab and scratchpad. In addition
|
||||
* to the options supported by openScratchpad, the following options
|
||||
* are supported:
|
||||
* - tabContent
|
||||
* A string providing the html content of the tab.
|
||||
* @return Promise
|
||||
*/
|
||||
function openTabAndScratchpad(aOptions = {})
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
return new promise(resolve => {
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
let {selectedBrowser} = gBrowser;
|
||||
selectedBrowser.addEventListener("load", function onLoad() {
|
||||
selectedBrowser.removeEventListener("load", onLoad, true);
|
||||
openScratchpad((win, sp) => resolve([win, sp]), aOptions);
|
||||
}, true);
|
||||
content.location = "data:text/html;charset=utf8," + (aOptions.tabContent || "");
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a temporary file, write to it and call a callback
|
||||
* when done.
|
||||
*
|
||||
* @param string aName
|
||||
* Name of your temporary file.
|
||||
* @param string aContent
|
||||
* Temporary file's contents.
|
||||
* @param function aCallback
|
||||
* Optional callback to be called when we're done writing
|
||||
* to the file. It will receive two parameters: status code
|
||||
* and a file object.
|
||||
*/
|
||||
function createTempFile(aName, aContent, aCallback = function () {})
|
||||
{
|
||||
// Create a temporary file.
|
||||
let file = FileUtils.getFile("TmpD", [aName]);
|
||||
file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, parseInt("666", 8));
|
||||
|
||||
// Write the temporary file.
|
||||
let fout = Cc["@mozilla.org/network/file-output-stream;1"].
|
||||
createInstance(Ci.nsIFileOutputStream);
|
||||
fout.init(file.QueryInterface(Ci.nsILocalFile), 0x02 | 0x08 | 0x20,
|
||||
parseInt("644", 8), fout.DEFER_OPEN);
|
||||
|
||||
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
|
||||
createInstance(Ci.nsIScriptableUnicodeConverter);
|
||||
converter.charset = "UTF-8";
|
||||
let fileContentStream = converter.convertToInputStream(aContent);
|
||||
|
||||
NetUtil.asyncCopy(fileContentStream, fout, function (aStatus) {
|
||||
aCallback(aStatus, file);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a set of asychronous tests sequentially defined by input and output.
|
||||
*
|
||||
* @param Scratchpad aScratchpad
|
||||
* The scratchpad to use in running the tests.
|
||||
* @param array aTests
|
||||
* An array of test objects, each with the following properties:
|
||||
* - method
|
||||
* Scratchpad method to use, one of "run", "display", or "inspect".
|
||||
* - code
|
||||
* Code to run in the scratchpad.
|
||||
* - result
|
||||
* Expected code that will be in the scratchpad upon completion.
|
||||
* - label
|
||||
* The tests label which will be logged in the test runner output.
|
||||
* @return Promise
|
||||
* The promise that will be resolved when all tests are finished.
|
||||
*/
|
||||
function runAsyncTests(aScratchpad, aTests)
|
||||
{
|
||||
let deferred = promise.defer();
|
||||
|
||||
(function runTest() {
|
||||
if (aTests.length) {
|
||||
let test = aTests.shift();
|
||||
aScratchpad.setText(test.code);
|
||||
aScratchpad[test.method]().then(function success() {
|
||||
is(aScratchpad.getText(), test.result, test.label);
|
||||
runTest();
|
||||
}, function failure(error) {
|
||||
ok(false, error.stack + " " + test.label);
|
||||
runTest();
|
||||
});
|
||||
} else {
|
||||
deferred.resolve();
|
||||
}
|
||||
})();
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a set of asychronous tests sequentially with callbacks to prepare each
|
||||
* test and to be called when the test result is ready.
|
||||
*
|
||||
* @param Scratchpad aScratchpad
|
||||
* The scratchpad to use in running the tests.
|
||||
* @param array aTests
|
||||
* An array of test objects, each with the following properties:
|
||||
* - method
|
||||
* Scratchpad method to use, one of "run", "display", or "inspect".
|
||||
* - prepare
|
||||
* The callback to run just prior to executing the scratchpad method.
|
||||
* - then
|
||||
* The callback to run when the scratchpad execution promise resolves.
|
||||
* @return Promise
|
||||
* The promise that will be resolved when all tests are finished.
|
||||
*/
|
||||
var runAsyncCallbackTests = Task.async(function* (aScratchpad, aTests) {
|
||||
for (let {prepare, method, then} of aTests) {
|
||||
yield prepare();
|
||||
let res = yield aScratchpad[method]();
|
||||
yield then(res);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* A simple wrapper for ContentTask.spawn for more compact code.
|
||||
*/
|
||||
function inContent(generator) {
|
||||
return ContentTask.spawn(gBrowser.selectedBrowser, {}, generator);
|
||||
}
|
||||
|
||||
function cleanup()
|
||||
{
|
||||
if (gScratchpadWindow) {
|
||||
gScratchpadWindow.close();
|
||||
gScratchpadWindow = null;
|
||||
}
|
||||
while (gBrowser.tabs.length > 1) {
|
||||
gBrowser.removeCurrentTab();
|
||||
}
|
||||
}
|
||||
|
||||
registerCleanupFunction(cleanup);
|
||||
Loading…
Add table
Add a link
Reference in a new issue