michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsDOMWindowUtils.h" michael@0: michael@0: #include "mozilla/layers/CompositorChild.h" michael@0: #include "mozilla/layers/LayerTransactionChild.h" michael@0: #include "nsPresContext.h" michael@0: #include "nsDOMClassInfoID.h" michael@0: #include "nsError.h" michael@0: #include "nsIDOMEvent.h" michael@0: #include "nsQueryContentEventResult.h" michael@0: #include "CompositionStringSynthesizer.h" michael@0: #include "nsGlobalWindow.h" michael@0: #include "nsIDocument.h" michael@0: #include "nsFocusManager.h" michael@0: #include "nsFrameManager.h" michael@0: #include "nsRefreshDriver.h" michael@0: #include "mozilla/dom/Touch.h" michael@0: #include "nsIObjectLoadingContent.h" michael@0: #include "nsFrame.h" michael@0: #include "mozilla/layers/ShadowLayers.h" michael@0: michael@0: #include "nsIScrollableFrame.h" michael@0: michael@0: #include "nsContentUtils.h" michael@0: michael@0: #include "nsIFrame.h" michael@0: #include "nsIWidget.h" michael@0: #include "nsCharsetSource.h" michael@0: #include "nsJSEnvironment.h" michael@0: #include "nsJSUtils.h" michael@0: michael@0: #include "mozilla/EventStateManager.h" michael@0: #include "mozilla/MiscEvents.h" michael@0: #include "mozilla/MouseEvents.h" michael@0: #include "mozilla/TextEvents.h" michael@0: #include "mozilla/TouchEvents.h" michael@0: michael@0: #include "nsViewManager.h" michael@0: michael@0: #include "nsIDOMHTMLCanvasElement.h" michael@0: #include "nsLayoutUtils.h" michael@0: #include "nsComputedDOMStyle.h" michael@0: #include "nsIPresShell.h" michael@0: #include "nsStyleAnimation.h" michael@0: #include "nsCSSProps.h" michael@0: #include "nsDOMFile.h" michael@0: #include "nsTArrayHelpers.h" michael@0: #include "nsIDocShell.h" michael@0: #include "nsIContentViewer.h" michael@0: #include "nsIMarkupDocumentViewer.h" michael@0: #include "mozilla/dom/DOMRect.h" michael@0: #include michael@0: michael@0: #if defined(MOZ_X11) && defined(MOZ_WIDGET_GTK) michael@0: #include michael@0: #include michael@0: #endif michael@0: michael@0: #include "Layers.h" michael@0: #include "mozilla/layers/ShadowLayers.h" michael@0: michael@0: #include "mozilla/dom/Element.h" michael@0: #include "mozilla/dom/file/FileHandle.h" michael@0: #include "mozilla/dom/FileHandleBinding.h" michael@0: #include "mozilla/dom/TabChild.h" michael@0: #include "mozilla/dom/IDBFactoryBinding.h" michael@0: #include "mozilla/dom/indexedDB/IndexedDatabaseManager.h" michael@0: #include "mozilla/dom/quota/PersistenceType.h" michael@0: #include "mozilla/dom/quota/QuotaManager.h" michael@0: #include "nsDOMBlobBuilder.h" michael@0: #include "nsPrintfCString.h" michael@0: #include "nsViewportInfo.h" michael@0: #include "nsIFormControl.h" michael@0: #include "nsIScriptError.h" michael@0: #include "nsIAppShell.h" michael@0: #include "nsWidgetsCID.h" michael@0: #include "FrameLayerBuilder.h" michael@0: #include "nsDisplayList.h" michael@0: #include "nsROCSSPrimitiveValue.h" michael@0: #include "nsIBaseWindow.h" michael@0: #include "nsIDocShellTreeOwner.h" michael@0: #include "nsIInterfaceRequestorUtils.h" michael@0: #include "GeckoProfiler.h" michael@0: #include "mozilla/Preferences.h" michael@0: #include "nsIContentIterator.h" michael@0: michael@0: #ifdef XP_WIN michael@0: #undef GetClassName michael@0: #endif michael@0: michael@0: using namespace mozilla; michael@0: using namespace mozilla::dom; michael@0: using namespace mozilla::layers; michael@0: using namespace mozilla::widget; michael@0: using namespace mozilla::gfx; michael@0: michael@0: class gfxContext; michael@0: michael@0: static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID); michael@0: michael@0: DOMCI_DATA(WindowUtils, nsDOMWindowUtils) michael@0: michael@0: NS_INTERFACE_MAP_BEGIN(nsDOMWindowUtils) michael@0: NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMWindowUtils) michael@0: NS_INTERFACE_MAP_ENTRY(nsIDOMWindowUtils) michael@0: NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) michael@0: NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WindowUtils) michael@0: NS_INTERFACE_MAP_END michael@0: michael@0: NS_IMPL_ADDREF(nsDOMWindowUtils) michael@0: NS_IMPL_RELEASE(nsDOMWindowUtils) michael@0: michael@0: nsDOMWindowUtils::nsDOMWindowUtils(nsGlobalWindow *aWindow) michael@0: { michael@0: nsCOMPtr supports = do_QueryObject(aWindow); michael@0: mWindow = do_GetWeakReference(supports); michael@0: NS_ASSERTION(aWindow->IsOuterWindow(), "How did that happen?"); michael@0: } michael@0: michael@0: nsDOMWindowUtils::~nsDOMWindowUtils() michael@0: { michael@0: } michael@0: michael@0: nsIPresShell* michael@0: nsDOMWindowUtils::GetPresShell() michael@0: { michael@0: nsCOMPtr window = do_QueryReferent(mWindow); michael@0: if (!window) michael@0: return nullptr; michael@0: michael@0: nsIDocShell *docShell = window->GetDocShell(); michael@0: if (!docShell) michael@0: return nullptr; michael@0: michael@0: return docShell->GetPresShell(); michael@0: } michael@0: michael@0: nsPresContext* michael@0: nsDOMWindowUtils::GetPresContext() michael@0: { michael@0: nsCOMPtr window = do_QueryReferent(mWindow); michael@0: if (!window) michael@0: return nullptr; michael@0: nsIDocShell *docShell = window->GetDocShell(); michael@0: if (!docShell) michael@0: return nullptr; michael@0: nsRefPtr presContext; michael@0: docShell->GetPresContext(getter_AddRefs(presContext)); michael@0: return presContext; michael@0: } michael@0: michael@0: nsIDocument* michael@0: nsDOMWindowUtils::GetDocument() michael@0: { michael@0: nsCOMPtr window = do_QueryReferent(mWindow); michael@0: if (!window) { michael@0: return nullptr; michael@0: } michael@0: return window->GetExtantDoc(); michael@0: } michael@0: michael@0: LayerTransactionChild* michael@0: nsDOMWindowUtils::GetLayerTransaction() michael@0: { michael@0: nsIWidget* widget = GetWidget(); michael@0: if (!widget) michael@0: return nullptr; michael@0: michael@0: LayerManager* manager = widget->GetLayerManager(); michael@0: if (!manager) michael@0: return nullptr; michael@0: michael@0: ShadowLayerForwarder* forwarder = manager->AsShadowForwarder(); michael@0: return forwarder && forwarder->HasShadowManager() ? michael@0: forwarder->GetShadowManager() : michael@0: nullptr; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetImageAnimationMode(uint16_t *aMode) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: NS_ENSURE_ARG_POINTER(aMode); michael@0: *aMode = 0; michael@0: nsPresContext* presContext = GetPresContext(); michael@0: if (presContext) { michael@0: *aMode = presContext->ImageAnimationMode(); michael@0: return NS_OK; michael@0: } michael@0: return NS_ERROR_NOT_AVAILABLE; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SetImageAnimationMode(uint16_t aMode) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsPresContext* presContext = GetPresContext(); michael@0: if (presContext) { michael@0: presContext->SetImageAnimationMode(aMode); michael@0: return NS_OK; michael@0: } michael@0: return NS_ERROR_NOT_AVAILABLE; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetDocCharsetIsForced(bool *aIsForced) michael@0: { michael@0: *aIsForced = false; michael@0: michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsIDocument* doc = GetDocument(); michael@0: *aIsForced = doc && michael@0: doc->GetDocumentCharacterSetSource() >= kCharsetFromParentForced; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetDocumentMetadata(const nsAString& aName, michael@0: nsAString& aValue) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsIDocument* doc = GetDocument(); michael@0: if (doc) { michael@0: nsCOMPtr name = do_GetAtom(aName); michael@0: doc->GetHeaderData(name, aValue); michael@0: return NS_OK; michael@0: } michael@0: michael@0: aValue.Truncate(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::Redraw(uint32_t aCount, uint32_t *aDurationOut) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: if (aCount == 0) michael@0: aCount = 1; michael@0: michael@0: if (nsIPresShell* presShell = GetPresShell()) { michael@0: nsIFrame *rootFrame = presShell->GetRootFrame(); michael@0: michael@0: if (rootFrame) { michael@0: PRIntervalTime iStart = PR_IntervalNow(); michael@0: michael@0: for (uint32_t i = 0; i < aCount; i++) michael@0: rootFrame->InvalidateFrame(); michael@0: michael@0: #if defined(MOZ_X11) && defined(MOZ_WIDGET_GTK) michael@0: XSync(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), False); michael@0: #endif michael@0: michael@0: *aDurationOut = PR_IntervalToMilliseconds(PR_IntervalNow() - iStart); michael@0: michael@0: return NS_OK; michael@0: } michael@0: } michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SetCSSViewport(float aWidthPx, float aHeightPx) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: if (!(aWidthPx >= 0.0 && aHeightPx >= 0.0)) { michael@0: return NS_ERROR_ILLEGAL_VALUE; michael@0: } michael@0: michael@0: nsIPresShell* presShell = GetPresShell(); michael@0: if (!presShell) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: nscoord width = nsPresContext::CSSPixelsToAppUnits(aWidthPx); michael@0: nscoord height = nsPresContext::CSSPixelsToAppUnits(aHeightPx); michael@0: michael@0: presShell->ResizeReflowOverride(width, height); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetViewportInfo(uint32_t aDisplayWidth, michael@0: uint32_t aDisplayHeight, michael@0: double *aDefaultZoom, bool *aAllowZoom, michael@0: double *aMinZoom, double *aMaxZoom, michael@0: uint32_t *aWidth, uint32_t *aHeight, michael@0: bool *aAutoSize) michael@0: { michael@0: nsIDocument* doc = GetDocument(); michael@0: NS_ENSURE_STATE(doc); michael@0: michael@0: nsViewportInfo info = nsContentUtils::GetViewportInfo(doc, ScreenIntSize(aDisplayWidth, aDisplayHeight)); michael@0: *aDefaultZoom = info.GetDefaultZoom().scale; michael@0: *aAllowZoom = info.IsZoomAllowed(); michael@0: *aMinZoom = info.GetMinZoom().scale; michael@0: *aMaxZoom = info.GetMaxZoom().scale; michael@0: *aWidth = info.GetSize().width; michael@0: *aHeight = info.GetSize().height; michael@0: *aAutoSize = info.IsAutoSizeEnabled(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SetDisplayPortForElement(float aXPx, float aYPx, michael@0: float aWidthPx, float aHeightPx, michael@0: nsIDOMElement* aElement, michael@0: uint32_t aPriority) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsIPresShell* presShell = GetPresShell(); michael@0: if (!presShell) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: if (!aElement) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: nsCOMPtr content = do_QueryInterface(aElement); michael@0: michael@0: if (!content) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: if (content->GetCurrentDoc() != presShell->GetDocument()) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: DisplayPortPropertyData* currentData = michael@0: static_cast(content->GetProperty(nsGkAtoms::DisplayPort)); michael@0: if (currentData && currentData->mPriority > aPriority) { michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsRect displayport(nsPresContext::CSSPixelsToAppUnits(aXPx), michael@0: nsPresContext::CSSPixelsToAppUnits(aYPx), michael@0: nsPresContext::CSSPixelsToAppUnits(aWidthPx), michael@0: nsPresContext::CSSPixelsToAppUnits(aHeightPx)); michael@0: michael@0: content->SetProperty(nsGkAtoms::DisplayPort, michael@0: new DisplayPortPropertyData(displayport, aPriority), michael@0: nsINode::DeleteProperty); michael@0: michael@0: nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame(); michael@0: if (rootScrollFrame && content == rootScrollFrame->GetContent()) { michael@0: // We are setting a root displayport for a document. michael@0: // The pres shell needs a special flag set. michael@0: presShell->SetIgnoreViewportScrolling(true); michael@0: } michael@0: michael@0: nsIFrame* rootFrame = presShell->FrameManager()->GetRootFrame(); michael@0: if (rootFrame) { michael@0: rootFrame->SchedulePaint(); michael@0: michael@0: // If we are hiding something that is a display root then send empty paint michael@0: // transaction in order to release retained layers because it won't get michael@0: // any more paint requests when it is hidden. michael@0: if (displayport.IsEmpty() && michael@0: rootFrame == nsLayoutUtils::GetDisplayRootFrame(rootFrame)) { michael@0: nsCOMPtr widget = GetWidget(); michael@0: if (widget) { michael@0: bool isRetainingManager; michael@0: LayerManager* manager = widget->GetLayerManager(&isRetainingManager); michael@0: if (isRetainingManager) { michael@0: manager->BeginTransaction(); michael@0: nsLayoutUtils::PaintFrame(nullptr, rootFrame, nsRegion(), NS_RGB(255, 255, 255), michael@0: nsLayoutUtils::PAINT_WIDGET_LAYERS | michael@0: nsLayoutUtils::PAINT_EXISTING_TRANSACTION); michael@0: } michael@0: } michael@0: } michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SetDisplayPortMarginsForElement(float aLeftMargin, michael@0: float aTopMargin, michael@0: float aRightMargin, michael@0: float aBottomMargin, michael@0: uint32_t aAlignmentX, michael@0: uint32_t aAlignmentY, michael@0: nsIDOMElement* aElement, michael@0: uint32_t aPriority) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsIPresShell* presShell = GetPresShell(); michael@0: if (!presShell) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: if (!aElement) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: nsCOMPtr content = do_QueryInterface(aElement); michael@0: michael@0: if (!content) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: if (content->GetCurrentDoc() != presShell->GetDocument()) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: // Note order change of arguments between our function signature and michael@0: // LayerMargin constructor. michael@0: LayerMargin displayportMargins(aTopMargin, michael@0: aRightMargin, michael@0: aBottomMargin, michael@0: aLeftMargin); michael@0: michael@0: nsLayoutUtils::SetDisplayPortMargins(content, presShell, displayportMargins, michael@0: aAlignmentX, aAlignmentY, aPriority); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SetDisplayPortBaseForElement(int32_t aX, michael@0: int32_t aY, michael@0: int32_t aWidth, michael@0: int32_t aHeight, michael@0: nsIDOMElement* aElement) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsIPresShell* presShell = GetPresShell(); michael@0: if (!presShell) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: if (!aElement) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: nsCOMPtr content = do_QueryInterface(aElement); michael@0: michael@0: if (!content) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: if (content->GetCurrentDoc() != presShell->GetDocument()) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: nsLayoutUtils::SetDisplayPortBase(content, nsRect(aX, aY, aWidth, aHeight)); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SetCriticalDisplayPortForElement(float aXPx, float aYPx, michael@0: float aWidthPx, float aHeightPx, michael@0: nsIDOMElement* aElement) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsIPresShell* presShell = GetPresShell(); michael@0: if (!presShell) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: if (!aElement) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: nsCOMPtr content = do_QueryInterface(aElement); michael@0: michael@0: if (!content) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: if (content->GetCurrentDoc() != presShell->GetDocument()) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: nsRect displayport; michael@0: if (!nsLayoutUtils::GetDisplayPort(content, &displayport)) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: nsRect criticalDisplayport(nsPresContext::CSSPixelsToAppUnits(aXPx), michael@0: nsPresContext::CSSPixelsToAppUnits(aYPx), michael@0: nsPresContext::CSSPixelsToAppUnits(aWidthPx), michael@0: nsPresContext::CSSPixelsToAppUnits(aHeightPx)); michael@0: content->SetProperty(nsGkAtoms::CriticalDisplayPort, new nsRect(criticalDisplayport), michael@0: nsINode::DeleteProperty); michael@0: michael@0: nsIFrame* rootFrame = presShell->GetRootFrame(); michael@0: if (rootFrame) { michael@0: rootFrame->InvalidateFrame(); michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SetResolution(float aXResolution, float aYResolution) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsIPresShell* presShell = GetPresShell(); michael@0: if (!presShell) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable(); michael@0: if (sf) { michael@0: sf->SetResolution(gfxSize(aXResolution, aYResolution)); michael@0: presShell->SetResolution(aXResolution, aYResolution); michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetResolution(float* aXResolution, float* aYResolution) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsIPresShell* presShell = GetPresShell(); michael@0: if (!presShell) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable(); michael@0: if (sf) { michael@0: const gfxSize& res = sf->GetResolution(); michael@0: *aXResolution = res.width; michael@0: *aYResolution = res.height; michael@0: } else { michael@0: *aXResolution = presShell->GetXResolution(); michael@0: *aYResolution = presShell->GetYResolution(); michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetIsResolutionSet(bool* aIsResolutionSet) { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsIPresShell* presShell = GetPresShell(); michael@0: if (!presShell) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: const nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable(); michael@0: *aIsResolutionSet = sf && sf->IsResolutionSet(); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SetIsFirstPaint(bool aIsFirstPaint) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsIPresShell* presShell = GetPresShell(); michael@0: if (presShell) { michael@0: presShell->SetIsFirstPaint(aIsFirstPaint); michael@0: return NS_OK; michael@0: } michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetIsFirstPaint(bool *aIsFirstPaint) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsIPresShell* presShell = GetPresShell(); michael@0: if (presShell) { michael@0: *aIsFirstPaint = presShell->GetIsFirstPaint(); michael@0: return NS_OK; michael@0: } michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetPresShellId(uint32_t *aPresShellId) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsIPresShell* presShell = GetPresShell(); michael@0: if (presShell) { michael@0: *aPresShellId = presShell->GetPresShellId(); michael@0: return NS_OK; michael@0: } michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: /* static */ michael@0: mozilla::Modifiers michael@0: nsDOMWindowUtils::GetWidgetModifiers(int32_t aModifiers) michael@0: { michael@0: Modifiers result = 0; michael@0: if (aModifiers & nsIDOMWindowUtils::MODIFIER_SHIFT) { michael@0: result |= mozilla::MODIFIER_SHIFT; michael@0: } michael@0: if (aModifiers & nsIDOMWindowUtils::MODIFIER_CONTROL) { michael@0: result |= mozilla::MODIFIER_CONTROL; michael@0: } michael@0: if (aModifiers & nsIDOMWindowUtils::MODIFIER_ALT) { michael@0: result |= mozilla::MODIFIER_ALT; michael@0: } michael@0: if (aModifiers & nsIDOMWindowUtils::MODIFIER_META) { michael@0: result |= mozilla::MODIFIER_META; michael@0: } michael@0: if (aModifiers & nsIDOMWindowUtils::MODIFIER_ALTGRAPH) { michael@0: result |= mozilla::MODIFIER_ALTGRAPH; michael@0: } michael@0: if (aModifiers & nsIDOMWindowUtils::MODIFIER_CAPSLOCK) { michael@0: result |= mozilla::MODIFIER_CAPSLOCK; michael@0: } michael@0: if (aModifiers & nsIDOMWindowUtils::MODIFIER_FN) { michael@0: result |= mozilla::MODIFIER_FN; michael@0: } michael@0: if (aModifiers & nsIDOMWindowUtils::MODIFIER_NUMLOCK) { michael@0: result |= mozilla::MODIFIER_NUMLOCK; michael@0: } michael@0: if (aModifiers & nsIDOMWindowUtils::MODIFIER_SCROLLLOCK) { michael@0: result |= mozilla::MODIFIER_SCROLLLOCK; michael@0: } michael@0: if (aModifiers & nsIDOMWindowUtils::MODIFIER_SYMBOLLOCK) { michael@0: result |= mozilla::MODIFIER_SYMBOLLOCK; michael@0: } michael@0: if (aModifiers & nsIDOMWindowUtils::MODIFIER_OS) { michael@0: result |= mozilla::MODIFIER_OS; michael@0: } michael@0: return result; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SendMouseEvent(const nsAString& aType, michael@0: float aX, michael@0: float aY, michael@0: int32_t aButton, michael@0: int32_t aClickCount, michael@0: int32_t aModifiers, michael@0: bool aIgnoreRootScrollFrame, michael@0: float aPressure, michael@0: unsigned short aInputSourceArg, michael@0: bool aIsSynthesized, michael@0: uint8_t aOptionalArgCount, michael@0: bool *aPreventDefault) michael@0: { michael@0: return SendMouseEventCommon(aType, aX, aY, aButton, aClickCount, aModifiers, michael@0: aIgnoreRootScrollFrame, aPressure, michael@0: aInputSourceArg, false, aPreventDefault, michael@0: aOptionalArgCount >= 4 ? aIsSynthesized : true); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SendMouseEventToWindow(const nsAString& aType, michael@0: float aX, michael@0: float aY, michael@0: int32_t aButton, michael@0: int32_t aClickCount, michael@0: int32_t aModifiers, michael@0: bool aIgnoreRootScrollFrame, michael@0: float aPressure, michael@0: unsigned short aInputSourceArg, michael@0: bool aIsSynthesized, michael@0: uint8_t aOptionalArgCount) michael@0: { michael@0: PROFILER_LABEL("nsDOMWindowUtils", "SendMouseEventToWindow"); michael@0: return SendMouseEventCommon(aType, aX, aY, aButton, aClickCount, aModifiers, michael@0: aIgnoreRootScrollFrame, aPressure, michael@0: aInputSourceArg, true, nullptr, michael@0: aOptionalArgCount >= 4 ? aIsSynthesized : true); michael@0: } michael@0: michael@0: static LayoutDeviceIntPoint michael@0: ToWidgetPoint(const CSSPoint& aPoint, const nsPoint& aOffset, michael@0: nsPresContext* aPresContext) michael@0: { michael@0: return LayoutDeviceIntPoint::FromAppUnitsRounded( michael@0: CSSPoint::ToAppUnits(aPoint) + aOffset, michael@0: aPresContext->AppUnitsPerDevPixel()); michael@0: } michael@0: michael@0: static inline int16_t michael@0: GetButtonsFlagForButton(int32_t aButton) michael@0: { michael@0: switch (aButton) { michael@0: case WidgetMouseEvent::eLeftButton: michael@0: return WidgetMouseEvent::eLeftButtonFlag; michael@0: case WidgetMouseEvent::eMiddleButton: michael@0: return WidgetMouseEvent::eMiddleButtonFlag; michael@0: case WidgetMouseEvent::eRightButton: michael@0: return WidgetMouseEvent::eRightButtonFlag; michael@0: case 4: michael@0: return WidgetMouseEvent::e4thButtonFlag; michael@0: case 5: michael@0: return WidgetMouseEvent::e5thButtonFlag; michael@0: default: michael@0: NS_ERROR("Button not known."); michael@0: return 0; michael@0: } michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SendMouseEventCommon(const nsAString& aType, michael@0: float aX, michael@0: float aY, michael@0: int32_t aButton, michael@0: int32_t aClickCount, michael@0: int32_t aModifiers, michael@0: bool aIgnoreRootScrollFrame, michael@0: float aPressure, michael@0: unsigned short aInputSourceArg, michael@0: bool aToWindow, michael@0: bool *aPreventDefault, michael@0: bool aIsSynthesized) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: // get the widget to send the event to michael@0: nsPoint offset; michael@0: nsCOMPtr widget = GetWidget(&offset); michael@0: if (!widget) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: int32_t msg; michael@0: bool contextMenuKey = false; michael@0: if (aType.EqualsLiteral("mousedown")) michael@0: msg = NS_MOUSE_BUTTON_DOWN; michael@0: else if (aType.EqualsLiteral("mouseup")) michael@0: msg = NS_MOUSE_BUTTON_UP; michael@0: else if (aType.EqualsLiteral("mousemove")) michael@0: msg = NS_MOUSE_MOVE; michael@0: else if (aType.EqualsLiteral("mouseover")) michael@0: msg = NS_MOUSE_ENTER; michael@0: else if (aType.EqualsLiteral("mouseout")) michael@0: msg = NS_MOUSE_EXIT; michael@0: else if (aType.EqualsLiteral("contextmenu")) { michael@0: msg = NS_CONTEXTMENU; michael@0: contextMenuKey = (aButton == 0); michael@0: } else if (aType.EqualsLiteral("MozMouseHittest")) michael@0: msg = NS_MOUSE_MOZHITTEST; michael@0: else michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: if (aInputSourceArg == nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN) { michael@0: aInputSourceArg = nsIDOMMouseEvent::MOZ_SOURCE_MOUSE; michael@0: } michael@0: michael@0: WidgetMouseEvent event(true, msg, widget, WidgetMouseEvent::eReal, michael@0: contextMenuKey ? WidgetMouseEvent::eContextMenuKey : michael@0: WidgetMouseEvent::eNormal); michael@0: event.modifiers = GetWidgetModifiers(aModifiers); michael@0: event.button = aButton; michael@0: event.buttons = GetButtonsFlagForButton(aButton); michael@0: event.widget = widget; michael@0: event.pressure = aPressure; michael@0: event.inputSource = aInputSourceArg; michael@0: event.clickCount = aClickCount; michael@0: event.time = PR_IntervalNow(); michael@0: event.mFlags.mIsSynthesizedForTests = aIsSynthesized; michael@0: michael@0: nsPresContext* presContext = GetPresContext(); michael@0: if (!presContext) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: event.refPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext); michael@0: event.ignoreRootScrollFrame = aIgnoreRootScrollFrame; michael@0: michael@0: nsEventStatus status; michael@0: if (aToWindow) { michael@0: nsCOMPtr presShell = presContext->PresShell(); michael@0: if (!presShell) michael@0: return NS_ERROR_FAILURE; michael@0: nsViewManager* viewManager = presShell->GetViewManager(); michael@0: if (!viewManager) michael@0: return NS_ERROR_FAILURE; michael@0: nsView* view = viewManager->GetRootView(); michael@0: if (!view) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: status = nsEventStatus_eIgnore; michael@0: return presShell->HandleEvent(view->GetFrame(), &event, false, &status); michael@0: } michael@0: nsresult rv = widget->DispatchEvent(&event, status); michael@0: *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault); michael@0: michael@0: return rv; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SendPointerEvent(const nsAString& aType, michael@0: float aX, michael@0: float aY, michael@0: int32_t aButton, michael@0: int32_t aClickCount, michael@0: int32_t aModifiers, michael@0: bool aIgnoreRootScrollFrame, michael@0: float aPressure, michael@0: unsigned short aInputSourceArg, michael@0: int32_t aPointerId, michael@0: int32_t aWidth, michael@0: int32_t aHeight, michael@0: int32_t tiltX, michael@0: int32_t tiltY, michael@0: bool aIsPrimary, michael@0: bool aIsSynthesized, michael@0: uint8_t aOptionalArgCount, michael@0: bool* aPreventDefault) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: // get the widget to send the event to michael@0: nsPoint offset; michael@0: nsCOMPtr widget = GetWidget(&offset); michael@0: if (!widget) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: int32_t msg; michael@0: if (aType.EqualsLiteral("pointerdown")) { michael@0: msg = NS_POINTER_DOWN; michael@0: } else if (aType.EqualsLiteral("pointerup")) { michael@0: msg = NS_POINTER_UP; michael@0: } else if (aType.EqualsLiteral("pointermove")) { michael@0: msg = NS_POINTER_MOVE; michael@0: } else if (aType.EqualsLiteral("pointerover")) { michael@0: msg = NS_POINTER_OVER; michael@0: } else if (aType.EqualsLiteral("pointerout")) { michael@0: msg = NS_POINTER_OUT; michael@0: } else { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: if (aInputSourceArg == nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN) { michael@0: aInputSourceArg = nsIDOMMouseEvent::MOZ_SOURCE_MOUSE; michael@0: } michael@0: michael@0: WidgetPointerEvent event(true, msg, widget); michael@0: event.modifiers = GetWidgetModifiers(aModifiers); michael@0: event.button = aButton; michael@0: event.buttons = GetButtonsFlagForButton(aButton); michael@0: event.widget = widget; michael@0: event.pressure = aPressure; michael@0: event.inputSource = aInputSourceArg; michael@0: event.pointerId = aPointerId; michael@0: event.width = aWidth; michael@0: event.height = aHeight; michael@0: event.tiltX = tiltX; michael@0: event.tiltY = tiltY; michael@0: event.isPrimary = aIsPrimary; michael@0: event.clickCount = aClickCount; michael@0: event.time = PR_IntervalNow(); michael@0: event.mFlags.mIsSynthesizedForTests = aOptionalArgCount >= 10 ? aIsSynthesized : true; michael@0: michael@0: nsPresContext* presContext = GetPresContext(); michael@0: if (!presContext) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: event.refPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext); michael@0: event.ignoreRootScrollFrame = aIgnoreRootScrollFrame; michael@0: michael@0: nsEventStatus status; michael@0: nsresult rv = widget->DispatchEvent(&event, status); michael@0: *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault); michael@0: michael@0: return rv; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SendWheelEvent(float aX, michael@0: float aY, michael@0: double aDeltaX, michael@0: double aDeltaY, michael@0: double aDeltaZ, michael@0: uint32_t aDeltaMode, michael@0: int32_t aModifiers, michael@0: int32_t aLineOrPageDeltaX, michael@0: int32_t aLineOrPageDeltaY, michael@0: uint32_t aOptions) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: // get the widget to send the event to michael@0: nsPoint offset; michael@0: nsCOMPtr widget = GetWidget(&offset); michael@0: if (!widget) { michael@0: return NS_ERROR_NULL_POINTER; michael@0: } michael@0: michael@0: WidgetWheelEvent wheelEvent(true, NS_WHEEL_WHEEL, widget); michael@0: wheelEvent.modifiers = GetWidgetModifiers(aModifiers); michael@0: wheelEvent.deltaX = aDeltaX; michael@0: wheelEvent.deltaY = aDeltaY; michael@0: wheelEvent.deltaZ = aDeltaZ; michael@0: wheelEvent.deltaMode = aDeltaMode; michael@0: wheelEvent.isMomentum = michael@0: (aOptions & WHEEL_EVENT_CAUSED_BY_MOMENTUM) != 0; michael@0: wheelEvent.isPixelOnlyDevice = michael@0: (aOptions & WHEEL_EVENT_CAUSED_BY_PIXEL_ONLY_DEVICE) != 0; michael@0: NS_ENSURE_TRUE( michael@0: !wheelEvent.isPixelOnlyDevice || michael@0: aDeltaMode == nsIDOMWheelEvent::DOM_DELTA_PIXEL, michael@0: NS_ERROR_INVALID_ARG); michael@0: wheelEvent.customizedByUserPrefs = michael@0: (aOptions & WHEEL_EVENT_CUSTOMIZED_BY_USER_PREFS) != 0; michael@0: wheelEvent.lineOrPageDeltaX = aLineOrPageDeltaX; michael@0: wheelEvent.lineOrPageDeltaY = aLineOrPageDeltaY; michael@0: wheelEvent.widget = widget; michael@0: michael@0: wheelEvent.time = PR_Now() / 1000; michael@0: michael@0: nsPresContext* presContext = GetPresContext(); michael@0: NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE); michael@0: michael@0: wheelEvent.refPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext); michael@0: michael@0: nsEventStatus status; michael@0: nsresult rv = widget->DispatchEvent(&wheelEvent, status); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: bool failedX = false; michael@0: if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_X_ZERO) && michael@0: wheelEvent.overflowDeltaX != 0) { michael@0: failedX = true; michael@0: } michael@0: if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_X_POSITIVE) && michael@0: wheelEvent.overflowDeltaX <= 0) { michael@0: failedX = true; michael@0: } michael@0: if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_X_NEGATIVE) && michael@0: wheelEvent.overflowDeltaX >= 0) { michael@0: failedX = true; michael@0: } michael@0: bool failedY = false; michael@0: if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_Y_ZERO) && michael@0: wheelEvent.overflowDeltaY != 0) { michael@0: failedY = true; michael@0: } michael@0: if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_Y_POSITIVE) && michael@0: wheelEvent.overflowDeltaY <= 0) { michael@0: failedY = true; michael@0: } michael@0: if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_Y_NEGATIVE) && michael@0: wheelEvent.overflowDeltaY >= 0) { michael@0: failedY = true; michael@0: } michael@0: michael@0: #ifdef DEBUG michael@0: if (failedX) { michael@0: nsPrintfCString debugMsg("SendWheelEvent(): unexpected overflowDeltaX: %f", michael@0: wheelEvent.overflowDeltaX); michael@0: NS_WARNING(debugMsg.get()); michael@0: } michael@0: if (failedY) { michael@0: nsPrintfCString debugMsg("SendWheelEvent(): unexpected overflowDeltaY: %f", michael@0: wheelEvent.overflowDeltaY); michael@0: NS_WARNING(debugMsg.get()); michael@0: } michael@0: #endif michael@0: michael@0: return (!failedX && !failedY) ? NS_OK : NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SendTouchEvent(const nsAString& aType, michael@0: uint32_t *aIdentifiers, michael@0: int32_t *aXs, michael@0: int32_t *aYs, michael@0: uint32_t *aRxs, michael@0: uint32_t *aRys, michael@0: float *aRotationAngles, michael@0: float *aForces, michael@0: uint32_t aCount, michael@0: int32_t aModifiers, michael@0: bool aIgnoreRootScrollFrame, michael@0: bool *aPreventDefault) michael@0: { michael@0: return SendTouchEventCommon(aType, aIdentifiers, aXs, aYs, aRxs, aRys, michael@0: aRotationAngles, aForces, aCount, aModifiers, michael@0: aIgnoreRootScrollFrame, false, aPreventDefault); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SendTouchEventToWindow(const nsAString& aType, michael@0: uint32_t* aIdentifiers, michael@0: int32_t* aXs, michael@0: int32_t* aYs, michael@0: uint32_t* aRxs, michael@0: uint32_t* aRys, michael@0: float* aRotationAngles, michael@0: float* aForces, michael@0: uint32_t aCount, michael@0: int32_t aModifiers, michael@0: bool aIgnoreRootScrollFrame, michael@0: bool* aPreventDefault) michael@0: { michael@0: return SendTouchEventCommon(aType, aIdentifiers, aXs, aYs, aRxs, aRys, michael@0: aRotationAngles, aForces, aCount, aModifiers, michael@0: aIgnoreRootScrollFrame, true, aPreventDefault); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SendTouchEventCommon(const nsAString& aType, michael@0: uint32_t* aIdentifiers, michael@0: int32_t* aXs, michael@0: int32_t* aYs, michael@0: uint32_t* aRxs, michael@0: uint32_t* aRys, michael@0: float* aRotationAngles, michael@0: float* aForces, michael@0: uint32_t aCount, michael@0: int32_t aModifiers, michael@0: bool aIgnoreRootScrollFrame, michael@0: bool aToWindow, michael@0: bool* aPreventDefault) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: // get the widget to send the event to michael@0: nsPoint offset; michael@0: nsCOMPtr widget = GetWidget(&offset); michael@0: if (!widget) { michael@0: return NS_ERROR_NULL_POINTER; michael@0: } michael@0: int32_t msg; michael@0: if (aType.EqualsLiteral("touchstart")) { michael@0: msg = NS_TOUCH_START; michael@0: } else if (aType.EqualsLiteral("touchmove")) { michael@0: msg = NS_TOUCH_MOVE; michael@0: } else if (aType.EqualsLiteral("touchend")) { michael@0: msg = NS_TOUCH_END; michael@0: } else if (aType.EqualsLiteral("touchcancel")) { michael@0: msg = NS_TOUCH_CANCEL; michael@0: } else { michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: WidgetTouchEvent event(true, msg, widget); michael@0: event.modifiers = GetWidgetModifiers(aModifiers); michael@0: event.widget = widget; michael@0: event.time = PR_Now(); michael@0: michael@0: nsPresContext* presContext = GetPresContext(); michael@0: if (!presContext) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: event.touches.SetCapacity(aCount); michael@0: for (uint32_t i = 0; i < aCount; ++i) { michael@0: LayoutDeviceIntPoint pt = michael@0: ToWidgetPoint(CSSPoint(aXs[i], aYs[i]), offset, presContext); michael@0: nsRefPtr t = new Touch(aIdentifiers[i], michael@0: LayoutDeviceIntPoint::ToUntyped(pt), michael@0: nsIntPoint(aRxs[i], aRys[i]), michael@0: aRotationAngles[i], michael@0: aForces[i]); michael@0: event.touches.AppendElement(t); michael@0: } michael@0: michael@0: nsEventStatus status; michael@0: if (aToWindow) { michael@0: nsCOMPtr presShell = presContext->PresShell(); michael@0: if (!presShell) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: nsViewManager* viewManager = presShell->GetViewManager(); michael@0: if (!viewManager) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: nsView* view = viewManager->GetRootView(); michael@0: if (!view) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: status = nsEventStatus_eIgnore; michael@0: *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault); michael@0: return presShell->HandleEvent(view->GetFrame(), &event, false, &status); michael@0: } michael@0: michael@0: nsresult rv = widget->DispatchEvent(&event, status); michael@0: *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault); michael@0: return rv; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SendKeyEvent(const nsAString& aType, michael@0: int32_t aKeyCode, michael@0: int32_t aCharCode, michael@0: int32_t aModifiers, michael@0: uint32_t aAdditionalFlags, michael@0: bool* aDefaultActionTaken) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: // get the widget to send the event to michael@0: nsCOMPtr widget = GetWidget(); michael@0: if (!widget) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: int32_t msg; michael@0: if (aType.EqualsLiteral("keydown")) michael@0: msg = NS_KEY_DOWN; michael@0: else if (aType.EqualsLiteral("keyup")) michael@0: msg = NS_KEY_UP; michael@0: else if (aType.EqualsLiteral("keypress")) michael@0: msg = NS_KEY_PRESS; michael@0: else michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: WidgetKeyboardEvent event(true, msg, widget); michael@0: event.modifiers = GetWidgetModifiers(aModifiers); michael@0: michael@0: if (msg == NS_KEY_PRESS) { michael@0: event.keyCode = aCharCode ? 0 : aKeyCode; michael@0: event.charCode = aCharCode; michael@0: } else { michael@0: event.keyCode = aKeyCode; michael@0: event.charCode = 0; michael@0: } michael@0: michael@0: uint32_t locationFlag = (aAdditionalFlags & michael@0: (KEY_FLAG_LOCATION_STANDARD | KEY_FLAG_LOCATION_LEFT | michael@0: KEY_FLAG_LOCATION_RIGHT | KEY_FLAG_LOCATION_NUMPAD | michael@0: KEY_FLAG_LOCATION_MOBILE | KEY_FLAG_LOCATION_JOYSTICK)); michael@0: switch (locationFlag) { michael@0: case KEY_FLAG_LOCATION_STANDARD: michael@0: event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD; michael@0: break; michael@0: case KEY_FLAG_LOCATION_LEFT: michael@0: event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_LEFT; michael@0: break; michael@0: case KEY_FLAG_LOCATION_RIGHT: michael@0: event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_RIGHT; michael@0: break; michael@0: case KEY_FLAG_LOCATION_NUMPAD: michael@0: event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_NUMPAD; michael@0: break; michael@0: case KEY_FLAG_LOCATION_MOBILE: michael@0: event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_MOBILE; michael@0: break; michael@0: case KEY_FLAG_LOCATION_JOYSTICK: michael@0: event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_JOYSTICK; michael@0: break; michael@0: default: michael@0: if (locationFlag != 0) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: // If location flag isn't set, choose the location from keycode. michael@0: switch (aKeyCode) { michael@0: case nsIDOMKeyEvent::DOM_VK_NUMPAD0: michael@0: case nsIDOMKeyEvent::DOM_VK_NUMPAD1: michael@0: case nsIDOMKeyEvent::DOM_VK_NUMPAD2: michael@0: case nsIDOMKeyEvent::DOM_VK_NUMPAD3: michael@0: case nsIDOMKeyEvent::DOM_VK_NUMPAD4: michael@0: case nsIDOMKeyEvent::DOM_VK_NUMPAD5: michael@0: case nsIDOMKeyEvent::DOM_VK_NUMPAD6: michael@0: case nsIDOMKeyEvent::DOM_VK_NUMPAD7: michael@0: case nsIDOMKeyEvent::DOM_VK_NUMPAD8: michael@0: case nsIDOMKeyEvent::DOM_VK_NUMPAD9: michael@0: case nsIDOMKeyEvent::DOM_VK_MULTIPLY: michael@0: case nsIDOMKeyEvent::DOM_VK_ADD: michael@0: case nsIDOMKeyEvent::DOM_VK_SEPARATOR: michael@0: case nsIDOMKeyEvent::DOM_VK_SUBTRACT: michael@0: case nsIDOMKeyEvent::DOM_VK_DECIMAL: michael@0: case nsIDOMKeyEvent::DOM_VK_DIVIDE: michael@0: event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_NUMPAD; michael@0: break; michael@0: case nsIDOMKeyEvent::DOM_VK_SHIFT: michael@0: case nsIDOMKeyEvent::DOM_VK_CONTROL: michael@0: case nsIDOMKeyEvent::DOM_VK_ALT: michael@0: case nsIDOMKeyEvent::DOM_VK_META: michael@0: event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_LEFT; michael@0: break; michael@0: default: michael@0: event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD; michael@0: break; michael@0: } michael@0: break; michael@0: } michael@0: michael@0: event.refPoint.x = event.refPoint.y = 0; michael@0: event.time = PR_IntervalNow(); michael@0: event.mFlags.mIsSynthesizedForTests = true; michael@0: michael@0: if (aAdditionalFlags & KEY_FLAG_PREVENT_DEFAULT) { michael@0: event.mFlags.mDefaultPrevented = true; michael@0: } michael@0: michael@0: nsEventStatus status; michael@0: nsresult rv = widget->DispatchEvent(&event, status); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: *aDefaultActionTaken = (status != nsEventStatus_eConsumeNoDefault); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SendNativeKeyEvent(int32_t aNativeKeyboardLayout, michael@0: int32_t aNativeKeyCode, michael@0: int32_t aModifiers, michael@0: const nsAString& aCharacters, michael@0: const nsAString& aUnmodifiedCharacters) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: // get the widget to send the event to michael@0: nsCOMPtr widget = GetWidget(); michael@0: if (!widget) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: return widget->SynthesizeNativeKeyEvent(aNativeKeyboardLayout, aNativeKeyCode, michael@0: aModifiers, aCharacters, aUnmodifiedCharacters); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SendNativeMouseEvent(int32_t aScreenX, michael@0: int32_t aScreenY, michael@0: int32_t aNativeMessage, michael@0: int32_t aModifierFlags, michael@0: nsIDOMElement* aElement) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: // get the widget to send the event to michael@0: nsCOMPtr widget = GetWidgetForElement(aElement); michael@0: if (!widget) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: return widget->SynthesizeNativeMouseEvent(nsIntPoint(aScreenX, aScreenY), michael@0: aNativeMessage, aModifierFlags); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SendNativeMouseScrollEvent(int32_t aScreenX, michael@0: int32_t aScreenY, michael@0: uint32_t aNativeMessage, michael@0: double aDeltaX, michael@0: double aDeltaY, michael@0: double aDeltaZ, michael@0: uint32_t aModifierFlags, michael@0: uint32_t aAdditionalFlags, michael@0: nsIDOMElement* aElement) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: // get the widget to send the event to michael@0: nsCOMPtr widget = GetWidgetForElement(aElement); michael@0: if (!widget) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: return widget->SynthesizeNativeMouseScrollEvent(nsIntPoint(aScreenX, michael@0: aScreenY), michael@0: aNativeMessage, michael@0: aDeltaX, aDeltaY, aDeltaZ, michael@0: aModifierFlags, michael@0: aAdditionalFlags); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SendNativeTouchPoint(uint32_t aPointerId, michael@0: uint32_t aTouchState, michael@0: int32_t aScreenX, michael@0: int32_t aScreenY, michael@0: double aPressure, michael@0: uint32_t aOrientation) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr widget = GetWidget(); michael@0: if (!widget) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: if (aPressure < 0 || aPressure > 1 || aOrientation > 359) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: return widget->SynthesizeNativeTouchPoint(aPointerId, michael@0: (nsIWidget::TouchPointerState)aTouchState, michael@0: nsIntPoint(aScreenX, aScreenY), michael@0: aPressure, aOrientation); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SendNativeTouchTap(int32_t aScreenX, michael@0: int32_t aScreenY, michael@0: bool aLongTap) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr widget = GetWidget(); michael@0: if (!widget) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: return widget->SynthesizeNativeTouchTap(nsIntPoint(aScreenX, aScreenY), aLongTap); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::ClearNativeTouchSequence() michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr widget = GetWidget(); michael@0: if (!widget) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: return widget->ClearNativeTouchSequence(); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::ActivateNativeMenuItemAt(const nsAString& indexString) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: // get the widget to send the event to michael@0: nsCOMPtr widget = GetWidget(); michael@0: if (!widget) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: return widget->ActivateNativeMenuItemAt(indexString); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::ForceUpdateNativeMenuAt(const nsAString& indexString) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: // get the widget to send the event to michael@0: nsCOMPtr widget = GetWidget(); michael@0: if (!widget) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: return widget->ForceUpdateNativeMenuAt(indexString); michael@0: } michael@0: michael@0: nsIWidget* michael@0: nsDOMWindowUtils::GetWidget(nsPoint* aOffset) michael@0: { michael@0: nsCOMPtr window = do_QueryReferent(mWindow); michael@0: if (window) { michael@0: nsIDocShell *docShell = window->GetDocShell(); michael@0: if (docShell) { michael@0: nsCOMPtr presShell = docShell->GetPresShell(); michael@0: if (presShell) { michael@0: nsIFrame* frame = presShell->GetRootFrame(); michael@0: if (frame) michael@0: return frame->GetView()->GetNearestWidget(aOffset); michael@0: } michael@0: } michael@0: } michael@0: michael@0: return nullptr; michael@0: } michael@0: michael@0: nsIWidget* michael@0: nsDOMWindowUtils::GetWidgetForElement(nsIDOMElement* aElement) michael@0: { michael@0: if (!aElement) michael@0: return GetWidget(); michael@0: michael@0: nsCOMPtr content = do_QueryInterface(aElement); michael@0: nsIDocument* doc = content->GetCurrentDoc(); michael@0: nsIPresShell* presShell = doc ? doc->GetShell() : nullptr; michael@0: michael@0: if (presShell) { michael@0: nsIFrame* frame = content->GetPrimaryFrame(); michael@0: if (!frame) { michael@0: frame = presShell->GetRootFrame(); michael@0: } michael@0: if (frame) michael@0: return frame->GetNearestWidget(); michael@0: } michael@0: michael@0: return nullptr; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::Focus(nsIDOMElement* aElement) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr window = do_QueryReferent(mWindow); michael@0: nsIFocusManager* fm = nsFocusManager::GetFocusManager(); michael@0: if (fm) { michael@0: if (aElement) michael@0: fm->SetFocus(aElement, 0); michael@0: else michael@0: fm->ClearFocus(window); michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GarbageCollect(nsICycleCollectorListener *aListener, michael@0: int32_t aExtraForgetSkippableCalls) michael@0: { michael@0: PROFILER_LABEL("GC", "GarbageCollect"); michael@0: // Always permit this in debug builds. michael@0: #ifndef DEBUG michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: #endif michael@0: michael@0: nsJSContext::GarbageCollectNow(JS::gcreason::DOM_UTILS); michael@0: nsJSContext::CycleCollectNow(aListener, aExtraForgetSkippableCalls); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::CycleCollect(nsICycleCollectorListener *aListener, michael@0: int32_t aExtraForgetSkippableCalls) michael@0: { michael@0: // Always permit this in debug builds. michael@0: #ifndef DEBUG michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: #endif michael@0: michael@0: nsJSContext::CycleCollectNow(aListener, aExtraForgetSkippableCalls); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::RunNextCollectorTimer() michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsJSContext::RunNextCollectorTimer(); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SendSimpleGestureEvent(const nsAString& aType, michael@0: float aX, michael@0: float aY, michael@0: uint32_t aDirection, michael@0: double aDelta, michael@0: int32_t aModifiers, michael@0: uint32_t aClickCount) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: // get the widget to send the event to michael@0: nsPoint offset; michael@0: nsCOMPtr widget = GetWidget(&offset); michael@0: if (!widget) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: int32_t msg; michael@0: if (aType.EqualsLiteral("MozSwipeGestureStart")) michael@0: msg = NS_SIMPLE_GESTURE_SWIPE_START; michael@0: else if (aType.EqualsLiteral("MozSwipeGestureUpdate")) michael@0: msg = NS_SIMPLE_GESTURE_SWIPE_UPDATE; michael@0: else if (aType.EqualsLiteral("MozSwipeGestureEnd")) michael@0: msg = NS_SIMPLE_GESTURE_SWIPE_END; michael@0: else if (aType.EqualsLiteral("MozSwipeGesture")) michael@0: msg = NS_SIMPLE_GESTURE_SWIPE; michael@0: else if (aType.EqualsLiteral("MozMagnifyGestureStart")) michael@0: msg = NS_SIMPLE_GESTURE_MAGNIFY_START; michael@0: else if (aType.EqualsLiteral("MozMagnifyGestureUpdate")) michael@0: msg = NS_SIMPLE_GESTURE_MAGNIFY_UPDATE; michael@0: else if (aType.EqualsLiteral("MozMagnifyGesture")) michael@0: msg = NS_SIMPLE_GESTURE_MAGNIFY; michael@0: else if (aType.EqualsLiteral("MozRotateGestureStart")) michael@0: msg = NS_SIMPLE_GESTURE_ROTATE_START; michael@0: else if (aType.EqualsLiteral("MozRotateGestureUpdate")) michael@0: msg = NS_SIMPLE_GESTURE_ROTATE_UPDATE; michael@0: else if (aType.EqualsLiteral("MozRotateGesture")) michael@0: msg = NS_SIMPLE_GESTURE_ROTATE; michael@0: else if (aType.EqualsLiteral("MozTapGesture")) michael@0: msg = NS_SIMPLE_GESTURE_TAP; michael@0: else if (aType.EqualsLiteral("MozPressTapGesture")) michael@0: msg = NS_SIMPLE_GESTURE_PRESSTAP; michael@0: else if (aType.EqualsLiteral("MozEdgeUIStarted")) michael@0: msg = NS_SIMPLE_GESTURE_EDGE_STARTED; michael@0: else if (aType.EqualsLiteral("MozEdgeUICanceled")) michael@0: msg = NS_SIMPLE_GESTURE_EDGE_CANCELED; michael@0: else if (aType.EqualsLiteral("MozEdgeUICompleted")) michael@0: msg = NS_SIMPLE_GESTURE_EDGE_COMPLETED; michael@0: else michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: WidgetSimpleGestureEvent event(true, msg, widget); michael@0: event.modifiers = GetWidgetModifiers(aModifiers); michael@0: event.direction = aDirection; michael@0: event.delta = aDelta; michael@0: event.clickCount = aClickCount; michael@0: event.time = PR_IntervalNow(); michael@0: michael@0: nsPresContext* presContext = GetPresContext(); michael@0: if (!presContext) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: event.refPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext); michael@0: michael@0: nsEventStatus status; michael@0: return widget->DispatchEvent(&event, status); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::ElementFromPoint(float aX, float aY, michael@0: bool aIgnoreRootScrollFrame, michael@0: bool aFlushLayout, michael@0: nsIDOMElement** aReturn) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr doc = GetDocument(); michael@0: NS_ENSURE_STATE(doc); michael@0: michael@0: Element* el = michael@0: doc->ElementFromPointHelper(aX, aY, aIgnoreRootScrollFrame, aFlushLayout); michael@0: nsCOMPtr retval = do_QueryInterface(el); michael@0: retval.forget(aReturn); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::NodesFromRect(float aX, float aY, michael@0: float aTopSize, float aRightSize, michael@0: float aBottomSize, float aLeftSize, michael@0: bool aIgnoreRootScrollFrame, michael@0: bool aFlushLayout, michael@0: nsIDOMNodeList** aReturn) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr doc = GetDocument(); michael@0: NS_ENSURE_STATE(doc); michael@0: michael@0: return doc->NodesFromRectHelper(aX, aY, aTopSize, aRightSize, aBottomSize, aLeftSize, michael@0: aIgnoreRootScrollFrame, aFlushLayout, aReturn); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetTranslationNodes(nsIDOMNode* aRoot, michael@0: nsITranslationNodeList** aRetVal) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: NS_ENSURE_ARG_POINTER(aRetVal); michael@0: nsCOMPtr root = do_QueryInterface(aRoot); michael@0: NS_ENSURE_STATE(root); michael@0: nsCOMPtr doc = GetDocument(); michael@0: NS_ENSURE_STATE(doc); michael@0: michael@0: if (root->OwnerDoc() != doc) { michael@0: return NS_ERROR_DOM_WRONG_DOCUMENT_ERR; michael@0: } michael@0: michael@0: nsTHashtable> translationNodesHash(1000); michael@0: nsRefPtr list = new nsTranslationNodeList; michael@0: michael@0: uint32_t limit = 15000; michael@0: michael@0: // We begin iteration with content->GetNextNode because we want to explictly michael@0: // skip the root tag from being a translation node. michael@0: nsIContent* content = root; michael@0: while ((limit > 0) && (content = content->GetNextNode(root))) { michael@0: if (!content->IsHTML()) { michael@0: continue; michael@0: } michael@0: michael@0: nsIAtom* localName = content->Tag(); michael@0: michael@0: // Skip elements that usually contain non-translatable text content. michael@0: if (localName == nsGkAtoms::script || michael@0: localName == nsGkAtoms::iframe || michael@0: localName == nsGkAtoms::frameset || michael@0: localName == nsGkAtoms::frame || michael@0: localName == nsGkAtoms::code || michael@0: localName == nsGkAtoms::noscript || michael@0: localName == nsGkAtoms::style) { michael@0: continue; michael@0: } michael@0: michael@0: // An element is a translation node if it contains michael@0: // at least one text node that has meaningful data michael@0: // for translation michael@0: for (nsIContent* child = content->GetFirstChild(); michael@0: child; michael@0: child = child->GetNextSibling()) { michael@0: michael@0: if (child->HasTextForTranslation()) { michael@0: translationNodesHash.PutEntry(content); michael@0: michael@0: bool isBlockFrame = false; michael@0: nsIFrame* frame = content->GetPrimaryFrame(); michael@0: if (frame) { michael@0: isBlockFrame = frame->IsFrameOfType(nsIFrame::eBlockFrame); michael@0: } michael@0: michael@0: bool isTranslationRoot = isBlockFrame; michael@0: if (!isBlockFrame) { michael@0: // If an element is not a block element, it still michael@0: // can be considered a translation root if the parent michael@0: // of this element didn't make into the list of nodes michael@0: // to be translated. michael@0: bool parentInList = false; michael@0: nsIContent* parent = content->GetParent(); michael@0: if (parent) { michael@0: parentInList = translationNodesHash.Contains(parent); michael@0: } michael@0: isTranslationRoot = !parentInList; michael@0: } michael@0: michael@0: list->AppendElement(content->AsDOMNode(), isTranslationRoot); michael@0: --limit; michael@0: break; michael@0: } michael@0: } michael@0: } michael@0: michael@0: *aRetVal = list.forget().take(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: static TemporaryRef michael@0: CanvasToDataSourceSurface(nsIDOMHTMLCanvasElement* aCanvas) michael@0: { michael@0: nsCOMPtr node = do_QueryInterface(aCanvas); michael@0: if (!node) { michael@0: return nullptr; michael@0: } michael@0: michael@0: NS_ABORT_IF_FALSE(node->IsElement(), michael@0: "An nsINode that implements nsIDOMHTMLCanvasElement should " michael@0: "be an element."); michael@0: nsLayoutUtils::SurfaceFromElementResult result = michael@0: nsLayoutUtils::SurfaceFromElement(node->AsElement()); michael@0: return result.mSourceSurface->GetDataSurface(); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::CompareCanvases(nsIDOMHTMLCanvasElement *aCanvas1, michael@0: nsIDOMHTMLCanvasElement *aCanvas2, michael@0: uint32_t* aMaxDifference, michael@0: uint32_t* retVal) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: if (aCanvas1 == nullptr || michael@0: aCanvas2 == nullptr || michael@0: retVal == nullptr) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: RefPtr img1 = CanvasToDataSourceSurface(aCanvas1); michael@0: RefPtr img2 = CanvasToDataSourceSurface(aCanvas2); michael@0: michael@0: if (img1 == nullptr || img2 == nullptr || michael@0: img1->GetSize() != img2->GetSize() || michael@0: img1->Stride() != img2->Stride()) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: int v; michael@0: IntSize size = img1->GetSize(); michael@0: uint32_t stride = img1->Stride(); michael@0: michael@0: // we can optimize for the common all-pass case michael@0: if (stride == (uint32_t) size.width * 4) { michael@0: v = memcmp(img1->GetData(), img2->GetData(), size.width * size.height * 4); michael@0: if (v == 0) { michael@0: if (aMaxDifference) michael@0: *aMaxDifference = 0; michael@0: *retVal = 0; michael@0: return NS_OK; michael@0: } michael@0: } michael@0: michael@0: uint32_t dc = 0; michael@0: uint32_t different = 0; michael@0: michael@0: for (int j = 0; j < size.height; j++) { michael@0: unsigned char *p1 = img1->GetData() + j*stride; michael@0: unsigned char *p2 = img2->GetData() + j*stride; michael@0: v = memcmp(p1, p2, stride); michael@0: michael@0: if (v) { michael@0: for (int i = 0; i < size.width; i++) { michael@0: if (*(uint32_t*) p1 != *(uint32_t*) p2) { michael@0: michael@0: different++; michael@0: michael@0: dc = std::max((uint32_t)abs(p1[0] - p2[0]), dc); michael@0: dc = std::max((uint32_t)abs(p1[1] - p2[1]), dc); michael@0: dc = std::max((uint32_t)abs(p1[2] - p2[2]), dc); michael@0: dc = std::max((uint32_t)abs(p1[3] - p2[3]), dc); michael@0: } michael@0: michael@0: p1 += 4; michael@0: p2 += 4; michael@0: } michael@0: } michael@0: } michael@0: michael@0: if (aMaxDifference) michael@0: *aMaxDifference = dc; michael@0: michael@0: *retVal = different; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetIsMozAfterPaintPending(bool *aResult) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: NS_ENSURE_ARG_POINTER(aResult); michael@0: *aResult = false; michael@0: nsPresContext* presContext = GetPresContext(); michael@0: if (!presContext) michael@0: return NS_OK; michael@0: *aResult = presContext->IsDOMPaintEventPending(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::ClearMozAfterPaintEvents() michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsPresContext* presContext = GetPresContext(); michael@0: if (!presContext) michael@0: return NS_OK; michael@0: presContext->ClearMozAfterPaintEvents(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::DisableNonTestMouseEvents(bool aDisable) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr window = do_QueryReferent(mWindow); michael@0: NS_ENSURE_TRUE(window, NS_ERROR_FAILURE); michael@0: nsIDocShell *docShell = window->GetDocShell(); michael@0: NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE); michael@0: nsCOMPtr presShell = docShell->GetPresShell(); michael@0: NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE); michael@0: presShell->DisableNonTestMouseEvents(aDisable); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SuppressEventHandling(bool aSuppress) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr doc = GetDocument(); michael@0: NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE); michael@0: michael@0: if (aSuppress) { michael@0: doc->SuppressEventHandling(nsIDocument::eEvents); michael@0: } else { michael@0: doc->UnsuppressEventHandlingAndFireEvents(nsIDocument::eEvents, true); michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: static nsresult michael@0: getScrollXYAppUnits(nsWeakPtr aWindow, bool aFlushLayout, nsPoint& aScrollPos) { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr window = do_QueryReferent(aWindow); michael@0: nsCOMPtr doc = window ? window->GetExtantDoc() : nullptr; michael@0: NS_ENSURE_STATE(doc); michael@0: michael@0: if (aFlushLayout) { michael@0: doc->FlushPendingNotifications(Flush_Layout); michael@0: } michael@0: michael@0: nsIPresShell *presShell = doc->GetShell(); michael@0: if (presShell) { michael@0: nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable(); michael@0: if (sf) { michael@0: aScrollPos = sf->GetScrollPosition(); michael@0: } michael@0: } michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetScrollXY(bool aFlushLayout, int32_t* aScrollX, int32_t* aScrollY) michael@0: { michael@0: nsPoint scrollPos(0,0); michael@0: nsresult rv = getScrollXYAppUnits(mWindow, aFlushLayout, scrollPos); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: *aScrollX = nsPresContext::AppUnitsToIntCSSPixels(scrollPos.x); michael@0: *aScrollY = nsPresContext::AppUnitsToIntCSSPixels(scrollPos.y); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetScrollXYFloat(bool aFlushLayout, float* aScrollX, float* aScrollY) michael@0: { michael@0: nsPoint scrollPos(0,0); michael@0: nsresult rv = getScrollXYAppUnits(mWindow, aFlushLayout, scrollPos); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: *aScrollX = nsPresContext::AppUnitsToFloatCSSPixels(scrollPos.x); michael@0: *aScrollY = nsPresContext::AppUnitsToFloatCSSPixels(scrollPos.y); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetScrollbarSize(bool aFlushLayout, int32_t* aWidth, michael@0: int32_t* aHeight) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: *aWidth = 0; michael@0: *aHeight = 0; michael@0: michael@0: nsCOMPtr doc = GetDocument(); michael@0: NS_ENSURE_STATE(doc); michael@0: michael@0: if (aFlushLayout) { michael@0: doc->FlushPendingNotifications(Flush_Layout); michael@0: } michael@0: michael@0: nsIPresShell* presShell = doc->GetShell(); michael@0: NS_ENSURE_TRUE(presShell, NS_ERROR_NOT_AVAILABLE); michael@0: michael@0: nsIScrollableFrame* scrollFrame = presShell->GetRootScrollFrameAsScrollable(); michael@0: NS_ENSURE_TRUE(scrollFrame, NS_OK); michael@0: michael@0: nsMargin sizes = scrollFrame->GetActualScrollbarSizes(); michael@0: *aWidth = nsPresContext::AppUnitsToIntCSSPixels(sizes.LeftRight()); michael@0: *aHeight = nsPresContext::AppUnitsToIntCSSPixels(sizes.TopBottom()); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetBoundsWithoutFlushing(nsIDOMElement *aElement, michael@0: nsIDOMClientRect** aResult) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr window = do_QueryReferent(mWindow); michael@0: NS_ENSURE_STATE(window); michael@0: michael@0: nsresult rv; michael@0: nsCOMPtr content = do_QueryInterface(aElement, &rv); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: nsRefPtr rect = new DOMRect(window); michael@0: nsIFrame* frame = content->GetPrimaryFrame(); michael@0: michael@0: if (frame) { michael@0: nsRect r = nsLayoutUtils::GetAllInFlowRectsUnion(frame, michael@0: nsLayoutUtils::GetContainingBlockForClientRect(frame), michael@0: nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS); michael@0: rect->SetLayoutRect(r); michael@0: } michael@0: michael@0: rect.forget(aResult); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetRootBounds(nsIDOMClientRect** aResult) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsIDocument* doc = GetDocument(); michael@0: NS_ENSURE_STATE(doc); michael@0: michael@0: nsRect bounds(0, 0, 0, 0); michael@0: nsIPresShell* presShell = doc->GetShell(); michael@0: if (presShell) { michael@0: nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable(); michael@0: if (sf) { michael@0: bounds = sf->GetScrollRange(); michael@0: bounds.width += sf->GetScrollPortRect().width; michael@0: bounds.height += sf->GetScrollPortRect().height; michael@0: } else if (presShell->GetRootFrame()) { michael@0: bounds = presShell->GetRootFrame()->GetRect(); michael@0: } michael@0: } michael@0: michael@0: nsCOMPtr window = do_QueryReferent(mWindow); michael@0: nsRefPtr rect = new DOMRect(window); michael@0: rect->SetRect(nsPresContext::AppUnitsToFloatCSSPixels(bounds.x), michael@0: nsPresContext::AppUnitsToFloatCSSPixels(bounds.y), michael@0: nsPresContext::AppUnitsToFloatCSSPixels(bounds.width), michael@0: nsPresContext::AppUnitsToFloatCSSPixels(bounds.height)); michael@0: rect.forget(aResult); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetIMEIsOpen(bool *aState) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: NS_ENSURE_ARG_POINTER(aState); michael@0: michael@0: nsCOMPtr widget = GetWidget(); michael@0: if (!widget) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: // Open state should not be available when IME is not enabled. michael@0: InputContext context = widget->GetInputContext(); michael@0: if (context.mIMEState.mEnabled != IMEState::ENABLED) { michael@0: return NS_ERROR_NOT_AVAILABLE; michael@0: } michael@0: michael@0: if (context.mIMEState.mOpen == IMEState::OPEN_STATE_NOT_SUPPORTED) { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: *aState = (context.mIMEState.mOpen == IMEState::OPEN); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetIMEStatus(uint32_t *aState) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: NS_ENSURE_ARG_POINTER(aState); michael@0: michael@0: nsCOMPtr widget = GetWidget(); michael@0: if (!widget) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: InputContext context = widget->GetInputContext(); michael@0: *aState = static_cast(context.mIMEState.mEnabled); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetFocusedInputType(char** aType) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: NS_ENSURE_ARG_POINTER(aType); michael@0: michael@0: nsCOMPtr widget = GetWidget(); michael@0: if (!widget) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: InputContext context = widget->GetInputContext(); michael@0: *aType = ToNewCString(context.mHTMLInputType); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::FindElementWithViewId(nsViewID aID, michael@0: nsIDOMElement** aResult) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsRefPtr content = nsLayoutUtils::FindContentFor(aID); michael@0: return content ? CallQueryInterface(content, aResult) : NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetViewId(nsIDOMElement* aElement, nsViewID* aResult) michael@0: { michael@0: nsCOMPtr content = do_QueryInterface(aElement); michael@0: if (content && nsLayoutUtils::FindIDFor(content, aResult)) { michael@0: return NS_OK; michael@0: } michael@0: return NS_ERROR_NOT_AVAILABLE; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetScreenPixelsPerCSSPixel(float* aScreenPixels) michael@0: { michael@0: nsCOMPtr window = do_QueryReferent(mWindow); michael@0: NS_ENSURE_TRUE(window, NS_ERROR_FAILURE); michael@0: return window->GetDevicePixelRatio(aScreenPixels); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetFullZoom(float* aFullZoom) michael@0: { michael@0: *aFullZoom = 1.0f; michael@0: michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsPresContext* presContext = GetPresContext(); michael@0: if (!presContext) { michael@0: return NS_OK; michael@0: } michael@0: michael@0: *aFullZoom = presContext->DeviceContext()->GetPixelScale(); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::DispatchDOMEventViaPresShell(nsIDOMNode* aTarget, michael@0: nsIDOMEvent* aEvent, michael@0: bool aTrusted, michael@0: bool* aRetVal) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: NS_ENSURE_STATE(aEvent); michael@0: aEvent->SetTrusted(aTrusted); michael@0: WidgetEvent* internalEvent = aEvent->GetInternalNSEvent(); michael@0: NS_ENSURE_STATE(internalEvent); michael@0: nsCOMPtr content = do_QueryInterface(aTarget); michael@0: NS_ENSURE_STATE(content); michael@0: nsCOMPtr window = do_QueryReferent(mWindow); michael@0: if (content->OwnerDoc()->GetWindow() != window) { michael@0: return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR; michael@0: } michael@0: nsCOMPtr targetDoc = content->GetCurrentDoc(); michael@0: NS_ENSURE_STATE(targetDoc); michael@0: nsRefPtr targetShell = targetDoc->GetShell(); michael@0: NS_ENSURE_STATE(targetShell); michael@0: michael@0: targetDoc->FlushPendingNotifications(Flush_Layout); michael@0: michael@0: nsEventStatus status = nsEventStatus_eIgnore; michael@0: targetShell->HandleEventWithTarget(internalEvent, nullptr, content, &status); michael@0: *aRetVal = (status != nsEventStatus_eConsumeNoDefault); michael@0: return NS_OK; michael@0: } michael@0: michael@0: static void michael@0: InitEvent(WidgetGUIEvent& aEvent, LayoutDeviceIntPoint* aPt = nullptr) michael@0: { michael@0: if (aPt) { michael@0: aEvent.refPoint = *aPt; michael@0: } michael@0: aEvent.time = PR_IntervalNow(); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SendCompositionEvent(const nsAString& aType, michael@0: const nsAString& aData, michael@0: const nsAString& aLocale) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: // get the widget to send the event to michael@0: nsCOMPtr widget = GetWidget(); michael@0: if (!widget) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: uint32_t msg; michael@0: if (aType.EqualsLiteral("compositionstart")) { michael@0: msg = NS_COMPOSITION_START; michael@0: } else if (aType.EqualsLiteral("compositionend")) { michael@0: msg = NS_COMPOSITION_END; michael@0: } else if (aType.EqualsLiteral("compositionupdate")) { michael@0: msg = NS_COMPOSITION_UPDATE; michael@0: } else { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: WidgetCompositionEvent compositionEvent(true, msg, widget); michael@0: InitEvent(compositionEvent); michael@0: if (msg != NS_COMPOSITION_START) { michael@0: compositionEvent.data = aData; michael@0: } michael@0: michael@0: compositionEvent.mFlags.mIsSynthesizedForTests = true; michael@0: michael@0: nsEventStatus status; michael@0: nsresult rv = widget->DispatchEvent(&compositionEvent, status); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::CreateCompositionStringSynthesizer( michael@0: nsICompositionStringSynthesizer** aResult) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aResult); michael@0: *aResult = nullptr; michael@0: michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr window = do_QueryReferent(mWindow); michael@0: NS_ENSURE_TRUE(window, NS_ERROR_NOT_AVAILABLE); michael@0: michael@0: NS_ADDREF(*aResult = new CompositionStringSynthesizer(window)); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SendQueryContentEvent(uint32_t aType, michael@0: uint32_t aOffset, uint32_t aLength, michael@0: int32_t aX, int32_t aY, michael@0: uint32_t aAdditionalFlags, michael@0: nsIQueryContentEventResult **aResult) michael@0: { michael@0: *aResult = nullptr; michael@0: michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr window = do_QueryReferent(mWindow); michael@0: NS_ENSURE_TRUE(window, NS_ERROR_FAILURE); michael@0: michael@0: nsIDocShell *docShell = window->GetDocShell(); michael@0: NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE); michael@0: michael@0: nsCOMPtr presShell = docShell->GetPresShell(); michael@0: NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE); michael@0: michael@0: nsPresContext* presContext = presShell->GetPresContext(); michael@0: NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE); michael@0: michael@0: // get the widget to send the event to michael@0: nsCOMPtr widget = GetWidget(); michael@0: if (!widget) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: if (aType != NS_QUERY_SELECTED_TEXT && michael@0: aType != NS_QUERY_TEXT_CONTENT && michael@0: aType != NS_QUERY_CARET_RECT && michael@0: aType != NS_QUERY_TEXT_RECT && michael@0: aType != NS_QUERY_EDITOR_RECT && michael@0: aType != NS_QUERY_CHARACTER_AT_POINT) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: nsCOMPtr targetWidget = widget; michael@0: LayoutDeviceIntPoint pt(aX, aY); michael@0: michael@0: bool useNativeLineBreak = michael@0: !(aAdditionalFlags & QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK); michael@0: michael@0: if (aType == QUERY_CHARACTER_AT_POINT) { michael@0: // Looking for the widget at the point. michael@0: WidgetQueryContentEvent dummyEvent(true, NS_QUERY_CONTENT_STATE, widget); michael@0: dummyEvent.mUseNativeLineBreak = useNativeLineBreak; michael@0: InitEvent(dummyEvent, &pt); michael@0: nsIFrame* popupFrame = michael@0: nsLayoutUtils::GetPopupFrameForEventCoordinates(presContext->GetRootPresContext(), &dummyEvent); michael@0: michael@0: nsIntRect widgetBounds; michael@0: nsresult rv = widget->GetClientBounds(widgetBounds); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: widgetBounds.MoveTo(0, 0); michael@0: michael@0: // There is no popup frame at the point and the point isn't in our widget, michael@0: // we cannot process this request. michael@0: NS_ENSURE_TRUE(popupFrame || michael@0: widgetBounds.Contains(LayoutDeviceIntPoint::ToUntyped(pt)), michael@0: NS_ERROR_FAILURE); michael@0: michael@0: // Fire the event on the widget at the point michael@0: if (popupFrame) { michael@0: targetWidget = popupFrame->GetNearestWidget(); michael@0: } michael@0: } michael@0: michael@0: pt += LayoutDeviceIntPoint::FromUntyped( michael@0: widget->WidgetToScreenOffset() - targetWidget->WidgetToScreenOffset()); michael@0: michael@0: WidgetQueryContentEvent queryEvent(true, aType, targetWidget); michael@0: InitEvent(queryEvent, &pt); michael@0: michael@0: switch (aType) { michael@0: case NS_QUERY_TEXT_CONTENT: michael@0: queryEvent.InitForQueryTextContent(aOffset, aLength, useNativeLineBreak); michael@0: break; michael@0: case NS_QUERY_CARET_RECT: michael@0: queryEvent.InitForQueryCaretRect(aOffset, useNativeLineBreak); michael@0: break; michael@0: case NS_QUERY_TEXT_RECT: michael@0: queryEvent.InitForQueryTextRect(aOffset, aLength, useNativeLineBreak); michael@0: break; michael@0: default: michael@0: queryEvent.mUseNativeLineBreak = useNativeLineBreak; michael@0: break; michael@0: } michael@0: michael@0: nsEventStatus status; michael@0: nsresult rv = targetWidget->DispatchEvent(&queryEvent, status); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: nsQueryContentEventResult* result = new nsQueryContentEventResult(); michael@0: NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY); michael@0: result->SetEventResult(widget, queryEvent); michael@0: NS_ADDREF(*aResult = result); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SendSelectionSetEvent(uint32_t aOffset, michael@0: uint32_t aLength, michael@0: uint32_t aAdditionalFlags, michael@0: bool *aResult) michael@0: { michael@0: *aResult = false; michael@0: michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: // get the widget to send the event to michael@0: nsCOMPtr widget = GetWidget(); michael@0: if (!widget) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: WidgetSelectionEvent selectionEvent(true, NS_SELECTION_SET, widget); michael@0: InitEvent(selectionEvent); michael@0: michael@0: selectionEvent.mOffset = aOffset; michael@0: selectionEvent.mLength = aLength; michael@0: selectionEvent.mReversed = (aAdditionalFlags & SELECTION_SET_FLAG_REVERSE); michael@0: selectionEvent.mUseNativeLineBreak = michael@0: !(aAdditionalFlags & SELECTION_SET_FLAG_USE_XP_LINE_BREAK); michael@0: michael@0: nsEventStatus status; michael@0: nsresult rv = widget->DispatchEvent(&selectionEvent, status); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: *aResult = selectionEvent.mSucceeded; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SendContentCommandEvent(const nsAString& aType, michael@0: nsITransferable * aTransferable) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: // get the widget to send the event to michael@0: nsCOMPtr widget = GetWidget(); michael@0: if (!widget) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: int32_t msg; michael@0: if (aType.EqualsLiteral("cut")) michael@0: msg = NS_CONTENT_COMMAND_CUT; michael@0: else if (aType.EqualsLiteral("copy")) michael@0: msg = NS_CONTENT_COMMAND_COPY; michael@0: else if (aType.EqualsLiteral("paste")) michael@0: msg = NS_CONTENT_COMMAND_PASTE; michael@0: else if (aType.EqualsLiteral("delete")) michael@0: msg = NS_CONTENT_COMMAND_DELETE; michael@0: else if (aType.EqualsLiteral("undo")) michael@0: msg = NS_CONTENT_COMMAND_UNDO; michael@0: else if (aType.EqualsLiteral("redo")) michael@0: msg = NS_CONTENT_COMMAND_REDO; michael@0: else if (aType.EqualsLiteral("pasteTransferable")) michael@0: msg = NS_CONTENT_COMMAND_PASTE_TRANSFERABLE; michael@0: else michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: WidgetContentCommandEvent event(true, msg, widget); michael@0: if (msg == NS_CONTENT_COMMAND_PASTE_TRANSFERABLE) { michael@0: event.mTransferable = aTransferable; michael@0: } michael@0: michael@0: nsEventStatus status; michael@0: return widget->DispatchEvent(&event, status); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetClassName(JS::Handle aObject, JSContext* aCx, michael@0: char** aName) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: // Our argument must be a non-null object. michael@0: if (JSVAL_IS_PRIMITIVE(aObject)) { michael@0: return NS_ERROR_XPC_BAD_CONVERT_JS; michael@0: } michael@0: michael@0: *aName = NS_strdup(JS_GetClass(JSVAL_TO_OBJECT(aObject))->name); michael@0: NS_ABORT_IF_FALSE(*aName, "NS_strdup should be infallible."); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetVisitedDependentComputedStyle( michael@0: nsIDOMElement *aElement, const nsAString& aPseudoElement, michael@0: const nsAString& aPropertyName, nsAString& aResult) michael@0: { michael@0: aResult.Truncate(); michael@0: michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr window = do_QueryReferent(mWindow); michael@0: NS_ENSURE_STATE(window); michael@0: michael@0: nsCOMPtr decl; michael@0: nsresult rv = michael@0: window->GetComputedStyle(aElement, aPseudoElement, getter_AddRefs(decl)); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: static_cast(decl.get())->SetExposeVisitedStyle(true); michael@0: rv = decl->GetPropertyValue(aPropertyName, aResult); michael@0: static_cast(decl.get())->SetExposeVisitedStyle(false); michael@0: michael@0: return rv; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::EnterModalState() michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr window = do_QueryReferent(mWindow); michael@0: NS_ENSURE_STATE(window); michael@0: michael@0: window->EnterModalState(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::LeaveModalState() michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr window = do_QueryReferent(mWindow); michael@0: NS_ENSURE_STATE(window); michael@0: michael@0: window->LeaveModalState(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::IsInModalState(bool *retval) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr window = do_QueryReferent(mWindow); michael@0: NS_ENSURE_STATE(window); michael@0: michael@0: *retval = static_cast(window.get())->IsInModalState(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetParent(JS::Handle aObject, michael@0: JSContext* aCx, michael@0: JS::MutableHandle aParent) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: // First argument must be an object. michael@0: if (aObject.isPrimitive()) { michael@0: return NS_ERROR_XPC_BAD_CONVERT_JS; michael@0: } michael@0: michael@0: JS::Rooted parent(aCx, JS_GetParent(&aObject.toObject())); michael@0: michael@0: // Outerize if necessary. michael@0: if (parent) { michael@0: if (JSObjectOp outerize = js::GetObjectClass(parent)->ext.outerObject) { michael@0: parent = outerize(aCx, parent); michael@0: } michael@0: } michael@0: michael@0: aParent.setObject(*parent); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetOuterWindowID(uint64_t *aWindowID) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr window = do_QueryReferent(mWindow); michael@0: NS_ENSURE_STATE(window); michael@0: michael@0: NS_ASSERTION(window->IsOuterWindow(), "How did that happen?"); michael@0: *aWindowID = window->WindowID(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetCurrentInnerWindowID(uint64_t *aWindowID) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr window = do_QueryReferent(mWindow); michael@0: NS_ENSURE_TRUE(window, NS_ERROR_NOT_AVAILABLE); michael@0: michael@0: NS_ASSERTION(window->IsOuterWindow(), "How did that happen?"); michael@0: nsGlobalWindow* inner = michael@0: static_cast(window.get())->GetCurrentInnerWindowInternal(); michael@0: if (!inner) { michael@0: return NS_ERROR_NOT_AVAILABLE; michael@0: } michael@0: *aWindowID = inner->WindowID(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SuspendTimeouts() michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr window = do_QueryReferent(mWindow); michael@0: NS_ENSURE_TRUE(window, NS_ERROR_FAILURE); michael@0: michael@0: window->SuspendTimeouts(); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::ResumeTimeouts() michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr window = do_QueryReferent(mWindow); michael@0: NS_ENSURE_TRUE(window, NS_ERROR_FAILURE); michael@0: michael@0: window->ResumeTimeouts(); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetLayerManagerType(nsAString& aType) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr widget = GetWidget(); michael@0: if (!widget) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: LayerManager *mgr = widget->GetLayerManager(nsIWidget::LAYER_MANAGER_PERSISTENT); michael@0: if (!mgr) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: mgr->GetBackendName(aType); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetLayerManagerRemote(bool* retval) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr widget = GetWidget(); michael@0: if (!widget) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: LayerManager *mgr = widget->GetLayerManager(); michael@0: if (!mgr) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: *retval = !!mgr->AsShadowForwarder(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::StartFrameTimeRecording(uint32_t *startIndex) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: NS_ENSURE_ARG_POINTER(startIndex); michael@0: michael@0: nsCOMPtr widget = GetWidget(); michael@0: if (!widget) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: LayerManager *mgr = widget->GetLayerManager(); michael@0: if (!mgr) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: const uint32_t kRecordingMinSize = 60 * 10; // 10 seconds @60 fps. michael@0: const uint32_t kRecordingMaxSize = 60 * 60 * 60; // One hour michael@0: uint32_t bufferSize = Preferences::GetUint("toolkit.framesRecording.bufferSize", uint32_t(0)); michael@0: bufferSize = std::min(bufferSize, kRecordingMaxSize); michael@0: bufferSize = std::max(bufferSize, kRecordingMinSize); michael@0: *startIndex = mgr->StartFrameTimeRecording(bufferSize); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::StopFrameTimeRecording(uint32_t startIndex, michael@0: uint32_t *frameCount, michael@0: float **frameIntervals) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: NS_ENSURE_ARG_POINTER(frameCount); michael@0: NS_ENSURE_ARG_POINTER(frameIntervals); michael@0: michael@0: nsCOMPtr widget = GetWidget(); michael@0: if (!widget) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: LayerManager *mgr = widget->GetLayerManager(); michael@0: if (!mgr) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: nsTArray tmpFrameIntervals; michael@0: mgr->StopFrameTimeRecording(startIndex, tmpFrameIntervals); michael@0: *frameCount = tmpFrameIntervals.Length(); michael@0: michael@0: *frameIntervals = (float*)nsMemory::Alloc(*frameCount * sizeof(float)); michael@0: michael@0: /* copy over the frame intervals and paint times into the arrays we just allocated */ michael@0: for (uint32_t i = 0; i < *frameCount; i++) { michael@0: (*frameIntervals)[i] = tmpFrameIntervals[i]; michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::BeginTabSwitch() michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr widget = GetWidget(); michael@0: if (!widget) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: LayerManager *mgr = widget->GetLayerManager(); michael@0: if (!mgr) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: mgr->BeginTabSwitch(); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: static bool michael@0: ComputeAnimationValue(nsCSSProperty aProperty, michael@0: Element* aElement, michael@0: const nsAString& aInput, michael@0: nsStyleAnimation::Value& aOutput) michael@0: { michael@0: michael@0: if (!nsStyleAnimation::ComputeValue(aProperty, aElement, aInput, michael@0: false, aOutput)) { michael@0: return false; michael@0: } michael@0: michael@0: // This matches TransExtractComputedValue in nsTransitionManager.cpp. michael@0: if (aProperty == eCSSProperty_visibility) { michael@0: NS_ABORT_IF_FALSE(aOutput.GetUnit() == nsStyleAnimation::eUnit_Enumerated, michael@0: "unexpected unit"); michael@0: aOutput.SetIntValue(aOutput.GetIntValue(), michael@0: nsStyleAnimation::eUnit_Visibility); michael@0: } michael@0: michael@0: return true; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::AdvanceTimeAndRefresh(int64_t aMilliseconds) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsRefreshDriver* driver = GetPresContext()->RefreshDriver(); michael@0: driver->AdvanceTimeAndRefresh(aMilliseconds); michael@0: michael@0: LayerTransactionChild* transaction = GetLayerTransaction(); michael@0: if (transaction) { michael@0: transaction->SendSetTestSampleTime(driver->MostRecentRefresh()); michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::RestoreNormalRefresh() michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: // Kick the compositor out of test mode before the refresh driver, so that michael@0: // the refresh driver doesn't send an update that gets ignored by the michael@0: // compositor. michael@0: LayerTransactionChild* transaction = GetLayerTransaction(); michael@0: if (transaction) { michael@0: transaction->SendLeaveTestMode(); michael@0: } michael@0: michael@0: nsRefreshDriver* driver = GetPresContext()->RefreshDriver(); michael@0: driver->RestoreNormalRefresh(); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetIsTestControllingRefreshes(bool *aResult) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsPresContext* pc = GetPresContext(); michael@0: *aResult = michael@0: pc ? pc->RefreshDriver()->IsTestControllingRefreshesEnabled() : false; michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SetAsyncScrollOffset(nsIDOMNode* aNode, michael@0: int32_t aX, int32_t aY) michael@0: { michael@0: nsCOMPtr element = do_QueryInterface(aNode); michael@0: if (!element) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: nsIFrame* frame = element->GetPrimaryFrame(); michael@0: if (!frame) { michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: nsIScrollableFrame* scrollable = do_QueryFrame(frame); michael@0: nsPresContext* presContext = frame->PresContext(); michael@0: nsIFrame* rootScrollFrame = presContext->PresShell()->GetRootScrollFrame(); michael@0: if (!scrollable) { michael@0: if (rootScrollFrame && rootScrollFrame->GetContent() == element) { michael@0: frame = rootScrollFrame; michael@0: scrollable = do_QueryFrame(frame); michael@0: } michael@0: } michael@0: if (!scrollable) { michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: Layer* layer = FrameLayerBuilder::GetDedicatedLayer(scrollable->GetScrolledFrame(), michael@0: nsDisplayItem::TYPE_SCROLL_LAYER); michael@0: if (!layer) { michael@0: if (rootScrollFrame == frame && !presContext->GetParentPresContext()) { michael@0: nsIWidget* widget = GetWidget(); michael@0: if (widget) { michael@0: LayerManager* manager = widget->GetLayerManager(); michael@0: if (manager) { michael@0: layer = manager->GetRoot(); michael@0: } michael@0: } michael@0: } michael@0: if (!layer) { michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: } michael@0: ShadowLayerForwarder* forwarder = layer->Manager()->AsShadowForwarder(); michael@0: if (!forwarder || !forwarder->HasShadowManager()) { michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: forwarder->GetShadowManager()->SendSetAsyncScrollOffset( michael@0: layer->AsShadowableLayer()->GetShadow(), aX, aY); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::ComputeAnimationDistance(nsIDOMElement* aElement, michael@0: const nsAString& aProperty, michael@0: const nsAString& aValue1, michael@0: const nsAString& aValue2, michael@0: double* aResult) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsresult rv; michael@0: nsCOMPtr content = do_QueryInterface(aElement, &rv); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: // Convert direction-dependent properties as appropriate, e.g., michael@0: // border-left to border-left-value. michael@0: nsCSSProperty property = michael@0: nsCSSProps::LookupProperty(aProperty, nsCSSProps::eIgnoreEnabledState); michael@0: if (property != eCSSProperty_UNKNOWN && nsCSSProps::IsShorthand(property)) { michael@0: nsCSSProperty subprop0 = *nsCSSProps::SubpropertyEntryFor(property); michael@0: if (nsCSSProps::PropHasFlags(subprop0, CSS_PROPERTY_REPORT_OTHER_NAME) && michael@0: nsCSSProps::OtherNameFor(subprop0) == property) { michael@0: property = subprop0; michael@0: } else { michael@0: property = eCSSProperty_UNKNOWN; michael@0: } michael@0: } michael@0: michael@0: NS_ABORT_IF_FALSE(property == eCSSProperty_UNKNOWN || michael@0: !nsCSSProps::IsShorthand(property), michael@0: "should not have shorthand"); michael@0: michael@0: nsStyleAnimation::Value v1, v2; michael@0: if (property == eCSSProperty_UNKNOWN || michael@0: !ComputeAnimationValue(property, content->AsElement(), aValue1, v1) || michael@0: !ComputeAnimationValue(property, content->AsElement(), aValue2, v2)) { michael@0: return NS_ERROR_ILLEGAL_VALUE; michael@0: } michael@0: michael@0: if (!nsStyleAnimation::ComputeDistance(property, v1, v2, *aResult)) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: nsDOMWindowUtils::RenderDocument(const nsRect& aRect, michael@0: uint32_t aFlags, michael@0: nscolor aBackgroundColor, michael@0: gfxContext* aThebesContext) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr doc = GetDocument(); michael@0: NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE); michael@0: michael@0: // Get Primary Shell michael@0: nsCOMPtr presShell = doc->GetShell(); michael@0: NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE); michael@0: michael@0: // Render Document michael@0: return presShell->RenderDocument(aRect, aFlags, aBackgroundColor, aThebesContext); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetCursorType(int16_t *aCursor) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: NS_ENSURE_ARG_POINTER(aCursor); michael@0: michael@0: nsIDocument* doc = GetDocument(); michael@0: NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE); michael@0: michael@0: bool isSameDoc = false; michael@0: do { michael@0: if (EventStateManager::sMouseOverDocument == doc) { michael@0: isSameDoc = true; michael@0: break; michael@0: } michael@0: } while ((doc = doc->GetParentDocument())); michael@0: michael@0: if (!isSameDoc) { michael@0: *aCursor = eCursor_none; michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsCOMPtr widget = GetWidget(); michael@0: if (!widget) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: // fetch cursor value from window's widget michael@0: *aCursor = widget->GetCursor(); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetDisplayDPI(float *aDPI) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr widget = GetWidget(); michael@0: if (!widget) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: *aDPI = widget->GetDPI(); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetOuterWindowWithId(uint64_t aWindowID, michael@0: nsIDOMWindow** aWindow) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: // XXX This method is deprecated. See bug 865664. michael@0: nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, michael@0: NS_LITERAL_CSTRING("DOM"), michael@0: nsContentUtils::GetDocumentFromCaller(), michael@0: nsContentUtils::eDOM_PROPERTIES, michael@0: "GetWindowWithOuterIdWarning"); michael@0: michael@0: *aWindow = nsGlobalWindow::GetOuterWindowWithId(aWindowID); michael@0: NS_IF_ADDREF(*aWindow); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetContainerElement(nsIDOMElement** aResult) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr window = do_QueryReferent(mWindow); michael@0: NS_ENSURE_STATE(window); michael@0: michael@0: nsCOMPtr element = michael@0: do_QueryInterface(window->GetFrameElementInternal()); michael@0: michael@0: element.forget(aResult); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::WrapDOMFile(nsIFile *aFile, michael@0: nsIDOMFile **aDOMFile) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: if (!aFile) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: NS_ADDREF(*aDOMFile = new nsDOMFileFile(aFile)); michael@0: return NS_OK; michael@0: } michael@0: michael@0: #ifdef DEBUG michael@0: static bool michael@0: CheckLeafLayers(Layer* aLayer, const nsIntPoint& aOffset, nsIntRegion* aCoveredRegion) michael@0: { michael@0: gfx::Matrix transform; michael@0: if (!aLayer->GetTransform().Is2D(&transform) || michael@0: transform.HasNonIntegerTranslation()) michael@0: return false; michael@0: transform.NudgeToIntegers(); michael@0: nsIntPoint offset = aOffset + nsIntPoint(transform._31, transform._32); michael@0: michael@0: Layer* child = aLayer->GetFirstChild(); michael@0: if (child) { michael@0: while (child) { michael@0: if (!CheckLeafLayers(child, offset, aCoveredRegion)) michael@0: return false; michael@0: child = child->GetNextSibling(); michael@0: } michael@0: } else { michael@0: nsIntRegion rgn = aLayer->GetVisibleRegion(); michael@0: rgn.MoveBy(offset); michael@0: nsIntRegion tmp; michael@0: tmp.And(rgn, *aCoveredRegion); michael@0: if (!tmp.IsEmpty()) michael@0: return false; michael@0: aCoveredRegion->Or(*aCoveredRegion, rgn); michael@0: } michael@0: michael@0: return true; michael@0: } michael@0: #endif michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::LeafLayersPartitionWindow(bool* aResult) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: *aResult = true; michael@0: #ifdef DEBUG michael@0: nsIWidget* widget = GetWidget(); michael@0: if (!widget) michael@0: return NS_ERROR_FAILURE; michael@0: LayerManager* manager = widget->GetLayerManager(); michael@0: if (!manager) michael@0: return NS_ERROR_FAILURE; michael@0: nsPresContext* presContext = GetPresContext(); michael@0: if (!presContext) michael@0: return NS_ERROR_FAILURE; michael@0: Layer* root = manager->GetRoot(); michael@0: if (!root) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: nsIntPoint offset(0, 0); michael@0: nsIntRegion coveredRegion; michael@0: if (!CheckLeafLayers(root, offset, &coveredRegion)) { michael@0: *aResult = false; michael@0: } michael@0: if (!coveredRegion.IsEqual(root->GetVisibleRegion())) { michael@0: *aResult = false; michael@0: } michael@0: #endif michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetMayHaveTouchEventListeners(bool* aResult) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr window = do_QueryReferent(mWindow); michael@0: NS_ENSURE_TRUE(window, NS_ERROR_FAILURE); michael@0: michael@0: nsPIDOMWindow* innerWindow = window->GetCurrentInnerWindow(); michael@0: *aResult = innerWindow ? innerWindow->HasTouchEventListeners() : false; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::CheckAndClearPaintedState(nsIDOMElement* aElement, bool* aResult) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: if (!aElement) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: nsresult rv; michael@0: nsCOMPtr content = do_QueryInterface(aElement, &rv); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: nsIFrame* frame = content->GetPrimaryFrame(); michael@0: michael@0: if (!frame) { michael@0: *aResult = false; michael@0: return NS_OK; michael@0: } michael@0: michael@0: *aResult = frame->CheckAndClearPaintedState(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::EnableDialogs() michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr window = do_QueryReferent(mWindow); michael@0: NS_ENSURE_TRUE(window, NS_ERROR_FAILURE); michael@0: michael@0: static_cast(window.get())->EnableDialogs(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::DisableDialogs() michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr window = do_QueryReferent(mWindow); michael@0: NS_ENSURE_TRUE(window, NS_ERROR_FAILURE); michael@0: michael@0: static_cast(window.get())->DisableDialogs(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::AreDialogsEnabled(bool* aResult) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr window = do_QueryReferent(mWindow); michael@0: NS_ENSURE_TRUE(window, NS_ERROR_FAILURE); michael@0: michael@0: *aResult = static_cast(window.get())->AreDialogsEnabled(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: static nsIDOMBlob* michael@0: GetXPConnectNative(JSContext* aCx, JSObject* aObj) { michael@0: nsCOMPtr blob = do_QueryInterface( michael@0: nsContentUtils::XPConnect()->GetNativeOfWrapper(aCx, aObj)); michael@0: return blob; michael@0: } michael@0: michael@0: static nsresult michael@0: GetFileOrBlob(const nsAString& aName, JS::Handle aBlobParts, michael@0: JS::Handle aParameters, JSContext* aCx, michael@0: uint8_t aOptionalArgCount, nsISupports** aResult) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsresult rv; michael@0: michael@0: nsCOMPtr file; michael@0: michael@0: if (aName.IsVoid()) { michael@0: rv = nsDOMMultipartFile::NewBlob(getter_AddRefs(file)); michael@0: } michael@0: else { michael@0: rv = nsDOMMultipartFile::NewFile(aName, getter_AddRefs(file)); michael@0: } michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: nsDOMMultipartFile* domFile = michael@0: static_cast(static_cast(file.get())); michael@0: michael@0: JS::AutoValueArray<2> args(aCx); michael@0: args[0].set(aBlobParts); michael@0: args[1].set(aParameters); michael@0: michael@0: rv = domFile->InitBlob(aCx, aOptionalArgCount, args.begin(), GetXPConnectNative); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: file.forget(aResult); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetFile(const nsAString& aName, JS::Handle aBlobParts, michael@0: JS::Handle aParameters, JSContext* aCx, michael@0: uint8_t aOptionalArgCount, nsIDOMFile** aResult) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr file; michael@0: nsresult rv = GetFileOrBlob(aName, aBlobParts, aParameters, aCx, michael@0: aOptionalArgCount, getter_AddRefs(file)); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: nsCOMPtr result = do_QueryInterface(file); michael@0: result.forget(aResult); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetBlob(JS::Handle aBlobParts, michael@0: JS::Handle aParameters, JSContext* aCx, michael@0: uint8_t aOptionalArgCount, nsIDOMBlob** aResult) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr blob; michael@0: nsresult rv = GetFileOrBlob(NullString(), aBlobParts, aParameters, aCx, michael@0: aOptionalArgCount, getter_AddRefs(blob)); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: nsCOMPtr result = do_QueryInterface(blob); michael@0: result.forget(aResult); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetFileId(JS::Handle aFile, JSContext* aCx, michael@0: int64_t* aResult) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: if (!JSVAL_IS_PRIMITIVE(aFile)) { michael@0: JSObject* obj = JSVAL_TO_OBJECT(aFile); michael@0: michael@0: file::FileHandle* fileHandle; michael@0: if (NS_SUCCEEDED(UNWRAP_OBJECT(FileHandle, obj, fileHandle))) { michael@0: *aResult = fileHandle->GetFileId(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsISupports* nativeObj = michael@0: nsContentUtils::XPConnect()->GetNativeOfWrapper(aCx, obj); michael@0: michael@0: nsCOMPtr blob = do_QueryInterface(nativeObj); michael@0: if (blob) { michael@0: *aResult = blob->GetFileId(); michael@0: return NS_OK; michael@0: } michael@0: } michael@0: michael@0: *aResult = -1; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetFileReferences(const nsAString& aDatabaseName, int64_t aId, michael@0: JS::Handle aOptions, michael@0: int32_t* aRefCnt, int32_t* aDBRefCnt, michael@0: int32_t* aSliceRefCnt, JSContext* aCx, michael@0: bool* aResult) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr window = do_QueryReferent(mWindow); michael@0: NS_ENSURE_TRUE(window, NS_ERROR_FAILURE); michael@0: michael@0: nsCString origin; michael@0: quota::PersistenceType defaultPersistenceType; michael@0: nsresult rv = michael@0: quota::QuotaManager::GetInfoFromWindow(window, nullptr, &origin, nullptr, michael@0: &defaultPersistenceType); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: IDBOpenDBOptions options; michael@0: JS::Rooted optionsVal(aCx, aOptions); michael@0: if (!options.Init(aCx, optionsVal)) { michael@0: return NS_ERROR_TYPE_ERR; michael@0: } michael@0: michael@0: quota::PersistenceType persistenceType = michael@0: quota::PersistenceTypeFromStorage(options.mStorage, defaultPersistenceType); michael@0: michael@0: nsRefPtr mgr = michael@0: indexedDB::IndexedDatabaseManager::Get(); michael@0: michael@0: if (mgr) { michael@0: rv = mgr->BlockAndGetFileReferences(persistenceType, origin, aDatabaseName, michael@0: aId, aRefCnt, aDBRefCnt, aSliceRefCnt, michael@0: aResult); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: } michael@0: else { michael@0: *aRefCnt = *aDBRefCnt = *aSliceRefCnt = -1; michael@0: *aResult = false; michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::IsIncrementalGCEnabled(JSContext* cx, bool* aResult) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: *aResult = JS::IsIncrementalGCEnabled(JS_GetRuntime(cx)); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::StartPCCountProfiling(JSContext* cx) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: js::StartPCCountProfiling(cx); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::StopPCCountProfiling(JSContext* cx) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: js::StopPCCountProfiling(cx); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::PurgePCCounts(JSContext* cx) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: js::PurgePCCounts(cx); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetPCCountScriptCount(JSContext* cx, int32_t *result) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: *result = js::GetPCCountScriptCount(cx); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetPCCountScriptSummary(int32_t script, JSContext* cx, nsAString& result) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: JSString *text = js::GetPCCountScriptSummary(cx, script); michael@0: if (!text) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: nsDependentJSString str; michael@0: if (!str.init(cx, text)) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: result = str; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetPCCountScriptContents(int32_t script, JSContext* cx, nsAString& result) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: JSString *text = js::GetPCCountScriptContents(cx, script); michael@0: if (!text) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: nsDependentJSString str; michael@0: if (!str.init(cx, text)) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: result = str; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetPaintingSuppressed(bool *aPaintingSuppressed) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr window = do_QueryReferent(mWindow); michael@0: NS_ENSURE_TRUE(window, NS_ERROR_FAILURE); michael@0: nsIDocShell *docShell = window->GetDocShell(); michael@0: NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE); michael@0: michael@0: nsCOMPtr presShell = docShell->GetPresShell(); michael@0: NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE); michael@0: michael@0: *aPaintingSuppressed = presShell->IsPaintingSuppressed(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetPlugins(JSContext* cx, JS::MutableHandle aPlugins) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr doc = GetDocument(); michael@0: NS_ENSURE_STATE(doc); michael@0: michael@0: nsTArray plugins; michael@0: doc->GetPlugins(plugins); michael@0: michael@0: JS::Rooted jsPlugins(cx); michael@0: nsresult rv = nsTArrayToJSArray(cx, plugins, jsPlugins.address()); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: aPlugins.setObject(*jsPlugins); michael@0: return NS_OK; michael@0: } michael@0: michael@0: static void michael@0: MaybeReflowForInflationScreenWidthChange(nsPresContext *aPresContext) michael@0: { michael@0: if (aPresContext) { michael@0: nsIPresShell* presShell = aPresContext->GetPresShell(); michael@0: bool fontInflationWasEnabled = presShell->FontSizeInflationEnabled(); michael@0: presShell->NotifyFontSizeInflationEnabledIsDirty(); michael@0: bool changed = false; michael@0: if (presShell && presShell->FontSizeInflationEnabled() && michael@0: presShell->FontSizeInflationMinTwips() != 0) { michael@0: aPresContext->ScreenWidthInchesForFontInflation(&changed); michael@0: } michael@0: michael@0: changed = changed || michael@0: (fontInflationWasEnabled != presShell->FontSizeInflationEnabled()); michael@0: if (changed) { michael@0: nsCOMPtr docShell = aPresContext->GetDocShell(); michael@0: if (docShell) { michael@0: nsCOMPtr cv; michael@0: docShell->GetContentViewer(getter_AddRefs(cv)); michael@0: nsCOMPtr mudv = do_QueryInterface(cv); michael@0: if (mudv) { michael@0: nsTArray > array; michael@0: mudv->AppendSubtree(array); michael@0: for (uint32_t i = 0, iEnd = array.Length(); i < iEnd; ++i) { michael@0: nsCOMPtr shell; michael@0: nsCOMPtr cv = do_QueryInterface(array[i]); michael@0: cv->GetPresShell(getter_AddRefs(shell)); michael@0: if (shell) { michael@0: nsIFrame *rootFrame = shell->GetRootFrame(); michael@0: if (rootFrame) { michael@0: shell->FrameNeedsReflow(rootFrame, michael@0: nsIPresShell::eStyleChange, michael@0: NS_FRAME_IS_DIRTY); michael@0: } michael@0: } michael@0: } michael@0: } michael@0: } michael@0: } michael@0: } michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SetScrollPositionClampingScrollPortSize(float aWidth, float aHeight) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: if (!(aWidth >= 0.0 && aHeight >= 0.0)) { michael@0: return NS_ERROR_ILLEGAL_VALUE; michael@0: } michael@0: michael@0: nsIPresShell* presShell = GetPresShell(); michael@0: if (!presShell) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: presShell->SetScrollPositionClampingScrollPortSize( michael@0: nsPresContext::CSSPixelsToAppUnits(aWidth), michael@0: nsPresContext::CSSPixelsToAppUnits(aHeight)); michael@0: michael@0: // When the "font.size.inflation.minTwips" preference is set, the michael@0: // layout depends on the size of the screen. Since when the size michael@0: // of the screen changes, the scroll position clamping scroll port michael@0: // size also changes, we hook in the needed updates here rather michael@0: // than adding a separate notification just for this change. michael@0: nsPresContext* presContext = GetPresContext(); michael@0: MaybeReflowForInflationScreenWidthChange(presContext); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SetContentDocumentFixedPositionMargins(float aTop, float aRight, michael@0: float aBottom, float aLeft) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: if (!(aTop >= 0.0f && aRight >= 0.0f && aBottom >= 0.0f && aLeft >= 0.0f)) { michael@0: return NS_ERROR_ILLEGAL_VALUE; michael@0: } michael@0: michael@0: nsIPresShell* presShell = GetPresShell(); michael@0: if (!presShell) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: nsMargin margins(nsPresContext::CSSPixelsToAppUnits(aTop), michael@0: nsPresContext::CSSPixelsToAppUnits(aRight), michael@0: nsPresContext::CSSPixelsToAppUnits(aBottom), michael@0: nsPresContext::CSSPixelsToAppUnits(aLeft)); michael@0: presShell->SetContentDocumentFixedPositionMargins(margins); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: nsDOMWindowUtils::RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement, michael@0: const nsAString& aNewOrigin) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr doc = GetDocument(); michael@0: NS_ENSURE_STATE(doc); michael@0: michael@0: doc->RemoteFrameFullscreenChanged(aFrameElement, aNewOrigin); michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: nsDOMWindowUtils::RemoteFrameFullscreenReverted() michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr doc = GetDocument(); michael@0: NS_ENSURE_STATE(doc); michael@0: michael@0: doc->RemoteFrameFullscreenReverted(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: nsDOMWindowUtils::ExitFullscreen() michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsIDocument::ExitFullscreen(nullptr, /* async */ false); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SelectAtPoint(float aX, float aY, uint32_t aSelectBehavior, michael@0: bool *_retval) michael@0: { michael@0: *_retval = false; michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsSelectionAmount amount; michael@0: switch (aSelectBehavior) { michael@0: case nsIDOMWindowUtils::SELECT_CHARACTER: michael@0: amount = eSelectCharacter; michael@0: break; michael@0: case nsIDOMWindowUtils::SELECT_CLUSTER: michael@0: amount = eSelectCluster; michael@0: break; michael@0: case nsIDOMWindowUtils::SELECT_WORD: michael@0: amount = eSelectWord; michael@0: break; michael@0: case nsIDOMWindowUtils::SELECT_LINE: michael@0: amount = eSelectLine; michael@0: break; michael@0: case nsIDOMWindowUtils::SELECT_BEGINLINE: michael@0: amount = eSelectBeginLine; michael@0: break; michael@0: case nsIDOMWindowUtils::SELECT_ENDLINE: michael@0: amount = eSelectEndLine; michael@0: break; michael@0: case nsIDOMWindowUtils::SELECT_PARAGRAPH: michael@0: amount = eSelectParagraph; michael@0: break; michael@0: case nsIDOMWindowUtils::SELECT_WORDNOSPACE: michael@0: amount = eSelectWordNoSpace; michael@0: break; michael@0: default: michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: nsIPresShell* presShell = GetPresShell(); michael@0: if (!presShell) { michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: // The root frame for this content window michael@0: nsIFrame* rootFrame = presShell->FrameManager()->GetRootFrame(); michael@0: if (!rootFrame) { michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: // Get the target frame at the client coordinates passed to us michael@0: nsPoint offset; michael@0: nsCOMPtr widget = GetWidget(&offset); michael@0: nsIntPoint pt = LayoutDeviceIntPoint::ToUntyped( michael@0: ToWidgetPoint(CSSPoint(aX, aY), offset, GetPresContext())); michael@0: nsPoint ptInRoot = michael@0: nsLayoutUtils::GetEventCoordinatesRelativeTo(widget, pt, rootFrame); michael@0: nsIFrame* targetFrame = nsLayoutUtils::GetFrameForPoint(rootFrame, ptInRoot); michael@0: // This can happen if the page hasn't loaded yet or if the point michael@0: // is outside the frame. michael@0: if (!targetFrame) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: // Convert point to coordinates relative to the target frame, which is michael@0: // what targetFrame's SelectByTypeAtPoint expects. michael@0: nsPoint relPoint = michael@0: nsLayoutUtils::GetEventCoordinatesRelativeTo(widget, pt, targetFrame); michael@0: michael@0: nsresult rv = michael@0: static_cast(targetFrame)-> michael@0: SelectByTypeAtPoint(GetPresContext(), relPoint, amount, amount, michael@0: nsFrame::SELECT_ACCUMULATE); michael@0: *_retval = !NS_FAILED(rv); michael@0: return NS_OK; michael@0: } michael@0: michael@0: static nsIDocument::additionalSheetType michael@0: convertSheetType(uint32_t aSheetType) michael@0: { michael@0: switch(aSheetType) { michael@0: case nsDOMWindowUtils::AGENT_SHEET: michael@0: return nsIDocument::eAgentSheet; michael@0: case nsDOMWindowUtils::USER_SHEET: michael@0: return nsIDocument::eUserSheet; michael@0: case nsDOMWindowUtils::AUTHOR_SHEET: michael@0: return nsIDocument::eAuthorSheet; michael@0: default: michael@0: NS_ASSERTION(false, "wrong type"); michael@0: // we must return something although this should never happen michael@0: return nsIDocument::SheetTypeCount; michael@0: } michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::LoadSheet(nsIURI *aSheetURI, uint32_t aSheetType) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: NS_ENSURE_ARG_POINTER(aSheetURI); michael@0: NS_ENSURE_ARG(aSheetType == AGENT_SHEET || michael@0: aSheetType == USER_SHEET || michael@0: aSheetType == AUTHOR_SHEET); michael@0: michael@0: nsCOMPtr doc = GetDocument(); michael@0: NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE); michael@0: michael@0: nsIDocument::additionalSheetType type = convertSheetType(aSheetType); michael@0: michael@0: return doc->LoadAdditionalStyleSheet(type, aSheetURI); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::RemoveSheet(nsIURI *aSheetURI, uint32_t aSheetType) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: NS_ENSURE_ARG_POINTER(aSheetURI); michael@0: NS_ENSURE_ARG(aSheetType == AGENT_SHEET || michael@0: aSheetType == USER_SHEET || michael@0: aSheetType == AUTHOR_SHEET); michael@0: michael@0: nsCOMPtr doc = GetDocument(); michael@0: NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE); michael@0: michael@0: nsIDocument::additionalSheetType type = convertSheetType(aSheetType); michael@0: michael@0: doc->RemoveAdditionalStyleSheet(type, aSheetURI); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetIsHandlingUserInput(bool* aHandlingUserInput) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: *aHandlingUserInput = EventStateManager::IsHandlingUserInput(); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::AllowScriptsToClose() michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: nsCOMPtr window = do_QueryReferent(mWindow); michael@0: NS_ENSURE_STATE(window); michael@0: static_cast(window.get())->AllowScriptsToClose(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetIsParentWindowMainWidgetVisible(bool* aIsVisible) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: // this should reflect the "is parent window visible" logic in michael@0: // nsWindowWatcher::OpenWindowInternal() michael@0: nsCOMPtr window = do_QueryReferent(mWindow); michael@0: NS_ENSURE_STATE(window); michael@0: michael@0: nsCOMPtr parentWidget; michael@0: nsIDocShell *docShell = window->GetDocShell(); michael@0: if (docShell) { michael@0: if (TabChild *tabChild = TabChild::GetFrom(docShell)) { michael@0: if (!tabChild->SendIsParentWindowMainWidgetVisible(aIsVisible)) michael@0: return NS_ERROR_FAILURE; michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsCOMPtr parentTreeOwner; michael@0: docShell->GetTreeOwner(getter_AddRefs(parentTreeOwner)); michael@0: nsCOMPtr parentWindow(do_GetInterface(parentTreeOwner)); michael@0: if (parentWindow) { michael@0: parentWindow->GetMainWidget(getter_AddRefs(parentWidget)); michael@0: } michael@0: } michael@0: if (!parentWidget) { michael@0: return NS_ERROR_NOT_AVAILABLE; michael@0: } michael@0: michael@0: *aIsVisible = parentWidget->IsVisible(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::IsNodeDisabledForEvents(nsIDOMNode* aNode, bool* aRetVal) michael@0: { michael@0: *aRetVal = false; michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: nsCOMPtr n = do_QueryInterface(aNode); michael@0: nsINode* node = n; michael@0: while (node) { michael@0: if (node->IsNodeOfType(nsINode::eHTML_FORM_CONTROL)) { michael@0: nsCOMPtr fc = do_QueryInterface(node); michael@0: if (fc && fc->IsDisabledForEvents(NS_EVENT_NULL)) { michael@0: *aRetVal = true; michael@0: break; michael@0: } michael@0: } michael@0: node = node->GetParentNode(); michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SetPaintFlashing(bool aPaintFlashing) michael@0: { michael@0: nsPresContext* presContext = GetPresContext(); michael@0: if (presContext) { michael@0: presContext->SetPaintFlashing(aPaintFlashing); michael@0: // Clear paint flashing colors michael@0: nsIPresShell* presShell = GetPresShell(); michael@0: if (!aPaintFlashing && presShell) { michael@0: nsIFrame* rootFrame = presShell->GetRootFrame(); michael@0: if (rootFrame) { michael@0: rootFrame->InvalidateFrameSubtree(); michael@0: } michael@0: } michael@0: } michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetPaintFlashing(bool* aRetVal) michael@0: { michael@0: *aRetVal = false; michael@0: nsPresContext* presContext = GetPresContext(); michael@0: if (presContext) { michael@0: *aRetVal = presContext->GetPaintFlashing(); michael@0: } michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::DispatchEventToChromeOnly(nsIDOMEventTarget* aTarget, michael@0: nsIDOMEvent* aEvent, michael@0: bool* aRetVal) michael@0: { michael@0: *aRetVal = false; michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: NS_ENSURE_STATE(aTarget && aEvent); michael@0: aEvent->GetInternalNSEvent()->mFlags.mOnlyChromeDispatch = true; michael@0: aTarget->DispatchEvent(aEvent, aRetVal); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::RunInStableState(nsIRunnable *runnable) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr appShell(do_GetService(kAppShellCID)); michael@0: if (!appShell) { michael@0: return NS_ERROR_NOT_AVAILABLE; michael@0: } michael@0: michael@0: return appShell->RunInStableState(runnable); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::RunBeforeNextEvent(nsIRunnable *runnable) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr appShell(do_GetService(kAppShellCID)); michael@0: if (!appShell) { michael@0: return NS_ERROR_NOT_AVAILABLE; michael@0: } michael@0: michael@0: return appShell->RunBeforeNextEvent(runnable); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetOMTAStyle(nsIDOMElement* aElement, michael@0: const nsAString& aProperty, michael@0: nsAString& aResult) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: nsCOMPtr element = do_QueryInterface(aElement); michael@0: if (!element) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: nsRefPtr cssValue = nullptr; michael@0: nsIFrame* frame = element->GetPrimaryFrame(); michael@0: if (frame && nsLayoutUtils::AreAsyncAnimationsEnabled()) { michael@0: if (aProperty.EqualsLiteral("opacity")) { michael@0: Layer* layer = michael@0: FrameLayerBuilder::GetDedicatedLayer(frame, michael@0: nsDisplayItem::TYPE_OPACITY); michael@0: if (layer) { michael@0: float value; michael@0: ShadowLayerForwarder* forwarder = layer->Manager()->AsShadowForwarder(); michael@0: if (forwarder && forwarder->HasShadowManager()) { michael@0: forwarder->GetShadowManager()->SendGetOpacity( michael@0: layer->AsShadowableLayer()->GetShadow(), &value); michael@0: cssValue = new nsROCSSPrimitiveValue; michael@0: cssValue->SetNumber(value); michael@0: } michael@0: } michael@0: } else if (aProperty.EqualsLiteral("transform")) { michael@0: Layer* layer = michael@0: FrameLayerBuilder::GetDedicatedLayer(frame, michael@0: nsDisplayItem::TYPE_TRANSFORM); michael@0: if (layer) { michael@0: ShadowLayerForwarder* forwarder = layer->Manager()->AsShadowForwarder(); michael@0: if (forwarder && forwarder->HasShadowManager()) { michael@0: MaybeTransform transform; michael@0: forwarder->GetShadowManager()->SendGetAnimationTransform( michael@0: layer->AsShadowableLayer()->GetShadow(), &transform); michael@0: if (transform.type() == MaybeTransform::Tgfx3DMatrix) { michael@0: cssValue = michael@0: nsComputedDOMStyle::MatrixToCSSValue(transform.get_gfx3DMatrix()); michael@0: } michael@0: } michael@0: } michael@0: } michael@0: } michael@0: michael@0: if (cssValue) { michael@0: nsString text; michael@0: ErrorResult rv; michael@0: cssValue->GetCssText(text, rv); michael@0: aResult.Assign(text); michael@0: return rv.ErrorCode(); michael@0: } else { michael@0: aResult.Truncate(); michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetOMTAOrComputedStyle(nsIDOMElement* aElement, michael@0: const nsAString& aProperty, michael@0: nsAString& aResult) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: michael@0: // Try to get OMTA style michael@0: nsresult rv = GetOMTAStyle(aElement, aProperty, aResult); michael@0: if (NS_FAILED(rv) || !aResult.IsEmpty()) { michael@0: return rv; michael@0: } michael@0: michael@0: // Otherwise, fall back to computed style michael@0: nsCOMPtr element = do_QueryInterface(aElement); michael@0: if (!element) { michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: nsCOMPtr style; michael@0: rv = element->GetCurrentDoc()->GetWindow()-> michael@0: GetComputedStyle(aElement, aProperty, getter_AddRefs(style)); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: return style->GetPropertyValue(aProperty, aResult); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetAudioMuted(bool* aMuted) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: nsCOMPtr window = do_QueryReferent(mWindow); michael@0: NS_ENSURE_STATE(window); michael@0: michael@0: *aMuted = window->GetAudioMuted(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SetAudioMuted(bool aMuted) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: nsCOMPtr window = do_QueryReferent(mWindow); michael@0: NS_ENSURE_STATE(window); michael@0: michael@0: window->SetAudioMuted(aMuted); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::GetAudioVolume(float* aVolume) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: nsCOMPtr window = do_QueryReferent(mWindow); michael@0: NS_ENSURE_STATE(window); michael@0: michael@0: *aVolume = window->GetAudioVolume(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDOMWindowUtils::SetAudioVolume(float aVolume) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: } michael@0: nsCOMPtr window = do_QueryReferent(mWindow); michael@0: NS_ENSURE_STATE(window); michael@0: michael@0: return window->SetAudioVolume(aVolume); michael@0: } michael@0: michael@0: NS_INTERFACE_MAP_BEGIN(nsTranslationNodeList) michael@0: NS_INTERFACE_MAP_ENTRY(nsISupports) michael@0: NS_INTERFACE_MAP_ENTRY(nsITranslationNodeList) michael@0: NS_INTERFACE_MAP_END michael@0: michael@0: NS_IMPL_ADDREF(nsTranslationNodeList) michael@0: NS_IMPL_RELEASE(nsTranslationNodeList) michael@0: michael@0: NS_IMETHODIMP michael@0: nsTranslationNodeList::Item(uint32_t aIndex, nsIDOMNode** aRetVal) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aRetVal); michael@0: NS_IF_ADDREF(*aRetVal = mNodes.SafeElementAt(aIndex)); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsTranslationNodeList::IsTranslationRootAtIndex(uint32_t aIndex, bool* aRetVal) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aRetVal); michael@0: if (aIndex >= mLength) { michael@0: *aRetVal = false; michael@0: return NS_OK; michael@0: } michael@0: michael@0: *aRetVal = mNodeIsRoot.ElementAt(aIndex); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsTranslationNodeList::GetLength(uint32_t* aRetVal) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aRetVal); michael@0: *aRetVal = mLength; michael@0: return NS_OK; michael@0: }