зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to graphics
MozReview-Commit-ID: 6ocpYm7MBCV
This commit is contained in:
Коммит
108f572510
|
@ -25,7 +25,6 @@ EventTree* const TreeMutation::kNoEventTree = reinterpret_cast<EventTree*>(-1);
|
|||
TreeMutation::TreeMutation(Accessible* aParent, bool aNoEvents) :
|
||||
mParent(aParent), mStartIdx(UINT32_MAX),
|
||||
mStateFlagsCopy(mParent->mStateFlags),
|
||||
mEventTree(aNoEvents ? kNoEventTree : nullptr),
|
||||
mQueueEvents(!aNoEvents)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
|
@ -33,7 +32,7 @@ TreeMutation::TreeMutation(Accessible* aParent, bool aNoEvents) :
|
|||
#endif
|
||||
|
||||
#ifdef A11Y_LOG
|
||||
if (mEventTree != kNoEventTree && logging::IsEnabled(logging::eEventTree)) {
|
||||
if (mQueueEvents && logging::IsEnabled(logging::eEventTree)) {
|
||||
logging::MsgBegin("EVENTS_TREE", "reordering tree before");
|
||||
logging::AccessibleInfo("reordering for", mParent);
|
||||
Controller()->RootEventTree().Log();
|
||||
|
@ -119,7 +118,7 @@ TreeMutation::Done()
|
|||
#endif
|
||||
|
||||
#ifdef A11Y_LOG
|
||||
if (mEventTree != kNoEventTree && logging::IsEnabled(logging::eEventTree)) {
|
||||
if (mQueueEvents && logging::IsEnabled(logging::eEventTree)) {
|
||||
logging::MsgBegin("EVENTS_TREE", "reordering tree after");
|
||||
logging::AccessibleInfo("reordering for", mParent);
|
||||
Controller()->RootEventTree().Log();
|
||||
|
|
|
@ -47,7 +47,6 @@ private:
|
|||
Accessible* mParent;
|
||||
uint32_t mStartIdx;
|
||||
uint32_t mStateFlagsCopy;
|
||||
EventTree* mEventTree;
|
||||
|
||||
/*
|
||||
* True if mutation events should be queued.
|
||||
|
|
|
@ -842,6 +842,10 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
|
|||
size_t newDocCount = newChildDocs.Length();
|
||||
for (size_t i = 0; i < newDocCount; i++) {
|
||||
DocAccessible* childDoc = newChildDocs[i];
|
||||
if (childDoc->IsDefunct()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Accessible* parent = childDoc->Parent();
|
||||
DocAccessibleChild* parentIPCDoc = mDocument->IPCDoc();
|
||||
uint64_t id = reinterpret_cast<uintptr_t>(parent->UniqueID());
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
#include "nsIObserverService.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsPluginFrame.h"
|
||||
#include "nsSVGPathGeometryFrame.h"
|
||||
#include "SVGGeometryFrame.h"
|
||||
#include "nsTreeBodyFrame.h"
|
||||
#include "nsTreeColumns.h"
|
||||
#include "nsTreeUtils.h"
|
||||
|
@ -1173,8 +1173,8 @@ nsAccessibilityService::CreateAccessible(nsINode* aNode,
|
|||
|
||||
if (!newAcc) {
|
||||
if (content->IsSVGElement()) {
|
||||
nsSVGPathGeometryFrame* pathGeometryFrame = do_QueryFrame(frame);
|
||||
if (pathGeometryFrame) {
|
||||
SVGGeometryFrame* geometryFrame = do_QueryFrame(frame);
|
||||
if (geometryFrame) {
|
||||
// A graphic elements: rect, circle, ellipse, line, path, polygon,
|
||||
// polyline and image. A 'use' and 'text' graphic elements require
|
||||
// special support.
|
||||
|
|
|
@ -451,16 +451,6 @@ pref("full-screen-api.ignore-widgets", true);
|
|||
|
||||
pref("media.volume.steps", 10);
|
||||
|
||||
#ifdef ENABLE_MARIONETTE
|
||||
//Enable/disable marionette server, set listening port
|
||||
pref("marionette.defaultPrefs.enabled", true);
|
||||
pref("marionette.defaultPrefs.port", 2828);
|
||||
#ifndef MOZ_WIDGET_GONK
|
||||
// On desktop builds, we need to force the socket to listen on localhost only
|
||||
pref("marionette.force-local", true);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_UPDATER
|
||||
// When we're applying updates, we can't let anything hang us on
|
||||
// quit+restart. The user has no recourse.
|
||||
|
@ -817,8 +807,7 @@ pref("network.sntp.pools", // Servers separated by ';'.
|
|||
pref("network.sntp.port", 123);
|
||||
pref("network.sntp.timeout", 30); // In seconds.
|
||||
|
||||
// Allow ADB to run for this many hours before disabling
|
||||
// (only applies when marionette is disabled)
|
||||
// Allow ADB to run for this many hours before disabling.
|
||||
// 0 disables the timer.
|
||||
pref("b2g.adb.timeout-hours", 12);
|
||||
|
||||
|
|
|
@ -166,19 +166,6 @@ var AdbController = {
|
|||
(!(this.lockEnabled && this.locked) || usbFuncActive);
|
||||
|
||||
let useDisableAdbTimer = true;
|
||||
try {
|
||||
if (Services.prefs.getBoolPref("marionette.defaultPrefs.enabled")) {
|
||||
// Marionette is enabled. Marionette requires that adb be on (and also
|
||||
// requires that remote debugging be off). The fact that marionette
|
||||
// is enabled also implies that we're doing a non-production build, so
|
||||
// we want adb enabled all of the time.
|
||||
enableAdb = true;
|
||||
useDisableAdbTimer = false;
|
||||
}
|
||||
} catch (e) {
|
||||
// This means that the pref doesn't exist. Which is fine. We just leave
|
||||
// enableAdb alone.
|
||||
}
|
||||
|
||||
// Check wakelock to prevent adb from disconnecting when phone is locked
|
||||
let lockFile = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
|
||||
|
|
|
@ -12,7 +12,6 @@ export GONK_PRODUCT=generic
|
|||
ac_add_options --with-gonk-toolchain-prefix="$topsrcdir/gonk-toolchain/prebuilt/$TOOLCHAIN_HOST/toolchain/arm-linux-androideabi-4.4.x/bin/arm-linux-androideabi-"
|
||||
ac_add_options --enable-debug-symbols
|
||||
ac_add_options --enable-debug
|
||||
ENABLE_MARIONETTE=1
|
||||
|
||||
# Enable dump() from JS.
|
||||
export CXXFLAGS="-DMOZ_ENABLE_JS_DUMP -include $topsrcdir/gonk-toolchain/gonk-misc/Unicode.h -include $topsrcdir/gonk-toolchain/system/vold/ResponseCode.h"
|
||||
|
|
|
@ -13,7 +13,6 @@ export GONK_PRODUCT=generic
|
|||
ac_add_options --with-gonk-toolchain-prefix="$topsrcdir/gonk-toolchain/prebuilt/$TOOLCHAIN_HOST/toolchain/arm-linux-androideabi-4.4.x/bin/arm-linux-androideabi-"
|
||||
ac_add_options --enable-debug-symbols
|
||||
# ac_add_options --enable-profiling
|
||||
ENABLE_MARIONETTE=1
|
||||
|
||||
# Enable dump() from JS.
|
||||
export CXXFLAGS="-DMOZ_ENABLE_JS_DUMP -include $topsrcdir/gonk-toolchain/gonk-misc/Unicode.h -include $topsrcdir/gonk-toolchain/system/vold/ResponseCode.h"
|
||||
|
|
|
@ -23,7 +23,6 @@ no_sccache=
|
|||
|
||||
#B2G options
|
||||
ac_add_options --enable-application=b2g
|
||||
ENABLE_MARIONETTE=1
|
||||
export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
|
||||
|
||||
GAIADIR=$topsrcdir/gaia
|
||||
|
|
|
@ -21,7 +21,6 @@ export MOZ_TELEMETRY_REPORTING=1
|
|||
ac_add_options --enable-application=b2g
|
||||
ac_add_options --enable-debug-symbols
|
||||
ac_add_options --enable-debug
|
||||
ENABLE_MARIONETTE=1
|
||||
|
||||
export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@ export MOZ_TELEMETRY_REPORTING=1
|
|||
|
||||
# B2G Options
|
||||
ac_add_options --enable-application=b2g
|
||||
ENABLE_MARIONETTE=1
|
||||
|
||||
export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@ no_sccache=
|
|||
. "$topsrcdir/build/mozconfig.cache"
|
||||
|
||||
# graphene options
|
||||
ENABLE_MARIONETTE=1
|
||||
export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
|
||||
|
||||
. "$topsrcdir/b2g/graphene/config/horizon-mozconfigs/common.override"
|
||||
|
|
|
@ -19,7 +19,6 @@ no_sccache=
|
|||
. "$topsrcdir/build/mozconfig.cache"
|
||||
|
||||
# graphene options
|
||||
ENABLE_MARIONETTE=1
|
||||
export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
|
||||
|
||||
. "$topsrcdir/b2g/graphene/config/horizon-mozconfigs/common.override"
|
||||
|
|
|
@ -16,7 +16,6 @@ export MOZILLA_OFFICIAL=1
|
|||
# graphene Stuff
|
||||
ac_add_options --enable-debug-symbols
|
||||
ac_add_options --enable-debug
|
||||
ENABLE_MARIONETTE=1
|
||||
|
||||
export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
|
||||
|
||||
|
|
|
@ -12,8 +12,6 @@ export MOZILLA_OFFICIAL=1
|
|||
. $topsrcdir/build/win32/mozconfig.vs-latest
|
||||
|
||||
# graphene Options
|
||||
ENABLE_MARIONETTE=1
|
||||
|
||||
export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
|
||||
|
||||
. "$topsrcdir/b2g/graphene/config/mozconfigs/common.override"
|
||||
|
|
|
@ -19,7 +19,6 @@ no_sccache=
|
|||
. "$topsrcdir/build/mozconfig.cache"
|
||||
|
||||
# graphene options
|
||||
ENABLE_MARIONETTE=1
|
||||
export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
|
||||
|
||||
. "$topsrcdir/b2g/graphene/config/mozconfigs/common.override"
|
||||
|
|
|
@ -19,7 +19,6 @@ no_sccache=
|
|||
. "$topsrcdir/build/mozconfig.cache"
|
||||
|
||||
# graphene options
|
||||
ENABLE_MARIONETTE=1
|
||||
export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
|
||||
|
||||
. "$topsrcdir/b2g/graphene/config/mozconfigs/common.override"
|
||||
|
|
|
@ -16,7 +16,6 @@ export MOZILLA_OFFICIAL=1
|
|||
# graphene Stuff
|
||||
ac_add_options --enable-debug-symbols
|
||||
ac_add_options --enable-debug
|
||||
ENABLE_MARIONETTE=1
|
||||
|
||||
export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
|
||||
|
||||
|
|
|
@ -12,8 +12,6 @@ export MOZILLA_OFFICIAL=1
|
|||
. $topsrcdir/build/win32/mozconfig.vs-latest
|
||||
|
||||
# graphene Options
|
||||
ENABLE_MARIONETTE=1
|
||||
|
||||
export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
|
||||
|
||||
. "$topsrcdir/b2g/grapheneconfig/mozconfigs/common.override"
|
||||
|
|
|
@ -47,10 +47,6 @@ pref("b2g.nativeWindowGeometry.fullscreen", false);
|
|||
|
||||
pref("media.useAudioChannelService", false);
|
||||
|
||||
#ifdef ENABLE_MARIONETTE
|
||||
pref("b2g.is_mulet", true);
|
||||
#endif
|
||||
|
||||
// Most DevTools prefs are set from the shared file
|
||||
// devtools/client/preferences/devtools.js, but this one is currently set
|
||||
// per-app or per-channel.
|
||||
|
|
|
@ -41,10 +41,6 @@ ifdef MOZ_DEBUG
|
|||
DEFINES += -DMOZ_DEBUG=1
|
||||
endif
|
||||
|
||||
ifdef ENABLE_MARIONETTE
|
||||
DEFINES += -DENABLE_MARIONETTE=1
|
||||
endif
|
||||
|
||||
MOZ_PACKAGER_MINIFY=1
|
||||
|
||||
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
|
||||
|
|
|
@ -768,12 +768,6 @@ bin/libfreebl_32int64_3.so
|
|||
@RESPATH@/chrome/chrome.manifest
|
||||
@RESPATH@/components/B2GComponents.manifest
|
||||
@BINPATH@/@DLL_PREFIX@omxplugin@DLL_SUFFIX@
|
||||
#if defined(ENABLE_MARIONETTE) || !defined(MOZ_WIDGET_GONK)
|
||||
@RESPATH@/chrome/marionette@JAREXT@
|
||||
@RESPATH@/chrome/marionette.manifest
|
||||
@RESPATH@/components/marionette.manifest
|
||||
@RESPATH@/components/marionette.js
|
||||
#endif
|
||||
@RESPATH@/components/AlertsService.js
|
||||
@RESPATH@/components/ContentPermissionPrompt.js
|
||||
@RESPATH@/components/DirectoryProvider.js
|
||||
|
|
|
@ -89,8 +89,7 @@ SSE2Check()
|
|||
}
|
||||
#endif
|
||||
|
||||
#if !defined(MOZ_WIDGET_COCOA) && !defined(MOZ_WIDGET_ANDROID) \
|
||||
&& !(defined(XP_LINUX) && defined(MOZ_SANDBOX))
|
||||
#if !defined(MOZ_WIDGET_COCOA) && !defined(MOZ_WIDGET_ANDROID)
|
||||
#define MOZ_BROWSER_CAN_BE_CONTENTPROC
|
||||
#include "../../ipc/contentproc/plugin-container.cpp"
|
||||
#endif
|
||||
|
|
|
@ -754,9 +754,6 @@ pref("gecko.handlerService.schemes.ircs.2.uriTemplate", "chrome://browser-region
|
|||
pref("gecko.handlerService.schemes.ircs.3.name", "chrome://browser-region/locale/region.properties");
|
||||
pref("gecko.handlerService.schemes.ircs.3.uriTemplate", "chrome://browser-region/locale/region.properties");
|
||||
|
||||
// By default, we don't want protocol/content handlers to be registered from a different host, see bug 402287
|
||||
pref("gecko.handlerService.allowRegisterFromDifferentHost", false);
|
||||
|
||||
pref("browser.geolocation.warning.infoURL", "https://www.mozilla.org/%LOCALE%/firefox/geolocation/");
|
||||
|
||||
pref("browser.EULA.version", 3);
|
||||
|
@ -1555,3 +1552,6 @@ pref("browser.crashReports.unsubmittedCheck.autoSubmit", false);
|
|||
// controlling validation are located in /services/sync/services-sync.js
|
||||
pref("services.sync.validation.enabled", true);
|
||||
#endif
|
||||
|
||||
// Preferences for the form autofill system extension
|
||||
pref("browser.formautofill.enabled", false);
|
||||
|
|
|
@ -559,6 +559,8 @@ toolbar:not(#TabsToolbar) > #personal-bookmarks {
|
|||
visibility: collapse;
|
||||
}
|
||||
|
||||
#urlbar[pageproxystate="invalid"] > #identity-box > #blocked-permissions-container,
|
||||
#urlbar[pageproxystate="invalid"] > #identity-box > #notification-popup-box,
|
||||
#urlbar[pageproxystate="invalid"] > #identity-box > #identity-icon-labels {
|
||||
visibility: collapse;
|
||||
}
|
||||
|
@ -567,10 +569,6 @@ toolbar:not(#TabsToolbar) > #personal-bookmarks {
|
|||
pointer-events: none;
|
||||
}
|
||||
|
||||
#urlbar[pageproxystate="invalid"] > #identity-box > #notification-popup-box {
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
#identity-icon-labels {
|
||||
max-width: 18em;
|
||||
}
|
||||
|
|
|
@ -2368,7 +2368,22 @@ function BrowserPageInfo(documentURL, initialTab, imageElement, frameOuterWindow
|
|||
"chrome,toolbar,dialog=no,resizable", args);
|
||||
}
|
||||
|
||||
function URLBarSetURI(aURI) {
|
||||
/**
|
||||
* Sets the URI to display in the location bar.
|
||||
*
|
||||
* @param aURI [optional]
|
||||
* nsIURI to set. If this is unspecified, the current URI will be used.
|
||||
* @param aOptions [optional]
|
||||
* An object with the following properties:
|
||||
* {
|
||||
* isForLocationChange:
|
||||
* Set to true to indicate that the function was invoked to respond
|
||||
* to a location change event, rather than to reset the current URI
|
||||
* value. This is useful to avoid calling PopupNotifications.jsm
|
||||
* multiple times.
|
||||
* }
|
||||
*/
|
||||
function URLBarSetURI(aURI, aOptions = {}) {
|
||||
var value = gBrowser.userTypedValue;
|
||||
var valid = false;
|
||||
|
||||
|
@ -2401,7 +2416,7 @@ function URLBarSetURI(aURI) {
|
|||
|
||||
gURLBar.value = value;
|
||||
gURLBar.valueIsTyped = !valid;
|
||||
SetPageProxyState(valid ? "valid" : "invalid");
|
||||
SetPageProxyState(valid ? "valid" : "invalid", aOptions);
|
||||
}
|
||||
|
||||
function losslessDecodeURI(aURI) {
|
||||
|
@ -2500,7 +2515,26 @@ function UpdatePageProxyState()
|
|||
SetPageProxyState("invalid");
|
||||
}
|
||||
|
||||
function SetPageProxyState(aState)
|
||||
/**
|
||||
* Updates the user interface to indicate whether the URI in the location bar is
|
||||
* different than the loaded page, because it's being edited or because a search
|
||||
* result is currently selected and is displayed in the location bar.
|
||||
*
|
||||
* @param aState
|
||||
* The string "valid" indicates that the security indicators and other
|
||||
* related user interface elments should be shown because the URI in the
|
||||
* location bar matches the loaded page. The string "invalid" indicates
|
||||
* that the URI in the location bar is different than the loaded page.
|
||||
* @param aOptions [optional]
|
||||
* An object with the following properties:
|
||||
* {
|
||||
* isForLocationChange:
|
||||
* Set to true to indicate that the function was invoked to respond
|
||||
* to a location change event. This is useful to avoid calling
|
||||
* PopupNotifications.jsm multiple times.
|
||||
* }
|
||||
*/
|
||||
function SetPageProxyState(aState, aOptions = {})
|
||||
{
|
||||
if (!gURLBar)
|
||||
return;
|
||||
|
@ -2515,6 +2549,15 @@ function SetPageProxyState(aState)
|
|||
} else if (aState == "invalid") {
|
||||
gURLBar.removeEventListener("input", UpdatePageProxyState, false);
|
||||
}
|
||||
|
||||
// Only need to call anchorVisibilityChange if the PopupNotifications object
|
||||
// for this window has already been initialized (i.e. its getter no
|
||||
// longer exists). If this is the result of a locations change, then we will
|
||||
// already invoke PopupNotifications.locationChange separately.
|
||||
if (!Object.getOwnPropertyDescriptor(window, "PopupNotifications").get &&
|
||||
!aOptions.isForLocationChange) {
|
||||
PopupNotifications.anchorVisibilityChange();
|
||||
}
|
||||
}
|
||||
|
||||
function PageProxyClickHandler(aEvent)
|
||||
|
@ -4508,7 +4551,7 @@ var XULBrowserWindow = {
|
|||
this.reloadCommand.removeAttribute("disabled");
|
||||
}
|
||||
|
||||
URLBarSetURI(aLocationURI);
|
||||
URLBarSetURI(aLocationURI, { isForLocationChange: true });
|
||||
|
||||
BookmarkingUI.onLocationChange();
|
||||
|
||||
|
@ -5307,7 +5350,7 @@ var gHomeButton = {
|
|||
if (homeButton) {
|
||||
var homePage = this.getHomePage();
|
||||
homePage = homePage.replace(/\|/g, ', ');
|
||||
if (homePage.toLowerCase() == "about:home")
|
||||
if (["about:home", "about:newtab"].includes(homePage.toLowerCase()))
|
||||
homeButton.setAttribute("tooltiptext", homeButton.getAttribute("aboutHomeOverrideTooltip"));
|
||||
else
|
||||
homeButton.setAttribute("tooltiptext", homePage);
|
||||
|
|
|
@ -409,14 +409,20 @@ Sanitizer.prototype = {
|
|||
let refObj = {};
|
||||
TelemetryStopwatch.start("FX_SANITIZE_FORMDATA", refObj);
|
||||
try {
|
||||
// Clear undo history of all searchBars
|
||||
// Clear undo history of all search bars.
|
||||
let windows = Services.wm.getEnumerator("navigator:browser");
|
||||
while (windows.hasMoreElements()) {
|
||||
let currentWindow = windows.getNext();
|
||||
let currentDocument = currentWindow.document;
|
||||
|
||||
// searchBar.textbox may not exist due to the search bar binding
|
||||
// not having been constructed yet if the search bar is in the
|
||||
// overflow or menu panel. It won't have a value or edit history in
|
||||
// that case.
|
||||
let searchBar = currentDocument.getElementById("searchbar");
|
||||
if (searchBar)
|
||||
if (searchBar && searchBar.textbox)
|
||||
searchBar.textbox.reset();
|
||||
|
||||
let tabBrowser = currentWindow.gBrowser;
|
||||
if (!tabBrowser) {
|
||||
// No tab browser? This means that it's too early during startup (typically,
|
||||
|
|
|
@ -365,6 +365,8 @@ support-files =
|
|||
refresh_meta.sjs
|
||||
[browser_relatedTabs.js]
|
||||
[browser_remoteTroubleshoot.js]
|
||||
skip-if = !updater
|
||||
reason = depends on UpdateUtils .Locale
|
||||
support-files =
|
||||
test_remoteTroubleshoot.html
|
||||
[browser_remoteWebNavigation_postdata.js]
|
||||
|
|
|
@ -16,5 +16,7 @@ skip-if = (os == "linux" && (debug || asan))
|
|||
skip-if = (os == "linux" && (debug || asan))
|
||||
[browser_popupNotification_checkbox.js]
|
||||
skip-if = (os == "linux" && (debug || asan))
|
||||
[browser_popupNotification_no_anchors.js]
|
||||
skip-if = (os == "linux" && (debug || asan))
|
||||
[browser_reshow_in_background.js]
|
||||
skip-if = (os == "linux" && (debug || asan))
|
||||
|
|
|
@ -8,11 +8,7 @@ add_task(function* test_displayURI() {
|
|||
gBrowser,
|
||||
url: "https://test1.example.com/",
|
||||
}, function*(browser) {
|
||||
let popupShownPromise = new Promise((resolve, reject) => {
|
||||
onPopupEvent("popupshown", function() {
|
||||
resolve(this);
|
||||
});
|
||||
});
|
||||
let popupShownPromise = waitForNotificationPanel();
|
||||
yield ContentTask.spawn(browser, null, function*() {
|
||||
content.navigator.geolocation.getCurrentPosition(function(pos) {
|
||||
// Do nothing
|
||||
|
|
|
@ -13,7 +13,6 @@ function test() {
|
|||
ok(PopupNotifications.panel, "PopupNotifications panel exists");
|
||||
|
||||
setup();
|
||||
goNext();
|
||||
}
|
||||
|
||||
var tests = [
|
||||
|
@ -110,7 +109,8 @@ var tests = [
|
|||
// Note: test 4 to 6 share a tab.
|
||||
{ id: "Test#4",
|
||||
run: function* () {
|
||||
let tab = gBrowser.addTab("about:blank");
|
||||
let tab = gBrowser.addTab("http://example.com/");
|
||||
yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
|
||||
isnot(gBrowser.selectedTab, tab, "new tab isn't selected");
|
||||
wrongBrowserNotificationObject.browser = gBrowser.getBrowserForTab(tab);
|
||||
let promiseTopic = promiseTopicObserved("PopupNotifications-backgroundShow");
|
||||
|
|
|
@ -9,7 +9,6 @@ function test() {
|
|||
ok(PopupNotifications.panel, "PopupNotifications panel exists");
|
||||
|
||||
setup();
|
||||
goNext();
|
||||
}
|
||||
|
||||
var tests = [
|
||||
|
@ -58,8 +57,7 @@ var tests = [
|
|||
{ id: "Test#3",
|
||||
run: function* () {
|
||||
this.oldSelectedTab = gBrowser.selectedTab;
|
||||
gBrowser.selectedTab = gBrowser.addTab("about:blank");
|
||||
yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.com/");
|
||||
yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/");
|
||||
this.notifyObj = new BasicNotification(this.id);
|
||||
this.notifyObj.addOptions({
|
||||
persistence: 2
|
||||
|
@ -69,7 +67,7 @@ var tests = [
|
|||
onShown: function* (popup) {
|
||||
this.complete = false;
|
||||
yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.org/");
|
||||
yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.com/")
|
||||
yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.com/");
|
||||
// Next load will remove the notification
|
||||
this.complete = true;
|
||||
yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.org/");
|
||||
|
@ -85,8 +83,7 @@ var tests = [
|
|||
{ id: "Test#4",
|
||||
run: function* () {
|
||||
this.oldSelectedTab = gBrowser.selectedTab;
|
||||
gBrowser.selectedTab = gBrowser.addTab("about:blank");
|
||||
yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.com/");
|
||||
yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/");
|
||||
this.notifyObj = new BasicNotification(this.id);
|
||||
// Set a timeout of 10 minutes that should never be hit
|
||||
this.notifyObj.addOptions({
|
||||
|
@ -115,8 +112,7 @@ var tests = [
|
|||
{ id: "Test#5",
|
||||
run: function* () {
|
||||
this.oldSelectedTab = gBrowser.selectedTab;
|
||||
gBrowser.selectedTab = gBrowser.addTab("about:blank");
|
||||
yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.com/");
|
||||
yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/");
|
||||
this.notifyObj = new BasicNotification(this.id);
|
||||
this.notifyObj.addOptions({
|
||||
persistWhileVisible: true
|
||||
|
@ -223,28 +219,4 @@ var tests = [
|
|||
window.locationbar.visible = true;
|
||||
}
|
||||
},
|
||||
// Test that dismissed popupnotifications can be opened on about:blank
|
||||
// (where the rest of the identity block is disabled)
|
||||
{ id: "Test#11",
|
||||
run: function() {
|
||||
this.oldSelectedTab = gBrowser.selectedTab;
|
||||
gBrowser.selectedTab = gBrowser.addTab("about:blank");
|
||||
|
||||
this.notifyObj = new BasicNotification(this.id);
|
||||
this.notifyObj.anchorID = "geo-notification-icon";
|
||||
this.notifyObj.addOptions({dismissed: true});
|
||||
this.notification = showNotification(this.notifyObj);
|
||||
|
||||
EventUtils.synthesizeMouse(document.getElementById("geo-notification-icon"), 0, 0, {});
|
||||
},
|
||||
onShown: function(popup) {
|
||||
checkPopup(popup, this.notifyObj);
|
||||
dismissNotification(popup);
|
||||
},
|
||||
onHidden: function(popup) {
|
||||
this.notification.remove();
|
||||
gBrowser.removeTab(gBrowser.selectedTab);
|
||||
gBrowser.selectedTab = this.oldSelectedTab;
|
||||
}
|
||||
}
|
||||
];
|
||||
|
|
|
@ -9,7 +9,6 @@ function test() {
|
|||
ok(PopupNotifications.panel, "PopupNotifications panel exists");
|
||||
|
||||
setup();
|
||||
goNext();
|
||||
}
|
||||
|
||||
var tests = [
|
||||
|
@ -66,7 +65,7 @@ var tests = [
|
|||
},
|
||||
// Test that multiple notification icons are removed when switching tabs
|
||||
{ id: "Test#3",
|
||||
run: function() {
|
||||
run: function* () {
|
||||
// show the notification on old tab.
|
||||
this.notifyObjOld = new BasicNotification(this.id);
|
||||
this.notifyObjOld.anchorID = "default-notification-icon";
|
||||
|
@ -74,7 +73,7 @@ var tests = [
|
|||
|
||||
// switch tab
|
||||
this.oldSelectedTab = gBrowser.selectedTab;
|
||||
gBrowser.selectedTab = gBrowser.addTab("about:blank");
|
||||
yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/");
|
||||
|
||||
// show the notification on new tab.
|
||||
this.notifyObjNew = new BasicNotification(this.id);
|
||||
|
@ -170,10 +169,7 @@ var tests = [
|
|||
{ id: "Test#7",
|
||||
run: function* () {
|
||||
let oldSelectedTab = gBrowser.selectedTab;
|
||||
let newTab = gBrowser.addTab("about:blank");
|
||||
gBrowser.selectedTab = newTab;
|
||||
|
||||
yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.com/");
|
||||
let newTab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/");
|
||||
gBrowser.selectedTab = oldSelectedTab;
|
||||
let browser = gBrowser.getBrowserForTab(newTab);
|
||||
|
||||
|
@ -199,9 +195,7 @@ var tests = [
|
|||
run: function* () {
|
||||
yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.com/");
|
||||
let originalTab = gBrowser.selectedTab;
|
||||
let bgTab = gBrowser.addTab("about:blank");
|
||||
gBrowser.selectedTab = bgTab;
|
||||
yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.com/");
|
||||
let bgTab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/");
|
||||
let anchor = document.createElement("box");
|
||||
anchor.id = "test26-anchor";
|
||||
anchor.className = "notification-anchor-icon";
|
||||
|
|
|
@ -9,14 +9,13 @@ function test() {
|
|||
ok(PopupNotifications.panel, "PopupNotifications panel exists");
|
||||
|
||||
setup();
|
||||
goNext();
|
||||
}
|
||||
|
||||
var tests = [
|
||||
// Popup Notifications main actions should catch exceptions from callbacks
|
||||
{ id: "Test#1",
|
||||
run: function() {
|
||||
this.testNotif = new ErrorNotification();
|
||||
this.testNotif = new ErrorNotification(this.id);
|
||||
showNotification(this.testNotif);
|
||||
},
|
||||
onShown: function(popup) {
|
||||
|
@ -30,7 +29,7 @@ var tests = [
|
|||
// Popup Notifications secondary actions should catch exceptions from callbacks
|
||||
{ id: "Test#2",
|
||||
run: function() {
|
||||
this.testNotif = new ErrorNotification();
|
||||
this.testNotif = new ErrorNotification(this.id);
|
||||
showNotification(this.testNotif);
|
||||
},
|
||||
onShown: function(popup) {
|
||||
|
@ -97,30 +96,36 @@ var tests = [
|
|||
},
|
||||
// Moving a tab to a new window should remove non-swappable notifications.
|
||||
{ id: "Test#5",
|
||||
run: function() {
|
||||
gBrowser.selectedTab = gBrowser.addTab("about:blank");
|
||||
run: function* () {
|
||||
yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/");
|
||||
|
||||
let notifyObj = new BasicNotification(this.id);
|
||||
|
||||
let shown = waitForNotificationPanel();
|
||||
showNotification(notifyObj);
|
||||
let win = gBrowser.replaceTabWithWindow(gBrowser.selectedTab);
|
||||
whenDelayedStartupFinished(win, function() {
|
||||
let anchor = win.document.getElementById("default-notification-icon");
|
||||
win.PopupNotifications._reshowNotifications(anchor);
|
||||
ok(win.PopupNotifications.panel.childNodes.length == 0,
|
||||
"no notification displayed in new window");
|
||||
ok(notifyObj.swappingCallbackTriggered, "the swapping callback was triggered");
|
||||
ok(notifyObj.removedCallbackTriggered, "the removed callback was triggered");
|
||||
win.close();
|
||||
goNext();
|
||||
});
|
||||
yield shown;
|
||||
|
||||
let promiseWin = BrowserTestUtils.waitForNewWindow();
|
||||
gBrowser.replaceTabWithWindow(gBrowser.selectedTab);
|
||||
let win = yield promiseWin;
|
||||
|
||||
let anchor = win.document.getElementById("default-notification-icon");
|
||||
win.PopupNotifications._reshowNotifications(anchor);
|
||||
ok(win.PopupNotifications.panel.childNodes.length == 0,
|
||||
"no notification displayed in new window");
|
||||
ok(notifyObj.swappingCallbackTriggered, "the swapping callback was triggered");
|
||||
ok(notifyObj.removedCallbackTriggered, "the removed callback was triggered");
|
||||
|
||||
yield BrowserTestUtils.closeWindow(win);
|
||||
yield waitForWindowReadyForPopupNotifications(window);
|
||||
|
||||
goNext();
|
||||
}
|
||||
},
|
||||
// Moving a tab to a new window should preserve swappable notifications.
|
||||
{ id: "Test#6",
|
||||
run: function* () {
|
||||
let originalBrowser = gBrowser.selectedBrowser;
|
||||
let originalWindow = window;
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab("about:blank");
|
||||
yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/");
|
||||
let notifyObj = new BasicNotification(this.id);
|
||||
let originalCallback = notifyObj.options.eventCallback;
|
||||
notifyObj.options.eventCallback = function(eventName) {
|
||||
|
@ -128,9 +133,14 @@ var tests = [
|
|||
return eventName == "swapping";
|
||||
};
|
||||
|
||||
let shown = waitForNotificationPanel();
|
||||
let notification = showNotification(notifyObj);
|
||||
let win = gBrowser.replaceTabWithWindow(gBrowser.selectedTab);
|
||||
yield whenDelayedStartupFinished(win);
|
||||
yield shown;
|
||||
|
||||
let promiseWin = BrowserTestUtils.waitForNewWindow();
|
||||
gBrowser.replaceTabWithWindow(gBrowser.selectedTab);
|
||||
let win = yield promiseWin;
|
||||
yield waitForWindowReadyForPopupNotifications(win);
|
||||
|
||||
yield new Promise(resolve => {
|
||||
let callback = notification.options.eventCallback;
|
||||
|
@ -146,16 +156,9 @@ var tests = [
|
|||
|
||||
checkPopup(win.PopupNotifications.panel, notifyObj);
|
||||
ok(notifyObj.swappingCallbackTriggered, "the swapping callback was triggered");
|
||||
yield BrowserTestUtils.closeWindow(win);
|
||||
|
||||
// These are the same checks that PopupNotifications.jsm makes before it
|
||||
// allows a notification to open. Do not go to the next test until we are
|
||||
// sure that its attempt to display a notification will not fail.
|
||||
yield BrowserTestUtils.waitForCondition(() => originalBrowser.docShellIsActive,
|
||||
"The browser should be active");
|
||||
let fm = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
|
||||
yield BrowserTestUtils.waitForCondition(() => fm.activeWindow == originalWindow,
|
||||
"The window should be active")
|
||||
yield BrowserTestUtils.closeWindow(win);
|
||||
yield waitForWindowReadyForPopupNotifications(window);
|
||||
|
||||
goNext();
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ function test() {
|
|||
ok(PopupNotifications.panel, "PopupNotifications panel exists");
|
||||
|
||||
setup();
|
||||
goNext();
|
||||
}
|
||||
|
||||
var gNotification;
|
||||
|
@ -65,17 +64,21 @@ var tests = [
|
|||
},
|
||||
// The anchor icon should be shown for notifications in background windows.
|
||||
{ id: "Test#3",
|
||||
run: function() {
|
||||
run: function* () {
|
||||
let notifyObj = new BasicNotification(this.id);
|
||||
notifyObj.options.dismissed = true;
|
||||
let win = gBrowser.replaceTabWithWindow(gBrowser.addTab("about:blank"));
|
||||
whenDelayedStartupFinished(win, function() {
|
||||
showNotification(notifyObj);
|
||||
let anchor = document.getElementById("default-notification-icon");
|
||||
is(anchor.getAttribute("showing"), "true", "the anchor is shown");
|
||||
win.close();
|
||||
goNext();
|
||||
});
|
||||
|
||||
let win = yield BrowserTestUtils.openNewBrowserWindow();
|
||||
|
||||
// Open the notification in the original window, now in the background.
|
||||
showNotification(notifyObj);
|
||||
let anchor = document.getElementById("default-notification-icon");
|
||||
is(anchor.getAttribute("showing"), "true", "the anchor is shown");
|
||||
|
||||
yield BrowserTestUtils.closeWindow(win);
|
||||
yield waitForWindowReadyForPopupNotifications(window);
|
||||
|
||||
goNext();
|
||||
}
|
||||
},
|
||||
// Test that persistent doesn't allow the notification to persist after
|
||||
|
@ -83,8 +86,7 @@ var tests = [
|
|||
{ id: "Test#4",
|
||||
run: function* () {
|
||||
this.oldSelectedTab = gBrowser.selectedTab;
|
||||
gBrowser.selectedTab = gBrowser.addTab("about:blank");
|
||||
yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.com/");
|
||||
yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/");
|
||||
this.notifyObj = new BasicNotification(this.id);
|
||||
this.notifyObj.addOptions({
|
||||
persistent: true
|
||||
|
@ -115,8 +117,7 @@ var tests = [
|
|||
{ id: "Test#5",
|
||||
run: function* () {
|
||||
this.oldSelectedTab = gBrowser.selectedTab;
|
||||
gBrowser.selectedTab = gBrowser.addTab("about:blank");
|
||||
yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.com/");
|
||||
yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/");
|
||||
this.notifyObj = new BasicNotification(this.id);
|
||||
this.notifyObj.addOptions({
|
||||
persistent: true
|
||||
|
@ -152,9 +153,7 @@ var tests = [
|
|||
},
|
||||
onShown: function* (popup) {
|
||||
this.oldSelectedTab = gBrowser.selectedTab;
|
||||
gBrowser.selectedTab = gBrowser.addTab("about:blank");
|
||||
info("Waiting for the new tab to load.");
|
||||
yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.com/");
|
||||
yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/");
|
||||
},
|
||||
onHidden: function(popup) {
|
||||
ok(true, "Should have hidden the notification after tab switch");
|
||||
|
@ -179,27 +178,37 @@ var tests = [
|
|||
{ id: "Test#7",
|
||||
run: function* () {
|
||||
this.oldSelectedTab = gBrowser.selectedTab;
|
||||
gBrowser.selectedTab = gBrowser.addTab("about:blank");
|
||||
yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/");
|
||||
|
||||
let shown = waitForNotificationPanel();
|
||||
let notifyObj = new BasicNotification(this.id);
|
||||
notifyObj.options.persistent = true;
|
||||
this.notification = showNotification(notifyObj);
|
||||
let win = gBrowser.replaceTabWithWindow(gBrowser.addTab("about:blank"));
|
||||
whenDelayedStartupFinished(win, () => {
|
||||
ok(notifyObj.shownCallbackTriggered, "Should have triggered the shown callback");
|
||||
let anchor = win.document.getElementById("default-notification-icon");
|
||||
win.PopupNotifications._reshowNotifications(anchor);
|
||||
ok(win.PopupNotifications.panel.childNodes.length == 0,
|
||||
"no notification displayed in new window");
|
||||
ok(PopupNotifications.isPanelOpen, "Should be still showing the popup in the first window");
|
||||
win.close();
|
||||
let id = PopupNotifications.panel.firstChild.getAttribute("popupid");
|
||||
ok(id.endsWith("Test#7"), "Should have found the notification from Test7");
|
||||
ok(PopupNotifications.isPanelOpen, "Should have shown the popup again after getting back to the window");
|
||||
this.notification.remove();
|
||||
gBrowser.removeTab(gBrowser.selectedTab);
|
||||
gBrowser.selectedTab = this.oldSelectedTab;
|
||||
goNext();
|
||||
});
|
||||
yield shown;
|
||||
|
||||
ok(notifyObj.shownCallbackTriggered, "Should have triggered the shown callback");
|
||||
|
||||
yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/");
|
||||
let promiseWin = BrowserTestUtils.waitForNewWindow();
|
||||
gBrowser.replaceTabWithWindow(gBrowser.selectedTab);
|
||||
let win = yield promiseWin;
|
||||
|
||||
let anchor = win.document.getElementById("default-notification-icon");
|
||||
win.PopupNotifications._reshowNotifications(anchor);
|
||||
ok(win.PopupNotifications.panel.childNodes.length == 0,
|
||||
"no notification displayed in new window");
|
||||
|
||||
yield BrowserTestUtils.closeWindow(win);
|
||||
yield waitForWindowReadyForPopupNotifications(window);
|
||||
|
||||
let id = PopupNotifications.panel.firstChild.getAttribute("popupid");
|
||||
ok(id.endsWith("Test#7"), "Should have found the notification from Test7");
|
||||
ok(PopupNotifications.isPanelOpen, "Should have shown the popup again after getting back to the window");
|
||||
this.notification.remove();
|
||||
gBrowser.removeTab(gBrowser.selectedTab);
|
||||
gBrowser.selectedTab = this.oldSelectedTab;
|
||||
|
||||
goNext();
|
||||
}
|
||||
},
|
||||
// Test that only the first persistent notification is shown on update
|
||||
|
|
|
@ -9,7 +9,6 @@ function test() {
|
|||
ok(PopupNotifications.panel, "PopupNotifications panel exists");
|
||||
|
||||
setup();
|
||||
goNext();
|
||||
}
|
||||
|
||||
function checkCheckbox(checkbox, label, checked = false, hidden = false) {
|
||||
|
|
|
@ -0,0 +1,153 @@
|
|||
/* 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/. */
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
ok(PopupNotifications, "PopupNotifications object exists");
|
||||
ok(PopupNotifications.panel, "PopupNotifications panel exists");
|
||||
|
||||
setup();
|
||||
}
|
||||
|
||||
var tests = [
|
||||
// Test that popupnotifications are anchored to the identity icon on
|
||||
// about:blank, where anchor icons are hidden.
|
||||
{ id: "Test#1",
|
||||
run: function* () {
|
||||
this.oldSelectedTab = gBrowser.selectedTab;
|
||||
yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
|
||||
|
||||
this.notifyObj = new BasicNotification(this.id);
|
||||
this.notifyObj.anchorID = "geo-notification-icon";
|
||||
this.notification = showNotification(this.notifyObj);
|
||||
},
|
||||
onShown: function(popup) {
|
||||
checkPopup(popup, this.notifyObj);
|
||||
is(document.getElementById("geo-notification-icon").boxObject.width, 0,
|
||||
"geo anchor shouldn't be visible");
|
||||
is(popup.anchorNode.id, "identity-icon",
|
||||
"notification anchored to identity icon");
|
||||
dismissNotification(popup);
|
||||
},
|
||||
onHidden: function(popup) {
|
||||
this.notification.remove();
|
||||
gBrowser.removeTab(gBrowser.selectedTab);
|
||||
gBrowser.selectedTab = this.oldSelectedTab;
|
||||
}
|
||||
},
|
||||
// Test that popupnotifications are anchored to the identity icon after
|
||||
// navigation to about:blank.
|
||||
{ id: "Test#2",
|
||||
run: function* () {
|
||||
this.oldSelectedTab = gBrowser.selectedTab;
|
||||
yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/");
|
||||
|
||||
this.notifyObj = new BasicNotification(this.id);
|
||||
this.notifyObj.anchorID = "geo-notification-icon";
|
||||
this.notifyObj.addOptions({
|
||||
persistence: 1,
|
||||
});
|
||||
this.notification = showNotification(this.notifyObj);
|
||||
},
|
||||
onShown: function* (popup) {
|
||||
yield promiseTabLoadEvent(gBrowser.selectedTab, "about:blank");
|
||||
|
||||
checkPopup(popup, this.notifyObj);
|
||||
is(document.getElementById("geo-notification-icon").boxObject.width, 0,
|
||||
"geo anchor shouldn't be visible");
|
||||
is(popup.anchorNode.id, "identity-icon",
|
||||
"notification anchored to identity icon");
|
||||
dismissNotification(popup);
|
||||
},
|
||||
onHidden: function(popup) {
|
||||
this.notification.remove();
|
||||
gBrowser.removeTab(gBrowser.selectedTab);
|
||||
gBrowser.selectedTab = this.oldSelectedTab;
|
||||
}
|
||||
},
|
||||
// Test that dismissed popupnotifications cannot be opened on about:blank, but
|
||||
// can be opened after navigation.
|
||||
{ id: "Test#3",
|
||||
run: function* () {
|
||||
this.oldSelectedTab = gBrowser.selectedTab;
|
||||
yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
|
||||
|
||||
this.notifyObj = new BasicNotification(this.id);
|
||||
this.notifyObj.anchorID = "geo-notification-icon";
|
||||
this.notifyObj.addOptions({
|
||||
dismissed: true,
|
||||
persistence: 1,
|
||||
});
|
||||
this.notification = showNotification(this.notifyObj);
|
||||
|
||||
is(document.getElementById("geo-notification-icon").boxObject.width, 0,
|
||||
"geo anchor shouldn't be visible");
|
||||
|
||||
yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.com/");
|
||||
|
||||
isnot(document.getElementById("geo-notification-icon").boxObject.width, 0,
|
||||
"geo anchor should be visible");
|
||||
|
||||
EventUtils.synthesizeMouse(document.getElementById("geo-notification-icon"), 0, 0, {});
|
||||
},
|
||||
onShown: function(popup) {
|
||||
checkPopup(popup, this.notifyObj);
|
||||
dismissNotification(popup);
|
||||
},
|
||||
onHidden: function(popup) {
|
||||
this.notification.remove();
|
||||
gBrowser.removeTab(gBrowser.selectedTab);
|
||||
gBrowser.selectedTab = this.oldSelectedTab;
|
||||
}
|
||||
},
|
||||
// Test that popupnotifications are anchored to the identity icon while
|
||||
// editing the URL in the location bar, and restored to their anchors when the
|
||||
// URL is reverted.
|
||||
{ id: "Test#4",
|
||||
run: function* () {
|
||||
this.oldSelectedTab = gBrowser.selectedTab;
|
||||
yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/");
|
||||
|
||||
let shownInitially = waitForNotificationPanel();
|
||||
this.notifyObj = new BasicNotification(this.id);
|
||||
this.notifyObj.anchorID = "geo-notification-icon";
|
||||
this.notifyObj.addOptions({
|
||||
persistent: true,
|
||||
});
|
||||
this.notification = showNotification(this.notifyObj);
|
||||
yield shownInitially;
|
||||
|
||||
checkPopup(PopupNotifications.panel, this.notifyObj);
|
||||
|
||||
let shownAgain = waitForNotificationPanel();
|
||||
// This will cause the popup to hide and show again.
|
||||
gURLBar.select();
|
||||
EventUtils.synthesizeKey("*", {});
|
||||
// Keep the URL bar empty, so we don't show the awesomebar.
|
||||
EventUtils.synthesizeKey("VK_BACK_SPACE", {});
|
||||
yield shownAgain;
|
||||
|
||||
is(document.getElementById("geo-notification-icon").boxObject.width, 0,
|
||||
"geo anchor shouldn't be visible");
|
||||
is(PopupNotifications.panel.anchorNode.id, "identity-icon",
|
||||
"notification anchored to identity icon");
|
||||
|
||||
let shownLastTime = waitForNotificationPanel();
|
||||
// This will cause the popup to hide and show again.
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {});
|
||||
yield shownLastTime;
|
||||
|
||||
checkPopup(PopupNotifications.panel, this.notifyObj);
|
||||
|
||||
let hidden = new Promise(resolve => onPopupEvent("popuphidden", resolve));
|
||||
this.notification.remove();
|
||||
gBrowser.removeTab(gBrowser.selectedTab);
|
||||
gBrowser.selectedTab = this.oldSelectedTab;
|
||||
yield hidden;
|
||||
|
||||
goNext();
|
||||
}
|
||||
},
|
||||
];
|
|
@ -9,8 +9,11 @@ add_task(function* test_background_notifications_dont_reshow_in_foreground() {
|
|||
// Our initial tab will be A. Let's open two more tabs B and C, but keep
|
||||
// A selected. Then, we'll trigger a PopupNotification in C, and then make
|
||||
// it reshow.
|
||||
let tabB = gBrowser.addTab("about:blank");
|
||||
let tabC = gBrowser.addTab("about:blank");
|
||||
let tabB = gBrowser.addTab("http://example.com/");
|
||||
yield BrowserTestUtils.browserLoaded(tabB.linkedBrowser);
|
||||
|
||||
let tabC = gBrowser.addTab("http://example.com/");
|
||||
yield BrowserTestUtils.browserLoaded(tabC.linkedBrowser);
|
||||
|
||||
let seenEvents = [];
|
||||
|
||||
|
|
|
@ -7,21 +7,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "Task",
|
|||
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
|
||||
"resource://gre/modules/PlacesUtils.jsm");
|
||||
|
||||
function whenDelayedStartupFinished(aWindow, aCallback) {
|
||||
return new Promise(resolve => {
|
||||
info("Waiting for delayed startup to finish");
|
||||
Services.obs.addObserver(function observer(aSubject, aTopic) {
|
||||
if (aWindow == aSubject) {
|
||||
Services.obs.removeObserver(observer, aTopic);
|
||||
if (aCallback) {
|
||||
executeSoon(aCallback);
|
||||
}
|
||||
resolve();
|
||||
}
|
||||
}, "browser-delayed-startup-finished", false);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows waiting for an observer notification once.
|
||||
*
|
||||
|
@ -43,6 +28,23 @@ function promiseTopicObserved(topic)
|
|||
return deferred.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after opening a new window or switching windows, this will wait until
|
||||
* we are sure that an attempt to display a notification will not fail.
|
||||
*/
|
||||
function* waitForWindowReadyForPopupNotifications(win)
|
||||
{
|
||||
// These are the same checks that PopupNotifications.jsm makes before it
|
||||
// allows a notification to open.
|
||||
yield BrowserTestUtils.waitForCondition(
|
||||
() => win.gBrowser.selectedBrowser.docShellIsActive,
|
||||
"The browser should be active"
|
||||
);
|
||||
yield BrowserTestUtils.waitForCondition(
|
||||
() => Services.focus.activeWindow == win,
|
||||
"The window should be active"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for a load (or custom) event to finish in a given tab. If provided
|
||||
|
@ -70,10 +72,10 @@ function promiseTabLoadEvent(tab, url)
|
|||
const PREF_SECURITY_DELAY_INITIAL = Services.prefs.getIntPref("security.notification_enable_delay");
|
||||
|
||||
function setup() {
|
||||
// Disable transitions as they slow the test down and we want to click the
|
||||
// mouse buttons in a predictable location.
|
||||
|
||||
BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/")
|
||||
.then(goNext);
|
||||
registerCleanupFunction(() => {
|
||||
gBrowser.removeTab(gBrowser.selectedTab);
|
||||
PopupNotifications.buttonDelay = PREF_SECURITY_DELAY_INITIAL;
|
||||
});
|
||||
}
|
||||
|
@ -173,7 +175,8 @@ BasicNotification.prototype.addOptions = function(options) {
|
|||
this.options[name] = value;
|
||||
};
|
||||
|
||||
function ErrorNotification() {
|
||||
function ErrorNotification(testId) {
|
||||
BasicNotification.call(this, testId);
|
||||
this.mainAction.callback = () => {
|
||||
this.mainActionClicked = true;
|
||||
throw new Error("Oops!");
|
||||
|
@ -184,8 +187,7 @@ function ErrorNotification() {
|
|||
};
|
||||
}
|
||||
|
||||
ErrorNotification.prototype = new BasicNotification();
|
||||
ErrorNotification.prototype.constructor = ErrorNotification;
|
||||
ErrorNotification.prototype = BasicNotification.prototype;
|
||||
|
||||
function checkPopup(popup, notifyObj) {
|
||||
info("Checking notification " + notifyObj.id);
|
||||
|
@ -257,6 +259,14 @@ function onPopupEvent(eventName, callback, condition) {
|
|||
PopupNotifications.panel.addEventListener(eventName, listener, false);
|
||||
}
|
||||
|
||||
function waitForNotificationPanel() {
|
||||
return new Promise(resolve => {
|
||||
onPopupEvent("popupshown", function() {
|
||||
resolve(this);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function triggerMainCommand(popup) {
|
||||
let notifications = popup.childNodes;
|
||||
ok(notifications.length > 0, "at least one notification displayed");
|
||||
|
|
|
@ -38,6 +38,7 @@ var gMenuBuilder = {
|
|||
// to be displayed. We always clear all the items again when
|
||||
// popuphidden fires.
|
||||
build(contextData) {
|
||||
let firstItem = true;
|
||||
let xulMenu = contextData.menu;
|
||||
xulMenu.addEventListener("popuphidden", this);
|
||||
this.xulMenu = xulMenu;
|
||||
|
@ -72,6 +73,13 @@ var gMenuBuilder = {
|
|||
rootElement.setAttribute("image", resolvedURL);
|
||||
}
|
||||
|
||||
if (firstItem) {
|
||||
firstItem = false;
|
||||
const separator = xulMenu.ownerDocument.createElement("menuseparator");
|
||||
this.itemsToCleanUp.add(separator);
|
||||
xulMenu.append(separator);
|
||||
}
|
||||
|
||||
xulMenu.appendChild(rootElement);
|
||||
this.itemsToCleanUp.add(rootElement);
|
||||
}
|
||||
|
@ -252,13 +260,8 @@ global.actionContextMenu = function(contextData) {
|
|||
gMenuBuilder.buildActionContextMenu(contextData);
|
||||
};
|
||||
|
||||
function contextMenuObserver(subject, topic, data) {
|
||||
subject = subject.wrappedJSObject;
|
||||
gMenuBuilder.build(subject);
|
||||
}
|
||||
|
||||
function getContexts(contextData) {
|
||||
let contexts = new Set(["all"]);
|
||||
let contexts = new Set();
|
||||
|
||||
if (contextData.inFrame) {
|
||||
contexts.add("frame");
|
||||
|
@ -300,10 +303,16 @@ function getContexts(contextData) {
|
|||
contexts.add("browser_action");
|
||||
}
|
||||
|
||||
if (contexts.size == 1) {
|
||||
if (contexts.size === 0) {
|
||||
contexts.add("page");
|
||||
}
|
||||
|
||||
if (contextData.onTab) {
|
||||
contexts.add("tab");
|
||||
} else {
|
||||
contexts.add("all");
|
||||
}
|
||||
|
||||
return contexts;
|
||||
}
|
||||
|
||||
|
@ -517,14 +526,53 @@ MenuItem.prototype = {
|
|||
},
|
||||
};
|
||||
|
||||
// While any extensions are active, this Tracker registers to observe/listen
|
||||
// for contex-menu events from both content and chrome.
|
||||
const contextMenuTracker = {
|
||||
register() {
|
||||
Services.obs.addObserver(this, "on-build-contextmenu", false);
|
||||
for (const window of WindowListManager.browserWindows()) {
|
||||
this.onWindowOpen(window);
|
||||
}
|
||||
WindowListManager.addOpenListener(this.onWindowOpen);
|
||||
},
|
||||
|
||||
unregister() {
|
||||
Services.obs.removeObserver(this, "on-build-contextmenu");
|
||||
for (const window of WindowListManager.browserWindows()) {
|
||||
const menu = window.document.getElementById("tabContextMenu");
|
||||
menu.removeEventListener("popupshowing", this);
|
||||
}
|
||||
WindowListManager.removeOpenListener(this.onWindowOpen);
|
||||
},
|
||||
|
||||
observe(subject, topic, data) {
|
||||
subject = subject.wrappedJSObject;
|
||||
gMenuBuilder.build(subject);
|
||||
},
|
||||
|
||||
onWindowOpen(window) {
|
||||
const menu = window.document.getElementById("tabContextMenu");
|
||||
menu.addEventListener("popupshowing", contextMenuTracker);
|
||||
},
|
||||
|
||||
handleEvent(event) {
|
||||
const menu = event.target;
|
||||
if (menu.id === "tabContextMenu") {
|
||||
const trigger = menu.triggerNode;
|
||||
const tab = trigger.localName === "tab" ? trigger : TabManager.activeTab;
|
||||
const pageUrl = tab.linkedBrowser.currentURI.spec;
|
||||
gMenuBuilder.build({menu, tab, pageUrl, onTab: true});
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
var gExtensionCount = 0;
|
||||
/* eslint-disable mozilla/balanced-listeners */
|
||||
extensions.on("startup", (type, extension) => {
|
||||
gContextMenuMap.set(extension, new Map());
|
||||
if (++gExtensionCount == 1) {
|
||||
Services.obs.addObserver(contextMenuObserver,
|
||||
"on-build-contextmenu",
|
||||
false);
|
||||
contextMenuTracker.register();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -532,8 +580,7 @@ extensions.on("shutdown", (type, extension) => {
|
|||
gContextMenuMap.delete(extension);
|
||||
gRootItems.delete(extension);
|
||||
if (--gExtensionCount == 0) {
|
||||
Services.obs.removeObserver(contextMenuObserver,
|
||||
"on-build-contextmenu");
|
||||
contextMenuTracker.unregister();
|
||||
}
|
||||
});
|
||||
/* eslint-enable mozilla/balanced-listeners */
|
||||
|
|
|
@ -31,8 +31,8 @@
|
|||
{
|
||||
"id": "ContextType",
|
||||
"type": "string",
|
||||
"enum": ["all", "page", "frame", "selection", "link", "editable", "password", "image", "video", "audio", "launcher", "browser_action", "page_action"],
|
||||
"description": "The different contexts a menu can appear in. Specifying 'all' is equivalent to the combination of all other contexts except for 'launcher'. The 'launcher' context is only supported by apps and is used to add menu items to the context menu that appears when clicking on the app icon in the launcher/taskbar/dock/etc. Different platforms might put limitations on what is actually supported in a launcher context menu."
|
||||
"enum": ["all", "page", "frame", "selection", "link", "editable", "password", "image", "video", "audio", "launcher", "browser_action", "page_action", "tab"],
|
||||
"description": "The different contexts a menu can appear in. Specifying 'all' is equivalent to the combination of all other contexts except for 'tab'."
|
||||
},
|
||||
{
|
||||
"id": "ItemType",
|
||||
|
|
|
@ -34,8 +34,8 @@ support-files =
|
|||
[browser_ext_commands_onCommand.js]
|
||||
[browser_ext_contentscript_connect.js]
|
||||
[browser_ext_contextMenus.js]
|
||||
[browser_ext_contextMenus_actionMenus.js]
|
||||
[browser_ext_contextMenus_checkboxes.js]
|
||||
[browser_ext_contextMenus_chrome.js]
|
||||
[browser_ext_contextMenus_icons.js]
|
||||
[browser_ext_contextMenus_onclick.js]
|
||||
[browser_ext_contextMenus_radioGroups.js]
|
||||
|
|
|
@ -1,64 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
add_task(function* () {
|
||||
const manifest = {
|
||||
page_action: {},
|
||||
browser_action: {},
|
||||
permissions: ["contextMenus"],
|
||||
};
|
||||
|
||||
async function background() {
|
||||
const contexts = ["page_action", "browser_action"];
|
||||
|
||||
const parentId = browser.contextMenus.create({contexts, title: "parent"});
|
||||
await browser.contextMenus.create({contexts, parentId, title: "click A"});
|
||||
await browser.contextMenus.create({contexts, parentId, title: "click B"});
|
||||
|
||||
for (let i = 1; i < 9; i++) {
|
||||
await browser.contextMenus.create({contexts, title: `click ${i}`});
|
||||
}
|
||||
|
||||
browser.contextMenus.onClicked.addListener((info, tab) => {
|
||||
browser.test.sendMessage("click", {info, tab});
|
||||
});
|
||||
|
||||
const [tab] = await browser.tabs.query({active: true});
|
||||
await browser.pageAction.show(tab.id);
|
||||
browser.test.sendMessage("ready", tab.id);
|
||||
}
|
||||
|
||||
const extension = ExtensionTestUtils.loadExtension({manifest, background});
|
||||
const tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/");
|
||||
|
||||
yield extension.startup();
|
||||
const tabId = yield extension.awaitMessage("ready");
|
||||
|
||||
for (const kind of ["page", "browser"]) {
|
||||
const menu = yield openActionContextMenu(extension, kind);
|
||||
const [submenu, second, , , , last, separator] = menu.children;
|
||||
|
||||
is(submenu.tagName, "menu", "Correct submenu type");
|
||||
is(submenu.label, "parent", "Correct submenu title");
|
||||
|
||||
const popup = yield openActionSubmenu(submenu);
|
||||
is(popup, submenu.firstChild, "Correct submenu opened");
|
||||
is(popup.children.length, 2, "Correct number of submenu items");
|
||||
|
||||
is(second.tagName, "menuitem", "Second menu item type is correct");
|
||||
is(second.label, "click 1", "Second menu item title is correct");
|
||||
|
||||
is(last.label, "click 5", "Last menu item title is correct");
|
||||
is(separator.tagName, "menuseparator", "Separator after last menu item");
|
||||
|
||||
yield closeActionContextMenu(popup.firstChild);
|
||||
const {info, tab} = yield extension.awaitMessage("click");
|
||||
is(info.pageUrl, "http://example.com/", "Click info pageUrl is correct");
|
||||
is(tab.id, tabId, "Click event tab ID is correct");
|
||||
}
|
||||
|
||||
yield BrowserTestUtils.removeTab(tab);
|
||||
yield extension.unload();
|
||||
});
|
|
@ -0,0 +1,129 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
add_task(function* test_actionContextMenus() {
|
||||
const manifest = {
|
||||
page_action: {},
|
||||
browser_action: {},
|
||||
permissions: ["contextMenus"],
|
||||
};
|
||||
|
||||
async function background() {
|
||||
const contexts = ["page_action", "browser_action"];
|
||||
|
||||
const parentId = browser.contextMenus.create({contexts, title: "parent"});
|
||||
await browser.contextMenus.create({contexts, parentId, title: "click A"});
|
||||
await browser.contextMenus.create({contexts, parentId, title: "click B"});
|
||||
|
||||
for (let i = 1; i < 9; i++) {
|
||||
await browser.contextMenus.create({contexts, title: `click ${i}`});
|
||||
}
|
||||
|
||||
browser.contextMenus.onClicked.addListener((info, tab) => {
|
||||
browser.test.sendMessage("click", {info, tab});
|
||||
});
|
||||
|
||||
const [tab] = await browser.tabs.query({active: true});
|
||||
await browser.pageAction.show(tab.id);
|
||||
browser.test.sendMessage("ready", tab.id);
|
||||
}
|
||||
|
||||
const extension = ExtensionTestUtils.loadExtension({manifest, background});
|
||||
const tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/");
|
||||
|
||||
yield extension.startup();
|
||||
const tabId = yield extension.awaitMessage("ready");
|
||||
|
||||
for (const kind of ["page", "browser"]) {
|
||||
const menu = yield openActionContextMenu(extension, kind);
|
||||
const [submenu, second, , , , last, separator] = menu.children;
|
||||
|
||||
is(submenu.tagName, "menu", "Correct submenu type");
|
||||
is(submenu.label, "parent", "Correct submenu title");
|
||||
|
||||
const popup = yield openSubmenu(submenu);
|
||||
is(popup, submenu.firstChild, "Correct submenu opened");
|
||||
is(popup.children.length, 2, "Correct number of submenu items");
|
||||
|
||||
is(second.tagName, "menuitem", "Second menu item type is correct");
|
||||
is(second.label, "click 1", "Second menu item title is correct");
|
||||
|
||||
is(last.label, "click 5", "Last menu item title is correct");
|
||||
is(separator.tagName, "menuseparator", "Separator after last menu item");
|
||||
|
||||
yield closeActionContextMenu(popup.firstChild);
|
||||
const {info, tab} = yield extension.awaitMessage("click");
|
||||
is(info.pageUrl, "http://example.com/", "Click info pageUrl is correct");
|
||||
is(tab.id, tabId, "Click event tab ID is correct");
|
||||
}
|
||||
|
||||
yield BrowserTestUtils.removeTab(tab);
|
||||
yield extension.unload();
|
||||
});
|
||||
|
||||
add_task(function* test_tabContextMenu() {
|
||||
const first = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
permissions: ["contextMenus"],
|
||||
},
|
||||
async background() {
|
||||
await browser.contextMenus.create({title: "alpha", contexts: ["tab"]});
|
||||
await browser.contextMenus.create({title: "beta", contexts: ["tab"]});
|
||||
|
||||
browser.contextMenus.onClicked.addListener((info, tab) => {
|
||||
browser.test.sendMessage("click", {info, tab});
|
||||
});
|
||||
|
||||
const [tab] = await browser.tabs.query({active: true});
|
||||
browser.test.sendMessage("ready", tab.id);
|
||||
},
|
||||
});
|
||||
|
||||
const second = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
permissions: ["contextMenus"],
|
||||
},
|
||||
async background() {
|
||||
await browser.contextMenus.create({title: "gamma", contexts: ["tab"]});
|
||||
browser.test.sendMessage("ready");
|
||||
},
|
||||
});
|
||||
|
||||
const tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com/");
|
||||
yield first.startup();
|
||||
yield second.startup();
|
||||
|
||||
const tabId = yield first.awaitMessage("ready");
|
||||
yield second.awaitMessage("ready");
|
||||
|
||||
const menu = yield openTabContextMenu();
|
||||
const [separator, submenu, gamma] = Array.from(menu.children).slice(-3);
|
||||
is(separator.tagName, "menuseparator", "Separator before first extension item");
|
||||
|
||||
is(submenu.tagName, "menu", "Correct submenu type");
|
||||
is(submenu.label, "Generated extension", "Correct submenu title");
|
||||
|
||||
is(gamma.tagName, "menuitem", "Third menu item type is correct");
|
||||
is(gamma.label, "gamma", "Third menu item label is correct");
|
||||
|
||||
const popup = yield openSubmenu(submenu);
|
||||
is(popup, submenu.firstChild, "Correct submenu opened");
|
||||
is(popup.children.length, 2, "Correct number of submenu items");
|
||||
|
||||
const [alpha, beta] = popup.children;
|
||||
is(alpha.tagName, "menuitem", "First menu item type is correct");
|
||||
is(alpha.label, "alpha", "First menu item label is correct");
|
||||
is(beta.tagName, "menuitem", "Second menu item type is correct");
|
||||
is(beta.label, "beta", "Second menu item label is correct");
|
||||
|
||||
yield closeTabContextMenu(beta);
|
||||
const click = yield first.awaitMessage("click");
|
||||
is(click.info.pageUrl, "http://example.com/", "Click info pageUrl is correct");
|
||||
is(click.tab.id, tabId, "Click event tab ID is correct");
|
||||
|
||||
yield BrowserTestUtils.removeTab(tab);
|
||||
yield first.unload();
|
||||
yield second.unload();
|
||||
});
|
|
@ -26,6 +26,33 @@ function createHiddenBrowser(url) {
|
|||
|
||||
let extension;
|
||||
let dummy = "http://mochi.test:8888/browser/browser/components/extensions/test/browser/file_dummy.html";
|
||||
let headers = {
|
||||
request: {
|
||||
add: {
|
||||
"X-WebRequest-request": "text",
|
||||
"X-WebRequest-request-binary": "binary",
|
||||
},
|
||||
modify: {
|
||||
"user-agent": "WebRequest",
|
||||
},
|
||||
remove: [
|
||||
"accept-encoding",
|
||||
],
|
||||
},
|
||||
response: {
|
||||
add: {
|
||||
"X-WebRequest-response": "text",
|
||||
"X-WebRequest-response-binary": "binary",
|
||||
},
|
||||
modify: {
|
||||
"server": "WebRequest",
|
||||
"content-type": "text/html; charset=utf-8",
|
||||
},
|
||||
remove: [
|
||||
"connection",
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
add_task(function* setup() {
|
||||
// SelfSupport has a tendency to fire when running this test alone, without
|
||||
|
@ -41,6 +68,7 @@ add_task(function* test_newWindow() {
|
|||
let expect = {
|
||||
"file_dummy.html": {
|
||||
type: "main_frame",
|
||||
headers,
|
||||
},
|
||||
};
|
||||
// NOTE: When running solo, favicon will be loaded at some point during
|
||||
|
@ -63,6 +91,7 @@ add_task(function* test_newTab() {
|
|||
let expect = {
|
||||
"file_dummy.html": {
|
||||
type: "main_frame",
|
||||
headers,
|
||||
},
|
||||
};
|
||||
extension.sendMessage("set-expected", {expect, ignore: ["favicon.ico"]});
|
||||
|
@ -77,6 +106,7 @@ add_task(function* test_subframe() {
|
|||
let expect = {
|
||||
"file_dummy.html": {
|
||||
type: "main_frame",
|
||||
headers,
|
||||
},
|
||||
};
|
||||
// test a content subframe attached to hidden window
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
* promisePopupShown promisePopupHidden
|
||||
* openContextMenu closeContextMenu
|
||||
* openExtensionContextMenu closeExtensionContextMenu
|
||||
* openActionContextMenu openActionSubmenu closeActionContextMenu
|
||||
* openActionContextMenu openSubmenu closeActionContextMenu
|
||||
* openTabContextMenu closeTabContextMenu
|
||||
* imageBuffer getListStyleImage getPanelForNode
|
||||
* awaitExtensionPanel awaitPopupResize
|
||||
* promiseContentDimensions alterContent
|
||||
|
@ -262,20 +263,16 @@ function* closeExtensionContextMenu(itemToSelect) {
|
|||
yield popupHiddenPromise;
|
||||
}
|
||||
|
||||
function* openActionContextMenu(extension, kind, win = window) {
|
||||
const menu = win.document.getElementById("toolbar-context-menu");
|
||||
const id = `${makeWidgetId(extension.id)}-${kind}-action`;
|
||||
const button = win.document.getElementById(id);
|
||||
SetPageProxyState("valid");
|
||||
|
||||
function* openChromeContextMenu(menuId, target, win = window) {
|
||||
const node = win.document.querySelector(target);
|
||||
const menu = win.document.getElementById(menuId);
|
||||
const shown = BrowserTestUtils.waitForEvent(menu, "popupshown");
|
||||
EventUtils.synthesizeMouseAtCenter(button, {type: "contextmenu"}, win);
|
||||
EventUtils.synthesizeMouseAtCenter(node, {type: "contextmenu"}, win);
|
||||
yield shown;
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
function* openActionSubmenu(submenuItem, win = window) {
|
||||
function* openSubmenu(submenuItem, win = window) {
|
||||
const submenu = submenuItem.firstChild;
|
||||
const shown = BrowserTestUtils.waitForEvent(submenu, "popupshown");
|
||||
EventUtils.synthesizeMouseAtCenter(submenuItem, {}, win);
|
||||
|
@ -283,8 +280,8 @@ function* openActionSubmenu(submenuItem, win = window) {
|
|||
return submenu;
|
||||
}
|
||||
|
||||
function closeActionContextMenu(itemToSelect, win = window) {
|
||||
const menu = win.document.getElementById("toolbar-context-menu");
|
||||
function closeChromeContextMenu(menuId, itemToSelect, win = window) {
|
||||
const menu = win.document.getElementById(menuId);
|
||||
const hidden = BrowserTestUtils.waitForEvent(menu, "popuphidden");
|
||||
if (itemToSelect) {
|
||||
EventUtils.synthesizeMouseAtCenter(itemToSelect, {}, win);
|
||||
|
@ -294,6 +291,25 @@ function closeActionContextMenu(itemToSelect, win = window) {
|
|||
return hidden;
|
||||
}
|
||||
|
||||
function openActionContextMenu(extension, kind, win = window) {
|
||||
// See comment from clickPageAction below.
|
||||
SetPageProxyState("valid");
|
||||
const id = `#${makeWidgetId(extension.id)}-${kind}-action`;
|
||||
return openChromeContextMenu("toolbar-context-menu", id, win);
|
||||
}
|
||||
|
||||
function closeActionContextMenu(itemToSelect, win = window) {
|
||||
return closeChromeContextMenu("toolbar-context-menu", itemToSelect, win);
|
||||
}
|
||||
|
||||
function openTabContextMenu(win = window) {
|
||||
return openChromeContextMenu("tabContextMenu", ".tabbrowser-tab[selected]", win);
|
||||
}
|
||||
|
||||
function closeTabContextMenu(itemToSelect, win = window) {
|
||||
return closeChromeContextMenu("tabContextMenu", itemToSelect, win);
|
||||
}
|
||||
|
||||
function getPageActionPopup(extension, win = window) {
|
||||
let panelId = makeWidgetId(extension.id) + "-panel";
|
||||
return win.document.getElementById(panelId);
|
||||
|
|
|
@ -30,7 +30,6 @@ const PREF_SELECTED_WEB = "browser.feeds.handlers.webservice";
|
|||
const PREF_SELECTED_ACTION = "browser.feeds.handler";
|
||||
const PREF_SELECTED_READER = "browser.feeds.handler.default";
|
||||
const PREF_HANDLER_EXTERNAL_PREFIX = "network.protocol-handler.external";
|
||||
const PREF_ALLOW_DIFFERENT_HOST = "gecko.handlerService.allowRegisterFromDifferentHost";
|
||||
|
||||
const STRING_BUNDLE_URI = "chrome://browser/locale/feeds/subscribe.properties";
|
||||
|
||||
|
@ -156,11 +155,8 @@ const Utils = {
|
|||
}
|
||||
|
||||
// We also reject handlers registered from a different host (see bug 402287)
|
||||
// The pref allows us to test the feature
|
||||
let pb = Services.prefs;
|
||||
if (!pb.getBoolPref(PREF_ALLOW_DIFFERENT_HOST) &&
|
||||
(!["http:", "https:"].includes(aContentWindow.location.protocol) ||
|
||||
aContentWindow.location.hostname != uri.host)) {
|
||||
if (!["http:", "https:"].includes(aContentWindow.location.protocol) ||
|
||||
aContentWindow.location.hostname != uri.host) {
|
||||
throw this.getSecurityError(
|
||||
"Permission denied to add " + uri.spec + " as a content or protocol handler",
|
||||
aContentWindow);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import os
|
||||
import shutil
|
||||
import time
|
||||
|
||||
from marionette_harness import MarionetteTestCase
|
||||
|
||||
|
@ -343,21 +344,22 @@ class TestFirefoxRefresh(MarionetteTestCase):
|
|||
|
||||
if self.reset_profile_path:
|
||||
# Remove ourselves from profiles.ini
|
||||
profileLeafName = os.path.basename(os.path.normpath(self.reset_profile_path))
|
||||
self.runCode("""
|
||||
let [salt, name] = arguments[0].split(".");
|
||||
let name = arguments[0];
|
||||
let profile = global.profSvc.getProfileByName(name);
|
||||
profile.remove(false)
|
||||
global.profSvc.flush();
|
||||
""", script_args=[profileLeafName])
|
||||
""", script_args=[self.profileNameToRemove])
|
||||
# And delete all the files.
|
||||
shutil.rmtree(self.reset_profile_path, ignore_errors=False, onerror=handleRemoveReadonly)
|
||||
|
||||
def doReset(self):
|
||||
profileName = "marionette-test-profile-" + str(int(time.time() * 1000))
|
||||
self.profileNameToRemove = profileName
|
||||
self.runCode("""
|
||||
// Ensure the current (temporary) profile is in profiles.ini:
|
||||
let profD = Services.dirsvc.get("ProfD", Ci.nsIFile);
|
||||
let profileName = "marionette-test-profile-" + Date.now();
|
||||
let profileName = arguments[1];
|
||||
let myProfile = global.profSvc.createProfile(profD, profileName);
|
||||
global.profSvc.flush()
|
||||
|
||||
|
@ -375,7 +377,7 @@ class TestFirefoxRefresh(MarionetteTestCase):
|
|||
env.set("MOZ_RESET_PROFILE_RESTART", "1");
|
||||
env.set("XRE_PROFILE_PATH", arguments[0]);
|
||||
env.set("XRE_PROFILE_NAME", profileName);
|
||||
""", script_args=[self.marionette.instance.profile.profile])
|
||||
""", script_args=[self.marionette.instance.profile.profile, profileName])
|
||||
|
||||
profileLeafName = os.path.basename(os.path.normpath(self.marionette.instance.profile.profile))
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
|||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/NetUtil.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "OfflineAppCacheHelper",
|
||||
"resource:///modules/offlineAppCache.jsm");
|
||||
|
@ -177,5 +178,28 @@ this.SiteDataManager = {
|
|||
Services.cookies.removeAll();
|
||||
OfflineAppCacheHelper.clear();
|
||||
this.updateSites();
|
||||
},
|
||||
|
||||
getSites() {
|
||||
return Promise.all([this._updateQuotaPromise, this._updateDiskCachePromise])
|
||||
.then(() => {
|
||||
let list = [];
|
||||
for (let [origin, site] of this._sites) {
|
||||
let cache = null;
|
||||
let usage = site.quotaUsage;
|
||||
for (cache of site.appCacheList) {
|
||||
usage += cache.usage;
|
||||
}
|
||||
for (cache of site.diskCacheList) {
|
||||
usage += cache.dataSize;
|
||||
}
|
||||
list.push({
|
||||
usage,
|
||||
status: site.status,
|
||||
uri: NetUtil.newURI(origin)
|
||||
});
|
||||
}
|
||||
return list;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
@ -60,6 +60,8 @@ var gAdvancedPane = {
|
|||
SiteDataManager.updateSites();
|
||||
setEventListener("clearSiteDataButton", "command",
|
||||
gAdvancedPane.clearSiteData);
|
||||
setEventListener("siteDataSettings", "command",
|
||||
gAdvancedPane.showSiteDataSettings);
|
||||
}
|
||||
|
||||
setEventListener("layers.acceleration.disabled", "change",
|
||||
|
@ -339,6 +341,10 @@ var gAdvancedPane = {
|
|||
gSubDialog.open("chrome://browser/content/preferences/connection.xul");
|
||||
},
|
||||
|
||||
showSiteDataSettings: function() {
|
||||
gSubDialog.open("chrome://browser/content/preferences/siteDataSettings.xul");
|
||||
},
|
||||
|
||||
updateTotalSiteDataSize: function() {
|
||||
SiteDataManager.getTotalUsage()
|
||||
.then(usage => {
|
||||
|
|
|
@ -338,6 +338,11 @@
|
|||
<button id="clearSiteDataButton" icon="clear"
|
||||
label="&clearSiteData.label;" accesskey="&clearSiteData.accesskey;"/>
|
||||
</hbox>
|
||||
<vbox align="end">
|
||||
<button id="siteDataSettings"
|
||||
label="&siteDataSettings.label;"
|
||||
accesskey="&siteDataSettings.accesskey;"/>
|
||||
</vbox>
|
||||
</groupbox>
|
||||
</tabpanel>
|
||||
|
||||
|
|
|
@ -245,10 +245,17 @@ var gMainPane = {
|
|||
{
|
||||
let homePref = document.getElementById("browser.startup.homepage");
|
||||
|
||||
// If the pref is set to about:home, set the value to "" to show the
|
||||
// placeholder text (about:home title).
|
||||
if (homePref.value.toLowerCase() == "about:home")
|
||||
// If the pref is set to about:home or about:newtab, set the value to ""
|
||||
// to show the placeholder text (about:home title) rather than
|
||||
// exposing those URLs to users.
|
||||
let defaultBranch = Services.prefs.getDefaultBranch("");
|
||||
let defaultValue = defaultBranch.getComplexValue("browser.startup.homepage",
|
||||
Ci.nsIPrefLocalizedString).data;
|
||||
let currentValue = homePref.value.toLowerCase();
|
||||
if (currentValue == "about:home" ||
|
||||
(currentValue == defaultValue && currentValue == "about:newtab")) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// If the pref is actually "", show about:blank. The actual home page
|
||||
// loading code treats them the same, and we don't want the placeholder text
|
||||
|
|
|
@ -6,6 +6,7 @@ support-files =
|
|||
|
||||
[browser_advanced_siteData.js]
|
||||
[browser_advanced_update.js]
|
||||
skip-if = !updater
|
||||
[browser_basic_rebuild_fonts_test.js]
|
||||
[browser_bug410900.js]
|
||||
[browser_bug705422.js]
|
||||
|
|
|
@ -27,5 +27,9 @@ browser.jar:
|
|||
content/browser/preferences/sanitize.js
|
||||
content/browser/preferences/selectBookmark.xul
|
||||
content/browser/preferences/selectBookmark.js
|
||||
content/browser/preferences/siteDataSettings.xul
|
||||
content/browser/preferences/siteDataSettings.js
|
||||
content/browser/preferences/siteDataSettings.css
|
||||
content/browser/preferences/siteListItem.xml
|
||||
content/browser/preferences/translation.xul
|
||||
content/browser/preferences/translation.js
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
/* 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/. */
|
||||
|
||||
#sitesList {
|
||||
min-height: 20em;
|
||||
}
|
||||
|
||||
#sitesList > richlistitem {
|
||||
-moz-binding: url("chrome://browser/content/preferences/siteListItem.xml#siteListItem");
|
||||
}
|
||||
|
||||
.item-box {
|
||||
padding: 5px 8px;
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
|
||||
/* 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/. */
|
||||
const { interfaces: Ci, utils: Cu } = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "SiteDataManager",
|
||||
"resource:///modules/SiteDataManager.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "DownloadUtils",
|
||||
"resource://gre/modules/DownloadUtils.jsm");
|
||||
|
||||
"use strict";
|
||||
|
||||
let gSiteDataSettings = {
|
||||
|
||||
// Array of meatdata of sites. Each array element is object holding:
|
||||
// - uri: uri of site; instance of nsIURI
|
||||
// - status: persistent-storage permission status
|
||||
// - usage: disk usage which site uses
|
||||
_sites: null,
|
||||
|
||||
_list: null,
|
||||
|
||||
init() {
|
||||
this._list = document.getElementById("sitesList");
|
||||
SiteDataManager.getSites().then(sites => {
|
||||
this._sites = sites;
|
||||
this._sortSites(this._sites, "decending");
|
||||
this._buildSitesList(this._sites);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Sort sites by usages
|
||||
*
|
||||
* @param sites {Array}
|
||||
* @param order {String} indicate to sort in the "decending" or "ascending" order
|
||||
*/
|
||||
_sortSites(sites, order) {
|
||||
sites.sort((a, b) => {
|
||||
if (order === "ascending") {
|
||||
return a.usage - b.usage;
|
||||
}
|
||||
return b.usage - a.usage;
|
||||
});
|
||||
},
|
||||
|
||||
_buildSitesList(sites) {
|
||||
// Clear old entries.
|
||||
while (this._list.childNodes.length > 1) {
|
||||
this._list.removeChild(this._list.lastChild);
|
||||
}
|
||||
|
||||
let prefStrBundle = document.getElementById("bundlePreferences");
|
||||
for (let data of sites) {
|
||||
let statusStrId = data.status === Ci.nsIPermissionManager.ALLOW_ACTION ? "important" : "default";
|
||||
let size = DownloadUtils.convertByteUnits(data.usage);
|
||||
let item = document.createElement("richlistitem");
|
||||
item.setAttribute("data-origin", data.uri.spec);
|
||||
item.setAttribute("host", data.uri.host);
|
||||
item.setAttribute("status", prefStrBundle.getString(statusStrId));
|
||||
item.setAttribute("usage", prefStrBundle.getFormattedString("siteUsage", size));
|
||||
this._list.appendChild(item);
|
||||
}
|
||||
}
|
||||
};
|
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<!-- 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/. -->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://browser/skin/preferences/preferences.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://browser/content/preferences/siteDataSettings.css" type="text/css"?>
|
||||
|
||||
<!DOCTYPE dialog SYSTEM "chrome://browser/locale/preferences/siteDataSettings.dtd" >
|
||||
|
||||
<window id="SiteDataSettingsDialog" windowtype="Browser:SiteDataSettings"
|
||||
class="windowDialog" title="&window.title;"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
style="width: 45em;"
|
||||
onload="gSiteDataSettings.init();"
|
||||
persist="screenX screenY width height">
|
||||
|
||||
<script src="chrome://browser/content/preferences/siteDataSettings.js"/>
|
||||
|
||||
<stringbundle id="bundlePreferences"
|
||||
src="chrome://browser/locale/preferences/preferences.properties"/>
|
||||
|
||||
<vbox flex="1">
|
||||
<description>&settings.description;</description>
|
||||
<separator class="thin"/>
|
||||
|
||||
<richlistbox id="sitesList" orient="vertical" flex="1">
|
||||
<listheader>
|
||||
<treecol flex="4" width="50" label="&hostCol.label;"/>
|
||||
<treecol flex="2" width="50" label="&statusCol.label;"/>
|
||||
<treecol flex="1" width="50" label="&usageCol.label;"/>
|
||||
</listheader>
|
||||
</richlistbox>
|
||||
</vbox>
|
||||
|
||||
</window>
|
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<!-- 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-globals-from siteDataSettings.js -->
|
||||
|
||||
<!DOCTYPE overlay [
|
||||
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
|
||||
<!ENTITY % applicationsDTD SYSTEM "chrome://browser/locale/preferences/siteDataSettings.dtd">
|
||||
%brandDTD;
|
||||
%applicationsDTD;
|
||||
]>
|
||||
|
||||
<bindings id="siteListItemBindings"
|
||||
xmlns="http://www.mozilla.org/xbl"
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:xbl="http://www.mozilla.org/xbl">
|
||||
|
||||
<binding id="siteListItem" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
|
||||
<content>
|
||||
<xul:hbox flex="1">
|
||||
<xul:hbox flex="4" width="50" class="item-box" align="center" xbl:inherits="tooltiptext=host">
|
||||
<xul:label flex="1" crop="end" xbl:inherits="value=host"/>
|
||||
</xul:hbox>
|
||||
<xul:hbox flex="2" width="50" class="item-box" align="center" xbl:inherits="tooltiptext=status">
|
||||
<xul:label flex="1" crop="end" xbl:inherits="value=status"/>
|
||||
</xul:hbox>
|
||||
<xul:hbox flex="1" width="50" class="item-box" align="center" xbl:inherits="tooltiptext=usage">
|
||||
<xul:label flex="1" crop="end" xbl:inherits="value=usage"/>
|
||||
</xul:hbox>
|
||||
</xul:hbox>
|
||||
</content>
|
||||
</binding>
|
||||
|
||||
</bindings>
|
|
@ -881,10 +881,8 @@ var SessionStoreInternal = {
|
|||
if (activePageData) {
|
||||
if (activePageData.title) {
|
||||
tab.label = activePageData.title;
|
||||
tab.crop = "end";
|
||||
} else if (activePageData.url != "about:blank") {
|
||||
tab.label = activePageData.url;
|
||||
tab.crop = "center";
|
||||
}
|
||||
} else if (tab.hasAttribute("customizemode")) {
|
||||
win.gCustomizeMode.setTab(tab);
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
[DEFAULT]
|
||||
|
||||
[browser_bug538331.js]
|
||||
skip-if = !updater
|
||||
reason = test depends on update channel
|
||||
[browser_contentpermissionprompt.js]
|
||||
|
|
|
@ -160,20 +160,15 @@ function loadJSONAsync(file, options) {
|
|||
|
||||
// Returns a promise that is resolved with the AddonInstall for that URL.
|
||||
function addonInstallForURL(url, hash) {
|
||||
let deferred = Promise.defer();
|
||||
AddonManager.getInstallForURL(url, install => deferred.resolve(install),
|
||||
"application/x-xpinstall", hash);
|
||||
return deferred.promise;
|
||||
return AddonManager.getInstallForURL(url, null, "application/x-xpinstall", hash);
|
||||
}
|
||||
|
||||
// Returns a promise that is resolved with an Array<Addon> of the installed
|
||||
// experiment addons.
|
||||
function installedExperimentAddons() {
|
||||
let deferred = Promise.defer();
|
||||
AddonManager.getAddonsByTypes(["experiment"], (addons) => {
|
||||
deferred.resolve(addons.filter(a => !a.appDisabled));
|
||||
return AddonManager.getAddonsByTypes(["experiment"]).then(addons => {
|
||||
return addons.filter(a => !a.appDisabled);
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
// Takes an Array<Addon> and returns a promise that is resolved when the
|
||||
|
@ -2025,18 +2020,14 @@ Experiments.ExperimentEntry.prototype = {
|
|||
return Promise.resolve(null);
|
||||
}
|
||||
|
||||
let deferred = Promise.defer();
|
||||
|
||||
AddonManager.getAddonByID(this._addonId, (addon) => {
|
||||
return AddonManager.getAddonByID(this._addonId).then(addon => {
|
||||
if (addon && addon.appDisabled) {
|
||||
// Don't return PreviousExperiments.
|
||||
addon = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
deferred.resolve(addon);
|
||||
return addon;
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
_logTermination: function(terminationKind, terminationReason) {
|
||||
|
|
|
@ -6,7 +6,25 @@
|
|||
|
||||
/* exported startup, shutdown, install, uninstall */
|
||||
|
||||
function startup() {}
|
||||
const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "FormAutofillParent",
|
||||
"resource://formautofill/FormAutofillParent.jsm");
|
||||
|
||||
function startup() {
|
||||
// Besides this pref, we'll need dom.forms.autocomplete.experimental enabled
|
||||
// as well to make sure form autocomplete works correctly.
|
||||
if (!Services.prefs.getBoolPref("browser.formautofill.enabled")) {
|
||||
return;
|
||||
}
|
||||
|
||||
FormAutofillParent.init();
|
||||
Services.mm.loadFrameScript("chrome://formautofill/content/FormAutofillContent.js", true);
|
||||
}
|
||||
|
||||
function shutdown() {}
|
||||
function install() {}
|
||||
function uninstall() {}
|
||||
|
|
|
@ -3,13 +3,14 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*
|
||||
* Implements a service used by DOM content to request Form Autofill.
|
||||
* Form Autofill frame script.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
|
||||
|
||||
/**
|
||||
* Handles profile autofill for a DOM Form element.
|
||||
* @param {HTMLFormElement} form Form that need to be auto filled
|
||||
|
@ -130,5 +131,3 @@ FormAutofillHandler.prototype = {
|
|||
}
|
||||
},
|
||||
};
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["FormAutofillHandler"];
|
|
@ -3,5 +3,8 @@
|
|||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
[features/formautofill@mozilla.org] chrome.jar:
|
||||
% resource formautofill %content/
|
||||
content/ (content/*)
|
||||
% resource formautofill %res/
|
||||
res/ (*.jsm)
|
||||
|
||||
% content formautofill %content/
|
||||
content/ (content/*)
|
||||
|
|
|
@ -20,3 +20,6 @@ BROWSER_CHROME_MANIFESTS += ['test/browser/browser.ini']
|
|||
XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini']
|
||||
|
||||
JAR_MANIFESTS += ['jar.mn']
|
||||
|
||||
with Files('**'):
|
||||
BUG_COMPONENT = ('Toolkit', 'Form Manager')
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Provides infrastructure for automated formautofill components tests.
|
||||
*/
|
||||
|
||||
/* exported importAutofillModule, getTempFile */
|
||||
/* exported getTempFile */
|
||||
|
||||
"use strict";
|
||||
|
||||
|
@ -18,11 +18,18 @@ XPCOMUtils.defineLazyModuleGetter(this, "DownloadPaths",
|
|||
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
|
||||
"resource://gre/modules/FileUtils.jsm");
|
||||
|
||||
// Register the resource path of formautofill
|
||||
let resHandler = Services.io.getProtocolHandler("resource")
|
||||
.QueryInterface(Ci.nsISubstitutingProtocolHandler);
|
||||
let dataURI = NetUtil.newURI(do_get_file(".", true));
|
||||
resHandler.setSubstitution("formautofill", dataURI);
|
||||
// Load our bootstrap extension manifest so we can access our chrome/resource URIs.
|
||||
const EXTENSION_ID = "formautofill@mozilla.org";
|
||||
let extensionDir = Services.dirsvc.get("GreD", Ci.nsIFile);
|
||||
extensionDir.append("browser");
|
||||
extensionDir.append("features");
|
||||
extensionDir.append(EXTENSION_ID);
|
||||
// If the unpacked extension doesn't exist, use the packed version.
|
||||
if (!extensionDir.exists()) {
|
||||
extensionDir = extensionDir.parent;
|
||||
extensionDir.append(EXTENSION_ID + ".xpi");
|
||||
}
|
||||
Components.manager.addBootstrappedManifestLocation(extensionDir);
|
||||
|
||||
// While the previous test file should have deleted all the temporary files it
|
||||
// used, on Windows these might still be pending deletion on the physical file
|
||||
|
@ -30,6 +37,17 @@ resHandler.setSubstitution("formautofill", dataURI);
|
|||
// with a file that is still pending deletion highly unlikely.
|
||||
let gFileCounter = Math.floor(Math.random() * 1000000);
|
||||
|
||||
function loadFormAutofillContent() {
|
||||
let facGlobal = {};
|
||||
let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"]
|
||||
.getService(Ci.mozIJSSubScriptLoader);
|
||||
loader.loadSubScriptWithOptions("chrome://formautofill/content/FormAutofillContent.js", {
|
||||
target: facGlobal,
|
||||
});
|
||||
|
||||
return facGlobal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to a temporary file, that is guaranteed not to exist, and
|
||||
* to have never been created before.
|
||||
|
@ -64,10 +82,13 @@ function getTempFile(leafName) {
|
|||
}
|
||||
|
||||
add_task(function* test_common_initialize() {
|
||||
Services.prefs.setBoolPref("browser.formautofill.enabled", true);
|
||||
Services.prefs.setBoolPref("dom.forms.autocomplete.experimental", true);
|
||||
loadFormAutofillContent();
|
||||
|
||||
// Clean up after every test.
|
||||
do_register_cleanup(() => {
|
||||
Services.prefs.setBoolPref("dom.forms.autocomplete.experimental", false);
|
||||
Services.prefs.clearUserPref("browser.formautofill.enabled");
|
||||
Services.prefs.clearUserPref("dom.forms.autocomplete.experimental");
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
/**
|
||||
* Cleans up the testing environment.
|
||||
*/
|
||||
|
||||
/* global resHandler */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Unregister the resource path of formautofill.
|
||||
resHandler.setSubstitution("formautofill", null);
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
let {FormAutofillHandler} = Cu.import("resource://formautofill/FormAutofillContent.jsm");
|
||||
let {FormAutofillHandler} = loadFormAutofillContent();
|
||||
|
||||
const TESTCASES = [
|
||||
{
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
let {FormAutofillHandler} = Cu.import("resource://formautofill/FormAutofillContent.jsm");
|
||||
let {FormAutofillHandler} = loadFormAutofillContent();
|
||||
|
||||
const TESTCASES = [
|
||||
{
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
[DEFAULT]
|
||||
firefox-appdir = browser
|
||||
head = head.js
|
||||
tail = tail.js
|
||||
tail =
|
||||
support-files =
|
||||
../../content/FormAutofillContent.jsm
|
||||
../../content/FormAutofillParent.jsm
|
||||
../../content/ProfileStorage.jsm
|
||||
|
||||
[test_autofillFormFields.js]
|
||||
[test_collectFormFields.js]
|
||||
|
|
|
@ -61,6 +61,8 @@
|
|||
<!ENTITY siteData.label "Site Data">
|
||||
<!ENTITY clearSiteData.label "Clear All Data">
|
||||
<!ENTITY clearSiteData.accesskey "l">
|
||||
<!ENTITY siteDataSettings.label "Settings…">
|
||||
<!ENTITY siteDataSettings.accesskey "i">
|
||||
|
||||
<!-- LOCALIZATION NOTE:
|
||||
The entities limitCacheSizeBefore.label and limitCacheSizeAfter.label appear on a single
|
||||
|
|
|
@ -173,6 +173,9 @@ totalSiteDataSize=Your stored site data is currently using %1$S %2$S of disk spa
|
|||
clearSiteDataPromptTitle=Clear all cookies and site data
|
||||
clearSiteDataPromptText=Selecting ‘Clear Now’ will clear all cookies and site data stored by Firefox. This may sign you out of websites and remove offline web content.
|
||||
clearSiteDataNow=Clear Now
|
||||
important=Important
|
||||
default=Default
|
||||
siteUsage=%1$S %2$S
|
||||
|
||||
syncUnlink.title=Do you want to unlink your device?
|
||||
syncUnlink.label=This device will no longer be associated with your Sync account. All of your personal data, both on this device and in your Sync account, will remain intact.
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<!-- 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/. -->
|
||||
|
||||
<!ENTITY window.title "Settings - Site Data">
|
||||
<!ENTITY settings.description "The following websites asked to store site data in your disk. You can specify which websites are allowed to store site data. Default site data is temporary and could be deleted automatically.">
|
||||
<!ENTITY hostCol.label "Site">
|
||||
<!ENTITY statusCol.label "Status">
|
||||
<!ENTITY usageCol.label "Storage">
|
|
@ -82,6 +82,7 @@
|
|||
locale/browser/preferences/sync.dtd (%chrome/browser/preferences/sync.dtd)
|
||||
locale/browser/preferences/tabs.dtd (%chrome/browser/preferences/tabs.dtd)
|
||||
locale/browser/preferences/search.dtd (%chrome/browser/preferences/search.dtd)
|
||||
locale/browser/preferences/siteDataSettings.dtd (%chrome/browser/preferences/siteDataSettings.dtd)
|
||||
locale/browser/preferences/translation.dtd (%chrome/browser/preferences/translation.dtd)
|
||||
locale/browser/syncBrand.dtd (%chrome/browser/syncBrand.dtd)
|
||||
locale/browser/syncSetup.dtd (%chrome/browser/syncSetup.dtd)
|
||||
|
|
Двоичные данные
browser/themes/linux/Security-broken.png
Двоичные данные
browser/themes/linux/Security-broken.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 928 B |
|
@ -31,7 +31,6 @@ browser.jar:
|
|||
skin/classic/browser/reload-stop-go.png
|
||||
skin/classic/browser/reload-stop-go@2x.png
|
||||
skin/classic/browser/searchbar.css
|
||||
skin/classic/browser/Security-broken.png
|
||||
skin/classic/browser/setDesktopBackground.css
|
||||
skin/classic/browser/slowStartup-16.png
|
||||
skin/classic/browser/Toolbar.png
|
||||
|
|
|
@ -398,7 +398,7 @@ if __name__ == "__main__":
|
|||
# by looking at an MSVC install, but we don't really have that here.
|
||||
# Force things on.
|
||||
extra_cflags2 = []
|
||||
extra_cxxflags2 = ['-fms-compatibility-version=19.00.23918', '-Xclang', '-std=c++14']
|
||||
extra_cxxflags2 = ['-fms-compatibility-version=19.00.24213', '-Xclang', '-std=c++14']
|
||||
|
||||
build_one_stage(
|
||||
[cc] + extra_cflags,
|
||||
|
|
|
@ -370,12 +370,12 @@ def check_compiler(compiler, language, target):
|
|||
if info.type == 'clang-cl' and info.language_version != 201402:
|
||||
append_flag('-std=c++14')
|
||||
|
||||
# We force clang-cl to emulate Visual C++ 2015 Update 2 with fallback to
|
||||
# We force clang-cl to emulate Visual C++ 2015 Update 3 with fallback to
|
||||
# cl.exe.
|
||||
if info.type == 'clang-cl' and info.version != '19.00.23918':
|
||||
if info.type == 'clang-cl' and info.version != '19.00.24213':
|
||||
# Those flags are direct clang-cl flags that don't need -Xclang, add
|
||||
# them directly.
|
||||
flags.append('-fms-compatibility-version=19.00.23918')
|
||||
flags.append('-fms-compatibility-version=19.00.24213')
|
||||
flags.append('-fallback')
|
||||
|
||||
# Check compiler target
|
||||
|
@ -716,11 +716,11 @@ def compiler(language, host_or_target, c_compiler=None, other_compiler=None,
|
|||
'Only clang/llvm 3.6 or newer is supported.')
|
||||
|
||||
if info.type == 'msvc':
|
||||
if info.version < '19.00.23918':
|
||||
if info.version < '19.00.24213':
|
||||
raise FatalCheckError(
|
||||
'This version (%s) of the MSVC compiler is not '
|
||||
'supported.\n'
|
||||
'You must install Visual C++ 2015 Update 2 or newer in '
|
||||
'You must install Visual C++ 2015 Update 3 or newer in '
|
||||
'order to build.\n'
|
||||
'See https://developer.mozilla.org/en/'
|
||||
'Windows_Build_Prerequisites' % info.version)
|
||||
|
|
|
@ -31,7 +31,7 @@ let promise = require("promise");
|
|||
let defer = require("devtools/shared/defer");
|
||||
const Services = require("Services");
|
||||
const {Task} = require("devtools/shared/task");
|
||||
const {KeyShortcuts} = require("devtools/client/shared/key-shortcuts");
|
||||
const KeyShortcuts = require("devtools/client/shared/key-shortcuts");
|
||||
|
||||
const TEST_DIR = gTestPath.substr(0, gTestPath.lastIndexOf("/"));
|
||||
const CHROME_URL_ROOT = TEST_DIR + "/";
|
||||
|
|
|
@ -55,7 +55,7 @@ loader.lazyRequireGetter(this, "system",
|
|||
loader.lazyRequireGetter(this, "getPreferenceFront",
|
||||
"devtools/shared/fronts/preference", true);
|
||||
loader.lazyRequireGetter(this, "KeyShortcuts",
|
||||
"devtools/client/shared/key-shortcuts", true);
|
||||
"devtools/client/shared/key-shortcuts");
|
||||
loader.lazyRequireGetter(this, "ZoomKeys",
|
||||
"devtools/client/shared/zoom-keys");
|
||||
loader.lazyRequireGetter(this, "settleAll",
|
||||
|
|
|
@ -16,7 +16,7 @@ const NS_XHTML = "http://www.w3.org/1999/xhtml";
|
|||
const SCROLL_REPEAT_MS = 100;
|
||||
|
||||
const EventEmitter = require("devtools/shared/event-emitter");
|
||||
const {KeyShortcuts} = require("devtools/client/shared/key-shortcuts");
|
||||
const KeyShortcuts = require("devtools/client/shared/key-shortcuts");
|
||||
|
||||
// Some margin may be required for visible element detection.
|
||||
const SCROLL_MARGIN = 1;
|
||||
|
|
|
@ -838,4 +838,4 @@ BoxModelView.prototype = {
|
|||
}
|
||||
};
|
||||
|
||||
exports.BoxModelView = BoxModelView;
|
||||
module.exports = BoxModelView;
|
||||
|
|
|
@ -12,7 +12,7 @@ const {ELEMENT_STYLE} = require("devtools/shared/specs/styles");
|
|||
const promise = require("promise");
|
||||
const defer = require("devtools/shared/defer");
|
||||
const Services = require("Services");
|
||||
const {OutputParser} = require("devtools/client/shared/output-parser");
|
||||
const OutputParser = require("devtools/client/shared/output-parser");
|
||||
const {PrefObserver} = require("devtools/client/shared/prefs");
|
||||
const {createChild} = require("devtools/client/inspector/shared/utils");
|
||||
const {gDevTools} = require("devtools/client/framework/devtools");
|
||||
|
@ -25,8 +25,8 @@ const {
|
|||
} = require("devtools/client/inspector/shared/node-types");
|
||||
const StyleInspectorMenu = require("devtools/client/inspector/shared/style-inspector-menu");
|
||||
const TooltipsOverlay = require("devtools/client/inspector/shared/tooltips-overlay");
|
||||
const {KeyShortcuts} = require("devtools/client/shared/key-shortcuts");
|
||||
const {BoxModelView} = require("devtools/client/inspector/components/box-model");
|
||||
const KeyShortcuts = require("devtools/client/shared/key-shortcuts");
|
||||
const BoxModelView = require("devtools/client/inspector/components/box-model");
|
||||
const clipboardHelper = require("devtools/shared/platform/clipboard");
|
||||
|
||||
const STYLE_INSPECTOR_PROPERTIES = "devtools/shared/locales/styleinspector.properties";
|
||||
|
|
|
@ -9,7 +9,7 @@ const {Task} = require("devtools/shared/task");
|
|||
const {KeyCodes} = require("devtools/client/shared/keycodes");
|
||||
|
||||
const EventEmitter = require("devtools/shared/event-emitter");
|
||||
const {AutocompletePopup} = require("devtools/client/shared/autocomplete-popup");
|
||||
const AutocompletePopup = require("devtools/client/shared/autocomplete-popup");
|
||||
const Services = require("Services");
|
||||
|
||||
// Maximum number of selector suggestions shown in the panel.
|
||||
|
|
|
@ -13,7 +13,7 @@ var promise = require("promise");
|
|||
var defer = require("devtools/shared/defer");
|
||||
var EventEmitter = require("devtools/shared/event-emitter");
|
||||
const {executeSoon} = require("devtools/shared/DevToolsUtils");
|
||||
var {KeyShortcuts} = require("devtools/client/shared/key-shortcuts");
|
||||
var KeyShortcuts = require("devtools/client/shared/key-shortcuts");
|
||||
var {Task} = require("devtools/shared/task");
|
||||
const {initCssProperties} = require("devtools/shared/fronts/css-properties");
|
||||
const nodeConstants = require("devtools/shared/dom-node-constants");
|
||||
|
@ -568,7 +568,7 @@ Inspector.prototype = {
|
|||
this.computedview = new ComputedViewTool(this, this.panelWin);
|
||||
|
||||
if (Services.prefs.getBoolPref("devtools.layoutview.enabled")) {
|
||||
const {LayoutView} = this.browserRequire("devtools/client/inspector/layout/layout");
|
||||
const LayoutView = this.browserRequire("devtools/client/inspector/layout/layout");
|
||||
this.layoutview = new LayoutView(this, this.panelWin);
|
||||
}
|
||||
|
||||
|
|
|
@ -258,4 +258,4 @@ LayoutView.prototype = {
|
|||
|
||||
};
|
||||
|
||||
exports.LayoutView = LayoutView;
|
||||
module.exports = LayoutView;
|
||||
|
|
|
@ -14,8 +14,8 @@ const EventEmitter = require("devtools/shared/event-emitter");
|
|||
const {LocalizationHelper} = require("devtools/shared/l10n");
|
||||
const {PluralForm} = require("devtools/shared/plural-form");
|
||||
const {template} = require("devtools/shared/gcli/templater");
|
||||
const {AutocompletePopup} = require("devtools/client/shared/autocomplete-popup");
|
||||
const {KeyShortcuts} = require("devtools/client/shared/key-shortcuts");
|
||||
const AutocompletePopup = require("devtools/client/shared/autocomplete-popup");
|
||||
const KeyShortcuts = require("devtools/client/shared/key-shortcuts");
|
||||
const {scrollIntoViewIfNeeded} = require("devtools/client/shared/scroll");
|
||||
const {UndoStack} = require("devtools/client/shared/undo");
|
||||
const {HTMLTooltip} = require("devtools/client/shared/widgets/tooltip/HTMLTooltip");
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
"use strict";
|
||||
|
||||
const promise = require("promise");
|
||||
const {Rule} = require("devtools/client/inspector/rules/models/rule");
|
||||
const Rule = require("devtools/client/inspector/rules/models/rule");
|
||||
const {promiseWarn} = require("devtools/client/inspector/shared/utils");
|
||||
const {ELEMENT_STYLE} = require("devtools/shared/specs/styles");
|
||||
const {getCssProperties} = require("devtools/shared/fronts/css-properties");
|
||||
|
@ -409,4 +409,4 @@ UserProperties.prototype = {
|
|||
}
|
||||
};
|
||||
|
||||
exports.ElementStyle = ElementStyle;
|
||||
module.exports = ElementStyle;
|
||||
|
|
|
@ -683,4 +683,4 @@ Rule.prototype = {
|
|||
}
|
||||
};
|
||||
|
||||
exports.Rule = Rule;
|
||||
module.exports = Rule;
|
||||
|
|
|
@ -12,11 +12,11 @@ const {Task} = require("devtools/shared/task");
|
|||
const {Tools} = require("devtools/client/definitions");
|
||||
const {l10n} = require("devtools/shared/inspector/css-logic");
|
||||
const {ELEMENT_STYLE} = require("devtools/shared/specs/styles");
|
||||
const {OutputParser} = require("devtools/client/shared/output-parser");
|
||||
const OutputParser = require("devtools/client/shared/output-parser");
|
||||
const {PrefObserver} = require("devtools/client/shared/prefs");
|
||||
const {ElementStyle} = require("devtools/client/inspector/rules/models/element-style");
|
||||
const {Rule} = require("devtools/client/inspector/rules/models/rule");
|
||||
const {RuleEditor} = require("devtools/client/inspector/rules/views/rule-editor");
|
||||
const ElementStyle = require("devtools/client/inspector/rules/models/element-style");
|
||||
const Rule = require("devtools/client/inspector/rules/models/rule");
|
||||
const RuleEditor = require("devtools/client/inspector/rules/views/rule-editor");
|
||||
const {gDevTools} = require("devtools/client/framework/devtools");
|
||||
const {getCssProperties} = require("devtools/shared/fronts/css-properties");
|
||||
const {
|
||||
|
@ -30,9 +30,9 @@ const StyleInspectorMenu = require("devtools/client/inspector/shared/style-inspe
|
|||
const TooltipsOverlay = require("devtools/client/inspector/shared/tooltips-overlay");
|
||||
const {createChild, promiseWarn, throttle} = require("devtools/client/inspector/shared/utils");
|
||||
const EventEmitter = require("devtools/shared/event-emitter");
|
||||
const {KeyShortcuts} = require("devtools/client/shared/key-shortcuts");
|
||||
const KeyShortcuts = require("devtools/client/shared/key-shortcuts");
|
||||
const clipboardHelper = require("devtools/shared/platform/clipboard");
|
||||
const {AutocompletePopup} = require("devtools/client/shared/autocomplete-popup");
|
||||
const AutocompletePopup = require("devtools/client/shared/autocomplete-popup");
|
||||
|
||||
const HTML_NS = "http://www.w3.org/1999/xhtml";
|
||||
const PREF_UA_STYLES = "devtools.inspector.showUserAgentStyles";
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
const {l10n} = require("devtools/shared/inspector/css-logic");
|
||||
const {ELEMENT_STYLE} = require("devtools/shared/specs/styles");
|
||||
const {Rule} = require("devtools/client/inspector/rules/models/rule");
|
||||
const Rule = require("devtools/client/inspector/rules/models/rule");
|
||||
const {InplaceEditor, editableField, editableItem} =
|
||||
require("devtools/client/shared/inplace-editor");
|
||||
const {TextPropertyEditor} =
|
||||
|
@ -618,4 +618,4 @@ RuleEditor.prototype = {
|
|||
}
|
||||
};
|
||||
|
||||
exports.RuleEditor = RuleEditor;
|
||||
module.exports = RuleEditor;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// This is more of a unit test than a mochitest-browser test, but can't be
|
||||
// tested with an xpcshell test as the output-parser requires the DOM to work.
|
||||
|
||||
const {OutputParser} = require("devtools/client/shared/output-parser");
|
||||
const OutputParser = require("devtools/client/shared/output-parser");
|
||||
const {initCssProperties, getCssProperties} = require("devtools/shared/fronts/css-properties");
|
||||
|
||||
const COLOR_CLASS = "color-class";
|
||||
|
|
|
@ -86,7 +86,6 @@ function AutocompletePopup(toolboxDoc, options = {}) {
|
|||
|
||||
this.selectedIndex = -1;
|
||||
}
|
||||
exports.AutocompletePopup = AutocompletePopup;
|
||||
|
||||
AutocompletePopup.prototype = {
|
||||
_document: null,
|
||||
|
@ -592,3 +591,5 @@ AutocompletePopup.prototype = {
|
|||
return this._document.defaultView;
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = AutocompletePopup;
|
||||
|
|
|
@ -104,7 +104,7 @@ define(function (require, exports, module) {
|
|||
props.push(Caption({
|
||||
object: objectLink({
|
||||
object: object
|
||||
}, `${object.ownPropertyLength - max} more…`)
|
||||
}, `${propertiesLength - max} more…`)
|
||||
}));
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
"use strict";
|
||||
|
||||
const { DOM: dom, createClass, PropTypes } = require("devtools/client/shared/vendor/react");
|
||||
const {KeyShortcuts} = require("devtools/client/shared/key-shortcuts");
|
||||
const KeyShortcuts = require("devtools/client/shared/key-shortcuts");
|
||||
|
||||
/**
|
||||
* A generic search box component for use across devtools
|
||||
|
|
|
@ -31,6 +31,7 @@ window.onload = Task.async(function* () {
|
|||
yield testProxy();
|
||||
yield testArrayBuffer();
|
||||
yield testSharedArrayBuffer();
|
||||
yield testApplicationCache();
|
||||
|
||||
// Test property iterator
|
||||
yield testMaxProps();
|
||||
|
@ -288,6 +289,43 @@ window.onload = Task.async(function* () {
|
|||
testRepRenderModes(modeTests, testName, componentUnderTest, getGripStub(testName));
|
||||
}
|
||||
|
||||
function testApplicationCache() {
|
||||
// Test object: `window.applicationCache`
|
||||
const testName = "testApplicationCache";
|
||||
|
||||
// Test that correct rep is chosen
|
||||
const gripStub = getGripStub(testName);
|
||||
const renderedRep = shallowRenderComponent(Rep, { object: gripStub });
|
||||
is(renderedRep.type, Grip.rep, `Rep correctly selects ${Grip.rep.displayName}`);
|
||||
|
||||
// Test rendering
|
||||
const defaultOutput =
|
||||
"OfflineResourceList { status: 0, onchecking: null, onerror: null, 7 more… }";
|
||||
|
||||
const modeTests = [
|
||||
{
|
||||
mode: undefined,
|
||||
expectedOutput: defaultOutput,
|
||||
},
|
||||
{
|
||||
mode: MODE.TINY,
|
||||
expectedOutput: "OfflineResourceList",
|
||||
},
|
||||
{
|
||||
mode: MODE.SHORT,
|
||||
expectedOutput: defaultOutput,
|
||||
},
|
||||
{
|
||||
mode: MODE.LONG,
|
||||
expectedOutput: "OfflineResourceList { status: 0, onchecking: null, " +
|
||||
"onerror: null, onnoupdate: null, ondownloading: null, onprogress: null, " +
|
||||
"onupdateready: null, oncached: null, onobsolete: null, mozItems: [] }",
|
||||
}
|
||||
];
|
||||
|
||||
testRepRenderModes(modeTests, testName, componentUnderTest, getGripStub(testName));
|
||||
}
|
||||
|
||||
function testMaxProps() {
|
||||
// Test object: `{a: "a", b: "b", c: "c"}`;
|
||||
const testName = "testMaxProps";
|
||||
|
@ -878,6 +916,108 @@ window.onload = Task.async(function* () {
|
|||
}
|
||||
}
|
||||
};
|
||||
case "testApplicationCache":
|
||||
return {
|
||||
"type": "object",
|
||||
"actor": "server2.conn1.child2/obj45",
|
||||
"class": "OfflineResourceList",
|
||||
"ownPropertyLength": 0,
|
||||
"preview": {
|
||||
"kind": "Object",
|
||||
"ownProperties": {},
|
||||
"ownPropertiesLength": 0,
|
||||
"safeGetterValues": {
|
||||
"status": {
|
||||
"getterValue": 0,
|
||||
"getterPrototypeLevel": 1,
|
||||
"enumerable": true,
|
||||
"writable": true
|
||||
},
|
||||
"onchecking": {
|
||||
"getterValue": {
|
||||
"type": "null"
|
||||
},
|
||||
"getterPrototypeLevel": 1,
|
||||
"enumerable": true,
|
||||
"writable": true
|
||||
},
|
||||
"onerror": {
|
||||
"getterValue": {
|
||||
"type": "null"
|
||||
},
|
||||
"getterPrototypeLevel": 1,
|
||||
"enumerable": true,
|
||||
"writable": true
|
||||
},
|
||||
"onnoupdate": {
|
||||
"getterValue": {
|
||||
"type": "null"
|
||||
},
|
||||
"getterPrototypeLevel": 1,
|
||||
"enumerable": true,
|
||||
"writable": true
|
||||
},
|
||||
"ondownloading": {
|
||||
"getterValue": {
|
||||
"type": "null"
|
||||
},
|
||||
"getterPrototypeLevel": 1,
|
||||
"enumerable": true,
|
||||
"writable": true
|
||||
},
|
||||
"onprogress": {
|
||||
"getterValue": {
|
||||
"type": "null"
|
||||
},
|
||||
"getterPrototypeLevel": 1,
|
||||
"enumerable": true,
|
||||
"writable": true
|
||||
},
|
||||
"onupdateready": {
|
||||
"getterValue": {
|
||||
"type": "null"
|
||||
},
|
||||
"getterPrototypeLevel": 1,
|
||||
"enumerable": true,
|
||||
"writable": true
|
||||
},
|
||||
"oncached": {
|
||||
"getterValue": {
|
||||
"type": "null"
|
||||
},
|
||||
"getterPrototypeLevel": 1,
|
||||
"enumerable": true,
|
||||
"writable": true
|
||||
},
|
||||
"onobsolete": {
|
||||
"getterValue": {
|
||||
"type": "null"
|
||||
},
|
||||
"getterPrototypeLevel": 1,
|
||||
"enumerable": true,
|
||||
"writable": true
|
||||
},
|
||||
"mozItems": {
|
||||
"getterValue": {
|
||||
"type": "object",
|
||||
"actor": "server2.conn1.child2/obj46",
|
||||
"class": "DOMStringList",
|
||||
"extensible": true,
|
||||
"frozen": false,
|
||||
"sealed": false,
|
||||
"ownPropertyLength": 0,
|
||||
"preview": {
|
||||
"kind": "ArrayLike",
|
||||
"length": 0
|
||||
}
|
||||
},
|
||||
"getterPrototypeLevel": 1,
|
||||
"enumerable": true,
|
||||
"writable": true
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -248,4 +248,5 @@ KeyShortcuts.prototype = {
|
|||
this.eventEmitter.off(key, listener);
|
||||
},
|
||||
};
|
||||
exports.KeyShortcuts = KeyShortcuts;
|
||||
|
||||
module.exports = KeyShortcuts;
|
||||
|
|
|
@ -27,7 +27,7 @@ const CSS_GRID_ENABLED_PREF = "layout.css.grid.enabled";
|
|||
* border radius, cubic-bezier etc.).
|
||||
*
|
||||
* Usage:
|
||||
* const {OutputParser} = require("devtools/client/shared/output-parser");
|
||||
* const OutputParser = require("devtools/client/shared/output-parser");
|
||||
*
|
||||
* let parser = new OutputParser(document, supportsType);
|
||||
*
|
||||
|
@ -52,8 +52,6 @@ function OutputParser(document, {supportsType, isValidOnClient}) {
|
|||
this._onAngleSwatchMouseDown = this._onAngleSwatchMouseDown.bind(this);
|
||||
}
|
||||
|
||||
exports.OutputParser = OutputParser;
|
||||
|
||||
OutputParser.prototype = {
|
||||
/**
|
||||
* Parse a CSS property value given a property name.
|
||||
|
@ -693,3 +691,5 @@ OutputParser.prototype = {
|
|||
return defaults;
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = OutputParser;
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче