Merge m-c to autoland. a=merge

--HG--
rename : accessible/tests/browser/browser_caching_attributes.js => accessible/tests/browser/e10s/browser_caching_attributes.js
rename : accessible/tests/browser/browser_caching_description.js => accessible/tests/browser/e10s/browser_caching_description.js
rename : accessible/tests/browser/browser_caching_name.js => accessible/tests/browser/e10s/browser_caching_name.js
rename : accessible/tests/browser/browser_caching_relations.js => accessible/tests/browser/e10s/browser_caching_relations.js
rename : accessible/tests/browser/browser_caching_states.js => accessible/tests/browser/e10s/browser_caching_states.js
rename : accessible/tests/browser/browser_caching_value.js => accessible/tests/browser/e10s/browser_caching_value.js
rename : accessible/tests/browser/browser_events_caretmove.js => accessible/tests/browser/e10s/browser_events_caretmove.js
rename : accessible/tests/browser/browser_events_hide.js => accessible/tests/browser/e10s/browser_events_hide.js
rename : accessible/tests/browser/browser_events_show.js => accessible/tests/browser/e10s/browser_events_show.js
rename : accessible/tests/browser/browser_events_statechange.js => accessible/tests/browser/e10s/browser_events_statechange.js
rename : accessible/tests/browser/browser_events_textchange.js => accessible/tests/browser/e10s/browser_events_textchange.js
rename : accessible/tests/browser/browser_treeupdate_ariadialog.js => accessible/tests/browser/e10s/browser_treeupdate_ariadialog.js
rename : accessible/tests/browser/browser_treeupdate_ariaowns.js => accessible/tests/browser/e10s/browser_treeupdate_ariaowns.js
rename : accessible/tests/browser/browser_treeupdate_canvas.js => accessible/tests/browser/e10s/browser_treeupdate_canvas.js
rename : accessible/tests/browser/browser_treeupdate_cssoverflow.js => accessible/tests/browser/e10s/browser_treeupdate_cssoverflow.js
rename : accessible/tests/browser/browser_treeupdate_doc.js => accessible/tests/browser/e10s/browser_treeupdate_doc.js
rename : accessible/tests/browser/browser_treeupdate_gencontent.js => accessible/tests/browser/e10s/browser_treeupdate_gencontent.js
rename : accessible/tests/browser/browser_treeupdate_hidden.js => accessible/tests/browser/e10s/browser_treeupdate_hidden.js
rename : accessible/tests/browser/browser_treeupdate_imagemap.js => accessible/tests/browser/e10s/browser_treeupdate_imagemap.js
rename : accessible/tests/browser/browser_treeupdate_list.js => accessible/tests/browser/e10s/browser_treeupdate_list.js
rename : accessible/tests/browser/browser_treeupdate_list_editabledoc.js => accessible/tests/browser/e10s/browser_treeupdate_list_editabledoc.js
rename : accessible/tests/browser/browser_treeupdate_listener.js => accessible/tests/browser/e10s/browser_treeupdate_listener.js
rename : accessible/tests/browser/browser_treeupdate_optgroup.js => accessible/tests/browser/e10s/browser_treeupdate_optgroup.js
rename : accessible/tests/browser/browser_treeupdate_removal.js => accessible/tests/browser/e10s/browser_treeupdate_removal.js
rename : accessible/tests/browser/browser_treeupdate_table.js => accessible/tests/browser/e10s/browser_treeupdate_table.js
rename : accessible/tests/browser/browser_treeupdate_textleaf.js => accessible/tests/browser/e10s/browser_treeupdate_textleaf.js
rename : accessible/tests/browser/browser_treeupdate_visibility.js => accessible/tests/browser/e10s/browser_treeupdate_visibility.js
rename : accessible/tests/browser/browser_treeupdate_whitespace.js => accessible/tests/browser/e10s/browser_treeupdate_whitespace.js
rename : accessible/tests/browser/doc_treeupdate_ariadialog.html => accessible/tests/browser/e10s/doc_treeupdate_ariadialog.html
rename : accessible/tests/browser/doc_treeupdate_ariaowns.html => accessible/tests/browser/e10s/doc_treeupdate_ariaowns.html
rename : accessible/tests/browser/doc_treeupdate_imagemap.html => accessible/tests/browser/e10s/doc_treeupdate_imagemap.html
rename : accessible/tests/browser/doc_treeupdate_removal.xhtml => accessible/tests/browser/e10s/doc_treeupdate_removal.xhtml
rename : accessible/tests/browser/doc_treeupdate_visibility.html => accessible/tests/browser/e10s/doc_treeupdate_visibility.html
rename : accessible/tests/browser/doc_treeupdate_whitespace.html => accessible/tests/browser/e10s/doc_treeupdate_whitespace.html
rename : accessible/tests/browser/events.js => accessible/tests/browser/e10s/events.js
rename : browser/components/extensions/test/browser/browser_ext_pageAction_context.js => browser/components/extensions/test/browser/browser_ext_pageAction_title.js
rename : browser/components/extensions/test/browser/browser_ext_pageAction_context.js => browser/components/extensions/test/browser/head_pageAction.js
rename : dom/events/test/pointerevents/pointerevent_element_haspointercapture.html => dom/events/test/pointerevents/pointerevent_element_haspointercapture-manual.html
rename : dom/events/test/pointerevents/test_pointerevent_element_haspointercapture.html => dom/events/test/pointerevents/test_pointerevent_element_haspointercapture-manual.html
rename : gfx/thebes/DeviceManagerD3D11.cpp => gfx/thebes/DeviceManagerDx.cpp
rename : gfx/thebes/DeviceManagerD3D11.h => gfx/thebes/DeviceManagerDx.h
rename : media/webrtc/trunk/tools/gyp/test/compiler-override/compiler.gyp => media/webrtc/trunk/tools/gyp/test/compiler-override/compiler-exe.gyp
rename : media/webrtc/trunk/tools/gyp/test/mac/app-bundle/TestApp/English.lproj/InfoPlist.strings => media/webrtc/trunk/tools/gyp/test/ios/app-bundle/TestApp/English.lproj/InfoPlist-error.strings
rename : media/webrtc/trunk/tools/gyp/test/mac/app-bundle/TestApp/English.lproj/InfoPlist.strings => media/webrtc/trunk/tools/gyp/test/mac/app-bundle/TestApp/English.lproj/InfoPlist-error.strings
rename : media/webrtc/trunk/tools/gyp/test/mac/gyptest-postbuild-static-library.gyp => media/webrtc/trunk/tools/gyp/test/mac/gyptest-postbuild-static-library.py
rename : media/webrtc/trunk/tools/gyp/test/rules/src/subdir4/asm-function.asm => media/webrtc/trunk/tools/gyp/test/rules/src/subdir4/asm-function.assem
rename : mfbt/unused.h => mfbt/Unused.h
rename : testing/web-platform/tests/pointerevents/pointerevent_element_haspointercapture.html => testing/web-platform/tests/pointerevents/pointerevent_element_haspointercapture-manual.html
extra : rebase_source : a3de7d91a61df9b14fe07a89f5b0184a067549cf
This commit is contained in:
Ryan VanderMeulen 2016-08-25 08:14:36 -04:00
commit e5adfbffe6
1739 changed files with 36479 additions and 15684 deletions

View File

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Bug 1294803's backout needed a clobber to fix SM builds
Bug 1297276 - renaming a file with a different case needed a clobber on case insensitive filesystem

View File

@ -0,0 +1,68 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "AccessibleNode.h"
#include "mozilla/dom/AccessibleNodeBinding.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "Accessible-inl.h"
#include "nsAccessibilityService.h"
#include "DocAccessible.h"
using namespace mozilla;
using namespace mozilla::a11y;
using namespace mozilla::dom;
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(AccessibleNode)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AccessibleNode)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(AccessibleNode)
NS_IMPL_CYCLE_COLLECTING_RELEASE(AccessibleNode)
AccessibleNode::AccessibleNode(nsINode* aNode) : mDOMNode(aNode)
{
DocAccessible* doc =
GetOrCreateAccService()->GetDocAccessible(mDOMNode->OwnerDoc());
if (doc) {
mIntl = doc->GetAccessible(mDOMNode);
}
}
AccessibleNode::~AccessibleNode()
{
}
/* virtual */ JSObject*
AccessibleNode::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return AccessibleNodeBinding::Wrap(aCx, this, aGivenProto);
}
/* virtual */ ParentObject
AccessibleNode::GetParentObject() const
{
return mDOMNode->GetParentObject();
}
void
AccessibleNode::GetRole(nsAString& aRole)
{
if (mIntl) {
GetOrCreateAccService()->GetStringRole(mIntl->Role(), aRole);
return;
}
aRole.AssignLiteral("unknown");
}
nsINode*
AccessibleNode::GetDOMNode()
{
return mDOMNode;
}

View File

@ -0,0 +1,53 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=40: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef A11Y_AOM_ACCESSIBLENODE_H
#define A11Y_AOM_ACCESSIBLENODE_H
#include "nsWrapperCache.h"
#include "mozilla/RefPtr.h"
class nsINode;
namespace mozilla {
namespace a11y {
class Accessible;
}
namespace dom {
struct ParentObject;
class AccessibleNode : public nsISupports,
public nsWrapperCache
{
public:
explicit AccessibleNode(nsINode* aNode);
NS_DECL_CYCLE_COLLECTING_ISUPPORTS;
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(AccessibleNode);
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override final;
virtual dom::ParentObject GetParentObject() const final;
void GetRole(nsAString& aRole);
nsINode* GetDOMNode();
protected:
AccessibleNode(const AccessibleNode& aCopy) = delete;
AccessibleNode& operator=(const AccessibleNode& aCopy) = delete;
virtual ~AccessibleNode();
RefPtr<a11y::Accessible> mIntl;
RefPtr<nsINode> mDOMNode;
};
} // dom
} // mozilla
#endif // A11Y_JSAPI_ACCESSIBLENODE

38
accessible/aom/moz.build Normal file
View File

@ -0,0 +1,38 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXPORTS.mozilla.dom += [
'AccessibleNode.h',
]
UNIFIED_SOURCES += [
'AccessibleNode.cpp',
]
LOCAL_INCLUDES += [
'/accessible/base',
'/accessible/generic',
]
if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
LOCAL_INCLUDES += [
'/accessible/atk',
]
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
LOCAL_INCLUDES += [
'/accessible/windows/ia2',
'/accessible/windows/msaa',
]
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
LOCAL_INCLUDES += [
'/accessible/mac',
]
else:
LOCAL_INCLUDES += [
'/accessible/other',
]
FINAL_LIBRARY = 'xul'

View File

@ -105,16 +105,18 @@ LogDocShellState(nsIDocument* aDocumentNode)
nsCOMPtr<nsIDocShell> docShell = aDocumentNode->GetDocShell();
uint32_t busyFlags = nsIDocShell::BUSY_FLAGS_NONE;
docShell->GetBusyFlags(&busyFlags);
if (busyFlags == nsIDocShell::BUSY_FLAGS_NONE)
if (busyFlags == nsIDocShell::BUSY_FLAGS_NONE) {
printf("'none'");
if (busyFlags & nsIDocShell::BUSY_FLAGS_BUSY)
}
if (busyFlags & nsIDocShell::BUSY_FLAGS_BUSY) {
printf("'busy'");
if (busyFlags & nsIDocShell::BUSY_FLAGS_BEFORE_PAGE_LOAD)
}
if (busyFlags & nsIDocShell::BUSY_FLAGS_BEFORE_PAGE_LOAD) {
printf(", 'before page load'");
if (busyFlags & nsIDocShell::BUSY_FLAGS_PAGE_LOADING)
}
if (busyFlags & nsIDocShell::BUSY_FLAGS_PAGE_LOADING) {
printf(", 'page loading'");
printf("[failed]");
}
}
static void

View File

@ -78,7 +78,7 @@
#include "mozilla/EventStates.h"
#include "mozilla/FloatingPoint.h"
#include "mozilla/MouseEvents.h"
#include "mozilla/unused.h"
#include "mozilla/Unused.h"
#include "mozilla/Preferences.h"
#include "mozilla/dom/CanvasRenderingContext2D.h"
#include "mozilla/dom/Element.h"

View File

@ -13,7 +13,7 @@
#include "mozilla/a11y/Role.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/TabParent.h"
#include "mozilla/unused.h"
#include "mozilla/Unused.h"
#include "RelationType.h"
#include "xpcAccessibleDocument.h"

View File

@ -10,7 +10,7 @@
#include "mozilla/a11y/DocManager.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/TabParent.h"
#include "mozilla/unused.h"
#include "mozilla/Unused.h"
#include "mozilla/a11y/Platform.h"
#include "RelationType.h"
#include "mozilla/a11y/Role.h"

View File

@ -11,7 +11,7 @@
#include "mozilla/a11y/DocManager.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/TabParent.h"
#include "mozilla/unused.h"
#include "mozilla/Unused.h"
#include "mozilla/a11y/Platform.h"
#include "RelationType.h"
#include "mozilla/a11y/Role.h"

View File

@ -15,11 +15,22 @@ elif toolkit == 'cocoa':
else:
DIRS += ['other']
DIRS += ['base', 'generic', 'html', 'interfaces', 'ipc', 'jsat', 'xpcom']
DIRS += [ 'aom',
'base',
'generic',
'html',
'interfaces',
'ipc',
'jsat',
'xpcom'
]
if CONFIG['MOZ_XUL']:
DIRS += ['xul']
TEST_DIRS += ['tests/mochitest']
BROWSER_CHROME_MANIFESTS += ['tests/browser/browser.ini']
BROWSER_CHROME_MANIFESTS += [
'tests/browser/browser.ini',
'tests/browser/e10s/browser.ini'
]

View File

@ -7,6 +7,8 @@
// Content scripts have global 'content' object
"content": true,
"add_task": true,
// Defined in accessible/tests/mochitest/ common.js, name.js, states.js
"prettyName": true,
"statesToString": true,
@ -22,13 +24,21 @@
"isAccessible": true,
"getAccessibleDOMNodeID": true,
// Defined for all accessibility browser tests.
// Defined for all top level accessibility browser tests.
"setE10sPrefs": true,
"unsetE10sPrefs": true,
"initPromise": true,
"shutdownPromise": true,
"forceGC": true,
// Defined for all e10s accessibility browser tests.
"addAccessibleTask": true,
"BrowserTestUtils": true,
"ContentTask": true,
"gBrowser": true,
"isDefunct": true,
"loadScripts": true,
"loadFrameScripts": true,
"Logger": true,
"MOCHITESTS_DIR": true,
"waitForEvent": true,
@ -36,7 +46,7 @@
"invokeSetAttribute": true,
"invokeSetStyle": true,
"invokeFocus": true,
"findAccessibleChildByID": true
"findAccessibleChildByID": true,
},
"rules": {
"mozilla/mark-test-function-used": 1,
@ -68,7 +78,7 @@
"key-spacing": [2, {"beforeColon": false, "afterColon": true}],
"linebreak-style": 0,
"max-depth": 0,
"max-nested-callbacks": [2, 3],
"max-nested-callbacks": [2, 4],
"max-params": 0,
"max-statements": 0,
"new-cap": [2, {"capIsNew": false}],

View File

@ -1,52 +1,9 @@
[DEFAULT]
skip-if = (e10s && os == 'win') # Bug 1269369: Document loaded event does not fire in Windows
support-files =
events.js
head.js
doc_treeupdate_ariadialog.html
doc_treeupdate_ariaowns.html
doc_treeupdate_imagemap.html
doc_treeupdate_removal.xhtml
doc_treeupdate_visibility.html
doc_treeupdate_whitespace.html
!/accessible/tests/mochitest/*.js
!/accessible/tests/mochitest/letters.gif
!/accessible/tests/mochitest/moz.png
shared-head.js
# Caching tests
[browser_caching_attributes.js]
[browser_caching_description.js]
[browser_caching_name.js]
skip-if = e10s
[browser_caching_relations.js]
[browser_caching_states.js]
[browser_caching_value.js]
# Events tests
[browser_events_caretmove.js]
[browser_events_hide.js]
[browser_events_show.js]
[browser_events_statechange.js]
[browser_events_textchange.js]
# Tree update tests
[browser_treeupdate_ariadialog.js]
[browser_treeupdate_ariaowns.js]
skip-if = e10s
[browser_treeupdate_canvas.js]
[browser_treeupdate_cssoverflow.js]
[browser_treeupdate_doc.js]
[browser_treeupdate_gencontent.js]
[browser_treeupdate_hidden.js]
[browser_treeupdate_imagemap.js]
skip-if = e10s
[browser_treeupdate_list.js]
[browser_treeupdate_list_editabledoc.js]
[browser_treeupdate_listener.js]
[browser_treeupdate_optgroup.js]
[browser_treeupdate_removal.js]
[browser_treeupdate_table.js]
[browser_treeupdate_textleaf.js]
[browser_treeupdate_visibility.js]
[browser_treeupdate_whitespace.js]
skip-if = true # Failing due to incorrect index of test container children on document load.
[browser_shutdown_multi_reference.js]
[browser_shutdown_scope_lifecycle.js]
[browser_shutdown_start_restart.js]

View File

@ -0,0 +1,48 @@
/* 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* () {
info('Creating a service');
// Create a11y service.
let a11yInit = initPromise();
let accService1 = Cc['@mozilla.org/accessibilityService;1'].getService(
Ci.nsIAccessibilityService);
yield a11yInit;
ok(accService1, 'Service initialized');
// Add another reference to a11y service. This will not trigger
// 'a11y-init-or-shutdown' event
let accService2 = Cc['@mozilla.org/accessibilityService;1'].getService(
Ci.nsIAccessibilityService);
ok(accService2, 'Service initialized');
info('Removing all service references');
let canShutdown = false;
// This promise will resolve only if canShutdonw flag is set to true. If
// 'a11y-init-or-shutdown' event with '0' flag comes before it can be shut
// down, the promise will reject.
let a11yShutdown = new Promise((resolve, reject) =>
shutdownPromise().then(flag => canShutdown ?
resolve() : reject('Accessible service was shut down incorrectly')));
// Remove first a11y service reference.
accService1 = null;
ok(!accService1, 'Service is removed');
// Force garbage collection that should not trigger shutdown because there is
// another reference.
forceGC();
// Have some breathing room when removing a11y service references.
yield new Promise(resolve => executeSoon(resolve));
// Now allow a11y service to shutdown.
canShutdown = true;
// Remove last a11y service reference.
accService2 = null;
ok(!accService2, 'Service is removed');
// Force garbage collection that should trigger shutdown.
forceGC();
yield a11yShutdown;
});

View File

@ -0,0 +1,21 @@
/* 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* testScopeLifecycle() {
// Create a11y service inside of the function scope. Its reference should be
// released once the anonimous function is called.
let a11yInitThenShutdown = initPromise().then(shutdownPromise);
(function() {
let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
Ci.nsIAccessibilityService);
ok(accService, 'Service initialized');
})();
// Force garbage collection that should trigger shutdown.
forceGC();
yield a11yInitThenShutdown;
});

View File

@ -0,0 +1,41 @@
/* 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* testStartAndRestart() {
info('Creating a service');
// Create a11y service.
let a11yInit = initPromise();
let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
Ci.nsIAccessibilityService);
yield a11yInit;
ok(accService, 'Service initialized');
info('Removing a service');
// Remove the only reference to an a11y service.
let a11yShutdown = shutdownPromise();
accService = null;
ok(!accService, 'Service is removed');
// Force garbage collection that should trigger shutdown.
forceGC();
yield a11yShutdown;
info('Recreating a service');
// Re-create a11y service.
a11yInit = initPromise();
accService = Cc['@mozilla.org/accessibilityService;1'].getService(
Ci.nsIAccessibilityService);
yield a11yInit;
ok(accService, 'Service initialized again');
info('Removing a service again');
// Remove the only reference to an a11y service again.
a11yShutdown = shutdownPromise();
accService = null;
ok(!accService, 'Service is removed again');
// Force garbage collection that should trigger shutdown.
forceGC();
yield a11yShutdown;
});

View File

@ -0,0 +1,53 @@
[DEFAULT]
skip-if = (e10s && os == 'win') # Bug 1269369: Document loaded event does not fire in Windows
support-files =
events.js
head.js
doc_treeupdate_ariadialog.html
doc_treeupdate_ariaowns.html
doc_treeupdate_imagemap.html
doc_treeupdate_removal.xhtml
doc_treeupdate_visibility.html
doc_treeupdate_whitespace.html
!/accessible/tests/browser/shared-head.js
!/accessible/tests/mochitest/*.js
!/accessible/tests/mochitest/letters.gif
!/accessible/tests/mochitest/moz.png
# Caching tests
[browser_caching_attributes.js]
[browser_caching_description.js]
[browser_caching_name.js]
skip-if = e10s
[browser_caching_relations.js]
[browser_caching_states.js]
[browser_caching_value.js]
# Events tests
[browser_events_caretmove.js]
[browser_events_hide.js]
[browser_events_show.js]
[browser_events_statechange.js]
[browser_events_textchange.js]
# Tree update tests
[browser_treeupdate_ariadialog.js]
[browser_treeupdate_ariaowns.js]
skip-if = e10s
[browser_treeupdate_canvas.js]
[browser_treeupdate_cssoverflow.js]
[browser_treeupdate_doc.js]
[browser_treeupdate_gencontent.js]
[browser_treeupdate_hidden.js]
[browser_treeupdate_imagemap.js]
skip-if = e10s
[browser_treeupdate_list.js]
[browser_treeupdate_list_editabledoc.js]
[browser_treeupdate_listener.js]
[browser_treeupdate_optgroup.js]
[browser_treeupdate_removal.js]
[browser_treeupdate_table.js]
[browser_treeupdate_textleaf.js]
[browser_treeupdate_visibility.js]
[browser_treeupdate_whitespace.js]
skip-if = true # Failing due to incorrect index of test container children on document load.

View File

@ -0,0 +1,84 @@
/* 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';
/* global EVENT_DOCUMENT_LOAD_COMPLETE, CURRENT_CONTENT_DIR, loadFrameScripts */
/* exported addAccessibleTask */
// Load the shared-head file first.
Services.scriptloader.loadSubScript(
'chrome://mochitests/content/browser/accessible/tests/browser/shared-head.js',
this);
/**
* A wrapper around browser test add_task that triggers an accessible test task
* as a new browser test task with given document, data URL or markup snippet.
* @param {String} doc URL (relative to current directory) or
* data URL or markup snippet that is used
* to test content with
* @param {Function|Function*} task a generator or a function with tests to
* run
*/
function addAccessibleTask(doc, task) {
add_task(function*() {
let url;
if (doc.includes('doc_')) {
url = `${CURRENT_CONTENT_DIR}e10s/${doc}`;
} else {
// Assume it's a markup snippet.
url = `data:text/html,
<html>
<head>
<meta charset="utf-8"/>
<title>Accessibility Test</title>
</head>
<body id="body">${doc}</body>
</html>`;
}
registerCleanupFunction(() => {
let observers = Services.obs.enumerateObservers('accessible-event');
while (observers.hasMoreElements()) {
Services.obs.removeObserver(
observers.getNext().QueryInterface(Ci.nsIObserver),
'accessible-event');
}
});
let onDocLoad = waitForEvent(EVENT_DOCUMENT_LOAD_COMPLETE, 'body');
yield BrowserTestUtils.withNewTab({
gBrowser,
url: url
}, function*(browser) {
registerCleanupFunction(() => {
if (browser) {
let tab = gBrowser.getTabForBrowser(browser);
if (tab && !tab.closing && tab.linkedBrowser) {
gBrowser.removeTab(tab);
}
}
});
yield SimpleTest.promiseFocus(browser);
loadFrameScripts(browser,
'let { document, window, navigator } = content;',
{ name: 'common.js', dir: MOCHITESTS_DIR });
Logger.log(
`e10s enabled: ${Services.appinfo.browserTabsRemoteAutostart}`);
Logger.log(`Actually remote browser: ${browser.isRemoteBrowser}`);
let event = yield onDocLoad;
yield task(browser, event.accessible);
});
});
}
// Loading and common.js from accessible/tests/mochitest/ for all tests, as
// well as events.js.
loadScripts({ name: 'common.js', dir: MOCHITESTS_DIR }, 'e10s/events.js');

View File

@ -4,300 +4,113 @@
'use strict';
/* global EVENT_DOCUMENT_LOAD_COMPLETE */
/* exported Logger, MOCHITESTS_DIR, isDefunct, addAccessibleTask,
invokeSetAttribute, invokeFocus, invokeSetStyle,
findAccessibleChildByID, getAccessibleDOMNodeID */
const { interfaces: Ci, utils: Cu } = Components;
Cu.import('resource://gre/modules/Services.jsm');
/* exported initPromise, shutdownPromise,
setE10sPrefs, unsetE10sPrefs, forceGC */
/**
* Current browser test directory path used to load subscripts.
* Set e10s related preferences in the test environment.
* @return {Promise} promise that resolves when preferences are set.
*/
const CURRENT_DIR =
'chrome://mochitests/content/browser/accessible/tests/browser/';
/**
* A11y mochitest directory where we find common files used in both browser and
* plain tests.
*/
const MOCHITESTS_DIR =
'chrome://mochitests/content/a11y/accessible/tests/mochitest/';
/**
* A base URL for test files used in content.
*/
const CURRENT_CONTENT_DIR =
'http://example.com/browser/accessible/tests/browser/';
/**
* Used to dump debug information.
*/
let Logger = {
/**
* Set up this variable to dump log messages into console.
*/
dumpToConsole: false,
/**
* Set up this variable to dump log messages into error console.
*/
dumpToAppConsole: false,
/**
* Return true if dump is enabled.
*/
get enabled() {
return this.dumpToConsole || this.dumpToAppConsole;
},
/**
* Dump information into console if applicable.
*/
log(msg) {
if (this.enabled) {
this.logToConsole(msg);
this.logToAppConsole(msg);
}
},
/**
* Log message to console.
*/
logToConsole(msg) {
if (this.dumpToConsole) {
dump(`\n${msg}\n`);
}
},
/**
* Log message to error console.
*/
logToAppConsole(msg) {
if (this.dumpToAppConsole) {
Services.console.logStringMessage(`${msg}`);
}
}
};
/**
* Check if an accessible object has a defunct test.
* @param {nsIAccessible} accessible object to test defunct state for
* @return {Boolean} flag indicating defunct state
*/
function isDefunct(accessible) {
let defunct = false;
try {
let extState = {};
accessible.getState({}, extState);
defunct = extState.value & Ci.nsIAccessibleStates.EXT_STATE_DEFUNCT;
} catch (x) {
defunct = true;
} finally {
if (defunct) {
Logger.log(`Defunct accessible: ${prettyName(accessible)}`);
}
}
return defunct;
function setE10sPrefs() {
return new Promise(resolve =>
SpecialPowers.pushPrefEnv({
set: [
['browser.tabs.remote.autostart', true],
['browser.tabs.remote.force-enable', true],
['extensions.e10sBlocksEnabling', false]
]
}, resolve));
}
/**
* Asynchronously set or remove content element's attribute (in content process
* if e10s is enabled).
* @param {Object} browser current "tabbrowser" element
* @param {String} id content element id
* @param {String} attr attribute name
* @param {String?} value optional attribute value, if not present, remove
* attribute
* @return {Promise} promise indicating that attribute is set/removed
* Unset e10s related preferences in the test environment.
* @return {Promise} promise that resolves when preferences are unset.
*/
function invokeSetAttribute(browser, id, attr, value) {
if (value) {
Logger.log(`Setting ${attr} attribute to ${value} for node with id: ${id}`);
} else {
Logger.log(`Removing ${attr} attribute from node with id: ${id}`);
}
return ContentTask.spawn(browser, { id, attr, value },
({ id, attr, value }) => {
let elm = content.document.getElementById(id);
if (value) {
elm.setAttribute(attr, value);
} else {
elm.removeAttribute(attr);
}
});
function unsetE10sPrefs() {
return new Promise(resolve => {
SpecialPowers.popPrefEnv(resolve);
});
}
/**
* Asynchronously set or remove content element's style (in content process if
* e10s is enabled).
* @param {Object} browser current "tabbrowser" element
* @param {String} id content element id
* @param {String} aStyle style property name
* @param {String?} aValue optional style property value, if not present,
* remove style
* @return {Promise} promise indicating that style is set/removed
*/
function invokeSetStyle(browser, id, style, value) {
if (value) {
Logger.log(`Setting ${style} style to ${value} for node with id: ${id}`);
} else {
Logger.log(`Removing ${style} style from node with id: ${id}`);
}
return ContentTask.spawn(browser, { id, style, value },
({ id, style, value }) => {
let elm = content.document.getElementById(id);
if (value) {
elm.style[style] = value;
} else {
delete elm.style[style];
}
});
}
// Load the shared-head file first.
Services.scriptloader.loadSubScript(
'chrome://mochitests/content/browser/accessible/tests/browser/shared-head.js',
this);
/**
* Asynchronously set focus on a content element (in content process if e10s is
* enabled).
* @param {Object} browser current "tabbrowser" element
* @param {String} id content element id
* @return {Promise} promise indicating that focus is set
* Returns a promise that resolves when 'a11y-init-or-shutdown' event is fired.
* @return {Promise} event promise evaluating to event's data
*/
function invokeFocus(browser, id) {
Logger.log(`Setting focus on a node with id: ${id}`);
return ContentTask.spawn(browser, id, id => {
let elm = content.document.getElementById(id);
if (elm instanceof Ci.nsIDOMNSEditableElement && elm.editor ||
elm instanceof Ci.nsIDOMXULTextBoxElement) {
elm.selectionStart = elm.selectionEnd = elm.value.length;
}
elm.focus();
function a11yInitOrShutdownPromise() {
return new Promise(resolve => {
let observe = (subject, topic, data) => {
Services.obs.removeObserver(observe, 'a11y-init-or-shutdown');
resolve(data);
};
Services.obs.addObserver(observe, 'a11y-init-or-shutdown', false);
});
}
/**
* Traverses the accessible tree starting from a given accessible as a root and
* looks for an accessible that matches based on its DOMNode id.
* @param {nsIAccessible} accessible root accessible
* @param {String} id id to look up accessible for
* @return {nsIAccessible?} found accessible if any
* Returns a promise that resolves when 'a11y-init-or-shutdown' event is fired
* in content.
* @param {Object} browser current "tabbrowser" element
* @return {Promise} event promise evaluating to event's data
*/
function findAccessibleChildByID(accessible, id) {
if (getAccessibleDOMNodeID(accessible) === id) {
return accessible;
}
for (let i = 0; i < accessible.children.length; ++i) {
let found = findAccessibleChildByID(accessible.getChildAt(i), id);
if (found) {
return found;
}
}
function contentA11yInitOrShutdownPromise(browser) {
return ContentTask.spawn(browser, {}, a11yInitOrShutdownPromise);
}
/**
* Load a list of scripts into the test
* @param {Array} scripts a list of scripts to load
* A helper function that maps 'a11y-init-or-shutdown' event to a promise that
* resovles or rejects depending on whether accessibility service is expected to
* be initialized or shut down.
*/
function loadScripts(...scripts) {
for (let script of scripts) {
let path = typeof script === 'string' ? `${CURRENT_DIR}${script}` :
`${script.dir}${script.name}`;
Services.scriptloader.loadSubScript(path, this);
}
function promiseOK(promise, expected) {
return promise.then(flag =>
flag === expected ? Promise.resolve() : Promise.reject());
}
/**
* Load a list of frame scripts into test's content.
* @param {Object} browser browser element that content belongs to
* @param {Array} scripts a list of scripts to load into content
* Checks and returns a promise that resolves when accessibility service is
* initialized with the correct flag.
* @param {?Object} contentBrowser optinal remove browser object that indicates
* that accessibility service is expected to be
* initialized in content process.
* @return {Promise} promise that resolves when the accessibility
* service initialized correctly.
*/
function loadFrameScripts(browser, ...scripts) {
let mm = browser.messageManager;
for (let script of scripts) {
let frameScript;
if (typeof script === 'string') {
if (script.includes('.js')) {
// If script string includes a .js extention, assume it is a script
// path.
frameScript = `${CURRENT_DIR}${script}`;
} else {
// Otherwise it is a serealized script.
frameScript = `data:,${script}`;
}
} else {
// Script is a object that has { dir, name } format.
frameScript = `${script.dir}${script.name}`;
}
mm.loadFrameScript(frameScript, false, true);
}
function initPromise(contentBrowser) {
let a11yInitPromise = contentBrowser ?
contentA11yInitOrShutdownPromise(contentBrowser) :
a11yInitOrShutdownPromise();
return promiseOK(a11yInitPromise, '1').then(
() => ok(true, 'Service initialized correctly'),
() => ok(false, 'Service shutdown incorrectly'));
}
/**
* A wrapper around browser test add_task that triggers an accessible test task
* as a new browser test task with given document, data URL or markup snippet.
* @param {String} doc URL (relative to current directory) or
* data URL or markup snippet that is used
* to test content with
* @param {Function|Function*} task a generator or a function with tests to
* run
* Checks and returns a promise that resolves when accessibility service is
* shut down with the correct flag.
* @param {?Object} contentBrowser optinal remove browser object that indicates
* that accessibility service is expected to be
* shut down in content process.
* @return {Promise} promise that resolves when the accessibility
* service shuts down correctly.
*/
function addAccessibleTask(doc, task) {
add_task(function*() {
let url;
if (doc.includes('doc_')) {
url = `${CURRENT_CONTENT_DIR}${doc}`;
} else {
// Assume it's a markup snippet.
url = `data:text/html,
<html>
<head>
<meta charset="utf-8"/>
<title>Accessibility Test</title>
</head>
<body id="body">${doc}</body>
</html>`;
}
registerCleanupFunction(() => {
let observers = Services.obs.enumerateObservers('accessible-event');
while (observers.hasMoreElements()) {
Services.obs.removeObserver(
observers.getNext().QueryInterface(Ci.nsIObserver),
'accessible-event');
}
});
let onDocLoad = waitForEvent(EVENT_DOCUMENT_LOAD_COMPLETE, 'body');
yield BrowserTestUtils.withNewTab({
gBrowser,
url: url
}, function*(browser) {
registerCleanupFunction(() => {
if (browser) {
let tab = gBrowser.getTabForBrowser(browser);
if (tab && !tab.closing && tab.linkedBrowser) {
gBrowser.removeTab(tab);
}
}
});
yield SimpleTest.promiseFocus(browser);
loadFrameScripts(browser,
'let { document, window, navigator } = content;',
{ name: 'common.js', dir: MOCHITESTS_DIR });
Logger.log(
`e10s enabled: ${Services.appinfo.browserTabsRemoteAutostart}`);
Logger.log(`Actually remote browser: ${browser.isRemoteBrowser}`);
let event = yield onDocLoad;
yield task(browser, event.accessible);
});
});
function shutdownPromise(contentBrowser) {
let a11yShutdownPromise = contentBrowser ?
contentA11yInitOrShutdownPromise(contentBrowser) :
a11yInitOrShutdownPromise();
return promiseOK(a11yShutdownPromise, '0').then(
() => ok(true, 'Service shutdown correctly'),
() => ok(false, 'Service initialized incorrectly'));
}
// Loading and common.js from accessible/tests/mochitest/ for all tests, as well
// as events.js.
loadScripts({ name: 'common.js', dir: MOCHITESTS_DIR }, 'events.js');
/**
* Force garbage collection.
*/
function forceGC() {
Cu.forceCC();
Cu.forceGC();
}

View File

@ -0,0 +1,229 @@
/* 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';
/* exported Logger, MOCHITESTS_DIR, isDefunct, invokeSetAttribute, invokeFocus,
invokeSetStyle, findAccessibleChildByID, getAccessibleDOMNodeID,
CURRENT_CONTENT_DIR, loadScripts, loadFrameScripts, Cc, Cu */
const { interfaces: Ci, utils: Cu, classes: Cc } = Components;
/**
* Current browser test directory path used to load subscripts.
*/
const CURRENT_DIR =
'chrome://mochitests/content/browser/accessible/tests/browser/';
/**
* A11y mochitest directory where we find common files used in both browser and
* plain tests.
*/
const MOCHITESTS_DIR =
'chrome://mochitests/content/a11y/accessible/tests/mochitest/';
/**
* A base URL for test files used in content.
*/
const CURRENT_CONTENT_DIR =
'http://example.com/browser/accessible/tests/browser/';
/**
* Used to dump debug information.
*/
let Logger = {
/**
* Set up this variable to dump log messages into console.
*/
dumpToConsole: false,
/**
* Set up this variable to dump log messages into error console.
*/
dumpToAppConsole: false,
/**
* Return true if dump is enabled.
*/
get enabled() {
return this.dumpToConsole || this.dumpToAppConsole;
},
/**
* Dump information into console if applicable.
*/
log(msg) {
if (this.enabled) {
this.logToConsole(msg);
this.logToAppConsole(msg);
}
},
/**
* Log message to console.
*/
logToConsole(msg) {
if (this.dumpToConsole) {
dump(`\n${msg}\n`);
}
},
/**
* Log message to error console.
*/
logToAppConsole(msg) {
if (this.dumpToAppConsole) {
Services.console.logStringMessage(`${msg}`);
}
}
};
/**
* Check if an accessible object has a defunct test.
* @param {nsIAccessible} accessible object to test defunct state for
* @return {Boolean} flag indicating defunct state
*/
function isDefunct(accessible) {
let defunct = false;
try {
let extState = {};
accessible.getState({}, extState);
defunct = extState.value & Ci.nsIAccessibleStates.EXT_STATE_DEFUNCT;
} catch (x) {
defunct = true;
} finally {
if (defunct) {
Logger.log(`Defunct accessible: ${prettyName(accessible)}`);
}
}
return defunct;
}
/**
* Asynchronously set or remove content element's attribute (in content process
* if e10s is enabled).
* @param {Object} browser current "tabbrowser" element
* @param {String} id content element id
* @param {String} attr attribute name
* @param {String?} value optional attribute value, if not present, remove
* attribute
* @return {Promise} promise indicating that attribute is set/removed
*/
function invokeSetAttribute(browser, id, attr, value) {
if (value) {
Logger.log(`Setting ${attr} attribute to ${value} for node with id: ${id}`);
} else {
Logger.log(`Removing ${attr} attribute from node with id: ${id}`);
}
return ContentTask.spawn(browser, { id, attr, value },
({ id, attr, value }) => {
let elm = content.document.getElementById(id);
if (value) {
elm.setAttribute(attr, value);
} else {
elm.removeAttribute(attr);
}
});
}
/**
* Asynchronously set or remove content element's style (in content process if
* e10s is enabled).
* @param {Object} browser current "tabbrowser" element
* @param {String} id content element id
* @param {String} aStyle style property name
* @param {String?} aValue optional style property value, if not present,
* remove style
* @return {Promise} promise indicating that style is set/removed
*/
function invokeSetStyle(browser, id, style, value) {
if (value) {
Logger.log(`Setting ${style} style to ${value} for node with id: ${id}`);
} else {
Logger.log(`Removing ${style} style from node with id: ${id}`);
}
return ContentTask.spawn(browser, { id, style, value },
({ id, style, value }) => {
let elm = content.document.getElementById(id);
if (value) {
elm.style[style] = value;
} else {
delete elm.style[style];
}
});
}
/**
* Asynchronously set focus on a content element (in content process if e10s is
* enabled).
* @param {Object} browser current "tabbrowser" element
* @param {String} id content element id
* @return {Promise} promise indicating that focus is set
*/
function invokeFocus(browser, id) {
Logger.log(`Setting focus on a node with id: ${id}`);
return ContentTask.spawn(browser, id, id => {
let elm = content.document.getElementById(id);
if (elm instanceof Ci.nsIDOMNSEditableElement && elm.editor ||
elm instanceof Ci.nsIDOMXULTextBoxElement) {
elm.selectionStart = elm.selectionEnd = elm.value.length;
}
elm.focus();
});
}
/**
* Traverses the accessible tree starting from a given accessible as a root and
* looks for an accessible that matches based on its DOMNode id.
* @param {nsIAccessible} accessible root accessible
* @param {String} id id to look up accessible for
* @return {nsIAccessible?} found accessible if any
*/
function findAccessibleChildByID(accessible, id) {
if (getAccessibleDOMNodeID(accessible) === id) {
return accessible;
}
for (let i = 0; i < accessible.children.length; ++i) {
let found = findAccessibleChildByID(accessible.getChildAt(i), id);
if (found) {
return found;
}
}
}
/**
* Load a list of scripts into the test
* @param {Array} scripts a list of scripts to load
*/
function loadScripts(...scripts) {
for (let script of scripts) {
let path = typeof script === 'string' ? `${CURRENT_DIR}${script}` :
`${script.dir}${script.name}`;
Services.scriptloader.loadSubScript(path, this);
}
}
/**
* Load a list of frame scripts into test's content.
* @param {Object} browser browser element that content belongs to
* @param {Array} scripts a list of scripts to load into content
*/
function loadFrameScripts(browser, ...scripts) {
let mm = browser.messageManager;
for (let script of scripts) {
let frameScript;
if (typeof script === 'string') {
if (script.includes('.js')) {
// If script string includes a .js extention, assume it is a script
// path.
frameScript = `${CURRENT_DIR}${script}`;
} else {
// Otherwise it is a serealized script.
frameScript = `data:,${script}`;
}
} else {
// Script is a object that has { dir, name } format.
frameScript = `${script.dir}${script.name}`;
}
mm.loadFrameScript(frameScript, false, true);
}
}

View File

@ -0,0 +1,3 @@
[DEFAULT]
[test_general.html]

View File

@ -0,0 +1,55 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Accessibility API: generic</title>
<link rel="stylesheet" type="text/css"
href="chrome://mochikit/content/tests/SimpleTest/test.css">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script>
'use strict';
SimpleTest.waitForExplicitFinish();
const finish = SimpleTest.finish.bind(SimpleTest);
enablePref()
.then(createIframe)
.then(checkImplementation)
.catch(err => {
dump(`${err}: ${err.stack}`);
finish();
});
function enablePref() {
const ops = {
"set": [
[ "accessibility.AOM.enabled", true ],
],
};
return SpecialPowers.pushPrefEnv(ops);
}
// WebIDL conditional annotations for an interface are evaluated once per
// global, so we need to create an iframe to see the effects of calling
// enablePref().
function createIframe() {
return new Promise((resolve) => {
let iframe = document.createElement("iframe");
iframe.src = "about:blank";
iframe.onload = () => resolve(iframe.contentDocument);
document.body.appendChild(iframe);
});
}
// Check that the WebIDL is as expected.
function checkImplementation(ifrDoc) {
let anode = ifrDoc.accessibleNode;
ok(anode, "DOM document has accessible node");
is(anode.role, 'document', 'correct role of a document accessible node');
is(anode.DOMNode, ifrDoc, 'correct DOM Node of a document accessible node');
finish();
}
</script>
</head>

View File

@ -7,6 +7,7 @@
A11Y_MANIFESTS += [
'a11y.ini',
'actions/a11y.ini',
'aom/a11y.ini',
'attributes/a11y.ini',
'bounds/a11y.ini',
'editabletext/a11y.ini',

View File

@ -618,7 +618,6 @@ pref("javascript.options.mem.gc_high_frequency_low_limit_mb", 0);
pref("javascript.options.mem.gc_low_frequency_heap_growth", 120);
pref("javascript.options.mem.high_water_mark", 6);
pref("javascript.options.mem.gc_allocation_threshold_mb", 1);
pref("javascript.options.mem.gc_decommit_threshold_mb", 1);
pref("javascript.options.mem.gc_min_empty_chunk_count", 1);
pref("javascript.options.mem.gc_max_empty_chunk_count", 2);

View File

@ -762,6 +762,7 @@ html|*#fullscreen-exit-button {
-moz-user-focus: normal;
}
.blocked-permission-icon:not([showing]),
.notification-anchor-icon:not([showing]) {
display: none;
}

View File

@ -692,19 +692,19 @@
onclick="PageProxyClickHandler(event);"/>
<image id="sharing-icon" mousethrough="always"/>
<box id="blocked-permissions-container" align="center" tooltiptext="">
<image data-permission-id="geo" class="notification-anchor-icon geo-icon blocked" role="button"
<image data-permission-id="geo" class="blocked-permission-icon geo-icon" role="button"
aria-label="&urlbar.geolocationNotificationAnchor.label;"/>
<image data-permission-id="desktop-notification" class="notification-anchor-icon desktop-notification-icon blocked" role="button"
<image data-permission-id="desktop-notification" class="blocked-permission-icon desktop-notification-icon" role="button"
aria-label="&urlbar.webNotsNotificationAnchor3.label;"/>
<image data-permission-id="camera" class="notification-anchor-icon camera-icon blocked" role="button"
<image data-permission-id="camera" class="blocked-permission-icon camera-icon" role="button"
aria-label="&urlbar.webRTCShareDevicesNotificationAnchor.label;"/>
<image data-permission-id="indexedDB" class="notification-anchor-icon indexedDB-icon blocked" role="button"
<image data-permission-id="indexedDB" class="blocked-permission-icon indexedDB-icon" role="button"
aria-label="&urlbar.indexedDBNotificationAnchor.label;"/>
<image data-permission-id="microphone" class="notification-anchor-icon microphone-icon blocked" role="button"
<image data-permission-id="microphone" class="blocked-permission-icon microphone-icon" role="button"
aria-label="&urlbar.webRTCShareMicrophoneNotificationAnchor.label;"/>
<image data-permission-id="screen" class="notification-anchor-icon screen-icon blocked" role="button"
<image data-permission-id="screen" class="blocked-permission-icon screen-icon" role="button"
aria-label="&urlbar.webRTCShareScreenNotificationAnchor.label;"/>
<image data-permission-id="pointerLock" class="notification-anchor-icon pointerLock-icon blocked" role="button"
<image data-permission-id="pointerLock" class="blocked-permission-icon pointerLock-icon" role="button"
aria-label="&urlbar.pointerLockNotificationAnchor.label;"/>
</box>
<box id="notification-popup-box"

View File

@ -19,7 +19,7 @@
}
.tab-close-button[pinned],
.tabbrowser-tabs[closebuttons="activetab"] > * > * > * > .tab-close-button:not([visuallyselected="true"]),
.tabbrowser-tabs[closebuttons="activetab"] > * > * > * > .tab-close-button:not([selected="true"]),
.tab-icon-image:not([src]):not([pinned]):not([crashed])[selected],
.tab-icon-image:not([src]):not([pinned]):not([crashed]):not([sharing]),
.tab-icon-image[busy],

View File

@ -6245,44 +6245,44 @@
<content context="tabContextMenu">
<xul:stack class="tab-stack" flex="1">
<xul:hbox xbl:inherits="pinned,selected,visuallyselected,fadein"
<xul:hbox xbl:inherits="pinned,selected=visuallyselected,fadein"
class="tab-background">
<xul:hbox xbl:inherits="pinned,selected,visuallyselected"
<xul:hbox xbl:inherits="pinned,selected=visuallyselected"
class="tab-background-start"/>
<xul:hbox xbl:inherits="pinned,selected,visuallyselected"
<xul:hbox xbl:inherits="pinned,selected=visuallyselected"
class="tab-background-middle"/>
<xul:hbox xbl:inherits="pinned,selected,visuallyselected"
<xul:hbox xbl:inherits="pinned,selected=visuallyselected"
class="tab-background-end"/>
</xul:hbox>
<xul:hbox xbl:inherits="pinned,selected,visuallyselected,titlechanged,attention"
<xul:hbox xbl:inherits="pinned,selected=visuallyselected,titlechanged,attention"
class="tab-content" align="center">
<xul:image xbl:inherits="fadein,pinned,busy,progress,selected,visuallyselected"
<xul:image xbl:inherits="fadein,pinned,busy,progress,selected=visuallyselected"
class="tab-throbber"
role="presentation"
layer="true" />
<xul:image xbl:inherits="src=image,fadein,pinned,selected,visuallyselected,busy,crashed,sharing"
<xul:image xbl:inherits="src=image,fadein,pinned,selected=visuallyselected,busy,crashed,sharing"
anonid="tab-icon-image"
class="tab-icon-image"
validate="never"
role="presentation"/>
<xul:image xbl:inherits="sharing,selected"
<xul:image xbl:inherits="sharing,selected=visuallyselected"
anonid="sharing-icon"
class="tab-sharing-icon-overlay"
role="presentation"/>
<xul:image xbl:inherits="crashed,busy,soundplaying,pinned,muted,visuallyselected"
<xul:image xbl:inherits="crashed,busy,soundplaying,pinned,muted,selected=visuallyselected"
anonid="overlay-icon"
class="tab-icon-overlay"
role="presentation"/>
<xul:label flex="1"
xbl:inherits="value=label,crop,accesskey,fadein,pinned,selected,visuallyselected,attention"
xbl:inherits="value=label,crop,accesskey,fadein,pinned,selected=visuallyselected,attention"
class="tab-text tab-label"
role="presentation"/>
<xul:image xbl:inherits="soundplaying,pinned,muted,visuallyselected"
<xul:image xbl:inherits="soundplaying,pinned,muted,selected=visuallyselected"
anonid="soundplaying-icon"
class="tab-icon-sound"
role="presentation"/>
<xul:toolbarbutton anonid="close-button"
xbl:inherits="fadein,pinned,selected,visuallyselected"
xbl:inherits="fadein,pinned,selected=visuallyselected"
class="tab-close-button close-icon"/>
</xul:hbox>
</xul:stack>

View File

@ -186,8 +186,6 @@ add_task(function* testPermissionIcons() {
let geoIcon = gIdentityHandler._identityBox.querySelector("[data-permission-id='geo']");
ok(geoIcon.hasAttribute("showing"), "blocked permission icon is shown");
ok(geoIcon.classList.contains("blocked"),
"blocked permission icon is shown as blocked");
let cameraIcon = gIdentityHandler._identityBox.querySelector("[data-permission-id='camera']");
ok(!cameraIcon.hasAttribute("showing"),

View File

@ -42,7 +42,7 @@ var gTests = [
// After selecting a new tab, check the attribute is still there,
// and the icon is now visible.
gBrowser.selectedTab = gBrowser.addTab();
yield BrowserTestUtils.switchTab(gBrowser, gBrowser.addTab());
is(gBrowser.selectedTab.getAttribute("sharing"), "",
"the new tab doesn't have the 'sharing' attribute");
is(tab.getAttribute("sharing"), aSharing,
@ -51,7 +51,7 @@ var gTests = [
"the animated sharing icon of the tab is now visible");
// Ensure the icon disappears when selecting the tab.
gBrowser.removeCurrentTab();
yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
ok(tab.selected, "the tab with ongoing sharing is selected again");
is(window.getComputedStyle(icon).display, "none",
"the animated sharing icon is gone after selecting the tab again");

View File

@ -25,3 +25,4 @@ tags = openwindow
[browser_blobUrl.js]
[browser_middleClick.js]
[browser_imageCache.js]
[browser_count_and_remove.js]

View File

@ -0,0 +1,34 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/ContextualIdentityService.jsm");
function openTabInUserContext(userContextId) {
let tab = gBrowser.addTab("about:blank", {userContextId});
gBrowser.selectedTab = tab;
}
add_task(function* setup() {
// make sure userContext is enabled.
yield SpecialPowers.pushPrefEnv({"set": [
["privacy.userContext.enabled", true]
]});
});
add_task(function* test() {
is(ContextualIdentityService.countContainerTabs(), 0, "0 container tabs by default.");
openTabInUserContext(1);
is(ContextualIdentityService.countContainerTabs(), 1, "1 container tab created");
openTabInUserContext(1);
is(ContextualIdentityService.countContainerTabs(), 2, "2 container tab created");
openTabInUserContext(2);
is(ContextualIdentityService.countContainerTabs(), 3, "3 container tab created");
ContextualIdentityService.closeAllContainerTabs();
is(ContextualIdentityService.countContainerTabs(), 0, "0 container tab at the end.");
});

View File

@ -1,6 +1,7 @@
[DEFAULT]
support-files =
head.js
head_pageAction.js
context.html
ctxmenu-image.png
context_tabs_onUpdated_page.html
@ -44,6 +45,7 @@ tags = webextensions
[browser_ext_pageAction_popup.js]
[browser_ext_pageAction_popup_resize.js]
[browser_ext_pageAction_simple.js]
[browser_ext_pageAction_title.js]
[browser_ext_popup_api_injection.js]
[browser_ext_popup_background.js]
[browser_ext_popup_corners.js]

View File

@ -2,160 +2,10 @@
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
function* runTests(options) {
function background(getTests) {
let tabs;
let tests;
/* global runTests */
// Gets the current details of the page action, and returns a
// promise that resolves to an object containing them.
function getDetails() {
return new Promise(resolve => {
return browser.tabs.query({active: true, currentWindow: true}, resolve);
}).then(([tab]) => {
let tabId = tab.id;
browser.test.log(`Get details: tab={id: ${tabId}, url: ${JSON.stringify(tab.url)}}`);
return Promise.all([
browser.pageAction.getTitle({tabId}),
browser.pageAction.getPopup({tabId})]);
}).then(details => {
return Promise.resolve({title: details[0],
popup: details[1]});
});
}
// Runs the next test in the `tests` array, checks the results,
// and passes control back to the outer test scope.
function nextTest() {
let test = tests.shift();
test(expecting => {
function finish() {
// Check that the actual icon has the expected values, then
// run the next test.
browser.test.sendMessage("nextTest", expecting, tests.length);
}
if (expecting) {
// Check that the API returns the expected values, and then
// run the next test.
getDetails().then(details => {
browser.test.assertEq(expecting.title, details.title,
"expected value from getTitle");
browser.test.assertEq(expecting.popup, details.popup,
"expected value from getPopup");
finish();
});
} else {
finish();
}
});
}
function runTests() {
tabs = [];
tests = getTests(tabs);
browser.tabs.query({active: true, currentWindow: true}, resultTabs => {
tabs[0] = resultTabs[0].id;
nextTest();
});
}
browser.test.onMessage.addListener((msg) => {
if (msg == "runTests") {
runTests();
} else if (msg == "runNextTest") {
nextTest();
} else {
browser.test.fail(`Unexpected message: ${msg}`);
}
});
runTests();
}
let extension = ExtensionTestUtils.loadExtension({
manifest: options.manifest,
files: options.files || {},
background: `(${background})(${options.getTests})`,
});
let pageActionId;
let currentWindow = window;
let windows = [];
function checkDetails(details) {
let image = currentWindow.document.getElementById(pageActionId);
if (details == null) {
ok(image == null || image.hidden, "image is hidden");
} else {
ok(image, "image exists");
is(getListStyleImage(image), details.icon, "icon URL is correct");
let title = details.title || options.manifest.name;
is(image.getAttribute("tooltiptext"), title, "image title is correct");
is(image.getAttribute("aria-label"), title, "image aria-label is correct");
// TODO: Popup URL.
}
}
let testNewWindows = 1;
let awaitFinish = new Promise(resolve => {
extension.onMessage("nextTest", (expecting, testsRemaining) => {
if (!pageActionId) {
pageActionId = `${makeWidgetId(extension.id)}-page-action`;
}
checkDetails(expecting);
if (testsRemaining) {
extension.sendMessage("runNextTest");
} else if (testNewWindows) {
testNewWindows--;
BrowserTestUtils.openNewBrowserWindow().then(window => {
windows.push(window);
currentWindow = window;
return focusWindow(window);
}).then(() => {
extension.sendMessage("runTests");
});
} else {
resolve();
}
});
});
yield SpecialPowers.pushPrefEnv({set: [["general.useragent.locale", "es-ES"]]});
yield extension.startup();
yield awaitFinish;
yield extension.unload();
yield SpecialPowers.popPrefEnv();
let node = document.getElementById(pageActionId);
is(node, null, "pageAction image removed from document");
currentWindow = null;
for (let win of windows.splice(0)) {
node = win.document.getElementById(pageActionId);
is(node, null, "pageAction image removed from second document");
yield BrowserTestUtils.closeWindow(win);
}
}
Services.scriptloader.loadSubScript(new URL("head_pageAction.js", gTestPath).href,
this);
add_task(function* testTabSwitchContext() {
yield runTests({
@ -329,55 +179,3 @@ add_task(function* testTabSwitchContext() {
},
});
});
add_task(function* testDefaultTitle() {
yield runTests({
manifest: {
"name": "Foo Extension",
"page_action": {
"default_icon": "icon.png",
},
"permissions": ["tabs"],
},
files: {
"icon.png": imageBuffer,
},
getTests(tabs) {
let details = [
{"title": "Foo Extension",
"popup": "",
"icon": browser.runtime.getURL("icon.png")},
{"title": "Foo Title",
"popup": "",
"icon": browser.runtime.getURL("icon.png")},
];
return [
expect => {
browser.test.log("Initial state. No icon visible.");
expect(null);
},
expect => {
browser.test.log("Show the icon on the first tab, expect extension title as default title.");
browser.pageAction.show(tabs[0]).then(() => {
expect(details[0]);
});
},
expect => {
browser.test.log("Change the title. Expect new title.");
browser.pageAction.setTitle({tabId: tabs[0], title: "Foo Title"});
expect(details[1]);
},
expect => {
browser.test.log("Clear the title. Expect extension title.");
browser.pageAction.setTitle({tabId: tabs[0], title: ""});
expect(details[0]);
},
];
},
});
});

View File

@ -0,0 +1,233 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
/* global runTests */
Services.scriptloader.loadSubScript(new URL("head_pageAction.js", gTestPath).href,
this);
add_task(function* testTabSwitchContext() {
yield runTests({
manifest: {
"name": "Foo Extension",
"page_action": {
"default_icon": "default.png",
"default_popup": "__MSG_popup__",
"default_title": "Default __MSG_title__ \u263a",
},
"default_locale": "en",
"permissions": ["tabs"],
},
"files": {
"_locales/en/messages.json": {
"popup": {
"message": "default.html",
"description": "Popup",
},
"title": {
"message": "Title",
"description": "Title",
},
},
"_locales/es_ES/messages.json": {
"popup": {
"message": "default.html",
"description": "Popup",
},
"title": {
"message": "T\u00edtulo",
"description": "Title",
},
},
"default.png": imageBuffer,
"1.png": imageBuffer,
"2.png": imageBuffer,
},
getTests(tabs) {
let details = [
{"icon": browser.runtime.getURL("default.png"),
"popup": browser.runtime.getURL("default.html"),
"title": "Default T\u00edtulo \u263a"},
{"icon": browser.runtime.getURL("1.png"),
"popup": browser.runtime.getURL("default.html"),
"title": "Default T\u00edtulo \u263a"},
{"icon": browser.runtime.getURL("2.png"),
"popup": browser.runtime.getURL("2.html"),
"title": "Title 2"},
{"icon": browser.runtime.getURL("2.png"),
"popup": browser.runtime.getURL("2.html"),
"title": "Default T\u00edtulo \u263a"},
];
let promiseTabLoad = details => {
return new Promise(resolve => {
browser.tabs.onUpdated.addListener(function listener(tabId, changed) {
if (tabId == details.id && changed.url == details.url) {
browser.tabs.onUpdated.removeListener(listener);
resolve();
}
});
});
};
return [
expect => {
browser.test.log("Initial state. No icon visible.");
expect(null);
},
expect => {
browser.test.log("Show the icon on the first tab, expect default properties.");
browser.pageAction.show(tabs[0]).then(() => {
expect(details[0]);
});
},
expect => {
browser.test.log("Change the icon. Expect default properties excluding the icon.");
browser.pageAction.setIcon({tabId: tabs[0], path: "1.png"});
expect(details[1]);
},
expect => {
browser.test.log("Create a new tab. No icon visible.");
browser.tabs.create({active: true, url: "about:blank?0"}, tab => {
tabs.push(tab.id);
expect(null);
});
},
expect => {
browser.test.log("Await tab load. No icon visible.");
expect(null);
},
expect => {
browser.test.log("Change properties. Expect new properties.");
let tabId = tabs[1];
browser.pageAction.show(tabId).then(() => {
browser.pageAction.setIcon({tabId, path: "2.png"});
browser.pageAction.setPopup({tabId, popup: "2.html"});
browser.pageAction.setTitle({tabId, title: "Title 2"});
expect(details[2]);
});
},
expect => {
browser.test.log("Change the hash. Expect same properties.");
promiseTabLoad({id: tabs[1], url: "about:blank?0#ref"}).then(() => {
expect(details[2]);
});
browser.tabs.update(tabs[1], {url: "about:blank?0#ref"});
},
expect => {
browser.test.log("Clear the title. Expect default title.");
browser.pageAction.setTitle({tabId: tabs[1], title: ""});
expect(details[3]);
},
expect => {
browser.test.log("Navigate to a new page. Expect icon hidden.");
// TODO: This listener should not be necessary, but the |tabs.update|
// callback currently fires too early in e10s windows.
promiseTabLoad({id: tabs[1], url: "about:blank?1"}).then(() => {
expect(null);
});
browser.tabs.update(tabs[1], {url: "about:blank?1"});
},
expect => {
browser.test.log("Show the icon. Expect default properties again.");
browser.pageAction.show(tabs[1]).then(() => {
expect(details[0]);
});
},
expect => {
browser.test.log("Switch back to the first tab. Expect previously set properties.");
browser.tabs.update(tabs[0], {active: true}, () => {
expect(details[1]);
});
},
expect => {
browser.test.log("Hide the icon on tab 2. Switch back, expect hidden.");
browser.pageAction.hide(tabs[1]).then(() => {
browser.tabs.update(tabs[1], {active: true}, () => {
expect(null);
});
});
},
expect => {
browser.test.log("Switch back to tab 1. Expect previous results again.");
browser.tabs.remove(tabs[1], () => {
expect(details[1]);
});
},
expect => {
browser.test.log("Hide the icon. Expect hidden.");
browser.pageAction.hide(tabs[0]).then(() => {
expect(null);
});
},
];
},
});
});
add_task(function* testDefaultTitle() {
yield runTests({
manifest: {
"name": "Foo Extension",
"page_action": {
"default_icon": "icon.png",
},
"permissions": ["tabs"],
},
files: {
"icon.png": imageBuffer,
},
getTests(tabs) {
let details = [
{"title": "Foo Extension",
"popup": "",
"icon": browser.runtime.getURL("icon.png")},
{"title": "Foo Title",
"popup": "",
"icon": browser.runtime.getURL("icon.png")},
];
return [
expect => {
browser.test.log("Initial state. No icon visible.");
expect(null);
},
expect => {
browser.test.log("Show the icon on the first tab, expect extension title as default title.");
browser.pageAction.show(tabs[0]).then(() => {
expect(details[0]);
});
},
expect => {
browser.test.log("Change the title. Expect new title.");
browser.pageAction.setTitle({tabId: tabs[0], title: "Foo Title"});
expect(details[1]);
},
expect => {
browser.test.log("Clear the title. Expect extension title.");
browser.pageAction.setTitle({tabId: tabs[0], title: ""});
expect(details[0]);
},
];
},
});
});

View File

@ -31,9 +31,11 @@ add_task(function* testExecuteScript() {
return Promise.reject(new Error("Max tries exceeded"));
}
let url = `${URL}?r=${Math.random()}`;
let loadingPromise = new Promise(resolve => {
browser.tabs.onUpdated.addListener(function listener(tabId, changed, tab_) {
if (tabId == tab.id && changed.status == "loading" && tab_.url == URL) {
if (tabId == tab.id && changed.status == "loading" && tab_.url == url) {
browser.tabs.onUpdated.removeListener(listener);
resolve();
}
@ -42,7 +44,7 @@ add_task(function* testExecuteScript() {
// TODO: Test allFrames and frameId.
return browser.tabs.update({url: URL}).then(() => {
return browser.tabs.update({url}).then(() => {
return loadingPromise;
}).then(() => {
return Promise.all([

View File

@ -0,0 +1,162 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
/* exported runTests */
/* globals getListStyleImage */
function* runTests(options) {
function background(getTests) {
let tabs;
let tests;
// Gets the current details of the page action, and returns a
// promise that resolves to an object containing them.
function getDetails() {
return new Promise(resolve => {
return browser.tabs.query({active: true, currentWindow: true}, resolve);
}).then(([tab]) => {
let tabId = tab.id;
browser.test.log(`Get details: tab={id: ${tabId}, url: ${JSON.stringify(tab.url)}}`);
return Promise.all([
browser.pageAction.getTitle({tabId}),
browser.pageAction.getPopup({tabId})]);
}).then(details => {
return Promise.resolve({title: details[0],
popup: details[1]});
});
}
// Runs the next test in the `tests` array, checks the results,
// and passes control back to the outer test scope.
function nextTest() {
let test = tests.shift();
test(expecting => {
function finish() {
// Check that the actual icon has the expected values, then
// run the next test.
browser.test.sendMessage("nextTest", expecting, tests.length);
}
if (expecting) {
// Check that the API returns the expected values, and then
// run the next test.
getDetails().then(details => {
browser.test.assertEq(expecting.title, details.title,
"expected value from getTitle");
browser.test.assertEq(expecting.popup, details.popup,
"expected value from getPopup");
finish();
});
} else {
finish();
}
});
}
function runTests() {
tabs = [];
tests = getTests(tabs);
browser.tabs.query({active: true, currentWindow: true}, resultTabs => {
tabs[0] = resultTabs[0].id;
nextTest();
});
}
browser.test.onMessage.addListener((msg) => {
if (msg == "runTests") {
runTests();
} else if (msg == "runNextTest") {
nextTest();
} else {
browser.test.fail(`Unexpected message: ${msg}`);
}
});
runTests();
}
let extension = ExtensionTestUtils.loadExtension({
manifest: options.manifest,
files: options.files || {},
background: `(${background})(${options.getTests})`,
});
let pageActionId;
let currentWindow = window;
let windows = [];
function checkDetails(details) {
let image = currentWindow.document.getElementById(pageActionId);
if (details == null) {
ok(image == null || image.hidden, "image is hidden");
} else {
ok(image, "image exists");
is(getListStyleImage(image), details.icon, "icon URL is correct");
let title = details.title || options.manifest.name;
is(image.getAttribute("tooltiptext"), title, "image title is correct");
is(image.getAttribute("aria-label"), title, "image aria-label is correct");
// TODO: Popup URL.
}
}
let testNewWindows = 1;
let awaitFinish = new Promise(resolve => {
extension.onMessage("nextTest", (expecting, testsRemaining) => {
if (!pageActionId) {
pageActionId = `${makeWidgetId(extension.id)}-page-action`;
}
checkDetails(expecting);
if (testsRemaining) {
extension.sendMessage("runNextTest");
} else if (testNewWindows) {
testNewWindows--;
BrowserTestUtils.openNewBrowserWindow().then(window => {
windows.push(window);
currentWindow = window;
return focusWindow(window);
}).then(() => {
extension.sendMessage("runTests");
});
} else {
resolve();
}
});
});
yield SpecialPowers.pushPrefEnv({set: [["general.useragent.locale", "es-ES"]]});
yield extension.startup();
yield awaitFinish;
yield extension.unload();
yield SpecialPowers.popPrefEnv();
let node = document.getElementById(pageActionId);
is(node, null, "pageAction image removed from document");
currentWindow = null;
for (let win of windows.splice(0)) {
node = win.document.getElementById(pageActionId);
is(node, null, "pageAction image removed from second document");
yield BrowserTestUtils.closeWindow(win);
}
}

View File

@ -23,6 +23,8 @@ const kPasswordManagerTopicTypes = new Set([
"modifyLogin",
]);
const kSyncTopic = "fxaccounts:onlogin";
const kNotificationId = "abouthome-automigration-undo";
Cu.import("resource:///modules/MigrationUtils.jsm");
@ -46,24 +48,28 @@ const AutoMigrate = {
},
maybeInitUndoObserver() {
// Check synchronously (NB: canUndo is async) if we really need
// to do this:
if (!this.getUndoRange()) {
if (!this.canUndo()) {
return;
}
// Now register places and password observers:
// Now register places, password and sync observers:
this.onItemAdded = this.onItemMoved = this.onItemChanged =
this.removeUndoOption;
this.removeUndoOption.bind(this, this.UNDO_REMOVED_REASON_BOOKMARK_CHANGE);
PlacesUtils.addLazyBookmarkObserver(this, true);
Services.obs.addObserver(this, kPasswordManagerTopic, true);
for (let topic of [kSyncTopic, kPasswordManagerTopic]) {
Services.obs.addObserver(this, topic, true);
}
},
observe(subject, topic, data) {
// As soon as any login gets added or modified, disable undo:
// (Note that this ignores logins being removed as that doesn't
// impair the 'undo' functionality of the import.)
if (kPasswordManagerTopicTypes.has(data)) {
this.removeUndoOption();
if (topic == kPasswordManagerTopic) {
// As soon as any login gets added or modified, disable undo:
// (Note that this ignores logins being removed as that doesn't
// impair the 'undo' functionality of the import.)
if (kPasswordManagerTopicTypes.has(data)) {
this.removeUndoOption(this.UNDO_REMOVED_REASON_PASSWORD_CHANGE);
}
} else if (topic == kSyncTopic) {
this.removeUndoOption(this.UNDO_REMOVED_REASON_SYNC_SIGNIN);
}
},
@ -190,24 +196,13 @@ const AutoMigrate = {
},
canUndo() {
if (!this.getUndoRange()) {
return Promise.resolve(false);
}
// Return a promise resolving to false if we're signed into sync, resolve
// to true otherwise.
let {fxAccounts} = Cu.import("resource://gre/modules/FxAccounts.jsm", {});
return fxAccounts.getSignedInUser().then(user => {
if (user) {
Services.telemetry.getHistogramById("FX_STARTUP_MIGRATION_CANT_UNDO_BECAUSE_SYNC").add(true);
}
return !user;
}, () => Promise.resolve(true));
return !!this.getUndoRange();
},
undo: Task.async(function* () {
let histogram = Services.telemetry.getHistogramById("FX_STARTUP_MIGRATION_AUTOMATED_IMPORT_UNDO");
histogram.add(0);
if (!(yield this.canUndo())) {
if (!this.canUndo()) {
histogram.add(5);
throw new Error("Can't undo!");
}
@ -238,19 +233,27 @@ const AutoMigrate = {
// ignore failure.
}
histogram.add(25);
this.removeUndoOption();
this.removeUndoOption(this.UNDO_REMOVED_REASON_UNDO_USED);
histogram.add(30);
}),
removeUndoOption() {
removeUndoOption(reason) {
// Remove observers, and ensure that exceptions doing so don't break
// removing the pref.
try {
Services.obs.removeObserver(this, kPasswordManagerTopic);
} catch (ex) {}
for (let topic of [kSyncTopic, kPasswordManagerTopic]) {
try {
Services.obs.removeObserver(this, topic);
} catch (ex) {
Cu.reportError("Error removing observer for " + topic + ": " + ex);
}
}
try {
PlacesUtils.removeLazyBookmarkObserver(this);
} catch (ex) {}
} catch (ex) {
Cu.reportError("Error removing lazy bookmark observer: " + ex);
}
let migrationBrowser = Preferences.get(kAutoMigrateBrowserPref, "unknown");
Services.prefs.clearUserPref(kAutoMigrateStartedPref);
Services.prefs.clearUserPref(kAutoMigrateFinishedPref);
Services.prefs.clearUserPref(kAutoMigrateBrowserPref);
@ -268,6 +271,9 @@ const AutoMigrate = {
}
}
}
let histogram =
Services.telemetry.getKeyedHistogramById("FX_STARTUP_MIGRATION_UNDO_REASON");
histogram.add(migrationBrowser, reason);
},
getBrowserUsedForMigration() {
@ -279,54 +285,53 @@ const AutoMigrate = {
},
maybeShowUndoNotification(target) {
this.canUndo().then(canUndo => {
// The tab might have navigated since we requested the undo state:
if (!canUndo || target.currentURI.spec != "about:home") {
return;
}
let win = target.ownerGlobal;
let notificationBox = win.gBrowser.getNotificationBox(target);
if (!notificationBox || notificationBox.getNotificationWithValue("abouthome-automigration-undo")) {
return;
}
// The tab might have navigated since we requested the undo state:
if (!this.canUndo() || target.currentURI.spec != "about:home") {
return;
}
// At this stage we're committed to show the prompt - unless we shouldn't,
// in which case we remove the undo prefs (which will cause canUndo() to
// return false from now on.):
if (!this.shouldStillShowUndoPrompt()) {
this.removeUndoOption();
return;
}
let win = target.ownerGlobal;
let notificationBox = win.gBrowser.getNotificationBox(target);
if (!notificationBox || notificationBox.getNotificationWithValue("abouthome-automigration-undo")) {
return;
}
let browserName = this.getBrowserUsedForMigration();
let message;
if (browserName) {
message = MigrationUtils.getLocalizedString("automigration.undo.message",
[browserName]);
} else {
message = MigrationUtils.getLocalizedString("automigration.undo.unknownBrowserMessage");
}
// At this stage we're committed to show the prompt - unless we shouldn't,
// in which case we remove the undo prefs (which will cause canUndo() to
// return false from now on.):
if (!this.shouldStillShowUndoPrompt()) {
this.removeUndoOption(this.UNDO_REMOVED_REASON_OFFER_EXPIRED);
return;
}
let buttons = [
{
label: MigrationUtils.getLocalizedString("automigration.undo.keep.label"),
accessKey: MigrationUtils.getLocalizedString("automigration.undo.keep.accesskey"),
callback: () => {
this.removeUndoOption();
},
let browserName = this.getBrowserUsedForMigration();
let message;
if (browserName) {
message = MigrationUtils.getLocalizedString("automigration.undo.message",
[browserName]);
} else {
message = MigrationUtils.getLocalizedString("automigration.undo.unknownBrowserMessage");
}
let buttons = [
{
label: MigrationUtils.getLocalizedString("automigration.undo.keep.label"),
accessKey: MigrationUtils.getLocalizedString("automigration.undo.keep.accesskey"),
callback: () => {
this.removeUndoOption(this.UNDO_REMOVED_REASON_OFFER_REJECTED);
},
{
label: MigrationUtils.getLocalizedString("automigration.undo.dontkeep.label"),
accessKey: MigrationUtils.getLocalizedString("automigration.undo.dontkeep.accesskey"),
callback: () => {
this.undo();
},
},
{
label: MigrationUtils.getLocalizedString("automigration.undo.dontkeep.label"),
accessKey: MigrationUtils.getLocalizedString("automigration.undo.dontkeep.accesskey"),
callback: () => {
this.undo();
},
];
notificationBox.appendNotification(
message, kNotificationId, null, notificationBox.PRIORITY_INFO_HIGH, buttons
);
});
},
];
notificationBox.appendNotification(
message, kNotificationId, null, notificationBox.PRIORITY_INFO_HIGH, buttons
);
},
shouldStillShowUndoPrompt() {
@ -350,6 +355,13 @@ const AutoMigrate = {
return true;
},
UNDO_REMOVED_REASON_UNDO_USED: 0,
UNDO_REMOVED_REASON_SYNC_SIGNIN: 1,
UNDO_REMOVED_REASON_PASSWORD_CHANGE: 2,
UNDO_REMOVED_REASON_BOOKMARK_CHANGE: 3,
UNDO_REMOVED_REASON_OFFER_EXPIRED: 4,
UNDO_REMOVED_REASON_OFFER_REJECTED: 5,
QueryInterface: XPCOMUtils.generateQI(
[Ci.nsIObserver, Ci.nsINavBookmarkObserver, Ci.nsISupportsWeakReference]
),

View File

@ -165,7 +165,7 @@ add_task(function* checkUndoPreconditions() {
"Should have set start time pref");
Assert.ok(Preferences.has("browser.migrate.automigrate.finished"),
"Should have set finish time pref");
Assert.ok((yield AutoMigrate.canUndo()), "Should be able to undo migration");
Assert.ok(AutoMigrate.canUndo(), "Should be able to undo migration");
let [beginRange, endRange] = AutoMigrate.getUndoRange();
let stringRange = `beginRange: ${beginRange}; endRange: ${endRange}`;
@ -226,7 +226,7 @@ add_task(function* checkUndoRemoval() {
Preferences.set("browser.migrate.automigrate.finished", endTime);
// Verify that we can undo, then undo:
Assert.ok(yield AutoMigrate.canUndo(), "Should be possible to undo migration");
Assert.ok(AutoMigrate.canUndo(), "Should be possible to undo migration");
yield AutoMigrate.undo();
// Check that the undo removed the history visits:
@ -259,17 +259,17 @@ add_task(function* checkUndoDisablingByBookmarksAndPasswords() {
Services.prefs.setCharPref("browser.migrate.automigrate.finished", endTime);
AutoMigrate.maybeInitUndoObserver();
ok((yield AutoMigrate.canUndo()), "Should be able to undo.");
ok(AutoMigrate.canUndo(), "Should be able to undo.");
// Insert a login and check that that disabled undo.
let login = Cc["@mozilla.org/login-manager/loginInfo;1"].createInstance(Ci.nsILoginInfo);
login.init("www.mozilla.org", "http://www.mozilla.org", null, "user", "pass", "userEl", "passEl");
Services.logins.addLogin(login);
ok(!(yield AutoMigrate.canUndo()), "Should no longer be able to undo.");
ok(!AutoMigrate.canUndo(), "Should no longer be able to undo.");
Services.prefs.setCharPref("browser.migrate.automigrate.started", startTime);
Services.prefs.setCharPref("browser.migrate.automigrate.finished", endTime);
ok((yield AutoMigrate.canUndo()), "Should be able to undo.");
ok(AutoMigrate.canUndo(), "Should be able to undo.");
AutoMigrate.maybeInitUndoObserver();
// Insert a bookmark and check that that disabled undo.
@ -278,7 +278,7 @@ add_task(function* checkUndoDisablingByBookmarksAndPasswords() {
url: "http://www.example.org/",
title: "Some example bookmark",
});
ok(!(yield AutoMigrate.canUndo()), "Should no longer be able to undo.");
ok(!AutoMigrate.canUndo(), "Should no longer be able to undo.");
try {
Services.logins.removeAllLogins();

View File

@ -3,6 +3,12 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
Components.utils.import("resource://gre/modules/AppConstants.jsm");
Components.utils.import("resource://gre/modules/PluralForm.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ContextualIdentityService",
"resource://gre/modules/ContextualIdentityService.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
"resource://gre/modules/PluralForm.jsm");
var gPrivacyPane = {
@ -65,6 +71,45 @@ var gPrivacyPane = {
link.href = Services.urlFormatter.formatURLPref("app.support.baseURL") + "containers";
document.getElementById("browserContainersbox").hidden = false;
document.getElementById("browserContainersCheckbox").checked =
Services.prefs.getBoolPref("privacy.userContext.enabled");
},
_checkBrowserContainers: function(event) {
let checkbox = document.getElementById("browserContainersCheckbox");
if (checkbox.checked) {
Services.prefs.setBoolPref("privacy.userContext.enabled", true);
return;
}
let count = ContextualIdentityService.countContainerTabs();
if (count == 0) {
Services.prefs.setBoolPref("privacy.userContext.enabled", false);
return;
}
let bundlePreferences = document.getElementById("bundlePreferences");
let title = bundlePreferences.getString("disableContainersAlertTitle");
let message = PluralForm.get(count, bundlePreferences.getString("disableContainersMsg"))
.replace("#S", count)
let okButton = PluralForm.get(count, bundlePreferences.getString("disableContainersOkButton"))
.replace("#S", count)
let cancelButton = bundlePreferences.getString("disableContainersButton2");
let buttonFlags = (Ci.nsIPrompt.BUTTON_TITLE_IS_STRING * Ci.nsIPrompt.BUTTON_POS_0) +
(Ci.nsIPrompt.BUTTON_TITLE_IS_STRING * Ci.nsIPrompt.BUTTON_POS_1);
let rv = Services.prompt.confirmEx(window, title, message, buttonFlags,
okButton, cancelButton, null, null, {});
if (rv == 0) {
ContextualIdentityService.closeAllContainerTabs();
Services.prefs.setBoolPref("privacy.userContext.enabled", false);
return;
}
checkbox.checked = true;
},
/**
@ -131,6 +176,8 @@ var gPrivacyPane = {
gPrivacyPane.showBlockLists);
setEventListener("changeBlockListPBM", "command",
gPrivacyPane.showBlockLists);
setEventListener("browserContainersCheckbox", "command",
gPrivacyPane._checkBrowserContainers);
},
// TRACKING PROTECTION MODE

View File

@ -73,12 +73,6 @@
<preference id="browser.privatebrowsing.autostart"
name="browser.privatebrowsing.autostart"
type="bool"/>
<!-- Containers -->
<preference id="privacy.userContext.enabled"
name="privacy.userContext.enabled"
type="bool"/>
</preferences>
<hbox id="header-privacy"
@ -298,7 +292,6 @@
</label></caption>
<checkbox id="browserContainersCheckbox"
label="&browserContainersEnabled.label;"
accesskey="&browserContainersEnabled.accesskey;"
preference="privacy.userContext.enabled"/>
accesskey="&browserContainersEnabled.accesskey;" />
</vbox>
</groupbox>

View File

@ -175,3 +175,8 @@ revertNoRestartButton=Revert
restartNow=Restart Now
restartLater=Restart Later
disableContainersAlertTitle=Close All Container Tabs?
disableContainersMsg=If you disable Container Tabs now, #S container tab will be closed. Are you sure you want to disable Container Tabs?;If you disable Containers Tabs now, #S container tabs will be closed. Are you sure you want to disable Containers Tabs?
disableContainersOkButton=Close #S Container Tab;Close #S Container Tabs
disableContainersButton2=Keep enabled

View File

@ -11,8 +11,8 @@
*/
/* Lightweight theme on tabs */
#tabbrowser-tabs:not([movingtab]) > .tabbrowser-tab > .tab-stack > .tab-background > .tab-background-start[visuallyselected=true]:-moz-lwtheme::before,
#tabbrowser-tabs:not([movingtab]) > .tabbrowser-tab > .tab-stack > .tab-background > .tab-background-end[visuallyselected=true]:-moz-lwtheme::before {
#tabbrowser-tabs:not([movingtab]) > .tabbrowser-tab > .tab-stack > .tab-background > .tab-background-start[selected=true]:-moz-lwtheme::before,
#tabbrowser-tabs:not([movingtab]) > .tabbrowser-tab > .tab-stack > .tab-background > .tab-background-end[selected=true]:-moz-lwtheme::before {
background-attachment: scroll, fixed;
background-color: transparent;
background-image: @fgTabTextureLWT@;/*, lwtHeader;*/
@ -20,7 +20,7 @@
background-repeat: repeat-x, no-repeat;
}
#tabbrowser-tabs:not([movingtab]) > .tabbrowser-tab > .tab-stack > .tab-background > .tab-background-middle[visuallyselected=true]:-moz-lwtheme {
#tabbrowser-tabs:not([movingtab]) > .tabbrowser-tab > .tab-stack > .tab-background > .tab-background-middle[selected=true]:-moz-lwtheme {
background-attachment: scroll, scroll, fixed;
background-color: transparent;
background-image: url(chrome://browser/skin/tabbrowser/tab-active-middle.png),

View File

@ -1592,12 +1592,12 @@ html|span.ac-emphasize-text-url {
}
/* Tab close button */
.tab-close-button:not([visuallyselected]):not(:hover) {
.tab-close-button:not([selected]):not(:hover) {
background-image: -moz-image-rect(url("chrome://global/skin/icons/close.svg"), 0, 64, 16, 48);
}
.tab-close-button:not(:hover):-moz-lwtheme-brighttext,
#TabsToolbar[brighttext] .tab-close-button:not([visuallyselected]):not(:hover) {
#TabsToolbar[brighttext] .tab-close-button:not([selected]):not(:hover) {
background-image: -moz-image-rect(url("chrome://global/skin/icons/close.svg"), 0, 80, 16, 64);
}

View File

@ -21,7 +21,7 @@
:root[devtoolstheme="dark"] .findbar-closebutton:not(:hover),
:root[devtoolstheme="dark"] #sidebar-header > .close-icon:not(:hover),
.tab-close-button[visuallyselected]:not(:hover) {
.tab-close-button[selected]:not(:hover) {
background-image: -moz-image-rect(url("chrome://global/skin/icons/close.svg"), 0, 80, 16, 64);
}

View File

@ -10,8 +10,8 @@
*/
/* Lightweight theme on tabs */
#tabbrowser-tabs:not([movingtab]) > .tabbrowser-tab > .tab-stack > .tab-background > .tab-background-start[visuallyselected=true]:-moz-lwtheme::before,
#tabbrowser-tabs:not([movingtab]) > .tabbrowser-tab > .tab-stack > .tab-background > .tab-background-end[visuallyselected=true]:-moz-lwtheme::before {
#tabbrowser-tabs:not([movingtab]) > .tabbrowser-tab > .tab-stack > .tab-background > .tab-background-start[selected=true]:-moz-lwtheme::before,
#tabbrowser-tabs:not([movingtab]) > .tabbrowser-tab > .tab-stack > .tab-background > .tab-background-end[selected=true]:-moz-lwtheme::before {
background-attachment: scroll, fixed;
background-color: transparent;
background-image: @fgTabTextureLWT@;/*, lwtHeader;*/
@ -19,7 +19,7 @@
background-repeat: repeat-x, no-repeat;
}
#tabbrowser-tabs:not([movingtab]) > .tabbrowser-tab > .tab-stack > .tab-background > .tab-background-middle[visuallyselected=true]:-moz-lwtheme {
#tabbrowser-tabs:not([movingtab]) > .tabbrowser-tab > .tab-stack > .tab-background > .tab-background-middle[selected=true]:-moz-lwtheme {
background-attachment: scroll, scroll, fixed;
background-color: transparent;
background-image: url(chrome://browser/skin/tabbrowser/tab-active-middle.png),
@ -30,7 +30,7 @@
}
@media (min-resolution: 2dppx) {
#tabbrowser-tabs:not([movingtab]) > .tabbrowser-tab > .tab-stack > .tab-background > .tab-background-middle[visuallyselected=true]:-moz-lwtheme {
#tabbrowser-tabs:not([movingtab]) > .tabbrowser-tab > .tab-stack > .tab-background > .tab-background-middle[selected=true]:-moz-lwtheme {
background-image: url(chrome://browser/skin/tabbrowser/tab-active-middle@2x.png),
@fgTabTextureLWT@;/*,
lwtHeader;*/

View File

@ -2480,30 +2480,30 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
url(chrome://browser/skin/tabbrowser/tab-background-start.png);
}
.tab-background-middle[visuallyselected=true]:-moz-window-inactive {
.tab-background-middle[selected=true]:-moz-window-inactive {
background-image: url(chrome://browser/skin/yosemite/tab-active-middle-inactive.png),
@fgTabTextureYosemiteInactive@,
none;
}
.tab-background-start[visuallyselected=true]:-moz-window-inactive:-moz-locale-dir(ltr)::after,
.tab-background-end[visuallyselected=true]:-moz-window-inactive:-moz-locale-dir(rtl)::after {
.tab-background-start[selected=true]:-moz-window-inactive:-moz-locale-dir(ltr)::after,
.tab-background-end[selected=true]:-moz-window-inactive:-moz-locale-dir(rtl)::after {
background-image: url(chrome://browser/skin/yosemite/tab-stroke-start-inactive.png);
}
.tab-background-end[visuallyselected=true]:-moz-window-inactive:-moz-locale-dir(ltr)::after,
.tab-background-start[visuallyselected=true]:-moz-window-inactive:-moz-locale-dir(rtl)::after {
.tab-background-end[selected=true]:-moz-window-inactive:-moz-locale-dir(ltr)::after,
.tab-background-start[selected=true]:-moz-window-inactive:-moz-locale-dir(rtl)::after {
background-image: url(chrome://browser/skin/yosemite/tab-stroke-end-inactive.png);
}
.tab-background-start[visuallyselected=true]:-moz-window-inactive:-moz-locale-dir(ltr):not(:-moz-lwtheme)::before,
.tab-background-end[visuallyselected=true]:-moz-window-inactive:-moz-locale-dir(rtl):not(:-moz-lwtheme)::before {
.tab-background-start[selected=true]:-moz-window-inactive:-moz-locale-dir(ltr):not(:-moz-lwtheme)::before,
.tab-background-end[selected=true]:-moz-window-inactive:-moz-locale-dir(rtl):not(:-moz-lwtheme)::before {
background-image: url(chrome://browser/skin/yosemite/tab-selected-start-inactive.svg);
background-size: 100% 100%;
}
.tab-background-end[visuallyselected=true]:-moz-window-inactive:-moz-locale-dir(ltr):not(:-moz-lwtheme)::before,
.tab-background-start[visuallyselected=true]:-moz-window-inactive:-moz-locale-dir(rtl):not(:-moz-lwtheme)::before {
.tab-background-end[selected=true]:-moz-window-inactive:-moz-locale-dir(ltr):not(:-moz-lwtheme)::before,
.tab-background-start[selected=true]:-moz-window-inactive:-moz-locale-dir(rtl):not(:-moz-lwtheme)::before {
background-image: url(chrome://browser/skin/yosemite/tab-selected-end-inactive.svg);
background-size: 100% 100%;
}
@ -2527,25 +2527,25 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
url(chrome://browser/skin/tabbrowser/tab-background-start@2x.png);
}
.tab-background-middle[visuallyselected=true]:-moz-window-inactive {
.tab-background-middle[selected=true]:-moz-window-inactive {
background-image: url(chrome://browser/skin/yosemite/tab-active-middle-inactive@2x.png),
@fgTabTextureYosemiteInactive@,
none;
}
.tab-background-start[visuallyselected=true]:-moz-window-inactive:-moz-locale-dir(ltr)::after,
.tab-background-end[visuallyselected=true]:-moz-window-inactive:-moz-locale-dir(rtl)::after {
.tab-background-start[selected=true]:-moz-window-inactive:-moz-locale-dir(ltr)::after,
.tab-background-end[selected=true]:-moz-window-inactive:-moz-locale-dir(rtl)::after {
background-image: url(chrome://browser/skin/yosemite/tab-stroke-start-inactive@2x.png);
}
.tab-background-end[visuallyselected=true]:-moz-window-inactive:-moz-locale-dir(ltr)::after,
.tab-background-start[visuallyselected=true]:-moz-window-inactive:-moz-locale-dir(rtl)::after {
.tab-background-end[selected=true]:-moz-window-inactive:-moz-locale-dir(ltr)::after,
.tab-background-start[selected=true]:-moz-window-inactive:-moz-locale-dir(rtl)::after {
background-image: url(chrome://browser/skin/yosemite/tab-stroke-end-inactive@2x.png);
}
}
}
.tabbrowser-tab:not(:hover) > .tab-stack > .tab-content > .tab-icon-image:not([visuallyselected="true"]) {
.tabbrowser-tab:not(:hover) > .tab-stack > .tab-content > .tab-icon-image:not([selected="true"]) {
opacity: .9;
}
@ -2557,7 +2557,7 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
opacity: 0.9999;
}
.tab-label:not([visuallyselected="true"]) {
.tab-label:not([selected="true"]) {
opacity: .7;
}
@ -2649,12 +2649,12 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
cursor: default;
}
#TabsToolbar[brighttext] .tab-close-button.close-icon:not([visuallyselected=true]):not(:hover) {
#TabsToolbar[brighttext] .tab-close-button.close-icon:not([selected=true]):not(:hover) {
-moz-image-region: rect(0, 64px, 16px, 48px);
}
@media (min-resolution: 2dppx) {
#TabsToolbar[brighttext] .tab-close-button.close-icon:not([visuallyselected=true]):not(:hover) {
#TabsToolbar[brighttext] .tab-close-button.close-icon:not([selected=true]):not(:hover) {
-moz-image-region: rect(0, 128px, 32px, 96px);
}
}

View File

@ -108,12 +108,12 @@
:root[devtoolstheme="dark"] .findbar-closebutton:not(:hover),
/* Tab styling - make sure to use an inverted icon for the selected tab
(brighttext only covers the unselected tabs) */
.tab-close-button[visuallyselected=true]:not(:hover) {
.tab-close-button[selected=true]:not(:hover) {
-moz-image-region: rect(0, 64px, 16px, 48px);
}
@media (min-resolution: 2dppx) {
:root[devtoolstheme="dark"] .findbar-closebutton:not(:hover),
.tab-close-button[visuallyselected=true]:not(:hover) {
.tab-close-button[selected=true]:not(:hover) {
-moz-image-region: rect(0, 128px, 32px, 96px);
}
}

View File

@ -285,7 +285,7 @@
-moz-appearance: none;
margin: 0;
border: none;
border-top: 1px solid #ccc;
border-top: 1px solid var(--panel-separator-color);
padding: 8px 20px;
color: ButtonText;
background-color: transparent;

View File

@ -118,17 +118,17 @@
padding-inline-start: 0;
}
.tab-background-start[visuallyselected=true]::after,
.tab-background-start[visuallyselected=true]::before,
.tab-background-start[selected=true]::after,
.tab-background-start[selected=true]::before,
.tab-background-start,
.tab-background-end,
.tab-background-end[visuallyselected=true]::after,
.tab-background-end[visuallyselected=true]::before {
.tab-background-end[selected=true]::after,
.tab-background-end[selected=true]::before {
width: 0;
}
.tab-background-start[visuallyselected=true]::after,
.tab-background-end[visuallyselected=true]::after {
.tab-background-start[selected=true]::after,
.tab-background-end[selected=true]::after {
margin-inline-start: 0;
}
/* End override @tabCurveHalfWidth@ and @tabCurveWidth@ */
@ -256,14 +256,14 @@ window:not([chromehidden~="toolbar"]) #urlbar-wrapper {
pointer-events: auto;
}
.tabbrowser-tab:-moz-any([image], [pinned]) > .tab-stack > .tab-content[attention]:not([visuallyselected="true"]),
.tabbrowser-tab > .tab-stack > .tab-content[pinned][titlechanged]:not([visuallyselected="true"]) {
.tabbrowser-tab:-moz-any([image], [pinned]) > .tab-stack > .tab-content[attention]:not([selected="true"]),
.tabbrowser-tab > .tab-stack > .tab-content[pinned][titlechanged]:not([selected="true"]) {
background-image: var(--pinned-tab-glow);
background-position: center;
background-size: 100%;
}
.tabbrowser-tab[image] > .tab-stack > .tab-content[attention]:not([pinned]):not([visuallyselected="true"]) {
.tabbrowser-tab[image] > .tab-stack > .tab-content[attention]:not([pinned]):not([selected="true"]) {
background-position: left bottom var(--tab-toolbar-navbar-overlap);
background-size: 34px 100%;
}

View File

@ -11,13 +11,17 @@
padding-inline-end: 5px;
}
.notification-anchor-icon,
.blocked-permission-icon {
width: 16px;
height: 16px;
margin-inline-start: 2px;
}
/* This class can be used alone or in combination with the class defining the
type of icon displayed. This rule must be defined before the others in order
for its list-style-image to be overridden. */
.notification-anchor-icon {
width: 16px;
height: 16px;
margin-inline-start: 2px;
%ifdef MOZ_WIDGET_GTK
list-style-image: url(moz-icon://stock/gtk-dialog-info?size=16);
%else
@ -76,7 +80,7 @@
list-style-image: url(chrome://browser/skin/notification-icons.svg#desktop-notification);
}
.desktop-notification-icon.blocked {
.desktop-notification-icon.blocked-permission-icon {
list-style-image: url(chrome://browser/skin/notification-icons.svg#desktop-notification-blocked);
}
@ -90,7 +94,7 @@
%endif
}
.geo-icon.blocked {
.geo-icon.blocked-permission-icon {
%ifdef XP_MACOSX
list-style-image: url(chrome://browser/skin/notification-icons.svg#geo-osx-blocked);
%elif defined(MOZ_WIDGET_GTK)
@ -115,7 +119,7 @@
list-style-image: url(chrome://browser/skin/notification-icons.svg#indexedDB);
}
.indexedDB-icon.blocked {
.indexedDB-icon.blocked-permission-icon {
list-style-image: url(chrome://browser/skin/notification-icons.svg#indexedDB-blocked);
}
@ -137,7 +141,7 @@
list-style-image: url(chrome://browser/skin/notification-icons.svg#camera);
}
.camera-icon.blocked {
.camera-icon.blocked-permission-icon {
list-style-image: url(chrome://browser/skin/notification-icons.svg#camera-blocked);
}
@ -145,7 +149,7 @@
list-style-image: url(chrome://browser/skin/notification-icons.svg#microphone);
}
.microphone-icon.blocked {
.microphone-icon.blocked-permission-icon {
list-style-image: url(chrome://browser/skin/notification-icons.svg#microphone-blocked);
}
@ -158,7 +162,7 @@
list-style-image: url(chrome://browser/skin/notification-icons.svg#screen);
}
.screen-icon.blocked {
.screen-icon.blocked-permission-icon {
list-style-image: url(chrome://browser/skin/notification-icons.svg#screen-blocked);
}
@ -167,7 +171,7 @@
list-style-image: url(chrome://browser/skin/notification-icons.svg#pointerLock);
}
.pointerLock-icon.blocked {
.pointerLock-icon.blocked-permission-icon {
list-style-image: url(chrome://browser/skin/notification-icons.svg#pointerLock-blocked);
}

View File

@ -161,13 +161,13 @@
list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio-small.svg#tab-audio-muted");
}
#TabsToolbar[brighttext] .tab-icon-overlay[soundplaying]:not([visuallyselected]):not(:hover),
.tab-icon-overlay[soundplaying][visuallyselected]:-moz-lwtheme-brighttext:not(:hover) {
#TabsToolbar[brighttext] .tab-icon-overlay[soundplaying]:not([selected]):not(:hover),
.tab-icon-overlay[soundplaying][selected]:-moz-lwtheme-brighttext:not(:hover) {
list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio-small.svg#tab-audio-white");
}
#TabsToolbar[brighttext] .tab-icon-overlay[muted]:not([crashed]):not([visuallyselected]):not(:hover),
.tab-icon-overlay[muted][visuallyselected]:-moz-lwtheme-brighttext:not(:hover) {
#TabsToolbar[brighttext] .tab-icon-overlay[muted]:not([crashed]):not([selected]):not(:hover),
.tab-icon-overlay[muted][selected]:-moz-lwtheme-brighttext:not(:hover) {
list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio-small.svg#tab-audio-white-muted");
}
@ -272,12 +272,12 @@
transition: opacity 150ms ease;
}
.tab-background-start[visuallyselected=true]::after,
.tab-background-start[visuallyselected=true]::before,
.tab-background-start[selected=true]::after,
.tab-background-start[selected=true]::before,
.tab-background-start,
.tab-background-end,
.tab-background-end[visuallyselected=true]::after,
.tab-background-end[visuallyselected=true]::before {
.tab-background-end[selected=true]::after,
.tab-background-end[selected=true]::before {
min-height: var(--tab-min-height);
width: @tabCurveWidth@;
}
@ -298,8 +298,8 @@
*/
.tab-background-start[visuallyselected=true]::after,
.tab-background-end[visuallyselected=true]::after {
.tab-background-start[selected=true]::after,
.tab-background-end[selected=true]::after {
/* position ::after on top of its parent */
margin-inline-start: -@tabCurveWidth@;
background-size: 100% 100%;
@ -308,47 +308,47 @@
position: relative;
}
.tab-background-start[visuallyselected=true]::before,
.tab-background-end[visuallyselected=true]::before {
.tab-background-start[selected=true]::before,
.tab-background-end[selected=true]::before {
/* all ::before pseudo elements */
content: "";
display: -moz-box;
}
.tab-background-start[visuallyselected=true]:-moz-locale-dir(ltr):not(:-moz-lwtheme)::before,
.tab-background-end[visuallyselected=true]:-moz-locale-dir(rtl):not(:-moz-lwtheme)::before {
.tab-background-start[selected=true]:-moz-locale-dir(ltr):not(:-moz-lwtheme)::before,
.tab-background-end[selected=true]:-moz-locale-dir(rtl):not(:-moz-lwtheme)::before {
background-image: url(chrome://browser/skin/tabbrowser/tab-selected-start.svg);
background-size: 100% 100%;
}
.tab-background-end[visuallyselected=true]:-moz-locale-dir(ltr):not(:-moz-lwtheme)::before,
.tab-background-start[visuallyselected=true]:-moz-locale-dir(rtl):not(:-moz-lwtheme)::before {
.tab-background-end[selected=true]:-moz-locale-dir(ltr):not(:-moz-lwtheme)::before,
.tab-background-start[selected=true]:-moz-locale-dir(rtl):not(:-moz-lwtheme)::before {
background-image: url(chrome://browser/skin/tabbrowser/tab-selected-end.svg);
background-size: 100% 100%;
}
/* For lightweight themes, clip the header image on start, middle, and end. */
.tab-background-start[visuallyselected=true]:-moz-locale-dir(ltr):-moz-lwtheme::before,
.tab-background-end[visuallyselected=true]:-moz-locale-dir(rtl):-moz-lwtheme::before {
.tab-background-start[selected=true]:-moz-locale-dir(ltr):-moz-lwtheme::before,
.tab-background-end[selected=true]:-moz-locale-dir(rtl):-moz-lwtheme::before {
clip-path: url(chrome://browser/content/browser.xul#tab-curve-clip-path-start);
}
.tab-background-end[visuallyselected=true]:-moz-locale-dir(ltr):-moz-lwtheme::before,
.tab-background-start[visuallyselected=true]:-moz-locale-dir(rtl):-moz-lwtheme::before {
.tab-background-end[selected=true]:-moz-locale-dir(ltr):-moz-lwtheme::before,
.tab-background-start[selected=true]:-moz-locale-dir(rtl):-moz-lwtheme::before {
clip-path: url(chrome://browser/content/browser.xul#tab-curve-clip-path-end);
}
.tab-background-start[visuallyselected=true]:-moz-locale-dir(ltr)::after,
.tab-background-end[visuallyselected=true]:-moz-locale-dir(rtl)::after {
.tab-background-start[selected=true]:-moz-locale-dir(ltr)::after,
.tab-background-end[selected=true]:-moz-locale-dir(rtl)::after {
background-image: url(chrome://browser/skin/tabbrowser/tab-stroke-start.png);
}
.tab-background-end[visuallyselected=true]:-moz-locale-dir(ltr)::after,
.tab-background-start[visuallyselected=true]:-moz-locale-dir(rtl)::after {
.tab-background-end[selected=true]:-moz-locale-dir(ltr)::after,
.tab-background-start[selected=true]:-moz-locale-dir(rtl)::after {
background-image: url(chrome://browser/skin/tabbrowser/tab-stroke-end.png);
}
.tab-background-middle[visuallyselected=true] {
.tab-background-middle[selected=true] {
background-clip: padding-box, padding-box, content-box;
background-color: @fgTabBackgroundColor@;
background-image: url(chrome://browser/skin/tabbrowser/tab-active-middle.png),
@ -363,7 +363,7 @@
/* Selected tab lightweight theme styles.
See browser-lightweightTheme.css for information about run-time changes to LWT styles. */
.tab-background-middle[visuallyselected=true]:-moz-lwtheme {
.tab-background-middle[selected=true]:-moz-lwtheme {
background-color: transparent;
background-image: url(chrome://browser/skin/tabbrowser/tab-active-middle.png),
@fgTabTextureLWT@;/*,
@ -373,21 +373,21 @@
}
/* These LWT styles are normally overridden by browser-lightweightTheme.css */
.tab-background-start[visuallyselected=true]:-moz-lwtheme::before,
.tab-background-end[visuallyselected=true]:-moz-lwtheme::before {
.tab-background-start[selected=true]:-moz-lwtheme::before,
.tab-background-end[selected=true]:-moz-lwtheme::before {
background-image: @fgTabTextureLWT@;
}
.tab-background-start[visuallyselected=true]:-moz-lwtheme::before,
.tab-background-end[visuallyselected=true]:-moz-lwtheme::before,
.tab-background-middle[visuallyselected=true]:-moz-lwtheme {
.tab-background-start[selected=true]:-moz-lwtheme::before,
.tab-background-end[selected=true]:-moz-lwtheme::before,
.tab-background-middle[selected=true]:-moz-lwtheme {
background-color: transparent;
}
/* End selected tab */
/* new tab button border and gradient on hover */
.tabbrowser-tab:hover > .tab-stack > .tab-background:not([visuallyselected=true]),
.tabbrowser-tab:hover > .tab-stack > .tab-background:not([selected=true]),
.tabs-newtab-button:hover {
background-image: url(chrome://browser/skin/tabbrowser/tab-background-start.png),
url(chrome://browser/skin/tabbrowser/tab-background-middle.png),
@ -419,20 +419,20 @@
position: absolute;
}
.tabbrowser-tab:-moz-any([image], [pinned]) > .tab-stack > .tab-content[attention]:not([visuallyselected="true"]),
.tabbrowser-tab > .tab-stack > .tab-content[pinned][titlechanged]:not([visuallyselected="true"]) {
.tabbrowser-tab:-moz-any([image], [pinned]) > .tab-stack > .tab-content[attention]:not([selected="true"]),
.tabbrowser-tab > .tab-stack > .tab-content[pinned][titlechanged]:not([selected="true"]) {
background-image: radial-gradient(farthest-corner at center bottom, rgb(255,255,255) 3%, rgba(186,221,251,0.75) 20%, rgba(127,179,255,0.25) 40%, transparent 70%);
background-position: center bottom var(--tab-toolbar-navbar-overlap);
background-repeat: no-repeat;
background-size: 85% 100%;
}
.tabbrowser-tab[image] > .tab-stack > .tab-content[attention]:not([pinned]):not([visuallyselected="true"]) {
.tabbrowser-tab[image] > .tab-stack > .tab-content[attention]:not([pinned]):not([selected="true"]) {
background-position: left bottom var(--tab-toolbar-navbar-overlap);
background-size: 34px 100%;
}
.tab-label[attention]:not([visuallyselected="true"]) {
.tab-label[attention]:not([selected="true"]) {
font-weight: bold;
}
@ -456,8 +456,8 @@
/* Also show separators beside the selected tab when dragging it. */
#tabbrowser-tabs[movingtab] > .tabbrowser-tab[beforeselected]:not([last-visible-tab])::after,
.tabbrowser-tab:not([visuallyselected]):not([afterselected-visible]):not([afterhovered]):not([first-visible-tab]):not(:hover)::before,
#tabbrowser-tabs:not([overflow]) > .tabbrowser-tab[last-visible-tab]:not([visuallyselected]):not([beforehovered]):not(:hover)::after {
.tabbrowser-tab:not([selected]):not([afterselected-visible]):not([afterhovered]):not([first-visible-tab]):not(:hover)::before,
#tabbrowser-tabs:not([overflow]) > .tabbrowser-tab[last-visible-tab]:not([selected]):not([beforehovered]):not(:hover)::after {
content: "";
display: -moz-box;
}
@ -477,26 +477,26 @@
url(chrome://browser/skin/tabbrowser/tab-background-start@2x.png);
}
.tabbrowser-tab:hover > .tab-stack > .tab-background:not([visuallyselected=true]),
.tabbrowser-tab:hover > .tab-stack > .tab-background:not([selected=true]),
.tabs-newtab-button:hover {
background-image: url(chrome://browser/skin/tabbrowser/tab-background-start@2x.png),
url(chrome://browser/skin/tabbrowser/tab-background-middle@2x.png),
url(chrome://browser/skin/tabbrowser/tab-background-end@2x.png);
}
.tab-background-middle[visuallyselected=true] {
.tab-background-middle[selected=true] {
background-image: url(chrome://browser/skin/tabbrowser/tab-active-middle@2x.png),
@fgTabTexture@,
none;
}
.tab-background-start[visuallyselected=true]:-moz-locale-dir(ltr)::after,
.tab-background-end[visuallyselected=true]:-moz-locale-dir(rtl)::after {
.tab-background-start[selected=true]:-moz-locale-dir(ltr)::after,
.tab-background-end[selected=true]:-moz-locale-dir(rtl)::after {
background-image: url(chrome://browser/skin/tabbrowser/tab-stroke-start@2x.png);
}
.tab-background-end[visuallyselected=true]:-moz-locale-dir(ltr)::after,
.tab-background-start[visuallyselected=true]:-moz-locale-dir(rtl)::after {
.tab-background-end[selected=true]:-moz-locale-dir(ltr)::after,
.tab-background-start[selected=true]:-moz-locale-dir(rtl)::after {
background-image: url(chrome://browser/skin/tabbrowser/tab-stroke-end@2x.png);
}

View File

@ -64,7 +64,7 @@
background-color: @customToolbarColor@;
}
.tab-background-middle[visuallyselected=true]:not(:-moz-lwtheme) {
.tab-background-middle[selected=true]:not(:-moz-lwtheme) {
background-color: @customToolbarColor@;
}
}

View File

@ -11,8 +11,8 @@
*/
/* Lightweight theme on tabs */
#tabbrowser-tabs:not([movingtab]) > .tabbrowser-tab > .tab-stack > .tab-background > .tab-background-start[visuallyselected=true]:-moz-lwtheme::before,
#tabbrowser-tabs:not([movingtab]) > .tabbrowser-tab > .tab-stack > .tab-background > .tab-background-end[visuallyselected=true]:-moz-lwtheme::before {
#tabbrowser-tabs:not([movingtab]) > .tabbrowser-tab > .tab-stack > .tab-background > .tab-background-start[selected=true]:-moz-lwtheme::before,
#tabbrowser-tabs:not([movingtab]) > .tabbrowser-tab > .tab-stack > .tab-background > .tab-background-end[selected=true]:-moz-lwtheme::before {
background-attachment: scroll, fixed;
background-color: transparent;
background-image: @fgTabTextureLWT@;/*, lwtHeader;*/
@ -20,7 +20,7 @@
background-repeat: repeat-x, no-repeat;
}
#tabbrowser-tabs:not([movingtab]) > .tabbrowser-tab > .tab-stack > .tab-background > .tab-background-middle[visuallyselected=true]:-moz-lwtheme {
#tabbrowser-tabs:not([movingtab]) > .tabbrowser-tab > .tab-stack > .tab-background > .tab-background-middle[selected=true]:-moz-lwtheme {
background-attachment: scroll, scroll, fixed;
background-color: transparent;
background-image: url(chrome://browser/skin/tabbrowser/tab-active-middle.png),
@ -31,7 +31,7 @@
}
@media (min-resolution: 1.25dppx) {
#tabbrowser-tabs:not([movingtab]) > .tabbrowser-tab > .tab-stack > .tab-background > .tab-background-middle[visuallyselected=true]:-moz-lwtheme {
#tabbrowser-tabs:not([movingtab]) > .tabbrowser-tab > .tab-stack > .tab-background > .tab-background-middle[selected=true]:-moz-lwtheme {
background-image: url(chrome://browser/skin/tabbrowser/tab-active-middle@2x.png),
@fgTabTextureLWT@;/*,
lwtHeader;*/

View File

@ -2063,8 +2063,8 @@ html|span.ac-emphasize-text-url {
@media not all and (-moz-os-version: windows-win7) {
@media not all and (-moz-os-version: windows-win8) {
@media (-moz-windows-default-theme) {
.tab-background-end[visuallyselected=true]::after,
.tab-background-start[visuallyselected=true]::after {
.tab-background-end[selected=true]::after,
.tab-background-start[selected=true]::after {
content: none;
}
@ -2089,14 +2089,14 @@ html|span.ac-emphasize-text-url {
/* Invert the unhovered close tab icons on bright-text tabs */
@media not all and (min-resolution: 1.1dppx) {
.tab-close-button:-moz-lwtheme-brighttext,
#TabsToolbar[brighttext] .tab-close-button:not([visuallyselected="true"]) {
#TabsToolbar[brighttext] .tab-close-button:not([selected="true"]) {
list-style-image: url("chrome://global/skin/icons/close-inverted.png");
}
}
@media (min-resolution: 1.1dppx) {
.tab-close-button:-moz-lwtheme-brighttext,
#TabsToolbar[brighttext] .tab-close-button:not([visuallyselected="true"]) {
#TabsToolbar[brighttext] .tab-close-button:not([selected="true"]) {
list-style-image: url("chrome://global/skin/icons/close-inverted@2x.png");
}
}

View File

@ -104,14 +104,14 @@
:root[devtoolstheme="dark"] #sidebar-header > .close-icon,
/* Tab styling - make sure to use an inverted icon for the selected tab
(brighttext only covers the unselected tabs) */
.tab-close-button[visuallyselected=true] {
.tab-close-button[selected=true] {
list-style-image: url("chrome://global/skin/icons/close-inverted.png");
}
@media (min-resolution: 1.1dppx) {
:root[devtoolstheme="dark"] .findbar-closebutton,
:root[devtoolstheme="dark"] #sidebar-header > .close-icon,
.tab-close-button[visuallyselected=true] {
.tab-close-button[selected=true] {
list-style-image: url("chrome://global/skin/icons/close-inverted@2x.png");
}
}

View File

@ -2,26 +2,6 @@ dnl This Source Code Form is subject to the terms of the Mozilla Public
dnl License, v. 2.0. If a copy of the MPL was not distributed with this
dnl file, You can obtain one at http://mozilla.org/MPL/2.0/.
AC_DEFUN([MOZ_CONFIG_FFI], [
MOZ_ARG_ENABLE_BOOL(system-ffi,
[ --enable-system-ffi Use system libffi (located with pkgconfig)],
MOZ_SYSTEM_FFI=1 )
if test -n "$MOZ_SYSTEM_FFI"; then
# Vanilla libffi 3.0.9 needs a few patches from upcoming version 3.0.10
# for non-GCC compilers.
if test -z "$GNU_CC"; then
PKG_CHECK_MODULES(MOZ_FFI, libffi > 3.0.9)
else
PKG_CHECK_MODULES(MOZ_FFI, libffi >= 3.0.9)
fi
fi
AC_SUBST(MOZ_SYSTEM_FFI)
])
AC_DEFUN([MOZ_SUBCONFIGURE_FFI], [
if test "$MOZ_BUILD_APP" != js -o -n "$JS_STANDALONE"; then

View File

@ -0,0 +1,16 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
js_option('--with-system-ffi',
help='Use system libffi (located with pkgconfig)')
use_system_ffi = depends_if('--with-system-ffi')(lambda _: True)
system_ffi = pkg_check_modules('MOZ_FFI', 'libffi > 3.0.9',
when=use_system_ffi)
set_config('MOZ_SYSTEM_FFI', system_ffi)
add_old_configure_assignment('MOZ_SYSTEM_FFI', system_ffi)

View File

@ -169,7 +169,6 @@ def old_configure_options(*options):
'--enable-cookies',
'--enable-cpp-rtti',
'--enable-crashreporter',
'--enable-ctypes',
'--enable-dbus',
'--enable-debug-js-modules',
'--enable-directshow',
@ -232,7 +231,6 @@ def old_configure_options(*options):
'--enable-synth-pico',
'--enable-system-cairo',
'--enable-system-extension-dirs',
'--enable-system-ffi',
'--enable-system-pixman',
'--enable-system-sqlite',
'--enable-tasktracer',

View File

@ -7,7 +7,7 @@
#include "DomainPolicy.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/ipc/URIUtils.h"
#include "mozilla/unused.h"
#include "mozilla/Unused.h"
#include "nsIMessageManager.h"
#include "nsScriptSecurityManager.h"

View File

@ -25,7 +25,7 @@
#include "nsXPCOMCIDInternal.h"
#include "mozilla/LookAndFeel.h"
#include "mozilla/unused.h"
#include "mozilla/Unused.h"
#include "nsICommandLine.h"
#include "nsILocaleService.h"

View File

@ -5,17 +5,19 @@
from __future__ import print_function, unicode_literals
import codecs
import json
import os
import subprocess
import sys
from collections import Iterable
import textwrap
base_dir = os.path.abspath(os.path.dirname(__file__))
sys.path.insert(0, os.path.join(base_dir, 'python', 'mozbuild'))
from mozbuild.configure import ConfigureSandbox
from mozbuild.util import (
indented_repr,
encode,
)
def main(argv):
@ -60,49 +62,27 @@ def config_status(config):
print("Creating config.status", file=sys.stderr)
encoding = 'mbcs' if sys.platform == 'win32' else 'utf-8'
with codecs.open('config.status', 'w', encoding) as fh:
fh.write('#!%s\n' % config['PYTHON'])
fh.write('# coding=%s\n' % encoding)
# Because we're serializing as JSON but reading as python, the values
# for True, False and None are true, false and null, which don't exist.
# Define them.
fh.write('true, false, null = True, False, None\n')
fh.write(textwrap.dedent('''\
#!%(python)s
# coding=%(encoding)s
from __future__ import unicode_literals
from mozbuild.util import encode
encoding = '%(encoding)s'
''') % {'python': config['PYTHON'], 'encoding': encoding})
# A lot of the build backend code is currently expecting byte
# strings and breaks in subtle ways with unicode strings. (bug 1296508)
for k, v in sanitized_config.iteritems():
fh.write('%s = ' % k)
json.dump(v, fh, sort_keys=True, indent=4, ensure_ascii=False)
fh.write('\n')
fh.write('%s = encode(%s, encoding)\n' % (k, indented_repr(v)))
fh.write("__all__ = ['topobjdir', 'topsrcdir', 'defines', "
"'non_global_defines', 'substs', 'mozconfig']")
if config.get('MOZ_BUILD_APP') != 'js' or config.get('JS_STANDALONE'):
fh.write('''
if __name__ == '__main__':
args = dict([(name, globals()[name]) for name in __all__])
from mozbuild.config_status import config_status
config_status(**args)
''')
# Running config.status standalone uses byte literals for all the config,
# instead of the unicode literals we have in sanitized_config right now.
# Some values in sanitized_config also have more complex types, such as
# EnumString, which using when calling config_status would currently break
# the build, as well as making it inconsistent with re-running
# config.status. Fortunately, EnumString derives from unicode, so it's
# covered by converting unicode strings.
# Moreover, a lot of the build backend code is currently expecting byte
# strings and breaks in subtle ways with unicode strings.
def encode(v):
if isinstance(v, dict):
return {
encode(k): encode(val)
for k, val in v.iteritems()
}
if isinstance(v, str):
return v
if isinstance(v, unicode):
return v.encode(encoding)
if isinstance(v, Iterable):
return [encode(i) for i in v]
return v
fh.write(textwrap.dedent('''
if __name__ == '__main__':
from mozbuild.config_status import config_status
args = dict([(name, globals()[name]) for name in __all__])
config_status(**args)
'''))
# Other things than us are going to run this file, so we need to give it
# executable permissions.
@ -110,7 +90,16 @@ if __name__ == '__main__':
if config.get('MOZ_BUILD_APP') != 'js' or config.get('JS_STANDALONE'):
os.environ[b'WRITE_MOZINFO'] = b'1'
from mozbuild.config_status import config_status
return config_status(args=[], **encode(sanitized_config))
# Some values in sanitized_config also have more complex types, such as
# EnumString, which using when calling config_status would currently
# break the build, as well as making it inconsistent with re-running
# config.status. Fortunately, EnumString derives from unicode, so it's
# covered by converting unicode strings.
# A lot of the build backend code is currently expecting byte strings
# and breaks in subtle ways with unicode strings.
return config_status(args=[], **encode(sanitized_config, encoding))
return 0

View File

@ -362,9 +362,7 @@ var SnapshotsListView = Heritage.extend(WidgetMethods, {
}
let channel = NetUtil.newChannel({
uri: NetUtil.newURI(fp.file),
loadingNode: window.document,
contentPolicyType: Ci.nsIContentPolicy.TYPE_OTHER});
uri: NetUtil.newURI(fp.file), loadUsingSystemPrincipal: true});
channel.contentType = "text/plain";
NetUtil.asyncFetch(channel, (inputStream, status) => {

View File

@ -34,13 +34,16 @@ function SourceMapService(target) {
target.on("source-updated", this._onSourceUpdated);
target.on("navigate", this.reset);
target.on("will-navigate", this.reset);
target.on("close", this.destroy);
}
/**
* Clears the store containing the cached promised locations
*/
SourceMapService.prototype.reset = function () {
// Guard to prevent clearing the store when it is not initialized yet.
if (!this._locationStore) {
return;
}
this._locationStore.clear();
this._isNotSourceMapped.clear();
};
@ -84,9 +87,10 @@ SourceMapService.prototype.unsubscribe = function (location, callback) {
// Check to see if the store exists before attempting to clear a location
// Sometimes un-subscribe happens during the destruction cascades and this
// condition is to protect against that. Could be looked into in the future.
if (this._locationStore) {
this._locationStore.clearByURL(location.url);
if (!this._locationStore) {
return;
}
this._locationStore.clearByURL(location.url);
};
/**

View File

@ -11,6 +11,8 @@ const {EyeDropper, HighlighterEnvironment} = require("devtools/server/actors/hig
/* eslint-enable mozilla/reject-some-requires */
const Telemetry = require("devtools/client/shared/telemetry");
const windowEyeDroppers = new WeakMap();
exports.items = [{
item: "command",
runAt: "client",
@ -48,9 +50,28 @@ exports.items = [{
name: "frommenu",
type: "boolean",
hidden: true
}, {
name: "hide",
type: "boolean",
hidden: true
}]
}],
exec: function (args, context) {
exec: function* (args, context) {
if (args.hide) {
context.updateExec("eyedropper_server_hide").catch(e => console.error(e));
return;
}
// If the inspector is already picking a color from the page, cancel it.
let target = context.environment.target;
let toolbox = gDevTools.getToolbox(target);
if (toolbox) {
let inspector = toolbox.getPanel("inspector");
if (inspector) {
yield inspector.hideEyeDropper();
}
}
let telemetry = new Telemetry();
telemetry.toolOpened(args.frommenu ? "menueyedropper" : "eyedropper");
context.updateExec("eyedropper_server").catch(e => console.error(e));
@ -61,15 +82,33 @@ exports.items = [{
name: "eyedropper_server",
hidden: true,
exec: function (args, {environment}) {
let env = new HighlighterEnvironment();
env.initFromWindow(environment.window);
let eyeDropper = new EyeDropper(env);
let eyeDropper = windowEyeDroppers.get(environment.window);
if (!eyeDropper) {
let env = new HighlighterEnvironment();
env.initFromWindow(environment.window);
eyeDropper = new EyeDropper(env);
eyeDropper.once("hidden", () => {
eyeDropper.destroy();
env.destroy();
windowEyeDroppers.delete(environment.window);
});
windowEyeDroppers.set(environment.window, eyeDropper);
}
eyeDropper.show(environment.document.documentElement, {copyOnSelect: true});
eyeDropper.once("hidden", () => {
eyeDropper.destroy();
env.destroy();
});
}
}, {
item: "command",
runAt: "server",
name: "eyedropper_server_hide",
hidden: true,
exec: function (args, {environment}) {
let eyeDropper = windowEyeDroppers.get(environment.window);
if (eyeDropper) {
eyeDropper.hide();
}
}
}];

View File

@ -1304,7 +1304,7 @@ InspectorPanel.prototype = {
this.telemetry.toolOpened("toolbareyedropper");
this.eyeDropperButton.setAttribute("checked", "true");
this.startEyeDropperListeners();
return this.inspector.pickColorFromPage({copyOnSelect: true})
return this.inspector.pickColorFromPage(this.toolbox, {copyOnSelect: true})
.catch(e => console.error(e));
},

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