зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-inbound to mozilla-central. a=merge
This commit is contained in:
Коммит
0d2ff9e60d
10
Makefile.in
10
Makefile.in
|
@ -33,8 +33,8 @@ DIST_GARBAGE = config.cache config.log config.status* config-defs.h \
|
|||
ifndef MOZ_PROFILE_USE
|
||||
# Automation builds should always have a new buildid, but for the sake of not
|
||||
# re-linking libxul on every incremental build we do not enforce this for
|
||||
# developer builds.
|
||||
ifneq (,$(MOZ_AUTOMATION)$(MOZ_BUILD_DATE))
|
||||
# developer builds. Tests always need a new buildid as well.
|
||||
ifneq (,$(MOZ_AUTOMATION)$(MOZ_BUILD_DATE)$(TEST_MOZBUILD))
|
||||
buildid.h source-repo.h: FORCE
|
||||
endif
|
||||
endif
|
||||
|
@ -109,7 +109,7 @@ default:: $(BUILD_BACKEND_FILES)
|
|||
endif
|
||||
|
||||
install_manifests := \
|
||||
$(addprefix dist/,branding idl include public private xpi-stage) \
|
||||
$(addprefix dist/,branding include public private xpi-stage) \
|
||||
_tests \
|
||||
$(NULL)
|
||||
# Skip the dist/bin install manifest when using the hybrid
|
||||
|
@ -140,12 +140,10 @@ install-manifests: $(addprefix install-,$(install_manifests))
|
|||
|
||||
# If we're using the hybrid FasterMake/RecursiveMake backend, we want
|
||||
# to recurse in the faster/ directory in parallel of install manifests.
|
||||
# But dist/idl needs to happen before (cf. dependencies in
|
||||
# config/faster/rules.mk)
|
||||
ifneq (,$(filter FasterMake+RecursiveMake,$(BUILD_BACKENDS)))
|
||||
install-manifests: faster
|
||||
.PHONY: faster
|
||||
faster: install-dist/idl
|
||||
faster:
|
||||
$(MAKE) -C faster FASTER_RECURSIVE_MAKE=1
|
||||
endif
|
||||
|
||||
|
|
|
@ -382,7 +382,7 @@ ItemIterator::Next()
|
|||
// XULTreeItemIterator
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
XULTreeItemIterator::XULTreeItemIterator(XULTreeAccessible* aXULTree,
|
||||
XULTreeItemIterator::XULTreeItemIterator(const XULTreeAccessible* aXULTree,
|
||||
nsITreeView* aTreeView,
|
||||
int32_t aRowIdx) :
|
||||
mXULTree(aXULTree), mTreeView(aTreeView), mRowCount(-1),
|
||||
|
|
|
@ -301,7 +301,7 @@ private:
|
|||
class XULTreeItemIterator : public AccIterable
|
||||
{
|
||||
public:
|
||||
XULTreeItemIterator(XULTreeAccessible* aXULTree, nsITreeView* aTreeView,
|
||||
XULTreeItemIterator(const XULTreeAccessible* aXULTree, nsITreeView* aTreeView,
|
||||
int32_t aRowIdx);
|
||||
virtual ~XULTreeItemIterator() { }
|
||||
|
||||
|
@ -312,7 +312,7 @@ private:
|
|||
XULTreeItemIterator(const XULTreeItemIterator&) = delete;
|
||||
XULTreeItemIterator& operator = (const XULTreeItemIterator&) = delete;
|
||||
|
||||
XULTreeAccessible* mXULTree;
|
||||
const XULTreeAccessible* mXULTree;
|
||||
nsITreeView* mTreeView;
|
||||
int32_t mRowCount;
|
||||
int32_t mContainerLevel;
|
||||
|
|
|
@ -327,7 +327,8 @@ MARKUPMAP(summary,
|
|||
MARKUPMAP(
|
||||
table,
|
||||
[](Element* aElement, Accessible* aContext) -> Accessible* {
|
||||
if (aElement->GetPrimaryFrame()->AccessibleType() != eHTMLTableType) {
|
||||
if (aElement->GetPrimaryFrame() &&
|
||||
aElement->GetPrimaryFrame()->AccessibleType() != eHTMLTableType) {
|
||||
return new ARIAGridAccessibleWrap(aElement, aContext->Document());
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -390,12 +391,13 @@ MARKUPMAP(
|
|||
if (table) {
|
||||
nsIContent* parentContent = aElement->GetParent();
|
||||
nsIFrame* parentFrame = parentContent->GetPrimaryFrame();
|
||||
if (!parentFrame->IsTableWrapperFrame()) {
|
||||
if (parentFrame && !parentFrame->IsTableWrapperFrame()) {
|
||||
parentContent = parentContent->GetParent();
|
||||
parentFrame = parentContent->GetPrimaryFrame();
|
||||
if (table->GetContent() == parentContent &&
|
||||
(!parentFrame->IsTableWrapperFrame() ||
|
||||
aElement->GetPrimaryFrame()->AccessibleType() != eHTMLTableRowType)) {
|
||||
((parentFrame && !parentFrame->IsTableWrapperFrame()) ||
|
||||
(aElement->GetPrimaryFrame() &&
|
||||
aElement->GetPrimaryFrame()->AccessibleType() != eHTMLTableRowType))) {
|
||||
return new ARIARowAccessible(aElement, aContext->Document());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1054,6 +1054,20 @@ nsAccessibilityService::CreateAccessible(nsINode* aNode,
|
|||
// Check frame and its visibility. Note, hidden frame allows visible
|
||||
// elements in subtree.
|
||||
if (!frame || !frame->StyleVisibility()->IsVisible()) {
|
||||
// display:contents element doesn't have a frame, but retains the semantics.
|
||||
// All its children are unaffected.
|
||||
if (content->IsElement() && content->AsElement()->IsDisplayContents()) {
|
||||
const HTMLMarkupMapInfo* markupMap =
|
||||
mHTMLMarkupMap.Get(content->NodeInfo()->NameAtom());
|
||||
if (markupMap && markupMap->new_func) {
|
||||
RefPtr<Accessible> newAcc =
|
||||
markupMap->new_func(content->AsElement(), aContext);
|
||||
document->BindToDocument(newAcc, aria::GetRoleMap(content->AsElement()));
|
||||
return newAcc;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aIsSubtreeHidden && !frame)
|
||||
*aIsSubtreeHidden = true;
|
||||
|
||||
|
|
|
@ -324,8 +324,14 @@ uint64_t
|
|||
Accessible::VisibilityState() const
|
||||
{
|
||||
nsIFrame* frame = GetFrame();
|
||||
if (!frame)
|
||||
if (!frame) {
|
||||
// Element having display:contents is considered visible semantically,
|
||||
// despite it doesn't have a visually visible box.
|
||||
if (mContent->IsElement() && mContent->AsElement()->IsDisplayContents()) {
|
||||
return states::OFFSCREEN;
|
||||
}
|
||||
return states::INVISIBLE;
|
||||
}
|
||||
|
||||
// Walk the parent frame chain to see if there's invisible parent or the frame
|
||||
// is in background tab.
|
||||
|
@ -1946,8 +1952,12 @@ Accessible::AppendTextTo(nsAString& aText, uint32_t aStartOffset,
|
|||
return;
|
||||
|
||||
nsIFrame *frame = GetFrame();
|
||||
if (!frame)
|
||||
if (!frame) {
|
||||
if (mContent->IsElement() && mContent->AsElement()->IsDisplayContents()) {
|
||||
aText += kEmbeddedObjectChar;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
NS_ASSERTION(mParent,
|
||||
"Called on accessible unbound from tree. Result can be wrong.");
|
||||
|
@ -2564,7 +2574,7 @@ Accessible::AreItemsOperable() const
|
|||
}
|
||||
|
||||
Accessible*
|
||||
Accessible::CurrentItem()
|
||||
Accessible::CurrentItem() const
|
||||
{
|
||||
// Check for aria-activedescendant, which changes which element has focus.
|
||||
// For activedescendant, the ARIA spec does not require that the user agent
|
||||
|
@ -2587,7 +2597,7 @@ Accessible::CurrentItem()
|
|||
}
|
||||
|
||||
void
|
||||
Accessible::SetCurrentItem(Accessible* aItem)
|
||||
Accessible::SetCurrentItem(const Accessible* aItem)
|
||||
{
|
||||
nsAtom* id = aItem->GetContent()->GetID();
|
||||
if (id) {
|
||||
|
|
|
@ -435,7 +435,7 @@ public:
|
|||
/**
|
||||
* Return true if accessible has children;
|
||||
*/
|
||||
bool HasChildren() { return !!GetChildAt(0); }
|
||||
bool HasChildren() const { return !!GetChildAt(0); }
|
||||
|
||||
/**
|
||||
* Return first/last/next/previous sibling of the accessible.
|
||||
|
@ -850,12 +850,12 @@ public:
|
|||
* Return the current item of the widget, i.e. an item that has or will have
|
||||
* keyboard focus when widget gets active.
|
||||
*/
|
||||
virtual Accessible* CurrentItem();
|
||||
virtual Accessible* CurrentItem() const;
|
||||
|
||||
/**
|
||||
* Set the current item of the widget.
|
||||
*/
|
||||
virtual void SetCurrentItem(Accessible* aItem);
|
||||
virtual void SetCurrentItem(const Accessible* aItem);
|
||||
|
||||
/**
|
||||
* Return container widget this accessible belongs to.
|
||||
|
|
|
@ -102,7 +102,7 @@ RootAccessible::NativeRole() const
|
|||
// RootAccessible protected member
|
||||
#ifdef MOZ_XUL
|
||||
uint32_t
|
||||
RootAccessible::GetChromeFlags()
|
||||
RootAccessible::GetChromeFlags() const
|
||||
{
|
||||
// Return the flag set for the top level window as defined
|
||||
// by nsIWebBrowserChrome::CHROME_WINDOW_[FLAGNAME]
|
||||
|
|
|
@ -76,7 +76,7 @@ protected:
|
|||
void HandleTreeInvalidatedEvent(dom::Event* aEvent,
|
||||
XULTreeAccessible* aAccessible);
|
||||
|
||||
uint32_t GetChromeFlags();
|
||||
uint32_t GetChromeFlags() const;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ HTMLSelectListAccessible::AreItemsOperable() const
|
|||
}
|
||||
|
||||
Accessible*
|
||||
HTMLSelectListAccessible::CurrentItem()
|
||||
HTMLSelectListAccessible::CurrentItem() const
|
||||
{
|
||||
nsIListControlFrame* listControlFrame = do_QueryFrame(GetFrame());
|
||||
if (listControlFrame) {
|
||||
|
@ -108,7 +108,7 @@ HTMLSelectListAccessible::CurrentItem()
|
|||
}
|
||||
|
||||
void
|
||||
HTMLSelectListAccessible::SetCurrentItem(Accessible* aItem)
|
||||
HTMLSelectListAccessible::SetCurrentItem(const Accessible* aItem)
|
||||
{
|
||||
if (!aItem->GetContent()->IsElement())
|
||||
return;
|
||||
|
@ -500,13 +500,13 @@ HTMLComboboxAccessible::AreItemsOperable() const
|
|||
}
|
||||
|
||||
Accessible*
|
||||
HTMLComboboxAccessible::CurrentItem()
|
||||
HTMLComboboxAccessible::CurrentItem() const
|
||||
{
|
||||
return AreItemsOperable() ? mListAccessible->CurrentItem() : nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
HTMLComboboxAccessible::SetCurrentItem(Accessible* aItem)
|
||||
HTMLComboboxAccessible::SetCurrentItem(const Accessible* aItem)
|
||||
{
|
||||
if (AreItemsOperable())
|
||||
mListAccessible->SetCurrentItem(aItem);
|
||||
|
|
|
@ -49,8 +49,8 @@ public:
|
|||
virtual bool IsWidget() const override;
|
||||
virtual bool IsActiveWidget() const override;
|
||||
virtual bool AreItemsOperable() const override;
|
||||
virtual Accessible* CurrentItem() override;
|
||||
virtual void SetCurrentItem(Accessible* aItem) override;
|
||||
virtual Accessible* CurrentItem() const override;
|
||||
virtual void SetCurrentItem(const Accessible* aItem) override;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -180,8 +180,8 @@ public:
|
|||
virtual bool IsWidget() const override;
|
||||
virtual bool IsActiveWidget() const override;
|
||||
virtual bool AreItemsOperable() const override;
|
||||
virtual Accessible* CurrentItem() override;
|
||||
virtual void SetCurrentItem(Accessible* aItem) override;
|
||||
virtual Accessible* CurrentItem() const override;
|
||||
virtual void SetCurrentItem(const Accessible* aItem) override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
testStates("div_off", STATE_OFFSCREEN, 0, STATE_INVISIBLE);
|
||||
testStates("div_transformed", STATE_OFFSCREEN, 0, STATE_INVISIBLE);
|
||||
testStates("div_abschild", 0, 0, STATE_INVISIBLE | STATE_OFFSCREEN);
|
||||
testStates("ul", STATE_OFFSCREEN, 0, STATE_INVISIBLE);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
@ -66,6 +67,10 @@
|
|||
<p style="position: absolute; left: 120px; top:120px;">absolute</p>
|
||||
</div>
|
||||
|
||||
<ul id="ul" style="display: contents;">
|
||||
<li>Supermarket 1</li>
|
||||
<li>Supermarket 2</li>
|
||||
</ul>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
// __h__e__l__l__o__ __!__ __s__e__e__ __!__
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13
|
||||
|
||||
var IDs = [ "hypertext", "hypertext2" ];
|
||||
var IDs = [ "hypertext", "hypertext2", "ht_displaycontents" ];
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////
|
||||
// characterCount
|
||||
|
@ -123,6 +123,10 @@
|
|||
|
||||
<div id="hypertext">hello <a>friend</a> see <img src="about:blank"></div>
|
||||
<div id="hypertext2">hello <a>friend</a> see <input></div>
|
||||
<div id="ht_displaycontents">hello <a>friend</a> see <ul id="ul" style="display: contents;">
|
||||
<li>Supermarket 1</li>
|
||||
<li>Supermarket 2</li>
|
||||
</ul></div>
|
||||
<ol id="list">
|
||||
<li id="listitem">foo</li>
|
||||
<li id="listitemnone">bar</li>
|
||||
|
|
|
@ -25,6 +25,7 @@ skip-if = true # Bug 561508
|
|||
[test_combobox.xul]
|
||||
[test_cssflexbox.html]
|
||||
[test_cssoverflow.html]
|
||||
[test_display_contents.html]
|
||||
[test_dochierarchy.html]
|
||||
[test_dockids.html]
|
||||
[test_filectrl.html]
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>CSS display:contents tests</title>
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../role.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function doTest() {
|
||||
let tree =
|
||||
{ LIST: [
|
||||
{ LISTITEM: [
|
||||
{ STATICTEXT: [] },
|
||||
{ TEXT_LEAF: [] }
|
||||
]},
|
||||
{ LISTITEM: [
|
||||
{ STATICTEXT: [] },
|
||||
{ TEXT_LEAF: [] }
|
||||
]},
|
||||
] };
|
||||
testAccessibleTree("ul", tree);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<ul id="ul" style="display: contents;">
|
||||
<li>Supermarket 1</li>
|
||||
<li>Supermarket 2</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
|
@ -573,7 +573,7 @@ XULMenubarAccessible::AreItemsOperable() const
|
|||
}
|
||||
|
||||
Accessible*
|
||||
XULMenubarAccessible::CurrentItem()
|
||||
XULMenubarAccessible::CurrentItem() const
|
||||
{
|
||||
nsMenuBarFrame* menuBarFrame = do_QueryFrame(GetFrame());
|
||||
if (menuBarFrame) {
|
||||
|
@ -587,7 +587,7 @@ XULMenubarAccessible::CurrentItem()
|
|||
}
|
||||
|
||||
void
|
||||
XULMenubarAccessible::SetCurrentItem(Accessible* aItem)
|
||||
XULMenubarAccessible::SetCurrentItem(const Accessible* aItem)
|
||||
{
|
||||
NS_ERROR("XULMenubarAccessible::SetCurrentItem not implemented");
|
||||
}
|
||||
|
|
|
@ -108,8 +108,8 @@ public:
|
|||
// Widget
|
||||
virtual bool IsActiveWidget() const override;
|
||||
virtual bool AreItemsOperable() const override;
|
||||
virtual Accessible* CurrentItem() override;
|
||||
virtual void SetCurrentItem(Accessible* aItem) override;
|
||||
virtual Accessible* CurrentItem() const override;
|
||||
virtual void SetCurrentItem(const Accessible* aItem) override;
|
||||
|
||||
protected:
|
||||
// Accessible
|
||||
|
|
|
@ -211,7 +211,7 @@ XULSelectControlAccessible::SelectAll()
|
|||
// XULSelectControlAccessible: Widgets
|
||||
|
||||
Accessible*
|
||||
XULSelectControlAccessible::CurrentItem()
|
||||
XULSelectControlAccessible::CurrentItem() const
|
||||
{
|
||||
if (!mSelectControl)
|
||||
return nullptr;
|
||||
|
@ -238,7 +238,7 @@ XULSelectControlAccessible::CurrentItem()
|
|||
}
|
||||
|
||||
void
|
||||
XULSelectControlAccessible::SetCurrentItem(Accessible* aItem)
|
||||
XULSelectControlAccessible::SetCurrentItem(const Accessible* aItem)
|
||||
{
|
||||
if (!mSelectControl)
|
||||
return;
|
||||
|
|
|
@ -36,8 +36,8 @@ public:
|
|||
virtual bool UnselectAll() override;
|
||||
|
||||
// Widgets
|
||||
virtual Accessible* CurrentItem() override;
|
||||
virtual void SetCurrentItem(Accessible* aItem) override;
|
||||
virtual Accessible* CurrentItem() const override;
|
||||
virtual void SetCurrentItem(const Accessible* aItem) override;
|
||||
|
||||
protected:
|
||||
// nsIDOMXULMultiSelectControlElement inherits from this, so we'll always have
|
||||
|
|
|
@ -222,7 +222,7 @@ XULTreeAccessible::ChildAtPoint(int32_t aX, int32_t aY,
|
|||
// XULTreeAccessible: SelectAccessible
|
||||
|
||||
Accessible*
|
||||
XULTreeAccessible::CurrentItem()
|
||||
XULTreeAccessible::CurrentItem() const
|
||||
{
|
||||
if (!mTreeView)
|
||||
return nullptr;
|
||||
|
@ -240,7 +240,7 @@ XULTreeAccessible::CurrentItem()
|
|||
}
|
||||
|
||||
void
|
||||
XULTreeAccessible::SetCurrentItem(Accessible* aItem)
|
||||
XULTreeAccessible::SetCurrentItem(const Accessible* aItem)
|
||||
{
|
||||
NS_ERROR("XULTreeAccessible::SetCurrentItem not implemented");
|
||||
}
|
||||
|
|
|
@ -64,8 +64,8 @@ public:
|
|||
virtual bool IsWidget() const override;
|
||||
virtual bool IsActiveWidget() const override;
|
||||
virtual bool AreItemsOperable() const override;
|
||||
virtual Accessible* CurrentItem() override;
|
||||
virtual void SetCurrentItem(Accessible* aItem) override;
|
||||
virtual Accessible* CurrentItem() const override;
|
||||
virtual void SetCurrentItem(const Accessible* aItem) override;
|
||||
|
||||
virtual Accessible* ContainerWidget() const override;
|
||||
|
||||
|
|
|
@ -97,14 +97,6 @@ $(addprefix install-,$(INSTALL_MANIFESTS)): install-%: $(addprefix $(TOPOBJDIR)/
|
|||
# Below is a set of additional dependencies and variables used to build things
|
||||
# that are not supported by data in moz.build.
|
||||
|
||||
# The xpidl target in config/makefiles/xpidl requires the install manifest for
|
||||
# dist/idl to have been processed. When using the hybrid
|
||||
# FasterMake/RecursiveMake backend, this dependency is handled in the top-level
|
||||
# Makefile.
|
||||
ifndef FASTER_RECURSIVE_MAKE
|
||||
$(TOPOBJDIR)/config/makefiles/xpidl/xpidl: $(TOPOBJDIR)/install-dist_idl
|
||||
endif
|
||||
|
||||
$(TOPOBJDIR)/build/application.ini: $(TOPOBJDIR)/buildid.h $(TOPOBJDIR)/source-repo.h
|
||||
|
||||
# The manifest of allowed system add-ons should be re-built when using
|
||||
|
|
|
@ -41,7 +41,8 @@ code_gen_deps := $(topsrcdir)/xpcom/reflect/xptinfo/perfecthash.py
|
|||
$(PYTHON_PATH) $(PLY_INCLUDE) -I$(topsrcdir)/xpcom/idl-parser -I$(DEPTH)/xpcom/idl-parser/xpidl \
|
||||
$(process_py) --cache-dir $(DEPTH)/xpcom/idl-parser/xpidl --depsdir $(idl_deps_dir) \
|
||||
--bindings-conf $(topsrcdir)/dom/bindings/Bindings.conf \
|
||||
$(dist_idl_dir) $(dist_include_dir) $(dist_xpcrs_dir) $(@D) \
|
||||
$(foreach dir,$(all_idl_dirs),-I $(dir)) \
|
||||
$(dist_include_dir) $(dist_xpcrs_dir) $(@D) \
|
||||
$(basename $(notdir $@)) $($(basename $(notdir $@))_deps)
|
||||
# When some IDL is added or removed, if the actual IDL file was already, or
|
||||
# still is, in the tree, simple dependencies can't detect that the XPT needs
|
||||
|
@ -75,7 +76,6 @@ $(generated_file): $(xpt_files) $(code_gen_py) $(code_gen_deps)
|
|||
|
||||
define xpt_deps
|
||||
$(1): $(call mkdir_deps,$(dir $(1)))
|
||||
$(1): $(addsuffix .idl,$(addprefix $(dist_idl_dir)/,$($(basename $(notdir $(1)))_deps)))
|
||||
ifneq ($($(basename $(notdir $(1)))_deps),$($(basename $(notdir $(1)))_deps_built))
|
||||
$(1): FORCE
|
||||
endif
|
||||
|
|
|
@ -546,7 +546,6 @@ previewers.Object = [
|
|||
obj.class != "CSSRuleList" &&
|
||||
obj.class != "MediaList" &&
|
||||
obj.class != "StyleSheetList" &&
|
||||
obj.class != "CSSValueList" &&
|
||||
obj.class != "NamedNodeMap" &&
|
||||
obj.class != "FileList" &&
|
||||
obj.class != "NodeList") {
|
||||
|
|
|
@ -108,6 +108,7 @@ method console.group
|
|||
method console.groupCollapsed
|
||||
method console.groupEnd
|
||||
method console.time
|
||||
method console.timeLog
|
||||
method console.timeEnd
|
||||
method console.exception
|
||||
method console.timeStamp
|
||||
|
|
|
@ -113,7 +113,7 @@ WindowNamedPropertiesHandler::getOwnPropDescriptor(JSContext* aCx,
|
|||
// global scope is still allowed, since |var| only looks up |own|
|
||||
// properties. But unqualified shadowing will fail, per-spec.
|
||||
JS::Rooted<JS::Value> v(aCx);
|
||||
if (!WrapObject(aCx, childWin, &v)) {
|
||||
if (!ToJSValue(aCx, nsGlobalWindowOuter::Cast(childWin), &v)) {
|
||||
return false;
|
||||
}
|
||||
FillPropertyDescriptor(aDesc, aProxy, 0, v);
|
||||
|
@ -128,27 +128,25 @@ WindowNamedPropertiesHandler::getOwnPropDescriptor(JSContext* aCx,
|
|||
}
|
||||
nsHTMLDocument* document = static_cast<nsHTMLDocument*>(htmlDoc.get());
|
||||
|
||||
JS::Rooted<JS::Value> v(aCx);
|
||||
Element* element = document->GetElementById(str);
|
||||
if (element) {
|
||||
JS::Rooted<JS::Value> v(aCx);
|
||||
if (!WrapObject(aCx, element, &v)) {
|
||||
if (!ToJSValue(aCx, element, &v)) {
|
||||
return false;
|
||||
}
|
||||
FillPropertyDescriptor(aDesc, aProxy, 0, v);
|
||||
return true;
|
||||
}
|
||||
|
||||
nsWrapperCache* cache;
|
||||
nsISupports* result = document->ResolveName(str, &cache);
|
||||
if (!result) {
|
||||
return true;
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> v(aCx);
|
||||
if (!WrapObject(aCx, result, cache, nullptr, &v)) {
|
||||
ErrorResult rv;
|
||||
bool found = document->ResolveName(aCx, str, &v, rv);
|
||||
if (rv.MaybeSetPendingException(aCx)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (found) {
|
||||
FillPropertyDescriptor(aDesc, aProxy, 0, v);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -80,7 +80,6 @@ EXPORTS += [
|
|||
'nsIDocument.h',
|
||||
'nsIDocumentInlines.h',
|
||||
'nsIDocumentObserver.h',
|
||||
'nsIDOMClassInfo.h',
|
||||
'nsIGlobalObject.h',
|
||||
'nsImageLoadingContent.h',
|
||||
'nsIMutationObserver.h',
|
||||
|
|
|
@ -2848,9 +2848,7 @@ const InterfaceShimEntry kInterfaceShimMap[] =
|
|||
{ { "nsIXMLHttpRequest", "XMLHttpRequest" },
|
||||
{ "nsIDOMDOMException", "DOMException" },
|
||||
{ "nsIDOMNode", "Node" },
|
||||
{ "nsIDOMCSSPrimitiveValue", "CSSPrimitiveValue" },
|
||||
{ "nsIDOMCSSRule", "CSSRule" },
|
||||
{ "nsIDOMCSSValue", "CSSValue" },
|
||||
{ "nsIDOMEvent", "Event" },
|
||||
{ "nsIDOMNSEvent", "Event" },
|
||||
{ "nsIDOMKeyEvent", "KeyEvent" },
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsIDOMClassInfo_h___
|
||||
#define nsIDOMClassInfo_h___
|
||||
|
||||
#include "nsIXPCScriptable.h"
|
||||
|
||||
#define DOM_BASE_SCRIPTABLE_FLAGS \
|
||||
(XPC_SCRIPTABLE_USE_JSSTUB_FOR_ADDPROPERTY | \
|
||||
XPC_SCRIPTABLE_USE_JSSTUB_FOR_DELPROPERTY | \
|
||||
XPC_SCRIPTABLE_ALLOW_PROP_MODS_TO_PROTOTYPE | \
|
||||
XPC_SCRIPTABLE_DONT_ASK_INSTANCE_FOR_SCRIPTABLE | \
|
||||
XPC_SCRIPTABLE_DONT_REFLECT_INTERFACE_NAMES)
|
||||
|
||||
#define DEFAULT_SCRIPTABLE_FLAGS \
|
||||
(DOM_BASE_SCRIPTABLE_FLAGS | \
|
||||
XPC_SCRIPTABLE_WANT_RESOLVE | \
|
||||
XPC_SCRIPTABLE_WANT_PRECREATE)
|
||||
|
||||
#define DOM_DEFAULT_SCRIPTABLE_FLAGS \
|
||||
(DEFAULT_SCRIPTABLE_FLAGS | \
|
||||
XPC_SCRIPTABLE_DONT_ENUM_QUERY_INTERFACE | \
|
||||
XPC_SCRIPTABLE_CLASSINFO_INTERFACES_ONLY)
|
||||
|
||||
#endif /* nsIDOMClassInfo_h___ */
|
|
@ -2140,12 +2140,6 @@ ToSupports(nsINode* aPointer)
|
|||
return aPointer;
|
||||
}
|
||||
|
||||
inline nsISupports*
|
||||
ToCanonicalSupports(nsINode* aPointer)
|
||||
{
|
||||
return aPointer;
|
||||
}
|
||||
|
||||
// Some checks are faster to do on nsIContent or Element than on
|
||||
// nsINode, so spit out FromNode versions taking those types too.
|
||||
#define NS_IMPL_FROMNODE_GENERIC(_class, _check, _const) \
|
||||
|
|
|
@ -586,12 +586,6 @@ protected:
|
|||
bool mCalledByJS : 1;
|
||||
};
|
||||
|
||||
inline nsISupports*
|
||||
ToCanonicalSupports(nsRange* aRange)
|
||||
{
|
||||
return static_cast<nsIDOMRange*>(aRange);
|
||||
}
|
||||
|
||||
inline nsISupports*
|
||||
ToSupports(nsRange* aRange)
|
||||
{
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include "mozilla/dom/BatteryManagerBinding.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIDOMClassInfo.h"
|
||||
#include "nsIDocument.h"
|
||||
|
||||
/**
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include "nsIXPConnect.h"
|
||||
#include "nsJSUtils.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "qsObjectHelper.h"
|
||||
#include "xpcObjectHelper.h"
|
||||
#include "xpcpublic.h"
|
||||
#include "nsIVariant.h"
|
||||
#include "mozilla/dom/FakeString.h"
|
||||
|
@ -1324,7 +1324,7 @@ HandleNewBindingWrappingFailure(JSContext* cx, JS::Handle<JSObject*> scope,
|
|||
return false;
|
||||
}
|
||||
|
||||
qsObjectHelper helper(value, GetWrapperCache(value));
|
||||
xpcObjectHelper helper(value, GetWrapperCache(value));
|
||||
return NativeInterface2JSObjectAndThrowIfFailed(cx, scope, rval,
|
||||
helper, nullptr, true);
|
||||
}
|
||||
|
@ -1558,7 +1558,7 @@ WrapObject(JSContext* cx, T* p, nsWrapperCache* cache, const nsIID* iid,
|
|||
{
|
||||
if (xpc_FastGetCachedWrapper(cx, cache, rval))
|
||||
return true;
|
||||
qsObjectHelper helper(p, cache);
|
||||
xpcObjectHelper helper(ToSupports(p), cache);
|
||||
JS::Rooted<JSObject*> scope(cx, JS::CurrentGlobalOrNull(cx));
|
||||
return XPCOMObjectToJsval(cx, scope, helper, iid, true, rval);
|
||||
}
|
||||
|
@ -1658,7 +1658,7 @@ template<typename T>
|
|||
static inline JSObject*
|
||||
WrapNativeISupports(JSContext* cx, T* p, nsWrapperCache* cache)
|
||||
{
|
||||
qsObjectHelper helper(ToSupports(p), cache);
|
||||
xpcObjectHelper helper(ToSupports(p), cache);
|
||||
JS::Rooted<JSObject*> scope(cx, JS::CurrentGlobalOrNull(cx));
|
||||
JS::Rooted<JS::Value> v(cx);
|
||||
return XPCOMObjectToJsval(cx, scope, helper, nullptr, false, &v) ?
|
||||
|
|
|
@ -192,10 +192,6 @@ DOMInterfaces = {
|
|||
'wrapperCache': False
|
||||
},
|
||||
|
||||
'CSSPrimitiveValue': {
|
||||
'nativeType': 'nsROCSSPrimitiveValue',
|
||||
},
|
||||
|
||||
'CSSRule': {
|
||||
'concrete': False,
|
||||
'nativeType': 'mozilla::css::Rule'
|
||||
|
@ -214,14 +210,6 @@ DOMInterfaces = {
|
|||
'binaryNames': { 'ownerRule': 'DOMOwnerRule' },
|
||||
},
|
||||
|
||||
'CSSValue': {
|
||||
'concrete': False
|
||||
},
|
||||
|
||||
'CSSValueList': {
|
||||
'nativeType': 'nsDOMCSSValueList'
|
||||
},
|
||||
|
||||
'DedicatedWorkerGlobalScope': {
|
||||
'headerFile': 'mozilla/dom/WorkerScope.h',
|
||||
},
|
||||
|
@ -718,10 +706,6 @@ DOMInterfaces = {
|
|||
}
|
||||
},
|
||||
|
||||
'Rect': {
|
||||
'nativeType': 'nsDOMCSSRect',
|
||||
},
|
||||
|
||||
'Request': {
|
||||
'binaryNames': {
|
||||
'headers': 'headers_',
|
||||
|
@ -736,10 +720,6 @@ DOMInterfaces = {
|
|||
'clone', 'cloneUnfiltered' ],
|
||||
},
|
||||
|
||||
'RGBColor': {
|
||||
'nativeType': 'nsDOMCSSRGBColor',
|
||||
},
|
||||
|
||||
'RTCDataChannel': {
|
||||
'nativeType': 'nsDOMDataChannel',
|
||||
},
|
||||
|
|
|
@ -187,7 +187,7 @@ ToJSValue(JSContext* aCx,
|
|||
// Make sure we're called in a compartment
|
||||
MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
|
||||
|
||||
qsObjectHelper helper(ToSupports(&aArgument), nullptr);
|
||||
xpcObjectHelper helper(ToSupports(&aArgument));
|
||||
JS::Rooted<JSObject*> scope(aCx, JS::CurrentGlobalOrNull(aCx));
|
||||
return XPCOMObjectToJsval(aCx, scope, helper, nullptr, true, aValue);
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ ClientHandle::StartOp(const ClientOpConstructorArgs& aArgs,
|
|||
|
||||
MaybeExecute([aArgs, kungFuGrip, aRejectCallback,
|
||||
resolve = Move(aResolveCallback)] (ClientHandleChild* aActor) {
|
||||
MOZ_RELEASE_ASSERT(aActor);
|
||||
ClientHandleOpChild* actor =
|
||||
new ClientHandleOpChild(kungFuGrip, aArgs, Move(resolve),
|
||||
Move(aRejectCallback));
|
||||
|
@ -57,6 +58,7 @@ ClientHandle::StartOp(const ClientOpConstructorArgs& aArgs,
|
|||
return;
|
||||
}
|
||||
}, [aRejectCallback] {
|
||||
MOZ_RELEASE_ASSERT(aRejectCallback);
|
||||
aRejectCallback(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -39,9 +39,9 @@ ClientHandleOpChild::ClientHandleOpChild(ClientHandle* aClientHandle,
|
|||
, mResolveCallback(Move(aResolveCallback))
|
||||
, mRejectCallback(Move(aRejectCallback))
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(mClientHandle);
|
||||
MOZ_DIAGNOSTIC_ASSERT(mResolveCallback);
|
||||
MOZ_DIAGNOSTIC_ASSERT(mRejectCallback);
|
||||
MOZ_RELEASE_ASSERT(mClientHandle);
|
||||
MOZ_RELEASE_ASSERT(mResolveCallback);
|
||||
MOZ_RELEASE_ASSERT(mRejectCallback);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -27,8 +27,13 @@ using mozilla::ipc::PrincipalInfo;
|
|||
|
||||
namespace {
|
||||
|
||||
uint32_t kBadThreadLocalIndex = -1;
|
||||
const uint32_t kBadThreadLocalIndex = -1;
|
||||
const uint32_t kThreadLocalMagic1 = 0x8d57eea6;
|
||||
const uint32_t kThreadLocalMagic2 = 0x59f375c9;
|
||||
uint32_t sClientManagerThreadLocalMagic1 = kThreadLocalMagic1;
|
||||
uint32_t sClientManagerThreadLocalIndex = kBadThreadLocalIndex;
|
||||
uint32_t sClientManagerThreadLocalMagic2 = kThreadLocalMagic2;
|
||||
uint32_t sClientManagerThreadLocalIndexDuplicate = kBadThreadLocalIndex;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
@ -79,7 +84,11 @@ ClientManager::~ClientManager()
|
|||
|
||||
Shutdown();
|
||||
|
||||
MOZ_DIAGNOSTIC_ASSERT(this == PR_GetThreadPrivate(sClientManagerThreadLocalIndex));
|
||||
MOZ_RELEASE_ASSERT(sClientManagerThreadLocalMagic1 == kThreadLocalMagic1);
|
||||
MOZ_RELEASE_ASSERT(sClientManagerThreadLocalMagic2 == kThreadLocalMagic2);
|
||||
MOZ_RELEASE_ASSERT(sClientManagerThreadLocalIndex != kBadThreadLocalIndex);
|
||||
MOZ_RELEASE_ASSERT(sClientManagerThreadLocalIndex == sClientManagerThreadLocalIndexDuplicate);
|
||||
MOZ_RELEASE_ASSERT(this == PR_GetThreadPrivate(sClientManagerThreadLocalIndex));
|
||||
|
||||
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
|
||||
PRStatus status =
|
||||
|
@ -185,7 +194,10 @@ ClientManager::StartOp(const ClientOpConstructorArgs& aArgs,
|
|||
already_AddRefed<ClientManager>
|
||||
ClientManager::GetOrCreateForCurrentThread()
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(sClientManagerThreadLocalIndex != kBadThreadLocalIndex);
|
||||
MOZ_RELEASE_ASSERT(sClientManagerThreadLocalMagic1 == kThreadLocalMagic1);
|
||||
MOZ_RELEASE_ASSERT(sClientManagerThreadLocalMagic2 == kThreadLocalMagic2);
|
||||
MOZ_RELEASE_ASSERT(sClientManagerThreadLocalIndex != kBadThreadLocalIndex);
|
||||
MOZ_RELEASE_ASSERT(sClientManagerThreadLocalIndex == sClientManagerThreadLocalIndexDuplicate);
|
||||
RefPtr<ClientManager> cm =
|
||||
static_cast<ClientManager*>(PR_GetThreadPrivate(sClientManagerThreadLocalIndex));
|
||||
|
||||
|
@ -199,7 +211,7 @@ ClientManager::GetOrCreateForCurrentThread()
|
|||
MOZ_DIAGNOSTIC_ASSERT(status == PR_SUCCESS);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(cm);
|
||||
MOZ_RELEASE_ASSERT(cm);
|
||||
return cm.forget();
|
||||
}
|
||||
|
||||
|
@ -216,12 +228,21 @@ void
|
|||
ClientManager::Startup()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
MOZ_RELEASE_ASSERT(sClientManagerThreadLocalMagic1 == kThreadLocalMagic1);
|
||||
MOZ_RELEASE_ASSERT(sClientManagerThreadLocalMagic2 == kThreadLocalMagic2);
|
||||
MOZ_RELEASE_ASSERT(sClientManagerThreadLocalIndex == kBadThreadLocalIndex);
|
||||
MOZ_RELEASE_ASSERT(sClientManagerThreadLocalIndex == sClientManagerThreadLocalIndexDuplicate);
|
||||
|
||||
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
|
||||
PRStatus status =
|
||||
#endif
|
||||
PR_NewThreadPrivateIndex(&sClientManagerThreadLocalIndex, nullptr);
|
||||
MOZ_DIAGNOSTIC_ASSERT(status == PR_SUCCESS);
|
||||
|
||||
MOZ_RELEASE_ASSERT(sClientManagerThreadLocalIndex != kBadThreadLocalIndex);
|
||||
sClientManagerThreadLocalIndexDuplicate = sClientManagerThreadLocalIndex;
|
||||
|
||||
ClientPrefsInit();
|
||||
}
|
||||
|
||||
|
|
|
@ -17,25 +17,43 @@ namespace dom {
|
|||
template <typename ActorType>
|
||||
class ClientThing
|
||||
{
|
||||
static const uint32_t kMagic1 = 0xC9FE2C9C;
|
||||
static const uint32_t kMagic2 = 0x832072D4;
|
||||
|
||||
ActorType* mActor;
|
||||
uint32_t mMagic1;
|
||||
uint32_t mMagic2;
|
||||
bool mShutdown;
|
||||
|
||||
protected:
|
||||
ClientThing()
|
||||
: mActor(nullptr)
|
||||
, mMagic1(kMagic1)
|
||||
, mMagic2(kMagic2)
|
||||
, mShutdown(false)
|
||||
{
|
||||
}
|
||||
|
||||
~ClientThing()
|
||||
{
|
||||
AssertIsValid();
|
||||
ShutdownThing();
|
||||
mMagic1 = 0;
|
||||
mMagic2 = 0;
|
||||
}
|
||||
|
||||
void
|
||||
AssertIsValid() const
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(mMagic1 == kMagic1);
|
||||
MOZ_RELEASE_ASSERT(mMagic2 == kMagic2);
|
||||
}
|
||||
|
||||
// Return the current actor.
|
||||
ActorType*
|
||||
GetActor() const
|
||||
{
|
||||
AssertIsValid();
|
||||
return mActor;
|
||||
}
|
||||
|
||||
|
@ -43,6 +61,7 @@ protected:
|
|||
bool
|
||||
IsShutdown() const
|
||||
{
|
||||
AssertIsValid();
|
||||
return mShutdown;
|
||||
}
|
||||
|
||||
|
@ -52,6 +71,7 @@ protected:
|
|||
MaybeExecute(const Callable& aSuccess,
|
||||
const std::function<void()>& aFailure = []{})
|
||||
{
|
||||
AssertIsValid();
|
||||
if (mShutdown) {
|
||||
aFailure();
|
||||
return;
|
||||
|
@ -67,6 +87,7 @@ protected:
|
|||
void
|
||||
ActivateThing(ActorType* aActor)
|
||||
{
|
||||
AssertIsValid();
|
||||
MOZ_DIAGNOSTIC_ASSERT(aActor);
|
||||
MOZ_DIAGNOSTIC_ASSERT(!mActor);
|
||||
MOZ_DIAGNOSTIC_ASSERT(!mShutdown);
|
||||
|
@ -78,6 +99,7 @@ protected:
|
|||
void
|
||||
ShutdownThing()
|
||||
{
|
||||
AssertIsValid();
|
||||
if (mShutdown) {
|
||||
return;
|
||||
}
|
||||
|
@ -106,6 +128,7 @@ public:
|
|||
void
|
||||
RevokeActor(ActorType* aActor)
|
||||
{
|
||||
AssertIsValid();
|
||||
MOZ_DIAGNOSTIC_ASSERT(mActor);
|
||||
MOZ_DIAGNOSTIC_ASSERT(mActor == aActor);
|
||||
mActor->RevokeOwner(this);
|
||||
|
|
|
@ -94,8 +94,8 @@ public:
|
|||
, mTimeStamp(JS_Now() / PR_USEC_PER_MSEC)
|
||||
, mStartTimerValue(0)
|
||||
, mStartTimerStatus(Console::eTimerUnknown)
|
||||
, mStopTimerDuration(0)
|
||||
, mStopTimerStatus(Console::eTimerUnknown)
|
||||
, mLogTimerDuration(0)
|
||||
, mLogTimerStatus(Console::eTimerUnknown)
|
||||
, mCountValue(MAX_PAGE_COUNTERS)
|
||||
, mIDType(eUnknown)
|
||||
, mOuterIDNumber(0)
|
||||
|
@ -221,14 +221,14 @@ public:
|
|||
Console::TimerStatus mStartTimerStatus;
|
||||
|
||||
// These values are set in the owning thread and they contain the duration,
|
||||
// the name and the status of the StopTimer method. If status is false,
|
||||
// the name and the status of the LogTimer method. If status is false,
|
||||
// something went wrong. They will be set on the owning thread and never
|
||||
// touched again on that thread. They will be used in order to create a
|
||||
// ConsoleTimerEnd dictionary. This members are set when
|
||||
// console.timeEnd() is called.
|
||||
double mStopTimerDuration;
|
||||
nsString mStopTimerLabel;
|
||||
Console::TimerStatus mStopTimerStatus;
|
||||
// ConsoleTimerLogOrEnd dictionary. This members are set when
|
||||
// console.timeEnd() or console.timeLog() are called.
|
||||
double mLogTimerDuration;
|
||||
nsString mLogTimerLabel;
|
||||
Console::TimerStatus mLogTimerStatus;
|
||||
|
||||
// These 2 values are set by IncreaseCounter on the owning thread and they are
|
||||
// used CreateCounterValue. These members are set when console.count() is
|
||||
|
@ -1231,30 +1231,42 @@ Console::GroupEnd(const GlobalObject& aGlobal)
|
|||
/* static */ void
|
||||
Console::Time(const GlobalObject& aGlobal, const nsAString& aLabel)
|
||||
{
|
||||
StringMethod(aGlobal, aLabel, MethodTime, NS_LITERAL_STRING("time"));
|
||||
StringMethod(aGlobal, aLabel, Sequence<JS::Value>(), MethodTime,
|
||||
NS_LITERAL_STRING("time"));
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
Console::TimeEnd(const GlobalObject& aGlobal, const nsAString& aLabel)
|
||||
{
|
||||
StringMethod(aGlobal, aLabel, MethodTimeEnd, NS_LITERAL_STRING("timeEnd"));
|
||||
StringMethod(aGlobal, aLabel, Sequence<JS::Value>(), MethodTimeEnd,
|
||||
NS_LITERAL_STRING("timeEnd"));
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
Console::TimeLog(const GlobalObject& aGlobal, const nsAString& aLabel,
|
||||
const Sequence<JS::Value>& aData)
|
||||
{
|
||||
StringMethod(aGlobal, aLabel, aData, MethodTimeLog,
|
||||
NS_LITERAL_STRING("timeLog"));
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
Console::StringMethod(const GlobalObject& aGlobal, const nsAString& aLabel,
|
||||
MethodName aMethodName, const nsAString& aMethodString)
|
||||
const Sequence<JS::Value>& aData, MethodName aMethodName,
|
||||
const nsAString& aMethodString)
|
||||
{
|
||||
RefPtr<Console> console = GetConsole(aGlobal);
|
||||
if (!console) {
|
||||
return;
|
||||
}
|
||||
|
||||
console->StringMethodInternal(aGlobal.Context(), aLabel, aMethodName,
|
||||
console->StringMethodInternal(aGlobal.Context(), aLabel, aData, aMethodName,
|
||||
aMethodString);
|
||||
}
|
||||
|
||||
void
|
||||
Console::StringMethodInternal(JSContext* aCx, const nsAString& aLabel,
|
||||
const Sequence<JS::Value>& aData,
|
||||
MethodName aMethodName,
|
||||
const nsAString& aMethodString)
|
||||
{
|
||||
|
@ -1272,6 +1284,12 @@ Console::StringMethodInternal(JSContext* aCx, const nsAString& aLabel,
|
|||
return;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < aData.Length(); ++i) {
|
||||
if (!data.AppendElement(aData[i], fallible)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
MethodInternal(aCx, aMethodName, aMethodString, data);
|
||||
}
|
||||
|
||||
|
@ -1422,7 +1440,8 @@ Console::Assert(const GlobalObject& aGlobal, bool aCondition,
|
|||
/* static */ void
|
||||
Console::Count(const GlobalObject& aGlobal, const nsAString& aLabel)
|
||||
{
|
||||
StringMethod(aGlobal, aLabel, MethodCount, NS_LITERAL_STRING("count"));
|
||||
StringMethod(aGlobal, aLabel, Sequence<JS::Value>(), MethodCount,
|
||||
NS_LITERAL_STRING("count"));
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
@ -1573,8 +1592,9 @@ Console::MethodInternal(JSContext* aCx, MethodName aMethodName,
|
|||
|
||||
DOMHighResTimeStamp monotonicTimer;
|
||||
|
||||
// Monotonic timer for 'time' and 'timeEnd'
|
||||
// Monotonic timer for 'time', 'timeLog' and 'timeEnd'
|
||||
if ((aMethodName == MethodTime ||
|
||||
aMethodName == MethodTimeLog ||
|
||||
aMethodName == MethodTimeEnd ||
|
||||
aMethodName == MethodTimeStamp) &&
|
||||
!MonotonicTimer(aCx, aMethodName, aData, &monotonicTimer)) {
|
||||
|
@ -1589,10 +1609,19 @@ Console::MethodInternal(JSContext* aCx, MethodName aMethodName,
|
|||
}
|
||||
|
||||
else if (aMethodName == MethodTimeEnd && !aData.IsEmpty()) {
|
||||
callData->mStopTimerStatus = StopTimer(aCx, aData[0],
|
||||
callData->mLogTimerStatus = LogTimer(aCx, aData[0],
|
||||
monotonicTimer,
|
||||
callData->mStopTimerLabel,
|
||||
&callData->mStopTimerDuration);
|
||||
callData->mLogTimerLabel,
|
||||
&callData->mLogTimerDuration,
|
||||
true /* Cancel timer */);
|
||||
}
|
||||
|
||||
else if (aMethodName == MethodTimeLog && !aData.IsEmpty()) {
|
||||
callData->mLogTimerStatus = LogTimer(aCx, aData[0],
|
||||
monotonicTimer,
|
||||
callData->mLogTimerLabel,
|
||||
&callData->mLogTimerDuration,
|
||||
false /* Cancel timer */);
|
||||
}
|
||||
|
||||
else if (aMethodName == MethodCount) {
|
||||
|
@ -1863,10 +1892,11 @@ Console::PopulateConsoleNotificationInTheTargetScope(JSContext* aCx,
|
|||
aData->mStartTimerStatus);
|
||||
}
|
||||
|
||||
else if (aData->mMethodName == MethodTimeEnd && !aArguments.IsEmpty()) {
|
||||
event.mTimer = CreateStopTimerValue(aCx, aData->mStopTimerLabel,
|
||||
aData->mStopTimerDuration,
|
||||
aData->mStopTimerStatus);
|
||||
else if ((aData->mMethodName == MethodTimeEnd ||
|
||||
aData->mMethodName == MethodTimeLog) && !aArguments.IsEmpty()) {
|
||||
event.mTimer = CreateLogOrEndTimerValue(aCx, aData->mLogTimerLabel,
|
||||
aData->mLogTimerDuration,
|
||||
aData->mLogTimerStatus);
|
||||
}
|
||||
|
||||
else if (aData->mMethodName == MethodCount) {
|
||||
|
@ -2321,10 +2351,11 @@ Console::CreateStartTimerValue(JSContext* aCx, const nsAString& aTimerLabel,
|
|||
}
|
||||
|
||||
Console::TimerStatus
|
||||
Console::StopTimer(JSContext* aCx, const JS::Value& aName,
|
||||
Console::LogTimer(JSContext* aCx, const JS::Value& aName,
|
||||
DOMHighResTimeStamp aTimestamp,
|
||||
nsAString& aTimerLabel,
|
||||
double* aTimerDuration)
|
||||
double* aTimerDuration,
|
||||
bool aCancelTimer)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aTimerDuration);
|
||||
|
@ -2345,24 +2376,32 @@ Console::StopTimer(JSContext* aCx, const JS::Value& aName,
|
|||
aTimerLabel = key;
|
||||
|
||||
DOMHighResTimeStamp value = 0;
|
||||
|
||||
if (aCancelTimer) {
|
||||
if (!mTimerRegistry.Remove(key, &value)) {
|
||||
NS_WARNING("mTimerRegistry entry not found");
|
||||
return eTimerDoesntExist;
|
||||
}
|
||||
} else {
|
||||
if (!mTimerRegistry.Get(key, &value)) {
|
||||
NS_WARNING("mTimerRegistry entry not found");
|
||||
return eTimerDoesntExist;
|
||||
}
|
||||
}
|
||||
|
||||
*aTimerDuration = aTimestamp - value;
|
||||
return eTimerDone;
|
||||
}
|
||||
|
||||
JS::Value
|
||||
Console::CreateStopTimerValue(JSContext* aCx, const nsAString& aLabel,
|
||||
Console::CreateLogOrEndTimerValue(JSContext* aCx, const nsAString& aLabel,
|
||||
double aDuration, TimerStatus aStatus) const
|
||||
{
|
||||
if (aStatus != eTimerDone) {
|
||||
return CreateTimerError(aCx, aLabel, aStatus);
|
||||
}
|
||||
|
||||
RootedDictionary<ConsoleTimerEnd> timer(aCx);
|
||||
RootedDictionary<ConsoleTimerLogOrEnd> timer(aCx);
|
||||
timer.mName = aLabel;
|
||||
timer.mDuration = aDuration;
|
||||
|
||||
|
@ -2996,6 +3035,7 @@ Console::WebIDLLogLevelToInteger(ConsoleLogLevel aLevel) const
|
|||
case ConsoleLogLevel::Info: return 3;
|
||||
case ConsoleLogLevel::Clear: return 3;
|
||||
case ConsoleLogLevel::Trace: return 3;
|
||||
case ConsoleLogLevel::TimeLog: return 3;
|
||||
case ConsoleLogLevel::TimeEnd: return 3;
|
||||
case ConsoleLogLevel::Time: return 3;
|
||||
case ConsoleLogLevel::Group: return 3;
|
||||
|
@ -3033,6 +3073,7 @@ Console::InternalLogLevelToInteger(MethodName aName) const
|
|||
case MethodGroupCollapsed: return 3;
|
||||
case MethodGroupEnd: return 3;
|
||||
case MethodTime: return 3;
|
||||
case MethodTimeLog: return 3;
|
||||
case MethodTimeEnd: return 3;
|
||||
case MethodTimeStamp: return 3;
|
||||
case MethodAssert: return 3;
|
||||
|
|
|
@ -96,6 +96,10 @@ public:
|
|||
static void
|
||||
Time(const GlobalObject& aGlobal, const nsAString& aLabel);
|
||||
|
||||
static void
|
||||
TimeLog(const GlobalObject& aGlobal, const nsAString& aLabel,
|
||||
const Sequence<JS::Value>& aData);
|
||||
|
||||
static void
|
||||
TimeEnd(const GlobalObject& aGlobal, const nsAString& aLabel);
|
||||
|
||||
|
@ -159,6 +163,7 @@ private:
|
|||
MethodGroupCollapsed,
|
||||
MethodGroupEnd,
|
||||
MethodTime,
|
||||
MethodTimeLog,
|
||||
MethodTimeEnd,
|
||||
MethodTimeStamp,
|
||||
MethodAssert,
|
||||
|
@ -193,10 +198,12 @@ private:
|
|||
|
||||
static void
|
||||
StringMethod(const GlobalObject& aGlobal, const nsAString& aLabel,
|
||||
MethodName aMethodName, const nsAString& aMethodString);
|
||||
const Sequence<JS::Value>& aData, MethodName aMethodName,
|
||||
const nsAString& aMethodString);
|
||||
|
||||
void
|
||||
StringMethodInternal(JSContext* aCx, const nsAString& aLabel,
|
||||
const Sequence<JS::Value>& aData,
|
||||
MethodName aMethodName, const nsAString& aMethodString);
|
||||
|
||||
// This method must receive aCx and aArguments in the same JSCompartment.
|
||||
|
@ -317,9 +324,9 @@ private:
|
|||
CreateStartTimerValue(JSContext* aCx, const nsAString& aTimerLabel,
|
||||
TimerStatus aTimerStatus) const;
|
||||
|
||||
// StopTimer follows the same pattern as StartTimer: it runs on the
|
||||
// LogTimer follows the same pattern as StartTimer: it runs on the
|
||||
// owning thread and populates aTimerLabel and aTimerDuration, used by
|
||||
// CreateStopTimerValue.
|
||||
// CreateLogOrEndTimerValue.
|
||||
// * aCx - the JSContext rooting aName.
|
||||
// * aName - this is (should be) the name of the timer as JS::Value.
|
||||
// * aTimestamp - the monotonicTimer for this context taken from
|
||||
|
@ -328,20 +335,22 @@ private:
|
|||
// string.
|
||||
// * aTimerDuration - the difference between aTimestamp and when the timer
|
||||
// started (see StartTimer).
|
||||
// * aCancelTimer - if true, the timer is removed from the table.
|
||||
TimerStatus
|
||||
StopTimer(JSContext* aCx, const JS::Value& aName,
|
||||
LogTimer(JSContext* aCx, const JS::Value& aName,
|
||||
DOMHighResTimeStamp aTimestamp,
|
||||
nsAString& aTimerLabel,
|
||||
double* aTimerDuration);
|
||||
double* aTimerDuration,
|
||||
bool aCancelTimer);
|
||||
|
||||
// This method generates a ConsoleTimerEnd dictionary exposed as JS::Value, or
|
||||
// a ConsoleTimerError dictionary if aTimerStatus is false. See StopTimer.
|
||||
// a ConsoleTimerError dictionary if aTimerStatus is false. See LogTimer.
|
||||
// * aCx - this is the context that will root the returned value.
|
||||
// * aTimerLabel - this label must be what StopTimer received as aTimerLabel.
|
||||
// * aTimerDuration - this is what StopTimer received as aTimerDuration
|
||||
// * aTimerStatus - the return value of StopTimer.
|
||||
// * aTimerLabel - this label must be what LogTimer received as aTimerLabel.
|
||||
// * aTimerDuration - this is what LogTimer received as aTimerDuration
|
||||
// * aTimerStatus - the return value of LogTimer.
|
||||
JS::Value
|
||||
CreateStopTimerValue(JSContext* aCx, const nsAString& aTimerLabel,
|
||||
CreateLogOrEndTimerValue(JSContext* aCx, const nsAString& aTimerLabel,
|
||||
double aTimerDuration,
|
||||
TimerStatus aTimerStatus) const;
|
||||
|
||||
|
|
|
@ -147,14 +147,24 @@ ConsoleInstance::GroupEnd(JSContext* aCx)
|
|||
void
|
||||
ConsoleInstance::Time(JSContext* aCx, const nsAString& aLabel)
|
||||
{
|
||||
mConsole->StringMethodInternal(aCx, aLabel, Console::MethodTime,
|
||||
mConsole->StringMethodInternal(aCx, aLabel, Sequence<JS::Value>(),
|
||||
Console::MethodTime,
|
||||
NS_LITERAL_STRING("time"));
|
||||
}
|
||||
|
||||
void
|
||||
ConsoleInstance::TimeLog(JSContext* aCx, const nsAString& aLabel,
|
||||
const Sequence<JS::Value>& aData)
|
||||
{
|
||||
mConsole->StringMethodInternal(aCx, aLabel, aData, Console::MethodTimeLog,
|
||||
NS_LITERAL_STRING("timeLog"));
|
||||
}
|
||||
|
||||
void
|
||||
ConsoleInstance::TimeEnd(JSContext* aCx, const nsAString& aLabel)
|
||||
{
|
||||
mConsole->StringMethodInternal(aCx, aLabel, Console::MethodTimeEnd,
|
||||
mConsole->StringMethodInternal(aCx, aLabel, Sequence<JS::Value>(),
|
||||
Console::MethodTimeEnd,
|
||||
NS_LITERAL_STRING("timeEnd"));
|
||||
}
|
||||
|
||||
|
@ -201,7 +211,8 @@ ConsoleInstance::Assert(JSContext* aCx, bool aCondition,
|
|||
void
|
||||
ConsoleInstance::Count(JSContext* aCx, const nsAString& aLabel)
|
||||
{
|
||||
mConsole->StringMethodInternal(aCx, aLabel, Console::MethodCount,
|
||||
mConsole->StringMethodInternal(aCx, aLabel, Sequence<JS::Value>(),
|
||||
Console::MethodCount,
|
||||
NS_LITERAL_STRING("count"));
|
||||
}
|
||||
|
||||
|
|
|
@ -74,6 +74,10 @@ public:
|
|||
void
|
||||
Time(JSContext* aCx, const nsAString& aLabel);
|
||||
|
||||
void
|
||||
TimeLog(JSContext* aCx, const nsAString& aLabel,
|
||||
const Sequence<JS::Value>& aData);
|
||||
|
||||
void
|
||||
TimeEnd(JSContext* aCx, const nsAString& aLabel);
|
||||
|
||||
|
|
|
@ -10,3 +10,4 @@ support-files =
|
|||
[test_console_binding.html]
|
||||
[test_console_proto.html]
|
||||
[test_devtools_pref.html]
|
||||
[test_timer.html]
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for timeStart/timeLog/timeEnd in console</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function ConsoleListener() {
|
||||
SpecialPowers.addObserver(this, "console-api-log-event");
|
||||
}
|
||||
|
||||
ConsoleListener.prototype = {
|
||||
observe(aSubject, aTopic, aData) {
|
||||
let obj = aSubject.wrappedJSObject;
|
||||
if (obj.arguments[0] != 'test') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this._cb) {
|
||||
ok(false, "Callback not set!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this._cb(obj)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._cb = null;
|
||||
this._resolve();
|
||||
},
|
||||
|
||||
shutdown() {
|
||||
SpecialPowers.removeObserver(this, "console-api-log-event");
|
||||
},
|
||||
|
||||
waitFor(cb) {
|
||||
return new Promise(resolve => {
|
||||
this._cb = cb;
|
||||
this._resolve = resolve;
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
let listener = new ConsoleListener();
|
||||
|
||||
// Timer creation:
|
||||
async function runTest() {
|
||||
let cl = listener.waitFor(obj => {
|
||||
return ("timer" in obj) &&
|
||||
("name" in obj.timer) &&
|
||||
obj.timer.name == 'test';
|
||||
});
|
||||
|
||||
console.time('test');
|
||||
await cl;
|
||||
ok(true, "Console.time received!");
|
||||
|
||||
// Timer check:
|
||||
cl = listener.waitFor(obj => {
|
||||
return ("timer" in obj) &&
|
||||
("name" in obj.timer) &&
|
||||
obj.timer.name == 'test' &&
|
||||
("duration" in obj.timer) &&
|
||||
obj.timer.duration > 0 &&
|
||||
obj.arguments[1] == 1 &&
|
||||
obj.arguments[2] == 2 &&
|
||||
obj.arguments[3] == 3 &&
|
||||
obj.arguments[4] == 4;
|
||||
});
|
||||
console.timeLog('test', 1, 2, 3, 4);
|
||||
await cl;
|
||||
ok(true, "Console.timeLog received!");
|
||||
|
||||
// Time deleted:
|
||||
cl = listener.waitFor(obj => {
|
||||
return ("timer" in obj) &&
|
||||
("name" in obj.timer) &&
|
||||
obj.timer.name == 'test' &&
|
||||
("duration" in obj.timer) &&
|
||||
obj.timer.duration > 0;
|
||||
});
|
||||
console.timeEnd('test');
|
||||
await cl;
|
||||
ok(true, "Console.timeEnd received!");
|
||||
|
||||
// Here an error:
|
||||
cl = listener.waitFor(obj => {
|
||||
return ("timer" in obj) &&
|
||||
("name" in obj.timer) &&
|
||||
obj.timer.name == 'test' &&
|
||||
("error" in obj.timer);
|
||||
});
|
||||
console.timeLog('test');
|
||||
await cl;
|
||||
ok(true, "Console.time with error received!");
|
||||
}
|
||||
|
||||
runTest().then(() => {
|
||||
listener.shutdown();
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -5368,6 +5368,54 @@ EventStateManager::ResetLastOverForContent(
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
EventStateManager::RemoveNodeFromChainIfNeeded(EventStates aState,
|
||||
nsIContent* aContentRemoved,
|
||||
bool aNotify)
|
||||
{
|
||||
MOZ_ASSERT(aState == NS_EVENT_STATE_HOVER || aState == NS_EVENT_STATE_ACTIVE);
|
||||
if (!aContentRemoved->IsElement() ||
|
||||
!aContentRemoved->AsElement()->State().HasState(aState)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent>& leaf =
|
||||
aState == NS_EVENT_STATE_HOVER ? mHoverContent : mActiveContent;
|
||||
|
||||
MOZ_ASSERT(leaf);
|
||||
// XBL Likes to unbind content without notifying, thus the
|
||||
// NODE_IS_ANONYMOUS_ROOT check...
|
||||
MOZ_ASSERT(nsContentUtils::ContentIsFlattenedTreeDescendantOf(
|
||||
leaf, aContentRemoved) ||
|
||||
leaf->SubtreeRoot()->HasFlag(NODE_IS_ANONYMOUS_ROOT));
|
||||
|
||||
nsIContent* newLeaf = aContentRemoved->GetFlattenedTreeParent();
|
||||
MOZ_ASSERT_IF(newLeaf,
|
||||
newLeaf->IsElement() &&
|
||||
newLeaf->AsElement()->State().HasState(aState));
|
||||
if (aNotify) {
|
||||
SetContentState(newLeaf, aState);
|
||||
} else {
|
||||
// We don't update the removed content's state here, since removing NAC
|
||||
// happens from layout and we don't really want to notify at that point or
|
||||
// what not.
|
||||
//
|
||||
// Also, NAC is not observable and NAC being removed will go away soon.
|
||||
leaf = newLeaf;
|
||||
}
|
||||
MOZ_ASSERT(leaf == newLeaf);
|
||||
}
|
||||
|
||||
void
|
||||
EventStateManager::NativeAnonymousContentRemoved(nsIContent* aContent)
|
||||
{
|
||||
// FIXME(bug 1450250): <svg:use> is nasty.
|
||||
MOZ_ASSERT(aContent->IsRootOfNativeAnonymousSubtree() ||
|
||||
aContent->GetParentNode()->IsSVGElement(nsGkAtoms::use));
|
||||
RemoveNodeFromChainIfNeeded(NS_EVENT_STATE_HOVER, aContent, false);
|
||||
RemoveNodeFromChainIfNeeded(NS_EVENT_STATE_ACTIVE, aContent, false);
|
||||
}
|
||||
|
||||
void
|
||||
EventStateManager::ContentRemoved(nsIDocument* aDocument, nsIContent* aContent)
|
||||
{
|
||||
|
@ -5392,19 +5440,8 @@ EventStateManager::ContentRemoved(nsIDocument* aDocument, nsIContent* aContent)
|
|||
if (fm)
|
||||
fm->ContentRemoved(aDocument, aContent);
|
||||
|
||||
if (mHoverContent &&
|
||||
nsContentUtils::ContentIsFlattenedTreeDescendantOf(mHoverContent, aContent)) {
|
||||
// Since hover is hierarchical, set the current hover to the
|
||||
// content's parent node.
|
||||
SetContentState(aContent->GetFlattenedTreeParent(), NS_EVENT_STATE_HOVER);
|
||||
}
|
||||
|
||||
if (mActiveContent &&
|
||||
nsContentUtils::ContentIsFlattenedTreeDescendantOf(mActiveContent, aContent)) {
|
||||
// Active is hierarchical, so set the current active to the
|
||||
// content's parent node.
|
||||
SetContentState(aContent->GetFlattenedTreeParent(), NS_EVENT_STATE_ACTIVE);
|
||||
}
|
||||
RemoveNodeFromChainIfNeeded(NS_EVENT_STATE_HOVER, aContent, true);
|
||||
RemoveNodeFromChainIfNeeded(NS_EVENT_STATE_ACTIVE, aContent, true);
|
||||
|
||||
if (sDragOverContent &&
|
||||
sDragOverContent->OwnerDoc() == aContent->OwnerDoc() &&
|
||||
|
|
|
@ -148,6 +148,8 @@ public:
|
|||
* affect the return value.
|
||||
*/
|
||||
bool SetContentState(nsIContent* aContent, EventStates aState);
|
||||
|
||||
void NativeAnonymousContentRemoved(nsIContent* aAnonContent);
|
||||
void ContentRemoved(nsIDocument* aDocument, nsIContent* aContent);
|
||||
|
||||
bool EventStatusOK(WidgetGUIEvent* aEvent);
|
||||
|
@ -1087,6 +1089,14 @@ protected:
|
|||
void HandleQueryContentEvent(WidgetQueryContentEvent* aEvent);
|
||||
|
||||
private:
|
||||
// Removes a node from the :hover / :active chain if needed, notifying if the
|
||||
// node is not a NAC subtree.
|
||||
//
|
||||
// Only meant to be called from ContentRemoved and
|
||||
// NativeAnonymousContentRemoved.
|
||||
void RemoveNodeFromChainIfNeeded(EventStates aState,
|
||||
nsIContent* aContentRemoved,
|
||||
bool aNotify);
|
||||
|
||||
bool IsEventOutsideDragThreshold(WidgetInputEvent* aEvent) const;
|
||||
|
||||
|
|
|
@ -1346,16 +1346,4 @@ NS_DECLARE_NS_NEW_HTML_ELEMENT(Track)
|
|||
NS_DECLARE_NS_NEW_HTML_ELEMENT(Unknown)
|
||||
NS_DECLARE_NS_NEW_HTML_ELEMENT(Video)
|
||||
|
||||
inline nsISupports*
|
||||
ToSupports(nsGenericHTMLElement* aHTMLElement)
|
||||
{
|
||||
return static_cast<nsIContent*>(aHTMLElement);
|
||||
}
|
||||
|
||||
inline nsISupports*
|
||||
ToCanonicalSupports(nsGenericHTMLElement* aHTMLElement)
|
||||
{
|
||||
return static_cast<nsIContent*>(aHTMLElement);
|
||||
}
|
||||
|
||||
#endif /* nsGenericHTMLElement_h___ */
|
||||
|
|
|
@ -1889,64 +1889,49 @@ nsHTMLDocument::ReleaseEvents()
|
|||
WarnOnceAbout(nsIDocument::eUseOfReleaseEvents);
|
||||
}
|
||||
|
||||
nsISupports*
|
||||
nsHTMLDocument::ResolveName(const nsAString& aName, nsWrapperCache **aCache)
|
||||
bool
|
||||
nsHTMLDocument::ResolveName(JSContext* aCx, const nsAString& aName,
|
||||
JS::MutableHandle<JS::Value> aRetval, ErrorResult& aError)
|
||||
{
|
||||
nsIdentifierMapEntry *entry = mIdentifierMap.GetEntry(aName);
|
||||
if (!entry) {
|
||||
*aCache = nullptr;
|
||||
return nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
nsBaseContentList *list = entry->GetNameContentList();
|
||||
uint32_t length = list ? list->Length() : 0;
|
||||
|
||||
nsIContent *node;
|
||||
if (length > 0) {
|
||||
if (length == 1) {
|
||||
if (length > 1) {
|
||||
// The list contains more than one element, return the whole list.
|
||||
if (!ToJSValue(aCx, list, aRetval)) {
|
||||
aError.NoteJSContextException(aCx);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Only one element in the list, return the element instead of returning
|
||||
// the list.
|
||||
nsIContent *node = list->Item(0);
|
||||
*aCache = node;
|
||||
return node;
|
||||
}
|
||||
|
||||
// The list contains more than one element, return the whole list.
|
||||
*aCache = 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)) {
|
||||
*aCache = e;
|
||||
return e;
|
||||
if (!e || !nsGenericHTMLElement::ShouldExposeIdAsHTMLDocumentProperty(e)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*aCache = nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLDocument::NamedGetter(JSContext* cx, const nsAString& aName, bool& aFound,
|
||||
JS::MutableHandle<JSObject*> aRetval,
|
||||
ErrorResult& rv)
|
||||
{
|
||||
nsWrapperCache* cache;
|
||||
nsISupports* supp = ResolveName(aName, &cache);
|
||||
if (!supp) {
|
||||
aFound = false;
|
||||
aRetval.set(nullptr);
|
||||
return;
|
||||
node = e;
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> val(cx);
|
||||
if (!dom::WrapObject(cx, supp, cache, nullptr, &val)) {
|
||||
rv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
if (!ToJSValue(aCx, node, aRetval)) {
|
||||
aError.NoteJSContextException(aCx);
|
||||
return false;
|
||||
}
|
||||
aFound = true;
|
||||
aRetval.set(&val.toObject());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -79,7 +79,9 @@ public:
|
|||
|
||||
mozilla::dom::HTMLAllCollection* All();
|
||||
|
||||
nsISupports* ResolveName(const nsAString& aName, nsWrapperCache **aCache);
|
||||
// Returns whether an object was found for aName.
|
||||
bool ResolveName(JSContext* aCx, const nsAString& aName,
|
||||
JS::MutableHandle<JS::Value> aRetval, mozilla::ErrorResult& aError);
|
||||
|
||||
virtual void AddedForm() override;
|
||||
virtual void RemovedForm() override;
|
||||
|
@ -151,7 +153,13 @@ public:
|
|||
void SetCookie(const nsAString& aCookie, mozilla::ErrorResult& rv);
|
||||
void NamedGetter(JSContext* cx, const nsAString& aName, bool& aFound,
|
||||
JS::MutableHandle<JSObject*> aRetval,
|
||||
mozilla::ErrorResult& rv);
|
||||
mozilla::ErrorResult& rv)
|
||||
{
|
||||
JS::Rooted<JS::Value> v(cx);
|
||||
if ((aFound = ResolveName(cx, aName, &v, rv))) {
|
||||
aRetval.set(v.toObjectOrNull());
|
||||
}
|
||||
}
|
||||
void GetSupportedNames(nsTArray<nsString>& aNames);
|
||||
already_AddRefed<nsIDocument> Open(JSContext* cx,
|
||||
const mozilla::dom::Optional<nsAString>& /* unused */,
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include "Connection.h"
|
||||
#include "ConnectionMainThread.h"
|
||||
#include "ConnectionWorker.h"
|
||||
#include "nsIDOMClassInfo.h"
|
||||
#include "Constants.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/dom/WorkerPrivate.h"
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "nsIDocument.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "ServiceWorkerImpl.h"
|
||||
#include "ServiceWorkerManager.h"
|
||||
#include "ServiceWorkerPrivate.h"
|
||||
|
||||
|
@ -62,7 +63,8 @@ ServiceWorker::Create(nsIGlobalObject* aOwner,
|
|||
return ref.forget();
|
||||
}
|
||||
|
||||
ref = new ServiceWorker(aOwner, aDescriptor, info);
|
||||
RefPtr<ServiceWorker::Inner> inner = new ServiceWorkerImpl(info);
|
||||
ref = new ServiceWorker(aOwner, aDescriptor, inner);
|
||||
return ref.forget();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ServiceWorkerImpl.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
ServiceWorkerImpl::~ServiceWorkerImpl()
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(!mOuter);
|
||||
mInfo->RemoveListener(this);
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerImpl::AddServiceWorker(ServiceWorker* aWorker)
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(!mOuter);
|
||||
MOZ_DIAGNOSTIC_ASSERT(aWorker);
|
||||
mOuter = aWorker;
|
||||
|
||||
// Wait to attach to the info as a listener until we have the outer
|
||||
// set. This is important because the info will try to set the
|
||||
// state immediately.
|
||||
mInfo->AddListener(this);
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerImpl::RemoveServiceWorker(ServiceWorker* aWorker)
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(mOuter);
|
||||
MOZ_DIAGNOSTIC_ASSERT(mOuter == aWorker);
|
||||
mOuter = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerImpl::PostMessage(ipc::StructuredCloneData&& aData,
|
||||
const ClientInfo& aClientInfo,
|
||||
const ClientState& aClientState)
|
||||
{
|
||||
mInfo->PostMessage(Move(aData), aClientInfo, aClientState);
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerImpl::SetState(ServiceWorkerState aState)
|
||||
{
|
||||
if (!mOuter) {
|
||||
return;
|
||||
}
|
||||
mOuter->SetState(aState);
|
||||
}
|
||||
|
||||
|
||||
ServiceWorkerImpl::ServiceWorkerImpl(ServiceWorkerInfo* aInfo)
|
||||
: mInfo(aInfo)
|
||||
, mOuter(nullptr)
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(mInfo);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,51 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_ServiceWorkerImpl_h
|
||||
#define mozilla_dom_ServiceWorkerImpl_h
|
||||
|
||||
#include "ServiceWorker.h"
|
||||
#include "ServiceWorkerInfo.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class ServiceWorkerInfo;
|
||||
|
||||
class ServiceWorkerImpl final : public ServiceWorker::Inner
|
||||
, public ServiceWorkerInfo::Listener
|
||||
{
|
||||
RefPtr<ServiceWorkerInfo> mInfo;
|
||||
ServiceWorker* mOuter;
|
||||
|
||||
~ServiceWorkerImpl();
|
||||
|
||||
// ServiceWorker::Inner interface
|
||||
void
|
||||
AddServiceWorker(ServiceWorker* aWorker) override;
|
||||
|
||||
void
|
||||
RemoveServiceWorker(ServiceWorker* aWorker) override;
|
||||
|
||||
void
|
||||
PostMessage(ipc::StructuredCloneData&& aData,
|
||||
const ClientInfo& aClientInfo,
|
||||
const ClientState& aClientState) override;
|
||||
|
||||
// ServiceWorkerInfo::Listener interface
|
||||
void
|
||||
SetState(ServiceWorkerState aState) override;
|
||||
|
||||
public:
|
||||
explicit ServiceWorkerImpl(ServiceWorkerInfo* aInfo);
|
||||
|
||||
NS_INLINE_DECL_REFCOUNTING(ServiceWorkerImpl, override);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_ServiceWorkerImpl_h
|
|
@ -118,7 +118,7 @@ namespace {
|
|||
class ChangeStateUpdater final : public Runnable
|
||||
{
|
||||
public:
|
||||
ChangeStateUpdater(const nsTArray<ServiceWorker*>& aInstances,
|
||||
ChangeStateUpdater(const nsTArray<ServiceWorkerInfo::Listener*>& aInstances,
|
||||
ServiceWorkerState aState)
|
||||
: Runnable("dom::ChangeStateUpdater")
|
||||
, mState(aState)
|
||||
|
@ -137,7 +137,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
AutoTArray<RefPtr<ServiceWorker>, 1> mInstances;
|
||||
AutoTArray<RefPtr<ServiceWorkerInfo::Listener>, 1> mInstances;
|
||||
ServiceWorkerState mState;
|
||||
};
|
||||
|
||||
|
@ -225,33 +225,20 @@ ServiceWorkerInfo::GetNextID() const
|
|||
}
|
||||
|
||||
void
|
||||
ServiceWorkerInfo::AddServiceWorker(ServiceWorker* aWorker)
|
||||
ServiceWorkerInfo::AddListener(Listener* aListener)
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(aWorker);
|
||||
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
|
||||
nsAutoString workerURL;
|
||||
aWorker->GetScriptURL(workerURL);
|
||||
MOZ_DIAGNOSTIC_ASSERT(
|
||||
workerURL.Equals(NS_ConvertUTF8toUTF16(mDescriptor.ScriptURL())));
|
||||
#endif
|
||||
MOZ_ASSERT(!mInstances.Contains(aWorker));
|
||||
MOZ_DIAGNOSTIC_ASSERT(aListener);
|
||||
MOZ_ASSERT(!mInstances.Contains(aListener));
|
||||
|
||||
mInstances.AppendElement(aWorker);
|
||||
aWorker->SetState(State());
|
||||
mInstances.AppendElement(aListener);
|
||||
aListener->SetState(State());
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerInfo::RemoveServiceWorker(ServiceWorker* aWorker)
|
||||
ServiceWorkerInfo::RemoveListener(Listener* aListener)
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(aWorker);
|
||||
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
|
||||
nsAutoString workerURL;
|
||||
aWorker->GetScriptURL(workerURL);
|
||||
MOZ_DIAGNOSTIC_ASSERT(
|
||||
workerURL.Equals(NS_ConvertUTF8toUTF16(mDescriptor.ScriptURL())));
|
||||
#endif
|
||||
|
||||
DebugOnly<bool> removed = mInstances.RemoveElement(aWorker);
|
||||
MOZ_DIAGNOSTIC_ASSERT(aListener);
|
||||
DebugOnly<bool> removed = mInstances.RemoveElement(aListener);
|
||||
MOZ_ASSERT(removed);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include "mozilla/dom/WorkerCommon.h"
|
||||
#include "mozilla/OriginAttributes.h"
|
||||
#include "nsIServiceWorkerManager.h"
|
||||
#include "ServiceWorker.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -27,8 +26,17 @@ class ServiceWorkerPrivate;
|
|||
* by this class and spawn a ServiceWorker in the right global when required.
|
||||
*/
|
||||
class ServiceWorkerInfo final : public nsIServiceWorkerInfo
|
||||
, public ServiceWorker::Inner
|
||||
{
|
||||
public:
|
||||
class Listener
|
||||
{
|
||||
public:
|
||||
virtual void
|
||||
SetState(ServiceWorkerState aState) = 0;
|
||||
|
||||
NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
|
||||
};
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
ServiceWorkerDescriptor mDescriptor;
|
||||
|
@ -60,7 +68,7 @@ private:
|
|||
//
|
||||
// There is a high chance of there being at least one ServiceWorker
|
||||
// associated with this all the time.
|
||||
AutoTArray<ServiceWorker*, 1> mInstances;
|
||||
AutoTArray<Listener*, 1> mInstances;
|
||||
|
||||
RefPtr<ServiceWorkerPrivate> mServiceWorkerPrivate;
|
||||
bool mSkipWaitingFlag;
|
||||
|
@ -78,22 +86,21 @@ private:
|
|||
uint64_t
|
||||
GetNextID() const;
|
||||
|
||||
// ServiceWorker::Inner implementation
|
||||
virtual void
|
||||
AddServiceWorker(ServiceWorker* aWorker) override;
|
||||
|
||||
virtual void
|
||||
RemoveServiceWorker(ServiceWorker* aWorker) override;
|
||||
|
||||
virtual void
|
||||
PostMessage(ipc::StructuredCloneData&& aData,
|
||||
const ClientInfo& aClientInfo,
|
||||
const ClientState& aClientState) override;
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISERVICEWORKERINFO
|
||||
|
||||
void
|
||||
AddListener(Listener* aListener);
|
||||
|
||||
void
|
||||
RemoveListener(Listener* aListener);
|
||||
|
||||
void
|
||||
PostMessage(ipc::StructuredCloneData&& aData,
|
||||
const ClientInfo& aClientInfo,
|
||||
const ClientState& aClientState);
|
||||
|
||||
class ServiceWorkerPrivate*
|
||||
WorkerPrivate() const
|
||||
{
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "nsIObserverService.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsISafeOutputStream.h"
|
||||
#include "nsIServiceWorkerManager.h"
|
||||
|
||||
#include "MainThreadUtils.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
|
@ -36,6 +37,7 @@
|
|||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "ServiceWorkerUtils.h"
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ UNIFIED_SOURCES += [
|
|||
'ServiceWorkerContainerImpl.cpp',
|
||||
'ServiceWorkerDescriptor.cpp',
|
||||
'ServiceWorkerEvents.cpp',
|
||||
'ServiceWorkerImpl.cpp',
|
||||
'ServiceWorkerInfo.cpp',
|
||||
'ServiceWorkerInterceptController.cpp',
|
||||
'ServiceWorkerJob.cpp',
|
||||
|
|
|
@ -32,6 +32,7 @@ function doTest() {
|
|||
"groupCollapsed": "function",
|
||||
"groupEnd": "function",
|
||||
"time": "function",
|
||||
"timeLog": "function",
|
||||
"timeEnd": "function",
|
||||
"profile": "function",
|
||||
"profileEnd": "function",
|
||||
|
|
|
@ -256,8 +256,6 @@ var interfaceNamesInGlobalScope =
|
|||
{name: "CSSNamespaceRule", insecureContext: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "CSSPageRule", insecureContext: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "CSSPrimitiveValue", insecureContext: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "CSSPseudoElement", insecureContext: true, release: false},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
@ -274,10 +272,6 @@ var interfaceNamesInGlobalScope =
|
|||
{name: "CSSSupportsRule", insecureContext: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "CSSTransition", insecureContext: true, release: false},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "CSSValue", insecureContext: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "CSSValueList", insecureContext: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "CustomElementRegistry", insecureContext: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
@ -814,14 +808,10 @@ var interfaceNamesInGlobalScope =
|
|||
{name: "RadioNodeList", insecureContext: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "Range", insecureContext: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "Rect", insecureContext: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "Request", insecureContext: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "Response", insecureContext: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "RGBColor", insecureContext: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "RTCCertificate", insecureContext: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
interface CSSPrimitiveValue : CSSValue {
|
||||
|
||||
// UnitTypes
|
||||
const unsigned short CSS_UNKNOWN = 0;
|
||||
const unsigned short CSS_NUMBER = 1;
|
||||
const unsigned short CSS_PERCENTAGE = 2;
|
||||
const unsigned short CSS_EMS = 3;
|
||||
const unsigned short CSS_EXS = 4;
|
||||
const unsigned short CSS_PX = 5;
|
||||
const unsigned short CSS_CM = 6;
|
||||
const unsigned short CSS_MM = 7;
|
||||
const unsigned short CSS_IN = 8;
|
||||
const unsigned short CSS_PT = 9;
|
||||
const unsigned short CSS_PC = 10;
|
||||
const unsigned short CSS_DEG = 11;
|
||||
const unsigned short CSS_RAD = 12;
|
||||
const unsigned short CSS_GRAD = 13;
|
||||
const unsigned short CSS_MS = 14;
|
||||
const unsigned short CSS_S = 15;
|
||||
const unsigned short CSS_HZ = 16;
|
||||
const unsigned short CSS_KHZ = 17;
|
||||
const unsigned short CSS_DIMENSION = 18;
|
||||
const unsigned short CSS_STRING = 19;
|
||||
const unsigned short CSS_URI = 20;
|
||||
const unsigned short CSS_IDENT = 21;
|
||||
const unsigned short CSS_ATTR = 22;
|
||||
const unsigned short CSS_COUNTER = 23;
|
||||
const unsigned short CSS_RECT = 24;
|
||||
const unsigned short CSS_RGBCOLOR = 25;
|
||||
|
||||
readonly attribute unsigned short primitiveType;
|
||||
[Throws]
|
||||
void setFloatValue(unsigned short unitType,
|
||||
float floatValue);
|
||||
[Throws]
|
||||
float getFloatValue(unsigned short unitType);
|
||||
[Throws]
|
||||
void setStringValue(unsigned short stringType,
|
||||
DOMString stringValue);
|
||||
[Throws]
|
||||
DOMString getStringValue();
|
||||
[Throws]
|
||||
void getCounterValue(); // always throws
|
||||
[Throws]
|
||||
Rect getRectValue();
|
||||
[Throws]
|
||||
RGBColor getRGBColorValue();
|
||||
};
|
|
@ -1,19 +0,0 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
interface CSSValue {
|
||||
|
||||
// UnitTypes
|
||||
const unsigned short CSS_INHERIT = 0;
|
||||
const unsigned short CSS_PRIMITIVE_VALUE = 1;
|
||||
const unsigned short CSS_VALUE_LIST = 2;
|
||||
const unsigned short CSS_CUSTOM = 3;
|
||||
|
||||
[Throws]
|
||||
attribute DOMString cssText;
|
||||
|
||||
readonly attribute unsigned short cssValueType;
|
||||
};
|
|
@ -1,10 +0,0 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
interface CSSValueList : CSSValue {
|
||||
readonly attribute unsigned long length;
|
||||
getter CSSValue? item(unsigned long index);
|
||||
};
|
|
@ -54,6 +54,8 @@ namespace console {
|
|||
[UseCounter]
|
||||
void time(optional DOMString label = "default");
|
||||
[UseCounter]
|
||||
void timeLog(optional DOMString label = "default", any... data);
|
||||
[UseCounter]
|
||||
void timeEnd(optional DOMString label = "default");
|
||||
|
||||
// Mozilla only or Webcompat methods
|
||||
|
@ -121,7 +123,7 @@ dictionary ConsoleTimerStart {
|
|||
DOMString name = "";
|
||||
};
|
||||
|
||||
dictionary ConsoleTimerEnd {
|
||||
dictionary ConsoleTimerLogOrEnd {
|
||||
DOMString name = "";
|
||||
double duration = 0;
|
||||
};
|
||||
|
@ -165,6 +167,7 @@ interface ConsoleInstance {
|
|||
|
||||
// Timing
|
||||
void time(optional DOMString label = "default");
|
||||
void timeLog(optional DOMString label = "default", any... data);
|
||||
void timeEnd(optional DOMString label = "default");
|
||||
|
||||
// Mozilla only or Webcompat methods
|
||||
|
@ -179,8 +182,9 @@ interface ConsoleInstance {
|
|||
callback ConsoleInstanceDumpCallback = void (DOMString message);
|
||||
|
||||
enum ConsoleLogLevel {
|
||||
"All", "Debug", "Log", "Info", "Clear", "Trace", "TimeEnd", "Time", "Group",
|
||||
"GroupEnd", "Profile", "ProfileEnd", "Dir", "Dirxml", "Warn", "Error", "Off"
|
||||
"All", "Debug", "Log", "Info", "Clear", "Trace", "TimeLog", "TimeEnd", "Time",
|
||||
"Group", "GroupEnd", "Profile", "ProfileEnd", "Dir", "Dirxml", "Warn", "Error",
|
||||
"Off"
|
||||
};
|
||||
|
||||
dictionary ConsoleInstanceOptions {
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* The origin of this IDL file is
|
||||
* http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-RGBColor
|
||||
*/
|
||||
|
||||
interface RGBColor {
|
||||
readonly attribute CSSPrimitiveValue red;
|
||||
readonly attribute CSSPrimitiveValue green;
|
||||
readonly attribute CSSPrimitiveValue blue;
|
||||
|
||||
// mozilla specific
|
||||
readonly attribute CSSPrimitiveValue alpha;
|
||||
};
|
|
@ -1,12 +0,0 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
interface Rect {
|
||||
readonly attribute CSSPrimitiveValue top;
|
||||
readonly attribute CSSPrimitiveValue right;
|
||||
readonly attribute CSSPrimitiveValue bottom;
|
||||
readonly attribute CSSPrimitiveValue left;
|
||||
};
|
|
@ -441,7 +441,6 @@ WEBIDL_FILES = [
|
|||
'CSSMozDocumentRule.webidl',
|
||||
'CSSNamespaceRule.webidl',
|
||||
'CSSPageRule.webidl',
|
||||
'CSSPrimitiveValue.webidl',
|
||||
'CSSPseudoElement.webidl',
|
||||
'CSSRule.webidl',
|
||||
'CSSRuleList.webidl',
|
||||
|
@ -450,8 +449,6 @@ WEBIDL_FILES = [
|
|||
'CSSStyleSheet.webidl',
|
||||
'CSSSupportsRule.webidl',
|
||||
'CSSTransition.webidl',
|
||||
'CSSValue.webidl',
|
||||
'CSSValueList.webidl',
|
||||
'CustomElementRegistry.webidl',
|
||||
'DataTransfer.webidl',
|
||||
'DataTransferItem.webidl',
|
||||
|
@ -738,10 +735,8 @@ WEBIDL_FILES = [
|
|||
'PushSubscriptionOptions.webidl',
|
||||
'RadioNodeList.webidl',
|
||||
'Range.webidl',
|
||||
'Rect.webidl',
|
||||
'Request.webidl',
|
||||
'Response.webidl',
|
||||
'RGBColor.webidl',
|
||||
'RTCStatsReport.webidl',
|
||||
'Screen.webidl',
|
||||
'ScreenOrientation.webidl',
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
#include "mozilla/EditorUtils.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/TextEditRules.h"
|
||||
#include "mozilla/dom/CSSPrimitiveValueBinding.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/EventTarget.h"
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include "mozilla/HTMLEditor.h"
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/dom/CSSPrimitiveValueBinding.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/EventTarget.h"
|
||||
#include "mozilla/mozalloc.h"
|
||||
|
|
|
@ -4211,15 +4211,16 @@ gfxFontStyle::gfxFontStyle(FontSlantStyle aStyle,
|
|||
PLDHashNumber
|
||||
gfxFontStyle::Hash() const
|
||||
{
|
||||
return mozilla::HashGeneric(systemFont, style.ForHash(),
|
||||
uint32_t hash =
|
||||
variationSettings.IsEmpty()
|
||||
? 0
|
||||
: mozilla::HashBytes(variationSettings.Elements(),
|
||||
variationSettings.Length() *
|
||||
sizeof(gfxFontVariation));
|
||||
return mozilla::AddToHash(hash, systemFont, style.ForHash(),
|
||||
stretch.ForHash(), weight.ForHash(),
|
||||
size, sizeAdjust,
|
||||
size, int32_t(sizeAdjust * 1000.0f),
|
||||
nsRefPtrHashKey<nsAtom>::HashKey(language));
|
||||
/* XXX
|
||||
return (style + (systemFont << 7) + (weight.ForHash() << 8) +
|
||||
uint32_t(size*1000) + int32_t(sizeAdjust*1000)) ^
|
||||
nsRefPtrHashKey<nsAtom>::HashKey(language);
|
||||
*/
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1524,8 +1524,6 @@ WeightDistance(const gfxFontEntry* aFontEntry, FontWeight aTargetWeight)
|
|||
return distance;
|
||||
}
|
||||
|
||||
#define MAX_DISTANCE 1.0e20 // >> than any WeightStyleStretchDistance result
|
||||
|
||||
static inline double
|
||||
WeightStyleStretchDistance(gfxFontEntry* aFontEntry,
|
||||
const gfxFontStyle& aTargetStyle)
|
||||
|
@ -1625,7 +1623,7 @@ gfxFontFamily::FindAllFontsForStyle(const gfxFontStyle& aFontStyle,
|
|||
// weight/style/stretch combination, only the last matched font entry will
|
||||
// be added.
|
||||
|
||||
double minDistance = MAX_DISTANCE;
|
||||
double minDistance = INFINITY;
|
||||
gfxFontEntry* matched = nullptr;
|
||||
// iterate in forward order so that faces like 'Bold' are matched before
|
||||
// matching style distance faces such as 'Bold Outline' (see bug 1185812)
|
||||
|
@ -1735,45 +1733,8 @@ void gfxFontFamily::LocalizedName(nsAString& aLocalizedName)
|
|||
aLocalizedName = mName;
|
||||
}
|
||||
|
||||
// metric for how close a given font matches a style
|
||||
static float
|
||||
CalcStyleMatch(gfxFontEntry *aFontEntry, const gfxFontStyle *aStyle)
|
||||
{
|
||||
float rank = 0;
|
||||
if (aStyle) {
|
||||
// TODO: stretch
|
||||
|
||||
// italics
|
||||
bool wantUpright = aStyle->style.IsNormal();
|
||||
if (aFontEntry->IsUpright() == wantUpright) {
|
||||
rank += 5000.0f;
|
||||
}
|
||||
|
||||
// measure of closeness of weight to the desired value
|
||||
if (aFontEntry->Weight().Min() > aStyle->weight) {
|
||||
rank += 1000.0f - (aFontEntry->Weight().Min() - aStyle->weight);
|
||||
} else if (aFontEntry->Weight().Max() < aStyle->weight) {
|
||||
rank += 1000.0f - (aStyle->weight - aFontEntry->Weight().Max());
|
||||
} else {
|
||||
rank += 2000.0f; // the font supports the exact weight wanted
|
||||
}
|
||||
} else {
|
||||
// if no font to match, prefer non-bold, non-italic fonts
|
||||
if (aFontEntry->IsUpright()) {
|
||||
rank += 2000.0f;
|
||||
}
|
||||
if (aFontEntry->Weight().Min() <= FontWeight(500)) {
|
||||
rank += 1000.0f;
|
||||
}
|
||||
}
|
||||
|
||||
return rank;
|
||||
}
|
||||
|
||||
#define RANK_MATCHED_CMAP 10000.0f
|
||||
|
||||
void
|
||||
gfxFontFamily::FindFontForChar(GlobalFontMatch *aMatchData)
|
||||
gfxFontFamily::FindFontForChar(GlobalFontMatch* aMatchData)
|
||||
{
|
||||
if (mFamilyCharacterMapInitialized && !TestCharacterMap(aMatchData->mCh)) {
|
||||
// none of the faces in the family support the required char,
|
||||
|
@ -1781,16 +1742,15 @@ gfxFontFamily::FindFontForChar(GlobalFontMatch *aMatchData)
|
|||
return;
|
||||
}
|
||||
|
||||
gfxFontEntry *fe =
|
||||
FindFontForStyle(aMatchData->mStyle ? *aMatchData->mStyle
|
||||
: gfxFontStyle(),
|
||||
true);
|
||||
gfxFontEntry* fe =
|
||||
FindFontForStyle(aMatchData->mStyle, /*aIgnoreSizeTolerance*/ true);
|
||||
if (!fe || fe->SkipDuringSystemFallback()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (fe && !fe->SkipDuringSystemFallback()) {
|
||||
float rank = 0;
|
||||
float distance = INFINITY;
|
||||
|
||||
if (fe->HasCharacter(aMatchData->mCh)) {
|
||||
rank += RANK_MATCHED_CMAP;
|
||||
aMatchData->mCount++;
|
||||
|
||||
LogModule* log = gfxPlatform::GetLog(eGfxLog_textrun);
|
||||
|
@ -1806,56 +1766,48 @@ gfxFontFamily::FindFontForChar(GlobalFontMatch *aMatchData)
|
|||
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);
|
||||
distance = WeightStyleStretchDistance(fe, aMatchData->mStyle);
|
||||
} else if (!fe->IsNormalStyle()) {
|
||||
// If style/weight/stretch was not Normal, see if we can
|
||||
// fall back to a next-best face (e.g. Arial Black -> Bold,
|
||||
// or Arial Narrow -> Regular).
|
||||
GlobalFontMatch data(aMatchData->mCh, aMatchData->mStyle);
|
||||
SearchAllFontsForChar(&data);
|
||||
if (data.mMatchRank >= RANK_MATCHED_CMAP) {
|
||||
if (std::isfinite(data.mMatchDistance)) {
|
||||
fe = data.mBestMatch;
|
||||
rank = data.mMatchRank;
|
||||
} else {
|
||||
return;
|
||||
distance = data.mMatchDistance;
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
aMatchData->mCmapsTested++;
|
||||
|
||||
// xxx - add whether AAT font with morphing info for specific lang groups
|
||||
if (std::isinf(distance)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (rank > aMatchData->mMatchRank
|
||||
|| (rank == aMatchData->mMatchRank &&
|
||||
Compare(fe->Name(), aMatchData->mBestMatch->Name()) > 0))
|
||||
{
|
||||
if (distance < aMatchData->mMatchDistance ||
|
||||
(distance == aMatchData->mMatchDistance &&
|
||||
Compare(fe->Name(), aMatchData->mBestMatch->Name()) > 0)) {
|
||||
aMatchData->mBestMatch = fe;
|
||||
aMatchData->mMatchedFamily = this;
|
||||
aMatchData->mMatchRank = rank;
|
||||
}
|
||||
aMatchData->mMatchDistance = distance;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gfxFontFamily::SearchAllFontsForChar(GlobalFontMatch *aMatchData)
|
||||
gfxFontFamily::SearchAllFontsForChar(GlobalFontMatch* aMatchData)
|
||||
{
|
||||
uint32_t i, numFonts = mAvailableFonts.Length();
|
||||
for (i = 0; i < numFonts; i++) {
|
||||
gfxFontEntry *fe = mAvailableFonts[i];
|
||||
if (fe && fe->HasCharacter(aMatchData->mCh)) {
|
||||
float rank = RANK_MATCHED_CMAP;
|
||||
rank += CalcStyleMatch(fe, aMatchData->mStyle);
|
||||
if (rank > aMatchData->mMatchRank
|
||||
|| (rank == aMatchData->mMatchRank &&
|
||||
float distance = WeightStyleStretchDistance(fe, aMatchData->mStyle);
|
||||
if (distance < aMatchData->mMatchDistance
|
||||
|| (distance == aMatchData->mMatchDistance &&
|
||||
Compare(fe->Name(), aMatchData->mBestMatch->Name()) > 0))
|
||||
{
|
||||
aMatchData->mBestMatch = fe;
|
||||
aMatchData->mMatchedFamily = this;
|
||||
aMatchData->mMatchRank = rank;
|
||||
aMatchData->mMatchDistance = distance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/WeakPtr.h"
|
||||
#include <math.h>
|
||||
|
||||
typedef struct gr_face gr_face;
|
||||
|
||||
|
@ -690,20 +691,19 @@ gfxFontEntry::SupportsBold()
|
|||
// used when iterating over all fonts looking for a match for a given character
|
||||
struct GlobalFontMatch {
|
||||
GlobalFontMatch(const uint32_t aCharacter,
|
||||
const gfxFontStyle *aStyle) :
|
||||
mCh(aCharacter), mStyle(aStyle),
|
||||
mMatchRank(0.0f), mCount(0), mCmapsTested(0)
|
||||
const gfxFontStyle& aStyle) :
|
||||
mStyle(aStyle), mCh(aCharacter),
|
||||
mCount(0), mCmapsTested(0), mMatchDistance(INFINITY)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
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
|
||||
const gfxFontStyle& mStyle; // style to match
|
||||
const uint32_t mCh; // codepoint to be matched
|
||||
uint32_t mCount; // number of fonts matched
|
||||
uint32_t mCmapsTested; // number of cmaps tested
|
||||
float mMatchDistance; // metric indicating closest match
|
||||
};
|
||||
|
||||
class gfxFontFamily {
|
||||
|
@ -786,10 +786,10 @@ public:
|
|||
|
||||
// checks for a matching font within the family
|
||||
// used as part of the font fallback process
|
||||
void FindFontForChar(GlobalFontMatch *aMatchData);
|
||||
void FindFontForChar(GlobalFontMatch* aMatchData);
|
||||
|
||||
// checks all fonts for a matching font within the family
|
||||
void SearchAllFontsForChar(GlobalFontMatch *aMatchData);
|
||||
void SearchAllFontsForChar(GlobalFontMatch* aMatchData);
|
||||
|
||||
// read in other family names, if any, and use functor to add each into cache
|
||||
virtual void ReadOtherFamilyNames(gfxPlatformFontList *aPlatformFontList);
|
||||
|
|
|
@ -23,6 +23,13 @@
|
|||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
template<class T>
|
||||
struct TagEquals {
|
||||
bool Equals(const T& aIter, uint32_t aTag) const {
|
||||
return aIter.mTag == aTag;
|
||||
}
|
||||
};
|
||||
|
||||
gfxMacFont::gfxMacFont(const RefPtr<UnscaledFontMac>& aUnscaledFont,
|
||||
MacOSFontEntry *aFontEntry,
|
||||
const gfxFontStyle *aFontStyle)
|
||||
|
@ -47,6 +54,55 @@ gfxMacFont::gfxMacFont(const RefPtr<UnscaledFontMac>& aUnscaledFont,
|
|||
AutoTArray<gfxFontVariation,4> vars;
|
||||
aFontEntry->GetVariationsForStyle(vars, *aFontStyle);
|
||||
|
||||
// Because of a Core Text bug, we need to ensure that if the font has
|
||||
// an 'opsz' axis, it is always explicitly set, and NOT to the font's
|
||||
// default value. (See bug 1457417.)
|
||||
// We record the result of searching the font's axes in the font entry,
|
||||
// so that this only has to be done by the first instance created for
|
||||
// a given font resource.
|
||||
const uint32_t kOpszTag = HB_TAG('o','p','s','z');
|
||||
|
||||
if (!aFontEntry->mCheckedForOpszAxis) {
|
||||
aFontEntry->mCheckedForOpszAxis = true;
|
||||
AutoTArray<gfxFontVariationAxis,4> axes;
|
||||
aFontEntry->GetVariationAxes(axes);
|
||||
auto index =
|
||||
axes.IndexOf(kOpszTag, 0, TagEquals<gfxFontVariationAxis>());
|
||||
if (index == axes.NoIndex) {
|
||||
aFontEntry->mHasOpszAxis = false;
|
||||
} else {
|
||||
const auto& axis = axes[index];
|
||||
aFontEntry->mHasOpszAxis = true;
|
||||
aFontEntry->mOpszAxis = axis;
|
||||
// Pick a slightly-adjusted version of the default that we'll
|
||||
// use to work around Core Text's habit of ignoring any attempt
|
||||
// to explicitly set the default value.
|
||||
aFontEntry->mAdjustedDefaultOpsz =
|
||||
axis.mDefaultValue == axis.mMinValue
|
||||
? axis.mDefaultValue + 0.001f
|
||||
: axis.mDefaultValue - 0.001f;
|
||||
}
|
||||
}
|
||||
|
||||
// Add 'opsz' if not present, or tweak its value if it looks too close
|
||||
// to the default (after clamping to the font's available range).
|
||||
if (aFontEntry->mHasOpszAxis) {
|
||||
auto index =
|
||||
vars.IndexOf(kOpszTag, 0, TagEquals<gfxFontVariation>());
|
||||
if (index == vars.NoIndex) {
|
||||
gfxFontVariation opsz{kOpszTag, aFontEntry->mAdjustedDefaultOpsz};
|
||||
vars.AppendElement(opsz);
|
||||
} else {
|
||||
// Figure out a "safe" value that Core Text won't ignore.
|
||||
auto& value = vars[index].mValue;
|
||||
auto& axis = aFontEntry->mOpszAxis;
|
||||
value = fmin(fmax(value, axis.mMinValue), axis.mMaxValue);
|
||||
if (abs(value - axis.mDefaultValue) < 0.001f) {
|
||||
value = aFontEntry->mAdjustedDefaultOpsz;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mCGFont =
|
||||
UnscaledFontMac::CreateCGFontWithVariations(baseFont,
|
||||
vars.Length(),
|
||||
|
|
|
@ -30,6 +30,7 @@ class MacOSFontEntry : public gfxFontEntry
|
|||
{
|
||||
public:
|
||||
friend class gfxMacPlatformFontList;
|
||||
friend class gfxMacFont;
|
||||
|
||||
MacOSFontEntry(const nsAString& aPostscriptName, WeightRange aWeight,
|
||||
bool aIsStandardFace = false,
|
||||
|
@ -104,6 +105,19 @@ protected:
|
|||
bool mHasAATSmallCaps;
|
||||
bool mHasAATSmallCapsInitialized;
|
||||
bool mCheckedForTracking;
|
||||
|
||||
// To work around Core Text's mishandling of the default value for 'opsz',
|
||||
// we need to record whether the font has an a optical size axis, what its
|
||||
// range and default values are, and a usable close-to-default alternative.
|
||||
// (See bug 1457417 for details.)
|
||||
// These fields are used by gfxMacFont, but stored in the font entry so
|
||||
// that only a single font instance needs to inspect the available
|
||||
// variations.
|
||||
bool mCheckedForOpszAxis;
|
||||
bool mHasOpszAxis;
|
||||
gfxFontVariationAxis mOpszAxis;
|
||||
float mAdjustedDefaultOpsz;
|
||||
|
||||
nsTHashtable<nsUint32HashKey> mAvailableTables;
|
||||
|
||||
mozilla::ThreadSafeWeakPtr<mozilla::gfx::UnscaledFontMac> mUnscaledFont;
|
||||
|
|
|
@ -381,6 +381,7 @@ MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName,
|
|||
mHasAATSmallCaps(false),
|
||||
mHasAATSmallCapsInitialized(false),
|
||||
mCheckedForTracking(false),
|
||||
mCheckedForOpszAxis(false),
|
||||
mTrakTable(nullptr),
|
||||
mTrakValues(nullptr),
|
||||
mTrakSizeTable(nullptr)
|
||||
|
@ -407,6 +408,7 @@ MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName,
|
|||
mHasAATSmallCaps(false),
|
||||
mHasAATSmallCapsInitialized(false),
|
||||
mCheckedForTracking(false),
|
||||
mCheckedForOpszAxis(false),
|
||||
mTrakTable(nullptr),
|
||||
mTrakValues(nullptr),
|
||||
mTrakSizeTable(nullptr)
|
||||
|
|
|
@ -682,7 +682,7 @@ gfxPlatformFontList::CommonFontFallback(uint32_t aCh, uint32_t aNextCh,
|
|||
// If style/weight/stretch was not Normal, see if we can
|
||||
// fall back to a next-best face (e.g. Arial Black -> Bold,
|
||||
// or Arial Narrow -> Regular).
|
||||
GlobalFontMatch data(aCh, aMatchStyle);
|
||||
GlobalFontMatch data(aCh, *aMatchStyle);
|
||||
fallback->SearchAllFontsForChar(&data);
|
||||
if (data.mBestMatch) {
|
||||
*aMatchedFamily = fallback;
|
||||
|
@ -715,7 +715,7 @@ gfxPlatformFontList::GlobalFontFallback(const uint32_t aCh,
|
|||
}
|
||||
|
||||
// otherwise, try to find it among local fonts
|
||||
GlobalFontMatch data(aCh, aMatchStyle);
|
||||
GlobalFontMatch data(aCh, *aMatchStyle);
|
||||
|
||||
// iterate over all font families to find a font that support the character
|
||||
for (auto iter = mFontFamilies.Iter(); !iter.Done(); iter.Next()) {
|
||||
|
@ -1721,6 +1721,7 @@ gfxPlatformFontList::ClearLangGroupPrefFonts()
|
|||
}
|
||||
}
|
||||
mCJKPrefLangs.Clear();
|
||||
mEmojiPrefFont = nullptr;
|
||||
}
|
||||
|
||||
// Support for memory reporting
|
||||
|
|
|
@ -2799,7 +2799,7 @@ gfxFontGroup::GetEllipsisTextRun(int32_t aAppUnitsPerDevPixel,
|
|||
gfxFont*
|
||||
gfxFontGroup::FindFallbackFaceForChar(gfxFontFamily* aFamily, uint32_t aCh)
|
||||
{
|
||||
GlobalFontMatch data(aCh, &mStyle);
|
||||
GlobalFontMatch data(aCh, mStyle);
|
||||
aFamily->SearchAllFontsForChar(&data);
|
||||
gfxFontEntry* fe = data.mBestMatch;
|
||||
if (!fe) {
|
||||
|
|
|
@ -780,7 +780,9 @@ js::ArraySetLength(JSContext* cx, Handle<ArrayObject*> arr, HandleId id,
|
|||
// for..in iteration over the array. Keys deleted before being reached
|
||||
// during the iteration must not be visited, and suppressing them here
|
||||
// would be too costly.
|
||||
if (!arr->isIndexed() && !MaybeInIteration(arr, cx)) {
|
||||
// This optimization is also invalid when there are sealed
|
||||
// (non-configurable) elements.
|
||||
if (!arr->isIndexed() && !MaybeInIteration(arr, cx) && !arr->denseElementsAreSealed()) {
|
||||
if (!arr->maybeCopyElementsForWrite(cx))
|
||||
return false;
|
||||
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
// Test array.length setter on non-extensible/sealed/frozen arrays.
|
||||
"use strict";
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
|
||||
function testNonExtensible() {
|
||||
var a = [1, 2, 3, , ,];
|
||||
Object.preventExtensions(a);
|
||||
for (var i = 0; i < 10; i++)
|
||||
a.length = 10;
|
||||
assertEq(a.length, 10);
|
||||
for (var i = 0; i < 10; i++)
|
||||
a.length = 0;
|
||||
assertEq(a.length, 0);
|
||||
assertEq(a.toString(), "");
|
||||
}
|
||||
testNonExtensible();
|
||||
|
||||
function testSealed() {
|
||||
var a = [1, 2, 3, , ,];
|
||||
Object.seal(a);
|
||||
for (var i = 0; i < 10; i++)
|
||||
a.length = 10;
|
||||
assertEq(a.length, 10);
|
||||
for (var i = 0; i < 10; i++)
|
||||
assertThrowsInstanceOf(() => a.length = 0, TypeError);
|
||||
assertEq(a.length, 3);
|
||||
assertEq(a.toString(), "1,2,3");
|
||||
}
|
||||
testSealed();
|
||||
|
||||
function testFrozen() {
|
||||
var a = [1, 2, 3, , ,];
|
||||
Object.freeze(a);
|
||||
for (var i = 0; i < 10; i++)
|
||||
assertThrowsInstanceOf(() => a.length = 10, TypeError);
|
||||
for (var i = 0; i < 10; i++)
|
||||
assertThrowsInstanceOf(() => a.length = 0, TypeError);
|
||||
assertEq(a.length, 5);
|
||||
assertEq(a.toString(), "1,2,3,,");
|
||||
}
|
||||
testFrozen();
|
|
@ -150,11 +150,18 @@ ref = exports.nested(baguette, 0);
|
|||
assertEq(ref, baguette);
|
||||
assertEq(ref.calories, baguette.calories);
|
||||
|
||||
if (wasmDebuggingIsSupported()) {
|
||||
let g = newGlobal();
|
||||
let dbg = new Debugger(g);
|
||||
g.eval(`o = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary('(module (func (result anyref) (param anyref) get_local 0) (export "" 0))')));`);
|
||||
}
|
||||
// Make sure grow-memory isn't blocked by the lack of gc.
|
||||
(function() {
|
||||
assertEq(wasmEvalText(`(module
|
||||
(memory 0 64)
|
||||
(func (export "f") (param anyref) (result i32)
|
||||
i32.const 10
|
||||
grow_memory
|
||||
drop
|
||||
current_memory
|
||||
)
|
||||
)`).exports.f({}), 10);
|
||||
})();
|
||||
|
||||
// More interesting use cases about control flow joins.
|
||||
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
if (!wasmGcEnabled() || !wasmDebuggingIsSupported()) {
|
||||
quit(0);
|
||||
}
|
||||
|
||||
(function() {
|
||||
let g = newGlobal();
|
||||
let dbg = new Debugger(g);
|
||||
g.eval(`o = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary('(module (func (result anyref) (param anyref) get_local 0) (export "" 0))')));`);
|
||||
})();
|
||||
|
||||
(function() {
|
||||
var g = newGlobal();
|
||||
g.parent = this;
|
||||
|
||||
let src = `
|
||||
(module
|
||||
(func (export "func") (result anyref) (param $ref anyref)
|
||||
get_local $ref
|
||||
)
|
||||
)
|
||||
`;
|
||||
|
||||
g.eval(`
|
||||
var obj = { somekey: 'somevalue' };
|
||||
|
||||
Debugger(parent).onEnterFrame = function(frame) {
|
||||
let v = frame.environment.getVariable('var0');
|
||||
assertEq(typeof v === 'object', true);
|
||||
assertEq(typeof v.somekey === 'string', true);
|
||||
assertEq(v.somekey === 'somevalue', true);
|
||||
};
|
||||
|
||||
new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(\`${src}\`))).exports.func(obj);
|
||||
`);
|
||||
})();
|
|
@ -131,6 +131,8 @@ CacheRegisterAllocator::useFixedValueRegister(MacroAssembler& masm, ValOperandId
|
|||
Register
|
||||
CacheRegisterAllocator::useRegister(MacroAssembler& masm, TypedOperandId typedId)
|
||||
{
|
||||
MOZ_ASSERT(!addedFailurePath_);
|
||||
|
||||
OperandLocation& loc = operandLocations_[typedId.id()];
|
||||
switch (loc.kind()) {
|
||||
case OperandLocation::PayloadReg:
|
||||
|
@ -206,6 +208,8 @@ CacheRegisterAllocator::useRegister(MacroAssembler& masm, TypedOperandId typedId
|
|||
ConstantOrRegister
|
||||
CacheRegisterAllocator::useConstantOrRegister(MacroAssembler& masm, ValOperandId val)
|
||||
{
|
||||
MOZ_ASSERT(!addedFailurePath_);
|
||||
|
||||
OperandLocation& loc = operandLocations_[val.id()];
|
||||
switch (loc.kind()) {
|
||||
case OperandLocation::Constant:
|
||||
|
@ -236,6 +240,8 @@ CacheRegisterAllocator::useConstantOrRegister(MacroAssembler& masm, ValOperandId
|
|||
Register
|
||||
CacheRegisterAllocator::defineRegister(MacroAssembler& masm, TypedOperandId typedId)
|
||||
{
|
||||
MOZ_ASSERT(!addedFailurePath_);
|
||||
|
||||
OperandLocation& loc = operandLocations_[typedId.id()];
|
||||
MOZ_ASSERT(loc.kind() == OperandLocation::Uninitialized);
|
||||
|
||||
|
@ -247,6 +253,8 @@ CacheRegisterAllocator::defineRegister(MacroAssembler& masm, TypedOperandId type
|
|||
ValueOperand
|
||||
CacheRegisterAllocator::defineValueRegister(MacroAssembler& masm, ValOperandId val)
|
||||
{
|
||||
MOZ_ASSERT(!addedFailurePath_);
|
||||
|
||||
OperandLocation& loc = operandLocations_[val.id()];
|
||||
MOZ_ASSERT(loc.kind() == OperandLocation::Uninitialized);
|
||||
|
||||
|
@ -309,6 +317,8 @@ CacheRegisterAllocator::discardStack(MacroAssembler& masm)
|
|||
Register
|
||||
CacheRegisterAllocator::allocateRegister(MacroAssembler& masm)
|
||||
{
|
||||
MOZ_ASSERT(!addedFailurePath_);
|
||||
|
||||
if (availableRegs_.empty())
|
||||
freeDeadOperandLocations(masm);
|
||||
|
||||
|
@ -359,6 +369,8 @@ CacheRegisterAllocator::allocateRegister(MacroAssembler& masm)
|
|||
void
|
||||
CacheRegisterAllocator::allocateFixedRegister(MacroAssembler& masm, Register reg)
|
||||
{
|
||||
MOZ_ASSERT(!addedFailurePath_);
|
||||
|
||||
// Fixed registers should be allocated first, to ensure they're
|
||||
// still available.
|
||||
MOZ_ASSERT(!currentOpRegs_.has(reg), "Register is in use");
|
||||
|
@ -479,6 +491,10 @@ CacheRegisterAllocator::fixupAliasedInputs(MacroAssembler& masm)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
assertValidState();
|
||||
#endif
|
||||
}
|
||||
|
||||
GeneralRegisterSet
|
||||
|
@ -668,6 +684,32 @@ CacheRegisterAllocator::popValue(MacroAssembler& masm, OperandLocation* loc, Val
|
|||
loc->setValueReg(dest);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
CacheRegisterAllocator::assertValidState() const
|
||||
{
|
||||
// Assert different operands don't have aliasing storage. We depend on this
|
||||
// when spilling registers, for instance.
|
||||
|
||||
if (!JitOptions.fullDebugChecks)
|
||||
return;
|
||||
|
||||
for (size_t i = 0; i < operandLocations_.length(); i++) {
|
||||
const auto& loc1 = operandLocations_[i];
|
||||
if (loc1.isUninitialized())
|
||||
continue;
|
||||
|
||||
for (size_t j = 0; j < i; j++) {
|
||||
const auto& loc2 = operandLocations_[j];
|
||||
if (loc2.isUninitialized())
|
||||
continue;
|
||||
MOZ_ASSERT(loc1 != loc2);
|
||||
MOZ_ASSERT(!loc1.aliasesReg(loc2));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool
|
||||
OperandLocation::aliasesReg(const OperandLocation& other) const
|
||||
{
|
||||
|
@ -1165,6 +1207,10 @@ FailurePath::canShareFailurePath(const FailurePath& other) const
|
|||
bool
|
||||
CacheIRCompiler::addFailurePath(FailurePath** failure)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
allocator.setAddedFailurePath();
|
||||
#endif
|
||||
|
||||
FailurePath newFailure;
|
||||
for (size_t i = 0; i < writer_.numInputOperands(); i++) {
|
||||
if (!newFailure.appendInput(allocator.operandLocation(i)))
|
||||
|
|
|
@ -211,6 +211,7 @@ class OperandLocation
|
|||
data_.baselineFrameSlot = slot;
|
||||
}
|
||||
|
||||
bool isUninitialized() const { return kind_ == Uninitialized; }
|
||||
bool isInRegister() const { return kind_ == PayloadReg || kind_ == ValueReg; }
|
||||
bool isOnStack() const { return kind_ == PayloadStack || kind_ == ValueStack; }
|
||||
|
||||
|
@ -305,6 +306,12 @@ class MOZ_RAII CacheRegisterAllocator
|
|||
// The number of bytes pushed on the native stack.
|
||||
uint32_t stackPushed_;
|
||||
|
||||
#ifdef DEBUG
|
||||
// Flag used to assert individual CacheIR instructions don't allocate
|
||||
// registers after calling addFailurePath.
|
||||
bool addedFailurePath_;
|
||||
#endif
|
||||
|
||||
// The index of the CacheIR instruction we're currently emitting.
|
||||
uint32_t currentInstruction_;
|
||||
|
||||
|
@ -321,6 +328,10 @@ class MOZ_RAII CacheRegisterAllocator
|
|||
void popPayload(MacroAssembler& masm, OperandLocation* loc, Register dest);
|
||||
void popValue(MacroAssembler& masm, OperandLocation* loc, ValueOperand dest);
|
||||
|
||||
#ifdef DEBUG
|
||||
void assertValidState() const;
|
||||
#endif
|
||||
|
||||
public:
|
||||
friend class AutoScratchRegister;
|
||||
friend class AutoScratchRegisterExcluding;
|
||||
|
@ -328,6 +339,9 @@ class MOZ_RAII CacheRegisterAllocator
|
|||
explicit CacheRegisterAllocator(const CacheIRWriter& writer)
|
||||
: allocatableRegs_(GeneralRegisterSet::All()),
|
||||
stackPushed_(0),
|
||||
#ifdef DEBUG
|
||||
addedFailurePath_(false),
|
||||
#endif
|
||||
currentInstruction_(0),
|
||||
writer_(writer)
|
||||
{}
|
||||
|
@ -383,10 +397,21 @@ class MOZ_RAII CacheRegisterAllocator
|
|||
}
|
||||
|
||||
void nextOp() {
|
||||
#ifdef DEBUG
|
||||
assertValidState();
|
||||
addedFailurePath_ = false;
|
||||
#endif
|
||||
currentOpRegs_.clear();
|
||||
currentInstruction_++;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void setAddedFailurePath() {
|
||||
MOZ_ASSERT(!addedFailurePath_, "multiple failure paths for instruction");
|
||||
addedFailurePath_ = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool isDeadAfterInstruction(OperandId opId) const {
|
||||
return writer_.operandIsDead(opId.id(), currentInstruction_ + 1);
|
||||
}
|
||||
|
@ -536,7 +561,8 @@ class FailurePath
|
|||
* Wrap an offset so that a call can decide to embed a constant
|
||||
* or load from the stub data.
|
||||
*/
|
||||
class StubFieldOffset {
|
||||
class StubFieldOffset
|
||||
{
|
||||
private:
|
||||
uint32_t offset_;
|
||||
StubField::Type type_;
|
||||
|
|
|
@ -647,6 +647,9 @@ DebugFrame::getLocal(uint32_t localIndex, MutableHandleValue vp)
|
|||
case jit::MIRType::Double:
|
||||
vp.set(NumberValue(JS::CanonicalizeNaN(*static_cast<double*>(dataPtr))));
|
||||
break;
|
||||
case jit::MIRType::Pointer:
|
||||
vp.set(ObjectOrNullValue(*(JSObject**)dataPtr));
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("local type");
|
||||
}
|
||||
|
@ -675,6 +678,9 @@ DebugFrame::updateReturnJSValue()
|
|||
case ExprType::F64:
|
||||
cachedReturnJSValue_.setDouble(JS::CanonicalizeNaN(resultF64_));
|
||||
break;
|
||||
case ExprType::AnyRef:
|
||||
cachedReturnJSValue_ = ObjectOrNullValue(*(JSObject**)&resultRef_);
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("result type");
|
||||
}
|
||||
|
|
|
@ -1963,6 +1963,7 @@ class DebugFrame
|
|||
{
|
||||
int32_t resultI32_;
|
||||
int64_t resultI64_;
|
||||
intptr_t resultRef_;
|
||||
float resultF32_;
|
||||
double resultF64_;
|
||||
};
|
||||
|
|
|
@ -49,10 +49,10 @@ interface nsIXPConnectWrappedNative;
|
|||
#define XPC_SCRIPTABLE_USE_JSSTUB_FOR_DELPROPERTY (1 << 11)
|
||||
// (1 << 12) is unused
|
||||
#define XPC_SCRIPTABLE_DONT_ENUM_QUERY_INTERFACE (1 << 13)
|
||||
#define XPC_SCRIPTABLE_DONT_ASK_INSTANCE_FOR_SCRIPTABLE (1 << 14)
|
||||
#define XPC_SCRIPTABLE_CLASSINFO_INTERFACES_ONLY (1 << 15)
|
||||
// (1 << 14) is unused
|
||||
// (1 << 15) is unused
|
||||
#define XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE (1 << 16)
|
||||
#define XPC_SCRIPTABLE_ALLOW_PROP_MODS_TO_PROTOTYPE (1 << 17)
|
||||
// (1 << 17) is unused
|
||||
#define XPC_SCRIPTABLE_IS_GLOBAL_OBJECT (1 << 18)
|
||||
#define XPC_SCRIPTABLE_DONT_REFLECT_INTERFACE_NAMES (1 << 19)
|
||||
%}
|
||||
|
@ -100,8 +100,6 @@ interface nsIXPCScriptable : nsISupports
|
|||
in JSContextPtr cx, in JSObjectPtr obj,
|
||||
in jsval val, out boolean bp);
|
||||
|
||||
void postCreatePrototype(in JSContextPtr cx, in JSObjectPtr proto);
|
||||
|
||||
%{ C++
|
||||
#define GET_IT(f_, c_) \
|
||||
bool f_() { \
|
||||
|
@ -119,46 +117,10 @@ interface nsIXPCScriptable : nsISupports
|
|||
GET_IT(UseJSStubForAddProperty, USE_JSSTUB_FOR_ADDPROPERTY)
|
||||
GET_IT(UseJSStubForDelProperty, USE_JSSTUB_FOR_DELPROPERTY)
|
||||
GET_IT(DontEnumQueryInterface, DONT_ENUM_QUERY_INTERFACE)
|
||||
GET_IT(DontAskInstanceForScriptable, DONT_ASK_INSTANCE_FOR_SCRIPTABLE)
|
||||
GET_IT(ClassInfoInterfacesOnly, CLASSINFO_INTERFACES_ONLY)
|
||||
GET_IT(AllowPropModsDuringResolve, ALLOW_PROP_MODS_DURING_RESOLVE)
|
||||
GET_IT(AllowPropModsToPrototype, ALLOW_PROP_MODS_TO_PROTOTYPE)
|
||||
GET_IT(IsGlobalObject, IS_GLOBAL_OBJECT)
|
||||
GET_IT(DontReflectInterfaceNames, DONT_REFLECT_INTERFACE_NAMES)
|
||||
|
||||
#undef GET_IT
|
||||
%}
|
||||
};
|
||||
|
||||
%{ C++
|
||||
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
#define NS_XPCCLASSINFO_IID \
|
||||
{ 0x43b67f01, 0xd4ce, 0x4b82, \
|
||||
{ 0xb3, 0xf8, 0xeb, 0xf2, 0x13, 0x60, 0xfb, 0x7e } }
|
||||
|
||||
class NS_NO_VTABLE nsXPCClassInfo : public nsIClassInfo,
|
||||
public nsIXPCScriptable
|
||||
{
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_XPCCLASSINFO_IID)
|
||||
|
||||
NS_IMETHOD_(MozExternalRefCountType) AddRef() override = 0;
|
||||
NS_IMETHOD_(MozExternalRefCountType) Release() override = 0;
|
||||
|
||||
virtual void PreserveWrapper(nsISupports *aNative) = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsXPCClassInfo, NS_XPCCLASSINFO_IID)
|
||||
|
||||
inline
|
||||
nsresult
|
||||
CallQueryInterface(nsISupports* aSourcePtr,
|
||||
RefPtrGetterAddRefs<nsXPCClassInfo> aDestPtr)
|
||||
{
|
||||
return CallQueryInterface(aSourcePtr,
|
||||
static_cast<nsXPCClassInfo**>(aDestPtr));
|
||||
}
|
||||
|
||||
%}
|
||||
|
|
|
@ -99,9 +99,6 @@ NS_IMETHODIMP XPC_MAP_CLASSNAME::HasInstance(nsIXPConnectWrappedNative* wrapper,
|
|||
{NS_ERROR("never called"); return NS_ERROR_NOT_IMPLEMENTED;}
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP XPC_MAP_CLASSNAME::PostCreatePrototype(JSContext* cx, JSObject* proto)
|
||||
{return NS_OK;}
|
||||
|
||||
/**************************************************************/
|
||||
|
||||
#undef XPC_MAP_CLASSNAME
|
||||
|
|
|
@ -2920,7 +2920,7 @@ XPCJSRuntime::DescribeCustomObjects(JSObject* obj, const js::Class* clasp,
|
|||
char (&name)[72]) const
|
||||
{
|
||||
|
||||
if (!IS_PROTO_CLASS(clasp)) {
|
||||
if (clasp != &XPC_WN_Proto_JSClass) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -156,7 +156,7 @@ XPCWrappedNative::WrapNewGlobal(xpcObjectHelper& nativeHelper,
|
|||
XPCWrappedNative** wrappedGlobal)
|
||||
{
|
||||
AutoJSContext cx;
|
||||
nsISupports* identity = nativeHelper.GetCanonical();
|
||||
nsCOMPtr<nsISupports> identity = do_QueryInterface(nativeHelper.Object());
|
||||
|
||||
// The object should specify that it's meant to be global.
|
||||
MOZ_ASSERT(nativeHelper.GetScriptableFlags() & XPC_SCRIPTABLE_IS_GLOBAL_OBJECT);
|
||||
|
@ -198,8 +198,7 @@ XPCWrappedNative::WrapNewGlobal(xpcObjectHelper& nativeHelper,
|
|||
XPCWrappedNativeProto* proto =
|
||||
XPCWrappedNativeProto::GetNewOrUsed(scope,
|
||||
nativeHelper.GetClassInfo(),
|
||||
scrProto,
|
||||
/* callPostCreatePrototype = */ false);
|
||||
scrProto);
|
||||
if (!proto)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -212,8 +211,7 @@ XPCWrappedNative::WrapNewGlobal(xpcObjectHelper& nativeHelper,
|
|||
|
||||
// Construct the wrapper, which takes over the strong reference to the
|
||||
// native object.
|
||||
RefPtr<XPCWrappedNative> wrapper =
|
||||
new XPCWrappedNative(nativeHelper.forgetCanonical(), proto);
|
||||
RefPtr<XPCWrappedNative> wrapper = new XPCWrappedNative(identity.forget(), proto);
|
||||
|
||||
//
|
||||
// We don't call ::Init() on this wrapper, because our setup requirements
|
||||
|
@ -284,7 +282,7 @@ XPCWrappedNative::GetNewOrUsed(xpcObjectHelper& helper,
|
|||
MOZ_ASSERT(!Scope->GetRuntime()->GCIsRunning(),
|
||||
"XPCWrappedNative::GetNewOrUsed called during GC");
|
||||
|
||||
nsISupports* identity = helper.GetCanonical();
|
||||
nsCOMPtr<nsISupports> identity = do_QueryInterface(helper.Object());
|
||||
|
||||
if (!identity) {
|
||||
NS_ERROR("This XPCOM object fails in QueryInterface to nsISupports!");
|
||||
|
@ -406,7 +404,7 @@ XPCWrappedNative::GetNewOrUsed(xpcObjectHelper& helper,
|
|||
if (!proto)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
wrapper = new XPCWrappedNative(helper.forgetCanonical(), proto);
|
||||
wrapper = new XPCWrappedNative(identity.forget(), proto);
|
||||
} else {
|
||||
RefPtr<XPCNativeInterface> iface = Interface;
|
||||
if (!iface)
|
||||
|
@ -419,8 +417,7 @@ XPCWrappedNative::GetNewOrUsed(xpcObjectHelper& helper,
|
|||
if (!set)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
wrapper = new XPCWrappedNative(helper.forgetCanonical(), Scope,
|
||||
set.forget());
|
||||
wrapper = new XPCWrappedNative(identity.forget(), Scope, set.forget());
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(parent),
|
||||
|
@ -550,14 +547,6 @@ XPCWrappedNative::GatherProtoScriptable(nsIClassInfo* classInfo)
|
|||
{
|
||||
MOZ_ASSERT(classInfo, "bad param");
|
||||
|
||||
nsXPCClassInfo* classInfoHelper = nullptr;
|
||||
CallQueryInterface(classInfo, &classInfoHelper);
|
||||
if (classInfoHelper) {
|
||||
nsCOMPtr<nsIXPCScriptable> helper =
|
||||
dont_AddRef(static_cast<nsIXPCScriptable*>(classInfoHelper));
|
||||
return helper;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIXPCScriptable> helper;
|
||||
nsresult rv = classInfo->GetScriptableHelper(getter_AddRefs(helper));
|
||||
if (NS_SUCCEEDED(rv) && helper) {
|
||||
|
@ -583,13 +572,6 @@ XPCWrappedNative::GatherScriptable(nsISupports* aObj,
|
|||
// Get the class scriptable helper (if present)
|
||||
if (aClassInfo) {
|
||||
scrProto = GatherProtoScriptable(aClassInfo);
|
||||
|
||||
if (scrProto && scrProto->DontAskInstanceForScriptable()) {
|
||||
scrWrapper = scrProto;
|
||||
scrProto.forget(aScrProto);
|
||||
scrWrapper.forget(aScrWrapper);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Do the same for the wrapper specific scriptable
|
||||
|
@ -608,25 +590,10 @@ XPCWrappedNative::GatherScriptable(nsISupports* aObj,
|
|||
MOZ_ASSERT_IF(scrWrapper->DontEnumQueryInterface() && scrProto,
|
||||
scrProto->DontEnumQueryInterface());
|
||||
|
||||
// Can't set DONT_ASK_INSTANCE_FOR_SCRIPTABLE on an instance scriptable
|
||||
// without also setting it on the class scriptable.
|
||||
MOZ_ASSERT_IF(scrWrapper->DontAskInstanceForScriptable(),
|
||||
scrProto && scrProto->DontAskInstanceForScriptable());
|
||||
|
||||
// Can't set CLASSINFO_INTERFACES_ONLY on an instance scriptable
|
||||
// without also setting it on the class scriptable (if present).
|
||||
MOZ_ASSERT_IF(scrWrapper->ClassInfoInterfacesOnly() && scrProto,
|
||||
scrProto->ClassInfoInterfacesOnly());
|
||||
|
||||
// Can't set ALLOW_PROP_MODS_DURING_RESOLVE on an instance scriptable
|
||||
// without also setting it on the class scriptable (if present).
|
||||
MOZ_ASSERT_IF(scrWrapper->AllowPropModsDuringResolve() && scrProto,
|
||||
scrProto->AllowPropModsDuringResolve());
|
||||
|
||||
// Can't set ALLOW_PROP_MODS_TO_PROTOTYPE on an instance scriptable
|
||||
// without also setting it on the class scriptable (if present).
|
||||
MOZ_ASSERT_IF(scrWrapper->AllowPropModsToPrototype() && scrProto,
|
||||
scrProto->AllowPropModsToPrototype());
|
||||
} else {
|
||||
scrWrapper = scrProto;
|
||||
}
|
||||
|
@ -993,15 +960,6 @@ XPCWrappedNative::InitTearOff(XPCWrappedNativeTearOff* aTearOff,
|
|||
// canonical nsISupports for this object.
|
||||
RefPtr<nsISupports> qiResult;
|
||||
|
||||
// If the scriptable helper forbids us from reflecting additional
|
||||
// interfaces, then don't even try the QI, just fail.
|
||||
if (mScriptable &&
|
||||
mScriptable->ClassInfoInterfacesOnly() &&
|
||||
!mSet->HasInterface(aInterface) &&
|
||||
!mSet->HasInterfaceWithAncestor(aInterface)) {
|
||||
return NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
|
||||
// We are about to call out to other code.
|
||||
// So protect our intended tearoff.
|
||||
|
||||
|
|
|
@ -252,18 +252,6 @@ DefinePropertyIfFound(XPCCallContext& ccx,
|
|||
if (!found) {
|
||||
if (reflectToStringAndToSource) {
|
||||
JSNative call;
|
||||
uint32_t flags = 0;
|
||||
|
||||
if (scr) {
|
||||
nsCOMPtr<nsIClassInfo> classInfo = do_QueryInterface(scr);
|
||||
|
||||
if (classInfo) {
|
||||
nsresult rv = classInfo->GetFlags(&flags);
|
||||
if (NS_FAILED(rv))
|
||||
return Throw(rv, ccx);
|
||||
}
|
||||
}
|
||||
|
||||
if (id == xpccx->GetStringID(XPCJSContext::IDX_TO_STRING)) {
|
||||
call = XPC_WN_Shared_ToString;
|
||||
name = xpccx->GetStringName(XPCJSContext::IDX_TO_STRING);
|
||||
|
@ -952,10 +940,9 @@ XPC_WN_GetterSetter(JSContext* cx, unsigned argc, Value* vp)
|
|||
/***************************************************************************/
|
||||
|
||||
static bool
|
||||
XPC_WN_Shared_Proto_Enumerate(JSContext* cx, HandleObject obj)
|
||||
XPC_WN_Proto_Enumerate(JSContext* cx, HandleObject obj)
|
||||
{
|
||||
MOZ_ASSERT(js::GetObjectClass(obj) == &XPC_WN_ModsAllowed_Proto_JSClass ||
|
||||
js::GetObjectClass(obj) == &XPC_WN_NoMods_Proto_JSClass,
|
||||
MOZ_ASSERT(js::GetObjectClass(obj) == &XPC_WN_Proto_JSClass,
|
||||
"bad proto");
|
||||
XPCWrappedNativeProto* self =
|
||||
(XPCWrappedNativeProto*) xpc_GetJSPrivate(obj);
|
||||
|
@ -986,7 +973,7 @@ XPC_WN_Shared_Proto_Enumerate(JSContext* cx, HandleObject obj)
|
|||
}
|
||||
|
||||
static void
|
||||
XPC_WN_Shared_Proto_Finalize(js::FreeOp* fop, JSObject* obj)
|
||||
XPC_WN_Proto_Finalize(js::FreeOp* fop, JSObject* obj)
|
||||
{
|
||||
// This can be null if xpc shutdown has already happened
|
||||
XPCWrappedNativeProto* p = (XPCWrappedNativeProto*) xpc_GetJSPrivate(obj);
|
||||
|
@ -995,7 +982,7 @@ XPC_WN_Shared_Proto_Finalize(js::FreeOp* fop, JSObject* obj)
|
|||
}
|
||||
|
||||
static size_t
|
||||
XPC_WN_Shared_Proto_ObjectMoved(JSObject* obj, JSObject* old)
|
||||
XPC_WN_Proto_ObjectMoved(JSObject* obj, JSObject* old)
|
||||
{
|
||||
// This can be null if xpc shutdown has already happened
|
||||
XPCWrappedNativeProto* p = (XPCWrappedNativeProto*) xpc_GetJSPrivate(obj);
|
||||
|
@ -1007,7 +994,7 @@ XPC_WN_Shared_Proto_ObjectMoved(JSObject* obj, JSObject* old)
|
|||
}
|
||||
|
||||
static void
|
||||
XPC_WN_Shared_Proto_Trace(JSTracer* trc, JSObject* obj)
|
||||
XPC_WN_Proto_Trace(JSTracer* trc, JSObject* obj)
|
||||
{
|
||||
// This can be null if xpc shutdown has already happened
|
||||
XPCWrappedNativeProto* p =
|
||||
|
@ -1018,64 +1005,11 @@ XPC_WN_Shared_Proto_Trace(JSTracer* trc, JSObject* obj)
|
|||
|
||||
/*****************************************************/
|
||||
|
||||
static bool
|
||||
XPC_WN_ModsAllowed_Proto_Resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvep)
|
||||
{
|
||||
MOZ_ASSERT(js::GetObjectClass(obj) == &XPC_WN_ModsAllowed_Proto_JSClass,
|
||||
"bad proto");
|
||||
|
||||
XPCWrappedNativeProto* self =
|
||||
(XPCWrappedNativeProto*) xpc_GetJSPrivate(obj);
|
||||
if (!self)
|
||||
return false;
|
||||
|
||||
XPCCallContext ccx(cx);
|
||||
if (!ccx.IsValid())
|
||||
return false;
|
||||
|
||||
nsCOMPtr<nsIXPCScriptable> scr = self->GetScriptable();
|
||||
return DefinePropertyIfFound(ccx, obj, id,
|
||||
self->GetSet(), nullptr, nullptr,
|
||||
self->GetScope(),
|
||||
true, nullptr, nullptr, scr,
|
||||
JSPROP_ENUMERATE, resolvep);
|
||||
}
|
||||
|
||||
static const js::ClassOps XPC_WN_ModsAllowed_Proto_JSClassOps = {
|
||||
nullptr, // addProperty
|
||||
nullptr, // delProperty
|
||||
XPC_WN_Shared_Proto_Enumerate, // enumerate
|
||||
nullptr, // newEnumerate
|
||||
XPC_WN_ModsAllowed_Proto_Resolve, // resolve
|
||||
nullptr, // mayResolve
|
||||
XPC_WN_Shared_Proto_Finalize, // finalize
|
||||
nullptr, // call
|
||||
nullptr, // construct
|
||||
nullptr, // hasInstance
|
||||
XPC_WN_Shared_Proto_Trace, // trace
|
||||
};
|
||||
|
||||
static const js::ClassExtension XPC_WN_Shared_Proto_ClassExtension = {
|
||||
nullptr, /* weakmapKeyDelegateOp */
|
||||
XPC_WN_Shared_Proto_ObjectMoved
|
||||
};
|
||||
|
||||
const js::Class XPC_WN_ModsAllowed_Proto_JSClass = {
|
||||
"XPC_WN_ModsAllowed_Proto_JSClass",
|
||||
XPC_WRAPPER_FLAGS,
|
||||
&XPC_WN_ModsAllowed_Proto_JSClassOps,
|
||||
JS_NULL_CLASS_SPEC,
|
||||
&XPC_WN_Shared_Proto_ClassExtension,
|
||||
JS_NULL_OBJECT_OPS
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static bool
|
||||
XPC_WN_OnlyIWrite_Proto_AddPropertyStub(JSContext* cx, HandleObject obj, HandleId id,
|
||||
HandleValue v)
|
||||
{
|
||||
MOZ_ASSERT(js::GetObjectClass(obj) == &XPC_WN_NoMods_Proto_JSClass,
|
||||
MOZ_ASSERT(js::GetObjectClass(obj) == &XPC_WN_Proto_JSClass,
|
||||
"bad proto");
|
||||
|
||||
XPCWrappedNativeProto* self =
|
||||
|
@ -1095,9 +1029,9 @@ XPC_WN_OnlyIWrite_Proto_AddPropertyStub(JSContext* cx, HandleObject obj, HandleI
|
|||
}
|
||||
|
||||
static bool
|
||||
XPC_WN_NoMods_Proto_Resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp)
|
||||
XPC_WN_Proto_Resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp)
|
||||
{
|
||||
MOZ_ASSERT(js::GetObjectClass(obj) == &XPC_WN_NoMods_Proto_JSClass,
|
||||
MOZ_ASSERT(js::GetObjectClass(obj) == &XPC_WN_Proto_JSClass,
|
||||
"bad proto");
|
||||
|
||||
XPCWrappedNativeProto* self =
|
||||
|
@ -1120,26 +1054,31 @@ XPC_WN_NoMods_Proto_Resolve(JSContext* cx, HandleObject obj, HandleId id, bool*
|
|||
JSPROP_ENUMERATE, resolvedp);
|
||||
}
|
||||
|
||||
static const js::ClassOps XPC_WN_NoMods_Proto_JSClassOps = {
|
||||
static const js::ClassOps XPC_WN_Proto_JSClassOps = {
|
||||
XPC_WN_OnlyIWrite_Proto_AddPropertyStub, // addProperty
|
||||
XPC_WN_CannotDeletePropertyStub, // delProperty
|
||||
XPC_WN_Shared_Proto_Enumerate, // enumerate
|
||||
XPC_WN_Proto_Enumerate, // enumerate
|
||||
nullptr, // newEnumerate
|
||||
XPC_WN_NoMods_Proto_Resolve, // resolve
|
||||
XPC_WN_Proto_Resolve, // resolve
|
||||
nullptr, // mayResolve
|
||||
XPC_WN_Shared_Proto_Finalize, // finalize
|
||||
XPC_WN_Proto_Finalize, // finalize
|
||||
nullptr, // call
|
||||
nullptr, // construct
|
||||
nullptr, // hasInstance
|
||||
XPC_WN_Shared_Proto_Trace, // trace
|
||||
XPC_WN_Proto_Trace, // trace
|
||||
};
|
||||
|
||||
const js::Class XPC_WN_NoMods_Proto_JSClass = {
|
||||
"XPC_WN_NoMods_Proto_JSClass",
|
||||
static const js::ClassExtension XPC_WN_Proto_ClassExtension = {
|
||||
nullptr, /* weakmapKeyDelegateOp */
|
||||
XPC_WN_Proto_ObjectMoved
|
||||
};
|
||||
|
||||
const js::Class XPC_WN_Proto_JSClass = {
|
||||
"XPC_WN_Proto_JSClass",
|
||||
XPC_WRAPPER_FLAGS,
|
||||
&XPC_WN_NoMods_Proto_JSClassOps,
|
||||
&XPC_WN_Proto_JSClassOps,
|
||||
JS_NULL_CLASS_SPEC,
|
||||
&XPC_WN_Shared_Proto_ClassExtension,
|
||||
&XPC_WN_Proto_ClassExtension,
|
||||
JS_NULL_OBJECT_OPS
|
||||
};
|
||||
|
||||
|
|
|
@ -50,54 +50,24 @@ XPCWrappedNativeProto::~XPCWrappedNativeProto()
|
|||
}
|
||||
|
||||
bool
|
||||
XPCWrappedNativeProto::Init(nsIXPCScriptable* scriptable,
|
||||
bool callPostCreatePrototype)
|
||||
XPCWrappedNativeProto::Init(nsIXPCScriptable* scriptable)
|
||||
{
|
||||
AutoJSContext cx;
|
||||
mScriptable = scriptable;
|
||||
|
||||
const js::Class* jsclazz =
|
||||
(mScriptable && mScriptable->AllowPropModsToPrototype())
|
||||
? &XPC_WN_ModsAllowed_Proto_JSClass
|
||||
: &XPC_WN_NoMods_Proto_JSClass;
|
||||
|
||||
JS::RootedObject global(cx, mScope->GetGlobalJSObject());
|
||||
JS::RootedObject proto(cx, JS_GetObjectPrototype(cx, global));
|
||||
mJSProtoObject = JS_NewObjectWithUniqueType(cx, js::Jsvalify(jsclazz),
|
||||
mJSProtoObject = JS_NewObjectWithUniqueType(cx, js::Jsvalify(&XPC_WN_Proto_JSClass),
|
||||
proto);
|
||||
|
||||
bool success = !!mJSProtoObject;
|
||||
if (success) {
|
||||
JS_SetPrivate(mJSProtoObject, this);
|
||||
if (callPostCreatePrototype)
|
||||
success = CallPostCreatePrototype();
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool
|
||||
XPCWrappedNativeProto::CallPostCreatePrototype()
|
||||
{
|
||||
AutoJSContext cx;
|
||||
|
||||
// Nothing to do if we don't have a scriptable callback.
|
||||
if (!mScriptable)
|
||||
return true;
|
||||
|
||||
// Call the helper. This can handle being called if it's not implemented,
|
||||
// so we don't have to check any sort of "want" here. See xpc_map_end.h.
|
||||
nsresult rv = mScriptable->PostCreatePrototype(cx, mJSProtoObject);
|
||||
if (NS_FAILED(rv)) {
|
||||
JS_SetPrivate(mJSProtoObject, nullptr);
|
||||
mJSProtoObject = nullptr;
|
||||
XPCThrower::Throw(rv, cx);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
XPCWrappedNativeProto::JSProtoObjectFinalized(js::FreeOp* fop, JSObject* obj)
|
||||
{
|
||||
|
@ -138,8 +108,7 @@ XPCWrappedNativeProto::SystemIsBeingShutDown()
|
|||
XPCWrappedNativeProto*
|
||||
XPCWrappedNativeProto::GetNewOrUsed(XPCWrappedNativeScope* scope,
|
||||
nsIClassInfo* classInfo,
|
||||
nsIXPCScriptable* scriptable,
|
||||
bool callPostCreatePrototype)
|
||||
nsIXPCScriptable* scriptable)
|
||||
{
|
||||
AutoJSContext cx;
|
||||
MOZ_ASSERT(scope, "bad param");
|
||||
|
@ -159,7 +128,7 @@ XPCWrappedNativeProto::GetNewOrUsed(XPCWrappedNativeScope* scope,
|
|||
|
||||
proto = new XPCWrappedNativeProto(scope, classInfo, set.forget());
|
||||
|
||||
if (!proto || !proto->Init(scriptable, callPostCreatePrototype)) {
|
||||
if (!proto || !proto->Init(scriptable)) {
|
||||
delete proto.get();
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
EXPORTS += [
|
||||
'BackstagePass.h',
|
||||
'qsObjectHelper.h',
|
||||
'XPCJSMemoryReporter.h',
|
||||
'xpcObjectHelper.h',
|
||||
'xpcpublic.h',
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set ts=8 sts=4 et sw=4 tw=99: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef qsObjectHelper_h
|
||||
#define qsObjectHelper_h
|
||||
|
||||
#include "xpcObjectHelper.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "mozilla/TypeTraits.h"
|
||||
|
||||
class qsObjectHelper : public xpcObjectHelper
|
||||
{
|
||||
public:
|
||||
template <class T>
|
||||
inline
|
||||
qsObjectHelper(T* aObject, nsWrapperCache* aCache)
|
||||
: xpcObjectHelper(ToSupports(aObject), ToCanonicalSupports(aObject),
|
||||
aCache)
|
||||
{}
|
||||
|
||||
template <class T>
|
||||
inline
|
||||
qsObjectHelper(nsCOMPtr<T>& aObject, nsWrapperCache* aCache)
|
||||
: xpcObjectHelper(ToSupports(aObject.get()),
|
||||
ToCanonicalSupports(aObject.get()), aCache)
|
||||
{
|
||||
if (mCanonical) {
|
||||
// Transfer the strong reference.
|
||||
mCanonicalStrong = dont_AddRef(mCanonical);
|
||||
aObject.forget();
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline
|
||||
qsObjectHelper(RefPtr<T>& aObject, nsWrapperCache* aCache)
|
||||
: xpcObjectHelper(ToSupports(aObject.get()),
|
||||
ToCanonicalSupports(aObject.get()), aCache)
|
||||
{
|
||||
if (mCanonical) {
|
||||
// Transfer the strong reference.
|
||||
mCanonicalStrong = dont_AddRef(mCanonical);
|
||||
aObject.forget();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -26,15 +26,11 @@ class xpcObjectHelper
|
|||
{
|
||||
public:
|
||||
explicit xpcObjectHelper(nsISupports* aObject, nsWrapperCache* aCache = nullptr)
|
||||
: mCanonical(nullptr)
|
||||
, mObject(aObject)
|
||||
: mObject(aObject)
|
||||
, mCache(aCache)
|
||||
{
|
||||
if (!mCache) {
|
||||
if (aObject)
|
||||
if (!mCache && aObject) {
|
||||
CallQueryInterface(aObject, &mCache);
|
||||
else
|
||||
mCache = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,57 +39,17 @@ public:
|
|||
return mObject;
|
||||
}
|
||||
|
||||
nsISupports* GetCanonical()
|
||||
{
|
||||
if (!mCanonical) {
|
||||
mCanonicalStrong = do_QueryInterface(mObject);
|
||||
mCanonical = mCanonicalStrong;
|
||||
}
|
||||
return mCanonical;
|
||||
}
|
||||
|
||||
already_AddRefed<nsISupports> forgetCanonical()
|
||||
{
|
||||
MOZ_ASSERT(mCanonical, "Huh, no canonical to forget?");
|
||||
|
||||
if (!mCanonicalStrong)
|
||||
mCanonicalStrong = mCanonical;
|
||||
mCanonical = nullptr;
|
||||
return mCanonicalStrong.forget();
|
||||
}
|
||||
|
||||
nsIClassInfo* GetClassInfo()
|
||||
{
|
||||
if (mXPCClassInfo)
|
||||
return mXPCClassInfo;
|
||||
if (!mClassInfo)
|
||||
mClassInfo = do_QueryInterface(mObject);
|
||||
return mClassInfo;
|
||||
}
|
||||
nsXPCClassInfo* GetXPCClassInfo()
|
||||
{
|
||||
if (!mXPCClassInfo) {
|
||||
CallQueryInterface(mObject, getter_AddRefs(mXPCClassInfo));
|
||||
}
|
||||
return mXPCClassInfo;
|
||||
}
|
||||
|
||||
already_AddRefed<nsXPCClassInfo> forgetXPCClassInfo()
|
||||
{
|
||||
GetXPCClassInfo();
|
||||
|
||||
return mXPCClassInfo.forget();
|
||||
}
|
||||
|
||||
// We assert that we can reach an nsIXPCScriptable somehow.
|
||||
uint32_t GetScriptableFlags()
|
||||
{
|
||||
// Try getting an nsXPCClassInfo - this handles DOM scriptable helpers.
|
||||
nsCOMPtr<nsIXPCScriptable> sinfo = GetXPCClassInfo();
|
||||
|
||||
// If that didn't work, try just QI-ing. This handles BackstagePass.
|
||||
if (!sinfo)
|
||||
sinfo = do_QueryInterface(GetCanonical());
|
||||
nsCOMPtr<nsIXPCScriptable> sinfo = do_QueryInterface(mObject);
|
||||
|
||||
// We should have something by now.
|
||||
MOZ_ASSERT(sinfo);
|
||||
|
@ -107,22 +63,6 @@ public:
|
|||
return mCache;
|
||||
}
|
||||
|
||||
protected:
|
||||
xpcObjectHelper(nsISupports* aObject, nsISupports* aCanonical,
|
||||
nsWrapperCache* aCache)
|
||||
: mCanonical(aCanonical)
|
||||
, mObject(aObject)
|
||||
, mCache(aCache)
|
||||
{
|
||||
if (!mCache && aObject)
|
||||
CallQueryInterface(aObject, &mCache);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupports> mCanonicalStrong;
|
||||
nsISupports* MOZ_UNSAFE_REF("xpcObjectHelper has been specifically optimized "
|
||||
"to avoid unnecessary AddRefs and Releases. "
|
||||
"(see bug 565742)") mCanonical;
|
||||
|
||||
private:
|
||||
xpcObjectHelper(xpcObjectHelper& aOther) = delete;
|
||||
|
||||
|
@ -131,7 +71,6 @@ private:
|
|||
"(see bug 565742)") mObject;
|
||||
nsWrapperCache* mCache;
|
||||
nsCOMPtr<nsIClassInfo> mClassInfo;
|
||||
RefPtr<nsXPCClassInfo> mXPCClassInfo;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -784,8 +784,7 @@ private:
|
|||
// visibility from more than one .cpp file.
|
||||
|
||||
extern const js::Class XPC_WN_NoHelper_JSClass;
|
||||
extern const js::Class XPC_WN_NoMods_Proto_JSClass;
|
||||
extern const js::Class XPC_WN_ModsAllowed_Proto_JSClass;
|
||||
extern const js::Class XPC_WN_Proto_JSClass;
|
||||
extern const js::Class XPC_WN_Tearoff_JSClass;
|
||||
#define XPC_WN_TEAROFF_RESERVED_SLOTS 1
|
||||
#define XPC_WN_TEAROFF_FLAT_OBJECT_SLOT 0
|
||||
|
@ -797,15 +796,6 @@ XPC_WN_CallMethod(JSContext* cx, unsigned argc, JS::Value* vp);
|
|||
extern bool
|
||||
XPC_WN_GetterSetter(JSContext* cx, unsigned argc, JS::Value* vp);
|
||||
|
||||
// Maybe this macro should check for class->enumerate ==
|
||||
// XPC_WN_Shared_Proto_Enumerate or something rather than checking for
|
||||
// 4 classes?
|
||||
static inline bool IS_PROTO_CLASS(const js::Class* clazz)
|
||||
{
|
||||
return clazz == &XPC_WN_NoMods_Proto_JSClass ||
|
||||
clazz == &XPC_WN_ModsAllowed_Proto_JSClass;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
// XPCWrappedNativeScope is one-to-one with a JS global object.
|
||||
|
||||
|
@ -1277,8 +1267,7 @@ public:
|
|||
static XPCWrappedNativeProto*
|
||||
GetNewOrUsed(XPCWrappedNativeScope* scope,
|
||||
nsIClassInfo* classInfo,
|
||||
nsIXPCScriptable* scriptable,
|
||||
bool callPostCreatePrototype = true);
|
||||
nsIXPCScriptable* scriptable);
|
||||
|
||||
XPCWrappedNativeScope*
|
||||
GetScope() const {return mScope;}
|
||||
|
@ -1301,7 +1290,6 @@ public:
|
|||
nsIXPCScriptable*
|
||||
GetScriptable() const { return mScriptable; }
|
||||
|
||||
bool CallPostCreatePrototype();
|
||||
void JSProtoObjectFinalized(js::FreeOp* fop, JSObject* obj);
|
||||
void JSProtoObjectMoved(JSObject* obj, const JSObject* old);
|
||||
|
||||
|
@ -1345,7 +1333,7 @@ protected:
|
|||
nsIClassInfo* ClassInfo,
|
||||
already_AddRefed<XPCNativeSet>&& Set);
|
||||
|
||||
bool Init(nsIXPCScriptable* scriptable, bool callPostCreatePrototype);
|
||||
bool Init(nsIXPCScriptable* scriptable);
|
||||
|
||||
private:
|
||||
#ifdef DEBUG
|
||||
|
|
|
@ -1451,11 +1451,6 @@ IsWindow(JSContext* cx, JSObject* wrapper)
|
|||
void
|
||||
XPCWrappedNativeXrayTraits::preserveWrapper(JSObject* target)
|
||||
{
|
||||
XPCWrappedNative* wn = XPCWrappedNative::Get(target);
|
||||
RefPtr<nsXPCClassInfo> ci;
|
||||
CallQueryInterface(wn->Native(), getter_AddRefs(ci));
|
||||
if (ci)
|
||||
ci->PreserveWrapper(wn->Native());
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
|
@ -259,14 +259,6 @@ nsFrameManager::RestoreFrameState(nsIFrame* aFrame,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsFrameManager::DestroyAnonymousContent(already_AddRefed<nsIContent> aContent)
|
||||
{
|
||||
if (nsCOMPtr<nsIContent> content = aContent) {
|
||||
content->UnbindFromTree();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsFrameManager::AddSizeOfIncludingThis(nsWindowSizes& aSizes) const
|
||||
{
|
||||
|
|
|
@ -93,8 +93,6 @@ public:
|
|||
|
||||
void RestoreFrameStateFor(nsIFrame* aFrame, nsILayoutHistoryState* aState);
|
||||
|
||||
void DestroyAnonymousContent(already_AddRefed<nsIContent> aContent);
|
||||
|
||||
void AddSizeOfIncludingThis(nsWindowSizes& aSizes) const;
|
||||
|
||||
protected:
|
||||
|
|
|
@ -451,6 +451,7 @@ nsTextControlFrame::CreateRootNode()
|
|||
MOZ_ASSERT(!mRootNode);
|
||||
|
||||
mRootNode = CreateEmptyDiv(*this);
|
||||
mRootNode->SetIsNativeAnonymousRoot();
|
||||
|
||||
mMutationObserver = new nsAnonDivObserver(*this);
|
||||
mRootNode->AddMutationObserver(mMutationObserver);
|
||||
|
|
|
@ -246,8 +246,10 @@ nsReflowStatus::UpdateTruncated(const ReflowInput& aReflowInput,
|
|||
nsIFrame::DestroyAnonymousContent(nsPresContext* aPresContext,
|
||||
already_AddRefed<nsIContent>&& aContent)
|
||||
{
|
||||
aPresContext->PresShell()->FrameConstructor()
|
||||
->DestroyAnonymousContent(Move(aContent));
|
||||
if (nsCOMPtr<nsIContent> content = aContent) {
|
||||
aPresContext->EventStateManager()->NativeAnonymousContentRemoved(content);
|
||||
content->UnbindFromTree();
|
||||
}
|
||||
}
|
||||
|
||||
// Formerly the nsIFrameDebug interface
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче