mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-07 18:04:46 +00:00
Merge autoland to mozilla-central. a=merge
This commit is contained in:
commit
79c4589718
@ -1,11 +1,11 @@
|
||||
An explanation of the Mozilla Source Code Directory Structure and links to
|
||||
project pages with documentation can be found at:
|
||||
|
||||
https://firefox-source-docs.mozilla.org/tools/docs/contribute/mozilla_source_code_directory_structure.html
|
||||
https://firefox-source-docs.mozilla.org/contributing/directory_structure.html
|
||||
|
||||
For information on how to build Mozilla from the source code and create the patch see:
|
||||
|
||||
https://firefox-source-docs.mozilla.org/tools/docs/contribute/how_to_contribute_firefox.html
|
||||
https://firefox-source-docs.mozilla.org/contributing/how_to_contribute_firefox.html
|
||||
|
||||
If you have a question about developing Mozilla, and can't find the solution
|
||||
on https://developer.mozilla.org, you can try asking your question on IRC at irc.mozilla.org in #introduction channel.
|
||||
|
@ -288,24 +288,25 @@ function prompt(
|
||||
// nsIContentPermissionRequest, but because webrtc uses their own prompting
|
||||
// system, we should manually apply the delegate policy here. Permission
|
||||
// should be delegated using Feature Policy and top principal
|
||||
const permDelegateHandler = aContentWindow.document.permDelegateHandler.QueryInterface(
|
||||
Ci.nsIPermissionDelegateHandler
|
||||
);
|
||||
|
||||
const shouldDelegatePermission =
|
||||
Services.prefs.getBoolPref("permissions.delegation.enabled", false) &&
|
||||
Services.prefs.getBoolPref("dom.security.featurePolicy.enabled", false);
|
||||
permDelegateHandler.permissionDelegateFPEnabled;
|
||||
|
||||
const origin = shouldDelegatePermission
|
||||
? aContentWindow.top.document.nodePrincipal.origin
|
||||
: aContentWindow.document.nodePrincipal.origin;
|
||||
|
||||
let secondOrigin = undefined;
|
||||
if (shouldDelegatePermission) {
|
||||
const permDelegateHandler = aContentWindow.document.permDelegateHandler.QueryInterface(
|
||||
Ci.nsIPermissionDelegateHandler
|
||||
);
|
||||
if (permDelegateHandler.maybeUnsafePermissionDelegate(requestTypes)) {
|
||||
// We are going to prompt both first party and third party origin.
|
||||
// SecondOrigin should be third party
|
||||
secondOrigin = aContentWindow.document.nodePrincipal.origin;
|
||||
}
|
||||
if (
|
||||
shouldDelegatePermission &&
|
||||
permDelegateHandler.maybeUnsafePermissionDelegate(requestTypes)
|
||||
) {
|
||||
// We are going to prompt both first party and third party origin.
|
||||
// SecondOrigin should be third party
|
||||
secondOrigin = aContentWindow.document.nodePrincipal.origin;
|
||||
}
|
||||
|
||||
let request = {
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1576881756956">
|
||||
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1578084466436">
|
||||
<emItems>
|
||||
<emItem blockID="i334" id="{0F827075-B026-42F3-885D-98981EE7B1AE}">
|
||||
<prefs/>
|
||||
@ -3440,6 +3440,14 @@
|
||||
<prefs/>
|
||||
<versionRange minVersion="0" maxVersion="*" severity="3"/>
|
||||
</emItem>
|
||||
<emItem blockID="3d3f2971-9764-4b6d-94ef-2a0b97da7619" id="/^((\{a91c41b7-4196-4867-84b4-d417a1b10da2\})|(\{e3d3ea5c-c8c0-4c9e-89c6-f6b5677186cc\})|(\{fa3b6777-4f64-476c-9ace-a79709ccd0a6\})|(\{6251b844-0c54-44bc-8c5e-891e3ba86c2e\})|(\{8e588566-afb2-4612-a420-3e3bd18693e7\})|(\{a0bf35ec-76cc-4d86-875b-09d46e8790c2\})|(\{fd257beb-d772-4333-9901-dc5913aee499\})|(\{a9acb248-93fb-4081-9d88-92468f229842\})|(\{7e1b62bc-3ab4-4c4d-8182-b095a492eab4\}))$/">
|
||||
<prefs/>
|
||||
<versionRange minVersion="0" maxVersion="*" severity="3"/>
|
||||
</emItem>
|
||||
<emItem blockID="de533f3a-d0e3-4704-916e-fd2a297cee93" id="/^((\{943773bb-c8a8-4576-bf3a-7cacca534887\})|(\{0afab6d1-c267-4ff6-9289-4a2b2ad78f33\})|(\{4278c56e-7b67-43ab-8c87-f68a6a883df6\})|(\{f146cde8-6dcf-4ebf-9d67-b7eccc9bc8a6\})|(\{d0e43d96-0e73-48d7-9a60-b235022f4330\})|(\{a94ed9b8-24a6-4719-97af-08eaac91a42b\})|(\{d62ca114-0f4e-4d25-813e-292d0c682e05\})|(\{908b1c05-3766-45e1-b56b-f0b4457c6451\})|(\{068054b5-46c0-47c2-be37-dd015fb1c050\})|(\{1c1cde54-c8e9-4c61-a2be-30411888ac8a\})|(\{b06648df-3c80-49e8-9d9e-71741ba28c72\})|(\{a085da90-cc10-4c26-954e-ae4eb773c6d7\})|(\{1d53aa0d-eca3-4bb1-947c-aebfdd0770fd\})|(\{83ebd575-b66b-4b02-a628-d2764194d0a6\})|(\{fd5f7e74-2e60-454b-b702-05e9d66b334b\})|(\{fdd2f5a3-9061-4fc8-87d2-cf7f7668d336\})|(\{f890d432-ce0b-4857-b030-dc36fc791423\})|(\{d5b4e84c-7991-4be5-9c26-c3e92ba0901a\})|(\{8d54459a-34cb-461f-b1fe-2266484cc098\})|(\{67b21df3-a1da-48ee-aee8-18ae8ad7fe21\})|(\{18feff20-5892-43cd-8606-83e8e7c33ebd\})|(\{554e901f-5476-4fad-8714-a08b8249068b\})|(\{248c9c9f-404d-4284-bd12-2fa988edb0ad\})|(\{9c347568-2528-4dea-8a0d-6e9fa7f88512\})|(\{0447e445-abb9-450b-b12c-de16fa40e176\})|(\{3015019d-1c2f-4310-adf1-1b33c4566d9e\})|(\{a3aca1ed-74b4-46d4-9c73-ca9ba8c91ac6\})|(\{7b2aabfa-673f-4afb-9cba-7a9329a24d79\}))$/">
|
||||
<prefs/>
|
||||
<versionRange minVersion="0" maxVersion="*" severity="3"/>
|
||||
</emItem>
|
||||
</emItems>
|
||||
<pluginItems>
|
||||
<pluginItem blockID="p332">
|
||||
@ -3472,15 +3480,15 @@
|
||||
<infoURL>https://get.adobe.com/shockwave/</infoURL>
|
||||
<versionRange maxVersion="12.2.0.162" minVersion="0" severity="0" vulnerabilitystatus="1"/>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="832dc9ff-3314-4df2-abcf-7bd65a645371">
|
||||
<match name="filename" exp="(NPSWF32.*\.dll)|(NPSWF64.*\.dll)|(Flash\ Player\.plugin)"/>
|
||||
<infoURL>https://get.adobe.com/flashplayer/</infoURL>
|
||||
<versionRange maxVersion="32.0.0.270" minVersion="0" severity="0" vulnerabilitystatus="1"/>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="49b843cc-a8fc-4ede-be0c-a0da56d0214f" os="Linux">
|
||||
<match name="filename" exp="libflashplayer\.so"/>
|
||||
<infoURL>https://get.adobe.com/flashplayer/</infoURL>
|
||||
<versionRange maxVersion="32.0.0.270" minVersion="0" severity="0" vulnerabilitystatus="1"/>
|
||||
<versionRange maxVersion="32.0.0.293" minVersion="0" severity="0" vulnerabilitystatus="1"/>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="832dc9ff-3314-4df2-abcf-7bd65a645371">
|
||||
<match name="filename" exp="(NPSWF32.*\.dll)|(NPSWF64.*\.dll)|(Flash\ Player\.plugin)"/>
|
||||
<infoURL>https://get.adobe.com/flashplayer/</infoURL>
|
||||
<versionRange maxVersion="32.0.0.293" minVersion="0" severity="0" vulnerabilitystatus="1"/>
|
||||
</pluginItem>
|
||||
</pluginItems>
|
||||
<gfxItems>
|
||||
|
@ -406,7 +406,6 @@ pref("permissions.default.xr", 0);
|
||||
pref("permissions.default.desktop-notification", 0);
|
||||
pref("permissions.default.shortcuts", 0);
|
||||
|
||||
pref("permissions.delegation.enabled", true);
|
||||
pref("permissions.desktop-notification.postPrompt.enabled", true);
|
||||
pref("permissions.desktop-notification.notNow.enabled", false);
|
||||
|
||||
@ -1707,8 +1706,6 @@ pref("view_source.tab", true);
|
||||
|
||||
pref("dom.serviceWorkers.enabled", true);
|
||||
|
||||
pref("dom.security.featurePolicy.enabled", true);
|
||||
|
||||
// Enable Push API.
|
||||
pref("dom.push.enabled", true);
|
||||
|
||||
|
@ -539,6 +539,7 @@ class _ASRouter {
|
||||
this.onPrefChange = this.onPrefChange.bind(this);
|
||||
this.dispatch = this.dispatch.bind(this);
|
||||
this._onLocaleChanged = this._onLocaleChanged.bind(this);
|
||||
this.isUnblockedMessage = this.isUnblockedMessage.bind(this);
|
||||
}
|
||||
|
||||
async onPrefChange(prefName) {
|
||||
@ -547,7 +548,7 @@ class _ASRouter {
|
||||
const invalidMessages = [];
|
||||
const context = this._getMessagesContext();
|
||||
|
||||
for (const msg of this._getUnblockedMessages()) {
|
||||
for (const msg of this.state.messages.filter(this.isUnblockedMessage)) {
|
||||
if (!msg.targeting) {
|
||||
continue;
|
||||
}
|
||||
@ -1129,6 +1130,18 @@ class _ASRouter {
|
||||
return bundle.sort((a, b) => a.order - b.order);
|
||||
}
|
||||
|
||||
isUnblockedMessage(message) {
|
||||
let { state } = this;
|
||||
return (
|
||||
!state.messageBlockList.includes(message.id) &&
|
||||
(!message.campaign ||
|
||||
!state.messageBlockList.includes(message.campaign)) &&
|
||||
!state.providerBlockList.includes(message.provider) &&
|
||||
this.hasGroupsEnabled(message.groups) &&
|
||||
!this.isExcludedByProvider(message)
|
||||
);
|
||||
}
|
||||
|
||||
// Work out if a message can be shown based on its and its provider's frequency caps.
|
||||
isBelowFrequencyCaps(message) {
|
||||
const { messageImpressions, groupImpressions } = this.state;
|
||||
@ -1197,9 +1210,12 @@ class _ASRouter {
|
||||
}
|
||||
|
||||
// First, find all messages of same template. These are potential matching targeting candidates
|
||||
let bundledMessagesOfSameTemplate = this._getUnblockedMessages().filter(
|
||||
let bundledMessagesOfSameTemplate = this.state.messages.filter(
|
||||
msg =>
|
||||
msg.bundled && msg.template === bundleTemplate && msg.id !== originalId
|
||||
msg.bundled &&
|
||||
msg.template === bundleTemplate &&
|
||||
msg.id !== originalId &&
|
||||
this.isUnblockedMessage(msg)
|
||||
);
|
||||
|
||||
if (force) {
|
||||
@ -1279,18 +1295,6 @@ class _ASRouter {
|
||||
];
|
||||
}
|
||||
|
||||
_getUnblockedMessages() {
|
||||
let { state } = this;
|
||||
return state.messages.filter(
|
||||
item =>
|
||||
!state.messageBlockList.includes(item.id) &&
|
||||
(!item.campaign || !state.messageBlockList.includes(item.campaign)) &&
|
||||
!state.providerBlockList.includes(item.provider) &&
|
||||
this.hasGroupsEnabled(item.groups) &&
|
||||
!this.isExcludedByProvider(item)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Route messages based on template to the correct module that can display them
|
||||
*/
|
||||
@ -1520,30 +1524,40 @@ class _ASRouter {
|
||||
ordered = false,
|
||||
returnAll = false,
|
||||
}) {
|
||||
let shouldCache;
|
||||
const messages =
|
||||
candidates ||
|
||||
this._getUnblockedMessages()
|
||||
.filter(m => {
|
||||
if (provider && m.provider !== provider) {
|
||||
return false;
|
||||
}
|
||||
if (template && m.template !== template) {
|
||||
return false;
|
||||
}
|
||||
if (triggerId && !m.trigger) {
|
||||
return false;
|
||||
}
|
||||
if (triggerId && m.trigger.id !== triggerId) {
|
||||
return false;
|
||||
}
|
||||
this.state.messages.filter(m => {
|
||||
if (provider && m.provider !== provider) {
|
||||
return false;
|
||||
}
|
||||
if (template && m.template !== template) {
|
||||
return false;
|
||||
}
|
||||
if (triggerId && !m.trigger) {
|
||||
return false;
|
||||
}
|
||||
if (triggerId && m.trigger.id !== triggerId) {
|
||||
return false;
|
||||
}
|
||||
if (!this.isUnblockedMessage(m)) {
|
||||
return false;
|
||||
}
|
||||
if (!this.isBelowFrequencyCaps(m)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
})
|
||||
.filter(m => this.isBelowFrequencyCaps(m));
|
||||
if (shouldCache !== false) {
|
||||
shouldCache = JEXL_PROVIDER_CACHE.has(m.provider);
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
if (!messages.length) {
|
||||
return returnAll ? messages : null;
|
||||
}
|
||||
|
||||
const shouldCache = messages.every(m =>
|
||||
JEXL_PROVIDER_CACHE.has(m.provider)
|
||||
);
|
||||
const context = this._getMessagesContext();
|
||||
|
||||
// Find a message that matches the targeting context as well as the trigger context (if one is provided)
|
||||
|
@ -1096,7 +1096,7 @@ describe("ASRouter", () => {
|
||||
const result = await Router.handleMessageRequest({
|
||||
provider: "snippets",
|
||||
});
|
||||
assert.isUndefined(result);
|
||||
assert.isNull(result);
|
||||
});
|
||||
it("should not return a message from a blocked campaign", async () => {
|
||||
// Block all messages except the first
|
||||
@ -1153,7 +1153,16 @@ describe("ASRouter", () => {
|
||||
const result = await Router.handleMessageRequest({
|
||||
provider: "snippets",
|
||||
});
|
||||
|
||||
assert.isNull(result);
|
||||
});
|
||||
it("should not return a message if the frequency cap has been hit", async () => {
|
||||
sandbox.stub(Router, "isBelowFrequencyCaps").returns(false);
|
||||
await Router.setState(() => ({
|
||||
messages: [{ id: "foo", provider: "snippets" }],
|
||||
}));
|
||||
const result = await Router.handleMessageRequest({
|
||||
provider: "snippets",
|
||||
});
|
||||
assert.isNull(result);
|
||||
});
|
||||
it("should get unblocked messages that match the trigger", async () => {
|
||||
@ -1220,18 +1229,21 @@ describe("ASRouter", () => {
|
||||
});
|
||||
it("should return all unblocked messages that match the template, trigger if returnAll=true", async () => {
|
||||
const message1 = {
|
||||
provider: "whats_new",
|
||||
id: "1",
|
||||
template: "whatsnew_panel_message",
|
||||
trigger: { id: "whatsNewPanelOpened" },
|
||||
groups: ["whats_new"],
|
||||
};
|
||||
const message2 = {
|
||||
provider: "whats_new",
|
||||
id: "2",
|
||||
template: "whatsnew_panel_message",
|
||||
trigger: { id: "whatsNewPanelOpened" },
|
||||
groups: ["whats_new"],
|
||||
};
|
||||
const message3 = {
|
||||
provider: "whats_new",
|
||||
id: "3",
|
||||
template: "badge",
|
||||
groups: ["whats_new"],
|
||||
@ -1239,9 +1251,12 @@ describe("ASRouter", () => {
|
||||
sandbox
|
||||
.stub(ASRouterTargeting, "findMatchingMessage")
|
||||
.callsFake(() => [message2, message1]);
|
||||
await Router.setState({ messages: [message3, message2, message1] });
|
||||
await Router.setState({
|
||||
messages: [message3, message2, message1],
|
||||
providers: [{ id: "whats_new" }],
|
||||
});
|
||||
const result = await Router.handleMessageRequest({
|
||||
template: "whatsnew-panel",
|
||||
template: "whatsnew_panel_message",
|
||||
triggerId: "whatsNewPanelOpened",
|
||||
returnAll: true,
|
||||
});
|
||||
@ -1794,7 +1809,7 @@ describe("ASRouter", () => {
|
||||
await Router.onMessage(msg);
|
||||
|
||||
assert.isTrue(Router.state.messageBlockList.includes("foocampaign"));
|
||||
assert.isEmpty(Router._getUnblockedMessages());
|
||||
assert.isEmpty(Router.state.messages.filter(Router.isUnblockedMessage));
|
||||
});
|
||||
it("should not broadcast CLEAR_MESSAGE if preventDismiss is true", async () => {
|
||||
const msg = fakeAsyncMessage({
|
||||
@ -2094,6 +2109,20 @@ describe("ASRouter", () => {
|
||||
|
||||
describe("#onMessage: TRIGGER", () => {
|
||||
it("should pass the trigger to ASRouterTargeting on TRIGGER message", async () => {
|
||||
await Router.setState({
|
||||
messages: [
|
||||
{
|
||||
id: "foo1",
|
||||
provider: "onboarding",
|
||||
template: "onboarding",
|
||||
trigger: { id: "firstRun" },
|
||||
content: { title: "Foo1", body: "Foo123-1" },
|
||||
groups: ["onboarding"],
|
||||
},
|
||||
],
|
||||
providers: [{ id: "onboarding" }],
|
||||
});
|
||||
sandbox.stub(Router, "loadMessagesFromAllProviders").resolves();
|
||||
sandbox.stub(ASRouterTargeting, "findMatchingMessage").resolves();
|
||||
const msg = fakeAsyncMessage({
|
||||
type: "TRIGGER",
|
||||
|
@ -237,11 +237,6 @@ const kBuiltInInputs = {
|
||||
},
|
||||
};
|
||||
|
||||
// We create a new flat object to cache strings. Since gBuiltInInputs is a
|
||||
// tree, caching/retrieval of localized strings would otherwise require tree
|
||||
// traversal.
|
||||
var localizedStrings = {};
|
||||
|
||||
const kHelperObservers = new Set([
|
||||
"bookmark-icon-updated",
|
||||
"reader-mode-available",
|
||||
@ -308,6 +303,8 @@ class TouchBarHelper {
|
||||
// icons) are loaded. We keep track of which inputs haven't updated and
|
||||
// run an update on them after the first location change.
|
||||
this._inputsNotUpdated = new Set(Object.keys(kBuiltInInputs));
|
||||
// This is a temporary workaround until bug 1596723 is resolved.
|
||||
this._inputsNotUpdated.delete("SearchPopover");
|
||||
|
||||
return layoutItems;
|
||||
}
|
||||
@ -354,8 +351,8 @@ class TouchBarHelper {
|
||||
// Skip localization if there is already a cached localized title or if
|
||||
// no title is needed.
|
||||
if (
|
||||
!inputData.hasOwnProperty("title") ||
|
||||
localizedStrings[inputData.title]
|
||||
kBuiltInInputs[inputName].hasOwnProperty("localTitle") ||
|
||||
!kBuiltInInputs[inputName].hasOwnProperty("title")
|
||||
) {
|
||||
return item;
|
||||
}
|
||||
@ -363,7 +360,7 @@ class TouchBarHelper {
|
||||
// Async l10n fills in the localized input labels after the initial load.
|
||||
this._l10n.formatValue(item.key).then(result => {
|
||||
item.title = result;
|
||||
localizedStrings[inputData.title] = result; // Cache result.
|
||||
kBuiltInInputs[inputName].localTitle = result; // Cache result.
|
||||
// Checking TouchBarHelper.window since this callback can fire after all windows are closed.
|
||||
if (TouchBarHelper.window) {
|
||||
if (this._inputsNotUpdated) {
|
||||
@ -478,16 +475,12 @@ class TouchBarHelper {
|
||||
);
|
||||
break;
|
||||
case "intl:app-locales-changed":
|
||||
// On locale change, refresh all inputs after loading new localTitle.
|
||||
this._searchPopover = null;
|
||||
localizedStrings = {};
|
||||
|
||||
// This event can fire before this._l10n updates to switch languages,
|
||||
// so all the new translations are in the old language. To avoid this,
|
||||
// we need to reinitialize this._l10n.
|
||||
this._l10n = new Localization(["browser/touchbar/touchbar.ftl"]);
|
||||
helperProto._l10n = this._l10n;
|
||||
|
||||
this._updateTouchBarInputs(...Object.keys(kBuiltInInputs));
|
||||
for (let input in kBuiltInInputs) {
|
||||
delete input.localTitle;
|
||||
}
|
||||
this._updateTouchBarInputs(...kBuiltInInputs.keys());
|
||||
break;
|
||||
case "quit-application":
|
||||
this.destructor();
|
||||
@ -530,7 +523,7 @@ helperProto._l10n = new Localization(["browser/touchbar/touchbar.ftl"]);
|
||||
class TouchBarInput {
|
||||
constructor(input) {
|
||||
this._key = input.key || input.title;
|
||||
this._title = localizedStrings[this._key] || "";
|
||||
this._title = input.hasOwnProperty("localTitle") ? input.localTitle : "";
|
||||
this._image = input.image;
|
||||
this._type = input.type;
|
||||
this._callback = input.callback;
|
||||
@ -551,7 +544,7 @@ class TouchBarInput {
|
||||
initializedChild.type = input.type + "-" + initializedChild.type;
|
||||
this._children.push(initializedChild);
|
||||
// Skip l10n for inputs without a title or those already localized.
|
||||
if (childData.title && !localizedStrings[childData.title]) {
|
||||
if (childData.title && childData.title != "") {
|
||||
toLocalize.push(initializedChild);
|
||||
}
|
||||
}
|
||||
@ -613,14 +606,9 @@ class TouchBarInput {
|
||||
|
||||
/**
|
||||
* Apply Fluent l10n to child inputs.
|
||||
* @param {Array} children
|
||||
* An array of initialized TouchBarInputs.
|
||||
* @param {Array} children An array of initialized TouchBarInputs.
|
||||
*/
|
||||
async _localizeChildren(children) {
|
||||
if (!children || !children.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
let titles = await helperProto._l10n.formatValues(
|
||||
children.map(child => ({ id: child.key }))
|
||||
);
|
||||
@ -629,9 +617,7 @@ class TouchBarInput {
|
||||
// results in titles match up with the inputs to be localized.
|
||||
children.forEach(function(child, index) {
|
||||
child.title = titles[index];
|
||||
localizedStrings[child.key] = child.title;
|
||||
});
|
||||
|
||||
gTouchBarUpdater.updateTouchBarInputs(TouchBarHelper.baseWindow, children);
|
||||
}
|
||||
}
|
||||
|
@ -492,12 +492,19 @@ const tests = [
|
||||
info(
|
||||
"With pageproxystate=valid, open the panel with openViewOnFocus, select with DOWN, Enter."
|
||||
);
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["browser.urlbar.update1", true],
|
||||
["browser.urlbar.openViewOnFocus", true],
|
||||
],
|
||||
});
|
||||
await addTopSite("http://example.org/");
|
||||
gURLBar.value = "";
|
||||
let promise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
|
||||
await UrlbarTestUtils.promisePopupOpen(window, () => {
|
||||
window.document.getElementById("Browser:OpenLocation").doCommand();
|
||||
});
|
||||
await SpecialPowers.popPrefEnv();
|
||||
await UrlbarTestUtils.promiseSearchComplete(window);
|
||||
while (gURLBar.untrimmedValue != "http://example.org/") {
|
||||
EventUtils.synthesizeKey("KEY_ArrowDown");
|
||||
@ -522,13 +529,20 @@ const tests = [
|
||||
info(
|
||||
"With pageproxystate=valid, open the panel with openViewOnFocus, click on entry."
|
||||
);
|
||||
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["browser.urlbar.update1", true],
|
||||
["browser.urlbar.openViewOnFocus", true],
|
||||
],
|
||||
});
|
||||
await addTopSite("http://example.com/");
|
||||
gURLBar.value = "";
|
||||
let promise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
|
||||
await UrlbarTestUtils.promisePopupOpen(window, () => {
|
||||
window.document.getElementById("Browser:OpenLocation").doCommand();
|
||||
});
|
||||
Services.prefs.clearUserPref("browser.urlbar.openViewOnFocus");
|
||||
await SpecialPowers.popPrefEnv();
|
||||
await UrlbarTestUtils.promiseSearchComplete(window);
|
||||
while (gURLBar.untrimmedValue != "http://example.com/") {
|
||||
EventUtils.synthesizeKey("KEY_ArrowDown");
|
||||
@ -554,6 +568,12 @@ const tests = [
|
||||
info(
|
||||
"With pageproxystate=invalid, open the panel with openViewOnFocus, Enter."
|
||||
);
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["browser.urlbar.update1", true],
|
||||
["browser.urlbar.openViewOnFocus", true],
|
||||
],
|
||||
});
|
||||
await addTopSite("http://example.org/");
|
||||
gURLBar.value = "example.org";
|
||||
gURLBar.setAttribute("pageproxystate", "invalid");
|
||||
@ -561,6 +581,7 @@ const tests = [
|
||||
await UrlbarTestUtils.promisePopupOpen(window, () => {
|
||||
window.document.getElementById("Browser:OpenLocation").doCommand();
|
||||
});
|
||||
await SpecialPowers.popPrefEnv();
|
||||
await UrlbarTestUtils.promiseSearchComplete(window);
|
||||
EventUtils.synthesizeKey("VK_RETURN");
|
||||
await promise;
|
||||
@ -582,6 +603,12 @@ const tests = [
|
||||
info(
|
||||
"With pageproxystate=invalid, open the panel with openViewOnFocus, click on entry."
|
||||
);
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["browser.urlbar.update1", true],
|
||||
["browser.urlbar.openViewOnFocus", true],
|
||||
],
|
||||
});
|
||||
// This value must be different from the previous test, or else the
|
||||
// Megabar's "retained results" feature will interfere with openViewOnFocus.
|
||||
// This issue will be addressed in bug 1601052.
|
||||
@ -591,6 +618,7 @@ const tests = [
|
||||
await UrlbarTestUtils.promisePopupOpen(window, () => {
|
||||
window.document.getElementById("Browser:OpenLocation").doCommand();
|
||||
});
|
||||
await SpecialPowers.popPrefEnv();
|
||||
await UrlbarTestUtils.promiseSearchComplete(window);
|
||||
let element = UrlbarTestUtils.getSelectedRow(window);
|
||||
EventUtils.synthesizeMouseAtCenter(element, {});
|
||||
|
@ -15,6 +15,7 @@ const EN_US_TOPSITES =
|
||||
add_task(async function init() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["browser.urlbar.update1", true],
|
||||
["browser.urlbar.openViewOnFocus", true],
|
||||
["browser.newtabpage.activity-stream.default.sites", EN_US_TOPSITES],
|
||||
],
|
||||
|
@ -945,11 +945,6 @@ Function CheckExistingInstall
|
||||
FunctionEnd
|
||||
|
||||
Function LaunchApp
|
||||
!ifndef DEV_EDITION
|
||||
${ManualCloseAppPrompt} "${MainWindowClass}" "$(WARN_MANUALLY_CLOSE_APP_LAUNCH)"
|
||||
${ManualCloseAppPrompt} "${DialogWindowClass}" "$(WARN_MANUALLY_CLOSE_APP_LAUNCH)"
|
||||
!endif
|
||||
|
||||
ClearErrors
|
||||
${GetParameters} $0
|
||||
${GetOptions} "$0" "/UAC:" $1
|
||||
|
@ -1766,22 +1766,6 @@ Function CanWrite
|
||||
FunctionEnd
|
||||
|
||||
Function LaunchApp
|
||||
!ifndef DEV_EDITION
|
||||
FindWindow $0 "${MainWindowClass}"
|
||||
FindWindow $1 "${DialogWindowClass}"
|
||||
${If} $0 <> 0 ; integer comparison
|
||||
${OrIf} $1 <> 0
|
||||
StrCpy $FirefoxLaunchCode "1"
|
||||
|
||||
StrCpy $ProgressCompleted ${PROGRESS_BAR_TOTAL_STEPS}
|
||||
Call SetProgressBars
|
||||
|
||||
MessageBox MB_OK|MB_ICONQUESTION "$(WARN_MANUALLY_CLOSE_APP_LAUNCH)"
|
||||
Call SendPing
|
||||
Return
|
||||
${EndIf}
|
||||
!endif
|
||||
|
||||
StrCpy $FirefoxLaunchCode "2"
|
||||
|
||||
; Set the current working directory to the installation directory
|
||||
|
@ -45,7 +45,6 @@ ICONS_STARTMENU=In my &Start Menu Programs folder
|
||||
ICONS_QUICKLAUNCH=In my &Quick Launch bar
|
||||
WARN_MANUALLY_CLOSE_APP_INSTALL=$BrandShortName must be closed to proceed with the installation.\n\nPlease close $BrandShortName to continue.
|
||||
WARN_MANUALLY_CLOSE_APP_UNINSTALL=$BrandShortName must be closed to proceed with the uninstall.\n\nPlease close $BrandShortName to continue.
|
||||
WARN_MANUALLY_CLOSE_APP_LAUNCH=$BrandShortName is already running.\n\nPlease close $BrandShortName prior to launching the version you have just installed.
|
||||
WARN_WRITE_ACCESS=You don't have access to write to the installation directory.\n\nClick OK to select a different directory.
|
||||
WARN_DISK_SPACE=You don't have sufficient disk space to install to this location.\n\nClick OK to select a different location.
|
||||
WARN_MIN_SUPPORTED_OSVER_MSG=Sorry, $BrandShortName can't be installed. This version of $BrandShortName requires ${MinSupportedVer} or newer. Please click the OK button for additional information.
|
||||
|
@ -43,7 +43,6 @@ WARN_MIN_SUPPORTED_CPU_MSG=Sorry, $BrandShortName can’t be installed. This ver
|
||||
WARN_MIN_SUPPORTED_OSVER_CPU_MSG=Sorry, $BrandShortName can’t be installed. This version of $BrandShortName requires ${MinSupportedVer} or newer and a processor with ${MinSupportedCPU} support. Please click the OK button for additional information.
|
||||
WARN_WRITE_ACCESS_QUIT=You don’t have access to write to the installation directory
|
||||
WARN_DISK_SPACE_QUIT=You don’t have sufficient disk space to install.
|
||||
WARN_MANUALLY_CLOSE_APP_LAUNCH=$BrandShortName is already running.\n\nPlease close $BrandShortName prior to launching the version you have just installed.
|
||||
|
||||
ERROR_DOWNLOAD_CONT=Hmm. For some reason, we could not install $BrandShortName.\nChoose OK to start over.
|
||||
|
||||
|
@ -733,7 +733,8 @@ toolbarbutton[constrain-size="true"][cui-areatype="menu-panel"] > .toolbarbutton
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.PanelUI-fxa-service-description-label {
|
||||
.PanelUI-fxa-service-description-label,
|
||||
.PanelUI-remotetabs-instruction-label {
|
||||
/* Use 'lighter' font for this to de-emphasize it compared to the title.
|
||||
* We use 300 on Linux because 100 is too light (lacks contrast with
|
||||
* the background) for some fonts in combination with anti-aliasing. */
|
||||
@ -784,7 +785,7 @@ toolbarbutton[constrain-size="true"][cui-areatype="menu-panel"] > .toolbarbutton
|
||||
color: var(--panel-disabled-color);
|
||||
}
|
||||
|
||||
/* From the FxA menu -> remote tabs, we don't need to clutter the view with
|
||||
/* From the FxA menu -> synced tabs, we don't need to clutter the view with
|
||||
redundant buttons because these are accessible from the main menu */
|
||||
panelmultiview[mainViewId="PanelUI-fxa"] #PanelUI-remotetabs-syncnow {
|
||||
display: none;
|
||||
@ -839,21 +840,9 @@ panelmultiview[mainViewId="PanelUI-fxa"] #PanelUI-remotetabs-syncnow {
|
||||
max-width: 15em;
|
||||
}
|
||||
|
||||
.PanelUI-fxa-service-description-label {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.PanelUI-fxa-service-description-label,
|
||||
.PanelUI-remotetabs-instruction-label {
|
||||
color: var(--panel-disabled-color);
|
||||
}
|
||||
|
||||
/* The boxes with "instructions" get extra top and bottom padding for space
|
||||
around the illustration and buttons */
|
||||
.PanelUI-remotetabs-instruction-box {
|
||||
/* If you change the padding here, the min-height of the synced tabs panel
|
||||
(e.g. #PanelUI-remotetabs[mainview] #PanelUI-remotetabs-setupsync, etc) may
|
||||
need adjusting (see bug 1248506) */
|
||||
padding-bottom: 30px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.PanelUI-fxa-signin-button,
|
||||
@ -874,7 +863,8 @@ panelmultiview[mainViewId="PanelUI-fxa"] #PanelUI-remotetabs-syncnow {
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
.PanelUI-fxa-signin-button {
|
||||
.PanelUI-fxa-signin-button,
|
||||
.PanelUI-remotetabs-button {
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
@ -905,11 +895,10 @@ panelmultiview[mainViewId="PanelUI-fxa"] #PanelUI-remotetabs-syncnow {
|
||||
.fxaSyncIllustration,
|
||||
.fxaSyncIllustrationIssue {
|
||||
/* If you change the margin here, the min-height of the synced tabs panel
|
||||
(e.g. #PanelUI-remotetabs[mainview] #PanelUI-remotetabs-setupsync, etc) may
|
||||
need adjusting (see bug 1248506) */
|
||||
(e.g. #PanelUI-remotetabs[mainview] #PanelUI-remotetabs-setupsync, etc) may
|
||||
need adjusting (see bug 1248506) */
|
||||
width: 204px;
|
||||
height: var(--panel-ui-sync-illustration-height);
|
||||
margin: 38px 0 15px;
|
||||
-moz-context-properties: fill;
|
||||
fill: #cdcdcd;
|
||||
}
|
||||
@ -943,11 +932,10 @@ panelmultiview[mainViewId="PanelUI-fxa"] #PanelUI-remotetabs-syncnow {
|
||||
#PanelUI-remotetabs[mainview] #PanelUI-remotetabs-nodevicespane,
|
||||
#PanelUI-remotetabs[mainview] #PanelUI-remotetabs-tabsdisabledpane {
|
||||
min-height: calc(var(--panel-ui-sync-illustration-height) +
|
||||
53px + /* margin of .fxaSyncIllustration */
|
||||
15px + /* margin of .fxaSyncIllustration */
|
||||
30px + /* margin of .PanelUI-remotetabs-button */
|
||||
16px + /* padding of .PanelUI-remotetabs-button */
|
||||
30px + /* padding of .PanelUI-remotetabs-instruction-box */
|
||||
11em);
|
||||
8px + /* padding of .PanelUI-remotetabs-button */
|
||||
1em);
|
||||
}
|
||||
|
||||
.PanelUI-remotetabs-clientcontainer > label[itemtype="client"] {
|
||||
|
@ -71,9 +71,9 @@ MACH_MODULES = [
|
||||
'toolkit/components/telemetry/tests/marionette/mach_commands.py',
|
||||
'tools/browsertime/mach_commands.py',
|
||||
'tools/compare-locales/mach_commands.py',
|
||||
'tools/docs/mach_commands.py',
|
||||
'tools/lint/mach_commands.py',
|
||||
'tools/mach_commands.py',
|
||||
'tools/moztreedocs/mach_commands.py',
|
||||
'tools/power/mach_commands.py',
|
||||
'tools/tryselect/mach_commands.py',
|
||||
'tools/vcs/mach_commands.py',
|
||||
|
@ -2,7 +2,8 @@
|
||||
|
||||
[include]
|
||||
# Code for generating docs.
|
||||
glob:tools/docs/**
|
||||
glob:docs/**
|
||||
glob:tools/moztreedocs/**
|
||||
|
||||
# Potential docs sources
|
||||
glob:**/*.rst
|
||||
|
@ -88,7 +88,7 @@ mozilla.pth:testing/web-platform/tests/tools/six
|
||||
mozilla.pth:testing/xpcshell
|
||||
mozilla.pth:third_party/python/mock-1.0.0
|
||||
mozilla.pth:xpcom/ds/tools
|
||||
mozilla.pth:tools/docs
|
||||
mozilla.pth:tools/moztreedocs
|
||||
mozilla.pth:third_party/python/cbor2
|
||||
mozilla.pth:third_party/python/pyasn1
|
||||
mozilla.pth:third_party/python/pyasn1-modules
|
||||
|
@ -6579,7 +6579,7 @@ NS_CycleCollectorSuspectUsingNursery
|
||||
?HasFocus@Document@dom@mozilla@@QBE_NAAVErrorResult@3@@Z
|
||||
?GetFocusedWindow@nsFocusManager@@UAG?AW4nsresult@@PAPAVmozIDOMWindowProxy@@@Z
|
||||
?GetCsp@SystemPrincipal@mozilla@@UAG?AW4nsresult@@PAPAVnsIContentSecurityPolicy@@@Z
|
||||
?InnerSetNewDocument@nsGlobalWindowInner@@IAEXPAUJSContext@@PAVDocument@dom@mozilla@@@Z
|
||||
?InitDocumentDependentState@nsGlobalWindowInner@@IAEXPAUJSContext@@@Z
|
||||
?WrapObject@nsINode@@UAEPAVJSObject@@PAUJSContext@@V?$Handle@PAVJSObject@@@JS@@@Z
|
||||
?WrapNode@nsHTMLDocument@@UAEPAVJSObject@@PAUJSContext@@V?$Handle@PAVJSObject@@@JS@@@Z
|
||||
?Wrap@HTMLDocument_Binding@dom@mozilla@@YA_NPAUJSContext@@PAVnsHTMLDocument@@PAVnsWrapperCache@@V?$Handle@PAVJSObject@@@JS@@V?$MutableHandle@PAVJSObject@@@8@@Z
|
||||
|
@ -6535,7 +6535,7 @@ NS_CycleCollectorSuspectUsingNursery
|
||||
?HasFocus@Document@dom@mozilla@@QEBA_NAEAVErrorResult@3@@Z
|
||||
?GetFocusedWindow@nsFocusManager@@UEAA?AW4nsresult@@PEAPEAVmozIDOMWindowProxy@@@Z
|
||||
?GetCsp@SystemPrincipal@mozilla@@UEAA?AW4nsresult@@PEAPEAVnsIContentSecurityPolicy@@@Z
|
||||
?InnerSetNewDocument@nsGlobalWindowInner@@IEAAXPEAUJSContext@@PEAVDocument@dom@mozilla@@@Z
|
||||
?InitDocumentDependentState@nsGlobalWindowInner@@IEAAXPEAUJSContext@@@Z
|
||||
?WrapObject@nsINode@@UEAAPEAVJSObject@@PEAUJSContext@@V?$Handle@PEAVJSObject@@@JS@@@Z
|
||||
?WrapNode@nsHTMLDocument@@UEAAPEAVJSObject@@PEAUJSContext@@V?$Handle@PEAVJSObject@@@JS@@@Z
|
||||
?Wrap@HTMLDocument_Binding@dom@mozilla@@YA_NPEAUJSContext@@PEAVnsHTMLDocument@@PEAVnsWrapperCache@@V?$Handle@PEAVJSObject@@@JS@@V?$MutableHandle@PEAVJSObject@@@8@@Z
|
||||
|
@ -1004,21 +1004,13 @@ nsresult nsScriptSecurityManager::CheckLoadURIFlags(
|
||||
}
|
||||
|
||||
nsresult nsScriptSecurityManager::ReportError(const char* aMessageTag,
|
||||
nsIURI* aSource, nsIURI* aTarget,
|
||||
const nsACString& aSourceSpec,
|
||||
const nsACString& aTargetSpec,
|
||||
bool aFromPrivateWindow,
|
||||
uint64_t aInnerWindowID) {
|
||||
nsresult rv;
|
||||
NS_ENSURE_TRUE(aSource && aTarget, NS_ERROR_NULL_POINTER);
|
||||
|
||||
// Get the source URL spec
|
||||
nsAutoCString sourceSpec;
|
||||
rv = aSource->GetAsciiSpec(sourceSpec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Get the target URL spec
|
||||
nsAutoCString targetSpec;
|
||||
rv = aTarget->GetAsciiSpec(targetSpec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (aSourceSpec.IsEmpty() || aTargetSpec.IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIStringBundle> bundle = BundleHelper::GetOrCreate();
|
||||
if (NS_WARN_IF(!bundle)) {
|
||||
@ -1028,9 +1020,10 @@ nsresult nsScriptSecurityManager::ReportError(const char* aMessageTag,
|
||||
// Localize the error message
|
||||
nsAutoString message;
|
||||
AutoTArray<nsString, 2> formatStrings;
|
||||
CopyASCIItoUTF16(sourceSpec, *formatStrings.AppendElement());
|
||||
CopyASCIItoUTF16(targetSpec, *formatStrings.AppendElement());
|
||||
rv = bundle->FormatStringFromName(aMessageTag, formatStrings, message);
|
||||
CopyASCIItoUTF16(aSourceSpec, *formatStrings.AppendElement());
|
||||
CopyASCIItoUTF16(aTargetSpec, *formatStrings.AppendElement());
|
||||
nsresult rv =
|
||||
bundle->FormatStringFromName(aMessageTag, formatStrings, message);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIConsoleService> console(
|
||||
@ -1055,6 +1048,26 @@ nsresult nsScriptSecurityManager::ReportError(const char* aMessageTag,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsScriptSecurityManager::ReportError(const char* aMessageTag,
|
||||
nsIURI* aSource, nsIURI* aTarget,
|
||||
bool aFromPrivateWindow,
|
||||
uint64_t aInnerWindowID) {
|
||||
NS_ENSURE_TRUE(aSource && aTarget, NS_ERROR_NULL_POINTER);
|
||||
|
||||
// Get the source URL spec
|
||||
nsAutoCString sourceSpec;
|
||||
nsresult rv = aSource->GetAsciiSpec(sourceSpec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Get the target URL spec
|
||||
nsAutoCString targetSpec;
|
||||
rv = aTarget->GetAsciiSpec(targetSpec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return ReportError(aMessageTag, sourceSpec, targetSpec, aFromPrivateWindow,
|
||||
aInnerWindowID);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::CheckLoadURIStrWithPrincipal(
|
||||
nsIPrincipal* aPrincipal, const nsACString& aTargetURIStr,
|
||||
|
@ -71,6 +71,13 @@ class nsScriptSecurityManager final : public nsIScriptSecurityManager {
|
||||
static nsresult ReportError(const char* aMessageTag, nsIURI* aSource,
|
||||
nsIURI* aTarget, bool aFromPrivateWindow,
|
||||
uint64_t aInnerWindowID = 0);
|
||||
static nsresult ReportError(const char* aMessageTag,
|
||||
const nsACString& sourceSpec,
|
||||
const nsACString& targetSpec,
|
||||
bool aFromPrivateWindow,
|
||||
uint64_t aInnerWindowID = 0);
|
||||
|
||||
static uint32_t HashPrincipalByOrigin(nsIPrincipal* aPrincipal);
|
||||
|
||||
static bool GetStrictFileOriginPolicy() { return sStrictFileOriginPolicy; }
|
||||
|
||||
|
@ -1267,16 +1267,6 @@ if CONFIG['MOZ_SYSTEM_ZLIB']:
|
||||
'zlib.h',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_ENABLE_STARTUP_NOTIFICATION']:
|
||||
system_headers += [
|
||||
'libsn/sn-common.h',
|
||||
'libsn/sn.h',
|
||||
'libsn/sn-launchee.h',
|
||||
'libsn/sn-launcher.h',
|
||||
'libsn/sn-monitor.h',
|
||||
'libsn/sn-util.h',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_SYSTEM_LIBEVENT']:
|
||||
system_headers += [
|
||||
'event2/event_compat.h',
|
||||
|
@ -133,7 +133,23 @@ module.exports = {
|
||||
"rules": {
|
||||
"mozilla/no-define-cc-etc": "off",
|
||||
}
|
||||
}, ],
|
||||
}, {
|
||||
// All DevTools files should avoid relative paths.
|
||||
"files": [
|
||||
"**"
|
||||
],
|
||||
"excludedFiles": [
|
||||
// Debugger modules have a custom bundling logic which relies on relative
|
||||
// paths.
|
||||
"client/debugger/**",
|
||||
// `client/shared/build` contains node helpers to build the debugger and
|
||||
// not devtools modules.
|
||||
"client/shared/build/**",
|
||||
],
|
||||
"rules": {
|
||||
"mozilla/reject-relative-requires": "error",
|
||||
}
|
||||
}],
|
||||
"rules": {
|
||||
// These are the rules that have been configured so far to match the
|
||||
// devtools coding style.
|
||||
|
@ -8,18 +8,21 @@ const { UPDATE_DETAILS } = require("devtools/client/accessibility/constants");
|
||||
/**
|
||||
* Update details with the given accessible object.
|
||||
*
|
||||
* @param {Object} dom walker front
|
||||
* @param {Object} accessible front
|
||||
*/
|
||||
exports.updateDetails = (domWalker, accessible) => dispatch =>
|
||||
Promise.all([
|
||||
domWalker.getNodeFromActor(accessible.actorID, [
|
||||
"rawAccessible",
|
||||
"DOMNode",
|
||||
]),
|
||||
accessible.getRelations(),
|
||||
accessible.audit(),
|
||||
accessible.hydrate(),
|
||||
])
|
||||
exports.updateDetails = accessible => dispatch =>
|
||||
accessible.targetFront
|
||||
.getFront("inspector")
|
||||
.then(({ walker: domWalker }) =>
|
||||
Promise.all([
|
||||
domWalker.getNodeFromActor(accessible.actorID, [
|
||||
"rawAccessible",
|
||||
"DOMNode",
|
||||
]),
|
||||
accessible.getRelations(),
|
||||
accessible.audit(),
|
||||
accessible.hydrate(),
|
||||
])
|
||||
)
|
||||
.then(response => dispatch({ accessible, type: UPDATE_DETAILS, response }))
|
||||
.catch(error => dispatch({ accessible, type: UPDATE_DETAILS, error }));
|
||||
|
@ -154,7 +154,7 @@ class AccessibilityRow extends Component {
|
||||
scrollIntoView(row);
|
||||
}
|
||||
|
||||
async update() {
|
||||
update() {
|
||||
const {
|
||||
dispatch,
|
||||
member: { object },
|
||||
@ -163,8 +163,7 @@ class AccessibilityRow extends Component {
|
||||
return;
|
||||
}
|
||||
|
||||
const domWalker = (await object.targetFront.getFront("inspector")).walker;
|
||||
dispatch(updateDetails(domWalker, object));
|
||||
dispatch(updateDetails(object));
|
||||
window.emit(EVENTS.NEW_ACCESSIBLE_FRONT_SELECTED, object);
|
||||
}
|
||||
|
||||
|
@ -185,16 +185,13 @@ class Accessible extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
async update() {
|
||||
update() {
|
||||
const { dispatch, accessibleFront } = this.props;
|
||||
if (!accessibleFront.actorID) {
|
||||
return;
|
||||
}
|
||||
|
||||
const domWalker = (await accessibleFront.targetFront.getFront("inspector"))
|
||||
.walker;
|
||||
|
||||
dispatch(updateDetails(domWalker, accessibleFront));
|
||||
dispatch(updateDetails(accessibleFront));
|
||||
}
|
||||
|
||||
setExpanded(item, isExpanded) {
|
||||
|
@ -31,7 +31,12 @@ function ErrorRep(props) {
|
||||
const mode = props.mode;
|
||||
|
||||
let name;
|
||||
if (preview && preview.name && preview.kind) {
|
||||
if (
|
||||
preview &&
|
||||
preview.name &&
|
||||
typeof preview.name === "string" &&
|
||||
preview.kind
|
||||
) {
|
||||
switch (preview.kind) {
|
||||
case "Error":
|
||||
name = preview.name;
|
||||
@ -48,7 +53,7 @@ function ErrorRep(props) {
|
||||
|
||||
const content = [];
|
||||
|
||||
if (mode === MODE.TINY) {
|
||||
if (mode === MODE.TINY || typeof preview.message !== "string") {
|
||||
content.push(name);
|
||||
} else {
|
||||
content.push(`${name}: "${preview.message}"`);
|
||||
|
@ -314,4 +314,43 @@ stubs.set("Error with undefined-grip stack", {
|
||||
},
|
||||
});
|
||||
|
||||
stubs.set("Error with undefined-grip name", {
|
||||
type: "object",
|
||||
actor: "server0.conn0.child1/obj88",
|
||||
class: "Error",
|
||||
extensible: true,
|
||||
frozen: false,
|
||||
sealed: false,
|
||||
ownPropertyLength: 4,
|
||||
preview: {
|
||||
kind: "Error",
|
||||
name: {
|
||||
type: "undefined",
|
||||
},
|
||||
message: "too much recursion",
|
||||
stack: "@debugger eval code:16:13\n",
|
||||
fileName: "debugger eval code",
|
||||
lineNumber: 13,
|
||||
columnNumber: 13,
|
||||
},
|
||||
});
|
||||
|
||||
stubs.set("Error with undefined-grip message", {
|
||||
type: "object",
|
||||
actor: "server0.conn0.child1/obj88",
|
||||
class: "Error",
|
||||
extensible: true,
|
||||
frozen: false,
|
||||
sealed: false,
|
||||
ownPropertyLength: 4,
|
||||
preview: {
|
||||
kind: "Error",
|
||||
message: { type: "undefined" },
|
||||
stack: "@debugger eval code:16:13\n",
|
||||
fileName: "debugger eval code",
|
||||
lineNumber: 13,
|
||||
columnNumber: 13,
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = stubs;
|
||||
|
@ -43,6 +43,84 @@ exports[`Error - Error with invalid stack renders with expected text 1`] = `
|
||||
</span>
|
||||
`;
|
||||
|
||||
exports[`Error - Error with undefined-grip message renders with expected text 1`] = `
|
||||
<span
|
||||
className="objectBox-stackTrace"
|
||||
data-link-actor-id="server0.conn0.child1/obj88"
|
||||
>
|
||||
Error
|
||||
<span
|
||||
className="objectBox-stackTrace-grid"
|
||||
key="stack"
|
||||
>
|
||||
|
||||
<span
|
||||
className="objectBox-stackTrace-fn"
|
||||
key="fn0"
|
||||
>
|
||||
<anonymous>
|
||||
</span>
|
||||
|
||||
<span
|
||||
className="objectBox-stackTrace-location"
|
||||
key="location0"
|
||||
>
|
||||
debugger eval code:16:13
|
||||
</span>
|
||||
|
||||
|
||||
</span>
|
||||
</span>
|
||||
`;
|
||||
|
||||
exports[`Error - Error with undefined-grip message renders with expected text 2`] = `
|
||||
<span
|
||||
className="objectBox-stackTrace"
|
||||
data-link-actor-id="server0.conn0.child1/obj88"
|
||||
>
|
||||
Error
|
||||
</span>
|
||||
`;
|
||||
|
||||
exports[`Error - Error with undefined-grip name renders with expected text 1`] = `
|
||||
<span
|
||||
className="objectBox-stackTrace"
|
||||
data-link-actor-id="server0.conn0.child1/obj88"
|
||||
>
|
||||
Error: "too much recursion"
|
||||
<span
|
||||
className="objectBox-stackTrace-grid"
|
||||
key="stack"
|
||||
>
|
||||
|
||||
<span
|
||||
className="objectBox-stackTrace-fn"
|
||||
key="fn0"
|
||||
>
|
||||
<anonymous>
|
||||
</span>
|
||||
|
||||
<span
|
||||
className="objectBox-stackTrace-location"
|
||||
key="location0"
|
||||
>
|
||||
debugger eval code:16:13
|
||||
</span>
|
||||
|
||||
|
||||
</span>
|
||||
</span>
|
||||
`;
|
||||
|
||||
exports[`Error - Error with undefined-grip name renders with expected text 2`] = `
|
||||
<span
|
||||
className="objectBox-stackTrace"
|
||||
data-link-actor-id="server0.conn0.child1/obj88"
|
||||
>
|
||||
Error
|
||||
</span>
|
||||
`;
|
||||
|
||||
exports[`Error - Error with undefined-grip stack renders with expected text 1`] = `
|
||||
<span
|
||||
className="objectBox-stackTrace"
|
||||
|
@ -618,3 +618,61 @@ describe("Error - Error with undefined-grip stack", () => {
|
||||
expectActorAttribute(renderedComponent, stub.actor);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Error - Error with undefined-grip name", () => {
|
||||
// Test object:
|
||||
// x = new Error("");
|
||||
// x.name = undefined;
|
||||
const stub = stubs.get("Error with undefined-grip name");
|
||||
|
||||
it("correctly selects Error Rep for Error object", () => {
|
||||
expect(getRep(stub)).toBe(ErrorRep.rep);
|
||||
});
|
||||
|
||||
it("renders with expected text", () => {
|
||||
const renderedComponent = shallow(
|
||||
ErrorRep.rep({
|
||||
object: stub,
|
||||
})
|
||||
);
|
||||
expect(renderedComponent).toMatchSnapshot();
|
||||
|
||||
const tinyRenderedComponent = shallow(
|
||||
ErrorRep.rep({
|
||||
object: stub,
|
||||
mode: MODE.TINY,
|
||||
})
|
||||
);
|
||||
|
||||
expect(tinyRenderedComponent).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe("Error - Error with undefined-grip message", () => {
|
||||
// Test object:
|
||||
// x = new Error("");
|
||||
// x.message = undefined;
|
||||
const stub = stubs.get("Error with undefined-grip message");
|
||||
|
||||
it("correctly selects Error Rep for Error object", () => {
|
||||
expect(getRep(stub)).toBe(ErrorRep.rep);
|
||||
});
|
||||
|
||||
it("renders with expected text", () => {
|
||||
const renderedComponent = shallow(
|
||||
ErrorRep.rep({
|
||||
object: stub,
|
||||
})
|
||||
);
|
||||
expect(renderedComponent).toMatchSnapshot();
|
||||
|
||||
const tinyRenderedComponent = shallow(
|
||||
ErrorRep.rep({
|
||||
object: stub,
|
||||
mode: MODE.TINY,
|
||||
})
|
||||
);
|
||||
|
||||
expect(tinyRenderedComponent).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
@ -158,6 +158,7 @@ async function expandFrames(
|
||||
generatedLocation: frame.generatedLocation,
|
||||
originalDisplayName: originalFrame.displayName,
|
||||
originalVariables: originalFrame.variables,
|
||||
asyncCause: null,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -21,6 +21,11 @@ export function selectFrame(cx: ThreadContext, frame: Frame) {
|
||||
return async ({ dispatch, client, getState, sourceMaps }: ThunkArgs) => {
|
||||
assert(cx.thread == frame.thread, "Thread mismatch");
|
||||
|
||||
// Frames with an async cause are not selected
|
||||
if (frame.asyncCause) {
|
||||
return dispatch(selectLocation(cx, frame.location));
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: "SELECT_FRAME",
|
||||
cx,
|
||||
@ -33,6 +38,7 @@ export function selectFrame(cx: ThreadContext, frame: Frame) {
|
||||
}
|
||||
|
||||
dispatch(selectLocation(cx, frame.location));
|
||||
|
||||
dispatch(evaluateExpressions(cx));
|
||||
dispatch(fetchScopes(cx));
|
||||
};
|
||||
|
@ -58,6 +58,8 @@ export function createFrame(
|
||||
this: frame.this,
|
||||
source: null,
|
||||
index,
|
||||
asyncCause: frame.asyncCause,
|
||||
state: frame.state,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -107,13 +107,13 @@ async function listWorkerTargets(args: Args) {
|
||||
installingWorker,
|
||||
evaluatingWorker,
|
||||
} = front;
|
||||
await maybeMarkServiceWorker(activeWorker, "active");
|
||||
await maybeMarkServiceWorker(waitingWorker, "waiting");
|
||||
await maybeMarkServiceWorker(installingWorker, "installing");
|
||||
await maybeMarkServiceWorker(evaluatingWorker, "evaluating");
|
||||
await maybeMarkServiceWorker(activeWorker);
|
||||
await maybeMarkServiceWorker(waitingWorker);
|
||||
await maybeMarkServiceWorker(installingWorker);
|
||||
await maybeMarkServiceWorker(evaluatingWorker);
|
||||
}
|
||||
|
||||
async function maybeMarkServiceWorker(info, status) {
|
||||
async function maybeMarkServiceWorker(info) {
|
||||
if (!info) {
|
||||
return;
|
||||
}
|
||||
@ -123,7 +123,7 @@ async function listWorkerTargets(args: Args) {
|
||||
return;
|
||||
}
|
||||
|
||||
worker.debuggerServiceWorkerStatus = status;
|
||||
worker.debuggerServiceWorkerStatus = info.stateText;
|
||||
if (!workers.includes(worker)) {
|
||||
workers.push(worker);
|
||||
}
|
||||
|
@ -88,6 +88,8 @@ export type FrameFront = {
|
||||
actorID: string,
|
||||
displayName: string,
|
||||
this: any,
|
||||
asyncCause: null | string,
|
||||
state: "on-stack" | "suspended",
|
||||
};
|
||||
|
||||
/**
|
||||
@ -156,9 +158,9 @@ export type TabPayload = {
|
||||
actor: ActorId,
|
||||
animationsActor: ActorId,
|
||||
consoleActor: ActorId,
|
||||
contentViewerActor: ActorId,
|
||||
cssPropertiesActor: ActorId,
|
||||
directorManagerActor: ActorId,
|
||||
emulationActor: ActorId,
|
||||
eventLoopLagActor: ActorId,
|
||||
framerateActor: ActorId,
|
||||
inspectorActor: ActorId,
|
||||
@ -169,6 +171,7 @@ export type TabPayload = {
|
||||
performanceEntriesActor: ActorId,
|
||||
profilerActor: ActorId,
|
||||
reflowActor: ActorId,
|
||||
responsiveActor: ActorId,
|
||||
storageActor: ActorId,
|
||||
styleEditorActor: ActorId,
|
||||
styleSheetsActor: ActorId,
|
||||
|
@ -68,6 +68,7 @@ type FrameComponentProps = {
|
||||
copyStackTrace: Function,
|
||||
toggleFrameworkGrouping: Function,
|
||||
selectFrame: typeof actions.selectFrame,
|
||||
selectLocation: typeof actions.selectLocation,
|
||||
frameworkGroupingOn: boolean,
|
||||
hideLocation: boolean,
|
||||
shouldMapDisplayName: boolean,
|
||||
@ -75,7 +76,7 @@ type FrameComponentProps = {
|
||||
displayFullUrl: boolean,
|
||||
getFrameTitle?: string => string,
|
||||
disableContextMenu: boolean,
|
||||
selectable: boolean,
|
||||
panel: "debugger" | "webconsole",
|
||||
};
|
||||
|
||||
export default class FrameComponent extends Component<FrameComponentProps> {
|
||||
@ -85,6 +86,14 @@ export default class FrameComponent extends Component<FrameComponentProps> {
|
||||
disableContextMenu: false,
|
||||
};
|
||||
|
||||
get isSelectable() {
|
||||
return this.props.panel == "webconsole";
|
||||
}
|
||||
|
||||
get isDebugger() {
|
||||
return this.props.panel == "debugger";
|
||||
}
|
||||
|
||||
onContextMenu(event: SyntheticMouseEvent<HTMLElement>) {
|
||||
const {
|
||||
frame,
|
||||
@ -111,6 +120,7 @@ export default class FrameComponent extends Component<FrameComponentProps> {
|
||||
if (e.button !== 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.props.selectFrame(this.props.cx, frame);
|
||||
}
|
||||
|
||||
@ -122,6 +132,7 @@ export default class FrameComponent extends Component<FrameComponentProps> {
|
||||
if (event.key != "Enter") {
|
||||
return;
|
||||
}
|
||||
|
||||
this.props.selectFrame(this.props.cx, frame);
|
||||
}
|
||||
|
||||
@ -134,7 +145,6 @@ export default class FrameComponent extends Component<FrameComponentProps> {
|
||||
displayFullUrl,
|
||||
getFrameTitle,
|
||||
disableContextMenu,
|
||||
selectable,
|
||||
} = this.props;
|
||||
const { l10n } = this.context;
|
||||
|
||||
@ -165,12 +175,14 @@ export default class FrameComponent extends Component<FrameComponentProps> {
|
||||
>
|
||||
{frame.asyncCause && (
|
||||
<span className="location-async-cause">
|
||||
{selectable && <FrameIndent />}
|
||||
{l10n.getFormatStr("stacktrace.asyncStack", frame.asyncCause)}
|
||||
{selectable && <br className="clipboard-only" />}
|
||||
{this.isSelectable && <FrameIndent />}
|
||||
{this.isDebugger
|
||||
? frame.asyncCause
|
||||
: l10n.getFormatStr("stacktrace.asyncStack", frame.asyncCause)}
|
||||
{this.isSelectable && <br className="clipboard-only" />}
|
||||
</span>
|
||||
)}
|
||||
{selectable && <FrameIndent />}
|
||||
{this.isSelectable && <FrameIndent />}
|
||||
<FrameTitle
|
||||
frame={frame}
|
||||
options={{ shouldMapDisplayName }}
|
||||
@ -180,7 +192,7 @@ export default class FrameComponent extends Component<FrameComponentProps> {
|
||||
{!hideLocation && (
|
||||
<FrameLocation frame={frame} displayFullUrl={displayFullUrl} />
|
||||
)}
|
||||
{selectable && <br className="clipboard-only" />}
|
||||
{this.isSelectable && <br className="clipboard-only" />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -43,6 +43,10 @@
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.call-stack-pane .location-async-cause {
|
||||
color: var(--theme-comment);
|
||||
}
|
||||
|
||||
.theme-light .frames .location {
|
||||
color: var(--theme-comment);
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ type Props = {
|
||||
group: Frame[],
|
||||
selectedFrame: Frame,
|
||||
selectFrame: typeof actions.selectFrame,
|
||||
selectLocation: typeof actions.selectLocation,
|
||||
toggleFrameworkGrouping: Function,
|
||||
copyStackTrace: Function,
|
||||
toggleBlackBox: Function,
|
||||
@ -51,7 +52,7 @@ type Props = {
|
||||
displayFullUrl: boolean,
|
||||
getFrameTitle?: string => string,
|
||||
disableContextMenu: boolean,
|
||||
selectable: boolean,
|
||||
panel: "debugger" | "webconsole",
|
||||
};
|
||||
|
||||
type State = {
|
||||
@ -66,6 +67,10 @@ export default class Group extends Component<Props, State> {
|
||||
this.state = { expanded: false };
|
||||
}
|
||||
|
||||
get isSelectable() {
|
||||
return this.props.panel == "webconsole";
|
||||
}
|
||||
|
||||
onContextMenu(event: SyntheticMouseEvent<HTMLElement>) {
|
||||
const {
|
||||
group,
|
||||
@ -95,6 +100,7 @@ export default class Group extends Component<Props, State> {
|
||||
cx,
|
||||
group,
|
||||
selectFrame,
|
||||
selectLocation,
|
||||
selectedFrame,
|
||||
toggleFrameworkGrouping,
|
||||
frameworkGroupingOn,
|
||||
@ -103,7 +109,7 @@ export default class Group extends Component<Props, State> {
|
||||
displayFullUrl,
|
||||
getFrameTitle,
|
||||
disableContextMenu,
|
||||
selectable,
|
||||
panel,
|
||||
} = this.props;
|
||||
|
||||
const { expanded } = this.state;
|
||||
@ -114,7 +120,7 @@ export default class Group extends Component<Props, State> {
|
||||
return (
|
||||
<div className="frames-list">
|
||||
{group.reduce((acc, frame, i) => {
|
||||
if (selectable) {
|
||||
if (this.isSelectable) {
|
||||
acc.push(<FrameIndent key={`frame-indent-${i}`} />);
|
||||
}
|
||||
return acc.concat(
|
||||
@ -127,13 +133,14 @@ export default class Group extends Component<Props, State> {
|
||||
key={frame.id}
|
||||
selectedFrame={selectedFrame}
|
||||
selectFrame={selectFrame}
|
||||
selectLocation={selectLocation}
|
||||
shouldMapDisplayName={false}
|
||||
toggleBlackBox={toggleBlackBox}
|
||||
toggleFrameworkGrouping={toggleFrameworkGrouping}
|
||||
displayFullUrl={displayFullUrl}
|
||||
getFrameTitle={getFrameTitle}
|
||||
disableContextMenu={disableContextMenu}
|
||||
selectable={selectable}
|
||||
panel={panel}
|
||||
/>
|
||||
);
|
||||
}, [])}
|
||||
@ -143,7 +150,7 @@ export default class Group extends Component<Props, State> {
|
||||
|
||||
renderDescription() {
|
||||
const { l10n } = this.context;
|
||||
const { selectable, group } = this.props;
|
||||
const { group } = this.props;
|
||||
|
||||
const frame = group[0];
|
||||
const expanded = this.state.expanded;
|
||||
@ -161,11 +168,11 @@ export default class Group extends Component<Props, State> {
|
||||
tabIndex={0}
|
||||
title={title}
|
||||
>
|
||||
{selectable && <FrameIndent />}
|
||||
{this.isSelectable && <FrameIndent />}
|
||||
<FrameLocation frame={frame} expanded={expanded} />
|
||||
{selectable && <span className="clipboard-only"> </span>}
|
||||
{this.isSelectable && <span className="clipboard-only"> </span>}
|
||||
<Badge>{this.props.group.length}</Badge>
|
||||
{selectable && <br className="clipboard-only" />}
|
||||
{this.isSelectable && <br className="clipboard-only" />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -31,21 +31,23 @@ const NUM_FRAMES_SHOWN = 7;
|
||||
|
||||
type OwnProps = {|
|
||||
getFrameTitle?: string => string,
|
||||
selectable?: boolean,
|
||||
panel: "debugger" | "webconsole",
|
||||
|};
|
||||
|
||||
type Props = {
|
||||
cx: ThreadContext,
|
||||
frames: Array<Frame>,
|
||||
frameworkGroupingOn: boolean,
|
||||
selectedFrame: Object,
|
||||
selectFrame: typeof actions.selectFrame,
|
||||
selectLocation: typeof actions.selectLocation,
|
||||
toggleBlackBox: Function,
|
||||
toggleFrameworkGrouping: Function,
|
||||
disableFrameTruncate: boolean,
|
||||
disableContextMenu: boolean,
|
||||
displayFullUrl: boolean,
|
||||
getFrameTitle?: string => string,
|
||||
selectable?: boolean,
|
||||
panel: "debugger" | "webconsole",
|
||||
};
|
||||
|
||||
type State = {
|
||||
@ -118,13 +120,14 @@ class Frames extends Component<Props, State> {
|
||||
const {
|
||||
cx,
|
||||
selectFrame,
|
||||
selectLocation,
|
||||
selectedFrame,
|
||||
toggleBlackBox,
|
||||
frameworkGroupingOn,
|
||||
displayFullUrl,
|
||||
getFrameTitle,
|
||||
disableContextMenu,
|
||||
selectable = false,
|
||||
panel,
|
||||
} = this.props;
|
||||
|
||||
const framesOrGroups = this.truncateFrames(this.collapseFrames(frames));
|
||||
@ -144,13 +147,14 @@ class Frames extends Component<Props, State> {
|
||||
copyStackTrace={this.copyStackTrace}
|
||||
frameworkGroupingOn={frameworkGroupingOn}
|
||||
selectFrame={selectFrame}
|
||||
selectLocation={selectLocation}
|
||||
selectedFrame={selectedFrame}
|
||||
toggleBlackBox={toggleBlackBox}
|
||||
key={String(frameOrGroup.id)}
|
||||
displayFullUrl={displayFullUrl}
|
||||
getFrameTitle={getFrameTitle}
|
||||
disableContextMenu={disableContextMenu}
|
||||
selectable={selectable}
|
||||
panel={panel}
|
||||
/>
|
||||
) : (
|
||||
<Group
|
||||
@ -160,13 +164,14 @@ class Frames extends Component<Props, State> {
|
||||
copyStackTrace={this.copyStackTrace}
|
||||
frameworkGroupingOn={frameworkGroupingOn}
|
||||
selectFrame={selectFrame}
|
||||
selectLocation={selectLocation}
|
||||
selectedFrame={selectedFrame}
|
||||
toggleBlackBox={toggleBlackBox}
|
||||
key={frameOrGroup[0].id}
|
||||
displayFullUrl={displayFullUrl}
|
||||
getFrameTitle={getFrameTitle}
|
||||
disableContextMenu={disableContextMenu}
|
||||
selectable={selectable}
|
||||
panel={panel}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
@ -232,6 +237,7 @@ export default connect<Props, OwnProps, _, _, _, _>(
|
||||
mapStateToProps,
|
||||
{
|
||||
selectFrame: actions.selectFrame,
|
||||
selectLocation: actions.selectLocation,
|
||||
toggleBlackBox: actions.toggleBlackBox,
|
||||
toggleFrameworkGrouping: actions.toggleFrameworkGrouping,
|
||||
}
|
||||
|
@ -24,10 +24,11 @@ function frameProperties(frame, selectedFrame: any, overrides = {}) {
|
||||
copyStackTrace: jest.fn(),
|
||||
contextTypes: {},
|
||||
selectFrame: jest.fn(),
|
||||
selectLocation: jest.fn(),
|
||||
toggleBlackBox: jest.fn(),
|
||||
displayFullUrl: false,
|
||||
frameworkGroupingOn: false,
|
||||
selectable: true,
|
||||
panel: "webconsole",
|
||||
toggleFrameworkGrouping: null,
|
||||
...overrides,
|
||||
};
|
||||
|
@ -25,11 +25,12 @@ function render(overrides = {}) {
|
||||
frameworkGroupingOn: true,
|
||||
toggleFrameworkGrouping: jest.fn(),
|
||||
selectFrame: jest.fn(),
|
||||
selectLocation: jest.fn(),
|
||||
copyStackTrace: jest.fn(),
|
||||
toggleBlackBox: jest.fn(),
|
||||
disableContextMenu: false,
|
||||
displayFullUrl: false,
|
||||
selectable: true,
|
||||
panel: "webconsole",
|
||||
};
|
||||
|
||||
const props = { ...defaultProps, ...overrides };
|
||||
|
@ -15,6 +15,7 @@ exports[`Frame getFrameTitle 1`] = `
|
||||
<FrameTitle
|
||||
frame={
|
||||
Object {
|
||||
"asyncCause": null,
|
||||
"displayName": "renderFoo",
|
||||
"generatedLocation": Object {
|
||||
"line": 10,
|
||||
@ -51,6 +52,7 @@ exports[`Frame getFrameTitle 1`] = `
|
||||
"relativeUrl": "https://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com/assets/src/js/foo-view.js",
|
||||
"url": "https://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com/assets/src/js/foo-view.js",
|
||||
},
|
||||
"state": "on-stack",
|
||||
"this": Object {},
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
@ -70,6 +72,7 @@ exports[`Frame getFrameTitle 1`] = `
|
||||
displayFullUrl={false}
|
||||
frame={
|
||||
Object {
|
||||
"asyncCause": null,
|
||||
"displayName": "renderFoo",
|
||||
"generatedLocation": Object {
|
||||
"line": 10,
|
||||
@ -106,6 +109,7 @@ exports[`Frame getFrameTitle 1`] = `
|
||||
"relativeUrl": "https://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com/assets/src/js/foo-view.js",
|
||||
"url": "https://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com/assets/src/js/foo-view.js",
|
||||
},
|
||||
"state": "on-stack",
|
||||
"this": Object {},
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
@ -131,6 +135,7 @@ exports[`Frame library frame 1`] = `
|
||||
<FrameTitle
|
||||
frame={
|
||||
Object {
|
||||
"asyncCause": null,
|
||||
"displayName": "updateEvents",
|
||||
"generatedLocation": Object {
|
||||
"line": 12,
|
||||
@ -168,6 +173,7 @@ exports[`Frame library frame 1`] = `
|
||||
"relativeUrl": "backbone.js",
|
||||
"url": "backbone.js",
|
||||
},
|
||||
"state": "on-stack",
|
||||
"this": Object {},
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
@ -187,6 +193,7 @@ exports[`Frame library frame 1`] = `
|
||||
displayFullUrl={false}
|
||||
frame={
|
||||
Object {
|
||||
"asyncCause": null,
|
||||
"displayName": "updateEvents",
|
||||
"generatedLocation": Object {
|
||||
"line": 12,
|
||||
@ -224,6 +231,7 @@ exports[`Frame library frame 1`] = `
|
||||
"relativeUrl": "backbone.js",
|
||||
"url": "backbone.js",
|
||||
},
|
||||
"state": "on-stack",
|
||||
"this": Object {},
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
@ -249,6 +257,7 @@ exports[`Frame user frame (not selected) 1`] = `
|
||||
<FrameTitle
|
||||
frame={
|
||||
Object {
|
||||
"asyncCause": null,
|
||||
"displayName": "renderFoo",
|
||||
"generatedLocation": Object {
|
||||
"line": 10,
|
||||
@ -285,6 +294,7 @@ exports[`Frame user frame (not selected) 1`] = `
|
||||
"relativeUrl": "foo-view.js",
|
||||
"url": "foo-view.js",
|
||||
},
|
||||
"state": "on-stack",
|
||||
"this": Object {},
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
@ -304,6 +314,7 @@ exports[`Frame user frame (not selected) 1`] = `
|
||||
displayFullUrl={false}
|
||||
frame={
|
||||
Object {
|
||||
"asyncCause": null,
|
||||
"displayName": "renderFoo",
|
||||
"generatedLocation": Object {
|
||||
"line": 10,
|
||||
@ -340,6 +351,7 @@ exports[`Frame user frame (not selected) 1`] = `
|
||||
"relativeUrl": "foo-view.js",
|
||||
"url": "foo-view.js",
|
||||
},
|
||||
"state": "on-stack",
|
||||
"this": Object {},
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
@ -365,6 +377,7 @@ exports[`Frame user frame 1`] = `
|
||||
<FrameTitle
|
||||
frame={
|
||||
Object {
|
||||
"asyncCause": null,
|
||||
"displayName": "renderFoo",
|
||||
"generatedLocation": Object {
|
||||
"line": 10,
|
||||
@ -401,6 +414,7 @@ exports[`Frame user frame 1`] = `
|
||||
"relativeUrl": "foo-view.js",
|
||||
"url": "foo-view.js",
|
||||
},
|
||||
"state": "on-stack",
|
||||
"this": Object {},
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
@ -420,6 +434,7 @@ exports[`Frame user frame 1`] = `
|
||||
displayFullUrl={false}
|
||||
frame={
|
||||
Object {
|
||||
"asyncCause": null,
|
||||
"displayName": "renderFoo",
|
||||
"generatedLocation": Object {
|
||||
"line": 10,
|
||||
@ -456,6 +471,7 @@ exports[`Frame user frame 1`] = `
|
||||
"relativeUrl": "foo-view.js",
|
||||
"url": "foo-view.js",
|
||||
},
|
||||
"state": "on-stack",
|
||||
"this": Object {},
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ exports[`Frames Blackboxed Frames filters blackboxed frames 1`] = `
|
||||
disableContextMenu={false}
|
||||
frame={
|
||||
Object {
|
||||
"asyncCause": null,
|
||||
"displayName": "display-1",
|
||||
"generatedLocation": Object {
|
||||
"line": 4,
|
||||
@ -48,6 +49,7 @@ exports[`Frames Blackboxed Frames filters blackboxed frames 1`] = `
|
||||
"relativeUrl": "url",
|
||||
"url": "url",
|
||||
},
|
||||
"state": "on-stack",
|
||||
"this": Object {},
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
@ -56,9 +58,9 @@ exports[`Frames Blackboxed Frames filters blackboxed frames 1`] = `
|
||||
hideLocation={false}
|
||||
key="1"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"asyncCause": null,
|
||||
"displayName": "display-1",
|
||||
"generatedLocation": Object {
|
||||
"line": 4,
|
||||
@ -95,6 +97,7 @@ exports[`Frames Blackboxed Frames filters blackboxed frames 1`] = `
|
||||
"relativeUrl": "url",
|
||||
"url": "url",
|
||||
},
|
||||
"state": "on-stack",
|
||||
"this": Object {},
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
@ -108,6 +111,7 @@ exports[`Frames Blackboxed Frames filters blackboxed frames 1`] = `
|
||||
disableContextMenu={false}
|
||||
frame={
|
||||
Object {
|
||||
"asyncCause": null,
|
||||
"displayName": "display-3",
|
||||
"generatedLocation": Object {
|
||||
"line": 4,
|
||||
@ -144,6 +148,7 @@ exports[`Frames Blackboxed Frames filters blackboxed frames 1`] = `
|
||||
"relativeUrl": "url",
|
||||
"url": "url",
|
||||
},
|
||||
"state": "on-stack",
|
||||
"this": Object {},
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
@ -152,9 +157,9 @@ exports[`Frames Blackboxed Frames filters blackboxed frames 1`] = `
|
||||
hideLocation={false}
|
||||
key="3"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"asyncCause": null,
|
||||
"displayName": "display-1",
|
||||
"generatedLocation": Object {
|
||||
"line": 4,
|
||||
@ -191,6 +196,7 @@ exports[`Frames Blackboxed Frames filters blackboxed frames 1`] = `
|
||||
"relativeUrl": "url",
|
||||
"url": "url",
|
||||
},
|
||||
"state": "on-stack",
|
||||
"this": Object {},
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
@ -222,7 +228,6 @@ exports[`Frames Library Frames groups all the Webpack-related frames 1`] = `
|
||||
hideLocation={false}
|
||||
key="1-appFrame"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"id": "1-appFrame",
|
||||
@ -265,7 +270,6 @@ exports[`Frames Library Frames groups all the Webpack-related frames 1`] = `
|
||||
}
|
||||
key="2-webpackBootstrapFrame"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"id": "1-appFrame",
|
||||
@ -297,7 +301,6 @@ exports[`Frames Library Frames selectable framework frames 1`] = `
|
||||
hideLocation={false}
|
||||
key="1"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={true}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"id": 1,
|
||||
@ -320,7 +323,6 @@ exports[`Frames Library Frames selectable framework frames 1`] = `
|
||||
hideLocation={false}
|
||||
key="2"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={true}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"id": 1,
|
||||
@ -343,7 +345,6 @@ exports[`Frames Library Frames selectable framework frames 1`] = `
|
||||
hideLocation={false}
|
||||
key="3"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={true}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"id": 1,
|
||||
@ -365,7 +366,6 @@ exports[`Frames Library Frames selectable framework frames 1`] = `
|
||||
hideLocation={false}
|
||||
key="8"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={true}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"id": 1,
|
||||
@ -398,7 +398,6 @@ exports[`Frames Library Frames selectable framework frames 2`] = `
|
||||
hideLocation={false}
|
||||
key="1"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={true}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"id": 1,
|
||||
@ -425,7 +424,6 @@ exports[`Frames Library Frames selectable framework frames 2`] = `
|
||||
}
|
||||
key="2"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={true}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"id": 1,
|
||||
@ -446,7 +444,6 @@ exports[`Frames Library Frames selectable framework frames 2`] = `
|
||||
hideLocation={false}
|
||||
key="8"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={true}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"id": 1,
|
||||
@ -479,7 +476,6 @@ exports[`Frames Library Frames toggling framework frames 1`] = `
|
||||
hideLocation={false}
|
||||
key="1"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"id": 1,
|
||||
@ -502,7 +498,6 @@ exports[`Frames Library Frames toggling framework frames 1`] = `
|
||||
hideLocation={false}
|
||||
key="2"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"id": 1,
|
||||
@ -525,7 +520,6 @@ exports[`Frames Library Frames toggling framework frames 1`] = `
|
||||
hideLocation={false}
|
||||
key="3"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"id": 1,
|
||||
@ -547,7 +541,6 @@ exports[`Frames Library Frames toggling framework frames 1`] = `
|
||||
hideLocation={false}
|
||||
key="8"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"id": 1,
|
||||
@ -580,7 +573,6 @@ exports[`Frames Library Frames toggling framework frames 2`] = `
|
||||
hideLocation={false}
|
||||
key="1"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"id": 1,
|
||||
@ -607,7 +599,6 @@ exports[`Frames Library Frames toggling framework frames 2`] = `
|
||||
}
|
||||
key="2"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"id": 1,
|
||||
@ -628,7 +619,6 @@ exports[`Frames Library Frames toggling framework frames 2`] = `
|
||||
hideLocation={false}
|
||||
key="8"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"id": 1,
|
||||
@ -661,7 +651,6 @@ exports[`Frames Supports different number of frames disable frame truncation 1`]
|
||||
hideLocation={false}
|
||||
key="1"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={null}
|
||||
shouldMapDisplayName={true}
|
||||
toggleBlackBox={[MockFunction]}
|
||||
@ -679,7 +668,6 @@ exports[`Frames Supports different number of frames disable frame truncation 1`]
|
||||
hideLocation={false}
|
||||
key="2"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={null}
|
||||
shouldMapDisplayName={true}
|
||||
toggleBlackBox={[MockFunction]}
|
||||
@ -697,7 +685,6 @@ exports[`Frames Supports different number of frames disable frame truncation 1`]
|
||||
hideLocation={false}
|
||||
key="3"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={null}
|
||||
shouldMapDisplayName={true}
|
||||
toggleBlackBox={[MockFunction]}
|
||||
@ -715,7 +702,6 @@ exports[`Frames Supports different number of frames disable frame truncation 1`]
|
||||
hideLocation={false}
|
||||
key="4"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={null}
|
||||
shouldMapDisplayName={true}
|
||||
toggleBlackBox={[MockFunction]}
|
||||
@ -733,7 +719,6 @@ exports[`Frames Supports different number of frames disable frame truncation 1`]
|
||||
hideLocation={false}
|
||||
key="5"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={null}
|
||||
shouldMapDisplayName={true}
|
||||
toggleBlackBox={[MockFunction]}
|
||||
@ -751,7 +736,6 @@ exports[`Frames Supports different number of frames disable frame truncation 1`]
|
||||
hideLocation={false}
|
||||
key="6"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={null}
|
||||
shouldMapDisplayName={true}
|
||||
toggleBlackBox={[MockFunction]}
|
||||
@ -769,7 +753,6 @@ exports[`Frames Supports different number of frames disable frame truncation 1`]
|
||||
hideLocation={false}
|
||||
key="7"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={null}
|
||||
shouldMapDisplayName={true}
|
||||
toggleBlackBox={[MockFunction]}
|
||||
@ -787,7 +770,6 @@ exports[`Frames Supports different number of frames disable frame truncation 1`]
|
||||
hideLocation={false}
|
||||
key="8"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={null}
|
||||
shouldMapDisplayName={true}
|
||||
toggleBlackBox={[MockFunction]}
|
||||
@ -805,7 +787,6 @@ exports[`Frames Supports different number of frames disable frame truncation 1`]
|
||||
hideLocation={false}
|
||||
key="9"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={null}
|
||||
shouldMapDisplayName={true}
|
||||
toggleBlackBox={[MockFunction]}
|
||||
@ -823,7 +804,6 @@ exports[`Frames Supports different number of frames disable frame truncation 1`]
|
||||
hideLocation={false}
|
||||
key="10"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={null}
|
||||
shouldMapDisplayName={true}
|
||||
toggleBlackBox={[MockFunction]}
|
||||
@ -841,7 +821,6 @@ exports[`Frames Supports different number of frames disable frame truncation 1`]
|
||||
hideLocation={false}
|
||||
key="11"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={null}
|
||||
shouldMapDisplayName={true}
|
||||
toggleBlackBox={[MockFunction]}
|
||||
@ -859,7 +838,6 @@ exports[`Frames Supports different number of frames disable frame truncation 1`]
|
||||
hideLocation={false}
|
||||
key="12"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={null}
|
||||
shouldMapDisplayName={true}
|
||||
toggleBlackBox={[MockFunction]}
|
||||
@ -877,7 +855,6 @@ exports[`Frames Supports different number of frames disable frame truncation 1`]
|
||||
hideLocation={false}
|
||||
key="13"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={null}
|
||||
shouldMapDisplayName={true}
|
||||
toggleBlackBox={[MockFunction]}
|
||||
@ -895,7 +872,6 @@ exports[`Frames Supports different number of frames disable frame truncation 1`]
|
||||
hideLocation={false}
|
||||
key="14"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={null}
|
||||
shouldMapDisplayName={true}
|
||||
toggleBlackBox={[MockFunction]}
|
||||
@ -913,7 +889,6 @@ exports[`Frames Supports different number of frames disable frame truncation 1`]
|
||||
hideLocation={false}
|
||||
key="15"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={null}
|
||||
shouldMapDisplayName={true}
|
||||
toggleBlackBox={[MockFunction]}
|
||||
@ -931,7 +906,6 @@ exports[`Frames Supports different number of frames disable frame truncation 1`]
|
||||
hideLocation={false}
|
||||
key="16"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={null}
|
||||
shouldMapDisplayName={true}
|
||||
toggleBlackBox={[MockFunction]}
|
||||
@ -949,7 +923,6 @@ exports[`Frames Supports different number of frames disable frame truncation 1`]
|
||||
hideLocation={false}
|
||||
key="17"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={null}
|
||||
shouldMapDisplayName={true}
|
||||
toggleBlackBox={[MockFunction]}
|
||||
@ -967,7 +940,6 @@ exports[`Frames Supports different number of frames disable frame truncation 1`]
|
||||
hideLocation={false}
|
||||
key="18"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={null}
|
||||
shouldMapDisplayName={true}
|
||||
toggleBlackBox={[MockFunction]}
|
||||
@ -985,7 +957,6 @@ exports[`Frames Supports different number of frames disable frame truncation 1`]
|
||||
hideLocation={false}
|
||||
key="19"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={null}
|
||||
shouldMapDisplayName={true}
|
||||
toggleBlackBox={[MockFunction]}
|
||||
@ -1003,7 +974,6 @@ exports[`Frames Supports different number of frames disable frame truncation 1`]
|
||||
hideLocation={false}
|
||||
key="20"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={null}
|
||||
shouldMapDisplayName={true}
|
||||
toggleBlackBox={[MockFunction]}
|
||||
@ -1044,7 +1014,6 @@ exports[`Frames Supports different number of frames one frame 1`] = `
|
||||
hideLocation={false}
|
||||
key="1"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"id": 1,
|
||||
@ -1085,7 +1054,6 @@ exports[`Frames Supports different number of frames passes the getFrameTitle pro
|
||||
hideLocation={false}
|
||||
key="1"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={null}
|
||||
shouldMapDisplayName={true}
|
||||
toggleBlackBox={[MockFunction]}
|
||||
@ -1114,7 +1082,6 @@ exports[`Frames Supports different number of frames toggling the show more butto
|
||||
hideLocation={false}
|
||||
key="1"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"id": 1,
|
||||
@ -1136,7 +1103,6 @@ exports[`Frames Supports different number of frames toggling the show more butto
|
||||
hideLocation={false}
|
||||
key="2"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"id": 1,
|
||||
@ -1158,7 +1124,6 @@ exports[`Frames Supports different number of frames toggling the show more butto
|
||||
hideLocation={false}
|
||||
key="3"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"id": 1,
|
||||
@ -1180,7 +1145,6 @@ exports[`Frames Supports different number of frames toggling the show more butto
|
||||
hideLocation={false}
|
||||
key="4"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"id": 1,
|
||||
@ -1202,7 +1166,6 @@ exports[`Frames Supports different number of frames toggling the show more butto
|
||||
hideLocation={false}
|
||||
key="5"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"id": 1,
|
||||
@ -1224,7 +1187,6 @@ exports[`Frames Supports different number of frames toggling the show more butto
|
||||
hideLocation={false}
|
||||
key="6"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"id": 1,
|
||||
@ -1246,7 +1208,6 @@ exports[`Frames Supports different number of frames toggling the show more butto
|
||||
hideLocation={false}
|
||||
key="7"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"id": 1,
|
||||
@ -1268,7 +1229,6 @@ exports[`Frames Supports different number of frames toggling the show more butto
|
||||
hideLocation={false}
|
||||
key="8"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"id": 1,
|
||||
@ -1290,7 +1250,6 @@ exports[`Frames Supports different number of frames toggling the show more butto
|
||||
hideLocation={false}
|
||||
key="9"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"id": 1,
|
||||
@ -1312,7 +1271,6 @@ exports[`Frames Supports different number of frames toggling the show more butto
|
||||
hideLocation={false}
|
||||
key="10"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={false}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"id": 1,
|
||||
|
@ -18,6 +18,7 @@ exports[`Group displays a group 1`] = `
|
||||
expanded={false}
|
||||
frame={
|
||||
Object {
|
||||
"asyncCause": null,
|
||||
"displayName": "foo",
|
||||
"generatedLocation": Object {
|
||||
"line": 4,
|
||||
@ -55,6 +56,7 @@ exports[`Group displays a group 1`] = `
|
||||
"relativeUrl": "url",
|
||||
"url": "url",
|
||||
},
|
||||
"state": "on-stack",
|
||||
"this": Object {},
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
@ -93,6 +95,7 @@ exports[`Group passes the getFrameTitle prop to the Frame components 1`] = `
|
||||
expanded={true}
|
||||
frame={
|
||||
Object {
|
||||
"asyncCause": null,
|
||||
"displayName": "renderFoo",
|
||||
"generatedLocation": Object {
|
||||
"line": 55,
|
||||
@ -130,6 +133,7 @@ exports[`Group passes the getFrameTitle prop to the Frame components 1`] = `
|
||||
"relativeUrl": "http://myfile.com/mahscripts.js",
|
||||
"url": "http://myfile.com/mahscripts.js",
|
||||
},
|
||||
"state": "on-stack",
|
||||
"this": Object {},
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
@ -167,6 +171,7 @@ exports[`Group passes the getFrameTitle prop to the Frame components 1`] = `
|
||||
displayFullUrl={false}
|
||||
frame={
|
||||
Object {
|
||||
"asyncCause": null,
|
||||
"displayName": "renderFoo",
|
||||
"generatedLocation": Object {
|
||||
"line": 55,
|
||||
@ -204,6 +209,7 @@ exports[`Group passes the getFrameTitle prop to the Frame components 1`] = `
|
||||
"relativeUrl": "http://myfile.com/mahscripts.js",
|
||||
"url": "http://myfile.com/mahscripts.js",
|
||||
},
|
||||
"state": "on-stack",
|
||||
"this": Object {},
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
@ -212,10 +218,12 @@ exports[`Group passes the getFrameTitle prop to the Frame components 1`] = `
|
||||
getFrameTitle={[Function]}
|
||||
hideLocation={true}
|
||||
key="1"
|
||||
panel="webconsole"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={true}
|
||||
selectLocation={[MockFunction]}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"asyncCause": null,
|
||||
"displayName": "foo",
|
||||
"generatedLocation": Object {
|
||||
"line": 4,
|
||||
@ -253,6 +261,7 @@ exports[`Group passes the getFrameTitle prop to the Frame components 1`] = `
|
||||
"relativeUrl": "url",
|
||||
"url": "url",
|
||||
},
|
||||
"state": "on-stack",
|
||||
"this": Object {},
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
@ -278,6 +287,7 @@ exports[`Group passes the getFrameTitle prop to the Frame components 1`] = `
|
||||
displayFullUrl={false}
|
||||
frame={
|
||||
Object {
|
||||
"asyncCause": null,
|
||||
"displayName": "a",
|
||||
"generatedLocation": Object {
|
||||
"line": 55,
|
||||
@ -315,6 +325,7 @@ exports[`Group passes the getFrameTitle prop to the Frame components 1`] = `
|
||||
"relativeUrl": "http://myfile.com/back.js",
|
||||
"url": "http://myfile.com/back.js",
|
||||
},
|
||||
"state": "on-stack",
|
||||
"this": Object {},
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
@ -323,10 +334,12 @@ exports[`Group passes the getFrameTitle prop to the Frame components 1`] = `
|
||||
getFrameTitle={[Function]}
|
||||
hideLocation={true}
|
||||
key="2"
|
||||
panel="webconsole"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={true}
|
||||
selectLocation={[MockFunction]}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"asyncCause": null,
|
||||
"displayName": "foo",
|
||||
"generatedLocation": Object {
|
||||
"line": 4,
|
||||
@ -364,6 +377,7 @@ exports[`Group passes the getFrameTitle prop to the Frame components 1`] = `
|
||||
"relativeUrl": "url",
|
||||
"url": "url",
|
||||
},
|
||||
"state": "on-stack",
|
||||
"this": Object {},
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
@ -389,6 +403,7 @@ exports[`Group passes the getFrameTitle prop to the Frame components 1`] = `
|
||||
displayFullUrl={false}
|
||||
frame={
|
||||
Object {
|
||||
"asyncCause": null,
|
||||
"displayName": "b",
|
||||
"generatedLocation": Object {
|
||||
"line": 55,
|
||||
@ -426,6 +441,7 @@ exports[`Group passes the getFrameTitle prop to the Frame components 1`] = `
|
||||
"relativeUrl": "http://myfile.com/back.js",
|
||||
"url": "http://myfile.com/back.js",
|
||||
},
|
||||
"state": "on-stack",
|
||||
"this": Object {},
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
@ -434,10 +450,12 @@ exports[`Group passes the getFrameTitle prop to the Frame components 1`] = `
|
||||
getFrameTitle={[Function]}
|
||||
hideLocation={true}
|
||||
key="3"
|
||||
panel="webconsole"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={true}
|
||||
selectLocation={[MockFunction]}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"asyncCause": null,
|
||||
"displayName": "foo",
|
||||
"generatedLocation": Object {
|
||||
"line": 4,
|
||||
@ -475,6 +493,7 @@ exports[`Group passes the getFrameTitle prop to the Frame components 1`] = `
|
||||
"relativeUrl": "url",
|
||||
"url": "url",
|
||||
},
|
||||
"state": "on-stack",
|
||||
"this": Object {},
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
@ -505,6 +524,7 @@ exports[`Group renders group with anonymous functions 1`] = `
|
||||
expanded={false}
|
||||
frame={
|
||||
Object {
|
||||
"asyncCause": null,
|
||||
"displayName": "display-1",
|
||||
"generatedLocation": Object {
|
||||
"line": 55,
|
||||
@ -542,6 +562,7 @@ exports[`Group renders group with anonymous functions 1`] = `
|
||||
"relativeUrl": "http://myfile.com/mahscripts.js",
|
||||
"url": "http://myfile.com/mahscripts.js",
|
||||
},
|
||||
"state": "on-stack",
|
||||
"this": Object {},
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
@ -580,6 +601,7 @@ exports[`Group renders group with anonymous functions 2`] = `
|
||||
expanded={true}
|
||||
frame={
|
||||
Object {
|
||||
"asyncCause": null,
|
||||
"displayName": "display-1",
|
||||
"generatedLocation": Object {
|
||||
"line": 55,
|
||||
@ -617,6 +639,7 @@ exports[`Group renders group with anonymous functions 2`] = `
|
||||
"relativeUrl": "http://myfile.com/mahscripts.js",
|
||||
"url": "http://myfile.com/mahscripts.js",
|
||||
},
|
||||
"state": "on-stack",
|
||||
"this": Object {},
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
@ -654,6 +677,7 @@ exports[`Group renders group with anonymous functions 2`] = `
|
||||
displayFullUrl={false}
|
||||
frame={
|
||||
Object {
|
||||
"asyncCause": null,
|
||||
"displayName": "display-1",
|
||||
"generatedLocation": Object {
|
||||
"line": 55,
|
||||
@ -691,6 +715,7 @@ exports[`Group renders group with anonymous functions 2`] = `
|
||||
"relativeUrl": "http://myfile.com/mahscripts.js",
|
||||
"url": "http://myfile.com/mahscripts.js",
|
||||
},
|
||||
"state": "on-stack",
|
||||
"this": Object {},
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
@ -698,10 +723,12 @@ exports[`Group renders group with anonymous functions 2`] = `
|
||||
frameworkGroupingOn={true}
|
||||
hideLocation={true}
|
||||
key="1"
|
||||
panel="webconsole"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={true}
|
||||
selectLocation={[MockFunction]}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"asyncCause": null,
|
||||
"displayName": "foo",
|
||||
"generatedLocation": Object {
|
||||
"line": 4,
|
||||
@ -739,6 +766,7 @@ exports[`Group renders group with anonymous functions 2`] = `
|
||||
"relativeUrl": "url",
|
||||
"url": "url",
|
||||
},
|
||||
"state": "on-stack",
|
||||
"this": Object {},
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
@ -764,6 +792,7 @@ exports[`Group renders group with anonymous functions 2`] = `
|
||||
displayFullUrl={false}
|
||||
frame={
|
||||
Object {
|
||||
"asyncCause": null,
|
||||
"displayName": "display-2",
|
||||
"generatedLocation": Object {
|
||||
"line": 55,
|
||||
@ -801,6 +830,7 @@ exports[`Group renders group with anonymous functions 2`] = `
|
||||
"relativeUrl": "http://myfile.com/back.js",
|
||||
"url": "http://myfile.com/back.js",
|
||||
},
|
||||
"state": "on-stack",
|
||||
"this": Object {},
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
@ -808,10 +838,12 @@ exports[`Group renders group with anonymous functions 2`] = `
|
||||
frameworkGroupingOn={true}
|
||||
hideLocation={true}
|
||||
key="2"
|
||||
panel="webconsole"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={true}
|
||||
selectLocation={[MockFunction]}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"asyncCause": null,
|
||||
"displayName": "foo",
|
||||
"generatedLocation": Object {
|
||||
"line": 4,
|
||||
@ -849,6 +881,7 @@ exports[`Group renders group with anonymous functions 2`] = `
|
||||
"relativeUrl": "url",
|
||||
"url": "url",
|
||||
},
|
||||
"state": "on-stack",
|
||||
"this": Object {},
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
@ -874,6 +907,7 @@ exports[`Group renders group with anonymous functions 2`] = `
|
||||
displayFullUrl={false}
|
||||
frame={
|
||||
Object {
|
||||
"asyncCause": null,
|
||||
"displayName": "display-3",
|
||||
"generatedLocation": Object {
|
||||
"line": 55,
|
||||
@ -911,6 +945,7 @@ exports[`Group renders group with anonymous functions 2`] = `
|
||||
"relativeUrl": "http://myfile.com/back.js",
|
||||
"url": "http://myfile.com/back.js",
|
||||
},
|
||||
"state": "on-stack",
|
||||
"this": Object {},
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
@ -918,10 +953,12 @@ exports[`Group renders group with anonymous functions 2`] = `
|
||||
frameworkGroupingOn={true}
|
||||
hideLocation={true}
|
||||
key="3"
|
||||
panel="webconsole"
|
||||
selectFrame={[MockFunction]}
|
||||
selectable={true}
|
||||
selectLocation={[MockFunction]}
|
||||
selectedFrame={
|
||||
Object {
|
||||
"asyncCause": null,
|
||||
"displayName": "foo",
|
||||
"generatedLocation": Object {
|
||||
"line": 4,
|
||||
@ -959,6 +996,7 @@ exports[`Group renders group with anonymous functions 2`] = `
|
||||
"relativeUrl": "url",
|
||||
"url": "url",
|
||||
},
|
||||
"state": "on-stack",
|
||||
"this": Object {},
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
|
@ -345,7 +345,7 @@ class SecondaryPanes extends Component<Props, State> {
|
||||
return {
|
||||
header: L10N.getStr("callStack.header"),
|
||||
className: "call-stack-pane",
|
||||
component: <Frames />,
|
||||
component: <Frames panel="debugger" />,
|
||||
opened: prefs.callStackVisible,
|
||||
onToggle: opened => {
|
||||
prefs.callStackVisible = opened;
|
||||
|
@ -9,13 +9,10 @@
|
||||
* @module reducers/pending-breakpoints
|
||||
*/
|
||||
|
||||
import { getSourcesByURL } from "./sources";
|
||||
|
||||
import {
|
||||
createPendingBreakpoint,
|
||||
makePendingLocationId,
|
||||
} from "../utils/breakpoint";
|
||||
import { isGenerated } from "../utils/source";
|
||||
|
||||
import type { SourcesState } from "./sources";
|
||||
import type { PendingBreakpoint, Source } from "../types";
|
||||
@ -86,12 +83,6 @@ export function getPendingBreakpointsForSource(
|
||||
state: OuterState,
|
||||
source: Source
|
||||
): PendingBreakpoint[] {
|
||||
const sources = getSourcesByURL(state, source.url);
|
||||
if (sources.length > 1 && isGenerated(source)) {
|
||||
// Don't return pending breakpoints for duplicated generated sources
|
||||
return [];
|
||||
}
|
||||
|
||||
return getPendingBreakpointList(state).filter(pendingBreakpoint => {
|
||||
return (
|
||||
pendingBreakpoint.location.sourceUrl === source.url ||
|
||||
|
@ -259,7 +259,7 @@ export type Frame = {
|
||||
originalVariables?: XScopeVariables,
|
||||
library?: string,
|
||||
index: number,
|
||||
asyncCause?: string,
|
||||
asyncCause: null | string,
|
||||
};
|
||||
|
||||
export type ChromeFrame = {
|
||||
|
@ -181,6 +181,8 @@ function makeMockFrame(
|
||||
scope,
|
||||
this: {},
|
||||
index,
|
||||
asyncCause: null,
|
||||
state: "on-stack",
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@ support-files =
|
||||
!/devtools/client/shared/test/test-actor.js
|
||||
|
||||
[browser_dbg-asm.js]
|
||||
[browser_dbg-asyncstacks.js]
|
||||
[browser_dbg-audiocontext.js]
|
||||
[browser_dbg-async-stepping.js]
|
||||
[browser_dbg-sourcemapped-breakpoint-console.js]
|
||||
|
@ -0,0 +1,19 @@
|
||||
/* 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/>. */
|
||||
|
||||
// Tests that async stacks include awaitees
|
||||
|
||||
add_task(async function() {
|
||||
pushPref("devtools.debugger.features.async-live-stacks", true);
|
||||
const dbg = await initDebugger("doc-frames-async.html");
|
||||
|
||||
invokeInTab("main");
|
||||
await waitForPaused(dbg);
|
||||
|
||||
is(findElement(dbg, "frame", 1).innerText, "sleep\ndoc-frames-async.html:13");
|
||||
is(
|
||||
findElement(dbg, "frame", 2).innerText,
|
||||
"await\nmain\ndoc-frames-async.html:17"
|
||||
);
|
||||
});
|
@ -83,7 +83,7 @@ add_task(async function() {
|
||||
|
||||
invokeInTab("registerWorker");
|
||||
await checkWorkerThreads(dbg, 1);
|
||||
await checkWorkerStatus(dbg, "active");
|
||||
await checkWorkerStatus(dbg, "activated");
|
||||
|
||||
const firstTab = gBrowser.selectedTab;
|
||||
|
||||
@ -143,7 +143,7 @@ add_task(async function() {
|
||||
await waitForBreakpointCount(dbg, 1);
|
||||
await waitForPaused(dbg);
|
||||
assertPausedAtSourceAndLine(dbg, workerSource.id, 2);
|
||||
await checkWorkerStatus(dbg, "evaluating");
|
||||
await checkWorkerStatus(dbg, "parsed");
|
||||
|
||||
await addBreakpoint(dbg, "service-worker.sjs", 19);
|
||||
await resume(dbg);
|
||||
@ -155,7 +155,7 @@ add_task(async function() {
|
||||
await resume(dbg);
|
||||
await waitForPaused(dbg);
|
||||
assertPausedAtSourceAndLine(dbg, workerSource.id, 5);
|
||||
await checkWorkerStatus(dbg, "active");
|
||||
await checkWorkerStatus(dbg, "activating");
|
||||
|
||||
await resume(dbg);
|
||||
invokeInTab("unregisterWorker");
|
||||
|
@ -0,0 +1,21 @@
|
||||
<!-- 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/. -->
|
||||
<html>
|
||||
<head>
|
||||
<title>Frames</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
async function sleep() {
|
||||
await new Promise(r => setTimeout(r, 10));
|
||||
debugger;
|
||||
}
|
||||
|
||||
async function main() {
|
||||
await sleep();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1966,13 +1966,13 @@ Toolbox.prototype = {
|
||||
|
||||
if (
|
||||
!ResponsiveUIManager.isActiveForTab(localTab) ||
|
||||
(await !this.target.actorHasMethod("emulation", "setElementPickerState"))
|
||||
(await !this.target.actorHasMethod("responsive", "setElementPickerState"))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const ui = ResponsiveUIManager.getResponsiveUIForTab(localTab);
|
||||
await ui.emulationFront.setElementPickerState(state);
|
||||
await ui.responsiveFront.setElementPickerState(state);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -168,11 +168,29 @@ class RulesView {
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the content-viewer front and enable the print and color scheme simulation
|
||||
* if they are supported in the current target.
|
||||
*/
|
||||
async initSimulationFeatures() {
|
||||
// In order to query if the emulation actor's print simulation methods are supported,
|
||||
// we have to call the emulation front so that the actor is lazily loaded. This allows
|
||||
// us to use `actorHasMethod`. Please see `getActorDescription` for more information.
|
||||
this.emulationFront = await this.currentTarget.getFront("emulation");
|
||||
// In order to query if the content-viewer actor's print and color simulation methods are
|
||||
// supported, we have to call the content-viewer front so that the actor is lazily loaded.
|
||||
// This allows us to use `actorHasMethod`. Please see `getActorDescription` for more
|
||||
// information.
|
||||
try {
|
||||
this.contentViewerFront = await this.currentTarget.getFront(
|
||||
"contentViewer"
|
||||
);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
// Bug 1606852: For backwards compatibility, we need to get the emulation actor. The ContentViewer
|
||||
// actor is only available in Firefox 73 or newer. We can remove this call when Firefox 73
|
||||
// is on release.
|
||||
if (!this.contentViewerFront) {
|
||||
this.contentViewerFront = await this.currentTarget.getFront("emulation");
|
||||
}
|
||||
|
||||
if (!this.currentTarget.chrome) {
|
||||
this.store.dispatch(updatePrintSimulationHidden(false));
|
||||
@ -183,14 +201,22 @@ class RulesView {
|
||||
// Show the color scheme simulation toggle button if:
|
||||
// - The feature pref is enabled.
|
||||
// - Color scheme simulation is supported for the current target.
|
||||
const isEmulateColorSchemeSupported =
|
||||
(await this.currentTarget.actorHasMethod(
|
||||
"contentViewer",
|
||||
"getEmulatedColorScheme"
|
||||
)) ||
|
||||
// Bug 1606852: We can removed this check when Firefox 73 is on release.
|
||||
(await this.currentTarget.actorHasMethod(
|
||||
"emulation",
|
||||
"getEmulatedColorScheme"
|
||||
));
|
||||
|
||||
if (
|
||||
Services.prefs.getBoolPref(
|
||||
"devtools.inspector.color-scheme-simulation.enabled"
|
||||
) &&
|
||||
(await this.currentTarget.actorHasMethod(
|
||||
"emulation",
|
||||
"getEmulatedColorScheme"
|
||||
))
|
||||
isEmulateColorSchemeSupported
|
||||
) {
|
||||
this.store.dispatch(updateColorSchemeSimulationHidden(false));
|
||||
} else {
|
||||
@ -226,9 +252,9 @@ class RulesView {
|
||||
this.elementStyle = null;
|
||||
}
|
||||
|
||||
if (this.emulationFront) {
|
||||
this.emulationFront.destroy();
|
||||
this.emulationFront = null;
|
||||
if (this.contentViewerFront) {
|
||||
this.contentViewerFront.destroy();
|
||||
this.contentViewerFront = null;
|
||||
}
|
||||
|
||||
this._dummyElement = null;
|
||||
@ -491,10 +517,10 @@ class RulesView {
|
||||
* Handler for toggling color scheme simulation.
|
||||
*/
|
||||
async onToggleColorSchemeSimulation() {
|
||||
const currentState = await this.emulationFront.getEmulatedColorScheme();
|
||||
const currentState = await this.contentViewerFront.getEmulatedColorScheme();
|
||||
const index = COLOR_SCHEMES.indexOf(currentState);
|
||||
const nextState = COLOR_SCHEMES[(index + 1) % COLOR_SCHEMES.length];
|
||||
await this.emulationFront.setEmulatedColorScheme(nextState);
|
||||
await this.contentViewerFront.setEmulatedColorScheme(nextState);
|
||||
await this.updateElementStyle();
|
||||
}
|
||||
|
||||
@ -502,12 +528,12 @@ class RulesView {
|
||||
* Handler for toggling print media simulation.
|
||||
*/
|
||||
async onTogglePrintSimulation() {
|
||||
const enabled = await this.emulationFront.getIsPrintSimulationEnabled();
|
||||
const enabled = await this.contentViewerFront.getIsPrintSimulationEnabled();
|
||||
|
||||
if (!enabled) {
|
||||
await this.emulationFront.startPrintMediaSimulation();
|
||||
await this.contentViewerFront.startPrintMediaSimulation();
|
||||
} else {
|
||||
await this.emulationFront.stopPrintMediaSimulation(false);
|
||||
await this.contentViewerFront.stopPrintMediaSimulation(false);
|
||||
}
|
||||
|
||||
await this.updateElementStyle();
|
||||
|
@ -288,10 +288,6 @@ CssRuleView.prototype = {
|
||||
return this._dummyElement;
|
||||
},
|
||||
|
||||
get emulationFront() {
|
||||
return this._emulationFront;
|
||||
},
|
||||
|
||||
// Get the highlighters overlay from the Inspector.
|
||||
get highlighters() {
|
||||
if (!this._highlighters) {
|
||||
@ -405,15 +401,28 @@ CssRuleView.prototype = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Initializes the emulation front and enable the print and color scheme simulation
|
||||
* Initializes the content-viewer front and enable the print and color scheme simulation
|
||||
* if they are supported in the current target.
|
||||
*/
|
||||
async _initSimulationFeatures() {
|
||||
// In order to query if the emulation actor's print and color simulation methods are
|
||||
// supported, we have to call the emulation front so that the actor is lazily loaded.
|
||||
// In order to query if the content-viewer actor's print and color simulation methods are
|
||||
// supported, we have to call the content-viewer front so that the actor is lazily loaded.
|
||||
// This allows us to use `actorHasMethod`. Please see `getActorDescription` for more
|
||||
// information.
|
||||
this._emulationFront = await this.currentTarget.getFront("emulation");
|
||||
try {
|
||||
this.contentViewerFront = await this.currentTarget.getFront(
|
||||
"contentViewer"
|
||||
);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
// Bug 1606852: For backwards compatibility, we need to get the emulation actor. The ContentViewer
|
||||
// actor is only available in Firefox 73 or newer. We can remove this call when Firefox 73
|
||||
// is on release.
|
||||
if (!this.contentViewerFront) {
|
||||
this.contentViewerFront = await this.currentTarget.getFront("emulation");
|
||||
}
|
||||
|
||||
if (!this.currentTarget.chrome) {
|
||||
this.printSimulationButton.removeAttribute("hidden");
|
||||
@ -426,14 +435,22 @@ CssRuleView.prototype = {
|
||||
// Show the color scheme simulation toggle button if:
|
||||
// - The feature pref is enabled.
|
||||
// - Color scheme simulation is supported for the current target.
|
||||
const isEmulateColorSchemeSupported =
|
||||
(await this.currentTarget.actorHasMethod(
|
||||
"contentViewer",
|
||||
"getEmulatedColorScheme"
|
||||
)) ||
|
||||
// Bug 1606852: We can removed this check when Firefox 73 is on release.
|
||||
(await this.currentTarget.actorHasMethod(
|
||||
"emulation",
|
||||
"getEmulatedColorScheme"
|
||||
));
|
||||
|
||||
if (
|
||||
Services.prefs.getBoolPref(
|
||||
"devtools.inspector.color-scheme-simulation.enabled"
|
||||
) &&
|
||||
(await this.currentTarget.actorHasMethod(
|
||||
"emulation",
|
||||
"getEmulatedColorScheme"
|
||||
))
|
||||
isEmulateColorSchemeSupported
|
||||
) {
|
||||
this.colorSchemeSimulationButton.removeAttribute("hidden");
|
||||
this.colorSchemeSimulationButton.addEventListener(
|
||||
@ -847,7 +864,7 @@ CssRuleView.prototype = {
|
||||
}
|
||||
|
||||
// Clean-up for print simulation.
|
||||
if (this._emulationFront) {
|
||||
if (this.contentViewerFront) {
|
||||
this.colorSchemeSimulationButton.removeEventListener(
|
||||
"click",
|
||||
this._onToggleColorSchemeSimulation
|
||||
@ -857,11 +874,11 @@ CssRuleView.prototype = {
|
||||
this._onTogglePrintSimulation
|
||||
);
|
||||
|
||||
this._emulationFront.destroy();
|
||||
this.contentViewerFront.destroy();
|
||||
|
||||
this.colorSchemeSimulationButton = null;
|
||||
this.printSimulationButton = null;
|
||||
this._emulationFront = null;
|
||||
this.contentViewerFront = null;
|
||||
}
|
||||
|
||||
this.tooltips.destroy();
|
||||
@ -1739,7 +1756,7 @@ CssRuleView.prototype = {
|
||||
},
|
||||
|
||||
async _onToggleColorSchemeSimulation() {
|
||||
const currentState = await this.emulationFront.getEmulatedColorScheme();
|
||||
const currentState = await this.contentViewerFront.getEmulatedColorScheme();
|
||||
const index = COLOR_SCHEMES.indexOf(currentState);
|
||||
const nextState = COLOR_SCHEMES[(index + 1) % COLOR_SCHEMES.length];
|
||||
|
||||
@ -1749,19 +1766,19 @@ CssRuleView.prototype = {
|
||||
this.colorSchemeSimulationButton.removeAttribute("state");
|
||||
}
|
||||
|
||||
await this.emulationFront.setEmulatedColorScheme(nextState);
|
||||
await this.contentViewerFront.setEmulatedColorScheme(nextState);
|
||||
this.refreshPanel();
|
||||
},
|
||||
|
||||
async _onTogglePrintSimulation() {
|
||||
const enabled = await this.emulationFront.getIsPrintSimulationEnabled();
|
||||
const enabled = await this.contentViewerFront.getIsPrintSimulationEnabled();
|
||||
|
||||
if (!enabled) {
|
||||
this.printSimulationButton.classList.add("checked");
|
||||
await this.emulationFront.startPrintMediaSimulation();
|
||||
await this.contentViewerFront.startPrintMediaSimulation();
|
||||
} else {
|
||||
this.printSimulationButton.classList.remove("checked");
|
||||
await this.emulationFront.stopPrintMediaSimulation(false);
|
||||
await this.contentViewerFront.stopPrintMediaSimulation(false);
|
||||
}
|
||||
|
||||
// Refresh the current element's rules in the panel.
|
||||
|
@ -151,17 +151,17 @@ exports.menuitems = [
|
||||
// Similarly, enable them when the color picker is done picking.
|
||||
if (
|
||||
ResponsiveUIManager.isActiveForTab(target.localTab) &&
|
||||
target.actorHasMethod("emulation", "setElementPickerState")
|
||||
target.actorHasMethod("responsive", "setElementPickerState")
|
||||
) {
|
||||
const ui = ResponsiveUIManager.getResponsiveUIForTab(target.localTab);
|
||||
await ui.emulationFront.setElementPickerState(true);
|
||||
await ui.responsiveFront.setElementPickerState(true);
|
||||
|
||||
inspectorFront.once("color-picked", async () => {
|
||||
await ui.emulationFront.setElementPickerState(false);
|
||||
await ui.responsiveFront.setElementPickerState(false);
|
||||
});
|
||||
|
||||
inspectorFront.once("color-pick-canceled", async () => {
|
||||
await ui.emulationFront.setElementPickerState(false);
|
||||
await ui.responsiveFront.setElementPickerState(false);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -83,8 +83,19 @@ class FirefoxConnector {
|
||||
this.tabTarget.on("will-navigate", this.willNavigate);
|
||||
this.tabTarget.on("navigate", this.navigate);
|
||||
|
||||
// Initialize Emulation front for network throttling.
|
||||
this.emulationFront = await this.tabTarget.getFront("emulation");
|
||||
// Initialize Responsive Emulation front for network throttling.
|
||||
try {
|
||||
this.responsiveFront = await this.tabTarget.getFront("responsive");
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
// Bug 1606852: For backwards compatibility, we need to get the emulation actor. The Responsive
|
||||
// actor is only available in Firefox 73 or newer. We can remove this call when Firefox 73
|
||||
// is on release.
|
||||
if (!this.responsiveFront) {
|
||||
this.responsiveFront = await this.tabTarget.getFront("emulation");
|
||||
}
|
||||
}
|
||||
|
||||
// Displaying cache events is only intended for the UI panel.
|
||||
@ -100,9 +111,9 @@ class FirefoxConnector {
|
||||
|
||||
this.removeListeners();
|
||||
|
||||
if (this.emulationFront) {
|
||||
this.emulationFront.destroy();
|
||||
this.emulationFront = null;
|
||||
if (this.responsiveFront) {
|
||||
this.responsiveFront.destroy();
|
||||
this.responsiveFront = null;
|
||||
}
|
||||
|
||||
if (this.webSocketFront) {
|
||||
@ -474,11 +485,11 @@ class FirefoxConnector {
|
||||
|
||||
async updateNetworkThrottling(enabled, profile) {
|
||||
if (!enabled) {
|
||||
await this.emulationFront.clearNetworkThrottling();
|
||||
await this.responsiveFront.clearNetworkThrottling();
|
||||
} else {
|
||||
const data = throttlingProfiles.find(({ id }) => id == profile);
|
||||
const { download, upload, latency } = data;
|
||||
await this.emulationFront.setNetworkThrottling({
|
||||
await this.responsiveFront.setNetworkThrottling({
|
||||
downloadThroughput: download,
|
||||
uploadThroughput: upload,
|
||||
latency,
|
||||
|
@ -42,7 +42,7 @@ function testNetworkThrottlingSelectorLabel(ui, expected) {
|
||||
}
|
||||
|
||||
var testNetworkThrottlingState = async function(ui, expected) {
|
||||
const state = await ui.emulationFront.getNetworkThrottling();
|
||||
const state = await ui.responsiveFront.getNetworkThrottling();
|
||||
Assert.deepEqual(
|
||||
state,
|
||||
expected,
|
||||
|
@ -543,7 +543,7 @@ async function testTouchEventsOverride(ui, expected) {
|
||||
const { document } = ui.toolWindow;
|
||||
const touchButton = document.getElementById("touch-simulation-button");
|
||||
|
||||
const flag = await ui.emulationFront.getTouchEventsOverride();
|
||||
const flag = await ui.responsiveFront.getTouchEventsOverride();
|
||||
is(
|
||||
flag === Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_ENABLED,
|
||||
expected,
|
||||
|
@ -206,7 +206,7 @@ class ResponsiveUI {
|
||||
await message.request(this.toolWindow, "start-frame-script");
|
||||
}
|
||||
|
||||
// Get the protocol ready to speak with emulation actor
|
||||
// Get the protocol ready to speak with responsive emulation actor
|
||||
debug("Wait until RDP server connect");
|
||||
await this.connectToServer();
|
||||
|
||||
@ -214,7 +214,7 @@ class ResponsiveUI {
|
||||
await this.restoreState();
|
||||
|
||||
if (this.isBrowserUIEnabled) {
|
||||
await this.emulationFront.setDocumentInRDMPane(true);
|
||||
await this.responsiveFront.setDocumentInRDMPane(true);
|
||||
}
|
||||
|
||||
if (!this.isBrowserUIEnabled) {
|
||||
@ -316,7 +316,7 @@ class ResponsiveUI {
|
||||
}
|
||||
|
||||
if (this.isBrowserUIEnabled) {
|
||||
await this.emulationFront.setDocumentInRDMPane(false);
|
||||
await this.responsiveFront.setDocumentInRDMPane(false);
|
||||
}
|
||||
|
||||
this.tab.removeEventListener("TabClose", this);
|
||||
@ -368,14 +368,14 @@ class ResponsiveUI {
|
||||
this.toolWindow = null;
|
||||
this.swap = null;
|
||||
|
||||
// Close the debugger client used to speak with emulation actor.
|
||||
// Close the debugger client used to speak with responsive emulation actor.
|
||||
// The actor handles clearing any overrides itself, so it's not necessary to clear
|
||||
// anything on shutdown client side.
|
||||
const clientClosed = this.client.close();
|
||||
if (!isTabContentDestroying) {
|
||||
await clientClosed;
|
||||
}
|
||||
this.client = this.emulationFront = null;
|
||||
this.client = this.responsiveFront = null;
|
||||
|
||||
if (!this.isBrowserUIEnabled && !isWindowClosing) {
|
||||
// Undo the swap and return the content back to a normal tab
|
||||
@ -395,11 +395,11 @@ class ResponsiveUI {
|
||||
this.client = new DebuggerClient(DebuggerServer.connectPipe());
|
||||
await this.client.connect();
|
||||
const targetFront = await this.client.mainRoot.getTab();
|
||||
this.emulationFront = await targetFront.getFront("emulation");
|
||||
this.responsiveFront = await targetFront.getFront("responsive");
|
||||
}
|
||||
|
||||
/**
|
||||
* Show one-time notification about reloads for emulation.
|
||||
* Show one-time notification about reloads for responsive emulation.
|
||||
*/
|
||||
showReloadNotification() {
|
||||
if (Services.prefs.getBoolPref(RELOAD_NOTIFICATION_PREF, false)) {
|
||||
@ -597,12 +597,12 @@ class ResponsiveUI {
|
||||
async onScreenshot() {
|
||||
const targetFront = await this.client.mainRoot.getTab();
|
||||
const captureScreenshotSupported = await targetFront.actorHasMethod(
|
||||
"emulation",
|
||||
"responsive",
|
||||
"captureScreenshot"
|
||||
);
|
||||
|
||||
if (captureScreenshotSupported) {
|
||||
const data = await this.emulationFront.captureScreenshot();
|
||||
const data = await this.responsiveFront.captureScreenshot();
|
||||
await saveScreenshot(this.browserWindow, {}, data);
|
||||
|
||||
message.post(this.rdmFrame.contentWindow, "screenshot-captured");
|
||||
@ -698,10 +698,10 @@ class ResponsiveUI {
|
||||
*/
|
||||
async updateDPPX(dppx) {
|
||||
if (!dppx) {
|
||||
await this.emulationFront.clearDPPXOverride();
|
||||
await this.responsiveFront.clearDPPXOverride();
|
||||
return false;
|
||||
}
|
||||
await this.emulationFront.setDPPXOverride(dppx);
|
||||
await this.responsiveFront.setDPPXOverride(dppx);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -714,12 +714,12 @@ class ResponsiveUI {
|
||||
*/
|
||||
async updateNetworkThrottling(enabled, profile) {
|
||||
if (!enabled) {
|
||||
await this.emulationFront.clearNetworkThrottling();
|
||||
await this.responsiveFront.clearNetworkThrottling();
|
||||
return false;
|
||||
}
|
||||
const data = throttlingProfiles.find(({ id }) => id == profile);
|
||||
const { download, upload, latency } = data;
|
||||
await this.emulationFront.setNetworkThrottling({
|
||||
await this.responsiveFront.setNetworkThrottling({
|
||||
downloadThroughput: download,
|
||||
uploadThroughput: upload,
|
||||
latency,
|
||||
@ -735,9 +735,9 @@ class ResponsiveUI {
|
||||
*/
|
||||
updateUserAgent(userAgent) {
|
||||
if (!userAgent) {
|
||||
return this.emulationFront.clearUserAgentOverride();
|
||||
return this.responsiveFront.clearUserAgentOverride();
|
||||
}
|
||||
return this.emulationFront.setUserAgentOverride(userAgent);
|
||||
return this.responsiveFront.setUserAgentOverride(userAgent);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -758,18 +758,18 @@ class ResponsiveUI {
|
||||
false
|
||||
);
|
||||
|
||||
reloadNeeded = await this.emulationFront.setTouchEventsOverride(
|
||||
reloadNeeded = await this.responsiveFront.setTouchEventsOverride(
|
||||
Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_ENABLED
|
||||
);
|
||||
|
||||
if (metaViewportEnabled) {
|
||||
reloadNeeded |= await this.emulationFront.setMetaViewportOverride(
|
||||
reloadNeeded |= await this.responsiveFront.setMetaViewportOverride(
|
||||
Ci.nsIDocShell.META_VIEWPORT_OVERRIDE_ENABLED
|
||||
);
|
||||
}
|
||||
} else {
|
||||
reloadNeeded = await this.emulationFront.clearTouchEventsOverride();
|
||||
reloadNeeded |= await this.emulationFront.clearMetaViewportOverride();
|
||||
reloadNeeded = await this.responsiveFront.clearTouchEventsOverride();
|
||||
reloadNeeded |= await this.responsiveFront.clearMetaViewportOverride();
|
||||
}
|
||||
return reloadNeeded;
|
||||
}
|
||||
@ -791,13 +791,13 @@ class ResponsiveUI {
|
||||
async updateScreenOrientation(type, angle, isViewportRotated = false) {
|
||||
const targetFront = await this.client.mainRoot.getTab();
|
||||
const simulateOrientationChangeSupported = await targetFront.actorHasMethod(
|
||||
"emulation",
|
||||
"responsive",
|
||||
"simulateScreenOrientationChange"
|
||||
);
|
||||
|
||||
// Ensure that simulateScreenOrientationChange is supported.
|
||||
if (simulateOrientationChangeSupported) {
|
||||
await this.emulationFront.simulateScreenOrientationChange(
|
||||
await this.responsiveFront.simulateScreenOrientationChange(
|
||||
type,
|
||||
angle,
|
||||
isViewportRotated
|
||||
|
@ -261,7 +261,7 @@ class SmartTrace extends Component {
|
||||
disableContextMenu: true,
|
||||
frameworkGroupingOn: true,
|
||||
displayFullUrl: !this.state || !this.state.isSourceMapped,
|
||||
selectable: true,
|
||||
panel: "webconsole",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -3179,7 +3179,7 @@ function ErrorRep(props) {
|
||||
const mode = props.mode;
|
||||
let name;
|
||||
|
||||
if (preview && preview.name && preview.kind) {
|
||||
if (preview && preview.name && typeof preview.name === "string" && preview.kind) {
|
||||
switch (preview.kind) {
|
||||
case "Error":
|
||||
name = preview.name;
|
||||
@ -3198,7 +3198,7 @@ function ErrorRep(props) {
|
||||
|
||||
const content = [];
|
||||
|
||||
if (mode === MODE.TINY) {
|
||||
if (mode === MODE.TINY || typeof preview.message !== "string") {
|
||||
content.push(name);
|
||||
} else {
|
||||
content.push(`${name}: "${preview.message}"`);
|
||||
|
@ -16,6 +16,8 @@ const TEST_URI =
|
||||
const STUB_FILE = "pageError.js";
|
||||
|
||||
add_task(async function() {
|
||||
await pushPref("javascript.options.asyncstack", true);
|
||||
|
||||
const isStubsUpdate = env.get(STUBS_UPDATE_ENV) == "true";
|
||||
info(`${isStubsUpdate ? "Update" : "Check"} ${STUB_FILE}`);
|
||||
|
||||
|
@ -11,6 +11,7 @@ const TEST_URI =
|
||||
"test/browser/test-error-worker.html";
|
||||
|
||||
add_task(async function() {
|
||||
await pushPref("javascript.options.asyncstack", true);
|
||||
const hud = await openNewTabAndConsole(TEST_URI);
|
||||
|
||||
await checkMessageStack(hud, "hello", [13, 4, 3]);
|
||||
|
@ -495,7 +495,7 @@ class WebConsoleUI {
|
||||
}
|
||||
|
||||
getLongString(grip) {
|
||||
this.getProxy().webConsoleFront.getString(grip);
|
||||
return this.getProxy().webConsoleFront.getString(grip);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -33,6 +33,8 @@ loader.lazyRequireGetter(
|
||||
* A subtle aspect of the code below is that all get* methods must return non-undefined
|
||||
* values, so that the absence of a previous value can be distinguished from the value for
|
||||
* "no override" for each of the properties.
|
||||
*
|
||||
* Bug 1606852: Delete this file when Firefox 73 is on release.
|
||||
*/
|
||||
const EmulationActor = protocol.ActorClassWithSpec(emulationSpec, {
|
||||
initialize(conn, targetActor) {
|
||||
|
132
devtools/server/actors/emulation/content-viewer.js
Normal file
132
devtools/server/actors/emulation/content-viewer.js
Normal file
@ -0,0 +1,132 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { Ci } = require("chrome");
|
||||
const protocol = require("devtools/shared/protocol");
|
||||
const { contentViewerSpec } = require("devtools/shared/specs/content-viewer");
|
||||
|
||||
/**
|
||||
* This actor emulates various browser content environments by using methods available
|
||||
* on the ContentViewer exposed by the platform.
|
||||
*/
|
||||
const ContentViewerActor = protocol.ActorClassWithSpec(contentViewerSpec, {
|
||||
initialize(conn, targetActor) {
|
||||
protocol.Actor.prototype.initialize.call(this, conn);
|
||||
this.targetActor = targetActor;
|
||||
this.docShell = targetActor.docShell;
|
||||
|
||||
this.onWillNavigate = this.onWillNavigate.bind(this);
|
||||
this.onWindowReady = this.onWindowReady.bind(this);
|
||||
|
||||
this.targetActor.on("will-navigate", this.onWillNavigate);
|
||||
this.targetActor.on("window-ready", this.onWindowReady);
|
||||
},
|
||||
|
||||
destroy() {
|
||||
this.stopPrintMediaSimulation();
|
||||
this.setEmulatedColorScheme();
|
||||
|
||||
this.targetActor.off("will-navigate", this.onWillNavigate);
|
||||
this.targetActor.off("window-ready", this.onWindowReady);
|
||||
|
||||
this.targetActor = null;
|
||||
this.docShell = null;
|
||||
|
||||
protocol.Actor.prototype.destroy.call(this);
|
||||
},
|
||||
|
||||
onWillNavigate({ isTopLevel }) {
|
||||
// Make sure that print simulation is stopped before navigating to another page. We
|
||||
// need to do this since the browser will cache the last state of the page in its
|
||||
// session history.
|
||||
if (this._printSimulationEnabled && isTopLevel) {
|
||||
this.stopPrintMediaSimulation(true);
|
||||
}
|
||||
},
|
||||
|
||||
onWindowReady({ isTopLevel }) {
|
||||
// Since `emulateMedium` only works for the current page, we need to ensure persistent
|
||||
// print simulation for when the user navigates to a new page while its enabled.
|
||||
// To do this, we need to tell the page to begin print simulation before the DOM
|
||||
// content is available to the user:
|
||||
if (this._printSimulationEnabled && isTopLevel) {
|
||||
this.startPrintMediaSimulation();
|
||||
}
|
||||
},
|
||||
|
||||
/* Color scheme simulation */
|
||||
|
||||
/**
|
||||
* Returns the currently emulated color scheme.
|
||||
*/
|
||||
getEmulatedColorScheme() {
|
||||
return this._emulatedColorScheme;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the currently emulated color scheme or if an invalid value is given,
|
||||
* the override is cleared.
|
||||
*/
|
||||
setEmulatedColorScheme(scheme = null) {
|
||||
if (this._emulatedColorScheme === scheme) {
|
||||
return;
|
||||
}
|
||||
|
||||
let internalColorScheme;
|
||||
switch (scheme) {
|
||||
case "light":
|
||||
internalColorScheme = Ci.nsIContentViewer.PREFERS_COLOR_SCHEME_LIGHT;
|
||||
break;
|
||||
case "dark":
|
||||
internalColorScheme = Ci.nsIContentViewer.PREFERS_COLOR_SCHEME_DARK;
|
||||
break;
|
||||
case "no-preference":
|
||||
internalColorScheme =
|
||||
Ci.nsIContentViewer.PREFERS_COLOR_SCHEME_NO_PREFERENCE;
|
||||
break;
|
||||
default:
|
||||
internalColorScheme = Ci.nsIContentViewer.PREFERS_COLOR_SCHEME_NONE;
|
||||
}
|
||||
|
||||
this._emulatedColorScheme = scheme;
|
||||
this.docShell.contentViewer.emulatePrefersColorScheme(internalColorScheme);
|
||||
},
|
||||
|
||||
// The current emulated color scheme value. It's possible values are listed in the
|
||||
// COLOR_SCHEMES constant in devtools/client/inspector/rules/constants.
|
||||
_emulatedColorScheme: null,
|
||||
|
||||
/* Simulating print media for the page */
|
||||
|
||||
_printSimulationEnabled: false,
|
||||
|
||||
getIsPrintSimulationEnabled() {
|
||||
return this._printSimulationEnabled;
|
||||
},
|
||||
|
||||
async startPrintMediaSimulation() {
|
||||
this._printSimulationEnabled = true;
|
||||
this.targetActor.docShell.contentViewer.emulateMedium("print");
|
||||
},
|
||||
|
||||
/**
|
||||
* Stop simulating print media for the current page.
|
||||
*
|
||||
* @param {Boolean} state
|
||||
* Whether or not to set _printSimulationEnabled to false. If true, we want to
|
||||
* stop simulation print media for the current page but NOT set
|
||||
* _printSimulationEnabled to false. We do this specifically for the
|
||||
* "will-navigate" event where we still want to continue simulating print when
|
||||
* navigating to the next page. Defaults to false, meaning we want to completely
|
||||
* stop print simulation.
|
||||
*/
|
||||
async stopPrintMediaSimulation(state = false) {
|
||||
this._printSimulationEnabled = state;
|
||||
this.targetActor.docShell.contentViewer.stopEmulatingMedium();
|
||||
},
|
||||
});
|
||||
|
||||
exports.ContentViewerActor = ContentViewerActor;
|
@ -5,5 +5,7 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DevToolsModules(
|
||||
'content-viewer.js',
|
||||
'responsive.js',
|
||||
'touch-simulator.js',
|
||||
)
|
||||
|
367
devtools/server/actors/emulation/responsive.js
Normal file
367
devtools/server/actors/emulation/responsive.js
Normal file
@ -0,0 +1,367 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { Ci } = require("chrome");
|
||||
const protocol = require("devtools/shared/protocol");
|
||||
const { responsiveSpec } = require("devtools/shared/specs/responsive");
|
||||
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
"ScreenshotActor",
|
||||
"devtools/server/actors/screenshot",
|
||||
true
|
||||
);
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
"TouchSimulator",
|
||||
"devtools/server/actors/emulation/touch-simulator",
|
||||
true
|
||||
);
|
||||
|
||||
/**
|
||||
* This actor overrides various browser features to simulate different environments to
|
||||
* test how pages perform under various conditions.
|
||||
*
|
||||
* The design below, which saves the previous value of each property before setting, is
|
||||
* needed because it's possible to have multiple copies of this actor for a single page.
|
||||
* When some instance of this actor changes a property, we want it to be able to restore
|
||||
* that property to the way it was found before the change.
|
||||
*
|
||||
* A subtle aspect of the code below is that all get* methods must return non-undefined
|
||||
* values, so that the absence of a previous value can be distinguished from the value for
|
||||
* "no override" for each of the properties.
|
||||
*/
|
||||
const ResponsiveActor = protocol.ActorClassWithSpec(responsiveSpec, {
|
||||
initialize(conn, targetActor) {
|
||||
protocol.Actor.prototype.initialize.call(this, conn);
|
||||
this.targetActor = targetActor;
|
||||
this.docShell = targetActor.docShell;
|
||||
},
|
||||
|
||||
destroy() {
|
||||
this.clearDPPXOverride();
|
||||
this.clearNetworkThrottling();
|
||||
this.clearTouchEventsOverride();
|
||||
this.clearMetaViewportOverride();
|
||||
this.clearUserAgentOverride();
|
||||
|
||||
this.targetActor = null;
|
||||
this.docShell = null;
|
||||
this._screenshotActor = null;
|
||||
this._touchSimulator = null;
|
||||
|
||||
protocol.Actor.prototype.destroy.call(this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieve the console actor for this tab. This allows us to expose network throttling
|
||||
* as part of emulation settings, even though it's internally connected to the network
|
||||
* monitor, which for historical reasons is part of the console actor.
|
||||
*/
|
||||
get _consoleActor() {
|
||||
if (this.targetActor.exited || !this.targetActor.actorID) {
|
||||
return null;
|
||||
}
|
||||
const form = this.targetActor.form();
|
||||
return this.conn._getOrCreateActor(form.consoleActor);
|
||||
},
|
||||
|
||||
get screenshotActor() {
|
||||
if (!this._screenshotActor) {
|
||||
this._screenshotActor = new ScreenshotActor(this.conn, this.targetActor);
|
||||
this.manage(this._screenshotActor);
|
||||
}
|
||||
|
||||
return this._screenshotActor;
|
||||
},
|
||||
|
||||
get touchSimulator() {
|
||||
if (!this._touchSimulator) {
|
||||
this._touchSimulator = new TouchSimulator(
|
||||
this.targetActor.chromeEventHandler
|
||||
);
|
||||
}
|
||||
|
||||
return this._touchSimulator;
|
||||
},
|
||||
|
||||
get win() {
|
||||
return this.docShell.chromeEventHandler.ownerGlobal;
|
||||
},
|
||||
|
||||
/* DPPX override */
|
||||
|
||||
_previousDPPXOverride: undefined,
|
||||
|
||||
setDPPXOverride(dppx) {
|
||||
if (this.getDPPXOverride() === dppx) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this._previousDPPXOverride === undefined) {
|
||||
this._previousDPPXOverride = this.getDPPXOverride();
|
||||
}
|
||||
|
||||
this.docShell.contentViewer.overrideDPPX = dppx;
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
getDPPXOverride() {
|
||||
return this.docShell.contentViewer.overrideDPPX;
|
||||
},
|
||||
|
||||
clearDPPXOverride() {
|
||||
if (this._previousDPPXOverride !== undefined) {
|
||||
return this.setDPPXOverride(this._previousDPPXOverride);
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
/* Network Throttling */
|
||||
|
||||
_previousNetworkThrottling: undefined,
|
||||
|
||||
/**
|
||||
* Transform the RDP format into the internal format and then set network throttling.
|
||||
*/
|
||||
setNetworkThrottling({ downloadThroughput, uploadThroughput, latency }) {
|
||||
const throttleData = {
|
||||
latencyMean: latency,
|
||||
latencyMax: latency,
|
||||
downloadBPSMean: downloadThroughput,
|
||||
downloadBPSMax: downloadThroughput,
|
||||
uploadBPSMean: uploadThroughput,
|
||||
uploadBPSMax: uploadThroughput,
|
||||
};
|
||||
return this._setNetworkThrottling(throttleData);
|
||||
},
|
||||
|
||||
_setNetworkThrottling(throttleData) {
|
||||
const current = this._getNetworkThrottling();
|
||||
// Check if they are both objects or both null
|
||||
let match = throttleData == current;
|
||||
// If both objects, check all entries
|
||||
if (match && current && throttleData) {
|
||||
match = Object.entries(current).every(([k, v]) => {
|
||||
return throttleData[k] === v;
|
||||
});
|
||||
}
|
||||
if (match) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this._previousNetworkThrottling === undefined) {
|
||||
this._previousNetworkThrottling = current;
|
||||
}
|
||||
|
||||
const consoleActor = this._consoleActor;
|
||||
if (!consoleActor) {
|
||||
return false;
|
||||
}
|
||||
consoleActor.startListeners(["NetworkActivity"]);
|
||||
consoleActor.setPreferences({
|
||||
"NetworkMonitor.throttleData": throttleData,
|
||||
});
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get network throttling and then transform the internal format into the RDP format.
|
||||
*/
|
||||
getNetworkThrottling() {
|
||||
const throttleData = this._getNetworkThrottling();
|
||||
if (!throttleData) {
|
||||
return null;
|
||||
}
|
||||
const { downloadBPSMax, uploadBPSMax, latencyMax } = throttleData;
|
||||
return {
|
||||
downloadThroughput: downloadBPSMax,
|
||||
uploadThroughput: uploadBPSMax,
|
||||
latency: latencyMax,
|
||||
};
|
||||
},
|
||||
|
||||
_getNetworkThrottling() {
|
||||
const consoleActor = this._consoleActor;
|
||||
if (!consoleActor) {
|
||||
return null;
|
||||
}
|
||||
const prefs = consoleActor.getPreferences(["NetworkMonitor.throttleData"]);
|
||||
return prefs.preferences["NetworkMonitor.throttleData"] || null;
|
||||
},
|
||||
|
||||
clearNetworkThrottling() {
|
||||
if (this._previousNetworkThrottling !== undefined) {
|
||||
return this._setNetworkThrottling(this._previousNetworkThrottling);
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
/* Touch events override */
|
||||
|
||||
_previousTouchEventsOverride: undefined,
|
||||
|
||||
/**
|
||||
* Set the current element picker state.
|
||||
*
|
||||
* True means the element picker is currently active and we should not be emulating
|
||||
* touch events.
|
||||
* False means the element picker is not active and it is ok to emulate touch events.
|
||||
*
|
||||
* This actor method is meant to be called by the DevTools front-end. The reason for
|
||||
* this is the following:
|
||||
* RDM is the only current consumer of the touch simulator. RDM instantiates this actor
|
||||
* on its own, whether or not the Toolbox is opened. That means it does so in its own
|
||||
* Debugger Server instance.
|
||||
* When the Toolbox is running, it uses a different DebuggerServer. Therefore, it is not
|
||||
* possible for the touch simulator to know whether the picker is active or not. This
|
||||
* state has to be sent by the client code of the Toolbox to this actor.
|
||||
* If a future use case arises where we want to use the touch simulator from the Toolbox
|
||||
* too, then we could add code in here to detect the picker mode as described in
|
||||
* https://bugzilla.mozilla.org/show_bug.cgi?id=1409085#c3
|
||||
* @param {Boolean} state
|
||||
*/
|
||||
setElementPickerState(state) {
|
||||
this.touchSimulator.setElementPickerState(state);
|
||||
},
|
||||
|
||||
setTouchEventsOverride(flag) {
|
||||
if (this.getTouchEventsOverride() == flag) {
|
||||
return false;
|
||||
}
|
||||
if (this._previousTouchEventsOverride === undefined) {
|
||||
this._previousTouchEventsOverride = this.getTouchEventsOverride();
|
||||
}
|
||||
|
||||
// Start or stop the touch simulator depending on the override flag
|
||||
if (flag == Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_ENABLED) {
|
||||
this.touchSimulator.start();
|
||||
} else {
|
||||
this.touchSimulator.stop();
|
||||
}
|
||||
|
||||
this.docShell.touchEventsOverride = flag;
|
||||
return true;
|
||||
},
|
||||
|
||||
getTouchEventsOverride() {
|
||||
return this.docShell.touchEventsOverride;
|
||||
},
|
||||
|
||||
clearTouchEventsOverride() {
|
||||
if (this._previousTouchEventsOverride !== undefined) {
|
||||
return this.setTouchEventsOverride(this._previousTouchEventsOverride);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
/* Meta viewport override */
|
||||
|
||||
_previousMetaViewportOverride: undefined,
|
||||
|
||||
setMetaViewportOverride(flag) {
|
||||
if (this.getMetaViewportOverride() == flag) {
|
||||
return false;
|
||||
}
|
||||
if (this._previousMetaViewportOverride === undefined) {
|
||||
this._previousMetaViewportOverride = this.getMetaViewportOverride();
|
||||
}
|
||||
|
||||
this.docShell.metaViewportOverride = flag;
|
||||
return true;
|
||||
},
|
||||
|
||||
getMetaViewportOverride() {
|
||||
return this.docShell.metaViewportOverride;
|
||||
},
|
||||
|
||||
clearMetaViewportOverride() {
|
||||
if (this._previousMetaViewportOverride !== undefined) {
|
||||
return this.setMetaViewportOverride(this._previousMetaViewportOverride);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
/* User agent override */
|
||||
|
||||
_previousUserAgentOverride: undefined,
|
||||
|
||||
setUserAgentOverride(userAgent) {
|
||||
if (this.getUserAgentOverride() == userAgent) {
|
||||
return false;
|
||||
}
|
||||
if (this._previousUserAgentOverride === undefined) {
|
||||
this._previousUserAgentOverride = this.getUserAgentOverride();
|
||||
}
|
||||
this.docShell.customUserAgent = userAgent;
|
||||
return true;
|
||||
},
|
||||
|
||||
getUserAgentOverride() {
|
||||
return this.docShell.customUserAgent;
|
||||
},
|
||||
|
||||
clearUserAgentOverride() {
|
||||
if (this._previousUserAgentOverride !== undefined) {
|
||||
return this.setUserAgentOverride(this._previousUserAgentOverride);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
setScreenOrientation(type, angle) {
|
||||
if (
|
||||
this.win.screen.orientation.angle !== angle ||
|
||||
this.win.screen.orientation.type !== type
|
||||
) {
|
||||
this.docShell.browsingContext.setRDMPaneOrientation(type, angle);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Simulates the "orientationchange" event when device screen is rotated.
|
||||
*
|
||||
* @param {String} type
|
||||
* The orientation type of the rotated device.
|
||||
* @param {Number} angle
|
||||
* The rotated angle of the device.
|
||||
* @param {Boolean} isViewportRotated
|
||||
* Whether or not screen orientation change is a result of rotating the viewport.
|
||||
* If true, then dispatch the "orientationchange" event on the content window.
|
||||
*/
|
||||
async simulateScreenOrientationChange(
|
||||
type,
|
||||
angle,
|
||||
isViewportRotated = false
|
||||
) {
|
||||
// Don't dispatch the "orientationchange" event if orientation change is a result
|
||||
// of switching to a new device, location change, or opening RDM.
|
||||
if (!isViewportRotated) {
|
||||
this.setScreenOrientation(type, angle);
|
||||
return;
|
||||
}
|
||||
|
||||
const { CustomEvent } = this.win;
|
||||
const orientationChangeEvent = new CustomEvent("orientationchange");
|
||||
|
||||
this.setScreenOrientation(type, angle);
|
||||
this.win.dispatchEvent(orientationChangeEvent);
|
||||
},
|
||||
|
||||
async captureScreenshot() {
|
||||
return this.screenshotActor.capture({});
|
||||
},
|
||||
|
||||
async setDocumentInRDMPane(inRDMPane) {
|
||||
if (this.docShell && this.docShell.document) {
|
||||
this.docShell.browsingContext.inRDMPane = inRDMPane;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
exports.ResponsiveActor = ResponsiveActor;
|
@ -214,9 +214,14 @@ const ActorRegistry = {
|
||||
constructor: "AnimationsActor",
|
||||
type: { target: true },
|
||||
});
|
||||
this.registerModule("devtools/server/actors/emulation", {
|
||||
prefix: "emulation",
|
||||
constructor: "EmulationActor",
|
||||
this.registerModule("devtools/server/actors/emulation/responsive", {
|
||||
prefix: "responsive",
|
||||
constructor: "ResponsiveActor",
|
||||
type: { target: true },
|
||||
});
|
||||
this.registerModule("devtools/server/actors/emulation/content-viewer", {
|
||||
prefix: "contentViewer",
|
||||
constructor: "ContentViewerActor",
|
||||
type: { target: true },
|
||||
});
|
||||
this.registerModule(
|
||||
|
26
devtools/shared/fronts/content-viewer.js
Normal file
26
devtools/shared/fronts/content-viewer.js
Normal file
@ -0,0 +1,26 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {
|
||||
FrontClassWithSpec,
|
||||
registerFront,
|
||||
} = require("devtools/shared/protocol");
|
||||
const { contentViewerSpec } = require("devtools/shared/specs/content-viewer");
|
||||
|
||||
/**
|
||||
* The corresponding Front object for the ContentViewer actor.
|
||||
*/
|
||||
class ContentViewerFront extends FrontClassWithSpec(contentViewerSpec) {
|
||||
constructor(client, targetFront, parentFront) {
|
||||
super(client, targetFront, parentFront);
|
||||
|
||||
// Attribute name from which to retrieve the actorID out of the target actor's form
|
||||
this.formAttributeName = "contentViewerActor";
|
||||
}
|
||||
}
|
||||
|
||||
exports.ContentViewerFront = ContentViewerFront;
|
||||
registerFront(ContentViewerFront);
|
@ -12,6 +12,8 @@ const { emulationSpec } = require("devtools/shared/specs/emulation");
|
||||
|
||||
/**
|
||||
* The corresponding Front object for the EmulationActor.
|
||||
*
|
||||
* Bug 1606852: Delete this file when Firefox 73 is on release.
|
||||
*/
|
||||
class EmulationFront extends FrontClassWithSpec(emulationSpec) {
|
||||
constructor(client, targetFront, parentFront) {
|
||||
|
@ -18,6 +18,7 @@ DevToolsModules(
|
||||
'animation.js',
|
||||
'array-buffer.js',
|
||||
'changes.js',
|
||||
'content-viewer.js',
|
||||
'css-properties.js',
|
||||
'device.js',
|
||||
'emulation.js',
|
||||
@ -37,6 +38,7 @@ DevToolsModules(
|
||||
'preference.js',
|
||||
'property-iterator.js',
|
||||
'reflow.js',
|
||||
'responsive.js',
|
||||
'root.js',
|
||||
'screenshot.js',
|
||||
'source.js',
|
||||
|
26
devtools/shared/fronts/responsive.js
Normal file
26
devtools/shared/fronts/responsive.js
Normal file
@ -0,0 +1,26 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {
|
||||
FrontClassWithSpec,
|
||||
registerFront,
|
||||
} = require("devtools/shared/protocol");
|
||||
const { responsiveSpec } = require("devtools/shared/specs/responsive");
|
||||
|
||||
/**
|
||||
* The corresponding Front object for the Responsive actor.
|
||||
*/
|
||||
class ResponsiveFront extends FrontClassWithSpec(responsiveSpec) {
|
||||
constructor(client, targetFront, parentFront) {
|
||||
super(client, targetFront, parentFront);
|
||||
|
||||
// Attribute name from which to retrieve the actorID out of the target actor's form
|
||||
this.formAttributeName = "responsiveActor";
|
||||
}
|
||||
}
|
||||
|
||||
exports.ResponsiveFront = ResponsiveFront;
|
||||
registerFront(ResponsiveFront);
|
@ -10,6 +10,7 @@ const {
|
||||
FrontClassWithSpec,
|
||||
registerFront,
|
||||
} = require("devtools/shared/protocol");
|
||||
const { Ci } = require("chrome");
|
||||
|
||||
class ServiceWorkerFront extends FrontClassWithSpec(serviceWorkerSpec) {
|
||||
get fetch() {
|
||||
@ -24,6 +25,25 @@ class ServiceWorkerFront extends FrontClassWithSpec(serviceWorkerSpec) {
|
||||
return this._form.state;
|
||||
}
|
||||
|
||||
get stateText() {
|
||||
switch (this.state) {
|
||||
case Ci.nsIServiceWorkerInfo.STATE_PARSED:
|
||||
return "parsed";
|
||||
case Ci.nsIServiceWorkerInfo.STATE_INSTALLING:
|
||||
return "installing";
|
||||
case Ci.nsIServiceWorkerInfo.STATE_INSTALLED:
|
||||
return "installed";
|
||||
case Ci.nsIServiceWorkerInfo.STATE_ACTIVATING:
|
||||
return "activating";
|
||||
case Ci.nsIServiceWorkerInfo.STATE_ACTIVATED:
|
||||
return "activated";
|
||||
case Ci.nsIServiceWorkerInfo.STATE_REDUNDANT:
|
||||
return "redundant";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
get id() {
|
||||
return this._form.id;
|
||||
}
|
||||
|
47
devtools/shared/specs/content-viewer.js
Normal file
47
devtools/shared/specs/content-viewer.js
Normal file
@ -0,0 +1,47 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
const { Arg, RetVal, generateActorSpec } = require("devtools/shared/protocol");
|
||||
|
||||
const contentViewerSpec = generateActorSpec({
|
||||
typeName: "contentViewer",
|
||||
|
||||
methods: {
|
||||
getEmulatedColorScheme: {
|
||||
request: {},
|
||||
response: {
|
||||
emulated: RetVal("nullable:string"),
|
||||
},
|
||||
},
|
||||
|
||||
setEmulatedColorScheme: {
|
||||
request: {
|
||||
scheme: Arg(0, "nullable:string"),
|
||||
},
|
||||
response: {},
|
||||
},
|
||||
|
||||
getIsPrintSimulationEnabled: {
|
||||
request: {},
|
||||
response: {
|
||||
enabled: RetVal("boolean"),
|
||||
},
|
||||
},
|
||||
|
||||
startPrintMediaSimulation: {
|
||||
request: {},
|
||||
response: {},
|
||||
},
|
||||
|
||||
stopPrintMediaSimulation: {
|
||||
request: {
|
||||
state: Arg(0, "boolean"),
|
||||
},
|
||||
response: {},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
exports.contentViewerSpec = contentViewerSpec;
|
@ -5,6 +5,8 @@
|
||||
|
||||
const { Arg, RetVal, generateActorSpec } = require("devtools/shared/protocol");
|
||||
|
||||
// Bug 1606852: Delete this file when Firefox 73 is on release.
|
||||
|
||||
const emulationSpec = generateActorSpec({
|
||||
typeName: "emulation",
|
||||
|
||||
|
@ -47,6 +47,11 @@ const Types = (exports.__TypesForTests = [
|
||||
spec: "devtools/shared/specs/changes",
|
||||
front: "devtools/shared/fronts/changes",
|
||||
},
|
||||
{
|
||||
types: ["contentViewer"],
|
||||
spec: "devtools/shared/specs/content-viewer",
|
||||
front: "devtools/shared/fronts/content-viewer",
|
||||
},
|
||||
{
|
||||
types: ["cssProperties"],
|
||||
spec: "devtools/shared/specs/css-properties",
|
||||
@ -72,11 +77,6 @@ const Types = (exports.__TypesForTests = [
|
||||
spec: "devtools/shared/specs/device",
|
||||
front: "devtools/shared/fronts/device",
|
||||
},
|
||||
{
|
||||
types: ["emulation"],
|
||||
spec: "devtools/shared/specs/emulation",
|
||||
front: "devtools/shared/fronts/emulation",
|
||||
},
|
||||
{
|
||||
types: ["environment"],
|
||||
spec: "devtools/shared/specs/environment",
|
||||
@ -174,6 +174,11 @@ const Types = (exports.__TypesForTests = [
|
||||
spec: "devtools/shared/specs/reflow",
|
||||
front: "devtools/shared/fronts/reflow",
|
||||
},
|
||||
{
|
||||
types: ["responsive"],
|
||||
spec: "devtools/shared/specs/responsive",
|
||||
front: "devtools/shared/fronts/responsive",
|
||||
},
|
||||
{
|
||||
types: ["screenshot"],
|
||||
spec: "devtools/shared/specs/screenshot",
|
||||
|
@ -17,6 +17,7 @@ DevToolsModules(
|
||||
'animation.js',
|
||||
'array-buffer.js',
|
||||
'changes.js',
|
||||
'content-viewer.js',
|
||||
'css-properties.js',
|
||||
'device.js',
|
||||
'emulation.js',
|
||||
@ -40,6 +41,7 @@ DevToolsModules(
|
||||
'preference.js',
|
||||
'property-iterator.js',
|
||||
'reflow.js',
|
||||
'responsive.js',
|
||||
'root.js',
|
||||
'screenshot.js',
|
||||
'source.js',
|
||||
|
159
devtools/shared/specs/responsive.js
Normal file
159
devtools/shared/specs/responsive.js
Normal file
@ -0,0 +1,159 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
const { Arg, RetVal, generateActorSpec } = require("devtools/shared/protocol");
|
||||
|
||||
const responsiveSpec = generateActorSpec({
|
||||
typeName: "responsive",
|
||||
|
||||
methods: {
|
||||
setDPPXOverride: {
|
||||
request: {
|
||||
dppx: Arg(0, "number"),
|
||||
},
|
||||
response: {
|
||||
valueChanged: RetVal("boolean"),
|
||||
},
|
||||
},
|
||||
|
||||
getDPPXOverride: {
|
||||
request: {},
|
||||
response: {
|
||||
dppx: RetVal("number"),
|
||||
},
|
||||
},
|
||||
|
||||
clearDPPXOverride: {
|
||||
request: {},
|
||||
response: {
|
||||
valueChanged: RetVal("boolean"),
|
||||
},
|
||||
},
|
||||
|
||||
setNetworkThrottling: {
|
||||
request: {
|
||||
options: Arg(0, "json"),
|
||||
},
|
||||
response: {
|
||||
valueChanged: RetVal("boolean"),
|
||||
},
|
||||
},
|
||||
|
||||
getNetworkThrottling: {
|
||||
request: {},
|
||||
response: {
|
||||
state: RetVal("json"),
|
||||
},
|
||||
},
|
||||
|
||||
clearNetworkThrottling: {
|
||||
request: {},
|
||||
response: {
|
||||
valueChanged: RetVal("boolean"),
|
||||
},
|
||||
},
|
||||
|
||||
setTouchEventsOverride: {
|
||||
request: {
|
||||
flag: Arg(0, "number"),
|
||||
},
|
||||
response: {
|
||||
valueChanged: RetVal("boolean"),
|
||||
},
|
||||
},
|
||||
|
||||
getTouchEventsOverride: {
|
||||
request: {},
|
||||
response: {
|
||||
flag: RetVal("number"),
|
||||
},
|
||||
},
|
||||
|
||||
clearTouchEventsOverride: {
|
||||
request: {},
|
||||
response: {
|
||||
valueChanged: RetVal("boolean"),
|
||||
},
|
||||
},
|
||||
|
||||
setMetaViewportOverride: {
|
||||
request: {
|
||||
flag: Arg(0, "number"),
|
||||
},
|
||||
response: {
|
||||
valueChanged: RetVal("boolean"),
|
||||
},
|
||||
},
|
||||
|
||||
getMetaViewportOverride: {
|
||||
request: {},
|
||||
response: {
|
||||
flag: RetVal("number"),
|
||||
},
|
||||
},
|
||||
|
||||
clearMetaViewportOverride: {
|
||||
request: {},
|
||||
response: {
|
||||
valueChanged: RetVal("boolean"),
|
||||
},
|
||||
},
|
||||
|
||||
setUserAgentOverride: {
|
||||
request: {
|
||||
flag: Arg(0, "string"),
|
||||
},
|
||||
response: {
|
||||
valueChanged: RetVal("boolean"),
|
||||
},
|
||||
},
|
||||
|
||||
getUserAgentOverride: {
|
||||
request: {},
|
||||
response: {
|
||||
userAgent: RetVal("string"),
|
||||
},
|
||||
},
|
||||
|
||||
clearUserAgentOverride: {
|
||||
request: {},
|
||||
response: {
|
||||
valueChanged: RetVal("boolean"),
|
||||
},
|
||||
},
|
||||
|
||||
setElementPickerState: {
|
||||
request: {
|
||||
state: Arg(0, "boolean"),
|
||||
},
|
||||
response: {},
|
||||
},
|
||||
|
||||
simulateScreenOrientationChange: {
|
||||
request: {
|
||||
orientation: Arg(0, "string"),
|
||||
angle: Arg(1, "number"),
|
||||
deviceChange: Arg(2, "boolean"),
|
||||
},
|
||||
response: {},
|
||||
},
|
||||
|
||||
captureScreenshot: {
|
||||
request: {},
|
||||
response: {
|
||||
value: RetVal("json"),
|
||||
},
|
||||
},
|
||||
|
||||
setDocumentInRDMPane: {
|
||||
request: {
|
||||
state: Arg(0, "boolean"),
|
||||
},
|
||||
response: {},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
exports.responsiveSpec = responsiveSpec;
|
@ -14,7 +14,7 @@ from recommonmark.transform import AutoStructify
|
||||
|
||||
# Set up Python environment to load build system packages.
|
||||
OUR_DIR = os.path.dirname(__file__)
|
||||
topsrcdir = os.path.normpath(os.path.join(OUR_DIR, '..', '..'))
|
||||
topsrcdir = os.path.normpath(os.path.join(OUR_DIR, '..'))
|
||||
|
||||
EXTRA_PATHS = (
|
||||
'layout/tools/reftest',
|
@ -3,6 +3,8 @@
|
||||
# The order of the main categories are defined in index.rst
|
||||
# Sub categories orders are preserved
|
||||
categories:
|
||||
contributing_doc:
|
||||
- contributing
|
||||
source_doc:
|
||||
- browser
|
||||
- dom
|
||||
@ -21,7 +23,7 @@ categories:
|
||||
- tools/try
|
||||
- build/buildsystem
|
||||
- taskcluster
|
||||
- tools/docs
|
||||
- tools/moztreedocs
|
||||
testing_doc:
|
||||
- testing/marionette
|
||||
- testing/geckodriver
|
||||
@ -52,3 +54,4 @@ redirects:
|
||||
testing/marionette/marionette: testing/marionette
|
||||
toolkit/components/telemetry/telemetry: toolkit/components/telemetry
|
||||
tools/compare-locales/index.html: build/buildsystem/locales.html
|
||||
tools/docs/index.html: tools/moztreedocs/index.html
|
11
docs/contributing/index.rst
Normal file
11
docs/contributing/index.rst
Normal file
@ -0,0 +1,11 @@
|
||||
Contributing to Firefox
|
||||
=======================
|
||||
|
||||
This is the preferred location for all Firefox development process and
|
||||
source code documentation.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:glob:
|
||||
|
||||
*
|
@ -2,6 +2,12 @@
|
||||
Mozilla Source Tree Documentation
|
||||
=================================
|
||||
|
||||
.. toctree::
|
||||
:caption: Contributing
|
||||
:maxdepth: 2
|
||||
|
||||
{contributing_doc}
|
||||
|
||||
.. toctree::
|
||||
:caption: Source code doc
|
||||
:maxdepth: 2
|
@ -391,6 +391,10 @@ void Animation::UpdatePlaybackRate(double aPlaybackRate) {
|
||||
//
|
||||
// All we need to do is update observers so that, e.g. DevTools, report the
|
||||
// right information.
|
||||
//
|
||||
// First we need to update the relevance however since we might have become
|
||||
// current or stopped being current.
|
||||
UpdateRelevance();
|
||||
if (IsRelevant()) {
|
||||
MutationObservers::NotifyAnimationChanged(this);
|
||||
}
|
||||
|
24
dom/animation/test/crashtests/1604500-1.html
Normal file
24
dom/animation/test/crashtests/1604500-1.html
Normal file
@ -0,0 +1,24 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
function start () {
|
||||
const keyframe = new KeyframeEffect(undefined, {});
|
||||
const animation = new Animation(keyframe, undefined);
|
||||
// Make animation run backwards...
|
||||
animation.playbackRate = -100;
|
||||
// But then set the current time to the future so it becomes "current"...
|
||||
animation.currentTime = 2055;
|
||||
// After updating the playback rate to zero, however, it should no longer
|
||||
// be "current" (and this takes effect immediately because |animation| is
|
||||
// paused)...
|
||||
animation.updatePlaybackRate(0);
|
||||
// Now update the target and hope nothing goes wrong...
|
||||
keyframe.target = div;
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', start)
|
||||
</script>
|
||||
</head>
|
||||
<div id=div></div>
|
||||
</html>
|
@ -45,3 +45,4 @@ pref(dom.animations-api.implicit-keyframes.enabled,true) load 1467277-1.html
|
||||
load 1524480-1.html
|
||||
load 1575926.html
|
||||
pref(dom.animations-api.implicit-keyframes.enabled,true) load 1585770.html
|
||||
load 1604500-1.html
|
||||
|
@ -29,7 +29,7 @@ test(function(t) {
|
||||
sandbox.importFunction(document, "document");
|
||||
sandbox.importFunction(assert_true, "assert_true");
|
||||
sandbox.importFunction(assert_unreached, "assert_unreached");
|
||||
SpecialPowers.Cu.evalInSandbox(`(${contentScript.toSource()})()`, sandbox);
|
||||
SpecialPowers.Cu.evalInSandbox(`(${contentScript.toString()})()`, sandbox);
|
||||
}, 'Setting easing should not throw any exceptions in sandbox');
|
||||
|
||||
</script>
|
||||
|
@ -108,14 +108,13 @@ nsDataDocumentContentPolicy::ShouldLoad(nsIURI* aContentLocation,
|
||||
// Report error, if we can.
|
||||
if (node) {
|
||||
nsIPrincipal* requestingPrincipal = node->NodePrincipal();
|
||||
RefPtr<nsIURI> principalURI;
|
||||
nsresult rv = requestingPrincipal->GetURI(getter_AddRefs(principalURI));
|
||||
if (NS_SUCCEEDED(rv) && principalURI) {
|
||||
nsScriptSecurityManager::ReportError(
|
||||
"ExternalDataError", principalURI, aContentLocation,
|
||||
requestingPrincipal->OriginAttributesRef().mPrivateBrowsingId >
|
||||
0);
|
||||
}
|
||||
nsAutoCString sourceSpec;
|
||||
requestingPrincipal->GetAsciiSpec(sourceSpec);
|
||||
nsAutoCString targetSpec;
|
||||
aContentLocation->GetAsciiSpec(targetSpec);
|
||||
nsScriptSecurityManager::ReportError(
|
||||
"ExternalDataError", sourceSpec, targetSpec,
|
||||
requestingPrincipal->OriginAttributesRef().mPrivateBrowsingId > 0);
|
||||
}
|
||||
} else if ((contentType == nsIContentPolicy::TYPE_IMAGE ||
|
||||
contentType == nsIContentPolicy::TYPE_IMAGESET) &&
|
||||
|
@ -1535,18 +1535,16 @@ void nsGlobalWindowInner::TraceGlobalJSObject(JSTracer* aTrc) {
|
||||
TraceWrapper(aTrc, "active window global");
|
||||
}
|
||||
|
||||
void nsGlobalWindowInner::InnerSetNewDocument(JSContext* aCx,
|
||||
Document* aDocument) {
|
||||
MOZ_ASSERT(aDocument);
|
||||
void nsGlobalWindowInner::InitDocumentDependentState(JSContext* aCx) {
|
||||
MOZ_ASSERT(mDoc);
|
||||
|
||||
if (MOZ_LOG_TEST(gDOMLeakPRLogInner, LogLevel::Debug)) {
|
||||
nsIURI* uri = aDocument->GetDocumentURI();
|
||||
nsIURI* uri = mDoc->GetDocumentURI();
|
||||
MOZ_LOG(gDOMLeakPRLogInner, LogLevel::Debug,
|
||||
("DOMWINDOW %p SetNewDocument %s", this,
|
||||
uri ? uri->GetSpecOrDefault().get() : ""));
|
||||
}
|
||||
|
||||
mDoc = aDocument;
|
||||
mFocusedElement = nullptr;
|
||||
mLocalStorage = nullptr;
|
||||
mSessionStorage = nullptr;
|
||||
@ -1580,7 +1578,7 @@ void nsGlobalWindowInner::InnerSetNewDocument(JSContext* aCx,
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
mLastOpenedURI = aDocument->GetDocumentURI();
|
||||
mLastOpenedURI = mDoc->GetDocumentURI();
|
||||
#endif
|
||||
|
||||
Telemetry::Accumulate(Telemetry::INNERWINDOWS_WITH_MUTATION_LISTENERS,
|
||||
|
@ -1017,9 +1017,9 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
||||
|
||||
void FreeInnerObjects();
|
||||
|
||||
// Only to be called on an inner window.
|
||||
// aDocument must not be null.
|
||||
void InnerSetNewDocument(JSContext* aCx, Document* aDocument);
|
||||
// Initialize state that depends on the document. By this point, mDoc should
|
||||
// be set correctly and have us set as its script global object.
|
||||
void InitDocumentDependentState(JSContext* aCx);
|
||||
|
||||
nsresult EnsureClientSource();
|
||||
nsresult ExecutionReady();
|
||||
|
@ -2162,15 +2162,28 @@ nsresult nsGlobalWindowOuter::SetNewDocument(Document* aDocument,
|
||||
// Add an extra ref in case we release mContext during GC.
|
||||
nsCOMPtr<nsIScriptContext> kungFuDeathGrip(mContext);
|
||||
|
||||
// Make sure the inner's document is set correctly before we call
|
||||
// SetScriptGlobalObject, because that might try to examine document-dependent
|
||||
// state. Unfortunately, we can't do some of the other clearing/resetting
|
||||
// work we do below until after SetScriptGlobalObject(), because it might
|
||||
// depend on the document having the right scope object.
|
||||
if (aState) {
|
||||
MOZ_RELEASE_ASSERT(newInnerWindow->mDoc == aDocument);
|
||||
} else {
|
||||
if (reUseInnerWindow) {
|
||||
MOZ_RELEASE_ASSERT(newInnerWindow->mDoc != aDocument);
|
||||
}
|
||||
newInnerWindow->mDoc = aDocument;
|
||||
}
|
||||
|
||||
aDocument->SetScriptGlobalObject(newInnerWindow);
|
||||
MOZ_ASSERT(newInnerWindow->mTabGroup,
|
||||
"We must have a TabGroup cached at this point");
|
||||
|
||||
MOZ_RELEASE_ASSERT(newInnerWindow->mDoc == aDocument);
|
||||
|
||||
if (!aState) {
|
||||
if (reUseInnerWindow) {
|
||||
MOZ_RELEASE_ASSERT(newInnerWindow->mDoc != aDocument);
|
||||
newInnerWindow->mDoc = aDocument;
|
||||
|
||||
// The storage objects contain the URL of the window. We have to
|
||||
// recreate them when the innerWindow is reused.
|
||||
newInnerWindow->mLocalStorage = nullptr;
|
||||
@ -2188,7 +2201,7 @@ nsresult nsGlobalWindowOuter::SetNewDocument(Document* aDocument,
|
||||
rv = newInnerWindow->ExecutionReady();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else {
|
||||
newInnerWindow->InnerSetNewDocument(cx, aDocument);
|
||||
newInnerWindow->InitDocumentDependentState(cx);
|
||||
|
||||
// Initialize DOM classes etc on the inner window.
|
||||
JS::Rooted<JSObject*> obj(cx, newInnerGlobal);
|
||||
|
@ -54,7 +54,7 @@ function compare(a, b) {
|
||||
for (var p in b) bProps.push(p);
|
||||
|
||||
is (aProps.length, bProps.length, 'Props match');
|
||||
is (aProps.sort().toSource(), bProps.sort().toSource(), 'Props match - using toSource()');
|
||||
is (aProps.sort().toString(), bProps.sort().toString(), 'Props names match');
|
||||
|
||||
for (var p in a) {
|
||||
compare(a[p], b[p]);
|
||||
@ -75,7 +75,7 @@ function compare(a, b) {
|
||||
}
|
||||
|
||||
if (type != 'null') {
|
||||
is (a.toSource(), b.toSource(), 'Matching using toSource()');
|
||||
is (a, b, 'Same value');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -428,18 +428,15 @@ bool nsScriptErrorBase::ComputeIsFromPrivateWindow(
|
||||
nsGlobalWindowInner* aWindow) {
|
||||
// Never mark exceptions from chrome windows as having come from private
|
||||
// windows, since we always want them to be reported.
|
||||
// winPrincipal needs to be null-checked - Bug 1601175
|
||||
nsIPrincipal* winPrincipal = aWindow->GetPrincipal();
|
||||
return aWindow->IsPrivateBrowsing() &&
|
||||
(!winPrincipal || !winPrincipal->IsSystemPrincipal());
|
||||
return aWindow->IsPrivateBrowsing() && !winPrincipal->IsSystemPrincipal();
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool nsScriptErrorBase::ComputeIsFromChromeContext(
|
||||
nsGlobalWindowInner* aWindow) {
|
||||
nsIPrincipal* winPrincipal = aWindow->GetPrincipal();
|
||||
// winPrincipal needs to be null-checked - Bug 1601175
|
||||
return (winPrincipal && winPrincipal->IsSystemPrincipal());
|
||||
return winPrincipal->IsSystemPrincipal();
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsScriptError, nsIConsoleMessage, nsIScriptError)
|
||||
|
@ -60,7 +60,7 @@ function compare(a, b) {
|
||||
for (let p in b) bProps.push(p);
|
||||
|
||||
is(aProps.length, bProps.length, "Props match");
|
||||
is(aProps.sort().toSource(), bProps.sort().toSource(), "Props match - using toSource()");
|
||||
is(aProps.sort().toString(), bProps.sort().toString(), "Props names match");
|
||||
|
||||
for (let p in a) {
|
||||
compare(a[p], b[p]);
|
||||
@ -70,7 +70,7 @@ function compare(a, b) {
|
||||
}
|
||||
|
||||
if (type != "null") {
|
||||
is(a.toSource(), b.toSource(), "Matching using toSource()");
|
||||
is(a, b, "Same value");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ function workerGroupUsage() {
|
||||
}
|
||||
|
||||
let url =
|
||||
URL.createObjectURL(new Blob(["(", workerScript.toSource(), ")()"]));
|
||||
URL.createObjectURL(new Blob(["(", workerScript.toString(), ")()"]));
|
||||
|
||||
let worker = new Worker(url);
|
||||
worker.onmessage = function(e) {
|
||||
|
@ -21302,7 +21302,7 @@ function test_2d_imageSmoothing() {
|
||||
pixels[1] == 255 &&
|
||||
pixels[2] == 0 &&
|
||||
pixels[3] == 255,
|
||||
"pixel is " + pixels.toSource() + " (expected [0,255,0,255])");
|
||||
"pixel is [" + pixels.toString() + "] (expected [0,255,0,255])");
|
||||
}
|
||||
|
||||
</script>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user