зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central into mozilla-inbound
This commit is contained in:
Коммит
1fc28fc2a4
|
@ -283,10 +283,14 @@ pref("content.image.allow_locking", true);
|
|||
pref("image.mem.min_discard_timeout_ms", 10000);
|
||||
pref("image.mem.max_decoded_image_kb", 5120); /* 5MB */
|
||||
|
||||
// XXX this isn't a good check for "are touch events supported", but
|
||||
// we don't really have a better one at the moment.
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
// enable touch events interfaces
|
||||
pref("dom.w3c_touch_events.enabled", 1);
|
||||
pref("dom.w3c_touch_events.safetyX", 0); // escape borders in units of 1/240"
|
||||
pref("dom.w3c_touch_events.safetyY", 120); // escape borders in units of 1/240"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_SAFE_BROWSING
|
||||
// Safe browsing does nothing unless this pref is set
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[
|
||||
{
|
||||
"size": 676733720,
|
||||
"digest": "6ae117e64af1e8532004e9de44f172b5db88f42a91b8821503b3832de6e168f8c000229705a5110ce294065780a6371e7852dd76ddd8f3c6113892a093b6fc55",
|
||||
"size": 676664796,
|
||||
"digest": "d50e0a916bb54c12f55961b3155c1bb754e46fccd0cc965f6c37c2142a7080e58dc3980b7f7f1249b078a21553d6ae2edfefce18213cf8c8fc3f593db27bb0e6",
|
||||
"algorithm": "sha512",
|
||||
"filename": "gonk.tar.xz"
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="ffc42185726384eaa80ea685bd9c95b7dab467c3"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="22629c7597d0d658fb472f76f2bf35e7eaaf98fd"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="167b4c59a82b9130e385de786e8056d89a1cb8c3"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="6ee1f8987ef36d688f97064c003ad57849dfadf2"/>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0"?>
|
||||
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1356125617000">
|
||||
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1357164966000">
|
||||
<emItems>
|
||||
<emItem blockID="i58" id="webmaster@buzzzzvideos.info">
|
||||
<versionRange minVersion="0" maxVersion="*">
|
||||
|
@ -379,7 +379,7 @@
|
|||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i220" id="pricepeep@getpricepeep.com">
|
||||
<versionRange minVersion="0" maxVersion="*" severity="1">
|
||||
<versionRange minVersion="0" maxVersion="2.1.0.19.99" severity="1">
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i226" id="{462be121-2b54-4218-bf00-b9bf8135b23f}">
|
||||
|
@ -576,14 +576,14 @@
|
|||
<pluginItem blockID="p176">
|
||||
<match name="filename" exp="(NPSWF32\.dll)|(Flash\ Player\.plugin)" /> <versionRange minVersion="0" maxVersion="10.3.183.18.999" severity="0" vulnerabilitystatus="1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="18.0a1" maxVersion="*" />
|
||||
<versionRange minVersion="19.0a1" maxVersion="*" />
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p178">
|
||||
<match name="filename" exp="(NPSWF[0-9_]*\.dll)|(Flash\ Player\.plugin)" /> <versionRange minVersion="11.0" maxVersion="11.4.402.286.999" severity="0" vulnerabilitystatus="1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="18.0a1" maxVersion="*" />
|
||||
<versionRange minVersion="19.0a1" maxVersion="*" />
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
|
|
|
@ -565,7 +565,7 @@
|
|||
<menupopup id="menuWebDeveloperPopup">
|
||||
<menuitem id="menu_devToolbox"
|
||||
observes="devtoolsMenuBroadcaster_DevToolbox"
|
||||
accesskey="&devToolbox.accesskey;"/>
|
||||
accesskey="&devToolboxMenuItem.accesskey;"/>
|
||||
<menuseparator id="menu_devtools_separator"/>
|
||||
<menuitem id="menu_devToolbar"
|
||||
observes="devtoolsMenuBroadcaster_DevToolbar"
|
||||
|
|
|
@ -174,7 +174,7 @@
|
|||
|
||||
<!-- DevTools broadcasters -->
|
||||
<broadcaster id="devtoolsMenuBroadcaster_DevToolbox"
|
||||
label="&devToolbarToolsButton.label;"
|
||||
label="&devToolboxMenuItem.label;"
|
||||
type="checkbox" autocheck="false"
|
||||
command="Tools:DevToolbox"/>
|
||||
<broadcaster id="devtoolsMenuBroadcaster_DevToolbar"
|
||||
|
|
|
@ -1516,6 +1516,11 @@ var gBrowserInit = {
|
|||
|
||||
gDevToolsBrowser.forgetBrowserWindow(window);
|
||||
|
||||
let desc = Object.getOwnPropertyDescriptor(window, "DeveloperToolbar");
|
||||
if (desc && !desc.get) {
|
||||
DeveloperToolbar.destroy();
|
||||
}
|
||||
|
||||
// First clean up services initialized in gBrowserInit.onLoad (or those whose
|
||||
// uninit methods don't depend on the services having been initialized).
|
||||
allTabs.uninit();
|
||||
|
|
|
@ -1152,7 +1152,8 @@
|
|||
</stack>
|
||||
<toolbarbutton id="developer-toolbar-toolbox-button"
|
||||
class="developer-toolbar-button"
|
||||
observes="devtoolsMenuBroadcaster_DevToolbox"/>
|
||||
observes="devtoolsMenuBroadcaster_DevToolbox"
|
||||
tooltiptext="&devToolbarToolsButton.tooltip;"/>
|
||||
#ifndef XP_MACOSX
|
||||
<toolbarbutton id="developer-toolbar-closebutton"
|
||||
class="devtools-closebutton"
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,297 +0,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/. */
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
|
||||
this.EXPORTED_SYMBOLS = [ "Flags" ];
|
||||
|
||||
Cu.import("resource:///modules/devtools/gcli.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "AddonManager",
|
||||
"resource://gre/modules/AddonManager.jsm");
|
||||
|
||||
// We need to use an object in which to store any flags because a primitive
|
||||
// would remain undefined.
|
||||
this.Flags = {
|
||||
addonsLoaded: false
|
||||
};
|
||||
|
||||
/**
|
||||
* 'addon' command.
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "addon",
|
||||
description: gcli.lookup("addonDesc")
|
||||
});
|
||||
|
||||
/**
|
||||
* 'addon list' command.
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "addon list",
|
||||
description: gcli.lookup("addonListDesc"),
|
||||
params: [{
|
||||
name: 'type',
|
||||
type: {
|
||||
name: 'selection',
|
||||
data: ["dictionary", "extension", "locale", "plugin", "theme", "all"]
|
||||
},
|
||||
defaultValue: 'all',
|
||||
description: gcli.lookup("addonListTypeDesc"),
|
||||
}],
|
||||
exec: function(aArgs, context) {
|
||||
function representEnabledAddon(aAddon) {
|
||||
return "<li><![CDATA[" + aAddon.name + "\u2002" + aAddon.version +
|
||||
getAddonStatus(aAddon) + "]]></li>";
|
||||
}
|
||||
|
||||
function representDisabledAddon(aAddon) {
|
||||
return "<li class=\"gcli-addon-disabled\">" +
|
||||
"<![CDATA[" + aAddon.name + "\u2002" + aAddon.version + aAddon.version +
|
||||
"]]></li>";
|
||||
}
|
||||
|
||||
function getAddonStatus(aAddon) {
|
||||
let operations = [];
|
||||
|
||||
if (aAddon.pendingOperations & AddonManager.PENDING_ENABLE) {
|
||||
operations.push("PENDING_ENABLE");
|
||||
}
|
||||
|
||||
if (aAddon.pendingOperations & AddonManager.PENDING_DISABLE) {
|
||||
operations.push("PENDING_DISABLE");
|
||||
}
|
||||
|
||||
if (aAddon.pendingOperations & AddonManager.PENDING_UNINSTALL) {
|
||||
operations.push("PENDING_UNINSTALL");
|
||||
}
|
||||
|
||||
if (aAddon.pendingOperations & AddonManager.PENDING_INSTALL) {
|
||||
operations.push("PENDING_INSTALL");
|
||||
}
|
||||
|
||||
if (aAddon.pendingOperations & AddonManager.PENDING_UPGRADE) {
|
||||
operations.push("PENDING_UPGRADE");
|
||||
}
|
||||
|
||||
if (operations.length) {
|
||||
return " (" + operations.join(", ") + ")";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two addons by their name. Used in sorting.
|
||||
*/
|
||||
function compareAddonNames(aNameA, aNameB) {
|
||||
return String.localeCompare(aNameA.name, aNameB.name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the promise which is the scope (this) of this function, filling
|
||||
* it with an HTML representation of the passed add-ons.
|
||||
*/
|
||||
function list(aType, aAddons) {
|
||||
if (!aAddons.length) {
|
||||
this.resolve(gcli.lookup("addonNoneOfType"));
|
||||
}
|
||||
|
||||
// Separate the enabled add-ons from the disabled ones.
|
||||
let enabledAddons = [];
|
||||
let disabledAddons = [];
|
||||
|
||||
aAddons.forEach(function(aAddon) {
|
||||
if (aAddon.isActive) {
|
||||
enabledAddons.push(aAddon);
|
||||
} else {
|
||||
disabledAddons.push(aAddon);
|
||||
}
|
||||
});
|
||||
|
||||
let header;
|
||||
switch(aType) {
|
||||
case "dictionary":
|
||||
header = gcli.lookup("addonListDictionaryHeading");
|
||||
break;
|
||||
case "extension":
|
||||
header = gcli.lookup("addonListExtensionHeading");
|
||||
break;
|
||||
case "locale":
|
||||
header = gcli.lookup("addonListLocaleHeading");
|
||||
break;
|
||||
case "plugin":
|
||||
header = gcli.lookup("addonListPluginHeading");
|
||||
break;
|
||||
case "theme":
|
||||
header = gcli.lookup("addonListThemeHeading");
|
||||
case "all":
|
||||
header = gcli.lookup("addonListAllHeading");
|
||||
break;
|
||||
default:
|
||||
header = gcli.lookup("addonListUnknownHeading");
|
||||
}
|
||||
|
||||
// Map and sort the add-ons, and create an HTML list.
|
||||
let message = header +
|
||||
"<ol>" +
|
||||
enabledAddons.sort(compareAddonNames).map(representEnabledAddon).join("") +
|
||||
disabledAddons.sort(compareAddonNames).map(representDisabledAddon).join("") +
|
||||
"</ol>";
|
||||
|
||||
this.resolve(context.createView({ html: message }));
|
||||
}
|
||||
|
||||
// Create the promise that will be resolved when the add-on listing has
|
||||
// been finished.
|
||||
let promise = context.createPromise();
|
||||
let types = aArgs.type == "all" ? null : [aArgs.type];
|
||||
AddonManager.getAddonsByTypes(types, list.bind(promise, aArgs.type));
|
||||
return promise;
|
||||
}
|
||||
});
|
||||
|
||||
// We need a list of addon names for the enable and disable commands. Because
|
||||
// getting the name list is async we do not add the commands until we have the
|
||||
// list.
|
||||
AddonManager.getAllAddons(function addonAsync(aAddons) {
|
||||
// We listen for installs to keep our addon list up to date. There is no need
|
||||
// to listen for uninstalls because uninstalled addons are simply disabled
|
||||
// until restart (to enable undo functionality).
|
||||
AddonManager.addAddonListener({
|
||||
onInstalled: function(aAddon) {
|
||||
addonNameCache.push({
|
||||
name: representAddon(aAddon).replace(/\s/g, "_"),
|
||||
value: aAddon.name
|
||||
});
|
||||
},
|
||||
onUninstalled: function(aAddon) {
|
||||
let name = representAddon(aAddon).replace(/\s/g, "_");
|
||||
|
||||
for (let i = 0; i < addonNameCache.length; i++) {
|
||||
if(addonNameCache[i].name == name) {
|
||||
addonNameCache.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Returns a string that represents the passed add-on.
|
||||
*/
|
||||
function representAddon(aAddon) {
|
||||
let name = aAddon.name + " " + aAddon.version;
|
||||
return name.trim();
|
||||
}
|
||||
|
||||
let addonNameCache = [];
|
||||
|
||||
// The name parameter, used in "addon enable" and "addon disable."
|
||||
let nameParameter = {
|
||||
name: "name",
|
||||
type: {
|
||||
name: "selection",
|
||||
lookup: addonNameCache
|
||||
},
|
||||
description: gcli.lookup("addonNameDesc")
|
||||
};
|
||||
|
||||
for (let addon of aAddons) {
|
||||
addonNameCache.push({
|
||||
name: representAddon(addon).replace(/\s/g, "_"),
|
||||
value: addon.name
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 'addon enable' command.
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "addon enable",
|
||||
description: gcli.lookup("addonEnableDesc"),
|
||||
params: [nameParameter],
|
||||
exec: function(aArgs, context) {
|
||||
/**
|
||||
* Enables the addon in the passed list which has a name that matches
|
||||
* according to the passed name comparer, and resolves the promise which
|
||||
* is the scope (this) of this function to display the result of this
|
||||
* enable attempt.
|
||||
*/
|
||||
function enable(aName, addons) {
|
||||
// Find the add-on.
|
||||
let addon = null;
|
||||
addons.some(function(candidate) {
|
||||
if (candidate.name == aName) {
|
||||
addon = candidate;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
let name = representAddon(addon);
|
||||
let message = "";
|
||||
|
||||
if (!addon.userDisabled) {
|
||||
message = gcli.lookupFormat("addonAlreadyEnabled", [name]);
|
||||
} else {
|
||||
addon.userDisabled = false;
|
||||
message = gcli.lookupFormat("addonEnabled", [name]);
|
||||
}
|
||||
this.resolve(message);
|
||||
}
|
||||
|
||||
let promise = context.createPromise();
|
||||
// List the installed add-ons, enable one when done listing.
|
||||
AddonManager.getAllAddons(enable.bind(promise, aArgs.name));
|
||||
return promise;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 'addon disable' command.
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "addon disable",
|
||||
description: gcli.lookup("addonDisableDesc"),
|
||||
params: [nameParameter],
|
||||
exec: function(aArgs, context) {
|
||||
/**
|
||||
* Like enable, but ... you know ... the exact opposite.
|
||||
*/
|
||||
function disable(aName, addons) {
|
||||
// Find the add-on.
|
||||
let addon = null;
|
||||
addons.some(function(candidate) {
|
||||
if (candidate.name == aName) {
|
||||
addon = candidate;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
let name = representAddon(addon);
|
||||
let message = "";
|
||||
|
||||
if (addon.userDisabled) {
|
||||
message = gcli.lookupFormat("addonAlreadyDisabled", [name]);
|
||||
} else {
|
||||
addon.userDisabled = true;
|
||||
message = gcli.lookupFormat("addonDisabled", [name]);
|
||||
}
|
||||
this.resolve(message);
|
||||
}
|
||||
|
||||
let promise = context.createPromise();
|
||||
// List the installed add-ons, disable one when done listing.
|
||||
AddonManager.getAllAddons(disable.bind(promise, aArgs.name));
|
||||
return promise;
|
||||
}
|
||||
});
|
||||
Flags.addonsLoaded = true;
|
||||
Services.obs.notifyObservers(null, "gcli_addon_commands_ready", null);
|
||||
});
|
|
@ -1,184 +0,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/. */
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
|
||||
this.EXPORTED_SYMBOLS = [ ];
|
||||
|
||||
Cu.import("resource:///modules/devtools/gcli.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "HUDService",
|
||||
"resource:///modules/HUDService.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "TargetFactory",
|
||||
"resource:///modules/devtools/Target.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "gDevTools",
|
||||
"resource:///modules/devtools/gDevTools.jsm");
|
||||
|
||||
/**
|
||||
* 'break' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "break",
|
||||
description: gcli.lookup("breakDesc"),
|
||||
manual: gcli.lookup("breakManual")
|
||||
});
|
||||
|
||||
/**
|
||||
* 'break list' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "break list",
|
||||
description: gcli.lookup("breaklistDesc"),
|
||||
returnType: "html",
|
||||
exec: function(args, context) {
|
||||
let dbg = getPanel(context, "jsdebugger");
|
||||
if (!dbg) {
|
||||
return gcli.lookup("debuggerStopped");
|
||||
}
|
||||
|
||||
let breakpoints = dbg.getAllBreakpoints();
|
||||
|
||||
if (Object.keys(breakpoints).length === 0) {
|
||||
return gcli.lookup("breaklistNone");
|
||||
}
|
||||
|
||||
let reply = gcli.lookup("breaklistIntro");
|
||||
reply += "<ol>";
|
||||
for each (let breakpoint in breakpoints) {
|
||||
let text = gcli.lookupFormat("breaklistLineEntry",
|
||||
[breakpoint.location.url,
|
||||
breakpoint.location.line]);
|
||||
reply += "<li>" + text + "</li>";
|
||||
};
|
||||
reply += "</ol>";
|
||||
return reply;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 'break add' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "break add",
|
||||
description: gcli.lookup("breakaddDesc"),
|
||||
manual: gcli.lookup("breakaddManual")
|
||||
});
|
||||
|
||||
/**
|
||||
* 'break add line' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "break add line",
|
||||
description: gcli.lookup("breakaddlineDesc"),
|
||||
params: [
|
||||
{
|
||||
name: "file",
|
||||
type: {
|
||||
name: "selection",
|
||||
data: function(args, context) {
|
||||
let files = [];
|
||||
let dbg = getPanel(context, "jsdebugger");
|
||||
if (dbg) {
|
||||
let sourcesView = dbg.panelWin.DebuggerView.Sources;
|
||||
for (let item in sourcesView) {
|
||||
files.push(item.value);
|
||||
}
|
||||
}
|
||||
return files;
|
||||
}
|
||||
},
|
||||
description: gcli.lookup("breakaddlineFileDesc")
|
||||
},
|
||||
{
|
||||
name: "line",
|
||||
type: { name: "number", min: 1, step: 10 },
|
||||
description: gcli.lookup("breakaddlineLineDesc")
|
||||
}
|
||||
],
|
||||
returnType: "html",
|
||||
exec: function(args, context) {
|
||||
args.type = "line";
|
||||
|
||||
let dbg = getPanel(context, "jsdebugger");
|
||||
if (!dbg) {
|
||||
return gcli.lookup("debuggerStopped");
|
||||
}
|
||||
var deferred = context.defer();
|
||||
let position = { url: args.file, line: args.line };
|
||||
dbg.addBreakpoint(position, function(aBreakpoint, aError) {
|
||||
if (aError) {
|
||||
deferred.resolve(gcli.lookupFormat("breakaddFailed", [aError]));
|
||||
return;
|
||||
}
|
||||
deferred.resolve(gcli.lookup("breakaddAdded"));
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* 'break del' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "break del",
|
||||
description: gcli.lookup("breakdelDesc"),
|
||||
params: [
|
||||
{
|
||||
name: "breakid",
|
||||
type: {
|
||||
name: "number",
|
||||
min: 0,
|
||||
max: function(args, context) {
|
||||
let dbg = getPanel(context, "jsdebugger");
|
||||
return dbg == null ?
|
||||
null :
|
||||
Object.keys(dbg.getAllBreakpoints()).length - 1;
|
||||
},
|
||||
},
|
||||
description: gcli.lookup("breakdelBreakidDesc")
|
||||
}
|
||||
],
|
||||
returnType: "html",
|
||||
exec: function(args, context) {
|
||||
let dbg = getPanel(context, "jsdebugger");
|
||||
if (!dbg) {
|
||||
return gcli.lookup("debuggerStopped");
|
||||
}
|
||||
|
||||
let breakpoints = dbg.getAllBreakpoints();
|
||||
let id = Object.keys(breakpoints)[args.breakid];
|
||||
if (!id || !(id in breakpoints)) {
|
||||
return gcli.lookup("breakNotFound");
|
||||
}
|
||||
|
||||
let deferred = context.defer();
|
||||
try {
|
||||
dbg.removeBreakpoint(breakpoints[id], function() {
|
||||
deferred.resolve(gcli.lookup("breakdelRemoved"));
|
||||
});
|
||||
} catch (ex) {
|
||||
// If the debugger has been closed already, don't scare the user.
|
||||
deferred.resolve(gcli.lookup("breakdelRemoved"));
|
||||
}
|
||||
return deferred.promise;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* A helper to go from a command context to a debugger panel
|
||||
*/
|
||||
function getPanel(context, id) {
|
||||
if (context == null) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let gBrowser = context.environment.chromeDocument.defaultView.gBrowser;
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
let toolbox = gDevTools.getToolbox(target);
|
||||
return toolbox == null ? undefined : toolbox.getPanel(id);
|
||||
}
|
|
@ -1,107 +0,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/. */
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
|
||||
this.EXPORTED_SYMBOLS = [ ];
|
||||
|
||||
Cu.import("resource:///modules/devtools/gcli.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "gDevTools",
|
||||
"resource:///modules/devtools/gDevTools.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "Debugger", function() {
|
||||
let JsDebugger = {};
|
||||
Components.utils.import("resource://gre/modules/jsdebugger.jsm", JsDebugger);
|
||||
|
||||
let global = Components.utils.getGlobalForObject({});
|
||||
JsDebugger.addDebuggerToGlobal(global);
|
||||
|
||||
return global.Debugger;
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "TargetFactory",
|
||||
"resource:///modules/devtools/Target.jsm");
|
||||
|
||||
let debuggers = [];
|
||||
|
||||
/**
|
||||
* 'calllog' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "calllog",
|
||||
description: gcli.lookup("calllogDesc")
|
||||
})
|
||||
|
||||
/**
|
||||
* 'calllog start' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "calllog start",
|
||||
description: gcli.lookup("calllogStartDesc"),
|
||||
|
||||
exec: function(args, context) {
|
||||
let contentWindow = context.environment.contentDocument.defaultView;
|
||||
|
||||
let dbg = new Debugger(contentWindow);
|
||||
dbg.onEnterFrame = function(frame) {
|
||||
// BUG 773652 - Make the output from the GCLI calllog command nicer
|
||||
contentWindow.console.log("Method call: " + this.callDescription(frame));
|
||||
}.bind(this);
|
||||
|
||||
debuggers.push(dbg);
|
||||
|
||||
let gBrowser = context.environment.chromeDocument.defaultView.gBrowser;
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
gDevTools.showToolbox(target, "webconsole");
|
||||
|
||||
return gcli.lookup("calllogStartReply");
|
||||
},
|
||||
|
||||
callDescription: function(frame) {
|
||||
let name = "<anonymous>";
|
||||
if (frame.callee.name) {
|
||||
name = frame.callee.name;
|
||||
}
|
||||
else {
|
||||
let desc = frame.callee.getOwnPropertyDescriptor("displayName");
|
||||
if (desc && desc.value && typeof desc.value == "string") {
|
||||
name = desc.value;
|
||||
}
|
||||
}
|
||||
|
||||
let args = frame.arguments.map(this.valueToString).join(", ");
|
||||
return name + "(" + args + ")";
|
||||
},
|
||||
|
||||
valueToString: function(value) {
|
||||
if (typeof value !== "object" || value === null) {
|
||||
return uneval(value);
|
||||
}
|
||||
return "[object " + value.class + "]";
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 'calllog stop' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "calllog stop",
|
||||
description: gcli.lookup("calllogStopDesc"),
|
||||
|
||||
exec: function(args, context) {
|
||||
let numDebuggers = debuggers.length;
|
||||
if (numDebuggers == 0) {
|
||||
return gcli.lookup("calllogStopNoLogging");
|
||||
}
|
||||
|
||||
for (let dbg of debuggers) {
|
||||
dbg.onEnterFrame = undefined;
|
||||
}
|
||||
debuggers = [];
|
||||
|
||||
return gcli.lookupFormat("calllogStopReply", [ numDebuggers ]);
|
||||
}
|
||||
});
|
|
@ -1,158 +0,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/. */
|
||||
|
||||
|
||||
this.EXPORTED_SYMBOLS = [ ];
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
|
||||
Cu.import("resource:///modules/devtools/gcli.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "gDevTools",
|
||||
"resource:///modules/devtools/gDevTools.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "TargetFactory",
|
||||
"resource:///modules/devtools/Target.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "Debugger", function() {
|
||||
let JsDebugger = {};
|
||||
Cu.import("resource://gre/modules/jsdebugger.jsm", JsDebugger);
|
||||
|
||||
let global = Components.utils.getGlobalForObject({});
|
||||
JsDebugger.addDebuggerToGlobal(global);
|
||||
|
||||
return global.Debugger;
|
||||
});
|
||||
|
||||
let debuggers = [];
|
||||
let sandboxes = [];
|
||||
|
||||
/**
|
||||
* 'calllog chromestart' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "calllog chromestart",
|
||||
description: gcli.lookup("calllogChromeStartDesc"),
|
||||
get hidden() gcli.hiddenByChromePref(),
|
||||
params: [
|
||||
{
|
||||
name: "sourceType",
|
||||
type: {
|
||||
name: "selection",
|
||||
data: ["content-variable", "chrome-variable", "jsm", "javascript"]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "source",
|
||||
type: "string",
|
||||
description: gcli.lookup("calllogChromeSourceTypeDesc"),
|
||||
manual: gcli.lookup("calllogChromeSourceTypeManual"),
|
||||
}
|
||||
],
|
||||
exec: function(args, context) {
|
||||
let globalObj;
|
||||
let contentWindow = context.environment.contentDocument.defaultView;
|
||||
|
||||
if (args.sourceType == "jsm") {
|
||||
try {
|
||||
globalObj = Cu.import(args.source);
|
||||
}
|
||||
catch (e) {
|
||||
return gcli.lookup("callLogChromeInvalidJSM");
|
||||
}
|
||||
} else if (args.sourceType == "content-variable") {
|
||||
if (args.source in contentWindow) {
|
||||
globalObj = Cu.getGlobalForObject(contentWindow[args.source]);
|
||||
} else {
|
||||
throw new Error(gcli.lookup("callLogChromeVarNotFoundContent"));
|
||||
}
|
||||
} else if (args.sourceType == "chrome-variable") {
|
||||
let chromeWin = context.environment.chromeDocument.defaultView;
|
||||
if (args.source in chromeWin) {
|
||||
globalObj = Cu.getGlobalForObject(chromeWin[args.source]);
|
||||
} else {
|
||||
return gcli.lookup("callLogChromeVarNotFoundChrome");
|
||||
}
|
||||
} else {
|
||||
let chromeWin = context.environment.chromeDocument.defaultView;
|
||||
let sandbox = new Cu.Sandbox(chromeWin,
|
||||
{
|
||||
sandboxPrototype: chromeWin,
|
||||
wantXrays: false,
|
||||
sandboxName: "gcli-cmd-calllog-chrome"
|
||||
});
|
||||
let returnVal;
|
||||
try {
|
||||
returnVal = Cu.evalInSandbox(args.source, sandbox, "ECMAv5");
|
||||
sandboxes.push(sandbox);
|
||||
} catch(e) {
|
||||
// We need to save the message before cleaning up else e contains a dead
|
||||
// object.
|
||||
let msg = gcli.lookup("callLogChromeEvalException") + ": " + e;
|
||||
Cu.nukeSandbox(sandbox);
|
||||
return msg;
|
||||
}
|
||||
|
||||
if (typeof returnVal == "undefined") {
|
||||
return gcli.lookup("callLogChromeEvalNeedsObject");
|
||||
}
|
||||
|
||||
globalObj = Cu.getGlobalForObject(returnVal);
|
||||
}
|
||||
|
||||
let dbg = new Debugger(globalObj);
|
||||
debuggers.push(dbg);
|
||||
|
||||
dbg.onEnterFrame = function(frame) {
|
||||
// BUG 773652 - Make the output from the GCLI calllog command nicer
|
||||
contentWindow.console.log(gcli.lookup("callLogChromeMethodCall") +
|
||||
": " + this.callDescription(frame));
|
||||
}.bind(this);
|
||||
|
||||
let gBrowser = context.environment.chromeDocument.defaultView.gBrowser;
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
gDevTools.showToolbox(target, "webconsole");
|
||||
|
||||
return gcli.lookup("calllogChromeStartReply");
|
||||
},
|
||||
|
||||
valueToString: function(value) {
|
||||
if (typeof value !== "object" || value === null)
|
||||
return uneval(value);
|
||||
return "[object " + value.class + "]";
|
||||
},
|
||||
|
||||
callDescription: function(frame) {
|
||||
let name = frame.callee.name || gcli.lookup("callLogChromeAnonFunction");
|
||||
let args = frame.arguments.map(this.valueToString).join(", ");
|
||||
return name + "(" + args + ")";
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 'calllog chromestop' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "calllog chromestop",
|
||||
description: gcli.lookup("calllogChromeStopDesc"),
|
||||
get hidden() gcli.hiddenByChromePref(),
|
||||
exec: function(args, context) {
|
||||
let numDebuggers = debuggers.length;
|
||||
if (numDebuggers == 0) {
|
||||
return gcli.lookup("calllogChromeStopNoLogging");
|
||||
}
|
||||
|
||||
for (let dbg of debuggers) {
|
||||
dbg.onEnterFrame = undefined;
|
||||
dbg.enabled = false;
|
||||
}
|
||||
for (let sandbox of sandboxes) {
|
||||
Cu.nukeSandbox(sandbox);
|
||||
}
|
||||
debuggers = [];
|
||||
sandboxes = [];
|
||||
|
||||
return gcli.lookupFormat("calllogChromeStopReply", [ numDebuggers ]);
|
||||
}
|
||||
});
|
|
@ -1,129 +0,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/. */
|
||||
|
||||
this.EXPORTED_SYMBOLS = [ "CmdCommands" ];
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
|
||||
Cu.import("resource:///modules/devtools/gcli.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
let prefSvc = "@mozilla.org/preferences-service;1";
|
||||
XPCOMUtils.defineLazyGetter(this, "prefBranch", function() {
|
||||
let prefService = Cc[prefSvc].getService(Ci.nsIPrefService);
|
||||
return prefService.getBranch(null).QueryInterface(Ci.nsIPrefBranch2);
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
|
||||
"resource://gre/modules/NetUtil.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "console",
|
||||
"resource://gre/modules/devtools/Console.jsm");
|
||||
|
||||
const PREF_DIR = "devtools.commands.dir";
|
||||
|
||||
/**
|
||||
* A place to store the names of the commands that we have added as a result of
|
||||
* calling refreshAutoCommands(). Used by refreshAutoCommands to remove the
|
||||
* added commands.
|
||||
*/
|
||||
let commands = [];
|
||||
|
||||
/**
|
||||
* Exported API
|
||||
*/
|
||||
this.CmdCommands = {
|
||||
/**
|
||||
* Called to look in a directory pointed at by the devtools.commands.dir pref
|
||||
* for *.mozcmd files which are then loaded.
|
||||
* @param nsIPrincipal aSandboxPrincipal Scope object for the Sandbox in which
|
||||
* we eval the script from the .mozcmd file. This should be a chrome window.
|
||||
*/
|
||||
refreshAutoCommands: function GC_refreshAutoCommands(aSandboxPrincipal) {
|
||||
// First get rid of the last set of commands
|
||||
commands.forEach(function(name) {
|
||||
gcli.removeCommand(name);
|
||||
});
|
||||
|
||||
let dirName = prefBranch.getComplexValue(PREF_DIR,
|
||||
Ci.nsISupportsString).data.trim();
|
||||
if (dirName == "") {
|
||||
return;
|
||||
}
|
||||
|
||||
let dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
|
||||
dir.initWithPath(dirName);
|
||||
if (!dir.exists() || !dir.isDirectory()) {
|
||||
throw new Error('\'' + dirName + '\' is not a directory.');
|
||||
}
|
||||
|
||||
let en = dir.directoryEntries.QueryInterface(Ci.nsIDirectoryEnumerator);
|
||||
|
||||
while (true) {
|
||||
let file = en.nextFile;
|
||||
if (!file) {
|
||||
break;
|
||||
}
|
||||
if (file.leafName.match(/.*\.mozcmd$/) && file.isFile() && file.isReadable()) {
|
||||
loadCommandFile(file, aSandboxPrincipal);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Load the commands from a single file
|
||||
* @param nsIFile aFile The file containing the commands that we should read
|
||||
* @param nsIPrincipal aSandboxPrincipal Scope object for the Sandbox in which
|
||||
* we eval the script from the .mozcmd file. This should be a chrome window.
|
||||
*/
|
||||
function loadCommandFile(aFile, aSandboxPrincipal) {
|
||||
NetUtil.asyncFetch(aFile, function refresh_fetch(aStream, aStatus) {
|
||||
if (!Components.isSuccessCode(aStatus)) {
|
||||
console.error("NetUtil.asyncFetch(" + aFile.path + ",..) failed. Status=" + aStatus);
|
||||
return;
|
||||
}
|
||||
|
||||
let source = NetUtil.readInputStreamToString(aStream, aStream.available());
|
||||
aStream.close();
|
||||
|
||||
let sandbox = new Cu.Sandbox(aSandboxPrincipal, {
|
||||
sandboxPrototype: aSandboxPrincipal,
|
||||
wantXrays: false,
|
||||
sandboxName: aFile.path
|
||||
});
|
||||
let data = Cu.evalInSandbox(source, sandbox, "1.8", aFile.leafName, 1);
|
||||
|
||||
if (!Array.isArray(data)) {
|
||||
console.error("Command file '" + aFile.leafName + "' does not have top level array.");
|
||||
return;
|
||||
}
|
||||
|
||||
data.forEach(function(commandSpec) {
|
||||
gcli.addCommand(commandSpec);
|
||||
commands.push(commandSpec.name);
|
||||
});
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* 'cmd' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "cmd",
|
||||
get hidden() { return !prefBranch.prefHasUserValue(PREF_DIR); },
|
||||
description: gcli.lookup("cmdDesc")
|
||||
});
|
||||
|
||||
/**
|
||||
* 'cmd refresh' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "cmd refresh",
|
||||
description: gcli.lookup("cmdRefreshDesc"),
|
||||
get hidden() { return !prefBranch.prefHasUserValue(PREF_DIR); },
|
||||
exec: function Command_cmdRefresh(args, context) {
|
||||
let chromeWindow = context.environment.chromeDocument.defaultView;
|
||||
CmdCommands.refreshAutoCommands(chromeWindow);
|
||||
}
|
||||
});
|
|
@ -1,68 +0,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/. */
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
|
||||
this.EXPORTED_SYMBOLS = [ ];
|
||||
|
||||
Cu.import("resource:///modules/devtools/gcli.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "HUDService",
|
||||
"resource:///modules/HUDService.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "gDevTools",
|
||||
"resource:///modules/devtools/gDevTools.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "TargetFactory",
|
||||
"resource:///modules/devtools/Target.jsm");
|
||||
|
||||
/**
|
||||
* 'console' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "console",
|
||||
description: gcli.lookup("consoleDesc"),
|
||||
manual: gcli.lookup("consoleManual")
|
||||
});
|
||||
|
||||
/**
|
||||
* 'console clear' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "console clear",
|
||||
description: gcli.lookup("consoleclearDesc"),
|
||||
exec: function Command_consoleClear(args, context) {
|
||||
let window = context.environment.contentDocument.defaultView;
|
||||
let hud = HUDService.getHudByWindow(window);
|
||||
// hud will be null if the web console has not been opened for this window
|
||||
if (hud) {
|
||||
hud.jsterm.clearOutput();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 'console close' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "console close",
|
||||
description: gcli.lookup("consolecloseDesc"),
|
||||
exec: function Command_consoleClose(args, context) {
|
||||
let gBrowser = context.environment.chromeDocument.defaultView.gBrowser;
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
return gDevTools.closeToolbox(target);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 'console open' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "console open",
|
||||
description: gcli.lookup("consoleopenDesc"),
|
||||
exec: function Command_consoleOpen(args, context) {
|
||||
let gBrowser = context.environment.chromeDocument.defaultView.gBrowser;
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
return gDevTools.showToolbox(target, "webconsole");
|
||||
}
|
||||
});
|
|
@ -1,207 +0,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/. */
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
|
||||
this.EXPORTED_SYMBOLS = [ ];
|
||||
|
||||
Cu.import("resource:///modules/devtools/gcli.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "console",
|
||||
"resource://gre/modules/devtools/Console.jsm");
|
||||
|
||||
// We should really be using nsICookieManager so we can read more than just the
|
||||
// key/value of cookies. The difficulty is filtering the cookies that are
|
||||
// relevant to the current page. See
|
||||
// https://github.com/firebug/firebug/blob/master/extension/content/firebug/cookies/cookieObserver.js#L123
|
||||
// For details on how this is done with Firebug
|
||||
|
||||
/**
|
||||
* 'cookie' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "cookie",
|
||||
description: gcli.lookup("cookieDesc"),
|
||||
manual: gcli.lookup("cookieManual")
|
||||
});
|
||||
|
||||
/**
|
||||
* The template for the 'cookie list' command.
|
||||
*/
|
||||
var cookieListHtml = "" +
|
||||
"<table>" +
|
||||
" <tr>" +
|
||||
" <th>" + gcli.lookup("cookieListOutKey") + "</th>" +
|
||||
" <th>" + gcli.lookup("cookieListOutValue") + "</th>" +
|
||||
" <th>" + gcli.lookup("cookieListOutActions") + "</th>" +
|
||||
" </tr>" +
|
||||
" <tr foreach='cookie in ${cookies}'>" +
|
||||
" <td>${cookie.key}</td>" +
|
||||
" <td>${cookie.value}</td>" +
|
||||
" <td>" +
|
||||
" <span class='gcli-out-shortcut' onclick='${onclick}'" +
|
||||
" data-command='cookie set ${cookie.key} '" +
|
||||
" >" + gcli.lookup("cookieListOutEdit") + "</span>" +
|
||||
" <span class='gcli-out-shortcut'" +
|
||||
" onclick='${onclick}' ondblclick='${ondblclick}'" +
|
||||
" data-command='cookie remove ${cookie.key}'" +
|
||||
" >" + gcli.lookup("cookieListOutRemove") + "</span>" +
|
||||
" </td>" +
|
||||
" </tr>" +
|
||||
"</table>" +
|
||||
"";
|
||||
|
||||
/**
|
||||
* 'cookie list' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "cookie list",
|
||||
description: gcli.lookup("cookieListDesc"),
|
||||
manual: gcli.lookup("cookieListManual"),
|
||||
returnType: "string",
|
||||
exec: function Command_cookieList(args, context) {
|
||||
// Parse out an array of { key:..., value:... } objects for each cookie
|
||||
var doc = context.environment.contentDocument;
|
||||
var cookies = doc.cookie.split("; ").map(function(cookieStr) {
|
||||
var equalsPos = cookieStr.indexOf("=");
|
||||
return {
|
||||
key: cookieStr.substring(0, equalsPos),
|
||||
value: cookieStr.substring(equalsPos + 1)
|
||||
};
|
||||
});
|
||||
|
||||
return context.createView({
|
||||
html: cookieListHtml,
|
||||
data: {
|
||||
cookies: cookies,
|
||||
onclick: createUpdateHandler(context),
|
||||
ondblclick: createExecuteHandler(context),
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 'cookie remove' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "cookie remove",
|
||||
description: gcli.lookup("cookieRemoveDesc"),
|
||||
manual: gcli.lookup("cookieRemoveManual"),
|
||||
params: [
|
||||
{
|
||||
name: "key",
|
||||
type: "string",
|
||||
description: gcli.lookup("cookieRemoveKeyDesc"),
|
||||
}
|
||||
],
|
||||
exec: function Command_cookieRemove(args, context) {
|
||||
let document = context.environment.contentDocument;
|
||||
let expDate = new Date();
|
||||
expDate.setDate(expDate.getDate() - 1);
|
||||
document.cookie = escape(args.key) + "=; expires=" + expDate.toGMTString();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 'cookie set' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "cookie set",
|
||||
description: gcli.lookup("cookieSetDesc"),
|
||||
manual: gcli.lookup("cookieSetManual"),
|
||||
params: [
|
||||
{
|
||||
name: "key",
|
||||
type: "string",
|
||||
description: gcli.lookup("cookieSetKeyDesc")
|
||||
},
|
||||
{
|
||||
name: "value",
|
||||
type: "string",
|
||||
description: gcli.lookup("cookieSetValueDesc")
|
||||
},
|
||||
{
|
||||
group: gcli.lookup("cookieSetOptionsDesc"),
|
||||
params: [
|
||||
{
|
||||
name: "path",
|
||||
type: "string",
|
||||
defaultValue: "/",
|
||||
description: gcli.lookup("cookieSetPathDesc")
|
||||
},
|
||||
{
|
||||
name: "domain",
|
||||
type: "string",
|
||||
defaultValue: null,
|
||||
description: gcli.lookup("cookieSetDomainDesc")
|
||||
},
|
||||
{
|
||||
name: "secure",
|
||||
type: "boolean",
|
||||
description: gcli.lookup("cookieSetSecureDesc")
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
exec: function Command_cookieSet(args, context) {
|
||||
let document = context.environment.contentDocument;
|
||||
|
||||
document.cookie = escape(args.key) + "=" + escape(args.value) +
|
||||
(args.domain ? "; domain=" + args.domain : "") +
|
||||
(args.path ? "; path=" + args.path : "") +
|
||||
(args.secure ? "; secure" : "");
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Helper to find the 'data-command' attribute and call some action on it.
|
||||
* @see |updateCommand()| and |executeCommand()|
|
||||
*/
|
||||
function withCommand(element, action) {
|
||||
var command = element.getAttribute("data-command");
|
||||
if (!command) {
|
||||
command = element.querySelector("*[data-command]")
|
||||
.getAttribute("data-command");
|
||||
}
|
||||
|
||||
if (command) {
|
||||
action(command);
|
||||
}
|
||||
else {
|
||||
console.warn("Missing data-command for " + util.findCssSelector(element));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a handler to update the requisition to contain the text held in the
|
||||
* first matching data-command attribute under the currentTarget of the event.
|
||||
* @param context Either a Requisition or an ExecutionContext or another object
|
||||
* that contains an |update()| function that follows a similar contract.
|
||||
*/
|
||||
function createUpdateHandler(context) {
|
||||
return function(ev) {
|
||||
withCommand(ev.currentTarget, function(command) {
|
||||
context.update(command);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a handler to execute the text held in the data-command attribute
|
||||
* under the currentTarget of the event.
|
||||
* @param context Either a Requisition or an ExecutionContext or another object
|
||||
* that contains an |update()| function that follows a similar contract.
|
||||
*/
|
||||
function createExecuteHandler(context) {
|
||||
return function(ev) {
|
||||
withCommand(ev.currentTarget, function(command) {
|
||||
context.exec({
|
||||
visible: true,
|
||||
typed: command
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,176 +0,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/. */
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
|
||||
this.EXPORTED_SYMBOLS = [ ];
|
||||
|
||||
Cu.import("resource:///modules/devtools/gcli.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "gDevTools",
|
||||
"resource:///modules/devtools/gDevTools.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "TargetFactory",
|
||||
"resource:///modules/devtools/Target.jsm");
|
||||
|
||||
/**
|
||||
* 'dbg' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "dbg",
|
||||
description: gcli.lookup("dbgDesc"),
|
||||
manual: gcli.lookup("dbgManual")
|
||||
});
|
||||
|
||||
/**
|
||||
* 'dbg open' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "dbg open",
|
||||
description: gcli.lookup("dbgOpen"),
|
||||
params: [],
|
||||
exec: function (args, context) {
|
||||
let gBrowser = context.environment.chromeDocument.defaultView.gBrowser;
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
return gDevTools.showToolbox(target, "jsdebugger");
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 'dbg close' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "dbg close",
|
||||
description: gcli.lookup("dbgClose"),
|
||||
params: [],
|
||||
exec: function (args, context) {
|
||||
let gBrowser = context.environment.chromeDocument.defaultView.gBrowser;
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
return gDevTools.closeToolbox(target);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 'dbg interrupt' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "dbg interrupt",
|
||||
description: gcli.lookup("dbgInterrupt"),
|
||||
params: [],
|
||||
exec: function(args, context) {
|
||||
let dbg = getPanel(context, "jsdebugger");
|
||||
if (!dbg) {
|
||||
return gcli.lookup("debuggerStopped");
|
||||
}
|
||||
|
||||
let controller = dbg._controller;
|
||||
let thread = controller.activeThread;
|
||||
if (!thread.paused) {
|
||||
thread.interrupt();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 'dbg continue' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "dbg continue",
|
||||
description: gcli.lookup("dbgContinue"),
|
||||
params: [],
|
||||
exec: function(args, context) {
|
||||
let dbg = getPanel(context, "jsdebugger");
|
||||
if (!dbg) {
|
||||
return gcli.lookup("debuggerStopped");
|
||||
}
|
||||
|
||||
let controller = dbg._controller;
|
||||
let thread = controller.activeThread;
|
||||
if (thread.paused) {
|
||||
thread.resume();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 'dbg step' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "dbg step",
|
||||
description: gcli.lookup("dbgStepDesc"),
|
||||
manual: gcli.lookup("dbgStepManual")
|
||||
});
|
||||
|
||||
/**
|
||||
* 'dbg step over' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "dbg step over",
|
||||
description: gcli.lookup("dbgStepOverDesc"),
|
||||
params: [],
|
||||
exec: function(args, context) {
|
||||
let dbg = getPanel(context, "jsdebugger");
|
||||
if (!dbg) {
|
||||
return gcli.lookup("debuggerStopped");
|
||||
}
|
||||
|
||||
let controller = dbg._controller;
|
||||
let thread = controller.activeThread;
|
||||
if (thread.paused) {
|
||||
thread.stepOver();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 'dbg step in' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: 'dbg step in',
|
||||
description: gcli.lookup("dbgStepInDesc"),
|
||||
params: [],
|
||||
exec: function(args, context) {
|
||||
let dbg = getPanel(context, "jsdebugger");
|
||||
if (!dbg) {
|
||||
return gcli.lookup("debuggerStopped");
|
||||
}
|
||||
|
||||
let controller = dbg._controller;
|
||||
let thread = controller.activeThread;
|
||||
if (thread.paused) {
|
||||
thread.stepIn();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 'dbg step over' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: 'dbg step out',
|
||||
description: gcli.lookup("dbgStepOutDesc"),
|
||||
params: [],
|
||||
exec: function(args, context) {
|
||||
let dbg = getPanel(context, "jsdebugger");
|
||||
if (!dbg) {
|
||||
return gcli.lookup("debuggerStopped");
|
||||
}
|
||||
|
||||
let controller = dbg._controller;
|
||||
let thread = controller.activeThread;
|
||||
if (thread.paused) {
|
||||
thread.stepOut();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* A helper to go from a command context to a debugger panel
|
||||
*/
|
||||
function getPanel(context, id) {
|
||||
let gBrowser = context.environment.chromeDocument.defaultView.gBrowser;
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
let toolbox = gDevTools.getToolbox(target);
|
||||
return toolbox == null ? undefined : toolbox.getPanel(id);
|
||||
}
|
|
@ -1,29 +0,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/. */
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
|
||||
this.EXPORTED_SYMBOLS = [ ];
|
||||
|
||||
Cu.import("resource:///modules/devtools/gcli.jsm");
|
||||
|
||||
/**
|
||||
* 'echo' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "echo",
|
||||
description: gcli.lookup("echoDesc"),
|
||||
params: [
|
||||
{
|
||||
name: "message",
|
||||
type: "string",
|
||||
description: gcli.lookup("echoMessageDesc")
|
||||
}
|
||||
],
|
||||
returnType: "string",
|
||||
hidden: true,
|
||||
exec: function Command_echo(args, context) {
|
||||
return args.message;
|
||||
}
|
||||
});
|
|
@ -1,32 +0,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/. */
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
|
||||
this.EXPORTED_SYMBOLS = [ ];
|
||||
|
||||
Cu.import("resource:///modules/devtools/gcli.jsm");
|
||||
|
||||
/**
|
||||
* 'export' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "export",
|
||||
description: gcli.lookup("exportDesc"),
|
||||
});
|
||||
|
||||
/**
|
||||
* The 'export html' command. This command allows the user to export the page to
|
||||
* HTML after they do DOM changes.
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "export html",
|
||||
description: gcli.lookup("exportHtmlDesc"),
|
||||
exec: function(args, context) {
|
||||
let document = context.environment.contentDocument;
|
||||
let window = document.defaultView;
|
||||
let page = document.documentElement.outerHTML;
|
||||
window.open('data:text/plain;charset=utf8,' + encodeURIComponent(page));
|
||||
}
|
||||
});
|
|
@ -1,138 +0,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/. */
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
const XMLHttpRequest =
|
||||
Components.Constructor("@mozilla.org/xmlextras/xmlhttprequest;1");
|
||||
|
||||
this.EXPORTED_SYMBOLS = [ ];
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource:///modules/devtools/gcli.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "js_beautify",
|
||||
"resource:///modules/devtools/Jsbeautify.jsm");
|
||||
|
||||
/**
|
||||
* jsb command.
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: 'jsb',
|
||||
description: gcli.lookup('jsbDesc'),
|
||||
returnValue:'string',
|
||||
params: [
|
||||
{
|
||||
name: 'url',
|
||||
type: 'string',
|
||||
description: gcli.lookup('jsbUrlDesc')
|
||||
},
|
||||
{
|
||||
group: gcli.lookup("jsbOptionsDesc"),
|
||||
params: [
|
||||
{
|
||||
name: 'indentSize',
|
||||
type: 'number',
|
||||
description: gcli.lookup('jsbIndentSizeDesc'),
|
||||
manual: gcli.lookup('jsbIndentSizeManual'),
|
||||
defaultValue: 2
|
||||
},
|
||||
{
|
||||
name: 'indentChar',
|
||||
type: {
|
||||
name: 'selection',
|
||||
lookup: [
|
||||
{ name: "space", value: " " },
|
||||
{ name: "tab", value: "\t" }
|
||||
]
|
||||
},
|
||||
description: gcli.lookup('jsbIndentCharDesc'),
|
||||
manual: gcli.lookup('jsbIndentCharManual'),
|
||||
defaultValue: ' ',
|
||||
},
|
||||
{
|
||||
name: 'doNotPreserveNewlines',
|
||||
type: 'boolean',
|
||||
description: gcli.lookup('jsbDoNotPreserveNewlinesDesc')
|
||||
},
|
||||
{
|
||||
name: 'preserveMaxNewlines',
|
||||
type: 'number',
|
||||
description: gcli.lookup('jsbPreserveMaxNewlinesDesc'),
|
||||
manual: gcli.lookup('jsbPreserveMaxNewlinesManual'),
|
||||
defaultValue: -1
|
||||
},
|
||||
{
|
||||
name: 'jslintHappy',
|
||||
type: 'boolean',
|
||||
description: gcli.lookup('jsbJslintHappyDesc'),
|
||||
manual: gcli.lookup('jsbJslintHappyManual')
|
||||
},
|
||||
{
|
||||
name: 'braceStyle',
|
||||
type: {
|
||||
name: 'selection',
|
||||
data: ['collapse', 'expand', 'end-expand', 'expand-strict']
|
||||
},
|
||||
description: gcli.lookup('jsbBraceStyleDesc'),
|
||||
manual: gcli.lookup('jsbBraceStyleManual'),
|
||||
defaultValue: "collapse"
|
||||
},
|
||||
{
|
||||
name: 'noSpaceBeforeConditional',
|
||||
type: 'boolean',
|
||||
description: gcli.lookup('jsbNoSpaceBeforeConditionalDesc')
|
||||
},
|
||||
{
|
||||
name: 'unescapeStrings',
|
||||
type: 'boolean',
|
||||
description: gcli.lookup('jsbUnescapeStringsDesc'),
|
||||
manual: gcli.lookup('jsbUnescapeStringsManual')
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
exec: function(args, context) {
|
||||
let opts = {
|
||||
indent_size: args.indentSize,
|
||||
indent_char: args.indentChar,
|
||||
preserve_newlines: !args.doNotPreserveNewlines,
|
||||
max_preserve_newlines: args.preserveMaxNewlines == -1 ?
|
||||
undefined : args.preserveMaxNewlines,
|
||||
jslint_happy: args.jslintHappy,
|
||||
brace_style: args.braceStyle,
|
||||
space_before_conditional: !args.noSpaceBeforeConditional,
|
||||
unescape_strings: args.unescapeStrings
|
||||
};
|
||||
|
||||
let xhr = new XMLHttpRequest();
|
||||
|
||||
try {
|
||||
xhr.open("GET", args.url, true);
|
||||
} catch(e) {
|
||||
return gcli.lookup('jsbInvalidURL');
|
||||
}
|
||||
|
||||
let promise = context.createPromise();
|
||||
|
||||
xhr.onreadystatechange = function(aEvt) {
|
||||
if (xhr.readyState == 4) {
|
||||
if (xhr.status == 200 || xhr.status == 0) {
|
||||
let browserDoc = context.environment.chromeDocument;
|
||||
let browserWindow = browserDoc.defaultView;
|
||||
let gBrowser = browserWindow.gBrowser;
|
||||
let result = js_beautify(xhr.responseText, opts);
|
||||
|
||||
browserWindow.Scratchpad.ScratchpadManager.openScratchpad({text: result});
|
||||
|
||||
promise.resolve();
|
||||
} else {
|
||||
promise.resolve("Unable to load page to beautify: " + args.url + " " +
|
||||
xhr.status + " " + xhr.statusText);
|
||||
}
|
||||
};
|
||||
}
|
||||
xhr.send(null);
|
||||
return promise;
|
||||
}
|
||||
});
|
|
@ -1,264 +0,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/. */
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
|
||||
this.EXPORTED_SYMBOLS = [ ];
|
||||
|
||||
Cu.import("resource:///modules/devtools/gcli.jsm");
|
||||
|
||||
/**
|
||||
* 'pagemod' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "pagemod",
|
||||
description: gcli.lookup("pagemodDesc"),
|
||||
});
|
||||
|
||||
/**
|
||||
* The 'pagemod replace' command. This command allows the user to search and
|
||||
* replace within text nodes and attributes.
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "pagemod replace",
|
||||
description: gcli.lookup("pagemodReplaceDesc"),
|
||||
params: [
|
||||
{
|
||||
name: "search",
|
||||
type: "string",
|
||||
description: gcli.lookup("pagemodReplaceSearchDesc"),
|
||||
},
|
||||
{
|
||||
name: "replace",
|
||||
type: "string",
|
||||
description: gcli.lookup("pagemodReplaceReplaceDesc"),
|
||||
},
|
||||
{
|
||||
name: "ignoreCase",
|
||||
type: "boolean",
|
||||
description: gcli.lookup("pagemodReplaceIgnoreCaseDesc"),
|
||||
},
|
||||
{
|
||||
name: "selector",
|
||||
type: "string",
|
||||
description: gcli.lookup("pagemodReplaceSelectorDesc"),
|
||||
defaultValue: "*:not(script):not(style):not(embed):not(object):not(frame):not(iframe):not(frameset)",
|
||||
},
|
||||
{
|
||||
name: "root",
|
||||
type: "node",
|
||||
description: gcli.lookup("pagemodReplaceRootDesc"),
|
||||
defaultValue: null,
|
||||
},
|
||||
{
|
||||
name: "attrOnly",
|
||||
type: "boolean",
|
||||
description: gcli.lookup("pagemodReplaceAttrOnlyDesc"),
|
||||
},
|
||||
{
|
||||
name: "contentOnly",
|
||||
type: "boolean",
|
||||
description: gcli.lookup("pagemodReplaceContentOnlyDesc"),
|
||||
},
|
||||
{
|
||||
name: "attributes",
|
||||
type: "string",
|
||||
description: gcli.lookup("pagemodReplaceAttributesDesc"),
|
||||
defaultValue: null,
|
||||
},
|
||||
],
|
||||
exec: function(args, context) {
|
||||
let document = context.environment.contentDocument;
|
||||
let searchTextNodes = !args.attrOnly;
|
||||
let searchAttributes = !args.contentOnly;
|
||||
let regexOptions = args.ignoreCase ? 'ig' : 'g';
|
||||
let search = new RegExp(escapeRegex(args.search), regexOptions);
|
||||
let attributeRegex = null;
|
||||
if (args.attributes) {
|
||||
attributeRegex = new RegExp(args.attributes, regexOptions);
|
||||
}
|
||||
|
||||
let root = args.root || document;
|
||||
let elements = root.querySelectorAll(args.selector);
|
||||
elements = Array.prototype.slice.call(elements);
|
||||
|
||||
let replacedTextNodes = 0;
|
||||
let replacedAttributes = 0;
|
||||
|
||||
function replaceAttribute() {
|
||||
replacedAttributes++;
|
||||
return args.replace;
|
||||
}
|
||||
function replaceTextNode() {
|
||||
replacedTextNodes++;
|
||||
return args.replace;
|
||||
}
|
||||
|
||||
for (let i = 0; i < elements.length; i++) {
|
||||
let element = elements[i];
|
||||
if (searchTextNodes) {
|
||||
for (let y = 0; y < element.childNodes.length; y++) {
|
||||
let node = element.childNodes[y];
|
||||
if (node.nodeType == node.TEXT_NODE) {
|
||||
node.textContent = node.textContent.replace(search, replaceTextNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (searchAttributes) {
|
||||
if (!element.attributes) {
|
||||
continue;
|
||||
}
|
||||
for (let y = 0; y < element.attributes.length; y++) {
|
||||
let attr = element.attributes[y];
|
||||
if (!attributeRegex || attributeRegex.test(attr.name)) {
|
||||
attr.value = attr.value.replace(search, replaceAttribute);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return gcli.lookupFormat("pagemodReplaceResult",
|
||||
[elements.length, replacedTextNodes,
|
||||
replacedAttributes]);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 'pagemod remove' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "pagemod remove",
|
||||
description: gcli.lookup("pagemodRemoveDesc"),
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* The 'pagemod remove element' command.
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "pagemod remove element",
|
||||
description: gcli.lookup("pagemodRemoveElementDesc"),
|
||||
params: [
|
||||
{
|
||||
name: "search",
|
||||
type: "string",
|
||||
description: gcli.lookup("pagemodRemoveElementSearchDesc"),
|
||||
},
|
||||
{
|
||||
name: "root",
|
||||
type: "node",
|
||||
description: gcli.lookup("pagemodRemoveElementRootDesc"),
|
||||
defaultValue: null,
|
||||
},
|
||||
{
|
||||
name: 'stripOnly',
|
||||
type: 'boolean',
|
||||
description: gcli.lookup("pagemodRemoveElementStripOnlyDesc"),
|
||||
},
|
||||
{
|
||||
name: 'ifEmptyOnly',
|
||||
type: 'boolean',
|
||||
description: gcli.lookup("pagemodRemoveElementIfEmptyOnlyDesc"),
|
||||
},
|
||||
],
|
||||
exec: function(args, context) {
|
||||
let document = context.environment.contentDocument;
|
||||
let root = args.root || document;
|
||||
let elements = Array.prototype.slice.call(root.querySelectorAll(args.search));
|
||||
|
||||
let removed = 0;
|
||||
for (let i = 0; i < elements.length; i++) {
|
||||
let element = elements[i];
|
||||
let parentNode = element.parentNode;
|
||||
if (!parentNode || !element.removeChild) {
|
||||
continue;
|
||||
}
|
||||
if (args.stripOnly) {
|
||||
while (element.hasChildNodes()) {
|
||||
parentNode.insertBefore(element.childNodes[0], element);
|
||||
}
|
||||
}
|
||||
if (!args.ifEmptyOnly || !element.hasChildNodes()) {
|
||||
element.parentNode.removeChild(element);
|
||||
removed++;
|
||||
}
|
||||
}
|
||||
|
||||
return gcli.lookupFormat("pagemodRemoveElementResultMatchedAndRemovedElements",
|
||||
[elements.length, removed]);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* The 'pagemod remove attribute' command.
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "pagemod remove attribute",
|
||||
description: gcli.lookup("pagemodRemoveAttributeDesc"),
|
||||
params: [
|
||||
{
|
||||
name: "searchAttributes",
|
||||
type: "string",
|
||||
description: gcli.lookup("pagemodRemoveAttributeSearchAttributesDesc"),
|
||||
},
|
||||
{
|
||||
name: "searchElements",
|
||||
type: "string",
|
||||
description: gcli.lookup("pagemodRemoveAttributeSearchElementsDesc"),
|
||||
},
|
||||
{
|
||||
name: "root",
|
||||
type: "node",
|
||||
description: gcli.lookup("pagemodRemoveAttributeRootDesc"),
|
||||
defaultValue: null,
|
||||
},
|
||||
{
|
||||
name: "ignoreCase",
|
||||
type: "boolean",
|
||||
description: gcli.lookup("pagemodRemoveAttributeIgnoreCaseDesc"),
|
||||
},
|
||||
],
|
||||
exec: function(args, context) {
|
||||
let document = context.environment.contentDocument;
|
||||
|
||||
let root = args.root || document;
|
||||
let regexOptions = args.ignoreCase ? 'ig' : 'g';
|
||||
let attributeRegex = new RegExp(args.searchAttributes, regexOptions);
|
||||
let elements = root.querySelectorAll(args.searchElements);
|
||||
elements = Array.prototype.slice.call(elements);
|
||||
|
||||
let removed = 0;
|
||||
for (let i = 0; i < elements.length; i++) {
|
||||
let element = elements[i];
|
||||
if (!element.attributes) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var attrs = Array.prototype.slice.call(element.attributes);
|
||||
for (let y = 0; y < attrs.length; y++) {
|
||||
let attr = attrs[y];
|
||||
if (attributeRegex.test(attr.name)) {
|
||||
element.removeAttribute(attr.name);
|
||||
removed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return gcli.lookupFormat("pagemodRemoveAttributeResult",
|
||||
[elements.length, removed]);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Make a given string safe to use in a regular expression.
|
||||
*
|
||||
* @param string aString
|
||||
* The string you want to use in a regex.
|
||||
* @return string
|
||||
* The equivalent of |aString| but safe to use in a regex.
|
||||
*/
|
||||
function escapeRegex(aString) {
|
||||
return aString.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
|
||||
}
|
|
@ -1,54 +0,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/. */
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
|
||||
this.EXPORTED_SYMBOLS = [ ];
|
||||
|
||||
Cu.import("resource:///modules/devtools/gcli.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
/**
|
||||
* Restart command
|
||||
*
|
||||
* @param boolean nocache
|
||||
* Disables loading content from cache upon restart.
|
||||
*
|
||||
* Examples :
|
||||
* >> restart
|
||||
* - restarts browser immediately
|
||||
* >> restart --nocache
|
||||
* - restarts immediately and starts Firefox without using cache
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "restart",
|
||||
description: gcli.lookup("restartFirefoxDesc"),
|
||||
params: [
|
||||
{
|
||||
name: "nocache",
|
||||
type: "boolean",
|
||||
description: gcli.lookup("restartFirefoxNocacheDesc")
|
||||
}
|
||||
],
|
||||
returnType: "string",
|
||||
exec: function Restart(args, context) {
|
||||
let canceled = Cc["@mozilla.org/supports-PRBool;1"]
|
||||
.createInstance(Ci.nsISupportsPRBool);
|
||||
Services.obs.notifyObservers(canceled, "quit-application-requested", "restart");
|
||||
if (canceled.data) {
|
||||
return gcli.lookup("restartFirefoxRequestCancelled");
|
||||
}
|
||||
|
||||
// disable loading content from cache.
|
||||
if (args.nocache) {
|
||||
Services.appinfo.invalidateCachesOnRestart();
|
||||
}
|
||||
|
||||
// restart
|
||||
Cc['@mozilla.org/toolkit/app-startup;1']
|
||||
.getService(Ci.nsIAppStartup)
|
||||
.quit(Ci.nsIAppStartup.eAttemptQuit | Ci.nsIAppStartup.eRestart);
|
||||
return gcli.lookup("restartFirefoxRestarting");
|
||||
}
|
||||
});
|
|
@ -1,238 +0,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/. */
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
|
||||
this.EXPORTED_SYMBOLS = [ ];
|
||||
|
||||
Cu.import("resource:///modules/devtools/gcli.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "LayoutHelpers",
|
||||
"resource:///modules/devtools/LayoutHelpers.jsm");
|
||||
|
||||
// String used as an indication to generate default file name in the following
|
||||
// format: "Screen Shot yyyy-mm-dd at HH.MM.SS.png"
|
||||
const FILENAME_DEFAULT_VALUE = " ";
|
||||
|
||||
/**
|
||||
* 'screenshot' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "screenshot",
|
||||
description: gcli.lookup("screenshotDesc"),
|
||||
manual: gcli.lookup("screenshotManual"),
|
||||
returnType: "html",
|
||||
params: [
|
||||
{
|
||||
name: "filename",
|
||||
type: "string",
|
||||
defaultValue: FILENAME_DEFAULT_VALUE,
|
||||
description: gcli.lookup("screenshotFilenameDesc"),
|
||||
manual: gcli.lookup("screenshotFilenameManual")
|
||||
},
|
||||
{
|
||||
group: gcli.lookup("screenshotGroupOptions"),
|
||||
params: [
|
||||
{
|
||||
name: "clipboard",
|
||||
type: "boolean",
|
||||
description: gcli.lookup("screenshotClipboardDesc"),
|
||||
manual: gcli.lookup("screenshotClipboardManual")
|
||||
},
|
||||
{
|
||||
name: "chrome",
|
||||
type: "boolean",
|
||||
description: gcli.lookup("screenshotChromeDesc"),
|
||||
manual: gcli.lookup("screenshotChromeManual")
|
||||
},
|
||||
{
|
||||
name: "delay",
|
||||
type: { name: "number", min: 0 },
|
||||
defaultValue: 0,
|
||||
description: gcli.lookup("screenshotDelayDesc"),
|
||||
manual: gcli.lookup("screenshotDelayManual")
|
||||
},
|
||||
{
|
||||
name: "fullpage",
|
||||
type: "boolean",
|
||||
description: gcli.lookup("screenshotFullPageDesc"),
|
||||
manual: gcli.lookup("screenshotFullPageManual")
|
||||
},
|
||||
{
|
||||
name: "selector",
|
||||
type: "node",
|
||||
defaultValue: null,
|
||||
description: gcli.lookup("inspectNodeDesc"),
|
||||
manual: gcli.lookup("inspectNodeManual")
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
exec: function Command_screenshot(args, context) {
|
||||
if (args.chrome && args.selector) {
|
||||
// Node screenshot with chrome option does not work as inteded
|
||||
// Refer https://bugzilla.mozilla.org/show_bug.cgi?id=659268#c7
|
||||
// throwing for now.
|
||||
throw new Error(gcli.lookup("screenshotSelectorChromeConflict"));
|
||||
}
|
||||
var document = args.chrome? context.environment.chromeDocument
|
||||
: context.environment.contentDocument;
|
||||
if (args.delay > 0) {
|
||||
var promise = context.createPromise();
|
||||
document.defaultView.setTimeout(function Command_screenshotDelay() {
|
||||
let reply = this.grabScreen(document, args.filename, args.clipboard,
|
||||
args.fullpage);
|
||||
promise.resolve(reply);
|
||||
}.bind(this), args.delay * 1000);
|
||||
return promise;
|
||||
}
|
||||
else {
|
||||
return this.grabScreen(document, args.filename, args.clipboard,
|
||||
args.fullpage, args.selector);
|
||||
}
|
||||
},
|
||||
grabScreen:
|
||||
function Command_screenshotGrabScreen(document, filename, clipboard,
|
||||
fullpage, node) {
|
||||
let window = document.defaultView;
|
||||
let canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
|
||||
let left = 0;
|
||||
let top = 0;
|
||||
let width;
|
||||
let height;
|
||||
let div = document.createElementNS("http://www.w3.org/1999/xhtml", "div");
|
||||
|
||||
if (!fullpage) {
|
||||
if (!node) {
|
||||
left = window.scrollX;
|
||||
top = window.scrollY;
|
||||
width = window.innerWidth;
|
||||
height = window.innerHeight;
|
||||
} else {
|
||||
let rect = LayoutHelpers.getRect(node, window);
|
||||
top = rect.top;
|
||||
left = rect.left;
|
||||
width = rect.width;
|
||||
height = rect.height;
|
||||
}
|
||||
} else {
|
||||
width = window.innerWidth + window.scrollMaxX;
|
||||
height = window.innerHeight + window.scrollMaxY;
|
||||
}
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
|
||||
let ctx = canvas.getContext("2d");
|
||||
ctx.drawWindow(window, left, top, width, height, "#fff");
|
||||
let data = canvas.toDataURL("image/png", "");
|
||||
|
||||
let loadContext = document.defaultView
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsILoadContext);
|
||||
|
||||
try {
|
||||
if (clipboard) {
|
||||
let io = Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(Ci.nsIIOService);
|
||||
let channel = io.newChannel(data, null, null);
|
||||
let input = channel.open();
|
||||
let imgTools = Cc["@mozilla.org/image/tools;1"]
|
||||
.getService(Ci.imgITools);
|
||||
|
||||
let container = {};
|
||||
imgTools.decodeImageData(input, channel.contentType, container);
|
||||
|
||||
let wrapped = Cc["@mozilla.org/supports-interface-pointer;1"]
|
||||
.createInstance(Ci.nsISupportsInterfacePointer);
|
||||
wrapped.data = container.value;
|
||||
|
||||
let trans = Cc["@mozilla.org/widget/transferable;1"]
|
||||
.createInstance(Ci.nsITransferable);
|
||||
trans.init(loadContext);
|
||||
trans.addDataFlavor(channel.contentType);
|
||||
trans.setTransferData(channel.contentType, wrapped, -1);
|
||||
|
||||
let clipid = Ci.nsIClipboard;
|
||||
let clip = Cc["@mozilla.org/widget/clipboard;1"].getService(clipid);
|
||||
clip.setData(trans, null, clipid.kGlobalClipboard);
|
||||
div.textContent = gcli.lookup("screenshotCopied");
|
||||
return div;
|
||||
}
|
||||
}
|
||||
catch (ex) {
|
||||
div.textContent = gcli.lookup("screenshotErrorCopying");
|
||||
return div;
|
||||
}
|
||||
|
||||
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
|
||||
|
||||
// Create a name for the file if not present
|
||||
if (filename == FILENAME_DEFAULT_VALUE) {
|
||||
let date = new Date();
|
||||
let dateString = date.getFullYear() + "-" + (date.getMonth() + 1) +
|
||||
"-" + date.getDate();
|
||||
dateString = dateString.split("-").map(function(part) {
|
||||
if (part.length == 1) {
|
||||
part = "0" + part;
|
||||
}
|
||||
return part;
|
||||
}).join("-");
|
||||
let timeString = date.toTimeString().replace(/:/g, ".").split(" ")[0];
|
||||
filename = gcli.lookupFormat("screenshotGeneratedFilename",
|
||||
[dateString, timeString]) + ".png";
|
||||
}
|
||||
// Check there is a .png extension to filename
|
||||
else if (!filename.match(/.png$/i)) {
|
||||
filename += ".png";
|
||||
}
|
||||
|
||||
// If the filename is relative, tack it onto the download directory
|
||||
if (!filename.match(/[\\\/]/)) {
|
||||
let downloadMgr = Cc["@mozilla.org/download-manager;1"]
|
||||
.getService(Ci.nsIDownloadManager);
|
||||
let tempfile = downloadMgr.userDownloadsDirectory;
|
||||
tempfile.append(filename);
|
||||
filename = tempfile.path;
|
||||
}
|
||||
|
||||
try {
|
||||
file.initWithPath(filename);
|
||||
} catch (ex) {
|
||||
div.textContent = gcli.lookup("screenshotErrorSavingToFile") + " " + filename;
|
||||
return div;
|
||||
}
|
||||
|
||||
let ioService = Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(Ci.nsIIOService);
|
||||
|
||||
let Persist = Ci.nsIWebBrowserPersist;
|
||||
let persist = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
|
||||
.createInstance(Persist);
|
||||
persist.persistFlags = Persist.PERSIST_FLAGS_REPLACE_EXISTING_FILES |
|
||||
Persist.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
|
||||
|
||||
let source = ioService.newURI(data, "UTF8", null);
|
||||
persist.saveURI(source, null, null, null, null, file, loadContext);
|
||||
|
||||
div.textContent = gcli.lookup("screenshotSavedToFile") + " \"" + filename +
|
||||
"\"";
|
||||
div.addEventListener("click", function openFile() {
|
||||
div.removeEventListener("click", openFile);
|
||||
file.reveal();
|
||||
});
|
||||
div.style.cursor = "pointer";
|
||||
let image = document.createElement("div");
|
||||
let previewHeight = parseInt(256*height/width);
|
||||
image.setAttribute("style",
|
||||
"width:256px; height:" + previewHeight + "px;" +
|
||||
"max-height: 256px;" +
|
||||
"background-image: url('" + data + "');" +
|
||||
"background-size: 256px " + previewHeight + "px;" +
|
||||
"margin: 4px; display: block");
|
||||
div.appendChild(image);
|
||||
return div;
|
||||
}
|
||||
});
|
|
@ -7,21 +7,9 @@ this.EXPORTED_SYMBOLS = [ ];
|
|||
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource:///modules/devtools/CmdAddon.jsm");
|
||||
Cu.import("resource:///modules/devtools/CmdBreak.jsm");
|
||||
Cu.import("resource:///modules/devtools/CmdCalllog.jsm");
|
||||
Cu.import("resource:///modules/devtools/CmdCalllogChrome.jsm");
|
||||
Cu.import("resource:///modules/devtools/CmdConsole.jsm");
|
||||
Cu.import("resource:///modules/devtools/CmdCookie.jsm");
|
||||
Cu.import("resource:///modules/devtools/CmdDbg.jsm");
|
||||
Cu.import("resource:///modules/devtools/CmdEcho.jsm");
|
||||
Cu.import("resource:///modules/devtools/BuiltinCommands.jsm");
|
||||
Cu.import("resource:///modules/devtools/CmdEdit.jsm");
|
||||
Cu.import("resource:///modules/devtools/CmdExport.jsm");
|
||||
Cu.import("resource:///modules/devtools/CmdInspect.jsm");
|
||||
Cu.import("resource:///modules/devtools/CmdJsb.jsm");
|
||||
Cu.import("resource:///modules/devtools/CmdPagemod.jsm");
|
||||
Cu.import("resource:///modules/devtools/CmdResize.jsm");
|
||||
Cu.import("resource:///modules/devtools/CmdRestart.jsm");
|
||||
Cu.import("resource:///modules/devtools/CmdScreenshot.jsm");
|
||||
Cu.import("resource:///modules/devtools/CmdTilt.jsm");
|
||||
Cu.import("resource:///modules/devtools/CmdScratchpad.jsm");
|
||||
|
|
|
@ -2436,7 +2436,6 @@ function Parameter(paramSpec, command, groupName) {
|
|||
this.name = this.paramSpec.name;
|
||||
this.type = this.paramSpec.type;
|
||||
this.groupName = groupName;
|
||||
this.defaultValue = this.paramSpec.defaultValue;
|
||||
|
||||
if (!this.name) {
|
||||
throw new Error('In ' + this.command.name +
|
||||
|
@ -2453,22 +2452,20 @@ function Parameter(paramSpec, command, groupName) {
|
|||
|
||||
// boolean parameters have an implicit defaultValue:false, which should
|
||||
// not be changed. See the docs.
|
||||
if (this.type instanceof BooleanType) {
|
||||
if (this.defaultValue !== undefined) {
|
||||
throw new Error('In ' + this.command.name + '/' + this.name +
|
||||
': boolean parameters can not have a defaultValue.' +
|
||||
' Ignoring');
|
||||
}
|
||||
this.defaultValue = false;
|
||||
if (this.type instanceof BooleanType &&
|
||||
this.paramSpec.defaultValue !== undefined) {
|
||||
throw new Error('In ' + this.command.name + '/' + this.name +
|
||||
': boolean parameters can not have a defaultValue.' +
|
||||
' Ignoring');
|
||||
}
|
||||
|
||||
// Check the defaultValue for validity.
|
||||
// Both undefined and null get a pass on this test. undefined is used when
|
||||
// there is no defaultValue, and null is used when the parameter is
|
||||
// optional, neither are required to parse and stringify.
|
||||
if (this.defaultValue != null) {
|
||||
if (this._defaultValue != null) {
|
||||
try {
|
||||
var defaultText = this.type.stringify(this.defaultValue);
|
||||
var defaultText = this.type.stringify(this.paramSpec.defaultValue);
|
||||
var defaultConversion = this.type.parseString(defaultText);
|
||||
if (defaultConversion.getStatus() !== Status.VALID) {
|
||||
throw new Error('In ' + this.command.name + '/' + this.name +
|
||||
|
@ -2482,20 +2479,31 @@ function Parameter(paramSpec, command, groupName) {
|
|||
}
|
||||
}
|
||||
|
||||
// Some types (boolean, array) have a non 'undefined' blank value. Give the
|
||||
// type a chance to override the default defaultValue of undefined
|
||||
if (this.defaultValue === undefined) {
|
||||
this.defaultValue = this.type.getBlank().value;
|
||||
}
|
||||
|
||||
// All parameters that can only be set via a named parameter must have a
|
||||
// non-undefined default value
|
||||
if (!this.isPositionalAllowed && this.defaultValue === undefined) {
|
||||
if (!this.isPositionalAllowed && this.paramSpec.defaultValue === undefined &&
|
||||
this.type.getBlank == null && !(this.type instanceof BooleanType)) {
|
||||
throw new Error('In ' + this.command.name + '/' + this.name +
|
||||
': Missing defaultValue for optional parameter.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* type.getBlank can be expensive, so we delay execution where we can
|
||||
*/
|
||||
Object.defineProperty(Parameter.prototype, 'defaultValue', {
|
||||
get: function() {
|
||||
if (!('_defaultValue' in this)) {
|
||||
this._defaultValue = (this.paramSpec.defaultValue !== undefined) ?
|
||||
this.paramSpec.defaultValue :
|
||||
this.type.getBlank().value;
|
||||
}
|
||||
|
||||
return this._defaultValue;
|
||||
},
|
||||
enumerable : true
|
||||
});
|
||||
|
||||
/**
|
||||
* Does the given name uniquely identify this param (among the other params
|
||||
* in this command)
|
||||
|
@ -2689,11 +2697,10 @@ canon.onCanonChange = util.createEvent('canon.onCanonChange');
|
|||
* CommandOutputManager stores the output objects generated by executed
|
||||
* commands.
|
||||
*
|
||||
* CommandOutputManager is exposed (via canon.commandOutputManager) to the the
|
||||
* outside world and could (but shouldn't) be used before gcli.startup() has
|
||||
* been called. This could should be defensive to that where possible, and we
|
||||
* should certainly document if the use of it or similar will fail if used too
|
||||
* soon.
|
||||
* CommandOutputManager is exposed to the the outside world and could (but
|
||||
* shouldn't) be used before gcli.startup() has been called.
|
||||
* This could should be defensive to that where possible, and we should
|
||||
* certainly document if the use of it or similar will fail if used too soon.
|
||||
*/
|
||||
function CommandOutputManager() {
|
||||
this.onOutput = util.createEvent('CommandOutputManager.onOutput');
|
||||
|
@ -2701,12 +2708,6 @@ function CommandOutputManager() {
|
|||
|
||||
canon.CommandOutputManager = CommandOutputManager;
|
||||
|
||||
/**
|
||||
* We maintain a global command output manager for the majority case where
|
||||
* there is only one important set of outputs.
|
||||
*/
|
||||
canon.commandOutputManager = new CommandOutputManager();
|
||||
|
||||
|
||||
});
|
||||
/*
|
||||
|
@ -2736,6 +2737,18 @@ define('gcli/util', ['require', 'exports', 'module' ], function(require, exports
|
|||
|
||||
var eventDebug = false;
|
||||
|
||||
/**
|
||||
* Patch up broken console API from node
|
||||
*/
|
||||
if (eventDebug) {
|
||||
if (console.group == null) {
|
||||
console.group = function() { console.log(arguments); };
|
||||
}
|
||||
if (console.groupEnd == null) {
|
||||
console.groupEnd = function() { console.log(arguments); };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Useful way to create a name for a handler, used in createEvent()
|
||||
*/
|
||||
|
@ -2817,6 +2830,10 @@ exports.createEvent = function(name) {
|
|||
* @param scope Optional 'this' object for the function call
|
||||
*/
|
||||
event.add = function(func, scope) {
|
||||
if (eventDebug) {
|
||||
console.log('Adding listener to ' + name);
|
||||
}
|
||||
|
||||
handlers.push({ func: func, scope: scope });
|
||||
};
|
||||
|
||||
|
@ -2827,16 +2844,20 @@ exports.createEvent = function(name) {
|
|||
* @param scope Optional 'this' object for the function call
|
||||
*/
|
||||
event.remove = function(func, scope) {
|
||||
if (eventDebug) {
|
||||
console.log('Removing listener from ' + name);
|
||||
}
|
||||
|
||||
var found = false;
|
||||
handlers = handlers.filter(function(test) {
|
||||
var noMatch = (test.func !== func && test.scope !== scope);
|
||||
if (!noMatch) {
|
||||
var match = (test.func === func && test.scope === scope);
|
||||
if (match) {
|
||||
found = true;
|
||||
}
|
||||
return noMatch;
|
||||
return !match;
|
||||
});
|
||||
if (!found) {
|
||||
console.warn('Failed to remove handler from ' + name);
|
||||
console.warn('Handler not found. Attached to ' + name);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -4057,6 +4078,7 @@ exports.setDocument = function(document) {
|
|||
*/
|
||||
exports.unsetDocument = function() {
|
||||
doc = undefined;
|
||||
exports._empty = undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -4686,26 +4708,8 @@ imports.XPCOMUtils.defineLazyGetter(imports, 'supportsString', function() {
|
|||
var util = require('gcli/util');
|
||||
var types = require('gcli/types');
|
||||
|
||||
var allSettings = [];
|
||||
|
||||
/**
|
||||
* Cache existing settings on startup
|
||||
*/
|
||||
exports.startup = function() {
|
||||
imports.prefBranch.getChildList('').forEach(function(name) {
|
||||
allSettings.push(new Setting(name));
|
||||
}.bind(this));
|
||||
allSettings.sort(function(s1, s2) {
|
||||
return s1.name.localeCompare(s2.name);
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
exports.shutdown = function() {
|
||||
allSettings = [];
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* All local settings have this prefix when used in Firefox
|
||||
*/
|
||||
var DEVTOOLS_PREFIX = 'devtools.gcli.';
|
||||
|
||||
|
@ -4824,14 +4828,76 @@ Setting.prototype.setDefault = function() {
|
|||
Services.prefs.savePrefFile(null);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 'static' function to get an array containing all known Settings
|
||||
* Collection of preferences for sorted access
|
||||
*/
|
||||
var settingsAll = [];
|
||||
|
||||
/**
|
||||
* Collection of preferences for fast indexed access
|
||||
*/
|
||||
var settingsMap = new Map();
|
||||
|
||||
/**
|
||||
* Flag so we know if we've read the system preferences
|
||||
*/
|
||||
var hasReadSystem = false;
|
||||
|
||||
/**
|
||||
* Clear out all preferences and return to initial state
|
||||
*/
|
||||
function reset() {
|
||||
settingsMap = new Map();
|
||||
settingsAll = [];
|
||||
hasReadSystem = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset everything on startup and shutdown because we're doing lazy loading
|
||||
*/
|
||||
exports.startup = function() {
|
||||
reset();
|
||||
};
|
||||
|
||||
exports.shutdown = function() {
|
||||
reset();
|
||||
};
|
||||
|
||||
/**
|
||||
* Load system prefs if they've not been loaded already
|
||||
* @return true
|
||||
*/
|
||||
function readSystem() {
|
||||
if (hasReadSystem) {
|
||||
return;
|
||||
}
|
||||
|
||||
imports.prefBranch.getChildList('').forEach(function(name) {
|
||||
var setting = new Setting(name);
|
||||
settingsAll.push(setting);
|
||||
settingsMap.set(name, setting);
|
||||
});
|
||||
|
||||
settingsAll.sort(function(s1, s2) {
|
||||
return s1.name.localeCompare(s2.name);
|
||||
});
|
||||
|
||||
hasReadSystem = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array containing all known Settings filtered to match the given
|
||||
* filter (string) at any point in the name of the setting
|
||||
*/
|
||||
exports.getAll = function(filter) {
|
||||
readSystem();
|
||||
|
||||
if (filter == null) {
|
||||
return allSettings;
|
||||
return settingsAll;
|
||||
}
|
||||
return allSettings.filter(function(setting) {
|
||||
|
||||
return settingsAll.filter(function(setting) {
|
||||
return setting.name.indexOf(filter) !== -1;
|
||||
});
|
||||
};
|
||||
|
@ -4841,12 +4907,19 @@ exports.getAll = function(filter) {
|
|||
*/
|
||||
exports.addSetting = function(prefSpec) {
|
||||
var setting = new Setting(prefSpec);
|
||||
for (var i = 0; i < allSettings.length; i++) {
|
||||
if (allSettings[i].name === setting.name) {
|
||||
allSettings[i] = setting;
|
||||
|
||||
if (settingsMap.has(setting.name)) {
|
||||
// Once exists already, we're going to need to replace it in the array
|
||||
for (var i = 0; i < settingsAll.length; i++) {
|
||||
if (settingsAll[i].name === setting.name) {
|
||||
settingsAll[i] = setting;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
settingsMap.set(setting.name, setting);
|
||||
exports.onChange({ added: setting.name });
|
||||
|
||||
return setting;
|
||||
};
|
||||
|
||||
|
@ -4860,15 +4933,20 @@ exports.addSetting = function(prefSpec) {
|
|||
* @return The found Setting object, or undefined if the setting was not found
|
||||
*/
|
||||
exports.getSetting = function(name) {
|
||||
var found = undefined;
|
||||
allSettings.some(function(setting) {
|
||||
if (setting.name === name) {
|
||||
found = setting;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
return found;
|
||||
// We might be able to give the answer without needing to read all system
|
||||
// settings if this is an internal setting
|
||||
var found = settingsMap.get(name);
|
||||
if (found) {
|
||||
return found;
|
||||
}
|
||||
|
||||
if (hasReadSystem) {
|
||||
return undefined;
|
||||
}
|
||||
else {
|
||||
readSystem();
|
||||
return settingsMap.get(name);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -4879,8 +4957,7 @@ exports.onChange = util.createEvent('Settings.onChange');
|
|||
/**
|
||||
* Remove a setting. A no-op in this case
|
||||
*/
|
||||
exports.removeSetting = function(nameOrSpec) {
|
||||
};
|
||||
exports.removeSetting = function() { };
|
||||
|
||||
|
||||
});
|
||||
|
@ -5109,6 +5186,7 @@ var l10n = require('gcli/l10n');
|
|||
|
||||
var canon = require('gcli/canon');
|
||||
var Q = require('gcli/promise');
|
||||
var CommandOutputManager = require('gcli/canon').CommandOutputManager;
|
||||
|
||||
var Status = require('gcli/types').Status;
|
||||
var Conversion = require('gcli/types').Conversion;
|
||||
|
@ -5467,9 +5545,11 @@ UnassignedAssignment.prototype.getStatus = function(arg) {
|
|||
* @param doc A DOM Document passed to commands using the Execution Context in
|
||||
* order to allow creation of DOM nodes. If missing Requisition will use the
|
||||
* global 'document'.
|
||||
* @param commandOutputManager A custom commandOutputManager to which output
|
||||
* should be sent (optional)
|
||||
* @constructor
|
||||
*/
|
||||
function Requisition(environment, doc) {
|
||||
function Requisition(environment, doc, commandOutputManager) {
|
||||
this.environment = environment;
|
||||
this.document = doc;
|
||||
if (this.document == null) {
|
||||
|
@ -5480,6 +5560,7 @@ function Requisition(environment, doc) {
|
|||
// Ignore
|
||||
}
|
||||
}
|
||||
this.commandOutputManager = commandOutputManager || new CommandOutputManager();
|
||||
|
||||
// The command that we are about to execute.
|
||||
// @see setCommandConversion()
|
||||
|
@ -5510,8 +5591,6 @@ function Requisition(environment, doc) {
|
|||
this.commandAssignment.onAssignmentChange.add(this._commandAssignmentChanged, this);
|
||||
this.commandAssignment.onAssignmentChange.add(this._assignmentChanged, this);
|
||||
|
||||
this.commandOutputManager = canon.commandOutputManager;
|
||||
|
||||
this.onAssignmentChange = util.createEvent('Requisition.onAssignmentChange');
|
||||
this.onTextChange = util.createEvent('Requisition.onTextChange');
|
||||
}
|
||||
|
@ -6992,21 +7071,21 @@ exports.shutdown = function() {
|
|||
* @param options Object containing user customization properties, including:
|
||||
* - blurDelay (default=150ms)
|
||||
* - debug (default=false)
|
||||
* - commandOutputManager (default=canon.commandOutputManager)
|
||||
* @param components Object that links to other UI components. GCLI provided:
|
||||
* - document
|
||||
* - requisition
|
||||
*/
|
||||
function FocusManager(options, components) {
|
||||
options = options || {};
|
||||
|
||||
this._document = components.document || document;
|
||||
this._requisition = components.requisition;
|
||||
|
||||
this._debug = options.debug || false;
|
||||
this._blurDelay = options.blurDelay || 150;
|
||||
this._window = this._document.defaultView;
|
||||
|
||||
this._commandOutputManager = options.commandOutputManager ||
|
||||
canon.commandOutputManager;
|
||||
this._commandOutputManager.onOutput.add(this._outputted, this);
|
||||
this._requisition.commandOutputManager.onOutput.add(this._outputted, this);
|
||||
|
||||
this._blurDelayTimeout = null; // Result of setTimeout in delaying a blur
|
||||
this._monitoredElements = []; // See addMonitoredElement()
|
||||
|
@ -7035,7 +7114,7 @@ FocusManager.prototype.destroy = function() {
|
|||
eagerHelper.onChange.remove(this._eagerHelperChanged, this);
|
||||
|
||||
this._document.removeEventListener('focus', this._focused, true);
|
||||
this._commandOutputManager.onOutput.remove(this._outputted, this);
|
||||
this._requisition.commandOutputManager.onOutput.remove(this._outputted, this);
|
||||
|
||||
for (var i = 0; i < this._monitoredElements.length; i++) {
|
||||
var monitor = this._monitoredElements[i];
|
||||
|
@ -7053,7 +7132,7 @@ FocusManager.prototype.destroy = function() {
|
|||
delete this._focused;
|
||||
delete this._document;
|
||||
delete this._window;
|
||||
delete this._commandOutputManager;
|
||||
delete this._requisition;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -9012,7 +9091,7 @@ var resource = require('gcli/types/resource');
|
|||
var host = require('gcli/host');
|
||||
var intro = require('gcli/ui/intro');
|
||||
|
||||
var commandOutputManager = require('gcli/canon').commandOutputManager;
|
||||
var CommandOutputManager = require('gcli/canon').CommandOutputManager;
|
||||
|
||||
/**
|
||||
* Handy utility to inject the content document (i.e. for the viewed page,
|
||||
|
@ -9048,6 +9127,7 @@ function setContentDocument(document) {
|
|||
* - environment
|
||||
* - scratchpad (optional)
|
||||
* - chromeWindow
|
||||
* - commandOutputManager (optional)
|
||||
*/
|
||||
function FFDisplay(options) {
|
||||
if (options.eval) {
|
||||
|
@ -9056,13 +9136,19 @@ function FFDisplay(options) {
|
|||
setContentDocument(options.contentDocument);
|
||||
host.chromeWindow = options.chromeWindow;
|
||||
|
||||
this.onOutput = commandOutputManager.onOutput;
|
||||
this.requisition = new Requisition(options.environment, options.outputDocument);
|
||||
this.commandOutputManager = options.commandOutputManager;
|
||||
if (this.commandOutputManager == null) {
|
||||
this.commandOutputManager = new CommandOutputManager();
|
||||
}
|
||||
|
||||
this.onOutput = this.commandOutputManager.onOutput;
|
||||
this.requisition = new Requisition(options.environment,
|
||||
options.outputDocument,
|
||||
this.commandOutputManager);
|
||||
|
||||
// Create a FocusManager for the various parts to register with
|
||||
this.focusManager = new FocusManager(options, {
|
||||
// TODO: can we kill chromeDocument here?
|
||||
document: options.chromeDocument
|
||||
document: options.chromeDocument,
|
||||
requisition: this.requisition,
|
||||
});
|
||||
this.onVisibilityChange = this.focusManager.onVisibilityChange;
|
||||
|
||||
|
@ -9106,7 +9192,7 @@ function FFDisplay(options) {
|
|||
* separate method
|
||||
*/
|
||||
FFDisplay.prototype.maybeShowIntro = function() {
|
||||
intro.maybeShowIntro(commandOutputManager);
|
||||
intro.maybeShowIntro(this.commandOutputManager);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -9151,7 +9237,7 @@ FFDisplay.prototype.destroy = function() {
|
|||
// DOM node hunter script from looking in all the nooks and crannies, so it's
|
||||
// better if we can be leak-free without deleting them:
|
||||
// - consoleWrap, resizer, tooltip, completer, inputter,
|
||||
// - focusManager, onVisibilityChange, requisition
|
||||
// - focusManager, onVisibilityChange, requisition, commandOutputManager
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -9945,7 +10031,8 @@ function Completer(options, components) {
|
|||
this.inputter.onAssignmentChange.add(this.update, this);
|
||||
this.inputter.onChoiceChange.add(this.update, this);
|
||||
|
||||
if (components.autoResize) {
|
||||
this.autoResize = components.autoResize;
|
||||
if (this.autoResize) {
|
||||
this.inputter.onResize.add(this.resized, this);
|
||||
|
||||
var dimensions = this.inputter.getDimensions();
|
||||
|
@ -9968,7 +10055,10 @@ Completer.prototype.destroy = function() {
|
|||
this.inputter.onInputChange.remove(this.update, this);
|
||||
this.inputter.onAssignmentChange.remove(this.update, this);
|
||||
this.inputter.onChoiceChange.remove(this.update, this);
|
||||
this.inputter.onResize.remove(this.resized, this);
|
||||
|
||||
if (this.autoResize) {
|
||||
this.inputter.onResize.remove(this.resized, this);
|
||||
}
|
||||
|
||||
delete this.document;
|
||||
delete this.element;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
// Tests that the addon commands works as they should
|
||||
|
||||
let imported = {};
|
||||
Components.utils.import("resource:///modules/devtools/CmdAddon.jsm", imported);
|
||||
Components.utils.import("resource:///modules/devtools/BuiltinCommands.jsm", imported);
|
||||
|
||||
function test() {
|
||||
DeveloperToolbarTest.test("about:blank", [ GAT_test ]);
|
||||
|
@ -96,7 +96,7 @@ function GAT_test() {
|
|||
|
||||
Services.obs.addObserver(GAT_ready, "gcli_addon_commands_ready", false);
|
||||
|
||||
if (imported.Flags.addonsLoaded) {
|
||||
if (imported.CmdAddonFlags.addonsLoaded) {
|
||||
info("The getAllAddons command has already completed and we have missed ");
|
||||
info("the notification. Let's send the gcli_addon_commands_ready ");
|
||||
info("notification ourselves.");
|
||||
|
|
|
@ -42,7 +42,7 @@ function test() {
|
|||
|
||||
|
||||
var Requisition = require('gcli/cli').Requisition;
|
||||
var canon = require('gcli/canon');
|
||||
var CommandOutputManager = require('gcli/canon').CommandOutputManager;
|
||||
// var mockCommands = require('gclitest/mockCommands');
|
||||
var nodetype = require('gcli/types/node');
|
||||
|
||||
|
@ -53,16 +53,22 @@ var actualOutput;
|
|||
var hideExec = false;
|
||||
var skip = 'skip';
|
||||
|
||||
exports.setup = function() {
|
||||
var environment = { value: 'example environment data' };
|
||||
var commandOutputManager = new CommandOutputManager();
|
||||
var requisition = new Requisition(environment, null, commandOutputManager);
|
||||
|
||||
exports.setup = function(options) {
|
||||
mockCommands.setup();
|
||||
mockCommands.onCommandExec.add(commandExeced);
|
||||
canon.commandOutputManager.onOutput.add(commandOutputed);
|
||||
|
||||
commandOutputManager.onOutput.add(commandOutputed);
|
||||
};
|
||||
|
||||
exports.shutdown = function() {
|
||||
exports.shutdown = function(options) {
|
||||
mockCommands.shutdown();
|
||||
mockCommands.onCommandExec.remove(commandExeced);
|
||||
canon.commandOutputManager.onOutput.remove(commandOutputed);
|
||||
|
||||
commandOutputManager.onOutput.remove(commandOutputed);
|
||||
};
|
||||
|
||||
function commandExeced(ev) {
|
||||
|
@ -74,9 +80,6 @@ function commandOutputed(ev) {
|
|||
}
|
||||
|
||||
function exec(command, expectedArgs) {
|
||||
var environment = {};
|
||||
|
||||
var requisition = new Requisition(environment);
|
||||
var outputObject = requisition.exec({ typed: command, hidden: hideExec });
|
||||
|
||||
assert.is(command.indexOf(actualExec.command.name), 0, 'Command name: ' + command);
|
||||
|
|
|
@ -1739,12 +1739,11 @@ create({ constructor: GlobalSearchView, proto: MenuContainer.prototype }, {
|
|||
*/
|
||||
_bounceMatch: function DVGS__bounceMatch(aMatch) {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
aMatch.setAttribute("focused", "");
|
||||
|
||||
aMatch.addEventListener("transitionend", function onEvent() {
|
||||
aMatch.removeEventListener("transitionend", onEvent);
|
||||
aMatch.removeAttribute("focused");
|
||||
});
|
||||
aMatch.setAttribute("focused", "");
|
||||
}}, 0);
|
||||
},
|
||||
|
||||
|
|
|
@ -113,7 +113,8 @@ ToolbarView.prototype = {
|
|||
_onTogglePanesPressed: function DVT__onTogglePanesPressed() {
|
||||
DebuggerView.togglePanes({
|
||||
visible: DebuggerView.panesHidden,
|
||||
animated: true
|
||||
animated: true,
|
||||
delayed: true
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -1056,6 +1057,7 @@ create({ constructor: FilteredSourcesView, proto: MenuContainer.prototype }, {
|
|||
let panel = this._panel = document.createElement("panel");
|
||||
panel.id = "filtered-sources-panel";
|
||||
panel.setAttribute("noautofocus", "true");
|
||||
panel.setAttribute("level", "top");
|
||||
panel.setAttribute("position", FILTERED_SOURCES_POPUP_POSITION);
|
||||
document.documentElement.appendChild(panel);
|
||||
|
||||
|
|
|
@ -394,47 +394,61 @@ let DebuggerView = {
|
|||
* An object containing some of the following boolean properties:
|
||||
* - visible: true if the pane should be shown, false for hidden
|
||||
* - animated: true to display an animation on toggle
|
||||
* - delayed: true to wait a few cycles before toggle
|
||||
* - callback: a function to invoke when the panes toggle finishes
|
||||
*/
|
||||
togglePanes: function DV__togglePanes(aFlags = {}) {
|
||||
// Avoid useless toggles.
|
||||
if (aFlags.visible == !this.panesHidden) {
|
||||
aFlags.callback && aFlags.callback();
|
||||
if (aFlags.callback) aFlags.callback();
|
||||
return;
|
||||
}
|
||||
|
||||
if (aFlags.visible) {
|
||||
this._stackframesAndBreakpoints.style.marginLeft = "0";
|
||||
this._variablesAndExpressions.style.marginRight = "0";
|
||||
this._togglePanesButton.removeAttribute("panesHidden");
|
||||
this._togglePanesButton.setAttribute("tooltiptext", L10N.getStr("collapsePanes"));
|
||||
} else {
|
||||
let marginL = ~~(this._stackframesAndBreakpoints.getAttribute("width")) + 1;
|
||||
let marginR = ~~(this._variablesAndExpressions.getAttribute("width")) + 1;
|
||||
this._stackframesAndBreakpoints.style.marginLeft = -marginL + "px";
|
||||
this._variablesAndExpressions.style.marginRight = -marginR + "px";
|
||||
this._togglePanesButton.setAttribute("panesHidden", "true");
|
||||
this._togglePanesButton.setAttribute("tooltiptext", L10N.getStr("expandPanes"));
|
||||
// Computes and sets the panes margins in order to hide or show them.
|
||||
function set() {
|
||||
if (aFlags.visible) {
|
||||
this._stackframesAndBreakpoints.style.marginLeft = "0";
|
||||
this._variablesAndExpressions.style.marginRight = "0";
|
||||
this._togglePanesButton.removeAttribute("panesHidden");
|
||||
this._togglePanesButton.setAttribute("tooltiptext", L10N.getStr("collapsePanes"));
|
||||
} else {
|
||||
let marginL = ~~(this._stackframesAndBreakpoints.getAttribute("width")) + 1;
|
||||
let marginR = ~~(this._variablesAndExpressions.getAttribute("width")) + 1;
|
||||
this._stackframesAndBreakpoints.style.marginLeft = -marginL + "px";
|
||||
this._variablesAndExpressions.style.marginRight = -marginR + "px";
|
||||
this._togglePanesButton.setAttribute("panesHidden", "true");
|
||||
this._togglePanesButton.setAttribute("tooltiptext", L10N.getStr("expandPanes"));
|
||||
}
|
||||
|
||||
if (aFlags.animated) {
|
||||
// Displaying the panes may have the effect of triggering scrollbars to
|
||||
// appear in the source editor, which would render the currently
|
||||
// highlighted line to appear behind them in some cases.
|
||||
window.addEventListener("transitionend", function onEvent() {
|
||||
window.removeEventListener("transitionend", onEvent, false);
|
||||
DebuggerView.updateEditor();
|
||||
|
||||
// Invoke the callback when the transition ended.
|
||||
if (aFlags.callback) aFlags.callback();
|
||||
}, false);
|
||||
} else {
|
||||
// Invoke the callback immediately since there's no transition.
|
||||
if (aFlags.callback) aFlags.callback();
|
||||
}
|
||||
}
|
||||
|
||||
if (aFlags.animated) {
|
||||
this._stackframesAndBreakpoints.setAttribute("animated", "");
|
||||
this._variablesAndExpressions.setAttribute("animated", "");
|
||||
|
||||
// Displaying the panes may have the effect of triggering scrollbars to
|
||||
// appear in the source editor, which would render the currently
|
||||
// highlighted line to appear behind them in some cases.
|
||||
let self = this;
|
||||
|
||||
window.addEventListener("transitionend", function onEvent() {
|
||||
window.removeEventListener("transitionend", onEvent, false);
|
||||
aFlags.callback && aFlags.callback();
|
||||
self.updateEditor();
|
||||
}, false);
|
||||
} else {
|
||||
this._stackframesAndBreakpoints.removeAttribute("animated");
|
||||
this._variablesAndExpressions.removeAttribute("animated");
|
||||
aFlags.callback && aFlags.callback();
|
||||
}
|
||||
|
||||
if (aFlags.delayed) {
|
||||
window.setTimeout(set.bind(this), PANES_APPEARANCE_DELAY);
|
||||
} else {
|
||||
set.call(this);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -450,6 +464,7 @@ let DebuggerView = {
|
|||
DebuggerView.togglePanes({
|
||||
visible: true,
|
||||
animated: true,
|
||||
delayed: true,
|
||||
callback: aCallback
|
||||
});
|
||||
}, PANES_APPEARANCE_DELAY);
|
||||
|
|
|
@ -238,6 +238,7 @@
|
|||
</toolbar>
|
||||
|
||||
<panel id="searchbox-panel"
|
||||
level="top"
|
||||
type="arrow"
|
||||
noautofocus="true"
|
||||
position="before_start">
|
||||
|
@ -267,6 +268,7 @@
|
|||
</panel>
|
||||
|
||||
<panel id="conditional-breakpoint-panel"
|
||||
level="top"
|
||||
type="arrow"
|
||||
noautofocus="true"
|
||||
position="after_start">
|
||||
|
|
|
@ -87,7 +87,7 @@ MOCHITEST_BROWSER_TESTS = \
|
|||
browser_dbg_breakpoint-new-script.js \
|
||||
browser_dbg_bug737803_editor_actual_location.js \
|
||||
browser_dbg_progress-listener-bug.js \
|
||||
$(filter disabled-for-intermittent-crashes--bug-821701, browser_dbg_chrome-debugging.js) \
|
||||
browser_dbg_chrome-debugging.js \
|
||||
$(filter disabled-for-intermittent-failures--bug-753225, browser_dbg_createRemote.js) \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
|
|
@ -16,9 +16,6 @@ const DEBUGGER_TAB_URL = EXAMPLE_URL + "browser_dbg_debuggerstatement.html";
|
|||
|
||||
function test()
|
||||
{
|
||||
// Make sure there is enough time for findAllGlobals.
|
||||
requestLongerTimeout(3);
|
||||
|
||||
let transport = DebuggerServer.connectPipe();
|
||||
gClient = new DebuggerClient(transport);
|
||||
gClient.connect(function(aType, aTraits) {
|
||||
|
|
|
@ -286,7 +286,8 @@ TabWebProgressListener.prototype = {
|
|||
return;
|
||||
}
|
||||
|
||||
if (this.target) {
|
||||
// emit event if the top frame is navigating
|
||||
if (this.target && this.target.window == progress.DOMWindow) {
|
||||
this.target.emit("will-navigate", request);
|
||||
}
|
||||
},
|
||||
|
|
|
@ -135,7 +135,7 @@ let styleEditorDefinition = {
|
|||
tooltip: l10n("ToolboxStyleEditor.tooltip", styleEditorStrings),
|
||||
|
||||
isTargetSupported: function(target) {
|
||||
return !target.isRemote && !target.isChrome;
|
||||
return target.isLocalTab;
|
||||
},
|
||||
|
||||
build: function(iframeWindow, toolbox) {
|
||||
|
@ -152,11 +152,7 @@ let profilerDefinition = {
|
|||
tooltip: l10n("profiler.tooltip", profilerStrings),
|
||||
|
||||
isTargetSupported: function (target) {
|
||||
if (target.isRemote || target.isChrome) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return !target.isRemote;
|
||||
},
|
||||
|
||||
build: function (frame, target) {
|
||||
|
|
|
@ -16,6 +16,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "Hosts",
|
|||
"resource:///modules/devtools/ToolboxHosts.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "CommandUtils",
|
||||
"resource:///modules/devtools/DeveloperToolbar.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "toolboxStrings", function() {
|
||||
let bundle = Services.strings.createBundle("chrome://browser/locale/devtools/toolbox.properties");
|
||||
let l10n = function(name) {
|
||||
|
@ -28,13 +29,12 @@ XPCOMUtils.defineLazyGetter(this, "toolboxStrings", function() {
|
|||
return l10n;
|
||||
});
|
||||
|
||||
// DO NOT put Require.jsm or gcli.jsm into lazy getters as this breaks the
|
||||
// requisition import a few lines down.
|
||||
Cu.import("resource:///modules/devtools/gcli.jsm");
|
||||
Cu.import("resource://gre/modules/devtools/Require.jsm");
|
||||
XPCOMUtils.defineLazyGetter(this, "Requisition", function() {
|
||||
Cu.import("resource://gre/modules/devtools/Require.jsm");
|
||||
Cu.import("resource:///modules/devtools/gcli.jsm");
|
||||
|
||||
let Requisition = require('gcli/cli').Requisition;
|
||||
let CommandOutputManager = require('gcli/canon').CommandOutputManager;
|
||||
return require('gcli/cli').Requisition;
|
||||
});
|
||||
|
||||
this.EXPORTED_SYMBOLS = [ "Toolbox" ];
|
||||
|
||||
|
@ -244,9 +244,14 @@ Toolbox.prototype = {
|
|||
open: function TBOX_open() {
|
||||
let deferred = Promise.defer();
|
||||
|
||||
this._host.open().then(function(iframe) {
|
||||
let onload = function() {
|
||||
iframe.removeEventListener("DOMContentLoaded", onload, true);
|
||||
this._host.create().then(function(iframe) {
|
||||
let domReady = function() {
|
||||
iframe.removeEventListener("DOMContentLoaded", domReady, true);
|
||||
|
||||
let vbox = this.doc.getElementById("toolbox-panel-" + this._currentToolId);
|
||||
if (vbox) {
|
||||
this.doc.commandDispatcher.advanceFocusIntoSubtree(vbox);
|
||||
}
|
||||
|
||||
this.isReady = true;
|
||||
|
||||
|
@ -255,7 +260,7 @@ Toolbox.prototype = {
|
|||
|
||||
this._buildDockButtons();
|
||||
this._buildTabs();
|
||||
this._buildButtons(this.frame);
|
||||
this._buildButtons();
|
||||
|
||||
this.selectTool(this._defaultToolId).then(function(panel) {
|
||||
this.emit("ready");
|
||||
|
@ -263,7 +268,7 @@ Toolbox.prototype = {
|
|||
}.bind(this));
|
||||
}.bind(this);
|
||||
|
||||
iframe.addEventListener("DOMContentLoaded", onload, true);
|
||||
iframe.addEventListener("DOMContentLoaded", domReady, true);
|
||||
iframe.setAttribute("src", this._URL);
|
||||
}.bind(this));
|
||||
|
||||
|
@ -317,21 +322,17 @@ Toolbox.prototype = {
|
|||
|
||||
/**
|
||||
* Add buttons to the UI as specified in the devtools.window.toolbarSpec pref
|
||||
*
|
||||
* @param {iframe} frame
|
||||
* The iframe to contain the buttons
|
||||
*/
|
||||
_buildButtons: function TBOX_buildButtons(frame) {
|
||||
if (this.target.isRemote) {
|
||||
_buildButtons: function TBOX_buildButtons() {
|
||||
if (!this.target.isLocalTab) {
|
||||
return;
|
||||
}
|
||||
|
||||
let toolbarSpec = CommandUtils.getCommandbarSpec("devtools.toolbox.toolbarSpec");
|
||||
let environment = { chromeDocument: frame.ownerDocument };
|
||||
let environment = { chromeDocument: this.target.tab.ownerDocument };
|
||||
let requisition = new Requisition(environment);
|
||||
requisition.commandOutputManager = new CommandOutputManager();
|
||||
|
||||
let buttons = CommandUtils.createButtons(toolbarSpec, this.doc, requisition);
|
||||
let buttons = CommandUtils.createButtons(toolbarSpec, this._target, this.doc, requisition);
|
||||
|
||||
let container = this.doc.getElementById("toolbox-buttons");
|
||||
buttons.forEach(function(button) {
|
||||
|
@ -473,11 +474,10 @@ Toolbox.prototype = {
|
|||
* The created host object
|
||||
*/
|
||||
_createHost: function TBOX_createHost(hostType) {
|
||||
let hostTab = this._getHostTab();
|
||||
if (!Hosts[hostType]) {
|
||||
throw new Error('Unknown hostType: '+ hostType);
|
||||
}
|
||||
let newHost = new Hosts[hostType](hostTab);
|
||||
let newHost = new Hosts[hostType](this.target.tab);
|
||||
|
||||
// clean up the toolbox if its window is closed
|
||||
newHost.on("window-closed", this.destroy);
|
||||
|
@ -502,7 +502,7 @@ Toolbox.prototype = {
|
|||
}
|
||||
|
||||
let newHost = this._createHost(hostType);
|
||||
return newHost.open().then(function(iframe) {
|
||||
return newHost.create().then(function(iframe) {
|
||||
// change toolbox document's parent to the new host
|
||||
iframe.QueryInterface(Ci.nsIFrameLoaderOwner);
|
||||
iframe.swapFrameLoaders(this.frame);
|
||||
|
@ -520,18 +520,6 @@ Toolbox.prototype = {
|
|||
}.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the most appropriate host tab, either the target or the current tab
|
||||
*/
|
||||
_getHostTab: function TBOX_getHostTab() {
|
||||
if (!this._target.isRemote && !this._target.isChrome) {
|
||||
return this._target.tab;
|
||||
} else {
|
||||
let win = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
return win.gBrowser.selectedTab;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Handler for the tool-registered event.
|
||||
* @param {string} event
|
||||
|
|
|
@ -17,7 +17,7 @@ this.EXPORTED_SYMBOLS = [ "Hosts" ];
|
|||
* sidebar or a separate window). Any host object should implement the
|
||||
* following functions:
|
||||
*
|
||||
* open() - create the UI and emit a 'ready' event when the UI is ready to use
|
||||
* create() - create the UI and emit a 'ready' event when the UI is ready to use
|
||||
* destroy() - destroy the host's UI
|
||||
*/
|
||||
|
||||
|
@ -44,7 +44,7 @@ BottomHost.prototype = {
|
|||
/**
|
||||
* Create a box at the bottom of the host tab.
|
||||
*/
|
||||
open: function BH_open() {
|
||||
create: function BH_create() {
|
||||
let deferred = Promise.defer();
|
||||
|
||||
let gBrowser = this.hostTab.ownerDocument.defaultView.gBrowser;
|
||||
|
@ -54,7 +54,7 @@ BottomHost.prototype = {
|
|||
this._splitter.setAttribute("class", "devtools-horizontal-splitter");
|
||||
|
||||
this.frame = ownerDocument.createElement("iframe");
|
||||
this.frame.id = "devtools-toolbox-bottom-iframe";
|
||||
this.frame.className = "devtools-toolbox-bottom-iframe";
|
||||
this.frame.height = Services.prefs.getIntPref(this.heightPref);
|
||||
|
||||
this._nbox = gBrowser.getNotificationBox(this.hostTab.linkedBrowser);
|
||||
|
@ -112,7 +112,7 @@ SidebarHost.prototype = {
|
|||
/**
|
||||
* Create a box in the sidebar of the host tab.
|
||||
*/
|
||||
open: function RH_open() {
|
||||
create: function SH_create() {
|
||||
let deferred = Promise.defer();
|
||||
|
||||
let gBrowser = this.hostTab.ownerDocument.defaultView.gBrowser;
|
||||
|
@ -122,7 +122,7 @@ SidebarHost.prototype = {
|
|||
this._splitter.setAttribute("class", "devtools-side-splitter");
|
||||
|
||||
this.frame = ownerDocument.createElement("iframe");
|
||||
this.frame.id = "devtools-toolbox-side-iframe";
|
||||
this.frame.className = "devtools-toolbox-side-iframe";
|
||||
this.frame.width = Services.prefs.getIntPref(this.widthPref);
|
||||
|
||||
this._sidebar = gBrowser.getSidebarContainer(this.hostTab.linkedBrowser);
|
||||
|
@ -147,7 +147,7 @@ SidebarHost.prototype = {
|
|||
/**
|
||||
* Destroy the sidebar.
|
||||
*/
|
||||
destroy: function RH_destroy() {
|
||||
destroy: function SH_destroy() {
|
||||
if (!this._destroyed) {
|
||||
this._destroyed = true;
|
||||
|
||||
|
@ -177,7 +177,7 @@ WindowHost.prototype = {
|
|||
/**
|
||||
* Create a new xul window to contain the toolbox.
|
||||
*/
|
||||
open: function WH_open() {
|
||||
create: function WH_create() {
|
||||
let deferred = Promise.defer();
|
||||
|
||||
let flags = "chrome,centerscreen,resizable,dialog=no";
|
||||
|
|
|
@ -429,7 +429,7 @@ let gDevToolsBrowser = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Update the "Toggle Toolbox" checkbox in the developer tools menu. This is
|
||||
* Update the "Toggle Tools" checkbox in the developer tools menu. This is
|
||||
* called when a toolbox is created or destroyed.
|
||||
*/
|
||||
_updateMenuCheckbox: function DT_updateMenuCheckbox() {
|
||||
|
|
|
@ -38,7 +38,8 @@ function testBottomHost(aToolbox)
|
|||
checkHostType(Toolbox.HostType.BOTTOM);
|
||||
|
||||
// test UI presence
|
||||
let iframe = document.getElementById("devtools-toolbox-bottom-iframe");
|
||||
let nbox = gBrowser.getNotificationBox();
|
||||
let iframe = document.getAnonymousElementByAttribute(nbox, "class", "devtools-toolbox-bottom-iframe");
|
||||
ok(iframe, "toolbox bottom iframe exists");
|
||||
|
||||
checkToolboxLoaded(iframe);
|
||||
|
@ -51,10 +52,11 @@ function testSidebarHost()
|
|||
checkHostType(Toolbox.HostType.SIDE);
|
||||
|
||||
// test UI presence
|
||||
let bottom = document.getElementById("devtools-toolbox-bottom-iframe");
|
||||
let nbox = gBrowser.getNotificationBox();
|
||||
let bottom = document.getAnonymousElementByAttribute(nbox, "class", "devtools-toolbox-bottom-iframe");
|
||||
ok(!bottom, "toolbox bottom iframe doesn't exist");
|
||||
|
||||
let iframe = document.getElementById("devtools-toolbox-side-iframe");
|
||||
let iframe = document.getAnonymousElementByAttribute(nbox, "class", "devtools-toolbox-side-iframe");
|
||||
ok(iframe, "toolbox side iframe exists");
|
||||
|
||||
checkToolboxLoaded(iframe);
|
||||
|
@ -66,7 +68,8 @@ function testWindowHost()
|
|||
{
|
||||
checkHostType(Toolbox.HostType.WINDOW);
|
||||
|
||||
let sidebar = document.getElementById("devtools-toolbox-side-iframe");
|
||||
let nbox = gBrowser.getNotificationBox();
|
||||
let sidebar = document.getAnonymousElementByAttribute(nbox, "class", "devtools-toolbox-side-iframe");
|
||||
ok(!sidebar, "toolbox sidebar iframe doesn't exist");
|
||||
|
||||
let win = Services.wm.getMostRecentWindow("devtools:toolbox");
|
||||
|
|
|
@ -228,7 +228,15 @@ InspectorPanel.prototype = {
|
|||
|
||||
request.suspend();
|
||||
|
||||
let notificationBox = this._toolbox.getNotificationBox();
|
||||
let notificationBox = null;
|
||||
if (this.target.isLocalTab) {
|
||||
let gBrowser = this.target.tab.ownerDocument.defaultView.gBrowser;
|
||||
notificationBox = gBrowser.getNotificationBox();
|
||||
}
|
||||
else {
|
||||
notificationBox = this._toolbox.getNotificationBox();
|
||||
}
|
||||
|
||||
let notification = notificationBox.
|
||||
getNotificationWithValue("inspector-page-navigation");
|
||||
|
||||
|
@ -259,9 +267,7 @@ InspectorPanel.prototype = {
|
|||
if (request) {
|
||||
request.resume();
|
||||
request = null;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}.bind(this),
|
||||
},
|
||||
{
|
||||
|
|
|
@ -25,7 +25,7 @@ function test() {
|
|||
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
let toolbox = gDevTools.getToolbox(target);
|
||||
notificationBox = toolbox.getNotificationBox();
|
||||
notificationBox = gBrowser.getNotificationBox();
|
||||
notificationBox.addEventListener("AlertActive", alertActive1, false);
|
||||
|
||||
ok(toolbox, "We have access to the notificationBox");
|
||||
|
|
|
@ -36,8 +36,10 @@ function test()
|
|||
{
|
||||
is(getActiveInspector().selection.node, objectNode, "selection matches node");
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
gDevTools.closeToolbox(target);
|
||||
finishUp();
|
||||
executeSoon(function() {
|
||||
gDevTools.closeToolbox(target);
|
||||
finishUp();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ function test()
|
|||
openInspector(findAndHighlightNode);
|
||||
}
|
||||
|
||||
function findAndHighlightNode(aInspector)
|
||||
function findAndHighlightNode(aInspector, aToolbox)
|
||||
{
|
||||
inspector = aInspector;
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ function openInspector(callback)
|
|||
{
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
gDevTools.showToolbox(target, "inspector").then(function(toolbox) {
|
||||
callback(toolbox.getCurrentPanel());
|
||||
callback(toolbox.getCurrentPanel(), toolbox);
|
||||
}).then(null, console.error);
|
||||
}
|
||||
|
||||
|
|
|
@ -40,9 +40,7 @@ browser.jar:
|
|||
content/browser/devtools/profiler/cleopatra/js/ProgressReporter.js (profiler/cleopatra/js/ProgressReporter.js)
|
||||
content/browser/devtools/profiler/cleopatra/js/devtools.js (profiler/cleopatra/js/devtools.js)
|
||||
content/browser/devtools/profiler/cleopatra/images/circlearrow.svg (profiler/cleopatra/images/circlearrow.svg)
|
||||
content/browser/devtools/profiler/cleopatra/images/filter.png (profiler/cleopatra/images/filter.png)
|
||||
content/browser/devtools/profiler/cleopatra/images/noise.png (profiler/cleopatra/images/noise.png)
|
||||
content/browser/devtools/profiler/cleopatra/images/showall.png (profiler/cleopatra/images/showall.png)
|
||||
content/browser/devtools/profiler/cleopatra/images/throbber.svg (profiler/cleopatra/images/throbber.svg)
|
||||
content/browser/devtools/profiler/cleopatra/images/treetwisty.svg (profiler/cleopatra/images/treetwisty.svg)
|
||||
content/browser/devtools/commandline.css (commandline/commandline.css)
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
<script src="profiler/cleopatra/js/ui.js"></script>
|
||||
<script src="profiler/cleopatra/js/ProgressReporter.js"></script>
|
||||
<script src="profiler/cleopatra/js/devtools.js"></script>
|
||||
|
||||
<link rel="shortcut icon" href="favicon.png" />
|
||||
</head>
|
||||
|
||||
<body onload="notifyParent('loaded');">
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
.treeViewContainer {
|
||||
-moz-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
cursor: default;
|
||||
line-height: 16px;
|
||||
|
@ -26,8 +25,6 @@
|
|||
.treeColumnHeader {
|
||||
position: absolute;
|
||||
display: block;
|
||||
background: -moz-linear-gradient(#FFF 45%, #EEE 60%);
|
||||
background: -webkit-linear-gradient(#FFF 45%, #EEE 60%);
|
||||
background: linear-gradient(#FFF 45%, #EEE 60%);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
@ -93,17 +90,11 @@
|
|||
|
||||
.treeViewVerticalScrollbox,
|
||||
.treeViewHorizontalScrollbox {
|
||||
background: -moz-linear-gradient(white, white 50%, #F0F5FF 50%, #F0F5FF);
|
||||
background: -webkit-linear-gradient(white, white 50%, #F0F5FF 50%, #F0F5FF);
|
||||
background: linear-gradient(white, white 50%, #F0F5FF 50%, #F0F5FF);
|
||||
background-size: 100px 32px;
|
||||
}
|
||||
|
||||
.leftColumnBackground {
|
||||
background: -moz-linear-gradient(left, transparent, transparent 98px, #CCC 98px, #CCC 99px, transparent 99px),
|
||||
-moz-linear-gradient(white, white 50%, #F0F5FF 50%, #F0F5FF);
|
||||
background: -webkit-linear-gradient(left, transparent, transparent 98px, #CCC 98px, #CCC 99px, transparent 99px),
|
||||
-webkit-linear-gradient(white, white 50%, #F0F5FF 50%, #F0F5FF);
|
||||
background: linear-gradient(left, transparent, transparent 98px, #CCC 98px, #CCC 99px, transparent 99px),
|
||||
linear-gradient(white, white 50%, #F0F5FF 50%, #F0F5FF);
|
||||
background-size: auto, 100px 32px;
|
||||
|
|
|
@ -31,10 +31,6 @@ body {
|
|||
.profileProgressPane {
|
||||
padding: 20px;
|
||||
background-color: rgb(229,229,229);
|
||||
background-image: url(../images/noise.png),
|
||||
-moz-linear-gradient(rgba(255,255,255,.5),rgba(255,255,255,.2));
|
||||
background-image: url(../images/noise.png),
|
||||
-webkit-linear-gradient(rgba(255,255,255,.5),rgba(255,255,255,.2));
|
||||
background-image: url(../images/noise.png),
|
||||
linear-gradient(rgba(255,255,255,.5),rgba(255,255,255,.2));
|
||||
text-shadow: rgba(255, 255, 255, 0.4) 0 1px;
|
||||
|
@ -62,22 +58,39 @@ body {
|
|||
height: 16px;
|
||||
}
|
||||
.finishedProfilePaneBackgroundCover {
|
||||
-webkit-animation: darken 300ms cubic-bezier(0, 0, 1, 0);
|
||||
-moz-animation: darken 300ms cubic-bezier(0, 0, 1, 0);
|
||||
animation: darken 300ms cubic-bezier(0, 0, 1, 0);
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.finishedProfilePane {
|
||||
-webkit-animation: appear 300ms ease-out;
|
||||
-moz-animation: appear 300ms ease-out;
|
||||
animation: appear 300ms ease-out;
|
||||
}
|
||||
|
||||
@keyframes darken {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@keyframes appear {
|
||||
from {
|
||||
transform: scale(0.3);
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
to {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
}
|
||||
}
|
||||
.breadcrumbTrail {
|
||||
top: 0;
|
||||
right: 0;
|
||||
height: 29px;
|
||||
left: 0;
|
||||
background: -moz-linear-gradient(#FFF 50%, #F3F3F3 55%);
|
||||
background: -webkit-linear-gradient(#FFF 50%, #F3F3F3 55%);
|
||||
background: linear-gradient(#FFF 50%, #F3F3F3 55%);
|
||||
border-bottom: 1px solid #CCC;
|
||||
margin: 0;
|
||||
|
@ -85,8 +98,6 @@ body {
|
|||
overflow: hidden;
|
||||
}
|
||||
.breadcrumbTrailItem {
|
||||
background: -moz-linear-gradient(#FFF 50%, #F3F3F3 55%);
|
||||
background: -webkit-linear-gradient(#FFF 50%, #F3F3F3 55%);
|
||||
background: linear-gradient(#FFF 50%, #F3F3F3 55%);
|
||||
display: block;
|
||||
margin: 0;
|
||||
|
@ -96,7 +107,6 @@ body {
|
|||
padding: 0 10px;
|
||||
font-size: 12px;
|
||||
-moz-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
cursor: default;
|
||||
border-right: 1px solid #CCC;
|
||||
|
@ -106,7 +116,7 @@ body {
|
|||
white-space: nowrap;
|
||||
position: relative;
|
||||
}
|
||||
@-webkit-keyframes slide-out {
|
||||
@keyframes slide-out {
|
||||
from {
|
||||
margin-left: -270px;
|
||||
opacity: 0;
|
||||
|
@ -116,7 +126,7 @@ body {
|
|||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@-moz-keyframes slide-out {
|
||||
@keyframes slide-out {
|
||||
from {
|
||||
margin-left: -270px;
|
||||
opacity: 0;
|
||||
|
@ -127,12 +137,9 @@ body {
|
|||
}
|
||||
}
|
||||
.breadcrumbTrailItem:not(:first-child) {
|
||||
-moz-animation: slide-out;
|
||||
-moz-animation-duration: 400ms;
|
||||
-moz-animation-timing-function: ease-out;
|
||||
-webkit-animation: slide-out;
|
||||
-webkit-animation-duration: 400ms;
|
||||
-webkit-animation-timing-function: ease-out;
|
||||
animation: slide-out;
|
||||
animation-duration: 400ms;
|
||||
animation-timing-function: ease-out;
|
||||
}
|
||||
.breadcrumbTrailItem.selected {
|
||||
background: linear-gradient(#E5E5E5 50%, #DADADA 55%);
|
||||
|
@ -141,10 +148,8 @@ body {
|
|||
background: linear-gradient(#F2F2F2 50%, #E6E6E6 55%);
|
||||
}
|
||||
.breadcrumbTrailItem.deleted {
|
||||
-moz-transition: 400ms ease-out;
|
||||
-moz-transition-property: opacity, margin-left;
|
||||
-webkit-transition: 400ms ease-out;
|
||||
-webkit-transition-property: opacity, margin-left;
|
||||
transition: 400ms ease-out;
|
||||
transition-property: opacity, margin-left;
|
||||
opacity: 0;
|
||||
margin-left: -270px;
|
||||
}
|
||||
|
@ -199,7 +204,6 @@ body {
|
|||
}
|
||||
.sideBar {
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
|
@ -246,8 +250,6 @@ body {
|
|||
right: 0;
|
||||
left: 0;
|
||||
border-bottom: 1px solid #CCC;
|
||||
background: -moz-linear-gradient(#EEE, #CCC);
|
||||
background: -webkit-linear-gradient(#EEE, #CCC);
|
||||
background: linear-gradient(#EEE, #CCC);
|
||||
}
|
||||
.histogramHilite {
|
||||
|
@ -287,8 +289,6 @@ body {
|
|||
text-indent: 8px;
|
||||
}
|
||||
.fileListItem.selected {
|
||||
background: -moz-linear-gradient(#4B91D7 1px, #5FA9E4 1px, #5FA9E4 2px, #58A0DE 3px, #2B70C7 39px, #2763B4 39px);
|
||||
background: -webkit-linear-gradient(#4B91D7 1px, #5FA9E4 1px, #5FA9E4 2px, #58A0DE 3px, #2B70C7 39px, #2763B4 39px);
|
||||
background: linear-gradient(#4B91D7 1px, #5FA9E4 1px, #5FA9E4 2px, #58A0DE 3px, #2B70C7 39px, #2763B4 39px);
|
||||
color: #FFF;
|
||||
text-shadow: 0 1px rgba(0, 0, 0, 0.3);
|
||||
|
@ -313,10 +313,8 @@ body {
|
|||
opacity: 0;
|
||||
pointer-events: none;
|
||||
background: rgba(120, 120, 120, 0.2);
|
||||
-moz-transition: 200ms ease-in-out;
|
||||
-moz-transition-property: visibility, opacity;
|
||||
-webkit-transition: 200ms ease-in-out;
|
||||
-webkit-transition-property: visibility, opacity;
|
||||
transition: 200ms ease-in-out;
|
||||
transition-property: visibility, opacity;
|
||||
}
|
||||
.busyCover.busy {
|
||||
visibility: visible;
|
||||
|
@ -330,7 +328,6 @@ body {
|
|||
margin: -12px;
|
||||
}
|
||||
label {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
}
|
||||
.videoPane {
|
||||
|
|
|
@ -35,6 +35,25 @@ gcli.addCommand({
|
|||
tooltipText: gcli.lookup("resizeModeToggleTooltip"),
|
||||
description: gcli.lookup('resizeModeToggleDesc'),
|
||||
manual: gcli.lookup('resizeModeManual'),
|
||||
state: {
|
||||
isChecked: function(aTarget) {
|
||||
let browserWindow = aTarget.tab.ownerDocument.defaultView;
|
||||
let mgr = browserWindow.ResponsiveUI.ResponsiveUIManager;
|
||||
return mgr.isActiveForTab(aTarget.tab);
|
||||
},
|
||||
onChange: function(aTarget, aChangeHandler) {
|
||||
let browserWindow = aTarget.tab.ownerDocument.defaultView;
|
||||
let mgr = browserWindow.ResponsiveUI.ResponsiveUIManager;
|
||||
mgr.on("on", aChangeHandler);
|
||||
mgr.on("off", aChangeHandler);
|
||||
},
|
||||
offChange: function(aTarget, aChangeHandler) {
|
||||
let browserWindow = aTarget.tab.ownerDocument.defaultView;
|
||||
let mgr = browserWindow.ResponsiveUI.ResponsiveUIManager;
|
||||
mgr.off("on", aChangeHandler);
|
||||
mgr.off("off", aChangeHandler);
|
||||
},
|
||||
},
|
||||
exec: gcli_cmd_resize
|
||||
});
|
||||
|
||||
|
|
|
@ -35,10 +35,19 @@ this.ResponsiveUIManager = {
|
|||
if (aTab.__responsiveUI) {
|
||||
aTab.__responsiveUI.close();
|
||||
} else {
|
||||
aTab.__responsiveUI = new ResponsiveUI(aWindow, aTab);
|
||||
new ResponsiveUI(aWindow, aTab);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if responsive view is active for the provided tab.
|
||||
*
|
||||
* @param aTab the tab targeted.
|
||||
*/
|
||||
isActiveForTab: function(aTab) {
|
||||
return !!aTab.__responsiveUI;
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle gcli commands.
|
||||
*
|
||||
|
@ -51,13 +60,13 @@ this.ResponsiveUIManager = {
|
|||
switch (aCommand) {
|
||||
case "resize to":
|
||||
if (!aTab.__responsiveUI) {
|
||||
aTab.__responsiveUI = new ResponsiveUI(aWindow, aTab);
|
||||
new ResponsiveUI(aWindow, aTab);
|
||||
}
|
||||
aTab.__responsiveUI.setSize(aArgs.width, aArgs.height);
|
||||
break;
|
||||
case "resize on":
|
||||
if (!aTab.__responsiveUI) {
|
||||
aTab.__responsiveUI = new ResponsiveUI(aWindow, aTab);
|
||||
new ResponsiveUI(aWindow, aTab);
|
||||
}
|
||||
break;
|
||||
case "resize off":
|
||||
|
@ -167,6 +176,8 @@ function ResponsiveUI(aWindow, aTab)
|
|||
if (this._floatingScrollbars)
|
||||
switchToFloatingScrollbars(this.tab);
|
||||
|
||||
this.tab.__responsiveUI = this;
|
||||
|
||||
ResponsiveUIManager.emit("on", this.tab, this);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "PageErrorListener",
|
|||
"resource://gre/modules/devtools/WebConsoleUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "prefBranch", function() {
|
||||
var prefService = Components.classes["@mozilla.org/preferences-service;1"]
|
||||
let prefService = Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService(Components.interfaces.nsIPrefService);
|
||||
return prefService.getBranch(null)
|
||||
.QueryInterface(Components.interfaces.nsIPrefBranch2);
|
||||
|
@ -51,12 +51,16 @@ this.CommandUtils = {
|
|||
/**
|
||||
* A toolbarSpec is an array of buttonSpecs. A buttonSpec is an array of
|
||||
* strings each of which is a GCLI command (including args if needed).
|
||||
*
|
||||
* Warning: this method uses the unload event of the window that owns the
|
||||
* buttons that are of type checkbox. this means that we don't properly
|
||||
* unregister event handlers until the window is destroyed.
|
||||
*/
|
||||
createButtons: function CU_createButtons(toolbarSpec, document, requisition) {
|
||||
var reply = [];
|
||||
createButtons: function CU_createButtons(toolbarSpec, target, document, requisition) {
|
||||
let reply = [];
|
||||
|
||||
toolbarSpec.forEach(function(buttonSpec) {
|
||||
var button = document.createElement("toolbarbutton");
|
||||
let button = document.createElement("toolbarbutton");
|
||||
reply.push(button);
|
||||
|
||||
if (typeof buttonSpec == "string") {
|
||||
|
@ -66,7 +70,7 @@ this.CommandUtils = {
|
|||
requisition.update(buttonSpec.typed);
|
||||
|
||||
// Ignore invalid commands
|
||||
var command = requisition.commandAssignment.value;
|
||||
let command = requisition.commandAssignment.value;
|
||||
if (command == null) {
|
||||
// TODO: Have a broken icon
|
||||
// button.icon = 'Broken';
|
||||
|
@ -101,15 +105,24 @@ this.CommandUtils = {
|
|||
}, false);
|
||||
|
||||
// Allow the command button to be toggleable
|
||||
/*
|
||||
if (command.checkedState) {
|
||||
button.setAttribute("type", "checkbox");
|
||||
button.setAttribute("checked", command.checkedState.get() ? "true" : "false");
|
||||
command.checkedState.on("change", function() {
|
||||
button.checked = command.checkedState.get();
|
||||
});
|
||||
if (command.state) {
|
||||
button.setAttribute("autocheck", false);
|
||||
let onChange = function(event, eventTab) {
|
||||
if (eventTab == target.tab) {
|
||||
if (command.state.isChecked(target)) {
|
||||
button.setAttribute("checked", true);
|
||||
}
|
||||
else if (button.hasAttribute("checked")) {
|
||||
button.removeAttribute("checked");
|
||||
}
|
||||
}
|
||||
};
|
||||
command.state.onChange(target, onChange);
|
||||
onChange(null, target.tab);
|
||||
document.defaultView.addEventListener("unload", function() {
|
||||
command.state.offChange(target, onChange);
|
||||
}, false);
|
||||
}
|
||||
*/
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -192,7 +205,7 @@ Object.defineProperty(DeveloperToolbar.prototype, 'visible', {
|
|||
enumerable: true
|
||||
});
|
||||
|
||||
var _gSequenceId = 0;
|
||||
let _gSequenceId = 0;
|
||||
|
||||
/**
|
||||
* Getter for a unique ID.
|
||||
|
@ -239,8 +252,8 @@ DeveloperToolbar.prototype.focusToggle = function DT_focusToggle()
|
|||
if (this.visible) {
|
||||
// If we have focus then the active element is the HTML input contained
|
||||
// inside the xul input element
|
||||
var active = this._chromeWindow.document.activeElement;
|
||||
var position = this._input.compareDocumentPosition(active);
|
||||
let active = this._chromeWindow.document.activeElement;
|
||||
let position = this._input.compareDocumentPosition(active);
|
||||
if (position & Node.DOCUMENT_POSITION_CONTAINED_BY) {
|
||||
this.hide();
|
||||
}
|
||||
|
@ -443,7 +456,12 @@ DeveloperToolbar.prototype.hide = function DT_hide()
|
|||
*/
|
||||
DeveloperToolbar.prototype.destroy = function DT_destroy()
|
||||
{
|
||||
if (this._lastState == NOTIFICATIONS.HIDE) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._chromeWindow.getBrowser().tabContainer.removeEventListener("TabSelect", this, false);
|
||||
this._chromeWindow.getBrowser().tabContainer.removeEventListener("TabClose", this, false);
|
||||
this._chromeWindow.getBrowser().removeEventListener("load", this, true);
|
||||
this._chromeWindow.getBrowser().removeEventListener("beforeunload", this, true);
|
||||
|
||||
|
@ -470,6 +488,8 @@ DeveloperToolbar.prototype.destroy = function DT_destroy()
|
|||
delete this.outputPanel;
|
||||
delete this.tooltipPanel;
|
||||
*/
|
||||
|
||||
this._lastState = NOTIFICATIONS.HIDE;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -1683,12 +1683,11 @@ VariablesView.prototype.commitHierarchy = function VV_commitHierarchy() {
|
|||
// Dispatch this action after all the nodes have been drawn, so that
|
||||
// the transition efects can take place.
|
||||
this.window.setTimeout(function(aTarget) {
|
||||
aTarget.setAttribute("changed", "");
|
||||
|
||||
aTarget.addEventListener("transitionend", function onEvent() {
|
||||
aTarget.removeEventListener("transitionend", onEvent, false);
|
||||
aTarget.removeAttribute("changed");
|
||||
}, false);
|
||||
aTarget.setAttribute("changed", "");
|
||||
}.bind(this, currVariable.target), LAZY_EMPTY_DELAY + 1);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -400,7 +400,7 @@ StyleEditorChrome.prototype = {
|
|||
onEditorAdded: function SEC_selectSheet_onEditorAdded(aChrome, aEditor) {
|
||||
let sheet = self._styleSheetToSelect.sheet;
|
||||
if ((sheet && aEditor.styleSheet == sheet) ||
|
||||
aEditor.styleSheetIndex == 0) {
|
||||
(aEditor.styleSheetIndex == 0 && sheet == null)) {
|
||||
aChrome.removeChromeListener(this);
|
||||
select(aEditor);
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ UpdateProcess.prototype = {
|
|||
*/
|
||||
schedule: function UP_schedule()
|
||||
{
|
||||
if (this.cancelled) {
|
||||
if (this.canceled) {
|
||||
return;
|
||||
}
|
||||
this._timeout = this.win.setTimeout(this._timeoutHandler.bind(this), 0);
|
||||
|
@ -100,7 +100,7 @@ UpdateProcess.prototype = {
|
|||
_runBatch: function Y_runBatch()
|
||||
{
|
||||
let time = Date.now();
|
||||
while(!this.cancelled) {
|
||||
while(!this.canceled) {
|
||||
// Continue until iter.next() throws...
|
||||
let next = this.iter.next();
|
||||
this.onItem(next[1]);
|
||||
|
@ -147,7 +147,6 @@ this.CssHtmlTree = function CssHtmlTree(aStyleInspector)
|
|||
this.root = this.styleDocument.getElementById("root");
|
||||
this.templateRoot = this.styleDocument.getElementById("templateRoot");
|
||||
this.propertyContainer = this.styleDocument.getElementById("propertyContainer");
|
||||
this.panel = aStyleInspector.panel;
|
||||
|
||||
// No results text.
|
||||
this.noResults = this.styleDocument.getElementById("noResults");
|
||||
|
@ -257,6 +256,13 @@ CssHtmlTree.prototype = {
|
|||
this._unmatchedProperties = null;
|
||||
this._matchedProperties = null;
|
||||
|
||||
if (!aElement) {
|
||||
if (this._refreshProcess) {
|
||||
this._refreshProcess.cancel();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.htmlComplete) {
|
||||
this.refreshSourceFilter();
|
||||
this.refreshPanel();
|
||||
|
|
|
@ -80,6 +80,7 @@ this.RuleViewTool = function RVT_RuleViewTool(aInspector, aWindow, aIFrame)
|
|||
this._cssLinkHandler);
|
||||
|
||||
this._onSelect = this.onSelect.bind(this);
|
||||
this.inspector.selection.on("detached", this._onSelect);
|
||||
this.inspector.selection.on("new-node", this._onSelect);
|
||||
this.refresh = this.refresh.bind(this);
|
||||
this.inspector.on("layout-change", this.refresh);
|
||||
|
@ -159,6 +160,7 @@ this.ComputedViewTool = function CVT_ComputedViewTool(aInspector, aWindow, aIFra
|
|||
this.view = new CssHtmlTree(this);
|
||||
|
||||
this._onSelect = this.onSelect.bind(this);
|
||||
this.inspector.selection.on("detached", this._onSelect);
|
||||
this.inspector.selection.on("new-node", this._onSelect);
|
||||
if (this.inspector.highlighter) {
|
||||
this.inspector.highlighter.on("locked", this._onSelect);
|
||||
|
@ -179,7 +181,7 @@ ComputedViewTool.prototype = {
|
|||
{
|
||||
if (!this.inspector.selection.isConnected() ||
|
||||
!this.inspector.selection.isElementNode()) {
|
||||
// FIXME: We should hide view's content
|
||||
this.view.highlight(null);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
|
||||
this.EXPORTED_SYMBOLS = [ ];
|
||||
|
||||
Components.utils.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
Components.utils.import("resource:///modules/devtools/gcli.jsm");
|
||||
Components.utils.import("resource:///modules/HUDService.jsm");
|
||||
Components.utils.import("resource:///modules/devtools/Tilt.jsm");
|
||||
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "TiltManager",
|
||||
"resource:///modules/devtools/Tilt.jsm");
|
||||
/**
|
||||
* 'tilt' command
|
||||
*/
|
||||
|
@ -46,6 +46,22 @@ gcli.addCommand({
|
|||
buttonClass: "command-button",
|
||||
tooltipText: gcli.lookup("tiltToggleTooltip"),
|
||||
hidden: true,
|
||||
state: {
|
||||
isChecked: function(aTarget) {
|
||||
let browserWindow = aTarget.tab.ownerDocument.defaultView;
|
||||
return !!TiltManager.getTiltForBrowser(browserWindow).currentInstance;
|
||||
},
|
||||
onChange: function(aTarget, aChangeHandler) {
|
||||
let browserWindow = aTarget.tab.ownerDocument.defaultView;
|
||||
let tilt = TiltManager.getTiltForBrowser(browserWindow);
|
||||
tilt.on("change", aChangeHandler);
|
||||
},
|
||||
offChange: function(aTarget, aChangeHandler) {
|
||||
let browserWindow = aTarget.tab.ownerDocument.defaultView;
|
||||
let tilt = TiltManager.getTiltForBrowser(browserWindow);
|
||||
tilt.off("change", aChangeHandler);
|
||||
},
|
||||
},
|
||||
exec: function(args, context) {
|
||||
let chromeWindow = context.environment.chromeDocument.defaultView;
|
||||
let Tilt = TiltManager.getTiltForBrowser(chromeWindow);
|
||||
|
|
|
@ -46,6 +46,7 @@ const TILT_NOTIFICATIONS = {
|
|||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource:///modules/devtools/TiltGL.jsm");
|
||||
Cu.import("resource:///modules/devtools/TiltUtils.jsm");
|
||||
Cu.import("resource:///modules/devtools/EventEmitter.jsm");
|
||||
Cu.import("resource:///modules/devtools/TiltVisualizer.jsm");
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["TiltManager"];
|
||||
|
@ -87,6 +88,8 @@ this.Tilt = function Tilt(aWindow)
|
|||
*/
|
||||
this.NOTIFICATIONS = TILT_NOTIFICATIONS;
|
||||
|
||||
EventEmitter.decorate(this);
|
||||
|
||||
this.setup();
|
||||
}
|
||||
|
||||
|
@ -128,6 +131,7 @@ Tilt.prototype = {
|
|||
return;
|
||||
}
|
||||
|
||||
this.emit("change", this.chromeWindow.gBrowser.selectedTab);
|
||||
Services.obs.notifyObservers(null, TILT_NOTIFICATIONS.INITIALIZING, null);
|
||||
},
|
||||
|
||||
|
@ -183,6 +187,7 @@ Tilt.prototype = {
|
|||
|
||||
this._isDestroying = false;
|
||||
this.chromeWindow.gBrowser.selectedBrowser.focus();
|
||||
this.emit("change", this.chromeWindow.gBrowser.selectedTab);
|
||||
Services.obs.notifyObservers(null, TILT_NOTIFICATIONS.DESTROYED, null);
|
||||
},
|
||||
|
||||
|
|
|
@ -30,10 +30,10 @@ WebConsolePanel.prototype = {
|
|||
* open is effectively an asynchronous constructor
|
||||
*/
|
||||
open: function StyleEditor_open() {
|
||||
let tab = this._toolbox._getHostTab();
|
||||
let parentDoc = this._frameWindow.document.defaultView.parent.document;
|
||||
let iframe = parentDoc.getElementById("toolbox-panel-iframe-webconsole");
|
||||
this.hud = HUDService.activateHUDForContext(tab, iframe, this._toolbox.target);
|
||||
this.hud = HUDService.activateHUDForContext(this.target.tab, iframe,
|
||||
this._toolbox.target);
|
||||
|
||||
let deferred = Promise.defer();
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ MOCHITEST_BROWSER_FILES = \
|
|||
browser_webconsole_bug_622303_persistent_filters.js \
|
||||
browser_webconsole_bug_770099_bad_policyuri.js \
|
||||
browser_webconsole_bug_770099_violation.js \
|
||||
$(filter disabled-temporarily--bug-808264, browser_webconsole_bug_782653_CSS_links_in_Style_Editor.js) \
|
||||
browser_webconsole_bug_782653_CSS_links_in_Style_Editor.js \
|
||||
browser_cached_messages.js \
|
||||
browser_bug664688_sandbox_update_after_navigation.js \
|
||||
browser_result_format_as_string.js \
|
||||
|
|
|
@ -234,10 +234,11 @@ These should match what Safari and other Apple applications use on OS X Lion. --
|
|||
<!ENTITY devToolbarMenu.accesskey "v">
|
||||
<!ENTITY devToolbar.keycode "VK_F2">
|
||||
<!ENTITY devToolbar.keytext "F2">
|
||||
<!ENTITY devToolbarToolsButton.label "Toggle Toolbox">
|
||||
<!ENTITY devToolbarOtherToolsButton.label "More Tools">
|
||||
<!ENTITY devToolboxMenuItem.label "Toggle Tools">
|
||||
<!ENTITY devToolboxMenuItem.accesskey "T">
|
||||
|
||||
<!ENTITY devToolbox.accesskey "B">
|
||||
<!ENTITY devToolbarToolsButton.tooltip "Toggle developer tools">
|
||||
<!ENTITY devToolbarOtherToolsButton.label "More Tools">
|
||||
|
||||
<!ENTITY getMoreDevtoolsCmd.label "Get More Tools">
|
||||
<!ENTITY getMoreDevtoolsCmd.accesskey "M">
|
||||
|
|
|
@ -2289,6 +2289,14 @@ html|*#gcli-output-frame {
|
|||
|
||||
/* Developer Toolbar */
|
||||
|
||||
#developer-toolbar-toolbox-button {
|
||||
min-width: 18px;
|
||||
}
|
||||
|
||||
#developer-toolbar-toolbox-button > .toolbarbutton-text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.developer-toolbar-button {
|
||||
-moz-appearance: none;
|
||||
min-width: 78px;
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
}
|
||||
|
||||
#command-button-responsive {
|
||||
list-style-image: url(chrome://browser/skin/devtools/command-responsivemode.png);
|
||||
list-style-image: url("chrome://browser/skin/devtools/command-responsivemode.png");
|
||||
-moz-image-region: rect(0px, 16px, 16px, 0px);
|
||||
}
|
||||
#command-button-responsive:hover {
|
||||
|
@ -86,7 +86,7 @@
|
|||
}
|
||||
|
||||
#command-button-tilt {
|
||||
list-style-image: url(chrome://browser/skin/devtools/command-tilt.png);
|
||||
list-style-image: url("chrome://browser/skin/devtools/command-tilt.png");
|
||||
-moz-image-region: rect(0px, 16px, 16px, 0px);
|
||||
}
|
||||
#command-button-tilt:hover {
|
||||
|
@ -102,7 +102,7 @@
|
|||
}
|
||||
|
||||
#command-button-scratchpad {
|
||||
list-style-image: url(chrome://browser/skin/devtools/command-scratchpad.png);
|
||||
list-style-image: url("chrome://browser/skin/devtools/command-scratchpad.png");
|
||||
-moz-image-region: rect(0px, 16px, 16px, 0px);
|
||||
}
|
||||
|
||||
|
@ -119,7 +119,7 @@
|
|||
|
||||
.devtools-tabbar {
|
||||
-moz-appearance: none;
|
||||
background-image: url(background-noise-toolbar.png),
|
||||
background-image: url("background-noise-toolbar.png"),
|
||||
linear-gradient(#303840, #2d3640);
|
||||
border-top: 1px solid #060a0d;
|
||||
box-shadow: 0 1px 0 hsla(204,45%,98%,.05) inset,
|
||||
|
@ -173,7 +173,7 @@
|
|||
background-image: linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1)),
|
||||
linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1)),
|
||||
linear-gradient(hsla(206,37%,4%,.1), hsla(206,37%,4%,.2));
|
||||
background size: 1px 100%,
|
||||
background-size: 1px 100%,
|
||||
1px 100%,
|
||||
100%;
|
||||
background-repeat: no-repeat,
|
||||
|
@ -189,8 +189,8 @@
|
|||
|
||||
.devtools-tab[selected=true] {
|
||||
color: #f5f7fa;
|
||||
background-image: radial-gradient(ellipse farthest-corner at center top, #9fdfff, hsla(200,100%,70%,.3)),
|
||||
radial-gradient(ellipse farthest-side at center top, hsla(200,100%,70%,.4), hsla(200,100%,70%,0)),
|
||||
background-image: radial-gradient(farthest-corner at center top, #9fdfff, hsla(200,100%,70%,.3)),
|
||||
radial-gradient(farthest-side at center top, hsla(200,100%,70%,.4), hsla(200,100%,70%,0)),
|
||||
linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1)),
|
||||
linear-gradient(hsla(204,45%,98%,.02), hsla(204,45%,98%,.04)),
|
||||
linear-gradient(hsla(206,37%,4%,.2), hsla(206,37%,4%,.3));
|
||||
|
|
|
@ -3752,6 +3752,14 @@ html|*#gcli-output-frame {
|
|||
|
||||
/* Developer Toolbar */
|
||||
|
||||
#developer-toolbar-toolbox-button {
|
||||
min-width: 18px;
|
||||
}
|
||||
|
||||
#developer-toolbar-toolbox-button > .toolbarbutton-text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.developer-toolbar-button {
|
||||
-moz-appearance: none;
|
||||
min-width: 78px;
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
}
|
||||
|
||||
#command-button-responsive {
|
||||
list-style-image: url(chrome://browser/skin/devtools/command-responsivemode.png);
|
||||
list-style-image: url("chrome://browser/skin/devtools/command-responsivemode.png");
|
||||
-moz-image-region: rect(0px, 16px, 16px, 0px);
|
||||
}
|
||||
#command-button-responsive:hover {
|
||||
|
@ -73,7 +73,7 @@
|
|||
}
|
||||
|
||||
#command-button-tilt {
|
||||
list-style-image: url(chrome://browser/skin/devtools/command-tilt.png);
|
||||
list-style-image: url("chrome://browser/skin/devtools/command-tilt.png");
|
||||
-moz-image-region: rect(0px, 16px, 16px, 0px);
|
||||
}
|
||||
#command-button-tilt:hover {
|
||||
|
@ -89,7 +89,7 @@
|
|||
}
|
||||
|
||||
#command-button-scratchpad {
|
||||
list-style-image: url(chrome://browser/skin/devtools/command-scratchpad.png);
|
||||
list-style-image: url("chrome://browser/skin/devtools/command-scratchpad.png");
|
||||
-moz-image-region: rect(0px, 16px, 16px, 0px);
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,7 @@
|
|||
|
||||
.devtools-tabbar {
|
||||
-moz-appearance: none;
|
||||
background-image: url(background-noise-toolbar.png),
|
||||
background-image: url("background-noise-toolbar.png"),
|
||||
linear-gradient(#303840, #2d3640);
|
||||
border-top: 1px solid #060a0d;
|
||||
box-shadow: 0 1px 0 hsla(204,45%,98%,.05) inset,
|
||||
|
@ -157,7 +157,7 @@
|
|||
background-image: linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1)),
|
||||
linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1)),
|
||||
linear-gradient(hsla(206,37%,4%,.1), hsla(206,37%,4%,.2));
|
||||
background size: 1px 100%,
|
||||
background-size: 1px 100%,
|
||||
1px 100%,
|
||||
100%;
|
||||
background-repeat: no-repeat,
|
||||
|
@ -173,8 +173,8 @@
|
|||
|
||||
.devtools-tab[selected=true] {
|
||||
color: #f5f7fa;
|
||||
background-image: radial-gradient(ellipse farthest-corner at center top, #9fdfff, hsla(200,100%,70%,.3)),
|
||||
radial-gradient(ellipse farthest-side at center top, hsla(200,100%,70%,.4), hsla(200,100%,70%,0)),
|
||||
background-image: radial-gradient(farthest-corner at center top, #9fdfff, hsla(200,100%,70%,.3)),
|
||||
radial-gradient(farthest-side at center top, hsla(200,100%,70%,.4), hsla(200,100%,70%,0)),
|
||||
linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1)),
|
||||
linear-gradient(hsla(204,45%,98%,.02), hsla(204,45%,98%,.04)),
|
||||
linear-gradient(hsla(206,37%,4%,.2), hsla(206,37%,4%,.3));
|
||||
|
|
|
@ -2972,6 +2972,14 @@ html|*#gcli-output-frame {
|
|||
|
||||
/* Developer Toolbar */
|
||||
|
||||
#developer-toolbar-toolbox-button {
|
||||
min-width: 18px;
|
||||
}
|
||||
|
||||
#developer-toolbar-toolbox-button > .toolbarbutton-text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.developer-toolbar-button {
|
||||
-moz-appearance: none;
|
||||
min-width: 78px;
|
||||
|
|
|
@ -75,7 +75,7 @@
|
|||
}
|
||||
|
||||
#command-button-responsive {
|
||||
list-style-image: url(chrome://browser/skin/devtools/command-responsivemode.png);
|
||||
list-style-image: url("chrome://browser/skin/devtools/command-responsivemode.png");
|
||||
-moz-image-region: rect(0px, 16px, 16px, 0px);
|
||||
}
|
||||
#command-button-responsive:hover {
|
||||
|
@ -89,7 +89,7 @@
|
|||
}
|
||||
|
||||
#command-button-tilt {
|
||||
list-style-image: url(chrome://browser/skin/devtools/command-tilt.png);
|
||||
list-style-image: url("chrome://browser/skin/devtools/command-tilt.png");
|
||||
-moz-image-region: rect(0px, 16px, 16px, 0px);
|
||||
}
|
||||
#command-button-tilt:hover {
|
||||
|
@ -105,7 +105,7 @@
|
|||
}
|
||||
|
||||
#command-button-scratchpad {
|
||||
list-style-image: url(chrome://browser/skin/devtools/command-scratchpad.png);
|
||||
list-style-image: url("chrome://browser/skin/devtools/command-scratchpad.png");
|
||||
-moz-image-region: rect(0px, 16px, 16px, 0px);
|
||||
}
|
||||
|
||||
|
@ -122,7 +122,7 @@
|
|||
|
||||
.devtools-tabbar {
|
||||
-moz-appearance: none;
|
||||
background-image: url(background-noise-toolbar.png),
|
||||
background-image: url("background-noise-toolbar.png"),
|
||||
linear-gradient(#303840, #2d3640);
|
||||
border: none;
|
||||
box-shadow: 0 1px 0 hsla(204,45%,98%,.05) inset,
|
||||
|
@ -174,7 +174,7 @@
|
|||
background-image: linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1)),
|
||||
linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1)),
|
||||
linear-gradient(hsla(206,37%,4%,.1), hsla(206,37%,4%,.2));
|
||||
background size: 1px 100%,
|
||||
background-size: 1px 100%,
|
||||
1px 100%,
|
||||
100%;
|
||||
background-repeat: no-repeat,
|
||||
|
@ -190,8 +190,8 @@
|
|||
|
||||
.devtools-tab[selected=true] {
|
||||
color: #f5f7fa;
|
||||
background-image: radial-gradient(ellipse farthest-corner at center top, #9fdfff, hsla(200,100%,70%,.3)),
|
||||
radial-gradient(ellipse farthest-side at center top, hsla(200,100%,70%,.4), hsla(200,100%,70%,0)),
|
||||
background-image: radial-gradient(farthest-corner at center top, #9fdfff, hsla(200,100%,70%,.3)),
|
||||
radial-gradient(farthest-side at center top, hsla(200,100%,70%,.4), hsla(200,100%,70%,0)),
|
||||
linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1)),
|
||||
linear-gradient(hsla(204,45%,98%,.02), hsla(204,45%,98%,.04)),
|
||||
linear-gradient(hsla(206,37%,4%,.2), hsla(206,37%,4%,.3));
|
||||
|
|
|
@ -688,7 +688,9 @@ nsXULPrototypeDocument::TraceProtos(JSTracer* aTrc, uint32_t aGCNumber)
|
|||
}
|
||||
|
||||
mGCNumber = aGCNumber;
|
||||
mRoot->TraceAllScripts(aTrc);
|
||||
if (mRoot) {
|
||||
mRoot->TraceAllScripts(aTrc);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
|
|
@ -6,8 +6,35 @@
|
|||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const ContentPanning = {
|
||||
// Are we listening to touch or mouse events?
|
||||
watchedEventsType: '',
|
||||
|
||||
// Are mouse events being delivered to this content along with touch
|
||||
// events, in violation of spec?
|
||||
hybridEvents: false,
|
||||
|
||||
init: function cp_init() {
|
||||
['mousedown', 'mouseup', 'mousemove'].forEach(function(type) {
|
||||
var events;
|
||||
try {
|
||||
content.document.createEvent('TouchEvent');
|
||||
events = ['touchstart', 'touchend', 'touchmove'];
|
||||
this.watchedEventsType = 'touch';
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
// The gonk widget backend does not deliver mouse events per
|
||||
// spec. Third-party content isn't exposed to this behavior,
|
||||
// but that behavior creates some extra work for us here.
|
||||
let appInfo = Cc["@mozilla.org/xre/app-info;1"];
|
||||
let isParentProcess =
|
||||
!appInfo || appInfo.getService(Ci.nsIXULRuntime)
|
||||
.processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
|
||||
this.hybridEvents = isParentProcess;
|
||||
#endif
|
||||
} catch(e) {
|
||||
// Touch events aren't supported, so fall back on mouse.
|
||||
events = ['mousedown', 'mouseup', 'mousemove'];
|
||||
this.watchedEventsType = 'mouse';
|
||||
}
|
||||
events.forEach(function(type) {
|
||||
addEventListener(type, ContentPanning, false);
|
||||
});
|
||||
|
||||
|
@ -16,14 +43,20 @@ const ContentPanning = {
|
|||
},
|
||||
|
||||
handleEvent: function cp_handleEvent(evt) {
|
||||
if (evt.defaultPrevented)
|
||||
return;
|
||||
|
||||
switch (evt.type) {
|
||||
case 'mousedown':
|
||||
case 'touchstart':
|
||||
this.onTouchStart(evt);
|
||||
break;
|
||||
case 'mousemove':
|
||||
case 'touchmove':
|
||||
this.onTouchMove(evt);
|
||||
break;
|
||||
case 'mouseup':
|
||||
case 'touchend':
|
||||
this.onTouchEnd(evt);
|
||||
break;
|
||||
case 'click':
|
||||
|
@ -40,21 +73,68 @@ const ContentPanning = {
|
|||
|
||||
position: new Point(0 , 0),
|
||||
|
||||
findPrimaryPointer: function cp_findPrimaryPointer(touches) {
|
||||
if (!('primaryPointerId' in this))
|
||||
return null;
|
||||
|
||||
for (let i = 0; i < touches.length; i++) {
|
||||
if (touches[i].identifier === this.primaryPointerId) {
|
||||
return touches[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
onTouchStart: function cp_onTouchStart(evt) {
|
||||
let screenX, screenY;
|
||||
if (this.watchedEventsType == 'touch') {
|
||||
if ('primaryPointerId' in this) {
|
||||
return;
|
||||
}
|
||||
|
||||
let firstTouch = evt.changedTouches[0];
|
||||
this.primaryPointerId = firstTouch.identifier;
|
||||
this.pointerDownTarget = firstTouch.target;
|
||||
screenX = firstTouch.screenX;
|
||||
screenY = firstTouch.screenY;
|
||||
} else {
|
||||
this.pointerDownTarget = evt.target;
|
||||
screenX = evt.screenX;
|
||||
screenY = evt.screenY;
|
||||
}
|
||||
this.dragging = true;
|
||||
this.panning = false;
|
||||
|
||||
let oldTarget = this.target;
|
||||
[this.target, this.scrollCallback] = this.getPannable(evt.target);
|
||||
[this.target, this.scrollCallback] = this.getPannable(this.pointerDownTarget);
|
||||
|
||||
// If we found a target, that means we have found a scrollable subframe. In
|
||||
// this case, and if we are using async panning and zooming on the parent
|
||||
// frame, inform the pan/zoom controller that it should not attempt to
|
||||
// handle any touch events it gets until the next batch (meaning the next
|
||||
// time we get a touch end).
|
||||
if (this.target != null && ContentPanning._asyncPanZoomForViewportFrame) {
|
||||
if (this.target != null && this._asyncPanZoomForViewportFrame) {
|
||||
this.detectingScrolling = true;
|
||||
var os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
|
||||
os.notifyObservers(docShell, 'cancel-default-pan-zoom', null);
|
||||
os.notifyObservers(docShell, 'detect-scrollable-subframe', null);
|
||||
}
|
||||
|
||||
// If we have a pointer down target and we're not async
|
||||
// pan/zooming, we may need to fill in for EventStateManager in
|
||||
// setting the active state on the target element. Set a timer to
|
||||
// ensure the pointer-down target is active. (If it's already
|
||||
// active, the timer is a no-op.)
|
||||
if (this.pointerDownTarget !== null && !this.detectingScrolling) {
|
||||
// If there's no possibility this is a drag/pan, activate now.
|
||||
// Otherwise wait a little bit to see if the gesture isn't a
|
||||
// tap.
|
||||
if (this.target === null) {
|
||||
this.notify(this._activationTimer);
|
||||
} else {
|
||||
this._activationTimer.initWithCallback(this,
|
||||
this._activationDelayMs,
|
||||
Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
}
|
||||
}
|
||||
|
||||
// If there is a pan animation running (from a previous pan gesture) and
|
||||
|
@ -69,19 +149,38 @@ const ContentPanning = {
|
|||
this.preventNextClick = true;
|
||||
}
|
||||
|
||||
|
||||
this.position.set(evt.screenX, evt.screenY);
|
||||
this.position.set(screenX, screenY);
|
||||
KineticPanning.record(new Point(0, 0), evt.timeStamp);
|
||||
},
|
||||
|
||||
onTouchEnd: function cp_onTouchEnd(evt) {
|
||||
if (!this.dragging)
|
||||
let touch = null;
|
||||
if (!this.dragging ||
|
||||
(this.watchedEventsType == 'touch' &&
|
||||
!(touch = this.findPrimaryPointer(evt.changedTouches)))) {
|
||||
return;
|
||||
this.dragging = false;
|
||||
}
|
||||
|
||||
this.onTouchMove(evt);
|
||||
// !isPan() and evt.detail should always give the same answer here
|
||||
// since they use the same heuristics, but use the native gecko
|
||||
// computation when possible.
|
||||
//
|
||||
// NB: when we're using touch events, then !KineticPanning.isPan()
|
||||
// => this.panning, so we'll never attempt to block the click
|
||||
// event. That's OK however, because we won't fire a synthetic
|
||||
// click when we're using touch events and this touch series
|
||||
// wasn't a "tap" gesture.
|
||||
let click = (this.watchedEventsType == 'mouse') ?
|
||||
evt.detail : !KineticPanning.isPan();
|
||||
// Additionally, if we're seeing non-compliant hybrid events, a
|
||||
// "real" click will be generated if we started and ended on the
|
||||
// same element.
|
||||
if (this.hybridEvents) {
|
||||
let target =
|
||||
content.document.elementFromPoint(touch.clientX, touch.clientY);
|
||||
click |= (target === this.pointerDownTarget);
|
||||
}
|
||||
|
||||
let click = evt.detail;
|
||||
if (this.target && click && (this.panning || this.preventNextClick)) {
|
||||
let target = this.target;
|
||||
let view = target.ownerDocument ? target.ownerDocument.defaultView
|
||||
|
@ -89,31 +188,84 @@ const ContentPanning = {
|
|||
view.addEventListener('click', this, true, true);
|
||||
}
|
||||
|
||||
if (this.panning)
|
||||
this._resetActive();
|
||||
this.dragging = false;
|
||||
this.detectingScrolling = false;
|
||||
delete this.primaryPointerId;
|
||||
this._activationTimer.cancel();
|
||||
|
||||
if (this.panning) {
|
||||
KineticPanning.start(this);
|
||||
}
|
||||
},
|
||||
|
||||
// True when there's an async pan-zoom controll watching the
|
||||
// outermost scrollable frame, and we're waiting to see whether
|
||||
// we're going to take over from it and synchronously scroll an
|
||||
// inner scrollable frame.
|
||||
detectingScrolling: false,
|
||||
|
||||
onTouchMove: function cp_onTouchMove(evt) {
|
||||
if (!this.dragging || !this.scrollCallback)
|
||||
if (!this.dragging)
|
||||
return;
|
||||
|
||||
let screenX, screenY;
|
||||
if (this.watchedEventsType == 'touch') {
|
||||
let primaryTouch = this.findPrimaryPointer(evt.changedTouches);
|
||||
if (evt.touches.length > 1 || !primaryTouch)
|
||||
return;
|
||||
screenX = primaryTouch.screenX;
|
||||
screenY = primaryTouch.screenY;
|
||||
} else {
|
||||
screenX = evt.screenX;
|
||||
screenY = evt.screenY;
|
||||
}
|
||||
|
||||
let current = this.position;
|
||||
let delta = new Point(evt.screenX - current.x, evt.screenY - current.y);
|
||||
current.set(evt.screenX, evt.screenY);
|
||||
let delta = new Point(screenX - current.x, screenY - current.y);
|
||||
current.set(screenX, screenY);
|
||||
|
||||
KineticPanning.record(delta, evt.timeStamp);
|
||||
|
||||
// There's no possibility of us panning anything.
|
||||
if (!this.scrollCallback) {
|
||||
return;
|
||||
}
|
||||
|
||||
let isPan = KineticPanning.isPan();
|
||||
if (this.detectingScrolling) {
|
||||
this.detectingScrolling = false;
|
||||
// Stop async-pan-zooming if the user is panning the subframe.
|
||||
if (isPan) {
|
||||
// We're going to drive synchronously scrolling an inner frame.
|
||||
Services.obs.notifyObservers(docShell, 'cancel-default-pan-zoom', null);
|
||||
} else {
|
||||
// Let AsyncPanZoomController handle the scrolling gesture.
|
||||
this.scrollCallback = null;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.scrollCallback(delta.scale(-1));
|
||||
|
||||
// If a pan action happens, cancel the active state of the
|
||||
// current target.
|
||||
if (!this.panning && KineticPanning.isPan()) {
|
||||
if (!this.panning && isPan) {
|
||||
this.panning = true;
|
||||
this._resetActive();
|
||||
this._activationTimer.cancel();
|
||||
}
|
||||
|
||||
if (this.panning) {
|
||||
evt.stopPropagation();
|
||||
evt.preventDefault();
|
||||
}
|
||||
evt.stopPropagation();
|
||||
evt.preventDefault();
|
||||
},
|
||||
|
||||
// nsITimerCallback
|
||||
notify: function cp_notify(timer) {
|
||||
this._setActive(this.pointerDownTarget);
|
||||
},
|
||||
|
||||
onKineticBegin: function cp_onKineticBegin(evt) {
|
||||
},
|
||||
|
@ -249,11 +401,27 @@ const ContentPanning = {
|
|||
.getService(Ci.inIDOMUtils);
|
||||
},
|
||||
|
||||
_resetActive: function cp_resetActive() {
|
||||
let root = this.target.ownerDocument || this.target.document;
|
||||
get _activationTimer() {
|
||||
delete this._activationTimer;
|
||||
return this._activationTimer = Cc["@mozilla.org/timer;1"]
|
||||
.createInstance(Ci.nsITimer);
|
||||
},
|
||||
|
||||
get _activationDelayMs() {
|
||||
let delay = Services.prefs.getIntPref('ui.touch_activation.delay_ms');
|
||||
delete this._activationDelayMs;
|
||||
return this._activationDelayMs = delay;
|
||||
},
|
||||
|
||||
_resetActive: function cp_resetActive() {
|
||||
let elt = this.target || this.pointerDownTarget;
|
||||
let root = elt.ownerDocument || elt.document;
|
||||
this._setActive(root.documentElement);
|
||||
},
|
||||
|
||||
_setActive: function cp_setActive(elt) {
|
||||
const kStateActive = 0x00000001;
|
||||
this._domUtils.setContentState(root.documentElement, kStateActive);
|
||||
this._domUtils.setContentState(elt, kStateActive);
|
||||
},
|
||||
|
||||
get _asyncPanZoomForViewportFrame() {
|
||||
|
|
|
@ -97,6 +97,7 @@ static const nsIntSize kDefaultViewportSize(980, 480);
|
|||
static const char CANCEL_DEFAULT_PAN_ZOOM[] = "cancel-default-pan-zoom";
|
||||
static const char BROWSER_ZOOM_TO_RECT[] = "browser-zoom-to-rect";
|
||||
static const char BEFORE_FIRST_PAINT[] = "before-first-paint";
|
||||
static const char DETECT_SCROLLABLE_SUBFRAME[] = "detect-scrollable-subframe";
|
||||
|
||||
NS_IMETHODIMP
|
||||
ContentListener::HandleEvent(nsIDOMEvent* aEvent)
|
||||
|
@ -162,6 +163,8 @@ TabChild::TabChild(const TabContext& aContext, uint32_t aChromeFlags)
|
|||
, mChromeFlags(aChromeFlags)
|
||||
, mOuterRect(0, 0, 0, 0)
|
||||
, mInnerSize(0, 0)
|
||||
, mActivePointerId(-1)
|
||||
, mTapHoldTimer(nullptr)
|
||||
, mOldViewportWidth(0.0f)
|
||||
, mLastBackgroundColor(NS_RGB(255, 255, 255))
|
||||
, mDidFakeShow(false)
|
||||
|
@ -243,6 +246,12 @@ TabChild::Observe(nsISupports *aSubject,
|
|||
HandlePossibleViewportChange();
|
||||
}
|
||||
}
|
||||
} else if (!strcmp(aTopic, DETECT_SCROLLABLE_SUBFRAME)) {
|
||||
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aSubject));
|
||||
nsCOMPtr<nsITabChild> tabChild(GetTabChildFrom(docShell));
|
||||
if (tabChild == this) {
|
||||
mRemoteFrame->DetectScrollableSubframe();
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -1349,42 +1358,135 @@ TabChild::RecvMouseWheelEvent(const WheelEvent& event)
|
|||
}
|
||||
|
||||
void
|
||||
TabChild::DispatchSynthesizedMouseEvent(const nsTouchEvent& aEvent)
|
||||
TabChild::DispatchSynthesizedMouseEvent(uint32_t aMsg, uint64_t aTime,
|
||||
const nsIntPoint& aRefPoint)
|
||||
{
|
||||
// Synthesize a phony mouse event.
|
||||
uint32_t msg;
|
||||
switch (aEvent.message) {
|
||||
case NS_TOUCH_START:
|
||||
msg = NS_MOUSE_BUTTON_DOWN;
|
||||
break;
|
||||
case NS_TOUCH_MOVE:
|
||||
msg = NS_MOUSE_MOVE;
|
||||
break;
|
||||
case NS_TOUCH_END:
|
||||
case NS_TOUCH_CANCEL:
|
||||
msg = NS_MOUSE_BUTTON_UP;
|
||||
break;
|
||||
default:
|
||||
MOZ_NOT_REACHED("Unknown touch event message");
|
||||
}
|
||||
MOZ_ASSERT(aMsg == NS_MOUSE_MOVE || aMsg == NS_MOUSE_BUTTON_DOWN ||
|
||||
aMsg == NS_MOUSE_BUTTON_UP);
|
||||
|
||||
nsIntPoint refPoint(0, 0);
|
||||
if (aEvent.touches.Length()) {
|
||||
refPoint = aEvent.touches[0]->mRefPoint;
|
||||
}
|
||||
|
||||
nsMouseEvent event(true, msg, NULL,
|
||||
nsMouseEvent event(true, aMsg, NULL,
|
||||
nsMouseEvent::eReal, nsMouseEvent::eNormal);
|
||||
event.refPoint = refPoint;
|
||||
event.time = aEvent.time;
|
||||
event.refPoint = aRefPoint;
|
||||
event.time = aTime;
|
||||
event.button = nsMouseEvent::eLeftButton;
|
||||
if (msg != NS_MOUSE_MOVE) {
|
||||
if (aMsg != NS_MOUSE_MOVE) {
|
||||
event.clickCount = 1;
|
||||
}
|
||||
|
||||
DispatchWidgetEvent(event);
|
||||
}
|
||||
|
||||
static nsDOMTouch*
|
||||
GetTouchForIdentifier(const nsTouchEvent& aEvent, int32_t aId)
|
||||
{
|
||||
for (uint32_t i = 0; i < aEvent.touches.Length(); ++i) {
|
||||
nsDOMTouch* touch = static_cast<nsDOMTouch*>(aEvent.touches[i].get());
|
||||
if (touch->mIdentifier == aId) {
|
||||
return touch;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
TabChild::UpdateTapState(const nsTouchEvent& aEvent, nsEventStatus aStatus)
|
||||
{
|
||||
static bool sHavePrefs;
|
||||
static bool sClickHoldContextMenusEnabled;
|
||||
static nsIntSize sDragThreshold;
|
||||
static int32_t sContextMenuDelayMs;
|
||||
if (!sHavePrefs) {
|
||||
sHavePrefs = true;
|
||||
Preferences::AddBoolVarCache(&sClickHoldContextMenusEnabled,
|
||||
"ui.click_hold_context_menus", true);
|
||||
Preferences::AddIntVarCache(&sDragThreshold.width,
|
||||
"ui.dragThresholdX", 25);
|
||||
Preferences::AddIntVarCache(&sDragThreshold.height,
|
||||
"ui.dragThresholdY", 25);
|
||||
Preferences::AddIntVarCache(&sContextMenuDelayMs,
|
||||
"ui.click_hold_context_menus.delay", 500);
|
||||
}
|
||||
|
||||
bool currentlyTrackingTouch = (mActivePointerId >= 0);
|
||||
if (aEvent.message == NS_TOUCH_START) {
|
||||
if (currentlyTrackingTouch || aEvent.touches.Length() > 1) {
|
||||
// We're tracking a possible tap for another point, or we saw a
|
||||
// touchstart for a later pointer after we canceled tracking of
|
||||
// the first point. Ignore this one.
|
||||
return;
|
||||
}
|
||||
if (aStatus == nsEventStatus_eConsumeNoDefault ||
|
||||
nsIPresShell::gPreventMouseEvents) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsDOMTouch* touch = static_cast<nsDOMTouch*>(aEvent.touches[0].get());
|
||||
mGestureDownPoint = touch->mRefPoint;
|
||||
mActivePointerId = touch->mIdentifier;
|
||||
if (sClickHoldContextMenusEnabled) {
|
||||
MOZ_ASSERT(!mTapHoldTimer);
|
||||
mTapHoldTimer = NewRunnableMethod(this,
|
||||
&TabChild::FireContextMenuEvent);
|
||||
MessageLoop::current()->PostDelayedTask(FROM_HERE, mTapHoldTimer,
|
||||
sContextMenuDelayMs);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// If we're not tracking a touch or this event doesn't include the
|
||||
// one we care about, bail.
|
||||
if (!currentlyTrackingTouch) {
|
||||
return;
|
||||
}
|
||||
nsDOMTouch* trackedTouch = GetTouchForIdentifier(aEvent, mActivePointerId);
|
||||
if (!trackedTouch) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsIntPoint currentPoint = trackedTouch->mRefPoint;
|
||||
int64_t time = aEvent.time;
|
||||
switch (aEvent.message) {
|
||||
case NS_TOUCH_MOVE:
|
||||
if (abs(currentPoint.x - mGestureDownPoint.x) > sDragThreshold.width ||
|
||||
abs(currentPoint.y - mGestureDownPoint.y) > sDragThreshold.height) {
|
||||
CancelTapTracking();
|
||||
}
|
||||
return;
|
||||
|
||||
case NS_TOUCH_END:
|
||||
if (!nsIPresShell::gPreventMouseEvents) {
|
||||
DispatchSynthesizedMouseEvent(NS_MOUSE_MOVE, time, currentPoint);
|
||||
DispatchSynthesizedMouseEvent(NS_MOUSE_BUTTON_DOWN, time, currentPoint);
|
||||
DispatchSynthesizedMouseEvent(NS_MOUSE_BUTTON_UP, time, currentPoint);
|
||||
}
|
||||
// fall through
|
||||
case NS_TOUCH_CANCEL:
|
||||
CancelTapTracking();
|
||||
return;
|
||||
|
||||
default:
|
||||
NS_WARNING("Unknown touch event type");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TabChild::FireContextMenuEvent()
|
||||
{
|
||||
MOZ_ASSERT(mTapHoldTimer && mActivePointerId >= 0);
|
||||
RecvHandleLongTap(mGestureDownPoint);
|
||||
CancelTapTracking();
|
||||
}
|
||||
|
||||
void
|
||||
TabChild::CancelTapTracking()
|
||||
{
|
||||
mActivePointerId = -1;
|
||||
if (mTapHoldTimer) {
|
||||
mTapHoldTimer->Cancel();
|
||||
}
|
||||
mTapHoldTimer = nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::RecvRealTouchEvent(const nsTouchEvent& aEvent)
|
||||
{
|
||||
|
@ -1398,8 +1500,8 @@ TabChild::RecvRealTouchEvent(const nsTouchEvent& aEvent)
|
|||
if (innerWindow && innerWindow->HasTouchEventListeners()) {
|
||||
SendContentReceivedTouch(nsIPresShell::gPreventMouseEvents);
|
||||
}
|
||||
} else if (status != nsEventStatus_eConsumeNoDefault) {
|
||||
DispatchSynthesizedMouseEvent(aEvent);
|
||||
} else {
|
||||
UpdateTapState(aEvent, status);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -1680,6 +1782,7 @@ TabChild::RecvDestroy()
|
|||
observerService->RemoveObserver(this, CANCEL_DEFAULT_PAN_ZOOM);
|
||||
observerService->RemoveObserver(this, BROWSER_ZOOM_TO_RECT);
|
||||
observerService->RemoveObserver(this, BEFORE_FIRST_PAINT);
|
||||
observerService->RemoveObserver(this, DETECT_SCROLLABLE_SUBFRAME);
|
||||
|
||||
const InfallibleTArray<PIndexedDBChild*>& idbActors =
|
||||
ManagedPIndexedDBChild();
|
||||
|
@ -1815,6 +1918,9 @@ TabChild::InitRenderingState()
|
|||
observerService->AddObserver(this,
|
||||
BEFORE_FIRST_PAINT,
|
||||
false);
|
||||
observerService->AddObserver(this,
|
||||
DETECT_SCROLLABLE_SUBFRAME,
|
||||
false);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -384,8 +384,18 @@ private:
|
|||
void DispatchMessageManagerMessage(const nsAString& aMessageName,
|
||||
const nsACString& aJSONData);
|
||||
|
||||
// Sends a simulated mouse event from a touch event for compatibility.
|
||||
void DispatchSynthesizedMouseEvent(const nsTouchEvent& aEvent);
|
||||
void DispatchSynthesizedMouseEvent(uint32_t aMsg, uint64_t aTime,
|
||||
const nsIntPoint& aRefPoint);
|
||||
|
||||
// These methods are used for tracking synthetic mouse events
|
||||
// dispatched for compatibility. On each touch event, we
|
||||
// UpdateTapState(). If we've detected that the current gesture
|
||||
// isn't a tap, then we CancelTapTracking(). In the meantime, we
|
||||
// may detect a context-menu event, and if so we
|
||||
// FireContextMenuEvent().
|
||||
void FireContextMenuEvent();
|
||||
void CancelTapTracking();
|
||||
void UpdateTapState(const nsTouchEvent& aEvent, nsEventStatus aStatus);
|
||||
|
||||
nsresult
|
||||
BrowserFrameProvideWindow(nsIDOMWindow* aOpener,
|
||||
|
@ -411,6 +421,15 @@ private:
|
|||
uint32_t mChromeFlags;
|
||||
nsIntRect mOuterRect;
|
||||
nsIntSize mInnerSize;
|
||||
// When we're tracking a possible tap gesture, this is the "down"
|
||||
// point of the touchstart.
|
||||
nsIntPoint mGestureDownPoint;
|
||||
// The touch identifier of the active gesture.
|
||||
int32_t mActivePointerId;
|
||||
// A timer task that fires if the tap-hold timeout is exceeded by
|
||||
// the touch we're tracking. That is, if touchend or a touchmove
|
||||
// that exceeds the gesture threshold doesn't happen.
|
||||
CancelableTask* mTapHoldTimer;
|
||||
float mOldViewportWidth;
|
||||
nscolor mLastBackgroundColor;
|
||||
ScrollingBehavior mScrolling;
|
||||
|
|
|
@ -248,6 +248,26 @@ nsEventStatus AsyncPanZoomController::HandleInputEvent(const InputData& aEvent)
|
|||
return rv;
|
||||
}
|
||||
|
||||
if (mDelayPanning && aEvent.mInputType == MULTITOUCH_INPUT) {
|
||||
const MultiTouchInput& multiTouchInput = aEvent.AsMultiTouchInput();
|
||||
if (multiTouchInput.mType == MultiTouchInput::MULTITOUCH_MOVE) {
|
||||
// Let BrowserElementScrolling perform panning gesture first.
|
||||
SetState(WAITING_LISTENERS);
|
||||
mTouchQueue.AppendElement(multiTouchInput);
|
||||
|
||||
if (!mTouchListenerTimeoutTask) {
|
||||
mTouchListenerTimeoutTask =
|
||||
NewRunnableMethod(this, &AsyncPanZoomController::TimeoutTouchListeners);
|
||||
|
||||
MessageLoop::current()->PostDelayedTask(
|
||||
FROM_HERE,
|
||||
mTouchListenerTimeoutTask,
|
||||
TOUCH_LISTENER_TIMEOUT);
|
||||
}
|
||||
return nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
}
|
||||
|
||||
switch (aEvent.mInputType) {
|
||||
case MULTITOUCH_INPUT: {
|
||||
const MultiTouchInput& multiTouchInput = aEvent.AsMultiTouchInput();
|
||||
|
@ -1137,6 +1157,7 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aViewportFr
|
|||
|
||||
mLastContentPaintMetrics = aViewportFrame;
|
||||
|
||||
mFrameMetrics.mMayHaveTouchListeners = aViewportFrame.mMayHaveTouchListeners;
|
||||
if (mWaitingForContentToPaint) {
|
||||
// Remove the oldest sample we have if adding a new sample takes us over our
|
||||
// desired number of samples.
|
||||
|
@ -1230,6 +1251,10 @@ void AsyncPanZoomController::CancelDefaultPanZoom() {
|
|||
}
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::DetectScrollableSubframe() {
|
||||
mDelayPanning = true;
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::ZoomToRect(const gfxRect& aRect) {
|
||||
gfx::Rect zoomToRect(gfx::Rect(aRect.x, aRect.y, aRect.width, aRect.height));
|
||||
|
||||
|
@ -1316,7 +1341,7 @@ void AsyncPanZoomController::ZoomToRect(const gfxRect& aRect) {
|
|||
}
|
||||
|
||||
void AsyncPanZoomController::ContentReceivedTouch(bool aPreventDefault) {
|
||||
if (!mFrameMetrics.mMayHaveTouchListeners) {
|
||||
if (!mFrameMetrics.mMayHaveTouchListeners && !mDelayPanning) {
|
||||
mTouchQueue.Clear();
|
||||
return;
|
||||
}
|
||||
|
@ -1328,12 +1353,21 @@ void AsyncPanZoomController::ContentReceivedTouch(bool aPreventDefault) {
|
|||
|
||||
if (mState == WAITING_LISTENERS) {
|
||||
if (!aPreventDefault) {
|
||||
SetState(NOTHING);
|
||||
// Delayed scrolling gesture is pending at TOUCHING state.
|
||||
if (mDelayPanning) {
|
||||
SetState(TOUCHING);
|
||||
} else {
|
||||
SetState(NOTHING);
|
||||
}
|
||||
}
|
||||
|
||||
mHandlingTouchQueue = true;
|
||||
|
||||
while (!mTouchQueue.IsEmpty()) {
|
||||
// we need to reset mDelayPanning before handling scrolling gesture.
|
||||
if (mTouchQueue[0].mType == MultiTouchInput::MULTITOUCH_MOVE) {
|
||||
mDelayPanning = false;
|
||||
}
|
||||
if (!aPreventDefault) {
|
||||
HandleInputEvent(mTouchQueue[0]);
|
||||
}
|
||||
|
|
|
@ -109,7 +109,7 @@ public:
|
|||
void UpdateCompositionBounds(const nsIntRect& aCompositionBounds);
|
||||
|
||||
/**
|
||||
* We have found a scrollable subframe, so disable our machinery until we hit
|
||||
* We are scrolling a subframe, so disable our machinery until we hit
|
||||
* a touch end or a new touch start. This prevents us from accidentally
|
||||
* panning both the subframe and the parent frame.
|
||||
*
|
||||
|
@ -118,6 +118,12 @@ public:
|
|||
*/
|
||||
void CancelDefaultPanZoom();
|
||||
|
||||
/**
|
||||
* We have found a scrollable subframe, so we need to delay the scrolling
|
||||
* gesture executed and let subframe do the scrolling first.
|
||||
*/
|
||||
void DetectScrollableSubframe();
|
||||
|
||||
/**
|
||||
* Kicks an animation to zoom to a rect. This may be either a zoom out or zoom
|
||||
* in. The actual animation is done on the compositor thread after being set
|
||||
|
@ -585,6 +591,12 @@ private:
|
|||
// and we don't want to queue the events back up again.
|
||||
bool mHandlingTouchQueue;
|
||||
|
||||
// Flag used to determine whether or not we should try scrolling by
|
||||
// BrowserElementScrolling first. If set, we delay delivering
|
||||
// touchmove events to GestureListener until BrowserElementScrolling
|
||||
// decides whether it wants to handle panning for this touch series.
|
||||
bool mDelayPanning;
|
||||
|
||||
friend class Axis;
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
// addAllGlobalsAsDebuggees adds all the globals as debuggees.
|
||||
|
||||
var g1 = newGlobal(); // Created before the Debugger; debuggee.
|
||||
var g2 = newGlobal(); // Created before the Debugger; not debuggee.
|
||||
|
||||
var dbg = new Debugger;
|
||||
|
||||
var g3 = newGlobal(); // Created after the Debugger; debuggee.
|
||||
var g4 = newGlobal(); // Created after the Debugger; not debuggee.
|
||||
|
||||
var g1w = dbg.addDebuggee(g1);
|
||||
assertEq(dbg.addAllGlobalsAsDebuggees(), undefined);
|
||||
|
||||
// Get Debugger.Objects viewing the globals from their own compartments;
|
||||
// this is the sort that findAllGlobals and addDebuggee return.
|
||||
var g1w = g1w.makeDebuggeeValue(g1).unwrap();
|
||||
var g2w = g1w.makeDebuggeeValue(g2).unwrap();
|
||||
var g3w = g1w.makeDebuggeeValue(g3).unwrap();
|
||||
var g4w = g1w.makeDebuggeeValue(g4).unwrap();
|
||||
var thisw = g1w.makeDebuggeeValue(this).unwrap();
|
||||
|
||||
// Check that they're all there.
|
||||
assertEq(dbg.hasDebuggee(g1w), true);
|
||||
assertEq(dbg.hasDebuggee(g2w), true);
|
||||
assertEq(dbg.hasDebuggee(g3w), true);
|
||||
assertEq(dbg.hasDebuggee(g4w), true);
|
||||
// The debugger's global is not a debuggee.
|
||||
assertEq(dbg.hasDebuggee(thisw), false);
|
|
@ -883,6 +883,15 @@ JSCompartment::updateForDebugMode(FreeOp *fop, AutoDebugModeGC &dmgc)
|
|||
|
||||
bool
|
||||
JSCompartment::addDebuggee(JSContext *cx, js::GlobalObject *global)
|
||||
{
|
||||
AutoDebugModeGC dmgc(cx->runtime);
|
||||
return addDebuggee(cx, global, dmgc);
|
||||
}
|
||||
|
||||
bool
|
||||
JSCompartment::addDebuggee(JSContext *cx,
|
||||
js::GlobalObject *global,
|
||||
AutoDebugModeGC &dmgc)
|
||||
{
|
||||
bool wasEnabled = debugMode();
|
||||
if (!debuggees.put(global)) {
|
||||
|
@ -891,7 +900,6 @@ JSCompartment::addDebuggee(JSContext *cx, js::GlobalObject *global)
|
|||
}
|
||||
debugModeBits |= DebugFromJS;
|
||||
if (!wasEnabled) {
|
||||
AutoDebugModeGC dmgc(cx->runtime);
|
||||
updateForDebugMode(cx->runtime->defaultFreeOp(), dmgc);
|
||||
}
|
||||
return true;
|
||||
|
@ -901,6 +909,16 @@ void
|
|||
JSCompartment::removeDebuggee(FreeOp *fop,
|
||||
js::GlobalObject *global,
|
||||
js::GlobalObjectSet::Enum *debuggeesEnum)
|
||||
{
|
||||
AutoDebugModeGC dmgc(rt);
|
||||
return removeDebuggee(fop, global, dmgc, debuggeesEnum);
|
||||
}
|
||||
|
||||
void
|
||||
JSCompartment::removeDebuggee(FreeOp *fop,
|
||||
js::GlobalObject *global,
|
||||
AutoDebugModeGC &dmgc,
|
||||
js::GlobalObjectSet::Enum *debuggeesEnum)
|
||||
{
|
||||
bool wasEnabled = debugMode();
|
||||
JS_ASSERT(debuggees.has(global));
|
||||
|
@ -912,7 +930,6 @@ JSCompartment::removeDebuggee(FreeOp *fop,
|
|||
if (debuggees.empty()) {
|
||||
debugModeBits &= ~DebugFromJS;
|
||||
if (wasEnabled && !debugMode()) {
|
||||
AutoDebugModeGC dmgc(rt);
|
||||
DebugScopes::onCompartmentLeaveDebugMode(this);
|
||||
updateForDebugMode(fop, dmgc);
|
||||
}
|
||||
|
|
|
@ -500,8 +500,13 @@ struct JSCompartment : private JS::shadow::Compartment, public js::gc::GraphNode
|
|||
public:
|
||||
js::GlobalObjectSet &getDebuggees() { return debuggees; }
|
||||
bool addDebuggee(JSContext *cx, js::GlobalObject *global);
|
||||
bool addDebuggee(JSContext *cx, js::GlobalObject *global,
|
||||
js::AutoDebugModeGC &dmgc);
|
||||
void removeDebuggee(js::FreeOp *fop, js::GlobalObject *global,
|
||||
js::GlobalObjectSet::Enum *debuggeesEnum = NULL);
|
||||
void removeDebuggee(js::FreeOp *fop, js::GlobalObject *global,
|
||||
js::AutoDebugModeGC &dmgc,
|
||||
js::GlobalObjectSet::Enum *debuggeesEnum = NULL);
|
||||
bool setDebugModeFromC(JSContext *cx, bool b, js::AutoDebugModeGC &dmgc);
|
||||
|
||||
void clearBreakpointsIn(js::FreeOp *fop, js::Debugger *dbg, JSObject *handler);
|
||||
|
|
|
@ -1881,6 +1881,26 @@ Debugger::addDebuggee(JSContext *cx, unsigned argc, Value *vp)
|
|||
return true;
|
||||
}
|
||||
|
||||
JSBool
|
||||
Debugger::addAllGlobalsAsDebuggees(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
THIS_DEBUGGER(cx, argc, vp, "addAllGlobalsAsDebuggees", args, dbg);
|
||||
AutoDebugModeGC dmgc(cx->runtime);
|
||||
for (CompartmentsIter c(cx->runtime); !c.done(); c.next()) {
|
||||
if (c == dbg->object->compartment())
|
||||
continue;
|
||||
c->scheduledForDestruction = false;
|
||||
GlobalObject *global = c->maybeGlobal();
|
||||
if (global) {
|
||||
Rooted<GlobalObject*> rg(cx, global);
|
||||
dbg->addDebuggeeGlobal(cx, rg, dmgc);
|
||||
}
|
||||
}
|
||||
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
||||
JSBool
|
||||
Debugger::removeDebuggee(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
|
@ -1899,8 +1919,9 @@ JSBool
|
|||
Debugger::removeAllDebuggees(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
THIS_DEBUGGER(cx, argc, vp, "removeAllDebuggees", args, dbg);
|
||||
AutoDebugModeGC dmgc(cx->runtime);
|
||||
for (GlobalObjectSet::Enum e(dbg->debuggees); !e.empty(); e.popFront())
|
||||
dbg->removeDebuggeeGlobal(cx->runtime->defaultFreeOp(), e.front(), NULL, &e);
|
||||
dbg->removeDebuggeeGlobal(cx->runtime->defaultFreeOp(), e.front(), dmgc, NULL, &e);
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
@ -2026,6 +2047,15 @@ Debugger::construct(JSContext *cx, unsigned argc, Value *vp)
|
|||
|
||||
bool
|
||||
Debugger::addDebuggeeGlobal(JSContext *cx, Handle<GlobalObject*> global)
|
||||
{
|
||||
AutoDebugModeGC dmgc(cx->runtime);
|
||||
return addDebuggeeGlobal(cx, global, dmgc);
|
||||
}
|
||||
|
||||
bool
|
||||
Debugger::addDebuggeeGlobal(JSContext *cx,
|
||||
Handle<GlobalObject*> global,
|
||||
AutoDebugModeGC &dmgc)
|
||||
{
|
||||
if (debuggees.has(global))
|
||||
return true;
|
||||
|
@ -2082,7 +2112,7 @@ Debugger::addDebuggeeGlobal(JSContext *cx, Handle<GlobalObject*> global)
|
|||
} else {
|
||||
if (global->getDebuggers()->length() > 1)
|
||||
return true;
|
||||
if (debuggeeCompartment->addDebuggee(cx, global))
|
||||
if (debuggeeCompartment->addDebuggee(cx, global, dmgc))
|
||||
return true;
|
||||
|
||||
/* Maintain consistency on error. */
|
||||
|
@ -2098,6 +2128,16 @@ void
|
|||
Debugger::removeDebuggeeGlobal(FreeOp *fop, GlobalObject *global,
|
||||
GlobalObjectSet::Enum *compartmentEnum,
|
||||
GlobalObjectSet::Enum *debugEnum)
|
||||
{
|
||||
AutoDebugModeGC dmgc(global->compartment()->rt);
|
||||
return removeDebuggeeGlobal(fop, global, dmgc, compartmentEnum, debugEnum);
|
||||
}
|
||||
|
||||
void
|
||||
Debugger::removeDebuggeeGlobal(FreeOp *fop, GlobalObject *global,
|
||||
AutoDebugModeGC &dmgc,
|
||||
GlobalObjectSet::Enum *compartmentEnum,
|
||||
GlobalObjectSet::Enum *debugEnum)
|
||||
{
|
||||
/*
|
||||
* Each debuggee is in two HashSets: one for its compartment and one for
|
||||
|
@ -2151,7 +2191,7 @@ Debugger::removeDebuggeeGlobal(FreeOp *fop, GlobalObject *global,
|
|||
* global cannot be rooted on the stack without a cx.
|
||||
*/
|
||||
if (v->empty())
|
||||
global->compartment()->removeDebuggee(fop, global, compartmentEnum);
|
||||
global->compartment()->removeDebuggee(fop, global, dmgc, compartmentEnum);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2538,6 +2578,7 @@ JSPropertySpec Debugger::properties[] = {
|
|||
|
||||
JSFunctionSpec Debugger::methods[] = {
|
||||
JS_FN("addDebuggee", Debugger::addDebuggee, 1, 0),
|
||||
JS_FN("addAllGlobalsAsDebuggees", Debugger::addAllGlobalsAsDebuggees, 0, 0),
|
||||
JS_FN("removeDebuggee", Debugger::removeDebuggee, 1, 0),
|
||||
JS_FN("removeAllDebuggees", Debugger::removeAllDebuggees, 0, 0),
|
||||
JS_FN("hasDebuggee", Debugger::hasDebuggee, 1, 0),
|
||||
|
|
|
@ -225,9 +225,15 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
|
|||
class ScriptQuery;
|
||||
|
||||
bool addDebuggeeGlobal(JSContext *cx, Handle<GlobalObject*> obj);
|
||||
bool addDebuggeeGlobal(JSContext *cx, Handle<GlobalObject*> obj,
|
||||
AutoDebugModeGC &dmgc);
|
||||
void removeDebuggeeGlobal(FreeOp *fop, GlobalObject *global,
|
||||
GlobalObjectSet::Enum *compartmentEnum,
|
||||
GlobalObjectSet::Enum *debugEnum);
|
||||
void removeDebuggeeGlobal(FreeOp *fop, GlobalObject *global,
|
||||
AutoDebugModeGC &dmgc,
|
||||
GlobalObjectSet::Enum *compartmentEnum,
|
||||
GlobalObjectSet::Enum *debugEnum);
|
||||
|
||||
/*
|
||||
* Cope with an error or exception in a debugger hook.
|
||||
|
@ -300,6 +306,7 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
|
|||
static JSBool getUncaughtExceptionHook(JSContext *cx, unsigned argc, Value *vp);
|
||||
static JSBool setUncaughtExceptionHook(JSContext *cx, unsigned argc, Value *vp);
|
||||
static JSBool addDebuggee(JSContext *cx, unsigned argc, Value *vp);
|
||||
static JSBool addAllGlobalsAsDebuggees(JSContext *cx, unsigned argc, Value *vp);
|
||||
static JSBool removeDebuggee(JSContext *cx, unsigned argc, Value *vp);
|
||||
static JSBool removeAllDebuggees(JSContext *cx, unsigned argc, Value *vp);
|
||||
static JSBool hasDebuggee(JSContext *cx, unsigned argc, Value *vp);
|
||||
|
|
|
@ -3149,7 +3149,7 @@ nsCSSFrameConstructor::ConstructFieldSetFrame(nsFrameConstructorState& aState,
|
|||
|
||||
newFrame->AddStateBits(NS_FRAME_MAY_HAVE_GENERATED_CONTENT);
|
||||
|
||||
// our new frame returned is the top frame which is the list frame.
|
||||
// Our new frame returned is the outer frame, which is the fieldset frame.
|
||||
*aNewFrame = newFrame;
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -42,6 +42,7 @@ parent:
|
|||
async NotifyCompositorTransaction();
|
||||
|
||||
async CancelDefaultPanZoom();
|
||||
async DetectScrollableSubframe();
|
||||
|
||||
async __delete__();
|
||||
|
||||
|
|
|
@ -38,6 +38,12 @@ RenderFrameChild::CancelDefaultPanZoom()
|
|||
SendCancelDefaultPanZoom();
|
||||
}
|
||||
|
||||
void
|
||||
RenderFrameChild::DetectScrollableSubframe()
|
||||
{
|
||||
SendDetectScrollableSubframe();
|
||||
}
|
||||
|
||||
PLayersChild*
|
||||
RenderFrameChild::AllocPLayers()
|
||||
{
|
||||
|
|
|
@ -20,6 +20,7 @@ public:
|
|||
virtual ~RenderFrameChild() {}
|
||||
|
||||
void CancelDefaultPanZoom();
|
||||
void DetectScrollableSubframe();
|
||||
|
||||
void Destroy();
|
||||
|
||||
|
|
|
@ -829,6 +829,15 @@ RenderFrameParent::RecvCancelDefaultPanZoom()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
RenderFrameParent::RecvDetectScrollableSubframe()
|
||||
{
|
||||
if (mPanZoomController) {
|
||||
mPanZoomController->DetectScrollableSubframe();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
PLayersParent*
|
||||
RenderFrameParent::AllocPLayers()
|
||||
{
|
||||
|
|
|
@ -109,6 +109,7 @@ protected:
|
|||
virtual bool RecvNotifyCompositorTransaction() MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvCancelDefaultPanZoom() MOZ_OVERRIDE;
|
||||
virtual bool RecvDetectScrollableSubframe() MOZ_OVERRIDE;
|
||||
|
||||
virtual PLayersParent* AllocPLayers() MOZ_OVERRIDE;
|
||||
virtual bool DeallocPLayers(PLayersParent* aLayers) MOZ_OVERRIDE;
|
||||
|
|
|
@ -7142,7 +7142,12 @@ nsRuleNode::ComputeColumnData(void* aStartStruct,
|
|||
canStoreInRuleTree = false;
|
||||
column->mColumnRuleColorIsForeground = false;
|
||||
if (parent->mColumnRuleColorIsForeground) {
|
||||
column->mColumnRuleColor = parentContext->GetStyleColor()->mColor;
|
||||
if (parentContext) {
|
||||
column->mColumnRuleColor = parentContext->GetStyleColor()->mColor;
|
||||
} else {
|
||||
nsStyleColor defaultColumnRuleColor(mPresContext);
|
||||
column->mColumnRuleColor = defaultColumnRuleColor.mColor;
|
||||
}
|
||||
} else {
|
||||
column->mColumnRuleColor = parent->mColumnRuleColor;
|
||||
}
|
||||
|
|
|
@ -3938,3 +3938,8 @@ pref("dom.placeholder.show_on_focus", true);
|
|||
pref("wap.UAProf.url", "");
|
||||
pref("wap.UAProf.tagname", "x-wap-profile");
|
||||
|
||||
// If the user puts a finger down on an element and we think the user
|
||||
// might be executing a pan gesture, how long do we wait before
|
||||
// tentatively deciding the gesture is actually a tap and activating
|
||||
// the target element?
|
||||
pref("ui.touch_activation.delay_ms", 50);
|
||||
|
|
|
@ -2266,10 +2266,8 @@ update(ChromeDebuggerActor.prototype, {
|
|||
*/
|
||||
globalManager: {
|
||||
findGlobals: function CDA_findGlobals() {
|
||||
// Fetch the list of globals from the debugger.
|
||||
for (let g of this.dbg.findAllGlobals()) {
|
||||
this.addDebuggee(g);
|
||||
}
|
||||
// Add every global known to the debugger as debuggee.
|
||||
this.dbg.addAllGlobalsAsDebuggees();
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -151,6 +151,21 @@
|
|||
onget="return this.getAttribute('autocompletesearchparam') || '';"
|
||||
onset="this.setAttribute('autocompletesearchparam', val); return val;"/>
|
||||
|
||||
<property name="searchCount" readonly="true"
|
||||
onget="return this.sessionCount;"/>
|
||||
|
||||
<method name="getSearchAt">
|
||||
<parameter name="aIndex"/>
|
||||
<body><![CDATA[
|
||||
var idx = -1;
|
||||
for (var name in this.mSessions)
|
||||
if (++idx == aIndex)
|
||||
return name;
|
||||
|
||||
return null;
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<property name="textValue"
|
||||
onget="return this.value;"
|
||||
onset="this.setTextValue(val); return val;"/>
|
||||
|
@ -556,12 +571,11 @@
|
|||
<method name="getSession">
|
||||
<parameter name="aIndex"/>
|
||||
<body><![CDATA[
|
||||
var idx = 0;
|
||||
for (var name in this.mSessions) {
|
||||
if (idx == aIndex)
|
||||
var idx = -1;
|
||||
for (var name in this.mSessions)
|
||||
if (++idx == aIndex)
|
||||
return this.mSessions[name];
|
||||
++idx;
|
||||
}
|
||||
|
||||
return null;
|
||||
]]></body>
|
||||
</method>
|
||||
|
@ -580,7 +594,7 @@
|
|||
<parameter name="aName"/>
|
||||
<body><![CDATA[
|
||||
++this.sessionCount;
|
||||
var name = aName || "anon_"+this.sessionCount;
|
||||
var name = aName || ("anon_" + this.sessionCount);
|
||||
this.mSessions[name] = aSession;
|
||||
this.mListeners[name] = new (this.mAutoCompleteListener)(name);
|
||||
this.mLastResults[name] = null;
|
||||
|
|
Загрузка…
Ссылка в новой задаче