Merge mozilla-central to autoland

This commit is contained in:
Carsten "Tomcat" Book 2016-07-05 16:09:08 +02:00
commit 2013c96abf
337 changed files with 6119 additions and 2295 deletions

View File

@ -230,6 +230,7 @@ const SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE = SEC_ERROR_BASE + 30;
const SEC_ERROR_OCSP_FUTURE_RESPONSE = SEC_ERROR_BASE + 131;
const SEC_ERROR_OCSP_OLD_RESPONSE = SEC_ERROR_BASE + 132;
const MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE = MOZILLA_PKIX_ERROR_BASE + 5;
const MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE = MOZILLA_PKIX_ERROR_BASE + 6;
const PREF_BLOCKLIST_CLOCK_SKEW_SECONDS = "services.blocklist.clock_skew_seconds";
@ -272,10 +273,10 @@ var AboutNetAndCertErrorListener = {
onCertErrorDetails(msg) {
let div = content.document.getElementById("certificateErrorText");
div.textContent = msg.data.info;
let learnMoreLink = content.document.getElementById("learnMoreLink");
switch (msg.data.code) {
case SEC_ERROR_UNKNOWN_ISSUER:
let learnMoreLink = content.document.getElementById("learnMoreLink");
learnMoreLink.href = "https://support.mozilla.org/kb/troubleshoot-SEC_ERROR_UNKNOWN_ISSUER";
break;
@ -286,6 +287,7 @@ var AboutNetAndCertErrorListener = {
case SEC_ERROR_OCSP_FUTURE_RESPONSE:
case SEC_ERROR_OCSP_OLD_RESPONSE:
case MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE:
case MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE:
// use blocklist stats if available
if (Services.prefs.getPrefType(PREF_BLOCKLIST_CLOCK_SKEW_SECONDS)) {
@ -311,7 +313,8 @@ var AboutNetAndCertErrorListener = {
.style.display = "block";
}
}
let url = Services.urlFormatter.formatURLPref("app.support.baseURL") + "time-errors";
learnMoreLink.setAttribute("href", url);
break;
}
},

View File

@ -125,12 +125,14 @@ add_task(function* checkWrongSystemTimeWarning() {
let div = doc.getElementById("wrongSystemTimePanel");
let systemDateDiv = doc.getElementById("wrongSystemTime_systemDate");
let actualDateDiv = doc.getElementById("wrongSystemTime_actualDate");
let learnMoreLink = doc.getElementById("learnMoreLink");
return {
divDisplay: content.getComputedStyle(div).display,
text: div.textContent,
systemDate: systemDateDiv.textContent,
actualDate: actualDateDiv.textContent
actualDate: actualDateDiv.textContent,
learnMoreLink: learnMoreLink.href
};
});
}
@ -155,6 +157,7 @@ add_task(function* checkWrongSystemTimeWarning() {
ok(message.text.includes("expired.example.com"), "URL found in error message");
ok(message.systemDate.includes(localDateFmt), "correct local date displayed");
ok(message.actualDate.includes(serverDateFmt), "correct server date displayed");
ok(message.learnMoreLink.includes("time-errors"), "time-errors in the Learn More URL");
yield BrowserTestUtils.removeTab(gBrowser.selectedTab);

View File

@ -220,7 +220,7 @@ add_task(function* test_search_input() {
});
add_task(function* test_datetime_month_week_datetimelocal_input_todos() {
for (let type of ["datetime", "month", "week", "datetime-local"]) {
for (let type of ["datetime", "week", "datetime-local"]) {
let returnedType = yield ContentTask.spawn(gBrowser.selectedBrowser, type, function*(type) {
let doc = content.document;
let input = doc.getElementById("input_" + type);

View File

@ -0,0 +1,11 @@
<Application xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
<VisualElements
DisplayName='Firefox Developer Edition'
Logo='VisualElements\VisualElements_150.png'
SmallLogo='VisualElements\VisualElements_70.png'
ForegroundText='light'
BackgroundColor='#14171a'/>
<DefaultTile ShowName='allLogos'/>
<SplashScreen Image='DummyFileNameRequiredByWindows.png'/>
</VisualElements>
</Application>

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,8 @@
<Application xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
<VisualElements
ShowNameOnSquare150x150Logo='on'
Square150x150Logo='VisualElements\VisualElements_150.png'
Square70x70Logo='VisualElements\VisualElements_70.png'
ForegroundText='light'
BackgroundColor='#14171a'/>
</Application>

View File

@ -11,6 +11,14 @@ def FirefoxBranding():
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
FINAL_TARGET_FILES['..'] += [
'firefox.VisualElementsManifest.xml',
'VisualElementsManifest.xml',
]
FINAL_TARGET_FILES.VisualElements += [
'VisualElements_150.png',
'VisualElements_70.png',
]
BRANDING_FILES += [
'appname.bmp',
'bgintro.bmp',

View File

@ -0,0 +1,11 @@
<Application xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
<VisualElements
DisplayName='Nightly'
Logo='VisualElements\VisualElements_150.png'
SmallLogo='VisualElements\VisualElements_70.png'
ForegroundText='light'
BackgroundColor='#14171a'/>
<DefaultTile ShowName='allLogos'/>
<SplashScreen Image='DummyFileNameRequiredByWindows.png'/>
</VisualElements>
</Application>

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

View File

@ -0,0 +1,8 @@
<Application xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
<VisualElements
ShowNameOnSquare150x150Logo='on'
Square150x150Logo='VisualElements\VisualElements_150.png'
Square70x70Logo='VisualElements\VisualElements_70.png'
ForegroundText='light'
BackgroundColor='#14171a'/>
</Application>

View File

@ -0,0 +1,11 @@
<Application xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
<VisualElements
DisplayName='Mozilla Firefox'
Logo='VisualElements\VisualElements_150.png'
SmallLogo='VisualElements\VisualElements_70.png'
ForegroundText='light'
BackgroundColor='#0996f8'/>
<DefaultTile ShowName='allLogos'/>
<SplashScreen Image='DummyFileNameRequiredByWindows.png'/>
</VisualElements>
</Application>

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

View File

@ -0,0 +1,8 @@
<Application xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
<VisualElements
ShowNameOnSquare150x150Logo='on'
Square150x150Logo='VisualElements\VisualElements_150.png'
Square70x70Logo='VisualElements\VisualElements_70.png'
ForegroundText='light'
BackgroundColor='#0996f8'/>
</Application>

View File

@ -0,0 +1,11 @@
<Application>
<VisualElements
DisplayName='Nightly'
Logo='VisualElements\VisualElements_150.png'
SmallLogo='VisualElements\VisualElements_70.png'
ForegroundText='light'
BackgroundColor='#14171a'>
<DefaultTile ShowName='allLogos'/>
<SplashScreen Image='DummyFileNameRequiredByWindows.png'/>
</VisualElements>
</Application>

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

View File

@ -0,0 +1,8 @@
<Application xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
<VisualElements
ShowNameOnSquare150x150Logo='on'
Square150x150Logo='VisualElements\VisualElements_150.png'
Square70x70Logo='VisualElements\VisualElements_70.png'
ForegroundText='light'
BackgroundColor='#14171a'/>
</Application>

View File

@ -559,6 +559,7 @@ var PlacesOrganizer = {
fp.appendFilter(PlacesUIUtils.getString("bookmarksRestoreFilterName"),
RESTORE_FILEPICKER_FILTER_EXT);
fp.defaultString = PlacesBackups.getFilenameForDate();
fp.defaultExtension = "json";
fp.displayDirectory = backupsDir;
fp.open(fpCallback);
},

View File

@ -113,6 +113,10 @@
; [Base Browser Files]
#ifndef XP_UNIX
@BINPATH@/@MOZ_APP_NAME@.exe
@BINPATH@/firefox.VisualElementsManifest.xml
@BINPATH@/VisualElementsManifest.xml
@BINPATH@/browser/VisualElements/VisualElements_150.png
@BINPATH@/browser/VisualElements/VisualElements_70.png
#else
@BINPATH@/@MOZ_APP_NAME@-bin
@BINPATH@/@MOZ_APP_NAME@
@ -438,6 +442,7 @@
@RESPATH@/components/nsTaggingService.js
@RESPATH@/components/UnifiedComplete.js
@RESPATH@/components/nsPlacesExpiration.js
@RESPATH@/components/PageIconProtocolHandler.js
@RESPATH@/components/PlacesCategoriesStarter.js
@RESPATH@/components/ColorAnalyzer.js
@RESPATH@/components/PageThumbsProtocol.js

View File

@ -53,8 +53,6 @@ PluginContent.prototype = {
global.addMessageListener("BrowserPlugins:NPAPIPluginProcessCrashed", this);
global.addMessageListener("BrowserPlugins:CrashReportSubmitted", this);
global.addMessageListener("BrowserPlugins:Test:ClearCrashData", this);
Services.obs.addObserver(this, "Plugin::HiddenPluginTouched", false);
},
uninit: function() {
@ -77,8 +75,6 @@ PluginContent.prototype = {
global.removeMessageListener("BrowserPlugins:Test:ClearCrashData", this);
delete this.global;
delete this.content;
Services.obs.removeObserver(this, "Plugin::HiddenPluginTouched");
},
receiveMessage: function (msg) {
@ -120,15 +116,6 @@ PluginContent.prototype = {
}
},
observe: function observe(aSubject, aTopic, aData) {
let pluginTag = aSubject.QueryInterface(Ci.nsIPluginTag);
if (aTopic == "Plugin::HiddenPluginTouched") {
this._showClickToPlayNotification(pluginTag, false);
} else {
Cu.reportError("unknown topic observed: " + aTopic);
}
},
onPageShow: function (event) {
// Ignore events that aren't from the main document.
if (!this.content || event.target != this.content.document) {
@ -207,45 +194,6 @@ PluginContent.prototype = {
};
},
_getPluginInfoForTag: function (pluginTag, tagMimetype) {
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
let pluginName = gNavigatorBundle.GetStringFromName("pluginInfo.unknownPlugin");
let permissionString = null;
let blocklistState = null;
if (pluginTag) {
pluginName = BrowserUtils.makeNicePluginName(pluginTag.name);
permissionString = pluginHost.getPermissionStringForTag(pluginTag);
blocklistState = pluginTag.blocklistState;
// Convert this from nsIPluginTag so it can be serialized.
let properties = ["name", "description", "filename", "version", "enabledState", "niceName"];
let pluginTagCopy = {};
for (let prop of properties) {
pluginTagCopy[prop] = pluginTag[prop];
}
pluginTag = pluginTagCopy;
// Make state-softblocked == state-notblocked for our purposes,
// they have the same UI. STATE_OUTDATED should not exist for plugin
// items, but let's alias it anyway, just in case.
if (blocklistState == Ci.nsIBlocklistService.STATE_SOFTBLOCKED ||
blocklistState == Ci.nsIBlocklistService.STATE_OUTDATED) {
blocklistState = Ci.nsIBlocklistService.STATE_NOT_BLOCKED;
}
}
return { mimetype: tagMimetype,
pluginName: pluginName,
pluginTag: pluginTag,
permissionString: permissionString,
fallbackType: null,
blocklistState: blocklistState,
};
},
/**
* Update the visibility of the plugin overlay.
*/
@ -762,13 +710,7 @@ PluginContent.prototype = {
let location = this.content.document.location.href;
for (let p of plugins) {
let pluginInfo;
if (p instanceof Ci.nsIPluginTag) {
let mimeType = p.getMimeTypes() > 0 ? p.getMimeTypes()[0] : null;
pluginInfo = this._getPluginInfoForTag(p, mimeType);
} else {
pluginInfo = this._getPluginInfo(p);
}
let pluginInfo = this._getPluginInfo(p);
if (pluginInfo.permissionString === null) {
Cu.reportError("No permission string for active plugin.");
continue;

View File

@ -43,10 +43,14 @@ if test "$MOZ_BUILD_APP" != js -o -n "$JS_STANDALONE"; then
if test -n "$CLANG_CC" -a "$CPU_ARCH" = arm; then
CFLAGS="-no-integrated-as $CFLAGS"
fi
if test "$CROSS_COMPILE"; then
export CPPFLAGS CFLAGS LDFLAGS
fi
ac_configure_args="$ac_configure_args --build=$build --host=$target"
if test "$CROSS_COMPILE"; then
ac_configure_args="$ac_configure_args \
CFLAGS=\"$CFLAGS\" \
CPPFLAGS=\"$CPPFLAGS\" \
LDFLAGS=\"$LDFLAGS\""
fi
CFLAGS="$old_cflags"
if test "$_MSC_VER"; then
# Use a wrapper script for cl and ml that looks more like gcc.
# autotools can't quite handle an MSVC build environment yet.
@ -83,7 +87,6 @@ if test "$MOZ_BUILD_APP" != js -o -n "$JS_STANDALONE"; then
AC_OUTPUT_SUBDIRS(js/src/ctypes/libffi)
ac_configure_args="$_SUBDIR_CONFIG_ARGS"
CONFIG_FILES=$old_config_files
CFLAGS="$old_cflags"
fi
fi

View File

@ -659,7 +659,7 @@ var DebuggerView = {
* @return boolean
*/
get instrumentsPaneHidden() {
return this._instrumentsPane.hasAttribute("pane-collapsed");
return this._instrumentsPane.classList.contains("pane-collapsed");
},
/**
@ -689,10 +689,10 @@ var DebuggerView = {
ViewHelpers.togglePane(aFlags, pane);
if (aFlags.visible) {
button.removeAttribute("pane-collapsed");
button.classList.remove("pane-collapsed");
button.setAttribute("tooltiptext", this._collapsePaneString);
} else {
button.setAttribute("pane-collapsed", "");
button.classList.add("pane-collapsed");
button.setAttribute("tooltiptext", this._expandPaneString);
}

View File

@ -41,8 +41,8 @@ function testPanesState() {
let instrumentsPaneToggleButton =
gDebugger.document.getElementById("instruments-pane-toggle");
ok(instrumentsPane.hasAttribute("pane-collapsed") &&
instrumentsPaneToggleButton.hasAttribute("pane-collapsed"),
ok(instrumentsPane.classList.contains("pane-collapsed") &&
instrumentsPaneToggleButton.classList.contains("pane-collapsed"),
"The debugger view instruments pane should initially be hidden.");
is(gPrefs.panesVisibleOnStartup, false,
"The debugger view instruments pane should initially be preffed as hidden.");
@ -65,8 +65,8 @@ function testInstrumentsPaneCollapse() {
"The instruments pane has an incorrect right margin.");
ok(!instrumentsPane.hasAttribute("animated"),
"The instruments pane has an incorrect animated attribute.");
ok(!instrumentsPane.hasAttribute("pane-collapsed") &&
!instrumentsPaneToggleButton.hasAttribute("pane-collapsed"),
ok(!instrumentsPane.classList.contains("pane-collapsed") &&
!instrumentsPaneToggleButton.classList.contains("pane-collapsed"),
"The instruments pane should at this point be visible.");
gDebugger.DebuggerView.toggleInstrumentsPane({ visible: false, animated: true });
@ -85,8 +85,8 @@ function testInstrumentsPaneCollapse() {
"The instruments pane has an incorrect right margin after collapsing.");
ok(instrumentsPane.hasAttribute("animated"),
"The instruments pane has an incorrect attribute after an animated collapsing.");
ok(instrumentsPane.hasAttribute("pane-collapsed") &&
instrumentsPaneToggleButton.hasAttribute("pane-collapsed"),
ok(instrumentsPane.classList.contains("pane-collapsed") &&
instrumentsPaneToggleButton.classList.contains("pane-collapsed"),
"The instruments pane should not be visible after collapsing.");
gDebugger.DebuggerView.toggleInstrumentsPane({ visible: true, animated: false });
@ -104,8 +104,8 @@ function testInstrumentsPaneCollapse() {
"The instruments pane has an incorrect right margin after uncollapsing.");
ok(!instrumentsPane.hasAttribute("animated"),
"The instruments pane has an incorrect attribute after an unanimated uncollapsing.");
ok(!instrumentsPane.hasAttribute("pane-collapsed") &&
!instrumentsPaneToggleButton.hasAttribute("pane-collapsed"),
ok(!instrumentsPane.classList.contains("pane-collapsed") &&
!instrumentsPaneToggleButton.classList.contains("pane-collapsed"),
"The instruments pane should be visible again after uncollapsing.");
}
@ -118,8 +118,8 @@ function testPanesStartupPref() {
is(gPrefs.panesVisibleOnStartup, false,
"The debugger view panes should still initially be preffed as hidden.");
ok(!instrumentsPane.hasAttribute("pane-collapsed") &&
!instrumentsPaneToggleButton.hasAttribute("pane-collapsed"),
ok(!instrumentsPane.classList.contains("pane-collapsed") &&
!instrumentsPaneToggleButton.classList.contains("pane-collapsed"),
"The debugger instruments pane should at this point be visible.");
is(gPrefs.panesVisibleOnStartup, false,
"The debugger view panes should initially be preffed as hidden.");
@ -129,8 +129,8 @@ function testPanesStartupPref() {
gOptions._showPanesOnStartupItem.setAttribute("checked", "true");
gOptions._toggleShowPanesOnStartup();
ok(!instrumentsPane.hasAttribute("pane-collapsed") &&
!instrumentsPaneToggleButton.hasAttribute("pane-collapsed"),
ok(!instrumentsPane.classList.contains("pane-collapsed") &&
!instrumentsPaneToggleButton.classList.contains("pane-collapsed"),
"The debugger instruments pane should at this point be visible.");
is(gPrefs.panesVisibleOnStartup, true,
"The debugger view panes should now be preffed as visible.");
@ -140,8 +140,8 @@ function testPanesStartupPref() {
gOptions._showPanesOnStartupItem.setAttribute("checked", "false");
gOptions._toggleShowPanesOnStartup();
ok(!instrumentsPane.hasAttribute("pane-collapsed") &&
!instrumentsPaneToggleButton.hasAttribute("pane-collapsed"),
ok(!instrumentsPane.classList.contains("pane-collapsed") &&
!instrumentsPaneToggleButton.classList.contains("pane-collapsed"),
"The debugger instruments pane should at this point be visible.");
is(gPrefs.panesVisibleOnStartup, false,
"The debugger view panes should now be preffed as hidden.");

View File

@ -144,7 +144,9 @@ ToolSidebar.prototype = {
// Add menuitems to the alltabs menu if there are already tabs in the
// sidebar
for (let [id, tab] of this._tabs) {
let item = this._addItemToAllTabsMenu(id, tab, tab.hasAttribute("selected"));
let item = this._addItemToAllTabsMenu(id, tab, {
selected: tab.hasAttribute("selected")
});
if (tab.hidden) {
item.hidden = true;
}
@ -179,23 +181,30 @@ ToolSidebar.prototype = {
/**
* Add an item in the allTabs menu for a given tab.
*/
_addItemToAllTabsMenu: function (id, tab, selected = false) {
_addItemToAllTabsMenu: function (id, tab, options) {
if (!this._allTabsBtn) {
return;
}
let item = this._panelDoc.createElementNS(XULNS, "menuitem");
item.setAttribute("id", "sidebar-alltabs-item-" + id);
let idPrefix = "sidebar-alltabs-item-";
item.setAttribute("id", idPrefix + id);
item.setAttribute("label", tab.getAttribute("label"));
item.setAttribute("type", "checkbox");
if (selected) {
if (options.selected) {
item.setAttribute("checked", true);
}
// The auto-checking of menuitems in this menu doesn't work, so let's do
// it manually
item.setAttribute("autocheck", false);
this._allTabsBtn.querySelector("menupopup").appendChild(item);
let menu = this._allTabsBtn.querySelector("menupopup");
if (options.insertBefore) {
let referenceItem = menu.querySelector(`#${idPrefix}${options.insertBefore}`);
menu.insertBefore(item, referenceItem);
} else {
menu.appendChild(item);
}
item.addEventListener("click", () => {
this._tabbox.selectedTab = tab;
@ -210,10 +219,14 @@ ToolSidebar.prototype = {
* Register a tab. A tab is a document.
* The document must have a title, which will be used as the name of the tab.
*
* @param {string} tab uniq id
* @param {string} url
* @param {string} id The unique id for this tab.
* @param {string} url The URL of the document to load in this new tab.
* @param {Object} options A set of options for this new tab:
* - {Boolean} selected Set to true to make this new tab selected by default.
* - {String} insertBefore By default, the new tab is appended at the end of the
* tabbox, pass the ID of an existing tab to insert it before that tab instead.
*/
addTab: function (id, url, selected = false) {
addTab: function (id, url, options = {}) {
let iframe = this._panelDoc.createElementNS(XULNS, "iframe");
iframe.className = "iframe-" + id;
iframe.setAttribute("flex", "1");
@ -222,13 +235,21 @@ ToolSidebar.prototype = {
// Creating the tab and adding it to the tabbox
let tab = this._panelDoc.createElementNS(XULNS, "tab");
this._tabbox.tabs.appendChild(tab);
tab.setAttribute("label", ""); // Avoid showing "undefined" while the tab is loading
tab.setAttribute("id", this.TAB_ID_PREFIX + id);
tab.setAttribute("crop", "end");
// Avoid showing "undefined" while the tab is loading
tab.setAttribute("label", "");
if (options.insertBefore) {
let referenceTab = this.getTab(options.insertBefore);
this._tabbox.tabs.insertBefore(tab, referenceTab);
} else {
this._tabbox.tabs.appendChild(tab);
}
// Add the tab to the allTabs menu if exists
let allTabsItem = this._addItemToAllTabsMenu(id, tab, selected);
let allTabsItem = this._addItemToAllTabsMenu(id, tab, options);
let onIFrameLoaded = (event) => {
let doc = event.target;
@ -251,7 +272,13 @@ ToolSidebar.prototype = {
let tabpanel = this._panelDoc.createElementNS(XULNS, "tabpanel");
tabpanel.setAttribute("id", this.TABPANEL_ID_PREFIX + id);
tabpanel.appendChild(iframe);
this._tabbox.tabpanels.appendChild(tabpanel);
if (options.insertBefore) {
let referenceTabpanel = this.getTabPanel(options.insertBefore);
this._tabbox.tabpanels.insertBefore(tabpanel, referenceTabpanel);
} else {
this._tabbox.tabpanels.appendChild(tabpanel);
}
this._tooltip = this._panelDoc.createElementNS(XULNS, "tooltip");
this._tooltip.id = "aHTMLTooltip";
@ -263,7 +290,7 @@ ToolSidebar.prototype = {
// We store the index of this tab.
this._tabs.set(id, tab);
if (selected) {
if (options.selected) {
this._selectTabSoon(id);
}

View File

@ -83,7 +83,7 @@ function test() {
allTabsReady(panel);
});
panel.sidebar.addTab("tab1", tab1URL, true);
panel.sidebar.addTab("tab1", tab1URL, {selected: true});
panel.sidebar.addTab("tab2", tab2URL);
panel.sidebar.addTab("tab3", tab3URL);

View File

@ -67,7 +67,7 @@ function test() {
});
panel.sidebar.once("tab1-selected", () => finishUp(panel));
panel.sidebar.addTab("tab1", tab1URL, true);
panel.sidebar.addTab("tab1", tab1URL, {selected: true});
panel.sidebar.show();
}).then(null, console.error);
});

View File

@ -48,7 +48,7 @@ add_task(function* () {
info("Adding 10 tabs to the sidebar widget");
for (let nb = 0; nb < 10; nb++) {
let url = `data:text/html;charset=utf8,<title>tab ${nb}</title><p>Test tab ${nb}</p>`;
sidebar.addTab("tab" + nb, url, nb === 0);
sidebar.addTab("tab" + nb, url, {selected: nb === 0});
}
info("Fake an overflow event so that the all-tabs menu is visible");

View File

@ -194,7 +194,7 @@ function CssComputedView(inspector, document, pageStyle) {
this.searchClearButton.hidden = true;
// No results text.
this.noResults = this.styleDocument.getElementById("noResults");
this.noResults = this.styleDocument.getElementById("computedview-no-results");
// Refresh panel when color unit changed.
this._handlePrefChange = this._handlePrefChange.bind(this);

View File

@ -34,6 +34,7 @@ support-files =
[browser_computed_search-filter_context-menu.js]
subsuite = clipboard
[browser_computed_search-filter_escape-keypress.js]
[browser_computed_search-filter_noproperties.js]
[browser_computed_select-and-copy-styles.js]
subsuite = clipboard
[browser_computed_style-editor-link.js]

View File

@ -0,0 +1,61 @@
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Tests that the "no-results" message is displayed when selecting an invalid element or
// when all properties have been filtered out.
const TEST_URI = `
<style type="text/css">
.matches {
color: #F00;
background-color: #00F;
border-color: #0F0;
}
</style>
<div>
<!-- comment node -->
<span id="matches" class="matches">Some styled text</span>
</div>
`;
add_task(function* () {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let {inspector, view} = yield openComputedView();
let propertyViews = view.propertyViews;
info("Select the #matches node");
let matchesNode = yield getNodeFront("#matches", inspector);
let onRefresh = inspector.once("computed-view-refreshed");
yield selectNode(matchesNode, inspector);
yield onRefresh;
ok(propertyViews.filter(p => p.visible).length > 0, "CSS properties are displayed");
ok(view.noResults.hasAttribute("hidden"), "no-results message is hidden");
info("Select a comment node");
let commentNode = yield inspector.walker.previousSibling(matchesNode);
yield selectNode(commentNode, inspector);
is(propertyViews.filter(p => p.visible).length, 0, "No properties displayed");
ok(!view.noResults.hasAttribute("hidden"), "no-results message is displayed");
info("Select the #matches node again");
onRefresh = inspector.once("computed-view-refreshed");
yield selectNode(matchesNode, inspector);
yield onRefresh;
ok(propertyViews.filter(p => p.visible).length > 0, "CSS properties are displayed");
ok(view.noResults.hasAttribute("hidden"), "no-results message is hidden");
info("Filter by 'will-not-match' and check the no-results message is displayed");
let searchField = view.searchField;
searchField.focus();
synthesizeKeys("will-not-match", view.styleWindow);
yield inspector.once("computed-view-refreshed");
is(propertyViews.filter(p => p.visible).length, 0, "No properties displayed");
ok(!view.noResults.hasAttribute("hidden"), "no-results message is displayed");
});

View File

@ -383,6 +383,18 @@ InspectorPanel.prototype = {
this.searchResultsLabel.textContent = str;
},
get React() {
return this._toolbox.React;
},
get ReactDOM() {
return this._toolbox.ReactDOM;
},
get browserRequire() {
return this._toolbox.browserRequire;
},
/**
* Build the sidebar.
*/
@ -407,19 +419,19 @@ InspectorPanel.prototype = {
this.ruleview = new RuleViewTool(this, this.panelWin);
this.computedview = new ComputedViewTool(this, this.panelWin);
if (Services.prefs.getBoolPref("devtools.fontinspector.enabled") &&
this.canGetUsedFontFaces) {
this.fontInspector = new FontInspector(this, this.panelWin);
this.sidebar.toggleTab(true, "fontinspector");
}
this.layoutview = new LayoutView(this, this.panelWin);
if (this.target.form.animationsActor) {
this.sidebar.addTab("animationinspector",
"chrome://devtools/content/animationinspector/animation-inspector.xhtml",
defaultTab == "animationinspector");
{selected: defaultTab == "animationinspector",
insertBefore: "fontinspector"});
}
if (Services.prefs.getBoolPref("devtools.fontinspector.enabled") &&
this.canGetUsedFontFaces) {
this.fontInspector = new FontInspector(this, this.panelWin);
this.sidebar.toggleTab(true, "fontinspector");
}
this.sidebar.show(defaultTab);
@ -431,11 +443,18 @@ InspectorPanel.prototype = {
* Add the expand/collapse behavior for the sidebar panel.
*/
setupSidebarToggle: function () {
this._paneToggleButton = this.panelDoc.getElementById("inspector-pane-toggle");
this._paneToggleButton.setAttribute("tooltiptext",
strings.GetStringFromName("inspector.collapsePane"));
this._paneToggleButton.addEventListener("mousedown",
this.onPaneToggleButtonClicked);
let SidebarToggle = this.React.createFactory(this.browserRequire(
"devtools/client/shared/components/sidebar-toggle"));
let sidebarToggle = SidebarToggle({
onClick: this.onPaneToggleButtonClicked,
collapsed: false,
expandPaneTitle: strings.GetStringFromName("inspector.expandPane"),
collapsePaneTitle: strings.GetStringFromName("inspector.collapsePane"),
});
let parentBox = this.panelDoc.getElementById("inspector-sidebar-toggle-box");
this._sidebarToggle = this.ReactDOM.render(sidebarToggle, parentBox);
},
/**
@ -689,9 +708,6 @@ InspectorPanel.prototype = {
this.addNodeButton.removeEventListener("click", this.addNode);
this.breadcrumbs.destroy();
this._paneToggleButton.removeEventListener("mousedown",
this.onPaneToggleButtonClicked);
this._paneToggleButton = null;
this.selection.off("new-node-front", this.onNewSelection);
this.selection.off("before-new-node", this.onBeforeNewSelection);
this.selection.off("before-new-node-front", this.onBeforeNewSelection);
@ -1143,8 +1159,7 @@ InspectorPanel.prototype = {
*/
onPaneToggleButtonClicked: function (e) {
let sidePane = this.panelDoc.querySelector("#inspector-sidebar");
let button = this._paneToggleButton;
let isVisible = !button.hasAttribute("pane-collapsed");
let isVisible = !this._sidebarToggle.state.collapsed;
// Make sure the sidebar has width and height attributes before collapsing
// because ViewHelpers needs it.
@ -1165,11 +1180,9 @@ InspectorPanel.prototype = {
}, sidePane);
if (isVisible) {
button.setAttribute("pane-collapsed", "");
button.setAttribute("tooltiptext", strings.GetStringFromName("inspector.expandPane"));
this._sidebarToggle.setState({collapsed: true});
} else {
button.removeAttribute("pane-collapsed");
button.setAttribute("tooltiptext", strings.GetStringFromName("inspector.collapsePane"));
this._sidebarToggle.setState({collapsed: false});
}
},

View File

@ -32,4 +32,8 @@
* Override `-moz-user-focus:ignore;` from toolkit/content/minimal-xul.css
*/
-moz-user-focus: normal;
}
}
#inspector-sidebar-toggle-box {
line-height: initial;
}

View File

@ -11,6 +11,7 @@
<?xml-stylesheet href="chrome://devtools/skin/computed.css" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/skin/fonts.css" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/skin/layout.css" type="text/css"?>
<?xml-stylesheet href="resource://devtools/client/shared/components/sidebar-toggle.css" type="text/css"?>
<!DOCTYPE window [
<!ENTITY % inspectorDTD SYSTEM "chrome://devtools/locale/inspector.dtd"> %inspectorDTD;
@ -39,9 +40,8 @@
timeout="50"
class="devtools-searchinput"
placeholder="&inspectorSearchHTML.label3;"/>
<html:button id="inspector-pane-toggle"
class="devtools-button"
tabindex="0" />
<div xmlns="http://www.w3.org/1999/xhtml"
id="inspector-sidebar-toggle-box" />
</html:div>
<vbox flex="1" id="markup-box">
</vbox>
@ -58,13 +58,13 @@
<tab id="sidebar-tab-computedview"
label="&computedViewTitle;"
crop="end"/>
<tab id="sidebar-tab-layoutview"
label="&layoutViewTitle;"
crop="end"/>
<tab id="sidebar-tab-fontinspector"
label="&fontInspectorTitle;"
crop="end"
hidden="true"/>
<tab id="sidebar-tab-layoutview"
label="&layoutViewTitle;"
crop="end"/>
</tabs>
<tabpanels flex="1">
<tabpanel id="sidebar-panel-ruleview" class="devtools-monospace theme-sidebar inspector-tabpanel">
@ -111,46 +111,11 @@
<html:div id="propertyContainer">
</html:div>
<html:div id="noResults" hidden="">
<html:div id="computedview-no-results" hidden="">
&noPropertiesFound;
</html:div>
</tabpanel>
<tabpanel id="sidebar-panel-fontinspector" class="devtools-monospace theme-sidebar inspector-tabpanel">
<html:div class="devtools-toolbar">
<html:div class="devtools-searchbox">
<html:input id="font-preview-text-input"
class="devtools-textinput"
type="search"
placeholder="&previewHint;"/>
</html:div>
</html:div>
<html:div id="font-container">
<html:ul id="all-fonts"></html:ul>
<html:button id="font-showall">&showAllFonts;</html:button>
</html:div>
<html:div id="font-template">
<html:section class="font">
<html:div class="font-preview-container">
<html:img class="font-preview"></html:img>
</html:div>
<html:div class="font-info">
<html:h1 class="font-name"></html:h1>
<html:span class="font-is-local">&system;</html:span>
<html:span class="font-is-remote">&remote;</html:span>
<html:p class="font-format-url">
<html:input readonly="readonly" class="font-url"></html:input>
<html:span class="font-format"></html:span>
</html:p>
<html:p class="font-css">&usedAs; "<html:span class="font-css-name"></html:span>"</html:p>
<html:pre class="font-css-code"></html:pre>
</html:div>
</html:section>
</html:div>
</tabpanel>
<tabpanel id="sidebar-panel-layoutview" class="devtools-monospace theme-sidebar inspector-tabpanel">
<html:div id="layout-wrapper">
<html:div id="layout-container">
@ -199,6 +164,41 @@
</html:div>
</html:div>
</tabpanel>
<tabpanel id="sidebar-panel-fontinspector" class="devtools-monospace theme-sidebar inspector-tabpanel">
<html:div class="devtools-toolbar">
<html:div class="devtools-searchbox">
<html:input id="font-preview-text-input"
class="devtools-textinput"
type="search"
placeholder="&previewHint;"/>
</html:div>
</html:div>
<html:div id="font-container">
<html:ul id="all-fonts"></html:ul>
<html:button id="font-showall">&showAllFonts;</html:button>
</html:div>
<html:div id="font-template">
<html:section class="font">
<html:div class="font-preview-container">
<html:img class="font-preview"></html:img>
</html:div>
<html:div class="font-info">
<html:h1 class="font-name"></html:h1>
<html:span class="font-is-local">&system;</html:span>
<html:span class="font-is-remote">&remote;</html:span>
<html:p class="font-format-url">
<html:input readonly="readonly" class="font-url"></html:input>
<html:span class="font-format"></html:span>
</html:p>
<html:p class="font-css">&usedAs; "<html:span class="font-css-name"></html:span>"</html:p>
<html:pre class="font-css-code"></html:pre>
</html:div>
</html:section>
</html:div>
</tabpanel>
</tabpanels>
</tabbox>
</box>

View File

@ -962,12 +962,12 @@ CssRuleView.prototype = {
* Show the user that the rule view has no node selected.
*/
_showEmpty: function () {
if (this.styleDocument.getElementById("noResults") > 0) {
if (this.styleDocument.getElementById("ruleview-no-results")) {
return;
}
createChild(this.element, "div", {
id: "noResults",
id: "ruleview-no-results",
textContent: l10n("rule.empty")
});
},

View File

@ -26,11 +26,11 @@ add_task(function* () {
let {inspector, view} = yield openRuleView();
yield selectNode("#testid", inspector);
is(view.element.querySelectorAll("#noResults").length, 0,
is(view.element.querySelectorAll("#ruleview-no-results").length, 0,
"After a highlight, no longer has a no-results element.");
yield clearCurrentNodeSelection(inspector);
is(view.element.querySelectorAll("#noResults").length, 1,
is(view.element.querySelectorAll("#ruleview-no-results").length, 1,
"After highlighting null, has a no-results element again.");
yield selectNode("#testid", inspector);

View File

@ -10,18 +10,18 @@ add_task(function* () {
info("Open the inspector in a bottom toolbox host");
let {toolbox, inspector} = yield openInspectorForURL("about:blank", "bottom");
let button = inspector.panelDoc.getElementById("inspector-pane-toggle");
let button = inspector.panelDoc.querySelector(".sidebar-toggle");
ok(button, "The toggle button exists in the DOM");
is(button.parentNode.id, "inspector-toolbar",
"The toggle button is in the toolbar");
ok(button.getAttribute("tooltiptext"), "The tool tip has initial state");
ok(!button.hasAttribute("pane-collapsed"), "The button is in expanded state");
is(button.parentNode.id, "inspector-sidebar-toggle-box",
"The toggle button has the right parent");
ok(button.getAttribute("title"), "The tool tip has initial state");
ok(!button.classList.contains("pane-collapsed"), "The button is in expanded state");
ok(!!button.getClientRects().length, "The button is visible");
info("Switch the host to side type");
yield toolbox.switchHost("side");
ok(!!button.getClientRects().length, "The button is still visible");
ok(!button.hasAttribute("pane-collapsed"),
ok(!button.classList.contains("pane-collapsed"),
"The button is still in expanded state");
});

View File

@ -12,31 +12,31 @@ add_task(function* () {
let {toolbox, inspector} = yield openInspectorForURL("about:blank", "side");
let panel = inspector.panelDoc.querySelector("#inspector-sidebar");
let button = inspector.panelDoc.getElementById("inspector-pane-toggle");
ok(!panel.hasAttribute("pane-collapsed"), "The panel is in expanded state");
let button = inspector.panelDoc.querySelector(".sidebar-toggle");
ok(!panel.classList.contains("pane-collapsed"), "The panel is in expanded state");
info("Listen to the end of the animation on the sidebar panel");
let onTransitionEnd = once(panel, "transitionend");
info("Click on the toggle button");
EventUtils.synthesizeMouseAtCenter(button, {type: "mousedown"},
EventUtils.synthesizeMouseAtCenter(button, {},
inspector.panelDoc.defaultView);
yield onTransitionEnd;
ok(panel.hasAttribute("pane-collapsed"), "The panel is in collapsed state");
ok(panel.classList.contains("pane-collapsed"), "The panel is in collapsed state");
ok(!panel.hasAttribute("animated"),
"The collapsed panel will not perform unwanted animations");
info("Switch the host to bottom type");
yield toolbox.switchHost("bottom");
ok(panel.hasAttribute("pane-collapsed"), "The panel is in collapsed state");
ok(panel.classList.contains("pane-collapsed"), "The panel is in collapsed state");
info("Click on the toggle button to expand the panel again");
onTransitionEnd = once(panel, "transitionend");
EventUtils.synthesizeMouseAtCenter(button, {type: "mousedown"},
EventUtils.synthesizeMouseAtCenter(button, {},
inspector.panelDoc.defaultView);
yield onTransitionEnd;
ok(!panel.hasAttribute("pane-collapsed"), "The panel is in expanded state");
ok(!panel.classList.contains("pane-collapsed"), "The panel is in expanded state");
});

View File

@ -9,30 +9,30 @@
add_task(function* () {
let {inspector} = yield openInspectorForURL("about:blank");
let button = inspector.panelDoc.getElementById("inspector-pane-toggle");
let button = inspector.panelDoc.querySelector(".sidebar-toggle");
let panel = inspector.panelDoc.querySelector("#inspector-sidebar");
ok(!button.hasAttribute("pane-collapsed"), "The button is in expanded state");
ok(!button.classList.contains("pane-collapsed"), "The button is in expanded state");
info("Listen to the end of the animation on the sidebar panel");
let onTransitionEnd = once(panel, "transitionend");
info("Click on the toggle button");
EventUtils.synthesizeMouseAtCenter(button, {type: "mousedown"},
EventUtils.synthesizeMouseAtCenter(button, {},
inspector.panelDoc.defaultView);
yield onTransitionEnd;
ok(button.hasAttribute("pane-collapsed"), "The button is in collapsed state");
ok(panel.hasAttribute("pane-collapsed"), "The panel is in collapsed state");
ok(button.classList.contains("pane-collapsed"), "The button is in collapsed state");
ok(panel.classList.contains("pane-collapsed"), "The panel is in collapsed state");
info("Listen again to the end of the animation on the sidebar panel");
onTransitionEnd = once(panel, "transitionend");
info("Click on the toggle button again");
EventUtils.synthesizeMouseAtCenter(button, {type: "mousedown"},
EventUtils.synthesizeMouseAtCenter(button, {},
inspector.panelDoc.defaultView);
yield onTransitionEnd;
ok(!button.hasAttribute("pane-collapsed"), "The button is in expanded state");
ok(!panel.hasAttribute("pane-collapsed"), "The panel is in expanded state");
ok(!button.classList.contains("pane-collapsed"), "The button is in expanded state");
ok(!panel.classList.contains("pane-collapsed"), "The panel is in expanded state");
});

View File

@ -19,7 +19,7 @@ add_task(function* () {
});
let { inspector, toolbox } = yield openInspectorForURL("about:blank");
let button = inspector.panelDoc.getElementById("inspector-pane-toggle");
let button = inspector.panelDoc.querySelector(".sidebar-toggle");
let panel = inspector.panelDoc.querySelector("#inspector-sidebar");
info("Changing toolbox host to a window.");
@ -33,15 +33,15 @@ add_task(function* () {
hostWindow.resizeTo(800, 300);
// Check the sidebar is expanded when the test starts.
ok(!panel.hasAttribute("pane-collapsed"), "The panel is in expanded state");
ok(!panel.classList.contains("pane-collapsed"), "The panel is in expanded state");
info("Collapse the inspector sidebar.");
let onTransitionEnd = once(panel, "transitionend");
EventUtils.synthesizeMouseAtCenter(button, {type: "mousedown"},
EventUtils.synthesizeMouseAtCenter(button, {},
inspector.panelDoc.defaultView);
yield onTransitionEnd;
ok(panel.hasAttribute("pane-collapsed"), "The panel is in collapsed state");
ok(panel.classList.contains("pane-collapsed"), "The panel is in collapsed state");
let currentPanelHeight = panel.getBoundingClientRect().height;
let currentPanelMarginBottom = panel.style.marginBottom;
@ -49,7 +49,7 @@ add_task(function* () {
hostWindow.resizeTo(300, 800);
// Check the panel is collapsed, and still has the same dimensions.
ok(panel.hasAttribute("pane-collapsed"), "The panel is still collapsed");
ok(panel.classList.contains("pane-collapsed"), "The panel is still collapsed");
is(panel.getBoundingClientRect().height, currentPanelHeight,
"The panel height has not been modified when changing the layout.");
is(panel.style.marginBottom, currentPanelMarginBottom,

View File

@ -250,7 +250,7 @@ var NetMonitorView = {
* @return boolean
*/
get detailsPaneHidden() {
return this._detailsPane.hasAttribute("pane-collapsed");
return this._detailsPane.classList.contains("pane-collapsed");
},
/**
@ -272,12 +272,12 @@ var NetMonitorView = {
ViewHelpers.togglePane(flags, pane);
if (flags.visible) {
this._body.removeAttribute("pane-collapsed");
button.removeAttribute("pane-collapsed");
this._body.classList.remove("pane-collapsed");
button.classList.remove("pane-collapsed");
button.setAttribute("tooltiptext", this._collapsePaneString);
} else {
this._body.setAttribute("pane-collapsed", "");
button.setAttribute("pane-collapsed", "");
this._body.classList.add("pane-collapsed");
button.classList.add("pane-collapsed");
button.setAttribute("tooltiptext", this._expandPaneString);
}

View File

@ -36,7 +36,7 @@
@media (max-width: 700px) {
#toolbar-spacer,
#details-pane-toggle,
#details-pane[pane-collapsed],
#details-pane.pane-collapsed,
.requests-menu-waterfall,
#requests-menu-network-summary-button > .toolbarbutton-text {
display: none;

View File

@ -34,15 +34,15 @@ function test() {
// Make sure we can now open the details pane
NetMonitorView.toggleDetailsPane({ visible: true, animated: false });
ok(!detailsPane.hasAttribute("pane-collapsed") &&
!detailsPaneToggleButton.hasAttribute("pane-collapsed"),
ok(!detailsPane.classList.contains("pane-collapsed") &&
!detailsPaneToggleButton.classList.contains("pane-collapsed"),
"The details pane should be visible after clicking the toggle button.");
// Click clear and make sure the details pane closes
EventUtils.sendMouseEvent({ type: "click" }, clearButton);
assertNoRequestState(RequestsMenu, detailsPaneToggleButton);
ok(detailsPane.hasAttribute("pane-collapsed") &&
detailsPaneToggleButton.hasAttribute("pane-collapsed"),
ok(detailsPane.classList.contains("pane-collapsed") &&
detailsPaneToggleButton.classList.contains("pane-collapsed"),
"The details pane should not be visible clicking 'clear'.");
teardown(aMonitor).then(finish);

View File

@ -13,8 +13,8 @@ function test() {
let detailsPane = document.getElementById("details-pane");
let detailsPaneToggleButton = document.getElementById("details-pane-toggle");
ok(detailsPane.hasAttribute("pane-collapsed") &&
detailsPaneToggleButton.hasAttribute("pane-collapsed"),
ok(detailsPane.classList.contains("pane-collapsed") &&
detailsPaneToggleButton.classList.contains("pane-collapsed"),
"The details pane should initially be hidden.");
NetMonitorView.toggleDetailsPane({ visible: true, animated: false });
@ -28,8 +28,8 @@ function test() {
"The details pane has an incorrect right margin.");
ok(!detailsPane.hasAttribute("animated"),
"The details pane has an incorrect animated attribute.");
ok(!detailsPane.hasAttribute("pane-collapsed") &&
!detailsPaneToggleButton.hasAttribute("pane-collapsed"),
ok(!detailsPane.classList.contains("pane-collapsed") &&
!detailsPaneToggleButton.classList.contains("pane-collapsed"),
"The details pane should at this point be visible.");
NetMonitorView.toggleDetailsPane({ visible: false, animated: true });
@ -43,8 +43,8 @@ function test() {
"The details pane has an incorrect right margin after collapsing.");
ok(detailsPane.hasAttribute("animated"),
"The details pane has an incorrect attribute after an animated collapsing.");
ok(detailsPane.hasAttribute("pane-collapsed") &&
detailsPaneToggleButton.hasAttribute("pane-collapsed"),
ok(detailsPane.classList.contains("pane-collapsed") &&
detailsPaneToggleButton.classList.contains("pane-collapsed"),
"The details pane should not be visible after collapsing.");
NetMonitorView.toggleDetailsPane({ visible: true, animated: false });
@ -57,8 +57,8 @@ function test() {
"The details pane has an incorrect right margin after uncollapsing.");
ok(!detailsPane.hasAttribute("animated"),
"The details pane has an incorrect attribute after an unanimated uncollapsing.");
ok(!detailsPane.hasAttribute("pane-collapsed") &&
!detailsPaneToggleButton.hasAttribute("pane-collapsed"),
ok(!detailsPane.classList.contains("pane-collapsed") &&
!detailsPaneToggleButton.classList.contains("pane-collapsed"),
"The details pane should be visible again after uncollapsing.");
teardown(aMonitor).then(finish);

View File

@ -18,7 +18,7 @@ function test() {
.hasAttribute("disabled"), true,
"The pane toggle button should be disabled when the frontend is opened.");
is(document.querySelector("#details-pane-toggle")
.hasAttribute("pane-collapsed"), true,
.classList.contains("pane-collapsed"), true,
"The pane toggle button should indicate that the details pane is " +
"collapsed when the frontend is opened.");
is(NetMonitorView.detailsPaneHidden, true,
@ -31,7 +31,7 @@ function test() {
.hasAttribute("disabled"), false,
"The pane toggle button should be enabled after the first request.");
is(document.querySelector("#details-pane-toggle")
.hasAttribute("pane-collapsed"), true,
.classList.contains("pane-collapsed"), true,
"The pane toggle button should still indicate that the details pane is " +
"collapsed after the first request.");
is(NetMonitorView.detailsPaneHidden, true,
@ -46,7 +46,7 @@ function test() {
.hasAttribute("disabled"), false,
"The pane toggle button should still be enabled after being pressed.");
is(document.querySelector("#details-pane-toggle")
.hasAttribute("pane-collapsed"), false,
.classList.contains("pane-collapsed"), false,
"The pane toggle button should now indicate that the details pane is " +
"not collapsed anymore after being pressed.");
is(NetMonitorView.detailsPaneHidden, false,
@ -63,7 +63,7 @@ function test() {
.hasAttribute("disabled"), false,
"The pane toggle button should still be enabled after being pressed again.");
is(document.querySelector("#details-pane-toggle")
.hasAttribute("pane-collapsed"), true,
.classList.contains("pane-collapsed"), true,
"The pane toggle button should now indicate that the details pane is " +
"collapsed after being pressed again.");
is(NetMonitorView.detailsPaneHidden, true,

View File

@ -323,7 +323,7 @@ pref("devtools.editor.enableCodeFolding", true);
pref("devtools.editor.autocomplete", true);
// Enable the Font Inspector
pref("devtools.fontinspector.enabled", false);
pref("devtools.fontinspector.enabled", true);
// Pref to store the browser version at the time of a telemetry ping for an
// opened developer tool. This allows us to ping telemetry just once per browser

View File

@ -706,7 +706,7 @@ var ProjectEditor = Class({
},
get sourcesVisible() {
return this.sourceToggle.hasAttribute("pane-collapsed");
return this.sourceToggle.classList.contains("pane-collapsed");
},
get currentShell() {

View File

@ -2309,7 +2309,7 @@ ScratchpadSidebar.prototype = {
}
else {
this._sidebar.once("variablesview-ready", onTabReady);
this._sidebar.addTab("variablesview", VARIABLES_VIEW_URL, true);
this._sidebar.addTab("variablesview", VARIABLES_VIEW_URL, {selected: true});
}
return deferred.promise;

View File

@ -15,6 +15,8 @@ DevToolsModules(
'h-split-box.js',
'notification-box.css',
'notification-box.js',
'sidebar-toggle.css',
'sidebar-toggle.js',
'stack-trace.js',
'tree.js',
)

View File

@ -50,16 +50,13 @@ define(function (require, exports, module) {
return items;
}
let provider = this.props.provider;
if (!provider) {
return items;
}
let delim;
let provider = this.props.provider;
for (let i = 0; i < array.length && i <= max; i++) {
try {
let value = provider.getValue(array[i]);
let itemGrip = array[i];
let value = provider ? provider.getValue(itemGrip) : itemGrip;
delim = (i == array.length - 1 ? "" : ", ");

View File

@ -0,0 +1,24 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* 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/. */
.sidebar-toggle {
display: block;
}
.sidebar-toggle::before {
background-image: var(--theme-pane-collapse-image);
}
.sidebar-toggle.pane-collapsed::before {
background-image: var(--theme-pane-expand-image);
}
/* Rotate button icon 90deg if the toolbox container is
in vertical mode (sidebar displayed under the main panel) */
@media (max-width: 700px) {
.sidebar-toggle::before {
transform: rotate(90deg);
}
}

View File

@ -0,0 +1,66 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { DOM, createClass, PropTypes } = require("devtools/client/shared/vendor/react");
// Shortcuts
const { button } = DOM;
/**
* Sidebar toggle button. This button is used to exapand
* and collapse Sidebar.
*/
var SidebarToggle = createClass({
displayName: "SidebarToggle",
propTypes: {
// Set to true if collapsed.
collapsed: PropTypes.bool.isRequired,
// Tooltip text used when the button indicates expanded state.
collapsePaneTitle: PropTypes.string.isRequired,
// Tooltip text used when the button indicates collapsed state.
expandPaneTitle: PropTypes.string.isRequired,
// Click callback
onClick: PropTypes.func.isRequired,
},
getInitialState: function () {
return {
collapsed: this.props.collapsed,
};
},
// Events
onClick: function (event) {
this.props.onClick(event);
},
// Rendering
render: function () {
let title = this.state.collapsed ?
this.props.expandPaneTitle :
this.props.collapsePaneTitle;
let classNames = ["devtools-button", "sidebar-toggle"];
if (this.state.collapsed) {
classNames.push("pane-collapsed");
}
return (
button({
className: classNames.join(" "),
title: title,
onClick: this.onClick
})
);
}
});
module.exports = SidebarToggle;

View File

@ -2,6 +2,7 @@
support-files =
head.js
[test_frame_01.html]
[test_HSplitBox_01.html]
[test_notification_box_01.html]
[test_notification_box_02.html]
@ -11,12 +12,13 @@ support-files =
[test_reps_function.html]
[test_reps_grip.html]
[test_reps_null.html]
[test_reps_number.html]
[test_reps_object-with-text.html]
[test_reps_object-with-url.html]
[test_reps_stylesheet.html]
[test_reps_undefined.html]
[test_reps_window.html]
[test_frame_01.html]
[test_sidebar_toggle.html]
[test_tree_01.html]
[test_tree_02.html]
[test_tree_03.html]

View File

@ -0,0 +1,75 @@
<!DOCTYPE HTML>
<html>
<!--
Test Number rep
-->
<head>
<meta charset="utf-8">
<title>Rep test - Number</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
</head>
<body>
<pre id="test">
<script src="head.js" type="application/javascript;version=1.8"></script>
<script type="application/javascript;version=1.8">
window.onload = Task.async(function* () {
let { Rep } = browserRequire("devtools/client/shared/components/reps/rep");
let { Number } = browserRequire("devtools/client/shared/components/reps/number");
try {
yield testInt();
yield testBoolean();
yield testUnsafeInt();
} catch(e) {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
} finally {
SimpleTest.finish();
}
function testInt() {
const renderedRep = shallowRenderComponent(Rep, { object: getGripStub("testInt") });
is(renderedRep.type, Number.rep, `Rep correctly selects ${Number.rep.displayName} for integer value`);
const renderedComponent = renderComponent(Number.rep, { object: getGripStub("testInt") });
is(renderedComponent.textContent, "5", "Number rep has expected text content for integer");
}
function testBoolean() {
const renderedRep = shallowRenderComponent(Rep, { object: getGripStub("testTrue") });
is(renderedRep.type, Number.rep, `Rep correctly selects ${Number.rep.displayName} for boolean value`);
let renderedComponent = renderComponent(Number.rep, { object: getGripStub("testTrue") });
is(renderedComponent.textContent, "true", "Number rep has expected text content for boolean true");
renderedComponent = renderComponent(Number.rep, { object: getGripStub("testFalse") });
is(renderedComponent.textContent, "false", "Number rep has expected text content for boolean false");
}
function testUnsafeInt() {
const renderedComponent = renderComponent(Number.rep, { object: getGripStub("testUnsafeInt") });
is(renderedComponent.textContent, "900719925474099100", "Number rep has expected text content for a long number");
}
function getGripStub(name) {
switch (name) {
case "testInt":
return 5;
case "testTrue":
return true;
case "testFalse":
return false;
case "testUnsafeInt":
return 900719925474099122;
}
}
});
</script>
</pre>
</body>
</html>

View File

@ -0,0 +1,53 @@
<!DOCTYPE HTML>
<html>
<!--
Test sidebar toggle button
-->
<head>
<meta charset="utf-8">
<title>Sidebar toggle button test</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
</head>
<body>
<pre id="test">
<script src="head.js" type="application/javascript;version=1.8"></script>
<script type="application/javascript;version=1.8">
window.onload = Task.async(function* () {
let SidebarToggle = browserRequire("devtools/client/shared/components/sidebar-toggle.js");
try {
yield test();
} catch(e) {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
} finally {
SimpleTest.finish();
}
function test() {
const output1 = shallowRenderComponent(SidebarToggle, {
collapsed: false,
collapsePaneTitle: "Expand",
expandPaneTitle: "Collapse"
});
is(output1.type, "button", "Output is a button element");
is(output1.props.title, "Expand", "Proper title is set");
is(output1.props.className.indexOf("pane-collapsed"), -1,
"Proper class name is set");
const output2 = shallowRenderComponent(SidebarToggle, {
collapsed: true,
collapsePaneTitle: "Expand",
expandPaneTitle: "Collapse"
});
is(output2.props.title, "Collapse", "Proper title is set");
ok(output2.props.className.indexOf("pane-collapsed") >= 0,
"Proper class name is set");
}
});
</script>
</pre>
</body>
</html>

View File

@ -534,7 +534,8 @@ DeveloperToolbar.prototype.show = function (focus) {
if (!DeveloperToolbar.introShownThisSession) {
let intro = require("gcli/ui/intro");
intro.maybeShowIntro(this.requisition.commandOutputManager,
this.requisition.conversionContext);
this.requisition.conversionContext,
this.outputPanel);
DeveloperToolbar.introShownThisSession = true;
}

View File

@ -800,7 +800,7 @@ TableWidget.prototype = {
* Removes the row associated with the `item` object.
*/
remove: function (item) {
if (typeof item == "string") {
if (typeof item != "object") {
item = this.items.get(item);
}
if (!item) {

View File

@ -244,7 +244,7 @@ const ViewHelpers = exports.ViewHelpers = {
pane.classList.add("generic-toggled-pane");
// Avoid useless toggles.
if (flags.visible == !pane.hasAttribute("pane-collapsed")) {
if (flags.visible == !pane.classList.contains("pane-collapsed")) {
if (flags.callback) {
flags.callback();
}
@ -267,14 +267,14 @@ const ViewHelpers = exports.ViewHelpers = {
pane.style.marginLeft = "0";
pane.style.marginRight = "0";
pane.style.marginBottom = "0";
pane.removeAttribute("pane-collapsed");
pane.classList.remove("pane-collapsed");
} else {
let width = Math.floor(pane.getAttribute("width")) + 1;
let height = Math.floor(pane.getAttribute("height")) + 1;
pane.style.marginLeft = -width + "px";
pane.style.marginRight = -width + "px";
pane.style.marginBottom = -height + "px";
pane.setAttribute("pane-collapsed", "");
pane.classList.add("pane-collapsed");
}
// Wait for the animation to end before calling afterToggle()

View File

@ -14,7 +14,9 @@ const TEST_CASES = [
[["sessionStorage", "http://test1.example.org"],
"ss1", "name"],
[["cookies", "test1.example.org"],
"c1", "name"]
"c1", "name"],
[["indexedDB", "http://test1.example.org", "idb1", "obj1"],
1, "name"]
];
add_task(function* () {
@ -23,18 +25,19 @@ add_task(function* () {
let contextMenu = gPanelWindow.document.getElementById("storage-table-popup");
let menuDeleteItem = contextMenu.querySelector("#storage-table-popup-delete");
for (let [ [store, host], rowName, cellToClick] of TEST_CASES) {
info(`Selecting tree item ${store} > ${host}`);
yield selectTreeItem([store, host]);
for (let [ treeItem, rowName, cellToClick] of TEST_CASES) {
let treeItemName = treeItem.join(" > ");
info(`Selecting tree item ${treeItemName}`);
yield selectTreeItem(treeItem);
let row = getRowCells(rowName);
ok(gUI.table.items.has(rowName),
`There is a row '${rowName}' in ${store} > ${host}`);
ok(gUI.table.items.has(rowName), `There is a row '${rowName}' in ${treeItemName}`);
let eventWait = gUI.once("store-objects-updated");
yield waitForContextMenu(contextMenu, row[cellToClick], () => {
info(`Opened context menu in ${store} > ${host}, row '${rowName}'`);
info(`Opened context menu in ${treeItemName}, row '${rowName}'`);
menuDeleteItem.click();
ok(menuDeleteItem.getAttribute("label").includes(rowName),
`Context menu item label contains '${rowName}'`);
@ -43,7 +46,7 @@ add_task(function* () {
yield eventWait;
ok(!gUI.table.items.has(rowName),
`There is no row '${rowName}' in ${store} > ${host} after deletion`);
`There is no row '${rowName}' in ${treeItemName} after deletion`);
}
yield finishTests();

View File

@ -29,6 +29,8 @@ add_task(function* () {
["iframe-u-ss1", "iframe-u-ss2"]],
[["sessionStorage", "https://sectest1.example.org"],
["iframe-s-ss1"]],
[["indexedDB", "http://test1.example.org", "idb1", "obj1"],
[1, 2, 3]],
];
yield checkState(beforeState);
@ -37,6 +39,7 @@ add_task(function* () {
const deleteHosts = [
[["localStorage", "https://sectest1.example.org"], "iframe-s-ls1"],
[["sessionStorage", "https://sectest1.example.org"], "iframe-s-ss1"],
[["indexedDB", "http://test1.example.org", "idb1", "obj1"], 1],
];
for (let [store, rowName] of deleteHosts) {
@ -71,6 +74,8 @@ add_task(function* () {
["iframe-u-ss1", "iframe-u-ss2"]],
[["sessionStorage", "https://sectest1.example.org"],
[]],
[["indexedDB", "http://test1.example.org", "idb1", "obj1"],
[]],
];
yield checkState(afterState);

View File

@ -20,6 +20,7 @@ add_task(function* () {
[["cookies", "test1.example.org"], ["c1", "c3", "cs2", "uc1"]],
[["localStorage", "http://test1.example.org"], ["ls1", "ls2"]],
[["sessionStorage", "http://test1.example.org"], ["ss1"]],
[["indexedDB", "http://test1.example.org", "idb1", "obj1"], [1, 2, 3]],
]);
info("do the delete");
@ -27,6 +28,7 @@ add_task(function* () {
["cookies", "test1.example.org"],
["localStorage", "http://test1.example.org"],
["sessionStorage", "http://test1.example.org"],
["indexedDB", "http://test1.example.org", "idb1", "obj1"],
];
for (let store of deleteHosts) {
@ -54,6 +56,7 @@ add_task(function* () {
[["cookies", "test1.example.org"], []],
[["localStorage", "http://test1.example.org"], []],
[["sessionStorage", "http://test1.example.org"], []],
[["indexedDB", "http://test1.example.org", "idb1", "obj1"], []],
]);
yield finishTests();

View File

@ -253,15 +253,47 @@ StorageUI.prototype = {
/**
* Event handler for "stores-cleared" event coming from the storage actor.
*
* @param {object} argument0
* @param {object} response
* An object containing which storage types were cleared
*/
onCleared: function (response) {
let [type, host] = this.tree.selectedItem;
if (response.hasOwnProperty(type) && response[type].indexOf(host) > -1) {
this.table.clear();
this.hideSidebar();
this.emit("store-objects-cleared");
function* enumPaths() {
for (let type in response) {
if (Array.isArray(response[type])) {
// Handle the legacy response with array of hosts
for (let host of response[type]) {
yield [type, host];
}
} else {
// Handle the new format that supports clearing sub-stores in a host
for (let host in response[type]) {
let paths = response[type][host];
if (!paths.length) {
yield [type, host];
} else {
for (let path of paths) {
try {
path = JSON.parse(path);
yield [type, host, ...path];
} catch (ex) {
// ignore
}
}
}
}
}
}
}
for (let path of enumPaths()) {
// Find if the path is selected (there is max one) and clear it
if (this.tree.isSelected(path)) {
this.table.clear();
this.hideSidebar();
this.emit("store-objects-cleared");
break;
}
}
},
@ -813,16 +845,20 @@ StorageUI.prototype = {
/**
* Fires before a cell context menu with the "Delete" action is shown.
* If the current storage actor doesn't support removing items, prevent
* If the currently selected storage object doesn't support removing items, prevent
* showing the menu.
*/
onTablePopupShowing: function (event) {
if (!this.getCurrentActor().removeItem) {
let selectedItem = this.tree.selectedItem;
let type = selectedItem[0];
let actor = this.getCurrentActor();
// IndexedDB only supports removing items from object stores (level 4 of the tree)
if (!actor.removeItem || (type === "indexedDB" && selectedItem.length !== 4)) {
event.preventDefault();
return;
}
let [type] = this.tree.selectedItem;
let rowId = this.table.contextMenuRowId;
let data = this.table.items.get(rowId);
let name = addEllipsis(data[this.table.uniqueId]);
@ -846,13 +882,20 @@ StorageUI.prototype = {
let selectedItem = this.tree.selectedItem;
if (selectedItem) {
// this.currentActor() would return wrong value here
let actor = this.storageTypes[selectedItem[0]];
let type = selectedItem[0];
let actor = this.storageTypes[type];
// The delete all (aka clear) action is displayed for IndexedDB object stores
// (level 4 of tree) and for the whole host (level 2 of tree) of other storage
// types (cookies, localStorage, ...).
let showDeleteAll = actor.removeAll &&
(selectedItem.length === (type === "indexedDB" ? 4 : 2));
let showDeleteAll = selectedItem.length == 2 && actor.removeAll;
this._treePopupDeleteAll.hidden = !showDeleteAll;
let showDeleteDb = selectedItem.length == 3 && actor.removeDatabase;
// The action to delete database is available for IndexedDB databases, i.e.,
// at level 3 of the tree.
let showDeleteDb = actor.removeDatabase && selectedItem.length === 3;
this._treePopupDeleteDatabase.hidden = !showDeleteDb;
if (showDeleteDb) {
let dbName = addEllipsis(selectedItem[2]);
@ -872,12 +915,15 @@ StorageUI.prototype = {
* Handles removing an item from the storage
*/
onRemoveItem: function () {
let [, host] = this.tree.selectedItem;
let [, host, ...path] = this.tree.selectedItem;
let actor = this.getCurrentActor();
let rowId = this.table.contextMenuRowId;
let data = this.table.items.get(rowId);
actor.removeItem(host, data[this.table.uniqueId]);
let name = data[this.table.uniqueId];
if (path.length > 0) {
name = JSON.stringify([...path, name]);
}
actor.removeItem(host, name);
},
/**
@ -887,10 +933,10 @@ StorageUI.prototype = {
// Cannot use this.currentActor() if the handler is called from the
// tree context menu: it returns correct value only after the table
// data from server are successfully fetched (and that's async).
let [type, host] = this.tree.selectedItem;
let [type, host, ...path] = this.tree.selectedItem;
let actor = this.storageTypes[type];
actor.removeAll(host);
let name = path.length > 0 ? JSON.stringify(path) : undefined;
actor.removeAll(host, name);
},
/**

View File

@ -141,10 +141,8 @@
opacity: 0.5;
}
#noResults {
font-size: 110%;
margin: 5px;
text-align: center;
#computedview-no-results {
height: 100%;
}
.onlyuserstyles {

View File

@ -643,7 +643,7 @@
list-style-image: var(--theme-pane-collapse-image);
}
#instruments-pane-toggle[pane-collapsed] {
#instruments-pane-toggle.pane-collapsed {
list-style-image: var(--theme-pane-expand-image);
}

View File

@ -78,26 +78,17 @@
font: message-box;
}
/* Expand/collapse panel toolbar button */
#inspector-pane-toggle::before {
background-image: var(--theme-pane-collapse-image);
}
#inspector-pane-toggle[pane-collapsed]::before {
background-image: var(--theme-pane-expand-image);
}
/* Rotate button icon 90deg if the toolbox container is
in vertical mode (sidebar displayed under the main panel) */
@media (max-width: 700px) {
#inspector-pane-toggle::before {
transform: rotate(90deg);
}
}
/* Add element toolbar button */
#inspector-element-add-button::before {
background-image: url("chrome://devtools/skin/images/add.svg");
}
/* "no results" warning message displayed in the ruleview and in the computed view */
#ruleview-no-results,
#computedview-no-results {
color: var(--theme-body-color-inactive);
text-align: center;
margin: 5px;
}

View File

@ -510,7 +510,7 @@
list-style-image: var(--theme-pane-collapse-image);
}
#details-pane-toggle[pane-collapsed] {
#details-pane-toggle.pane-collapsed {
list-style-image: var(--theme-pane-expand-image);
}

View File

@ -198,8 +198,7 @@
border-left: solid 10px;
}
.ruleview-rule,
#noResults {
.ruleview-rule {
padding: 2px 4px;
}
@ -267,11 +266,6 @@
color: #CCCCCC;
}
#noResults {
font: message-box;
color: GrayText;
}
.ruleview-rule + .ruleview-rule {
border-top-width: 1px;
border-top-style: dotted;

View File

@ -149,7 +149,7 @@ text {
height: 16px;
}
#inspector-pane-toggle[pane-collapsed] {
#inspector-pane-toggle.pane-collapsed {
list-style-image: var(--theme-pane-expand-image);
}

View File

@ -186,7 +186,7 @@ a {
height: 8px;
width: 8px;
border-radius: 50%;
margin-left: 5px;
margin-inline-start: 5px;
border-width: 1px;
border-style: solid;
}
@ -565,7 +565,7 @@ a.learn-more-link.webconsole-learn-more-link {
.webconsole-filter-button > .toolbarbutton-menubutton-button:before {
width: 12px;
height: 12px;
margin-left: 1px;
margin-inline-start: 1px;
}
.toolbarbutton-menubutton-dropmarker {
margin: 0px;

View File

@ -97,7 +97,7 @@
cursor: n-resize;
}
.devtools-responsive-container > .devtools-sidebar-tabs:not([pane-collapsed]) {
.devtools-responsive-container > .devtools-sidebar-tabs:not(.pane-collapsed) {
/* When the panel is collapsed min/max height should not be applied because
collapsing relies on negative margins, which implies constant height. */
min-height: 35vh;
@ -351,6 +351,7 @@
.theme-firebug .breadcrumbs-widget-item {
margin-inline-start: 10px;
margin-inline-end: 1px;
background-image: none;
border: 1px solid transparent;
color: #141414;
border-radius: 2px;

View File

@ -65,7 +65,7 @@ var ToggleMixin = {
* is currently being shown.
*/
isVisible: function () {
return !this.el.hasAttribute("pane-collapsed");
return !this.el.classList.contains("pane-collapsed");
},
/**
@ -88,11 +88,11 @@ var ToggleMixin = {
ViewHelpers.togglePane(flags, this.el);
if (flags.visible) {
this.button.removeAttribute("pane-collapsed");
this.button.classList.remove("pane-collapsed");
this.button.setAttribute("tooltiptext", this._collapseString);
}
else {
this.button.setAttribute("pane-collapsed", "");
this.button.classList.add("pane-collapsed");
this.button.setAttribute("tooltiptext", this._expandString);
}
},

View File

@ -657,7 +657,7 @@ JSTerm.prototype = {
}
} else {
this.sidebar.once("variablesview-ready", onTabReady);
this.sidebar.addTab("variablesview", VARIABLES_VIEW_URL, true);
this.sidebar.addTab("variablesview", VARIABLES_VIEW_URL, {selected: true});
}
return deferred.promise;

View File

@ -3,11 +3,11 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const protocol = require("devtools/shared/protocol");
const { actorBridge } = require("devtools/server/actors/common");
const { method, custom, Arg, Option, RetVal } = protocol;
const { Actor, ActorClassWithSpec } = require("devtools/shared/protocol");
const { actorBridgeWithSpec } = require("devtools/server/actors/common");
const { on, once, off, emit } = require("sdk/event/core");
const { Framerate } = require("devtools/server/performance/framerate");
const { framerateSpec } = require("devtools/shared/specs/framerate");
/**
* An actor wrapper around Framerate. Uses exposed
@ -15,48 +15,19 @@ const { Framerate } = require("devtools/server/performance/framerate");
*
* @see devtools/server/performance/framerate.js for documentation.
*/
var FramerateActor = exports.FramerateActor = protocol.ActorClass({
typeName: "framerate",
var FramerateActor = exports.FramerateActor = ActorClassWithSpec(framerateSpec, {
initialize: function (conn, tabActor) {
protocol.Actor.prototype.initialize.call(this, conn);
Actor.prototype.initialize.call(this, conn);
this.bridge = new Framerate(tabActor);
},
destroy: function (conn) {
protocol.Actor.prototype.destroy.call(this, conn);
Actor.prototype.destroy.call(this, conn);
this.bridge.destroy();
},
startRecording: actorBridge("startRecording", {}),
stopRecording: actorBridge("stopRecording", {
request: {
beginAt: Arg(0, "nullable:number"),
endAt: Arg(1, "nullable:number")
},
response: { ticks: RetVal("array:number") }
}),
cancelRecording: actorBridge("cancelRecording"),
isRecording: actorBridge("isRecording", {
response: { recording: RetVal("boolean") }
}),
getPendingTicks: actorBridge("getPendingTicks", {
request: {
beginAt: Arg(0, "nullable:number"),
endAt: Arg(1, "nullable:number")
},
response: { ticks: RetVal("array:number") }
}),
});
/**
* The corresponding Front object for the FramerateActor.
*/
var FramerateFront = exports.FramerateFront = protocol.FrontClass(FramerateActor, {
initialize: function (client, { framerateActor }) {
protocol.Front.prototype.initialize.call(this, client, { actor: framerateActor });
this.manage(this);
}
startRecording: actorBridgeWithSpec("startRecording"),
stopRecording: actorBridgeWithSpec("stopRecording"),
cancelRecording: actorBridgeWithSpec("cancelRecording"),
isRecording: actorBridgeWithSpec("isRecording"),
getPendingTicks: actorBridgeWithSpec("getPendingTicks"),
});

View File

@ -537,11 +537,12 @@ StorageActors.createActor({
break;
case "cleared":
this.storageActor.update("cleared", "cookies", hosts);
break;
case "reload":
this.storageActor.update("reloaded", "cookies", hosts);
if (hosts.length) {
for (let host of hosts) {
data[host] = [];
}
this.storageActor.update("cleared", "cookies", data);
}
break;
}
return null;
@ -1392,6 +1393,30 @@ StorageActors.createActor({
return this.removeDB(host, principal, name);
}),
removeAll: Task.async(function* (host, name) {
let [db, store] = JSON.parse(name);
let win = this.storageActor.getWindowFromHost(host);
if (!win) {
return;
}
let principal = win.document.nodePrincipal;
this.clearDBStore(host, principal, db, store);
}),
removeItem: Task.async(function* (host, name) {
let [db, store, id] = JSON.parse(name);
let win = this.storageActor.getWindowFromHost(host);
if (!win) {
return;
}
let principal = win.document.nodePrincipal;
this.removeDBRecord(host, principal, db, store, id);
}),
getHostName(location) {
if (!location.host) {
return location.href;
@ -1552,13 +1577,16 @@ StorageActors.createActor({
};
},
onDatabaseRemoved(host, name) {
if (this.hostVsStores.has(host)) {
this.hostVsStores.get(host).delete(name);
onItemUpdated(action, host, path) {
// Database was removed, remove it from stores map
if (action === "deleted" && path.length === 1) {
if (this.hostVsStores.has(host)) {
this.hostVsStores.get(host).delete(path[0]);
}
}
this.storageActor.update("deleted", "indexedDB", {
[host]: [ JSON.stringify([name]) ]
this.storageActor.update(action, "indexedDB", {
[host]: [ JSON.stringify(path) ]
});
},
@ -1573,6 +1601,8 @@ StorageActors.createActor({
this.getValuesForHost = indexedDBHelpers.getValuesForHost;
this.getObjectStoreData = indexedDBHelpers.getObjectStoreData;
this.removeDB = indexedDBHelpers.removeDB;
this.removeDBRecord = indexedDBHelpers.removeDBRecord;
this.clearDBStore = indexedDBHelpers.clearDBStore;
return;
}
@ -1584,14 +1614,12 @@ StorageActors.createActor({
setupParent: "setupParentProcessForIndexedDB"
});
this.getDBMetaData =
callParentProcessAsync.bind(null, "getDBMetaData");
this.getDBNamesForHost =
callParentProcessAsync.bind(null, "getDBNamesForHost");
this.getValuesForHost =
callParentProcessAsync.bind(null, "getValuesForHost");
this.removeDB =
callParentProcessAsync.bind(null, "removeDB");
this.getDBMetaData = callParentProcessAsync.bind(null, "getDBMetaData");
this.getDBNamesForHost = callParentProcessAsync.bind(null, "getDBNamesForHost");
this.getValuesForHost = callParentProcessAsync.bind(null, "getValuesForHost");
this.removeDB = callParentProcessAsync.bind(null, "removeDB");
this.removeDBRecord = callParentProcessAsync.bind(null, "removeDBRecord");
this.clearDBStore = callParentProcessAsync.bind(null, "clearDBStore");
addMessageListener("storage:storage-indexedDB-request-child", msg => {
switch (msg.json.method) {
@ -1604,9 +1632,9 @@ StorageActors.createActor({
}
break;
}
case "onDatabaseRemoved": {
let [host, name] = msg.json.args;
this.onDatabaseRemoved(host, name);
case "onItemUpdated": {
let [action, host, path] = msg.json.args;
this.onItemUpdated(action, host, path);
}
}
});
@ -1638,13 +1666,13 @@ var indexedDBHelpers = {
});
},
onDatabaseRemoved: function (host, name) {
onItemUpdated(action, host, path) {
let mm = Cc["@mozilla.org/globalmessagemanager;1"]
.getService(Ci.nsIMessageListenerManager);
mm.broadcastAsyncMessage("storage:storage-indexedDB-request-child", {
method: "onDatabaseRemoved",
args: [ host, name ]
method: "onItemUpdated",
args: [ action, host, path ]
});
},
@ -1665,9 +1693,9 @@ var indexedDBHelpers = {
success.resolve(this.backToChild("getDBMetaData", dbData));
};
request.onerror = () => {
request.onerror = ({target}) => {
console.error(
`Error opening indexeddb database ${name} for host ${host}`);
`Error opening indexeddb database ${name} for host ${host}`, target.error);
success.resolve(this.backToChild("getDBMetaData", null));
};
return success.promise;
@ -1682,24 +1710,24 @@ var indexedDBHelpers = {
},
removeDB: Task.async(function* (host, principal, name) {
let request = require("indexedDB").deleteForPrincipal(principal, name);
let result = new promise(resolve => {
let request = require("indexedDB").deleteForPrincipal(principal, name);
request.onsuccess = () => {
resolve({});
this.onDatabaseRemoved(host, name);
this.onItemUpdated("deleted", host, [name]);
};
request.onblocked = () => {
console.error(
`Deleting indexedDB database ${name} for host ${host} is blocked`);
console.warn(`Deleting indexedDB database ${name} for host ${host} is blocked`);
resolve({ blocked: true });
};
request.onerror = () => {
console.error(
`Error deleting indexedDB database ${name} for host ${host}`);
resolve({ error: request.error });
let { error } = request;
console.warn(
`Error deleting indexedDB database ${name} for host ${host}: ${error}`);
resolve({ error: error.message });
};
// If the database is blocked repeatedly, the onblocked event will not
@ -1711,6 +1739,70 @@ var indexedDBHelpers = {
return this.backToChild("removeDB", yield result);
}),
removeDBRecord: Task.async(function* (host, principal, dbName, storeName, id) {
let db;
try {
db = yield new promise((resolve, reject) => {
let request = this.openWithPrincipal(principal, dbName);
request.onsuccess = ev => resolve(ev.target.result);
request.onerror = ev => reject(ev.target.error);
});
let transaction = db.transaction(storeName, "readwrite");
let store = transaction.objectStore(storeName);
yield new promise((resolve, reject) => {
let request = store.delete(id);
request.onsuccess = () => resolve();
request.onerror = ev => reject(ev.target.error);
});
this.onItemUpdated("deleted", host, [dbName, storeName, id]);
} catch (error) {
let recordPath = [dbName, storeName, id].join("/");
console.error(`Failed to delete indexedDB record: ${recordPath}: ${error}`);
}
if (db) {
db.close();
}
return this.backToChild("removeDBRecord", null);
}),
clearDBStore: Task.async(function* (host, principal, dbName, storeName) {
let db;
try {
db = yield new promise((resolve, reject) => {
let request = this.openWithPrincipal(principal, dbName);
request.onsuccess = ev => resolve(ev.target.result);
request.onerror = ev => reject(ev.target.error);
});
let transaction = db.transaction(storeName, "readwrite");
let store = transaction.objectStore(storeName);
yield new promise((resolve, reject) => {
let request = store.clear();
request.onsuccess = () => resolve();
request.onerror = ev => reject(ev.target.error);
});
this.onItemUpdated("cleared", host, [dbName, storeName]);
} catch (error) {
let storePath = [dbName, storeName].join("/");
console.error(`Failed to clear indexedDB store: ${storePath}: ${error}`);
}
if (db) {
db.close();
}
return this.backToChild("clearDBStore", null);
}),
/**
* Fetches all the databases and their metadata for the given `host`.
*/
@ -1986,6 +2078,14 @@ var indexedDBHelpers = {
let [host, principal, name] = args;
return indexedDBHelpers.removeDB(host, principal, name);
}
case "removeDBRecord": {
let [host, principal, db, store, id] = args;
return indexedDBHelpers.removeDBRecord(host, principal, db, store, id);
}
case "clearDBStore": {
let [host, principal, db, store] = args;
return indexedDBHelpers.clearDBStore(host, principal, db, store);
}
default:
console.error("ERR_DIRECTOR_PARENT_UNKNOWN_METHOD", msg.json.method);
throw new Error("ERR_DIRECTOR_PARENT_UNKNOWN_METHOD");
@ -2243,16 +2343,13 @@ let StorageActor = protocol.ActorClassWithSpec(specs.storageSpec, {
* <host2>: [<store_names34>...],
* }
* Where host1, host2 are the host in which this change happened and
* [<store_namesX] is an array of the names of the changed store
* objects. Leave it empty if the host was completely removed.
* When the action is "reloaded" or "cleared", `data` is an array of
* hosts for which the stores were cleared or reloaded.
* [<store_namesX] is an array of the names of the changed store objects.
* Pass an empty array if the host itself was affected: either completely
* removed or cleared.
*/
update(action, storeType, data) {
if (action == "cleared" || action == "reloaded") {
let toSend = {};
toSend[storeType] = data;
events.emit(this, "stores-" + action, toSend);
if (action == "cleared") {
events.emit(this, "stores-cleared", { [storeType]: data });
return null;
}

View File

@ -31,7 +31,7 @@ window.onload = function() {
SimpleTest.waitForExplicitFinish();
var {FramerateFront} = require("devtools/server/actors/framerate");
var {FramerateFront} = require("devtools/shared/fronts/framerate");
function plotFPS(ticks, interval = 100, clamp = 60) {
var timeline = [];

View File

@ -31,7 +31,7 @@ window.onload = function() {
SimpleTest.waitForExplicitFinish();
var {FramerateFront} = require("devtools/server/actors/framerate");
var {FramerateFront} = require("devtools/shared/fronts/framerate");
function plotFPS(ticks, interval = 100, clamp = 60) {
var timeline = [];

View File

@ -31,7 +31,7 @@ window.onload = function() {
SimpleTest.waitForExplicitFinish();
var {FramerateFront} = require("devtools/server/actors/framerate");
var {FramerateFront} = require("devtools/shared/fronts/framerate");
var START_TICK = 2000;
var STOP_TICK = 3000;
var TOTAL_TIME = 5000;

View File

@ -16,7 +16,7 @@ Bug 1023018 - Tests if the framerate actor keeps recording after navigations.
window.onload = function() {
SimpleTest.waitForExplicitFinish();
var {FramerateFront} = require("devtools/server/actors/framerate");
var {FramerateFront} = require("devtools/shared/fronts/framerate");
var {TargetFactory} = require("devtools/client/framework/target");
var url = document.getElementById("testContent").href;

View File

@ -31,7 +31,7 @@ window.onload = function() {
SimpleTest.waitForExplicitFinish();
var {FramerateFront} = require("devtools/server/actors/framerate");
var {FramerateFront} = require("devtools/shared/fronts/framerate");
DebuggerServer.init();
DebuggerServer.addBrowserActors();

View File

@ -16,7 +16,7 @@ Bug 1171489 - Tests if the framerate actor does not record timestamps from multi
window.onload = function() {
SimpleTest.waitForExplicitFinish();
var {FramerateFront} = require("devtools/server/actors/framerate");
var {FramerateFront} = require("devtools/shared/fronts/framerate");
var {TargetFactory} = require("devtools/client/framework/target");
var url = document.getElementById("testContent").href;

View File

@ -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/. */
"use strict";
const { Front, FrontClassWithSpec } = require("devtools/shared/protocol");
const { framerateSpec } = require("devtools/shared/specs/framerate");
/**
* The corresponding Front object for the FramerateActor.
*/
var FramerateFront = exports.FramerateFront = FrontClassWithSpec(framerateSpec, {
initialize: function (client, { framerateActor }) {
Front.prototype.initialize.call(this, client, { actor: framerateActor });
this.manage(this);
}
});
exports.FramerateFront = FramerateFront;

View File

@ -15,6 +15,7 @@ DevToolsModules(
'device.js',
'director-manager.js',
'director-registry.js',
'framerate.js',
'gcli.js',
'highlighters.js',
'inspector.js',

View File

@ -36,7 +36,8 @@ exports.items = [
/**
* Called when the UI is ready to add a welcome message to the output
*/
exports.maybeShowIntro = function(commandOutputManager, conversionContext) {
exports.maybeShowIntro = function (commandOutputManager, conversionContext,
outputPanel) {
var hideIntro = conversionContext.system.settings.get('hideIntro');
if (hideIntro.value) {
return;
@ -46,7 +47,7 @@ exports.maybeShowIntro = function(commandOutputManager, conversionContext) {
output.type = 'view';
commandOutputManager.onOutput({ output: output });
var viewData = this.createView(null, conversionContext, true);
var viewData = this.createView(null, conversionContext, true, outputPanel);
output.complete({ isTypedData: true, type: 'view', data: viewData });
};
@ -54,7 +55,8 @@ exports.maybeShowIntro = function(commandOutputManager, conversionContext) {
/**
* Called when the UI is ready to add a welcome message to the output
*/
exports.createView = function(ignoreArgs, conversionContext, showHideButton) {
exports.createView = function (ignoreArgs, conversionContext, showHideButton,
outputPanel) {
return view.createView({
html:
'<div save="${mainDiv}">\n' +
@ -81,7 +83,7 @@ exports.createView = function(ignoreArgs, conversionContext, showHideButton) {
var settings = conversionContext.system.settings;
var hideIntro = settings.get('hideIntro');
hideIntro.value = true;
this.mainDiv.style.display = 'none';
outputPanel.remove();
}
}
});

View File

@ -0,0 +1,34 @@
/* 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 framerateSpec = generateActorSpec({
typeName: "framerate",
methods: {
startRecording: {},
stopRecording: {
request: {
beginAt: Arg(0, "nullable:number"),
endAt: Arg(1, "nullable:number")
},
response: { ticks: RetVal("array:number") }
},
cancelRecording: {},
isRecording: {
response: { recording: RetVal("boolean") }
},
getPendingTicks: {
request: {
beginAt: Arg(0, "nullable:number"),
endAt: Arg(1, "nullable:number")
},
response: { ticks: RetVal("array:number") }
}
}
});
exports.framerateSpec = framerateSpec;

View File

@ -18,6 +18,7 @@ DevToolsModules(
'director-registry.js',
'environment.js',
'frame.js',
'framerate.js',
'gcli.js',
'heap-snapshot-file.js',
'highlighters.js',

View File

@ -187,7 +187,21 @@ createStorageSpec({
name: Arg(1, "string"),
},
response: RetVal("idbdeleteresult")
}
},
removeAll: {
request: {
host: Arg(0, "string"),
name: Arg(1, "string"),
},
response: {}
},
removeItem: {
request: {
host: Arg(0, "string"),
name: Arg(1, "string"),
},
response: {}
},
}
});

View File

@ -305,7 +305,7 @@ AutoJSAPI::~AutoJSAPI()
ReportException();
if (mOldWarningReporter.isSome()) {
JS::SetWarningReporter(JS_GetRuntime(cx()), mOldWarningReporter.value());
JS::SetWarningReporter(cx(), mOldWarningReporter.value());
}
// Leave the request before popping.
@ -345,10 +345,9 @@ AutoJSAPI::InitInternal(nsIGlobalObject* aGlobalObject, JSObject* aGlobal,
ScriptSettingsStack::Push(this);
JSRuntime* rt = JS_GetRuntime(aCx);
mOldWarningReporter.emplace(JS::GetWarningReporter(rt));
mOldWarningReporter.emplace(JS::GetWarningReporter(aCx));
JS::SetWarningReporter(rt, WarningOnlyErrorReporter);
JS::SetWarningReporter(aCx, WarningOnlyErrorReporter);
#ifdef DEBUG
if (haveException) {

View File

@ -682,8 +682,8 @@ nsCopySupport::FireClipboardEvent(EventMessage aEventMessage,
RefPtr<DataTransfer> clipboardData;
if (chromeShell || Preferences::GetBool("dom.event.clipboardevents.enabled", true)) {
clipboardData =
new DataTransfer(piWindow, aEventMessage, aEventMessage == ePaste,
aClipboardType);
new DataTransfer(doc->GetScopeObject(), aEventMessage,
aEventMessage == ePaste, aClipboardType);
nsEventStatus status = nsEventStatus_eIgnore;
InternalClipboardEvent evt(true, aEventMessage);

View File

@ -2693,7 +2693,7 @@ nsDocument::ApplySettingsFromCSP(bool aSpeculative)
mReferrerPolicy = static_cast<ReferrerPolicy>(referrerPolicy);
mReferrerPolicySet = true;
}
// Set up 'block-all-mixed-content' if not already inherited
// from the parent context or set by any other CSP.
if (!mBlockAllMixedContent) {
@ -13375,6 +13375,11 @@ nsIDocument::SetCachedEncoder(already_AddRefed<nsIDocumentEncoder> aEncoder)
void
nsIDocument::SetContentTypeInternal(const nsACString& aType)
{
if (!IsHTMLOrXHTML() && mDefaultElementType == kNameSpaceID_None &&
aType.EqualsLiteral("application/xhtml+xml")) {
mDefaultElementType = kNameSpaceID_XHTML;
}
mCachedEncoder = nullptr;
mContentType = aType;
}

View File

@ -13078,13 +13078,6 @@ nsGlobalWindow::ResumeTimeouts(bool aThawChildren, bool aThawWorkers)
RefPtr<Promise> d = mAudioContexts[i]->Resume(dummy);
}
// Thaw or resume all of the workers for this window.
if (aThawWorkers) {
mozilla::dom::workers::ThawWorkersForWindow(AsInner());
} else {
mozilla::dom::workers::ResumeWorkersForWindow(AsInner());
}
// Restore all of the timeouts, using the stored time remaining
// (stored in timeout->mTimeRemaining).
@ -13129,6 +13122,15 @@ nsGlobalWindow::ResumeTimeouts(bool aThawChildren, bool aThawWorkers)
// Add a reference for the new timer's closure.
t->AddRef();
}
// Thaw or resume all of the workers for this window. We must do this
// after timeouts since workers may have queued events that can trigger
// a setTimeout().
if (aThawWorkers) {
mozilla::dom::workers::ThawWorkersForWindow(AsInner());
} else {
mozilla::dom::workers::ResumeWorkersForWindow(AsInner());
}
}
// Resume our children as well.

View File

@ -748,10 +748,15 @@ nsImageLoadingContent::LoadImage(const nsAString& aNewURI,
return NS_OK;
}
// Second, parse the URI string to get image URI
nsCOMPtr<nsIURI> imageURI;
nsresult rv = StringToURI(aNewURI, doc, getter_AddRefs(imageURI));
NS_ENSURE_SUCCESS(rv, rv);
// XXXbiesi fire onerror if that failed?
if (NS_FAILED(rv)) {
// Cancel image requests and fire error event per spec
CancelImageRequests(aNotify);
FireEvent(NS_LITERAL_STRING("error"));
return NS_OK;
}
bool equal;

View File

@ -2454,7 +2454,7 @@ nsJSContext::EnsureStatics()
AsmJSCacheOpenEntryForWrite,
asmjscache::CloseEntryForWrite
};
JS::SetAsmJSCacheOps(sRuntime, &asmJSCacheOps);
JS::SetAsmJSCacheOps(JS_GetContext(sRuntime), &asmJSCacheOps);
// Set these global xpconnect options...
Preferences::RegisterCallbackAndCall(SetMemoryHighWaterMarkPrefChangedCallback,

View File

@ -19,8 +19,6 @@
#include "nsIWeakReference.h"
#include "mozilla/Services.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIPermissionManager.h"
#include "nsIDocument.h"
#include "nsContentUtils.h"
using namespace mozilla;
@ -75,8 +73,7 @@ NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsPluginArray,
mWindow,
mPlugins,
mCTPPlugins)
mPlugins)
static void
GetPluginMimeTypes(const nsTArray<RefPtr<nsPluginElement> >& aPlugins,
@ -156,7 +153,6 @@ nsPluginArray::Refresh(bool aReloadDocuments)
}
mPlugins.Clear();
mCTPPlugins.Clear();
nsCOMPtr<nsIDOMNavigator> navigator = mWindow->GetNavigator();
@ -232,13 +228,6 @@ nsPluginArray::NamedGetter(const nsAString& aName, bool &aFound)
nsPluginElement* plugin = FindPlugin(mPlugins, aName);
aFound = (plugin != nullptr);
if (!aFound) {
nsPluginElement* hiddenPlugin = FindPlugin(mCTPPlugins, aName);
if (hiddenPlugin) {
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
obs->NotifyObservers(hiddenPlugin->PluginTag(), "Plugin::HiddenPluginTouched", nsString(aName).get());
}
}
return plugin;
}
@ -300,7 +289,7 @@ operator<(const RefPtr<nsPluginElement>& lhs,
void
nsPluginArray::EnsurePlugins()
{
if (!mPlugins.IsEmpty() || !mCTPPlugins.IsEmpty()) {
if (!mPlugins.IsEmpty()) {
// We already have an array of plugin elements.
return;
}
@ -317,31 +306,7 @@ nsPluginArray::EnsurePlugins()
// need to wrap each of these with a nsPluginElement, which is
// scriptable.
for (uint32_t i = 0; i < pluginTags.Length(); ++i) {
nsCOMPtr<nsPluginTag> pluginTag = do_QueryInterface(pluginTags[i]);
if (!pluginTag) {
mPlugins.AppendElement(new nsPluginElement(mWindow, pluginTags[i]));
} else if (pluginTag->IsActive()) {
uint32_t permission = nsIPermissionManager::ALLOW_ACTION;
if (pluginTag->IsClicktoplay()) {
nsCString name;
pluginTag->GetName(name);
if (NS_LITERAL_CSTRING("Shockwave Flash").Equals(name)) {
RefPtr<nsPluginHost> pluginHost = nsPluginHost::GetInst();
nsCString permString;
nsresult rv = pluginHost->GetPermissionStringForTag(pluginTag, 0, permString);
if (rv == NS_OK) {
nsIPrincipal* principal = mWindow->GetExtantDoc()->NodePrincipal();
nsCOMPtr<nsIPermissionManager> permMgr = services::GetPermissionManager();
permMgr->TestPermissionFromPrincipal(principal, permString.get(), &permission);
}
}
}
if (permission == nsIPermissionManager::ALLOW_ACTION) {
mPlugins.AppendElement(new nsPluginElement(mWindow, pluginTags[i]));
} else {
mCTPPlugins.AppendElement(new nsPluginElement(mWindow, pluginTags[i]));
}
}
mPlugins.AppendElement(new nsPluginElement(mWindow, pluginTags[i]));
}
// Alphabetize the enumeration order of non-hidden plugins to reduce

View File

@ -60,10 +60,6 @@ private:
nsCOMPtr<nsPIDOMWindowInner> mWindow;
nsTArray<RefPtr<nsPluginElement> > mPlugins;
/* A separate list of click-to-play plugins that we don't tell content
* about but keep track of so we can still prompt the user to click to play.
*/
nsTArray<RefPtr<nsPluginElement> > mCTPPlugins;
};
class nsPluginElement final : public nsISupports,

View File

@ -3297,46 +3297,23 @@ namespace {
// This runnable is used to write a deprecation message from a worker to the
// console running on the main-thread.
class DeprecationWarningRunnable final : public Runnable
, public WorkerHolder
class DeprecationWarningRunnable final : public WorkerProxyToMainThreadRunnable
{
WorkerPrivate* mWorkerPrivate;
nsIDocument::DeprecatedOperations mOperation;
public:
DeprecationWarningRunnable(WorkerPrivate* aWorkerPrivate,
nsIDocument::DeprecatedOperations aOperation)
: mWorkerPrivate(aWorkerPrivate)
: WorkerProxyToMainThreadRunnable(aWorkerPrivate)
, mOperation(aOperation)
{
MOZ_ASSERT(aWorkerPrivate);
}
void
Dispatch()
{
if (NS_WARN_IF(!HoldWorker(mWorkerPrivate))) {
return;
}
if (NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(this)))) {
ReleaseWorker();
return;
}
}
virtual bool
Notify(Status aStatus) override
{
// We don't care about the notification. We just want to keep the
// mWorkerPrivate alive.
return true;
aWorkerPrivate->AssertIsOnWorkerThread();
}
private:
NS_IMETHOD
Run() override
void
RunOnMainThread() override
{
MOZ_ASSERT(NS_IsMainThread());
@ -3350,40 +3327,11 @@ private:
if (window && window->GetExtantDoc()) {
window->GetExtantDoc()->WarnOnceAbout(mOperation);
}
ReleaseWorkerHolder();
return NS_OK;
}
void
ReleaseWorkerHolder()
{
class ReleaseRunnable final : public MainThreadWorkerRunnable
{
RefPtr<DeprecationWarningRunnable> mRunnable;
public:
ReleaseRunnable(WorkerPrivate* aWorkerPrivate,
DeprecationWarningRunnable* aRunnable)
: MainThreadWorkerRunnable(aWorkerPrivate)
, mRunnable(aRunnable)
{}
virtual bool
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
{
MOZ_ASSERT(aWorkerPrivate);
aWorkerPrivate->AssertIsOnWorkerThread();
mRunnable->ReleaseWorker();
return true;
}
};
RefPtr<ReleaseRunnable> runnable =
new ReleaseRunnable(mWorkerPrivate, this);
NS_WARN_IF(!runnable->Dispatch());
}
RunBackOnWorkerThread() override
{}
};
} // anonymous namespace

View File

@ -28,8 +28,8 @@ FakeMediaStreamGraph::DispatchToMainThreadAfterStreamStateUpdate(already_AddRefe
NS_DispatchToMainThread(task);
}
CameraPreviewMediaStream::CameraPreviewMediaStream(DOMMediaStream* aWrapper)
: ProcessedMediaStream(aWrapper)
CameraPreviewMediaStream::CameraPreviewMediaStream()
: ProcessedMediaStream()
, mMutex("mozilla::camera::CameraPreviewMediaStream")
, mInvalidatePending(0)
, mDiscardedFrames(0)

View File

@ -40,7 +40,7 @@ class CameraPreviewMediaStream : public ProcessedMediaStream
typedef mozilla::layers::Image Image;
public:
explicit CameraPreviewMediaStream(DOMMediaStream* aWrapper);
CameraPreviewMediaStream();
virtual void AddAudioOutput(void* aKey) override;
virtual void SetAudioOutputVolume(void* aKey, float aVolume) override;

View File

@ -259,7 +259,7 @@ nsDOMCameraControl::nsDOMCameraControl(uint32_t aCameraId,
, mSetInitialConfig(false)
{
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
mInput = new CameraPreviewMediaStream(this);
mInput = new CameraPreviewMediaStream();
mOwnedStream = mInput;
BindToOwner(aWindow);

Some files were not shown because too many files have changed in this diff Show More