Skip to content
This repository has been archived by the owner on Aug 4, 2022. It is now read-only.

Commit

Permalink
Merge mozilla-central to mozilla-inbound. CLOSED TREE
Browse files Browse the repository at this point in the history
  • Loading branch information
ncsoregi committed Dec 11, 2018
2 parents 66e0e47 + 29b1eba commit 817b0d4
Show file tree
Hide file tree
Showing 19 changed files with 395 additions and 63 deletions.
3 changes: 2 additions & 1 deletion devtools/client/definitions.js
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,8 @@ Tools.accessibility = {
label: l10n("accessibility.label"),
panelLabel: l10n("accessibility.panelLabel"),
get tooltip() {
return l10n("accessibility.tooltip2");
return l10n("accessibility.tooltip3",
"Shift+" + functionkey(l10n("accessibility.commandkey")));
},
inMenu: true,

Expand Down
4 changes: 2 additions & 2 deletions devtools/client/locales/en-US/startup.properties
Original file line number Diff line number Diff line change
Expand Up @@ -262,11 +262,11 @@ accessibility.panelLabel=Accessibility Panel
# Used for the menuitem in the tool menu
accessibility.accesskey=y

# LOCALIZATION NOTE (accessibility.tooltip2):
# LOCALIZATION NOTE (accessibility.tooltip3):
# This string is displayed in the tooltip of the tab when the Accessibility is
# displayed inside the developer tools window.
# Keyboard shortcut for Accessibility panel will be shown inside the brackets.
accessibility.tooltip2=Accessibility
accessibility.tooltip3=Accessibility (%S)

# LOCALIZATION NOTE (application.label):
# This string is displayed in the title of the tab when the Application panel
Expand Down
2 changes: 1 addition & 1 deletion devtools/server/actors/root.js
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ RootActor.prototype = {

let targetActor;
try {
targetActor = await tabList.getTab(options);
targetActor = await tabList.getTab(options, { forceUnzombify: true });
} catch (error) {
if (error.error) {
// Pipe expected errors as-is to the client
Expand Down
62 changes: 51 additions & 11 deletions devtools/server/actors/targets/frame-proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ FrameTargetActorProxy.prototype = {
}
this.exit();
};

await this._unzombifyIfNeeded();

const connect = DebuggerServer.connectToFrame(this._conn, this._browser, onDestroy);
const form = await connect;

Expand Down Expand Up @@ -101,6 +104,11 @@ FrameTargetActorProxy.prototype = {
return this.connect();
}

// This function may be called if we are inspecting tabs and the actor proxy
// has already been generated. In that case we need to unzombify tabs.
// If we are not inspecting tabs then this will be a no-op.
await this._unzombifyIfNeeded();

const form = await new Promise(resolve => {
const onFormUpdate = msg => {
// There may be more than one FrameTargetActor up and running
Expand All @@ -124,11 +132,23 @@ FrameTargetActorProxy.prototype = {
return this;
},

_isZombieTab() {
// Check for Firefox on Android.
if (this._browser.hasAttribute("pending")) {
return true;
}

// Check for other.
const tabbrowser = this._tabbrowser;
const tab = tabbrowser ? tabbrowser.getTabForBrowser(this._browser) : null;
return tab && tab.hasAttribute && tab.hasAttribute("pending");
},

/**
* If we don't have a title from the content side because it's a zombie tab, try to find
* it on the chrome side.
*/
get title() {
_getZombieTabTitle() {
// On Fennec, we can check the session store data for zombie tabs
if (this._browser && this._browser.__SS_restore) {
const sessionStore = this._browser.__SS_data;
Expand All @@ -145,34 +165,54 @@ FrameTargetActorProxy.prototype = {
return tab.label;
}
}
return "";

return null;
},

/**
* If we don't have a url from the content side because it's a zombie tab, try to find
* it on the chrome side.
*/
get url() {
_getZombieTabUrl() {
// On Fennec, we can check the session store data for zombie tabs
if (this._browser && this._browser.__SS_restore) {
const sessionStore = this._browser.__SS_data;
// Get the last selected entry
const entry = sessionStore.entries[sessionStore.index - 1];
return entry.url;
}

return null;
},

async _unzombifyIfNeeded() {
if (!this.options.forceUnzombify || !this._isZombieTab()) {
return;
}

// Unzombify if the browser is a zombie tab on Android.
const browserApp = this._browser ? this._browser.ownerGlobal.BrowserApp : null;
if (browserApp) {
// Wait until the content is loaded so as to ensure that the inspector actor refers
// to same document.
const waitForUnzombify = new Promise(resolve => {
this._browser.addEventListener("DOMContentLoaded", resolve,
{ capture: true, once: true });
});

const tab = browserApp.getTabForBrowser(this._browser);
tab.unzombify();

await waitForUnzombify;
}
},

form() {
const form = Object.assign({}, this._form);
// In some cases, the title and url fields might be empty. Zombie tabs (not yet
// restored) are a good example. In such cases, try to look up values for these
// fields using other data in the parent process.
if (!form.title) {
form.title = this.title;
}
if (!form.url) {
form.url = this.url;
// In case of Zombie tabs (not yet restored), look up title and url from other.
if (this._isZombieTab()) {
form.title = this._getZombieTabTitle() || form.title;
form.url = this._getZombieTabUrl() || form.url;
}

return form;
Expand Down
79 changes: 61 additions & 18 deletions devtools/server/actors/webbrowser.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ loader.lazyRequireGetter(this, "WorkerTargetActorList", "devtools/server/actors/
loader.lazyRequireGetter(this, "ServiceWorkerRegistrationActorList", "devtools/server/actors/worker/worker-list", true);
loader.lazyRequireGetter(this, "ProcessActorList", "devtools/server/actors/process", true);
loader.lazyImporter(this, "AddonManager", "resource://gre/modules/AddonManager.jsm");
loader.lazyImporter(this, "AppConstants", "resource://gre/modules/AppConstants.jsm");

/**
* Browser-specific actors.
Expand Down Expand Up @@ -143,11 +144,11 @@ exports.createRootActor = function createRootActor(connection) {
* - Title changes:
*
* For tabs living in the child process, we listen for DOMTitleChange message
* via the top-level window's message manager. Doing this also allows listening
* for title changes on Fennec.
* via the top-level window's message manager.
* But as these messages aren't sent for tabs loaded in the parent process,
* we also listen for TabAttrModified event, which is fired only on Firefox
* desktop.
* Also, we listen DOMTitleChange event on Android document.
*/
function BrowserTabList(connection) {
this._connection = connection;
Expand Down Expand Up @@ -191,6 +192,8 @@ function BrowserTabList(connection) {

/* True if we're testing, and should throw if consistency checks fail. */
this._testing = false;

this._onAndroidDocumentEvent = this._onAndroidDocumentEvent.bind(this);
}

BrowserTabList.prototype.constructor = BrowserTabList;
Expand Down Expand Up @@ -310,7 +313,8 @@ BrowserTabList.prototype._getActorForBrowser = function(browser, browserActorOpt
return actor.connect();
};

BrowserTabList.prototype.getTab = function({ outerWindowID, tabId }) {
BrowserTabList.prototype.getTab = function({ outerWindowID, tabId },
browserActorOptions) {
if (typeof outerWindowID == "number") {
// First look for in-process frames with this ID
const window = Services.wm.getOuterWindowWithId(outerWindowID);
Expand All @@ -324,14 +328,14 @@ BrowserTabList.prototype.getTab = function({ outerWindowID, tabId }) {
if (window) {
const iframe = window.windowUtils.containerElement;
if (iframe) {
return this._getActorForBrowser(iframe);
return this._getActorForBrowser(iframe, browserActorOptions);
}
}
// Then also look on registered <xul:browsers> when using outerWindowID for
// OOP tabs
for (const browser of this._getBrowsers()) {
if (browser.outerWindowID == outerWindowID) {
return this._getActorForBrowser(browser);
return this._getActorForBrowser(browser, browserActorOptions);
}
}
return Promise.reject({
Expand All @@ -344,7 +348,7 @@ BrowserTabList.prototype.getTab = function({ outerWindowID, tabId }) {
if (browser.frameLoader &&
browser.frameLoader.tabParent &&
browser.frameLoader.tabParent.tabId === tabId) {
return this._getActorForBrowser(browser);
return this._getActorForBrowser(browser, browserActorOptions);
}
}
return Promise.reject({
Expand All @@ -357,7 +361,7 @@ BrowserTabList.prototype.getTab = function({ outerWindowID, tabId }) {
DebuggerServer.chromeWindowType);
if (topXULWindow) {
const selectedBrowser = this._getSelectedBrowser(topXULWindow);
return this._getActorForBrowser(selectedBrowser);
return this._getActorForBrowser(selectedBrowser, browserActorOptions);
}
return Promise.reject({
error: "noTab",
Expand Down Expand Up @@ -453,11 +457,28 @@ BrowserTabList.prototype._checkListening = function() {

/*
* We also listen for title changed from the child process.
* This allows listening for title changes from Fennec and OOP tabs in Fx.
* This allows listening for title changes from OOP tabs.
* OOP tabs are running browser-child.js frame script which sends DOMTitleChanged
* events through the message manager.
*/
this._listenForMessagesIf(this._onListChanged && this._mustNotify,
"_listeningForTitleChange",
["DOMTitleChanged"]);

/*
* We also listen for title changed event on Android document.
* Android document events are used for single process Gecko View and Firefox for
* Android. They do no execute browser-child.js because of single process, instead
* DOMTitleChanged events are emitted on the top level document.
* Also, Multi process Gecko View is not covered by here since that receives title
* updates via DOMTitleChanged messages.
*/
if (AppConstants.platform === "android") {
this._listenForEventsIf(this._onListChanged && this._mustNotify,
"_listeningForAndroidDocument",
["DOMTitleChanged"],
this._onAndroidDocumentEvent);
}
};

/*
Expand All @@ -472,12 +493,12 @@ BrowserTabList.prototype._checkListening = function() {
* An array of event names.
*/
BrowserTabList.prototype._listenForEventsIf =
function(shouldListen, guard, eventNames) {
function(shouldListen, guard, eventNames, listener = this) {
if (!shouldListen !== !this[guard]) {
const op = shouldListen ? "addEventListener" : "removeEventListener";
for (const win of Services.wm.getEnumerator(DebuggerServer.chromeWindowType)) {
for (const name of eventNames) {
win[op](name, this, false);
win[op](name, listener, false);
}
}
this[guard] = shouldListen;
Expand All @@ -487,12 +508,12 @@ BrowserTabList.prototype._listenForEventsIf =
/*
* Add or remove message listeners for all XUL windows.
*
* @param aShouldListen boolean
* @param shouldListen boolean
* True if we should add message listeners; false if we should remove them.
* @param aGuard string
* @param guard string
* The name of a guard property of 'this', indicating whether we're
* already listening for those messages.
* @param aMessageNames array of strings
* @param messageNames array of strings
* An array of message names.
*/
BrowserTabList.prototype._listenForMessagesIf =
Expand All @@ -508,6 +529,20 @@ BrowserTabList.prototype._listenForMessagesIf =
}
};

/*
* This function assumes to be used as a event listener for Android document.
*/
BrowserTabList.prototype._onAndroidDocumentEvent = function(event) {
switch (event.type) {
case "DOMTitleChanged": {
const win = event.currentTarget.ownerGlobal;
const browser = win.BrowserApp.getBrowserForDocument(event.target);
this._onDOMTitleChanged(browser);
break;
}
}
};

/**
* Implement nsIMessageListener.
*/
Expand All @@ -516,16 +551,24 @@ BrowserTabList.prototype.receiveMessage = DevToolsUtils.makeInfallible(
const browser = message.target;
switch (message.name) {
case "DOMTitleChanged": {
const actor = this._actorByBrowser.get(browser);
if (actor) {
this._notifyListChanged();
this._checkListening();
}
this._onDOMTitleChanged(browser);
break;
}
}
});

/**
* Handle "DOMTitleChanged" event.
*/
BrowserTabList.prototype._onDOMTitleChanged = DevToolsUtils.makeInfallible(
function(browser) {
const actor = this._actorByBrowser.get(browser);
if (actor) {
this._notifyListChanged();
this._checkListening();
}
});

/**
* Implement nsIDOMEventListener.
*/
Expand Down
6 changes: 6 additions & 0 deletions devtools/startup/devtools-startup.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,12 @@ XPCOMUtils.defineLazyGetter(this, "KeyShortcuts", function() {
shortcut: KeyShortcutsBundle.GetStringFromName("dom.commandkey"),
modifiers,
},
// Key for opening the Accessibility Panel
{
toolId: "accessibility",
shortcut: KeyShortcutsBundle.GetStringFromName("accessibility.commandkey"),
modifiers: "shift",
},
];

if (isMac) {
Expand Down
4 changes: 4 additions & 0 deletions devtools/startup/locales/en-US/key-shortcuts.properties
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,7 @@ storage.commandkey=VK_F9
# LOCALIZATION NOTE (dom.commandkey):
# Key pressed to open a toolbox with the DOM panel selected
dom.commandkey=W

# LOCALIZATION NOTE (accessibility.commandkey):
# Key pressed to open a toolbox with the accessibility panel selected
accessibility.commandkey=VK_F10
7 changes: 6 additions & 1 deletion layout/painting/nsDisplayList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4509,7 +4509,12 @@ void nsDisplayBackgroundColor::ApplyOpacity(nsDisplayListBuilder* aBuilder,
IntersectClip(aBuilder, aClip, false);
}

bool nsDisplayBackgroundColor::CanApplyOpacity() const { return true; }
bool nsDisplayBackgroundColor::CanApplyOpacity() const {
// Don't apply opacity if the background color is animated since the color is
// going to be changed on the compositor.
return !EffectCompositor::HasAnimationsForCompositor(
mFrame, eCSSProperty_background_color);
}

LayerState nsDisplayBackgroundColor::GetLayerState(
nsDisplayListBuilder* aBuilder, LayerManager* aManager,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<style>
#target {
background-color: green;
width: 100px;
height: 100px;
opacity: 0.5;
}
</style>
<div id="target"></div>
</html>
Loading

0 comments on commit 817b0d4

Please sign in to comment.