mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 15:52:07 +00:00
Merge mozilla-central to mozilla-inbound
This commit is contained in:
commit
9c7a020058
@ -107,7 +107,9 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(DocAccessible, Accessible)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNotificationController)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVirtualCursor)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChildDocuments)
|
||||
tmp->mDependentIDsHash.EnumerateRead(CycleCollectorTraverseDepIDsEntry, &cb);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAccessibleCache)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAnchorJumpElm)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(DocAccessible, Accessible)
|
||||
@ -117,6 +119,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(DocAccessible, Accessible)
|
||||
tmp->mDependentIDsHash.Clear();
|
||||
tmp->mNodeToAccessibleMap.Clear();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mAccessibleCache)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mAnchorJumpElm)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(DocAccessible)
|
||||
@ -1981,3 +1984,25 @@ DocAccessible::IsLoadEventTarget() const
|
||||
return (contentType == nsIDocShellTreeItem::typeContent);
|
||||
}
|
||||
|
||||
PLDHashOperator
|
||||
DocAccessible::CycleCollectorTraverseDepIDsEntry(const nsAString& aKey,
|
||||
AttrRelProviderArray* aProviders,
|
||||
void* aUserArg)
|
||||
{
|
||||
nsCycleCollectionTraversalCallback* cb =
|
||||
static_cast<nsCycleCollectionTraversalCallback*>(aUserArg);
|
||||
|
||||
for (int32_t jdx = aProviders->Length() - 1; jdx >= 0; jdx--) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb,
|
||||
"content of dependent ids hash entry of document accessible");
|
||||
|
||||
AttrRelProvider* provider = (*aProviders)[jdx];
|
||||
cb->NoteXPCOMChild(provider->mContent);
|
||||
|
||||
NS_ASSERTION(provider->mContent->IsInDoc(),
|
||||
"Referred content is not in document!");
|
||||
}
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
|
@ -561,11 +561,19 @@ protected:
|
||||
AttrRelProvider& operator =(const AttrRelProvider&);
|
||||
};
|
||||
|
||||
typedef nsTArray<nsAutoPtr<AttrRelProvider> > AttrRelProviderArray;
|
||||
typedef nsClassHashtable<nsStringHashKey, AttrRelProviderArray>
|
||||
DependentIDsHashtable;
|
||||
|
||||
/**
|
||||
* The cache of IDs pointed by relation attributes.
|
||||
*/
|
||||
typedef nsTArray<nsAutoPtr<AttrRelProvider> > AttrRelProviderArray;
|
||||
nsClassHashtable<nsStringHashKey, AttrRelProviderArray> mDependentIDsHash;
|
||||
DependentIDsHashtable mDependentIDsHash;
|
||||
|
||||
static PLDHashOperator
|
||||
CycleCollectorTraverseDepIDsEntry(const nsAString& aKey,
|
||||
AttrRelProviderArray* aProviders,
|
||||
void* aUserArg);
|
||||
|
||||
friend class RelatedAccIterator;
|
||||
|
||||
|
@ -3,10 +3,10 @@
|
||||
* 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 "mozilla/DebugOnly.h"
|
||||
|
||||
#include "HTMLTableAccessible.h"
|
||||
|
||||
#include "mozilla/DebugOnly.h"
|
||||
|
||||
#include "Accessible-inl.h"
|
||||
#include "nsAccessibilityService.h"
|
||||
#include "nsAccUtils.h"
|
||||
@ -18,6 +18,7 @@
|
||||
#include "States.h"
|
||||
#include "TreeWalker.h"
|
||||
|
||||
#include "mozilla/dom/HTMLTableElement.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMRange.h"
|
||||
@ -25,10 +26,6 @@
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIDOMNodeList.h"
|
||||
#include "nsIDOMHTMLCollection.h"
|
||||
#include "nsIDOMHTMLTableCellElement.h"
|
||||
#include "nsIDOMHTMLTableElement.h"
|
||||
#include "nsIDOMHTMLTableRowElement.h"
|
||||
#include "nsIDOMHTMLTableSectionElement.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIMutableArray.h"
|
||||
#include "nsIPresShell.h"
|
||||
@ -455,7 +452,7 @@ HTMLTableAccessible::Caption()
|
||||
void
|
||||
HTMLTableAccessible::Summary(nsString& aSummary)
|
||||
{
|
||||
nsCOMPtr<nsIDOMHTMLTableElement> table(do_QueryInterface(mContent));
|
||||
dom::HTMLTableElement* table = dom::HTMLTableElement::FromContent(mContent);
|
||||
|
||||
if (table)
|
||||
table->GetSummary(aSummary);
|
||||
|
@ -351,14 +351,15 @@ let SocialChatBar = {
|
||||
return !!this.chatbar.firstElementChild;
|
||||
},
|
||||
openChat: function(aProvider, aURL, aCallback, aMode) {
|
||||
if (this.isAvailable) {
|
||||
this.chatbar.openChat(aProvider, aURL, aCallback, aMode);
|
||||
// We only want to focus the chat if it is as a result of user input.
|
||||
let dwu = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
if (dwu.isHandlingUserInput)
|
||||
this.chatbar.focus();
|
||||
}
|
||||
if (!this.isAvailable)
|
||||
return false;
|
||||
this.chatbar.openChat(aProvider, aURL, aCallback, aMode);
|
||||
// We only want to focus the chat if it is as a result of user input.
|
||||
let dwu = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
if (dwu.isHandlingUserInput)
|
||||
this.chatbar.focus();
|
||||
return true;
|
||||
},
|
||||
update: function() {
|
||||
let command = document.getElementById("Social:FocusChat");
|
||||
|
@ -627,4 +627,5 @@ chatbox {
|
||||
chatbar {
|
||||
-moz-binding: url("chrome://browser/content/socialchat.xml#chatbar");
|
||||
height: 0;
|
||||
max-height: 0;
|
||||
}
|
||||
|
@ -248,6 +248,19 @@ var tests = {
|
||||
// cause focus to move between all elements in our chat window before moving
|
||||
// to the next chat window.
|
||||
testTab: function(next) {
|
||||
function sendTabAndWaitForFocus(chat, eltid, callback) {
|
||||
// ideally we would use the 'focus' event here, but that doesn't work
|
||||
// as expected for the iframe - the iframe itself never gets the focus
|
||||
// event (apparently the sub-document etc does.)
|
||||
// So just poll for the correct element getting focus...
|
||||
let doc = chat.iframe.contentDocument;
|
||||
EventUtils.sendKey("tab");
|
||||
waitForCondition(function() {
|
||||
let elt = eltid ? doc.getElementById(eltid) : doc.documentElement;
|
||||
return doc.activeElement == elt;
|
||||
}, callback, "element " + eltid + " never got focus");
|
||||
}
|
||||
|
||||
let chatbar = SocialChatBar.chatbar;
|
||||
startTestAndWaitForSidebar(function(port) {
|
||||
openChatViaSidebarMessage(port, {id: 1}, function() {
|
||||
@ -259,22 +272,27 @@ var tests = {
|
||||
ok(isChatFocused(chat2), "new chat is focused");
|
||||
// Our chats have 3 focusable elements, so it takes 4 TABs to move
|
||||
// to the new chat.
|
||||
EventUtils.sendKey("tab");
|
||||
ok(isChatFocused(chat2), "new chat still focused after first tab");
|
||||
is(chat2.iframe.contentDocument.activeElement.getAttribute("id"), "input1",
|
||||
"first input field has focus");
|
||||
EventUtils.sendKey("tab");
|
||||
ok(isChatFocused(chat2), "new chat still focused after tab");
|
||||
is(chat2.iframe.contentDocument.activeElement.getAttribute("id"), "input2",
|
||||
"second input field has focus");
|
||||
EventUtils.sendKey("tab");
|
||||
ok(isChatFocused(chat2), "new chat still focused after tab");
|
||||
is(chat2.iframe.contentDocument.activeElement.getAttribute("id"), "iframe",
|
||||
"iframe has focus");
|
||||
// this tab now should move to the next chat.
|
||||
EventUtils.sendKey("tab");
|
||||
ok(isChatFocused(chat1), "first chat is focused");
|
||||
next();
|
||||
sendTabAndWaitForFocus(chat2, "input1", function() {
|
||||
is(chat2.iframe.contentDocument.activeElement.getAttribute("id"), "input1",
|
||||
"first input field has focus");
|
||||
ok(isChatFocused(chat2), "new chat still focused after first tab");
|
||||
sendTabAndWaitForFocus(chat2, "input2", function() {
|
||||
ok(isChatFocused(chat2), "new chat still focused after tab");
|
||||
is(chat2.iframe.contentDocument.activeElement.getAttribute("id"), "input2",
|
||||
"second input field has focus");
|
||||
sendTabAndWaitForFocus(chat2, "iframe", function() {
|
||||
ok(isChatFocused(chat2), "new chat still focused after tab");
|
||||
is(chat2.iframe.contentDocument.activeElement.getAttribute("id"), "iframe",
|
||||
"iframe has focus");
|
||||
// this tab now should move to the next chat, but focus the
|
||||
// document element itself (hence the null eltid)
|
||||
sendTabAndWaitForFocus(chat1, null, function() {
|
||||
ok(isChatFocused(chat1), "first chat is focused");
|
||||
next();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -122,7 +122,7 @@ var MigrationWizard = {
|
||||
this._selectedProfile = null;
|
||||
}
|
||||
this._source = newSource;
|
||||
|
||||
|
||||
// check for more than one source profile
|
||||
var sourceProfiles = this._migrator.sourceProfiles;
|
||||
if (sourceProfiles && sourceProfiles.length > 1) {
|
||||
|
@ -11,6 +11,9 @@ var gTab = null;
|
||||
var gDebuggee = null;
|
||||
|
||||
function test() {
|
||||
// Windows XP test slaves are terribly slow at this test.
|
||||
requestLongerTimeout(2);
|
||||
|
||||
debug_chrome(STACK_URL, aOnClosing, function(aTab, aDebuggee, aProcess) {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
|
@ -31,7 +31,7 @@ BROWSER_TESTS = \
|
||||
$(NULL)
|
||||
|
||||
BROWSER_TEST_RESOURCES = \
|
||||
res\image01.png \
|
||||
res/image01.png \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(BROWSER_TESTS)
|
||||
|
@ -474,6 +474,7 @@ user_pref("app.update.staging.enabled", false);
|
||||
user_pref("browser.panorama.experienced_first_run", true); // Assume experienced
|
||||
user_pref("dom.w3c_touch_events.enabled", 1);
|
||||
user_pref("dom.undo_manager.enabled", true);
|
||||
user_pref("dom.webcomponents.enabled", true);
|
||||
// Set a future policy version to avoid the telemetry prompt.
|
||||
user_pref("toolkit.telemetry.prompted", 999);
|
||||
user_pref("toolkit.telemetry.notifiedOptOut", 999);
|
||||
|
@ -105,6 +105,7 @@ public class FennecNativeActions implements Actions {
|
||||
private final String mGeckoEvent;
|
||||
private final Object[] mRegistrationParams;
|
||||
private boolean mEventReceived;
|
||||
private boolean mEventEverReceived;
|
||||
private String mEventData;
|
||||
private static final int MAX_WAIT_MS = 90000;
|
||||
|
||||
@ -140,6 +141,7 @@ public class FennecNativeActions implements Actions {
|
||||
}
|
||||
FennecNativeDriver.log(FennecNativeDriver.LogLevel.DEBUG,
|
||||
"unblocked on expecter for " + mGeckoEvent);
|
||||
mEventReceived = false;
|
||||
}
|
||||
|
||||
public synchronized void blockUntilClear(long millis) {
|
||||
@ -189,6 +191,7 @@ public class FennecNativeActions implements Actions {
|
||||
}
|
||||
FennecNativeDriver.log(FennecNativeDriver.LogLevel.DEBUG,
|
||||
"unblocked on expecter for " + mGeckoEvent);
|
||||
mEventReceived = false;
|
||||
}
|
||||
|
||||
public synchronized String blockForEventData() {
|
||||
@ -197,7 +200,7 @@ public class FennecNativeActions implements Actions {
|
||||
}
|
||||
|
||||
public synchronized boolean eventReceived() {
|
||||
return mEventReceived;
|
||||
return mEventEverReceived;
|
||||
}
|
||||
|
||||
void notifyOfEvent(Object[] args) {
|
||||
@ -205,6 +208,7 @@ public class FennecNativeActions implements Actions {
|
||||
"received event " + mGeckoEvent);
|
||||
synchronized (this) {
|
||||
mEventReceived = true;
|
||||
mEventEverReceived = true;
|
||||
mEventData = args[1].toString();
|
||||
this.notifyAll();
|
||||
}
|
||||
|
@ -92,6 +92,7 @@ class DocumentFragment;
|
||||
class DocumentType;
|
||||
class DOMImplementation;
|
||||
class Element;
|
||||
struct ElementRegistrationOptions;
|
||||
class GlobalObject;
|
||||
class HTMLBodyElement;
|
||||
class Link;
|
||||
@ -1910,6 +1911,10 @@ public:
|
||||
{
|
||||
return GetRootElement();
|
||||
}
|
||||
virtual JSObject*
|
||||
Register(JSContext* aCx, const nsAString& aName,
|
||||
const mozilla::dom::ElementRegistrationOptions& aOptions,
|
||||
mozilla::ErrorResult& rv) = 0;
|
||||
already_AddRefed<nsContentList>
|
||||
GetElementsByTagName(const nsAString& aTagName)
|
||||
{
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsIScriptRuntime.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsDOMClassInfo.h"
|
||||
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsAsyncDOMEvent.h"
|
||||
@ -138,10 +139,12 @@
|
||||
#include "nsIPrompt.h"
|
||||
#include "nsIPropertyBag2.h"
|
||||
#include "nsIDOMPageTransitionEvent.h"
|
||||
#include "nsJSUtils.h"
|
||||
#include "nsFrameLoader.h"
|
||||
#include "nsEscape.h"
|
||||
#include "nsObjectLoadingContent.h"
|
||||
#include "nsHtml5TreeOpExecutor.h"
|
||||
#include "nsIDOMElementReplaceEvent.h"
|
||||
#ifdef MOZ_MEDIA
|
||||
#include "nsHTMLMediaElement.h"
|
||||
#endif // MOZ_MEDIA
|
||||
@ -171,8 +174,10 @@
|
||||
#include "mozilla/dom/Comment.h"
|
||||
#include "nsTextNode.h"
|
||||
#include "mozilla/dom/Link.h"
|
||||
#include "mozilla/dom/HTMLElementBinding.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "nsDOMTouchEvent.h"
|
||||
#include "DictionaryHelpers.h"
|
||||
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
@ -183,6 +188,7 @@
|
||||
#include "nsIAppsService.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/DocumentFragment.h"
|
||||
#include "mozilla/dom/WebComponentsBinding.h"
|
||||
#include "mozilla/dom/HTMLBodyElement.h"
|
||||
#include "mozilla/dom/NodeFilterBinding.h"
|
||||
#include "mozilla/dom/UndoManager.h"
|
||||
@ -1372,6 +1378,13 @@ nsDocument::~nsDocument()
|
||||
mInDestructor = true;
|
||||
mInUnlinkOrDeletion = true;
|
||||
|
||||
mCustomPrototypes.Clear();
|
||||
|
||||
nsISupports* supports;
|
||||
QueryInterface(NS_GET_IID(nsCycleCollectionISupports), reinterpret_cast<void**>(&supports));
|
||||
NS_ASSERTION(supports, "Failed to QI to nsCycleCollectionISupports?!");
|
||||
nsContentUtils::DropJSObjects(supports);
|
||||
|
||||
// Clear mObservers to keep it in sync with the mutationobserver list
|
||||
mObservers.Clear();
|
||||
|
||||
@ -1478,6 +1491,7 @@ NS_INTERFACE_TABLE_HEAD(nsDocument)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIDOMDocumentTouch)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsDocument, nsITouchEventReceiver)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIInlineEventHandlers)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIDocumentRegister)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIObserver)
|
||||
NS_OFFSET_AND_INTERFACE_TABLE_END
|
||||
NS_OFFSET_AND_INTERFACE_TABLE_TO_MAP_SEGUE
|
||||
@ -1716,7 +1730,25 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
|
||||
struct CustomPrototypeTraceArgs {
|
||||
TraceCallback callback;
|
||||
void* closure;
|
||||
};
|
||||
|
||||
|
||||
static PLDHashOperator
|
||||
CustomPrototypeTrace(const nsAString& aName, JSObject* aObject, void *aArg)
|
||||
{
|
||||
CustomPrototypeTraceArgs* traceArgs = static_cast<CustomPrototypeTraceArgs*>(aArg);
|
||||
MOZ_ASSERT(aObject, "Protocol object value must not be null");
|
||||
traceArgs->callback(aObject, "mCustomPrototypes entry", traceArgs->closure);
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsDocument)
|
||||
CustomPrototypeTraceArgs customPrototypeArgs = { aCallback, aClosure };
|
||||
tmp->mCustomPrototypes.EnumerateRead(CustomPrototypeTrace, &customPrototypeArgs);
|
||||
nsINode::Trace(tmp, aCallback, aClosure);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
@ -1781,6 +1813,8 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDocument)
|
||||
|
||||
tmp->mIdentifierMap.Clear();
|
||||
|
||||
tmp->mCustomPrototypes.Clear();
|
||||
|
||||
if (tmp->mAnimationController) {
|
||||
tmp->mAnimationController->Unlink();
|
||||
}
|
||||
@ -1805,6 +1839,7 @@ nsDocument::Init()
|
||||
mIdentifierMap.Init();
|
||||
mStyledLinks.Init();
|
||||
mRadioGroups.Init();
|
||||
mCustomPrototypes.Init();
|
||||
|
||||
// Force initialization.
|
||||
nsINode::nsSlots* slots = Slots();
|
||||
@ -1841,6 +1876,15 @@ nsDocument::Init()
|
||||
mImageTracker.Init();
|
||||
mPlugins.Init();
|
||||
|
||||
nsXPCOMCycleCollectionParticipant* participant;
|
||||
CallQueryInterface(this, &participant);
|
||||
NS_ASSERTION(participant, "Failed to QI to nsXPCOMCycleCollectionParticipant!");
|
||||
|
||||
nsISupports* thisSupports;
|
||||
QueryInterface(NS_GET_IID(nsCycleCollectionISupports), reinterpret_cast<void**>(&thisSupports));
|
||||
NS_ASSERTION(thisSupports, "Failed to QI to nsCycleCollectionISupports!");
|
||||
nsContentUtils::HoldJSObjects(thisSupports, participant);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1961,6 +2005,8 @@ nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup,
|
||||
mInUnlinkOrDeletion = oldVal;
|
||||
mCachedRootElement = nullptr;
|
||||
|
||||
mCustomPrototypes.Clear();
|
||||
|
||||
// Reset our stylesheets
|
||||
ResetStylesheetsToURI(aURI);
|
||||
|
||||
@ -4845,6 +4891,205 @@ nsIDocument::CreateAttributeNS(const nsAString& aNamespaceURI,
|
||||
return attribute.forget();
|
||||
}
|
||||
|
||||
static JSBool
|
||||
CustomElementConstructor(JSContext *aCx, unsigned aArgc, JS::Value* aVp)
|
||||
{
|
||||
JS::Value calleeVal = JS_CALLEE(aCx, aVp);
|
||||
|
||||
JSObject* global = JS_GetGlobalForObject(aCx, &calleeVal.toObject());
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryWrapper(aCx, global);
|
||||
MOZ_ASSERT(window, "Should have a non-null window");
|
||||
|
||||
nsIDocument* document = window->GetDoc();
|
||||
|
||||
// Function name is the type of the custom element.
|
||||
JSString* jsFunName = JS_GetFunctionId(JS_ValueToFunction(aCx, calleeVal));
|
||||
nsDependentJSString elemName;
|
||||
if (!elemName.init(aCx, jsFunName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> newElement;
|
||||
nsresult rv = document->CreateElem(elemName, nullptr, kNameSpaceID_XHTML,
|
||||
getter_AddRefs(newElement));
|
||||
JS::Value v;
|
||||
rv = nsContentUtils::WrapNative(aCx, global, newElement, newElement, &v);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
JS_SET_RVAL(aCx, aVp, v);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
nsDocument::RegisterEnabled()
|
||||
{
|
||||
static bool sPrefValue =
|
||||
Preferences::GetBool("dom.webcomponents.enabled", false);
|
||||
return sPrefValue;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocument::Register(const nsAString& aName, const JS::Value& aOptions,
|
||||
JSContext* aCx, uint8_t aOptionalArgc,
|
||||
jsval* aConstructor /* out param */)
|
||||
{
|
||||
ElementRegistrationOptions options;
|
||||
if (aOptionalArgc > 0) {
|
||||
JSAutoCompartment ac(aCx, GetWrapper());
|
||||
NS_ENSURE_TRUE(JS_WrapValue(aCx, const_cast<JS::Value*>(&aOptions)),
|
||||
NS_ERROR_UNEXPECTED);
|
||||
NS_ENSURE_TRUE(options.Init(aCx, nullptr, aOptions),
|
||||
NS_ERROR_UNEXPECTED);
|
||||
}
|
||||
|
||||
ErrorResult rv;
|
||||
JSObject* object = Register(aCx, aName, options, rv);
|
||||
if (rv.Failed()) {
|
||||
return rv.ErrorCode();
|
||||
}
|
||||
NS_ENSURE_TRUE(object, NS_ERROR_UNEXPECTED);
|
||||
|
||||
*aConstructor = OBJECT_TO_JSVAL(object);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
JSObject*
|
||||
nsDocument::Register(JSContext* aCx, const nsAString& aName,
|
||||
const ElementRegistrationOptions& aOptions,
|
||||
ErrorResult& rv)
|
||||
{
|
||||
nsAutoString lcName;
|
||||
nsContentUtils::ASCIIToLower(aName, lcName);
|
||||
if (!StringBeginsWith(lcName, NS_LITERAL_STRING("x-"))) {
|
||||
rv.Throw(NS_ERROR_DOM_INVALID_CHARACTER_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
if (NS_FAILED(nsContentUtils::CheckQName(lcName, false))) {
|
||||
rv.Throw(NS_ERROR_DOM_INVALID_CHARACTER_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsIScriptGlobalObject* sgo = GetScopeObject();
|
||||
if (!sgo) {
|
||||
rv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
JSObject* global = sgo->GetGlobalJSObject();
|
||||
|
||||
JSAutoCompartment ac(aCx, global);
|
||||
|
||||
JSObject* htmlProto = HTMLElementBinding::GetProtoObject(aCx, global);
|
||||
if (!htmlProto) {
|
||||
rv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JSObject* protoObject;
|
||||
if (!aOptions.mPrototype) {
|
||||
protoObject = JS_NewObject(aCx, NULL, htmlProto, NULL);
|
||||
if (!protoObject) {
|
||||
rv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
// If a prototype is provided, we must check to ensure that it inherits
|
||||
// from HTMLElement.
|
||||
protoObject = aOptions.mPrototype;
|
||||
if (!JS_WrapObject(aCx, &protoObject)) {
|
||||
rv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Check the proto chain for HTMLElement prototype.
|
||||
JSObject* protoProto;
|
||||
if (!JS_GetPrototype(aCx, protoObject, &protoProto)) {
|
||||
rv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
while (protoProto) {
|
||||
if (protoProto == htmlProto) {
|
||||
break;
|
||||
}
|
||||
if (!JS_GetPrototype(aCx, protoProto, &protoProto)) {
|
||||
rv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (!protoProto) {
|
||||
rv.Throw(NS_ERROR_DOM_TYPE_MISMATCH_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Associate the prototype with the custom element.
|
||||
mCustomPrototypes.Put(lcName, protoObject);
|
||||
|
||||
// Do element upgrade.
|
||||
nsRefPtr<nsContentList> list = GetElementsByTagName(lcName);
|
||||
for (int32_t i = 0; i < list->Length(false); i++) {
|
||||
nsCOMPtr<nsINode> oldNode = list->Item(i, false);
|
||||
|
||||
// TODO(wchen): Perform upgrade on Shadow DOM when implemented.
|
||||
// Bug 806506.
|
||||
nsCOMPtr<nsINode> newNode;
|
||||
rv = nsNodeUtils::Clone(oldNode, true, getter_AddRefs(newNode));
|
||||
if (rv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsINode* parentNode = oldNode->GetParentNode();
|
||||
MOZ_ASSERT(parentNode, "Node obtained by GetElementsByTagName.");
|
||||
nsCOMPtr<nsIDOMElement> newElement = do_QueryInterface(newNode);
|
||||
MOZ_ASSERT(newElement, "Cloned of node obtained by GetElementsByTagName.");
|
||||
|
||||
parentNode->ReplaceChild(*newNode, *oldNode, rv);
|
||||
if (rv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Dispatch elementreplaced to replaced elements.
|
||||
nsCOMPtr<nsIDOMEvent> event;
|
||||
rv = CreateEvent(NS_LITERAL_STRING("elementreplace"), getter_AddRefs(event));
|
||||
if (rv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aOptions.mLifecycle.mCreated) {
|
||||
// Don't abort the upgrade algorithm if the callback throws an
|
||||
// exception.
|
||||
ErrorResult dummy;
|
||||
aOptions.mLifecycle.mCreated->Call(newElement, dummy);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMElementReplaceEvent> ptEvent = do_QueryInterface(event);
|
||||
MOZ_ASSERT(ptEvent);
|
||||
|
||||
rv = ptEvent->InitElementReplaceEvent(NS_LITERAL_STRING("elementreplace"),
|
||||
false, false, newElement);
|
||||
if (rv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
event->SetTrusted(true);
|
||||
event->SetTarget(oldNode);
|
||||
nsEventDispatcher::DispatchDOMEvent(oldNode, nullptr, event,
|
||||
nullptr, nullptr);
|
||||
}
|
||||
|
||||
nsContentUtils::DispatchTrustedEvent(this, static_cast<nsIDocument*>(this),
|
||||
NS_LITERAL_STRING("elementupgrade"),
|
||||
true, true);
|
||||
|
||||
// Create constructor to return. Store the name of the custom element as the
|
||||
// name of the function.
|
||||
JSFunction* constructor = JS_NewFunction(aCx, CustomElementConstructor, 0,
|
||||
JSFUN_CONSTRUCTOR, nullptr,
|
||||
NS_ConvertUTF16toUTF8(lcName).get());
|
||||
JSObject* constructorObject = JS_GetFunctionObject(constructor);
|
||||
return constructorObject;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocument::GetElementsByTagName(const nsAString& aTagname,
|
||||
nsIDOMNodeList** aReturn)
|
||||
@ -7427,6 +7672,8 @@ nsDocument::Destroy()
|
||||
// tearing down all those frame trees right now is the right thing to do.
|
||||
mExternalResourceMap.Shutdown();
|
||||
|
||||
mCustomPrototypes.Clear();
|
||||
|
||||
// XXX We really should let cycle collection do this, but that currently still
|
||||
// leaks (see https://bugzilla.mozilla.org/show_bug.cgi?id=406684).
|
||||
nsContentUtils::ReleaseWrapper(static_cast<nsINode*>(this), this);
|
||||
|
@ -62,6 +62,7 @@
|
||||
#include "nsIProgressEventSink.h"
|
||||
#include "nsISecurityEventSink.h"
|
||||
#include "nsIChannelEventSink.h"
|
||||
#include "nsIDocumentRegister.h"
|
||||
#include "imgIRequest.h"
|
||||
#include "mozilla/dom/DOMImplementation.h"
|
||||
#include "nsIDOMTouchEvent.h"
|
||||
@ -480,6 +481,7 @@ class nsDocument : public nsIDocument,
|
||||
public nsStubMutationObserver,
|
||||
public nsIDOMDocumentTouch,
|
||||
public nsIInlineEventHandlers,
|
||||
public nsIDocumentRegister,
|
||||
public nsIObserver
|
||||
{
|
||||
public:
|
||||
@ -779,6 +781,9 @@ public:
|
||||
// nsIInlineEventHandlers
|
||||
NS_DECL_NSIINLINEEVENTHANDLERS
|
||||
|
||||
// nsIDocumentRegister
|
||||
NS_DECL_NSIDOCUMENTREGISTER
|
||||
|
||||
// nsIObserver
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
@ -1013,9 +1018,22 @@ public:
|
||||
|
||||
virtual nsIDOMNode* AsDOMNode() { return this; }
|
||||
|
||||
JSObject* GetCustomPrototype(const nsAString& aElementName)
|
||||
{
|
||||
JSObject* prototype = nullptr;
|
||||
mCustomPrototypes.Get(aElementName, &prototype);
|
||||
return prototype;
|
||||
}
|
||||
|
||||
static bool RegisterEnabled();
|
||||
|
||||
// WebIDL bits
|
||||
virtual mozilla::dom::DOMImplementation*
|
||||
GetImplementation(mozilla::ErrorResult& rv);
|
||||
virtual JSObject*
|
||||
Register(JSContext* aCx, const nsAString& aName,
|
||||
const mozilla::dom::ElementRegistrationOptions& aOptions,
|
||||
mozilla::ErrorResult& rv);
|
||||
virtual nsIDOMStyleSheetList* StyleSheets();
|
||||
virtual void SetSelectedStyleSheetSet(const nsAString& aSheetSet);
|
||||
virtual void GetLastStyleSheetSet(nsString& aSheetSet);
|
||||
@ -1184,6 +1202,10 @@ protected:
|
||||
// non-null when this document is in fullscreen mode.
|
||||
nsWeakPtr mFullscreenRoot;
|
||||
|
||||
// Hashtable for custom element prototypes in web components.
|
||||
// Custom prototypes are in the document's compartment.
|
||||
nsDataHashtable<nsStringHashKey, JSObject*> mCustomPrototypes;
|
||||
|
||||
nsRefPtr<nsEventListenerManager> mListenerManager;
|
||||
nsCOMPtr<nsIDOMStyleSheetList> mDOMStyleSheets;
|
||||
nsRefPtr<nsDOMStyleSheetSetList> mStyleSheetSetList;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 sw=2 et tw=79: */
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
@ -2032,7 +2032,7 @@ nsINode::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
|
||||
|
||||
// Measurement of the following members may be added later if DMD finds it is
|
||||
// worthwhile:
|
||||
// - mNodeInfo (Nb: allocated in nsNodeInfo.cpp with a nsFixedSizeAllocator)
|
||||
// - mNodeInfo
|
||||
// - mSlots
|
||||
//
|
||||
// The following members are not measured:
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
@ -24,7 +25,6 @@
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include NEW_H
|
||||
#include "nsFixedSizeAllocator.h"
|
||||
#include "prprf.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsGkAtoms.h"
|
||||
@ -32,43 +32,6 @@
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
static const size_t kNodeInfoPoolSizes[] = {
|
||||
sizeof(nsNodeInfo)
|
||||
};
|
||||
|
||||
static const int32_t kNodeInfoPoolInitialSize = sizeof(nsNodeInfo) * 64;
|
||||
|
||||
// static
|
||||
nsFixedSizeAllocator* nsNodeInfo::sNodeInfoPool = nullptr;
|
||||
|
||||
// static
|
||||
nsNodeInfo*
|
||||
nsNodeInfo::Create(nsIAtom *aName, nsIAtom *aPrefix, int32_t aNamespaceID,
|
||||
uint16_t aNodeType, nsIAtom *aExtraName,
|
||||
nsNodeInfoManager *aOwnerManager)
|
||||
{
|
||||
if (!sNodeInfoPool) {
|
||||
sNodeInfoPool = new nsFixedSizeAllocator();
|
||||
if (!sNodeInfoPool)
|
||||
return nullptr;
|
||||
|
||||
nsresult rv = sNodeInfoPool->Init("NodeInfo Pool", kNodeInfoPoolSizes,
|
||||
1, kNodeInfoPoolInitialSize);
|
||||
if (NS_FAILED(rv)) {
|
||||
delete sNodeInfoPool;
|
||||
sNodeInfoPool = nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new one
|
||||
void* place = sNodeInfoPool->Alloc(sizeof(nsNodeInfo));
|
||||
return place ?
|
||||
new (place) nsNodeInfo(aName, aPrefix, aNamespaceID, aNodeType, aExtraName,
|
||||
aOwnerManager) :
|
||||
nullptr;
|
||||
}
|
||||
|
||||
nsNodeInfo::~nsNodeInfo()
|
||||
{
|
||||
mOwnerManager->RemoveNodeInfo(this);
|
||||
@ -234,28 +197,11 @@ nsNodeInfo::NamespaceEquals(const nsAString& aNamespaceURI) const
|
||||
return nsINodeInfo::NamespaceEquals(nsid);
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
nsNodeInfo::ClearCache()
|
||||
{
|
||||
// Clear our cache.
|
||||
delete sNodeInfoPool;
|
||||
sNodeInfoPool = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
nsNodeInfo::LastRelease()
|
||||
{
|
||||
nsRefPtr<nsNodeInfoManager> kungFuDeathGrip = mOwnerManager;
|
||||
this->~nsNodeInfo();
|
||||
|
||||
// The refcount balancing and destructor re-entrancy protection
|
||||
// code in Release() sets mRefCnt to 1 so we have to set it to 0
|
||||
// here to prevent leaks
|
||||
mRefCnt = 0;
|
||||
|
||||
NS_ASSERTION(sNodeInfoPool, "No NodeInfoPool when deleting NodeInfo!!!");
|
||||
sNodeInfoPool->Free(this, sizeof(nsNodeInfo));
|
||||
delete this;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
@ -20,8 +21,6 @@
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsGkAtoms.h"
|
||||
|
||||
class nsFixedSizeAllocator;
|
||||
|
||||
class nsNodeInfo : public nsINodeInfo
|
||||
{
|
||||
public:
|
||||
@ -33,39 +32,27 @@ public:
|
||||
virtual bool NamespaceEquals(const nsAString& aNamespaceURI) const;
|
||||
|
||||
// nsNodeInfo
|
||||
// Create objects with Create
|
||||
public:
|
||||
/*
|
||||
* aName and aOwnerManager may not be null.
|
||||
*/
|
||||
static nsNodeInfo *Create(nsIAtom *aName, nsIAtom *aPrefix,
|
||||
int32_t aNamespaceID, uint16_t aNodeType,
|
||||
nsIAtom *aExtraName,
|
||||
nsNodeInfoManager *aOwnerManager);
|
||||
private:
|
||||
nsNodeInfo(); // Unimplemented
|
||||
nsNodeInfo(const nsNodeInfo& aOther); // Unimplemented
|
||||
nsNodeInfo(nsIAtom *aName, nsIAtom *aPrefix, int32_t aNamespaceID,
|
||||
uint16_t aNodeType, nsIAtom *aExtraName,
|
||||
nsNodeInfoManager *aOwnerManager);
|
||||
|
||||
private:
|
||||
nsNodeInfo(); // Unimplemented
|
||||
nsNodeInfo(const nsNodeInfo& aOther); // Unimplemented
|
||||
protected:
|
||||
virtual ~nsNodeInfo();
|
||||
|
||||
public:
|
||||
/**
|
||||
* Call before shutdown to clear the cache and free memory for this class.
|
||||
*/
|
||||
static void ClearCache();
|
||||
|
||||
bool CanSkip();
|
||||
|
||||
private:
|
||||
static nsFixedSizeAllocator* sNodeInfoPool;
|
||||
|
||||
/**
|
||||
* This method gets called by Release() when it's time to delete
|
||||
* this object, instead of always deleting the object we'll put the
|
||||
* object in the cache unless the cache is already full.
|
||||
* This method gets called by Release() when it's time to delete
|
||||
* this object.
|
||||
*/
|
||||
void LastRelease();
|
||||
};
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
@ -220,10 +221,9 @@ nsNodeInfoManager::GetNodeInfo(nsIAtom *aName, nsIAtom *aPrefix,
|
||||
}
|
||||
|
||||
nsRefPtr<nsNodeInfo> newNodeInfo =
|
||||
nsNodeInfo::Create(aName, aPrefix, aNamespaceID, aNodeType, aExtraName,
|
||||
this);
|
||||
new nsNodeInfo(aName, aPrefix, aNamespaceID, aNodeType, aExtraName, this);
|
||||
NS_ENSURE_TRUE(newNodeInfo, nullptr);
|
||||
|
||||
|
||||
PLHashEntry *he;
|
||||
he = PL_HashTableAdd(mNodeInfoHash, &newNodeInfo->mInner, newNodeInfo);
|
||||
NS_ENSURE_TRUE(he, nullptr);
|
||||
@ -266,13 +266,11 @@ nsNodeInfoManager::GetNodeInfo(const nsAString& aName, nsIAtom *aPrefix,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(aName);
|
||||
NS_ENSURE_TRUE(nameAtom, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsRefPtr<nsNodeInfo> newNodeInfo =
|
||||
nsNodeInfo::Create(nameAtom, aPrefix, aNamespaceID, aNodeType, nullptr,
|
||||
this);
|
||||
new nsNodeInfo(nameAtom, aPrefix, aNamespaceID, aNodeType, nullptr, this);
|
||||
NS_ENSURE_TRUE(newNodeInfo, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
PLHashEntry *he;
|
||||
|
@ -156,6 +156,16 @@ public:
|
||||
nullptr, aNodesWithProperties, nullptr, aResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones aNode, its attributes and, if aDeep is true, its descendant nodes
|
||||
*/
|
||||
static nsresult Clone(nsINode *aNode, bool aDeep, nsINode **aResult)
|
||||
{
|
||||
nsCOMArray<nsINode> dummyNodeWithProperties;
|
||||
return CloneAndAdopt(aNode, true, aDeep, nullptr, nullptr, nullptr,
|
||||
dummyNodeWithProperties, aNode->GetParent(), aResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* Walks aNode, its attributes and descendant nodes. If aNewNodeInfoManager is
|
||||
* not null, it is used to create new nodeinfos for the nodes. Also reparents
|
||||
|
@ -54,6 +54,7 @@ MOCHITEST_CHROME_FILES = \
|
||||
test_domparsing.xul \
|
||||
test_bug814638.xul \
|
||||
host_bug814638.xul \
|
||||
test_document_register.xul \
|
||||
frame_bug814638.xul \
|
||||
$(NULL)
|
||||
|
||||
|
37
content/base/test/chrome/test_document_register.xul
Normal file
37
content/base/test/chrome/test_document_register.xul
Normal file
@ -0,0 +1,37 @@
|
||||
<?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"?>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=783129
|
||||
-->
|
||||
<window title="Mozilla Bug 549682"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<!-- test results are displayed in the html:body -->
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=783129"
|
||||
target="_blank">Mozilla Bug 783129</a>
|
||||
<iframe onload="startTests()" id="fooframe" src="http://example.com"></iframe>
|
||||
</body>
|
||||
|
||||
<!-- test code goes here -->
|
||||
<script type="application/javascript"><![CDATA[
|
||||
|
||||
/** Test for Bug 783129 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function startTests() {
|
||||
var c = $("fooframe").contentDocument.register("x-foo");
|
||||
var elem = new c();
|
||||
is(elem.tagName, "X-FOO", "Constructor should create an x-foo element.");
|
||||
|
||||
var anotherElem = $("fooframe").contentDocument.createElement("x-foo");
|
||||
is(anotherElem.tagName, "X-FOO", "createElement should create an x-foo element.");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
]]></script>
|
||||
</window>
|
@ -564,7 +564,6 @@ WebGLContext::SetDimensions(int32_t width, int32_t height)
|
||||
// we'll end up displaying random memory
|
||||
gl->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
|
||||
|
||||
gl->fViewport(0, 0, mWidth, mHeight);
|
||||
gl->fClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
gl->fClearDepth(1.0f);
|
||||
gl->fClearStencil(0);
|
||||
|
@ -764,6 +764,9 @@ public:
|
||||
bool ValidateUniformSetter(const char* name, WebGLUniformLocation *location_object, GLint& location);
|
||||
void ValidateProgram(WebGLProgram *prog);
|
||||
bool ValidateUniformLocation(const char* info, WebGLUniformLocation *location_object);
|
||||
bool ValidateSamplerUniformSetter(const char* info,
|
||||
WebGLUniformLocation *location,
|
||||
WebGLint value);
|
||||
|
||||
void VertexAttrib1f(WebGLuint index, WebGLfloat x0);
|
||||
void VertexAttrib2f(WebGLuint index, WebGLfloat x0, WebGLfloat x1);
|
||||
|
@ -2850,6 +2850,15 @@ WebGLContext::GetVertexAttrib(JSContext* cx, WebGLuint index, WebGLenum pname,
|
||||
return JS::Int32Value(mAttribBuffers[index].stride);
|
||||
|
||||
case LOCAL_GL_VERTEX_ATTRIB_ARRAY_SIZE:
|
||||
{
|
||||
if (!ValidateAttribIndex(index, "enableVertexAttribArray"))
|
||||
return JS::NullValue();
|
||||
|
||||
if (!mAttribBuffers[index].enabled)
|
||||
return JS::Int32Value(4);
|
||||
|
||||
// Don't break; fall through.
|
||||
}
|
||||
case LOCAL_GL_VERTEX_ATTRIB_ARRAY_TYPE:
|
||||
{
|
||||
GLint i = 0;
|
||||
@ -3673,12 +3682,17 @@ WebGLContext::SurfaceFromElementResultToImageSurface(nsLayoutUtils::SurfaceFromE
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
WebGLContext::Uniform1i(WebGLUniformLocation *location_object, WebGLint a1)
|
||||
{
|
||||
GLint location;
|
||||
if (!ValidateUniformSetter("Uniform1i", location_object, location))
|
||||
return;
|
||||
|
||||
if (!ValidateSamplerUniformSetter("Uniform1i", location_object, a1))
|
||||
return;
|
||||
|
||||
MakeContextCurrent();
|
||||
gl->fUniform1i(location, a1);
|
||||
}
|
||||
@ -3690,6 +3704,13 @@ WebGLContext::Uniform2i(WebGLUniformLocation *location_object, WebGLint a1,
|
||||
GLint location;
|
||||
if (!ValidateUniformSetter("Uniform2i", location_object, location))
|
||||
return;
|
||||
|
||||
if (!ValidateSamplerUniformSetter("Uniform2i", location_object, a1) ||
|
||||
!ValidateSamplerUniformSetter("Uniform2i", location_object, a2))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MakeContextCurrent();
|
||||
gl->fUniform2i(location, a1, a2);
|
||||
}
|
||||
@ -3701,6 +3722,14 @@ WebGLContext::Uniform3i(WebGLUniformLocation *location_object, WebGLint a1,
|
||||
GLint location;
|
||||
if (!ValidateUniformSetter("Uniform3i", location_object, location))
|
||||
return;
|
||||
|
||||
if (!ValidateSamplerUniformSetter("Uniform3i", location_object, a1) ||
|
||||
!ValidateSamplerUniformSetter("Uniform3i", location_object, a2) ||
|
||||
!ValidateSamplerUniformSetter("Uniform3i", location_object, a3))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MakeContextCurrent();
|
||||
gl->fUniform3i(location, a1, a2, a3);
|
||||
}
|
||||
@ -3712,6 +3741,15 @@ WebGLContext::Uniform4i(WebGLUniformLocation *location_object, WebGLint a1,
|
||||
GLint location;
|
||||
if (!ValidateUniformSetter("Uniform4i", location_object, location))
|
||||
return;
|
||||
|
||||
if (!ValidateSamplerUniformSetter("Uniform4i", location_object, a1) ||
|
||||
!ValidateSamplerUniformSetter("Uniform4i", location_object, a2) ||
|
||||
!ValidateSamplerUniformSetter("Uniform4i", location_object, a3) ||
|
||||
!ValidateSamplerUniformSetter("Uniform4i", location_object, a4))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MakeContextCurrent();
|
||||
gl->fUniform4i(location, a1, a2, a3, a4);
|
||||
}
|
||||
@ -3769,6 +3807,10 @@ WebGLContext::Uniform1iv_base(WebGLUniformLocation *location_object,
|
||||
numElementsToUpload, arrayLength)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ValidateSamplerUniformSetter("Uniform1iv", location_object, data[0]))
|
||||
return;
|
||||
|
||||
MakeContextCurrent();
|
||||
gl->fUniform1iv(location, numElementsToUpload, data);
|
||||
}
|
||||
@ -3783,6 +3825,13 @@ WebGLContext::Uniform2iv_base(WebGLUniformLocation *location_object,
|
||||
numElementsToUpload, arrayLength)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ValidateSamplerUniformSetter("Uniform2iv", location_object, data[0]) ||
|
||||
!ValidateSamplerUniformSetter("Uniform2iv", location_object, data[1]))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MakeContextCurrent();
|
||||
gl->fUniform2iv(location, numElementsToUpload, data);
|
||||
}
|
||||
@ -3797,6 +3846,14 @@ WebGLContext::Uniform3iv_base(WebGLUniformLocation *location_object,
|
||||
numElementsToUpload, arrayLength)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ValidateSamplerUniformSetter("Uniform3iv", location_object, data[0]) ||
|
||||
!ValidateSamplerUniformSetter("Uniform3iv", location_object, data[1]) ||
|
||||
!ValidateSamplerUniformSetter("Uniform3iv", location_object, data[2]))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MakeContextCurrent();
|
||||
gl->fUniform3iv(location, numElementsToUpload, data);
|
||||
}
|
||||
@ -3811,6 +3868,15 @@ WebGLContext::Uniform4iv_base(WebGLUniformLocation *location_object,
|
||||
numElementsToUpload, arrayLength)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ValidateSamplerUniformSetter("Uniform4iv", location_object, data[0]) ||
|
||||
!ValidateSamplerUniformSetter("Uniform4iv", location_object, data[1]) ||
|
||||
!ValidateSamplerUniformSetter("Uniform4iv", location_object, data[2]) ||
|
||||
!ValidateSamplerUniformSetter("Uniform4iv", location_object, data[3]))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MakeContextCurrent();
|
||||
gl->fUniform4iv(location, numElementsToUpload, data);
|
||||
}
|
||||
|
@ -688,6 +688,23 @@ WebGLContext::ValidateUniformLocation(const char* info, WebGLUniformLocation *lo
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLContext::ValidateSamplerUniformSetter(const char* info, WebGLUniformLocation *location, WebGLint value)
|
||||
{
|
||||
if (location->Info().type != SH_SAMPLER_2D &&
|
||||
location->Info().type != SH_SAMPLER_CUBE)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (value >= 0 && value < mGLMaxTextureUnits)
|
||||
return true;
|
||||
|
||||
ErrorInvalidValue("%s: this uniform location is a sampler, but %d is not a valid texture unit",
|
||||
info, value);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLContext::ValidateAttribArraySetter(const char* name, uint32_t cnt, uint32_t arrayLength)
|
||||
{
|
||||
|
@ -866,6 +866,8 @@ nsEventDispatcher::CreateEvent(nsPresContext* aPresContext,
|
||||
if (aEventType.LowerCaseEqualsLiteral("commandevent") ||
|
||||
aEventType.LowerCaseEqualsLiteral("commandevents"))
|
||||
return NS_NewDOMCommandEvent(aDOMEvent, aPresContext, nullptr);
|
||||
if (aEventType.LowerCaseEqualsLiteral("elementreplace"))
|
||||
return NS_NewDOMElementReplaceEvent(aDOMEvent, aPresContext, nullptr);
|
||||
if (aEventType.LowerCaseEqualsLiteral("datacontainerevent") ||
|
||||
aEventType.LowerCaseEqualsLiteral("datacontainerevents"))
|
||||
return NS_NewDOMDataContainerEvent(aDOMEvent, aPresContext, nullptr);
|
||||
|
@ -155,6 +155,11 @@ public:
|
||||
SetHTMLBoolAttr(nsGkAtoms::nohref, aValue, aError);
|
||||
}
|
||||
|
||||
void Stringify(nsAString& aResult)
|
||||
{
|
||||
GetHref(aResult);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual JSObject* WrapNode(JSContext* aCx, JSObject* aScope,
|
||||
bool* aTriedToWrap) MOZ_OVERRIDE;
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "nsAttrValueInlines.h"
|
||||
#include "nsRuleData.h"
|
||||
#include "nsHTMLStyleSheet.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/HTMLCollectionBinding.h"
|
||||
#include "mozilla/dom/HTMLTableElementBinding.h"
|
||||
@ -1211,6 +1212,15 @@ HTMLTableElement::BuildInheritedAttributes()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HTMLTableElement::ReleaseInheritedAttributes()
|
||||
{
|
||||
if (mTableInheritedAttributes &&
|
||||
mTableInheritedAttributes != TABLE_ATTRS_DIRTY)
|
||||
NS_RELEASE(mTableInheritedAttributes);
|
||||
mTableInheritedAttributes = TABLE_ATTRS_DIRTY;
|
||||
}
|
||||
|
||||
nsresult
|
||||
HTMLTableElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include "nsIDOMHTMLTableElement.h"
|
||||
#include "mozilla/dom/HTMLTableCaptionElement.h"
|
||||
#include "mozilla/dom/HTMLTableSectionElement.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -224,12 +223,7 @@ protected:
|
||||
// to be recalculated.
|
||||
nsMappedAttributes *mTableInheritedAttributes;
|
||||
void BuildInheritedAttributes();
|
||||
void ReleaseInheritedAttributes() {
|
||||
if (mTableInheritedAttributes &&
|
||||
mTableInheritedAttributes != TABLE_ATTRS_DIRTY)
|
||||
NS_RELEASE(mTableInheritedAttributes);
|
||||
mTableInheritedAttributes = TABLE_ATTRS_DIRTY;
|
||||
}
|
||||
void ReleaseInheritedAttributes();
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -3,6 +3,7 @@
|
||||
* 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 "nsDocument.h"
|
||||
#include "HTMLUnknownElement.h"
|
||||
#include "mozilla/dom/HTMLElementBinding.h"
|
||||
|
||||
@ -18,7 +19,19 @@ JSObject*
|
||||
HTMLUnknownElement::WrapNode(JSContext *aCx, JSObject *aScope,
|
||||
bool *aTriedToWrap)
|
||||
{
|
||||
return HTMLUnknownElementBinding::Wrap(aCx, aScope, this, aTriedToWrap);
|
||||
JSObject* obj =
|
||||
HTMLUnknownElementBinding::Wrap(aCx, aScope, this, aTriedToWrap);
|
||||
if (obj && Substring(NodeName(), 0, 2).LowerCaseEqualsLiteral("x-")) {
|
||||
// If we have a registered x-tag then we fix the prototype.
|
||||
JSAutoCompartment ac(aCx, obj);
|
||||
nsDocument* document = static_cast<nsDocument*>(OwnerDoc());
|
||||
JSObject* prototype = document->GetCustomPrototype(LocalName());
|
||||
if (prototype) {
|
||||
NS_ENSURE_TRUE(JS_WrapObject(aCx, &prototype), nullptr);
|
||||
NS_ENSURE_TRUE(JS_SetPrototype(aCx, obj, prototype), nullptr);
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
// QueryInterface implementation for HTMLUnknownElement
|
||||
|
@ -1479,8 +1479,8 @@ nsGenericHTMLElement::ParseScrollingValue(const nsAString& aString,
|
||||
* Handle attributes common to all html elements
|
||||
*/
|
||||
void
|
||||
nsGenericHTMLElement::MapCommonAttributesExceptHiddenInto(const nsMappedAttributes* aAttributes,
|
||||
nsRuleData* aData)
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(const nsMappedAttributes* aAttributes,
|
||||
nsRuleData* aData)
|
||||
{
|
||||
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(UserInterface)) {
|
||||
nsCSSValue* userModify = aData->ValueForUserModify();
|
||||
@ -1508,13 +1508,6 @@ nsGenericHTMLElement::MapCommonAttributesExceptHiddenInto(const nsMappedAttribut
|
||||
eCSSUnit_Ident);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(const nsMappedAttributes* aAttributes,
|
||||
nsRuleData* aData)
|
||||
{
|
||||
nsGenericHTMLElement::MapCommonAttributesExceptHiddenInto(aAttributes, aData);
|
||||
|
||||
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Display)) {
|
||||
nsCSSValue* display = aData->ValueForDisplay();
|
||||
|
@ -517,14 +517,6 @@ public:
|
||||
static void MapCommonAttributesInto(const nsMappedAttributes* aAttributes,
|
||||
nsRuleData* aRuleData);
|
||||
|
||||
/**
|
||||
* This method is used by embed elements because they should ignore the hidden
|
||||
* attribute for the moment.
|
||||
* TODO: This should be removed when bug 614825 will be fixed.
|
||||
*/
|
||||
static void MapCommonAttributesExceptHiddenInto(const nsMappedAttributes* aAttributes,
|
||||
nsRuleData* aRuleData);
|
||||
|
||||
static const MappedAttributeEntry sCommonAttributeMap[];
|
||||
static const MappedAttributeEntry sImageMarginSizeAttributeMap[];
|
||||
static const MappedAttributeEntry sImageBorderAttributeMap[];
|
||||
|
@ -419,21 +419,6 @@ MapAttributesIntoRule(const nsMappedAttributes *aAttributes,
|
||||
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aData);
|
||||
}
|
||||
|
||||
static void
|
||||
EmbedMapAttributesIntoRule(const nsMappedAttributes *aAttributes,
|
||||
nsRuleData *aData)
|
||||
{
|
||||
// NOTE: this should call the exact some methods than MapAttributesIntoRule
|
||||
// except that MapCommonAttributesExceptHiddenInto is called instead of
|
||||
// MapCommonAttributesInto.
|
||||
// TODO: This method should be removed when bug 614825 will be fixed.
|
||||
nsGenericHTMLElement::MapImageBorderAttributeInto(aAttributes, aData);
|
||||
nsGenericHTMLElement::MapImageMarginAttributeInto(aAttributes, aData);
|
||||
nsGenericHTMLElement::MapImageSizeAttributesInto(aAttributes, aData);
|
||||
nsGenericHTMLElement::MapImageAlignAttributeInto(aAttributes, aData);
|
||||
nsGenericHTMLElement::MapCommonAttributesExceptHiddenInto(aAttributes, aData);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
nsHTMLSharedObjectElement::IsAttributeMapped(const nsIAtom *aAttribute) const
|
||||
{
|
||||
@ -451,10 +436,6 @@ nsHTMLSharedObjectElement::IsAttributeMapped(const nsIAtom *aAttribute) const
|
||||
nsMapRuleToAttributesFunc
|
||||
nsHTMLSharedObjectElement::GetAttributeMappingFunction() const
|
||||
{
|
||||
if (mNodeInfo->Equals(nsGkAtoms::embed)) {
|
||||
return &EmbedMapAttributesIntoRule;
|
||||
}
|
||||
|
||||
return &MapAttributesIntoRule;
|
||||
}
|
||||
|
||||
|
@ -270,6 +270,7 @@ MOCHITEST_FILES = \
|
||||
test_bug827126.html \
|
||||
test_bug827426.html \
|
||||
test_bug838582.html \
|
||||
test_bug839913.html \
|
||||
test_bug841466.html \
|
||||
test_iframe_sandbox_inheritance.html \
|
||||
file_iframe_sandbox_a_if1.html \
|
||||
|
@ -19,16 +19,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=613722
|
||||
|
||||
/** Test for Bug 613722 **/
|
||||
|
||||
/**
|
||||
* TODO: this test should be removed when bug 614825 will be fixed.
|
||||
*/
|
||||
|
||||
var rect = document.getElementsByTagName('embed')[0].getBoundingClientRect();
|
||||
|
||||
var hasFrame = rect.left != 0 || rect.right != 0 || rect.top != 0 ||
|
||||
rect.bottom != 0;
|
||||
|
||||
ok(hasFrame, "embed should have a frame with hidden set");
|
||||
ok(!hasFrame, "embed should not have a frame with hidden set");
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
|
14
content/html/content/test/test_bug839913.html
Normal file
14
content/html/content/test/test_bug839913.html
Normal file
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>Test for HTMLAreaElement's stringifier</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
test(function() {
|
||||
var area = document.createElement("area");
|
||||
area.href = "http://example.org/";
|
||||
assert_equals(area.href, "http://example.org/");
|
||||
assert_equals(String(area), "http://example.org/");
|
||||
}, "Area elements should stringify to the href attribute");
|
||||
</script>
|
@ -9,7 +9,6 @@
|
||||
#include "nsDocument.h"
|
||||
#include "nsIHTMLDocument.h"
|
||||
#include "nsIDOMHTMLDocument.h"
|
||||
#include "nsIDOMHTMLBodyElement.h"
|
||||
#include "nsIDOMHTMLCollection.h"
|
||||
#include "nsIScriptElement.h"
|
||||
#include "jsapi.h"
|
||||
|
@ -18,6 +18,97 @@ namespace mozilla {
|
||||
|
||||
namespace dom {
|
||||
|
||||
// This is an internal helper class and should not be used outside of this header.
|
||||
struct AudioTimelineEvent {
|
||||
enum Type MOZ_ENUM_TYPE(uint32_t) {
|
||||
SetValue,
|
||||
LinearRamp,
|
||||
ExponentialRamp,
|
||||
SetTarget,
|
||||
SetValueCurve
|
||||
};
|
||||
|
||||
AudioTimelineEvent(Type aType, double aTime, float aValue, double aTimeConstant = 0.0,
|
||||
float aDuration = 0.0, float* aCurve = nullptr, uint32_t aCurveLength = 0)
|
||||
: mType(aType)
|
||||
, mTimeConstant(aTimeConstant)
|
||||
, mDuration(aDuration)
|
||||
#ifdef DEBUG
|
||||
, mTimeIsInTicks(false)
|
||||
#endif
|
||||
{
|
||||
if (aType == AudioTimelineEvent::SetValueCurve) {
|
||||
mCurve = aCurve;
|
||||
mCurveLength = aCurveLength;
|
||||
} else {
|
||||
mValue = aValue;
|
||||
mTime = aTime;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsValid() const
|
||||
{
|
||||
return IsValid(mTime) &&
|
||||
IsValid(mValue) &&
|
||||
IsValid(mTimeConstant) &&
|
||||
IsValid(mDuration);
|
||||
}
|
||||
|
||||
template <class TimeType>
|
||||
TimeType Time() const;
|
||||
|
||||
void SetTimeInTicks(int64_t aTimeInTicks)
|
||||
{
|
||||
mTimeInTicks = aTimeInTicks;
|
||||
#ifdef DEBUG
|
||||
mTimeIsInTicks = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
Type mType;
|
||||
union {
|
||||
float mValue;
|
||||
uint32_t mCurveLength;
|
||||
};
|
||||
union {
|
||||
// The time for an event can either be in absolute value or in ticks.
|
||||
// Initially the time of the event is always in absolute value.
|
||||
// In order to convert it to ticks, call SetTimeInTicks. Once this
|
||||
// method has been called for an event, the time cannot be converted
|
||||
// back to absolute value.
|
||||
union {
|
||||
double mTime;
|
||||
int64_t mTimeInTicks;
|
||||
};
|
||||
float* mCurve;
|
||||
};
|
||||
double mTimeConstant;
|
||||
double mDuration;
|
||||
#ifdef DEBUG
|
||||
bool mTimeIsInTicks;
|
||||
#endif
|
||||
|
||||
private:
|
||||
static bool IsValid(double value)
|
||||
{
|
||||
return MOZ_DOUBLE_IS_FINITE(value);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
inline double AudioTimelineEvent::Time<double>() const
|
||||
{
|
||||
MOZ_ASSERT(!mTimeIsInTicks);
|
||||
return mTime;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline int64_t AudioTimelineEvent::Time<int64_t>() const
|
||||
{
|
||||
MOZ_ASSERT(mTimeIsInTicks);
|
||||
return mTimeInTicks;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class will be instantiated with different template arguments for testing and
|
||||
* production code.
|
||||
@ -28,64 +119,31 @@ namespace dom {
|
||||
template <class ErrorResult>
|
||||
class AudioEventTimeline
|
||||
{
|
||||
private:
|
||||
struct Event {
|
||||
enum Type MOZ_ENUM_TYPE(uint32_t) {
|
||||
SetValue,
|
||||
LinearRamp,
|
||||
ExponentialRamp,
|
||||
SetTarget,
|
||||
SetValueCurve
|
||||
};
|
||||
|
||||
Event(Type aType, double aTime, float aValue, double aTimeConstant = 0.0,
|
||||
float aDuration = 0.0, float* aCurve = nullptr, uint32_t aCurveLength = 0)
|
||||
: mType(aType)
|
||||
, mTimeConstant(aTimeConstant)
|
||||
, mDuration(aDuration)
|
||||
{
|
||||
if (aType == Event::SetValueCurve) {
|
||||
mCurve = aCurve;
|
||||
mCurveLength = aCurveLength;
|
||||
} else {
|
||||
mValue = aValue;
|
||||
mTime = aTime;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsValid() const
|
||||
{
|
||||
return IsValid(mTime) &&
|
||||
IsValid(mValue) &&
|
||||
IsValid(mTimeConstant) &&
|
||||
IsValid(mDuration);
|
||||
}
|
||||
|
||||
Type mType;
|
||||
union {
|
||||
float mValue;
|
||||
uint32_t mCurveLength;
|
||||
};
|
||||
union {
|
||||
double mTime;
|
||||
float* mCurve;
|
||||
};
|
||||
double mTimeConstant;
|
||||
double mDuration;
|
||||
|
||||
private:
|
||||
static bool IsValid(double value)
|
||||
{
|
||||
return MOZ_DOUBLE_IS_FINITE(value);
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
// This constructor should only be used for objects which are meant to be
|
||||
// copied from other properly constructed objects.
|
||||
AudioEventTimeline()
|
||||
: mValue(0.f)
|
||||
{
|
||||
}
|
||||
|
||||
explicit AudioEventTimeline(float aDefaultValue)
|
||||
: mValue(aDefaultValue)
|
||||
{
|
||||
}
|
||||
|
||||
bool HasSimpleValue() const
|
||||
{
|
||||
return mEvents.IsEmpty();
|
||||
}
|
||||
|
||||
float GetValue() const
|
||||
{
|
||||
// This method should only be called if HasSimpleValue() returns true
|
||||
MOZ_ASSERT(HasSimpleValue());
|
||||
return mValue;
|
||||
}
|
||||
|
||||
float Value() const
|
||||
{
|
||||
// TODO: Return the current value based on the timeline of the AudioContext
|
||||
@ -108,29 +166,29 @@ public:
|
||||
|
||||
void SetValueAtTime(float aValue, double aStartTime, ErrorResult& aRv)
|
||||
{
|
||||
InsertEvent(Event(Event::SetValue, aStartTime, aValue), aRv);
|
||||
InsertEvent(AudioTimelineEvent(AudioTimelineEvent::SetValue, aStartTime, aValue), aRv);
|
||||
}
|
||||
|
||||
void LinearRampToValueAtTime(float aValue, double aEndTime, ErrorResult& aRv)
|
||||
{
|
||||
InsertEvent(Event(Event::LinearRamp, aEndTime, aValue), aRv);
|
||||
InsertEvent(AudioTimelineEvent(AudioTimelineEvent::LinearRamp, aEndTime, aValue), aRv);
|
||||
}
|
||||
|
||||
void ExponentialRampToValueAtTime(float aValue, double aEndTime, ErrorResult& aRv)
|
||||
{
|
||||
InsertEvent(Event(Event::ExponentialRamp, aEndTime, aValue), aRv);
|
||||
InsertEvent(AudioTimelineEvent(AudioTimelineEvent::ExponentialRamp, aEndTime, aValue), aRv);
|
||||
}
|
||||
|
||||
void SetTargetAtTime(float aTarget, double aStartTime, double aTimeConstant, ErrorResult& aRv)
|
||||
{
|
||||
InsertEvent(Event(Event::SetTarget, aStartTime, aTarget, aTimeConstant), aRv);
|
||||
InsertEvent(AudioTimelineEvent(AudioTimelineEvent::SetTarget, aStartTime, aTarget, aTimeConstant), aRv);
|
||||
}
|
||||
|
||||
void SetValueCurveAtTime(const float* aValues, uint32_t aValuesLength, double aStartTime, double aDuration, ErrorResult& aRv)
|
||||
{
|
||||
// TODO: implement
|
||||
// Note that we will need to copy the buffer here.
|
||||
// InsertEvent(Event(Event::SetValueCurve, aStartTime, 0.0f, 0.0f, aDuration, aValues, aValuesLength), aRv);
|
||||
// InsertEvent(AudioTimelineEvent(AudioTimelineEvent::SetValueCurve, aStartTime, 0.0f, 0.0f, aDuration, aValues, aValuesLength), aRv);
|
||||
}
|
||||
|
||||
void CancelScheduledValues(double aStartTime)
|
||||
@ -151,33 +209,34 @@ public:
|
||||
}
|
||||
|
||||
// This method computes the AudioParam value at a given time based on the event timeline
|
||||
float GetValueAtTime(double aTime) const
|
||||
template<class TimeType>
|
||||
float GetValueAtTime(TimeType aTime) const
|
||||
{
|
||||
const Event* previous = nullptr;
|
||||
const Event* next = nullptr;
|
||||
const AudioTimelineEvent* previous = nullptr;
|
||||
const AudioTimelineEvent* next = nullptr;
|
||||
|
||||
bool bailOut = false;
|
||||
for (unsigned i = 0; !bailOut && i < mEvents.Length(); ++i) {
|
||||
switch (mEvents[i].mType) {
|
||||
case Event::SetValue:
|
||||
case Event::SetTarget:
|
||||
case Event::LinearRamp:
|
||||
case Event::ExponentialRamp:
|
||||
if (aTime == mEvents[i].mTime) {
|
||||
case AudioTimelineEvent::SetValue:
|
||||
case AudioTimelineEvent::SetTarget:
|
||||
case AudioTimelineEvent::LinearRamp:
|
||||
case AudioTimelineEvent::ExponentialRamp:
|
||||
if (aTime == mEvents[i].template Time<TimeType>()) {
|
||||
// Find the last event with the same time
|
||||
do {
|
||||
++i;
|
||||
} while (i < mEvents.Length() &&
|
||||
aTime == mEvents[i].mTime);
|
||||
aTime == mEvents[i].template Time<TimeType>());
|
||||
return mEvents[i - 1].mValue;
|
||||
}
|
||||
previous = next;
|
||||
next = &mEvents[i];
|
||||
if (aTime < mEvents[i].mTime) {
|
||||
if (aTime < mEvents[i].template Time<TimeType>()) {
|
||||
bailOut = true;
|
||||
}
|
||||
break;
|
||||
case Event::SetValueCurve:
|
||||
case AudioTimelineEvent::SetValueCurve:
|
||||
// TODO: implement
|
||||
break;
|
||||
default:
|
||||
@ -198,17 +257,17 @@ public:
|
||||
// If the requested time is before all of the existing events
|
||||
if (!previous) {
|
||||
switch (next->mType) {
|
||||
case Event::SetValue:
|
||||
case Event::SetTarget:
|
||||
case AudioTimelineEvent::SetValue:
|
||||
case AudioTimelineEvent::SetTarget:
|
||||
// The requested time is before the first event
|
||||
return mValue;
|
||||
case Event::LinearRamp:
|
||||
case AudioTimelineEvent::LinearRamp:
|
||||
// Use t=0 as T0 and v=defaultValue as V0
|
||||
return LinearInterpolate(0.0, mValue, next->mTime, next->mValue, aTime);
|
||||
case Event::ExponentialRamp:
|
||||
return LinearInterpolate(0.0, mValue, next->template Time<TimeType>(), next->mValue, aTime);
|
||||
case AudioTimelineEvent::ExponentialRamp:
|
||||
// Use t=0 as T0 and v=defaultValue as V0
|
||||
return ExponentialInterpolate(0.0, mValue, next->mTime, next->mValue, aTime);
|
||||
case Event::SetValueCurve:
|
||||
return ExponentialInterpolate(0.0, mValue, next->template Time<TimeType>(), next->mValue, aTime);
|
||||
case AudioTimelineEvent::SetValueCurve:
|
||||
// TODO: implement
|
||||
return 0.0f;
|
||||
}
|
||||
@ -216,24 +275,24 @@ public:
|
||||
}
|
||||
|
||||
// SetTarget nodes can be handled no matter what their next node is (if they have one)
|
||||
if (previous->mType == Event::SetTarget) {
|
||||
if (previous->mType == AudioTimelineEvent::SetTarget) {
|
||||
// Follow the curve, without regard to the next node
|
||||
return ExponentialApproach(previous->mTime, mValue, previous->mValue,
|
||||
return ExponentialApproach(previous->template Time<TimeType>(), mValue, previous->mValue,
|
||||
previous->mTimeConstant, aTime);
|
||||
}
|
||||
|
||||
// If the requested time is after all of the existing events
|
||||
if (!next) {
|
||||
switch (previous->mType) {
|
||||
case Event::SetValue:
|
||||
case Event::LinearRamp:
|
||||
case Event::ExponentialRamp:
|
||||
case AudioTimelineEvent::SetValue:
|
||||
case AudioTimelineEvent::LinearRamp:
|
||||
case AudioTimelineEvent::ExponentialRamp:
|
||||
// The value will be constant after the last event
|
||||
return previous->mValue;
|
||||
case Event::SetValueCurve:
|
||||
case AudioTimelineEvent::SetValueCurve:
|
||||
// TODO: implement
|
||||
return 0.0f;
|
||||
case Event::SetTarget:
|
||||
case AudioTimelineEvent::SetTarget:
|
||||
MOZ_ASSERT(false, "unreached");
|
||||
}
|
||||
MOZ_ASSERT(false, "unreached");
|
||||
@ -243,28 +302,28 @@ public:
|
||||
|
||||
// First, handle the case where our range ends up in a ramp event
|
||||
switch (next->mType) {
|
||||
case Event::LinearRamp:
|
||||
return LinearInterpolate(previous->mTime, previous->mValue, next->mTime, next->mValue, aTime);
|
||||
case Event::ExponentialRamp:
|
||||
return ExponentialInterpolate(previous->mTime, previous->mValue, next->mTime, next->mValue, aTime);
|
||||
case Event::SetValue:
|
||||
case Event::SetTarget:
|
||||
case Event::SetValueCurve:
|
||||
case AudioTimelineEvent::LinearRamp:
|
||||
return LinearInterpolate(previous->template Time<TimeType>(), previous->mValue, next->template Time<TimeType>(), next->mValue, aTime);
|
||||
case AudioTimelineEvent::ExponentialRamp:
|
||||
return ExponentialInterpolate(previous->template Time<TimeType>(), previous->mValue, next->template Time<TimeType>(), next->mValue, aTime);
|
||||
case AudioTimelineEvent::SetValue:
|
||||
case AudioTimelineEvent::SetTarget:
|
||||
case AudioTimelineEvent::SetValueCurve:
|
||||
break;
|
||||
}
|
||||
|
||||
// Now handle all other cases
|
||||
switch (previous->mType) {
|
||||
case Event::SetValue:
|
||||
case Event::LinearRamp:
|
||||
case Event::ExponentialRamp:
|
||||
case AudioTimelineEvent::SetValue:
|
||||
case AudioTimelineEvent::LinearRamp:
|
||||
case AudioTimelineEvent::ExponentialRamp:
|
||||
// If the next event type is neither linear or exponential ramp, the
|
||||
// value is constant.
|
||||
return previous->mValue;
|
||||
case Event::SetValueCurve:
|
||||
case AudioTimelineEvent::SetValueCurve:
|
||||
// TODO: implement
|
||||
return 0.0f;
|
||||
case Event::SetTarget:
|
||||
case AudioTimelineEvent::SetTarget:
|
||||
MOZ_ASSERT(false, "unreached");
|
||||
}
|
||||
|
||||
@ -293,19 +352,26 @@ public:
|
||||
return v1 + (v0 - v1) * expf(-(t - t0) / timeConstant);
|
||||
}
|
||||
|
||||
private:
|
||||
const Event* GetPreviousEvent(double aTime) const
|
||||
void ConvertEventTimesToTicks(int64_t (*aConvertor)(double aTime, void* aClosure), void* aClosure)
|
||||
{
|
||||
const Event* previous = nullptr;
|
||||
const Event* next = nullptr;
|
||||
for (unsigned i = 0; i < mEvents.Length(); ++i) {
|
||||
mEvents[i].SetTimeInTicks(aConvertor(mEvents[i].template Time<double>(), aClosure));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const AudioTimelineEvent* GetPreviousEvent(double aTime) const
|
||||
{
|
||||
const AudioTimelineEvent* previous = nullptr;
|
||||
const AudioTimelineEvent* next = nullptr;
|
||||
|
||||
bool bailOut = false;
|
||||
for (unsigned i = 0; !bailOut && i < mEvents.Length(); ++i) {
|
||||
switch (mEvents[i].mType) {
|
||||
case Event::SetValue:
|
||||
case Event::SetTarget:
|
||||
case Event::LinearRamp:
|
||||
case Event::ExponentialRamp:
|
||||
case AudioTimelineEvent::SetValue:
|
||||
case AudioTimelineEvent::SetTarget:
|
||||
case AudioTimelineEvent::LinearRamp:
|
||||
case AudioTimelineEvent::ExponentialRamp:
|
||||
if (aTime == mEvents[i].mTime) {
|
||||
// Find the last event with the same time
|
||||
do {
|
||||
@ -320,7 +386,7 @@ private:
|
||||
bailOut = true;
|
||||
}
|
||||
break;
|
||||
case Event::SetValueCurve:
|
||||
case AudioTimelineEvent::SetValueCurve:
|
||||
// TODO: implement
|
||||
break;
|
||||
default:
|
||||
@ -335,7 +401,7 @@ private:
|
||||
return previous;
|
||||
}
|
||||
|
||||
void InsertEvent(const Event& aEvent, ErrorResult& aRv)
|
||||
void InsertEvent(const AudioTimelineEvent& aEvent, ErrorResult& aRv)
|
||||
{
|
||||
if (!aEvent.IsValid()) {
|
||||
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
|
||||
@ -345,7 +411,7 @@ private:
|
||||
// Make sure that non-curve events don't fall within the duration of a
|
||||
// curve event.
|
||||
for (unsigned i = 0; i < mEvents.Length(); ++i) {
|
||||
if (mEvents[i].mType == Event::SetValueCurve &&
|
||||
if (mEvents[i].mType == AudioTimelineEvent::SetValueCurve &&
|
||||
mEvents[i].mTime <= aEvent.mTime &&
|
||||
(mEvents[i].mTime + mEvents[i].mDuration) >= aEvent.mTime) {
|
||||
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
|
||||
@ -355,7 +421,7 @@ private:
|
||||
|
||||
// Make sure that curve events don't fall in a range which includes other
|
||||
// events.
|
||||
if (aEvent.mType == Event::SetValueCurve) {
|
||||
if (aEvent.mType == AudioTimelineEvent::SetValueCurve) {
|
||||
for (unsigned i = 0; i < mEvents.Length(); ++i) {
|
||||
if (mEvents[i].mTime >= aEvent.mTime &&
|
||||
mEvents[i].mTime <= (aEvent.mTime + aEvent.mDuration)) {
|
||||
@ -366,12 +432,12 @@ private:
|
||||
}
|
||||
|
||||
// Make sure that invalid values are not used for exponential curves
|
||||
if (aEvent.mType == Event::ExponentialRamp) {
|
||||
if (aEvent.mType == AudioTimelineEvent::ExponentialRamp) {
|
||||
if (aEvent.mValue <= 0.f) {
|
||||
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
|
||||
return;
|
||||
}
|
||||
const Event* previousEvent = GetPreviousEvent(aEvent.mTime);
|
||||
const AudioTimelineEvent* previousEvent = GetPreviousEvent(aEvent.mTime);
|
||||
if (previousEvent) {
|
||||
if (previousEvent->mValue <= 0.f) {
|
||||
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
|
||||
@ -418,7 +484,7 @@ private:
|
||||
// and that is the reason why we're using a simple array as the data structure.
|
||||
// We can optimize this in the future if the performance of the array ends up
|
||||
// being a bottleneck.
|
||||
nsTArray<Event> mEvents;
|
||||
nsTArray<AudioTimelineEvent> mEvents;
|
||||
float mValue;
|
||||
};
|
||||
|
||||
|
@ -68,4 +68,14 @@ AudioBlockCopyChannelWithScale(const float aInput[WEBAUDIO_BLOCK_SIZE],
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioBlockCopyChannelWithScale(const float aInput[WEBAUDIO_BLOCK_SIZE],
|
||||
const float aScale[WEBAUDIO_BLOCK_SIZE],
|
||||
float aOutput[WEBAUDIO_BLOCK_SIZE])
|
||||
{
|
||||
for (uint32_t i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) {
|
||||
aOutput[i] = aInput[i]*aScale[i];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -100,6 +100,13 @@ void AudioBlockCopyChannelWithScale(const float aInput[WEBAUDIO_BLOCK_SIZE],
|
||||
float aScale,
|
||||
float aOutput[WEBAUDIO_BLOCK_SIZE]);
|
||||
|
||||
/**
|
||||
* Vector copy-scaled operation.
|
||||
*/
|
||||
void AudioBlockCopyChannelWithScale(const float aInput[WEBAUDIO_BLOCK_SIZE],
|
||||
const float aScale[WEBAUDIO_BLOCK_SIZE],
|
||||
float aOutput[WEBAUDIO_BLOCK_SIZE]);
|
||||
|
||||
/**
|
||||
* All methods of this class and its subclasses are called on the
|
||||
* MediaStreamGraph thread.
|
||||
|
@ -6,6 +6,9 @@
|
||||
|
||||
#include "GainNode.h"
|
||||
#include "mozilla/dom/GainNodeBinding.h"
|
||||
#include "AudioNodeEngine.h"
|
||||
#include "AudioNodeStream.h"
|
||||
#include "AudioDestinationNode.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -19,10 +22,107 @@ NS_INTERFACE_MAP_END_INHERITING(AudioNode)
|
||||
NS_IMPL_ADDREF_INHERITED(GainNode, AudioNode)
|
||||
NS_IMPL_RELEASE_INHERITED(GainNode, AudioNode)
|
||||
|
||||
struct ConvertTimeToTickHelper
|
||||
{
|
||||
AudioNodeStream* mSourceStream;
|
||||
AudioNodeStream* mDestinationStream;
|
||||
|
||||
static int64_t Convert(double aTime, void* aClosure)
|
||||
{
|
||||
TrackRate sampleRate = IdealAudioRate();
|
||||
|
||||
ConvertTimeToTickHelper* This = static_cast<ConvertTimeToTickHelper*> (aClosure);
|
||||
TrackTicks tick = This->mSourceStream->GetCurrentPosition();
|
||||
StreamTime streamTime = TicksToTimeRoundDown(sampleRate, tick);
|
||||
GraphTime graphTime = This->mSourceStream->StreamTimeToGraphTime(streamTime);
|
||||
StreamTime destinationStreamTime = This->mDestinationStream->GraphTimeToStreamTime(graphTime);
|
||||
return TimeToTicksRoundDown(sampleRate, destinationStreamTime + SecondsToMediaTime(aTime));
|
||||
}
|
||||
};
|
||||
|
||||
class GainNodeEngine : public AudioNodeEngine
|
||||
{
|
||||
public:
|
||||
explicit GainNodeEngine(AudioDestinationNode* aDestination)
|
||||
: mSource(nullptr)
|
||||
, mDestination(static_cast<AudioNodeStream*> (aDestination->Stream()))
|
||||
{
|
||||
}
|
||||
|
||||
void SetSourceStream(AudioNodeStream* aSource)
|
||||
{
|
||||
mSource = aSource;
|
||||
}
|
||||
|
||||
enum Parameters {
|
||||
GAIN
|
||||
};
|
||||
void SetTimelineParameter(uint32_t aIndex, const AudioParamTimeline& aValue) MOZ_OVERRIDE
|
||||
{
|
||||
switch (aIndex) {
|
||||
case GAIN:
|
||||
MOZ_ASSERT(mSource && mDestination);
|
||||
mGain = aValue;
|
||||
ConvertTimeToTickHelper ctth;
|
||||
ctth.mSourceStream = mSource;
|
||||
ctth.mDestinationStream = mDestination;
|
||||
mGain.ConvertEventTimesToTicks(ConvertTimeToTickHelper::Convert, &ctth);
|
||||
break;
|
||||
default:
|
||||
NS_ERROR("Bad GainNodeEngine TimelineParameter");
|
||||
}
|
||||
}
|
||||
|
||||
virtual void ProduceAudioBlock(AudioNodeStream* aStream,
|
||||
const AudioChunk& aInput,
|
||||
AudioChunk* aOutput,
|
||||
bool* aFinished)
|
||||
{
|
||||
MOZ_ASSERT(mSource == aStream, "Invalid source stream");
|
||||
|
||||
*aOutput = aInput;
|
||||
if (mGain.HasSimpleValue()) {
|
||||
// Optimize the case where we only have a single value set as the volume
|
||||
aOutput->mVolume *= mGain.GetValue();
|
||||
} else {
|
||||
// First, compute a vector of gains for each track tick based on the
|
||||
// timeline at hand, and then for each channel, multiply the values
|
||||
// in the buffer with the gain vector.
|
||||
|
||||
// Compute the gain values for the duration of the input AudioChunk
|
||||
// XXX we need to add a method to AudioEventTimeline to compute this buffer directly.
|
||||
float computedGain[WEBAUDIO_BLOCK_SIZE];
|
||||
for (size_t counter = 0; counter < WEBAUDIO_BLOCK_SIZE; ++counter) {
|
||||
TrackTicks tick = aStream->GetCurrentPosition() + counter;
|
||||
computedGain[counter] = mGain.GetValueAtTime<TrackTicks>(tick);
|
||||
}
|
||||
|
||||
// Apply the gain to the output buffer
|
||||
for (size_t channel = 0; channel < aOutput->mChannelData.Length(); ++channel) {
|
||||
float* buffer = static_cast<float*> (const_cast<void*>
|
||||
(aOutput->mChannelData[channel]));
|
||||
AudioBlockCopyChannelWithScale(buffer, computedGain, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AudioNodeStream* mSource;
|
||||
AudioNodeStream* mDestination;
|
||||
AudioParamTimeline mGain;
|
||||
};
|
||||
|
||||
GainNode::GainNode(AudioContext* aContext)
|
||||
: AudioNode(aContext)
|
||||
, mGain(new AudioParam(this, Callback, 1.0f, 0.0f, 1.0f))
|
||||
, mGain(new AudioParam(this, SendGainToStream, 1.0f, 0.0f, 1.0f))
|
||||
{
|
||||
GainNodeEngine* engine = new GainNodeEngine(aContext->Destination());
|
||||
mStream = aContext->Graph()->CreateAudioNodeStream(engine);
|
||||
engine->SetSourceStream(static_cast<AudioNodeStream*> (mStream.get()));
|
||||
}
|
||||
|
||||
GainNode::~GainNode()
|
||||
{
|
||||
DestroyMediaStream();
|
||||
}
|
||||
|
||||
JSObject*
|
||||
@ -31,6 +131,14 @@ GainNode::WrapObject(JSContext* aCx, JSObject* aScope)
|
||||
return GainNodeBinding::Wrap(aCx, aScope, this);
|
||||
}
|
||||
|
||||
void
|
||||
GainNode::SendGainToStream(AudioNode* aNode)
|
||||
{
|
||||
GainNode* This = static_cast<GainNode*>(aNode);
|
||||
AudioNodeStream* ns = static_cast<AudioNodeStream*>(This->mStream.get());
|
||||
ns->SetTimelineParameter(GainNodeEngine::GAIN, *This->mGain);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@ class GainNode : public AudioNode
|
||||
{
|
||||
public:
|
||||
explicit GainNode(AudioContext* aContext);
|
||||
virtual ~GainNode();
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(GainNode, AudioNode)
|
||||
@ -30,6 +31,14 @@ public:
|
||||
return mGain;
|
||||
}
|
||||
|
||||
virtual bool SupportsMediaStreams() const MOZ_OVERRIDE
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
static void SendGainToStream(AudioNode* aNode);
|
||||
|
||||
private:
|
||||
nsRefPtr<AudioParam> mGain;
|
||||
};
|
||||
|
@ -868,8 +868,10 @@ WebAudioDecodeJob::OnFailure(ErrorCode aErrorCode)
|
||||
|
||||
// Ignore errors in calling the callback, since there is not much that we can
|
||||
// do about it here.
|
||||
ErrorResult rv;
|
||||
mFailureCallback->Call(rv);
|
||||
if (mFailureCallback) {
|
||||
ErrorResult rv;
|
||||
mFailureCallback->Call(rv);
|
||||
}
|
||||
|
||||
mContext->RemoveFromDecodeQueue(this);
|
||||
}
|
||||
|
@ -91,14 +91,14 @@ void TestSpecExample()
|
||||
ErrorResultMock rv;
|
||||
|
||||
// This test is copied from the example in the Web Audio spec
|
||||
const float t0 = 0.0,
|
||||
t1 = 0.1,
|
||||
t2 = 0.2,
|
||||
t3 = 0.3,
|
||||
t4 = 0.4,
|
||||
t5 = 0.6,
|
||||
t6 = 0.7/*,
|
||||
t7 = 1.0*/;
|
||||
const double t0 = 0.0,
|
||||
t1 = 0.1,
|
||||
t2 = 0.2,
|
||||
t3 = 0.3,
|
||||
t4 = 0.4,
|
||||
t5 = 0.6,
|
||||
t6 = 0.7/*,
|
||||
t7 = 1.0*/;
|
||||
timeline.SetValueAtTime(0.2f, t0, rv);
|
||||
is(rv, NS_OK, "SetValueAtTime succeeded");
|
||||
timeline.SetValueAtTime(0.3f, t1, rv);
|
||||
@ -115,22 +115,22 @@ void TestSpecExample()
|
||||
is(rv, NS_OK, "ExponentialRampToValueAtTime succeeded");
|
||||
// TODO: Add the SetValueCurveAtTime test
|
||||
|
||||
is(timeline.GetValueAtTime(0.0f), 0.2f, "Correct value");
|
||||
is(timeline.GetValueAtTime(0.05f), 0.2f, "Correct value");
|
||||
is(timeline.GetValueAtTime(0.1f), 0.3f, "Correct value");
|
||||
is(timeline.GetValueAtTime(0.15f), 0.3f, "Correct value");
|
||||
is(timeline.GetValueAtTime(0.2f), 0.4f, "Correct value");
|
||||
is(timeline.GetValueAtTime(0.25f), (0.4f + 1.0f) / 2, "Correct value");
|
||||
is(timeline.GetValueAtTime(0.3f), 1.0f, "Correct value");
|
||||
is(timeline.GetValueAtTime(0.35f), (1.0f + 0.15f) / 2, "Correct value");
|
||||
is(timeline.GetValueAtTime(0.4f), 0.15f, "Correct value");
|
||||
is(timeline.GetValueAtTime(0.45f), (0.15f * powf(0.75f / 0.15f, 0.05f / 0.2f)), "Correct value");
|
||||
is(timeline.GetValueAtTime(0.5f), (0.15f * powf(0.75f / 0.15f, 0.5f)), "Correct value");
|
||||
is(timeline.GetValueAtTime(0.55f), (0.15f * powf(0.75f / 0.15f, 0.15f / 0.2f)), "Correct value");
|
||||
is(timeline.GetValueAtTime(0.6f), 0.75f, "Correct value");
|
||||
is(timeline.GetValueAtTime(0.65f), (0.75f * powf(0.05 / 0.75f, 0.5f)), "Correct value");
|
||||
is(timeline.GetValueAtTime(0.7f), 0.05f, "Correct value");
|
||||
is(timeline.GetValueAtTime(1.0f), 0.05f, "Correct value");
|
||||
is(timeline.GetValueAtTime(0.0), 0.2f, "Correct value");
|
||||
is(timeline.GetValueAtTime(0.05), 0.2f, "Correct value");
|
||||
is(timeline.GetValueAtTime(0.1), 0.3f, "Correct value");
|
||||
is(timeline.GetValueAtTime(0.15), 0.3f, "Correct value");
|
||||
is(timeline.GetValueAtTime(0.2), 0.4f, "Correct value");
|
||||
is(timeline.GetValueAtTime(0.25), (0.4f + 1.0f) / 2, "Correct value");
|
||||
is(timeline.GetValueAtTime(0.3), 1.0f, "Correct value");
|
||||
is(timeline.GetValueAtTime(0.35), (1.0f + 0.15f) / 2, "Correct value");
|
||||
is(timeline.GetValueAtTime(0.4), 0.15f, "Correct value");
|
||||
is(timeline.GetValueAtTime(0.45), (0.15f * powf(0.75f / 0.15f, 0.05f / 0.2f)), "Correct value");
|
||||
is(timeline.GetValueAtTime(0.5), (0.15f * powf(0.75f / 0.15f, 0.5f)), "Correct value");
|
||||
is(timeline.GetValueAtTime(0.55), (0.15f * powf(0.75f / 0.15f, 0.15f / 0.2f)), "Correct value");
|
||||
is(timeline.GetValueAtTime(0.6), 0.75f, "Correct value");
|
||||
is(timeline.GetValueAtTime(0.65), (0.75f * powf(0.05 / 0.75f, 0.5f)), "Correct value");
|
||||
is(timeline.GetValueAtTime(0.7), 0.05f, "Correct value");
|
||||
is(timeline.GetValueAtTime(1.0), 0.05f, "Correct value");
|
||||
}
|
||||
|
||||
void TestInvalidEvents()
|
||||
@ -189,11 +189,11 @@ void TestEventReplacement()
|
||||
timeline.SetValueAtTime(20.0f, 0.1, rv);
|
||||
is(rv, NS_OK, "Event scheduling should be successful");
|
||||
is(timeline.GetEventCount(), 1u, "Event should be replaced");
|
||||
is(timeline.GetValueAtTime(0.1f), 20.0f, "The first event should be overwritten");
|
||||
is(timeline.GetValueAtTime(0.1), 20.0f, "The first event should be overwritten");
|
||||
timeline.LinearRampToValueAtTime(30.0f, 0.1, rv);
|
||||
is(rv, NS_OK, "Event scheduling should be successful");
|
||||
is(timeline.GetEventCount(), 2u, "Different event type should be appended");
|
||||
is(timeline.GetValueAtTime(0.1f), 30.0f, "The first event should be overwritten");
|
||||
is(timeline.GetValueAtTime(0.1), 30.0f, "The first event should be overwritten");
|
||||
}
|
||||
|
||||
void TestEventRemoval()
|
||||
@ -222,7 +222,7 @@ void TestBeforeFirstEvent()
|
||||
ErrorResultMock rv;
|
||||
|
||||
timeline.SetValueAtTime(20.0f, 1.0, rv);
|
||||
is(timeline.GetValueAtTime(0.5f), 10.0f, "Retrun the default value before the first event");
|
||||
is(timeline.GetValueAtTime(0.5), 10.0f, "Retrun the default value before the first event");
|
||||
}
|
||||
|
||||
void TestAfterLastValueEvent()
|
||||
@ -232,7 +232,7 @@ void TestAfterLastValueEvent()
|
||||
ErrorResultMock rv;
|
||||
|
||||
timeline.SetValueAtTime(20.0f, 1.0, rv);
|
||||
is(timeline.GetValueAtTime(1.5f), 20.0f, "Return the last value after the last SetValue event");
|
||||
is(timeline.GetValueAtTime(1.5), 20.0f, "Return the last value after the last SetValue event");
|
||||
}
|
||||
|
||||
void TestAfterLastTargetValueEvent()
|
||||
@ -242,7 +242,7 @@ void TestAfterLastTargetValueEvent()
|
||||
ErrorResultMock rv;
|
||||
|
||||
timeline.SetTargetAtTime(20.0f, 1.0, 5.0, rv);
|
||||
is(timeline.GetValueAtTime(10.f), (20.f + (10.f - 20.f) * expf(-9.0f / 5.0f)), "Return the value after the last SetTarget event based on the curve");
|
||||
is(timeline.GetValueAtTime(10.), (20.f + (10.f - 20.f) * expf(-9.0f / 5.0f)), "Return the value after the last SetTarget event based on the curve");
|
||||
}
|
||||
|
||||
void TestAfterLastTargetValueEventWithValueSet()
|
||||
@ -253,7 +253,7 @@ void TestAfterLastTargetValueEventWithValueSet()
|
||||
|
||||
timeline.SetValue(50.f);
|
||||
timeline.SetTargetAtTime(20.0f, 1.0, 5.0, rv);
|
||||
is(timeline.GetValueAtTime(10.f), (20.f + (50.f - 20.f) * expf(-9.0f / 5.0f)), "Return the value after SetValue and the last SetTarget event based on the curve");
|
||||
is(timeline.GetValueAtTime(10.), (20.f + (50.f - 20.f) * expf(-9.0f / 5.0f)), "Return the value after SetValue and the last SetTarget event based on the curve");
|
||||
}
|
||||
|
||||
void TestValue()
|
||||
@ -279,7 +279,7 @@ void TestLinearRampAtZero()
|
||||
ErrorResultMock rv;
|
||||
|
||||
timeline.LinearRampToValueAtTime(20.0f, 0.0, rv);
|
||||
is(timeline.GetValueAtTime(0.0f), 20.0f, "Should get the correct value when t0 == t1 == 0");
|
||||
is(timeline.GetValueAtTime(0.0), 20.0f, "Should get the correct value when t0 == t1 == 0");
|
||||
}
|
||||
|
||||
void TestExponentialRampAtZero()
|
||||
@ -289,7 +289,7 @@ void TestExponentialRampAtZero()
|
||||
ErrorResultMock rv;
|
||||
|
||||
timeline.ExponentialRampToValueAtTime(20.0f, 0.0, rv);
|
||||
is(timeline.GetValueAtTime(0.0f), 20.0f, "Should get the correct value when t0 == t1 == 0");
|
||||
is(timeline.GetValueAtTime(0.0), 20.0f, "Should get the correct value when t0 == t1 == 0");
|
||||
}
|
||||
|
||||
void TestLinearRampAtSameTime()
|
||||
@ -300,7 +300,7 @@ void TestLinearRampAtSameTime()
|
||||
|
||||
timeline.SetValueAtTime(5.0f, 1.0, rv);
|
||||
timeline.LinearRampToValueAtTime(20.0f, 1.0, rv);
|
||||
is(timeline.GetValueAtTime(1.0f), 20.0f, "Should get the correct value when t0 == t1");
|
||||
is(timeline.GetValueAtTime(1.0), 20.0f, "Should get the correct value when t0 == t1");
|
||||
}
|
||||
|
||||
void TestExponentialRampAtSameTime()
|
||||
@ -311,7 +311,7 @@ void TestExponentialRampAtSameTime()
|
||||
|
||||
timeline.SetValueAtTime(5.0f, 1.0, rv);
|
||||
timeline.ExponentialRampToValueAtTime(20.0f, 1.0, rv);
|
||||
is(timeline.GetValueAtTime(1.0f), 20.0f, "Should get the correct value when t0 == t1");
|
||||
is(timeline.GetValueAtTime(1.0), 20.0f, "Should get the correct value when t0 == t1");
|
||||
}
|
||||
|
||||
void TestSetTargetZeroTimeConstant()
|
||||
@ -321,7 +321,7 @@ void TestSetTargetZeroTimeConstant()
|
||||
ErrorResultMock rv;
|
||||
|
||||
timeline.SetTargetAtTime(20.0f, 1.0, 0.0, rv);
|
||||
is(timeline.GetValueAtTime(10.f), 20.f, "Should get the correct value with timeConstant == 0");
|
||||
is(timeline.GetValueAtTime(10.), 20.f, "Should get the correct value with timeConstant == 0");
|
||||
}
|
||||
|
||||
void TestExponentialInvalidPreviousZeroValue()
|
||||
|
@ -15,6 +15,7 @@ MOCHITEST_FILES := \
|
||||
test_bug808374.html \
|
||||
test_bug827541.html \
|
||||
test_bug839753.html \
|
||||
test_bug845960.html \
|
||||
test_AudioBuffer.html \
|
||||
test_AudioContext.html \
|
||||
test_AudioListener.html \
|
||||
|
20
content/media/webaudio/test/test_bug845960.html
Normal file
20
content/media/webaudio/test/test_bug845960.html
Normal file
@ -0,0 +1,20 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Crashtest for bug 845960</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
SpecialPowers.setBoolPref("media.webaudio.enabled", true);
|
||||
(new AudioContext()).decodeAudioData(new ArrayBuffer(0), function() {});
|
||||
ok(true, "Should not crash when the optional failure callback is not specified");
|
||||
SpecialPowers.clearUserPref("media.webaudio.enabled");
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -7,7 +7,6 @@
|
||||
#define nsContentSupportMap_h__
|
||||
|
||||
#include "pldhash.h"
|
||||
#include "nsFixedSizeAllocator.h"
|
||||
#include "nsTemplateMatch.h"
|
||||
|
||||
/**
|
||||
|
@ -8,7 +8,6 @@
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsRuleNetwork.h"
|
||||
#include "nsFixedSizeAllocator.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
|
||||
|
@ -7,7 +7,6 @@
|
||||
#define nsRDFConInstanceTestNode_h__
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsFixedSizeAllocator.h"
|
||||
#include "nsRDFTestNode.h"
|
||||
#include "nsIRDFResource.h"
|
||||
#include "nsIRDFDataSource.h"
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include "nsICollation.h"
|
||||
#include "nsCollationCID.h"
|
||||
|
||||
#include "nsFixedSizeAllocator.h"
|
||||
#include "nsResourceSet.h"
|
||||
#include "nsRuleNetwork.h"
|
||||
#include "nsRDFQuery.h"
|
||||
|
@ -6,7 +6,6 @@
|
||||
#ifndef nsXULTemplateResultSetRDF_h__
|
||||
#define nsXULTemplateResultSetRDF_h__
|
||||
|
||||
#include "nsFixedSizeAllocator.h"
|
||||
#include "nsISimpleEnumerator.h"
|
||||
#include "nsRuleNetwork.h"
|
||||
#include "nsRDFQuery.h"
|
||||
|
@ -2044,6 +2044,8 @@ nsDOMClassInfo::Init()
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(HTMLDocument, nsIDOMHTMLDocument)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLDocument)
|
||||
DOM_CLASSINFO_MAP_CONDITIONAL_ENTRY(nsIDocumentRegister,
|
||||
nsDocument::RegisterEnabled())
|
||||
DOM_CLASSINFO_DOCUMENT_MAP_ENTRIES
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
|
@ -696,6 +696,15 @@ GetWrapperCache(void* p)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Helper template for smart pointers to resolve ambiguity between
|
||||
// GetWrappeCache(void*) and GetWrapperCache(const ParentObject&).
|
||||
template <template <typename> class SmartPtr, typename T>
|
||||
inline nsWrapperCache*
|
||||
GetWrapperCache(const SmartPtr<T>& aObject)
|
||||
{
|
||||
return GetWrapperCache(aObject.get());
|
||||
}
|
||||
|
||||
/**
|
||||
* A method to handle new-binding wrap failure, by possibly falling back to
|
||||
* wrapping as a non-new-binding object.
|
||||
|
@ -59,8 +59,8 @@ public:
|
||||
// Overrides:
|
||||
NS_IMETHOD GetInternalStream(nsIInputStream**);
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(ArchiveZipFile, nsIDOMFile)
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ArchiveZipFile, nsDOMFileCC)
|
||||
|
||||
protected:
|
||||
virtual already_AddRefed<nsIDOMBlob> CreateSlice(uint64_t aStart,
|
||||
|
@ -418,6 +418,11 @@ IndexedDatabaseManager::GetOrCreate()
|
||||
nsCOMPtr<nsIObserverService> obs = GetObserverService();
|
||||
NS_ENSURE_TRUE(obs, nullptr);
|
||||
|
||||
// Must initialize the storage service on the main thread.
|
||||
nsCOMPtr<mozIStorageService> ss =
|
||||
do_GetService(MOZ_STORAGE_SERVICE_CONTRACTID);
|
||||
NS_ENSURE_TRUE(ss, nullptr);
|
||||
|
||||
// We need this callback to know when to shut down all our threads.
|
||||
rv = obs->AddObserver(instance, PROFILE_BEFORE_CHANGE_OBSERVER_ID, false);
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
|
@ -29,6 +29,7 @@ SDK_XPIDLSRCS = \
|
||||
nsIDOMNodeList.idl \
|
||||
nsIDOMProcessingInstruction.idl \
|
||||
nsIDOMText.idl \
|
||||
nsIDocumentRegister.idl \
|
||||
$(NULL)
|
||||
XPIDLSRCS = \
|
||||
nsIDOMDOMStringList.idl \
|
||||
|
16
dom/interfaces/core/nsIDocumentRegister.idl
Normal file
16
dom/interfaces/core/nsIDocumentRegister.idl
Normal file
@ -0,0 +1,16 @@
|
||||
/* -*- 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(e35935bd-ebae-4e0d-93bf-efa93ab14c05)]
|
||||
interface nsIDocumentRegister : nsISupports
|
||||
{
|
||||
[optional_argc,
|
||||
implicit_jscontext] jsval register(in DOMString name,
|
||||
[optional] in jsval options)
|
||||
raises(DOMException);
|
||||
};
|
||||
|
@ -48,6 +48,7 @@ XPIDLSRCS = \
|
||||
nsIDOMUserProximityEvent.idl \
|
||||
nsIDOMDeviceOrientationEvent.idl \
|
||||
nsIDOMDeviceMotionEvent.idl \
|
||||
nsIDOMElementReplaceEvent.idl \
|
||||
nsIDOMScrollAreaEvent.idl \
|
||||
nsIDOMTransitionEvent.idl \
|
||||
nsIDOMAnimationEvent.idl \
|
||||
|
24
dom/interfaces/events/nsIDOMElementReplaceEvent.idl
Normal file
24
dom/interfaces/events/nsIDOMElementReplaceEvent.idl
Normal file
@ -0,0 +1,24 @@
|
||||
/* -*- 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 "nsIDOMEvent.idl"
|
||||
|
||||
interface nsIDOMElement;
|
||||
|
||||
[scriptable, builtinclass, uuid(19a31767-54bf-4044-8769-cd172e37eca2)]
|
||||
interface nsIDOMElementReplaceEvent : nsIDOMEvent
|
||||
{
|
||||
readonly attribute nsIDOMElement upgrade;
|
||||
|
||||
void initElementReplaceEvent(in DOMString typeArg,
|
||||
in boolean canBubbleArg,
|
||||
in boolean canCancelArg,
|
||||
in nsIDOMElement upgrade);
|
||||
};
|
||||
|
||||
dictionary ElementReplaceEventInit : EventInit
|
||||
{
|
||||
nsIDOMElement upgrade;
|
||||
};
|
@ -10315,7 +10315,7 @@ let ICCRecordHelper = {
|
||||
* @param onerror Callback to be called when error.
|
||||
*/
|
||||
readEmail: function readEmail(fileId, fileType, recordNumber, onsuccess, onerror) {
|
||||
function callback(optoins) {
|
||||
function callback(options) {
|
||||
let strLen = Buf.readUint32();
|
||||
let octetLen = strLen / 2;
|
||||
let email = null;
|
||||
@ -10362,7 +10362,7 @@ let ICCRecordHelper = {
|
||||
* @param onerror Callback to be called when error.
|
||||
*/
|
||||
readANR: function readANR(fileId, fileType, recordNumber, onsuccess, onerror) {
|
||||
function callback(optoins) {
|
||||
function callback(options) {
|
||||
let strLen = Buf.readUint32();
|
||||
let octetLen = strLen / 2;
|
||||
let number = null;
|
||||
|
@ -64,6 +64,7 @@ var interfaceNamesInGlobalScope =
|
||||
"HTMLOptionElement",
|
||||
"Pkcs11",
|
||||
"NotifyAudioAvailableEvent",
|
||||
"ElementReplaceEvent",
|
||||
"Array",
|
||||
"SVGZoomAndPan",
|
||||
"XULPopupElement",
|
||||
|
@ -21,6 +21,7 @@ DIRS += [
|
||||
'storageevent',
|
||||
'pointerlock',
|
||||
'webapps',
|
||||
'webcomponents',
|
||||
]
|
||||
|
||||
#needs IPC support, also tests do not run successfully in Firefox for now
|
||||
|
18
dom/tests/mochitest/webcomponents/Makefile.in
Normal file
18
dom/tests/mochitest/webcomponents/Makefile.in
Normal file
@ -0,0 +1,18 @@
|
||||
# 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/.
|
||||
|
||||
DEPTH = @DEPTH@
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
relativesrcdir = @relativesrcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MOCHITEST_FILES = \
|
||||
test_document_register.html \
|
||||
test_document_register_lifecycle.html \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
5
dom/tests/mochitest/webcomponents/moz.build
Normal file
5
dom/tests/mochitest/webcomponents/moz.build
Normal file
@ -0,0 +1,5 @@
|
||||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
@ -0,0 +1,90 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=783129
|
||||
-->
|
||||
<head>
|
||||
<title>Test for document.register using custom prototype</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
|
||||
<script>
|
||||
var gElementUpgraded = false;
|
||||
var gElementReplaced = false;
|
||||
|
||||
function elementUpgrade() {
|
||||
gElementUpgraded = true;
|
||||
|
||||
// Check for prototype on upgraded element.
|
||||
var documentElement = document.getElementById("grabme");
|
||||
ok(documentElement.hello, "Upgraded element should inherit 'hello' method from prototype.");
|
||||
documentElement.hello();
|
||||
|
||||
var customChild = document.getElementById("kid");
|
||||
ok(customChild, "Upgrade should preserve children.");
|
||||
ok(customChild.parentNode == documentElement, "Parent should be updated to new custom element.");
|
||||
|
||||
// Try creating new element and checking for prototype.
|
||||
var constructedElement = document.createElement("x-hello");
|
||||
ok(constructedElement.hello, "Created element should inherit 'hello' method from prototype.");
|
||||
constructedElement.hello();
|
||||
}
|
||||
|
||||
function elementReplace(e) {
|
||||
gElementReplaced = true;
|
||||
|
||||
ok(e.upgrade != e.target, "Upgraded element should be different from the target.");
|
||||
ok(e.upgrade.firstElementChild.id == "kid", "Upgrade element should have a child.");
|
||||
ok(e.target.firstElementChild.id == "kid", "Replacement element should have a child.");
|
||||
}
|
||||
|
||||
function startTest() {
|
||||
// Create a prototype that inheits from HTMLElement.
|
||||
var customProto = {};
|
||||
customProto.__proto__ = HTMLElement.prototype;
|
||||
customProto.hello = function() {
|
||||
ok(true, "Custom element should use provided prototype.");
|
||||
};
|
||||
|
||||
var oldElem = document.getElementById("grabme");
|
||||
oldElem.addEventListener("elementreplace", elementReplace);
|
||||
|
||||
document.addEventListener("elementupgrade", elementUpgrade);
|
||||
var elementConstructor = document.register("x-hello", { prototype: customProto });
|
||||
|
||||
// Try creating new element and checking for prototype.
|
||||
var constructedElement = new elementConstructor();
|
||||
ok(constructedElement.hello, "Created element should inherit 'hello' method from prototype.");
|
||||
constructedElement.hello();
|
||||
|
||||
ok(!oldElem.hello, "Element obtained prior to registration should not have inherited prototype.");
|
||||
|
||||
ok(gElementUpgraded && gElementReplaced, "Upgrade and replace events should have been fired.");
|
||||
|
||||
// Check that custom elements registered without a prototype inherit from HTMLElement.
|
||||
document.register("x-bye");
|
||||
var byeElement = document.createElement("x-bye");
|
||||
ok(byeElement.__proto__.__proto__, HTMLElement.prototype, "Element registered without prototype should inherit from HTMLElement.");
|
||||
|
||||
// Check that element registration with a prototype that does not inherit from HTMLElement results in exception.
|
||||
try {
|
||||
document.register("x-foo", { "prototype": {} });
|
||||
ok(false, "Prototype that does not inherit from HTMLElement should throw exception");
|
||||
} catch (ex) {
|
||||
ok(true, "Prototype that does not inherit from HTMLElement should throw exception");
|
||||
}
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body onload="startTest()">
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=783129">Bug 783129</a>
|
||||
<x-hello id="grabme">
|
||||
<div id="kid"></div>
|
||||
</x-hello>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,49 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=783129
|
||||
-->
|
||||
<head>
|
||||
<title>Test for document.register lifecycle callback</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
|
||||
<script>
|
||||
|
||||
var gLifecycleCallbackCalled = false;
|
||||
|
||||
var lifecycleCallbacks = {
|
||||
created: function() {
|
||||
is(this.getAttribute("id"), "grabme", "|this| value should be the upgrade element");
|
||||
gLifecycleCallbackCalled = true;
|
||||
}
|
||||
};
|
||||
|
||||
function startTest() {
|
||||
var HtmlProto = function() {};
|
||||
HtmlProto.prototype = HTMLElement.prototype;
|
||||
|
||||
// Create a prototype that inheits from HTMLElement.
|
||||
var customProto = new HtmlProto();
|
||||
customProto.hello = function() {
|
||||
ok(true, "Custom element should use provided prototype.");
|
||||
};
|
||||
|
||||
var elementConstructor = document.register("x-hello", { prototype: customProto, lifecycle: lifecycleCallbacks });
|
||||
|
||||
ok(gLifecycleCallbackCalled, "Lifecycle callback should be called.");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body onload="startTest()">
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=783129">Bug 783129</a>
|
||||
<x-hello id="grabme">
|
||||
<div id="kid"></div>
|
||||
</x-hello>
|
||||
</body>
|
||||
</html>
|
@ -228,6 +228,12 @@ partial interface Document {
|
||||
void mozExitPointerLock ();
|
||||
};
|
||||
|
||||
//http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html#dfn-document-register
|
||||
partial interface Document {
|
||||
[Throws, Pref="dom.webcomponents.enabled"]
|
||||
object register(DOMString name, optional ElementRegistrationOptions options);
|
||||
};
|
||||
|
||||
// http://dvcs.w3.org/hg/webperf/raw-file/tip/specs/PageVisibility/Overview.html#sec-document-interface
|
||||
partial interface Document {
|
||||
readonly attribute boolean hidden;
|
||||
|
@ -20,8 +20,12 @@ interface HTMLAreaElement : HTMLElement {
|
||||
attribute DOMString coords;
|
||||
[SetterThrows]
|
||||
attribute DOMString shape;
|
||||
// No support for stringifier attributes yet
|
||||
//[SetterThrows]
|
||||
//stringifier attribute DOMString href;
|
||||
stringifier;
|
||||
[SetterThrows]
|
||||
stringifier attribute DOMString href;
|
||||
attribute DOMString href;
|
||||
[SetterThrows]
|
||||
attribute DOMString target;
|
||||
[SetterThrows]
|
||||
|
24
dom/webidl/WebComponents.webidl
Normal file
24
dom/webidl/WebComponents.webidl
Normal file
@ -0,0 +1,24 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* The origin of this IDL file is
|
||||
* http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html
|
||||
*
|
||||
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
|
||||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
interface DocumentFragment;
|
||||
|
||||
callback LifecycleCreatedCallback = void();
|
||||
|
||||
dictionary LifecycleCallbacks {
|
||||
LifecycleCreatedCallback? created = null;
|
||||
};
|
||||
|
||||
dictionary ElementRegistrationOptions {
|
||||
object? prototype = null;
|
||||
LifecycleCallbacks lifecycle;
|
||||
};
|
||||
|
@ -217,6 +217,7 @@ webidl_files = \
|
||||
TreeWalker.webidl \
|
||||
URL.webidl \
|
||||
ValidityState.webidl \
|
||||
WebComponents.webidl \
|
||||
WebSocket.webidl \
|
||||
UndoManager.webidl \
|
||||
URLUtils.webidl \
|
||||
|
@ -39,7 +39,6 @@
|
||||
#include "nsIDOMDocumentFragment.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMHTMLAnchorElement.h"
|
||||
#include "nsIDOMHTMLBodyElement.h"
|
||||
#include "nsIDOMHTMLEmbedElement.h"
|
||||
#include "nsIDOMHTMLFrameElement.h"
|
||||
#include "nsIDOMHTMLIFrameElement.h"
|
||||
@ -48,9 +47,6 @@
|
||||
#include "nsIDOMHTMLLinkElement.h"
|
||||
#include "nsIDOMHTMLObjectElement.h"
|
||||
#include "nsIDOMHTMLScriptElement.h"
|
||||
#include "nsIDOMHTMLTableCellElement.h"
|
||||
#include "nsIDOMHTMLTableElement.h"
|
||||
#include "nsIDOMHTMLTableRowElement.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIDOMRange.h"
|
||||
#include "nsIDocument.h"
|
||||
@ -737,30 +733,24 @@ nsHTMLEditor::GetAttributeToModifyOnNode(nsIDOMNode *aNode, nsAString &aAttr)
|
||||
}
|
||||
|
||||
NS_NAMED_LITERAL_STRING(bgStr, "background");
|
||||
nsCOMPtr<nsIDOMHTMLBodyElement> nodeAsBody = do_QueryInterface(aNode);
|
||||
if (nodeAsBody)
|
||||
{
|
||||
nsCOMPtr<dom::Element> element = do_QueryInterface(aNode);
|
||||
if (element && element->IsHTML(nsGkAtoms::body)) {
|
||||
aAttr = bgStr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLTableElement> nodeAsTable = do_QueryInterface(aNode);
|
||||
if (nodeAsTable)
|
||||
{
|
||||
if (element && element->IsHTML(nsGkAtoms::table)) {
|
||||
aAttr = bgStr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLTableRowElement> nodeAsTableRow = do_QueryInterface(aNode);
|
||||
if (nodeAsTableRow)
|
||||
{
|
||||
if (element && element->IsHTML(nsGkAtoms::tr)) {
|
||||
aAttr = bgStr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLTableCellElement> nodeAsTableCell = do_QueryInterface(aNode);
|
||||
if (nodeAsTableCell)
|
||||
{
|
||||
if (element &&
|
||||
(element->IsHTML(nsGkAtoms::td) || element->IsHTML(nsGkAtoms::th))) {
|
||||
aAttr = bgStr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -55,10 +55,6 @@
|
||||
|
||||
#include "nsIDOMNodeFilter.h"
|
||||
#include "nsIDOMProcessingInstruction.h"
|
||||
#include "nsIDOMHTMLBodyElement.h"
|
||||
#include "nsIDOMHTMLTableElement.h"
|
||||
#include "nsIDOMHTMLTableRowElement.h"
|
||||
#include "nsIDOMHTMLTableCellElement.h"
|
||||
#include "nsIDOMHTMLAnchorElement.h"
|
||||
#include "nsIDOMHTMLAreaElement.h"
|
||||
#include "nsIDOMHTMLImageElement.h"
|
||||
@ -2734,30 +2730,22 @@ nsresult nsWebBrowserPersist::OnWalkDOMNode(nsIDOMNode *aNode)
|
||||
}
|
||||
#endif // MOZ_MEDIA
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLBodyElement> nodeAsBody = do_QueryInterface(aNode);
|
||||
if (nodeAsBody)
|
||||
{
|
||||
if (content->IsHTML(nsGkAtoms::body)) {
|
||||
StoreURIAttribute(aNode, "background");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLTableElement> nodeAsTable = do_QueryInterface(aNode);
|
||||
if (nodeAsTable)
|
||||
{
|
||||
if (content->IsHTML(nsGkAtoms::table)) {
|
||||
StoreURIAttribute(aNode, "background");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLTableRowElement> nodeAsTableRow = do_QueryInterface(aNode);
|
||||
if (nodeAsTableRow)
|
||||
{
|
||||
if (content->IsHTML(nsGkAtoms::tr)) {
|
||||
StoreURIAttribute(aNode, "background");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLTableCellElement> nodeAsTableCell = do_QueryInterface(aNode);
|
||||
if (nodeAsTableCell)
|
||||
{
|
||||
if (content->IsHTML(nsGkAtoms::td) || content->IsHTML(nsGkAtoms::th)) {
|
||||
StoreURIAttribute(aNode, "background");
|
||||
return NS_OK;
|
||||
}
|
||||
@ -3024,9 +3012,7 @@ nsWebBrowserPersist::CloneNodeWithFixedUpAttributes(
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLBodyElement> nodeAsBody = do_QueryInterface(aNodeIn);
|
||||
if (nodeAsBody)
|
||||
{
|
||||
if (content->IsHTML(nsGkAtoms::body)) {
|
||||
rv = GetNodeToFixup(aNodeIn, aNodeOut);
|
||||
if (NS_SUCCEEDED(rv) && *aNodeOut)
|
||||
{
|
||||
@ -3035,9 +3021,7 @@ nsWebBrowserPersist::CloneNodeWithFixedUpAttributes(
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLTableElement> nodeAsTable = do_QueryInterface(aNodeIn);
|
||||
if (nodeAsTable)
|
||||
{
|
||||
if (content->IsHTML(nsGkAtoms::table)) {
|
||||
rv = GetNodeToFixup(aNodeIn, aNodeOut);
|
||||
if (NS_SUCCEEDED(rv) && *aNodeOut)
|
||||
{
|
||||
@ -3046,9 +3030,7 @@ nsWebBrowserPersist::CloneNodeWithFixedUpAttributes(
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLTableRowElement> nodeAsTableRow = do_QueryInterface(aNodeIn);
|
||||
if (nodeAsTableRow)
|
||||
{
|
||||
if (content->IsHTML(nsGkAtoms::tr)) {
|
||||
rv = GetNodeToFixup(aNodeIn, aNodeOut);
|
||||
if (NS_SUCCEEDED(rv) && *aNodeOut)
|
||||
{
|
||||
@ -3057,9 +3039,7 @@ nsWebBrowserPersist::CloneNodeWithFixedUpAttributes(
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLTableCellElement> nodeAsTableCell = do_QueryInterface(aNodeIn);
|
||||
if (nodeAsTableCell)
|
||||
{
|
||||
if (content->IsHTML(nsGkAtoms::td) || content->IsHTML(nsGkAtoms::th)) {
|
||||
rv = GetNodeToFixup(aNodeIn, aNodeOut);
|
||||
if (NS_SUCCEEDED(rv) && *aNodeOut)
|
||||
{
|
||||
|
@ -574,7 +574,7 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
|
||||
}
|
||||
|
||||
// We're ready for final setup.
|
||||
InitFramebuffers();
|
||||
fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
|
||||
|
||||
if (mCaps.any)
|
||||
DetermineCaps();
|
||||
|
@ -606,11 +606,6 @@ public:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void InitFramebuffers() {
|
||||
MakeCurrent();
|
||||
BindFB(0);
|
||||
}
|
||||
|
||||
private:
|
||||
void GetShaderPrecisionFormatNonES2(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
|
||||
switch (precisiontype) {
|
||||
@ -1173,7 +1168,10 @@ public:
|
||||
if (!CreateScreenBuffer(size, caps))
|
||||
return false;
|
||||
|
||||
InitFramebuffers();
|
||||
MakeCurrent();
|
||||
fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
|
||||
fScissor(0, 0, size.width, size.height);
|
||||
fViewport(0, 0, size.width, size.height);
|
||||
|
||||
mCaps = mScreen->Caps();
|
||||
UpdateGLFormats(caps);
|
||||
|
@ -113,7 +113,6 @@ public:
|
||||
if (!InitWithPrefix("gl", true))
|
||||
return false;
|
||||
|
||||
InitFramebuffers();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -348,8 +348,8 @@ public:
|
||||
}
|
||||
|
||||
SetupLookupFunction();
|
||||
|
||||
bool ok = InitWithPrefix("gl", true);
|
||||
if (!InitWithPrefix("gl", true))
|
||||
return false;
|
||||
|
||||
PR_STATIC_ASSERT(sizeof(GLint) >= sizeof(int32_t));
|
||||
mMaxTextureImageSize = INT32_MAX;
|
||||
@ -358,10 +358,7 @@ public:
|
||||
sEGLLibrary.HasKHRImageTexture2D() &&
|
||||
IsExtensionSupported(OES_EGL_image);
|
||||
|
||||
if (ok)
|
||||
InitFramebuffers();
|
||||
|
||||
return ok;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsDoubleBuffered() {
|
||||
|
@ -864,8 +864,6 @@ TRY_AGAIN_NO_SHARING:
|
||||
if (!IsExtensionSupported(EXT_framebuffer_object))
|
||||
return false;
|
||||
|
||||
InitFramebuffers();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -319,7 +319,6 @@ public:
|
||||
if (!InitWithPrefix("gl", true))
|
||||
return false;
|
||||
|
||||
InitFramebuffers();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -109,6 +109,13 @@ DeclMarker(TypeObject, types::TypeObject)
|
||||
|
||||
#undef DeclMarker
|
||||
|
||||
/* Return true if the pointer is NULL, or if it is a tagged pointer to NULL. */
|
||||
JS_ALWAYS_INLINE bool
|
||||
IsNullTaggedPointer(void *p)
|
||||
{
|
||||
return uintptr_t(p) < 32;
|
||||
}
|
||||
|
||||
/*** Externally Typed Marking ***/
|
||||
|
||||
/*
|
||||
|
@ -46,7 +46,7 @@ static inline void
|
||||
MarkExactStackRoot(JSTracer *trc, Rooted<void*> *rooter, ThingRootKind kind)
|
||||
{
|
||||
void **addr = (void **)rooter->address();
|
||||
if (!*addr)
|
||||
if (IsNullTaggedPointer(*addr))
|
||||
return;
|
||||
|
||||
if (kind == THING_ROOT_OBJECT && *addr == Proxy::LazyProto)
|
||||
|
3
js/src/jit-test/tests/basic/bug839313.js
Normal file
3
js/src/jit-test/tests/basic/bug839313.js
Normal file
@ -0,0 +1,3 @@
|
||||
// Bug 839313: Verify that 'it' does not leave JS_AddValueRoot roots lying around.
|
||||
var dbg = new Debugger;
|
||||
it.customNative = assertEq;
|
@ -1121,7 +1121,9 @@ class FastInvokeGuard
|
||||
RootedFunction fun_;
|
||||
RootedScript script_;
|
||||
#ifdef JS_ION
|
||||
ion::IonContext ictx_;
|
||||
// Constructing an IonContext is pretty expensive due to the TLS access,
|
||||
// so only do this if we have to.
|
||||
mozilla::Maybe<ion::IonContext> ictx_;
|
||||
bool useIon_;
|
||||
#endif
|
||||
|
||||
@ -1130,7 +1132,6 @@ class FastInvokeGuard
|
||||
: fun_(cx)
|
||||
, script_(cx)
|
||||
#ifdef JS_ION
|
||||
, ictx_(cx, cx->compartment, NULL)
|
||||
, useIon_(ion::IsEnabled(cx))
|
||||
#endif
|
||||
{
|
||||
@ -1155,6 +1156,8 @@ class FastInvokeGuard
|
||||
bool invoke(JSContext *cx) {
|
||||
#ifdef JS_ION
|
||||
if (useIon_ && fun_) {
|
||||
if (ictx_.empty())
|
||||
ictx_.construct(cx, cx->compartment, (js::ion::TempAllocator *)NULL);
|
||||
JS_ASSERT(fun_->nonLazyScript() == script_);
|
||||
|
||||
ion::MethodStatus status = ion::CanEnterUsingFastInvoke(cx, script_, args_.length());
|
||||
|
@ -359,7 +359,7 @@ js::ObjectImpl::writeBarrierPre(ObjectImpl *obj)
|
||||
* This would normally be a null test, but TypeScript::global uses 0x1 as a
|
||||
* special value.
|
||||
*/
|
||||
if (uintptr_t(obj) < 32)
|
||||
if (IsNullTaggedPointer(obj))
|
||||
return;
|
||||
|
||||
Zone *zone = obj->zone();
|
||||
@ -376,7 +376,7 @@ js::ObjectImpl::writeBarrierPre(ObjectImpl *obj)
|
||||
js::ObjectImpl::writeBarrierPost(ObjectImpl *obj, void *addr)
|
||||
{
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
if (uintptr_t(obj) < 32)
|
||||
if (IsNullTaggedPointer(obj))
|
||||
return;
|
||||
obj->runtime()->gcStoreBuffer.putCell((Cell **)addr);
|
||||
#endif
|
||||
|
@ -39,6 +39,7 @@ simple_events = [
|
||||
'MozVoicemailEvent',
|
||||
'USSDReceivedEvent',
|
||||
#endif
|
||||
'ElementReplaceEvent',
|
||||
'MozSmsEvent',
|
||||
'DeviceStorageChangeEvent',
|
||||
'PopupBlockedEvent',
|
||||
|
@ -30,8 +30,6 @@
|
||||
#include "nsTableColGroupFrame.h"
|
||||
#include "nsTableColFrame.h"
|
||||
#include "nsIDOMHTMLDocument.h"
|
||||
#include "nsIDOMHTMLTableColElement.h"
|
||||
#include "nsIDOMHTMLTableCaptionElem.h"
|
||||
#include "nsHTMLParts.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
|
@ -5512,6 +5512,12 @@ PresShell::Paint(nsView* aViewToPaint,
|
||||
aViewToPaint->GetWidget()->GetLayerManager(&isRetainingManager);
|
||||
NS_ASSERTION(layerManager, "Must be in paint event");
|
||||
|
||||
if (!layerManager) {
|
||||
// Crash so we get a good stack on how this code is getting triggered.
|
||||
// See bug 847002 for details.
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
// Whether or not we should set first paint when painting is
|
||||
// suppressed is debatable. For now we'll do it because
|
||||
// B2G relies on first paint to configure the viewport and
|
||||
|
@ -20,11 +20,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=93077
|
||||
<p><a name=TOP>Top</a></p>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
if (navigator.platform.startsWith("Linux")) {
|
||||
SimpleTest.expectAssertions(0, 2); // bug 846096
|
||||
}
|
||||
|
||||
/** Test for Bug 93077 **/
|
||||
["#top", "#Top"].forEach(function(fragid) {
|
||||
document.getElementById("below").scrollIntoView()
|
||||
|
@ -16,10 +16,6 @@
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
if (!navigator.platform.startsWith("Win")) {
|
||||
SimpleTest.expectAssertions(0, 2); // bug 846096
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var startPaintCount = window.mozPaintCount;
|
||||
|
@ -14,10 +14,6 @@
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
|
||||
if (!navigator.platform.startsWith("Win")) {
|
||||
SimpleTest.expectAssertions(0, 2); // bug 846096
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var canvases = [];
|
||||
|
@ -20,10 +20,6 @@
|
||||
<script type="application/javascript;version=1.7">
|
||||
"use strict";
|
||||
|
||||
if (!navigator.platform.startsWith("Win")) {
|
||||
SimpleTest.expectAssertions(0, 2); // bug 846096
|
||||
}
|
||||
|
||||
var referenceSnapshot;
|
||||
var iterations = 0;
|
||||
|
||||
|
@ -67,10 +67,6 @@
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
if (navigator.platform.startsWith("Mac")) {
|
||||
SimpleTest.expectAssertions(0, 2); // bug 846096
|
||||
}
|
||||
|
||||
var ANCHOR = 0;
|
||||
var FOCUS = 1;
|
||||
|
||||
|
@ -330,7 +330,6 @@ nsLayoutStatics::Shutdown()
|
||||
|
||||
nsAttrValue::Shutdown();
|
||||
nsContentUtils::Shutdown();
|
||||
nsNodeInfo::ClearCache();
|
||||
nsLayoutStylesheetCache::Shutdown();
|
||||
NS_NameSpaceManagerShutdown();
|
||||
|
||||
|
@ -63,7 +63,6 @@
|
||||
#include "nsBidiPresUtils.h"
|
||||
#endif // IBMBIDI
|
||||
|
||||
#include "nsIDOMHTMLBodyElement.h"
|
||||
#include "nsIDOMHTMLHtmlElement.h"
|
||||
|
||||
static const int MIN_LINES_NEEDING_CURSOR = 20;
|
||||
|
@ -16,8 +16,6 @@
|
||||
#include "nsContainerFrame.h"
|
||||
#include "nsBlockFrame.h"
|
||||
#include "nsLineBox.h"
|
||||
#include "nsIDOMHTMLTableCellElement.h"
|
||||
#include "nsIDOMHTMLBodyElement.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIDOMHTMLTableCellElement.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsCSSRendering.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDOMHTMLTableColElement.h"
|
||||
|
||||
#define COL_TYPE_BITS (NS_FRAME_STATE_BIT(28) | \
|
||||
NS_FRAME_STATE_BIT(29) | \
|
||||
|
@ -5,7 +5,6 @@
|
||||
#include "nsTableColGroupFrame.h"
|
||||
#include "nsTableColFrame.h"
|
||||
#include "nsTableFrame.h"
|
||||
#include "nsIDOMHTMLTableColElement.h"
|
||||
#include "nsStyleContext.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsPresContext.h"
|
||||
|
@ -33,7 +33,6 @@
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMHTMLElement.h"
|
||||
#include "nsIDOMHTMLBodyElement.h"
|
||||
#include "nsFrameManager.h"
|
||||
#include "nsError.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
@ -31,6 +31,7 @@ EXPORTS_mtransport = \
|
||||
../dtlsidentity.h \
|
||||
../nricectx.h \
|
||||
../nricemediastream.h \
|
||||
../nriceresolverfake.h \
|
||||
../transportflow.h \
|
||||
../transportlayer.h \
|
||||
../transportlayerdtls.h \
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user