Merge mozilla-inbound to mozilla-central. a=merge

This commit is contained in:
Dorel Luca 2018-05-16 00:54:22 +03:00
Родитель 8f1ede4723 432ab75dea
Коммит 0d2ff9e60d
144 изменённых файлов: 1331 добавлений и 1401 удалений

Просмотреть файл

@ -33,8 +33,8 @@ DIST_GARBAGE = config.cache config.log config.status* config-defs.h \
ifndef MOZ_PROFILE_USE
# Automation builds should always have a new buildid, but for the sake of not
# re-linking libxul on every incremental build we do not enforce this for
# developer builds.
ifneq (,$(MOZ_AUTOMATION)$(MOZ_BUILD_DATE))
# developer builds. Tests always need a new buildid as well.
ifneq (,$(MOZ_AUTOMATION)$(MOZ_BUILD_DATE)$(TEST_MOZBUILD))
buildid.h source-repo.h: FORCE
endif
endif
@ -109,7 +109,7 @@ default:: $(BUILD_BACKEND_FILES)
endif
install_manifests := \
$(addprefix dist/,branding idl include public private xpi-stage) \
$(addprefix dist/,branding include public private xpi-stage) \
_tests \
$(NULL)
# Skip the dist/bin install manifest when using the hybrid
@ -140,12 +140,10 @@ install-manifests: $(addprefix install-,$(install_manifests))
# If we're using the hybrid FasterMake/RecursiveMake backend, we want
# to recurse in the faster/ directory in parallel of install manifests.
# But dist/idl needs to happen before (cf. dependencies in
# config/faster/rules.mk)
ifneq (,$(filter FasterMake+RecursiveMake,$(BUILD_BACKENDS)))
install-manifests: faster
.PHONY: faster
faster: install-dist/idl
faster:
$(MAKE) -C faster FASTER_RECURSIVE_MAKE=1
endif

Просмотреть файл

@ -382,7 +382,7 @@ ItemIterator::Next()
// XULTreeItemIterator
////////////////////////////////////////////////////////////////////////////////
XULTreeItemIterator::XULTreeItemIterator(XULTreeAccessible* aXULTree,
XULTreeItemIterator::XULTreeItemIterator(const XULTreeAccessible* aXULTree,
nsITreeView* aTreeView,
int32_t aRowIdx) :
mXULTree(aXULTree), mTreeView(aTreeView), mRowCount(-1),

Просмотреть файл

@ -301,7 +301,7 @@ private:
class XULTreeItemIterator : public AccIterable
{
public:
XULTreeItemIterator(XULTreeAccessible* aXULTree, nsITreeView* aTreeView,
XULTreeItemIterator(const XULTreeAccessible* aXULTree, nsITreeView* aTreeView,
int32_t aRowIdx);
virtual ~XULTreeItemIterator() { }
@ -312,7 +312,7 @@ private:
XULTreeItemIterator(const XULTreeItemIterator&) = delete;
XULTreeItemIterator& operator = (const XULTreeItemIterator&) = delete;
XULTreeAccessible* mXULTree;
const XULTreeAccessible* mXULTree;
nsITreeView* mTreeView;
int32_t mRowCount;
int32_t mContainerLevel;

Просмотреть файл

@ -327,7 +327,8 @@ MARKUPMAP(summary,
MARKUPMAP(
table,
[](Element* aElement, Accessible* aContext) -> Accessible* {
if (aElement->GetPrimaryFrame()->AccessibleType() != eHTMLTableType) {
if (aElement->GetPrimaryFrame() &&
aElement->GetPrimaryFrame()->AccessibleType() != eHTMLTableType) {
return new ARIAGridAccessibleWrap(aElement, aContext->Document());
}
return nullptr;
@ -390,12 +391,13 @@ MARKUPMAP(
if (table) {
nsIContent* parentContent = aElement->GetParent();
nsIFrame* parentFrame = parentContent->GetPrimaryFrame();
if (!parentFrame->IsTableWrapperFrame()) {
if (parentFrame && !parentFrame->IsTableWrapperFrame()) {
parentContent = parentContent->GetParent();
parentFrame = parentContent->GetPrimaryFrame();
if (table->GetContent() == parentContent &&
(!parentFrame->IsTableWrapperFrame() ||
aElement->GetPrimaryFrame()->AccessibleType() != eHTMLTableRowType)) {
((parentFrame && !parentFrame->IsTableWrapperFrame()) ||
(aElement->GetPrimaryFrame() &&
aElement->GetPrimaryFrame()->AccessibleType() != eHTMLTableRowType))) {
return new ARIARowAccessible(aElement, aContext->Document());
}
}

Просмотреть файл

@ -1054,6 +1054,20 @@ nsAccessibilityService::CreateAccessible(nsINode* aNode,
// Check frame and its visibility. Note, hidden frame allows visible
// elements in subtree.
if (!frame || !frame->StyleVisibility()->IsVisible()) {
// display:contents element doesn't have a frame, but retains the semantics.
// All its children are unaffected.
if (content->IsElement() && content->AsElement()->IsDisplayContents()) {
const HTMLMarkupMapInfo* markupMap =
mHTMLMarkupMap.Get(content->NodeInfo()->NameAtom());
if (markupMap && markupMap->new_func) {
RefPtr<Accessible> newAcc =
markupMap->new_func(content->AsElement(), aContext);
document->BindToDocument(newAcc, aria::GetRoleMap(content->AsElement()));
return newAcc;
}
return nullptr;
}
if (aIsSubtreeHidden && !frame)
*aIsSubtreeHidden = true;

Просмотреть файл

@ -324,8 +324,14 @@ uint64_t
Accessible::VisibilityState() const
{
nsIFrame* frame = GetFrame();
if (!frame)
if (!frame) {
// Element having display:contents is considered visible semantically,
// despite it doesn't have a visually visible box.
if (mContent->IsElement() && mContent->AsElement()->IsDisplayContents()) {
return states::OFFSCREEN;
}
return states::INVISIBLE;
}
// Walk the parent frame chain to see if there's invisible parent or the frame
// is in background tab.
@ -1946,8 +1952,12 @@ Accessible::AppendTextTo(nsAString& aText, uint32_t aStartOffset,
return;
nsIFrame *frame = GetFrame();
if (!frame)
if (!frame) {
if (mContent->IsElement() && mContent->AsElement()->IsDisplayContents()) {
aText += kEmbeddedObjectChar;
}
return;
}
NS_ASSERTION(mParent,
"Called on accessible unbound from tree. Result can be wrong.");
@ -2564,7 +2574,7 @@ Accessible::AreItemsOperable() const
}
Accessible*
Accessible::CurrentItem()
Accessible::CurrentItem() const
{
// Check for aria-activedescendant, which changes which element has focus.
// For activedescendant, the ARIA spec does not require that the user agent
@ -2587,7 +2597,7 @@ Accessible::CurrentItem()
}
void
Accessible::SetCurrentItem(Accessible* aItem)
Accessible::SetCurrentItem(const Accessible* aItem)
{
nsAtom* id = aItem->GetContent()->GetID();
if (id) {

Просмотреть файл

@ -435,7 +435,7 @@ public:
/**
* Return true if accessible has children;
*/
bool HasChildren() { return !!GetChildAt(0); }
bool HasChildren() const { return !!GetChildAt(0); }
/**
* Return first/last/next/previous sibling of the accessible.
@ -850,12 +850,12 @@ public:
* Return the current item of the widget, i.e. an item that has or will have
* keyboard focus when widget gets active.
*/
virtual Accessible* CurrentItem();
virtual Accessible* CurrentItem() const;
/**
* Set the current item of the widget.
*/
virtual void SetCurrentItem(Accessible* aItem);
virtual void SetCurrentItem(const Accessible* aItem);
/**
* Return container widget this accessible belongs to.

Просмотреть файл

@ -102,7 +102,7 @@ RootAccessible::NativeRole() const
// RootAccessible protected member
#ifdef MOZ_XUL
uint32_t
RootAccessible::GetChromeFlags()
RootAccessible::GetChromeFlags() const
{
// Return the flag set for the top level window as defined
// by nsIWebBrowserChrome::CHROME_WINDOW_[FLAGNAME]

Просмотреть файл

@ -76,7 +76,7 @@ protected:
void HandleTreeInvalidatedEvent(dom::Event* aEvent,
XULTreeAccessible* aAccessible);
uint32_t GetChromeFlags();
uint32_t GetChromeFlags() const;
#endif
};

Просмотреть файл

@ -93,7 +93,7 @@ HTMLSelectListAccessible::AreItemsOperable() const
}
Accessible*
HTMLSelectListAccessible::CurrentItem()
HTMLSelectListAccessible::CurrentItem() const
{
nsIListControlFrame* listControlFrame = do_QueryFrame(GetFrame());
if (listControlFrame) {
@ -108,7 +108,7 @@ HTMLSelectListAccessible::CurrentItem()
}
void
HTMLSelectListAccessible::SetCurrentItem(Accessible* aItem)
HTMLSelectListAccessible::SetCurrentItem(const Accessible* aItem)
{
if (!aItem->GetContent()->IsElement())
return;
@ -500,13 +500,13 @@ HTMLComboboxAccessible::AreItemsOperable() const
}
Accessible*
HTMLComboboxAccessible::CurrentItem()
HTMLComboboxAccessible::CurrentItem() const
{
return AreItemsOperable() ? mListAccessible->CurrentItem() : nullptr;
}
void
HTMLComboboxAccessible::SetCurrentItem(Accessible* aItem)
HTMLComboboxAccessible::SetCurrentItem(const Accessible* aItem)
{
if (AreItemsOperable())
mListAccessible->SetCurrentItem(aItem);

Просмотреть файл

@ -49,8 +49,8 @@ public:
virtual bool IsWidget() const override;
virtual bool IsActiveWidget() const override;
virtual bool AreItemsOperable() const override;
virtual Accessible* CurrentItem() override;
virtual void SetCurrentItem(Accessible* aItem) override;
virtual Accessible* CurrentItem() const override;
virtual void SetCurrentItem(const Accessible* aItem) override;
};
/*
@ -180,8 +180,8 @@ public:
virtual bool IsWidget() const override;
virtual bool IsActiveWidget() const override;
virtual bool AreItemsOperable() const override;
virtual Accessible* CurrentItem() override;
virtual void SetCurrentItem(Accessible* aItem) override;
virtual Accessible* CurrentItem() const override;
virtual void SetCurrentItem(const Accessible* aItem) override;
protected:
/**

Просмотреть файл

@ -23,6 +23,7 @@
testStates("div_off", STATE_OFFSCREEN, 0, STATE_INVISIBLE);
testStates("div_transformed", STATE_OFFSCREEN, 0, STATE_INVISIBLE);
testStates("div_abschild", 0, 0, STATE_INVISIBLE | STATE_OFFSCREEN);
testStates("ul", STATE_OFFSCREEN, 0, STATE_INVISIBLE);
SimpleTest.finish();
}
@ -66,6 +67,10 @@
<p style="position: absolute; left: 120px; top:120px;">absolute</p>
</div>
<ul id="ul" style="display: contents;">
<li>Supermarket 1</li>
<li>Supermarket 2</li>
</ul>
</div>
</body>
</html>

Просмотреть файл

@ -39,7 +39,7 @@
// __h__e__l__l__o__ __!__ __s__e__e__ __!__
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13
var IDs = [ "hypertext", "hypertext2" ];
var IDs = [ "hypertext", "hypertext2", "ht_displaycontents" ];
// //////////////////////////////////////////////////////////////////////
// characterCount
@ -123,6 +123,10 @@
<div id="hypertext">hello <a>friend</a> see <img src="about:blank"></div>
<div id="hypertext2">hello <a>friend</a> see <input></div>
<div id="ht_displaycontents">hello <a>friend</a> see <ul id="ul" style="display: contents;">
<li>Supermarket 1</li>
<li>Supermarket 2</li>
</ul></div>
<ol id="list">
<li id="listitem">foo</li>
<li id="listitemnone">bar</li>

Просмотреть файл

@ -25,6 +25,7 @@ skip-if = true # Bug 561508
[test_combobox.xul]
[test_cssflexbox.html]
[test_cssoverflow.html]
[test_display_contents.html]
[test_dochierarchy.html]
[test_dockids.html]
[test_filectrl.html]

Просмотреть файл

@ -0,0 +1,50 @@
<!DOCTYPE html>
<html>
<head>
<title>CSS display:contents tests</title>
<link rel="stylesheet" type="text/css"
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="../common.js"></script>
<script type="application/javascript"
src="../role.js"></script>
<script type="application/javascript">
function doTest() {
let tree =
{ LIST: [
{ LISTITEM: [
{ STATICTEXT: [] },
{ TEXT_LEAF: [] }
]},
{ LISTITEM: [
{ STATICTEXT: [] },
{ TEXT_LEAF: [] }
]},
] };
testAccessibleTree("ul", tree);
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
</script>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<ul id="ul" style="display: contents;">
<li>Supermarket 1</li>
<li>Supermarket 2</li>
</ul>
</body>
</html>

Просмотреть файл

@ -573,7 +573,7 @@ XULMenubarAccessible::AreItemsOperable() const
}
Accessible*
XULMenubarAccessible::CurrentItem()
XULMenubarAccessible::CurrentItem() const
{
nsMenuBarFrame* menuBarFrame = do_QueryFrame(GetFrame());
if (menuBarFrame) {
@ -587,7 +587,7 @@ XULMenubarAccessible::CurrentItem()
}
void
XULMenubarAccessible::SetCurrentItem(Accessible* aItem)
XULMenubarAccessible::SetCurrentItem(const Accessible* aItem)
{
NS_ERROR("XULMenubarAccessible::SetCurrentItem not implemented");
}

Просмотреть файл

@ -108,8 +108,8 @@ public:
// Widget
virtual bool IsActiveWidget() const override;
virtual bool AreItemsOperable() const override;
virtual Accessible* CurrentItem() override;
virtual void SetCurrentItem(Accessible* aItem) override;
virtual Accessible* CurrentItem() const override;
virtual void SetCurrentItem(const Accessible* aItem) override;
protected:
// Accessible

Просмотреть файл

@ -211,7 +211,7 @@ XULSelectControlAccessible::SelectAll()
// XULSelectControlAccessible: Widgets
Accessible*
XULSelectControlAccessible::CurrentItem()
XULSelectControlAccessible::CurrentItem() const
{
if (!mSelectControl)
return nullptr;
@ -238,7 +238,7 @@ XULSelectControlAccessible::CurrentItem()
}
void
XULSelectControlAccessible::SetCurrentItem(Accessible* aItem)
XULSelectControlAccessible::SetCurrentItem(const Accessible* aItem)
{
if (!mSelectControl)
return;

Просмотреть файл

@ -36,8 +36,8 @@ public:
virtual bool UnselectAll() override;
// Widgets
virtual Accessible* CurrentItem() override;
virtual void SetCurrentItem(Accessible* aItem) override;
virtual Accessible* CurrentItem() const override;
virtual void SetCurrentItem(const Accessible* aItem) override;
protected:
// nsIDOMXULMultiSelectControlElement inherits from this, so we'll always have

Просмотреть файл

@ -222,7 +222,7 @@ XULTreeAccessible::ChildAtPoint(int32_t aX, int32_t aY,
// XULTreeAccessible: SelectAccessible
Accessible*
XULTreeAccessible::CurrentItem()
XULTreeAccessible::CurrentItem() const
{
if (!mTreeView)
return nullptr;
@ -240,7 +240,7 @@ XULTreeAccessible::CurrentItem()
}
void
XULTreeAccessible::SetCurrentItem(Accessible* aItem)
XULTreeAccessible::SetCurrentItem(const Accessible* aItem)
{
NS_ERROR("XULTreeAccessible::SetCurrentItem not implemented");
}

Просмотреть файл

@ -64,8 +64,8 @@ public:
virtual bool IsWidget() const override;
virtual bool IsActiveWidget() const override;
virtual bool AreItemsOperable() const override;
virtual Accessible* CurrentItem() override;
virtual void SetCurrentItem(Accessible* aItem) override;
virtual Accessible* CurrentItem() const override;
virtual void SetCurrentItem(const Accessible* aItem) override;
virtual Accessible* ContainerWidget() const override;

Просмотреть файл

@ -97,14 +97,6 @@ $(addprefix install-,$(INSTALL_MANIFESTS)): install-%: $(addprefix $(TOPOBJDIR)/
# Below is a set of additional dependencies and variables used to build things
# that are not supported by data in moz.build.
# The xpidl target in config/makefiles/xpidl requires the install manifest for
# dist/idl to have been processed. When using the hybrid
# FasterMake/RecursiveMake backend, this dependency is handled in the top-level
# Makefile.
ifndef FASTER_RECURSIVE_MAKE
$(TOPOBJDIR)/config/makefiles/xpidl/xpidl: $(TOPOBJDIR)/install-dist_idl
endif
$(TOPOBJDIR)/build/application.ini: $(TOPOBJDIR)/buildid.h $(TOPOBJDIR)/source-repo.h
# The manifest of allowed system add-ons should be re-built when using

Просмотреть файл

@ -41,7 +41,8 @@ code_gen_deps := $(topsrcdir)/xpcom/reflect/xptinfo/perfecthash.py
$(PYTHON_PATH) $(PLY_INCLUDE) -I$(topsrcdir)/xpcom/idl-parser -I$(DEPTH)/xpcom/idl-parser/xpidl \
$(process_py) --cache-dir $(DEPTH)/xpcom/idl-parser/xpidl --depsdir $(idl_deps_dir) \
--bindings-conf $(topsrcdir)/dom/bindings/Bindings.conf \
$(dist_idl_dir) $(dist_include_dir) $(dist_xpcrs_dir) $(@D) \
$(foreach dir,$(all_idl_dirs),-I $(dir)) \
$(dist_include_dir) $(dist_xpcrs_dir) $(@D) \
$(basename $(notdir $@)) $($(basename $(notdir $@))_deps)
# When some IDL is added or removed, if the actual IDL file was already, or
# still is, in the tree, simple dependencies can't detect that the XPT needs
@ -75,7 +76,6 @@ $(generated_file): $(xpt_files) $(code_gen_py) $(code_gen_deps)
define xpt_deps
$(1): $(call mkdir_deps,$(dir $(1)))
$(1): $(addsuffix .idl,$(addprefix $(dist_idl_dir)/,$($(basename $(notdir $(1)))_deps)))
ifneq ($($(basename $(notdir $(1)))_deps),$($(basename $(notdir $(1)))_deps_built))
$(1): FORCE
endif

Просмотреть файл

@ -546,7 +546,6 @@ previewers.Object = [
obj.class != "CSSRuleList" &&
obj.class != "MediaList" &&
obj.class != "StyleSheetList" &&
obj.class != "CSSValueList" &&
obj.class != "NamedNodeMap" &&
obj.class != "FileList" &&
obj.class != "NodeList") {

Просмотреть файл

@ -108,6 +108,7 @@ method console.group
method console.groupCollapsed
method console.groupEnd
method console.time
method console.timeLog
method console.timeEnd
method console.exception
method console.timeStamp

Просмотреть файл

@ -113,7 +113,7 @@ WindowNamedPropertiesHandler::getOwnPropDescriptor(JSContext* aCx,
// global scope is still allowed, since |var| only looks up |own|
// properties. But unqualified shadowing will fail, per-spec.
JS::Rooted<JS::Value> v(aCx);
if (!WrapObject(aCx, childWin, &v)) {
if (!ToJSValue(aCx, nsGlobalWindowOuter::Cast(childWin), &v)) {
return false;
}
FillPropertyDescriptor(aDesc, aProxy, 0, v);
@ -128,27 +128,25 @@ WindowNamedPropertiesHandler::getOwnPropDescriptor(JSContext* aCx,
}
nsHTMLDocument* document = static_cast<nsHTMLDocument*>(htmlDoc.get());
JS::Rooted<JS::Value> v(aCx);
Element* element = document->GetElementById(str);
if (element) {
JS::Rooted<JS::Value> v(aCx);
if (!WrapObject(aCx, element, &v)) {
if (!ToJSValue(aCx, element, &v)) {
return false;
}
FillPropertyDescriptor(aDesc, aProxy, 0, v);
return true;
}
nsWrapperCache* cache;
nsISupports* result = document->ResolveName(str, &cache);
if (!result) {
return true;
}
JS::Rooted<JS::Value> v(aCx);
if (!WrapObject(aCx, result, cache, nullptr, &v)) {
ErrorResult rv;
bool found = document->ResolveName(aCx, str, &v, rv);
if (rv.MaybeSetPendingException(aCx)) {
return false;
}
FillPropertyDescriptor(aDesc, aProxy, 0, v);
if (found) {
FillPropertyDescriptor(aDesc, aProxy, 0, v);
}
return true;
}

Просмотреть файл

@ -80,7 +80,6 @@ EXPORTS += [
'nsIDocument.h',
'nsIDocumentInlines.h',
'nsIDocumentObserver.h',
'nsIDOMClassInfo.h',
'nsIGlobalObject.h',
'nsImageLoadingContent.h',
'nsIMutationObserver.h',

Просмотреть файл

@ -2848,9 +2848,7 @@ const InterfaceShimEntry kInterfaceShimMap[] =
{ { "nsIXMLHttpRequest", "XMLHttpRequest" },
{ "nsIDOMDOMException", "DOMException" },
{ "nsIDOMNode", "Node" },
{ "nsIDOMCSSPrimitiveValue", "CSSPrimitiveValue" },
{ "nsIDOMCSSRule", "CSSRule" },
{ "nsIDOMCSSValue", "CSSValue" },
{ "nsIDOMEvent", "Event" },
{ "nsIDOMNSEvent", "Event" },
{ "nsIDOMKeyEvent", "KeyEvent" },

Просмотреть файл

@ -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/. */
#ifndef nsIDOMClassInfo_h___
#define nsIDOMClassInfo_h___
#include "nsIXPCScriptable.h"
#define DOM_BASE_SCRIPTABLE_FLAGS \
(XPC_SCRIPTABLE_USE_JSSTUB_FOR_ADDPROPERTY | \
XPC_SCRIPTABLE_USE_JSSTUB_FOR_DELPROPERTY | \
XPC_SCRIPTABLE_ALLOW_PROP_MODS_TO_PROTOTYPE | \
XPC_SCRIPTABLE_DONT_ASK_INSTANCE_FOR_SCRIPTABLE | \
XPC_SCRIPTABLE_DONT_REFLECT_INTERFACE_NAMES)
#define DEFAULT_SCRIPTABLE_FLAGS \
(DOM_BASE_SCRIPTABLE_FLAGS | \
XPC_SCRIPTABLE_WANT_RESOLVE | \
XPC_SCRIPTABLE_WANT_PRECREATE)
#define DOM_DEFAULT_SCRIPTABLE_FLAGS \
(DEFAULT_SCRIPTABLE_FLAGS | \
XPC_SCRIPTABLE_DONT_ENUM_QUERY_INTERFACE | \
XPC_SCRIPTABLE_CLASSINFO_INTERFACES_ONLY)
#endif /* nsIDOMClassInfo_h___ */

Просмотреть файл

@ -2140,12 +2140,6 @@ ToSupports(nsINode* aPointer)
return aPointer;
}
inline nsISupports*
ToCanonicalSupports(nsINode* aPointer)
{
return aPointer;
}
// Some checks are faster to do on nsIContent or Element than on
// nsINode, so spit out FromNode versions taking those types too.
#define NS_IMPL_FROMNODE_GENERIC(_class, _check, _const) \

Просмотреть файл

@ -586,12 +586,6 @@ protected:
bool mCalledByJS : 1;
};
inline nsISupports*
ToCanonicalSupports(nsRange* aRange)
{
return static_cast<nsIDOMRange*>(aRange);
}
inline nsISupports*
ToSupports(nsRange* aRange)
{

Просмотреть файл

@ -13,7 +13,6 @@
#include "mozilla/dom/BatteryManagerBinding.h"
#include "mozilla/Preferences.h"
#include "nsContentUtils.h"
#include "nsIDOMClassInfo.h"
#include "nsIDocument.h"
/**

Просмотреть файл

@ -35,7 +35,7 @@
#include "nsIXPConnect.h"
#include "nsJSUtils.h"
#include "nsISupportsImpl.h"
#include "qsObjectHelper.h"
#include "xpcObjectHelper.h"
#include "xpcpublic.h"
#include "nsIVariant.h"
#include "mozilla/dom/FakeString.h"
@ -1324,7 +1324,7 @@ HandleNewBindingWrappingFailure(JSContext* cx, JS::Handle<JSObject*> scope,
return false;
}
qsObjectHelper helper(value, GetWrapperCache(value));
xpcObjectHelper helper(value, GetWrapperCache(value));
return NativeInterface2JSObjectAndThrowIfFailed(cx, scope, rval,
helper, nullptr, true);
}
@ -1558,7 +1558,7 @@ WrapObject(JSContext* cx, T* p, nsWrapperCache* cache, const nsIID* iid,
{
if (xpc_FastGetCachedWrapper(cx, cache, rval))
return true;
qsObjectHelper helper(p, cache);
xpcObjectHelper helper(ToSupports(p), cache);
JS::Rooted<JSObject*> scope(cx, JS::CurrentGlobalOrNull(cx));
return XPCOMObjectToJsval(cx, scope, helper, iid, true, rval);
}
@ -1658,7 +1658,7 @@ template<typename T>
static inline JSObject*
WrapNativeISupports(JSContext* cx, T* p, nsWrapperCache* cache)
{
qsObjectHelper helper(ToSupports(p), cache);
xpcObjectHelper helper(ToSupports(p), cache);
JS::Rooted<JSObject*> scope(cx, JS::CurrentGlobalOrNull(cx));
JS::Rooted<JS::Value> v(cx);
return XPCOMObjectToJsval(cx, scope, helper, nullptr, false, &v) ?

Просмотреть файл

@ -192,10 +192,6 @@ DOMInterfaces = {
'wrapperCache': False
},
'CSSPrimitiveValue': {
'nativeType': 'nsROCSSPrimitiveValue',
},
'CSSRule': {
'concrete': False,
'nativeType': 'mozilla::css::Rule'
@ -214,14 +210,6 @@ DOMInterfaces = {
'binaryNames': { 'ownerRule': 'DOMOwnerRule' },
},
'CSSValue': {
'concrete': False
},
'CSSValueList': {
'nativeType': 'nsDOMCSSValueList'
},
'DedicatedWorkerGlobalScope': {
'headerFile': 'mozilla/dom/WorkerScope.h',
},
@ -718,10 +706,6 @@ DOMInterfaces = {
}
},
'Rect': {
'nativeType': 'nsDOMCSSRect',
},
'Request': {
'binaryNames': {
'headers': 'headers_',
@ -736,10 +720,6 @@ DOMInterfaces = {
'clone', 'cloneUnfiltered' ],
},
'RGBColor': {
'nativeType': 'nsDOMCSSRGBColor',
},
'RTCDataChannel': {
'nativeType': 'nsDOMDataChannel',
},

Просмотреть файл

@ -187,7 +187,7 @@ ToJSValue(JSContext* aCx,
// Make sure we're called in a compartment
MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
qsObjectHelper helper(ToSupports(&aArgument), nullptr);
xpcObjectHelper helper(ToSupports(&aArgument));
JS::Rooted<JSObject*> scope(aCx, JS::CurrentGlobalOrNull(aCx));
return XPCOMObjectToJsval(aCx, scope, helper, nullptr, true, aValue);
}

Просмотреть файл

@ -49,6 +49,7 @@ ClientHandle::StartOp(const ClientOpConstructorArgs& aArgs,
MaybeExecute([aArgs, kungFuGrip, aRejectCallback,
resolve = Move(aResolveCallback)] (ClientHandleChild* aActor) {
MOZ_RELEASE_ASSERT(aActor);
ClientHandleOpChild* actor =
new ClientHandleOpChild(kungFuGrip, aArgs, Move(resolve),
Move(aRejectCallback));
@ -57,6 +58,7 @@ ClientHandle::StartOp(const ClientOpConstructorArgs& aArgs,
return;
}
}, [aRejectCallback] {
MOZ_RELEASE_ASSERT(aRejectCallback);
aRejectCallback(NS_ERROR_DOM_INVALID_STATE_ERR);
});
}

Просмотреть файл

@ -39,9 +39,9 @@ ClientHandleOpChild::ClientHandleOpChild(ClientHandle* aClientHandle,
, mResolveCallback(Move(aResolveCallback))
, mRejectCallback(Move(aRejectCallback))
{
MOZ_DIAGNOSTIC_ASSERT(mClientHandle);
MOZ_DIAGNOSTIC_ASSERT(mResolveCallback);
MOZ_DIAGNOSTIC_ASSERT(mRejectCallback);
MOZ_RELEASE_ASSERT(mClientHandle);
MOZ_RELEASE_ASSERT(mResolveCallback);
MOZ_RELEASE_ASSERT(mRejectCallback);
}
} // namespace dom

Просмотреть файл

@ -27,8 +27,13 @@ using mozilla::ipc::PrincipalInfo;
namespace {
uint32_t kBadThreadLocalIndex = -1;
const uint32_t kBadThreadLocalIndex = -1;
const uint32_t kThreadLocalMagic1 = 0x8d57eea6;
const uint32_t kThreadLocalMagic2 = 0x59f375c9;
uint32_t sClientManagerThreadLocalMagic1 = kThreadLocalMagic1;
uint32_t sClientManagerThreadLocalIndex = kBadThreadLocalIndex;
uint32_t sClientManagerThreadLocalMagic2 = kThreadLocalMagic2;
uint32_t sClientManagerThreadLocalIndexDuplicate = kBadThreadLocalIndex;
} // anonymous namespace
@ -79,7 +84,11 @@ ClientManager::~ClientManager()
Shutdown();
MOZ_DIAGNOSTIC_ASSERT(this == PR_GetThreadPrivate(sClientManagerThreadLocalIndex));
MOZ_RELEASE_ASSERT(sClientManagerThreadLocalMagic1 == kThreadLocalMagic1);
MOZ_RELEASE_ASSERT(sClientManagerThreadLocalMagic2 == kThreadLocalMagic2);
MOZ_RELEASE_ASSERT(sClientManagerThreadLocalIndex != kBadThreadLocalIndex);
MOZ_RELEASE_ASSERT(sClientManagerThreadLocalIndex == sClientManagerThreadLocalIndexDuplicate);
MOZ_RELEASE_ASSERT(this == PR_GetThreadPrivate(sClientManagerThreadLocalIndex));
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
PRStatus status =
@ -185,7 +194,10 @@ ClientManager::StartOp(const ClientOpConstructorArgs& aArgs,
already_AddRefed<ClientManager>
ClientManager::GetOrCreateForCurrentThread()
{
MOZ_DIAGNOSTIC_ASSERT(sClientManagerThreadLocalIndex != kBadThreadLocalIndex);
MOZ_RELEASE_ASSERT(sClientManagerThreadLocalMagic1 == kThreadLocalMagic1);
MOZ_RELEASE_ASSERT(sClientManagerThreadLocalMagic2 == kThreadLocalMagic2);
MOZ_RELEASE_ASSERT(sClientManagerThreadLocalIndex != kBadThreadLocalIndex);
MOZ_RELEASE_ASSERT(sClientManagerThreadLocalIndex == sClientManagerThreadLocalIndexDuplicate);
RefPtr<ClientManager> cm =
static_cast<ClientManager*>(PR_GetThreadPrivate(sClientManagerThreadLocalIndex));
@ -199,7 +211,7 @@ ClientManager::GetOrCreateForCurrentThread()
MOZ_DIAGNOSTIC_ASSERT(status == PR_SUCCESS);
}
MOZ_ASSERT(cm);
MOZ_RELEASE_ASSERT(cm);
return cm.forget();
}
@ -216,12 +228,21 @@ void
ClientManager::Startup()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_RELEASE_ASSERT(sClientManagerThreadLocalMagic1 == kThreadLocalMagic1);
MOZ_RELEASE_ASSERT(sClientManagerThreadLocalMagic2 == kThreadLocalMagic2);
MOZ_RELEASE_ASSERT(sClientManagerThreadLocalIndex == kBadThreadLocalIndex);
MOZ_RELEASE_ASSERT(sClientManagerThreadLocalIndex == sClientManagerThreadLocalIndexDuplicate);
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
PRStatus status =
#endif
PR_NewThreadPrivateIndex(&sClientManagerThreadLocalIndex, nullptr);
MOZ_DIAGNOSTIC_ASSERT(status == PR_SUCCESS);
MOZ_RELEASE_ASSERT(sClientManagerThreadLocalIndex != kBadThreadLocalIndex);
sClientManagerThreadLocalIndexDuplicate = sClientManagerThreadLocalIndex;
ClientPrefsInit();
}

Просмотреть файл

@ -17,25 +17,43 @@ namespace dom {
template <typename ActorType>
class ClientThing
{
static const uint32_t kMagic1 = 0xC9FE2C9C;
static const uint32_t kMagic2 = 0x832072D4;
ActorType* mActor;
uint32_t mMagic1;
uint32_t mMagic2;
bool mShutdown;
protected:
ClientThing()
: mActor(nullptr)
, mMagic1(kMagic1)
, mMagic2(kMagic2)
, mShutdown(false)
{
}
~ClientThing()
{
AssertIsValid();
ShutdownThing();
mMagic1 = 0;
mMagic2 = 0;
}
void
AssertIsValid() const
{
MOZ_RELEASE_ASSERT(mMagic1 == kMagic1);
MOZ_RELEASE_ASSERT(mMagic2 == kMagic2);
}
// Return the current actor.
ActorType*
GetActor() const
{
AssertIsValid();
return mActor;
}
@ -43,6 +61,7 @@ protected:
bool
IsShutdown() const
{
AssertIsValid();
return mShutdown;
}
@ -52,6 +71,7 @@ protected:
MaybeExecute(const Callable& aSuccess,
const std::function<void()>& aFailure = []{})
{
AssertIsValid();
if (mShutdown) {
aFailure();
return;
@ -67,6 +87,7 @@ protected:
void
ActivateThing(ActorType* aActor)
{
AssertIsValid();
MOZ_DIAGNOSTIC_ASSERT(aActor);
MOZ_DIAGNOSTIC_ASSERT(!mActor);
MOZ_DIAGNOSTIC_ASSERT(!mShutdown);
@ -78,6 +99,7 @@ protected:
void
ShutdownThing()
{
AssertIsValid();
if (mShutdown) {
return;
}
@ -106,6 +128,7 @@ public:
void
RevokeActor(ActorType* aActor)
{
AssertIsValid();
MOZ_DIAGNOSTIC_ASSERT(mActor);
MOZ_DIAGNOSTIC_ASSERT(mActor == aActor);
mActor->RevokeOwner(this);

Просмотреть файл

@ -94,8 +94,8 @@ public:
, mTimeStamp(JS_Now() / PR_USEC_PER_MSEC)
, mStartTimerValue(0)
, mStartTimerStatus(Console::eTimerUnknown)
, mStopTimerDuration(0)
, mStopTimerStatus(Console::eTimerUnknown)
, mLogTimerDuration(0)
, mLogTimerStatus(Console::eTimerUnknown)
, mCountValue(MAX_PAGE_COUNTERS)
, mIDType(eUnknown)
, mOuterIDNumber(0)
@ -221,14 +221,14 @@ public:
Console::TimerStatus 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,
// the name and the status of the LogTimer 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 in order to create a
// ConsoleTimerEnd dictionary. This members are set when
// console.timeEnd() is called.
double mStopTimerDuration;
nsString mStopTimerLabel;
Console::TimerStatus mStopTimerStatus;
// ConsoleTimerLogOrEnd dictionary. This members are set when
// console.timeEnd() or console.timeLog() are called.
double mLogTimerDuration;
nsString mLogTimerLabel;
Console::TimerStatus mLogTimerStatus;
// These 2 values are set by IncreaseCounter on the owning thread and they are
// used CreateCounterValue. These members are set when console.count() is
@ -1231,30 +1231,42 @@ Console::GroupEnd(const GlobalObject& aGlobal)
/* static */ void
Console::Time(const GlobalObject& aGlobal, const nsAString& aLabel)
{
StringMethod(aGlobal, aLabel, MethodTime, NS_LITERAL_STRING("time"));
StringMethod(aGlobal, aLabel, Sequence<JS::Value>(), MethodTime,
NS_LITERAL_STRING("time"));
}
/* static */ void
Console::TimeEnd(const GlobalObject& aGlobal, const nsAString& aLabel)
{
StringMethod(aGlobal, aLabel, MethodTimeEnd, NS_LITERAL_STRING("timeEnd"));
StringMethod(aGlobal, aLabel, Sequence<JS::Value>(), MethodTimeEnd,
NS_LITERAL_STRING("timeEnd"));
}
/* static */ void
Console::TimeLog(const GlobalObject& aGlobal, const nsAString& aLabel,
const Sequence<JS::Value>& aData)
{
StringMethod(aGlobal, aLabel, aData, MethodTimeLog,
NS_LITERAL_STRING("timeLog"));
}
/* static */ void
Console::StringMethod(const GlobalObject& aGlobal, const nsAString& aLabel,
MethodName aMethodName, const nsAString& aMethodString)
const Sequence<JS::Value>& aData, MethodName aMethodName,
const nsAString& aMethodString)
{
RefPtr<Console> console = GetConsole(aGlobal);
if (!console) {
return;
}
console->StringMethodInternal(aGlobal.Context(), aLabel, aMethodName,
console->StringMethodInternal(aGlobal.Context(), aLabel, aData, aMethodName,
aMethodString);
}
void
Console::StringMethodInternal(JSContext* aCx, const nsAString& aLabel,
const Sequence<JS::Value>& aData,
MethodName aMethodName,
const nsAString& aMethodString)
{
@ -1272,6 +1284,12 @@ Console::StringMethodInternal(JSContext* aCx, const nsAString& aLabel,
return;
}
for (uint32_t i = 0; i < aData.Length(); ++i) {
if (!data.AppendElement(aData[i], fallible)) {
return;
}
}
MethodInternal(aCx, aMethodName, aMethodString, data);
}
@ -1422,7 +1440,8 @@ Console::Assert(const GlobalObject& aGlobal, bool aCondition,
/* static */ void
Console::Count(const GlobalObject& aGlobal, const nsAString& aLabel)
{
StringMethod(aGlobal, aLabel, MethodCount, NS_LITERAL_STRING("count"));
StringMethod(aGlobal, aLabel, Sequence<JS::Value>(), MethodCount,
NS_LITERAL_STRING("count"));
}
namespace {
@ -1573,8 +1592,9 @@ Console::MethodInternal(JSContext* aCx, MethodName aMethodName,
DOMHighResTimeStamp monotonicTimer;
// Monotonic timer for 'time' and 'timeEnd'
// Monotonic timer for 'time', 'timeLog' and 'timeEnd'
if ((aMethodName == MethodTime ||
aMethodName == MethodTimeLog ||
aMethodName == MethodTimeEnd ||
aMethodName == MethodTimeStamp) &&
!MonotonicTimer(aCx, aMethodName, aData, &monotonicTimer)) {
@ -1589,10 +1609,19 @@ Console::MethodInternal(JSContext* aCx, MethodName aMethodName,
}
else if (aMethodName == MethodTimeEnd && !aData.IsEmpty()) {
callData->mStopTimerStatus = StopTimer(aCx, aData[0],
monotonicTimer,
callData->mStopTimerLabel,
&callData->mStopTimerDuration);
callData->mLogTimerStatus = LogTimer(aCx, aData[0],
monotonicTimer,
callData->mLogTimerLabel,
&callData->mLogTimerDuration,
true /* Cancel timer */);
}
else if (aMethodName == MethodTimeLog && !aData.IsEmpty()) {
callData->mLogTimerStatus = LogTimer(aCx, aData[0],
monotonicTimer,
callData->mLogTimerLabel,
&callData->mLogTimerDuration,
false /* Cancel timer */);
}
else if (aMethodName == MethodCount) {
@ -1863,10 +1892,11 @@ Console::PopulateConsoleNotificationInTheTargetScope(JSContext* aCx,
aData->mStartTimerStatus);
}
else if (aData->mMethodName == MethodTimeEnd && !aArguments.IsEmpty()) {
event.mTimer = CreateStopTimerValue(aCx, aData->mStopTimerLabel,
aData->mStopTimerDuration,
aData->mStopTimerStatus);
else if ((aData->mMethodName == MethodTimeEnd ||
aData->mMethodName == MethodTimeLog) && !aArguments.IsEmpty()) {
event.mTimer = CreateLogOrEndTimerValue(aCx, aData->mLogTimerLabel,
aData->mLogTimerDuration,
aData->mLogTimerStatus);
}
else if (aData->mMethodName == MethodCount) {
@ -2321,10 +2351,11 @@ Console::CreateStartTimerValue(JSContext* aCx, const nsAString& aTimerLabel,
}
Console::TimerStatus
Console::StopTimer(JSContext* aCx, const JS::Value& aName,
DOMHighResTimeStamp aTimestamp,
nsAString& aTimerLabel,
double* aTimerDuration)
Console::LogTimer(JSContext* aCx, const JS::Value& aName,
DOMHighResTimeStamp aTimestamp,
nsAString& aTimerLabel,
double* aTimerDuration,
bool aCancelTimer)
{
AssertIsOnOwningThread();
MOZ_ASSERT(aTimerDuration);
@ -2345,9 +2376,17 @@ Console::StopTimer(JSContext* aCx, const JS::Value& aName,
aTimerLabel = key;
DOMHighResTimeStamp value = 0;
if (!mTimerRegistry.Remove(key, &value)) {
NS_WARNING("mTimerRegistry entry not found");
return eTimerDoesntExist;
if (aCancelTimer) {
if (!mTimerRegistry.Remove(key, &value)) {
NS_WARNING("mTimerRegistry entry not found");
return eTimerDoesntExist;
}
} else {
if (!mTimerRegistry.Get(key, &value)) {
NS_WARNING("mTimerRegistry entry not found");
return eTimerDoesntExist;
}
}
*aTimerDuration = aTimestamp - value;
@ -2355,14 +2394,14 @@ Console::StopTimer(JSContext* aCx, const JS::Value& aName,
}
JS::Value
Console::CreateStopTimerValue(JSContext* aCx, const nsAString& aLabel,
double aDuration, TimerStatus aStatus) const
Console::CreateLogOrEndTimerValue(JSContext* aCx, const nsAString& aLabel,
double aDuration, TimerStatus aStatus) const
{
if (aStatus != eTimerDone) {
return CreateTimerError(aCx, aLabel, aStatus);
}
RootedDictionary<ConsoleTimerEnd> timer(aCx);
RootedDictionary<ConsoleTimerLogOrEnd> timer(aCx);
timer.mName = aLabel;
timer.mDuration = aDuration;
@ -2996,6 +3035,7 @@ Console::WebIDLLogLevelToInteger(ConsoleLogLevel aLevel) const
case ConsoleLogLevel::Info: return 3;
case ConsoleLogLevel::Clear: return 3;
case ConsoleLogLevel::Trace: return 3;
case ConsoleLogLevel::TimeLog: return 3;
case ConsoleLogLevel::TimeEnd: return 3;
case ConsoleLogLevel::Time: return 3;
case ConsoleLogLevel::Group: return 3;
@ -3033,6 +3073,7 @@ Console::InternalLogLevelToInteger(MethodName aName) const
case MethodGroupCollapsed: return 3;
case MethodGroupEnd: return 3;
case MethodTime: return 3;
case MethodTimeLog: return 3;
case MethodTimeEnd: return 3;
case MethodTimeStamp: return 3;
case MethodAssert: return 3;

Просмотреть файл

@ -96,6 +96,10 @@ public:
static void
Time(const GlobalObject& aGlobal, const nsAString& aLabel);
static void
TimeLog(const GlobalObject& aGlobal, const nsAString& aLabel,
const Sequence<JS::Value>& aData);
static void
TimeEnd(const GlobalObject& aGlobal, const nsAString& aLabel);
@ -159,6 +163,7 @@ private:
MethodGroupCollapsed,
MethodGroupEnd,
MethodTime,
MethodTimeLog,
MethodTimeEnd,
MethodTimeStamp,
MethodAssert,
@ -193,10 +198,12 @@ private:
static void
StringMethod(const GlobalObject& aGlobal, const nsAString& aLabel,
MethodName aMethodName, const nsAString& aMethodString);
const Sequence<JS::Value>& aData, MethodName aMethodName,
const nsAString& aMethodString);
void
StringMethodInternal(JSContext* aCx, const nsAString& aLabel,
const Sequence<JS::Value>& aData,
MethodName aMethodName, const nsAString& aMethodString);
// This method must receive aCx and aArguments in the same JSCompartment.
@ -317,9 +324,9 @@ private:
CreateStartTimerValue(JSContext* aCx, const nsAString& aTimerLabel,
TimerStatus aTimerStatus) const;
// StopTimer follows the same pattern as StartTimer: it runs on the
// LogTimer follows the same pattern as StartTimer: it runs on the
// owning thread and populates aTimerLabel and aTimerDuration, used by
// CreateStopTimerValue.
// CreateLogOrEndTimerValue.
// * 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
@ -328,22 +335,24 @@ private:
// string.
// * aTimerDuration - the difference between aTimestamp and when the timer
// started (see StartTimer).
// * aCancelTimer - if true, the timer is removed from the table.
TimerStatus
StopTimer(JSContext* aCx, const JS::Value& aName,
DOMHighResTimeStamp aTimestamp,
nsAString& aTimerLabel,
double* aTimerDuration);
LogTimer(JSContext* aCx, const JS::Value& aName,
DOMHighResTimeStamp aTimestamp,
nsAString& aTimerLabel,
double* aTimerDuration,
bool aCancelTimer);
// This method generates a ConsoleTimerEnd dictionary exposed as JS::Value, or
// a ConsoleTimerError dictionary if aTimerStatus is false. See StopTimer.
// a ConsoleTimerError dictionary if aTimerStatus is false. See LogTimer.
// * 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.
// * aTimerLabel - this label must be what LogTimer received as aTimerLabel.
// * aTimerDuration - this is what LogTimer received as aTimerDuration
// * aTimerStatus - the return value of LogTimer.
JS::Value
CreateStopTimerValue(JSContext* aCx, const nsAString& aTimerLabel,
double aTimerDuration,
TimerStatus aTimerStatus) const;
CreateLogOrEndTimerValue(JSContext* aCx, const nsAString& aTimerLabel,
double aTimerDuration,
TimerStatus aTimerStatus) const;
// The method populates a Sequence from an array of JS::Value.
bool

Просмотреть файл

@ -147,14 +147,24 @@ ConsoleInstance::GroupEnd(JSContext* aCx)
void
ConsoleInstance::Time(JSContext* aCx, const nsAString& aLabel)
{
mConsole->StringMethodInternal(aCx, aLabel, Console::MethodTime,
mConsole->StringMethodInternal(aCx, aLabel, Sequence<JS::Value>(),
Console::MethodTime,
NS_LITERAL_STRING("time"));
}
void
ConsoleInstance::TimeLog(JSContext* aCx, const nsAString& aLabel,
const Sequence<JS::Value>& aData)
{
mConsole->StringMethodInternal(aCx, aLabel, aData, Console::MethodTimeLog,
NS_LITERAL_STRING("timeLog"));
}
void
ConsoleInstance::TimeEnd(JSContext* aCx, const nsAString& aLabel)
{
mConsole->StringMethodInternal(aCx, aLabel, Console::MethodTimeEnd,
mConsole->StringMethodInternal(aCx, aLabel, Sequence<JS::Value>(),
Console::MethodTimeEnd,
NS_LITERAL_STRING("timeEnd"));
}
@ -201,7 +211,8 @@ ConsoleInstance::Assert(JSContext* aCx, bool aCondition,
void
ConsoleInstance::Count(JSContext* aCx, const nsAString& aLabel)
{
mConsole->StringMethodInternal(aCx, aLabel, Console::MethodCount,
mConsole->StringMethodInternal(aCx, aLabel, Sequence<JS::Value>(),
Console::MethodCount,
NS_LITERAL_STRING("count"));
}

Просмотреть файл

@ -74,6 +74,10 @@ public:
void
Time(JSContext* aCx, const nsAString& aLabel);
void
TimeLog(JSContext* aCx, const nsAString& aLabel,
const Sequence<JS::Value>& aData);
void
TimeEnd(JSContext* aCx, const nsAString& aLabel);

Просмотреть файл

@ -10,3 +10,4 @@ support-files =
[test_console_binding.html]
[test_console_proto.html]
[test_devtools_pref.html]
[test_timer.html]

Просмотреть файл

@ -0,0 +1,111 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for timeStart/timeLog/timeEnd in console</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="application/javascript">
SimpleTest.waitForExplicitFinish();
function ConsoleListener() {
SpecialPowers.addObserver(this, "console-api-log-event");
}
ConsoleListener.prototype = {
observe(aSubject, aTopic, aData) {
let obj = aSubject.wrappedJSObject;
if (obj.arguments[0] != 'test') {
return;
}
if (!this._cb) {
ok(false, "Callback not set!");
return;
}
if (!this._cb(obj)) {
return;
}
this._cb = null;
this._resolve();
},
shutdown() {
SpecialPowers.removeObserver(this, "console-api-log-event");
},
waitFor(cb) {
return new Promise(resolve => {
this._cb = cb;
this._resolve = resolve;
});
},
};
let listener = new ConsoleListener();
// Timer creation:
async function runTest() {
let cl = listener.waitFor(obj => {
return ("timer" in obj) &&
("name" in obj.timer) &&
obj.timer.name == 'test';
});
console.time('test');
await cl;
ok(true, "Console.time received!");
// Timer check:
cl = listener.waitFor(obj => {
return ("timer" in obj) &&
("name" in obj.timer) &&
obj.timer.name == 'test' &&
("duration" in obj.timer) &&
obj.timer.duration > 0 &&
obj.arguments[1] == 1 &&
obj.arguments[2] == 2 &&
obj.arguments[3] == 3 &&
obj.arguments[4] == 4;
});
console.timeLog('test', 1, 2, 3, 4);
await cl;
ok(true, "Console.timeLog received!");
// Time deleted:
cl = listener.waitFor(obj => {
return ("timer" in obj) &&
("name" in obj.timer) &&
obj.timer.name == 'test' &&
("duration" in obj.timer) &&
obj.timer.duration > 0;
});
console.timeEnd('test');
await cl;
ok(true, "Console.timeEnd received!");
// Here an error:
cl = listener.waitFor(obj => {
return ("timer" in obj) &&
("name" in obj.timer) &&
obj.timer.name == 'test' &&
("error" in obj.timer);
});
console.timeLog('test');
await cl;
ok(true, "Console.time with error received!");
}
runTest().then(() => {
listener.shutdown();
SimpleTest.finish();
});
</script>
</body>
</html>

Просмотреть файл

@ -5368,6 +5368,54 @@ EventStateManager::ResetLastOverForContent(
}
}
void
EventStateManager::RemoveNodeFromChainIfNeeded(EventStates aState,
nsIContent* aContentRemoved,
bool aNotify)
{
MOZ_ASSERT(aState == NS_EVENT_STATE_HOVER || aState == NS_EVENT_STATE_ACTIVE);
if (!aContentRemoved->IsElement() ||
!aContentRemoved->AsElement()->State().HasState(aState)) {
return;
}
nsCOMPtr<nsIContent>& leaf =
aState == NS_EVENT_STATE_HOVER ? mHoverContent : mActiveContent;
MOZ_ASSERT(leaf);
// XBL Likes to unbind content without notifying, thus the
// NODE_IS_ANONYMOUS_ROOT check...
MOZ_ASSERT(nsContentUtils::ContentIsFlattenedTreeDescendantOf(
leaf, aContentRemoved) ||
leaf->SubtreeRoot()->HasFlag(NODE_IS_ANONYMOUS_ROOT));
nsIContent* newLeaf = aContentRemoved->GetFlattenedTreeParent();
MOZ_ASSERT_IF(newLeaf,
newLeaf->IsElement() &&
newLeaf->AsElement()->State().HasState(aState));
if (aNotify) {
SetContentState(newLeaf, aState);
} else {
// We don't update the removed content's state here, since removing NAC
// happens from layout and we don't really want to notify at that point or
// what not.
//
// Also, NAC is not observable and NAC being removed will go away soon.
leaf = newLeaf;
}
MOZ_ASSERT(leaf == newLeaf);
}
void
EventStateManager::NativeAnonymousContentRemoved(nsIContent* aContent)
{
// FIXME(bug 1450250): <svg:use> is nasty.
MOZ_ASSERT(aContent->IsRootOfNativeAnonymousSubtree() ||
aContent->GetParentNode()->IsSVGElement(nsGkAtoms::use));
RemoveNodeFromChainIfNeeded(NS_EVENT_STATE_HOVER, aContent, false);
RemoveNodeFromChainIfNeeded(NS_EVENT_STATE_ACTIVE, aContent, false);
}
void
EventStateManager::ContentRemoved(nsIDocument* aDocument, nsIContent* aContent)
{
@ -5392,19 +5440,8 @@ EventStateManager::ContentRemoved(nsIDocument* aDocument, nsIContent* aContent)
if (fm)
fm->ContentRemoved(aDocument, aContent);
if (mHoverContent &&
nsContentUtils::ContentIsFlattenedTreeDescendantOf(mHoverContent, aContent)) {
// Since hover is hierarchical, set the current hover to the
// content's parent node.
SetContentState(aContent->GetFlattenedTreeParent(), NS_EVENT_STATE_HOVER);
}
if (mActiveContent &&
nsContentUtils::ContentIsFlattenedTreeDescendantOf(mActiveContent, aContent)) {
// Active is hierarchical, so set the current active to the
// content's parent node.
SetContentState(aContent->GetFlattenedTreeParent(), NS_EVENT_STATE_ACTIVE);
}
RemoveNodeFromChainIfNeeded(NS_EVENT_STATE_HOVER, aContent, true);
RemoveNodeFromChainIfNeeded(NS_EVENT_STATE_ACTIVE, aContent, true);
if (sDragOverContent &&
sDragOverContent->OwnerDoc() == aContent->OwnerDoc() &&

Просмотреть файл

@ -148,6 +148,8 @@ public:
* affect the return value.
*/
bool SetContentState(nsIContent* aContent, EventStates aState);
void NativeAnonymousContentRemoved(nsIContent* aAnonContent);
void ContentRemoved(nsIDocument* aDocument, nsIContent* aContent);
bool EventStatusOK(WidgetGUIEvent* aEvent);
@ -1087,6 +1089,14 @@ protected:
void HandleQueryContentEvent(WidgetQueryContentEvent* aEvent);
private:
// Removes a node from the :hover / :active chain if needed, notifying if the
// node is not a NAC subtree.
//
// Only meant to be called from ContentRemoved and
// NativeAnonymousContentRemoved.
void RemoveNodeFromChainIfNeeded(EventStates aState,
nsIContent* aContentRemoved,
bool aNotify);
bool IsEventOutsideDragThreshold(WidgetInputEvent* aEvent) const;

Просмотреть файл

@ -1346,16 +1346,4 @@ NS_DECLARE_NS_NEW_HTML_ELEMENT(Track)
NS_DECLARE_NS_NEW_HTML_ELEMENT(Unknown)
NS_DECLARE_NS_NEW_HTML_ELEMENT(Video)
inline nsISupports*
ToSupports(nsGenericHTMLElement* aHTMLElement)
{
return static_cast<nsIContent*>(aHTMLElement);
}
inline nsISupports*
ToCanonicalSupports(nsGenericHTMLElement* aHTMLElement)
{
return static_cast<nsIContent*>(aHTMLElement);
}
#endif /* nsGenericHTMLElement_h___ */

Просмотреть файл

@ -1889,64 +1889,49 @@ nsHTMLDocument::ReleaseEvents()
WarnOnceAbout(nsIDocument::eUseOfReleaseEvents);
}
nsISupports*
nsHTMLDocument::ResolveName(const nsAString& aName, nsWrapperCache **aCache)
bool
nsHTMLDocument::ResolveName(JSContext* aCx, const nsAString& aName,
JS::MutableHandle<JS::Value> aRetval, ErrorResult& aError)
{
nsIdentifierMapEntry *entry = mIdentifierMap.GetEntry(aName);
if (!entry) {
*aCache = nullptr;
return nullptr;
return false;
}
nsBaseContentList *list = entry->GetNameContentList();
uint32_t length = list ? list->Length() : 0;
nsIContent *node;
if (length > 0) {
if (length == 1) {
// Only one element in the list, return the element instead of returning
// the list.
nsIContent *node = list->Item(0);
*aCache = node;
return node;
if (length > 1) {
// The list contains more than one element, return the whole list.
if (!ToJSValue(aCx, list, aRetval)) {
aError.NoteJSContextException(aCx);
return false;
}
return true;
}
// The list contains more than one element, return the whole list.
*aCache = list;
return list;
// Only one element in the list, return the element instead of returning
// the list.
node = list->Item(0);
} else {
// No named items were found, see if there's one registerd by id for aName.
Element *e = entry->GetIdElement();
if (!e || !nsGenericHTMLElement::ShouldExposeIdAsHTMLDocumentProperty(e)) {
return false;
}
node = e;
}
// No named items were found, see if there's one registerd by id for aName.
Element *e = entry->GetIdElement();
if (e && nsGenericHTMLElement::ShouldExposeIdAsHTMLDocumentProperty(e)) {
*aCache = e;
return e;
if (!ToJSValue(aCx, node, aRetval)) {
aError.NoteJSContextException(aCx);
return false;
}
*aCache = nullptr;
return nullptr;
}
void
nsHTMLDocument::NamedGetter(JSContext* cx, const nsAString& aName, bool& aFound,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& rv)
{
nsWrapperCache* cache;
nsISupports* supp = ResolveName(aName, &cache);
if (!supp) {
aFound = false;
aRetval.set(nullptr);
return;
}
JS::Rooted<JS::Value> val(cx);
if (!dom::WrapObject(cx, supp, cache, nullptr, &val)) {
rv.Throw(NS_ERROR_OUT_OF_MEMORY);
return;
}
aFound = true;
aRetval.set(&val.toObject());
return true;
}
void

Просмотреть файл

@ -79,7 +79,9 @@ public:
mozilla::dom::HTMLAllCollection* All();
nsISupports* ResolveName(const nsAString& aName, nsWrapperCache **aCache);
// Returns whether an object was found for aName.
bool ResolveName(JSContext* aCx, const nsAString& aName,
JS::MutableHandle<JS::Value> aRetval, mozilla::ErrorResult& aError);
virtual void AddedForm() override;
virtual void RemovedForm() override;
@ -151,7 +153,13 @@ public:
void SetCookie(const nsAString& aCookie, mozilla::ErrorResult& rv);
void NamedGetter(JSContext* cx, const nsAString& aName, bool& aFound,
JS::MutableHandle<JSObject*> aRetval,
mozilla::ErrorResult& rv);
mozilla::ErrorResult& rv)
{
JS::Rooted<JS::Value> v(cx);
if ((aFound = ResolveName(cx, aName, &v, rv))) {
aRetval.set(v.toObjectOrNull());
}
}
void GetSupportedNames(nsTArray<nsString>& aNames);
already_AddRefed<nsIDocument> Open(JSContext* cx,
const mozilla::dom::Optional<nsAString>& /* unused */,

Просмотреть файл

@ -7,7 +7,6 @@
#include "Connection.h"
#include "ConnectionMainThread.h"
#include "ConnectionWorker.h"
#include "nsIDOMClassInfo.h"
#include "Constants.h"
#include "mozilla/Telemetry.h"
#include "mozilla/dom/WorkerPrivate.h"

Просмотреть файл

@ -8,6 +8,7 @@
#include "nsIDocument.h"
#include "nsPIDOMWindow.h"
#include "ServiceWorkerImpl.h"
#include "ServiceWorkerManager.h"
#include "ServiceWorkerPrivate.h"
@ -62,7 +63,8 @@ ServiceWorker::Create(nsIGlobalObject* aOwner,
return ref.forget();
}
ref = new ServiceWorker(aOwner, aDescriptor, info);
RefPtr<ServiceWorker::Inner> inner = new ServiceWorkerImpl(info);
ref = new ServiceWorker(aOwner, aDescriptor, inner);
return ref.forget();
}

Просмотреть файл

@ -0,0 +1,65 @@
/* -*- 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/. */
#include "ServiceWorkerImpl.h"
namespace mozilla {
namespace dom {
ServiceWorkerImpl::~ServiceWorkerImpl()
{
MOZ_DIAGNOSTIC_ASSERT(!mOuter);
mInfo->RemoveListener(this);
}
void
ServiceWorkerImpl::AddServiceWorker(ServiceWorker* aWorker)
{
MOZ_DIAGNOSTIC_ASSERT(!mOuter);
MOZ_DIAGNOSTIC_ASSERT(aWorker);
mOuter = aWorker;
// Wait to attach to the info as a listener until we have the outer
// set. This is important because the info will try to set the
// state immediately.
mInfo->AddListener(this);
}
void
ServiceWorkerImpl::RemoveServiceWorker(ServiceWorker* aWorker)
{
MOZ_DIAGNOSTIC_ASSERT(mOuter);
MOZ_DIAGNOSTIC_ASSERT(mOuter == aWorker);
mOuter = nullptr;
}
void
ServiceWorkerImpl::PostMessage(ipc::StructuredCloneData&& aData,
const ClientInfo& aClientInfo,
const ClientState& aClientState)
{
mInfo->PostMessage(Move(aData), aClientInfo, aClientState);
}
void
ServiceWorkerImpl::SetState(ServiceWorkerState aState)
{
if (!mOuter) {
return;
}
mOuter->SetState(aState);
}
ServiceWorkerImpl::ServiceWorkerImpl(ServiceWorkerInfo* aInfo)
: mInfo(aInfo)
, mOuter(nullptr)
{
MOZ_DIAGNOSTIC_ASSERT(mInfo);
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,51 @@
/* -*- 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/. */
#ifndef mozilla_dom_ServiceWorkerImpl_h
#define mozilla_dom_ServiceWorkerImpl_h
#include "ServiceWorker.h"
#include "ServiceWorkerInfo.h"
namespace mozilla {
namespace dom {
class ServiceWorkerInfo;
class ServiceWorkerImpl final : public ServiceWorker::Inner
, public ServiceWorkerInfo::Listener
{
RefPtr<ServiceWorkerInfo> mInfo;
ServiceWorker* mOuter;
~ServiceWorkerImpl();
// ServiceWorker::Inner interface
void
AddServiceWorker(ServiceWorker* aWorker) override;
void
RemoveServiceWorker(ServiceWorker* aWorker) override;
void
PostMessage(ipc::StructuredCloneData&& aData,
const ClientInfo& aClientInfo,
const ClientState& aClientState) override;
// ServiceWorkerInfo::Listener interface
void
SetState(ServiceWorkerState aState) override;
public:
explicit ServiceWorkerImpl(ServiceWorkerInfo* aInfo);
NS_INLINE_DECL_REFCOUNTING(ServiceWorkerImpl, override);
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_ServiceWorkerImpl_h

Просмотреть файл

@ -118,7 +118,7 @@ namespace {
class ChangeStateUpdater final : public Runnable
{
public:
ChangeStateUpdater(const nsTArray<ServiceWorker*>& aInstances,
ChangeStateUpdater(const nsTArray<ServiceWorkerInfo::Listener*>& aInstances,
ServiceWorkerState aState)
: Runnable("dom::ChangeStateUpdater")
, mState(aState)
@ -137,7 +137,7 @@ public:
}
private:
AutoTArray<RefPtr<ServiceWorker>, 1> mInstances;
AutoTArray<RefPtr<ServiceWorkerInfo::Listener>, 1> mInstances;
ServiceWorkerState mState;
};
@ -225,33 +225,20 @@ ServiceWorkerInfo::GetNextID() const
}
void
ServiceWorkerInfo::AddServiceWorker(ServiceWorker* aWorker)
ServiceWorkerInfo::AddListener(Listener* aListener)
{
MOZ_DIAGNOSTIC_ASSERT(aWorker);
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
nsAutoString workerURL;
aWorker->GetScriptURL(workerURL);
MOZ_DIAGNOSTIC_ASSERT(
workerURL.Equals(NS_ConvertUTF8toUTF16(mDescriptor.ScriptURL())));
#endif
MOZ_ASSERT(!mInstances.Contains(aWorker));
MOZ_DIAGNOSTIC_ASSERT(aListener);
MOZ_ASSERT(!mInstances.Contains(aListener));
mInstances.AppendElement(aWorker);
aWorker->SetState(State());
mInstances.AppendElement(aListener);
aListener->SetState(State());
}
void
ServiceWorkerInfo::RemoveServiceWorker(ServiceWorker* aWorker)
ServiceWorkerInfo::RemoveListener(Listener* aListener)
{
MOZ_DIAGNOSTIC_ASSERT(aWorker);
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
nsAutoString workerURL;
aWorker->GetScriptURL(workerURL);
MOZ_DIAGNOSTIC_ASSERT(
workerURL.Equals(NS_ConvertUTF8toUTF16(mDescriptor.ScriptURL())));
#endif
DebugOnly<bool> removed = mInstances.RemoveElement(aWorker);
MOZ_DIAGNOSTIC_ASSERT(aListener);
DebugOnly<bool> removed = mInstances.RemoveElement(aListener);
MOZ_ASSERT(removed);
}

Просмотреть файл

@ -12,7 +12,6 @@
#include "mozilla/dom/WorkerCommon.h"
#include "mozilla/OriginAttributes.h"
#include "nsIServiceWorkerManager.h"
#include "ServiceWorker.h"
namespace mozilla {
namespace dom {
@ -27,8 +26,17 @@ class ServiceWorkerPrivate;
* by this class and spawn a ServiceWorker in the right global when required.
*/
class ServiceWorkerInfo final : public nsIServiceWorkerInfo
, public ServiceWorker::Inner
{
public:
class Listener
{
public:
virtual void
SetState(ServiceWorkerState aState) = 0;
NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
};
private:
nsCOMPtr<nsIPrincipal> mPrincipal;
ServiceWorkerDescriptor mDescriptor;
@ -60,7 +68,7 @@ private:
//
// There is a high chance of there being at least one ServiceWorker
// associated with this all the time.
AutoTArray<ServiceWorker*, 1> mInstances;
AutoTArray<Listener*, 1> mInstances;
RefPtr<ServiceWorkerPrivate> mServiceWorkerPrivate;
bool mSkipWaitingFlag;
@ -78,22 +86,21 @@ private:
uint64_t
GetNextID() const;
// ServiceWorker::Inner implementation
virtual void
AddServiceWorker(ServiceWorker* aWorker) override;
virtual void
RemoveServiceWorker(ServiceWorker* aWorker) override;
virtual void
PostMessage(ipc::StructuredCloneData&& aData,
const ClientInfo& aClientInfo,
const ClientState& aClientState) override;
public:
NS_DECL_ISUPPORTS
NS_DECL_NSISERVICEWORKERINFO
void
AddListener(Listener* aListener);
void
RemoveListener(Listener* aListener);
void
PostMessage(ipc::StructuredCloneData&& aData,
const ClientInfo& aClientInfo,
const ClientState& aClientState);
class ServiceWorkerPrivate*
WorkerPrivate() const
{

Просмотреть файл

@ -15,6 +15,7 @@
#include "nsIObserverService.h"
#include "nsIOutputStream.h"
#include "nsISafeOutputStream.h"
#include "nsIServiceWorkerManager.h"
#include "MainThreadUtils.h"
#include "mozilla/ClearOnShutdown.h"
@ -36,6 +37,7 @@
#include "nsServiceManagerUtils.h"
#include "nsThreadUtils.h"
#include "nsXULAppAPI.h"
#include "ServiceWorkerUtils.h"
using namespace mozilla::ipc;

Просмотреть файл

@ -32,6 +32,7 @@ UNIFIED_SOURCES += [
'ServiceWorkerContainerImpl.cpp',
'ServiceWorkerDescriptor.cpp',
'ServiceWorkerEvents.cpp',
'ServiceWorkerImpl.cpp',
'ServiceWorkerInfo.cpp',
'ServiceWorkerInterceptController.cpp',
'ServiceWorkerJob.cpp',

Просмотреть файл

@ -32,6 +32,7 @@ function doTest() {
"groupCollapsed": "function",
"groupEnd": "function",
"time": "function",
"timeLog": "function",
"timeEnd": "function",
"profile": "function",
"profileEnd": "function",

Просмотреть файл

@ -256,8 +256,6 @@ var interfaceNamesInGlobalScope =
{name: "CSSNamespaceRule", insecureContext: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "CSSPageRule", insecureContext: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "CSSPrimitiveValue", insecureContext: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "CSSPseudoElement", insecureContext: true, release: false},
// IMPORTANT: Do not change this list without review from a DOM peer!
@ -274,10 +272,6 @@ var interfaceNamesInGlobalScope =
{name: "CSSSupportsRule", insecureContext: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "CSSTransition", insecureContext: true, release: false},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "CSSValue", insecureContext: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "CSSValueList", insecureContext: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "CustomElementRegistry", insecureContext: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
@ -814,14 +808,10 @@ var interfaceNamesInGlobalScope =
{name: "RadioNodeList", insecureContext: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "Range", insecureContext: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "Rect", insecureContext: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "Request", insecureContext: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "Response", insecureContext: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "RGBColor", insecureContext: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "RTCCertificate", insecureContext: true},
// IMPORTANT: Do not change this list without review from a DOM peer!

Просмотреть файл

@ -1,54 +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/.
*/
interface CSSPrimitiveValue : CSSValue {
// UnitTypes
const unsigned short CSS_UNKNOWN = 0;
const unsigned short CSS_NUMBER = 1;
const unsigned short CSS_PERCENTAGE = 2;
const unsigned short CSS_EMS = 3;
const unsigned short CSS_EXS = 4;
const unsigned short CSS_PX = 5;
const unsigned short CSS_CM = 6;
const unsigned short CSS_MM = 7;
const unsigned short CSS_IN = 8;
const unsigned short CSS_PT = 9;
const unsigned short CSS_PC = 10;
const unsigned short CSS_DEG = 11;
const unsigned short CSS_RAD = 12;
const unsigned short CSS_GRAD = 13;
const unsigned short CSS_MS = 14;
const unsigned short CSS_S = 15;
const unsigned short CSS_HZ = 16;
const unsigned short CSS_KHZ = 17;
const unsigned short CSS_DIMENSION = 18;
const unsigned short CSS_STRING = 19;
const unsigned short CSS_URI = 20;
const unsigned short CSS_IDENT = 21;
const unsigned short CSS_ATTR = 22;
const unsigned short CSS_COUNTER = 23;
const unsigned short CSS_RECT = 24;
const unsigned short CSS_RGBCOLOR = 25;
readonly attribute unsigned short primitiveType;
[Throws]
void setFloatValue(unsigned short unitType,
float floatValue);
[Throws]
float getFloatValue(unsigned short unitType);
[Throws]
void setStringValue(unsigned short stringType,
DOMString stringValue);
[Throws]
DOMString getStringValue();
[Throws]
void getCounterValue(); // always throws
[Throws]
Rect getRectValue();
[Throws]
RGBColor getRGBColorValue();
};

Просмотреть файл

@ -1,19 +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/.
*/
interface CSSValue {
// UnitTypes
const unsigned short CSS_INHERIT = 0;
const unsigned short CSS_PRIMITIVE_VALUE = 1;
const unsigned short CSS_VALUE_LIST = 2;
const unsigned short CSS_CUSTOM = 3;
[Throws]
attribute DOMString cssText;
readonly attribute unsigned short cssValueType;
};

Просмотреть файл

@ -1,10 +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/.
*/
interface CSSValueList : CSSValue {
readonly attribute unsigned long length;
getter CSSValue? item(unsigned long index);
};

Просмотреть файл

@ -54,6 +54,8 @@ namespace console {
[UseCounter]
void time(optional DOMString label = "default");
[UseCounter]
void timeLog(optional DOMString label = "default", any... data);
[UseCounter]
void timeEnd(optional DOMString label = "default");
// Mozilla only or Webcompat methods
@ -121,7 +123,7 @@ dictionary ConsoleTimerStart {
DOMString name = "";
};
dictionary ConsoleTimerEnd {
dictionary ConsoleTimerLogOrEnd {
DOMString name = "";
double duration = 0;
};
@ -165,6 +167,7 @@ interface ConsoleInstance {
// Timing
void time(optional DOMString label = "default");
void timeLog(optional DOMString label = "default", any... data);
void timeEnd(optional DOMString label = "default");
// Mozilla only or Webcompat methods
@ -179,8 +182,9 @@ interface ConsoleInstance {
callback ConsoleInstanceDumpCallback = void (DOMString message);
enum ConsoleLogLevel {
"All", "Debug", "Log", "Info", "Clear", "Trace", "TimeEnd", "Time", "Group",
"GroupEnd", "Profile", "ProfileEnd", "Dir", "Dirxml", "Warn", "Error", "Off"
"All", "Debug", "Log", "Info", "Clear", "Trace", "TimeLog", "TimeEnd", "Time",
"Group", "GroupEnd", "Profile", "ProfileEnd", "Dir", "Dirxml", "Warn", "Error",
"Off"
};
dictionary ConsoleInstanceOptions {

Просмотреть файл

@ -1,17 +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/DOM-Level-2-Style/css.html#CSS-RGBColor
*/
interface RGBColor {
readonly attribute CSSPrimitiveValue red;
readonly attribute CSSPrimitiveValue green;
readonly attribute CSSPrimitiveValue blue;
// mozilla specific
readonly attribute CSSPrimitiveValue alpha;
};

Просмотреть файл

@ -1,12 +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/.
*/
interface Rect {
readonly attribute CSSPrimitiveValue top;
readonly attribute CSSPrimitiveValue right;
readonly attribute CSSPrimitiveValue bottom;
readonly attribute CSSPrimitiveValue left;
};

Просмотреть файл

@ -441,7 +441,6 @@ WEBIDL_FILES = [
'CSSMozDocumentRule.webidl',
'CSSNamespaceRule.webidl',
'CSSPageRule.webidl',
'CSSPrimitiveValue.webidl',
'CSSPseudoElement.webidl',
'CSSRule.webidl',
'CSSRuleList.webidl',
@ -450,8 +449,6 @@ WEBIDL_FILES = [
'CSSStyleSheet.webidl',
'CSSSupportsRule.webidl',
'CSSTransition.webidl',
'CSSValue.webidl',
'CSSValueList.webidl',
'CustomElementRegistry.webidl',
'DataTransfer.webidl',
'DataTransferItem.webidl',
@ -738,10 +735,8 @@ WEBIDL_FILES = [
'PushSubscriptionOptions.webidl',
'RadioNodeList.webidl',
'Range.webidl',
'Rect.webidl',
'Request.webidl',
'Response.webidl',
'RGBColor.webidl',
'RTCStatsReport.webidl',
'Screen.webidl',
'ScreenOrientation.webidl',

Просмотреть файл

@ -14,7 +14,6 @@
#include "mozilla/EditorUtils.h"
#include "mozilla/Preferences.h"
#include "mozilla/TextEditRules.h"
#include "mozilla/dom/CSSPrimitiveValueBinding.h"
#include "mozilla/dom/Selection.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/EventTarget.h"

Просмотреть файл

@ -5,7 +5,6 @@
#include "mozilla/HTMLEditor.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/CSSPrimitiveValueBinding.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/EventTarget.h"
#include "mozilla/mozalloc.h"

Просмотреть файл

@ -4211,15 +4211,16 @@ gfxFontStyle::gfxFontStyle(FontSlantStyle aStyle,
PLDHashNumber
gfxFontStyle::Hash() const
{
return mozilla::HashGeneric(systemFont, style.ForHash(),
stretch.ForHash(), weight.ForHash(),
size, sizeAdjust,
nsRefPtrHashKey<nsAtom>::HashKey(language));
/* XXX
return (style + (systemFont << 7) + (weight.ForHash() << 8) +
uint32_t(size*1000) + int32_t(sizeAdjust*1000)) ^
nsRefPtrHashKey<nsAtom>::HashKey(language);
*/
uint32_t hash =
variationSettings.IsEmpty()
? 0
: mozilla::HashBytes(variationSettings.Elements(),
variationSettings.Length() *
sizeof(gfxFontVariation));
return mozilla::AddToHash(hash, systemFont, style.ForHash(),
stretch.ForHash(), weight.ForHash(),
size, int32_t(sizeAdjust * 1000.0f),
nsRefPtrHashKey<nsAtom>::HashKey(language));
}
void

Просмотреть файл

@ -1524,8 +1524,6 @@ WeightDistance(const gfxFontEntry* aFontEntry, FontWeight aTargetWeight)
return distance;
}
#define MAX_DISTANCE 1.0e20 // >> than any WeightStyleStretchDistance result
static inline double
WeightStyleStretchDistance(gfxFontEntry* aFontEntry,
const gfxFontStyle& aTargetStyle)
@ -1625,7 +1623,7 @@ gfxFontFamily::FindAllFontsForStyle(const gfxFontStyle& aFontStyle,
// weight/style/stretch combination, only the last matched font entry will
// be added.
double minDistance = MAX_DISTANCE;
double minDistance = INFINITY;
gfxFontEntry* matched = nullptr;
// iterate in forward order so that faces like 'Bold' are matched before
// matching style distance faces such as 'Bold Outline' (see bug 1185812)
@ -1735,45 +1733,8 @@ void gfxFontFamily::LocalizedName(nsAString& aLocalizedName)
aLocalizedName = mName;
}
// metric for how close a given font matches a style
static float
CalcStyleMatch(gfxFontEntry *aFontEntry, const gfxFontStyle *aStyle)
{
float rank = 0;
if (aStyle) {
// TODO: stretch
// italics
bool wantUpright = aStyle->style.IsNormal();
if (aFontEntry->IsUpright() == wantUpright) {
rank += 5000.0f;
}
// measure of closeness of weight to the desired value
if (aFontEntry->Weight().Min() > aStyle->weight) {
rank += 1000.0f - (aFontEntry->Weight().Min() - aStyle->weight);
} else if (aFontEntry->Weight().Max() < aStyle->weight) {
rank += 1000.0f - (aStyle->weight - aFontEntry->Weight().Max());
} else {
rank += 2000.0f; // the font supports the exact weight wanted
}
} else {
// if no font to match, prefer non-bold, non-italic fonts
if (aFontEntry->IsUpright()) {
rank += 2000.0f;
}
if (aFontEntry->Weight().Min() <= FontWeight(500)) {
rank += 1000.0f;
}
}
return rank;
}
#define RANK_MATCHED_CMAP 10000.0f
void
gfxFontFamily::FindFontForChar(GlobalFontMatch *aMatchData)
gfxFontFamily::FindFontForChar(GlobalFontMatch* aMatchData)
{
if (mFamilyCharacterMapInitialized && !TestCharacterMap(aMatchData->mCh)) {
// none of the faces in the family support the required char,
@ -1781,81 +1742,72 @@ gfxFontFamily::FindFontForChar(GlobalFontMatch *aMatchData)
return;
}
gfxFontEntry *fe =
FindFontForStyle(aMatchData->mStyle ? *aMatchData->mStyle
: gfxFontStyle(),
true);
gfxFontEntry* fe =
FindFontForStyle(aMatchData->mStyle, /*aIgnoreSizeTolerance*/ true);
if (!fe || fe->SkipDuringSystemFallback()) {
return;
}
if (fe && !fe->SkipDuringSystemFallback()) {
float rank = 0;
float distance = INFINITY;
if (fe->HasCharacter(aMatchData->mCh)) {
rank += RANK_MATCHED_CMAP;
aMatchData->mCount++;
if (fe->HasCharacter(aMatchData->mCh)) {
aMatchData->mCount++;
LogModule* log = gfxPlatform::GetLog(eGfxLog_textrun);
LogModule* log = gfxPlatform::GetLog(eGfxLog_textrun);
if (MOZ_UNLIKELY(MOZ_LOG_TEST(log, LogLevel::Debug))) {
uint32_t unicodeRange = FindCharUnicodeRange(aMatchData->mCh);
Script script = GetScriptCode(aMatchData->mCh);
MOZ_LOG(log, LogLevel::Debug,\
("(textrun-systemfallback-fonts) char: u+%6.6x "
"unicode-range: %d script: %d match: [%s]\n",
aMatchData->mCh,
unicodeRange, int(script),
NS_ConvertUTF16toUTF8(fe->Name()).get()));
}
// omitting from original windows code -- family name, lang group, pitch
// not available in current FontEntry implementation
rank += CalcStyleMatch(fe, aMatchData->mStyle);
} else if (!fe->IsNormalStyle()) {
// If style/weight/stretch was not Normal, see if we can
// fall back to a next-best face (e.g. Arial Black -> Bold,
// or Arial Narrow -> Regular).
GlobalFontMatch data(aMatchData->mCh, aMatchData->mStyle);
SearchAllFontsForChar(&data);
if (data.mMatchRank >= RANK_MATCHED_CMAP) {
fe = data.mBestMatch;
rank = data.mMatchRank;
} else {
return;
}
} else {
return;
if (MOZ_UNLIKELY(MOZ_LOG_TEST(log, LogLevel::Debug))) {
uint32_t unicodeRange = FindCharUnicodeRange(aMatchData->mCh);
Script script = GetScriptCode(aMatchData->mCh);
MOZ_LOG(log, LogLevel::Debug,\
("(textrun-systemfallback-fonts) char: u+%6.6x "
"unicode-range: %d script: %d match: [%s]\n",
aMatchData->mCh,
unicodeRange, int(script),
NS_ConvertUTF16toUTF8(fe->Name()).get()));
}
aMatchData->mCmapsTested++;
// xxx - add whether AAT font with morphing info for specific lang groups
if (rank > aMatchData->mMatchRank
|| (rank == aMatchData->mMatchRank &&
Compare(fe->Name(), aMatchData->mBestMatch->Name()) > 0))
{
aMatchData->mBestMatch = fe;
aMatchData->mMatchedFamily = this;
aMatchData->mMatchRank = rank;
distance = WeightStyleStretchDistance(fe, aMatchData->mStyle);
} else if (!fe->IsNormalStyle()) {
// If style/weight/stretch was not Normal, see if we can
// fall back to a next-best face (e.g. Arial Black -> Bold,
// or Arial Narrow -> Regular).
GlobalFontMatch data(aMatchData->mCh, aMatchData->mStyle);
SearchAllFontsForChar(&data);
if (std::isfinite(data.mMatchDistance)) {
fe = data.mBestMatch;
distance = data.mMatchDistance;
}
}
aMatchData->mCmapsTested++;
if (std::isinf(distance)) {
return;
}
if (distance < aMatchData->mMatchDistance ||
(distance == aMatchData->mMatchDistance &&
Compare(fe->Name(), aMatchData->mBestMatch->Name()) > 0)) {
aMatchData->mBestMatch = fe;
aMatchData->mMatchedFamily = this;
aMatchData->mMatchDistance = distance;
}
}
void
gfxFontFamily::SearchAllFontsForChar(GlobalFontMatch *aMatchData)
gfxFontFamily::SearchAllFontsForChar(GlobalFontMatch* aMatchData)
{
uint32_t i, numFonts = mAvailableFonts.Length();
for (i = 0; i < numFonts; i++) {
gfxFontEntry *fe = mAvailableFonts[i];
if (fe && fe->HasCharacter(aMatchData->mCh)) {
float rank = RANK_MATCHED_CMAP;
rank += CalcStyleMatch(fe, aMatchData->mStyle);
if (rank > aMatchData->mMatchRank
|| (rank == aMatchData->mMatchRank &&
float distance = WeightStyleStretchDistance(fe, aMatchData->mStyle);
if (distance < aMatchData->mMatchDistance
|| (distance == aMatchData->mMatchDistance &&
Compare(fe->Name(), aMatchData->mBestMatch->Name()) > 0))
{
aMatchData->mBestMatch = fe;
aMatchData->mMatchedFamily = this;
aMatchData->mMatchRank = rank;
aMatchData->mMatchDistance = distance;
}
}
}

Просмотреть файл

@ -24,6 +24,7 @@
#include "mozilla/gfx/2D.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/WeakPtr.h"
#include <math.h>
typedef struct gr_face gr_face;
@ -690,20 +691,19 @@ gfxFontEntry::SupportsBold()
// used when iterating over all fonts looking for a match for a given character
struct GlobalFontMatch {
GlobalFontMatch(const uint32_t aCharacter,
const gfxFontStyle *aStyle) :
mCh(aCharacter), mStyle(aStyle),
mMatchRank(0.0f), mCount(0), mCmapsTested(0)
const gfxFontStyle& aStyle) :
mStyle(aStyle), mCh(aCharacter),
mCount(0), mCmapsTested(0), mMatchDistance(INFINITY)
{
}
RefPtr<gfxFontEntry> mBestMatch; // current best match
RefPtr<gfxFontFamily> mMatchedFamily; // the family it belongs to
const gfxFontStyle& mStyle; // style to match
const uint32_t mCh; // codepoint to be matched
const gfxFontStyle* mStyle; // style to match
float mMatchRank; // metric indicating closest match
RefPtr<gfxFontEntry> mBestMatch; // current best match
RefPtr<gfxFontFamily> mMatchedFamily; // the family it belongs to
uint32_t mCount; // number of fonts matched
uint32_t mCmapsTested; // number of cmaps tested
float mMatchDistance; // metric indicating closest match
};
class gfxFontFamily {
@ -786,10 +786,10 @@ public:
// checks for a matching font within the family
// used as part of the font fallback process
void FindFontForChar(GlobalFontMatch *aMatchData);
void FindFontForChar(GlobalFontMatch* aMatchData);
// checks all fonts for a matching font within the family
void SearchAllFontsForChar(GlobalFontMatch *aMatchData);
void SearchAllFontsForChar(GlobalFontMatch* aMatchData);
// read in other family names, if any, and use functor to add each into cache
virtual void ReadOtherFamilyNames(gfxPlatformFontList *aPlatformFontList);

Просмотреть файл

@ -23,6 +23,13 @@
using namespace mozilla;
using namespace mozilla::gfx;
template<class T>
struct TagEquals {
bool Equals(const T& aIter, uint32_t aTag) const {
return aIter.mTag == aTag;
}
};
gfxMacFont::gfxMacFont(const RefPtr<UnscaledFontMac>& aUnscaledFont,
MacOSFontEntry *aFontEntry,
const gfxFontStyle *aFontStyle)
@ -47,6 +54,55 @@ gfxMacFont::gfxMacFont(const RefPtr<UnscaledFontMac>& aUnscaledFont,
AutoTArray<gfxFontVariation,4> vars;
aFontEntry->GetVariationsForStyle(vars, *aFontStyle);
// Because of a Core Text bug, we need to ensure that if the font has
// an 'opsz' axis, it is always explicitly set, and NOT to the font's
// default value. (See bug 1457417.)
// We record the result of searching the font's axes in the font entry,
// so that this only has to be done by the first instance created for
// a given font resource.
const uint32_t kOpszTag = HB_TAG('o','p','s','z');
if (!aFontEntry->mCheckedForOpszAxis) {
aFontEntry->mCheckedForOpszAxis = true;
AutoTArray<gfxFontVariationAxis,4> axes;
aFontEntry->GetVariationAxes(axes);
auto index =
axes.IndexOf(kOpszTag, 0, TagEquals<gfxFontVariationAxis>());
if (index == axes.NoIndex) {
aFontEntry->mHasOpszAxis = false;
} else {
const auto& axis = axes[index];
aFontEntry->mHasOpszAxis = true;
aFontEntry->mOpszAxis = axis;
// Pick a slightly-adjusted version of the default that we'll
// use to work around Core Text's habit of ignoring any attempt
// to explicitly set the default value.
aFontEntry->mAdjustedDefaultOpsz =
axis.mDefaultValue == axis.mMinValue
? axis.mDefaultValue + 0.001f
: axis.mDefaultValue - 0.001f;
}
}
// Add 'opsz' if not present, or tweak its value if it looks too close
// to the default (after clamping to the font's available range).
if (aFontEntry->mHasOpszAxis) {
auto index =
vars.IndexOf(kOpszTag, 0, TagEquals<gfxFontVariation>());
if (index == vars.NoIndex) {
gfxFontVariation opsz{kOpszTag, aFontEntry->mAdjustedDefaultOpsz};
vars.AppendElement(opsz);
} else {
// Figure out a "safe" value that Core Text won't ignore.
auto& value = vars[index].mValue;
auto& axis = aFontEntry->mOpszAxis;
value = fmin(fmax(value, axis.mMinValue), axis.mMaxValue);
if (abs(value - axis.mDefaultValue) < 0.001f) {
value = aFontEntry->mAdjustedDefaultOpsz;
}
}
}
mCGFont =
UnscaledFontMac::CreateCGFontWithVariations(baseFont,
vars.Length(),

Просмотреть файл

@ -30,6 +30,7 @@ class MacOSFontEntry : public gfxFontEntry
{
public:
friend class gfxMacPlatformFontList;
friend class gfxMacFont;
MacOSFontEntry(const nsAString& aPostscriptName, WeightRange aWeight,
bool aIsStandardFace = false,
@ -104,6 +105,19 @@ protected:
bool mHasAATSmallCaps;
bool mHasAATSmallCapsInitialized;
bool mCheckedForTracking;
// To work around Core Text's mishandling of the default value for 'opsz',
// we need to record whether the font has an a optical size axis, what its
// range and default values are, and a usable close-to-default alternative.
// (See bug 1457417 for details.)
// These fields are used by gfxMacFont, but stored in the font entry so
// that only a single font instance needs to inspect the available
// variations.
bool mCheckedForOpszAxis;
bool mHasOpszAxis;
gfxFontVariationAxis mOpszAxis;
float mAdjustedDefaultOpsz;
nsTHashtable<nsUint32HashKey> mAvailableTables;
mozilla::ThreadSafeWeakPtr<mozilla::gfx::UnscaledFontMac> mUnscaledFont;

Просмотреть файл

@ -381,6 +381,7 @@ MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName,
mHasAATSmallCaps(false),
mHasAATSmallCapsInitialized(false),
mCheckedForTracking(false),
mCheckedForOpszAxis(false),
mTrakTable(nullptr),
mTrakValues(nullptr),
mTrakSizeTable(nullptr)
@ -407,6 +408,7 @@ MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName,
mHasAATSmallCaps(false),
mHasAATSmallCapsInitialized(false),
mCheckedForTracking(false),
mCheckedForOpszAxis(false),
mTrakTable(nullptr),
mTrakValues(nullptr),
mTrakSizeTable(nullptr)

Просмотреть файл

@ -682,7 +682,7 @@ gfxPlatformFontList::CommonFontFallback(uint32_t aCh, uint32_t aNextCh,
// If style/weight/stretch was not Normal, see if we can
// fall back to a next-best face (e.g. Arial Black -> Bold,
// or Arial Narrow -> Regular).
GlobalFontMatch data(aCh, aMatchStyle);
GlobalFontMatch data(aCh, *aMatchStyle);
fallback->SearchAllFontsForChar(&data);
if (data.mBestMatch) {
*aMatchedFamily = fallback;
@ -715,7 +715,7 @@ gfxPlatformFontList::GlobalFontFallback(const uint32_t aCh,
}
// otherwise, try to find it among local fonts
GlobalFontMatch data(aCh, aMatchStyle);
GlobalFontMatch data(aCh, *aMatchStyle);
// iterate over all font families to find a font that support the character
for (auto iter = mFontFamilies.Iter(); !iter.Done(); iter.Next()) {
@ -1721,6 +1721,7 @@ gfxPlatformFontList::ClearLangGroupPrefFonts()
}
}
mCJKPrefLangs.Clear();
mEmojiPrefFont = nullptr;
}
// Support for memory reporting

Просмотреть файл

@ -2799,7 +2799,7 @@ gfxFontGroup::GetEllipsisTextRun(int32_t aAppUnitsPerDevPixel,
gfxFont*
gfxFontGroup::FindFallbackFaceForChar(gfxFontFamily* aFamily, uint32_t aCh)
{
GlobalFontMatch data(aCh, &mStyle);
GlobalFontMatch data(aCh, mStyle);
aFamily->SearchAllFontsForChar(&data);
gfxFontEntry* fe = data.mBestMatch;
if (!fe) {

Просмотреть файл

@ -780,7 +780,9 @@ js::ArraySetLength(JSContext* cx, Handle<ArrayObject*> arr, HandleId id,
// for..in iteration over the array. Keys deleted before being reached
// during the iteration must not be visited, and suppressing them here
// would be too costly.
if (!arr->isIndexed() && !MaybeInIteration(arr, cx)) {
// This optimization is also invalid when there are sealed
// (non-configurable) elements.
if (!arr->isIndexed() && !MaybeInIteration(arr, cx) && !arr->denseElementsAreSealed()) {
if (!arr->maybeCopyElementsForWrite(cx))
return false;

Просмотреть файл

@ -0,0 +1,42 @@
// Test array.length setter on non-extensible/sealed/frozen arrays.
"use strict";
load(libdir + "asserts.js");
function testNonExtensible() {
var a = [1, 2, 3, , ,];
Object.preventExtensions(a);
for (var i = 0; i < 10; i++)
a.length = 10;
assertEq(a.length, 10);
for (var i = 0; i < 10; i++)
a.length = 0;
assertEq(a.length, 0);
assertEq(a.toString(), "");
}
testNonExtensible();
function testSealed() {
var a = [1, 2, 3, , ,];
Object.seal(a);
for (var i = 0; i < 10; i++)
a.length = 10;
assertEq(a.length, 10);
for (var i = 0; i < 10; i++)
assertThrowsInstanceOf(() => a.length = 0, TypeError);
assertEq(a.length, 3);
assertEq(a.toString(), "1,2,3");
}
testSealed();
function testFrozen() {
var a = [1, 2, 3, , ,];
Object.freeze(a);
for (var i = 0; i < 10; i++)
assertThrowsInstanceOf(() => a.length = 10, TypeError);
for (var i = 0; i < 10; i++)
assertThrowsInstanceOf(() => a.length = 0, TypeError);
assertEq(a.length, 5);
assertEq(a.toString(), "1,2,3,,");
}
testFrozen();

Просмотреть файл

@ -150,11 +150,18 @@ ref = exports.nested(baguette, 0);
assertEq(ref, baguette);
assertEq(ref.calories, baguette.calories);
if (wasmDebuggingIsSupported()) {
let g = newGlobal();
let dbg = new Debugger(g);
g.eval(`o = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary('(module (func (result anyref) (param anyref) get_local 0) (export "" 0))')));`);
}
// Make sure grow-memory isn't blocked by the lack of gc.
(function() {
assertEq(wasmEvalText(`(module
(memory 0 64)
(func (export "f") (param anyref) (result i32)
i32.const 10
grow_memory
drop
current_memory
)
)`).exports.f({}), 10);
})();
// More interesting use cases about control flow joins.

Просмотреть файл

@ -0,0 +1,35 @@
if (!wasmGcEnabled() || !wasmDebuggingIsSupported()) {
quit(0);
}
(function() {
let g = newGlobal();
let dbg = new Debugger(g);
g.eval(`o = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary('(module (func (result anyref) (param anyref) get_local 0) (export "" 0))')));`);
})();
(function() {
var g = newGlobal();
g.parent = this;
let src = `
(module
(func (export "func") (result anyref) (param $ref anyref)
get_local $ref
)
)
`;
g.eval(`
var obj = { somekey: 'somevalue' };
Debugger(parent).onEnterFrame = function(frame) {
let v = frame.environment.getVariable('var0');
assertEq(typeof v === 'object', true);
assertEq(typeof v.somekey === 'string', true);
assertEq(v.somekey === 'somevalue', true);
};
new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(\`${src}\`))).exports.func(obj);
`);
})();

Просмотреть файл

@ -131,6 +131,8 @@ CacheRegisterAllocator::useFixedValueRegister(MacroAssembler& masm, ValOperandId
Register
CacheRegisterAllocator::useRegister(MacroAssembler& masm, TypedOperandId typedId)
{
MOZ_ASSERT(!addedFailurePath_);
OperandLocation& loc = operandLocations_[typedId.id()];
switch (loc.kind()) {
case OperandLocation::PayloadReg:
@ -206,6 +208,8 @@ CacheRegisterAllocator::useRegister(MacroAssembler& masm, TypedOperandId typedId
ConstantOrRegister
CacheRegisterAllocator::useConstantOrRegister(MacroAssembler& masm, ValOperandId val)
{
MOZ_ASSERT(!addedFailurePath_);
OperandLocation& loc = operandLocations_[val.id()];
switch (loc.kind()) {
case OperandLocation::Constant:
@ -236,6 +240,8 @@ CacheRegisterAllocator::useConstantOrRegister(MacroAssembler& masm, ValOperandId
Register
CacheRegisterAllocator::defineRegister(MacroAssembler& masm, TypedOperandId typedId)
{
MOZ_ASSERT(!addedFailurePath_);
OperandLocation& loc = operandLocations_[typedId.id()];
MOZ_ASSERT(loc.kind() == OperandLocation::Uninitialized);
@ -247,6 +253,8 @@ CacheRegisterAllocator::defineRegister(MacroAssembler& masm, TypedOperandId type
ValueOperand
CacheRegisterAllocator::defineValueRegister(MacroAssembler& masm, ValOperandId val)
{
MOZ_ASSERT(!addedFailurePath_);
OperandLocation& loc = operandLocations_[val.id()];
MOZ_ASSERT(loc.kind() == OperandLocation::Uninitialized);
@ -309,6 +317,8 @@ CacheRegisterAllocator::discardStack(MacroAssembler& masm)
Register
CacheRegisterAllocator::allocateRegister(MacroAssembler& masm)
{
MOZ_ASSERT(!addedFailurePath_);
if (availableRegs_.empty())
freeDeadOperandLocations(masm);
@ -359,6 +369,8 @@ CacheRegisterAllocator::allocateRegister(MacroAssembler& masm)
void
CacheRegisterAllocator::allocateFixedRegister(MacroAssembler& masm, Register reg)
{
MOZ_ASSERT(!addedFailurePath_);
// Fixed registers should be allocated first, to ensure they're
// still available.
MOZ_ASSERT(!currentOpRegs_.has(reg), "Register is in use");
@ -479,6 +491,10 @@ CacheRegisterAllocator::fixupAliasedInputs(MacroAssembler& masm)
}
}
}
#ifdef DEBUG
assertValidState();
#endif
}
GeneralRegisterSet
@ -668,6 +684,32 @@ CacheRegisterAllocator::popValue(MacroAssembler& masm, OperandLocation* loc, Val
loc->setValueReg(dest);
}
#ifdef DEBUG
void
CacheRegisterAllocator::assertValidState() const
{
// Assert different operands don't have aliasing storage. We depend on this
// when spilling registers, for instance.
if (!JitOptions.fullDebugChecks)
return;
for (size_t i = 0; i < operandLocations_.length(); i++) {
const auto& loc1 = operandLocations_[i];
if (loc1.isUninitialized())
continue;
for (size_t j = 0; j < i; j++) {
const auto& loc2 = operandLocations_[j];
if (loc2.isUninitialized())
continue;
MOZ_ASSERT(loc1 != loc2);
MOZ_ASSERT(!loc1.aliasesReg(loc2));
}
}
}
#endif
bool
OperandLocation::aliasesReg(const OperandLocation& other) const
{
@ -1165,6 +1207,10 @@ FailurePath::canShareFailurePath(const FailurePath& other) const
bool
CacheIRCompiler::addFailurePath(FailurePath** failure)
{
#ifdef DEBUG
allocator.setAddedFailurePath();
#endif
FailurePath newFailure;
for (size_t i = 0; i < writer_.numInputOperands(); i++) {
if (!newFailure.appendInput(allocator.operandLocation(i)))

Просмотреть файл

@ -211,6 +211,7 @@ class OperandLocation
data_.baselineFrameSlot = slot;
}
bool isUninitialized() const { return kind_ == Uninitialized; }
bool isInRegister() const { return kind_ == PayloadReg || kind_ == ValueReg; }
bool isOnStack() const { return kind_ == PayloadStack || kind_ == ValueStack; }
@ -305,6 +306,12 @@ class MOZ_RAII CacheRegisterAllocator
// The number of bytes pushed on the native stack.
uint32_t stackPushed_;
#ifdef DEBUG
// Flag used to assert individual CacheIR instructions don't allocate
// registers after calling addFailurePath.
bool addedFailurePath_;
#endif
// The index of the CacheIR instruction we're currently emitting.
uint32_t currentInstruction_;
@ -321,6 +328,10 @@ class MOZ_RAII CacheRegisterAllocator
void popPayload(MacroAssembler& masm, OperandLocation* loc, Register dest);
void popValue(MacroAssembler& masm, OperandLocation* loc, ValueOperand dest);
#ifdef DEBUG
void assertValidState() const;
#endif
public:
friend class AutoScratchRegister;
friend class AutoScratchRegisterExcluding;
@ -328,6 +339,9 @@ class MOZ_RAII CacheRegisterAllocator
explicit CacheRegisterAllocator(const CacheIRWriter& writer)
: allocatableRegs_(GeneralRegisterSet::All()),
stackPushed_(0),
#ifdef DEBUG
addedFailurePath_(false),
#endif
currentInstruction_(0),
writer_(writer)
{}
@ -383,10 +397,21 @@ class MOZ_RAII CacheRegisterAllocator
}
void nextOp() {
#ifdef DEBUG
assertValidState();
addedFailurePath_ = false;
#endif
currentOpRegs_.clear();
currentInstruction_++;
}
#ifdef DEBUG
void setAddedFailurePath() {
MOZ_ASSERT(!addedFailurePath_, "multiple failure paths for instruction");
addedFailurePath_ = true;
}
#endif
bool isDeadAfterInstruction(OperandId opId) const {
return writer_.operandIsDead(opId.id(), currentInstruction_ + 1);
}
@ -536,7 +561,8 @@ class FailurePath
* Wrap an offset so that a call can decide to embed a constant
* or load from the stub data.
*/
class StubFieldOffset {
class StubFieldOffset
{
private:
uint32_t offset_;
StubField::Type type_;
@ -544,7 +570,7 @@ class StubFieldOffset {
StubFieldOffset(uint32_t offset, StubField::Type type)
: offset_(offset),
type_(type)
{ }
{ }
uint32_t getOffset() { return offset_; }
StubField::Type getStubFieldType() { return type_; }

Просмотреть файл

@ -647,6 +647,9 @@ DebugFrame::getLocal(uint32_t localIndex, MutableHandleValue vp)
case jit::MIRType::Double:
vp.set(NumberValue(JS::CanonicalizeNaN(*static_cast<double*>(dataPtr))));
break;
case jit::MIRType::Pointer:
vp.set(ObjectOrNullValue(*(JSObject**)dataPtr));
break;
default:
MOZ_CRASH("local type");
}
@ -675,6 +678,9 @@ DebugFrame::updateReturnJSValue()
case ExprType::F64:
cachedReturnJSValue_.setDouble(JS::CanonicalizeNaN(resultF64_));
break;
case ExprType::AnyRef:
cachedReturnJSValue_ = ObjectOrNullValue(*(JSObject**)&resultRef_);
break;
default:
MOZ_CRASH("result type");
}

Просмотреть файл

@ -1961,10 +1961,11 @@ class DebugFrame
// the return value of a frame being debugged.
union
{
int32_t resultI32_;
int64_t resultI64_;
float resultF32_;
double resultF64_;
int32_t resultI32_;
int64_t resultI64_;
intptr_t resultRef_;
float resultF32_;
double resultF64_;
};
// The returnValue() method returns a HandleValue pointing to this field.

Просмотреть файл

@ -49,10 +49,10 @@ interface nsIXPConnectWrappedNative;
#define XPC_SCRIPTABLE_USE_JSSTUB_FOR_DELPROPERTY (1 << 11)
// (1 << 12) is unused
#define XPC_SCRIPTABLE_DONT_ENUM_QUERY_INTERFACE (1 << 13)
#define XPC_SCRIPTABLE_DONT_ASK_INSTANCE_FOR_SCRIPTABLE (1 << 14)
#define XPC_SCRIPTABLE_CLASSINFO_INTERFACES_ONLY (1 << 15)
// (1 << 14) is unused
// (1 << 15) is unused
#define XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE (1 << 16)
#define XPC_SCRIPTABLE_ALLOW_PROP_MODS_TO_PROTOTYPE (1 << 17)
// (1 << 17) is unused
#define XPC_SCRIPTABLE_IS_GLOBAL_OBJECT (1 << 18)
#define XPC_SCRIPTABLE_DONT_REFLECT_INTERFACE_NAMES (1 << 19)
%}
@ -100,8 +100,6 @@ interface nsIXPCScriptable : nsISupports
in JSContextPtr cx, in JSObjectPtr obj,
in jsval val, out boolean bp);
void postCreatePrototype(in JSContextPtr cx, in JSObjectPtr proto);
%{ C++
#define GET_IT(f_, c_) \
bool f_() { \
@ -119,46 +117,10 @@ interface nsIXPCScriptable : nsISupports
GET_IT(UseJSStubForAddProperty, USE_JSSTUB_FOR_ADDPROPERTY)
GET_IT(UseJSStubForDelProperty, USE_JSSTUB_FOR_DELPROPERTY)
GET_IT(DontEnumQueryInterface, DONT_ENUM_QUERY_INTERFACE)
GET_IT(DontAskInstanceForScriptable, DONT_ASK_INSTANCE_FOR_SCRIPTABLE)
GET_IT(ClassInfoInterfacesOnly, CLASSINFO_INTERFACES_ONLY)
GET_IT(AllowPropModsDuringResolve, ALLOW_PROP_MODS_DURING_RESOLVE)
GET_IT(AllowPropModsToPrototype, ALLOW_PROP_MODS_TO_PROTOTYPE)
GET_IT(IsGlobalObject, IS_GLOBAL_OBJECT)
GET_IT(DontReflectInterfaceNames, DONT_REFLECT_INTERFACE_NAMES)
#undef GET_IT
%}
};
%{ C++
#include "nsAutoPtr.h"
#define NS_XPCCLASSINFO_IID \
{ 0x43b67f01, 0xd4ce, 0x4b82, \
{ 0xb3, 0xf8, 0xeb, 0xf2, 0x13, 0x60, 0xfb, 0x7e } }
class NS_NO_VTABLE nsXPCClassInfo : public nsIClassInfo,
public nsIXPCScriptable
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_XPCCLASSINFO_IID)
NS_IMETHOD_(MozExternalRefCountType) AddRef() override = 0;
NS_IMETHOD_(MozExternalRefCountType) Release() override = 0;
virtual void PreserveWrapper(nsISupports *aNative) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsXPCClassInfo, NS_XPCCLASSINFO_IID)
inline
nsresult
CallQueryInterface(nsISupports* aSourcePtr,
RefPtrGetterAddRefs<nsXPCClassInfo> aDestPtr)
{
return CallQueryInterface(aSourcePtr,
static_cast<nsXPCClassInfo**>(aDestPtr));
}
%}

Просмотреть файл

@ -99,9 +99,6 @@ NS_IMETHODIMP XPC_MAP_CLASSNAME::HasInstance(nsIXPConnectWrappedNative* wrapper,
{NS_ERROR("never called"); return NS_ERROR_NOT_IMPLEMENTED;}
#endif
NS_IMETHODIMP XPC_MAP_CLASSNAME::PostCreatePrototype(JSContext* cx, JSObject* proto)
{return NS_OK;}
/**************************************************************/
#undef XPC_MAP_CLASSNAME

Просмотреть файл

@ -2920,7 +2920,7 @@ XPCJSRuntime::DescribeCustomObjects(JSObject* obj, const js::Class* clasp,
char (&name)[72]) const
{
if (!IS_PROTO_CLASS(clasp)) {
if (clasp != &XPC_WN_Proto_JSClass) {
return false;
}

Просмотреть файл

@ -156,7 +156,7 @@ XPCWrappedNative::WrapNewGlobal(xpcObjectHelper& nativeHelper,
XPCWrappedNative** wrappedGlobal)
{
AutoJSContext cx;
nsISupports* identity = nativeHelper.GetCanonical();
nsCOMPtr<nsISupports> identity = do_QueryInterface(nativeHelper.Object());
// The object should specify that it's meant to be global.
MOZ_ASSERT(nativeHelper.GetScriptableFlags() & XPC_SCRIPTABLE_IS_GLOBAL_OBJECT);
@ -198,8 +198,7 @@ XPCWrappedNative::WrapNewGlobal(xpcObjectHelper& nativeHelper,
XPCWrappedNativeProto* proto =
XPCWrappedNativeProto::GetNewOrUsed(scope,
nativeHelper.GetClassInfo(),
scrProto,
/* callPostCreatePrototype = */ false);
scrProto);
if (!proto)
return NS_ERROR_FAILURE;
@ -212,8 +211,7 @@ XPCWrappedNative::WrapNewGlobal(xpcObjectHelper& nativeHelper,
// Construct the wrapper, which takes over the strong reference to the
// native object.
RefPtr<XPCWrappedNative> wrapper =
new XPCWrappedNative(nativeHelper.forgetCanonical(), proto);
RefPtr<XPCWrappedNative> wrapper = new XPCWrappedNative(identity.forget(), proto);
//
// We don't call ::Init() on this wrapper, because our setup requirements
@ -284,7 +282,7 @@ XPCWrappedNative::GetNewOrUsed(xpcObjectHelper& helper,
MOZ_ASSERT(!Scope->GetRuntime()->GCIsRunning(),
"XPCWrappedNative::GetNewOrUsed called during GC");
nsISupports* identity = helper.GetCanonical();
nsCOMPtr<nsISupports> identity = do_QueryInterface(helper.Object());
if (!identity) {
NS_ERROR("This XPCOM object fails in QueryInterface to nsISupports!");
@ -406,7 +404,7 @@ XPCWrappedNative::GetNewOrUsed(xpcObjectHelper& helper,
if (!proto)
return NS_ERROR_FAILURE;
wrapper = new XPCWrappedNative(helper.forgetCanonical(), proto);
wrapper = new XPCWrappedNative(identity.forget(), proto);
} else {
RefPtr<XPCNativeInterface> iface = Interface;
if (!iface)
@ -419,8 +417,7 @@ XPCWrappedNative::GetNewOrUsed(xpcObjectHelper& helper,
if (!set)
return NS_ERROR_FAILURE;
wrapper = new XPCWrappedNative(helper.forgetCanonical(), Scope,
set.forget());
wrapper = new XPCWrappedNative(identity.forget(), Scope, set.forget());
}
MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(parent),
@ -550,14 +547,6 @@ XPCWrappedNative::GatherProtoScriptable(nsIClassInfo* classInfo)
{
MOZ_ASSERT(classInfo, "bad param");
nsXPCClassInfo* classInfoHelper = nullptr;
CallQueryInterface(classInfo, &classInfoHelper);
if (classInfoHelper) {
nsCOMPtr<nsIXPCScriptable> helper =
dont_AddRef(static_cast<nsIXPCScriptable*>(classInfoHelper));
return helper;
}
nsCOMPtr<nsIXPCScriptable> helper;
nsresult rv = classInfo->GetScriptableHelper(getter_AddRefs(helper));
if (NS_SUCCEEDED(rv) && helper) {
@ -583,13 +572,6 @@ XPCWrappedNative::GatherScriptable(nsISupports* aObj,
// Get the class scriptable helper (if present)
if (aClassInfo) {
scrProto = GatherProtoScriptable(aClassInfo);
if (scrProto && scrProto->DontAskInstanceForScriptable()) {
scrWrapper = scrProto;
scrProto.forget(aScrProto);
scrWrapper.forget(aScrWrapper);
return;
}
}
// Do the same for the wrapper specific scriptable
@ -608,25 +590,10 @@ XPCWrappedNative::GatherScriptable(nsISupports* aObj,
MOZ_ASSERT_IF(scrWrapper->DontEnumQueryInterface() && scrProto,
scrProto->DontEnumQueryInterface());
// Can't set DONT_ASK_INSTANCE_FOR_SCRIPTABLE on an instance scriptable
// without also setting it on the class scriptable.
MOZ_ASSERT_IF(scrWrapper->DontAskInstanceForScriptable(),
scrProto && scrProto->DontAskInstanceForScriptable());
// Can't set CLASSINFO_INTERFACES_ONLY on an instance scriptable
// without also setting it on the class scriptable (if present).
MOZ_ASSERT_IF(scrWrapper->ClassInfoInterfacesOnly() && scrProto,
scrProto->ClassInfoInterfacesOnly());
// Can't set ALLOW_PROP_MODS_DURING_RESOLVE on an instance scriptable
// without also setting it on the class scriptable (if present).
MOZ_ASSERT_IF(scrWrapper->AllowPropModsDuringResolve() && scrProto,
scrProto->AllowPropModsDuringResolve());
// Can't set ALLOW_PROP_MODS_TO_PROTOTYPE on an instance scriptable
// without also setting it on the class scriptable (if present).
MOZ_ASSERT_IF(scrWrapper->AllowPropModsToPrototype() && scrProto,
scrProto->AllowPropModsToPrototype());
} else {
scrWrapper = scrProto;
}
@ -993,15 +960,6 @@ XPCWrappedNative::InitTearOff(XPCWrappedNativeTearOff* aTearOff,
// canonical nsISupports for this object.
RefPtr<nsISupports> qiResult;
// If the scriptable helper forbids us from reflecting additional
// interfaces, then don't even try the QI, just fail.
if (mScriptable &&
mScriptable->ClassInfoInterfacesOnly() &&
!mSet->HasInterface(aInterface) &&
!mSet->HasInterfaceWithAncestor(aInterface)) {
return NS_ERROR_NO_INTERFACE;
}
// We are about to call out to other code.
// So protect our intended tearoff.

Просмотреть файл

@ -252,18 +252,6 @@ DefinePropertyIfFound(XPCCallContext& ccx,
if (!found) {
if (reflectToStringAndToSource) {
JSNative call;
uint32_t flags = 0;
if (scr) {
nsCOMPtr<nsIClassInfo> classInfo = do_QueryInterface(scr);
if (classInfo) {
nsresult rv = classInfo->GetFlags(&flags);
if (NS_FAILED(rv))
return Throw(rv, ccx);
}
}
if (id == xpccx->GetStringID(XPCJSContext::IDX_TO_STRING)) {
call = XPC_WN_Shared_ToString;
name = xpccx->GetStringName(XPCJSContext::IDX_TO_STRING);
@ -952,10 +940,9 @@ XPC_WN_GetterSetter(JSContext* cx, unsigned argc, Value* vp)
/***************************************************************************/
static bool
XPC_WN_Shared_Proto_Enumerate(JSContext* cx, HandleObject obj)
XPC_WN_Proto_Enumerate(JSContext* cx, HandleObject obj)
{
MOZ_ASSERT(js::GetObjectClass(obj) == &XPC_WN_ModsAllowed_Proto_JSClass ||
js::GetObjectClass(obj) == &XPC_WN_NoMods_Proto_JSClass,
MOZ_ASSERT(js::GetObjectClass(obj) == &XPC_WN_Proto_JSClass,
"bad proto");
XPCWrappedNativeProto* self =
(XPCWrappedNativeProto*) xpc_GetJSPrivate(obj);
@ -986,7 +973,7 @@ XPC_WN_Shared_Proto_Enumerate(JSContext* cx, HandleObject obj)
}
static void
XPC_WN_Shared_Proto_Finalize(js::FreeOp* fop, JSObject* obj)
XPC_WN_Proto_Finalize(js::FreeOp* fop, JSObject* obj)
{
// This can be null if xpc shutdown has already happened
XPCWrappedNativeProto* p = (XPCWrappedNativeProto*) xpc_GetJSPrivate(obj);
@ -995,7 +982,7 @@ XPC_WN_Shared_Proto_Finalize(js::FreeOp* fop, JSObject* obj)
}
static size_t
XPC_WN_Shared_Proto_ObjectMoved(JSObject* obj, JSObject* old)
XPC_WN_Proto_ObjectMoved(JSObject* obj, JSObject* old)
{
// This can be null if xpc shutdown has already happened
XPCWrappedNativeProto* p = (XPCWrappedNativeProto*) xpc_GetJSPrivate(obj);
@ -1007,7 +994,7 @@ XPC_WN_Shared_Proto_ObjectMoved(JSObject* obj, JSObject* old)
}
static void
XPC_WN_Shared_Proto_Trace(JSTracer* trc, JSObject* obj)
XPC_WN_Proto_Trace(JSTracer* trc, JSObject* obj)
{
// This can be null if xpc shutdown has already happened
XPCWrappedNativeProto* p =
@ -1018,64 +1005,11 @@ XPC_WN_Shared_Proto_Trace(JSTracer* trc, JSObject* obj)
/*****************************************************/
static bool
XPC_WN_ModsAllowed_Proto_Resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvep)
{
MOZ_ASSERT(js::GetObjectClass(obj) == &XPC_WN_ModsAllowed_Proto_JSClass,
"bad proto");
XPCWrappedNativeProto* self =
(XPCWrappedNativeProto*) xpc_GetJSPrivate(obj);
if (!self)
return false;
XPCCallContext ccx(cx);
if (!ccx.IsValid())
return false;
nsCOMPtr<nsIXPCScriptable> scr = self->GetScriptable();
return DefinePropertyIfFound(ccx, obj, id,
self->GetSet(), nullptr, nullptr,
self->GetScope(),
true, nullptr, nullptr, scr,
JSPROP_ENUMERATE, resolvep);
}
static const js::ClassOps XPC_WN_ModsAllowed_Proto_JSClassOps = {
nullptr, // addProperty
nullptr, // delProperty
XPC_WN_Shared_Proto_Enumerate, // enumerate
nullptr, // newEnumerate
XPC_WN_ModsAllowed_Proto_Resolve, // resolve
nullptr, // mayResolve
XPC_WN_Shared_Proto_Finalize, // finalize
nullptr, // call
nullptr, // construct
nullptr, // hasInstance
XPC_WN_Shared_Proto_Trace, // trace
};
static const js::ClassExtension XPC_WN_Shared_Proto_ClassExtension = {
nullptr, /* weakmapKeyDelegateOp */
XPC_WN_Shared_Proto_ObjectMoved
};
const js::Class XPC_WN_ModsAllowed_Proto_JSClass = {
"XPC_WN_ModsAllowed_Proto_JSClass",
XPC_WRAPPER_FLAGS,
&XPC_WN_ModsAllowed_Proto_JSClassOps,
JS_NULL_CLASS_SPEC,
&XPC_WN_Shared_Proto_ClassExtension,
JS_NULL_OBJECT_OPS
};
/***************************************************************************/
static bool
XPC_WN_OnlyIWrite_Proto_AddPropertyStub(JSContext* cx, HandleObject obj, HandleId id,
HandleValue v)
{
MOZ_ASSERT(js::GetObjectClass(obj) == &XPC_WN_NoMods_Proto_JSClass,
MOZ_ASSERT(js::GetObjectClass(obj) == &XPC_WN_Proto_JSClass,
"bad proto");
XPCWrappedNativeProto* self =
@ -1095,9 +1029,9 @@ XPC_WN_OnlyIWrite_Proto_AddPropertyStub(JSContext* cx, HandleObject obj, HandleI
}
static bool
XPC_WN_NoMods_Proto_Resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp)
XPC_WN_Proto_Resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp)
{
MOZ_ASSERT(js::GetObjectClass(obj) == &XPC_WN_NoMods_Proto_JSClass,
MOZ_ASSERT(js::GetObjectClass(obj) == &XPC_WN_Proto_JSClass,
"bad proto");
XPCWrappedNativeProto* self =
@ -1120,26 +1054,31 @@ XPC_WN_NoMods_Proto_Resolve(JSContext* cx, HandleObject obj, HandleId id, bool*
JSPROP_ENUMERATE, resolvedp);
}
static const js::ClassOps XPC_WN_NoMods_Proto_JSClassOps = {
static const js::ClassOps XPC_WN_Proto_JSClassOps = {
XPC_WN_OnlyIWrite_Proto_AddPropertyStub, // addProperty
XPC_WN_CannotDeletePropertyStub, // delProperty
XPC_WN_Shared_Proto_Enumerate, // enumerate
XPC_WN_Proto_Enumerate, // enumerate
nullptr, // newEnumerate
XPC_WN_NoMods_Proto_Resolve, // resolve
XPC_WN_Proto_Resolve, // resolve
nullptr, // mayResolve
XPC_WN_Shared_Proto_Finalize, // finalize
XPC_WN_Proto_Finalize, // finalize
nullptr, // call
nullptr, // construct
nullptr, // hasInstance
XPC_WN_Shared_Proto_Trace, // trace
XPC_WN_Proto_Trace, // trace
};
const js::Class XPC_WN_NoMods_Proto_JSClass = {
"XPC_WN_NoMods_Proto_JSClass",
static const js::ClassExtension XPC_WN_Proto_ClassExtension = {
nullptr, /* weakmapKeyDelegateOp */
XPC_WN_Proto_ObjectMoved
};
const js::Class XPC_WN_Proto_JSClass = {
"XPC_WN_Proto_JSClass",
XPC_WRAPPER_FLAGS,
&XPC_WN_NoMods_Proto_JSClassOps,
&XPC_WN_Proto_JSClassOps,
JS_NULL_CLASS_SPEC,
&XPC_WN_Shared_Proto_ClassExtension,
&XPC_WN_Proto_ClassExtension,
JS_NULL_OBJECT_OPS
};

Просмотреть файл

@ -50,54 +50,24 @@ XPCWrappedNativeProto::~XPCWrappedNativeProto()
}
bool
XPCWrappedNativeProto::Init(nsIXPCScriptable* scriptable,
bool callPostCreatePrototype)
XPCWrappedNativeProto::Init(nsIXPCScriptable* scriptable)
{
AutoJSContext cx;
mScriptable = scriptable;
const js::Class* jsclazz =
(mScriptable && mScriptable->AllowPropModsToPrototype())
? &XPC_WN_ModsAllowed_Proto_JSClass
: &XPC_WN_NoMods_Proto_JSClass;
JS::RootedObject global(cx, mScope->GetGlobalJSObject());
JS::RootedObject proto(cx, JS_GetObjectPrototype(cx, global));
mJSProtoObject = JS_NewObjectWithUniqueType(cx, js::Jsvalify(jsclazz),
mJSProtoObject = JS_NewObjectWithUniqueType(cx, js::Jsvalify(&XPC_WN_Proto_JSClass),
proto);
bool success = !!mJSProtoObject;
if (success) {
JS_SetPrivate(mJSProtoObject, this);
if (callPostCreatePrototype)
success = CallPostCreatePrototype();
}
return success;
}
bool
XPCWrappedNativeProto::CallPostCreatePrototype()
{
AutoJSContext cx;
// Nothing to do if we don't have a scriptable callback.
if (!mScriptable)
return true;
// Call the helper. This can handle being called if it's not implemented,
// so we don't have to check any sort of "want" here. See xpc_map_end.h.
nsresult rv = mScriptable->PostCreatePrototype(cx, mJSProtoObject);
if (NS_FAILED(rv)) {
JS_SetPrivate(mJSProtoObject, nullptr);
mJSProtoObject = nullptr;
XPCThrower::Throw(rv, cx);
return false;
}
return true;
}
void
XPCWrappedNativeProto::JSProtoObjectFinalized(js::FreeOp* fop, JSObject* obj)
{
@ -138,8 +108,7 @@ XPCWrappedNativeProto::SystemIsBeingShutDown()
XPCWrappedNativeProto*
XPCWrappedNativeProto::GetNewOrUsed(XPCWrappedNativeScope* scope,
nsIClassInfo* classInfo,
nsIXPCScriptable* scriptable,
bool callPostCreatePrototype)
nsIXPCScriptable* scriptable)
{
AutoJSContext cx;
MOZ_ASSERT(scope, "bad param");
@ -159,7 +128,7 @@ XPCWrappedNativeProto::GetNewOrUsed(XPCWrappedNativeScope* scope,
proto = new XPCWrappedNativeProto(scope, classInfo, set.forget());
if (!proto || !proto->Init(scriptable, callPostCreatePrototype)) {
if (!proto || !proto->Init(scriptable)) {
delete proto.get();
return nullptr;
}

Просмотреть файл

@ -6,7 +6,6 @@
EXPORTS += [
'BackstagePass.h',
'qsObjectHelper.h',
'XPCJSMemoryReporter.h',
'xpcObjectHelper.h',
'xpcpublic.h',

Просмотреть файл

@ -1,53 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=8 sts=4 et sw=4 tw=99: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef qsObjectHelper_h
#define qsObjectHelper_h
#include "xpcObjectHelper.h"
#include "nsCOMPtr.h"
#include "nsWrapperCache.h"
#include "mozilla/TypeTraits.h"
class qsObjectHelper : public xpcObjectHelper
{
public:
template <class T>
inline
qsObjectHelper(T* aObject, nsWrapperCache* aCache)
: xpcObjectHelper(ToSupports(aObject), ToCanonicalSupports(aObject),
aCache)
{}
template <class T>
inline
qsObjectHelper(nsCOMPtr<T>& aObject, nsWrapperCache* aCache)
: xpcObjectHelper(ToSupports(aObject.get()),
ToCanonicalSupports(aObject.get()), aCache)
{
if (mCanonical) {
// Transfer the strong reference.
mCanonicalStrong = dont_AddRef(mCanonical);
aObject.forget();
}
}
template <class T>
inline
qsObjectHelper(RefPtr<T>& aObject, nsWrapperCache* aCache)
: xpcObjectHelper(ToSupports(aObject.get()),
ToCanonicalSupports(aObject.get()), aCache)
{
if (mCanonical) {
// Transfer the strong reference.
mCanonicalStrong = dont_AddRef(mCanonical);
aObject.forget();
}
}
};
#endif

Просмотреть файл

@ -26,15 +26,11 @@ class xpcObjectHelper
{
public:
explicit xpcObjectHelper(nsISupports* aObject, nsWrapperCache* aCache = nullptr)
: mCanonical(nullptr)
, mObject(aObject)
: mObject(aObject)
, mCache(aCache)
{
if (!mCache) {
if (aObject)
CallQueryInterface(aObject, &mCache);
else
mCache = nullptr;
if (!mCache && aObject) {
CallQueryInterface(aObject, &mCache);
}
}
@ -43,57 +39,17 @@ public:
return mObject;
}
nsISupports* GetCanonical()
{
if (!mCanonical) {
mCanonicalStrong = do_QueryInterface(mObject);
mCanonical = mCanonicalStrong;
}
return mCanonical;
}
already_AddRefed<nsISupports> forgetCanonical()
{
MOZ_ASSERT(mCanonical, "Huh, no canonical to forget?");
if (!mCanonicalStrong)
mCanonicalStrong = mCanonical;
mCanonical = nullptr;
return mCanonicalStrong.forget();
}
nsIClassInfo* GetClassInfo()
{
if (mXPCClassInfo)
return mXPCClassInfo;
if (!mClassInfo)
mClassInfo = do_QueryInterface(mObject);
return mClassInfo;
}
nsXPCClassInfo* GetXPCClassInfo()
{
if (!mXPCClassInfo) {
CallQueryInterface(mObject, getter_AddRefs(mXPCClassInfo));
}
return mXPCClassInfo;
}
already_AddRefed<nsXPCClassInfo> forgetXPCClassInfo()
{
GetXPCClassInfo();
return mXPCClassInfo.forget();
}
// We assert that we can reach an nsIXPCScriptable somehow.
uint32_t GetScriptableFlags()
{
// Try getting an nsXPCClassInfo - this handles DOM scriptable helpers.
nsCOMPtr<nsIXPCScriptable> sinfo = GetXPCClassInfo();
// If that didn't work, try just QI-ing. This handles BackstagePass.
if (!sinfo)
sinfo = do_QueryInterface(GetCanonical());
nsCOMPtr<nsIXPCScriptable> sinfo = do_QueryInterface(mObject);
// We should have something by now.
MOZ_ASSERT(sinfo);
@ -107,22 +63,6 @@ public:
return mCache;
}
protected:
xpcObjectHelper(nsISupports* aObject, nsISupports* aCanonical,
nsWrapperCache* aCache)
: mCanonical(aCanonical)
, mObject(aObject)
, mCache(aCache)
{
if (!mCache && aObject)
CallQueryInterface(aObject, &mCache);
}
nsCOMPtr<nsISupports> mCanonicalStrong;
nsISupports* MOZ_UNSAFE_REF("xpcObjectHelper has been specifically optimized "
"to avoid unnecessary AddRefs and Releases. "
"(see bug 565742)") mCanonical;
private:
xpcObjectHelper(xpcObjectHelper& aOther) = delete;
@ -131,7 +71,6 @@ private:
"(see bug 565742)") mObject;
nsWrapperCache* mCache;
nsCOMPtr<nsIClassInfo> mClassInfo;
RefPtr<nsXPCClassInfo> mXPCClassInfo;
};
#endif

Просмотреть файл

@ -784,8 +784,7 @@ private:
// visibility from more than one .cpp file.
extern const js::Class XPC_WN_NoHelper_JSClass;
extern const js::Class XPC_WN_NoMods_Proto_JSClass;
extern const js::Class XPC_WN_ModsAllowed_Proto_JSClass;
extern const js::Class XPC_WN_Proto_JSClass;
extern const js::Class XPC_WN_Tearoff_JSClass;
#define XPC_WN_TEAROFF_RESERVED_SLOTS 1
#define XPC_WN_TEAROFF_FLAT_OBJECT_SLOT 0
@ -797,15 +796,6 @@ XPC_WN_CallMethod(JSContext* cx, unsigned argc, JS::Value* vp);
extern bool
XPC_WN_GetterSetter(JSContext* cx, unsigned argc, JS::Value* vp);
// Maybe this macro should check for class->enumerate ==
// XPC_WN_Shared_Proto_Enumerate or something rather than checking for
// 4 classes?
static inline bool IS_PROTO_CLASS(const js::Class* clazz)
{
return clazz == &XPC_WN_NoMods_Proto_JSClass ||
clazz == &XPC_WN_ModsAllowed_Proto_JSClass;
}
/***************************************************************************/
// XPCWrappedNativeScope is one-to-one with a JS global object.
@ -1277,8 +1267,7 @@ public:
static XPCWrappedNativeProto*
GetNewOrUsed(XPCWrappedNativeScope* scope,
nsIClassInfo* classInfo,
nsIXPCScriptable* scriptable,
bool callPostCreatePrototype = true);
nsIXPCScriptable* scriptable);
XPCWrappedNativeScope*
GetScope() const {return mScope;}
@ -1301,7 +1290,6 @@ public:
nsIXPCScriptable*
GetScriptable() const { return mScriptable; }
bool CallPostCreatePrototype();
void JSProtoObjectFinalized(js::FreeOp* fop, JSObject* obj);
void JSProtoObjectMoved(JSObject* obj, const JSObject* old);
@ -1345,7 +1333,7 @@ protected:
nsIClassInfo* ClassInfo,
already_AddRefed<XPCNativeSet>&& Set);
bool Init(nsIXPCScriptable* scriptable, bool callPostCreatePrototype);
bool Init(nsIXPCScriptable* scriptable);
private:
#ifdef DEBUG

Просмотреть файл

@ -1451,11 +1451,6 @@ IsWindow(JSContext* cx, JSObject* wrapper)
void
XPCWrappedNativeXrayTraits::preserveWrapper(JSObject* target)
{
XPCWrappedNative* wn = XPCWrappedNative::Get(target);
RefPtr<nsXPCClassInfo> ci;
CallQueryInterface(wn->Native(), getter_AddRefs(ci));
if (ci)
ci->PreserveWrapper(wn->Native());
}
static bool

Просмотреть файл

@ -259,14 +259,6 @@ nsFrameManager::RestoreFrameState(nsIFrame* aFrame,
}
}
void
nsFrameManager::DestroyAnonymousContent(already_AddRefed<nsIContent> aContent)
{
if (nsCOMPtr<nsIContent> content = aContent) {
content->UnbindFromTree();
}
}
void
nsFrameManager::AddSizeOfIncludingThis(nsWindowSizes& aSizes) const
{

Просмотреть файл

@ -93,8 +93,6 @@ public:
void RestoreFrameStateFor(nsIFrame* aFrame, nsILayoutHistoryState* aState);
void DestroyAnonymousContent(already_AddRefed<nsIContent> aContent);
void AddSizeOfIncludingThis(nsWindowSizes& aSizes) const;
protected:

Просмотреть файл

@ -451,6 +451,7 @@ nsTextControlFrame::CreateRootNode()
MOZ_ASSERT(!mRootNode);
mRootNode = CreateEmptyDiv(*this);
mRootNode->SetIsNativeAnonymousRoot();
mMutationObserver = new nsAnonDivObserver(*this);
mRootNode->AddMutationObserver(mMutationObserver);

Просмотреть файл

@ -246,8 +246,10 @@ nsReflowStatus::UpdateTruncated(const ReflowInput& aReflowInput,
nsIFrame::DestroyAnonymousContent(nsPresContext* aPresContext,
already_AddRefed<nsIContent>&& aContent)
{
aPresContext->PresShell()->FrameConstructor()
->DestroyAnonymousContent(Move(aContent));
if (nsCOMPtr<nsIContent> content = aContent) {
aPresContext->EventStateManager()->NativeAnonymousContentRemoved(content);
content->UnbindFromTree();
}
}
// Formerly the nsIFrameDebug interface

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше