merge mozilla-inbound to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2016-02-12 15:15:17 +01:00
commit b0531843fe
420 changed files with 4985 additions and 5460 deletions

View File

@ -15,9 +15,11 @@ export TOPLEVEL_BUILD := 1
default::
ifndef TEST_MOZBUILD
ifdef MOZ_BUILD_APP
include $(topsrcdir)/$(MOZ_BUILD_APP)/build.mk
endif
endif
include $(topsrcdir)/config/config.mk
@ -28,6 +30,10 @@ DIST_GARBAGE = config.cache config.log config.status* config-defs.h \
netwerk/necko-config.h xpcom/xpcom-config.h xpcom/xpcom-private.h \
.mozconfig.mk
ifndef MOZ_PROFILE_USE
buildid.h source-repo.h: FORCE
endif
ifdef JS_STANDALONE
configure_dir = $(topsrcdir)/js/src
else
@ -309,12 +315,6 @@ ifdef SOCORRO_SYMBOL_UPLOAD_TOKEN_FILE
else
$(SHELL) $(topsrcdir)/toolkit/crashreporter/tools/upload_symbols.sh $(SYMBOL_INDEX_NAME) '$(DIST)/$(PKG_PATH)$(SYMBOL_FULL_ARCHIVE_BASENAME).zip'
endif
# MOZ_SOURCE_STAMP is defined in package-name.mk with a deferred assignment.
# exporting it makes make run its $(shell) command for each invoked submake,
# so transform it to an immediate assignment.
MOZ_SOURCE_STAMP := $(MOZ_SOURCE_STAMP)
export MOZ_SOURCE_STAMP
endif
.PHONY: update-packaging

View File

@ -80,11 +80,9 @@ TreeWalker::NextChild()
nsIContent* parent = parentNode->AsElement();
top = PushState(parent);
while (nsIContent* childNode = Next(top)) {
if (childNode == mAnchorNode) {
mAnchorNode = parent;
return NextChild();
}
if (top->mDOMIter.Seek(mAnchorNode)) {
mAnchorNode = parent;
return NextChild();
}
// XXX We really should never get here, it means we're trying to find an

View File

@ -2,9 +2,6 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
USE_RCS_MK := 1
include $(topsrcdir)/config/makefiles/rcs.mk
# Make sure the standalone glue doesn't try to get libxpcom.so from b2g/app.
NSDISTMODE = copy
@ -61,7 +58,6 @@ libs::
# Copy the app icon for b2g-desktop
ifeq ($(OS_ARCH),WINNT)
cp $(DIST)/branding/$(APP_ICON).ico $(DIST)/bin/chrome/icons/default/$(APP_ICON).ico
$(DIST)/bin/redit$(HOST_BIN_SUFFIX) $(DIST)/bin/$(APP_BINARY) $(DIST)/branding/$(APP_ICON).ico
cp $(DIST)/branding/$(APP_ICON).ico $(DIST)/bin/chrome/icons/default/default.ico
else ifneq (gonk,$(MOZ_WIDGET_TOOLKIT))
cp $(DIST)/branding/default.png $(DIST)/bin/chrome/icons/default/default.png

View File

@ -1015,7 +1015,6 @@ pref("security.exthelperapp.disable_background_handling", true);
// Inactivity time in milliseconds after which we shut down the OS.File worker.
pref("osfile.reset_worker_delay", 5000);
pref("apz.displayport_expiry_ms", 0);
// APZ physics settings, tuned by UX designers
pref("apz.axis_lock.mode", 2); // Use "sticky" axis locking
pref("apz.fling_curve_function_x1", "0.41");

View File

@ -8,9 +8,6 @@ CONFIGURE_SUBST_FILES += ['installer/Makefile']
DIRS += ['chrome', 'components', 'locales']
if CONFIG['OS_ARCH'] == 'WINNT':
DIRS += ['../xulrunner/tools/redit']
if CONFIG['GAIADIR']:
DIRS += ['gaia']

View File

@ -79,7 +79,7 @@ LPROJ := Contents/Resources/$(LPROJ_ROOT).lproj
clean clobber repackage::
$(RM) -r $(dist_dest)
MAC_BUNDLE_VERSION = $(shell $(PYTHON) $(srcdir)/macversion.py --version=$(MOZ_APP_VERSION) --buildid=$(DEPTH)/config/buildid)
MAC_BUNDLE_VERSION = $(shell $(PYTHON) $(srcdir)/macversion.py --version=$(MOZ_APP_VERSION) --buildid=$(DEPTH)/buildid.h)
.PHONY: repackage
tools repackage:: $(DIST)/bin/$(MOZ_APP_NAME)

View File

@ -28,7 +28,7 @@ if not options.version:
# builds), but also so that newly-built older versions (e.g. beta build) aren't
# considered "newer" than previously-built newer versions (e.g. a trunk nightly)
buildid = open(options.buildid, 'r').read()
define, MOZ_BUILDID, buildid = open(options.buildid, 'r').read().split()
# extract only the major version (i.e. "14" from "14.0b1")
majorVersion = re.match(r'^(\d+)[^\d].*', options.version).group(1)

View File

@ -1106,6 +1106,8 @@
}
if (!this._previewMode) {
this._recordTabAccess(this.mCurrentTab);
this.mCurrentTab.lastAccessed = Infinity;
this.mCurrentTab.removeAttribute("unread");
oldTab.lastAccessed = Date.now();
@ -1298,6 +1300,45 @@
]]></body>
</method>
<!--
This function assumes we have an LRU cache of tabs (either
images of tab content or their layers). The goal is to find
out how far into the cache we need to look in order to find
aTab. We record this number in telemetry and also move aTab to
the front of the cache.
A newly created tab has position Infinity in the cache.
If a tab is closed, it has no effect on the position of other
tabs in the cache since we assume that closing a tab doesn't
cause us to load in any other tabs.
We ignore the effect of dragging tabs between windows.
-->
<method name="_recordTabAccess">
<parameter name="aTab"/>
<body><![CDATA[
if (!Services.telemetry.canRecordExtended) {
return;
}
let tabs = Array.from(this.visibleTabs);
let pos = aTab.cachePosition;
for (let i = 0; i < tabs.length; i++) {
// If aTab is moving to the front, everything that was
// previously in front of it is bumped up one position.
if (tabs[i].cachePosition < pos) {
tabs[i].cachePosition++;
}
}
aTab.cachePosition = 0;
if (isFinite(pos)) {
Services.telemetry.getHistogramById("TAB_SWITCH_CACHE_POSITION").add(pos);
}
]]></body>
</method>
<method name="_tabAttrModified">
<parameter name="aTab"/>
<parameter name="aChanged"/>
@ -4267,6 +4308,7 @@
this.mCurrentTab._tPos = 0;
this.mCurrentTab._fullyOpen = true;
this.mCurrentTab.lastAccessed = Infinity;
this.mCurrentTab.cachePosition = 0;
this.mCurrentTab.linkedBrowser = this.mCurrentBrowser;
this._tabForBrowser.set(this.mCurrentBrowser, this.mCurrentTab);
@ -6163,6 +6205,8 @@
</setter>
</property>
<field name="cachePosition">Infinity</field>
<field name="mOverCloseButton">false</field>
<property name="_overPlayingIcon" readonly="true">
<getter><![CDATA[

View File

@ -9,25 +9,7 @@ include $(topsrcdir)/config/makefiles/makeutils.mk
ifdef MOZ_APP_BASENAME
APP_INI_DEPS = $(topsrcdir)/config/milestone.txt
MOZ_BUILDID := $(shell cat $(DEPTH)/config/buildid)
APP_INI_DEPS += $(DEPTH)/config/buildid
DEFINES += -DMOZ_BUILDID=$(MOZ_BUILDID)
APP_INI_DEPS += $(DEPTH)/config/autoconf.mk
MOZ_SOURCE_STAMP := $(firstword $(shell cd $(topsrcdir)/$(MOZ_BUILD_APP)/.. && hg parent --template='{node}\n' 2>/dev/null))
ifdef MOZ_SOURCE_STAMP
DEFINES += -DMOZ_SOURCE_STAMP='$(MOZ_SOURCE_STAMP)'
endif
ifdef MOZ_INCLUDE_SOURCE_INFO
source_repo ?= $(call getSourceRepo,$(topsrcdir)/$(MOZ_BUILD_APP)/..)
ifneq (,$(source_repo))
DEFINES += -DMOZ_SOURCE_REPO='$(source_repo)'
endif
endif
endif
# NOTE: Keep .gdbinit in the topsrcdir for people who run gdb from the topsrcdir.

View File

@ -15,6 +15,8 @@
; file, You can obtain one at http://mozilla.org/MPL/2.0/.
#endif
#filter substitution
#include @TOPOBJDIR@/buildid.h
#include @TOPOBJDIR@/source-repo.h
[App]
Vendor=@MOZ_APP_VENDOR@
Name=@MOZ_APP_BASENAME@

View File

@ -7,6 +7,7 @@ import glob
import time
import re
import os
import posixpath
import tempfile
import shutil
import subprocess
@ -214,7 +215,7 @@ class RemoteAutomation(Automation):
try:
dumpDir = tempfile.mkdtemp()
remoteCrashDir = self._remoteProfile + '/minidumps/'
remoteCrashDir = posixpath.join(self._remoteProfile, 'minidumps')
if not self._devicemanager.dirExists(remoteCrashDir):
# If crash reporting is enabled (MOZ_CRASHREPORTER=1), the
# minidumps directory is automatically created when Fennec

View File

@ -75,3 +75,5 @@ if CONFIG['MOZ_APP_BASENAME']:
FINAL_TARGET_PP_FILES += ['application.ini']
if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'android' and CONFIG['MOZ_UPDATER']:
FINAL_TARGET_PP_FILES += ['update-settings.ini']
DEFINES['TOPOBJDIR'] = TOPOBJDIR

View File

@ -38,7 +38,12 @@ import errno
import hashlib
import shutil
from optparse import OptionParser
from subprocess import check_call, check_output, STDOUT
from subprocess import (
check_call,
check_output,
STDOUT,
CalledProcessError,
)
import redo
def OptionalEnvironmentVariable(v):
@ -93,7 +98,14 @@ def DoSSHCommand(command, user, host, port=None, ssh_key=None):
cmdline.extend(["%s@%s" % (user, host), command])
with redo.retrying(check_output, sleeptime=10) as f:
output = f(cmdline, stderr=STDOUT).strip()
try:
output = f(cmdline, stderr=STDOUT).strip()
except CalledProcessError as e:
print "failed ssh command output:"
print '=' * 20
print e.output
print '=' * 20
raise
return output
raise Exception("Command %s returned non-zero exit code" % cmdline)

78
build/variables.py Normal file
View File

@ -0,0 +1,78 @@
# 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/.
from __future__ import print_function, unicode_literals
import os
import subprocess
import sys
from datetime import datetime
def buildid_header(output):
buildid = os.environ.get('MOZ_BUILD_DATE')
if buildid and len(buildid) != 14:
print('Ignoring invalid MOZ_BUILD_DATE: %s' % buildid, file=sys.stderr)
buildid = None
if not buildid:
buildid = datetime.now().strftime('%Y%m%d%H%M%S')
output.write("#define MOZ_BUILDID %s\n" % buildid)
def get_program_output(*command):
try:
with open(os.devnull) as stderr:
return subprocess.check_output(command, stderr=stderr)
except:
return ''
def get_hg_info(workdir):
repo = get_program_output('hg', '-R', workdir, 'path', 'default')
if repo:
repo = repo.strip()
if repo.startswith('ssh://'):
repo = 'https://' + repo[6:]
repo = repo.rstrip('/')
changeset = get_program_output(
'hg', '-R', workdir, 'parent', '--template={node}')
return repo, changeset
def source_repo_header(output):
# We allow the source repo and changeset to be specified via the
# environment (see configure)
import buildconfig
repo = buildconfig.substs.get('MOZ_SOURCE_REPO')
changeset = buildconfig.substs.get('MOZ_SOURCE_CHANGESET')
source = ''
if bool(repo) != bool(changeset):
raise Exception('MOZ_SOURCE_REPO and MOZ_SOURCE_CHANGESET both must '
'be set (or not set).')
if not repo:
if os.path.exists(os.path.join(buildconfig.topsrcdir, '.hg')):
repo, changeset = get_hg_info(buildconfig.topsrcdir)
if changeset:
output.write('#define MOZ_SOURCE_STAMP %s\n' % changeset)
if repo and buildconfig.substs.get('MOZ_INCLUDE_SOURCE_INFO'):
source = '%s/rev/%s' % (repo, changeset)
output.write('#define MOZ_SOURCE_REPO %s\n' % repo)
output.write('#define MOZ_SOURCE_URL %s\n' % source)
def main(args):
if (len(args)):
func = globals().get(args[0])
if func:
return func(sys.stdout, *args[1:])
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))

View File

@ -238,7 +238,7 @@ profiledbuild::
ifdef MOZ_UNIFY_BDATE
ifndef MOZ_BUILD_DATE
ifdef MOZ_BUILD_PROJECTS
MOZ_BUILD_DATE = $(shell $(PYTHON) $(TOPSRCDIR)/toolkit/xre/make-platformini.py --print-buildid)
MOZ_BUILD_DATE = $(shell $(PYTHON) $(TOPSRCDIR)/build/variables.py buildid_header | awk '{print $$3}')
export MOZ_BUILD_DATE
endif
endif

View File

@ -32,21 +32,6 @@ endif
include $(topsrcdir)/config/rules.mk
ifndef JS_STANDALONE
ifndef MOZ_PROFILE_USE
# Generate a new buildid every time we "export" in config... that's only
# supposed to be once per-build!
export:: buildid
buildid: FORCE
ifdef MOZ_BUILD_DATE
printf '%s' $(MOZ_BUILD_DATE) > buildid
else
$(PYTHON) $(topsrcdir)/toolkit/xre/make-platformini.py --print-buildid > buildid
endif
endif
endif
ifdef WRAP_SYSTEM_INCLUDES
export-preqs = \
$(call mkdir_deps,system_wrappers) \

View File

@ -80,7 +80,7 @@ $(TOPOBJDIR)/%: FORCE
# corresponding install manifests are named correspondingly, with forward
# slashes replaced with underscores, and prefixed with `install_`. That is,
# the install manifest for `dist/bin` would be `install_dist_bin`.
$(addprefix install-,$(INSTALL_MANIFESTS)): install-%: $(TOPOBJDIR)/config/buildid
$(addprefix install-,$(INSTALL_MANIFESTS)): install-%: $(addprefix $(TOPOBJDIR)/,buildid.h source-repo.h)
@# For now, force preprocessed files to be reprocessed every time.
@# The overhead is not that big, and this avoids waiting for proper
@# support for defines tracking in process_install_manifest.
@ -91,7 +91,6 @@ $(addprefix install-,$(INSTALL_MANIFESTS)): install-%: $(TOPOBJDIR)/config/build
$(TOPOBJDIR)/$* \
-DAB_CD=en-US \
-DBOOKMARKS_INCLUDE_DIR=$(TOPSRCDIR)/browser/locales/en-US/profile \
-DMOZ_BUILDID=$(shell cat $(TOPOBJDIR)/config/buildid) \
$(ACDEFINES) \
install_$(subst /,_,$*)

View File

@ -58,6 +58,7 @@ endif
$(LOOP_OVER_DIRS)
showbuild showhost: _DEPEND_CFLAGS=
showbuild showhost: COMPILE_PDB_FLAG=
showbuild:
$(call print_vars,\
MOZ_BUILD_ROOT \

View File

@ -117,9 +117,5 @@ ifdef USE_AUTOTARGETS_MK # mkdir_deps
include $(topORerr)/config/makefiles/autotargets.mk
endif
ifdef USE_RCS_MK
include $(topORerr)/config/makefiles/rcs.mk
endif
## copy(src, dst): recursive copy
copy_dir = (cd $(1)/. && $(TAR) $(TAR_CREATE_FLAGS) - .) | (cd $(2)/. && tar -xf -)

View File

@ -1,54 +0,0 @@
# -*- makefile -*-
# vim:set ts=8 sw=8 sts=8 noet:
#
# 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/.
#
ifdef USE_RCS_MK #{
ifndef INCLUDED_RCS_MK #{
MOZ_RCS_TYPE_HG ?= $(notdir $(wildcard $(topsrcdir)/.hg))
MOZ_RCS_TYPE_GIT ?= $(notdir $(wildcard $(topsrcdir)/.git))
###########################################################################
# HAVE_MERCURIAL_RCS
###########################################################################
ifeq (.hg,$(MOZ_RCS_TYPE_HG)) #{
# Intent: Retrieve the http:// repository path for a directory.
# Usage: $(call getSourceRepo[,repo_dir|args])
# Args:
# path (optional): repository to query. Defaults to $(topsrcdir)
getSourceRepo = \
$(call FUNC_getSourceRepo,$(if $(1),cd $(1) && hg,hg --repository $(topsrcdir)))
# return: http://hg.mozilla.org/mozilla-central
FUNC_getSourceRepo = \
$(strip \
$(patsubst %/,%,\
$(patsubst ssh://%,http://%,\
$(firstword $(shell $(getargv) showconfig paths.default))\
)))
#} HAVE_MERCURIAL_RCS
###########################################################################
# HAVE_GIT_RCS
###########################################################################
else ifeq (.git,$(MOZ_RCS_TYPE_GIT)) #{
GIT ?= git
getSourceRepo = \
$(shell cd $(topsrcdir) && $(GIT) rev-parse --verify HEAD)
endif #} HAVE_GIT_RCS
INCLUDED_RCS_MK := 1
endif #}
endif #}

View File

@ -114,7 +114,7 @@ if (!defined($module))
my $bufferstr=" ";
my $MILESTONE_FILE = "$topsrcdir/config/milestone.txt";
my $BUILDID_FILE = "$depth/config/buildid";
my $BUILDID_FILE = "$depth/buildid.h";
#Read module.ver file
#Version file overrides for WIN32:
@ -183,7 +183,7 @@ $displayname =~ s/^\s*(.*)\s*$/$1/;
open(BUILDID, "<", $BUILDID_FILE) || die("Couldn't open buildid file: $BUILDID_FILE");
$buildid = <BUILDID>;
$buildid =~ s/\s*$//;
$buildid =~ s/^#define MOZ_BUILDID\s+(\S+)\s*$/$1/;
close BUILDID;
my $daycount = daysFromBuildID($buildid);

View File

@ -8724,15 +8724,8 @@ fi
# External builds (specifically Ubuntu) may drop the hg repo information, so we allow to
# explicitly set the repository and changeset information in.
if test "$MOZILLA_OFFICIAL"; then
if test -z "$MOZ_SOURCE_REPO" && test -z "$MOZ_SOURCE_CHANGESET" && test -d ${_topsrcdir}/.hg; then
MOZ_SOURCE_CHANGESET=`cd $_topsrcdir && hg parent --template='{node}'`
MOZ_SOURCE_REPO=`cd $_topsrcdir && hg showconfig paths.default | sed -e 's|^ssh://|http://|' -e 's|/$||'`
fi
SOURCE_REV_URL=$MOZ_SOURCE_REPO/rev/$MOZ_SOURCE_CHANGESET
fi
AC_SUBST(SOURCE_REV_URL)
AC_SUBST(MOZ_SOURCE_REPO)
AC_SUBST(MOZ_SOURCE_CHANGESET)
AC_SUBST(MOZ_INCLUDE_SOURCE_INFO)
if test "$MOZ_TELEMETRY_REPORTING"; then

View File

@ -49,17 +49,7 @@ ArchiveReaderEvent::ArchiveReaderEvent(ArchiveReader* aArchiveReader)
ArchiveReaderEvent::~ArchiveReaderEvent()
{
if (!NS_IsMainThread()) {
nsIMIMEService* mimeService;
mMimeService.forget(&mimeService);
if (mimeService) {
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
NS_WARN_IF_FALSE(mainThread, "Couldn't get the main thread! Leaking!");
if (mainThread) {
NS_ProxyRelease(mainThread, mimeService);
}
}
NS_ReleaseOnMainThread(mMimeService.forget());
}
MOZ_COUNT_DTOR(ArchiveReaderEvent);

View File

@ -190,7 +190,7 @@ FlattenedChildIterator::Init(bool aIgnoreXBL)
}
}
void
bool
ExplicitChildIterator::Seek(nsIContent* aChildToFind)
{
if (aChildToFind->GetParent() == mParent &&
@ -204,14 +204,14 @@ ExplicitChildIterator::Seek(nsIContent* aChildToFind)
mShadowIterator = nullptr;
mDefaultChild = nullptr;
mIsFirst = false;
return;
return true;
}
// Can we add more fast paths here based on whether the parent of aChildToFind
// is a shadow insertion point or content insertion point?
// Slow path: just walk all our kids.
Seek(aChildToFind, nullptr);
return Seek(aChildToFind, nullptr);
}
nsIContent*
@ -311,6 +311,37 @@ ExplicitChildIterator::GetPreviousChild()
return mChild;
}
bool
AllChildrenIterator::Seek(nsIContent* aChildToFind)
{
if (mPhase == eNeedBeforeKid) {
mPhase = eNeedExplicitKids;
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
if (frame) {
nsIFrame* beforeFrame = nsLayoutUtils::GetBeforeFrame(frame);
if (beforeFrame) {
if (beforeFrame->GetContent() == aChildToFind) {
return true;
}
}
}
}
if (mPhase == eNeedExplicitKids) {
if (ExplicitChildIterator::Seek(aChildToFind)) {
return true;
}
mPhase = eNeedAnonKids;
}
nsIContent* child = nullptr;
do {
child = GetNextChild();
} while (child && child != aChildToFind);
return child == aChildToFind;
}
nsIContent*
AllChildrenIterator::GetNextChild()
{

View File

@ -64,7 +64,7 @@ public:
// found. This version can take shortcuts that the two-argument version
// can't, so can be faster (and in fact can be O(1) instead of O(N) in many
// cases).
void Seek(nsIContent* aChildToFind);
bool Seek(nsIContent* aChildToFind);
// Looks for aChildToFind respecting insertion points until aChildToFind is found.
// or aBound is found. If aBound is nullptr then the seek is unbounded. Returns
@ -199,6 +199,8 @@ public:
~AllChildrenIterator() { MOZ_ASSERT(!mMutationGuard.Mutated(0)); }
#endif
bool Seek(nsIContent* aChildToFind);
nsIContent* GetNextChild();
nsIContent* Parent() const { return mOriginalContent; }

View File

@ -84,6 +84,11 @@ public:
: mMethodName(Console::MethodLog)
, mPrivate(false)
, mTimeStamp(JS_Now() / PR_USEC_PER_MSEC)
, mStartTimerValue(0)
, mStartTimerStatus(false)
, mStopTimerDuration(0)
, mStopTimerStatus(false)
, mCountValue(MAX_PAGE_COUNTERS)
, mIDType(eUnknown)
, mOuterIDNumber(0)
, mInnerIDNumber(0)
@ -172,7 +177,34 @@ public:
Console::MethodName mMethodName;
bool mPrivate;
int64_t mTimeStamp;
DOMHighResTimeStamp mMonotonicTimer;
// These values are set in the owning thread and they contain the timestamp of
// when the new timer has started, the name of it and the status of the
// creation of it. If status is false, something went wrong. User
// DOMHighResTimeStamp instead mozilla::TimeStamp because we use
// monotonicTimer from Performance.now();
// They will be set on the owning thread and never touched again on that
// thread. They will be used on the main-thread in order to create a
// ConsoleTimerStart dictionary when console.time() is used.
DOMHighResTimeStamp mStartTimerValue;
nsString mStartTimerLabel;
bool mStartTimerStatus;
// These values are set in the owning thread and they contain the duration,
// the name and the status of the StopTimer method. If status is false,
// something went wrong. They will be set on the owning thread and never
// touched again on that thread. They will be used on the main-thread in order
// to create a ConsoleTimerEnd dictionary. This members are set when
// console.timeEnd() is called.
double mStopTimerDuration;
nsString mStopTimerLabel;
bool mStopTimerStatus;
// These 2 values are set by IncreaseCounter on the owning thread and they are
// used on the main-thread by CreateCounterValue. These members are set when
// console.count() is called.
nsString mCountLabel;
uint32_t mCountValue;
// The concept of outerID and innerID is misleading because when a
// ConsoleCallData is created from a window, these are the window IDs, but
@ -345,7 +377,7 @@ private:
void
RunWithWindow(nsPIDOMWindowInner* aWindow)
{
MOZ_ASSERT(NS_IsMainThread());
AssertIsOnMainThread();
AutoJSAPI jsapi;
MOZ_ASSERT(aWindow);
@ -367,7 +399,7 @@ private:
void
RunWindowless()
{
MOZ_ASSERT(NS_IsMainThread());
AssertIsOnMainThread();
WorkerPrivate* wp = mWorkerPrivate;
while (wp->GetParent()) {
@ -517,7 +549,7 @@ private:
RunConsole(JSContext* aCx, nsPIDOMWindowOuter* aOuterWindow,
nsPIDOMWindowInner* aInnerWindow) override
{
MOZ_ASSERT(NS_IsMainThread());
AssertIsOnMainThread();
MOZ_ASSERT(mCallData->mCopiedArguments.IsEmpty());
// The windows have to run in parallel.
@ -564,6 +596,8 @@ private:
void
ProcessCallData(JSContext* aCx)
{
AssertIsOnMainThread();
ClearException ce(aCx);
JS::Rooted<JS::Value> argumentsValue(aCx);
@ -658,7 +692,7 @@ private:
RunConsole(JSContext* aCx, nsPIDOMWindowOuter* aOuterWindow,
nsPIDOMWindowInner* aInnerWindow) override
{
MOZ_ASSERT(NS_IsMainThread());
AssertIsOnMainThread();
ClearException ce(aCx);
@ -746,6 +780,9 @@ NS_INTERFACE_MAP_END
Console::Console(nsPIDOMWindowInner* aWindow)
: mWindow(aWindow)
#ifdef DEBUG
, mOwningThread(PR_GetCurrentThread())
#endif
, mOuterID(0)
, mInnerID(0)
{
@ -774,15 +811,16 @@ Console::Console(nsPIDOMWindowInner* aWindow)
Console::~Console()
{
AssertIsOnOwningThread();
MOZ_ASSERT(mConsoleCallDataArray.IsEmpty());
if (!NS_IsMainThread()) {
if (mStorage) {
NS_ReleaseOnMainThread(mStorage);
NS_ReleaseOnMainThread(mStorage.forget());
}
if (mSandbox) {
NS_ReleaseOnMainThread(mSandbox);
NS_ReleaseOnMainThread(mSandbox.forget());
}
}
@ -793,7 +831,7 @@ NS_IMETHODIMP
Console::Observe(nsISupports* aSubject, const char* aTopic,
const char16_t* aData)
{
MOZ_ASSERT(NS_IsMainThread());
AssertIsOnMainThread();
if (strcmp(aTopic, "inner-window-destroyed")) {
return NS_OK;
@ -843,6 +881,8 @@ METHOD(Table, "table")
void
Console::Trace(JSContext* aCx)
{
AssertIsOnOwningThread();
const Sequence<JS::Value> data;
Method(aCx, MethodTrace, NS_LITERAL_STRING("trace"), data);
}
@ -858,6 +898,8 @@ METHOD(GroupEnd, "groupEnd")
void
Console::Time(JSContext* aCx, const JS::Handle<JS::Value> aTime)
{
AssertIsOnOwningThread();
Sequence<JS::Value> data;
SequenceRooter<JS::Value> rooter(aCx, &data);
@ -871,6 +913,8 @@ Console::Time(JSContext* aCx, const JS::Handle<JS::Value> aTime)
void
Console::TimeEnd(JSContext* aCx, const JS::Handle<JS::Value> aTime)
{
AssertIsOnOwningThread();
Sequence<JS::Value> data;
SequenceRooter<JS::Value> rooter(aCx, &data);
@ -884,6 +928,8 @@ Console::TimeEnd(JSContext* aCx, const JS::Handle<JS::Value> aTime)
void
Console::TimeStamp(JSContext* aCx, const JS::Handle<JS::Value> aData)
{
AssertIsOnOwningThread();
Sequence<JS::Value> data;
SequenceRooter<JS::Value> rooter(aCx, &data);
@ -897,12 +943,14 @@ Console::TimeStamp(JSContext* aCx, const JS::Handle<JS::Value> aData)
void
Console::Profile(JSContext* aCx, const Sequence<JS::Value>& aData)
{
AssertIsOnOwningThread();
ProfileMethod(aCx, NS_LITERAL_STRING("profile"), aData);
}
void
Console::ProfileEnd(JSContext* aCx, const Sequence<JS::Value>& aData)
{
AssertIsOnOwningThread();
ProfileMethod(aCx, NS_LITERAL_STRING("profileEnd"), aData);
}
@ -966,6 +1014,8 @@ void
Console::Assert(JSContext* aCx, bool aCondition,
const Sequence<JS::Value>& aData)
{
AssertIsOnOwningThread();
if (!aCondition) {
Method(aCx, MethodAssert, NS_LITERAL_STRING("assert"), aData);
}
@ -976,6 +1026,8 @@ METHOD(Count, "count")
void
Console::NoopMethod()
{
AssertIsOnOwningThread();
// Nothing to do.
}
@ -1053,6 +1105,8 @@ Console::Method(JSContext* aCx, MethodName aMethodName,
const nsAString& aMethodString,
const Sequence<JS::Value>& aData)
{
AssertIsOnOwningThread();
RefPtr<ConsoleCallData> callData(new ConsoleCallData());
ClearException ce(aCx);
@ -1120,6 +1174,8 @@ Console::Method(JSContext* aCx, MethodName aMethodName,
}
}
DOMHighResTimeStamp monotonicTimer;
// Monotonic timer for 'time' and 'timeEnd'
if (aMethodName == MethodTime ||
aMethodName == MethodTimeEnd ||
@ -1133,7 +1189,7 @@ Console::Method(JSContext* aCx, MethodName aMethodName,
return;
}
callData->mMonotonicTimer = performance->Now();
monotonicTimer = performance->Now();
nsDocShell* docShell = static_cast<nsDocShell*>(mWindow->GetDocShell());
RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
@ -1175,12 +1231,36 @@ Console::Method(JSContext* aCx, MethodName aMethodName,
MOZ_ASSERT(workerPrivate);
TimeDuration duration =
mozilla::TimeStamp::Now() - workerPrivate->CreationTimeStamp();
mozilla::TimeStamp::Now() - workerPrivate->NowBaseTimeStamp();
callData->mMonotonicTimer = duration.ToMilliseconds();
monotonicTimer = duration.ToMilliseconds();
}
}
if (aMethodName == MethodTime && !aData.IsEmpty()) {
callData->mStartTimerStatus = StartTimer(aCx, aData[0],
monotonicTimer,
callData->mStartTimerLabel,
&callData->mStartTimerValue);
}
else if (aMethodName == MethodTimeEnd && !aData.IsEmpty()) {
callData->mStopTimerStatus = StopTimer(aCx, aData[0],
monotonicTimer,
callData->mStopTimerLabel,
&callData->mStopTimerDuration);
}
else if (aMethodName == MethodCount) {
ConsoleStackEntry frame;
if (callData->mTopStackFrame) {
frame = *callData->mTopStackFrame;
}
callData->mCountValue = IncreaseCounter(aCx, frame, aData,
callData->mCountLabel);
}
JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
if (NS_IsMainThread()) {
@ -1207,6 +1287,8 @@ enum {
bool
LazyStackGetter(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
{
AssertIsOnMainThread();
JS::CallArgs args = CallArgsFromVp(aArgc, aVp);
JS::Rooted<JSObject*> callee(aCx, &args.callee());
@ -1243,8 +1325,8 @@ void
Console::ProcessCallData(ConsoleCallData* aData, JS::Handle<JSObject*> aGlobal,
const Sequence<JS::Value>& aArguments)
{
AssertIsOnMainThread();
MOZ_ASSERT(aData);
MOZ_ASSERT(NS_IsMainThread());
ConsoleStackEntry frame;
if (aData->mTopStackFrame) {
@ -1322,15 +1404,20 @@ Console::ProcessCallData(ConsoleCallData* aData, JS::Handle<JSObject*> aGlobal,
}
else if (aData->mMethodName == MethodTime && !aArguments.IsEmpty()) {
event.mTimer = StartTimer(cx, aArguments[0], aData->mMonotonicTimer);
event.mTimer = CreateStartTimerValue(cx, aData->mStartTimerLabel,
aData->mStartTimerValue,
aData->mStartTimerStatus);
}
else if (aData->mMethodName == MethodTimeEnd && !aArguments.IsEmpty()) {
event.mTimer = StopTimer(cx, aArguments[0], aData->mMonotonicTimer);
event.mTimer = CreateStopTimerValue(cx, aData->mStopTimerLabel,
aData->mStopTimerDuration,
aData->mStopTimerStatus);
}
else if (aData->mMethodName == MethodCount) {
event.mCounter = IncreaseCounter(cx, frame, aArguments);
event.mCounter = CreateCounterValue(cx, aData->mCountLabel,
aData->mCountValue);
}
// We want to create a console event object and pass it to our
@ -1434,6 +1521,8 @@ namespace {
bool
FlushOutput(JSContext* aCx, Sequence<JS::Value>& aSequence, nsString &aOutput)
{
AssertIsOnMainThread();
if (!aOutput.IsEmpty()) {
JS::Rooted<JSString*> str(aCx, JS_NewUCStringCopyN(aCx,
aOutput.get(),
@ -1460,6 +1549,8 @@ Console::ProcessArguments(JSContext* aCx,
Sequence<JS::Value>& aSequence,
Sequence<JS::Value>& aStyles) const
{
AssertIsOnMainThread();
if (aData.IsEmpty()) {
return true;
}
@ -1697,7 +1788,7 @@ void
Console::MakeFormatString(nsCString& aFormat, int32_t aInteger,
int32_t aMantissa, char aCh) const
{
MOZ_ASSERT(NS_IsMainThread());
AssertIsOnMainThread();
aFormat.Append('%');
if (aInteger >= 0) {
@ -1717,6 +1808,8 @@ Console::ComposeGroupName(JSContext* aCx,
const Sequence<JS::Value>& aData,
nsAString& aName) const
{
AssertIsOnMainThread();
for (uint32_t i = 0; i < aData.Length(); ++i) {
if (i != 0) {
aName.AppendASCII(" ");
@ -1737,13 +1830,52 @@ Console::ComposeGroupName(JSContext* aCx,
}
}
JS::Value
bool
Console::StartTimer(JSContext* aCx, const JS::Value& aName,
DOMHighResTimeStamp aTimestamp)
DOMHighResTimeStamp aTimestamp,
nsAString& aTimerLabel,
DOMHighResTimeStamp* aTimerValue)
{
MOZ_ASSERT(NS_IsMainThread());
AssertIsOnOwningThread();
MOZ_ASSERT(aTimerValue);
*aTimerValue = 0;
if (mTimerRegistry.Count() >= MAX_PAGE_TIMERS) {
return false;
}
JS::Rooted<JS::Value> name(aCx, aName);
JS::Rooted<JSString*> jsString(aCx, JS::ToString(aCx, name));
if (!jsString) {
return false;
}
nsAutoJSString label;
if (!label.init(aCx, jsString)) {
return false;
}
DOMHighResTimeStamp entry;
if (!mTimerRegistry.Get(label, &entry)) {
mTimerRegistry.Put(label, aTimestamp);
} else {
aTimestamp = entry;
}
aTimerLabel = label;
*aTimerValue = aTimestamp;
return true;
}
JS::Value
Console::CreateStartTimerValue(JSContext* aCx, const nsAString& aTimerLabel,
DOMHighResTimeStamp aTimerValue,
bool aTimerStatus) const
{
AssertIsOnMainThread();
if (!aTimerStatus) {
RootedDictionary<ConsoleTimerError> error(aCx);
JS::Rooted<JS::Value> value(aCx);
@ -1756,27 +1888,8 @@ Console::StartTimer(JSContext* aCx, const JS::Value& aName,
RootedDictionary<ConsoleTimerStart> timer(aCx);
JS::Rooted<JS::Value> name(aCx, aName);
JS::Rooted<JSString*> jsString(aCx, JS::ToString(aCx, name));
if (!jsString) {
return JS::UndefinedValue();
}
nsAutoJSString key;
if (!key.init(aCx, jsString)) {
return JS::UndefinedValue();
}
timer.mName = key;
DOMHighResTimeStamp entry;
if (!mTimerRegistry.Get(key, &entry)) {
mTimerRegistry.Put(key, aTimestamp);
} else {
aTimestamp = entry;
}
timer.mStarted = aTimestamp;
timer.mName = aTimerLabel;
timer.mStarted = aTimerValue;
JS::Rooted<JS::Value> value(aCx);
if (!ToJSValue(aCx, timer, &value)) {
@ -1786,33 +1899,53 @@ Console::StartTimer(JSContext* aCx, const JS::Value& aName,
return value;
}
JS::Value
bool
Console::StopTimer(JSContext* aCx, const JS::Value& aName,
DOMHighResTimeStamp aTimestamp)
DOMHighResTimeStamp aTimestamp,
nsAString& aTimerLabel,
double* aTimerDuration)
{
MOZ_ASSERT(NS_IsMainThread());
AssertIsOnOwningThread();
MOZ_ASSERT(aTimerDuration);
*aTimerDuration = 0;
JS::Rooted<JS::Value> name(aCx, aName);
JS::Rooted<JSString*> jsString(aCx, JS::ToString(aCx, name));
if (!jsString) {
return JS::UndefinedValue();
return false;
}
nsAutoJSString key;
if (!key.init(aCx, jsString)) {
return JS::UndefinedValue();
return false;
}
DOMHighResTimeStamp entry;
if (!mTimerRegistry.Get(key, &entry)) {
return JS::UndefinedValue();
return false;
}
mTimerRegistry.Remove(key);
aTimerLabel = key;
*aTimerDuration = aTimestamp - entry;
return true;
}
JS::Value
Console::CreateStopTimerValue(JSContext* aCx, const nsAString& aLabel,
double aDuration, bool aStatus) const
{
AssertIsOnMainThread();
if (!aStatus) {
return JS::UndefinedValue();
}
RootedDictionary<ConsoleTimerEnd> timer(aCx);
timer.mName = key;
timer.mDuration = aTimestamp - entry;
timer.mName = aLabel;
timer.mDuration = aDuration;
JS::Rooted<JS::Value> value(aCx);
if (!ToJSValue(aCx, timer, &value)) {
@ -1826,6 +1959,8 @@ bool
Console::ArgumentsToValueList(const Sequence<JS::Value>& aData,
Sequence<JS::Value>& aSequence) const
{
AssertIsOnMainThread();
for (uint32_t i = 0; i < aData.Length(); ++i) {
if (!aSequence.AppendElement(aData[i], fallible)) {
return false;
@ -1835,11 +1970,12 @@ Console::ArgumentsToValueList(const Sequence<JS::Value>& aData,
return true;
}
JS::Value
uint32_t
Console::IncreaseCounter(JSContext* aCx, const ConsoleStackEntry& aFrame,
const Sequence<JS::Value>& aArguments)
const Sequence<JS::Value>& aArguments,
nsAString& aCountLabel)
{
MOZ_ASSERT(NS_IsMainThread());
AssertIsOnOwningThread();
ClearException ce(aCx);
@ -1864,25 +2000,40 @@ Console::IncreaseCounter(JSContext* aCx, const ConsoleStackEntry& aFrame,
}
uint32_t count = 0;
if (!mCounterRegistry.Get(key, &count)) {
if (mCounterRegistry.Count() >= MAX_PAGE_COUNTERS) {
RootedDictionary<ConsoleCounterError> error(aCx);
JS::Rooted<JS::Value> value(aCx);
if (!ToJSValue(aCx, error, &value)) {
return JS::UndefinedValue();
}
return value;
}
if (!mCounterRegistry.Get(key, &count) &&
mCounterRegistry.Count() >= MAX_PAGE_COUNTERS) {
return MAX_PAGE_COUNTERS;
}
++count;
mCounterRegistry.Put(key, count);
aCountLabel = label;
return count;
}
JS::Value
Console::CreateCounterValue(JSContext* aCx, const nsAString& aCountLabel,
uint32_t aCountValue) const
{
AssertIsOnMainThread();
ClearException ce(aCx);
if (aCountValue == MAX_PAGE_COUNTERS) {
RootedDictionary<ConsoleCounterError> error(aCx);
JS::Rooted<JS::Value> value(aCx);
if (!ToJSValue(aCx, error, &value)) {
return JS::UndefinedValue();
}
return value;
}
RootedDictionary<ConsoleCounter> data(aCx);
data.mLabel = label;
data.mCount = count;
data.mLabel = aCountLabel;
data.mCount = aCountValue;
JS::Rooted<JS::Value> value(aCx);
if (!ToJSValue(aCx, data, &value)) {
@ -1909,7 +2060,7 @@ Console::ShouldIncludeStackTrace(MethodName aMethodName) const
JSObject*
Console::GetOrCreateSandbox(JSContext* aCx, nsIPrincipal* aPrincipal)
{
MOZ_ASSERT(NS_IsMainThread());
AssertIsOnMainThread();
if (!mSandbox) {
nsIXPConnect* xpc = nsContentUtils::XPConnect();
@ -1930,6 +2081,8 @@ Console::GetOrCreateSandbox(JSContext* aCx, nsIPrincipal* aPrincipal)
void
Console::RegisterConsoleCallData(ConsoleCallData* aData)
{
AssertIsOnOwningThread();
MOZ_ASSERT(!mConsoleCallDataArray.Contains(aData));
mConsoleCallDataArray.AppendElement(aData);
}
@ -1937,9 +2090,18 @@ Console::RegisterConsoleCallData(ConsoleCallData* aData)
void
Console::UnregisterConsoleCallData(ConsoleCallData* aData)
{
AssertIsOnOwningThread();
MOZ_ASSERT(mConsoleCallDataArray.Contains(aData));
mConsoleCallDataArray.RemoveElement(aData);
}
void
Console::AssertIsOnOwningThread() const
{
MOZ_ASSERT(mOwningThread);
MOZ_ASSERT(PR_GetCurrentThread() == mOwningThread);
}
} // namespace dom
} // namespace mozilla

View File

@ -181,13 +181,67 @@ private:
ComposeGroupName(JSContext* aCx, const Sequence<JS::Value>& aData,
nsAString& aName) const;
JS::Value
// StartTimer is called on the owning thread and populates aTimerLabel and
// aTimerValue. It returns false if a JS exception is thrown or if
// the max number of timers is reached.
// * aCx - the JSContext rooting aName.
// * aName - this is (should be) the name of the timer as JS::Value.
// * aTimestamp - the monotonicTimer for this context (taken from
// window->performance.now() or from Now() -
// workerPrivate->NowBaseTimeStamp() in workers.
// * aTimerLabel - This label will be populated with the aName converted to a
// string.
// * aTimerValue - the StartTimer value stored into (or taken from)
// mTimerRegistry.
bool
StartTimer(JSContext* aCx, const JS::Value& aName,
DOMHighResTimeStamp aTimestamp);
DOMHighResTimeStamp aTimestamp,
nsAString& aTimerLabel,
DOMHighResTimeStamp* aTimerValue);
// CreateStartTimerValue is called on the main thread only and generates a
// ConsoleTimerStart dictionary exposed as JS::Value. If aTimerStatus is
// false, it generates a ConsoleTimerError instead. It's called only after
// the execution StartTimer on the owning thread.
// * aCx - this is the context that will root the returned value.
// * aTimerLabel - this label must be what StartTimer received as aTimerLabel.
// * aTimerValue - this is what StartTimer received as aTimerValue
// * aTimerStatus - the return value of StartTimer.
JS::Value
CreateStartTimerValue(JSContext* aCx, const nsAString& aTimerLabel,
DOMHighResTimeStamp aTimerValue,
bool aTimerStatus) const;
// StopTimer follows the same pattern as StartTimer: it runs on the
// owning thread and populates aTimerLabel and aTimerDuration, used by
// CreateStopTimerValue on the main thread. It returns false if a JS
// exception is thrown or if the aName timer doesn't exist in mTimerRegistry.
// * aCx - the JSContext rooting aName.
// * aName - this is (should be) the name of the timer as JS::Value.
// * aTimestamp - the monotonicTimer for this context (taken from
// window->performance.now() or from Now() -
// workerPrivate->NowBaseTimeStamp() in workers.
// * aTimerLabel - This label will be populated with the aName converted to a
// string.
// * aTimerDuration - the difference between aTimestamp and when the timer
// started (see StartTimer).
bool
StopTimer(JSContext* aCx, const JS::Value& aName,
DOMHighResTimeStamp aTimestamp);
DOMHighResTimeStamp aTimestamp,
nsAString& aTimerLabel,
double* aTimerDuration);
// Executed on the main thread and generates a ConsoleTimerEnd dictionary
// exposed as JS::Value, or a ConsoleTimerError dictionary if aTimerStatus is
// false. See StopTimer.
// * aCx - this is the context that will root the returned value.
// * aTimerLabel - this label must be what StopTimer received as aTimerLabel.
// * aTimerDuration - this is what StopTimer received as aTimerDuration
// * aTimerStatus - the return value of StopTimer.
JS::Value
CreateStopTimerValue(JSContext* aCx, const nsAString& aTimerLabel,
double aTimerDuration,
bool aTimerStatus) const;
// The method populates a Sequence from an array of JS::Value.
bool
@ -198,9 +252,29 @@ private:
ProfileMethod(JSContext* aCx, const nsAString& aAction,
const Sequence<JS::Value>& aData);
JS::Value
// This method follows the same pattern as StartTimer: its runs on the owning
// thread and populates aCountLabel, used by CreateCounterValue on the
// main thread. Returns MAX_PAGE_COUNTERS in case of error otherwise the
// incremented counter value.
// * aCx - the JSContext rooting aData.
// * aFrame - the first frame of ConsoleCallData.
// * aData - the arguments received by the console.count() method.
// * aCountLabel - the label that will be populated by this method.
uint32_t
IncreaseCounter(JSContext* aCx, const ConsoleStackEntry& aFrame,
const Sequence<JS::Value>& aArguments);
const Sequence<JS::Value>& aData,
nsAString& aCountLabel);
// Executed on the main thread and generates a ConsoleCounter dictionary as
// JS::Value. If aCountValue is == MAX_PAGE_COUNTERS it generates a
// ConsoleCounterError instead. See IncreaseCounter.
// * aCx - this is the context that will root the returned value.
// * aCountLabel - this label must be what IncreaseCounter received as
// aTimerLabel.
// * aCountValue - the return value of IncreaseCounter.
JS::Value
CreateCounterValue(JSContext* aCx, const nsAString& aCountLabel,
uint32_t aCountValue) const;
bool
ShouldIncludeStackTrace(MethodName aMethodName) const;
@ -214,21 +288,26 @@ private:
void
UnregisterConsoleCallData(ConsoleCallData* aData);
// All these nsCOMPtr are touched on main-thread only.
void
AssertIsOnOwningThread() const;
// All these nsCOMPtr are touched on main thread only.
nsCOMPtr<nsPIDOMWindowInner> mWindow;
nsCOMPtr<nsIConsoleAPIStorage> mStorage;
RefPtr<JSObjectHolder> mSandbox;
// Touched on main-thread only.
// Touched on the owner thread.
nsDataHashtable<nsStringHashKey, DOMHighResTimeStamp> mTimerRegistry;
// Touched on main-thread only.
nsDataHashtable<nsStringHashKey, uint32_t> mCounterRegistry;
// Raw pointers because ConsoleCallData manages its own
// registration/unregistration.
nsTArray<ConsoleCallData*> mConsoleCallDataArray;
#ifdef DEBUG
PRThread* mOwningThread;
#endif
uint64_t mOuterID;
uint64_t mInnerID;

View File

@ -45,7 +45,6 @@
#include "nsNameSpaceManager.h"
#include "nsContentList.h"
#include "nsVariant.h"
#include "nsDOMSettableTokenList.h"
#include "nsDOMTokenList.h"
#include "nsXBLPrototypeBinding.h"
#include "nsError.h"
@ -3066,11 +3065,11 @@ Element::GetLinkTarget(nsAString& aTarget)
}
static void
nsDOMSettableTokenListPropertyDestructor(void *aObject, nsIAtom *aProperty,
void *aPropertyValue, void *aData)
nsDOMTokenListPropertyDestructor(void *aObject, nsIAtom *aProperty,
void *aPropertyValue, void *aData)
{
nsDOMSettableTokenList* list =
static_cast<nsDOMSettableTokenList*>(aPropertyValue);
nsDOMTokenList* list =
static_cast<nsDOMTokenList*>(aPropertyValue);
NS_RELEASE(list);
}
@ -3092,7 +3091,7 @@ Element::HTMLSVGPropertiesToTraverseAndUnlink()
return sPropertiesToTraverseAndUnlink;
}
nsDOMSettableTokenList*
nsDOMTokenList*
Element::GetTokenList(nsIAtom* aAtom)
{
#ifdef DEBUG
@ -3108,14 +3107,14 @@ Element::GetTokenList(nsIAtom* aAtom)
MOZ_ASSERT(found, "Trying to use an unknown tokenlist!");
#endif
nsDOMSettableTokenList* list = nullptr;
nsDOMTokenList* list = nullptr;
if (HasProperties()) {
list = static_cast<nsDOMSettableTokenList*>(GetProperty(aAtom));
list = static_cast<nsDOMTokenList*>(GetProperty(aAtom));
}
if (!list) {
list = new nsDOMSettableTokenList(this, aAtom);
list = new nsDOMTokenList(this, aAtom);
NS_ADDREF(list);
SetProperty(aAtom, list, nsDOMSettableTokenListPropertyDestructor);
SetProperty(aAtom, list, nsDOMTokenListPropertyDestructor);
}
return list;
}
@ -3132,7 +3131,7 @@ Element::GetTokenList(nsIAtom* aAtom, nsIVariant** aResult)
nsresult
Element::SetTokenList(nsIAtom* aAtom, nsIVariant* aValue)
{
nsDOMSettableTokenList* itemType = GetTokenList(aAtom);
nsDOMTokenList* itemType = GetTokenList(aAtom);
nsAutoString string;
aValue->GetAsAString(string);
ErrorResult rv;

View File

@ -44,7 +44,6 @@ class nsIURI;
class nsIScrollableFrame;
class nsAttrValueOrString;
class nsContentList;
class nsDOMSettableTokenList;
class nsDOMTokenList;
struct nsRect;
class nsFocusManager;
@ -1298,7 +1297,7 @@ protected:
*/
virtual void GetLinkTarget(nsAString& aTarget);
nsDOMSettableTokenList* GetTokenList(nsIAtom* aAtom);
nsDOMTokenList* GetTokenList(nsIAtom* aAtom);
void GetTokenList(nsIAtom* aAtom, nsIVariant** aResult);
nsresult SetTokenList(nsIAtom* aAtom, nsIVariant* aValue);

View File

@ -57,9 +57,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ProcessGlobal)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
for (uint32_t i = 0; i < tmp->mAnonymousGlobalScopes.Length(); ++i) {
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mAnonymousGlobalScopes[i])
}
tmp->nsMessageManagerScriptExecutor::Trace(aCallbacks, aClosure);
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ProcessGlobal)

View File

@ -629,8 +629,8 @@ WebSocketImpl::Disconnect()
// until the end of the method.
RefPtr<WebSocketImpl> kungfuDeathGrip = this;
NS_ReleaseOnMainThread(mChannel);
NS_ReleaseOnMainThread(static_cast<nsIWebSocketEventService*>(mService.forget().take()));
NS_ReleaseOnMainThread(mChannel.forget());
NS_ReleaseOnMainThread(mService.forget());
mWebSocket->DontKeepAliveAnyMore();
mWebSocket->mImpl = nullptr;

View File

@ -281,7 +281,6 @@ UNIFIED_SOURCES += [
'nsDOMNavigationTiming.cpp',
'nsDOMScriptObjectFactory.cpp',
'nsDOMSerializer.cpp',
'nsDOMSettableTokenList.cpp',
'nsDOMTokenList.cpp',
'nsDOMWindowList.cpp',
'nsFocusManager.cpp',

View File

@ -1,29 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* Implementation of DOMSettableTokenList specified by HTML5.
*/
#include "nsDOMSettableTokenList.h"
#include "mozilla/dom/DOMSettableTokenListBinding.h"
#include "mozilla/dom/Element.h"
void
nsDOMSettableTokenList::SetValue(const nsAString& aValue, mozilla::ErrorResult& rv)
{
if (!mElement) {
return;
}
rv = mElement->SetAttr(kNameSpaceID_None, mAttrAtom, aValue, true);
}
JSObject*
nsDOMSettableTokenList::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
{
return mozilla::dom::DOMSettableTokenListBinding::Wrap(cx, this, aGivenProto);
}

View File

@ -1,35 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* Implementation of DOMSettableTokenList specified by HTML5.
*/
#ifndef nsDOMSettableTokenList_h___
#define nsDOMSettableTokenList_h___
#include "nsDOMTokenList.h"
class nsIAtom;
// nsISupports must be on the primary inheritance chain
// because nsDOMSettableTokenList is traversed by Element.
class nsDOMSettableTokenList final : public nsDOMTokenList
{
public:
nsDOMSettableTokenList(mozilla::dom::Element* aElement, nsIAtom* aAttrAtom)
: nsDOMTokenList(aElement, aAttrAtom) {}
virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
// WebIDL
void GetValue(nsAString& aResult) { Stringify(aResult); }
void SetValue(const nsAString& aValue, mozilla::ErrorResult& rv);
};
#endif // nsDOMSettableTokenList_h___

View File

@ -9,7 +9,6 @@
*/
#include "nsDOMTokenList.h"
#include "nsAttrValue.h"
#include "nsContentUtils.h"
#include "nsError.h"
@ -74,6 +73,16 @@ nsDOMTokenList::IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aResult)
}
}
void
nsDOMTokenList::SetValue(const nsAString& aValue, mozilla::ErrorResult& rv)
{
if (!mElement) {
return;
}
rv = mElement->SetAttr(kNameSpaceID_None, mAttrAtom, aValue, true);
}
nsresult
nsDOMTokenList::CheckToken(const nsAString& aStr)
{

View File

@ -26,7 +26,7 @@ class nsAttrValue;
class nsIAtom;
// nsISupports must be on the primary inheritance chain
// because nsDOMSettableTokenList is traversed by Element.
class nsDOMTokenList : public nsISupports,
public nsWrapperCache
{
@ -66,6 +66,9 @@ public:
bool Toggle(const nsAString& aToken,
const mozilla::dom::Optional<bool>& force,
mozilla::ErrorResult& aError);
void GetValue(nsAString& aResult) { Stringify(aResult); }
void SetValue(const nsAString& aValue, mozilla::ErrorResult& rv);
void Stringify(nsAString& aResult);
protected:

View File

@ -1791,6 +1791,14 @@ nsMessageManagerScriptExecutor::TryCacheLoadAndCompileScript(
TryCacheLoadAndCompileScript(aURL, aRunInGlobalScope, true, &script);
}
void
nsMessageManagerScriptExecutor::Trace(const TraceCallbacks& aCallbacks, void* aClosure)
{
for (size_t i = 0, length = mAnonymousGlobalScopes.Length(); i < length; ++i) {
aCallbacks.Trace(&mAnonymousGlobalScopes[i], "mAnonymousGlobalScopes[i]", aClosure);
}
}
bool
nsMessageManagerScriptExecutor::InitChildGlobalInternal(
nsISupports* aScope,

View File

@ -397,6 +397,7 @@ protected:
void TryCacheLoadAndCompileScript(const nsAString& aURL,
bool aRunInGlobalScope);
bool InitChildGlobalInternal(nsISupports* aScope, const nsACString& aID);
void Trace(const TraceCallbacks& aCallbacks, void* aClosure);
nsCOMPtr<nsIXPConnectJSObjectHolder> mGlobal;
nsCOMPtr<nsIPrincipal> mPrincipal;
AutoTArray<JS::Heap<JSObject*>, 2> mAnonymousGlobalScopes;

View File

@ -146,9 +146,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(nsInProcessTabChildGlobal,
DOMEventTargetHelper)
for (uint32_t i = 0; i < tmp->mAnonymousGlobalScopes.Length(); ++i) {
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mAnonymousGlobalScopes[i])
}
tmp->nsMessageManagerScriptExecutor::Trace(aCallbacks, aClosure);
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsInProcessTabChildGlobal,

View File

@ -782,17 +782,8 @@ nsScriptLoader::ProcessOffThreadRequest(nsScriptLoadRequest* aRequest)
NotifyOffThreadScriptLoadCompletedRunnable::~NotifyOffThreadScriptLoadCompletedRunnable()
{
if (MOZ_UNLIKELY(mRequest || mLoader) && !NS_IsMainThread()) {
nsCOMPtr<nsIThread> mainThread;
NS_GetMainThread(getter_AddRefs(mainThread));
if (mainThread) {
NS_ProxyRelease(mainThread, mRequest);
NS_ProxyRelease(mainThread, mLoader);
} else {
MOZ_ASSERT(false, "We really shouldn't leak!");
// Better to leak than crash.
Unused << mRequest.forget();
Unused << mLoader.forget();
}
NS_ReleaseOnMainThread(mRequest.forget());
NS_ReleaseOnMainThread(mLoader.forget());
}
}

View File

@ -22,7 +22,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=346485
/** Test for Bug 346485 **/
/**
* This test is testing DOMSettableTokenList used by the output element.
* This test is testing DOMTokenList used by the output element.
*/
function checkHtmlFor(htmlFor, list, msg) {

View File

@ -35,14 +35,14 @@ function loadFileContent(aFile, aCharset) {
null, // aLoadingNode
SpecialPowers.Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
SpecialPowers.Ci.nsILoadInfo.SEC_NORMAL,
SpecialPowers.Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
SpecialPowers.Ci.nsIContentPolicy.TYPE_OTHER);
var cis = SpecialPowers.Ci.nsIConverterInputStream;
var inputStream = SpecialPowers.Cc["@mozilla.org/intl/converter-input-stream;1"]
.createInstance(cis);
inputStream.init(chann.open(), aCharset, 1024, cis.DEFAULT_REPLACEMENT_CHARACTER);
inputStream.init(chann.open2(), aCharset, 1024, cis.DEFAULT_REPLACEMENT_CHARACTER);
var str = {}, content = '';
while (inputStream.readString(4096, str) != 0) {
content += str.value;

View File

@ -35,14 +35,14 @@ function loadFileContent(aFile, aCharset) {
null, // aLoadingNode
SpecialPowers.Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
SpecialPowers.Ci.nsILoadInfo.SEC_NORMAL,
SpecialPowers.Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
SpecialPowers.Ci.nsIContentPolicy.TYPE_OTHER);
var cis = SpecialPowers.Ci.nsIConverterInputStream;
var inputStream = SpecialPowers.Cc["@mozilla.org/intl/converter-input-stream;1"]
.createInstance(cis);
inputStream.init(chann.open(), aCharset, 1024, cis.DEFAULT_REPLACEMENT_CHARACTER);
inputStream.init(chann.open2(), aCharset, 1024, cis.DEFAULT_REPLACEMENT_CHARACTER);
var str = {}, content = '';
while (inputStream.readString(4096, str) != 0) {
content += str.value;

View File

@ -35,14 +35,14 @@ function loadFileContent(aFile, aCharset) {
null, // aLoadingNode
SpecialPowers.Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
SpecialPowers.Ci.nsILoadInfo.SEC_NORMAL,
SpecialPowers.Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
SpecialPowers.Ci.nsIContentPolicy.TYPE_OTHER);
var cis = SpecialPowers.Ci.nsIConverterInputStream;
var inputStream = SpecialPowers.Cc["@mozilla.org/intl/converter-input-stream;1"]
.createInstance(cis);
inputStream.init(chann.open(), aCharset, 1024, cis.DEFAULT_REPLACEMENT_CHARACTER);
inputStream.init(chann.open2(), aCharset, 1024, cis.DEFAULT_REPLACEMENT_CHARACTER);
var str = {}, content = '';
while (inputStream.readString(4096, str) != 0) {
content += str.value;

View File

@ -35,14 +35,14 @@ function loadFileContent(aFile, aCharset) {
null, // aLoadingNode
SpecialPowers.Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
SpecialPowers.Ci.nsILoadInfo.SEC_NORMAL,
SpecialPowers.Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
SpecialPowers.Ci.nsIContentPolicy.TYPE_OTHER);
var cis = SpecialPowers.Ci.nsIConverterInputStream;
var inputStream = SpecialPowers.Cc["@mozilla.org/intl/converter-input-stream;1"]
.createInstance(cis);
inputStream.init(chann.open(), aCharset, 1024, cis.DEFAULT_REPLACEMENT_CHARACTER);
inputStream.init(chann.open2(), aCharset, 1024, cis.DEFAULT_REPLACEMENT_CHARACTER);
var str = {}, content = '';
while (inputStream.readString(4096, str) != 0) {
content += str.value;

View File

@ -34,14 +34,14 @@ function loadFileContent(aFile, aCharset) {
null, // aLoadingNode
SpecialPowers.Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
SpecialPowers.Ci.nsILoadInfo.SEC_NORMAL,
SpecialPowers.Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
SpecialPowers.Ci.nsIContentPolicy.TYPE_OTHER);
var cis = SpecialPowers.Ci.nsIConverterInputStream;
var inputStream = SpecialPowers.Cc["@mozilla.org/intl/converter-input-stream;1"]
.createInstance(cis);
inputStream.init(chann.open(), aCharset, 1024, cis.DEFAULT_REPLACEMENT_CHARACTER);
inputStream.init(chann.open2(), aCharset, 1024, cis.DEFAULT_REPLACEMENT_CHARACTER);
var str = {}, content = '';
while (inputStream.readString(4096, str) != 0) {
content += str.value;

View File

@ -98,15 +98,20 @@ function assignToClassListStrict(e) {
"use strict";
try {
e.classList = "foo";
ok(false, "assigning to classList didn't throw");
} catch (e) { }
ok(true, "assigning to classList didn't throw");
e.removeAttribute("class");
} catch (e) {
ok(false, "assigning to classList threw");
}
}
function assignToClassList(e) {
try {
var expect = e.classList;
e.classList = "foo";
ok(true, "assigning to classList didn't throw");
is(e.classList, expect, "classList should be unchanged after assignment");
e.removeAttribute("class");
} catch (e) {
ok(false, "assigning to classList threw");
}
@ -160,8 +165,6 @@ function testClassList(e) {
ok(DOMTokenList.prototype.hasOwnProperty("toString"),
"Should have own toString on DOMTokenList")
ok(!DOMSettableTokenList.prototype.hasOwnProperty("toString"),
"Should not have own toString on DOMSettableTokenList")
e.removeAttribute("class");
is(e.classList.toString(), "", "wrong classList.toString() value");

View File

@ -437,10 +437,6 @@ DOMInterfaces = {
'implicitJSContext': [ 'then' ],
},
'DOMSettableTokenList': {
'nativeType': 'nsDOMSettableTokenList',
},
'DOMStringMap': {
'nativeType': 'nsDOMStringMap'
},

View File

@ -62,10 +62,7 @@ ManagerId::~ManagerId()
// The PBackground worker thread shouldn't be running after the main thread
// is stopped. So main thread is guaranteed to exist here.
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
MOZ_ASSERT(mainThread);
NS_ProxyRelease(mainThread, mPrincipal.forget().take());
NS_ReleaseOnMainThread(mPrincipal.forget());
}
} // namespace cache

View File

@ -139,8 +139,11 @@ CanvasRenderingContextHelper::CreateContext(CanvasContextType aContextType)
Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_USED, 1);
ret = WebGL1Context::Create();
if (!ret)
if (!ret) {
Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_SUCCESS, 0);
return nullptr;
}
Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_SUCCESS, 1);
break;
@ -148,8 +151,11 @@ CanvasRenderingContextHelper::CreateContext(CanvasContextType aContextType)
Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_USED, 1);
ret = WebGL2Context::Create();
if (!ret)
if (!ret) {
Telemetry::Accumulate(Telemetry::CANVAS_WEBGL2_SUCCESS, 0);
return nullptr;
}
Telemetry::Accumulate(Telemetry::CANVAS_WEBGL2_SUCCESS, 1);
break;

View File

@ -860,7 +860,7 @@ DeviceStorageStatics::ListenerWrapper::ListenerWrapper(nsDOMDeviceStorage* aList
DeviceStorageStatics::ListenerWrapper::~ListenerWrapper()
{
// Even weak pointers are not thread safe
NS_ProxyRelease(mOwningThread, mListener);
NS_ProxyRelease(mOwningThread, mListener.forget());
}
bool

View File

@ -3716,8 +3716,7 @@ DeviceStorageRequestManager::~DeviceStorageRequestManager()
while (i > 0) {
--i;
DS_LOG_ERROR("terminate %u", mPending[i].mId);
NS_ProxyRelease(mOwningThread,
NS_ISUPPORTS_CAST(EventTarget*, mPending[i].mRequest.forget().take()));
NS_ProxyRelease(mOwningThread, mPending[i].mRequest.forget());
}
}
}

View File

@ -872,7 +872,7 @@ nsresult nsGeolocationService::Init()
return NS_ERROR_FAILURE;
}
obs->AddObserver(this, "quit-application", false);
obs->AddObserver(this, "xpcom-shutdown", false);
obs->AddObserver(this, "mozsettings-changed", false);
#ifdef MOZ_ENABLE_QT5GEOPOSITION
@ -980,10 +980,10 @@ nsGeolocationService::Observe(nsISupports* aSubject,
const char* aTopic,
const char16_t* aData)
{
if (!strcmp("quit-application", aTopic)) {
if (!strcmp("xpcom-shutdown", aTopic)) {
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (obs) {
obs->RemoveObserver(this, "quit-application");
obs->RemoveObserver(this, "xpcom-shutdown");
obs->RemoveObserver(this, "mozsettings-changed");
}

View File

@ -10,7 +10,7 @@
#include "mozilla/Attributes.h"
#include "nsGenericHTMLFrameElement.h"
#include "nsIDOMHTMLIFrameElement.h"
#include "nsDOMSettableTokenList.h"
#include "nsDOMTokenList.h"
namespace mozilla {
namespace dom {
@ -84,7 +84,7 @@ public:
{
SetHTMLAttr(nsGkAtoms::name, aName, aError);
}
nsDOMSettableTokenList* Sandbox()
nsDOMTokenList* Sandbox()
{
return GetTokenList(nsGkAtoms::sandbox);
}

View File

@ -119,7 +119,7 @@ public:
{
SetHTMLAttr(nsGkAtoms::hreflang, aHreflang, aRv);
}
nsDOMSettableTokenList* Sizes()
nsDOMTokenList* Sizes()
{
return GetTokenList(nsGkAtoms::sizes);
}

View File

@ -1431,6 +1431,8 @@ NS_IMETHODIMP HTMLMediaElement::GetCurrentTime(double* aCurrentTime)
void
HTMLMediaElement::FastSeek(double aTime, ErrorResult& aRv)
{
LOG(LogLevel::Debug, ("Reporting telemetry VIDEO_FASTSEEK_USED"));
Telemetry::Accumulate(Telemetry::VIDEO_FASTSEEK_USED, 1);
Seek(aTime, SeekTarget::PrevSyncPoint, aRv);
}

View File

@ -11,7 +11,7 @@
#include "mozilla/dom/HTMLFormElement.h"
#include "mozilla/dom/HTMLOutputElementBinding.h"
#include "nsContentUtils.h"
#include "nsDOMSettableTokenList.h"
#include "nsDOMTokenList.h"
#include "nsFormSubmission.h"
NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Output)
@ -166,11 +166,11 @@ HTMLOutputElement::SetDefaultValue(const nsAString& aDefaultValue, ErrorResult&
}
}
nsDOMSettableTokenList*
nsDOMTokenList*
HTMLOutputElement::HtmlFor()
{
if (!mTokenList) {
mTokenList = new nsDOMSettableTokenList(this, nsGkAtoms::_for);
mTokenList = new nsDOMTokenList(this, nsGkAtoms::_for);
}
return mTokenList;
}

View File

@ -64,7 +64,7 @@ public:
virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
// WebIDL
nsDOMSettableTokenList* HtmlFor();
nsDOMTokenList* HtmlFor();
// nsGenericHTMLFormElement::GetForm is fine.
void GetName(nsAString& aName)
{
@ -108,7 +108,7 @@ protected:
ValueModeFlag mValueModeFlag;
bool mIsDoneAddingChildren;
nsString mDefaultValue;
RefPtr<nsDOMSettableTokenList> mTokenList;
RefPtr<nsDOMTokenList> mTokenList;
};
} // namespace dom

View File

@ -9,7 +9,7 @@
#include "nsContentUtils.h"
#include "nsGenericHTMLElement.h"
#include "nsVariant.h"
#include "nsDOMSettableTokenList.h"
#include "nsDOMTokenList.h"
#include "nsAttrValue.h"
#include "nsWrapperCacheInlines.h"
#include "mozilla/dom/HTMLPropertiesCollectionBinding.h"

View File

@ -47,7 +47,7 @@ public:
{
SetHTMLIntAttr(nsGkAtoms::rowspan, aRowSpan, aError);
}
//already_AddRefed<nsDOMSettableTokenList> Headers() const;
//already_AddRefed<nsDOMTokenList> Headers() const;
void GetHeaders(DOMString& aHeaders)
{
GetHTMLAttr(nsGkAtoms::headers, aHeaders);

View File

@ -96,7 +96,7 @@
#include "HTMLPropertiesCollection.h"
#include "nsVariant.h"
#include "nsDOMSettableTokenList.h"
#include "nsDOMTokenList.h"
#include "nsThreadUtils.h"
#include "nsTextFragment.h"
#include "mozilla/dom/BindingUtils.h"

View File

@ -20,7 +20,7 @@
#include "mozilla/dom/ValidityState.h"
#include "mozilla/dom/ElementInlines.h"
class nsDOMSettableTokenList;
class nsDOMTokenList;
class nsIDOMHTMLMenuElement;
class nsIEditor;
class nsIFormControlFrame;
@ -104,7 +104,7 @@ public:
{
SetHTMLBoolAttr(nsGkAtoms::itemscope, aItemScope, aError);
}
nsDOMSettableTokenList* ItemType()
nsDOMTokenList* ItemType()
{
return GetTokenList(nsGkAtoms::itemtype);
}
@ -116,11 +116,11 @@ public:
{
SetHTMLAttr(nsGkAtoms::itemid, aItemID, aError);
}
nsDOMSettableTokenList* ItemRef()
nsDOMTokenList* ItemRef()
{
return GetTokenList(nsGkAtoms::itemref);
}
nsDOMSettableTokenList* ItemProp()
nsDOMTokenList* ItemProp()
{
return GetTokenList(nsGkAtoms::itemprop);
}

View File

@ -109,7 +109,7 @@ function checkHtmlForIDLAttribute(element)
is(String(element.htmlFor), 'a b',
"htmlFor IDL attribute should reflect the for content attribute");
// DOMSettableTokenList is tested in another bug so we just test assignation
// DOMTokenList is tested in another bug so we just test assignation
element.htmlFor.value = 'a b c';
is(String(element.htmlFor), 'a b c', "htmlFor should have changed");
}

View File

@ -26,8 +26,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=845057
return ((a+'').split(" ").sort()+'') == ((b+'').split(" ").sort()+'');
}
ok(attr instanceof DOMSettableTokenList,
"Iframe sandbox attribute is instace of DOMSettableTokenList");
ok(attr instanceof DOMTokenList,
"Iframe sandbox attribute is instace of DOMTokenList");
ok(eq(attr, "allow-scripts") &&
eq(iframe.getAttribute("sandbox"), "allow-scripts"),
"Stringyfied sandbox attribute is same as that of the DOM element");

View File

@ -33,8 +33,7 @@ var interfaces = [
"HTMLCollection",
"DOMStringList",
"DOMTokenList",
"DOMSettableTokenList"
];
];
test(function() {
for (var p in window) {
interfaces.forEach(function(i) {

View File

@ -249,6 +249,7 @@ interface Element : Node {
attribute DOMString id;
attribute DOMString className;
[PutForwards=value]
readonly attribute DOMTokenList classList;
readonly attribute Attr[] attributes;
@ -414,10 +415,7 @@ interface DOMTokenList {
void remove(DOMString... tokens);
boolean toggle(DOMString token, optional boolean force);
stringifier;
};
interface DOMSettableTokenList : DOMTokenList {
attribute DOMString value;
attribute DOMString value;
};
</script>
<script>

View File

@ -379,7 +379,9 @@ function workerScript() {
};
self.executeSoon = function(_fun_) {
setTimeout(_fun_, 0);
var channel = new MessageChannel();
channel.port1.postMessage("");
channel.port2.onmessage = function(event) { _fun_(); };
};
self.finishTest = function() {

View File

@ -3,14 +3,6 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
var disableWorkerTest =
"This test requires a precise 'executeSoon()' to complete reliably. On a " +
"worker 'executeSoon()' currently uses 'setTimeout()', and that switches " +
"to the timer thread and back before completing. That gives the IndexedDB " +
"transaction thread time to fully complete transactions and to place " +
"'complete' events in the worker thread's queue before the timer event, " +
"causing ordering problems in the spot marked 'Worker Fails Here' below.";
var testGenerator = testSteps();
var abortFired = false;
@ -338,8 +330,6 @@ function testSteps()
// During COMMITTING
transaction = db.transaction("foo", "readwrite");
transaction.objectStore("foo").put({hello: "world"}, 1).onsuccess = function(event) {
// Worker Fails Here! Due to the thread switching of 'executeSoon()' the
// transaction can commit and fire a 'complete' event before we continue.
continueToNextStep();
};
yield undefined;

View File

@ -3,14 +3,6 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
var disableWorkerTest =
"This test requires a precise 'executeSoon()' to complete reliably. On a " +
"worker 'executeSoon()' currently uses 'setTimeout()', and that switches " +
"to the timer thread and back before completing. That gives the IndexedDB " +
"transaction thread time to fully complete transactions and to place " +
"'complete' events in the worker thread's queue before the timer event, " +
"causing ordering problems in the spot marked 'Worker Fails Here' below.";
var testGenerator = testSteps();
function testSteps()
@ -49,8 +41,6 @@ function testSteps()
let wasAbleToGrabObjectStoreOutsideOfCallback = false;
let wasAbleToGrabIndexOutsideOfCallback = false;
executeSoon(function() {
// Worker Fails Here! Due to the thread switching of 'executeSoon()' the
// transaction can commit and fire a 'complete' event before we continue.
ok(!requestComplete, "Ordering is correct.");
wasAbleToGrabObjectStoreOutsideOfCallback = !!transaction.objectStore("foo");
wasAbleToGrabIndexOutsideOfCallback =

View File

@ -32,7 +32,7 @@ interface nsIDOMHTMLElement : nsIDOMElement
attribute nsIVariant itemType;
attribute DOMString itemId;
readonly attribute nsISupports properties;
// The following attributes are really nsDOMSettableTokenList, which has
// The following attributes are really nsDOMTokenList, which has
// PutForwards, so we express them as nsIVariants to deal with this.
attribute nsIVariant itemValue;
attribute nsIVariant itemProp;

View File

@ -175,9 +175,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(TabChildBase)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(TabChildBase)
for (uint32_t i = 0; i < tmp->mAnonymousGlobalScopes.Length(); ++i) {
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mAnonymousGlobalScopes[i])
}
tmp->nsMessageManagerScriptExecutor::Trace(aCallbacks, aClosure);
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TabChildBase)

View File

@ -333,11 +333,8 @@ public:
mVideoDevice->GetSource()->Stop(source, kVideoTrack);
mVideoDevice->GetSource()->Deallocate();
}
// We consider ourselves finished if all tracks have been stopped, as
// there is no way to restart them from the JS APIs.
if (mBool || ((!mAudioDevice || mAudioDevice->GetSource()->IsAvailable()) &&
(!mVideoDevice || mVideoDevice->GetSource()->IsAvailable()))) {
source->Finish();
if (mType == MEDIA_STOP) {
source->EndAllTrackAndFinish();
}
nsIRunnable *event =
@ -686,26 +683,6 @@ public:
}
}
// For gUM streams, we have a trackunion which assigns TrackIDs. However, for a
// single-source trackunion like we have here, the TrackUnion will assign trackids
// that match the source's trackids, so we can avoid needing a mapping function.
// XXX This will not handle more complex cases well.
void StopTrack(TrackID aTrackID) override
{
if (GetSourceStream()) {
GetSourceStream()->EndTrack(aTrackID);
// We could override NotifyMediaStreamTrackEnded(), and maybe should, but it's
// risky to do late in a release since that will affect all track ends, and not
// just StopTrack()s.
RefPtr<dom::MediaStreamTrack> ownedTrack = FindOwnedDOMTrack(mOwnedStream, aTrackID);
if (ownedTrack) {
mListener->StopTrack(aTrackID, !!ownedTrack->AsAudioStreamTrack());
} else {
LOG(("StopTrack(%d) on non-existent track", aTrackID));
}
}
}
already_AddRefed<Promise>
ApplyConstraintsToTrack(TrackID aTrackID,
const MediaTrackConstraints& aConstraints,
@ -2442,7 +2419,7 @@ StopSharingCallback(MediaManager *aThis,
GetUserMediaCallbackMediaStreamListener *listener = aListeners->ElementAt(i);
if (listener->Stream()) { // aka HasBeenActivate()ed
listener->Invalidate();
listener->Stop();
}
listener->Remove();
listener->StopSharing();
@ -2459,8 +2436,8 @@ MediaManager::OnNavigation(uint64_t aWindowID)
MOZ_ASSERT(NS_IsMainThread());
LOG(("OnNavigation for %llu", aWindowID));
// Invalidate this window. The runnables check this value before making
// a call to content.
// Stop the streams for this window. The runnables check this value before
// making a call to content.
nsTArray<nsString>* callIDs;
if (mCallIds.Get(aWindowID, &callIDs)) {
@ -3092,7 +3069,7 @@ MediaManager::IsActivelyCapturingOrHasAPermission(uint64_t aWindowId)
}
void
GetUserMediaCallbackMediaStreamListener::Invalidate()
GetUserMediaCallbackMediaStreamListener::Stop()
{
MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread");
if (mStopped) {
@ -3108,7 +3085,7 @@ GetUserMediaCallbackMediaStreamListener::Invalidate()
this, nullptr, nullptr,
!mAudioStopped ? mAudioDevice.get() : nullptr,
!mVideoStopped ? mVideoDevice.get() : nullptr,
mFinished, mWindowID, nullptr));
false, mWindowID, nullptr));
mStopped = mAudioStopped = mVideoStopped = true;
}
@ -3117,21 +3094,14 @@ void
GetUserMediaCallbackMediaStreamListener::StopSharing()
{
MOZ_ASSERT(NS_IsMainThread());
if (mVideoDevice && !mStopped &&
if (mVideoDevice &&
(mVideoDevice->GetMediaSource() == dom::MediaSourceEnum::Screen ||
mVideoDevice->GetMediaSource() == dom::MediaSourceEnum::Application ||
mVideoDevice->GetMediaSource() == dom::MediaSourceEnum::Window)) {
// Stop the whole stream if there's no audio; just the video track if we have both
if (!mAudioDevice) {
Invalidate();
} else if (!mVideoStopped) {
MediaManager::PostTask(FROM_HERE,
new MediaOperationTask(MEDIA_STOP_TRACK,
this, nullptr, nullptr,
nullptr, mVideoDevice,
mFinished, mWindowID, nullptr));
mVideoStopped = true;
}
// We want to stop the whole stream if there's no audio;
// just the video track if we have both.
// StopTrack figures this out for us.
StopTrack(kVideoTrack);
} else if (mAudioDevice &&
mAudioDevice->GetMediaSource() == dom::MediaSourceEnum::AudioCapture) {
nsCOMPtr<nsPIDOMWindowInner> window = nsGlobalWindow::GetInnerWindowWithId(mWindowID)->AsInner();
@ -3241,28 +3211,43 @@ GetUserMediaCallbackMediaStreamListener::ApplyConstraintsToTrack(
// Stop backend for track
void
GetUserMediaCallbackMediaStreamListener::StopTrack(TrackID aTrackID, bool aIsAudio)
GetUserMediaCallbackMediaStreamListener::StopTrack(TrackID aTrackID)
{
MOZ_ASSERT(NS_IsMainThread());
if (((aIsAudio && mAudioDevice) ||
(!aIsAudio && mVideoDevice)) && !mStopped)
MOZ_ASSERT(aTrackID == kAudioTrack || aTrackID == kVideoTrack);
// XXX to support multiple tracks of a type in a stream, this should key off
// the TrackID and not just hard coded values.
bool stopAudio = aTrackID == kAudioTrack;
bool stopVideo = aTrackID == kVideoTrack;
if (mStopped ||
(stopAudio && (mAudioStopped || !mAudioDevice)) ||
(stopVideo && (mVideoStopped || !mVideoDevice)))
{
// XXX to support multiple tracks of a type in a stream, this should key off
// the TrackID and not just the type
bool stopAudio = aIsAudio && !mAudioStopped;
bool stopVideo = !aIsAudio && !mVideoStopped;
MediaManager::PostTask(FROM_HERE,
new MediaOperationTask(MEDIA_STOP_TRACK,
this, nullptr, nullptr,
stopAudio ? mAudioDevice.get() : nullptr,
stopVideo ? mVideoDevice.get() : nullptr,
mFinished, mWindowID, nullptr));
mAudioStopped |= stopAudio;
mVideoStopped |= stopVideo;
} else {
LOG(("gUM track %d ended, but we don't have type %s",
aTrackID, aIsAudio ? "audio" : "video"));
LOG(("Can't stop gUM track %d (%s), exists=%d, stopped=%d",
aTrackID,
aTrackID == kAudioTrack ? "audio" : "video",
aTrackID == kAudioTrack ? !!mAudioDevice : !!mVideoDevice,
aTrackID == kAudioTrack ? mAudioStopped : mVideoStopped));
return;
}
if ((stopAudio || mAudioStopped || !mAudioDevice) &&
(stopVideo || mVideoStopped || !mVideoDevice)) {
Stop();
return;
}
MediaManager::PostTask(FROM_HERE,
new MediaOperationTask(MEDIA_STOP_TRACK,
this, nullptr, nullptr,
stopAudio ? mAudioDevice.get() : nullptr,
stopVideo ? mVideoDevice.get() : nullptr,
false , mWindowID, nullptr));
mAudioStopped |= stopAudio;
mVideoStopped |= stopVideo;
}
void
@ -3270,7 +3255,7 @@ GetUserMediaCallbackMediaStreamListener::NotifyFinished()
{
MOZ_ASSERT(NS_IsMainThread());
mFinished = true;
Invalidate(); // we know it's been activated
Stop(); // we know it's been activated
RefPtr<MediaManager> manager(MediaManager::GetInstance());
manager->RemoveFromWindowList(mWindowID, this);

View File

@ -166,7 +166,7 @@ public:
void StopSharing();
void StopTrack(TrackID aID, bool aIsAudio);
void StopTrack(TrackID aID);
typedef media::Pledge<bool, dom::MediaStreamError*> PledgeVoid;
@ -225,7 +225,7 @@ public:
// implement in .cpp to avoid circular dependency with MediaOperationTask
// Can be invoked from EITHER MainThread or MSG thread
void Invalidate();
void Stop();
void
AudioConfig(bool aEchoOn, uint32_t aEcho,
@ -318,7 +318,7 @@ private:
// MainThread only.
bool mAudioStopped;
// true if we have sent MEDIA_STOP or MEDIA_STOP_TRACK for mAudioDevice.
// true if we have sent MEDIA_STOP or MEDIA_STOP_TRACK for mVideoDevice.
// MainThread only.
bool mVideoStopped;

View File

@ -78,6 +78,17 @@ MediaStreamGraphImpl::FinishStream(MediaStream* aStream)
if (aStream->mFinished)
return;
STREAM_LOG(LogLevel::Debug, ("MediaStream %p will finish", aStream));
#ifdef DEBUG
for (StreamBuffer::TrackIter track(aStream->mBuffer);
!track.IsEnded(); track.Next()) {
if (!track->IsEnded()) {
STREAM_LOG(LogLevel::Error,
("MediaStream %p will finish, but track %d has not ended.",
aStream, track->GetID()));
NS_ASSERTION(false, "Finished stream cannot contain live track");
}
}
#endif
aStream->mFinished = true;
aStream->mBuffer.AdvanceKnownTracksTime(STREAM_TIME_MAX);
@ -974,7 +985,7 @@ MediaStreamGraphImpl::OpenAudioInput(CubebUtils::AudioDeviceID aID,
CubebUtils::AudioDeviceID mID;
RefPtr<AudioDataListener> mListener;
};
this->AppendMessage(new Message(this, aID, aListener));
this->AppendMessage(MakeUnique<Message>(this, aID, aListener));
return NS_OK;
}
@ -1041,7 +1052,7 @@ MediaStreamGraphImpl::CloseAudioInput(AudioDataListener *aListener)
MediaStreamGraphImpl *mGraph;
RefPtr<AudioDataListener> mListener;
};
this->AppendMessage(new Message(this, aListener));
this->AppendMessage(MakeUnique<Message>(this, aListener));
}
@ -1155,7 +1166,7 @@ MediaStreamGraphImpl::AllFinishedStreamsNotified()
}
void
MediaStreamGraphImpl::RunMessageAfterProcessing(nsAutoPtr<ControlMessage> aMessage)
MediaStreamGraphImpl::RunMessageAfterProcessing(UniquePtr<ControlMessage> aMessage)
{
MOZ_ASSERT(CurrentDriver()->OnThread());
@ -1175,7 +1186,7 @@ MediaStreamGraphImpl::RunMessagesInQueue()
// batch corresponding to an event loop task). This isolates the performance
// of different scripts to some extent.
for (uint32_t i = 0; i < mFrontMessageQueue.Length(); ++i) {
nsTArray<nsAutoPtr<ControlMessage> >& messages = mFrontMessageQueue[i].mMessages;
nsTArray<UniquePtr<ControlMessage>>& messages = mFrontMessageQueue[i].mMessages;
for (uint32_t j = 0; j < messages.Length(); ++j) {
messages[j]->Run();
@ -1532,7 +1543,7 @@ MediaStreamGraphImpl::RunInStableState(bool aSourceIsMSG)
// When we're doing a forced shutdown, pending control messages may be
// run on the main thread via RunDuringShutdown. Those messages must
// run without the graph monitor being held. So, we collect them here.
nsTArray<nsAutoPtr<ControlMessage> > controlMessagesToRunDuringShutdown;
nsTArray<UniquePtr<ControlMessage>> controlMessagesToRunDuringShutdown;
{
MonitorAutoLock lock(mMonitor);
@ -1710,7 +1721,7 @@ MediaStreamGraphImpl::EnsureStableStateEventPosted()
}
void
MediaStreamGraphImpl::AppendMessage(ControlMessage* aMessage)
MediaStreamGraphImpl::AppendMessage(UniquePtr<ControlMessage> aMessage)
{
MOZ_ASSERT(NS_IsMainThread(), "main thread only");
MOZ_ASSERT(!aMessage->GetStream() ||
@ -1733,7 +1744,6 @@ MediaStreamGraphImpl::AppendMessage(ControlMessage* aMessage)
#ifdef DEBUG
mCanRunMessagesSynchronously = true;
#endif
delete aMessage;
if (IsEmpty() &&
mLifecycleState >= LIFECYCLE_WAITING_FOR_STREAM_DESTRUCTION) {
@ -1747,7 +1757,7 @@ MediaStreamGraphImpl::AppendMessage(ControlMessage* aMessage)
return;
}
mCurrentTaskMessageQueue.AppendElement(aMessage);
mCurrentTaskMessageQueue.AppendElement(Move(aMessage));
EnsureRunInStableState();
}
@ -1925,7 +1935,7 @@ MediaStream::Destroy()
{ Run(); }
};
mWrapper = nullptr;
GraphImpl()->AppendMessage(new Message(this));
GraphImpl()->AppendMessage(MakeUnique<Message>(this));
// Message::RunDuringShutdown may have removed this stream from the graph,
// but our kungFuDeathGrip above will have kept this stream alive if
// necessary.
@ -1944,7 +1954,7 @@ MediaStream::AddAudioOutput(void* aKey)
}
void* mKey;
};
GraphImpl()->AppendMessage(new Message(this, aKey));
GraphImpl()->AppendMessage(MakeUnique<Message>(this, aKey));
}
void
@ -1973,7 +1983,7 @@ MediaStream::SetAudioOutputVolume(void* aKey, float aVolume)
void* mKey;
float mVolume;
};
GraphImpl()->AppendMessage(new Message(this, aKey, aVolume));
GraphImpl()->AppendMessage(MakeUnique<Message>(this, aKey, aVolume));
}
void
@ -2011,7 +2021,7 @@ MediaStream::RemoveAudioOutput(void* aKey)
}
void* mKey;
};
GraphImpl()->AppendMessage(new Message(this, aKey));
GraphImpl()->AppendMessage(MakeUnique<Message>(this, aKey));
}
void
@ -2047,7 +2057,7 @@ MediaStream::AddVideoOutput(VideoFrameContainer* aContainer)
}
RefPtr<VideoFrameContainer> mContainer;
};
GraphImpl()->AppendMessage(new Message(this, aContainer));
GraphImpl()->AppendMessage(MakeUnique<Message>(this, aContainer));
}
void
@ -2063,7 +2073,7 @@ MediaStream::RemoveVideoOutput(VideoFrameContainer* aContainer)
}
RefPtr<VideoFrameContainer> mContainer;
};
GraphImpl()->AppendMessage(new Message(this, aContainer));
GraphImpl()->AppendMessage(MakeUnique<Message>(this, aContainer));
}
void
@ -2084,7 +2094,7 @@ MediaStream::Suspend()
if (mMainThreadDestroyed) {
return;
}
GraphImpl()->AppendMessage(new Message(this));
GraphImpl()->AppendMessage(MakeUnique<Message>(this));
}
void
@ -2105,7 +2115,7 @@ MediaStream::Resume()
if (mMainThreadDestroyed) {
return;
}
GraphImpl()->AppendMessage(new Message(this));
GraphImpl()->AppendMessage(MakeUnique<Message>(this));
}
void
@ -2135,7 +2145,7 @@ MediaStream::AddListener(MediaStreamListener* aListener)
}
RefPtr<MediaStreamListener> mListener;
};
GraphImpl()->AppendMessage(new Message(this, aListener));
GraphImpl()->AppendMessage(MakeUnique<Message>(this, aListener));
}
void
@ -2163,7 +2173,7 @@ MediaStream::RemoveListener(MediaStreamListener* aListener)
// If the stream is destroyed the Listeners have or will be
// removed.
if (!IsDestroyed()) {
GraphImpl()->AppendMessage(new Message(this, aListener));
GraphImpl()->AppendMessage(MakeUnique<Message>(this, aListener));
}
}
@ -2203,7 +2213,7 @@ MediaStream::RunAfterPendingUpdates(already_AddRefed<nsIRunnable> aRunnable)
nsCOMPtr<nsIRunnable> mRunnable;
};
graph->AppendMessage(new Message(this, runnable.forget()));
graph->AppendMessage(MakeUnique<Message>(this, runnable.forget()));
}
void
@ -2232,7 +2242,7 @@ MediaStream::SetTrackEnabled(TrackID aTrackID, bool aEnabled)
TrackID mTrackID;
bool mEnabled;
};
GraphImpl()->AppendMessage(new Message(this, aTrackID, aEnabled));
GraphImpl()->AppendMessage(MakeUnique<Message>(this, aTrackID, aEnabled));
}
void
@ -2439,7 +2449,7 @@ SourceMediaStream::NotifyListenersEvent(MediaStreamListener::MediaStreamGraphEve
}
MediaStreamListener::MediaStreamGraphEvent mEvent;
};
GraphImpl()->AppendMessage(new Message(this, aNewEvent));
GraphImpl()->AppendMessage(MakeUnique<Message>(this, aNewEvent));
}
void
@ -2611,7 +2621,7 @@ MediaInputPort::Destroy()
}
MediaInputPort* mPort;
};
GraphImpl()->AppendMessage(new Message(this));
GraphImpl()->AppendMessage(MakeUnique<Message>(this));
}
MediaStreamGraphImpl*
@ -2661,7 +2671,7 @@ MediaInputPort::BlockTrackId(TrackID aTrackId)
MOZ_ASSERT(aTrackId != TRACK_NONE && aTrackId != TRACK_INVALID && aTrackId != TRACK_ANY,
"Only explicit TrackID is allowed");
GraphImpl()->AppendMessage(new Message(this, aTrackId));
GraphImpl()->AppendMessage(MakeUnique<Message>(this, aTrackId));
}
already_AddRefed<MediaInputPort>
@ -2695,7 +2705,7 @@ ProcessedMediaStream::AllocateInputPort(MediaStream* aStream, TrackID aTrackID,
RefPtr<MediaInputPort> port = new MediaInputPort(aStream, aTrackID, this,
aInputNumber, aOutputNumber);
port->SetGraphImpl(GraphImpl());
GraphImpl()->AppendMessage(new Message(port));
GraphImpl()->AppendMessage(MakeUnique<Message>(port));
return port.forget();
}
@ -2711,7 +2721,7 @@ ProcessedMediaStream::Finish()
mStream->GraphImpl()->FinishStream(mStream);
}
};
GraphImpl()->AppendMessage(new Message(this));
GraphImpl()->AppendMessage(MakeUnique<Message>(this));
}
void
@ -2727,7 +2737,7 @@ ProcessedMediaStream::SetAutofinish(bool aAutofinish)
}
bool mAutofinish;
};
GraphImpl()->AppendMessage(new Message(this, aAutofinish));
GraphImpl()->AppendMessage(MakeUnique<Message>(this, aAutofinish));
}
void
@ -3015,7 +3025,7 @@ MediaStreamGraph::AddStream(MediaStream* aStream)
NS_ADDREF(aStream);
MediaStreamGraphImpl* graph = static_cast<MediaStreamGraphImpl*>(this);
aStream->SetGraphImpl(graph);
graph->AppendMessage(new CreateMessage(aStream));
graph->AppendMessage(MakeUnique<CreateMessage>(aStream));
}
class GraphStartedRunnable final : public nsRunnable
@ -3072,7 +3082,7 @@ MediaStreamGraph::NotifyWhenGraphStarted(AudioNodeStream* aStream)
if (!aStream->IsDestroyed()) {
MediaStreamGraphImpl* graphImpl = static_cast<MediaStreamGraphImpl*>(this);
graphImpl->AppendMessage(new GraphStartedNotificationControlMessage(aStream));
graphImpl->AppendMessage(MakeUnique<GraphStartedNotificationControlMessage>(aStream));
}
}
@ -3291,8 +3301,8 @@ MediaStreamGraph::ApplyAudioContextOperation(MediaStream* aDestinationStream,
MediaStreamGraphImpl* graphImpl = static_cast<MediaStreamGraphImpl*>(this);
graphImpl->AppendMessage(
new AudioContextOperationControlMessage(aDestinationStream, aStreams,
aOperation, aPromise));
MakeUnique<AudioContextOperationControlMessage>(aDestinationStream, aStreams,
aOperation, aPromise));
}
bool

View File

@ -15,6 +15,7 @@
#include "nsIRunnable.h"
#include "nsIAsyncShutdown.h"
#include "Latency.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/WeakPtr.h"
#include "GraphDriver.h"
#include "AudioMixer.h"
@ -80,7 +81,7 @@ protected:
class MessageBlock
{
public:
nsTArray<nsAutoPtr<ControlMessage> > mMessages;
nsTArray<UniquePtr<ControlMessage>> mMessages;
};
/**
@ -139,7 +140,7 @@ public:
* Append a ControlMessage to the message queue. This queue is drained
* during RunInStableState; the messages will run on the graph thread.
*/
void AppendMessage(ControlMessage* aMessage);
void AppendMessage(UniquePtr<ControlMessage> aMessage);
// Shutdown helpers.
@ -293,7 +294,7 @@ public:
* Schedules |aMessage| to run after processing, at a time when graph state
* can be changed. Graph thread.
*/
void RunMessageAfterProcessing(nsAutoPtr<ControlMessage> aMessage);
void RunMessageAfterProcessing(UniquePtr<ControlMessage> aMessage);
/**
* Called when a suspend/resume/close operation has been completed, on the
@ -748,7 +749,7 @@ public:
* immediately because we want all messages between stable states to be
* processed as an atomic batch.
*/
nsTArray<nsAutoPtr<ControlMessage> > mCurrentTaskMessageQueue;
nsTArray<UniquePtr<ControlMessage>> mCurrentTaskMessageQueue;
/**
* True when RunInStableState has determined that mLifecycleState is >
* LIFECYCLE_RUNNING. Since only the main thread can reset mLifecycleState to

View File

@ -7,10 +7,6 @@
#include "mozilla/Logging.h"
#include "nsComponentManagerUtils.h"
#include "nsComponentManagerUtils.h"
#include "nsIInputStream.h"
#include "nsILineInputStream.h"
#include "nsNetUtil.h"
#include "nsCharSeparatedTokenizer.h"
#include "nsThreadUtils.h"
#include "nsIRunnable.h"
#include "nsIWritablePropertyBag2.h"
@ -734,27 +730,14 @@ GMPParent::DeallocPGMPTimerParent(PGMPTimerParent* aActor)
return true;
}
nsresult
ParseNextRecord(nsILineInputStream* aLineInputStream,
const nsCString& aPrefix,
nsCString& aResult,
bool& aMoreLines)
bool
ReadRequiredField(GMPInfoFileParser& aParser, const nsCString& aKey, nsACString& aOutValue)
{
nsAutoCString record;
nsresult rv = aLineInputStream->ReadLine(record, &aMoreLines);
if (NS_FAILED(rv)) {
return rv;
if (!aParser.Contains(aKey) || aParser.Get(aKey).IsEmpty()) {
return false;
}
if (record.Length() <= aPrefix.Length() ||
!Substring(record, 0, aPrefix.Length()).Equals(aPrefix)) {
return NS_ERROR_FAILURE;
}
aResult = Substring(record, aPrefix.Length());
aResult.Trim("\b\t\r\n ");
return NS_OK;
aOutValue = aParser.Get(aKey);
return true;
}
nsresult
@ -770,71 +753,22 @@ GMPParent::ReadGMPMetaData()
}
infoFile->AppendRelativePath(mName + NS_LITERAL_STRING(".info"));
nsCOMPtr<nsIInputStream> inputStream;
rv = NS_NewLocalFileInputStream(getter_AddRefs(inputStream), infoFile);
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsILineInputStream> lineInputStream = do_QueryInterface(inputStream, &rv);
if (NS_FAILED(rv)) {
return rv;
}
nsCString value;
bool moreLines = false;
// 'Name:' record
nsCString prefix = NS_LITERAL_CSTRING("Name:");
rv = ParseNextRecord(lineInputStream, prefix, value, moreLines);
if (NS_FAILED(rv)) {
return rv;
}
if (value.IsEmpty()) {
// Not OK for name to be empty. Must have one non-whitespace character.
GMPInfoFileParser parser;
if (!parser.Init(infoFile)) {
return NS_ERROR_FAILURE;
}
mDisplayName = value;
// 'Description:' record
if (!moreLines) {
nsAutoCString apis;
if (!ReadRequiredField(parser, NS_LITERAL_CSTRING("name"), mDisplayName) ||
!ReadRequiredField(parser, NS_LITERAL_CSTRING("description"), mDescription) ||
!ReadRequiredField(parser, NS_LITERAL_CSTRING("version"), mVersion) ||
!ReadRequiredField(parser, NS_LITERAL_CSTRING("apis"), apis)) {
return NS_ERROR_FAILURE;
}
prefix = NS_LITERAL_CSTRING("Description:");
rv = ParseNextRecord(lineInputStream, prefix, value, moreLines);
if (NS_FAILED(rv)) {
return rv;
}
mDescription = value;
// 'Version:' record
if (!moreLines) {
return NS_ERROR_FAILURE;
}
prefix = NS_LITERAL_CSTRING("Version:");
rv = ParseNextRecord(lineInputStream, prefix, value, moreLines);
if (NS_FAILED(rv)) {
return rv;
}
mVersion = value;
// 'Capability:' record
if (!moreLines) {
return NS_ERROR_FAILURE;
}
prefix = NS_LITERAL_CSTRING("APIs:");
rv = ParseNextRecord(lineInputStream, prefix, value, moreLines);
if (NS_FAILED(rv)) {
return rv;
}
nsCCharSeparatedTokenizer apiTokens(value, ',');
while (apiTokens.hasMoreTokens()) {
nsAutoCString api(apiTokens.nextToken());
api.StripWhitespace();
if (api.IsEmpty()) {
continue;
}
nsTArray<nsCString> apiTokens;
SplitAt(", ", apis, apiTokens);
for (nsCString api : apiTokens) {
int32_t tagsStart = api.FindChar('[');
if (tagsStart == 0) {
// Not allowed to be the first character.
@ -858,9 +792,9 @@ GMPParent::ReadGMPMetaData()
if ((tagsEnd - tagsStart) > 1) {
const nsDependentCSubstring ts(Substring(api, tagsStart + 1, tagsEnd - tagsStart - 1));
nsCCharSeparatedTokenizer tagTokens(ts, ':');
while (tagTokens.hasMoreTokens()) {
const nsDependentCSubstring tag(tagTokens.nextToken());
nsTArray<nsCString> tagTokens;
SplitAt(":", ts, tagTokens);
for (nsCString tag : tagTokens) {
cap->mAPITags.AppendElement(tag);
}
}

View File

@ -169,15 +169,19 @@ GMPInfoFileParser::Init(nsIFile* aInfoFile)
SplitAt("\r\n", info, lines);
for (nsCString line : lines) {
nsTArray<nsCString> tokens;
SplitAt(":", line, tokens);
if (tokens.Length() < 2) {
// Field name is the string up to but not including the first ':'
// character on the line.
int32_t colon = line.FindChar(':');
if (colon <= 0) {
// Not allowed to be the first character.
// Info field name must be at least one character.
continue;
}
nsCString key = tokens[0];
nsAutoCString key(Substring(line, 0, colon));
ToLowerCase(key);
key.Trim(" ");
nsCString* value = new nsCString(tokens[1]);
nsCString* value = new nsCString(Substring(line, colon + 1));
value->Trim(" ");
mValues.Put(key, value); // Hashtable assumes ownership of value.
}

View File

@ -13,6 +13,7 @@
#include "mozilla/camera/PCamerasChild.h"
#include "mozilla/camera/PCamerasParent.h"
#include "mozilla/Mutex.h"
#include "base/singleton.h"
#include "nsCOMPtr.h"
// conflicts with #include of scoped_ptr.h
@ -79,24 +80,21 @@ public:
~CamerasSingleton();
static OffTheBooksMutex& Mutex() {
return GetInstance().mCamerasMutex;
return gTheInstance.get()->mCamerasMutex;
}
static CamerasChild*& Child() {
Mutex().AssertCurrentThreadOwns();
return GetInstance().mCameras;
return gTheInstance.get()->mCameras;
}
static nsCOMPtr<nsIThread>& Thread() {
Mutex().AssertCurrentThreadOwns();
return GetInstance().mCamerasChildThread;
return gTheInstance.get()->mCamerasChildThread;
}
private:
static CamerasSingleton& GetInstance() {
static CamerasSingleton instance;
return instance;
}
static Singleton<CamerasSingleton> gTheInstance;
// Reinitializing CamerasChild will change the pointers below.
// We don't want this to happen in the middle of preparing IPC.

View File

@ -92,7 +92,6 @@ HTTP load media-element-source-seek-1.html
load offline-buffer-source-ended-1.html
load oscillator-ended-1.html
load oscillator-ended-2.html
skip-if(winWidget) load video-replay-after-audio-end.html
# This needs to run at the end to avoid leaking busted state into other tests.
skip-if(B2G) load 691096-1.html # bug 852821

View File

@ -1,43 +0,0 @@
<html class="reftest-wait">
<head>
<title> Bug 1242774 : video crashed if pause and play again after audio track ends </title>
</head>
<body>
<script type="text/javascript">
function assert(value, msg) {
if (!value) {
dump("### Error : " + msg + "\n");
}
}
var AUDIO_END_TIME = 4.5;
var video = document.createElement('video');
video.src = "video-crash.webm";
video.play();
video.ontimeupdate = function () {
assert(AUDIO_END_TIME < video.duration,
"AUDIO_END_TIME should be smaller than the duration!");
if (video.currentTime > AUDIO_END_TIME) {
dump("### Pause video during silent part.\n");
video.ontimeupdate = null;
video.pause();
}
video.onpause = function () {
video.onpause = null;
setTimeout(function() {
dump("### Re-play after pausing during silent part.\n");
video.play();
video.onended = function () {
video.onended = null;
dump("### Video is ended.\n");
document.documentElement.removeAttribute("class");
}
}, 1000);
}
}
</script>
</body>
</html>

View File

@ -147,9 +147,9 @@ AudioNodeStream::SetStreamTimeParameter(uint32_t aIndex, AudioContext* aContext,
uint32_t mIndex;
};
GraphImpl()->AppendMessage(new Message(this, aIndex,
aContext->DestinationStream(),
aStreamTime));
GraphImpl()->AppendMessage(MakeUnique<Message>(this, aIndex,
aContext->DestinationStream(),
aStreamTime));
}
void
@ -178,7 +178,7 @@ AudioNodeStream::SetDoubleParameter(uint32_t aIndex, double aValue)
uint32_t mIndex;
};
GraphImpl()->AppendMessage(new Message(this, aIndex, aValue));
GraphImpl()->AppendMessage(MakeUnique<Message>(this, aIndex, aValue));
}
void
@ -199,7 +199,7 @@ AudioNodeStream::SetInt32Parameter(uint32_t aIndex, int32_t aValue)
uint32_t mIndex;
};
GraphImpl()->AppendMessage(new Message(this, aIndex, aValue));
GraphImpl()->AppendMessage(MakeUnique<Message>(this, aIndex, aValue));
}
void
@ -225,7 +225,7 @@ AudioNodeStream::SendTimelineEvent(uint32_t aIndex,
TrackRate mSampleRate;
uint32_t mIndex;
};
GraphImpl()->AppendMessage(new Message(this, aIndex, aEvent));
GraphImpl()->AppendMessage(MakeUnique<Message>(this, aIndex, aEvent));
}
void
@ -246,7 +246,7 @@ AudioNodeStream::SetThreeDPointParameter(uint32_t aIndex, const ThreeDPoint& aVa
uint32_t mIndex;
};
GraphImpl()->AppendMessage(new Message(this, aIndex, aValue));
GraphImpl()->AppendMessage(MakeUnique<Message>(this, aIndex, aValue));
}
void
@ -267,7 +267,7 @@ AudioNodeStream::SetBuffer(already_AddRefed<ThreadSharedFloatArrayBufferList>&&
RefPtr<ThreadSharedFloatArrayBufferList> mBuffer;
};
GraphImpl()->AppendMessage(new Message(this, aBuffer));
GraphImpl()->AppendMessage(MakeUnique<Message>(this, aBuffer));
}
void
@ -289,7 +289,7 @@ AudioNodeStream::SetRawArrayData(nsTArray<float>& aData)
nsTArray<float> mData;
};
GraphImpl()->AppendMessage(new Message(this, aData));
GraphImpl()->AppendMessage(MakeUnique<Message>(this, aData));
}
void
@ -320,9 +320,9 @@ AudioNodeStream::SetChannelMixingParameters(uint32_t aNumberOfChannels,
ChannelInterpretation mChannelInterpretation;
};
GraphImpl()->AppendMessage(new Message(this, aNumberOfChannels,
aChannelCountMode,
aChannelInterpretation));
GraphImpl()->AppendMessage(MakeUnique<Message>(this, aNumberOfChannels,
aChannelCountMode,
aChannelInterpretation));
}
void
@ -341,7 +341,7 @@ AudioNodeStream::SetPassThrough(bool aPassThrough)
bool mPassThrough;
};
GraphImpl()->AppendMessage(new Message(this, aPassThrough));
GraphImpl()->AppendMessage(MakeUnique<Message>(this, aPassThrough));
}
void
@ -399,7 +399,7 @@ void
AudioNodeStream::AdvanceAndResume(StreamTime aAdvance)
{
mMainThreadCurrentTime += aAdvance;
GraphImpl()->AppendMessage(new AdvanceAndResumeMessage(this, aAdvance));
GraphImpl()->AppendMessage(MakeUnique<AdvanceAndResumeMessage>(this, aAdvance));
}
void
@ -731,7 +731,7 @@ AudioNodeStream::ScheduleCheckForInactive()
return;
}
nsAutoPtr<CheckForInactiveMessage> message(new CheckForInactiveMessage(this));
auto message = MakeUnique<CheckForInactiveMessage>(this);
GraphImpl()->RunMessageAfterProcessing(Move(message));
}

View File

@ -22,10 +22,7 @@ SpeechStreamListener::~SpeechStreamListener()
nsCOMPtr<nsIThread> mainThread;
NS_GetMainThread(getter_AddRefs(mainThread));
SpeechRecognition* forgottenRecognition = nullptr;
mRecognition.swap(forgottenRecognition);
NS_ProxyRelease(mainThread,
static_cast<DOMEventTargetHelper*>(forgottenRecognition));
NS_ProxyRelease(mainThread, mRecognition.forget());
}
void

View File

@ -45,46 +45,10 @@ using namespace mozilla::dom::workers;
namespace mozilla {
namespace dom {
class DispatchEventRunnable final : public nsICancelableRunnable
class PostMessageRunnable final : public nsICancelableRunnable
{
friend class MessagePort;
public:
NS_DECL_ISUPPORTS
explicit DispatchEventRunnable(MessagePort* aPort)
: mPort(aPort)
{ }
NS_IMETHOD
Run() override
{
MOZ_ASSERT(mPort);
MOZ_ASSERT(mPort->mDispatchRunnable == this);
mPort->mDispatchRunnable = nullptr;
mPort->Dispatch();
return NS_OK;
}
NS_IMETHOD
Cancel() override
{
mPort = nullptr;
return NS_OK;
}
private:
~DispatchEventRunnable()
{}
RefPtr<MessagePort> mPort;
};
NS_IMPL_ISUPPORTS(DispatchEventRunnable, nsICancelableRunnable, nsIRunnable)
class PostMessageRunnable final : public nsICancelableRunnable
{
public:
NS_DECL_ISUPPORTS
@ -98,6 +62,29 @@ public:
NS_IMETHOD
Run() override
{
MOZ_ASSERT(mPort);
MOZ_ASSERT(mPort->mPostMessageRunnable == this);
nsresult rv = DispatchMessage();
mPort->mPostMessageRunnable = nullptr;
mPort->Dispatch();
return rv;
}
NS_IMETHOD
Cancel() override
{
mPort = nullptr;
mData = nullptr;
return NS_OK;
}
private:
nsresult
DispatchMessage() const
{
nsCOMPtr<nsIGlobalObject> globalObject;
@ -157,14 +144,6 @@ public:
return NS_OK;
}
NS_IMETHOD
Cancel() override
{
mPort = nullptr;
mData = nullptr;
return NS_OK;
}
private:
~PostMessageRunnable()
{}
@ -179,8 +158,8 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(MessagePort)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MessagePort,
DOMEventTargetHelper)
if (tmp->mDispatchRunnable) {
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDispatchRunnable->mPort);
if (tmp->mPostMessageRunnable) {
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPostMessageRunnable->mPort);
}
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMessages);
@ -190,8 +169,8 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(MessagePort,
DOMEventTargetHelper)
if (tmp->mDispatchRunnable) {
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDispatchRunnable->mPort);
if (tmp->mPostMessageRunnable) {
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPostMessageRunnable->mPort);
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mUnshippedEntangledPort);
@ -497,7 +476,7 @@ MessagePort::Start()
void
MessagePort::Dispatch()
{
if (!mMessageQueueEnabled || mMessages.IsEmpty() || mDispatchRunnable) {
if (!mMessageQueueEnabled || mMessages.IsEmpty() || mPostMessageRunnable) {
return;
}
@ -549,13 +528,9 @@ MessagePort::Dispatch()
RefPtr<SharedMessagePortMessage> data = mMessages.ElementAt(0);
mMessages.RemoveElementAt(0);
RefPtr<PostMessageRunnable> runnable = new PostMessageRunnable(this, data);
mPostMessageRunnable = new PostMessageRunnable(this, data);
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToCurrentThread(runnable)));
mDispatchRunnable = new DispatchEventRunnable(this);
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToCurrentThread(mDispatchRunnable)));
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToCurrentThread(mPostMessageRunnable)));
}
void

View File

@ -21,7 +21,6 @@ class nsPIDOMWindowInner;
namespace mozilla {
namespace dom {
class DispatchEventRunnable;
class MessagePortChild;
class MessagePortIdentifier;
class MessagePortMessage;
@ -36,7 +35,6 @@ class MessagePort final : public DOMEventTargetHelper
, public nsIIPCBackgroundChildCreateCallback
, public nsIObserver
{
friend class DispatchEventRunnable;
friend class PostMessageRunnable;
public:
@ -166,7 +164,7 @@ private:
nsAutoPtr<workers::WorkerFeature> mWorkerFeature;
RefPtr<DispatchEventRunnable> mDispatchRunnable;
RefPtr<PostMessageRunnable> mPostMessageRunnable;
RefPtr<MessagePortChild> mActor;

View File

@ -851,19 +851,26 @@ nsCSPContext::SendReports(nsISupports* aBlockedContentSource,
}
// try to create a new channel for every report-uri
nsLoadFlags loadFlags = nsIRequest::LOAD_NORMAL | nsIChannel::LOAD_CLASSIFY_URI;
if (doc) {
rv = NS_NewChannel(getter_AddRefs(reportChannel),
reportURI,
doc,
nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
nsIContentPolicy::TYPE_CSP_REPORT);
nsIContentPolicy::TYPE_CSP_REPORT,
nullptr, // aLoadGroup
nullptr, // aCallbacks
loadFlags);
}
else {
rv = NS_NewChannel(getter_AddRefs(reportChannel),
reportURI,
mLoadingPrincipal,
nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
nsIContentPolicy::TYPE_CSP_REPORT);
nsIContentPolicy::TYPE_CSP_REPORT,
nullptr, // aLoadGroup
nullptr, // aCallbacks
loadFlags);
}
if (NS_FAILED(rv)) {

View File

@ -15,8 +15,6 @@
namespace mozilla {
namespace dom {
NS_IMPL_ISUPPORTS0(SVGTests)
nsIAtom** SVGTests::sStringListNames[3] =
{
&nsGkAtoms::requiredFeatures,

View File

@ -28,7 +28,6 @@ class SVGTests : public nsISupports
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_DOMSVGTESTS_IID)
NS_DECL_ISUPPORTS
SVGTests();

View File

@ -449,8 +449,6 @@ var interfaceNamesInGlobalScope =
"DOMRectReadOnly",
// IMPORTANT: Do not change this list without review from a DOM peer!
"DOMRequest",
// IMPORTANT: Do not change this list without review from a DOM peer!
"DOMSettableTokenList",
// IMPORTANT: Do not change this list without review from a DOM peer!
"DOMStringList",
// IMPORTANT: Do not change this list without review from a DOM peer!

View File

@ -18,7 +18,7 @@ function parseQueryString(str)
}
function getPosition(action)
{
{
var response = {
status: "OK",
location: {
@ -27,7 +27,7 @@ function getPosition(action)
},
accuracy: (action == "worse-accuracy") ? 100 : 42,
};
return JSON.stringify(response);
}

View File

@ -5,7 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
[ChromeOnly,
Exposed=(Window,Worker)]
Exposed=(Window,Worker,WorkerDebugger)]
interface Console {
void log(any... data);
void info(any... data);

View File

@ -1,16 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* http://www.w3.org/TR/2012/WD-dom-20120105/
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
interface DOMSettableTokenList : DOMTokenList {
[SetterThrows]
attribute DOMString value;
};

View File

@ -21,5 +21,7 @@ interface DOMTokenList {
void remove(DOMString... tokens);
[Throws]
boolean toggle(DOMString token, optional boolean force);
[SetterThrows]
attribute DOMString value;
stringifier DOMString ();
};

View File

@ -30,7 +30,7 @@ interface Element : Node {
attribute DOMString id;
[Pure]
attribute DOMString className;
[Constant]
[Constant, PutForwards=value]
readonly attribute DOMTokenList classList;
[SameObject]

View File

@ -23,6 +23,7 @@ interface HTMLAnchorElement : HTMLElement {
attribute DOMString rel;
[SetterThrows, Pref="network.http.enablePerElementReferrer"]
attribute DOMString referrerPolicy;
[PutForwards=value]
readonly attribute DOMTokenList relList;
[SetterThrows]
attribute DOMString hreflang;

View File

@ -30,6 +30,7 @@ interface HTMLAreaElement : HTMLElement {
attribute DOMString rel;
[SetterThrows, Pref="network.http.enablePerElementReferrer"]
attribute DOMString referrerPolicy;
[PutForwards=value]
readonly attribute DOMTokenList relList;
};

View File

@ -28,11 +28,11 @@ interface HTMLElement : Element {
// microdata
[SetterThrows, Pure]
attribute boolean itemScope;
[PutForwards=value,Constant] readonly attribute DOMSettableTokenList itemType;
[PutForwards=value,Constant] readonly attribute DOMTokenList itemType;
[SetterThrows, Pure]
attribute DOMString itemId;
[PutForwards=value,Constant] readonly attribute DOMSettableTokenList itemRef;
[PutForwards=value,Constant] readonly attribute DOMSettableTokenList itemProp;
[PutForwards=value,Constant] readonly attribute DOMTokenList itemRef;
[PutForwards=value,Constant] readonly attribute DOMTokenList itemProp;
[Constant]
readonly attribute HTMLPropertiesCollection properties;
[Throws]
@ -54,7 +54,7 @@ interface HTMLElement : Element {
readonly attribute DOMString accessKeyLabel;
[SetterThrows, Pure]
attribute boolean draggable;
//[PutForwards=value] readonly attribute DOMSettableTokenList dropzone;
//[PutForwards=value] readonly attribute DOMTokenList dropzone;
[SetterThrows, Pure]
attribute DOMString contentEditable;
[Pure]

View File

@ -18,7 +18,7 @@ interface HTMLIFrameElement : HTMLElement {
attribute DOMString srcdoc;
[SetterThrows, Pure]
attribute DOMString name;
[PutForwards=value] readonly attribute DOMSettableTokenList sandbox;
[PutForwards=value] readonly attribute DOMTokenList sandbox;
// attribute boolean seamless;
[SetterThrows, Pure]
attribute boolean allowFullscreen;

View File

@ -21,6 +21,7 @@ interface HTMLLinkElement : HTMLElement {
attribute DOMString? crossOrigin;
[SetterThrows, Pure]
attribute DOMString rel;
[PutForwards=value]
readonly attribute DOMTokenList relList;
[SetterThrows, Pure]
attribute DOMString media;
@ -28,7 +29,7 @@ interface HTMLLinkElement : HTMLElement {
attribute DOMString hreflang;
[SetterThrows, Pure]
attribute DOMString type;
[PutForwards=value] readonly attribute DOMSettableTokenList sizes;
[PutForwards=value] readonly attribute DOMTokenList sizes;
};
HTMLLinkElement implements LinkStyle;

View File

@ -14,7 +14,7 @@
// http://www.whatwg.org/specs/web-apps/current-work/#the-output-element
interface HTMLOutputElement : HTMLElement {
[PutForwards=value, Constant]
readonly attribute DOMSettableTokenList htmlFor;
readonly attribute DOMTokenList htmlFor;
readonly attribute HTMLFormElement? form;
[SetterThrows, Pure]
attribute DOMString name;

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