Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9edf1b7bea |
No files matched your search
@@ -22,4 +22,4 @@
|
||||
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||
# don't change CLOBBER for WebIDL changes any more.
|
||||
|
||||
Touching ICU's build system requires a CLOBBER. (Issue #2165)
|
||||
Clobber for NSS update
|
||||
+50
-7
@@ -137,10 +137,16 @@ default:: $(BUILD_BACKEND_FILES)
|
||||
endif
|
||||
|
||||
install_manifests := \
|
||||
$(addprefix dist/,branding bin idl include public private sdk xpi-stage) \
|
||||
$(addprefix dist/,branding idl include public private sdk xpi-stage) \
|
||||
_tests \
|
||||
$(NULL)
|
||||
|
||||
# Skip the dist/bin install manifest when using the hybrid
|
||||
# FasterMake/RecursiveMake backend. This is a hack until bug 1241744 moves
|
||||
# xpidl handling to FasterMake in that case, mechanically making the dist/bin
|
||||
# install manifest non-existent (non-existent manifests being skipped)
|
||||
ifeq (,$(filter FasterMake+RecursiveMake,$(BUILD_BACKENDS)))
|
||||
install_manifests += dist/bin
|
||||
endif
|
||||
install_manifest_depends = \
|
||||
CLOBBER \
|
||||
$(configure_dir)/configure \
|
||||
@@ -160,9 +166,45 @@ endif
|
||||
.PHONY: install-manifests
|
||||
install-manifests: $(addprefix install-,$(install_manifests))
|
||||
|
||||
.PHONY: $(addprefix install-,$(install_manifests))
|
||||
# If we're using the hybrid FasterMake/RecursiveMake backend, we want
|
||||
# to recurse in the faster/ directory in parallel of install manifests.
|
||||
# But dist/idl needs to happen before (cf. dependencies in
|
||||
# config/faster/rules.mk)
|
||||
ifneq (,$(filter FasterMake+RecursiveMake,$(BUILD_BACKENDS)))
|
||||
install-manifests: faster
|
||||
.PHONY: faster
|
||||
faster: install-dist/idl
|
||||
$(MAKE) -C faster FASTER_RECURSIVE_MAKE=1
|
||||
endif
|
||||
|
||||
.PHONY: tup
|
||||
tup:
|
||||
$(call BUILDSTATUS,TIERS make tup)
|
||||
$(call BUILDSTATUS,TIER_START make)
|
||||
$(MAKE) install-manifests buildid.h source-repo.h
|
||||
$(call BUILDSTATUS,TIER_FINISH make)
|
||||
$(call BUILDSTATUS,TIER_START tup)
|
||||
@$(TUP) $(if $(findstring s,$(filter-out --%,$(MAKEFLAGS))),,--verbose)
|
||||
$(call BUILDSTATUS,TIER_FINISH tup)
|
||||
|
||||
# process_install_manifest needs to be invoked with --no-remove when building
|
||||
# js as standalone because automated builds are building nspr separately and
|
||||
# that would remove the resulting files.
|
||||
# Eventually, a standalone js build would just be able to build nspr itself,
|
||||
# removing the need for the former.
|
||||
ifdef JS_STANDALONE
|
||||
NO_REMOVE=1
|
||||
endif
|
||||
|
||||
.PHONY: $(addprefix install-,$(subst /,_,$(install_manifests)))
|
||||
$(addprefix install-,$(install_manifests)): install-%: $(install_manifest_depends)
|
||||
$(addprefix $(call py_action,process_install_manifest,--track install_$(subst /,_,$*).track $*) ,$(wildcard _build_manifests/install/$(subst /,_,$*)))
|
||||
ifneq (,$(filter FasterMake+RecursiveMake,$(BUILD_BACKENDS)))
|
||||
@# If we're using the hybrid FasterMake/RecursiveMake backend, we want
|
||||
@# to ensure the FasterMake end doesn't have install manifests for the
|
||||
@# same directory, because that would blow up
|
||||
$(if $(wildcard _build_manifests/install/$(subst /,_,$*)),$(if $(wildcard faster/install_$(subst /,_,$*)*),$(error FasterMake and RecursiveMake ends of the hybrid build system want to handle $*)))
|
||||
endif
|
||||
$(addprefix $(call py_action,process_install_manifest,$(if $(NO_REMOVE),--no-remove )$*) ,$(wildcard _build_manifests/install/$(subst /,_,$*)))
|
||||
|
||||
# Dummy wrapper rule to allow the faster backend to piggy back
|
||||
$(addprefix install-,$(subst /,_,$(filter dist/%,$(install_manifests)))): install-dist_%: install-dist/% ;
|
||||
@@ -175,9 +217,10 @@ install-tests: install-test-files
|
||||
.PHONY: run-tests-deps
|
||||
run-tests-deps: $(install_manifest_depends)
|
||||
|
||||
# Force --no-remove, because $objdir/_tests is handled by multiple manifests.
|
||||
.PHONY: install-test-files
|
||||
install-test-files:
|
||||
$(call py_action,process_install_manifest,--track install__test_files.track _tests _build_manifests/install/_test_files)
|
||||
$(call py_action,process_install_manifest,--no-remove _tests _build_manifests/install/_test_files)
|
||||
|
||||
include $(topsrcdir)/build/moz-automation.mk
|
||||
|
||||
@@ -197,13 +240,13 @@ ifndef NO_PROFILE_GUIDED_OPTIMIZE
|
||||
ifneq ($(OS_ARCH)_$(GNU_CC), WINNT_)
|
||||
recurse_pre-export:: install-manifests
|
||||
binaries::
|
||||
@$(MAKE) install-manifests install_manifests=dist/include
|
||||
@$(MAKE) install-manifests NO_REMOVE=1 install_manifests=dist/include
|
||||
endif
|
||||
endif
|
||||
else # !MOZ_PROFILE_USE (normal build)
|
||||
recurse_pre-export:: install-manifests
|
||||
binaries::
|
||||
@$(MAKE) install-manifests install_manifests=dist/include
|
||||
@$(MAKE) install-manifests NO_REMOVE=1 install_manifests=dist/include
|
||||
endif
|
||||
|
||||
# For historical reasons that are unknown, $(DIST)/sdk is always blown away
|
||||
|
||||
@@ -33,7 +33,5 @@ If you fork this repository to perform your own work on it, please consider offe
|
||||
improvement patches upstream to its origin to mutually improve the platform and build
|
||||
a future for XUL.
|
||||
|
||||
## Looking for Pale Moon?
|
||||
As of [`Issue #969`](https://repo.palemoon.org/MoonchildProductions/UXP/issues/969), release version `28.9.0`,
|
||||
applications have been split off into their own dedicated (front-end) repositories, with Pale Moon located at
|
||||
[`MoonchildProductions/Pale-Moon`](https://repo.palemoon.org/MoonchildProductions/Pale-Moon).
|
||||
## Looking for Pale Moon and Basilisk?
|
||||
As of [`Issue #969`](https://repo.palemoon.org/MoonchildProductions/UXP/issues/969), release versions `28.9.0` and `2020.03.04` respectively, they have been split off into their own dedicated repositories located at [`MoonchildProductions/Pale-Moon`](https://repo.palemoon.org/MoonchildProductions/Pale-Moon) and [`MoonchildProductions/Basilisk`](https://repo.palemoon.org/MoonchildProductions/Basilisk).
|
||||
Vendored
+1
@@ -25,6 +25,7 @@ builtin(include, build/autoconf/zlib.m4)dnl
|
||||
builtin(include, build/autoconf/icu.m4)dnl
|
||||
builtin(include, build/autoconf/clang-plugin.m4)dnl
|
||||
builtin(include, build/autoconf/alloc.m4)dnl
|
||||
builtin(include, build/autoconf/ios.m4)dnl
|
||||
builtin(include, build/autoconf/sanitize.m4)dnl
|
||||
|
||||
MOZ_PROG_CHECKMSYS()
|
||||
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
import java.util.regex.Pattern
|
||||
|
||||
allprojects {
|
||||
// Expose the per-object-directory configuration to all projects.
|
||||
ext {
|
||||
mozconfig = gradle.mozconfig
|
||||
topsrcdir = gradle.mozconfig.topsrcdir
|
||||
topobjdir = gradle.mozconfig.topobjdir
|
||||
}
|
||||
|
||||
repositories {
|
||||
if (gradle.mozconfig.substs.GRADLE_MAVEN_REPOSITORY) {
|
||||
maven {
|
||||
url gradle.mozconfig.substs.GRADLE_MAVEN_REPOSITORY
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buildDir "${topobjdir}/gradle/build"
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
if (gradle.mozconfig.substs.GRADLE_MAVEN_REPOSITORY) {
|
||||
maven {
|
||||
url gradle.mozconfig.substs.GRADLE_MAVEN_REPOSITORY
|
||||
}
|
||||
}
|
||||
// For android-sdk-manager SNAPSHOT releases.
|
||||
maven {
|
||||
url "file://${gradle.mozconfig.topsrcdir}/mobile/android/gradle/m2repo"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:2.1.3'
|
||||
classpath('com.stanfy.spoon:spoon-gradle-plugin:1.0.4') {
|
||||
// Without these, we get errors linting.
|
||||
exclude module: 'guava'
|
||||
}
|
||||
// Provided in tree.
|
||||
classpath 'com.jakewharton.sdkmanager:gradle-plugin:1.5.0-SNAPSHOT'
|
||||
}
|
||||
}
|
||||
|
||||
task generateCodeAndResources(type:Exec) {
|
||||
workingDir "${topobjdir}"
|
||||
|
||||
commandLine mozconfig.substs.GMAKE
|
||||
args '-C'
|
||||
args "${topobjdir}/mobile/android/base"
|
||||
args 'gradle-targets'
|
||||
|
||||
// Only show the output if something went wrong.
|
||||
ignoreExitValue = true
|
||||
standardOutput = new ByteArrayOutputStream()
|
||||
errorOutput = standardOutput
|
||||
doLast {
|
||||
if (execResult.exitValue != 0) {
|
||||
throw new GradleException("Process '${commandLine}' finished with non-zero exit value ${execResult.exitValue}:\n\n${standardOutput.toString()}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Skip unit test for all build variants, unless if it was specifically requested by user.
|
||||
// The enabled property for the unit test tasks is reset based on the command line task names just before the task execution.
|
||||
// I bet there is a easier/cleaner way to do this, but this gets the job done for now.
|
||||
Pattern pattern = Pattern.compile('.*test(.+UnitTest)?.*')
|
||||
boolean startTasksIncludeTest = gradle.startParameter.taskNames.any {
|
||||
taskName ->
|
||||
taskName.matches(pattern)
|
||||
}
|
||||
gradle.taskGraph.beforeTask {
|
||||
Task task ->
|
||||
if (task.name.matches(pattern)) {
|
||||
task.enabled = startTasksIncludeTest
|
||||
}
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
subprojects {
|
||||
if (!hasProperty('android')) {
|
||||
return
|
||||
}
|
||||
android.applicationVariants.all {
|
||||
preBuild.dependsOn rootProject.generateCodeAndResources
|
||||
}
|
||||
android.libraryVariants.all {
|
||||
preBuild.dependsOn rootProject.generateCodeAndResources
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'idea'
|
||||
|
||||
idea {
|
||||
project {
|
||||
languageLevel = '1.7'
|
||||
}
|
||||
|
||||
module {
|
||||
// Object directories take a huge amount of time for IntelliJ to index.
|
||||
// Exclude them. Convention is that object directories start with obj.
|
||||
// IntelliJ is clever and will not exclude the parts of the object
|
||||
// directory that are referenced, if there are any. In practice,
|
||||
// indexing the entirety of the tree is taking too long, so exclude all
|
||||
// but mobile/.
|
||||
def topsrcdirURI = file(topsrcdir).toURI()
|
||||
excludeDirs += files(file(topsrcdir)
|
||||
.listFiles({it.isDirectory()} as FileFilter)
|
||||
.collect({topsrcdirURI.relativize(it.toURI()).toString()}) // Relative paths.
|
||||
.findAll({!it.equals('mobile/')}))
|
||||
|
||||
// If topobjdir is below topsrcdir, hide only some portions of that tree.
|
||||
def topobjdirURI = file(topobjdir).toURI()
|
||||
if (!topsrcdirURI.relativize(topobjdirURI).isAbsolute()) {
|
||||
excludeDirs -= file(topobjdir)
|
||||
excludeDirs += files(file(topobjdir).listFiles())
|
||||
excludeDirs -= file("${topobjdir}/gradle")
|
||||
}
|
||||
|
||||
if (!mozconfig.substs.MOZ_INSTALL_TRACKING) {
|
||||
excludeDirs += file("${topsrcdir}/mobile/android/thirdparty/com/adjust")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
}
|
||||
@@ -34,10 +34,11 @@ if test -n "$USE_ICU"; then
|
||||
ICU_DATA_FILE="icudt${version}l.dat"
|
||||
|
||||
dnl We won't build ICU data as a separate file when building
|
||||
dnl ICU as a shared library, as we need to fold the data into
|
||||
dnl the shared library in order for consumers like Spidermonkey
|
||||
dnl to use it without code duplication.
|
||||
if test -z "$MOZ_SHARED_ICU"; then
|
||||
dnl JS standalone so that embedders don't have to deal with it.
|
||||
dnl We also don't do it on Windows because sometimes the file goes
|
||||
dnl missing -- possibly due to overzealous antivirus software? --
|
||||
dnl which prevents the browser from starting up :(
|
||||
if test -z "$JS_STANDALONE"; then
|
||||
MOZ_ICU_DATA_ARCHIVE=1
|
||||
else
|
||||
MOZ_ICU_DATA_ARCHIVE=
|
||||
@@ -45,18 +46,17 @@ if test -n "$USE_ICU"; then
|
||||
fi
|
||||
|
||||
AC_SUBST(MOZ_ICU_VERSION)
|
||||
AC_SUBST(ENABLE_INTL_API)
|
||||
AC_SUBST(USE_ICU)
|
||||
AC_SUBST(ICU_DATA_FILE)
|
||||
AC_SUBST(MOZ_ICU_DATA_ARCHIVE)
|
||||
AC_SUBST(MOZ_SHARED_ICU)
|
||||
|
||||
if test -n "$USE_ICU"; then
|
||||
if test -z "$YASM" -a -z "$GNU_AS" -a "$COMPILE_ENVIRONMENT"; then
|
||||
AC_MSG_ERROR([Building ICU requires either yasm or a GNU assembler. If you do not have either of those available for this platform you must use --without-intl-api])
|
||||
fi
|
||||
if test -z "$MOZ_SHARED_ICU"; then
|
||||
AC_DEFINE(U_STATIC_IMPLEMENTATION)
|
||||
fi
|
||||
dnl We build ICU as a static library.
|
||||
AC_DEFINE(U_STATIC_IMPLEMENTATION)
|
||||
dnl Source files that use ICU should have control over which parts of the ICU
|
||||
dnl namespace they want to use.
|
||||
AC_DEFINE(U_USING_ICU_NAMESPACE,0)
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
dnl This Source Code Form is subject to the terms of the Mozilla Public
|
||||
dnl License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
dnl file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
AC_DEFUN([MOZ_IOS_PATH_PROG],
|
||||
[
|
||||
changequote({,})
|
||||
_prog_name=ifelse($2, {}, `echo $1 | tr "[:upper:]" "[:lower:]"`, $2)
|
||||
changequote([,])
|
||||
AC_CACHE_CHECK([for $_prog_name in iOS SDK],
|
||||
ac_cv_ios_path_$1,
|
||||
[
|
||||
_path=`xcrun --sdk $ios_sdk --find $_prog_name 2>/dev/null`
|
||||
_res=$?
|
||||
if test $_res -ne 0; then
|
||||
AC_MSG_ERROR([Could not find '$_prog_name' in the iOS SDK])
|
||||
fi
|
||||
ac_cv_ios_path_$1=$_path
|
||||
])
|
||||
$1="${ac_cv_ios_path_$1}$3"
|
||||
])
|
||||
|
||||
AC_DEFUN([MOZ_IOS_SDK],
|
||||
[
|
||||
|
||||
MOZ_ARG_WITH_STRING(ios-sdk,
|
||||
[ --with-ios-sdk=TYPE
|
||||
Type of iOS SDK to use (iphonesimulator, iphoneos)
|
||||
and optionally version (like iphoneos8.2)],
|
||||
ios_sdk=$withval)
|
||||
|
||||
MOZ_ARG_ENABLE_STRING(ios-target,
|
||||
[ --enable-ios-target=VER (default=8.0)
|
||||
Set the minimum iOS version needed at runtime],
|
||||
[_IOS_TARGET=$enableval])
|
||||
_IOS_TARGET_DEFAULT=8.0
|
||||
|
||||
case "$target" in
|
||||
arm*-apple-darwin*)
|
||||
if test -z "$ios_sdk" -o "$ios_sdk" = "yes"; then
|
||||
ios_sdk=iphoneos
|
||||
fi
|
||||
case "$ios_sdk" in
|
||||
iphoneos*)
|
||||
ios_target_arg="-miphoneos-version-min"
|
||||
;;
|
||||
*)
|
||||
AC_MSG_ERROR([Only 'iphoneos' SDKs are valid when targeting iOS device, don't know what to do with '$ios_sdk'.])
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*-apple-darwin*)
|
||||
ios_target_arg="-mios-simulator-version-min"
|
||||
case "$ios_sdk" in
|
||||
# Empty SDK is okay, this might be an OS X desktop build.
|
||||
""|iphonesimulator*)
|
||||
;;
|
||||
# Default to iphonesimulator
|
||||
yes)
|
||||
ios_sdk=iphonesimulator
|
||||
;;
|
||||
*)
|
||||
AC_MSG_ERROR([Only 'iphonesimulator' SDKs are valid when targeting iOS simulator.])
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
if test -n "$ios_sdk"; then
|
||||
if test -z "$_IOS_TARGET"; then
|
||||
_IOS_TARGET=$_IOS_TARGET_DEFAULT
|
||||
ios_target_arg="${ios_target_arg}=${_IOS_TARGET}"
|
||||
fi
|
||||
# Ensure that xcrun knows where this SDK is.
|
||||
ios_sdk_path=`xcrun --sdk $ios_sdk --show-sdk-path 2>/dev/null`
|
||||
_ret=$?
|
||||
if test $_ret -ne 0; then
|
||||
AC_MSG_ERROR([iOS SDK '$ios_sdk' could not be found.])
|
||||
fi
|
||||
MOZ_IOS=1
|
||||
export HOST_CC=clang
|
||||
export HOST_CXX=clang++
|
||||
# Add isysroot, arch, and ios target arguments
|
||||
case "$target_cpu" in
|
||||
arm*)
|
||||
ARGS="-arch armv7"
|
||||
;;
|
||||
*)
|
||||
# Unfortunately simulator builds need this.
|
||||
export CROSS_COMPILE=1
|
||||
;;
|
||||
esac
|
||||
ARGS=" $ARGS -isysroot $ios_sdk_path $ios_target_arg"
|
||||
# Now find our tools
|
||||
MOZ_IOS_PATH_PROG(CC, clang, $ARGS)
|
||||
MOZ_IOS_PATH_PROG(CXX, clang++, $ARGS)
|
||||
export CPP="$CC -E"
|
||||
export LD="$CXX"
|
||||
MOZ_IOS_PATH_PROG(AR)
|
||||
MOZ_IOS_PATH_PROG(AS, as, $ARGS)
|
||||
MOZ_IOS_PATH_PROG(OTOOL)
|
||||
MOZ_IOS_PATH_PROG(STRIP)
|
||||
export PKG_CONFIG_PATH=${ios_sdk_path}/usr/lib/pkgconfig/
|
||||
fi
|
||||
|
||||
AC_SUBST(MOZ_IOS)
|
||||
])
|
||||
@@ -27,9 +27,6 @@ fi
|
||||
if test "`echo | $AS -o conftest.out -v 2>&1 | grep -c GNU`" != "0"; then
|
||||
GNU_AS=1
|
||||
fi
|
||||
if test "`echo | $AS -o conftest.out -v 2>&1 | grep -c Apple`" != "0"; then
|
||||
GNU_AS=1
|
||||
fi
|
||||
rm -f conftest.out
|
||||
if test "`echo | $LD -v 2>&1 | grep -c GNU`" != "0"; then
|
||||
GNU_LD=1
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
# 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/.
|
||||
|
||||
# Imports
|
||||
from __future__ import print_function, unicode_literals
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
# Sanity check
|
||||
if not len(sys.argv) > 1:
|
||||
print("Incorrect number of arguments")
|
||||
sys.exit(1)
|
||||
|
||||
# Vars
|
||||
listConfigure = sys.argv[1:]
|
||||
listConfig = []
|
||||
strBrandingDirectory = ""
|
||||
listViolations = []
|
||||
|
||||
# Build a list of set configure variables
|
||||
for _value in listConfigure:
|
||||
_splitString = _value.split("=")
|
||||
|
||||
if _splitString[1] == "1":
|
||||
listConfig += [ _splitString[0] ]
|
||||
elif _splitString[0] == "MOZ_BRANDING_DIRECTORY":
|
||||
strBrandingDirectory = _splitString[1]
|
||||
|
||||
# Only applies if using Official Branding or specific branding directories
|
||||
if ('MOZ_OFFICIAL_BRANDING' in listConfig) or (strBrandingDirectory.endswith("branding/official")) or (strBrandingDirectory.endswith("branding/unstable")):
|
||||
# Applies to Pale Moon and Basilisk
|
||||
if ('MC_BASILISK' in listConfig) or ('MC_PALEMOON' in listConfig):
|
||||
listViolations += [
|
||||
'MOZ_SYSTEM_JPEG',
|
||||
'MOZ_SYSTEM_ZLIB',
|
||||
'MOZ_SYSTEM_BZ2',
|
||||
'MOZ_SYSTEM_JEMALLOC'
|
||||
]
|
||||
|
||||
# Applies to Pale Moon Only
|
||||
if 'MC_PALEMOON' in listConfig:
|
||||
listViolations += [
|
||||
'MOZ_EME',
|
||||
'MOZ_WEBRTC'
|
||||
]
|
||||
|
||||
# Iterate through enabled violations and output 1 to DIRECTIVE4 if any are found
|
||||
for _value in listViolations:
|
||||
if _value in listConfig:
|
||||
sys.stdout.write("1")
|
||||
sys.exit(1)
|
||||
|
||||
# Exit outputting nothing to DIRECTIVE4 being empty because there are no violations
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
.. _build_cppeclipse:
|
||||
|
||||
=====================
|
||||
Cpp Eclipse Projects
|
||||
=====================
|
||||
|
||||
For additional information on using Eclipse CDT see
|
||||
`the MDN page
|
||||
<https://developer.mozilla.org/en-US/docs/Eclipse_CDT>`_.
|
||||
|
||||
The build system contains alpha support for generating C++ Eclipse
|
||||
project files to aid with development.
|
||||
|
||||
Please report bugs to bugzilla and make them depend on bug 973770.
|
||||
|
||||
To generate a C++ Eclipse project files, you'll need to have a fully
|
||||
built tree::
|
||||
|
||||
mach build
|
||||
|
||||
Then, simply generate the Eclipse build backend::
|
||||
|
||||
mach build-backend -b CppEclipse
|
||||
|
||||
If all goes well, the path to the generated workspace should be
|
||||
printed.
|
||||
|
||||
To use the generated Eclipse project files, you'll need to
|
||||
have a Eclipse CDT 8.3 (We plan to follow the latest Eclipse release)
|
||||
`Eclipse CDT plugin
|
||||
<https://www.eclipse.org/cdt/>`_
|
||||
installed. You can then import all the projects into Eclipse using
|
||||
*File > Import ... > General > Existing Projects into Workspace*
|
||||
-only- if you have not ran the background indexer.
|
||||
|
||||
Updating Project Files
|
||||
======================
|
||||
|
||||
As you pull and update the source tree, your C++ Eclipse files may
|
||||
fall out of sync with the build configuration. The tree should still
|
||||
build fine from within Eclipse, but source files may be missing and in
|
||||
rare circumstances Eclipse's index may not have the proper build
|
||||
configuration.
|
||||
|
||||
To account for this, you'll want to periodically regenerate the
|
||||
Eclipse project files. You can do this by running ``mach build
|
||||
&& mach build-backend -b CppEclipse`` from the
|
||||
command line.
|
||||
|
||||
Currently, regeneration rewrites the original project files. **If
|
||||
you've made any customizations to the projects, they will likely get
|
||||
overwritten.** We would like to improve this user experience in the
|
||||
future.
|
||||
|
||||
@@ -28,6 +28,14 @@ Important Concepts
|
||||
locales
|
||||
rust
|
||||
|
||||
integrated development environment (IDE)
|
||||
========================================
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
cppeclipse
|
||||
visualstudio
|
||||
|
||||
mozbuild
|
||||
========
|
||||
|
||||
|
||||
@@ -5,44 +5,41 @@ Supported Configurations
|
||||
========================
|
||||
|
||||
This page attempts to document supported build configurations.
|
||||
For more up-to-date information please go to http://developer.palemoon.org/
|
||||
|
||||
Windows
|
||||
=======
|
||||
|
||||
We support building on Windows 7 and newer operating systems using
|
||||
Visual Studio 2015 U3.
|
||||
We support building on Windows XP and newer operating systems using
|
||||
Visual Studio 2010 and newer.
|
||||
|
||||
The following are not fully supported (but may work):
|
||||
The following are not fully supported by Mozilla (but may work):
|
||||
|
||||
* Building with a *MozillaBuild* Windows development
|
||||
environment not mentioned on the developer documentation site.
|
||||
* Building without the latest *MozillaBuild* Windows development
|
||||
environment
|
||||
* Building with Mingw or any other non-Visual Studio toolchain.
|
||||
|
||||
OS X
|
||||
====
|
||||
(This section needs updating)
|
||||
We support building on OS X 10.8 and newer with the OS X 10.8 SDK.
|
||||
|
||||
We support building on OS X 10.6 and newer with the OS X 10.6 SDK.
|
||||
|
||||
The tree should build with the following OS X releases and SDK versions:
|
||||
|
||||
* 10.6 Snow Leopard
|
||||
* 10.7 Lion
|
||||
* 10.8 Mountain Lion
|
||||
* 10.9 Mavericks
|
||||
* 10.10 Yosemite
|
||||
* 10.11 El Capitan
|
||||
* 10.12 Sierra
|
||||
* 10.13 High Sierra
|
||||
* 10.14 Mojave
|
||||
* 10.15 Catalina
|
||||
* 11 Big Sur (Including Apple ARM SoC)
|
||||
|
||||
The tree requires building with Apple's Clang 4.2 that ships with Xcode.
|
||||
This corresponds to Xcode 4.6 and newer. Xcode 4.6 only runs on OS X 10.7.4
|
||||
and newer.
|
||||
The tree requires building with Clang 3.3 and newer. This corresponds to
|
||||
version of 4.2 of Apple's Clang that ships with Xcode. This corresponds
|
||||
to Xcode 4.6 and newer. Xcode 4.6 only runs on OS X 10.7.4 and newer.
|
||||
So, OS X 10.6 users will need to install a non-Apple toolchain. Running
|
||||
``mach bootstrap`` should install an appropriate toolchain from Homebrew
|
||||
or MacPorts automatically.
|
||||
|
||||
The tree should build with GCC 7.1 and newer on OS X. However, this
|
||||
The tree should build with GCC 4.4 and newer on OS X. However, this
|
||||
build configuration isn't as widely used (and differs from what Mozilla
|
||||
uses to produce OS X builds).
|
||||
uses to produce OS X builds), so it's recommended to stick with Clang.
|
||||
|
||||
Linux
|
||||
=====
|
||||
@@ -50,6 +47,9 @@ Linux
|
||||
Linux 2.6 and later kernels are supported.
|
||||
|
||||
Most distributions are supported as long as the proper package
|
||||
dependencies are in place. ``configure`` will typically
|
||||
dependencies are in place. Running ``mach bootstrap`` should install
|
||||
packages for popular Linux distributions. ``configure`` will typically
|
||||
detect missing dependencies and inform you how to disable features to
|
||||
work around unsatisfied dependencies.
|
||||
|
||||
Clang 3.3 or GCC 4.4 is required to build the tree.
|
||||
@@ -0,0 +1,100 @@
|
||||
.. _build_visualstudio:
|
||||
|
||||
======================
|
||||
Visual Studio Projects
|
||||
======================
|
||||
|
||||
The build system contains alpha support for generating Visual Studio
|
||||
project files to aid with development.
|
||||
|
||||
To generate Visual Studio project files, you'll need to have a configured tree::
|
||||
|
||||
mach configure
|
||||
|
||||
(If you have built recently, your tree is already configured.)
|
||||
|
||||
Then, simply generate the Visual Studio build backend::
|
||||
|
||||
mach build-backend -b VisualStudio
|
||||
|
||||
If all goes well, the path to the generated Solution (``.sln``) file should be
|
||||
printed. You should be able to open that solution with Visual Studio 2010 or
|
||||
newer.
|
||||
|
||||
Currently, output is hard-coded to the Visual Studio 2010 format. If you open
|
||||
the solution in a newer Visual Studio release, you will be prompted to upgrade
|
||||
projects. Simply click through the wizard to do that.
|
||||
|
||||
Structure of Solution
|
||||
=====================
|
||||
|
||||
The Visual Studio solution consists of hundreds of projects spanning thousands
|
||||
of files. To help with organization, the solution is divided into the following
|
||||
trees/folders:
|
||||
|
||||
Build Targets
|
||||
This folder contains common build targets. The *full* project is used to
|
||||
perform a full build. The *binaries* project is used to build just binaries.
|
||||
The *visual-studio* project can be built to regenerate the Visual Studio
|
||||
project files.
|
||||
|
||||
Performing the *clean* action on any of these targets will clean the
|
||||
*entire* build output.
|
||||
|
||||
Binaries
|
||||
This folder contains common binaries that can be executed from within
|
||||
Visual Studio. If you are building the Firefox desktop application,
|
||||
the *firefox* project will launch firefox.exe. You probably want one of
|
||||
these set to your startup project.
|
||||
|
||||
Libraries
|
||||
This folder contains entries for each static library that is produced as
|
||||
part of the build. These roughly correspond to each directory in the tree
|
||||
containing C/C++. e.g. code from ``dom/base`` will be contained in the
|
||||
``dom_base`` project.
|
||||
|
||||
These projects don't do anything when built. If you build a project here,
|
||||
the *binaries* build target project is built.
|
||||
|
||||
Updating Project Files
|
||||
======================
|
||||
|
||||
As you pull and update the source tree, your Visual Studio files may fall out
|
||||
of sync with the build configuration. The tree should still build fine from
|
||||
within Visual Studio. But source files may be missing and IntelliSense may not
|
||||
have the proper build configuration.
|
||||
|
||||
To account for this, you'll want to periodically regenerate the Visual Studio
|
||||
project files. You can do this within Visual Studio by building the
|
||||
``Build Targets :: visual-studio`` project or by running
|
||||
``mach build-backend -b VisualStudio`` from the command line.
|
||||
|
||||
Currently, regeneration rewrites the original project files. **If you've made
|
||||
any customizations to the solution or projects, they will likely get
|
||||
overwritten.** We would like to improve this user experience in the
|
||||
future.
|
||||
|
||||
Moving Project Files Around
|
||||
===========================
|
||||
|
||||
The produced Visual Studio solution and project files should be portable.
|
||||
If you want to move them to a non-default directory, they should continue
|
||||
to work from wherever they are. If they don't, please file a bug.
|
||||
|
||||
Invoking mach through Visual Studio
|
||||
===================================
|
||||
|
||||
It's possible to build the tree via Visual Studio. There is some light magic
|
||||
involved here.
|
||||
|
||||
Alongside the Visual Studio project files is a batch script named ``mach.bat``.
|
||||
This batch script sets the environment variables present in your *MozillaBuild*
|
||||
development environment at the time of Visual Studio project generation
|
||||
and invokes *mach* inside an msys shell with the arguments specified to the
|
||||
batch script. This script essentially allows you to invoke mach commands
|
||||
inside the MozillaBuild environment without having to load MozillaBuild.
|
||||
|
||||
While projects currently only utilize the ``mach build`` command, the batch
|
||||
script does not limit it's use: any mach command can be invoked. Developers
|
||||
may abuse this fact to add custom projects and commands that invoke other
|
||||
mach commands.
|
||||
@@ -16,7 +16,7 @@ if os == 'WINNT':
|
||||
flavors = {
|
||||
'WINNT': 'win',
|
||||
'Linux': 'linux',
|
||||
'Darwin': 'mac',
|
||||
'Darwin': 'mac' if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa' else 'ios',
|
||||
'SunOS': 'solaris',
|
||||
'GNU/kFreeBSD': 'freebsd',
|
||||
'DragonFly': 'dragonfly',
|
||||
|
||||
@@ -100,6 +100,7 @@ MACH_MODULES = [
|
||||
'python/mach/mach/commands/settings.py',
|
||||
'python/compare-locales/mach_commands.py',
|
||||
'python/mozbuild/mozbuild/mach_commands.py',
|
||||
'python/mozbuild/mozbuild/backend/mach_commands.py',
|
||||
'python/mozbuild/mozbuild/compilation/codecomplete.py',
|
||||
'python/mozbuild/mozbuild/frontend/mach_commands.py',
|
||||
'services/common/tests/mach_commands.py',
|
||||
|
||||
@@ -97,3 +97,10 @@ if CONFIG['MOZ_VALGRIND']:
|
||||
'valgrind/i386-redhat-linux-gnu.sup',
|
||||
'valgrind/x86_64-redhat-linux-gnu.sup',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_ARTIFACT_BUILDS']:
|
||||
# Ensure a pre-built interfaces.xpt installed to the objdir by the artifact
|
||||
# code is included by the top-level chrome.manifest.
|
||||
EXTRA_COMPONENTS += [
|
||||
'prebuilt-interfaces.manifest',
|
||||
]
|
||||
@@ -321,6 +321,9 @@ def split_triplet(triplet):
|
||||
elif os.startswith('darwin'):
|
||||
canonical_kernel = 'Darwin'
|
||||
canonical_os = 'OSX'
|
||||
elif os.startswith('ios'):
|
||||
canonical_kernel = 'Darwin'
|
||||
canonical_os = 'iOS'
|
||||
elif os.startswith('dragonfly'):
|
||||
canonical_os = canonical_kernel = 'DragonFly'
|
||||
elif os.startswith('freebsd'):
|
||||
@@ -452,6 +455,10 @@ add_old_configure_arg(host_for_old_configure)
|
||||
@depends(host, target)
|
||||
def target_for_old_configure(host, target):
|
||||
target_alias = target.alias
|
||||
# old-configure does plenty of tests against $target and $target_os
|
||||
# and expects darwin for iOS, so make it happy.
|
||||
if target.os == 'iOS':
|
||||
target_alias = target_alias.replace('-ios', '-darwin')
|
||||
return '--target=%s' % target_alias
|
||||
|
||||
add_old_configure_arg(target_for_old_configure)
|
||||
|
||||
@@ -156,9 +156,7 @@ def old_configure_options(*options):
|
||||
'--enable-accessibility',
|
||||
'--enable-address-sanitizer',
|
||||
'--enable-alsa',
|
||||
'--enable-appcompat-guid',
|
||||
'--enable-av1',
|
||||
'--enable-jxl',
|
||||
'--enable-b2g-bt',
|
||||
'--enable-b2g-camera',
|
||||
'--enable-b2g-ril',
|
||||
@@ -227,7 +225,6 @@ def old_configure_options(*options):
|
||||
'--enable-safe-browsing',
|
||||
'--enable-sandbox',
|
||||
'--enable-security-sqlstore',
|
||||
'--enable-shared-icu',
|
||||
'--enable-shared-media',
|
||||
'--enable-signmar',
|
||||
'--enable-simulator',
|
||||
@@ -275,7 +272,6 @@ def old_configure_options(*options):
|
||||
'--with-ios-sdk',
|
||||
'--with-jitreport-granularity',
|
||||
'--with-macbundlename-prefix',
|
||||
'--with-macbundle-identity',
|
||||
'--with-macos-private-frameworks',
|
||||
'--with-macos-sdk',
|
||||
'--with-nspr-cflags',
|
||||
@@ -310,6 +306,7 @@ def old_configure_options(*options):
|
||||
'--disable-browser-statusbar',
|
||||
'--disable-sync',
|
||||
'--disable-personas',
|
||||
'--enable-phoenix-extensions',
|
||||
|
||||
# Below are configure flags used by Basilisk
|
||||
'--disable-webextensions',
|
||||
|
||||
@@ -383,65 +383,57 @@ def check_compiler(compiler, language, target):
|
||||
)
|
||||
|
||||
|
||||
@imports(_from='__builtin__', _import='open')
|
||||
@imports('json')
|
||||
@imports('subprocess')
|
||||
@imports('sys')
|
||||
def get_vc_paths(topsrcdir):
|
||||
def vswhere(args):
|
||||
encoding = 'mbcs' if sys.platform == 'win32' else 'utf-8'
|
||||
return json.loads(subprocess.check_output([os.path.join(topsrcdir, 'build/win32/vswhere.exe'), '-format', 'json'] + args).decode(encoding, 'replace'))
|
||||
|
||||
# Can't pass -requires with -legacy, so query each separately.
|
||||
# Legacy versions first (VS2015)
|
||||
for install in vswhere(['-legacy', '-version', '[14.0,15.0)']):
|
||||
version = Version(install['installationVersion'])
|
||||
# Skip anything older than VS2015.
|
||||
if version < '14':
|
||||
continue
|
||||
path = install['installationPath']
|
||||
|
||||
yield (Version(install['installationVersion']), {
|
||||
'x64': [os.path.join(path, r'VC\bin\amd64')],
|
||||
# The x64->x86 cross toolchain requires DLLs from the native x64 toolchain.
|
||||
'x86': [os.path.join(path, r'VC\bin\amd64_x86'), os.path.join (path, r'VC\bin\amd64')],
|
||||
})
|
||||
# Then VS2017 and newer.
|
||||
for install in vswhere(['-requires', 'Microsoft.VisualStudio.Component.VC.Tools.x86.x64']):
|
||||
path = install['installationPath']
|
||||
tools_version = open(os.path.join(path, r'VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt'), 'rb').read().strip()
|
||||
tools_path = os.path.join(path, r'VC\Tools\MSVC', tools_version, r'bin\HostX64')
|
||||
yield (Version(install['installationVersion']), {
|
||||
'x64': [os.path.join(tools_path, 'x64')],
|
||||
# The x64->x86 cross toolchain requires DLLs from the native x64 toolchain.
|
||||
'x86': [os.path.join(tools_path, 'x86'), os.path.join(tools_path, 'x64')],
|
||||
})
|
||||
|
||||
|
||||
@depends(host, target, check_build_environment)
|
||||
@imports(_from='collections', _import='defaultdict')
|
||||
@imports(_from='__builtin__', _import='sorted')
|
||||
@imports(_from='operator', _import='itemgetter')
|
||||
def get_vc_paths(base):
|
||||
vc = defaultdict(lambda: defaultdict(dict))
|
||||
subkey = r'Microsoft\VisualStudio\VC\*\*\*\Compiler'
|
||||
for v, h, t, p in get_registry_values(base + '\\' + subkey):
|
||||
vc[v][h][t] = p
|
||||
if not vc:
|
||||
return
|
||||
version, data = sorted(vc.iteritems(), key=lambda x: Version(x[0]))[-1]
|
||||
return data
|
||||
|
||||
|
||||
@depends(host)
|
||||
@imports('platform')
|
||||
def vc_compiler_path(host, target, env):
|
||||
def vc_compiler_path(host):
|
||||
if host.kernel != 'WINNT':
|
||||
return
|
||||
vc_host = {
|
||||
'x86': 'x86',
|
||||
'AMD64': 'x64',
|
||||
}.get(platform.machine())
|
||||
if vc_host is None:
|
||||
return
|
||||
vc_target = {
|
||||
'x86': 'x86',
|
||||
'x86_64': 'x64',
|
||||
'arm': 'arm',
|
||||
}.get(target.cpu)
|
||||
}.get(host.cpu)
|
||||
if vc_target is None:
|
||||
return
|
||||
all_versions = sorted(get_vc_paths(env.topsrcdir), key=itemgetter(0))
|
||||
if not all_versions:
|
||||
|
||||
base_key = r'HKEY_LOCAL_MACHINE\SOFTWARE'
|
||||
data = get_vc_paths(base_key)
|
||||
if not data:
|
||||
data = get_vc_paths(base_key + r'\Wow6432Node')
|
||||
if not data:
|
||||
return
|
||||
|
||||
# Choose the newest version.
|
||||
data = all_versions[-1][1]
|
||||
paths = data.get(vc_target)
|
||||
if not paths:
|
||||
path = data.get(vc_host, {}).get(vc_target)
|
||||
if not path and vc_host == 'x64':
|
||||
vc_host = 'x86'
|
||||
path = data.get(vc_host, {}).get(vc_target)
|
||||
if not path:
|
||||
return
|
||||
return paths
|
||||
path = os.path.dirname(path)
|
||||
if vc_host != vc_target:
|
||||
other_path = data.get(vc_host, {}).get(vc_host)
|
||||
if other_path:
|
||||
return (path, os.path.dirname(other_path))
|
||||
return (path,)
|
||||
|
||||
|
||||
@depends(vc_compiler_path)
|
||||
|
||||
@@ -261,17 +261,13 @@ def vc_path(c_compiler):
|
||||
break
|
||||
return result
|
||||
|
||||
@depends_win(vc_path, c_compiler)
|
||||
|
||||
@depends_win(vc_path)
|
||||
@checking('for the Debug Interface Access SDK', lambda x: x or 'not found')
|
||||
@imports(_from='os.path', _import='isdir')
|
||||
def dia_sdk_dir(vc_path, c_compiler):
|
||||
def dia_sdk_dir(vc_path):
|
||||
if vc_path:
|
||||
if c_compiler.version < '19.10':
|
||||
path = os.path.join(os.path.dirname(vc_path), 'DIA SDK')
|
||||
else:
|
||||
# This would be easier if we had the installationPath that
|
||||
# get_vc_paths works with, since 'DIA SDK' is relative to that.
|
||||
path = os.path.normpath(os.path.join(vc_path, r'..\..\..\..\DIA SDK'))
|
||||
path = os.path.join(os.path.dirname(vc_path), 'DIA SDK')
|
||||
if isdir(path):
|
||||
return path
|
||||
|
||||
@@ -313,36 +309,29 @@ def include_path(vc_path, windows_sdk_dir, ucrt_sdk_dir, dia_sdk_dir):
|
||||
set_config('INCLUDE', include_path)
|
||||
|
||||
|
||||
@depends_win(target, c_compiler, vc_path, valid_windows_sdk_dir, valid_ucrt_sdk_dir, dia_sdk_dir)
|
||||
@depends_win(target, vc_path, valid_windows_sdk_dir, valid_ucrt_sdk_dir, dia_sdk_dir)
|
||||
@imports('os')
|
||||
def lib_path(target, c_compiler, vc_path, windows_sdk_dir, ucrt_sdk_dir, dia_sdk_dir):
|
||||
def lib_path(target, vc_path, windows_sdk_dir, ucrt_sdk_dir, dia_sdk_dir):
|
||||
if not vc_path:
|
||||
return
|
||||
vc_target = {
|
||||
'x86': '',
|
||||
'x86_64': 'amd64',
|
||||
'arm': 'arm',
|
||||
}.get(target.cpu)
|
||||
if vc_target is None:
|
||||
return
|
||||
# As vc_target can be '', and os.path.join will happily use the empty
|
||||
# string, leading to a string ending with a backslash, that Make will
|
||||
# interpret as a "string continues on next line" indicator, use variable
|
||||
# args.
|
||||
vc_target = (vc_target,) if vc_target else ()
|
||||
sdk_target = {
|
||||
'x86': 'x86',
|
||||
'x86_64': 'x64',
|
||||
'arm': 'arm',
|
||||
}.get(target.cpu)
|
||||
|
||||
old_target = {
|
||||
'x86': '',
|
||||
'x86_64': 'amd64',
|
||||
'arm': 'arm',
|
||||
}.get(target.cpu)
|
||||
if old_target is None:
|
||||
return
|
||||
# As old_target can be '', and os.path.join will happily use the empty
|
||||
# string, leading to a string ending with a backslash, that Make will
|
||||
# interpret as a "string continues on next line" indicator, use variable
|
||||
# args.
|
||||
old_target = (old_target,) if old_target else ()
|
||||
if c_compiler.version < '19.10':
|
||||
# MSVC2015
|
||||
vc_target = old_target
|
||||
else:
|
||||
# MSVC2017 switched to use the same target naming as the sdk.
|
||||
vc_target = (sdk_target,)
|
||||
|
||||
atlmfc_dir = os.path.join(vc_path, 'atlmfc', 'lib', *vc_target)
|
||||
if not os.path.isdir(atlmfc_dir):
|
||||
die('Cannot find the ATL/MFC libraries in the Visual C++ directory (%s). '
|
||||
@@ -360,9 +349,7 @@ def lib_path(target, c_compiler, vc_path, windows_sdk_dir, ucrt_sdk_dir, dia_sdk
|
||||
os.path.join(ucrt_sdk_dir.lib, 'ucrt', sdk_target),
|
||||
))
|
||||
if dia_sdk_dir:
|
||||
# For some reason the DIA SDK still uses the old-style targets
|
||||
# even in a newer MSVC.
|
||||
libs.append(os.path.join(dia_sdk_dir, 'lib', *old_target))
|
||||
libs.append(os.path.join(dia_sdk_dir, 'lib', *vc_target))
|
||||
# Set in the environment for old-configure
|
||||
libs = os.pathsep.join(libs)
|
||||
os.environ['LIB'] = libs
|
||||
|
||||
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Binary file not shown.
@@ -287,6 +287,8 @@ public:
|
||||
|
||||
virtual bool AddonHasPermission(const nsAString& aPerm);
|
||||
|
||||
virtual bool IsOnCSSUnprefixingWhitelist() override { return false; }
|
||||
|
||||
virtual bool IsCodebasePrincipal() const { return false; };
|
||||
|
||||
static BasePrincipal* Cast(nsIPrincipal* aPrin) { return static_cast<BasePrincipal*>(aPrin); }
|
||||
|
||||
+10
-1
@@ -21,7 +21,7 @@ interface nsIDOMDocument;
|
||||
[ptr] native JSPrincipals(JSPrincipals);
|
||||
[ptr] native PrincipalArray(nsTArray<nsCOMPtr<nsIPrincipal> >);
|
||||
|
||||
[scriptable, builtinclass, uuid(f75f502d-79fd-48be-a079-e5a7b8f80c8b)]
|
||||
[scriptable, builtinclass, uuid(3da7b133-f1a0-4de9-a2bc-5c49014c1077)]
|
||||
interface nsIPrincipal : nsISerializable
|
||||
{
|
||||
/**
|
||||
@@ -333,6 +333,15 @@ interface nsIPrincipal : nsISerializable
|
||||
* Returns true iff this is the system principal.
|
||||
*/
|
||||
[infallible] readonly attribute boolean isSystemPrincipal;
|
||||
|
||||
/**
|
||||
* Returns true if this principal's origin is recognized as being on the
|
||||
* whitelist of sites that can use the CSS Unprefixing Service.
|
||||
*
|
||||
* (This interface provides a trivial implementation, just returning false;
|
||||
* subclasses can implement something more complex as-needed.)
|
||||
*/
|
||||
[noscript,notxpcom,nostdcall] bool IsOnCSSUnprefixingWhitelist();
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -85,7 +85,7 @@ nsJSPrincipals::Destroy(JSPrincipals *jsprin)
|
||||
#ifdef DEBUG
|
||||
|
||||
// Defined here so one can do principals->dump() in the debugger
|
||||
void
|
||||
JS_PUBLIC_API(void)
|
||||
JSPrincipals::dump()
|
||||
{
|
||||
if (debugToken == nsJSPrincipals::DEBUG_TOKEN) {
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
static bool gIsWhitelistingTestDomains = false;
|
||||
static bool gCodeBasePrincipalSupport = false;
|
||||
|
||||
static bool URIIsImmutable(nsIURI* aURI)
|
||||
@@ -60,6 +61,10 @@ NS_IMPL_CI_INTERFACE_GETTER(nsPrincipal,
|
||||
/* static */ void
|
||||
nsPrincipal::InitializeStatics()
|
||||
{
|
||||
Preferences::AddBoolVarCache(
|
||||
&gIsWhitelistingTestDomains,
|
||||
"layout.css.unprefixing-service.include-test-domains");
|
||||
|
||||
Preferences::AddBoolVarCache(&gCodeBasePrincipalSupport,
|
||||
"signed.applets.codebase_principal_support",
|
||||
false);
|
||||
@@ -478,6 +483,196 @@ nsPrincipal::Write(nsIObjectOutputStream* aStream)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Helper-function to indicate whether the CSS Unprefixing Service
|
||||
// whitelist should include dummy domains that are only intended for
|
||||
// use in testing. (Controlled by a pref.)
|
||||
static inline bool
|
||||
IsWhitelistingTestDomains()
|
||||
{
|
||||
return gIsWhitelistingTestDomains;
|
||||
}
|
||||
|
||||
// Checks if the given URI's host is on our "full domain" whitelist
|
||||
// (i.e. if it's an exact match against a domain that needs unprefixing)
|
||||
static bool
|
||||
IsOnFullDomainWhitelist(nsIURI* aURI)
|
||||
{
|
||||
nsAutoCString hostStr;
|
||||
nsresult rv = aURI->GetHost(hostStr);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
// NOTE: This static whitelist is expected to be short. If that changes,
|
||||
// we should consider a different representation; e.g. hash-set, prefix tree.
|
||||
static const nsLiteralCString sFullDomainsOnWhitelist[] = {
|
||||
// 0th entry only active when testing:
|
||||
NS_LITERAL_CSTRING("test1.example.org"),
|
||||
NS_LITERAL_CSTRING("map.baidu.com"),
|
||||
NS_LITERAL_CSTRING("3g.163.com"),
|
||||
NS_LITERAL_CSTRING("3glogo.gtimg.com"), // for 3g.163.com
|
||||
NS_LITERAL_CSTRING("info.3g.qq.com"), // for 3g.qq.com
|
||||
NS_LITERAL_CSTRING("3gimg.qq.com"), // for 3g.qq.com
|
||||
NS_LITERAL_CSTRING("img.m.baidu.com"), // for [shucheng|ks].baidu.com
|
||||
NS_LITERAL_CSTRING("m.mogujie.com"),
|
||||
NS_LITERAL_CSTRING("touch.qunar.com"),
|
||||
NS_LITERAL_CSTRING("mjs.sinaimg.cn"), // for sina.cn
|
||||
NS_LITERAL_CSTRING("static.qiyi.com"), // for m.iqiyi.com
|
||||
NS_LITERAL_CSTRING("cdn.kuaidi100.com"), // for m.kuaidi100.com
|
||||
NS_LITERAL_CSTRING("m.pc6.com"),
|
||||
NS_LITERAL_CSTRING("m.haosou.com"),
|
||||
NS_LITERAL_CSTRING("m.mi.com"),
|
||||
NS_LITERAL_CSTRING("wappass.baidu.com"),
|
||||
NS_LITERAL_CSTRING("m.video.baidu.com"),
|
||||
NS_LITERAL_CSTRING("m.video.baidu.com"),
|
||||
NS_LITERAL_CSTRING("imgcache.gtimg.cn"), // for m.v.qq.com
|
||||
NS_LITERAL_CSTRING("s.tabelog.jp"),
|
||||
NS_LITERAL_CSTRING("s.yimg.jp"), // for s.tabelog.jp
|
||||
NS_LITERAL_CSTRING("i.yimg.jp"), // for *.yahoo.co.jp
|
||||
NS_LITERAL_CSTRING("ai.yimg.jp"), // for *.yahoo.co.jp
|
||||
NS_LITERAL_CSTRING("m.finance.yahoo.co.jp"),
|
||||
NS_LITERAL_CSTRING("daily.c.yimg.jp"), // for sp.daily.co.jp
|
||||
NS_LITERAL_CSTRING("stat100.ameba.jp"), // for ameblo.jp
|
||||
NS_LITERAL_CSTRING("user.ameba.jp"), // for ameblo.jp
|
||||
NS_LITERAL_CSTRING("www.goo.ne.jp"),
|
||||
NS_LITERAL_CSTRING("x.gnst.jp"), // for mobile.gnavi.co.jp
|
||||
NS_LITERAL_CSTRING("c.x.gnst.jp"), // for mobile.gnavi.co.jp
|
||||
NS_LITERAL_CSTRING("www.smbc-card.com"),
|
||||
NS_LITERAL_CSTRING("static.card.jp.rakuten-static.com"), // for rakuten-card.co.jp
|
||||
NS_LITERAL_CSTRING("img.travel.rakuten.co.jp"), // for travel.rakuten.co.jp
|
||||
NS_LITERAL_CSTRING("img.mixi.net"), // for mixi.jp
|
||||
NS_LITERAL_CSTRING("girlschannel.net"),
|
||||
NS_LITERAL_CSTRING("www.fancl.co.jp"),
|
||||
NS_LITERAL_CSTRING("s.cosme.net"),
|
||||
NS_LITERAL_CSTRING("www.sapporobeer.jp"),
|
||||
NS_LITERAL_CSTRING("www.mapion.co.jp"),
|
||||
NS_LITERAL_CSTRING("touch.navitime.co.jp"),
|
||||
NS_LITERAL_CSTRING("sp.mbga.jp"),
|
||||
NS_LITERAL_CSTRING("ava-a.sp.mbga.jp"), // for sp.mbga.jp
|
||||
NS_LITERAL_CSTRING("www.ntv.co.jp"),
|
||||
NS_LITERAL_CSTRING("mobile.suntory.co.jp"), // for suntory.jp
|
||||
NS_LITERAL_CSTRING("www.aeonsquare.net"),
|
||||
NS_LITERAL_CSTRING("mw.nikkei.com"),
|
||||
NS_LITERAL_CSTRING("www.nhk.or.jp"),
|
||||
NS_LITERAL_CSTRING("www.tokyo-sports.co.jp"),
|
||||
NS_LITERAL_CSTRING("www.bellemaison.jp"),
|
||||
NS_LITERAL_CSTRING("www.kuronekoyamato.co.jp"),
|
||||
NS_LITERAL_CSTRING("formassist.jp"), // for orico.jp
|
||||
NS_LITERAL_CSTRING("sp.m.reuters.co.jp"),
|
||||
NS_LITERAL_CSTRING("www.atre.co.jp"),
|
||||
NS_LITERAL_CSTRING("www.jtb.co.jp"),
|
||||
NS_LITERAL_CSTRING("www.sharp.co.jp"),
|
||||
NS_LITERAL_CSTRING("www.biccamera.com"),
|
||||
NS_LITERAL_CSTRING("weathernews.jp"),
|
||||
NS_LITERAL_CSTRING("cache.ymail.jp"), // for www.yamada-denkiweb.com
|
||||
};
|
||||
static const size_t sNumFullDomainsOnWhitelist =
|
||||
MOZ_ARRAY_LENGTH(sFullDomainsOnWhitelist);
|
||||
|
||||
// Skip 0th (dummy) entry in whitelist, unless a pref is enabled.
|
||||
const size_t firstWhitelistIdx = IsWhitelistingTestDomains() ? 0 : 1;
|
||||
|
||||
for (size_t i = firstWhitelistIdx; i < sNumFullDomainsOnWhitelist; ++i) {
|
||||
if (hostStr == sFullDomainsOnWhitelist[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Checks if the given URI's host is on our "base domain" whitelist
|
||||
// (i.e. if it's a subdomain of some host that we've whitelisted as needing
|
||||
// unprefixing for all its subdomains)
|
||||
static bool
|
||||
IsOnBaseDomainWhitelist(nsIURI* aURI)
|
||||
{
|
||||
static const nsLiteralCString sBaseDomainsOnWhitelist[] = {
|
||||
// 0th entry only active when testing:
|
||||
NS_LITERAL_CSTRING("test2.example.org"),
|
||||
NS_LITERAL_CSTRING("tbcdn.cn"), // for m.taobao.com
|
||||
NS_LITERAL_CSTRING("alicdn.com"), // for m.taobao.com
|
||||
NS_LITERAL_CSTRING("dpfile.com"), // for m.dianping.com
|
||||
NS_LITERAL_CSTRING("hao123img.com"), // for hao123.com
|
||||
NS_LITERAL_CSTRING("tabelog.k-img.com"), // for s.tabelog.com
|
||||
NS_LITERAL_CSTRING("tsite.jp"), // for *.tsite.jp
|
||||
};
|
||||
static const size_t sNumBaseDomainsOnWhitelist =
|
||||
MOZ_ARRAY_LENGTH(sBaseDomainsOnWhitelist);
|
||||
|
||||
nsCOMPtr<nsIEffectiveTLDService> tldService =
|
||||
do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
|
||||
|
||||
if (tldService) {
|
||||
// Skip 0th test-entry in whitelist, unless the testing pref is enabled.
|
||||
const size_t firstWhitelistIdx = IsWhitelistingTestDomains() ? 0 : 1;
|
||||
|
||||
// Right now, the test base-domain "test2.example.org" is the only entry in
|
||||
// its whitelist with a nonzero "depth". So we'll only bother going beyond
|
||||
// 0 depth (to 1) if that entry is enabled. (No point in slowing down the
|
||||
// normal codepath, for the benefit of a disabled test domain.) If we add a
|
||||
// "real" base-domain with a depth of >= 1 to our whitelist, we can get rid
|
||||
// of this conditional & just make this a static variable.
|
||||
const uint32_t maxSubdomainDepth = IsWhitelistingTestDomains() ? 1 : 0;
|
||||
|
||||
for (uint32_t subdomainDepth = 0;
|
||||
subdomainDepth <= maxSubdomainDepth; ++subdomainDepth) {
|
||||
|
||||
// Get the base domain (to depth |subdomainDepth|) from passed-in URI:
|
||||
nsAutoCString baseDomainStr;
|
||||
nsresult rv = tldService->GetBaseDomain(aURI, subdomainDepth,
|
||||
baseDomainStr);
|
||||
if (NS_FAILED(rv)) {
|
||||
// aURI doesn't have |subdomainDepth| levels of subdomains. If we got
|
||||
// here without a match yet, then aURI is not on our whitelist.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Compare the base domain against each entry in our whitelist:
|
||||
for (size_t i = firstWhitelistIdx; i < sNumBaseDomainsOnWhitelist; ++i) {
|
||||
if (baseDomainStr == sBaseDomainsOnWhitelist[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// The actual (non-cached) implementation of IsOnCSSUnprefixingWhitelist():
|
||||
static bool
|
||||
IsOnCSSUnprefixingWhitelistImpl(nsIURI* aURI)
|
||||
{
|
||||
// Check scheme, so we can drop any non-HTTP/HTTPS URIs right away
|
||||
nsAutoCString schemeStr;
|
||||
nsresult rv = aURI->GetScheme(schemeStr);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
// Only proceed if scheme is "http" or "https"
|
||||
if (!(StringBeginsWith(schemeStr, NS_LITERAL_CSTRING("http")) &&
|
||||
(schemeStr.Length() == 4 ||
|
||||
(schemeStr.Length() == 5 && schemeStr[4] == 's')))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (IsOnFullDomainWhitelist(aURI) ||
|
||||
IsOnBaseDomainWhitelist(aURI));
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
nsPrincipal::IsOnCSSUnprefixingWhitelist()
|
||||
{
|
||||
if (mIsOnCSSUnprefixingWhitelist.isNothing()) {
|
||||
// Value not cached -- perform our lazy whitelist-check.
|
||||
// (NOTE: If our URI is mutable, we just assume it's not on the whitelist,
|
||||
// since our caching strategy won't work. This isn't expected to be common.)
|
||||
mIsOnCSSUnprefixingWhitelist.emplace(
|
||||
mCodebaseImmutable &&
|
||||
IsOnCSSUnprefixingWhitelistImpl(mCodebase));
|
||||
}
|
||||
|
||||
return *mIsOnCSSUnprefixingWhitelist;
|
||||
}
|
||||
|
||||
/************************************************************************************************************************/
|
||||
|
||||
NS_IMPL_CLASSINFO(nsExpandedPrincipal, nullptr, nsIClassInfo::MAIN_THREAD_ONLY,
|
||||
@@ -642,6 +837,15 @@ nsExpandedPrincipal::AddonHasPermission(const nsAString& aPerm)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
nsExpandedPrincipal::IsOnCSSUnprefixingWhitelist()
|
||||
{
|
||||
// CSS Unprefixing Whitelist is a per-origin thing; doesn't really make sense
|
||||
// for an expanded principal. (And probably shouldn't be needed.)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsExpandedPrincipal::GetScriptLocation(nsACString& aStr)
|
||||
{
|
||||
|
||||
@@ -25,6 +25,7 @@ public:
|
||||
NS_IMETHOD GetDomain(nsIURI** aDomain) override;
|
||||
NS_IMETHOD SetDomain(nsIURI* aDomain) override;
|
||||
NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) override;
|
||||
virtual bool IsOnCSSUnprefixingWhitelist() override;
|
||||
bool IsCodebasePrincipal() const override { return true; }
|
||||
nsresult GetOriginInternal(nsACString& aOrigin) override;
|
||||
|
||||
@@ -54,6 +55,7 @@ public:
|
||||
bool mCodebaseImmutable;
|
||||
bool mDomainImmutable;
|
||||
bool mInitialized;
|
||||
mozilla::Maybe<bool> mIsOnCSSUnprefixingWhitelist; // Lazily-computed
|
||||
|
||||
protected:
|
||||
virtual ~nsPrincipal();
|
||||
@@ -79,6 +81,7 @@ public:
|
||||
NS_IMETHOD SetDomain(nsIURI* aDomain) override;
|
||||
NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) override;
|
||||
virtual bool AddonHasPermission(const nsAString& aPerm) override;
|
||||
virtual bool IsOnCSSUnprefixingWhitelist() override;
|
||||
virtual nsresult GetScriptLocation(nsACString &aStr) override;
|
||||
nsresult GetOriginInternal(nsACString& aOrigin) override;
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ const URLs = new Map([
|
||||
["data:text/html,Hi", true, false, true],
|
||||
["view-source:data:text/html,Hi", false, false, true],
|
||||
["javascript:alert('hi')", true, false, true],
|
||||
["moz://a", false, false, true],
|
||||
["about:test-chrome-privs", false, false, true],
|
||||
["about:test-unknown-unlinkable", false, false, true],
|
||||
["about:test-content-unlinkable", false, false, true],
|
||||
@@ -79,6 +80,7 @@ const URLs = new Map([
|
||||
["data:text/html,Hi", true, false, true],
|
||||
["view-source:data:text/html,Hi", false, false, true],
|
||||
["javascript:alert('hi')", true, false, true],
|
||||
["moz://a", false, false, true],
|
||||
["about:test-chrome-privs", false, false, true],
|
||||
["about:test-unknown-unlinkable", false, false, true],
|
||||
["about:test-content-unlinkable", false, false, true],
|
||||
@@ -100,6 +102,7 @@ const URLs = new Map([
|
||||
["data:text/html,Hi", true, false, true],
|
||||
["view-source:data:text/html,Hi", true, false, true],
|
||||
["javascript:alert('hi')", true, false, true],
|
||||
["moz://a", false, false, true],
|
||||
["about:test-chrome-privs", false, false, true],
|
||||
["about:test-unknown-unlinkable", false, false, true],
|
||||
["about:test-content-unlinkable", false, false, true],
|
||||
|
||||
@@ -160,7 +160,7 @@ nsChromeProtocolHandler::NewChannel2(nsIURI* aURI,
|
||||
file->Exists(&exists);
|
||||
if (!exists) {
|
||||
nsAutoCString path;
|
||||
file->GetNativePath(path);
|
||||
file->GetPersistentDescriptor(path);
|
||||
printf("Chrome file doesn't exist: %s\n", path.get());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ endif # WINNT
|
||||
ifndef INCLUDED_AUTOCONF_MK
|
||||
default::
|
||||
else
|
||||
TIERS := pre-export export $(if $(COMPILE_ENVIRONMENT),compile )misc libs tools
|
||||
TIERS := $(if $(MOZ_ARTIFACT_BUILDS),artifact )pre-export export $(if $(COMPILE_ENVIRONMENT),compile )misc libs tools
|
||||
endif
|
||||
|
||||
# These defines are used to support the twin-topsrcdir model for comm-central.
|
||||
|
||||
@@ -86,14 +86,12 @@ included_inclnames_to_ignore = set([
|
||||
'unicode/ucol.h', # ICU
|
||||
'unicode/udat.h', # ICU
|
||||
'unicode/udatpg.h', # ICU
|
||||
'unicode/udisplaycontext.h',# ICU
|
||||
'unicode/uenum.h', # ICU
|
||||
'unicode/uniset.h', # ICU
|
||||
'unicode/unorm2.h', # ICU
|
||||
'unicode/unorm.h', # ICU
|
||||
'unicode/unum.h', # ICU
|
||||
'unicode/unumsys.h', # ICU
|
||||
'unicode/upluralrules.h', # ICU
|
||||
'unicode/ureldatefmt.h', # ICU
|
||||
'unicode/ustring.h', # ICU
|
||||
'unicode/utypes.h', # ICU
|
||||
'vtune/VTuneWrapper.h' # VTune
|
||||
|
||||
+2
-14
@@ -377,20 +377,8 @@ endif # WINNT
|
||||
|
||||
ifdef _MSC_VER
|
||||
ifeq ($(CPU_ARCH),x86_64)
|
||||
# Normal operation on 64-bit Windows needs 2 MB of stack. (Bug 582910)
|
||||
# ASAN requires 6 MB of stack.
|
||||
# Setting the stack to 8 MB to match the capability of other systems
|
||||
# to deal with frame construction for unreasonably deep DOM trees
|
||||
# with worst-case styling. This uses address space unnecessarily for
|
||||
# non-main threads, but that should be tolerable on 64-bit systems.
|
||||
WIN32_EXE_LDFLAGS += -STACK:8388608
|
||||
else
|
||||
# Since this setting affects the default stack size for non-main
|
||||
# threads, too, to avoid burning the address space, increase only
|
||||
# 512 KB over the default. Just enough to be able to deal with
|
||||
# reasonable styling applied to DOM trees whose depth is near what
|
||||
# Blink's HTML parser can output.
|
||||
WIN32_EXE_LDFLAGS += -STACK:1572864
|
||||
# set stack to 2MB on x64 build. See bug 582910
|
||||
WIN32_EXE_LDFLAGS += -STACK:2097152
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
@@ -45,7 +45,6 @@ SECTION_INSERT_BEFORE = [
|
||||
('.text', '.fini'),
|
||||
('.rodata', '.rodata1'),
|
||||
('.data.rel.ro', '.dynamic'),
|
||||
('.kPStaticModules', '.data.rel.ro'),
|
||||
('.data', '.data1'),
|
||||
]
|
||||
|
||||
|
||||
Vendored
-2
@@ -121,8 +121,6 @@ else:
|
||||
DEFINES['SYMBOL_UNDERSCORE'] = True
|
||||
else:
|
||||
ffi_srcs = ('ffi.c', 'darwin.S', 'ffi64.c', 'darwin64.S')
|
||||
elif CONFIG['FFI_TARGET'] == 'AARCH64_DARWIN':
|
||||
ffi_srcs = ('sysv.S', 'ffi.c')
|
||||
|
||||
SOURCES += [
|
||||
'/js/src/ctypes/libffi/src/%s/%s' % (CONFIG['FFI_TARGET_DIR'], s)
|
||||
|
||||
+52
-63
@@ -4,28 +4,26 @@ SOURCES += [
|
||||
'/intl/icu/source/common/bmpset.cpp',
|
||||
'/intl/icu/source/common/brkeng.cpp',
|
||||
'/intl/icu/source/common/brkiter.cpp',
|
||||
'/intl/icu/source/common/bytesinkutil.cpp',
|
||||
'/intl/icu/source/common/bytestream.cpp',
|
||||
'/intl/icu/source/common/bytestrie.cpp',
|
||||
'/intl/icu/source/common/bytestriebuilder.cpp',
|
||||
'/intl/icu/source/common/bytestrieiterator.cpp',
|
||||
'/intl/icu/source/common/caniter.cpp',
|
||||
'/intl/icu/source/common/characterproperties.cpp',
|
||||
'/intl/icu/source/common/chariter.cpp',
|
||||
'/intl/icu/source/common/charstr.cpp',
|
||||
'/intl/icu/source/common/cmemory.cpp',
|
||||
'/intl/icu/source/common/cmemory.c',
|
||||
'/intl/icu/source/common/cstr.cpp',
|
||||
'/intl/icu/source/common/cstring.cpp',
|
||||
'/intl/icu/source/common/cwchar.cpp',
|
||||
'/intl/icu/source/common/cstring.c',
|
||||
'/intl/icu/source/common/cwchar.c',
|
||||
'/intl/icu/source/common/dictbe.cpp',
|
||||
'/intl/icu/source/common/dictionarydata.cpp',
|
||||
'/intl/icu/source/common/dtintrv.cpp',
|
||||
'/intl/icu/source/common/edits.cpp',
|
||||
'/intl/icu/source/common/errorcode.cpp',
|
||||
'/intl/icu/source/common/filteredbrk.cpp',
|
||||
'/intl/icu/source/common/filterednormalizer2.cpp',
|
||||
'/intl/icu/source/common/icudataver.cpp',
|
||||
'/intl/icu/source/common/icudataver.c',
|
||||
'/intl/icu/source/common/icuplug.cpp',
|
||||
'/intl/icu/source/common/listformatter.cpp',
|
||||
'/intl/icu/source/common/loadednormalizer2impl.cpp',
|
||||
'/intl/icu/source/common/locavailable.cpp',
|
||||
'/intl/icu/source/common/locbased.cpp',
|
||||
@@ -33,7 +31,7 @@ SOURCES += [
|
||||
'/intl/icu/source/common/locdspnm.cpp',
|
||||
'/intl/icu/source/common/locid.cpp',
|
||||
'/intl/icu/source/common/loclikely.cpp',
|
||||
'/intl/icu/source/common/locmap.cpp',
|
||||
'/intl/icu/source/common/locmap.c',
|
||||
'/intl/icu/source/common/locresdata.cpp',
|
||||
'/intl/icu/source/common/locutil.cpp',
|
||||
'/intl/icu/source/common/messagepattern.cpp',
|
||||
@@ -44,11 +42,10 @@ SOURCES += [
|
||||
'/intl/icu/source/common/patternprops.cpp',
|
||||
'/intl/icu/source/common/pluralmap.cpp',
|
||||
'/intl/icu/source/common/propname.cpp',
|
||||
'/intl/icu/source/common/propsvec.cpp',
|
||||
'/intl/icu/source/common/propsvec.c',
|
||||
'/intl/icu/source/common/punycode.cpp',
|
||||
'/intl/icu/source/common/putil.cpp',
|
||||
'/intl/icu/source/common/rbbi.cpp',
|
||||
'/intl/icu/source/common/rbbi_cache.cpp',
|
||||
'/intl/icu/source/common/rbbidata.cpp',
|
||||
'/intl/icu/source/common/rbbinode.cpp',
|
||||
'/intl/icu/source/common/rbbirb.cpp',
|
||||
@@ -70,70 +67,68 @@ SOURCES += [
|
||||
'/intl/icu/source/common/servslkf.cpp',
|
||||
'/intl/icu/source/common/sharedobject.cpp',
|
||||
'/intl/icu/source/common/simpleformatter.cpp',
|
||||
'/intl/icu/source/common/static_unicode_sets.cpp',
|
||||
'/intl/icu/source/common/stringpiece.cpp',
|
||||
'/intl/icu/source/common/stringtriebuilder.cpp',
|
||||
'/intl/icu/source/common/uarrsort.cpp',
|
||||
'/intl/icu/source/common/ubidi.cpp',
|
||||
'/intl/icu/source/common/ubidi_props.cpp',
|
||||
'/intl/icu/source/common/ubidiln.cpp',
|
||||
'/intl/icu/source/common/ubiditransform.cpp',
|
||||
'/intl/icu/source/common/ubidiwrt.cpp',
|
||||
'/intl/icu/source/common/uarrsort.c',
|
||||
'/intl/icu/source/common/ubidi.c',
|
||||
'/intl/icu/source/common/ubidi_props.c',
|
||||
'/intl/icu/source/common/ubidiln.c',
|
||||
'/intl/icu/source/common/ubiditransform.c',
|
||||
'/intl/icu/source/common/ubidiwrt.c',
|
||||
'/intl/icu/source/common/ubrk.cpp',
|
||||
'/intl/icu/source/common/ucase.cpp',
|
||||
'/intl/icu/source/common/ucasemap.cpp',
|
||||
'/intl/icu/source/common/ucasemap_titlecase_brkiter.cpp',
|
||||
'/intl/icu/source/common/ucat.cpp',
|
||||
'/intl/icu/source/common/uchar.cpp',
|
||||
'/intl/icu/source/common/ucat.c',
|
||||
'/intl/icu/source/common/uchar.c',
|
||||
'/intl/icu/source/common/ucharstrie.cpp',
|
||||
'/intl/icu/source/common/ucharstriebuilder.cpp',
|
||||
'/intl/icu/source/common/ucharstrieiterator.cpp',
|
||||
'/intl/icu/source/common/uchriter.cpp',
|
||||
'/intl/icu/source/common/ucln_cmn.cpp',
|
||||
'/intl/icu/source/common/ucmndata.cpp',
|
||||
'/intl/icu/source/common/ucnv.cpp',
|
||||
'/intl/icu/source/common/ucmndata.c',
|
||||
'/intl/icu/source/common/ucnv.c',
|
||||
'/intl/icu/source/common/ucnv2022.cpp',
|
||||
'/intl/icu/source/common/ucnv_bld.cpp',
|
||||
'/intl/icu/source/common/ucnv_cb.cpp',
|
||||
'/intl/icu/source/common/ucnv_cnv.cpp',
|
||||
'/intl/icu/source/common/ucnv_ct.cpp',
|
||||
'/intl/icu/source/common/ucnv_err.cpp',
|
||||
'/intl/icu/source/common/ucnv_cb.c',
|
||||
'/intl/icu/source/common/ucnv_cnv.c',
|
||||
'/intl/icu/source/common/ucnv_ct.c',
|
||||
'/intl/icu/source/common/ucnv_err.c',
|
||||
'/intl/icu/source/common/ucnv_ext.cpp',
|
||||
'/intl/icu/source/common/ucnv_io.cpp',
|
||||
'/intl/icu/source/common/ucnv_lmb.cpp',
|
||||
'/intl/icu/source/common/ucnv_set.cpp',
|
||||
'/intl/icu/source/common/ucnv_u16.cpp',
|
||||
'/intl/icu/source/common/ucnv_u32.cpp',
|
||||
'/intl/icu/source/common/ucnv_u7.cpp',
|
||||
'/intl/icu/source/common/ucnv_u8.cpp',
|
||||
'/intl/icu/source/common/ucnv_lmb.c',
|
||||
'/intl/icu/source/common/ucnv_set.c',
|
||||
'/intl/icu/source/common/ucnv_u16.c',
|
||||
'/intl/icu/source/common/ucnv_u32.c',
|
||||
'/intl/icu/source/common/ucnv_u7.c',
|
||||
'/intl/icu/source/common/ucnv_u8.c',
|
||||
'/intl/icu/source/common/ucnvbocu.cpp',
|
||||
'/intl/icu/source/common/ucnvdisp.cpp',
|
||||
'/intl/icu/source/common/ucnvhz.cpp',
|
||||
'/intl/icu/source/common/ucnvisci.cpp',
|
||||
'/intl/icu/source/common/ucnvlat1.cpp',
|
||||
'/intl/icu/source/common/ucnvdisp.c',
|
||||
'/intl/icu/source/common/ucnvhz.c',
|
||||
'/intl/icu/source/common/ucnvisci.c',
|
||||
'/intl/icu/source/common/ucnvlat1.c',
|
||||
'/intl/icu/source/common/ucnvmbcs.cpp',
|
||||
'/intl/icu/source/common/ucnvscsu.cpp',
|
||||
'/intl/icu/source/common/ucnvscsu.c',
|
||||
'/intl/icu/source/common/ucnvsel.cpp',
|
||||
'/intl/icu/source/common/ucol_swp.cpp',
|
||||
'/intl/icu/source/common/ucptrie.cpp',
|
||||
'/intl/icu/source/common/ucurr.cpp',
|
||||
'/intl/icu/source/common/udata.cpp',
|
||||
'/intl/icu/source/common/udatamem.cpp',
|
||||
'/intl/icu/source/common/udataswp.cpp',
|
||||
'/intl/icu/source/common/uenum.cpp',
|
||||
'/intl/icu/source/common/uhash.cpp',
|
||||
'/intl/icu/source/common/udatamem.c',
|
||||
'/intl/icu/source/common/udataswp.c',
|
||||
'/intl/icu/source/common/uenum.c',
|
||||
'/intl/icu/source/common/uhash.c',
|
||||
'/intl/icu/source/common/uhash_us.cpp',
|
||||
'/intl/icu/source/common/uidna.cpp',
|
||||
'/intl/icu/source/common/uinit.cpp',
|
||||
'/intl/icu/source/common/uinvchar.cpp',
|
||||
'/intl/icu/source/common/uinvchar.c',
|
||||
'/intl/icu/source/common/uiter.cpp',
|
||||
'/intl/icu/source/common/ulist.cpp',
|
||||
'/intl/icu/source/common/ulist.c',
|
||||
'/intl/icu/source/common/ulistformatter.cpp',
|
||||
'/intl/icu/source/common/uloc.cpp',
|
||||
'/intl/icu/source/common/uloc_keytype.cpp',
|
||||
'/intl/icu/source/common/uloc_tag.cpp',
|
||||
'/intl/icu/source/common/umapfile.cpp',
|
||||
'/intl/icu/source/common/umath.cpp',
|
||||
'/intl/icu/source/common/umutablecptrie.cpp',
|
||||
'/intl/icu/source/common/uloc_tag.c',
|
||||
'/intl/icu/source/common/umapfile.c',
|
||||
'/intl/icu/source/common/umath.c',
|
||||
'/intl/icu/source/common/umutex.cpp',
|
||||
'/intl/icu/source/common/unames.cpp',
|
||||
'/intl/icu/source/common/unifiedcache.cpp',
|
||||
@@ -153,11 +148,11 @@ SOURCES += [
|
||||
'/intl/icu/source/common/unormcmp.cpp',
|
||||
'/intl/icu/source/common/uobject.cpp',
|
||||
'/intl/icu/source/common/uprops.cpp',
|
||||
'/intl/icu/source/common/ures_cnv.cpp',
|
||||
'/intl/icu/source/common/ures_cnv.c',
|
||||
'/intl/icu/source/common/uresbund.cpp',
|
||||
'/intl/icu/source/common/uresdata.cpp',
|
||||
'/intl/icu/source/common/usc_impl.cpp',
|
||||
'/intl/icu/source/common/uscript.cpp',
|
||||
'/intl/icu/source/common/usc_impl.c',
|
||||
'/intl/icu/source/common/uscript.c',
|
||||
'/intl/icu/source/common/uscript_props.cpp',
|
||||
'/intl/icu/source/common/uset.cpp',
|
||||
'/intl/icu/source/common/uset_props.cpp',
|
||||
@@ -171,24 +166,23 @@ SOURCES += [
|
||||
'/intl/icu/source/common/ustrcase.cpp',
|
||||
'/intl/icu/source/common/ustrcase_locale.cpp',
|
||||
'/intl/icu/source/common/ustrenum.cpp',
|
||||
'/intl/icu/source/common/ustrfmt.cpp',
|
||||
'/intl/icu/source/common/ustrfmt.c',
|
||||
'/intl/icu/source/common/ustring.cpp',
|
||||
'/intl/icu/source/common/ustrtrns.cpp',
|
||||
'/intl/icu/source/common/utext.cpp',
|
||||
'/intl/icu/source/common/utf_impl.cpp',
|
||||
'/intl/icu/source/common/utf_impl.c',
|
||||
'/intl/icu/source/common/util.cpp',
|
||||
'/intl/icu/source/common/util_props.cpp',
|
||||
'/intl/icu/source/common/utrace.cpp',
|
||||
'/intl/icu/source/common/utrace.c',
|
||||
'/intl/icu/source/common/utrie.cpp',
|
||||
'/intl/icu/source/common/utrie2.cpp',
|
||||
'/intl/icu/source/common/utrie2_builder.cpp',
|
||||
'/intl/icu/source/common/utrie_swap.cpp',
|
||||
'/intl/icu/source/common/uts46.cpp',
|
||||
'/intl/icu/source/common/utypes.cpp',
|
||||
'/intl/icu/source/common/utypes.c',
|
||||
'/intl/icu/source/common/uvector.cpp',
|
||||
'/intl/icu/source/common/uvectr32.cpp',
|
||||
'/intl/icu/source/common/uvectr64.cpp',
|
||||
'/intl/icu/source/common/wintz.cpp',
|
||||
'/intl/icu/source/common/wintz.c',
|
||||
]
|
||||
|
||||
EXPORTS.unicode += [
|
||||
@@ -198,19 +192,17 @@ EXPORTS.unicode += [
|
||||
'/intl/icu/source/common/unicode/bytestrie.h',
|
||||
'/intl/icu/source/common/unicode/bytestriebuilder.h',
|
||||
'/intl/icu/source/common/unicode/caniter.h',
|
||||
'/intl/icu/source/common/unicode/casemap.h',
|
||||
'/intl/icu/source/common/unicode/char16ptr.h',
|
||||
'/intl/icu/source/common/unicode/chariter.h',
|
||||
'/intl/icu/source/common/unicode/dbbi.h',
|
||||
'/intl/icu/source/common/unicode/docmain.h',
|
||||
'/intl/icu/source/common/unicode/dtintrv.h',
|
||||
'/intl/icu/source/common/unicode/edits.h',
|
||||
'/intl/icu/source/common/unicode/enumset.h',
|
||||
'/intl/icu/source/common/unicode/errorcode.h',
|
||||
'/intl/icu/source/common/unicode/filteredbrk.h',
|
||||
'/intl/icu/source/common/unicode/icudataver.h',
|
||||
'/intl/icu/source/common/unicode/icuplug.h',
|
||||
'/intl/icu/source/common/unicode/idna.h',
|
||||
'/intl/icu/source/common/unicode/listformatter.h',
|
||||
'/intl/icu/source/common/unicode/localpointer.h',
|
||||
'/intl/icu/source/common/unicode/locdspnm.h',
|
||||
'/intl/icu/source/common/unicode/locid.h',
|
||||
@@ -229,7 +221,6 @@ EXPORTS.unicode += [
|
||||
'/intl/icu/source/common/unicode/simpleformatter.h',
|
||||
'/intl/icu/source/common/unicode/std_string.h',
|
||||
'/intl/icu/source/common/unicode/strenum.h',
|
||||
'/intl/icu/source/common/unicode/stringoptions.h',
|
||||
'/intl/icu/source/common/unicode/stringpiece.h',
|
||||
'/intl/icu/source/common/unicode/stringtriebuilder.h',
|
||||
'/intl/icu/source/common/unicode/symtable.h',
|
||||
@@ -248,8 +239,6 @@ EXPORTS.unicode += [
|
||||
'/intl/icu/source/common/unicode/ucnv_err.h',
|
||||
'/intl/icu/source/common/unicode/ucnvsel.h',
|
||||
'/intl/icu/source/common/unicode/uconfig.h',
|
||||
'/intl/icu/source/common/unicode/ucpmap.h',
|
||||
'/intl/icu/source/common/unicode/ucptrie.h',
|
||||
'/intl/icu/source/common/unicode/ucurr.h',
|
||||
'/intl/icu/source/common/unicode/udata.h',
|
||||
'/intl/icu/source/common/unicode/udisplaycontext.h',
|
||||
@@ -257,10 +246,10 @@ EXPORTS.unicode += [
|
||||
'/intl/icu/source/common/unicode/uidna.h',
|
||||
'/intl/icu/source/common/unicode/uiter.h',
|
||||
'/intl/icu/source/common/unicode/uldnames.h',
|
||||
'/intl/icu/source/common/unicode/ulistformatter.h',
|
||||
'/intl/icu/source/common/unicode/uloc.h',
|
||||
'/intl/icu/source/common/unicode/umachine.h',
|
||||
'/intl/icu/source/common/unicode/umisc.h',
|
||||
'/intl/icu/source/common/unicode/umutablecptrie.h',
|
||||
'/intl/icu/source/common/unicode/unifilt.h',
|
||||
'/intl/icu/source/common/unicode/unifunct.h',
|
||||
'/intl/icu/source/common/unicode/unimatch.h',
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
Vendored
+1
@@ -14,6 +14,7 @@ DEFINES.update(
|
||||
UCONFIG_NO_LEGACY_CONVERSION = True,
|
||||
UCONFIG_NO_TRANSLITERATION = True,
|
||||
UCONFIG_NO_REGULAR_EXPRESSIONS = True,
|
||||
UCONFIG_NO_BREAK_ITERATION = True,
|
||||
|
||||
# We don't need to pass data to and from legacy char* APIs.
|
||||
U_CHARSET_IS_UTF8 = True,
|
||||
|
||||
+19
-57
@@ -1,5 +1,6 @@
|
||||
# THIS FILE IS GENERATED BY /intl/icu_sources_data.py DO NOT EDIT
|
||||
SOURCES += [
|
||||
'/intl/icu/source/i18n/affixpatternparser.cpp',
|
||||
'/intl/icu/source/i18n/alphaindex.cpp',
|
||||
'/intl/icu/source/i18n/anytrans.cpp',
|
||||
'/intl/icu/source/i18n/astro.cpp',
|
||||
@@ -52,22 +53,23 @@ SOURCES += [
|
||||
'/intl/icu/source/i18n/datefmt.cpp',
|
||||
'/intl/icu/source/i18n/dayperiodrules.cpp',
|
||||
'/intl/icu/source/i18n/dcfmtsym.cpp',
|
||||
'/intl/icu/source/i18n/decContext.cpp',
|
||||
'/intl/icu/source/i18n/decContext.c',
|
||||
'/intl/icu/source/i18n/decfmtst.cpp',
|
||||
'/intl/icu/source/i18n/decimalformatpattern.cpp',
|
||||
'/intl/icu/source/i18n/decimfmt.cpp',
|
||||
'/intl/icu/source/i18n/decNumber.cpp',
|
||||
'/intl/icu/source/i18n/double-conversion-bignum-dtoa.cpp',
|
||||
'/intl/icu/source/i18n/double-conversion-bignum.cpp',
|
||||
'/intl/icu/source/i18n/double-conversion-cached-powers.cpp',
|
||||
'/intl/icu/source/i18n/double-conversion-diy-fp.cpp',
|
||||
'/intl/icu/source/i18n/double-conversion-fast-dtoa.cpp',
|
||||
'/intl/icu/source/i18n/double-conversion-strtod.cpp',
|
||||
'/intl/icu/source/i18n/double-conversion.cpp',
|
||||
'/intl/icu/source/i18n/decimfmtimpl.cpp',
|
||||
'/intl/icu/source/i18n/decNumber.c',
|
||||
'/intl/icu/source/i18n/digitaffix.cpp',
|
||||
'/intl/icu/source/i18n/digitaffixesandpadding.cpp',
|
||||
'/intl/icu/source/i18n/digitformatter.cpp',
|
||||
'/intl/icu/source/i18n/digitgrouping.cpp',
|
||||
'/intl/icu/source/i18n/digitinterval.cpp',
|
||||
'/intl/icu/source/i18n/digitlst.cpp',
|
||||
'/intl/icu/source/i18n/dtfmtsym.cpp',
|
||||
'/intl/icu/source/i18n/dtitvfmt.cpp',
|
||||
'/intl/icu/source/i18n/dtitvinf.cpp',
|
||||
'/intl/icu/source/i18n/dtptngen.cpp',
|
||||
'/intl/icu/source/i18n/dtrule.cpp',
|
||||
'/intl/icu/source/i18n/erarules.cpp',
|
||||
'/intl/icu/source/i18n/esctrn.cpp',
|
||||
'/intl/icu/source/i18n/ethpccal.cpp',
|
||||
'/intl/icu/source/i18n/fmtable.cpp',
|
||||
@@ -84,7 +86,6 @@ SOURCES += [
|
||||
'/intl/icu/source/i18n/inputext.cpp',
|
||||
'/intl/icu/source/i18n/islamcal.cpp',
|
||||
'/intl/icu/source/i18n/japancal.cpp',
|
||||
'/intl/icu/source/i18n/listformatter.cpp',
|
||||
'/intl/icu/source/i18n/measfmt.cpp',
|
||||
'/intl/icu/source/i18n/measunit.cpp',
|
||||
'/intl/icu/source/i18n/measure.cpp',
|
||||
@@ -94,50 +95,15 @@ SOURCES += [
|
||||
'/intl/icu/source/i18n/nfrule.cpp',
|
||||
'/intl/icu/source/i18n/nfsubs.cpp',
|
||||
'/intl/icu/source/i18n/nortrans.cpp',
|
||||
'/intl/icu/source/i18n/nounit.cpp',
|
||||
'/intl/icu/source/i18n/nultrans.cpp',
|
||||
'/intl/icu/source/i18n/number_affixutils.cpp',
|
||||
'/intl/icu/source/i18n/number_asformat.cpp',
|
||||
'/intl/icu/source/i18n/number_capi.cpp',
|
||||
'/intl/icu/source/i18n/number_compact.cpp',
|
||||
'/intl/icu/source/i18n/number_currencysymbols.cpp',
|
||||
'/intl/icu/source/i18n/number_decimalquantity.cpp',
|
||||
'/intl/icu/source/i18n/number_decimfmtprops.cpp',
|
||||
'/intl/icu/source/i18n/number_fluent.cpp',
|
||||
'/intl/icu/source/i18n/number_formatimpl.cpp',
|
||||
'/intl/icu/source/i18n/number_grouping.cpp',
|
||||
'/intl/icu/source/i18n/number_integerwidth.cpp',
|
||||
'/intl/icu/source/i18n/number_longnames.cpp',
|
||||
'/intl/icu/source/i18n/number_mapper.cpp',
|
||||
'/intl/icu/source/i18n/number_modifiers.cpp',
|
||||
'/intl/icu/source/i18n/number_multiplier.cpp',
|
||||
'/intl/icu/source/i18n/number_notation.cpp',
|
||||
'/intl/icu/source/i18n/number_padding.cpp',
|
||||
'/intl/icu/source/i18n/number_patternmodifier.cpp',
|
||||
'/intl/icu/source/i18n/number_patternstring.cpp',
|
||||
'/intl/icu/source/i18n/number_rounding.cpp',
|
||||
'/intl/icu/source/i18n/number_scientific.cpp',
|
||||
'/intl/icu/source/i18n/number_skeletons.cpp',
|
||||
'/intl/icu/source/i18n/number_stringbuilder.cpp',
|
||||
'/intl/icu/source/i18n/number_utils.cpp',
|
||||
'/intl/icu/source/i18n/numfmt.cpp',
|
||||
'/intl/icu/source/i18n/numparse_affixes.cpp',
|
||||
'/intl/icu/source/i18n/numparse_compositions.cpp',
|
||||
'/intl/icu/source/i18n/numparse_currency.cpp',
|
||||
'/intl/icu/source/i18n/numparse_decimal.cpp',
|
||||
'/intl/icu/source/i18n/numparse_impl.cpp',
|
||||
'/intl/icu/source/i18n/numparse_parsednumber.cpp',
|
||||
'/intl/icu/source/i18n/numparse_scientific.cpp',
|
||||
'/intl/icu/source/i18n/numparse_stringsegment.cpp',
|
||||
'/intl/icu/source/i18n/numparse_symbols.cpp',
|
||||
'/intl/icu/source/i18n/numparse_validators.cpp',
|
||||
'/intl/icu/source/i18n/numrange_fluent.cpp',
|
||||
'/intl/icu/source/i18n/numrange_impl.cpp',
|
||||
'/intl/icu/source/i18n/numsys.cpp',
|
||||
'/intl/icu/source/i18n/olsontz.cpp',
|
||||
'/intl/icu/source/i18n/persncal.cpp',
|
||||
'/intl/icu/source/i18n/pluralaffix.cpp',
|
||||
'/intl/icu/source/i18n/plurfmt.cpp',
|
||||
'/intl/icu/source/i18n/plurrule.cpp',
|
||||
'/intl/icu/source/i18n/precision.cpp',
|
||||
'/intl/icu/source/i18n/quant.cpp',
|
||||
'/intl/icu/source/i18n/quantityformatter.cpp',
|
||||
'/intl/icu/source/i18n/rbnf.cpp',
|
||||
@@ -164,6 +130,7 @@ SOURCES += [
|
||||
'/intl/icu/source/i18n/selfmt.cpp',
|
||||
'/intl/icu/source/i18n/sharedbreakiterator.cpp',
|
||||
'/intl/icu/source/i18n/simpletz.cpp',
|
||||
'/intl/icu/source/i18n/smallintformatter.cpp',
|
||||
'/intl/icu/source/i18n/smpdtfmt.cpp',
|
||||
'/intl/icu/source/i18n/smpdtfst.cpp',
|
||||
'/intl/icu/source/i18n/sortkey.cpp',
|
||||
@@ -200,8 +167,7 @@ SOURCES += [
|
||||
'/intl/icu/source/i18n/udatpg.cpp',
|
||||
'/intl/icu/source/i18n/ufieldpositer.cpp',
|
||||
'/intl/icu/source/i18n/uitercollationiterator.cpp',
|
||||
'/intl/icu/source/i18n/ulistformatter.cpp',
|
||||
'/intl/icu/source/i18n/ulocdata.cpp',
|
||||
'/intl/icu/source/i18n/ulocdata.c',
|
||||
'/intl/icu/source/i18n/umsg.cpp',
|
||||
'/intl/icu/source/i18n/unesctrn.cpp',
|
||||
'/intl/icu/source/i18n/uni2name.cpp',
|
||||
@@ -218,8 +184,10 @@ SOURCES += [
|
||||
'/intl/icu/source/i18n/uspoof_impl.cpp',
|
||||
'/intl/icu/source/i18n/utf16collationiterator.cpp',
|
||||
'/intl/icu/source/i18n/utf8collationiterator.cpp',
|
||||
'/intl/icu/source/i18n/utmscale.cpp',
|
||||
'/intl/icu/source/i18n/utmscale.c',
|
||||
'/intl/icu/source/i18n/utrans.cpp',
|
||||
'/intl/icu/source/i18n/valueformatter.cpp',
|
||||
'/intl/icu/source/i18n/visibledigits.cpp',
|
||||
'/intl/icu/source/i18n/vtzone.cpp',
|
||||
'/intl/icu/source/i18n/vzone.cpp',
|
||||
'/intl/icu/source/i18n/windtfmt.cpp',
|
||||
@@ -255,14 +223,10 @@ EXPORTS.unicode += [
|
||||
'/intl/icu/source/i18n/unicode/fpositer.h',
|
||||
'/intl/icu/source/i18n/unicode/gender.h',
|
||||
'/intl/icu/source/i18n/unicode/gregocal.h',
|
||||
'/intl/icu/source/i18n/unicode/listformatter.h',
|
||||
'/intl/icu/source/i18n/unicode/measfmt.h',
|
||||
'/intl/icu/source/i18n/unicode/measunit.h',
|
||||
'/intl/icu/source/i18n/unicode/measure.h',
|
||||
'/intl/icu/source/i18n/unicode/msgfmt.h',
|
||||
'/intl/icu/source/i18n/unicode/nounit.h',
|
||||
'/intl/icu/source/i18n/unicode/numberformatter.h',
|
||||
'/intl/icu/source/i18n/unicode/numberrangeformatter.h',
|
||||
'/intl/icu/source/i18n/unicode/numfmt.h',
|
||||
'/intl/icu/source/i18n/unicode/numsys.h',
|
||||
'/intl/icu/source/i18n/unicode/plurfmt.h',
|
||||
@@ -299,12 +263,10 @@ EXPORTS.unicode += [
|
||||
'/intl/icu/source/i18n/unicode/ufieldpositer.h',
|
||||
'/intl/icu/source/i18n/unicode/uformattable.h',
|
||||
'/intl/icu/source/i18n/unicode/ugender.h',
|
||||
'/intl/icu/source/i18n/unicode/ulistformatter.h',
|
||||
'/intl/icu/source/i18n/unicode/ulocdata.h',
|
||||
'/intl/icu/source/i18n/unicode/umsg.h',
|
||||
'/intl/icu/source/i18n/unicode/unirepl.h',
|
||||
'/intl/icu/source/i18n/unicode/unum.h',
|
||||
'/intl/icu/source/i18n/unicode/unumberformatter.h',
|
||||
'/intl/icu/source/i18n/unicode/unumsys.h',
|
||||
'/intl/icu/source/i18n/unicode/upluralrules.h',
|
||||
'/intl/icu/source/i18n/unicode/uregex.h',
|
||||
|
||||
Vendored
+2
-9
@@ -3,6 +3,8 @@
|
||||
# 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/.
|
||||
|
||||
Library('icu')
|
||||
|
||||
DIRS += [
|
||||
'common',
|
||||
'data',
|
||||
@@ -12,14 +14,5 @@ DIRS += [
|
||||
if CONFIG['MOZ_ICU_DATA_ARCHIVE']:
|
||||
DIRS += ['stubdata']
|
||||
USE_LIBS += ['icustubdata']
|
||||
Library('icu')
|
||||
else:
|
||||
USE_LIBS += ['icudata']
|
||||
SharedLibrary('icu')
|
||||
SHARED_LIBRARY_NAME = 'icu' + CONFIG['MOZ_ICU_VERSION']
|
||||
# Linking ICU gets too spammy in warnings with MSVC
|
||||
if CONFIG['_MSC_VER'] and not CONFIG['CLANG_CL']:
|
||||
LDFLAGS += [
|
||||
'/IGNORE:4217', # symbol defined in $1.obj is defined in $2.obj
|
||||
'/IGNORE:4286', # similar with LNK4217
|
||||
]
|
||||
+1
-1
@@ -9,4 +9,4 @@
|
||||
|
||||
Library('icustubdata')
|
||||
|
||||
SOURCES += ['/intl/icu/source/stubdata/stubdata.cpp']
|
||||
SOURCES += ['/intl/icu/source/stubdata/stubdata.c']
|
||||
Vendored
-3
@@ -41,9 +41,6 @@ if CONFIG['CPU_ARCH'] == 'arm':
|
||||
if CONFIG['MOZ_FFVPX']:
|
||||
external_dirs += ['media/ffvpx']
|
||||
|
||||
if CONFIG["MOZ_JXL"]:
|
||||
external_dirs += ["media/libjxl", "media/highway"]
|
||||
|
||||
external_dirs += [
|
||||
'media/kiss_fft',
|
||||
'media/libcubeb',
|
||||
|
||||
+20
-8
@@ -10,12 +10,13 @@
|
||||
# things happening at each step required other things happening in previous
|
||||
# steps without any documentation of those dependencies.
|
||||
#
|
||||
# This build system establishes what files or operations are needed for the
|
||||
# build, and applying the necessary rules to have those in place, relying on
|
||||
# make dependencies to get them going.
|
||||
# This new build system tries to start afresh by establishing what files or
|
||||
# operations are needed for the build, and applying the necessary rules to
|
||||
# have those in place, relying on make dependencies to get them going.
|
||||
#
|
||||
# Only non-compiled parts of the application and platform are built and
|
||||
# supported here (a few other things are also left out).
|
||||
# As of writing, only building non-compiled parts of Firefox is supported
|
||||
# here (a few other things are also left out). This is a starting point, with
|
||||
# the intent to grow this build system to make it more complete.
|
||||
#
|
||||
# This file contains rules and dependencies to get things working. The intent
|
||||
# is for a Makefile to define some dependencies and variables, and include
|
||||
@@ -41,11 +42,19 @@ ifndef NO_XPIDL
|
||||
default: $(TOPOBJDIR)/config/makefiles/xpidl/xpidl
|
||||
endif
|
||||
|
||||
# Mac builds require copying files in dist/bin/*.app
|
||||
# Mac builds require to copy things in dist/bin/*.app
|
||||
# TODO: remove the MOZ_WIDGET_TOOLKIT and MOZ_BUILD_APP variables from
|
||||
# faster/Makefile and python/mozbuild/mozbuild/test/backend/test_build.py
|
||||
# when this is not required anymore.
|
||||
# We however don't need to do this when using the hybrid
|
||||
# FasterMake/RecursiveMake backend (FASTER_RECURSIVE_MAKE is set when
|
||||
# recursing from the RecursiveMake backend)
|
||||
ifndef FASTER_RECURSIVE_MAKE
|
||||
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
|
||||
default:
|
||||
$(MAKE) -C $(TOPOBJDIR)/$(MOZ_BUILD_APP)/app repackage
|
||||
endif
|
||||
endif
|
||||
|
||||
.PHONY: FORCE
|
||||
|
||||
@@ -90,9 +99,12 @@ $(addprefix install-,$(INSTALL_MANIFESTS)): install-%: $(addprefix $(TOPOBJDIR)/
|
||||
# that are not supported by data in moz.build.
|
||||
|
||||
# The xpidl target in config/makefiles/xpidl requires the install manifest for
|
||||
# dist/idl to have been processed.
|
||||
# dist/idl to have been processed. When using the hybrid
|
||||
# FasterMake/RecursiveMake backend, this dependency is handled in the top-level
|
||||
# Makefile.
|
||||
ifndef FASTER_RECURSIVE_MAKE
|
||||
$(TOPOBJDIR)/config/makefiles/xpidl/xpidl: $(TOPOBJDIR)/install-dist_idl
|
||||
|
||||
endif
|
||||
# It also requires all the install manifests for dist/bin to have been processed
|
||||
# because it adds interfaces.manifest references with buildlist.py.
|
||||
$(TOPOBJDIR)/config/makefiles/xpidl/xpidl: $(addprefix install-,$(filter dist/bin%,$(INSTALL_MANIFESTS)))
|
||||
@@ -8,4 +8,4 @@
|
||||
# Referenced by milestone.py.
|
||||
#--------------------------------------------------------
|
||||
|
||||
6.1.0
|
||||
5.1.0+
|
||||
@@ -19,6 +19,12 @@
|
||||
# define MOZ_INCLUDE_MOZALLOC_H_FROM_${HEADER}
|
||||
#endif
|
||||
|
||||
// Code built with !_HAS_EXCEPTIONS calls std::_Throw(), but the win2k
|
||||
// CRT doesn't export std::_Throw(). So we define it.
|
||||
#ifndef mozilla_Throw_h
|
||||
# include "mozilla/throw_msvc.h"
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
// From
|
||||
// http://msdn.microsoft.com/en-us/library/aa985982%28VS.80%29.aspx
|
||||
|
||||
@@ -810,7 +810,6 @@ sym.h
|
||||
synch.h
|
||||
syncmgr.h
|
||||
sys/atomic_op.h
|
||||
sys/auxv.h
|
||||
sys/bitypes.h
|
||||
sys/byteorder.h
|
||||
syscall.h
|
||||
|
||||
@@ -26,19 +26,16 @@
|
||||
key="&closeCmd.key;"
|
||||
command="toolbox-cmd-close"
|
||||
modifiers="accel"/>
|
||||
#ifdef XP_MACOSX
|
||||
<key id="toolbox-key-toggle-osx"
|
||||
key="&toggleToolbox.key;"
|
||||
command="toolbox-cmd-close"
|
||||
modifiers="accel,alt"
|
||||
disabled="true"/>
|
||||
#else
|
||||
<key id="toolbox-key-toggle"
|
||||
key="&toggleToolbox.key;"
|
||||
command="toolbox-cmd-close"
|
||||
modifiers="accel,shift"
|
||||
disabled="true"/>
|
||||
#endif
|
||||
<key id="toolbox-key-toggle-osx"
|
||||
key="&toggleToolbox.key;"
|
||||
command="toolbox-cmd-close"
|
||||
modifiers="accel,alt"
|
||||
disabled="true"/>
|
||||
<key id="toolbox-key-toggle-F12"
|
||||
keycode="&toggleToolboxF12.keycode;"
|
||||
keytext="&toggleToolboxF12.keytext;"
|
||||
|
||||
@@ -25,8 +25,10 @@
|
||||
<script>
|
||||
"use strict";
|
||||
var host = document.querySelector("#shadow");
|
||||
var root = host.attachShadow({ mode: "open" });
|
||||
root.innerHTML = "<h3>Shadow DOM</h3><select multiple></select>";
|
||||
if (host.createShadowRoot) {
|
||||
var root = host.createShadowRoot();
|
||||
root.innerHTML = "<h3>Shadow DOM</h3><select multiple></select>";
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -20,11 +20,6 @@
|
||||
* code by having a tag called "padding" and a property
|
||||
* value called "margin".
|
||||
*/
|
||||
|
||||
const { PrefObserver } = require("devtools/client/shared/prefs");
|
||||
const PREF_ENABLE_MDN_DOCS_TOOLTIP =
|
||||
"devtools.inspector.mdnDocsTooltip.enabled";
|
||||
|
||||
const TEST_URI = `
|
||||
<html>
|
||||
<head>
|
||||
@@ -40,50 +35,12 @@ const TEST_URI = `
|
||||
`;
|
||||
|
||||
add_task(function* () {
|
||||
info("Ensure the pref is true to begin with");
|
||||
let initial = Services.prefs.getBoolPref(PREF_ENABLE_MDN_DOCS_TOOLTIP);
|
||||
if (initial != true) {
|
||||
yield setBooleanPref(PREF_ENABLE_MDN_DOCS_TOOLTIP, true);
|
||||
}
|
||||
|
||||
yield addTab("data:text/html;charset=utf8," + encodeURIComponent(TEST_URI));
|
||||
let {inspector, view} = yield openRuleView();
|
||||
yield selectNode("padding", inspector);
|
||||
yield testMdnContextMenuItemVisibility(view);
|
||||
|
||||
info("Ensure the pref is reset to its initial value");
|
||||
let eventual = Services.prefs.getBoolPref(PREF_ENABLE_MDN_DOCS_TOOLTIP);
|
||||
if (eventual != initial) {
|
||||
yield setBooleanPref(PREF_ENABLE_MDN_DOCS_TOOLTIP, initial);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Set a boolean pref, and wait for the pref observer to
|
||||
* trigger, so that code listening for the pref change
|
||||
* has had a chance to update itself.
|
||||
*
|
||||
* @param pref {string} Name of the pref to change
|
||||
* @param state {boolean} Desired value of the pref.
|
||||
*
|
||||
* Note that if the pref already has the value in `state`,
|
||||
* then the prefObserver will not trigger. So you should only
|
||||
* call this function if you know the pref's current value is
|
||||
* not `state`.
|
||||
*/
|
||||
function* setBooleanPref(pref, state) {
|
||||
let oncePrefChanged = defer();
|
||||
let prefObserver = new PrefObserver("devtools.");
|
||||
prefObserver.on(pref, oncePrefChanged.resolve);
|
||||
|
||||
info("Set the pref " + pref + " to: " + state);
|
||||
Services.prefs.setBoolPref(pref, state);
|
||||
|
||||
info("Wait for prefObserver to call back so the UI can update");
|
||||
yield oncePrefChanged.promise;
|
||||
prefObserver.off(pref, oncePrefChanged.resolve);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the MDN context menu item is shown when it should be,
|
||||
* and hidden when it should be.
|
||||
|
||||
@@ -32,7 +32,7 @@ add_task(function* () {
|
||||
info("Ensure the pref is true to begin with");
|
||||
let initial = Services.prefs.getBoolPref(PREF_ENABLE_MDN_DOCS_TOOLTIP);
|
||||
if (initial != true) {
|
||||
yield setBooleanPref(PREF_ENABLE_MDN_DOCS_TOOLTIP, true);
|
||||
setBooleanPref(PREF_ENABLE_MDN_DOCS_TOOLTIP, true);
|
||||
}
|
||||
|
||||
yield addTab("data:text/html;charset=utf8," + encodeURIComponent(TEST_DOC));
|
||||
@@ -58,7 +58,7 @@ add_task(function* () {
|
||||
info("Ensure the pref is reset to its initial value");
|
||||
let eventual = Services.prefs.getBoolPref(PREF_ENABLE_MDN_DOCS_TOOLTIP);
|
||||
if (eventual != initial) {
|
||||
yield setBooleanPref(PREF_ENABLE_MDN_DOCS_TOOLTIP, initial);
|
||||
setBooleanPref(PREF_ENABLE_MDN_DOCS_TOOLTIP, initial);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ devtools.jar:
|
||||
content/commandline/commandline.css (commandline/commandline.css)
|
||||
content/commandline/commandlineoutput.xhtml (commandline/commandlineoutput.xhtml)
|
||||
content/commandline/commandlinetooltip.xhtml (commandline/commandlinetooltip.xhtml)
|
||||
* content/framework/toolbox-window.xul (framework/toolbox-window.xul)
|
||||
content/framework/toolbox-window.xul (framework/toolbox-window.xul)
|
||||
content/framework/toolbox-options.xhtml (framework/toolbox-options.xhtml)
|
||||
content/framework/toolbox.xul (framework/toolbox.xul)
|
||||
content/framework/toolbox-init.js (framework/toolbox-init.js)
|
||||
|
||||
@@ -59,7 +59,7 @@ pref("devtools.inspector.showUserAgentStyles", false);
|
||||
// Show all native anonymous content (like controls in <video> tags)
|
||||
pref("devtools.inspector.showAllAnonymousContent", false);
|
||||
// Enable the MDN docs tooltip
|
||||
pref("devtools.inspector.mdnDocsTooltip.enabled", false);
|
||||
pref("devtools.inspector.mdnDocsTooltip.enabled", true);
|
||||
|
||||
// Enable the Font Inspector
|
||||
pref("devtools.fontinspector.enabled", true);
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
.tabs .all-tabs-menu {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
inset-inline-end: 0;
|
||||
offset-inline-end: 0;
|
||||
width: 15px;
|
||||
height: 100%;
|
||||
border-inline-start: 1px solid var(--theme-splitter-color);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* Copyright (C) 2008, 2009 Anthony Ricaud <rik@webkit.org>
|
||||
* Copyright (C) 2011 Google Inc. All rights reserved.
|
||||
* Copyright (C) 2009 Mozilla Foundation. All rights reserved.
|
||||
* Copyright (C) 2022, 2023 Moonchild Productions. All rights reserved.
|
||||
* Copyright (C) 2022 Moonchild Productions. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -138,8 +138,7 @@ const Curl = {
|
||||
for (let i = 0; i < headers.length; i++) {
|
||||
let header = headers[i];
|
||||
if (header.name.toLowerCase() === "accept-encoding") {
|
||||
// Ignore transfer encoding (compression) as not all commonly installed
|
||||
// versions of curl support this.
|
||||
addParam("--compressed");
|
||||
continue;
|
||||
}
|
||||
if (ignoredHeaders.has(header.name.toLowerCase())) {
|
||||
@@ -398,55 +397,41 @@ const CurlUtils = {
|
||||
|
||||
/**
|
||||
* Escape util function for Windows systems.
|
||||
* Credit: Google DevTools
|
||||
*/
|
||||
escapeStringWin: function (str) {
|
||||
/*
|
||||
Because the cmd.exe parser and the MS Crt arguments parsers use some
|
||||
of the same escape characters, they can interact with each other in
|
||||
terrible ways, meaning the order of operations is critical here.
|
||||
Replace the backtick character ` with `` in order to escape it.
|
||||
The backtick character is an escape character in PowerShell and
|
||||
can, among other things, be used to disable the effect of some
|
||||
of the other escapes created below.
|
||||
|
||||
1. Replace \ with \\ first, because it is an escape character for
|
||||
certain conditions in both parsers.
|
||||
|
||||
2. Replace double quote chars with two double quotes (not by escaping
|
||||
with \") because it is recognized by both the cmd.exe and MS Crt
|
||||
arguments parsers.
|
||||
Replace dollar sign because of commands in powershell when using
|
||||
double quotes. e.g $(calc.exe).
|
||||
|
||||
3. Escape ` and $ so commands do not get executed, e.g $(calc.exe) or
|
||||
`\$(calc.exe)
|
||||
|
||||
4. Escape all characters we are not sure about with ^, to ensure it
|
||||
gets to the MS Crt arguments parser safely.
|
||||
Also see http://www.rlmueller.net/PowerShellEscape.htm for details.
|
||||
|
||||
5. The % character is special because the MS Crt arguments parser will
|
||||
try and look for environment variables and fill them in, in-place. We
|
||||
cannot escape them with % and cannot escape them with ^ (because it's
|
||||
cmd.exe's escape, not the MS Crt arguments parser). So, we can get the
|
||||
cmd.exe parser to escape the character after it, if it is followed by
|
||||
a valid starting character of an environment variable.
|
||||
This ensures we do not try and double-escape another ^ if it was placed
|
||||
by the previous replace.
|
||||
Replace quote by double quote (but not by \") because it is
|
||||
recognized by both cmd.exe and MS Crt arguments parser.
|
||||
|
||||
6. We replace \r and \r\n with \n; this allows us to consistently
|
||||
escape all new lines in the next replace.
|
||||
Replace % by "%" because it could be expanded to an environment
|
||||
variable value. So %% becomes "%""%". Even if an env variable ""
|
||||
(2 doublequotes) is declared, the cmd.exe will not
|
||||
substitute it with its value.
|
||||
|
||||
7. Lastly, we replace new lines with ^ and TWO new lines, because the
|
||||
first new line is there to enact the escape command, and the second is
|
||||
the character to escape (in this case new line).
|
||||
The extra " enables escaping new lines with ^ within quotes in cmd.exe.
|
||||
Replace each backslash with double backslash to make sure
|
||||
MS Crt arguments parser won't collapse them.
|
||||
|
||||
Replace new line outside of quotes since cmd.exe doesn't let
|
||||
us do it inside.
|
||||
*/
|
||||
const encapsChars = '"';
|
||||
return (
|
||||
encapsChars +
|
||||
str
|
||||
.replace(/\\/g, "\\\\")
|
||||
.replace(/"/g, '""')
|
||||
.replace(/[`$]/g, "\\$&")
|
||||
.replace(/[^a-zA-Z0-9\s_\-:=+~\/.',?;()*\$&\\{}\"`]/g, "^$&")
|
||||
.replace(/%(?=[a-zA-Z0-9_])/g, "%^")
|
||||
.replace(/\r\n?/g, "\n")
|
||||
.replace(/\n/g, '"^\r\n\r\n"')
|
||||
+ encapsChars);
|
||||
return "\"" +
|
||||
str.replaceAll("`", "``")
|
||||
.replaceAll("$", "`$")
|
||||
.replaceAll('"', '""')
|
||||
.replaceAll("%", '"%"')
|
||||
.replace(/\\/g, "\\\\")
|
||||
.replace(/[\r\n]+/g, "\"^$&\"") + "\"";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1032,7 +1032,7 @@ OutputPanel.prototype._resize = function () {
|
||||
break;
|
||||
}
|
||||
|
||||
this.document.body.style.width = "max-content";
|
||||
this.document.body.style.width = "-moz-max-content";
|
||||
let style = this._frame.contentWindow.getComputedStyle(this.document.body);
|
||||
let frameWidth = parseInt(style.width, 10);
|
||||
let width = Math.min(maxWidth, frameWidth);
|
||||
|
||||
@@ -652,7 +652,7 @@ checkbox:-moz-focusring {
|
||||
.devtools-searchinput-clear {
|
||||
position: absolute;
|
||||
top: 3.5px;
|
||||
inset-inline-end: 7px;
|
||||
offset-inline-end: 7px;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
width: 16px;
|
||||
|
||||
@@ -216,7 +216,7 @@
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 1px;
|
||||
inset-inline-start: 0;
|
||||
offset-inline-start: 0;
|
||||
width: 12px;
|
||||
height: 22px;
|
||||
background-repeat: no-repeat;
|
||||
|
||||
@@ -521,8 +521,8 @@
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
position: absolute;
|
||||
inset-inline-start: 3px;
|
||||
inset-block-start: 3px;
|
||||
offset-inline-start: 3px;
|
||||
offset-block-start: 3px;
|
||||
box-shadow: 0px 0px 0px black;
|
||||
border: solid 1px #fff;
|
||||
}
|
||||
|
||||
@@ -1462,9 +1462,7 @@ DebuggerServerConnection.prototype = {
|
||||
},
|
||||
|
||||
send(packet) {
|
||||
if (this.transport) {
|
||||
this.transport.send(packet);
|
||||
}
|
||||
this.transport.send(packet);
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
|
||||
// Set up a basic shadow DOM
|
||||
var host = document.querySelector('#shadow');
|
||||
if (host.attachShadow) {
|
||||
let root = host.attachShadow({ mode: "open" });
|
||||
if (host.createShadowRoot) {
|
||||
var root = host.createShadowRoot();
|
||||
root.innerHTML = '<h3>Shadow <em>DOM</em></h3><select multiple></select>';
|
||||
}
|
||||
|
||||
|
||||
@@ -2209,13 +2209,13 @@ exports.CSS_PROPERTIES = {
|
||||
"-moz-available",
|
||||
"-moz-calc",
|
||||
"-moz-fit-content",
|
||||
"-moz-max-content",
|
||||
"-moz-min-content",
|
||||
"auto",
|
||||
"calc",
|
||||
"content",
|
||||
"inherit",
|
||||
"initial",
|
||||
"max-content",
|
||||
"min-content",
|
||||
"unset"
|
||||
]
|
||||
},
|
||||
@@ -2232,13 +2232,13 @@ exports.CSS_PROPERTIES = {
|
||||
"-moz-available",
|
||||
"-moz-calc",
|
||||
"-moz-fit-content",
|
||||
"-moz-max-content",
|
||||
"-moz-min-content",
|
||||
"auto",
|
||||
"calc",
|
||||
"content",
|
||||
"inherit",
|
||||
"initial",
|
||||
"max-content",
|
||||
"min-content",
|
||||
"unset"
|
||||
]
|
||||
},
|
||||
@@ -3144,10 +3144,10 @@ exports.CSS_PROPERTIES = {
|
||||
"mix-blend-mode",
|
||||
"object-fit",
|
||||
"object-position",
|
||||
"inset-block-end",
|
||||
"inset-block-start",
|
||||
"inset-inline-end",
|
||||
"inset-inline-start",
|
||||
"offset-block-end",
|
||||
"offset-block-start",
|
||||
"offset-inline-end",
|
||||
"offset-inline-start",
|
||||
"opacity",
|
||||
"order",
|
||||
"-moz-orient",
|
||||
@@ -3304,7 +3304,9 @@ exports.CSS_PROPERTIES = {
|
||||
"-moz-mac-source-list-selection",
|
||||
"-moz-mac-vibrancy-dark",
|
||||
"-moz-mac-vibrancy-light",
|
||||
"-moz-max-content",
|
||||
"-moz-middle-with-baseline",
|
||||
"-moz-min-content",
|
||||
"-moz-none",
|
||||
"-moz-popup",
|
||||
"-moz-pre-space",
|
||||
@@ -3360,7 +3362,6 @@ exports.CSS_PROPERTIES = {
|
||||
"bottom",
|
||||
"bottom-outside",
|
||||
"break-all",
|
||||
"break-spaces",
|
||||
"break-word",
|
||||
"butt",
|
||||
"button",
|
||||
@@ -3492,7 +3493,6 @@ exports.CSS_PROPERTIES = {
|
||||
"margin-box",
|
||||
"match-source",
|
||||
"mathematical",
|
||||
"max-content",
|
||||
"medium",
|
||||
"menuarrow",
|
||||
"menubar",
|
||||
@@ -3510,7 +3510,6 @@ exports.CSS_PROPERTIES = {
|
||||
"meterbar",
|
||||
"meterchunk",
|
||||
"middle",
|
||||
"min-content",
|
||||
"miter",
|
||||
"mixed",
|
||||
"multiply",
|
||||
@@ -6001,13 +6000,13 @@ exports.CSS_PROPERTIES = {
|
||||
"-moz-available",
|
||||
"-moz-calc",
|
||||
"-moz-fit-content",
|
||||
"-moz-max-content",
|
||||
"-moz-min-content",
|
||||
"auto",
|
||||
"calc",
|
||||
"content",
|
||||
"inherit",
|
||||
"initial",
|
||||
"max-content",
|
||||
"min-content",
|
||||
"unset"
|
||||
]
|
||||
},
|
||||
@@ -6024,13 +6023,13 @@ exports.CSS_PROPERTIES = {
|
||||
"-moz-available",
|
||||
"-moz-calc",
|
||||
"-moz-fit-content",
|
||||
"-moz-max-content",
|
||||
"-moz-min-content",
|
||||
"auto",
|
||||
"calc",
|
||||
"content",
|
||||
"inherit",
|
||||
"initial",
|
||||
"max-content",
|
||||
"min-content",
|
||||
"unset"
|
||||
]
|
||||
},
|
||||
@@ -6817,12 +6816,12 @@ exports.CSS_PROPERTIES = {
|
||||
"-moz-available",
|
||||
"-moz-calc",
|
||||
"-moz-fit-content",
|
||||
"-moz-max-content",
|
||||
"-moz-min-content",
|
||||
"auto",
|
||||
"calc",
|
||||
"inherit",
|
||||
"initial",
|
||||
"max-content",
|
||||
"min-content",
|
||||
"unset"
|
||||
]
|
||||
},
|
||||
@@ -6904,101 +6903,8 @@ exports.CSS_PROPERTIES = {
|
||||
"-moz-available",
|
||||
"-moz-calc",
|
||||
"-moz-fit-content",
|
||||
"auto",
|
||||
"calc",
|
||||
"inherit",
|
||||
"initial",
|
||||
"max-content",
|
||||
"min-content",
|
||||
"unset"
|
||||
]
|
||||
},
|
||||
"inset": {
|
||||
"isInherited": false,
|
||||
"subproperties": [
|
||||
"top",
|
||||
"right",
|
||||
"bottom",
|
||||
"left"
|
||||
],
|
||||
"supports": [
|
||||
6,
|
||||
8
|
||||
],
|
||||
"values": [
|
||||
"-moz-calc",
|
||||
"auto",
|
||||
"calc",
|
||||
"inherit",
|
||||
"initial",
|
||||
"unset"
|
||||
]
|
||||
},
|
||||
"inset-block-end": {
|
||||
"isInherited": false,
|
||||
"subproperties": [
|
||||
"inset-block-end"
|
||||
],
|
||||
"supports": [
|
||||
6,
|
||||
8
|
||||
],
|
||||
"values": [
|
||||
"-moz-calc",
|
||||
"auto",
|
||||
"calc",
|
||||
"inherit",
|
||||
"initial",
|
||||
"unset"
|
||||
]
|
||||
},
|
||||
"inset-block-start": {
|
||||
"isInherited": false,
|
||||
"subproperties": [
|
||||
"inset-block-start"
|
||||
],
|
||||
"supports": [
|
||||
6,
|
||||
8
|
||||
],
|
||||
"values": [
|
||||
"-moz-calc",
|
||||
"auto",
|
||||
"calc",
|
||||
"inherit",
|
||||
"initial",
|
||||
"unset"
|
||||
]
|
||||
},
|
||||
"inset-inline-end": {
|
||||
"isInherited": false,
|
||||
"subproperties": [
|
||||
"inset-inline-end"
|
||||
],
|
||||
"supports": [
|
||||
6,
|
||||
8
|
||||
],
|
||||
"values": [
|
||||
"-moz-calc",
|
||||
"auto",
|
||||
"calc",
|
||||
"inherit",
|
||||
"initial",
|
||||
"unset"
|
||||
]
|
||||
},
|
||||
"inset-inline-start": {
|
||||
"isInherited": false,
|
||||
"subproperties": [
|
||||
"inset-inline-start"
|
||||
],
|
||||
"supports": [
|
||||
6,
|
||||
8
|
||||
],
|
||||
"values": [
|
||||
"-moz-calc",
|
||||
"-moz-max-content",
|
||||
"-moz-min-content",
|
||||
"auto",
|
||||
"calc",
|
||||
"inherit",
|
||||
@@ -7745,11 +7651,11 @@ exports.CSS_PROPERTIES = {
|
||||
"-moz-available",
|
||||
"-moz-calc",
|
||||
"-moz-fit-content",
|
||||
"-moz-max-content",
|
||||
"-moz-min-content",
|
||||
"calc",
|
||||
"inherit",
|
||||
"initial",
|
||||
"max-content",
|
||||
"min-content",
|
||||
"none",
|
||||
"unset"
|
||||
]
|
||||
@@ -7767,11 +7673,11 @@ exports.CSS_PROPERTIES = {
|
||||
"-moz-available",
|
||||
"-moz-calc",
|
||||
"-moz-fit-content",
|
||||
"-moz-max-content",
|
||||
"-moz-min-content",
|
||||
"calc",
|
||||
"inherit",
|
||||
"initial",
|
||||
"max-content",
|
||||
"min-content",
|
||||
"none",
|
||||
"unset"
|
||||
]
|
||||
@@ -7789,11 +7695,11 @@ exports.CSS_PROPERTIES = {
|
||||
"-moz-available",
|
||||
"-moz-calc",
|
||||
"-moz-fit-content",
|
||||
"-moz-max-content",
|
||||
"-moz-min-content",
|
||||
"calc",
|
||||
"inherit",
|
||||
"initial",
|
||||
"max-content",
|
||||
"min-content",
|
||||
"none",
|
||||
"unset"
|
||||
]
|
||||
@@ -7829,12 +7735,12 @@ exports.CSS_PROPERTIES = {
|
||||
"-moz-available",
|
||||
"-moz-calc",
|
||||
"-moz-fit-content",
|
||||
"-moz-max-content",
|
||||
"-moz-min-content",
|
||||
"auto",
|
||||
"calc",
|
||||
"inherit",
|
||||
"initial",
|
||||
"max-content",
|
||||
"min-content",
|
||||
"unset"
|
||||
]
|
||||
},
|
||||
@@ -7851,12 +7757,12 @@ exports.CSS_PROPERTIES = {
|
||||
"-moz-available",
|
||||
"-moz-calc",
|
||||
"-moz-fit-content",
|
||||
"-moz-max-content",
|
||||
"-moz-min-content",
|
||||
"auto",
|
||||
"calc",
|
||||
"inherit",
|
||||
"initial",
|
||||
"max-content",
|
||||
"min-content",
|
||||
"unset"
|
||||
]
|
||||
},
|
||||
@@ -7873,12 +7779,12 @@ exports.CSS_PROPERTIES = {
|
||||
"-moz-available",
|
||||
"-moz-calc",
|
||||
"-moz-fit-content",
|
||||
"-moz-max-content",
|
||||
"-moz-min-content",
|
||||
"auto",
|
||||
"calc",
|
||||
"inherit",
|
||||
"initial",
|
||||
"max-content",
|
||||
"min-content",
|
||||
"unset"
|
||||
]
|
||||
},
|
||||
@@ -7945,7 +7851,7 @@ exports.CSS_PROPERTIES = {
|
||||
"offset-block-end": {
|
||||
"isInherited": false,
|
||||
"subproperties": [
|
||||
"inset-block-end"
|
||||
"offset-block-end"
|
||||
],
|
||||
"supports": [
|
||||
6,
|
||||
@@ -7963,7 +7869,7 @@ exports.CSS_PROPERTIES = {
|
||||
"offset-block-start": {
|
||||
"isInherited": false,
|
||||
"subproperties": [
|
||||
"inset-block-start"
|
||||
"offset-block-start"
|
||||
],
|
||||
"supports": [
|
||||
6,
|
||||
@@ -7981,7 +7887,7 @@ exports.CSS_PROPERTIES = {
|
||||
"offset-inline-end": {
|
||||
"isInherited": false,
|
||||
"subproperties": [
|
||||
"inset-inline-end"
|
||||
"offset-inline-end"
|
||||
],
|
||||
"supports": [
|
||||
6,
|
||||
@@ -7999,7 +7905,7 @@ exports.CSS_PROPERTIES = {
|
||||
"offset-inline-start": {
|
||||
"isInherited": false,
|
||||
"subproperties": [
|
||||
"inset-inline-start"
|
||||
"offset-inline-start"
|
||||
],
|
||||
"supports": [
|
||||
6,
|
||||
@@ -9613,7 +9519,6 @@ exports.CSS_PROPERTIES = {
|
||||
"supports": [],
|
||||
"values": [
|
||||
"-moz-pre-space",
|
||||
"break-spaces",
|
||||
"inherit",
|
||||
"initial",
|
||||
"normal",
|
||||
@@ -9637,12 +9542,12 @@ exports.CSS_PROPERTIES = {
|
||||
"-moz-available",
|
||||
"-moz-calc",
|
||||
"-moz-fit-content",
|
||||
"-moz-max-content",
|
||||
"-moz-min-content",
|
||||
"auto",
|
||||
"calc",
|
||||
"inherit",
|
||||
"initial",
|
||||
"max-content",
|
||||
"min-content",
|
||||
"unset"
|
||||
]
|
||||
},
|
||||
|
||||
@@ -190,6 +190,23 @@ LoadContext::GetOriginAttributes(JS::MutableHandleValue aAttrs)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
LoadContext::IsTrackingProtectionOn(bool* aIsTrackingProtectionOn)
|
||||
{
|
||||
MOZ_ASSERT(mIsNotNull);
|
||||
|
||||
if (Preferences::GetBool("privacy.trackingprotection.enabled", false)) {
|
||||
*aIsTrackingProtectionOn = true;
|
||||
} else if ((mOriginAttributes.mPrivateBrowsingId > 0) &&
|
||||
Preferences::GetBool("privacy.trackingprotection.pbmode.enabled", false)) {
|
||||
*aIsTrackingProtectionOn = true;
|
||||
} else {
|
||||
*aIsTrackingProtectionOn = false;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LoadContext::nsIInterfaceRequestor
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -13651,6 +13651,21 @@ nsDocShell::GetNestedFrameId(uint64_t* aId)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::IsTrackingProtectionOn(bool* aIsTrackingProtectionOn)
|
||||
{
|
||||
if (Preferences::GetBool("privacy.trackingprotection.enabled", false)) {
|
||||
*aIsTrackingProtectionOn = true;
|
||||
} else if (UsePrivateBrowsing() &&
|
||||
Preferences::GetBool("privacy.trackingprotection.pbmode.enabled", false)) {
|
||||
*aIsTrackingProtectionOn = true;
|
||||
} else {
|
||||
*aIsTrackingProtectionOn = false;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetIsContent(bool* aIsContent)
|
||||
{
|
||||
|
||||
@@ -233,6 +233,7 @@ public:
|
||||
NS_IMETHOD GetUseRemoteTabs(bool*) override;
|
||||
NS_IMETHOD SetRemoteTabs(bool) override;
|
||||
NS_IMETHOD GetOriginAttributes(JS::MutableHandle<JS::Value>) override;
|
||||
NS_IMETHOD IsTrackingProtectionOn(bool*) override;
|
||||
|
||||
// Restores a cached presentation from history (mLSHE).
|
||||
// This method swaps out the content viewer and simulates loads for
|
||||
|
||||
@@ -137,4 +137,19 @@ interface nsILoadContext : nsISupports
|
||||
#endif
|
||||
%}
|
||||
|
||||
/**
|
||||
* Returns true if tracking protection is enabled for the load context.
|
||||
*/
|
||||
boolean IsTrackingProtectionOn();
|
||||
|
||||
%{C++
|
||||
/**
|
||||
* De-XPCOMed getter to make call-sites cleaner.
|
||||
*/
|
||||
bool UseTrackingProtection() {
|
||||
bool usingTP;
|
||||
IsTrackingProtectionOn(&usingTP);
|
||||
return usingTP;
|
||||
}
|
||||
%}
|
||||
};
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "TimelineConsumers.h"
|
||||
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "jsapi.h"
|
||||
#include "nsAppRunner.h" // for XRE_IsContentProcess, XRE_IsParentProcess
|
||||
#include "nsDocShell.h"
|
||||
|
||||
@@ -126,9 +125,6 @@ TimelineConsumers::AddConsumer(nsDocShell* aDocShell)
|
||||
UniquePtr<ObservedDocShell>& observed = aDocShell->mObserved;
|
||||
MOZ_ASSERT(!observed);
|
||||
|
||||
if (mActiveConsumers == 0) {
|
||||
JS::SetProfileTimelineRecordingEnabled(true);
|
||||
}
|
||||
mActiveConsumers++;
|
||||
|
||||
ObservedDocShell* obsDocShell = new ObservedDocShell(aDocShell);
|
||||
@@ -148,9 +144,6 @@ TimelineConsumers::RemoveConsumer(nsDocShell* aDocShell)
|
||||
MOZ_ASSERT(observed);
|
||||
|
||||
mActiveConsumers--;
|
||||
if (mActiveConsumers == 0) {
|
||||
JS::SetProfileTimelineRecordingEnabled(false);
|
||||
}
|
||||
|
||||
// Clear all markers from the `mTimelineMarkers` store.
|
||||
observed.get()->ClearMarkers();
|
||||
|
||||
@@ -36,6 +36,11 @@ EXPORTS.mozilla += [
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'KeyframeEffect.cpp',
|
||||
'KeyframeEffectReadOnly.cpp',
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
'Animation.cpp',
|
||||
'AnimationEffectReadOnly.cpp',
|
||||
'AnimationEffectTiming.cpp',
|
||||
@@ -49,9 +54,7 @@ UNIFIED_SOURCES += [
|
||||
'DocumentTimeline.cpp',
|
||||
'EffectCompositor.cpp',
|
||||
'EffectSet.cpp',
|
||||
'KeyframeEffect.cpp',
|
||||
'KeyframeEffectParams.cpp',
|
||||
'KeyframeEffectReadOnly.cpp',
|
||||
'KeyframeUtils.cpp',
|
||||
'PendingAnimationTracker.cpp',
|
||||
'TimingParams.cpp',
|
||||
|
||||
@@ -15,7 +15,7 @@ EXPORTS += [
|
||||
'AudioChannelService.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
SOURCES += [
|
||||
'AudioChannelAgent.cpp',
|
||||
'AudioChannelService.cpp',
|
||||
]
|
||||
|
||||
@@ -536,5 +536,23 @@ StyleChildrenIterator::IsNeeded(const Element* aElement)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
nsIContent*
|
||||
StyleChildrenIterator::GetNextChild()
|
||||
{
|
||||
while (nsIContent* child = AllChildrenIterator::GetNextChild()) {
|
||||
if (IsNativeAnonymousImplementationOfPseudoElement(child)) {
|
||||
// Skip any native-anonymous children that are used to implement pseudo-
|
||||
// elements. These match pseudo-element selectors instead of being
|
||||
// considered a child of their host, and thus the style system needs to
|
||||
// handle them separately.
|
||||
} else {
|
||||
return child;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
+16
-51
@@ -7,8 +7,6 @@
|
||||
#define ChildIterator_h
|
||||
|
||||
#include "nsIContent.h"
|
||||
#include "nsIContentInlines.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* Iterates over the children on a node. If a child is an insertion point,
|
||||
@@ -19,6 +17,9 @@
|
||||
* binding's <xbl:content> element.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
class nsIContent;
|
||||
|
||||
namespace mozilla {
|
||||
@@ -188,33 +189,20 @@ protected:
|
||||
class AllChildrenIterator : private FlattenedChildIterator
|
||||
{
|
||||
public:
|
||||
AllChildrenIterator(const nsIContent* aNode,
|
||||
uint32_t aFlags,
|
||||
bool aStartAtBeginning = true)
|
||||
: FlattenedChildIterator(aNode, aFlags, aStartAtBeginning)
|
||||
, mAnonKidsIdx(aStartAtBeginning ? UINT32_MAX : 0)
|
||||
, mFlags(aFlags), mPhase(aStartAtBeginning ? eAtBegin : eAtEnd)
|
||||
{
|
||||
}
|
||||
AllChildrenIterator(const nsIContent* aNode, uint32_t aFlags,
|
||||
bool aStartAtBeginning = true) :
|
||||
FlattenedChildIterator(aNode, aFlags, aStartAtBeginning),
|
||||
mAnonKidsIdx(aStartAtBeginning ? UINT32_MAX : 0),
|
||||
mFlags(aFlags), mPhase(aStartAtBeginning ? eAtBegin : eAtEnd) { }
|
||||
|
||||
AllChildrenIterator(AllChildrenIterator&& aOther)
|
||||
: FlattenedChildIterator(Move(aOther))
|
||||
, mAnonKids(Move(aOther.mAnonKids))
|
||||
, mAnonKidsIdx(aOther.mAnonKidsIdx)
|
||||
, mFlags(aOther.mFlags)
|
||||
, mPhase(aOther.mPhase)
|
||||
: FlattenedChildIterator(Move(aOther)),
|
||||
mAnonKids(Move(aOther.mAnonKids)), mAnonKidsIdx(aOther.mAnonKidsIdx),
|
||||
mFlags(aOther.mFlags), mPhase(aOther.mPhase)
|
||||
#ifdef DEBUG
|
||||
, mMutationGuard(aOther.mMutationGuard)
|
||||
, mMutationGuard(aOther.mMutationGuard)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
AllChildrenIterator& operator=(AllChildrenIterator&& aOther)
|
||||
{
|
||||
this->~AllChildrenIterator();
|
||||
new (this)AllChildrenIterator(Move(aOther));
|
||||
return *this;
|
||||
}
|
||||
{}
|
||||
|
||||
#ifdef DEBUG
|
||||
~AllChildrenIterator() { MOZ_ASSERT(!mMutationGuard.Mutated(0)); }
|
||||
@@ -280,43 +268,20 @@ private:
|
||||
*/
|
||||
class StyleChildrenIterator : private AllChildrenIterator {
|
||||
public:
|
||||
StyleChildrenIterator(const nsIContent* aContent,
|
||||
bool aStartAtBeginning = true)
|
||||
explicit StyleChildrenIterator(const nsIContent* aContent)
|
||||
: AllChildrenIterator(aContent,
|
||||
nsIContent::eAllChildren |
|
||||
nsIContent::eSkipDocumentLevelNativeAnonymousContent,
|
||||
aStartAtBeginning)
|
||||
nsIContent::eSkipDocumentLevelNativeAnonymousContent)
|
||||
{
|
||||
MOZ_COUNT_CTOR(StyleChildrenIterator);
|
||||
}
|
||||
|
||||
StyleChildrenIterator(StyleChildrenIterator&& aOther)
|
||||
: AllChildrenIterator(Move(aOther))
|
||||
{
|
||||
MOZ_COUNT_CTOR(StyleChildrenIterator);
|
||||
}
|
||||
|
||||
StyleChildrenIterator& operator=(StyleChildrenIterator&& aOther)
|
||||
{
|
||||
AllChildrenIterator::operator=(Move(aOther));
|
||||
return *this;
|
||||
}
|
||||
|
||||
~StyleChildrenIterator() { MOZ_COUNT_DTOR(StyleChildrenIterator); }
|
||||
|
||||
static nsIContent* GetParent(const nsIContent& aContent)
|
||||
{
|
||||
nsINode* node = aContent.GetFlattenedTreeParentNodeForStyle();
|
||||
return node && node->IsContent() ? node->AsContent() : nullptr;
|
||||
}
|
||||
nsIContent* GetNextChild();
|
||||
|
||||
// Returns true if we cannot find all the children we need to style by
|
||||
// traversing the siblings of the first child.
|
||||
static bool IsNeeded(const Element* aParent);
|
||||
|
||||
using AllChildrenIterator::GetNextChild;
|
||||
using AllChildrenIterator::GetPreviousChild;
|
||||
using AllChildrenIterator::Seek;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsHTMLTags.h"
|
||||
#include "jsapi.h"
|
||||
#include "ShadowRoot.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@@ -416,95 +415,6 @@ CustomElementRegistry::EnqueueLifecycleCallback(nsIDocument::ElementCallbackType
|
||||
reactionsStack->EnqueueCallbackReaction(aCustomElement, Move(callback));
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class CandidateFinder
|
||||
{
|
||||
public:
|
||||
CandidateFinder(nsTArray<nsWeakPtr>&& aCandidates, nsIDocument* aDoc);
|
||||
nsTArray<nsCOMPtr<Element>> OrderedCandidates();
|
||||
|
||||
private:
|
||||
bool Traverse(Element* aRoot, nsTArray<nsCOMPtr<Element>>& aOrderedElements);
|
||||
|
||||
nsCOMPtr<nsIDocument> mDoc;
|
||||
nsInterfaceHashtable<nsPtrHashKey<Element>, Element> mCandidates;
|
||||
};
|
||||
|
||||
CandidateFinder::CandidateFinder(nsTArray<nsWeakPtr>&& aCandidates,
|
||||
nsIDocument* aDoc)
|
||||
: mDoc(aDoc)
|
||||
, mCandidates(aCandidates.Length())
|
||||
{
|
||||
MOZ_ASSERT(mDoc);
|
||||
for (auto& candidate : aCandidates) {
|
||||
nsCOMPtr<Element> elem = do_QueryReferent(candidate);
|
||||
if (!elem) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Element* key = elem.get();
|
||||
mCandidates.Put(key, elem.forget());
|
||||
}
|
||||
}
|
||||
|
||||
nsTArray<nsCOMPtr<Element>>
|
||||
CandidateFinder::OrderedCandidates()
|
||||
{
|
||||
if (mCandidates.Count() == 1) {
|
||||
// Fast path for one candidate.
|
||||
for (auto iter = mCandidates.Iter(); !iter.Done(); iter.Next()) {
|
||||
nsTArray<nsCOMPtr<Element>> rval({ Move(iter.Data()) });
|
||||
iter.Remove();
|
||||
return rval;
|
||||
}
|
||||
}
|
||||
|
||||
nsTArray<nsCOMPtr<Element>> orderedElements(mCandidates.Count());
|
||||
for (Element* child = mDoc->GetFirstElementChild(); child; child = child->GetNextElementSibling()) {
|
||||
if (!Traverse(child->AsElement(), orderedElements)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return orderedElements;
|
||||
}
|
||||
|
||||
bool
|
||||
CandidateFinder::Traverse(Element* aRoot, nsTArray<nsCOMPtr<Element>>& aOrderedElements)
|
||||
{
|
||||
nsCOMPtr<Element> elem = mCandidates.Get(aRoot);
|
||||
if (elem) {
|
||||
mCandidates.Remove(aRoot);
|
||||
aOrderedElements.AppendElement(Move(elem));
|
||||
if (mCandidates.Count() == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (ShadowRoot* root = aRoot->GetShadowRoot()) {
|
||||
// First iterate the children of the shadow root if aRoot is a shadow host.
|
||||
for (Element* child = root->GetFirstElementChild(); child;
|
||||
child = child->GetNextElementSibling()) {
|
||||
if (!Traverse(child, aOrderedElements)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Iterate the explicit children of aRoot.
|
||||
for (Element* child = aRoot->GetFirstElementChild(); child;
|
||||
child = child->GetNextElementSibling()) {
|
||||
if (!Traverse(child, aOrderedElements)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
CustomElementRegistry::UpgradeCandidates(nsIAtom* aKey,
|
||||
CustomElementDefinition* aDefinition,
|
||||
@@ -516,13 +426,18 @@ CustomElementRegistry::UpgradeCandidates(nsIAtom* aKey,
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Bug 1326028 - Upgrade custom element in shadow-including tree order
|
||||
nsAutoPtr<nsTArray<nsWeakPtr>> candidates;
|
||||
mCandidatesMap.RemoveAndForget(aKey, candidates);
|
||||
if (candidates) {
|
||||
CustomElementReactionsStack* reactionsStack =
|
||||
docGroup->CustomElementReactionsStack();
|
||||
CandidateFinder finder(Move(*candidates), mWindow->GetExtantDoc());
|
||||
for (auto& elem : finder.OrderedCandidates()) {
|
||||
for (size_t i = 0; i < candidates->Length(); ++i) {
|
||||
nsCOMPtr<Element> elem = do_QueryReferent(candidates->ElementAt(i));
|
||||
if (!elem) {
|
||||
continue;
|
||||
}
|
||||
|
||||
reactionsStack->EnqueueUpgradeReaction(elem, aDefinition);
|
||||
}
|
||||
}
|
||||
@@ -876,45 +791,6 @@ CustomElementRegistry::Define(const nsAString& aName,
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
TryUpgrade(nsINode& aNode)
|
||||
{
|
||||
Element* element = aNode.IsElement() ? aNode.AsElement() : nullptr;
|
||||
if (element) {
|
||||
CustomElementData* ceData = element->GetCustomElementData();
|
||||
if (ceData) {
|
||||
NodeInfo* nodeInfo = element->NodeInfo();
|
||||
nsIAtom* typeAtom = ceData->GetCustomElementType();
|
||||
CustomElementDefinition* definition =
|
||||
nsContentUtils::LookupCustomElementDefinition(nodeInfo->GetDocument(),
|
||||
nodeInfo->NameAtom(),
|
||||
nodeInfo->NamespaceID(),
|
||||
typeAtom);
|
||||
if (definition) {
|
||||
nsContentUtils::EnqueueUpgradeReaction(element, definition);
|
||||
}
|
||||
}
|
||||
|
||||
if (ShadowRoot* root = element->GetShadowRoot()) {
|
||||
for (Element* child = root->GetFirstElementChild(); child;
|
||||
child = child->GetNextElementSibling()) {
|
||||
TryUpgrade(*child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Element* child = aNode.GetFirstElementChild(); child;
|
||||
child = child->GetNextElementSibling()) {
|
||||
TryUpgrade(*child);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CustomElementRegistry::Upgrade(nsINode& aRoot)
|
||||
{
|
||||
TryUpgrade(aRoot);
|
||||
}
|
||||
|
||||
void
|
||||
CustomElementRegistry::Get(JSContext* aCx, const nsAString& aName,
|
||||
JS::MutableHandle<JS::Value> aRetVal)
|
||||
|
||||
@@ -525,8 +525,6 @@ public:
|
||||
JS::MutableHandle<JS::Value> aRetVal);
|
||||
|
||||
already_AddRefed<Promise> WhenDefined(const nsAString& aName, ErrorResult& aRv);
|
||||
|
||||
void Upgrade(nsINode& aRoot);
|
||||
};
|
||||
|
||||
class MOZ_RAII AutoCEReaction final {
|
||||
|
||||
@@ -4,14 +4,11 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "DocumentOrShadowRoot.h"
|
||||
#include "mozilla/EventStateManager.h"
|
||||
#include "mozilla/dom/StyleSheetList.h"
|
||||
#include "nsDocument.h"
|
||||
#include "nsFocusManager.h"
|
||||
#include "ShadowRoot.h"
|
||||
#include "XULDocument.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsSVGUtils.h"
|
||||
|
||||
class nsINode;
|
||||
class nsIDocument;
|
||||
@@ -147,158 +144,5 @@ DocumentOrShadowRoot::GetRetargetedFocusedElement()
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Element*
|
||||
DocumentOrShadowRoot::GetPointerLockElement()
|
||||
{
|
||||
nsCOMPtr<Element> pointerLockedElement =
|
||||
do_QueryReferent(EventStateManager::sPointerLockedElement);
|
||||
if (!pointerLockedElement) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsIContent* retargetedPointerLockedElement = Retarget(pointerLockedElement);
|
||||
return
|
||||
retargetedPointerLockedElement && retargetedPointerLockedElement->IsElement() ?
|
||||
retargetedPointerLockedElement->AsElement() : nullptr;
|
||||
}
|
||||
|
||||
Element*
|
||||
DocumentOrShadowRoot::GetFullscreenElement()
|
||||
{
|
||||
if (!AsNode().IsInComposedDoc()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Element* element = AsNode().OwnerDoc()->FullScreenStackTop();
|
||||
NS_ASSERTION(!element ||
|
||||
element->State().HasState(NS_EVENT_STATE_FULL_SCREEN),
|
||||
"Fullscreen element should have fullscreen styles applied");
|
||||
|
||||
nsIContent* retargeted = Retarget(element);
|
||||
if (retargeted && retargeted->IsElement()) {
|
||||
return retargeted->AsElement();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Element*
|
||||
DocumentOrShadowRoot::ElementFromPoint(float aX, float aY)
|
||||
{
|
||||
return ElementFromPointHelper(aX, aY, false, true);
|
||||
}
|
||||
|
||||
void
|
||||
DocumentOrShadowRoot::ElementsFromPoint(float aX, float aY,
|
||||
nsTArray<RefPtr<Element>>& aElements)
|
||||
{
|
||||
ElementsFromPointHelper(aX, aY, nsIDocument::FLUSH_LAYOUT, aElements);
|
||||
}
|
||||
|
||||
Element*
|
||||
DocumentOrShadowRoot::ElementFromPointHelper(float aX, float aY,
|
||||
bool aIgnoreRootScrollFrame,
|
||||
bool aFlushLayout)
|
||||
{
|
||||
AutoTArray<RefPtr<Element>, 1> elementArray;
|
||||
ElementsFromPointHelper(aX, aY,
|
||||
((aIgnoreRootScrollFrame ? nsIDocument::IGNORE_ROOT_SCROLL_FRAME : 0) |
|
||||
(aFlushLayout ? nsIDocument::FLUSH_LAYOUT : 0) |
|
||||
nsIDocument::IS_ELEMENT_FROM_POINT),
|
||||
elementArray);
|
||||
if (elementArray.IsEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
return elementArray[0];
|
||||
}
|
||||
|
||||
void
|
||||
DocumentOrShadowRoot::ElementsFromPointHelper(float aX, float aY,
|
||||
uint32_t aFlags,
|
||||
nsTArray<RefPtr<mozilla::dom::Element>>& aElements)
|
||||
{
|
||||
// As per the the spec, we return null if either coord is negative
|
||||
if (!(aFlags & nsIDocument::IGNORE_ROOT_SCROLL_FRAME) && (aX < 0 || aY < 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nscoord x = nsPresContext::CSSPixelsToAppUnits(aX);
|
||||
nscoord y = nsPresContext::CSSPixelsToAppUnits(aY);
|
||||
nsPoint pt(x, y);
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = AsNode().OwnerDoc();
|
||||
|
||||
// Make sure the layout information we get is up-to-date, and
|
||||
// ensure we get a root frame (for everything but XUL)
|
||||
if (aFlags & nsIDocument::FLUSH_LAYOUT) {
|
||||
doc->FlushPendingNotifications(Flush_Layout);
|
||||
}
|
||||
|
||||
nsIPresShell* ps = doc->GetShell();
|
||||
if (!ps) {
|
||||
return;
|
||||
}
|
||||
nsIFrame* rootFrame = ps->GetRootFrame();
|
||||
|
||||
// XUL docs, unlike HTML, have no frame tree until everything's done loading
|
||||
if (!rootFrame) {
|
||||
return; // return null to premature XUL callers as a reminder to wait
|
||||
}
|
||||
|
||||
nsTArray<nsIFrame*> outFrames;
|
||||
// Emulate what GetFrameAtPoint does, since we want all the frames under our
|
||||
// point.
|
||||
nsLayoutUtils::GetFramesForArea(rootFrame, nsRect(pt, nsSize(1, 1)), outFrames,
|
||||
nsLayoutUtils::IGNORE_PAINT_SUPPRESSION | nsLayoutUtils::IGNORE_CROSS_DOC |
|
||||
((aFlags & nsIDocument::IGNORE_ROOT_SCROLL_FRAME) ? nsLayoutUtils::IGNORE_ROOT_SCROLL_FRAME : 0));
|
||||
|
||||
// Dunno when this would ever happen, as we should at least have a root frame under us?
|
||||
if (outFrames.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Used to filter out repeated elements in sequence.
|
||||
nsIContent* lastAdded = nullptr;
|
||||
|
||||
for (uint32_t i = 0; i < outFrames.Length(); i++) {
|
||||
nsIContent* node = doc->GetContentInThisDocument(outFrames[i]);
|
||||
|
||||
if (!node || !node->IsElement()) {
|
||||
// If this helper is called via ElementsFromPoint, we need to make sure
|
||||
// our frame is an element. Otherwise return whatever the top frame is
|
||||
// even if it isn't the top-painted element.
|
||||
// SVG 'text' element's SVGTextFrame doesn't respond to hit-testing, so
|
||||
// if 'node' is a child of such an element then we need to manually defer
|
||||
// to the parent here.
|
||||
if (!(aFlags & nsIDocument::IS_ELEMENT_FROM_POINT) &&
|
||||
!outFrames[i]->IsSVGText()) {
|
||||
continue;
|
||||
}
|
||||
node = node->GetParent();
|
||||
if (node) {
|
||||
ShadowRoot* shadow = ShadowRoot::FromNode(node);
|
||||
if (shadow) {
|
||||
node = shadow->Host();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//XXXsmaug There is plenty of unspec'ed behavior here
|
||||
// https://github.com/w3c/webcomponents/issues/735
|
||||
// https://github.com/w3c/webcomponents/issues/736
|
||||
node = Retarget(node);
|
||||
|
||||
if (node && node != lastAdded) {
|
||||
aElements.AppendElement(node->AsElement());
|
||||
lastAdded = node;
|
||||
// If this helper is called via ElementFromPoint, just return the first
|
||||
// element we find.
|
||||
if (aFlags & nsIDocument::IS_ELEMENT_FROM_POINT) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -114,32 +114,6 @@ public:
|
||||
|
||||
~DocumentOrShadowRoot() = default;
|
||||
|
||||
Element* GetPointerLockElement();
|
||||
Element* GetFullscreenElement();
|
||||
|
||||
Element* ElementFromPoint(float aX, float aY);
|
||||
void ElementsFromPoint(float aX, float aY,
|
||||
nsTArray<RefPtr<mozilla::dom::Element>>& aElements);
|
||||
|
||||
/**
|
||||
* Helper for nsIDOMDocument::elementFromPoint implementation that allows
|
||||
* ignoring the scroll frame and/or avoiding layout flushes.
|
||||
*
|
||||
* @see nsIDOMWindowUtils::elementFromPoint
|
||||
*/
|
||||
Element* ElementFromPointHelper(float aX, float aY,
|
||||
bool aIgnoreRootScrollFrame,
|
||||
bool aFlushLayout);
|
||||
enum ElementsFromPointFlags
|
||||
{
|
||||
IGNORE_ROOT_SCROLL_FRAME = 1,
|
||||
FLUSH_LAYOUT = 2,
|
||||
IS_ELEMENT_FROM_POINT = 4
|
||||
};
|
||||
|
||||
void ElementsFromPointHelper(float aX, float aY, uint32_t aFlags,
|
||||
nsTArray<RefPtr<mozilla::dom::Element>>& aElements);
|
||||
|
||||
protected:
|
||||
nsIContent* Retarget(nsIContent* aContent) const;
|
||||
|
||||
|
||||
+21
-12
@@ -1122,6 +1122,18 @@ Element::AttachShadow(const ShadowRootInit& aInit, ErrorResult& aError)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return AttachShadowInternal(aInit.mMode == ShadowRootMode::Closed, aError);
|
||||
}
|
||||
|
||||
already_AddRefed<ShadowRoot>
|
||||
Element::CreateShadowRoot(ErrorResult& aError)
|
||||
{
|
||||
return AttachShadowInternal(false, aError);
|
||||
}
|
||||
|
||||
already_AddRefed<ShadowRoot>
|
||||
Element::AttachShadowInternal(bool aClosed, ErrorResult& aError)
|
||||
{
|
||||
/**
|
||||
* 3. If context object is a shadow host, then throw
|
||||
* an "InvalidStateError" DOMException.
|
||||
@@ -1167,9 +1179,8 @@ Element::AttachShadow(const ShadowRootInit& aInit, ErrorResult& aError)
|
||||
* context object???s node document, host is context object,
|
||||
* and mode is init???s mode.
|
||||
*/
|
||||
bool isClosed = (aInit.mMode == ShadowRootMode::Closed);
|
||||
RefPtr<ShadowRoot> shadowRoot =
|
||||
new ShadowRoot(this, isClosed, nodeInfo.forget(), protoBinding);
|
||||
new ShadowRoot(this, aClosed, nodeInfo.forget(), protoBinding);
|
||||
|
||||
shadowRoot->SetIsComposedDocParticipant(IsInComposedDoc());
|
||||
|
||||
@@ -1706,11 +1717,10 @@ Element::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
if (!hadParent) {
|
||||
uint32_t editableDescendantChange = EditableInclusiveDescendantCount(this);
|
||||
if (editableDescendantChange != 0) {
|
||||
// If we are binding a subtree root to the document, we need to update
|
||||
// the editable descendant count of all the ancestors. However, we don't
|
||||
// cross the Shadow DOM boundary (expected behavior is unclear).
|
||||
// If we are binding a subtree root to the document, we need to update
|
||||
// the editable descendant count of all the ancestors.
|
||||
nsIContent* parent = GetParent();
|
||||
while (parent && parent->IsElement()) {
|
||||
while (parent) {
|
||||
parent->ChangeEditableDescendantCount(editableDescendantChange);
|
||||
parent = parent->GetParent();
|
||||
}
|
||||
@@ -3418,9 +3428,9 @@ Element::Closest(const nsAString& aSelector, ErrorResult& aResult)
|
||||
matchingContext.AddScopeElement(this);
|
||||
for (nsINode* node = this; node; node = node->GetParentNode()) {
|
||||
if (node->IsElement() &&
|
||||
nsCSSRuleProcessor::RestrictedSelectorListMatches(node->AsElement(),
|
||||
matchingContext,
|
||||
selectorList)) {
|
||||
nsCSSRuleProcessor::SelectorListMatches(node->AsElement(),
|
||||
matchingContext,
|
||||
selectorList)) {
|
||||
return node->AsElement();
|
||||
}
|
||||
}
|
||||
@@ -3444,9 +3454,8 @@ Element::Matches(const nsAString& aSelector, ErrorResult& aError)
|
||||
TreeMatchContext::eNeverMatchVisited);
|
||||
matchingContext.SetHasSpecifiedScope();
|
||||
matchingContext.AddScopeElement(this);
|
||||
return nsCSSRuleProcessor::RestrictedSelectorListMatches(this,
|
||||
matchingContext,
|
||||
selectorList);
|
||||
return nsCSSRuleProcessor::SelectorListMatches(this, matchingContext,
|
||||
selectorList);
|
||||
}
|
||||
|
||||
static const nsAttrValue::EnumTable kCORSAttributeTable[] = {
|
||||
|
||||
@@ -470,6 +470,9 @@ protected:
|
||||
mState &= ~aStates;
|
||||
}
|
||||
|
||||
already_AddRefed<ShadowRoot> AttachShadowInternal(bool aClosed,
|
||||
ErrorResult& aError);
|
||||
|
||||
private:
|
||||
// Need to allow the ESM, nsGlobalWindow, and the focus manager to
|
||||
// set our state
|
||||
@@ -927,6 +930,9 @@ public:
|
||||
void SetSlot(const nsAString& aName, ErrorResult& aError);
|
||||
void GetSlot(nsAString& aName);
|
||||
|
||||
// [deprecated] Shadow DOM v0
|
||||
already_AddRefed<ShadowRoot> CreateShadowRoot(ErrorResult& aError);
|
||||
|
||||
ShadowRoot *FastGetShadowRoot() const
|
||||
{
|
||||
nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
|
||||
|
||||
+401
-1168
File diff suppressed because it is too large.
Load diff
+179
-39
@@ -35,81 +35,221 @@ namespace dom {
|
||||
|
||||
struct EventSourceInit;
|
||||
|
||||
class EventSourceImpl;
|
||||
|
||||
class EventSource final : public DOMEventTargetHelper
|
||||
, public nsIObserver
|
||||
, public nsIStreamListener
|
||||
, public nsIChannelEventSink
|
||||
, public nsIInterfaceRequestor
|
||||
, public nsSupportsWeakReference
|
||||
{
|
||||
friend class EventSourceImpl;
|
||||
public:
|
||||
explicit EventSource(nsPIDOMWindowInner* aOwnerWindow);
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(EventSource, DOMEventTargetHelper)
|
||||
virtual bool IsCertainlyAliveForCC() const override;
|
||||
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_INHERITED(
|
||||
EventSource, DOMEventTargetHelper)
|
||||
|
||||
// EventTarget
|
||||
void DisconnectFromOwner() override
|
||||
{
|
||||
DOMEventTargetHelper::DisconnectFromOwner();
|
||||
Close();
|
||||
}
|
||||
NS_DECL_NSIOBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSICHANNELEVENTSINK
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
// nsWrapperCache
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
// WebIDL
|
||||
nsPIDOMWindowInner*
|
||||
GetParentObject() const
|
||||
{
|
||||
return GetOwner();
|
||||
}
|
||||
static already_AddRefed<EventSource>
|
||||
Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
|
||||
const EventSourceInit& aEventSourceInitDict, ErrorResult& aRv);
|
||||
const EventSourceInit& aEventSourceInitDict,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void GetUrl(nsAString& aURL) const
|
||||
{
|
||||
AssertIsOnTargetThread();
|
||||
aURL = mOriginalURL;
|
||||
}
|
||||
|
||||
bool WithCredentials() const
|
||||
{
|
||||
AssertIsOnTargetThread();
|
||||
return mWithCredentials;
|
||||
}
|
||||
|
||||
enum {
|
||||
CONNECTING = 0U,
|
||||
OPEN = 1U,
|
||||
CLOSED = 2U
|
||||
};
|
||||
uint16_t ReadyState() const
|
||||
{
|
||||
AssertIsOnTargetThread();
|
||||
return mReadyState;
|
||||
}
|
||||
|
||||
IMPL_EVENT_HANDLER(open)
|
||||
IMPL_EVENT_HANDLER(message)
|
||||
IMPL_EVENT_HANDLER(error)
|
||||
|
||||
void Close();
|
||||
|
||||
private:
|
||||
EventSource(nsPIDOMWindowInner* aOwnerWindow, bool aWithCredentials);
|
||||
virtual void DisconnectFromOwner() override;
|
||||
|
||||
protected:
|
||||
virtual ~EventSource();
|
||||
// prevent bad usage
|
||||
EventSource(const EventSource& x) = delete;
|
||||
EventSource& operator=(const EventSource& x) = delete;
|
||||
|
||||
void AssertIsOnTargetThread() const
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread() == mIsMainThread);
|
||||
}
|
||||
MOZ_IS_CLASS_INIT
|
||||
nsresult Init(nsISupports* aOwner,
|
||||
const nsAString& aURL,
|
||||
bool aWithCredentials);
|
||||
|
||||
nsresult CreateAndDispatchSimpleEvent(const nsAString& aName);
|
||||
nsresult GetBaseURI(nsIURI **aBaseURI);
|
||||
|
||||
// Raw pointer because this EventSourceImpl is created, managed and destroyed
|
||||
// by EventSource.
|
||||
EventSourceImpl* mImpl;
|
||||
nsString mOriginalURL;
|
||||
uint16_t mReadyState;
|
||||
void SetupHttpChannel();
|
||||
nsresult SetupReferrerPolicy();
|
||||
nsresult InitChannelAndRequestEventSource();
|
||||
nsresult ResetConnection();
|
||||
nsresult DispatchFailConnection();
|
||||
nsresult SetReconnectionTimeout();
|
||||
|
||||
void AnnounceConnection();
|
||||
void DispatchAllMessageEvents();
|
||||
void ReestablishConnection();
|
||||
void FailConnection();
|
||||
|
||||
nsresult Thaw();
|
||||
nsresult Freeze();
|
||||
|
||||
static void TimerCallback(nsITimer *aTimer, void *aClosure);
|
||||
|
||||
nsresult PrintErrorOnConsole(const char *aBundleURI,
|
||||
const char16_t *aError,
|
||||
const char16_t **aFormatStrings,
|
||||
uint32_t aFormatStringsLen);
|
||||
nsresult ConsoleError();
|
||||
|
||||
static nsresult StreamReaderFunc(nsIInputStream *aInputStream,
|
||||
void *aClosure,
|
||||
const char *aFromRawSegment,
|
||||
uint32_t aToOffset,
|
||||
uint32_t aCount,
|
||||
uint32_t *aWriteCount);
|
||||
nsresult SetFieldAndClear();
|
||||
nsresult ClearFields();
|
||||
nsresult ResetEvent();
|
||||
nsresult DispatchCurrentMessageEvent();
|
||||
nsresult ParseCharacter(char16_t aChr);
|
||||
nsresult CheckHealthOfRequestCallback(nsIRequest *aRequestCallback);
|
||||
nsresult OnRedirectVerifyCallback(nsresult result);
|
||||
|
||||
nsCOMPtr<nsIURI> mSrc;
|
||||
|
||||
nsString mLastEventID;
|
||||
uint32_t mReconnectionTime; // in ms
|
||||
|
||||
struct Message {
|
||||
nsString mEventName;
|
||||
nsString mLastEventID;
|
||||
nsString mData;
|
||||
};
|
||||
nsDeque mMessagesToDispatch;
|
||||
Message mCurrentMessage;
|
||||
|
||||
/**
|
||||
* A simple state machine used to manage the event-source's line buffer
|
||||
*
|
||||
* PARSE_STATE_OFF -> PARSE_STATE_BEGIN_OF_STREAM
|
||||
*
|
||||
* PARSE_STATE_BEGIN_OF_STREAM -> PARSE_STATE_BOM_WAS_READ |
|
||||
* PARSE_STATE_CR_CHAR |
|
||||
* PARSE_STATE_BEGIN_OF_LINE |
|
||||
* PARSE_STATE_COMMENT |
|
||||
* PARSE_STATE_FIELD_NAME
|
||||
*
|
||||
* PARSE_STATE_BOM_WAS_READ -> PARSE_STATE_CR_CHAR |
|
||||
* PARSE_STATE_BEGIN_OF_LINE |
|
||||
* PARSE_STATE_COMMENT |
|
||||
* PARSE_STATE_FIELD_NAME
|
||||
*
|
||||
* PARSE_STATE_CR_CHAR -> PARSE_STATE_CR_CHAR |
|
||||
* PARSE_STATE_COMMENT |
|
||||
* PARSE_STATE_FIELD_NAME |
|
||||
* PARSE_STATE_BEGIN_OF_LINE
|
||||
*
|
||||
* PARSE_STATE_COMMENT -> PARSE_STATE_CR_CHAR |
|
||||
* PARSE_STATE_BEGIN_OF_LINE
|
||||
*
|
||||
* PARSE_STATE_FIELD_NAME -> PARSE_STATE_CR_CHAR |
|
||||
* PARSE_STATE_BEGIN_OF_LINE |
|
||||
* PARSE_STATE_FIRST_CHAR_OF_FIELD_VALUE
|
||||
*
|
||||
* PARSE_STATE_FIRST_CHAR_OF_FIELD_VALUE -> PARSE_STATE_FIELD_VALUE |
|
||||
* PARSE_STATE_CR_CHAR |
|
||||
* PARSE_STATE_BEGIN_OF_LINE
|
||||
*
|
||||
* PARSE_STATE_FIELD_VALUE -> PARSE_STATE_CR_CHAR |
|
||||
* PARSE_STATE_BEGIN_OF_LINE
|
||||
*
|
||||
* PARSE_STATE_BEGIN_OF_LINE -> PARSE_STATE_CR_CHAR |
|
||||
* PARSE_STATE_COMMENT |
|
||||
* PARSE_STATE_FIELD_NAME |
|
||||
* PARSE_STATE_BEGIN_OF_LINE
|
||||
*
|
||||
* Whenever the parser find an empty line or the end-of-file
|
||||
* it dispatches the stacked event.
|
||||
*
|
||||
*/
|
||||
enum ParserStatus {
|
||||
PARSE_STATE_OFF,
|
||||
PARSE_STATE_BEGIN_OF_STREAM,
|
||||
PARSE_STATE_BOM_WAS_READ,
|
||||
PARSE_STATE_CR_CHAR,
|
||||
PARSE_STATE_COMMENT,
|
||||
PARSE_STATE_FIELD_NAME,
|
||||
PARSE_STATE_FIRST_CHAR_OF_FIELD_VALUE,
|
||||
PARSE_STATE_FIELD_VALUE,
|
||||
PARSE_STATE_BEGIN_OF_LINE
|
||||
};
|
||||
ParserStatus mStatus;
|
||||
|
||||
bool mFrozen;
|
||||
bool mErrorLoadOnRedirect;
|
||||
bool mGoingToDispatchAllMessages;
|
||||
bool mWithCredentials;
|
||||
bool mIsMainThread;
|
||||
// This is used to keep EventSourceImpl instance when there is a connection.
|
||||
bool mKeepingAlive;
|
||||
bool mWaitingForOnStopRequest;
|
||||
|
||||
void UpdateMustKeepAlive();
|
||||
void UpdateDontKeepAlive();
|
||||
// used while reading the input streams
|
||||
nsCOMPtr<nsIUnicodeDecoder> mUnicodeDecoder;
|
||||
nsresult mLastConvertionResult;
|
||||
nsString mLastFieldName;
|
||||
nsString mLastFieldValue;
|
||||
|
||||
nsCOMPtr<nsILoadGroup> mLoadGroup;
|
||||
|
||||
nsCOMPtr<nsIHttpChannel> mHttpChannel;
|
||||
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
|
||||
uint16_t mReadyState;
|
||||
nsString mOriginalURL;
|
||||
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
nsString mOrigin;
|
||||
|
||||
// Event Source owner information:
|
||||
// - the script file name
|
||||
// - source code line number and column number where the Event Source object
|
||||
// was constructed.
|
||||
// - the ID of the inner window where the script lives. Note that this may not
|
||||
// be the same as the Event Source owner window.
|
||||
// These attributes are used for error reporting.
|
||||
nsString mScriptFile;
|
||||
uint32_t mScriptLine;
|
||||
uint32_t mScriptColumn;
|
||||
uint64_t mInnerWindowID;
|
||||
|
||||
private:
|
||||
EventSource(const EventSource& x); // prevent bad usage
|
||||
EventSource& operator=(const EventSource& x);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
||||
+15
-116
@@ -797,22 +797,6 @@ FindChromeAccessOnlySubtreeOwner(nsIContent* aContent)
|
||||
return aContent;
|
||||
}
|
||||
|
||||
already_AddRefed<nsINode>
|
||||
FindChromeAccessOnlySubtreeOwner(EventTarget* aTarget)
|
||||
{
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(aTarget);
|
||||
if (!node || !node->ChromeOnlyAccess()) {
|
||||
return node.forget();
|
||||
}
|
||||
|
||||
if (!node->IsContent()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
node = FindChromeAccessOnlySubtreeOwner(node->AsContent());
|
||||
return node.forget();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsIContent::GetEventTargetParent(EventChainPreVisitor& aVisitor)
|
||||
{
|
||||
@@ -833,11 +817,24 @@ nsIContent::GetEventTargetParent(EventChainPreVisitor& aVisitor)
|
||||
// chrome access only subtree or if we are about to propagate out of
|
||||
// a shadow root to a shadow root host.
|
||||
((this == aVisitor.mEvent->mOriginalTarget &&
|
||||
!ChromeOnlyAccess()) || isAnonForEvents)) {
|
||||
!ChromeOnlyAccess()) || isAnonForEvents || GetShadowRoot())) {
|
||||
nsCOMPtr<nsIContent> relatedTarget =
|
||||
do_QueryInterface(aVisitor.mEvent->AsMouseEvent()->mRelatedTarget);
|
||||
if (relatedTarget &&
|
||||
relatedTarget->OwnerDoc() == OwnerDoc()) {
|
||||
|
||||
// In the web components case, we may need to stop propagation of events
|
||||
// at shadow root host.
|
||||
if (GetShadowRoot()) {
|
||||
nsIContent* adjustedTarget =
|
||||
Event::GetShadowRelatedTarget(this, relatedTarget);
|
||||
if (this == adjustedTarget) {
|
||||
aVisitor.SetParentTarget(nullptr, false);
|
||||
aVisitor.mCanHandle = false;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// If current target is anonymous for events or we know that related
|
||||
// target is descendant of an element which is anonymous for events,
|
||||
// we may want to stop event propagation.
|
||||
@@ -953,104 +950,6 @@ nsIContent::GetEventTargetParent(EventChainPreVisitor& aVisitor)
|
||||
} else {
|
||||
aVisitor.SetParentTarget(GetComposedDoc(), false);
|
||||
}
|
||||
|
||||
if (!ChromeOnlyAccess() && !aVisitor.mRelatedTargetRetargetedInCurrentScope) {
|
||||
// We don't support Shadow DOM in native anonymous content yet.
|
||||
aVisitor.mRelatedTargetRetargetedInCurrentScope = true;
|
||||
if (aVisitor.mEvent->mOriginalRelatedTarget) {
|
||||
// https://dom.spec.whatwg.org/#concept-event-dispatch
|
||||
// Step 3.
|
||||
// "Let relatedTarget be the result of retargeting event's relatedTarget
|
||||
// against target if event's relatedTarget is non-null, and null
|
||||
// otherwise."
|
||||
//
|
||||
// This is a bit complicated because the event might be from native
|
||||
// anonymous content, but we need to deal with non-native anonymous
|
||||
// content there.
|
||||
bool initialTarget = this == aVisitor.mEvent->mOriginalTarget;
|
||||
nsCOMPtr<nsINode> originalTargetAsNode;
|
||||
// Use of mOriginalTargetIsInAnon is an optimization here.
|
||||
if (!initialTarget && aVisitor.mOriginalTargetIsInAnon) {
|
||||
originalTargetAsNode =
|
||||
FindChromeAccessOnlySubtreeOwner(aVisitor.mEvent->mOriginalTarget);
|
||||
initialTarget = originalTargetAsNode == this;
|
||||
}
|
||||
if (initialTarget) {
|
||||
nsCOMPtr<nsINode> relatedTargetAsNode =
|
||||
FindChromeAccessOnlySubtreeOwner(aVisitor.mEvent->mOriginalRelatedTarget);
|
||||
if (!originalTargetAsNode) {
|
||||
originalTargetAsNode =
|
||||
do_QueryInterface(aVisitor.mEvent->mOriginalTarget);
|
||||
}
|
||||
|
||||
if (relatedTargetAsNode && originalTargetAsNode) {
|
||||
nsINode* retargetedRelatedTarget =
|
||||
nsContentUtils::Retarget(relatedTargetAsNode, originalTargetAsNode);
|
||||
if (originalTargetAsNode == retargetedRelatedTarget &&
|
||||
retargetedRelatedTarget != relatedTargetAsNode) {
|
||||
// Step 4.
|
||||
// "If target is relatedTarget and target is not event's
|
||||
// relatedTarget, then return true."
|
||||
aVisitor.IgnoreCurrentTargetBecauseOfShadowDOMRetargeting();
|
||||
// Old code relies on mTarget to point to the first element which
|
||||
// was not added to the event target chain because of mCanHandle
|
||||
// being false, but in Shadow DOM case mTarget really should
|
||||
// point to a node in Shadow DOM.
|
||||
aVisitor.mEvent->mTarget = aVisitor.mTargetInKnownToBeHandledScope;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Part of step 5. Retargeting target has happened already higher
|
||||
// up in this method.
|
||||
// "Append to an event path with event, target, targetOverride,
|
||||
// relatedTarget, and false."
|
||||
aVisitor.mRetargetedRelatedTarget = retargetedRelatedTarget;
|
||||
}
|
||||
} else {
|
||||
nsCOMPtr<nsINode> relatedTargetAsNode =
|
||||
FindChromeAccessOnlySubtreeOwner(aVisitor.mEvent->mOriginalRelatedTarget);
|
||||
if (relatedTargetAsNode) {
|
||||
// Step 11.3.
|
||||
// "Let relatedTarget be the result of retargeting event's
|
||||
// relatedTarget against parent if event's relatedTarget is non-null,
|
||||
// and null otherwise.".
|
||||
nsINode* retargetedRelatedTarget =
|
||||
nsContentUtils::Retarget(relatedTargetAsNode, this);
|
||||
nsCOMPtr<nsINode> targetInKnownToBeHandledScope =
|
||||
FindChromeAccessOnlySubtreeOwner(aVisitor.mTargetInKnownToBeHandledScope);
|
||||
if (nsContentUtils::ContentIsShadowIncludingDescendantOf(
|
||||
this, targetInKnownToBeHandledScope->SubtreeRoot())) {
|
||||
// Part of step 11.4.
|
||||
// "If target's root is a shadow-including inclusive ancestor of
|
||||
// parent, then"
|
||||
// "...Append to an event path with event, parent, null, relatedTarget,
|
||||
// " and slot-in-closed-tree."
|
||||
aVisitor.mRetargetedRelatedTarget = retargetedRelatedTarget;
|
||||
} else if (this == retargetedRelatedTarget) {
|
||||
// Step 11.5
|
||||
// "Otherwise, if parent and relatedTarget are identical, then set
|
||||
// parent to null."
|
||||
aVisitor.IgnoreCurrentTargetBecauseOfShadowDOMRetargeting();
|
||||
// Old code relies on mTarget to point to the first element which
|
||||
// was not added to the event target chain because of mCanHandle
|
||||
// being false, but in Shadow DOM case mTarget really should
|
||||
// point to a node in Shadow DOM.
|
||||
aVisitor.mEvent->mTarget = aVisitor.mTargetInKnownToBeHandledScope;
|
||||
return NS_OK;
|
||||
} else {
|
||||
// Step 11.6
|
||||
aVisitor.mRetargetedRelatedTarget = retargetedRelatedTarget;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (slot) {
|
||||
// Inform that we're about to exit the current scope.
|
||||
aVisitor.mRelatedTargetRetargetedInCurrentScope = false;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -2018,7 +1917,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(FragmentOrElement)
|
||||
}
|
||||
|
||||
nsAutoCString orphan;
|
||||
if (!tmp->IsInComposedDoc() &&
|
||||
if (!tmp->IsInUncomposedDoc() &&
|
||||
// Ignore xbl:content, which is never in the document and hence always
|
||||
// appears to be orphaned.
|
||||
!tmp->NodeInfo()->Equals(nsGkAtoms::content, kNameSpaceID_XBL)) {
|
||||
|
||||
@@ -1390,8 +1390,9 @@ Navigator::GetPlatform(nsAString& aPlatform, bool aUsePrefOverriddenValue)
|
||||
aPlatform.AssignLiteral("Win32");
|
||||
#elif defined(XP_MACOSX) && defined(__ppc__)
|
||||
aPlatform.AssignLiteral("MacPPC");
|
||||
#elif defined(XP_MACOSX)
|
||||
// Always return "MacIntel", even on ARM64 macOS like Safari does.
|
||||
#elif defined(XP_MACOSX) && defined(__i386__)
|
||||
aPlatform.AssignLiteral("MacIntel");
|
||||
#elif defined(XP_MACOSX) && defined(__x86_64__)
|
||||
aPlatform.AssignLiteral("MacIntel");
|
||||
#else
|
||||
// XXX Communicator uses compiled-in build-time string defines
|
||||
|
||||
+25
-58
@@ -9,7 +9,6 @@
|
||||
#include "mozilla/dom/DocumentFragment.h"
|
||||
#include "ChildIterator.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsDOMClassInfoID.h"
|
||||
#include "nsIDOMHTMLElement.h"
|
||||
#include "nsIStyleSheetLinkingElement.h"
|
||||
@@ -102,23 +101,6 @@ ShadowRoot::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
return mozilla::dom::ShadowRootBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
void
|
||||
ShadowRoot::CloneInternalDataFrom(ShadowRoot* aOther)
|
||||
{
|
||||
size_t sheetCount = aOther->SheetCount();
|
||||
for (size_t i = 0; i < sheetCount; ++i) {
|
||||
StyleSheet* sheet = aOther->SheetAt(i);
|
||||
if (sheet && sheet->IsApplicable()) {
|
||||
// TODO: Remove AsGecko() call once Stylo is removed.
|
||||
RefPtr<CSSStyleSheet> clonedSheet =
|
||||
sheet->AsGecko()->Clone(nullptr, nullptr, nullptr, nullptr);
|
||||
if (clonedSheet) {
|
||||
AppendStyleSheet(*clonedSheet);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ShadowRoot*
|
||||
ShadowRoot::FromNode(nsINode* aNode)
|
||||
{
|
||||
@@ -163,19 +145,6 @@ ShadowRoot::AddSlot(HTMLSlotElement* aSlot)
|
||||
|
||||
oldSlot->RemoveAssignedNode(assignedNode);
|
||||
currentSlot->AppendAssignedNode(assignedNode);
|
||||
|
||||
Element* restyleElement;
|
||||
if (assignedNode->IsElement()) {
|
||||
restyleElement = assignedNode->AsElement();
|
||||
} else {
|
||||
// This is likely a text node. Use the host instead.
|
||||
restyleElement = GetHost();
|
||||
}
|
||||
if (restyleElement) {
|
||||
nsLayoutUtils::PostRestyleEvent(
|
||||
restyleElement, eRestyle_Subtree, nsChangeHint(0));
|
||||
}
|
||||
|
||||
doEnqueueSlotChange = true;
|
||||
}
|
||||
|
||||
@@ -293,13 +262,6 @@ ShadowRoot::InsertSheet(StyleSheet* aSheet,
|
||||
}
|
||||
|
||||
nsINode* sheetOwningNode = SheetAt(i)->GetOwnerNode();
|
||||
|
||||
if (!sheetOwningNode) {
|
||||
// Keep moving; all sheets with a sheetOwner come after all
|
||||
// sheets without an owning Node
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nsContentUtils::PositionIsBefore(aLinkingContent, sheetOwningNode)) {
|
||||
InsertSheetAt(i, *aSheet);
|
||||
mProtoBinding->InsertStyleSheetAt(i, aSheet);
|
||||
@@ -349,8 +311,6 @@ ShadowRoot::GetEventTargetParent(EventChainPreVisitor& aVisitor)
|
||||
{
|
||||
aVisitor.mCanHandle = true;
|
||||
aVisitor.mRootOfClosedTree = IsClosed();
|
||||
// Inform that we're about to exit the current scope.
|
||||
aVisitor.mRelatedTargetRetargetedInCurrentScope = false;
|
||||
|
||||
// https://dom.spec.whatwg.org/#ref-for-get-the-parent%E2%91%A6
|
||||
if (!aVisitor.mEvent->mFlags.mComposed) {
|
||||
@@ -373,10 +333,12 @@ ShadowRoot::GetEventTargetParent(EventChainPreVisitor& aVisitor)
|
||||
nsIContent* shadowHost = GetHost();
|
||||
aVisitor.SetParentTarget(shadowHost, false);
|
||||
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(aVisitor.mEvent->mTarget));
|
||||
if (content && content->GetBindingParent() == shadowHost) {
|
||||
aVisitor.mEventTargetAtParent = shadowHost;
|
||||
}
|
||||
if (aVisitor.mOriginalTargetIsInAnon) {
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(aVisitor.mEvent->mTarget));
|
||||
if (content && content->GetBindingParent() == shadowHost) {
|
||||
aVisitor.mEventTargetAtParent = shadowHost;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -526,6 +488,25 @@ ShadowRoot::Host()
|
||||
return host->AsElement();
|
||||
}
|
||||
|
||||
bool
|
||||
ShadowRoot::ApplyAuthorStyles()
|
||||
{
|
||||
return mProtoBinding->InheritsStyle();
|
||||
}
|
||||
|
||||
void
|
||||
ShadowRoot::SetApplyAuthorStyles(bool aApplyAuthorStyles)
|
||||
{
|
||||
mProtoBinding->SetInheritsStyle(aApplyAuthorStyles);
|
||||
|
||||
nsIPresShell* shell = OwnerDoc()->GetShell();
|
||||
if (shell) {
|
||||
OwnerDoc()->BeginUpdate(UPDATE_STYLE);
|
||||
shell->RecordShadowStyleChange(this);
|
||||
OwnerDoc()->EndUpdate(UPDATE_STYLE);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ShadowRoot::AttributeChanged(nsIDocument* aDocument,
|
||||
Element* aElement,
|
||||
@@ -599,13 +580,6 @@ ShadowRoot::ContentInserted(nsIDocument* aDocument,
|
||||
if (slot && slot->GetContainingShadow() == this &&
|
||||
slot->AssignedNodes().IsEmpty()) {
|
||||
slot->EnqueueSlotChangeEvent();
|
||||
return;
|
||||
}
|
||||
|
||||
// XXX: The following makes the host destroy its frames and force a
|
||||
// restyle for cases where the content isn't slotted.
|
||||
if (aContainer == this) {
|
||||
DistributionChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -642,13 +616,6 @@ ShadowRoot::ContentRemoved(nsIDocument* aDocument,
|
||||
if (slot && slot->GetContainingShadow() == this &&
|
||||
slot->AssignedNodes().IsEmpty()) {
|
||||
slot->EnqueueSlotChangeEvent();
|
||||
return;
|
||||
}
|
||||
|
||||
// XXX: The following makes the host destroy its frames and force a
|
||||
// restyle for cases where the content isn't slotted.
|
||||
if (aContainer == this) {
|
||||
DistributionChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -59,16 +59,13 @@ public:
|
||||
// [deprecated] Shadow DOM v0
|
||||
void InsertSheet(StyleSheet* aSheet, nsIContent* aLinkingContent);
|
||||
void RemoveSheet(StyleSheet* aSheet);
|
||||
bool ApplyAuthorStyles();
|
||||
void SetApplyAuthorStyles(bool aApplyAuthorStyles);
|
||||
StyleSheetList* StyleSheets()
|
||||
{
|
||||
return &DocumentOrShadowRoot::EnsureDOMStyleSheets();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones internal state, for example stylesheets, of aOther to 'this'.
|
||||
*/
|
||||
void CloneInternalDataFrom(ShadowRoot* aOther);
|
||||
|
||||
/**
|
||||
* Distributes all the explicit children of the pool host to the content
|
||||
* insertion points in this ShadowRoot.
|
||||
|
||||
+26
-6
@@ -1402,6 +1402,32 @@ WebSocket::ConstructorCommon(const GlobalObject& aGlobal,
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(WebSocket)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(WebSocket)
|
||||
bool isBlack = tmp->IsBlack();
|
||||
if (isBlack || tmp->mKeepingAlive) {
|
||||
if (tmp->mListenerManager) {
|
||||
tmp->mListenerManager->MarkForCC();
|
||||
}
|
||||
if (!isBlack && tmp->PreservingWrapper()) {
|
||||
// This marks the wrapper black.
|
||||
tmp->GetWrapper();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(WebSocket)
|
||||
return tmp->IsBlack();
|
||||
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(WebSocket)
|
||||
return tmp->IsBlack();
|
||||
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(WebSocket,
|
||||
DOMEventTargetHelper)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(WebSocket,
|
||||
DOMEventTargetHelper)
|
||||
if (tmp->mImpl) {
|
||||
@@ -1418,12 +1444,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(WebSocket,
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
bool
|
||||
WebSocket::IsCertainlyAliveForCC() const
|
||||
{
|
||||
return mKeepingAlive;
|
||||
}
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(WebSocket)
|
||||
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
||||
|
||||
|
||||
@@ -45,8 +45,8 @@ public:
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(WebSocket, DOMEventTargetHelper)
|
||||
virtual bool IsCertainlyAliveForCC() const override;
|
||||
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_INHERITED(
|
||||
WebSocket, DOMEventTargetHelper)
|
||||
|
||||
// EventTarget
|
||||
virtual void EventListenerAdded(nsIAtom* aType) override;
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
<body>
|
||||
<div id="host"></div>
|
||||
<script>
|
||||
host.attachShadow({ mode: "open" }).innerHTML = '<input type="range" />';
|
||||
var s = host.createShadowRoot();
|
||||
s.innerHTML = '<input type="range" />';
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -3,7 +3,7 @@
|
||||
<body>
|
||||
<script>
|
||||
var x = document.createElement('span');
|
||||
x.attachShadow({ mode: "open" });
|
||||
x.createShadowRoot();
|
||||
x.id = 'a';
|
||||
</script>
|
||||
</body>
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<style>
|
||||
#foo {
|
||||
overflow: scroll;
|
||||
height: 100px;
|
||||
}
|
||||
</style>
|
||||
<div id="foo">
|
||||
Mozilla Firefox<br>
|
||||
Mozilla Firefox<br>
|
||||
Mozilla Firefox<br>
|
||||
Mozilla Firefox<br>
|
||||
Mozilla Firefox<br>
|
||||
Mozilla Firefox<br>
|
||||
Mozilla Firefox<br>
|
||||
Mozilla Firefox<br>
|
||||
Mozilla Firefox<br>
|
||||
Mozilla Firefox<br>
|
||||
Mozilla Firefox<br>
|
||||
Mozilla Firefox<br>
|
||||
Mozilla Firefox<br>
|
||||
Mozilla Firefox<br>
|
||||
Mozilla Firefox<br>
|
||||
Mozilla Firefox<br>
|
||||
Mozilla Firefox<br>
|
||||
Mozilla Firefox<br>
|
||||
<script>
|
||||
foo.createShadowRoot().innerHTML = "<content></content>";
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,17 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
function fun_0() {
|
||||
document.implementation.createDocument('', '', null).adoptNode(o2);
|
||||
}
|
||||
|
||||
o1 = document.createElement('map');
|
||||
o2 = document.createElement('iframe');
|
||||
document.documentElement.appendChild(o1);
|
||||
document.documentElement.appendChild(o2);
|
||||
o1.textContent = 'x';
|
||||
document.addEventListener('DOMNodeRemoved', fun_0, false);
|
||||
o1.innerText = 'x';
|
||||
</script>
|
||||
</head>
|
||||
</html>
|
||||
@@ -209,7 +209,6 @@ load 1230422.html
|
||||
load 1251361.html
|
||||
load 1304437.html
|
||||
pref(clipboard.autocopy,true) load 1385272-1.html
|
||||
load 1393806.html
|
||||
pref(dom.webcomponents.enabled,true) load 1341693.html
|
||||
pref(dom.webcomponents.enabled,true) load 1419799.html
|
||||
pref(dom.webcomponents.enabled,false) load 1422931.html
|
||||
+3
-4
@@ -222,7 +222,7 @@ EXPORTS.mozilla.dom += [
|
||||
'WindowOrientationObserver.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
SOURCES += [
|
||||
'AnonymousContent.cpp',
|
||||
'Attr.cpp',
|
||||
'BarProps.cpp',
|
||||
@@ -238,6 +238,7 @@ UNIFIED_SOURCES += [
|
||||
'DirectionalityUtils.cpp',
|
||||
'DocGroup.cpp',
|
||||
'DocumentFragment.cpp',
|
||||
'DocumentOrShadowRoot.cpp',
|
||||
'DocumentType.cpp',
|
||||
'DOMCursor.cpp',
|
||||
'DOMError.cpp',
|
||||
@@ -372,14 +373,12 @@ UNIFIED_SOURCES += [
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WEBRTC']:
|
||||
UNIFIED_SOURCES += [
|
||||
SOURCES += [
|
||||
'nsDOMDataChannel.cpp',
|
||||
]
|
||||
|
||||
# these files couldn't be in UNIFIED_SOURCES for now for reasons given below:
|
||||
SOURCES += [
|
||||
# DocumentOrShadowRoot conflicts with mozilla::dom::ShadowRoot
|
||||
'DocumentOrShadowRoot.cpp',
|
||||
# Several conflicts with other bindings.
|
||||
'DOMIntersectionObserver.cpp',
|
||||
# Because of OS X headers.
|
||||
|
||||
+8
-215
@@ -2248,34 +2248,6 @@ nsContentUtils::ContentIsHostIncludingDescendantOf(
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
nsContentUtils::ContentIsShadowIncludingDescendantOf(
|
||||
const nsINode* aPossibleDescendant, const nsINode* aPossibleAncestor)
|
||||
{
|
||||
MOZ_ASSERT(aPossibleDescendant, "The possible descendant is null!");
|
||||
MOZ_ASSERT(aPossibleAncestor, "The possible ancestor is null!");
|
||||
|
||||
if (aPossibleAncestor == aPossibleDescendant->GetComposedDoc()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
do {
|
||||
if (aPossibleDescendant == aPossibleAncestor) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aPossibleDescendant->NodeType() == nsIDOMNode::DOCUMENT_FRAGMENT_NODE) {
|
||||
ShadowRoot* shadowRoot =
|
||||
ShadowRoot::FromNode(const_cast<nsINode*>(aPossibleDescendant));
|
||||
aPossibleDescendant = shadowRoot ? shadowRoot->GetHost() : nullptr;
|
||||
} else {
|
||||
aPossibleDescendant = aPossibleDescendant->GetParentNode();
|
||||
}
|
||||
} while (aPossibleDescendant);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
bool
|
||||
nsContentUtils::ContentIsCrossDocDescendantOf(nsINode* aPossibleDescendant,
|
||||
@@ -2294,30 +2266,6 @@ nsContentUtils::ContentIsCrossDocDescendantOf(nsINode* aPossibleDescendant,
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
nsINode*
|
||||
nsContentUtils::Retarget(nsINode* aTargetA, nsINode* aTargetB)
|
||||
{
|
||||
while (true && aTargetA) {
|
||||
// If A's root is not a shadow root...
|
||||
nsINode* root = aTargetA->SubtreeRoot();
|
||||
// TODO: replace with IsShadowRoot() check once bug 1427511 lands.
|
||||
if (!ShadowRoot::FromNode(root)) {
|
||||
// ...then return A.
|
||||
return aTargetA;
|
||||
}
|
||||
|
||||
// or A's root is a shadow-including inclusive ancestor of B...
|
||||
if (nsContentUtils::ContentIsShadowIncludingDescendantOf(aTargetB, root)) {
|
||||
// ...then return A.
|
||||
return aTargetA;
|
||||
}
|
||||
|
||||
aTargetA = ShadowRoot::FromNode(root)->GetHost();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
@@ -2429,56 +2377,6 @@ nsContentUtils::GetCommonAncestor(nsINode* aNode1,
|
||||
return parent;
|
||||
}
|
||||
|
||||
// static
|
||||
nsINode*
|
||||
nsContentUtils::GetCommonAncestorUnderInteractiveContent(nsINode* aNode1,
|
||||
nsINode* aNode2)
|
||||
{
|
||||
if (!aNode1 || !aNode2) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aNode1 == aNode2) {
|
||||
return aNode1;
|
||||
}
|
||||
|
||||
// Build the chain of parents
|
||||
AutoTArray<nsINode*, 30> parents1;
|
||||
do {
|
||||
parents1.AppendElement(aNode1);
|
||||
if (aNode1->IsElement() &&
|
||||
aNode1->AsElement()->IsInteractiveHTMLContent(true)) {
|
||||
break;
|
||||
}
|
||||
aNode1 = aNode1->GetFlattenedTreeParentNode();
|
||||
} while (aNode1);
|
||||
|
||||
AutoTArray<nsINode*, 30> parents2;
|
||||
do {
|
||||
parents2.AppendElement(aNode2);
|
||||
if (aNode2->IsElement() &&
|
||||
aNode2->AsElement()->IsInteractiveHTMLContent(true)) {
|
||||
break;
|
||||
}
|
||||
aNode2 = aNode2->GetFlattenedTreeParentNode();
|
||||
} while (aNode2);
|
||||
|
||||
// Find where the parent chain differs
|
||||
uint32_t pos1 = parents1.Length();
|
||||
uint32_t pos2 = parents2.Length();
|
||||
nsINode* parent = nullptr;
|
||||
for (uint32_t len = std::min(pos1, pos2); len > 0; --len) {
|
||||
nsINode* child1 = parents1.ElementAt(--pos1);
|
||||
nsINode* child2 = parents2.ElementAt(--pos2);
|
||||
if (child1 != child2) {
|
||||
break;
|
||||
}
|
||||
parent = child1;
|
||||
}
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool
|
||||
nsContentUtils::PositionIsBefore(nsINode* aNode1, nsINode* aNode2)
|
||||
@@ -6434,7 +6332,9 @@ nsContentUtils::IsFocusedContent(const nsIContent* aContent)
|
||||
bool
|
||||
nsContentUtils::IsSubDocumentTabbable(nsIContent* aContent)
|
||||
{
|
||||
nsIDocument* doc = aContent->GetComposedDoc();
|
||||
//XXXsmaug Shadow DOM spec issue!
|
||||
// We may need to change this to GetComposedDoc().
|
||||
nsIDocument* doc = aContent->GetUncomposedDoc();
|
||||
if (!doc) {
|
||||
return false;
|
||||
}
|
||||
@@ -7156,26 +7056,16 @@ nsContentUtils::HasDistributedChildren(nsIContent* aContent)
|
||||
|
||||
// static
|
||||
bool
|
||||
nsContentUtils::IsForbiddenRequestHeader(const nsACString& aHeader,
|
||||
const nsACString& aValue)
|
||||
nsContentUtils::IsForbiddenRequestHeader(const nsACString& aHeader)
|
||||
{
|
||||
if (IsForbiddenSystemRequestHeader(aHeader)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((nsContentUtils::IsOverrideMethodHeader(aHeader) &&
|
||||
nsContentUtils::ContainsForbiddenMethod(aValue))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (StringBeginsWith(aHeader, NS_LITERAL_CSTRING("proxy-"),
|
||||
nsCaseInsensitiveCStringComparator()) ||
|
||||
StringBeginsWith(aHeader, NS_LITERAL_CSTRING("sec-"),
|
||||
nsCaseInsensitiveCStringComparator())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return StringBeginsWith(aHeader, NS_LITERAL_CSTRING("proxy-"),
|
||||
nsCaseInsensitiveCStringComparator()) ||
|
||||
StringBeginsWith(aHeader, NS_LITERAL_CSTRING("sec-"),
|
||||
nsCaseInsensitiveCStringComparator());
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -7204,64 +7094,6 @@ nsContentUtils::IsForbiddenResponseHeader(const nsACString& aHeader)
|
||||
aHeader.LowerCaseEqualsASCII("set-cookie2"));
|
||||
}
|
||||
|
||||
// static
|
||||
bool
|
||||
nsContentUtils::IsOverrideMethodHeader(const nsACString& headerName) {
|
||||
return headerName.LowerCaseEqualsASCII("x-http-method-override") ||
|
||||
headerName.LowerCaseEqualsASCII("x-http-method") ||
|
||||
headerName.LowerCaseEqualsASCII("x-method-override");
|
||||
}
|
||||
|
||||
// static
|
||||
bool
|
||||
nsContentUtils::ContainsForbiddenMethod(const nsACString& headerValue) {
|
||||
bool hasInsecureMethod = false;
|
||||
nsCCharSeparatedTokenizer tokenizer(headerValue, ',');
|
||||
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
const nsDependentCSubstring& value = tokenizer.nextToken();
|
||||
|
||||
if (value.LowerCaseEqualsASCII("connect") ||
|
||||
value.LowerCaseEqualsASCII("trace") ||
|
||||
value.LowerCaseEqualsASCII("track")) {
|
||||
hasInsecureMethod = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return hasInsecureMethod;
|
||||
}
|
||||
|
||||
// static
|
||||
bool nsContentUtils::IsCorsUnsafeRequestHeaderValue(
|
||||
const nsACString& aHeaderValue) {
|
||||
const char* cur = aHeaderValue.BeginReading();
|
||||
const char* end = aHeaderValue.EndReading();
|
||||
|
||||
while (cur != end) {
|
||||
// Implementation of
|
||||
// https://fetch.spec.whatwg.org/#cors-unsafe-request-header-byte Is less
|
||||
// than a space but not a horizontal tab
|
||||
if ((*cur < ' ' && *cur != '\t') || *cur == '"' || *cur == '(' ||
|
||||
*cur == ')' || *cur == ':' || *cur == '<' || *cur == '>' ||
|
||||
*cur == '?' || *cur == '@' || *cur == '[' || *cur == '\\' ||
|
||||
*cur == ']' || *cur == '{' || *cur == '}' ||
|
||||
*cur == 0x7F) { // 0x75 is DEL
|
||||
return true;
|
||||
}
|
||||
cur++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
bool nsContentUtils::IsAllowedNonCorsAccept(const nsACString& aHeaderValue) {
|
||||
if (IsCorsUnsafeRequestHeaderValue(aHeaderValue)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
bool
|
||||
nsContentUtils::IsAllowedNonCorsContentType(const nsACString& aHeaderValue)
|
||||
@@ -7269,10 +7101,6 @@ nsContentUtils::IsAllowedNonCorsContentType(const nsACString& aHeaderValue)
|
||||
nsAutoCString contentType;
|
||||
nsAutoCString unused;
|
||||
|
||||
if (IsCorsUnsafeRequestHeaderValue(aHeaderValue)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsresult rv = NS_ParseRequestContentType(aHeaderValue, contentType, unused);
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
@@ -7283,41 +7111,6 @@ nsContentUtils::IsAllowedNonCorsContentType(const nsACString& aHeaderValue)
|
||||
contentType.LowerCaseEqualsLiteral("multipart/form-data");
|
||||
}
|
||||
|
||||
// static
|
||||
bool nsContentUtils::IsAllowedNonCorsLanguage(const nsACString& aHeaderValue) {
|
||||
const char* cur = aHeaderValue.BeginReading();
|
||||
const char* end = aHeaderValue.EndReading();
|
||||
|
||||
while (cur != end) {
|
||||
if ((*cur >= '0' && *cur <= '9') || (*cur >= 'A' && *cur <= 'Z') ||
|
||||
(*cur >= 'a' && *cur <= 'z') || *cur == ' ' || *cur == '*' ||
|
||||
*cur == ',' || *cur == '-' || *cur == '.' || *cur == ';' ||
|
||||
*cur == '=') {
|
||||
cur++;
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
bool nsContentUtils::IsCORSSafelistedRequestHeader(const nsACString& aName,
|
||||
const nsACString& aValue) {
|
||||
// See https://fetch.spec.whatwg.org/#cors-safelisted-request-header
|
||||
if (aValue.Length() > 128) {
|
||||
return false;
|
||||
}
|
||||
return (aName.LowerCaseEqualsLiteral("accept") &&
|
||||
nsContentUtils::IsAllowedNonCorsAccept(aValue)) ||
|
||||
(aName.LowerCaseEqualsLiteral("accept-language") &&
|
||||
nsContentUtils::IsAllowedNonCorsLanguage(aValue)) ||
|
||||
(aName.LowerCaseEqualsLiteral("content-language") &&
|
||||
nsContentUtils::IsAllowedNonCorsLanguage(aValue)) ||
|
||||
(aName.LowerCaseEqualsLiteral("content-type") &&
|
||||
nsContentUtils::IsAllowedNonCorsContentType(aValue));
|
||||
}
|
||||
|
||||
bool
|
||||
nsContentUtils::DOMWindowDumpEnabled()
|
||||
{
|
||||
|
||||
@@ -279,13 +279,6 @@ public:
|
||||
static bool ContentIsHostIncludingDescendantOf(
|
||||
const nsINode* aPossibleDescendant, const nsINode* aPossibleAncestor);
|
||||
|
||||
/**
|
||||
* Similar to above, but does special case only ShadowRoot,
|
||||
* not HTMLTemplateElement.
|
||||
*/
|
||||
static bool ContentIsShadowIncludingDescendantOf(
|
||||
const nsINode* aPossibleDescendant, const nsINode* aPossibleAncestor);
|
||||
|
||||
/**
|
||||
* Similar to ContentIsDescendantOf except it crosses document boundaries,
|
||||
* this function uses ancestor/descendant relations in the composed document
|
||||
@@ -294,13 +287,6 @@ public:
|
||||
static bool ContentIsCrossDocDescendantOf(nsINode* aPossibleDescendant,
|
||||
nsINode* aPossibleAncestor);
|
||||
|
||||
/**
|
||||
* Retarget an object A against an object B
|
||||
* @see https://dom.spec.whatwg.org/#retarget
|
||||
*/
|
||||
static nsINode*
|
||||
Retarget(nsINode* aTargetA, nsINode* aTargetB);
|
||||
|
||||
/*
|
||||
* This method fills the |aArray| with all ancestor nodes of |aNode|
|
||||
* including |aNode| at the zero index.
|
||||
@@ -338,15 +324,6 @@ public:
|
||||
static nsINode* GetCommonAncestor(nsINode* aNode1,
|
||||
nsINode* aNode2);
|
||||
|
||||
/**
|
||||
* Returns the common ancestor under interactive content, if any.
|
||||
* If neither one has interactive content as ancestor, common ancestor will be
|
||||
* returned. If only one has interactive content as ancestor, null will be
|
||||
* returned. If the nodes are the same, that node is returned.
|
||||
*/
|
||||
static nsINode* GetCommonAncestorUnderInteractiveContent(nsINode* aNode1,
|
||||
nsINode* aNode2);
|
||||
|
||||
/**
|
||||
* Returns true if aNode1 is before aNode2 in the same connected
|
||||
* tree.
|
||||
@@ -2448,8 +2425,7 @@ public:
|
||||
* Returns whether a given header is forbidden for an XHR or fetch
|
||||
* request.
|
||||
*/
|
||||
static bool IsForbiddenRequestHeader(const nsACString& aHeader,
|
||||
const nsACString& aValue);
|
||||
static bool IsForbiddenRequestHeader(const nsACString& aHeader);
|
||||
|
||||
/**
|
||||
* Returns whether a given header is forbidden for a system XHR
|
||||
@@ -2457,50 +2433,18 @@ public:
|
||||
*/
|
||||
static bool IsForbiddenSystemRequestHeader(const nsACString& aHeader);
|
||||
|
||||
/**
|
||||
* Returns whether a given header has characters that aren't permitted
|
||||
*/
|
||||
static bool IsCorsUnsafeRequestHeaderValue(const nsACString& aHeaderValue);
|
||||
|
||||
/**
|
||||
* Returns whether a given Accept header value is allowed
|
||||
* for a non-CORS XHR or fetch request.
|
||||
*/
|
||||
static bool IsAllowedNonCorsAccept(const nsACString& aHeaderValue);
|
||||
|
||||
/**
|
||||
* Returns whether a given Content-Type header value is allowed
|
||||
* for a non-CORS XHR or fetch request.
|
||||
*/
|
||||
static bool IsAllowedNonCorsContentType(const nsACString& aHeaderValue);
|
||||
|
||||
/**
|
||||
* Returns whether a given Content-Language or accept-language header value is
|
||||
* allowed for a non-CORS XHR or fetch request.
|
||||
*/
|
||||
static bool IsAllowedNonCorsLanguage(const nsACString& aHeaderValue);
|
||||
|
||||
/**
|
||||
* Returns whether a given header and value is a CORS-safelisted request
|
||||
* header per https://fetch.spec.whatwg.org/#cors-safelisted-request-header
|
||||
*/
|
||||
static bool IsCORSSafelistedRequestHeader(const nsACString& aName,
|
||||
const nsACString& aValue);
|
||||
|
||||
/**
|
||||
* Returns whether a given header is forbidden for an XHR or fetch
|
||||
* response.
|
||||
*/
|
||||
static bool IsForbiddenResponseHeader(const nsACString& aHeader);
|
||||
|
||||
/**
|
||||
* Checks whether the header overrides any http methods
|
||||
*/
|
||||
static bool IsOverrideMethodHeader(const nsACString& headerName);
|
||||
/**
|
||||
* Checks whether the header value contains any forbidden method
|
||||
*/
|
||||
static bool ContainsForbiddenMethod(const nsACString& headerValue);
|
||||
/**
|
||||
* Returns the inner window ID for the window associated with a request,
|
||||
*/
|
||||
|
||||
@@ -2367,6 +2367,75 @@ nsDOMWindowUtils::GetCurrentAudioBackend(nsAString& aBackend)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::StartFrameTimeRecording(uint32_t *startIndex)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(startIndex);
|
||||
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (!widget)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
LayerManager *mgr = widget->GetLayerManager();
|
||||
if (!mgr)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
const uint32_t kRecordingMinSize = 60 * 10; // 10 seconds @60 fps.
|
||||
const uint32_t kRecordingMaxSize = 60 * 60 * 60; // One hour
|
||||
uint32_t bufferSize = Preferences::GetUint("toolkit.framesRecording.bufferSize", uint32_t(0));
|
||||
bufferSize = std::min(bufferSize, kRecordingMaxSize);
|
||||
bufferSize = std::max(bufferSize, kRecordingMinSize);
|
||||
*startIndex = mgr->StartFrameTimeRecording(bufferSize);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::StopFrameTimeRecording(uint32_t startIndex,
|
||||
uint32_t *frameCount,
|
||||
float **frameIntervals)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(frameCount);
|
||||
NS_ENSURE_ARG_POINTER(frameIntervals);
|
||||
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (!widget)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
LayerManager *mgr = widget->GetLayerManager();
|
||||
if (!mgr)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsTArray<float> tmpFrameIntervals;
|
||||
mgr->StopFrameTimeRecording(startIndex, tmpFrameIntervals);
|
||||
*frameCount = tmpFrameIntervals.Length();
|
||||
|
||||
*frameIntervals = (float*)moz_xmalloc(*frameCount * sizeof(float));
|
||||
|
||||
/* copy over the frame intervals and paint times into the arrays we just allocated */
|
||||
for (uint32_t i = 0; i < *frameCount; i++) {
|
||||
(*frameIntervals)[i] = tmpFrameIntervals[i];
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::BeginTabSwitch()
|
||||
{
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (!widget)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
LayerManager *mgr = widget->GetLayerManager();
|
||||
if (!mgr)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
mgr->BeginTabSwitch();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static bool
|
||||
ComputeAnimationValue(nsCSSPropertyID aProperty,
|
||||
Element* aElement,
|
||||
@@ -2409,7 +2478,7 @@ nsDOMWindowUtils::AdvanceTimeAndRefresh(int64_t aMilliseconds)
|
||||
|
||||
nsPresContext* presContext = GetPresContext();
|
||||
if (presContext) {
|
||||
RefPtr<nsRefreshDriver> driver = presContext->RefreshDriver();
|
||||
nsRefreshDriver* driver = presContext->RefreshDriver();
|
||||
driver->AdvanceTimeAndRefresh(aMilliseconds);
|
||||
|
||||
RefPtr<LayerTransactionChild> transaction = GetLayerTransaction();
|
||||
|
||||
+163
-46
@@ -2504,21 +2504,6 @@ nsDocument::InitCSP(nsIChannel* aChannel)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If this is explicitly loaded as a data document, no need to set a CSP.
|
||||
if (mLoadedAsData) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If this is an image, no need to set a CSP.
|
||||
// If we don't do this, SVG images will be parsed as normal XML documents and
|
||||
// subject to served CSPs, which might block internally applied inline styles.
|
||||
// See UXP issue #1959.
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
|
||||
if (loadInfo->GetExternalContentPolicyType() ==
|
||||
nsIContentPolicy::TYPE_IMAGE) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoCString tCspHeaderValue, tCspROHeaderValue;
|
||||
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel;
|
||||
@@ -2547,6 +2532,7 @@ nsDocument::InitCSP(nsIChannel* aChannel)
|
||||
|
||||
// Check if this is a signed content to apply default CSP.
|
||||
bool applySignedContentCSP = false;
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
|
||||
if (loadInfo && loadInfo->GetVerifySignedContent()) {
|
||||
applySignedContentCSP = true;
|
||||
}
|
||||
@@ -3120,6 +3106,106 @@ nsDocument::ElementFromPoint(float aX, float aY, nsIDOMElement** aReturn)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
Element*
|
||||
nsIDocument::ElementFromPoint(float aX, float aY)
|
||||
{
|
||||
return ElementFromPointHelper(aX, aY, false, true);
|
||||
}
|
||||
|
||||
void
|
||||
nsIDocument::ElementsFromPoint(float aX, float aY,
|
||||
nsTArray<RefPtr<Element>>& aElements)
|
||||
{
|
||||
ElementsFromPointHelper(aX, aY, nsIDocument::FLUSH_LAYOUT, aElements);
|
||||
}
|
||||
|
||||
Element*
|
||||
nsDocument::ElementFromPointHelper(float aX, float aY,
|
||||
bool aIgnoreRootScrollFrame,
|
||||
bool aFlushLayout)
|
||||
{
|
||||
AutoTArray<RefPtr<Element>, 1> elementArray;
|
||||
ElementsFromPointHelper(aX, aY,
|
||||
((aIgnoreRootScrollFrame ? nsIDocument::IGNORE_ROOT_SCROLL_FRAME : 0) |
|
||||
(aFlushLayout ? nsIDocument::FLUSH_LAYOUT : 0) |
|
||||
nsIDocument::IS_ELEMENT_FROM_POINT),
|
||||
elementArray);
|
||||
if (elementArray.IsEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
return elementArray[0];
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::ElementsFromPointHelper(float aX, float aY,
|
||||
uint32_t aFlags,
|
||||
nsTArray<RefPtr<mozilla::dom::Element>>& aElements)
|
||||
{
|
||||
// As per the the spec, we return null if either coord is negative
|
||||
if (!(aFlags & nsIDocument::IGNORE_ROOT_SCROLL_FRAME) && (aX < 0 || aY < 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nscoord x = nsPresContext::CSSPixelsToAppUnits(aX);
|
||||
nscoord y = nsPresContext::CSSPixelsToAppUnits(aY);
|
||||
nsPoint pt(x, y);
|
||||
|
||||
// Make sure the layout information we get is up-to-date, and
|
||||
// ensure we get a root frame (for everything but XUL)
|
||||
if (aFlags & nsIDocument::FLUSH_LAYOUT) {
|
||||
FlushPendingNotifications(Flush_Layout);
|
||||
}
|
||||
|
||||
nsIPresShell *ps = GetShell();
|
||||
if (!ps) {
|
||||
return;
|
||||
}
|
||||
nsIFrame *rootFrame = ps->GetRootFrame();
|
||||
|
||||
// XUL docs, unlike HTML, have no frame tree until everything's done loading
|
||||
if (!rootFrame) {
|
||||
return; // return null to premature XUL callers as a reminder to wait
|
||||
}
|
||||
|
||||
nsTArray<nsIFrame*> outFrames;
|
||||
// Emulate what GetFrameAtPoint does, since we want all the frames under our
|
||||
// point.
|
||||
nsLayoutUtils::GetFramesForArea(rootFrame, nsRect(pt, nsSize(1, 1)), outFrames,
|
||||
nsLayoutUtils::IGNORE_PAINT_SUPPRESSION | nsLayoutUtils::IGNORE_CROSS_DOC |
|
||||
((aFlags & nsIDocument::IGNORE_ROOT_SCROLL_FRAME) ? nsLayoutUtils::IGNORE_ROOT_SCROLL_FRAME : 0));
|
||||
|
||||
// Dunno when this would ever happen, as we should at least have a root frame under us?
|
||||
if (outFrames.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Used to filter out repeated elements in sequence.
|
||||
nsIContent* lastAdded = nullptr;
|
||||
|
||||
for (uint32_t i = 0; i < outFrames.Length(); i++) {
|
||||
nsIContent* node = GetContentInThisDocument(outFrames[i]);
|
||||
|
||||
if (!node || !node->IsElement()) {
|
||||
// If this helper is called via ElementsFromPoint, we need to make sure
|
||||
// our frame is an element. Otherwise return whatever the top frame is
|
||||
// even if it isn't the top-painted element.
|
||||
if (!(aFlags & nsIDocument::IS_ELEMENT_FROM_POINT)) {
|
||||
continue;
|
||||
}
|
||||
node = node->GetParent();
|
||||
}
|
||||
if (node && node != lastAdded) {
|
||||
aElements.AppendElement(node->AsElement());
|
||||
lastAdded = node;
|
||||
// If this helper is called via ElementFromPoint, just return the first
|
||||
// element we find.
|
||||
if (aFlags & nsIDocument::IS_ELEMENT_FROM_POINT) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocument::NodesFromRectHelper(float aX, float aY,
|
||||
float aTopSize, float aRightSize,
|
||||
@@ -5823,9 +5909,14 @@ nsIDocument::ImportNode(nsINode& aNode, bool aDeep, ErrorResult& rv) const
|
||||
case nsIDOMNode::COMMENT_NODE:
|
||||
case nsIDOMNode::DOCUMENT_TYPE_NODE:
|
||||
{
|
||||
nsCOMPtr<nsINode> newNode;
|
||||
nsCOMArray<nsINode> nodesWithProperties;
|
||||
return nsNodeUtils::Clone(imported, aDeep, mNodeInfoManager,
|
||||
&nodesWithProperties, rv);
|
||||
rv = nsNodeUtils::Clone(imported, aDeep, mNodeInfoManager,
|
||||
nodesWithProperties, getter_AddRefs(newNode));
|
||||
if (rv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
return newNode.forget();
|
||||
}
|
||||
default:
|
||||
{
|
||||
@@ -6986,8 +7077,8 @@ nsIDocument::AdoptNode(nsINode& aAdoptedNode, ErrorResult& rv)
|
||||
}
|
||||
|
||||
nsCOMArray<nsINode> nodesWithProperties;
|
||||
nsNodeUtils::Adopt(adoptedNode, sameDocument ? nullptr : mNodeInfoManager,
|
||||
newScope, nodesWithProperties, rv);
|
||||
rv = nsNodeUtils::Adopt(adoptedNode, sameDocument ? nullptr : mNodeInfoManager,
|
||||
newScope, nodesWithProperties);
|
||||
if (rv.Failed()) {
|
||||
// Disconnect all nodes from their parents, since some have the old document
|
||||
// as their ownerDocument and some have this as their ownerDocument.
|
||||
@@ -8282,7 +8373,7 @@ nsDocument::DoUnblockOnload()
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
nsIDocument::GetContentInThisDocument(nsIFrame* aFrame) const
|
||||
nsDocument::GetContentInThisDocument(nsIFrame* aFrame) const
|
||||
{
|
||||
for (nsIFrame* f = aFrame; f;
|
||||
f = nsLayoutUtils::GetParentOrPlaceholderForCrossDoc(f)) {
|
||||
@@ -8493,7 +8584,7 @@ nsDocument::OnPageHide(bool aPersisted,
|
||||
EnumerateActivityObservers(NotifyActivityChanged, nullptr);
|
||||
|
||||
ClearPendingFullscreenRequests(this);
|
||||
if (FullScreenStackTop()) {
|
||||
if (GetFullscreenElement()) {
|
||||
// If this document was fullscreen, we should exit fullscreen in this
|
||||
// doctree branch. This ensures that if the user navigates while in
|
||||
// fullscreen mode we don't leave its still visible ancestor documents
|
||||
@@ -10197,7 +10288,7 @@ nsIDocument::AsyncExitFullscreen(nsIDocument* aDoc)
|
||||
static bool
|
||||
CountFullscreenSubDocuments(nsIDocument* aDoc, void* aData)
|
||||
{
|
||||
if (aDoc->FullScreenStackTop()) {
|
||||
if (aDoc->GetFullscreenElement()) {
|
||||
uint32_t* count = static_cast<uint32_t*>(aData);
|
||||
(*count)++;
|
||||
}
|
||||
@@ -10217,7 +10308,7 @@ nsDocument::IsFullscreenLeaf()
|
||||
{
|
||||
// A fullscreen leaf document is fullscreen, and has no fullscreen
|
||||
// subdocuments.
|
||||
if (!FullScreenStackTop()) {
|
||||
if (!GetFullscreenElement()) {
|
||||
return false;
|
||||
}
|
||||
return CountFullscreenSubDocuments(this) == 0;
|
||||
@@ -10226,11 +10317,11 @@ nsDocument::IsFullscreenLeaf()
|
||||
static bool
|
||||
ResetFullScreen(nsIDocument* aDocument, void* aData)
|
||||
{
|
||||
if (aDocument->FullScreenStackTop()) {
|
||||
if (aDocument->GetFullscreenElement()) {
|
||||
NS_ASSERTION(CountFullscreenSubDocuments(aDocument) <= 1,
|
||||
"Should have at most 1 fullscreen subdocument.");
|
||||
static_cast<nsDocument*>(aDocument)->CleanupFullscreenState();
|
||||
NS_ASSERTION(!aDocument->FullScreenStackTop(),
|
||||
NS_ASSERTION(!aDocument->GetFullscreenElement(),
|
||||
"Should reset full-screen");
|
||||
auto changed = reinterpret_cast<nsCOMArray<nsIDocument>*>(aData);
|
||||
changed->AppendElement(aDocument);
|
||||
@@ -10278,7 +10369,7 @@ nsIDocument::ExitFullscreenInDocTree(nsIDocument* aMaybeNotARootDoc)
|
||||
UnlockPointer();
|
||||
|
||||
nsCOMPtr<nsIDocument> root = aMaybeNotARootDoc->GetFullscreenRoot();
|
||||
if (!root || !root->FullScreenStackTop()) {
|
||||
if (!root || !root->GetFullscreenElement()) {
|
||||
// If a document was detached before exiting from fullscreen, it is
|
||||
// possible that the root had left fullscreen state. In this case,
|
||||
// we would not get anything from the ResetFullScreen() call. Root's
|
||||
@@ -10307,7 +10398,7 @@ nsIDocument::ExitFullscreenInDocTree(nsIDocument* aMaybeNotARootDoc)
|
||||
DispatchFullScreenChange(changed[changed.Length() - i - 1]);
|
||||
}
|
||||
|
||||
NS_ASSERTION(!root->FullScreenStackTop(),
|
||||
NS_ASSERTION(!root->GetFullscreenElement(),
|
||||
"Fullscreen root should no longer be a fullscreen doc...");
|
||||
|
||||
// Move the top-level window out of fullscreen mode.
|
||||
@@ -10324,7 +10415,7 @@ GetFullscreenLeaf(nsIDocument* aDoc, void* aData)
|
||||
nsIDocument** result = static_cast<nsIDocument**>(aData);
|
||||
*result = aDoc;
|
||||
return false;
|
||||
} else if (aDoc->FullScreenStackTop()) {
|
||||
} else if (aDoc->GetFullscreenElement()) {
|
||||
aDoc->EnumerateSubDocuments(GetFullscreenLeaf, aData);
|
||||
}
|
||||
return true;
|
||||
@@ -10343,7 +10434,7 @@ GetFullscreenLeaf(nsIDocument* aDoc)
|
||||
nsIDocument* root = nsContentUtils::GetRootDocument(aDoc);
|
||||
// Check that the root is actually fullscreen so we don't waste time walking
|
||||
// around its descendants.
|
||||
if (!root->FullScreenStackTop()) {
|
||||
if (!root->GetFullscreenElement()) {
|
||||
return nullptr;
|
||||
}
|
||||
GetFullscreenLeaf(root, &leaf);
|
||||
@@ -10353,10 +10444,10 @@ GetFullscreenLeaf(nsIDocument* aDoc)
|
||||
void
|
||||
nsDocument::RestorePreviousFullScreenState()
|
||||
{
|
||||
NS_ASSERTION(!FullScreenStackTop() || !FullscreenRoots::IsEmpty(),
|
||||
NS_ASSERTION(!GetFullscreenElement() || !FullscreenRoots::IsEmpty(),
|
||||
"Should have at least 1 fullscreen root when fullscreen!");
|
||||
|
||||
if (!FullScreenStackTop() || !GetWindow() || FullscreenRoots::IsEmpty()) {
|
||||
if (!GetFullscreenElement() || !GetWindow() || FullscreenRoots::IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -10531,7 +10622,7 @@ nsDocument::FullScreenStackPush(Element* aElement)
|
||||
}
|
||||
EventStateManager::SetFullScreenState(aElement, true);
|
||||
mFullScreenStack.AppendElement(do_GetWeakReference(aElement));
|
||||
NS_ASSERTION(FullScreenStackTop() == aElement, "Should match");
|
||||
NS_ASSERTION(GetFullscreenElement() == aElement, "Should match");
|
||||
UpdateViewportScrollbarOverrideForFullscreen(this);
|
||||
return true;
|
||||
}
|
||||
@@ -10579,7 +10670,7 @@ nsDocument::FullScreenStackTop()
|
||||
uint32_t last = mFullScreenStack.Length() - 1;
|
||||
nsCOMPtr<Element> element(do_QueryReferent(mFullScreenStack[last]));
|
||||
NS_ASSERTION(element, "Should have full-screen element!");
|
||||
NS_ASSERTION(element->IsInComposedDoc(), "Full-screen element should be in doc");
|
||||
NS_ASSERTION(element->IsInUncomposedDoc(), "Full-screen element should be in doc");
|
||||
NS_ASSERTION(element->OwnerDoc() == this, "Full-screen element should be in this doc");
|
||||
return element;
|
||||
}
|
||||
@@ -10657,7 +10748,7 @@ nsresult nsDocument::RemoteFrameFullscreenReverted()
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
nsIDocument::IsUnprefixedFullscreenEnabled(JSContext* aCx, JSObject* aObject)
|
||||
nsDocument::IsUnprefixedFullscreenEnabled(JSContext* aCx, JSObject* aObject)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
return nsContentUtils::IsCallerChrome() ||
|
||||
@@ -10705,10 +10796,10 @@ nsDocument::FullscreenElementReadyCheck(Element* aElement,
|
||||
{
|
||||
NS_ASSERTION(aElement,
|
||||
"Must pass non-null element to nsDocument::RequestFullScreen");
|
||||
if (!aElement || aElement == FullScreenStackTop()) {
|
||||
if (!aElement || aElement == GetFullscreenElement()) {
|
||||
return false;
|
||||
}
|
||||
if (!aElement->IsInComposedDoc()) {
|
||||
if (!aElement->IsInUncomposedDoc()) {
|
||||
DispatchFullscreenError("FullscreenDeniedNotInDocument");
|
||||
return false;
|
||||
}
|
||||
@@ -10732,11 +10823,8 @@ nsDocument::FullscreenElementReadyCheck(Element* aElement,
|
||||
DispatchFullscreenError("FullscreenDeniedSubDocFullScreen");
|
||||
return false;
|
||||
}
|
||||
//XXXsmaug Note, we don't follow the latest fullscreen spec here.
|
||||
// This whole check could be probably removed.
|
||||
if (FullScreenStackTop() &&
|
||||
!nsContentUtils::ContentIsHostIncludingDescendantOf(aElement,
|
||||
FullScreenStackTop())) {
|
||||
if (GetFullscreenElement() &&
|
||||
!nsContentUtils::ContentIsDescendantOf(aElement, GetFullscreenElement())) {
|
||||
// If this document is full-screen, only grant full-screen requests from
|
||||
// a descendant of the current full-screen element.
|
||||
DispatchFullscreenError("FullscreenDeniedNotDescendant");
|
||||
@@ -11096,6 +11184,16 @@ nsDocument::GetMozFullScreenElement(nsIDOMElement **aFullScreenElement)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
Element*
|
||||
nsDocument::GetFullscreenElement()
|
||||
{
|
||||
Element* element = FullScreenStackTop();
|
||||
NS_ASSERTION(!element ||
|
||||
element->State().HasState(NS_EVENT_STATE_FULL_SCREEN),
|
||||
"Fullscreen element should have fullscreen styles applied");
|
||||
return element;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocument::GetMozFullScreen(bool *aFullScreen)
|
||||
{
|
||||
@@ -11214,7 +11312,7 @@ GetPointerLockError(Element* aElement, Element* aCurrentLock,
|
||||
return "PointerLockDeniedInUse";
|
||||
}
|
||||
|
||||
if (!aElement->IsInComposedDoc()) {
|
||||
if (!aElement->IsInUncomposedDoc()) {
|
||||
return "PointerLockDeniedNotInDocument";
|
||||
}
|
||||
|
||||
@@ -11265,11 +11363,11 @@ ChangePointerLockedElement(Element* aElement, nsIDocument* aDocument,
|
||||
MOZ_ASSERT(aDocument);
|
||||
MOZ_ASSERT(aElement != aPointerLockedElement);
|
||||
if (aPointerLockedElement) {
|
||||
MOZ_ASSERT(aPointerLockedElement->GetComposedDoc() == aDocument);
|
||||
MOZ_ASSERT(aPointerLockedElement->GetUncomposedDoc() == aDocument);
|
||||
aPointerLockedElement->ClearPointerLock();
|
||||
}
|
||||
if (aElement) {
|
||||
MOZ_ASSERT(aElement->GetComposedDoc() == aDocument);
|
||||
MOZ_ASSERT(aElement->GetUncomposedDoc() == aDocument);
|
||||
aElement->SetPointerLock();
|
||||
EventStateManager::sPointerLockedElement = do_GetWeakReference(aElement);
|
||||
EventStateManager::sPointerLockedDoc = do_GetWeakReference(aDocument);
|
||||
@@ -11293,9 +11391,9 @@ PointerLockRequest::Run()
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocument);
|
||||
nsDocument* d = static_cast<nsDocument*>(doc.get());
|
||||
const char* error = nullptr;
|
||||
if (!e || !d || !e->GetComposedDoc()) {
|
||||
if (!e || !d || !e->GetUncomposedDoc()) {
|
||||
error = "PointerLockDeniedNotInDocument";
|
||||
} else if (e->GetComposedDoc() != d) {
|
||||
} else if (e->GetUncomposedDoc() != d) {
|
||||
error = "PointerLockDeniedMovedDocument";
|
||||
}
|
||||
if (!error) {
|
||||
@@ -11461,6 +11559,25 @@ nsDocument::GetMozPointerLockElement(nsIDOMElement** aPointerLockedElement)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
Element*
|
||||
nsIDocument::GetPointerLockElement()
|
||||
{
|
||||
nsCOMPtr<Element> pointerLockedElement =
|
||||
do_QueryReferent(EventStateManager::sPointerLockedElement);
|
||||
if (!pointerLockedElement) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Make sure pointer locked element is in the same document.
|
||||
nsCOMPtr<nsIDocument> pointerLockedDoc =
|
||||
do_QueryReferent(EventStateManager::sPointerLockedDoc);
|
||||
if (pointerLockedDoc != this) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return pointerLockedElement;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocument::Observe(nsISupports *aSubject,
|
||||
const char *aTopic,
|
||||
|
||||
+22
-1
@@ -692,6 +692,14 @@ public:
|
||||
nsIAtom* aAttrName,
|
||||
const nsAString& aAttrValue) const override;
|
||||
|
||||
virtual Element* ElementFromPointHelper(float aX, float aY,
|
||||
bool aIgnoreRootScrollFrame,
|
||||
bool aFlushLayout) override;
|
||||
|
||||
virtual void ElementsFromPointHelper(float aX, float aY,
|
||||
uint32_t aFlags,
|
||||
nsTArray<RefPtr<mozilla::dom::Element>>& aElements) override;
|
||||
|
||||
virtual nsresult NodesFromRectHelper(float aX, float aY,
|
||||
float aTopSize, float aRightSize,
|
||||
float aBottomSize, float aLeftSize,
|
||||
@@ -888,6 +896,8 @@ public:
|
||||
//
|
||||
already_AddRefed<nsSimpleContentList> BlockedTrackingNodes() const;
|
||||
|
||||
static bool IsUnprefixedFullscreenEnabled(JSContext* aCx, JSObject* aObject);
|
||||
|
||||
// Do the "fullscreen element ready check" from the fullscreen spec.
|
||||
// It returns true if the given element is allowed to go into fullscreen.
|
||||
bool FullscreenElementReadyCheck(Element* aElement, bool aWasCallerChrome);
|
||||
@@ -911,10 +921,11 @@ public:
|
||||
void FullScreenStackPop();
|
||||
|
||||
// Returns the top element from the full-screen stack.
|
||||
Element* FullScreenStackTop() override;
|
||||
Element* FullScreenStackTop();
|
||||
|
||||
// DOM-exposed fullscreen API
|
||||
bool FullscreenEnabled() override;
|
||||
Element* GetFullscreenElement() override;
|
||||
|
||||
void RequestPointerLock(Element* aElement) override;
|
||||
bool SetPointerLock(Element* aElement, int aCursorStyle);
|
||||
@@ -1304,6 +1315,16 @@ private:
|
||||
|
||||
nsresult InitCSP(nsIChannel* aChannel);
|
||||
|
||||
/**
|
||||
* Find the (non-anonymous) content in this document for aFrame. It will
|
||||
* be aFrame's content node if that content is in this document and not
|
||||
* anonymous. Otherwise, when aFrame is in a subdocument, we use the frame
|
||||
* element containing the subdocument containing aFrame, and/or find the
|
||||
* nearest non-anonymous ancestor in this document.
|
||||
* Returns null if there is no such element.
|
||||
*/
|
||||
nsIContent* GetContentInThisDocument(nsIFrame* aFrame) const;
|
||||
|
||||
// Just like EnableStyleSheetsForSet, but doesn't check whether
|
||||
// aSheetSet is null and allows the caller to control whether to set
|
||||
// aSheetSet as the preferred set in the CSSLoader.
|
||||
|
||||
+94
-639
@@ -8,12 +8,10 @@
|
||||
#include "nsFocusManager.h"
|
||||
|
||||
#include "AccessibleCaretEventHub.h"
|
||||
#include "ChildIterator.h"
|
||||
#include "nsAttrValueInlines.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsDocument.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIEditor.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIDOMChromeWindow.h"
|
||||
@@ -48,9 +46,7 @@
|
||||
|
||||
#include "mozilla/ContentEvents.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/ShadowRoot.h"
|
||||
#include "mozilla/dom/HTMLInputElement.h"
|
||||
#include "mozilla/dom/HTMLSlotElement.h"
|
||||
#include "mozilla/EventDispatcher.h"
|
||||
#include "mozilla/EventStateManager.h"
|
||||
#include "mozilla/EventStates.h"
|
||||
@@ -2976,378 +2972,6 @@ nsFocusManager::DetermineElementToMoveFocus(nsPIDOMWindowOuter* aWindow,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static bool
|
||||
IsHostOrSlot(nsIContent* aContent)
|
||||
{
|
||||
return aContent && (aContent->GetShadowRoot() ||
|
||||
aContent->IsHTMLElement(nsGkAtoms::slot));
|
||||
}
|
||||
|
||||
// Helper class to iterate contents in scope by traversing flattened tree
|
||||
// in tree order
|
||||
class MOZ_STACK_CLASS ScopedContentTraversal
|
||||
{
|
||||
public:
|
||||
ScopedContentTraversal(nsIContent* aStartContent, nsIContent* aOwner)
|
||||
: mCurrent(aStartContent)
|
||||
, mOwner(aOwner)
|
||||
{
|
||||
MOZ_ASSERT(aStartContent);
|
||||
}
|
||||
|
||||
void Next();
|
||||
void Prev();
|
||||
|
||||
void Reset()
|
||||
{
|
||||
SetCurrent(mOwner);
|
||||
}
|
||||
|
||||
nsIContent* GetCurrent()
|
||||
{
|
||||
return mCurrent;
|
||||
}
|
||||
|
||||
private:
|
||||
void SetCurrent(nsIContent* aContent)
|
||||
{
|
||||
mCurrent = aContent;
|
||||
}
|
||||
|
||||
nsIContent* mCurrent;
|
||||
nsIContent* mOwner;
|
||||
};
|
||||
|
||||
void
|
||||
ScopedContentTraversal::Next()
|
||||
{
|
||||
MOZ_ASSERT(mCurrent);
|
||||
|
||||
// Get mCurrent's first child if it's in the same scope.
|
||||
if (!IsHostOrSlot(mCurrent) || mCurrent == mOwner) {
|
||||
StyleChildrenIterator iter(mCurrent);
|
||||
nsIContent* child = iter.GetNextChild();
|
||||
if (child) {
|
||||
SetCurrent(child);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If mOwner has no children, END traversal
|
||||
if (mCurrent == mOwner) {
|
||||
SetCurrent(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
nsIContent* current = mCurrent;
|
||||
while (1) {
|
||||
// Create parent's iterator and move to current
|
||||
nsIContent* parent = current->GetFlattenedTreeParent();
|
||||
StyleChildrenIterator parentIter(parent);
|
||||
parentIter.Seek(current);
|
||||
|
||||
// Get next sibling of current
|
||||
if (nsIContent* next = parentIter.GetNextChild()) {
|
||||
SetCurrent(next);
|
||||
return;
|
||||
}
|
||||
|
||||
// If no next sibling and parent is mOwner, END traversal
|
||||
if (parent == mOwner) {
|
||||
SetCurrent(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
current = parent;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ScopedContentTraversal::Prev()
|
||||
{
|
||||
MOZ_ASSERT(mCurrent);
|
||||
|
||||
nsIContent* parent;
|
||||
nsIContent* last;
|
||||
if (mCurrent == mOwner) {
|
||||
// Get last child of mOwner
|
||||
StyleChildrenIterator ownerIter(mOwner, false /* aStartAtBeginning */);
|
||||
last = ownerIter.GetPreviousChild();
|
||||
|
||||
parent = last;
|
||||
} else {
|
||||
// Create parent's iterator and move to mCurrent
|
||||
parent = mCurrent->GetFlattenedTreeParent();
|
||||
StyleChildrenIterator parentIter(parent);
|
||||
parentIter.Seek(mCurrent);
|
||||
|
||||
// Get previous sibling
|
||||
last = parentIter.GetPreviousChild();
|
||||
}
|
||||
|
||||
while (last) {
|
||||
parent = last;
|
||||
if (parent->GetShadowRoot() ||
|
||||
parent->IsHTMLElement(nsGkAtoms::slot)) {
|
||||
// Skip contents in other scopes
|
||||
break;
|
||||
}
|
||||
|
||||
// Find last child
|
||||
StyleChildrenIterator iter(parent, false /* aStartAtBeginning */);
|
||||
last = iter.GetPreviousChild();
|
||||
}
|
||||
|
||||
// If parent is mOwner and no previous sibling remains, END traversal
|
||||
SetCurrent(parent == mOwner ? nullptr : parent);
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
nsFocusManager::FindOwner(nsIContent* aContent)
|
||||
{
|
||||
nsIContent* currentContent = aContent;
|
||||
while (currentContent) {
|
||||
nsIContent* parent = currentContent->GetFlattenedTreeParent();
|
||||
|
||||
// Shadow host / Slot
|
||||
if (IsHostOrSlot(parent)) {
|
||||
return parent;
|
||||
}
|
||||
|
||||
currentContent = parent;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Host and Slot elements need to be handled as if they had tabindex 0 even
|
||||
* when they don't have the attribute. This is a helper method to get the
|
||||
* right value for focus navigation. If aIsFocusable is passed, it is set to
|
||||
* true if the element itself is focusable.
|
||||
*/
|
||||
static int32_t
|
||||
HostOrSlotTabIndexValue(nsIContent* aContent,
|
||||
bool* aIsFocusable = nullptr)
|
||||
{
|
||||
MOZ_ASSERT(IsHostOrSlot(aContent));
|
||||
|
||||
if (aIsFocusable) {
|
||||
*aIsFocusable = false;
|
||||
nsIFrame* frame = aContent->GetPrimaryFrame();
|
||||
if (frame) {
|
||||
int32_t tabIndex;
|
||||
frame->IsFocusable(&tabIndex, 0);
|
||||
*aIsFocusable = tabIndex >= 0;
|
||||
}
|
||||
}
|
||||
|
||||
const nsAttrValue* attrVal =
|
||||
aContent->AsElement()->GetParsedAttr(nsGkAtoms::tabindex);
|
||||
if (!attrVal) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (attrVal->Type() == nsAttrValue::eInteger) {
|
||||
return attrVal->GetIntegerValue();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
nsFocusManager::GetNextTabbableContentInScope(nsIContent* aOwner,
|
||||
nsIContent* aStartContent,
|
||||
nsIContent* aOriginalStartContent,
|
||||
bool aForward,
|
||||
int32_t aCurrentTabIndex,
|
||||
bool aIgnoreTabIndex,
|
||||
bool aForDocumentNavigation,
|
||||
bool aSkipOwner)
|
||||
{
|
||||
MOZ_ASSERT(IsHostOrSlot(aOwner), "Scope owner should be host or slot");
|
||||
|
||||
if (!aSkipOwner && (aForward && aOwner == aStartContent)) {
|
||||
int32_t tabIndex = -1;
|
||||
nsIFrame* frame = aOwner->GetPrimaryFrame();
|
||||
if (frame && frame->IsFocusable(&tabIndex, false) && tabIndex >= 0) {
|
||||
return aOwner;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Iterate contents in scope
|
||||
//
|
||||
ScopedContentTraversal contentTraversal(aStartContent, aOwner);
|
||||
nsCOMPtr<nsIContent> iterContent;
|
||||
nsIContent* firstNonChromeOnly = aStartContent->IsInNativeAnonymousSubtree() ?
|
||||
aStartContent->FindFirstNonChromeOnlyAccessContent() : nullptr;
|
||||
while (1) {
|
||||
// Iterate tab index to find corresponding contents in scope
|
||||
|
||||
while (1) {
|
||||
// Iterate remaining contents in scope to find next content to focus
|
||||
|
||||
// Get next content
|
||||
aForward ? contentTraversal.Next() : contentTraversal.Prev();
|
||||
iterContent = contentTraversal.GetCurrent();
|
||||
|
||||
if (firstNonChromeOnly && firstNonChromeOnly == iterContent) {
|
||||
// We just broke out from the native anonymous content, so move
|
||||
// to the previous/next node of the native anonymous owner.
|
||||
if (aForward) {
|
||||
contentTraversal.Next();
|
||||
} else {
|
||||
contentTraversal.Prev();
|
||||
}
|
||||
iterContent = contentTraversal.GetCurrent();
|
||||
}
|
||||
|
||||
if (!iterContent) {
|
||||
// Reach the end
|
||||
break;
|
||||
}
|
||||
|
||||
// Get the tab index of the next element. For NAC we rely on frames.
|
||||
//XXXsmaug we should probably use frames also for Shadow DOM and special
|
||||
// case only display:contents elements.
|
||||
int32_t tabIndex = 0;
|
||||
if (iterContent->IsInNativeAnonymousSubtree() &&
|
||||
iterContent->GetPrimaryFrame()) {
|
||||
iterContent->GetPrimaryFrame()->IsFocusable(&tabIndex);
|
||||
} else if (IsHostOrSlot(iterContent)) {
|
||||
tabIndex = HostOrSlotTabIndexValue(iterContent);
|
||||
} else {
|
||||
iterContent->IsFocusable(&tabIndex);
|
||||
}
|
||||
if (tabIndex < 0 || !(aIgnoreTabIndex || tabIndex == aCurrentTabIndex)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!IsHostOrSlot(iterContent)) {
|
||||
nsCOMPtr<nsIContent> elementInFrame;
|
||||
bool checkSubDocument = true;
|
||||
if (aForDocumentNavigation &&
|
||||
TryDocumentNavigation(iterContent, &checkSubDocument,
|
||||
getter_AddRefs(elementInFrame))) {
|
||||
return elementInFrame;
|
||||
}
|
||||
if (!checkSubDocument) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (TryToMoveFocusToSubDocument(iterContent, aOriginalStartContent,
|
||||
aForward, aForDocumentNavigation,
|
||||
getter_AddRefs(elementInFrame))) {
|
||||
return elementInFrame;
|
||||
}
|
||||
|
||||
// Found content to focus
|
||||
return iterContent;
|
||||
}
|
||||
|
||||
// Search in scope owned by iterContent
|
||||
nsIContent* contentToFocus =
|
||||
GetNextTabbableContentInScope(iterContent, iterContent,
|
||||
aOriginalStartContent, aForward,
|
||||
aForward ? 1 : 0, aIgnoreTabIndex,
|
||||
aForDocumentNavigation,
|
||||
false /* aSkipOwner */);
|
||||
if (contentToFocus) {
|
||||
return contentToFocus;
|
||||
}
|
||||
};
|
||||
|
||||
// If already at lowest priority tab (0), end search completely.
|
||||
// A bit counterintuitive but true, tabindex order goes 1, 2, ... 32767, 0
|
||||
if (aCurrentTabIndex == (aForward ? 0 : 1)) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Continue looking for next highest priority tabindex
|
||||
aCurrentTabIndex = GetNextTabIndex(aOwner, aCurrentTabIndex, aForward);
|
||||
contentTraversal.Reset();
|
||||
}
|
||||
|
||||
// Return scope owner at last for backward navigation if its tabindex
|
||||
// is non-negative
|
||||
if (!aSkipOwner && !aForward) {
|
||||
int32_t tabIndex = -1;
|
||||
nsIFrame* frame = aOwner->GetPrimaryFrame();
|
||||
if (frame && frame->IsFocusable(&tabIndex, false) && tabIndex >= 0) {
|
||||
return aOwner;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
nsFocusManager::GetNextTabbableContentInAncestorScopes(
|
||||
nsIContent* aStartOwner,
|
||||
nsIContent** aStartContent,
|
||||
nsIContent* aOriginalStartContent,
|
||||
bool aForward,
|
||||
int32_t* aCurrentTabIndex,
|
||||
bool aIgnoreTabIndex,
|
||||
bool aForDocumentNavigation)
|
||||
{
|
||||
MOZ_ASSERT(aStartOwner == FindOwner(*aStartContent),
|
||||
"aStartOwner should be the scope owner of aStartContent");
|
||||
MOZ_ASSERT(IsHostOrSlot(aStartOwner), "scope owner should be host or slot");
|
||||
|
||||
nsIContent* owner = aStartOwner;
|
||||
nsIContent* startContent = *aStartContent;
|
||||
|
||||
while (IsHostOrSlot(owner)) {
|
||||
int32_t tabIndex = 0;
|
||||
if (IsHostOrSlot(startContent)) {
|
||||
tabIndex = HostOrSlotTabIndexValue(startContent);
|
||||
} else {
|
||||
startContent->IsFocusable(&tabIndex);
|
||||
}
|
||||
nsIContent* contentToFocus =
|
||||
GetNextTabbableContentInScope(owner, startContent, aOriginalStartContent,
|
||||
aForward, tabIndex, aIgnoreTabIndex,
|
||||
aForDocumentNavigation,
|
||||
false /* aSkipOwner */);
|
||||
if (contentToFocus) {
|
||||
return contentToFocus;
|
||||
}
|
||||
|
||||
startContent = owner;
|
||||
owner = FindOwner(startContent);
|
||||
}
|
||||
|
||||
// If not found in shadow DOM, search from the top level shadow host in light DOM
|
||||
*aStartContent = startContent;
|
||||
*aCurrentTabIndex = HostOrSlotTabIndexValue(startContent);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static nsIContent*
|
||||
GetTopLevelScopeOwner(nsIContent* aContent)
|
||||
{
|
||||
nsIContent* topLevelScopeOwner = nullptr;
|
||||
while (aContent) {
|
||||
if (HTMLSlotElement* slot = aContent->GetAssignedSlot()) {
|
||||
aContent = slot;
|
||||
} else if (ShadowRoot* shadowRoot = aContent->GetContainingShadow()) {
|
||||
aContent = shadowRoot->Host();
|
||||
topLevelScopeOwner = aContent;
|
||||
} else {
|
||||
// TODO: replaced with FromNode.
|
||||
if (HTMLSlotElement::FromContentOrNull(aContent)) {
|
||||
topLevelScopeOwner = aContent;
|
||||
}
|
||||
aContent = aContent->GetParent();
|
||||
}
|
||||
}
|
||||
|
||||
return topLevelScopeOwner;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFocusManager::GetNextTabbableContent(nsIPresShell* aPresShell,
|
||||
nsIContent* aRootContent,
|
||||
@@ -3365,163 +2989,70 @@ nsFocusManager::GetNextTabbableContent(nsIPresShell* aPresShell,
|
||||
if (!startContent)
|
||||
return NS_OK;
|
||||
|
||||
nsIContent* currentTopLevelScopeOwner = GetTopLevelScopeOwner(aStartContent);
|
||||
|
||||
LOGCONTENTNAVIGATION("GetNextTabbable: %s", aStartContent);
|
||||
LOGFOCUSNAVIGATION((" tabindex: %d", aCurrentTabIndex));
|
||||
|
||||
if (nsDocument::IsWebComponentsEnabled(aRootContent)) {
|
||||
// If aStartContent is a shadow host or slot in forward navigation,
|
||||
// search in scope owned by aStartContent.
|
||||
if (aForward && IsHostOrSlot(aStartContent)) {
|
||||
nsIContent* contentToFocus =
|
||||
GetNextTabbableContentInScope(aStartContent, aStartContent,
|
||||
aOriginalStartContent, aForward,
|
||||
aForward ? 1 : 0, aIgnoreTabIndex,
|
||||
aForDocumentNavigation,
|
||||
true /* aSkipOwner */);
|
||||
if (contentToFocus) {
|
||||
NS_ADDREF(*aResultContent = contentToFocus);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// If aStartContent is in a scope owned by Shadow DOM search from scope
|
||||
// including aStartContent.
|
||||
if (nsIContent* owner = FindOwner(aStartContent)) {
|
||||
nsIContent* contentToFocus =
|
||||
GetNextTabbableContentInAncestorScopes(owner,
|
||||
&aStartContent,
|
||||
aOriginalStartContent,
|
||||
aForward,
|
||||
&aCurrentTabIndex,
|
||||
aIgnoreTabIndex,
|
||||
aForDocumentNavigation);
|
||||
if (contentToFocus) {
|
||||
NS_ADDREF(*aResultContent = contentToFocus);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// If we reach here, it means no next tabbable content in shadow DOM.
|
||||
// We need to continue searching in light DOM, starting at the top level
|
||||
// shadow host in light DOM (updated aStartContent) and its tabindex
|
||||
// (updated aCurrentTabIndex).
|
||||
MOZ_ASSERT(!FindOwner(aStartContent),
|
||||
"aStartContent should not be owned by Shadow DOM at this point");
|
||||
}
|
||||
|
||||
nsPresContext* presContext = aPresShell->GetPresContext();
|
||||
|
||||
bool getNextFrame = true;
|
||||
nsCOMPtr<nsIContent> iterStartContent = aStartContent;
|
||||
// Iterate tab index to find corresponding contents
|
||||
while (1) {
|
||||
nsIFrame* frame = iterStartContent->GetPrimaryFrame();
|
||||
nsIFrame* startFrame = iterStartContent->GetPrimaryFrame();
|
||||
// if there is no frame, look for another content node that has a frame
|
||||
while (!frame) {
|
||||
if (!startFrame) {
|
||||
// if the root content doesn't have a frame, just return
|
||||
if (iterStartContent == aRootContent) {
|
||||
if (iterStartContent == aRootContent)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// look for the next or previous content node in tree order
|
||||
iterStartContent = aForward ? iterStartContent->GetNextNode()
|
||||
: iterStartContent->GetPreviousContent();
|
||||
if (!iterStartContent) {
|
||||
break;
|
||||
}
|
||||
|
||||
frame = iterStartContent->GetPrimaryFrame();
|
||||
// Host without frame, enter its scope.
|
||||
if (nsDocument::IsWebComponentsEnabled(aRootContent) &&
|
||||
(!frame && iterStartContent->GetShadowRoot())) {
|
||||
int32_t tabIndex = HostOrSlotTabIndexValue(iterStartContent);
|
||||
if (tabIndex >= 0 &&
|
||||
(aIgnoreTabIndex || aCurrentTabIndex == tabIndex)) {
|
||||
nsIContent* contentToFocus = GetNextTabbableContentInScope(
|
||||
iterStartContent, iterStartContent, aOriginalStartContent,
|
||||
aForward, aForward ? 1 : 0, aIgnoreTabIndex,
|
||||
aForDocumentNavigation, true /* aSkipOwner */);
|
||||
if (contentToFocus) {
|
||||
NS_ADDREF(*aResultContent = contentToFocus);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
iterStartContent = aForward ? iterStartContent->GetNextNode() : iterStartContent->GetPreviousContent();
|
||||
// we've already skipped over the initial focused content, so we
|
||||
// don't want to traverse frames.
|
||||
getNextFrame = false;
|
||||
if (iterStartContent)
|
||||
continue;
|
||||
|
||||
// otherwise, as a last attempt, just look at the root content
|
||||
iterStartContent = aRootContent;
|
||||
continue;
|
||||
}
|
||||
|
||||
// For tab navigation, pass false for aSkipPopupChecks so that we don't
|
||||
// iterate into or out of a popup. For document naviation pass true to
|
||||
// ignore these boundaries.
|
||||
nsCOMPtr<nsIFrameEnumerator> frameTraversal;
|
||||
if (frame) {
|
||||
// For tab navigation, pass false for aSkipPopupChecks so that we don't
|
||||
// iterate into or out of a popup. For document navigation, pass true to
|
||||
// ignore these boundaries.
|
||||
nsresult rv = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),
|
||||
presContext,
|
||||
frame,
|
||||
ePreOrder,
|
||||
false, // aVisual
|
||||
false, // aLockInScrollView
|
||||
true, // aFollowOOFs
|
||||
aForDocumentNavigation // aSkipPopupChecks
|
||||
);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsresult rv = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),
|
||||
presContext, startFrame,
|
||||
ePreOrder,
|
||||
false, // aVisual
|
||||
false, // aLockInScrollView
|
||||
true, // aFollowOOFs
|
||||
aForDocumentNavigation // aSkipPopupChecks
|
||||
);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (iterStartContent == aRootContent) {
|
||||
if (!aForward) {
|
||||
frameTraversal->Last();
|
||||
} else if (aRootContent->IsFocusable()) {
|
||||
frameTraversal->Next();
|
||||
}
|
||||
frame = static_cast<nsIFrame*>(frameTraversal->CurrentItem());
|
||||
} else if (getNextFrame &&
|
||||
(!iterStartContent ||
|
||||
!iterStartContent->IsHTMLElement(nsGkAtoms::area))) {
|
||||
// Need to do special check in case we're in an imagemap which has multiple
|
||||
// content nodes per frame, so don't skip over the starting frame.
|
||||
if (aForward) {
|
||||
frameTraversal->Next();
|
||||
} else {
|
||||
frameTraversal->Prev();
|
||||
}
|
||||
|
||||
frame = static_cast<nsIFrame*>(frameTraversal->CurrentItem());
|
||||
if (iterStartContent == aRootContent) {
|
||||
if (!aForward) {
|
||||
frameTraversal->Last();
|
||||
} else if (aRootContent->IsFocusable()) {
|
||||
frameTraversal->Next();
|
||||
}
|
||||
}
|
||||
else if (getNextFrame &&
|
||||
(!iterStartContent ||
|
||||
!iterStartContent->IsHTMLElement(nsGkAtoms::area))) {
|
||||
// Need to do special check in case we're in an imagemap which has multiple
|
||||
// content nodes per frame, so don't skip over the starting frame.
|
||||
if (aForward)
|
||||
frameTraversal->Next();
|
||||
else
|
||||
frameTraversal->Prev();
|
||||
}
|
||||
|
||||
// Walk frames to find something tabbable matching mCurrentTabIndex
|
||||
nsIFrame* frame = static_cast<nsIFrame*>(frameTraversal->CurrentItem());
|
||||
while (frame) {
|
||||
nsIContent* currentContent = frame->GetContent();
|
||||
if (nsDocument::IsWebComponentsEnabled(currentContent)) {
|
||||
// Try to find the topmost scope owner, since we want to skip the node
|
||||
// that is not owned by document in frame traversal.
|
||||
nsIContent* oldTopLevelScopeOwner = currentTopLevelScopeOwner;
|
||||
if (!aForward || oldTopLevelScopeOwner != currentContent) {
|
||||
currentTopLevelScopeOwner = GetTopLevelScopeOwner(currentContent);
|
||||
} else {
|
||||
currentTopLevelScopeOwner = currentContent;
|
||||
}
|
||||
if (currentTopLevelScopeOwner) {
|
||||
if (currentTopLevelScopeOwner == oldTopLevelScopeOwner) {
|
||||
// We're within non-document scope, continue.
|
||||
do {
|
||||
if (aForward) {
|
||||
frameTraversal->Next();
|
||||
} else {
|
||||
frameTraversal->Prev();
|
||||
}
|
||||
frame = static_cast<nsIFrame*>(frameTraversal->CurrentItem());
|
||||
// For the usage of GetPrevContinuation, see the comment
|
||||
// at the end of while (frame) loop.
|
||||
} while (frame && frame->GetPrevContinuation());
|
||||
continue;
|
||||
}
|
||||
currentContent = currentTopLevelScopeOwner;
|
||||
}
|
||||
}
|
||||
|
||||
// For document navigation, check if this element is an open panel. Since
|
||||
// panels aren't focusable (tabIndex would be -1), we'll just assume that
|
||||
@@ -3555,7 +3086,7 @@ nsFocusManager::GetNextTabbableContent(nsIPresShell* aPresShell,
|
||||
// and root content, so that we only find content within the panel.
|
||||
// Note also that we pass false for aForDocumentNavigation since we
|
||||
// want to locate the first content, not the first document.
|
||||
nsresult rv = GetNextTabbableContent(aPresShell, currentContent,
|
||||
rv = GetNextTabbableContent(aPresShell, currentContent,
|
||||
nullptr, currentContent,
|
||||
true, 1, false, false,
|
||||
aResultContent);
|
||||
@@ -3566,34 +3097,6 @@ nsFocusManager::GetNextTabbableContent(nsIPresShell* aPresShell,
|
||||
}
|
||||
}
|
||||
|
||||
// As of now, 2018/04/12, sequential focus navigation is still
|
||||
// in the obsolete Shadow DOM specification.
|
||||
// http://w3c.github.io/webcomponents/spec/shadow/#sequential-focus-navigation
|
||||
// "if ELEMENT is focusable, a shadow host, or a slot element,
|
||||
// append ELEMENT to NAVIGATION-ORDER."
|
||||
// and later in "For each element ELEMENT in NAVIGATION-ORDER: "
|
||||
// hosts and slots are handled before other elements.
|
||||
if (nsDocument::IsWebComponentsEnabled(currentContent) &&
|
||||
IsHostOrSlot(currentContent)) {
|
||||
bool focusableHostSlot;
|
||||
int32_t tabIndex =
|
||||
HostOrSlotTabIndexValue(currentContent, &focusableHostSlot);
|
||||
// Host or slot itself isn't focusable or going backwards, enter its scope.
|
||||
if ((!aForward || !focusableHostSlot) && tabIndex >= 0 &&
|
||||
(aIgnoreTabIndex || aCurrentTabIndex == tabIndex)) {
|
||||
nsIContent* contentToFocus =
|
||||
GetNextTabbableContentInScope(currentContent, currentContent,
|
||||
aOriginalStartContent, aForward,
|
||||
aForward ? 1 : 0, aIgnoreTabIndex,
|
||||
aForDocumentNavigation,
|
||||
true /* aSkipOwner */);
|
||||
if (contentToFocus) {
|
||||
NS_ADDREF(*aResultContent = contentToFocus);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TabIndex not set defaults to 0 for form elements, anchors and other
|
||||
// elements that are normally focusable. Tabindex defaults to -1
|
||||
// for elements that are not normally focusable.
|
||||
@@ -3642,22 +3145,54 @@ nsFocusManager::GetNextTabbableContent(nsIPresShell* aPresShell,
|
||||
|
||||
// Next, for document navigation, check if this a non-remote child document.
|
||||
bool checkSubDocument = true;
|
||||
if (aForDocumentNavigation &&
|
||||
TryDocumentNavigation(currentContent, &checkSubDocument,
|
||||
aResultContent)) {
|
||||
return NS_OK;
|
||||
if (aForDocumentNavigation) {
|
||||
nsIContent* docRoot = GetRootForChildDocument(currentContent);
|
||||
if (docRoot) {
|
||||
// If GetRootForChildDocument returned something then call
|
||||
// FocusFirst to find the root or first element to focus within
|
||||
// the child document. If this is a frameset though, skip this and
|
||||
// fall through to the checkSubDocument block below to iterate into
|
||||
// the frameset's frames and locate the first focusable frame.
|
||||
if (!docRoot->IsHTMLElement(nsGkAtoms::frameset)) {
|
||||
return FocusFirst(docRoot, aResultContent);
|
||||
}
|
||||
} else {
|
||||
// Set checkSubDocument to false, as this was neither a frame
|
||||
// type element or a child document that was focusable.
|
||||
checkSubDocument = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (checkSubDocument) {
|
||||
// found a node with a matching tab index. Check if it is a child
|
||||
// frame. If so, navigate into the child frame instead.
|
||||
if (TryToMoveFocusToSubDocument(currentContent,
|
||||
aOriginalStartContent,
|
||||
aForward,
|
||||
aForDocumentNavigation,
|
||||
aResultContent)) {
|
||||
MOZ_ASSERT(*aResultContent);
|
||||
return NS_OK;
|
||||
nsIDocument* doc = currentContent->GetComposedDoc();
|
||||
NS_ASSERTION(doc, "content not in document");
|
||||
nsIDocument* subdoc = doc->GetSubDocumentFor(currentContent);
|
||||
if (subdoc && !subdoc->EventHandlingSuppressed()) {
|
||||
if (aForward) {
|
||||
// when tabbing forward into a frame, return the root
|
||||
// frame so that the canvas becomes focused.
|
||||
nsCOMPtr<nsPIDOMWindowOuter> subframe = subdoc->GetWindow();
|
||||
if (subframe) {
|
||||
*aResultContent = GetRootForFocus(subframe, subdoc, false, true);
|
||||
if (*aResultContent) {
|
||||
NS_ADDREF(*aResultContent);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
Element* rootElement = subdoc->GetRootElement();
|
||||
nsIPresShell* subShell = subdoc->GetShell();
|
||||
if (rootElement && subShell) {
|
||||
rv = GetNextTabbableContent(subShell, rootElement,
|
||||
aOriginalStartContent, rootElement,
|
||||
aForward, (aForward ? 1 : 0),
|
||||
false, aForDocumentNavigation, aResultContent);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (*aResultContent)
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
// otherwise, use this as the next content node to tab to, unless
|
||||
// this was the element we started on. This would happen for
|
||||
@@ -3728,77 +3263,6 @@ nsFocusManager::GetNextTabbableContent(nsIPresShell* aPresShell,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
nsFocusManager::TryDocumentNavigation(nsIContent* aCurrentContent,
|
||||
bool* aCheckSubDocument,
|
||||
nsIContent** aResultContent)
|
||||
{
|
||||
*aCheckSubDocument = true;
|
||||
nsIContent* docRoot = GetRootForChildDocument(aCurrentContent);
|
||||
if (docRoot) {
|
||||
// If GetRootForChildDocument returned something then call
|
||||
// FocusFirst to find the root or first element to focus within
|
||||
// the child document. If this is a frameset though, skip this and
|
||||
// fall through to normal tab navigation to iterate into
|
||||
// the frameset's frames and locate the first focusable frame.
|
||||
if (!docRoot->IsHTMLElement(nsGkAtoms::frameset)) {
|
||||
*aCheckSubDocument = false;
|
||||
Unused << FocusFirst(docRoot, aResultContent);
|
||||
return *aResultContent != nullptr;
|
||||
}
|
||||
} else {
|
||||
// Set aCheckSubDocument to false, as this was neither a frame
|
||||
// type element or a child document that was focusable.
|
||||
*aCheckSubDocument = false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
nsFocusManager::TryToMoveFocusToSubDocument(nsIContent* aCurrentContent,
|
||||
nsIContent* aOriginalStartContent,
|
||||
bool aForward,
|
||||
bool aForDocumentNavigation,
|
||||
nsIContent** aResultContent)
|
||||
{
|
||||
nsIDocument* doc = aCurrentContent->GetComposedDoc();
|
||||
NS_ASSERTION(doc, "content not in document");
|
||||
nsIDocument* subdoc = doc->GetSubDocumentFor(aCurrentContent);
|
||||
if (subdoc && !subdoc->EventHandlingSuppressed()) {
|
||||
if (aForward) {
|
||||
// when tabbing forward into a frame, return the root
|
||||
// frame so that the canvas becomes focused.
|
||||
nsCOMPtr<nsPIDOMWindowOuter> subframe = subdoc->GetWindow();
|
||||
if (subframe) {
|
||||
*aResultContent = GetRootForFocus(subframe, subdoc, false, true);
|
||||
if (*aResultContent) {
|
||||
NS_ADDREF(*aResultContent);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Element* rootElement = subdoc->GetRootElement();
|
||||
nsIPresShell* subShell = subdoc->GetShell();
|
||||
if (rootElement && subShell) {
|
||||
nsresult rv = GetNextTabbableContent(subShell,
|
||||
rootElement,
|
||||
aOriginalStartContent,
|
||||
rootElement,
|
||||
aForward,
|
||||
(aForward ? 1 : 0),
|
||||
false,
|
||||
aForDocumentNavigation,
|
||||
aResultContent);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
if (*aResultContent) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
nsFocusManager::GetNextTabbableMapArea(bool aForward,
|
||||
int32_t aCurrentTabIndex,
|
||||
@@ -3845,20 +3309,15 @@ nsFocusManager::GetNextTabIndex(nsIContent* aParent,
|
||||
bool aForward)
|
||||
{
|
||||
int32_t tabIndex, childTabIndex;
|
||||
StyleChildrenIterator iter(aParent);
|
||||
|
||||
if (aForward) {
|
||||
tabIndex = 0;
|
||||
for (nsIContent* child = iter.GetNextChild();
|
||||
for (nsIContent* child = aParent->GetFirstChild();
|
||||
child;
|
||||
child = iter.GetNextChild()) {
|
||||
// Skip child's descendants if child is a shadow host, as they are
|
||||
// in the focus navigation scope owned by child's shadow root
|
||||
if (!(nsDocument::IsWebComponentsEnabled(aParent) && IsHostOrSlot(child))) {
|
||||
childTabIndex = GetNextTabIndex(child, aCurrentTabIndex, aForward);
|
||||
if (childTabIndex > aCurrentTabIndex && childTabIndex != tabIndex) {
|
||||
tabIndex = (tabIndex == 0 || childTabIndex < tabIndex) ? childTabIndex : tabIndex;
|
||||
}
|
||||
child = child->GetNextSibling()) {
|
||||
childTabIndex = GetNextTabIndex(child, aCurrentTabIndex, aForward);
|
||||
if (childTabIndex > aCurrentTabIndex && childTabIndex != tabIndex) {
|
||||
tabIndex = (tabIndex == 0 || childTabIndex < tabIndex) ? childTabIndex : tabIndex;
|
||||
}
|
||||
|
||||
nsAutoString tabIndexStr;
|
||||
@@ -3872,17 +3331,13 @@ nsFocusManager::GetNextTabIndex(nsIContent* aParent,
|
||||
}
|
||||
else { /* !aForward */
|
||||
tabIndex = 1;
|
||||
for (nsIContent* child = iter.GetNextChild();
|
||||
for (nsIContent* child = aParent->GetFirstChild();
|
||||
child;
|
||||
child = iter.GetNextChild()) {
|
||||
// Skip child's descendants if child is a shadow host, as they are
|
||||
// in the focus navigation scope owned by child's shadow root
|
||||
if (!(nsDocument::IsWebComponentsEnabled(aParent) && IsHostOrSlot(child))) {
|
||||
childTabIndex = GetNextTabIndex(child, aCurrentTabIndex, aForward);
|
||||
if ((aCurrentTabIndex == 0 && childTabIndex > tabIndex) ||
|
||||
(childTabIndex < aCurrentTabIndex && childTabIndex > tabIndex)) {
|
||||
tabIndex = childTabIndex;
|
||||
}
|
||||
child = child->GetNextSibling()) {
|
||||
childTabIndex = GetNextTabIndex(child, aCurrentTabIndex, aForward);
|
||||
if ((aCurrentTabIndex == 0 && childTabIndex > tabIndex) ||
|
||||
(childTabIndex < aCurrentTabIndex && childTabIndex > tabIndex)) {
|
||||
tabIndex = childTabIndex;
|
||||
}
|
||||
|
||||
nsAutoString tabIndexStr;
|
||||
|
||||
@@ -384,91 +384,6 @@ protected:
|
||||
int32_t aType, bool aNoParentTraversal,
|
||||
nsIContent** aNextContent);
|
||||
|
||||
/**
|
||||
* Returns scope owner of aContent.
|
||||
* A scope owner is either a document root, shadow host, or slot.
|
||||
*/
|
||||
nsIContent* FindOwner(nsIContent* aContent);
|
||||
|
||||
/**
|
||||
* Retrieve the next tabbable element in scope owned by aOwner, using
|
||||
* focusability and tabindex to determine the tab order.
|
||||
*
|
||||
* aOwner is the owner of scope to search in.
|
||||
*
|
||||
* aStartContent is the starting point for this call of this method.
|
||||
*
|
||||
* aOriginalStartContent is the initial starting point for sequential
|
||||
* navigation.
|
||||
*
|
||||
* aForward should be true for forward navigation or false for backward
|
||||
* navigation.
|
||||
*
|
||||
* aCurrentTabIndex is the current tabindex.
|
||||
*
|
||||
* aIgnoreTabIndex to ignore the current tabindex and find the element
|
||||
* irrespective or the tab index.
|
||||
*
|
||||
* aForDocumentNavigation informs whether we're navigating only through
|
||||
* documents.
|
||||
*
|
||||
* aSkipOwner to skip owner while searching. The flag is set when caller is
|
||||
* |GetNextTabbableContent| in order to let caller handle owner.
|
||||
*
|
||||
* NOTE:
|
||||
* Consider the method searches downwards in flattened subtree
|
||||
* rooted at aOwner.
|
||||
*/
|
||||
nsIContent* GetNextTabbableContentInScope(nsIContent* aOwner,
|
||||
nsIContent* aStartContent,
|
||||
nsIContent* aOriginalStartContent,
|
||||
bool aForward,
|
||||
int32_t aCurrentTabIndex,
|
||||
bool aIgnoreTabIndex,
|
||||
bool aForDocumentNavigation,
|
||||
bool aSkipOwner);
|
||||
|
||||
/**
|
||||
* Retrieve the next tabbable element in scope including aStartContent
|
||||
* and the scope's ancestor scopes, using focusability and tabindex to
|
||||
* determine the tab order.
|
||||
*
|
||||
* aStartOwner is the scope owner of the aStartContent.
|
||||
*
|
||||
* aStartContent an in/out paremeter. It as input is the starting point
|
||||
* for this call of this method; as output it is the shadow host in
|
||||
* light DOM if the next tabbable element is not found in shadow DOM,
|
||||
* in order to continue searching in light DOM.
|
||||
*
|
||||
* aOriginalStartContent is the initial starting point for sequential
|
||||
* navigation.
|
||||
*
|
||||
* aForward should be true for forward navigation or false for backward
|
||||
* navigation.
|
||||
*
|
||||
* aCurrentTabIndex returns tab index of shadow host in light DOM if the
|
||||
* next tabbable element is not found in shadow DOM, in order to continue
|
||||
* searching in light DOM.
|
||||
*
|
||||
* aIgnoreTabIndex to ignore the current tabindex and find the element
|
||||
* irrespective or the tab index.
|
||||
*
|
||||
* aForDocumentNavigation informs whether we're navigating only through
|
||||
* documents.
|
||||
*
|
||||
* NOTE:
|
||||
* Consider the method searches upwards in all shadow host- or slot-rooted
|
||||
* flattened subtrees that contains aStartContent as non-root, except
|
||||
* the flattened subtree rooted at shadow host in light DOM.
|
||||
*/
|
||||
nsIContent* GetNextTabbableContentInAncestorScopes(nsIContent* aStartOwner,
|
||||
nsIContent** aStartContent,
|
||||
nsIContent* aOriginalStartContent,
|
||||
bool aForward,
|
||||
int32_t* aCurrentTabIndex,
|
||||
bool aIgnoreTabIndex,
|
||||
bool aForDocumentNavigation);
|
||||
|
||||
/**
|
||||
* Retrieve the next tabbable element within a document, using focusability
|
||||
* and tabindex to determine the tab order. The element is returned in
|
||||
@@ -588,16 +503,6 @@ private:
|
||||
|
||||
void SetFocusedWindowInternal(nsPIDOMWindowOuter* aWindow);
|
||||
|
||||
bool TryDocumentNavigation(nsIContent* aCurrentContent,
|
||||
bool* aCheckSubDocument,
|
||||
nsIContent** aResultContent);
|
||||
|
||||
bool TryToMoveFocusToSubDocument(nsIContent* aCurrentContent,
|
||||
nsIContent* aOriginalStartContent,
|
||||
bool aForward,
|
||||
bool aForDocumentNavigation,
|
||||
nsIContent** aResultContent);
|
||||
|
||||
// the currently active and front-most top-most window
|
||||
nsCOMPtr<nsPIDOMWindowOuter> mActiveWindow;
|
||||
|
||||
|
||||
Loaded 100 of 10261 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user