mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-11-12 14:20:14 +02:00
When the PluginRemoved event is fired when changing locations, it's fired asynchronously such that the document that the plugin belongs to has already been unloaded. This was causing the hidden plugin notification to appear in some cases when users browsed away from documents that had hidden plugins in them. Now we pass the Principal for the unloading document back to the parent and do a comparison with the current browser Principal to ensure that they match before showing the hidden plugin notification. --HG-- rename : browser/base/content/test/plugins/plugin_small.html => browser/base/content/test/plugins/plugin_small_2.html extra : rebase_source : e748e3b09de77cc7796b1a78f8e39a23af64049a
198 lines
5.9 KiB
JavaScript
198 lines
5.9 KiB
JavaScript
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
|
|
|
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
|
|
"resource://gre/modules/Promise.jsm");
|
|
XPCOMUtils.defineLazyModuleGetter(this, "Task",
|
|
"resource://gre/modules/Task.jsm");
|
|
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
|
|
"resource://gre/modules/PlacesUtils.jsm");
|
|
|
|
function whenDelayedStartupFinished(aWindow, aCallback) {
|
|
Services.obs.addObserver(function observer(aSubject, aTopic) {
|
|
if (aWindow == aSubject) {
|
|
Services.obs.removeObserver(observer, aTopic);
|
|
executeSoon(aCallback);
|
|
}
|
|
}, "browser-delayed-startup-finished", false);
|
|
}
|
|
|
|
function findChromeWindowByURI(aURI) {
|
|
let windows = Services.wm.getEnumerator(null);
|
|
while (windows.hasMoreElements()) {
|
|
let win = windows.getNext();
|
|
if (win.location.href == aURI)
|
|
return win;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function waitForCondition(condition, nextTest, errorMsg) {
|
|
var tries = 0;
|
|
var interval = setInterval(function() {
|
|
if (tries >= 30) {
|
|
ok(false, errorMsg);
|
|
moveOn();
|
|
}
|
|
var conditionPassed;
|
|
try {
|
|
conditionPassed = condition();
|
|
} catch (e) {
|
|
ok(false, e + "\n" + e.stack);
|
|
conditionPassed = false;
|
|
}
|
|
if (conditionPassed) {
|
|
moveOn();
|
|
}
|
|
tries++;
|
|
}, 100);
|
|
var moveOn = function() { clearInterval(interval); nextTest(); };
|
|
}
|
|
|
|
function getTestPlugin(aName) {
|
|
var pluginName = aName || "Test Plug-in";
|
|
var ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
|
|
var tags = ph.getPluginTags();
|
|
|
|
// Find the test plugin
|
|
for (var i = 0; i < tags.length; i++) {
|
|
if (tags[i].name == pluginName)
|
|
return tags[i];
|
|
}
|
|
ok(false, "Unable to find plugin");
|
|
return null;
|
|
}
|
|
|
|
// call this to set the test plugin(s) initially expected enabled state.
|
|
// it will automatically be reset to it's previous value after the test
|
|
// ends
|
|
function setTestPluginEnabledState(newEnabledState, pluginName) {
|
|
var plugin = getTestPlugin(pluginName);
|
|
var oldEnabledState = plugin.enabledState;
|
|
plugin.enabledState = newEnabledState;
|
|
SimpleTest.registerCleanupFunction(function() {
|
|
getTestPlugin(pluginName).enabledState = oldEnabledState;
|
|
});
|
|
}
|
|
|
|
// after a test is done using the plugin doorhanger, we should just clear
|
|
// any permissions that may have crept in
|
|
function clearAllPluginPermissions() {
|
|
let perms = Services.perms.enumerator;
|
|
while (perms.hasMoreElements()) {
|
|
let perm = perms.getNext();
|
|
if (perm.type.startsWith('plugin')) {
|
|
Services.perms.remove(perm.host, perm.type);
|
|
}
|
|
}
|
|
}
|
|
|
|
function updateBlocklist(aCallback) {
|
|
var blocklistNotifier = Cc["@mozilla.org/extensions/blocklist;1"]
|
|
.getService(Ci.nsITimerCallback);
|
|
var observer = function() {
|
|
Services.obs.removeObserver(observer, "blocklist-updated");
|
|
SimpleTest.executeSoon(aCallback);
|
|
};
|
|
Services.obs.addObserver(observer, "blocklist-updated", false);
|
|
blocklistNotifier.notify(null);
|
|
}
|
|
|
|
var _originalTestBlocklistURL = null;
|
|
function setAndUpdateBlocklist(aURL, aCallback) {
|
|
if (!_originalTestBlocklistURL)
|
|
_originalTestBlocklistURL = Services.prefs.getCharPref("extensions.blocklist.url");
|
|
Services.prefs.setCharPref("extensions.blocklist.url", aURL);
|
|
updateBlocklist(aCallback);
|
|
}
|
|
|
|
function resetBlocklist() {
|
|
Services.prefs.setCharPref("extensions.blocklist.url", _originalTestBlocklistURL);
|
|
}
|
|
|
|
function waitForNotificationPopup(notificationID, browser, callback) {
|
|
let notification;
|
|
waitForCondition(
|
|
() => (notification = PopupNotifications.getNotification(notificationID, browser)),
|
|
() => {
|
|
ok(notification, `Successfully got the ${notificationID} notification popup`);
|
|
callback(notification);
|
|
},
|
|
`Waited too long for the ${notificationID} notification popup`
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Returns a Promise that resolves when a notification bar
|
|
* for a browser is shown. Alternatively, for old-style callers,
|
|
* can automatically call a callback before it resolves.
|
|
*
|
|
* @param notificationID
|
|
* The ID of the notification to look for.
|
|
* @param browser
|
|
* The browser to check for the notification bar.
|
|
* @param callback (optional)
|
|
* A function to be called just before the Promise resolves.
|
|
*
|
|
* @return Promise
|
|
*/
|
|
function waitForNotificationBar(notificationID, browser, callback) {
|
|
return new Promise((resolve, reject) => {
|
|
let notification;
|
|
let notificationBox = gBrowser.getNotificationBox(browser);
|
|
waitForCondition(
|
|
() => (notification = notificationBox.getNotificationWithValue(notificationID)),
|
|
() => {
|
|
ok(notification, `Successfully got the ${notificationID} notification bar`);
|
|
if (callback) {
|
|
callback(notification);
|
|
}
|
|
resolve(notification);
|
|
},
|
|
`Waited too long for the ${notificationID} notification bar`
|
|
);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Due to layout being async, "PluginBindAttached" may trigger later.
|
|
* This returns a Promise that resolves once we've forced a layout
|
|
* flush, which triggers the PluginBindAttached event to fire.
|
|
*
|
|
* @param browser
|
|
* The browser to force plugin bindings in.
|
|
*
|
|
* @return Promise
|
|
*/
|
|
function forcePluginBindingAttached(browser) {
|
|
return new Promise((resolve, reject) => {
|
|
let doc = browser.contentDocument;
|
|
let elems = doc.getElementsByTagName('embed');
|
|
if (elems.length < 1) {
|
|
elems = doc.getElementsByTagName('object');
|
|
}
|
|
elems[0].clientTop;
|
|
executeSoon(resolve);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Loads a page in a browser, and returns a Promise that
|
|
* resolves once the "load" event has been fired for that
|
|
* browser.
|
|
*
|
|
* @param browser
|
|
* The browser to load the page in.
|
|
* @param uri
|
|
* The URI to load.
|
|
*
|
|
* @return Promise
|
|
*/
|
|
function loadPage(browser, uri) {
|
|
return new Promise((resolve, reject) => {
|
|
browser.addEventListener("load", function onLoad(event) {
|
|
browser.removeEventListener("load", onLoad, true);
|
|
resolve();
|
|
}, true);
|
|
browser.loadURI(uri);
|
|
});
|
|
}
|