diff --git a/accessible/xpcom/xpcAccessibleTextRange.cpp b/accessible/xpcom/xpcAccessibleTextRange.cpp index 0ca9ebf8bf0a..b551542d31b1 100644 --- a/accessible/xpcom/xpcAccessibleTextRange.cpp +++ b/accessible/xpcom/xpcAccessibleTextRange.cpp @@ -11,6 +11,7 @@ #include "nsIMutableArray.h" #include "nsComponentManagerUtils.h" +#include "nsQueryObject.h" using namespace mozilla; using namespace mozilla::a11y; diff --git a/accessible/xul/XULTreeAccessible.cpp b/accessible/xul/XULTreeAccessible.cpp index f754fa520150..0d3685333735 100644 --- a/accessible/xul/XULTreeAccessible.cpp +++ b/accessible/xul/XULTreeAccessible.cpp @@ -17,6 +17,7 @@ #include "Role.h" #include "States.h" #include "XULTreeGridAccessible.h" +#include "nsQueryObject.h" #include "nsComponentManagerUtils.h" #include "nsIAccessibleRelation.h" diff --git a/accessible/xul/XULTreeGridAccessible.cpp b/accessible/xul/XULTreeGridAccessible.cpp index c8c4bd978f34..1aee464acfb1 100644 --- a/accessible/xul/XULTreeGridAccessible.cpp +++ b/accessible/xul/XULTreeGridAccessible.cpp @@ -13,6 +13,7 @@ #include "Relation.h" #include "Role.h" #include "States.h" +#include "nsQueryObject.h" #include "nsIBoxObject.h" #include "nsIMutableArray.h" diff --git a/browser/components/sessionstore/test/browser_354894_perwindowpb.js b/browser/components/sessionstore/test/browser_354894_perwindowpb.js index 682a8af65fc8..d7c2e2531bfd 100644 --- a/browser/components/sessionstore/test/browser_354894_perwindowpb.js +++ b/browser/components/sessionstore/test/browser_354894_perwindowpb.js @@ -368,24 +368,31 @@ function test() { browserWindowsCount([0, 1], "browser windows while running testOpenCloseRestoreFromPopup"); newWin = undoCloseWindow(0); + newWin.addEventListener("load", function whenloaded() { + newWin.removeEventListener("load", whenloaded, false); - whenNewWindowLoaded({}, function (newWin2) { - is(newWin2.gBrowser.browsers.length, 1, - "Did not restore, as undoCloseWindow() was last called"); - is(TEST_URLS.indexOf(newWin2.gBrowser.browsers[0].currentURI.spec), -1, - "Did not restore, as undoCloseWindow() was last called (2)"); + newWin.gBrowser.tabContainer.addEventListener("SSTabRestored", function whenSSTabRestored() { + newWin.gBrowser.tabContainer.removeEventListener("SSTabRestored", whenSSTabRestored, false); - browserWindowsCount([2, 3], "browser windows while running testOpenCloseRestoreFromPopup"); + whenNewWindowLoaded({}, function (newWin2) { + is(newWin2.gBrowser.browsers.length, 1, + "Did not restore, as undoCloseWindow() was last called"); + is(TEST_URLS.indexOf(newWin2.gBrowser.browsers[0].currentURI.spec), -1, + "Did not restore, as undoCloseWindow() was last called (2)"); - // Cleanup - newWin.close(); - newWin2.close(); + browserWindowsCount([2, 3], "browser windows while running testOpenCloseRestoreFromPopup"); - browserWindowsCount([0, 1], "browser windows while running testOpenCloseRestoreFromPopup"); + // Cleanup + newWin.close(); + newWin2.close(); - // Next please - executeSoon(nextFn); - }); + browserWindowsCount([0, 1], "browser windows while running testOpenCloseRestoreFromPopup"); + + // Next please + executeSoon(nextFn); + }); + }, false); + }, false); }); }); } diff --git a/chrome/nsChromeRegistry.cpp b/chrome/nsChromeRegistry.cpp index dfdc4d1451f2..9a041401adbf 100644 --- a/chrome/nsChromeRegistry.cpp +++ b/chrome/nsChromeRegistry.cpp @@ -15,6 +15,7 @@ #include "nsEscape.h" #include "nsNetUtil.h" #include "nsString.h" +#include "nsQueryObject.h" #include "mozilla/CSSStyleSheet.h" #include "mozilla/dom/URL.h" diff --git a/docshell/base/nsDSURIContentListener.cpp b/docshell/base/nsDSURIContentListener.cpp index e72bdf49ccd4..b8434f40155b 100644 --- a/docshell/base/nsDSURIContentListener.cpp +++ b/docshell/base/nsDSURIContentListener.cpp @@ -14,6 +14,7 @@ #include "nsIDOMWindow.h" #include "nsNetUtil.h" #include "nsAutoPtr.h" +#include "nsQueryObject.h" #include "nsIHttpChannel.h" #include "nsIScriptSecurityManager.h" #include "nsError.h" diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index ac365ef72bf1..2e6891325705 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -59,6 +59,7 @@ #include "nsContentPolicyUtils.h" // NS_CheckContentLoadPolicy(...) #include "nsISeekableStream.h" #include "nsAutoPtr.h" +#include "nsQueryObject.h" #include "nsIWritablePropertyBag2.h" #include "nsIAppShell.h" #include "nsWidgetsCID.h" diff --git a/dom/base/NodeInfo.cpp b/dom/base/NodeInfo.cpp index 50ba1e1b4e8e..8c60eee4f455 100644 --- a/dom/base/NodeInfo.cpp +++ b/dom/base/NodeInfo.cpp @@ -37,10 +37,6 @@ using mozilla::dom::NodeInfo; NodeInfo::~NodeInfo() { mOwnerManager->RemoveNodeInfo(this); - - NS_RELEASE(mInner.mName); - NS_IF_RELEASE(mInner.mPrefix); - NS_IF_RELEASE(mInner.mExtraName); } NodeInfo::NodeInfo(nsIAtom *aName, nsIAtom *aPrefix, int32_t aNamespaceID, @@ -51,12 +47,12 @@ NodeInfo::NodeInfo(nsIAtom *aName, nsIAtom *aPrefix, int32_t aNamespaceID, MOZ_ASSERT(aOwnerManager, "Invalid aOwnerManager"); // Initialize mInner - NS_ADDREF(mInner.mName = aName); - NS_IF_ADDREF(mInner.mPrefix = aPrefix); + mInner.mName = aName; + mInner.mPrefix = aPrefix; mInner.mNamespaceID = aNamespaceID; mInner.mNodeType = aNodeType; mOwnerManager = aOwnerManager; - NS_IF_ADDREF(mInner.mExtraName = aExtraName); + mInner.mExtraName = aExtraName; mDocument = aOwnerManager->GetDocument(); diff --git a/dom/base/NodeInfo.h b/dom/base/NodeInfo.h index 443855c4a7ad..87751d8145a9 100644 --- a/dom/base/NodeInfo.h +++ b/dom/base/NodeInfo.h @@ -26,8 +26,8 @@ #include "mozilla/dom/NameSpaceConstants.h" #include "nsStringGlue.h" #include "mozilla/Attributes.h" +#include "nsIAtom.h" -class nsIAtom; class nsIDocument; class nsNodeInfoManager; @@ -263,14 +263,12 @@ protected: { } - // These atoms hold pointers to nsGkAtoms members, and are therefore safe - // as a non-owning reference. - nsIAtom* MOZ_NON_OWNING_REF mName; - nsIAtom* MOZ_NON_OWNING_REF mPrefix; + nsCOMPtr mName; + nsCOMPtr mPrefix; int32_t mNamespaceID; uint16_t mNodeType; // As defined by nsIDOMNode.nodeType const nsAString* mNameString; - nsIAtom* MOZ_NON_OWNING_REF mExtraName; // Only used by PIs and DocTypes + nsCOMPtr mExtraName; // Only used by PIs and DocTypes }; // nsNodeInfoManager needs to pass mInner to the hash table. diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index d8dd19052100..e6dbd511c325 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -115,6 +115,7 @@ #include "nsIDOMNode.h" #include "nsIDOMNodeList.h" #include "nsIDOMScriptObjectFactory.h" +#include "nsIDOMWindowUtils.h" #include "nsIDOMXULCommandEvent.h" #include "nsIDragService.h" #include "nsIEditor.h" @@ -7391,3 +7392,300 @@ nsContentUtils::GetSurfaceData(mozilla::gfx::DataSourceSurface* aSurface, aSurface->Unmap(); return surfaceData; } + +mozilla::Modifiers +nsContentUtils::GetWidgetModifiers(int32_t aModifiers) +{ + Modifiers result = 0; + if (aModifiers & nsIDOMWindowUtils::MODIFIER_SHIFT) { + result |= mozilla::MODIFIER_SHIFT; + } + if (aModifiers & nsIDOMWindowUtils::MODIFIER_CONTROL) { + result |= mozilla::MODIFIER_CONTROL; + } + if (aModifiers & nsIDOMWindowUtils::MODIFIER_ALT) { + result |= mozilla::MODIFIER_ALT; + } + if (aModifiers & nsIDOMWindowUtils::MODIFIER_META) { + result |= mozilla::MODIFIER_META; + } + if (aModifiers & nsIDOMWindowUtils::MODIFIER_ALTGRAPH) { + result |= mozilla::MODIFIER_ALTGRAPH; + } + if (aModifiers & nsIDOMWindowUtils::MODIFIER_CAPSLOCK) { + result |= mozilla::MODIFIER_CAPSLOCK; + } + if (aModifiers & nsIDOMWindowUtils::MODIFIER_FN) { + result |= mozilla::MODIFIER_FN; + } + if (aModifiers & nsIDOMWindowUtils::MODIFIER_FNLOCK) { + result |= mozilla::MODIFIER_FNLOCK; + } + if (aModifiers & nsIDOMWindowUtils::MODIFIER_NUMLOCK) { + result |= mozilla::MODIFIER_NUMLOCK; + } + if (aModifiers & nsIDOMWindowUtils::MODIFIER_SCROLLLOCK) { + result |= mozilla::MODIFIER_SCROLLLOCK; + } + if (aModifiers & nsIDOMWindowUtils::MODIFIER_SYMBOL) { + result |= mozilla::MODIFIER_SYMBOL; + } + if (aModifiers & nsIDOMWindowUtils::MODIFIER_SYMBOLLOCK) { + result |= mozilla::MODIFIER_SYMBOLLOCK; + } + if (aModifiers & nsIDOMWindowUtils::MODIFIER_OS) { + result |= mozilla::MODIFIER_OS; + } + return result; +} + +nsIWidget* +nsContentUtils::GetWidget(nsIPresShell* aPresShell, nsPoint* aOffset) { + if (aPresShell) { + nsIFrame* frame = aPresShell->GetRootFrame(); + if (frame) + return frame->GetView()->GetNearestWidget(aOffset); + } + return nullptr; +} + +int16_t +nsContentUtils::GetButtonsFlagForButton(int32_t aButton) +{ + switch (aButton) { + case WidgetMouseEvent::eLeftButton: + return WidgetMouseEvent::eLeftButtonFlag; + case WidgetMouseEvent::eMiddleButton: + return WidgetMouseEvent::eMiddleButtonFlag; + case WidgetMouseEvent::eRightButton: + return WidgetMouseEvent::eRightButtonFlag; + case 4: + return WidgetMouseEvent::e4thButtonFlag; + case 5: + return WidgetMouseEvent::e5thButtonFlag; + default: + NS_ERROR("Button not known."); + return 0; + } +} + +LayoutDeviceIntPoint +nsContentUtils::ToWidgetPoint(const CSSPoint& aPoint, + const nsPoint& aOffset, + nsPresContext* aPresContext) +{ + return LayoutDeviceIntPoint::FromAppUnitsRounded( + CSSPoint::ToAppUnits(aPoint) + aOffset, + aPresContext->AppUnitsPerDevPixel()); +} + +nsView* +nsContentUtils::GetViewToDispatchEvent(nsPresContext* presContext, + nsIPresShell** presShell) +{ + if (presContext && presShell) { + *presShell = presContext->PresShell(); + if (*presShell) { + NS_ADDREF(*presShell); + if (nsViewManager* viewManager = (*presShell)->GetViewManager()) { + if (nsView* view = viewManager->GetRootView()) { + return view; + } + } + } + } + return nullptr; +} + +nsresult +nsContentUtils::SendKeyEvent(nsCOMPtr aWidget, + const nsAString& aType, + int32_t aKeyCode, + int32_t aCharCode, + int32_t aModifiers, + uint32_t aAdditionalFlags, + bool* aDefaultActionTaken) +{ + // get the widget to send the event to + if (!aWidget) + return NS_ERROR_FAILURE; + + int32_t msg; + if (aType.EqualsLiteral("keydown")) + msg = NS_KEY_DOWN; + else if (aType.EqualsLiteral("keyup")) + msg = NS_KEY_UP; + else if (aType.EqualsLiteral("keypress")) + msg = NS_KEY_PRESS; + else + return NS_ERROR_FAILURE; + + WidgetKeyboardEvent event(true, msg, aWidget); + event.modifiers = GetWidgetModifiers(aModifiers); + + if (msg == NS_KEY_PRESS) { + event.keyCode = aCharCode ? 0 : aKeyCode; + event.charCode = aCharCode; + } else { + event.keyCode = aKeyCode; + event.charCode = 0; + } + + uint32_t locationFlag = (aAdditionalFlags & + (nsIDOMWindowUtils::KEY_FLAG_LOCATION_STANDARD | nsIDOMWindowUtils::KEY_FLAG_LOCATION_LEFT | + nsIDOMWindowUtils::KEY_FLAG_LOCATION_RIGHT | nsIDOMWindowUtils::KEY_FLAG_LOCATION_NUMPAD)); + switch (locationFlag) { + case nsIDOMWindowUtils::KEY_FLAG_LOCATION_STANDARD: + event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD; + break; + case nsIDOMWindowUtils::KEY_FLAG_LOCATION_LEFT: + event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_LEFT; + break; + case nsIDOMWindowUtils::KEY_FLAG_LOCATION_RIGHT: + event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_RIGHT; + break; + case nsIDOMWindowUtils::KEY_FLAG_LOCATION_NUMPAD: + event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_NUMPAD; + break; + default: + if (locationFlag != 0) { + return NS_ERROR_INVALID_ARG; + } + // If location flag isn't set, choose the location from keycode. + switch (aKeyCode) { + case nsIDOMKeyEvent::DOM_VK_NUMPAD0: + case nsIDOMKeyEvent::DOM_VK_NUMPAD1: + case nsIDOMKeyEvent::DOM_VK_NUMPAD2: + case nsIDOMKeyEvent::DOM_VK_NUMPAD3: + case nsIDOMKeyEvent::DOM_VK_NUMPAD4: + case nsIDOMKeyEvent::DOM_VK_NUMPAD5: + case nsIDOMKeyEvent::DOM_VK_NUMPAD6: + case nsIDOMKeyEvent::DOM_VK_NUMPAD7: + case nsIDOMKeyEvent::DOM_VK_NUMPAD8: + case nsIDOMKeyEvent::DOM_VK_NUMPAD9: + case nsIDOMKeyEvent::DOM_VK_MULTIPLY: + case nsIDOMKeyEvent::DOM_VK_ADD: + case nsIDOMKeyEvent::DOM_VK_SEPARATOR: + case nsIDOMKeyEvent::DOM_VK_SUBTRACT: + case nsIDOMKeyEvent::DOM_VK_DECIMAL: + case nsIDOMKeyEvent::DOM_VK_DIVIDE: + event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_NUMPAD; + break; + case nsIDOMKeyEvent::DOM_VK_SHIFT: + case nsIDOMKeyEvent::DOM_VK_CONTROL: + case nsIDOMKeyEvent::DOM_VK_ALT: + case nsIDOMKeyEvent::DOM_VK_META: + event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_LEFT; + break; + default: + event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD; + break; + } + break; + } + + event.refPoint.x = event.refPoint.y = 0; + event.time = PR_IntervalNow(); + if (!(aAdditionalFlags & nsIDOMWindowUtils::KEY_FLAG_NOT_SYNTHESIZED_FOR_TESTS)) { + event.mFlags.mIsSynthesizedForTests = true; + } + + if (aAdditionalFlags & nsIDOMWindowUtils::KEY_FLAG_PREVENT_DEFAULT) { + event.mFlags.mDefaultPrevented = true; + } + + nsEventStatus status; + nsresult rv = aWidget->DispatchEvent(&event, status); + NS_ENSURE_SUCCESS(rv, rv); + + *aDefaultActionTaken = (status != nsEventStatus_eConsumeNoDefault); + + return NS_OK; +} + +nsresult +nsContentUtils::SendMouseEvent(nsCOMPtr aPresShell, + const nsAString& aType, + float aX, + float aY, + int32_t aButton, + int32_t aClickCount, + int32_t aModifiers, + bool aIgnoreRootScrollFrame, + float aPressure, + unsigned short aInputSourceArg, + bool aToWindow, + bool *aPreventDefault, + bool aIsSynthesized) +{ + nsPoint offset; + nsCOMPtr widget = GetWidget(aPresShell, &offset); + if (!widget) + return NS_ERROR_FAILURE; + + int32_t msg; + bool contextMenuKey = false; + if (aType.EqualsLiteral("mousedown")) + msg = NS_MOUSE_BUTTON_DOWN; + else if (aType.EqualsLiteral("mouseup")) + msg = NS_MOUSE_BUTTON_UP; + else if (aType.EqualsLiteral("mousemove")) + msg = NS_MOUSE_MOVE; + else if (aType.EqualsLiteral("mouseover")) + msg = NS_MOUSE_ENTER; + else if (aType.EqualsLiteral("mouseout")) + msg = NS_MOUSE_EXIT; + else if (aType.EqualsLiteral("contextmenu")) { + msg = NS_CONTEXTMENU; + contextMenuKey = (aButton == 0); + } else if (aType.EqualsLiteral("MozMouseHittest")) + msg = NS_MOUSE_MOZHITTEST; + else + return NS_ERROR_FAILURE; + + if (aInputSourceArg == nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN) { + aInputSourceArg = nsIDOMMouseEvent::MOZ_SOURCE_MOUSE; + } + + WidgetMouseEvent event(true, msg, widget, WidgetMouseEvent::eReal, + contextMenuKey ? WidgetMouseEvent::eContextMenuKey : + WidgetMouseEvent::eNormal); + event.modifiers = GetWidgetModifiers(aModifiers); + event.button = aButton; + event.buttons = GetButtonsFlagForButton(aButton); + event.widget = widget; + event.pressure = aPressure; + event.inputSource = aInputSourceArg; + event.clickCount = aClickCount; + event.time = PR_IntervalNow(); + event.mFlags.mIsSynthesizedForTests = aIsSynthesized; + + nsPresContext* presContext = aPresShell->GetPresContext(); + if (!presContext) + return NS_ERROR_FAILURE; + + event.refPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext); + event.ignoreRootScrollFrame = aIgnoreRootScrollFrame; + + nsEventStatus status = nsEventStatus_eIgnore; + if (aToWindow) { + nsCOMPtr presShell; + nsView* view = GetViewToDispatchEvent(presContext, getter_AddRefs(presShell)); + if (!presShell || !view) { + return NS_ERROR_FAILURE; + } + return presShell->HandleEvent(view->GetFrame(), &event, false, &status); + } + if (gfxPrefs::TestEventsAsyncEnabled()) { + status = widget->DispatchInputEvent(&event); + } else { + nsresult rv = widget->DispatchEvent(&event, status); + NS_ENSURE_SUCCESS(rv, rv); + } + if (aPreventDefault) { + *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault); + } + + return NS_OK; +} + diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h index 1b2459379c9e..9a8895edfcc9 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -100,6 +100,7 @@ class nsScriptObjectTracer; class nsStringBuffer; class nsStringHashKey; class nsTextFragment; +class nsView; class nsViewportInfo; class nsWrapperCache; class nsAttrValue; @@ -2316,6 +2317,47 @@ public: static mozilla::UniquePtr GetSurfaceData(mozilla::gfx::DataSourceSurface* aSurface, size_t* aLength, int32_t* aStride); + // Helpers shared by the implementations of nsContentUtils methods and + // nsIDOMWindowUtils methods. + static mozilla::Modifiers GetWidgetModifiers(int32_t aModifiers); + static nsIWidget* GetWidget(nsIPresShell* aPresShell, nsPoint* aOffset); + static int16_t GetButtonsFlagForButton(int32_t aButton); + static mozilla::LayoutDeviceIntPoint ToWidgetPoint(const mozilla::CSSPoint& aPoint, + const nsPoint& aOffset, + nsPresContext* aPresContext); + static nsView* GetViewToDispatchEvent(nsPresContext* aPresContext, + nsIPresShell** aPresShell); + + /** + * Synthesize a key event to the given widget + * (see nsIDOMWindowUtils.sendKeyEvent). + */ + static nsresult SendKeyEvent(nsCOMPtr aWidget, + const nsAString& aType, + int32_t aKeyCode, + int32_t aCharCode, + int32_t aModifiers, + uint32_t aAdditionalFlags, + bool* aDefaultActionTaken); + + /** + * Synthesize a mouse event to the given widget + * (see nsIDOMWindowUtils.sendMouseEvent). + */ + static nsresult SendMouseEvent(nsCOMPtr aPresShell, + const nsAString& aType, + float aX, + float aY, + int32_t aButton, + int32_t aClickCount, + int32_t aModifiers, + bool aIgnoreRootScrollFrame, + float aPressure, + unsigned short aInputSourceArg, + bool aToWindow, + bool *aPreventDefault, + bool aIsSynthesized); + private: static bool InitializeEventTable(); diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index 8170cc8e5bfe..da2282e74901 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -24,6 +24,7 @@ #include "nsFrame.h" #include "mozilla/layers/ShadowLayers.h" #include "ClientLayerManager.h" +#include "nsQueryObject.h" #include "nsIScrollableFrame.h" @@ -591,53 +592,6 @@ nsDOMWindowUtils::GetPresShellId(uint32_t *aPresShellId) return NS_ERROR_FAILURE; } -/* static */ -mozilla::Modifiers -nsDOMWindowUtils::GetWidgetModifiers(int32_t aModifiers) -{ - Modifiers result = 0; - if (aModifiers & nsIDOMWindowUtils::MODIFIER_SHIFT) { - result |= mozilla::MODIFIER_SHIFT; - } - if (aModifiers & nsIDOMWindowUtils::MODIFIER_CONTROL) { - result |= mozilla::MODIFIER_CONTROL; - } - if (aModifiers & nsIDOMWindowUtils::MODIFIER_ALT) { - result |= mozilla::MODIFIER_ALT; - } - if (aModifiers & nsIDOMWindowUtils::MODIFIER_META) { - result |= mozilla::MODIFIER_META; - } - if (aModifiers & nsIDOMWindowUtils::MODIFIER_ALTGRAPH) { - result |= mozilla::MODIFIER_ALTGRAPH; - } - if (aModifiers & nsIDOMWindowUtils::MODIFIER_CAPSLOCK) { - result |= mozilla::MODIFIER_CAPSLOCK; - } - if (aModifiers & nsIDOMWindowUtils::MODIFIER_FN) { - result |= mozilla::MODIFIER_FN; - } - if (aModifiers & nsIDOMWindowUtils::MODIFIER_FNLOCK) { - result |= mozilla::MODIFIER_FNLOCK; - } - if (aModifiers & nsIDOMWindowUtils::MODIFIER_NUMLOCK) { - result |= mozilla::MODIFIER_NUMLOCK; - } - if (aModifiers & nsIDOMWindowUtils::MODIFIER_SCROLLLOCK) { - result |= mozilla::MODIFIER_SCROLLLOCK; - } - if (aModifiers & nsIDOMWindowUtils::MODIFIER_SYMBOL) { - result |= mozilla::MODIFIER_SYMBOL; - } - if (aModifiers & nsIDOMWindowUtils::MODIFIER_SYMBOLLOCK) { - result |= mozilla::MODIFIER_SYMBOLLOCK; - } - if (aModifiers & nsIDOMWindowUtils::MODIFIER_OS) { - result |= mozilla::MODIFIER_OS; - } - return result; -} - NS_IMETHODIMP nsDOMWindowUtils::SendMouseEvent(const nsAString& aType, float aX, @@ -680,52 +634,6 @@ nsDOMWindowUtils::SendMouseEventToWindow(const nsAString& aType, aOptionalArgCount >= 4 ? aIsSynthesized : true); } -static LayoutDeviceIntPoint -ToWidgetPoint(const CSSPoint& aPoint, const nsPoint& aOffset, - nsPresContext* aPresContext) -{ - return LayoutDeviceIntPoint::FromAppUnitsRounded( - CSSPoint::ToAppUnits(aPoint) + aOffset, - aPresContext->AppUnitsPerDevPixel()); -} - -static inline int16_t -GetButtonsFlagForButton(int32_t aButton) -{ - switch (aButton) { - case WidgetMouseEvent::eLeftButton: - return WidgetMouseEvent::eLeftButtonFlag; - case WidgetMouseEvent::eMiddleButton: - return WidgetMouseEvent::eMiddleButtonFlag; - case WidgetMouseEvent::eRightButton: - return WidgetMouseEvent::eRightButtonFlag; - case 4: - return WidgetMouseEvent::e4thButtonFlag; - case 5: - return WidgetMouseEvent::e5thButtonFlag; - default: - NS_ERROR("Button not known."); - return 0; - } -} - -nsView* -nsDOMWindowUtils::GetViewToDispatchEvent(nsPresContext* presContext, nsIPresShell** presShell) -{ - if (presContext && presShell) { - *presShell = presContext->PresShell(); - if (*presShell) { - NS_ADDREF(*presShell); - if (nsViewManager* viewManager = (*presShell)->GetViewManager()) { - if (nsView* view = viewManager->GetRootView()) { - return view; - } - } - } - } - return nullptr; -} - NS_IMETHODIMP nsDOMWindowUtils::SendMouseEventCommon(const nsAString& aType, float aX, @@ -742,76 +650,10 @@ nsDOMWindowUtils::SendMouseEventCommon(const nsAString& aType, { MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome()); - // get the widget to send the event to - nsPoint offset; - nsCOMPtr widget = GetWidget(&offset); - if (!widget) - return NS_ERROR_FAILURE; - - int32_t msg; - bool contextMenuKey = false; - if (aType.EqualsLiteral("mousedown")) - msg = NS_MOUSE_BUTTON_DOWN; - else if (aType.EqualsLiteral("mouseup")) - msg = NS_MOUSE_BUTTON_UP; - else if (aType.EqualsLiteral("mousemove")) - msg = NS_MOUSE_MOVE; - else if (aType.EqualsLiteral("mouseover")) - msg = NS_MOUSE_ENTER; - else if (aType.EqualsLiteral("mouseout")) - msg = NS_MOUSE_EXIT; - else if (aType.EqualsLiteral("contextmenu")) { - msg = NS_CONTEXTMENU; - contextMenuKey = (aButton == 0); - } else if (aType.EqualsLiteral("MozMouseHittest")) - msg = NS_MOUSE_MOZHITTEST; - else - return NS_ERROR_FAILURE; - - if (aInputSourceArg == nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN) { - aInputSourceArg = nsIDOMMouseEvent::MOZ_SOURCE_MOUSE; - } - - WidgetMouseEvent event(true, msg, widget, WidgetMouseEvent::eReal, - contextMenuKey ? WidgetMouseEvent::eContextMenuKey : - WidgetMouseEvent::eNormal); - event.modifiers = GetWidgetModifiers(aModifiers); - event.button = aButton; - event.buttons = GetButtonsFlagForButton(aButton); - event.widget = widget; - event.pressure = aPressure; - event.inputSource = aInputSourceArg; - event.clickCount = aClickCount; - event.time = PR_IntervalNow(); - event.mFlags.mIsSynthesizedForTests = aIsSynthesized; - - nsPresContext* presContext = GetPresContext(); - if (!presContext) - return NS_ERROR_FAILURE; - - event.refPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext); - event.ignoreRootScrollFrame = aIgnoreRootScrollFrame; - - nsEventStatus status = nsEventStatus_eIgnore; - if (aToWindow) { - nsCOMPtr presShell; - nsView* view = GetViewToDispatchEvent(presContext, getter_AddRefs(presShell)); - if (!presShell || !view) { - return NS_ERROR_FAILURE; - } - return presShell->HandleEvent(view->GetFrame(), &event, false, &status); - } - if (gfxPrefs::TestEventsAsyncEnabled()) { - status = widget->DispatchInputEvent(&event); - } else { - nsresult rv = widget->DispatchEvent(&event, status); - NS_ENSURE_SUCCESS(rv, rv); - } - if (aPreventDefault) { - *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault); - } - - return NS_OK; + nsCOMPtr presShell = GetPresShell(); + return nsContentUtils::SendMouseEvent(presShell, aType, aX, aY, aButton, + aClickCount, aModifiers, aIgnoreRootScrollFrame, aPressure, + aInputSourceArg, aToWindow, aPreventDefault, aIsSynthesized); } NS_IMETHODIMP @@ -864,9 +706,9 @@ nsDOMWindowUtils::SendPointerEventCommon(const nsAString& aType, } WidgetPointerEvent event(true, msg, widget); - event.modifiers = GetWidgetModifiers(aModifiers); + event.modifiers = nsContentUtils::GetWidgetModifiers(aModifiers); event.button = aButton; - event.buttons = GetButtonsFlagForButton(aButton); + event.buttons = nsContentUtils::GetButtonsFlagForButton(aButton); event.widget = widget; event.pressure = aPressure; event.inputSource = aInputSourceArg; @@ -885,13 +727,13 @@ nsDOMWindowUtils::SendPointerEventCommon(const nsAString& aType, return NS_ERROR_FAILURE; } - event.refPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext); + event.refPoint = nsContentUtils::ToWidgetPoint(CSSPoint(aX, aY), offset, presContext); event.ignoreRootScrollFrame = aIgnoreRootScrollFrame; nsEventStatus status; if (aToWindow) { nsCOMPtr presShell; - nsView* view = GetViewToDispatchEvent(presContext, getter_AddRefs(presShell)); + nsView* view = nsContentUtils::GetViewToDispatchEvent(presContext, getter_AddRefs(presShell)); if (!presShell || !view) { return NS_ERROR_FAILURE; } @@ -989,7 +831,7 @@ nsDOMWindowUtils::SendWheelEvent(float aX, } WidgetWheelEvent wheelEvent(true, NS_WHEEL_WHEEL, widget); - wheelEvent.modifiers = GetWidgetModifiers(aModifiers); + wheelEvent.modifiers = nsContentUtils::GetWidgetModifiers(aModifiers); wheelEvent.deltaX = aDeltaX; wheelEvent.deltaY = aDeltaY; wheelEvent.deltaZ = aDeltaZ; @@ -1009,7 +851,7 @@ nsDOMWindowUtils::SendWheelEvent(float aX, nsPresContext* presContext = GetPresContext(); NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE); - wheelEvent.refPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext); + wheelEvent.refPoint = nsContentUtils::ToWidgetPoint(CSSPoint(aX, aY), offset, presContext); widget->DispatchAPZAwareEvent(&wheelEvent); @@ -1136,7 +978,7 @@ nsDOMWindowUtils::SendTouchEventCommon(const nsAString& aType, return NS_ERROR_UNEXPECTED; } WidgetTouchEvent event(true, msg, widget); - event.modifiers = GetWidgetModifiers(aModifiers); + event.modifiers = nsContentUtils::GetWidgetModifiers(aModifiers); event.widget = widget; event.time = PR_Now(); @@ -1147,7 +989,7 @@ nsDOMWindowUtils::SendTouchEventCommon(const nsAString& aType, event.touches.SetCapacity(aCount); for (uint32_t i = 0; i < aCount; ++i) { LayoutDeviceIntPoint pt = - ToWidgetPoint(CSSPoint(aXs[i], aYs[i]), offset, presContext); + nsContentUtils::ToWidgetPoint(CSSPoint(aXs[i], aYs[i]), offset, presContext); nsRefPtr t = new Touch(aIdentifiers[i], pt, nsIntPoint(aRxs[i], aRys[i]), @@ -1159,7 +1001,7 @@ nsDOMWindowUtils::SendTouchEventCommon(const nsAString& aType, nsEventStatus status; if (aToWindow) { nsCOMPtr presShell; - nsView* view = GetViewToDispatchEvent(presContext, getter_AddRefs(presShell)); + nsView* view = nsContentUtils::GetViewToDispatchEvent(presContext, getter_AddRefs(presShell)); if (!presShell || !view) { return NS_ERROR_FAILURE; } @@ -1185,100 +1027,10 @@ nsDOMWindowUtils::SendKeyEvent(const nsAString& aType, // get the widget to send the event to nsCOMPtr widget = GetWidget(); - if (!widget) - return NS_ERROR_FAILURE; - - int32_t msg; - if (aType.EqualsLiteral("keydown")) - msg = NS_KEY_DOWN; - else if (aType.EqualsLiteral("keyup")) - msg = NS_KEY_UP; - else if (aType.EqualsLiteral("keypress")) - msg = NS_KEY_PRESS; - else - return NS_ERROR_FAILURE; - - WidgetKeyboardEvent event(true, msg, widget); - event.modifiers = GetWidgetModifiers(aModifiers); - - if (msg == NS_KEY_PRESS) { - event.keyCode = aCharCode ? 0 : aKeyCode; - event.charCode = aCharCode; - } else { - event.keyCode = aKeyCode; - event.charCode = 0; - } - - uint32_t locationFlag = (aAdditionalFlags & - (KEY_FLAG_LOCATION_STANDARD | KEY_FLAG_LOCATION_LEFT | - KEY_FLAG_LOCATION_RIGHT | KEY_FLAG_LOCATION_NUMPAD)); - switch (locationFlag) { - case KEY_FLAG_LOCATION_STANDARD: - event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD; - break; - case KEY_FLAG_LOCATION_LEFT: - event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_LEFT; - break; - case KEY_FLAG_LOCATION_RIGHT: - event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_RIGHT; - break; - case KEY_FLAG_LOCATION_NUMPAD: - event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_NUMPAD; - break; - default: - if (locationFlag != 0) { - return NS_ERROR_INVALID_ARG; - } - // If location flag isn't set, choose the location from keycode. - switch (aKeyCode) { - case nsIDOMKeyEvent::DOM_VK_NUMPAD0: - case nsIDOMKeyEvent::DOM_VK_NUMPAD1: - case nsIDOMKeyEvent::DOM_VK_NUMPAD2: - case nsIDOMKeyEvent::DOM_VK_NUMPAD3: - case nsIDOMKeyEvent::DOM_VK_NUMPAD4: - case nsIDOMKeyEvent::DOM_VK_NUMPAD5: - case nsIDOMKeyEvent::DOM_VK_NUMPAD6: - case nsIDOMKeyEvent::DOM_VK_NUMPAD7: - case nsIDOMKeyEvent::DOM_VK_NUMPAD8: - case nsIDOMKeyEvent::DOM_VK_NUMPAD9: - case nsIDOMKeyEvent::DOM_VK_MULTIPLY: - case nsIDOMKeyEvent::DOM_VK_ADD: - case nsIDOMKeyEvent::DOM_VK_SEPARATOR: - case nsIDOMKeyEvent::DOM_VK_SUBTRACT: - case nsIDOMKeyEvent::DOM_VK_DECIMAL: - case nsIDOMKeyEvent::DOM_VK_DIVIDE: - event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_NUMPAD; - break; - case nsIDOMKeyEvent::DOM_VK_SHIFT: - case nsIDOMKeyEvent::DOM_VK_CONTROL: - case nsIDOMKeyEvent::DOM_VK_ALT: - case nsIDOMKeyEvent::DOM_VK_META: - event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_LEFT; - break; - default: - event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD; - break; - } - break; - } - - event.refPoint.x = event.refPoint.y = 0; - event.time = PR_IntervalNow(); - if (!(aAdditionalFlags & KEY_FLAG_NOT_SYNTHESIZED_FOR_TESTS)) { - event.mFlags.mIsSynthesizedForTests = true; - } - - if (aAdditionalFlags & KEY_FLAG_PREVENT_DEFAULT) { - event.mFlags.mDefaultPrevented = true; - } - - nsEventStatus status; - nsresult rv = widget->DispatchEvent(&event, status); - NS_ENSURE_SUCCESS(rv, rv); - - *aDefaultActionTaken = (status != nsEventStatus_eConsumeNoDefault); - return NS_OK; + return nsContentUtils::SendKeyEvent(widget, aType, aKeyCode, aCharCode, + aModifiers, aAdditionalFlags, + aDefaultActionTaken); } NS_IMETHODIMP @@ -1451,11 +1203,7 @@ nsDOMWindowUtils::GetWidget(nsPoint* aOffset) nsIDocShell *docShell = window->GetDocShell(); if (docShell) { nsCOMPtr presShell = docShell->GetPresShell(); - if (presShell) { - nsIFrame* frame = presShell->GetRootFrame(); - if (frame) - return frame->GetView()->GetNearestWidget(aOffset); - } + return nsContentUtils::GetWidget(presShell, aOffset); } } @@ -1587,7 +1335,7 @@ nsDOMWindowUtils::SendSimpleGestureEvent(const nsAString& aType, return NS_ERROR_FAILURE; WidgetSimpleGestureEvent event(true, msg, widget); - event.modifiers = GetWidgetModifiers(aModifiers); + event.modifiers = nsContentUtils::GetWidgetModifiers(aModifiers); event.direction = aDirection; event.delta = aDelta; event.clickCount = aClickCount; @@ -1597,7 +1345,7 @@ nsDOMWindowUtils::SendSimpleGestureEvent(const nsAString& aType, if (!presContext) return NS_ERROR_FAILURE; - event.refPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext); + event.refPoint = nsContentUtils::ToWidgetPoint(CSSPoint(aX, aY), offset, presContext); nsEventStatus status; return widget->DispatchEvent(&event, status); @@ -3386,7 +3134,7 @@ nsDOMWindowUtils::SelectAtPoint(float aX, float aY, uint32_t aSelectBehavior, nsPoint offset; nsCOMPtr widget = GetWidget(&offset); LayoutDeviceIntPoint pt = - ToWidgetPoint(CSSPoint(aX, aY), offset, GetPresContext()); + nsContentUtils::ToWidgetPoint(CSSPoint(aX, aY), offset, GetPresContext()); nsPoint ptInRoot = nsLayoutUtils::GetEventCoordinatesRelativeTo(widget, pt, rootFrame); nsIFrame* targetFrame = nsLayoutUtils::GetFrameForPoint(rootFrame, ptInRoot); diff --git a/dom/base/nsDOMWindowUtils.h b/dom/base/nsDOMWindowUtils.h index aa13a3bd4c0f..4ba0c5fce342 100644 --- a/dom/base/nsDOMWindowUtils.h +++ b/dom/base/nsDOMWindowUtils.h @@ -81,8 +81,6 @@ protected: nsIDocument* GetDocument(); mozilla::layers::LayerTransactionChild* GetLayerTransaction(); - nsView* GetViewToDispatchEvent(nsPresContext* presContext, nsIPresShell** presShell); - NS_IMETHOD SendMouseEventCommon(const nsAString& aType, float aX, float aY, @@ -129,8 +127,6 @@ protected: bool aIgnoreRootScrollFrame, bool aToWindow, bool* aPreventDefault); - - static mozilla::Modifiers GetWidgetModifiers(int32_t aModifiers); }; #endif diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 9bf9d707ae1c..0708c4151bff 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -35,6 +35,7 @@ #include "nsDocShell.h" #include "nsIDocShellTreeItem.h" #include "nsCOMArray.h" +#include "nsQueryObject.h" #include "nsDOMClassInfo.h" #include "mozilla/Services.h" diff --git a/dom/base/nsFrameMessageManager.cpp b/dom/base/nsFrameMessageManager.cpp index c13de4c0d346..6b94a9f6ac84 100644 --- a/dom/base/nsFrameMessageManager.cpp +++ b/dom/base/nsFrameMessageManager.cpp @@ -44,6 +44,7 @@ #include "mozilla/jsipc/CrossProcessObjectWrappers.h" #include "nsPrintfCString.h" #include "nsXULAppAPI.h" +#include "nsQueryObject.h" #include #ifdef ANDROID diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 4b4cd5034f8e..2e0d233bef5d 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -120,6 +120,7 @@ #include "nsIControllerContext.h" #include "nsGlobalWindowCommands.h" #include "nsAutoPtr.h" +#include "nsQueryObject.h" #include "nsContentUtils.h" #include "nsCSSProps.h" #include "nsIDOMFileList.h" @@ -501,7 +502,9 @@ public: private: ~nsGlobalWindowObserver() {} - nsGlobalWindow* mWindow; + // This reference is non-owning and safe because it's cleared by + // nsGlobalWindow::CleanUp(). + nsGlobalWindow* MOZ_NON_OWNING_REF mWindow; }; NS_IMPL_ISUPPORTS(nsGlobalWindowObserver, nsIObserver, nsIInterfaceRequestor) @@ -1143,7 +1146,6 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow) mObserver = new nsGlobalWindowObserver(this); if (mObserver) { - NS_ADDREF(mObserver); nsCOMPtr os = mozilla::services::GetObserverService(); if (os) { // Watch for online/offline status changes so we can fire events. Use @@ -1163,8 +1165,6 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow) // remain frozen until they get an inner window, so freeze this // outer window here. Freeze(); - - mObserver = nullptr; } // We could have failed the first time through trying @@ -1462,7 +1462,6 @@ nsGlobalWindow::CleanUp() // Drop its reference to this dying window, in case for some bogus reason // the object stays around. mObserver->Forget(); - NS_RELEASE(mObserver); } if (mNavigator) { diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h index 58485263d28f..0597ce35d1b8 100644 --- a/dom/base/nsGlobalWindow.h +++ b/dom/base/nsGlobalWindow.h @@ -1625,7 +1625,7 @@ protected: nsRefPtr mWindowUtils; nsString mStatus; nsString mDefaultStatus; - nsGlobalWindowObserver* mObserver; // Inner windows only. + nsRefPtr mObserver; // Inner windows only. nsRefPtr mCrypto; nsRefPtr mCacheStorage; nsRefPtr mConsole; diff --git a/dom/base/nsStyleLinkElement.cpp b/dom/base/nsStyleLinkElement.cpp index 8e81eec07e99..adaa3ac57833 100644 --- a/dom/base/nsStyleLinkElement.cpp +++ b/dom/base/nsStyleLinkElement.cpp @@ -30,6 +30,7 @@ #include "nsUnicharInputStream.h" #include "nsContentUtils.h" #include "nsStyleUtil.h" +#include "nsQueryObject.h" using namespace mozilla; using namespace mozilla::dom; diff --git a/dom/base/nsTreeSanitizer.cpp b/dom/base/nsTreeSanitizer.cpp index 721107c0ff20..a3f02aa0f678 100644 --- a/dom/base/nsTreeSanitizer.cpp +++ b/dom/base/nsTreeSanitizer.cpp @@ -23,6 +23,7 @@ #include "nsContentUtils.h" #include "nsIParserUtils.h" #include "nsIDocument.h" +#include "nsQueryObject.h" using namespace mozilla; diff --git a/dom/bluetooth/BluetoothRilListener.cpp b/dom/bluetooth/BluetoothRilListener.cpp index 716c6b4f6340..d1f1e5075e3b 100644 --- a/dom/bluetooth/BluetoothRilListener.cpp +++ b/dom/bluetooth/BluetoothRilListener.cpp @@ -14,6 +14,7 @@ #include "nsITelephonyService.h" #include "nsServiceManagerUtils.h" #include "nsString.h" +#include "nsQueryObject.h" USING_BLUETOOTH_NAMESPACE diff --git a/dom/bluetooth/bluetooth2/BluetoothRilListener.cpp b/dom/bluetooth/bluetooth2/BluetoothRilListener.cpp new file mode 100644 index 000000000000..7f2da3512f48 --- /dev/null +++ b/dom/bluetooth/bluetooth2/BluetoothRilListener.cpp @@ -0,0 +1,453 @@ +/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "BluetoothRilListener.h" + +#include "BluetoothHfpManager.h" +#include "nsIIccService.h" +#include "nsIMobileConnectionInfo.h" +#include "nsIMobileConnectionService.h" +#include "nsITelephonyService.h" +#include "nsServiceManagerUtils.h" +#include "nsString.h" +#include "nsQueryObject.h" + +USING_BLUETOOTH_NAMESPACE + +/** + * IccListener + */ +NS_IMPL_ISUPPORTS(IccListener, nsIIccListener) + +NS_IMETHODIMP +IccListener::NotifyIccInfoChanged() +{ + // mOwner would be set to nullptr only in the dtor of BluetoothRilListener + NS_ENSURE_TRUE(mOwner, NS_ERROR_FAILURE); + + BluetoothHfpManager* hfp = BluetoothHfpManager::Get(); + NS_ENSURE_TRUE(hfp, NS_ERROR_FAILURE); + + hfp->HandleIccInfoChanged(mOwner->mClientId); + + return NS_OK; +} + +NS_IMETHODIMP +IccListener::NotifyStkCommand(const nsAString & aMessage) +{ + return NS_OK; +} + +NS_IMETHODIMP +IccListener::NotifyStkSessionEnd() +{ + return NS_OK; +} + +NS_IMETHODIMP +IccListener::NotifyCardStateChanged() +{ + return NS_OK; +} + +bool +IccListener::Listen(bool aStart) +{ + NS_ENSURE_TRUE(mOwner, false); + + nsCOMPtr service = + do_GetService(ICC_SERVICE_CONTRACTID); + NS_ENSURE_TRUE(service, false); + + nsCOMPtr icc; + service->GetIccByServiceId(mOwner->mClientId, getter_AddRefs(icc)); + NS_ENSURE_TRUE(icc, false); + + nsresult rv; + if (aStart) { + rv = icc->RegisterListener(this); + } else { + rv = icc->UnregisterListener(this); + } + + return NS_SUCCEEDED(rv); +} + +void +IccListener::SetOwner(BluetoothRilListener *aOwner) +{ + mOwner = aOwner; +} + +/** + * MobileConnectionListener + */ +NS_IMPL_ISUPPORTS(MobileConnectionListener, nsIMobileConnectionListener) + +NS_IMETHODIMP +MobileConnectionListener::NotifyVoiceChanged() +{ + BluetoothHfpManager* hfp = BluetoothHfpManager::Get(); + NS_ENSURE_TRUE(hfp, NS_OK); + + hfp->HandleVoiceConnectionChanged(mClientId); + + return NS_OK; +} + +NS_IMETHODIMP +MobileConnectionListener::NotifyDataChanged() +{ + return NS_OK; +} + +NS_IMETHODIMP +MobileConnectionListener::NotifyDataError(const nsAString & message) +{ + return NS_OK; +} + +NS_IMETHODIMP +MobileConnectionListener::NotifyCFStateChanged(uint16_t action, + uint16_t reason, + const nsAString& number, + uint16_t timeSeconds, + uint16_t serviceClass) +{ + return NS_OK; +} + +NS_IMETHODIMP +MobileConnectionListener::NotifyEmergencyCbModeChanged(bool active, + uint32_t timeoutMs) +{ + return NS_OK; +} + +NS_IMETHODIMP +MobileConnectionListener::NotifyOtaStatusChanged(const nsAString & status) +{ + return NS_OK; +} + +NS_IMETHODIMP +MobileConnectionListener::NotifyRadioStateChanged() +{ + return NS_OK; +} + +NS_IMETHODIMP +MobileConnectionListener::NotifyClirModeChanged(uint32_t aMode) +{ + return NS_OK; +} + +NS_IMETHODIMP +MobileConnectionListener::NotifyLastKnownNetworkChanged() +{ + return NS_OK; +} + +NS_IMETHODIMP +MobileConnectionListener::NotifyLastKnownHomeNetworkChanged() +{ + return NS_OK; +} + +NS_IMETHODIMP +MobileConnectionListener::NotifyNetworkSelectionModeChanged() +{ + return NS_OK; +} + +bool +MobileConnectionListener::Listen(bool aStart) +{ + nsCOMPtr service = + do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID); + NS_ENSURE_TRUE(service, false); + + nsCOMPtr connection; + service->GetItemByServiceId(mClientId, getter_AddRefs(connection)); + NS_ENSURE_TRUE(connection, false); + + nsresult rv; + if (aStart) { + rv = connection->RegisterListener(this); + } else { + rv = connection->UnregisterListener(this); + } + + return NS_SUCCEEDED(rv); +} + +/** + * TelephonyListener Implementation + */ +NS_IMPL_ISUPPORTS(TelephonyListener, nsITelephonyListener) + +/** + * @param aSend A boolean indicates whether we need to notify headset or not + */ +nsresult +TelephonyListener::HandleCallInfo(nsITelephonyCallInfo* aInfo, bool aSend) +{ + BluetoothHfpManager* hfp = BluetoothHfpManager::Get(); + NS_ENSURE_TRUE(hfp, NS_ERROR_FAILURE); + + uint32_t callIndex; + uint16_t callState; + nsAutoString number; + bool isOutgoing; + bool isConference; + + aInfo->GetCallIndex(&callIndex); + aInfo->GetCallState(&callState); + aInfo->GetNumber(number); + aInfo->GetIsOutgoing(&isOutgoing); + aInfo->GetIsConference(&isConference); + + hfp->HandleCallStateChanged(callIndex, callState, EmptyString(), number, + isOutgoing, isConference, aSend); + return NS_OK; +} + +NS_IMETHODIMP +TelephonyListener::CallStateChanged(nsITelephonyCallInfo* aInfo) +{ + return HandleCallInfo(aInfo, true); +} + +NS_IMETHODIMP +TelephonyListener::EnumerateCallState(nsITelephonyCallInfo* aInfo) +{ + return HandleCallInfo(aInfo, false); +} + +NS_IMETHODIMP +TelephonyListener::NotifyError(uint32_t aServiceId, + int32_t aCallIndex, + const nsAString& aError) +{ + BluetoothHfpManager* hfp = BluetoothHfpManager::Get(); + NS_ENSURE_TRUE(hfp, NS_ERROR_FAILURE); + + if (aCallIndex > 0) { + // In order to not miss any related call state transition. + // It's possible that 3G network signal lost for unknown reason. + // If a call is released abnormally, NotifyError() will be called, + // instead of CallStateChanged(). We need to reset the call array state + // via setting CALL_STATE_DISCONNECTED + hfp->HandleCallStateChanged(aCallIndex, + nsITelephonyService::CALL_STATE_DISCONNECTED, + aError, EmptyString(), false, false, true); + BT_WARNING("Reset the call state due to call transition ends abnormally"); + } + + BT_WARNING(NS_ConvertUTF16toUTF8(aError).get()); + return NS_OK; +} + +NS_IMETHODIMP +TelephonyListener::ConferenceCallStateChanged(uint16_t aCallState) +{ + return NS_OK; +} + +NS_IMETHODIMP +TelephonyListener::EnumerateCallStateComplete() +{ + return NS_OK; +} + +NS_IMETHODIMP +TelephonyListener::SupplementaryServiceNotification(uint32_t aServiceId, + int32_t aCallIndex, + uint16_t aNotification) +{ + return NS_OK; +} + +NS_IMETHODIMP +TelephonyListener::NotifyConferenceError(const nsAString& aName, + const nsAString& aMessage) +{ + BT_WARNING(NS_ConvertUTF16toUTF8(aName).get()); + BT_WARNING(NS_ConvertUTF16toUTF8(aMessage).get()); + + return NS_OK; +} + +NS_IMETHODIMP +TelephonyListener::NotifyCdmaCallWaiting(uint32_t aServiceId, + const nsAString& aNumber, + uint16_t aNumberPresentation, + const nsAString& aName, + uint16_t aNamePresentation) +{ + BluetoothHfpManager* hfp = BluetoothHfpManager::Get(); + NS_ENSURE_TRUE(hfp, NS_ERROR_FAILURE); + + hfp->UpdateSecondNumber(aNumber); + + return NS_OK; +} + +bool +TelephonyListener::Listen(bool aStart) +{ + nsCOMPtr service = + do_GetService(TELEPHONY_SERVICE_CONTRACTID); + NS_ENSURE_TRUE(service, false); + + nsresult rv; + if (aStart) { + rv = service->RegisterListener(this); + } else { + rv = service->UnregisterListener(this); + } + + return NS_SUCCEEDED(rv); +} + +/** + * BluetoothRilListener + */ +BluetoothRilListener::BluetoothRilListener() +{ + nsCOMPtr service = + do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID); + NS_ENSURE_TRUE_VOID(service); + + // Query number of total clients (sim slots) + uint32_t numItems = 0; + if (NS_SUCCEEDED(service->GetNumItems(&numItems))) { + // Init MobileConnectionListener array and IccInfoListener + for (uint32_t i = 0; i < numItems; i++) { + mMobileConnListeners.AppendElement(new MobileConnectionListener(i)); + } + } + + mTelephonyListener = new TelephonyListener(); + mIccListener = new IccListener(); + mIccListener->SetOwner(this); + + // Probe for available client + SelectClient(); +} + +BluetoothRilListener::~BluetoothRilListener() +{ + mIccListener->SetOwner(nullptr); +} + +bool +BluetoothRilListener::Listen(bool aStart) +{ + NS_ENSURE_TRUE(ListenMobileConnAndIccInfo(aStart), false); + NS_ENSURE_TRUE(mTelephonyListener->Listen(aStart), false); + + return true; +} + +void +BluetoothRilListener::SelectClient() +{ + // Reset mClientId + mClientId = mMobileConnListeners.Length(); + + nsCOMPtr service = + do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID); + NS_ENSURE_TRUE_VOID(service); + + for (uint32_t i = 0; i < mMobileConnListeners.Length(); i++) { + nsCOMPtr connection; + service->GetItemByServiceId(i, getter_AddRefs(connection)); + if (!connection) { + BT_WARNING("%s: Failed to get mobile connection", __FUNCTION__); + continue; + } + + nsCOMPtr voiceInfo; + connection->GetVoice(getter_AddRefs(voiceInfo)); + if (!voiceInfo) { + BT_WARNING("%s: Failed to get voice connection info", __FUNCTION__); + continue; + } + + nsString regState; + voiceInfo->GetState(regState); + if (regState.EqualsLiteral("registered")) { + // Found available client + mClientId = i; + return; + } + } +} + +void +BluetoothRilListener::ServiceChanged(uint32_t aClientId, bool aRegistered) +{ + // Stop listening + ListenMobileConnAndIccInfo(false); + + /** + * aRegistered: + * - TRUE: service becomes registered. We were listening to all clients + * and one of them becomes available. Select it to listen. + * - FALSE: service becomes un-registered. The client we were listening + * becomes unavailable. Select another registered one to listen. + */ + if (aRegistered) { + mClientId = aClientId; + } else { + SelectClient(); + } + + // Restart listening + ListenMobileConnAndIccInfo(true); + + BT_LOGR("%d client %d. new mClientId %d", aRegistered, aClientId, + (mClientId < mMobileConnListeners.Length()) ? mClientId : -1); +} + +void +BluetoothRilListener::EnumerateCalls() +{ + nsCOMPtr service = + do_GetService(TELEPHONY_SERVICE_CONTRACTID); + NS_ENSURE_TRUE_VOID(service); + + nsCOMPtr listener( + do_QueryObject(mTelephonyListener)); + + service->EnumerateCalls(listener); +} + +bool +BluetoothRilListener::ListenMobileConnAndIccInfo(bool aStart) +{ + /** + * mClientId < number of total clients: + * The client with mClientId is available. Start/Stop listening + * mobile connection and icc info of this client only. + * + * mClientId >= number of total clients: + * All clients are unavailable. Start/Stop listening mobile + * connections of all clients. + */ + if (mClientId < mMobileConnListeners.Length()) { + NS_ENSURE_TRUE(mMobileConnListeners[mClientId]->Listen(aStart), false); + NS_ENSURE_TRUE(mIccListener->Listen(aStart), false); + } else { + for (uint32_t i = 0; i < mMobileConnListeners.Length(); i++) { + NS_ENSURE_TRUE(mMobileConnListeners[i]->Listen(aStart), false); + } + } + + return true; +} diff --git a/dom/cache/DBAction.cpp b/dom/cache/DBAction.cpp index 3bfedce06ad4..0e37470c20d2 100644 --- a/dom/cache/DBAction.cpp +++ b/dom/cache/DBAction.cpp @@ -153,6 +153,7 @@ DBAction::OpenConnection(const QuotaInfo& aQuotaInfo, nsIFile* aDBDir, if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } rv = ss->OpenDatabaseWithFileURL(dbFileUrl, getter_AddRefs(conn)); + if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } } rv = db::InitializeConnection(conn); diff --git a/dom/cache/QuotaClient.cpp b/dom/cache/QuotaClient.cpp index 52b87ca2d872..fe8f281c58fe 100644 --- a/dom/cache/QuotaClient.cpp +++ b/dom/cache/QuotaClient.cpp @@ -153,6 +153,7 @@ public: if (isDir) { if (leafName.EqualsLiteral("morgue")) { rv = GetBodyUsage(file, aUsageInfo); + if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } } else { NS_WARNING("Unknown Cache directory found!"); } diff --git a/dom/cache/TypeUtils.cpp b/dom/cache/TypeUtils.cpp index 1c9b92d1bafa..990aeab44265 100644 --- a/dom/cache/TypeUtils.cpp +++ b/dom/cache/TypeUtils.cpp @@ -23,6 +23,7 @@ #include "nsIAsyncInputStream.h" #include "nsIAsyncOutputStream.h" #include "nsIIPCSerializableInputStream.h" +#include "nsQueryObject.h" #include "nsStreamUtils.h" #include "nsString.h" #include "nsURLParsers.h" diff --git a/dom/camera/DOMCameraControlListener.cpp b/dom/camera/DOMCameraControlListener.cpp index 3939c033b9cf..96f55ab2f09d 100644 --- a/dom/camera/DOMCameraControlListener.cpp +++ b/dom/camera/DOMCameraControlListener.cpp @@ -9,6 +9,7 @@ #include "CameraPreviewMediaStream.h" #include "mozilla/dom/CameraManagerBinding.h" #include "mozilla/dom/File.h" +#include "nsQueryObject.h" using namespace mozilla; using namespace mozilla::dom; diff --git a/dom/camera/DOMCameraManager.cpp b/dom/camera/DOMCameraManager.cpp index b936bc7733b2..95c0c1e305c5 100644 --- a/dom/camera/DOMCameraManager.cpp +++ b/dom/camera/DOMCameraManager.cpp @@ -19,6 +19,7 @@ #include "CameraPreferences.h" #include "mozilla/dom/BindingUtils.h" #include "mozilla/dom/PermissionMessageUtils.h" +#include "nsQueryObject.h" using namespace mozilla; using namespace mozilla::dom; diff --git a/dom/canvas/WebGLActiveInfo.cpp b/dom/canvas/WebGLActiveInfo.cpp index e0a1e06b8f9e..f0b32ceab709 100644 --- a/dom/canvas/WebGLActiveInfo.cpp +++ b/dom/canvas/WebGLActiveInfo.cpp @@ -16,16 +16,18 @@ ElemSizeFromType(GLenum elemType) case LOCAL_GL_BOOL: case LOCAL_GL_FLOAT: case LOCAL_GL_INT: - case LOCAL_GL_INT_SAMPLER_2D: - case LOCAL_GL_INT_SAMPLER_2D_ARRAY: - case LOCAL_GL_INT_SAMPLER_3D: - case LOCAL_GL_INT_SAMPLER_CUBE: + case LOCAL_GL_UNSIGNED_INT: case LOCAL_GL_SAMPLER_2D: + case LOCAL_GL_SAMPLER_3D: + case LOCAL_GL_SAMPLER_CUBE: + case LOCAL_GL_SAMPLER_2D_SHADOW: case LOCAL_GL_SAMPLER_2D_ARRAY: case LOCAL_GL_SAMPLER_2D_ARRAY_SHADOW: - case LOCAL_GL_SAMPLER_2D_SHADOW: - case LOCAL_GL_SAMPLER_CUBE: case LOCAL_GL_SAMPLER_CUBE_SHADOW: + case LOCAL_GL_INT_SAMPLER_2D: + case LOCAL_GL_INT_SAMPLER_3D: + case LOCAL_GL_INT_SAMPLER_CUBE: + case LOCAL_GL_INT_SAMPLER_2D_ARRAY: case LOCAL_GL_UNSIGNED_INT_SAMPLER_2D: case LOCAL_GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: case LOCAL_GL_UNSIGNED_INT_SAMPLER_3D: @@ -35,18 +37,20 @@ ElemSizeFromType(GLenum elemType) case LOCAL_GL_BOOL_VEC2: case LOCAL_GL_FLOAT_VEC2: case LOCAL_GL_INT_VEC2: + case LOCAL_GL_UNSIGNED_INT_VEC2: return 2; case LOCAL_GL_BOOL_VEC3: case LOCAL_GL_FLOAT_VEC3: case LOCAL_GL_INT_VEC3: + case LOCAL_GL_UNSIGNED_INT_VEC3: return 3; - case LOCAL_GL_BOOL_VEC4: - case LOCAL_GL_FLOAT_MAT2: case LOCAL_GL_FLOAT_VEC4: case LOCAL_GL_INT_VEC4: + case LOCAL_GL_UNSIGNED_INT_VEC4: + case LOCAL_GL_FLOAT_MAT2: return 4; case LOCAL_GL_FLOAT_MAT2x3: diff --git a/dom/canvas/WebGLUniformLocation.cpp b/dom/canvas/WebGLUniformLocation.cpp index 451434bafe77..14f7e774e66c 100644 --- a/dom/canvas/WebGLUniformLocation.cpp +++ b/dom/canvas/WebGLUniformLocation.cpp @@ -213,7 +213,20 @@ WebGLUniformLocation::GetUniform(JSContext* js, WebGLContext* webgl) const case LOCAL_GL_INT_VEC3: case LOCAL_GL_INT_VEC4: case LOCAL_GL_SAMPLER_2D: + case LOCAL_GL_SAMPLER_3D: case LOCAL_GL_SAMPLER_CUBE: + case LOCAL_GL_SAMPLER_2D_SHADOW: + case LOCAL_GL_SAMPLER_2D_ARRAY: + case LOCAL_GL_SAMPLER_2D_ARRAY_SHADOW: + case LOCAL_GL_SAMPLER_CUBE_SHADOW: + case LOCAL_GL_INT_SAMPLER_2D: + case LOCAL_GL_INT_SAMPLER_3D: + case LOCAL_GL_INT_SAMPLER_CUBE: + case LOCAL_GL_INT_SAMPLER_2D_ARRAY: + case LOCAL_GL_UNSIGNED_INT_SAMPLER_2D: + case LOCAL_GL_UNSIGNED_INT_SAMPLER_3D: + case LOCAL_GL_UNSIGNED_INT_SAMPLER_CUBE: + case LOCAL_GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: { GLint buffer[kMaxElemSize] = {0}; gl->fGetUniformiv(prog, mLoc, buffer); @@ -260,6 +273,12 @@ WebGLUniformLocation::GetUniform(JSContext* js, WebGLContext* webgl) const case LOCAL_GL_FLOAT_MAT2: case LOCAL_GL_FLOAT_MAT3: case LOCAL_GL_FLOAT_MAT4: + case LOCAL_GL_FLOAT_MAT2x3: + case LOCAL_GL_FLOAT_MAT2x4: + case LOCAL_GL_FLOAT_MAT3x2: + case LOCAL_GL_FLOAT_MAT3x4: + case LOCAL_GL_FLOAT_MAT4x2: + case LOCAL_GL_FLOAT_MAT4x3: { GLfloat buffer[16] = {0.0f}; gl->fGetUniformfv(prog, mLoc, buffer); @@ -275,6 +294,25 @@ WebGLUniformLocation::GetUniform(JSContext* js, WebGLContext* webgl) const return JS::ObjectOrNullValue(obj); } + case LOCAL_GL_UNSIGNED_INT: + case LOCAL_GL_UNSIGNED_INT_VEC2: + case LOCAL_GL_UNSIGNED_INT_VEC3: + case LOCAL_GL_UNSIGNED_INT_VEC4: + { + GLuint buffer[kMaxElemSize] = {0}; + gl->fGetUniformuiv(prog, mLoc, buffer); + + if (elemSize == 1) + return JS::DoubleValue(buffer[0]); // This is Double because only Int32 is special cased. + + JSObject* obj = dom::Uint32Array::Create(js, webgl, elemSize, buffer); + if (!obj) { + webgl->ErrorOutOfMemory("getUniform: out of memory"); + return JS::NullValue(); + } + return JS::ObjectOrNullValue(obj); + } + default: MOZ_CRASH("Invalid elemType."); } diff --git a/dom/filehandle/FileStreamWrappers.cpp b/dom/filehandle/FileStreamWrappers.cpp index 12e49a2c2083..a19d9a5502b3 100644 --- a/dom/filehandle/FileStreamWrappers.cpp +++ b/dom/filehandle/FileStreamWrappers.cpp @@ -17,6 +17,7 @@ #include "nsIRunnable.h" #include "nsISeekableStream.h" #include "nsThreadUtils.h" +#include "nsQueryObject.h" #ifdef DEBUG #include "nsXULAppAPI.h" diff --git a/dom/html/HTMLFieldSetElement.cpp b/dom/html/HTMLFieldSetElement.cpp index 647152c853ca..fe8e11944164 100644 --- a/dom/html/HTMLFieldSetElement.cpp +++ b/dom/html/HTMLFieldSetElement.cpp @@ -9,6 +9,7 @@ #include "mozilla/dom/HTMLFieldSetElement.h" #include "mozilla/dom/HTMLFieldSetElementBinding.h" #include "nsContentList.h" +#include "nsQueryObject.h" NS_IMPL_NS_NEW_HTML_ELEMENT(FieldSet) diff --git a/dom/html/HTMLFormElement.cpp b/dom/html/HTMLFormElement.cpp index b316f61ece69..915fe5ba3a68 100644 --- a/dom/html/HTMLFormElement.cpp +++ b/dom/html/HTMLFormElement.cpp @@ -30,6 +30,7 @@ #include "nsIMutableArray.h" #include "nsIFormAutofillContentService.h" #include "mozilla/BinarySearch.h" +#include "nsQueryObject.h" // form submission #include "mozilla/Telemetry.h" diff --git a/dom/html/HTMLLabelElement.cpp b/dom/html/HTMLLabelElement.cpp index 832e045f7bf9..72336780ef9a 100644 --- a/dom/html/HTMLLabelElement.cpp +++ b/dom/html/HTMLLabelElement.cpp @@ -12,6 +12,7 @@ #include "mozilla/dom/HTMLLabelElementBinding.h" #include "nsFocusManager.h" #include "nsIDOMMouseEvent.h" +#include "nsQueryObject.h" // construction, destruction diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp index 2af77eeb14d8..c756e58e3c29 100644 --- a/dom/html/HTMLMediaElement.cpp +++ b/dom/html/HTMLMediaElement.cpp @@ -38,6 +38,7 @@ #include "nsIThreadInternal.h" #include "nsContentUtils.h" #include "nsIRequest.h" +#include "nsQueryObject.h" #include "nsIScriptSecurityManager.h" #include "nsIXPConnect.h" diff --git a/dom/html/nsGenericHTMLElement.cpp b/dom/html/nsGenericHTMLElement.cpp index fe946abca5c2..640b69d0116e 100644 --- a/dom/html/nsGenericHTMLElement.cpp +++ b/dom/html/nsGenericHTMLElement.cpp @@ -17,6 +17,7 @@ #include "nsAttrValueInlines.h" #include "nsCOMPtr.h" #include "nsIAtom.h" +#include "nsQueryObject.h" #include "nsIContentInlines.h" #include "nsIContentViewer.h" #include "mozilla/css/StyleRule.h" diff --git a/dom/indexedDB/IDBDatabase.cpp b/dom/indexedDB/IDBDatabase.cpp index 249002702ca3..7f9b7494f12f 100644 --- a/dom/indexedDB/IDBDatabase.cpp +++ b/dom/indexedDB/IDBDatabase.cpp @@ -50,6 +50,7 @@ #include "nsThreadUtils.h" #include "ProfilerHelpers.h" #include "ReportInternalError.h" +#include "nsQueryObject.h" // Include this last to avoid path problems on Windows. #include "ActorsChild.h" diff --git a/dom/indexedDB/IDBObjectStore.cpp b/dom/indexedDB/IDBObjectStore.cpp index 9fd9347f0721..e9e7a0c63a09 100644 --- a/dom/indexedDB/IDBObjectStore.cpp +++ b/dom/indexedDB/IDBObjectStore.cpp @@ -41,6 +41,7 @@ #include "mozilla/ipc/BackgroundChild.h" #include "mozilla/ipc/PBackgroundSharedTypes.h" #include "nsCOMPtr.h" +#include "nsQueryObject.h" #include "ProfilerHelpers.h" #include "ReportInternalError.h" #include "WorkerPrivate.h" diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index 91340cd5483d..461a1de6a072 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -275,6 +275,9 @@ TabChildBase::HandlePossibleViewportChange(const ScreenIntSize& aOldScreenSize) Stringify(aOldScreenSize).c_str(), Stringify(mInnerSize).c_str()); nsCOMPtr document(GetDocument()); + if (!document) { + return false; + } nsViewportInfo viewportInfo = nsContentUtils::GetViewportInfo(document, mInnerSize); uint32_t presShellId = 0; @@ -2114,7 +2117,7 @@ bool TabChild::RecvHandleLongTap(const CSSPoint& aPoint, const Modifiers& aModifiers, const ScrollableLayerGuid& aGuid, const uint64_t& aInputBlockId) { if (mGlobal && mTabChildGlobal) { - mAPZEventState->ProcessLongTap(GetDOMWindowUtils(), aPoint, aModifiers, aGuid, + mAPZEventState->ProcessLongTap(GetPresShell(), aPoint, aModifiers, aGuid, aInputBlockId, GetPresShellResolution()); } return true; @@ -2165,7 +2168,7 @@ TabChild::RecvMouseEvent(const nsString& aType, const int32_t& aModifiers, const bool& aIgnoreRootScrollFrame) { - APZCCallbackHelper::DispatchMouseEvent(GetDOMWindowUtils(), aType, CSSPoint(aX, aY), + APZCCallbackHelper::DispatchMouseEvent(GetPresShell(), aType, CSSPoint(aX, aY), aButton, aClickCount, aModifiers, aIgnoreRootScrollFrame, nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN); return true; } @@ -2328,7 +2331,7 @@ TabChild::FireContextMenuEvent() MOZ_ASSERT(mTapHoldTimer && mActivePointerId >= 0); bool defaultPrevented = APZCCallbackHelper::DispatchMouseEvent( - GetDOMWindowUtils(), + GetPresShell(), NS_LITERAL_STRING("contextmenu"), mGestureDownPoint / CSSToLayoutDeviceScale(scale), 2 /* Right button */, @@ -2526,11 +2529,9 @@ TabChild::RecvKeyEvent(const nsString& aType, const int32_t& aModifiers, const bool& aPreventDefault) { - nsCOMPtr utils(GetDOMWindowUtils()); - NS_ENSURE_TRUE(utils, true); bool ignored = false; - utils->SendKeyEvent(aType, aKeyCode, aCharCode, - aModifiers, aPreventDefault, &ignored); + nsContentUtils::SendKeyEvent(mWidget, aType, aKeyCode, aCharCode, + aModifiers, aPreventDefault, &ignored); return true; } diff --git a/dom/media/DecoderTraits.cpp b/dom/media/DecoderTraits.cpp index 93c0b6caad93..a92209344c59 100644 --- a/dom/media/DecoderTraits.cpp +++ b/dom/media/DecoderTraits.cpp @@ -354,12 +354,16 @@ IsMP4SupportedType(const nsACString& aType, // For other normal MP4, it still uses current omx decoder. // Bug 1061034 is a follow-up bug to enable all MP4s with MOZ_FMP4 #ifdef MOZ_OMX_DECODER - return false; -#else + // Use MP4Decoder when blank-decoder is enabled so that we can run EME + // mochitests on B2G platforms. This will be removed once bug 1146729 is + // fixed when we don't need blank-decoder to play mp4 on B2G. + if (!Preferences::GetBool("media.fragmented-mp4.use-blank-decoder", false)) { + return false; + } +#endif bool haveAAC, haveMP3, haveH264; return Preferences::GetBool("media.fragmented-mp4.exposed", false) && MP4Decoder::CanHandleMediaType(aType, aCodecs, haveAAC, haveH264, haveMP3); -#endif } #endif diff --git a/dom/media/MediaDevices.cpp b/dom/media/MediaDevices.cpp index 18e57b5ec01a..2d2e01541f25 100644 --- a/dom/media/MediaDevices.cpp +++ b/dom/media/MediaDevices.cpp @@ -11,6 +11,7 @@ #include "nsIScriptGlobalObject.h" #include "nsIPermissionManager.h" #include "nsPIDOMWindow.h" +#include "nsQueryObject.h" namespace mozilla { namespace dom { diff --git a/dom/media/MediaPermissionGonk.cpp b/dom/media/MediaPermissionGonk.cpp index f7eff2a7f044..b93188f7e3bd 100644 --- a/dom/media/MediaPermissionGonk.cpp +++ b/dom/media/MediaPermissionGonk.cpp @@ -12,6 +12,7 @@ #include "nsIStringEnumerator.h" #include "nsISupportsArray.h" #include "nsJSUtils.h" +#include "nsQueryObject.h" #include "nsPIDOMWindow.h" #include "nsTArray.h" #include "GetUserMediaRequest.h" diff --git a/dom/media/fmp4/eme/EMEVideoDecoder.cpp b/dom/media/fmp4/eme/EMEVideoDecoder.cpp index 20aebcfcc925..0c2d56cd53e8 100644 --- a/dom/media/fmp4/eme/EMEVideoDecoder.cpp +++ b/dom/media/fmp4/eme/EMEVideoDecoder.cpp @@ -36,10 +36,10 @@ EMEVideoDecoder::GetNodeId() return mProxy->GetNodeId(); } -GMPUnique::Ptr +GMPUniquePtr EMEVideoDecoder::CreateFrame(MediaRawData* aSample) { - GMPUnique::Ptr frame = GMPVideoDecoder::CreateFrame(aSample); + GMPUniquePtr frame = GMPVideoDecoder::CreateFrame(aSample); if (frame && aSample->mCrypto.mValid) { static_cast(frame.get())->InitCrypto(aSample->mCrypto); } diff --git a/dom/media/fmp4/eme/EMEVideoDecoder.h b/dom/media/fmp4/eme/EMEVideoDecoder.h index 6f389da8ecdc..bf7247185d87 100644 --- a/dom/media/fmp4/eme/EMEVideoDecoder.h +++ b/dom/media/fmp4/eme/EMEVideoDecoder.h @@ -50,7 +50,7 @@ public: private: virtual void InitTags(nsTArray& aTags) override; virtual nsCString GetNodeId() override; - virtual GMPUnique::Ptr CreateFrame(MediaRawData* aSample) override; + virtual GMPUniquePtr CreateFrame(MediaRawData* aSample) override; nsRefPtr mProxy; }; diff --git a/dom/media/fmp4/gmp/GMPVideoDecoder.cpp b/dom/media/fmp4/gmp/GMPVideoDecoder.cpp index 5a74e5ddb08d..fb1fdb456c37 100644 --- a/dom/media/fmp4/gmp/GMPVideoDecoder.cpp +++ b/dom/media/fmp4/gmp/GMPVideoDecoder.cpp @@ -19,7 +19,7 @@ extern bool IsOnGMPThread(); void VideoCallbackAdapter::Decoded(GMPVideoi420Frame* aDecodedFrame) { - GMPUnique::Ptr decodedFrame(aDecodedFrame); + GMPUniquePtr decodedFrame(aDecodedFrame); MOZ_ASSERT(IsOnGMPThread()); @@ -115,7 +115,7 @@ GMPVideoDecoder::GetNodeId() return NS_LITERAL_CSTRING(""); } -GMPUnique::Ptr +GMPUniquePtr GMPVideoDecoder::CreateFrame(MediaRawData* aSample) { GMPVideoFrame* ftmp = nullptr; @@ -125,7 +125,7 @@ GMPVideoDecoder::CreateFrame(MediaRawData* aSample) return nullptr; } - GMPUnique::Ptr frame(static_cast(ftmp)); + GMPUniquePtr frame(static_cast(ftmp)); err = frame->CreateEmptyFrame(aSample->mSize); if (GMP_FAILED(err)) { mCallback->Error(); @@ -248,7 +248,7 @@ GMPVideoDecoder::Input(MediaRawData* aSample) mAdapter->SetLastStreamOffset(sample->mOffset); - GMPUnique::Ptr frame = CreateFrame(sample); + GMPUniquePtr frame = CreateFrame(sample); nsTArray info; // No codec specific per-frame info to pass. nsresult rv = mGMP->Decode(Move(frame), false, info, 0); if (NS_FAILED(rv)) { diff --git a/dom/media/fmp4/gmp/GMPVideoDecoder.h b/dom/media/fmp4/gmp/GMPVideoDecoder.h index f14cad5aaf15..946f0cbea685 100644 --- a/dom/media/fmp4/gmp/GMPVideoDecoder.h +++ b/dom/media/fmp4/gmp/GMPVideoDecoder.h @@ -93,7 +93,7 @@ public: protected: virtual void InitTags(nsTArray& aTags); virtual nsCString GetNodeId(); - virtual GMPUnique::Ptr CreateFrame(MediaRawData* aSample); + virtual GMPUniquePtr CreateFrame(MediaRawData* aSample); private: class GMPInitDoneRunnable : public nsRunnable diff --git a/dom/media/fmp4/wmf/WMFMediaDataDecoder.cpp b/dom/media/fmp4/wmf/WMFMediaDataDecoder.cpp index 835b0cfa2466..1396809d8eb3 100644 --- a/dom/media/fmp4/wmf/WMFMediaDataDecoder.cpp +++ b/dom/media/fmp4/wmf/WMFMediaDataDecoder.cpp @@ -27,13 +27,14 @@ WMFMediaDataDecoder::WMFMediaDataDecoder(MFTManager* aMFTManager, : mTaskQueue(aTaskQueue) , mCallback(aCallback) , mMFTManager(aMFTManager) + , mMonitor("WMFMediaDataDecoder") + , mIsDecodeTaskDispatched(false) + , mIsFlushing(false) { - MOZ_COUNT_CTOR(WMFMediaDataDecoder); } WMFMediaDataDecoder::~WMFMediaDataDecoder() { - MOZ_COUNT_DTOR(WMFMediaDataDecoder); } nsresult @@ -48,11 +49,13 @@ WMFMediaDataDecoder::Init() nsresult WMFMediaDataDecoder::Shutdown() { - DebugOnly rv = mTaskQueue->FlushAndDispatch( + mTaskQueue->Dispatch( NS_NewRunnableMethod(this, &WMFMediaDataDecoder::ProcessShutdown)); #ifdef DEBUG - if (NS_FAILED(rv)) { - NS_WARNING("WMFMediaDataDecoder::Shutdown() dispatch of task failed!"); + { + MonitorAutoLock mon(mMonitor); + // The MP4Reader should have flushed before calling Shutdown(). + MOZ_ASSERT(!mIsDecodeTaskDispatched); } #endif return NS_OK; @@ -61,36 +64,73 @@ WMFMediaDataDecoder::Shutdown() void WMFMediaDataDecoder::ProcessShutdown() { - mMFTManager->Shutdown(); - mMFTManager = nullptr; + if (mMFTManager) { + mMFTManager->Shutdown(); + mMFTManager = nullptr; + } mDecoder = nullptr; } +void +WMFMediaDataDecoder::EnsureDecodeTaskDispatched() +{ + mMonitor.AssertCurrentThreadOwns(); + if (!mIsDecodeTaskDispatched) { + mTaskQueue->Dispatch( + NS_NewRunnableMethod(this, + &WMFMediaDataDecoder::Decode)); + mIsDecodeTaskDispatched = true; + } +} + // Inserts data into the decoder's pipeline. nsresult WMFMediaDataDecoder::Input(MediaRawData* aSample) { - mTaskQueue->Dispatch( - NS_NewRunnableMethodWithArg>( - this, - &WMFMediaDataDecoder::ProcessDecode, - nsRefPtr(aSample))); + MonitorAutoLock mon(mMonitor); + mInput.push(aSample); + EnsureDecodeTaskDispatched(); return NS_OK; } void -WMFMediaDataDecoder::ProcessDecode(MediaRawData* aSample) +WMFMediaDataDecoder::Decode() { - HRESULT hr = mMFTManager->Input(aSample); - if (FAILED(hr)) { - NS_WARNING("MFTManager rejected sample"); - mCallback->Error(); - return; + while (true) { + nsRefPtr input; + { + MonitorAutoLock mon(mMonitor); + MOZ_ASSERT(mIsDecodeTaskDispatched); + if (mInput.empty()) { + if (mIsFlushing) { + if (mDecoder) { + mDecoder->Flush(); + } + mIsFlushing = false; + } + mIsDecodeTaskDispatched = false; + mon.NotifyAll(); + return; + } + input = mInput.front(); + mInput.pop(); + } + + HRESULT hr = mMFTManager->Input(input); + if (FAILED(hr)) { + NS_WARNING("MFTManager rejected sample"); + { + MonitorAutoLock mon(mMonitor); + PurgeInputQueue(); + } + mCallback->Error(); + return; + } + + mLastStreamOffset = input->mOffset; + + ProcessOutput(); } - - mLastStreamOffset = aSample->mOffset; - - ProcessOutput(); } void @@ -108,24 +148,33 @@ WMFMediaDataDecoder::ProcessOutput() } } else if (FAILED(hr)) { NS_WARNING("WMFMediaDataDecoder failed to output data"); + { + MonitorAutoLock mon(mMonitor); + PurgeInputQueue(); + } mCallback->Error(); } } +void +WMFMediaDataDecoder::PurgeInputQueue() +{ + mMonitor.AssertCurrentThreadOwns(); + while (!mInput.empty()) { + mInput.pop(); + } +} + nsresult WMFMediaDataDecoder::Flush() { - // Flush the input task queue. This cancels all pending Decode() calls. - // Note this blocks until the task queue finishes its current job, if - // it's executing at all. Note the MP4Reader ignores all output while - // flushing. - mTaskQueue->Flush(); - - // Order the MFT to flush; drop all internal data. - NS_ENSURE_TRUE(mDecoder, NS_ERROR_FAILURE); - HRESULT hr = mDecoder->Flush(); - NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE); - + MonitorAutoLock mon(mMonitor); + PurgeInputQueue(); + mIsFlushing = true; + EnsureDecodeTaskDispatched(); + while (mIsDecodeTaskDispatched || mIsFlushing) { + mon.Wait(); + } return NS_OK; } diff --git a/dom/media/fmp4/wmf/WMFMediaDataDecoder.h b/dom/media/fmp4/wmf/WMFMediaDataDecoder.h index 42c61738a22a..dbd6090ee8db 100644 --- a/dom/media/fmp4/wmf/WMFMediaDataDecoder.h +++ b/dom/media/fmp4/wmf/WMFMediaDataDecoder.h @@ -74,9 +74,9 @@ public: private: - // Called on the task queue. Inserts the sample into the decoder, and - // extracts output if available. - void ProcessDecode(MediaRawData* aSample); + void Decode(); + void EnsureDecodeTaskDispatched(); + void PurgeInputQueue(); // Called on the task queue. Extracts output if available, and delivers // it to the reader. Called after ProcessDecode() and ProcessDrain(). @@ -97,6 +97,11 @@ private: // The last offset into the media resource that was passed into Input(). // This is used to approximate the decoder's position in the media resource. int64_t mLastStreamOffset; + + Monitor mMonitor; + std::queue> mInput; + bool mIsDecodeTaskDispatched; + bool mIsFlushing; }; } // namespace mozilla diff --git a/dom/media/gmp/GMPChild.cpp b/dom/media/gmp/GMPChild.cpp index fbd1577d5f3a..9d9327451a52 100644 --- a/dom/media/gmp/GMPChild.cpp +++ b/dom/media/gmp/GMPChild.cpp @@ -310,6 +310,10 @@ GMPChild::PreLoadLibraries(const std::string& aPluginPath) { "d3d9.dll", // Create an `IDirect3D9` to get adapter information "dxva2.dll", // Get monitor information + "evr.dll", // MFGetStrideForBitmapInfoHeader + "mfh264dec.dll", // H.264 decoder (on Windows Vista) + "mfheaacdec.dll", // AAC decoder (on Windows Vista) + "mfplat.dll", // MFCreateSample, MFCreateAlignedMemoryBuffer, MFCreateMediaType "msauddecmft.dll", // AAC decoder (on Windows 8) "msmpeg2adec.dll", // AAC decoder (on Windows 7) "msmpeg2vdec.dll", // H.264 decoder diff --git a/dom/media/gmp/GMPUtils.h b/dom/media/gmp/GMPUtils.h index 52bdb27f9ffb..d62f0011b0a9 100644 --- a/dom/media/gmp/GMPUtils.h +++ b/dom/media/gmp/GMPUtils.h @@ -18,11 +18,8 @@ struct DestroyPolicy } }; -// Ideally, this would be a template alias, but GCC 4.6 doesn't support them. See bug 1124021. template -struct GMPUnique { - typedef mozilla::UniquePtr> Ptr; -}; +using GMPUniquePtr = mozilla::UniquePtr>; } // namespace mozilla diff --git a/dom/media/gmp/GMPVideoDecoderParent.cpp b/dom/media/gmp/GMPVideoDecoderParent.cpp index 422545bd8c06..138c72dea115 100644 --- a/dom/media/gmp/GMPVideoDecoderParent.cpp +++ b/dom/media/gmp/GMPVideoDecoderParent.cpp @@ -109,7 +109,7 @@ GMPVideoDecoderParent::InitDecode(const GMPVideoCodec& aCodecSettings, } nsresult -GMPVideoDecoderParent::Decode(GMPUnique::Ptr aInputFrame, +GMPVideoDecoderParent::Decode(GMPUniquePtr aInputFrame, bool aMissingFrames, const nsTArray& aCodecSpecificInfo, int64_t aRenderTimeMs) @@ -121,7 +121,7 @@ GMPVideoDecoderParent::Decode(GMPUnique::Ptr aInputFrame, MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread()); - GMPUnique::Ptr inputFrameImpl( + GMPUniquePtr inputFrameImpl( static_cast(aInputFrame.release())); // Very rough kill-switch if the plugin stops processing. If it's merely diff --git a/dom/media/gmp/GMPVideoDecoderParent.h b/dom/media/gmp/GMPVideoDecoderParent.h index a231cd01a5b3..ffa3a8832bb6 100644 --- a/dom/media/gmp/GMPVideoDecoderParent.h +++ b/dom/media/gmp/GMPVideoDecoderParent.h @@ -38,7 +38,7 @@ public: const nsTArray& aCodecSpecific, GMPVideoDecoderCallbackProxy* aCallback, int32_t aCoreCount) override; - virtual nsresult Decode(GMPUnique::Ptr aInputFrame, + virtual nsresult Decode(GMPUniquePtr aInputFrame, bool aMissingFrames, const nsTArray& aCodecSpecificInfo, int64_t aRenderTimeMs = -1) override; diff --git a/dom/media/gmp/GMPVideoDecoderProxy.h b/dom/media/gmp/GMPVideoDecoderProxy.h index f4d344ac8d8f..1a5c771c988d 100644 --- a/dom/media/gmp/GMPVideoDecoderProxy.h +++ b/dom/media/gmp/GMPVideoDecoderProxy.h @@ -38,7 +38,7 @@ public: const nsTArray& aCodecSpecific, GMPVideoDecoderCallbackProxy* aCallback, int32_t aCoreCount) = 0; - virtual nsresult Decode(mozilla::GMPUnique::Ptr aInputFrame, + virtual nsresult Decode(mozilla::GMPUniquePtr aInputFrame, bool aMissingFrames, const nsTArray& aCodecSpecificInfo, int64_t aRenderTimeMs = -1) = 0; diff --git a/dom/media/gmp/GMPVideoEncoderParent.cpp b/dom/media/gmp/GMPVideoEncoderParent.cpp index 322277817078..a5c0fa32e9bf 100644 --- a/dom/media/gmp/GMPVideoEncoderParent.cpp +++ b/dom/media/gmp/GMPVideoEncoderParent.cpp @@ -126,7 +126,7 @@ GMPVideoEncoderParent::InitEncode(const GMPVideoCodec& aCodecSettings, } GMPErr -GMPVideoEncoderParent::Encode(GMPUnique::Ptr aInputFrame, +GMPVideoEncoderParent::Encode(GMPUniquePtr aInputFrame, const nsTArray& aCodecSpecificInfo, const nsTArray& aFrameTypes) { @@ -137,7 +137,7 @@ GMPVideoEncoderParent::Encode(GMPUnique::Ptr aInputFrame, MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread()); - GMPUnique::Ptr inputFrameImpl( + GMPUniquePtr inputFrameImpl( static_cast(aInputFrame.release())); // Very rough kill-switch if the plugin stops processing. If it's merely diff --git a/dom/media/gmp/GMPVideoEncoderParent.h b/dom/media/gmp/GMPVideoEncoderParent.h index 0485cb43ad38..169adf981b64 100644 --- a/dom/media/gmp/GMPVideoEncoderParent.h +++ b/dom/media/gmp/GMPVideoEncoderParent.h @@ -39,7 +39,7 @@ public: GMPVideoEncoderCallbackProxy* aCallback, int32_t aNumberOfCores, uint32_t aMaxPayloadSize) override; - virtual GMPErr Encode(GMPUnique::Ptr aInputFrame, + virtual GMPErr Encode(GMPUniquePtr aInputFrame, const nsTArray& aCodecSpecificInfo, const nsTArray& aFrameTypes) override; virtual GMPErr SetChannelParameters(uint32_t aPacketLoss, uint32_t aRTT) override; diff --git a/dom/media/gmp/GMPVideoEncoderProxy.h b/dom/media/gmp/GMPVideoEncoderProxy.h index 3e76e5358fcf..b1141e684adb 100644 --- a/dom/media/gmp/GMPVideoEncoderProxy.h +++ b/dom/media/gmp/GMPVideoEncoderProxy.h @@ -40,7 +40,7 @@ public: GMPVideoEncoderCallbackProxy* aCallback, int32_t aNumberOfCores, uint32_t aMaxPayloadSize) = 0; - virtual GMPErr Encode(mozilla::GMPUnique::Ptr aInputFrame, + virtual GMPErr Encode(mozilla::GMPUniquePtr aInputFrame, const nsTArray& aCodecSpecificInfo, const nsTArray& aFrameTypes) = 0; virtual GMPErr SetChannelParameters(uint32_t aPacketLoss, uint32_t aRTT) = 0; diff --git a/dom/media/systemservices/MediaChild.cpp b/dom/media/systemservices/MediaChild.cpp index adca365fa38b..efffed30cc7c 100644 --- a/dom/media/systemservices/MediaChild.cpp +++ b/dom/media/systemservices/MediaChild.cpp @@ -11,6 +11,7 @@ #include "nsGlobalWindow.h" #include "mozilla/MediaManager.h" #include "prlog.h" +#include "nsQueryObject.h" #undef LOG #if defined(PR_LOGGING) diff --git a/dom/media/webspeech/recognition/SpeechRecognition.cpp b/dom/media/webspeech/recognition/SpeechRecognition.cpp index 90244d2409b4..bb0df662ebf7 100644 --- a/dom/media/webspeech/recognition/SpeechRecognition.cpp +++ b/dom/media/webspeech/recognition/SpeechRecognition.cpp @@ -21,6 +21,7 @@ #include "mozilla/dom/SpeechRecognitionEvent.h" #include "nsIObserverService.h" #include "nsServiceManagerUtils.h" +#include "nsQueryObject.h" #include diff --git a/dom/plugins/base/nsJSNPRuntime.cpp b/dom/plugins/base/nsJSNPRuntime.cpp index a0d66358eead..e796f24cce80 100644 --- a/dom/plugins/base/nsJSNPRuntime.cpp +++ b/dom/plugins/base/nsJSNPRuntime.cpp @@ -664,7 +664,7 @@ ReportExceptionIfPending(JSContext *cx) } nsJSObjWrapper::nsJSObjWrapper(NPP npp) - : mJSObj(nullptr), mNpp(npp) + : mJSObj(nullptr), mNpp(npp), mDestroyPending(false) { MOZ_COUNT_CTOR(nsJSObjWrapper); OnWrapperCreated(); diff --git a/dom/plugins/base/nsPluginHost.cpp b/dom/plugins/base/nsPluginHost.cpp index 02d2890d1561..dcf8c794ad41 100644 --- a/dom/plugins/base/nsPluginHost.cpp +++ b/dom/plugins/base/nsPluginHost.cpp @@ -72,6 +72,7 @@ #include "prprf.h" #include "nsThreadUtils.h" #include "nsIInputStreamTee.h" +#include "nsQueryObject.h" #include "nsDirectoryServiceDefs.h" #include "nsAppDirectoryServiceDefs.h" diff --git a/dom/svg/DOMSVGStringList.cpp b/dom/svg/DOMSVGStringList.cpp index 7961d9d4322b..2dcb1fef2622 100644 --- a/dom/svg/DOMSVGStringList.cpp +++ b/dom/svg/DOMSVGStringList.cpp @@ -10,6 +10,7 @@ #include "nsError.h" #include "nsCOMPtr.h" #include "nsSVGAttrTearoffTable.h" +#include "nsQueryObject.h" #include // See the architecture comment in this file's header. diff --git a/dom/svg/SVGMotionSMILType.cpp b/dom/svg/SVGMotionSMILType.cpp index a357f28ac738..6671a78194cd 100644 --- a/dom/svg/SVGMotionSMILType.cpp +++ b/dom/svg/SVGMotionSMILType.cpp @@ -36,7 +36,9 @@ struct TranslationParams { // Simple translation float mY; }; struct PathPointParams { // Point along a path - Path* mPath; // NOTE: Refcounted; need to AddRef/Release. + // Refcounted: need to AddRef/Release. This can't be an nsRefPtr because + // this struct is used inside a union so it can't have a default constructor. + Path* MOZ_OWNING_REF mPath; float mDistToPoint; // Distance from path start to the point on the path that // we're interested in. }; diff --git a/dom/svg/nsSVGElement.cpp b/dom/svg/nsSVGElement.cpp index 069e1ddbc4a0..4c8987a395b4 100644 --- a/dom/svg/nsSVGElement.cpp +++ b/dom/svg/nsSVGElement.cpp @@ -45,6 +45,7 @@ #include "SVGAnimatedPathSegList.h" #include "SVGContentUtils.h" #include "nsIFrame.h" +#include "nsQueryObject.h" #include #include "nsSMILMappedAttribute.h" #include "SVGMotionSMILAttr.h" diff --git a/dom/workers/ServiceWorkerEvents.cpp b/dom/workers/ServiceWorkerEvents.cpp index 914867004baa..26dee0e65535 100644 --- a/dom/workers/ServiceWorkerEvents.cpp +++ b/dom/workers/ServiceWorkerEvents.cpp @@ -16,6 +16,7 @@ #include "nsStreamUtils.h" #include "nsNetCID.h" #include "nsSerializationHelper.h" +#include "nsQueryObject.h" #include "mozilla/dom/FetchEventBinding.h" #include "mozilla/dom/PromiseNativeHandler.h" diff --git a/dom/workers/ServiceWorkerManager.cpp b/dom/workers/ServiceWorkerManager.cpp index f49ac66e9709..1ed198f3376b 100644 --- a/dom/workers/ServiceWorkerManager.cpp +++ b/dom/workers/ServiceWorkerManager.cpp @@ -40,6 +40,7 @@ #include "nsGlobalWindow.h" #include "nsNetUtil.h" #include "nsProxyRelease.h" +#include "nsQueryObject.h" #include "nsTArray.h" #include "RuntimeService.h" diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index 616ef8c76cdf..7a1d94b9d33c 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -81,6 +81,7 @@ #include "nsNetUtil.h" #include "nsPrintfCString.h" #include "nsProxyRelease.h" +#include "nsQueryObject.h" #include "nsSandboxFlags.h" #include "prthread.h" #include "xpcpublic.h" diff --git a/dom/xbl/nsXBLPrototypeHandler.cpp b/dom/xbl/nsXBLPrototypeHandler.cpp index 68e651c7dbbd..24f8f6526307 100644 --- a/dom/xbl/nsXBLPrototypeHandler.cpp +++ b/dom/xbl/nsXBLPrototypeHandler.cpp @@ -6,6 +6,7 @@ #include "mozilla/ArrayUtils.h" #include "nsCOMPtr.h" +#include "nsQueryObject.h" #include "nsXBLPrototypeHandler.h" #include "nsXBLPrototypeBinding.h" #include "nsContentUtils.h" @@ -23,6 +24,7 @@ #include "nsIDOMHTMLTextAreaElement.h" #include "nsIDOMHTMLInputElement.h" #include "nsFocusManager.h" +#include "nsIFormControl.h" #include "nsIDOMEventListener.h" #include "nsPIDOMWindow.h" #include "nsPIWindowRoot.h" @@ -475,34 +477,17 @@ nsXBLPrototypeHandler::DispatchXBLCommand(EventTarget* aTarget, nsIDOMEvent* aEv nsFocusManager::GetFocusedDescendant(windowToCheck, true, getter_AddRefs(focusedWindow)); } - bool isLink = false; - nsIContent *content = focusedContent; + // If the focus is in an editable region, don't scroll. + if (focusedContent->IsEditable()) { + return NS_OK; + } - // if the focused element is a link then we do want space to - // scroll down. The focused element may be an element in a link, - // we need to check the parent node too. Only do this check if an - // element is focused and has a parent. - if (focusedContent && focusedContent->GetParent()) { - while (content) { - if (content->IsHTMLElement(nsGkAtoms::a)) { - isLink = true; - break; - } - - if (content->HasAttr(kNameSpaceID_XLink, nsGkAtoms::type)) { - isLink = content->AttrValueIs(kNameSpaceID_XLink, nsGkAtoms::type, - nsGkAtoms::simple, eCaseMatters); - - if (isLink) { - break; - } - } - - content = content->GetParent(); - } - - if (!isLink) + // If the focus is in a form control, don't scroll. + for (nsIContent* c = focusedContent; c; c = c->GetParent()) { + nsCOMPtr formControl = do_QueryInterface(c); + if (formControl) { return NS_OK; + } } } diff --git a/dom/xul/XULDocument.cpp b/dom/xul/XULDocument.cpp index 05e95ae25e67..fef63a9be3c4 100644 --- a/dom/xul/XULDocument.cpp +++ b/dom/xul/XULDocument.cpp @@ -4434,13 +4434,11 @@ XULDocument::CachedChromeStreamListener::CachedChromeStreamListener(XULDocument* : mDocument(aDocument), mProtoLoaded(aProtoLoaded) { - NS_ADDREF(mDocument); } XULDocument::CachedChromeStreamListener::~CachedChromeStreamListener() { - NS_RELEASE(mDocument); } diff --git a/dom/xul/XULDocument.h b/dom/xul/XULDocument.h index ef7100259da3..640508e6f82b 100644 --- a/dom/xul/XULDocument.h +++ b/dom/xul/XULDocument.h @@ -684,8 +684,8 @@ protected: class CachedChromeStreamListener : public nsIStreamListener { protected: - XULDocument* mDocument; - bool mProtoLoaded; + nsRefPtr mDocument; + bool mProtoLoaded; virtual ~CachedChromeStreamListener(); diff --git a/dom/xul/nsXULElement.cpp b/dom/xul/nsXULElement.cpp index dee3cd51f8e9..861195a4663f 100644 --- a/dom/xul/nsXULElement.cpp +++ b/dom/xul/nsXULElement.cpp @@ -93,6 +93,7 @@ #include "nsAttrValueInlines.h" #include "mozilla/Attributes.h" #include "nsIController.h" +#include "nsQueryObject.h" #include // The XUL doc interface diff --git a/editor/libeditor/IMETextTxn.cpp b/editor/libeditor/IMETextTxn.cpp index 0ba3485c156e..1088df5e49e8 100644 --- a/editor/libeditor/IMETextTxn.cpp +++ b/editor/libeditor/IMETextTxn.cpp @@ -13,6 +13,7 @@ #include "nsError.h" // for NS_SUCCEEDED, NS_FAILED, etc #include "nsIPresShell.h" // nsISelectionController constants #include "nsRange.h" // local var +#include "nsQueryObject.h" // for do_QueryObject using namespace mozilla; using namespace mozilla::dom; diff --git a/editor/libeditor/InsertTextTxn.cpp b/editor/libeditor/InsertTextTxn.cpp index 17efc2959b5e..bd5343772e55 100644 --- a/editor/libeditor/InsertTextTxn.cpp +++ b/editor/libeditor/InsertTextTxn.cpp @@ -11,6 +11,7 @@ #include "nsDebug.h" // for NS_ASSERTION, etc #include "nsEditor.h" // mEditor #include "nsError.h" // for NS_OK, etc +#include "nsQueryObject.h" // for do_QueryObject using namespace mozilla; using namespace mozilla::dom; diff --git a/editor/libeditor/PlaceholderTxn.cpp b/editor/libeditor/PlaceholderTxn.cpp index b3ffb067afeb..f8ecbe200158 100644 --- a/editor/libeditor/PlaceholderTxn.cpp +++ b/editor/libeditor/PlaceholderTxn.cpp @@ -8,6 +8,7 @@ #include "IMETextTxn.h" #include "nsGkAtoms.h" #include "mozilla/dom/Selection.h" +#include "nsQueryObject.h" using namespace mozilla; using namespace mozilla::dom; diff --git a/editor/libeditor/nsEditorEventListener.cpp b/editor/libeditor/nsEditorEventListener.cpp index bc157d1ed9c4..5a23d234268f 100644 --- a/editor/libeditor/nsEditorEventListener.cpp +++ b/editor/libeditor/nsEditorEventListener.cpp @@ -53,6 +53,7 @@ #include "nsRange.h" #include "nsServiceManagerUtils.h" // for do_GetService #include "nsString.h" // for nsAutoString +#include "nsQueryObject.h" // for do_QueryObject #ifdef HANDLE_NATIVE_TEXT_DIRECTION_SWITCH #include "nsContentUtils.h" // for nsContentUtils, etc #include "nsIBidiKeyboard.h" // for nsIBidiKeyboard diff --git a/editor/libeditor/nsHTMLEditorEventListener.cpp b/editor/libeditor/nsHTMLEditorEventListener.cpp index 53477df64267..e0a0afec557d 100644 --- a/editor/libeditor/nsHTMLEditorEventListener.cpp +++ b/editor/libeditor/nsHTMLEditorEventListener.cpp @@ -24,6 +24,7 @@ #include "nsIHTMLObjectResizer.h" #include "nsISupportsImpl.h" #include "nsLiteralString.h" +#include "nsQueryObject.h" #include "nsRange.h" using namespace mozilla; diff --git a/editor/libeditor/tests/file_bug915962.html b/editor/libeditor/tests/file_bug915962.html new file mode 100644 index 000000000000..85c5139d3b50 --- /dev/null +++ b/editor/libeditor/tests/file_bug915962.html @@ -0,0 +1,13 @@ + + + + + + + + + +

+ + diff --git a/editor/libeditor/tests/mochitest.ini b/editor/libeditor/tests/mochitest.ini index e4472c1589f4..982cf608bf50 100644 --- a/editor/libeditor/tests/mochitest.ini +++ b/editor/libeditor/tests/mochitest.ini @@ -9,6 +9,7 @@ support-files = file_bug549262.html file_bug586662.html file_bug674770-1.html + file_bug915962.html file_select_all_without_body.html green.png spellcheck.js @@ -137,6 +138,8 @@ skip-if = toolkit == 'android' || e10s [test_bug832025.html] [test_bug857487.html] [test_bug858918.html] +[test_bug915962.html] +skip-if = toolkit == 'android' || e10s [test_bug966155.html] skip-if = os != "win" [test_bug966552.html] diff --git a/editor/libeditor/tests/test_bug915962.html b/editor/libeditor/tests/test_bug915962.html new file mode 100644 index 000000000000..af6f850b5c1a --- /dev/null +++ b/editor/libeditor/tests/test_bug915962.html @@ -0,0 +1,85 @@ + + + + + Test for Bug 915962 + + + + + +Mozilla Bug 915962 +

+
+
+
+
+
+ + diff --git a/gfx/gl/GLContext.cpp b/gfx/gl/GLContext.cpp index 3535cc8b47d0..61d0caf0f390 100644 --- a/gfx/gl/GLContext.cpp +++ b/gfx/gl/GLContext.cpp @@ -1222,6 +1222,7 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl) { (PRFuncPtr*) &mSymbols.fUniform3uiv, { "Uniform3uiv", "Uniform3uivEXT", nullptr } }, { (PRFuncPtr*) &mSymbols.fUniform4uiv, { "Uniform4uiv", "Uniform4uivEXT", nullptr } }, { (PRFuncPtr*) &mSymbols.fGetFragDataLocation, { "GetFragDataLocation", "GetFragDataLocationEXT", nullptr } }, + { (PRFuncPtr*) &mSymbols.fGetUniformuiv, { "GetUniformuiv", "GetUniformuivEXT", nullptr } }, END_SYMBOLS }; diff --git a/gfx/gl/GLContext.h b/gfx/gl/GLContext.h index 0e0ec350d298..4fbb585c9785 100644 --- a/gfx/gl/GLContext.h +++ b/gfx/gl/GLContext.h @@ -1421,6 +1421,13 @@ public: AFTER_GL_CALL; } + void fGetUniformuiv(GLuint program, GLint location, GLuint* params) { + BEFORE_GL_CALL; + ASSERT_SYMBOL_PRESENT(fGetUniformuiv); + mSymbols.fGetUniformuiv(program, location, params); + AFTER_GL_CALL; + } + GLint fGetUniformLocation (GLint programObj, const GLchar* name) { BEFORE_GL_CALL; GLint retval = mSymbols.fGetUniformLocation(programObj, name); diff --git a/gfx/gl/GLContextSymbols.h b/gfx/gl/GLContextSymbols.h index c5bda3d4ddaf..215e4e4c428d 100644 --- a/gfx/gl/GLContextSymbols.h +++ b/gfx/gl/GLContextSymbols.h @@ -165,6 +165,8 @@ struct GLContextSymbols PFNGLGETUNIFORMFVPROC fGetUniformfv; typedef void (GLAPIENTRY * PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint* params); PFNGLGETUNIFORMIVPROC fGetUniformiv; + typedef void (GLAPIENTRY * PFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint* params); + PFNGLGETUNIFORMUIVPROC fGetUniformuiv; typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMLOCATIONPROC) (GLint programObj, const GLchar* name); PFNGLGETUNIFORMLOCATIONPROC fGetUniformLocation; typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVPROC) (GLuint, GLenum, GLfloat*); @@ -657,19 +659,19 @@ struct GLContextSymbols GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); PFNGLCOPYTEXSUBIMAGE3DPROC fCopyTexSubImage3D; - typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE3D) (GLenum target, GLint level, GLenum internalformat, - GLsizei width, GLsizei height, GLsizei depth, - GLint border, GLsizei imageSize, const GLvoid* data); - PFNGLCOMPRESSEDTEXIMAGE3D fCompressedTexImage3D; - typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3D) (GLenum target, GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLsizei imageSize, const GLvoid* data); - PFNGLCOMPRESSEDTEXSUBIMAGE3D fCompressedTexSubImage3D; + typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLsizei depth, + GLint border, GLsizei imageSize, const GLvoid* data); + PFNGLCOMPRESSEDTEXIMAGE3DPROC fCompressedTexImage3D; + typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLsizei imageSize, const GLvoid* data); + PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC fCompressedTexSubImage3D; // get_string_indexed - typedef const GLubyte* (GLAPIENTRY * pfnGLGetStringiT)(GLenum name, GLuint index); - pfnGLGetStringiT fGetStringi; + typedef const GLubyte* (GLAPIENTRY * PFNGLGETSTRINGIPROC)(GLenum name, GLuint index); + PFNGLGETSTRINGIPROC fGetStringi; }; } diff --git a/gfx/layers/apz/util/APZCCallbackHelper.cpp b/gfx/layers/apz/util/APZCCallbackHelper.cpp index 355009fe9a82..382633b1bb72 100644 --- a/gfx/layers/apz/util/APZCCallbackHelper.cpp +++ b/gfx/layers/apz/util/APZCCallbackHelper.cpp @@ -433,7 +433,7 @@ APZCCallbackHelper::DispatchSynthesizedMouseEvent(uint32_t aMsg, } bool -APZCCallbackHelper::DispatchMouseEvent(const nsCOMPtr& aUtils, +APZCCallbackHelper::DispatchMouseEvent(const nsCOMPtr& aPresShell, const nsString& aType, const CSSPoint& aPoint, int32_t aButton, @@ -442,11 +442,12 @@ APZCCallbackHelper::DispatchMouseEvent(const nsCOMPtr& aUtils bool aIgnoreRootScrollFrame, unsigned short aInputSourceArg) { - NS_ENSURE_TRUE(aUtils, true); + NS_ENSURE_TRUE(aPresShell, true); bool defaultPrevented = false; - aUtils->SendMouseEvent(aType, aPoint.x, aPoint.y, aButton, aClickCount, aModifiers, - aIgnoreRootScrollFrame, 0, aInputSourceArg, false, 4, &defaultPrevented); + nsContentUtils::SendMouseEvent(aPresShell, aType, aPoint.x, aPoint.y, + aButton, aClickCount, aModifiers, aIgnoreRootScrollFrame, 0, + aInputSourceArg, false, &defaultPrevented, false); return defaultPrevented; } diff --git a/gfx/layers/apz/util/APZCCallbackHelper.h b/gfx/layers/apz/util/APZCCallbackHelper.h index c34816dfb528..396d28f3ee2d 100644 --- a/gfx/layers/apz/util/APZCCallbackHelper.h +++ b/gfx/layers/apz/util/APZCCallbackHelper.h @@ -122,7 +122,7 @@ public: /* Dispatch a mouse event with the given parameters. * Return whether or not any listeners have called preventDefault on the event. */ - static bool DispatchMouseEvent(const nsCOMPtr& aUtils, + static bool DispatchMouseEvent(const nsCOMPtr& aPresShell, const nsString& aType, const CSSPoint& aPoint, int32_t aButton, diff --git a/gfx/layers/apz/util/APZEventState.cpp b/gfx/layers/apz/util/APZEventState.cpp index 425a9f5d068c..15abaa62207b 100644 --- a/gfx/layers/apz/util/APZEventState.cpp +++ b/gfx/layers/apz/util/APZEventState.cpp @@ -190,7 +190,7 @@ APZEventState::ProcessSingleTap(const CSSPoint& aPoint, } void -APZEventState::ProcessLongTap(const nsCOMPtr& aUtils, +APZEventState::ProcessLongTap(const nsCOMPtr& aPresShell, const CSSPoint& aPoint, Modifiers aModifiers, const ScrollableLayerGuid& aGuid, @@ -211,7 +211,7 @@ APZEventState::ProcessLongTap(const nsCOMPtr& aUtils, // just converts them back to widget format, but that API has many callers, // including in JS code, so it's not trivial to change. bool eventHandled = - APZCCallbackHelper::DispatchMouseEvent(aUtils, NS_LITERAL_STRING("contextmenu"), + APZCCallbackHelper::DispatchMouseEvent(aPresShell, NS_LITERAL_STRING("contextmenu"), APZCCallbackHelper::ApplyCallbackTransform(aPoint, aGuid, aPresShellResolution), 2, 1, WidgetModifiersToDOMModifiers(aModifiers), true, nsIDOMMouseEvent::MOZ_SOURCE_TOUCH); diff --git a/gfx/layers/apz/util/APZEventState.h b/gfx/layers/apz/util/APZEventState.h index e94aa62e1139..b9c9a9a12e36 100644 --- a/gfx/layers/apz/util/APZEventState.h +++ b/gfx/layers/apz/util/APZEventState.h @@ -18,7 +18,7 @@ #include "nsRefPtr.h" template class nsCOMPtr; -class nsIDOMWindowUtils; +class nsIPresShell; class nsIWidget; namespace mozilla { @@ -53,7 +53,7 @@ public: Modifiers aModifiers, const ScrollableLayerGuid& aGuid, float aPresShellResolution); - void ProcessLongTap(const nsCOMPtr& aUtils, + void ProcessLongTap(const nsCOMPtr& aUtils, const CSSPoint& aPoint, Modifiers aModifiers, const ScrollableLayerGuid& aGuid, diff --git a/gfx/layers/apz/util/ChromeProcessController.cpp b/gfx/layers/apz/util/ChromeProcessController.cpp index 333c10ffe551..333b7e279537 100644 --- a/gfx/layers/apz/util/ChromeProcessController.cpp +++ b/gfx/layers/apz/util/ChromeProcessController.cpp @@ -179,7 +179,7 @@ ChromeProcessController::HandleLongTap(const mozilla::CSSPoint& aPoint, Modifier return; } - mAPZEventState->ProcessLongTap(GetDOMWindowUtils(), aPoint, aModifiers, aGuid, + mAPZEventState->ProcessLongTap(GetPresShell(), aPoint, aModifiers, aGuid, aInputBlockId, GetPresShellResolution()); } diff --git a/gfx/layers/basic/TextureClientX11.cpp b/gfx/layers/basic/TextureClientX11.cpp index 40c64c250c91..ef56ac0e5e50 100644 --- a/gfx/layers/basic/TextureClientX11.cpp +++ b/gfx/layers/basic/TextureClientX11.cpp @@ -112,7 +112,9 @@ TextureClientX11::AllocateForSurface(IntSize aSize, TextureAllocationFlags aText //MOZ_ASSERT(mFormat != gfx::FORMAT_YUV, "This TextureClient cannot use YCbCr data"); MOZ_ASSERT(aSize.width >= 0 && aSize.height >= 0); - if (aSize.width <= 0 || aSize.height <= 0) { + if (aSize.width <= 0 || aSize.height <= 0 || + aSize.width > XLIB_IMAGE_SIDE_SIZE_LIMIT || + aSize.height > XLIB_IMAGE_SIDE_SIZE_LIMIT) { gfxDebug() << "Asking for X11 surface of invalid size " << aSize.width << "x" << aSize.height; return false; } diff --git a/gfx/thebes/gfxAndroidPlatform.h b/gfx/thebes/gfxAndroidPlatform.h index fbca3745d623..edbf4a5d37f4 100644 --- a/gfx/thebes/gfxAndroidPlatform.h +++ b/gfx/thebes/gfxAndroidPlatform.h @@ -96,7 +96,7 @@ public: virtual bool IsInGonkEmulator() const { return mIsInGonkEmulator; } #endif - virtual bool SupportsApzTouchInput() override { + virtual bool SupportsApzTouchInput() const override { return true; } diff --git a/gfx/thebes/gfxPlatform.h b/gfx/thebes/gfxPlatform.h index 82315050cc11..d5efd2d36f13 100644 --- a/gfx/thebes/gfxPlatform.h +++ b/gfx/thebes/gfxPlatform.h @@ -622,10 +622,10 @@ public: /** * Used to test which input types are handled via APZ. */ - virtual bool SupportsApzWheelInput() { + virtual bool SupportsApzWheelInput() const { return false; } - virtual bool SupportsApzTouchInput() { + virtual bool SupportsApzTouchInput() const { return false; } diff --git a/gfx/thebes/gfxPlatformGtk.h b/gfx/thebes/gfxPlatformGtk.h index 9b0126ad651f..a132c8911e95 100644 --- a/gfx/thebes/gfxPlatformGtk.h +++ b/gfx/thebes/gfxPlatformGtk.h @@ -110,7 +110,7 @@ public: virtual int GetScreenDepth() const override; - bool SupportsApzWheelInput() override { + bool SupportsApzWheelInput() const override { return true; } diff --git a/gfx/thebes/gfxPlatformMac.h b/gfx/thebes/gfxPlatformMac.h index 943e6c4d5b1e..2335a54f35d0 100644 --- a/gfx/thebes/gfxPlatformMac.h +++ b/gfx/thebes/gfxPlatformMac.h @@ -68,6 +68,10 @@ public: return true; } + virtual bool SupportsApzWheelInput() const override { + return true; + } + bool UseAcceleratedCanvas(); virtual bool UseProgressivePaint() override; diff --git a/gfx/thebes/gfxUtils.cpp b/gfx/thebes/gfxUtils.cpp index 79413108e438..a38d8437490d 100644 --- a/gfx/thebes/gfxUtils.cpp +++ b/gfx/thebes/gfxUtils.cpp @@ -389,7 +389,7 @@ IsSafeImageTransformComponent(gfxFloat aValue) return aValue >= -32768 && aValue <= 32767; } -#ifndef MOZ_GFX_OPTIMIZE_MOBILE +#if !defined(MOZ_GFX_OPTIMIZE_MOBILE) && !defined(MOZ_WIDGET_COCOA) /** * This returns the fastest operator to use for solid surfaces which have no * alpha channel or their alpha channel is uniformly opaque. @@ -455,7 +455,7 @@ CreateSamplingRestrictedDrawable(gfxDrawable* aDrawable, nsRefPtr drawable = new gfxSurfaceDrawable(surface, size, gfxMatrix::Translation(-needed.TopLeft())); return drawable.forget(); } -#endif // !MOZ_GFX_OPTIMIZE_MOBILE +#endif // !MOZ_GFX_OPTIMIZE_MOBILE && !MOZ_WIDGET_COCOA // working around cairo/pixman bug (bug 364968) // Our device-space-to-image-space transform may not be acceptable to pixman. @@ -650,7 +650,7 @@ gfxUtils::DrawPixelSnapped(gfxContext* aContext, // On Mobile, we don't ever want to do this; it has the potential for // allocating very large temporary surfaces, especially since we'll // do full-page snapshots often (see bug 749426). -#ifndef MOZ_GFX_OPTIMIZE_MOBILE +#if !defined(MOZ_GFX_OPTIMIZE_MOBILE) && !defined(MOZ_WIDGET_COCOA) nsRefPtr restrictedDrawable = CreateSamplingRestrictedDrawable(aDrawable, aContext, aRegion, aFormat); diff --git a/gfx/thebes/gfxWindowsPlatform.cpp b/gfx/thebes/gfxWindowsPlatform.cpp index 6b8dde430ebd..7ff2dd198870 100644 --- a/gfx/thebes/gfxWindowsPlatform.cpp +++ b/gfx/thebes/gfxWindowsPlatform.cpp @@ -2277,7 +2277,7 @@ gfxWindowsPlatform::CreateHardwareVsyncSource() } bool -gfxWindowsPlatform::SupportsApzTouchInput() +gfxWindowsPlatform::SupportsApzTouchInput() const { int value = Preferences::GetInt("dom.w3c_touch_events.enabled", 0); return value == 1 || value == 2; diff --git a/gfx/thebes/gfxWindowsPlatform.h b/gfx/thebes/gfxWindowsPlatform.h index 9b5d549584f0..212e19598eef 100644 --- a/gfx/thebes/gfxWindowsPlatform.h +++ b/gfx/thebes/gfxWindowsPlatform.h @@ -257,10 +257,10 @@ public: bool IsWARP() { return mIsWARP; } - bool SupportsApzWheelInput() override { + bool SupportsApzWheelInput() const override { return true; } - bool SupportsApzTouchInput() override; + bool SupportsApzTouchInput() const override; virtual already_AddRefed CreateHardwareVsyncSource() override; static mozilla::Atomic sD3D11MemoryUsed; diff --git a/gfx/thebes/gfxXlibSurface.cpp b/gfx/thebes/gfxXlibSurface.cpp index b954e6a2f623..fae03f63798f 100644 --- a/gfx/thebes/gfxXlibSurface.cpp +++ b/gfx/thebes/gfxXlibSurface.cpp @@ -21,11 +21,6 @@ using namespace mozilla; -// Although the dimension parameters in the xCreatePixmapReq wire protocol are -// 16-bit unsigned integers, the server's CreatePixmap returns BadAlloc if -// either dimension cannot be represented by a 16-bit *signed* integer. -#define XLIB_IMAGE_SIDE_SIZE_LIMIT 0x7fff - gfxXlibSurface::gfxXlibSurface(Display *dpy, Drawable drawable, Visual *visual) : mPixmapTaken(false), mDisplay(dpy), mDrawable(drawable) #if defined(GL_PROVIDER_GLX) diff --git a/gfx/thebes/gfxXlibSurface.h b/gfx/thebes/gfxXlibSurface.h index 34b33abcba2c..1597f7034513 100644 --- a/gfx/thebes/gfxXlibSurface.h +++ b/gfx/thebes/gfxXlibSurface.h @@ -17,6 +17,12 @@ #include "nsSize.h" +// Although the dimension parameters in the xCreatePixmapReq wire protocol are +// 16-bit unsigned integers, the server's CreatePixmap returns BadAlloc if +// either dimension cannot be represented by a 16-bit *signed* integer. +#define XLIB_IMAGE_SIDE_SIZE_LIMIT 0x7fff + + class gfxXlibSurface final : public gfxASurface { public: // construct a wrapper around the specified drawable with dpy/visual. diff --git a/image/src/imgRequestProxy.cpp b/image/src/imgRequestProxy.cpp index bfa3be147fe5..cf46bade85ac 100644 --- a/image/src/imgRequestProxy.cpp +++ b/image/src/imgRequestProxy.cpp @@ -7,7 +7,7 @@ #include "ImageLogging.h" #include "imgRequestProxy.h" #include "imgIOnloadBlocker.h" - +#include "imgLoader.h" #include "Image.h" #include "ImageOps.h" #include "nsError.h" @@ -695,6 +695,11 @@ imgRequestProxy::PerformClone(imgINotificationObserver* aObserver, return rv; } + if (GetOwner() && GetOwner()->GetValidator()) { + clone->SetNotificationsDeferred(true); + GetOwner()->GetValidator()->AddProxy(clone); + } + // Assign to *aClone before calling Notify so that if the caller expects to // only be notified for requests it's already holding pointers to it won't be // surprised. diff --git a/js/src/asmjs/AsmJSValidate.cpp b/js/src/asmjs/AsmJSValidate.cpp index 12c4e316b6dd..e6935cee7c25 100644 --- a/js/src/asmjs/AsmJSValidate.cpp +++ b/js/src/asmjs/AsmJSValidate.cpp @@ -7399,8 +7399,8 @@ CheckHeapLengthCondition(ModuleCompiler& m, ParseNode* cond, PropertyName* newBu uint32_t minLengthExclusive; if (!IsLiteralInt(m, minLengthNode, &minLengthExclusive)) return m.fail(minLengthNode, "expecting integer literal"); - if (minLengthExclusive < 0xffffff) - return m.fail(minLengthNode, "literal must be >= 0xffffff"); + if (minLengthExclusive < 0xffffff || minLengthExclusive == UINT32_MAX) + return m.fail(minLengthNode, "literal must be >= 0xffffff and < 0xffffffff"); // Add one to convert from exclusive (the branch rejects if ==) to inclusive. *minLength = minLengthExclusive + 1; diff --git a/js/src/builtin/Array.js b/js/src/builtin/Array.js index b3f16d5ef389..94703d253161 100644 --- a/js/src/builtin/Array.js +++ b/js/src/builtin/Array.js @@ -53,7 +53,7 @@ function ArrayIndexOf(searchElement/*, fromIndex*/) { function ArrayStaticIndexOf(list, searchElement/*, fromIndex*/) { if (arguments.length < 1) - ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'Array.indexOf'); + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.indexOf'); var fromIndex = arguments.length > 2 ? arguments[2] : 0; return callFunction(ArrayIndexOf, list, searchElement, fromIndex); } @@ -101,7 +101,7 @@ function ArrayLastIndexOf(searchElement/*, fromIndex*/) { function ArrayStaticLastIndexOf(list, searchElement/*, fromIndex*/) { if (arguments.length < 1) - ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'Array.lastIndexOf'); + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.lastIndexOf'); var fromIndex; if (arguments.length > 2) { fromIndex = arguments[2]; @@ -147,9 +147,9 @@ function ArrayEvery(callbackfn/*, thisArg*/) { function ArrayStaticEvery(list, callbackfn/*, thisArg*/) { if (arguments.length < 2) - ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'Array.every'); + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.every'); if (!IsCallable(callbackfn)) - ThrowError(JSMSG_NOT_FUNCTION, DecompileArg(1, callbackfn)); + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, callbackfn)); var T = arguments.length > 2 ? arguments[2] : void 0; return callFunction(ArrayEvery, list, callbackfn, T); } @@ -164,9 +164,9 @@ function ArraySome(callbackfn/*, thisArg*/) { /* Step 4. */ if (arguments.length === 0) - ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'Array.prototype.some'); + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.prototype.some'); if (!IsCallable(callbackfn)) - ThrowError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); /* Step 5. */ var T = arguments.length > 1 ? arguments[1] : void 0; @@ -188,9 +188,9 @@ function ArraySome(callbackfn/*, thisArg*/) { function ArrayStaticSome(list, callbackfn/*, thisArg*/) { if (arguments.length < 2) - ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'Array.some'); + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.some'); if (!IsCallable(callbackfn)) - ThrowError(JSMSG_NOT_FUNCTION, DecompileArg(1, callbackfn)); + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, callbackfn)); var T = arguments.length > 2 ? arguments[2] : void 0; return callFunction(ArraySome, list, callbackfn, T); } @@ -205,9 +205,9 @@ function ArrayForEach(callbackfn/*, thisArg*/) { /* Step 4. */ if (arguments.length === 0) - ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'Array.prototype.forEach'); + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.prototype.forEach'); if (!IsCallable(callbackfn)) - ThrowError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); /* Step 5. */ var T = arguments.length > 1 ? arguments[1] : void 0; @@ -236,9 +236,9 @@ function ArrayMap(callbackfn/*, thisArg*/) { /* Step 4. */ if (arguments.length === 0) - ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'Array.prototype.map'); + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.prototype.map'); if (!IsCallable(callbackfn)) - ThrowError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); /* Step 5. */ var T = arguments.length > 1 ? arguments[1] : void 0; @@ -264,18 +264,18 @@ function ArrayMap(callbackfn/*, thisArg*/) { function ArrayStaticMap(list, callbackfn/*, thisArg*/) { if (arguments.length < 2) - ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'Array.map'); + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.map'); if (!IsCallable(callbackfn)) - ThrowError(JSMSG_NOT_FUNCTION, DecompileArg(1, callbackfn)); + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, callbackfn)); var T = arguments.length > 2 ? arguments[2] : void 0; return callFunction(ArrayMap, list, callbackfn, T); } function ArrayStaticForEach(list, callbackfn/*, thisArg*/) { if (arguments.length < 2) - ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'Array.forEach'); + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.forEach'); if (!IsCallable(callbackfn)) - ThrowError(JSMSG_NOT_FUNCTION, DecompileArg(1, callbackfn)); + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, callbackfn)); var T = arguments.length > 2 ? arguments[2] : void 0; callFunction(ArrayForEach, list, callbackfn, T); } @@ -290,9 +290,9 @@ function ArrayReduce(callbackfn/*, initialValue*/) { /* Step 4. */ if (arguments.length === 0) - ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'Array.prototype.reduce'); + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.prototype.reduce'); if (!IsCallable(callbackfn)) - ThrowError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); /* Step 6. */ var k = 0; @@ -304,7 +304,7 @@ function ArrayReduce(callbackfn/*, initialValue*/) { } else { /* Step 5. */ if (len === 0) - ThrowError(JSMSG_EMPTY_ARRAY_REDUCE); + ThrowTypeError(JSMSG_EMPTY_ARRAY_REDUCE); if (IsPackedArray(O)) { accumulator = O[k++]; } else { @@ -318,7 +318,7 @@ function ArrayReduce(callbackfn/*, initialValue*/) { } } if (!kPresent) - ThrowError(JSMSG_EMPTY_ARRAY_REDUCE); + ThrowTypeError(JSMSG_EMPTY_ARRAY_REDUCE); } } @@ -338,9 +338,9 @@ function ArrayReduce(callbackfn/*, initialValue*/) { function ArrayStaticReduce(list, callbackfn) { if (arguments.length < 2) - ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'Array.reduce'); + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.reduce'); if (!IsCallable(callbackfn)) - ThrowError(JSMSG_NOT_FUNCTION, DecompileArg(1, callbackfn)); + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, callbackfn)); if (arguments.length > 2) return callFunction(ArrayReduce, list, callbackfn, arguments[2]); else @@ -357,9 +357,9 @@ function ArrayReduceRight(callbackfn/*, initialValue*/) { /* Step 4. */ if (arguments.length === 0) - ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'Array.prototype.reduce'); + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.prototype.reduce'); if (!IsCallable(callbackfn)) - ThrowError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); /* Step 6. */ var k = len - 1; @@ -371,7 +371,7 @@ function ArrayReduceRight(callbackfn/*, initialValue*/) { } else { /* Step 5. */ if (len === 0) - ThrowError(JSMSG_EMPTY_ARRAY_REDUCE); + ThrowTypeError(JSMSG_EMPTY_ARRAY_REDUCE); if (IsPackedArray(O)) { accumulator = O[k--]; } else { @@ -385,7 +385,7 @@ function ArrayReduceRight(callbackfn/*, initialValue*/) { } } if (!kPresent) - ThrowError(JSMSG_EMPTY_ARRAY_REDUCE); + ThrowTypeError(JSMSG_EMPTY_ARRAY_REDUCE); } } @@ -405,9 +405,9 @@ function ArrayReduceRight(callbackfn/*, initialValue*/) { function ArrayStaticReduceRight(list, callbackfn) { if (arguments.length < 2) - ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'Array.reduceRight'); + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.reduceRight'); if (!IsCallable(callbackfn)) - ThrowError(JSMSG_NOT_FUNCTION, DecompileArg(1, callbackfn)); + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, callbackfn)); if (arguments.length > 2) return callFunction(ArrayReduceRight, list, callbackfn, arguments[2]); else @@ -424,9 +424,9 @@ function ArrayFind(predicate/*, thisArg*/) { /* Step 6. */ if (arguments.length === 0) - ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'Array.prototype.find'); + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.prototype.find'); if (!IsCallable(predicate)) - ThrowError(JSMSG_NOT_FUNCTION, DecompileArg(0, predicate)); + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, predicate)); /* Step 7. */ var T = arguments.length > 1 ? arguments[1] : undefined; @@ -460,9 +460,9 @@ function ArrayFindIndex(predicate/*, thisArg*/) { /* Step 6. */ if (arguments.length === 0) - ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'Array.prototype.find'); + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.prototype.find'); if (!IsCallable(predicate)) - ThrowError(JSMSG_NOT_FUNCTION, DecompileArg(0, predicate)); + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, predicate)); /* Step 7. */ var T = arguments.length > 1 ? arguments[1] : undefined; @@ -715,7 +715,7 @@ function ArrayFrom(items, mapfn=undefined, thisArg=undefined) { // Steps 2-3. var mapping = mapfn !== undefined; if (mapping && !IsCallable(mapfn)) - ThrowError(JSMSG_NOT_FUNCTION, DecompileArg(1, mapfn)); + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, mapfn)); var T = thisArg; // All elements defined by this algorithm have the same attrs: @@ -742,7 +742,7 @@ function ArrayFrom(items, mapfn=undefined, thisArg=undefined) { // Steps 6.g.i-iii. var next = iterator.next(); if (!IsObject(next)) - ThrowError(JSMSG_NEXT_RETURNED_PRIMITIVE); + ThrowTypeError(JSMSG_NEXT_RETURNED_PRIMITIVE); // Step 6.g.iv. if (next.done) { diff --git a/js/src/builtin/Error.js b/js/src/builtin/Error.js index a737857c1e00..8dacf8b8c154 100644 --- a/js/src/builtin/Error.js +++ b/js/src/builtin/Error.js @@ -8,7 +8,7 @@ function ErrorToString() /* Steps 1-2. */ var obj = this; if (!IsObject(obj)) - ThrowError(JSMSG_INCOMPATIBLE_PROTO, "Error", "toString", "value"); + ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "Error", "toString", "value"); /* Steps 3-5. */ var name = obj.name; diff --git a/js/src/builtin/Generator.js b/js/src/builtin/Generator.js index 0639455d53ec..b3758c609078 100644 --- a/js/src/builtin/Generator.js +++ b/js/src/builtin/Generator.js @@ -15,7 +15,7 @@ function StarGeneratorNext(val) { return { value: undefined, done: true }; if (GeneratorIsRunning(this)) - ThrowError(JSMSG_NESTING_GENERATOR); + ThrowTypeError(JSMSG_NESTING_GENERATOR); } try { @@ -36,7 +36,7 @@ function StarGeneratorThrow(val) { throw val; if (GeneratorIsRunning(this)) - ThrowError(JSMSG_NESTING_GENERATOR); + ThrowTypeError(JSMSG_NESTING_GENERATOR); } try { @@ -57,7 +57,7 @@ function StarGeneratorReturn(val) { return { value: val, done: true }; if (GeneratorIsRunning(this)) - ThrowError(JSMSG_NESTING_GENERATOR); + ThrowTypeError(JSMSG_NESTING_GENERATOR); } try { @@ -78,7 +78,7 @@ function LegacyGeneratorNext(val) { ThrowStopIteration(); if (GeneratorIsRunning(this)) - ThrowError(JSMSG_NESTING_GENERATOR); + ThrowTypeError(JSMSG_NESTING_GENERATOR); try { return resumeGenerator(this, val, 'next'); @@ -97,7 +97,7 @@ function LegacyGeneratorThrow(val) { throw val; if (GeneratorIsRunning(this)) - ThrowError(JSMSG_NESTING_GENERATOR); + ThrowTypeError(JSMSG_NESTING_GENERATOR); try { return resumeGenerator(this, val, 'throw'); @@ -115,7 +115,7 @@ function LegacyGeneratorCloseInternal() { assert(!LegacyGeneratorObjectIsClosed(this), "Already closed: " + ToString(this)); if (GeneratorIsRunning(this)) - ThrowError(JSMSG_NESTING_GENERATOR); + ThrowTypeError(JSMSG_NESTING_GENERATOR); resumeGenerator(this, undefined, 'close'); if (!LegacyGeneratorObjectIsClosed(this)) diff --git a/js/src/builtin/Intl.js b/js/src/builtin/Intl.js index 74513209ab43..06f8f97d3f62 100644 --- a/js/src/builtin/Intl.js +++ b/js/src/builtin/Intl.js @@ -843,7 +843,7 @@ function SupportedLocales(availableLocales, requestedLocales, options) { if (matcher !== undefined) { matcher = ToString(matcher); if (matcher !== "lookup" && matcher !== "best fit") - ThrowError(JSMSG_INVALID_LOCALE_MATCHER, matcher); + ThrowRangeError(JSMSG_INVALID_LOCALE_MATCHER, matcher); } } @@ -888,7 +888,7 @@ function GetOption(options, property, type, values, fallback) { // Step 2.d. if (values !== undefined && callFunction(std_Array_indexOf, values, value) === -1) - ThrowError(JSMSG_INVALID_OPTION_VALUE, property, value); + ThrowRangeError(JSMSG_INVALID_OPTION_VALUE, property, value); // Step 2.e. return value; @@ -917,7 +917,7 @@ function GetNumberOption(options, property, minimum, maximum, fallback) { if (value !== undefined) { value = ToNumber(value); if (Number_isNaN(value) || value < minimum || value > maximum) - ThrowError(JSMSG_INVALID_DIGITS_VALUE, value); + ThrowRangeError(JSMSG_INVALID_DIGITS_VALUE, value); return std_Math_floor(value); } @@ -1081,7 +1081,7 @@ function getIntlObjectInternals(obj, className, methodName) { assert(internals === undefined || isInitializedIntlObject(obj), "bad mapping in internalsMap"); if (internals === undefined || internals.type !== className) - ThrowError(JSMSG_INTL_OBJECT_NOT_INITED, className, methodName, className); + ThrowTypeError(JSMSG_INTL_OBJECT_NOT_INITED, className, methodName, className); return internals; } @@ -1255,7 +1255,7 @@ function InitializeCollator(collator, locales, options) { // Step 1. if (isInitializedIntlObject(collator)) - ThrowError(JSMSG_INTL_OBJECT_REINITED); + ThrowTypeError(JSMSG_INTL_OBJECT_REINITED); // Step 2. var internals = initializeIntlObject(collator); @@ -1597,7 +1597,7 @@ function InitializeNumberFormat(numberFormat, locales, options) { // Step 1. if (isInitializedIntlObject(numberFormat)) - ThrowError(JSMSG_INTL_OBJECT_REINITED); + ThrowTypeError(JSMSG_INTL_OBJECT_REINITED); // Step 2. var internals = initializeIntlObject(numberFormat); @@ -1666,11 +1666,11 @@ function InitializeNumberFormat(numberFormat, locales, options) { // Steps 17-20. var c = GetOption(options, "currency", "string", undefined, undefined); if (c !== undefined && !IsWellFormedCurrencyCode(c)) - ThrowError(JSMSG_INVALID_CURRENCY_CODE, c); + ThrowRangeError(JSMSG_INVALID_CURRENCY_CODE, c); var cDigits; if (s === "currency") { if (c === undefined) - ThrowError(JSMSG_UNDEFINED_CURRENCY); + ThrowTypeError(JSMSG_UNDEFINED_CURRENCY); // Steps 20.a-c. c = toASCIIUpperCase(c); @@ -2045,7 +2045,7 @@ function InitializeDateTimeFormat(dateTimeFormat, locales, options) { // Step 1. if (isInitializedIntlObject(dateTimeFormat)) - ThrowError(JSMSG_INTL_OBJECT_REINITED); + ThrowTypeError(JSMSG_INTL_OBJECT_REINITED); // Step 2. var internals = initializeIntlObject(dateTimeFormat); @@ -2101,7 +2101,7 @@ function InitializeDateTimeFormat(dateTimeFormat, locales, options) { if (tz !== undefined) { tz = toASCIIUpperCase(ToString(tz)); if (tz !== "UTC") - ThrowError(JSMSG_INVALID_TIME_ZONE, tz); + ThrowRangeError(JSMSG_INVALID_TIME_ZONE, tz); } lazyDateTimeFormatData.timeZone = tz; diff --git a/js/src/builtin/Map.js b/js/src/builtin/Map.js index 8c734277f726..fee4f8ba7efe 100644 --- a/js/src/builtin/Map.js +++ b/js/src/builtin/Map.js @@ -8,19 +8,19 @@ function MapForEach(callbackfn, thisArg = undefined) { /* Step 1-2. */ var M = this; if (!IsObject(M)) - ThrowError(JSMSG_INCOMPATIBLE_PROTO, "Map", "forEach", typeof M); + ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "Map", "forEach", typeof M); /* Step 3-4. */ try { callFunction(std_Map_has, M); } catch (e) { // has will throw on non-Map objects, throw our own error in that case. - ThrowError(JSMSG_INCOMPATIBLE_PROTO, "Map", "forEach", typeof M); + ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "Map", "forEach", typeof M); } /* Step 5. */ if (!IsCallable(callbackfn)) - ThrowError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); /* Step 6-8. */ var entries = callFunction(std_Map_iterator, M); diff --git a/js/src/builtin/Object.js b/js/src/builtin/Object.js index 9eeb525cda27..048513017faf 100644 --- a/js/src/builtin/Object.js +++ b/js/src/builtin/Object.js @@ -49,7 +49,7 @@ function ObjectDefineSetter(name, setter) { object = ToObject(this); if (!IsCallable(setter)) - ThrowError(JSMSG_BAD_GETTER_OR_SETTER, "setter"); + ThrowTypeError(JSMSG_BAD_GETTER_OR_SETTER, "setter"); var key = ToPropertyKey(name); @@ -71,7 +71,7 @@ function ObjectDefineGetter(name, getter) { object = ToObject(this); if (!IsCallable(getter)) - ThrowError(JSMSG_BAD_GETTER_OR_SETTER, "getter"); + ThrowTypeError(JSMSG_BAD_GETTER_OR_SETTER, "getter"); var key = ToPropertyKey(name); diff --git a/js/src/builtin/RegExp.js b/js/src/builtin/RegExp.js index 25732fece0ba..13cc5ba894d8 100644 --- a/js/src/builtin/RegExp.js +++ b/js/src/builtin/RegExp.js @@ -7,7 +7,7 @@ function RegExpFlagsGetter() { // Steps 1-2. var R = this; if (!IsObject(R)) - ThrowError(JSMSG_NOT_NONNULL_OBJECT, R === null ? "null" : typeof R); + ThrowTypeError(JSMSG_NOT_NONNULL_OBJECT, R === null ? "null" : typeof R); // Step 3. var result = ""; @@ -43,7 +43,7 @@ function RegExpToString() // Steps 1-2. var R = this; if (!IsObject(R)) - ThrowError(JSMSG_NOT_NONNULL_OBJECT, R === null ? "null" : typeof R); + ThrowTypeError(JSMSG_NOT_NONNULL_OBJECT, R === null ? "null" : typeof R); // Steps 3-4. var pattern = R.source; diff --git a/js/src/builtin/Set.js b/js/src/builtin/Set.js index 5373f1227b50..561b70f9f90b 100644 --- a/js/src/builtin/Set.js +++ b/js/src/builtin/Set.js @@ -8,19 +8,19 @@ function SetForEach(callbackfn, thisArg = undefined) { /* Step 1-2. */ var S = this; if (!IsObject(S)) - ThrowError(JSMSG_INCOMPATIBLE_PROTO, "Set", "forEach", typeof S); + ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "Set", "forEach", typeof S); /* Step 3-4. */ try { callFunction(std_Set_has, S); } catch (e) { // has will throw on non-Set objects, throw our own error in that case. - ThrowError(JSMSG_INCOMPATIBLE_PROTO, "Set", "forEach", typeof S); + ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "Set", "forEach", typeof S); } /* Step 5-6. */ if (!IsCallable(callbackfn)) - ThrowError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); /* Step 7-8. */ var values = callFunction(std_Set_iterator, S); diff --git a/js/src/builtin/String.js b/js/src/builtin/String.js index 10e8a5b46339..9f3dc1a4602e 100644 --- a/js/src/builtin/String.js +++ b/js/src/builtin/String.js @@ -44,7 +44,7 @@ function String_substring(start, end) { function String_static_substring(string, start, end) { if (arguments.length < 1) - ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'String.substring'); + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.substring'); return callFunction(String_substring, string, start, end); } @@ -83,7 +83,7 @@ function String_substr(start, length) { function String_static_substr(string, start, length) { if (arguments.length < 1) - ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'String.substr'); + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.substr'); return callFunction(String_substr, string, start, length); } @@ -120,7 +120,7 @@ function String_slice(start, end) { function String_static_slice(string, start, end) { if (arguments.length < 1) - ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'String.slice'); + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.slice'); return callFunction(String_slice, string, start, end); } @@ -167,10 +167,10 @@ function String_repeat(count) { // Steps 6-7. if (n < 0) - ThrowError(JSMSG_NEGATIVE_REPETITION_COUNT); // a RangeError + ThrowRangeError(JSMSG_NEGATIVE_REPETITION_COUNT); if (!(n * S.length < (1 << 28))) - ThrowError(JSMSG_RESULTING_STRING_TOO_LARGE); // a RangeError + ThrowRangeError(JSMSG_RESULTING_STRING_TOO_LARGE); // Communicate |n|'s possible range to the compiler. n = n & ((1 << 28) - 1); @@ -290,11 +290,11 @@ function String_static_fromCodePoint(codePoints) { // Step 5d. if (nextCP !== ToInteger(nextCP) || Number_isNaN(nextCP)) - ThrowError(JSMSG_NOT_A_CODEPOINT, ToString(nextCP)); + ThrowRangeError(JSMSG_NOT_A_CODEPOINT, ToString(nextCP)); // Step 5e. if (nextCP < 0 || nextCP > 0x10FFFF) - ThrowError(JSMSG_NOT_A_CODEPOINT, ToString(nextCP)); + ThrowRangeError(JSMSG_NOT_A_CODEPOINT, ToString(nextCP)); // Step 5f. // Inlined UTF-16 Encoding @@ -373,7 +373,7 @@ function String_static_raw(callSite, ...substitutions) { */ function String_static_localeCompare(str1, str2) { if (arguments.length < 1) - ThrowError(JSMSG_MISSING_FUN_ARG, 0, "String.localeCompare"); + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "String.localeCompare"); var locales = arguments.length > 2 ? arguments[2] : undefined; var options = arguments.length > 3 ? arguments[3] : undefined; return callFunction(String_localeCompare, str1, str2, locales, options); diff --git a/js/src/builtin/TypedArray.js b/js/src/builtin/TypedArray.js index fcf14d5e0d02..4c46b93e7cf1 100644 --- a/js/src/builtin/TypedArray.js +++ b/js/src/builtin/TypedArray.js @@ -249,9 +249,9 @@ function TypedArrayFind(predicate, thisArg = undefined) { // Step 6. if (arguments.length === 0) - ThrowError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.find"); + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.find"); if (!IsCallable(predicate)) - ThrowError(JSMSG_NOT_FUNCTION, DecompileArg(0, predicate)); + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, predicate)); // Step 7. var T = thisArg; @@ -286,9 +286,9 @@ function TypedArrayFindIndex(predicate, thisArg = undefined) { // Step 6. if (arguments.length === 0) - ThrowError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.findIndex"); + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.findIndex"); if (!IsCallable(predicate)) - ThrowError(JSMSG_NOT_FUNCTION, DecompileArg(0, predicate)); + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, predicate)); // Step 7. var T = thisArg; @@ -321,9 +321,9 @@ function TypedArrayForEach(callbackfn, thisArg = undefined) { // Step 5. if (arguments.length === 0) - ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'TypedArray.prototype.forEach'); + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'TypedArray.prototype.forEach'); if (!IsCallable(callbackfn)) - ThrowError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); // Step 6. var T = thisArg; @@ -505,9 +505,9 @@ function TypedArrayMap(callbackfn, thisArg = undefined) { // Step 5. if (arguments.length === 0) - ThrowError(JSMSG_MISSING_FUN_ARG, 0, '%TypedArray%.prototype.map'); + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, '%TypedArray%.prototype.map'); if (!IsCallable(callbackfn)) - ThrowError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); // Step 6. var T = thisArg; @@ -547,13 +547,13 @@ function TypedArrayReduce(callbackfn/*, initialValue*/) { // Step 6. if (arguments.length === 0) - ThrowError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.reduce"); + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.reduce"); if (!IsCallable(callbackfn)) - ThrowError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); // Step 7. if (len === 0 && arguments.length === 1) - ThrowError(JSMSG_EMPTY_ARRAY_REDUCE); + ThrowTypeError(JSMSG_EMPTY_ARRAY_REDUCE); // Step 8. var k = 0; @@ -586,13 +586,13 @@ function TypedArrayReduceRight(callbackfn/*, initialValue*/) { // Step 6. if (arguments.length === 0) - ThrowError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.reduceRight"); + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.reduceRight"); if (!IsCallable(callbackfn)) - ThrowError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); // Step 7. if (len === 0 && arguments.length === 1) - ThrowError(JSMSG_EMPTY_ARRAY_REDUCE); + ThrowTypeError(JSMSG_EMPTY_ARRAY_REDUCE); // Step 8. var k = len - 1; @@ -724,9 +724,9 @@ function TypedArraySome(callbackfn, thisArg = undefined) { // Step 6. if (arguments.length === 0) - ThrowError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.some"); + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.some"); if (!IsCallable(callbackfn)) - ThrowError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); // Step 7. var T = thisArg; @@ -868,14 +868,14 @@ function TypedArrayStaticFrom(source, mapfn = undefined, thisArg = undefined) { // Step 2. if (!IsConstructor(C)) - ThrowError(JSMSG_NOT_CONSTRUCTOR, DecompileArg(1, C)); + ThrowTypeError(JSMSG_NOT_CONSTRUCTOR, DecompileArg(1, C)); // Step 3. var f = mapfn; // Step 4. if (f !== undefined && !IsCallable(f)) - ThrowError(JSMSG_NOT_FUNCTION, DecompileArg(1, f)); + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, f)); // Steps 5-6. return TypedArrayFrom(C, undefined, source, f, thisArg); @@ -922,7 +922,7 @@ function TypedArrayFrom(constructor, target, items, mapfn, thisArg) { // Steps 10.e.i-ii. var next = iterator.next(); if (!IsObject(next)) - ThrowError(JSMSG_NEXT_RETURNED_PRIMITIVE); + ThrowTypeError(JSMSG_NEXT_RETURNED_PRIMITIVE); // Steps 10.e.iii-vi. if (next.done) @@ -1001,7 +1001,7 @@ function TypedArrayStaticOf(/*...items*/) { // Steps 4-5. if (!IsConstructor(C)) - ThrowError(JSMSG_NOT_CONSTRUCTOR, typeof C); + ThrowTypeError(JSMSG_NOT_CONSTRUCTOR, typeof C); var newObj = new C(len); diff --git a/js/src/builtin/TypedObject.js b/js/src/builtin/TypedObject.js index 06240fc63509..59145e151135 100644 --- a/js/src/builtin/TypedObject.js +++ b/js/src/builtin/TypedObject.js @@ -49,7 +49,7 @@ function TypedObjectGet(descr, typedObj, offset) { "get() called with bad type descr"); if (!TypedObjectIsAttached(typedObj)) - ThrowError(JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED); + ThrowTypeError(JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED); switch (DESCR_KIND(descr)) { case JS_TYPEREPR_SCALAR_KIND: @@ -179,7 +179,7 @@ function TypedObjectGetSimd(descr, typedObj, offset) { // and works for any type. function TypedObjectSet(descr, typedObj, offset, name, fromValue) { if (!TypedObjectIsAttached(typedObj)) - ThrowError(JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED); + ThrowTypeError(JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED); switch (DESCR_KIND(descr)) { case JS_TYPEREPR_SCALAR_KIND: @@ -218,9 +218,9 @@ function TypedObjectSet(descr, typedObj, offset, name, fromValue) { return; } - ThrowError(JSMSG_CANT_CONVERT_TO, - typeof(fromValue), - DESCR_STRING_REPR(descr)); + ThrowTypeError(JSMSG_CANT_CONVERT_TO, + typeof(fromValue), + DESCR_STRING_REPR(descr)); } function TypedObjectSetArray(descr, length, typedObj, offset, fromValue) { @@ -310,14 +310,14 @@ function TypedObjectSetReference(descr, typedObj, offset, name, fromValue) { // Sets `fromValue` to `this` assuming that `this` is a scalar type. function TypedObjectSetSimd(descr, typedObj, offset, fromValue) { if (!IsObject(fromValue) || !ObjectIsTypedObject(fromValue)) - ThrowError(JSMSG_CANT_CONVERT_TO, - typeof(fromValue), - DESCR_STRING_REPR(descr)); + ThrowTypeError(JSMSG_CANT_CONVERT_TO, + typeof(fromValue), + DESCR_STRING_REPR(descr)); if (!DescrsEquiv(descr, TypedObjectTypeDescr(fromValue))) - ThrowError(JSMSG_CANT_CONVERT_TO, - typeof(fromValue), - DESCR_STRING_REPR(descr)); + ThrowTypeError(JSMSG_CANT_CONVERT_TO, + typeof(fromValue), + DESCR_STRING_REPR(descr)); var type = DESCR_TYPE(descr); switch (type) { @@ -360,7 +360,7 @@ function ConvertAndCopyTo(destDescr, "ConvertAndCopyTo: not type typedObj"); if (!TypedObjectIsAttached(destTypedObj)) - ThrowError(JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED); + ThrowTypeError(JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED); TypedObjectSet(destDescr, destTypedObj, destOffset, fieldName, fromValue); } @@ -375,7 +375,7 @@ function Reify(sourceDescr, "Reify: not type typedObj"); if (!TypedObjectIsAttached(sourceTypedObj)) - ThrowError(JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED); + ThrowTypeError(JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED); return TypedObjectGet(sourceDescr, sourceTypedObj, sourceOffset); } @@ -383,9 +383,9 @@ function Reify(sourceDescr, // Warning: user exposed! function TypeDescrEquivalent(otherDescr) { if (!IsObject(this) || !ObjectIsTypeDescr(this)) - ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); if (!IsObject(otherDescr) || !ObjectIsTypeDescr(otherDescr)) - ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); return DescrsEquiv(this, otherDescr); } @@ -411,10 +411,10 @@ function TypeDescrEquivalent(otherDescr) { // Warning: user exposed! function TypedObjectArrayRedimension(newArrayType) { if (!IsObject(this) || !ObjectIsTypedObject(this)) - ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); if (!IsObject(newArrayType) || !ObjectIsTypeDescr(newArrayType)) - ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); // Peel away the outermost array layers from the type of `this` to find // the core element type. In the process, count the number of elements. @@ -423,7 +423,7 @@ function TypedObjectArrayRedimension(newArrayType) { var oldElementCount = 1; if (DESCR_KIND(oldArrayType) != JS_TYPEREPR_ARRAY_KIND) - ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); while (DESCR_KIND(oldElementType) === JS_TYPEREPR_ARRAY_KIND) { oldElementCount *= oldElementType.length; @@ -441,12 +441,12 @@ function TypedObjectArrayRedimension(newArrayType) { // Check that the total number of elements does not change. if (oldElementCount !== newElementCount) { - ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); } // Check that the element types are equivalent. if (!DescrsEquiv(oldElementType, newElementType)) { - ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); } // Together, this should imply that the sizes are unchanged. @@ -489,12 +489,12 @@ function SimdTypeToLength(type) { function SimdToSource() { if (!IsObject(this) || !ObjectIsTypedObject(this)) - ThrowError(JSMSG_INCOMPATIBLE_PROTO, "SIMD", "toSource", typeof this); + ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "SIMD", "toSource", typeof this); var descr = TypedObjectTypeDescr(this); if (DESCR_KIND(descr) != JS_TYPEREPR_SIMD_KIND) - ThrowError(JSMSG_INCOMPATIBLE_PROTO, "SIMD", "toSource", typeof this); + ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "SIMD", "toSource", typeof this); var type = DESCR_TYPE(descr); var protoString = SimdProtoString(type); @@ -526,7 +526,7 @@ function DescrsEquiv(descr1, descr2) { // Warning: user exposed! function DescrToSource() { if (!IsObject(this) || !ObjectIsTypeDescr(this)) - ThrowError(JSMSG_INCOMPATIBLE_PROTO, "Type", "toSource", "value"); + ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "Type", "toSource", "value"); return DESCR_STRING_REPR(this); } @@ -534,12 +534,12 @@ function DescrToSource() { // Warning: user exposed! function ArrayShorthand(...dims) { if (!IsObject(this) || !ObjectIsTypeDescr(this)) - ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); var T = GetTypedObjectModule(); if (dims.length == 0) - ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); var accum = this; for (var i = dims.length - 1; i >= 0; i--) @@ -560,7 +560,7 @@ function StorageOfTypedObject(obj) { if (ObjectIsTransparentTypedObject(obj)) { if (!TypedObjectIsAttached(obj)) - ThrowError(JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED); + ThrowTypeError(JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED); var descr = TypedObjectTypeDescr(obj); var byteLength = DESCR_SIZE(descr); @@ -571,7 +571,7 @@ function StorageOfTypedObject(obj) { } } - ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); } // This is the `objectType()` function defined in the spec. @@ -607,7 +607,7 @@ function TypedObjectArrayTypeBuild(a,b,c) { // Arguments : [depth], func if (!IsObject(this) || !ObjectIsTypeDescr(this)) - ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); var kind = DESCR_KIND(this); switch (kind) { case JS_TYPEREPR_ARRAY_KIND: @@ -616,11 +616,11 @@ function TypedObjectArrayTypeBuild(a,b,c) { else if (typeof a === "number" && typeof b === "function") return BuildTypedSeqImpl(this, this.length, a, b); else if (typeof a === "number") - ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); else - ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); default: - ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); } } @@ -629,7 +629,7 @@ function TypedObjectArrayTypeFrom(a, b, c) { // Arguments: arrayLike, [depth], func if (!IsObject(this) || !ObjectIsTypeDescr(this)) - ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); var untypedInput = !IsObject(a) || !ObjectIsTypedObject(a); @@ -645,7 +645,7 @@ function TypedObjectArrayTypeFrom(a, b, c) { else if (IsCallable(b)) return MapUntypedSeqImpl(a, this, b); else - ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); } else { var explicitDepth = (typeof b === "number"); if (explicitDepth && IsCallable(c)) @@ -653,39 +653,39 @@ function TypedObjectArrayTypeFrom(a, b, c) { else if (IsCallable(b)) return MapTypedSeqImpl(a, 1, this, b); else if (explicitDepth) - ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); else - ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); } } // Warning: user exposed! function TypedObjectArrayMap(a, b) { if (!IsObject(this) || !ObjectIsTypedObject(this)) - ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); var thisType = TypedObjectTypeDescr(this); if (!TypeDescrIsArrayType(thisType)) - ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); // Arguments: [depth], func if (typeof a === "number" && typeof b === "function") return MapTypedSeqImpl(this, a, thisType, b); else if (typeof a === "function") return MapTypedSeqImpl(this, 1, thisType, a); - ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); } // Warning: user exposed! function TypedObjectArrayReduce(a, b) { // Arguments: func, [initial] if (!IsObject(this) || !ObjectIsTypedObject(this)) - ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); var thisType = TypedObjectTypeDescr(this); if (!TypeDescrIsArrayType(thisType)) - ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); if (a !== undefined && typeof a !== "function") - ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); var outputType = thisType.elementType; return ReduceTypedSeqImpl(this, outputType, a, b); @@ -695,13 +695,13 @@ function TypedObjectArrayReduce(a, b) { function TypedObjectArrayFilter(func) { // Arguments: predicate if (!IsObject(this) || !ObjectIsTypedObject(this)) - ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); var thisType = TypedObjectTypeDescr(this); if (!TypeDescrIsArrayType(thisType)) - ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); if (typeof func !== "function") - ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); return FilterTypedSeqImpl(this, func); } @@ -725,9 +725,10 @@ function GET_BIT(data, index) { function BuildTypedSeqImpl(arrayType, len, depth, func) { assert(IsObject(arrayType) && ObjectIsTypeDescr(arrayType), "Build called on non-type-object"); - if (depth <= 0 || TO_INT32(depth) !== depth) + if (depth <= 0 || TO_INT32(depth) !== depth) { // RangeError("bad depth") - ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); + } // For example, if we have as input // ArrayType(ArrayType(T, 4), 5) @@ -787,7 +788,7 @@ function ComputeIterationSpace(arrayType, depth, len) { grainType = grainType.elementType; } else { // RangeError("Depth "+depth+" too high"); - ThrowError(JSMSG_TYPEDOBJECT_ARRAYTYPE_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); } } return { iterationSpace: iterationSpace, @@ -829,7 +830,7 @@ function MapUntypedSeqImpl(inArray, outputType, maybeFunc) { assert(TypeDescrIsArrayType(outputType), "Map/From called on non array-type outputType"); if (!IsCallable(maybeFunc)) - ThrowError(JSMSG_NOT_FUNCTION, DecompileArg(0, maybeFunc)); + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, maybeFunc)); var func = maybeFunc; // Skip check for compatible iteration spaces; any normal JS array @@ -880,20 +881,20 @@ function MapTypedSeqImpl(inArray, depth, outputType, func) { assert(TypeDescrIsArrayType(outputType), "Map/From called on non array-type outputType"); if (depth <= 0 || TO_INT32(depth) !== depth) - ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); // Compute iteration space for input and output and check for compatibility. var inputType = TypeOfTypedObject(inArray); var {iterationSpace:inIterationSpace, grainType:inGrainType} = ComputeIterationSpace(inputType, depth, inArray.length); if (!IsObject(inGrainType) || !ObjectIsTypeDescr(inGrainType)) - ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); var {iterationSpace, grainType:outGrainType, totalLength} = ComputeIterationSpace(outputType, depth, outputType.length); for (var i = 0; i < depth; i++) if (inIterationSpace[i] !== iterationSpace[i]) // TypeError("Incompatible iteration space in input and output type"); - ThrowError(JSMSG_TYPEDOBJECT_ARRAYTYPE_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); // Create a zeroed instance with no data var result = new outputType(); @@ -986,7 +987,7 @@ function ReduceTypedSeqImpl(array, outputType, func, initial) { if (initial === undefined && array.length < 1) // RangeError("reduce requires array of length > 0") - ThrowError(JSMSG_TYPEDOBJECT_ARRAYTYPE_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); // FIXME bug 950106 Should reduce method supply an outptr handle? // For now, reduce never supplies an outptr, regardless of outputType. @@ -1025,7 +1026,7 @@ function FilterTypedSeqImpl(array, func) { var arrayType = TypeOfTypedObject(array); if (!TypeDescrIsArrayType(arrayType)) - ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS); + ThrowTypeError(JSMSG_TYPEDOBJECT_BAD_ARGS); var elementType = arrayType.elementType; var flags = new Uint8Array(NUM_BYTES(array.length)); diff --git a/js/src/builtin/Utilities.js b/js/src/builtin/Utilities.js index 5e31a9cdb582..5d7c78879ab4 100644 --- a/js/src/builtin/Utilities.js +++ b/js/src/builtin/Utilities.js @@ -10,7 +10,8 @@ */ /*global ToObject: false, ToInteger: false, IsCallable: false, - ThrowError: false, AssertionFailed: false, + ThrowRangeError: false, ThrowTypeError: false, + AssertionFailed: false, MakeConstructible: false, DecompileArg: false, RuntimeDefaultLocale: false, ParallelDo: false, ParallelSlices: false, NewDenseArray: false, @@ -92,7 +93,7 @@ function ToNumber(v) { /* Spec: ECMAScript Language Specification, 5.1 edition, 9.10 */ function CheckObjectCoercible(v) { if (v === undefined || v === null) - ThrowError(JSMSG_CANT_CONVERT_TO, ToString(v), "object"); + ThrowTypeError(JSMSG_CANT_CONVERT_TO, ToString(v), "object"); } /* Spec: ECMAScript Draft, 6 edition May 22, 2014, 7.1.15 */ @@ -125,7 +126,7 @@ function GetMethod(O, P) { // Step 5. if (!IsCallable(func)) - ThrowError(JSMSG_NOT_FUNCTION, typeof func); + ThrowTypeError(JSMSG_NOT_FUNCTION, typeof func); // Step 6. return func; @@ -148,7 +149,7 @@ function GetIterator(obj, method) { // Step 5. if (!IsObject(iterator)) - ThrowError(JSMSG_NOT_ITERABLE, ToString(iterator)); + ThrowTypeError(JSMSG_NOT_ITERABLE, ToString(iterator)); // Step 6. return iterator; @@ -168,7 +169,7 @@ function SpeciesConstructor(obj, defaultConstructor) { // Step 5. if (!IsObject(ctor)) - ThrowError(JSMSG_NOT_NONNULL_OBJECT, "object's 'constructor' property"); + ThrowTypeError(JSMSG_NOT_NONNULL_OBJECT, "object's 'constructor' property"); // Steps 6-7. We don't yet implement @@species and Symbol.species, so we // don't implement this correctly right now. Somebody fix this! @@ -183,6 +184,5 @@ function SpeciesConstructor(obj, defaultConstructor) { return s; // Step 10. - ThrowError(JSMSG_NOT_CONSTRUCTOR, - "@@species property of object's constructor"); + ThrowTypeError(JSMSG_NOT_CONSTRUCTOR, "@@species property of object's constructor"); } diff --git a/js/src/builtin/WeakSet.js b/js/src/builtin/WeakSet.js index e7913a465131..7004e635d5f1 100644 --- a/js/src/builtin/WeakSet.js +++ b/js/src/builtin/WeakSet.js @@ -7,16 +7,16 @@ function WeakSet_add(value) { // Steps 1-3. var S = this; if (!IsObject(S) || !IsWeakSet(S)) - ThrowError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "add", typeof S); + ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "add", typeof S); // Step 4.,6. let entries = UnsafeGetReservedSlot(this, WEAKSET_MAP_SLOT); if (!entries) - ThrowError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "add", typeof S); + ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "add", typeof S); // Step 5. if (!IsObject(value)) - ThrowError(JSMSG_NOT_NONNULL_OBJECT, DecompileArg(0, value)); + ThrowTypeError(JSMSG_NOT_NONNULL_OBJECT, DecompileArg(0, value)); // Steps 7-8. callFunction(std_WeakMap_set, entries, value, true); @@ -30,12 +30,12 @@ function WeakSet_clear() { // Step 1-3. var S = this; if (!IsObject(S) || !IsWeakSet(S)) - ThrowError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "clear", typeof S); + ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "clear", typeof S); // Step 4. let entries = UnsafeGetReservedSlot(this, WEAKSET_MAP_SLOT); if (!entries) - ThrowError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "clear", typeof S); + ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "clear", typeof S); // Step 5. callFunction(std_WeakMap_clear, entries); @@ -49,12 +49,12 @@ function WeakSet_delete(value) { // Steps 1-3. var S = this; if (!IsObject(S) || !IsWeakSet(S)) - ThrowError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "delete", typeof S); + ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "delete", typeof S); // Step 4.,6. let entries = UnsafeGetReservedSlot(this, WEAKSET_MAP_SLOT); if (!entries) - ThrowError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "delete", typeof S); + ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "delete", typeof S); // Step 5. if (!IsObject(value)) @@ -69,12 +69,12 @@ function WeakSet_has(value) { // Steps 1-3. var S = this; if (!IsObject(S) || !IsWeakSet(S)) - ThrowError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "has", typeof S); + ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "has", typeof S); // Step 4-5. let entries = UnsafeGetReservedSlot(this, WEAKSET_MAP_SLOT); if (!entries) - ThrowError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "has", typeof S); + ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "has", typeof S); // Step 6. if (!IsObject(value)) diff --git a/js/src/configure.in b/js/src/configure.in index a968c5b15bbb..8a62df8482e1 100644 --- a/js/src/configure.in +++ b/js/src/configure.in @@ -1243,9 +1243,12 @@ if test "$GNU_CC"; then # Turn off the following warnings that -Wall turns on: # -Wno-unused - lots of violations in third-party code + # -Wno-inline-new-delete - we inline 'new' and 'delete' in mozalloc # _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wno-unused" + MOZ_CXX_SUPPORTS_WARNING(-Wno-, inline-new-delete, ac_cxx_has_wno_inline_new_delete) + if test -z "$INTEL_CC" -a -z "$CLANG_CC"; then # Don't use -Wcast-align with ICC or clang case "$CPU_ARCH" in @@ -1789,6 +1792,10 @@ ia64*-hpux*) # the same thing as C4244, we disable C4267, too. CFLAGS="$CFLAGS -wd4244 -wd4267" CXXFLAGS="$CXXFLAGS -wd4244 -wd4267 -wd4251" + if test -n "$CLANG_CL"; then + # Suppress the clang-cl warning for the inline 'new' and 'delete' in mozalloc + CXXFLAGS="$CXXFLAGS -Wno-inline-new-delete" + fi # make 'foo == bar;' error out CFLAGS="$CFLAGS -we4553" CXXFLAGS="$CXXFLAGS -we4553" diff --git a/js/src/jit-test/tests/asm.js/testResize.js b/js/src/jit-test/tests/asm.js/testResize.js index 4b97e8052858..9487c76366d1 100644 --- a/js/src/jit-test/tests/asm.js/testResize.js +++ b/js/src/jit-test/tests/asm.js/testResize.js @@ -109,6 +109,7 @@ assertAsmTypeFail('glob', 'ffis', 'b', USE_ASM + IMPORT1 + 'function ch(b2) { if assertAsmTypeFail('glob', 'ffis', 'b', USE_ASM + IMPORT1 + 'function ch(b2) { if(len(b2) & 0xffffff || len(b2) <= 0xffffff || len(b2) > 0.0) return false; i8=new I8(b2); b=b2; return true } function f() { return 42 } return f'); assertAsmTypeFail('glob', 'ffis', 'b', USE_ASM + IMPORT1 + 'function ch(b2) { if(len(b2) & 0xffffff || len(b2) <= 0xffffff || len(b2) > 0xffffff) return false; i8=new I8(b2); b=b2; return true } function f() { return 42 } return f'); asmCompile('glob', 'ffis', 'b', USE_ASM + IMPORT1 + 'function ch(b2) { if(len(b2) & 0xffffff || len(b2) <= 0xffffff || len(b2) > 0x1000000) return false; i8=new I8(b2); b=b2; return true } function f() { return 42 } return f'); +assertAsmTypeFail('glob', 'ffis', 'b', USE_ASM + IMPORT1 + 'function ch(b2) { if(len(b2) & 0xffffff || len(b2) <= 0xffffffff || len(b2) > 0x1000000) return false; i8=new I8(b2); b=b2; return true } function f() { return 42 } return f'); assertAsmTypeFail('glob', 'ffis', 'b', USE_ASM + IMPORT1 + 'function ch(b2) { if(len(b2) & 0xffffff || len(b2) <= 0x1000000 || len(b2) > 0x1000000) return false; i8=new I8(b2); b=b2; return true } function f() { return 42 } return f'); asmCompile('glob', 'ffis', 'b', USE_ASM + IMPORT1 + 'function ch(b2) { if(len(b2) & 0xffffff || len(b2) <= 0x1000000 || len(b2) > 0x1000001) return false; i8=new I8(b2); b=b2; return true } function f() { return 42 } return f'); assertAsmTypeFail('glob', 'ffis', 'b', USE_ASM + IMPORT1 + 'function ch(b2) { if(len(b2) & 0xffffff || len(b2) <= 0xffffff || len(b2) > 0x80000001) return false; i8=new I8(b2); b=b2; return true } function f() { return 42 } return f'); diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h index d543f7244ff6..d98bd50173ff 100644 --- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -891,7 +891,13 @@ class IonBuilder MObjectGroupDispatch* dispatch, MGetPropertyCache* cache, MBasicBlock** fallbackTarget); - bool atomicsMeetsPreconditions(CallInfo& callInfo, Scalar::Type* arrayElementType); + enum AtomicCheckResult { + DontCheckAtomicResult, + DoCheckAtomicResult + }; + + bool atomicsMeetsPreconditions(CallInfo& callInfo, Scalar::Type* arrayElementType, + AtomicCheckResult checkResult=DoCheckAtomicResult); void atomicsCheckBounds(CallInfo& callInfo, MInstruction** elements, MDefinition** index); bool testNeedsArgumentCheck(JSFunction* target, CallInfo& callInfo); diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp index bcbae617ecbe..fe9f3f9ff342 100644 --- a/js/src/jit/MCallOptimize.cpp +++ b/js/src/jit/MCallOptimize.cpp @@ -2808,7 +2808,7 @@ IonBuilder::inlineAtomicsStore(CallInfo& callInfo) } Scalar::Type arrayType; - if (!atomicsMeetsPreconditions(callInfo, &arrayType)) + if (!atomicsMeetsPreconditions(callInfo, &arrayType, DontCheckAtomicResult)) return InliningStatus_NotInlined; MDefinition* value = callInfo.getArg(2); @@ -2917,7 +2917,8 @@ IonBuilder::inlineAtomicsBinop(CallInfo& callInfo, JSFunction* target) } bool -IonBuilder::atomicsMeetsPreconditions(CallInfo& callInfo, Scalar::Type* arrayType) +IonBuilder::atomicsMeetsPreconditions(CallInfo& callInfo, Scalar::Type* arrayType, + AtomicCheckResult checkResult) { if (!JitSupportsAtomics()) return false; @@ -2945,12 +2946,12 @@ IonBuilder::atomicsMeetsPreconditions(CallInfo& callInfo, Scalar::Type* arrayTyp case Scalar::Int16: case Scalar::Uint16: case Scalar::Int32: - return getInlineReturnType() == MIRType_Int32; + return checkResult == DontCheckAtomicResult || getInlineReturnType() == MIRType_Int32; case Scalar::Uint32: // Bug 1077305: it would be attractive to allow inlining even // if the inline return type is Int32, which it will frequently // be. - return getInlineReturnType() == MIRType_Double; + return checkResult == DontCheckAtomicResult || getInlineReturnType() == MIRType_Double; default: // Excludes floating types and Uint8Clamped return false; diff --git a/js/src/jit/x86-shared/Assembler-x86-shared.h b/js/src/jit/x86-shared/Assembler-x86-shared.h index a782e257e09d..e59aadf48a94 100644 --- a/js/src/jit/x86-shared/Assembler-x86-shared.h +++ b/js/src/jit/x86-shared/Assembler-x86-shared.h @@ -29,7 +29,7 @@ class Operand private: Kind kind_ : 4; // Used as a Register::Encoding and a FloatRegister::Encoding. - int32_t base_ : 5; + uint32_t base_ : 5; Scale scale_ : 3; Register::Encoding index_ : 5; int32_t disp_; @@ -37,15 +37,23 @@ class Operand public: explicit Operand(Register reg) : kind_(REG), - base_(reg.encoding()) + base_(reg.encoding()), + scale_(TimesOne), + index_(Registers::Invalid), + disp_(0) { } explicit Operand(FloatRegister reg) : kind_(FPREG), - base_(reg.encoding()) + base_(reg.encoding()), + scale_(TimesOne), + index_(Registers::Invalid), + disp_(0) { } explicit Operand(const Address& address) : kind_(MEM_REG_DISP), base_(address.base.encoding()), + scale_(TimesOne), + index_(Registers::Invalid), disp_(address.offset) { } explicit Operand(const BaseIndex& address) @@ -65,14 +73,22 @@ class Operand Operand(Register reg, int32_t disp) : kind_(MEM_REG_DISP), base_(reg.encoding()), + scale_(TimesOne), + index_(Registers::Invalid), disp_(disp) { } explicit Operand(AbsoluteAddress address) : kind_(MEM_ADDRESS32), + base_(Registers::Invalid), + scale_(TimesOne), + index_(Registers::Invalid), disp_(X86Encoding::AddressImmediate(address.addr)) { } explicit Operand(PatchedAbsoluteAddress address) : kind_(MEM_ADDRESS32), + base_(Registers::Invalid), + scale_(TimesOne), + index_(Registers::Invalid), disp_(X86Encoding::AddressImmediate(address.addr)) { } diff --git a/js/src/js.msg b/js/src/js.msg index 0b2f190556d6..19598df2ea8f 100644 --- a/js/src/js.msg +++ b/js/src/js.msg @@ -444,7 +444,6 @@ MSG_DEF(JSMSG_NO_SUCH_SELF_HOSTED_PROP,1, JSEXN_ERR, "No such property on self-h // Typed object MSG_DEF(JSMSG_INVALID_PROTOTYPE, 0, JSEXN_TYPEERR, "prototype field is not an object") -MSG_DEF(JSMSG_TYPEDOBJECT_ARRAYTYPE_BAD_ARGS, 0, JSEXN_ERR, "Invalid arguments") MSG_DEF(JSMSG_TYPEDOBJECT_BAD_ARGS, 0, JSEXN_TYPEERR, "invalid arguments") MSG_DEF(JSMSG_TYPEDOBJECT_BINARYARRAY_BAD_INDEX, 0, JSEXN_RANGEERR, "invalid or out-of-range index") MSG_DEF(JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED, 0, JSEXN_TYPEERR, "handle unattached") diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h index fae098031bc7..cba1c7af027e 100644 --- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -823,7 +823,6 @@ bool intrinsic_IsObject(JSContext* cx, unsigned argc, Value* vp); bool intrinsic_ToInteger(JSContext* cx, unsigned argc, Value* vp); bool intrinsic_ToString(JSContext* cx, unsigned argc, Value* vp); bool intrinsic_IsCallable(JSContext* cx, unsigned argc, Value* vp); -bool intrinsic_ThrowError(JSContext* cx, unsigned argc, Value* vp); bool intrinsic_ThrowRangeError(JSContext* cx, unsigned argc, Value* vp); bool intrinsic_ThrowTypeError(JSContext* cx, unsigned argc, Value* vp); bool intrinsic_NewDenseArray(JSContext* cx, unsigned argc, Value* vp); diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp index bda19fdf0e8e..6a51343195db 100644 --- a/js/src/vm/SelfHosting.cpp +++ b/js/src/vm/SelfHosting.cpp @@ -187,17 +187,6 @@ ThrowErrorWithType(JSContext* cx, JSExnType type, const CallArgs& args) errorArgs[0].ptr(), errorArgs[1].ptr(), errorArgs[2].ptr()); } -bool -js::intrinsic_ThrowError(JSContext* cx, unsigned argc, Value* vp) -{ - CallArgs args = CallArgsFromVp(argc, vp); - MOZ_ASSERT(args.length() >= 1); - - uint32_t errorNumber = args[0].toInt32(); - ThrowErrorWithType(cx, JSExnType(GetErrorMessage(nullptr, errorNumber)->exnType), args); - return false; -} - bool js::intrinsic_ThrowRangeError(JSContext* cx, unsigned argc, Value* vp) { @@ -984,7 +973,6 @@ static const JSFunctionSpec intrinsic_functions[] = { JS_FN("IsCallable", intrinsic_IsCallable, 1,0), JS_FN("IsConstructor", intrinsic_IsConstructor, 1,0), JS_FN("OwnPropertyKeys", intrinsic_OwnPropertyKeys, 1,0), - JS_FN("ThrowError", intrinsic_ThrowError, 4,0), JS_FN("ThrowRangeError", intrinsic_ThrowRangeError, 4,0), JS_FN("ThrowTypeError", intrinsic_ThrowTypeError, 4,0), JS_FN("AssertionFailed", intrinsic_AssertionFailed, 1,0), diff --git a/js/src/vm/Xdr.h b/js/src/vm/Xdr.h index 52f17636bb07..1a4aa9c992a4 100644 --- a/js/src/vm/Xdr.h +++ b/js/src/vm/Xdr.h @@ -29,11 +29,11 @@ namespace js { * * https://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals/Bytecode */ -static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 277; +static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 278; static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - XDR_BYTECODE_VERSION_SUBTRAHEND); -static_assert(JSErr_Limit == 394, +static_assert(JSErr_Limit == 393, "GREETINGS, POTENTIAL SUBTRAHEND INCREMENTER! If you added or " "removed MSG_DEFs from js.msg, you should increment " "XDR_BYTECODE_VERSION_SUBTRAHEND and update this assertion's " diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 18ecbb1bb440..a2833497dbc4 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -9804,6 +9804,23 @@ nsCSSFrameConstructor::WrapItemsInPseudoRubyLevelContainer( // whether contentEndIter has been done. RubyWhitespaceType whitespaceType = InterpretRubyWhitespace(aState, endIter, contentEndIter); + if ((whitespaceType == eRubyInterLeafWhitespace || + whitespaceType == eRubyInterSegmentWhitespace) && + !endIter.item().mStyleContext->ShouldSuppressLineBreak()) { + // It is possible that a whitespace is not contained by any ruby + // box before we wrap it, which makes the ShouldSuppressLineBreak + // bit not be set properly before. Hence we have to get a new + // context which suppress line break here. + nsStyleContext* oldContext = endIter.item().mStyleContext; + nsRefPtr newContext = mPresShell->StyleSet()-> + ResolveStyleForNonElement(oldContext->GetParent(), true); + MOZ_ASSERT(newContext->ShouldSuppressLineBreak()); + for (FCItemIterator iter(endIter); iter != contentEndIter; iter.Next()) { + MOZ_ASSERT(iter.item().mStyleContext == oldContext, + "all whitespaces should share the same style context"); + iter.item().mStyleContext = newContext; + } + } if (whitespaceType == eRubyInterLevelWhitespace) { // Remove inter-level whitespace. bool atStart = (aIter == endIter); diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 4c2ab7b6df49..1c09793789c1 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -3413,6 +3413,26 @@ nsDisplayBorder::CalculateBounds(const nsStyleBorder& aStyleBorder) result.UnionRect(result, nsRect(borderBounds.X(), borderBounds.Y(), border.left, borderBounds.Height())); } + nscoord radii[8]; + if (mFrame->GetBorderRadii(radii)) { + if (border.left > 0 || border.top > 0) { + nsSize cornerSize(radii[NS_CORNER_TOP_LEFT_X], radii[NS_CORNER_TOP_LEFT_Y]); + result.UnionRect(result, nsRect(borderBounds.TopLeft(), cornerSize)); + } + if (border.top > 0 || border.right > 0) { + nsSize cornerSize(radii[NS_CORNER_TOP_RIGHT_X], radii[NS_CORNER_TOP_RIGHT_Y]); + result.UnionRect(result, nsRect(borderBounds.TopRight() - nsPoint(cornerSize.width, 0), cornerSize)); + } + if (border.right > 0 || border.bottom > 0) { + nsSize cornerSize(radii[NS_CORNER_BOTTOM_RIGHT_X], radii[NS_CORNER_BOTTOM_RIGHT_Y]); + result.UnionRect(result, nsRect(borderBounds.BottomRight() - nsPoint(cornerSize.width, cornerSize.height), cornerSize)); + } + if (border.bottom > 0 || border.left > 0) { + nsSize cornerSize(radii[NS_CORNER_BOTTOM_LEFT_X], radii[NS_CORNER_BOTTOM_LEFT_Y]); + result.UnionRect(result, nsRect(borderBounds.BottomLeft() - nsPoint(0, cornerSize.height), cornerSize)); + } + } + return result; } } diff --git a/layout/base/nsIPresShell.h b/layout/base/nsIPresShell.h index 97d3d653395c..ed6a924a7b4f 100644 --- a/layout/base/nsIPresShell.h +++ b/layout/base/nsIPresShell.h @@ -22,6 +22,7 @@ #include "mozilla/EventForwards.h" #include "mozilla/MemoryReporting.h" +#include "mozilla/StaticPtr.h" #include "mozilla/WeakPtr.h" #include "gfxPoint.h" #include "nsTHashtable.h" @@ -136,7 +137,7 @@ typedef struct CapturingContentInfo { bool mPointerLock; bool mRetargetToElement; bool mPreventDrag; - nsIContent* mContent; + mozilla::StaticRefPtr mContent; } CapturingContentInfo; // d910f009-d209-74c1-6b04-30c83c051c78 diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 196137cbf9c4..0559775d2229 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -176,6 +176,7 @@ #include "nsIFrameInlines.h" #include "mozilla/gfx/2D.h" #include "nsSubDocumentFrame.h" +#include "nsQueryObject.h" #ifdef ANDROID #include "nsIDocShellTreeOwner.h" @@ -199,7 +200,7 @@ using namespace mozilla::layout; CapturingContentInfo nsIPresShell::gCaptureInfo = { false /* mAllowed */, false /* mPointerLock */, false /* mRetargetToElement */, - false /* mPreventDrag */, nullptr /* mContent */ }; + false /* mPreventDrag */ }; nsIContent* nsIPresShell::gKeyDownTarget; nsClassHashtable* nsIPresShell::gPointerCaptureList; nsClassHashtable* nsIPresShell::gActivePointersIds; @@ -3875,7 +3876,7 @@ PresShell::ClearMouseCaptureOnView(nsView* aView) if (view) { do { if (view == aView) { - NS_RELEASE(gCaptureInfo.mContent); + gCaptureInfo.mContent = nullptr; // the view containing the captured content likely disappeared so // disable capture for now. gCaptureInfo.mAllowed = false; @@ -3890,7 +3891,7 @@ PresShell::ClearMouseCaptureOnView(nsView* aView) } } - NS_RELEASE(gCaptureInfo.mContent); + gCaptureInfo.mContent = nullptr; } // disable mouse capture until the next mousedown as a dialog has opened @@ -3909,20 +3910,20 @@ nsIPresShell::ClearMouseCapture(nsIFrame* aFrame) // null frame argument means clear the capture if (!aFrame) { - NS_RELEASE(gCaptureInfo.mContent); + gCaptureInfo.mContent = nullptr; gCaptureInfo.mAllowed = false; return; } nsIFrame* capturingFrame = gCaptureInfo.mContent->GetPrimaryFrame(); if (!capturingFrame) { - NS_RELEASE(gCaptureInfo.mContent); + gCaptureInfo.mContent = nullptr; gCaptureInfo.mAllowed = false; return; } if (nsLayoutUtils::IsAncestorFrameCrossDoc(aFrame, capturingFrame)) { - NS_RELEASE(gCaptureInfo.mContent); + gCaptureInfo.mContent = nullptr; gCaptureInfo.mAllowed = false; } } @@ -6357,14 +6358,14 @@ nsIPresShell::SetCapturingContent(nsIContent* aContent, uint8_t aFlags) return; } - NS_IF_RELEASE(gCaptureInfo.mContent); + gCaptureInfo.mContent = nullptr; // only set capturing content if allowed or the CAPTURE_IGNOREALLOWED or // CAPTURE_POINTERLOCK flags are used. if ((aFlags & CAPTURE_IGNOREALLOWED) || gCaptureInfo.mAllowed || (aFlags & CAPTURE_POINTERLOCK)) { if (aContent) { - NS_ADDREF(gCaptureInfo.mContent = aContent); + gCaptureInfo.mContent = aContent; } // CAPTURE_POINTERLOCK is the same as CAPTURE_RETARGETTOELEMENT & CAPTURE_IGNOREALLOWED gCaptureInfo.mRetargetToElement = ((aFlags & CAPTURE_RETARGETTOELEMENT) != 0) || diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp index 5c2f4eef8115..648be173ed5e 100644 --- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -182,7 +182,7 @@ nsImageFrame::DisconnectMap() { if (mImageMap) { mImageMap->Destroy(); - NS_RELEASE(mImageMap); + mImageMap = nullptr; #ifdef ACCESSIBILITY nsAccessibilityService* accService = GetAccService(); @@ -1779,7 +1779,6 @@ nsImageFrame::GetImageMap() nsIContent* map = GetMapElement(); if (map) { mImageMap = new nsImageMap(); - NS_ADDREF(mImageMap); mImageMap->Init(this, map); } } @@ -2220,10 +2219,12 @@ nsImageFrame::IconLoad::Observe(nsISupports *aSubject, const char* aTopic, "wrong topic"); #ifdef DEBUG // assert |aData| is one of our prefs. - for (uint32_t i = 0; i < ArrayLength(kIconLoadPrefs) || - (NS_NOTREACHED("wrong pref"), false); ++i) + uint32_t i = 0; + for (; i < ArrayLength(kIconLoadPrefs); ++i) { if (NS_ConvertASCIItoUTF16(kIconLoadPrefs[i]) == nsDependentString(aData)) break; + } + MOZ_ASSERT(i < ArrayLength(kIconLoadPrefs)); #endif GetPrefs(); diff --git a/layout/generic/nsImageFrame.h b/layout/generic/nsImageFrame.h index b8595d633b20..59a824414825 100644 --- a/layout/generic/nsImageFrame.h +++ b/layout/generic/nsImageFrame.h @@ -296,7 +296,7 @@ private: void InvalidateSelf(const nsIntRect* aLayerInvalidRect, const nsRect* aFrameInvalidRect); - nsImageMap* mImageMap; + nsRefPtr mImageMap; nsCOMPtr mListener; diff --git a/layout/generic/nsLineLayout.cpp b/layout/generic/nsLineLayout.cpp index d68e80a9c867..8a79e5883979 100644 --- a/layout/generic/nsLineLayout.cpp +++ b/layout/generic/nsLineLayout.cpp @@ -2910,7 +2910,7 @@ FindNearestRubyBaseAncestor(nsIFrame* aFrame) // XXX It is possible that no ruby base ancestor is found because of // some edge cases like form control or canvas inside ruby text. // See bug 1138092 comment 4. - NS_ASSERTION(aFrame, "No ruby base ancestor?"); + NS_WARN_IF_FALSE(aFrame, "no ruby base ancestor?"); return aFrame; } diff --git a/layout/inspector/inDOMUtils.cpp b/layout/inspector/inDOMUtils.cpp index 0cbacb70002e..23755c62709f 100644 --- a/layout/inspector/inDOMUtils.cpp +++ b/layout/inspector/inDOMUtils.cpp @@ -45,6 +45,7 @@ #include "nsColor.h" #include "nsStyleSet.h" #include "nsStyleUtil.h" +#include "nsQueryObject.h" using namespace mozilla; using namespace mozilla::css; diff --git a/layout/reftests/backgrounds/reftest.list b/layout/reftests/backgrounds/reftest.list index da9c07b788ec..ba547b4d171f 100644 --- a/layout/reftests/backgrounds/reftest.list +++ b/layout/reftests/backgrounds/reftest.list @@ -116,7 +116,7 @@ random-if(OSX==1010) == background-size-monster-rem.html background-size-monster # the image aren't the issue, because they're being obscured to avoid sampling # algorithm dependencies (at least assuming the sampling algorithm in use # doesn't sample too far astray from the boundaries). -fails == background-size-zoom-repeat.html background-size-zoom-repeat-ref.html +fails-if(supportsRepeatResampling) == background-size-zoom-repeat.html background-size-zoom-repeat-ref.html # -moz-default-background-color and -moz-default-color (bug 591341) == background-moz-default-background-color.html background-moz-default-background-color-ref.html diff --git a/layout/reftests/bugs/1156129-1-ref.html b/layout/reftests/bugs/1156129-1-ref.html new file mode 100644 index 000000000000..461fea35382a --- /dev/null +++ b/layout/reftests/bugs/1156129-1-ref.html @@ -0,0 +1,36 @@ + + + +The bounds calculation for border display items needs to take the border radius into account + + + +
+
+
diff --git a/layout/reftests/bugs/1156129-1.html b/layout/reftests/bugs/1156129-1.html new file mode 100644 index 000000000000..58f82fe4f569 --- /dev/null +++ b/layout/reftests/bugs/1156129-1.html @@ -0,0 +1,44 @@ + + + +The bounds calculation for border display items needs to take the border radius into account + + + +
+
+
+ + diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index 8174d814967d..fdffba6edf32 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -1014,7 +1014,7 @@ skip-if(B2G||Mulet) == 421234-1.html 421234-1-ref.html # Initial mulet triage: p == 421436-1b.html 421436-1-ref.html == 421632-1.html 421632-1-ref.html != 421710-1.html about:blank -skip-if(B2G||Mulet) fails-if(Android) == 421885-1.xml 421885-1-ref.xml # Initial mulet triage: parity with B2G/B2G Desktop +skip-if(B2G||Mulet) fails-if(Android) fails-if(!supportsRepeatResampling) == 421885-1.xml 421885-1-ref.xml # Initial mulet triage: parity with B2G/B2G Desktop == 421955-1.html 421955-1-ref.html skip-if(B2G||Mulet) == 422249-1.html 422249-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop == 422394-1.html 422394-1-ref.html @@ -1164,13 +1164,13 @@ random == 445004-1.html 445004-1-ref.html # bug 472268 == 445142-1c.html 445142-1-ref.html == 445142-2a.html 445142-2-ref.html == 445142-2b.html 445142-2-ref.html -== 446100-1a.html about:blank -skip-if(B2G||Mulet) fails-if(Android) == 446100-1b.html about:blank # Initial mulet triage: parity with B2G/B2G Desktop -skip-if(B2G||Mulet) fails-if(Android) == 446100-1c.html about:blank # Initial mulet triage: parity with B2G/B2G Desktop -== 446100-1d.html about:blank +fails-if(!supportsRepeatResampling) == 446100-1a.html about:blank +skip-if(B2G||Mulet) fails-if(Android) fails-if(!supportsRepeatResampling) == 446100-1b.html about:blank # Initial mulet triage: parity with B2G/B2G Desktop +skip-if(B2G||Mulet) fails-if(Android) fails-if(!supportsRepeatResampling) == 446100-1c.html about:blank # Initial mulet triage: parity with B2G/B2G Desktop +fails-if(!supportsRepeatResampling) == 446100-1d.html about:blank == 446100-1e.html about:blank == 446100-1f.html about:blank -skip-if(B2G||Mulet) fails-if(Android) == 446100-1g.html about:blank # Initial mulet triage: parity with B2G/B2G Desktop +skip-if(B2G||Mulet) fails-if(Android) fails-if(!supportsRepeatResampling) == 446100-1g.html about:blank # Initial mulet triage: parity with B2G/B2G Desktop == 446100-1h.html about:blank skip-if(B2G||Mulet) == 447749-1.html 447749-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop fuzzy(127,2) == 448193.html 448193-ref.html @@ -1875,3 +1875,4 @@ fuzzy-if(d2d,36,304) HTTP(..) == 1116480-1-fakeitalic-overflow.html 1116480-1-fa skip-if(B2G||Mulet) == 1150021-1.xul 1150021-1-ref.xul == 1151145-1.html 1151145-1-ref.html == 1151306-1.html 1151306-1-ref.html +== 1156129-1.html 1156129-1-ref.html diff --git a/layout/reftests/css-ruby/line-break-suppression-4-ref.html b/layout/reftests/css-ruby/line-break-suppression-4-ref.html new file mode 100644 index 000000000000..5e680a298405 --- /dev/null +++ b/layout/reftests/css-ruby/line-break-suppression-4-ref.html @@ -0,0 +1,11 @@ + + + + + Bug 1149009 - Line break suppression on whitespaces wrapped but not contained in ruby boxes + + + a +b + + diff --git a/layout/reftests/css-ruby/line-break-suppression-4.html b/layout/reftests/css-ruby/line-break-suppression-4.html new file mode 100644 index 000000000000..90d7e73dec60 --- /dev/null +++ b/layout/reftests/css-ruby/line-break-suppression-4.html @@ -0,0 +1,11 @@ + + + + + Bug 1149009 - Line break suppression on whitespaces wrapped but not contained in ruby boxes + + + a +b + + diff --git a/layout/reftests/css-ruby/reftest.list b/layout/reftests/css-ruby/reftest.list index d8a2e8f8b363..45ab4df49811 100644 --- a/layout/reftests/css-ruby/reftest.list +++ b/layout/reftests/css-ruby/reftest.list @@ -31,6 +31,7 @@ fuzzy-if(winWidget,255,792) == lang-specific-style-1.html lang-specific-style-1- == line-break-suppression-1.html line-break-suppression-1-ref.html == line-break-suppression-2.html line-break-suppression-2-ref.html == line-break-suppression-3.html line-break-suppression-3-ref.html +fails-if(B2G) == line-break-suppression-4.html line-break-suppression-4-ref.html # bug 1156169 == line-height-1.html line-height-1-ref.html == line-height-2.html line-height-2-ref.html == line-height-3.html line-height-3-ref.html diff --git a/layout/reftests/image-element/reftest.list b/layout/reftests/image-element/reftest.list index 029a289f47ee..c6e9e5f73bc7 100644 --- a/layout/reftests/image-element/reftest.list +++ b/layout/reftests/image-element/reftest.list @@ -18,7 +18,7 @@ fuzzy-if(d2d&&/^Windows\x20NT\x206\.1/.test(http.oscpu),16,90) == element-paint- == element-paint-transform-repeated.html element-paint-transform-repeated-ref.html fuzzy-if(d2d,255,24) == element-paint-transform-03.html element-paint-transform-03-ref.html == element-paint-native-widget.html element-paint-native-widget-ref.html -== element-paint-subimage-sampling-restriction.html about:blank +fails-if(!supportsRepeatResampling) == element-paint-subimage-sampling-restriction.html about:blank == element-paint-clippath.html element-paint-clippath-ref.html == element-paint-sharpness-01a.html element-paint-sharpness-01b.html == element-paint-sharpness-01b.html element-paint-sharpness-01c.html diff --git a/layout/reftests/writing-mode/ua-style-sheet-margin-10-ref.html b/layout/reftests/writing-mode/ua-style-sheet-margin-10-ref.html index 95662bf2de20..deeebed5223a 100644 --- a/layout/reftests/writing-mode/ua-style-sheet-margin-10-ref.html +++ b/layout/reftests/writing-mode/ua-style-sheet-margin-10-ref.html @@ -23,9 +23,11 @@ caption { margin: 0; } Caption + diff --git a/layout/reftests/writing-mode/ua-style-sheet-margin-10.html b/layout/reftests/writing-mode/ua-style-sheet-margin-10.html index 23ec26ada0b1..421d881b5bcc 100644 --- a/layout/reftests/writing-mode/ua-style-sheet-margin-10.html +++ b/layout/reftests/writing-mode/ua-style-sheet-margin-10.html @@ -19,9 +19,11 @@ caption { border: 1px solid orange; display: block; width: 100px; height: 100px; Caption + diff --git a/layout/reftests/writing-mode/ua-style-sheet-margin-8-ref.html b/layout/reftests/writing-mode/ua-style-sheet-margin-8-ref.html index 885d99080be2..5f42d074d179 100644 --- a/layout/reftests/writing-mode/ua-style-sheet-margin-8-ref.html +++ b/layout/reftests/writing-mode/ua-style-sheet-margin-8-ref.html @@ -23,9 +23,11 @@ caption { margin: 0; } Caption + diff --git a/layout/reftests/writing-mode/ua-style-sheet-margin-8.html b/layout/reftests/writing-mode/ua-style-sheet-margin-8.html index e445ea80285a..1e3718b0531d 100644 --- a/layout/reftests/writing-mode/ua-style-sheet-margin-8.html +++ b/layout/reftests/writing-mode/ua-style-sheet-margin-8.html @@ -19,9 +19,11 @@ caption { border: 1px solid orange; } Caption + diff --git a/layout/style/CSSStyleSheet.cpp b/layout/style/CSSStyleSheet.cpp index 4d8d9631847f..cf968b86869d 100644 --- a/layout/style/CSSStyleSheet.cpp +++ b/layout/style/CSSStyleSheet.cpp @@ -21,6 +21,7 @@ #include "nsIDocument.h" #include "nsPresContext.h" #include "nsGkAtoms.h" +#include "nsQueryObject.h" #include "nsString.h" #include "nsTArray.h" #include "nsIDOMCSSStyleSheet.h" diff --git a/layout/style/nsDOMCSSDeclaration.cpp b/layout/style/nsDOMCSSDeclaration.cpp index 9adc003ce72d..3fccfb1d7e48 100644 --- a/layout/style/nsDOMCSSDeclaration.cpp +++ b/layout/style/nsDOMCSSDeclaration.cpp @@ -18,6 +18,7 @@ #include "nsIURI.h" #include "mozilla/dom/BindingUtils.h" #include "nsContentUtils.h" +#include "nsQueryObject.h" using namespace mozilla; diff --git a/layout/style/nsRuleWalker.h b/layout/style/nsRuleWalker.h index f77ee89161e3..b2715bf6f2b9 100644 --- a/layout/style/nsRuleWalker.h +++ b/layout/style/nsRuleWalker.h @@ -14,6 +14,7 @@ #include "nsRuleNode.h" #include "nsIStyleRule.h" #include "StyleRule.h" +#include "nsQueryObject.h" class nsRuleWalker { public: diff --git a/layout/style/nsStyleContext.cpp b/layout/style/nsStyleContext.cpp index 162d0f3e8f44..10386a8c2c0a 100644 --- a/layout/style/nsStyleContext.cpp +++ b/layout/style/nsStyleContext.cpp @@ -326,7 +326,7 @@ already_AddRefed nsStyleContext::FindChildWithRules(const nsIAtom* aPseudoTag, nsRuleNode* aRuleNode, nsRuleNode* aRulesIfVisited, - bool aRelevantLinkVisited) + uint32_t aFlags) { uint32_t threshold = 10; // The # of siblings we're willing to examine // before just giving this whole thing up. @@ -334,13 +334,16 @@ nsStyleContext::FindChildWithRules(const nsIAtom* aPseudoTag, nsRefPtr result; nsStyleContext *list = aRuleNode->IsRoot() ? mEmptyChild : mChild; + bool relevantLinkVisited = aFlags & eRelevantLinkVisited; + bool suppressLineBreak = aFlags & eSuppressLineBreak; if (list) { nsStyleContext *child = list; do { if (child->mRuleNode == aRuleNode && child->mPseudoTag == aPseudoTag && !child->IsStyleIfVisited() && - child->RelevantLinkVisited() == aRelevantLinkVisited) { + child->RelevantLinkVisited() == relevantLinkVisited && + child->ShouldSuppressLineBreak() == suppressLineBreak) { bool match = false; if (aRulesIfVisited) { match = child->GetStyleIfVisited() && @@ -684,7 +687,10 @@ nsStyleContext::ApplyStyleFixups(bool aSkipParentDisplayBasedStyleFixup) } if (::ShouldSuppressLineBreak(disp, containerContext, containerDisp)) { - mBits |= NS_STYLE_SUPPRESS_LINEBREAK; + // Note that, in one case, this bit isn't set here: a whitespace + // which is surrounded but not contained by ruby boxes. In that + // case, this bit is set in nsStyleSet::GetContext. + AddStyleBit(NS_STYLE_SUPPRESS_LINEBREAK); uint8_t displayVal = disp->mDisplay; nsRuleNode::EnsureInlineDisplay(displayVal); if (displayVal != disp->mDisplay) { diff --git a/layout/style/nsStyleContext.h b/layout/style/nsStyleContext.h index 5052264bf278..9dd9bfb0ff6f 100644 --- a/layout/style/nsStyleContext.h +++ b/layout/style/nsStyleContext.h @@ -135,17 +135,22 @@ public: NS_STYLE_CONTEXT_TYPE_SHIFT); } + enum { + eRelevantLinkVisited = 1 << 0, + eSuppressLineBreak = 1 << 1 + }; + // Find, if it already exists *and is easily findable* (i.e., near the // start of the child list), a style context whose: // * GetPseudo() matches aPseudoTag // * RuleNode() matches aRules // * !GetStyleIfVisited() == !aRulesIfVisited, and, if they're // non-null, GetStyleIfVisited()->RuleNode() == aRulesIfVisited - // * RelevantLinkVisited() == aRelevantLinkVisited + // * RelevantLinkVisited() == (aFlags & eRelevantLinkVisited) + // * ShouldSuppressLineBreak() == (aFlags & eSuppressLineBreak) already_AddRefed FindChildWithRules(const nsIAtom* aPseudoTag, nsRuleNode* aRules, - nsRuleNode* aRulesIfVisited, - bool aRelevantLinkVisited); + nsRuleNode* aRulesIfVisited, uint32_t aFlags); // Does this style context or any of its ancestors have text // decoration lines? diff --git a/layout/style/nsStyleSet.cpp b/layout/style/nsStyleSet.cpp index 110a003814c5..dd56291cce56 100644 --- a/layout/style/nsStyleSet.cpp +++ b/layout/style/nsStyleSet.cpp @@ -38,6 +38,7 @@ #include "nsPrintfCString.h" #include "nsIFrame.h" #include "RestyleManager.h" +#include "nsQueryObject.h" #include @@ -838,12 +839,20 @@ nsStyleSet::GetContext(nsStyleContext* aParentContext, bool relevantLinkVisited = (aFlags & eIsLink) ? (aFlags & eIsVisitedLink) : (aParentContext && aParentContext->RelevantLinkVisited()); + bool suppressLineBreak = aFlags & eSuppressLineBreak; nsRefPtr result; - if (aParentContext) + if (aParentContext) { + uint32_t childFlags = 0; + if (relevantLinkVisited) { + childFlags |= nsStyleContext::eRelevantLinkVisited; + } + if (suppressLineBreak) { + childFlags |= nsStyleContext::eSuppressLineBreak; + } result = aParentContext->FindChildWithRules(aPseudoTag, aRuleNode, - aVisitedRuleNode, - relevantLinkVisited); + aVisitedRuleNode, childFlags); + } #ifdef NOISY_DEBUG if (result) @@ -856,11 +865,17 @@ nsStyleSet::GetContext(nsStyleContext* aParentContext, result = NS_NewStyleContext(aParentContext, aPseudoTag, aPseudoType, aRuleNode, aFlags & eSkipParentDisplayBasedStyleFixup); + if (suppressLineBreak) { + result->AddStyleBit(NS_STYLE_SUPPRESS_LINEBREAK); + } if (aVisitedRuleNode) { nsRefPtr resultIfVisited = NS_NewStyleContext(parentIfVisited, aPseudoTag, aPseudoType, aVisitedRuleNode, aFlags & eSkipParentDisplayBasedStyleFixup); + if (suppressLineBreak) { + resultIfVisited->AddStyleBit(NS_STYLE_SUPPRESS_LINEBREAK); + } if (!parentIfVisited) { mRoots.AppendElement(resultIfVisited); } @@ -1657,12 +1672,13 @@ nsStyleSet::ResolveStyleWithoutAnimation(dom::Element* aTarget, } already_AddRefed -nsStyleSet::ResolveStyleForNonElement(nsStyleContext* aParentContext) +nsStyleSet::ResolveStyleForNonElement(nsStyleContext* aParentContext, + bool aSuppressLineBreak) { return GetContext(aParentContext, mRuleTree, nullptr, nsCSSAnonBoxes::mozNonElement, nsCSSPseudoElements::ePseudo_AnonBox, nullptr, - eNoFlags); + aSuppressLineBreak ? eSuppressLineBreak : eNoFlags); } void diff --git a/layout/style/nsStyleSet.h b/layout/style/nsStyleSet.h index be8963798244..1e0731612237 100644 --- a/layout/style/nsStyleSet.h +++ b/layout/style/nsStyleSet.h @@ -164,7 +164,8 @@ class nsStyleSet // contexts for such content nodes. However, not doing any rule // matching for them is a first step. already_AddRefed - ResolveStyleForNonElement(nsStyleContext* aParentContext); + ResolveStyleForNonElement(nsStyleContext* aParentContext, + bool aSuppressLineBreak = false); // Get a style context for a pseudo-element. aParentElement must be // non-null. aPseudoID is the nsCSSPseudoElements::Type for the @@ -446,7 +447,10 @@ class nsStyleSet // or "display: grid" but we can tell we're not going to honor that (e.g. if // it's the outer frame of a button widget, and we're the inline frame for // the button's label). - eSkipParentDisplayBasedStyleFixup = 1 << 3 + eSkipParentDisplayBasedStyleFixup = 1 << 3, + + // Indicates that the given context should have ShouldSuppressLineBreak set. + eSuppressLineBreak = 1 << 4 }; already_AddRefed diff --git a/layout/tools/reftest/reftest.js b/layout/tools/reftest/reftest.js index 56e7245a030b..659aa8d47417 100644 --- a/layout/tools/reftest/reftest.js +++ b/layout/tools/reftest/reftest.js @@ -754,6 +754,9 @@ function BuildConditionSandbox(aURL) { dump("REFTEST INFO | " + JSON.stringify(CU.waiveXrays(sandbox)) + " \n"); gDumpedConditionSandbox = true; } + + // Graphics features + sandbox.supportsRepeatResampling = !sandbox.cocoaWidget; return sandbox; } diff --git a/layout/xul/nsMenuBarFrame.cpp b/layout/xul/nsMenuBarFrame.cpp index a5029ec05f14..6c31e4487ffc 100644 --- a/layout/xul/nsMenuBarFrame.cpp +++ b/layout/xul/nsMenuBarFrame.cpp @@ -51,7 +51,6 @@ NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame) // nsMenuBarFrame::nsMenuBarFrame(nsStyleContext* aContext): nsBoxFrame(aContext), - mMenuBarListener(nullptr), mStayActive(false), mIsActive(false), mCurrentMenu(nullptr), @@ -68,7 +67,6 @@ nsMenuBarFrame::Init(nsIContent* aContent, // Create the menu bar listener. mMenuBarListener = new nsMenuBarListener(this); - NS_ADDREF(mMenuBarListener); // Hook up the menu bar as a key listener on the whole document. It will see every // key press that occurs, but after everyone else does. @@ -420,7 +418,7 @@ nsMenuBarFrame::DestroyFrom(nsIFrame* aDestructRoot) mTarget->RemoveEventListener(NS_LITERAL_STRING("mousedown"), mMenuBarListener, false); mTarget->RemoveEventListener(NS_LITERAL_STRING("blur"), mMenuBarListener, true); - NS_IF_RELEASE(mMenuBarListener); + mMenuBarListener = nullptr; nsBoxFrame::DestroyFrom(aDestructRoot); } diff --git a/layout/xul/nsMenuBarFrame.h b/layout/xul/nsMenuBarFrame.h index d9a2deafc24f..cdd79e597589 100644 --- a/layout/xul/nsMenuBarFrame.h +++ b/layout/xul/nsMenuBarFrame.h @@ -101,7 +101,7 @@ public: #endif protected: - nsMenuBarListener* mMenuBarListener; // The listener that tells us about key and mouse events. + nsRefPtr mMenuBarListener; // The listener that tells us about key and mouse events. // flag that is temporarily set when switching from one menu on the menubar to another // to indicate that the menubar should not be deactivated. diff --git a/layout/xul/tree/nsTreeColumns.cpp b/layout/xul/tree/nsTreeColumns.cpp index 2f0d6980b2f3..ab8353e2dd7b 100644 --- a/layout/xul/tree/nsTreeColumns.cpp +++ b/layout/xul/tree/nsTreeColumns.cpp @@ -393,8 +393,7 @@ nsTreeColumn::Invalidate(mozilla::ErrorResult& aRv) } nsTreeColumns::nsTreeColumns(nsTreeBodyFrame* aTree) - : mTree(aTree), - mFirstColumn(nullptr) + : mTree(aTree) { } @@ -669,7 +668,7 @@ nsTreeColumns::InvalidateColumns() currCol = currCol->GetNext()) { currCol->SetColumns(nullptr); } - NS_IF_RELEASE(mFirstColumn); + mFirstColumn = nullptr; return NS_OK; } @@ -759,7 +758,7 @@ nsTreeColumns::EnsureColumns() col->SetPrevious(currCol); } else { - NS_ADDREF(mFirstColumn = col); + mFirstColumn = col; } currCol = col; } diff --git a/layout/xul/tree/nsTreeColumns.h b/layout/xul/tree/nsTreeColumns.h index ae4afee2d746..7e7420fed633 100644 --- a/layout/xul/tree/nsTreeColumns.h +++ b/layout/xul/tree/nsTreeColumns.h @@ -211,7 +211,7 @@ private: * XXX this means that new nsTreeColumn objects are unnecessarily created * for untouched columns. */ - nsTreeColumn* mFirstColumn; + nsRefPtr mFirstColumn; }; #endif // nsTreeColumns_h__ diff --git a/media/gmp-clearkey/0.1/ClearKeySessionManager.cpp b/media/gmp-clearkey/0.1/ClearKeySessionManager.cpp index 4b77ac95a91f..1a9b96bb26ae 100644 --- a/media/gmp-clearkey/0.1/ClearKeySessionManager.cpp +++ b/media/gmp-clearkey/0.1/ClearKeySessionManager.cpp @@ -26,6 +26,7 @@ #include "gmp-task-utils.h" #if defined(ENABLE_WMF) #include "WMFUtils.h" +#include #endif #include @@ -50,6 +51,16 @@ ClearKeySessionManager::~ClearKeySessionManager() assert(!mRefCount); } +static bool +ShouldBeAbleToDecode() +{ +#if !defined(ENABLE_WMF) + return false; +#else + return IsWindowsVistaOrGreater(); +#endif +} + static bool CanDecode() { @@ -65,9 +76,18 @@ ClearKeySessionManager::Init(GMPDecryptorCallback* aCallback) { CK_LOGD("ClearKeySessionManager::Init"); mCallback = aCallback; - mCallback->SetCapabilities(CanDecode() ? - GMP_EME_CAP_DECRYPT_AND_DECODE_AUDIO | GMP_EME_CAP_DECRYPT_AND_DECODE_VIDEO : - GMP_EME_CAP_DECRYPT_AUDIO | GMP_EME_CAP_DECRYPT_VIDEO); + if (ShouldBeAbleToDecode()) { + if (!CanDecode()) { + const char* err = "EME plugin can't load system decoder!"; + mCallback->SessionError(nullptr, 0, kGMPAbortError, 0, err, strlen(err)); + } else { + mCallback->SetCapabilities(GMP_EME_CAP_DECRYPT_AND_DECODE_AUDIO | + GMP_EME_CAP_DECRYPT_AND_DECODE_VIDEO); + } + } else { + mCallback->SetCapabilities(GMP_EME_CAP_DECRYPT_AUDIO | + GMP_EME_CAP_DECRYPT_VIDEO); + } ClearKeyPersistence::EnsureInitialized(); } diff --git a/media/gmp-clearkey/0.1/VideoDecoder.cpp b/media/gmp-clearkey/0.1/VideoDecoder.cpp index 2e385db24942..5d86fb320ca8 100644 --- a/media/gmp-clearkey/0.1/VideoDecoder.cpp +++ b/media/gmp-clearkey/0.1/VideoDecoder.cpp @@ -56,12 +56,14 @@ VideoDecoder::InitDecode(const GMPVideoCodec& aCodecSettings, mDecoder = new WMFH264Decoder(); HRESULT hr = mDecoder->Init(); if (FAILED(hr)) { + CK_LOGD("VideoDecoder::InitDecode failed to init WMFH264Decoder"); mCallback->Error(GMPGenericErr); return; } auto err = GetPlatform()->createmutex(&mMutex); if (GMP_FAILED(err)) { + CK_LOGD("VideoDecoder::InitDecode failed to create GMPMutex"); mCallback->Error(GMPGenericErr); return; } diff --git a/media/gmp-clearkey/0.1/WMFAACDecoder.cpp b/media/gmp-clearkey/0.1/WMFAACDecoder.cpp index 27672b9962fb..495f840e8db5 100644 --- a/media/gmp-clearkey/0.1/WMFAACDecoder.cpp +++ b/media/gmp-clearkey/0.1/WMFAACDecoder.cpp @@ -92,11 +92,11 @@ WMFAACDecoder::Init(int32_t aChannelCount, // AAC decoder is in msauddecmft on Win8, and msmpeg2adec in earlier versions. hr = CreateMFT(CLSID_CMSAACDecMFT, - "msauddecmft.dll", + WMFDecoderDllNameFor(AAC), mDecoder); if (FAILED(hr)) { hr = CreateMFT(CLSID_CMSAACDecMFT, - "msmpeg2adec.dll", + WMFDecoderDllNameFor(AAC), mDecoder); if (FAILED(hr)) { LOG("Failed to create AAC decoder\n"); diff --git a/media/gmp-clearkey/0.1/WMFH264Decoder.cpp b/media/gmp-clearkey/0.1/WMFH264Decoder.cpp index 47cb361d6125..c0397419e210 100644 --- a/media/gmp-clearkey/0.1/WMFH264Decoder.cpp +++ b/media/gmp-clearkey/0.1/WMFH264Decoder.cpp @@ -36,13 +36,13 @@ WMFH264Decoder::Init() HRESULT hr; hr = CreateMFT(__uuidof(CMSH264DecoderMFT), - "msmpeg2vdec.dll", + WMFDecoderDllNameFor(H264), mDecoder); if (FAILED(hr)) { // Windows 7 Enterprise Server N (which is what Mozilla's mochitests run // on) need a different CLSID to instantiate the H.264 decoder. hr = CreateMFT(CLSID_CMSH264DecMFT, - "msmpeg2vdec.dll", + WMFDecoderDllNameFor(H264), mDecoder); } ENSURE(SUCCEEDED(hr), hr); diff --git a/media/gmp-clearkey/0.1/WMFSymbols.h b/media/gmp-clearkey/0.1/WMFSymbols.h index 6b6a8020b4c5..60a0a6854b11 100644 --- a/media/gmp-clearkey/0.1/WMFSymbols.h +++ b/media/gmp-clearkey/0.1/WMFSymbols.h @@ -14,7 +14,7 @@ * limitations under the License. */ -MFPLAT_FUNC(MFCreateSample); -MFPLAT_FUNC(MFCreateAlignedMemoryBuffer); -MFPLAT_FUNC(MFGetStrideForBitmapInfoHeader); -MFPLAT_FUNC(MFCreateMediaType); +MFPLAT_FUNC(MFCreateSample, "mfplat.dll"); +MFPLAT_FUNC(MFCreateAlignedMemoryBuffer, "mfplat.dll"); +MFPLAT_FUNC(MFGetStrideForBitmapInfoHeader, "evr.dll"); +MFPLAT_FUNC(MFCreateMediaType, "mfplat.dll"); diff --git a/media/gmp-clearkey/0.1/WMFUtils.cpp b/media/gmp-clearkey/0.1/WMFUtils.cpp index 6171c259b0e7..6f2204a99223 100644 --- a/media/gmp-clearkey/0.1/WMFUtils.cpp +++ b/media/gmp-clearkey/0.1/WMFUtils.cpp @@ -15,6 +15,8 @@ */ #include "WMFUtils.h" +#include "ClearKeyUtils.h" +#include #include @@ -45,7 +47,7 @@ DEFINE_GUID(CLSID_CMSH264DecMFT, 0x62CE7E72, 0x4C71, 0x4d20, 0xB1, 0x5D, 0x45, 0 namespace wmf { -#define MFPLAT_FUNC(_func) \ +#define MFPLAT_FUNC(_func, _dllname) \ decltype(::_func)* _func; #include "WMFSymbols.h" #undef MFPLAT_FUNC @@ -57,11 +59,14 @@ LinkMfplat() static bool sInitOk = false; if (!sInitDone) { sInitDone = true; - auto handle = GetModuleHandleA("mfplat.dll"); -#define MFPLAT_FUNC(_func) \ - if (!(_func = (decltype(_func))(GetProcAddress(handle, #_func)))) { \ - return false; \ - } + HMODULE handle; + +#define MFPLAT_FUNC(_func, _dllname) \ + handle = GetModuleHandleA(_dllname); \ + if (!(_func = (decltype(_func))(GetProcAddress(handle, #_func)))) { \ + return false; \ + } + #include "WMFSymbols.h" #undef MFPLAT_FUNC sInitOk = true; @@ -69,18 +74,42 @@ LinkMfplat() return sInitOk; } +const char* +WMFDecoderDllNameFor(CodecType aCodec) +{ + if (aCodec == H264) { + // For H.264 decoding, we need msmpeg2vdec.dll on Win 7 & 8, + // and mfh264dec.dll on Vista. + if (IsWindows7OrGreater()) { + return "msmpeg2vdec.dll"; + } else { + return "mfh264dec.dll"; + } + } else if (aCodec == AAC) { + // For AAC decoding, we need to use msauddecmft.dll on Win8, + // msmpeg2adec.dll on Win7, and msheaacdec.dll on Vista. + if (IsWindows8OrGreater()) { + return "msauddecmft.dll"; + } else if (IsWindows7OrGreater()) { + return "msmpeg2adec.dll"; + } else { + return "mfheaacdec.dll"; + } + } else { + return ""; + } +} + + bool EnsureLibs() { static bool sInitDone = false; static bool sInitOk = false; if (!sInitDone) { - // Note: For AAC decoding, we need to use msauddecmft.dll on Win8, - // and msmpeg2adec.dll on earlier Windows. So if we have at least - // one of these, assume we can decode. sInitOk = LinkMfplat() && - (!!GetModuleHandleA("msauddecmft.dll") || !!GetModuleHandleA("msmpeg2adec.dll")) && - !!GetModuleHandleA("msmpeg2vdec.dll"); + !!GetModuleHandleA(WMFDecoderDllNameFor(AAC)) && + !!GetModuleHandleA(WMFDecoderDllNameFor(H264)); sInitDone = true; } return sInitOk; diff --git a/media/gmp-clearkey/0.1/WMFUtils.h b/media/gmp-clearkey/0.1/WMFUtils.h index 86444b8489b9..6c938efa0308 100644 --- a/media/gmp-clearkey/0.1/WMFUtils.h +++ b/media/gmp-clearkey/0.1/WMFUtils.h @@ -122,7 +122,7 @@ typedef int64_t Microseconds; #define GMP_SUCCEEDED(x) ((x) == GMPNoErr) #define GMP_FAILED(x) ((x) != GMPNoErr) -#define MFPLAT_FUNC(_func) \ +#define MFPLAT_FUNC(_func, _dllname) \ extern decltype(::_func)* _func; #include "WMFSymbols.h" #undef MFPLAT_FUNC @@ -265,6 +265,15 @@ CreateMFT(const CLSID& clsid, const char* aDllName, CComPtr& aOutMFT); +enum CodecType { + H264, + AAC, +}; + +// Returns the name of the DLL that is needed to decode H.264 or AAC on +// the given windows version we're running on. +const char* WMFDecoderDllNameFor(CodecType aCodec); + } // namespace wmf #endif // __WMFUtils_h__ diff --git a/media/gmp-clearkey/0.1/clearkey.info.in b/media/gmp-clearkey/0.1/clearkey.info.in index 080cb1724c40..aca4bc286021 100644 --- a/media/gmp-clearkey/0.1/clearkey.info.in +++ b/media/gmp-clearkey/0.1/clearkey.info.in @@ -3,7 +3,7 @@ Description: ClearKey Gecko Media Plugin Version: 1 #ifdef ENABLE_WMF APIs: eme-decrypt-v7[org.w3.clearkey], decode-audio[aac:org.w3.clearkey], decode-video[h264:org.w3.clearkey] -Libraries: dxva2.dll, d3d9.dll, msmpeg2vdec.dll, msmpeg2adec.dll, MSAudDecMFT.dll +Libraries: dxva2.dll, d3d9.dll, msmpeg2vdec.dll, msmpeg2adec.dll, MSAudDecMFT.dll, evr.dll, mfheaacdec.dll, mfh264dec.dll, mfplat.dll #else APIs: eme-decrypt-v7[org.w3.clearkey] Libraries: diff --git a/media/libcubeb/src/cubeb_wasapi.cpp b/media/libcubeb/src/cubeb_wasapi.cpp index b4771ddc716a..d70eea59123a 100644 --- a/media/libcubeb/src/cubeb_wasapi.cpp +++ b/media/libcubeb/src/cubeb_wasapi.cpp @@ -8,6 +8,7 @@ #if defined(HAVE_CONFIG_H) #include "config.h" #endif +#include #include #include #include @@ -392,14 +393,12 @@ float stream_to_mix_samplerate_ratio(cubeb_stream * stream) return float(stream->stream_params.rate) / stream->mix_params.rate; } -/* Upmix function, copies a mono channel in two interleaved - * stereo channel. |out| has to be twice as long as |in| */ +/* Upmix function, copies a mono channel into L and R */ template void -mono_to_stereo(T * in, long insamples, T * out) +mono_to_stereo(T * in, long insamples, T * out, int32_t out_channels) { - int j = 0; - for (int i = 0; i < insamples; ++i, j += 2) { + for (int i = 0, j = 0; i < insamples; ++i, j += out_channels) { out[j] = out[j + 1] = in[i]; } } @@ -408,22 +407,32 @@ template void upmix(T * in, long inframes, T * out, int32_t in_channels, int32_t out_channels) { - XASSERT(out_channels >= in_channels); + XASSERT(out_channels >= in_channels && in_channels > 0); + + /* Either way, if we have 2 or more channels, the first two are L and R. */ /* If we are playing a mono stream over stereo speakers, copy the data over. */ - if (in_channels == 1 && out_channels == 2) { - mono_to_stereo(in, inframes, out); + if (in_channels == 1 && out_channels >= 2) { + mono_to_stereo(in, inframes, out, out_channels); + } else { + /* Copy through. */ + for (int i = 0, o = 0; i < inframes * in_channels; + i += in_channels, o += out_channels) { + for (int j = 0; j < in_channels; ++j) { + out[o + j] = in[i + j]; + } + } + } + + /* Check if more channels. */ + if (out_channels <= 2) { return; } - /* Otherwise, put silence in other channels. */ - long out_index = 0; - for (long i = 0; i < inframes * in_channels; i += in_channels) { - for (int j = 0; j < in_channels; ++j) { - out[out_index + j] = in[i + j]; + + /* Put silence in remaining channels. */ + for (long i = 0, o = 0; i < inframes; ++i, o += out_channels) { + for (int j = 2; j < out_channels; ++j) { + out[o + j] = 0.0; } - for (int j = in_channels; j < out_channels; ++j) { - out[out_index + j] = 0.0; - } - out_index += out_channels; } } @@ -586,7 +595,7 @@ wasapi_stream_render_loop(LPVOID stream) if (SUCCEEDED(hr)) { double playing_frame = stm->mix_params.rate * (double)position / stm->device_frequency; double last_written_frame = stm->clock - stm->base_clock; - latency_set(stm, max(last_written_frame - playing_frame, 0)); + latency_set(stm, std::max(last_written_frame - playing_frame, 0.0)); } if (stm->draining) { diff --git a/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp index 3a80ecfc2e08..d3dc01cd7777 100644 --- a/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp +++ b/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp @@ -1843,6 +1843,10 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { size = 0; } + // Make sure (size + chunk_size) isn't going to overflow. + if (size > (size_t)-1 - chunk_size) { + return ERROR_MALFORMED; + } uint8_t *buffer = new uint8_t[size + chunk_size]; if (size > 0) { @@ -2689,6 +2693,11 @@ status_t MPEG4Source::parseChunk(off64_t *offset) { return ERROR_MALFORMED; } + if (chunk_size >= INT32_MAX - 128) { + // Could cause an overflow later. Abort. + return ERROR_MALFORMED; + } + char chunk[5]; MakeFourCCString(chunk_type, chunk); ALOGV("MPEG4Source chunk %s @ %llx", chunk, *offset); diff --git a/media/webrtc/signaling/src/media-conduit/WebrtcGmpVideoCodec.cpp b/media/webrtc/signaling/src/media-conduit/WebrtcGmpVideoCodec.cpp index 9d7be03c8ca8..0c45da3e4b32 100644 --- a/media/webrtc/signaling/src/media-conduit/WebrtcGmpVideoCodec.cpp +++ b/media/webrtc/signaling/src/media-conduit/WebrtcGmpVideoCodec.cpp @@ -330,7 +330,7 @@ WebrtcGmpVideoEncoder::Encode_g(const webrtc::I420VideoFrame* aInputImage, if (err != GMPNoErr) { return WEBRTC_VIDEO_CODEC_ERROR; } - GMPUnique::Ptr frame(static_cast(ftmp)); + GMPUniquePtr frame(static_cast(ftmp)); err = frame->CreateFrame(aInputImage->allocated_size(webrtc::kYPlane), aInputImage->buffer(webrtc::kYPlane), @@ -721,7 +721,7 @@ WebrtcGmpVideoDecoder::Decode_g(const webrtc::EncodedImage& aInputImage, return WEBRTC_VIDEO_CODEC_ERROR; } - GMPUnique::Ptr frame(static_cast(ftmp)); + GMPUniquePtr frame(static_cast(ftmp)); err = frame->CreateEmptyFrame(aInputImage._length); if (err != GMPNoErr) { return WEBRTC_VIDEO_CODEC_ERROR; diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp index b9e32ab7c88e..a1be60644cad 100644 --- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp +++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp @@ -30,6 +30,7 @@ #include "nsIPrefService.h" #include "nsIPrefBranch.h" #include "nsProxyRelease.h" +#include "nsQueryObject.h" #include "prtime.h" #include "AudioConduit.h" diff --git a/media/webrtc/signaling/test/signaling_unittests.cpp b/media/webrtc/signaling/test/signaling_unittests.cpp index 8c77c5de9df1..92e762fde0d7 100644 --- a/media/webrtc/signaling/test/signaling_unittests.cpp +++ b/media/webrtc/signaling/test/signaling_unittests.cpp @@ -32,6 +32,7 @@ #include "nsIPrefService.h" #include "nsIPrefBranch.h" #include "nsIDNSService.h" +#include "nsQueryObject.h" #include "nsWeakReference.h" #include "nricectx.h" #include "rlogringbuffer.h" diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp index f66250845288..eab6ffa2b48b 100644 --- a/netwerk/protocol/http/HttpChannelParent.cpp +++ b/netwerk/protocol/http/HttpChannelParent.cpp @@ -33,6 +33,7 @@ #include "nsICachingChannel.h" #include "mozilla/LoadInfo.h" #include "nsIHttpHeaderVisitor.h" +#include "nsQueryObject.h" using namespace mozilla::dom; using namespace mozilla::ipc; diff --git a/netwerk/protocol/http/NullHttpTransaction.cpp b/netwerk/protocol/http/NullHttpTransaction.cpp index 38ec1e1851bc..e4bc57989ed3 100644 --- a/netwerk/protocol/http/NullHttpTransaction.cpp +++ b/netwerk/protocol/http/NullHttpTransaction.cpp @@ -13,6 +13,7 @@ #include "nsHttpRequestHead.h" #include "nsIHttpActivityObserver.h" #include "NullHttpChannel.h" +#include "nsQueryObject.h" namespace mozilla { namespace net { diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index 5fd28278dd3b..1bb993b3b802 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -37,6 +37,7 @@ #include "nsError.h" #include "nsPrintfCString.h" #include "nsAlgorithm.h" +#include "nsQueryObject.h" #include "GeckoProfiler.h" #include "nsIConsoleService.h" #include "mozilla/Attributes.h" diff --git a/profile/dirserviceprovider/nsProfileLock.cpp b/profile/dirserviceprovider/nsProfileLock.cpp index 0344f1bd9bfd..510ee29f3f22 100644 --- a/profile/dirserviceprovider/nsProfileLock.cpp +++ b/profile/dirserviceprovider/nsProfileLock.cpp @@ -6,6 +6,7 @@ #include "nsProfileStringTypes.h" #include "nsProfileLock.h" #include "nsCOMPtr.h" +#include "nsQueryObject.h" #if defined(XP_WIN) #include "mozilla/ProfileUnlockerWin.h" diff --git a/storage/src/mozStoragePrivateHelpers.cpp b/storage/src/mozStoragePrivateHelpers.cpp index 682ae42ff9c9..adbb973e98f0 100644 --- a/storage/src/mozStoragePrivateHelpers.cpp +++ b/storage/src/mozStoragePrivateHelpers.cpp @@ -13,6 +13,7 @@ #include "nsError.h" #include "mozilla/Mutex.h" #include "mozilla/CondVar.h" +#include "nsQueryObject.h" #include "nsThreadUtils.h" #include "nsJSUtils.h" diff --git a/testing/marionette/client/marionette/runner/base.py b/testing/marionette/client/marionette/runner/base.py index 55c2ea6fef3e..787858f297c6 100644 --- a/testing/marionette/client/marionette/runner/base.py +++ b/testing/marionette/client/marionette/runner/base.py @@ -762,11 +762,16 @@ setReq.onerror = function() { if self._capabilities['device'] == "desktop": need_external_ip = False + # Gaia sets server_root and that means we shouldn't spin up our own httpd if not self.httpd: - self.logger.info("starting httpd") - self.start_httpd(need_external_ip) - self.marionette.baseurl = self.httpd.get_url() - self.logger.info("running httpd on %s" % self.marionette.baseurl) + if self.server_root is None or os.path.isdir(self.server_root): + self.logger.info("starting httpd") + self.start_httpd(need_external_ip) + self.marionette.baseurl = self.httpd.get_url() + self.logger.info("running httpd on %s" % self.marionette.baseurl) + else: + self.marionette.baseurl = self.server_root + self.logger.info("using remote content from %s" % self.marionette.baseurl) for test in tests: self.add_test(test) diff --git a/testing/marionette/client/setup.py b/testing/marionette/client/setup.py index 324a53d348a4..79883fb71e25 100644 --- a/testing/marionette/client/setup.py +++ b/testing/marionette/client/setup.py @@ -1,6 +1,6 @@ from setuptools import setup, find_packages -version = '0.10' +version = '0.11' # dependencies with open('requirements.txt') as f: diff --git a/testing/marionette/driver.js b/testing/marionette/driver.js index 0067e7fef8ab..00292b526253 100644 --- a/testing/marionette/driver.js +++ b/testing/marionette/driver.js @@ -155,7 +155,8 @@ ListenerProxy.prototype.__noSuchMethod__ = function*(name, args) { let okListener = () => resolve(); let valListener = msg => resolve(msg.json.value); - let errListener = msg => reject(msg.objects.error); + let errListener = msg => reject( + "error" in msg.objects ? msg.objects.error : msg.json); let handleDialog = function(subject, topic) { listeners.remove(); @@ -2061,7 +2062,7 @@ GeckoDriver.prototype.clickElement = function(cmd, resp) { // listen for it and then just send an error back. The person making the // call should be aware something isnt right and handle accordingly this.addFrameCloseListener("click"); - yield this.listener.clickElement(id); + yield this.listener.clickElement({id: id}); break; } }; @@ -2085,7 +2086,7 @@ GeckoDriver.prototype.getElementAttribute = function(cmd, resp) { break; case Context.CONTENT: - resp.value = yield this.listener.getElementAttribute(id, name); + resp.value = yield this.listener.getElementAttribute({id: id, name: name}); break; } }; @@ -2111,7 +2112,7 @@ GeckoDriver.prototype.getElementText = function(cmd, resp) { break; case Context.CONTENT: - resp.value = yield this.listener.getElementText(id); + resp.value = yield this.listener.getElementText({id: id}); break; } }; @@ -2133,7 +2134,7 @@ GeckoDriver.prototype.getElementTagName = function(cmd, resp) { break; case Context.CONTENT: - resp.value = yield this.listener.getElementTagName(id); + resp.value = yield this.listener.getElementTagName({id: id}); break; } }; @@ -2223,7 +2224,7 @@ GeckoDriver.prototype.isElementEnabled = function(cmd, resp) { break; case Context.CONTENT: - resp.value = yield this.listener.isElementEnabled(id); + resp.value = yield this.listener.isElementEnabled({id: id}); break; } }, @@ -2269,7 +2270,7 @@ GeckoDriver.prototype.getElementSize = function(cmd, resp) { break; case Context.CONTENT: - resp.value = yield this.listener.getElementSize(id); + resp.value = yield this.listener.getElementSize({id: id}); break; } }; @@ -2291,7 +2292,7 @@ GeckoDriver.prototype.getElementRect = function(cmd, resp) { break; case Context.CONTENT: - resp.value = yield this.listener.getElementRect(id); + resp.value = yield this.listener.getElementRect({id: id}); break; } }; diff --git a/testing/marionette/elements.js b/testing/marionette/elements.js index 53f13559bba4..884a0f8de1a2 100644 --- a/testing/marionette/elements.js +++ b/testing/marionette/elements.js @@ -1,11 +1,8 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 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/. */ -let {utils: Cu} = Components; - -Cu.import("chrome://marionette/content/error.js"); - /** * The ElementManager manages DOM references and interactions with elements. * According to the WebDriver spec (http://code.google.com/p/selenium/wiki/JsonWireProtocol), the @@ -31,8 +28,8 @@ this.EXPORTED_SYMBOLS = [ const DOCUMENT_POSITION_DISCONNECTED = 1; -const uuidGen = Components.classes["@mozilla.org/uuid-generator;1"] - .getService(Components.interfaces.nsIUUIDGenerator); +let uuidGen = Components.classes["@mozilla.org/uuid-generator;1"] + .getService(Components.interfaces.nsIUUIDGenerator); this.CLASS_NAME = "class name"; this.SELECTOR = "css selector"; @@ -45,6 +42,12 @@ this.XPATH = "xpath"; this.ANON= "anon"; this.ANON_ATTRIBUTE = "anon attribute"; +function ElementException(msg, num, stack) { + this.message = msg; + this.code = num; + this.stack = stack; +} + this.Accessibility = function Accessibility() { // A flag indicating whether the accessibility issue should be logged or cause // an exception. Default: log to stdout. @@ -182,7 +185,7 @@ Accessibility.prototype = { return; } if (this.strict) { - throw new ElementNotAccessibleError(message); + throw new ElementException(message, 56, null); } dump(Date.now() + " Marionette: " + message); } @@ -221,17 +224,19 @@ ElementManager.prototype = { let foundEl = null; try { foundEl = this.seenItems[i].get(); - } catch (e) {} + } + catch(e) {} if (foundEl) { if (XPCNativeWrapper(foundEl) == XPCNativeWrapper(element)) { return i; } - } else { - // cleanup reference to GC'd element + } + else { + //cleanup reference to GC'd element delete this.seenItems[i]; } } - let id = uuidGen.generateUUID().toString(); + var id = uuidGen.generateUUID().toString(); this.seenItems[id] = Components.utils.getWeakReference(element); return id; }, @@ -250,7 +255,7 @@ ElementManager.prototype = { getKnownElement: function EM_getKnownElement(id, win) { let el = this.seenItems[id]; if (!el) { - throw new JavaScriptError("Element has not been seen before. Id given was " + id); + throw new ElementException("Element has not been seen before. Id given was " + id, 17, null); } try { el = el.get(); @@ -265,9 +270,8 @@ ElementManager.prototype = { !(XPCNativeWrapper(el).ownerDocument == wrappedWin.document) || (XPCNativeWrapper(el).compareDocumentPosition(wrappedWin.document.documentElement) & DOCUMENT_POSITION_DISCONNECTED)) { - throw new StaleElementReferenceError( - "The element reference is stale. Either the element " + - "is no longer attached to the DOM or the page has been refreshed."); + throw new ElementException("The element reference is stale. Either the element " + + "is no longer attached to the DOM or the page has been refreshed.", 10, null); } return el; }, @@ -365,9 +369,8 @@ ElementManager.prototype = { args.hasOwnProperty(this.w3cElementKey))) { let elementUniqueIdentifier = args[this.w3cElementKey] ? args[this.w3cElementKey] : args[this.elementKey]; converted = this.getKnownElement(elementUniqueIdentifier, win); - if (converted == null) { - throw new WebDriverError(`Unknown element: ${elementUniqueIdentifier}`); - } + if (converted == null) + throw new ElementException("Unknown element: " + elementUniqueIdentifier, 500, null); } else { converted = {}; @@ -440,7 +443,7 @@ ElementManager.prototype = { let startNode = (values.element != undefined) ? this.getKnownElement(values.element, win) : win.document; if (this.elementStrategies.indexOf(values.using) < 0) { - throw new InvalidSelectorError(`No such strategy: ${values.using}`); + throw new ElementException("No such strategy.", 32, null); } let found = all ? this.findElements(values.using, values.value, win.document, startNode) : this.findElement(values.using, values.value, win.document, startNode); @@ -458,7 +461,7 @@ ElementManager.prototype = { } else if (values.using == ANON_ATTRIBUTE) { message = "Unable to locate anonymous element: " + JSON.stringify(values.value); } - on_error(new NoSuchElementError(message), command_id); + on_error({message: message, code: 7}, command_id); } } else { values.time = startTime; @@ -591,7 +594,7 @@ ElementManager.prototype = { element = rootNode.getAnonymousElementByAttribute(startNode, attr, value[attr]); break; default: - throw new WebDriverError("No such strategy"); + throw new ElementException("No such strategy", 500, null); } return element; }, @@ -658,7 +661,7 @@ ElementManager.prototype = { } break; default: - throw new WebDriverError("No such strategy"); + throw new ElementException("No such strategy", 500, null); } return elements; }, diff --git a/testing/marionette/error.js b/testing/marionette/error.js index 4921af21d44d..9f664fa37260 100644 --- a/testing/marionette/error.js +++ b/testing/marionette/error.js @@ -4,16 +4,14 @@ "use strict"; -const {results: Cr, utils: Cu} = Components; +const {utils: Cu} = Components; const errors = [ - "ElementNotAccessibleError", "ElementNotVisibleError", "FrameSendFailureError", "FrameSendNotInitializedError", "IllegalArgumentError", "InvalidElementStateError", - "InvalidSelectorError", "JavaScriptError", "NoAlertOpenError", "NoSuchElementError", @@ -21,7 +19,6 @@ const errors = [ "NoSuchWindowError", "ScriptTimeoutError", "SessionNotCreatedError", - "StaleElementReferenceError", "TimeoutError", "UnknownCommandError", "UnknownError", @@ -31,26 +28,6 @@ const errors = [ this.EXPORTED_SYMBOLS = ["error"].concat(errors); -// Because XPCOM is a cesspool of undocumented odd behaviour, -// Object.getPrototypeOf(err) causes another exception if err is an XPCOM -// exception, and cannot be used to determine if err is a prototypal Error. -// -// Consequently we need to check for properties in its prototypal chain -// (using in, instead of err.hasOwnProperty because that causes other -// issues). -// -// Since the input is arbitrary it might _not_ be an Error, and can as -// such be an object with a "result" property without it being considered to -// be an exception. The solution is to build a lookup table of XPCOM -// exceptions from Components.results and check if the value of err#results -// is in that table. -const XPCOM_EXCEPTIONS = []; -{ - for (let prop in Cr) { - XPCOM_EXCEPTIONS.push(Cr[prop]); - } -} - this.error = {}; error.toJSON = function(err) { @@ -61,6 +38,11 @@ error.toJSON = function(err) { }; }; +/** + * Gets WebDriver error by its Selenium status code number. + */ +error.byCode = n => lookup.get(n); + /** * Determines if the given status code is successful. */ @@ -83,19 +65,18 @@ let isOldStyleError = function(obj) { * Prefer using this over using instanceof since the Error prototype * isn't unique across browsers, and XPCOM exceptions are special * snowflakes. - * - * @param {*} val - * Any value that should be undergo the test for errorness. - * @return {boolean} - * True if error, false otherwise. */ -error.isError = function(val) { - if (val === null || typeof val != "object") { +error.isError = function(obj) { + if (obj === null || typeof obj != "object") { return false; - } else if ("result" in val && val.result in XPCOM_EXCEPTIONS) { + // XPCOM exception. + // Object.getPrototypeOf(obj).result throws error, + // consequently we must do the check for properties in its + // prototypal chain (using in, instead of obj.hasOwnProperty) here. + } else if ("result" in obj) { return true; } else { - return Object.getPrototypeOf(val) == "Error" || isOldStyleError(val); + return Object.getPrototypeOf(obj) == "Error" || isOldStyleError(obj); } }; @@ -149,14 +130,6 @@ this.WebDriverError = function(msg) { }; WebDriverError.prototype = Object.create(Error.prototype); -this.ElementNotAccessibleError = function(msg) { - WebDriverError.call(this, msg); - this.name = "ElementNotAccessibleError"; - this.status = "element not accessible"; - this.code = 56; -}; -ElementNotAccessibleError.prototype = Object.create(WebDriverError.prototype); - this.ElementNotVisibleError = function(msg) { WebDriverError.call(this, msg); this.name = "ElementNotVisibleError"; @@ -203,14 +176,6 @@ this.InvalidElementStateError = function(msg) { }; InvalidElementStateError.prototype = Object.create(WebDriverError.prototype); -this.InvalidSelectorError = function(msg) { - WebDriverError.call(this, msg); - this.name = "InvalidSelectorError"; - this.status = "invalid selector"; - this.code = 32; -}; -InvalidSelectorError.prototype = Object.create(WebDriverError.prototype); - /** * Creates an error message for a JavaScript error thrown during * executeScript or executeAsyncScript. @@ -305,17 +270,9 @@ this.SessionNotCreatedError = function(msg) { this.status = "session not created"; // should be 33 to match Selenium this.code = 71; -}; +} SessionNotCreatedError.prototype = Object.create(WebDriverError.prototype); -this.StaleElementReferenceError = function(msg) { - WebDriverError.call(this, msg); - this.name = "StaleElementReferenceError"; - this.status = "stale element reference"; - this.code = 10; -}; -StaleElementReferenceError.prototype = Object.create(WebDriverError.prototype); - this.TimeoutError = function(msg) { WebDriverError.call(this, msg); this.name = "TimeoutError"; @@ -347,3 +304,24 @@ this.UnsupportedOperationError = function(msg) { this.code = 405; }; UnsupportedOperationError.prototype = Object.create(WebDriverError.prototype); + +const errorObjs = [ + this.ElementNotVisibleError, + this.FrameSendFailureError, + this.FrameSendNotInitializedError, + this.IllegalArgumentError, + this.InvalidElementStateError, + this.JavaScriptError, + this.NoAlertOpenError, + this.NoSuchElementError, + this.NoSuchFrameError, + this.NoSuchWindowError, + this.ScriptTimeoutError, + this.SessionNotCreatedError, + this.TimeoutError, + this.UnknownCommandError, + this.UnknownError, + this.UnsupportedOperationError, + this.WebDriverError, +]; +const lookup = new Map(errorObjs.map(err => [new err().code, err])); diff --git a/testing/marionette/listener.js b/testing/marionette/listener.js index 53d3ae5a34c3..33822d5cd4db 100644 --- a/testing/marionette/listener.js +++ b/testing/marionette/listener.js @@ -15,7 +15,6 @@ loader.loadSubScript("chrome://marionette/content/simpletest.js"); loader.loadSubScript("chrome://marionette/content/common.js"); loader.loadSubScript("chrome://marionette/content/actions.js"); Cu.import("chrome://marionette/content/elements.js"); -Cu.import("chrome://marionette/content/error.js"); Cu.import("resource://gre/modules/FileUtils.jsm"); Cu.import("resource://gre/modules/NetUtil.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); @@ -94,7 +93,7 @@ let modalHandler = function() { * If the actor returns an ID, we start the listeners. Otherwise, nothing happens. */ function registerSelf() { - let msg = {value: winUtil.outerWindowID}; + let msg = {value: winUtil.outerWindowID} // register will have the ID and a boolean describing if this is the main process or not let register = sendSyncMessage("Marionette:register", msg); @@ -147,28 +146,6 @@ function emitTouchEventForIFrame(message) { message.force, 90); } -function dispatch(fn) { - return function(msg) { - let id = msg.json.command_id; - try { - let rv; - if (typeof msg.json == "undefined" || msg.json instanceof Array) { - rv = fn.apply(null, msg.json); - } else { - rv = fn(msg.json); - } - - if (typeof rv == "undefined") { - sendOk(id); - } else { - sendResponse({value: rv}, id); - } - } catch (e) { - sendError(e, id); - } - }; -} - /** * Add a message listener that's tied to our listenerId. */ @@ -183,15 +160,6 @@ function removeMessageListenerId(messageName, handler) { removeMessageListener(messageName + listenerId, handler); } -let getElementSizeFn = dispatch(getElementSize); -let getActiveElementFn = dispatch(getActiveElement); -let clickElementFn = dispatch(clickElement); -let getElementAttributeFn = dispatch(getElementAttribute); -let getElementTextFn = dispatch(getElementText); -let getElementTagNameFn = dispatch(getElementTagName); -let getElementRectFn = dispatch(getElementRect); -let isElementEnabledFn = dispatch(isElementEnabled); - /** * Start all message listeners */ @@ -214,17 +182,17 @@ function startListeners() { addMessageListenerId("Marionette:refresh", refresh); addMessageListenerId("Marionette:findElementContent", findElementContent); addMessageListenerId("Marionette:findElementsContent", findElementsContent); - addMessageListenerId("Marionette:getActiveElement", getActiveElementFn); - addMessageListenerId("Marionette:clickElement", clickElementFn); - addMessageListenerId("Marionette:getElementAttribute", getElementAttributeFn); - addMessageListenerId("Marionette:getElementText", getElementTextFn); - addMessageListenerId("Marionette:getElementTagName", getElementTagNameFn); + addMessageListenerId("Marionette:getActiveElement", getActiveElement); + addMessageListenerId("Marionette:clickElement", clickElement); + addMessageListenerId("Marionette:getElementAttribute", getElementAttribute); + addMessageListenerId("Marionette:getElementText", getElementText); + addMessageListenerId("Marionette:getElementTagName", getElementTagName); addMessageListenerId("Marionette:isElementDisplayed", isElementDisplayed); addMessageListenerId("Marionette:getElementValueOfCssProperty", getElementValueOfCssProperty); addMessageListenerId("Marionette:submitElement", submitElement); - addMessageListenerId("Marionette:getElementSize", getElementSizeFn); // deprecated - addMessageListenerId("Marionette:getElementRect", getElementRectFn); - addMessageListenerId("Marionette:isElementEnabled", isElementEnabledFn); + addMessageListenerId("Marionette:getElementSize", getElementSize); + addMessageListenerId("Marionette:getElementRect", getElementRect); + addMessageListenerId("Marionette:isElementEnabled", isElementEnabled); addMessageListenerId("Marionette:isElementSelected", isElementSelected); addMessageListenerId("Marionette:sendKeysToElement", sendKeysToElement); addMessageListenerId("Marionette:getElementLocation", getElementLocation); //deprecated @@ -319,17 +287,17 @@ function deleteSession(msg) { removeMessageListenerId("Marionette:refresh", refresh); removeMessageListenerId("Marionette:findElementContent", findElementContent); removeMessageListenerId("Marionette:findElementsContent", findElementsContent); - removeMessageListenerId("Marionette:getActiveElement", getActiveElementFn); - removeMessageListenerId("Marionette:clickElement", clickElementFn); - removeMessageListenerId("Marionette:getElementAttribute", getElementAttributeFn); - removeMessageListenerId("Marionette:getElementText", getElementTextFn); - removeMessageListenerId("Marionette:getElementTagName", getElementTagNameFn); + removeMessageListenerId("Marionette:getActiveElement", getActiveElement); + removeMessageListenerId("Marionette:clickElement", clickElement); + removeMessageListenerId("Marionette:getElementAttribute", getElementAttribute); + removeMessageListenerId("Marionette:getElementText", getElementText); + removeMessageListenerId("Marionette:getElementTagName", getElementTagName); removeMessageListenerId("Marionette:isElementDisplayed", isElementDisplayed); removeMessageListenerId("Marionette:getElementValueOfCssProperty", getElementValueOfCssProperty); removeMessageListenerId("Marionette:submitElement", submitElement); - removeMessageListenerId("Marionette:getElementSize", getElementSizeFn); // deprecated - removeMessageListenerId("Marionette:getElementRect", getElementRectFn); - removeMessageListenerId("Marionette:isElementEnabled", isElementEnabledFn); + removeMessageListenerId("Marionette:getElementSize", getElementSize); //deprecated + removeMessageListenerId("Marionette:getElementRect", getElementRect); + removeMessageListenerId("Marionette:isElementEnabled", isElementEnabled); removeMessageListenerId("Marionette:isElementSelected", isElementSelected); removeMessageListenerId("Marionette:sendKeysToElement", sendKeysToElement); removeMessageListenerId("Marionette:getElementLocation", getElementLocation); @@ -363,42 +331,40 @@ function deleteSession(msg) { /** * Generic method to send a message to the server */ -function sendToServer(name, data, objs, id) { - if (!data) { - data = {} +function sendToServer(msg, value, command_id) { + if (command_id) { + value.command_id = command_id; } - if (id) { - data.command_id = id; - } - sendAsyncMessage(name, data, objs); + sendAsyncMessage(msg, value); } /** * Send response back to server */ function sendResponse(value, command_id) { - sendToServer("Marionette:done", value, null, command_id); + sendToServer("Marionette:done", value, command_id); } /** * Send ack back to server */ function sendOk(command_id) { - sendToServer("Marionette:ok", null, null, command_id); + sendToServer("Marionette:ok", {}, command_id); } /** * Send log message to server */ function sendLog(msg) { - sendToServer("Marionette:log", {message: msg}); + sendToServer("Marionette:log", { message: msg }); } /** * Send error message to server */ -function sendError(err, cmdId) { - sendToServer("Marionette:error", null, {error: err}, cmdId); +function sendError(msg, code, stack, cmdId) { + let payload = {message: msg, code: code, stack: stack}; + sendToServer("Marionette:error", payload, cmdId); } /** @@ -492,8 +458,8 @@ function createExecuteContentSandbox(aWindow, timeout) { }); } - sandbox.asyncComplete = function(obj, id) { - if (id == asyncTestCommandId) { + sandbox.asyncComplete = function sandbox_asyncComplete(value, status, stack, commandId) { + if (commandId == asyncTestCommandId) { curFrame.removeEventListener("unload", onunload, false); curFrame.clearTimeout(asyncTestTimeoutId); @@ -501,19 +467,24 @@ function createExecuteContentSandbox(aWindow, timeout) { curFrame.clearTimeout(inactivityTimeoutId); } + sendSyncMessage("Marionette:shareData", - {log: elementManager.wrapValue(marionetteLogObj.getLogs())}); + {log: elementManager.wrapValue(marionetteLogObj.getLogs())}); marionetteLogObj.clearLogs(); - if (error.isError(obj)) { - sendError(obj, id); - } else { + if (status == 0){ if (Object.keys(_emu_cbs).length) { _emu_cbs = {}; - sendError(new WebDriverError("Emulator callback still pending when finish() called"), id); - } else { - sendResponse({value: elementManager.wrapValue(obj)}, id); + sendError("Emulator callback still pending when finish() called", + 500, null, commandId); } + else { + sendResponse({value: elementManager.wrapValue(value), status: status}, + commandId); + } + } + else { + sendError(value, status, stack, commandId); } asyncTestRunning = false; @@ -524,32 +495,33 @@ function createExecuteContentSandbox(aWindow, timeout) { }; sandbox.finish = function sandbox_finish() { if (asyncTestRunning) { - sandbox.asyncComplete(marionette.generate_results(), sandbox.asyncTestCommandId); + sandbox.asyncComplete(marionette.generate_results(), 0, null, sandbox.asyncTestCommandId); } else { return marionette.generate_results(); } }; - sandbox.marionetteScriptFinished = val => - sandbox.asyncComplete(val, sandbox.asyncTestCommandId); + sandbox.marionetteScriptFinished = function sandbox_marionetteScriptFinished(value) { + return sandbox.asyncComplete(value, 0, null, sandbox.asyncTestCommandId); + }; return sandbox; } /** * Execute the given script either as a function body (executeScript) - * or directly (for mochitest like JS Marionette tests). + * or directly (for 'mochitest' like JS Marionette tests) */ function executeScript(msg, directInject) { // Set up inactivity timeout. if (msg.json.inactivityTimeout) { let setTimer = function() { - inactivityTimeoutId = curFrame.setTimeout(function() { - sendError(new ScriptTimeoutError("timed out due to inactivity"), asyncTestCommandId); + inactivityTimeoutId = curFrame.setTimeout(function() { + sendError('timed out due to inactivity', 28, null, asyncTestCommandId); }, msg.json.inactivityTimeout); }; setTimer(); - heartbeatCallback = function() { + heartbeatCallback = function resetInactivityTimeout() { curFrame.clearTimeout(inactivityTimeoutId); setTimer(); }; @@ -562,10 +534,11 @@ function executeScript(msg, directInject) { sandbox = createExecuteContentSandbox(curFrame, msg.json.timeout); if (!sandbox) { - sendError(new WebDriverError("Could not create sandbox!"), asyncTestCommandId); + sendError("Could not create sandbox!", 500, null, asyncTestCommandId); return; } - } else { + } + else { sandbox.asyncTestCommandId = asyncTestCommandId; } @@ -585,7 +558,7 @@ function executeScript(msg, directInject) { marionetteLogObj.clearLogs(); if (res == undefined || res.passed == undefined) { - sendError(new JavaScriptError("Marionette.finish() not called"), asyncTestCommandId); + sendError("Marionette.finish() not called", 17, null, asyncTestCommandId); } else { sendResponse({value: elementManager.wrapValue(res)}, asyncTestCommandId); @@ -595,8 +568,9 @@ function executeScript(msg, directInject) { try { sandbox.__marionetteParams = Cu.cloneInto(elementManager.convertWrappedArguments( msg.json.args, curFrame), sandbox, { wrapReflectors: true }); - } catch (e) { - sendError(e, asyncTestCommandId); + } + catch(e) { + sendError(e.message, e.code, e.stack, asyncTestCommandId); return; } @@ -616,14 +590,15 @@ function executeScript(msg, directInject) { marionetteLogObj.clearLogs(); sendResponse({value: elementManager.wrapValue(res)}, asyncTestCommandId); } - } catch (e) { - let err = new JavaScriptError( - e, - "execute_script", - msg.json.filename, - msg.json.line, - script); - sendError(err, asyncTestCommandId); + } + catch (e) { + // 17 = JavascriptException + let error = createStackMessage(e, + "execute_script", + msg.json.filename, + msg.json.line, + script); + sendError(error[0], 17, error[1], asyncTestCommandId); } } @@ -667,12 +642,12 @@ function executeWithCallback(msg, useFinish) { if (msg.json.inactivityTimeout) { let setTimer = function() { inactivityTimeoutId = curFrame.setTimeout(function() { - sandbox.asyncComplete(new ScriptTimeout("timed out due to inactivity"), asyncTestCommandId); + sandbox.asyncComplete('timed out due to inactivity', 28, null, asyncTestCommandId); }, msg.json.inactivityTimeout); }; setTimer(); - heartbeatCallback = function() { + heartbeatCallback = function resetInactivityTimeout() { curFrame.clearTimeout(inactivityTimeoutId); setTimer(); }; @@ -682,7 +657,7 @@ function executeWithCallback(msg, useFinish) { asyncTestCommandId = msg.json.command_id; onunload = function() { - sendError(new JavaScriptError("unload was called"), asyncTestCommandId); + sendError("unload was called", 17, null, asyncTestCommandId); }; curFrame.addEventListener("unload", onunload, false); @@ -690,7 +665,7 @@ function executeWithCallback(msg, useFinish) { sandbox = createExecuteContentSandbox(curFrame, msg.json.timeout); if (!sandbox) { - sendError(new JavaScriptError("Could not create sandbox!"), asyncTestCommandId); + sendError("Could not create sandbox!", 17, null, asyncTestCommandId); return; } } @@ -705,19 +680,19 @@ function executeWithCallback(msg, useFinish) { // http://code.google.com/p/selenium/source/browse/trunk/javascript/firefox-driver/js/evaluate.js. // We'll stay compatible with the Selenium code. asyncTestTimeoutId = curFrame.setTimeout(function() { - sandbox.asyncComplete(new ScriptTimeoutError("timed out"), asyncTestCommandId); + sandbox.asyncComplete('timed out', 28, null, asyncTestCommandId); }, msg.json.timeout); originalOnError = curFrame.onerror; - curFrame.onerror = function errHandler(msg, url, line) { - sandbox.asyncComplete(new JavaScriptError(msg + "@" + url + ", line " + line), asyncTestCommandId); + curFrame.onerror = function errHandler(errMsg, url, line) { + sandbox.asyncComplete(errMsg, 17, "@" + url + ", line " + line, asyncTestCommandId); curFrame.onerror = originalOnError; }; let scriptSrc; if (useFinish) { if (msg.json.timeout == null || msg.json.timeout == 0) { - sendError(new TimeoutError("Please set a timeout"), asyncTestCommandId); + sendError("Please set a timeout", 21, null, asyncTestCommandId); } scriptSrc = script; } @@ -725,8 +700,9 @@ function executeWithCallback(msg, useFinish) { try { sandbox.__marionetteParams = Cu.cloneInto(elementManager.convertWrappedArguments( msg.json.args, curFrame), sandbox, { wrapReflectors: true }); - } catch (e) { - sendError(e, asyncTestCommandId); + } + catch(e) { + sendError(e.message, e.code, e.stack, asyncTestCommandId); return; } @@ -747,13 +723,13 @@ function executeWithCallback(msg, useFinish) { } Cu.evalInSandbox(scriptSrc, sandbox, "1.8", "dummy file", 0); } catch (e) { - let err = new JavaScriptError( - e, - "execute_async_script", - msg.json.filename, - msg.json.line, - scriptSrc); - sandbox.asyncComplete(err, asyncTestCommandId); + // 17 = JavascriptException + let error = createStackMessage(e, + "execute_async_script", + msg.json.filename, + msg.json.line, + scriptSrc); + sandbox.asyncComplete(error[0], 17, error[1], asyncTestCommandId); } } @@ -880,7 +856,7 @@ function singleTap(msg) { let visible = checkVisible(el, msg.json.corx, msg.json.cory); checkVisibleAccessibility(acc, visible); if (!visible) { - sendError(new ElementNotVisibleError("Element is not currently visible and may not be manipulated"), command_id); + sendError("Element is not currently visible and may not be manipulated", 11, null, command_id); return; } checkActionableAccessibility(acc); @@ -895,9 +871,10 @@ function singleTap(msg) { emitTouchEvent('touchend', touch); } actions.mouseTap(el.ownerDocument, c.x, c.y); - sendOk(command_id); - } catch (e) { - sendError(e, command_id); + sendOk(msg.json.command_id); + } + catch (e) { + sendError(e.message, e.code, e.stack, msg.json.command_id); } } @@ -982,8 +959,12 @@ function actionChain(msg) { let touchId = msg.json.nextId; let callbacks = {}; - callbacks.onSuccess = value => sendResponse(value, command_id); - callbacks.onError = err => sendError(err, command_id); + callbacks.onSuccess = (value) => { + sendResponse(value, command_id); + }; + callbacks.onError = (message, code, trace) => { + sendError(message, code, trace, msg.json.command_id); + }; let touchProvider = {}; touchProvider.createATouch = createATouch; @@ -998,7 +979,7 @@ function actionChain(msg) { callbacks, touchProvider); } catch (e) { - sendError(e, command_id); + sendError(e.message, e.code, e.stack, command_id); } } @@ -1163,8 +1144,9 @@ function multiAction(msg) { // pendingTouches keeps track of current touches that's on the screen let pendingTouches = []; setDispatch(concurrentEvent, pendingTouches, command_id); - } catch (e) { - sendError(e, command_id); + } + catch (e) { + sendError(e.message, e.code, e.stack, msg.json.command_id); } } @@ -1196,7 +1178,7 @@ function pollForReadyState(msg, start, callback) { !curFrame.document.baseURI.startsWith(url)) { // We have reached an error url without requesting it. callback(); - sendError(new UnknownError("Error loading page"), command_id); + sendError("Error loading page", 13, null, command_id); } else if (curFrame.document.readyState == "interactive" && curFrame.document.baseURI.startsWith("about:")) { callback(); @@ -1204,9 +1186,11 @@ function pollForReadyState(msg, start, callback) { } else { navTimer.initWithCallback(checkLoad, 100, Ci.nsITimer.TYPE_ONE_SHOT); } - } else { + } + else { callback(); - sendError(new TimeoutError("Error loading page, timed out (checkLoad)"), command_id); + sendError("Error loading page, timed out (checkLoad)", 21, null, + command_id); } } checkLoad(); @@ -1236,7 +1220,8 @@ function get(msg) { function timerFunc() { removeEventListener("DOMContentLoaded", onDOMContentLoaded, false); - sendError(new TimeoutError("Error loading page, timed out (onDOMContentLoaded)"), msg.json.command_id); + sendError("Error loading page, timed out (onDOMContentLoaded)", 21, + null, msg.json.command_id); } if (msg.json.pageTimeout != null) { navTimer.initWithCallback(timerFunc, msg.json.pageTimeout, Ci.nsITimer.TYPE_ONE_SHOT); @@ -1321,12 +1306,13 @@ function refresh(msg) { function findElementContent(msg) { let command_id = msg.json.command_id; try { - let onSuccess = (el, id) => sendResponse({value: el}, id); - let onError = (err, id) => sendError(err, id); + let on_success = function(el, cmd_id) { sendResponse({value: el}, cmd_id) }; + let on_error = function(e, cmd_id) { sendError(e.message, e.code, null, cmd_id); }; elementManager.find(curFrame, msg.json, msg.json.searchTimeout, - false /* all */, onSuccess, onError, command_id); - } catch (e) { - sendError(e, command_id); + false /* all */, on_success, on_error, command_id); + } + catch (e) { + sendError(e.message, e.code, e.stack, command_id); } } @@ -1336,90 +1322,97 @@ function findElementContent(msg) { function findElementsContent(msg) { let command_id = msg.json.command_id; try { - let onSuccess = (els, id) => sendResponse({value: els}, id); - let onError = (err, id) => sendError(err, id); + let on_success = function(els, cmd_id) { sendResponse({value: els}, cmd_id); }; + let on_error = function(e, cmd_id) { sendError(e.message, e.code, null, cmd_id); }; elementManager.find(curFrame, msg.json, msg.json.searchTimeout, - true /* all */, onSuccess, onError, command_id); - } catch (e) { - sendError(e, command_id); + true /* all */, on_success, on_error, command_id); + } + catch (e) { + sendError(e.message, e.code, e.stack, command_id); } } /** - * Find and return the active element on the page. - * - * @return {WebElement} - * Reference to web element. + * Find and return the active element on the page */ -function getActiveElement() { - let el = curFrame.document.activeElement; - return elementManager.addToKnownElements(el); +function getActiveElement(msg) { + let command_id = msg.json.command_id; + var element = curFrame.document.activeElement; + var id = elementManager.addToKnownElements(element); + sendResponse({value: id}, command_id); } /** - * Send click event to element. - * - * @param {WebElement} id - * Reference to the web element to click. + * Send click event to element */ -function clickElement(id) { - let el = elementManager.getKnownElement(id, curFrame); - let acc = accessibility.getAccessibleObject(el, true); - let visible = checkVisible(el); - checkVisibleAccessibility(acc, visible); - if (!visible) { - throw new ElementNotVisibleError("Element is not visible"); +function clickElement(msg) { + let command_id = msg.json.command_id; + let el; + try { + el = elementManager.getKnownElement(msg.json.id, curFrame); + let acc = accessibility.getAccessibleObject(el, true); + let visible = checkVisible(el); + checkVisibleAccessibility(acc, visible); + if (visible) { + checkActionableAccessibility(acc); + if (utils.isElementEnabled(el)) { + utils.synthesizeMouseAtCenter(el, {}, el.ownerDocument.defaultView) + } + else { + sendError("Element is not Enabled", 12, null, command_id) + } + } + else { + sendError("Element is not visible", 11, null, command_id) + } + sendOk(command_id); } - checkActionableAccessibility(acc); - if (utils.isElementEnabled(el)) { - utils.synthesizeMouseAtCenter(el, {}, el.ownerDocument.defaultView); - } else { - throw new InvalidElementStateError("Element is not Enabled"); + catch (e) { + sendError(e.message, e.code, e.stack, command_id); } } /** - * Get a given attribute of an element. - * - * @param {WebElement} id - * Reference to the web element to get the attribute of. - * @param {string} name - * Name of the attribute. - * - * @return {string} - * The value of the attribute. + * Get a given attribute of an element */ -function getElementAttribute(id, name) { - let el = elementManager.getKnownElement(id, curFrame); - return utils.getElementAttribute(el, name); +function getElementAttribute(msg) { + let command_id = msg.json.command_id; + try { + let el = elementManager.getKnownElement(msg.json.id, curFrame); + sendResponse({value: utils.getElementAttribute(el, msg.json.name)}, + command_id); + } + catch (e) { + sendError(e.message, e.code, e.stack, command_id); + } } /** * Get the text of this element. This includes text from child elements. - * - * @param {WebElement} id - * Reference to web element. - * - * @return {string} - * Text of element. */ -function getElementText(id) { - let el = elementManager.getKnownElement(id, curFrame); - return utils.getElementText(el); +function getElementText(msg) { + let command_id = msg.json.command_id; + try { + let el = elementManager.getKnownElement(msg.json.id, curFrame); + sendResponse({value: utils.getElementText(el)}, command_id); + } + catch (e) { + sendError(e.message, e.code, e.stack, command_id); + } } /** * Get the tag name of an element. - * - * @param {WebElement} id - * Reference to web element. - * - * @return {string} - * Tag name of element. */ -function getElementTagName(id) { - let el = elementManager.getKnownElement(id, curFrame); - return el.tagName.toLowerCase(); +function getElementTagName(msg) { + let command_id = msg.json.command_id; + try { + let el = elementManager.getKnownElement(msg.json.id, curFrame); + sendResponse({value: el.tagName.toLowerCase()}, command_id); + } + catch (e) { + sendError(e.message, e.code, e.stack, command_id); + } } /** @@ -1432,8 +1425,9 @@ function isElementDisplayed(msg) { let displayed = utils.isElementDisplayed(el); checkVisibleAccessibility(accessibility.getAccessibleObject(el), displayed); sendResponse({value: displayed}, command_id); - } catch (e) { - sendError(e, command_id); + } + catch (e) { + sendError(e.message, e.code, e.stack, command_id); } } @@ -1452,8 +1446,9 @@ function getElementValueOfCssProperty(msg){ let el = elementManager.getKnownElement(msg.json.id, curFrame); sendResponse({value: curFrame.document.defaultView.getComputedStyle(el, null).getPropertyValue(propertyName)}, command_id); - } catch (e) { - sendError(e, command_id); + } + catch (e) { + sendError(e.message, e.code, e.stack, command_id); } } @@ -1472,63 +1467,67 @@ function submitElement (msg) { if (el.tagName && el.tagName.toLowerCase() == 'form') { el.submit(); sendOk(command_id); - } else { - sendError(new NoSuchElementError("Element is not a form element or in a form"), command_id); } - } catch (e) { - sendError(e, command_id); + else { + sendError("Element is not a form element or in a form", 7, null, command_id); + } + + } + catch (e) { + sendError(e.message, e.code, e.stack, command_id); } } /** - * Get the size of the element. - * - * @param {WebElement} id - * Web element reference. - * - * @return {Object.} - * The width/height dimensions of th element. + * Get the size of the element and return it */ -function getElementSize(id) { - let el = elementManager.getKnownElement(id, curFrame); - let clientRect = el.getBoundingClientRect(); - return {width: clientRect.width, height: clientRect.height}; +function getElementSize(msg){ + let command_id = msg.json.command_id; + try { + let el = elementManager.getKnownElement(msg.json.id, curFrame); + let clientRect = el.getBoundingClientRect(); + sendResponse({value: {width: clientRect.width, height: clientRect.height}}, + command_id); + } + catch (e) { + sendError(e.message, e.code, e.stack, command_id); + } } /** - * Get the size of the element. - * - * @param {WebElement} id - * Reference to web element. - * - * @return {Object.} - * The x, y, width, and height properties of the element. + * Get the size of the element and return it */ -function getElementRect(id) { - let el = elementManager.getKnownElement(id, curFrame); - let clientRect = el.getBoundingClientRect(); - return { - x: clientRect.x + curFrame.pageXOffset, - y: clientRect.y + curFrame.pageYOffset, - width: clientRect.width, - height: clientRect.height - }; +function getElementRect(msg){ + let command_id = msg.json.command_id; + try { + let el = elementManager.getKnownElement(msg.json.id, curFrame); + let clientRect = el.getBoundingClientRect(); + sendResponse({value: {x: clientRect.x + curFrame.pageXOffset, + y: clientRect.y + curFrame.pageYOffset, + width: clientRect.width, + height: clientRect.height}}, + command_id); + } + catch (e) { + sendError(e.message, e.code, e.stack, command_id); + } } /** - * Check if element is enabled. - * - * @param {WebElement} id - * Reference to web element. - * - * @return {boolean} - * True if enabled, false otherwise. + * Check if element is enabled */ -function isElementEnabled(id) { - let el = elementManager.getKnownElement(id, curFrame); - let enabled = utils.isElementEnabled(el); - checkEnabledStateAccessibility(accessibility.getAccessibleObject(el), enabled); - return enabled; +function isElementEnabled(msg) { + let command_id = msg.json.command_id; + try { + let el = elementManager.getKnownElement(msg.json.id, curFrame); + let enabled = utils.isElementEnabled(el); + checkEnabledStateAccessibility(accessibility.getAccessibleObject(el), + enabled); + sendResponse({value: enabled}, command_id); + } + catch (e) { + sendError(e.message, e.code, e.stack, command_id); + } } /** @@ -1539,8 +1538,9 @@ function isElementSelected(msg) { try { let el = elementManager.getKnownElement(msg.json.id, curFrame); sendResponse({value: utils.isElementSelected(el)}, command_id); - } catch (e) { - sendError(e, command_id); + } + catch (e) { + sendError(e.message, e.code, e.stack, command_id); } } @@ -1567,7 +1567,7 @@ function sendKeysToElement(msg) { file = new File(p); } catch (e) { let err = new IllegalArgumentError(`File not found: ${val}`); - sendError(err, command_id); + sendError(err.message, err.code, err.stack, command_id); return; } fs.push(file); @@ -1598,8 +1598,9 @@ function getElementLocation(msg) { location.y = rect.top; sendResponse({value: location}, command_id); - } catch (e) { - sendError(e, command_id); + } + catch (e) { + sendError(e.message, e.code, e.stack, command_id); } } @@ -1617,7 +1618,7 @@ function clearElement(msg) { } sendOk(command_id); } catch (e) { - sendError(e, command_id); + sendError(e.message, e.code, e.stack, command_id); } } @@ -1632,9 +1633,9 @@ function switchToFrame(msg) { if (curFrame.document.readyState == "complete") { sendOk(command_id); return; - } else if (curFrame.document.readyState == "interactive" && - errorRegex.exec(curFrame.document.baseURI)) { - sendError(new UnknownError("Error loading page"), command_id); + } + else if (curFrame.document.readyState == "interactive" && errorRegex.exec(curFrame.document.baseURI)) { + sendError("Error loading page", 13, null, command_id); return; } checkTimer.initWithCallback(checkLoad, 100, Ci.nsITimer.TYPE_ONE_SHOT); @@ -1674,8 +1675,9 @@ function switchToFrame(msg) { let wantedFrame; try { wantedFrame = elementManager.getKnownElement(msg.json.element, curFrame); //Frame Element - } catch (e) { - sendError(e, command_id); + } + catch(e) { + sendError(e.message, e.code, e.stack, command_id); } if (frames.length > 0) { @@ -1733,9 +1735,8 @@ function switchToFrame(msg) { } } } - if (foundFrame === null) { - sendError(new NoSuchFrameError("Unable to locate frame: " + (msg.json.id || msg.json.element)), command_id); + sendError("Unable to locate frame: " + (msg.json.id || msg.json.element), 8, null, command_id); return true; } @@ -1776,11 +1777,12 @@ function addCookie(msg) { if (!cookie.domain) { var location = curFrame.document.location; cookie.domain = location.hostname; - } else { + } + else { var currLocation = curFrame.location; var currDomain = currLocation.host; if (currDomain.indexOf(cookie.domain) == -1) { - sendError(new InvalidCookieDomainError("You may only set cookies for the current domain"), msg.json.command_id); + sendError("You may only set cookies for the current domain", 24, null, msg.json.command_id); } } @@ -1793,12 +1795,12 @@ function addCookie(msg) { var document = curFrame.document; if (!document || !document.contentType.match(/html/i)) { - sendError(new UnableToSetCookie("You may only set cookies on html documents"), msg.json.command_id); + sendError('You may only set cookies on html documents', 25, null, msg.json.command_id); } let added = sendSyncMessage("Marionette:addCookie", {value: cookie}); if (added[0] !== true) { - sendError(new UnknownError("Error setting cookie"), msg.json.command_id); + sendError("Error setting cookie", 13, null, msg.json.command_id); return; } sendOk(msg.json.command_id); @@ -1839,7 +1841,7 @@ function deleteCookie(msg) { if (cookie.name == toDelete) { let deleted = sendSyncMessage("Marionette:deleteCookie", {value: cookie}); if (deleted[0] !== true) { - sendError(new UnknownError("Could not delete cookie: " + msg.json.name), msg.json.command_id); + sendError("Could not delete cookie: " + msg.json.name, 13, null, msg.json.command_id); return; } } @@ -1856,7 +1858,7 @@ function deleteAllCookies(msg) { for (let cookie of cookies) { let deleted = sendSyncMessage("Marionette:deleteCookie", {value: cookie}); if (!deleted[0]) { - sendError(new UnknownError("Could not delete cookie: " + JSON.stringify(cookie)), msg.json.command_id); + sendError("Could not delete cookie: " + JSON.stringify(cookie), 13, null, msg.json.command_id); return; } } @@ -1910,8 +1912,9 @@ function emulatorCmdResult(msg) { } try { cb(message.result); - } catch (e) { - sendError(e, -1); + } + catch(e) { + sendError(e.message, e.code, e.stack, -1); return; } } diff --git a/testing/marionette/sendkeys.js b/testing/marionette/sendkeys.js index eb2b8e050f1e..096330afc0aa 100644 --- a/testing/marionette/sendkeys.js +++ b/testing/marionette/sendkeys.js @@ -17,11 +17,8 @@ */ let {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("chrome://marionette/content/error.js"); - let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"] - .getService(Ci.mozIJSSubScriptLoader); + .getService(Ci.mozIJSSubScriptLoader); let utils = {}; loader.loadSubScript("chrome://marionette/content/EventUtils.js", utils); @@ -141,7 +138,8 @@ function sendKeysToElement (document, element, keysToSend, successCallback, erro sendSingleKey(c, modifiers, document); } successCallback(command_id); - } else { - errorCallback(new ElementNotVisibleError("Element is not visible"), command_id); + } + else { + errorCallback("Element is not visible", 11, null, command_id); } }; diff --git a/testing/web-platform/harness/requirements_firefox.txt b/testing/web-platform/harness/requirements_firefox.txt index d3562bdc5caf..379e522acc45 100644 --- a/testing/web-platform/harness/requirements_firefox.txt +++ b/testing/web-platform/harness/requirements_firefox.txt @@ -1,4 +1,5 @@ -marionette_client >= 0.7.10 +marionette_driver >= 0.4 mozprofile >= 0.21 mozprocess >= 0.19 mozcrash >= 0.13 +mozrunner >= 6.7 diff --git a/testing/web-platform/harness/test/test.py b/testing/web-platform/harness/test/test.py index bca2c106132a..234cb671353e 100644 --- a/testing/web-platform/harness/test/test.py +++ b/testing/web-platform/harness/test/test.py @@ -139,7 +139,7 @@ def get_parser(): help="Specific product to include in test run") parser.add_argument("--pdb", action="store_true", help="Invoke pdb on uncaught exception") - parser.add_argument("test", nargs="*", type=wptcommandline.slash_prefixed, + parser.add_argument("test", nargs="*", help="Specific tests to include in test run") return parser diff --git a/testing/web-platform/harness/wptrunner/executors/executormarionette.py b/testing/web-platform/harness/wptrunner/executors/executormarionette.py index c48b5e623c57..aadb51c2776b 100644 --- a/testing/web-platform/harness/wptrunner/executors/executormarionette.py +++ b/testing/web-platform/harness/wptrunner/executors/executormarionette.py @@ -131,7 +131,7 @@ class MarionetteProtocol(Protocol): self.marionette.execute_async_script(""); except errors.ScriptTimeoutException: pass - except (socket.timeout, errors.InvalidResponseException, IOError): + except (socket.timeout, IOError): break except Exception as e: self.logger.error(traceback.format_exc(e)) @@ -227,7 +227,7 @@ class MarionetteRun(object): # make that possible. It also seems to time out immediately if the # timeout is set too high. This works at least. self.marionette.set_script_timeout(2**31 - 1) - except (IOError, errors.InvalidResponseException): + except IOError: self.logger.error("Lost marionette connection before starting test") return Stop @@ -253,7 +253,7 @@ class MarionetteRun(object): except errors.ScriptTimeoutException: self.logger.debug("Got a marionette timeout") self.result = False, ("EXTERNAL-TIMEOUT", None) - except (socket.timeout, errors.InvalidResponseException, IOError): + except (socket.timeout, IOError): # This can happen on a crash # Also, should check after the test if the firefox process is still running # and otherwise ignore any other result and set it to crash diff --git a/toolkit/components/places/nsNavHistoryResult.cpp b/toolkit/components/places/nsNavHistoryResult.cpp index 28ebcc5b250d..fb273b32f735 100644 --- a/toolkit/components/places/nsNavHistoryResult.cpp +++ b/toolkit/components/places/nsNavHistoryResult.cpp @@ -18,6 +18,7 @@ #include "nsUnicharUtils.h" #include "prtime.h" #include "prprf.h" +#include "nsQueryObject.h" #include "nsCycleCollectionParticipant.h" diff --git a/toolkit/components/url-classifier/HashStore.cpp b/toolkit/components/url-classifier/HashStore.cpp index b59035f64eb6..7985ae81f606 100644 --- a/toolkit/components/url-classifier/HashStore.cpp +++ b/toolkit/components/url-classifier/HashStore.cpp @@ -375,6 +375,7 @@ HashStore::ReadChunkNumbers() nsCOMPtr seekable = do_QueryInterface(mInputStream); nsresult rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET, sizeof(Header)); + NS_ENSURE_SUCCESS(rv, rv); rv = mAddChunks.Read(mInputStream, mHeader.numAddChunks); NS_ENSURE_SUCCESS(rv, rv); @@ -401,6 +402,7 @@ HashStore::ReadHashes() uint32_t offset = sizeof(Header); offset += (mHeader.numAddChunks + mHeader.numSubChunks) * sizeof(uint32_t); nsresult rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET, offset); + NS_ENSURE_SUCCESS(rv, rv); rv = ReadAddPrefixes(); NS_ENSURE_SUCCESS(rv, rv); diff --git a/toolkit/locales/l10n.mk b/toolkit/locales/l10n.mk index dd57b1e1dd94..d1c327f7e64d 100644 --- a/toolkit/locales/l10n.mk +++ b/toolkit/locales/l10n.mk @@ -112,6 +112,7 @@ ifdef MOZ_STUB_INSTALLER $(STUB_HOOK) endif $(PYTHON) $(MOZILLA_DIR)/toolkit/mozapps/installer/l10n-repack.py $(STAGEDIST) $(DIST)/xpi-stage/locale-$(AB_CD) \ + $(MOZ_PKG_EXTRAL10N) \ $(if $(filter omni,$(MOZ_PACKAGER_FORMAT)),$(if $(NON_OMNIJAR_FILES),--non-resource $(NON_OMNIJAR_FILES))) ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT)) diff --git a/toolkit/xre/ProfileReset.h b/toolkit/xre/ProfileReset.h index faf74d09820e..1eada066677a 100644 --- a/toolkit/xre/ProfileReset.h +++ b/toolkit/xre/ProfileReset.h @@ -54,8 +54,9 @@ public: nsresult rv = mProfileDir->CopyToFollowingLinks(mTargetDir, mLeafName); if (NS_SUCCEEDED(rv)) rv = mProfileDir->Remove(true); - else + if (NS_WARN_IF(NS_FAILED(rv))) { NS_WARNING("Could not backup the root profile directory"); + } // If we have a separate local cache profile directory, just delete it. // Don't return an error if this fails so that reset can proceed if it can't be deleted. diff --git a/uriloader/base/nsDocLoader.cpp b/uriloader/base/nsDocLoader.cpp index 8a0e77735ae9..3e82582a7a01 100644 --- a/uriloader/base/nsDocLoader.cpp +++ b/uriloader/base/nsDocLoader.cpp @@ -20,6 +20,7 @@ #include "nscore.h" #include "nsWeakPtr.h" #include "nsAutoPtr.h" +#include "nsQueryObject.h" #include "nsIDOMWindow.h" diff --git a/view/nsView.cpp b/view/nsView.cpp index db179b432c0d..41703691011d 100644 --- a/view/nsView.cpp +++ b/view/nsView.cpp @@ -134,7 +134,7 @@ void nsView::DestroyWidget() NS_DispatchToMainThread(widgetDestroyer); } - NS_RELEASE(mWindow); + mWindow = nullptr; } } @@ -233,7 +233,7 @@ nsIntRect nsView::CalcWidgetBounds(nsWindowType aType) // cocoa rounds widget coordinates to the nearest global "display pixel" // integer value. So we avoid fractional display pixel values by rounding // to the nearest value that won't yield a fractional display pixel. - nsIWidget* widget = parentWidget ? parentWidget : mWindow; + nsIWidget* widget = parentWidget ? parentWidget : mWindow.get(); uint32_t round; if (aType == eWindowType_popup && widget && ((round = widget->RoundsWidgetCoordinatesTo()) > 1)) { @@ -575,7 +575,7 @@ nsresult nsView::CreateWidget(nsWidgetInitData *aWidgetInitData, // XXX: using aForceUseIWidgetParent=true to preserve previous // semantics. It's not clear that it's actually needed. - mWindow = parentWidget->CreateChild(trect, aWidgetInitData, true).take(); + mWindow = parentWidget->CreateChild(trect, aWidgetInitData, true); if (!mWindow) { return NS_ERROR_FAILURE; } @@ -601,8 +601,7 @@ nsresult nsView::CreateWidgetForParent(nsIWidget* aParentWidget, nsIntRect trect = CalcWidgetBounds(aWidgetInitData->mWindowType); - mWindow = - aParentWidget->CreateChild(trect, aWidgetInitData).take(); + mWindow = aParentWidget->CreateChild(trect, aWidgetInitData); if (!mWindow) { return NS_ERROR_FAILURE; } @@ -631,7 +630,7 @@ nsresult nsView::CreateWidgetForPopup(nsWidgetInitData *aWidgetInitData, if (aParentWidget) { // XXX: using aForceUseIWidgetParent=true to preserve previous // semantics. It's not clear that it's actually needed. - mWindow = aParentWidget->CreateChild(trect, aWidgetInitData, true).take(); + mWindow = aParentWidget->CreateChild(trect, aWidgetInitData, true); } else { nsIWidget* nearestParent = GetParent() ? GetParent()->GetNearestWidget(nullptr) @@ -642,7 +641,7 @@ nsresult nsView::CreateWidgetForPopup(nsWidgetInitData *aWidgetInitData, return NS_ERROR_FAILURE; } - mWindow = nearestParent->CreateChild(trect, aWidgetInitData).take(); + mWindow = nearestParent->CreateChild(trect, aWidgetInitData); } if (!mWindow) { return NS_ERROR_FAILURE; @@ -695,7 +694,6 @@ nsresult nsView::AttachToTopLevelWidget(nsIWidget* aWidget) return rv; mWindow = aWidget; - NS_ADDREF(mWindow); mWindow->SetAttachedWidgetListener(this); mWindow->EnableDragDrop(true); @@ -714,7 +712,7 @@ nsresult nsView::DetachFromTopLevelWidget() NS_PRECONDITION(mWindow, "null mWindow for DetachFromTopLevelWidget!"); mWindow->SetAttachedWidgetListener(nullptr); - NS_RELEASE(mWindow); + mWindow = nullptr; mWidgetIsTopLevel = false; @@ -739,7 +737,7 @@ void nsView::AssertNoWindow() NS_ERROR("We already have a window for this view? BAD"); mWindow->SetWidgetListener(nullptr); mWindow->Destroy(); - NS_RELEASE(mWindow); + mWindow = nullptr; } } @@ -775,8 +773,8 @@ void nsView::List(FILE* out, int32_t aIndent) const nsRect windowBounds = rect.ToAppUnits(p2a); mWindow->GetBounds(rect); nsRect nonclientBounds = rect.ToAppUnits(p2a); - nsrefcnt widgetRefCnt = mWindow->AddRef() - 1; - mWindow->Release(); + nsrefcnt widgetRefCnt = mWindow.get()->AddRef() - 1; + mWindow.get()->Release(); int32_t Z = mWindow->GetZIndex(); fprintf(out, "(widget=%p[%" PRIuPTR "] z=%d pos={%d,%d,%d,%d}) ", (void*)mWindow, widgetRefCnt, Z, diff --git a/view/nsView.h b/view/nsView.h index 3c9c93263875..5fe51ddd3f33 100644 --- a/view/nsView.h +++ b/view/nsView.h @@ -11,6 +11,7 @@ #include "nsPoint.h" #include "nsRegion.h" #include "nsCRT.h" +#include "nsCOMPtr.h" #include "nsWidgetInitData.h" // for nsWindowType #include "nsIWidgetListener.h" #include "mozilla/EventForwards.h" @@ -446,7 +447,7 @@ private: nsViewManager *mViewManager; nsView *mParent; - nsIWidget *mWindow; + nsCOMPtr mWindow; nsView *mNextSibling; nsView *mFirstChild; nsIFrame *mFrame; diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm index 99b957553d37..169ec8095f19 100644 --- a/widget/cocoa/nsChildView.mm +++ b/widget/cocoa/nsChildView.mm @@ -3136,7 +3136,10 @@ NSEvent* gLastDragMouseDownEvent = nil; if (mGeckoChild) { nsIWidgetListener* listener = mGeckoChild->GetWidgetListener(); if (listener) { - listener->GetPresShell()->ReconstructFrames(); + nsIPresShell* presShell = listener->GetPresShell(); + if (presShell) { + presShell->ReconstructFrames(); + } } } } diff --git a/widget/cocoa/nsDeviceContextSpecX.mm b/widget/cocoa/nsDeviceContextSpecX.mm index 6b28c9379422..4ed5e2aeb0c3 100644 --- a/widget/cocoa/nsDeviceContextSpecX.mm +++ b/widget/cocoa/nsDeviceContextSpecX.mm @@ -9,6 +9,7 @@ #include #include "nsAutoPtr.h" +#include "nsQueryObject.h" #include "nsIServiceManager.h" #include "nsIPrintOptions.h" #include "nsPrintSettingsX.h" diff --git a/widget/cocoa/nsMenuUtilsX.mm b/widget/cocoa/nsMenuUtilsX.mm index e55a50756cd3..d0865124a943 100644 --- a/widget/cocoa/nsMenuUtilsX.mm +++ b/widget/cocoa/nsMenuUtilsX.mm @@ -17,6 +17,7 @@ #include "nsIDOMDocument.h" #include "nsIDOMXULCommandEvent.h" #include "nsPIDOMWindow.h" +#include "nsQueryObject.h" using namespace mozilla; diff --git a/widget/cocoa/nsPrintDialogX.mm b/widget/cocoa/nsPrintDialogX.mm index 4320fe19edb7..35b3d2287953 100644 --- a/widget/cocoa/nsPrintDialogX.mm +++ b/widget/cocoa/nsPrintDialogX.mm @@ -9,6 +9,7 @@ #include "nsIPrintSettings.h" #include "nsPrintSettingsX.h" #include "nsCOMPtr.h" +#include "nsQueryObject.h" #include "nsServiceManagerUtils.h" #include "nsIWebProgressListener.h" #include "nsIStringBundle.h" diff --git a/widget/cocoa/nsPrintOptionsX.mm b/widget/cocoa/nsPrintOptionsX.mm index 2ebedf7bb2e7..db72392dc3b3 100644 --- a/widget/cocoa/nsPrintOptionsX.mm +++ b/widget/cocoa/nsPrintOptionsX.mm @@ -4,6 +4,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsCOMPtr.h" +#include "nsQueryObject.h" #include "nsIServiceManager.h" #include "nsPrintOptionsX.h" #include "nsPrintSettingsX.h" diff --git a/widget/windows/LSPAnnotator.cpp b/widget/windows/LSPAnnotator.cpp index 98ac8b88f6b1..0f001ef37c9f 100644 --- a/widget/windows/LSPAnnotator.cpp +++ b/widget/windows/LSPAnnotator.cpp @@ -15,6 +15,7 @@ #include "nsISupportsImpl.h" #include "nsServiceManagerUtils.h" #include "nsThreadUtils.h" +#include "nsQueryObject.h" #include #include diff --git a/xpcom/base/moz.build b/xpcom/base/moz.build index fb21ee2a1ee3..34e4c4e8bf48 100644 --- a/xpcom/base/moz.build +++ b/xpcom/base/moz.build @@ -56,6 +56,7 @@ EXPORTS += [ 'nsISizeOf.h', 'nsISupportsBase.h', 'nsObjCExceptions.h', + 'nsQueryObject.h', 'nsRefPtr.h', 'nsStackWalk.h', 'nsTraceRefcnt.h', diff --git a/xpcom/base/nsAutoPtr.h b/xpcom/base/nsAutoPtr.h index a02dc6aa6de5..a6665d15cb3b 100644 --- a/xpcom/base/nsAutoPtr.h +++ b/xpcom/base/nsAutoPtr.h @@ -759,94 +759,6 @@ operator!=(NSCAP_Zero* aLhs, const nsAutoArrayPtr& aRhs) } -/*****************************************************************************/ - -template -class MOZ_STACK_CLASS nsQueryObject : public nsCOMPtr_helper -{ -public: - explicit nsQueryObject(T* aRawPtr) - : mRawPtr(aRawPtr) - { - } - - virtual nsresult NS_FASTCALL operator()(const nsIID& aIID, - void** aResult) const override - { - nsresult status = mRawPtr ? mRawPtr->QueryInterface(aIID, aResult) - : NS_ERROR_NULL_POINTER; - return status; - } -private: - T* MOZ_NON_OWNING_REF mRawPtr; -}; - -template -class MOZ_STACK_CLASS nsQueryObjectWithError : public nsCOMPtr_helper -{ -public: - nsQueryObjectWithError(T* aRawPtr, nsresult* aErrorPtr) - : mRawPtr(aRawPtr), mErrorPtr(aErrorPtr) - { - } - - virtual nsresult NS_FASTCALL operator()(const nsIID& aIID, - void** aResult) const - { - nsresult status = mRawPtr ? mRawPtr->QueryInterface(aIID, aResult) - : NS_ERROR_NULL_POINTER; - if (mErrorPtr) { - *mErrorPtr = status; - } - return status; - } -private: - T* MOZ_NON_OWNING_REF mRawPtr; - nsresult* mErrorPtr; -}; - -template -inline nsQueryObject -do_QueryObject(T* aRawPtr) -{ - return nsQueryObject(aRawPtr); -} - -template -inline nsQueryObject -do_QueryObject(nsCOMPtr& aRawPtr) -{ - return nsQueryObject(aRawPtr); -} - -template -inline nsQueryObject -do_QueryObject(nsRefPtr& aRawPtr) -{ - return nsQueryObject(aRawPtr); -} - -template -inline nsQueryObjectWithError -do_QueryObject(T* aRawPtr, nsresult* aErrorPtr) -{ - return nsQueryObjectWithError(aRawPtr, aErrorPtr); -} - -template -inline nsQueryObjectWithError -do_QueryObject(nsCOMPtr& aRawPtr, nsresult* aErrorPtr) -{ - return nsQueryObjectWithError(aRawPtr, aErrorPtr); -} - -template -inline nsQueryObjectWithError -do_QueryObject(nsRefPtr& aRawPtr, nsresult* aErrorPtr) -{ - return nsQueryObjectWithError(aRawPtr, aErrorPtr); -} - /*****************************************************************************/ #endif // !defined(nsAutoPtr_h) diff --git a/xpcom/base/nsQueryObject.h b/xpcom/base/nsQueryObject.h new file mode 100644 index 000000000000..dceabeb69a9a --- /dev/null +++ b/xpcom/base/nsQueryObject.h @@ -0,0 +1,107 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nsQueryObject_h +#define nsQueryObject_h + +#include "nsCOMPtr.h" +#include "nsRefPtr.h" + +/*****************************************************************************/ + +template +class nsQueryObject : public nsCOMPtr_helper +{ +public: + explicit nsQueryObject(T* aRawPtr) + : mRawPtr(aRawPtr) + { + } + + virtual nsresult NS_FASTCALL operator()(const nsIID& aIID, + void** aResult) const + { + nsresult status = mRawPtr ? mRawPtr->QueryInterface(aIID, aResult) + : NS_ERROR_NULL_POINTER; + return status; + } +private: + T* mRawPtr; +}; + +template +class nsQueryObjectWithError : public nsCOMPtr_helper +{ +public: + nsQueryObjectWithError(T* aRawPtr, nsresult* aErrorPtr) + : mRawPtr(aRawPtr), mErrorPtr(aErrorPtr) + { + } + + virtual nsresult NS_FASTCALL operator()(const nsIID& aIID, + void** aResult) const + { + nsresult status = mRawPtr ? mRawPtr->QueryInterface(aIID, aResult) + : NS_ERROR_NULL_POINTER; + if (mErrorPtr) { + *mErrorPtr = status; + } + return status; + } +private: + T* mRawPtr; + nsresult* mErrorPtr; +}; + +/*****************************************************************************/ + +/*****************************************************************************/ + +template +inline nsQueryObject +do_QueryObject(T* aRawPtr) +{ + return nsQueryObject(aRawPtr); +} + +template +inline nsQueryObject +do_QueryObject(nsCOMPtr& aRawPtr) +{ + return nsQueryObject(aRawPtr); +} + +template +inline nsQueryObject +do_QueryObject(nsRefPtr& aRawPtr) +{ + return nsQueryObject(aRawPtr); +} + +template +inline nsQueryObjectWithError +do_QueryObject(T* aRawPtr, nsresult* aErrorPtr) +{ + return nsQueryObjectWithError(aRawPtr, aErrorPtr); +} + +template +inline nsQueryObjectWithError +do_QueryObject(nsCOMPtr& aRawPtr, nsresult* aErrorPtr) +{ + return nsQueryObjectWithError(aRawPtr, aErrorPtr); +} + +template +inline nsQueryObjectWithError +do_QueryObject(nsRefPtr& aRawPtr, nsresult* aErrorPtr) +{ + return nsQueryObjectWithError(aRawPtr, aErrorPtr); +} + +/*****************************************************************************/ + +#endif // !defined(nsQueryObject_h) diff --git a/xpcom/glue/nsDebug.h b/xpcom/glue/nsDebug.h index e55f80c3761a..40a201c631b0 100644 --- a/xpcom/glue/nsDebug.h +++ b/xpcom/glue/nsDebug.h @@ -77,10 +77,13 @@ inline bool NS_warn_if_impl(bool aCondition, const char* aExpr, * evaluate the message argument. */ #ifdef DEBUG +inline void MOZ_PretendNoReturn() + MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS {} #define NS_ASSERTION(expr, str) \ do { \ if (!(expr)) { \ NS_DebugBreak(NS_DEBUG_ASSERTION, str, #expr, __FILE__, __LINE__); \ + MOZ_PretendNoReturn(); \ } \ } while(0) #else @@ -99,7 +102,10 @@ inline bool NS_warn_if_impl(bool aCondition, const char* aExpr, */ #ifdef DEBUG #define NS_NOTYETIMPLEMENTED(str) \ - NS_DebugBreak(NS_DEBUG_ASSERTION, str, "NotYetImplemented", __FILE__, __LINE__) + do { \ + NS_DebugBreak(NS_DEBUG_ASSERTION, str, "NotYetImplemented", __FILE__, __LINE__); \ + MOZ_PretendNoReturn(); \ + } while(0) #else #define NS_NOTYETIMPLEMENTED(str) do { /* nothing */ } while(0) #endif @@ -110,7 +116,10 @@ inline bool NS_warn_if_impl(bool aCondition, const char* aExpr, */ #ifdef DEBUG #define NS_NOTREACHED(str) \ - NS_DebugBreak(NS_DEBUG_ASSERTION, str, "Not Reached", __FILE__, __LINE__) + do { \ + NS_DebugBreak(NS_DEBUG_ASSERTION, str, "Not Reached", __FILE__, __LINE__); \ + MOZ_PretendNoReturn(); \ + } while(0) #else #define NS_NOTREACHED(str) do { /* nothing */ } while(0) #endif @@ -120,7 +129,10 @@ inline bool NS_warn_if_impl(bool aCondition, const char* aExpr, */ #ifdef DEBUG #define NS_ERROR(str) \ - NS_DebugBreak(NS_DEBUG_ASSERTION, str, "Error", __FILE__, __LINE__) + do { \ + NS_DebugBreak(NS_DEBUG_ASSERTION, str, "Error", __FILE__, __LINE__); \ + MOZ_PretendNoReturn(); \ + } while(0) #else #define NS_ERROR(str) do { /* nothing */ } while(0) #endif @@ -142,7 +154,10 @@ inline bool NS_warn_if_impl(bool aCondition, const char* aExpr, */ #ifdef DEBUG #define NS_ABORT() \ - NS_DebugBreak(NS_DEBUG_ABORT, nullptr, nullptr, __FILE__, __LINE__) + do { \ + NS_DebugBreak(NS_DEBUG_ABORT, nullptr, nullptr, __FILE__, __LINE__); \ + MOZ_PretendNoReturn(); \ + } while(0) #else #define NS_ABORT() do { /* nothing */ } while(0) #endif @@ -152,7 +167,10 @@ inline bool NS_warn_if_impl(bool aCondition, const char* aExpr, */ #ifdef DEBUG #define NS_BREAK() \ - NS_DebugBreak(NS_DEBUG_BREAK, nullptr, nullptr, __FILE__, __LINE__) + do { \ + NS_DebugBreak(NS_DEBUG_BREAK, nullptr, nullptr, __FILE__, __LINE__); \ + MOZ_PretendNoReturn(); \ + } while(0) #else #define NS_BREAK() do { /* nothing */ } while(0) #endif diff --git a/xpcom/io/nsStorageStream.cpp b/xpcom/io/nsStorageStream.cpp index 21531e75723f..926ff7d47724 100644 --- a/xpcom/io/nsStorageStream.cpp +++ b/xpcom/io/nsStorageStream.cpp @@ -351,7 +351,6 @@ public: mSegmentSize(aSegmentSize), mLogicalCursor(0), mStatus(NS_OK) { - NS_ADDREF(mStorageStream); } NS_DECL_THREADSAFE_ISUPPORTS @@ -363,7 +362,6 @@ public: private: ~nsStorageInputStream() { - NS_IF_RELEASE(mStorageStream); } protected: @@ -372,7 +370,7 @@ protected: friend class nsStorageStream; private: - nsStorageStream* mStorageStream; + nsRefPtr mStorageStream; uint32_t mReadCursor; // Next memory location to read byte, or 0 uint32_t mSegmentEnd; // One byte past end of current buffer segment uint32_t mSegmentNum; // Segment number containing read cursor diff --git a/xpcom/tests/TestNsRefPtr.cpp b/xpcom/tests/TestNsRefPtr.cpp index 55a503a82c7f..ecf941bf8a01 100644 --- a/xpcom/tests/TestNsRefPtr.cpp +++ b/xpcom/tests/TestNsRefPtr.cpp @@ -8,6 +8,7 @@ #include "nsCOMPtr.h" #include "nsAutoPtr.h" #include "nsISupports.h" +#include "nsQueryObject.h" #define NS_FOO_IID \ { 0x6f7652e0, 0xee43, 0x11d1, \ diff --git a/xpfe/appshell/nsXULWindow.cpp b/xpfe/appshell/nsXULWindow.cpp index 0beecb97b3cf..ef4fb7424261 100644 --- a/xpfe/appshell/nsXULWindow.cpp +++ b/xpfe/appshell/nsXULWindow.cpp @@ -17,6 +17,7 @@ #include "prprf.h" #include "nsThreadUtils.h" #include "nsNetCID.h" +#include "nsQueryObject.h" //Interfaces needed to be included #include "nsIAppShell.h"