Merge mozilla-central to mozilla-inbound

This commit is contained in:
Ed Morley 2013-03-05 10:30:18 +00:00
commit 9c7a020058
154 changed files with 2822 additions and 545 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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");

View File

@ -627,4 +627,5 @@ chatbox {
chatbar {
-moz-binding: url("chrome://browser/content/socialchat.xml#chatbar");
height: 0;
max-height: 0;
}

View File

@ -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();
});
});
});
});
});
});
});

View File

@ -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) {

View File

@ -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;

View File

@ -31,7 +31,7 @@ BROWSER_TESTS = \
$(NULL)
BROWSER_TEST_RESOURCES = \
res\image01.png \
res/image01.png \
$(NULL)
libs:: $(BROWSER_TESTS)

View File

@ -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);

View File

@ -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();
}

View File

@ -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)
{

View File

@ -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/. */

View File

@ -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);

View File

@ -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;

View File

@ -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:

View File

@ -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

View File

@ -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();
};

View File

@ -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;

View File

@ -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

View File

@ -54,6 +54,7 @@ MOCHITEST_CHROME_FILES = \
test_domparsing.xul \
test_bug814638.xul \
host_bug814638.xul \
test_document_register.xul \
frame_bug814638.xul \
$(NULL)

View 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>

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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)
{

View File

@ -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);

View File

@ -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;

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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();

View File

@ -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[];

View File

@ -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;
}

View File

@ -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 \

View File

@ -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>

View 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>

View File

@ -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"

View File

@ -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;
};

View File

@ -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];
}
}
}

View File

@ -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.

View File

@ -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);
}
}
}

View File

@ -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;
};

View File

@ -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);
}

View File

@ -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()

View File

@ -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 \

View 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>

View File

@ -7,7 +7,6 @@
#define nsContentSupportMap_h__
#include "pldhash.h"
#include "nsFixedSizeAllocator.h"
#include "nsTemplateMatch.h"
/**

View File

@ -8,7 +8,6 @@
#include "nscore.h"
#include "nsRuleNetwork.h"
#include "nsFixedSizeAllocator.h"
#include "nsIAtom.h"
#include "nsIDOMDocument.h"

View File

@ -7,7 +7,6 @@
#define nsRDFConInstanceTestNode_h__
#include "nscore.h"
#include "nsFixedSizeAllocator.h"
#include "nsRDFTestNode.h"
#include "nsIRDFResource.h"
#include "nsIRDFDataSource.h"

View File

@ -18,7 +18,6 @@
#include "nsICollation.h"
#include "nsCollationCID.h"
#include "nsFixedSizeAllocator.h"
#include "nsResourceSet.h"
#include "nsRuleNetwork.h"
#include "nsRDFQuery.h"

View File

@ -6,7 +6,6 @@
#ifndef nsXULTemplateResultSetRDF_h__
#define nsXULTemplateResultSetRDF_h__
#include "nsFixedSizeAllocator.h"
#include "nsISimpleEnumerator.h"
#include "nsRuleNetwork.h"
#include "nsRDFQuery.h"

View File

@ -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

View File

@ -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.

View File

@ -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,

View File

@ -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);

View File

@ -29,6 +29,7 @@ SDK_XPIDLSRCS = \
nsIDOMNodeList.idl \
nsIDOMProcessingInstruction.idl \
nsIDOMText.idl \
nsIDocumentRegister.idl \
$(NULL)
XPIDLSRCS = \
nsIDOMDOMStringList.idl \

View 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);
};

View File

@ -48,6 +48,7 @@ XPIDLSRCS = \
nsIDOMUserProximityEvent.idl \
nsIDOMDeviceOrientationEvent.idl \
nsIDOMDeviceMotionEvent.idl \
nsIDOMElementReplaceEvent.idl \
nsIDOMScrollAreaEvent.idl \
nsIDOMTransitionEvent.idl \
nsIDOMAnimationEvent.idl \

View 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;
};

View File

@ -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;

View File

@ -64,6 +64,7 @@ var interfaceNamesInGlobalScope =
"HTMLOptionElement",
"Pkcs11",
"NotifyAudioAvailableEvent",
"ElementReplaceEvent",
"Array",
"SVGZoomAndPan",
"XULPopupElement",

View File

@ -21,6 +21,7 @@ DIRS += [
'storageevent',
'pointerlock',
'webapps',
'webcomponents',
]
#needs IPC support, also tests do not run successfully in Firefox for now

View 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

View 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/.

View File

@ -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>

View File

@ -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>

View File

@ -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;

View File

@ -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]

View 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;
};

View File

@ -217,6 +217,7 @@ webidl_files = \
TreeWalker.webidl \
URL.webidl \
ValidityState.webidl \
WebComponents.webidl \
WebSocket.webidl \
UndoManager.webidl \
URLUtils.webidl \

View File

@ -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;
}

View File

@ -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)
{

View File

@ -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();

View File

@ -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);

View File

@ -113,7 +113,6 @@ public:
if (!InitWithPrefix("gl", true))
return false;
InitFramebuffers();
return true;
}

View File

@ -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() {

View File

@ -864,8 +864,6 @@ TRY_AGAIN_NO_SHARING:
if (!IsExtensionSupported(EXT_framebuffer_object))
return false;
InitFramebuffers();
return true;
}

View File

@ -319,7 +319,6 @@ public:
if (!InitWithPrefix("gl", true))
return false;
InitFramebuffers();
return true;
}

View File

@ -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 ***/
/*

View File

@ -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)

View 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;

View File

@ -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());

View File

@ -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

View File

@ -39,6 +39,7 @@ simple_events = [
'MozVoicemailEvent',
'USSDReceivedEvent',
#endif
'ElementReplaceEvent',
'MozSmsEvent',
'DeviceStorageChangeEvent',
'PopupBlockedEvent',

View File

@ -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"

View File

@ -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

View File

@ -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()

View File

@ -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;

View File

@ -14,10 +14,6 @@
</style>
<script type="text/javascript">
if (!navigator.platform.startsWith("Win")) {
SimpleTest.expectAssertions(0, 2); // bug 846096
}
SimpleTest.waitForExplicitFinish();
var canvases = [];

View File

@ -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;

View File

@ -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;

View File

@ -330,7 +330,6 @@ nsLayoutStatics::Shutdown()
nsAttrValue::Shutdown();
nsContentUtils::Shutdown();
nsNodeInfo::ClearCache();
nsLayoutStylesheetCache::Shutdown();
NS_NameSpaceManagerShutdown();

View File

@ -63,7 +63,6 @@
#include "nsBidiPresUtils.h"
#endif // IBMBIDI
#include "nsIDOMHTMLBodyElement.h"
#include "nsIDOMHTMLHtmlElement.h"
static const int MIN_LINES_NEEDING_CURSOR = 20;

View File

@ -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"

View File

@ -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"

View File

@ -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) | \

View File

@ -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"

View File

@ -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"

View File

@ -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