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 ifndef MOZ_PROFILE_USE
# Automation builds should always have a new buildid, but for the sake of not # 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 # re-linking libxul on every incremental build we do not enforce this for
# developer builds. # developer builds. Tests always need a new buildid as well.
ifneq (,$(MOZ_AUTOMATION)$(MOZ_BUILD_DATE)) ifneq (,$(MOZ_AUTOMATION)$(MOZ_BUILD_DATE)$(TEST_MOZBUILD))
buildid.h source-repo.h: FORCE buildid.h source-repo.h: FORCE
endif endif
endif endif
@ -109,7 +109,7 @@ default:: $(BUILD_BACKEND_FILES)
endif endif
install_manifests := \ install_manifests := \
$(addprefix dist/,branding idl include public private xpi-stage) \ $(addprefix dist/,branding include public private xpi-stage) \
_tests \ _tests \
$(NULL) $(NULL)
# Skip the dist/bin install manifest when using the hybrid # 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 # If we're using the hybrid FasterMake/RecursiveMake backend, we want
# to recurse in the faster/ directory in parallel of install manifests. # 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))) ifneq (,$(filter FasterMake+RecursiveMake,$(BUILD_BACKENDS)))
install-manifests: faster install-manifests: faster
.PHONY: faster .PHONY: faster
faster: install-dist/idl faster:
$(MAKE) -C faster FASTER_RECURSIVE_MAKE=1 $(MAKE) -C faster FASTER_RECURSIVE_MAKE=1
endif endif

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

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

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

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

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

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

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

@ -1054,6 +1054,20 @@ nsAccessibilityService::CreateAccessible(nsINode* aNode,
// Check frame and its visibility. Note, hidden frame allows visible // Check frame and its visibility. Note, hidden frame allows visible
// elements in subtree. // elements in subtree.
if (!frame || !frame->StyleVisibility()->IsVisible()) { 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) if (aIsSubtreeHidden && !frame)
*aIsSubtreeHidden = true; *aIsSubtreeHidden = true;

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

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

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

@ -435,7 +435,7 @@ public:
/** /**
* Return true if accessible has children; * 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. * 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 * Return the current item of the widget, i.e. an item that has or will have
* keyboard focus when widget gets active. * keyboard focus when widget gets active.
*/ */
virtual Accessible* CurrentItem(); virtual Accessible* CurrentItem() const;
/** /**
* Set the current item of the widget. * 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. * Return container widget this accessible belongs to.

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

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

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

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

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

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

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

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

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

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

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

@ -39,7 +39,7 @@
// __h__e__l__l__o__ __!__ __s__e__e__ __!__ // __h__e__l__l__o__ __!__ __s__e__e__ __!__
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 // 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 // characterCount
@ -123,6 +123,10 @@
<div id="hypertext">hello <a>friend</a> see <img src="about:blank"></div> <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="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"> <ol id="list">
<li id="listitem">foo</li> <li id="listitem">foo</li>
<li id="listitemnone">bar</li> <li id="listitemnone">bar</li>

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

@ -25,6 +25,7 @@ skip-if = true # Bug 561508
[test_combobox.xul] [test_combobox.xul]
[test_cssflexbox.html] [test_cssflexbox.html]
[test_cssoverflow.html] [test_cssoverflow.html]
[test_display_contents.html]
[test_dochierarchy.html] [test_dochierarchy.html]
[test_dockids.html] [test_dockids.html]
[test_filectrl.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* Accessible*
XULMenubarAccessible::CurrentItem() XULMenubarAccessible::CurrentItem() const
{ {
nsMenuBarFrame* menuBarFrame = do_QueryFrame(GetFrame()); nsMenuBarFrame* menuBarFrame = do_QueryFrame(GetFrame());
if (menuBarFrame) { if (menuBarFrame) {
@ -587,7 +587,7 @@ XULMenubarAccessible::CurrentItem()
} }
void void
XULMenubarAccessible::SetCurrentItem(Accessible* aItem) XULMenubarAccessible::SetCurrentItem(const Accessible* aItem)
{ {
NS_ERROR("XULMenubarAccessible::SetCurrentItem not implemented"); NS_ERROR("XULMenubarAccessible::SetCurrentItem not implemented");
} }

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

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

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

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

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

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

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

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

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

@ -64,8 +64,8 @@ public:
virtual bool IsWidget() const override; virtual bool IsWidget() const override;
virtual bool IsActiveWidget() const override; virtual bool IsActiveWidget() const override;
virtual bool AreItemsOperable() const override; virtual bool AreItemsOperable() const override;
virtual Accessible* CurrentItem() override; virtual Accessible* CurrentItem() const override;
virtual void SetCurrentItem(Accessible* aItem) override; virtual void SetCurrentItem(const Accessible* aItem) override;
virtual Accessible* ContainerWidget() const 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 # Below is a set of additional dependencies and variables used to build things
# that are not supported by data in moz.build. # 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 $(TOPOBJDIR)/build/application.ini: $(TOPOBJDIR)/buildid.h $(TOPOBJDIR)/source-repo.h
# The manifest of allowed system add-ons should be re-built when using # 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 \ $(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) \ $(process_py) --cache-dir $(DEPTH)/xpcom/idl-parser/xpidl --depsdir $(idl_deps_dir) \
--bindings-conf $(topsrcdir)/dom/bindings/Bindings.conf \ --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) $(basename $(notdir $@)) $($(basename $(notdir $@))_deps)
# When some IDL is added or removed, if the actual IDL file was already, or # 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 # 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 define xpt_deps
$(1): $(call mkdir_deps,$(dir $(1))) $(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)) ifneq ($($(basename $(notdir $(1)))_deps),$($(basename $(notdir $(1)))_deps_built))
$(1): FORCE $(1): FORCE
endif endif

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

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

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

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

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

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

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

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

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

@ -2848,9 +2848,7 @@ const InterfaceShimEntry kInterfaceShimMap[] =
{ { "nsIXMLHttpRequest", "XMLHttpRequest" }, { { "nsIXMLHttpRequest", "XMLHttpRequest" },
{ "nsIDOMDOMException", "DOMException" }, { "nsIDOMDOMException", "DOMException" },
{ "nsIDOMNode", "Node" }, { "nsIDOMNode", "Node" },
{ "nsIDOMCSSPrimitiveValue", "CSSPrimitiveValue" },
{ "nsIDOMCSSRule", "CSSRule" }, { "nsIDOMCSSRule", "CSSRule" },
{ "nsIDOMCSSValue", "CSSValue" },
{ "nsIDOMEvent", "Event" }, { "nsIDOMEvent", "Event" },
{ "nsIDOMNSEvent", "Event" }, { "nsIDOMNSEvent", "Event" },
{ "nsIDOMKeyEvent", "KeyEvent" }, { "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; return aPointer;
} }
inline nsISupports*
ToCanonicalSupports(nsINode* aPointer)
{
return aPointer;
}
// Some checks are faster to do on nsIContent or Element than on // Some checks are faster to do on nsIContent or Element than on
// nsINode, so spit out FromNode versions taking those types too. // nsINode, so spit out FromNode versions taking those types too.
#define NS_IMPL_FROMNODE_GENERIC(_class, _check, _const) \ #define NS_IMPL_FROMNODE_GENERIC(_class, _check, _const) \

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -147,14 +147,24 @@ ConsoleInstance::GroupEnd(JSContext* aCx)
void void
ConsoleInstance::Time(JSContext* aCx, const nsAString& aLabel) 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")); 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 void
ConsoleInstance::TimeEnd(JSContext* aCx, const nsAString& aLabel) 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")); NS_LITERAL_STRING("timeEnd"));
} }
@ -201,7 +211,8 @@ ConsoleInstance::Assert(JSContext* aCx, bool aCondition,
void void
ConsoleInstance::Count(JSContext* aCx, const nsAString& aLabel) 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")); NS_LITERAL_STRING("count"));
} }

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

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

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

@ -10,3 +10,4 @@ support-files =
[test_console_binding.html] [test_console_binding.html]
[test_console_proto.html] [test_console_proto.html]
[test_devtools_pref.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 void
EventStateManager::ContentRemoved(nsIDocument* aDocument, nsIContent* aContent) EventStateManager::ContentRemoved(nsIDocument* aDocument, nsIContent* aContent)
{ {
@ -5392,19 +5440,8 @@ EventStateManager::ContentRemoved(nsIDocument* aDocument, nsIContent* aContent)
if (fm) if (fm)
fm->ContentRemoved(aDocument, aContent); fm->ContentRemoved(aDocument, aContent);
if (mHoverContent && RemoveNodeFromChainIfNeeded(NS_EVENT_STATE_HOVER, aContent, true);
nsContentUtils::ContentIsFlattenedTreeDescendantOf(mHoverContent, aContent)) { RemoveNodeFromChainIfNeeded(NS_EVENT_STATE_ACTIVE, aContent, true);
// 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);
}
if (sDragOverContent && if (sDragOverContent &&
sDragOverContent->OwnerDoc() == aContent->OwnerDoc() && sDragOverContent->OwnerDoc() == aContent->OwnerDoc() &&

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

@ -148,6 +148,8 @@ public:
* affect the return value. * affect the return value.
*/ */
bool SetContentState(nsIContent* aContent, EventStates aState); bool SetContentState(nsIContent* aContent, EventStates aState);
void NativeAnonymousContentRemoved(nsIContent* aAnonContent);
void ContentRemoved(nsIDocument* aDocument, nsIContent* aContent); void ContentRemoved(nsIDocument* aDocument, nsIContent* aContent);
bool EventStatusOK(WidgetGUIEvent* aEvent); bool EventStatusOK(WidgetGUIEvent* aEvent);
@ -1087,6 +1089,14 @@ protected:
void HandleQueryContentEvent(WidgetQueryContentEvent* aEvent); void HandleQueryContentEvent(WidgetQueryContentEvent* aEvent);
private: 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; 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(Unknown)
NS_DECLARE_NS_NEW_HTML_ELEMENT(Video) 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___ */ #endif /* nsGenericHTMLElement_h___ */

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

@ -1889,64 +1889,49 @@ nsHTMLDocument::ReleaseEvents()
WarnOnceAbout(nsIDocument::eUseOfReleaseEvents); WarnOnceAbout(nsIDocument::eUseOfReleaseEvents);
} }
nsISupports* bool
nsHTMLDocument::ResolveName(const nsAString& aName, nsWrapperCache **aCache) nsHTMLDocument::ResolveName(JSContext* aCx, const nsAString& aName,
JS::MutableHandle<JS::Value> aRetval, ErrorResult& aError)
{ {
nsIdentifierMapEntry *entry = mIdentifierMap.GetEntry(aName); nsIdentifierMapEntry *entry = mIdentifierMap.GetEntry(aName);
if (!entry) { if (!entry) {
*aCache = nullptr; return false;
return nullptr;
} }
nsBaseContentList *list = entry->GetNameContentList(); nsBaseContentList *list = entry->GetNameContentList();
uint32_t length = list ? list->Length() : 0; uint32_t length = list ? list->Length() : 0;
nsIContent *node;
if (length > 0) { if (length > 0) {
if (length == 1) { if (length > 1) {
// Only one element in the list, return the element instead of returning // The list contains more than one element, return the whole list.
// the list. if (!ToJSValue(aCx, list, aRetval)) {
nsIContent *node = list->Item(0); aError.NoteJSContextException(aCx);
*aCache = node; return false;
return node; }
return true;
} }
// The list contains more than one element, return the whole list. // Only one element in the list, return the element instead of returning
*aCache = list; // the list.
return 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. if (!ToJSValue(aCx, node, aRetval)) {
Element *e = entry->GetIdElement(); aError.NoteJSContextException(aCx);
return false;
if (e && nsGenericHTMLElement::ShouldExposeIdAsHTMLDocumentProperty(e)) {
*aCache = e;
return e;
} }
*aCache = nullptr; return true;
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());
} }
void void

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

@ -79,7 +79,9 @@ public:
mozilla::dom::HTMLAllCollection* All(); 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 AddedForm() override;
virtual void RemovedForm() override; virtual void RemovedForm() override;
@ -151,7 +153,13 @@ public:
void SetCookie(const nsAString& aCookie, mozilla::ErrorResult& rv); void SetCookie(const nsAString& aCookie, mozilla::ErrorResult& rv);
void NamedGetter(JSContext* cx, const nsAString& aName, bool& aFound, void NamedGetter(JSContext* cx, const nsAString& aName, bool& aFound,
JS::MutableHandle<JSObject*> aRetval, 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); void GetSupportedNames(nsTArray<nsString>& aNames);
already_AddRefed<nsIDocument> Open(JSContext* cx, already_AddRefed<nsIDocument> Open(JSContext* cx,
const mozilla::dom::Optional<nsAString>& /* unused */, const mozilla::dom::Optional<nsAString>& /* unused */,

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

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

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

@ -8,6 +8,7 @@
#include "nsIDocument.h" #include "nsIDocument.h"
#include "nsPIDOMWindow.h" #include "nsPIDOMWindow.h"
#include "ServiceWorkerImpl.h"
#include "ServiceWorkerManager.h" #include "ServiceWorkerManager.h"
#include "ServiceWorkerPrivate.h" #include "ServiceWorkerPrivate.h"
@ -62,7 +63,8 @@ ServiceWorker::Create(nsIGlobalObject* aOwner,
return ref.forget(); 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(); 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 class ChangeStateUpdater final : public Runnable
{ {
public: public:
ChangeStateUpdater(const nsTArray<ServiceWorker*>& aInstances, ChangeStateUpdater(const nsTArray<ServiceWorkerInfo::Listener*>& aInstances,
ServiceWorkerState aState) ServiceWorkerState aState)
: Runnable("dom::ChangeStateUpdater") : Runnable("dom::ChangeStateUpdater")
, mState(aState) , mState(aState)
@ -137,7 +137,7 @@ public:
} }
private: private:
AutoTArray<RefPtr<ServiceWorker>, 1> mInstances; AutoTArray<RefPtr<ServiceWorkerInfo::Listener>, 1> mInstances;
ServiceWorkerState mState; ServiceWorkerState mState;
}; };
@ -225,33 +225,20 @@ ServiceWorkerInfo::GetNextID() const
} }
void void
ServiceWorkerInfo::AddServiceWorker(ServiceWorker* aWorker) ServiceWorkerInfo::AddListener(Listener* aListener)
{ {
MOZ_DIAGNOSTIC_ASSERT(aWorker); MOZ_DIAGNOSTIC_ASSERT(aListener);
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED MOZ_ASSERT(!mInstances.Contains(aListener));
nsAutoString workerURL;
aWorker->GetScriptURL(workerURL);
MOZ_DIAGNOSTIC_ASSERT(
workerURL.Equals(NS_ConvertUTF8toUTF16(mDescriptor.ScriptURL())));
#endif
MOZ_ASSERT(!mInstances.Contains(aWorker));
mInstances.AppendElement(aWorker); mInstances.AppendElement(aListener);
aWorker->SetState(State()); aListener->SetState(State());
} }
void void
ServiceWorkerInfo::RemoveServiceWorker(ServiceWorker* aWorker) ServiceWorkerInfo::RemoveListener(Listener* aListener)
{ {
MOZ_DIAGNOSTIC_ASSERT(aWorker); MOZ_DIAGNOSTIC_ASSERT(aListener);
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED DebugOnly<bool> removed = mInstances.RemoveElement(aListener);
nsAutoString workerURL;
aWorker->GetScriptURL(workerURL);
MOZ_DIAGNOSTIC_ASSERT(
workerURL.Equals(NS_ConvertUTF8toUTF16(mDescriptor.ScriptURL())));
#endif
DebugOnly<bool> removed = mInstances.RemoveElement(aWorker);
MOZ_ASSERT(removed); MOZ_ASSERT(removed);
} }

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

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

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

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

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

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

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

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

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

@ -256,8 +256,6 @@ var interfaceNamesInGlobalScope =
{name: "CSSNamespaceRule", insecureContext: true}, {name: "CSSNamespaceRule", insecureContext: true},
// IMPORTANT: Do not change this list without review from a DOM peer! // IMPORTANT: Do not change this list without review from a DOM peer!
{name: "CSSPageRule", insecureContext: true}, {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! // IMPORTANT: Do not change this list without review from a DOM peer!
{name: "CSSPseudoElement", insecureContext: true, release: false}, {name: "CSSPseudoElement", insecureContext: true, release: false},
// IMPORTANT: Do not change this list without review from a DOM peer! // IMPORTANT: Do not change this list without review from a DOM peer!
@ -274,10 +272,6 @@ var interfaceNamesInGlobalScope =
{name: "CSSSupportsRule", insecureContext: true}, {name: "CSSSupportsRule", insecureContext: true},
// IMPORTANT: Do not change this list without review from a DOM peer! // IMPORTANT: Do not change this list without review from a DOM peer!
{name: "CSSTransition", insecureContext: true, release: false}, {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! // IMPORTANT: Do not change this list without review from a DOM peer!
{name: "CustomElementRegistry", insecureContext: true}, {name: "CustomElementRegistry", insecureContext: true},
// IMPORTANT: Do not change this list without review from a DOM peer! // IMPORTANT: Do not change this list without review from a DOM peer!
@ -814,14 +808,10 @@ var interfaceNamesInGlobalScope =
{name: "RadioNodeList", insecureContext: true}, {name: "RadioNodeList", insecureContext: true},
// IMPORTANT: Do not change this list without review from a DOM peer! // IMPORTANT: Do not change this list without review from a DOM peer!
{name: "Range", insecureContext: true}, {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! // IMPORTANT: Do not change this list without review from a DOM peer!
{name: "Request", insecureContext: true}, {name: "Request", insecureContext: true},
// IMPORTANT: Do not change this list without review from a DOM peer! // IMPORTANT: Do not change this list without review from a DOM peer!
{name: "Response", insecureContext: true}, {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! // IMPORTANT: Do not change this list without review from a DOM peer!
{name: "RTCCertificate", insecureContext: true}, {name: "RTCCertificate", insecureContext: true},
// IMPORTANT: Do not change this list without review from a DOM peer! // 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] [UseCounter]
void time(optional DOMString label = "default"); void time(optional DOMString label = "default");
[UseCounter] [UseCounter]
void timeLog(optional DOMString label = "default", any... data);
[UseCounter]
void timeEnd(optional DOMString label = "default"); void timeEnd(optional DOMString label = "default");
// Mozilla only or Webcompat methods // Mozilla only or Webcompat methods
@ -121,7 +123,7 @@ dictionary ConsoleTimerStart {
DOMString name = ""; DOMString name = "";
}; };
dictionary ConsoleTimerEnd { dictionary ConsoleTimerLogOrEnd {
DOMString name = ""; DOMString name = "";
double duration = 0; double duration = 0;
}; };
@ -165,6 +167,7 @@ interface ConsoleInstance {
// Timing // Timing
void time(optional DOMString label = "default"); void time(optional DOMString label = "default");
void timeLog(optional DOMString label = "default", any... data);
void timeEnd(optional DOMString label = "default"); void timeEnd(optional DOMString label = "default");
// Mozilla only or Webcompat methods // Mozilla only or Webcompat methods
@ -179,8 +182,9 @@ interface ConsoleInstance {
callback ConsoleInstanceDumpCallback = void (DOMString message); callback ConsoleInstanceDumpCallback = void (DOMString message);
enum ConsoleLogLevel { enum ConsoleLogLevel {
"All", "Debug", "Log", "Info", "Clear", "Trace", "TimeEnd", "Time", "Group", "All", "Debug", "Log", "Info", "Clear", "Trace", "TimeLog", "TimeEnd", "Time",
"GroupEnd", "Profile", "ProfileEnd", "Dir", "Dirxml", "Warn", "Error", "Off" "Group", "GroupEnd", "Profile", "ProfileEnd", "Dir", "Dirxml", "Warn", "Error",
"Off"
}; };
dictionary ConsoleInstanceOptions { 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', 'CSSMozDocumentRule.webidl',
'CSSNamespaceRule.webidl', 'CSSNamespaceRule.webidl',
'CSSPageRule.webidl', 'CSSPageRule.webidl',
'CSSPrimitiveValue.webidl',
'CSSPseudoElement.webidl', 'CSSPseudoElement.webidl',
'CSSRule.webidl', 'CSSRule.webidl',
'CSSRuleList.webidl', 'CSSRuleList.webidl',
@ -450,8 +449,6 @@ WEBIDL_FILES = [
'CSSStyleSheet.webidl', 'CSSStyleSheet.webidl',
'CSSSupportsRule.webidl', 'CSSSupportsRule.webidl',
'CSSTransition.webidl', 'CSSTransition.webidl',
'CSSValue.webidl',
'CSSValueList.webidl',
'CustomElementRegistry.webidl', 'CustomElementRegistry.webidl',
'DataTransfer.webidl', 'DataTransfer.webidl',
'DataTransferItem.webidl', 'DataTransferItem.webidl',
@ -738,10 +735,8 @@ WEBIDL_FILES = [
'PushSubscriptionOptions.webidl', 'PushSubscriptionOptions.webidl',
'RadioNodeList.webidl', 'RadioNodeList.webidl',
'Range.webidl', 'Range.webidl',
'Rect.webidl',
'Request.webidl', 'Request.webidl',
'Response.webidl', 'Response.webidl',
'RGBColor.webidl',
'RTCStatsReport.webidl', 'RTCStatsReport.webidl',
'Screen.webidl', 'Screen.webidl',
'ScreenOrientation.webidl', 'ScreenOrientation.webidl',

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

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

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

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

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

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

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

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

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

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

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

@ -23,6 +23,13 @@
using namespace mozilla; using namespace mozilla;
using namespace mozilla::gfx; 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, gfxMacFont::gfxMacFont(const RefPtr<UnscaledFontMac>& aUnscaledFont,
MacOSFontEntry *aFontEntry, MacOSFontEntry *aFontEntry,
const gfxFontStyle *aFontStyle) const gfxFontStyle *aFontStyle)
@ -47,6 +54,55 @@ gfxMacFont::gfxMacFont(const RefPtr<UnscaledFontMac>& aUnscaledFont,
AutoTArray<gfxFontVariation,4> vars; AutoTArray<gfxFontVariation,4> vars;
aFontEntry->GetVariationsForStyle(vars, *aFontStyle); 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 = mCGFont =
UnscaledFontMac::CreateCGFontWithVariations(baseFont, UnscaledFontMac::CreateCGFontWithVariations(baseFont,
vars.Length(), vars.Length(),

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

@ -30,6 +30,7 @@ class MacOSFontEntry : public gfxFontEntry
{ {
public: public:
friend class gfxMacPlatformFontList; friend class gfxMacPlatformFontList;
friend class gfxMacFont;
MacOSFontEntry(const nsAString& aPostscriptName, WeightRange aWeight, MacOSFontEntry(const nsAString& aPostscriptName, WeightRange aWeight,
bool aIsStandardFace = false, bool aIsStandardFace = false,
@ -104,6 +105,19 @@ protected:
bool mHasAATSmallCaps; bool mHasAATSmallCaps;
bool mHasAATSmallCapsInitialized; bool mHasAATSmallCapsInitialized;
bool mCheckedForTracking; 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; nsTHashtable<nsUint32HashKey> mAvailableTables;
mozilla::ThreadSafeWeakPtr<mozilla::gfx::UnscaledFontMac> mUnscaledFont; mozilla::ThreadSafeWeakPtr<mozilla::gfx::UnscaledFontMac> mUnscaledFont;

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

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

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

@ -2799,7 +2799,7 @@ gfxFontGroup::GetEllipsisTextRun(int32_t aAppUnitsPerDevPixel,
gfxFont* gfxFont*
gfxFontGroup::FindFallbackFaceForChar(gfxFontFamily* aFamily, uint32_t aCh) gfxFontGroup::FindFallbackFaceForChar(gfxFontFamily* aFamily, uint32_t aCh)
{ {
GlobalFontMatch data(aCh, &mStyle); GlobalFontMatch data(aCh, mStyle);
aFamily->SearchAllFontsForChar(&data); aFamily->SearchAllFontsForChar(&data);
gfxFontEntry* fe = data.mBestMatch; gfxFontEntry* fe = data.mBestMatch;
if (!fe) { 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 // for..in iteration over the array. Keys deleted before being reached
// during the iteration must not be visited, and suppressing them here // during the iteration must not be visited, and suppressing them here
// would be too costly. // 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)) if (!arr->maybeCopyElementsForWrite(cx))
return false; 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, baguette);
assertEq(ref.calories, baguette.calories); assertEq(ref.calories, baguette.calories);
if (wasmDebuggingIsSupported()) { // Make sure grow-memory isn't blocked by the lack of gc.
let g = newGlobal(); (function() {
let dbg = new Debugger(g); assertEq(wasmEvalText(`(module
g.eval(`o = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary('(module (func (result anyref) (param anyref) get_local 0) (export "" 0))')));`); (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. // 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 Register
CacheRegisterAllocator::useRegister(MacroAssembler& masm, TypedOperandId typedId) CacheRegisterAllocator::useRegister(MacroAssembler& masm, TypedOperandId typedId)
{ {
MOZ_ASSERT(!addedFailurePath_);
OperandLocation& loc = operandLocations_[typedId.id()]; OperandLocation& loc = operandLocations_[typedId.id()];
switch (loc.kind()) { switch (loc.kind()) {
case OperandLocation::PayloadReg: case OperandLocation::PayloadReg:
@ -206,6 +208,8 @@ CacheRegisterAllocator::useRegister(MacroAssembler& masm, TypedOperandId typedId
ConstantOrRegister ConstantOrRegister
CacheRegisterAllocator::useConstantOrRegister(MacroAssembler& masm, ValOperandId val) CacheRegisterAllocator::useConstantOrRegister(MacroAssembler& masm, ValOperandId val)
{ {
MOZ_ASSERT(!addedFailurePath_);
OperandLocation& loc = operandLocations_[val.id()]; OperandLocation& loc = operandLocations_[val.id()];
switch (loc.kind()) { switch (loc.kind()) {
case OperandLocation::Constant: case OperandLocation::Constant:
@ -236,6 +240,8 @@ CacheRegisterAllocator::useConstantOrRegister(MacroAssembler& masm, ValOperandId
Register Register
CacheRegisterAllocator::defineRegister(MacroAssembler& masm, TypedOperandId typedId) CacheRegisterAllocator::defineRegister(MacroAssembler& masm, TypedOperandId typedId)
{ {
MOZ_ASSERT(!addedFailurePath_);
OperandLocation& loc = operandLocations_[typedId.id()]; OperandLocation& loc = operandLocations_[typedId.id()];
MOZ_ASSERT(loc.kind() == OperandLocation::Uninitialized); MOZ_ASSERT(loc.kind() == OperandLocation::Uninitialized);
@ -247,6 +253,8 @@ CacheRegisterAllocator::defineRegister(MacroAssembler& masm, TypedOperandId type
ValueOperand ValueOperand
CacheRegisterAllocator::defineValueRegister(MacroAssembler& masm, ValOperandId val) CacheRegisterAllocator::defineValueRegister(MacroAssembler& masm, ValOperandId val)
{ {
MOZ_ASSERT(!addedFailurePath_);
OperandLocation& loc = operandLocations_[val.id()]; OperandLocation& loc = operandLocations_[val.id()];
MOZ_ASSERT(loc.kind() == OperandLocation::Uninitialized); MOZ_ASSERT(loc.kind() == OperandLocation::Uninitialized);
@ -309,6 +317,8 @@ CacheRegisterAllocator::discardStack(MacroAssembler& masm)
Register Register
CacheRegisterAllocator::allocateRegister(MacroAssembler& masm) CacheRegisterAllocator::allocateRegister(MacroAssembler& masm)
{ {
MOZ_ASSERT(!addedFailurePath_);
if (availableRegs_.empty()) if (availableRegs_.empty())
freeDeadOperandLocations(masm); freeDeadOperandLocations(masm);
@ -359,6 +369,8 @@ CacheRegisterAllocator::allocateRegister(MacroAssembler& masm)
void void
CacheRegisterAllocator::allocateFixedRegister(MacroAssembler& masm, Register reg) CacheRegisterAllocator::allocateFixedRegister(MacroAssembler& masm, Register reg)
{ {
MOZ_ASSERT(!addedFailurePath_);
// Fixed registers should be allocated first, to ensure they're // Fixed registers should be allocated first, to ensure they're
// still available. // still available.
MOZ_ASSERT(!currentOpRegs_.has(reg), "Register is in use"); MOZ_ASSERT(!currentOpRegs_.has(reg), "Register is in use");
@ -479,6 +491,10 @@ CacheRegisterAllocator::fixupAliasedInputs(MacroAssembler& masm)
} }
} }
} }
#ifdef DEBUG
assertValidState();
#endif
} }
GeneralRegisterSet GeneralRegisterSet
@ -668,6 +684,32 @@ CacheRegisterAllocator::popValue(MacroAssembler& masm, OperandLocation* loc, Val
loc->setValueReg(dest); 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 bool
OperandLocation::aliasesReg(const OperandLocation& other) const OperandLocation::aliasesReg(const OperandLocation& other) const
{ {
@ -1165,6 +1207,10 @@ FailurePath::canShareFailurePath(const FailurePath& other) const
bool bool
CacheIRCompiler::addFailurePath(FailurePath** failure) CacheIRCompiler::addFailurePath(FailurePath** failure)
{ {
#ifdef DEBUG
allocator.setAddedFailurePath();
#endif
FailurePath newFailure; FailurePath newFailure;
for (size_t i = 0; i < writer_.numInputOperands(); i++) { for (size_t i = 0; i < writer_.numInputOperands(); i++) {
if (!newFailure.appendInput(allocator.operandLocation(i))) if (!newFailure.appendInput(allocator.operandLocation(i)))

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

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

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

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

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

@ -1961,10 +1961,11 @@ class DebugFrame
// the return value of a frame being debugged. // the return value of a frame being debugged.
union union
{ {
int32_t resultI32_; int32_t resultI32_;
int64_t resultI64_; int64_t resultI64_;
float resultF32_; intptr_t resultRef_;
double resultF64_; float resultF32_;
double resultF64_;
}; };
// The returnValue() method returns a HandleValue pointing to this field. // 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) #define XPC_SCRIPTABLE_USE_JSSTUB_FOR_DELPROPERTY (1 << 11)
// (1 << 12) is unused // (1 << 12) is unused
#define XPC_SCRIPTABLE_DONT_ENUM_QUERY_INTERFACE (1 << 13) #define XPC_SCRIPTABLE_DONT_ENUM_QUERY_INTERFACE (1 << 13)
#define XPC_SCRIPTABLE_DONT_ASK_INSTANCE_FOR_SCRIPTABLE (1 << 14) // (1 << 14) is unused
#define XPC_SCRIPTABLE_CLASSINFO_INTERFACES_ONLY (1 << 15) // (1 << 15) is unused
#define XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE (1 << 16) #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_IS_GLOBAL_OBJECT (1 << 18)
#define XPC_SCRIPTABLE_DONT_REFLECT_INTERFACE_NAMES (1 << 19) #define XPC_SCRIPTABLE_DONT_REFLECT_INTERFACE_NAMES (1 << 19)
%} %}
@ -100,8 +100,6 @@ interface nsIXPCScriptable : nsISupports
in JSContextPtr cx, in JSObjectPtr obj, in JSContextPtr cx, in JSObjectPtr obj,
in jsval val, out boolean bp); in jsval val, out boolean bp);
void postCreatePrototype(in JSContextPtr cx, in JSObjectPtr proto);
%{ C++ %{ C++
#define GET_IT(f_, c_) \ #define GET_IT(f_, c_) \
bool f_() { \ bool f_() { \
@ -119,46 +117,10 @@ interface nsIXPCScriptable : nsISupports
GET_IT(UseJSStubForAddProperty, USE_JSSTUB_FOR_ADDPROPERTY) GET_IT(UseJSStubForAddProperty, USE_JSSTUB_FOR_ADDPROPERTY)
GET_IT(UseJSStubForDelProperty, USE_JSSTUB_FOR_DELPROPERTY) GET_IT(UseJSStubForDelProperty, USE_JSSTUB_FOR_DELPROPERTY)
GET_IT(DontEnumQueryInterface, DONT_ENUM_QUERY_INTERFACE) 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(AllowPropModsDuringResolve, ALLOW_PROP_MODS_DURING_RESOLVE)
GET_IT(AllowPropModsToPrototype, ALLOW_PROP_MODS_TO_PROTOTYPE)
GET_IT(IsGlobalObject, IS_GLOBAL_OBJECT) GET_IT(IsGlobalObject, IS_GLOBAL_OBJECT)
GET_IT(DontReflectInterfaceNames, DONT_REFLECT_INTERFACE_NAMES) GET_IT(DontReflectInterfaceNames, DONT_REFLECT_INTERFACE_NAMES)
#undef GET_IT #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;} {NS_ERROR("never called"); return NS_ERROR_NOT_IMPLEMENTED;}
#endif #endif
NS_IMETHODIMP XPC_MAP_CLASSNAME::PostCreatePrototype(JSContext* cx, JSObject* proto)
{return NS_OK;}
/**************************************************************/ /**************************************************************/
#undef XPC_MAP_CLASSNAME #undef XPC_MAP_CLASSNAME

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

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

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

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

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

@ -252,18 +252,6 @@ DefinePropertyIfFound(XPCCallContext& ccx,
if (!found) { if (!found) {
if (reflectToStringAndToSource) { if (reflectToStringAndToSource) {
JSNative call; 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)) { if (id == xpccx->GetStringID(XPCJSContext::IDX_TO_STRING)) {
call = XPC_WN_Shared_ToString; call = XPC_WN_Shared_ToString;
name = xpccx->GetStringName(XPCJSContext::IDX_TO_STRING); name = xpccx->GetStringName(XPCJSContext::IDX_TO_STRING);
@ -952,10 +940,9 @@ XPC_WN_GetterSetter(JSContext* cx, unsigned argc, Value* vp)
/***************************************************************************/ /***************************************************************************/
static bool 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 || MOZ_ASSERT(js::GetObjectClass(obj) == &XPC_WN_Proto_JSClass,
js::GetObjectClass(obj) == &XPC_WN_NoMods_Proto_JSClass,
"bad proto"); "bad proto");
XPCWrappedNativeProto* self = XPCWrappedNativeProto* self =
(XPCWrappedNativeProto*) xpc_GetJSPrivate(obj); (XPCWrappedNativeProto*) xpc_GetJSPrivate(obj);
@ -986,7 +973,7 @@ XPC_WN_Shared_Proto_Enumerate(JSContext* cx, HandleObject obj)
} }
static void 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 // This can be null if xpc shutdown has already happened
XPCWrappedNativeProto* p = (XPCWrappedNativeProto*) xpc_GetJSPrivate(obj); XPCWrappedNativeProto* p = (XPCWrappedNativeProto*) xpc_GetJSPrivate(obj);
@ -995,7 +982,7 @@ XPC_WN_Shared_Proto_Finalize(js::FreeOp* fop, JSObject* obj)
} }
static size_t 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 // This can be null if xpc shutdown has already happened
XPCWrappedNativeProto* p = (XPCWrappedNativeProto*) xpc_GetJSPrivate(obj); XPCWrappedNativeProto* p = (XPCWrappedNativeProto*) xpc_GetJSPrivate(obj);
@ -1007,7 +994,7 @@ XPC_WN_Shared_Proto_ObjectMoved(JSObject* obj, JSObject* old)
} }
static void 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 // This can be null if xpc shutdown has already happened
XPCWrappedNativeProto* p = 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 static bool
XPC_WN_OnlyIWrite_Proto_AddPropertyStub(JSContext* cx, HandleObject obj, HandleId id, XPC_WN_OnlyIWrite_Proto_AddPropertyStub(JSContext* cx, HandleObject obj, HandleId id,
HandleValue v) HandleValue v)
{ {
MOZ_ASSERT(js::GetObjectClass(obj) == &XPC_WN_NoMods_Proto_JSClass, MOZ_ASSERT(js::GetObjectClass(obj) == &XPC_WN_Proto_JSClass,
"bad proto"); "bad proto");
XPCWrappedNativeProto* self = XPCWrappedNativeProto* self =
@ -1095,9 +1029,9 @@ XPC_WN_OnlyIWrite_Proto_AddPropertyStub(JSContext* cx, HandleObject obj, HandleI
} }
static bool 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"); "bad proto");
XPCWrappedNativeProto* self = XPCWrappedNativeProto* self =
@ -1120,26 +1054,31 @@ XPC_WN_NoMods_Proto_Resolve(JSContext* cx, HandleObject obj, HandleId id, bool*
JSPROP_ENUMERATE, resolvedp); 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_OnlyIWrite_Proto_AddPropertyStub, // addProperty
XPC_WN_CannotDeletePropertyStub, // delProperty XPC_WN_CannotDeletePropertyStub, // delProperty
XPC_WN_Shared_Proto_Enumerate, // enumerate XPC_WN_Proto_Enumerate, // enumerate
nullptr, // newEnumerate nullptr, // newEnumerate
XPC_WN_NoMods_Proto_Resolve, // resolve XPC_WN_Proto_Resolve, // resolve
nullptr, // mayResolve nullptr, // mayResolve
XPC_WN_Shared_Proto_Finalize, // finalize XPC_WN_Proto_Finalize, // finalize
nullptr, // call nullptr, // call
nullptr, // construct nullptr, // construct
nullptr, // hasInstance nullptr, // hasInstance
XPC_WN_Shared_Proto_Trace, // trace XPC_WN_Proto_Trace, // trace
}; };
const js::Class XPC_WN_NoMods_Proto_JSClass = { static const js::ClassExtension XPC_WN_Proto_ClassExtension = {
"XPC_WN_NoMods_Proto_JSClass", nullptr, /* weakmapKeyDelegateOp */
XPC_WN_Proto_ObjectMoved
};
const js::Class XPC_WN_Proto_JSClass = {
"XPC_WN_Proto_JSClass",
XPC_WRAPPER_FLAGS, XPC_WRAPPER_FLAGS,
&XPC_WN_NoMods_Proto_JSClassOps, &XPC_WN_Proto_JSClassOps,
JS_NULL_CLASS_SPEC, JS_NULL_CLASS_SPEC,
&XPC_WN_Shared_Proto_ClassExtension, &XPC_WN_Proto_ClassExtension,
JS_NULL_OBJECT_OPS JS_NULL_OBJECT_OPS
}; };

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

@ -50,54 +50,24 @@ XPCWrappedNativeProto::~XPCWrappedNativeProto()
} }
bool bool
XPCWrappedNativeProto::Init(nsIXPCScriptable* scriptable, XPCWrappedNativeProto::Init(nsIXPCScriptable* scriptable)
bool callPostCreatePrototype)
{ {
AutoJSContext cx; AutoJSContext cx;
mScriptable = scriptable; 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 global(cx, mScope->GetGlobalJSObject());
JS::RootedObject proto(cx, JS_GetObjectPrototype(cx, global)); 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); proto);
bool success = !!mJSProtoObject; bool success = !!mJSProtoObject;
if (success) { if (success) {
JS_SetPrivate(mJSProtoObject, this); JS_SetPrivate(mJSProtoObject, this);
if (callPostCreatePrototype)
success = CallPostCreatePrototype();
} }
return success; 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 void
XPCWrappedNativeProto::JSProtoObjectFinalized(js::FreeOp* fop, JSObject* obj) XPCWrappedNativeProto::JSProtoObjectFinalized(js::FreeOp* fop, JSObject* obj)
{ {
@ -138,8 +108,7 @@ XPCWrappedNativeProto::SystemIsBeingShutDown()
XPCWrappedNativeProto* XPCWrappedNativeProto*
XPCWrappedNativeProto::GetNewOrUsed(XPCWrappedNativeScope* scope, XPCWrappedNativeProto::GetNewOrUsed(XPCWrappedNativeScope* scope,
nsIClassInfo* classInfo, nsIClassInfo* classInfo,
nsIXPCScriptable* scriptable, nsIXPCScriptable* scriptable)
bool callPostCreatePrototype)
{ {
AutoJSContext cx; AutoJSContext cx;
MOZ_ASSERT(scope, "bad param"); MOZ_ASSERT(scope, "bad param");
@ -159,7 +128,7 @@ XPCWrappedNativeProto::GetNewOrUsed(XPCWrappedNativeScope* scope,
proto = new XPCWrappedNativeProto(scope, classInfo, set.forget()); proto = new XPCWrappedNativeProto(scope, classInfo, set.forget());
if (!proto || !proto->Init(scriptable, callPostCreatePrototype)) { if (!proto || !proto->Init(scriptable)) {
delete proto.get(); delete proto.get();
return nullptr; return nullptr;
} }

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

@ -6,7 +6,6 @@
EXPORTS += [ EXPORTS += [
'BackstagePass.h', 'BackstagePass.h',
'qsObjectHelper.h',
'XPCJSMemoryReporter.h', 'XPCJSMemoryReporter.h',
'xpcObjectHelper.h', 'xpcObjectHelper.h',
'xpcpublic.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: public:
explicit xpcObjectHelper(nsISupports* aObject, nsWrapperCache* aCache = nullptr) explicit xpcObjectHelper(nsISupports* aObject, nsWrapperCache* aCache = nullptr)
: mCanonical(nullptr) : mObject(aObject)
, mObject(aObject)
, mCache(aCache) , mCache(aCache)
{ {
if (!mCache) { if (!mCache && aObject) {
if (aObject) CallQueryInterface(aObject, &mCache);
CallQueryInterface(aObject, &mCache);
else
mCache = nullptr;
} }
} }
@ -43,57 +39,17 @@ public:
return mObject; 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() nsIClassInfo* GetClassInfo()
{ {
if (mXPCClassInfo)
return mXPCClassInfo;
if (!mClassInfo) if (!mClassInfo)
mClassInfo = do_QueryInterface(mObject); mClassInfo = do_QueryInterface(mObject);
return mClassInfo; 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. // We assert that we can reach an nsIXPCScriptable somehow.
uint32_t GetScriptableFlags() uint32_t GetScriptableFlags()
{ {
// Try getting an nsXPCClassInfo - this handles DOM scriptable helpers. nsCOMPtr<nsIXPCScriptable> sinfo = do_QueryInterface(mObject);
nsCOMPtr<nsIXPCScriptable> sinfo = GetXPCClassInfo();
// If that didn't work, try just QI-ing. This handles BackstagePass.
if (!sinfo)
sinfo = do_QueryInterface(GetCanonical());
// We should have something by now. // We should have something by now.
MOZ_ASSERT(sinfo); MOZ_ASSERT(sinfo);
@ -107,22 +63,6 @@ public:
return mCache; 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: private:
xpcObjectHelper(xpcObjectHelper& aOther) = delete; xpcObjectHelper(xpcObjectHelper& aOther) = delete;
@ -131,7 +71,6 @@ private:
"(see bug 565742)") mObject; "(see bug 565742)") mObject;
nsWrapperCache* mCache; nsWrapperCache* mCache;
nsCOMPtr<nsIClassInfo> mClassInfo; nsCOMPtr<nsIClassInfo> mClassInfo;
RefPtr<nsXPCClassInfo> mXPCClassInfo;
}; };
#endif #endif

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

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

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

@ -1451,11 +1451,6 @@ IsWindow(JSContext* cx, JSObject* wrapper)
void void
XPCWrappedNativeXrayTraits::preserveWrapper(JSObject* target) 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 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 void
nsFrameManager::AddSizeOfIncludingThis(nsWindowSizes& aSizes) const nsFrameManager::AddSizeOfIncludingThis(nsWindowSizes& aSizes) const
{ {

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

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

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

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

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

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

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