зеркало из https://github.com/mozilla/gecko-dev.git
merge mozilla-inbound to mozilla-central a=merge
This commit is contained in:
Коммит
0def8508d2
3
CLOBBER
3
CLOBBER
|
@ -22,5 +22,4 @@
|
|||
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||
# don't change CLOBBER for WebIDL changes any more.
|
||||
|
||||
b=1010371; ANGLE update. Files got moved around, needs a clobber to fix.
|
||||
|
||||
bug 940506: removing idl files appears to break the build without a clobber
|
||||
|
|
17
Makefile.in
17
Makefile.in
|
@ -250,9 +250,26 @@ MOZ_SOURCE_STAMP := $(MOZ_SOURCE_STAMP)
|
|||
export MOZ_SOURCE_STAMP
|
||||
endif
|
||||
|
||||
.PHONY: update-packaging
|
||||
update-packaging:
|
||||
$(MAKE) -C tools/update-packaging
|
||||
|
||||
.PHONY: pretty-package
|
||||
pretty-package:
|
||||
$(MAKE) package MOZ_PKG_PRETTYNAMES=1
|
||||
|
||||
.PHONY: pretty-package-tests
|
||||
pretty-package-tests:
|
||||
$(MAKE) package-tests MOZ_PKG_PRETTYNAMES=1
|
||||
|
||||
.PHONY: pretty-l10n-check
|
||||
pretty-l10n-check:
|
||||
$(MAKE) l10n-check MOZ_PKG_PRETTYNAMES=1
|
||||
|
||||
.PHONY: pretty-update-packaging
|
||||
pretty-update-packaging:
|
||||
$(MAKE) -C tools/update-packaging MOZ_PKG_PRETTYNAMES=1
|
||||
|
||||
#XXX: this is a hack, since we don't want to clobber for MSVC
|
||||
# PGO support, but we can't do this test in client.mk
|
||||
ifneq ($(OS_ARCH)_$(GNU_CC), WINNT_)
|
||||
|
|
|
@ -81,6 +81,14 @@ def print_header_file(fd, conf):
|
|||
fd.write(" %s\n" % attributeVariableTypeAndName(a))
|
||||
fd.write("};\n\n")
|
||||
|
||||
fd.write("namespace mozilla {\n"
|
||||
"template<>\n"
|
||||
"struct HasDangerousPublicDestructor<%s>\n"
|
||||
"{\n"
|
||||
" static const bool value = true;\n"
|
||||
"};\n"
|
||||
"}\n" % classname)
|
||||
|
||||
fd.write("#endif\n")
|
||||
|
||||
def interfaceAttributeTypes(idl):
|
||||
|
|
|
@ -991,10 +991,8 @@ pref("touchcaret.enabled", false);
|
|||
pref("selectioncaret.enabled", false);
|
||||
|
||||
// Enable sync and mozId with Firefox Accounts.
|
||||
#ifdef MOZ_SERVICES_FXACCOUNTS
|
||||
pref("services.sync.fxaccounts.enabled", true);
|
||||
pref("identity.fxaccounts.enabled", true);
|
||||
#endif
|
||||
|
||||
// Mobile Identity API.
|
||||
pref("services.mobileid.server.uri", "https://msisdn-dev.stage.mozaws.net");
|
||||
|
|
|
@ -19,7 +19,7 @@ if not CONFIG['LIBXUL_SDK']:
|
|||
|
||||
DEFINES['XPCOM_GLUE'] = True
|
||||
|
||||
for var in ('MOZ_APP_NAME', 'MOZ_APP_VERSION', 'MOZ_UPDATER', 'MOZ_SERVICES_FXACCOUNTS'):
|
||||
for var in ('MOZ_APP_NAME', 'MOZ_APP_VERSION', 'MOZ_UPDATER'):
|
||||
DEFINES[var] = CONFIG[var]
|
||||
|
||||
GENERATED_INCLUDES += [
|
||||
|
|
|
@ -26,10 +26,7 @@ Cu.import('resource://gre/modules/ResourceStatsService.jsm');
|
|||
Cu.import('resource://gre/modules/SignInToWebsite.jsm');
|
||||
SignInToWebsiteController.init();
|
||||
|
||||
#ifdef MOZ_SERVICES_FXACCOUNTS
|
||||
Cu.import('resource://gre/modules/FxAccountsMgmtService.jsm');
|
||||
#endif
|
||||
|
||||
Cu.import('resource://gre/modules/DownloadsAPI.jsm');
|
||||
Cu.import('resource://gre/modules/MobileIdentityManager.jsm');
|
||||
|
||||
|
|
|
@ -80,11 +80,9 @@ component {637b0f77-2429-49a0-915f-abf5d0db8b9a} WebappsUpdateTimer.js
|
|||
contract @mozilla.org/b2g/webapps-update-timer;1 {637b0f77-2429-49a0-915f-abf5d0db8b9a}
|
||||
category update-timer WebappsUpdateTimer @mozilla.org/b2g/webapps-update-timer;1,getService,background-update-timer,webapps.update.interval,86400
|
||||
|
||||
#ifdef MOZ_SERVICES_FXACCOUNTS
|
||||
# FxAccountsUIGlue.js
|
||||
component {51875c14-91d7-4b8c-b65d-3549e101228c} FxAccountsUIGlue.js
|
||||
contract @mozilla.org/fxaccounts/fxaccounts-ui-glue;1 {51875c14-91d7-4b8c-b65d-3549e101228c}
|
||||
#endif
|
||||
|
||||
# HelperAppDialog.js
|
||||
component {710322af-e6ae-4b0c-b2c9-1474a87b077e} HelperAppDialog.js
|
||||
|
|
|
@ -12,6 +12,7 @@ EXTRA_COMPONENTS += [
|
|||
'B2GAboutRedirector.js',
|
||||
'ContentPermissionPrompt.js',
|
||||
'FilePicker.js',
|
||||
'FxAccountsUIGlue.js',
|
||||
'HelperAppDialog.js',
|
||||
'InterAppCommUIGlue.js',
|
||||
'MailtoProtocolHandler.js',
|
||||
|
@ -48,6 +49,7 @@ EXTRA_JS_MODULES += [
|
|||
'AppFrames.jsm',
|
||||
'ContentRequestHelper.jsm',
|
||||
'ErrorPage.jsm',
|
||||
'FxAccountsMgmtService.jsm',
|
||||
'SignInToWebsite.jsm',
|
||||
'SystemAppProxy.jsm',
|
||||
'TelURIParser.jsm',
|
||||
|
@ -58,11 +60,3 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk':
|
|||
EXTRA_JS_MODULES += [
|
||||
'GlobalSimulatorScreen.jsm'
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_SERVICES_FXACCOUNTS']:
|
||||
EXTRA_COMPONENTS += [
|
||||
'FxAccountsUIGlue.js'
|
||||
]
|
||||
EXTRA_JS_MODULES += [
|
||||
'FxAccountsMgmtService.jsm'
|
||||
]
|
||||
|
|
|
@ -64,8 +64,6 @@ MOZ_FOLD_LIBS=1
|
|||
|
||||
MOZ_JSDOWNLOADS=1
|
||||
|
||||
MOZ_SERVICES_FXACCOUNTS=1
|
||||
|
||||
MOZ_BUNDLED_FONTS=1
|
||||
|
||||
# Enable exact rooting on b2g.
|
||||
|
|
|
@ -832,10 +832,8 @@ bin/components/@DLL_PREFIX@nkgnomevfs@DLL_SUFFIX@
|
|||
@BINPATH@/components/SimulatorScreen.js
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_SERVICES_FXACCOUNTS
|
||||
@BINPATH@/components/FxAccountsUIGlue.js
|
||||
@BINPATH@/components/services_fxaccounts.xpt
|
||||
#endif
|
||||
|
||||
@BINPATH@/components/DataStore.manifest
|
||||
@BINPATH@/components/DataStoreImpl.js
|
||||
|
|
|
@ -2313,7 +2313,8 @@ let BrowserOnClick = {
|
|||
switch (msg.name) {
|
||||
case "Browser:CertExceptionError":
|
||||
this.onAboutCertError(msg.target, msg.json.elementId,
|
||||
msg.json.isTopFrame, msg.json.location);
|
||||
msg.json.isTopFrame, msg.json.location,
|
||||
msg.objects.failedChannel);
|
||||
break;
|
||||
case "Browser:SiteBlockedError":
|
||||
this.onAboutBlocked(msg.json.elementId, msg.json.isMalware,
|
||||
|
@ -2326,19 +2327,16 @@ let BrowserOnClick = {
|
|||
}
|
||||
},
|
||||
|
||||
onAboutCertError: function (browser, elementId, isTopFrame, location) {
|
||||
onAboutCertError: function (browser, elementId, isTopFrame, location, failedChannel) {
|
||||
let secHistogram = Services.telemetry.getHistogramById("SECURITY_UI");
|
||||
|
||||
switch (elementId) {
|
||||
case "exceptionDialogButton":
|
||||
let docshell = aOwnerDoc.defaultView.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShell);
|
||||
let securityInfo = docshell.failedChannel.securityInfo;
|
||||
let sslStatus = securityInfo.QueryInterface(Ci.nsISSLStatusProvider).SSLStatus;
|
||||
if (isTopFrame) {
|
||||
secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_BAD_CERT_TOP_CLICK_ADD_EXCEPTION);
|
||||
}
|
||||
let sslStatus = failedChannel.securityInfo.QueryInterface(Ci.nsISSLStatusProvider)
|
||||
.SSLStatus;
|
||||
let params = { exceptionAdded : false,
|
||||
sslStatus : sslStatus };
|
||||
|
||||
|
|
|
@ -307,10 +307,15 @@ let ClickEventHandler = {
|
|||
},
|
||||
|
||||
onAboutCertError: function (targetElement, ownerDoc) {
|
||||
let docshell = ownerDoc.defaultView.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShell);
|
||||
sendAsyncMessage("Browser:CertExceptionError", {
|
||||
location: ownerDoc.location.href,
|
||||
elementId: targetElement.getAttribute("id"),
|
||||
isTopFrame: (ownerDoc.defaultView.parent === ownerDoc.defaultView)
|
||||
isTopFrame: (ownerDoc.defaultView.parent === ownerDoc.defaultView),
|
||||
}, {
|
||||
failedChannel: docshell.failedChannel
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -426,3 +426,5 @@ skip-if = e10s # Bug 940206 - nsIWebContentHandlerRegistrar::registerProtocolHan
|
|||
skip-if = e10s # Bug 516755 - SessionStore disabled for e10s
|
||||
[browser_bug1003461-switchtab-override.js]
|
||||
[browser_bug1025195_switchToTabHavingURI_ignoreFragment.js]
|
||||
[browser_addCertException.js]
|
||||
skip-if = e10s # Bug ?????? - test directly manipulates content (content.document.getElementById)
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
// Test adding a certificate exception by attempting to browse to a site with
|
||||
// a bad certificate, being redirected to the internal about:certerror page,
|
||||
// using the button contained therein to load the certificate exception
|
||||
// dialog, using that to add an exception, and finally successfully visiting
|
||||
// the site.
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
whenNewTabLoaded(window, loadBadCertPage);
|
||||
}
|
||||
|
||||
// Attempt to load https://expired.example.com (which has an expired cert).
|
||||
function loadBadCertPage() {
|
||||
gBrowser.addProgressListener(certErrorProgressListener);
|
||||
gBrowser.selectedBrowser.loadURI("https://expired.example.com");
|
||||
}
|
||||
|
||||
// The browser should load about:certerror. When This happens, click the
|
||||
// button to open the certificate exception dialog.
|
||||
let certErrorProgressListener = {
|
||||
buttonClicked: false,
|
||||
|
||||
onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus) {
|
||||
if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) {
|
||||
let self = this;
|
||||
// Can't directly call button.click() in onStateChange
|
||||
executeSoon(function() {
|
||||
let button = content.document.getElementById("exceptionDialogButton");
|
||||
// If about:certerror hasn't fully loaded, the button won't be present.
|
||||
// It will eventually be there, however.
|
||||
if (button && !self.buttonClicked) {
|
||||
gBrowser.removeProgressListener(self);
|
||||
Services.obs.addObserver(certExceptionDialogObserver,
|
||||
"cert-exception-ui-ready", false);
|
||||
button.click();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// When the certificate exception dialog has opened, click the button to add
|
||||
// an exception.
|
||||
const EXCEPTION_DIALOG_URI = "chrome://pippki/content/exceptionDialog.xul";
|
||||
let certExceptionDialogObserver = {
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
if (aTopic == "cert-exception-ui-ready") {
|
||||
Services.obs.removeObserver(this, "cert-exception-ui-ready");
|
||||
let certExceptionDialog = getDialog(EXCEPTION_DIALOG_URI);
|
||||
ok(certExceptionDialog, "found exception dialog");
|
||||
executeSoon(function() {
|
||||
gBrowser.selectedBrowser.addEventListener("load",
|
||||
successfulLoadListener,
|
||||
true);
|
||||
certExceptionDialog.documentElement.getButton("extra1").click();
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Finally, we should successfully load https://expired.example.com.
|
||||
let successfulLoadListener = {
|
||||
handleEvent: function() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", this, true);
|
||||
let certOverrideService = Cc["@mozilla.org/security/certoverride;1"]
|
||||
.getService(Ci.nsICertOverrideService);
|
||||
certOverrideService.clearValidityOverride("expired.example.com", -1);
|
||||
gBrowser.removeTab(gBrowser.selectedTab);
|
||||
finish();
|
||||
}
|
||||
};
|
||||
|
||||
// Utility function to get a handle on the certificate exception dialog.
|
||||
// Modified from toolkit/components/passwordmgr/test/prompt_common.js
|
||||
function getDialog(aLocation) {
|
||||
let wm = Cc["@mozilla.org/appshell/window-mediator;1"]
|
||||
.getService(Ci.nsIWindowMediator);
|
||||
let enumerator = wm.getXULWindowEnumerator(null);
|
||||
|
||||
while (enumerator.hasMoreElements()) {
|
||||
let win = enumerator.getNext();
|
||||
let windowDocShell = win.QueryInterface(Ci.nsIXULWindow).docShell;
|
||||
|
||||
let containedDocShells = windowDocShell.getDocShellEnumerator(
|
||||
Ci.nsIDocShellTreeItem.typeChrome,
|
||||
Ci.nsIDocShell.ENUMERATE_FORWARDS);
|
||||
while (containedDocShells.hasMoreElements()) {
|
||||
// Get the corresponding document for this docshell
|
||||
let childDocShell = containedDocShells.getNext();
|
||||
let childDoc = childDocShell.QueryInterface(Ci.nsIDocShell)
|
||||
.contentViewer
|
||||
.DOMDocument;
|
||||
|
||||
if (childDoc.location.href == aLocation) {
|
||||
return childDoc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
.module-cache
|
||||
standalone/content/config.js
|
|
@ -1,21 +1,32 @@
|
|||
This is the directory for the Loop desktop implementation and the standalone client.
|
||||
This is the directory for the Loop desktop implementation and the standalone
|
||||
client.
|
||||
|
||||
The desktop implementation is the UX built into Firefox, activated by the Loop button on the toolbar. The standalone client is the link-clicker UX for any modern browser that supports WebRTC.
|
||||
The desktop implementation is the UX built into Firefox, activated by the Loop
|
||||
button on the toolbar. The standalone client is the link-clicker UX for any
|
||||
modern browser that supports WebRTC.
|
||||
|
||||
The standalone client is a set of web pages intended to be hosted on a standalone server referenced by the loop-server.
|
||||
The standalone client is a set of web pages intended to be hosted on a
|
||||
standalone server referenced by the loop-server.
|
||||
|
||||
The standalone client exists in standalone/ but shares items
|
||||
(from content/shared/) with the desktop implementation. See the README.md
|
||||
file in the standalone/ directory for how to run the server locally.
|
||||
|
||||
The standalone client exists in standalone/ but shares items (from content/shared/) with the desktop implementation. See the README.md file in the standalone/ directory for how to run the server locally.
|
||||
|
||||
Working with JSX
|
||||
================
|
||||
|
||||
You need to install the JSX compiler in order to compile the .jsx files into regular .js ones.
|
||||
|
||||
The JSX compiler is installable using npm:
|
||||
You need to install the JSX compiler using npm in order to compile the .jsx
|
||||
files into regular .js ones:
|
||||
|
||||
npm install -g react-tools
|
||||
|
||||
Once installed, run it with the --watch option, eg.:
|
||||
Once installed, run build-jsx with the --watch option from
|
||||
browser/components/loop, eg.:
|
||||
|
||||
jsx --watch --x jsx browser/components/loop/content/js/src \
|
||||
browser/components/loop/content/js
|
||||
cd browser/components/loop
|
||||
./build-jsx --watch
|
||||
|
||||
build-jsx can also be do a one-time compile pass instead of watching if
|
||||
the --watch argument is omitted. Be sure to commit any transpiled files
|
||||
at the same time as changes to their sources.
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
import os
|
||||
from distutils import spawn
|
||||
import subprocess
|
||||
from threading import Thread
|
||||
import argparse
|
||||
|
||||
src_files = [] # files to be compiled
|
||||
|
||||
# search for react-tools install
|
||||
jsx_path = spawn.find_executable('jsx')
|
||||
if jsx_path is None:
|
||||
print 'You do not have the react-tools installed'
|
||||
print 'Please do $ npm install -g react-tools'
|
||||
exit(1)
|
||||
|
||||
# parse the CLI arguments
|
||||
description = 'Loop build tool for JSX files. ' + \
|
||||
'Will scan entire loop directory and compile them in place. ' + \
|
||||
'Must be executed from browser/components/loop directory.'
|
||||
|
||||
parser = argparse.ArgumentParser(description=description)
|
||||
parser.add_argument('--watch', '-w', action='store_true', help='continuous' +
|
||||
'build based on file changes (optional)')
|
||||
args = parser.parse_args()
|
||||
|
||||
# loop through all tuples and get unique dirs only
|
||||
unique_jsx_dirs = []
|
||||
|
||||
# find all .jsx files
|
||||
for dirname, dirnames, filenames in os.walk('.'):
|
||||
for filename in filenames:
|
||||
if '.jsx' == os.path.splitext(filename)[1]: # (root, ext)
|
||||
src_files.append(filename)
|
||||
if dirname not in unique_jsx_dirs:
|
||||
unique_jsx_dirs.append(dirname)
|
||||
|
||||
|
||||
def jsx_run_watcher(path):
|
||||
subprocess.call(['jsx', '-w', '-x', 'jsx', path, path])
|
||||
|
||||
|
||||
def start_jsx_watcher_threads(dirs):
|
||||
"""
|
||||
starts a thread with a jsx watch process
|
||||
for every dir in the dirs argument
|
||||
"""
|
||||
threads = []
|
||||
for udir in dirs:
|
||||
t = Thread(target=jsx_run_watcher, args=(udir,))
|
||||
threads.append(t)
|
||||
t.start()
|
||||
|
||||
for t in threads:
|
||||
t.join()
|
||||
|
||||
|
||||
def check_file_packaging(srcs):
|
||||
"""
|
||||
get all lines from jar.mn file
|
||||
check against the files we are going to compile.
|
||||
Note that this only looks at filenames, and will miss
|
||||
the one of two identically named files.
|
||||
"""
|
||||
# get all lines from jar.mn
|
||||
packaged_files = [line.strip() for line in open('./jar.mn')]
|
||||
|
||||
# loop through our compiled files and compare against jar.mn
|
||||
# XXX fix to use paths so that identically named files don't get overlooked
|
||||
# and update the docstring for this function
|
||||
missing_jar_files = [] # initially empty
|
||||
for src_file in srcs:
|
||||
transpiled_file = os.path.splitext(src_file)[0] + ".js" # (root, ext)
|
||||
if not any(transpiled_file in x for x in packaged_files):
|
||||
missing_jar_files.append(transpiled_file)
|
||||
|
||||
# output a message to the user
|
||||
if len(missing_jar_files):
|
||||
for f in missing_jar_files:
|
||||
print f + ' not in jar.mn file'
|
||||
|
||||
check_file_packaging(src_files)
|
||||
|
||||
if args.watch:
|
||||
start_jsx_watcher_threads(unique_jsx_dirs)
|
||||
else:
|
||||
for d in unique_jsx_dirs:
|
||||
out = subprocess.call(['jsx', '-x', 'jsx', d, d])
|
|
@ -1,3 +1,7 @@
|
|||
MOZ_AUTOMATION_UPLOAD=0
|
||||
MOZ_AUTOMATION_UNITTEST_SENDCHANGE=0
|
||||
MOZ_AUTOMATION_CHECK=0
|
||||
|
||||
. "$topsrcdir/browser/config/mozconfigs/linux64/debug"
|
||||
|
||||
ac_add_options --disable-unified-compilation
|
||||
|
|
|
@ -2,6 +2,7 @@ MOZ_AUTOMATION_UPLOAD=0
|
|||
MOZ_AUTOMATION_UNITTEST_SENDCHANGE=0
|
||||
MOZ_AUTOMATION_TALOS_SENDCHANGE=0
|
||||
MOZ_AUTOMATION_CHECK=0
|
||||
MOZ_AUTOMATION_PRETTY=1
|
||||
|
||||
. "$topsrcdir/browser/config/mozconfigs/linux64/nightly"
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@ MOZ_DISABLE_EXPORT_JS=1
|
|||
MOZ_SAFE_BROWSING=1
|
||||
MOZ_SERVICES_COMMON=1
|
||||
MOZ_SERVICES_CRYPTO=1
|
||||
MOZ_SERVICES_FXACCOUNTS=1
|
||||
MOZ_SERVICES_HEALTHREPORT=1
|
||||
MOZ_SERVICES_METRICS=1
|
||||
MOZ_SERVICES_SYNC=1
|
||||
|
|
|
@ -22,9 +22,13 @@ AUTOMATION_UPLOAD_OUTPUT = $(DIST)/automation-upload.txt
|
|||
tier_BUILD_SYMBOLS = buildsymbols
|
||||
tier_CHECK = check
|
||||
tier_L10N_CHECK = l10n-check
|
||||
tier_PRETTY_L10N_CHECK = pretty-l10n-check
|
||||
tier_PACKAGE = package
|
||||
tier_PRETTY_PACKAGE = pretty-package
|
||||
tier_PACKAGE_TESTS = package-tests
|
||||
tier_PRETTY_PACKAGE_TESTS = pretty-package-tests
|
||||
tier_UPDATE_PACKAGING = update-packaging
|
||||
tier_PRETTY_UPDATE_PACKAGING = pretty-update-packaging
|
||||
tier_UPLOAD_SYMBOLS = uploadsymbols
|
||||
tier_UPLOAD = upload
|
||||
|
||||
|
@ -32,7 +36,20 @@ tier_UPLOAD = upload
|
|||
# TIERS for mach display. As such, the MOZ_AUTOMATION_TIERS are roughly sorted
|
||||
# here in the order that they will be executed (since mach doesn't know of the
|
||||
# dependencies between them).
|
||||
moz_automation_symbols = PACKAGE_TESTS BUILD_SYMBOLS UPLOAD_SYMBOLS PACKAGE UPDATE_PACKAGING CHECK L10N_CHECK UPLOAD
|
||||
moz_automation_symbols = \
|
||||
PACKAGE_TESTS \
|
||||
PRETTY_PACKAGE_TESTS \
|
||||
BUILD_SYMBOLS \
|
||||
UPLOAD_SYMBOLS \
|
||||
PACKAGE \
|
||||
PRETTY_PACKAGE \
|
||||
UPDATE_PACKAGING \
|
||||
PRETTY_UPDATE_PACKAGING \
|
||||
CHECK \
|
||||
L10N_CHECK \
|
||||
PRETTY_L10N_CHECK \
|
||||
UPLOAD \
|
||||
$(NULL)
|
||||
MOZ_AUTOMATION_TIERS := $(foreach sym,$(moz_automation_symbols),$(if $(filter 1,$(MOZ_AUTOMATION_$(sym))),$(tier_$(sym))))
|
||||
|
||||
# Dependencies between automation build steps
|
||||
|
@ -53,6 +70,13 @@ automation/upload: automation/update-packaging
|
|||
automation/package: automation/buildsymbols
|
||||
automation/check: automation/buildsymbols
|
||||
|
||||
# The 'pretty' versions of targets run before the regular ones to avoid
|
||||
# conflicts in writing to the same files.
|
||||
automation/package: automation/pretty-package
|
||||
automation/package-tests: automation/pretty-package-tests
|
||||
automation/l10n-check: automation/pretty-l10n-check
|
||||
automation/update-packaging: automation/pretty-update-packaging
|
||||
|
||||
automation/build: $(addprefix automation/,$(MOZ_AUTOMATION_TIERS))
|
||||
$(PYTHON) $(topsrcdir)/build/gen_mach_buildprops.py --complete-mar-file $(DIST)/$(COMPLETE_MAR) --upload-output $(AUTOMATION_UPLOAD_OUTPUT)
|
||||
|
||||
|
|
|
@ -19,3 +19,15 @@ mk_add_options "export MOZ_AUTOMATION_UNITTEST_SENDCHANGE=${MOZ_AUTOMATION_UNITT
|
|||
mk_add_options "export MOZ_AUTOMATION_UPDATE_PACKAGING=${MOZ_AUTOMATION_UPDATE_PACKAGING-0}"
|
||||
mk_add_options "export MOZ_AUTOMATION_UPLOAD=${MOZ_AUTOMATION_UPLOAD-1}"
|
||||
mk_add_options "export MOZ_AUTOMATION_UPLOAD_SYMBOLS=${MOZ_AUTOMATION_UPLOAD_SYMBOLS-0}"
|
||||
|
||||
# If we are also building with MOZ_PKG_PRETTYNAMES, set the corresponding
|
||||
# stages.
|
||||
if test "$MOZ_AUTOMATION_PRETTY" = "1"; then
|
||||
mk_add_options "export MOZ_AUTOMATION_PRETTY_PACKAGE=${MOZ_AUTOMATION_PACKAGE-1}"
|
||||
mk_add_options "export MOZ_AUTOMATION_PRETTY_PACKAGE_TESTS=${MOZ_AUTOMATION_PACKAGE_TESTS-1}"
|
||||
mk_add_options "export MOZ_AUTOMATION_PRETTY_L10N_CHECK=${MOZ_AUTOMATION_L10N_CHECK-1}"
|
||||
|
||||
# Note that we always build the update packaging with pretty names even if
|
||||
# we don't build it without, so this is set to 1.
|
||||
mk_add_options "export MOZ_AUTOMATION_PRETTY_UPDATE_PACKAGING=1"
|
||||
fi
|
||||
|
|
|
@ -7551,14 +7551,6 @@ if test -n "$MOZ_AUDIO_CHANNEL_MANAGER"; then
|
|||
fi
|
||||
AC_SUBST(MOZ_AUDIO_CHANNEL_MANAGER)
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Enable Support for Firefox Accounts (services/fxaccounts)
|
||||
dnl ========================================================
|
||||
if test -n "$MOZ_SERVICES_FXACCOUNTS"; then
|
||||
AC_DEFINE(MOZ_SERVICES_FXACCOUNTS)
|
||||
fi
|
||||
AC_SUBST(MOZ_SERVICES_FXACCOUNTS)
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Support for demangling undefined symbols
|
||||
dnl ========================================================
|
||||
|
|
|
@ -17,7 +17,7 @@ interface nsIPrincipal;
|
|||
* one of these per document/principal.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(1ae83090-e1e1-4272-b0c4-0fbd751c1e27)]
|
||||
[scriptable, uuid(15c409c5-ebf8-457c-a8dd-5b169ca0b218)]
|
||||
interface nsIContentSecurityPolicy : nsISerializable
|
||||
{
|
||||
|
||||
|
@ -55,13 +55,9 @@ interface nsIContentSecurityPolicy : nsISerializable
|
|||
* @param reportOnly
|
||||
* Should this policy affect content, script and style processing or
|
||||
* just send reports if it is violated?
|
||||
* @param specCompliant
|
||||
* Whether or not the policy conforms to the W3C specification.
|
||||
* If this is false, that indicates this policy is from the older
|
||||
* implementation with different semantics and directive names.
|
||||
*/
|
||||
void appendPolicy(in AString policyString, in nsIURI selfURI,
|
||||
in boolean reportOnly, in boolean specCompliant);
|
||||
in boolean reportOnly);
|
||||
|
||||
/**
|
||||
* Whether this policy allows in-page script.
|
||||
|
|
|
@ -192,8 +192,7 @@ CSPPolicyURIListener.prototype = {
|
|||
if (Components.isSuccessCode(status)) {
|
||||
// send the policy we received back to the parent document's CSP
|
||||
// for parsing
|
||||
this._csp.appendPolicy(this._policy, this._docURI,
|
||||
this._reportOnly, true);
|
||||
this._csp.appendPolicy(this._policy, this._docURI, this._reportOnly);
|
||||
}
|
||||
else {
|
||||
// problem fetching policy so fail closed by appending a "block it all"
|
||||
|
@ -201,8 +200,7 @@ CSPPolicyURIListener.prototype = {
|
|||
// this policy is used.
|
||||
this._csp.log(WARN_FLAG, CSPLocalizer.getFormatStr("errorFetchingPolicy",
|
||||
[status]));
|
||||
this._csp.appendPolicy("default-src 'none'", this._docURI,
|
||||
this._reportOnly, true);
|
||||
this._csp.appendPolicy("default-src 'none'", this._docURI, this._reportOnly);
|
||||
}
|
||||
// resume the parent document request
|
||||
this._docRequest.resume();
|
||||
|
@ -228,7 +226,7 @@ this.CSPRep = function CSPRep() {
|
|||
this._directives = {};
|
||||
}
|
||||
|
||||
// Source directives for our CSP 1.0 spec compliant implementation.
|
||||
// Source directives for our CSP 1.0 implementation.
|
||||
CSPRep.SRC_DIRECTIVES = {
|
||||
DEFAULT_SRC: "default-src",
|
||||
SCRIPT_SRC: "script-src",
|
||||
|
|
|
@ -385,7 +385,7 @@ ContentSecurityPolicy.prototype = {
|
|||
* @returns the count of policies.
|
||||
*/
|
||||
appendPolicy:
|
||||
function csp_appendPolicy(aPolicy, selfURI, aReportOnly, aSpecCompliant) {
|
||||
function csp_appendPolicy(aPolicy, selfURI, aReportOnly) {
|
||||
return this._appendPolicyInternal(aPolicy, selfURI, aReportOnly, true);
|
||||
},
|
||||
|
||||
|
|
|
@ -286,8 +286,7 @@ nsCSPContext::RemovePolicy(uint32_t aIndex)
|
|||
NS_IMETHODIMP
|
||||
nsCSPContext::AppendPolicy(const nsAString& aPolicyString,
|
||||
nsIURI* aSelfURI,
|
||||
bool aReportOnly,
|
||||
bool aSpecCompliant)
|
||||
bool aReportOnly)
|
||||
{
|
||||
CSPCONTEXTLOG(("nsCSPContext::AppendPolicy: %s",
|
||||
NS_ConvertUTF16toUTF8(aPolicyString).get()));
|
||||
|
@ -1215,16 +1214,6 @@ nsCSPContext::Read(nsIObjectInputStream* aStream)
|
|||
rv = aStream->ReadBoolean(&reportOnly);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool specCompliant = false;
|
||||
rv = aStream->ReadBoolean(&specCompliant);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Using the new backend, we don't support non-spec-compliant policies, so
|
||||
// skip any of those, will be fixed in bug 991466
|
||||
if (!specCompliant) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsCSPPolicy* policy = nsCSPParser::parseContentSecurityPolicy(policyString,
|
||||
mSelfURI,
|
||||
reportOnly,
|
||||
|
@ -1254,8 +1243,6 @@ nsCSPContext::Write(nsIObjectOutputStream* aStream)
|
|||
mPolicies[p]->toString(polStr);
|
||||
aStream->WriteWStringZ(polStr.get());
|
||||
aStream->WriteBoolean(mPolicies[p]->getReportOnlyFlag());
|
||||
// Setting specCompliant boolean for backwards compatibility (fix in bug 991466)
|
||||
aStream->WriteBoolean(true);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -665,7 +665,8 @@ nsContentSink::ProcessLink(const nsSubstring& aAnchor, const nsSubstring& aHref,
|
|||
const nsSubstring& aRel, const nsSubstring& aTitle,
|
||||
const nsSubstring& aType, const nsSubstring& aMedia)
|
||||
{
|
||||
uint32_t linkTypes = nsStyleLinkElement::ParseLinkTypes(aRel);
|
||||
uint32_t linkTypes =
|
||||
nsStyleLinkElement::ParseLinkTypes(aRel, mDocument->NodePrincipal());
|
||||
|
||||
// The link relation may apply to a different resource, specified
|
||||
// in the anchor parameter. For the link relations supported so far,
|
||||
|
|
|
@ -2640,7 +2640,7 @@ nsDocument::SendToConsole(nsCOMArray<nsISecurityConsoleMessage>& aMessages)
|
|||
|
||||
static nsresult
|
||||
AppendCSPFromHeader(nsIContentSecurityPolicy* csp, const nsAString& aHeaderValue,
|
||||
nsIURI* aSelfURI, bool aReportOnly, bool aSpecCompliant)
|
||||
nsIURI* aSelfURI, bool aReportOnly)
|
||||
{
|
||||
// Need to tokenize the header value since multiple headers could be
|
||||
// concatenated into one comma-separated list of policies.
|
||||
|
@ -2649,7 +2649,7 @@ AppendCSPFromHeader(nsIContentSecurityPolicy* csp, const nsAString& aHeaderValue
|
|||
nsCharSeparatedTokenizer tokenizer(aHeaderValue, ',');
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
const nsSubstring& policy = tokenizer.nextToken();
|
||||
rv = csp->AppendPolicy(policy, aSelfURI, aReportOnly, aSpecCompliant);
|
||||
rv = csp->AppendPolicy(policy, aSelfURI, aReportOnly);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
#ifdef PR_LOGGING
|
||||
{
|
||||
|
@ -2798,24 +2798,24 @@ nsDocument::InitCSP(nsIChannel* aChannel)
|
|||
}
|
||||
|
||||
if (appCSP) {
|
||||
csp->AppendPolicy(appCSP, selfURI, false, true);
|
||||
csp->AppendPolicy(appCSP, selfURI, false);
|
||||
}
|
||||
}
|
||||
|
||||
// ----- if the doc is an app and specifies a CSP in its manifest, apply it.
|
||||
if (applyAppManifestCSP) {
|
||||
csp->AppendPolicy(appManifestCSP, selfURI, false, true);
|
||||
csp->AppendPolicy(appManifestCSP, selfURI, false);
|
||||
}
|
||||
|
||||
// ----- if there's a full-strength CSP header, apply it.
|
||||
if (!cspHeaderValue.IsEmpty()) {
|
||||
rv = AppendCSPFromHeader(csp, cspHeaderValue, selfURI, false, true);
|
||||
rv = AppendCSPFromHeader(csp, cspHeaderValue, selfURI, false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// ----- if there's a report-only CSP header, apply it.
|
||||
if (!cspROHeaderValue.IsEmpty()) {
|
||||
rv = AppendCSPFromHeader(csp, cspROHeaderValue, selfURI, true, true);
|
||||
rv = AppendCSPFromHeader(csp, cspROHeaderValue, selfURI, true);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
|
@ -5445,7 +5445,7 @@ nsDocument::CustomElementConstructor(JSContext* aCx, unsigned aArgc, JS::Value*
|
|||
}
|
||||
|
||||
bool
|
||||
nsDocument::IsRegisterElementEnabled(JSContext* aCx, JSObject* aObject)
|
||||
nsDocument::IsWebComponentsEnabled(JSContext* aCx, JSObject* aObject)
|
||||
{
|
||||
JS::Rooted<JSObject*> obj(aCx, aObject);
|
||||
return Preferences::GetBool("dom.webcomponents.enabled") ||
|
||||
|
|
|
@ -1479,7 +1479,7 @@ public:
|
|||
uint32_t aNamespaceID,
|
||||
mozilla::ErrorResult& rv);
|
||||
|
||||
static bool IsRegisterElementEnabled(JSContext* aCx, JSObject* aObject);
|
||||
static bool IsWebComponentsEnabled(JSContext* aCx, JSObject* aObject);
|
||||
|
||||
// The "registry" from the web components spec.
|
||||
nsRefPtr<mozilla::dom::Registry> mRegistry;
|
||||
|
|
|
@ -120,21 +120,30 @@ nsStyleLinkElement::SetLineNumber(uint32_t aLineNumber)
|
|||
}
|
||||
|
||||
/* static */ bool
|
||||
nsStyleLinkElement::IsImportEnabled()
|
||||
nsStyleLinkElement::IsImportEnabled(nsIPrincipal* aPrincipal)
|
||||
{
|
||||
static bool sAdded = false;
|
||||
static bool sImportEnabled;
|
||||
static bool sWebComponentsEnabled;
|
||||
if (!sAdded) {
|
||||
// This part runs only once because of the static flag.
|
||||
Preferences::AddBoolVarCache(&sImportEnabled,
|
||||
Preferences::AddBoolVarCache(&sWebComponentsEnabled,
|
||||
"dom.webcomponents.enabled",
|
||||
false);
|
||||
sAdded = true;
|
||||
}
|
||||
return sImportEnabled;
|
||||
|
||||
if (sWebComponentsEnabled) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If the web components pref is not enabled, check
|
||||
// if we are in a certified app because imports is enabled
|
||||
// for certified apps.
|
||||
return aPrincipal &&
|
||||
aPrincipal->GetAppStatus() == nsIPrincipal::APP_STATUS_CERTIFIED;
|
||||
}
|
||||
|
||||
static uint32_t ToLinkMask(const nsAString& aLink)
|
||||
static uint32_t ToLinkMask(const nsAString& aLink, nsIPrincipal* aPrincipal)
|
||||
{
|
||||
if (aLink.EqualsLiteral("prefetch"))
|
||||
return nsStyleLinkElement::ePREFETCH;
|
||||
|
@ -146,13 +155,14 @@ static uint32_t ToLinkMask(const nsAString& aLink)
|
|||
return nsStyleLinkElement::eNEXT;
|
||||
else if (aLink.EqualsLiteral("alternate"))
|
||||
return nsStyleLinkElement::eALTERNATE;
|
||||
else if (aLink.EqualsLiteral("import") && nsStyleLinkElement::IsImportEnabled())
|
||||
else if (aLink.EqualsLiteral("import") && aPrincipal &&
|
||||
nsStyleLinkElement::IsImportEnabled(aPrincipal))
|
||||
return nsStyleLinkElement::eHTMLIMPORT;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t nsStyleLinkElement::ParseLinkTypes(const nsAString& aTypes)
|
||||
uint32_t nsStyleLinkElement::ParseLinkTypes(const nsAString& aTypes, nsIPrincipal* aPrincipal)
|
||||
{
|
||||
uint32_t linkMask = 0;
|
||||
nsAString::const_iterator start, done;
|
||||
|
@ -169,7 +179,7 @@ uint32_t nsStyleLinkElement::ParseLinkTypes(const nsAString& aTypes)
|
|||
if (nsContentUtils::IsHTMLWhitespace(*current)) {
|
||||
if (inString) {
|
||||
nsContentUtils::ASCIIToLower(Substring(start, current), subString);
|
||||
linkMask |= ToLinkMask(subString);
|
||||
linkMask |= ToLinkMask(subString, aPrincipal);
|
||||
inString = false;
|
||||
}
|
||||
}
|
||||
|
@ -183,7 +193,7 @@ uint32_t nsStyleLinkElement::ParseLinkTypes(const nsAString& aTypes)
|
|||
}
|
||||
if (inString) {
|
||||
nsContentUtils::ASCIIToLower(Substring(start, current), subString);
|
||||
linkMask |= ToLinkMask(subString);
|
||||
linkMask |= ToLinkMask(subString, aPrincipal);
|
||||
}
|
||||
return linkMask;
|
||||
}
|
||||
|
|
|
@ -61,10 +61,13 @@ public:
|
|||
eHTMLIMPORT = 0x00000020
|
||||
};
|
||||
|
||||
// The return value is a bitwise or of 0 or more RelValues
|
||||
static uint32_t ParseLinkTypes(const nsAString& aTypes);
|
||||
// The return value is a bitwise or of 0 or more RelValues.
|
||||
// aPrincipal is used to check if HTML imports is enabled for the
|
||||
// provided principal.
|
||||
static uint32_t ParseLinkTypes(const nsAString& aTypes,
|
||||
nsIPrincipal* aPrincipal);
|
||||
|
||||
static bool IsImportEnabled();
|
||||
static bool IsImportEnabled(nsIPrincipal* aPrincipal);
|
||||
|
||||
void UpdateStyleSheetInternal()
|
||||
{
|
||||
|
|
|
@ -117,7 +117,7 @@ nsresult runTest(uint32_t aExpectedPolicyCount, // this should be 0 for policies
|
|||
policyStr.AssignASCII(aPolicy);
|
||||
// Second argument in AppendPolicy needs to be a nullptr,
|
||||
// because we are using the selfURI set in SetRequestingContext
|
||||
rv = csp->AppendPolicy(policyStr, nullptr, false, true);
|
||||
rv = csp->AppendPolicy(policyStr, nullptr, false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// when executing fuzzy tests we do not care about the actual output
|
||||
|
|
|
@ -66,13 +66,8 @@ window.done = function(result) {
|
|||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// save this for last so that our listeners are registered.
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set':[["security.csp.speccompliant", true]]},
|
||||
function() {
|
||||
// save this for last so that our listeners are registered.
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('content_iframe').src = 'file_redirect_content.sjs?301';
|
||||
});
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('content_iframe').src = 'file_redirect_content.sjs?301';
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
|
|
@ -66,13 +66,8 @@ window.done = function(result) {
|
|||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// save this for last so that our listeners are registered.
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set':[["security.csp.speccompliant", true]]},
|
||||
function() {
|
||||
// save this for last so that our listeners are registered.
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('content_iframe').src = 'file_redirect_content.sjs?302';
|
||||
});
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('content_iframe').src = 'file_redirect_content.sjs?302';
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
|
|
@ -66,13 +66,8 @@ window.done = function(result) {
|
|||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// save this for last so that our listeners are registered.
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set':[["security.csp.speccompliant", true]]},
|
||||
function() {
|
||||
// save this for last so that our listeners are registered.
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('content_iframe').src = 'file_redirect_content.sjs?303';
|
||||
});
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('content_iframe').src = 'file_redirect_content.sjs?303';
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
|
|
@ -66,13 +66,9 @@ window.done = function(result) {
|
|||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// save this for last so that our listeners are registered.
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set':[["security.csp.speccompliant", true]]},
|
||||
function() {
|
||||
// save this for last so that our listeners are registered.
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('content_iframe').src = 'file_redirect_content.sjs?307';
|
||||
});
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('content_iframe').src = 'file_redirect_content.sjs?307';
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
|
|
@ -101,8 +101,7 @@ window.testResult = function(testname, result, msg) {
|
|||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set':[["security.csp.speccompliant", true],
|
||||
// This defaults to 0 ("preload none") on mobile (B2G/Android), which
|
||||
{'set':[// This defaults to 0 ("preload none") on mobile (B2G/Android), which
|
||||
// blocks loading the resource until the user interacts with a
|
||||
// corresponding widget, which breaks the media_* tests. We set it
|
||||
// back to the default used by desktop Firefox to get consistent
|
||||
|
|
|
@ -65,16 +65,11 @@ function checkBlocked () {
|
|||
checkExplicitFinish();
|
||||
}
|
||||
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set':[["security.csp.speccompliant", true]]},
|
||||
function () {
|
||||
document.getElementById('xsltframe').addEventListener('load', checkAllowed, false);
|
||||
document.getElementById('xsltframe').src = 'file_CSP_bug663567_allows.xml';
|
||||
document.getElementById('xsltframe').addEventListener('load', checkAllowed, false);
|
||||
document.getElementById('xsltframe').src = 'file_CSP_bug663567_allows.xml';
|
||||
|
||||
document.getElementById('xsltframe2').addEventListener('load', checkBlocked, false);
|
||||
document.getElementById('xsltframe2').src = 'file_CSP_bug663567_blocks.xml';
|
||||
}
|
||||
);
|
||||
document.getElementById('xsltframe2').addEventListener('load', checkBlocked, false);
|
||||
document.getElementById('xsltframe2').src = 'file_CSP_bug663567_blocks.xml';
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -25,33 +25,28 @@ var checkExplicitFinish = function () {
|
|||
}
|
||||
}
|
||||
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set':[["security.csp.speccompliant", true]]},
|
||||
function () {
|
||||
// add event listeners for CSP-permitted EventSrc callbacks
|
||||
addEventListener('allowedEventSrcCallbackOK', function (e) {
|
||||
ok(true, "OK: CSP allows EventSource for whitelisted domain!");
|
||||
checkExplicitFinish();
|
||||
}, false);
|
||||
addEventListener('allowedEventSrcCallbackFailed', function (e) {
|
||||
ok(false, "Error: CSP blocks EventSource for whitelisted domain!");
|
||||
checkExplicitFinish();
|
||||
}, false);
|
||||
// add event listeners for CSP-permitted EventSrc callbacks
|
||||
addEventListener('allowedEventSrcCallbackOK', function (e) {
|
||||
ok(true, "OK: CSP allows EventSource for whitelisted domain!");
|
||||
checkExplicitFinish();
|
||||
}, false);
|
||||
addEventListener('allowedEventSrcCallbackFailed', function (e) {
|
||||
ok(false, "Error: CSP blocks EventSource for whitelisted domain!");
|
||||
checkExplicitFinish();
|
||||
}, false);
|
||||
|
||||
// add event listeners for CSP-blocked EventSrc callbacks
|
||||
addEventListener('blockedEventSrcCallbackOK', function (e) {
|
||||
ok(false, "Error: CSP allows EventSource to not whitelisted domain!");
|
||||
checkExplicitFinish();
|
||||
}, false);
|
||||
addEventListener('blockedEventSrcCallbackFailed', function (e) {
|
||||
ok(true, "OK: CSP blocks EventSource for not whitelisted domain!");
|
||||
checkExplicitFinish();
|
||||
}, false);
|
||||
// add event listeners for CSP-blocked EventSrc callbacks
|
||||
addEventListener('blockedEventSrcCallbackOK', function (e) {
|
||||
ok(false, "Error: CSP allows EventSource to not whitelisted domain!");
|
||||
checkExplicitFinish();
|
||||
}, false);
|
||||
addEventListener('blockedEventSrcCallbackFailed', function (e) {
|
||||
ok(true, "OK: CSP blocks EventSource for not whitelisted domain!");
|
||||
checkExplicitFinish();
|
||||
}, false);
|
||||
|
||||
// load it
|
||||
document.getElementById('eventframe').src = 'file_CSP_bug802872.html';
|
||||
}
|
||||
);
|
||||
// load it
|
||||
document.getElementById('eventframe').src = 'file_CSP_bug802872.html';
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -50,15 +50,10 @@ function checkBlocked () {
|
|||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set':[["security.csp.speccompliant", true]]},
|
||||
function () {
|
||||
document.getElementById('cspframe').src = 'file_CSP_bug885433_allows.html';
|
||||
document.getElementById('cspframe').addEventListener('load', checkAllowed, false);
|
||||
document.getElementById('cspframe2').src = 'file_CSP_bug885433_blocks.html';
|
||||
document.getElementById('cspframe2').addEventListener('load', checkBlocked, false);
|
||||
}
|
||||
);
|
||||
document.getElementById('cspframe').src = 'file_CSP_bug885433_allows.html';
|
||||
document.getElementById('cspframe').addEventListener('load', checkAllowed, false);
|
||||
document.getElementById('cspframe2').src = 'file_CSP_bug885433_blocks.html';
|
||||
document.getElementById('cspframe2').addEventListener('load', checkBlocked, false);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
|
|
@ -56,22 +56,17 @@ function checkDefaultSrcWithStyleSrc() {
|
|||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set':[["security.csp.speccompliant", true]]},
|
||||
function () {
|
||||
document.getElementById('testframe1').src = 'file_CSP_bug888172.sjs?csp=' +
|
||||
escape("default-src 'self' 'unsafe-inline' 'unsafe-eval'");
|
||||
document.getElementById('testframe1').addEventListener('load', checkDefaultSrcOnly, false);
|
||||
document.getElementById('testframe1').src = 'file_CSP_bug888172.sjs?csp=' +
|
||||
escape("default-src 'self' 'unsafe-inline' 'unsafe-eval'");
|
||||
document.getElementById('testframe1').addEventListener('load', checkDefaultSrcOnly, false);
|
||||
|
||||
document.getElementById('testframe2').src = 'file_CSP_bug888172.sjs?csp=' +
|
||||
escape("default-src 'self' 'unsafe-inline' 'unsafe-eval'; script-src 'self'");
|
||||
document.getElementById('testframe2').addEventListener('load', checkDefaultSrcWithScriptSrc, false);
|
||||
document.getElementById('testframe2').src = 'file_CSP_bug888172.sjs?csp=' +
|
||||
escape("default-src 'self' 'unsafe-inline' 'unsafe-eval'; script-src 'self'");
|
||||
document.getElementById('testframe2').addEventListener('load', checkDefaultSrcWithScriptSrc, false);
|
||||
|
||||
document.getElementById('testframe3').src = 'file_CSP_bug888172.sjs?csp=' +
|
||||
escape("default-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self'");
|
||||
document.getElementById('testframe3').addEventListener('load', checkDefaultSrcWithStyleSrc, false);
|
||||
}
|
||||
);
|
||||
document.getElementById('testframe3').src = 'file_CSP_bug888172.sjs?csp=' +
|
||||
escape("default-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self'");
|
||||
document.getElementById('testframe3').addEventListener('load', checkDefaultSrcWithStyleSrc, false);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
|
|
@ -120,15 +120,10 @@ function checkInlineWithNone() {
|
|||
"Inline scripts should be blocked (style-src 'unsafe-inline' with none)");
|
||||
}
|
||||
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set':[["security.csp.speccompliant", true]]},
|
||||
function () {
|
||||
document.getElementById('testframe1').src = 'file_CSP_bug909029_star.html';
|
||||
document.getElementById('testframe1').addEventListener('load', checkInlineWithStar, false);
|
||||
document.getElementById('testframe2').src = 'file_CSP_bug909029_none.html';
|
||||
document.getElementById('testframe2').addEventListener('load', checkInlineWithNone, false);
|
||||
}
|
||||
);
|
||||
document.getElementById('testframe1').src = 'file_CSP_bug909029_star.html';
|
||||
document.getElementById('testframe1').addEventListener('load', checkInlineWithStar, false);
|
||||
document.getElementById('testframe2').src = 'file_CSP_bug909029_none.html';
|
||||
document.getElementById('testframe2').addEventListener('load', checkInlineWithNone, false);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -58,13 +58,8 @@ function checkBlocked () {
|
|||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set':[["security.csp.speccompliant", true]]},
|
||||
function () {
|
||||
document.getElementById('xsltframe').addEventListener('load', checkAllowed, false);
|
||||
document.getElementById('xsltframe').src = 'file_CSP_bug910139.sjs';
|
||||
}
|
||||
);
|
||||
document.getElementById('xsltframe').addEventListener('load', checkAllowed, false);
|
||||
document.getElementById('xsltframe').src = 'file_CSP_bug910139.sjs';
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -97,13 +97,9 @@ window.testResult = function(testname, result, msg) {
|
|||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set':[["security.csp.speccompliant", true]]},
|
||||
function() {
|
||||
// save this for last so that our listeners are registered.
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('cspframe').src = 'file_CSP_bug941404.html';
|
||||
});
|
||||
// save this for last so that our listeners are registered.
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('cspframe').src = 'file_CSP_bug941404.html';
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
|
|
|
@ -49,14 +49,10 @@ var checkTestResults = function() {
|
|||
// set up and go
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set':[["security.csp.speccompliant", true]]},
|
||||
function() {
|
||||
// save this for last so that our listeners are registered.
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('cspframe').src = 'file_CSP_evalscript_main.html';
|
||||
document.getElementById('cspframe2').src = 'file_CSP_evalscript_main_allowed.html';
|
||||
});
|
||||
// save this for last so that our listeners are registered.
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('cspframe').src = 'file_CSP_evalscript_main.html';
|
||||
document.getElementById('cspframe2').src = 'file_CSP_evalscript_main_allowed.html';
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
|
|
@ -48,15 +48,11 @@ var checkTestResults = function() {
|
|||
// set up and go
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set':[["security.csp.speccompliant", true]]},
|
||||
function() {
|
||||
// save this for last so that our listeners are registered.
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('cspframe').src = 'file_CSP_evalscript_main_getCRMFRequest.html';
|
||||
document.getElementById('cspframe2').src = 'file_CSP_evalscript_main_allowed_getCRMFRequest.html';
|
||||
document.getElementById('cspframe3').src = 'file_CSP_evalscript_no_CSP_at_all.html';
|
||||
});
|
||||
// save this for last so that our listeners are registered.
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('cspframe').src = 'file_CSP_evalscript_main_getCRMFRequest.html';
|
||||
document.getElementById('cspframe2').src = 'file_CSP_evalscript_main_allowed_getCRMFRequest.html';
|
||||
document.getElementById('cspframe3').src = 'file_CSP_evalscript_no_CSP_at_all.html';
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
|
|
@ -147,14 +147,9 @@ function receiveMessage(event) {
|
|||
window.examiner = new examiner();
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// added this so the tests run even if we don't flip the pref on by default.
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set':[["security.csp.speccompliant", true]]},
|
||||
function() {
|
||||
// save this for last so that our listeners are registered.
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('cspframe').src = 'file_CSP_frameancestors_main.html';
|
||||
});
|
||||
// save this for last so that our listeners are registered.
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('cspframe').src = 'file_CSP_frameancestors_main.html';
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
|
|
|
@ -101,16 +101,12 @@ function clickit2() {
|
|||
sendMouseEvent({type:'click'}, a, cspframe2.contentWindow);
|
||||
}
|
||||
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set':[["security.csp.speccompliant", true]]},
|
||||
function() {
|
||||
// save this for last so that our listeners are registered.
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('cspframe1').src = 'file_CSP_inlinescript_main.html';
|
||||
document.getElementById('cspframe1').addEventListener('load', clickit1, false);
|
||||
document.getElementById('cspframe2').src = 'file_CSP_inlinescript_main_allowed.html';
|
||||
document.getElementById('cspframe2').addEventListener('load', clickit2, false);
|
||||
});
|
||||
// save this for last so that our listeners are registered.
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('cspframe1').src = 'file_CSP_inlinescript_main.html';
|
||||
document.getElementById('cspframe1').addEventListener('load', clickit1, false);
|
||||
document.getElementById('cspframe2').src = 'file_CSP_inlinescript_main_allowed.html';
|
||||
document.getElementById('cspframe2').addEventListener('load', clickit2, false);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
|
|
@ -94,17 +94,13 @@ function checkIfDone() {
|
|||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set':[["security.csp.speccompliant", true]]},
|
||||
function() {
|
||||
// save this for last so that our listeners are registered.
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('cspframe1').src = 'file_CSP_inlinestyle_main.html';
|
||||
document.getElementById('cspframe1').addEventListener('load', checkStyles, false);
|
||||
document.getElementById('cspframe2').src = 'file_CSP_inlinestyle_main_allowed.html';
|
||||
document.getElementById('cspframe2').addEventListener('load', checkStylesAllowed, false);
|
||||
}
|
||||
);
|
||||
// save this for last so that our listeners are registered.
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('cspframe1').src = 'file_CSP_inlinestyle_main.html';
|
||||
document.getElementById('cspframe1').addEventListener('load', checkStyles, false);
|
||||
document.getElementById('cspframe2').src = 'file_CSP_inlinestyle_main_allowed.html';
|
||||
document.getElementById('cspframe2').addEventListener('load', checkStylesAllowed, false);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
|
|
@ -235,13 +235,9 @@ window.testResult = function(testname, result, msg) {
|
|||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set':[["security.csp.speccompliant", true]]},
|
||||
function() {
|
||||
// save this for last so that our listeners are registered.
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('cspframe').src = 'http://mochi.test:8888' + path + 'file_bug836922_npolicies.html';
|
||||
});
|
||||
// save this for last so that our listeners are registered.
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('cspframe').src = 'http://mochi.test:8888' + path + 'file_bug836922_npolicies.html';
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
|
|
|
@ -157,18 +157,14 @@ window.testResult = function(testname, result, msg) {
|
|||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set':[["security.csp.speccompliant", true]]},
|
||||
function() {
|
||||
// save this for last so that our listeners are registered.
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('cspframe').src = 'file_bug886164.html';
|
||||
document.getElementById('cspframe2').src = 'file_bug886164_2.html';
|
||||
document.getElementById('cspframe3').src = 'file_bug886164_3.html';
|
||||
document.getElementById('cspframe4').src = 'file_bug886164_4.html';
|
||||
document.getElementById('cspframe5').src = 'file_bug886164_5.html';
|
||||
document.getElementById('cspframe6').src = 'file_bug886164_6.html';
|
||||
});
|
||||
// save this for last so that our listeners are registered.
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('cspframe').src = 'file_bug886164.html';
|
||||
document.getElementById('cspframe2').src = 'file_bug886164_2.html';
|
||||
document.getElementById('cspframe3').src = 'file_bug886164_3.html';
|
||||
document.getElementById('cspframe4').src = 'file_bug886164_4.html';
|
||||
document.getElementById('cspframe5').src = 'file_bug886164_5.html';
|
||||
document.getElementById('cspframe6').src = 'file_bug886164_6.html';
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
|
|
|
@ -213,8 +213,7 @@ SpecialPowers.pushPrefEnv({'set': [["dom.mozBrowserFramesEnabled", true],
|
|||
["security.apps.privileged.CSP.default", DEFAULT_CSP_PRIV],
|
||||
["security.apps.certified.CSP.default", DEFAULT_CSP_CERT],
|
||||
["security.mixed_content.block_active_content", false],
|
||||
["security.mixed_content.block_display_content", false],
|
||||
["security.csp.speccompliant", true]]},
|
||||
["security.mixed_content.block_display_content", false]]},
|
||||
function() { gTestRunner.next(); });
|
||||
|
||||
|
||||
|
|
|
@ -218,8 +218,7 @@ SpecialPowers.addPermission("browser", true, "https://example.com");
|
|||
|
||||
SpecialPowers.pushPrefEnv({'set': [["dom.mozBrowserFramesEnabled", true],
|
||||
["security.apps.privileged.CSP.default", DEFAULT_CSP_PRIV],
|
||||
["security.apps.certified.CSP.default", DEFAULT_CSP_CERT],
|
||||
["security.csp.speccompliant", true]]},
|
||||
["security.apps.certified.CSP.default", DEFAULT_CSP_CERT]]},
|
||||
function() { gTestRunner.next(); });
|
||||
|
||||
|
||||
|
|
|
@ -111,8 +111,7 @@ var testResult = function(testName, url, result) {
|
|||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set':[["security.csp.speccompliant", true],
|
||||
// This defaults to 0 ("preload none") on mobile (B2G/Android), which
|
||||
{'set':[// This defaults to 0 ("preload none") on mobile (B2G/Android), which
|
||||
// blocks loading the resource until the user interacts with a
|
||||
// corresponding widget, which breaks the media_* tests. We set it
|
||||
// back to the default used by desktop Firefox to get consistent
|
||||
|
|
|
@ -94,12 +94,7 @@ function test() {
|
|||
loadNextTest();
|
||||
}
|
||||
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set':[["security.csp.speccompliant", true]]},
|
||||
function () {
|
||||
loadNextTest();
|
||||
}
|
||||
);
|
||||
loadNextTest();
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -100,13 +100,9 @@ window.examiner = new examiner();
|
|||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// load the resource which will generate a CSP violation report
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set':[["security.csp.speccompliant", true]]},
|
||||
function() {
|
||||
// save this for last so that our listeners are registered.
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById("cspframe").src = testFile;
|
||||
});
|
||||
// save this for last so that our listeners are registered.
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById("cspframe").src = testFile;
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
|
|
@ -125,14 +125,10 @@ function checkInline () {
|
|||
// set up and go
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set':[["security.csp.speccompliant", true]]},
|
||||
function() {
|
||||
// save this for last so that our listeners are registered.
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('cspframe').src = 'file_hash_source.html';
|
||||
document.getElementById('cspframe').addEventListener('load', checkInline, false);
|
||||
});
|
||||
// save this for last so that our listeners are registered.
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('cspframe').src = 'file_hash_source.html';
|
||||
document.getElementById('cspframe').addEventListener('load', checkInline, false);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
|
|
@ -110,13 +110,9 @@ window.testResult = function(testname, result, msg) {
|
|||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// save this for last so that our listeners are registered.
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set':[["security.csp.speccompliant", true]]},
|
||||
function() {
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('cspframe').src = 'file_multi_policy_injection_bypass.html';
|
||||
document.getElementById('cspframe2').src = 'file_multi_policy_injection_bypass_2.html';
|
||||
});
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('cspframe').src = 'file_multi_policy_injection_bypass.html';
|
||||
document.getElementById('cspframe2').src = 'file_multi_policy_injection_bypass_2.html';
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
|
|
@ -112,14 +112,10 @@ function checkInlineScriptsAndStyles () {
|
|||
window.examiner = new examiner();
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set':[["security.csp.speccompliant", true]]},
|
||||
function() {
|
||||
// save this for last so that our listeners are registered.
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('cspframe').src = 'file_nonce_source.html';
|
||||
document.getElementById('cspframe').addEventListener('load', checkInlineScriptsAndStyles, false);
|
||||
});
|
||||
// save this for last so that our listeners are registered.
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('cspframe').src = 'file_nonce_source.html';
|
||||
document.getElementById('cspframe').addEventListener('load', checkInlineScriptsAndStyles, false);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
|
|
@ -14,19 +14,14 @@
|
|||
<script class="testbody" type="text/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set':[["security.csp.speccompliant", true]]},
|
||||
function () {
|
||||
var testframe = document.getElementById('testframe');
|
||||
testframe.src = 'file_policyuri_regression_from_multipolicy.html';
|
||||
testframe.addEventListener('load', function checkInlineScriptExecuted () {
|
||||
is(this.contentDocument.getElementById('testdiv').innerHTML,
|
||||
'Inline Script Executed',
|
||||
'Inline script should execute (it would be blocked by the policy, but the policy is report-only)');
|
||||
SimpleTest.finish();
|
||||
});
|
||||
}
|
||||
);
|
||||
var testframe = document.getElementById('testframe');
|
||||
testframe.src = 'file_policyuri_regression_from_multipolicy.html';
|
||||
testframe.addEventListener('load', function checkInlineScriptExecuted () {
|
||||
is(this.contentDocument.getElementById('testdiv').innerHTML,
|
||||
'Inline Script Executed',
|
||||
'Inline script should execute (it would be blocked by the policy, but the policy is report-only)');
|
||||
SimpleTest.finish();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -40,11 +40,7 @@ SpecialPowers.registerConsoleListener(function ConsoleMsgListener(aMsg) {
|
|||
|
||||
// set up and start testing
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set': [["security.csp.speccompliant", true]]},
|
||||
function() {
|
||||
document.getElementById('cspframe').src = 'file_report_uri_missing_in_report_only_header.html';
|
||||
});
|
||||
document.getElementById('cspframe').src = 'file_report_uri_missing_in_report_only_header.html';
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
|
|
@ -47,12 +47,8 @@ SpecialPowers.registerConsoleListener(function ConsoleMsgListener(aMsg) {
|
|||
|
||||
// set up and start testing
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set': [["security.csp.speccompliant", true]]},
|
||||
function() {
|
||||
document.getElementById('cspframe').src = 'file_self_none_as_hostname_confusion.html';
|
||||
startTest = true;
|
||||
});
|
||||
document.getElementById('cspframe').src = 'file_self_none_as_hostname_confusion.html';
|
||||
startTest = true;
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
|
|
@ -27,11 +27,7 @@ function checkResult()
|
|||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set':[["security.csp.speccompliant", true]]},
|
||||
function() {
|
||||
document.getElementById('i').src = 'file_subframe_run_js_if_allowed.html';
|
||||
});
|
||||
document.getElementById('i').src = 'file_subframe_run_js_if_allowed.html';
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -79,7 +79,7 @@ function makeTest(id, expectedJSON, useReportOnlyPolicy, callback) {
|
|||
|
||||
// Load up the policy
|
||||
// set as report-only if that's the case
|
||||
csp.appendPolicy(policy, selfuri, useReportOnlyPolicy, true);
|
||||
csp.appendPolicy(policy, selfuri, useReportOnlyPolicy);
|
||||
|
||||
// prime the report server
|
||||
var handler = makeReportHandler("/test" + id, "Test " + id, expectedJSON);
|
||||
|
|
|
@ -500,7 +500,7 @@ test(function test_FrameAncestor_ignores_userpass_bug779918() {
|
|||
function testPermits(aChildUri, aParentUri, aContentType) {
|
||||
let cspObj = Cc["@mozilla.org/contentsecuritypolicy;1"]
|
||||
.createInstance(Ci.nsIContentSecurityPolicy);
|
||||
cspObj.appendPolicy(testPolicy, aChildUri, false, false);
|
||||
cspObj.appendPolicy(testPolicy, aChildUri, false);
|
||||
let docshellparent = Cc["@mozilla.org/docshell;1"]
|
||||
.createInstance(Ci.nsIDocShell);
|
||||
let docshellchild = Cc["@mozilla.org/docshell;1"]
|
||||
|
@ -677,9 +677,9 @@ test(
|
|||
*
|
||||
* Document with CSP: https://foobar.com:4443
|
||||
* Transmitted policy:
|
||||
* "allow 'self' a.com"
|
||||
* "default-src 'self' a.com"
|
||||
* Explicit policy:
|
||||
* "allow https://foobar.com:4443 https://a.com:443"
|
||||
* "default-src https://foobar.com:4443 https://a.com:443"
|
||||
*
|
||||
* This test examines scheme and nonstandard port inheritance.
|
||||
*/
|
||||
|
@ -716,7 +716,7 @@ test(
|
|||
test(
|
||||
function test_bug634773_noneAndStarAreDifferent() {
|
||||
/**
|
||||
* Bug 634773 is that allow * and allow 'none' end up "equal" via
|
||||
* Bug 634773 is that default-src * and default-src 'none' end up "equal" via
|
||||
* CSPSourceList.prototype.equals(), which is wrong. This tests that
|
||||
* doesn't happen.
|
||||
*/
|
||||
|
@ -748,7 +748,7 @@ test(
|
|||
};
|
||||
|
||||
const policy = "script-src 'self'";
|
||||
cspObj.appendPolicy(policy, selfURI, false, true);
|
||||
cspObj.appendPolicy(policy, selfURI, false);
|
||||
|
||||
// Spec-Compliant policy default-src defaults to *.
|
||||
// This means all images are allowed, and only 'self'
|
||||
|
@ -833,13 +833,13 @@ test(function test_csp_permits_case_insensitive() {
|
|||
test(function test_CSPRep_fromPolicyURI_failswhenmixed() {
|
||||
var cspr;
|
||||
var self = "http://localhost:" + POLICY_PORT;
|
||||
var closed_policy = CSPRep.fromString("allow 'none'");
|
||||
var closed_policy = CSPRep.fromString("default-src 'none'");
|
||||
var my_uri_policy = "policy-uri " + POLICY_URI;
|
||||
|
||||
//print(" --- Ignore the following two errors if they print ---");
|
||||
cspr = CSPRep.fromString("allow *; " + my_uri_policy, URI(self));
|
||||
cspr = CSPRep.fromString("default-src *; " + my_uri_policy, URI(self));
|
||||
|
||||
//"Parsing should fail when 'policy-uri' is mixed with allow directive"
|
||||
//"Parsing should fail when 'policy-uri' is mixed with default-src directive"
|
||||
do_check_equivalent(cspr, closed_policy);
|
||||
cspr = CSPRep.fromString("img-src 'self'; " + my_uri_policy, URI(self));
|
||||
|
||||
|
|
|
@ -3660,7 +3660,11 @@ CanvasRenderingContext2D::DrawWindow(nsGlobalWindow& window, double x,
|
|||
}
|
||||
nsRefPtr<gfxContext> thebes;
|
||||
RefPtr<DrawTarget> drawDT;
|
||||
if (gfxPlatform::GetPlatform()->SupportsAzureContentForDrawTarget(mTarget)) {
|
||||
// Rendering directly is faster and can be done if mTarget supports Azure
|
||||
// and does not need alpha blending.
|
||||
if (gfxPlatform::GetPlatform()->SupportsAzureContentForDrawTarget(mTarget) &&
|
||||
GlobalAlpha() == 1.0f)
|
||||
{
|
||||
thebes = new gfxContext(mTarget);
|
||||
thebes->SetMatrix(gfxMatrix(matrix._11, matrix._12, matrix._21,
|
||||
matrix._22, matrix._31, matrix._32));
|
||||
|
@ -3698,7 +3702,7 @@ CanvasRenderingContext2D::DrawWindow(nsGlobalWindow& window, double x,
|
|||
mgfx::Rect sourceRect(0, 0, sw, sh);
|
||||
mTarget->DrawSurface(source, destRect, sourceRect,
|
||||
DrawSurfaceOptions(mgfx::Filter::POINT),
|
||||
DrawOptions(1.0f, CompositionOp::OP_OVER,
|
||||
DrawOptions(GlobalAlpha(), CompositionOp::OP_OVER,
|
||||
AntialiasMode::NONE));
|
||||
mTarget->Flush();
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
<template>
#
|
|
@ -55,3 +55,4 @@ load 877910.html
|
|||
load 903106.html
|
||||
load 916322-1.html
|
||||
load 916322-2.html
|
||||
load 1032654.html
|
||||
|
|
|
@ -276,7 +276,7 @@ HTMLLinkElement::UpdateImport()
|
|||
// 2. rel type should be import.
|
||||
nsAutoString rel;
|
||||
GetAttr(kNameSpaceID_None, nsGkAtoms::rel, rel);
|
||||
uint32_t linkTypes = nsStyleLinkElement::ParseLinkTypes(rel);
|
||||
uint32_t linkTypes = nsStyleLinkElement::ParseLinkTypes(rel, NodePrincipal());
|
||||
if (!(linkTypes & eHTMLIMPORT)) {
|
||||
mImportLoader = nullptr;
|
||||
return;
|
||||
|
@ -288,7 +288,7 @@ HTMLLinkElement::UpdateImport()
|
|||
return;
|
||||
}
|
||||
|
||||
if (!nsStyleLinkElement::IsImportEnabled()) {
|
||||
if (!nsStyleLinkElement::IsImportEnabled(NodePrincipal())) {
|
||||
// For now imports are hidden behind a pref...
|
||||
return;
|
||||
}
|
||||
|
@ -330,7 +330,8 @@ HTMLLinkElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|||
aName == nsGkAtoms::type)) {
|
||||
bool dropSheet = false;
|
||||
if (aName == nsGkAtoms::rel) {
|
||||
uint32_t linkTypes = nsStyleLinkElement::ParseLinkTypes(aValue);
|
||||
uint32_t linkTypes = nsStyleLinkElement::ParseLinkTypes(aValue,
|
||||
NodePrincipal());
|
||||
if (GetSheet()) {
|
||||
dropSheet = !(linkTypes & nsStyleLinkElement::eSTYLESHEET);
|
||||
} else if (linkTypes & eHTMLIMPORT) {
|
||||
|
@ -456,7 +457,7 @@ HTMLLinkElement::GetStyleSheetInfo(nsAString& aTitle,
|
|||
|
||||
nsAutoString rel;
|
||||
GetAttr(kNameSpaceID_None, nsGkAtoms::rel, rel);
|
||||
uint32_t linkTypes = nsStyleLinkElement::ParseLinkTypes(rel);
|
||||
uint32_t linkTypes = nsStyleLinkElement::ParseLinkTypes(rel, NodePrincipal());
|
||||
// Is it a stylesheet link?
|
||||
if (!(linkTypes & nsStyleLinkElement::eSTYLESHEET)) {
|
||||
return;
|
||||
|
|
|
@ -607,7 +607,8 @@ nsXMLContentSink::CloseElement(nsIContent* aContent)
|
|||
nsAutoString relVal;
|
||||
aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::rel, relVal);
|
||||
if (!relVal.IsEmpty()) {
|
||||
uint32_t linkTypes = nsStyleLinkElement::ParseLinkTypes(relVal);
|
||||
uint32_t linkTypes =
|
||||
nsStyleLinkElement::ParseLinkTypes(relVal, aContent->NodePrincipal());
|
||||
bool hasPrefetch = linkTypes & nsStyleLinkElement::ePREFETCH;
|
||||
if (hasPrefetch || (linkTypes & nsStyleLinkElement::eNEXT)) {
|
||||
nsAutoString hrefVal;
|
||||
|
|
|
@ -1598,8 +1598,7 @@ ConcatJSString(JSContext* cx, const char* pre, JS::Handle<JSString*> str, const
|
|||
|
||||
bool
|
||||
NativeToString(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<JSObject*> obj, const char* pre,
|
||||
const char* post,
|
||||
JS::Handle<JSObject*> obj,
|
||||
JS::MutableHandle<JS::Value> v)
|
||||
{
|
||||
JS::Rooted<JSPropertyDescriptor> toStringDesc(cx);
|
||||
|
@ -1644,7 +1643,6 @@ NativeToString(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
|||
JS::Rooted<JSFunction*> fun(cx, JS_GetObjectFunction(obj));
|
||||
str = JS_DecompileFunction(cx, fun, 0);
|
||||
}
|
||||
str = ConcatJSString(cx, pre, str, post);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2385,14 +2385,11 @@ MustInheritFromNonRefcountedDOMObject(NonRefcountedDOMObject*)
|
|||
* wrapper is the Xray JS object.
|
||||
* obj is the target object of the Xray, a binding's instance object or a
|
||||
* interface or interface prototype object.
|
||||
* pre is a string that should be prefixed to the value.
|
||||
* post is a string that should be prefixed to the value.
|
||||
* v contains the JSString for the value if the function returns true.
|
||||
*/
|
||||
bool
|
||||
NativeToString(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<JSObject*> obj, const char* pre,
|
||||
const char* post,
|
||||
JS::Handle<JSObject*> obj,
|
||||
JS::MutableHandle<JS::Value> v);
|
||||
|
||||
HAS_MEMBER(JSBindingFinalized)
|
||||
|
|
|
@ -150,7 +150,6 @@ public:
|
|||
|
||||
MediaPermissionRequest(nsRefPtr<dom::GetUserMediaRequest> &aRequest,
|
||||
nsTArray<nsCOMPtr<nsIMediaDevice> > &aDevices);
|
||||
virtual ~MediaPermissionRequest() {}
|
||||
|
||||
// It will be called when prompt dismissed.
|
||||
virtual bool Recv__delete__(const bool &allow,
|
||||
|
@ -159,6 +158,9 @@ public:
|
|||
|
||||
already_AddRefed<nsPIDOMWindow> GetOwner();
|
||||
|
||||
protected:
|
||||
virtual ~MediaPermissionRequest() {}
|
||||
|
||||
private:
|
||||
nsresult DoAllow(const nsString &audioDevice, const nsString &videoDevice);
|
||||
|
||||
|
@ -378,6 +380,8 @@ public:
|
|||
|
||||
MediaDeviceSuccessCallback(nsRefPtr<dom::GetUserMediaRequest> &aRequest)
|
||||
: mRequest(aRequest) {}
|
||||
|
||||
protected:
|
||||
virtual ~MediaDeviceSuccessCallback() {}
|
||||
|
||||
private:
|
||||
|
@ -479,6 +483,7 @@ public:
|
|||
MediaDeviceErrorCallback(const nsAString &aCallID)
|
||||
: mCallID(aCallID) {}
|
||||
|
||||
protected:
|
||||
virtual ~MediaDeviceErrorCallback() {}
|
||||
|
||||
private:
|
||||
|
|
|
@ -23,6 +23,8 @@ public:
|
|||
NS_DECL_NSIOBSERVER
|
||||
|
||||
static MediaPermissionManager* GetInstance();
|
||||
|
||||
protected:
|
||||
virtual ~MediaPermissionManager();
|
||||
|
||||
private:
|
||||
|
|
|
@ -431,32 +431,28 @@ nsGeolocationRequest::Allow(JS::HandleValue aChoices)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMGeoPosition> lastPosition = gs->GetCachedPosition();
|
||||
DOMTimeStamp cachedPositionTime;
|
||||
if (lastPosition) {
|
||||
lastPosition->GetTimestamp(&cachedPositionTime);
|
||||
}
|
||||
|
||||
// check to see if we can use a cached value
|
||||
// if the user has specified a maximumAge, return a cached value.
|
||||
|
||||
uint32_t maximumAge = 0;
|
||||
if (mOptions) {
|
||||
if (mOptions->mMaximumAge > 0) {
|
||||
maximumAge = mOptions->mMaximumAge;
|
||||
bool canUseCache = false;
|
||||
CachedPositionAndAccuracy lastPosition = gs->GetCachedPosition();
|
||||
if (lastPosition.position) {
|
||||
DOMTimeStamp cachedPositionTime_ms;
|
||||
lastPosition.position->GetTimestamp(&cachedPositionTime_ms);
|
||||
// check to see if we can use a cached value
|
||||
// if the user has specified a maximumAge, return a cached value.
|
||||
if (mOptions && mOptions->mMaximumAge > 0) {
|
||||
uint32_t maximumAge_ms = mOptions->mMaximumAge;
|
||||
bool isCachedWithinRequestedAccuracy = WantsHighAccuracy() <= lastPosition.isHighAccuracy;
|
||||
bool isCachedWithinRequestedTime =
|
||||
DOMTimeStamp(PR_Now() / PR_USEC_PER_MSEC - maximumAge_ms) <= cachedPositionTime_ms;
|
||||
canUseCache = isCachedWithinRequestedAccuracy && isCachedWithinRequestedTime;
|
||||
}
|
||||
}
|
||||
|
||||
gs->UpdateAccuracy(WantsHighAccuracy());
|
||||
|
||||
bool canUseCache = lastPosition && maximumAge > 0 &&
|
||||
(PRTime(PR_Now() / PR_USEC_PER_MSEC) - maximumAge <=
|
||||
PRTime(cachedPositionTime));
|
||||
|
||||
if (canUseCache) {
|
||||
// okay, we can return a cached position
|
||||
// getCurrentPosition requests serviced by the cache
|
||||
// will now be owned by the RequestSendLocationEvent
|
||||
Update(lastPosition);
|
||||
Update(lastPosition.position);
|
||||
}
|
||||
|
||||
if (mIsWatchPositionRequest || !canUseCache) {
|
||||
|
@ -764,7 +760,7 @@ nsGeolocationService::HandleMozsettingValue(const bool aValue)
|
|||
// turn things off
|
||||
StopDevice();
|
||||
Update(nullptr);
|
||||
mLastPosition = nullptr;
|
||||
mLastPosition.position = nullptr;
|
||||
sGeoEnabled = false;
|
||||
} else {
|
||||
sGeoEnabled = true;
|
||||
|
@ -854,10 +850,11 @@ nsGeolocationService::NotifyError(uint16_t aErrorCode)
|
|||
void
|
||||
nsGeolocationService::SetCachedPosition(nsIDOMGeoPosition* aPosition)
|
||||
{
|
||||
mLastPosition = aPosition;
|
||||
mLastPosition.position = aPosition;
|
||||
mLastPosition.isHighAccuracy = mHigherAccuracy;
|
||||
}
|
||||
|
||||
nsIDOMGeoPosition*
|
||||
CachedPositionAndAccuracy
|
||||
nsGeolocationService::GetCachedPosition()
|
||||
{
|
||||
return mLastPosition;
|
||||
|
|
|
@ -45,6 +45,11 @@ typedef CallbackObjectHolder<PositionErrorCallback, nsIDOMGeoPositionErrorCallba
|
|||
}
|
||||
}
|
||||
|
||||
struct CachedPositionAndAccuracy {
|
||||
nsCOMPtr<nsIDOMGeoPosition> position;
|
||||
bool isHighAccuracy;
|
||||
};
|
||||
|
||||
/**
|
||||
* Singleton that manages the geolocation provider
|
||||
*/
|
||||
|
@ -73,7 +78,7 @@ public:
|
|||
void RemoveLocator(mozilla::dom::Geolocation* locator);
|
||||
|
||||
void SetCachedPosition(nsIDOMGeoPosition* aPosition);
|
||||
nsIDOMGeoPosition* GetCachedPosition();
|
||||
CachedPositionAndAccuracy GetCachedPosition();
|
||||
|
||||
// Find and startup a geolocation device (gps, nmea, etc.)
|
||||
nsresult StartDevice(nsIPrincipal* aPrincipal);
|
||||
|
@ -106,7 +111,7 @@ private:
|
|||
nsTArray<mozilla::dom::Geolocation*> mGeolocators;
|
||||
|
||||
// This is the last geo position that we have seen.
|
||||
nsCOMPtr<nsIDOMGeoPosition> mLastPosition;
|
||||
CachedPositionAndAccuracy mLastPosition;
|
||||
|
||||
// Current state of requests for higher accuracy
|
||||
bool mHigherAccuracy;
|
||||
|
|
|
@ -20,7 +20,7 @@ let gLoggingEnabled = false;
|
|||
from the Wifi subsystem. If this timer fires, we believe the Wifi scan has
|
||||
had a problem and we no longer can use Wifi to position the user this time
|
||||
around (we will continue to be hopeful that Wifi will recover).
|
||||
|
||||
|
||||
This timeout value is also used when Wifi scanning is disabled (see
|
||||
gWifiScanningEnabled). In this case, we use this timer to collect cell/ip
|
||||
data and xhr it to the location server.
|
||||
|
@ -39,6 +39,172 @@ function LOG(aMsg) {
|
|||
}
|
||||
}
|
||||
|
||||
function CachedRequest(loc, cellInfo, wifiList) {
|
||||
this.location = loc;
|
||||
|
||||
let wifis = new Set();
|
||||
if (wifiList) {
|
||||
for (let i = 0; i < wifiList.length; i++) {
|
||||
wifis.add(wifiList[i].macAddress);
|
||||
}
|
||||
}
|
||||
|
||||
// Use only these values for equality
|
||||
// (the JSON will contain additional values in future)
|
||||
function makeCellKey(cell) {
|
||||
return "" + cell.radio + ":" + cell.mobileCountryCode + ":" +
|
||||
cell.mobileNetworkCode + ":" + cell.locationAreaCode + ":" +
|
||||
cell.cellId;
|
||||
}
|
||||
|
||||
let cells = new Set();
|
||||
if (cellInfo) {
|
||||
for (let i = 0; i < cellInfo.length; i++) {
|
||||
cells.add(makeCellKey(cellInfo[i]));
|
||||
}
|
||||
}
|
||||
|
||||
this.hasCells = () => cells.size > 0;
|
||||
|
||||
this.hasWifis = () => wifis.size > 0;
|
||||
|
||||
// if fields match
|
||||
this.isCellEqual = function(cellInfo) {
|
||||
if (!this.hasCells()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let len1 = cells.size;
|
||||
let len2 = cellInfo.length;
|
||||
|
||||
if (len1 != len2) {
|
||||
LOG("cells not equal len");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < len2; i++) {
|
||||
if (!cells.has(makeCellKey(cellInfo[i]))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
// if 50% of the SSIDS match
|
||||
this.isWifiApproxEqual = function(wifiList) {
|
||||
if (!this.hasWifis()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// if either list is a 50% subset of the other, they are equal
|
||||
let common = 0;
|
||||
for (let i = 0; i < wifiList.length; i++) {
|
||||
if (wifis.has(wifiList[i].macAddress)) {
|
||||
common++;
|
||||
}
|
||||
}
|
||||
let kPercentMatch = 0.5;
|
||||
return common >= (Math.max(wifis.size, wifiList.length) * kPercentMatch);
|
||||
};
|
||||
|
||||
this.isGeoip = function() {
|
||||
return !this.hasCells() && !this.hasWifis();
|
||||
};
|
||||
|
||||
this.isCellAndWifi = function() {
|
||||
return this.hasCells() && this.hasWifis();
|
||||
};
|
||||
|
||||
this.isCellOnly = function() {
|
||||
return this.hasCells() && !this.hasWifis();
|
||||
};
|
||||
|
||||
this.isWifiOnly = function() {
|
||||
return this.hasWifis() && !this.hasCells();
|
||||
};
|
||||
}
|
||||
|
||||
let gCachedRequest = null;
|
||||
let gDebugCacheReasoning = ""; // for logging the caching logic
|
||||
|
||||
// This function serves two purposes:
|
||||
// 1) do we have a cached request
|
||||
// 2) is the cached request better than what newCell and newWifiList will obtain
|
||||
// If the cached request exists, and we know it to have greater accuracy
|
||||
// by the nature of its origin (wifi/cell/geoip), use its cached location.
|
||||
//
|
||||
// If there is more source info than the cached request had, return false
|
||||
// In other cases, MLS is known to produce better/worse accuracy based on the
|
||||
// inputs, so base the decision on that.
|
||||
function isCachedRequestMoreAccurateThanServerRequest(newCell, newWifiList)
|
||||
{
|
||||
gDebugCacheReasoning = "";
|
||||
let isNetworkRequestCacheEnabled = true;
|
||||
try {
|
||||
// Mochitest needs this pref to simulate request failure
|
||||
isNetworkRequestCacheEnabled = Services.prefs.getBoolPref("geo.wifi.debug.requestCache.enabled");
|
||||
if (!isNetworkRequestCacheEnabled) {
|
||||
gCachedRequest = null;
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
if (!gCachedRequest || !isNetworkRequestCacheEnabled) {
|
||||
gDebugCacheReasoning = "No cached data";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!newCell && !newWifiList) {
|
||||
gDebugCacheReasoning = "New req. is GeoIP.";
|
||||
return true;
|
||||
}
|
||||
|
||||
if (newCell && newWifiList && (gCachedRequest.isCellOnly() || gCachedRequest.isWifiOnly())) {
|
||||
gDebugCacheReasoning = "New req. is cell+wifi, cache only cell or wifi.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (newCell && gCachedRequest.isWifiOnly()) {
|
||||
// In order to know if a cell-only request should trump a wifi-only request
|
||||
// need to know if wifi is low accuracy. >5km would be VERY low accuracy,
|
||||
// it is worth trying the cell
|
||||
var isHighAccuracyWifi = gCachedRequest.location.coords.accuracy < 5000;
|
||||
gDebugCacheReasoning = "Req. is cell, cache is wifi, isHigh:" + isHighAccuracyWifi;
|
||||
return isHighAccuracyWifi;
|
||||
}
|
||||
|
||||
let hasEqualCells = false;
|
||||
if (newCell) {
|
||||
hasEqualCells = gCachedRequest.isCellEqual(newCell);
|
||||
}
|
||||
|
||||
let hasEqualWifis = false;
|
||||
if (newWifiList) {
|
||||
hasEqualWifis = gCachedRequest.isWifiApproxEqual(newWifiList);
|
||||
}
|
||||
|
||||
gDebugCacheReasoning = "EqualCells:" + hasEqualCells + " EqualWifis:" + hasEqualWifis;
|
||||
|
||||
if (gCachedRequest.isCellOnly()) {
|
||||
gDebugCacheReasoning += ", Cell only.";
|
||||
if (hasEqualCells) {
|
||||
return true;
|
||||
}
|
||||
} else if (gCachedRequest.isWifiOnly() && hasEqualWifis) {
|
||||
gDebugCacheReasoning +=", Wifi only."
|
||||
return true;
|
||||
} else if (gCachedRequest.isCellAndWifi()) {
|
||||
gDebugCacheReasoning += ", Cache has Cell+Wifi.";
|
||||
if ((hasEqualCells && hasEqualWifis) ||
|
||||
(!newWifiList && hasEqualCells) ||
|
||||
(!newCell && hasEqualWifis))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function WifiGeoCoordsObject(lat, lon, acc, alt, altacc) {
|
||||
this.latitude = lat;
|
||||
this.longitude = lon;
|
||||
|
@ -140,7 +306,7 @@ WifiGeoPositionProvider.prototype = {
|
|||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
handleError: function(message) {
|
||||
gLoggingEnabled = false;
|
||||
LOG("settings callback threw an exception, dropping");
|
||||
|
@ -178,6 +344,10 @@ WifiGeoPositionProvider.prototype = {
|
|||
return;
|
||||
}
|
||||
|
||||
// Without clearing this, we could end up using the cache almost indefinitely
|
||||
// TODO: add logic for cache lifespan, for now just be safe and clear it
|
||||
gCachedRequest = null;
|
||||
|
||||
if (this.timer) {
|
||||
this.timer.cancel();
|
||||
this.timer = null;
|
||||
|
@ -232,7 +402,7 @@ WifiGeoPositionProvider.prototype = {
|
|||
},
|
||||
|
||||
getMobileInfo: function() {
|
||||
LOG("updateMobileInfo called");
|
||||
LOG("getMobileInfo called");
|
||||
try {
|
||||
let radioService = Cc["@mozilla.org/ril;1"]
|
||||
.getService(Ci.nsIRadioInterfaceLayer);
|
||||
|
@ -269,6 +439,30 @@ WifiGeoPositionProvider.prototype = {
|
|||
},
|
||||
|
||||
sendLocationRequest: function (wifiData) {
|
||||
let data = {};
|
||||
if (wifiData) {
|
||||
data.wifiAccessPoints = wifiData;
|
||||
}
|
||||
|
||||
if (gCellScanningEnabled) {
|
||||
let cellData = this.getMobileInfo();
|
||||
if (cellData && cellData.length > 0) {
|
||||
data.cellTowers = cellData;
|
||||
}
|
||||
}
|
||||
|
||||
let useCached = isCachedRequestMoreAccurateThanServerRequest(data.cellTowers,
|
||||
data.wifiAccessPoints);
|
||||
|
||||
LOG("Use request cache:" + useCached + " reason:" + gDebugCacheReasoning);
|
||||
|
||||
if (useCached) {
|
||||
gCachedRequest.location.timestamp = Date.now();
|
||||
this.listener.update(gCachedRequest.location);
|
||||
return;
|
||||
}
|
||||
|
||||
// From here on, do a network geolocation request //
|
||||
let url = Services.urlFormatter.formatURLPref("geo.wifi.uri");
|
||||
let listener = this.listener;
|
||||
LOG("Sending request: " + url + "\n");
|
||||
|
@ -304,23 +498,12 @@ WifiGeoPositionProvider.prototype = {
|
|||
xhr.response.accuracy);
|
||||
|
||||
listener.update(newLocation);
|
||||
gCachedRequest = new CachedRequest(newLocation, data.cellTowers, data.wifiAccessPoints);
|
||||
};
|
||||
|
||||
let data = {};
|
||||
if (wifiData) {
|
||||
data.wifiAccessPoints = wifiData;
|
||||
}
|
||||
|
||||
if (gCellScanningEnabled) {
|
||||
let cellData = this.getMobileInfo();
|
||||
if (cellData) {
|
||||
data.cellTowers = cellData;
|
||||
}
|
||||
}
|
||||
|
||||
data = JSON.stringify(data);
|
||||
LOG("sending " + data);
|
||||
xhr.send(data);
|
||||
var requestData = JSON.stringify(data);
|
||||
LOG("sending " + requestData);
|
||||
xhr.send(requestData);
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=741267
|
|||
|
||||
try {
|
||||
var css = Components.utils.evalInSandbox("CSSStyleDeclaration", sandbox);
|
||||
is(css.prototype, "[object XrayWrapper [object CSSStyleDeclarationPrototype]]", "'CSSStyleDeclaration.prototype' in a sandbox should return the CSSStyleDeclaration interface prototype object");
|
||||
is(css.prototype, "[object CSSStyleDeclarationPrototype]", "'CSSStyleDeclaration.prototype' in a sandbox should return the CSSStyleDeclaration interface prototype object");
|
||||
} catch (e) {
|
||||
ok(false, "'CSSStyleDeclaration' shouldn't throw in a sandbox");
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=741267
|
|||
}
|
||||
try {
|
||||
var xhr = Components.utils.evalInSandbox("XMLHttpRequest", sandbox);
|
||||
is(xhr, "[object XrayWrapper " + XMLHttpRequest + "]", "'XMLHttpRequest' in a sandbox should return the XMLHttpRequest interface object");
|
||||
is(xhr, XMLHttpRequest + "", "'XMLHttpRequest' in a sandbox should return the XMLHttpRequest interface object");
|
||||
ok(isXrayWrapper(xhr.prototype), "Getting the prototype property on an Xray wrapper of an interface object should return an Xray wrapper");
|
||||
isnot(Object.getOwnPropertyDescriptor(xhr, "UNSENT"), undefined,
|
||||
"We should claim to have an UNSENT constant");
|
||||
|
@ -109,13 +109,13 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=741267
|
|||
}
|
||||
try {
|
||||
var xhr = Components.utils.evalInSandbox("new XMLHttpRequest()", sandbox);
|
||||
is("" + xhr, "[object XrayWrapper " + new XMLHttpRequest() + "]", "'XMLHttpRequest()' in a sandbox should create an XMLHttpRequest object");
|
||||
is("" + xhr, new XMLHttpRequest() + "", "'XMLHttpRequest()' in a sandbox should create an XMLHttpRequest object");
|
||||
} catch (e) {
|
||||
ok(false, "'new XMLHttpRequest()' shouldn't throw in a sandbox (1)");
|
||||
}
|
||||
try {
|
||||
var xhr = Components.utils.evalInSandbox("XMLHttpRequest.prototype.toString = function () { return 'Failed'; }; new XMLHttpRequest();", sandbox);
|
||||
is(xhr.toString(), "[object XrayWrapper " + new XMLHttpRequest() + "]", "XMLHttpRequest.prototype.toString in the sandbox should not override the native toString behaviour");
|
||||
is(xhr.toString(), new XMLHttpRequest() + "", "XMLHttpRequest.prototype.toString in the sandbox should not override the native toString behaviour");
|
||||
} catch (e) {
|
||||
ok(false, "'new XMLHttpRequest()' shouldn't throw in a sandbox (2)");
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=741267
|
|||
Components.utils.evalInSandbox("document.defaultView.XMLHttpRequest = function() {};", sandbox);
|
||||
var win = Components.utils.evalInSandbox("document.defaultView", sandbox);
|
||||
var xhr = new win.XMLHttpRequest();
|
||||
is("" + xhr, "[object XrayWrapper " + new XMLHttpRequest() + "]", "'XMLHttpRequest()' in a sandbox should create an XMLHttpRequest object");
|
||||
is("" + xhr, new XMLHttpRequest() + "", "'XMLHttpRequest()' in a sandbox should create an XMLHttpRequest object");
|
||||
} catch (e) {
|
||||
ok(false, "'XMLHttpRequest()' shouldn't throw in a sandbox");
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
var BASE_URL = "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs";
|
||||
|
||||
function sleep(delay)
|
||||
{
|
||||
|
@ -11,7 +12,7 @@ function force_prompt(allow, callback) {
|
|||
|
||||
function start_sending_garbage(callback)
|
||||
{
|
||||
SpecialPowers.pushPrefEnv({"set": [["geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs?action=respond-garbage"]]}, function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [["geo.wifi.uri", BASE_URL + "?action=respond-garbage"]]}, function() {
|
||||
// we need to be sure that all location data has been purged/set.
|
||||
sleep(1000);
|
||||
callback.call();
|
||||
|
@ -20,7 +21,7 @@ function start_sending_garbage(callback)
|
|||
|
||||
function stop_sending_garbage(callback)
|
||||
{
|
||||
SpecialPowers.pushPrefEnv({"set": [["geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs"]]}, function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [["geo.wifi.uri", BASE_URL + ""]]}, function() {
|
||||
// we need to be sure that all location data has been purged/set.
|
||||
sleep(1000);
|
||||
callback.call();
|
||||
|
@ -29,31 +30,37 @@ function stop_sending_garbage(callback)
|
|||
|
||||
function stop_geolocationProvider(callback)
|
||||
{
|
||||
SpecialPowers.pushPrefEnv({"set": [["geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs?action=stop-responding"]]}, function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [["geo.wifi.uri", BASE_URL + "?action=stop-responding"]]}, function() {
|
||||
// we need to be sure that all location data has been purged/set.
|
||||
sleep(1000);
|
||||
callback.call();
|
||||
});
|
||||
}
|
||||
|
||||
function set_network_request_cache_enabled(enabled, callback)
|
||||
{
|
||||
SpecialPowers.pushPrefEnv({"set": [["geo.wifi.debug.requestCache.enabled", enabled]]}, callback);
|
||||
}
|
||||
|
||||
function worse_geolocationProvider(callback)
|
||||
{
|
||||
SpecialPowers.pushPrefEnv({"set": [["geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs?action=worse-accuracy"]]}, callback);
|
||||
SpecialPowers.pushPrefEnv({"set": [["geo.wifi.uri", BASE_URL + "?action=worse-accuracy"]]}, callback);
|
||||
}
|
||||
|
||||
function resume_geolocationProvider(callback)
|
||||
{
|
||||
SpecialPowers.pushPrefEnv({"set": [["geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs"]]}, callback);
|
||||
SpecialPowers.pushPrefEnv({"set": [["geo.wifi.uri", BASE_URL + ""]]}, callback);
|
||||
}
|
||||
|
||||
function delay_geolocationProvider(delay, callback)
|
||||
{
|
||||
SpecialPowers.pushPrefEnv({"set": [["geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs?delay=" + delay]]}, callback);
|
||||
SpecialPowers.pushPrefEnv({"set": [["geo.wifi.uri", BASE_URL + "?delay=" + delay]]}, callback);
|
||||
}
|
||||
|
||||
function send404_geolocationProvider(callback)
|
||||
{
|
||||
SpecialPowers.pushPrefEnv({"set": [["geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs?action=send404"]]}, callback);
|
||||
set_network_request_cache_enabled(false, function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [["geo.wifi.uri", BASE_URL + "?action=send404"]]}, callback);});
|
||||
}
|
||||
|
||||
function check_geolocation(location) {
|
||||
|
@ -76,8 +83,8 @@ function check_geolocation(location) {
|
|||
// optional ok("heading" in coords, "Check to see if there is a heading");
|
||||
// optional ok("speed" in coords, "Check to see if there is a speed");
|
||||
|
||||
ok (location.coords.latitude == 37.41857, "lat matches known value");
|
||||
ok (location.coords.longitude == -122.08769, "lon matches known value");
|
||||
ok (Math.abs(location.coords.latitude - 37.41857) < 0.001, "lat matches known value");
|
||||
ok (Math.abs(location.coords.longitude + 122.08769) < 0.001, "lon matches known value");
|
||||
// optional ok(location.coords.altitude == 42, "alt matches known value");
|
||||
// optional ok(location.coords.altitudeAccuracy == 42, "alt acc matches known value");
|
||||
}
|
||||
|
|
|
@ -22,12 +22,18 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=850442
|
|||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
resume_geolocationProvider(function() {
|
||||
force_prompt(true, test1);
|
||||
force_prompt(true, function () {
|
||||
set_network_request_cache_enabled(false, function() {
|
||||
test1();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function done() {
|
||||
resume_geolocationProvider(function() {
|
||||
SimpleTest.finish();
|
||||
set_network_request_cache_enabled(true, function() {
|
||||
resume_geolocationProvider(function() {
|
||||
SimpleTest.finish();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -37,15 +37,18 @@ function errorCallback(err) {
|
|||
if (times >= 3) {
|
||||
navigator.geolocation.clearWatch(watchID);
|
||||
resume_geolocationProvider(function() {
|
||||
SimpleTest.finish();
|
||||
set_network_request_cache_enabled(true,
|
||||
function() { SimpleTest.finish(); } );
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function successCallback(position) {
|
||||
ok(1, "on success");
|
||||
// Now that we got a success callback, lets try to ensure
|
||||
// that we get a timeout error.
|
||||
stop_geolocationProvider(function() {});
|
||||
// The network cache is already off, now stop the sjs from reponding to requests
|
||||
stop_geolocationProvider(function(){});
|
||||
}
|
||||
|
||||
var options = {
|
||||
|
@ -54,7 +57,10 @@ var options = {
|
|||
};
|
||||
|
||||
function test1() {
|
||||
watchID = navigator.geolocation.watchPosition(successCallback, errorCallback, options);
|
||||
set_network_request_cache_enabled(false,
|
||||
function() {
|
||||
watchID = navigator.geolocation.watchPosition(successCallback, errorCallback, options);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
|
|
|
@ -229,7 +229,7 @@ partial interface Document {
|
|||
|
||||
//http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html#dfn-document-register
|
||||
partial interface Document {
|
||||
[Throws, Func="nsDocument::IsRegisterElementEnabled"]
|
||||
[Throws, Func="nsDocument::IsWebComponentsEnabled"]
|
||||
object registerElement(DOMString name, optional ElementRegistrationOptions options);
|
||||
};
|
||||
|
||||
|
|
|
@ -201,11 +201,11 @@ partial interface Element {
|
|||
|
||||
// http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-element-interface
|
||||
partial interface Element {
|
||||
[Throws,Pref="dom.webcomponents.enabled"]
|
||||
[Throws,Func="nsDocument::IsWebComponentsEnabled"]
|
||||
ShadowRoot createShadowRoot();
|
||||
[Pref="dom.webcomponents.enabled"]
|
||||
[Func="nsDocument::IsWebComponentsEnabled"]
|
||||
NodeList getDestinationInsertionPoints();
|
||||
[Pref="dom.webcomponents.enabled"]
|
||||
[Func="nsDocument::IsWebComponentsEnabled"]
|
||||
readonly attribute ShadowRoot? shadowRoot;
|
||||
};
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ partial interface HTMLLinkElement {
|
|||
|
||||
// http://w3c.github.io/webcomponents/spec/imports/#interface-import
|
||||
partial interface HTMLLinkElement {
|
||||
[Pref="dom.webcomponents.enabled"]
|
||||
[Func="nsDocument::IsWebComponentsEnabled"]
|
||||
readonly attribute Document? import;
|
||||
};
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[Pref="dom.webcomponents.enabled"]
|
||||
[Func="nsDocument::IsWebComponentsEnabled"]
|
||||
interface ShadowRoot : DocumentFragment
|
||||
{
|
||||
Element? getElementById(DOMString elementId);
|
||||
|
|
|
@ -5227,43 +5227,62 @@ nsEditor::IsAcceptableInputEvent(nsIDOMEvent* aEvent)
|
|||
// If the event is trusted, the event should always cause input.
|
||||
NS_ENSURE_TRUE(aEvent, false);
|
||||
|
||||
// If this is mouse event but this editor doesn't have focus, we shouldn't
|
||||
// handle it.
|
||||
nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aEvent);
|
||||
if (mouseEvent) {
|
||||
WidgetEvent* widgetEvent = aEvent->GetInternalNSEvent();
|
||||
if (NS_WARN_IF(!widgetEvent)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If this is dispatched by using cordinates but this editor doesn't have
|
||||
// focus, we shouldn't handle it.
|
||||
if (widgetEvent->IsUsingCoordinates()) {
|
||||
nsCOMPtr<nsIContent> focusedContent = GetFocusedContent();
|
||||
if (!focusedContent) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
nsAutoString eventType;
|
||||
aEvent->GetType(eventType);
|
||||
// If composition event or text event isn't dispatched via widget,
|
||||
// we need to ignore them since they cannot be managed by TextComposition.
|
||||
// E.g., the event was created by chrome JS.
|
||||
// Note that if we allow to handle such events, editor may be confused by
|
||||
// strange event order.
|
||||
if (eventType.EqualsLiteral("text") ||
|
||||
eventType.EqualsLiteral("compositionstart") ||
|
||||
eventType.EqualsLiteral("compositionend")) {
|
||||
WidgetGUIEvent* widgetGUIEvent =
|
||||
aEvent->GetInternalNSEvent()->AsGUIEvent();
|
||||
if (!widgetGUIEvent || !widgetGUIEvent->widget) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool isTrusted;
|
||||
nsresult rv = aEvent->GetIsTrusted(&isTrusted);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
if (isTrusted) {
|
||||
// If composition event or text event isn't dispatched via widget,
|
||||
// we need to ignore them since they cannot be managed by TextComposition.
|
||||
// E.g., the event was created by chrome JS.
|
||||
// Note that if we allow to handle such events, editor may be confused by
|
||||
// strange event order.
|
||||
bool needsWidget = false;
|
||||
WidgetGUIEvent* widgetGUIEvent = nullptr;
|
||||
switch (widgetEvent->message) {
|
||||
case NS_USER_DEFINED_EVENT:
|
||||
// If events are not created with proper event interface, their message
|
||||
// are initialized with NS_USER_DEFINED_EVENT. Let's ignore such event.
|
||||
return false;
|
||||
case NS_TEXT_TEXT:
|
||||
// Don't allow text events whose internal event are not
|
||||
// WidgetTextEvent.
|
||||
widgetGUIEvent = aEvent->GetInternalNSEvent()->AsTextEvent();
|
||||
needsWidget = true;
|
||||
break;
|
||||
case NS_COMPOSITION_START:
|
||||
case NS_COMPOSITION_END:
|
||||
case NS_COMPOSITION_UPDATE:
|
||||
// Don't allow composition events whose internal event are not
|
||||
// WidgetCompositionEvent.
|
||||
widgetGUIEvent = aEvent->GetInternalNSEvent()->AsCompositionEvent();
|
||||
needsWidget = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (needsWidget &&
|
||||
(!widgetGUIEvent || !widgetGUIEvent->widget)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Accept all trusted events.
|
||||
if (widgetEvent->mFlags.mIsTrusted) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Ignore untrusted mouse event.
|
||||
// XXX Why are we handling other untrusted input events?
|
||||
if (mouseEvent) {
|
||||
if (widgetEvent->AsMouseEventBase()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,5 +3,6 @@
|
|||
[test_bug46555.html]
|
||||
[test_bug599983.xul]
|
||||
[test_bug646194.xul]
|
||||
[test_composition_event_created_in_chrome.html]
|
||||
[test_dragdrop.html]
|
||||
[test_selection_move_commands.xul]
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<input id="input">
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var gInputElement = document.getElementById("input");
|
||||
|
||||
function getEditorIMESupport(aInputElement)
|
||||
{
|
||||
var editableElement = aInputElement.QueryInterface(Components.interfaces.nsIDOMNSEditableElement);
|
||||
ok(editableElement, "The input element doesn't have nsIDOMNSEditableElement interface");
|
||||
ok(editableElement.editor, "There is no editor for the input element");
|
||||
var editorIMESupport = editableElement.editor.QueryInterface(Components.interfaces.nsIEditorIMESupport);
|
||||
ok(editorIMESupport, "The input element doesn't have nsIEditorIMESupport interface");
|
||||
return editorIMESupport;
|
||||
}
|
||||
|
||||
var gEditorIMESupport;
|
||||
|
||||
function testNotGenerateCompositionByCreatedEvents(aEventInterface)
|
||||
{
|
||||
var compositionEvent = document.createEvent(aEventInterface);
|
||||
if (compositionEvent.initCompositionEvent) {
|
||||
compositionEvent.initCompositionEvent("compositionstart", true, true, window, "", "");
|
||||
} else if (compositionEvent.initMouseEvent) {
|
||||
compositionEvent.initMouseEvent("compositionstart", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
|
||||
}
|
||||
gInputElement.dispatchEvent(compositionEvent);
|
||||
ok(!gEditorIMESupport.composing, "Composition shouldn't be started with a created compositionstart event (" + aEventInterface + ")");
|
||||
|
||||
compositionEvent = document.createEvent(aEventInterface);
|
||||
if (compositionEvent.initCompositionEvent) {
|
||||
compositionEvent.initCompositionEvent("compositionupdate", true, false, window, "abc", "");
|
||||
} else if (compositionEvent.initMouseEvent) {
|
||||
compositionEvent.initMouseEvent("compositionupdate", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
|
||||
}
|
||||
gInputElement.dispatchEvent(compositionEvent);
|
||||
ok(!gEditorIMESupport.composing, "Composition shouldn't be started with a created compositionupdate event (" + aEventInterface + ")");
|
||||
is(gInputElement.value, "", "Input element shouldn't be modified with a created compositionupdate event (" + aEventInterface + ")");
|
||||
|
||||
compositionEvent = document.createEvent(aEventInterface);
|
||||
if (compositionEvent.initCompositionEvent) {
|
||||
compositionEvent.initCompositionEvent("compositionend", true, false, window, "abc", "");
|
||||
} else if (compositionEvent.initMouseEvent) {
|
||||
compositionEvent.initMouseEvent("compositionend", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
|
||||
}
|
||||
gInputElement.dispatchEvent(compositionEvent);
|
||||
ok(!gEditorIMESupport.composing, "Composition shouldn't be committed with a created compositionend event (" + aEventInterface + ")");
|
||||
is(gInputElement.value, "", "Input element shouldn't be committed with a created compositionend event (" + aEventInterface + ")");
|
||||
}
|
||||
|
||||
function doTests()
|
||||
{
|
||||
gInputElement.focus();
|
||||
gEditorIMESupport = getEditorIMESupport(gInputElement);
|
||||
|
||||
testNotGenerateCompositionByCreatedEvents("CompositionEvent");
|
||||
testNotGenerateCompositionByCreatedEvents("MouseEvent");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForFocus(doTests);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -258,7 +258,7 @@ ffs (int x)
|
|||
__asm _emit ((__COUNTER__>>8) & 0xff) \
|
||||
__asm _emit ((__COUNTER__>>16) & 0xff)\
|
||||
__asm _emit ((__COUNTER__>>24) & 0xff)\
|
||||
__asm lea eax, file \
|
||||
__asm lea eax, dword ptr file \
|
||||
__asm __internal_skip_line_no: \
|
||||
}; \
|
||||
} while (0)
|
||||
|
|
|
@ -150,19 +150,37 @@ void GrallocImage::SetData(const GrallocData& aData)
|
|||
*/
|
||||
static void
|
||||
ConvertYVU420SPToRGB565(void *aYData, uint32_t aYStride,
|
||||
void *aUVData, uint32_t aUVStride,
|
||||
void *aUData, void *aVData, uint32_t aUVStride,
|
||||
void *aOut,
|
||||
uint32_t aWidth, uint32_t aHeight)
|
||||
{
|
||||
uint8_t *y = (uint8_t*)aYData;
|
||||
int8_t *uv = (int8_t*)aUVData;
|
||||
bool isCbCr;
|
||||
int8_t *uv;
|
||||
|
||||
if (aUData < aVData) {
|
||||
// The color format is YCbCr
|
||||
isCbCr = true;
|
||||
uv = (int8_t*)aUData;
|
||||
} else {
|
||||
// The color format is YCrCb
|
||||
isCbCr = false;
|
||||
uv = (int8_t*)aVData;
|
||||
}
|
||||
|
||||
uint16_t *rgb = (uint16_t*)aOut;
|
||||
|
||||
for (size_t i = 0; i < aHeight; i++) {
|
||||
for (size_t j = 0; j < aWidth; j++) {
|
||||
int8_t d = uv[j | 1] - 128;
|
||||
int8_t e = uv[j & ~1] - 128;
|
||||
int8_t d, e;
|
||||
|
||||
if (isCbCr) {
|
||||
d = uv[j & ~1] - 128;
|
||||
e = uv[j | 1] - 128;
|
||||
} else {
|
||||
d = uv[j | 1] - 128;
|
||||
e = uv[j & ~1] - 128;
|
||||
}
|
||||
|
||||
// Constants taken from https://en.wikipedia.org/wiki/YUV
|
||||
int32_t r = (298 * y[j] + 409 * e + 128) >> 11;
|
||||
|
@ -183,113 +201,192 @@ ConvertYVU420SPToRGB565(void *aYData, uint32_t aYStride,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the format of vendor-specific YVU420(planar and semi-planar)
|
||||
* with the help of GraphicBuffer::lockYCbCr. In this way, we can convert
|
||||
* the YUV color format without awaring actual definition/enumeration
|
||||
* of vendor formats.
|
||||
*/
|
||||
static status_t
|
||||
ConvertVendorYUVFormatToRGB565(android::sp<GraphicBuffer>& aBuffer,
|
||||
gfx::DataSourceSurface *aSurface,
|
||||
gfx::DataSourceSurface::MappedSurface *aMappedSurface)
|
||||
{
|
||||
status_t rv = BAD_VALUE;
|
||||
|
||||
#if ANDROID_VERSION >= 18
|
||||
android_ycbcr ycbcr;
|
||||
|
||||
// Check if the vendor provides explicit addresses of Y/Cb/Cr buffer from lockYCbCr
|
||||
rv = aBuffer->lockYCbCr(android::GraphicBuffer::USAGE_SW_READ_OFTEN, &ycbcr);
|
||||
|
||||
if (rv != OK) {
|
||||
NS_WARNING("Couldn't lock graphic buffer using lockYCbCr()");
|
||||
return rv;
|
||||
}
|
||||
|
||||
GraphicBufferAutoUnlock unlock(aBuffer);
|
||||
|
||||
uint32_t width = aSurface->GetSize().width;
|
||||
uint32_t height = aSurface->GetSize().height;
|
||||
|
||||
if (ycbcr.chroma_step == 2) {
|
||||
// From the system/core/include/system/graphics.h
|
||||
// @chroma_step is the distance in bytes from one chroma pixel value to
|
||||
// the next. This is 2 bytes for semiplanar (because chroma values are
|
||||
// interleaved and each chroma value is one byte) and 1 for planar.
|
||||
ConvertYVU420SPToRGB565(ycbcr.y, ycbcr.ystride,
|
||||
ycbcr.cb, ycbcr.cr, ycbcr.cstride,
|
||||
aMappedSurface->mData,
|
||||
width, height);
|
||||
} else {
|
||||
layers::PlanarYCbCrData ycbcrData;
|
||||
ycbcrData.mYChannel = static_cast<uint8_t*>(ycbcr.y);
|
||||
ycbcrData.mYStride = ycbcr.ystride;
|
||||
ycbcrData.mYSize = aSurface->GetSize();
|
||||
ycbcrData.mCbChannel = static_cast<uint8_t*>(ycbcr.cb);
|
||||
ycbcrData.mCrChannel = static_cast<uint8_t*>(ycbcr.cr);
|
||||
ycbcrData.mCbCrStride = ycbcr.cstride;
|
||||
ycbcrData.mCbCrSize = aSurface->GetSize() / 2;
|
||||
ycbcrData.mPicSize = aSurface->GetSize();
|
||||
|
||||
gfx::ConvertYCbCrToRGB(ycbcrData,
|
||||
aSurface->GetFormat(),
|
||||
aSurface->GetSize(),
|
||||
aMappedSurface->mData,
|
||||
aMappedSurface->mStride);
|
||||
}
|
||||
#endif
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static status_t
|
||||
ConvertOmxYUVFormatToRGB565(android::sp<GraphicBuffer>& aBuffer,
|
||||
gfx::DataSourceSurface *aSurface,
|
||||
gfx::DataSourceSurface::MappedSurface *aMappedSurface,
|
||||
const layers::PlanarYCbCrData& aYcbcrData,
|
||||
int aOmxFormat)
|
||||
{
|
||||
if (!aOmxFormat) {
|
||||
NS_WARNING("Unknown color format");
|
||||
return BAD_VALUE;
|
||||
}
|
||||
|
||||
status_t rv;
|
||||
uint8_t *buffer;
|
||||
|
||||
rv = aBuffer->lock(android::GraphicBuffer::USAGE_SW_READ_OFTEN,
|
||||
reinterpret_cast<void **>(&buffer));
|
||||
if (rv != OK) {
|
||||
NS_WARNING("Couldn't lock graphic buffer");
|
||||
return BAD_VALUE;
|
||||
}
|
||||
|
||||
GraphicBufferAutoUnlock unlock(aBuffer);
|
||||
|
||||
uint32_t format = aBuffer->getPixelFormat();
|
||||
uint32_t width = aSurface->GetSize().width;
|
||||
uint32_t height = aSurface->GetSize().height;
|
||||
|
||||
if (format == GrallocImage::HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO) {
|
||||
// The Adreno hardware decoder aligns image dimensions to a multiple of 32,
|
||||
// so we have to account for that here
|
||||
uint32_t alignedWidth = ALIGN(width, 32);
|
||||
uint32_t alignedHeight = ALIGN(height, 32);
|
||||
uint32_t uvOffset = ALIGN(alignedHeight * alignedWidth, 4096);
|
||||
uint32_t uvStride = 2 * ALIGN(width / 2, 32);
|
||||
ConvertYVU420SPToRGB565(buffer, alignedWidth,
|
||||
buffer + uvOffset + 1,
|
||||
buffer + uvOffset,
|
||||
uvStride,
|
||||
aMappedSurface->mData,
|
||||
width, height);
|
||||
return OK;
|
||||
}
|
||||
|
||||
if (format == HAL_PIXEL_FORMAT_YCrCb_420_SP) {
|
||||
uint32_t uvOffset = height * width;
|
||||
ConvertYVU420SPToRGB565(buffer, width,
|
||||
buffer + uvOffset + 1,
|
||||
buffer + uvOffset,
|
||||
width,
|
||||
aMappedSurface->mData,
|
||||
width, height);
|
||||
return OK;
|
||||
}
|
||||
|
||||
if (format == HAL_PIXEL_FORMAT_YV12) {
|
||||
gfx::ConvertYCbCrToRGB(aYcbcrData,
|
||||
aSurface->GetFormat(),
|
||||
aSurface->GetSize(),
|
||||
aSurface->GetData(),
|
||||
aSurface->Stride());
|
||||
return OK;
|
||||
}
|
||||
|
||||
android::ColorConverter colorConverter((OMX_COLOR_FORMATTYPE)aOmxFormat,
|
||||
OMX_COLOR_Format16bitRGB565);
|
||||
if (!colorConverter.isValid()) {
|
||||
NS_WARNING("Invalid color conversion");
|
||||
return BAD_VALUE;
|
||||
}
|
||||
|
||||
rv = colorConverter.convert(buffer, width, height,
|
||||
0, 0, width - 1, height - 1 /* source crop */,
|
||||
aMappedSurface->mData, width, height,
|
||||
0, 0, width - 1, height - 1 /* dest crop */);
|
||||
if (rv) {
|
||||
NS_WARNING("OMX color conversion failed");
|
||||
return BAD_VALUE;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
TemporaryRef<gfx::SourceSurface>
|
||||
GrallocImage::GetAsSourceSurface()
|
||||
{
|
||||
if (!mTextureClient) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
android::sp<GraphicBuffer> graphicBuffer =
|
||||
mTextureClient->GetGraphicBuffer();
|
||||
|
||||
void *buffer;
|
||||
int32_t rv =
|
||||
graphicBuffer->lock(android::GraphicBuffer::USAGE_SW_READ_OFTEN, &buffer);
|
||||
|
||||
if (rv) {
|
||||
NS_WARNING("Couldn't lock graphic buffer");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GraphicBufferAutoUnlock unlock(graphicBuffer);
|
||||
|
||||
uint32_t format = graphicBuffer->getPixelFormat();
|
||||
uint32_t omxFormat = 0;
|
||||
|
||||
for (int i = 0; sColorIdMap[i]; i += 2) {
|
||||
if (sColorIdMap[i] == format) {
|
||||
omxFormat = sColorIdMap[i + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!omxFormat) {
|
||||
NS_WARNING("Unknown color format");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<gfx::DataSourceSurface> surface
|
||||
= gfx::Factory::CreateDataSourceSurface(GetSize(), gfx::SurfaceFormat::R5G6B5);
|
||||
RefPtr<gfx::DataSourceSurface> surface =
|
||||
gfx::Factory::CreateDataSourceSurface(GetSize(), gfx::SurfaceFormat::R5G6B5);
|
||||
if (!surface) {
|
||||
NS_WARNING("Failed to create SourceSurface.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32_t width = GetSize().width;
|
||||
uint32_t height = GetSize().height;
|
||||
|
||||
gfx::DataSourceSurface::MappedSurface mappedSurface;
|
||||
if (!surface->Map(gfx::DataSourceSurface::WRITE, &mappedSurface)) {
|
||||
NS_WARNING("Could not map DataSourceSurface");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (format == HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO) {
|
||||
// The Adreno hardware decoder aligns image dimensions to a multiple of 32,
|
||||
// so we have to account for that here
|
||||
uint32_t alignedWidth = ALIGN(width, 32);
|
||||
uint32_t alignedHeight = ALIGN(height, 32);
|
||||
uint32_t uvOffset = ALIGN(alignedHeight * alignedWidth, 4096);
|
||||
uint32_t uvStride = 2 * ALIGN(width / 2, 32);
|
||||
uint8_t* buffer_as_bytes = static_cast<uint8_t*>(buffer);
|
||||
ConvertYVU420SPToRGB565(buffer, alignedWidth,
|
||||
buffer_as_bytes + uvOffset, uvStride,
|
||||
mappedSurface.mData,
|
||||
width, height);
|
||||
int32_t rv;
|
||||
uint32_t omxFormat = 0;
|
||||
|
||||
omxFormat = GrallocImage::GetOmxFormat(graphicBuffer->getPixelFormat());
|
||||
if (!omxFormat) {
|
||||
rv = ConvertVendorYUVFormatToRGB565(graphicBuffer, surface, &mappedSurface);
|
||||
surface->Unmap();
|
||||
|
||||
if (rv != OK) {
|
||||
NS_WARNING("Unknown color format");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
if (format == HAL_PIXEL_FORMAT_YCrCb_420_SP) {
|
||||
uint32_t uvOffset = height * width;
|
||||
ConvertYVU420SPToRGB565(buffer, width,
|
||||
buffer + uvOffset, width,
|
||||
mappedSurface.mData,
|
||||
width, height);
|
||||
|
||||
surface->Unmap();
|
||||
return surface;
|
||||
}
|
||||
|
||||
if (format == HAL_PIXEL_FORMAT_YV12) {
|
||||
gfx::ConvertYCbCrToRGB(mData,
|
||||
surface->GetFormat(),
|
||||
mSize,
|
||||
surface->GetData(),
|
||||
surface->Stride());
|
||||
surface->Unmap();
|
||||
return surface;
|
||||
}
|
||||
|
||||
android::ColorConverter colorConverter((OMX_COLOR_FORMATTYPE)omxFormat,
|
||||
OMX_COLOR_Format16bitRGB565);
|
||||
|
||||
if (!colorConverter.isValid()) {
|
||||
NS_WARNING("Invalid color conversion");
|
||||
surface->Unmap();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
rv = colorConverter.convert(buffer, width, height,
|
||||
0, 0, width - 1, height - 1 /* source crop */,
|
||||
mappedSurface.mData, width, height,
|
||||
0, 0, width - 1, height - 1 /* dest crop */);
|
||||
|
||||
rv = ConvertOmxYUVFormatToRGB565(graphicBuffer, surface, &mappedSurface, mData, omxFormat);
|
||||
surface->Unmap();
|
||||
|
||||
if (rv) {
|
||||
NS_WARNING("OMX color conversion failed");
|
||||
if (rv != OK) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -107,6 +107,20 @@ public:
|
|||
return (static_cast<ANativeWindowBuffer*>(GetNativeBuffer()))->usage;
|
||||
}
|
||||
|
||||
static int GetOmxFormat(int aFormat)
|
||||
{
|
||||
uint32_t omxFormat = 0;
|
||||
|
||||
for (int i = 0; sColorIdMap[i]; i += 2) {
|
||||
if (sColorIdMap[i] == aFormat) {
|
||||
omxFormat = sColorIdMap[i + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return omxFormat;
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<GrallocTextureClientOGL> mTextureClient;
|
||||
};
|
||||
|
|
|
@ -116,27 +116,30 @@ AppendToString(std::stringstream& aStream, const nsIntSize& sz,
|
|||
|
||||
void
|
||||
AppendToString(std::stringstream& aStream, const FrameMetrics& m,
|
||||
const char* pfx, const char* sfx)
|
||||
const char* pfx, const char* sfx, bool detailed)
|
||||
{
|
||||
aStream << pfx;
|
||||
AppendToString(aStream, m.mViewport, "{ viewport=");
|
||||
AppendToString(aStream, m.mCompositionBounds, " cb=");
|
||||
AppendToString(aStream, m.GetScrollOffset(), " viewportScroll=");
|
||||
AppendToString(aStream, m.mDisplayPort, " displayport=");
|
||||
AppendToString(aStream, m.mCriticalDisplayPort, " critdp=");
|
||||
AppendToString(aStream, m.mScrollableRect, " scrollableRect=");
|
||||
AppendToString(aStream, m.GetScrollId(), " scrollId=", " }");
|
||||
aStream << sfx;
|
||||
}
|
||||
|
||||
void
|
||||
AppendToString(std::stringstream& aStream, const IntSize& size,
|
||||
const char* pfx, const char* sfx)
|
||||
{
|
||||
aStream << pfx;
|
||||
aStream << nsPrintfCString(
|
||||
"(width=%d, height=%d)",
|
||||
size.width, size.height).get();
|
||||
AppendToString(aStream, m.mCompositionBounds, "{ cb=");
|
||||
AppendToString(aStream, m.mScrollableRect, " sr=");
|
||||
AppendToString(aStream, m.GetScrollOffset(), " s=");
|
||||
AppendToString(aStream, m.mDisplayPort, " dp=");
|
||||
AppendToString(aStream, m.mCriticalDisplayPort, " cdp=");
|
||||
if (!detailed) {
|
||||
aStream << nsPrintfCString(" z=%.3f }", m.GetZoom().scale).get();
|
||||
} else {
|
||||
AppendToString(aStream, m.GetDisplayPortMargins(), " dpm=");
|
||||
aStream << nsPrintfCString(" um=%d", m.GetUseDisplayPortMargins()).get();
|
||||
AppendToString(aStream, m.GetRootCompositionSize(), " rcs=");
|
||||
AppendToString(aStream, m.mViewport, " v=");
|
||||
aStream << nsPrintfCString(" z=(ld=%.3f r=%.3f cr=%.3f z=%.3f ts=%.3f)",
|
||||
m.mDevPixelsPerCSSPixel.scale, m.mResolution.scale,
|
||||
m.mCumulativeResolution.scale, m.GetZoom().scale,
|
||||
m.mTransformScale.scale).get();
|
||||
aStream << nsPrintfCString(" u=(%d %lu)",
|
||||
m.GetScrollOffsetUpdated(), m.GetScrollGeneration()).get();
|
||||
aStream << nsPrintfCString(" i=(%ld %lld) }",
|
||||
m.GetPresShellId(), m.GetScrollId()).get();
|
||||
}
|
||||
aStream << sfx;
|
||||
}
|
||||
|
||||
|
|
|
@ -97,11 +97,43 @@ AppendToString(std::stringstream& aStream, const nsIntSize& sz,
|
|||
|
||||
void
|
||||
AppendToString(std::stringstream& aStream, const FrameMetrics& m,
|
||||
const char* pfx="", const char* sfx="");
|
||||
const char* pfx="", const char* sfx="", bool detailed = false);
|
||||
|
||||
template<class T>
|
||||
void
|
||||
AppendToString(std::stringstream& aStream, const mozilla::gfx::IntSize& size,
|
||||
const char* pfx="", const char* sfx="");
|
||||
AppendToString(std::stringstream& aStream, const mozilla::gfx::MarginTyped<T>& m,
|
||||
const char* pfx="", const char* sfx="")
|
||||
{
|
||||
aStream << pfx;
|
||||
aStream << nsPrintfCString(
|
||||
"(l=%f, t=%f, r=%f, b=%f)",
|
||||
m.left, m.top, m.right, m.bottom).get();
|
||||
aStream << sfx;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
AppendToString(std::stringstream& aStream, const mozilla::gfx::SizeTyped<T>& sz,
|
||||
const char* pfx="", const char* sfx="")
|
||||
{
|
||||
aStream << pfx;
|
||||
aStream << nsPrintfCString(
|
||||
"(w=%f, h=%f)",
|
||||
sz.width, sz.height).get();
|
||||
aStream << sfx;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
AppendToString(std::stringstream& aStream, const mozilla::gfx::IntSizeTyped<T>& sz,
|
||||
const char* pfx="", const char* sfx="")
|
||||
{
|
||||
aStream << pfx;
|
||||
aStream << nsPrintfCString(
|
||||
"(w=%d, h=%d)",
|
||||
sz.width, sz.height).get();
|
||||
aStream << sfx;
|
||||
}
|
||||
|
||||
void
|
||||
AppendToString(std::stringstream& aStream, const mozilla::gfx::Matrix4x4& m,
|
||||
|
|
|
@ -1084,7 +1084,7 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc,
|
|||
// Hit testing for this layer takes place in our parent layer coordinates,
|
||||
// since the composition bounds (used to initialize the visible rect against
|
||||
// which we hit test are in those coordinates).
|
||||
gfxPoint hitTestPointForThisLayer = ancestorUntransform.ProjectPoint(aHitTestPoint);
|
||||
gfxPointH3D hitTestPointForThisLayer = ancestorUntransform.ProjectPoint(aHitTestPoint);
|
||||
APZCTM_LOG("Untransformed %f %f to transient coordinates %f %f for hit-testing APZC %p\n",
|
||||
aHitTestPoint.x, aHitTestPoint.y,
|
||||
hitTestPointForThisLayer.x, hitTestPointForThisLayer.y, aApzc);
|
||||
|
@ -1096,7 +1096,7 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc,
|
|||
gfx3DMatrix childUntransform = ancestorUntransform
|
||||
* aApzc->GetCSSTransform().Inverse()
|
||||
* gfx3DMatrix(aApzc->GetCurrentAsyncTransform()).Inverse();
|
||||
gfxPoint hitTestPointForChildLayers = childUntransform.ProjectPoint(aHitTestPoint);
|
||||
gfxPointH3D hitTestPointForChildLayers = childUntransform.ProjectPoint(aHitTestPoint);
|
||||
APZCTM_LOG("Untransformed %f %f to layer coordinates %f %f for APZC %p\n",
|
||||
aHitTestPoint.x, aHitTestPoint.y,
|
||||
hitTestPointForChildLayers.x, hitTestPointForChildLayers.y, aApzc);
|
||||
|
@ -1104,14 +1104,17 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc,
|
|||
AsyncPanZoomController* result = nullptr;
|
||||
// This walks the tree in depth-first, reverse order, so that it encounters
|
||||
// APZCs front-to-back on the screen.
|
||||
for (AsyncPanZoomController* child = aApzc->GetLastChild(); child; child = child->GetPrevSibling()) {
|
||||
AsyncPanZoomController* match = GetAPZCAtPoint(child, hitTestPointForChildLayers, aOutInOverscrolledApzc);
|
||||
if (match) {
|
||||
result = match;
|
||||
break;
|
||||
if (hitTestPointForChildLayers.HasPositiveWCoord()) {
|
||||
for (AsyncPanZoomController* child = aApzc->GetLastChild(); child; child = child->GetPrevSibling()) {
|
||||
AsyncPanZoomController* match = GetAPZCAtPoint(child, hitTestPointForChildLayers.As2DPoint(), aOutInOverscrolledApzc);
|
||||
if (match) {
|
||||
result = match;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!result && aApzc->VisibleRegionContains(ViewAs<ParentLayerPixel>(hitTestPointForThisLayer))) {
|
||||
if (!result && hitTestPointForThisLayer.HasPositiveWCoord() &&
|
||||
aApzc->VisibleRegionContains(ViewAs<ParentLayerPixel>(hitTestPointForThisLayer.As2DPoint()))) {
|
||||
APZCTM_LOG("Successfully matched untransformed point %f %f to visible region for APZC %p\n",
|
||||
hitTestPointForThisLayer.x, hitTestPointForThisLayer.y, aApzc);
|
||||
result = aApzc;
|
||||
|
|
|
@ -62,24 +62,21 @@
|
|||
|
||||
// #define APZC_ENABLE_RENDERTRACE
|
||||
|
||||
#define APZC_LOG(...)
|
||||
// #define APZC_LOG(...) printf_stderr("APZC: " __VA_ARGS__)
|
||||
#define APZC_LOG_FM(fm, prefix, ...) \
|
||||
APZC_LOG(prefix ":" \
|
||||
" i=(%ld %lld) cb=(%.3f %.3f %.3f %.3f) rcs=(%.3f %.3f) dp=(%.3f %.3f %.3f %.3f) dpm=(%.3f %.3f %.3f %.3f) um=%d " \
|
||||
"v=(%.3f %.3f %.3f %.3f) s=(%.3f %.3f) sr=(%.3f %.3f %.3f %.3f) z(ld=%.3f r=%.3f cr=%.3f z=%.3f ts=%.3f) u=(%d %lu)\n", \
|
||||
__VA_ARGS__, \
|
||||
fm.GetPresShellId(), fm.GetScrollId(), \
|
||||
fm.mCompositionBounds.x, fm.mCompositionBounds.y, fm.mCompositionBounds.width, fm.mCompositionBounds.height, \
|
||||
fm.GetRootCompositionSize().width, fm.GetRootCompositionSize().height, \
|
||||
fm.mDisplayPort.x, fm.mDisplayPort.y, fm.mDisplayPort.width, fm.mDisplayPort.height, \
|
||||
fm.GetDisplayPortMargins().top, fm.GetDisplayPortMargins().right, fm.GetDisplayPortMargins().bottom, fm.GetDisplayPortMargins().left, \
|
||||
fm.GetUseDisplayPortMargins() ? 1 : 0, \
|
||||
fm.mViewport.x, fm.mViewport.y, fm.mViewport.width, fm.mViewport.height, \
|
||||
fm.GetScrollOffset().x, fm.GetScrollOffset().y, \
|
||||
fm.mScrollableRect.x, fm.mScrollableRect.y, fm.mScrollableRect.width, fm.mScrollableRect.height, \
|
||||
fm.mDevPixelsPerCSSPixel.scale, fm.mResolution.scale, fm.mCumulativeResolution.scale, fm.GetZoom().scale, fm.mTransformScale.scale, \
|
||||
fm.GetScrollOffsetUpdated(), fm.GetScrollGeneration()); \
|
||||
#define ENABLE_APZC_LOGGING 0
|
||||
// #define ENABLE_APZC_LOGGING 1
|
||||
|
||||
#if ENABLE_APZC_LOGGING
|
||||
# define APZC_LOG(...) printf_stderr("APZC: " __VA_ARGS__)
|
||||
# define APZC_LOG_FM(fm, prefix, ...) \
|
||||
{ std::stringstream ss; \
|
||||
ss << nsPrintfCString(prefix, __VA_ARGS__).get(); \
|
||||
AppendToString(ss, fm, ":", "", true); \
|
||||
APZC_LOG("%s", ss.str().c_str()); \
|
||||
}
|
||||
#else
|
||||
# define APZC_LOG(...)
|
||||
# define APZC_LOG_FM(fm, prefix, ...)
|
||||
#endif
|
||||
|
||||
// Static helper functions
|
||||
namespace {
|
||||
|
|
|
@ -753,89 +753,88 @@ gfx3DMatrix::ProjectTo2D()
|
|||
return *this;
|
||||
}
|
||||
|
||||
gfxPoint gfx3DMatrix::ProjectPoint(const gfxPoint& aPoint) const
|
||||
gfxPointH3D gfx3DMatrix::ProjectPoint(const gfxPoint& aPoint) const
|
||||
{
|
||||
// Define a ray of the form P + Ut where t is a real number
|
||||
// w is assumed to always be 1 when transforming 3d points with our
|
||||
// 4x4 matrix.
|
||||
// p is our click point, q is another point on the same ray.
|
||||
//
|
||||
// Note: since the transformation is a general projective transformation and is not
|
||||
// necessarily affine, we can't just take a unit vector u, back-transform it, and use
|
||||
// it as unit vector on the back-transformed ray. Instead, we really must take two points
|
||||
// on the ray and back-transform them.
|
||||
gfxPoint3D p(aPoint.x, aPoint.y, 0);
|
||||
gfxPoint3D q(aPoint.x, aPoint.y, 1);
|
||||
// Find a value for z that will transform to 0.
|
||||
|
||||
// Back transform the vectors (using w = 1) and normalize
|
||||
// back into 3d vectors by dividing by the w component.
|
||||
gfxPoint3D pback = Transform3D(p);
|
||||
gfxPoint3D qback = Transform3D(q);
|
||||
gfxPoint3D uback = qback - pback;
|
||||
// The transformed value of z is computed as:
|
||||
// z' = aPoint.x * _13 + aPoint.y * _23 + z * _33 + _43;
|
||||
|
||||
// Find the point where the back transformed line intersects z=0
|
||||
// and find t.
|
||||
// Solving for z when z' = 0 gives us:
|
||||
float z = -(aPoint.x * _13 + aPoint.y * _23 + _43) / _33;
|
||||
|
||||
// Compute the transformed point
|
||||
return Transform4D(gfxPointH3D(aPoint.x, aPoint.y, z, 1));
|
||||
}
|
||||
|
||||
gfxPointH3D ComputePerspectivePlaneIntercept(const gfxPointH3D& aFirst,
|
||||
const gfxPointH3D& aSecond)
|
||||
{
|
||||
// FIXME: See bug 1035611
|
||||
// Since we can't easily deal with points as w=0 (since we divide by w), we
|
||||
// approximate this by finding a point with w just greater than 0. Unfortunately
|
||||
// this is a tradeoff between accuracy and floating point precision.
|
||||
|
||||
float t = -pback.z / uback.z;
|
||||
// We want to interpolate aFirst and aSecond to find a point as close to
|
||||
// the positive side of the w=0 plane as possible.
|
||||
|
||||
gfxPoint result(pback.x + t*uback.x, pback.y + t*uback.y);
|
||||
// Since we know what we want the w component to be, we can rearrange the
|
||||
// interpolation equation and solve for t.
|
||||
float w = 0.00001f;
|
||||
float t = (w - aFirst.w) / (aSecond.w - aFirst.w);
|
||||
|
||||
return result;
|
||||
// Use t to find the remainder of the components
|
||||
return aFirst + (aSecond - aFirst) * t;
|
||||
}
|
||||
|
||||
gfxRect gfx3DMatrix::ProjectRectBounds(const gfxRect& aRect) const
|
||||
{
|
||||
gfxPoint points[4];
|
||||
gfxPointH3D points[4];
|
||||
|
||||
points[0] = ProjectPoint(aRect.TopLeft());
|
||||
points[1] = ProjectPoint(aRect.TopRight());
|
||||
points[2] = ProjectPoint(aRect.BottomLeft());
|
||||
points[3] = ProjectPoint(aRect.BottomRight());
|
||||
|
||||
gfxFloat min_x, max_x;
|
||||
gfxFloat min_y, max_y;
|
||||
gfxFloat min_x = std::numeric_limits<gfxFloat>::max();
|
||||
gfxFloat min_y = std::numeric_limits<gfxFloat>::max();
|
||||
gfxFloat max_x = -std::numeric_limits<gfxFloat>::max();
|
||||
gfxFloat max_y = -std::numeric_limits<gfxFloat>::max();
|
||||
|
||||
min_x = max_x = points[0].x;
|
||||
min_y = max_y = points[0].y;
|
||||
bool foundPoint = false;
|
||||
for (int i=0; i<4; i++) {
|
||||
// Only use points that exist above the w=0 plane
|
||||
if (points[i].HasPositiveWCoord()) {
|
||||
foundPoint = true;
|
||||
gfxPoint point2d = points[i].As2DPoint();
|
||||
min_x = min(point2d.x, min_x);
|
||||
max_x = max(point2d.x, max_x);
|
||||
min_y = min(point2d.y, min_y);
|
||||
max_y = max(point2d.y, max_y);
|
||||
}
|
||||
|
||||
for (int i=1; i<4; i++) {
|
||||
min_x = min(points[i].x, min_x);
|
||||
max_x = max(points[i].x, max_x);
|
||||
min_y = min(points[i].y, min_y);
|
||||
max_y = max(points[i].y, max_y);
|
||||
int next = (i == 3) ? 0 : i + 1;
|
||||
if (points[i].HasPositiveWCoord() != points[next].HasPositiveWCoord()) {
|
||||
// If the line between two points crosses the w=0 plane, then interpolate a point
|
||||
// as close to the w=0 plane as possible and use that instead.
|
||||
gfxPointH3D intercept = ComputePerspectivePlaneIntercept(points[i], points[next]);
|
||||
MOZ_ASSERT(intercept.HasPositiveWCoord());
|
||||
|
||||
gfxPoint point2d = intercept.As2DPoint();
|
||||
min_x = min(point2d.x, min_x);
|
||||
max_x = max(point2d.x, max_x);
|
||||
min_y = min(point2d.y, min_y);
|
||||
max_y = max(point2d.y, max_y);
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundPoint) {
|
||||
return gfxRect(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
return gfxRect(min_x, min_y, max_x - min_x, max_y - min_y);
|
||||
}
|
||||
|
||||
gfxRect gfx3DMatrix::UntransformBounds(const gfxRect& aRect, const gfxRect& aChildBounds) const
|
||||
{
|
||||
if (Is2D()) {
|
||||
return Inverse().TransformBounds(aRect);
|
||||
}
|
||||
gfxRect bounds = TransformBounds(aChildBounds);
|
||||
|
||||
gfxRect rect = aRect.Intersect(bounds);
|
||||
|
||||
return Inverse().ProjectRectBounds(rect);
|
||||
}
|
||||
|
||||
bool gfx3DMatrix::UntransformPoint(const gfxPoint& aPoint, const gfxRect& aChildBounds, gfxPoint* aOut) const
|
||||
{
|
||||
if (Is2D()) {
|
||||
*aOut = Inverse().Transform(aPoint);
|
||||
return true;
|
||||
}
|
||||
gfxRect bounds = TransformBounds(aChildBounds);
|
||||
|
||||
if (!bounds.Contains(aPoint)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*aOut = Inverse().ProjectPoint(aPoint);
|
||||
return true;
|
||||
}
|
||||
|
||||
gfxPoint3D gfx3DMatrix::GetNormalVector() const
|
||||
{
|
||||
// Define a plane in transformed space as the transformations
|
||||
|
|
|
@ -247,29 +247,13 @@ public:
|
|||
gfxPointH3D Transform4D(const gfxPointH3D& aPoint) const;
|
||||
gfxPointH3D TransposeTransform4D(const gfxPointH3D& aPoint) const;
|
||||
|
||||
gfxPoint ProjectPoint(const gfxPoint& aPoint) const;
|
||||
/**
|
||||
* Given a point (x,y) find a value for z such that (x,y,z,1) transforms
|
||||
* into (x',y',0,w') and returns the latter.
|
||||
*/
|
||||
gfxPointH3D ProjectPoint(const gfxPoint& aPoint) const;
|
||||
gfxRect ProjectRectBounds(const gfxRect& aRect) const;
|
||||
|
||||
/**
|
||||
* Transforms a point by the inverse of this matrix. In the case of perspective transforms, some screen
|
||||
* points have no equivalent in the untransformed plane (if they exist past the vanishing point). To
|
||||
* avoid this, we need to specify the bounds of the untransformed plane to restrict the search area.
|
||||
*
|
||||
* @param aPoint Point to untransform.
|
||||
* @param aChildBounds Bounds of the untransformed plane.
|
||||
* @param aOut Untransformed point.
|
||||
* @return Returns true if a point was found within a ChildBounds, false otherwise.
|
||||
*/
|
||||
bool UntransformPoint(const gfxPoint& aPoint, const gfxRect& aChildBounds, gfxPoint* aOut) const;
|
||||
|
||||
|
||||
/**
|
||||
* Same as UntransformPoint, but untransforms a rect and returns the bounding rect of the result.
|
||||
* Returns an empty rect if the result doesn't intersect aChildBounds.
|
||||
*/
|
||||
gfxRect UntransformBounds(const gfxRect& aRect, const gfxRect& aChildBounds) const;
|
||||
|
||||
|
||||
/**
|
||||
* Inverts this matrix, if possible. Otherwise, the matrix is left
|
||||
* unchanged.
|
||||
|
|
|
@ -8,12 +8,19 @@
|
|||
|
||||
#include "mozilla/gfx/BasePoint4D.h"
|
||||
#include "gfxTypes.h"
|
||||
#include "gfxPoint.h"
|
||||
|
||||
struct gfxPointH3D : public mozilla::gfx::BasePoint4D<float, gfxPointH3D> {
|
||||
typedef mozilla::gfx::BasePoint4D<float, gfxPointH3D> Super;
|
||||
|
||||
gfxPointH3D() : Super() {}
|
||||
gfxPointH3D(float aX, float aY, float aZ, float aW) : Super(aX, aY, aZ, aW) {}
|
||||
|
||||
bool HasPositiveWCoord() { return w > 0; }
|
||||
|
||||
gfxPoint As2DPoint() {
|
||||
return gfxPoint(x / w, y / w);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* GFX_POINTH3D_H */
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче