mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-18 15:55:36 +00:00
Merge m-c to b2g-inbound
This commit is contained in:
commit
efa9474eef
@ -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>
|
||||
|
@ -1,6 +1,3 @@
|
||||
# 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/.
|
||||
|
||||
DIST_SUBDIR = 'browser'
|
||||
export('DIST_SUBDIR')
|
||||
|
@ -70,12 +70,16 @@ ToolSidebar.prototype = {
|
||||
|
||||
let tab = this._tabbox.tabs.appendItem();
|
||||
tab.setAttribute("label", ""); // Avoid showing "undefined" while the tab is loading
|
||||
tab.setAttribute("id", "sidebar-tab-" + id);
|
||||
|
||||
let onIFrameLoaded = (event) => {
|
||||
let doc = event.target;
|
||||
let win = doc.defaultView;
|
||||
tab.setAttribute("label", doc.title);
|
||||
|
||||
let onIFrameLoaded = () => {
|
||||
tab.setAttribute("label", iframe.contentDocument.title);
|
||||
iframe.removeEventListener("load", onIFrameLoaded, true);
|
||||
if ("setPanel" in iframe.contentWindow) {
|
||||
iframe.contentWindow.setPanel(this._toolPanel, iframe);
|
||||
if ("setPanel" in win) {
|
||||
win.setPanel(this._toolPanel, iframe);
|
||||
}
|
||||
this.emit(id + "-ready");
|
||||
};
|
||||
@ -109,6 +113,27 @@ ToolSidebar.prototype = {
|
||||
this.emit("new-tab-registered", id);
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove an existing tab.
|
||||
*/
|
||||
removeTab: function(id) {
|
||||
let tab = this._tabbox.tabs.querySelector("tab#sidebar-tab-" + id);
|
||||
if (!tab) {
|
||||
return;
|
||||
}
|
||||
|
||||
tab.remove();
|
||||
|
||||
let panel = this.getTab(id);
|
||||
if (panel) {
|
||||
panel.remove();
|
||||
}
|
||||
|
||||
this._tabs.delete(id);
|
||||
|
||||
this.emit("tab-unregistered", id);
|
||||
},
|
||||
|
||||
/**
|
||||
* Select a specific tab.
|
||||
*/
|
||||
|
@ -108,6 +108,7 @@ function test() {
|
||||
for (let tab of tabs) {
|
||||
is(tab.getAttribute("label"), label++, "Tab has the right title");
|
||||
}
|
||||
|
||||
is(label, 4, "Found the right amount of tabs.");
|
||||
is(panel.sidebar._tabbox.selectedPanel, panels[0], "First tab is selected");
|
||||
ok(panel.sidebar.getCurrentTabID(), "tab1", "getCurrentTabID() is correct");
|
||||
@ -119,13 +120,32 @@ function test() {
|
||||
panel.sidebar.hide();
|
||||
is(panel.sidebar._tabbox.getAttribute("hidden"), "true", "Sidebar hidden");
|
||||
is(panel.sidebar.getWindowForTab("tab1").location.href, tab1URL, "Window is accessible");
|
||||
testWidth(panel);
|
||||
testRemoval(panel);
|
||||
});
|
||||
});
|
||||
|
||||
panel.sidebar.select("tab2");
|
||||
}
|
||||
|
||||
function testRemoval(panel) {
|
||||
panel.sidebar.once("tab-unregistered", function(event, id) {
|
||||
info(event);
|
||||
registeredTabs[id] = false;
|
||||
|
||||
is(id, "tab3", "The right tab must be removed");
|
||||
|
||||
let tabs = panel.sidebar._tabbox.querySelectorAll("tab");
|
||||
let panels = panel.sidebar._tabbox.querySelectorAll("tabpanel");
|
||||
|
||||
is(tabs.length, 2, "There is the right number of tabs");
|
||||
is(panels.length, 2, "There is the right number of panels");
|
||||
|
||||
testWidth(panel);
|
||||
});
|
||||
|
||||
panel.sidebar.removeTab("tab3");
|
||||
}
|
||||
|
||||
function testWidth(panel) {
|
||||
let tabbox = panel.panelDoc.getElementById("sidebar");
|
||||
tabbox.width = 420;
|
||||
|
@ -736,6 +736,19 @@ InspectorPanel.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Show DOM properties
|
||||
*/
|
||||
showDOMProperties: function InspectorPanel_showDOMProperties() {
|
||||
this._toolbox.openSplitConsole().then(() => {
|
||||
let panel = this._toolbox.getPanel("webconsole");
|
||||
let jsterm = panel.hud.jsterm;
|
||||
|
||||
jsterm.execute("inspect($0)");
|
||||
jsterm.focusInput();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Clear any pseudo-class locks applied to the current hierarchy.
|
||||
*/
|
||||
|
@ -55,6 +55,9 @@
|
||||
<menuitem id="node-menu-copyimagedatauri"
|
||||
label="&inspectorCopyImageDataUri.label;"
|
||||
oncommand="inspector.copyImageDataUri()"/>
|
||||
<menuitem id="node-menu-showdomproperties"
|
||||
label="&inspectorShowDOMProperties.label;"
|
||||
oncommand="inspector.showDOMProperties()"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="node-menu-pasteouterhtml"
|
||||
label="&inspectorHTMLPasteOuter.label;"
|
||||
|
@ -80,11 +80,12 @@ registerCleanupFunction(() => {
|
||||
});
|
||||
|
||||
let test = asyncTest(function* () {
|
||||
let { inspector } = yield openInspectorForURL(TEST_URL);
|
||||
let { inspector, toolbox } = yield openInspectorForURL(TEST_URL);
|
||||
|
||||
yield testMenuItemSensitivity();
|
||||
yield testPasteOuterHTMLMenuItemSensitivity();
|
||||
yield testCopyMenuItems();
|
||||
yield testShowDOMProperties();
|
||||
yield testPasteOuterHTMLMenu();
|
||||
yield testDeleteNode();
|
||||
yield testDeleteRootNode();
|
||||
@ -154,6 +155,27 @@ let test = asyncTest(function* () {
|
||||
}
|
||||
}
|
||||
|
||||
function* testShowDOMProperties() {
|
||||
info("Testing 'Show DOM Properties' menu item.");
|
||||
let showDOMPropertiesNode = inspector.panelDoc.getElementById("node-menu-showdomproperties");
|
||||
ok(showDOMPropertiesNode, "the popup menu has a show dom properties item");
|
||||
|
||||
let consoleOpened = toolbox.once("webconsole-ready");
|
||||
|
||||
info("Triggering 'Show DOM Properties' and waiting for inspector open");
|
||||
dispatchCommandEvent(showDOMPropertiesNode);
|
||||
yield consoleOpened;
|
||||
|
||||
let webconsoleUI = toolbox.getPanel("webconsole").hud.ui;
|
||||
let messagesAdded = webconsoleUI.once("messages-added");
|
||||
yield messagesAdded;
|
||||
|
||||
info("Checking if 'inspect($0)' was evaluated");
|
||||
ok(webconsoleUI.jsterm.history[0] === 'inspect($0)');
|
||||
|
||||
yield toolbox.toggleSplitConsole();
|
||||
}
|
||||
|
||||
function* testPasteOuterHTMLMenu() {
|
||||
info("Testing that 'Paste Outer HTML' menu item works.");
|
||||
clipboard.set("this was pasted");
|
||||
|
@ -36,6 +36,9 @@
|
||||
.html-editor-inner {
|
||||
border: solid .1px;
|
||||
flex: 1 1 main-size;
|
||||
|
||||
/* Keep the editor away from the markup view floating scrollbars */
|
||||
-moz-margin-end: 12px;
|
||||
}
|
||||
|
||||
.html-editor iframe {
|
||||
|
@ -22,3 +22,5 @@
|
||||
<!ENTITY inspectorSearchHTML.key "F">
|
||||
|
||||
<!ENTITY inspectorCopyImageDataUri.label "Copy Image Data-URL">
|
||||
|
||||
<!ENTITY inspectorShowDOMProperties.label "Show DOM Properties">
|
||||
|
@ -413,6 +413,16 @@ case "$target" in
|
||||
;;
|
||||
esac
|
||||
|
||||
MOZ_ARG_ENABLE_BOOL(android-resource-constrained,
|
||||
[ --enable-android-resource-constrained
|
||||
exclude hi-res images and similar from the final APK],
|
||||
MOZ_ANDROID_RESOURCE_CONSTRAINED=1)
|
||||
|
||||
if test -n "$MOZ_ANDROID_RESOURCE_CONSTRAINED"; then
|
||||
AC_DEFINE(MOZ_ANDROID_RESOURCE_CONSTRAINED, $MOZ_ANDROID_RESOURCE_CONSTRAINED)
|
||||
AC_SUBST(MOZ_ANDROID_RESOURCE_CONSTRAINED)
|
||||
fi
|
||||
|
||||
MOZ_ARG_WITH_STRING(android-min-sdk,
|
||||
[ --with-android-min-sdk=[VER] Impose a minimum Firefox for Android SDK version],
|
||||
[ MOZ_ANDROID_MIN_SDK_VERSION=$withval ])
|
||||
@ -433,10 +443,12 @@ if test -n "$MOZ_ANDROID_MIN_SDK_VERSION"; then
|
||||
fi
|
||||
|
||||
AC_DEFINE_UNQUOTED(MOZ_ANDROID_MIN_SDK_VERSION, $MOZ_ANDROID_MIN_SDK_VERSION)
|
||||
AC_SUBST(MOZ_ANDROID_MIN_SDK_VERSION)
|
||||
fi
|
||||
|
||||
if test -n "$MOZ_ANDROID_MAX_SDK_VERSION"; then
|
||||
AC_DEFINE_UNQUOTED(MOZ_ANDROID_MAX_SDK_VERSION, $MOZ_ANDROID_MAX_SDK_VERSION)
|
||||
AC_SUBST(MOZ_ANDROID_MAX_SDK_VERSION)
|
||||
fi
|
||||
|
||||
])
|
||||
|
@ -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>
|
||||
|
@ -386,14 +386,35 @@ nsDefaultURIFixup::GetFixupURIInfo(const nsACString& aStringURI, uint32_t aFixup
|
||||
info->mFixupCreatedAlternateURI = MakeAlternateURI(info->mFixedURI);
|
||||
}
|
||||
|
||||
// If there is no relevent dot in the host, do we require the domain to
|
||||
// be whitelisted?
|
||||
if (info->mFixedURI) {
|
||||
if (aFixupFlags & FIXUP_FLAG_REQUIRE_WHITELISTED_HOST) {
|
||||
|
||||
nsAutoCString asciiHost;
|
||||
if (NS_SUCCEEDED(info->mFixedURI->GetAsciiHost(asciiHost)) &&
|
||||
!asciiHost.IsEmpty()) {
|
||||
|
||||
uint32_t dotLoc = uint32_t(asciiHost.FindChar('.'));
|
||||
|
||||
if ((dotLoc == uint32_t(kNotFound) || dotLoc == asciiHost.Length() - 1)) {
|
||||
if (IsDomainWhitelisted(asciiHost, dotLoc)) {
|
||||
info->mPreferredURI = info->mFixedURI;
|
||||
}
|
||||
} else {
|
||||
info->mPreferredURI = info->mFixedURI;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
info->mPreferredURI = info->mFixedURI;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If we still haven't been able to construct a valid URI, try to force a
|
||||
// keyword match. This catches search strings with '.' or ':' in them.
|
||||
if (info->mFixedURI)
|
||||
{
|
||||
info->mPreferredURI = info->mFixedURI;
|
||||
}
|
||||
else if (sFixupKeywords && (aFixupFlags & FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP))
|
||||
{
|
||||
if (sFixupKeywords && (aFixupFlags & FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP)) {
|
||||
rv = KeywordToURI(aStringURI, aPostData, getter_AddRefs(info->mPreferredURI));
|
||||
if (NS_SUCCEEDED(rv) && info->mPreferredURI)
|
||||
{
|
||||
@ -964,26 +985,17 @@ void nsDefaultURIFixup::KeywordURIFixup(const nsACString & aURIString,
|
||||
(dotLoc == lastDotLoc && (dotLoc == 0 || dotLoc == aURIString.Length() - 1))) &&
|
||||
colonLoc == uint32_t(kNotFound) && qMarkLoc == uint32_t(kNotFound))
|
||||
{
|
||||
|
||||
nsAutoCString asciiHost;
|
||||
if (aFixupInfo->mFixedURI &&
|
||||
NS_SUCCEEDED(aFixupInfo->mFixedURI->GetAsciiHost(asciiHost)) &&
|
||||
!asciiHost.IsEmpty())
|
||||
{
|
||||
// Check if this domain is whitelisted as an actual
|
||||
// domain (which will prevent a keyword query)
|
||||
// NB: any processing of the host here should stay in sync with
|
||||
// code in the front-end(s) that set the pref.
|
||||
nsAutoCString pref("browser.fixup.domainwhitelist.");
|
||||
if (dotLoc == aURIString.Length() - 1) {
|
||||
pref.Append(Substring(asciiHost, 0, asciiHost.Length() - 1));
|
||||
} else {
|
||||
pref.Append(asciiHost);
|
||||
}
|
||||
if (Preferences::GetBool(pref.get(), false))
|
||||
{
|
||||
!asciiHost.IsEmpty()) {
|
||||
|
||||
if (IsDomainWhitelisted(asciiHost, dotLoc)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If we get here, we don't have a valid URI, or we did but the
|
||||
// host is not whitelisted, so we do a keyword search *anyway*:
|
||||
rv = KeywordToURI(aFixupInfo->mOriginalInput, aPostData,
|
||||
@ -995,6 +1007,25 @@ void nsDefaultURIFixup::KeywordURIFixup(const nsACString & aURIString,
|
||||
}
|
||||
}
|
||||
|
||||
bool nsDefaultURIFixup::IsDomainWhitelisted(const nsAutoCString aAsciiHost,
|
||||
const uint32_t aDotLoc)
|
||||
{
|
||||
// Check if this domain is whitelisted as an actual
|
||||
// domain (which will prevent a keyword query)
|
||||
// NB: any processing of the host here should stay in sync with
|
||||
// code in the front-end(s) that set the pref.
|
||||
|
||||
nsAutoCString pref("browser.fixup.domainwhitelist.");
|
||||
|
||||
if (aDotLoc == aAsciiHost.Length() - 1) {
|
||||
pref.Append(Substring(aAsciiHost, 0, aAsciiHost.Length() - 1));
|
||||
} else {
|
||||
pref.Append(aAsciiHost);
|
||||
}
|
||||
|
||||
return Preferences::GetBool(pref.get(), false);
|
||||
}
|
||||
|
||||
|
||||
nsresult NS_NewURIFixup(nsIURIFixup **aURIFixup)
|
||||
{
|
||||
|
@ -37,6 +37,8 @@ private:
|
||||
bool PossiblyHostPortUrl(const nsACString& aUrl);
|
||||
bool MakeAlternateURI(nsIURI *aURI);
|
||||
bool IsLikelyFTP(const nsCString& aHostSpec);
|
||||
bool IsDomainWhitelisted(const nsAutoCString aAsciiHost,
|
||||
const uint32_t aDotLoc);
|
||||
};
|
||||
|
||||
class nsDefaultURIFixupInfo : public nsIURIFixupInfo
|
||||
|
@ -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.
|
||||
|
@ -63,7 +63,7 @@ interface nsIURIFixupInfo : nsISupports
|
||||
/**
|
||||
* Interface implemented by objects capable of fixing up strings into URIs
|
||||
*/
|
||||
[scriptable, uuid(80d4932e-bb2e-4afb-98e0-de9cc9ea7d82)]
|
||||
[scriptable, uuid(49298f2b-3630-4874-aecc-522300a7fead)]
|
||||
interface nsIURIFixup : nsISupports
|
||||
{
|
||||
/** No fixup flags. */
|
||||
@ -83,12 +83,18 @@ interface nsIURIFixup : nsISupports
|
||||
const unsigned long FIXUP_FLAGS_MAKE_ALTERNATE_URI = 2;
|
||||
|
||||
/**
|
||||
* For an input that may be just a domain with only 1 level (eg, "mozilla"),
|
||||
* require that the host be whitelisted.
|
||||
*
|
||||
* Overridden by FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP.
|
||||
*/
|
||||
const unsigned long FIXUP_FLAG_REQUIRE_WHITELISTED_HOST = 4;
|
||||
|
||||
/*
|
||||
* Fix common scheme typos.
|
||||
*/
|
||||
const unsigned long FIXUP_FLAG_FIX_SCHEME_TYPOS = 8;
|
||||
|
||||
/* Note that flag 4 is available. */
|
||||
|
||||
/**
|
||||
* Converts an internal URI (e.g. a wyciwyg URI) into one which we can
|
||||
* expose to the user, for example on the URL bar.
|
||||
|
@ -3,7 +3,8 @@ let urifixup = Cc["@mozilla.org/docshell/urifixup;1"].
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
let prefList = ["browser.fixup.typo.scheme", "keyword.enabled"];
|
||||
let prefList = ["browser.fixup.typo.scheme", "keyword.enabled",
|
||||
"browser.fixup.domainwhitelist.whitelisted"];
|
||||
for (let pref of prefList) {
|
||||
Services.prefs.setBoolPref(pref, true);
|
||||
}
|
||||
@ -34,7 +35,8 @@ do_register_cleanup(function() {
|
||||
let flagInputs = [
|
||||
urifixup.FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP,
|
||||
urifixup.FIXUP_FLAGS_MAKE_ALTERNATE_URI,
|
||||
urifixup.FIXUP_FLAG_FIX_SCHEME_TYPOS
|
||||
urifixup.FIXUP_FLAG_FIX_SCHEME_TYPOS,
|
||||
urifixup.FIXUP_FLAG_REQUIRE_WHITELISTED_HOST,
|
||||
];
|
||||
|
||||
flagInputs.concat([
|
||||
@ -44,42 +46,192 @@ flagInputs.concat([
|
||||
flagInputs[0] | flagInputs[1] | flagInputs[2]
|
||||
]);
|
||||
|
||||
let testcases = [
|
||||
["http://www.mozilla.org", "http://www.mozilla.org/", null, false, false],
|
||||
["http://127.0.0.1/", "http://127.0.0.1/", null, false, false],
|
||||
["file:///foo/bar", "file:///foo/bar", null, false, false],
|
||||
["://www.mozilla.org", "http://www.mozilla.org/", null, false, true],
|
||||
["www.mozilla.org", "http://www.mozilla.org/", null, false, true],
|
||||
["http://mozilla/", "http://mozilla/", "http://www.mozilla.com/", false, false],
|
||||
["http://test./", "http://test./", "http://www.test./", false, false],
|
||||
["127.0.0.1", "http://127.0.0.1/", null, false, true],
|
||||
["1234", "http://1234/", "http://www.1234.com/", true, true],
|
||||
["host/foo.txt", "http://host/foo.txt", "http://www.host.com/foo.txt", false, true],
|
||||
["mozilla", "http://mozilla/", "http://www.mozilla.com/", true, true],
|
||||
["test.", "http://test./", "http://www.test./", true, true],
|
||||
[".test", "http://.test/", "http://www..test/", true, true],
|
||||
["mozilla is amazing", null, null, true, true],
|
||||
["mozilla ", "http://mozilla/", "http://www.mozilla.com/", true, true],
|
||||
[" mozilla ", "http://mozilla/", "http://www.mozilla.com/", true, true],
|
||||
["mozilla \\", null, null, true, true],
|
||||
["mozilla \\ foo.txt", null, null, true, true],
|
||||
["mozilla \\\r foo.txt", null, null, true, true],
|
||||
["mozilla\n", "http://mozilla/", "http://www.mozilla.com/", true, true],
|
||||
["mozilla \r\n", "http://mozilla/", "http://www.mozilla.com/", true, true],
|
||||
["moz\r\nfirefox\nos\r", "http://mozfirefoxos/", "http://www.mozfirefoxos.com/", true, true],
|
||||
["moz\r\n firefox\n", null, null, true, true],
|
||||
["", null, null, true, true],
|
||||
["[]", null, null, true, true]
|
||||
];
|
||||
/*
|
||||
The following properties are supported for these test cases:
|
||||
{
|
||||
input: "", // Input string, required
|
||||
fixedURI: "", // Expected fixedURI
|
||||
alternateURI: "", // Expected alternateURI
|
||||
keywordLookup: false, // Whether a keyword lookup is expected
|
||||
protocolChange: false, // Whether a protocol change is expected
|
||||
affectedByWhitelist: false, // Whether the input host is affected by the whitelist
|
||||
inWhitelist: false, // Whether the input host is in the whitelist
|
||||
}
|
||||
*/
|
||||
let testcases = [ {
|
||||
input: "http://www.mozilla.org",
|
||||
fixedURI: "http://www.mozilla.org/",
|
||||
}, {
|
||||
input: "http://127.0.0.1/",
|
||||
fixedURI: "http://127.0.0.1/",
|
||||
}, {
|
||||
input: "file:///foo/bar",
|
||||
fixedURI: "file:///foo/bar",
|
||||
}, {
|
||||
input: "://www.mozilla.org",
|
||||
fixedURI: "http://www.mozilla.org/",
|
||||
protocolChange: true,
|
||||
}, {
|
||||
input: "www.mozilla.org",
|
||||
fixedURI: "http://www.mozilla.org/",
|
||||
protocolChange: true,
|
||||
}, {
|
||||
input: "http://mozilla/",
|
||||
fixedURI: "http://mozilla/",
|
||||
alternateURI: "http://www.mozilla.com/",
|
||||
}, {
|
||||
input: "http://test./",
|
||||
fixedURI: "http://test./",
|
||||
alternateURI: "http://www.test./",
|
||||
}, {
|
||||
input: "127.0.0.1",
|
||||
fixedURI: "http://127.0.0.1/",
|
||||
protocolChange: true,
|
||||
}, {
|
||||
input: "1234",
|
||||
fixedURI: "http://1234/",
|
||||
alternateURI: "http://www.1234.com/",
|
||||
keywordLookup: true,
|
||||
protocolChange: true,
|
||||
affectedByWhitelist: true,
|
||||
}, {
|
||||
input: "host/foo.txt",
|
||||
fixedURI: "http://host/foo.txt",
|
||||
alternateURI: "http://www.host.com/foo.txt",
|
||||
protocolChange: true,
|
||||
affectedByWhitelist: true,
|
||||
}, {
|
||||
input: "mozilla",
|
||||
fixedURI: "http://mozilla/",
|
||||
alternateURI: "http://www.mozilla.com/",
|
||||
keywordLookup: true,
|
||||
protocolChange: true,
|
||||
affectedByWhitelist: true,
|
||||
}, {
|
||||
input: "test.",
|
||||
fixedURI: "http://test./",
|
||||
alternateURI: "http://www.test./",
|
||||
keywordLookup: true,
|
||||
protocolChange: true,
|
||||
affectedByWhitelist: true,
|
||||
}, {
|
||||
input: ".test",
|
||||
fixedURI: "http://.test/",
|
||||
alternateURI: "http://www..test/",
|
||||
keywordLookup: true,
|
||||
protocolChange: true,
|
||||
}, {
|
||||
input: "mozilla is amazing",
|
||||
keywordLookup: true,
|
||||
protocolChange: true,
|
||||
}, {
|
||||
input: "mozilla ",
|
||||
fixedURI: "http://mozilla/",
|
||||
alternateURI: "http://www.mozilla.com/",
|
||||
keywordLookup: true,
|
||||
protocolChange: true,
|
||||
affectedByWhitelist: true,
|
||||
}, {
|
||||
input: " mozilla ",
|
||||
fixedURI: "http://mozilla/",
|
||||
alternateURI: "http://www.mozilla.com/",
|
||||
keywordLookup: true,
|
||||
protocolChange: true,
|
||||
affectedByWhitelist: true,
|
||||
}, {
|
||||
input: "mozilla \\",
|
||||
keywordLookup: true,
|
||||
protocolChange: true,
|
||||
affectedByWhitelist: true,
|
||||
}, {
|
||||
input: "mozilla \\ foo.txt",
|
||||
keywordLookup: true,
|
||||
protocolChange: true,
|
||||
}, {
|
||||
input: "mozilla \\\r foo.txt",
|
||||
keywordLookup: true,
|
||||
protocolChange: true,
|
||||
}, {
|
||||
input: "mozilla\n",
|
||||
fixedURI: "http://mozilla/",
|
||||
alternateURI: "http://www.mozilla.com/",
|
||||
keywordLookup: true,
|
||||
protocolChange: true,
|
||||
affectedByWhitelist: true,
|
||||
}, {
|
||||
input: "mozilla \r\n",
|
||||
fixedURI: "http://mozilla/",
|
||||
alternateURI: "http://www.mozilla.com/",
|
||||
keywordLookup: true,
|
||||
protocolChange: true,
|
||||
affectedByWhitelist: true,
|
||||
}, {
|
||||
input: "moz\r\nfirefox\nos\r",
|
||||
fixedURI: "http://mozfirefoxos/",
|
||||
alternateURI: "http://www.mozfirefoxos.com/",
|
||||
keywordLookup: true,
|
||||
protocolChange: true,
|
||||
affectedByWhitelist: true,
|
||||
}, {
|
||||
input: "moz\r\n firefox\n",
|
||||
keywordLookup: true,
|
||||
protocolChange: true,
|
||||
}, {
|
||||
input: "",
|
||||
keywordLookup: true,
|
||||
protocolChange: true,
|
||||
}, {
|
||||
input: "[]",
|
||||
keywordLookup: true,
|
||||
protocolChange: true,
|
||||
}, {
|
||||
input: "http://whitelisted/",
|
||||
fixedURI: "http://whitelisted/",
|
||||
alternateURI: "http://www.whitelisted.com/",
|
||||
affectedByWhitelist: true,
|
||||
inWhitelist: true,
|
||||
}];
|
||||
|
||||
if (Services.appinfo.OS.toLowerCase().startsWith("win")) {
|
||||
testcases.push(["C:\\some\\file.txt", "file:///C:/some/file.txt", null, false, true]);
|
||||
testcases.push(["//mozilla", "http://mozilla/", "http://www.mozilla.com/", false, true]);
|
||||
testcases.push(["mozilla\\", "http://mozilla/", "http://www.mozilla.com/", true, true]);
|
||||
testcases.push({
|
||||
input: "C:\\some\\file.txt",
|
||||
fixedURI: "file:///C:/some/file.txt",
|
||||
protocolChange: true,
|
||||
});
|
||||
testcases.push({
|
||||
input: "//mozilla",
|
||||
fixedURI: "http://mozilla/",
|
||||
alternateURI: "http://www.mozilla.com/",
|
||||
protocolChange: true,
|
||||
affectedByWhitelist: true,
|
||||
});
|
||||
testcases.push({
|
||||
input: "mozilla\\",
|
||||
fixedURI: "http://mozilla/",
|
||||
alternateURI: "http://www.mozilla.com/",
|
||||
keywordLookup: true,
|
||||
protocolChange: true,
|
||||
affectedByWhitelist: true,
|
||||
});
|
||||
} else {
|
||||
testcases.push(["/some/file.txt", "file:///some/file.txt", null, false, true]);
|
||||
testcases.push(["//mozilla", "file:////mozilla", null, false, true]);
|
||||
testcases.push(["mozilla\\", "http://mozilla\\/", "http://www.mozilla/", true, true]);
|
||||
testcases.push({
|
||||
input: "/some/file.txt",
|
||||
fixedURI: "file:///some/file.txt",
|
||||
protocolChange: true,
|
||||
});
|
||||
testcases.push({
|
||||
input: "//mozilla",
|
||||
fixedURI: "file:////mozilla",
|
||||
protocolChange: true,
|
||||
});
|
||||
testcases.push({
|
||||
input: "mozilla\\",
|
||||
fixedURI: "http://mozilla\\/",
|
||||
alternateURI: "http://www.mozilla/",
|
||||
keywordLookup: true,
|
||||
protocolChange: true,
|
||||
affectedByWhitelist: true,
|
||||
});
|
||||
}
|
||||
|
||||
function sanitize(input) {
|
||||
@ -87,8 +239,20 @@ function sanitize(input) {
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
for (let [testInput, expectedFixedURI, alternativeURI,
|
||||
expectKeywordLookup, expectProtocolChange] of testcases) {
|
||||
for (let { input: testInput,
|
||||
fixedURI: expectedFixedURI,
|
||||
alternateURI: alternativeURI,
|
||||
keywordLookup: expectKeywordLookup,
|
||||
protocolChange: expectProtocolChange,
|
||||
affectedByWhitelist: affectedByWhitelist,
|
||||
inWhitelist: inWhitelist } of testcases) {
|
||||
|
||||
// Explicitly force these into a boolean
|
||||
expectKeywordLookup = !!expectKeywordLookup;
|
||||
expectProtocolChange = !!expectProtocolChange;
|
||||
affectedByWhitelist = !!affectedByWhitelist;
|
||||
inWhitelist = !!inWhitelist;
|
||||
|
||||
for (let flags of flagInputs) {
|
||||
let info;
|
||||
let fixupURIOnly = null;
|
||||
@ -109,10 +273,12 @@ function run_test() {
|
||||
continue;
|
||||
}
|
||||
|
||||
do_print("Checking " + testInput + " with flags " + flags);
|
||||
do_print("Checking \"" + testInput + "\" with flags " + flags);
|
||||
|
||||
// Both APIs should then also be using the same spec.
|
||||
do_check_eq(fixupURIOnly.spec, info.preferredURI.spec);
|
||||
do_check_eq(!!fixupURIOnly, !!info.preferredURI);
|
||||
if (fixupURIOnly)
|
||||
do_check_eq(fixupURIOnly.spec, info.preferredURI.spec);
|
||||
|
||||
let isFileURL = expectedFixedURI && expectedFixedURI.startsWith("file");
|
||||
|
||||
@ -131,10 +297,25 @@ function run_test() {
|
||||
do_check_eq(info.fixupCreatedAlternateURI, makeAlternativeURI && alternativeURI != null);
|
||||
|
||||
// Check the preferred URI
|
||||
if (couldDoKeywordLookup && expectKeywordLookup) {
|
||||
let requiresWhitelistedDomain = flags & urifixup.FIXUP_FLAG_REQUIRE_WHITELISTED_HOST
|
||||
if (couldDoKeywordLookup) {
|
||||
if (expectKeywordLookup) {
|
||||
if (!affectedByWhitelist || (affectedByWhitelist && !inWhitelist)) {
|
||||
let urlparamInput = encodeURIComponent(sanitize(testInput)).replace("%20", "+", "g");
|
||||
let searchURL = kSearchEngineURL.replace("{searchTerms}", urlparamInput);
|
||||
do_check_eq(info.preferredURI.spec, searchURL);
|
||||
} else {
|
||||
do_check_eq(info.preferredURI, null);
|
||||
}
|
||||
} else {
|
||||
do_check_eq(info.preferredURI.spec, info.fixedURI.spec);
|
||||
}
|
||||
} else if (requiresWhitelistedDomain) {
|
||||
// Not a keyword search, but we want to enforce the host whitelist
|
||||
if (!affectedByWhitelist || (affectedByWhitelist && inWhitelist))
|
||||
do_check_eq(info.preferredURI.spec, info.fixedURI.spec);
|
||||
else
|
||||
do_check_eq(info.preferredURI, null);
|
||||
} else {
|
||||
// In these cases, we should never be doing a keyword lookup and
|
||||
// the fixed URI should be preferred:
|
||||
|
@ -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;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user