import changes from `devel' branch of rmottola/Arctic-Fox:
- Bug 1132874 - Improve protections against sending a parent plugin protocol shutdown message to the child after the child has torn down. r=aklotz (b80b45fa7) - Bug 1103036 - Follow-up to initial patch; r=jchen (51337c2dc) - Bug 1132874 - Simplify PPluginWidget protocol handling, and avoid sending async messages from the parent. Addresses a problem with sub protocols that are torn down randomly from either side of the connection. r=aklotz (3ad936e84) - Bug 1128214 - Avoid a crash when attempting to render windows titlebar specific theme elements with e10s. r=roc (b6f17da09) - Bug 1139368 - Set FilterTypeSet dependency in improveThisTypesForCall. r=h4writer (422de7271) - Bug 864041 - Remove Firefox 2+3 compat code from about:sessionrestore. r=mak (4cfc6fe9a) - Bug 1009599 - Restoring from about:sessionrestore fails when there is more than one tab in the window r=smacleod (88ca1cfbc) - Bug 1146052 - Fix empty about:sessionrestore after crash as well as empty about:welcomeback after resetting the profile r=smacleod (211b50396) - Bug 1043797: extended popup notifications to create a generic doorhanger for all security notifications incl. mixed content r=adw (f7c2d5ded) - Bug 900845 - We aren't using the NetUtil module in SessionStore.jsm. (3f5ddd133) - Bug 898755 - Remove _resume_session_once_on_shutdown code from SessionStore; r=yoric (eb159fec9) - Bug 902727 - [Session Restore] Remove legacy _writeFileEncoder; r=smacleod (8e375c529) - space cleanup (cbd71ce91) - Bug 968923 - part 1 - add infrastructure for defining use counters from UseCounters.conf; original-author=heycam; r=heycam,gfritzsche,mshal (d0dea9997) - Bug 968923 - part 2 - change MappedAttrParser to store a nsSVGElement directly, instead of its nsIPrincipal; r=smaug (4eff86d7f) - Merge branch 'devel' of https://github.com/rmottola/Arctic-Fox into devel (feb4378e6)
@@ -549,6 +549,10 @@ window[chromehidden~="toolbar"] toolbar:not(.toolbar-primary):not(#nav-bar):not(
|
||||
-moz-binding: url("chrome://browser/content/urlbarBindings.xml#addon-progress-notification");
|
||||
}
|
||||
|
||||
#bad-content-notification {
|
||||
-moz-binding: url("chrome://browser/content/urlbarBindings.xml#bad-content-notification");
|
||||
}
|
||||
|
||||
#click-to-play-plugins-notification {
|
||||
-moz-binding: url("chrome://browser/content/urlbarBindings.xml#click-to-play-plugins-notification");
|
||||
}
|
||||
|
||||
@@ -6472,43 +6472,26 @@ var gIdentityHandler = {
|
||||
|
||||
// Ensure the doorhanger is shown when mixed active content is blocked.
|
||||
if (state & nsIWebProgressListener.STATE_BLOCKED_MIXED_ACTIVE_CONTENT)
|
||||
this.showMixedContentDoorhanger();
|
||||
this.showBadContentDoorhanger(state);
|
||||
},
|
||||
|
||||
/**
|
||||
* Display the Mixed Content Blocker doohanger, providing an option
|
||||
* to the user to override mixed content blocking
|
||||
*/
|
||||
showMixedContentDoorhanger : function() {
|
||||
showBadContentDoorhanger : function(state) {
|
||||
var currentNotification =
|
||||
PopupNotifications.getNotification("bad-content",
|
||||
gBrowser.selectedBrowser);
|
||||
|
||||
// If we've already got an active notification, bail out to avoid showing it repeatedly.
|
||||
if (PopupNotifications.getNotification("mixed-content-blocked", gBrowser.selectedBrowser))
|
||||
if (currentNotification && currentNotification.options.state == state)
|
||||
return;
|
||||
|
||||
let brandBundle = document.getElementById("bundle_brand");
|
||||
let brandShortName = brandBundle.getString("brandShortName");
|
||||
let messageString = gNavigatorBundle.getFormattedString("mixedContentBlocked.message", [brandShortName]);
|
||||
let action = {
|
||||
label: gNavigatorBundle.getString("mixedContentBlocked.keepBlockingButton.label"),
|
||||
accessKey: gNavigatorBundle.getString("mixedContentBlocked.keepBlockingButton.accesskey"),
|
||||
callback: function() { /* NOP */ }
|
||||
};
|
||||
let secondaryActions = [
|
||||
{
|
||||
label: gNavigatorBundle.getString("mixedContentBlocked.unblock.label"),
|
||||
accessKey: gNavigatorBundle.getString("mixedContentBlocked.unblock.accesskey"),
|
||||
callback: function() {
|
||||
// Reload the page with the content unblocked
|
||||
BrowserReloadWithFlags(nsIWebNavigation.LOAD_FLAGS_ALLOW_MIXED_CONTENT);
|
||||
}
|
||||
}
|
||||
];
|
||||
let options = {
|
||||
dismissed: true,
|
||||
learnMoreURL: Services.urlFormatter.formatURLPref("browser.mixedcontent.warning.infoURL"),
|
||||
state: state
|
||||
};
|
||||
PopupNotifications.show(gBrowser.selectedBrowser, "mixed-content-blocked",
|
||||
messageString, "mixed-content-blocked-notification-icon",
|
||||
action, secondaryActions, options);
|
||||
|
||||
PopupNotifications.show(gBrowser.selectedBrowser, "bad-content",
|
||||
"", "bad-content-blocked-notification-icon",
|
||||
null, null, options);
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -441,7 +441,7 @@
|
||||
<image id="webapps-notification-icon" class="notification-anchor-icon" role="button"/>
|
||||
<image id="plugins-notification-icon" class="notification-anchor-icon" role="button"/>
|
||||
<image id="web-notifications-notification-icon" class="notification-anchor-icon" role="button"/>
|
||||
<image id="mixed-content-blocked-notification-icon" class="notification-anchor-icon" role="button"/>
|
||||
<image id="bad-content-blocked-notification-icon" class="notification-anchor-icon" role="button"/>
|
||||
<image id="webRTC-shareDevices-notification-icon" class="notification-anchor-icon" role="button"/>
|
||||
<image id="webRTC-sharingDevices-notification-icon" class="notification-anchor-icon" role="button"/>
|
||||
<image id="pointerLock-notification-icon" class="notification-anchor-icon" role="button"/>
|
||||
|
||||
@@ -88,10 +88,3 @@
|
||||
<label id="pointerLock-cancel" value="&pointerLock.notification.message;"/>
|
||||
</popupnotificationcontent>
|
||||
</popupnotification>
|
||||
|
||||
<popupnotification id="mixed-content-blocked-notification" hidden="true">
|
||||
<popupnotificationcontent orient="vertical" align="start">
|
||||
<separator/>
|
||||
<description id="mixed-content-blocked-moreinfo">&mixedContentBlocked.moreinfo;</description>
|
||||
</popupnotificationcontent>
|
||||
</popupnotification>
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
%notificationDTD;
|
||||
<!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd">
|
||||
%browserDTD;
|
||||
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
|
||||
%brandDTD;
|
||||
]>
|
||||
|
||||
<bindings id="urlbarBindings" xmlns="http://www.mozilla.org/xbl"
|
||||
@@ -1264,6 +1266,110 @@
|
||||
</implementation>
|
||||
</binding>
|
||||
|
||||
<binding id="bad-content-notification" extends="chrome://global/content/bindings/notification.xml#popup-notification">
|
||||
<content>
|
||||
<xul:hbox align="start">
|
||||
<xul:image class="popup-notification-icon" xbl:inherits="popupid"/>
|
||||
<xul:vbox>
|
||||
<!-- header -->
|
||||
<xul:vbox>
|
||||
<xul:description anonid="badContentBlocked.title"
|
||||
class="popup-notification-item-title" xbl:inherits="popupid">
|
||||
</xul:description>
|
||||
<xul:description class="popup-notification-item-message"
|
||||
xbl:inherits="popupid">
|
||||
&badContentBlocked.moreinfo;
|
||||
</xul:description>
|
||||
</xul:vbox>
|
||||
<!-- mixed content -->
|
||||
<xul:vbox anonid="mixedContent" hidden="true">
|
||||
<xul:separator class="groove"/>
|
||||
<xul:hbox align="start">
|
||||
<xul:vbox>
|
||||
<xul:description class="popup-notification-item-title"
|
||||
xbl:inherits="popupid">
|
||||
&mixedContentBlocked2.message;
|
||||
</xul:description>
|
||||
<xul:description class="popup-notification-item-message"
|
||||
xbl:inherits="popupid">
|
||||
&mixedContentBlocked2.moreinfo;
|
||||
</xul:description>
|
||||
<xul:label anonid="mixedContent.helplink"
|
||||
class="text-link plain" href=""
|
||||
value="&mixedContentBlocked2.learnMore;"/>
|
||||
</xul:vbox>
|
||||
<xul:button
|
||||
type="menu" label="&mixedContentBlocked2.options;"
|
||||
sizetopopup="none">
|
||||
<xul:menupopup>
|
||||
<xul:menuitem anonid="mixedContentAction.unblock"
|
||||
hidden="true" label="&mixedContentBlocked2.unblock.label;"
|
||||
accesskey="&mixedContentBlocked2.unblock.accesskey;"
|
||||
oncommand="document.getBindingParent(this).disableMixedContentProtection();"/>
|
||||
</xul:menupopup>
|
||||
</xul:button>
|
||||
</xul:hbox>
|
||||
</xul:vbox>
|
||||
</xul:vbox>
|
||||
</xul:hbox>
|
||||
</content>
|
||||
<resources>
|
||||
<stylesheet src="chrome://global/skin/notification.css"/>
|
||||
</resources>
|
||||
<implementation>
|
||||
<field name="_brandShortName">
|
||||
document.getElementById("bundle_brand").getString("brandShortName")
|
||||
</field>
|
||||
<field name="_doorhangerTitle">
|
||||
document.getAnonymousElementByAttribute(this, "anonid",
|
||||
"badContentBlocked.title")
|
||||
</field>
|
||||
<field name="_mixedContent">
|
||||
document.getAnonymousElementByAttribute(this, "anonid",
|
||||
"mixedContent")
|
||||
</field>
|
||||
<field name="_mixedContentUnblock">
|
||||
document.getAnonymousElementByAttribute(this, "anonid",
|
||||
"mixedContentAction.unblock")
|
||||
</field>
|
||||
<field name="_mixedContentHelplink">
|
||||
document.getAnonymousElementByAttribute(this, "anonid",
|
||||
"mixedContent.helplink")
|
||||
</field>
|
||||
<constructor><![CDATA[
|
||||
// default title
|
||||
_doorhangerTitle.value =
|
||||
gNavigatorBundle.getFormattedString(
|
||||
"badContentBlocked.notblocked.message", [this._brandShortName]);
|
||||
|
||||
if (this.notification.options.state &
|
||||
Ci.nsIWebProgressListener.STATE_BLOCKED_MIXED_ACTIVE_CONTENT) {
|
||||
_doorhangerTitle.value =
|
||||
gNavigatorBundle.getFormattedString(
|
||||
"badContentBlocked.blocked.message", [this._brandShortName]);
|
||||
_mixedContent.hidden = false;
|
||||
_mixedContentUnblock.hidden = false;
|
||||
_mixedContentHelplink.href =
|
||||
Services.urlFormatter.formatURLPref("app.support.baseURL")
|
||||
+ "mixed-content";
|
||||
}
|
||||
]]></constructor>
|
||||
<method name="disableMixedContentProtection">
|
||||
<body><![CDATA[
|
||||
// Use telemetry to measure how often unblocking happens
|
||||
const kMIXED_CONTENT_UNBLOCK_EVENT = 2;
|
||||
let histogram =
|
||||
Services.telemetry.getHistogramById(
|
||||
"MIXED_CONTENT_UNBLOCK_COUNTER");
|
||||
histogram.add(kMIXED_CONTENT_UNBLOCK_EVENT);
|
||||
// Reload the page with the content unblocked
|
||||
BrowserReloadWithFlags(
|
||||
nsIWebNavigation.LOAD_FLAGS_ALLOW_MIXED_CONTENT);
|
||||
]]></body>
|
||||
</method>
|
||||
</implementation>
|
||||
</binding>
|
||||
|
||||
<binding id="click-to-play-plugins-notification" extends="chrome://global/content/bindings/notification.xml#popup-notification">
|
||||
<content align="start" class="click-to-play-plugins-notification-content">
|
||||
<xul:vbox flex="1" align="stretch" class="popup-notification-main-box"
|
||||
|
||||
@@ -72,14 +72,9 @@ let SessionMigrationInternal = {
|
||||
win._closedTabs = [];
|
||||
return win;
|
||||
});
|
||||
let wrappedState = {
|
||||
url: "about:welcomeback",
|
||||
formdata: {
|
||||
id: {"sessionData": state},
|
||||
xpath: {}
|
||||
}
|
||||
};
|
||||
return {windows: [{tabs: [{entries: [wrappedState]}]}]};
|
||||
let url = "about:welcomeback";
|
||||
let formdata = {id: {sessionData: state}, url};
|
||||
return {windows: [{tabs: [{entries: [{url}], formdata}]}]};
|
||||
},
|
||||
/**
|
||||
* Asynchronously read session restore state (JSON) from a path
|
||||
|
||||
@@ -138,9 +138,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "PrivacyFilter",
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "RunState",
|
||||
"resource:///modules/sessionstore/RunState.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
|
||||
"resource://gre/modules/NetUtil.jsm");
|
||||
|
||||
#ifdef MOZ_DEVTOOLS
|
||||
|
||||
Object.defineProperty(this, "HUDService", {
|
||||
@@ -409,16 +406,6 @@ let SessionStoreInternal = {
|
||||
// Whether session has been initialized
|
||||
_sessionInitialized: false,
|
||||
|
||||
// The original "sessionstore.resume_session_once" preference value before it
|
||||
// was modified by saveState. saveState will set the
|
||||
// "sessionstore.resume_session_once" to true when the
|
||||
// the "sessionstore.resume_from_crash" preference is false (crash recovery
|
||||
// is disabled) so that pinned tabs will be restored in the case of a
|
||||
// crash. This variable is used to restore the original value so the
|
||||
// previous session is not always restored when
|
||||
// "sessionstore.resume_from_crash" is true.
|
||||
_resume_session_once_on_shutdown: null,
|
||||
|
||||
// Keep busy state counters per window.
|
||||
_windowBusyStates: new WeakMap(),
|
||||
|
||||
@@ -500,14 +487,9 @@ let SessionStoreInternal = {
|
||||
|
||||
if (this._needsRestorePage(state, this._recentCrashes)) {
|
||||
// replace the crashed session with a restore-page-only session
|
||||
let pageData = {
|
||||
url: "about:sessionrestore",
|
||||
formdata: {
|
||||
id: { "sessionData": state },
|
||||
xpath: {}
|
||||
}
|
||||
};
|
||||
state = { windows: [{ tabs: [{ entries: [pageData] }] }] };
|
||||
let url = "about:sessionrestore";
|
||||
let formdata = {id: {sessionData: state}, url};
|
||||
state = { windows: [{ tabs: [{ entries: [{url}], formdata }] }] };
|
||||
} else if (this._hasSingleTabWithURL(state.windows,
|
||||
"about:welcomeback")) {
|
||||
// On a single about:welcomeback URL that crashed, replace about:welcomeback
|
||||
@@ -544,20 +526,11 @@ let SessionStoreInternal = {
|
||||
this._prefBranch.getBoolPref("sessionstore.resume_session_once"))
|
||||
this._prefBranch.setBoolPref("sessionstore.resume_session_once", false);
|
||||
|
||||
this._initEncoding();
|
||||
|
||||
this._sessionInitialized = true;
|
||||
TelemetryStopwatch.finish("FX_SESSION_RESTORE_STARTUP_INIT_SESSION_MS");
|
||||
return state;
|
||||
},
|
||||
|
||||
_initEncoding : function ssi_initEncoding() {
|
||||
// The (UTF-8) encoder used to write to files.
|
||||
XPCOMUtils.defineLazyGetter(this, "_writeFileEncoder", function () {
|
||||
return new TextEncoder();
|
||||
});
|
||||
},
|
||||
|
||||
_initPrefs : function() {
|
||||
this._prefBranch = Services.prefs.getBranch("browser.");
|
||||
|
||||
@@ -864,7 +837,7 @@ let SessionStoreInternal = {
|
||||
// it happens before observers are notified
|
||||
this._globalState.setFromState(aInitialState);
|
||||
|
||||
let overwrite = this._isCmdLineEmpty(aWindow, aInitialState);
|
||||
let overwrite = this._isCmdLineEmpty(aWindow, aInitialState);
|
||||
let options = {firstWindow: true, overwriteTabs: overwrite};
|
||||
this.restoreWindow(aWindow, aInitialState, options);
|
||||
}
|
||||
@@ -1209,15 +1182,6 @@ let SessionStoreInternal = {
|
||||
// browser is about to exit anyway.
|
||||
Services.obs.removeObserver(this, "browser:purge-session-history");
|
||||
}
|
||||
else if (this._resume_session_once_on_shutdown != null) {
|
||||
// if the sessionstore.resume_session_once preference was changed by
|
||||
// saveState because crash recovery is disabled then restore the
|
||||
// preference back to the value it was prior to that. This will prevent
|
||||
// SessionStore from always restoring the session when crash recovery is
|
||||
// disabled.
|
||||
this._prefBranch.setBoolPref("sessionstore.resume_session_once",
|
||||
this._resume_session_once_on_shutdown);
|
||||
}
|
||||
|
||||
if (aData != "restart") {
|
||||
// Throw away the previous session on shutdown
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
var gStateObject;
|
||||
var gTreeData;
|
||||
@@ -20,19 +19,7 @@ window.onload = function() {
|
||||
return;
|
||||
}
|
||||
|
||||
// remove unneeded braces (added for compatibility with Firefox 2.0 and 3.0)
|
||||
if (sessionData.value.charAt(0) == '(')
|
||||
sessionData.value = sessionData.value.slice(1, -1);
|
||||
try {
|
||||
gStateObject = JSON.parse(sessionData.value);
|
||||
}
|
||||
catch (exJSON) {
|
||||
var s = new Cu.Sandbox("about:blank", {sandboxName: 'aboutSessionRestore'});
|
||||
gStateObject = Cu.evalInSandbox("(" + sessionData.value + ")", s);
|
||||
// If we couldn't parse the string with JSON.parse originally, make sure
|
||||
// that the value in the textbox will be parsable.
|
||||
sessionData.value = JSON.stringify(gStateObject);
|
||||
}
|
||||
gStateObject = JSON.parse(sessionData.value);
|
||||
|
||||
// make sure the data is tracked to be restored in case of a subsequent crash
|
||||
var event = document.createEvent("UIEvents");
|
||||
@@ -111,14 +98,20 @@ function restoreSession() {
|
||||
|
||||
// restore the session into a new window and close the current tab
|
||||
var newWindow = top.openDialog(top.location, "_blank", "chrome,dialog=no,all");
|
||||
newWindow.addEventListener("load", function() {
|
||||
newWindow.removeEventListener("load", arguments.callee, true);
|
||||
|
||||
var obs = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
|
||||
obs.addObserver(function observe(win, topic) {
|
||||
if (win != newWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs.removeObserver(observe, topic);
|
||||
ss.setWindowState(newWindow, stateString, true);
|
||||
|
||||
var tabbrowser = top.gBrowser;
|
||||
var tabIndex = tabbrowser.getBrowserIndexForDocument(document);
|
||||
tabbrowser.removeTab(tabbrowser.tabs[tabIndex]);
|
||||
}, true);
|
||||
}, "browser-delayed-startup-finished", false);
|
||||
}
|
||||
|
||||
function startNewSession() {
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const CRASH_SHENTRY = {url: "about:mozilla"};
|
||||
const CRASH_TAB = {entries: [CRASH_SHENTRY]};
|
||||
const CRASH_STATE = {windows: [{tabs: [CRASH_TAB]}]};
|
||||
|
||||
const TAB_FORMDATA = {id: {sessionData: CRASH_STATE}};
|
||||
const TAB_SHENTRY = {url: "about:sessionrestore", formdata: TAB_FORMDATA};
|
||||
const TAB_STATE = {entries: [TAB_SHENTRY]};
|
||||
|
||||
const FRAME_SCRIPT = "data:," +
|
||||
"content.document.getElementById('errorTryAgain').click()";
|
||||
|
||||
add_task(function* () {
|
||||
// Prepare a blank tab.
|
||||
let tab = gBrowser.addTab("about:blank");
|
||||
let browser = tab.linkedBrowser;
|
||||
yield promiseBrowserLoaded(browser);
|
||||
|
||||
// Fake a post-crash tab.
|
||||
ss.setTabState(tab, JSON.stringify(TAB_STATE));
|
||||
yield promiseTabRestored(tab);
|
||||
|
||||
ok(gBrowser.tabs.length > 1, "we have more than one tab");
|
||||
browser.messageManager.loadFrameScript(FRAME_SCRIPT, true);
|
||||
|
||||
// Wait until the new window was restored.
|
||||
let win = yield waitForNewWindow();
|
||||
yield promiseWindowClosed(win);
|
||||
|
||||
let [{tabs: [{entries: [{url}]}]}] = JSON.parse(ss.getClosedWindowData());
|
||||
is(url, "about:mozilla", "session was restored correctly");
|
||||
ss.forgetClosedWindow(0);
|
||||
});
|
||||
|
||||
function waitForNewWindow() {
|
||||
return new Promise(resolve => {
|
||||
Services.obs.addObserver(function observe(win, topic) {
|
||||
Services.obs.removeObserver(observe, topic);
|
||||
resolve(win);
|
||||
}, "browser-delayed-startup-finished", false);
|
||||
});
|
||||
}
|
||||
@@ -645,7 +645,15 @@ just addresses the organization to follow, e.g. "This site is run by " -->
|
||||
<!ENTITY webrtcIndicatorButton.label "Camera / Microphone Access">
|
||||
<!ENTITY webrtcIndicatorButton.tooltip "Display sites you are currently sharing your camera or microphone with">
|
||||
|
||||
<!ENTITY mixedContentBlocked.moreinfo "Most websites will still work properly even when this content is blocked.">
|
||||
<!-- Bad Content Blocker Doorhanger Notification -->
|
||||
<!ENTITY badContentBlocked.moreinfo "Most websites will work properly even if content is blocked.">
|
||||
|
||||
<!ENTITY mixedContentBlocked2.message "Insecure content">
|
||||
<!ENTITY mixedContentBlocked2.moreinfo "Some unencrypted elements on this website have been blocked.">
|
||||
<!ENTITY mixedContentBlocked2.learnMore "Learn More">
|
||||
<!ENTITY mixedContentBlocked2.options "Options">
|
||||
<!ENTITY mixedContentBlocked2.unblock.label "Disable protection for now">
|
||||
<!ENTITY mixedContentBlocked2.unblock.accesskey "D">
|
||||
|
||||
<!ENTITY pointerLock.notification.message "Press ESC at any time to show it again.">
|
||||
|
||||
|
||||
@@ -112,6 +112,11 @@ popupWarningDontShowFromMessage=Don't show this message when pop-ups are blocked
|
||||
popupWarningDontShowFromLocationbar=Don't show info bar when pop-ups are blocked
|
||||
popupShowPopupPrefix=Show '%S'
|
||||
|
||||
# Bad Content Blocker Doorhanger Notification
|
||||
# %S is brandShortName
|
||||
badContentBlocked.blocked.message=%S is blocking content on this page.
|
||||
badContentBlocked.notblocked.message=%S is not blocking any content on this page.
|
||||
|
||||
crashedpluginsMessage.title=The %S plugin has crashed.
|
||||
crashedpluginsMessage.reloadButton.label=Reload page
|
||||
crashedpluginsMessage.reloadButton.accesskey=R
|
||||
@@ -456,14 +461,6 @@ getUserMedia.sharingCamera.message2 = You are currently sharing your camera with
|
||||
getUserMedia.sharingMicrophone.message2 = You are currently sharing your microphone with this page.
|
||||
getUserMedia.sharingCameraAndMicrophone.message2 = You are currently sharing your camera and microphone with this page.
|
||||
|
||||
# Mixed Content Blocker Doorhanger Notification
|
||||
# LOCALIZATION NOTE - %S is brandShortName
|
||||
mixedContentBlocked.message = %S has blocked content that isn't secure.
|
||||
mixedContentBlocked.keepBlockingButton.label = Keep Blocking
|
||||
mixedContentBlocked.keepBlockingButton.accesskey = B
|
||||
mixedContentBlocked.unblock.label = Disable Protection on This Page
|
||||
mixedContentBlocked.unblock.accesskey = D
|
||||
|
||||
# LOCALIZATION NOTE - %S is brandShortName
|
||||
slowStartup.message = %S seems slow… to… start.
|
||||
slowStartup.helpButton.label = Learn How to Speed It Up
|
||||
|
||||
|
Before Width: | Height: | Size: 346 B After Width: | Height: | Size: 346 B |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
@@ -1922,6 +1922,7 @@ toolbar[mode="text"] toolbarbutton.chevron > .toolbarbutton-icon {
|
||||
%include ../../../toolkit/themes/shared/devtools/commandline.inc.css
|
||||
%endif
|
||||
%include ../shared/plugin-doorhanger.inc.css
|
||||
%include ../shared/badcontent-doorhanger.inc.css
|
||||
|
||||
%ifdef MOZ_DEVTOOLS
|
||||
.gcli-panel {
|
||||
|
||||
@@ -36,8 +36,8 @@ browser.jar:
|
||||
skin/classic/browser/identity-icons-https-mixed-active.png
|
||||
skin/classic/browser/Info.png
|
||||
skin/classic/browser/KUI-close.png
|
||||
skin/classic/browser/mixed-content-blocked-16.png
|
||||
skin/classic/browser/mixed-content-blocked-64.png
|
||||
skin/classic/browser/bad-content-blocked-16.png
|
||||
skin/classic/browser/bad-content-blocked-64.png
|
||||
skin/classic/browser/monitor.png
|
||||
skin/classic/browser/monitor_16-10.png
|
||||
skin/classic/browser/notification-16.png
|
||||
|
||||
|
Before Width: | Height: | Size: 346 B After Width: | Height: | Size: 346 B |
|
After Width: | Height: | Size: 691 B |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
@@ -2249,6 +2249,7 @@ toolbar[brighttext] #addonbar-closebutton {
|
||||
%include ../../../toolkit/themes/shared/devtools/commandline.inc.css
|
||||
%endif
|
||||
%include ../shared/plugin-doorhanger.inc.css
|
||||
%include ../shared/badcontent-doorhanger.inc.css
|
||||
|
||||
%ifdef MOZ_DEVTOOLS
|
||||
/* Error counter */
|
||||
|
||||
@@ -43,8 +43,10 @@ browser.jar:
|
||||
skin/classic/browser/livemark-folder.png
|
||||
skin/classic/browser/menu-back.png
|
||||
skin/classic/browser/menu-forward.png
|
||||
skin/classic/browser/mixed-content-blocked-16.png
|
||||
skin/classic/browser/mixed-content-blocked-64.png
|
||||
skin/classic/browser/bad-content-blocked-16.png
|
||||
skin/classic/browser/bad-content-blocked-16@2x.png
|
||||
skin/classic/browser/bad-content-blocked-64.png
|
||||
skin/classic/browser/bad-content-blocked-64@2x.png
|
||||
skin/classic/browser/monitor.png
|
||||
skin/classic/browser/monitor_16-10.png
|
||||
skin/classic/browser/notification-16.png
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
.popup-notification-item-title[popupid="bad-content"] {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.popup-notification-item-message[popupid="bad-content"] {
|
||||
width: 17em;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 346 B After Width: | Height: | Size: 346 B |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
@@ -2686,6 +2686,7 @@ toolbar[brighttext] #addonbar-closebutton {
|
||||
%include ../../../toolkit/themes/shared/devtools/commandline.inc.css
|
||||
%endif
|
||||
%include ../shared/plugin-doorhanger.inc.css
|
||||
%include ../shared/badcontent-doorhanger.inc.css
|
||||
|
||||
%ifdef MOZ_DEVTOOLS
|
||||
/* Error counter */
|
||||
|
||||
@@ -43,8 +43,8 @@ browser.jar:
|
||||
skin/classic/browser/livemark-folder.png
|
||||
skin/classic/browser/menu-back.png
|
||||
skin/classic/browser/menu-forward.png
|
||||
skin/classic/browser/mixed-content-blocked-16.png
|
||||
skin/classic/browser/mixed-content-blocked-64.png
|
||||
skin/classic/browser/bad-content-blocked-16.png
|
||||
skin/classic/browser/bad-content-blocked-64.png
|
||||
skin/classic/browser/monitor.png
|
||||
skin/classic/browser/monitor_16-10.png
|
||||
skin/classic/browser/notification-16.png
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
INSTALL_TARGETS += usecounterlist
|
||||
usecounterlist_FILES := UseCounterList.h
|
||||
usecounterlist_DEST = $(DIST)/include/mozilla/dom
|
||||
usecounterlist_TARGET := export
|
||||
@@ -0,0 +1,27 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#ifndef UseCounter_h_
|
||||
#define UseCounter_h_
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
enum UseCounter {
|
||||
eUseCounter_UNKNOWN = -1,
|
||||
#define USE_COUNTER_DOM_METHOD(interface_, name_) \
|
||||
eUseCounter_##interface_##_##name_,
|
||||
#define USE_COUNTER_DOM_ATTRIBUTE(interface_, name_) \
|
||||
eUseCounter_##interface_##_##name_,
|
||||
#define USE_COUNTER_CSS_PROPERTY(name_, id_) \
|
||||
eUseCounter_property_##id_,
|
||||
#include "mozilla/dom/UseCounterList.h"
|
||||
#undef USE_COUNTER_DOM_METHOD
|
||||
#undef USE_COUNTER_DOM_ATTRIBUTE
|
||||
#undef USE_COUNTER_CSS_PROPERTY
|
||||
eUseCounter_Count
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,33 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
// This file defines a list of use counters, which are things that can
|
||||
// record usage of Web platform features and then report this information
|
||||
// through Telemetry.
|
||||
//
|
||||
// The format of this file is very strict. Each line can be:
|
||||
//
|
||||
// (a) a blank line
|
||||
//
|
||||
// (b) a comment, which is a line that begins with "//"
|
||||
//
|
||||
// (c) an #if/ifdef/else/endif preprocessor directive
|
||||
//
|
||||
// (d) one of three possible use counter declarations:
|
||||
//
|
||||
// method <IDL interface name>.<IDL operation name>
|
||||
// attribute <IDL interface name>.<IDL attribute name>
|
||||
// property <CSS property name>
|
||||
//
|
||||
// To actually cause use counters to be incremented, DOM methods
|
||||
// and attributes must have a [UseCounter] extended attribute in
|
||||
// the Web IDL file, and CSS properties must be declared with
|
||||
// the CSS_PROPERTY_HAS_USE_COUNTER flag in nsCSSPropList.h.
|
||||
//
|
||||
// You might reasonably ask why we have this file and we require
|
||||
// annotating things with [UseCounter] in the relevant WebIDL file as
|
||||
// well. Generating things from bindings codegen and ensuring all the
|
||||
// dependencies were correct would have been rather difficult, and
|
||||
// annotating the WebIDL files does nothing for identifying CSS
|
||||
// property usage, which we would also like to track.
|
||||
@@ -0,0 +1,79 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
sys.path.append(os.path.dirname(__file__))
|
||||
|
||||
import usecounters
|
||||
|
||||
AUTOGENERATED_WARNING_COMMENT = "/* THIS FILE IS AUTOGENERATED BY gen-usercounters.py - DO NOT EDIT */"
|
||||
|
||||
def generate_list(f, counters):
|
||||
def print_optional_macro_declare(name):
|
||||
print('''
|
||||
#ifndef %(name)s
|
||||
#define %(name)s(interface_, name_) // nothing
|
||||
#define DEFINED_%(name)s
|
||||
#endif
|
||||
''' % { 'name': name }, file=f)
|
||||
|
||||
def print_optional_macro_undeclare(name):
|
||||
print('''
|
||||
#ifdef DEFINED_%(name)s
|
||||
#undef DEFINED_%(name)s
|
||||
#undef %(name)s
|
||||
#endif
|
||||
''' % { 'name': name }, file=f)
|
||||
|
||||
print(AUTOGENERATED_WARNING_COMMENT, file=f)
|
||||
|
||||
print_optional_macro_declare('USE_COUNTER_DOM_METHOD')
|
||||
print_optional_macro_declare('USE_COUNTER_DOM_ATTRIBUTE')
|
||||
print_optional_macro_declare('USE_COUNTER_CSS_PROPERTY')
|
||||
|
||||
for counter in counters:
|
||||
if counter['type'] == 'method':
|
||||
print('USE_COUNTER_DOM_METHOD(%s, %s)' % (counter['interface_name'], counter['method_name']), file=f)
|
||||
elif counter['type'] == 'attribute':
|
||||
print('USE_COUNTER_DOM_ATTRIBUTE(%s, %s)' % (counter['interface_name'], counter['attribute_name']), file=f)
|
||||
elif counter['type'] == 'property':
|
||||
prop = counter['property_name']
|
||||
print('USE_COUNTER_CSS_PROPERTY(%s, %s)' % (prop, prop.replace('-', '_')), file=f)
|
||||
|
||||
print_optional_macro_undeclare('USE_COUNTER_DOM_METHOD')
|
||||
print_optional_macro_undeclare('USE_COUNTER_DOM_ATTRIBUTE')
|
||||
print_optional_macro_undeclare('USE_COUNTER_CSS_PROPERTY')
|
||||
|
||||
def generate_property_map(f, counters):
|
||||
print(AUTOGENERATED_WARNING_COMMENT, file=f)
|
||||
print('''
|
||||
enum {
|
||||
// XXX is this the right define?
|
||||
#define CSS_PROP_LIST_INCLUDE_LOGICAL
|
||||
#define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, \\
|
||||
kwtable_, stylestruct_, stylestructoffset_, animtype_) \\
|
||||
USE_COUNTER_FOR_CSS_PROPERTY_##id_ = eUseCounter_UNKNOWN,
|
||||
#include "nsCSSPropList.h"
|
||||
#undef CSS_PROP
|
||||
#undef CSS_PROP_LIST_INCLUDE_LOGICAL
|
||||
};
|
||||
''', file=f)
|
||||
for counter in counters:
|
||||
if counter['type'] == 'property':
|
||||
prop = counter['property_name'].replace('-', '_')
|
||||
print('#define USE_COUNTER_FOR_CSS_PROPERTY_%s eUseCounter_property_%s' % (prop, prop), file=f)
|
||||
|
||||
def use_counter_list(output_header, conf_filename):
|
||||
counters = usecounters.read_conf(conf_filename)
|
||||
generate_list(output_header, counters)
|
||||
|
||||
def property_map(output_map, conf_filename):
|
||||
counters = usecounters.read_conf(conf_filename)
|
||||
generate_property_map(output_map, counters)
|
||||
@@ -142,6 +142,7 @@ EXPORTS.mozilla += [
|
||||
'CORSMode.h',
|
||||
'FeedWriterEnabled.h',
|
||||
'TextInputProcessor.h',
|
||||
'UseCounter.h',
|
||||
]
|
||||
|
||||
EXPORTS.mozilla.dom += [
|
||||
@@ -457,3 +458,16 @@ if CONFIG['MOZ_BUILD_APP'] in ['browser', 'mobile/android', 'xulrunner']:
|
||||
|
||||
if CONFIG['MOZ_X11']:
|
||||
CXXFLAGS += CONFIG['TK_CFLAGS']
|
||||
|
||||
GENERATED_FILES += [
|
||||
'PropertyUseCounterMap.inc',
|
||||
'UseCounterList.h',
|
||||
]
|
||||
|
||||
countermap = GENERATED_FILES['PropertyUseCounterMap.inc']
|
||||
countermap.script = 'gen-usecounters.py:property_map'
|
||||
countermap.inputs = ['UseCounters.conf']
|
||||
|
||||
counterlist = GENERATED_FILES['UseCounterList.h']
|
||||
counterlist.script = 'gen-usecounters.py:use_counter_list'
|
||||
counterlist.inputs = ['UseCounters.conf']
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
# 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/.
|
||||
|
||||
import buildconfig
|
||||
import collections
|
||||
import re
|
||||
import StringIO
|
||||
import sys
|
||||
|
||||
from mozbuild.preprocessor import preprocess
|
||||
|
||||
def read_conf(conf_filename):
|
||||
# Invoking the preprocessor ourselves is easier than writing build rules
|
||||
# to do it for us.
|
||||
processed = StringIO.StringIO()
|
||||
preprocess(includes=[conf_filename],
|
||||
defines=buildconfig.defines,
|
||||
output=processed)
|
||||
|
||||
# Can't read/write from a single StringIO, so make a new one for reading.
|
||||
stream = StringIO.StringIO(processed.getvalue())
|
||||
|
||||
def parse_counters(stream):
|
||||
for line_num, line in enumerate(stream):
|
||||
line = line.rstrip('\n')
|
||||
if not line or line.startswith('//'):
|
||||
# empty line or comment
|
||||
continue
|
||||
m = re.match(r'method ([A-Za-z0-9]+)\.([A-Za-z0-9]+)$', line)
|
||||
if m:
|
||||
interface_name, method_name = m.groups()
|
||||
yield { 'type': 'method',
|
||||
'interface_name': interface_name,
|
||||
'method_name': method_name }
|
||||
continue
|
||||
m = re.match(r'attribute ([A-Za-z0-9]+)\.([A-Za-z0-9]+)$', line)
|
||||
if m:
|
||||
interface_name, attribute_name = m.groups()
|
||||
yield { 'type': 'attribute',
|
||||
'interface_name': interface_name,
|
||||
'attribute_name': attribute_name }
|
||||
continue
|
||||
m = re.match(r'property ([a-z0-9-]+)$', line)
|
||||
if m:
|
||||
property_name = m.group(1)
|
||||
yield { 'type': 'property',
|
||||
'property_name': property_name }
|
||||
continue
|
||||
raise ValueError('error parsing %s at line %d' % (conf_filename, line_num))
|
||||
|
||||
return parse_counters(stream)
|
||||
|
||||
def generate_histograms(filename):
|
||||
# The mapping for use counters to telemetry histograms depends on the
|
||||
# ordering of items in the dictionary.
|
||||
items = collections.OrderedDict()
|
||||
for counter in read_conf(filename):
|
||||
def append_counter(name, desc):
|
||||
items[name] = { 'expires_in_version': 'never',
|
||||
'kind' : 'boolean',
|
||||
'description': desc }
|
||||
|
||||
def append_counters(name, desc):
|
||||
append_counter('USE_COUNTER_%s_DOCUMENT' % name, 'Whether a document %s' % desc)
|
||||
append_counter('USE_COUNTER_%s_PAGE' % name, 'Whether a page %s' % desc)
|
||||
|
||||
if counter['type'] == 'method':
|
||||
method = '%s.%s' % (counter['interface_name'], counter['method_name'])
|
||||
append_counters(method.replace('.', '_').upper(), 'called %s' % method)
|
||||
elif counter['type'] == 'attribute':
|
||||
attr = '%s.%s' % (counter['interface_name'], counter['attribute_name'])
|
||||
append_counters(attr.replace('.', '_').upper(), 'got or set %s' % attr)
|
||||
elif counter['type'] == 'property':
|
||||
prop = counter['property_name']
|
||||
append_counters('PROPERTY_%s' % prop.replace('-', '_').upper(), "used the '%s' property" % prop)
|
||||
|
||||
return items
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "mozilla/layers/PCompositorChild.h"
|
||||
#include "mozilla/layers/SharedBufferManagerChild.h"
|
||||
#include "mozilla/net/NeckoChild.h"
|
||||
#include "mozilla/plugins/PluginInstanceParent.h"
|
||||
#include "mozilla/plugins/PluginModuleParent.h"
|
||||
|
||||
#if defined(MOZ_CONTENT_SANDBOX)
|
||||
@@ -2624,11 +2625,10 @@ ContentChild::RecvShutdown()
|
||||
if (os) {
|
||||
os->NotifyObservers(this, "content-child-shutdown", nullptr);
|
||||
}
|
||||
// Let the parent know we're done and let it close the channel.
|
||||
// Both sides will clean up even if an error occurs here.
|
||||
MessageLoop::current()->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableMethod(this, &ContentChild::SendFinishShutdown));
|
||||
|
||||
// Ignore errors here. If this fails, the parent will kill us after a
|
||||
// timeout.
|
||||
unused << SendFinishShutdown();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2644,6 +2644,26 @@ ContentChild::GetBrowserOrId(TabChild* aTabChild)
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ContentChild::RecvUpdateWindow(const uintptr_t& aChildId)
|
||||
{
|
||||
#if defined(XP_WIN)
|
||||
NS_ASSERTION(aChildId, "Expected child hwnd value for remote plugin instance.");
|
||||
mozilla::plugins::PluginInstanceParent* parentInstance =
|
||||
mozilla::plugins::PluginInstanceParent::LookupPluginInstanceByID(aChildId);
|
||||
NS_ASSERTION(parentInstance, "Expected matching plugin instance");
|
||||
if (parentInstance) {
|
||||
// sync! update call to the plugin instance that forces the
|
||||
// plugin to paint its child window.
|
||||
parentInstance->CallUpdateWindow();
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
NS_NOTREACHED("ContentChild::RecvUpdateWindow calls unexpected on this platform.");
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
// This code goes here rather than nsGlobalWindow.cpp because nsGlobalWindow.cpp
|
||||
// can't include ContentChild.h since it includes windows.h.
|
||||
|
||||
|
||||
@@ -372,6 +372,7 @@ public:
|
||||
const base::ProcessId& aProcessId) override;
|
||||
virtual bool RecvLoadPluginResult(const uint32_t& aPluginId,
|
||||
const bool& aResult) override;
|
||||
virtual bool RecvUpdateWindow(const uintptr_t& aChildId) override;
|
||||
|
||||
virtual bool RecvStartProfiler(const uint32_t& aEntries,
|
||||
const double& aInterval,
|
||||
|
||||
@@ -854,6 +854,27 @@ ContentParent::GetInitialProcessPriority(Element* aFrameElement)
|
||||
PROCESS_PRIORITY_FOREGROUND;
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
extern const wchar_t* kPluginWidgetContentParentProperty;
|
||||
|
||||
/*static*/ void
|
||||
ContentParent::SendAsyncUpdate(nsIWidget* aWidget)
|
||||
{
|
||||
if (!aWidget || aWidget->Destroyed()) {
|
||||
return;
|
||||
}
|
||||
printf_stderr("TabParent::SendAsyncUpdate()\n");
|
||||
// Fire off an async request to the plugin to paint its window
|
||||
HWND hwnd = (HWND)aWidget->GetNativeData(NS_NATIVE_WINDOW);
|
||||
NS_ASSERTION(hwnd, "Expected valid hwnd value.");
|
||||
ContentParent* cp = reinterpret_cast<ContentParent*>(
|
||||
::GetPropW(hwnd, kPluginWidgetContentParentProperty));
|
||||
if (cp && !cp->IsDestroyed()) {
|
||||
cp->SendUpdateWindow((uintptr_t)hwnd);
|
||||
}
|
||||
}
|
||||
#endif // defined(XP_WIN)
|
||||
|
||||
bool
|
||||
ContentParent::PreallocatedProcessReady()
|
||||
{
|
||||
@@ -1538,8 +1559,7 @@ ContentParent::ShutDownProcess(ShutDownMethod aMethod)
|
||||
// other methods. We first call Shutdown() in the child. After the child is
|
||||
// ready, it calls FinishShutdown() on us. Then we close the channel.
|
||||
if (aMethod == SEND_SHUTDOWN_MESSAGE) {
|
||||
|
||||
if (SendShutdown()) {
|
||||
if (mIPCOpen && SendShutdown()) {
|
||||
mShutdownPending = true;
|
||||
}
|
||||
|
||||
@@ -1803,7 +1823,7 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
|
||||
|
||||
// Signal shutdown completion regardless of error state,
|
||||
// so we can finish waiting in the xpcom-shutdown observer.
|
||||
mShutdownComplete = true;
|
||||
mIPCOpen = false;
|
||||
|
||||
if (why == NormalShutdown && !mCalledClose) {
|
||||
// If we shut down normally but haven't called Close, assume somebody
|
||||
@@ -1999,7 +2019,7 @@ ContentParent::InitializeMembers()
|
||||
mCalledKillHard = false;
|
||||
mCreatedPairedMinidumps = false;
|
||||
mShutdownPending = false;
|
||||
mShutdownComplete = false;
|
||||
mIPCOpen = true;
|
||||
mHangMonitorActor = nullptr;
|
||||
}
|
||||
|
||||
@@ -2741,15 +2761,15 @@ ContentParent::Observe(nsISupports* aSubject,
|
||||
const char16_t* aData)
|
||||
{
|
||||
if (!strcmp(aTopic, "xpcom-shutdown") && mSubprocess) {
|
||||
if (mShutdownPending) {
|
||||
// Wait for shutdown to complete, so that we receive any shutdown
|
||||
// data (e.g. telemetry) from the child before we quit.
|
||||
while (!mShutdownComplete) {
|
||||
NS_ProcessNextEvent(nullptr, true);
|
||||
}
|
||||
} else {
|
||||
// Just close the channel if we never tried shutting down.
|
||||
ShutDownProcess(CLOSE_CHANNEL);
|
||||
if (!mShutdownPending && mIPCOpen) {
|
||||
ShutDownProcess(SEND_SHUTDOWN_MESSAGE);
|
||||
}
|
||||
|
||||
// Wait for shutdown to complete, so that we receive any shutdown
|
||||
// data (e.g. telemetry) from the child before we quit.
|
||||
// This loop terminate prematurely based on mForceKillTimer.
|
||||
while (mIPCOpen) {
|
||||
NS_ProcessNextEvent(nullptr, true);
|
||||
}
|
||||
NS_ASSERTION(!mSubprocess, "Close should have nulled mSubprocess");
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ class nsIDOMBlob;
|
||||
class nsIDumpGCAndCCLogsCallback;
|
||||
class nsIMemoryReporter;
|
||||
class ParentIdleListener;
|
||||
class nsIWidget;
|
||||
|
||||
namespace mozilla {
|
||||
class PRemoteSpellcheckEngineParent;
|
||||
@@ -143,6 +144,20 @@ public:
|
||||
|
||||
static void NotifyUpdatedDictionaries();
|
||||
|
||||
#if defined(XP_WIN)
|
||||
/**
|
||||
* Windows helper for firing off an update window request to a plugin
|
||||
* instance.
|
||||
*
|
||||
* aWidget - the eWindowType_plugin_ipc_chrome widget associated with
|
||||
* this plugin window.
|
||||
*/
|
||||
static void SendAsyncUpdate(nsIWidget* aWidget);
|
||||
#endif
|
||||
|
||||
// Let managees query if it is safe to send messages.
|
||||
bool IsDestroyed() { return !mIPCOpen; }
|
||||
|
||||
virtual bool RecvCreateChildProcess(const IPCTabContext& aContext,
|
||||
const hal::ProcessPriority& aPriority,
|
||||
const TabId& aOpenerTabId,
|
||||
@@ -831,7 +846,7 @@ private:
|
||||
bool mCalledKillHard;
|
||||
bool mCreatedPairedMinidumps;
|
||||
bool mShutdownPending;
|
||||
bool mShutdownComplete;
|
||||
bool mIPCOpen;
|
||||
|
||||
nsRefPtr<nsConsoleService> mConsoleService;
|
||||
nsConsoleService* GetConsoleService();
|
||||
|
||||
@@ -569,6 +569,12 @@ child:
|
||||
|
||||
async LoadProcessScript(nsString url);
|
||||
|
||||
/**
|
||||
* Requests a full native update of a native plugin child window. This is
|
||||
* a Windows specific call.
|
||||
*/
|
||||
async UpdateWindow(uintptr_t aChildId);
|
||||
|
||||
parent:
|
||||
/**
|
||||
* Tell the parent process a new accessible document has been created.
|
||||
|
||||
@@ -31,11 +31,7 @@ sync protocol PPluginWidget {
|
||||
|
||||
parent:
|
||||
async __delete__();
|
||||
|
||||
parent:
|
||||
sync Create() returns (nsresult aResult);
|
||||
|
||||
async Destroy();
|
||||
async SetFocus(bool aRaise);
|
||||
|
||||
/**
|
||||
@@ -45,18 +41,6 @@ parent:
|
||||
* native HWND of the plugin widget.
|
||||
*/
|
||||
sync GetNativePluginPort() returns (uintptr_t value);
|
||||
|
||||
child:
|
||||
/**
|
||||
* Event indicating the parent is shutting down.
|
||||
* aWhichSide - indicates which side intititated the shutdown.
|
||||
*/
|
||||
async ParentShutdown(uint16_t aWhichSide);
|
||||
|
||||
/**
|
||||
* Requests a full update of the plugin window.
|
||||
*/
|
||||
async UpdateWindow(uintptr_t aChildId);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -265,7 +265,8 @@ public:
|
||||
Create(nsIContentChild* aManager, const TabId& aTabId, const TabContext& aContext, uint32_t aChromeFlags);
|
||||
|
||||
bool IsRootContentDocument();
|
||||
|
||||
// Let managees query if it is safe to send messages.
|
||||
bool IsDestroyed() { return mDestroyed; }
|
||||
const TabId GetTabId() const {
|
||||
MOZ_ASSERT(mUniqueId != 0);
|
||||
return mUniqueId;
|
||||
|
||||
@@ -3,18 +3,17 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/plugins/PluginWidgetChild.h"
|
||||
|
||||
#include "mozilla/dom/TabChild.h"
|
||||
#include "mozilla/plugins/PluginWidgetParent.h"
|
||||
#include "PluginWidgetProxy.h"
|
||||
|
||||
#include "mozilla/unused.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "nsDebug.h"
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#include "mozilla/plugins/PluginInstanceParent.h"
|
||||
using mozilla::plugins::PluginInstanceParent;
|
||||
#endif
|
||||
|
||||
#define PWLOG(...)
|
||||
// #define PWLOG(...) printf_stderr(__VA_ARGS__)
|
||||
//#define PWLOG(...) printf_stderr(__VA_ARGS__)
|
||||
|
||||
namespace mozilla {
|
||||
namespace plugins {
|
||||
@@ -22,11 +21,13 @@ namespace plugins {
|
||||
PluginWidgetChild::PluginWidgetChild() :
|
||||
mWidget(nullptr)
|
||||
{
|
||||
PWLOG("PluginWidgetChild::PluginWidgetChild()\n");
|
||||
MOZ_COUNT_CTOR(PluginWidgetChild);
|
||||
}
|
||||
|
||||
PluginWidgetChild::~PluginWidgetChild()
|
||||
{
|
||||
PWLOG("PluginWidgetChild::~PluginWidgetChild()\n");
|
||||
MOZ_COUNT_DTOR(PluginWidgetChild);
|
||||
}
|
||||
|
||||
@@ -37,8 +38,11 @@ PluginWidgetChild::ProxyShutdown()
|
||||
{
|
||||
PWLOG("PluginWidgetChild::ProxyShutdown()\n");
|
||||
if (mWidget) {
|
||||
SendDestroy();
|
||||
mWidget = nullptr;
|
||||
auto tab = static_cast<mozilla::dom::TabChild*>(Manager());
|
||||
if (!tab->IsDestroyed()) {
|
||||
unused << Send__delete__(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,40 +59,9 @@ PluginWidgetChild::KillWidget()
|
||||
void
|
||||
PluginWidgetChild::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
PWLOG("PluginWidgetChild::ActorDestroy()\n");
|
||||
PWLOG("PluginWidgetChild::ActorDestroy(%d)\n", aWhy);
|
||||
KillWidget();
|
||||
}
|
||||
|
||||
bool
|
||||
PluginWidgetChild::RecvParentShutdown(const uint16_t& aType)
|
||||
{
|
||||
PWLOG("PluginWidgetChild::RecvParentShutdown()\n");
|
||||
KillWidget();
|
||||
if (aType == PluginWidgetParent::CONTENT) {
|
||||
Send__delete__(this);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginWidgetChild::RecvUpdateWindow(const uintptr_t& aChildId)
|
||||
{
|
||||
#if defined(XP_WIN)
|
||||
NS_ASSERTION(aChildId, "Expected child hwnd value for remote plugin instance.");
|
||||
PluginInstanceParent* parentInstance =
|
||||
PluginInstanceParent::LookupPluginInstanceByID(aChildId);
|
||||
NS_ASSERTION(parentInstance, "Expected matching plugin instance");
|
||||
if (parentInstance) {
|
||||
// sync! update call to the plugin instance that forces the
|
||||
// plugin to paint its child window.
|
||||
parentInstance->CallUpdateWindow();
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
NS_NOTREACHED("PluginWidgetChild::RecvUpdateWindow calls unexpected on this platform.");
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace plugins
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -19,9 +19,7 @@ public:
|
||||
PluginWidgetChild();
|
||||
virtual ~PluginWidgetChild();
|
||||
|
||||
virtual bool RecvUpdateWindow(const uintptr_t& aChildId) override;
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
virtual bool RecvParentShutdown(const uint16_t& aType) override;
|
||||
|
||||
void SetWidget(mozilla::widget::PluginWidgetProxy* aWidget) {
|
||||
mWidget = aWidget;
|
||||
|
||||
@@ -7,9 +7,10 @@
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsWidgetsCID.h"
|
||||
|
||||
#include "mozilla/unused.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "nsDebug.h"
|
||||
#include "mozilla/unused.h"
|
||||
|
||||
#if defined(MOZ_WIDGET_GTK)
|
||||
#include "nsPluginNativeWindowGtk.h"
|
||||
@@ -19,17 +20,20 @@ using namespace mozilla;
|
||||
using namespace mozilla::widget;
|
||||
|
||||
#define PWLOG(...)
|
||||
// #define PWLOG(...) printf_stderr(__VA_ARGS__)
|
||||
//#define PWLOG(...) printf_stderr(__VA_ARGS__)
|
||||
|
||||
#if defined(XP_WIN)
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
// For nsWindow
|
||||
const wchar_t* kPluginWidgetContentParentProperty =
|
||||
L"kPluginWidgetParentProperty";
|
||||
} }
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace plugins {
|
||||
|
||||
#if defined(XP_WIN)
|
||||
// For nsWindow
|
||||
const wchar_t* kPluginWidgetParentProperty =
|
||||
L"kPluginWidgetParentProperty";
|
||||
#endif
|
||||
|
||||
static NS_DEFINE_CID(kWidgetCID, NS_CHILD_CID);
|
||||
|
||||
// This macro returns true to prevent an abort in the child process when
|
||||
@@ -41,22 +45,6 @@ static NS_DEFINE_CID(kWidgetCID, NS_CHILD_CID);
|
||||
} \
|
||||
}
|
||||
|
||||
/*
|
||||
* Tear down scenarios
|
||||
* layout (plugin content unloading):
|
||||
* - PluginWidgetProxy::Destroy() calls PluginWidgetChild::ProxyShutdown(), calls SendDestroy()
|
||||
* - PluginWidgetParent::RecvDestroy(), sends async ParentShutdown(CONTENT)
|
||||
* - PluginWidgetChild::RecvParentShutdown(CONTENT), calls Send__delete__()
|
||||
* - PluginWidgetParent::ActorDestroy() called in response to __delete__
|
||||
* PBrowser teardown (tab closing):
|
||||
* - PluginWidgetParent::ParentDestroy() called by TabParent::Destroy(), sends async ParentShutdown(TAB_CLOSURE)
|
||||
* - PluginWidgetChild::RecvParentShutdown(TAB_CLOSURE) (PluginWidgetProxy disabled)
|
||||
* - PluginWidgetParent::ActorDestroy()
|
||||
* - PluginWidgetParent::~PluginWidgetParent() in response to PBrowserParent::DeallocSubtree()
|
||||
* - PluginWidgetChild::ActorDestroy() from PPluginWidgetChild::DestroySubtree
|
||||
* - ~PluginWidgetChild() in response to PBrowserChild::DeallocSubtree()
|
||||
**/
|
||||
|
||||
PluginWidgetParent::PluginWidgetParent()
|
||||
{
|
||||
PWLOG("PluginWidgetParent::PluginWidgetParent()\n");
|
||||
@@ -70,18 +58,7 @@ PluginWidgetParent::~PluginWidgetParent()
|
||||
// A destroy call can actually get skipped if a widget is associated
|
||||
// with the last out-of-process page, make sure and cleanup any left
|
||||
// over widgets if we have them.
|
||||
if (mWidget) {
|
||||
#if defined(MOZ_WIDGET_GTK)
|
||||
mWidget->SetNativeData(NS_NATIVE_PLUGIN_OBJECT_PTR, (uintptr_t)0);
|
||||
mWrapper = nullptr;
|
||||
#elif defined(XP_WIN)
|
||||
::RemovePropW((HWND)mWidget->GetNativeData(NS_NATIVE_WINDOW),
|
||||
kPluginWidgetParentProperty);
|
||||
#endif
|
||||
mWidget->UnregisterPluginWindowForRemoteUpdates();
|
||||
mWidget->Destroy();
|
||||
mWidget = nullptr;
|
||||
}
|
||||
KillWidget();
|
||||
}
|
||||
|
||||
mozilla::dom::TabParent*
|
||||
@@ -98,25 +75,6 @@ PluginWidgetParent::SetParent(nsIWidget* aParent)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
// static
|
||||
void
|
||||
PluginWidgetParent::SendAsyncUpdate(nsIWidget* aWidget)
|
||||
{
|
||||
if (!aWidget || aWidget->Destroyed()) {
|
||||
return;
|
||||
}
|
||||
// Fire off an async request to the plugin to paint its window
|
||||
HWND hwnd = (HWND)aWidget->GetNativeData(NS_NATIVE_WINDOW);
|
||||
NS_ASSERTION(hwnd, "Expected valid hwnd value.");
|
||||
PluginWidgetParent* parent = reinterpret_cast<PluginWidgetParent*>(
|
||||
::GetPropW(hwnd, mozilla::plugins::kPluginWidgetParentProperty));
|
||||
if (parent && !parent->ActorDestroyed()) {
|
||||
parent->SendUpdateWindow((uintptr_t)hwnd);
|
||||
}
|
||||
}
|
||||
#endif // defined(XP_WIN)
|
||||
|
||||
// When plugins run in chrome, nsPluginNativeWindow(Plat) implements platform
|
||||
// specific functionality that wraps plugin widgets. With e10s we currently
|
||||
// bypass this code on Window, and reuse a bit of it on Linux. Content still
|
||||
@@ -135,6 +93,7 @@ PluginWidgetParent::RecvCreate(nsresult* aResult)
|
||||
// we can send over to content -> plugin.
|
||||
PLUG_NewPluginNativeWindow((nsPluginNativeWindow**)&mWrapper);
|
||||
if (!mWrapper) {
|
||||
KillWidget();
|
||||
return false;
|
||||
}
|
||||
// Give a copy of this to the widget, which handles some update
|
||||
@@ -147,6 +106,7 @@ PluginWidgetParent::RecvCreate(nsresult* aResult)
|
||||
// If this fails, bail.
|
||||
if (!parentWidget) {
|
||||
*aResult = NS_ERROR_NOT_AVAILABLE;
|
||||
KillWidget();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -158,8 +118,7 @@ PluginWidgetParent::RecvCreate(nsresult* aResult)
|
||||
*aResult = mWidget->Create(parentWidget.get(), nullptr, nsIntRect(0,0,0,0),
|
||||
&initData);
|
||||
if (NS_FAILED(*aResult)) {
|
||||
mWidget->Destroy();
|
||||
mWidget = nullptr;
|
||||
KillWidget();
|
||||
// This should never fail, abort.
|
||||
return false;
|
||||
}
|
||||
@@ -178,7 +137,8 @@ PluginWidgetParent::RecvCreate(nsresult* aResult)
|
||||
#elif defined(XP_WIN)
|
||||
DebugOnly<DWORD> winres =
|
||||
::SetPropW((HWND)mWidget->GetNativeData(NS_NATIVE_WINDOW),
|
||||
kPluginWidgetParentProperty, this);
|
||||
mozilla::dom::kPluginWidgetContentParentProperty,
|
||||
GetTabParent()->Manager()->AsContentParent());
|
||||
NS_ASSERTION(winres, "SetPropW call failure");
|
||||
#endif
|
||||
|
||||
@@ -192,21 +152,29 @@ PluginWidgetParent::RecvCreate(nsresult* aResult)
|
||||
}
|
||||
|
||||
void
|
||||
PluginWidgetParent::Shutdown(ShutdownType aType)
|
||||
PluginWidgetParent::KillWidget()
|
||||
{
|
||||
PWLOG("PluginWidgetParent::KillWidget() widget=%p\n", (void*)mWidget.get());
|
||||
if (mWidget) {
|
||||
mWidget->UnregisterPluginWindowForRemoteUpdates();
|
||||
DebugOnly<nsresult> rv = mWidget->Destroy();
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "widget destroy failure");
|
||||
#if defined(MOZ_WIDGET_GTK)
|
||||
mWidget->SetNativeData(NS_NATIVE_PLUGIN_OBJECT_PTR, (uintptr_t)0);
|
||||
mWrapper = nullptr;
|
||||
#elif defined(XP_WIN)
|
||||
::RemovePropW((HWND)mWidget->GetNativeData(NS_NATIVE_WINDOW),
|
||||
mozilla::dom::kPluginWidgetContentParentProperty);
|
||||
#endif
|
||||
mWidget = nullptr;
|
||||
unused << SendParentShutdown(aType);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PluginWidgetParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
PWLOG("PluginWidgetParent::ActorDestroy()\n");
|
||||
PWLOG("PluginWidgetParent::ActorDestroy(%d)\n", aWhy);
|
||||
KillWidget();
|
||||
}
|
||||
|
||||
// Called by TabParent's Destroy() in response to an early tear down (Early
|
||||
@@ -216,17 +184,6 @@ void
|
||||
PluginWidgetParent::ParentDestroy()
|
||||
{
|
||||
PWLOG("PluginWidgetParent::ParentDestroy()\n");
|
||||
Shutdown(TAB_CLOSURE);
|
||||
}
|
||||
|
||||
// Called by the child when a plugin is torn down within a tab
|
||||
// normally. Messages back via ParentShutdown().
|
||||
bool
|
||||
PluginWidgetParent::RecvDestroy()
|
||||
{
|
||||
PWLOG("PluginWidgetParent::RecvDestroy()\n");
|
||||
Shutdown(CONTENT);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -242,7 +199,6 @@ bool
|
||||
PluginWidgetParent::RecvGetNativePluginPort(uintptr_t* value)
|
||||
{
|
||||
ENSURE_CHANNEL;
|
||||
PWLOG("PluginWidgetParent::RecvGetNativeData()\n");
|
||||
#if defined(MOZ_WIDGET_GTK)
|
||||
*value = (uintptr_t)mWrapper->window;
|
||||
NS_ASSERTION(*value, "no xid??");
|
||||
|
||||
@@ -24,20 +24,11 @@ namespace plugins {
|
||||
class PluginWidgetParent : public PPluginWidgetParent
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Windows helper for firing off an update window request to a plugin.
|
||||
*
|
||||
* aWidget - the eWindowType_plugin_ipc_chrome widget associated with
|
||||
* this plugin window.
|
||||
*/
|
||||
static void SendAsyncUpdate(nsIWidget* aWidget);
|
||||
|
||||
PluginWidgetParent();
|
||||
virtual ~PluginWidgetParent();
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
virtual bool RecvCreate(nsresult* aResult) override;
|
||||
virtual bool RecvDestroy() override;
|
||||
virtual bool RecvSetFocus(const bool& aRaise) override;
|
||||
virtual bool RecvGetNativePluginPort(uintptr_t* value) override;
|
||||
|
||||
@@ -54,15 +45,8 @@ private:
|
||||
// The tab our connection is associated with.
|
||||
mozilla::dom::TabParent* GetTabParent();
|
||||
|
||||
public:
|
||||
// Identifies the side of the connection that initiates shutdown.
|
||||
enum ShutdownType {
|
||||
TAB_CLOSURE = 1,
|
||||
CONTENT = 2
|
||||
};
|
||||
|
||||
private:
|
||||
void Shutdown(ShutdownType aType);
|
||||
void KillWidget();
|
||||
|
||||
// The chrome side native widget.
|
||||
nsCOMPtr<nsIWidget> mWidget;
|
||||
|
||||
@@ -1127,7 +1127,7 @@ public:
|
||||
MappedAttrParser(css::Loader* aLoader,
|
||||
nsIURI* aDocURI,
|
||||
already_AddRefed<nsIURI> aBaseURI,
|
||||
nsIPrincipal* aNodePrincipal);
|
||||
nsSVGElement* aElement);
|
||||
~MappedAttrParser();
|
||||
|
||||
// Parses a mapped attribute value.
|
||||
@@ -1147,18 +1147,20 @@ private:
|
||||
// Arguments for nsCSSParser::ParseProperty
|
||||
nsIURI* mDocURI;
|
||||
nsCOMPtr<nsIURI> mBaseURI;
|
||||
nsIPrincipal* mNodePrincipal;
|
||||
|
||||
// Declaration for storing parsed values (lazily initialized)
|
||||
css::Declaration* mDecl;
|
||||
|
||||
// For reporting use counters
|
||||
nsSVGElement* mElement;
|
||||
};
|
||||
|
||||
MappedAttrParser::MappedAttrParser(css::Loader* aLoader,
|
||||
nsIURI* aDocURI,
|
||||
already_AddRefed<nsIURI> aBaseURI,
|
||||
nsIPrincipal* aNodePrincipal)
|
||||
nsSVGElement* aElement)
|
||||
: mParser(aLoader), mDocURI(aDocURI), mBaseURI(aBaseURI),
|
||||
mNodePrincipal(aNodePrincipal), mDecl(nullptr)
|
||||
mDecl(nullptr), mElement(aElement)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1185,7 +1187,7 @@ MappedAttrParser::ParseMappedAttrValue(nsIAtom* aMappedAttrName,
|
||||
if (propertyID != eCSSProperty_UNKNOWN) {
|
||||
bool changed; // outparam for ParseProperty. (ignored)
|
||||
mParser.ParseProperty(propertyID, aMappedAttrValue, mDocURI, mBaseURI,
|
||||
mNodePrincipal, mDecl, &changed, false, true);
|
||||
mElement->NodePrincipal(), mDecl, &changed, false, true);
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(aMappedAttrName == nsGkAtoms::lang,
|
||||
@@ -1232,7 +1234,7 @@ nsSVGElement::UpdateContentStyleRule()
|
||||
|
||||
nsIDocument* doc = OwnerDoc();
|
||||
MappedAttrParser mappedAttrParser(doc->CSSLoader(), doc->GetDocumentURI(),
|
||||
GetBaseURI(), NodePrincipal());
|
||||
GetBaseURI(), this);
|
||||
|
||||
for (uint32_t i = 0; i < attrCount; ++i) {
|
||||
const nsAttrName* attrName = mAttrsAndChildren.AttrNameAt(i);
|
||||
@@ -1323,7 +1325,7 @@ nsSVGElement::UpdateAnimatedContentStyleRule()
|
||||
}
|
||||
|
||||
MappedAttrParser mappedAttrParser(doc->CSSLoader(), doc->GetDocumentURI(),
|
||||
GetBaseURI(), NodePrincipal());
|
||||
GetBaseURI(), this);
|
||||
doc->PropertyTable(SMIL_MAPPED_ATTR_ANIMVAL)->
|
||||
Enumerate(this, ParseMappedAttrAnimValueCallback, &mappedAttrParser);
|
||||
|
||||
|
||||
@@ -10063,6 +10063,11 @@ IonBuilder::improveThisTypesForCall()
|
||||
MFilterTypeSet *filter = MFilterTypeSet::New(alloc(), thisDef, types);
|
||||
current->add(filter);
|
||||
current->rewriteAtDepth(-2, filter);
|
||||
|
||||
// FilterTypeSetPolicy::adjustInputs will insert an infallible Unbox(Object)
|
||||
// for the input. Don't hoist this unbox above the getprop or getelem
|
||||
// operation.
|
||||
filter->setDependency(current->peek(-1)->toInstruction());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ histoenums_TARGET := export
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
histograms_file := $(srcdir)/Histograms.json
|
||||
histogram_files := $(srcdir)/Histograms.json $(topsrcdir)/dom/base/UseCounters.conf
|
||||
histogram_enum_file := TelemetryHistogramEnums.h
|
||||
histogram_data_file := TelemetryHistogramData.inc
|
||||
|
||||
@@ -36,9 +36,9 @@ data_python_deps := \
|
||||
$(srcdir)/histogram_tools.py \
|
||||
$(NULL)
|
||||
|
||||
$(histogram_enum_file): $(histograms_file) $(enum_python_deps)
|
||||
$(PYTHON) $(srcdir)/gen-histogram-enum.py $< > $@
|
||||
$(histogram_data_file): $(histograms_file) $(data_python_deps)
|
||||
$(PYTHON) $(srcdir)/gen-histogram-data.py $< > $@
|
||||
$(histogram_enum_file): $(histogram_files) $(enum_python_deps)
|
||||
$(PYTHON) $(srcdir)/gen-histogram-enum.py $(histogram_files) > $@
|
||||
$(histogram_data_file): $(histogram_files) $(data_python_deps)
|
||||
$(PYTHON) $(srcdir)/gen-histogram-data.py $(histogram_files) > $@
|
||||
|
||||
GARBAGE += $(histogram_enum_file)
|
||||
|
||||
@@ -17,10 +17,11 @@ from collections import OrderedDict
|
||||
startup_histogram_re = re.compile("SQLITE|HTTP|SPDY|CACHE|DNS")
|
||||
|
||||
def main(argv):
|
||||
filename = argv[0]
|
||||
filenames = argv
|
||||
|
||||
all_histograms = OrderedDict()
|
||||
|
||||
for histogram in histogram_tools.from_file(filename):
|
||||
for histogram in histogram_tools.from_files(filenames):
|
||||
name = histogram.name()
|
||||
parameters = OrderedDict()
|
||||
table = {
|
||||
|
||||
@@ -187,9 +187,9 @@ def write_debug_histogram_ranges(histograms):
|
||||
print "#endif"
|
||||
|
||||
def main(argv):
|
||||
filename = argv[0]
|
||||
filenames = argv
|
||||
|
||||
histograms = list(histogram_tools.from_file(filename))
|
||||
histograms = list(histogram_tools.from_files(filenames))
|
||||
|
||||
print banner
|
||||
write_histogram_table(histograms)
|
||||
|
||||
@@ -3,28 +3,63 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
# Write out a C++ enum definition whose members are the names of
|
||||
# histograms. The histograms are defined in a file provided as a
|
||||
# command-line argument.
|
||||
# histograms as well as the following other members:
|
||||
#
|
||||
# - HistogramCount
|
||||
# - HistogramFirstUseCounter
|
||||
# - HistogramLastUseCounter
|
||||
# - HistogramUseCounterCount
|
||||
#
|
||||
# The histograms are defined in files provided as command-line arguments.
|
||||
|
||||
import sys
|
||||
import histogram_tools
|
||||
import itertools
|
||||
import sys
|
||||
|
||||
banner = """/* This file is auto-generated, see gen-histogram-enum.py. */
|
||||
"""
|
||||
|
||||
def main(argv):
|
||||
filename = argv[0]
|
||||
filenames = argv
|
||||
|
||||
print banner
|
||||
print "enum ID : uint32_t {"
|
||||
for histogram in histogram_tools.from_file(filename):
|
||||
cpp_guard = histogram.cpp_guard()
|
||||
if cpp_guard:
|
||||
print "#if defined(%s)" % cpp_guard
|
||||
print " %s," % histogram.name()
|
||||
if cpp_guard:
|
||||
print "#endif"
|
||||
print " HistogramCount"
|
||||
|
||||
groups = itertools.groupby(histogram_tools.from_files(filenames),
|
||||
lambda h: h.name().startswith("USE_COUNTER_"))
|
||||
seen_use_counters = False
|
||||
|
||||
# Note that histogram_tools.py guarantees that all of the USE_COUNTER_*
|
||||
# histograms are defined in a contiguous block. We therefore assume
|
||||
# that there's at most one group for which use_counter_group is true.
|
||||
for (use_counter_group, histograms) in groups:
|
||||
if use_counter_group:
|
||||
seen_use_counters = True
|
||||
|
||||
# The HistogramDUMMY* enum variables are used to make the computation
|
||||
# of Histogram{First,Last}UseCounter easier. Otherwise, we'd have to
|
||||
# special case the first and last histogram in the group.
|
||||
if use_counter_group:
|
||||
print " HistogramFirstUseCounter,"
|
||||
print " HistogramDUMMY1 = HistogramFirstUseCounter - 1,"
|
||||
|
||||
for histogram in histograms:
|
||||
cpp_guard = histogram.cpp_guard()
|
||||
if cpp_guard:
|
||||
print "#if defined(%s)" % cpp_guard
|
||||
print " %s," % histogram.name()
|
||||
if cpp_guard:
|
||||
print "#endif"
|
||||
|
||||
if use_counter_group:
|
||||
print " HistogramDUMMY2,"
|
||||
print " HistogramLastUseCounter = HistogramDUMMY2 - 1,"
|
||||
|
||||
print " HistogramCount,"
|
||||
if seen_use_counters:
|
||||
print " HistogramUseCounterCount = HistogramLastUseCounter - HistogramFirstUseCounter + 1"
|
||||
else:
|
||||
print " HistogramUseCounterCount = 0"
|
||||
print "};"
|
||||
|
||||
main(sys.argv[1:])
|
||||
|
||||
@@ -2,9 +2,16 @@
|
||||
# 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/.
|
||||
|
||||
import buildconfig
|
||||
import json
|
||||
import math
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
# Need to update sys.path to be able to find usecounters.
|
||||
sys.path.append(os.path.join(buildconfig.topsrcdir, 'dom/base/'))
|
||||
import usecounters
|
||||
|
||||
from collections import OrderedDict
|
||||
|
||||
@@ -246,11 +253,57 @@ is enabled."""
|
||||
definition['high'],
|
||||
definition['n_buckets'])
|
||||
|
||||
def from_file(filename):
|
||||
"""Return an iterator that provides a sequence of Histograms for
|
||||
the histograms defined in filename.
|
||||
"""
|
||||
# We support generating histograms from multiple different input files, not
|
||||
# just Histograms.json. For each file's basename, we have a specific
|
||||
# routine to parse that file, and return a dictionary mapping histogram
|
||||
# names to histogram parameters.
|
||||
def from_Histograms_json(filename):
|
||||
with open(filename, 'r') as f:
|
||||
histograms = json.load(f, object_pairs_hook=OrderedDict)
|
||||
try:
|
||||
histograms = json.load(f, object_pairs_hook=OrderedDict)
|
||||
except ValueError, e:
|
||||
raise BaseException, "error parsing histograms in %s: %s" % (filename, e.message)
|
||||
return histograms
|
||||
|
||||
def from_UseCounters_conf(filename):
|
||||
return usecounters.generate_histograms(filename)
|
||||
|
||||
FILENAME_PARSERS = {
|
||||
'Histograms.json': from_Histograms_json,
|
||||
'UseCounters.conf': from_UseCounters_conf,
|
||||
}
|
||||
|
||||
def from_files(filenames):
|
||||
"""Return an iterator that provides a sequence of Histograms for
|
||||
the histograms defined in filenames.
|
||||
"""
|
||||
all_histograms = OrderedDict()
|
||||
for filename in filenames:
|
||||
parser = FILENAME_PARSERS[os.path.basename(filename)]
|
||||
histograms = parser(filename)
|
||||
|
||||
# OrderedDicts are important, because then the iteration order over
|
||||
# the parsed histograms is stable, which makes the insertion into
|
||||
# all_histograms stable, which makes ordering in generated files
|
||||
# stable, which makes builds more deterministic.
|
||||
if not isinstance(histograms, OrderedDict):
|
||||
raise BaseException, "histogram parser didn't provide an OrderedDict"
|
||||
|
||||
for (name, definition) in histograms.iteritems():
|
||||
yield Histogram(name, definition)
|
||||
if all_histograms.has_key(name):
|
||||
raise DefinitionException, "duplicate histogram name %s" % name
|
||||
all_histograms[name] = definition
|
||||
|
||||
# We require that all USE_COUNTER_* histograms be defined in a contiguous
|
||||
# block.
|
||||
use_counter_indices = filter(lambda x: x[1].startswith("USE_COUNTER_"),
|
||||
enumerate(all_histograms.iterkeys()));
|
||||
if use_counter_indices:
|
||||
lower_bound = use_counter_indices[0][0]
|
||||
upper_bound = use_counter_indices[-1][0]
|
||||
n_counters = upper_bound - lower_bound + 1
|
||||
if n_counters != len(use_counter_indices):
|
||||
raise DefinitionException, "use counter histograms must be defined in a contiguous block"
|
||||
|
||||
for (name, definition) in all_histograms.iteritems():
|
||||
yield Histogram(name, definition)
|
||||
|
||||
@@ -122,6 +122,10 @@ PluginWidgetProxy::GetNativeData(uint32_t aDataType)
|
||||
if (!mActor) {
|
||||
return nullptr;
|
||||
}
|
||||
auto tab = static_cast<mozilla::dom::TabChild*>(mActor->Manager());
|
||||
if (tab && tab->IsDestroyed()) {
|
||||
return nullptr;
|
||||
}
|
||||
switch (aDataType) {
|
||||
case NS_NATIVE_PLUGIN_PORT:
|
||||
case NS_NATIVE_WINDOW:
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<title>Testcase for bug 1128214</title>
|
||||
<style type="text/css">
|
||||
html,body {
|
||||
color:black;
|
||||
background-color:white;
|
||||
font-size:16px;
|
||||
padding:10px;
|
||||
margin:0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div style="-moz-appearance:-moz-window-button-close; background-color: #ffd800; width:20px; height:20px;"></div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,3 +1,4 @@
|
||||
load 303901-1.html
|
||||
load 303901-2.html
|
||||
load 380359-1.xhtml
|
||||
load 1128214.html
|
||||
|
||||
@@ -65,6 +65,12 @@ nsNativeThemeWin::~nsNativeThemeWin()
|
||||
static int32_t
|
||||
GetTopLevelWindowActiveState(nsIFrame *aFrame)
|
||||
{
|
||||
// Used by window frame and button box rendering. We can end up in here in
|
||||
// the content process when rendering one of these moz styles freely in a
|
||||
// page. Bail in this case, there is no applicable window focus state.
|
||||
if (XRE_GetProcessType() != GeckoProcessType_Default) {
|
||||
return mozilla::widget::themeconst::FS_INACTIVE;
|
||||
}
|
||||
// Get the widget. nsIFrame's GetNearestWidget walks up the view chain
|
||||
// until it finds a real window.
|
||||
nsIWidget* widget = aFrame->GetNearestWidget();
|
||||
|
||||
@@ -7,10 +7,6 @@
|
||||
* nsWindowGfx - Painting and aceleration.
|
||||
*/
|
||||
|
||||
// XXX Future: this should really be a stand alone class stored as
|
||||
// a member of nsWindow with getters and setters for things like render
|
||||
// mode and methods for handling paint.
|
||||
|
||||
/**************************************************************
|
||||
**************************************************************
|
||||
**
|
||||
@@ -21,10 +17,9 @@
|
||||
**************************************************************
|
||||
**************************************************************/
|
||||
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/plugins/PluginInstanceParent.h"
|
||||
using mozilla::plugins::PluginInstanceParent;
|
||||
#include "mozilla/plugins/PluginWidgetParent.h"
|
||||
using mozilla::plugins::PluginWidgetParent;
|
||||
|
||||
#include "nsWindowGfx.h"
|
||||
#include "nsAppRunner.h"
|
||||
@@ -57,13 +52,6 @@ extern "C" {
|
||||
#include "pixman.h"
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
namespace plugins {
|
||||
// For plugins with e10s
|
||||
extern const wchar_t* kPluginWidgetParentProperty;
|
||||
}
|
||||
}
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
using namespace mozilla::layers;
|
||||
@@ -214,7 +202,7 @@ bool nsWindow::OnPaint(HDC aDC, uint32_t aNestingLevel)
|
||||
|
||||
if (mWindowType == eWindowType_plugin_ipc_chrome) {
|
||||
// Fire off an async request to the plugin to paint its window
|
||||
PluginWidgetParent::SendAsyncUpdate(this);
|
||||
mozilla::dom::ContentParent::SendAsyncUpdate(this);
|
||||
ValidateRect(mWnd, nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||