mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
merge mozilla-inbound to mozilla-central a=merge
This commit is contained in:
commit
71900c9741
@ -35,7 +35,7 @@ static const uint32_t kGenericAccType = 0;
|
||||
* via the object attribute "xml-roles".
|
||||
*/
|
||||
|
||||
static nsRoleMapEntry sWAIRoleMaps[] =
|
||||
static const nsRoleMapEntry sWAIRoleMaps[] =
|
||||
{
|
||||
{ // alert
|
||||
&nsGkAtoms::alert,
|
||||
@ -760,7 +760,7 @@ static nsRoleMapEntry sWAIRoleMaps[] =
|
||||
}
|
||||
};
|
||||
|
||||
static nsRoleMapEntry sLandmarkRoleMap = {
|
||||
static const nsRoleMapEntry sLandmarkRoleMap = {
|
||||
&nsGkAtoms::_empty,
|
||||
roles::NOTHING,
|
||||
kUseNativeRole,
|
||||
@ -861,7 +861,7 @@ struct RoleComparator
|
||||
|
||||
}
|
||||
|
||||
nsRoleMapEntry*
|
||||
const nsRoleMapEntry*
|
||||
aria::GetRoleMap(dom::Element* aEl)
|
||||
{
|
||||
nsAutoString roles;
|
||||
|
@ -210,7 +210,7 @@ extern nsRoleMapEntry gEmptyRoleMap;
|
||||
* @return a pointer to the role map entry for the ARIA role, or nullptr
|
||||
* if none
|
||||
*/
|
||||
nsRoleMapEntry* GetRoleMap(dom::Element* aEl);
|
||||
const nsRoleMapEntry* GetRoleMap(dom::Element* aEl);
|
||||
|
||||
/**
|
||||
* Return accessible state from ARIA universal states applied to the given
|
||||
|
@ -146,7 +146,7 @@ nsAccUtils::SetLiveContainerAttributes(nsIPersistentProperties *aAttributes,
|
||||
|
||||
// container-live, and container-live-role attributes
|
||||
if (live.IsEmpty()) {
|
||||
nsRoleMapEntry* role = nullptr;
|
||||
const nsRoleMapEntry* role = nullptr;
|
||||
if (ancestor->IsElement()) {
|
||||
role = aria::GetRoleMap(ancestor->AsElement());
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ New_HTMLLink(nsIContent* aContent, Accessible* aContext)
|
||||
{
|
||||
// Only some roles truly enjoy life as HTMLLinkAccessibles, for details
|
||||
// see closed bug 494807.
|
||||
nsRoleMapEntry* roleMapEntry = aria::GetRoleMap(aContent->AsElement());
|
||||
const nsRoleMapEntry* roleMapEntry = aria::GetRoleMap(aContent->AsElement());
|
||||
if (roleMapEntry && roleMapEntry->role != roles::NOTHING &&
|
||||
roleMapEntry->role != roles::LINK) {
|
||||
return new HyperTextAccessibleWrap(aContent, aContext->Document());
|
||||
@ -1132,7 +1132,7 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
|
||||
return newAcc;
|
||||
}
|
||||
|
||||
nsRoleMapEntry* roleMapEntry = aria::GetRoleMap(content->AsElement());
|
||||
const nsRoleMapEntry* roleMapEntry = aria::GetRoleMap(content->AsElement());
|
||||
|
||||
// If the element is focusable or global ARIA attribute is applied to it or
|
||||
// it is referenced by ARIA relationship then treat role="presentation" on
|
||||
@ -1184,7 +1184,7 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
|
||||
// expose their native roles.
|
||||
if (!roleMapEntry && newAcc && aContext->HasStrongARIARole()) {
|
||||
if (frame->AccessibleType() == eHTMLTableRowType) {
|
||||
nsRoleMapEntry* contextRoleMap = aContext->ARIARoleMap();
|
||||
const nsRoleMapEntry* contextRoleMap = aContext->ARIARoleMap();
|
||||
if (!contextRoleMap->IsOfType(eTable))
|
||||
roleMapEntry = &aria::gEmptyRoleMap;
|
||||
|
||||
@ -1196,7 +1196,7 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
|
||||
nsGkAtoms::li,
|
||||
nsGkAtoms::dd) ||
|
||||
frame->AccessibleType() == eHTMLLiType) {
|
||||
nsRoleMapEntry* contextRoleMap = aContext->ARIARoleMap();
|
||||
const nsRoleMapEntry* contextRoleMap = aContext->ARIARoleMap();
|
||||
if (!contextRoleMap->IsOfType(eList))
|
||||
roleMapEntry = &aria::gEmptyRoleMap;
|
||||
}
|
||||
|
@ -226,7 +226,7 @@ public:
|
||||
/**
|
||||
* Retrun ARIA role map if any.
|
||||
*/
|
||||
nsRoleMapEntry* ARIARoleMap() const { return mRoleMapEntry; }
|
||||
const nsRoleMapEntry* ARIARoleMap() const { return mRoleMapEntry; }
|
||||
|
||||
/**
|
||||
* Return accessible role specified by ARIA (see constants in
|
||||
@ -372,7 +372,7 @@ public:
|
||||
/**
|
||||
* Set the ARIA role map entry for a new accessible.
|
||||
*/
|
||||
void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry)
|
||||
void SetRoleMapEntry(const nsRoleMapEntry* aRoleMapEntry)
|
||||
{ mRoleMapEntry = aRoleMapEntry; }
|
||||
|
||||
/**
|
||||
@ -1188,7 +1188,7 @@ protected:
|
||||
/**
|
||||
* Non-null indicates author-supplied role; possibly state & value as well
|
||||
*/
|
||||
nsRoleMapEntry* mRoleMapEntry;
|
||||
const nsRoleMapEntry* mRoleMapEntry;
|
||||
|
||||
private:
|
||||
Accessible() = delete;
|
||||
|
@ -1282,7 +1282,7 @@ DocAccessible::GetAccessibleOrDescendant(nsINode* aNode) const
|
||||
|
||||
void
|
||||
DocAccessible::BindToDocument(Accessible* aAccessible,
|
||||
nsRoleMapEntry* aRoleMapEntry)
|
||||
const nsRoleMapEntry* aRoleMapEntry)
|
||||
{
|
||||
// Put into DOM node cache.
|
||||
if (aAccessible->IsNodeMapEntry())
|
||||
|
@ -314,7 +314,8 @@ public:
|
||||
* @param aRoleMapEntry [in] the role map entry role the ARIA role or nullptr
|
||||
* if none
|
||||
*/
|
||||
void BindToDocument(Accessible* aAccessible, nsRoleMapEntry* aRoleMapEntry);
|
||||
void BindToDocument(Accessible* aAccessible,
|
||||
const nsRoleMapEntry* aRoleMapEntry);
|
||||
|
||||
/**
|
||||
* Remove from document and shutdown the given accessible.
|
||||
|
@ -353,7 +353,7 @@ DocAccessibleChild::RecvARIARoleAtom(const uint64_t& aID, nsString* aRole)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (nsRoleMapEntry* roleMap = acc->ARIARoleMap()) {
|
||||
if (const nsRoleMapEntry* roleMap = acc->ARIARoleMap()) {
|
||||
if (nsIAtom* roleAtom = *(roleMap->roleAtom)) {
|
||||
roleAtom->ToString(*aRole);
|
||||
}
|
||||
|
@ -811,7 +811,7 @@ ConvertToNSArray(nsTArray<ProxyAccessible*>& aArray)
|
||||
// Now, deal with widget roles
|
||||
nsIAtom* roleAtom = nullptr;
|
||||
if (accWrap && accWrap->HasARIARole()) {
|
||||
nsRoleMapEntry* roleMap = accWrap->ARIARoleMap();
|
||||
const nsRoleMapEntry* roleMap = accWrap->ARIARoleMap();
|
||||
roleAtom = *roleMap->roleAtom;
|
||||
}
|
||||
if (proxy)
|
||||
|
@ -6138,7 +6138,7 @@ function CanCloseWindow()
|
||||
{
|
||||
// Avoid redundant calls to canClose from showing multiple
|
||||
// PermitUnload dialogs.
|
||||
if (window.skipNextCanClose) {
|
||||
if (Services.startup.shuttingDown || window.skipNextCanClose) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1560,7 +1560,13 @@
|
||||
// Unhook our progress listener.
|
||||
let tab = this.getTabForBrowser(aBrowser);
|
||||
let filter = this._tabFilters.get(tab);
|
||||
let listener = this._tabListeners.get(tab);
|
||||
aBrowser.webProgress.removeProgressListener(filter);
|
||||
filter.removeProgressListener(listener);
|
||||
|
||||
// We'll be creating a new listener, so destroy the old one.
|
||||
listener.destroy();
|
||||
|
||||
// Make sure the browser is destroyed so it unregisters from observer notifications
|
||||
aBrowser.destroy();
|
||||
|
||||
@ -1582,6 +1588,13 @@
|
||||
aBrowser.docShellIsActive = (aBrowser == this.selectedBrowser &&
|
||||
window.windowState != window.STATE_MINIMIZED);
|
||||
|
||||
// Create a new tab progress listener for the new browser we just injected,
|
||||
// since tab progress listeners have logic for handling the initial about:blank
|
||||
// load
|
||||
listener = this.mTabProgressListener(tab, aBrowser, false, false);
|
||||
this._tabListeners.set(tab, listener);
|
||||
filter.addProgressListener(listener, Ci.nsIWebProgress.NOTIFY_ALL);
|
||||
|
||||
// Restore the progress listener.
|
||||
aBrowser.webProgress.addProgressListener(filter, Ci.nsIWebProgress.NOTIFY_ALL);
|
||||
|
||||
|
@ -120,6 +120,8 @@ support-files =
|
||||
xul_tooltiptext.xhtml
|
||||
file_bug1045809_1.html
|
||||
file_bug1045809_2.html
|
||||
file_csp_block_all_mixedcontent.html
|
||||
file_csp_block_all_mixedcontent.js
|
||||
|
||||
[browser_URLBarSetURI.js]
|
||||
skip-if = (os == "linux" || os == "mac") && debug # bug 970052, bug 970053
|
||||
@ -554,3 +556,5 @@ skip-if = !e10s || !crashreporter
|
||||
skip-if = !e10s || !crashreporter
|
||||
[browser_aboutTabCrashed_withoutDump.js]
|
||||
skip-if = !e10s
|
||||
[browser_csp_block_all_mixedcontent.js]
|
||||
tags = mcb
|
||||
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Description of the Test:
|
||||
* We load an https page which uses a CSP including block-all-mixed-content.
|
||||
* The page tries to load a script over http. We make sure the UI is not
|
||||
* influenced when blocking the mixed content. In particular the page
|
||||
* should still appear fully encrypted with a green lock.
|
||||
*/
|
||||
|
||||
const PRE_PATH = "https://example.com/browser/browser/base/content/test/general/";
|
||||
var gTestBrowser = null;
|
||||
|
||||
//------------------------------------------------------
|
||||
function cleanUpAfterTests() {
|
||||
gBrowser.removeCurrentTab();
|
||||
window.focus();
|
||||
finish();
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
function verifyUInotDegraded() {
|
||||
// make sure that not mixed content is loaded and also not blocked
|
||||
assertMixedContentBlockingState(
|
||||
gTestBrowser,
|
||||
{ activeLoaded: false,
|
||||
activeBlocked: false,
|
||||
passiveLoaded: false
|
||||
}
|
||||
);
|
||||
// clean up and finish test
|
||||
cleanUpAfterTests();
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
function runTests() {
|
||||
var newTab = gBrowser.addTab();
|
||||
gBrowser.selectedTab = newTab;
|
||||
gTestBrowser = gBrowser.selectedBrowser;
|
||||
newTab.linkedBrowser.stop();
|
||||
|
||||
// Starting the test
|
||||
BrowserTestUtils.browserLoaded(gTestBrowser).then(verifyUInotDegraded);
|
||||
var url = PRE_PATH + "file_csp_block_all_mixedcontent.html";
|
||||
gTestBrowser.loadURI(url);
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
function test() {
|
||||
// Performing async calls, e.g. 'onload', we have to wait till all of them finished
|
||||
waitForExplicitFinish();
|
||||
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{ 'set': [["security.mixed_content.block_active_content", true]] },
|
||||
function() { runTests(); }
|
||||
);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
function test() {
|
||||
add_task(function* () {
|
||||
gPrefService.setBoolPref("browser.ctrlTab.previews", true);
|
||||
|
||||
gBrowser.addTab();
|
||||
@ -7,39 +7,39 @@ function test() {
|
||||
|
||||
checkTabs(4);
|
||||
|
||||
ctrlTabTest([2] , 1, 0);
|
||||
ctrlTabTest([2, 3, 1], 2, 2);
|
||||
ctrlTabTest([] , 4, 2);
|
||||
yield ctrlTabTest([2] , 1, 0);
|
||||
yield ctrlTabTest([2, 3, 1], 2, 2);
|
||||
yield ctrlTabTest([] , 4, 2);
|
||||
|
||||
{
|
||||
let selectedIndex = gBrowser.tabContainer.selectedIndex;
|
||||
pressCtrlTab();
|
||||
pressCtrlTab(true);
|
||||
releaseCtrl();
|
||||
yield pressCtrlTab();
|
||||
yield pressCtrlTab(true);
|
||||
yield releaseCtrl();
|
||||
is(gBrowser.tabContainer.selectedIndex, selectedIndex,
|
||||
"Ctrl+Tab -> Ctrl+Shift+Tab keeps the selected tab");
|
||||
}
|
||||
|
||||
{ // test for bug 445369
|
||||
let tabs = gBrowser.tabs.length;
|
||||
pressCtrlTab();
|
||||
EventUtils.synthesizeKey("w", { ctrlKey: true });
|
||||
yield pressCtrlTab();
|
||||
yield synthesizeCtrlW();
|
||||
is(gBrowser.tabs.length, tabs - 1, "Ctrl+Tab -> Ctrl+W removes one tab");
|
||||
releaseCtrl();
|
||||
yield releaseCtrl();
|
||||
}
|
||||
|
||||
{ // test for bug 667314
|
||||
let tabs = gBrowser.tabs.length;
|
||||
pressCtrlTab();
|
||||
pressCtrlTab(true);
|
||||
EventUtils.synthesizeKey("w", { ctrlKey: true });
|
||||
yield pressCtrlTab();
|
||||
yield pressCtrlTab(true);
|
||||
yield synthesizeCtrlW();
|
||||
is(gBrowser.tabs.length, tabs - 1, "Ctrl+Tab -> Ctrl+W removes the selected tab");
|
||||
releaseCtrl();
|
||||
yield releaseCtrl();
|
||||
}
|
||||
|
||||
gBrowser.addTab();
|
||||
checkTabs(3);
|
||||
ctrlTabTest([2, 1, 0], 7, 1);
|
||||
yield ctrlTabTest([2, 1, 0], 7, 1);
|
||||
|
||||
gBrowser.addTab();
|
||||
checkTabs(4);
|
||||
@ -50,22 +50,22 @@ function test() {
|
||||
let selectedTab = gBrowser.selectedTab;
|
||||
let tabToRemove = gBrowser.tabs[1];
|
||||
|
||||
pressCtrlTab();
|
||||
pressCtrlTab();
|
||||
EventUtils.synthesizeKey("w", { ctrlKey: true });
|
||||
yield pressCtrlTab();
|
||||
yield pressCtrlTab();
|
||||
yield synthesizeCtrlW();
|
||||
ok(!tabToRemove.parentNode,
|
||||
"Ctrl+Tab*2 -> Ctrl+W removes the second most recently selected tab");
|
||||
|
||||
pressCtrlTab(true);
|
||||
pressCtrlTab(true);
|
||||
releaseCtrl();
|
||||
yield pressCtrlTab(true);
|
||||
yield pressCtrlTab(true);
|
||||
yield releaseCtrl();
|
||||
ok(selectedTab.selected,
|
||||
"Ctrl+Tab*2 -> Ctrl+W -> Ctrl+Shift+Tab*2 keeps the selected tab");
|
||||
}
|
||||
gBrowser.removeTab(gBrowser.tabContainer.lastChild);
|
||||
checkTabs(2);
|
||||
|
||||
ctrlTabTest([1], 1, 0);
|
||||
yield ctrlTabTest([1], 1, 0);
|
||||
|
||||
gBrowser.removeTab(gBrowser.tabContainer.lastChild);
|
||||
checkTabs(1);
|
||||
@ -77,7 +77,7 @@ function test() {
|
||||
eventConsumed = event.defaultPrevented;
|
||||
};
|
||||
document.addEventListener("keypress", detectKeyEvent, false);
|
||||
pressCtrlTab();
|
||||
yield pressCtrlTab();
|
||||
document.removeEventListener("keypress", detectKeyEvent, false);
|
||||
ok(eventConsumed, "Ctrl+Tab consumed by the tabbed browser if one tab is open");
|
||||
is(focusedWindow, document.commandDispatcher.focusedWindow,
|
||||
@ -90,18 +90,42 @@ function test() {
|
||||
|
||||
/* private utility functions */
|
||||
|
||||
function pressCtrlTab(aShiftKey) {
|
||||
function* pressCtrlTab(aShiftKey) {
|
||||
let promise;
|
||||
if (!isOpen() && canOpen()) {
|
||||
promise = BrowserTestUtils.waitForEvent(ctrlTab.panel, "popupshown");
|
||||
} else {
|
||||
promise = BrowserTestUtils.waitForEvent(document, "keyup");
|
||||
}
|
||||
EventUtils.synthesizeKey("VK_TAB", { ctrlKey: true, shiftKey: !!aShiftKey });
|
||||
return promise;
|
||||
}
|
||||
|
||||
function releaseCtrl() {
|
||||
function* releaseCtrl() {
|
||||
let promise;
|
||||
if (isOpen()) {
|
||||
promise = BrowserTestUtils.waitForEvent(ctrlTab.panel, "popuphidden");
|
||||
} else {
|
||||
promise = BrowserTestUtils.waitForEvent(document, "keyup");
|
||||
}
|
||||
EventUtils.synthesizeKey("VK_CONTROL", { type: "keyup" });
|
||||
return promise;
|
||||
}
|
||||
|
||||
function* synthesizeCtrlW() {
|
||||
let promise = BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "TabClose");
|
||||
EventUtils.synthesizeKey("w", { ctrlKey: true });
|
||||
return promise;
|
||||
}
|
||||
|
||||
function isOpen() {
|
||||
return ctrlTab.isOpen;
|
||||
}
|
||||
|
||||
function canOpen() {
|
||||
return gPrefService.getBoolPref("browser.ctrlTab.previews") && gBrowser.tabs.length > 2;
|
||||
}
|
||||
|
||||
function checkTabs(aTabs) {
|
||||
var tabs = gBrowser.tabs.length;
|
||||
if (tabs != aTabs) {
|
||||
@ -117,7 +141,7 @@ function test() {
|
||||
});
|
||||
}
|
||||
|
||||
function ctrlTabTest(tabsToSelect, tabTimes, expectedIndex) {
|
||||
function* ctrlTabTest(tabsToSelect, tabTimes, expectedIndex) {
|
||||
selectTabs(tabsToSelect);
|
||||
|
||||
var indexStart = gBrowser.tabContainer.selectedIndex;
|
||||
@ -127,7 +151,7 @@ function test() {
|
||||
normalized + " tabs back in most-recently-selected order";
|
||||
|
||||
for (let i = 0; i < tabTimes; i++) {
|
||||
pressCtrlTab();
|
||||
yield pressCtrlTab();
|
||||
|
||||
if (tabCount > 2)
|
||||
is(gBrowser.tabContainer.selectedIndex, indexStart,
|
||||
@ -138,7 +162,7 @@ function test() {
|
||||
ok(isOpen(),
|
||||
"With " + tabCount + " tabs open, Ctrl+Tab opens the preview panel");
|
||||
|
||||
releaseCtrl();
|
||||
yield releaseCtrl();
|
||||
|
||||
ok(!isOpen(),
|
||||
"Releasing Ctrl closes the preview panel");
|
||||
@ -151,4 +175,4 @@ function test() {
|
||||
"With "+ tabCount +" tabs open and tab " + indexStart
|
||||
+ " selected, Ctrl+Tab*" + tabTimes + " goes " + where);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -0,0 +1,9 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html><head><meta charset="utf-8">
|
||||
<title>Bug 1122236 - CSP: Implement block-all-mixed-content</title>
|
||||
</head>
|
||||
<meta http-equiv="Content-Security-Policy" content="block-all-mixed-content">
|
||||
<body>
|
||||
<script src="http://example.com/browser/browser/base/content/test/general/file_csp_block_all_mixedcontent.js"/>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,3 @@
|
||||
// empty script file just used for testing Bug 1122236.
|
||||
// Making sure the UI is not degraded when blocking
|
||||
// mixed content using the CSP directive: block-all-mixed-content.
|
@ -9,6 +9,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
|
||||
|
||||
Cu.import("resource://gre/modules/ExtensionUtils.jsm");
|
||||
Cu.import("resource://gre/modules/AddonManager.jsm");
|
||||
Cu.import("resource://gre/modules/AppConstants.jsm");
|
||||
|
||||
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
|
||||
@ -138,6 +139,25 @@ function promisePopupShown(popup) {
|
||||
});
|
||||
}
|
||||
|
||||
XPCOMUtils.defineLazyGetter(global, "stylesheets", () => {
|
||||
let styleSheetService = Cc["@mozilla.org/content/style-sheet-service;1"]
|
||||
.getService(Components.interfaces.nsIStyleSheetService);
|
||||
let styleSheetURI = Services.io.newURI("chrome://browser/content/extension.css",
|
||||
null, null);
|
||||
let styleSheet = styleSheetService.preloadSheet(styleSheetURI,
|
||||
styleSheetService.AGENT_SHEET);
|
||||
let stylesheets = [styleSheet];
|
||||
|
||||
if (AppConstants.platform === "macosx") {
|
||||
styleSheetURI = Services.io.newURI("chrome://browser/content/extension-mac.css",
|
||||
null, null);
|
||||
let macStyleSheet = styleSheetService.preloadSheet(styleSheetURI,
|
||||
styleSheetService.AGENT_SHEET);
|
||||
stylesheets.push(macStyleSheet);
|
||||
}
|
||||
return stylesheets;
|
||||
});
|
||||
|
||||
class BasePopup {
|
||||
constructor(extension, viewNode, popupURL) {
|
||||
let popupURI = Services.io.newURI(popupURL, null, extension.baseURI);
|
||||
@ -163,6 +183,7 @@ class BasePopup {
|
||||
|
||||
destroy() {
|
||||
this.browserReady.then(() => {
|
||||
this.browser.removeEventListener("DOMWindowCreated", this, true);
|
||||
this.browser.removeEventListener("load", this, true);
|
||||
this.browser.removeEventListener("DOMTitleChanged", this, true);
|
||||
this.browser.removeEventListener("DOMWindowClose", this, true);
|
||||
@ -190,6 +211,13 @@ class BasePopup {
|
||||
this.destroy();
|
||||
break;
|
||||
|
||||
case "DOMWindowCreated":
|
||||
let winUtils = this.browser.contentWindow
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
for (let stylesheet of global.stylesheets) {
|
||||
winUtils.addSheet(stylesheet, winUtils.AGENT_SHEET);
|
||||
}
|
||||
break;
|
||||
case "DOMWindowClose":
|
||||
if (event.target === this.browser.contentWindow) {
|
||||
event.preventDefault();
|
||||
@ -217,7 +245,6 @@ class BasePopup {
|
||||
|
||||
createBrowser(viewNode, popupURI) {
|
||||
let document = viewNode.ownerDocument;
|
||||
|
||||
this.browser = document.createElementNS(XUL_NS, "browser");
|
||||
this.browser.setAttribute("type", "content");
|
||||
this.browser.setAttribute("disableglobalhistory", "true");
|
||||
@ -259,6 +286,7 @@ class BasePopup {
|
||||
GlobalManager.injectInDocShell(this.browser.docShell, this.extension, this.context);
|
||||
this.browser.setAttribute("src", this.context.uri.spec);
|
||||
|
||||
this.browser.addEventListener("DOMWindowCreated", this, true);
|
||||
this.browser.addEventListener("load", this, true);
|
||||
this.browser.addEventListener("DOMTitleChanged", this, true);
|
||||
this.browser.addEventListener("DOMWindowClose", this, true);
|
||||
|
11
browser/components/extensions/extension-mac.css
Normal file
11
browser/components/extensions/extension-mac.css
Normal file
@ -0,0 +1,11 @@
|
||||
button,
|
||||
select,
|
||||
input[type="checkbox"] + label::before {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.panel-section-footer {
|
||||
border-bottom-left-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
572
browser/components/extensions/extension.css
Normal file
572
browser/components/extensions/extension.css
Normal file
@ -0,0 +1,572 @@
|
||||
/* stylelint-disable property-no-vendor-prefix */
|
||||
/* stylelint-disable property-no-vendor-prefix */
|
||||
/* Base */
|
||||
button,
|
||||
select,
|
||||
option,
|
||||
input {
|
||||
-moz-appearance: none;
|
||||
}
|
||||
|
||||
/* Variables */
|
||||
html,
|
||||
body {
|
||||
background-color: #fcfcfc;
|
||||
box-sizing: border-box;
|
||||
color: #222426;
|
||||
cursor: default;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font: caption;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
body * {
|
||||
box-sizing: border-box;
|
||||
text-align: start;
|
||||
}
|
||||
|
||||
/* stylelint-disable property-no-vendor-prefix */
|
||||
/* Buttons */
|
||||
button,
|
||||
select {
|
||||
background-color: #fbfbfb;
|
||||
border: 1px solid #b1b1b1;
|
||||
box-shadow: 0 0 0 0 transparent;
|
||||
font: caption;
|
||||
height: 24px;
|
||||
outline: 0 !important;
|
||||
padding: 0 8px 0;
|
||||
transition-duration: 250ms;
|
||||
transition-property: box-shadow, border;
|
||||
}
|
||||
|
||||
select {
|
||||
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgdmlld0JveD0iMCAwIDE2IDE2Ij4KICA8cGF0aCBkPSJNOCwxMkwzLDcsNCw2bDQsNCw0LTQsMSwxWiIgZmlsbD0iIzZBNkE2QSIgLz4KPC9zdmc+Cg==);
|
||||
background-position: calc(100% - 4px) center;
|
||||
background-repeat: no-repeat;
|
||||
-moz-padding-end: 24px;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
label {
|
||||
font: caption;
|
||||
}
|
||||
|
||||
button::-moz-focus-inner {
|
||||
border: 0;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
/* Dropdowns */
|
||||
select {
|
||||
background-color: #fbfbfb;
|
||||
border: 1px solid #b1b1b1;
|
||||
box-shadow: 0 0 0 0 transparent;
|
||||
font: caption;
|
||||
height: 24px;
|
||||
outline: 0 !important;
|
||||
padding: 0 8px 0;
|
||||
transition-duration: 250ms;
|
||||
transition-property: box-shadow, border;
|
||||
}
|
||||
|
||||
select {
|
||||
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgdmlld0JveD0iMCAwIDE2IDE2Ij4KICA8cGF0aCBkPSJNOCwxMkwzLDcsNCw2bDQsNCw0LTQsMSwxWiIgZmlsbD0iIzZBNkE2QSIgLz4KPC9zdmc+Cg==);
|
||||
background-position: calc(100% - 4px) center;
|
||||
background-repeat: no-repeat;
|
||||
-moz-padding-end: 24px;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
select:-moz-focusring {
|
||||
color: transparent;
|
||||
text-shadow: 0 0 0 #000;
|
||||
}
|
||||
|
||||
select:-moz-focusring * {
|
||||
color: #000;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
button.hover,
|
||||
select.hover {
|
||||
background-color: #ebebeb;
|
||||
border: 1px solid #b1b1b1;
|
||||
}
|
||||
|
||||
button.pressed,
|
||||
select.pressed {
|
||||
background-color: #d4d4d4;
|
||||
border: 1px solid #858585;
|
||||
}
|
||||
|
||||
button.disabled,
|
||||
select.disabled {
|
||||
color: #999;
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
button.focused,
|
||||
select.focused {
|
||||
border-color: #fff;
|
||||
box-shadow: 0 0 0 2px rgba(97, 181, 255, 0.75);
|
||||
}
|
||||
|
||||
button.default {
|
||||
background-color: #0996f8;
|
||||
border-color: #0670cc;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
button.default.hover {
|
||||
background-color: #0670cc;
|
||||
border-color: #005bab;
|
||||
}
|
||||
|
||||
button.default.pressed {
|
||||
background-color: #005bab;
|
||||
border-color: #004480;
|
||||
}
|
||||
|
||||
button.default.focused {
|
||||
border-color: #fff;
|
||||
}
|
||||
|
||||
/* Radio Buttons */
|
||||
.radioItem {
|
||||
margin-bottom: 6px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
input[type="radio"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
input[type="radio"] + label {
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
input[type="radio"] + label::before {
|
||||
background-color: #fff;
|
||||
background-position: center;
|
||||
border: 1px solid #b1b1b1;
|
||||
border-radius: 50%;
|
||||
content: "";
|
||||
display: inline-block;
|
||||
height: 16px;
|
||||
margin-right: 6px;
|
||||
vertical-align: text-top;
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
input[type="radio"]:hover + label::before,
|
||||
.radioItem.hover input[type="radio"]:not(active) + label::before {
|
||||
background-color: #fbfbfb;
|
||||
border-color: #b1b1b1;
|
||||
}
|
||||
|
||||
input[type="radio"]:hover:active + label::before,
|
||||
.radioItem.pressed input[type="radio"]:not(active) + label::before {
|
||||
background-color: #ebebeb;
|
||||
border-color: #858585;
|
||||
}
|
||||
|
||||
input[type="radio"]:checked + label::before {
|
||||
background-color: #0996f8;
|
||||
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgdmlld0JveD0iMCAwIDE2IDE2Ij4KICA8Y2lyY2xlIGN4PSI4IiBjeT0iOCIgcj0iNCIgZmlsbD0iI2ZmZiIgLz4KPC9zdmc+Cg==);
|
||||
border-color: #0670cc;
|
||||
}
|
||||
|
||||
input[type="radio"]:checked:hover + label::before,
|
||||
.radioItem.hover input[type="radio"]:checked:not(active) + label::before {
|
||||
background-color: #0670cc;
|
||||
border-color: #005bab;
|
||||
}
|
||||
|
||||
input[type="radio"]:checked:hover:active + label::before,
|
||||
.radioItem.pressed input[type="radio"]:checked:not(active) + label::before {
|
||||
background-color: #005bab;
|
||||
border-color: #004480;
|
||||
}
|
||||
|
||||
.radioItem.disabled input[type="radio"] + label,
|
||||
.radioItem.disabled input[type="radio"]:hover + label,
|
||||
.radioItem.disabled input[type="radio"]:hover:active + label {
|
||||
color: #999;
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
.radioItem.focused input[type="radio"] + label::before {
|
||||
border-color: #0996f8;
|
||||
box-shadow: 0 0 0 2px rgba(97, 181, 255, 0.75);
|
||||
}
|
||||
|
||||
.radioItem.focused input[type="radio"]:checked + label::before {
|
||||
border-color: #fff;
|
||||
}
|
||||
|
||||
/* Checkboxes */
|
||||
.checkboxItem {
|
||||
margin-bottom: 6px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
input[type="checkbox"] + label {
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
input[type="checkbox"] + label::before {
|
||||
background-color: #fff;
|
||||
background-position: center;
|
||||
border: 1px solid #b1b1b1;
|
||||
content: "";
|
||||
display: inline-block;
|
||||
height: 16px;
|
||||
margin-right: 6px;
|
||||
vertical-align: text-top;
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
input[type="checkbox"]:hover + label::before,
|
||||
.checkboxItem.hover input[type="checkbox"]:not(active) + label::before {
|
||||
background-color: #fbfbfb;
|
||||
border-color: #b1b1b1;
|
||||
}
|
||||
|
||||
input[type="checkbox"]:hover:active + label::before,
|
||||
.checkboxItem.pressed input[type="checkbox"]:not(active) + label::before {
|
||||
background-color: #ebebeb;
|
||||
border-color: #858585;
|
||||
}
|
||||
|
||||
input[type="checkbox"]:checked + label::before {
|
||||
background-color: #0996f8;
|
||||
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgdmlld0JveD0iMCAwIDE2IDE2Ij4KICA8cGF0aCBkPSJNNy43LDEyLjkgQzcuNCwxMy4zIDYuOCwxMy40IDYuNCwxMyBMMy4yLDkuOCBDMi44LDkuNCAyLjgsOC42IDMuMiw4LjIgQzMuNiw3LjggNC40LDcuOCA0LjgsOC4yIEw2LjksMTAuMyBMMTEuMSw0LjQgQzExLjUsMy45IDEyLjIsMy44IDEyLjcsNC4xIEMxMy4yLDQuNSAxMy4zLDUuMiAxMyw1LjcgTDcuNywxMi45IEw3LjcsMTIuOSBaIiBmaWxsPSIjZmZmIiAvPgo8L3N2Zz4K);
|
||||
border-color: #0670cc;
|
||||
}
|
||||
|
||||
input[type="checkbox"]:checked:hover + label::before,
|
||||
.checkboxItem.hover input[type="checkbox"]:checked:not(active) + label::before {
|
||||
background-color: #0670cc;
|
||||
border-color: #005bab;
|
||||
}
|
||||
|
||||
input[type="checkbox"]:checked:hover:active + label::before,
|
||||
.checkboxItem.pressed input[type="checkbox"]:checked:not(active) + label::before {
|
||||
background-color: #005bab;
|
||||
border-color: #004480;
|
||||
}
|
||||
|
||||
.checkboxItem.disabled input[type="checkbox"] + label,
|
||||
.checkboxItem.disabled input[type="checkbox"]:hover + label,
|
||||
.checkboxItem.disabled input[type="checkbox"]:hover:active + label {
|
||||
color: #999;
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
.checkboxItem.focused input[type="checkbox"] + label::before {
|
||||
border-color: #0996f8;
|
||||
box-shadow: 0 0 0 2px rgba(97, 181, 255, 0.75);
|
||||
}
|
||||
|
||||
.checkboxItem.focused input[type="checkbox"]:checked + label::before {
|
||||
border-color: #fff;
|
||||
}
|
||||
|
||||
/* Expander Button */
|
||||
button.expander {
|
||||
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgdmlld0JveD0iMCAwIDE2IDE2Ij4KICA8cGF0aCBkPSJNOCwxMkwzLDcsNCw2bDQsNCw0LTQsMSwxWiIgZmlsbD0iIzZBNkE2QSIgLz4KPC9zdmc+Cg==);
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
height: 24px;
|
||||
padding: 0;
|
||||
width: 24px;
|
||||
}
|
||||
|
||||
/* Interactive States */
|
||||
button:hover:not(.pressed):not(.disabled):not(.focused),
|
||||
select:hover:not(.pressed):not(.disabled):not(.focused) {
|
||||
background-color: #ebebeb;
|
||||
border: 1px solid #b1b1b1;
|
||||
}
|
||||
|
||||
button:hover:active:not(.hover):not(.disabled):not(.focused),
|
||||
select:hover:active:not(.hover):not(.disabled):not(.focused) {
|
||||
background-color: #d4d4d4;
|
||||
border: 1px solid #858585;
|
||||
}
|
||||
|
||||
button.default:hover:not(.pressed):not(.disabled):not(.focused) {
|
||||
background-color: #0670cc;
|
||||
border-color: #005bab;
|
||||
}
|
||||
|
||||
button.default:hover:active:not(.hover):not(.disabled):not(.focused) {
|
||||
background-color: #005bab;
|
||||
border-color: #004480;
|
||||
}
|
||||
|
||||
button:focus:not(.disabled) {
|
||||
border-color: #fff !important;
|
||||
box-shadow: 0 0 0 2px rgba(97, 181, 255, 0.75);
|
||||
}
|
||||
|
||||
/* Fields */
|
||||
input[type="text"],
|
||||
textarea {
|
||||
background-color: #fff;
|
||||
border: 1px solid #b1b1b1;
|
||||
box-shadow: 0 0 0 0 rgba(97, 181, 255, 0);
|
||||
font: caption;
|
||||
padding: 0 6px 0;
|
||||
transition-duration: 250ms;
|
||||
transition-property: box-shadow;
|
||||
}
|
||||
|
||||
input[type="text"] {
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
input[type="text"].hover,
|
||||
textarea.hover {
|
||||
border: 1px solid #858585;
|
||||
}
|
||||
|
||||
input[type="text"].disabled,
|
||||
textarea.disabled {
|
||||
color: #999;
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
input[type="text"].focused,
|
||||
textarea.focused {
|
||||
border-color: #0996f8;
|
||||
box-shadow: 0 0 0 2px rgba(97, 181, 255, 0.75);
|
||||
}
|
||||
|
||||
/* Interactive States */
|
||||
input[type="text"]:not(disabled):hover,
|
||||
textarea:not(disabled):hover {
|
||||
border: 1px solid #858585;
|
||||
}
|
||||
|
||||
input[type="text"]:focus,
|
||||
input[type="text"]:focus:hover,
|
||||
textarea:focus,
|
||||
textarea:focus:hover {
|
||||
border-color: #0996f8;
|
||||
box-shadow: 0 0 0 2px rgba(97, 181, 255, 0.75);
|
||||
}
|
||||
|
||||
/* stylelint-disable property-no-vendor-prefix */
|
||||
.panel-section {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.panel-section-separator {
|
||||
background-color: rgba(0, 0, 0, 0.15);
|
||||
min-height: 1px;
|
||||
}
|
||||
|
||||
/* Panel Section - Header */
|
||||
.panel-section-header {
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.15);
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.panel-section-header > .icon-section-header {
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
height: 32px;
|
||||
margin-right: 16px;
|
||||
position: relative;
|
||||
width: 32px;
|
||||
}
|
||||
|
||||
.panel-section-header > .text-section-header {
|
||||
align-self: center;
|
||||
font-size: 1.385em;
|
||||
font-weight: lighter;
|
||||
}
|
||||
|
||||
/* Panel Section - List */
|
||||
.panel-section-list {
|
||||
flex-direction: column;
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
.panel-list-item {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
height: 24px;
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
.panel-list-item:not(.disabled):hover {
|
||||
background-color: rgba(0, 0, 0, 0.06);
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.panel-list-item:not(.disabled):hover:active {
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.panel-list-item.disabled {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.panel-list-item > .icon {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.panel-list-item > .text {
|
||||
flex-grow: 10;
|
||||
}
|
||||
|
||||
.panel-list-item > .text-shortcut {
|
||||
color: #808080;
|
||||
font-family: "Lucida Grande", caption;
|
||||
font-size: .847em;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.panel-section-list .panel-section-separator {
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
/* Panel Section - Form Elements */
|
||||
.panel-section-formElements {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.panel-formElements-item {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.panel-formElements-item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.panel-formElements-item label {
|
||||
flex-shrink: 0;
|
||||
margin-right: 6px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.panel-formElements-item input[type="text"],
|
||||
.panel-formElements-item select {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
/* Panel Section - Footer */
|
||||
.panel-section-footer {
|
||||
background-color: rgba(0, 0, 0, 0.06);
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.15);
|
||||
color: #1a1a1a;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
height: 41px;
|
||||
margin-top: -1px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.panel-section-footer-button {
|
||||
flex: 1 1 auto;
|
||||
height: 100%;
|
||||
margin: 0 -1px;
|
||||
padding: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.panel-section-footer-button > .text-shortcut {
|
||||
color: #808080;
|
||||
font-family: "Lucida Grande", caption;
|
||||
font-size: .847em;
|
||||
}
|
||||
|
||||
.panel-section-footer-button:hover {
|
||||
background-color: rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
.panel-section-footer-button:hover:active {
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.panel-section-footer-button.default {
|
||||
background-color: #0996f8;
|
||||
box-shadow: 0 1px 0 #0670cc inset;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.panel-section-footer-button.default:hover {
|
||||
background-color: #0670cc;
|
||||
box-shadow: 0 1px 0 #005bab inset;
|
||||
}
|
||||
|
||||
.panel-section-footer-button.default:hover:active {
|
||||
background-color: #005bab;
|
||||
box-shadow: 0 1px 0 #004480 inset;
|
||||
}
|
||||
|
||||
.panel-section-footer-separator {
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
width: 1px;
|
||||
z-index: 99;
|
||||
}
|
||||
|
||||
/* Panel Section - Tabs */
|
||||
.panel-section-tabs {
|
||||
color: #1a1a1a;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
height: 41px;
|
||||
margin-bottom: -1px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.panel-section-tabs-button {
|
||||
flex: 1 1 auto;
|
||||
height: 100%;
|
||||
margin: 0 -1px;
|
||||
padding: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.panel-section-tabs-button:hover {
|
||||
background-color: rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
.panel-section-tabs-button:hover:active {
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.panel-section-tabs-button.selected {
|
||||
box-shadow: 0 -1px 0 #0670cc inset, 0 -4px 0 #0996f8 inset;
|
||||
color: #0996f8;
|
||||
}
|
||||
|
||||
.panel-section-tabs-button.selected:hover {
|
||||
color: #0670cc;
|
||||
}
|
||||
|
||||
.panel-section-tabs-separator {
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
width: 1px;
|
||||
z-index: 99;
|
||||
}
|
@ -3,6 +3,8 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
browser.jar:
|
||||
content/browser/extension.css
|
||||
content/browser/extension-mac.css
|
||||
content/browser/extension.svg
|
||||
content/browser/ext-utils.js
|
||||
content/browser/ext-commands.js
|
||||
|
@ -3,7 +3,7 @@
|
||||
"use strict";
|
||||
|
||||
function* testInArea(area) {
|
||||
let scriptPage = url => `<html><head><meta charset="utf-8"><script src="${url}"></script></head></html>`;
|
||||
let scriptPage = url => `<html><head><meta charset="utf-8"><script src="${url}"></script></head><body>${url}</body></html>`;
|
||||
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
@ -18,7 +18,13 @@ function* testInArea(area) {
|
||||
files: {
|
||||
"popup-a.html": scriptPage("popup-a.js"),
|
||||
"popup-a.js": function() {
|
||||
browser.runtime.sendMessage("from-popup-a");
|
||||
window.onload = () => {
|
||||
if (window.getComputedStyle(document.body).backgroundColor == "rgb(252, 252, 252)") {
|
||||
browser.runtime.sendMessage("from-popup-a");
|
||||
} else {
|
||||
browser.runtime.sendMessage("popup-a-failed-style-check");
|
||||
}
|
||||
};
|
||||
browser.runtime.onMessage.addListener(msg => {
|
||||
if (msg == "close-popup") {
|
||||
window.close();
|
||||
@ -74,6 +80,8 @@ function* testInArea(area) {
|
||||
browser.runtime.onMessage.addListener(msg => {
|
||||
if (msg == "close-popup") {
|
||||
return;
|
||||
} else if (msg == "popup-a-failed-style-check") {
|
||||
browser.test.fail("popup failed style check");
|
||||
} else if (expect.popup) {
|
||||
browser.test.assertEq(msg, `from-popup-${expect.popup}`,
|
||||
"expected popup opened");
|
||||
|
@ -255,6 +255,14 @@ panelmultiview[nosubviews=true] > .panel-viewcontainer > .panel-viewstack > .pan
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
.cui-widget-panel[viewId^=PanelUI-webext-] > .panel-arrowcontainer > .panel-arrowcontent {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.cui-widget-panelview[id^=PanelUI-webext-] {
|
||||
border-radius: 3.5px;
|
||||
}
|
||||
|
||||
panelview:not([mainview]) .toolbarbutton-text,
|
||||
.cui-widget-panel toolbarbutton > .toolbarbutton-text {
|
||||
text-align: start;
|
||||
|
@ -49,7 +49,7 @@ def checking(what):
|
||||
# use that value instead.
|
||||
@template
|
||||
def check_prog(var, progs, allow_missing=False):
|
||||
option(env=var, nargs=1, help=var)
|
||||
option(env=var, nargs=1, help='Path to the %s program' % var.lower())
|
||||
|
||||
not_found = 'not found'
|
||||
progs = list(progs)
|
||||
|
@ -260,6 +260,7 @@ def wanted_mozconfig_variables(help):
|
||||
'MOZ_BUILD_APP',
|
||||
'PERL',
|
||||
'RPMBUILD',
|
||||
'TAR',
|
||||
'UNZIP',
|
||||
'XARGS',
|
||||
'ZIP',
|
||||
@ -404,6 +405,7 @@ def split_triplet(triplet):
|
||||
kernel=canonical_kernel,
|
||||
os=canonical_os,
|
||||
raw_cpu=cpu,
|
||||
raw_os=os,
|
||||
)
|
||||
|
||||
|
||||
@ -466,6 +468,9 @@ def target_variables(target):
|
||||
if target.cpu in ('x86', 'x86_64'):
|
||||
set_config('INTEL_ARCHITECTURE', '1')
|
||||
|
||||
set_config('TARGET_CPU', target.raw_cpu)
|
||||
set_config('TARGET_OS', target.raw_os)
|
||||
|
||||
@depends(host)
|
||||
def host_variables(host):
|
||||
if host.kernel == 'kFreeBSD':
|
||||
|
@ -81,10 +81,10 @@ check_mozconfig_variables()
|
||||
|
||||
|
||||
@depends('OLD_CONFIGURE', mozconfig, autoconf, check_build_environment, shell,
|
||||
old_configure_assignments)
|
||||
old_configure_assignments, build_project)
|
||||
@advanced
|
||||
def prepare_configure(old_configure, mozconfig, autoconf, build_env, shell,
|
||||
old_configure_assignments):
|
||||
old_configure_assignments, build_project):
|
||||
import glob
|
||||
import itertools
|
||||
import subprocess
|
||||
@ -98,6 +98,11 @@ def prepare_configure(old_configure, mozconfig, autoconf, build_env, shell,
|
||||
# as $0, and backslashes there breaks autoconf's detection of the source
|
||||
# directory.
|
||||
old_configure = os.path.abspath(old_configure[0])
|
||||
if build_project == 'js':
|
||||
old_configure_dir = os.path.dirname(old_configure)
|
||||
if not old_configure_dir.endswith('/js/src'):
|
||||
old_configure = os.path.join(old_configure_dir, 'js', 'src',
|
||||
os.path.basename(old_configure))
|
||||
|
||||
refresh = True
|
||||
if os.path.exists(old_configure):
|
||||
@ -137,6 +142,10 @@ def prepare_configure(old_configure, mozconfig, autoconf, build_env, shell,
|
||||
for key in mozconfig[t]['removed'].keys():
|
||||
print("unset %s" % key, file=out)
|
||||
|
||||
# Autoconf is special, because it might be passed from
|
||||
# mozconfig['make_extra'], which we don't pass automatically above.
|
||||
print('export AUTOCONF=%s' % quote(autoconf), file=out)
|
||||
|
||||
for assignment in old_configure_assignments:
|
||||
print(assignment, file=out)
|
||||
|
||||
|
@ -24,6 +24,10 @@ def main(argv):
|
||||
if sandbox._help:
|
||||
return 0
|
||||
|
||||
return config_status(config)
|
||||
|
||||
|
||||
def config_status(config):
|
||||
# Sanitize config data to feed config.status
|
||||
sanitized_config = {}
|
||||
sanitized_config['substs'] = {
|
||||
@ -43,6 +47,10 @@ def main(argv):
|
||||
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')
|
||||
for k, v in sanitized_config.iteritems():
|
||||
fh.write('%s = ' % k)
|
||||
json.dump(v, fh, sort_keys=True, indent=4, ensure_ascii=False)
|
||||
@ -69,5 +77,6 @@ if __name__ == '__main__':
|
||||
return subprocess.call([config['PYTHON'], 'config.status'])
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main(sys.argv))
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -27,6 +27,7 @@ const POLICY_REPORT_ONLY = "report-only"
|
||||
|
||||
// special handling of directives
|
||||
const DIR_UPGRADE_INSECURE = "upgrade-insecure-requests";
|
||||
const DIR_BLOCK_ALL_MIXED_CONTENT = "block-all-mixed-content";
|
||||
|
||||
// special handling of sources
|
||||
const SRC_UNSAFE_INLINE = "'unsafe-inline'";
|
||||
@ -89,13 +90,15 @@ exports.items = [
|
||||
// loop over all the directive-sources within that directive
|
||||
var outSrcs = [];
|
||||
|
||||
// special case handling for upgrade-insecure-requests
|
||||
// which does not have any srcs
|
||||
if (dir === DIR_UPGRADE_INSECURE) {
|
||||
// special case handling for the directives
|
||||
// upgrade-insecure-requests and block-all-mixed-content
|
||||
// which do not include any srcs
|
||||
if (dir === DIR_UPGRADE_INSECURE ||
|
||||
dir === DIR_BLOCK_ALL_MIXED_CONTENT) {
|
||||
outSrcs.push({
|
||||
icon: GOOD_IMG_SRC,
|
||||
src: "", // no src for upgrade-insecure-requests
|
||||
desc: "" // no description for upgrade-insecure-requests
|
||||
src: "", // no src
|
||||
desc: "" // no description
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -334,7 +334,9 @@ AutoJSAPI::InitInternal(JSObject* aGlobal, JSContext* aCx, bool aIsMainThread)
|
||||
{
|
||||
MOZ_ASSERT(aCx);
|
||||
MOZ_ASSERT(aIsMainThread == NS_IsMainThread());
|
||||
MOZ_ASSERT(!JS_IsExceptionPending(aCx));
|
||||
#ifdef DEBUG
|
||||
bool haveException = JS_IsExceptionPending(aCx);
|
||||
#endif // DEBUG
|
||||
|
||||
mCx = aCx;
|
||||
mIsMainThread = aIsMainThread;
|
||||
@ -356,6 +358,72 @@ AutoJSAPI::InitInternal(JSObject* aGlobal, JSContext* aCx, bool aIsMainThread)
|
||||
if (aIsMainThread) {
|
||||
JS_SetErrorReporter(rt, xpc::SystemErrorReporter);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (haveException) {
|
||||
JS::Rooted<JS::Value> exn(aCx);
|
||||
JS_GetPendingException(aCx, &exn);
|
||||
|
||||
JS_ClearPendingException(aCx);
|
||||
if (exn.isObject()) {
|
||||
JS::Rooted<JSObject*> exnObj(aCx, &exn.toObject());
|
||||
|
||||
nsAutoJSString stack, filename, name, message;
|
||||
int32_t line;
|
||||
|
||||
JS::Rooted<JS::Value> tmp(aCx);
|
||||
if (!JS_GetProperty(aCx, exnObj, "filename", &tmp)) {
|
||||
JS_ClearPendingException(aCx);
|
||||
}
|
||||
if (tmp.isUndefined()) {
|
||||
if (!JS_GetProperty(aCx, exnObj, "fileName", &tmp)) {
|
||||
JS_ClearPendingException(aCx);
|
||||
}
|
||||
}
|
||||
|
||||
if (!filename.init(aCx, tmp)) {
|
||||
JS_ClearPendingException(aCx);
|
||||
}
|
||||
|
||||
if (!JS_GetProperty(aCx, exnObj, "stack", &tmp) ||
|
||||
!stack.init(aCx, tmp)) {
|
||||
JS_ClearPendingException(aCx);
|
||||
}
|
||||
|
||||
if (!JS_GetProperty(aCx, exnObj, "name", &tmp) ||
|
||||
!name.init(aCx, tmp)) {
|
||||
JS_ClearPendingException(aCx);
|
||||
}
|
||||
|
||||
if (!JS_GetProperty(aCx, exnObj, "message", &tmp) ||
|
||||
!message.init(aCx, tmp)) {
|
||||
JS_ClearPendingException(aCx);
|
||||
}
|
||||
|
||||
if (!JS_GetProperty(aCx, exnObj, "lineNumber", &tmp) ||
|
||||
!JS::ToInt32(aCx, tmp, &line)) {
|
||||
JS_ClearPendingException(aCx);
|
||||
line = 0;
|
||||
}
|
||||
|
||||
printf_stderr("PREEXISTING EXCEPTION OBJECT: '%s: %s'\n%s:%d\n%s\n",
|
||||
NS_ConvertUTF16toUTF8(name).get(),
|
||||
NS_ConvertUTF16toUTF8(message).get(),
|
||||
NS_ConvertUTF16toUTF8(filename).get(), line,
|
||||
NS_ConvertUTF16toUTF8(stack).get());
|
||||
} else {
|
||||
// It's a primitive... not much we can do other than stringify it.
|
||||
nsAutoJSString exnStr;
|
||||
if (!exnStr.init(aCx, exn)) {
|
||||
JS_ClearPendingException(aCx);
|
||||
}
|
||||
|
||||
printf_stderr("PREEXISTING EXCEPTION PRIMITIVE: %s\n",
|
||||
NS_ConvertUTF16toUTF8(exnStr).get());
|
||||
}
|
||||
MOZ_ASSERT(false, "We had an exception; we should not have");
|
||||
}
|
||||
#endif // DEBUG
|
||||
}
|
||||
|
||||
AutoJSAPI::AutoJSAPI(nsIGlobalObject* aGlobalObject,
|
||||
|
@ -197,7 +197,8 @@ TextInputProcessor::BeginInputTransactionInternal(
|
||||
}
|
||||
|
||||
if (aForTests) {
|
||||
rv = dispatcher->BeginInputTransactionForTests(this);
|
||||
bool isAPZAware = gfxPrefs::TestEventsAsyncEnabled();
|
||||
rv = dispatcher->BeginTestInputTransaction(this, isAPZAware);
|
||||
} else {
|
||||
rv = dispatcher->BeginInputTransaction(this);
|
||||
}
|
||||
@ -631,8 +632,11 @@ TextInputProcessor::NotifyIME(TextEventDispatcher* aTextEventDispatcher,
|
||||
const IMENotification& aNotification)
|
||||
{
|
||||
// If This is called while this is being initialized, ignore the call.
|
||||
// In such case, this method should return NS_ERROR_NOT_IMPLEMENTED because
|
||||
// we can say, TextInputProcessor doesn't implement any handlers of the
|
||||
// requests and notifications.
|
||||
if (!mDispatcher) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
MOZ_ASSERT(aTextEventDispatcher == mDispatcher,
|
||||
"Wrong TextEventDispatcher notifies this");
|
||||
@ -701,6 +705,16 @@ TextInputProcessor::OnRemovedFrom(TextEventDispatcher* aTextEventDispatcher)
|
||||
UnlinkFromTextEventDispatcher();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(void)
|
||||
TextInputProcessor::WillDispatchKeyboardEvent(
|
||||
TextEventDispatcher* aTextEventDispatcher,
|
||||
WidgetKeyboardEvent& aKeyboardEvent,
|
||||
uint32_t aIndexOfKeypress,
|
||||
void* aData)
|
||||
{
|
||||
// TextInputProcessor doesn't set alternative char code.
|
||||
}
|
||||
|
||||
nsresult
|
||||
TextInputProcessor::PrepareKeyboardEventToDispatch(
|
||||
WidgetKeyboardEvent& aKeyboardEvent,
|
||||
@ -776,23 +790,6 @@ TextInputProcessor::Keydown(nsIDOMKeyEvent* aDOMKeyEvent,
|
||||
return KeydownInternal(*originalKeyEvent, aKeyFlags, true, *aConsumedFlags);
|
||||
}
|
||||
|
||||
TextEventDispatcher::DispatchTo
|
||||
TextInputProcessor::GetDispatchTo() const
|
||||
{
|
||||
// Support asynchronous tests.
|
||||
if (mForTests) {
|
||||
return gfxPrefs::TestEventsAsyncEnabled() ?
|
||||
TextEventDispatcher::eDispatchToParentProcess :
|
||||
TextEventDispatcher::eDispatchToCurrentProcess;
|
||||
}
|
||||
|
||||
// Otherwise, TextInputProcessor supports only keyboard apps on B2G.
|
||||
// Keyboard apps on B2G doesn't want to dispatch keyboard events to
|
||||
// chrome process. Therefore, this should dispatch key events only in
|
||||
// the current process.
|
||||
return TextEventDispatcher::eDispatchToCurrentProcess;
|
||||
}
|
||||
|
||||
nsresult
|
||||
TextInputProcessor::KeydownInternal(const WidgetKeyboardEvent& aKeyboardEvent,
|
||||
uint32_t aKeyFlags,
|
||||
@ -838,8 +835,7 @@ TextInputProcessor::KeydownInternal(const WidgetKeyboardEvent& aKeyboardEvent,
|
||||
|
||||
nsEventStatus status = aConsumedFlags ? nsEventStatus_eConsumeNoDefault :
|
||||
nsEventStatus_eIgnore;
|
||||
if (!mDispatcher->DispatchKeyboardEvent(eKeyDown, keyEvent, status,
|
||||
GetDispatchTo())) {
|
||||
if (!mDispatcher->DispatchKeyboardEvent(eKeyDown, keyEvent, status)) {
|
||||
// If keydown event isn't dispatched, we don't need to dispatch keypress
|
||||
// events.
|
||||
return NS_OK;
|
||||
@ -850,8 +846,7 @@ TextInputProcessor::KeydownInternal(const WidgetKeyboardEvent& aKeyboardEvent,
|
||||
KEYEVENT_NOT_CONSUMED;
|
||||
|
||||
if (aAllowToDispatchKeypress &&
|
||||
mDispatcher->MaybeDispatchKeypressEvents(keyEvent, status,
|
||||
GetDispatchTo())) {
|
||||
mDispatcher->MaybeDispatchKeypressEvents(keyEvent, status)) {
|
||||
aConsumedFlags |=
|
||||
(status == nsEventStatus_eConsumeNoDefault) ? KEYPRESS_IS_CONSUMED :
|
||||
KEYEVENT_NOT_CONSUMED;
|
||||
@ -920,7 +915,7 @@ TextInputProcessor::KeyupInternal(const WidgetKeyboardEvent& aKeyboardEvent,
|
||||
|
||||
nsEventStatus status = aDoDefault ? nsEventStatus_eIgnore :
|
||||
nsEventStatus_eConsumeNoDefault;
|
||||
mDispatcher->DispatchKeyboardEvent(eKeyUp, keyEvent, status, GetDispatchTo());
|
||||
mDispatcher->DispatchKeyboardEvent(eKeyUp, keyEvent, status);
|
||||
aDoDefault = (status != nsEventStatus_eConsumeNoDefault);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -36,6 +36,12 @@ public:
|
||||
NS_IMETHOD_(void)
|
||||
OnRemovedFrom(TextEventDispatcher* aTextEventDispatcher) override;
|
||||
|
||||
NS_IMETHOD_(void) WillDispatchKeyboardEvent(
|
||||
TextEventDispatcher* aTextEventDispatcher,
|
||||
WidgetKeyboardEvent& aKeyboardEvent,
|
||||
uint32_t aIndexOfKeypress,
|
||||
void* aData) override;
|
||||
|
||||
protected:
|
||||
virtual ~TextInputProcessor();
|
||||
|
||||
@ -61,7 +67,6 @@ private:
|
||||
nsresult KeyupInternal(const WidgetKeyboardEvent& aKeyboardEvent,
|
||||
uint32_t aKeyFlags,
|
||||
bool& aDoDefault);
|
||||
TextEventDispatcher::DispatchTo GetDispatchTo() const;
|
||||
nsresult IsValidStateForComposition();
|
||||
void UnlinkFromTextEventDispatcher();
|
||||
nsresult PrepareKeyboardEventToDispatch(WidgetKeyboardEvent& aKeyboardEvent,
|
||||
|
@ -1429,6 +1429,8 @@ nsIDocument::nsIDocument()
|
||||
: nsINode(nullNodeInfo),
|
||||
mReferrerPolicySet(false),
|
||||
mReferrerPolicy(mozilla::net::RP_Default),
|
||||
mBlockAllMixedContent(false),
|
||||
mBlockAllMixedContentPreloads(false),
|
||||
mUpgradeInsecureRequests(false),
|
||||
mUpgradeInsecurePreloads(false),
|
||||
mCharacterSet(NS_LITERAL_CSTRING("ISO-8859-1")),
|
||||
@ -2592,13 +2594,18 @@ nsDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
|
||||
nsCOMPtr<nsIDocShellTreeItem> sameTypeParent;
|
||||
treeItem->GetSameTypeParent(getter_AddRefs(sameTypeParent));
|
||||
if (sameTypeParent) {
|
||||
mUpgradeInsecureRequests =
|
||||
sameTypeParent->GetDocument()->GetUpgradeInsecureRequests(false);
|
||||
nsIDocument* doc = sameTypeParent->GetDocument();
|
||||
mBlockAllMixedContent = doc->GetBlockAllMixedContent(false);
|
||||
// if the parent document makes use of block-all-mixed-content
|
||||
// then subdocument preloads should always be blocked.
|
||||
mBlockAllMixedContentPreloads =
|
||||
mBlockAllMixedContent || doc->GetBlockAllMixedContent(true);
|
||||
|
||||
mUpgradeInsecureRequests = doc->GetUpgradeInsecureRequests(false);
|
||||
// if the parent document makes use of upgrade-insecure-requests
|
||||
// then subdocument preloads should always be upgraded.
|
||||
mUpgradeInsecurePreloads =
|
||||
mUpgradeInsecureRequests ||
|
||||
sameTypeParent->GetDocument()->GetUpgradeInsecureRequests(true);
|
||||
mUpgradeInsecureRequests || doc->GetUpgradeInsecureRequests(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2697,6 +2704,16 @@ nsDocument::ApplySettingsFromCSP(bool aSpeculative)
|
||||
mReferrerPolicy = static_cast<ReferrerPolicy>(referrerPolicy);
|
||||
mReferrerPolicySet = true;
|
||||
}
|
||||
|
||||
// Set up 'block-all-mixed-content' if not already inherited
|
||||
// from the parent context or set by any other CSP.
|
||||
if (!mBlockAllMixedContent) {
|
||||
rv = csp->GetBlockAllMixedContent(&mBlockAllMixedContent);
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
}
|
||||
if (!mBlockAllMixedContentPreloads) {
|
||||
mBlockAllMixedContentPreloads = mBlockAllMixedContent;
|
||||
}
|
||||
|
||||
// Set up 'upgrade-insecure-requests' if not already inherited
|
||||
// from the parent context or set by any other CSP.
|
||||
@ -2712,12 +2729,17 @@ nsDocument::ApplySettingsFromCSP(bool aSpeculative)
|
||||
}
|
||||
|
||||
// 2) apply settings from speculative csp
|
||||
if (!mUpgradeInsecurePreloads) {
|
||||
nsCOMPtr<nsIContentSecurityPolicy> preloadCsp;
|
||||
rv = NodePrincipal()->GetPreloadCsp(getter_AddRefs(preloadCsp));
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
if (preloadCsp) {
|
||||
preloadCsp->GetUpgradeInsecureRequests(&mUpgradeInsecurePreloads);
|
||||
nsCOMPtr<nsIContentSecurityPolicy> preloadCsp;
|
||||
rv = NodePrincipal()->GetPreloadCsp(getter_AddRefs(preloadCsp));
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
if (preloadCsp) {
|
||||
if (!mBlockAllMixedContentPreloads) {
|
||||
rv = preloadCsp->GetBlockAllMixedContent(&mBlockAllMixedContentPreloads);
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
}
|
||||
if (!mUpgradeInsecurePreloads) {
|
||||
rv = preloadCsp->GetUpgradeInsecureRequests(&mUpgradeInsecurePreloads);
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -401,50 +401,66 @@ nsHTMLContentSerializer::AppendElementEnd(Element* aElement,
|
||||
}
|
||||
|
||||
static const uint16_t kValNBSP = 160;
|
||||
static const char* kEntities[] = {
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "&", nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
"<", nullptr, ">", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
" "
|
||||
|
||||
#define _ 0
|
||||
|
||||
// This table indexes into kEntityStrings[].
|
||||
static const uint8_t kEntities[] = {
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
_, _, _, _, _, _, _, _, 2, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
3, _, 4, _, _, _, _, _, _, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
5
|
||||
};
|
||||
|
||||
static const char* kAttrEntities[] = {
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, """, nullptr, nullptr, nullptr, "&", nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
"<", nullptr, ">", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
" "
|
||||
// This table indexes into kEntityStrings[].
|
||||
static const uint8_t kAttrEntities[] = {
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
_, _, _, _, 1, _, _, _, 2, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
3, _, 4, _, _, _, _, _, _, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
5
|
||||
};
|
||||
|
||||
#undef _
|
||||
|
||||
static const char* const kEntityStrings[] = {
|
||||
/* 0 */ nullptr,
|
||||
/* 1 */ """,
|
||||
/* 2 */ "&",
|
||||
/* 3 */ "<",
|
||||
/* 4 */ ">",
|
||||
/* 5 */ " "
|
||||
};
|
||||
|
||||
uint32_t FindNextBasicEntity(const nsAString& aStr,
|
||||
const uint32_t aLen,
|
||||
uint32_t aIndex,
|
||||
const char** aEntityTable,
|
||||
const uint8_t* aEntityTable,
|
||||
const char** aEntity)
|
||||
{
|
||||
for (; aIndex < aLen; ++aIndex) {
|
||||
@ -452,7 +468,7 @@ uint32_t FindNextBasicEntity(const nsAString& aStr,
|
||||
// needs to be replaced
|
||||
char16_t val = aStr[aIndex];
|
||||
if (val <= kValNBSP && aEntityTable[val]) {
|
||||
*aEntity = aEntityTable[val];
|
||||
*aEntity = kEntityStrings[aEntityTable[val]];
|
||||
return aIndex;
|
||||
}
|
||||
}
|
||||
@ -478,7 +494,7 @@ nsHTMLContentSerializer::AppendAndTranslateEntities(const nsAString& aStr,
|
||||
|
||||
if (!nonBasicEntities &&
|
||||
(mFlags & (nsIDocumentEncoder::OutputEncodeBasicEntities))) {
|
||||
const char **entityTable = mInAttribute ? kAttrEntities : kEntities;
|
||||
const uint8_t* entityTable = mInAttribute ? kAttrEntities : kEntities;
|
||||
uint32_t start = 0;
|
||||
const uint32_t len = aStr.Length();
|
||||
for (uint32_t i = 0; i < len; ++i) {
|
||||
@ -510,7 +526,7 @@ nsHTMLContentSerializer::AppendAndTranslateEntities(const nsAString& aStr,
|
||||
uint32_t advanceLength = 0;
|
||||
nsReadingIterator<char16_t> iter;
|
||||
|
||||
const char **entityTable = mInAttribute ? kAttrEntities : kEntities;
|
||||
const uint8_t* entityTable = mInAttribute ? kAttrEntities : kEntities;
|
||||
nsAutoCString entityReplacement;
|
||||
|
||||
for (aStr.BeginReading(iter);
|
||||
@ -532,7 +548,7 @@ nsHTMLContentSerializer::AppendAndTranslateEntities(const nsAString& aStr,
|
||||
for (; c < fragmentEnd; c++, advanceLength++) {
|
||||
char16_t val = *c;
|
||||
if (val <= kValNBSP && entityTable[val]) {
|
||||
fullConstEntityText = entityTable[val];
|
||||
fullConstEntityText = kEntityStrings[entityTable[val]];
|
||||
break;
|
||||
} else if (val > 127 &&
|
||||
((val < 256 &&
|
||||
|
@ -316,6 +316,19 @@ public:
|
||||
return GetReferrerPolicy();
|
||||
}
|
||||
|
||||
/**
|
||||
* If true, this flag indicates that all mixed content subresource
|
||||
* loads for this document (and also embeded browsing contexts) will
|
||||
* be blocked.
|
||||
*/
|
||||
bool GetBlockAllMixedContent(bool aPreload) const
|
||||
{
|
||||
if (aPreload) {
|
||||
return mBlockAllMixedContentPreloads;
|
||||
}
|
||||
return mBlockAllMixedContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* If true, this flag indicates that all subresource loads for this
|
||||
* document need to be upgraded from http to https.
|
||||
@ -2766,6 +2779,8 @@ protected:
|
||||
bool mReferrerPolicySet;
|
||||
ReferrerPolicyEnum mReferrerPolicy;
|
||||
|
||||
bool mBlockAllMixedContent;
|
||||
bool mBlockAllMixedContentPreloads;
|
||||
bool mUpgradeInsecureRequests;
|
||||
bool mUpgradeInsecurePreloads;
|
||||
|
||||
|
@ -1193,24 +1193,39 @@ nsXMLContentSerializer::AppendToString(const nsAString& aStr,
|
||||
|
||||
|
||||
static const uint16_t kGTVal = 62;
|
||||
static const char* kEntities[] = {
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "&", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"<", "", ">"
|
||||
|
||||
#define _ 0
|
||||
|
||||
// This table indexes into kEntityStrings[].
|
||||
static const uint8_t kEntities[] = {
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
_, _, _, _, _, _, _, _, 2, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
3, _, 4
|
||||
};
|
||||
|
||||
static const char* kAttrEntities[] = {
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", """, "", "", "", "&", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"<", "", ">"
|
||||
// This table indexes into kEntityStrings[].
|
||||
static const uint8_t kAttrEntities[] = {
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
_, _, _, _, 1, _, _, _, 2, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
_, _, _, _, _, _, _, _, _, _,
|
||||
3, _, 4
|
||||
};
|
||||
|
||||
#undef _
|
||||
|
||||
static const char* const kEntityStrings[] = {
|
||||
/* 0 */ nullptr,
|
||||
/* 1 */ """,
|
||||
/* 2 */ "&",
|
||||
/* 3 */ "<",
|
||||
/* 4 */ ">",
|
||||
};
|
||||
|
||||
bool
|
||||
@ -1224,7 +1239,7 @@ nsXMLContentSerializer::AppendAndTranslateEntities(const nsAString& aStr,
|
||||
uint32_t advanceLength = 0;
|
||||
nsReadingIterator<char16_t> iter;
|
||||
|
||||
const char **entityTable = mInAttribute ? kAttrEntities : kEntities;
|
||||
const uint8_t* entityTable = mInAttribute ? kAttrEntities : kEntities;
|
||||
|
||||
for (aStr.BeginReading(iter);
|
||||
iter != done_reading;
|
||||
@ -1240,8 +1255,8 @@ nsXMLContentSerializer::AppendAndTranslateEntities(const nsAString& aStr,
|
||||
// needs to be replaced
|
||||
for (; c < fragmentEnd; c++, advanceLength++) {
|
||||
char16_t val = *c;
|
||||
if ((val <= kGTVal) && (entityTable[val][0] != 0)) {
|
||||
entityText = entityTable[val];
|
||||
if ((val <= kGTVal) && entityTable[val]) {
|
||||
entityText = kEntityStrings[entityTable[val]];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -55,7 +55,7 @@
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
JSErrorFormatString ErrorFormatString[] = {
|
||||
const JSErrorFormatString ErrorFormatString[] = {
|
||||
#define MSG_DEF(_name, _argc, _exn, _str) \
|
||||
{ #_name, _str, _argc, _exn },
|
||||
#include "mozilla/dom/Errors.msg"
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "GLContext.h"
|
||||
#include "WebGLContext.h"
|
||||
#include "WebGLTimerQuery.h"
|
||||
#include "gfxPrefs.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@ -117,6 +118,7 @@ WebGLExtensionDisjointTimerQuery::EndQueryEXT(GLenum target)
|
||||
|
||||
mContext->MakeContextCurrent();
|
||||
mContext->GL()->fEndQuery(target);
|
||||
mActiveQuery->QueueAvailablity();
|
||||
mActiveQuery = nullptr;
|
||||
}
|
||||
|
||||
@ -139,6 +141,7 @@ WebGLExtensionDisjointTimerQuery::QueryCounterEXT(WebGLTimerQuery* query,
|
||||
mContext->MakeContextCurrent();
|
||||
mContext->GL()->fQueryCounter(query->mGLName, target);
|
||||
query->mTarget = LOCAL_GL_TIMESTAMP_EXT;
|
||||
query->QueueAvailablity();
|
||||
}
|
||||
|
||||
void
|
||||
@ -221,7 +224,8 @@ WebGLExtensionDisjointTimerQuery::GetQueryObjectEXT(JSContext* cx,
|
||||
mContext->GL()->fGetQueryObjectuiv(query->mGLName,
|
||||
LOCAL_GL_QUERY_RESULT_AVAILABLE_EXT,
|
||||
&avail);
|
||||
retval.set(JS::BooleanValue(bool(avail)));
|
||||
bool canBeAvailable = query->CanBeAvailable() || gfxPrefs::WebGLImmediateQueries();
|
||||
retval.set(JS::BooleanValue(bool(avail) && canBeAvailable));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -118,7 +118,7 @@ ShaderOutput(gl::GLContext* gl)
|
||||
}
|
||||
}
|
||||
|
||||
return SH_GLSL_OUTPUT;
|
||||
return SH_GLSL_COMPATIBILITY_OUTPUT;
|
||||
}
|
||||
|
||||
webgl::ShaderValidator*
|
||||
@ -129,7 +129,7 @@ WebGLContext::CreateShaderValidator(GLenum shaderType) const
|
||||
|
||||
ShShaderSpec spec = IsWebGL2() ? SH_WEBGL2_SPEC : SH_WEBGL_SPEC;
|
||||
ShShaderOutput outputLanguage = gl->IsGLES() ? SH_ESSL_OUTPUT
|
||||
: SH_GLSL_OUTPUT;
|
||||
: SH_GLSL_COMPATIBILITY_OUTPUT;
|
||||
|
||||
// If we're using WebGL2 we want a more specific version of GLSL
|
||||
if (IsWebGL2())
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "mozilla/dom/WebGLRenderingContextBinding.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "WebGLContext.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@ -23,6 +24,7 @@ WebGLTimerQuery::WebGLTimerQuery(WebGLContext* webgl, GLuint name)
|
||||
: WebGLContextBoundObject(webgl)
|
||||
, mGLName(name)
|
||||
, mTarget(LOCAL_GL_NONE)
|
||||
, mCanBeAvailable(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -53,6 +55,12 @@ WebGLTimerQuery::GetParentObject() const
|
||||
return mContext;
|
||||
}
|
||||
|
||||
void
|
||||
WebGLTimerQuery::QueueAvailablity()
|
||||
{
|
||||
RefPtr<WebGLTimerQuery> self = this;
|
||||
NS_DispatchToCurrentThread(NS_NewRunnableFunction([self] { self->mCanBeAvailable = true; }));
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLTimerQuery)
|
||||
|
||||
|
@ -24,6 +24,8 @@ public:
|
||||
void Delete();
|
||||
|
||||
bool HasEverBeenBound() const { return mTarget != LOCAL_GL_NONE; }
|
||||
bool CanBeAvailable() const { return mCanBeAvailable; }
|
||||
void QueueAvailablity();
|
||||
GLenum Target() const { return mTarget; }
|
||||
|
||||
WebGLContext* GetParentObject() const;
|
||||
@ -41,6 +43,7 @@ private:
|
||||
~WebGLTimerQuery();
|
||||
|
||||
GLenum mTarget;
|
||||
bool mCanBeAvailable;
|
||||
|
||||
friend class WebGLExtensionDisjointTimerQuery;
|
||||
};
|
||||
|
@ -15,7 +15,7 @@ fail-if = (os == 'android')
|
||||
[webgl-mochitest/ensure-exts/test_EXT_color_buffer_half_float.html]
|
||||
fail-if = (os == 'android')
|
||||
[webgl-mochitest/ensure-exts/test_EXT_disjoint_timer_query.html]
|
||||
fail-if = (os == 'android') || (os == 'mac') || (os == 'win')
|
||||
fail-if = (os == 'android') || (os == 'mac') || (os == 'win' && (os_version == '5.1' || os_version == '6.1'))
|
||||
[webgl-mochitest/ensure-exts/test_EXT_frag_depth.html]
|
||||
fail-if = (os == 'android')
|
||||
[webgl-mochitest/ensure-exts/test_EXT_sRGB.html]
|
||||
|
@ -15,11 +15,11 @@
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
static const char* labelsEncodings[][3] = {
|
||||
static const char* const labelsEncodings[][3] = {
|
||||
#include "labelsencodings.properties.h"
|
||||
};
|
||||
|
||||
static const char* encodingsGroups[][3] = {
|
||||
static const char* const encodingsGroups[][3] = {
|
||||
#include "encodingsgroups.properties.h"
|
||||
};
|
||||
|
||||
|
@ -15,15 +15,15 @@
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
static const char* localesFallbacks[][3] = {
|
||||
static const char* const localesFallbacks[][3] = {
|
||||
#include "localesfallbacks.properties.h"
|
||||
};
|
||||
|
||||
static const char* domainsFallbacks[][3] = {
|
||||
static const char* const domainsFallbacks[][3] = {
|
||||
#include "domainsfallbacks.properties.h"
|
||||
};
|
||||
|
||||
static const char* nonParticipatingDomains[][3] = {
|
||||
static const char* const nonParticipatingDomains[][3] = {
|
||||
#include "nonparticipatingdomains.properties.h"
|
||||
};
|
||||
|
||||
|
@ -85,9 +85,46 @@ private:
|
||||
uint32_t mInitialCount;
|
||||
};
|
||||
|
||||
static bool IsEventTargetChrome(EventTarget* aEventTarget,
|
||||
nsIDocument** aDocument = nullptr)
|
||||
{
|
||||
if (aDocument) {
|
||||
*aDocument = nullptr;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!aEventTarget)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(aEventTarget);
|
||||
if (!doc) {
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(aEventTarget);
|
||||
if (node) {
|
||||
doc = node->OwnerDoc();
|
||||
} else {
|
||||
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aEventTarget);
|
||||
if (!window) {
|
||||
return false;
|
||||
}
|
||||
doc = window->GetExtantDoc();
|
||||
}
|
||||
if (!doc) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool isChrome = nsContentUtils::IsChromeDoc(doc);
|
||||
if (aDocument) {
|
||||
doc.swap(*aDocument);
|
||||
}
|
||||
return isChrome;
|
||||
}
|
||||
|
||||
|
||||
#define NS_TARGET_CHAIN_FORCE_CONTENT_DISPATCH (1 << 0)
|
||||
#define NS_TARGET_CHAIN_WANTS_WILL_HANDLE_EVENT (1 << 1)
|
||||
#define NS_TARGET_CHAIN_MAY_HAVE_MANAGER (1 << 2)
|
||||
#define NS_TARGET_CHAIN_CHECKED_IF_CHROME (1 << 3)
|
||||
#define NS_TARGET_CHAIN_IS_CHROME_CONTENT (1 << 4)
|
||||
|
||||
// EventTargetChainItem represents a single item in the event target chain.
|
||||
class EventTargetChainItem
|
||||
@ -210,6 +247,11 @@ public:
|
||||
if (aVisitor.mEvent->mFlags.mPropagationStopped) {
|
||||
return;
|
||||
}
|
||||
if (aVisitor.mEvent->mFlags.mOnlySystemGroupDispatchInContent &&
|
||||
!aVisitor.mEvent->mFlags.mInSystemGroup &&
|
||||
!IsCurrentTargetChrome()) {
|
||||
return;
|
||||
}
|
||||
if (!mManager) {
|
||||
if (!MayHaveListenerManager() && !aCd.MayHaveNewListenerManager()) {
|
||||
return;
|
||||
@ -233,6 +275,7 @@ public:
|
||||
*/
|
||||
void PostHandleEvent(EventChainPostVisitor& aVisitor);
|
||||
|
||||
private:
|
||||
nsCOMPtr<EventTarget> mTarget;
|
||||
uint16_t mFlags;
|
||||
uint16_t mItemFlags;
|
||||
@ -241,6 +284,17 @@ public:
|
||||
nsCOMPtr<EventTarget> mNewTarget;
|
||||
// Cache mTarget's event listener manager.
|
||||
RefPtr<EventListenerManager> mManager;
|
||||
|
||||
bool IsCurrentTargetChrome()
|
||||
{
|
||||
if (!(mFlags & NS_TARGET_CHAIN_CHECKED_IF_CHROME)) {
|
||||
mFlags |= NS_TARGET_CHAIN_CHECKED_IF_CHROME;
|
||||
if (IsEventTargetChrome(mTarget)) {
|
||||
mFlags |= NS_TARGET_CHAIN_IS_CHROME_CONTENT;
|
||||
}
|
||||
}
|
||||
return !!(mFlags & NS_TARGET_CHAIN_IS_CHROME_CONTENT);
|
||||
}
|
||||
};
|
||||
|
||||
EventTargetChainItem::EventTargetChainItem(EventTarget* aTarget)
|
||||
@ -468,18 +522,9 @@ EventDispatcher::Dispatch(nsISupports* aTarget,
|
||||
}
|
||||
|
||||
if (aEvent->mFlags.mOnlyChromeDispatch) {
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(aTarget);
|
||||
if (!node) {
|
||||
nsCOMPtr<nsPIDOMWindowInner> win = do_QueryInterface(aTarget);
|
||||
if (win) {
|
||||
node = win->GetExtantDoc();
|
||||
}
|
||||
}
|
||||
|
||||
NS_ENSURE_STATE(node);
|
||||
nsIDocument* doc = node->OwnerDoc();
|
||||
if (!nsContentUtils::IsChromeDoc(doc)) {
|
||||
nsPIDOMWindowInner* win = doc ? doc->GetInnerWindow() : nullptr;
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
if (!IsEventTargetChrome(target, getter_AddRefs(doc)) && doc) {
|
||||
nsPIDOMWindowInner* win = doc->GetInnerWindow();
|
||||
// If we can't dispatch the event to chrome, do nothing.
|
||||
EventTarget* piTarget = win ? win->GetParentTarget() : nullptr;
|
||||
if (!piTarget) {
|
||||
@ -490,6 +535,8 @@ EventDispatcher::Dispatch(nsISupports* aTarget,
|
||||
aEvent->target = target;
|
||||
// but use chrome event handler or TabChildGlobal for event target chain.
|
||||
target = piTarget;
|
||||
} else if (NS_WARN_IF(!doc)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,7 @@ interface nsIContentSecurityPolicy : nsISerializable
|
||||
const unsigned short WEB_MANIFEST_SRC_DIRECTIVE = 16;
|
||||
const unsigned short UPGRADE_IF_INSECURE_DIRECTIVE = 17;
|
||||
const unsigned short CHILD_SRC_DIRECTIVE = 18;
|
||||
const unsigned short BLOCK_ALL_MIXED_CONTENT = 19;
|
||||
|
||||
/**
|
||||
* Accessor method for a read-only string version of the policy at a given
|
||||
@ -72,6 +73,15 @@ interface nsIContentSecurityPolicy : nsISerializable
|
||||
*/
|
||||
readonly attribute bool upgradeInsecureRequests;
|
||||
|
||||
/**
|
||||
* Returns whether this policy uses the directive block-all-mixed-content.
|
||||
* Please note that block-all-mixed-content takes presedence in case the
|
||||
* directive upgrade-insecure-requests is defined in the same policy and
|
||||
* will therefore block all mixed content without even trying to perform
|
||||
* an upgrade.
|
||||
*/
|
||||
readonly attribute bool blockAllMixedContent;
|
||||
|
||||
/**
|
||||
* Obtains the referrer policy (as integer) for this browsing context as
|
||||
* specified in CSP. If there are multiple policies and...
|
||||
|
@ -68,6 +68,9 @@ hostNameMightBeKeyword = Interpreting %1$S as a hostname, not a keyword. If you
|
||||
# LOCALIZATION NOTE (notSupportingDirective):
|
||||
# directive is not supported (e.g. 'reflected-xss')
|
||||
notSupportingDirective = Not supporting directive '%1$S'. Directive and values will be ignored.
|
||||
# LOCALIZATION NOTE (blockAllMixedContent):
|
||||
# %1$S is the URL of the blocked resource load.
|
||||
blockAllMixedContent = Blocking insecure request '%1$S'.
|
||||
|
||||
# CSP Errors:
|
||||
# LOCALIZATION NOTE (couldntParseInvalidSource):
|
||||
|
@ -1,12 +0,0 @@
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
INSTALL_TARGETS += FAKE_GMP_OPENH264_PLUGIN
|
||||
FAKE_GMP_OPENH264_PLUGIN_DEST = $(DEPTH)/dist/bin/gmp-fakeopenh264/1.0
|
||||
FAKE_GMP_OPENH264_PLUGIN_FILES = \
|
||||
$(srcdir)/fakeopenh264.info \
|
||||
$(srcdir)/fakeopenh264.voucher \
|
||||
$(NULL)
|
||||
|
@ -7,6 +7,12 @@
|
||||
# largely a copy of dom/media/gmp-fake/moz.build
|
||||
|
||||
FINAL_TARGET = 'dist/bin/gmp-fakeopenh264/1.0'
|
||||
|
||||
FINAL_TARGET_FILES += [
|
||||
'fakeopenh264.info',
|
||||
'fakeopenh264.voucher',
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
'gmp-fake-openh264.cpp',
|
||||
]
|
||||
|
@ -1,13 +0,0 @@
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
INSTALL_TARGETS += FAKE_GMP_PLUGIN
|
||||
FAKE_GMP_PLUGIN_DEST = $(DEPTH)/dist/bin/gmp-fake/1.0
|
||||
FAKE_GMP_PLUGIN_FILES = \
|
||||
$(SHARED_LIBRARY) \
|
||||
$(srcdir)/fake.info \
|
||||
$(srcdir)/fake.voucher
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
@ -4,7 +4,13 @@
|
||||
# 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/.
|
||||
|
||||
DIST_INSTALL = False
|
||||
FINAL_TARGET = 'dist/bin/gmp-fake/1.0'
|
||||
|
||||
FINAL_TARGET_FILES += [
|
||||
'fake.info',
|
||||
'fake.voucher',
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
'gmp-fake.cpp',
|
||||
'gmp-test-decryptor.cpp',
|
||||
|
@ -124,6 +124,11 @@ mozilla::plugins::SetupBridge(uint32_t aPluginId,
|
||||
return true;
|
||||
}
|
||||
PluginModuleChromeParent* chromeParent = static_cast<PluginModuleChromeParent*>(plugin->GetLibrary());
|
||||
/*
|
||||
* We can't accumulate BLOCKED_ON_PLUGIN_MODULE_INIT_MS until here because
|
||||
* its histogram key is not available until *after* NP_Initialize.
|
||||
*/
|
||||
chromeParent->AccumulateModuleInitBlockedTime();
|
||||
*rv = chromeParent->GetRunID(runID);
|
||||
if (NS_FAILED(*rv)) {
|
||||
return true;
|
||||
@ -401,13 +406,16 @@ PluginModuleContentParent::LoadModule(uint32_t aPluginId,
|
||||
dom::ContentChild* cp = dom::ContentChild::GetSingleton();
|
||||
nsresult rv;
|
||||
uint32_t runID;
|
||||
TimeStamp sendLoadPluginStart = TimeStamp::Now();
|
||||
if (!cp->SendLoadPlugin(aPluginId, &rv, &runID) ||
|
||||
NS_FAILED(rv)) {
|
||||
return nullptr;
|
||||
}
|
||||
TimeStamp sendLoadPluginEnd = TimeStamp::Now();
|
||||
|
||||
PluginModuleContentParent* parent = mapping->GetModule();
|
||||
MOZ_ASSERT(parent);
|
||||
parent->mTimeBlocked += (sendLoadPluginEnd - sendLoadPluginStart);
|
||||
|
||||
if (!mapping->IsChannelOpened()) {
|
||||
// mapping is linked into PluginModuleMapping::sModuleListHead and is
|
||||
@ -2626,6 +2634,18 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
PluginModuleParent::AccumulateModuleInitBlockedTime()
|
||||
{
|
||||
if (mPluginName.IsEmpty()) {
|
||||
GetPluginDetails();
|
||||
}
|
||||
Telemetry::Accumulate(Telemetry::BLOCKED_ON_PLUGIN_MODULE_INIT_MS,
|
||||
GetHistogramKey(),
|
||||
static_cast<uint32_t>(mTimeBlocked.ToMilliseconds()));
|
||||
mTimeBlocked = TimeDuration();
|
||||
}
|
||||
|
||||
nsresult
|
||||
PluginModuleParent::NPP_NewInternal(NPMIMEType pluginType, NPP instance,
|
||||
uint16_t mode,
|
||||
@ -2640,12 +2660,9 @@ PluginModuleParent::NPP_NewInternal(NPMIMEType pluginType, NPP instance,
|
||||
* on plugin module initialization. As implemented, this is the sum of
|
||||
* plugin-container launch + toolhelp32 snapshot + NP_Initialize.
|
||||
* We don't accumulate its value until here because the plugin info
|
||||
* is not available until *after* NP_Initialize.
|
||||
* for its histogram key is not available until *after* NP_Initialize.
|
||||
*/
|
||||
Telemetry::Accumulate(Telemetry::BLOCKED_ON_PLUGIN_MODULE_INIT_MS,
|
||||
GetHistogramKey(),
|
||||
static_cast<uint32_t>(mTimeBlocked.ToMilliseconds()));
|
||||
mTimeBlocked = TimeDuration();
|
||||
AccumulateModuleInitBlockedTime();
|
||||
}
|
||||
|
||||
nsCaseInsensitiveUTF8StringArrayComparator comparator;
|
||||
|
@ -136,6 +136,8 @@ public:
|
||||
return mPluginName + mPluginVersion;
|
||||
}
|
||||
|
||||
void AccumulateModuleInitBlockedTime();
|
||||
|
||||
virtual nsresult GetRunID(uint32_t* aRunID) override;
|
||||
virtual void SetHasLocalInstance() override {
|
||||
mHadLocalInstance = true;
|
||||
|
@ -308,6 +308,19 @@ nsCSPContext::GetUpgradeInsecureRequests(bool *outUpgradeRequest)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCSPContext::GetBlockAllMixedContent(bool *outBlockAllMixedContent)
|
||||
{
|
||||
*outBlockAllMixedContent = false;
|
||||
for (uint32_t i = 0; i < mPolicies.Length(); i++) {
|
||||
if (mPolicies[i]->hasDirective(nsIContentSecurityPolicy::BLOCK_ALL_MIXED_CONTENT)) {
|
||||
*outBlockAllMixedContent = true;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCSPContext::GetReferrerPolicy(uint32_t* outPolicy, bool* outIsSet)
|
||||
{
|
||||
|
@ -1008,6 +1008,11 @@ nsCSPParser::directiveName()
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// special case handling for block-all-mixed-content
|
||||
if (CSP_IsDirective(mCurToken, nsIContentSecurityPolicy::BLOCK_ALL_MIXED_CONTENT)) {
|
||||
return new nsBlockAllMixedContentDirective(CSP_StringToCSPDirective(mCurToken));
|
||||
}
|
||||
|
||||
// special case handling for upgrade-insecure-requests
|
||||
if (CSP_IsDirective(mCurToken, nsIContentSecurityPolicy::UPGRADE_IF_INSECURE_DIRECTIVE)) {
|
||||
return new nsUpgradeInsecureDirective(CSP_StringToCSPDirective(mCurToken));
|
||||
@ -1059,6 +1064,20 @@ nsCSPParser::directive()
|
||||
return;
|
||||
}
|
||||
|
||||
// special case handling for block-all-mixed-content, which is only specified
|
||||
// by a directive name but does not include any srcs.
|
||||
if (cspDir->equals(nsIContentSecurityPolicy::BLOCK_ALL_MIXED_CONTENT)) {
|
||||
if (mCurDir.Length() > 1) {
|
||||
const char16_t* params[] = { MOZ_UTF16("block-all-mixed-content") };
|
||||
logWarningErrorToConsole(nsIScriptError::warningFlag,
|
||||
"ignoreSrcForDirective",
|
||||
params, ArrayLength(params));
|
||||
}
|
||||
// add the directive and return
|
||||
mPolicy->addDirective(cspDir);
|
||||
return;
|
||||
}
|
||||
|
||||
// special case handling for upgrade-insecure-requests, which is only specified
|
||||
// by a directive name but does not include any srcs.
|
||||
if (cspDir->equals(nsIContentSecurityPolicy::UPGRADE_IF_INSECURE_DIRECTIVE)) {
|
||||
|
@ -902,6 +902,11 @@ nsCSPDirective::toDomCSPStruct(mozilla::dom::CSP& outCSP) const
|
||||
outCSP.mForm_action.Value() = mozilla::Move(srcs);
|
||||
return;
|
||||
|
||||
case nsIContentSecurityPolicy::BLOCK_ALL_MIXED_CONTENT:
|
||||
outCSP.mBlock_all_mixed_content.Construct();
|
||||
// does not have any srcs
|
||||
return;
|
||||
|
||||
case nsIContentSecurityPolicy::UPGRADE_IF_INSECURE_DIRECTIVE:
|
||||
outCSP.mUpgrade_insecure_requests.Construct();
|
||||
// does not have any srcs
|
||||
@ -987,6 +992,24 @@ bool nsCSPChildSrcDirective::equals(CSPDirective aDirective) const
|
||||
return (aDirective == nsIContentSecurityPolicy::CHILD_SRC_DIRECTIVE);
|
||||
}
|
||||
|
||||
/* =============== nsBlockAllMixedContentDirective ============= */
|
||||
|
||||
nsBlockAllMixedContentDirective::nsBlockAllMixedContentDirective(CSPDirective aDirective)
|
||||
: nsCSPDirective(aDirective)
|
||||
{
|
||||
}
|
||||
|
||||
nsBlockAllMixedContentDirective::~nsBlockAllMixedContentDirective()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
nsBlockAllMixedContentDirective::toString(nsAString& outStr) const
|
||||
{
|
||||
outStr.AppendASCII(CSP_CSPDirectiveToString(
|
||||
nsIContentSecurityPolicy::BLOCK_ALL_MIXED_CONTENT));
|
||||
}
|
||||
|
||||
/* =============== nsUpgradeInsecureDirective ============= */
|
||||
|
||||
nsUpgradeInsecureDirective::nsUpgradeInsecureDirective(CSPDirective aDirective)
|
||||
|
@ -88,7 +88,8 @@ static const char* CSPStrDirectives[] = {
|
||||
"referrer", // REFERRER_DIRECTIVE
|
||||
"manifest-src", // MANIFEST_SRC_DIRECTIVE
|
||||
"upgrade-insecure-requests", // UPGRADE_IF_INSECURE_DIRECTIVE
|
||||
"child-src" // CHILD_SRC_DIRECTIVE
|
||||
"child-src", // CHILD_SRC_DIRECTIVE
|
||||
"block-all-mixed-content" // BLOCK_ALL_MIXED_CONTENT
|
||||
};
|
||||
|
||||
inline const char* CSP_CSPDirectiveToString(CSPDirective aDir)
|
||||
@ -343,6 +344,29 @@ class nsCSPChildSrcDirective : public nsCSPDirective {
|
||||
bool mHandleFrameSrc;
|
||||
};
|
||||
|
||||
/* =============== nsBlockAllMixedContentDirective === */
|
||||
|
||||
class nsBlockAllMixedContentDirective : public nsCSPDirective {
|
||||
public:
|
||||
explicit nsBlockAllMixedContentDirective(CSPDirective aDirective);
|
||||
~nsBlockAllMixedContentDirective();
|
||||
|
||||
bool permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected,
|
||||
bool aReportOnly, bool aUpgradeInsecure) const
|
||||
{ return false; }
|
||||
|
||||
bool permits(nsIURI* aUri) const
|
||||
{ return false; }
|
||||
|
||||
bool allows(enum CSPKeyword aKeyword, const nsAString& aHashOrNonce) const
|
||||
{ return false; }
|
||||
|
||||
void toString(nsAString& outStr) const;
|
||||
|
||||
void addSrcs(const nsTArray<nsCSPBaseSrc*>& aSrcs)
|
||||
{ MOZ_ASSERT(false, "block-all-mixed-content does not hold any srcs"); }
|
||||
};
|
||||
|
||||
/* =============== nsUpgradeInsecureDirective === */
|
||||
|
||||
/*
|
||||
|
@ -632,6 +632,35 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShell> docShell = NS_CP_GetDocShellFromContext(aRequestingContext);
|
||||
NS_ENSURE_TRUE(docShell, NS_OK);
|
||||
|
||||
// The page might have set the CSP directive 'block-all-mixed-content' which
|
||||
// should block not only active mixed content loads but in fact all mixed content
|
||||
// loads, see https://www.w3.org/TR/mixed-content/#strict-checking
|
||||
// Block all non secure loads in case the CSP directive is present. Please note
|
||||
// that at this point we already know, based on |schemeSecure| that the load is
|
||||
// not secure, so we can bail out early at this point.
|
||||
if (docShell->GetDocument()->GetBlockAllMixedContent(isPreload)) {
|
||||
// log a message to the console before returning.
|
||||
nsAutoCString spec;
|
||||
rv = aContentLocation->GetSpec(spec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ConvertUTF8toUTF16 reportSpec(spec);
|
||||
|
||||
const char16_t* params[] = { reportSpec.get()};
|
||||
CSP_LogLocalizedStr(MOZ_UTF16("blockAllMixedContent"),
|
||||
params, ArrayLength(params),
|
||||
EmptyString(), // aSourceFile
|
||||
EmptyString(), // aScriptSample
|
||||
0, // aLineNumber
|
||||
0, // aColumnNumber
|
||||
nsIScriptError::errorFlag, "CSP",
|
||||
docShell->GetDocument()->InnerWindowID());
|
||||
*aDecision = REJECT_REQUEST;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Disallow mixed content loads for workers, shared workers and service
|
||||
// workers.
|
||||
if (isWorkerType) {
|
||||
@ -649,10 +678,6 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Determine if the rootDoc is https and if the user decided to allow Mixed Content
|
||||
nsCOMPtr<nsIDocShell> docShell = NS_CP_GetDocShellFromContext(aRequestingContext);
|
||||
NS_ENSURE_TRUE(docShell, NS_OK);
|
||||
|
||||
// The page might have set the CSP directive 'upgrade-insecure-requests'. In such
|
||||
// a case allow the http: load to succeed with the promise that the channel will
|
||||
// get upgraded to https before fetching any data from the netwerk.
|
||||
@ -672,6 +697,7 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Determine if the rootDoc is https and if the user decided to allow Mixed Content
|
||||
bool rootHasSecureConnection = false;
|
||||
bool allowMixedContent = false;
|
||||
bool isRootDocShell = false;
|
||||
|
53
dom/security/test/csp/file_block_all_mcb.sjs
Normal file
53
dom/security/test/csp/file_block_all_mcb.sjs
Normal file
@ -0,0 +1,53 @@
|
||||
// custom *.sjs for Bug 1122236
|
||||
// CSP: 'block-all-mixed-content'
|
||||
|
||||
const HEAD =
|
||||
"<!DOCTYPE HTML>" +
|
||||
"<html><head><meta charset=\"utf-8\">" +
|
||||
"<title>Bug 1122236 - CSP: Implement block-all-mixed-content</title>" +
|
||||
"</head>";
|
||||
|
||||
const CSP_ALLOW =
|
||||
"<meta http-equiv=\"Content-Security-Policy\" content=\"img-src *\">";
|
||||
|
||||
const CSP_BLOCK =
|
||||
"<meta http-equiv=\"Content-Security-Policy\" content=\"block-all-mixed-content\">";
|
||||
|
||||
const BODY =
|
||||
"<body>" +
|
||||
"<img id=\"testimage\" src=\"http://mochi.test:8888/tests/image/test/mochitest/blue.png\"></img>" +
|
||||
"<script type=\"application/javascript\">" +
|
||||
" var myImg = document.getElementById(\"testimage\");" +
|
||||
" myImg.onload = function(e) {" +
|
||||
" window.parent.postMessage({result: \"img-loaded\"}, \"*\");" +
|
||||
" };" +
|
||||
" myImg.onerror = function(e) {" +
|
||||
" window.parent.postMessage({result: \"img-blocked\"}, \"*\");" +
|
||||
" };" +
|
||||
"</script>" +
|
||||
"</body>" +
|
||||
"</html>";
|
||||
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
// avoid confusing cache behaviors
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
|
||||
var queryString = request.queryString;
|
||||
|
||||
if (queryString === "csp-block") {
|
||||
response.write(HEAD + CSP_BLOCK + BODY);
|
||||
return;
|
||||
}
|
||||
if (queryString === "csp-allow") {
|
||||
response.write(HEAD + CSP_ALLOW + BODY);
|
||||
return;
|
||||
}
|
||||
if (queryString === "no-csp") {
|
||||
response.write(HEAD + BODY);
|
||||
return;
|
||||
}
|
||||
// we should never get here but just in case return something unexpected
|
||||
response.write("do'h");
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-Security-Policy" content="block-all-mixed-content">
|
||||
<title>Bug 1122236 - CSP: Implement block-all-mixed-content</title>
|
||||
</head>
|
||||
<body>
|
||||
<b>user clicks and navigates from https://b.com to http://c.com</b>
|
||||
|
||||
<a id="navlink" href="http://example.com/tests/dom/security/test/csp/file_block_all_mixed_content_frame_navigation2.html">foo</a>
|
||||
|
||||
<script class="testbody" type="text/javascript">
|
||||
// click the link to start the frame navigation
|
||||
document.getElementById("navlink").click();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,15 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Bug 1122236 - CSP: Implement block-all-mixed-content</title>
|
||||
</head>
|
||||
<body>
|
||||
<b>http://c.com loaded, let's tell the parent</b>
|
||||
|
||||
<script class="testbody" type="text/javascript">
|
||||
window.parent.postMessage({result: "frame-navigated"}, "*");
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -156,6 +156,9 @@ support-files =
|
||||
file_multipart_testserver.sjs
|
||||
file_fontloader.sjs
|
||||
file_fontloader.woff
|
||||
file_block_all_mcb.sjs
|
||||
file_block_all_mixed_content_frame_navigation1.html
|
||||
file_block_all_mixed_content_frame_navigation2.html
|
||||
|
||||
[test_base-uri.html]
|
||||
[test_blob_data_schemes.html]
|
||||
@ -236,3 +239,7 @@ skip-if = toolkit == 'android' #investigate in bug 1250814
|
||||
[test_docwrite_meta.html]
|
||||
[test_multipartchannel.html]
|
||||
[test_fontloader.html]
|
||||
[test_block_all_mixed_content.html]
|
||||
tags = mcb
|
||||
[test_block_all_mixed_content_frame_navigation.html]
|
||||
tags = mcb
|
||||
|
94
dom/security/test/csp/test_block_all_mixed_content.html
Normal file
94
dom/security/test/csp/test_block_all_mixed_content.html
Normal file
@ -0,0 +1,94 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Bug 1122236 - CSP: Implement block-all-mixed-content</title>
|
||||
<!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<iframe style="width:100%;" id="testframe"></iframe>
|
||||
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
/* Description of the tests:
|
||||
* Test 1:
|
||||
* We load mixed display content in a frame using the CSP
|
||||
* directive 'block-all-mixed-content' and observe that the image is blocked.
|
||||
*
|
||||
* Test 2:
|
||||
* We load mixed display content in a frame using a CSP that allows the load
|
||||
* and observe that the image is loaded.
|
||||
*
|
||||
* Test 3:
|
||||
* We load mixed display content in a frame not using a CSP at all
|
||||
* and observe that the image is loaded.
|
||||
*
|
||||
* Test 4:
|
||||
* We load mixed display content in a frame using the CSP
|
||||
* directive 'block-all-mixed-content' and observe that the image is blocked.
|
||||
* Please note that Test 3 loads the image we are about to load in Test 4 into
|
||||
* the img cache. Let's make sure the cached (mixed display content) image is
|
||||
* not allowed to be loaded.
|
||||
*/
|
||||
|
||||
const BASE_URI = "https://example.com/tests/dom/security/test/csp/";
|
||||
|
||||
const tests = [
|
||||
{ // Test 1
|
||||
query: "csp-block",
|
||||
expected: "img-blocked",
|
||||
description: "(csp-block) block-all-mixed content should block mixed display content"
|
||||
},
|
||||
{ // Test 2
|
||||
query: "csp-allow",
|
||||
expected: "img-loaded",
|
||||
description: "(csp-allow) mixed display content should be loaded"
|
||||
},
|
||||
{ // Test 3
|
||||
query: "no-csp",
|
||||
expected: "img-loaded",
|
||||
description: "(no-csp) mixed display content should be loaded"
|
||||
},
|
||||
{ // Test 4
|
||||
query: "csp-block",
|
||||
expected: "img-blocked",
|
||||
description: "(csp-block) block-all-mixed content should block insecure cache loads"
|
||||
},
|
||||
];
|
||||
|
||||
var curTest;
|
||||
var counter = -1;
|
||||
|
||||
function checkResults(result) {
|
||||
is(result, curTest.expected, curTest.description);
|
||||
loadNextTest();
|
||||
}
|
||||
|
||||
window.addEventListener("message", receiveMessage, false);
|
||||
function receiveMessage(event) {
|
||||
checkResults(event.data.result);
|
||||
}
|
||||
|
||||
function loadNextTest() {
|
||||
counter++;
|
||||
if (counter == tests.length) {
|
||||
window.removeEventListener("message", receiveMessage, false);
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
curTest = tests[counter];
|
||||
testframe.src = BASE_URI + "file_block_all_mcb.sjs?" + curTest.query;
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{ 'set': [["security.mixed_content.block_display_content", false]] },
|
||||
function() { loadNextTest(); }
|
||||
);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,46 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Bug 1122236 - CSP: Implement block-all-mixed-content</title>
|
||||
<!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<iframe style="width:100%;" id="testframe"></iframe>
|
||||
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
/* Description of the test:
|
||||
*
|
||||
* http://a.com embeds https://b.com.
|
||||
* https://b.com has a CSP using 'block-all-mixed-content'.
|
||||
* | site | http://a.com
|
||||
* | embeds | https://b.com (uses block-all-mixed-content)
|
||||
*
|
||||
* The user navigates the embedded frame from
|
||||
* https://b.com -> http://c.com.
|
||||
* The test makes sure that such a navigation is not blocked
|
||||
* by block-all-mixed-content.
|
||||
*/
|
||||
|
||||
function checkResults(result) {
|
||||
is(result, "frame-navigated", "frame should be allowed to be navigated");
|
||||
window.removeEventListener("message", receiveMessage, false);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
window.addEventListener("message", receiveMessage, false);
|
||||
function receiveMessage(event) {
|
||||
checkResults(event.data.result);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
// http://a.com loads https://b.com
|
||||
document.getElementById("testframe").src =
|
||||
"https://example.com/tests/dom/security/test/csp/file_block_all_mixed_content_frame_navigation1.html";
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -27,6 +27,7 @@ dictionary CSP {
|
||||
sequence<DOMString> manifest-src;
|
||||
sequence<DOMString> upgrade-insecure-requests;
|
||||
sequence<DOMString> child-src;
|
||||
sequence<DOMString> block-all-mixed-content;
|
||||
};
|
||||
|
||||
dictionary CSPPolicies {
|
||||
|
@ -556,22 +556,7 @@ nsXBLService::AttachGlobalKeyHandler(EventTarget* aTarget)
|
||||
RefPtr<nsXBLWindowKeyHandler> handler =
|
||||
NS_NewXBLWindowKeyHandler(elt, piTarget);
|
||||
|
||||
// listen to these events
|
||||
manager->AddEventListenerByType(handler, NS_LITERAL_STRING("keydown"),
|
||||
TrustedEventsAtSystemGroupBubble());
|
||||
manager->AddEventListenerByType(handler, NS_LITERAL_STRING("keyup"),
|
||||
TrustedEventsAtSystemGroupBubble());
|
||||
manager->AddEventListenerByType(handler, NS_LITERAL_STRING("keypress"),
|
||||
TrustedEventsAtSystemGroupBubble());
|
||||
|
||||
// The capturing listener is only used for XUL keysets to properly handle
|
||||
// shortcut keys in a multi-process environment.
|
||||
manager->AddEventListenerByType(handler, NS_LITERAL_STRING("keydown"),
|
||||
TrustedEventsAtSystemGroupCapture());
|
||||
manager->AddEventListenerByType(handler, NS_LITERAL_STRING("keyup"),
|
||||
TrustedEventsAtSystemGroupCapture());
|
||||
manager->AddEventListenerByType(handler, NS_LITERAL_STRING("keypress"),
|
||||
TrustedEventsAtSystemGroupCapture());
|
||||
handler->InstallKeyboardEventListenersTo(manager);
|
||||
|
||||
if (contentNode)
|
||||
return contentNode->SetProperty(nsGkAtoms::listener,
|
||||
@ -611,19 +596,8 @@ nsXBLService::DetachGlobalKeyHandler(EventTarget* aTarget)
|
||||
if (!handler)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
manager->RemoveEventListenerByType(handler, NS_LITERAL_STRING("keydown"),
|
||||
TrustedEventsAtSystemGroupBubble());
|
||||
manager->RemoveEventListenerByType(handler, NS_LITERAL_STRING("keyup"),
|
||||
TrustedEventsAtSystemGroupBubble());
|
||||
manager->RemoveEventListenerByType(handler, NS_LITERAL_STRING("keypress"),
|
||||
TrustedEventsAtSystemGroupBubble());
|
||||
|
||||
manager->RemoveEventListenerByType(handler, NS_LITERAL_STRING("keydown"),
|
||||
TrustedEventsAtSystemGroupCapture());
|
||||
manager->RemoveEventListenerByType(handler, NS_LITERAL_STRING("keyup"),
|
||||
TrustedEventsAtSystemGroupCapture());
|
||||
manager->RemoveEventListenerByType(handler, NS_LITERAL_STRING("keypress"),
|
||||
TrustedEventsAtSystemGroupCapture());
|
||||
static_cast<nsXBLWindowKeyHandler*>(handler)->
|
||||
RemoveKeyboardEventListenersFrom(manager);
|
||||
|
||||
contentNode->DeleteProperty(nsGkAtoms::listener);
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "mozilla/EventListenerManager.h"
|
||||
#include "mozilla/EventStateManager.h"
|
||||
#include "nsISelectionController.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
@ -297,6 +298,82 @@ nsXBLWindowKeyHandler::WalkHandlers(nsIDOMKeyEvent* aKeyEvent, nsIAtom* aEventTy
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsXBLWindowKeyHandler::InstallKeyboardEventListenersTo(
|
||||
EventListenerManager* aEventListenerManager)
|
||||
{
|
||||
// For marking each keyboard event as if it's reserved by chrome,
|
||||
// nsXBLWindowKeyHandlers need to listen each keyboard events before
|
||||
// web contents.
|
||||
aEventListenerManager->AddEventListenerByType(
|
||||
this, NS_LITERAL_STRING("keydown"),
|
||||
TrustedEventsAtCapture());
|
||||
aEventListenerManager->AddEventListenerByType(
|
||||
this, NS_LITERAL_STRING("keyup"),
|
||||
TrustedEventsAtCapture());
|
||||
aEventListenerManager->AddEventListenerByType(
|
||||
this, NS_LITERAL_STRING("keypress"),
|
||||
TrustedEventsAtCapture());
|
||||
|
||||
// For reducing the IPC cost, preventing to dispatch reserved keyboard
|
||||
// events into the content process.
|
||||
aEventListenerManager->AddEventListenerByType(
|
||||
this, NS_LITERAL_STRING("keydown"),
|
||||
TrustedEventsAtSystemGroupCapture());
|
||||
aEventListenerManager->AddEventListenerByType(
|
||||
this, NS_LITERAL_STRING("keyup"),
|
||||
TrustedEventsAtSystemGroupCapture());
|
||||
aEventListenerManager->AddEventListenerByType(
|
||||
this, NS_LITERAL_STRING("keypress"),
|
||||
TrustedEventsAtSystemGroupCapture());
|
||||
|
||||
// Handle keyboard events in bubbling phase of the system event group.
|
||||
aEventListenerManager->AddEventListenerByType(
|
||||
this, NS_LITERAL_STRING("keydown"),
|
||||
TrustedEventsAtSystemGroupBubble());
|
||||
aEventListenerManager->AddEventListenerByType(
|
||||
this, NS_LITERAL_STRING("keyup"),
|
||||
TrustedEventsAtSystemGroupBubble());
|
||||
aEventListenerManager->AddEventListenerByType(
|
||||
this, NS_LITERAL_STRING("keypress"),
|
||||
TrustedEventsAtSystemGroupBubble());
|
||||
}
|
||||
|
||||
void
|
||||
nsXBLWindowKeyHandler::RemoveKeyboardEventListenersFrom(
|
||||
EventListenerManager* aEventListenerManager)
|
||||
{
|
||||
aEventListenerManager->RemoveEventListenerByType(
|
||||
this, NS_LITERAL_STRING("keydown"),
|
||||
TrustedEventsAtCapture());
|
||||
aEventListenerManager->RemoveEventListenerByType(
|
||||
this, NS_LITERAL_STRING("keyup"),
|
||||
TrustedEventsAtCapture());
|
||||
aEventListenerManager->RemoveEventListenerByType(
|
||||
this, NS_LITERAL_STRING("keypress"),
|
||||
TrustedEventsAtCapture());
|
||||
|
||||
aEventListenerManager->RemoveEventListenerByType(
|
||||
this, NS_LITERAL_STRING("keydown"),
|
||||
TrustedEventsAtSystemGroupCapture());
|
||||
aEventListenerManager->RemoveEventListenerByType(
|
||||
this, NS_LITERAL_STRING("keyup"),
|
||||
TrustedEventsAtSystemGroupCapture());
|
||||
aEventListenerManager->RemoveEventListenerByType(
|
||||
this, NS_LITERAL_STRING("keypress"),
|
||||
TrustedEventsAtSystemGroupCapture());
|
||||
|
||||
aEventListenerManager->RemoveEventListenerByType(
|
||||
this, NS_LITERAL_STRING("keydown"),
|
||||
TrustedEventsAtSystemGroupBubble());
|
||||
aEventListenerManager->RemoveEventListenerByType(
|
||||
this, NS_LITERAL_STRING("keyup"),
|
||||
TrustedEventsAtSystemGroupBubble());
|
||||
aEventListenerManager->RemoveEventListenerByType(
|
||||
this, NS_LITERAL_STRING("keypress"),
|
||||
TrustedEventsAtSystemGroupBubble());
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLWindowKeyHandler::HandleEvent(nsIDOMEvent* aEvent)
|
||||
{
|
||||
@ -306,7 +383,11 @@ nsXBLWindowKeyHandler::HandleEvent(nsIDOMEvent* aEvent)
|
||||
uint16_t eventPhase;
|
||||
aEvent->GetEventPhase(&eventPhase);
|
||||
if (eventPhase == nsIDOMEvent::CAPTURING_PHASE) {
|
||||
HandleEventOnCapture(keyEvent);
|
||||
if (aEvent->WidgetEventPtr()->mFlags.mInSystemGroup) {
|
||||
HandleEventOnCaptureInSystemEventGroup(keyEvent);
|
||||
} else {
|
||||
HandleEventOnCaptureInDefaultEventGroup(keyEvent);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -319,12 +400,41 @@ nsXBLWindowKeyHandler::HandleEvent(nsIDOMEvent* aEvent)
|
||||
}
|
||||
|
||||
void
|
||||
nsXBLWindowKeyHandler::HandleEventOnCapture(nsIDOMKeyEvent* aEvent)
|
||||
nsXBLWindowKeyHandler::HandleEventOnCaptureInDefaultEventGroup(
|
||||
nsIDOMKeyEvent* aEvent)
|
||||
{
|
||||
WidgetKeyboardEvent* widgetKeyboardEvent =
|
||||
aEvent->AsEvent()->WidgetEventPtr()->AsKeyboardEvent();
|
||||
|
||||
if (widgetKeyboardEvent->mFlags.mOnlySystemGroupDispatchInContent) {
|
||||
MOZ_RELEASE_ASSERT(
|
||||
widgetKeyboardEvent->mFlags.mNoCrossProcessBoundaryForwarding);
|
||||
return;
|
||||
}
|
||||
|
||||
bool isReserved = false;
|
||||
if (HasHandlerForEvent(aEvent, &isReserved) && isReserved) {
|
||||
// For reserved commands (such as Open New Tab), we don't to wait for
|
||||
// the content to answer (so mWantReplyFromContentProcess remains false),
|
||||
// neither to give a chance for content to override its behavior.
|
||||
widgetKeyboardEvent->mFlags.mNoCrossProcessBoundaryForwarding = true;
|
||||
// If the key combination is reserved by chrome, we shouldn't expose the
|
||||
// keyboard event to web contents because such keyboard events shouldn't be
|
||||
// cancelable. So, it's not good behavior to fire keyboard events but
|
||||
// to ignore the defaultPrevented attribute value in chrome.
|
||||
widgetKeyboardEvent->mFlags.mOnlySystemGroupDispatchInContent = true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsXBLWindowKeyHandler::HandleEventOnCaptureInSystemEventGroup(
|
||||
nsIDOMKeyEvent* aEvent)
|
||||
{
|
||||
WidgetKeyboardEvent* widgetEvent =
|
||||
aEvent->AsEvent()->WidgetEventPtr()->AsKeyboardEvent();
|
||||
|
||||
if (widgetEvent->mFlags.mNoCrossProcessBoundaryForwarding) {
|
||||
if (widgetEvent->mFlags.mNoCrossProcessBoundaryForwarding ||
|
||||
widgetEvent->mFlags.mOnlySystemGroupDispatchInContent) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -334,27 +444,19 @@ nsXBLWindowKeyHandler::HandleEventOnCapture(nsIDOMKeyEvent* aEvent)
|
||||
return;
|
||||
}
|
||||
|
||||
bool aReservedForChrome = false;
|
||||
if (!HasHandlerForEvent(aEvent, &aReservedForChrome)) {
|
||||
if (!HasHandlerForEvent(aEvent)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aReservedForChrome) {
|
||||
// For reserved commands (such as Open New Tab), we don't to wait for
|
||||
// the content to answer (so mWantReplyFromContentProcess remains false),
|
||||
// neither to give a chance for content to override its behavior.
|
||||
widgetEvent->mFlags.mNoCrossProcessBoundaryForwarding = true;
|
||||
} else {
|
||||
// Inform the child process that this is a event that we want a reply
|
||||
// from.
|
||||
widgetEvent->mFlags.mWantReplyFromContentProcess = true;
|
||||
|
||||
// If this event hadn't been marked as mNoCrossProcessBoundaryForwarding
|
||||
// yet, it means it wasn't processed by content. We'll not call any
|
||||
// of the handlers at this moment, and will wait for the event to be
|
||||
// redispatched with mNoCrossProcessBoundaryForwarding = 1 to process it.
|
||||
aEvent->AsEvent()->StopPropagation();
|
||||
}
|
||||
// Inform the child process that this is a event that we want a reply
|
||||
// from.
|
||||
widgetEvent->mFlags.mWantReplyFromContentProcess = true;
|
||||
// If this event hadn't been marked as mNoCrossProcessBoundaryForwarding
|
||||
// yet, it means it wasn't processed by content. We'll not call any
|
||||
// of the handlers at this moment, and will wait for the event to be
|
||||
// redispatched with mNoCrossProcessBoundaryForwarding = 1 to process it.
|
||||
// XXX Why not StopImmediatePropagation()?
|
||||
aEvent->AsEvent()->StopPropagation();
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -17,6 +17,7 @@ class nsXBLSpecialDocInfo;
|
||||
class nsXBLPrototypeHandler;
|
||||
|
||||
namespace mozilla {
|
||||
class EventListenerManager;
|
||||
namespace dom {
|
||||
class Element;
|
||||
class EventTarget;
|
||||
@ -27,10 +28,16 @@ struct IgnoreModifierState;
|
||||
class nsXBLWindowKeyHandler : public nsIDOMEventListener
|
||||
{
|
||||
typedef mozilla::dom::IgnoreModifierState IgnoreModifierState;
|
||||
typedef mozilla::EventListenerManager EventListenerManager;
|
||||
|
||||
public:
|
||||
nsXBLWindowKeyHandler(nsIDOMElement* aElement, mozilla::dom::EventTarget* aTarget);
|
||||
|
||||
void InstallKeyboardEventListenersTo(
|
||||
EventListenerManager* aEventListenerManager);
|
||||
void RemoveKeyboardEventListenersFrom(
|
||||
EventListenerManager* aEventListenerManager);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDOMEVENTLISTENER
|
||||
|
||||
@ -55,8 +62,10 @@ protected:
|
||||
bool aExecute,
|
||||
bool* aOutReservedForChrome = nullptr);
|
||||
|
||||
// HandleEvent function for the capturing phase.
|
||||
void HandleEventOnCapture(nsIDOMKeyEvent* aEvent);
|
||||
// HandleEvent function for the capturing phase in the default event group.
|
||||
void HandleEventOnCaptureInDefaultEventGroup(nsIDOMKeyEvent* aEvent);
|
||||
// HandleEvent function for the capturing phase in the system event group.
|
||||
void HandleEventOnCaptureInSystemEventGroup(nsIDOMKeyEvent* aEvent);
|
||||
|
||||
// Check if any handler would handle the given event. Optionally returns
|
||||
// whether the command handler for the event is marked with the "reserved"
|
||||
|
@ -11,6 +11,8 @@ MOCHITEST_MANIFESTS += [
|
||||
|
||||
MOCHITEST_CHROME_MANIFESTS += ['tests/chrome.ini']
|
||||
|
||||
BROWSER_CHROME_MANIFESTS += ['tests/browser.ini']
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'ChangeAttributeTxn.cpp',
|
||||
'ChangeStyleTxn.cpp',
|
||||
|
6
editor/libeditor/tests/browser.ini
Normal file
6
editor/libeditor/tests/browser.ini
Normal file
@ -0,0 +1,6 @@
|
||||
[browser_bug527935.js]
|
||||
skip-if = toolkit == 'android'
|
||||
support-files = bug527935.html
|
||||
[browser_bug629172.js]
|
||||
skip-if = toolkit == 'android'
|
||||
support-files = bug629172.html
|
63
editor/libeditor/tests/browser_bug527935.js
Normal file
63
editor/libeditor/tests/browser_bug527935.js
Normal file
@ -0,0 +1,63 @@
|
||||
add_task(function*() {
|
||||
yield new Promise(resolve => waitForFocus(resolve, window));
|
||||
|
||||
const kPageURL = "http://example.org/browser/editor/libeditor/tests/bug527935.html";
|
||||
yield BrowserTestUtils.withNewTab({
|
||||
gBrowser,
|
||||
url: kPageURL
|
||||
}, function*(aBrowser) {
|
||||
var popupShown = false;
|
||||
function listener() {
|
||||
popupShown = true;
|
||||
}
|
||||
SpecialPowers.addAutoCompletePopupEventListener(window, "popupshowing", listener);
|
||||
|
||||
yield ContentTask.spawn(aBrowser, {}, function*() {
|
||||
var window = content.window.wrappedJSObject;
|
||||
var document = window.document;
|
||||
var formTarget = document.getElementById("formTarget");
|
||||
var initValue = document.getElementById("initValue");
|
||||
|
||||
window.loadPromise = new Promise(resolve => {
|
||||
formTarget.onload = resolve;
|
||||
});
|
||||
|
||||
initValue.focus();
|
||||
initValue.value = "foo";
|
||||
});
|
||||
|
||||
EventUtils.synthesizeKey("VK_RETURN", {});
|
||||
|
||||
yield ContentTask.spawn(aBrowser, {}, function*() {
|
||||
var window = content.window.wrappedJSObject;
|
||||
var document = window.document;
|
||||
|
||||
yield window.loadPromise;
|
||||
|
||||
var newInput = document.createElement("input");
|
||||
newInput.setAttribute("name", "test");
|
||||
document.body.appendChild(newInput);
|
||||
|
||||
var event = document.createEvent("KeyboardEvent");
|
||||
|
||||
event.initKeyEvent("keypress", true, true, null, false, false,
|
||||
false, false, 0, "f".charCodeAt(0));
|
||||
newInput.value = "";
|
||||
newInput.focus();
|
||||
newInput.dispatchEvent(event);
|
||||
});
|
||||
|
||||
yield new Promise(resolve => hitEventLoop(resolve, 100));
|
||||
|
||||
ok(!popupShown, "Popup must not be opened");
|
||||
SpecialPowers.removeAutoCompletePopupEventListener(window, "popupshowing", listener);
|
||||
});
|
||||
});
|
||||
|
||||
function hitEventLoop(func, times) {
|
||||
if (times > 0) {
|
||||
setTimeout(hitEventLoop, 0, func, times - 1);
|
||||
} else {
|
||||
setTimeout(func, 0);
|
||||
}
|
||||
}
|
106
editor/libeditor/tests/browser_bug629172.js
Normal file
106
editor/libeditor/tests/browser_bug629172.js
Normal file
@ -0,0 +1,106 @@
|
||||
add_task(function*() {
|
||||
yield new Promise(resolve => waitForFocus(resolve, window));
|
||||
|
||||
const kPageURL = "http://example.org/browser/editor/libeditor/tests/bug629172.html";
|
||||
yield BrowserTestUtils.withNewTab({
|
||||
gBrowser,
|
||||
url: kPageURL
|
||||
}, function*(aBrowser) {
|
||||
yield ContentTask.spawn(aBrowser, {}, function*() {
|
||||
var window = content.window.wrappedJSObject;
|
||||
var document = window.document;
|
||||
|
||||
// Note: Using the with keyword, we would have been able to write this as:
|
||||
//
|
||||
// with (window) {
|
||||
// Screenshots = {};
|
||||
// // so on
|
||||
// }
|
||||
//
|
||||
// However, browser-chrome tests are somehow forced to run in strict mode,
|
||||
// which doesn't permit the usage of the with keyword, turning the following
|
||||
// into the ugliest test you've ever seen. :(
|
||||
var LTRRef = document.getElementById("ltr-ref");
|
||||
var RTLRef = document.getElementById("rtl-ref");
|
||||
window.Screenshots = {};
|
||||
|
||||
// generate the reference screenshots
|
||||
LTRRef.style.display = "";
|
||||
document.body.clientWidth;
|
||||
window.Screenshots.ltr = window.snapshotWindow(window);
|
||||
LTRRef.parentNode.removeChild(LTRRef);
|
||||
RTLRef.style.display = "";
|
||||
document.body.clientWidth;
|
||||
window.Screenshots.rtl = window.snapshotWindow(window);
|
||||
RTLRef.parentNode.removeChild(RTLRef);
|
||||
window.Screenshots.get = function(dir, flip) {
|
||||
if (flip) {
|
||||
return this[dir == "rtl" ? "ltr" : "rtl"];
|
||||
} else {
|
||||
return this[dir];
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
function simulateCtrlShiftX(aBrowser) {
|
||||
// In e10s, the keypress event will be dispatched to the content process,
|
||||
// but in non-e10s it is handled by the browser UI code and hence won't
|
||||
// reach the web page. As a result, we need to observe the event in
|
||||
// the content process only in e10s mode.
|
||||
var waitForKeypressContent = BrowserTestUtils.waitForContentEvent(aBrowser, "keypress");
|
||||
EventUtils.synthesizeKey("x", {accelKey: true, shiftKey: true});
|
||||
if (gMultiProcessBrowser) {
|
||||
return waitForKeypressContent;
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
function* testDirection(initialDir, aBrowser) {
|
||||
yield ContentTask.spawn(aBrowser, {initialDir}, function({initialDir}) {
|
||||
var window = content.window.wrappedJSObject;
|
||||
var document = window.document;
|
||||
|
||||
var t = window.t = document.createElement("textarea");
|
||||
t.setAttribute("dir", initialDir);
|
||||
t.value = "test.";
|
||||
window.inputEventCount = 0;
|
||||
t.oninput = function() { window.inputEventCount++; };
|
||||
document.getElementById("content").appendChild(t);
|
||||
document.body.clientWidth;
|
||||
var s1 = window.snapshotWindow(window);
|
||||
ok(window.compareSnapshots(s1, window.Screenshots.get(initialDir, false), true)[0],
|
||||
"Textarea should appear correctly before switching the direction (" + initialDir + ")");
|
||||
t.focus();
|
||||
is(window.inputEventCount, 0, "input event count must be 0 before");
|
||||
});
|
||||
yield simulateCtrlShiftX(aBrowser);
|
||||
yield ContentTask.spawn(aBrowser, {initialDir}, function({initialDir}) {
|
||||
var window = content.window.wrappedJSObject;
|
||||
|
||||
is(window.t.getAttribute("dir"), initialDir == "ltr" ? "rtl" : "ltr", "The dir attribute must be correctly updated");
|
||||
is(window.inputEventCount, 1, "input event count must be 1 after");
|
||||
window.t.blur();
|
||||
var s2 = window.snapshotWindow(window);
|
||||
ok(window.compareSnapshots(s2, window.Screenshots.get(initialDir, true), true)[0],
|
||||
"Textarea should appear correctly after switching the direction (" + initialDir + ")");
|
||||
window.t.focus();
|
||||
is(window.inputEventCount, 1, "input event count must be 1 before");
|
||||
});
|
||||
yield simulateCtrlShiftX(aBrowser);
|
||||
yield ContentTask.spawn(aBrowser, {initialDir}, function({initialDir}) {
|
||||
var window = content.window.wrappedJSObject;
|
||||
|
||||
is(window.inputEventCount, 2, "input event count must be 2 after");
|
||||
is(window.t.getAttribute("dir"), initialDir == "ltr" ? "ltr" : "rtl", "The dir attribute must be correctly updated");
|
||||
window.t.blur();
|
||||
var s3 = window.snapshotWindow(window);
|
||||
ok(window.compareSnapshots(s3, window.Screenshots.get(initialDir, false), true)[0],
|
||||
"Textarea should appear correctly after switching back the direction (" + initialDir + ")");
|
||||
window.t.parentNode.removeChild(window.t);
|
||||
});
|
||||
}
|
||||
|
||||
yield testDirection("ltr", aBrowser);
|
||||
yield testDirection("rtl", aBrowser);
|
||||
});
|
||||
});
|
11
editor/libeditor/tests/bug527935.html
Normal file
11
editor/libeditor/tests/bug527935.html
Normal file
@ -0,0 +1,11 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<body>
|
||||
<div id="content">
|
||||
<iframe id="formTarget" name="formTarget"></iframe>
|
||||
<form action="data:text/html," target="formTarget">
|
||||
<input name="test" id="initValue"><input type="submit">
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html
|
15
editor/libeditor/tests/bug629172.html
Normal file
15
editor/libeditor/tests/bug629172.html
Normal file
@ -0,0 +1,15 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script>
|
||||
<style>
|
||||
textarea { resize: none }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="content">
|
||||
<textarea id="ltr-ref" style="display: none">test.</textarea>
|
||||
<textarea id="rtl-ref" style="display: none; direction: rtl">test.</textarea>
|
||||
</div
|
||||
</body>
|
||||
</html>
|
@ -58,8 +58,6 @@ skip-if = toolkit == 'android'
|
||||
skip-if = toolkit == 'android'
|
||||
[test_bug525389.html]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_bug527935.html]
|
||||
skip-if = toolkit == 'android' || e10s
|
||||
[test_bug537046.html]
|
||||
[test_bug549262.html]
|
||||
skip-if = toolkit == 'android'
|
||||
@ -102,8 +100,6 @@ skip-if = toolkit == 'android' #TIMED_OUT
|
||||
[test_bug622371.html]
|
||||
skip-if = toolkit == 'android' #bug 957797
|
||||
[test_bug625452.html]
|
||||
[test_bug629172.html]
|
||||
skip-if = toolkit == 'android' || e10s
|
||||
[test_bug629845.html]
|
||||
[test_bug638596.html]
|
||||
[test_bug640321.html]
|
||||
|
@ -1,74 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=527935
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 527935</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=527935">Mozilla Bug 527935</a>
|
||||
<p id="display"></p>
|
||||
<div id="content">
|
||||
<iframe id="formTarget" name="formTarget"></iframe>
|
||||
<form action="data:text/html," target="formTarget">
|
||||
<input name="test" id="initValue"><input type="submit">
|
||||
</form>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 527935 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.waitForFocus(function() {
|
||||
var formTarget = document.getElementById("formTarget");
|
||||
var initValue = document.getElementById("initValue");
|
||||
|
||||
formTarget.addEventListener("load", function() {
|
||||
var newInput = document.createElement("input");
|
||||
newInput.setAttribute("name", "test");
|
||||
document.body.appendChild(newInput);
|
||||
|
||||
setTimeout(function() {
|
||||
var popupShown = false;
|
||||
function listener() {
|
||||
popupShown = true;
|
||||
}
|
||||
SpecialPowers.addAutoCompletePopupEventListener(window, "popupshowing", listener);
|
||||
|
||||
var event = document.createEvent("KeyboardEvent");
|
||||
|
||||
event.initKeyEvent("keypress", true, true, null, false, false,
|
||||
false, false, 0, "f".charCodeAt(0));
|
||||
newInput.value = "";
|
||||
newInput.focus();
|
||||
newInput.dispatchEvent(event);
|
||||
|
||||
hitEventLoop(function() {
|
||||
ok(!popupShown, "Popup must not be opened");
|
||||
SpecialPowers.removeAutoCompletePopupEventListener(window, "popupshowing", listener);
|
||||
SimpleTest.finish();
|
||||
}, 100);
|
||||
}, 0);
|
||||
}, false);
|
||||
|
||||
initValue.focus();
|
||||
initValue.value = "foo";
|
||||
synthesizeKey("VK_RETURN", {});
|
||||
});
|
||||
|
||||
function hitEventLoop(func, times) {
|
||||
if (times > 0) {
|
||||
setTimeout(hitEventLoop, 0, func, times - 1);
|
||||
} else {
|
||||
setTimeout(func, 0);
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -1,88 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=629172
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 629172</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=629172">Mozilla Bug 629172</a>
|
||||
<p id="display"></p>
|
||||
<div id="content">
|
||||
<textarea id="ltr-ref" style="display: none">test.</textarea>
|
||||
<textarea id="rtl-ref" style="display: none; direction: rtl">test.</textarea>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 629172 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.waitForFocus(function() {
|
||||
var LTRRef = document.getElementById("ltr-ref");
|
||||
var RTLRef = document.getElementById("rtl-ref");
|
||||
var Screenshots = {};
|
||||
|
||||
// generate the reference screenshots
|
||||
LTRRef.style.display = "";
|
||||
document.body.clientWidth;
|
||||
Screenshots.ltr = snapshotWindow(window);
|
||||
LTRRef.parentNode.removeChild(LTRRef);
|
||||
RTLRef.style.display = "";
|
||||
document.body.clientWidth;
|
||||
Screenshots.rtl = snapshotWindow(window);
|
||||
RTLRef.parentNode.removeChild(RTLRef);
|
||||
Screenshots.get = function(dir, flip) {
|
||||
if (flip) {
|
||||
return this[dir == "rtl" ? "ltr" : "rtl"];
|
||||
} else {
|
||||
return this[dir];
|
||||
}
|
||||
};
|
||||
|
||||
function testDirection(initialDir) {
|
||||
var t = document.createElement("textarea");
|
||||
t.setAttribute("dir", initialDir);
|
||||
t.value = "test.";
|
||||
var inputEventCount = 0;
|
||||
t.oninput = function() { inputEventCount++; };
|
||||
document.getElementById("content").appendChild(t);
|
||||
document.body.clientWidth;
|
||||
var s1 = snapshotWindow(window);
|
||||
ok(compareSnapshots(s1, Screenshots.get(initialDir, false), true)[0],
|
||||
"Textarea should appear correctly before switching the direction (" + initialDir + ")");
|
||||
t.focus();
|
||||
is(inputEventCount, 0, "input event count must be 0 before");
|
||||
synthesizeKey("x", {accelKey: true, shiftKey: true});
|
||||
is(t.getAttribute("dir"), initialDir == "ltr" ? "rtl" : "ltr", "The dir attribute must be correctly updated");
|
||||
is(inputEventCount, 1, "input event count must be 1 after");
|
||||
t.blur();
|
||||
var s2 = snapshotWindow(window);
|
||||
ok(compareSnapshots(s2, Screenshots.get(initialDir, true), true)[0],
|
||||
"Textarea should appear correctly after switching the direction (" + initialDir + ")");
|
||||
t.focus();
|
||||
is(inputEventCount, 1, "input event count must be 1 before");
|
||||
synthesizeKey("x", {accelKey: true, shiftKey: true});
|
||||
is(inputEventCount, 2, "input event count must be 2 after");
|
||||
is(t.getAttribute("dir"), initialDir == "ltr" ? "ltr" : "rtl", "The dir attribute must be correctly updated");
|
||||
t.blur();
|
||||
var s3 = snapshotWindow(window);
|
||||
ok(compareSnapshots(s3, Screenshots.get(initialDir, false), true)[0],
|
||||
"Textarea should appear correctly after switching back the direction (" + initialDir + ")");
|
||||
t.parentNode.removeChild(t);
|
||||
}
|
||||
|
||||
testDirection("ltr");
|
||||
testDirection("rtl");
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -15,24 +15,20 @@ angle_git_is_present = exec_script("src/commit_id.py",
|
||||
|
||||
angle_use_commit_id = angle_git_is_present == 1
|
||||
|
||||
gles_gypi = exec_script(
|
||||
"//build/gypi_to_gn.py",
|
||||
[ rebase_path("src/libGLESv2.gypi") ],
|
||||
"scope",
|
||||
[ "src/libGLESv2.gypi" ])
|
||||
gles_gypi = exec_script("//build/gypi_to_gn.py",
|
||||
[ rebase_path("src/libGLESv2.gypi") ],
|
||||
"scope",
|
||||
[ "src/libGLESv2.gypi" ])
|
||||
|
||||
compiler_gypi = exec_script(
|
||||
"//build/gypi_to_gn.py",
|
||||
[ rebase_path("src/compiler.gypi") ],
|
||||
"scope",
|
||||
[ "src/compiler.gypi" ])
|
||||
compiler_gypi = exec_script("//build/gypi_to_gn.py",
|
||||
[ rebase_path("src/compiler.gypi") ],
|
||||
"scope",
|
||||
[ "src/compiler.gypi" ])
|
||||
|
||||
# This config is exported to dependent targets (and also applied to internal
|
||||
# ones).
|
||||
config("external_config") {
|
||||
include_dirs = [
|
||||
"include",
|
||||
]
|
||||
include_dirs = [ "include" ]
|
||||
}
|
||||
|
||||
# This config is applied to internal Angle targets (not pushed to dependents).
|
||||
@ -45,8 +41,12 @@ config("internal_config") {
|
||||
|
||||
if (is_win) {
|
||||
copy("copy_compiler_dll") {
|
||||
sources = [ "$windows_sdk_path/Redist/D3D/$target_cpu/d3dcompiler_47.dll" ]
|
||||
outputs = [ "$root_build_dir/d3dcompiler_47.dll" ]
|
||||
sources = [
|
||||
"$windows_sdk_path/Redist/D3D/$target_cpu/d3dcompiler_47.dll",
|
||||
]
|
||||
outputs = [
|
||||
"$root_out_dir/d3dcompiler_47.dll",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,11 +58,6 @@ component("translator") {
|
||||
|
||||
defines = [ "ANGLE_TRANSLATOR_IMPLEMENTATION" ]
|
||||
|
||||
if (angle_enable_hlsl) {
|
||||
sources += rebase_path(compiler_gypi.angle_translator_lib_hlsl_sources, ".", "src")
|
||||
defines += [ "ANGLE_ENABLE_HLSL" ]
|
||||
}
|
||||
|
||||
configs -= [ "//build/config/compiler:chromium_code" ]
|
||||
configs += [
|
||||
":internal_config",
|
||||
@ -84,9 +79,9 @@ source_set("includes") {
|
||||
"include/GLES2/gl2ext.h",
|
||||
"include/GLES2/gl2platform.h",
|
||||
"include/GLES3/gl3.h",
|
||||
"include/GLES3/gl3platform.h",
|
||||
"include/GLES3/gl31.h",
|
||||
"include/GLES3/gl32.h",
|
||||
"include/GLES3/gl3platform.h",
|
||||
"include/GLSLANG/ShaderLang.h",
|
||||
"include/KHR/khrplatform.h",
|
||||
]
|
||||
@ -106,12 +101,9 @@ config("translator_static_config") {
|
||||
defines = [ "ANGLE_TRANSLATOR_STATIC" ]
|
||||
}
|
||||
|
||||
|
||||
config("debug_annotations_config") {
|
||||
if (is_debug) {
|
||||
defines = [
|
||||
"ANGLE_ENABLE_DEBUG_ANNOTATIONS",
|
||||
]
|
||||
defines = [ "ANGLE_ENABLE_DEBUG_ANNOTATIONS" ]
|
||||
}
|
||||
}
|
||||
|
||||
@ -128,10 +120,24 @@ static_library("angle_common") {
|
||||
|
||||
static_library("translator_lib") {
|
||||
sources = rebase_path(compiler_gypi.angle_translator_lib_sources, ".", "src")
|
||||
defines = []
|
||||
|
||||
if (angle_enable_essl) {
|
||||
sources +=
|
||||
rebase_path(compiler_gypi.angle_translator_lib_essl_sources, ".", "src")
|
||||
defines += [ "ANGLE_ENABLE_ESSL" ]
|
||||
}
|
||||
|
||||
if (angle_enable_glsl) {
|
||||
sources +=
|
||||
rebase_path(compiler_gypi.angle_translator_lib_glsl_sources, ".", "src")
|
||||
defines += [ "ANGLE_ENABLE_GLSL" ]
|
||||
}
|
||||
|
||||
if (angle_enable_hlsl) {
|
||||
sources += rebase_path(compiler_gypi.angle_translator_lib_hlsl_sources, ".", "src")
|
||||
defines = [ "ANGLE_ENABLE_HLSL" ]
|
||||
sources +=
|
||||
rebase_path(compiler_gypi.angle_translator_lib_hlsl_sources, ".", "src")
|
||||
defines += [ "ANGLE_ENABLE_HLSL" ]
|
||||
}
|
||||
configs -= [ "//build/config/compiler:chromium_code" ]
|
||||
configs += [
|
||||
@ -246,18 +252,13 @@ static_library("libANGLE") {
|
||||
|
||||
include_dirs = []
|
||||
libs = []
|
||||
defines = [
|
||||
"LIBANGLE_IMPLEMENTATION",
|
||||
]
|
||||
defines = [ "LIBANGLE_IMPLEMENTATION" ]
|
||||
|
||||
# Shared D3D sources.
|
||||
if (angle_enable_d3d9 || angle_enable_d3d11) {
|
||||
sources += rebase_path(gles_gypi.libangle_d3d_shared_sources, ".", "src")
|
||||
|
||||
defines += [
|
||||
"ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ " +
|
||||
"\"d3dcompiler_47.dll\", \"d3dcompiler_46.dll\", \"d3dcompiler_43.dll\" }",
|
||||
]
|
||||
defines += [ "ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ " + "\"d3dcompiler_47.dll\", \"d3dcompiler_46.dll\", \"d3dcompiler_43.dll\" }" ]
|
||||
}
|
||||
|
||||
if (angle_enable_d3d9) {
|
||||
@ -285,9 +286,7 @@ static_library("libANGLE") {
|
||||
}
|
||||
|
||||
if (is_debug) {
|
||||
defines += [
|
||||
"ANGLE_GENERATE_SHADER_DEBUG_INFO",
|
||||
]
|
||||
defines += [ "ANGLE_GENERATE_SHADER_DEBUG_INFO" ]
|
||||
}
|
||||
|
||||
configs -= [ "//build/config/compiler:chromium_code" ]
|
||||
@ -300,10 +299,10 @@ static_library("libANGLE") {
|
||||
]
|
||||
|
||||
deps = [
|
||||
":angle_common",
|
||||
":commit_id",
|
||||
":includes",
|
||||
":translator_static",
|
||||
":angle_common",
|
||||
]
|
||||
|
||||
if (is_win) {
|
||||
@ -315,8 +314,8 @@ shared_library("libGLESv2") {
|
||||
sources = rebase_path(gles_gypi.libglesv2_sources, ".", "src")
|
||||
|
||||
if (is_win) {
|
||||
ldflags = [ "/DEF:" +
|
||||
rebase_path("src/libGLESv2/libGLESv2.def", root_build_dir) ]
|
||||
ldflags =
|
||||
[ "/DEF:" + rebase_path("src/libGLESv2/libGLESv2.def", root_build_dir) ]
|
||||
}
|
||||
|
||||
configs -= [ "//build/config/compiler:chromium_code" ]
|
||||
@ -328,9 +327,7 @@ shared_library("libGLESv2") {
|
||||
"//build/config/compiler:no_chromium_code",
|
||||
]
|
||||
|
||||
defines = [
|
||||
"LIBGLESV2_IMPLEMENTATION",
|
||||
]
|
||||
defines = [ "LIBGLESV2_IMPLEMENTATION" ]
|
||||
|
||||
deps = [
|
||||
":includes",
|
||||
@ -342,8 +339,7 @@ shared_library("libEGL") {
|
||||
sources = rebase_path(gles_gypi.libegl_sources, ".", "src")
|
||||
|
||||
if (is_win) {
|
||||
ldflags = [ "/DEF:" +
|
||||
rebase_path("src/libEGL/libEGL.def", root_build_dir) ]
|
||||
ldflags = [ "/DEF:" + rebase_path("src/libEGL/libEGL.def", root_build_dir) ]
|
||||
}
|
||||
|
||||
configs -= [ "//build/config/compiler:chromium_code" ]
|
||||
@ -355,9 +351,7 @@ shared_library("libEGL") {
|
||||
"//build/config/compiler:no_chromium_code",
|
||||
]
|
||||
|
||||
defines = [
|
||||
"LIBEGL_IMPLEMENTATION",
|
||||
]
|
||||
defines = [ "LIBEGL_IMPLEMENTATION" ]
|
||||
|
||||
deps = [
|
||||
":includes",
|
||||
@ -365,11 +359,17 @@ shared_library("libEGL") {
|
||||
]
|
||||
}
|
||||
|
||||
util_gypi = exec_script(
|
||||
"//build/gypi_to_gn.py",
|
||||
[ rebase_path("util/util.gyp") ],
|
||||
"scope",
|
||||
[ "util/util.gyp" ])
|
||||
util_gypi = exec_script("//build/gypi_to_gn.py",
|
||||
[ rebase_path("util/util.gyp") ],
|
||||
"scope",
|
||||
[ "util/util.gyp" ])
|
||||
|
||||
config("angle_util_config") {
|
||||
include_dirs = [ "util" ]
|
||||
if (is_linux) {
|
||||
libs = [ "X11" ]
|
||||
}
|
||||
}
|
||||
|
||||
static_library("angle_util") {
|
||||
sources = rebase_path(util_gypi.util_sources, ".", "util")
|
||||
@ -396,16 +396,15 @@ static_library("angle_util") {
|
||||
"EGL_EGLEXT_PROTOTYPES",
|
||||
]
|
||||
|
||||
configs += [
|
||||
":internal_config",
|
||||
":debug_annotations_config",
|
||||
]
|
||||
configs += [ ":debug_annotations_config" ]
|
||||
|
||||
include_dirs = [
|
||||
"util",
|
||||
public_configs = [
|
||||
":angle_util_config",
|
||||
":internal_config",
|
||||
]
|
||||
|
||||
deps = [
|
||||
":angle_common",
|
||||
":libEGL",
|
||||
":libGLESv2",
|
||||
]
|
||||
|
@ -66,6 +66,40 @@ hooks = [
|
||||
'-s', 'buildtools/linux64/clang-format.sha1',
|
||||
],
|
||||
},
|
||||
# Pull GN binaries using checked-in hashes.
|
||||
{
|
||||
'name': 'gn_win',
|
||||
'pattern': '.',
|
||||
'action': [ 'download_from_google_storage',
|
||||
'--no_resume',
|
||||
'--platform=win32',
|
||||
'--no_auth',
|
||||
'--bucket', 'chromium-gn',
|
||||
'-s', 'buildtools/win/gn.exe.sha1',
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': 'gn_mac',
|
||||
'pattern': '.',
|
||||
'action': [ 'download_from_google_storage',
|
||||
'--no_resume',
|
||||
'--platform=darwin',
|
||||
'--no_auth',
|
||||
'--bucket', 'chromium-gn',
|
||||
'-s', 'buildtools/mac/gn.sha1',
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': 'gn_linux64',
|
||||
'pattern': '.',
|
||||
'action': [ 'download_from_google_storage',
|
||||
'--no_resume',
|
||||
'--platform=linux*',
|
||||
'--no_auth',
|
||||
'--bucket', 'chromium-gn',
|
||||
'-s', 'buildtools/linux64/gn.sha1',
|
||||
],
|
||||
},
|
||||
{
|
||||
# A change to a .gyp, .gypi, or to GYP itself should run the generator.
|
||||
"pattern": ".",
|
||||
|
@ -39,5 +39,6 @@ View the [Dev setup instructions](doc/DevSetup.md). For generating a Windows Sto
|
||||
* Read about WebGL on the [Khronos WebGL Wiki](http://khronos.org/webgl/wiki/Main_Page).
|
||||
* Learn about implementation details in the [OpenGL Insights chapter on ANGLE](http://www.seas.upenn.edu/~pcozzi/OpenGLInsights/OpenGLInsights-ANGLE.pdf) and this [ANGLE presentation](https://drive.google.com/file/d/0Bw29oYeC09QbbHoxNE5EUFh0RGs/view?usp=sharing).
|
||||
* Learn about the past, present, and future of the ANGLE implementation in [this recent presentation](https://docs.google.com/presentation/d/1CucIsdGVDmdTWRUbg68IxLE5jXwCb2y1E9YVhQo0thg/pub?start=false&loop=false).
|
||||
* Notes on [debugging ANGLE](doc/DebuggingTips.md).
|
||||
* If you use ANGLE in your own project, we'd love to hear about it!
|
||||
|
||||
|
@ -468,6 +468,11 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu
|
||||
#define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1
|
||||
#endif /* EGL_ANGLE_surface_d3d_texture_2d_share_handle */
|
||||
|
||||
#ifndef EGL_ANGLE_direct_composition
|
||||
#define EGL_ANGLE_direct_composition 1
|
||||
#define EGL_DIRECT_COMPOSITION_ANGLE 0x33A5
|
||||
#endif /* EGL_ANGLE_direct_composition */
|
||||
|
||||
#ifndef EGL_ANGLE_platform_angle
|
||||
#define EGL_ANGLE_platform_angle 1
|
||||
#define EGL_PLATFORM_ANGLE_ANGLE 0x3202
|
||||
@ -504,6 +509,26 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu
|
||||
#define EGL_X11_VISUAL_ID_ANGLE 0x33A3
|
||||
#endif /* EGL_ANGLE_x11_visual */
|
||||
|
||||
#ifndef EGL_ANGLE_flexible_surface_compatibility
|
||||
#define EGL_ANGLE_flexible_surface_compatibility 1
|
||||
#define EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE 0x33A6
|
||||
#endif /* EGL_ANGLE_flexible_surface_compatibility */
|
||||
|
||||
#ifndef EGL_ANGLE_surface_orientation
|
||||
#define EGL_ANGLE_surface_orientation
|
||||
#define EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE 0x33A7
|
||||
#define EGL_SURFACE_ORIENTATION_ANGLE 0x33A8
|
||||
#define EGL_SURFACE_ORIENTATION_INVERT_X_ANGLE 0x0001
|
||||
#define EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE 0x0002
|
||||
#endif /* EGL_ANGLE_surface_orientation */
|
||||
|
||||
#ifndef EGL_ANGLE_experimental_present_path
|
||||
#define EGL_ANGLE_experimental_present_path
|
||||
#define EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE 0x33A4
|
||||
#define EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE 0x33A9
|
||||
#define EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE 0x33AA
|
||||
#endif /* EGL_ANGLE_experimental_present_path */
|
||||
|
||||
#ifndef EGL_ARM_pixmap_multisample_discard
|
||||
#define EGL_ARM_pixmap_multisample_discard 1
|
||||
#define EGL_DISCARD_SAMPLES_ARM 0x3286
|
||||
|
@ -2920,6 +2920,21 @@ GL_APICALL void GL_APIENTRY glEndTilingQCOM (GLbitfield preserveMask);
|
||||
#define GL_SHADER_BINARY_VIV 0x8FC4
|
||||
#endif /* GL_VIV_shader_binary */
|
||||
|
||||
#ifndef GL_ANGLE_lossy_etc_decode
|
||||
#define GL_ANGLE_lossy_etc_decode 1
|
||||
#define GL_ETC1_RGB8_LOSSY_DECODE_ANGLE 0x9690
|
||||
#define GL_COMPRESSED_R11_LOSSY_DECODE_EAC_ANGLE 0x9691
|
||||
#define GL_COMPRESSED_SIGNED_R11_LOSSY_DECODE_EAC_ANGLE 0x9692
|
||||
#define GL_COMPRESSED_RG11_LOSSY_DECODE_EAC_ANGLE 0x9693
|
||||
#define GL_COMPRESSED_SIGNED_RG11_LOSSY_DECODE_EAC_ANGLE 0x9694
|
||||
#define GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE 0x9695
|
||||
#define GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE 0x9696
|
||||
#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE 0x9697
|
||||
#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE 0x9698
|
||||
#define GL_COMPRESSED_RGBA8_LOSSY_DECODE_ETC2_EAC_ANGLE 0x9699
|
||||
#define GL_COMPRESSED_SRGB8_ALPHA8_LOSSY_DECODE_ETC2_EAC_ANGLE 0x969A
|
||||
#endif /* GL_ANGLE_lossy_etc_decode */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -48,7 +48,7 @@ typedef unsigned int GLenum;
|
||||
|
||||
// Version number for shader translation API.
|
||||
// It is incremented every time the API changes.
|
||||
#define ANGLE_SH_VERSION 140
|
||||
#define ANGLE_SH_VERSION 143
|
||||
|
||||
typedef enum {
|
||||
SH_GLES2_SPEC = 0x8B40,
|
||||
@ -80,30 +80,35 @@ typedef enum {
|
||||
SH_CSS_SHADERS_SPEC = 0x8B42
|
||||
} ShShaderSpec;
|
||||
|
||||
typedef enum {
|
||||
SH_ESSL_OUTPUT = 0x8B45,
|
||||
// SH_GLSL_OUTPUT is deprecated. This is to not break the build.
|
||||
SH_GLSL_OUTPUT = 0x8B46,
|
||||
SH_GLSL_COMPATIBILITY_OUTPUT = 0x8B46,
|
||||
// SH_GLSL_CORE_OUTPUT is deprecated.
|
||||
SH_GLSL_CORE_OUTPUT = 0x8B47,
|
||||
//Note: GL introduced core profiles in 1.5. However, for compatiblity with Chromium, we treat SH_GLSL_CORE_OUTPUT as GLSL_130_OUTPUT.
|
||||
//TODO: Remove SH_GLSL_CORE_OUTPUT
|
||||
SH_GLSL_130_OUTPUT = 0x8B47,
|
||||
SH_GLSL_140_OUTPUT = 0x8B80,
|
||||
SH_GLSL_150_CORE_OUTPUT = 0x8B81,
|
||||
SH_GLSL_330_CORE_OUTPUT = 0x8B82,
|
||||
SH_GLSL_400_CORE_OUTPUT = 0x8B83,
|
||||
SH_GLSL_410_CORE_OUTPUT = 0x8B84,
|
||||
SH_GLSL_420_CORE_OUTPUT = 0x8B85,
|
||||
SH_GLSL_430_CORE_OUTPUT = 0x8B86,
|
||||
SH_GLSL_440_CORE_OUTPUT = 0x8B87,
|
||||
SH_GLSL_450_CORE_OUTPUT = 0x8B88,
|
||||
typedef enum
|
||||
{
|
||||
// ESSL output only supported in some configurations.
|
||||
SH_ESSL_OUTPUT = 0x8B45,
|
||||
|
||||
// HLSL output only supported in some configurations.
|
||||
SH_HLSL_OUTPUT = 0x8B48,
|
||||
SH_HLSL9_OUTPUT = 0x8B48,
|
||||
SH_HLSL11_OUTPUT = 0x8B49
|
||||
// GLSL output only supported in some configurations.
|
||||
SH_GLSL_COMPATIBILITY_OUTPUT = 0x8B46,
|
||||
// Note: GL introduced core profiles in 1.5.
|
||||
SH_GLSL_130_OUTPUT = 0x8B47,
|
||||
SH_GLSL_140_OUTPUT = 0x8B80,
|
||||
SH_GLSL_150_CORE_OUTPUT = 0x8B81,
|
||||
SH_GLSL_330_CORE_OUTPUT = 0x8B82,
|
||||
SH_GLSL_400_CORE_OUTPUT = 0x8B83,
|
||||
SH_GLSL_410_CORE_OUTPUT = 0x8B84,
|
||||
SH_GLSL_420_CORE_OUTPUT = 0x8B85,
|
||||
SH_GLSL_430_CORE_OUTPUT = 0x8B86,
|
||||
SH_GLSL_440_CORE_OUTPUT = 0x8B87,
|
||||
SH_GLSL_450_CORE_OUTPUT = 0x8B88,
|
||||
|
||||
// HLSL output only supported in some configurations.
|
||||
// Deprecated:
|
||||
SH_HLSL_OUTPUT = 0x8B48,
|
||||
SH_HLSL9_OUTPUT = 0x8B48,
|
||||
SH_HLSL11_OUTPUT = 0x8B49,
|
||||
|
||||
// Prefer using these to specify HLSL output type:
|
||||
SH_HLSL_3_0_OUTPUT = 0x8B48, // D3D 9
|
||||
SH_HLSL_4_1_OUTPUT = 0x8B49, // D3D 11
|
||||
SH_HLSL_4_0_FL9_3_OUTPUT = 0x8B4A // D3D 11 feature level 9_3
|
||||
} ShShaderOutput;
|
||||
|
||||
// Compile options.
|
||||
@ -334,9 +339,9 @@ COMPILER_EXPORT const std::string &ShGetBuiltInResourcesString(const ShHandle ha
|
||||
// type: Specifies the type of shader - GL_FRAGMENT_SHADER or GL_VERTEX_SHADER.
|
||||
// spec: Specifies the language spec the compiler must conform to -
|
||||
// SH_GLES2_SPEC or SH_WEBGL_SPEC.
|
||||
// output: Specifies the output code type - SH_ESSL_OUTPUT, SH_GLSL_OUTPUT,
|
||||
// SH_HLSL9_OUTPUT or SH_HLSL11_OUTPUT. Note: HLSL output is only
|
||||
// supported in some configurations.
|
||||
// output: Specifies the output code type - for example SH_ESSL_OUTPUT, SH_GLSL_OUTPUT,
|
||||
// SH_HLSL_3_0_OUTPUT or SH_HLSL_4_1_OUTPUT. Note: Each output type may only
|
||||
// be supported in some configurations.
|
||||
// resources: Specifies the built-in resources.
|
||||
COMPILER_EXPORT ShHandle ShConstructCompiler(
|
||||
sh::GLenum type,
|
||||
|
@ -200,6 +200,9 @@ struct COMPILER_EXPORT InterfaceBlock
|
||||
InterfaceBlock(const InterfaceBlock &other);
|
||||
InterfaceBlock &operator=(const InterfaceBlock &other);
|
||||
|
||||
// Fields from blocks with non-empty instance names are prefixed with the block name.
|
||||
std::string fieldPrefix() const;
|
||||
|
||||
std::string name;
|
||||
std::string mappedName;
|
||||
std::string instanceName;
|
||||
@ -210,6 +213,6 @@ struct COMPILER_EXPORT InterfaceBlock
|
||||
std::vector<InterfaceBlockField> fields;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace sh
|
||||
|
||||
#endif // GLSLANG_SHADERVARS_H_
|
||||
|
@ -108,7 +108,8 @@ SOURCES += [
|
||||
'src/compiler/translator/glslang_tab.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['GNU_CXX'] or CONFIG['CLANG_CL']:
|
||||
|
||||
if CONFIG['GNU_CXX']:
|
||||
CXXFLAGS += [
|
||||
'-Wno-attributes',
|
||||
'-Wno-shadow',
|
||||
@ -116,16 +117,16 @@ if CONFIG['GNU_CXX'] or CONFIG['CLANG_CL']:
|
||||
'-Wno-unknown-pragmas',
|
||||
'-Wno-unreachable-code',
|
||||
]
|
||||
if CONFIG['GNU_CXX'] and not CONFIG['CLANG_CXX'] and not CONFIG['CLANG_CL']:
|
||||
CXXFLAGS += [
|
||||
'-Wno-shadow-compatible-local',
|
||||
'-Wno-shadow-local',
|
||||
]
|
||||
if CONFIG['CLANG_CXX'] or CONFIG['CLANG_CL']:
|
||||
CXXFLAGS += [
|
||||
'-Wno-inconsistent-missing-override',
|
||||
'-Wno-unused-private-field',
|
||||
]
|
||||
if CONFIG['CLANG_CXX']:
|
||||
CXXFLAGS += [
|
||||
'-Wno-inconsistent-missing-override',
|
||||
'-Wno-unused-private-field',
|
||||
]
|
||||
else:
|
||||
CXXFLAGS += [
|
||||
'-Wno-shadow-compatible-local',
|
||||
'-Wno-shadow-local',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_DIRECTX_SDK_PATH'] and not CONFIG['MOZ_HAS_WINSDK_WITH_D3D']:
|
||||
LOCAL_INCLUDES += ['%' + '%s/include/' % CONFIG['MOZ_DIRECTX_SDK_PATH']]
|
||||
@ -154,6 +155,8 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||
DIRS += [ 'src/libANGLE', 'src/libGLESv2', 'src/libEGL' ]
|
||||
|
||||
DEFINES['ANGLE_ENABLE_HLSL'] = "1"
|
||||
DEFINES['ANGLE_ENABLE_GLSL'] = "1"
|
||||
DEFINES['ANGLE_ENABLE_ESSL'] = "1"
|
||||
DEFINES['ANGLE_ENABLE_KEYEDMUTEX'] = "1"
|
||||
|
||||
EXPORTS.angle += [ 'include/GLSLANG/ShaderLang.h', 'include/GLSLANG/ShaderVars.h' ]
|
||||
|
@ -16,6 +16,8 @@
|
||||
'angle_enable_d3d9%': 0,
|
||||
'angle_enable_d3d11%': 0,
|
||||
'angle_enable_gl%': 0,
|
||||
'angle_enable_essl%': 1, # Enable this for all configs by default
|
||||
'angle_enable_glsl%': 1, # Enable this for all configs by default
|
||||
'angle_enable_hlsl%': 0,
|
||||
'angle_link_glx%': 0,
|
||||
'angle_gl_library_type%': 'shared_library',
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user