mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
merge mozilla-inbound to mozilla-central a=merge
This commit is contained in:
commit
ef8e5b7042
@ -154,6 +154,12 @@ SelectionManager::ProcessTextSelChangeEvent(AccEvent* aEvent)
|
||||
return;
|
||||
|
||||
Selection* selection = caretCntr->DOMSelection();
|
||||
|
||||
// XXX Sometimes we can't get a selection for caretCntr, in that case assume
|
||||
// event->mSel is correct.
|
||||
if (!selection)
|
||||
selection = event->mSel;
|
||||
|
||||
mCaretOffset = caretCntr->DOMPointToOffset(selection->GetFocusNode(),
|
||||
selection->FocusOffset());
|
||||
mAccWithCaret = caretCntr;
|
||||
@ -179,8 +185,7 @@ SelectionManager::NotifySelectionChanged(nsIDOMDocument* aDOMDocument,
|
||||
logging::SelChange(aSelection, document, aReason);
|
||||
#endif
|
||||
|
||||
// Don't fire events until document is loaded.
|
||||
if (document && document->IsContentLoaded()) {
|
||||
if (document) {
|
||||
// Selection manager has longer lifetime than any document accessible,
|
||||
// so that we are guaranteed that the notification is processed before
|
||||
// the selection manager is destroyed.
|
||||
|
@ -12,36 +12,17 @@
|
||||
#include "mozilla/dom/ChildIterator.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// WalkState
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
struct WalkState
|
||||
{
|
||||
WalkState(nsIContent *aContent, uint32_t aFilter) :
|
||||
content(aContent), prevState(nullptr), iter(aContent, aFilter) {}
|
||||
|
||||
nsCOMPtr<nsIContent> content;
|
||||
WalkState *prevState;
|
||||
dom::AllChildrenIterator iter;
|
||||
};
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// TreeWalker
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TreeWalker::
|
||||
TreeWalker(Accessible* aContext, nsIContent* aContent, uint32_t aFlags) :
|
||||
mDoc(aContext->Document()), mContext(aContext),
|
||||
mFlags(aFlags), mState(nullptr)
|
||||
mDoc(aContext->Document()), mContext(aContext), mAnchorNode(aContent),
|
||||
mFlags(aFlags)
|
||||
{
|
||||
NS_ASSERTION(aContent, "No node for the accessible tree walker!");
|
||||
|
||||
@ -50,17 +31,13 @@ TreeWalker::
|
||||
mChildFilter |= nsIContent::eSkipPlaceholderContent;
|
||||
|
||||
if (aContent)
|
||||
mState = new WalkState(aContent, mChildFilter);
|
||||
PushState(aContent);
|
||||
|
||||
MOZ_COUNT_CTOR(TreeWalker);
|
||||
}
|
||||
|
||||
TreeWalker::~TreeWalker()
|
||||
{
|
||||
// Clear state stack from memory
|
||||
while (mState)
|
||||
PopState();
|
||||
|
||||
MOZ_COUNT_DTOR(TreeWalker);
|
||||
}
|
||||
|
||||
@ -68,74 +45,66 @@ TreeWalker::~TreeWalker()
|
||||
// TreeWalker: private
|
||||
|
||||
Accessible*
|
||||
TreeWalker::NextChildInternal(bool aNoWalkUp)
|
||||
TreeWalker::NextChild()
|
||||
{
|
||||
if (!mState || !mState->content)
|
||||
if (mStateStack.IsEmpty())
|
||||
return nullptr;
|
||||
|
||||
while (nsIContent* childNode = mState->iter.GetNextChild()) {
|
||||
bool isSubtreeHidden = false;
|
||||
Accessible* accessible = mFlags & eWalkCache ?
|
||||
mDoc->GetAccessible(childNode) :
|
||||
GetAccService()->GetOrCreateAccessible(childNode, mContext,
|
||||
&isSubtreeHidden);
|
||||
dom::AllChildrenIterator* top = &mStateStack[mStateStack.Length() - 1];
|
||||
while (top) {
|
||||
while (nsIContent* childNode = top->GetNextChild()) {
|
||||
bool isSubtreeHidden = false;
|
||||
Accessible* accessible = mFlags & eWalkCache ?
|
||||
mDoc->GetAccessible(childNode) :
|
||||
GetAccService()->GetOrCreateAccessible(childNode, mContext,
|
||||
&isSubtreeHidden);
|
||||
|
||||
if (accessible)
|
||||
return accessible;
|
||||
|
||||
// Walk down into subtree to find accessibles.
|
||||
if (!isSubtreeHidden && childNode->IsElement()) {
|
||||
PushState(childNode);
|
||||
accessible = NextChildInternal(true);
|
||||
if (accessible)
|
||||
return accessible;
|
||||
|
||||
// Walk down into subtree to find accessibles.
|
||||
if (!isSubtreeHidden && childNode->IsElement())
|
||||
top = PushState(childNode);
|
||||
}
|
||||
|
||||
top = PopState();
|
||||
}
|
||||
|
||||
// No more children, get back to the parent.
|
||||
nsIContent* anchorNode = mState->content;
|
||||
PopState();
|
||||
if (aNoWalkUp)
|
||||
return nullptr;
|
||||
|
||||
if (mState)
|
||||
return NextChildInternal(false);
|
||||
|
||||
// If we traversed the whole subtree of the anchor node. Move to next node
|
||||
// relative anchor node within the context subtree if possible.
|
||||
if (mFlags != eWalkContextTree)
|
||||
return nullptr;
|
||||
|
||||
while (anchorNode != mContext->GetNode()) {
|
||||
nsINode* parentNode = anchorNode->GetFlattenedTreeParent();
|
||||
nsINode* contextNode = mContext->GetNode();
|
||||
while (mAnchorNode != contextNode) {
|
||||
nsINode* parentNode = mAnchorNode->GetFlattenedTreeParent();
|
||||
if (!parentNode || !parentNode->IsElement())
|
||||
return nullptr;
|
||||
|
||||
PushState(parentNode->AsElement());
|
||||
while (nsIContent* childNode = mState->iter.GetNextChild()) {
|
||||
if (childNode == anchorNode)
|
||||
return NextChildInternal(false);
|
||||
nsIContent* parent = parentNode->AsElement();
|
||||
top = mStateStack.AppendElement(dom::AllChildrenIterator(parent,
|
||||
mChildFilter));
|
||||
while (nsIContent* childNode = top->GetNextChild()) {
|
||||
if (childNode == mAnchorNode) {
|
||||
mAnchorNode = parent;
|
||||
return NextChild();
|
||||
}
|
||||
}
|
||||
PopState();
|
||||
|
||||
anchorNode = parentNode->AsElement();
|
||||
// XXX We really should never get here, it means we're trying to find an
|
||||
// accessible for a dom node where iterating over its parent's children
|
||||
// doesn't return it. However this sometimes happens when we're asked for
|
||||
// the nearest accessible to place holder content which we ignore.
|
||||
mAnchorNode = parent;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
dom::AllChildrenIterator*
|
||||
TreeWalker::PopState()
|
||||
{
|
||||
WalkState* prevToLastState = mState->prevState;
|
||||
delete mState;
|
||||
mState = prevToLastState;
|
||||
}
|
||||
|
||||
void
|
||||
TreeWalker::PushState(nsIContent* aContent)
|
||||
{
|
||||
WalkState* nextToLastState = new WalkState(aContent, mChildFilter);
|
||||
nextToLastState->prevState = mState;
|
||||
mState = nextToLastState;
|
||||
size_t length = mStateStack.Length();
|
||||
mStateStack.RemoveElementAt(length - 1);
|
||||
return mStateStack.IsEmpty() ? nullptr : &mStateStack[mStateStack.Length() - 1];
|
||||
}
|
||||
|
@ -8,6 +8,8 @@
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include <stdint.h>
|
||||
#include "mozilla/dom/ChildIterator.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
class nsIContent;
|
||||
|
||||
@ -17,8 +19,6 @@ namespace a11y {
|
||||
class Accessible;
|
||||
class DocAccessible;
|
||||
|
||||
struct WalkState;
|
||||
|
||||
/**
|
||||
* This class is used to walk the DOM tree to create accessible tree.
|
||||
*/
|
||||
@ -50,43 +50,36 @@ public:
|
||||
* rejected during tree creation then the caller should be unbind it
|
||||
* from the document.
|
||||
*/
|
||||
Accessible* NextChild()
|
||||
{
|
||||
return NextChildInternal(false);
|
||||
}
|
||||
Accessible* NextChild();
|
||||
|
||||
private:
|
||||
TreeWalker();
|
||||
TreeWalker(const TreeWalker&);
|
||||
TreeWalker& operator =(const TreeWalker&);
|
||||
|
||||
/**
|
||||
* Return the next child accessible.
|
||||
*
|
||||
* @param aNoWalkUp [in] specifies the walk direction, true means we
|
||||
* shouldn't go up through the tree if we failed find
|
||||
* accessible children.
|
||||
*/
|
||||
Accessible* NextChildInternal(bool aNoWalkUp);
|
||||
|
||||
/**
|
||||
* Create new state for the given node and push it on top of stack.
|
||||
*
|
||||
* @note State stack is used to navigate up/down the DOM subtree during
|
||||
* accessible children search.
|
||||
*/
|
||||
void PushState(nsIContent* aNode);
|
||||
dom::AllChildrenIterator* PushState(nsIContent* aContent)
|
||||
{
|
||||
return mStateStack.AppendElement(dom::AllChildrenIterator(aContent,
|
||||
mChildFilter));
|
||||
}
|
||||
|
||||
/**
|
||||
* Pop state from stack.
|
||||
*/
|
||||
void PopState();
|
||||
dom::AllChildrenIterator* PopState();
|
||||
|
||||
DocAccessible* mDoc;
|
||||
Accessible* mContext;
|
||||
nsIContent* mAnchorNode;
|
||||
nsAutoTArray<dom::AllChildrenIterator, 20> mStateStack;
|
||||
int32_t mChildFilter;
|
||||
uint32_t mFlags;
|
||||
WalkState* mState;
|
||||
};
|
||||
|
||||
} // namespace a11y
|
||||
|
@ -1743,10 +1743,11 @@ function textChangeChecker(aID, aStart, aEnd, aTextOrFunc, aIsInserted, aFromUse
|
||||
/**
|
||||
* Caret move events checker.
|
||||
*/
|
||||
function caretMoveChecker(aCaretOffset, aTargetOrFunc, aTargetFuncArg)
|
||||
function caretMoveChecker(aCaretOffset, aTargetOrFunc, aTargetFuncArg,
|
||||
aIsAsync)
|
||||
{
|
||||
this.__proto__ = new invokerChecker(EVENT_TEXT_CARET_MOVED,
|
||||
aTargetOrFunc, aTargetFuncArg);
|
||||
aTargetOrFunc, aTargetFuncArg, aIsAsync);
|
||||
|
||||
this.check = function caretMoveChecker_check(aEvent)
|
||||
{
|
||||
@ -1756,6 +1757,12 @@ function caretMoveChecker(aCaretOffset, aTargetOrFunc, aTargetFuncArg)
|
||||
}
|
||||
}
|
||||
|
||||
function asyncCaretMoveChecker(aCaretOffset, aTargetOrFunc, aTargetFuncArg)
|
||||
{
|
||||
this.__proto__ = new caretMoveChecker(aCaretOffset, aTargetOrFunc,
|
||||
aTargetFuncArg, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Text selection change checker.
|
||||
*/
|
||||
|
@ -46,6 +46,7 @@ skip-if = os == 'win' || os == 'linux'
|
||||
[test_namechange.xul]
|
||||
[test_namechange.html]
|
||||
[test_scroll.xul]
|
||||
[test_scroll_caret.xul]
|
||||
[test_selection.html]
|
||||
skip-if = buildapp == 'mulet'
|
||||
[test_selection.xul]
|
||||
|
@ -119,5 +119,63 @@
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
</p>
|
||||
|
||||
<h1 id="heading_1">heading 1</h1>
|
||||
<p style="color: blue">
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
</p>
|
||||
</body>
|
||||
<html>
|
||||
|
91
accessible/tests/mochitest/events/test_scroll_caret.xul
Normal file
91
accessible/tests/mochitest/events/test_scroll_caret.xul
Normal file
@ -0,0 +1,91 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/chrome-harness.js"/>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js" />
|
||||
<script type="application/javascript"
|
||||
src="../role.js" />
|
||||
<script type="application/javascript"
|
||||
src="../states.js" />
|
||||
<script type="application/javascript"
|
||||
src="../events.js" />
|
||||
<script type="application/javascript"
|
||||
src="../browser.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Tests
|
||||
|
||||
function getAnchorJumpInTabDocument(aTabIdx)
|
||||
{
|
||||
var tabDoc = aTabIdx ? tabDocumentAt(aTabIdx) : currentTabDocument();
|
||||
return tabDoc.querySelector("h1[id='heading_1']");
|
||||
}
|
||||
|
||||
function loadTab(aURL)
|
||||
{
|
||||
this.eventSeq = [
|
||||
new asyncInvokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, currentTabDocument),
|
||||
new asyncCaretMoveChecker(0, getAnchorJumpInTabDocument)
|
||||
];
|
||||
|
||||
this.invoke = function loadTab_invoke()
|
||||
{
|
||||
tabBrowser().loadURI(aURL);
|
||||
}
|
||||
|
||||
this.getID = function loadTab_getID()
|
||||
{
|
||||
return "load tab: " + aURL;
|
||||
}
|
||||
}
|
||||
|
||||
//gA11yEventDumpToConsole = true; // debug stuff
|
||||
|
||||
var gQueue = null;
|
||||
function doTest()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
var url = "http://mochi.test:8888/a11y/accessible/tests/mochitest/events/scroll.html#heading_1";
|
||||
gQueue.push(new loadTab(url));
|
||||
gQueue.onFinish = function() { closeBrowserWindow(); }
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
openBrowserWindow(doTest);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<vbox flex="1" style="overflow: auto;">
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=1056459"
|
||||
title="Make sure caret move event is fired when document receive focus">
|
||||
Mozilla Bug 1056459
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox id="eventdump"></vbox>
|
||||
</vbox>
|
||||
</window>
|
@ -92,6 +92,8 @@
|
||||
testWordAt("div17", 3, "you", kOk);
|
||||
testWordAt("div17", 4, "here", kTodo);
|
||||
|
||||
testWords("input_1", ["foo", "bar"]);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
@ -125,5 +127,7 @@
|
||||
<div id="div16">3+4*5=23</div>
|
||||
<div id="div17">Hello. Friend, are you here?!</div>
|
||||
</pre>
|
||||
<input id="input_1" type="text" value="foo bar" placeholder="something or other">
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -684,7 +684,7 @@ class Automation(object):
|
||||
import fix_stack_using_bpsyms as stackFixerModule
|
||||
stackFixerFunction = lambda line: stackFixerModule.fixSymbols(line, symbolsPath)
|
||||
del sys.path[0]
|
||||
elif self.IS_DEBUG_BUILD and self.IS_MAC and False:
|
||||
elif self.IS_DEBUG_BUILD and self.IS_MAC:
|
||||
# Run each line through a function in fix_macosx_stack.py (uses atos)
|
||||
sys.path.insert(0, utilityPath)
|
||||
import fix_macosx_stack as stackFixerModule
|
||||
|
@ -1426,7 +1426,15 @@ nsScriptSecurityManager::AddSitesToFileURIWhitelist(const nsCString& aSiteList)
|
||||
{
|
||||
// Grab the current site.
|
||||
bound = SkipUntil<IsWhitespace>(aSiteList, base);
|
||||
auto site = Substring(aSiteList, base, bound - base);
|
||||
nsAutoCString site(Substring(aSiteList, base, bound - base));
|
||||
|
||||
// Check if the URI is schemeless. If so, add both http and https.
|
||||
nsAutoCString unused;
|
||||
if (NS_FAILED(sIOService->ExtractScheme(site, unused))) {
|
||||
AddSitesToFileURIWhitelist(NS_LITERAL_CSTRING("http://") + site);
|
||||
AddSitesToFileURIWhitelist(NS_LITERAL_CSTRING("https://") + site);
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert it to a URI and add it to our list.
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
|
@ -82,11 +82,13 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=995943
|
||||
pushPrefs.bind(null, [['capability.policy.policynames', ',somepolicy, someotherpolicy, '],
|
||||
['capability.policy.somepolicy.checkloaduri.enabled', 'allaccess'],
|
||||
['capability.policy.someotherpolicy.checkloaduri.enabled', 'nope'],
|
||||
['capability.policy.somepolicy.sites', ' http://example.org https://example.com'],
|
||||
['capability.policy.somepolicy.sites', ' http://example.org https://example.com test1.example.com'],
|
||||
['capability.policy.someotherpolicy.sites', 'http://example.net ']]))
|
||||
.then(checkLoadFileURI.bind(null, 'http://example.org', true))
|
||||
.then(checkLoadFileURI.bind(null, 'http://example.com', false))
|
||||
.then(checkLoadFileURI.bind(null, 'http://example.net', false))
|
||||
.then(checkLoadFileURI.bind(null, 'http://test1.example.com', true))
|
||||
.then(checkLoadFileURI.bind(null, 'https://test1.example.com', true))
|
||||
.then(pushPrefs.bind(null, [['capability.policy.someotherpolicy.checkloaduri.enabled', 'allAccess']]))
|
||||
.then(checkLoadFileURI.bind(null, 'http://example.net', true))
|
||||
.then(popPrefs)
|
||||
|
@ -574,6 +574,10 @@ def tarjan(V, E):
|
||||
|
||||
|
||||
def main():
|
||||
# Suppress the build time check if MOZ_NO_BUILD_TIME_SM_CHECKS is set.
|
||||
if "MOZ_NO_BUILD_TIME_SM_CHECKS" in os.environ:
|
||||
sys.exit(0)
|
||||
|
||||
ok = check_style()
|
||||
|
||||
if ok:
|
||||
|
@ -983,6 +983,62 @@ public:
|
||||
*/
|
||||
nsresult SetBoolAttr(nsIAtom* aAttr, bool aValue);
|
||||
|
||||
/**
|
||||
* Helper method for NS_IMPL_ENUM_ATTR_DEFAULT_VALUE.
|
||||
* Gets the enum value string of an attribute and using a default value if
|
||||
* the attribute is missing or the string is an invalid enum value.
|
||||
*
|
||||
* @param aType the name of the attribute.
|
||||
* @param aDefault the default value if the attribute is missing or invalid.
|
||||
* @param aResult string corresponding to the value [out].
|
||||
*/
|
||||
void GetEnumAttr(nsIAtom* aAttr,
|
||||
const char* aDefault,
|
||||
nsAString& aResult) const;
|
||||
|
||||
/**
|
||||
* Helper method for NS_IMPL_ENUM_ATTR_DEFAULT_MISSING_INVALID_VALUES.
|
||||
* Gets the enum value string of an attribute and using the default missing
|
||||
* value if the attribute is missing or the default invalid value if the
|
||||
* string is an invalid enum value.
|
||||
*
|
||||
* @param aType the name of the attribute.
|
||||
* @param aDefaultMissing the default value if the attribute is missing. If
|
||||
null and the attribute is missing, aResult will be
|
||||
set to the null DOMString; this only matters for
|
||||
cases in which we're reflecting a nullable string.
|
||||
* @param aDefaultInvalid the default value if the attribute is invalid.
|
||||
* @param aResult string corresponding to the value [out].
|
||||
*/
|
||||
void GetEnumAttr(nsIAtom* aAttr,
|
||||
const char* aDefaultMissing,
|
||||
const char* aDefaultInvalid,
|
||||
nsAString& aResult) const;
|
||||
|
||||
/**
|
||||
* Unset an attribute.
|
||||
*/
|
||||
void UnsetAttr(nsIAtom* aAttr, ErrorResult& aError)
|
||||
{
|
||||
aError = UnsetAttr(kNameSpaceID_None, aAttr, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an attribute in the simplest way possible.
|
||||
*/
|
||||
void SetAttr(nsIAtom* aAttr, const nsAString& aValue, ErrorResult& aError)
|
||||
{
|
||||
aError = SetAttr(kNameSpaceID_None, aAttr, aValue, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a content attribute via a reflecting nullable string IDL
|
||||
* attribute (e.g. a CORS attribute). If DOMStringIsNull(aValue),
|
||||
* this will actually remove the content attribute.
|
||||
*/
|
||||
void SetOrRemoveNullableStringAttr(nsIAtom* aName, const nsAString& aValue,
|
||||
ErrorResult& aError);
|
||||
|
||||
/**
|
||||
* Retrieve the ratio of font-size-inflated text font size to computed font
|
||||
* size for this element. This will query the element for its primary frame,
|
||||
|
@ -2349,8 +2349,6 @@ public:
|
||||
virtual nsHTMLDocument* AsHTMLDocument() { return nullptr; }
|
||||
virtual mozilla::dom::SVGDocument* AsSVGDocument() { return nullptr; }
|
||||
|
||||
virtual JSObject* WrapObject(JSContext *aCx) MOZ_OVERRIDE;
|
||||
|
||||
// Each import tree has exactly one master document which is
|
||||
// the root of the tree, and owns the browser context.
|
||||
virtual already_AddRefed<nsIDocument> MasterDocument() = 0;
|
||||
|
@ -3107,6 +3107,50 @@ Element::SetBoolAttr(nsIAtom* aAttr, bool aValue)
|
||||
return UnsetAttr(kNameSpaceID_None, aAttr, true);
|
||||
}
|
||||
|
||||
void
|
||||
Element::GetEnumAttr(nsIAtom* aAttr,
|
||||
const char* aDefault,
|
||||
nsAString& aResult) const
|
||||
{
|
||||
GetEnumAttr(aAttr, aDefault, aDefault, aResult);
|
||||
}
|
||||
|
||||
void
|
||||
Element::GetEnumAttr(nsIAtom* aAttr,
|
||||
const char* aDefaultMissing,
|
||||
const char* aDefaultInvalid,
|
||||
nsAString& aResult) const
|
||||
{
|
||||
const nsAttrValue* attrVal = mAttrsAndChildren.GetAttr(aAttr);
|
||||
|
||||
aResult.Truncate();
|
||||
|
||||
if (!attrVal) {
|
||||
if (aDefaultMissing) {
|
||||
AppendASCIItoUTF16(nsDependentCString(aDefaultMissing), aResult);
|
||||
} else {
|
||||
SetDOMStringToNull(aResult);
|
||||
}
|
||||
} else {
|
||||
if (attrVal->Type() == nsAttrValue::eEnum) {
|
||||
attrVal->GetEnumString(aResult, true);
|
||||
} else if (aDefaultInvalid) {
|
||||
AppendASCIItoUTF16(nsDependentCString(aDefaultInvalid), aResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Element::SetOrRemoveNullableStringAttr(nsIAtom* aName, const nsAString& aValue,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
if (DOMStringIsNull(aValue)) {
|
||||
UnsetAttr(aName, aError);
|
||||
} else {
|
||||
SetAttr(aName, aValue, aError);
|
||||
}
|
||||
}
|
||||
|
||||
Directionality
|
||||
Element::GetComputedDirectionality() const
|
||||
{
|
||||
|
@ -150,6 +150,9 @@
|
||||
#include "nsHtml5TreeOpExecutor.h"
|
||||
#include "mozilla/dom/HTMLLinkElement.h"
|
||||
#include "mozilla/dom/HTMLMediaElement.h"
|
||||
#ifdef MOZ_MEDIA_NAVIGATOR
|
||||
#include "mozilla/MediaManager.h"
|
||||
#endif // MOZ_MEDIA_NAVIGATOR
|
||||
#ifdef MOZ_WEBRTC
|
||||
#include "IPeerConnection.h"
|
||||
#endif // MOZ_WEBRTC
|
||||
@ -8503,6 +8506,14 @@ nsDocument::CanSavePresentation(nsIRequest *aNewRequest)
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef MOZ_MEDIA_NAVIGATOR
|
||||
// Check if we have active GetUserMedia use
|
||||
if (MediaManager::Exists() && win &&
|
||||
MediaManager::Get()->IsWindowStillActive(win->WindowID())) {
|
||||
return false;
|
||||
}
|
||||
#endif // MOZ_MEDIA_NAVIGATOR
|
||||
|
||||
#ifdef MOZ_WEBRTC
|
||||
// Check if we have active PeerConnections
|
||||
nsCOMPtr<IPeerConnectionManager> pcManager =
|
||||
@ -12258,54 +12269,6 @@ nsDocument::Evaluate(const nsAString& aExpression, nsIDOMNode* aContextNode,
|
||||
aInResult, aResult);
|
||||
}
|
||||
|
||||
// This is just a hack around the fact that window.document is not
|
||||
// [Unforgeable] yet.
|
||||
JSObject*
|
||||
nsIDocument::WrapObject(JSContext *aCx)
|
||||
{
|
||||
MOZ_ASSERT(IsDOMBinding());
|
||||
|
||||
JS::Rooted<JSObject*> obj(aCx, nsINode::WrapObject(aCx));
|
||||
if (!obj) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(GetInnerWindow());
|
||||
if (!win ||
|
||||
static_cast<nsGlobalWindow*>(win.get())->IsDOMBinding()) {
|
||||
// No window or window on new DOM binding, nothing else to do here.
|
||||
return obj;
|
||||
}
|
||||
|
||||
if (this != win->GetExtantDoc()) {
|
||||
// We're not the current document; we're also done here
|
||||
return obj;
|
||||
}
|
||||
|
||||
JSAutoCompartment ac(aCx, obj);
|
||||
|
||||
JS::Rooted<JS::Value> winVal(aCx);
|
||||
nsresult rv = nsContentUtils::WrapNative(aCx, win, &NS_GET_IID(nsIDOMWindow),
|
||||
&winVal,
|
||||
false);
|
||||
if (NS_FAILED(rv)) {
|
||||
Throw(aCx, rv);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NS_NAMED_LITERAL_STRING(doc_str, "document");
|
||||
|
||||
JS::Rooted<JSObject*> winObj(aCx, &winVal.toObject());
|
||||
if (!JS_DefineUCProperty(aCx, winObj, doc_str.get(),
|
||||
doc_str.Length(), obj,
|
||||
JSPROP_READONLY | JSPROP_ENUMERATE,
|
||||
JS_PropertyStub, JS_StrictPropertyStub)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
XPathEvaluator*
|
||||
nsIDocument::XPathEvaluator()
|
||||
{
|
||||
|
@ -64,7 +64,6 @@
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/dom/DOMImplementation.h"
|
||||
#include "mozilla/dom/StyleSheetList.h"
|
||||
#include "nsIDOMTouchEvent.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
@ -363,10 +363,16 @@ public:
|
||||
|
||||
// XPCOM GetCurrentSrc() is OK
|
||||
|
||||
// XPCOM GetCrossorigin() is OK
|
||||
void SetCrossOrigin(const nsAString& aValue, ErrorResult& aRv)
|
||||
void GetCrossOrigin(nsAString& aResult)
|
||||
{
|
||||
SetHTMLAttr(nsGkAtoms::crossorigin, aValue, aRv);
|
||||
// Null for both missing and invalid defaults is ok, since we
|
||||
// always parse to an enum value, so we don't need an invalid
|
||||
// default, and we _want_ the missing default to be null.
|
||||
GetEnumAttr(nsGkAtoms::crossorigin, nullptr, aResult);
|
||||
}
|
||||
void SetCrossOrigin(const nsAString& aCrossOrigin, ErrorResult& aError)
|
||||
{
|
||||
SetOrRemoveNullableStringAttr(nsGkAtoms::crossorigin, aCrossOrigin, aError);
|
||||
}
|
||||
|
||||
uint16_t NetworkState() const
|
||||
|
@ -151,11 +151,6 @@ HTMLImageElement::SetItemValueText(const nsAString& aValue)
|
||||
SetSrc(aValue);
|
||||
}
|
||||
|
||||
// crossorigin is not "limited to only known values" per spec, so it's
|
||||
// just a string attr purposes of the DOM crossOrigin property.
|
||||
// TODO: It is now (bug 880997).
|
||||
NS_IMPL_STRING_ATTR(HTMLImageElement, CrossOrigin, crossorigin)
|
||||
|
||||
bool
|
||||
HTMLImageElement::Draggable() const
|
||||
{
|
||||
|
@ -142,9 +142,16 @@ public:
|
||||
{
|
||||
SetHTMLAttr(nsGkAtoms::srcset, aSrcset, aError);
|
||||
}
|
||||
void GetCrossOrigin(nsAString& aResult)
|
||||
{
|
||||
// Null for both missing and invalid defaults is ok, since we
|
||||
// always parse to an enum value, so we don't need an invalid
|
||||
// default, and we _want_ the missing default to be null.
|
||||
GetEnumAttr(nsGkAtoms::crossorigin, nullptr, aResult);
|
||||
}
|
||||
void SetCrossOrigin(const nsAString& aCrossOrigin, ErrorResult& aError)
|
||||
{
|
||||
SetHTMLAttr(nsGkAtoms::crossorigin, aCrossOrigin, aError);
|
||||
SetOrRemoveNullableStringAttr(nsGkAtoms::crossorigin, aCrossOrigin, aError);
|
||||
}
|
||||
void SetUseMap(const nsAString& aUseMap, ErrorResult& aError)
|
||||
{
|
||||
|
@ -117,7 +117,6 @@ NS_IMPL_STRING_ATTR(HTMLLinkElement, Rel, rel)
|
||||
NS_IMPL_STRING_ATTR(HTMLLinkElement, Rev, rev)
|
||||
NS_IMPL_STRING_ATTR(HTMLLinkElement, Target, target)
|
||||
NS_IMPL_STRING_ATTR(HTMLLinkElement, Type, type)
|
||||
NS_IMPL_STRING_ATTR(HTMLLinkElement, CrossOrigin, crossorigin)
|
||||
|
||||
void
|
||||
HTMLLinkElement::GetItemValueText(nsAString& aValue)
|
||||
|
@ -90,10 +90,16 @@ public:
|
||||
{
|
||||
SetHTMLAttr(nsGkAtoms::href, aHref, aRv);
|
||||
}
|
||||
// XPCOM GetCrossOrigin is fine.
|
||||
void SetCrossOrigin(const nsAString& aCrossOrigin, ErrorResult& aRv)
|
||||
void GetCrossOrigin(nsAString& aResult)
|
||||
{
|
||||
SetHTMLAttr(nsGkAtoms::crossorigin, aCrossOrigin, aRv);
|
||||
// Null for both missing and invalid defaults is ok, since we
|
||||
// always parse to an enum value, so we don't need an invalid
|
||||
// default, and we _want_ the missing default to be null.
|
||||
GetEnumAttr(nsGkAtoms::crossorigin, nullptr, aResult);
|
||||
}
|
||||
void SetCrossOrigin(const nsAString& aCrossOrigin, ErrorResult& aError)
|
||||
{
|
||||
SetOrRemoveNullableStringAttr(nsGkAtoms::crossorigin, aCrossOrigin, aError);
|
||||
}
|
||||
// XPCOM GetRel is fine.
|
||||
void SetRel(const nsAString& aRel, ErrorResult& aRv)
|
||||
|
@ -470,7 +470,6 @@ NS_INTERFACE_MAP_END_INHERITING(nsGenericHTMLElement)
|
||||
|
||||
// nsIDOMHTMLMediaElement
|
||||
NS_IMPL_URI_ATTR(HTMLMediaElement, Src, src)
|
||||
NS_IMPL_STRING_ATTR(HTMLMediaElement, CrossOrigin, crossorigin)
|
||||
NS_IMPL_BOOL_ATTR(HTMLMediaElement, Controls, controls)
|
||||
NS_IMPL_BOOL_ATTR(HTMLMediaElement, Autoplay, autoplay)
|
||||
NS_IMPL_BOOL_ATTR(HTMLMediaElement, Loop, loop)
|
||||
|
@ -137,7 +137,6 @@ NS_IMPL_URI_ATTR(HTMLScriptElement, Src, src)
|
||||
NS_IMPL_STRING_ATTR(HTMLScriptElement, Type, type)
|
||||
NS_IMPL_STRING_ATTR(HTMLScriptElement, HtmlFor, _for)
|
||||
NS_IMPL_STRING_ATTR(HTMLScriptElement, Event, event)
|
||||
NS_IMPL_STRING_ATTR(HTMLScriptElement, CrossOrigin, crossorigin)
|
||||
|
||||
void
|
||||
HTMLScriptElement::SetCharset(const nsAString& aCharset, ErrorResult& rv)
|
||||
@ -181,12 +180,6 @@ HTMLScriptElement::SetEvent(const nsAString& aEvent, ErrorResult& rv)
|
||||
SetHTMLAttr(nsGkAtoms::event, aEvent, rv);
|
||||
}
|
||||
|
||||
void
|
||||
HTMLScriptElement::SetCrossOrigin(const nsAString& aCrossOrigin, ErrorResult& rv)
|
||||
{
|
||||
SetHTMLAttr(nsGkAtoms::crossorigin, aCrossOrigin, rv);
|
||||
}
|
||||
|
||||
nsresult
|
||||
HTMLScriptElement::GetAsync(bool* aValue)
|
||||
{
|
||||
|
@ -68,7 +68,17 @@ public:
|
||||
void SetType(const nsAString& aType, ErrorResult& rv);
|
||||
void SetHtmlFor(const nsAString& aHtmlFor, ErrorResult& rv);
|
||||
void SetEvent(const nsAString& aEvent, ErrorResult& rv);
|
||||
void SetCrossOrigin(const nsAString& aCrossOrigin, ErrorResult& rv);
|
||||
void GetCrossOrigin(nsAString& aResult)
|
||||
{
|
||||
// Null for both missing and invalid defaults is ok, since we
|
||||
// always parse to an enum value, so we don't need an invalid
|
||||
// default, and we _want_ the missing default to be null.
|
||||
GetEnumAttr(nsGkAtoms::crossorigin, nullptr, aResult);
|
||||
}
|
||||
void SetCrossOrigin(const nsAString& aCrossOrigin, ErrorResult& aError)
|
||||
{
|
||||
SetOrRemoveNullableStringAttr(nsGkAtoms::crossorigin, aCrossOrigin, aError);
|
||||
}
|
||||
bool Async();
|
||||
void SetAsync(bool aValue, ErrorResult& rv);
|
||||
|
||||
|
@ -347,7 +347,7 @@ nsGenericHTMLElement::GetOffsetRect(CSSIntRect& aRect)
|
||||
}
|
||||
|
||||
nsIContent* offsetParent = nullptr;
|
||||
Element* docElement = GetCurrentDoc()->GetRootElement();
|
||||
Element* docElement = GetComposedDoc()->GetRootElement();
|
||||
nsIContent* content = frame->GetContent();
|
||||
|
||||
if (content && (content->IsHTML(nsGkAtoms::body) || content == docElement)) {
|
||||
@ -398,7 +398,7 @@ nsGenericHTMLElement::GetOffsetRect(CSSIntRect& aRect)
|
||||
// parent chain. We want the offset parent in this case to be
|
||||
// the body, so we just get the body element from the document.
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLDocument> html_doc(do_QueryInterface(GetCurrentDoc()));
|
||||
nsCOMPtr<nsIDOMHTMLDocument> html_doc(do_QueryInterface(GetComposedDoc()));
|
||||
|
||||
if (html_doc) {
|
||||
offsetParent = static_cast<nsHTMLDocument*>(html_doc.get())->GetBody();
|
||||
@ -1766,37 +1766,6 @@ nsGenericHTMLElement::GetURIListAttr(nsIAtom* aAttr, nsAString& aResult)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericHTMLElement::GetEnumAttr(nsIAtom* aAttr,
|
||||
const char* aDefault,
|
||||
nsAString& aResult) const
|
||||
{
|
||||
GetEnumAttr(aAttr, aDefault, aDefault, aResult);
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericHTMLElement::GetEnumAttr(nsIAtom* aAttr,
|
||||
const char* aDefaultMissing,
|
||||
const char* aDefaultInvalid,
|
||||
nsAString& aResult) const
|
||||
{
|
||||
const nsAttrValue* attrVal = mAttrsAndChildren.GetAttr(aAttr);
|
||||
|
||||
aResult.Truncate();
|
||||
|
||||
if (!attrVal) {
|
||||
if (aDefaultMissing) {
|
||||
AppendASCIItoUTF16(nsDependentCString(aDefaultMissing), aResult);
|
||||
}
|
||||
} else {
|
||||
if (attrVal->Type() == nsAttrValue::eEnum) {
|
||||
attrVal->GetEnumString(aResult, true);
|
||||
} else if (aDefaultInvalid) {
|
||||
AppendASCIItoUTF16(nsDependentCString(aDefaultInvalid), aResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HTMLMenuElement*
|
||||
nsGenericHTMLElement::GetContextMenu() const
|
||||
{
|
||||
|
@ -1011,11 +1011,11 @@ protected:
|
||||
}
|
||||
void SetHTMLAttr(nsIAtom* aName, const nsAString& aValue, mozilla::ErrorResult& aError)
|
||||
{
|
||||
aError = SetAttr(kNameSpaceID_None, aName, aValue, true);
|
||||
mozilla::dom::Element::SetAttr(aName, aValue, aError);
|
||||
}
|
||||
void UnsetHTMLAttr(nsIAtom* aName, mozilla::ErrorResult& aError)
|
||||
{
|
||||
aError = UnsetAttr(kNameSpaceID_None, aName, true);
|
||||
mozilla::dom::Element::UnsetAttr(aName, aError);
|
||||
}
|
||||
void SetHTMLBoolAttr(nsIAtom* aName, bool aValue, mozilla::ErrorResult& aError)
|
||||
{
|
||||
@ -1122,35 +1122,6 @@ protected:
|
||||
*/
|
||||
nsresult GetURIListAttr(nsIAtom* aAttr, nsAString& aResult);
|
||||
|
||||
/**
|
||||
* Helper method for NS_IMPL_ENUM_ATTR_DEFAULT_VALUE.
|
||||
* Gets the enum value string of an attribute and using a default value if
|
||||
* the attribute is missing or the string is an invalid enum value.
|
||||
*
|
||||
* @param aType the name of the attribute.
|
||||
* @param aDefault the default value if the attribute is missing or invalid.
|
||||
* @param aResult string corresponding to the value [out].
|
||||
*/
|
||||
void GetEnumAttr(nsIAtom* aAttr,
|
||||
const char* aDefault,
|
||||
nsAString& aResult) const;
|
||||
|
||||
/**
|
||||
* Helper method for NS_IMPL_ENUM_ATTR_DEFAULT_MISSING_INVALID_VALUES.
|
||||
* Gets the enum value string of an attribute and using the default missing
|
||||
* value if the attribute is missing or the default invalid value if the
|
||||
* string is an invalid enum value.
|
||||
*
|
||||
* @param aType the name of the attribute.
|
||||
* @param aDefaultMissing the default value if the attribute is missing.
|
||||
* @param aDefaultInvalid the default value if the attribute is invalid.
|
||||
* @param aResult string corresponding to the value [out].
|
||||
*/
|
||||
void GetEnumAttr(nsIAtom* aAttr,
|
||||
const char* aDefaultMissing,
|
||||
const char* aDefaultInvalid,
|
||||
nsAString& aResult) const;
|
||||
|
||||
/**
|
||||
* Locates the nsIEditor associated with this node. In general this is
|
||||
* equivalent to GetEditorInternal(), but for designmode or contenteditable,
|
||||
|
@ -248,6 +248,7 @@ function reflectUnsignedInt(aParameters)
|
||||
* OR
|
||||
* defaultValue Object [optional] object containing two attributes, 'invalid' and 'missing'
|
||||
* - unsupportedValues Array [optional] valid values we do not support
|
||||
* - nullable boolean [optional] whether the attribute is nullable
|
||||
*/
|
||||
function reflectLimitedEnumerated(aParameters)
|
||||
{
|
||||
@ -266,60 +267,73 @@ function reflectLimitedEnumerated(aParameters)
|
||||
? aParameters.defaultValue : aParameters.defaultValue.missing
|
||||
var unsupportedValues = aParameters.unsupportedValues !== undefined
|
||||
? aParameters.unsupportedValues : [];
|
||||
var nullable = aParameters.nullable;
|
||||
|
||||
ok(idlAttr in element, idlAttr + " should be an IDL attribute of this element");
|
||||
is(typeof element[idlAttr], "string", "'" + idlAttr + "' IDL attribute should be a string");
|
||||
if (nullable) {
|
||||
// The missing value default is null, which is typeof == "object"
|
||||
is(typeof element[idlAttr], "object", "'" + idlAttr + "' IDL attribute should be null, which has typeof == object");
|
||||
ise(element[idlAttr], null, "'" + idlAttr + "' IDL attribute should be null");
|
||||
} else {
|
||||
is(typeof element[idlAttr], "string", "'" + idlAttr + "' IDL attribute should be a string");
|
||||
}
|
||||
|
||||
if (nullable) {
|
||||
element.setAttribute(contentAttr, "something");
|
||||
// Now it will be a string
|
||||
is(typeof element[idlAttr], "string", "'" + idlAttr + "' IDL attribute should be a string");
|
||||
}
|
||||
|
||||
// Explicitly check the default value.
|
||||
element.removeAttribute(contentAttr);
|
||||
is(element[idlAttr], defaultValueMissing,
|
||||
"When no attribute is set, the value should be the default value.");
|
||||
ise(element[idlAttr], defaultValueMissing,
|
||||
"When no attribute is set, the value should be the default value.");
|
||||
|
||||
// Check valid values.
|
||||
validValues.forEach(function (v) {
|
||||
element.setAttribute(contentAttr, v);
|
||||
is(element[idlAttr], v,
|
||||
v + " should be accepted as a valid value for " + idlAttr);
|
||||
is(element.getAttribute(contentAttr), v,
|
||||
"Content attribute should return the value it has been set to.");
|
||||
ise(element[idlAttr], v,
|
||||
"'" + v + "' should be accepted as a valid value for " + idlAttr);
|
||||
ise(element.getAttribute(contentAttr), v,
|
||||
"Content attribute should return the value it has been set to.");
|
||||
element.removeAttribute(contentAttr);
|
||||
|
||||
element.setAttribute(contentAttr, v.toUpperCase());
|
||||
is(element[idlAttr], v,
|
||||
"Enumerated attributes should be case-insensitive.");
|
||||
is(element.getAttribute(contentAttr), v.toUpperCase(),
|
||||
"Content attribute should not be lower-cased.");
|
||||
ise(element[idlAttr], v,
|
||||
"Enumerated attributes should be case-insensitive.");
|
||||
ise(element.getAttribute(contentAttr), v.toUpperCase(),
|
||||
"Content attribute should not be lower-cased.");
|
||||
element.removeAttribute(contentAttr);
|
||||
|
||||
element[idlAttr] = v;
|
||||
is(element[idlAttr], v,
|
||||
v + " should be accepted as a valid value for " + idlAttr);
|
||||
is(element.getAttribute(contentAttr), v,
|
||||
"Content attribute should return the value it has been set to.");
|
||||
ise(element[idlAttr], v,
|
||||
"'" + v + "' should be accepted as a valid value for " + idlAttr);
|
||||
ise(element.getAttribute(contentAttr), v,
|
||||
"Content attribute should return the value it has been set to.");
|
||||
element.removeAttribute(contentAttr);
|
||||
|
||||
element[idlAttr] = v.toUpperCase();
|
||||
is(element[idlAttr], v,
|
||||
"Enumerated attributes should be case-insensitive.");
|
||||
is(element.getAttribute(contentAttr), v.toUpperCase(),
|
||||
"Content attribute should not be lower-cased.");
|
||||
ise(element[idlAttr], v,
|
||||
"Enumerated attributes should be case-insensitive.");
|
||||
ise(element.getAttribute(contentAttr), v.toUpperCase(),
|
||||
"Content attribute should not be lower-cased.");
|
||||
element.removeAttribute(contentAttr);
|
||||
});
|
||||
|
||||
// Check invalid values.
|
||||
invalidValues.forEach(function (v) {
|
||||
element.setAttribute(contentAttr, v);
|
||||
is(element[idlAttr], defaultValueInvalid,
|
||||
"When the content attribute is set to an invalid value, the default value should be returned.");
|
||||
is(element.getAttribute(contentAttr), v,
|
||||
"Content attribute should not have been changed.");
|
||||
ise(element[idlAttr], defaultValueInvalid,
|
||||
"When the content attribute is set to an invalid value, the default value should be returned.");
|
||||
ise(element.getAttribute(contentAttr), v,
|
||||
"Content attribute should not have been changed.");
|
||||
element.removeAttribute(contentAttr);
|
||||
|
||||
element[idlAttr] = v;
|
||||
is(element[idlAttr], defaultValueInvalid,
|
||||
"When the value is set to an invalid value, the default value should be returned.");
|
||||
is(element.getAttribute(contentAttr), v,
|
||||
"Content attribute should not have been changed.");
|
||||
ise(element[idlAttr], defaultValueInvalid,
|
||||
"When the value is set to an invalid value, the default value should be returned.");
|
||||
ise(element.getAttribute(contentAttr), v,
|
||||
"Content attribute should not have been changed.");
|
||||
element.removeAttribute(contentAttr);
|
||||
});
|
||||
|
||||
@ -328,7 +342,7 @@ function reflectLimitedEnumerated(aParameters)
|
||||
unsupportedValues.forEach(function (v) {
|
||||
element.setAttribute(contentAttr, v);
|
||||
todo_is(element[idlAttr], v,
|
||||
v + " should be accepted as a valid value for " + idlAttr);
|
||||
"'" + v + "' should be accepted as a valid value for " + idlAttr);
|
||||
is(element.getAttribute(contentAttr), v,
|
||||
"Content attribute should return the value it has been set to.");
|
||||
element.removeAttribute(contentAttr);
|
||||
@ -342,7 +356,7 @@ function reflectLimitedEnumerated(aParameters)
|
||||
|
||||
element[idlAttr] = v;
|
||||
todo_is(element[idlAttr], v,
|
||||
v + " should be accepted as a valid value for " + idlAttr);
|
||||
"'" + v + "' should be accepted as a valid value for " + idlAttr);
|
||||
is(element.getAttribute(contentAttr), v,
|
||||
"Content attribute should return the value it has been set to.");
|
||||
element.removeAttribute(contentAttr);
|
||||
@ -354,6 +368,18 @@ function reflectLimitedEnumerated(aParameters)
|
||||
"Content attribute should not be lower-cased.");
|
||||
element.removeAttribute(contentAttr);
|
||||
});
|
||||
|
||||
if (nullable) {
|
||||
ise(defaultValueMissing, null,
|
||||
"Missing default value should be null for nullable attributes");
|
||||
ok(validValues.length > 0, "We better have at least one valid value");
|
||||
element.setAttribute(contentAttr, validValues[0]);
|
||||
ok(element.hasAttribute(contentAttr),
|
||||
"Should have content attribute: we just set it");
|
||||
element[idlAttr] = null;
|
||||
ok(!element.hasAttribute(contentAttr),
|
||||
"Should have removed content attribute");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -24,10 +24,17 @@ var els = [ document.createElement("script"),
|
||||
document.createElementNS("http://www.w3.org/2000/svg", "script") ]
|
||||
|
||||
for (var i = 0; i < els.length; ++i) {
|
||||
reflectString({
|
||||
reflectLimitedEnumerated({
|
||||
element: els[i],
|
||||
attribute: { content: "crossorigin", idl: "crossOrigin" },
|
||||
otherValues: [ "anonymous", "use-credentials" ]
|
||||
// "" is a valid value per spec, but gets mapped to the "anonymous" state,
|
||||
// just like invalid values, so just list it under invalidValues
|
||||
validValues: [ "anonymous", "use-credentials" ],
|
||||
invalidValues: [
|
||||
"", " aNOnYmous ", " UsE-CreDEntIALS ", "foobar", "FOOBAR", " fOoBaR "
|
||||
],
|
||||
defaultValue: { invalid: "anonymous", missing: null },
|
||||
nullable: true,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -26,15 +26,17 @@ reflectURL({
|
||||
|
||||
todo("srcset" in document.createElement("img"), "Should implement srcset")
|
||||
|
||||
// TODO: Bug 880997 - Make crossOrigin a limited enumerated attribute.
|
||||
reflectString({
|
||||
reflectLimitedEnumerated({
|
||||
element: document.createElement("img"),
|
||||
attribute: "crossOrigin",
|
||||
otherValues: [
|
||||
"", "anonymous", "ANONYMOUS", " aNOnYmous ",
|
||||
"use-credentials", "USE-CREDENTIALS", " UsE-CreDEntIALS ",
|
||||
"foobar", "FOOBAR", " fOoBaR "
|
||||
]
|
||||
// "" is a valid value per spec, but gets mapped to the "anonymous" state,
|
||||
// just like invalid values, so just list it under invalidValues
|
||||
validValues: [ "anonymous", "use-credentials" ],
|
||||
invalidValues: [
|
||||
"", " aNOnYmous ", " UsE-CreDEntIALS ", "foobar", "FOOBAR", " fOoBaR "
|
||||
],
|
||||
defaultValue: { invalid: "anonymous", missing: null },
|
||||
nullable: true,
|
||||
})
|
||||
|
||||
reflectString({
|
||||
|
@ -21,12 +21,19 @@ reflectURL({
|
||||
attribute: "href",
|
||||
});
|
||||
|
||||
// .crossOrigin (String)
|
||||
reflectString({
|
||||
// .crossOrigin (String or null)
|
||||
reflectLimitedEnumerated({
|
||||
element: document.createElement("link"),
|
||||
attribute: "crossOrigin",
|
||||
otherValues: ["anonymous", "use-credentials"],
|
||||
});
|
||||
// "" is a valid value per spec, but gets mapped to the "anonymous" state,
|
||||
// just like invalid values, so just list it under invalidValues
|
||||
validValues: [ "anonymous", "use-credentials" ],
|
||||
invalidValues: [
|
||||
"", " aNOnYmous ", " UsE-CreDEntIALS ", "foobar", "FOOBAR", " fOoBaR "
|
||||
],
|
||||
defaultValue: { invalid: "anonymous", missing: null },
|
||||
nullable: true,
|
||||
})
|
||||
|
||||
// .rel (String)
|
||||
reflectString({
|
||||
|
@ -168,9 +168,10 @@ static const int32_t MAX_VIDEO_HEIGHT = 3000;
|
||||
void ScaleDisplayByAspectRatio(nsIntSize& aDisplay, float aAspectRatio);
|
||||
|
||||
// The amount of virtual memory reserved for thread stacks.
|
||||
#if (defined(XP_WIN) || defined(XP_MACOSX) || defined(LINUX)) && \
|
||||
!defined(MOZ_ASAN)
|
||||
#if (defined(XP_WIN) || defined(LINUX)) && !defined(MOZ_ASAN)
|
||||
#define MEDIA_THREAD_STACK_SIZE (128 * 1024)
|
||||
#elif defined(XP_MACOSX) && !defined(MOZ_ASAN)
|
||||
#define MEDIA_THREAD_STACK_SIZE (256 * 1024)
|
||||
#else
|
||||
// All other platforms use their system defaults.
|
||||
#define MEDIA_THREAD_STACK_SIZE nsIThreadManager::DEFAULT_STACK_SIZE
|
||||
|
@ -64,7 +64,10 @@ public:
|
||||
{
|
||||
return &mRef;
|
||||
}
|
||||
|
||||
private:
|
||||
// Copy operator isn't supported and is not implemented.
|
||||
AutoCFRelease<T>& operator=(const AutoCFRelease<T>&);
|
||||
T mRef;
|
||||
};
|
||||
|
||||
|
@ -6,17 +6,19 @@
|
||||
|
||||
#include <CoreFoundation/CFString.h>
|
||||
|
||||
#include "AppleCMLinker.h"
|
||||
#include "AppleUtils.h"
|
||||
#include "AppleVTDecoder.h"
|
||||
#include "AppleVTLinker.h"
|
||||
#include "mp4_demuxer/DecoderData.h"
|
||||
#include "MP4Reader.h"
|
||||
#include "MP4Decoder.h"
|
||||
#include "MediaData.h"
|
||||
#include "MacIOSurfaceImage.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "AppleCMLinker.h"
|
||||
#include "AppleVTDecoder.h"
|
||||
#include "AppleVTLinker.h"
|
||||
#include "prlog.h"
|
||||
#include "MediaData.h"
|
||||
#include "VideoUtils.h"
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
@ -238,81 +240,34 @@ nsresult
|
||||
AppleVTDecoder::OutputFrame(CVPixelBufferRef aImage,
|
||||
nsAutoPtr<FrameRef> aFrameRef)
|
||||
{
|
||||
size_t width = CVPixelBufferGetWidth(aImage);
|
||||
size_t height = CVPixelBufferGetHeight(aImage);
|
||||
LOG(" got decoded frame data... %ux%u %s", width, height,
|
||||
CVPixelBufferIsPlanar(aImage) ? "planar" : "chunked");
|
||||
#ifdef DEBUG
|
||||
size_t planes = CVPixelBufferGetPlaneCount(aImage);
|
||||
for (size_t i = 0; i < planes; ++i) {
|
||||
size_t stride = CVPixelBufferGetBytesPerRowOfPlane(aImage, i);
|
||||
LOG(" plane %u %ux%u rowbytes %u",
|
||||
(unsigned)i,
|
||||
CVPixelBufferGetWidthOfPlane(aImage, i),
|
||||
CVPixelBufferGetHeightOfPlane(aImage, i),
|
||||
(unsigned)stride);
|
||||
}
|
||||
MOZ_ASSERT(planes == 2);
|
||||
#endif // DEBUG
|
||||
|
||||
VideoData::YCbCrBuffer buffer;
|
||||
|
||||
// Lock the returned image data.
|
||||
CVReturn rv = CVPixelBufferLockBaseAddress(aImage, kCVPixelBufferLock_ReadOnly);
|
||||
if (rv != kCVReturnSuccess) {
|
||||
NS_ERROR("error locking pixel data");
|
||||
mCallback->Error();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
// Y plane.
|
||||
buffer.mPlanes[0].mData =
|
||||
static_cast<uint8_t*>(CVPixelBufferGetBaseAddressOfPlane(aImage, 0));
|
||||
buffer.mPlanes[0].mStride = CVPixelBufferGetBytesPerRowOfPlane(aImage, 0);
|
||||
buffer.mPlanes[0].mWidth = width;
|
||||
buffer.mPlanes[0].mHeight = height;
|
||||
buffer.mPlanes[0].mOffset = 0;
|
||||
buffer.mPlanes[0].mSkip = 0;
|
||||
// Cb plane.
|
||||
buffer.mPlanes[1].mData =
|
||||
static_cast<uint8_t*>(CVPixelBufferGetBaseAddressOfPlane(aImage, 1));
|
||||
buffer.mPlanes[1].mStride = CVPixelBufferGetBytesPerRowOfPlane(aImage, 1);
|
||||
buffer.mPlanes[1].mWidth = (width+1) / 2;
|
||||
buffer.mPlanes[1].mHeight = (height+1) / 2;
|
||||
buffer.mPlanes[1].mOffset = 0;
|
||||
buffer.mPlanes[1].mSkip = 1;
|
||||
// Cr plane.
|
||||
buffer.mPlanes[2].mData =
|
||||
static_cast<uint8_t*>(CVPixelBufferGetBaseAddressOfPlane(aImage, 1));
|
||||
buffer.mPlanes[2].mStride = CVPixelBufferGetBytesPerRowOfPlane(aImage, 1);
|
||||
buffer.mPlanes[2].mWidth = (width+1) / 2;
|
||||
buffer.mPlanes[2].mHeight = (height+1) / 2;
|
||||
buffer.mPlanes[2].mOffset = 1;
|
||||
buffer.mPlanes[2].mSkip = 1;
|
||||
IOSurfacePtr surface = MacIOSurfaceLib::CVPixelBufferGetIOSurface(aImage);
|
||||
MOZ_ASSERT(surface, "VideoToolbox didn't return an IOSurface backed buffer");
|
||||
|
||||
nsRefPtr<MacIOSurface> macSurface = new MacIOSurface(surface);
|
||||
// Bounds.
|
||||
VideoInfo info;
|
||||
info.mDisplay = nsIntSize(width, height);
|
||||
info.mDisplay = nsIntSize(macSurface->GetWidth(), macSurface->GetHeight());
|
||||
info.mHasVideo = true;
|
||||
gfx::IntRect visible = gfx::IntRect(0,
|
||||
0,
|
||||
mConfig.display_width,
|
||||
mConfig.display_height);
|
||||
|
||||
// Copy the image data into our own format.
|
||||
nsRefPtr<layers::Image> image =
|
||||
mImageContainer->CreateImage(ImageFormat::MAC_IOSURFACE);
|
||||
layers::MacIOSurfaceImage* videoImage =
|
||||
static_cast<layers::MacIOSurfaceImage*>(image.get());
|
||||
videoImage->SetSurface(macSurface);
|
||||
|
||||
nsAutoPtr<VideoData> data;
|
||||
data =
|
||||
VideoData::Create(info,
|
||||
mImageContainer,
|
||||
nullptr,
|
||||
aFrameRef->byte_offset,
|
||||
aFrameRef->composition_timestamp,
|
||||
aFrameRef->duration,
|
||||
buffer,
|
||||
aFrameRef->is_sync_point,
|
||||
aFrameRef->decode_timestamp,
|
||||
visible);
|
||||
// Unlock the returned image data.
|
||||
CVPixelBufferUnlockBaseAddress(aImage, kCVPixelBufferLock_ReadOnly);
|
||||
data = VideoData::CreateFromImage(info,
|
||||
mImageContainer,
|
||||
aFrameRef->byte_offset,
|
||||
aFrameRef->composition_timestamp,
|
||||
aFrameRef->duration, image.forget(),
|
||||
aFrameRef->is_sync_point,
|
||||
aFrameRef->decode_timestamp,
|
||||
visible);
|
||||
|
||||
if (!data) {
|
||||
NS_ERROR("Couldn't create VideoData for frame");
|
||||
@ -445,31 +400,43 @@ AppleVTDecoder::InitializeSession()
|
||||
}
|
||||
|
||||
// Contruct video decoder selection spec.
|
||||
AutoCFRelease<CFMutableDictionaryRef> spec =
|
||||
CFDictionaryCreateMutable(NULL, 0,
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks);
|
||||
// FIXME: Enabling hardware acceleration causes crashes in
|
||||
// VTDecompressionSessionCreate() with multiple videos. Bug 1055694
|
||||
#if 0
|
||||
// This key is supported (or ignored) but not declared prior to OSX 10.9.
|
||||
AutoCFRelease<CFStringRef>
|
||||
kVTVideoDecoderSpecification_EnableHardwareAcceleratedVideoDecoder =
|
||||
CFStringCreateWithCString(NULL, "EnableHardwareAcceleratedVideoDecoder",
|
||||
kCFStringEncodingUTF8);
|
||||
AutoCFRelease<CFDictionaryRef> spec = CreateDecoderSpecification();
|
||||
|
||||
CFDictionarySetValue(spec,
|
||||
kVTVideoDecoderSpecification_EnableHardwareAcceleratedVideoDecoder,
|
||||
kCFBooleanTrue);
|
||||
#endif
|
||||
// Contruct output configuration.
|
||||
AutoCFRelease<CFDictionaryRef> IOSurfaceProperties =
|
||||
CFDictionaryCreate(NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks);
|
||||
|
||||
SInt32 PixelFormatTypeValue = kCVPixelFormatType_32BGRA;
|
||||
AutoCFRelease<CFNumberRef> PixelFormatTypeNumber =
|
||||
CFNumberCreate(NULL, kCFNumberSInt32Type, &PixelFormatTypeValue);
|
||||
|
||||
const void* outputKeys[] = { kCVPixelBufferIOSurfacePropertiesKey,
|
||||
kCVPixelBufferPixelFormatTypeKey,
|
||||
kCVPixelBufferOpenGLCompatibilityKey };
|
||||
const void* outputValues[] = { IOSurfaceProperties,
|
||||
PixelFormatTypeNumber,
|
||||
kCFBooleanTrue };
|
||||
AutoCFRelease<CFDictionaryRef> outputConfiguration =
|
||||
CFDictionaryCreate(NULL,
|
||||
outputKeys,
|
||||
outputValues,
|
||||
ArrayLength(outputKeys),
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks);
|
||||
|
||||
VTDecompressionOutputCallbackRecord cb = { PlatformCallback, this };
|
||||
rv = VTDecompressionSessionCreate(NULL, // Allocator.
|
||||
mFormat,
|
||||
spec, // Video decoder selection.
|
||||
NULL, // Output video format.
|
||||
outputConfiguration, // Output video format.
|
||||
&cb,
|
||||
&mSession);
|
||||
|
||||
if (rv != noErr) {
|
||||
NS_ERROR("Couldn't create decompression session!");
|
||||
return NS_ERROR_FAILURE;
|
||||
@ -478,4 +445,21 @@ AppleVTDecoder::InitializeSession()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
CFDictionaryRef
|
||||
AppleVTDecoder::CreateDecoderSpecification()
|
||||
{
|
||||
if (!AppleVTLinker::GetPropHWAccel()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const void* specKeys[] = { AppleVTLinker::GetPropHWAccel() };
|
||||
const void* specValues[] = { kCFBooleanTrue };
|
||||
return CFDictionaryCreate(NULL,
|
||||
specKeys,
|
||||
specValues,
|
||||
ArrayLength(specKeys),
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -55,6 +55,8 @@ private:
|
||||
nsresult WaitForAsynchronousFrames();
|
||||
void DrainReorderedFrames();
|
||||
void ClearReorderedFrames();
|
||||
|
||||
CFDictionaryRef CreateDecoderSpecification();
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -24,6 +24,7 @@ AppleVTLinker::sLinkStatus = LinkStatus_INIT;
|
||||
|
||||
void* AppleVTLinker::sLink = nullptr;
|
||||
nsrefcnt AppleVTLinker::sRefCount = 0;
|
||||
CFStringRef AppleVTLinker::skPropHWAccel = nullptr;
|
||||
|
||||
#define LINK_FUNC(func) typeof(func) func;
|
||||
#include "AppleVTFunctions.h"
|
||||
@ -58,6 +59,10 @@ AppleVTLinker::Link()
|
||||
#include "AppleVTFunctions.h"
|
||||
#undef LINK_FUNC
|
||||
|
||||
// Will only resolve in 10.9 and later.
|
||||
skPropHWAccel =
|
||||
GetIOConst("kVTVideoDecoderSpecification_EnableHardwareAcceleratedVideoDecoder");
|
||||
|
||||
LOG("Loaded VideoToolbox framework.");
|
||||
sLinkStatus = LinkStatus_SUCCEEDED;
|
||||
return true;
|
||||
@ -83,7 +88,25 @@ AppleVTLinker::Unlink()
|
||||
LOG("Unlinking VideoToolbox framework.");
|
||||
dlclose(sLink);
|
||||
sLink = nullptr;
|
||||
skPropHWAccel = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ CFStringRef
|
||||
AppleVTLinker::GetIOConst(const char* symbol)
|
||||
{
|
||||
CFStringRef* address = (CFStringRef*)dlsym(sLink, symbol);
|
||||
if (!address) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return *address;
|
||||
}
|
||||
|
||||
/* static */ CFStringRef
|
||||
AppleVTLinker::GetPropHWAccel()
|
||||
{
|
||||
return skPropHWAccel;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -22,16 +22,20 @@ class AppleVTLinker
|
||||
public:
|
||||
static bool Link();
|
||||
static void Unlink();
|
||||
static CFStringRef GetPropHWAccel();
|
||||
|
||||
private:
|
||||
static void* sLink;
|
||||
static nsrefcnt sRefCount;
|
||||
static CFStringRef skPropHWAccel;
|
||||
|
||||
static enum LinkStatus {
|
||||
LinkStatus_INIT = 0,
|
||||
LinkStatus_FAILED,
|
||||
LinkStatus_SUCCEEDED
|
||||
} sLinkStatus;
|
||||
|
||||
static CFStringRef GetIOConst(const char* symbol);
|
||||
};
|
||||
|
||||
#define LINK_FUNC(func) extern typeof(func)* func;
|
||||
|
@ -209,28 +209,28 @@ void
|
||||
MediaSourceReader::Shutdown()
|
||||
{
|
||||
MediaDecoderReader::Shutdown();
|
||||
for (uint32_t i = 0; i < mTrackBuffers.Length(); ++i) {
|
||||
mTrackBuffers[i]->Shutdown();
|
||||
}
|
||||
mTrackBuffers.Clear();
|
||||
mAudioTrack = nullptr;
|
||||
mAudioReader = nullptr;
|
||||
mVideoTrack = nullptr;
|
||||
mVideoReader = nullptr;
|
||||
for (uint32_t i = 0; i < mTrackBuffers.Length(); ++i) {
|
||||
mTrackBuffers[i]->Shutdown();
|
||||
}
|
||||
mTrackBuffers.Clear();
|
||||
}
|
||||
|
||||
void
|
||||
MediaSourceReader::BreakCycles()
|
||||
{
|
||||
MediaDecoderReader::BreakCycles();
|
||||
for (uint32_t i = 0; i < mTrackBuffers.Length(); ++i) {
|
||||
mTrackBuffers[i]->BreakCycles();
|
||||
}
|
||||
mTrackBuffers.Clear();
|
||||
mAudioTrack = nullptr;
|
||||
mAudioReader = nullptr;
|
||||
mVideoTrack = nullptr;
|
||||
mVideoReader = nullptr;
|
||||
for (uint32_t i = 0; i < mTrackBuffers.Length(); ++i) {
|
||||
mTrackBuffers[i]->BreakCycles();
|
||||
}
|
||||
mTrackBuffers.Clear();
|
||||
}
|
||||
|
||||
bool
|
||||
|
17
content/media/mediasource/test/crashtests/931388.html
Normal file
17
content/media/mediasource/test/crashtests/931388.html
Normal file
@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<script>
|
||||
|
||||
function boom()
|
||||
{
|
||||
var v = document.createElement('video');
|
||||
v.src = URL.createObjectURL(new MediaSource());
|
||||
v.play();
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="boom();"></body>
|
||||
</html>
|
@ -1,3 +1,4 @@
|
||||
test-pref(media.mediasource.enabled,true) load 926665.html
|
||||
test-pref(media.mediasource.enabled,true) load 931388.html
|
||||
test-pref(media.mediasource.enabled,true) load 1005366.html
|
||||
test-pref(media.mediasource.enabled,true) load 1059035.html
|
||||
|
22
content/media/mediasource/test/mediasource.js
Normal file
22
content/media/mediasource/test/mediasource.js
Normal file
@ -0,0 +1,22 @@
|
||||
// Helpers for Media Source Extensions tests
|
||||
|
||||
function runWithMSE(testFunction) {
|
||||
addLoadEvent(() => SpecialPowers.pushPrefEnv({"set": [[ "media.mediasource.enabled", true ]]}, testFunction));
|
||||
}
|
||||
|
||||
function fetchWithXHR(uri, onLoadFunction) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", uri, true);
|
||||
xhr.responseType = "blob";
|
||||
xhr.addEventListener("load", function (e) {
|
||||
if (xhr.status != 200) {
|
||||
return;
|
||||
}
|
||||
var rdr = new FileReader();
|
||||
rdr.addEventListener("load", function (e) {
|
||||
onLoadFunction(e.target.result);
|
||||
});
|
||||
rdr.readAsArrayBuffer(e.target.response);
|
||||
});
|
||||
xhr.send();
|
||||
};
|
@ -1,6 +1,6 @@
|
||||
[DEFAULT]
|
||||
skip-if = e10s
|
||||
support-files = seek.webm seek.webm^headers^
|
||||
support-files = mediasource.js seek.webm seek.webm^headers^
|
||||
|
||||
[test_MediaSource.html]
|
||||
skip-if = buildapp == 'b2g' # b2g( ReferenceError: MediaSource is not defined)
|
||||
|
@ -3,6 +3,7 @@
|
||||
<head>
|
||||
<title>MSE: seeking in buffered range</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="mediasource.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
@ -11,84 +12,49 @@
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
addLoadEvent(function() {
|
||||
ok(!window.MediaSource, "MediaSource should be hidden behind a pref");
|
||||
var accessThrows = false;
|
||||
try {
|
||||
new MediaSource();
|
||||
} catch (e) {
|
||||
accessThrows = true;
|
||||
}
|
||||
ok(accessThrows, "MediaSource should be hidden behind a pref");
|
||||
SpecialPowers.pushPrefEnv({"set": [[ "media.mediasource.enabled", true ]]},
|
||||
function () {
|
||||
SpecialPowers.setBoolPref("media.mediasource.enabled", true);
|
||||
var ms = new MediaSource();
|
||||
ok(ms, "Create a MediaSource object");
|
||||
ok(ms instanceof EventTarget, "MediaSource must be an EventTarget");
|
||||
is(ms.readyState, "closed", "New MediaSource must be in closed state");
|
||||
// Force wrapper creation, tests for leaks.
|
||||
ms.foo = null;
|
||||
var o = URL.createObjectURL(ms);
|
||||
ok(o, "Create an objectURL from the MediaSource");
|
||||
var v = document.createElement("video");
|
||||
v.preload = "auto";
|
||||
document.body.appendChild(v);
|
||||
v.src = o;
|
||||
ms.addEventListener("sourceopen", function () {
|
||||
ok(true, "Receive a sourceopen event");
|
||||
is(ms.readyState, "open", "MediaSource must be in open state after sourceopen");
|
||||
var sb = ms.addSourceBuffer("video/webm");
|
||||
ok(sb, "Create a SourceBuffer");
|
||||
is(ms.sourceBuffers.length, 1, "MediaSource.sourceBuffers is expected length");
|
||||
is(ms.sourceBuffers[0], sb, "SourceBuffer in list matches our SourceBuffer");
|
||||
fetch("seek.webm", function (blob) {
|
||||
var r = new FileReader();
|
||||
r.addEventListener("load", function (e) {
|
||||
sb.appendBuffer(new Uint8Array(e.target.result));
|
||||
ms.endOfStream();
|
||||
var target = 2;
|
||||
v.addEventListener("loadedmetadata", function () {
|
||||
if (v.buffered.length && v.currentTime != target &&
|
||||
target >= v.buffered.start(0) &&
|
||||
target < v.buffered.end(0)) {
|
||||
v.currentTime = target;
|
||||
}
|
||||
});
|
||||
var wasSeeking = false;
|
||||
v.addEventListener("seeking", function () {
|
||||
wasSeeking = true;
|
||||
is(v.currentTime, target, "Video currentTime not at target");
|
||||
});
|
||||
v.addEventListener("seeked", function () {
|
||||
ok(wasSeeking, "Received expected seeking and seeked events");
|
||||
is(v.currentTime, target, "Video currentTime not at target");
|
||||
v.parentNode.removeChild(v);
|
||||
SimpleTest.finish();
|
||||
});
|
||||
});
|
||||
r.readAsArrayBuffer(blob);
|
||||
});
|
||||
runWithMSE(function () {
|
||||
var ms = new MediaSource();
|
||||
|
||||
var v = document.createElement("video");
|
||||
v.preload = "auto";
|
||||
v.src = URL.createObjectURL(ms);
|
||||
document.body.appendChild(v);
|
||||
|
||||
ms.addEventListener("sourceopen", function () {
|
||||
var sb = ms.addSourceBuffer("video/webm");
|
||||
|
||||
fetchWithXHR("seek.webm", function (arrayBuffer) {
|
||||
sb.appendBuffer(new Uint8Array(arrayBuffer));
|
||||
ms.endOfStream();
|
||||
});
|
||||
ms.addEventListener("sourceended", function () {
|
||||
ok(true, "Receive a sourceended event");
|
||||
is(ms.readyState, "ended", "MediaSource must be in ended state after sourceended");
|
||||
|
||||
var target = 2;
|
||||
|
||||
v.addEventListener("loadedmetadata", function () {
|
||||
if (v.currentTime != target &&
|
||||
v.buffered.length &&
|
||||
target >= v.buffered.start(0) &&
|
||||
target < v.buffered.end(0)) {
|
||||
v.currentTime = target;
|
||||
}
|
||||
});
|
||||
|
||||
var wasSeeking = false;
|
||||
|
||||
v.addEventListener("seeking", function () {
|
||||
wasSeeking = true;
|
||||
is(v.currentTime, target, "Video currentTime not at target");
|
||||
});
|
||||
|
||||
v.addEventListener("seeked", function () {
|
||||
ok(wasSeeking, "Received expected seeking and seeked events");
|
||||
is(v.currentTime, target, "Video currentTime not at target");
|
||||
v.parentNode.removeChild(v);
|
||||
SimpleTest.finish();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function fetch(src, cb) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", src, true);
|
||||
xhr.responseType = "blob";
|
||||
xhr.addEventListener("load", function (e) {
|
||||
if (xhr.status != 200) {
|
||||
return false;
|
||||
}
|
||||
cb(xhr.response);
|
||||
});
|
||||
xhr.send();
|
||||
};
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
@ -3,6 +3,7 @@
|
||||
<head>
|
||||
<title>MSE: basic functionality</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="mediasource.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
@ -11,71 +12,64 @@
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
addLoadEvent(function() {
|
||||
ok(!window.MediaSource, "MediaSource should be hidden behind a pref");
|
||||
var accessThrows = false;
|
||||
try {
|
||||
new MediaSource();
|
||||
} catch (e) {
|
||||
accessThrows = true;
|
||||
}
|
||||
ok(accessThrows, "MediaSource should be hidden behind a pref");
|
||||
SpecialPowers.pushPrefEnv({"set": [[ "media.mediasource.enabled", true ]]},
|
||||
function () {
|
||||
SpecialPowers.setBoolPref("media.mediasource.enabled", true);
|
||||
var ms = new MediaSource();
|
||||
ok(ms, "Create a MediaSource object");
|
||||
ok(ms instanceof EventTarget, "MediaSource must be an EventTarget");
|
||||
is(ms.readyState, "closed", "New MediaSource must be in closed state");
|
||||
// Force wrapper creation, tests for leaks.
|
||||
ms.foo = null;
|
||||
var o = URL.createObjectURL(ms);
|
||||
ok(o, "Create an objectURL from the MediaSource");
|
||||
var v = document.createElement("video");
|
||||
v.preload = "auto";
|
||||
document.body.appendChild(v);
|
||||
v.src = o;
|
||||
ms.addEventListener("sourceopen", function () {
|
||||
ok(true, "Receive a sourceopen event");
|
||||
is(ms.readyState, "open", "MediaSource must be in open state after sourceopen");
|
||||
var sb = ms.addSourceBuffer("video/webm");
|
||||
ok(sb, "Create a SourceBuffer");
|
||||
is(ms.sourceBuffers.length, 1, "MediaSource.sourceBuffers is expected length");
|
||||
is(ms.sourceBuffers[0], sb, "SourceBuffer in list matches our SourceBuffer");
|
||||
fetch("seek.webm", function (blob) {
|
||||
var r = new FileReader();
|
||||
r.addEventListener("load", function (e) {
|
||||
sb.appendBuffer(new Uint8Array(e.target.result));
|
||||
ms.endOfStream();
|
||||
v.play();
|
||||
});
|
||||
r.readAsArrayBuffer(blob);
|
||||
});
|
||||
});
|
||||
ms.addEventListener("sourceended", function () {
|
||||
ok(true, "Receive a sourceended event");
|
||||
is(ms.readyState, "ended", "MediaSource must be in ended state after sourceended");
|
||||
});
|
||||
v.addEventListener("ended", function () {
|
||||
is(v.duration, 4, "Video has correct duration");
|
||||
v.parentNode.removeChild(v);
|
||||
SimpleTest.finish();
|
||||
addLoadEvent(function () {
|
||||
ok(!window.MediaSource && !window.SourceBuffer && !window.SourceBufferList,
|
||||
"MediaSource should be hidden behind a pref");
|
||||
SimpleTest.doesThrow(() => new MediaSource, "MediaSource should be hidden behind a pref");
|
||||
});
|
||||
|
||||
runWithMSE(function () {
|
||||
SimpleTest.doesThrow(() => new SourceBuffer, "new SourceBuffer should fail");
|
||||
SimpleTest.doesThrow(() => new SourceBufferList, "new SourceBufferList direct should fail");
|
||||
|
||||
var ms = new MediaSource();
|
||||
ok(ms, "Create a MediaSource object");
|
||||
ok(ms instanceof EventTarget, "MediaSource must be an EventTarget");
|
||||
is(ms.readyState, "closed", "New MediaSource must be in closed state");
|
||||
|
||||
// Wrapper creation, tests for leaks.
|
||||
SpecialPowers.wrap(ms);
|
||||
|
||||
// Set an expando to force wrapper creation, tests for leaks.
|
||||
ms.foo = null;
|
||||
|
||||
var o = URL.createObjectURL(ms);
|
||||
ok(o, "Create an objectURL from the MediaSource");
|
||||
|
||||
var v = document.createElement("video");
|
||||
v.preload = "auto";
|
||||
v.src = o;
|
||||
document.body.appendChild(v);
|
||||
|
||||
ms.addEventListener("sourceopen", function () {
|
||||
ok(true, "Receive a sourceopen event");
|
||||
is(ms.readyState, "open", "MediaSource must be in open state after sourceopen");
|
||||
var sb = ms.addSourceBuffer("video/webm");
|
||||
ok(sb, "Create a SourceBuffer");
|
||||
is(ms.sourceBuffers.length, 1, "MediaSource.sourceBuffers is expected length");
|
||||
is(ms.sourceBuffers[0], sb, "SourceBuffer in list matches our SourceBuffer");
|
||||
is(ms.activeSourceBuffers[0], sb, "SourceBuffer in active list matches our SourceBuffer");
|
||||
|
||||
fetchWithXHR("seek.webm", function (arrayBuffer) {
|
||||
sb.appendBuffer(new Uint8Array(arrayBuffer));
|
||||
ms.endOfStream();
|
||||
v.play();
|
||||
});
|
||||
});
|
||||
|
||||
ms.addEventListener("sourceended", function () {
|
||||
ok(true, "Receive a sourceended event");
|
||||
is(ms.readyState, "ended", "MediaSource must be in ended state after sourceended");
|
||||
});
|
||||
|
||||
v.addEventListener("ended", function () {
|
||||
is(v.duration, 4, "Video has correct duration");
|
||||
is(v.currentTime, 4, "Video has played to end");
|
||||
v.parentNode.removeChild(v);
|
||||
SimpleTest.finish();
|
||||
});
|
||||
});
|
||||
|
||||
function fetch(src, cb) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", src, true);
|
||||
xhr.responseType = "blob";
|
||||
xhr.addEventListener("load", function (e) {
|
||||
if (xhr.status != 200) {
|
||||
return false;
|
||||
}
|
||||
cb(xhr.response);
|
||||
});
|
||||
xhr.send();
|
||||
};
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
@ -3,6 +3,7 @@
|
||||
<head>
|
||||
<title>MSE: append initialization and media segment separately</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="mediasource.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
@ -11,72 +12,33 @@
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
addLoadEvent(function() {
|
||||
ok(!window.MediaSource, "MediaSource should be hidden behind a pref");
|
||||
var accessThrows = false;
|
||||
try {
|
||||
new MediaSource();
|
||||
} catch (e) {
|
||||
accessThrows = true;
|
||||
}
|
||||
ok(accessThrows, "MediaSource should be hidden behind a pref");
|
||||
SpecialPowers.pushPrefEnv({"set": [[ "media.mediasource.enabled", true ]]},
|
||||
function () {
|
||||
SpecialPowers.setBoolPref("media.mediasource.enabled", true);
|
||||
var ms = new MediaSource();
|
||||
ok(ms, "Create a MediaSource object");
|
||||
ok(ms instanceof EventTarget, "MediaSource must be an EventTarget");
|
||||
is(ms.readyState, "closed", "New MediaSource must be in closed state");
|
||||
// Force wrapper creation, tests for leaks.
|
||||
ms.foo = null;
|
||||
var o = URL.createObjectURL(ms);
|
||||
ok(o, "Create an objectURL from the MediaSource");
|
||||
var v = document.createElement("video");
|
||||
v.preload = "auto";
|
||||
document.body.appendChild(v);
|
||||
v.src = o;
|
||||
ms.addEventListener("sourceopen", function () {
|
||||
ok(true, "Receive a sourceopen event");
|
||||
is(ms.readyState, "open", "MediaSource must be in open state after sourceopen");
|
||||
var sb = ms.addSourceBuffer("video/webm");
|
||||
ok(sb, "Create a SourceBuffer");
|
||||
is(ms.sourceBuffers.length, 1, "MediaSource.sourceBuffers is expected length");
|
||||
is(ms.sourceBuffers[0], sb, "SourceBuffer in list matches our SourceBuffer");
|
||||
fetch("seek.webm", function (blob) {
|
||||
var r = new FileReader();
|
||||
r.addEventListener("load", function (e) {
|
||||
sb.appendBuffer(new Uint8Array(e.target.result, 0, 318));
|
||||
sb.appendBuffer(new Uint8Array(e.target.result, 318));
|
||||
ms.endOfStream();
|
||||
v.play();
|
||||
});
|
||||
r.readAsArrayBuffer(blob);
|
||||
});
|
||||
});
|
||||
ms.addEventListener("sourceended", function () {
|
||||
ok(true, "Receive a sourceended event");
|
||||
is(ms.readyState, "ended", "MediaSource must be in ended state after sourceended");
|
||||
});
|
||||
v.addEventListener("ended", function () {
|
||||
is(v.duration, 4, "Video has correct duration");
|
||||
v.parentNode.removeChild(v);
|
||||
SimpleTest.finish();
|
||||
runWithMSE(function () {
|
||||
var ms = new MediaSource();
|
||||
|
||||
var v = document.createElement("video");
|
||||
v.preload = "auto";
|
||||
v.src = URL.createObjectURL(ms);
|
||||
document.body.appendChild(v);
|
||||
|
||||
ms.addEventListener("sourceopen", function () {
|
||||
var sb = ms.addSourceBuffer("video/webm");
|
||||
|
||||
fetchWithXHR("seek.webm", function (arrayBuffer) {
|
||||
sb.appendBuffer(new Uint8Array(arrayBuffer, 0, 318));
|
||||
sb.appendBuffer(new Uint8Array(arrayBuffer, 318));
|
||||
ms.endOfStream();
|
||||
v.play();
|
||||
});
|
||||
});
|
||||
|
||||
v.addEventListener("ended", function () {
|
||||
is(v.duration, 4, "Video has correct duration");
|
||||
is(v.currentTime, 4, "Video has played to end");
|
||||
v.parentNode.removeChild(v);
|
||||
SimpleTest.finish();
|
||||
});
|
||||
});
|
||||
|
||||
function fetch(src, cb) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", src, true);
|
||||
xhr.responseType = "blob";
|
||||
xhr.addEventListener("load", function (e) {
|
||||
if (xhr.status != 200) {
|
||||
return false;
|
||||
}
|
||||
cb(xhr.response);
|
||||
});
|
||||
xhr.send();
|
||||
};
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
@ -3,6 +3,7 @@
|
||||
<head>
|
||||
<title>MSE: append segments with delay</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="mediasource.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
@ -11,74 +12,35 @@
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
addLoadEvent(function() {
|
||||
ok(!window.MediaSource, "MediaSource should be hidden behind a pref");
|
||||
var accessThrows = false;
|
||||
try {
|
||||
new MediaSource();
|
||||
} catch (e) {
|
||||
accessThrows = true;
|
||||
}
|
||||
ok(accessThrows, "MediaSource should be hidden behind a pref");
|
||||
SpecialPowers.pushPrefEnv({"set": [[ "media.mediasource.enabled", true ]]},
|
||||
function () {
|
||||
SpecialPowers.setBoolPref("media.mediasource.enabled", true);
|
||||
var ms = new MediaSource();
|
||||
ok(ms, "Create a MediaSource object");
|
||||
ok(ms instanceof EventTarget, "MediaSource must be an EventTarget");
|
||||
is(ms.readyState, "closed", "New MediaSource must be in closed state");
|
||||
// Force wrapper creation, tests for leaks.
|
||||
ms.foo = null;
|
||||
var o = URL.createObjectURL(ms);
|
||||
ok(o, "Create an objectURL from the MediaSource");
|
||||
var v = document.createElement("video");
|
||||
v.preload = "auto";
|
||||
document.body.appendChild(v);
|
||||
v.src = o;
|
||||
ms.addEventListener("sourceopen", function () {
|
||||
ok(true, "Receive a sourceopen event");
|
||||
is(ms.readyState, "open", "MediaSource must be in open state after sourceopen");
|
||||
var sb = ms.addSourceBuffer("video/webm");
|
||||
ok(sb, "Create a SourceBuffer");
|
||||
is(ms.sourceBuffers.length, 1, "MediaSource.sourceBuffers is expected length");
|
||||
is(ms.sourceBuffers[0], sb, "SourceBuffer in list matches our SourceBuffer");
|
||||
fetch("seek.webm", function (blob) {
|
||||
var r = new FileReader();
|
||||
r.addEventListener("load", function (e) {
|
||||
sb.appendBuffer(new Uint8Array(e.target.result, 0, 318));
|
||||
window.setTimeout(function () {
|
||||
sb.appendBuffer(new Uint8Array(e.target.result, 318));
|
||||
ms.endOfStream();
|
||||
}, 1000);
|
||||
v.play();
|
||||
});
|
||||
r.readAsArrayBuffer(blob);
|
||||
});
|
||||
});
|
||||
ms.addEventListener("sourceended", function () {
|
||||
ok(true, "Receive a sourceended event");
|
||||
is(ms.readyState, "ended", "MediaSource must be in ended state after sourceended");
|
||||
});
|
||||
v.addEventListener("ended", function () {
|
||||
is(v.duration, 4, "Video has correct duration");
|
||||
v.parentNode.removeChild(v);
|
||||
SimpleTest.finish();
|
||||
runWithMSE(function () {
|
||||
var ms = new MediaSource();
|
||||
|
||||
var v = document.createElement("video");
|
||||
v.preload = "auto";
|
||||
v.src = URL.createObjectURL(ms);
|
||||
document.body.appendChild(v);
|
||||
|
||||
ms.addEventListener("sourceopen", function () {
|
||||
var sb = ms.addSourceBuffer("video/webm");
|
||||
|
||||
fetchWithXHR("seek.webm", function (arrayBuffer) {
|
||||
sb.appendBuffer(new Uint8Array(arrayBuffer, 0, 318));
|
||||
window.setTimeout(function () {
|
||||
sb.appendBuffer(new Uint8Array(arrayBuffer, 318));
|
||||
ms.endOfStream();
|
||||
}, 1000);
|
||||
v.play();
|
||||
});
|
||||
});
|
||||
|
||||
v.addEventListener("ended", function () {
|
||||
is(v.duration, 4, "Video has correct duration");
|
||||
is(v.currentTime, 4, "Video has played to end");
|
||||
v.parentNode.removeChild(v);
|
||||
SimpleTest.finish();
|
||||
});
|
||||
});
|
||||
|
||||
function fetch(src, cb) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", src, true);
|
||||
xhr.responseType = "blob";
|
||||
xhr.addEventListener("load", function (e) {
|
||||
if (xhr.status != 200) {
|
||||
return false;
|
||||
}
|
||||
cb(xhr.response);
|
||||
});
|
||||
xhr.send();
|
||||
};
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
@ -91,15 +91,19 @@ SVGScriptElement::SetType(const nsAString & aType, ErrorResult& rv)
|
||||
}
|
||||
|
||||
void
|
||||
SVGScriptElement::GetCrossOrigin(nsAString & aOrigin)
|
||||
SVGScriptElement::GetCrossOrigin(nsAString & aCrossOrigin)
|
||||
{
|
||||
GetAttr(kNameSpaceID_None, nsGkAtoms::crossorigin, aOrigin);
|
||||
// Null for both missing and invalid defaults is ok, since we
|
||||
// always parse to an enum value, so we don't need an invalid
|
||||
// default, and we _want_ the missing default to be null.
|
||||
GetEnumAttr(nsGkAtoms::crossorigin, nullptr, aCrossOrigin);
|
||||
}
|
||||
|
||||
void
|
||||
SVGScriptElement::SetCrossOrigin(const nsAString & aOrigin, ErrorResult& rv)
|
||||
SVGScriptElement::SetCrossOrigin(const nsAString & aCrossOrigin,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
rv = SetAttr(kNameSpaceID_None, nsGkAtoms::crossorigin, aOrigin, true);
|
||||
SetOrRemoveNullableStringAttr(nsGkAtoms::crossorigin, aCrossOrigin, aError);
|
||||
}
|
||||
|
||||
already_AddRefed<SVGAnimatedString>
|
||||
|
@ -66,8 +66,8 @@ public:
|
||||
// WebIDL
|
||||
void GetType(nsAString & aType);
|
||||
void SetType(const nsAString & aType, ErrorResult& rv);
|
||||
void GetCrossOrigin(nsAString & aOrigin);
|
||||
void SetCrossOrigin(const nsAString & aOrigin, ErrorResult& rv);
|
||||
void GetCrossOrigin(nsAString & aCrossOrigin);
|
||||
void SetCrossOrigin(const nsAString & aCrossOrigin, ErrorResult& aError);
|
||||
already_AddRefed<SVGAnimatedString> Href();
|
||||
|
||||
protected:
|
||||
|
@ -16,6 +16,7 @@ support-files =
|
||||
getSubStringLength-helper.svg
|
||||
matrixUtils.js
|
||||
MutationEventChecker.js
|
||||
object-delayed-intrinsic-size.sjs
|
||||
pointer-events.js
|
||||
scientific-helper.svg
|
||||
selectSubString-helper.svg
|
||||
@ -50,6 +51,7 @@ skip-if = true
|
||||
[test_lengthParsing.html]
|
||||
[test_nonAnimStrings.xhtml]
|
||||
[test_non-scaling-stroke.html]
|
||||
[test_object-delayed-intrinsic-size.html]
|
||||
[test_onerror.xhtml]
|
||||
[test_pathAnimInterpolation.xhtml]
|
||||
[test_pathLength.html]
|
||||
|
24
content/svg/content/test/object-delayed-intrinsic-size.sjs
Normal file
24
content/svg/content/test/object-delayed-intrinsic-size.sjs
Normal file
@ -0,0 +1,24 @@
|
||||
|
||||
var timer = null;
|
||||
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
response.processAsync();
|
||||
|
||||
response.setStatusLine(null, 200, "OK");
|
||||
response.setHeader("Content-Type", "image/svg+xml", false);
|
||||
|
||||
// We need some body output or else gecko will not do an initial reflow
|
||||
// while waiting for the rest of the document to load:
|
||||
response.bodyOutputStream.write("\n", 1);
|
||||
|
||||
timer = Components.classes["@mozilla.org/timer;1"]
|
||||
.createInstance(Components.interfaces.nsITimer);
|
||||
timer.initWithCallback(function()
|
||||
{
|
||||
var body = "<svg xmlns='http://www.w3.org/2000/svg' width='70' height='0'></svg>";
|
||||
response.bodyOutputStream.write(body, body.length);
|
||||
response.finish();
|
||||
}, 1000 /* milliseconds */, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
|
||||
}
|
||||
|
@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1063073
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>Test that <object> embedding SVG and using its intrinsic
|
||||
size will resize if the <object> gets a reflow before the
|
||||
root-<svg> gets its nsSVGOuterSVGFrame
|
||||
</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<script>
|
||||
|
||||
// This test checks for a race condition. If it fails intermittently then it
|
||||
// may actually be a full failure.
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function runTest()
|
||||
{
|
||||
var object = document.querySelector("object");
|
||||
var cs = document.defaultView.getComputedStyle(object, "");
|
||||
var width = cs.getPropertyValue("width");
|
||||
is(width, "70px", "Check that the <object> size updated");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="runTest();">
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1063073">Mozilla Bug 1063073</a>
|
||||
<p id="display"></p>
|
||||
<div id="content">
|
||||
<object style="border:1px solid black" type="image/svg+xml"
|
||||
data="object-delayed-intrinsic-size.sjs"></object>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -9416,14 +9416,7 @@ nsDocShell::InternalLoad(nsIURI * aURI,
|
||||
aLoadType == LOAD_HISTORY ||
|
||||
aLoadType == LOAD_LINK) {
|
||||
|
||||
nsCOMPtr<nsIURI> currentURI;
|
||||
if (sURIFixup && mCurrentURI) {
|
||||
rv = sURIFixup->CreateExposableURI(mCurrentURI,
|
||||
getter_AddRefs(currentURI));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else {
|
||||
currentURI = mCurrentURI;
|
||||
}
|
||||
nsCOMPtr<nsIURI> currentURI = mCurrentURI;
|
||||
// Split currentURI and aURI on the '#' character. Make sure we read
|
||||
// the return values of SplitURIAtHash; if it fails, we don't want to
|
||||
// allow a short-circuited navigation.
|
||||
@ -9439,6 +9432,19 @@ nsDocShell::InternalLoad(nsIURI * aURI,
|
||||
NS_SUCCEEDED(splitRv2) &&
|
||||
curBeforeHash.Equals(newBeforeHash);
|
||||
|
||||
if (!sameExceptHashes && sURIFixup && currentURI &&
|
||||
NS_SUCCEEDED(splitRv2)) {
|
||||
// Maybe aURI came from the exposable form of currentURI?
|
||||
nsCOMPtr<nsIURI> currentExposableURI;
|
||||
rv = sURIFixup->CreateExposableURI(currentURI,
|
||||
getter_AddRefs(currentExposableURI));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
splitRv1 = nsContentUtils::SplitURIAtHash(currentExposableURI,
|
||||
curBeforeHash, curHash);
|
||||
sameExceptHashes = NS_SUCCEEDED(splitRv1) &&
|
||||
curBeforeHash.Equals(newBeforeHash);
|
||||
}
|
||||
|
||||
bool historyNavBetweenSameDoc = false;
|
||||
if (mOSHE && aSHEntry) {
|
||||
// We're doing a history load.
|
||||
|
@ -911,9 +911,8 @@ Console::Method(JSContext* aCx, MethodName aMethodName,
|
||||
nsGlobalWindow *win = static_cast<nsGlobalWindow*>(mWindow.get());
|
||||
MOZ_ASSERT(win);
|
||||
|
||||
ErrorResult rv;
|
||||
nsRefPtr<nsPerformance> performance = win->GetPerformance(rv);
|
||||
if (rv.Failed() || !performance) {
|
||||
nsRefPtr<nsPerformance> performance = win->GetPerformance();
|
||||
if (!performance) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -69,19 +69,6 @@ ShouldExposeChildWindow(nsString& aNameBeingResolved, nsIDOMWindow *aChild)
|
||||
aNameBeingResolved, eCaseMatters);
|
||||
}
|
||||
|
||||
static nsGlobalWindow*
|
||||
GetWindowFromGlobal(JSObject* aGlobal)
|
||||
{
|
||||
nsGlobalWindow* win;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(Window, aGlobal, win))) {
|
||||
return win;
|
||||
}
|
||||
XPCWrappedNative* wrapper = XPCWrappedNative::Get(aGlobal);
|
||||
nsCOMPtr<nsPIDOMWindow> piWin = do_QueryWrappedNative(wrapper);
|
||||
MOZ_ASSERT(piWin);
|
||||
return static_cast<nsGlobalWindow*>(piWin.get());
|
||||
}
|
||||
|
||||
bool
|
||||
WindowNamedPropertiesHandler::getOwnPropDescriptor(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aProxy,
|
||||
@ -106,7 +93,7 @@ WindowNamedPropertiesHandler::getOwnPropDescriptor(JSContext* aCx,
|
||||
}
|
||||
|
||||
// Grab the DOM window.
|
||||
nsGlobalWindow* win = GetWindowFromGlobal(global);
|
||||
nsGlobalWindow* win = xpc::WindowOrNull(global);
|
||||
if (win->Length() > 0) {
|
||||
nsCOMPtr<nsIDOMWindow> childWin = win->GetChildWindow(str);
|
||||
if (childWin && ShouldExposeChildWindow(str, childWin)) {
|
||||
@ -178,7 +165,7 @@ WindowNamedPropertiesHandler::ownPropNames(JSContext* aCx,
|
||||
JS::AutoIdVector& aProps) const
|
||||
{
|
||||
// Grab the DOM window.
|
||||
nsGlobalWindow* win = GetWindowFromGlobal(JS_GetGlobalForObject(aCx, aProxy));
|
||||
nsGlobalWindow* win = xpc::WindowOrNull(JS_GetGlobalForObject(aCx, aProxy));
|
||||
nsTArray<nsString> names;
|
||||
win->GetSupportedNames(names);
|
||||
// Filter out the ones we wouldn't expose from getOwnPropertyDescriptor.
|
||||
|
@ -35,7 +35,6 @@
|
||||
#include "nsIXPConnect.h"
|
||||
#include "xptcall.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsDocument.h" // nsDOMStyleSheetList
|
||||
#include "nsDOMBlobBuilder.h"
|
||||
|
||||
// General helper includes
|
||||
@ -51,18 +50,12 @@
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
||||
// Window scriptable helper includes
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsJSUtils.h"
|
||||
#include "nsScriptNameSpaceManager.h"
|
||||
#include "nsIJSNativeInitializer.h"
|
||||
#include "nsJSEnvironment.h"
|
||||
|
||||
// DOM base includes
|
||||
#include "nsIDOMLocation.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIDOMJSWindow.h"
|
||||
#include "nsIDOMChromeWindow.h"
|
||||
#include "nsIDOMConstructor.h"
|
||||
|
||||
// DOM core includes
|
||||
@ -134,10 +127,7 @@
|
||||
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/Likely.h"
|
||||
#include "WindowNamedPropertiesHandler.h"
|
||||
#include "nsIInterfaceInfoManager.h"
|
||||
#include "mozilla/dom/EventTargetBinding.h"
|
||||
#include "mozilla/dom/WindowBinding.h"
|
||||
|
||||
#ifdef MOZ_TIME_MANAGER
|
||||
#include "TimeManager.h"
|
||||
@ -151,14 +141,6 @@ static NS_DEFINE_CID(kDOMSOF_CID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
|
||||
// NOTE: DEFAULT_SCRIPTABLE_FLAGS and DOM_DEFAULT_SCRIPTABLE_FLAGS
|
||||
// are defined in nsIDOMClassInfo.h.
|
||||
|
||||
#define WINDOW_SCRIPTABLE_FLAGS \
|
||||
(nsIXPCScriptable::WANT_PRECREATE | \
|
||||
nsIXPCScriptable::WANT_POSTCREATE | \
|
||||
nsIXPCScriptable::WANT_ENUMERATE | \
|
||||
nsIXPCScriptable::DONT_ENUM_QUERY_INTERFACE | \
|
||||
nsIXPCScriptable::IS_GLOBAL_OBJECT | \
|
||||
nsIXPCScriptable::WANT_OUTER_OBJECT)
|
||||
|
||||
#define ARRAY_SCRIPTABLE_FLAGS \
|
||||
(DOM_DEFAULT_SCRIPTABLE_FLAGS | \
|
||||
nsIXPCScriptable::WANT_GETPROPERTY | \
|
||||
@ -244,17 +226,6 @@ DOMCI_DATA_NO_CLASS(XULPopupElement)
|
||||
static nsDOMClassInfoData sClassInfoData[] = {
|
||||
// Base classes
|
||||
|
||||
// The Window class lets you QI into interfaces that are not in the
|
||||
// flattened set (i.e. nsIXPCScriptable::CLASSINFO_INTERFACES_ONLY
|
||||
// is not set), because of this make sure all scriptable interfaces
|
||||
// that are implemented by nsGlobalWindow can securely be exposed
|
||||
// to JS.
|
||||
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(Window, nsWindowSH,
|
||||
DEFAULT_SCRIPTABLE_FLAGS |
|
||||
WINDOW_SCRIPTABLE_FLAGS)
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(DOMPrototype, nsDOMConstructorSH,
|
||||
DOM_BASE_SCRIPTABLE_FLAGS |
|
||||
nsIXPCScriptable::WANT_PRECREATE |
|
||||
@ -300,11 +271,6 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||
DEFAULT_SCRIPTABLE_FLAGS)
|
||||
#endif
|
||||
|
||||
// DOM Chrome Window class.
|
||||
NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(ChromeWindow, nsWindowSH,
|
||||
DEFAULT_SCRIPTABLE_FLAGS |
|
||||
WINDOW_SCRIPTABLE_FLAGS)
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULTemplateBuilder, nsDOMGenericSH,
|
||||
DEFAULT_SCRIPTABLE_FLAGS)
|
||||
@ -335,10 +301,6 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||
NS_DEFINE_CLASSINFO_DATA(File, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(ModalContentWindow, nsWindowSH,
|
||||
DEFAULT_SCRIPTABLE_FLAGS |
|
||||
WINDOW_SCRIPTABLE_FLAGS)
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(MozSmsMessage, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
||||
@ -424,10 +386,7 @@ nsIXPConnect *nsDOMClassInfo::sXPConnect = nullptr;
|
||||
bool nsDOMClassInfo::sIsInitialized = false;
|
||||
|
||||
|
||||
jsid nsDOMClassInfo::sLocation_id = JSID_VOID;
|
||||
jsid nsDOMClassInfo::sConstructor_id = JSID_VOID;
|
||||
jsid nsDOMClassInfo::sTop_id = JSID_VOID;
|
||||
jsid nsDOMClassInfo::sDocument_id = JSID_VOID;
|
||||
jsid nsDOMClassInfo::sWrappedJSObject_id = JSID_VOID;
|
||||
|
||||
static const JSClass *sObjectClass = nullptr;
|
||||
@ -519,10 +478,7 @@ nsDOMClassInfo::DefineStaticJSVals(JSContext *cx)
|
||||
else \
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
SET_JSID_TO_STRING(sLocation_id, cx, "location");
|
||||
SET_JSID_TO_STRING(sConstructor_id, cx, "constructor");
|
||||
SET_JSID_TO_STRING(sTop_id, cx, "top");
|
||||
SET_JSID_TO_STRING(sDocument_id, cx, "document");
|
||||
SET_JSID_TO_STRING(sWrappedJSObject_id, cx, "wrappedJSObject");
|
||||
|
||||
return NS_OK;
|
||||
@ -734,29 +690,6 @@ nsDOMClassInfo::RegisterExternalClasses()
|
||||
d.mInterfaces = interface_list; \
|
||||
}
|
||||
|
||||
#ifdef MOZ_B2G
|
||||
#define DOM_CLASSINFO_WINDOW_MAP_ENTRIES \
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMWindow) \
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMWindowB2G) \
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMJSWindow) \
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget) \
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIInlineEventHandlers) \
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMWindowPerformance) \
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIInterfaceRequestor) \
|
||||
DOM_CLASSINFO_MAP_CONDITIONAL_ENTRY(nsITouchEventReceiver, \
|
||||
TouchEvent::PrefEnabled())
|
||||
#else // !MOZ_B2G
|
||||
#define DOM_CLASSINFO_WINDOW_MAP_ENTRIES \
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMWindow) \
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMJSWindow) \
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget) \
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIInlineEventHandlers) \
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMWindowPerformance) \
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIInterfaceRequestor) \
|
||||
DOM_CLASSINFO_MAP_CONDITIONAL_ENTRY(nsITouchEventReceiver, \
|
||||
TouchEvent::PrefEnabled())
|
||||
#endif // MOZ_B2G
|
||||
|
||||
nsresult
|
||||
nsDOMClassInfo::Init()
|
||||
{
|
||||
@ -778,13 +711,6 @@ nsDOMClassInfo::Init()
|
||||
|
||||
AutoSafeJSContext cx;
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(Window, nsIDOMWindow)
|
||||
DOM_CLASSINFO_WINDOW_MAP_ENTRIES
|
||||
#ifdef MOZ_WEBSPEECH
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsISpeechSynthesisGetter)
|
||||
#endif
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(DOMPrototype, nsIDOMDOMConstructor)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMDOMConstructor)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
@ -838,14 +764,6 @@ nsDOMClassInfo::Init()
|
||||
DOM_CLASSINFO_MAP_END
|
||||
#endif
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(ChromeWindow, nsIDOMWindow)
|
||||
DOM_CLASSINFO_WINDOW_MAP_ENTRIES
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMChromeWindow)
|
||||
#ifdef MOZ_WEBSPEECH
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsISpeechSynthesisGetter)
|
||||
#endif
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
DOM_CLASSINFO_MAP_BEGIN(XULTemplateBuilder, nsIXULTemplateBuilder)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIXULTemplateBuilder)
|
||||
@ -890,14 +808,6 @@ nsDOMClassInfo::Init()
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMFile)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(ModalContentWindow, nsIDOMWindow)
|
||||
DOM_CLASSINFO_WINDOW_MAP_ENTRIES
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMModalContentWindow)
|
||||
#ifdef MOZ_WEBSPEECH
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsISpeechSynthesisGetter)
|
||||
#endif
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(MozSmsMessage, nsIDOMMozSmsMessage)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozSmsMessage)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
@ -1555,146 +1465,13 @@ nsDOMClassInfo::ShutDown()
|
||||
}
|
||||
}
|
||||
|
||||
sLocation_id = JSID_VOID;
|
||||
sConstructor_id = JSID_VOID;
|
||||
sTop_id = JSID_VOID;
|
||||
sDocument_id = JSID_VOID;
|
||||
sWrappedJSObject_id = JSID_VOID;
|
||||
|
||||
NS_IF_RELEASE(sXPConnect);
|
||||
sIsInitialized = false;
|
||||
}
|
||||
|
||||
// Window helper
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
|
||||
JSObject *globalObj, JSObject **parentObj)
|
||||
{
|
||||
// Normally ::PreCreate() is used to give XPConnect the parent
|
||||
// object for the object that's being wrapped, this parent object is
|
||||
// set as the parent of the wrapper and it's also used to find the
|
||||
// right scope for the object being wrapped. Now, in the case of the
|
||||
// global object the wrapper shouldn't have a parent but we supply
|
||||
// one here anyway (the global object itself) and this will be used
|
||||
// by XPConnect only to find the right scope, once the scope is
|
||||
// found XPConnect will find the existing wrapper (which always
|
||||
// exists since it's created on window construction), since an
|
||||
// existing wrapper is found the parent we supply here is ignored
|
||||
// after the wrapper is found.
|
||||
|
||||
nsCOMPtr<nsIScriptGlobalObject> sgo(do_QueryInterface(nativeObj));
|
||||
NS_ASSERTION(sgo, "nativeObj not a global object!");
|
||||
|
||||
nsGlobalWindow *win = nsGlobalWindow::FromSupports(nativeObj);
|
||||
NS_ASSERTION(win->IsInnerWindow(), "Should be inner window.");
|
||||
|
||||
// We sometimes get a disconnected window during file api test. :-(
|
||||
if (!win->GetOuterWindowInternal())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// If we're bootstrapping, we don't have a JS object yet.
|
||||
if (win->GetOuterWindowInternal()->IsCreatingInnerWindow())
|
||||
return NS_OK;
|
||||
|
||||
return SetParentToWindow(win, parentObj);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowSH::PostCreatePrototype(JSContext* aCx, JSObject* aProto)
|
||||
{
|
||||
JS::Rooted<JSObject*> proto(aCx, aProto);
|
||||
|
||||
nsresult rv = nsDOMClassInfo::PostCreatePrototype(aCx, proto);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// We should probably move this into the CreateInterfaceObjects for Window
|
||||
// once it is on WebIDL bindings.
|
||||
WindowNamedPropertiesHandler::Install(aCx, proto);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowSH::PostCreate(nsIXPConnectWrappedNative *wrapper,
|
||||
JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JS::Rooted<JSObject*> window(cx, obj);
|
||||
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsIScriptGlobalObject> sgo(do_QueryWrappedNative(wrapper));
|
||||
|
||||
NS_ASSERTION(sgo && sgo->GetGlobalJSObject() == obj,
|
||||
"Multiple wrappers created for global object!");
|
||||
#endif
|
||||
|
||||
const NativeProperties* windowProperties =
|
||||
WindowBinding::sNativePropertyHooks->mNativeProperties.regular;
|
||||
const NativeProperties* eventTargetProperties =
|
||||
EventTargetBinding::sNativePropertyHooks->mNativeProperties.regular;
|
||||
|
||||
if (!DefineWebIDLBindingUnforgeablePropertiesOnXPCObject(cx, window, windowProperties) ||
|
||||
!DefineWebIDLBindingUnforgeablePropertiesOnXPCObject(cx, window, eventTargetProperties)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (!GlobalPropertiesAreOwn()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return DefineWebIDLBindingPropertiesOnXPCObject(cx, window, windowProperties) &&
|
||||
DefineWebIDLBindingPropertiesOnXPCObject(cx, window, eventTargetProperties) ?
|
||||
NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
struct ResolveGlobalNameClosure
|
||||
{
|
||||
JSContext* cx;
|
||||
JS::Handle<JSObject*> obj;
|
||||
bool* retval;
|
||||
};
|
||||
|
||||
static PLDHashOperator
|
||||
ResolveGlobalName(const nsAString& aName,
|
||||
const nsGlobalNameStruct& aNameStruct,
|
||||
void* aClosure)
|
||||
{
|
||||
ResolveGlobalNameClosure* closure =
|
||||
static_cast<ResolveGlobalNameClosure*>(aClosure);
|
||||
JS::Rooted<JS::Value> dummy(closure->cx);
|
||||
bool ok = JS_LookupUCProperty(closure->cx, closure->obj,
|
||||
aName.BeginReading(), aName.Length(),
|
||||
&dummy);
|
||||
if (!ok) {
|
||||
*closure->retval = false;
|
||||
return PL_DHASH_STOP;
|
||||
}
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowSH::Enumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *aObj, bool *_retval)
|
||||
{
|
||||
JS::Rooted<JSObject*> obj(cx, aObj);
|
||||
if (!xpc::WrapperFactory::IsXrayWrapper(obj)) {
|
||||
*_retval = JS_EnumerateStandardClasses(cx, obj);
|
||||
if (!*_retval) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Now resolve everything from the namespace manager
|
||||
nsScriptNameSpaceManager *nameSpaceManager = GetNameSpaceManager();
|
||||
if (!nameSpaceManager) {
|
||||
NS_ERROR("Can't get namespace manager.");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
ResolveGlobalNameClosure closure = { cx, obj, _retval };
|
||||
nameSpaceManager->EnumerateGlobalNames(ResolveGlobalName, &closure);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsDOMConstructorFunc
|
||||
FindConstructorFunc(const nsDOMClassInfoData *aDOMClassInfoData)
|
||||
{
|
||||
@ -2265,23 +2042,6 @@ GetXPCProto(nsIXPConnect *aXPConnect, JSContext *cx, nsGlobalWindow *aWin,
|
||||
nsDOMClassInfoID ci_id = (nsDOMClassInfoID)id;
|
||||
|
||||
ci = NS_GetDOMClassInfoInstance(ci_id);
|
||||
|
||||
// In most cases we want to find the wrapped native prototype in
|
||||
// aWin's scope and use that prototype for
|
||||
// ClassName.prototype. But in the case where we're setting up
|
||||
// "Window.prototype" or "ChromeWindow.prototype" we want to do
|
||||
// the look up in aWin's outer window's scope since the inner
|
||||
// window's wrapped native prototype comes from the outer
|
||||
// window's scope.
|
||||
if (ci_id == eDOMClassInfo_Window_id ||
|
||||
ci_id == eDOMClassInfo_ModalContentWindow_id ||
|
||||
ci_id == eDOMClassInfo_ChromeWindow_id) {
|
||||
nsGlobalWindow *scopeWindow = aWin->GetOuterWindowInternal();
|
||||
|
||||
if (scopeWindow) {
|
||||
aWin = scopeWindow;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ci = nsDOMClassInfo::GetClassInfoInstance(aNameStruct->mData);
|
||||
@ -2498,6 +2258,7 @@ LookupComponentsShim(JSContext *cx, JS::Handle<JSObject*> global,
|
||||
nsPIDOMWindow *win,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc);
|
||||
|
||||
// static
|
||||
bool
|
||||
nsWindowSH::NameStructEnabled(JSContext* aCx, nsGlobalWindow *aWin,
|
||||
const nsAString& aName,
|
||||
@ -2732,7 +2493,7 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
|
||||
// set up the prototype chain. This will go ahead and define things on the
|
||||
// actual window's global.
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> proto_holder;
|
||||
rv = GetXPCProto(sXPConnect, cx, aWin, name_struct,
|
||||
rv = GetXPCProto(nsDOMClassInfo::sXPConnect, cx, aWin, name_struct,
|
||||
getter_AddRefs(proto_holder));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
bool isXray = xpc::WrapperFactory::IsXrayWrapper(obj);
|
||||
@ -2755,7 +2516,8 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
|
||||
ci_data = name_struct->mData;
|
||||
}
|
||||
|
||||
return ResolvePrototype(sXPConnect, aWin, cx, obj, class_name, ci_data,
|
||||
return ResolvePrototype(nsDOMClassInfo::sXPConnect, aWin, cx, obj,
|
||||
class_name, ci_data,
|
||||
name_struct, nameSpaceManager, dot_prototype,
|
||||
desc);
|
||||
}
|
||||
@ -2763,7 +2525,8 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
|
||||
if (name_struct->mType == nsGlobalNameStruct::eTypeClassProto) {
|
||||
// We don't have a XPConnect prototype object, let ResolvePrototype create
|
||||
// one.
|
||||
return ResolvePrototype(sXPConnect, aWin, cx, obj, class_name, nullptr,
|
||||
return ResolvePrototype(nsDOMClassInfo::sXPConnect, aWin, cx, obj,
|
||||
class_name, nullptr,
|
||||
name_struct, nameSpaceManager, nullptr, desc);
|
||||
}
|
||||
|
||||
@ -2776,7 +2539,7 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
|
||||
// constructor is an alias for (for example for Image we need the prototype
|
||||
// for HTMLImageElement).
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> proto_holder;
|
||||
rv = GetXPCProto(sXPConnect, cx, aWin, alias_struct,
|
||||
rv = GetXPCProto(nsDOMClassInfo::sXPConnect, cx, aWin, alias_struct,
|
||||
getter_AddRefs(proto_holder));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
@ -2792,7 +2555,8 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
return ResolvePrototype(sXPConnect, aWin, cx, obj, class_name, ci_data,
|
||||
return ResolvePrototype(nsDOMClassInfo::sXPConnect, aWin, cx, obj,
|
||||
class_name, ci_data,
|
||||
name_struct, nameSpaceManager, nullptr, desc);
|
||||
}
|
||||
|
||||
@ -2860,77 +2624,6 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
|
||||
return rv;
|
||||
}
|
||||
|
||||
template<class Interface>
|
||||
static nsresult
|
||||
LocationSetterGuts(JSContext *cx, JSObject *obj, JS::MutableHandle<JS::Value> vp)
|
||||
{
|
||||
// This function duplicates some of the logic in XPC_WN_HelperSetProperty
|
||||
obj = js::CheckedUnwrap(obj, /* stopAtOuter = */ false);
|
||||
if (!IS_WN_REFLECTOR(obj))
|
||||
return NS_ERROR_XPC_BAD_CONVERT_JS;
|
||||
XPCWrappedNative *wrapper = XPCWrappedNative::Get(obj);
|
||||
|
||||
// The error checks duplicate code in THROW_AND_RETURN_IF_BAD_WRAPPER
|
||||
NS_ENSURE_TRUE(!wrapper || wrapper->IsValid(), NS_ERROR_XPC_HAS_BEEN_SHUTDOWN);
|
||||
|
||||
nsCOMPtr<Interface> xpcomObj = do_QueryWrappedNative(wrapper, obj);
|
||||
NS_ENSURE_TRUE(xpcomObj, NS_ERROR_UNEXPECTED);
|
||||
|
||||
nsCOMPtr<nsIDOMLocation> location;
|
||||
nsresult rv = xpcomObj->GetLocation(getter_AddRefs(location));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Grab the value we're being set to before we stomp on |vp|
|
||||
JS::Rooted<JSString*> val(cx, JS::ToString(cx, vp));
|
||||
NS_ENSURE_TRUE(val, NS_ERROR_UNEXPECTED);
|
||||
|
||||
// Make sure |val| stays alive below
|
||||
JS::Anchor<JSString *> anchor(val);
|
||||
|
||||
// We have to wrap location into vp before null-checking location, to
|
||||
// avoid assigning the wrong thing into the slot.
|
||||
rv = WrapNative(cx, location, &NS_GET_IID(nsIDOMLocation), true, vp);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!location) {
|
||||
// Make this a no-op
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoJSString str;
|
||||
NS_ENSURE_TRUE(str.init(cx, val), NS_ERROR_UNEXPECTED);
|
||||
|
||||
return location->SetHref(str);
|
||||
}
|
||||
|
||||
template<class Interface>
|
||||
static bool
|
||||
LocationSetter(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, bool strict,
|
||||
JS::MutableHandle<JS::Value> vp)
|
||||
{
|
||||
nsresult rv = LocationSetterGuts<Interface>(cx, obj, vp);
|
||||
if (NS_FAILED(rv)) {
|
||||
xpc::Throw(cx, rv);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
LocationSetterUnwrapper(JSContext *cx, JS::Handle<JSObject*> obj_, JS::Handle<jsid> id,
|
||||
bool strict, JS::MutableHandle<JS::Value> vp)
|
||||
{
|
||||
JS::Rooted<JSObject*> obj(cx, obj_);
|
||||
|
||||
JSObject *wrapped = XPCWrapper::UnsafeUnwrapSecurityWrapper(obj);
|
||||
if (wrapped) {
|
||||
obj = wrapped;
|
||||
}
|
||||
|
||||
return LocationSetter<nsIDOMWindow>(cx, obj, id, strict, vp);
|
||||
}
|
||||
|
||||
struct InterfaceShimEntry {
|
||||
const char *geckoName;
|
||||
const char *domName;
|
||||
@ -3019,200 +2712,6 @@ LookupComponentsShim(JSContext *cx, JS::Handle<JSObject*> global,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj_, jsid id_, JSObject **objp,
|
||||
bool *_retval)
|
||||
{
|
||||
JS::Rooted<JSObject*> obj(cx, obj_);
|
||||
JS::Rooted<jsid> id(cx, id_);
|
||||
|
||||
if (!JSID_IS_STRING(id)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(*_retval == true); // guaranteed by XPC_WN_Helper_NewResolve
|
||||
|
||||
nsGlobalWindow *win = nsGlobalWindow::FromWrapper(wrapper);
|
||||
MOZ_ASSERT(win->IsInnerWindow());
|
||||
|
||||
// Don't resolve standard classes on XrayWrappers, only resolve them if we're
|
||||
// resolving on the real global object.
|
||||
bool isXray = xpc::WrapperFactory::IsXrayWrapper(obj);
|
||||
if (!isXray) {
|
||||
bool did_resolve = false;
|
||||
if (!JS_ResolveStandardClass(cx, obj, id, &did_resolve)) {
|
||||
// Return NS_OK to avoid stomping over the exception that was passed
|
||||
// down from the ResolveStandardClass call.
|
||||
*_retval = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (did_resolve) {
|
||||
*objp = obj;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// WebIDL quickstubs handle location for us, but Xrays don't see those. So if
|
||||
// we're an Xray, we have to resolve stuff here to make "window.location =
|
||||
// someString" work.
|
||||
if (sLocation_id == id && isXray) {
|
||||
nsCOMPtr<nsIDOMLocation> location;
|
||||
nsresult rv = win->GetLocation(getter_AddRefs(location));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
JS::Rooted<JS::Value> v(cx);
|
||||
rv = WrapNative(cx, location, &NS_GET_IID(nsIDOMLocation), true, &v);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool ok = JS_DefinePropertyById(cx, obj, id, v,
|
||||
JSPROP_PERMANENT | JSPROP_ENUMERATE,
|
||||
JS_PropertyStub, LocationSetterUnwrapper);
|
||||
|
||||
if (!ok) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*objp = obj;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// WebIDL quickstubs handle "top" for us, but Xrays don't see those. So if
|
||||
// we're an Xray and we want "top" to be JSPROP_PERMANENT, we need to resolve
|
||||
// it here.
|
||||
if (sTop_id == id && isXray) {
|
||||
nsCOMPtr<nsIDOMWindow> top;
|
||||
nsresult rv = win->GetScriptableTop(getter_AddRefs(top));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
JS::Rooted<JS::Value> v(cx);
|
||||
js::AssertSameCompartment(cx, obj);
|
||||
rv = WrapNative(cx, top, &NS_GET_IID(nsIDOMWindow), true, &v);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Hold on to the top window object as a global property so we
|
||||
// don't need to worry about losing expando properties etc.
|
||||
if (!JS_DefinePropertyById(cx, obj, id, v,
|
||||
JSPROP_READONLY | JSPROP_PERMANENT |
|
||||
JSPROP_ENUMERATE,
|
||||
JS_PropertyStub, JS_StrictPropertyStub)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
*objp = obj;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (isXray) {
|
||||
// We promise to resolve on the underlying object first. That will create
|
||||
// the actual interface object if needed and store it in a data structure
|
||||
// hanging off the global. Then our second call will wrap up in an Xray as
|
||||
// needed. We do things this way because we use the existence of the
|
||||
// object in that data structure as a flag that indicates that its name
|
||||
// (and any relevant named constructor names) has been resolved before;
|
||||
// this allows us to avoid re-resolving in the Xray case if the property is
|
||||
// deleted by page script.
|
||||
JS::Rooted<JSObject*> global(cx,
|
||||
js::UncheckedUnwrap(obj, /* stopAtOuter = */ false));
|
||||
JSAutoCompartment ac(cx, global);
|
||||
JS::Rooted<JSPropertyDescriptor> desc(cx);
|
||||
if (!win->DoNewResolve(cx, global, id, &desc)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
// If we have an object here, that means we resolved the property.
|
||||
// But if the value is undefined, that means that GlobalResolve
|
||||
// also already defined it, so we don't have to.
|
||||
if (desc.object() && !desc.value().isUndefined() &&
|
||||
!JS_DefinePropertyById(cx, global, id, desc.value(),
|
||||
desc.attributes(),
|
||||
desc.getter(), desc.setter())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
JS::Rooted<JSPropertyDescriptor> desc(cx);
|
||||
if (!win->DoNewResolve(cx, obj, id, &desc)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (desc.object()) {
|
||||
// If we have an object here, that means we resolved the property.
|
||||
// But if the value is undefined, that means that GlobalResolve
|
||||
// also already defined it, so we don't have to. Note that in the
|
||||
// Xray case we should never see undefined.
|
||||
MOZ_ASSERT_IF(isXray, !desc.value().isUndefined());
|
||||
if (!desc.value().isUndefined() &&
|
||||
!JS_DefinePropertyById(cx, obj, id, desc.value(),
|
||||
desc.attributes(),
|
||||
desc.getter(), desc.setter())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*objp = obj;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (sDocument_id == id) {
|
||||
nsCOMPtr<nsIDocument> document = win->GetDoc();
|
||||
JS::Rooted<JS::Value> v(cx);
|
||||
nsresult rv = WrapNative(cx, document, document,
|
||||
&NS_GET_IID(nsIDOMDocument), &v, false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// nsIDocument::WrapObject will handle defining the property.
|
||||
*objp = obj;
|
||||
|
||||
// NB: We need to do this for any Xray wrapper.
|
||||
if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
|
||||
*_retval = JS_WrapValue(cx, &v) &&
|
||||
JS_DefineProperty(cx, obj, "document", v,
|
||||
JSPROP_READONLY | JSPROP_ENUMERATE,
|
||||
JS_PropertyStub, JS_StrictPropertyStub);
|
||||
if (!*_retval) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return nsDOMGenericSH::NewResolve(wrapper, cx, obj, id, objp, _retval);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowSH::OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
|
||||
JSObject * obj, JSObject * *_retval)
|
||||
{
|
||||
nsGlobalWindow *origWin = nsGlobalWindow::FromWrapper(wrapper);
|
||||
nsGlobalWindow *win = origWin->GetOuterWindowInternal();
|
||||
|
||||
if (!win) {
|
||||
// If we no longer have an outer window. No code should ever be
|
||||
// running on a window w/o an outer, which means this hook should
|
||||
// never be called when we have no outer. But just in case, return
|
||||
// null to prevent leaking an inner window to code in a different
|
||||
// window.
|
||||
*_retval = nullptr;
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> winObj(cx, win->FastGetGlobalJSObject());
|
||||
MOZ_ASSERT(winObj);
|
||||
|
||||
// Note that while |wrapper| is same-compartment with cx, the outer window
|
||||
// might not be. If we're running script in an inactive scope and evalute
|
||||
// |this|, the outer window is actually a cross-compartment wrapper. So we
|
||||
// need to wrap here.
|
||||
if (!JS_WrapObject(cx, &winObj)) {
|
||||
*_retval = nullptr;
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
*_retval = winObj;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// EventTarget helper
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -68,10 +68,11 @@ struct nsExternalDOMClassInfoData : public nsDOMClassInfoData
|
||||
#define MARK_EXTERNAL(_ptr) (nsIClassInfo*)(uintptr_t(_ptr) | 0x1)
|
||||
#define IS_EXTERNAL(_ptr) (uintptr_t(_ptr) & 0x1)
|
||||
|
||||
class nsWindowSH;
|
||||
|
||||
class nsDOMClassInfo : public nsXPCClassInfo
|
||||
{
|
||||
friend class nsHTMLDocumentSH;
|
||||
friend class nsWindowSH;
|
||||
|
||||
protected:
|
||||
virtual ~nsDOMClassInfo();
|
||||
@ -156,10 +157,7 @@ protected:
|
||||
static bool sIsInitialized;
|
||||
|
||||
public:
|
||||
static jsid sLocation_id;
|
||||
static jsid sConstructor_id;
|
||||
static jsid sTop_id;
|
||||
static jsid sDocument_id;
|
||||
static jsid sWrappedJSObject_id;
|
||||
};
|
||||
|
||||
@ -230,46 +228,20 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
// Window scriptable helper
|
||||
|
||||
class nsWindowSH : public nsDOMGenericSH
|
||||
// A place to hang some static methods that we should really consider
|
||||
// moving to be nsGlobalWindow member methods. See bug 1062418.
|
||||
class nsWindowSH
|
||||
{
|
||||
protected:
|
||||
explicit nsWindowSH(nsDOMClassInfoData *aData) : nsDOMGenericSH(aData)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~nsWindowSH()
|
||||
{
|
||||
}
|
||||
|
||||
static nsresult GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
|
||||
JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc);
|
||||
|
||||
friend class nsGlobalWindow;
|
||||
public:
|
||||
NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx,
|
||||
JSObject *globalObj, JSObject **parentObj) MOZ_OVERRIDE;
|
||||
NS_IMETHOD PostCreatePrototype(JSContext * cx, JSObject * proto) MOZ_OVERRIDE;
|
||||
NS_IMETHOD PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj) MOZ_OVERRIDE;
|
||||
NS_IMETHOD Enumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, bool *_retval) MOZ_OVERRIDE;
|
||||
NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, jsid id, JSObject **objp,
|
||||
bool *_retval) MOZ_OVERRIDE;
|
||||
NS_IMETHOD OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
|
||||
JSObject * obj, JSObject * *_retval) MOZ_OVERRIDE;
|
||||
|
||||
static bool NameStructEnabled(JSContext* aCx, nsGlobalWindow *aWin,
|
||||
const nsAString& aName,
|
||||
const nsGlobalNameStruct& aNameStruct);
|
||||
|
||||
static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
|
||||
{
|
||||
return new nsWindowSH(aData);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -4,7 +4,6 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
// IWYU pragma: private, include "nsDOMClassInfoID.h"
|
||||
|
||||
DOMCI_CLASS(Window)
|
||||
DOMCI_CLASS(DOMPrototype)
|
||||
DOMCI_CLASS(DOMConstructor)
|
||||
|
||||
@ -26,9 +25,6 @@ DOMCI_CLASS(TreeSelection)
|
||||
DOMCI_CLASS(TreeContentView)
|
||||
#endif
|
||||
|
||||
// DOM Chrome Window class, almost identical to Window
|
||||
DOMCI_CLASS(ChromeWindow)
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
DOMCI_CLASS(XULTemplateBuilder)
|
||||
DOMCI_CLASS(XULTreeBuilder)
|
||||
@ -50,9 +46,6 @@ DOMCI_CLASS(XPathNSResolver)
|
||||
DOMCI_CLASS(Blob)
|
||||
DOMCI_CLASS(File)
|
||||
|
||||
// DOM modal content window class, almost identical to Window
|
||||
DOMCI_CLASS(ModalContentWindow)
|
||||
|
||||
DOMCI_CLASS(MozSmsMessage)
|
||||
DOMCI_CLASS(MozMmsMessage)
|
||||
DOMCI_CLASS(MozMobileMessageThread)
|
||||
|
@ -3612,6 +3612,23 @@ nsDOMWindowUtils::RunBeforeNextEvent(nsIRunnable *runnable)
|
||||
return appShell->RunBeforeNextEvent(runnable);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::RequestCompositorProperty(const nsAString& property,
|
||||
float* aResult)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
|
||||
|
||||
if (nsIWidget* widget = GetWidget()) {
|
||||
mozilla::layers::LayerManager* manager = widget->GetLayerManager();
|
||||
if (manager) {
|
||||
*aResult = manager->RequestProperty(property);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::GetOMTAStyle(nsIDOMElement* aElement,
|
||||
const nsAString& aProperty,
|
||||
|
@ -1125,10 +1125,7 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
|
||||
// Initialize the PRCList (this).
|
||||
PR_INIT_CLIST(this);
|
||||
|
||||
if (Preferences::GetBool("dom.window_experimental_bindings") ||
|
||||
!aOuterWindow) {
|
||||
SetIsDOMBinding();
|
||||
}
|
||||
SetIsDOMBinding();
|
||||
|
||||
if (aOuterWindow) {
|
||||
// |this| is an inner window, add this inner window to the outer
|
||||
@ -1640,20 +1637,12 @@ nsGlobalWindow::FreeInnerObjects()
|
||||
// nsGlobalWindow::nsISupports
|
||||
//*****************************************************************************
|
||||
|
||||
DOMCI_DATA(Window, nsGlobalWindow)
|
||||
|
||||
// QueryInterface implementation for nsGlobalWindow
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsGlobalWindow)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
// Make sure this matches the cast in nsGlobalWindow::FromWrapper()
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMEventTarget)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMWindow)
|
||||
#ifdef MOZ_B2G
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMWindowB2G)
|
||||
#endif // MOZ_B2G
|
||||
#ifdef MOZ_WEBSPEECH
|
||||
NS_INTERFACE_MAP_ENTRY(nsISpeechSynthesisGetter)
|
||||
#endif // MOZ_B2G
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMJSWindow)
|
||||
if (aIID.Equals(NS_GET_IID(nsIDOMWindowInternal))) {
|
||||
foundInterface = static_cast<nsIDOMWindowInternal*>(this);
|
||||
@ -1673,10 +1662,6 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsGlobalWindow)
|
||||
NS_INTERFACE_MAP_ENTRY(nsPIDOMWindow)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMWindowPerformance)
|
||||
NS_INTERFACE_MAP_ENTRY(nsITouchEventReceiver)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIInlineEventHandlers)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Window)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
|
||||
@ -2285,22 +2270,10 @@ CreateNativeGlobalForInner(JSContext* aCx,
|
||||
uint32_t flags = needComponents ? 0 : nsIXPConnect::OMIT_COMPONENTS_OBJECT;
|
||||
flags |= nsIXPConnect::DONT_FIRE_ONNEWGLOBALHOOK;
|
||||
|
||||
if (aNewInner->IsDOMBinding()) {
|
||||
aGlobal.set(WindowBinding::Wrap(aCx, aNewInner, aNewInner, options,
|
||||
nsJSPrincipals::get(aPrincipal), false));
|
||||
if (!aGlobal || !xpc::InitGlobalObject(aCx, aGlobal, flags)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
} else {
|
||||
nsIXPConnect* xpc = nsContentUtils::XPConnect();
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
|
||||
nsresult rv = xpc->InitClassesWithNewWrappedGlobal(
|
||||
aCx, ToSupports(aNewInner),
|
||||
aPrincipal, flags, options, getter_AddRefs(holder));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aGlobal.set(holder->GetJSObject());
|
||||
MOZ_ASSERT(aGlobal);
|
||||
aGlobal.set(WindowBinding::Wrap(aCx, aNewInner, aNewInner, options,
|
||||
nsJSPrincipals::get(aPrincipal), false));
|
||||
if (!aGlobal || !xpc::InitGlobalObject(aCx, aGlobal, flags)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aNewInner->GetWrapperPreserveColor() == aGlobal);
|
||||
@ -2403,8 +2376,8 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
|
||||
// having to *always* reach into the inner window to find the
|
||||
// document.
|
||||
mDoc = aDocument;
|
||||
if (IsInnerWindow() && IsDOMBinding()) {
|
||||
WindowBinding::ClearCachedDocumentValue(cx, this);
|
||||
if (IsInnerWindow()) {
|
||||
ClearDocumentDependentSlots(cx);
|
||||
}
|
||||
|
||||
// Take this opportunity to clear mSuspendedDoc. Our old inner window is now
|
||||
@ -2611,21 +2584,10 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
|
||||
// If we created a new inner window above, we need to do the last little bit
|
||||
// of initialization now that the dust has settled.
|
||||
if (createdInnerWindow) {
|
||||
if (newInnerWindow->IsDOMBinding()) {
|
||||
JS::Rooted<JSObject*> global(cx, newInnerGlobal);
|
||||
JS::Rooted<JSObject*> proto(cx);
|
||||
JS_GetPrototype(cx, global, &proto);
|
||||
WindowNamedPropertiesHandler::Install(cx, proto);
|
||||
} else {
|
||||
nsIXPConnect *xpc = nsContentUtils::XPConnect();
|
||||
nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
|
||||
nsresult rv = xpc->GetWrappedNativeOfJSObject(cx, newInnerGlobal,
|
||||
getter_AddRefs(wrapper));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ABORT_IF_FALSE(wrapper, "bad wrapper");
|
||||
rv = wrapper->FinishInitForWrappedGlobal();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
JS::Rooted<JSObject*> global(cx, newInnerGlobal);
|
||||
JS::Rooted<JSObject*> proto(cx);
|
||||
JS_GetPrototype(cx, global, &proto);
|
||||
WindowNamedPropertiesHandler::Install(cx, proto);
|
||||
}
|
||||
|
||||
if (!aState) {
|
||||
@ -2682,17 +2644,7 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
|
||||
newInnerWindow->mLocalStorage = nullptr;
|
||||
newInnerWindow->mSessionStorage = nullptr;
|
||||
|
||||
if (newInnerWindow->IsDOMBinding()) {
|
||||
WindowBinding::ClearCachedDocumentValue(cx, newInnerWindow);
|
||||
} else {
|
||||
// We're reusing the inner window for a new document. In this
|
||||
// case we don't clear the inner window's scope, but we must
|
||||
// make sure the cached document property gets updated.
|
||||
|
||||
JS::Rooted<JSObject*> obj(cx,
|
||||
currentInner->GetWrapperPreserveColor());
|
||||
::JS_DeleteProperty(cx, obj, "document");
|
||||
}
|
||||
newInnerWindow->ClearDocumentDependentSlots(cx);
|
||||
}
|
||||
} else {
|
||||
newInnerWindow->InnerSetNewDocument(cx, aDocument);
|
||||
@ -2834,9 +2786,7 @@ nsGlobalWindow::InnerSetNewDocument(JSContext* aCx, nsIDocument* aDocument)
|
||||
#endif
|
||||
|
||||
mDoc = aDocument;
|
||||
if (IsDOMBinding()) {
|
||||
WindowBinding::ClearCachedDocumentValue(aCx, this);
|
||||
}
|
||||
ClearDocumentDependentSlots(aCx);
|
||||
mFocusedNode = nullptr;
|
||||
mLocalStorage = nullptr;
|
||||
mSessionStorage = nullptr;
|
||||
@ -3644,25 +3594,11 @@ nsGlobalWindow::GetHistory(nsISupports** aHistory)
|
||||
}
|
||||
|
||||
nsPerformance*
|
||||
nsGlobalWindow::GetPerformance(ErrorResult& aError)
|
||||
nsGlobalWindow::GetPerformance()
|
||||
{
|
||||
FORWARD_TO_INNER_OR_THROW(GetPerformance, (aError), aError, nullptr);
|
||||
FORWARD_TO_INNER(GetPerformance, (), nullptr);
|
||||
|
||||
nsPerformance* p = nsPIDOMWindow::GetPerformance();
|
||||
if (!p) {
|
||||
aError.Throw(NS_ERROR_FAILURE);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalWindow::GetPerformance(nsISupports** aPerformance)
|
||||
{
|
||||
ErrorResult rv;
|
||||
nsCOMPtr<nsISupports> performance = GetPerformance(rv);
|
||||
performance.forget(aPerformance);
|
||||
|
||||
return rv.ErrorCode();
|
||||
return nsPIDOMWindow::GetPerformance();
|
||||
}
|
||||
|
||||
nsPerformance*
|
||||
@ -3830,19 +3766,6 @@ nsGlobalWindow::GetSpeechSynthesis(ErrorResult& aError)
|
||||
|
||||
return mSpeechSynthesis;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalWindow::GetSpeechSynthesis(nsISupports** aSpeechSynthesis)
|
||||
{
|
||||
ErrorResult rv;
|
||||
nsCOMPtr<nsISupports> speechSynthesis;
|
||||
if (Preferences::GetBool("media.webspeech.synth.enabled")) {
|
||||
speechSynthesis = GetSpeechSynthesis(rv);
|
||||
}
|
||||
speechSynthesis.forget(aSpeechSynthesis);
|
||||
|
||||
return rv.ErrorCode();
|
||||
}
|
||||
#endif
|
||||
|
||||
already_AddRefed<nsIDOMWindow>
|
||||
@ -13409,12 +13332,9 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsGlobalChromeWindow,
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mGroupMessageManagers)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
DOMCI_DATA(ChromeWindow, nsGlobalChromeWindow)
|
||||
|
||||
// QueryInterface implementation for nsGlobalChromeWindow
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsGlobalChromeWindow)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMChromeWindow)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(ChromeWindow)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsGlobalWindow)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsGlobalChromeWindow, nsGlobalWindow)
|
||||
@ -13811,11 +13731,8 @@ nsGlobalWindow::GetGroupMessageManager(const nsAString& aGroup,
|
||||
// nsGlobalModalWindow implementation
|
||||
|
||||
// QueryInterface implementation for nsGlobalModalWindow
|
||||
DOMCI_DATA(ModalContentWindow, nsGlobalModalWindow)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsGlobalModalWindow)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMModalContentWindow)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(ModalContentWindow)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsGlobalWindow)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsGlobalModalWindow, nsGlobalWindow)
|
||||
@ -13928,7 +13845,6 @@ nsGlobalModalWindow::SetReturnValue(nsIVariant *aRetVal)
|
||||
bool
|
||||
nsGlobalWindow::IsModalContentWindow(JSContext* aCx, JSObject* aGlobal)
|
||||
{
|
||||
// For now, have to deal with XPConnect objects here.
|
||||
return xpc::WindowOrNull(aGlobal)->IsModalContentWindow();
|
||||
}
|
||||
|
||||
@ -14027,15 +13943,13 @@ nsGlobalWindow::GetSidebar(OwningExternalOrWindowProxy& aResult,
|
||||
#endif
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool
|
||||
nsGlobalWindow::WindowOnWebIDL(JSContext* aCx, JSObject* aObj)
|
||||
void
|
||||
nsGlobalWindow::ClearDocumentDependentSlots(JSContext* aCx)
|
||||
{
|
||||
DebugOnly<nsGlobalWindow*> win;
|
||||
MOZ_ASSERT_IF(IsDOMObject(aObj),
|
||||
NS_SUCCEEDED(UNWRAP_OBJECT(Window, aObj, win)));
|
||||
|
||||
return IsDOMObject(aObj);
|
||||
MOZ_ASSERT(IsInnerWindow());
|
||||
MOZ_ASSERT(IsDOMBinding());
|
||||
WindowBinding::ClearCachedDocumentValue(aCx, this);
|
||||
WindowBinding::ClearCachedPerformanceValue(aCx, this);
|
||||
}
|
||||
|
||||
#ifdef MOZ_B2G
|
||||
@ -14108,94 +14022,6 @@ nsGlobalWindow::DisableNetworkEvent(uint32_t aType)
|
||||
}
|
||||
#endif // MOZ_B2G
|
||||
|
||||
#define EVENT(name_, id_, type_, struct_) \
|
||||
NS_IMETHODIMP nsGlobalWindow::GetOn##name_(JSContext *cx, \
|
||||
JS::MutableHandle<JS::Value> vp) { \
|
||||
EventHandlerNonNull* h = GetOn##name_(); \
|
||||
vp.setObjectOrNull(h ? h->Callable().get() : nullptr); \
|
||||
return NS_OK; \
|
||||
} \
|
||||
NS_IMETHODIMP nsGlobalWindow::SetOn##name_(JSContext *cx, \
|
||||
JS::Handle<JS::Value> v) { \
|
||||
nsRefPtr<EventHandlerNonNull> handler; \
|
||||
JS::Rooted<JSObject*> callable(cx); \
|
||||
if (v.isObject() && \
|
||||
JS_ObjectIsCallable(cx, callable = &v.toObject())) { \
|
||||
handler = new EventHandlerNonNull(callable, GetIncumbentGlobal()); \
|
||||
} \
|
||||
SetOn##name_(handler); \
|
||||
return NS_OK; \
|
||||
}
|
||||
#define ERROR_EVENT(name_, id_, type_, struct_) \
|
||||
NS_IMETHODIMP nsGlobalWindow::GetOn##name_(JSContext *cx, \
|
||||
JS::MutableHandle<JS::Value> vp) { \
|
||||
EventListenerManager *elm = GetExistingListenerManager(); \
|
||||
if (elm) { \
|
||||
OnErrorEventHandlerNonNull* h = elm->GetOnErrorEventHandler(); \
|
||||
if (h) { \
|
||||
vp.setObject(*h->Callable()); \
|
||||
return NS_OK; \
|
||||
} \
|
||||
} \
|
||||
vp.setNull(); \
|
||||
return NS_OK; \
|
||||
} \
|
||||
NS_IMETHODIMP nsGlobalWindow::SetOn##name_(JSContext *cx, \
|
||||
JS::Handle<JS::Value> v) { \
|
||||
EventListenerManager *elm = GetOrCreateListenerManager(); \
|
||||
if (!elm) { \
|
||||
return NS_ERROR_OUT_OF_MEMORY; \
|
||||
} \
|
||||
\
|
||||
nsRefPtr<OnErrorEventHandlerNonNull> handler; \
|
||||
JS::Rooted<JSObject*> callable(cx); \
|
||||
if (v.isObject() && \
|
||||
JS_ObjectIsCallable(cx, callable = &v.toObject())) { \
|
||||
handler = new OnErrorEventHandlerNonNull(callable, GetIncumbentGlobal()); \
|
||||
} \
|
||||
elm->SetEventHandler(handler); \
|
||||
return NS_OK; \
|
||||
}
|
||||
#define BEFOREUNLOAD_EVENT(name_, id_, type_, struct_) \
|
||||
NS_IMETHODIMP nsGlobalWindow::GetOn##name_(JSContext *cx, \
|
||||
JS::MutableHandle<JS::Value> vp) { \
|
||||
EventListenerManager *elm = GetExistingListenerManager(); \
|
||||
if (elm) { \
|
||||
OnBeforeUnloadEventHandlerNonNull* h = \
|
||||
elm->GetOnBeforeUnloadEventHandler(); \
|
||||
if (h) { \
|
||||
vp.setObject(*h->Callable()); \
|
||||
return NS_OK; \
|
||||
} \
|
||||
} \
|
||||
vp.setNull(); \
|
||||
return NS_OK; \
|
||||
} \
|
||||
NS_IMETHODIMP nsGlobalWindow::SetOn##name_(JSContext *cx, \
|
||||
JS::Handle<JS::Value> v) { \
|
||||
EventListenerManager *elm = GetOrCreateListenerManager(); \
|
||||
if (!elm) { \
|
||||
return NS_ERROR_OUT_OF_MEMORY; \
|
||||
} \
|
||||
\
|
||||
nsRefPtr<OnBeforeUnloadEventHandlerNonNull> handler; \
|
||||
JS::Rooted<JSObject*> callable(cx); \
|
||||
if (v.isObject() && \
|
||||
JS_ObjectIsCallable(cx, callable = &v.toObject())) { \
|
||||
handler = new OnBeforeUnloadEventHandlerNonNull(callable, GetIncumbentGlobal()); \
|
||||
} \
|
||||
elm->SetEventHandler(handler); \
|
||||
return NS_OK; \
|
||||
}
|
||||
#define WINDOW_ONLY_EVENT EVENT
|
||||
#define TOUCH_EVENT EVENT
|
||||
#include "mozilla/EventNameList.h"
|
||||
#undef TOUCH_EVENT
|
||||
#undef WINDOW_ONLY_EVENT
|
||||
#undef BEFOREUNLOAD_EVENT
|
||||
#undef ERROR_EVENT
|
||||
#undef EVENT
|
||||
|
||||
#ifdef _WINDOWS_
|
||||
#error "Never include windows.h in this file!"
|
||||
#endif
|
||||
|
@ -43,24 +43,14 @@
|
||||
#include "nsFrameMessageManager.h"
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "nsIInlineEventHandlers.h"
|
||||
#include "nsWrapperCacheInlines.h"
|
||||
#include "nsIIdleObserver.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMTouchEvent.h"
|
||||
#include "mozilla/dom/EventTarget.h"
|
||||
#include "mozilla/dom/WindowBinding.h"
|
||||
#include "Units.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
|
||||
#ifdef MOZ_B2G
|
||||
#include "nsIDOMWindowB2G.h"
|
||||
#endif // MOZ_B2G
|
||||
|
||||
#ifdef MOZ_WEBSPEECH
|
||||
#include "nsISpeechSynthesisGetter.h"
|
||||
#endif // MOZ_WEBSPEECH
|
||||
|
||||
#define DEFAULT_HOME_PAGE "www.mozilla.org"
|
||||
#define PREF_BROWSER_STARTUP_HOMEPAGE "browser.startup.homepage"
|
||||
|
||||
@ -329,16 +319,7 @@ class nsGlobalWindow : public mozilla::dom::EventTarget,
|
||||
public nsIDOMJSWindow,
|
||||
public nsSupportsWeakReference,
|
||||
public nsIInterfaceRequestor,
|
||||
public PRCListStr,
|
||||
public nsIDOMWindowPerformance,
|
||||
public nsITouchEventReceiver,
|
||||
public nsIInlineEventHandlers
|
||||
#ifdef MOZ_B2G
|
||||
, public nsIDOMWindowB2G
|
||||
#endif // MOZ_B2G
|
||||
#ifdef MOZ_WEBSPEECH
|
||||
, public nsISpeechSynthesisGetter
|
||||
#endif // MOZ_WEBSPEECH
|
||||
public PRCListStr
|
||||
{
|
||||
public:
|
||||
typedef mozilla::TimeStamp TimeStamp;
|
||||
@ -387,19 +368,6 @@ public:
|
||||
// nsIDOMWindow
|
||||
NS_DECL_NSIDOMWINDOW
|
||||
|
||||
#ifdef MOZ_B2G
|
||||
// nsIDOMWindowB2G
|
||||
NS_DECL_NSIDOMWINDOWB2G
|
||||
#endif // MOZ_B2G
|
||||
|
||||
#ifdef MOZ_WEBSPEECH
|
||||
// nsISpeechSynthesisGetter
|
||||
NS_DECL_NSISPEECHSYNTHESISGETTER
|
||||
#endif // MOZ_WEBSPEECH
|
||||
|
||||
// nsIDOMWindowPerformance
|
||||
NS_DECL_NSIDOMWINDOWPERFORMANCE
|
||||
|
||||
// nsIDOMJSWindow
|
||||
NS_DECL_NSIDOMJSWINDOW
|
||||
|
||||
@ -427,12 +395,6 @@ public:
|
||||
return GetOuterFromCurrentInner(this);
|
||||
}
|
||||
|
||||
// nsITouchEventReceiver
|
||||
NS_DECL_NSITOUCHEVENTRECEIVER
|
||||
|
||||
// nsIInlineEventHandlers
|
||||
NS_DECL_NSIINLINEEVENTHANDLERS
|
||||
|
||||
// nsPIDOMWindow
|
||||
virtual nsPIDOMWindow* GetPrivateRoot();
|
||||
|
||||
@ -823,8 +785,6 @@ public:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static bool WindowOnWebIDL(JSContext* /* unused */, JSObject* aObj);
|
||||
|
||||
nsIDOMWindow* GetWindow(mozilla::ErrorResult& aError);
|
||||
nsIDOMWindow* GetSelf(mozilla::ErrorResult& aError);
|
||||
nsIDocument* GetDocument()
|
||||
@ -973,7 +933,7 @@ public:
|
||||
int32_t RequestAnimationFrame(mozilla::dom::FrameRequestCallback& aCallback,
|
||||
mozilla::ErrorResult& aError);
|
||||
void CancelAnimationFrame(int32_t aHandle, mozilla::ErrorResult& aError);
|
||||
nsPerformance* GetPerformance(mozilla::ErrorResult& aError);
|
||||
nsPerformance* GetPerformance();
|
||||
#ifdef MOZ_WEBSPEECH
|
||||
mozilla::dom::SpeechSynthesis*
|
||||
GetSpeechSynthesis(mozilla::ErrorResult& aError);
|
||||
@ -1399,6 +1359,8 @@ protected:
|
||||
|
||||
inline int32_t DOMMinTimeoutValue() const;
|
||||
|
||||
// Clear the document-dependent slots on our JS wrapper. Inner windows only.
|
||||
void ClearDocumentDependentSlots(JSContext* aCx);
|
||||
|
||||
// Inner windows only.
|
||||
already_AddRefed<mozilla::dom::StorageEvent>
|
||||
|
@ -1596,7 +1596,6 @@ DOMInterfaces = {
|
||||
|
||||
'Window': {
|
||||
'nativeType': 'nsGlobalWindow',
|
||||
'hasXPConnectImpls': True,
|
||||
'binaryNames': {
|
||||
'postMessage': 'postMessageMoz',
|
||||
},
|
||||
|
@ -2956,12 +2956,6 @@ def CreateBindingJSObject(descriptor, properties, parent):
|
||||
js::SetReservedSlot(obj, DOM_OBJECT_SLOT, PRIVATE_TO_JSVAL(aObject));
|
||||
""",
|
||||
parent=parent)
|
||||
if "Window" in descriptor.interface.identifier.name:
|
||||
create = dedent("""
|
||||
MOZ_ASSERT(false,
|
||||
"Our current reserved slot situation is unsafe for globals. Fix "
|
||||
"bug 760095!");
|
||||
""") + create
|
||||
create = objDecl + create
|
||||
|
||||
if descriptor.nativeOwnership == 'refcounted':
|
||||
@ -5287,7 +5281,7 @@ class CGArgumentConverter(CGThing):
|
||||
"args.hasDefined(${index})").substitute(replacer)
|
||||
self.replacementVariables["haveValue"] = haveValueCheck
|
||||
self.descriptorProvider = descriptorProvider
|
||||
if self.argument.optional and not self.argument.defaultValue:
|
||||
if self.argument.canHaveMissingValue():
|
||||
self.argcAndIndex = replacer
|
||||
else:
|
||||
self.argcAndIndex = None
|
||||
@ -6130,10 +6124,9 @@ class CGCallGenerator(CGThing):
|
||||
return True
|
||||
if a.type.isString():
|
||||
return True
|
||||
if a.optional and not a.defaultValue:
|
||||
# If a.defaultValue, then it's not going to use an Optional,
|
||||
# so doesn't need to be const just due to being optional.
|
||||
# This also covers variadic arguments.
|
||||
if a.canHaveMissingValue():
|
||||
# This will need an Optional or it's a variadic;
|
||||
# in both cases it should be const.
|
||||
return True
|
||||
if a.type.isUnion():
|
||||
return True
|
||||
@ -6350,7 +6343,7 @@ def wrapArgIntoCurrentCompartment(arg, value, isMember=True):
|
||||
As wrapTypeIntoCurrentCompartment but handles things being optional
|
||||
"""
|
||||
origValue = value
|
||||
isOptional = arg.optional and not arg.defaultValue
|
||||
isOptional = arg.canHaveMissingValue()
|
||||
if isOptional:
|
||||
value = value + ".Value()"
|
||||
wrap = wrapTypeIntoCurrentCompartment(arg.type, value, isMember)
|
||||
@ -6857,8 +6850,7 @@ class CGMethodCall(CGThing):
|
||||
# enough that we can examine this argument. But note that we
|
||||
# still want to claim that optional arguments are optional, in
|
||||
# case undefined was passed in.
|
||||
argIsOptional = (distinguishingArgument(signature).optional and
|
||||
not distinguishingArgument(signature).defaultValue)
|
||||
argIsOptional = distinguishingArgument(signature).canHaveMissingValue()
|
||||
testCode = instantiateJSToNativeConversion(
|
||||
getJSToNativeConversionInfo(type, descriptor,
|
||||
failureCode=failureCode,
|
||||
@ -7144,6 +7136,9 @@ class FakeArgument():
|
||||
def allowTreatNonCallableAsNull(self):
|
||||
return self._allowTreatNonCallableAsNull
|
||||
|
||||
def canHaveMissingValue(self):
|
||||
return False
|
||||
|
||||
|
||||
class CGSetterCall(CGPerSignatureCall):
|
||||
"""
|
||||
@ -7675,9 +7670,7 @@ class CGSpecializedGetter(CGAbstractStaticMethod):
|
||||
nativeName = CGSpecializedGetter.makeNativeName(self.descriptor,
|
||||
self.attr)
|
||||
if self.attr.slotIndex is not None:
|
||||
if (self.descriptor.hasXPConnectImpls and
|
||||
(self.descriptor.interface.identifier.name != 'Window' or
|
||||
self.attr.identifier.name != 'document')):
|
||||
if self.descriptor.hasXPConnectImpls:
|
||||
raise TypeError("Interface '%s' has XPConnect impls, so we "
|
||||
"can't use our slot for property '%s'!" %
|
||||
(self.descriptor.interface.identifier.name,
|
||||
@ -11119,10 +11112,9 @@ class CGDictionary(CGThing):
|
||||
isEnforceRange=member.enforceRange,
|
||||
isClamp=member.clamp,
|
||||
isMember="Dictionary",
|
||||
isOptional=(not member.defaultValue),
|
||||
isOptional=member.canHaveMissingValue(),
|
||||
defaultValue=member.defaultValue,
|
||||
sourceDescription=("'%s' member of %s" %
|
||||
(member.identifier.name, dictionary.identifier.name))))
|
||||
sourceDescription=self.getMemberSourceDescription(member)))
|
||||
for member in dictionary.members]
|
||||
|
||||
# If we have a union member containing something in the same
|
||||
@ -11322,7 +11314,7 @@ class CGDictionary(CGThing):
|
||||
self.makeClassName(self.dictionary.parent)))
|
||||
for m, _ in self.memberInfo:
|
||||
memberName = self.makeMemberName(m.identifier.name)
|
||||
if not m.defaultValue:
|
||||
if m.canHaveMissingValue():
|
||||
memberAssign = CGGeneric(fill(
|
||||
"""
|
||||
if (aOther.${name}.WasPassed()) {
|
||||
@ -11476,6 +11468,19 @@ class CGDictionary(CGThing):
|
||||
"}\n")
|
||||
if member.defaultValue:
|
||||
conversion += "${convert}"
|
||||
elif not conversionInfo.dealWithOptional:
|
||||
# We're required, but have no default value. Make sure
|
||||
# that we throw if we have no value provided.
|
||||
conversion += dedent(
|
||||
"""
|
||||
// Skip the undefined check if we have no cx. In that
|
||||
// situation the caller is default-constructing us and we'll
|
||||
// just assume they know what they're doing.
|
||||
if (cx && (isNull || temp->isUndefined())) {
|
||||
return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
|
||||
"%s");
|
||||
}
|
||||
${convert}""" % self.getMemberSourceDescription(member))
|
||||
else:
|
||||
conversion += (
|
||||
"if (!isNull && !temp->isUndefined()) {\n"
|
||||
@ -11491,7 +11496,7 @@ class CGDictionary(CGThing):
|
||||
member = memberInfo[0]
|
||||
declType = memberInfo[1].declType
|
||||
memberLoc = self.makeMemberName(member.identifier.name)
|
||||
if member.defaultValue:
|
||||
if not member.canHaveMissingValue():
|
||||
memberData = memberLoc
|
||||
else:
|
||||
# The data is inside the Optional<>
|
||||
@ -11547,7 +11552,7 @@ class CGDictionary(CGThing):
|
||||
pre=("do {\n"
|
||||
" // block for our 'break' successCode and scope for 'temp' and 'currentValue'\n"),
|
||||
post="} while(0);\n")
|
||||
if not member.defaultValue:
|
||||
if member.canHaveMissingValue():
|
||||
# Only do the conversion if we have a value
|
||||
conversion = CGIfWrapper(conversion, "%s.WasPassed()" % memberLoc)
|
||||
return conversion
|
||||
@ -11556,7 +11561,7 @@ class CGDictionary(CGThing):
|
||||
type = member.type
|
||||
assert typeNeedsRooting(type)
|
||||
memberLoc = self.makeMemberName(member.identifier.name)
|
||||
if member.defaultValue:
|
||||
if not member.canHaveMissingValue():
|
||||
memberData = memberLoc
|
||||
else:
|
||||
# The data is inside the Optional<>
|
||||
@ -11597,7 +11602,7 @@ class CGDictionary(CGThing):
|
||||
else:
|
||||
assert False # unknown type
|
||||
|
||||
if not member.defaultValue:
|
||||
if member.canHaveMissingValue():
|
||||
trace = CGIfWrapper(trace, "%s.WasPassed()" % memberLoc)
|
||||
|
||||
return trace.define()
|
||||
@ -11609,8 +11614,8 @@ class CGDictionary(CGThing):
|
||||
value, so they're safe to trace at all times.
|
||||
"""
|
||||
member, _ = memberInfo
|
||||
if not member.defaultValue:
|
||||
# No default value means no need to set it up front, since it's
|
||||
if member.canHaveMissingValue():
|
||||
# Allowed missing value means no need to set it up front, since it's
|
||||
# inside an Optional and won't get traced until it's actually set
|
||||
# up.
|
||||
return None
|
||||
@ -11621,6 +11626,10 @@ class CGDictionary(CGThing):
|
||||
return "nullptr"
|
||||
return None
|
||||
|
||||
def getMemberSourceDescription(self, member):
|
||||
return ("'%s' member of %s" %
|
||||
(member.identifier.name, self.dictionary.identifier.name))
|
||||
|
||||
@staticmethod
|
||||
def makeIdName(name):
|
||||
return name.replace("-", "_") + "_id"
|
||||
@ -12526,8 +12535,7 @@ class CGNativeMember(ClassMethod):
|
||||
"""
|
||||
Get the full argument declaration for an argument
|
||||
"""
|
||||
decl, ref = self.getArgType(arg.type,
|
||||
arg.optional and not arg.defaultValue,
|
||||
decl, ref = self.getArgType(arg.type, arg.canHaveMissingValue(),
|
||||
"Variadic" if arg.variadic else False)
|
||||
if ref:
|
||||
decl = CGWrapper(decl, pre="const ", post="&")
|
||||
@ -13606,7 +13614,7 @@ class CallbackMember(CGNativeMember):
|
||||
jsvalIndex = "%d + idx" % i
|
||||
else:
|
||||
jsvalIndex = "%d" % i
|
||||
if arg.optional and not arg.defaultValue:
|
||||
if arg.canHaveMissingValue():
|
||||
argval += ".Value()"
|
||||
if arg.type.isDOMString():
|
||||
# XPConnect string-to-JS conversion wants to mutate the string. So
|
||||
@ -13649,7 +13657,7 @@ class CallbackMember(CGNativeMember):
|
||||
""",
|
||||
arg=arg.identifier.name,
|
||||
conversion=conversion)
|
||||
elif arg.optional and not arg.defaultValue:
|
||||
elif arg.canHaveMissingValue():
|
||||
conversion = fill(
|
||||
"""
|
||||
if (${argName}.WasPassed()) {
|
||||
@ -14383,7 +14391,7 @@ class CGEventMethod(CGNativeMember):
|
||||
|
||||
def getArg(self, arg):
|
||||
decl, ref = self.getArgType(arg.type,
|
||||
arg.optional and not arg.defaultValue,
|
||||
arg.canHaveMissingValue(),
|
||||
"Variadic" if arg.variadic else False)
|
||||
if ref:
|
||||
decl = CGWrapper(decl, pre="const ", post="&")
|
||||
|
@ -59,3 +59,4 @@ MSG_DEF(MSG_INVALID_HEADER_NAME, 1, "{0} is an invalid header name.")
|
||||
MSG_DEF(MSG_INVALID_HEADER_VALUE, 1, "{0} is an invalid header value.")
|
||||
MSG_DEF(MSG_INVALID_HEADER_SEQUENCE, 0, "Headers require name/value tuples when being initialized by a sequence.")
|
||||
MSG_DEF(MSG_PERMISSION_DENIED_TO_PASS_ARG, 1, "Permission denied to pass cross-origin object as {0}.")
|
||||
MSG_DEF(MSG_MISSING_REQUIRED_DICTIONARY_MEMBER, 1, "Missing required {0}.")
|
||||
|
@ -2,11 +2,6 @@
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
|
||||
/*
|
||||
user_pref("dom.window_experimental_bindings", true);
|
||||
*/
|
||||
|
||||
function boom()
|
||||
{
|
||||
window.__proto__ = null;
|
||||
|
@ -2,11 +2,6 @@
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
|
||||
/*
|
||||
user_pref("dom.window_experimental_bindings", true);
|
||||
*/
|
||||
|
||||
function boom()
|
||||
{
|
||||
window.__proto__ = function(){};
|
||||
|
@ -3474,6 +3474,9 @@ class IDLArgument(IDLObjectWithIdentifier):
|
||||
deps.add(self.defaultValue)
|
||||
return deps
|
||||
|
||||
def canHaveMissingValue(self):
|
||||
return self.optional and not self.defaultValue
|
||||
|
||||
class IDLCallbackType(IDLType, IDLObjectWithScope):
|
||||
def __init__(self, location, parentScope, identifier, returnType, arguments):
|
||||
assert isinstance(returnType, IDLType)
|
||||
@ -4141,8 +4144,8 @@ class Tokenizer(object):
|
||||
"long": "LONG",
|
||||
"object": "OBJECT",
|
||||
"octet": "OCTET",
|
||||
"optional": "OPTIONAL",
|
||||
"Promise": "PROMISE",
|
||||
"required": "REQUIRED",
|
||||
"sequence": "SEQUENCE",
|
||||
"MozMap": "MOZMAP",
|
||||
"short": "SHORT",
|
||||
@ -4427,15 +4430,21 @@ class Parser(Tokenizer):
|
||||
|
||||
def p_DictionaryMember(self, p):
|
||||
"""
|
||||
DictionaryMember : Type IDENTIFIER Default SEMICOLON
|
||||
DictionaryMember : Required Type IDENTIFIER Default SEMICOLON
|
||||
"""
|
||||
# These quack a lot like optional arguments, so just treat them that way.
|
||||
t = p[1]
|
||||
t = p[2]
|
||||
assert isinstance(t, IDLType)
|
||||
identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2])
|
||||
defaultValue = p[3]
|
||||
identifier = IDLUnresolvedIdentifier(self.getLocation(p, 3), p[3])
|
||||
defaultValue = p[4]
|
||||
optional = not p[1]
|
||||
|
||||
p[0] = IDLArgument(self.getLocation(p, 2), identifier, t, optional=True,
|
||||
if not optional and defaultValue:
|
||||
raise WebIDLError("Required dictionary members can't have a default value.",
|
||||
[self.getLocation(p, 4)])
|
||||
|
||||
p[0] = IDLArgument(self.getLocation(p, 3), identifier, t,
|
||||
optional=optional,
|
||||
defaultValue=defaultValue, variadic=False,
|
||||
dictionaryMember=True)
|
||||
|
||||
@ -4633,7 +4642,7 @@ class Parser(Tokenizer):
|
||||
|
||||
def p_AttributeRest(self, p):
|
||||
"""
|
||||
AttributeRest : ReadOnly ATTRIBUTE Type IDENTIFIER SEMICOLON
|
||||
AttributeRest : ReadOnly ATTRIBUTE Type AttributeName SEMICOLON
|
||||
"""
|
||||
location = self.getLocation(p, 2)
|
||||
readonly = p[1]
|
||||
@ -4962,6 +4971,7 @@ class Parser(Tokenizer):
|
||||
| INTERFACE
|
||||
| LEGACYCALLER
|
||||
| PARTIAL
|
||||
| REQUIRED
|
||||
| SERIALIZER
|
||||
| SETTER
|
||||
| STATIC
|
||||
@ -4972,6 +4982,13 @@ class Parser(Tokenizer):
|
||||
"""
|
||||
p[0] = p[1]
|
||||
|
||||
def p_AttributeName(self, p):
|
||||
"""
|
||||
AttributeName : IDENTIFIER
|
||||
| REQUIRED
|
||||
"""
|
||||
p[0] = p[1]
|
||||
|
||||
def p_Optional(self, p):
|
||||
"""
|
||||
Optional : OPTIONAL
|
||||
@ -4984,6 +5001,18 @@ class Parser(Tokenizer):
|
||||
"""
|
||||
p[0] = False
|
||||
|
||||
def p_Required(self, p):
|
||||
"""
|
||||
Required : REQUIRED
|
||||
"""
|
||||
p[0] = True
|
||||
|
||||
def p_RequiredEmpty(self, p):
|
||||
"""
|
||||
Required :
|
||||
"""
|
||||
p[0] = False
|
||||
|
||||
def p_Ellipsis(self, p):
|
||||
"""
|
||||
Ellipsis : ELLIPSIS
|
||||
|
@ -951,6 +951,9 @@ dictionary Dict : ParentDict {
|
||||
sequence<long>? seq5 = [];
|
||||
|
||||
long dashed-name;
|
||||
|
||||
required long requiredLong;
|
||||
required object requiredObject;
|
||||
};
|
||||
|
||||
dictionary ParentDict : GrandparentDict {
|
||||
|
@ -3496,22 +3496,6 @@ CanvasRenderingContext2D::DrawDirectlyToCanvas(
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
}
|
||||
|
||||
static bool
|
||||
IsStandardCompositeOp(CompositionOp op)
|
||||
{
|
||||
return (op == CompositionOp::OP_SOURCE ||
|
||||
op == CompositionOp::OP_ATOP ||
|
||||
op == CompositionOp::OP_IN ||
|
||||
op == CompositionOp::OP_OUT ||
|
||||
op == CompositionOp::OP_OVER ||
|
||||
op == CompositionOp::OP_DEST_IN ||
|
||||
op == CompositionOp::OP_DEST_OUT ||
|
||||
op == CompositionOp::OP_DEST_OVER ||
|
||||
op == CompositionOp::OP_DEST_ATOP ||
|
||||
op == CompositionOp::OP_ADD ||
|
||||
op == CompositionOp::OP_XOR);
|
||||
}
|
||||
|
||||
void
|
||||
CanvasRenderingContext2D::SetGlobalCompositeOperation(const nsAString& op,
|
||||
ErrorResult& error)
|
||||
@ -3551,10 +3535,6 @@ CanvasRenderingContext2D::SetGlobalCompositeOperation(const nsAString& op,
|
||||
// XXX ERRMSG we need to report an error to developers here! (bug 329026)
|
||||
else return;
|
||||
|
||||
if (!IsStandardCompositeOp(comp_op)) {
|
||||
Demote();
|
||||
}
|
||||
|
||||
#undef CANVAS_OP_TO_GFX_OP
|
||||
CurrentState().op = comp_op;
|
||||
}
|
||||
@ -3599,10 +3579,6 @@ CanvasRenderingContext2D::GetGlobalCompositeOperation(nsAString& op,
|
||||
error.Throw(NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
if (!IsStandardCompositeOp(comp_op)) {
|
||||
Demote();
|
||||
}
|
||||
|
||||
#undef CANVAS_OP_TO_GFX_OP
|
||||
}
|
||||
|
||||
|
@ -38,15 +38,5 @@ XPIDL_SOURCES += [
|
||||
'nsITabParent.idl',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_B2G']:
|
||||
XPIDL_SOURCES += [
|
||||
'nsIDOMWindowB2G.idl',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WEBSPEECH']:
|
||||
XPIDL_SOURCES += [
|
||||
'nsISpeechSynthesisGetter.idl'
|
||||
]
|
||||
|
||||
XPIDL_MODULE = 'dom_base'
|
||||
|
||||
|
@ -23,7 +23,7 @@ interface nsIVariant;
|
||||
* @see <http://www.whatwg.org/html/#window>
|
||||
*/
|
||||
|
||||
[scriptable, uuid(ed7cc4e4-cf5b-42af-9c2e-8df074a01470)]
|
||||
[scriptable, uuid(3addc629-754d-4a2a-99a3-449ed1a2e4bd)]
|
||||
interface nsIDOMWindow : nsISupports
|
||||
{
|
||||
// the current browsing context
|
||||
@ -478,56 +478,12 @@ interface nsIDOMWindow : nsISupports
|
||||
*/
|
||||
readonly attribute long long mozAnimationStartTime;
|
||||
|
||||
/**
|
||||
* HTML5 event attributes that only apply to windows and <body>/<frameset>
|
||||
*/
|
||||
[implicit_jscontext] attribute jsval onafterprint;
|
||||
[implicit_jscontext] attribute jsval onbeforeprint;
|
||||
[implicit_jscontext] attribute jsval onbeforeunload;
|
||||
[implicit_jscontext] attribute jsval onhashchange;
|
||||
[implicit_jscontext] attribute jsval onlanguagechange;
|
||||
[implicit_jscontext] attribute jsval onmessage;
|
||||
[implicit_jscontext] attribute jsval onoffline;
|
||||
[implicit_jscontext] attribute jsval ononline;
|
||||
[implicit_jscontext] attribute jsval onpopstate;
|
||||
[implicit_jscontext] attribute jsval onpagehide;
|
||||
[implicit_jscontext] attribute jsval onpageshow;
|
||||
// Not supported yet
|
||||
// [implicit_jscontext] attribute jsval onredo;
|
||||
[implicit_jscontext] attribute jsval onresize;
|
||||
// Not supported yet
|
||||
// [implicit_jscontext] attribute jsval onstorage;
|
||||
// Not supported yet
|
||||
// [implicit_jscontext] attribute jsval onundo;
|
||||
[implicit_jscontext] attribute jsval onunload;
|
||||
|
||||
/**
|
||||
* Non-HTML5 window-specific event attributes
|
||||
*/
|
||||
[implicit_jscontext] attribute jsval ondevicemotion;
|
||||
[implicit_jscontext] attribute jsval ondeviceorientation;
|
||||
[implicit_jscontext] attribute jsval ondeviceproximity;
|
||||
[implicit_jscontext] attribute jsval onuserproximity;
|
||||
[implicit_jscontext] attribute jsval ondevicelight;
|
||||
|
||||
[implicit_jscontext] attribute jsval onmouseenter;
|
||||
[implicit_jscontext] attribute jsval onmouseleave;
|
||||
|
||||
/**
|
||||
* Console API
|
||||
*/
|
||||
[implicit_jscontext] attribute jsval console;
|
||||
};
|
||||
|
||||
[scriptable, uuid(2146c906-57f7-486c-a1b4-8cdb57ef577f)]
|
||||
interface nsIDOMWindowPerformance : nsISupports
|
||||
{
|
||||
/**
|
||||
* A namespace to hold performance related data and statistics.
|
||||
*/
|
||||
readonly attribute nsISupports performance;
|
||||
};
|
||||
|
||||
/**
|
||||
* Empty interface for compatibility with older versions.
|
||||
* @deprecated Use nsIDOMWindow instead
|
||||
|
@ -1,14 +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/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[scriptable, uuid(96bde2ae-9b74-4f4d-b674-664a67a35b7e)]
|
||||
interface nsIDOMWindowB2G : nsISupports
|
||||
{
|
||||
[implicit_jscontext] attribute jsval onmoztimechange;
|
||||
[implicit_jscontext] attribute jsval onmoznetworkupload;
|
||||
[implicit_jscontext] attribute jsval onmoznetworkdownload;
|
||||
};
|
@ -51,7 +51,7 @@ interface nsITranslationNodeList;
|
||||
interface nsIJSRAIIHelper;
|
||||
interface nsIContentPermissionRequest;
|
||||
|
||||
[scriptable, uuid(11911980-607c-4efd-aacc-de3b9005c058)]
|
||||
[scriptable, uuid(669095d8-1b96-472f-a48d-022adde26cfd)]
|
||||
interface nsIDOMWindowUtils : nsISupports {
|
||||
|
||||
/**
|
||||
@ -1673,6 +1673,18 @@ interface nsIDOMWindowUtils : nsISupports {
|
||||
*/
|
||||
AString getOMTAStyle(in nsIDOMElement aElement, in AString aProperty);
|
||||
|
||||
/**
|
||||
* Special function that gets a property syncronously from the last composite
|
||||
* that occured.
|
||||
*
|
||||
* Supported properties:
|
||||
* "overdraw": Report a percentage between 0 and 999 indicate how many times
|
||||
* each pixels on the destination window have been touched.
|
||||
* "missed_hwc": Report a bool if hardware composer is supported but was
|
||||
* not used for the last frame.
|
||||
*/
|
||||
float requestCompositorProperty(in AString aProperty);
|
||||
|
||||
/**
|
||||
* If aHandlingInput is true, this informs the event state manager that
|
||||
* we're handling user input. Otherwise, this is a no-op (as by default
|
||||
|
@ -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/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
/**
|
||||
* SpeechSynthesisGetter
|
||||
* http://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section
|
||||
*/
|
||||
|
||||
[scriptable, uuid(31e6c818-0279-4948-843c-930043f6bafd)]
|
||||
interface nsISpeechSynthesisGetter : nsISupports
|
||||
{
|
||||
readonly attribute nsISupports speechSynthesis;
|
||||
};
|
@ -23,7 +23,6 @@ XPIDL_SOURCES += [
|
||||
'nsIDOMText.idl',
|
||||
'nsIDOMUserDataHandler.idl',
|
||||
'nsIDOMXMLDocument.idl',
|
||||
'nsIInlineEventHandlers.idl',
|
||||
]
|
||||
|
||||
XPIDL_MODULE = 'dom_core'
|
||||
|
@ -1,93 +0,0 @@
|
||||
/* 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 "domstubs.idl"
|
||||
|
||||
%{ C++
|
||||
#include "jspubtd.h"
|
||||
%}
|
||||
|
||||
[scriptable, uuid(6c1fcf3d-119b-4cf4-9437-b9357508976a)]
|
||||
interface nsIInlineEventHandlers : nsISupports
|
||||
{
|
||||
[implicit_jscontext] attribute jsval onabort;
|
||||
[implicit_jscontext] attribute jsval onblur;
|
||||
[implicit_jscontext] attribute jsval oncanplay;
|
||||
[implicit_jscontext] attribute jsval oncanplaythrough;
|
||||
[implicit_jscontext] attribute jsval onchange;
|
||||
[implicit_jscontext] attribute jsval onclick;
|
||||
[implicit_jscontext] attribute jsval oncontextmenu;
|
||||
// Not supported yet
|
||||
// [implicit_jscontext] attribute jsval oncuechange;
|
||||
[implicit_jscontext] attribute jsval ondblclick;
|
||||
[implicit_jscontext] attribute jsval ondrag;
|
||||
[implicit_jscontext] attribute jsval ondragend;
|
||||
[implicit_jscontext] attribute jsval ondragenter;
|
||||
[implicit_jscontext] attribute jsval ondragleave;
|
||||
[implicit_jscontext] attribute jsval ondragover;
|
||||
[implicit_jscontext] attribute jsval ondragstart;
|
||||
[implicit_jscontext] attribute jsval ondrop;
|
||||
[implicit_jscontext] attribute jsval ondurationchange;
|
||||
[implicit_jscontext] attribute jsval onemptied;
|
||||
[implicit_jscontext] attribute jsval onended;
|
||||
[implicit_jscontext] attribute jsval onerror;
|
||||
[implicit_jscontext] attribute jsval onfocus;
|
||||
[implicit_jscontext] attribute jsval oninput;
|
||||
[implicit_jscontext] attribute jsval oninvalid;
|
||||
[implicit_jscontext] attribute jsval onkeydown;
|
||||
[implicit_jscontext] attribute jsval onkeypress;
|
||||
[implicit_jscontext] attribute jsval onkeyup;
|
||||
[implicit_jscontext] attribute jsval onload;
|
||||
[implicit_jscontext] attribute jsval onloadeddata;
|
||||
[implicit_jscontext] attribute jsval onloadedmetadata;
|
||||
[implicit_jscontext] attribute jsval onloadstart;
|
||||
[implicit_jscontext] attribute jsval onmousedown;
|
||||
[implicit_jscontext] attribute jsval onmousemove;
|
||||
[implicit_jscontext] attribute jsval onmouseout;
|
||||
[implicit_jscontext] attribute jsval onmouseover;
|
||||
[implicit_jscontext] attribute jsval onmouseup;
|
||||
// Not supported yet
|
||||
// [implicit_jscontext] attribute jsval onmousewheel;
|
||||
[implicit_jscontext] attribute jsval onmozfullscreenchange;
|
||||
[implicit_jscontext] attribute jsval onmozfullscreenerror;
|
||||
[implicit_jscontext] attribute jsval onmozpointerlockchange;
|
||||
[implicit_jscontext] attribute jsval onmozpointerlockerror;
|
||||
[implicit_jscontext] attribute jsval onpause;
|
||||
[implicit_jscontext] attribute jsval onplay;
|
||||
[implicit_jscontext] attribute jsval onplaying;
|
||||
[implicit_jscontext] attribute jsval onprogress;
|
||||
[implicit_jscontext] attribute jsval onratechange;
|
||||
[implicit_jscontext] attribute jsval onreset;
|
||||
[implicit_jscontext] attribute jsval onscroll;
|
||||
[implicit_jscontext] attribute jsval onseeked;
|
||||
[implicit_jscontext] attribute jsval onseeking;
|
||||
[implicit_jscontext] attribute jsval onselect;
|
||||
[implicit_jscontext] attribute jsval onshow;
|
||||
[implicit_jscontext] attribute jsval onstalled;
|
||||
[implicit_jscontext] attribute jsval onsubmit;
|
||||
[implicit_jscontext] attribute jsval onsuspend;
|
||||
[implicit_jscontext] attribute jsval ontimeupdate;
|
||||
[implicit_jscontext] attribute jsval onvolumechange;
|
||||
[implicit_jscontext] attribute jsval onwaiting;
|
||||
[implicit_jscontext] attribute jsval onwheel;
|
||||
|
||||
[implicit_jscontext] attribute jsval onpointerdown;
|
||||
[implicit_jscontext] attribute jsval onpointermove;
|
||||
[implicit_jscontext] attribute jsval onpointerout;
|
||||
[implicit_jscontext] attribute jsval onpointerover;
|
||||
[implicit_jscontext] attribute jsval onpointerup;
|
||||
[implicit_jscontext] attribute jsval onpointerenter;
|
||||
[implicit_jscontext] attribute jsval onpointerleave;
|
||||
[implicit_jscontext] attribute jsval ongotpointercapture;
|
||||
[implicit_jscontext] attribute jsval onlostpointercapture;
|
||||
[implicit_jscontext] attribute jsval onpointercancel;
|
||||
|
||||
/**
|
||||
* Non-HTML5 event attributes
|
||||
*/
|
||||
[implicit_jscontext] attribute jsval oncopy;
|
||||
[implicit_jscontext] attribute jsval oncut;
|
||||
[implicit_jscontext] attribute jsval onpaste;
|
||||
[implicit_jscontext] attribute jsval onbeforescriptexecute;
|
||||
[implicit_jscontext] attribute jsval onafterscriptexecute;
|
||||
};
|
@ -28,7 +28,6 @@ XPIDL_SOURCES += [
|
||||
'nsIDOMPaintRequest.idl',
|
||||
'nsIDOMScrollAreaEvent.idl',
|
||||
'nsIDOMSimpleGestureEvent.idl',
|
||||
'nsIDOMTouchEvent.idl',
|
||||
'nsIDOMTransitionEvent.idl',
|
||||
'nsIDOMUIEvent.idl',
|
||||
'nsIDOMWheelEvent.idl',
|
||||
|
@ -1,19 +0,0 @@
|
||||
/* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
|
||||
/* 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 "nsIDOMUIEvent.idl"
|
||||
%{C++
|
||||
#include "nsWeakPtr.h"
|
||||
#include "nsPoint.h"
|
||||
%}
|
||||
interface nsIVariant;
|
||||
|
||||
[scriptable, uuid(6d5484f7-92ac-45f8-9388-39b5bad055ce)]
|
||||
interface nsITouchEventReceiver : nsISupports {
|
||||
[implicit_jscontext] attribute jsval ontouchstart;
|
||||
[implicit_jscontext] attribute jsval ontouchend;
|
||||
[implicit_jscontext] attribute jsval ontouchmove;
|
||||
[implicit_jscontext] attribute jsval ontouchcancel;
|
||||
};
|
@ -16,14 +16,13 @@
|
||||
* http://www.whatwg.org/specs/web-apps/current-work/
|
||||
*/
|
||||
|
||||
[uuid(e83e726a-0aef-4292-938b-253fec691e2f)]
|
||||
[uuid(ec18e71c-4f5c-4cc3-aa36-5273168644dc)]
|
||||
interface nsIDOMHTMLImageElement : nsISupports
|
||||
{
|
||||
attribute DOMString alt;
|
||||
attribute DOMString src;
|
||||
attribute DOMString srcset;
|
||||
attribute DOMString sizes;
|
||||
attribute DOMString crossOrigin;
|
||||
attribute DOMString useMap;
|
||||
attribute boolean isMap;
|
||||
attribute unsigned long width;
|
||||
|
@ -16,7 +16,7 @@
|
||||
* http://www.whatwg.org/specs/web-apps/current-work/
|
||||
*/
|
||||
|
||||
[uuid(95d6ec66-2754-45bd-a068-49ac1fb45004)]
|
||||
[uuid(ee50b7ab-0015-4fbe-89e0-e3feacd4ffde)]
|
||||
interface nsIDOMHTMLLinkElement : nsISupports
|
||||
{
|
||||
[binaryname(MozDisabled)]
|
||||
@ -29,5 +29,4 @@ interface nsIDOMHTMLLinkElement : nsISupports
|
||||
attribute DOMString rev;
|
||||
attribute DOMString target;
|
||||
attribute DOMString type;
|
||||
attribute DOMString crossOrigin;
|
||||
};
|
||||
|
@ -27,7 +27,7 @@ interface nsIDOMMediaStream;
|
||||
#endif
|
||||
%}
|
||||
|
||||
[uuid(0e14e6ad-2074-48b7-a247-e545a3a15131)]
|
||||
[uuid(c041d76c-15ce-47ad-b61d-e8755a6db638)]
|
||||
interface nsIDOMHTMLMediaElement : nsISupports
|
||||
{
|
||||
// error state
|
||||
@ -37,7 +37,6 @@ interface nsIDOMHTMLMediaElement : nsISupports
|
||||
attribute DOMString src;
|
||||
attribute nsIDOMMediaStream mozSrcObject;
|
||||
readonly attribute DOMString currentSrc;
|
||||
attribute DOMString crossOrigin;
|
||||
const unsigned short NETWORK_EMPTY = 0;
|
||||
const unsigned short NETWORK_IDLE = 1;
|
||||
const unsigned short NETWORK_LOADING = 2;
|
||||
|
@ -16,7 +16,7 @@
|
||||
* http://www.whatwg.org/specs/web-apps/current-work/
|
||||
*/
|
||||
|
||||
[uuid(4627336e-3070-4e73-8f67-3851b54cc0eb)]
|
||||
[uuid(fe96dc1c-40e4-4974-9354-e3fce663c3d5)]
|
||||
interface nsIDOMHTMLScriptElement : nsISupports
|
||||
{
|
||||
attribute DOMString src;
|
||||
@ -28,5 +28,4 @@ interface nsIDOMHTMLScriptElement : nsISupports
|
||||
|
||||
attribute DOMString htmlFor;
|
||||
attribute DOMString event;
|
||||
attribute DOMString crossOrigin;
|
||||
};
|
||||
|
@ -879,11 +879,6 @@ TabChild::Observe(nsISupports *aSubject,
|
||||
|
||||
mContentDocumentIsDisplayed = true;
|
||||
|
||||
// Reset CSS viewport and zoom to default on new page, then
|
||||
// calculate them properly using the actual metadata from the
|
||||
// page.
|
||||
SetCSSViewport(kDefaultViewportSize);
|
||||
|
||||
// In some cases before-first-paint gets called before
|
||||
// RecvUpdateDimensions is called and therefore before we have an
|
||||
// mInnerSize value set. In such cases defer initializing the viewport
|
||||
|
@ -546,6 +546,11 @@ public:
|
||||
// from MediaManager thread.
|
||||
static MediaManager* Get();
|
||||
|
||||
static bool Exists()
|
||||
{
|
||||
return !!sSingleton;
|
||||
}
|
||||
|
||||
static nsIThread* GetThread() {
|
||||
return Get()->mMediaThread;
|
||||
}
|
||||
|
@ -679,16 +679,19 @@ RTCPeerConnection.prototype = {
|
||||
let idpComplete = false;
|
||||
let setRemoteComplete = false;
|
||||
let idpError = null;
|
||||
let isDone = false;
|
||||
|
||||
// we can run the IdP validation in parallel with setRemoteDescription this
|
||||
// complicates much more than would be ideal, but it ensures that the IdP
|
||||
// doesn't hold things up too much when it's not on the critical path
|
||||
let allDone = () => {
|
||||
if (!setRemoteComplete || !idpComplete || !onSuccess) {
|
||||
if (!setRemoteComplete || !idpComplete || isDone) {
|
||||
return;
|
||||
}
|
||||
// May be null if the user didn't supply success/failure callbacks.
|
||||
// Violation of spec, but we allow it for now
|
||||
this.callCB(onSuccess);
|
||||
onSuccess = null;
|
||||
isDone = true;
|
||||
this._executeNext();
|
||||
};
|
||||
|
||||
|
@ -643,8 +643,6 @@ var interfaceNamesInGlobalScope =
|
||||
"MimeType",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"MimeTypeArray",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"ModalContentWindow",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"MouseEvent",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
@ -26,7 +26,7 @@ interface HTMLImageElement : HTMLElement {
|
||||
[SetterThrows, Pref="dom.image.srcset.enabled"]
|
||||
attribute DOMString srcset;
|
||||
[SetterThrows]
|
||||
attribute DOMString crossOrigin;
|
||||
attribute DOMString? crossOrigin;
|
||||
[SetterThrows]
|
||||
attribute DOMString useMap;
|
||||
[SetterThrows]
|
||||
|
@ -18,7 +18,7 @@ interface HTMLLinkElement : HTMLElement {
|
||||
[SetterThrows, Pure]
|
||||
attribute DOMString href;
|
||||
[SetterThrows, Pure]
|
||||
attribute DOMString crossOrigin;
|
||||
attribute DOMString? crossOrigin;
|
||||
[SetterThrows, Pure]
|
||||
attribute DOMString rel;
|
||||
readonly attribute DOMTokenList relList;
|
||||
|
@ -22,7 +22,7 @@ interface HTMLMediaElement : HTMLElement {
|
||||
readonly attribute DOMString currentSrc;
|
||||
|
||||
[SetterThrows]
|
||||
attribute DOMString crossOrigin;
|
||||
attribute DOMString? crossOrigin;
|
||||
const unsigned short NETWORK_EMPTY = 0;
|
||||
const unsigned short NETWORK_IDLE = 1;
|
||||
const unsigned short NETWORK_LOADING = 2;
|
||||
|
@ -20,7 +20,7 @@ interface HTMLScriptElement : HTMLElement {
|
||||
[SetterThrows]
|
||||
attribute boolean defer;
|
||||
[SetterThrows]
|
||||
attribute DOMString crossOrigin;
|
||||
attribute DOMString? crossOrigin;
|
||||
[SetterThrows]
|
||||
attribute DOMString text;
|
||||
};
|
||||
|
@ -16,7 +16,7 @@ interface SVGScriptElement : SVGElement {
|
||||
|
||||
// CORS attribute
|
||||
[SetterThrows]
|
||||
attribute DOMString crossOrigin;
|
||||
attribute DOMString? crossOrigin;
|
||||
};
|
||||
|
||||
SVGScriptElement implements SVGURIReference;
|
||||
|
@ -31,7 +31,7 @@ typedef any Transferable;
|
||||
CrossOriginReadable] readonly attribute WindowProxy window;
|
||||
[Replaceable, Throws,
|
||||
CrossOriginReadable] readonly attribute WindowProxy self;
|
||||
[Unforgeable, StoreInSlot, Pure, Func="nsGlobalWindow::WindowOnWebIDL"] readonly attribute Document? document;
|
||||
[Unforgeable, StoreInSlot, Pure] readonly attribute Document? document;
|
||||
[Throws] attribute DOMString name;
|
||||
[PutForwards=href, Unforgeable, Throws,
|
||||
CrossOriginReadable, CrossOriginWritable] readonly attribute Location? location;
|
||||
@ -218,7 +218,7 @@ callback FrameRequestCallback = void (DOMHighResTimeStamp time);
|
||||
|
||||
// https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/NavigationTiming/Overview.html
|
||||
partial interface Window {
|
||||
[Replaceable, Throws] readonly attribute Performance? performance;
|
||||
[Replaceable, Pure, StoreInSlot] readonly attribute Performance? performance;
|
||||
};
|
||||
|
||||
// https://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html
|
||||
|
@ -985,6 +985,9 @@ public:
|
||||
void *GetUserData(UserDataKey *key) {
|
||||
return mUserData.Get(key);
|
||||
}
|
||||
void *RemoveUserData(UserDataKey *key) {
|
||||
return mUserData.Remove(key);
|
||||
}
|
||||
|
||||
/** Within this rectangle all pixels will be opaque by the time the result of
|
||||
* this DrawTarget is first used for drawing. Either by the underlying surface
|
||||
|
@ -178,7 +178,16 @@ Factory::HasSSE2()
|
||||
// cl.exe with -arch:SSE2 (default on x64 compiler)
|
||||
return true;
|
||||
#elif defined(HAVE_CPU_DETECTION)
|
||||
return HasCPUIDBit(1u, edx, (1u<<26));
|
||||
static enum {
|
||||
UNINITIALIZED,
|
||||
NO_SSE2,
|
||||
HAS_SSE2
|
||||
} sDetectionState = UNINITIALIZED;
|
||||
|
||||
if (sDetectionState == UNINITIALIZED) {
|
||||
sDetectionState = HasCPUIDBit(1u, edx, (1u<<26)) ? HAS_SSE2 : NO_SSE2;
|
||||
}
|
||||
return sDetectionState == HAS_SSE2;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
|
@ -18,9 +18,11 @@ using namespace mozilla;
|
||||
#define OPENGL_FRAMEWORK_PATH \
|
||||
"/System/Library/Frameworks/OpenGL.framework/OpenGL"
|
||||
#define COREGRAPHICS_FRAMEWORK_PATH \
|
||||
"/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/CoreGraphics"
|
||||
|
||||
|
||||
"/System/Library/Frameworks/ApplicationServices.framework/Frameworks/" \
|
||||
"CoreGraphics.framework/CoreGraphics"
|
||||
#define COREVIDEO_FRAMEWORK_PATH \
|
||||
"/System/Library/Frameworks/ApplicationServices.framework/Frameworks/" \
|
||||
"CoreVideo.framework/CoreVideo"
|
||||
|
||||
#define GET_CONST(const_name) \
|
||||
((CFStringRef*) dlsym(sIOSurfaceFramework, const_name))
|
||||
@ -30,26 +32,34 @@ using namespace mozilla;
|
||||
(typeof(dest)) dlsym(sOpenGLFramework, sym_name)
|
||||
#define GET_CGSYM(dest,sym_name) \
|
||||
(typeof(dest)) dlsym(sCoreGraphicsFramework, sym_name)
|
||||
#define GET_CVSYM(dest, sym_name) \
|
||||
(typeof(dest)) dlsym(sCoreVideoFramework, sym_name)
|
||||
|
||||
MacIOSurfaceLib::LibraryUnloader MacIOSurfaceLib::sLibraryUnloader;
|
||||
bool MacIOSurfaceLib::isLoaded = false;
|
||||
void* MacIOSurfaceLib::sIOSurfaceFramework;
|
||||
void* MacIOSurfaceLib::sOpenGLFramework;
|
||||
void* MacIOSurfaceLib::sCoreGraphicsFramework;
|
||||
void* MacIOSurfaceLib::sCoreVideoFramework;
|
||||
IOSurfaceCreateFunc MacIOSurfaceLib::sCreate;
|
||||
IOSurfaceGetIDFunc MacIOSurfaceLib::sGetID;
|
||||
IOSurfaceLookupFunc MacIOSurfaceLib::sLookup;
|
||||
IOSurfaceGetBaseAddressFunc MacIOSurfaceLib::sGetBaseAddress;
|
||||
IOSurfaceGetWidthFunc MacIOSurfaceLib::sWidth;
|
||||
IOSurfaceGetHeightFunc MacIOSurfaceLib::sHeight;
|
||||
IOSurfaceGetBytesPerRowFunc MacIOSurfaceLib::sBytesPerRow;
|
||||
IOSurfaceGetBaseAddressOfPlaneFunc MacIOSurfaceLib::sGetBaseAddressOfPlane;
|
||||
IOSurfaceSizeTFunc MacIOSurfaceLib::sWidth;
|
||||
IOSurfaceSizeTFunc MacIOSurfaceLib::sHeight;
|
||||
IOSurfaceSizeTFunc MacIOSurfaceLib::sPlaneCount;
|
||||
IOSurfaceSizeTFunc MacIOSurfaceLib::sBytesPerRow;
|
||||
IOSurfaceGetPropertyMaximumFunc MacIOSurfaceLib::sGetPropertyMaximum;
|
||||
IOSurfaceVoidFunc MacIOSurfaceLib::sIncrementUseCount;
|
||||
IOSurfaceVoidFunc MacIOSurfaceLib::sDecrementUseCount;
|
||||
IOSurfaceLockFunc MacIOSurfaceLib::sLock;
|
||||
IOSurfaceUnlockFunc MacIOSurfaceLib::sUnlock;
|
||||
CGLTexImageIOSurface2DFunc MacIOSurfaceLib::sTexImage;
|
||||
IOSurfaceContextCreateFunc MacIOSurfaceLib::sIOSurfaceContextCreate;
|
||||
IOSurfaceContextCreateImageFunc MacIOSurfaceLib::sIOSurfaceContextCreateImage;
|
||||
IOSurfaceContextGetSurfaceFunc MacIOSurfaceLib::sIOSurfaceContextGetSurface;
|
||||
CVPixelBufferGetIOSurfaceFunc MacIOSurfaceLib::sCVPixelBufferGetIOSurface;
|
||||
unsigned int (*MacIOSurfaceLib::sCGContextGetTypePtr) (CGContextRef) = nullptr;
|
||||
|
||||
CFStringRef MacIOSurfaceLib::kPropWidth;
|
||||
@ -83,6 +93,15 @@ void* MacIOSurfaceLib::IOSurfaceGetBaseAddress(IOSurfacePtr aIOSurfacePtr) {
|
||||
return sGetBaseAddress(aIOSurfacePtr);
|
||||
}
|
||||
|
||||
void* MacIOSurfaceLib::IOSurfaceGetBaseAddressOfPlane(IOSurfacePtr aIOSurfacePtr,
|
||||
size_t planeIndex) {
|
||||
return sGetBaseAddressOfPlane(aIOSurfacePtr, planeIndex);
|
||||
}
|
||||
|
||||
size_t MacIOSurfaceLib::IOSurfaceGetPlaneCount(IOSurfacePtr aIOSurfacePtr) {
|
||||
return sPlaneCount(aIOSurfacePtr);
|
||||
}
|
||||
|
||||
size_t MacIOSurfaceLib::IOSurfaceGetWidth(IOSurfacePtr aIOSurfacePtr) {
|
||||
return sWidth(aIOSurfacePtr);
|
||||
}
|
||||
@ -99,16 +118,24 @@ size_t MacIOSurfaceLib::IOSurfaceGetPropertyMaximum(CFStringRef property) {
|
||||
return sGetPropertyMaximum(property);
|
||||
}
|
||||
|
||||
IOReturn MacIOSurfaceLib::IOSurfaceLock(IOSurfacePtr aIOSurfacePtr,
|
||||
uint32_t options, uint32_t *seed) {
|
||||
IOReturn MacIOSurfaceLib::IOSurfaceLock(IOSurfacePtr aIOSurfacePtr,
|
||||
uint32_t options, uint32_t* seed) {
|
||||
return sLock(aIOSurfacePtr, options, seed);
|
||||
}
|
||||
|
||||
IOReturn MacIOSurfaceLib::IOSurfaceUnlock(IOSurfacePtr aIOSurfacePtr,
|
||||
IOReturn MacIOSurfaceLib::IOSurfaceUnlock(IOSurfacePtr aIOSurfacePtr,
|
||||
uint32_t options, uint32_t *seed) {
|
||||
return sUnlock(aIOSurfacePtr, options, seed);
|
||||
}
|
||||
|
||||
void MacIOSurfaceLib::IOSurfaceIncrementUseCount(IOSurfacePtr aIOSurfacePtr) {
|
||||
sIncrementUseCount(aIOSurfacePtr);
|
||||
}
|
||||
|
||||
void MacIOSurfaceLib::IOSurfaceDecrementUseCount(IOSurfacePtr aIOSurfacePtr) {
|
||||
sDecrementUseCount(aIOSurfacePtr);
|
||||
}
|
||||
|
||||
CGLError MacIOSurfaceLib::CGLTexImageIOSurface2D(CGLContextObj ctxt,
|
||||
GLenum target, GLenum internalFormat,
|
||||
GLsizei width, GLsizei height,
|
||||
@ -118,6 +145,10 @@ CGLError MacIOSurfaceLib::CGLTexImageIOSurface2D(CGLContextObj ctxt,
|
||||
format, type, ioSurface, plane);
|
||||
}
|
||||
|
||||
IOSurfacePtr MacIOSurfaceLib::CVPixelBufferGetIOSurface(CVPixelBufferRef aPixelBuffer) {
|
||||
return sCVPixelBufferGetIOSurface(aPixelBuffer);
|
||||
}
|
||||
|
||||
CGContextRef MacIOSurfaceLib::IOSurfaceContextCreate(IOSurfacePtr aIOSurfacePtr,
|
||||
unsigned aWidth, unsigned aHeight,
|
||||
unsigned aBitsPerComponent, unsigned aBytes,
|
||||
@ -159,16 +190,24 @@ void MacIOSurfaceLib::LoadLibrary() {
|
||||
|
||||
sCoreGraphicsFramework = dlopen(COREGRAPHICS_FRAMEWORK_PATH,
|
||||
RTLD_LAZY | RTLD_LOCAL);
|
||||
if (!sIOSurfaceFramework || !sOpenGLFramework || !sCoreGraphicsFramework) {
|
||||
|
||||
sCoreVideoFramework = dlopen(COREVIDEO_FRAMEWORK_PATH,
|
||||
RTLD_LAZY | RTLD_LOCAL);
|
||||
|
||||
if (!sIOSurfaceFramework || !sOpenGLFramework || !sCoreGraphicsFramework ||
|
||||
!sCoreVideoFramework) {
|
||||
if (sIOSurfaceFramework)
|
||||
dlclose(sIOSurfaceFramework);
|
||||
if (sOpenGLFramework)
|
||||
dlclose(sOpenGLFramework);
|
||||
if (sCoreGraphicsFramework)
|
||||
dlclose(sCoreGraphicsFramework);
|
||||
if (sCoreVideoFramework)
|
||||
dlclose(sCoreVideoFramework);
|
||||
sIOSurfaceFramework = nullptr;
|
||||
sOpenGLFramework = nullptr;
|
||||
sCoreGraphicsFramework = nullptr;
|
||||
sCoreVideoFramework = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -186,19 +225,32 @@ void MacIOSurfaceLib::LoadLibrary() {
|
||||
sLookup = GET_IOSYM(sLookup, "IOSurfaceLookup");
|
||||
sLock = GET_IOSYM(sLock, "IOSurfaceLock");
|
||||
sUnlock = GET_IOSYM(sUnlock, "IOSurfaceUnlock");
|
||||
sIncrementUseCount =
|
||||
GET_IOSYM(sIncrementUseCount, "IOSurfaceIncrementUseCount");
|
||||
sDecrementUseCount =
|
||||
GET_IOSYM(sDecrementUseCount, "IOSurfaceDecrementUseCount");
|
||||
sGetBaseAddress = GET_IOSYM(sGetBaseAddress, "IOSurfaceGetBaseAddress");
|
||||
sGetBaseAddressOfPlane =
|
||||
GET_IOSYM(sGetBaseAddressOfPlane, "IOSurfaceGetBaseAddressOfPlane");
|
||||
sPlaneCount = GET_IOSYM(sPlaneCount, "IOSurfaceGetPlaneCount");
|
||||
|
||||
sTexImage = GET_CGLSYM(sTexImage, "CGLTexImageIOSurface2D");
|
||||
sCGContextGetTypePtr = (unsigned int (*)(CGContext*))dlsym(RTLD_DEFAULT, "CGContextGetType");
|
||||
|
||||
sCVPixelBufferGetIOSurface =
|
||||
GET_CVSYM(sCVPixelBufferGetIOSurface, "CVPixelBufferGetIOSurface");
|
||||
|
||||
// Optional symbols
|
||||
sIOSurfaceContextCreate = GET_CGSYM(sIOSurfaceContextCreate, "CGIOSurfaceContextCreate");
|
||||
sIOSurfaceContextCreateImage = GET_CGSYM(sIOSurfaceContextCreateImage, "CGIOSurfaceContextCreateImage");
|
||||
sIOSurfaceContextGetSurface = GET_CGSYM(sIOSurfaceContextGetSurface, "CGIOSurfaceContextGetSurface");
|
||||
|
||||
if (!sCreate || !sGetID || !sLookup || !sTexImage || !sGetBaseAddress ||
|
||||
!sGetBaseAddressOfPlane || !sPlaneCount ||
|
||||
!kPropWidth || !kPropHeight || !kPropBytesPerElem || !kPropIsGlobal ||
|
||||
!sLock || !sUnlock || !sWidth || !sHeight || !kPropBytesPerRow ||
|
||||
!sBytesPerRow || !sGetPropertyMaximum) {
|
||||
!sLock || !sUnlock || !sIncrementUseCount || !sDecrementUseCount ||
|
||||
!sWidth || !sHeight || !kPropBytesPerRow ||
|
||||
!sBytesPerRow || !sGetPropertyMaximum || !sCVPixelBufferGetIOSurface) {
|
||||
CloseLibrary();
|
||||
}
|
||||
}
|
||||
@ -210,11 +262,26 @@ void MacIOSurfaceLib::CloseLibrary() {
|
||||
if (sOpenGLFramework) {
|
||||
dlclose(sOpenGLFramework);
|
||||
}
|
||||
if (sCoreVideoFramework) {
|
||||
dlclose(sCoreVideoFramework);
|
||||
}
|
||||
sIOSurfaceFramework = nullptr;
|
||||
sOpenGLFramework = nullptr;
|
||||
sCoreVideoFramework = nullptr;
|
||||
}
|
||||
|
||||
MacIOSurface::MacIOSurface(const void* aIOSurfacePtr,
|
||||
double aContentsScaleFactor, bool aHasAlpha)
|
||||
: mIOSurfacePtr(aIOSurfacePtr)
|
||||
, mContentsScaleFactor(aContentsScaleFactor)
|
||||
, mHasAlpha(aHasAlpha)
|
||||
{
|
||||
CFRetain(mIOSurfacePtr);
|
||||
IncrementUseCount();
|
||||
}
|
||||
|
||||
MacIOSurface::~MacIOSurface() {
|
||||
DecrementUseCount();
|
||||
CFRelease(mIOSurfacePtr);
|
||||
}
|
||||
|
||||
@ -265,6 +332,9 @@ TemporaryRef<MacIOSurface> MacIOSurface::CreateIOSurface(int aWidth, int aHeight
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Release the IOSurface because MacIOSurface retained it
|
||||
CFRelease(surfaceRef);
|
||||
|
||||
return ioSurface.forget();
|
||||
}
|
||||
|
||||
@ -283,6 +353,10 @@ TemporaryRef<MacIOSurface> MacIOSurface::LookupSurface(IOSurfaceID aIOSurfaceID,
|
||||
::CFRelease(surfaceRef);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Release the IOSurface because MacIOSurface retained it
|
||||
CFRelease(surfaceRef);
|
||||
|
||||
return ioSurface.forget();
|
||||
}
|
||||
|
||||
@ -294,6 +368,12 @@ void* MacIOSurface::GetBaseAddress() {
|
||||
return MacIOSurfaceLib::IOSurfaceGetBaseAddress(mIOSurfacePtr);
|
||||
}
|
||||
|
||||
void* MacIOSurface::GetBaseAddressOfPlane(size_t aPlaneIndex)
|
||||
{
|
||||
return MacIOSurfaceLib::IOSurfaceGetBaseAddressOfPlane(mIOSurfacePtr,
|
||||
aPlaneIndex);
|
||||
}
|
||||
|
||||
size_t MacIOSurface::GetWidth() {
|
||||
size_t intScaleFactor = ceil(mContentsScaleFactor);
|
||||
return GetDevicePixelWidth() / intScaleFactor;
|
||||
@ -304,6 +384,10 @@ size_t MacIOSurface::GetHeight() {
|
||||
return GetDevicePixelHeight() / intScaleFactor;
|
||||
}
|
||||
|
||||
size_t MacIOSurface::GetPlaneCount() {
|
||||
return MacIOSurfaceLib::IOSurfaceGetPlaneCount(mIOSurfacePtr);
|
||||
}
|
||||
|
||||
/*static*/ size_t MacIOSurface::GetMaxWidth() {
|
||||
return MacIOSurfaceLib::IOSurfaceGetPropertyMaximum(MacIOSurfaceLib::kPropWidth);
|
||||
}
|
||||
@ -324,6 +408,14 @@ size_t MacIOSurface::GetBytesPerRow() {
|
||||
return MacIOSurfaceLib::IOSurfaceGetBytesPerRow(mIOSurfacePtr);
|
||||
}
|
||||
|
||||
void MacIOSurface::IncrementUseCount() {
|
||||
MacIOSurfaceLib::IOSurfaceIncrementUseCount(mIOSurfacePtr);
|
||||
}
|
||||
|
||||
void MacIOSurface::DecrementUseCount() {
|
||||
MacIOSurfaceLib::IOSurfaceDecrementUseCount(mIOSurfacePtr);
|
||||
}
|
||||
|
||||
#define READ_ONLY 0x1
|
||||
void MacIOSurface::Lock() {
|
||||
MacIOSurfaceLib::IOSurfaceLock(mIOSurfacePtr, READ_ONLY, nullptr);
|
||||
@ -413,9 +505,6 @@ TemporaryRef<MacIOSurface> MacIOSurface::IOSurfaceContextGetSurface(CGContextRef
|
||||
if (!surfaceRef)
|
||||
return nullptr;
|
||||
|
||||
// Retain the IOSurface because MacIOSurface will release it
|
||||
CFRetain(surfaceRef);
|
||||
|
||||
RefPtr<MacIOSurface> ioSurface = new MacIOSurface(surfaceRef, aContentsScaleFactor, aHasAlpha);
|
||||
if (!ioSurface) {
|
||||
::CFRelease(surfaceRef);
|
||||
|
@ -14,17 +14,16 @@
|
||||
typedef CFTypeRef IOSurfacePtr;
|
||||
typedef IOSurfacePtr (*IOSurfaceCreateFunc) (CFDictionaryRef properties);
|
||||
typedef IOSurfacePtr (*IOSurfaceLookupFunc) (uint32_t io_surface_id);
|
||||
typedef IOSurfaceID (*IOSurfaceGetIDFunc) (CFTypeRef io_surface);
|
||||
typedef IOReturn (*IOSurfaceLockFunc) (CFTypeRef io_surface,
|
||||
uint32_t options,
|
||||
uint32_t *seed);
|
||||
typedef IOReturn (*IOSurfaceUnlockFunc) (CFTypeRef io_surface,
|
||||
uint32_t options,
|
||||
uint32_t *seed);
|
||||
typedef void* (*IOSurfaceGetBaseAddressFunc) (CFTypeRef io_surface);
|
||||
typedef size_t (*IOSurfaceGetWidthFunc) (IOSurfacePtr io_surface);
|
||||
typedef size_t (*IOSurfaceGetHeightFunc) (IOSurfacePtr io_surface);
|
||||
typedef size_t (*IOSurfaceGetBytesPerRowFunc) (IOSurfacePtr io_surface);
|
||||
typedef IOSurfaceID (*IOSurfaceGetIDFunc)(IOSurfacePtr io_surface);
|
||||
typedef void (*IOSurfaceVoidFunc)(IOSurfacePtr io_surface);
|
||||
typedef IOReturn (*IOSurfaceLockFunc)(IOSurfacePtr io_surface, uint32_t options,
|
||||
uint32_t *seed);
|
||||
typedef IOReturn (*IOSurfaceUnlockFunc)(IOSurfacePtr io_surface,
|
||||
uint32_t options, uint32_t *seed);
|
||||
typedef void* (*IOSurfaceGetBaseAddressFunc)(IOSurfacePtr io_surface);
|
||||
typedef void* (*IOSurfaceGetBaseAddressOfPlaneFunc)(IOSurfacePtr io_surface,
|
||||
size_t planeIndex);
|
||||
typedef size_t (*IOSurfaceSizeTFunc)(IOSurfacePtr io_surface);
|
||||
typedef size_t (*IOSurfaceGetPropertyMaximumFunc) (CFStringRef property);
|
||||
typedef CGLError (*CGLTexImageIOSurface2DFunc) (CGLContextObj ctxt,
|
||||
GLenum target, GLenum internalFormat,
|
||||
@ -38,6 +37,8 @@ typedef CGContextRef (*IOSurfaceContextCreateFunc)(CFTypeRef io_surface,
|
||||
typedef CGImageRef (*IOSurfaceContextCreateImageFunc)(CGContextRef ref);
|
||||
typedef IOSurfacePtr (*IOSurfaceContextGetSurfaceFunc)(CGContextRef ref);
|
||||
|
||||
typedef IOSurfacePtr (*CVPixelBufferGetIOSurfaceFunc)(
|
||||
CVPixelBufferRef pixelBuffer);
|
||||
|
||||
#import <OpenGL/OpenGL.h>
|
||||
#include "2D.h"
|
||||
@ -64,6 +65,10 @@ public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(MacIOSurface)
|
||||
typedef mozilla::gfx::SourceSurface SourceSurface;
|
||||
|
||||
// The usage count of the IOSurface is increased by 1 during the lifetime
|
||||
// of the MacIOSurface instance.
|
||||
// MacIOSurface holds a reference to the corresponding IOSurface.
|
||||
|
||||
static mozilla::TemporaryRef<MacIOSurface> CreateIOSurface(int aWidth, int aHeight,
|
||||
double aContentsScaleFactor = 1.0,
|
||||
bool aHasAlpha = true);
|
||||
@ -72,11 +77,14 @@ public:
|
||||
double aContentsScaleFactor = 1.0,
|
||||
bool aHasAlpha = true);
|
||||
|
||||
explicit MacIOSurface(const void *aIOSurfacePtr, double aContentsScaleFactor = 1.0, bool aHasAlpha = true)
|
||||
: mIOSurfacePtr(aIOSurfacePtr), mContentsScaleFactor(aContentsScaleFactor), mHasAlpha(aHasAlpha) {}
|
||||
explicit MacIOSurface(const void *aIOSurfacePtr,
|
||||
double aContentsScaleFactor = 1.0,
|
||||
bool aHasAlpha = true);
|
||||
virtual ~MacIOSurface();
|
||||
IOSurfaceID GetIOSurfaceID();
|
||||
void *GetBaseAddress();
|
||||
void *GetBaseAddressOfPlane(size_t planeIndex);
|
||||
size_t GetPlaneCount();
|
||||
// GetWidth() and GetHeight() return values in "display pixels". A
|
||||
// "display pixel" is the smallest fully addressable part of a display.
|
||||
// But in HiDPI modes each "display pixel" corresponds to more than one
|
||||
@ -89,6 +97,8 @@ public:
|
||||
size_t GetBytesPerRow();
|
||||
void Lock();
|
||||
void Unlock();
|
||||
void IncrementUseCount();
|
||||
void DecrementUseCount();
|
||||
bool HasAlpha() { return mHasAlpha; }
|
||||
// We would like to forward declare NSOpenGLContext, but it is an @interface
|
||||
// and this file is also used from c++, so we use a void *.
|
||||
@ -117,21 +127,27 @@ public:
|
||||
static void *sIOSurfaceFramework;
|
||||
static void *sOpenGLFramework;
|
||||
static void *sCoreGraphicsFramework;
|
||||
static void *sCoreVideoFramework;
|
||||
static bool isLoaded;
|
||||
static IOSurfaceCreateFunc sCreate;
|
||||
static IOSurfaceGetIDFunc sGetID;
|
||||
static IOSurfaceLookupFunc sLookup;
|
||||
static IOSurfaceGetBaseAddressFunc sGetBaseAddress;
|
||||
static IOSurfaceGetBaseAddressOfPlaneFunc sGetBaseAddressOfPlane;
|
||||
static IOSurfaceSizeTFunc sPlaneCount;
|
||||
static IOSurfaceLockFunc sLock;
|
||||
static IOSurfaceUnlockFunc sUnlock;
|
||||
static IOSurfaceGetWidthFunc sWidth;
|
||||
static IOSurfaceGetHeightFunc sHeight;
|
||||
static IOSurfaceGetBytesPerRowFunc sBytesPerRow;
|
||||
static IOSurfaceVoidFunc sIncrementUseCount;
|
||||
static IOSurfaceVoidFunc sDecrementUseCount;
|
||||
static IOSurfaceSizeTFunc sWidth;
|
||||
static IOSurfaceSizeTFunc sHeight;
|
||||
static IOSurfaceSizeTFunc sBytesPerRow;
|
||||
static IOSurfaceGetPropertyMaximumFunc sGetPropertyMaximum;
|
||||
static CGLTexImageIOSurface2DFunc sTexImage;
|
||||
static IOSurfaceContextCreateFunc sIOSurfaceContextCreate;
|
||||
static IOSurfaceContextCreateImageFunc sIOSurfaceContextCreateImage;
|
||||
static IOSurfaceContextGetSurfaceFunc sIOSurfaceContextGetSurface;
|
||||
static CVPixelBufferGetIOSurfaceFunc sCVPixelBufferGetIOSurface;
|
||||
static CFStringRef kPropWidth;
|
||||
static CFStringRef kPropHeight;
|
||||
static CFStringRef kPropBytesPerElem;
|
||||
@ -144,14 +160,19 @@ public:
|
||||
static IOSurfacePtr IOSurfaceLookup(IOSurfaceID aIOSurfaceID);
|
||||
static IOSurfaceID IOSurfaceGetID(IOSurfacePtr aIOSurfacePtr);
|
||||
static void* IOSurfaceGetBaseAddress(IOSurfacePtr aIOSurfacePtr);
|
||||
static void* IOSurfaceGetBaseAddressOfPlane(IOSurfacePtr aIOSurfacePtr,
|
||||
size_t aPlaneIndex);
|
||||
static size_t IOSurfaceGetPlaneCount(IOSurfacePtr aIOSurfacePtr);
|
||||
static size_t IOSurfaceGetWidth(IOSurfacePtr aIOSurfacePtr);
|
||||
static size_t IOSurfaceGetHeight(IOSurfacePtr aIOSurfacePtr);
|
||||
static size_t IOSurfaceGetBytesPerRow(IOSurfacePtr aIOSurfacePtr);
|
||||
static size_t IOSurfaceGetPropertyMaximum(CFStringRef property);
|
||||
static IOReturn IOSurfaceLock(IOSurfacePtr aIOSurfacePtr,
|
||||
static IOReturn IOSurfaceLock(IOSurfacePtr aIOSurfacePtr,
|
||||
uint32_t options, uint32_t *seed);
|
||||
static IOReturn IOSurfaceUnlock(IOSurfacePtr aIOSurfacePtr,
|
||||
static IOReturn IOSurfaceUnlock(IOSurfacePtr aIOSurfacePtr,
|
||||
uint32_t options, uint32_t *seed);
|
||||
static void IOSurfaceIncrementUseCount(IOSurfacePtr aIOSurfacePtr);
|
||||
static void IOSurfaceDecrementUseCount(IOSurfacePtr aIOSurfacePtr);
|
||||
static CGLError CGLTexImageIOSurface2D(CGLContextObj ctxt,
|
||||
GLenum target, GLenum internalFormat,
|
||||
GLsizei width, GLsizei height,
|
||||
@ -163,6 +184,7 @@ public:
|
||||
CGColorSpaceRef aColorSpace, CGBitmapInfo bitmapInfo);
|
||||
static CGImageRef IOSurfaceContextCreateImage(CGContextRef ref);
|
||||
static IOSurfacePtr IOSurfaceContextGetSurface(CGContextRef ref);
|
||||
static IOSurfacePtr CVPixelBufferGetIOSurface(CVPixelBufferRef apixelBuffer);
|
||||
static unsigned int (*sCGContextGetTypePtr) (CGContextRef);
|
||||
static void LoadLibrary();
|
||||
static void CloseLibrary();
|
||||
|
@ -667,6 +667,8 @@ public:
|
||||
return SupportsMixBlendModes(modes);
|
||||
}
|
||||
|
||||
virtual float RequestProperty(const nsAString& property) { return -1; }
|
||||
|
||||
protected:
|
||||
nsRefPtr<Layer> mRoot;
|
||||
gfx::UserData mUserData;
|
||||
|
@ -934,31 +934,10 @@ APZCTreeManager::DispatchFling(AsyncPanZoomController* aPrev,
|
||||
nsRefPtr<const OverscrollHandoffChain> aOverscrollHandoffChain,
|
||||
bool aHandoff)
|
||||
{
|
||||
nsRefPtr<AsyncPanZoomController> next;
|
||||
|
||||
// If the fling is being handed off, give it to the next APZC in the
|
||||
// handoff chain after |aPrev|.
|
||||
if (aHandoff) {
|
||||
// Find |aPrev| in the handoff chain.
|
||||
uint32_t i = aOverscrollHandoffChain->IndexOf(aPrev);
|
||||
|
||||
// Get the next APZC in the handoff chain, if any.
|
||||
if (i + 1 < aOverscrollHandoffChain->Length()) {
|
||||
next = aOverscrollHandoffChain->GetApzcAtIndex(i + 1);
|
||||
}
|
||||
// If the fling is being started, give it to the first APZC in the
|
||||
// handoff chain.
|
||||
} else {
|
||||
if (aOverscrollHandoffChain->Length() != 0) {
|
||||
next = aOverscrollHandoffChain->GetApzcAtIndex(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Nothing to hand off fling to.
|
||||
if (next == nullptr || next->IsDestroyed()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsRefPtr<AsyncPanZoomController> current;
|
||||
uint32_t aOverscrollHandoffChainLength = aOverscrollHandoffChain->Length();
|
||||
uint32_t startIndex;
|
||||
|
||||
// The fling's velocity needs to be transformed from the screen coordinates
|
||||
// of |aPrev| to the screen coordinates of |next|. To transform a velocity
|
||||
// correctly, we need to convert it to a displacement. For now, we do this
|
||||
@ -967,14 +946,51 @@ APZCTreeManager::DispatchFling(AsyncPanZoomController* aPrev,
|
||||
// use the end point of the touch that started the fling as the start point
|
||||
// rather than (0, 0).
|
||||
ScreenPoint startPoint; // (0, 0)
|
||||
ScreenPoint endPoint = startPoint + aVelocity;
|
||||
if (aPrev != next) {
|
||||
TransformDisplacement(this, aPrev, next, startPoint, endPoint);
|
||||
ScreenPoint endPoint;
|
||||
ScreenPoint transformedVelocity = aVelocity;
|
||||
|
||||
if (aHandoff) {
|
||||
startIndex = aOverscrollHandoffChain->IndexOf(aPrev) + 1;
|
||||
|
||||
// IndexOf will return aOverscrollHandoffChain->Length() if
|
||||
// |aPrev| is not found.
|
||||
if (startIndex >= aOverscrollHandoffChainLength) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
startIndex = 0;
|
||||
}
|
||||
ScreenPoint transformedVelocity = endPoint - startPoint;
|
||||
|
||||
// Tell |next| to start a fling with the transformed velocity.
|
||||
return next->AttemptFling(transformedVelocity, aOverscrollHandoffChain, aHandoff);
|
||||
|
||||
for (; startIndex < aOverscrollHandoffChainLength; startIndex++) {
|
||||
current = aOverscrollHandoffChain->GetApzcAtIndex(startIndex);
|
||||
|
||||
// Make sure the apcz about to be handled can be handled
|
||||
if (current == nullptr || current->IsDestroyed()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
endPoint = startPoint + transformedVelocity;
|
||||
|
||||
// Only transform when current apcz can be transformed with previous
|
||||
if (startIndex > 0) {
|
||||
TransformDisplacement(this,
|
||||
aOverscrollHandoffChain->GetApzcAtIndex(startIndex - 1),
|
||||
current,
|
||||
startPoint,
|
||||
endPoint);
|
||||
}
|
||||
|
||||
transformedVelocity = endPoint - startPoint;
|
||||
|
||||
bool handoff = (startIndex < 1) ? aHandoff : true;
|
||||
if (current->AttemptFling(transformedVelocity,
|
||||
aOverscrollHandoffChain,
|
||||
handoff)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1964,18 +1964,8 @@ bool AsyncPanZoomController::AttemptFling(ScreenPoint aVelocity,
|
||||
false /* do not allow overscroll */);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Otherwise, hand the fling back to the tree manager to pass on to the
|
||||
// next APZC in the handoff chain. Had we started a fling animation in this
|
||||
// APZC, we would have done this hand-off on its first frame anyways, but
|
||||
// doing it here allows the tree manager to tell the previous APZC to enter
|
||||
// an overscroll fling if nothing further in the chain wants the fling.
|
||||
APZCTreeManager* treeManagerLocal = mTreeManager;
|
||||
return treeManagerLocal
|
||||
&& treeManagerLocal->DispatchFling(this,
|
||||
aVelocity,
|
||||
aOverscrollHandoffChain,
|
||||
true /* handoff */);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::HandleFlingOverscroll(const ScreenPoint& aVelocity,
|
||||
|
@ -385,6 +385,19 @@ ClientLayerManager::GetCompositorSideAPZTestData(APZTestData* aData) const
|
||||
}
|
||||
}
|
||||
|
||||
float
|
||||
ClientLayerManager::RequestProperty(const nsAString& aProperty)
|
||||
{
|
||||
if (mForwarder->HasShadowManager()) {
|
||||
float value;
|
||||
if (!mForwarder->GetShadowManager()->SendRequestProperty(nsString(aProperty), &value)) {
|
||||
NS_WARNING("Call to PLayerTransactionChild::SendGetAPZTestData() failed");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
ClientLayerManager::StartNewRepaintRequest(SequenceNumber aSequenceNumber)
|
||||
{
|
||||
|
@ -237,6 +237,7 @@ public:
|
||||
|
||||
void SetTransactionIdAllocator(TransactionIdAllocator* aAllocator) { mTransactionIdAllocator = aAllocator; }
|
||||
|
||||
float RequestProperty(const nsAString& aProperty) MOZ_OVERRIDE;
|
||||
protected:
|
||||
enum TransactionPhase {
|
||||
PHASE_NONE, PHASE_CONSTRUCTION, PHASE_DRAWING, PHASE_FORWARD
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user