From 7dc785f46a0155b472f56a150401bb831597e319 Mon Sep 17 00:00:00 2001 From: Mike Conley Date: Wed, 22 Apr 2015 10:58:15 -0400 Subject: [PATCH 01/57] Bug 1096093 - Add infrastructure for LookAndFeel metric caching, and allowing the parent process to send down cache to content process. r=jimm. --- dom/ipc/ContentChild.cpp | 2 ++ dom/ipc/ContentParent.cpp | 9 +++++++++ dom/ipc/ContentParent.h | 5 +++-- dom/ipc/PContent.ipdl | 3 +++ widget/LookAndFeel.h | 14 +++++++++++++ widget/WidgetMessageUtils.h | 39 +++++++++++++++++++++++++++++++++++++ widget/moz.build | 1 + widget/nsXPLookAndFeel.cpp | 30 ++++++++++++++++++++++++++++ widget/nsXPLookAndFeel.h | 4 ++++ 9 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 widget/WidgetMessageUtils.h diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index 799497ffd7a..2c63c88aa35 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -23,6 +23,7 @@ #ifdef ACCESSIBILITY #include "mozilla/a11y/DocAccessibleChild.h" #endif +#include "mozilla/LookAndFeel.h" #include "mozilla/Preferences.h" #include "mozilla/ProcessHangMonitorIPC.h" #include "mozilla/docshell/OfflineCacheUpdateChild.h" @@ -53,6 +54,7 @@ #include "mozilla/net/NeckoChild.h" #include "mozilla/plugins/PluginInstanceParent.h" #include "mozilla/plugins/PluginModuleParent.h" +#include "mozilla/widget/WidgetMessageUtils.h" #if defined(MOZ_CONTENT_SANDBOX) #if defined(XP_WIN) diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index d8b4c25768d..c82d6d4fa3a 100755 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -76,6 +76,7 @@ #include "mozilla/layers/CompositorParent.h" #include "mozilla/layers/ImageBridgeParent.h" #include "mozilla/layers/SharedBufferManagerParent.h" +#include "mozilla/LookAndFeel.h" #include "mozilla/net/NeckoParent.h" #include "mozilla/plugins/PluginBridge.h" #include "mozilla/Preferences.h" @@ -2887,6 +2888,7 @@ ContentParent::RecvAddNewProcess(const uint32_t& aPid, InfallibleTArray unusedDictionaries; ClipboardCapabilities clipboardCaps; DomainPolicyClone domainPolicy; + RecvGetXPCOMProcessAttributes(&isOffline, &isLangRTL, &unusedDictionaries, &clipboardCaps, &domainPolicy); mozilla::unused << content->SendSetOffline(isOffline); @@ -4037,6 +4039,13 @@ ContentParent::RecvGetSystemMemory(const uint64_t& aGetterId) return true; } +bool +ContentParent::RecvGetLookAndFeelCache(nsTArray&& aLookAndFeelIntCache) +{ + aLookAndFeelIntCache = LookAndFeel::GetIntCache(); + return true; +} + bool ContentParent::RecvIsSecureURI(const uint32_t& type, const URIParams& uri, diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index 680845e43a4..1e7e66d5ac2 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -543,8 +543,7 @@ private: bool* aIsLangRTL, InfallibleTArray* dictionaries, ClipboardCapabilities* clipboardCaps, - DomainPolicyClone* domainPolicy) - override; + DomainPolicyClone* domainPolicy) override; virtual bool DeallocPJavaScriptParent(mozilla::jsipc::PJavaScriptParent*) override; @@ -756,6 +755,8 @@ private: const bool& aHidden) override; virtual bool RecvGetSystemMemory(const uint64_t& getterId) override; + virtual bool RecvGetLookAndFeelCache(nsTArray&& aLookAndFeelIntCache) override; + virtual bool RecvDataStoreGetStores( const nsString& aName, const nsString& aOwner, diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index cc92354bd7d..8e4cbb028b7 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -87,6 +87,7 @@ using mozilla::hal::ProcessPriority from "mozilla/HalTypes.h"; using gfxIntSize from "nsSize.h"; using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h"; using mozilla::dom::ContentParentId from "mozilla/dom/ipc/IdType.h"; +using struct LookAndFeelInt from "mozilla/widget/WidgetMessageUtils.h"; union ChromeRegistryItem { @@ -690,6 +691,8 @@ parent: sync IsSecureURI(uint32_t type, URIParams uri, uint32_t flags) returns (bool isSecureURI); + sync GetLookAndFeelCache(LookAndFeelInt[] lookAndFeelIntCache); + PHal(); PIcc(uint32_t serviceId); diff --git a/widget/LookAndFeel.h b/widget/LookAndFeel.h index e0283eaa4b7..df3fa4a52f1 100644 --- a/widget/LookAndFeel.h +++ b/widget/LookAndFeel.h @@ -12,9 +12,16 @@ #include "nsDebug.h" #include "nsColor.h" +#include "nsTArray.h" struct gfxFontStyle; +struct LookAndFeelInt +{ + int32_t id; + int32_t value; +}; + namespace mozilla { class LookAndFeel @@ -583,6 +590,13 @@ public: * cached data would be released. */ static void Refresh(); + + /** + * If the implementation is caching values, these accessors allow the + * cache to be exported and imported. + */ + static nsTArray GetIntCache(); + static void SetIntCache(const nsTArray& aLookAndFeelIntCache); }; } // namespace mozilla diff --git a/widget/WidgetMessageUtils.h b/widget/WidgetMessageUtils.h new file mode 100644 index 00000000000..3287296d9fe --- /dev/null +++ b/widget/WidgetMessageUtils.h @@ -0,0 +1,39 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_WidgetMessageUtils_h +#define mozilla_WidgetMessageUtils_h + +#include "ipc/IPCMessageUtils.h" +#include "mozilla/LookAndFeel.h" + +namespace IPC { + +template<> +struct ParamTraits +{ + typedef LookAndFeelInt paramType; + + static void Write(Message* aMsg, const paramType& aParam) + { + WriteParam(aMsg, aParam.id); + WriteParam(aMsg, aParam.value); + } + + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) + { + int32_t id, value; + if (ReadParam(aMsg, aIter, &id) && + ReadParam(aMsg, aIter, &value)) { + aResult->id = id; + aResult->value = value; + return true; + } + return false; + } +}; + +} // namespace IPC + +#endif // WidgetMessageUtils_h \ No newline at end of file diff --git a/widget/moz.build b/widget/moz.build index 9b1e40ed632..91beee8ccfe 100644 --- a/widget/moz.build +++ b/widget/moz.build @@ -133,6 +133,7 @@ EXPORTS.mozilla += [ EXPORTS.mozilla.widget += [ 'PuppetBidiKeyboard.h', + 'WidgetMessageUtils.h', ] UNIFIED_SOURCES += [ diff --git a/widget/nsXPLookAndFeel.cpp b/widget/nsXPLookAndFeel.cpp index b804143b113..1aecc875232 100644 --- a/widget/nsXPLookAndFeel.cpp +++ b/widget/nsXPLookAndFeel.cpp @@ -13,6 +13,7 @@ #include "nsFont.h" #include "mozilla/Preferences.h" #include "mozilla/gfx/2D.h" +#include "mozilla/widget/WidgetMessageUtils.h" #include "gfxPlatform.h" #include "qcms.h" @@ -453,6 +454,15 @@ nsXPLookAndFeel::Init() if (NS_SUCCEEDED(Preferences::GetBool("ui.use_native_colors", &val))) { sUseNativeColors = val; } + + if (XRE_GetProcessType() == GeckoProcessType_Content) { + mozilla::dom::ContentChild* cc = + mozilla::dom::ContentChild::GetSingleton(); + + nsTArray lookAndFeelIntCache; + cc->SendGetLookAndFeelCache(lookAndFeelIntCache); + LookAndFeel::SetIntCache(lookAndFeelIntCache); + } } nsXPLookAndFeel::~nsXPLookAndFeel() @@ -703,6 +713,12 @@ nsXPLookAndFeel::RefreshImpl() sCachedColorBits[i] = 0; } +nsTArray +nsXPLookAndFeel::GetIntCacheImpl() +{ + return nsTArray(); +} + namespace mozilla { // static @@ -763,4 +779,18 @@ LookAndFeel::Refresh() nsLookAndFeel::GetInstance()->RefreshImpl(); } +// static +nsTArray +LookAndFeel::GetIntCache() +{ + return nsLookAndFeel::GetInstance()->GetIntCacheImpl(); +} + +// static +void +LookAndFeel::SetIntCache(const nsTArray& aLookAndFeelIntCache) +{ + return nsLookAndFeel::GetInstance()->SetIntCacheImpl(aLookAndFeelIntCache); +} + } // namespace mozilla diff --git a/widget/nsXPLookAndFeel.h b/widget/nsXPLookAndFeel.h index a0ee2f59af1..174c410e9e6 100644 --- a/widget/nsXPLookAndFeel.h +++ b/widget/nsXPLookAndFeel.h @@ -7,6 +7,7 @@ #define __nsXPLookAndFeel #include "mozilla/LookAndFeel.h" +#include "nsTArray.h" class nsLookAndFeel; @@ -79,6 +80,9 @@ public: return 600; } + virtual nsTArray GetIntCacheImpl(); + virtual void SetIntCacheImpl(const nsTArray& aLookAndFeelIntCache) {} + protected: nsXPLookAndFeel(); From 40b6ffe55834314baaef4d3678c74f783f1ed1e7 Mon Sep 17 00:00:00 2001 From: Mike Conley Date: Wed, 22 Apr 2015 10:58:33 -0400 Subject: [PATCH 02/57] Bug 1096093 - Send ThemeRefresh message from parent down to content process. r=smaug. --- dom/ipc/PBrowser.ipdl | 7 +++++++ dom/ipc/TabChild.cpp | 23 +++++++++++++++++++++-- dom/ipc/TabChild.h | 2 ++ dom/ipc/TabParent.cpp | 14 ++++++++++++++ dom/ipc/TabParent.h | 1 + layout/base/nsPresContext.cpp | 11 +++++++++++ 6 files changed, 56 insertions(+), 2 deletions(-) diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl index df74b1eea1c..36c8ff79ced 100644 --- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -58,6 +58,7 @@ using mozilla::layers::GeckoContentController::APZStateChange from "mozilla/laye using mozilla::WritingMode from "mozilla/WritingModes.h"; using mozilla::layers::TouchBehaviorFlags from "mozilla/layers/APZUtils.h"; using nsIWidget::TouchPointerState from "nsIWidget.h"; +using struct LookAndFeelInt from "mozilla/widget/WidgetMessageUtils.h"; namespace mozilla { namespace dom { @@ -673,6 +674,12 @@ child: */ UIResolutionChanged(); + /** + * Tell the child that the system theme has changed, and that a repaint + * is necessary. + */ + ThemeChanged(LookAndFeelInt[] lookAndFeelIntCache); + /** * Tell the child of an app's offline status */ diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index 5bb4f164d9b..fa2ba3836a5 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -3140,8 +3140,27 @@ TabChild::RecvUIResolutionChanged() static_cast(mWidget.get())->ClearBackingScaleCache(); nsCOMPtr document(GetDocument()); nsCOMPtr presShell = document->GetShell(); - nsRefPtr presContext = presShell->GetPresContext(); - presContext->UIResolutionChanged(); + if (presShell) { + nsRefPtr presContext = presShell->GetPresContext(); + if (presContext) { + presContext->UIResolutionChanged(); + } + } + return true; +} + +bool +TabChild::RecvThemeChanged(nsTArray&& aLookAndFeelIntCache) +{ + LookAndFeel::SetIntCache(aLookAndFeelIntCache); + nsCOMPtr document(GetDocument()); + nsCOMPtr presShell = document->GetShell(); + if (presShell) { + nsRefPtr presContext = presShell->GetPresContext(); + if (presContext) { + presContext->ThemeChanged(); + } + } return true; } diff --git a/dom/ipc/TabChild.h b/dom/ipc/TabChild.h index e9da68c1112..fabefb4674d 100644 --- a/dom/ipc/TabChild.h +++ b/dom/ipc/TabChild.h @@ -480,6 +480,8 @@ public: virtual bool RecvUIResolutionChanged() override; + virtual bool RecvThemeChanged(nsTArray&& aLookAndFeelIntCache) override; + /** * Native widget remoting protocol for use with windowed plugins with e10s. */ diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index d927bb2a746..0eba65a491e 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -24,6 +24,7 @@ #include "mozilla/layers/CompositorParent.h" #include "mozilla/layers/InputAPZContext.h" #include "mozilla/layout/RenderFrameParent.h" +#include "mozilla/LookAndFeel.h" #include "mozilla/MouseEvents.h" #include "mozilla/net/NeckoChild.h" #include "mozilla/Preferences.h" @@ -992,6 +993,19 @@ TabParent::UIResolutionChanged() } } +void +TabParent::ThemeChanged() +{ + if (!mIsDestroyed) { + // The theme has changed, and any cached values we had sent down + // to the child have been invalidated. When this method is called, + // LookAndFeel should have the up-to-date values, which we now + // send down to the child. We do this for every remote tab for now, + // but bug 1156934 has been filed to do it once per content process. + unused << SendThemeChanged(LookAndFeel::GetIntCache()); + } +} + void TabParent::RequestFlingSnap(const FrameMetrics::ViewID& aScrollId, const mozilla::CSSPoint& aDestination) diff --git a/dom/ipc/TabParent.h b/dom/ipc/TabParent.h index 145738ab53b..e3af125599a 100644 --- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -246,6 +246,7 @@ public: void UpdateDimensions(const nsIntRect& rect, const ScreenIntSize& size); void UpdateFrame(const layers::FrameMetrics& aFrameMetrics); void UIResolutionChanged(); + void ThemeChanged(); void RequestFlingSnap(const FrameMetrics::ViewID& aScrollId, const mozilla::CSSPoint& aDestination); void AcknowledgeScrollUpdate(const ViewID& aScrollId, const uint32_t& aScrollGeneration); diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp index 12cc002abba..f807b476a1a 100644 --- a/layout/base/nsPresContext.cpp +++ b/layout/base/nsPresContext.cpp @@ -1702,6 +1702,12 @@ nsPresContext::ThemeChanged() } } +static void +NotifyThemeChanged(TabParent* aTabParent, void* aArg) +{ + aTabParent->ThemeChanged(); +} + void nsPresContext::ThemeChangedInternal() { @@ -1735,6 +1741,11 @@ nsPresContext::ThemeChangedInternal() // changes are not), and -moz-appearance (whose changes likewise are // not), so we need to reflow. MediaFeatureValuesChanged(eRestyle_Subtree, NS_STYLE_HINT_REFLOW); + + // Recursively notify all remote leaf descendants that the + // system theme has changed. + nsContentUtils::CallOnAllRemoteChildren(mDocument->GetWindow(), + NotifyThemeChanged, nullptr); } void From fafa7edcb4a4d4938d4ff69c67cafdd7a8222c48 Mon Sep 17 00:00:00 2001 From: Mike Conley Date: Wed, 22 Apr 2015 10:58:48 -0400 Subject: [PATCH 03/57] Bug 1096093 - Have Cocoa widget backend cache overlay scrollbar metrics. r=mstange. --- widget/cocoa/nsLookAndFeel.h | 11 ++++++ widget/cocoa/nsLookAndFeel.mm | 68 +++++++++++++++++++++++++++++++++-- 2 files changed, 76 insertions(+), 3 deletions(-) diff --git a/widget/cocoa/nsLookAndFeel.h b/widget/cocoa/nsLookAndFeel.h index 57ccff719b1..d6734d3dcce 100644 --- a/widget/cocoa/nsLookAndFeel.h +++ b/widget/cocoa/nsLookAndFeel.h @@ -26,6 +26,10 @@ public: static bool UseOverlayScrollbars(); + virtual nsTArray GetIntCacheImpl(); + virtual void SetIntCacheImpl(const nsTArray& lookAndFeelIntCache); + + virtual void RefreshImpl(); protected: // Apple hasn't defined a constant for scollbars with two arrows on each end, so we'll use this one. @@ -34,6 +38,13 @@ protected: static bool SystemWantsOverlayScrollbars(); static bool AllowOverlayScrollbarsOverlap(); + +private: + int32_t mUseOverlayScrollbars; + bool mUseOverlayScrollbarsCached; + + int32_t mAllowOverlayScrollbarsOverlap; + bool mAllowOverlayScrollbarsOverlapCached; }; #endif // nsLookAndFeel_h_ diff --git a/widget/cocoa/nsLookAndFeel.mm b/widget/cocoa/nsLookAndFeel.mm index f0733b1f378..bac6106d68f 100644 --- a/widget/cocoa/nsLookAndFeel.mm +++ b/widget/cocoa/nsLookAndFeel.mm @@ -12,6 +12,7 @@ #include "gfxFont.h" #include "gfxFontConstants.h" #include "mozilla/gfx/2D.h" +#include "mozilla/widget/WidgetMessageUtils.h" #import @@ -28,7 +29,12 @@ typedef NSInteger mozNSScrollerStyle; + (mozNSScrollerStyle)preferredScrollerStyle; @end -nsLookAndFeel::nsLookAndFeel() : nsXPLookAndFeel() +nsLookAndFeel::nsLookAndFeel() + : nsXPLookAndFeel() + , mUseOverlayScrollbars(-1) + , mUseOverlayScrollbarsCached(false) + , mAllowOverlayScrollbarsOverlap(-1) + , mAllowOverlayScrollbarsOverlapCached(false) { } @@ -359,10 +365,18 @@ nsLookAndFeel::GetIntImpl(IntID aID, int32_t &aResult) aResult = eScrollThumbStyle_Proportional; break; case eIntID_UseOverlayScrollbars: - aResult = SystemWantsOverlayScrollbars() ? 1 : 0; + if (!mUseOverlayScrollbarsCached) { + mUseOverlayScrollbars = SystemWantsOverlayScrollbars() ? 1 : 0; + mUseOverlayScrollbarsCached = true; + } + aResult = mUseOverlayScrollbars; break; case eIntID_AllowOverlayScrollbarsOverlap: - aResult = AllowOverlayScrollbarsOverlap() ? 1 : 0; + if (!mAllowOverlayScrollbarsOverlapCached) { + mAllowOverlayScrollbarsOverlap = AllowOverlayScrollbarsOverlap() ? 1 : 0; + mAllowOverlayScrollbarsOverlapCached = true; + } + aResult = mAllowOverlayScrollbarsOverlap; break; case eIntID_ScrollbarDisplayOnMouseMove: aResult = 0; @@ -633,3 +647,51 @@ nsLookAndFeel::GetFontImpl(FontID aID, nsString &aFontName, NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(false); } + +nsTArray +nsLookAndFeel::GetIntCacheImpl() +{ + nsTArray lookAndFeelIntCache = + nsXPLookAndFeel::GetIntCacheImpl(); + + LookAndFeelInt useOverlayScrollbars; + useOverlayScrollbars.id = eIntID_UseOverlayScrollbars; + useOverlayScrollbars.value = GetInt(eIntID_UseOverlayScrollbars); + lookAndFeelIntCache.AppendElement(useOverlayScrollbars); + + LookAndFeelInt allowOverlayScrollbarsOverlap; + allowOverlayScrollbarsOverlap.id = eIntID_AllowOverlayScrollbarsOverlap; + allowOverlayScrollbarsOverlap.value = GetInt(eIntID_AllowOverlayScrollbarsOverlap); + lookAndFeelIntCache.AppendElement(allowOverlayScrollbarsOverlap); + + return lookAndFeelIntCache; +} + +void +nsLookAndFeel::SetIntCacheImpl(const nsTArray& lookAndFeelIntCache) +{ + for (auto entry : lookAndFeelIntCache) { + switch(entry.id) { + case eIntID_UseOverlayScrollbars: + mUseOverlayScrollbars = entry.value; + mUseOverlayScrollbarsCached = true; + break; + case eIntID_AllowOverlayScrollbarsOverlap: + mAllowOverlayScrollbarsOverlap = entry.value; + mAllowOverlayScrollbarsOverlapCached = true; + break; + } + } +} + +void +nsLookAndFeel::RefreshImpl() +{ + // We should only clear the cache if we're in the main browser process. + // Otherwise, we should wait for the parent to inform us of new values + // to cache via LookAndFeel::SetIntCache. + if (XRE_GetProcessType() == GeckoProcessType_Default) { + mUseOverlayScrollbarsCached = false; + mAllowOverlayScrollbarsOverlapCached = false; + } +} \ No newline at end of file From 9ff5a3e1041f9a82625890a0f07c64b561f25e7e Mon Sep 17 00:00:00 2001 From: Doug Turner Date: Thu, 23 Apr 2015 20:43:40 +0200 Subject: [PATCH 04/57] Bug 1157108 - onpush EventHandler support. r=ehsan --- dom/base/nsGkAtomList.h | 2 ++ dom/push/test/worker.js | 6 ++++-- dom/webidl/ServiceWorkerGlobalScope.webidl | 5 +++++ dom/workers/WorkerScope.h | 4 ++++ 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/dom/base/nsGkAtomList.h b/dom/base/nsGkAtomList.h index 4184451bfee..a1f7fbfea6e 100644 --- a/dom/base/nsGkAtomList.h +++ b/dom/base/nsGkAtomList.h @@ -845,6 +845,8 @@ GK_ATOM(onpopuphiding, "onpopuphiding") GK_ATOM(onpopupshowing, "onpopupshowing") GK_ATOM(onpopupshown, "onpopupshown") GK_ATOM(onpreviewstatechange, "onpreviewstatechange") +GK_ATOM(onpush, "onpush") +GK_ATOM(onpushsubscriptionchange, "onpushsubscriptionchange") GK_ATOM(onpschange, "onpschange") GK_ATOM(onptychange, "onptychange") GK_ATOM(onradiostatechange, "onradiostatechange") diff --git a/dom/push/test/worker.js b/dom/push/test/worker.js index eb583460f04..73071ab66ea 100644 --- a/dom/push/test/worker.js +++ b/dom/push/test/worker.js @@ -1,7 +1,9 @@ // Any copyright is dedicated to the Public Domain. // http://creativecommons.org/licenses/publicdomain/ -addEventListener("push", function(event) { +this.onpush = handlePush; + +function handlePush(event) { self.clients.matchAll().then(function(result) { if (event instanceof PushEvent && @@ -13,4 +15,4 @@ addEventListener("push", function(event) { } result[0].postMessage({type: "finished", okay: "no"}); }); -}); +} diff --git a/dom/webidl/ServiceWorkerGlobalScope.webidl b/dom/webidl/ServiceWorkerGlobalScope.webidl index 9b736395d4e..95410510325 100644 --- a/dom/webidl/ServiceWorkerGlobalScope.webidl +++ b/dom/webidl/ServiceWorkerGlobalScope.webidl @@ -26,4 +26,9 @@ interface ServiceWorkerGlobalScope : WorkerGlobalScope { attribute EventHandler onmessage; }; +// These are from w3c.github.io/push-api/ +partial interface ServiceWorkerGlobalScope { + attribute EventHandler onpush; + attribute EventHandler onpushsubscriptionchange; +}; diff --git a/dom/workers/WorkerScope.h b/dom/workers/WorkerScope.h index 9252180c1ba..2644699fa6c 100644 --- a/dom/workers/WorkerScope.h +++ b/dom/workers/WorkerScope.h @@ -232,6 +232,10 @@ public: IMPL_EVENT_HANDLER(fetch) IMPL_EVENT_HANDLER(install) IMPL_EVENT_HANDLER(message) + + IMPL_EVENT_HANDLER(push) + IMPL_EVENT_HANDLER(pushsubscriptionchange) + }; class WorkerDebuggerGlobalScope final : public DOMEventTargetHelper, From d241a4e0612b58c493df5efe4c8b842518a2bbcd Mon Sep 17 00:00:00 2001 From: Doug Turner Date: Thu, 23 Apr 2015 20:43:40 +0200 Subject: [PATCH 05/57] Bug 1157732 - Allow ws (insecure) connections to localhost. r=kcambridge --- dom/push/PushService.jsm | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/dom/push/PushService.jsm b/dom/push/PushService.jsm index 60ae0d4351d..4416e2d2b54 100644 --- a/dom/push/PushService.jsm +++ b/dom/push/PushService.jsm @@ -887,21 +887,26 @@ this.PushService = { if (uri.scheme === "wss") { socket = Cc["@mozilla.org/network/protocol;1?name=wss"] .createInstance(Ci.nsIWebSocketChannel); - - socket.initLoadInfo(null, // aLoadingNode - Services.scriptSecurityManager.getSystemPrincipal(), - null, // aTriggeringPrincipal - Ci.nsILoadInfo.SEC_NORMAL, - Ci.nsIContentPolicy.TYPE_WEBSOCKET); } else if (uri.scheme === "ws") { - debug("Push over an insecure connection (ws://) is not allowed!"); - return null; + if (uri.host != "localhost") { + debug("Push over an insecure connection (ws://) is not allowed!"); + return null; + } + socket = Cc["@mozilla.org/network/protocol;1?name=ws"] + .createInstance(Ci.nsIWebSocketChannel); } else { debug("Unsupported websocket scheme " + uri.scheme); return null; } + + socket.initLoadInfo(null, // aLoadingNode + Services.scriptSecurityManager.getSystemPrincipal(), + null, // aTriggeringPrincipal + Ci.nsILoadInfo.SEC_NORMAL, + Ci.nsIContentPolicy.TYPE_WEBSOCKET); + return socket; }, From 2f0479c4d11d3b3b87ded09069d17037ea98a705 Mon Sep 17 00:00:00 2001 From: Doug Turner Date: Thu, 23 Apr 2015 20:43:40 +0200 Subject: [PATCH 06/57] Bug 1153503 - Enable push notifications on Nightly / DevTools. r=nsm --- modules/libpref/init/all.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index b7df1c5fb53..15802bcb707 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -4175,8 +4175,11 @@ pref("dom.mozContacts.enabled", false); pref("dom.mozAlarms.enabled", false); // Push +#ifdef RELEASE_BUILD pref("dom.push.enabled", false); - +#else +pref("dom.push.enabled", true); +#endif pref("dom.push.debug", false); pref("dom.push.serverURL", "wss://push.services.mozilla.com/"); pref("dom.push.userAgentID", ""); From b8414b591100d2f0293d2759a80189063435dd7f Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Thu, 2 Apr 2015 09:12:31 -0700 Subject: [PATCH 07/57] Bug 1144481 - Switch nsIThread implementation of AbstractThread::IsCurrentThreadIn() to use PRThreads. r=jww --- dom/media/AbstractThread.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dom/media/AbstractThread.cpp b/dom/media/AbstractThread.cpp index 51ffa4ea718..2938fcbfbe8 100644 --- a/dom/media/AbstractThread.cpp +++ b/dom/media/AbstractThread.cpp @@ -63,7 +63,11 @@ public: virtual bool IsCurrentThreadIn() override { - bool in = NS_GetCurrentThread() == mTarget; + // Compare NSPR threads so that this works after shutdown when + // NS_GetCurrentThread starts returning null. + PRThread* thread = nullptr; + mTarget->GetPRThread(&thread); + bool in = PR_GetCurrentThread() == thread; MOZ_ASSERT(in == (GetCurrent() == this)); return in; } From 0efed16cba5e6e85b1ece1f684032929d32d3dc3 Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Mon, 20 Apr 2015 15:35:52 -0700 Subject: [PATCH 08/57] Bug 1144481 - Invoke SeekCompleted synchronously. r=jww The current behavior is a holdover from when this some of this tuff was happening on the decode thread. It's problematic because nothing guarantees that we don't call CheckIfSeekComplete twice, and queue up two SeekCompleted events. --- dom/media/MediaDecoderStateMachine.cpp | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/dom/media/MediaDecoderStateMachine.cpp b/dom/media/MediaDecoderStateMachine.cpp index 90b23040a27..e091cf5bfd5 100644 --- a/dom/media/MediaDecoderStateMachine.cpp +++ b/dom/media/MediaDecoderStateMachine.cpp @@ -1086,6 +1086,7 @@ MediaDecoderStateMachine::CheckIfSeekComplete() { MOZ_ASSERT(OnTaskQueue()); AssertCurrentThreadInMonitor(); + MOZ_ASSERT(mState == DECODER_STATE_SEEKING); const bool videoSeekComplete = IsVideoSeekComplete(); if (HasVideo() && !videoSeekComplete) { @@ -1110,9 +1111,7 @@ MediaDecoderStateMachine::CheckIfSeekComplete() if (audioSeekComplete && videoSeekComplete) { mDecodeToSeekTarget = false; - nsCOMPtr task( - NS_NewRunnableMethod(this, &MediaDecoderStateMachine::SeekCompleted)); - TaskQueue()->Dispatch(task.forget()); + SeekCompleted(); } } @@ -2393,15 +2392,7 @@ MediaDecoderStateMachine::SeekCompleted() { MOZ_ASSERT(OnTaskQueue()); ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); - - if (mState != DECODER_STATE_SEEKING) { - MOZ_DIAGNOSTIC_ASSERT(mState == DECODER_STATE_DORMANT || - IsShutdown()); - // It would be nice to assert mCurrent.Exists() here, but it's possible that - // we've transitioned to DECODER_STATE_SHUTDOWN but not yet gone through - // RunStateMachine in that state, which is where this promise gets rejected. - return; - } + MOZ_ASSERT(mState == DECODER_STATE_SEEKING); int64_t seekTime = mCurrentSeek.mTarget.mTime; int64_t newCurrentTime = seekTime; From 833500a4af3e09fddf42327b3f404875dd4333d6 Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Thu, 2 Apr 2015 10:49:01 -0700 Subject: [PATCH 09/57] Bug 1144481 - Force state machine setting to go through a setter. r=jww We need this so that we can hook up the state mirroring in the subsequent patch. --- dom/media/MediaDecoder.cpp | 13 ++++++++++--- dom/media/MediaDecoder.h | 13 +++++++++---- dom/media/mediasource/MediaSourceDecoder.cpp | 14 +++++++------- dom/media/omx/MediaOmxCommonDecoder.cpp | 12 ++++++------ 4 files changed, 32 insertions(+), 20 deletions(-) diff --git a/dom/media/MediaDecoder.cpp b/dom/media/MediaDecoder.cpp index 970ef38c415..e0250db9bf2 100644 --- a/dom/media/MediaDecoder.cpp +++ b/dom/media/MediaDecoder.cpp @@ -712,8 +712,8 @@ nsresult MediaDecoder::Load(nsIStreamListener** aStreamListener, nsresult rv = OpenResource(aStreamListener); NS_ENSURE_SUCCESS(rv, rv); - mDecoderStateMachine = CreateStateMachine(); - NS_ENSURE_TRUE(mDecoderStateMachine, NS_ERROR_FAILURE); + SetStateMachine(CreateStateMachine()); + NS_ENSURE_TRUE(GetStateMachine(), NS_ERROR_FAILURE); return InitializeStateMachine(aCloneDonor); } @@ -1596,6 +1596,13 @@ bool MediaDecoder::OnDecodeTaskQueue() const { return mDecoderStateMachine ? mDecoderStateMachine->OnDecodeTaskQueue() : false; } +void +MediaDecoder::SetStateMachine(MediaDecoderStateMachine* aStateMachine) +{ + MOZ_ASSERT_IF(aStateMachine, !mDecoderStateMachine); + mDecoderStateMachine = aStateMachine; +} + ReentrantMonitor& MediaDecoder::GetReentrantMonitor() { return mReentrantMonitor; } @@ -1670,7 +1677,7 @@ bool MediaDecoder::IsShutdown() const { // Drop reference to state machine. Only called during shutdown dance. void MediaDecoder::BreakCycles() { - mDecoderStateMachine = nullptr; + SetStateMachine(nullptr); } MediaDecoderOwner* MediaDecoder::GetMediaOwner() const diff --git a/dom/media/MediaDecoder.h b/dom/media/MediaDecoder.h index a15425fa874..f7b92aa7a85 100644 --- a/dom/media/MediaDecoder.h +++ b/dom/media/MediaDecoder.h @@ -680,6 +680,9 @@ public: bool OnDecodeTaskQueue() const override; + MediaDecoderStateMachine* GetStateMachine() { return mDecoderStateMachine; } + void SetStateMachine(MediaDecoderStateMachine* aStateMachine); + // Returns the monitor for other threads to synchronise access to // state. ReentrantMonitor& GetReentrantMonitor() override; @@ -1109,17 +1112,19 @@ protected: * The following member variables can be accessed from any thread. ******/ + // Media data resource. + nsRefPtr mResource; + +private: // The state machine object for handling the decoding. It is safe to // call methods of this object from other threads. Its internal data // is synchronised on a monitor. The lifetime of this object is // after mPlayState is LOADING and before mPlayState is SHUTDOWN. It // is safe to access it during this period. + // + // Explicitly prievate to force access via accessors. nsRefPtr mDecoderStateMachine; - // Media data resource. - nsRefPtr mResource; - -private: // |ReentrantMonitor| for detecting when the video play state changes. A call // to |Wait| on this monitor will block the thread until the next state // change. Explicitly private for force access via GetReentrantMonitor. diff --git a/dom/media/mediasource/MediaSourceDecoder.cpp b/dom/media/mediasource/MediaSourceDecoder.cpp index 2fd7712b0f2..7941146efdf 100644 --- a/dom/media/mediasource/MediaSourceDecoder.cpp +++ b/dom/media/mediasource/MediaSourceDecoder.cpp @@ -54,14 +54,14 @@ MediaSourceDecoder::CreateStateMachine() nsresult MediaSourceDecoder::Load(nsIStreamListener**, MediaDecoder*) { - MOZ_ASSERT(!mDecoderStateMachine); - mDecoderStateMachine = CreateStateMachine(); - if (!mDecoderStateMachine) { + MOZ_ASSERT(!GetStateMachine()); + SetStateMachine(CreateStateMachine()); + if (!GetStateMachine()) { NS_WARNING("Failed to create state machine!"); return NS_ERROR_FAILURE; } - nsresult rv = mDecoderStateMachine->Init(nullptr); + nsresult rv = GetStateMachine()->Init(nullptr); NS_ENSURE_SUCCESS(rv, rv); SetStateMachineParameters(); @@ -116,7 +116,7 @@ MediaSourceDecoder::CreateResource(nsIPrincipal* aPrincipal) void MediaSourceDecoder::AttachMediaSource(dom::MediaSource* aMediaSource) { - MOZ_ASSERT(!mMediaSource && !mDecoderStateMachine && NS_IsMainThread()); + MOZ_ASSERT(!mMediaSource && !GetStateMachine() && NS_IsMainThread()); mMediaSource = aMediaSource; } @@ -233,10 +233,10 @@ MediaSourceDecoder::SetMediaSourceDuration(double aDuration, MSRangeRemovalActio // We want a very bigger number, but not infinity. checkedDuration = INT64_MAX - 1; } - mDecoderStateMachine->SetDuration(checkedDuration); + GetStateMachine()->SetDuration(checkedDuration); mMediaSourceDuration = aDuration; } else { - mDecoderStateMachine->SetDuration(INT64_MAX); + GetStateMachine()->SetDuration(INT64_MAX); mMediaSourceDuration = PositiveInfinity(); } if (mReader) { diff --git a/dom/media/omx/MediaOmxCommonDecoder.cpp b/dom/media/omx/MediaOmxCommonDecoder.cpp index 12ba4072a37..2820e964242 100644 --- a/dom/media/omx/MediaOmxCommonDecoder.cpp +++ b/dom/media/omx/MediaOmxCommonDecoder.cpp @@ -98,16 +98,16 @@ MediaOmxCommonDecoder::PauseStateMachine() MOZ_ASSERT(NS_IsMainThread()); GetReentrantMonitor().AssertCurrentThreadIn(); DECODER_LOG(PR_LOG_DEBUG, ("%s", __PRETTY_FUNCTION__)); - if (!mDecoderStateMachine) { + if (!GetStateMachine()) { return; } // enter dormant state RefPtr event = NS_NewRunnableMethodWithArg( - mDecoderStateMachine, + GetStateMachine(), &MediaDecoderStateMachine::SetDormant, true); - mDecoderStateMachine->TaskQueue()->Dispatch(event); + GetStateMachine()->TaskQueue()->Dispatch(event); } void @@ -118,7 +118,7 @@ MediaOmxCommonDecoder::ResumeStateMachine() DECODER_LOG(PR_LOG_DEBUG, ("%s current time %f", __PRETTY_FUNCTION__, mCurrentTime)); - if (!mDecoderStateMachine) { + if (!GetStateMachine()) { return; } @@ -134,10 +134,10 @@ MediaOmxCommonDecoder::ResumeStateMachine() // exit dormant state RefPtr event = NS_NewRunnableMethodWithArg( - mDecoderStateMachine, + GetStateMachine(), &MediaDecoderStateMachine::SetDormant, false); - mDecoderStateMachine->TaskQueue()->Dispatch(event); + GetStateMachine()->TaskQueue()->Dispatch(event); } void From f223aa00357374371533681885ce1fa01e47f10b Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Tue, 31 Mar 2015 18:44:13 -0700 Subject: [PATCH 10/57] Bug 1144481 - Implement state mirroring machinery. r=jww --- dom/media/StateMirroring.h | 366 +++++++++++++++++++++++++++++++++++++ dom/media/StateWatching.h | 2 + dom/media/moz.build | 1 + 3 files changed, 369 insertions(+) create mode 100644 dom/media/StateMirroring.h diff --git a/dom/media/StateMirroring.h b/dom/media/StateMirroring.h new file mode 100644 index 00000000000..4844a9fb0da --- /dev/null +++ b/dom/media/StateMirroring.h @@ -0,0 +1,366 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#if !defined(StateMirroring_h_) +#define StateMirroring_h_ + +#include "MediaPromise.h" + +#include "StateWatching.h" +#include "TaskDispatcher.h" + +#include "mozilla/Maybe.h" +#include "mozilla/UniquePtr.h" +#include "mozilla/unused.h" + +#include "prlog.h" +#include "nsISupportsImpl.h" + +/* + * The state-mirroring machinery allows pieces of interesting state to be + * observed on multiple thread without locking. The basic strategy is to track + * changes in a canonical value and post updates to other threads that hold + * mirrors for that value. + * + * One problem with the naive implementation of such a system is that some pieces + * of state need to be updated atomically, and certain other operations need to + * wait for these atomic updates to complete before executing. The state-mirroring + * machinery solves this problem by requiring that its owner thread uses tail + * dispatch, and posting state update events (which should always be run first by + * TaskDispatcher implementations) to that tail dispatcher. This ensures that + * state changes are always atomic from the perspective of observing threads. + * + * Given that semantics may change and comments tend to go out of date, we + * deliberately don't provide usage examples here. Grep around to find them. + */ + +namespace mozilla { + +// Mirror and Canonical inherit WatchTarget, so we piggy-back on the +// logging that WatchTarget already does. Given that, it makes sense to share +// the same log module. +#define MIRROR_LOG(x, ...) \ + MOZ_ASSERT(gStateWatchingLog); \ + PR_LOG(gStateWatchingLog, PR_LOG_DEBUG, (x, ##__VA_ARGS__)) + +template class AbstractMirror; + +/* + * AbstractCanonical is a superclass from which all Canonical values must + * inherit. It serves as the interface of operations which may be performed (via + * asynchronous dispatch) by other threads, in particular by the corresponding + * Mirror value. + */ +template +class AbstractCanonical +{ +public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AbstractCanonical) + AbstractCanonical(AbstractThread* aThread) : mOwnerThread(aThread) {} + virtual void AddMirror(AbstractMirror* aMirror) = 0; + virtual void RemoveMirror(AbstractMirror* aMirror) = 0; + + AbstractThread* OwnerThread() const { return mOwnerThread; } +protected: + virtual ~AbstractCanonical() {} + nsRefPtr mOwnerThread; +}; + +/* + * AbstractMirror is a superclass from which all Mirror values must + * inherit. It serves as the interface of operations which may be performed (via + * asynchronous dispatch) by other threads, in particular by the corresponding + * Canonical value. + */ +template +class AbstractMirror +{ +public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AbstractMirror) + AbstractMirror(AbstractThread* aThread) : mOwnerThread(aThread) {} + virtual void UpdateValue(const T& aNewValue) = 0; + virtual void NotifyDisconnected() = 0; + + AbstractThread* OwnerThread() const { return mOwnerThread; } +protected: + virtual ~AbstractMirror() {} + nsRefPtr mOwnerThread; +}; + +/* + * Canonical is a wrapper class that allows a given value to be mirrored by other + * threads. It maintains a list of active mirrors, and queues updates for them + * when the internal value changes. When changing the value, the caller needs to + * pass a TaskDispatcher object, which fires the updates at the appropriate time. + * Canonical is also a WatchTarget, and may be set up to trigger other routines + * (on the same thread) when the canonical value changes. + * + * Do not instantiate a Canonical directly as a member. Instead, instantiate a + * Canonical::Holder, which handles lifetime issues and may eventually be + * extended to do other things as well. + */ +template +class Canonical : public AbstractCanonical, public WatchTarget +{ +public: + using AbstractCanonical::OwnerThread; + + Canonical(AbstractThread* aThread, const T& aInitialValue, const char* aName) + : AbstractCanonical(aThread), WatchTarget(aName), mValue(aInitialValue) + { + MIRROR_LOG("%s [%p] initialized", mName, this); + MOZ_ASSERT(aThread->RequiresTailDispatch(), "Can't get coherency without tail dispatch"); + } + + void AddMirror(AbstractMirror* aMirror) override + { + MIRROR_LOG("%s [%p] adding mirror %p", mName, this, aMirror); + MOZ_ASSERT(OwnerThread()->IsCurrentThreadIn()); + MOZ_ASSERT(!mMirrors.Contains(aMirror)); + mMirrors.AppendElement(aMirror); + aMirror->OwnerThread()->Dispatch(MakeNotifier(aMirror)); + } + + void RemoveMirror(AbstractMirror* aMirror) override + { + MIRROR_LOG("%s [%p] removing mirror %p", mName, this, aMirror); + MOZ_ASSERT(OwnerThread()->IsCurrentThreadIn()); + MOZ_ASSERT(mMirrors.Contains(aMirror)); + mMirrors.RemoveElement(aMirror); + } + + void DisconnectAll() + { + MIRROR_LOG("%s [%p] Disconnecting all mirrors", mName, this); + for (size_t i = 0; i < mMirrors.Length(); ++i) { + nsCOMPtr r = + NS_NewRunnableMethod(mMirrors[i], &AbstractMirror::NotifyDisconnected); + mMirrors[i]->OwnerThread()->Dispatch(r.forget()); + } + mMirrors.Clear(); + } + + operator const T&() + { + MOZ_ASSERT(OwnerThread()->IsCurrentThreadIn()); + return mValue; + } + + Canonical& operator=(const T& aNewValue) + { + MOZ_ASSERT(OwnerThread()->IsCurrentThreadIn()); + + if (aNewValue == mValue) { + return *this; + } + + // Notify same-thread watchers. The state watching machinery will make sure + // that notifications run at the right time. + NotifyWatchers(); + + // Check if we've already got a pending update. If so we won't schedule another + // one. + bool alreadyNotifying = mInitialValue.isSome(); + + // Stash the initial value if needed, then update to the new value. + if (mInitialValue.isNothing()) { + mInitialValue.emplace(mValue); + } + mValue = aNewValue; + + // We wait until things have stablized before sending state updates so that + // we can avoid sending multiple updates, and possibly avoid sending any + // updates at all if the value ends up where it started. + if (!alreadyNotifying) { + nsCOMPtr r = NS_NewRunnableMethod(this, &Canonical::DoNotify); + AbstractThread::GetCurrent()->TailDispatcher().AddDirectTask(r.forget()); + } + + return *this; + } + + class Holder + { + public: + Holder() {} + ~Holder() { MOZ_DIAGNOSTIC_ASSERT(mCanonical, "Should have initialized me"); } + + // NB: Because mirror-initiated disconnection can race with canonical- + // initiated disconnection, a canonical should never be reinitialized. + void Init(AbstractThread* aThread, const T& aInitialValue, const char* aName) + { + mCanonical = new Canonical(aThread, aInitialValue, aName); + } + + // Forward control operations to the Canonical. + void DisconnectAll() { return mCanonical->DisconnectAll(); } + + // Access to the Canonical. + operator Canonical&() { return *mCanonical; } + Canonical* operator&() { return mCanonical; } + + // Access to the T. + const T& Ref() { return *mCanonical; } + operator const T&() { return Ref(); } + Holder& operator=(const T& aNewValue) { *mCanonical = aNewValue; return *this; } + + private: + nsRefPtr> mCanonical; + }; + +protected: + ~Canonical() { MOZ_DIAGNOSTIC_ASSERT(mMirrors.IsEmpty()); } + +private: + void DoNotify() + { + MOZ_ASSERT(OwnerThread()->IsCurrentThreadIn()); + MOZ_ASSERT(mInitialValue.isSome()); + bool same = mInitialValue.ref() == mValue; + mInitialValue.reset(); + + if (same) { + MIRROR_LOG("%s [%p] unchanged - not sending update", mName, this); + return; + } + + for (size_t i = 0; i < mMirrors.Length(); ++i) { + OwnerThread()->TailDispatcher().AddStateChangeTask(mMirrors[i]->OwnerThread(), MakeNotifier(mMirrors[i])); + } + } + + already_AddRefed MakeNotifier(AbstractMirror* aMirror) + { + nsCOMPtr r = + NS_NewRunnableMethodWithArg(aMirror, &AbstractMirror::UpdateValue, mValue); + return r.forget(); + } + + T mValue; + Maybe mInitialValue; + nsTArray>> mMirrors; +}; + +/* + * Mirror is a wrapper class that allows a given value to mirror that of a + * Canonical owned by another thread. It registers itself with a Canonical, + * and is periodically updated with new values. Mirror is also a WatchTarget, + * and may be set up to trigger other routines (on the same thread) when the + * mirrored value changes. + * + * Do not instantiate a Mirror directly as a member. Instead, instantiate a + * Mirror::Holder, which handles lifetime issues and whose destructor + * initiates an asynchronous teardown of the reference-counted Mirror, + * breaking the inherent cycle between Mirror and Canonical. + */ +template +class Mirror : public AbstractMirror, public WatchTarget +{ +public: + using AbstractMirror::OwnerThread; + + Mirror(AbstractThread* aThread, const T& aInitialValue, const char* aName) + : AbstractMirror(aThread), WatchTarget(aName), mValue(aInitialValue) + { + MIRROR_LOG("%s [%p] initialized", mName, this); + } + + operator const T&() + { + MOZ_ASSERT(OwnerThread()->IsCurrentThreadIn()); + return mValue; + } + + virtual void UpdateValue(const T& aNewValue) override + { + MOZ_ASSERT(OwnerThread()->IsCurrentThreadIn()); + if (mValue != aNewValue) { + mValue = aNewValue; + WatchTarget::NotifyWatchers(); + } + } + + virtual void NotifyDisconnected() override + { + MIRROR_LOG("%s [%p] Notifed of disconnection from %p", mName, this, mCanonical.get()); + MOZ_ASSERT(OwnerThread()->IsCurrentThreadIn()); + mCanonical = nullptr; + } + + bool IsConnected() const { return !!mCanonical; } + + void Connect(AbstractCanonical* aCanonical) + { + MIRROR_LOG("%s [%p] Connecting to %p", mName, this, aCanonical); + MOZ_ASSERT(OwnerThread()->IsCurrentThreadIn()); + MOZ_ASSERT(!IsConnected()); + + nsCOMPtr r = NS_NewRunnableMethodWithArg>> + (aCanonical, &AbstractCanonical::AddMirror, this); + aCanonical->OwnerThread()->Dispatch(r.forget()); + mCanonical = aCanonical; + } + + void DisconnectIfConnected() + { + MOZ_ASSERT(OwnerThread()->IsCurrentThreadIn()); + if (!IsConnected()) { + return; + } + + MIRROR_LOG("%s [%p] Disconnecting from %p", mName, this, mCanonical.get()); + nsCOMPtr r = NS_NewRunnableMethodWithArg>> + (mCanonical, &AbstractCanonical::RemoveMirror, this); + mCanonical->OwnerThread()->Dispatch(r.forget()); + mCanonical = nullptr; + } + + class Holder + { + public: + Holder() {} + ~Holder() + { + MOZ_DIAGNOSTIC_ASSERT(mMirror, "Should have initialized me"); + mMirror->DisconnectIfConnected(); + } + + // NB: Because mirror-initiated disconnection can race with canonical- + // initiated disconnection, a mirror should never be reinitialized. + void Init(AbstractThread* aThread, const T& aInitialValue, const char* aName) + { + mMirror = new Mirror(aThread, aInitialValue, aName); + } + + // Forward control operations to the Mirror. + void Connect(AbstractCanonical* aCanonical) { mMirror->Connect(aCanonical); } + void DisconnectIfConnected() { mMirror->DisconnectIfConnected(); } + + // Access to the Mirror. + operator Mirror&() { return *mMirror; } + Mirror* operator&() { return mMirror; } + + // Access to the T. + const T& Ref() { return *mMirror; } + operator const T&() { return Ref(); } + + private: + nsRefPtr> mMirror; + }; + +protected: + ~Mirror() { MOZ_DIAGNOSTIC_ASSERT(!IsConnected()); } + +private: + T mValue; + nsRefPtr> mCanonical; +}; + +#undef MIRROR_LOG + +} // namespace mozilla + +#endif diff --git a/dom/media/StateWatching.h b/dom/media/StateWatching.h index 5022ca7577e..ac8052d1d85 100644 --- a/dom/media/StateWatching.h +++ b/dom/media/StateWatching.h @@ -142,6 +142,8 @@ private: } nsTArray> mWatchers; + +protected: const char* mName; }; diff --git a/dom/media/moz.build b/dom/media/moz.build index db4d7dc8063..4546a2a89f8 100644 --- a/dom/media/moz.build +++ b/dom/media/moz.build @@ -137,6 +137,7 @@ EXPORTS += [ 'SelfRef.h', 'SharedBuffer.h', 'SharedThreadPool.h', + 'StateMirroring.h', 'StateWatching.h', 'StreamBuffer.h', 'TaskDispatcher.h', From 0566ba550c46ab42b258954438374eb4b250e8ad Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Tue, 31 Mar 2015 18:44:36 -0700 Subject: [PATCH 11/57] Bug 1144481 - Use state mirroring for NextFrameStatus. r=jww --- dom/html/HTMLMediaElement.cpp | 61 +++++---- dom/html/HTMLMediaElement.h | 12 +- dom/media/MediaDecoder.cpp | 31 ++--- dom/media/MediaDecoder.h | 12 +- dom/media/MediaDecoderOwner.h | 7 - dom/media/MediaDecoderStateMachine.cpp | 170 +++++++++++++----------- dom/media/MediaDecoderStateMachine.h | 28 +++- dom/media/gtest/MockMediaDecoderOwner.h | 3 - dom/media/omx/MediaOmxCommonDecoder.cpp | 14 +- dom/media/omx/MediaOmxCommonDecoder.h | 2 +- 10 files changed, 182 insertions(+), 158 deletions(-) diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp index 0221093a8c5..9fd087a438c 100644 --- a/dom/html/HTMLMediaElement.cpp +++ b/dom/html/HTMLMediaElement.cpp @@ -700,7 +700,6 @@ void HTMLMediaElement::AbortExistingLoads() mPendingEncryptedInitData.mInitDatas.Clear(); #endif // MOZ_EME mSourcePointer = nullptr; - mNextFrameStatus = NEXT_FRAME_UNINITIALIZED; mTags = nullptr; @@ -2047,7 +2046,6 @@ HTMLMediaElement::HTMLMediaElement(already_AddRefed& aNo mNetworkState(nsIDOMHTMLMediaElement::NETWORK_EMPTY), mReadyState(nsIDOMHTMLMediaElement::HAVE_NOTHING, "HTMLMediaElement::mReadyState"), mReadyStateUpdater("HTMLMediaElement::mReadyStateUpdater"), - mNextFrameStatus(NEXT_FRAME_UNINITIALIZED, "HTMLMediaElement::mNextFrameStatus"), mLoadWaitStatus(NOT_WAITING), mVolume(1.0), mPreloadAction(PRELOAD_UNDEFINED), @@ -2113,7 +2111,6 @@ HTMLMediaElement::HTMLMediaElement(already_AddRefed& aNo MOZ_ASSERT(NS_IsMainThread()); mReadyStateUpdater->AddWeakCallback(this, &HTMLMediaElement::UpdateReadyStateInternal); - mReadyStateUpdater->Watch(mNextFrameStatus); mReadyStateUpdater->Watch(mDownloadSuspendedByCache); // Paradoxically, there is a self-edge whereby UpdateReadyStateInternal refuses // to run until mReadyState reaches at least HAVE_METADATA by some other means. @@ -2614,8 +2611,8 @@ HTMLMediaElement::ReportMSETelemetry() ErrorResult ignore; stalled = index != TimeRanges::NoIndex && (ranges->End(index, ignore) - t) < errorMargin; - stalled |= mNextFrameStatus == MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE_BUFFERING && - mReadyState == HTMLMediaElement::HAVE_CURRENT_DATA; + stalled |= mDecoder && NextFrameStatus() == MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE_BUFFERING && + mReadyState == HTMLMediaElement::HAVE_CURRENT_DATA; if (stalled) { state = STALLED; } @@ -2850,13 +2847,16 @@ nsresult HTMLMediaElement::FinishDecoderSetup(MediaDecoder* aDecoder, return rv; } -class HTMLMediaElement::StreamListener : public MediaStreamListener { +class HTMLMediaElement::StreamListener : public MediaStreamListener, + public WatchTarget +{ public: - explicit StreamListener(HTMLMediaElement* aElement) : + explicit StreamListener(HTMLMediaElement* aElement, const char* aName) : + WatchTarget(aName), mElement(aElement), mHaveCurrentData(false), mBlocked(false), - mMutex("HTMLMediaElement::StreamListener"), + mMutex(aName), mPendingNotifyOutput(false) {} void Forget() { mElement = nullptr; } @@ -2869,24 +2869,25 @@ public: mElement->PlaybackEnded(); } } - void UpdateReadyStateForData() + + MediaDecoderOwner::NextFrameStatus NextFrameStatus() { - if (mElement && mHaveCurrentData) { - nsRefPtr deathGrip = mElement; - mElement->UpdateReadyStateForData( - mBlocked ? MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE_BUFFERING : - MediaDecoderOwner::NEXT_FRAME_AVAILABLE); + if (!mElement || !mHaveCurrentData) { + return MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE; } + return mBlocked ? MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE_BUFFERING + : MediaDecoderOwner::NEXT_FRAME_AVAILABLE; } + void DoNotifyBlocked() { mBlocked = true; - UpdateReadyStateForData(); + NotifyWatchers(); } void DoNotifyUnblocked() { mBlocked = false; - UpdateReadyStateForData(); + NotifyWatchers(); } void DoNotifyOutput() { @@ -2906,7 +2907,7 @@ public: nsRefPtr deathGrip = mElement; mElement->FirstFrameLoaded(); } - UpdateReadyStateForData(); + NotifyWatchers(); DoNotifyOutput(); } @@ -3070,8 +3071,9 @@ void HTMLMediaElement::SetupSrcMediaStreamPlayback(DOMMediaStream* aStream) // XXX if we ever support capturing the output of a media element which is // playing a stream, we'll need to add a CombineWithPrincipal call here. - mMediaStreamListener = new StreamListener(this); + mMediaStreamListener = new StreamListener(this, "HTMLMediaElement::mMediaStreamListener"); mMediaStreamSizeListener = new StreamSizeListener(this); + mReadyStateUpdater->Watch(*mMediaStreamListener); GetSrcMediaStream()->AddListener(mMediaStreamListener); // Listen for an initial image size on mSrcStream so we can get results even @@ -3121,6 +3123,7 @@ void HTMLMediaElement::EndSrcMediaStreamPlayback() } // Kill its reference to this element + mReadyStateUpdater->Unwatch(*mMediaStreamListener); mMediaStreamListener->Forget(); mMediaStreamListener = nullptr; mMediaStreamSizeListener->Forget(); @@ -3504,11 +3507,6 @@ bool HTMLMediaElement::IsCORSSameOrigin() ShouldCheckAllowOrigin(); } -void HTMLMediaElement::UpdateReadyStateForData(MediaDecoderOwner::NextFrameStatus aNextFrame) -{ - mNextFrameStatus = aNextFrame; -} - void HTMLMediaElement::UpdateReadyStateInternal() { @@ -3539,7 +3537,7 @@ HTMLMediaElement::UpdateReadyStateInternal() MetadataLoaded(&mediaInfo, nsAutoPtr(nullptr)); } - if (mNextFrameStatus == MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE_SEEKING) { + if (NextFrameStatus() == MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE_SEEKING) { ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_METADATA); return; } @@ -3568,9 +3566,9 @@ HTMLMediaElement::UpdateReadyStateInternal() return; } - if (mNextFrameStatus != MediaDecoderOwner::NEXT_FRAME_AVAILABLE) { + if (NextFrameStatus() != MediaDecoderOwner::NEXT_FRAME_AVAILABLE) { ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA); - if (!mWaitingFired && mNextFrameStatus == MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE_BUFFERING) { + if (!mWaitingFired && NextFrameStatus() == MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE_BUFFERING) { FireTimeUpdate(false); DispatchAsyncEvent(NS_LITERAL_STRING("waiting")); mWaitingFired = true; @@ -4700,5 +4698,16 @@ HTMLMediaElement::SetMozAudioChannelType(AudioChannel aValue, ErrorResult& aRv) SetHTMLAttr(nsGkAtoms::mozaudiochannel, channel, aRv); } +MediaDecoderOwner::NextFrameStatus +HTMLMediaElement::NextFrameStatus() +{ + if (mDecoder) { + return mDecoder->NextFrameStatus(); + } else if (mMediaStreamListener) { + return mMediaStreamListener->NextFrameStatus(); + } + return NEXT_FRAME_UNINITIALIZED; +} + } // namespace dom } // namespace mozilla diff --git a/dom/html/HTMLMediaElement.h b/dom/html/HTMLMediaElement.h index 04fcc0b5d62..f3b906d89da 100644 --- a/dom/html/HTMLMediaElement.h +++ b/dom/html/HTMLMediaElement.h @@ -220,13 +220,6 @@ public: // Dispatch events that were raised while in the bfcache nsresult DispatchPendingMediaEvents(); - // Called by the decoder when some data has been downloaded or - // buffering/seeking has ended. aNextFrameAvailable is true when - // the data for the next frame is available. This method will - // decide whether to set the ready state to HAVE_CURRENT_DATA, - // HAVE_FUTURE_DATA or HAVE_ENOUGH_DATA. - virtual void UpdateReadyStateForData(MediaDecoderOwner::NextFrameStatus aNextFrame) final override; - // Return true if we can activate autoplay assuming enough data has arrived. bool CanActivateAutoplay(); @@ -648,6 +641,8 @@ protected: class StreamListener; class StreamSizeListener; + MediaDecoderOwner::NextFrameStatus NextFrameStatus(); + void SetDecoder(MediaDecoder* aDecoder) { if (mDecoder) { @@ -1109,9 +1104,6 @@ protected: WatcherHolder mReadyStateUpdater; - // Last value passed from codec or stream source to UpdateReadyStateForData. - Watchable mNextFrameStatus; - enum LoadAlgorithmState { // No load algorithm instance is waiting for a source to be added to the // media in order to continue loading. diff --git a/dom/media/MediaDecoder.cpp b/dom/media/MediaDecoder.cpp index e0250db9bf2..ef02a79ca76 100644 --- a/dom/media/MediaDecoder.cpp +++ b/dom/media/MediaDecoder.cpp @@ -626,9 +626,15 @@ MediaDecoder::MediaDecoder() : } EnsureStateWatchingLog(); #endif + + mNextFrameStatus.Init(AbstractThread::MainThread(), MediaDecoderOwner::NEXT_FRAME_UNINITIALIZED, + "MediaDecoder::mNextFrameStatus (Mirror)"); + + mAudioChannel = AudioChannelService::GetDefaultAudioChannel(); mReadyStateWatchTarget->Watch(mPlayState); + mReadyStateWatchTarget->Watch(mNextFrameStatus); } bool MediaDecoder::Init(MediaDecoderOwner* aOwner) @@ -1052,7 +1058,7 @@ void MediaDecoder::PlaybackEnded() ChangeState(PLAY_STATE_ENDED); InvalidateWithFlags(VideoFrameContainer::INVALIDATE_FORCE); - UpdateReadyStateForData(); + mReadyStateWatchTarget->Notify(); // XXXbholley - Still necessary? if (mOwner) { mOwner->PlaybackEnded(); } @@ -1214,17 +1220,6 @@ void MediaDecoder::NotifyBytesConsumed(int64_t aBytes, int64_t aOffset) mDecoderPosition = aOffset + aBytes; } -void MediaDecoder::UpdateReadyStateForData() -{ - MOZ_ASSERT(NS_IsMainThread()); - if (!mOwner || mShuttingDown || !mDecoderStateMachine) { - return; - } - MediaDecoderOwner::NextFrameStatus frameStatus = - mDecoderStateMachine->GetNextFrameStatus(); - mOwner->UpdateReadyStateForData(frameStatus); -} - void MediaDecoder::OnSeekResolved(SeekResolveValue aVal) { MOZ_ASSERT(NS_IsMainThread()); @@ -1257,7 +1252,7 @@ void MediaDecoder::OnSeekResolved(SeekResolveValue aVal) PlaybackPositionChanged(aVal.mEventVisibility); if (mOwner) { - UpdateReadyStateForData(); + mReadyStateWatchTarget->Notify(); // XXXbholley - Still necessary? if (!seekWasAborted && (aVal.mEventVisibility != MediaDecoderEventVisibility::Suppressed)) { mOwner->SeekCompleted(); if (fireEnded) { @@ -1274,7 +1269,7 @@ void MediaDecoder::SeekingStarted(MediaDecoderEventVisibility aEventVisibility) return; if (mOwner) { - UpdateReadyStateForData(); + mReadyStateWatchTarget->Notify(); // XXXbholley - Still necessary? if (aEventVisibility != MediaDecoderEventVisibility::Suppressed) { mOwner->SeekStarted(); } @@ -1601,6 +1596,12 @@ MediaDecoder::SetStateMachine(MediaDecoderStateMachine* aStateMachine) { MOZ_ASSERT_IF(aStateMachine, !mDecoderStateMachine); mDecoderStateMachine = aStateMachine; + + if (mDecoderStateMachine) { + mNextFrameStatus.Connect(mDecoderStateMachine->CanonicalNextFrameStatus()); + } else { + mNextFrameStatus.DisconnectIfConnected(); + } } ReentrantMonitor& MediaDecoder::GetReentrantMonitor() { @@ -1651,7 +1652,7 @@ void MediaDecoder::NotifyDataArrived(const char* aBuffer, uint32_t aLength, int6 if (mDecoderStateMachine) { mDecoderStateMachine->NotifyDataArrived(aBuffer, aLength, aOffset); } - UpdateReadyStateForData(); + mReadyStateWatchTarget->Notify(); // XXXbholley - Still necessary? } // Provide access to the state machine object diff --git a/dom/media/MediaDecoder.h b/dom/media/MediaDecoder.h index f7b92aa7a85..6b50c7df9ef 100644 --- a/dom/media/MediaDecoder.h +++ b/dom/media/MediaDecoder.h @@ -194,8 +194,10 @@ destroying the MediaDecoder object. #include "mozilla/dom/AudioChannelBinding.h" #include "mozilla/gfx/Rect.h" #include "mozilla/ReentrantMonitor.h" +#include "MediaDecoderOwner.h" #include "MediaStreamGraph.h" #include "AbstractMediaDecoder.h" +#include "StateMirroring.h" #include "StateWatching.h" #include "necko-config.h" #ifdef MOZ_EME @@ -218,7 +220,6 @@ class Image; class VideoFrameContainer; class MediaDecoderStateMachine; -class MediaDecoderOwner; // GetCurrentTime is defined in winbase.h as zero argument macro forwarding to // GetTickCount() and conflicts with MediaDecoder::GetCurrentTime implementation. @@ -827,10 +828,6 @@ public: // This must be called on the main thread only. virtual void PlaybackPositionChanged(MediaDecoderEventVisibility aEventVisibility = MediaDecoderEventVisibility::Observable); - // Calls mElement->UpdateReadyStateForData, telling it whether we have - // data for the next frame and if we're buffering. Main thread only. - virtual void UpdateReadyStateForData(); - // Find the end of the cached data starting at the current decoder // position. int64_t GetDownloadPosition(); @@ -1049,6 +1046,8 @@ public: WatchTarget& ReadyStateWatchTarget() { return *mReadyStateWatchTarget; } + virtual MediaDecoderOwner::NextFrameStatus NextFrameStatus() { return mNextFrameStatus; } + protected: virtual ~MediaDecoder(); void SetStateMachineParameters(); @@ -1066,6 +1065,9 @@ protected: WatcherHolder mReadyStateWatchTarget; + // NextFrameStatus, mirrored from the state machine. + Mirror::Holder mNextFrameStatus; + /****** * The following members should be accessed with the decoder lock held. ******/ diff --git a/dom/media/MediaDecoderOwner.h b/dom/media/MediaDecoderOwner.h index b4d8d015682..98b7ca9bfb0 100644 --- a/dom/media/MediaDecoderOwner.h +++ b/dom/media/MediaDecoderOwner.h @@ -113,13 +113,6 @@ public: NEXT_FRAME_UNINITIALIZED }; - // Called by the decoder when some data has been downloaded or - // buffering/seeking has ended. aNextFrameAvailable is true when - // the data for the next frame is available. This method will - // decide whether to set the ready state to HAVE_CURRENT_DATA, - // HAVE_FUTURE_DATA or HAVE_ENOUGH_DATA. - virtual void UpdateReadyStateForData(NextFrameStatus aNextFrame) = 0; - // Check if the decoder owner is active. virtual bool IsActive() = 0; diff --git a/dom/media/MediaDecoderStateMachine.cpp b/dom/media/MediaDecoderStateMachine.cpp index e091cf5bfd5..d43215a33d5 100644 --- a/dom/media/MediaDecoderStateMachine.cpp +++ b/dom/media/MediaDecoderStateMachine.cpp @@ -239,7 +239,6 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder, mDropVideoUntilNextDiscontinuity(false), mDecodeToSeekTarget(false), mCurrentTimeBeforeSeek(0), - mLastFrameStatus(MediaDecoderOwner::NEXT_FRAME_UNINITIALIZED), mCorruptFrames(30), mDisabledHardwareAcceleration(false), mDecodingFrozenAtStateDecoding(false), @@ -255,6 +254,9 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder, MOZ_DIAGNOSTIC_ASSERT(pool); mTaskQueue = new MediaTaskQueue(pool.forget(), /* aAssertTailDispatch = */ true); + mNextFrameStatus.Init(mTaskQueue, MediaDecoderOwner::NEXT_FRAME_UNINITIALIZED, + "MediaDecoderStateMachine::mNextFrameStatus (Canonical)"); + static bool sPrefCacheInit = false; if (!sPrefCacheInit) { sPrefCacheInit = true; @@ -556,7 +558,7 @@ void MediaDecoderStateMachine::SendStreamData() // the decoding speed. if (a && a->mTime <= clockTime) { OnAudioEndTimeUpdate(std::max(mAudioEndTime, a->GetEndTime())); - nsRefPtr releaseMe = AudioQueue().PopFront(); + nsRefPtr releaseMe = PopAudio(); continue; } break; @@ -566,7 +568,7 @@ void MediaDecoderStateMachine::SendStreamData() // until all samples are drained. if (finished && AudioQueue().GetSize() == 0) { mAudioCompleted = true; - UpdateReadyState(); + UpdateNextFrameStatus(); } } @@ -801,7 +803,7 @@ MediaDecoderStateMachine::OnAudioDecoded(AudioData* aAudioSample) } if (mCurrentSeek.mTarget.mType == SeekTarget::PrevSyncPoint) { // Non-precise seek; we can stop the seek at the first sample. - AudioQueue().Push(audio); + Push(audio); } else { // We're doing an accurate seek. We must discard // MediaData up to the one containing exact seek target. @@ -830,13 +832,21 @@ MediaDecoderStateMachine::Push(AudioData* aSample) // otherwise AdvanceFrame may pop the sample before we have a chance // to reach playing. AudioQueue().Push(aSample); - if (mState > DECODER_STATE_DECODING_FIRSTFRAME) { - // The ready state can change when we've decoded data, so update the - // ready state, so that DOM events can fire. - UpdateReadyState(); - DispatchDecodeTasksIfNeeded(); - mDecoder->GetReentrantMonitor().NotifyAll(); - } + UpdateNextFrameStatus(); + DispatchDecodeTasksIfNeeded(); + + // XXXbholley - Still necessary? + mDecoder->GetReentrantMonitor().NotifyAll(); +} + +void +MediaDecoderStateMachine::PushFront(AudioData* aSample) +{ + MOZ_ASSERT(OnTaskQueue()); + MOZ_ASSERT(aSample); + + AudioQueue().PushFront(aSample); + UpdateNextFrameStatus(); } void @@ -848,13 +858,39 @@ MediaDecoderStateMachine::Push(VideoData* aSample) // otherwise AdvanceFrame may pop the sample before we have a chance // to reach playing. VideoQueue().Push(aSample); - if (mState > DECODER_STATE_DECODING_FIRSTFRAME) { - // The ready state can change when we've decoded data, so update the - // ready state, so that DOM events can fire. - UpdateReadyState(); - DispatchDecodeTasksIfNeeded(); - mDecoder->GetReentrantMonitor().NotifyAll(); - } + UpdateNextFrameStatus(); + DispatchDecodeTasksIfNeeded(); + + // XXXbholley - Is this still necessary? + mDecoder->GetReentrantMonitor().NotifyAll(); +} + +void +MediaDecoderStateMachine::PushFront(VideoData* aSample) +{ + MOZ_ASSERT(OnTaskQueue()); + MOZ_ASSERT(aSample); + + VideoQueue().PushFront(aSample); + UpdateNextFrameStatus(); +} + +already_AddRefed +MediaDecoderStateMachine::PopAudio() +{ + MOZ_ASSERT(OnTaskQueue()); + nsRefPtr sample = AudioQueue().PopFront(); + UpdateNextFrameStatus(); + return sample.forget(); +} + +already_AddRefed +MediaDecoderStateMachine::PopVideo() +{ + MOZ_ASSERT(OnTaskQueue()); + nsRefPtr sample = VideoQueue().PopFront(); + UpdateNextFrameStatus(); + return sample.forget(); } void @@ -910,7 +946,7 @@ MediaDecoderStateMachine::OnNotDecoded(MediaData::Type aType, // insert it into the queue so that we have something to display. // We make sure to do this before invoking VideoQueue().Finish() // below. - VideoQueue().Push(mFirstVideoFrameAfterSeek); + Push(mFirstVideoFrameAfterSeek); mFirstVideoFrameAfterSeek = nullptr; } if (isAudio) { @@ -931,7 +967,7 @@ MediaDecoderStateMachine::OnNotDecoded(MediaData::Type aType, CheckIfDecodeComplete(); // The ready state can change when we've decoded data, so update the // ready state, so that DOM events can fire. - UpdateReadyState(); + UpdateNextFrameStatus(); mDecoder->GetReentrantMonitor().NotifyAll(); // Schedule the state machine to notify track ended as soon as possible. if (mAudioCaptured) { @@ -1061,7 +1097,7 @@ MediaDecoderStateMachine::OnVideoDecoded(VideoData* aVideoSample) } if (mCurrentSeek.mTarget.mType == SeekTarget::PrevSyncPoint) { // Non-precise seek; we can stop the seek at the first sample. - VideoQueue().Push(video); + Push(video); } else { // We're doing an accurate seek. We still need to discard // MediaData up to the one containing exact seek target. @@ -1287,19 +1323,6 @@ void MediaDecoderStateMachine::ClearPositionChangeFlag() mPositionChangeQueued = false; } -MediaDecoderOwner::NextFrameStatus MediaDecoderStateMachine::GetNextFrameStatus() -{ - ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); - if (IsBuffering()) { - return MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE_BUFFERING; - } else if (IsSeeking()) { - return MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE_SEEKING; - } else if (HaveNextFrameData()) { - return MediaDecoderOwner::NEXT_FRAME_AVAILABLE; - } - return MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE; -} - static const char* const gMachineStateStr[] = { "NONE", "DECODING_METADATA", @@ -1869,9 +1892,11 @@ MediaDecoderStateMachine::InitiateSeek() StopPlayback(); UpdatePlaybackPositionInternal(mCurrentSeek.mTarget.mTime); - // SeekingStarted will do a UpdateReadyStateForData which will - // inform the element and its users that we have no frames - // to display + + // Make sure the main thread decoder gets notified of the seek only after + // we've updated the mirrored NextFrameStatus, which has special behavior + // when we're in DECODER_STATE_SEEKING. + UpdateNextFrameStatus(); nsCOMPtr startEvent = NS_NewRunnableMethodWithArg( mDecoder, @@ -2515,6 +2540,9 @@ MediaDecoderStateMachine::FinishShutdown() // mPendingWakeDecoder being needed again. Revoke it. mPendingWakeDecoder = nullptr; + // Disconnect mirrors before shutting down our task queue. + mNextFrameStatus.DisconnectAll(); + MOZ_ASSERT(mState == DECODER_STATE_SHUTDOWN, "How did we escape from the shutdown state?"); // We must daisy-chain these events to destroy the decoder. We must @@ -2674,7 +2702,7 @@ nsresult MediaDecoderStateMachine::RunStateMachine() // Notify to allow blocked decoder thread to continue mDecoder->GetReentrantMonitor().NotifyAll(); - UpdateReadyState(); + UpdateNextFrameStatus(); MaybeStartPlayback(); NS_ASSERTION(IsStateMachineScheduled(), "Must have timer scheduled"); return NS_OK; @@ -2932,7 +2960,7 @@ void MediaDecoderStateMachine::AdvanceFrame() #endif } currentFrame = frame; - nsRefPtr releaseMe = VideoQueue().PopFront(); + nsRefPtr releaseMe = PopVideo(); // Notify the decode thread that the video queue's buffers may have // free'd up space for more frames. mDecoder->GetReentrantMonitor().NotifyAll(); @@ -2966,7 +2994,7 @@ void MediaDecoderStateMachine::AdvanceFrame() } if (shouldBuffer) { if (currentFrame) { - VideoQueue().PushFront(currentFrame); + PushFront(currentFrame); } StartBuffering(); // Don't go straight back to the state machine loop since that might @@ -3032,7 +3060,7 @@ void MediaDecoderStateMachine::AdvanceFrame() // this function popping and playing a video frame, or by the audio // thread popping and playing an audio frame, we may need to update our // ready state. Post an update to do so. - UpdateReadyState(); + UpdateNextFrameStatus(); int64_t delay = remainingTime / mPlaybackRate; if (delay > 0) { @@ -3087,7 +3115,7 @@ MediaDecoderStateMachine::DropVideoUpToSeekTarget(VideoData* aSample) DECODER_LOG("DropVideoUpToSeekTarget() found video frame [%lld, %lld] containing target=%lld", video->mTime, video->GetEndTime(), target); - VideoQueue().PushFront(video); + PushFront(video); } return NS_OK; @@ -3122,7 +3150,7 @@ MediaDecoderStateMachine::DropAudioUpToSeekTarget(AudioData* aSample) // silence to cover the gap. Typically this happens in poorly muxed // files. DECODER_WARN("Audio not synced after seek, maybe a poorly muxed file?"); - AudioQueue().Push(audio); + Push(audio); return NS_OK; } @@ -3158,7 +3186,7 @@ MediaDecoderStateMachine::DropAudioUpToSeekTarget(AudioData* aSample) audioData.forget(), channels, audio->mRate)); - AudioQueue().PushFront(data); + PushFront(data); return NS_OK; } @@ -3191,30 +3219,31 @@ void MediaDecoderStateMachine::SetStartTime(int64_t aStartTimeUsecs) DECODER_LOG("Set media start time to %lld", mStartTime); } -void MediaDecoderStateMachine::UpdateReadyState() { +void MediaDecoderStateMachine::UpdateNextFrameStatus() { + MOZ_ASSERT(OnTaskQueue()); AssertCurrentThreadInMonitor(); - MediaDecoderOwner::NextFrameStatus nextFrameStatus = GetNextFrameStatus(); - // FIXME: This optimization could result in inconsistent next frame status - // between the decoder and state machine when GetNextFrameStatus() is called - // by the decoder without updating mLastFrameStatus. - // Note not to regress bug 882027 when fixing this bug. - if (nextFrameStatus == mLastFrameStatus) { - return; + MediaDecoderOwner::NextFrameStatus status; + const char* statusString; + if (IsBuffering()) { + status = MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE_BUFFERING; + statusString = "NEXT_FRAME_UNAVAILABLE_BUFFERING"; + } else if (IsSeeking()) { + status = MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE_SEEKING; + statusString = "NEXT_FRAME_UNAVAILABLE_SEEKING"; + } else if (HaveNextFrameData()) { + status = MediaDecoderOwner::NEXT_FRAME_AVAILABLE; + statusString = "NEXT_FRAME_AVAILABLE"; + } else { + status = MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE; + statusString = "NEXT_FRAME_UNAVAILABLE"; } - mLastFrameStatus = nextFrameStatus; - /* This is a bit tricky. MediaDecoder::UpdateReadyStateForData will run on - * the main thread and re-evaluate GetNextFrameStatus there, passing it to - * HTMLMediaElement::UpdateReadyStateForData. It doesn't use the value of - * GetNextFrameStatus we computed here, because what we're computing here - * could be stale by the time MediaDecoder::UpdateReadyStateForData runs. - * We only compute GetNextFrameStatus here to avoid posting runnables to the main - * thread unnecessarily. - */ - nsCOMPtr event; - event = NS_NewRunnableMethod(mDecoder, &MediaDecoder::UpdateReadyStateForData); - AbstractThread::MainThread()->Dispatch(event.forget()); + if (status != mNextFrameStatus) { + DECODER_LOG("Changed mNextFrameStatus to %s", statusString); + } + + mNextFrameStatus = status; } bool MediaDecoderStateMachine::JustExitedQuickBuffering() @@ -3251,17 +3280,8 @@ void MediaDecoderStateMachine::StartBuffering() decodeDuration < UsecsToDuration(QUICK_BUFFER_THRESHOLD_USECS); mBufferingStart = TimeStamp::Now(); - // We need to tell the element that buffering has started. - // We can't just directly send an asynchronous runnable that - // eventually fires the "waiting" event. The problem is that - // there might be pending main-thread events, such as "data - // received" notifications, that mean we're not actually still - // buffering by the time this runnable executes. So instead - // we just trigger UpdateReadyStateForData; when it runs, it - // will check the current state and decide whether to tell - // the element we're buffering or not. SetState(DECODER_STATE_BUFFERING); - UpdateReadyState(); + UpdateNextFrameStatus(); DECODER_LOG("Changed state from DECODING to BUFFERING, decoded for %.3lfs", decodeDuration.ToSeconds()); #ifdef PR_LOGGING @@ -3444,7 +3464,7 @@ void MediaDecoderStateMachine::OnAudioSinkComplete() } ResyncAudioClock(); mAudioCompleted = true; - UpdateReadyState(); + UpdateNextFrameStatus(); // Kick the decode thread; it may be sleeping waiting for this to finish. mDecoder->GetReentrantMonitor().NotifyAll(); } diff --git a/dom/media/MediaDecoderStateMachine.h b/dom/media/MediaDecoderStateMachine.h index 9e21e6ebea6..a383e6b74f6 100644 --- a/dom/media/MediaDecoderStateMachine.h +++ b/dom/media/MediaDecoderStateMachine.h @@ -91,6 +91,7 @@ hardware (via AudioStream). #include "MediaMetadataManager.h" #include "mozilla/RollingMean.h" #include "MediaTimer.h" +#include "StateMirroring.h" namespace mozilla { @@ -122,6 +123,7 @@ class MediaDecoderStateMachine friend class AudioSink; NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDecoderStateMachine) public: + typedef MediaDecoderOwner::NextFrameStatus NextFrameStatus; typedef MediaDecoder::DecodedStreamData DecodedStreamData; MediaDecoderStateMachine(MediaDecoder* aDecoder, MediaDecoderReader* aReader, @@ -209,8 +211,6 @@ public: bool OnDecodeTaskQueue() const; bool OnTaskQueue() const; - MediaDecoderOwner::NextFrameStatus GetNextFrameStatus(); - // Cause state transitions. These methods obtain the decoder monitor // to synchronise the change of state, and to notify other threads // that the state has changed. @@ -432,6 +432,16 @@ protected: // aSample must not be null. void Push(AudioData* aSample); void Push(VideoData* aSample); + void PushFront(AudioData* aSample); + void PushFront(VideoData* aSample); + + // Pops MediaData* samples from their respective MediaQueues. + // Note that the audio queue is also drained on the audio thread, + // which we can't easily react to - This should be fixed when we + // remove the audio thread in bug 750596. + already_AddRefed PopAudio(); + already_AddRefed PopVideo(); + class WakeDecoderRunnable : public nsRunnable { public: @@ -517,8 +527,9 @@ protected: // Returns true if we recently exited "quick buffering" mode. bool JustExitedQuickBuffering(); - // Dispatches an asynchronous event to update the media element's ready state. - void UpdateReadyState(); + // Recomputes mNextFrameStatus, possibly dispatching notifications to interested + // parties. + void UpdateNextFrameStatus(); // Called when AudioSink reaches the end. |mPlayStartTime| and // |mPlayDuration| are updated to provide a good base for calculating video @@ -881,6 +892,13 @@ public: // as mStartTime and mEndTime could have been set separately. bool mDurationSet; + // The status of our next frame. Mirrored on the main thread and used to + // compute ready state. + Canonical::Holder mNextFrameStatus; +public: + AbstractCanonical* CanonicalNextFrameStatus() { return &mNextFrameStatus; } +protected: + struct SeekJob { void Steal(SeekJob& aOther) { @@ -1213,8 +1231,6 @@ public: mozilla::MediaMetadataManager mMetadataManager; - MediaDecoderOwner::NextFrameStatus mLastFrameStatus; - mozilla::RollingMean mCorruptFrames; bool mDisabledHardwareAcceleration; diff --git a/dom/media/gtest/MockMediaDecoderOwner.h b/dom/media/gtest/MockMediaDecoderOwner.h index c7dc55216ad..fe91ea7f4b9 100644 --- a/dom/media/gtest/MockMediaDecoderOwner.h +++ b/dom/media/gtest/MockMediaDecoderOwner.h @@ -33,9 +33,6 @@ public: virtual void DownloadResumed(bool aForceNetworkLoading) override {} virtual void NotifySuspendedByCache(bool aIsSuspended) override {} virtual void NotifyDecoderPrincipalChanged() override {} - virtual void UpdateReadyStateForData(NextFrameStatus aNextFrame) override - { - } virtual VideoFrameContainer* GetVideoFrameContainer() override { return nullptr; diff --git a/dom/media/omx/MediaOmxCommonDecoder.cpp b/dom/media/omx/MediaOmxCommonDecoder.cpp index 2820e964242..84a527e39b0 100644 --- a/dom/media/omx/MediaOmxCommonDecoder.cpp +++ b/dom/media/omx/MediaOmxCommonDecoder.cpp @@ -264,18 +264,12 @@ MediaOmxCommonDecoder::SetElementVisibility(bool aIsVisible) } } -void -MediaOmxCommonDecoder::UpdateReadyStateForData() +MediaDecoderOwner::NextFrameStatus +MediaOmxCommonDecoder::NextFrameStatus() { MOZ_ASSERT(NS_IsMainThread()); - if (!mAudioOffloadPlayer) { - MediaDecoder::UpdateReadyStateForData(); - return; - } - - if (!mOwner || mShuttingDown) - return; - mOwner->UpdateReadyStateForData(mAudioOffloadPlayer->GetNextFrameStatus()); + return mAudioOffloadPlayer ? mAudioOffloadPlayer->GetNextFrameStatus() + : MediaDecoder::NextFrameStatus(); } void diff --git a/dom/media/omx/MediaOmxCommonDecoder.h b/dom/media/omx/MediaOmxCommonDecoder.h index a770a2acd84..31fd55be2cf 100644 --- a/dom/media/omx/MediaOmxCommonDecoder.h +++ b/dom/media/omx/MediaOmxCommonDecoder.h @@ -30,7 +30,7 @@ public: virtual void SetVolume(double aVolume); virtual void PlaybackPositionChanged(MediaDecoderEventVisibility aEventVisibility = MediaDecoderEventVisibility::Observable); - virtual void UpdateReadyStateForData(); + virtual MediaDecoderOwner::NextFrameStatus NextFrameStatus() override; virtual void SetElementVisibility(bool aIsVisible); virtual void SetPlatformCanOffloadAudio(bool aCanOffloadAudio); virtual bool CheckDecoderCanOffloadAudio(); From ecf6194c8451180d4339df3d6b9c62911da0307c Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Thu, 23 Apr 2015 15:10:27 -0400 Subject: [PATCH 12/57] Bug 1039866 - Delete widget/windows/winrt. r=jimm --- widget/windows/winrt/APZController.cpp | 314 ---- widget/windows/winrt/APZController.h | 78 - widget/windows/winrt/DisplayInfo_sdk81.h | 458 ----- widget/windows/winrt/FrameworkView.cpp | 507 ----- widget/windows/winrt/FrameworkView.h | 205 --- widget/windows/winrt/Makefile.in | 19 - widget/windows/winrt/MetroApp.cpp | 282 --- widget/windows/winrt/MetroApp.h | 62 - widget/windows/winrt/MetroAppShell.cpp | 522 ------ widget/windows/winrt/MetroAppShell.h | 44 - widget/windows/winrt/MetroContracts.cpp | 576 ------ widget/windows/winrt/MetroD3DCheckHelper.h | 96 - widget/windows/winrt/MetroInput.cpp | 1573 ---------------- widget/windows/winrt/MetroInput.h | 292 --- widget/windows/winrt/MetroUIUtils.js | 175 -- widget/windows/winrt/MetroUIUtils.manifest | 3 - widget/windows/winrt/MetroUtils.cpp | 190 -- widget/windows/winrt/MetroUtils.h | 96 - widget/windows/winrt/MetroWidget.cpp | 1628 ----------------- widget/windows/winrt/MetroWidget.h | 280 --- .../winrt/ToastNotificationHandler.cpp | 153 -- .../windows/winrt/ToastNotificationHandler.h | 44 - .../windows/winrt/UIAAccessibilityBridge.cpp | 54 - widget/windows/winrt/UIAAccessibilityBridge.h | 80 - widget/windows/winrt/UIABridge.cpp | 801 -------- widget/windows/winrt/UIABridge.idl | 22 - widget/windows/winrt/UIABridgePrivate.h | 139 -- widget/windows/winrt/UIABridgePublic.h | 19 - widget/windows/winrt/WakeLockListener.cpp | 29 - widget/windows/winrt/WakeLockListener.h | 25 - widget/windows/winrt/moz.build | 52 - widget/windows/winrt/mozwrlbase.h | 77 - widget/windows/winrt/nsMetroFilePicker.cpp | 484 ----- widget/windows/winrt/nsMetroFilePicker.h | 69 - widget/windows/winrt/nsWinMetroUtils.cpp | 402 ---- widget/windows/winrt/nsWinMetroUtils.h | 27 - 36 files changed, 9877 deletions(-) delete mode 100644 widget/windows/winrt/APZController.cpp delete mode 100644 widget/windows/winrt/APZController.h delete mode 100644 widget/windows/winrt/DisplayInfo_sdk81.h delete mode 100644 widget/windows/winrt/FrameworkView.cpp delete mode 100644 widget/windows/winrt/FrameworkView.h delete mode 100644 widget/windows/winrt/Makefile.in delete mode 100644 widget/windows/winrt/MetroApp.cpp delete mode 100644 widget/windows/winrt/MetroApp.h delete mode 100644 widget/windows/winrt/MetroAppShell.cpp delete mode 100644 widget/windows/winrt/MetroAppShell.h delete mode 100644 widget/windows/winrt/MetroContracts.cpp delete mode 100644 widget/windows/winrt/MetroD3DCheckHelper.h delete mode 100644 widget/windows/winrt/MetroInput.cpp delete mode 100644 widget/windows/winrt/MetroInput.h delete mode 100644 widget/windows/winrt/MetroUIUtils.js delete mode 100644 widget/windows/winrt/MetroUIUtils.manifest delete mode 100644 widget/windows/winrt/MetroUtils.cpp delete mode 100644 widget/windows/winrt/MetroUtils.h delete mode 100644 widget/windows/winrt/MetroWidget.cpp delete mode 100644 widget/windows/winrt/MetroWidget.h delete mode 100644 widget/windows/winrt/ToastNotificationHandler.cpp delete mode 100644 widget/windows/winrt/ToastNotificationHandler.h delete mode 100644 widget/windows/winrt/UIAAccessibilityBridge.cpp delete mode 100644 widget/windows/winrt/UIAAccessibilityBridge.h delete mode 100644 widget/windows/winrt/UIABridge.cpp delete mode 100644 widget/windows/winrt/UIABridge.idl delete mode 100644 widget/windows/winrt/UIABridgePrivate.h delete mode 100644 widget/windows/winrt/UIABridgePublic.h delete mode 100644 widget/windows/winrt/WakeLockListener.cpp delete mode 100644 widget/windows/winrt/WakeLockListener.h delete mode 100644 widget/windows/winrt/moz.build delete mode 100644 widget/windows/winrt/mozwrlbase.h delete mode 100644 widget/windows/winrt/nsMetroFilePicker.cpp delete mode 100644 widget/windows/winrt/nsMetroFilePicker.h delete mode 100644 widget/windows/winrt/nsWinMetroUtils.cpp delete mode 100644 widget/windows/winrt/nsWinMetroUtils.h diff --git a/widget/windows/winrt/APZController.cpp b/widget/windows/winrt/APZController.cpp deleted file mode 100644 index 549caaf83e5..00000000000 --- a/widget/windows/winrt/APZController.cpp +++ /dev/null @@ -1,314 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "APZController.h" -#include "base/message_loop.h" -#include "mozilla/layers/GeckoContentController.h" -#include "nsThreadUtils.h" -#include "MetroUtils.h" -#include "nsPrintfCString.h" -#include "mozilla/layers/APZCCallbackHelper.h" -#include "nsIDocument.h" -#include "nsPresContext.h" -#include "nsIDOMElement.h" -#include "mozilla/dom/Element.h" -#include "nsIDOMWindowUtils.h" -#include "nsIInterfaceRequestorUtils.h" -#include "nsLayoutUtils.h" -#include "mozilla/TouchEvents.h" - -//#define DEBUG_CONTROLLER 1 - -#ifdef DEBUG_CONTROLLER -#include "WinUtils.h" -using namespace mozilla::widget; -#endif - -namespace mozilla { -namespace widget { -namespace winrt { - -nsRefPtr APZController::sAPZC; - -/* - * Metro layout specific - test to see if a sub document is a - * tab. - */ -static bool -IsTab(nsCOMPtr& aSubDocument) -{ - nsRefPtr parent = aSubDocument->GetParentDocument(); - if (!parent) { - NS_WARNING("huh? IsTab should always get a sub document for a parameter"); - return false; - } - return parent->IsRootDisplayDocument(); -} - -/* - * Returns the sub document associated with the scroll id. - */ -static bool -GetDOMTargets(uint64_t aScrollId, - nsCOMPtr& aSubDocument, - nsCOMPtr& aTargetContent) -{ - // For tabs and subframes this will return the HTML sub document - aTargetContent = nsLayoutUtils::FindContentFor(aScrollId); - if (!aTargetContent) { - return false; - } - nsCOMPtr domElement = do_QueryInterface(aTargetContent); - if (!domElement) { - return false; - } - - aSubDocument = domElement->OwnerDoc(); - - if (!aSubDocument) { - return false; - } - - // If the root element equals domElement, FindElementWithViewId found - // a document, vs. an element within a document. - if (aSubDocument->GetRootElement() == domElement && IsTab(aSubDocument)) { - aTargetContent = nullptr; - } - - return true; -} - -void -APZController::SetPendingResponseFlusher(APZPendingResponseFlusher* aFlusher) -{ - mFlusher = aFlusher; -} - -void -APZController::ContentReceivedInputBlock(const uint64_t aInputBlockId, bool aPreventDefault) -{ - if (!sAPZC) { - return; - } - sAPZC->ContentReceivedInputBlock(aInputBlockId, aPreventDefault); -} - -bool -APZController::HitTestAPZC(ScreenIntPoint& aPoint) -{ - if (!sAPZC) { - return false; - } - return sAPZC->HitTestAPZC(aPoint); -} - -void -APZController::TransformCoordinateToGecko(const ScreenIntPoint& aPoint, - LayoutDeviceIntPoint* aRefPointOut) -{ - if (!sAPZC || !aRefPointOut) { - return; - } - sAPZC->TransformCoordinateToGecko(aPoint, aRefPointOut); -} - -nsEventStatus -APZController::ReceiveInputEvent(WidgetInputEvent* aEvent, - ScrollableLayerGuid* aOutTargetGuid, - uint64_t* aOutInputBlockId) -{ - MOZ_ASSERT(aEvent); - - if (!sAPZC) { - return nsEventStatus_eIgnore; - } - return sAPZC->ReceiveInputEvent(*aEvent->AsInputEvent(), aOutTargetGuid, aOutInputBlockId); -} - -// APZC sends us this request when we need to update the display port on -// the scrollable frame the apzc is managing. -void -APZController::RequestContentRepaint(const FrameMetrics& aFrameMetrics) -{ -#ifdef DEBUG_CONTROLLER - WinUtils::Log("APZController::RequestContentRepaint scrollid=%I64d", - aFrameMetrics.GetScrollId()); -#endif - - // This must be on the gecko thread since we access the dom - MOZ_ASSERT(NS_IsMainThread()); - -#ifdef DEBUG_CONTROLLER - WinUtils::Log("APZController: mScrollOffset: %f %f", aFrameMetrics.mScrollOffset.x, - aFrameMetrics.mScrollOffset.y); -#endif - - nsCOMPtr subDocument; - nsCOMPtr targetContent; - if (!GetDOMTargets(aFrameMetrics.GetScrollId(), - subDocument, targetContent)) { - return; - } - - // If we're dealing with a sub frame or content editable element, - // call UpdateSubFrame. - if (targetContent) { -#ifdef DEBUG_CONTROLLER - WinUtils::Log("APZController: detected subframe or content editable"); -#endif - FrameMetrics metrics = aFrameMetrics; - mozilla::layers::APZCCallbackHelper::UpdateSubFrame(targetContent, metrics); - return; - } - -#ifdef DEBUG_CONTROLLER - WinUtils::Log("APZController: detected tab"); -#endif - - // We're dealing with a tab, call UpdateRootFrame. - FrameMetrics metrics = aFrameMetrics; - if (subDocument->GetShell()) { - mozilla::layers::APZCCallbackHelper::UpdateRootFrame(subDocument->GetShell(), metrics); - } - -#ifdef DEBUG_CONTROLLER - WinUtils::Log("APZController: %I64d mDisplayPortMargins: %0.2f %0.2f %0.2f %0.2f", - metrics.GetScrollId(), - metrics.GetDisplayPortMargins().left, - metrics.GetDisplayPortMargins().top, - metrics.GetDisplayPortMargins().right, - metrics.GetDisplayPortMargins().bottom); -#endif -} - -void -APZController::RequestFlingSnap(const FrameMetrics::ViewID& aScrollId, - const mozilla::CSSPoint& aDestination) -{ -#ifdef DEBUG_CONTROLLER - WinUtils::Log("APZController::RequestFlingSnap scrollid=%I64d destination: %lu %lu", - aScrollId, aDestination.x, aDestination.y); -#endif - mozilla::layers::APZCCallbackHelper::RequestFlingSnap(aScrollId, aDestination); -} - -void -APZController::AcknowledgeScrollUpdate(const FrameMetrics::ViewID& aScrollId, - const uint32_t& aScrollGeneration) -{ -#ifdef DEBUG_CONTROLLER - WinUtils::Log("APZController::AcknowledgeScrollUpdate scrollid=%I64d gen=%lu", - aScrollId, aScrollGeneration); -#endif - mozilla::layers::APZCCallbackHelper::AcknowledgeScrollUpdate(aScrollId, aScrollGeneration); -} - -void -APZController::HandleDoubleTap(const CSSPoint& aPoint, - Modifiers aModifiers, - const ScrollableLayerGuid& aGuid) -{ -} - -void -APZController::HandleSingleTap(const CSSPoint& aPoint, - Modifiers aModifiers, - const ScrollableLayerGuid& aGuid) -{ -} - -void -APZController::HandleLongTap(const CSSPoint& aPoint, - Modifiers aModifiers, - const mozilla::layers::ScrollableLayerGuid& aGuid, - uint64_t aInputBlockId) -{ - if (mFlusher) { - mFlusher->FlushPendingContentResponse(); - } - ContentReceivedInputBlock(aInputBlockId, false); -} - -// requests that we send a mozbrowserasyncscroll domevent. not in use. -void -APZController::SendAsyncScrollDOMEvent(bool aIsRoot, - const CSSRect &aContentRect, - const CSSSize &aScrollableSize) -{ -} - -void -APZController::PostDelayedTask(Task* aTask, int aDelayMs) -{ - MessageLoop::current()->PostDelayedTask(FROM_HERE, aTask, aDelayMs); -} - -bool -APZController::GetRootZoomConstraints(ZoomConstraints* aOutConstraints) -{ - if (aOutConstraints) { - // Until we support the meta-viewport tag properly allow zooming - // from 1/4 to 4x by default. - aOutConstraints->mAllowZoom = true; - aOutConstraints->mAllowDoubleTapZoom = false; - aOutConstraints->mMinZoom = CSSToParentLayerScale(0.25f); - aOutConstraints->mMaxZoom = CSSToParentLayerScale(4.0f); - return true; - } - return false; -} - -// apzc notifications - -class TransformedStartEvent : public nsRunnable -{ - NS_IMETHOD Run() { - MetroUtils::FireObserver("apzc-transform-start", L""); - return NS_OK; - } -}; - -class TransformedEndEvent : public nsRunnable -{ - NS_IMETHOD Run() { - MetroUtils::FireObserver("apzc-transform-end", L""); - return NS_OK; - } -}; - -void -APZController::NotifyAPZStateChange(const ScrollableLayerGuid& aGuid, - APZStateChange aChange, - int aArg) -{ - switch (aChange) { - case APZStateChange::TransformBegin: - { - if (NS_IsMainThread()) { - MetroUtils::FireObserver("apzc-transform-begin", L""); - return; - } - nsCOMPtr runnable = new TransformedStartEvent(); - NS_DispatchToMainThread(runnable); - break; - } - case APZStateChange::TransformEnd: - { - if (NS_IsMainThread()) { - MetroUtils::FireObserver("apzc-transform-end", L""); - return; - } - nsCOMPtr runnable = new TransformedEndEvent(); - NS_DispatchToMainThread(runnable); - break; - } - default: - { - // We don't currently care about other state changes. - break; - } - } -} - -} } } diff --git a/widget/windows/winrt/APZController.h b/widget/windows/winrt/APZController.h deleted file mode 100644 index 8e09052a31d..00000000000 --- a/widget/windows/winrt/APZController.h +++ /dev/null @@ -1,78 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#pragma once - -#include "mozwrlbase.h" - -#include "mozilla/layers/GeckoContentController.h" -#include "mozilla/layers/APZCTreeManager.h" -#include "mozilla/EventForwards.h" -#include "FrameMetrics.h" -#include "Units.h" - -namespace mozilla { -namespace widget { -namespace winrt { - -class APZPendingResponseFlusher -{ -public: - virtual void FlushPendingContentResponse() = 0; -}; - -class APZController : - public mozilla::layers::GeckoContentController -{ - typedef mozilla::layers::FrameMetrics FrameMetrics; - typedef mozilla::layers::ScrollableLayerGuid ScrollableLayerGuid; - typedef mozilla::layers::ZoomConstraints ZoomConstraints; - -public: - APZController() : - mFlusher(nullptr) - { - } - - // GeckoContentController interface - virtual void RequestContentRepaint(const FrameMetrics& aFrameMetrics); - virtual void RequestFlingSnap(const FrameMetrics::ViewID& aScrollId, - const mozilla::CSSPoint& aDestination); - virtual void AcknowledgeScrollUpdate(const FrameMetrics::ViewID& aScrollId, const uint32_t& aScrollGeneration); - virtual void HandleDoubleTap(const mozilla::CSSPoint& aPoint, - Modifiers aModifiers, - const mozilla::layers::ScrollableLayerGuid& aGuid); - virtual void HandleSingleTap(const mozilla::CSSPoint& aPoint, - Modifiers aModifiers, - const mozilla::layers::ScrollableLayerGuid& aGuid); - virtual void HandleLongTap(const mozilla::CSSPoint& aPoint, - Modifiers aModifiers, - const mozilla::layers::ScrollableLayerGuid& aGuid, - uint64_t aInputBlockId); - virtual void SendAsyncScrollDOMEvent(bool aIsRoot, const mozilla::CSSRect &aContentRect, const mozilla::CSSSize &aScrollableSize); - virtual void PostDelayedTask(Task* aTask, int aDelayMs); - virtual bool GetRootZoomConstraints(ZoomConstraints* aOutConstraints); - virtual void NotifyAPZStateChange(const ScrollableLayerGuid& aGuid, - APZStateChange aChange, - int aArg); - - void SetPendingResponseFlusher(APZPendingResponseFlusher* aFlusher); - - bool HitTestAPZC(mozilla::ScreenIntPoint& aPoint); - void TransformCoordinateToGecko(const mozilla::ScreenIntPoint& aPoint, - LayoutDeviceIntPoint* aRefPointOut); - void ContentReceivedInputBlock(uint64_t aInputBlockId, bool aPreventDefault); - nsEventStatus ReceiveInputEvent(mozilla::WidgetInputEvent* aEvent, - ScrollableLayerGuid* aOutTargetGuid, - uint64_t* aOutInputBlockId); - -public: - // todo: make this a member variable as prep for multiple views - static nsRefPtr sAPZC; - -private: - APZPendingResponseFlusher* mFlusher; -}; - -} } } diff --git a/widget/windows/winrt/DisplayInfo_sdk81.h b/widget/windows/winrt/DisplayInfo_sdk81.h deleted file mode 100644 index 3298d260181..00000000000 --- a/widget/windows/winrt/DisplayInfo_sdk81.h +++ /dev/null @@ -1,458 +0,0 @@ - -/* this file contains the definitions for DisplayInformation related interfaces - copied over from Windows.Graphics.Display.h file in the windows 8.1 SDK - This file can be deleted once our build system moves to 8.1. */ - - /* File created by MIDL compiler version 8.00.0603 */ -/* @@MIDL_FILE_HEADING( ) */ - -/* Forward Declarations */ - -#ifndef ____FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable_FWD_DEFINED__ -#define ____FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable_FWD_DEFINED__ -typedef interface __FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable __FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable; - -#endif /* ____FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable_FWD_DEFINED__ */ - - -#ifndef ____x_ABI_CWindows_CGraphics_CDisplay_CIDisplayInformationStatics_FWD_DEFINED__ -#define ____x_ABI_CWindows_CGraphics_CDisplay_CIDisplayInformationStatics_FWD_DEFINED__ -typedef interface __x_ABI_CWindows_CGraphics_CDisplay_CIDisplayInformationStatics __x_ABI_CWindows_CGraphics_CDisplay_CIDisplayInformationStatics; - -#ifdef __cplusplus -namespace ABI { - namespace Windows { - namespace Graphics { - namespace Display { - interface IDisplayInformationStatics; - } /* end namespace */ - } /* end namespace */ - } /* end namespace */ -} /* end namespace */ - -#endif /* __cplusplus */ - -#endif /* ____x_ABI_CWindows_CGraphics_CDisplay_CIDisplayInformationStatics_FWD_DEFINED__ */ - - -#ifndef ____x_ABI_CWindows_CGraphics_CDisplay_CIDisplayInformation_FWD_DEFINED__ -#define ____x_ABI_CWindows_CGraphics_CDisplay_CIDisplayInformation_FWD_DEFINED__ -typedef interface __x_ABI_CWindows_CGraphics_CDisplay_CIDisplayInformation __x_ABI_CWindows_CGraphics_CDisplay_CIDisplayInformation; - -#ifdef __cplusplus -namespace ABI { - namespace Windows { - namespace Graphics { - namespace Display { - interface IDisplayInformation; - } /* end namespace */ - } /* end namespace */ - } /* end namespace */ -} /* end namespace */ - -#endif /* __cplusplus */ - -#endif /* ____x_ABI_CWindows_CGraphics_CDisplay_CIDisplayInformation_FWD_DEFINED__ */ - - -#ifdef __cplusplus -namespace ABI { -namespace Windows { -namespace Graphics { -namespace Display { -class DisplayInformation; -} /*Display*/ -} /*Graphics*/ -} /*Windows*/ -} -#endif - -#ifdef __cplusplus -namespace ABI { -namespace Windows { -namespace Graphics { -namespace Display { -interface IDisplayInformation; -} /*Display*/ -} /*Graphics*/ -} /*Windows*/ -} -#endif - -interface IInspectable; - - -/* interface __MIDL_itf_windows2Egraphics2Edisplay_0000_0000 */ -/* [local] */ - - - - - -extern RPC_IF_HANDLE __MIDL_itf_windows2Egraphics2Edisplay_0000_0000_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_windows2Egraphics2Edisplay_0000_0000_v0_0_s_ifspec; - -/* interface __MIDL_itf_windows2Egraphics2Edisplay_0000_0580 */ - - - - -/* interface __MIDL_itf_windows2Egraphics2Edisplay_0000_0580 */ - - - - -extern RPC_IF_HANDLE __MIDL_itf_windows2Egraphics2Edisplay_0000_0580_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_windows2Egraphics2Edisplay_0000_0580_v0_0_s_ifspec; - -/* interface __MIDL_itf_windows2Egraphics2Edisplay_0000_0001 */ -/* [local] */ - -#ifndef DEF___FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable_USE -#define DEF___FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable_USE -#if defined(__cplusplus) && !defined(RO_NO_TEMPLATE_NAME) -namespace ABI { namespace Windows { namespace Foundation { -template <> -struct __declspec(uuid("86c4f619-67b6-51c7-b30d-d8cf13625327")) -ITypedEventHandler : ITypedEventHandler_impl,IInspectable*> { -static const wchar_t* z_get_rc_name_impl() { -return L"Windows.Foundation.TypedEventHandler`2"; } -}; -typedef ITypedEventHandler __FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable_t; -#define ____FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable_FWD_DEFINED__ -#define __FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable ABI::Windows::Foundation::__FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable_t - -/* ABI */ } /* Windows */ } /* Foundation */ } -#endif //__cplusplus -#endif /* DEF___FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable_USE */ - -#ifndef DEF___FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable -#define DEF___FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable -#if !defined(__cplusplus) || defined(RO_NO_TEMPLATE_NAME) - - -/* interface __MIDL_itf_windows2Egraphics2Edisplay_0000_0004 */ -/* [local] */ - - - -extern RPC_IF_HANDLE __MIDL_itf_windows2Egraphics2Edisplay_0000_0004_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_windows2Egraphics2Edisplay_0000_0004_v0_0_s_ifspec; - -#ifndef ____FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable_INTERFACE_DEFINED__ -#define ____FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable_INTERFACE_DEFINED__ - -/* interface __FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable */ -/* [unique][uuid][object] */ - - - -/* interface __FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable */ -/* [unique][uuid][object] */ - - -EXTERN_C const IID IID___FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("86c4f619-67b6-51c7-b30d-d8cf13625327") - __FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE Invoke( - /* [in] */ __RPC__in_opt ABI::Windows::Graphics::Display::IDisplayInformation *sender, - /* [in] */ __RPC__in_opt IInspectable *e) = 0; - - }; - - -#else /* C style interface */ - - typedef struct __FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectableVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( - __RPC__in __FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable * This, - /* [in] */ __RPC__in REFIID riid, - /* [annotation][iid_is][out] */ - _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( - __RPC__in __FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable * This); - - ULONG ( STDMETHODCALLTYPE *Release )( - __RPC__in __FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable * This); - - HRESULT ( STDMETHODCALLTYPE *Invoke )( - __RPC__in __FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable * This, - /* [in] */ __RPC__in_opt __x_ABI_CWindows_CGraphics_CDisplay_CIDisplayInformation *sender, - /* [in] */ __RPC__in_opt IInspectable *e); - - END_INTERFACE - } __FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectableVtbl; - - interface __FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable - { - CONST_VTBL struct __FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectableVtbl *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define __FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) - -#define __FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) - -#define __FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) - - -#define __FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable_Invoke(This,sender,e) \ - ( (This)->lpVtbl -> Invoke(This,sender,e) ) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - - -#endif /* ____FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable_INTERFACE_DEFINED__ */ - - -/* interface __MIDL_itf_windows2Egraphics2Edisplay_0000_0005 */ -/* [local] */ - -#endif /* pinterface */ -#endif /* DEF___FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable */ - - -/* interface __MIDL_itf_windows2Egraphics2Edisplay_0000_0005 */ -/* [local] */ - - -/* interface __x_ABI_CWindows_CGraphics_CDisplay_CIDisplayPropertiesEventHandler */ -/* [uuid][object] */ - - - -/* interface ABI::Windows::Graphics::Display::IDisplayPropertiesEventHandler */ -/* [uuid][object] */ - - - - -/* interface __MIDL_itf_windows2Egraphics2Edisplay_0000_0006 */ -/* [local] */ - -#if !defined(____x_ABI_CWindows_CGraphics_CDisplay_CIDisplayInformationStatics_INTERFACE_DEFINED__) -extern const __declspec(selectany) _Null_terminated_ WCHAR InterfaceName_Windows_Graphics_Display_IDisplayInformationStatics[] = L"Windows.Graphics.Display.IDisplayInformationStatics"; -#endif /* !defined(____x_ABI_CWindows_CGraphics_CDisplay_CIDisplayInformationStatics_INTERFACE_DEFINED__) */ - - -/* interface __MIDL_itf_windows2Egraphics2Edisplay_0000_0006 */ -/* [local] */ - - - -extern RPC_IF_HANDLE __MIDL_itf_windows2Egraphics2Edisplay_0000_0006_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_windows2Egraphics2Edisplay_0000_0006_v0_0_s_ifspec; - -#ifndef ____x_ABI_CWindows_CGraphics_CDisplay_CIDisplayInformationStatics_INTERFACE_DEFINED__ -#define ____x_ABI_CWindows_CGraphics_CDisplay_CIDisplayInformationStatics_INTERFACE_DEFINED__ - -/* interface __x_ABI_CWindows_CGraphics_CDisplay_CIDisplayInformationStatics */ -/* [uuid][object] */ - - - -/* interface ABI::Windows::Graphics::Display::IDisplayInformationStatics */ -/* [uuid][object] */ - - -EXTERN_C const IID IID___x_ABI_CWindows_CGraphics_CDisplay_CIDisplayInformationStatics; - -#if defined(__cplusplus) && !defined(CINTERFACE) - namespace ABI { - namespace Windows { - namespace Graphics { - namespace Display { - - MIDL_INTERFACE("C6A02A6C-D452-44DC-BA07-96F3C6ADF9D1") - IDisplayInformationStatics : public IInspectable - { - public: - virtual HRESULT STDMETHODCALLTYPE GetForCurrentView( - /* [out][retval] */ __RPC__deref_out_opt ABI::Windows::Graphics::Display::IDisplayInformation **current) = 0; - - virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_AutoRotationPreferences( - /* [out][retval] */ __RPC__out ABI::Windows::Graphics::Display::DisplayOrientations *value) = 0; - - virtual /* [propput] */ HRESULT STDMETHODCALLTYPE put_AutoRotationPreferences( - /* [in] */ ABI::Windows::Graphics::Display::DisplayOrientations value) = 0; - - virtual HRESULT STDMETHODCALLTYPE add_DisplayContentsInvalidated( - /* [in] */ __RPC__in_opt __FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable *handler, - /* [out][retval] */ __RPC__out EventRegistrationToken *token) = 0; - - virtual HRESULT STDMETHODCALLTYPE remove_DisplayContentsInvalidated( - /* [in] */ EventRegistrationToken token) = 0; - - }; - - extern const __declspec(selectany) IID & IID_IDisplayInformationStatics = __uuidof(IDisplayInformationStatics); - - - } /* end namespace */ - } /* end namespace */ - } /* end namespace */ - } /* end namespace */ - -#endif /* C style interface */ - - - - -#endif /* ____x_ABI_CWindows_CGraphics_CDisplay_CIDisplayInformationStatics_INTERFACE_DEFINED__ */ - - -/* interface __MIDL_itf_windows2Egraphics2Edisplay_0000_0007 */ -/* [local] */ - -#if !defined(____x_ABI_CWindows_CGraphics_CDisplay_CIDisplayInformation_INTERFACE_DEFINED__) -extern const __declspec(selectany) _Null_terminated_ WCHAR InterfaceName_Windows_Graphics_Display_IDisplayInformation[] = L"Windows.Graphics.Display.IDisplayInformation"; -#endif /* !defined(____x_ABI_CWindows_CGraphics_CDisplay_CIDisplayInformation_INTERFACE_DEFINED__) */ - - -/* interface __MIDL_itf_windows2Egraphics2Edisplay_0000_0007 */ -/* [local] */ - - - -extern RPC_IF_HANDLE __MIDL_itf_windows2Egraphics2Edisplay_0000_0007_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_windows2Egraphics2Edisplay_0000_0007_v0_0_s_ifspec; - -#ifndef ____x_ABI_CWindows_CGraphics_CDisplay_CIDisplayInformation_INTERFACE_DEFINED__ -#define ____x_ABI_CWindows_CGraphics_CDisplay_CIDisplayInformation_INTERFACE_DEFINED__ - -/* interface __x_ABI_CWindows_CGraphics_CDisplay_CIDisplayInformation */ -/* [uuid][object] */ - - - -/* interface ABI::Windows::Graphics::Display::IDisplayInformation */ -/* [uuid][object] */ - - -EXTERN_C const IID IID___x_ABI_CWindows_CGraphics_CDisplay_CIDisplayInformation; - -#if defined(__cplusplus) && !defined(CINTERFACE) - namespace ABI { - namespace Windows { - namespace Graphics { - namespace Display { - - MIDL_INTERFACE("BED112AE-ADC3-4DC9-AE65-851F4D7D4799") - IDisplayInformation : public IInspectable - { - public: - virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_CurrentOrientation( - /* [out][retval] */ __RPC__out ABI::Windows::Graphics::Display::DisplayOrientations *value) = 0; - - virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_NativeOrientation( - /* [out][retval] */ __RPC__out ABI::Windows::Graphics::Display::DisplayOrientations *value) = 0; - - virtual HRESULT STDMETHODCALLTYPE add_OrientationChanged( - /* [in] */ __RPC__in_opt __FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable *handler, - /* [out][retval] */ __RPC__out EventRegistrationToken *token) = 0; - - virtual HRESULT STDMETHODCALLTYPE remove_OrientationChanged( - /* [in] */ EventRegistrationToken token) = 0; - - virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_ResolutionScale( - /* [out][retval] */ __RPC__out ABI::Windows::Graphics::Display::ResolutionScale *value) = 0; - - virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_LogicalDpi( - /* [out][retval] */ __RPC__out FLOAT *value) = 0; - - virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_RawDpiX( - /* [out][retval] */ __RPC__out FLOAT *value) = 0; - - virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_RawDpiY( - /* [out][retval] */ __RPC__out FLOAT *value) = 0; - - virtual HRESULT STDMETHODCALLTYPE add_DpiChanged( - /* [in] */ __RPC__in_opt __FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable *handler, - /* [out][retval] */ __RPC__out EventRegistrationToken *token) = 0; - - virtual HRESULT STDMETHODCALLTYPE remove_DpiChanged( - /* [in] */ EventRegistrationToken token) = 0; - - virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_StereoEnabled( - /* [out][retval] */ __RPC__out boolean *value) = 0; - - virtual HRESULT STDMETHODCALLTYPE add_StereoEnabledChanged( - /* [in] */ __RPC__in_opt __FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable *handler, - /* [out][retval] */ __RPC__out EventRegistrationToken *token) = 0; - - virtual HRESULT STDMETHODCALLTYPE remove_StereoEnabledChanged( - /* [in] */ EventRegistrationToken token) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetColorProfileAsync( - /* [out][retval] */ __RPC__deref_out_opt __FIAsyncOperation_1_Windows__CStorage__CStreams__CIRandomAccessStream **asyncInfo) = 0; - - virtual HRESULT STDMETHODCALLTYPE add_ColorProfileChanged( - /* [in] */ __RPC__in_opt __FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable *handler, - /* [out][retval] */ __RPC__out EventRegistrationToken *token) = 0; - - virtual HRESULT STDMETHODCALLTYPE remove_ColorProfileChanged( - /* [in] */ EventRegistrationToken token) = 0; - - }; - - extern const __declspec(selectany) IID & IID_IDisplayInformation = __uuidof(IDisplayInformation); - - - } /* end namespace */ - } /* end namespace */ - } /* end namespace */ - } /* end namespace */ - -#endif /* C style interface */ - - - - -#endif /* ____x_ABI_CWindows_CGraphics_CDisplay_CIDisplayInformation_INTERFACE_DEFINED__ */ - - -/* interface __MIDL_itf_windows2Egraphics2Edisplay_0000_0008 */ -/* [local] */ - - -/* interface __MIDL_itf_windows2Egraphics2Edisplay_0000_0009 */ -/* [local] */ - -#ifndef RUNTIMECLASS_Windows_Graphics_Display_DisplayInformation_DEFINED -#define RUNTIMECLASS_Windows_Graphics_Display_DisplayInformation_DEFINED -extern const __declspec(selectany) _Null_terminated_ WCHAR RuntimeClass_Windows_Graphics_Display_DisplayInformation[] = L"Windows.Graphics.Display.DisplayInformation"; -#endif - - -/* interface __MIDL_itf_windows2Egraphics2Edisplay_0000_0009 */ -/* [local] */ - - - -extern RPC_IF_HANDLE __MIDL_itf_windows2Egraphics2Edisplay_0000_0009_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_windows2Egraphics2Edisplay_0000_0009_v0_0_s_ifspec; - -/* Additional Prototypes for ALL interfaces */ - -/* end of Additional Prototypes */ diff --git a/widget/windows/winrt/FrameworkView.cpp b/widget/windows/winrt/FrameworkView.cpp deleted file mode 100644 index 7055c8dae92..00000000000 --- a/widget/windows/winrt/FrameworkView.cpp +++ /dev/null @@ -1,507 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "FrameworkView.h" -#include "MetroAppShell.h" -#include "MetroWidget.h" -#include "mozilla/AutoRestore.h" -#include "MetroUtils.h" -#include "MetroApp.h" -#include "UIABridgePublic.h" -#include "KeyboardLayout.h" - -// generated -#include "UIABridge.h" - -using namespace mozilla; -using namespace mozilla::widget::winrt; -#ifdef ACCESSIBILITY -using namespace mozilla::a11y; -#endif -using namespace ABI::Windows::ApplicationModel; -using namespace ABI::Windows::ApplicationModel::Core; -using namespace ABI::Windows::ApplicationModel::Activation; -using namespace ABI::Windows::UI::Core; -using namespace ABI::Windows::UI::ViewManagement; -using namespace ABI::Windows::UI::Input; -using namespace ABI::Windows::Devices::Input; -using namespace ABI::Windows::System; -using namespace ABI::Windows::Foundation; -using namespace Microsoft::WRL; -using namespace Microsoft::WRL::Wrappers; - -namespace mozilla { -namespace widget { -namespace winrt { - -// statics -bool FrameworkView::sKeyboardIsVisible = false; -Rect FrameworkView::sKeyboardRect; -HSTRING FrameworkView::sActivationURI = NULL; -ApplicationExecutionState FrameworkView::sPreviousExecutionState; -nsTArray* sSettingsArray; - -FrameworkView::FrameworkView(MetroApp* aMetroApp) : - mDPI(-1.0f), - mWidget(nullptr), - mShuttingDown(false), - mMetroApp(aMetroApp), - mWindow(nullptr), - mMetroInput(nullptr), - mWinVisible(false), - mWinActiveState(false) -{ - mActivated.value = 0; - mWindowActivated.value = 0; - mWindowVisibilityChanged.value = 0; - mWindowSizeChanged.value = 0; - mSoftKeyboardHidden.value = 0; - mSoftKeyboardShown.value = 0; - mDisplayPropertiesChanged.value = 0; - mAutomationProviderRequested.value = 0; - mDataTransferRequested.value = 0; - mSearchQuerySubmitted.value = 0; - mPlayToRequested.value = 0; - mSettingsPane.value = 0; - mPrintManager.value = 0; - memset(&sKeyboardRect, 0, sizeof(Rect)); - sSettingsArray = new nsTArray(); - LogFunction(); -} - -//////////////////////////////////////////////////// -// IFrameworkView impl. - -HRESULT -FrameworkView::Initialize(ICoreApplicationView* aAppView) -{ - LogFunction(); - if (mShuttingDown) - return E_FAIL; - - aAppView->add_Activated(Callback<__FITypedEventHandler_2_Windows__CApplicationModel__CCore__CCoreApplicationView_Windows__CApplicationModel__CActivation__CIActivatedEventArgs_t>( - this, &FrameworkView::OnActivated).Get(), &mActivated); - - //CoCreateInstance(CLSID_WICImagingFactory, nullptr, - // CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&mWicFactory)); - return S_OK; -} - -HRESULT -FrameworkView::Uninitialize() -{ - return S_OK; -} - -HRESULT -FrameworkView::Load(HSTRING aEntryPoint) -{ - return S_OK; -} - -// called by winrt on startup -HRESULT -FrameworkView::Run() -{ - LogFunction(); - - // Initialize XPCOM, create mWidget and go! We get a - // callback in MetroAppShell::Run, in which we kick - // off normal browser execution / event dispatching. - mMetroApp->Run(); - - // Gecko is completely shut down at this point. - WinUtils::Log("Exiting FrameworkView::Run()"); - - WindowsDeleteString(sActivationURI); - return S_OK; -} - -HRESULT -FrameworkView::ActivateView() -{ - LogFunction(); - - UpdateWidgetSizeAndPosition(); - - nsIntRegion region(nsIntRect(0, 0, mWindowBounds.width, mWindowBounds.height)); - mWidget->Paint(region); - - // Activate the window, this kills the splash screen - mWindow->Activate(); - - ProcessLaunchArguments(); - AddEventHandlers(); - SetupContracts(); - - return S_OK; -} - -HRESULT -FrameworkView::SetWindow(ICoreWindow* aWindow) -{ - LogFunction(); - - NS_ASSERTION(!mWindow, "Attempting to set a window on a view that already has a window!"); - NS_ASSERTION(aWindow, "Attempting to set a null window on a view!"); - - mWindow = aWindow; - UpdateLogicalDPI(); - return S_OK; -} - -//////////////////////////////////////////////////// -// FrameworkView impl. - -void -FrameworkView::AddEventHandlers() { - NS_ASSERTION(mWindow, "SetWindow must be called before AddEventHandlers!"); - NS_ASSERTION(mWidget, "SetWidget must be called before AddEventHAndlers!"); - - mMetroInput = Make(mWidget.Get(), - mWindow.Get()); - - mWindow->add_VisibilityChanged(Callback<__FITypedEventHandler_2_Windows__CUI__CCore__CCoreWindow_Windows__CUI__CCore__CVisibilityChangedEventArgs>( - this, &FrameworkView::OnWindowVisibilityChanged).Get(), &mWindowVisibilityChanged); - mWindow->add_Activated(Callback<__FITypedEventHandler_2_Windows__CUI__CCore__CCoreWindow_Windows__CUI__CCore__CWindowActivatedEventArgs_t>( - this, &FrameworkView::OnWindowActivated).Get(), &mWindowActivated); - mWindow->add_SizeChanged(Callback<__FITypedEventHandler_2_Windows__CUI__CCore__CCoreWindow_Windows__CUI__CCore__CWindowSizeChangedEventArgs_t>( - this, &FrameworkView::OnWindowSizeChanged).Get(), &mWindowSizeChanged); - - mWindow->add_AutomationProviderRequested(Callback<__FITypedEventHandler_2_Windows__CUI__CCore__CCoreWindow_Windows__CUI__CCore__CAutomationProviderRequestedEventArgs_t>( - this, &FrameworkView::OnAutomationProviderRequested).Get(), &mAutomationProviderRequested); - - HRESULT hr; - ComPtr dispProps; - if (SUCCEEDED(GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), dispProps.GetAddressOf()))) { - hr = dispProps->add_LogicalDpiChanged(Callback( - this, &FrameworkView::OnLogicalDpiChanged).Get(), &mDisplayPropertiesChanged); - LogHRESULT(hr); - } - - ComPtr inputStatic; - if (SUCCEEDED(hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_UI_ViewManagement_InputPane).Get(), inputStatic.GetAddressOf()))) { - ComPtr inputPane; - if (SUCCEEDED(inputStatic->GetForCurrentView(inputPane.GetAddressOf()))) { - inputPane->add_Hiding(Callback<__FITypedEventHandler_2_Windows__CUI__CViewManagement__CInputPane_Windows__CUI__CViewManagement__CInputPaneVisibilityEventArgs_t>( - this, &FrameworkView::OnSoftkeyboardHidden).Get(), &mSoftKeyboardHidden); - inputPane->add_Showing(Callback<__FITypedEventHandler_2_Windows__CUI__CViewManagement__CInputPane_Windows__CUI__CViewManagement__CInputPaneVisibilityEventArgs_t>( - this, &FrameworkView::OnSoftkeyboardShown).Get(), &mSoftKeyboardShown); - } - } -} - -// Called by MetroApp -void -FrameworkView::Shutdown() -{ - LogFunction(); - mShuttingDown = true; - - if (mWindow && mWindowVisibilityChanged.value) { - mWindow->remove_VisibilityChanged(mWindowVisibilityChanged); - mWindow->remove_Activated(mWindowActivated); - mWindow->remove_Closed(mWindowClosed); - mWindow->remove_SizeChanged(mWindowSizeChanged); - mWindow->remove_AutomationProviderRequested(mAutomationProviderRequested); - } - - ComPtr dispProps; - if (mDisplayPropertiesChanged.value && - SUCCEEDED(GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), dispProps.GetAddressOf()))) { - dispProps->remove_LogicalDpiChanged(mDisplayPropertiesChanged); - } - - ComPtr inputStatic; - if (mSoftKeyboardHidden.value && - SUCCEEDED(GetActivationFactory(HStringReference(RuntimeClass_Windows_UI_ViewManagement_InputPane).Get(), inputStatic.GetAddressOf()))) { - ComPtr inputPane; - if (SUCCEEDED(inputStatic->GetForCurrentView(inputPane.GetAddressOf()))) { - inputPane->remove_Hiding(mSoftKeyboardHidden); - inputPane->remove_Showing(mSoftKeyboardShown); - } - } - - if (mAutomationProvider) { - ComPtr provider; - mAutomationProvider.As(&provider); - if (provider) { - provider->Disconnect(); - } - } - mAutomationProvider = nullptr; - - mMetroInput = nullptr; - delete sSettingsArray; - sSettingsArray = nullptr; - mWidget = nullptr; - mMetroApp = nullptr; - mWindow = nullptr; -} - -void -FrameworkView::SetCursor(CoreCursorType aCursorType, DWORD aCustomId) -{ - if (mShuttingDown) { - return; - } - NS_ASSERTION(mWindow, "SetWindow must be called before SetCursor!"); - ComPtr factory; - AssertHRESULT(GetActivationFactory(HStringReference(RuntimeClass_Windows_UI_Core_CoreCursor).Get(), factory.GetAddressOf())); - ComPtr cursor; - AssertHRESULT(factory->CreateCursor(aCursorType, aCustomId, cursor.GetAddressOf())); - mWindow->put_PointerCursor(cursor.Get()); -} - -void -FrameworkView::ClearCursor() -{ - if (mShuttingDown) { - return; - } - NS_ASSERTION(mWindow, "SetWindow must be called before ClearCursor!"); - mWindow->put_PointerCursor(nullptr); -} - -void -FrameworkView::UpdateLogicalDPI() -{ - ComPtr dispProps; - HRESULT hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), - dispProps.GetAddressOf()); - AssertHRESULT(hr); - FLOAT value; - AssertHRESULT(dispProps->get_LogicalDpi(&value)); - SetDpi(value); -} - -void -FrameworkView::GetBounds(nsIntRect &aRect) -{ - // May be called by compositor thread - if (mShuttingDown) { - return; - } - aRect = mWindowBounds; -} - -void -FrameworkView::UpdateWidgetSizeAndPosition() -{ - if (mShuttingDown) - return; - - NS_ASSERTION(mWindow, "SetWindow must be called before UpdateWidgetSizeAndPosition!"); - NS_ASSERTION(mWidget, "SetWidget must be called before UpdateWidgetSizeAndPosition!"); - - UpdateBounds(); - mWidget->Move(0, 0); - mWidget->Resize(0, 0, mWindowBounds.width, mWindowBounds.height, true); - mWidget->SizeModeChanged(); -} - -bool -FrameworkView::IsEnabled() const -{ - return mWinActiveState; -} - -bool -FrameworkView::IsVisible() const -{ - // we could check the wnd in MetroWidget for this, but - // generally we don't let nsIWidget control visibility - // or activation. - return mWinVisible; -} - -void FrameworkView::SetDpi(float aDpi) -{ - if (aDpi != mDPI) { - LogFunction(); - - mDPI = aDpi; - - // notify the widget that dpi has changed - if (mWidget) { - mWidget->ChangedDPI(); - UpdateBounds(); - } - } -} - -void -FrameworkView::UpdateBounds() -{ - if (!mWidget) - return; - - RECT winRect; - GetClientRect(mWidget->GetICoreWindowHWND(), &winRect); - - mWindowBounds = nsIntRect(winRect.left, - winRect.top, - winRect.right - winRect.left, - winRect.bottom - winRect.top); -} - -void -FrameworkView::SetWidget(MetroWidget* aWidget) -{ - NS_ASSERTION(!mWidget, "Attempting to set a widget for a view that already has a widget!"); - NS_ASSERTION(aWidget, "Attempting to set a null widget for a view!"); - LogFunction(); - mWidget = aWidget; - mWidget->FindMetroWindow(); - UpdateBounds(); -} - -//////////////////////////////////////////////////// -// Event handlers - -void -FrameworkView::SendActivationEvent() -{ - if (mShuttingDown) { - return; - } - NS_ASSERTION(mWindow, "SetWindow must be called before SendActivationEvent!"); - mWidget->Activated(mWinActiveState); - if (mWinActiveState) { - UpdateWidgetSizeAndPosition(); - } - EnsureAutomationProviderCreated(); -} - -HRESULT -FrameworkView::OnWindowVisibilityChanged(ICoreWindow* aWindow, - IVisibilityChangedEventArgs* aArgs) -{ - // If we're visible, or we can't determine if we're visible, just store - // that we are visible. - boolean visible; - mWinVisible = FAILED(aArgs->get_Visible(&visible)) || visible; - return S_OK; -} - -HRESULT -FrameworkView::OnActivated(ICoreApplicationView* aApplicationView, - IActivatedEventArgs* aArgs) -{ - LogFunction(); - - if (mShuttingDown) { - return S_OK; - } - - aArgs->get_PreviousExecutionState(&sPreviousExecutionState); - bool startup = sPreviousExecutionState == ApplicationExecutionState::ApplicationExecutionState_Terminated || - sPreviousExecutionState == ApplicationExecutionState::ApplicationExecutionState_ClosedByUser || - sPreviousExecutionState == ApplicationExecutionState::ApplicationExecutionState_NotRunning; - ProcessActivationArgs(aArgs, startup); - return S_OK; -} - -HRESULT -FrameworkView::OnSoftkeyboardHidden(IInputPane* aSender, - IInputPaneVisibilityEventArgs* aArgs) -{ - LogFunction(); - sKeyboardIsVisible = false; - memset(&sKeyboardRect, 0, sizeof(Rect)); - MetroUtils::FireObserver("metro_softkeyboard_hidden"); - aArgs->put_EnsuredFocusedElementInView(true); - return S_OK; -} - -HRESULT -FrameworkView::OnSoftkeyboardShown(IInputPane* aSender, - IInputPaneVisibilityEventArgs* aArgs) -{ - LogFunction(); - sKeyboardIsVisible = true; - aSender->get_OccludedRect(&sKeyboardRect); - MetroUtils::FireObserver("metro_softkeyboard_shown"); - aArgs->put_EnsuredFocusedElementInView(true); - return S_OK; -} - -HRESULT -FrameworkView::OnWindowSizeChanged(ICoreWindow* aSender, IWindowSizeChangedEventArgs* aArgs) -{ - LogFunction(); - UpdateWidgetSizeAndPosition(); - return S_OK; -} - -HRESULT -FrameworkView::OnWindowActivated(ICoreWindow* aSender, IWindowActivatedEventArgs* aArgs) -{ - LogFunction(); - if (!mWidget) { - return S_OK; - } - CoreWindowActivationState state; - aArgs->get_WindowActivationState(&state); - mWinActiveState = !(state == CoreWindowActivationState::CoreWindowActivationState_Deactivated); - SendActivationEvent(); - return S_OK; -} - -HRESULT -FrameworkView::OnLogicalDpiChanged(IInspectable* aSender) -{ - LogFunction(); - UpdateLogicalDPI(); - if (mWidget) { - mWidget->Invalidate(); - } - return S_OK; -} - -bool -FrameworkView::EnsureAutomationProviderCreated() -{ -#ifdef ACCESSIBILITY - if (!mWidget || mShuttingDown) - return false; - - if (mAutomationProvider) { - return true; - } - - Accessible *rootAccessible = mWidget->GetRootAccessible(); - if (rootAccessible) { - IInspectable* inspectable; - HRESULT hr; - AssertRetHRESULT(hr = UIABridge_CreateInstance(&inspectable), hr); // Addref - IUIABridge* bridge = nullptr; - inspectable->QueryInterface(IID_IUIABridge, (void**)&bridge); // Addref - if (bridge) { - bridge->Init(this, mWindow.Get(), (ULONG)rootAccessible); - mAutomationProvider = inspectable; - inspectable->Release(); - return true; - } - } -#endif - return false; -} - -HRESULT -FrameworkView::OnAutomationProviderRequested(ICoreWindow* aSender, - IAutomationProviderRequestedEventArgs* aArgs) -{ - LogFunction(); - if (!EnsureAutomationProviderCreated()) - return E_FAIL; - HRESULT hr = aArgs->put_AutomationProvider(mAutomationProvider.Get()); - if (FAILED(hr)) { - WinUtils::Log("put failed? %X", hr); - } - return S_OK; -} - -} } } diff --git a/widget/windows/winrt/FrameworkView.h b/widget/windows/winrt/FrameworkView.h deleted file mode 100644 index ad4e0ac74f8..00000000000 --- a/widget/windows/winrt/FrameworkView.h +++ /dev/null @@ -1,205 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#pragma once - -#include "MetroWidget.h" -#include "MetroInput.h" -#include "gfxWindowsPlatform.h" -#include "nsDataHashtable.h" - -#include "mozwrlbase.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace mozilla { -namespace widget { -namespace winrt { - -class MetroApp; - -class FrameworkView : public Microsoft::WRL::RuntimeClass -{ - InspectableClass(L"FrameworkView", TrustLevel::BaseTrust) - - typedef mozilla::layers::LayerManager LayerManager; - - typedef ABI::Windows::Foundation::Rect Rect; - typedef ABI::Windows::UI::Core::IWindowSizeChangedEventArgs IWindowSizeChangedEventArgs; - typedef ABI::Windows::UI::Core::ICoreWindowEventArgs ICoreWindowEventArgs; - typedef ABI::Windows::UI::Core::IWindowActivatedEventArgs IWindowActivatedEventArgs; - typedef ABI::Windows::UI::Core::IAutomationProviderRequestedEventArgs IAutomationProviderRequestedEventArgs; - typedef ABI::Windows::UI::Core::ICoreWindow ICoreWindow; - typedef ABI::Windows::UI::Core::ICoreDispatcher ICoreDispatcher; - typedef ABI::Windows::UI::Core::IVisibilityChangedEventArgs IVisibilityChangedEventArgs; - typedef ABI::Windows::UI::ViewManagement::IInputPaneVisibilityEventArgs IInputPaneVisibilityEventArgs; - typedef ABI::Windows::UI::ViewManagement::IInputPane IInputPane; - typedef ABI::Windows::UI::ViewManagement::ApplicationViewState ApplicationViewState; - typedef ABI::Windows::UI::ApplicationSettings::ISettingsPane ISettingsPane; - typedef ABI::Windows::UI::ApplicationSettings::ISettingsPaneCommandsRequestedEventArgs ISettingsPaneCommandsRequestedEventArgs; - typedef ABI::Windows::UI::Popups::IUICommand IUICommand; - typedef ABI::Windows::ApplicationModel::Activation::ILaunchActivatedEventArgs ILaunchActivatedEventArgs; - typedef ABI::Windows::ApplicationModel::Activation::IActivatedEventArgs IActivatedEventArgs; - typedef ABI::Windows::ApplicationModel::Activation::ISearchActivatedEventArgs ISearchActivatedEventArgs; - typedef ABI::Windows::ApplicationModel::Activation::IFileActivatedEventArgs IFileActivatedEventArgs; - typedef ABI::Windows::ApplicationModel::Core::ICoreApplicationView ICoreApplicationView; - typedef ABI::Windows::ApplicationModel::DataTransfer::IDataTransferManager IDataTransferManager; - typedef ABI::Windows::ApplicationModel::DataTransfer::IDataRequestedEventArgs IDataRequestedEventArgs; - typedef ABI::Windows::ApplicationModel::Search::ISearchPane ISearchPane; - typedef ABI::Windows::ApplicationModel::Search::ISearchPaneQuerySubmittedEventArgs ISearchPaneQuerySubmittedEventArgs; - typedef ABI::Windows::Media::PlayTo::IPlayToManager IPlayToManager; - typedef ABI::Windows::Media::PlayTo::IPlayToSourceRequestedEventArgs IPlayToSourceRequestedEventArgs; - typedef ABI::Windows::Graphics::Printing::IPrintManager IPrintManager; - typedef ABI::Windows::Graphics::Printing::IPrintTaskRequestedEventArgs IPrintTaskRequestedEventArgs; - typedef ABI::Windows::Graphics::Printing::IPrintTaskSourceRequestedArgs IPrintTaskSourceRequestedArgs; - -public: - FrameworkView(MetroApp* aMetroApp); - - // IFrameworkView Methods - STDMETHODIMP Initialize(ICoreApplicationView* aAppView); - STDMETHODIMP SetWindow(ICoreWindow* aWindow); - STDMETHODIMP Load(HSTRING aEntryPoint); - STDMETHODIMP Run(); - STDMETHODIMP Uninitialize(); - - HRESULT ActivateView(); - - // Public apis for MetroWidget - float GetDPI() { return mDPI; } - ICoreWindow* GetCoreWindow() { return mWindow.Get(); } - void SetWidget(MetroWidget* aWidget); - MetroWidget* GetWidget() { return mWidget.Get(); } - void GetBounds(nsIntRect &aRect); - void SetCursor(ABI::Windows::UI::Core::CoreCursorType aCursorType, DWORD aCustomId = 0); - void ClearCursor(); - bool IsEnabled() const; - bool IsVisible() const; - - // Activation apis for nsIWinMetroUtils - static int GetPreviousExecutionState() { return sPreviousExecutionState; } - static void GetActivationURI(nsAString &aActivationURI) { - unsigned int length; - aActivationURI = WindowsGetStringRawBuffer(sActivationURI, &length); - } - - // Soft keyboard info for nsIWinMetroUtils - static bool IsKeyboardVisible() { return sKeyboardIsVisible; } - static ABI::Windows::Foundation::Rect KeyboardVisibleRect() { return sKeyboardRect; } - - // MetroApp apis - void SetupContracts(); - void Shutdown(); - - // MetroContracts settings panel enumerator entry - void AddSetting(ISettingsPaneCommandsRequestedEventArgs* aArgs, uint32_t aId, - Microsoft::WRL::Wrappers::HString& aSettingName); -protected: - // Event Handlers - HRESULT OnActivated(ICoreApplicationView* aApplicationView, - IActivatedEventArgs* aArgs); - HRESULT OnWindowVisibilityChanged(ICoreWindow* aCoreWindow, - IVisibilityChangedEventArgs* aArgs); - - HRESULT OnWindowSizeChanged(ICoreWindow* aSender, - IWindowSizeChangedEventArgs* aArgs); - HRESULT OnWindowActivated(ICoreWindow* aSender, - IWindowActivatedEventArgs* aArgs); - HRESULT OnLogicalDpiChanged(IInspectable* aSender); - - HRESULT OnAutomationProviderRequested(ICoreWindow* aSender, - IAutomationProviderRequestedEventArgs* aArgs); - - HRESULT OnSoftkeyboardHidden(IInputPane* aSender, - IInputPaneVisibilityEventArgs* aArgs); - HRESULT OnSoftkeyboardShown(IInputPane* aSender, - IInputPaneVisibilityEventArgs* aArgs); - - HRESULT OnDataShareRequested(IDataTransferManager*, IDataRequestedEventArgs* aArgs); - HRESULT OnSearchQuerySubmitted(ISearchPane* aPane, ISearchPaneQuerySubmittedEventArgs* aArgs); - HRESULT OnSettingsCommandsRequested(ISettingsPane* aPane, ISettingsPaneCommandsRequestedEventArgs* aArgs); - HRESULT OnPlayToSourceRequested(IPlayToManager* aPane, IPlayToSourceRequestedEventArgs* aArgs); - HRESULT OnSettingsCommandInvoked(IUICommand* aCommand); - HRESULT OnPrintTaskRequested(IPrintManager* aMgr, IPrintTaskRequestedEventArgs* aArgs); - HRESULT OnPrintTaskSourceRequested(IPrintTaskSourceRequestedArgs* aArgs); - -protected: - void SetDpi(float aDpi); - void UpdateWidgetSizeAndPosition(); - void PerformURILoad(Microsoft::WRL::Wrappers::HString& aString); - void PerformSearch(Microsoft::WRL::Wrappers::HString& aQuery); - void PerformURILoadOrSearch(Microsoft::WRL::Wrappers::HString& aString); - bool EnsureAutomationProviderCreated(); - void SearchActivated(Microsoft::WRL::ComPtr& aArgs, bool aStartup); - void FileActivated(Microsoft::WRL::ComPtr& aArgs, bool aStartup); - void LaunchActivated(Microsoft::WRL::ComPtr& aArgs, bool aStartup); - void ProcessActivationArgs(IActivatedEventArgs* aArgs, bool aStartup); - void UpdateForWindowSizeChange(); - void SendActivationEvent(); - void UpdateLogicalDPI(); - void FireViewStateObservers(); - void ProcessLaunchArguments(); - void UpdateBounds(); - - // Printing and preview - void CreatePrintControl(IPrintDocumentPackageTarget* aDocPackageTarget, - D2D1_PRINT_CONTROL_PROPERTIES* aPrintControlProperties); - HRESULT ClosePrintControl(); - void PrintPage(uint32_t aPageNumber, D2D1_RECT_F aImageableArea, - D2D1_SIZE_F aPageSize, IStream* aPagePrintTicketStream); - void AddEventHandlers(); - -private: - EventRegistrationToken mActivated; - EventRegistrationToken mWindowActivated; - EventRegistrationToken mWindowVisibilityChanged; - EventRegistrationToken mWindowClosed; - EventRegistrationToken mWindowSizeChanged; - EventRegistrationToken mSoftKeyboardHidden; - EventRegistrationToken mSoftKeyboardShown; - EventRegistrationToken mDisplayPropertiesChanged; - EventRegistrationToken mAutomationProviderRequested; - EventRegistrationToken mDataTransferRequested; - EventRegistrationToken mSearchQuerySubmitted; - EventRegistrationToken mPlayToRequested; - EventRegistrationToken mSettingsPane; - EventRegistrationToken mPrintManager; - -private: - nsIntRect mWindowBounds; // in device-pixel coordinates - float mDPI; - bool mShuttingDown; - nsAutoString mActivationCommandLine; - Microsoft::WRL::ComPtr mAutomationProvider; - //Microsoft::WRL::ComPtr mD2DPrintControl; - // Private critical section protects D2D device context for on-screen - // rendering from that for print/preview in the different thread. - //Microsoft::WRL::ComPtr mWicFactory; - Microsoft::WRL::ComPtr mMetroApp; - Microsoft::WRL::ComPtr mWindow; - Microsoft::WRL::ComPtr mWidget; - Microsoft::WRL::ComPtr mMetroInput; - bool mWinVisible; - bool mWinActiveState; - - static bool sKeyboardIsVisible; - static Rect sKeyboardRect; - static HSTRING sActivationURI; - static ABI::Windows::ApplicationModel::Activation::ApplicationExecutionState sPreviousExecutionState; -}; - -} } } diff --git a/widget/windows/winrt/Makefile.in b/widget/windows/winrt/Makefile.in deleted file mode 100644 index 60e54eb3ef8..00000000000 --- a/widget/windows/winrt/Makefile.in +++ /dev/null @@ -1,19 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this file, -# You can obtain one at http://mozilla.org/MPL/2.0/. - -MIDL_GENERATED_FILES = \ - UIABridge_i.c \ - UIABridge_p.c \ - dlldata.c \ - $(NULL) - -GARBAGE += $(MIDL_GENERATED_FILES) done_gen - -do_interfaces_gen: UIABridge.idl - $(MIDL) $(srcdir)/UIABridge.idl -I $(srcdir) - touch $@ - -export:: do_interfaces_gen - -include $(topsrcdir)/config/rules.mk diff --git a/widget/windows/winrt/MetroApp.cpp b/widget/windows/winrt/MetroApp.cpp deleted file mode 100644 index 8b2c0442c7e..00000000000 --- a/widget/windows/winrt/MetroApp.cpp +++ /dev/null @@ -1,282 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "MetroApp.h" -#include "MetroWidget.h" -#include "mozilla/IOInterposer.h" -#include "mozilla/widget/AudioSession.h" -#include "nsIRunnable.h" -#include "MetroUtils.h" -#include "MetroAppShell.h" -#include "nsICommandLineRunner.h" -#include "FrameworkView.h" -#include "nsAppDirectoryServiceDefs.h" -#include "GeckoProfiler.h" -#include - -using namespace ABI::Windows::ApplicationModel; -using namespace ABI::Windows::ApplicationModel::Core; -using namespace ABI::Windows::UI::Core; -using namespace ABI::Windows::System; -using namespace ABI::Windows::Foundation; -using namespace Microsoft::WRL; -using namespace Microsoft::WRL::Wrappers; -using namespace mozilla::widget; - -// Metro specific XRE methods we call from here on an -// appropriate thread. -extern nsresult XRE_metroStartup(bool runXREMain); -extern void XRE_metroShutdown(); - -static const char* gGeckoThreadName = "GeckoMain"; - -#ifdef PR_LOGGING -extern PRLogModuleInfo* gWindowsLog; -#endif - -namespace mozilla { -namespace widget { -namespace winrt { - -ComPtr sFrameworkView; -ComPtr sMetroApp; -ComPtr sCoreApp; -bool MetroApp::sGeckoShuttingDown = false; - -//////////////////////////////////////////////////// -// IFrameworkViewSource impl. - -// Called after CoreApplication::Run(app) -HRESULT -MetroApp::CreateView(ABI::Windows::ApplicationModel::Core::IFrameworkView **aViewProvider) -{ - // This entry point is called on the metro main thread, but the thread won't - // be recognized as such until after Run() is called below. XPCOM has not - // gone through startup at this point. - - // Note that we create the view which creates our native window for us. The - // gecko widget gets created by gecko, and the two get hooked up later in - // MetroWidget::Create(). - - LogFunction(); - - sFrameworkView = Make(this); - sFrameworkView.Get()->AddRef(); - *aViewProvider = sFrameworkView.Get(); - return !sFrameworkView ? E_FAIL : S_OK; -} - -//////////////////////////////////////////////////// -// MetroApp impl. - -void -MetroApp::Run() -{ - LogThread(); - - // Name this thread for debugging and register it with the profiler - // and IOInterposer as the main gecko thread. - char aLocal; - PR_SetCurrentThreadName(gGeckoThreadName); - profiler_register_thread(gGeckoThreadName, &aLocal); - IOInterposer::RegisterCurrentThread(true); - - HRESULT hr; - hr = sCoreApp->add_Suspending(Callback<__FIEventHandler_1_Windows__CApplicationModel__CSuspendingEventArgs_t>( - this, &MetroApp::OnSuspending).Get(), &mSuspendEvent); - AssertHRESULT(hr); - - hr = sCoreApp->add_Resuming(Callback<__FIEventHandler_1_IInspectable_t>( - this, &MetroApp::OnResuming).Get(), &mResumeEvent); - AssertHRESULT(hr); - - WinUtils::Log("Calling XRE_metroStartup."); - nsresult rv = XRE_metroStartup(true); - WinUtils::Log("Exiting XRE_metroStartup."); - if (NS_FAILED(rv)) { - WinUtils::Log("XPCOM startup initialization failed, bailing. rv=%X", rv); - CoreExit(); - } -} - -// Free all xpcom related resources before calling the xre shutdown call. -// Must be called on the metro main thread. Currently called from appshell. -void -MetroApp::Shutdown() -{ - LogThread(); - - if (sCoreApp) { - sCoreApp->remove_Suspending(mSuspendEvent); - sCoreApp->remove_Resuming(mResumeEvent); - } - - if (sFrameworkView) { - sFrameworkView->Shutdown(); - } - - MetroApp::sGeckoShuttingDown = true; - - // Shut down xpcom - XRE_metroShutdown(); - - // Unhook this thread from the profiler - profiler_unregister_thread(); -} - -// Request a shutdown of the application -void -MetroApp::CoreExit() -{ - LogFunction(); - HRESULT hr; - ComPtr coreExit; - HStringReference className(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication); - hr = GetActivationFactory(className.Get(), coreExit.GetAddressOf()); - NS_ASSERTION(SUCCEEDED(hr), "Activation of ICoreApplicationExit"); - if (SUCCEEDED(hr)) { - coreExit->Exit(); - } -} - -void -MetroApp::ActivateBaseView() -{ - if (sFrameworkView) { - sFrameworkView->ActivateView(); - } -} - -/* - * TBD: when we support multiple widgets, we'll need a way to sync up the view - * created in CreateView with the widget gecko creates. Currently we only have - * one view (sFrameworkView) and one main widget. - */ -void -MetroApp::SetWidget(MetroWidget* aPtr) -{ - LogThread(); - - NS_ASSERTION(aPtr, "setting null base widget?"); - - // Both of these calls AddRef the ptr we pass in - aPtr->SetView(sFrameworkView.Get()); - sFrameworkView->SetWidget(aPtr); -} - -//////////////////////////////////////////////////// -// MetroApp events - -HRESULT -MetroApp::OnSuspending(IInspectable* aSender, ISuspendingEventArgs* aArgs) -{ - LogThread(); - PostSuspendResumeProcessNotification(true); - return S_OK; -} - -HRESULT -MetroApp::OnResuming(IInspectable* aSender, IInspectable* aArgs) -{ - LogThread(); - PostSuspendResumeProcessNotification(false); - return S_OK; -} - -HRESULT -MetroApp::OnAsyncTileCreated(ABI::Windows::Foundation::IAsyncOperation* aOperation, - AsyncStatus aStatus) -{ - WinUtils::Log("Async operation status: %d", aStatus); - MetroUtils::FireObserver("metro_on_async_tile_created"); - return S_OK; -} - -// static -void -MetroApp::PostSuspendResumeProcessNotification(const bool aIsSuspend) -{ - static bool isSuspend = false; - if (isSuspend == aIsSuspend) { - return; - } - isSuspend = aIsSuspend; - MetroUtils::FireObserver(aIsSuspend ? "suspend_process_notification" : - "resume_process_notification"); -} - -// static -void -MetroApp::PostSleepWakeNotification(const bool aIsSleep) -{ - static bool isSleep = false; - if (isSleep == aIsSleep) { - return; - } - isSleep = aIsSleep; - MetroUtils::FireObserver(aIsSleep ? "sleep_notification" : - "wake_notification"); -} - -} } } - - -static bool -IsBackgroundSessionClosedStartup() -{ - int argc; - LPWSTR *argv = CommandLineToArgvW(GetCommandLineW(), &argc); - bool backgroundSessionClosed = argc > 1 && !wcsicmp(argv[1], L"-BackgroundSessionClosed"); - LocalFree(argv); - return backgroundSessionClosed; -} - -bool -XRE_MetroCoreApplicationRun() -{ - HRESULT hr; - LogThread(); - - using namespace mozilla::widget::winrt; - - sMetroApp = Make(); - - HStringReference className(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication); - hr = GetActivationFactory(className.Get(), sCoreApp.GetAddressOf()); - if (FAILED(hr)) { - LogHRESULT(hr); - return false; - } - - // Perform any cleanup for unclean shutdowns here, such as when the background session - // is closed via the appbar on the left when outside of Metro. Windows restarts the - // process solely for cleanup reasons. - if (IsBackgroundSessionClosedStartup() && SUCCEEDED(XRE_metroStartup(false))) { - - // Whether or not to use sessionstore depends on if the bak exists. Since host process - // shutdown isn't a crash we shouldn't restore sessionstore. - nsCOMPtr sessionBAK; - if (NS_FAILED(NS_GetSpecialDirectory("ProfDS", getter_AddRefs(sessionBAK)))) { - return false; - } - - sessionBAK->AppendNative(nsDependentCString("sessionstore.bak")); - bool exists; - if (NS_SUCCEEDED(sessionBAK->Exists(&exists)) && exists) { - sessionBAK->Remove(false); - } - return false; - } - - hr = sCoreApp->Run(sMetroApp.Get()); - - WinUtils::Log("Exiting CoreApplication::Run"); - - sCoreApp = nullptr; - sMetroApp = nullptr; - - return true; -} - diff --git a/widget/windows/winrt/MetroApp.h b/widget/windows/winrt/MetroApp.h deleted file mode 100644 index 2d9dac4cb08..00000000000 --- a/widget/windows/winrt/MetroApp.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#pragma once - -#include "mozwrlbase.h" - -#include -#include -#include -#include -#include - -class MetroWidget; - -namespace mozilla { -namespace widget { -namespace winrt { - -class MetroApp : public Microsoft::WRL::RuntimeClass -{ - InspectableClass(L"MetroApp", TrustLevel::BaseTrust) - - typedef ABI::Windows::UI::Core::CoreDispatcherPriority CoreDispatcherPriority; - typedef ABI::Windows::ApplicationModel::Activation::LaunchActivatedEventArgs LaunchActivatedEventArgs; - typedef ABI::Windows::ApplicationModel::ISuspendingEventArgs ISuspendingEventArgs; - typedef ABI::Windows::ApplicationModel::Core::IFrameworkView IFrameworkView; - typedef ABI::Windows::ApplicationModel::Core::ICoreApplication ICoreApplication; - -public: - // IFrameworkViewSource - STDMETHODIMP CreateView(IFrameworkView **viewProvider); - - // ICoreApplication event - HRESULT OnSuspending(IInspectable* aSender, ISuspendingEventArgs* aArgs); - HRESULT OnResuming(IInspectable* aSender, IInspectable* aArgs); - - // nsIWinMetroUtils tile related async callbacks - HRESULT OnAsyncTileCreated(ABI::Windows::Foundation::IAsyncOperation* aOperation, AsyncStatus aStatus); - - void Run(); - void CoreExit(); - void Shutdown(); - void ActivateBaseView(); - - // Set when gecko enters xpcom shutdown. - static bool sGeckoShuttingDown; - - // Shared pointers between framework and widget - void SetWidget(MetroWidget* aPtr); - - static void PostSuspendResumeProcessNotification(bool aIsSuspend); - static void PostSleepWakeNotification(bool aIsSuspend); - -private: - EventRegistrationToken mSuspendEvent; - EventRegistrationToken mResumeEvent; -}; - -} } } diff --git a/widget/windows/winrt/MetroAppShell.cpp b/widget/windows/winrt/MetroAppShell.cpp deleted file mode 100644 index 3666b0fddbe..00000000000 --- a/widget/windows/winrt/MetroAppShell.cpp +++ /dev/null @@ -1,522 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "MetroAppShell.h" - -#include "mozilla/AutoRestore.h" -#include "mozilla/TimeStamp.h" -#include "mozilla/widget/AudioSession.h" -#include "mozilla/ipc/WindowsMessageLoop.h" - -#include "nsIObserverService.h" -#include "nsIAppStartup.h" -#include "nsToolkitCompsCID.h" -#include "nsIPowerManagerService.h" - -#include "nsXULAppAPI.h" -#include "nsServiceManagerUtils.h" -#include "WinUtils.h" -#include "nsWinMetroUtils.h" -#include "MetroUtils.h" -#include "MetroApp.h" -#include "FrameworkView.h" -#include "WakeLockListener.h" - -#include - -using namespace mozilla; -using namespace mozilla::widget; -using namespace mozilla::widget::winrt; -using namespace Microsoft::WRL; -using namespace Microsoft::WRL::Wrappers; -using namespace ABI::Windows::UI::Core; -using namespace ABI::Windows::Foundation; - -// ProcessNextNativeEvent message wait timeout, see bug 907410. -#define MSG_WAIT_TIMEOUT 250 -// MetroInput will occasionally ask us to flush all input so that the dom is -// up to date. This is the maximum amount of time we'll agree to spend in -// NS_ProcessPendingEvents. -#define PURGE_MAX_TIMEOUT 50 - -namespace mozilla { -namespace widget { -namespace winrt { -extern ComPtr sMetroApp; -} } } - -namespace mozilla { -namespace widget { -// pulled from win32 app shell -extern UINT sAppShellGeckoMsgId; -} } - -static ComPtr sCoreStatic; -static bool sIsDispatching = false; -static bool sShouldPurgeThreadQueue = false; -static bool sBlockNativeEvents = false; -static TimeStamp sPurgeThreadQueueStart; - -MetroAppShell::~MetroAppShell() -{ - if (mEventWnd) { - SendMessage(mEventWnd, WM_CLOSE, 0, 0); - } -} - -nsresult -MetroAppShell::Init() -{ - LogFunction(); - - WNDCLASSW wc; - HINSTANCE module = GetModuleHandle(nullptr); - - mozilla::ipc::windows::InitUIThread(); - - const char16_t *const kWindowClass = L"nsAppShell:EventWindowClass"; - if (!GetClassInfoW(module, kWindowClass, &wc)) { - wc.style = 0; - wc.lpfnWndProc = EventWindowProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = module; - wc.hIcon = nullptr; - wc.hCursor = nullptr; - wc.hbrBackground = (HBRUSH) nullptr; - wc.lpszMenuName = (LPCWSTR) nullptr; - wc.lpszClassName = kWindowClass; - RegisterClassW(&wc); - } - - mEventWnd = CreateWindowW(kWindowClass, L"nsAppShell:EventWindow", - 0, 0, 0, 10, 10, nullptr, nullptr, module, nullptr); - NS_ENSURE_STATE(mEventWnd); - - nsresult rv; - nsCOMPtr observerService = - do_GetService("@mozilla.org/observer-service;1", &rv); - if (NS_SUCCEEDED(rv)) { - observerService->AddObserver(this, "dl-start", false); - observerService->AddObserver(this, "dl-done", false); - observerService->AddObserver(this, "dl-cancel", false); - observerService->AddObserver(this, "dl-failed", false); - } - - return nsBaseAppShell::Init(); -} - -HRESULT -SHCreateShellItemArrayFromShellItemDynamic(IShellItem *psi, REFIID riid, void **ppv) -{ - HMODULE shell32DLL = LoadLibraryW(L"shell32.dll"); - if (!shell32DLL) { - return E_FAIL; - } - - typedef BOOL (WINAPI* SHFn)(IShellItem *psi, REFIID riid, void **ppv); - - HRESULT hr = E_FAIL; - SHFn SHCreateShellItemArrayFromShellItemDynamicPtr = - (SHFn)GetProcAddress(shell32DLL, "SHCreateShellItemArrayFromShellItem"); - FreeLibrary(shell32DLL); - if (SHCreateShellItemArrayFromShellItemDynamicPtr) { - hr = SHCreateShellItemArrayFromShellItemDynamicPtr(psi, riid, ppv); - } - - FreeLibrary(shell32DLL); - return hr; -} - -HRESULT -WinLaunchDeferredMetroFirefox() -{ - // Create an instance of the Firefox Metro CEH which is used to launch the browser - const CLSID CLSID_FirefoxMetroDEH = {0x5100FEC1,0x212B, 0x4BF5 ,{0x9B,0xF8, 0x3E,0x65, 0x0F,0xD7,0x94,0xA3}}; - - nsRefPtr executeCommand; - HRESULT hr = CoCreateInstance(CLSID_FirefoxMetroDEH, - nullptr, - CLSCTX_LOCAL_SERVER, - IID_IExecuteCommand, - getter_AddRefs(executeCommand)); - if (FAILED(hr)) - return hr; - - // Get the currently running exe path - WCHAR exePath[MAX_PATH + 1] = { L'\0' }; - if (!::GetModuleFileNameW(0, exePath, MAX_PATH)) - return hr; - - // Convert the path to a long path since GetModuleFileNameW returns the path - // that was used to launch Firefox which is not necessarily a long path. - if (!::GetLongPathNameW(exePath, exePath, MAX_PATH)) - return hr; - - // Create an IShellItem for the current browser path - nsRefPtr shellItem; - hr = WinUtils::SHCreateItemFromParsingName(exePath, nullptr, IID_IShellItem, - getter_AddRefs(shellItem)); - if (FAILED(hr)) - return hr; - - // Convert to an IShellItemArray which is used for the path to launch - nsRefPtr shellItemArray; - hr = SHCreateShellItemArrayFromShellItemDynamic(shellItem, IID_IShellItemArray, getter_AddRefs(shellItemArray)); - if (FAILED(hr)) - return hr; - - // Set the path to launch and parameters needed - nsRefPtr selection; - hr = executeCommand->QueryInterface(IID_IObjectWithSelection, getter_AddRefs(selection)); - if (FAILED(hr)) - return hr; - hr = selection->SetSelection(shellItemArray); - if (FAILED(hr)) - return hr; - - if (nsWinMetroUtils::sUpdatePending) { - hr = executeCommand->SetParameters(L"--metro-update"); - } else { - hr = executeCommand->SetParameters(L"--metro-restart"); - } - if (FAILED(hr)) - return hr; - - // Run the default browser through the CEH - return executeCommand->Execute(); -} - -static WakeLockListener* -InitWakeLock() -{ - nsCOMPtr powerManagerService = - do_GetService(POWERMANAGERSERVICE_CONTRACTID); - if (powerManagerService) { - WakeLockListener* pLock = new WakeLockListener(); - powerManagerService->AddWakeLockListener(pLock); - return pLock; - } - else { - NS_WARNING("Failed to retrieve PowerManagerService, wakelocks will be broken!"); - } - return nullptr; -} - -static void -ShutdownWakeLock(WakeLockListener* aLock) -{ - if (!aLock) { - return; - } - nsCOMPtr powerManagerService = - do_GetService(POWERMANAGERSERVICE_CONTRACTID); - if (powerManagerService) { - powerManagerService->RemoveWakeLockListener(aLock); - } -} - -// Called by appstartup->run in xre, which is initiated by a call to -// XRE_metroStartup in MetroApp. This call is on the metro main thread. -NS_IMETHODIMP -MetroAppShell::Run(void) -{ - LogFunction(); - nsresult rv = NS_OK; - - switch(XRE_GetProcessType()) { - case GeckoProcessType_Content: - case GeckoProcessType_IPDLUnitTest: - mozilla::widget::StartAudioSession(); - rv = nsBaseAppShell::Run(); - mozilla::widget::StopAudioSession(); - break; - case GeckoProcessType_Plugin: - NS_WARNING("We don't support plugins currently."); - // Just exit - rv = NS_ERROR_NOT_IMPLEMENTED; - break; - case GeckoProcessType_Default: { - { - nsRefPtr wakeLock = InitWakeLock(); - mozilla::widget::StartAudioSession(); - sMetroApp->ActivateBaseView(); - rv = nsBaseAppShell::Run(); - mozilla::widget::StopAudioSession(); - ShutdownWakeLock(wakeLock); - } - - nsCOMPtr appStartup (do_GetService(NS_APPSTARTUP_CONTRACTID)); - bool restartingInMetro = false, restartingInDesktop = false; - - if (!appStartup || NS_FAILED(appStartup->GetRestarting(&restartingInDesktop))) { - WinUtils::Log("appStartup->GetRestarting() unsuccessful"); - } - - if (appStartup && NS_SUCCEEDED(appStartup->GetRestartingTouchEnvironment(&restartingInMetro)) && - restartingInMetro) { - restartingInDesktop = false; - } - - // This calls XRE_metroShutdown() in xre. Shuts down gecko, including - // releasing the profile, and destroys MessagePump. - sMetroApp->Shutdown(); - - // Handle update restart or browser switch requests - if (restartingInDesktop) { - WinUtils::Log("Relaunching desktop browser"); - // We can't call into the ceh to do this. Microsoft prevents switching to - // desktop unless we go through shell execute. - SHELLEXECUTEINFOW sinfo; - memset(&sinfo, 0, sizeof(SHELLEXECUTEINFOW)); - sinfo.cbSize = sizeof(SHELLEXECUTEINFOW); - // Per microsoft's metro style enabled desktop browser documentation - // SEE_MASK_FLAG_LOG_USAGE is needed if we want to change from immersive - // mode to desktop mode. - sinfo.fMask = SEE_MASK_FLAG_LOG_USAGE; - // The ceh will filter out this fake target. - sinfo.lpFile = L"http://-desktop/"; - sinfo.lpVerb = L"open"; - sinfo.lpParameters = L"--desktop-restart"; - sinfo.nShow = SW_SHOWNORMAL; - ShellExecuteEx(&sinfo); - } else if (restartingInMetro) { - HRESULT hresult = WinLaunchDeferredMetroFirefox(); - WinUtils::Log("Relaunching metro browser (hr=%X)", hresult); - } - - // This will free the real main thread in CoreApplication::Run() - // once winrt cleans up this thread. - sMetroApp->CoreExit(); - } - break; - } - - return rv; -} - -// Called in certain cases where we have async input events in the thread -// queue and need to make sure they get dispatched before the stack unwinds. -void // static -MetroAppShell::MarkEventQueueForPurge() -{ - sShouldPurgeThreadQueue = true; - - // If we're dispatching native events, wait until the dispatcher is - // off the stack. - if (sIsDispatching) { - return; - } - - // Safe to process pending events now - DispatchAllGeckoEvents(); -} - -// Notification from MetroInput that all events it wanted delivered -// have been dispatched. It is safe to start processing windowing -// events. -void // static -MetroAppShell::InputEventsDispatched() -{ - sBlockNativeEvents = false; -} - -// static -void -MetroAppShell::DispatchAllGeckoEvents() -{ - // Only do this if requested and when we're not shutting down - if (!sShouldPurgeThreadQueue || MetroApp::sGeckoShuttingDown) { - return; - } - - NS_ASSERTION(NS_IsMainThread(), "DispatchAllGeckoEvents should be called on the main thread"); - - sShouldPurgeThreadQueue = false; - sPurgeThreadQueueStart = TimeStamp::Now(); - - sBlockNativeEvents = true; - nsIThread *thread = NS_GetCurrentThread(); - NS_ProcessPendingEvents(thread, PURGE_MAX_TIMEOUT); - sBlockNativeEvents = false; -} - -static void -ProcessNativeEvents(CoreProcessEventsOption eventOption) -{ - HRESULT hr; - if (!sCoreStatic) { - hr = GetActivationFactory(HStringReference(L"Windows.UI.Core.CoreWindow").Get(), sCoreStatic.GetAddressOf()); - NS_ASSERTION(SUCCEEDED(hr), "GetActivationFactory failed?"); - AssertHRESULT(hr); - } - - ComPtr window; - AssertHRESULT(sCoreStatic->GetForCurrentThread(window.GetAddressOf())); - ComPtr dispatcher; - hr = window->get_Dispatcher(&dispatcher); - NS_ASSERTION(SUCCEEDED(hr), "get_Dispatcher failed?"); - AssertHRESULT(hr); - dispatcher->ProcessEvents(eventOption); -} - -// static -bool -MetroAppShell::ProcessOneNativeEventIfPresent() -{ - if (sIsDispatching) { - // Calling into ProcessNativeEvents is harmless, but won't actually process any - // native events. So we log here so we can spot this and get a handle on the - // corner cases where this can happen. - WinUtils::Log("WARNING: Reentrant call into process events detected, returning early."); - return false; - } - - { - AutoRestore dispatching(sIsDispatching); - sIsDispatching = true; - ProcessNativeEvents(CoreProcessEventsOption::CoreProcessEventsOption_ProcessOneIfPresent); - } - - DispatchAllGeckoEvents(); - - return !!HIWORD(::GetQueueStatus(MOZ_QS_ALLEVENT)); -} - -bool -MetroAppShell::ProcessNextNativeEvent(bool mayWait) -{ - // NS_ProcessPendingEvents will process thread events *and* call - // nsBaseAppShell::OnProcessNextEvent to process native events. However - // we do not want native events getting dispatched while we are trying - // to dispatch pending input in DispatchAllGeckoEvents since a native - // event may be a UIA Automation call coming in to check focus. - if (sBlockNativeEvents) { - if ((TimeStamp::Now() - sPurgeThreadQueueStart).ToMilliseconds() - < PURGE_MAX_TIMEOUT) { - return false; - } - sBlockNativeEvents = false; - } - - if (ProcessOneNativeEventIfPresent()) { - return true; - } - if (mayWait) { - DWORD result = ::MsgWaitForMultipleObjectsEx(0, nullptr, MSG_WAIT_TIMEOUT, - MOZ_QS_ALLEVENT, - MWMO_INPUTAVAILABLE|MWMO_ALERTABLE); - NS_WARN_IF_FALSE(result != WAIT_FAILED, "Wait failed"); - } - return ProcessOneNativeEventIfPresent(); -} - -void -MetroAppShell::NativeCallback() -{ - NS_ASSERTION(NS_IsMainThread(), "Native callbacks must be on the metro main thread"); - - // We shouldn't process native events during xpcom shutdown - this can - // trigger unexpected xpcom event dispatching for the main thread when - // the thread manager is in the process of shutting down non-main threads, - // resulting in shutdown hangs. - if (MetroApp::sGeckoShuttingDown) { - return; - } - - NativeEventCallback(); -} - -// static -LRESULT CALLBACK -MetroAppShell::EventWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - if (uMsg == sAppShellGeckoMsgId) { - MetroAppShell *as = reinterpret_cast(lParam); - as->NativeCallback(); - NS_RELEASE(as); - return TRUE; - } - return DefWindowProc(hwnd, uMsg, wParam, lParam); -} - -void -MetroAppShell::ScheduleNativeEventCallback() -{ - NS_ADDREF_THIS(); - PostMessage(mEventWnd, sAppShellGeckoMsgId, 0, reinterpret_cast(this)); -} - -void -MetroAppShell::DoProcessMoreGeckoEvents() -{ - ScheduleNativeEventCallback(); -} - -static HANDLE -PowerCreateRequestDyn(REASON_CONTEXT *context) -{ - typedef HANDLE (WINAPI * PowerCreateRequestPtr)(REASON_CONTEXT *context); - static HMODULE kernel32 = GetModuleHandleW(L"kernel32.dll"); - static PowerCreateRequestPtr powerCreateRequest = - (PowerCreateRequestPtr)GetProcAddress(kernel32, "PowerCreateRequest"); - if (!powerCreateRequest) - return INVALID_HANDLE_VALUE; - return powerCreateRequest(context); -} - -static BOOL -PowerClearRequestDyn(HANDLE powerRequest, POWER_REQUEST_TYPE requestType) -{ - typedef BOOL (WINAPI * PowerClearRequestPtr)(HANDLE powerRequest, POWER_REQUEST_TYPE requestType); - static HMODULE kernel32 = GetModuleHandleW(L"kernel32.dll"); - static PowerClearRequestPtr powerClearRequest = - (PowerClearRequestPtr)GetProcAddress(kernel32, "PowerClearRequest"); - if (!powerClearRequest) - return FALSE; - return powerClearRequest(powerRequest, requestType); -} - -static BOOL -PowerSetRequestDyn(HANDLE powerRequest, POWER_REQUEST_TYPE requestType) -{ - typedef BOOL (WINAPI * PowerSetRequestPtr)(HANDLE powerRequest, POWER_REQUEST_TYPE requestType); - static HMODULE kernel32 = GetModuleHandleW(L"kernel32.dll"); - static PowerSetRequestPtr powerSetRequest = - (PowerSetRequestPtr)GetProcAddress(kernel32, "PowerSetRequest"); - if (!powerSetRequest) - return FALSE; - return powerSetRequest(powerRequest, requestType); -} - -NS_IMETHODIMP -MetroAppShell::Observe(nsISupports *subject, const char *topic, - const char16_t *data) -{ - NS_ENSURE_ARG_POINTER(topic); - if (!strcmp(topic, "dl-start")) { - if (mPowerRequestCount++ == 0) { - WinUtils::Log("Download started - Disallowing suspend"); - REASON_CONTEXT context; - context.Version = POWER_REQUEST_CONTEXT_VERSION; - context.Flags = POWER_REQUEST_CONTEXT_SIMPLE_STRING; - context.Reason.SimpleReasonString = L"downloading"; - mPowerRequest.own(PowerCreateRequestDyn(&context)); - PowerSetRequestDyn(mPowerRequest, PowerRequestExecutionRequired); - } - return NS_OK; - } else if (!strcmp(topic, "dl-done") || - !strcmp(topic, "dl-cancel") || - !strcmp(topic, "dl-failed")) { - if (--mPowerRequestCount == 0 && mPowerRequest) { - WinUtils::Log("All downloads ended - Allowing suspend"); - PowerClearRequestDyn(mPowerRequest, PowerRequestExecutionRequired); - mPowerRequest.reset(); - } - return NS_OK; - } - - return nsBaseAppShell::Observe(subject, topic, data); -} diff --git a/widget/windows/winrt/MetroAppShell.h b/widget/windows/winrt/MetroAppShell.h deleted file mode 100644 index b1bd7f55db1..00000000000 --- a/widget/windows/winrt/MetroAppShell.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#pragma once - -#include "nsBaseAppShell.h" -#include -#include "nsWindowsHelpers.h" -#include "nsIObserver.h" - -class MetroAppShell : public nsBaseAppShell -{ -public: - NS_DECL_NSIOBSERVER - - MetroAppShell() : - mEventWnd(nullptr), - mPowerRequestCount(0) - { - } - - nsresult Init(); - void DoProcessMoreGeckoEvents(); - void NativeCallback(); - - static LRESULT CALLBACK EventWindowProc(HWND, UINT, WPARAM, LPARAM); - static bool ProcessOneNativeEventIfPresent(); - static void MarkEventQueueForPurge(); - static void InputEventsDispatched(); - -protected: - NS_IMETHOD Run(); - - virtual void ScheduleNativeEventCallback(); - virtual bool ProcessNextNativeEvent(bool mayWait); - static void DispatchAllGeckoEvents(); - virtual ~MetroAppShell(); - - HWND mEventWnd; - nsAutoHandle mPowerRequest; - ULONG mPowerRequestCount; -}; diff --git a/widget/windows/winrt/MetroContracts.cpp b/widget/windows/winrt/MetroContracts.cpp deleted file mode 100644 index 7bb04e431af..00000000000 --- a/widget/windows/winrt/MetroContracts.cpp +++ /dev/null @@ -1,576 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "FrameworkView.h" -#include "MetroUtils.h" -#include "nsICommandLineRunner.h" -#include "nsNetUtil.h" -#include "nsIDOMChromeWindow.h" -#include "nsIURI.h" -#include "nsPrintfCString.h" -#include "mozilla/Services.h" -#include -#include -#include -#include -#include -#include -#include "MetroUIUtils.h" -#include "nsIStringBundle.h" - -using namespace mozilla; -using namespace ABI::Windows::Foundation; -using namespace ABI::Windows::Foundation::Collections; -using namespace Microsoft::WRL; -using namespace Microsoft::WRL::Wrappers; - -// Play to contract -using namespace ABI::Windows::Media::PlayTo; - -// Activation contracts -using namespace ABI::Windows::ApplicationModel::Activation; -using namespace ABI::Windows::ApplicationModel::DataTransfer; -using namespace ABI::Windows::ApplicationModel::Search; - -// Settings contract -using namespace ABI::Windows::UI::ApplicationSettings; -using namespace ABI::Windows::UI::Popups; - -// Print contract -using namespace ABI::Windows::Graphics::Printing; - -namespace mozilla { -namespace widget { -namespace winrt { - -extern nsTArray* sSettingsArray; - -void -FrameworkView::SearchActivated(ComPtr& aArgs, bool aStartup) -{ - if (!aArgs) - return; - - HString data; - AssertHRESULT(aArgs->get_QueryText(data.GetAddressOf())); - if (WindowsIsStringEmpty(data.Get())) - return; - - unsigned int length; - WinUtils::LogW(L"SearchActivated text=%s", data.GetRawBuffer(&length)); - if (aStartup) { - WindowsDuplicateString(data.Get(), &sActivationURI); - } else { - PerformURILoadOrSearch(data); - } -} - -void -FrameworkView::FileActivated(ComPtr& aArgs, bool aStartup) -{ - if (!aArgs) - return; - - ComPtr> list; - AssertHRESULT(aArgs->get_Files(list.GetAddressOf())); - ComPtr item; - AssertHRESULT(list->GetAt(0, item.GetAddressOf())); - HString filePath; - AssertHRESULT(item->get_Path(filePath.GetAddressOf())); - - if (aStartup) { - WindowsDuplicateString(filePath.Get(), &sActivationURI); - } else { - PerformURILoad(filePath); - } -} - -void -FrameworkView::LaunchActivated(ComPtr& aArgs, bool aStartup) -{ - if (!aArgs) - return; - HString data; - AssertHRESULT(aArgs->get_Arguments(data.GetAddressOf())); - if (WindowsIsStringEmpty(data.Get())) - return; - - // If we're being launched from a secondary tile then we have a 2nd command line param of --url - // and a third of the secondary tile. We want it in sActivationURI so that browser.js will - // load it in without showing the start UI. - int argc; - unsigned int length; - LPWSTR* argv = CommandLineToArgvW(data.GetRawBuffer(&length), &argc); - if (aStartup && argc == 2 && - (!wcsicmp(argv[0], L"-url") || - !wcsicmp(argv[0], L"--url") || - !wcsicmp(argv[0], L"/url"))) { - WindowsCreateString(argv[1], wcslen(argv[1]), &sActivationURI); - } else { - // Some other command line or this is not a startup. - // If it is startup we process it later when XPCOM is initialilzed. - mActivationCommandLine = data.GetRawBuffer(&length); - if (!aStartup) { - ProcessLaunchArguments(); - } - } -} - -void -FrameworkView::ProcessLaunchArguments() -{ - if (!mActivationCommandLine.Length()) - return; - - int argc; - LPWSTR* argv = CommandLineToArgvW(mActivationCommandLine.BeginReading(), &argc); - nsCOMPtr cmdLine = - (do_CreateInstance("@mozilla.org/toolkit/command-line;1")); - if (!cmdLine) { - NS_WARNING("Unable to instantiate command line runner."); - return; - } - - LPSTR *argvUTF8 = new LPSTR[argc]; - for (int i = 0; i < argc; ++i) { - NS_ConvertUTF16toUTF8 arg(argv[i]); - argvUTF8[i] = new char[arg.Length() + 1]; - strcpy(argvUTF8[i], const_cast(arg.BeginReading())); - WinUtils::LogW(L"Launch arg[%d]: '%s'", i, argv[i]); - } - - nsresult rv = cmdLine->Init(argc, - argvUTF8, - nullptr, - nsICommandLine::STATE_REMOTE_EXPLICIT); - if (NS_SUCCEEDED(rv)) { - cmdLine->Run(); - } else { - NS_WARNING("cmdLine->Init failed."); - } - - for (int i = 0; i < argc; ++i) { - delete[] argvUTF8[i]; - } - delete[] argvUTF8; -} - -void -FrameworkView::ProcessActivationArgs(IActivatedEventArgs* aArgs, bool aStartup) -{ - ActivationKind kind; - if (!aArgs || FAILED(aArgs->get_Kind(&kind))) - return; - ComPtr args(aArgs); - if (kind == ActivationKind::ActivationKind_Protocol) { - WinUtils::Log("Activation argument kind: Protocol"); - ComPtr protoArgs; - AssertHRESULT(args.As(&protoArgs)); - ComPtr uri; - AssertHRESULT(protoArgs->get_Uri(uri.GetAddressOf())); - if (!uri) - return; - - HString data; - AssertHRESULT(uri->get_AbsoluteUri(data.GetAddressOf())); - if (WindowsIsStringEmpty(data.Get())) - return; - - if (aStartup) { - WindowsDuplicateString(data.Get(), &sActivationURI); - } else { - PerformURILoad(data); - } - } else if (kind == ActivationKind::ActivationKind_Search) { - WinUtils::Log("Activation argument kind: Search"); - ComPtr searchArgs; - args.As(&searchArgs); - SearchActivated(searchArgs, aStartup); - } else if (kind == ActivationKind::ActivationKind_File) { - WinUtils::Log("Activation argument kind: File"); - ComPtr fileArgs; - args.As(&fileArgs); - FileActivated(fileArgs, aStartup); - } else if (kind == ActivationKind::ActivationKind_Launch) { - WinUtils::Log("Activation argument kind: Launch"); - ComPtr launchArgs; - args.As(&launchArgs); - LaunchActivated(launchArgs, aStartup); - } -} - -void -FrameworkView::SetupContracts() -{ - LogFunction(); - HRESULT hr; - - // Add support for the share charm to indicate that we share data to other apps - ComPtr transStatics; - hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_ApplicationModel_DataTransfer_DataTransferManager).Get(), - transStatics.GetAddressOf()); - AssertHRESULT(hr); - ComPtr trans; - AssertHRESULT(transStatics->GetForCurrentView(trans.GetAddressOf())); - trans->add_DataRequested(Callback<__FITypedEventHandler_2_Windows__CApplicationModel__CDataTransfer__CDataTransferManager_Windows__CApplicationModel__CDataTransfer__CDataRequestedEventArgs_t>( - this, &FrameworkView::OnDataShareRequested).Get(), &mDataTransferRequested); - - // Add support for the search charm to indicate that you can search using our app. - ComPtr searchStatics; - hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_ApplicationModel_Search_SearchPane).Get(), - searchStatics.GetAddressOf()); - AssertHRESULT(hr); - ComPtr searchPane; - AssertHRESULT(searchStatics->GetForCurrentView(searchPane.GetAddressOf())); - searchPane->add_QuerySubmitted(Callback<__FITypedEventHandler_2_Windows__CApplicationModel__CSearch__CSearchPane_Windows__CApplicationModel__CSearch__CSearchPaneQuerySubmittedEventArgs_t>( - this, &FrameworkView::OnSearchQuerySubmitted).Get(), &mSearchQuerySubmitted); - - // Add support for the devices play to charm - ComPtr playToStatics; - hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_Media_PlayTo_PlayToManager).Get(), - playToStatics.GetAddressOf()); - AssertHRESULT(hr); - ComPtr playTo; - AssertHRESULT(playToStatics->GetForCurrentView(playTo.GetAddressOf())); - playTo->add_SourceRequested(Callback<__FITypedEventHandler_2_Windows__CMedia__CPlayTo__CPlayToManager_Windows__CMedia__CPlayTo__CPlayToSourceRequestedEventArgs_t>( - this, &FrameworkView::OnPlayToSourceRequested).Get(), &mPlayToRequested); - - // Add support for the settings charm - ComPtr settingsPaneStatics; - hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_UI_ApplicationSettings_SettingsPane).Get(), - settingsPaneStatics.GetAddressOf()); - AssertHRESULT(hr); - ComPtr settingsPane; - AssertHRESULT(settingsPaneStatics->GetForCurrentView(settingsPane.GetAddressOf())); - settingsPane->add_CommandsRequested(Callback<__FITypedEventHandler_2_Windows__CUI__CApplicationSettings__CSettingsPane_Windows__CUI__CApplicationSettings__CSettingsPaneCommandsRequestedEventArgs_t>( - this, &FrameworkView::OnSettingsCommandsRequested).Get(), &mSettingsPane); - - // Add support for the settings print charm - ComPtr printStatics; - hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Printing_PrintManager).Get(), - printStatics.GetAddressOf()); - AssertHRESULT(hr); - ComPtr printManager; - AssertHRESULT(printStatics->GetForCurrentView(printManager.GetAddressOf())); - printManager->add_PrintTaskRequested(Callback<__FITypedEventHandler_2_Windows__CGraphics__CPrinting__CPrintManager_Windows__CGraphics__CPrinting__CPrintTaskRequestedEventArgs_t>( - this, &FrameworkView::OnPrintTaskRequested).Get(), &mPrintManager); -} - -void -FrameworkView::PerformURILoad(HString& aURI) -{ - LogFunction(); - - unsigned int length; - WinUtils::LogW(L"PerformURILoad uri=%s", aURI.GetRawBuffer(&length)); - - nsCOMPtr cmdLine = - (do_CreateInstance("@mozilla.org/toolkit/command-line;1")); - if (!cmdLine) { - NS_WARNING("Unable to instantiate command line runner."); - return; - } - - nsAutoCString utf8data(NS_ConvertUTF16toUTF8(aURI.GetRawBuffer(&length))); - - // NB: The first argument gets stripped by nsICommandLineRunner::Init, - // so it doesn't matter what we pass as the first argument, but we - // have to pass something. - const char *argv[] = { "", // This argument gets stripped - "-url", - utf8data.BeginReading() }; - nsresult rv = cmdLine->Init(ArrayLength(argv), - const_cast(argv), nullptr, - nsICommandLine::STATE_REMOTE_EXPLICIT); - if (NS_FAILED(rv)) { - NS_WARNING("cmdLine->Init failed."); - return; - } - cmdLine->Run(); -} - -void -FrameworkView::PerformSearch(HString& aQuery) -{ - LogFunction(); - - nsCOMPtr cmdLine = - (do_CreateInstance("@mozilla.org/toolkit/command-line;1")); - if (!cmdLine) { - NS_WARNING("Unable to instantiate command line runner."); - return; - } - - nsAutoCString parameter; - parameter.Append('"'); - unsigned int length; - parameter.Append(NS_ConvertUTF16toUTF8(aQuery.GetRawBuffer(&length))); - parameter.Append('"'); - - // NB: The first argument gets stripped by nsICommandLineRunner::Init, - // so it doesn't matter what we pass as the first argument, but we - // have to pass something. - const char *argv[] = { "", // This argument gets stripped - "-search", - parameter.BeginReading() }; - nsresult rv = cmdLine->Init(ArrayLength(argv), - const_cast(argv), nullptr, - nsICommandLine::STATE_REMOTE_EXPLICIT); - if (NS_FAILED(rv)) { - NS_WARNING("cmdLine->Init failed."); - return; - } - cmdLine->Run(); -} - -void -FrameworkView::PerformURILoadOrSearch(HString& aString) -{ - LogFunction(); - - if (WindowsIsStringEmpty(aString.Get())) { - WinUtils::Log("Emptry string passed to PerformURILoadOrSearch"); - return; - } - - // If we have a URI then devert to load the URI directly - ComPtr uri; - MetroUtils::CreateUri(aString.Get(), uri); - if (uri) { - PerformURILoad(aString); - } else { - PerformSearch(aString); - } -} - -HRESULT -FrameworkView::OnDataShareRequested(IDataTransferManager* aDTM, - IDataRequestedEventArgs* aArg) -{ - // Only share pages that contain a title and a URI - nsCOMPtr metroUIUtils = do_CreateInstance("@mozilla.org/metro-ui-utils;1"); - if (!metroUIUtils) - return E_FAIL; - - nsString url, title; - nsresult rv = metroUIUtils->GetCurrentPageURI(url); - nsresult rv2 = metroUIUtils->GetCurrentPageTitle(title); - if (NS_FAILED(rv) || NS_FAILED(rv2)) { - return E_FAIL; - } - - // Get the package to share - HRESULT hr; - ComPtr request; - AssertRetHRESULT(hr = aArg->get_Request(request.GetAddressOf()), hr); - ComPtr dataPackage; - AssertRetHRESULT(hr = request->get_Data(dataPackage.GetAddressOf()), hr); - ComPtr props; - AssertRetHRESULT(hr = dataPackage->get_Properties(props.GetAddressOf()), hr); - - // Only add a URI to the package when there is no selected content. - // This is because most programs treat URIs as highest priority to generate - // their own preview, but we only want the selected content to show up. - bool hasSelectedContent = false; - metroUIUtils->GetHasSelectedContent(&hasSelectedContent); - if (!hasSelectedContent) { - ComPtr uri; - AssertRetHRESULT(hr = MetroUtils::CreateUri(HStringReference(url.BeginReading()).Get(), uri), hr); - - // If there is no selection, then we don't support sharing for sites that - // are not HTTP, HTTPS, FTP, and FILE. - HString schemeHString; - uri->get_SchemeName(schemeHString.GetAddressOf()); - unsigned int length; - LPCWSTR scheme = schemeHString.GetRawBuffer(&length); - if (!scheme || wcscmp(scheme, L"http") && wcscmp(scheme, L"https") && - wcscmp(scheme, L"ftp") && wcscmp(scheme, L"file")) { - return S_OK; - } - - AssertRetHRESULT(hr = dataPackage->SetUri(uri.Get()), hr); - } - - // Add whatever content metroUIUtils wants us to for the text sharing - nsString shareText; - if (NS_SUCCEEDED(metroUIUtils->GetShareText(shareText)) && shareText.Length()) { - AssertRetHRESULT(hr = dataPackage->SetText(HStringReference(shareText.BeginReading()).Get()) ,hr); - } - - // Add whatever content metroUIUtils wants us to for the HTML sharing - nsString shareHTML; - if (NS_SUCCEEDED(metroUIUtils->GetShareHTML(shareHTML)) && shareHTML.Length()) { - // The sharing format needs some special headers, so pass it through Windows - ComPtr htmlFormatHelper; - hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_ApplicationModel_DataTransfer_HtmlFormatHelper).Get(), - htmlFormatHelper.GetAddressOf()); - AssertRetHRESULT(hr, hr); - HSTRING fixedHTML; - htmlFormatHelper->CreateHtmlFormat(HStringReference(shareHTML.BeginReading()).Get(), &fixedHTML); - - // And now add the fixed HTML to the data package - AssertRetHRESULT(hr = dataPackage->SetHtmlFormat(fixedHTML), hr); - } - - // Obtain the brand name - nsCOMPtr bundleService = - do_GetService(NS_STRINGBUNDLE_CONTRACTID); - NS_ENSURE_TRUE(bundleService, E_FAIL); - nsCOMPtr brandBundle; - nsString brandName; - bundleService->CreateBundle("chrome://branding/locale/brand.properties", - getter_AddRefs(brandBundle)); - NS_ENSURE_TRUE(brandBundle, E_FAIL); - if(brandBundle) { - brandBundle->GetStringFromName(MOZ_UTF16("brandFullName"), - getter_Copies(brandName)); - } - - // Set these properties at the end. Otherwise users can get a - // "There was a problem with the data package" error when there - // is simply nothing to share. - props->put_ApplicationName(HStringReference(brandName.BeginReading()).Get()); - if (title.Length()) { - props->put_Title(HStringReference(title.BeginReading()).Get()); - } else { - props->put_Title(HStringReference(brandName.BeginReading()).Get()); - } - props->put_Description(HStringReference(url.BeginReading()).Get()); - - return S_OK; -} - -HRESULT -FrameworkView::OnSearchQuerySubmitted(ISearchPane* aPane, - ISearchPaneQuerySubmittedEventArgs* aArgs) -{ - LogFunction(); - HString aQuery; - aArgs->get_QueryText(aQuery.GetAddressOf()); - PerformURILoadOrSearch(aQuery); - return S_OK; -} - -HRESULT -FrameworkView::OnSettingsCommandInvoked(IUICommand* aCommand) -{ - LogFunction(); - HRESULT hr; - uint32_t id; - ComPtr prop; - AssertRetHRESULT(hr = aCommand->get_Id((IInspectable**)prop.GetAddressOf()), hr); - AssertRetHRESULT(hr = prop->GetUInt32(&id), hr); - - nsCOMPtr obs = mozilla::services::GetObserverService(); - if (obs) { - NS_ConvertASCIItoUTF16 idStr(nsPrintfCString("%lu", id)); - obs->NotifyObservers(nullptr, "metro-settings-entry-selected", idStr.BeginReading()); - } - - return S_OK; -} - -void -FrameworkView::AddSetting(ISettingsPaneCommandsRequestedEventArgs* aArgs, - uint32_t aId, HString& aSettingName) -{ - HRESULT hr; - - ComPtr request; - AssertHRESULT(aArgs->get_Request(request.GetAddressOf())); - - // ApplicationCommands - vector that holds SettingsCommand to be invoked - ComPtr> list; - AssertHRESULT(request->get_ApplicationCommands(list.GetAddressOf())); - - ComPtr command; - ComPtr factory; - hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_UI_ApplicationSettings_SettingsCommand).Get(), - factory.GetAddressOf()); - AssertHRESULT(hr); - - // Create the IInspectable string property that identifies this command - ComPtr prop; - ComPtr propStatics; - hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_Foundation_PropertyValue).Get(), - propStatics.GetAddressOf()); - AssertHRESULT(hr); - hr = propStatics->CreateUInt32(aId, prop.GetAddressOf()); - AssertHRESULT(hr); - - // Create the command - hr = factory->CreateSettingsCommand(prop.Get(), aSettingName.Get(), - Callback( - this, &FrameworkView::OnSettingsCommandInvoked).Get(), command.GetAddressOf()); - AssertHRESULT(hr); - - // Add it to the list - hr = list->Append(command.Get()); - AssertHRESULT(hr); -} - -HRESULT -FrameworkView::OnSettingsCommandsRequested(ISettingsPane* aPane, - ISettingsPaneCommandsRequestedEventArgs* aArgs) -{ - if (!sSettingsArray) - return E_FAIL; - if (!sSettingsArray->Length()) - return S_OK; - for (uint32_t i = 0; i < sSettingsArray->Length(); i++) { - HString label; - label.Set(sSettingsArray->ElementAt(i).BeginReading()); - AddSetting(aArgs, i, label); - } - return S_OK; -} - -HRESULT -FrameworkView::OnPlayToSourceRequested(IPlayToManager* aPlayToManager, - IPlayToSourceRequestedEventArgs* aArgs) -{ - // TODO: Implement PlayTo, find the element on the page and then do something similar to this: - // PlayToReceiver::Dispatcher.Helper.BeginInvoke( - // mMediaElement = ref new Windows::UI::Xaml::Controls::MediaElement(); - // mMediaElement->Source = ref new Uri("http://www.youtube.com/watch?v=2U0NFgoNI7s"); - // aArgs->SourceRequest->SetSource(mMediaElement->PlayToSource); - return S_OK; -} - -HRESULT -FrameworkView::OnPrintTaskSourceRequested(IPrintTaskSourceRequestedArgs* aArgs) -{ - return S_OK; -} - -HRESULT -FrameworkView::OnPrintTaskRequested(IPrintManager* aPrintManager, - IPrintTaskRequestedEventArgs* aArgs) -{ - return S_OK; -} - -void -FrameworkView::CreatePrintControl(IPrintDocumentPackageTarget* docPackageTarget, - D2D1_PRINT_CONTROL_PROPERTIES* printControlProperties) -{ -} - -HRESULT -FrameworkView::ClosePrintControl() -{ - return S_OK; -} - -// Print out one page, with the given print ticket. -// This sample has only one page and we ignore pageNumber below. -void FrameworkView::PrintPage(uint32_t pageNumber, - D2D1_RECT_F imageableArea, - D2D1_SIZE_F pageSize, - IStream* pagePrintTicketStream) -{ -} - -} } } diff --git a/widget/windows/winrt/MetroD3DCheckHelper.h b/widget/windows/winrt/MetroD3DCheckHelper.h deleted file mode 100644 index 6a44ba701ec..00000000000 --- a/widget/windows/winrt/MetroD3DCheckHelper.h +++ /dev/null @@ -1,96 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#pragma once - -/* this file is included by exe stubs, don't pull xpcom into it. */ - -#include -#include -#include - -/* - * Checks to see if the d3d implementation supports feature level 9.3 or - * above. Metrofx can't run on systems that fail this check. - * - * Note, this can hit perf, don't call this unless you absolutely have to. - * Both the ceh and winrt widget code save a cached result in the registry. - */ -static bool D3DFeatureLevelCheck() -{ - HMODULE dxgiModule = LoadLibraryA("dxgi.dll"); - if (!dxgiModule) { - return false; - } - decltype(CreateDXGIFactory1)* createDXGIFactory1 = - (decltype(CreateDXGIFactory1)*) GetProcAddress(dxgiModule, "CreateDXGIFactory1"); - if (!createDXGIFactory1) { - FreeLibrary(dxgiModule); - return false; - } - - HMODULE d3d10module = LoadLibraryA("d3d10_1.dll"); - if (!d3d10module) { - FreeLibrary(dxgiModule); - return false; - } - decltype(D3D10CreateDevice1)* createD3DDevice = - (decltype(D3D10CreateDevice1)*) GetProcAddress(d3d10module, - "D3D10CreateDevice1"); - if (!createD3DDevice) { - FreeLibrary(d3d10module); - FreeLibrary(dxgiModule); - return false; - } - - IDXGIFactory1* factory1; - if (FAILED(createDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&factory1))) { - FreeLibrary(d3d10module); - FreeLibrary(dxgiModule); - return false; - } - - IDXGIAdapter1* adapter1; - if (FAILED(factory1->EnumAdapters1(0, &adapter1))) { - factory1->Release(); - FreeLibrary(d3d10module); - FreeLibrary(dxgiModule); - return false; - } - - // Try for DX10.1 - ID3D10Device1* device; - if (FAILED(createD3DDevice(adapter1, D3D10_DRIVER_TYPE_HARDWARE, nullptr, - D3D10_CREATE_DEVICE_BGRA_SUPPORT | - D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS, - D3D10_FEATURE_LEVEL_10_1, - D3D10_1_SDK_VERSION, &device))) { - // Try for DX10 - if (FAILED(createD3DDevice(adapter1, D3D10_DRIVER_TYPE_HARDWARE, nullptr, - D3D10_CREATE_DEVICE_BGRA_SUPPORT | - D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS, - D3D10_FEATURE_LEVEL_10_0, - D3D10_1_SDK_VERSION, &device))) { - // Try for DX9.3 (we fall back to cairo and cairo has support for D3D 9.3) - if (FAILED(createD3DDevice(adapter1, D3D10_DRIVER_TYPE_HARDWARE, nullptr, - D3D10_CREATE_DEVICE_BGRA_SUPPORT | - D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS, - D3D10_FEATURE_LEVEL_9_3, - D3D10_1_SDK_VERSION, &device))) { - adapter1->Release(); - factory1->Release(); - FreeLibrary(d3d10module); - FreeLibrary(dxgiModule); - return false; - } - } - } - device->Release(); - adapter1->Release(); - factory1->Release(); - FreeLibrary(d3d10module); - FreeLibrary(dxgiModule); - return true; -} diff --git a/widget/windows/winrt/MetroInput.cpp b/widget/windows/winrt/MetroInput.cpp deleted file mode 100644 index 0212eb06f4d..00000000000 --- a/widget/windows/winrt/MetroInput.cpp +++ /dev/null @@ -1,1573 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -// Moz headers (alphabetical) -#include "MetroInput.h" -#include "MetroUtils.h" // Logging, POINT_CEIL_*, ActivateGenericInstance, etc -#include "MetroWidget.h" // MetroInput::mWidget -#include "mozilla/dom/Touch.h" // Touch -#include "nsTArray.h" // Touch lists -#include "nsIDOMSimpleGestureEvent.h" // Constants for gesture events -#include "InputData.h" -#include "UIABridgePrivate.h" -#include "MetroAppShell.h" -#include "mozilla/EventStateManager.h" -#include "mozilla/EventStates.h" -#include "mozilla/MouseEvents.h" -#include "mozilla/TouchEvents.h" -#include "mozilla/Preferences.h" // for Preferences -#include "WinUtils.h" -#include "nsIPresShell.h" -#include "nsPoint.h" - -// System headers (alphabetical) -#include // ABI::Window::UI::Core namespace -#include // ABI::Window::UI::Input namespace - -//#define DEBUG_INPUT - -// Using declarations -using namespace ABI::Windows; // UI, System, Foundation namespaces -using namespace Microsoft; // WRL namespace (ComPtr, possibly others) -using namespace mozilla; -using namespace mozilla::widget; -using namespace mozilla::widget::winrt; -using namespace mozilla::dom; - -// File-scoped statics (unnamed namespace) -namespace { - // XXX: Set these min values appropriately - const double SWIPE_MIN_DISTANCE = 5.0; - const double SWIPE_MIN_VELOCITY = 5.0; - - // Convenience typedefs for event handler types - typedef Foundation::__FITypedEventHandler_2_Windows__CUI__CInput__CEdgeGesture_Windows__CUI__CInput__CEdgeGestureEventArgs_t EdgeGestureHandler; - typedef Foundation::__FITypedEventHandler_2_Windows__CUI__CCore__CCoreDispatcher_Windows__CUI__CCore__CAcceleratorKeyEventArgs_t AcceleratorKeyActivatedHandler; - typedef Foundation::__FITypedEventHandler_2_Windows__CUI__CCore__CCoreWindow_Windows__CUI__CCore__CPointerEventArgs_t PointerEventHandler; - typedef Foundation::__FITypedEventHandler_2_Windows__CUI__CInput__CGestureRecognizer_Windows__CUI__CInput__CTappedEventArgs_t TappedEventHandler; - typedef Foundation::__FITypedEventHandler_2_Windows__CUI__CInput__CGestureRecognizer_Windows__CUI__CInput__CRightTappedEventArgs_t RightTappedEventHandler; - typedef Foundation::__FITypedEventHandler_2_Windows__CUI__CInput__CGestureRecognizer_Windows__CUI__CInput__CManipulationStartedEventArgs_t ManipulationStartedEventHandler; - typedef Foundation::__FITypedEventHandler_2_Windows__CUI__CInput__CGestureRecognizer_Windows__CUI__CInput__CManipulationUpdatedEventArgs_t ManipulationUpdatedEventHandler; - typedef Foundation::__FITypedEventHandler_2_Windows__CUI__CInput__CGestureRecognizer_Windows__CUI__CInput__CManipulationCompletedEventArgs_t ManipulationCompletedEventHandler; - - // Other convenience typedefs - typedef ABI::Windows::UI::Core::ICoreAcceleratorKeys ICoreAcceleratorKeys; - - /** - * Specifies whether touch-action property is in force. - */ - static bool gTouchActionPropertyEnabled = false; - - /** - * Creates and returns a new {@link Touch} from the given - * ABI::Windows::UI::Input::IPointerPoint. Note that the caller is - * responsible for freeing the memory for the Touch returned from - * this function. - * - * @param aPoint the ABI::Windows::UI::Input::IPointerPoint containing the - * metadata from which to create our new {@link Touch} - * @return a new {@link Touch} representing the touch point. The caller - * is responsible for freeing the memory for this touch point. - */ - Touch* - CreateDOMTouch(UI::Input::IPointerPoint* aPoint) { - WRL::ComPtr props; - Foundation::Point position; - uint32_t pointerId; - Foundation::Rect contactRect; - float pressure; - float tiltX; - float tiltY; - - aPoint->get_Properties(props.GetAddressOf()); - aPoint->get_Position(&position); - aPoint->get_PointerId(&pointerId); - props->get_ContactRect(&contactRect); - props->get_Pressure(&pressure); - props->get_XTilt(&tiltX); - props->get_YTilt(&tiltY); - - nsIntPoint touchPoint = MetroUtils::LogToPhys(position); - nsIntPoint touchRadius; - touchRadius.x = WinUtils::LogToPhys(contactRect.Width) / 2; - touchRadius.y = WinUtils::LogToPhys(contactRect.Height) / 2; - Touch* touch = - new Touch(pointerId, - touchPoint, - // Rotation radius and angle. - // W3C touch events v1 do not use these. - // The draft for W3C touch events v2 explains that - // radius and angle should describe the ellipse that - // most closely circumscribes the touching area. Since - // Windows gives us a bounding rectangle rather than an - // ellipse, we provide the ellipse that is most closely - // circumscribed by the bounding rectangle that Windows - // gave us. - touchRadius, - 0.0f, - // Pressure - // W3C touch events v1 do not use this. - // The current draft for W3C touch events v2 says that - // this should be a value between 0.0 and 1.0, which is - // consistent with what Windows provides us here. - // XXX: Windows defaults to 0.5, but the current W3C - // draft says that the value should be 0.0 if no value - // known. - pressure); - touch->tiltX = tiltX; - touch->tiltY = tiltY; - return touch; - } - - /** - * Test if a touchpoint position has moved. See Touch.Equals for - * criteria. - * - * @param aTouch previous touch point - * @param aPoint new winrt touch point - * @return true if the point has moved - */ - bool - HasPointMoved(Touch* aTouch, UI::Input::IPointerPoint* aPoint) { - WRL::ComPtr props; - Foundation::Point position; - Foundation::Rect contactRect; - float pressure; - - aPoint->get_Properties(props.GetAddressOf()); - aPoint->get_Position(&position); - props->get_ContactRect(&contactRect); - props->get_Pressure(&pressure); - nsIntPoint touchPoint = MetroUtils::LogToPhys(position); - nsIntPoint touchRadius; - touchRadius.x = WinUtils::LogToPhys(contactRect.Width) / 2; - touchRadius.y = WinUtils::LogToPhys(contactRect.Height) / 2; - - // from Touch.Equals - return touchPoint != aTouch->mRefPoint || - pressure != aTouch->Force() || - /* mRotationAngle == aTouch->RotationAngle() || */ - touchRadius.x != aTouch->RadiusX() || - touchRadius.y != aTouch->RadiusY(); - } - - /** - * Converts from the Devices::Input::PointerDeviceType enumeration - * to a nsIDOMMouseEvent::MOZ_SOURCE_* value. - * - * @param aDeviceType the value to convert - * @param aMozInputSource the converted value - */ - void - MozInputSourceFromDeviceType( - Devices::Input::PointerDeviceType const& aDeviceType, - unsigned short& aMozInputSource) { - if (Devices::Input::PointerDeviceType::PointerDeviceType_Mouse - == aDeviceType) { - aMozInputSource = nsIDOMMouseEvent::MOZ_SOURCE_MOUSE; - } else if (Devices::Input::PointerDeviceType::PointerDeviceType_Touch - == aDeviceType) { - aMozInputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH; - } else if (Devices::Input::PointerDeviceType::PointerDeviceType_Pen - == aDeviceType) { - aMozInputSource = nsIDOMMouseEvent::MOZ_SOURCE_PEN; - } - } - - int16_t - ButtonsForPointerPoint(UI::Input::IPointerPoint* aPoint) { - WRL::ComPtr props; - aPoint->get_Properties(props.GetAddressOf()); - - int16_t buttons = 0; - boolean buttonPressed; - - props->get_IsLeftButtonPressed(&buttonPressed); - if (buttonPressed) { - buttons |= WidgetMouseEvent::eLeftButtonFlag; - } - props->get_IsMiddleButtonPressed(&buttonPressed); - if (buttonPressed) { - buttons |= WidgetMouseEvent::eMiddleButtonFlag; - } - props->get_IsRightButtonPressed(&buttonPressed); - if (buttonPressed) { - buttons |= WidgetMouseEvent::eRightButtonFlag; - } - props->get_IsXButton1Pressed(&buttonPressed); - if (buttonPressed) { - buttons |= WidgetMouseEvent::e4thButtonFlag; - } - props->get_IsXButton2Pressed(&buttonPressed); - if (buttonPressed) { - buttons |= WidgetMouseEvent::e5thButtonFlag; - } - return buttons; - } - - /** - * This function is for use with mTouches.Enumerate. It will - * append each element it encounters to the {@link nsTArray} - * of {@link mozilla::dom::Touch}es passed in through the third (void*) - * parameter. - * - * NOTE: This function will set the `mChanged` member of each - * element it encounters to `false`, since this function is only - * used to populate a touchlist that is about to be dispatched - * in a gecko touch event. - * - * @param aKey the key of the current element being enumerated - * @param aData the value of the current element being enumerated - * @param aTouchList the {@link WidgetTouchEvent::TouchArray} to append to - */ - PLDHashOperator - AppendToTouchList(const unsigned int& aKey, - nsRefPtr& aData, - void *aTouchList) - { - WidgetTouchEvent::TouchArray* touches = - static_cast(aTouchList); - nsRefPtr copy = new Touch(aData->mIdentifier, - aData->mRefPoint, - aData->mRadius, - aData->mRotationAngle, - aData->mForce); - copy->tiltX = aData->tiltX; - copy->tiltY = aData->tiltY; - touches->AppendElement(copy); - aData->mChanged = false; - return PL_DHASH_NEXT; - } - - // Helper for making sure event ptrs get freed. - class AutoDeleteEvent - { - public: - AutoDeleteEvent(WidgetGUIEvent* aPtr) : - mPtr(aPtr) {} - ~AutoDeleteEvent() { - if (mPtr) { - delete mPtr; - } - } - WidgetGUIEvent* mPtr; - }; -} - -namespace mozilla { -namespace widget { -namespace winrt { - -MetroInput::InputPrecisionLevel MetroInput::sCurrentInputLevel = - MetroInput::InputPrecisionLevel::LEVEL_IMPRECISE; - -MetroInput::MetroInput(MetroWidget* aWidget, - UI::Core::ICoreWindow* aWindow) - : mWidget(aWidget), - mNonApzTargetForTouch(false), - mWindow(aWindow), - mInputBlockId(0) -{ - LogFunction(); - NS_ASSERTION(aWidget, "Attempted to create MetroInput for null widget!"); - NS_ASSERTION(aWindow, "Attempted to create MetroInput for null window!"); - - mWidget->SetApzPendingResponseFlusher(this); - - Preferences::AddBoolVarCache(&gTouchActionPropertyEnabled, "layout.css.touch_action.enabled", gTouchActionPropertyEnabled); - mTokenPointerPressed.value = 0; - mTokenPointerReleased.value = 0; - mTokenPointerMoved.value = 0; - mTokenPointerEntered.value = 0; - mTokenPointerExited.value = 0; - mTokenEdgeStarted.value = 0; - mTokenEdgeCanceled.value = 0; - mTokenEdgeCompleted.value = 0; - mTokenManipulationCompleted.value = 0; - mTokenTapped.value = 0; - mTokenRightTapped.value = 0; - - // Create our Gesture Recognizer - ActivateGenericInstance(RuntimeClass_Windows_UI_Input_GestureRecognizer, - mGestureRecognizer); - NS_ASSERTION(mGestureRecognizer, "Failed to create GestureRecognizer!"); - - RegisterInputEvents(); -} - -MetroInput::~MetroInput() -{ - LogFunction(); - UnregisterInputEvents(); -} - -/* static */ -bool MetroInput::IsInputModeImprecise() -{ - return sCurrentInputLevel == LEVEL_IMPRECISE; -} - -/** - * Tracks the current input level (precise/imprecise) and fires an observer - * when the mode changes. - */ -void -MetroInput::UpdateInputLevel(InputPrecisionLevel aInputLevel) -{ - // ignore mouse input if we have active touch input. - if (aInputLevel == LEVEL_PRECISE && mTouches.Count() > 0) { - return; - } - if (sCurrentInputLevel != aInputLevel) { - sCurrentInputLevel = aInputLevel; - MetroUtils::FireObserver(sCurrentInputLevel == LEVEL_PRECISE ? - "metro_precise_input" : "metro_imprecise_input"); - } -} - -/** - * Processes an IEdgeGestureEventArgs and returns the input source type - * for the event. Also updates input level via UpdateInputLevel. - */ -uint16_t -MetroInput::ProcessInputTypeForGesture(UI::Input::IEdgeGestureEventArgs* aArgs) -{ - MOZ_ASSERT(aArgs); - UI::Input::EdgeGestureKind kind; - aArgs->get_Kind(&kind); - switch(kind) { - case UI::Input::EdgeGestureKind::EdgeGestureKind_Touch: - UpdateInputLevel(LEVEL_IMPRECISE); - return nsIDOMMouseEvent::MOZ_SOURCE_TOUCH; - break; - case UI::Input::EdgeGestureKind::EdgeGestureKind_Keyboard: - return nsIDOMMouseEvent::MOZ_SOURCE_KEYBOARD; - break; - case UI::Input::EdgeGestureKind::EdgeGestureKind_Mouse: - UpdateInputLevel(LEVEL_PRECISE); - return nsIDOMMouseEvent::MOZ_SOURCE_MOUSE; - break; - } - return nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN; -} - -/** - * When the user swipes her/his finger in from the top of the screen, - * we receive this event. - * - * @param sender the CoreDispatcher that fired this event - * @param aArgs the event-specific args we use when processing this event - * @returns S_OK - */ -HRESULT -MetroInput::OnEdgeGestureStarted(UI::Input::IEdgeGesture* sender, - UI::Input::IEdgeGestureEventArgs* aArgs) -{ -#ifdef DEBUG_INPUT - LogFunction(); -#endif - WidgetSimpleGestureEvent geckoEvent(true, - NS_SIMPLE_GESTURE_EDGE_STARTED, - mWidget.Get()); - mModifierKeyState.Update(); - mModifierKeyState.InitInputEvent(geckoEvent); - geckoEvent.time = ::GetMessageTime(); - geckoEvent.inputSource = ProcessInputTypeForGesture(aArgs); - - // Safe - DispatchEventIgnoreStatus(&geckoEvent); - return S_OK; -} - -/** - * This event can be received if the user swipes her/his finger back to - * the top of the screen, or continues moving her/his finger such that - * the movement is interpreted as a "grab this window" gesture - * - * @param sender the CoreDispatcher that fired this event - * @param aArgs the event-specific args we use when processing this event - * @returns S_OK - */ -HRESULT -MetroInput::OnEdgeGestureCanceled(UI::Input::IEdgeGesture* sender, - UI::Input::IEdgeGestureEventArgs* aArgs) -{ -#ifdef DEBUG_INPUT - LogFunction(); -#endif - WidgetSimpleGestureEvent geckoEvent(true, - NS_SIMPLE_GESTURE_EDGE_CANCELED, - mWidget.Get()); - mModifierKeyState.Update(); - mModifierKeyState.InitInputEvent(geckoEvent); - geckoEvent.time = ::GetMessageTime(); - geckoEvent.inputSource = ProcessInputTypeForGesture(aArgs); - - // Safe - DispatchEventIgnoreStatus(&geckoEvent); - return S_OK; -} - -/** - * This event is received if the user presses ctrl+Z or lifts her/his - * finger after causing an EdgeGestureStarting event to fire. - * - * @param sender the CoreDispatcher that fired this event - * @param aArgs the event-specific args we use when processing this event - * @returns S_OK - */ -HRESULT -MetroInput::OnEdgeGestureCompleted(UI::Input::IEdgeGesture* sender, - UI::Input::IEdgeGestureEventArgs* aArgs) -{ -#ifdef DEBUG_INPUT - LogFunction(); -#endif - WidgetSimpleGestureEvent geckoEvent(true, - NS_SIMPLE_GESTURE_EDGE_COMPLETED, - mWidget.Get()); - mModifierKeyState.Update(); - mModifierKeyState.InitInputEvent(geckoEvent); - geckoEvent.time = ::GetMessageTime(); - geckoEvent.inputSource = ProcessInputTypeForGesture(aArgs); - - // Safe - DispatchEventIgnoreStatus(&geckoEvent); - return S_OK; -} - -/** - * This helper function is used by our processing of PointerPressed, - * PointerReleased, and PointerMoved events. - * It dispatches a gecko event in response to the input received. This - * function should only be called for non-touch (i.e. pen or mouse) input - * events. - * - * @param aPoint the PointerPoint for the input event - */ -void -MetroInput::OnPointerNonTouch(UI::Input::IPointerPoint* aPoint) { - WRL::ComPtr props; - UI::Input::PointerUpdateKind pointerUpdateKind; - - aPoint->get_Properties(props.GetAddressOf()); - props->get_PointerUpdateKind(&pointerUpdateKind); - - uint32_t message = NS_MOUSE_MOVE; - int16_t button = 0; - - switch (pointerUpdateKind) { - case UI::Input::PointerUpdateKind::PointerUpdateKind_LeftButtonPressed: - button = WidgetMouseEvent::buttonType::eLeftButton; - message = NS_MOUSE_BUTTON_DOWN; - break; - case UI::Input::PointerUpdateKind::PointerUpdateKind_MiddleButtonPressed: - button = WidgetMouseEvent::buttonType::eMiddleButton; - message = NS_MOUSE_BUTTON_DOWN; - break; - case UI::Input::PointerUpdateKind::PointerUpdateKind_RightButtonPressed: - button = WidgetMouseEvent::buttonType::eRightButton; - message = NS_MOUSE_BUTTON_DOWN; - break; - case UI::Input::PointerUpdateKind::PointerUpdateKind_LeftButtonReleased: - button = WidgetMouseEvent::buttonType::eLeftButton; - message = NS_MOUSE_BUTTON_UP; - break; - case UI::Input::PointerUpdateKind::PointerUpdateKind_MiddleButtonReleased: - button = WidgetMouseEvent::buttonType::eMiddleButton; - message = NS_MOUSE_BUTTON_UP; - break; - case UI::Input::PointerUpdateKind::PointerUpdateKind_RightButtonReleased: - button = WidgetMouseEvent::buttonType::eRightButton; - message = NS_MOUSE_BUTTON_UP; - break; - } - - UpdateInputLevel(LEVEL_PRECISE); - - WidgetMouseEvent* event = - new WidgetMouseEvent(true, message, mWidget.Get(), - WidgetMouseEvent::eReal, - WidgetMouseEvent::eNormal); - event->button = button; - aPoint->get_PointerId(&event->pointerId); - InitGeckoMouseEventFromPointerPoint(event, aPoint); - DispatchAsyncEventIgnoreStatus(event); -} - -void -MetroInput::InitTouchEventTouchList(WidgetTouchEvent* aEvent) -{ - MOZ_ASSERT(aEvent); - mTouches.Enumerate(&AppendToTouchList, - static_cast(&aEvent->touches)); -} - -bool -MetroInput::ShouldDeliverInputToRecognizer() -{ - return mRecognizerWantsEvents; -} - -void -MetroInput::GetAllowedTouchBehavior(WidgetTouchEvent* aTransformedEvent, nsTArray& aOutBehaviors) -{ - for (uint32_t i = 0; i < aTransformedEvent->touches.Length(); i++) { - // performing hit testing fallback: asking content to perform hit testing itself - // (in spite that this operation has high latency). - aOutBehaviors.AppendElement(mWidget->ContentGetAllowedTouchBehavior(aTransformedEvent->touches[i]->mRefPoint)); - } -} - -// This event is raised when the user pushes the left mouse button, presses a -// pen to the surface, or presses a touch screen. -HRESULT -MetroInput::OnPointerPressed(UI::Core::ICoreWindow* aSender, - UI::Core::IPointerEventArgs* aArgs) -{ -#ifdef DEBUG_INPUT - LogFunction(); -#endif - - WRL::ComPtr currentPoint; - WRL::ComPtr device; - Devices::Input::PointerDeviceType deviceType; - - aArgs->get_CurrentPoint(currentPoint.GetAddressOf()); - currentPoint->get_PointerDevice(device.GetAddressOf()); - device->get_PointerDeviceType(&deviceType); - - // For mouse and pen input, simply call our helper function - if (deviceType != - Devices::Input::PointerDeviceType::PointerDeviceType_Touch) { - OnPointerNonTouch(currentPoint.Get()); - mGestureRecognizer->ProcessDownEvent(currentPoint.Get()); - return S_OK; - } - - // This is touch input. - UpdateInputLevel(LEVEL_IMPRECISE); - - // Create the new touch point and add it to our event. - uint32_t pointerId; - currentPoint->get_PointerId(&pointerId); - nsRefPtr touch = CreateDOMTouch(currentPoint.Get()); - touch->mChanged = true; - mTouches.Put(pointerId, touch); - - WidgetTouchEvent* touchEvent = - new WidgetTouchEvent(true, NS_TOUCH_START, mWidget.Get()); - - if (mTouches.Count() == 1) { - // If this is the first touchstart of a touch session reset some - // tracking flags. - mRecognizerWantsEvents = true; - } - - InitTouchEventTouchList(touchEvent); - DispatchAsyncTouchEvent(touchEvent); - - if (ShouldDeliverInputToRecognizer()) { - mGestureRecognizer->ProcessDownEvent(currentPoint.Get()); - } - return S_OK; -} - -void -MetroInput::AddPointerMoveDataToRecognizer(UI::Core::IPointerEventArgs* aArgs) -{ - if (ShouldDeliverInputToRecognizer()) { - WRL::ComPtr> - pointerPoints; - aArgs->GetIntermediatePoints(pointerPoints.GetAddressOf()); - mGestureRecognizer->ProcessMoveEvents(pointerPoints.Get()); - } -} - -// This event is raised when the user moves the mouse, moves a pen that is -// in contact with the surface, or moves a finger that is in contact with -// a touch screen. -HRESULT -MetroInput::OnPointerMoved(UI::Core::ICoreWindow* aSender, - UI::Core::IPointerEventArgs* aArgs) -{ -#ifdef DEBUG_INPUT - LogFunction(); -#endif - - WRL::ComPtr currentPoint; - WRL::ComPtr device; - Devices::Input::PointerDeviceType deviceType; - - aArgs->get_CurrentPoint(currentPoint.GetAddressOf()); - currentPoint->get_PointerDevice(device.GetAddressOf()); - device->get_PointerDeviceType(&deviceType); - - // For mouse and pen input, simply call our helper function - if (deviceType != - Devices::Input::PointerDeviceType::PointerDeviceType_Touch) { - OnPointerNonTouch(currentPoint.Get()); - AddPointerMoveDataToRecognizer(aArgs); - return S_OK; - } - - // This is touch input. - UpdateInputLevel(LEVEL_IMPRECISE); - - // Get the touch associated with this touch point. - uint32_t pointerId; - currentPoint->get_PointerId(&pointerId); - nsRefPtr touch = mTouches.Get(pointerId); - - // Some old drivers cause us to receive a PointerMoved event for a touchId - // after we've already received a PointerReleased event for that touchId. - // To work around those busted drivers, we simply ignore TouchMoved events - // for touchIds that we are not currently tracking. See bug 819223. - if (!touch) { - return S_OK; - } - - AddPointerMoveDataToRecognizer(aArgs); - - // If the point hasn't moved, filter it out per the spec. Pres shell does - // this as well, but we need to know when our first touchmove is going to - // get delivered so we can check the result. - if (!HasPointMoved(touch, currentPoint.Get())) { - return S_OK; - } - - touch = CreateDOMTouch(currentPoint.Get()); - touch->mChanged = true; - // replacing old touch point in mTouches map - mTouches.Put(pointerId, touch); - - WidgetTouchEvent* touchEvent = - new WidgetTouchEvent(true, NS_TOUCH_MOVE, mWidget.Get()); - InitTouchEventTouchList(touchEvent); - DispatchAsyncTouchEvent(touchEvent); - - return S_OK; -} - -// This event is raised when the user lifts the left mouse button, lifts a -// pen from the surface, or lifts her/his finger from a touch screen. -HRESULT -MetroInput::OnPointerReleased(UI::Core::ICoreWindow* aSender, - UI::Core::IPointerEventArgs* aArgs) -{ -#ifdef DEBUG_INPUT - LogFunction(); -#endif - - WRL::ComPtr currentPoint; - WRL::ComPtr device; - Devices::Input::PointerDeviceType deviceType; - - aArgs->get_CurrentPoint(currentPoint.GetAddressOf()); - currentPoint->get_PointerDevice(device.GetAddressOf()); - device->get_PointerDeviceType(&deviceType); - - // For mouse and pen input, simply call our helper function - if (deviceType != - Devices::Input::PointerDeviceType::PointerDeviceType_Touch) { - OnPointerNonTouch(currentPoint.Get()); - mGestureRecognizer->ProcessUpEvent(currentPoint.Get()); - return S_OK; - } - - // This is touch input. - UpdateInputLevel(LEVEL_IMPRECISE); - - // Get the touch associated with this touch point. - uint32_t pointerId; - currentPoint->get_PointerId(&pointerId); - nsRefPtr touch = mTouches.Get(pointerId); - - // Purge any pending moves for this pointer - if (touch->mChanged) { - WidgetTouchEvent* touchEvent = - new WidgetTouchEvent(true, NS_TOUCH_MOVE, mWidget.Get()); - InitTouchEventTouchList(touchEvent); - DispatchAsyncTouchEvent(touchEvent); - } - - // Remove this touch point from our map. Eventually all touch points are - // removed for this session since we receive released events for every - // point. - mTouches.Remove(pointerId); - - // touchend events only have a single touch; the touch that has been removed - WidgetTouchEvent* touchEvent = - new WidgetTouchEvent(true, NS_TOUCH_END, mWidget.Get()); - touchEvent->touches.AppendElement(CreateDOMTouch(currentPoint.Get())); - DispatchAsyncTouchEvent(touchEvent); - - if (ShouldDeliverInputToRecognizer()) { - mGestureRecognizer->ProcessUpEvent(currentPoint.Get()); - } - - return S_OK; -} - -// Tests for chrome vs. content target so we know whether input coordinates need -// to be transformed through the apz. Eventually this hit testing should move -// into the apz (bug 918288). -bool -MetroInput::HitTestChrome(const LayoutDeviceIntPoint& pt) -{ - // Confirm this event targets content. We pick this up in browser's input.js. - WidgetMouseEvent hittest(true, NS_MOUSE_MOZHITTEST, mWidget.Get(), - WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal); - hittest.refPoint = pt; - nsEventStatus status; - mWidget->DispatchEvent(&hittest, status); - return (status == nsEventStatus_eConsumeNoDefault); -} - -/** - * Returns true if the position is in chrome, false otherwise. - */ -bool -MetroInput::TransformRefPoint(const Foundation::Point& aPosition, LayoutDeviceIntPoint& aRefPointOut) -{ - // If this event is destined for content we need to transform our ref point through - // the apz so that zoom can be accounted for. - aRefPointOut = LayoutDeviceIntPoint::FromUntyped(MetroUtils::LogToPhys(aPosition)); - ScreenIntPoint spt(aRefPointOut.x, aRefPointOut.y); - // This is currently a general contained rect hit test, it may produce a false positive for - // overlay chrome elements. - bool apzIntersect = mWidget->ApzHitTest(spt); - if (!apzIntersect) { - return true; - } - if (HitTestChrome(aRefPointOut)) { - return true; - } - mWidget->ApzTransformGeckoCoordinate(spt, &aRefPointOut); - return false; -} - -void -MetroInput::TransformTouchEvent(WidgetTouchEvent* aEvent) -{ - WidgetTouchEvent::TouchArray& touches = aEvent->touches; - for (uint32_t i = 0; i < touches.Length(); ++i) { - dom::Touch* touch = touches[i]; - if (touch) { - LayoutDeviceIntPoint lpt; - ScreenIntPoint spt; - spt.x = touch->mRefPoint.x; - spt.y = touch->mRefPoint.y; - mWidget->ApzTransformGeckoCoordinate(spt, &lpt); - touch->mRefPoint.x = lpt.x; - touch->mRefPoint.y = lpt.y; - } - } -} - -void -MetroInput::InitGeckoMouseEventFromPointerPoint( - WidgetMouseEvent* aEvent, - UI::Input::IPointerPoint* aPointerPoint) -{ - NS_ASSERTION(aPointerPoint, "InitGeckoMouseEventFromPointerPoint " - "called with null PointerPoint!"); - - WRL::ComPtr props; - WRL::ComPtr device; - Devices::Input::PointerDeviceType deviceType; - Foundation::Point position; - uint64_t timestamp; - float pressure; - boolean canBeDoubleTap; - float tiltX; - float tiltY; - - aPointerPoint->get_Position(&position); - aPointerPoint->get_Timestamp(×tamp); - aPointerPoint->get_PointerDevice(device.GetAddressOf()); - device->get_PointerDeviceType(&deviceType); - aPointerPoint->get_Properties(props.GetAddressOf()); - aPointerPoint->get_PointerId(&aEvent->pointerId); - props->get_Pressure(&pressure); - props->get_XTilt(&tiltX); - props->get_YTilt(&tiltY); - - mGestureRecognizer->CanBeDoubleTap(aPointerPoint, &canBeDoubleTap); - - TransformRefPoint(position, aEvent->refPoint); - - if (!canBeDoubleTap) { - aEvent->clickCount = 1; - } else { - aEvent->clickCount = 2; - } - aEvent->pressure = pressure; - aEvent->tiltX = tiltX; - aEvent->tiltY = tiltY; - aEvent->buttons = ButtonsForPointerPoint(aPointerPoint); - - MozInputSourceFromDeviceType(deviceType, aEvent->inputSource); -} - -// This event is raised when a precise pointer moves into the bounding box of -// our window. For touch input, this will be raised before the PointerPressed -// event. -HRESULT -MetroInput::OnPointerEntered(UI::Core::ICoreWindow* aSender, - UI::Core::IPointerEventArgs* aArgs) -{ -#ifdef DEBUG_INPUT - LogFunction(); -#endif - - WRL::ComPtr currentPoint; - WRL::ComPtr device; - Devices::Input::PointerDeviceType deviceType; - - aArgs->get_CurrentPoint(currentPoint.GetAddressOf()); - currentPoint->get_PointerDevice(device.GetAddressOf()); - device->get_PointerDeviceType(&deviceType); - - // We only dispatch mouseenter and mouseexit events for mouse and pen input. - if (deviceType != - Devices::Input::PointerDeviceType::PointerDeviceType_Touch) { - WidgetMouseEvent* event = - new WidgetMouseEvent(true, NS_MOUSE_ENTER, mWidget.Get(), - WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal); - UpdateInputLevel(LEVEL_PRECISE); - InitGeckoMouseEventFromPointerPoint(event, currentPoint.Get()); - DispatchAsyncEventIgnoreStatus(event); - return S_OK; - } - UpdateInputLevel(LEVEL_IMPRECISE); - return S_OK; -} - -// This event is raised when a precise pointer leaves the bounding box of -// our window. For touch input, this will be raised before the -// PointerReleased event. -HRESULT -MetroInput::OnPointerExited(UI::Core::ICoreWindow* aSender, - UI::Core::IPointerEventArgs* aArgs) -{ -#ifdef DEBUG_INPUT - LogFunction(); -#endif - - WRL::ComPtr currentPoint; - WRL::ComPtr device; - Devices::Input::PointerDeviceType deviceType; - - aArgs->get_CurrentPoint(currentPoint.GetAddressOf()); - currentPoint->get_PointerDevice(device.GetAddressOf()); - device->get_PointerDeviceType(&deviceType); - - // We only dispatch mouseenter and mouseexit events for mouse and pen input. - if (deviceType != - Devices::Input::PointerDeviceType::PointerDeviceType_Touch) { - WidgetMouseEvent* event = - new WidgetMouseEvent(true, NS_MOUSE_EXIT, mWidget.Get(), - WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal); - event->exit = WidgetMouseEvent::eTopLevel; - UpdateInputLevel(LEVEL_PRECISE); - InitGeckoMouseEventFromPointerPoint(event, currentPoint.Get()); - DispatchAsyncEventIgnoreStatus(event); - return S_OK; - } - UpdateInputLevel(LEVEL_IMPRECISE); - return S_OK; -} - -// Gecko expects a "finished" event to be sent that has the cumulative -// changes since the gesture began. The idea is that consumers could hook -// only this last event and still effectively support magnification and -// rotation. We accomplish sending this "finished" event by calling our -// helper function with a cumulative "delta" value. -// -// After sending the "finished" event, this function detects and sends -// swipe gestures. -HRESULT -MetroInput::OnManipulationCompleted( - UI::Input::IGestureRecognizer* aSender, - UI::Input::IManipulationCompletedEventArgs* aArgs) -{ -#ifdef DEBUG_INPUT - LogFunction(); -#endif - - Devices::Input::PointerDeviceType deviceType; - aArgs->get_PointerDeviceType(&deviceType); - if (deviceType == - Devices::Input::PointerDeviceType::PointerDeviceType_Mouse) { - return S_OK; - } - - UI::Input::ManipulationDelta delta; - Foundation::Point position; - - aArgs->get_Position(&position); - aArgs->get_Cumulative(&delta); - - // We check that the distance the user's finger traveled and the - // velocity with which it traveled exceed our thresholds for - // classifying the movement as a swipe. - UI::Input::ManipulationVelocities velocities; - aArgs->get_Velocities(&velocities); - - bool isHorizontalSwipe = - abs(velocities.Linear.X) >= SWIPE_MIN_VELOCITY - && abs(delta.Translation.X) >= SWIPE_MIN_DISTANCE; - bool isVerticalSwipe = - abs(velocities.Linear.Y) >= SWIPE_MIN_VELOCITY - && abs(delta.Translation.Y) >= SWIPE_MIN_DISTANCE; - - // If our thresholds were exceeded for both a vertical and a horizontal - // swipe, it means the user is flinging her/his finger around and we - // should just ignore the input. - if (isHorizontalSwipe && isVerticalSwipe) { - return S_OK; - } - - if (isHorizontalSwipe) { - WidgetSimpleGestureEvent* swipeEvent = - new WidgetSimpleGestureEvent(true, NS_SIMPLE_GESTURE_SWIPE, - mWidget.Get()); - swipeEvent->direction = delta.Translation.X > 0 - ? nsIDOMSimpleGestureEvent::DIRECTION_RIGHT - : nsIDOMSimpleGestureEvent::DIRECTION_LEFT; - swipeEvent->delta = delta.Translation.X; - swipeEvent->inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH; - swipeEvent->refPoint = LayoutDeviceIntPoint::FromUntyped(MetroUtils::LogToPhys(position)); - DispatchAsyncEventIgnoreStatus(swipeEvent); - } - - if (isVerticalSwipe) { - WidgetSimpleGestureEvent* swipeEvent = - new WidgetSimpleGestureEvent(true, NS_SIMPLE_GESTURE_SWIPE, - mWidget.Get()); - swipeEvent->direction = delta.Translation.Y > 0 - ? nsIDOMSimpleGestureEvent::DIRECTION_DOWN - : nsIDOMSimpleGestureEvent::DIRECTION_UP; - swipeEvent->delta = delta.Translation.Y; - swipeEvent->inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH; - swipeEvent->refPoint = LayoutDeviceIntPoint::FromUntyped(MetroUtils::LogToPhys(position)); - DispatchAsyncEventIgnoreStatus(swipeEvent); - } - - return S_OK; -} - -// This event is raised when a sequence of pointer events has been -// interpreted by the GestureRecognizer as a tap (this could be a mouse -// click, a pen tap, or a tap on a touch surface). -HRESULT -MetroInput::OnTapped(UI::Input::IGestureRecognizer* aSender, - UI::Input::ITappedEventArgs* aArgs) -{ -#ifdef DEBUG_INPUT - LogFunction(); -#endif - - Devices::Input::PointerDeviceType deviceType; - aArgs->get_PointerDeviceType(&deviceType); - - unsigned int tapCount; - aArgs->get_TapCount(&tapCount); - - // For mouse and pen input, we send mousedown/mouseup/mousemove - // events as soon as we detect the input event. For touch input, a set of - // mousedown/mouseup events will be sent only once a tap has been detected. - if (deviceType != Devices::Input::PointerDeviceType::PointerDeviceType_Touch) { - return S_OK; - } - - Foundation::Point position; - aArgs->get_Position(&position); - HandleTap(position, tapCount); - return S_OK; -} - -// This event is raised when a sequence of pointer events has been -// interpreted by the GestureRecognizer as a right tap. -// This could be a mouse right-click, a right-click on a pen, or -// a tap-and-hold on a touch surface. -HRESULT -MetroInput::OnRightTapped(UI::Input::IGestureRecognizer* aSender, - UI::Input::IRightTappedEventArgs* aArgs) -{ -#ifdef DEBUG_INPUT - LogFunction(); -#endif - - Devices::Input::PointerDeviceType deviceType; - aArgs->get_PointerDeviceType(&deviceType); - - Foundation::Point position; - aArgs->get_Position(&position); - HandleLongTap(position); - - return S_OK; -} - -void -MetroInput::HandleTap(const Foundation::Point& aPoint, unsigned int aTapCount) -{ -#ifdef DEBUG_INPUT - LogFunction(); -#endif - - LayoutDeviceIntPoint refPoint; - TransformRefPoint(aPoint, refPoint); - - WidgetMouseEvent* mouseEvent = - new WidgetMouseEvent(true, NS_MOUSE_MOVE, mWidget.Get(), - WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal); - mouseEvent->refPoint = refPoint; - mouseEvent->clickCount = aTapCount; - mouseEvent->inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH; - DispatchAsyncEventIgnoreStatus(mouseEvent); - - mouseEvent = - new WidgetMouseEvent(true, NS_MOUSE_BUTTON_DOWN, mWidget.Get(), - WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal); - mouseEvent->refPoint = refPoint; - mouseEvent->clickCount = aTapCount; - mouseEvent->inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH; - mouseEvent->button = WidgetMouseEvent::buttonType::eLeftButton; - DispatchAsyncEventIgnoreStatus(mouseEvent); - - mouseEvent = - new WidgetMouseEvent(true, NS_MOUSE_BUTTON_UP, mWidget.Get(), - WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal); - mouseEvent->refPoint = refPoint; - mouseEvent->clickCount = aTapCount; - mouseEvent->inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH; - mouseEvent->button = WidgetMouseEvent::buttonType::eLeftButton; - DispatchAsyncEventIgnoreStatus(mouseEvent); - - // Make sure all gecko events are dispatched and the dom is up to date - // so that when ui automation comes in looking for focus info it gets - // the right information. - MetroAppShell::MarkEventQueueForPurge(); -} - -void -MetroInput::HandleLongTap(const Foundation::Point& aPoint) -{ -#ifdef DEBUG_INPUT - LogFunction(); -#endif - LayoutDeviceIntPoint refPoint; - TransformRefPoint(aPoint, refPoint); - - WidgetMouseEvent* contextEvent = - new WidgetMouseEvent(true, NS_CONTEXTMENU, mWidget.Get(), - WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal); - contextEvent->refPoint = refPoint; - contextEvent->inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH; - DispatchAsyncEventIgnoreStatus(contextEvent); -} - -/** - * Implementation Details - */ -nsEventStatus MetroInput::sThrowawayStatus; - -void -MetroInput::DispatchAsyncEventIgnoreStatus(WidgetInputEvent* aEvent) -{ - aEvent->time = ::GetMessageTime(); - mModifierKeyState.Update(); - mModifierKeyState.InitInputEvent(*aEvent); - mInputEventQueue.Push(aEvent); - nsCOMPtr runnable = - NS_NewRunnableMethod(this, &MetroInput::DeliverNextQueuedEventIgnoreStatus); - NS_DispatchToCurrentThread(runnable); -} - -void -MetroInput::DeliverNextQueuedEventIgnoreStatus() -{ - nsAutoPtr event = - static_cast(mInputEventQueue.PopFront()); - MOZ_ASSERT(event.get()); - DispatchEventIgnoreStatus(event.get()); - - // Let app shell know we've delivered that last input we wanted purged - // via a call to MarkEventQueueForPurge(). - if (event->message == NS_MOUSE_BUTTON_UP) { - MetroAppShell::InputEventsDispatched(); - } - - // Clear :hover/:active states for mouse events generated by HandleTap - WidgetMouseEvent* mouseEvent = event.get()->AsMouseEvent(); - if (!mouseEvent) { - return; - } - if (mouseEvent->message != NS_MOUSE_BUTTON_UP || - mouseEvent->inputSource != nsIDOMMouseEvent::MOZ_SOURCE_TOUCH) { - return; - } - nsCOMPtr presShell = mWidget->GetPresShell(); - if (presShell) { - EventStateManager* esm = presShell->GetPresContext()->EventStateManager(); - if (esm) { - esm->SetContentState(nullptr, NS_EVENT_STATE_HOVER); - } - } -} - -void -MetroInput::DispatchAsyncTouchEvent(WidgetTouchEvent* aEvent) -{ - aEvent->time = ::GetMessageTime(); - mModifierKeyState.Update(); - mModifierKeyState.InitInputEvent(*aEvent); - mInputEventQueue.Push(aEvent); - nsCOMPtr runnable = - NS_NewRunnableMethod(this, &MetroInput::DeliverNextQueuedTouchEvent); - NS_DispatchToCurrentThread(runnable); -} - -static void DumpTouchIds(const char* aTarget, WidgetTouchEvent* aEvent) -{ - // comment out for touch moves - if (aEvent->message == NS_TOUCH_MOVE) { - return; - } - switch(aEvent->message) { - case NS_TOUCH_START: - WinUtils::Log("DumpTouchIds: NS_TOUCH_START block"); - break; - case NS_TOUCH_MOVE: - WinUtils::Log("DumpTouchIds: NS_TOUCH_MOVE block"); - break; - case NS_TOUCH_END: - WinUtils::Log("DumpTouchIds: NS_TOUCH_END block"); - break; - case NS_TOUCH_CANCEL: - WinUtils::Log("DumpTouchIds: NS_TOUCH_CANCEL block"); - break; - } - WidgetTouchEvent::TouchArray& touches = aEvent->touches; - for (uint32_t i = 0; i < touches.Length(); ++i) { - dom::Touch* touch = touches[i]; - if (!touch) { - continue; - } - int32_t id = touch->Identifier(); - WinUtils::Log(" id=%d target=%s", id, aTarget); - } -} - -static void DumpTouchBehavior(nsTArray& aBehavior) -{ - WinUtils::Log("DumpTouchBehavior: Touch behavior flags set for current touch session:"); - for (uint32_t i = 0; i < aBehavior.Length(); i++) { - if (mozilla::layers::AllowedTouchBehavior::VERTICAL_PAN & aBehavior[i]) { - WinUtils::Log("VERTICAL_PAN"); - } - - if (mozilla::layers::AllowedTouchBehavior::HORIZONTAL_PAN & aBehavior[i]) { - WinUtils::Log("HORIZONTAL_PAN"); - } - - if (mozilla::layers::AllowedTouchBehavior::UNKNOWN & aBehavior[i]) { - WinUtils::Log("UNKNOWN"); - } - - if ((mozilla::layers::AllowedTouchBehavior::NONE & aBehavior[i]) == 0) { - WinUtils::Log("NONE"); - } - } -} - -/* - * nsPreShell's processing of WidgetTouchEvent events: - * - * NS_TOUCH_START: - * Interprets a single touch point as the first touch point of a block and will reset its - * queue when it receives this. For multiple touch points it sets all points in its queue - * and marks new points as changed. - * NS_TOUCH_MOVE: - * Uses the equality tests in dom::Touch to test if a touch point has changed (moved). - * If a point has moved, keeps this touch point in the event, otherwise it removes - * the touch point. Note if no points have changed, it exits without sending a dom event. - * NS_TOUCH_CANCEL/NS_TOUCH_END - * Assumes any point in touchEvent->touches has been removed or canceled. -*/ - -//#define DUMP_TOUCH_IDS(aTarget, aEvent) DumpTouchIds(aTarget, aEvent) -#define DUMP_TOUCH_IDS(...) - -//#define DUMP_ALLOWED_TOUCH_BEHAVIOR(aBehavior) DumpTouchBehavior(aBehavior) -#define DUMP_ALLOWED_TOUCH_BEHAVIOR(...) - -void -MetroInput::HandleTouchStartEvent(WidgetTouchEvent* aEvent) -{ - // This is the start of a new touch block. See what the APZ wants to do with it. - - WidgetTouchEvent transformedEvent(*aEvent); - DUMP_TOUCH_IDS("APZC(1)", aEvent); - nsEventStatus result = mWidget->ApzReceiveInputEvent(&transformedEvent, &mTargetAPZCGuid, &mInputBlockId); - if (result == nsEventStatus_eConsumeNoDefault) { - // The APZ said: throw this event away entirely. - CancelGesture(); - return; - } - - // If the APZ is using this block, send it touch-action behavior. - if (gTouchActionPropertyEnabled) { - nsTArray touchBehaviors; - // Retrieving touch behaviors from apzctm and from the content (if needed) - // then setting it back to the apzc. The apzc we retrieved touch behaviors - // from and we're setting to may changes if there are multiple touches (in that - // case apzctm needs to take common ancestor of them). - GetAllowedTouchBehavior(&transformedEvent, touchBehaviors); - // Setting the touch behaviors to the apzc that will be responsible - // for interpreting it. It may be not the same apzc we retrieved touch - // action values from. E.g. for zooming we're taking parent apzc of a few ones - // that were touched but touch behaviors would be taken from childs. - DUMP_ALLOWED_TOUCH_BEHAVIOR(touchBehaviors); - mWidget->ApzcSetAllowedTouchBehavior(mInputBlockId, touchBehaviors); - } - - // Pass the event on to content - DUMP_TOUCH_IDS("DOM(2)", aEvent); - nsEventStatus contentStatus = nsEventStatus_eIgnore; - mWidget->DispatchEvent(&transformedEvent, contentStatus); - if (nsEventStatus_eConsumeNoDefault == contentStatus) { - // Content consumed the event, so we need to notify the APZ - // to not do anything with this touch block. - mWidget->ApzContentConsumingTouch(mInputBlockId); - mCancelable = false; - - // Also cancel the gesture detection. - CancelGesture(); - } -} - -void -MetroInput::HandleFirstTouchMoveEvent(WidgetTouchEvent* aEvent) -{ - // If the APZ is using this block, pass the event to it. - WidgetTouchEvent transformedEvent(*aEvent); - DUMP_TOUCH_IDS("APZC(2)", aEvent); - nsEventStatus apzcStatus = mWidget->ApzReceiveInputEvent(&transformedEvent, &mTargetAPZCGuid, &mInputBlockId); - if (apzcStatus == nsEventStatus_eConsumeNoDefault) { - // The APZ said: throw this event away entirely. - CancelGesture(); - return; - } - - // ==== RANDOM INTERLUDE ABOut POINTER EVENTS ==== - // We need to dispatch here only touch event, not pointer one. - // That's because according to the spec pointer events doesn't imply pointermove event - // between pointerdown and pointercancel (If default touch behavior is triggered). - // But at the same time we need to dispatch at least touchmove event to let content to - // consume it (or not consume). - // TODO: determine how to dispatch only one kind of events: currently there are two options: - // 1) Create two separate instances of the WidgetTouchEvent and WidgetPointerEvent and - // dispatch them separately. - // 2) Add a boolean flag to the WidgetTouchEvent that states whether this event should produce - // both touch and pointer event or only touch one. - // Anyway it's worth to add this stuff only after patches from bug 822898 (Pointer events) are - // fully commited. - // ==== END RANDOM INTERLUDE ABOut POINTER EVENTS ==== - - // And pass the untransformed event to content. - DUMP_TOUCH_IDS("DOM(3)", aEvent); - nsEventStatus contentStatus = nsEventStatus_eIgnore; - mWidget->DispatchEvent(&transformedEvent, contentStatus); - - // Let the apz know if content wants to consume touch events. - if (mCancelable) { - if (nsEventStatus_eConsumeNoDefault == contentStatus) { - mWidget->ApzContentConsumingTouch(mInputBlockId); - } else { - mWidget->ApzContentIgnoringTouch(mInputBlockId); - if (apzcStatus == nsEventStatus_eConsumeDoDefault) { - SendPointerCancelToContent(transformedEvent); - } - } - mCancelable = false; - } - - // Cancel the gesture detection as well if content is taking this block. - if (nsEventStatus_eConsumeNoDefault == contentStatus) { - CancelGesture(); - } -} - -void -MetroInput::SendPointerCancelToContent(const WidgetTouchEvent& aEvent) -{ - // The APZ is consuming the touch pointers specified in |aEvent| so - // we need to send pointer-cancel events for them to content. We - // do that by sending touchcancel events which the EventStateManager - // turns into pointer-cancel events - WidgetTouchEvent cancel(aEvent); - cancel.message = NS_TOUCH_CANCEL; - for (uint32_t i = 0; i < cancel.touches.Length(); i++) { - cancel.touches[i]->convertToPointer = true; - } - nsEventStatus status; - mWidget->DispatchEvent(&cancel, status); -} - -bool -MetroInput::SendPendingResponseToApz() -{ - // If this is called, content has missed its chance to consume this event block - // so we should notify the APZ that content is ignoring this touch block. - if (mCancelable) { - mWidget->ApzContentIgnoringTouch(mInputBlockId); - mCancelable = false; - return true; - } - return false; -} - -void -MetroInput::FlushPendingContentResponse() -{ - SendPendingResponseToApz(); -} - -void -MetroInput::CancelGesture() -{ - if (mRecognizerWantsEvents) { - mRecognizerWantsEvents = false; - mGestureRecognizer->CompleteGesture(); - } -} - -void -MetroInput::DeliverNextQueuedTouchEvent() -{ - /* - * Note: never rely on the contents of mTouches here, since this is a delayed - * callback. mTouches will likely have been modified. - */ - - nsEventStatus status = nsEventStatus_eIgnore; - - WidgetTouchEvent* event = - static_cast(mInputEventQueue.PopFront()); - MOZ_ASSERT(event); - - AutoDeleteEvent wrap(event); - - // This is the start of a new touch block. If we haven't - // responded to the APZ about the last touch block, do that - // now, and reset variables for the new touch block. - if (event->message == NS_TOUCH_START) { - SendPendingResponseToApz(); - - mCancelable = true; - mTargetAPZCGuid = ScrollableLayerGuid(); - mInputBlockId = 0; - } - - // Test for non-apz vs. apz target. To do this we only use the first touch - // point since that will be the input batch target. Cache this for touch events - // since HitTestChrome has to send a dom event. - if (event->message == NS_TOUCH_START && event->touches.Length() == 1) { - nsRefPtr touch = event->touches[0]; - LayoutDeviceIntPoint pt = LayoutDeviceIntPoint::FromUntyped(touch->mRefPoint); - // This is currently a general contained rect hit test, it may produce a false - // positive for overlay chrome elements. Also, some content pages won't support - // apzc, so this may be false for content as well. - bool apzIntersect = mWidget->ApzHitTest(mozilla::ScreenIntPoint(pt.x, pt.y)); - mNonApzTargetForTouch = (!apzIntersect || HitTestChrome(pt)); - } - - // If this event is destined for dom, deliver it directly there bypassing - // the apz. Continue doing this until the number of active touch points drops - // to zero. After that we recompute mNonApzTargetForTouch in the block above. - if (mNonApzTargetForTouch) { - DUMP_TOUCH_IDS("DOM(1)", event); - mWidget->DispatchEvent(event, status); - if (mCancelable) { - // Disable gesture based events (taps, swipes, rotation) if - // preventDefault is called on touchstart. - if (nsEventStatus_eConsumeNoDefault == status) { - CancelGesture(); - } - if (event->message == NS_TOUCH_MOVE) { - mCancelable = false; - } - } - return; - } - - // Special handling for the start and first move events - if (event->message == NS_TOUCH_START) { - HandleTouchStartEvent(event); - return; - } else if (mCancelable && event->message == NS_TOUCH_MOVE) { - HandleFirstTouchMoveEvent(event); - return; - } - - // If we get here, content has already had its chance to consume this event - // block. If it didn't do so we can inform the APZ that content is ignoring - // this event block. - bool responseSent = SendPendingResponseToApz(); - - // Normal processing of events. Send it to the APZ first for handling and - // untransformation. then pass the untransformed event to content. - DUMP_TOUCH_IDS("APZC(3)", event); - status = mWidget->ApzReceiveInputEvent(event, nullptr, nullptr); - if (status == nsEventStatus_eConsumeNoDefault) { - CancelGesture(); - return; - } - if (responseSent && status == nsEventStatus_eConsumeDoDefault) { - SendPointerCancelToContent(*event); - return; - } - DUMP_TOUCH_IDS("DOM(4)", event); - mWidget->DispatchEvent(event, status); -} - -void -MetroInput::DispatchEventIgnoreStatus(WidgetGUIEvent *aEvent) -{ - mWidget->DispatchEvent(aEvent, sThrowawayStatus); -} - -void -MetroInput::UnregisterInputEvents() { - // Unregister ourselves for the edge swipe event - WRL::ComPtr edgeStatics; - if (SUCCEEDED(Foundation::GetActivationFactory( - WRL::Wrappers::HStringReference( - RuntimeClass_Windows_UI_Input_EdgeGesture).Get(), - edgeStatics.GetAddressOf()))) { - WRL::ComPtr edge; - if (SUCCEEDED(edgeStatics->GetForCurrentView(edge.GetAddressOf()))) { - edge->remove_Starting(mTokenEdgeStarted); - edge->remove_Canceled(mTokenEdgeCanceled); - edge->remove_Completed(mTokenEdgeCompleted); - } - } - // Unregister ourselves from the window events. This is extremely important; - // once this object is destroyed we don't want Windows to try to send events - // to it. - mWindow->remove_PointerPressed(mTokenPointerPressed); - mWindow->remove_PointerReleased(mTokenPointerReleased); - mWindow->remove_PointerMoved(mTokenPointerMoved); - mWindow->remove_PointerEntered(mTokenPointerEntered); - mWindow->remove_PointerExited(mTokenPointerExited); - - // Unregistering from the gesture recognizer events probably isn't as - // necessary since we're about to destroy the gesture recognizer, but - // it can't hurt. - mGestureRecognizer->remove_ManipulationCompleted( - mTokenManipulationCompleted); - mGestureRecognizer->remove_Tapped(mTokenTapped); - mGestureRecognizer->remove_RightTapped(mTokenRightTapped); -} - -void -MetroInput::RegisterInputEvents() -{ - NS_ASSERTION(mWindow, "Must have a window to register for input events!"); - NS_ASSERTION(mGestureRecognizer, - "Must have a GestureRecognizer for input events!"); - // Register for edge swipe - WRL::ComPtr edgeStatics; - Foundation::GetActivationFactory( - WRL::Wrappers::HStringReference( - RuntimeClass_Windows_UI_Input_EdgeGesture) - .Get(), - edgeStatics.GetAddressOf()); - WRL::ComPtr edge; - edgeStatics->GetForCurrentView(edge.GetAddressOf()); - - edge->add_Starting( - WRL::Callback( - this, - &MetroInput::OnEdgeGestureStarted).Get(), - &mTokenEdgeStarted); - - edge->add_Canceled( - WRL::Callback( - this, - &MetroInput::OnEdgeGestureCanceled).Get(), - &mTokenEdgeCanceled); - - edge->add_Completed( - WRL::Callback( - this, - &MetroInput::OnEdgeGestureCompleted).Get(), - &mTokenEdgeCompleted); - - // Set up our Gesture Recognizer to raise events for the gestures we - // care about - mGestureRecognizer->put_GestureSettings( - UI::Input::GestureSettings::GestureSettings_Tap - | UI::Input::GestureSettings::GestureSettings_DoubleTap - | UI::Input::GestureSettings::GestureSettings_RightTap - | UI::Input::GestureSettings::GestureSettings_Hold - | UI::Input::GestureSettings::GestureSettings_ManipulationTranslateX - | UI::Input::GestureSettings::GestureSettings_ManipulationTranslateY); - - // Register for the pointer events on our Window - mWindow->add_PointerPressed( - WRL::Callback( - this, - &MetroInput::OnPointerPressed).Get(), - &mTokenPointerPressed); - - mWindow->add_PointerReleased( - WRL::Callback( - this, - &MetroInput::OnPointerReleased).Get(), - &mTokenPointerReleased); - - mWindow->add_PointerMoved( - WRL::Callback( - this, - &MetroInput::OnPointerMoved).Get(), - &mTokenPointerMoved); - - mWindow->add_PointerEntered( - WRL::Callback( - this, - &MetroInput::OnPointerEntered).Get(), - &mTokenPointerEntered); - - mWindow->add_PointerExited( - WRL::Callback( - this, - &MetroInput::OnPointerExited).Get(), - &mTokenPointerExited); - - // Register for the events raised by our Gesture Recognizer - mGestureRecognizer->add_Tapped( - WRL::Callback( - this, - &MetroInput::OnTapped).Get(), - &mTokenTapped); - - mGestureRecognizer->add_RightTapped( - WRL::Callback( - this, - &MetroInput::OnRightTapped).Get(), - &mTokenRightTapped); - - mGestureRecognizer->add_ManipulationCompleted( - WRL::Callback( - this, - &MetroInput::OnManipulationCompleted).Get(), - &mTokenManipulationCompleted); -} - -} } } diff --git a/widget/windows/winrt/MetroInput.h b/widget/windows/winrt/MetroInput.h deleted file mode 100644 index 56c8105feac..00000000000 --- a/widget/windows/winrt/MetroInput.h +++ /dev/null @@ -1,292 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#pragma once - -// Moz headers (alphabetical) -#include "APZController.h" -#include "keyboardlayout.h" // mModifierKeyState -#include "nsBaseHashtable.h" // mTouches -#include "nsHashKeys.h" // type of key for mTouches -#include "mozwrlbase.h" -#include "nsDeque.h" -#include "mozilla/EventForwards.h" -#include "mozilla/layers/APZCTreeManager.h" - -// System headers (alphabetical) -#include // EventRegistrationToken -#include // uint32_t -#include // Microsoft::WRL::ComPtr class -#include // Microsoft::WRL::InspectableClass macro - -// Moz forward declarations -class MetroWidget; - -namespace mozilla { -namespace dom { -class Touch; -} -} - -// Windows forward declarations -namespace ABI { - namespace Windows { - namespace Devices { - namespace Input { - enum PointerDeviceType; - } - }; - namespace Foundation { - struct Point; - }; - namespace UI { - namespace Core { - struct ICoreWindow; - struct IAcceleratorKeyEventArgs; - struct IKeyEventArgs; - struct IPointerEventArgs; - }; - namespace Input { - struct IEdgeGesture; - struct IEdgeGestureEventArgs; - struct IGestureRecognizer; - struct IManipulationCompletedEventArgs; - struct IManipulationStartedEventArgs; - struct IManipulationUpdatedEventArgs; - struct IPointerPoint; - struct IRightTappedEventArgs; - struct ITappedEventArgs; - struct ManipulationDelta; - }; - }; - }; -}; - -namespace mozilla { -namespace widget { -namespace winrt { - -class MetroInput : public Microsoft::WRL::RuntimeClass, - public APZPendingResponseFlusher -{ - InspectableClass(L"MetroInput", BaseTrust); - -private: - typedef mozilla::layers::AllowedTouchBehavior AllowedTouchBehavior; - typedef uint32_t TouchBehaviorFlags; - - // Devices - typedef ABI::Windows::Devices::Input::PointerDeviceType PointerDeviceType; - - // Foundation - typedef ABI::Windows::Foundation::Point Point; - - // UI::Core - typedef ABI::Windows::UI::Core::ICoreWindow ICoreWindow; - typedef ABI::Windows::UI::Core::IAcceleratorKeyEventArgs \ - IAcceleratorKeyEventArgs; - typedef ABI::Windows::UI::Core::IKeyEventArgs IKeyEventArgs; - typedef ABI::Windows::UI::Core::IPointerEventArgs IPointerEventArgs; - - // UI::Input - typedef ABI::Windows::UI::Input::IEdgeGesture IEdgeGesture; - typedef ABI::Windows::UI::Input::IEdgeGestureEventArgs IEdgeGestureEventArgs; - typedef ABI::Windows::UI::Input::IGestureRecognizer IGestureRecognizer; - typedef ABI::Windows::UI::Input::IManipulationCompletedEventArgs \ - IManipulationCompletedEventArgs; - typedef ABI::Windows::UI::Input::IManipulationStartedEventArgs \ - IManipulationStartedEventArgs; - typedef ABI::Windows::UI::Input::IManipulationUpdatedEventArgs \ - IManipulationUpdatedEventArgs; - typedef ABI::Windows::UI::Input::IPointerPoint IPointerPoint; - typedef ABI::Windows::UI::Input::IRightTappedEventArgs IRightTappedEventArgs; - typedef ABI::Windows::UI::Input::ITappedEventArgs ITappedEventArgs; - typedef ABI::Windows::UI::Input::ManipulationDelta ManipulationDelta; - - typedef mozilla::layers::ScrollableLayerGuid ScrollableLayerGuid; - -public: - MetroInput(MetroWidget* aWidget, - ICoreWindow* aWindow); - virtual ~MetroInput(); - - // These input events are received from our window. These are basic - // pointer and keyboard press events. MetroInput responds to them - // by sending gecko events and forwarding these input events to its - // GestureRecognizer to be processed into more complex input events - // (tap, rightTap, rotate, etc) - HRESULT OnPointerPressed(ICoreWindow* aSender, - IPointerEventArgs* aArgs); - HRESULT OnPointerReleased(ICoreWindow* aSender, - IPointerEventArgs* aArgs); - HRESULT OnPointerMoved(ICoreWindow* aSender, - IPointerEventArgs* aArgs); - HRESULT OnPointerEntered(ICoreWindow* aSender, - IPointerEventArgs* aArgs); - HRESULT OnPointerExited(ICoreWindow* aSender, - IPointerEventArgs* aArgs); - - // The Edge gesture event is special. It does not come from our window - // or from our GestureRecognizer. - HRESULT OnEdgeGestureStarted(IEdgeGesture* aSender, - IEdgeGestureEventArgs* aArgs); - HRESULT OnEdgeGestureCanceled(IEdgeGesture* aSender, - IEdgeGestureEventArgs* aArgs); - HRESULT OnEdgeGestureCompleted(IEdgeGesture* aSender, - IEdgeGestureEventArgs* aArgs); - - // Swipe gesture callback from the GestureRecognizer. - HRESULT OnManipulationCompleted(IGestureRecognizer* aSender, - IManipulationCompletedEventArgs* aArgs); - - // Tap gesture callback from the GestureRecognizer. - HRESULT OnTapped(IGestureRecognizer* aSender, ITappedEventArgs* aArgs); - HRESULT OnRightTapped(IGestureRecognizer* aSender, - IRightTappedEventArgs* aArgs); - - void HandleTap(const Point& aPoint, unsigned int aTapCount); - void HandleLongTap(const Point& aPoint); - - // The APZPendingResponseFlusher implementation - void FlushPendingContentResponse(); - - static bool IsInputModeImprecise(); - -private: - Microsoft::WRL::ComPtr mWindow; - Microsoft::WRL::ComPtr mWidget; - Microsoft::WRL::ComPtr mGestureRecognizer; - - ModifierKeyState mModifierKeyState; - - // Tracking input level - enum InputPrecisionLevel { - LEVEL_PRECISE, - LEVEL_IMPRECISE - }; - static InputPrecisionLevel sCurrentInputLevel; - void UpdateInputLevel(InputPrecisionLevel aInputLevel); - - // Initialization/Uninitialization helpers - void RegisterInputEvents(); - void UnregisterInputEvents(); - - // Hit testing for apz content - bool mNonApzTargetForTouch; - bool HitTestChrome(const LayoutDeviceIntPoint& pt); - - // Event processing helpers. See function definitions for more info. - bool TransformRefPoint(const Point& aPosition, - LayoutDeviceIntPoint& aRefPointOut); - void TransformTouchEvent(WidgetTouchEvent* aEvent); - void OnPointerNonTouch(IPointerPoint* aPoint); - void AddPointerMoveDataToRecognizer(IPointerEventArgs* aArgs); - void InitGeckoMouseEventFromPointerPoint(WidgetMouseEvent* aEvent, - IPointerPoint* aPoint); - void ProcessManipulationDelta(ManipulationDelta const& aDelta, - Point const& aPosition, - uint32_t aMagEventType, - uint32_t aRotEventType); - uint16_t ProcessInputTypeForGesture(IEdgeGestureEventArgs* aArgs); - bool ShouldDeliverInputToRecognizer(); - - // Returns array of allowed touch behaviors for touch points of given TouchEvent. - // Note: event argument should be transformed via apzc before supplying to this method. - void GetAllowedTouchBehavior(WidgetTouchEvent* aTransformedEvent, nsTArray& aOutBehaviors); - - // First, read the comment in gfx/layers/apz/src/TouchBlockState.h. - // The following booleans track the following pieces of state: - // mCancelable - if we have not yet notified the APZ code about the prevent- - // default status of the current touch block. This is flipped from true - // to false when this notification happens. - // mRecognizerWantsEvents - If the gesture recognizer should be receiving - // events. This is normally true, but will be set to false if the APZ - // decides the touch block should be thrown away entirely, or if content - // consumes the touch block. - // XXX There is a hazard with mRecognizerWantsEvents because it is accessed - // both in the sync and async portions of the code. - bool mCancelable; - bool mRecognizerWantsEvents; - - // In the old Win32 way of doing things, we would receive a WM_TOUCH event - // that told us the state of every touchpoint on the touch surface. If - // multiple touchpoints had moved since the last update we would learn - // about all their movement simultaneously. - // - // In the new WinRT way of doing things, we receive a separate - // PointerPressed/PointerMoved/PointerReleased event for each touchpoint - // that has changed. - // - // When we learn of touch input, we dispatch gecko events in response. - // With the new WinRT way of doing things, we would end up sending many - // more gecko events than we would using the Win32 mechanism. E.g., - // for 5 active touchpoints, we would be sending 5 times as many gecko - // events. This caused performance to visibly degrade on modestly-powered - // machines. In response, we no longer send touch events immediately - // upon receiving PointerPressed or PointerMoved. Instead, we store - // the updated touchpoint info and record the fact that the touchpoint - // has changed. If ever we try to update a touchpoint has already - // changed, we dispatch a touch event containing all the changed touches. - void InitTouchEventTouchList(WidgetTouchEvent* aEvent); - nsBaseHashtable, - nsRefPtr > mTouches; - - // These registration tokens are set when we register ourselves to receive - // events from our window. We must hold on to them for the entire duration - // that we want to receive these events. When we are done, we must - // unregister ourself with the window using these tokens. - EventRegistrationToken mTokenPointerPressed; - EventRegistrationToken mTokenPointerReleased; - EventRegistrationToken mTokenPointerMoved; - EventRegistrationToken mTokenPointerEntered; - EventRegistrationToken mTokenPointerExited; - - // When we register ourselves to handle edge gestures, we receive a - // token. To we unregister ourselves, we must use the token we received. - EventRegistrationToken mTokenEdgeStarted; - EventRegistrationToken mTokenEdgeCanceled; - EventRegistrationToken mTokenEdgeCompleted; - - // These registration tokens are set when we register ourselves to receive - // events from our GestureRecognizer. It's probably not a huge deal if we - // don't unregister ourselves with our GestureRecognizer before destroying - // the GestureRecognizer, but it can't hurt. - EventRegistrationToken mTokenManipulationCompleted; - EventRegistrationToken mTokenTapped; - EventRegistrationToken mTokenRightTapped; - - // Due to a limitation added in 8.1 the ui thread can't re-enter the main - // native event dispatcher in MetroAppShell. So all events delivered to us - // on the ui thread via a native event dispatch call get bounced through - // the gecko thread event queue using runnables. Most events can be sent - // async without the need to see the status result. Those that do have - // specialty callbacks. Note any event that arrives to us on the ui thread - // that originates from another thread is safe to send sync. - - // Async event dispatching - void DispatchAsyncEventIgnoreStatus(WidgetInputEvent* aEvent); - void DispatchAsyncTouchEvent(WidgetTouchEvent* aEvent); - - // Async event callbacks - void DeliverNextQueuedEventIgnoreStatus(); - void DeliverNextQueuedTouchEvent(); - - void HandleTouchStartEvent(WidgetTouchEvent* aEvent); - void HandleFirstTouchMoveEvent(WidgetTouchEvent* aEvent); - void SendPointerCancelToContent(const WidgetTouchEvent& aEvent); - bool SendPendingResponseToApz(); - void CancelGesture(); - - // Sync event dispatching - void DispatchEventIgnoreStatus(WidgetGUIEvent* aEvent); - - nsDeque mInputEventQueue; - mozilla::layers::ScrollableLayerGuid mTargetAPZCGuid; - uint64_t mInputBlockId; - static nsEventStatus sThrowawayStatus; -}; - -} } } diff --git a/widget/windows/winrt/MetroUIUtils.js b/widget/windows/winrt/MetroUIUtils.js deleted file mode 100644 index 372e4bc14b1..00000000000 --- a/widget/windows/winrt/MetroUIUtils.js +++ /dev/null @@ -1,175 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cu = Components.utils; -const Cr = Components.results; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); - -function MetroUIUtils() { -} - -const URLElements = { - "a": "href", - "applet": ["archive", "code", "codebase"], - "area": "href", - "audio": "src", - "base": "href", - "blockquote": ["cite"], - "body": "background", - "button": "formaction", - "command": "icon", - "del": ["cite"], - "embed": "src", - "form": "action", - "frame": ["longdesc", "src"], - "iframe": ["longdesc", "src"], - "img": ["longdesc", "src"], - "input": ["formaction", "src"], - "ins": ["cite"], - "link": "href", - "object": ["archive", "codebase", "data"], - "q": ["cite"], - "script": "src", - "source": "src", -}; - -MetroUIUtils.prototype = { - classID : Components.ID("e4626085-17f7-4068-a225-66c1acc0485c"), - QueryInterface : XPCOMUtils.generateQI([Ci.nsIMetroUIUtils]), - /** - * Loads the specified panel in the browser. - * @ param aPanelId The identifier of the pane to load - */ - showPanel: function(aPanelId) { - let browserWin = Services.wm.getMostRecentWindow("navigator:browser"); - browserWin.PanelUI.show(aPanelId); - }, - - /** - * Determines if the browser has selected content - */ - get hasSelectedContent() { - try { - let browserWin = Services.wm.getMostRecentWindow("navigator:browser"); - let tabBrowser = browserWin.getBrowser(); - if (!browserWin || !tabBrowser || !tabBrowser.contentWindow) { - return false; - } - - let sel = tabBrowser.contentWindow.getSelection(); - return sel && sel.toString(); - } catch(e) { - return false; - } - }, - - /** - * Obtains the current page title - */ - get currentPageTitle() { - let browserWin = Services.wm.getMostRecentWindow("navigator:browser"); - if (!browserWin || !browserWin.content || !browserWin.content.document) { - throw Cr.NS_ERROR_FAILURE; - } - return browserWin.content.document.title || ""; - }, - - /** - * Obtains the current page URI - */ - get currentPageURI() { - let browserWin = Services.wm.getMostRecentWindow("navigator:browser"); - if (!browserWin || !browserWin.content || !browserWin.content.document) { - throw Cr.NS_ERROR_FAILURE; - } - return browserWin.content.document.URL || ""; - }, - - /** - * Determines the text that should be shared - */ - get shareText() { - let browserWin = Services.wm.getMostRecentWindow("navigator:browser"); - let tabBrowser = browserWin.getBrowser(); - if (browserWin && tabBrowser && tabBrowser.contentWindow) { - let sel = tabBrowser.contentWindow.getSelection(); - if (sel && sel.rangeCount) - return sel; - } - - throw Cr.NS_ERROR_FAILURE; - }, - - /** - * Replaces the node's attribute value to be a fully qualified URL - */ - _expandAttribute : function(ioService, doc, node, attrName) { - let attrValue = node.getAttribute(attrName); - if (!attrValue) - return; - - try { - let uri = ioService.newURI(attrValue, null, doc.baseURIObject); - node.setAttribute(attrName, uri.spec); - } catch (e) { - } - }, - - /* - * Replaces all attribute values in 'n' which contain URLs recursiely - * to fully qualified URLs. - */ - _expandURLs: function(doc, n) { - let ioService = Cc["@mozilla.org/network/io-service;1"]. - getService(Ci.nsIIOService); - for (let i = 0; i < n.children.length; i++) { - let child = n.children[i]; - let childTagName = child.tagName.toLowerCase(); - - // Iterate through all known tags which can contain URLs. A tag either - // contains a single attribute name or an array of attribute names. - for (let tagName in URLElements) { - if (tagName === childTagName) { - if (URLElements[tagName] instanceof Array) { - URLElements[tagName].forEach(function(attrName) { - this._expandAttribute(ioService ,doc, child, attrName); - }, this); - } else { - this._expandAttribute(ioService ,doc, child, URLElements[tagName]); - } - } - } - - this._expandURLs(doc, child); - } - }, - - /** - * Determines the HTML that should be shared - */ - get shareHTML() { - let browserWin = Services.wm.getMostRecentWindow("navigator:browser"); - let tabBrowser = browserWin.getBrowser(); - let sel; - if (browserWin && tabBrowser && tabBrowser.contentWindow && - (sel = tabBrowser.contentWindow.getSelection()) && sel.rangeCount) { - let div = tabBrowser.contentWindow.document.createElement("DIV"); - for (let i = 0; i < sel.rangeCount; i++) { - let contents = sel.getRangeAt(i).cloneContents(true); - div.appendChild(contents); - } - this._expandURLs(tabBrowser.contentWindow.document, div); - return div.outerHTML; - } - - throw Cr.NS_ERROR_FAILURE; - } -}; - -var component = [MetroUIUtils]; -this.NSGetFactory = XPCOMUtils.generateNSGetFactory(component); diff --git a/widget/windows/winrt/MetroUIUtils.manifest b/widget/windows/winrt/MetroUIUtils.manifest deleted file mode 100644 index 48620c9d91b..00000000000 --- a/widget/windows/winrt/MetroUIUtils.manifest +++ /dev/null @@ -1,3 +0,0 @@ -# MetroUIUtils.js -component {e4626085-17f7-4068-a225-66c1acc0485c} MetroUIUtils.js -contract @mozilla.org/metro-ui-utils;1 {e4626085-17f7-4068-a225-66c1acc0485c} diff --git a/widget/windows/winrt/MetroUtils.cpp b/widget/windows/winrt/MetroUtils.cpp deleted file mode 100644 index e6731b44c7c..00000000000 --- a/widget/windows/winrt/MetroUtils.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "MetroUtils.h" -#include -#include "nsICommandLineRunner.h" -#include "nsNetUtil.h" -#include "nsIBrowserDOMWindow.h" -#include "nsIWebNavigation.h" -#include "nsIDocShellTreeItem.h" -#include "nsIDOMWindow.h" -#include "nsIDOMChromeWindow.h" -#include "nsIWindowMediator.h" -#include "nsIURI.h" -#include "prlog.h" -#include "nsIObserverService.h" -#include "nsRect.h" - -#include -#include -#include -#include "DisplayInfo_sdk81.h" - -using namespace ABI::Windows::UI::ApplicationSettings; - -using namespace mozilla; - -using namespace ABI::Windows::Foundation; -using namespace Microsoft::WRL; -using namespace Microsoft::WRL::Wrappers; -using namespace ABI::Windows::UI::ViewManagement; -using namespace ABI::Windows::Graphics::Display; - -// Conversion between logical and physical coordinates - -double -MetroUtils::LogToPhysFactor() -{ - ComPtr dispInfoStatics; - if (SUCCEEDED(GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayInformation).Get(), - dispInfoStatics.GetAddressOf()))) { - ComPtr dispInfo; - if (SUCCEEDED(dispInfoStatics->GetForCurrentView(&dispInfo))) { - FLOAT dpi; - if (SUCCEEDED(dispInfo->get_LogicalDpi(&dpi))) { - return (double)dpi / 96.0f; - } - } - } - - ComPtr dispProps; - if (SUCCEEDED(GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), - dispProps.GetAddressOf()))) { - FLOAT dpi; - if (SUCCEEDED(dispProps->get_LogicalDpi(&dpi))) { - return (double)dpi / 96.0f; - } - } - - return 1.0; -} - -double -MetroUtils::PhysToLogFactor() -{ - return 1.0 / LogToPhysFactor(); -} - -double -MetroUtils::ScaleFactor() -{ - // Return the resolution scale factor reported by the metro environment. - // XXX TODO: also consider the desktop resolution setting, as IE appears to do? - ComPtr dispInfoStatics; - if (SUCCEEDED(GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayInformation).Get(), - dispInfoStatics.GetAddressOf()))) { - ComPtr dispInfo; - if (SUCCEEDED(dispInfoStatics->GetForCurrentView(&dispInfo))) { - ResolutionScale scale; - if (SUCCEEDED(dispInfo->get_ResolutionScale(&scale))) { - return (double)scale / 100.0; - } - } - } - - ComPtr dispProps; - if (SUCCEEDED(GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), - dispProps.GetAddressOf()))) { - ResolutionScale scale; - if (SUCCEEDED(dispProps->get_ResolutionScale(&scale))) { - return (double)scale / 100.0; - } - } - - return 1.0; -} - -nsIntPoint -MetroUtils::LogToPhys(const Point& aPt) -{ - double factor = LogToPhysFactor(); - return nsIntPoint(int32_t(NS_round(aPt.X * factor)), int32_t(NS_round(aPt.Y * factor))); -} - -nsIntRect -MetroUtils::LogToPhys(const Rect& aRect) -{ - double factor = LogToPhysFactor(); - return nsIntRect(int32_t(NS_round(aRect.X * factor)), - int32_t(NS_round(aRect.Y * factor)), - int32_t(NS_round(aRect.Width * factor)), - int32_t(NS_round(aRect.Height * factor))); -} - -Point -MetroUtils::PhysToLog(const nsIntPoint& aPt) -{ - // Points contain FLOATs - FLOAT factor = (FLOAT)PhysToLogFactor(); - Point p = { FLOAT(aPt.x) * factor, FLOAT(aPt.y) * factor }; - return p; -} - -nsresult -MetroUtils::FireObserver(const char* aMessage, const char16_t* aData) -{ - nsCOMPtr observerService = - mozilla::services::GetObserverService(); - if (observerService) { - return observerService->NotifyObservers(nullptr, aMessage, aData); - } - return NS_ERROR_FAILURE; -} - -HRESULT MetroUtils::CreateUri(HSTRING aUriStr, ComPtr& aUriOut) -{ - HRESULT hr; - ComPtr uriFactory; - hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_Foundation_Uri).Get(), &uriFactory); - AssertRetHRESULT(hr, hr); - ComPtr uri; - return uriFactory->CreateUri(aUriStr, &aUriOut); -} - -HRESULT MetroUtils::CreateUri(HString& aHString, ComPtr& aUriOut) -{ - return MetroUtils::CreateUri(aHString.Get(), aUriOut); -} - -HRESULT -MetroUtils::GetViewState(ApplicationViewState& aState) -{ - HRESULT hr; - ComPtr appViewStatics; - hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_UI_ViewManagement_ApplicationView).Get(), - appViewStatics.GetAddressOf()); - AssertRetHRESULT(hr, hr); - hr = appViewStatics->get_Value(&aState); - return hr; -} - -HRESULT -MetroUtils::TryUnsnap(bool* aResult) -{ - HRESULT hr; - ComPtr appViewStatics; - hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_UI_ViewManagement_ApplicationView).Get(), - appViewStatics.GetAddressOf()); - AssertRetHRESULT(hr, hr); - boolean success = false; - hr = appViewStatics->TryUnsnap(&success); - if (aResult) - *aResult = success; - return hr; -} - -HRESULT -MetroUtils::ShowSettingsFlyout() -{ - ComPtr settingsPaneStatics; - HRESULT hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_UI_ApplicationSettings_SettingsPane).Get(), - settingsPaneStatics.GetAddressOf()); - if (SUCCEEDED(hr)) { - settingsPaneStatics->Show(); - } - - return hr; -} diff --git a/widget/windows/winrt/MetroUtils.h b/widget/windows/winrt/MetroUtils.h deleted file mode 100644 index 97740b7d20d..00000000000 --- a/widget/windows/winrt/MetroUtils.h +++ /dev/null @@ -1,96 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#pragma once - -#include "nsDebug.h" -#include "nsThreadUtils.h" -#include "nsString.h" -#include "nsPoint.h" -#include "WinUtils.h" -#include "nsRect.h" - -#include "mozwrlbase.h" - -#include -#include -#include - -// HRESULT checkers, these warn on failure in debug builds -#ifdef DEBUG -#define DebugLogHR(hr) LogHRESULT(hr) -#else -#define DebugLogHR(hr) -#endif -#define AssertHRESULT(hr) \ - if (FAILED(hr)) { \ - DebugLogHR(hr); \ - return; \ - } -#define AssertRetHRESULT(hr, res) \ - if (FAILED(hr)) { \ - DebugLogHR(hr); \ - return res; \ - } - -// MS Point helpers -#define POINT_CEIL_X(position) (uint32_t)ceil(position.X) -#define POINT_CEIL_Y(position) (uint32_t)ceil(position.Y) - -class nsIBrowserDOMWindow; -class nsIDOMWindow; - -namespace mozilla { -namespace widget { -namespace winrt { - -template -HRESULT ActivateGenericInstance(wchar_t const (&RuntimeClassName)[size], Microsoft::WRL::ComPtr& aOutObject) { - Microsoft::WRL::ComPtr factory; - HRESULT hr = ABI::Windows::Foundation::GetActivationFactory(Microsoft::WRL::Wrappers::HStringReference(RuntimeClassName).Get(), - factory.GetAddressOf()); - if (FAILED(hr)) - return hr; - Microsoft::WRL::ComPtr inspect; - hr = factory->ActivateInstance(inspect.GetAddressOf()); - if (FAILED(hr)) - return hr; - return inspect.As(&aOutObject); -} - -} } } - -class MetroUtils -{ - typedef ABI::Windows::Foundation::IUriRuntimeClass IUriRuntimeClass; - typedef Microsoft::WRL::Wrappers::HString HString; - typedef ABI::Windows::UI::ViewManagement::ApplicationViewState ApplicationViewState; - typedef ABI::Windows::Foundation::Point Point; - typedef ABI::Windows::Foundation::Rect Rect; - -public: - // Functions to convert between logical pixels as used by most Windows APIs - // and physical (device) pixels. - static double LogToPhysFactor(); - static double PhysToLogFactor(); - static nsIntPoint LogToPhys(const Point& aPt); - static nsIntRect LogToPhys(const Rect& aRect); - static Point PhysToLog(const nsIntPoint& aPt); - - // Resolution scale factor - static double ScaleFactor(); - - static nsresult FireObserver(const char* aMessage, const char16_t* aData = nullptr); - - static HRESULT CreateUri(HSTRING aUriStr, Microsoft::WRL::ComPtr& aUriOut); - static HRESULT CreateUri(HString& aHString, Microsoft::WRL::ComPtr& aUriOut); - static HRESULT GetViewState(ApplicationViewState& aState); - static HRESULT TryUnsnap(bool* aResult = nullptr); - static HRESULT ShowSettingsFlyout(); - -private: - static nsresult GetBrowserDOMWindow(nsCOMPtr &aBWin); - static nsresult GetMostRecentWindow(const char16_t* aType, nsIDOMWindow** aWindow); -}; diff --git a/widget/windows/winrt/MetroWidget.cpp b/widget/windows/winrt/MetroWidget.cpp deleted file mode 100644 index ad8ec420868..00000000000 --- a/widget/windows/winrt/MetroWidget.cpp +++ /dev/null @@ -1,1628 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "ContentHelper.h" -#include "MetroWidget.h" -#include "MetroApp.h" -#include "mozilla/Preferences.h" -#include "nsToolkit.h" -#include "KeyboardLayout.h" -#include "MetroUtils.h" -#include "WinUtils.h" -#include "nsToolkitCompsCID.h" -#include "nsIAppStartup.h" -#include "../resource.h" -#include "nsIWidgetListener.h" -#include "nsIPresShell.h" -#include "nsPrintfCString.h" -#include "nsWindowDefs.h" -#include "FrameworkView.h" -#include "nsTextStore.h" -#include "Layers.h" -#include "ClientLayerManager.h" -#include "BasicLayers.h" -#include "FrameMetrics.h" -#include -#include "Windows.Graphics.Display.h" -#include "DisplayInfo_sdk81.h" -#include "nsNativeDragTarget.h" -#ifdef MOZ_CRASHREPORTER -#include "nsExceptionHandler.h" -#endif -#include "UIABridgePrivate.h" -#include "WinMouseScrollHandler.h" -#include "InputData.h" -#include "mozilla/TextEvents.h" -#include "mozilla/TouchEvents.h" -#include "mozilla/MiscEvents.h" -#include "gfxPrefs.h" - -using namespace Microsoft::WRL; -using namespace Microsoft::WRL::Wrappers; - -using namespace mozilla; -using namespace mozilla::widget; -using namespace mozilla::layers; -using namespace mozilla::widget::winrt; - -using namespace ABI::Windows::ApplicationModel; -using namespace ABI::Windows::ApplicationModel::Core; -using namespace ABI::Windows::ApplicationModel::Activation; -using namespace ABI::Windows::UI::Input; -using namespace ABI::Windows::Devices::Input; -using namespace ABI::Windows::UI::Core; -using namespace ABI::Windows::System; -using namespace ABI::Windows::Foundation; -using namespace ABI::Windows::Foundation::Collections; -using namespace ABI::Windows::Graphics::Display; - -#ifdef PR_LOGGING -extern PRLogModuleInfo* gWindowsLog; -#endif - -#if !defined(SM_CONVERTIBLESLATEMODE) -#define SM_CONVERTIBLESLATEMODE 0x2003 -#endif - -static uint32_t gInstanceCount = 0; -const char16_t* kMetroSubclassThisProp = L"MetroSubclassThisProp"; -HWND MetroWidget::sICoreHwnd = nullptr; - -namespace mozilla { -namespace widget { -UINT sDefaultBrowserMsgId = RegisterWindowMessageW(L"DefaultBrowserClosing"); -} } - -// WM_GETOBJECT id pulled from uia headers -#define MOZOBJID_UIAROOT -25 - -namespace mozilla { -namespace widget { -namespace winrt { -extern ComPtr sMetroApp; -extern ComPtr gProviderRoot; -} } } - -namespace { - - void SendInputs(uint32_t aModifiers, INPUT* aExtraInputs, uint32_t aExtraInputsLen) - { - // keySequence holds the virtual key values of each of the keys we intend - // to press - nsAutoTArray keySequence; - for (uint32_t i = 0; i < ArrayLength(sModifierKeyMap); ++i) { - const uint32_t* map = sModifierKeyMap[i]; - if (aModifiers & map[0]) { - keySequence.AppendElement(KeyPair(map[1], map[2])); - } - } - - uint32_t const len = keySequence.Length() * 2 + aExtraInputsLen; - - // The `inputs` array is a sequence of input events that will happen - // serially. We set the array up so that each modifier key is pressed - // down, then the additional input events happen, - // then each modifier key is released in reverse order of when - // it was pressed down. We pass this array to `SendInput`. - // - // inputs[0]: modifier key (e.g. shift, ctrl, etc) down - // ... ... - // inputs[keySequence.Length()-1]: modifier key (e.g. shift, ctrl, etc) down - // inputs[keySequence.Length()]: aExtraInputs[0] - // inputs[keySequence.Length()+1]: aExtraInputs[1] - // ... ... - // inputs[keySequence.Length() + aExtraInputsLen - 1]: aExtraInputs[aExtraInputsLen - 1] - // inputs[keySequence.Length() + aExtraInputsLen]: modifier key (e.g. shift, ctrl, etc) up - // ... ... - // inputs[len-1]: modifier key (e.g. shift, ctrl, etc) up - INPUT* inputs = new INPUT[len]; - memset(inputs, 0, len * sizeof(INPUT)); - for (uint32_t i = 0; i < keySequence.Length(); ++i) { - inputs[i].type = inputs[len-i-1].type = INPUT_KEYBOARD; - inputs[i].ki.wVk = inputs[len-i-1].ki.wVk = keySequence[i].mSpecific - ? keySequence[i].mSpecific - : keySequence[i].mGeneral; - inputs[len-i-1].ki.dwFlags |= KEYEVENTF_KEYUP; - } - for (uint32_t i = 0; i < aExtraInputsLen; i++) { - inputs[keySequence.Length()+i] = aExtraInputs[i]; - } - WinUtils::Log(" Sending inputs"); - for (uint32_t i = 0; i < len; i++) { - if (inputs[i].type == INPUT_KEYBOARD) { - WinUtils::Log(" Key press: 0x%x %s", - inputs[i].ki.wVk, - inputs[i].ki.dwFlags & KEYEVENTF_KEYUP - ? "UP" - : "DOWN"); - } else if(inputs[i].type == INPUT_MOUSE) { - WinUtils::Log(" Mouse input: 0x%x 0x%x", - inputs[i].mi.dwFlags, - inputs[i].mi.mouseData); - } else { - WinUtils::Log(" Unknown input type!"); - } - } - ::SendInput(len, inputs, sizeof(INPUT)); - delete[] inputs; - - // The inputs have been sent, and the WM_* messages they generate are - // waiting to be processed by our event loop. Now we manually pump - // those messages so that, upon our return, all the inputs have been - // processed. - WinUtils::Log(" Inputs sent. Waiting for input messages to clear"); - MSG msg; - while (WinUtils::PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) { - if (nsTextStore::ProcessRawKeyMessage(msg)) { - continue; // the message is consumed by TSF - } - ::TranslateMessage(&msg); - ::DispatchMessage(&msg); - WinUtils::Log(" Dispatched 0x%x 0x%x 0x%x", msg.message, msg.wParam, msg.lParam); - } - WinUtils::Log(" No more input messages"); - } -} - -NS_IMPL_ISUPPORTS_INHERITED0(MetroWidget, nsBaseWidget) - -MetroWidget::MetroWidget() : - mTransparencyMode(eTransparencyOpaque), - mWnd(nullptr), - mMetroWndProc(nullptr), - mTempBasicLayerInUse(false), - mRootLayerTreeId(), - nsWindowBase() -{ - // Global initialization - if (!gInstanceCount) { - UserActivity(); - nsTextStore::Initialize(); - MouseScrollHandler::Initialize(); - KeyboardLayout::GetInstance()->OnLayoutChange(::GetKeyboardLayout(0)); - } // !gInstanceCount - gInstanceCount++; -} - -MetroWidget::~MetroWidget() -{ - LogThis(); - - gInstanceCount--; - - // Global shutdown - if (!gInstanceCount) { - APZController::sAPZC = nullptr; - nsTextStore::Terminate(); - } // !gInstanceCount -} - -static bool gTopLevelAssigned = false; -NS_IMETHODIMP -MetroWidget::Create(nsIWidget *aParent, - nsNativeWidget aNativeParent, - const nsIntRect &aRect, - nsWidgetInitData *aInitData) -{ - LogFunction(); - - nsWidgetInitData defaultInitData; - if (!aInitData) - aInitData = &defaultInitData; - - mWindowType = aInitData->mWindowType; - - // Ensure that the toolkit is created. - nsToolkit::GetToolkit(); - - BaseCreate(aParent, aRect, aInitData); - - if (mWindowType != eWindowType_toplevel) { - switch(mWindowType) { - case eWindowType_dialog: - WinUtils::Log("eWindowType_dialog window requested, returning failure."); - break; - case eWindowType_child: - WinUtils::Log("eWindowType_child window requested, returning failure."); - break; - case eWindowType_popup: - WinUtils::Log("eWindowType_popup window requested, returning failure."); - break; - case eWindowType_plugin: - WinUtils::Log("eWindowType_plugin window requested, returning failure."); - break; - // we should support toolkit's eWindowType_invisible at some point. - case eWindowType_invisible: - WinUtils::Log("eWindowType_invisible window requested, this doesn't actually exist!"); - return NS_OK; - } - NS_WARNING("Invalid window type requested."); - return NS_ERROR_FAILURE; - } - - if (gTopLevelAssigned) { - // Need to accept so that the mochitest-chrome test harness window - // can be created. - NS_WARNING("New eWindowType_toplevel window requested after FrameworkView widget created."); - NS_WARNING("Widget created but the physical window does not exist! Fix me!"); - return NS_OK; - } - - // the main widget gets created first - gTopLevelAssigned = true; - sMetroApp->SetWidget(this); - WinUtils::SetNSWindowBasePtr(mWnd, this); - - if (mWidgetListener) { - mWidgetListener->WindowActivated(); - } - - return NS_OK; -} - -void -MetroWidget::SetView(FrameworkView* aView) -{ - mView = aView; - // If we've already set this up, it points to a useless - // layer manager, so reset it. - mLayerManager = nullptr; -} - -NS_IMETHODIMP -MetroWidget::Destroy() -{ - if (mOnDestroyCalled) - return NS_OK; - WinUtils::Log("[%X] %s mWnd=%X type=%d", this, __FUNCTION__, mWnd, mWindowType); - mOnDestroyCalled = true; - - nsCOMPtr kungFuDeathGrip(this); - - if (ShouldUseAPZC()) { - nsresult rv; - nsCOMPtr observerService = do_GetService("@mozilla.org/observer-service;1", &rv); - if (NS_SUCCEEDED(rv)) { - observerService->RemoveObserver(this, "apzc-scroll-offset-changed"); - observerService->RemoveObserver(this, "apzc-zoom-to-rect"); - observerService->RemoveObserver(this, "apzc-disable-zoom"); - } - } - - RemoveSubclass(); - NotifyWindowDestroyed(); - - // Prevent the widget from sending additional events. - mWidgetListener = nullptr; - mAttachedWidgetListener = nullptr; - - // Release references to children, device context, toolkit, and app shell. - nsBaseWidget::Destroy(); - nsBaseWidget::OnDestroy(); - WinUtils::SetNSWindowBasePtr(mWnd, nullptr); - - if (mLayerManager) { - mLayerManager->Destroy(); - } - - mLayerManager = nullptr; - mView = nullptr; - mIdleService = nullptr; - mWnd = nullptr; - - return NS_OK; -} - -NS_IMETHODIMP -MetroWidget::SetParent(nsIWidget *aNewParent) -{ - return NS_OK; -} - -NS_IMETHODIMP -MetroWidget::Show(bool bState) -{ - return NS_OK; -} - -uint32_t -MetroWidget::GetMaxTouchPoints() const -{ - ComPtr deviceStatics; - - HRESULT hr = GetActivationFactory( - HStringReference(RuntimeClass_Windows_Devices_Input_PointerDevice).Get(), - deviceStatics.GetAddressOf()); - - if (FAILED(hr)) { - return 0; - } - - ComPtr< IVectorView > deviceList; - hr = deviceStatics->GetPointerDevices(&deviceList); - - if (FAILED(hr)) { - return 0; - } - - uint32_t deviceNum = 0; - deviceList->get_Size(&deviceNum); - - uint32_t maxTouchPoints = 0; - for (uint32_t index = 0; index < deviceNum; ++index) { - ComPtr device; - PointerDeviceType deviceType; - - if (FAILED(deviceList->GetAt(index, device.GetAddressOf()))) { - continue; - } - - if (FAILED(device->get_PointerDeviceType(&deviceType))) { - continue; - } - - if (deviceType == PointerDeviceType_Touch) { - uint32_t deviceMaxTouchPoints = 0; - device->get_MaxContacts(&deviceMaxTouchPoints); - maxTouchPoints = std::max(maxTouchPoints, deviceMaxTouchPoints); - } - } - - return maxTouchPoints; -} - -NS_IMETHODIMP -MetroWidget::IsVisible(bool & aState) -{ - aState = mView->IsVisible(); - return NS_OK; -} - -bool -MetroWidget::IsVisible() const -{ - if (!mView) - return false; - return mView->IsVisible(); -} - -NS_IMETHODIMP -MetroWidget::EnableDragDrop(bool aEnable) { - if (aEnable) { - if (nullptr == mNativeDragTarget) { - mNativeDragTarget = new nsNativeDragTarget(this); - if (!mNativeDragTarget) { - return NS_ERROR_FAILURE; - } - } - - HRESULT hr = ::RegisterDragDrop(mWnd, static_cast(mNativeDragTarget)); - return SUCCEEDED(hr) ? NS_OK : NS_ERROR_FAILURE; - } else { - if (nullptr == mNativeDragTarget) { - return NS_OK; - } - - HRESULT hr = ::RevokeDragDrop(mWnd); - return SUCCEEDED(hr) ? NS_OK : NS_ERROR_FAILURE; - } -} - -NS_IMETHODIMP -MetroWidget::IsEnabled(bool *aState) -{ - *aState = mView->IsEnabled(); - return NS_OK; -} - -bool -MetroWidget::IsEnabled() const -{ - if (!mView) - return false; - return mView->IsEnabled(); -} - -NS_IMETHODIMP -MetroWidget::Enable(bool bState) -{ - return NS_OK; -} - -NS_IMETHODIMP -MetroWidget::GetBounds(nsIntRect &aRect) -{ - if (mView) { - mView->GetBounds(aRect); - } else { - nsIntRect rect(0,0,0,0); - aRect = rect; - } - return NS_OK; -} - -NS_IMETHODIMP -MetroWidget::GetScreenBounds(nsIntRect &aRect) -{ - if (mView) { - mView->GetBounds(aRect); - } else { - nsIntRect rect(0,0,0,0); - aRect = rect; - } - return NS_OK; -} - -NS_IMETHODIMP -MetroWidget::GetClientBounds(nsIntRect &aRect) -{ - if (mView) { - mView->GetBounds(aRect); - } else { - nsIntRect rect(0,0,0,0); - aRect = rect; - } - return NS_OK; -} - -NS_IMETHODIMP -MetroWidget::SetCursor(nsCursor aCursor) -{ - if (!mView) - return NS_ERROR_FAILURE; - - switch (aCursor) { - case eCursor_select: - mView->SetCursor(CoreCursorType::CoreCursorType_IBeam); - break; - case eCursor_wait: - mView->SetCursor(CoreCursorType::CoreCursorType_Wait); - break; - case eCursor_hyperlink: - mView->SetCursor(CoreCursorType::CoreCursorType_Hand); - break; - case eCursor_standard: - mView->SetCursor(CoreCursorType::CoreCursorType_Arrow); - break; - case eCursor_n_resize: - case eCursor_s_resize: - mView->SetCursor(CoreCursorType::CoreCursorType_SizeNorthSouth); - break; - case eCursor_w_resize: - case eCursor_e_resize: - mView->SetCursor(CoreCursorType::CoreCursorType_SizeWestEast); - break; - case eCursor_nw_resize: - case eCursor_se_resize: - mView->SetCursor(CoreCursorType::CoreCursorType_SizeNorthwestSoutheast); - break; - case eCursor_ne_resize: - case eCursor_sw_resize: - mView->SetCursor(CoreCursorType::CoreCursorType_SizeNortheastSouthwest); - break; - case eCursor_crosshair: - mView->SetCursor(CoreCursorType::CoreCursorType_Cross); - break; - case eCursor_move: - mView->SetCursor(CoreCursorType::CoreCursorType_SizeAll); - break; - case eCursor_help: - mView->SetCursor(CoreCursorType::CoreCursorType_Help); - break; - // CSS3 custom cursors - case eCursor_copy: - mView->SetCursor(CoreCursorType::CoreCursorType_Custom, IDC_COPY); - break; - case eCursor_alias: - mView->SetCursor(CoreCursorType::CoreCursorType_Custom, IDC_ALIAS); - break; - case eCursor_cell: - mView->SetCursor(CoreCursorType::CoreCursorType_Custom, IDC_CELL); - break; - case eCursor_grab: - mView->SetCursor(CoreCursorType::CoreCursorType_Custom, IDC_GRAB); - break; - case eCursor_grabbing: - mView->SetCursor(CoreCursorType::CoreCursorType_Custom, IDC_GRABBING); - break; - case eCursor_spinning: - mView->SetCursor(CoreCursorType::CoreCursorType_Wait); - break; - case eCursor_context_menu: - mView->SetCursor(CoreCursorType::CoreCursorType_Arrow); - break; - case eCursor_zoom_in: - mView->SetCursor(CoreCursorType::CoreCursorType_Custom, IDC_ZOOMIN); - break; - case eCursor_zoom_out: - mView->SetCursor(CoreCursorType::CoreCursorType_Custom, IDC_ZOOMOUT); - break; - case eCursor_not_allowed: - case eCursor_no_drop: - mView->SetCursor(CoreCursorType::CoreCursorType_UniversalNo); - break; - case eCursor_col_resize: - mView->SetCursor(CoreCursorType::CoreCursorType_Custom, IDC_COLRESIZE); - break; - case eCursor_row_resize: - mView->SetCursor(CoreCursorType::CoreCursorType_Custom, IDC_ROWRESIZE); - break; - case eCursor_vertical_text: - mView->SetCursor(CoreCursorType::CoreCursorType_Custom, IDC_VERTICALTEXT); - break; - case eCursor_all_scroll: - mView->SetCursor(CoreCursorType::CoreCursorType_SizeAll); - break; - case eCursor_nesw_resize: - mView->SetCursor(CoreCursorType::CoreCursorType_SizeNortheastSouthwest); - break; - case eCursor_nwse_resize: - mView->SetCursor(CoreCursorType::CoreCursorType_SizeNorthwestSoutheast); - break; - case eCursor_ns_resize: - mView->SetCursor(CoreCursorType::CoreCursorType_SizeNorthSouth); - break; - case eCursor_ew_resize: - mView->SetCursor(CoreCursorType::CoreCursorType_SizeWestEast); - break; - case eCursor_none: - mView->ClearCursor(); - break; - default: - NS_WARNING("Invalid cursor type"); - break; - } - return NS_OK; -} - -nsresult -MetroWidget::SynthesizeNativeKeyEvent(int32_t aNativeKeyboardLayout, - int32_t aNativeKeyCode, - uint32_t aModifierFlags, - const nsAString& aCharacters, - const nsAString& aUnmodifiedCharacters, - nsIObserver* aObserver) -{ - AutoObserverNotifier notifier(aObserver, "keyevent"); - KeyboardLayout* keyboardLayout = KeyboardLayout::GetInstance(); - return keyboardLayout->SynthesizeNativeKeyEvent( - this, aNativeKeyboardLayout, aNativeKeyCode, aModifierFlags, - aCharacters, aUnmodifiedCharacters); -} - -nsresult -MetroWidget::SynthesizeNativeMouseEvent(LayoutDeviceIntPoint aPoint, - uint32_t aNativeMessage, - uint32_t aModifierFlags, - nsIObserver* aObserver) -{ - WinUtils::Log("ENTERED SynthesizeNativeMouseEvent"); - - AutoObserverNotifier notifier(aObserver, "mouseevent"); - INPUT inputs[2]; - memset(inputs, 0, 2*sizeof(INPUT)); - inputs[0].type = inputs[1].type = INPUT_MOUSE; - inputs[0].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE; - // Inexplicably, the x and y coordinates that we want to move the mouse to - // are specified as values in the range (0, 65535). (0,0) represents the - // top left of the primary monitor and (65535, 65535) represents the - // bottom right of the primary monitor. - inputs[0].mi.dx = (aPoint.x * 65535) / ::GetSystemMetrics(SM_CXSCREEN); - inputs[0].mi.dy = (aPoint.y * 65535) / ::GetSystemMetrics(SM_CYSCREEN); - inputs[1].mi.dwFlags = aNativeMessage; - SendInputs(aModifierFlags, inputs, 2); - - WinUtils::Log("Exiting SynthesizeNativeMouseEvent"); - return NS_OK; -} - -nsresult -MetroWidget::SynthesizeNativeMouseScrollEvent(LayoutDeviceIntPoint aPoint, - uint32_t aNativeMessage, - double aDeltaX, - double aDeltaY, - double aDeltaZ, - uint32_t aModifierFlags, - uint32_t aAdditionalFlags - nsIObserver* aObserver) -{ - AutoObserverNotifier notifier(aObserver, "mousescrollevent"); - return MouseScrollHandler::SynthesizeNativeMouseScrollEvent( - this, aPoint, aNativeMessage, - (aNativeMessage == WM_MOUSEWHEEL || aNativeMessage == WM_VSCROLL) ? - static_cast(aDeltaY) : static_cast(aDeltaX), - aModifierFlags, aAdditionalFlags); -} - -static void -CloseGesture() -{ - LogFunction(); - nsCOMPtr appStartup = - do_GetService(NS_APPSTARTUP_CONTRACTID); - if (appStartup) { - appStartup->Quit(nsIAppStartup::eForceQuit); - } -} - -// Async event sending for mouse and keyboard input. - -// defined in nsWindowBase, called from shared module WinMouseScrollHandler. -bool -MetroWidget::DispatchWheelEvent(mozilla::WidgetWheelEvent* aEvent) -{ - WidgetWheelEvent* wheelEvent = - new WidgetWheelEvent(aEvent->mFlags.mIsTrusted, aEvent->message, aEvent->widget); - wheelEvent->AssignWheelEventData(*aEvent, true); - mEventQueue.Push(wheelEvent); - nsCOMPtr runnable = - NS_NewRunnableMethod(this, &MetroWidget::DeliverNextScrollEvent); - NS_DispatchToCurrentThread(runnable); - return false; -} - -bool -MetroWidget::DispatchContentCommandEvent(mozilla::WidgetGUIEvent* aEvent) -{ - WidgetContentCommandEvent* cmdEvent = - new WidgetContentCommandEvent(aEvent->mFlags.mIsTrusted, aEvent->message, aEvent->widget); - cmdEvent->AssignContentCommandEventData(*aEvent, true); - mEventQueue.Push(cmdEvent); - nsCOMPtr runnable = - NS_NewRunnableMethod(this, &MetroWidget::DeliverNextScrollEvent); - NS_DispatchToCurrentThread(runnable); - return false; -} - -void -MetroWidget::DeliverNextScrollEvent() -{ - WidgetGUIEvent* event = - static_cast(mEventQueue.PopFront()); - DispatchWindowEvent(event); - delete event; -} - -// defined in nsWindowBase, called from shared module KeyboardLayout. -bool -MetroWidget::DispatchKeyboardEvent(WidgetKeyboardEvent* aEvent) -{ - MOZ_ASSERT(aEvent); - WidgetKeyboardEvent* keyEvent = - new WidgetKeyboardEvent(aEvent->mFlags.mIsTrusted, - aEvent->message, aEvent->widget); - // XXX note this leaves pluginEvent null, which is fine for now. - keyEvent->AssignKeyEventData(*aEvent, true); - mKeyEventQueue.Push(keyEvent); - nsCOMPtr runnable = - NS_NewRunnableMethod(this, &MetroWidget::DeliverNextKeyboardEvent); - NS_DispatchToCurrentThread(runnable); - return false; -} - -// Used in conjunction with mKeyEventQueue to find a keypress event -// that should not be delivered due to the return result of the -// preceeding keydown. -class KeyQueryIdAndCancel : public nsDequeFunctor { -public: - KeyQueryIdAndCancel(uint32_t aIdToCancel) : - mId(aIdToCancel) { - } - virtual void* operator() (void* aObject) { - WidgetKeyboardEvent* event = static_cast(aObject); - if (event->mUniqueId == mId) { - event->mFlags.mPropagationStopped = true; - } - return nullptr; - } -protected: - uint32_t mId; -}; - -void -MetroWidget::DeliverNextKeyboardEvent() -{ - WidgetKeyboardEvent* event = - static_cast(mKeyEventQueue.PopFront()); - if (event->mFlags.mPropagationStopped) { - // This can happen if a keypress was previously cancelled. - delete event; - return; - } - - if (DispatchWindowEvent(event) && event->message == NS_KEY_DOWN) { - // keydown events may be followed by multiple keypress events which - // shouldn't be sent if preventDefault is called on keydown. - KeyQueryIdAndCancel query(event->mUniqueId); - mKeyEventQueue.ForEach(query); - } - delete event; -} - -// static -LRESULT CALLBACK -MetroWidget::StaticWindowProcedure(HWND aWnd, UINT aMsg, WPARAM aWParam, LPARAM aLParam) -{ - MetroWidget* self = reinterpret_cast( - GetProp(aWnd, kMetroSubclassThisProp)); - if (!self) { - NS_NOTREACHED("Missing 'this' prop on subclassed metro window, this is bad."); - return 0; - } - return self->WindowProcedure(aWnd, aMsg, aWParam, aLParam); -} - -LRESULT -MetroWidget::WindowProcedure(HWND aWnd, UINT aMsg, WPARAM aWParam, LPARAM aLParam) -{ - if(sDefaultBrowserMsgId == aMsg) { - CloseGesture(); - } else if (WM_SETTINGCHANGE == aMsg) { - if (aLParam && !wcsicmp(L"ConvertibleSlateMode", (wchar_t*)aLParam)) { - // If we're switching away from slate mode, switch to Desktop for - // hardware that supports this feature if the pref is set. - if (GetSystemMetrics(SM_CONVERTIBLESLATEMODE) != 0 && - Preferences::GetBool("browser.shell.metro-auto-switch-enabled", - false)) { - nsCOMPtr appStartup(do_GetService(NS_APPSTARTUP_CONTRACTID)); - if (appStartup) { - appStartup->Quit(nsIAppStartup::eForceQuit | nsIAppStartup::eRestart); - } - } - } - } - - // Indicates if we should hand messages to the default windows - // procedure for processing. - bool processDefault = true; - - // The result returned if we do not do default processing. - LRESULT processResult = 0; - - MSGResult msgResult(&processResult); - MouseScrollHandler::ProcessMessage(this, aMsg, aWParam, aLParam, msgResult); - if (msgResult.mConsumed) { - return processResult; - } - - nsTextStore::ProcessMessage(this, aMsg, aWParam, aLParam, msgResult); - if (msgResult.mConsumed) { - return processResult; - } - - switch (aMsg) { - case WM_POWERBROADCAST: - { - switch (aWParam) - { - case PBT_APMSUSPEND: - MetroApp::PostSleepWakeNotification(true); - break; - case PBT_APMRESUMEAUTOMATIC: - case PBT_APMRESUMECRITICAL: - case PBT_APMRESUMESUSPEND: - MetroApp::PostSleepWakeNotification(false); - break; - } - break; - } - - // Keyboard handling is passed to KeyboardLayout, which delivers gecko events - // via DispatchKeyboardEvent. - - case WM_KEYDOWN: - case WM_SYSKEYDOWN: - { - MSG msg = WinUtils::InitMSG(aMsg, aWParam, aLParam, aWnd); - // If this method doesn't call NativeKey::HandleKeyDownMessage(), this - // method must clean up the redirected message information itself. For - // more information, see above comment of - // RedirectedKeyDownMessageManager::AutoFlusher class definition in - // KeyboardLayout.h. - RedirectedKeyDownMessageManager::AutoFlusher - redirectedMsgFlusher(this, msg); - - if (nsTextStore::IsComposingOn(this)) { - break; - } - - ModifierKeyState modKeyState; - NativeKey nativeKey(this, msg, modKeyState); - processDefault = !nativeKey.HandleKeyDownMessage(); - // HandleKeyDownMessage cleaned up the redirected message information - // itself, so, we should do nothing. - redirectedMsgFlusher.Cancel(); - break; - } - - case WM_KEYUP: - case WM_SYSKEYUP: - { - if (nsTextStore::IsComposingOn(this)) { - break; - } - - MSG msg = WinUtils::InitMSG(aMsg, aWParam, aLParam, aWnd); - ModifierKeyState modKeyState; - NativeKey nativeKey(this, msg, modKeyState); - processDefault = !nativeKey.HandleKeyUpMessage(); - break; - } - - case WM_CHAR: - case WM_SYSCHAR: - { - if (nsTextStore::IsComposingOn(this)) { - nsTextStore::CommitComposition(false); - } - - MSG msg = WinUtils::InitMSG(aMsg, aWParam, aLParam, aWnd); - ModifierKeyState modKeyState; - NativeKey nativeKey(this, msg, modKeyState); - processDefault = !nativeKey.HandleCharMessage(msg); - break; - } - - case WM_INPUTLANGCHANGE: - { - KeyboardLayout::GetInstance()-> - OnLayoutChange(reinterpret_cast(aLParam)); - processResult = 1; - break; - } - - case WM_APPCOMMAND: - { - MSG msg = WinUtils::InitMSG(aMsg, aWParam, aLParam, aWnd); - processDefault = HandleAppCommandMsg(msg, &processResult); - break; - } - - case WM_GETOBJECT: - { - DWORD dwObjId = (LPARAM)(DWORD) aLParam; - // Passing this to CallWindowProc can result in a failure due to a timing issue - // in winrt core window server code, so we call it directly here. Also, it's not - // clear Windows::UI::Core::WindowServer::OnAutomationProviderRequestedEvent is - // compatible with metro enabled desktop browsers, it makes an initial call to - // UiaReturnRawElementProvider passing the return result from FrameworkView - // OnAutomationProviderRequested as the hwnd (me scratches head) which results in - // GetLastError always being set to invalid handle (6) after CallWindowProc returns. - if (dwObjId == MOZOBJID_UIAROOT && gProviderRoot) { - ComPtr simple; - gProviderRoot.As(&simple); - if (simple) { - LRESULT res = UiaReturnRawElementProvider(aWnd, aWParam, aLParam, simple.Get()); - if (res) { - return res; - } - NS_ASSERTION(res, "UiaReturnRawElementProvider failed!"); - WinUtils::Log("UiaReturnRawElementProvider failed! GetLastError=%X", GetLastError()); - } - } - break; - } - - default: - { - break; - } - } - - if (processDefault) { - return CallWindowProc(mMetroWndProc, aWnd, aMsg, aWParam, - aLParam); - } - return processResult; -} - -static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) -{ - WCHAR className[56]; - if (GetClassNameW(hwnd, className, sizeof(className)/sizeof(WCHAR)) && - !wcscmp(L"Windows.UI.Core.CoreWindow", className)) { - DWORD processID = 0; - GetWindowThreadProcessId(hwnd, &processID); - if (processID && processID == GetCurrentProcessId()) { - *((HWND*)lParam) = hwnd; - return FALSE; - } - } - return TRUE; -} - -void -MetroWidget::FindMetroWindow() -{ - LogFunction(); - if (mWnd) - return; - EnumWindows(EnumWindowsProc, (LPARAM)&mWnd); - NS_ASSERTION(mWnd, "Couldn't find our metro CoreWindow, this is bad."); - - // subclass it - SetSubclass(); - sICoreHwnd = mWnd; - return; -} - -void -MetroWidget::SetSubclass() -{ - if (!mWnd) { - NS_NOTREACHED("SetSubclass called without a valid hwnd."); - return; - } - - WNDPROC wndProc = reinterpret_cast( - GetWindowLongPtr(mWnd, GWLP_WNDPROC)); - if (wndProc != StaticWindowProcedure) { - if (!SetPropW(mWnd, kMetroSubclassThisProp, this)) { - NS_NOTREACHED("SetProp failed, can't continue."); - return; - } - mMetroWndProc = - reinterpret_cast( - SetWindowLongPtr(mWnd, GWLP_WNDPROC, - reinterpret_cast(StaticWindowProcedure))); - NS_ASSERTION(mMetroWndProc != StaticWindowProcedure, "WTF?"); - } -} - -void -MetroWidget::RemoveSubclass() -{ - if (!mWnd) - return; - WNDPROC wndProc = reinterpret_cast( - GetWindowLongPtr(mWnd, GWLP_WNDPROC)); - if (wndProc == StaticWindowProcedure) { - NS_ASSERTION(mMetroWndProc, "Should have old proc here."); - SetWindowLongPtr(mWnd, GWLP_WNDPROC, - reinterpret_cast(mMetroWndProc)); - mMetroWndProc = nullptr; - } - RemovePropW(mWnd, kMetroSubclassThisProp); -} - -bool -MetroWidget::ShouldUseOffMainThreadCompositing() -{ - // Either we're not initialized yet, or this is the toolkit widget - if (!mView) { - return false; - } - // toolkit or test widgets can't use omtc, they don't have ICoreWindow. - return gfxPlatform::UsesOffMainThreadCompositing() && - mWindowType == eWindowType_toplevel; -} - -bool -MetroWidget::ShouldUseBasicManager() -{ - // toolkit or test widgets fall back on empty shadow layers - return (mWindowType != eWindowType_toplevel); -} - -bool -MetroWidget::ShouldUseAPZC() -{ - return gfxPrefs::AsyncPanZoomEnabled(); -} - -void -MetroWidget::SetWidgetListener(nsIWidgetListener* aWidgetListener) -{ - mWidgetListener = aWidgetListener; -} - -void -MetroWidget::ConfigureAPZCTreeManager() -{ - nsBaseWidget::ConfigureAPZCTreeManager(); - - nsresult rv; - nsCOMPtr observerService = do_GetService("@mozilla.org/observer-service;1", &rv); - if (NS_SUCCEEDED(rv)) { - observerService->AddObserver(this, "apzc-scroll-offset-changed", false); - observerService->AddObserver(this, "apzc-zoom-to-rect", false); - observerService->AddObserver(this, "apzc-disable-zoom", false); - } -} - -already_AddRefed -MetroWidget::CreateRootContentController() -{ - MOZ_ASSERT(!mController); - - mController = new APZController(); - return mController; -} - -MetroWidget::TouchBehaviorFlags -MetroWidget::ContentGetAllowedTouchBehavior(const LayoutDeviceIntPoint& aPoint) -{ - return ContentHelper::GetAllowedTouchBehavior(this, aPoint); -} - -void -MetroWidget::ApzcSetAllowedTouchBehavior(uint64_t aInputBlockId, - nsTArray& aBehaviors) -{ - LogFunction(); - if (!APZController::sAPZC) { - return; - } - APZController::sAPZC->SetAllowedTouchBehavior(aInputBlockId, aBehaviors); -} - -void -MetroWidget::ApzContentConsumingTouch(uint64_t aInputBlockId) -{ - LogFunction(); - if (!mController) { - return; - } - mController->ContentReceivedInputBlock(aInputBlockId, true); -} - -void -MetroWidget::ApzContentIgnoringTouch(uint64_t aInputBlockId) -{ - LogFunction(); - if (!mController) { - return; - } - mController->ContentReceivedInputBlock(aInputBlockId, false); -} - -bool -MetroWidget::ApzHitTest(ScreenIntPoint& pt) -{ - if (!mController) { - return false; - } - return mController->HitTestAPZC(pt); -} - -void -MetroWidget::ApzTransformGeckoCoordinate(const ScreenIntPoint& aPoint, - LayoutDeviceIntPoint* aRefPointOut) -{ - if (!mController) { - return; - } - mController->TransformCoordinateToGecko(aPoint, aRefPointOut); -} - -nsEventStatus -MetroWidget::ApzReceiveInputEvent(WidgetInputEvent* aEvent, - ScrollableLayerGuid* aOutTargetGuid, - uint64_t* aOutInputBlockId) -{ - MOZ_ASSERT(aEvent); - - if (!mController) { - return nsEventStatus_eIgnore; - } - return mController->ReceiveInputEvent(aEvent, aOutTargetGuid, aOutInputBlockId); -} - -void -MetroWidget::SetApzPendingResponseFlusher(APZPendingResponseFlusher* aFlusher) -{ - mController->SetPendingResponseFlusher(aFlusher); -} - -LayerManager* -MetroWidget::GetLayerManager(PLayerTransactionChild* aShadowManager, - LayersBackend aBackendHint, - LayerManagerPersistence aPersistence, - bool* aAllowRetaining) -{ - bool retaining = true; - - // If we initialized earlier than the view, recreate the layer manager now - if (mLayerManager && - mTempBasicLayerInUse && - ShouldUseOffMainThreadCompositing()) { - mLayerManager = nullptr; - mTempBasicLayerInUse = false; - retaining = false; - } - - HRESULT hr = S_OK; - - // Create a layer manager: try to use an async compositor first, if enabled. - // Otherwise fall back on the main thread d3d manager. - if (!mLayerManager) { - if (ShouldUseOffMainThreadCompositing()) { - NS_ASSERTION(aShadowManager == nullptr, "Async Compositor not supported with e10s"); - CreateCompositor(); - } else { - mLayerManager = CreateBasicLayerManager(); - } - // Either we're not ready to initialize yet due to a missing view pointer, - // or something has gone wrong. - if (!mLayerManager) { - if (!mView) { - NS_WARNING("Using temporary basic layer manager."); - mLayerManager = new BasicLayerManager(this); - mTempBasicLayerInUse = true; - } else { -#ifdef MOZ_CRASHREPORTER - if (FAILED(hr)) { - char errorBuf[10]; - errorBuf[0] = '\0'; - _snprintf_s(errorBuf, sizeof(errorBuf), _TRUNCATE, "%X", hr); - CrashReporter:: - AnnotateCrashReport(NS_LITERAL_CSTRING("HRESULT"), - nsDependentCString(errorBuf)); - } -#endif - NS_RUNTIMEABORT("Couldn't create layer manager"); - } - } - } - - if (aAllowRetaining) { - *aAllowRetaining = retaining; - } - - return mLayerManager; -} - -NS_IMETHODIMP -MetroWidget::Invalidate(bool aEraseBackground, - bool aUpdateNCArea, - bool aIncludeChildren) -{ - nsIntRect rect; - if (mView) { - mView->GetBounds(rect); - } - Invalidate(rect); - return NS_OK; -} - -NS_IMETHODIMP -MetroWidget::Invalidate(const nsIntRect & aRect) -{ - if (mWnd) { - RECT rect; - rect.left = aRect.x; - rect.top = aRect.y; - rect.right = aRect.x + aRect.width; - rect.bottom = aRect.y + aRect.height; - InvalidateRect(mWnd, &rect, FALSE); - } - - return NS_OK; -} - -nsTransparencyMode -MetroWidget::GetTransparencyMode() -{ - return mTransparencyMode; -} - -void -MetroWidget::SetTransparencyMode(nsTransparencyMode aMode) -{ - mTransparencyMode = aMode; -} - -nsIWidgetListener* -MetroWidget::GetPaintListener() -{ - if (mOnDestroyCalled) - return nullptr; - return mAttachedWidgetListener ? mAttachedWidgetListener : - mWidgetListener; -} - -void MetroWidget::Paint(const nsIntRegion& aInvalidRegion) -{ - gfxWindowsPlatform::GetPlatform()->UpdateRenderMode(); - - nsIWidgetListener* listener = GetPaintListener(); - if (!listener) - return; - - listener->WillPaintWindow(this); - - // Refresh since calls like WillPaintWindow can destroy the widget - listener = GetPaintListener(); - if (!listener) - return; - - listener->PaintWindow(this, aInvalidRegion); - - listener = GetPaintListener(); - if (!listener) - return; - - listener->DidPaintWindow(); -} - -void MetroWidget::UserActivity() -{ - // Check if we have the idle service, if not we try to get it. - if (!mIdleService) { - mIdleService = do_GetService("@mozilla.org/widget/idleservice;1"); - } - - // Check that we now have the idle service. - if (mIdleService) { - mIdleService->ResetIdleTimeOut(0); - } -} - -// InitEvent assumes physical coordinates and is used by shared win32 code. Do -// not hand winrt event coordinates to this routine. -void -MetroWidget::InitEvent(WidgetGUIEvent& event, nsIntPoint* aPoint) -{ - if (!aPoint) { - event.refPoint.x = event.refPoint.y = 0; - } else { - event.refPoint.x = aPoint->x; - event.refPoint.y = aPoint->y; - } - event.time = ::GetMessageTime(); -} - -bool -MetroWidget::DispatchWindowEvent(WidgetGUIEvent* aEvent) -{ - MOZ_ASSERT(aEvent); - nsEventStatus status = nsEventStatus_eIgnore; - DispatchEvent(aEvent, status); - return (status == nsEventStatus_eConsumeNoDefault); -} - -NS_IMETHODIMP -MetroWidget::DispatchEvent(WidgetGUIEvent* event, nsEventStatus & aStatus) -{ - if (event->AsInputEvent()) { - UserActivity(); - } - - aStatus = nsEventStatus_eIgnore; - - // Top level windows can have a view attached which requires events be sent - // to the underlying base window and the view. Added when we combined the - // base chrome window with the main content child for nc client area (title - // bar) rendering. - if (mAttachedWidgetListener) { - aStatus = mAttachedWidgetListener->HandleEvent(event, mUseAttachedEvents); - } - else if (mWidgetListener) { - aStatus = mWidgetListener->HandleEvent(event, mUseAttachedEvents); - } - - // the window can be destroyed during processing of seemingly innocuous events like, say, - // mousedowns due to the magic of scripting. mousedowns will return nsEventStatus_eIgnore, - // which causes problems with the deleted window. therefore: - if (mOnDestroyCalled) - aStatus = nsEventStatus_eConsumeNoDefault; - return NS_OK; -} - -#ifdef ACCESSIBILITY -mozilla::a11y::Accessible* -MetroWidget::GetAccessible() -{ - // We want the ability to forcibly disable a11y on windows, because - // some non-a11y-related components attempt to bring it up. See bug - // 538530 for details; we have a pref here that allows it to be disabled - // for performance and testing resons. - // - // This pref is checked only once, and the browser needs a restart to - // pick up any changes. - static int accForceDisable = -1; - - if (accForceDisable == -1) { - const char* kPrefName = "accessibility.win32.force_disabled"; - if (Preferences::GetBool(kPrefName, false)) { - accForceDisable = 1; - } else { - accForceDisable = 0; - } - } - - // If the pref was true, return null here, disabling a11y. - if (accForceDisable) - return nullptr; - - return GetRootAccessible(); -} -#endif - -double -MetroWidget::GetDefaultScaleInternal() -{ - return MetroUtils::ScaleFactor(); -} - -LayoutDeviceIntPoint -MetroWidget::CSSIntPointToLayoutDeviceIntPoint(const CSSIntPoint &aCSSPoint) -{ - CSSToLayoutDeviceScale scale = GetDefaultScale(); - LayoutDeviceIntPoint devPx(int32_t(NS_round(scale.scale * aCSSPoint.x)), - int32_t(NS_round(scale.scale * aCSSPoint.y))); - return devPx; -} - -float -MetroWidget::GetDPI() -{ - if (!mView) { - return 96.0; - } - return mView->GetDPI(); -} - -void -MetroWidget::ChangedDPI() -{ - if (mWidgetListener) { - nsIPresShell* presShell = mWidgetListener->GetPresShell(); - if (presShell) { - presShell->BackingScaleFactorChanged(); - } - } -} - -already_AddRefed -MetroWidget::GetPresShell() -{ - if (mWidgetListener) { - nsCOMPtr ps = mWidgetListener->GetPresShell(); - return ps.forget(); - } - return nullptr; -} - -NS_IMETHODIMP -MetroWidget::ConstrainPosition(bool aAllowSlop, int32_t *aX, int32_t *aY) -{ - return NS_OK; -} - -void -MetroWidget::SizeModeChanged() -{ - if (mWidgetListener) { - mWidgetListener->SizeModeChanged(nsSizeMode_Normal); - } -} - -void -MetroWidget::Activated(bool aActiveated) -{ - if (mWidgetListener) { - aActiveated ? - mWidgetListener->WindowActivated() : - mWidgetListener->WindowDeactivated(); - } -} - -NS_IMETHODIMP -MetroWidget::Move(double aX, double aY) -{ - NotifyWindowMoved(aX, aY); - return NS_OK; -} - -NS_IMETHODIMP -MetroWidget::Resize(double aWidth, double aHeight, bool aRepaint) -{ - return Resize(0, 0, aWidth, aHeight, aRepaint); -} - -NS_IMETHODIMP -MetroWidget::Resize(double aX, double aY, double aWidth, double aHeight, bool aRepaint) -{ - WinUtils::Log("Resize: %f %f %f %f", aX, aY, aWidth, aHeight); - if (mAttachedWidgetListener) { - mAttachedWidgetListener->WindowResized(this, aWidth, aHeight); - } - if (mWidgetListener) { - mWidgetListener->WindowResized(this, aWidth, aHeight); - } - Invalidate(); - return NS_OK; -} - -NS_IMETHODIMP -MetroWidget::SetFocus(bool aRaise) -{ - return NS_OK; -} - -nsresult -MetroWidget::ConfigureChildren(const nsTArray& aConfigurations) -{ - return NS_OK; -} - -void* -MetroWidget::GetNativeData(uint32_t aDataType) -{ - switch(aDataType) { - case NS_NATIVE_WINDOW: - return mWnd; - case NS_NATIVE_ICOREWINDOW: - if (mView) { - return reinterpret_cast(mView->GetCoreWindow()); - } - break; - case NS_NATIVE_TSF_THREAD_MGR: - case NS_NATIVE_TSF_CATEGORY_MGR: - case NS_NATIVE_TSF_DISPLAY_ATTR_MGR: - return nsTextStore::GetNativeData(aDataType); - } - return nullptr; -} - -void -MetroWidget::FreeNativeData(void * data, uint32_t aDataType) -{ -} - -NS_IMETHODIMP -MetroWidget::SetTitle(const nsAString& aTitle) -{ - return NS_OK; -} - -LayoutDeviceIntPoint -MetroWidget::WidgetToScreenOffset() -{ - return LayoutDeviceIntPoint(0,0); -} - -NS_IMETHODIMP -MetroWidget::CaptureRollupEvents(nsIRollupListener * aListener, - bool aDoCapture) -{ - return NS_OK; -} - -NS_IMETHODIMP_(void) -MetroWidget::SetInputContext(const InputContext& aContext, - const InputContextAction& aAction) -{ - // XXX This should set mInputContext.mNativeIMEContext properly - mInputContext = aContext; - nsTextStore::SetInputContext(this, mInputContext, aAction); - bool enable = (mInputContext.mIMEState.mEnabled == IMEState::ENABLED || - mInputContext.mIMEState.mEnabled == IMEState::PLUGIN); - if (enable && - mInputContext.mIMEState.mOpen != IMEState::DONT_CHANGE_OPEN_STATE) { - bool open = (mInputContext.mIMEState.mOpen == IMEState::OPEN); - nsTextStore::SetIMEOpenState(open); - } -} - -NS_IMETHODIMP_(nsIWidget::InputContext) -MetroWidget::GetInputContext() -{ - return mInputContext; -} - -nsresult -MetroWidget::NotifyIMEInternal(const IMENotification& aIMENotification) -{ - switch (aIMENotification.mMessage) { - case REQUEST_TO_COMMIT_COMPOSITION: - nsTextStore::CommitComposition(false); - return NS_OK; - case REQUEST_TO_CANCEL_COMPOSITION: - nsTextStore::CommitComposition(true); - return NS_OK; - case NOTIFY_IME_OF_FOCUS: - return nsTextStore::OnFocusChange(true, this, mInputContext); - case NOTIFY_IME_OF_BLUR: - return nsTextStore::OnFocusChange(false, this, mInputContext); - case NOTIFY_IME_OF_SELECTION_CHANGE: - return nsTextStore::OnSelectionChange(); - case NOTIFY_IME_OF_TEXT_CHANGE: - return nsTextStore::OnTextChange(aIMENotification); - case NOTIFY_IME_OF_POSITION_CHANGE: - return nsTextStore::OnLayoutChange(); - case NOTIFY_IME_OF_MOUSE_BUTTON_EVENT: - return nsTextStore::OnMouseButtonEvent(aIMENotification); - default: - return NS_ERROR_NOT_IMPLEMENTED; - } -} - -NS_IMETHODIMP -MetroWidget::GetToggledKeyState(uint32_t aKeyCode, bool* aLEDState) -{ - NS_ENSURE_ARG_POINTER(aLEDState); - *aLEDState = (::GetKeyState(aKeyCode) & 1) != 0; - return NS_OK; -} - -nsIMEUpdatePreference -MetroWidget::GetIMEUpdatePreference() -{ - return nsTextStore::GetIMEUpdatePreference(); -} - -NS_IMETHODIMP -MetroWidget::ReparentNativeWidget(nsIWidget* aNewParent) -{ - return NS_OK; -} - -void -MetroWidget::SuppressBlurEvents(bool aSuppress) -{ -} - -bool -MetroWidget::BlurEventsSuppressed() -{ - return false; -} - -void -MetroWidget::PickerOpen() -{ -} - -void -MetroWidget::PickerClosed() -{ -} - -bool -MetroWidget::HasPendingInputEvent() -{ - if (HIWORD(GetQueueStatus(QS_INPUT))) - return true; - return false; -} - -NS_IMETHODIMP -MetroWidget::Observe(nsISupports *subject, const char *topic, const char16_t *data) -{ - NS_ENSURE_ARG_POINTER(topic); - if (!strcmp(topic, "apzc-zoom-to-rect")) { - CSSRect rect = CSSRect(); - uint64_t viewId = 0; - int32_t presShellId = 0; - - int reScan = swscanf(data, L"%f,%f,%f,%f,%d,%llu", - &rect.x, &rect.y, &rect.width, &rect.height, - &presShellId, &viewId); - if(reScan != 6) { - NS_WARNING("Malformed apzc-zoom-to-rect message"); - } - - ScrollableLayerGuid guid = ScrollableLayerGuid(mRootLayerTreeId, presShellId, viewId); - APZController::sAPZC->ZoomToRect(guid, rect); - } - else if (!strcmp(topic, "apzc-disable-zoom")) { - uint64_t viewId = 0; - int32_t presShellId = 0; - - int reScan = swscanf(data, L"%d,%llu", - &presShellId, &viewId); - if (reScan != 2) { - NS_WARNING("Malformed apzc-disable-zoom message"); - } - - ScrollableLayerGuid guid = ScrollableLayerGuid(mRootLayerTreeId, presShellId, viewId); - APZController::sAPZC->UpdateZoomConstraints(guid, - ZoomConstraints(false, false, CSSToScreenScale(1.0f), CSSToScreenScale(1.0f))); - } - return NS_OK; -} diff --git a/widget/windows/winrt/MetroWidget.h b/widget/windows/winrt/MetroWidget.h deleted file mode 100644 index 6b4d36db095..00000000000 --- a/widget/windows/winrt/MetroWidget.h +++ /dev/null @@ -1,280 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#pragma once - -#include "nscore.h" -#include "nsdefs.h" -#include "prlog.h" -#include "nsAutoPtr.h" -#include "nsBaseWidget.h" -#include "nsWindowBase.h" -#include "nsString.h" -#include "nsTArray.h" -#include "nsWindowDbg.h" -#include "WindowHook.h" -#include "TaskbarWindowPreview.h" -#include "nsIdleService.h" -#ifdef ACCESSIBILITY -#include "mozilla/a11y/Accessible.h" -#endif -#include "mozilla/EventForwards.h" -#include "mozilla/layers/CompositorParent.h" -#include "mozilla/layers/LayerManagerComposite.h" -#include "nsDeque.h" -#include "APZController.h" - -#include "mozwrlbase.h" - -#include -#include -#include -#include -#include - -class nsNativeDragTarget; - -namespace mozilla { -namespace widget { -namespace winrt { - -class APZPendingResponseFlusher; -class FrameworkView; - -} } } - -class DispatchMsg; - -class MetroWidget : public nsWindowBase, - public nsIObserver -{ - typedef uint32_t TouchBehaviorFlags; - - typedef mozilla::widget::WindowHook WindowHook; - typedef mozilla::widget::TaskbarWindowPreview TaskbarWindowPreview; - typedef ABI::Windows::UI::Input::IPointerPoint IPointerPoint; - typedef ABI::Windows::UI::Core::IPointerEventArgs IPointerEventArgs; - typedef ABI::Windows::UI::Core::IKeyEventArgs IKeyEventArgs; - typedef ABI::Windows::UI::Core::ICharacterReceivedEventArgs ICharacterReceivedEventArgs; - typedef mozilla::widget::winrt::FrameworkView FrameworkView; - typedef mozilla::widget::winrt::APZController APZController; - typedef mozilla::widget::winrt::APZPendingResponseFlusher APZPendingResponseFlusher; - typedef mozilla::layers::ScrollableLayerGuid ScrollableLayerGuid; - - static LRESULT CALLBACK - StaticWindowProcedure(HWND aWnd, UINT aMsg, WPARAM aWParan, LPARAM aLParam); - LRESULT WindowProcedure(HWND aWnd, UINT aMsg, WPARAM aWParan, LPARAM aLParam); - -public: - MetroWidget(); - virtual ~MetroWidget(); - - NS_DECL_ISUPPORTS_INHERITED - NS_DECL_NSIOBSERVER - - static HWND GetICoreWindowHWND() { return sICoreHwnd; } - - // nsWindowBase - virtual bool DispatchWindowEvent(mozilla::WidgetGUIEvent* aEvent) override; - virtual bool DispatchKeyboardEvent(mozilla::WidgetKeyboardEvent* aEvent) override; - virtual bool DispatchWheelEvent(mozilla::WidgetWheelEvent* aEvent) override; - virtual bool DispatchContentCommandEvent(mozilla::WidgetContentCommandEvent* aEvent) override; - virtual bool DispatchPluginEvent(const MSG &aMsg) override { return false; } - virtual bool IsTopLevelWidget() override { return true; } - virtual nsWindowBase* GetParentWindowBase(bool aIncludeOwner) override { return nullptr; } - // InitEvent assumes physical coordinates and is used by shared win32 code. Do - // not hand winrt event coordinates to this routine. - virtual void InitEvent(mozilla::WidgetGUIEvent& aEvent, - nsIntPoint* aPoint = nullptr) override; - - // nsBaseWidget - virtual void SetWidgetListener(nsIWidgetListener* aWidgetListener); - - // nsIWidget interface - NS_IMETHOD Create(nsIWidget *aParent, - nsNativeWidget aNativeParent, - const nsIntRect &aRect, - nsWidgetInitData *aInitData = nullptr); - NS_IMETHOD Destroy(); - NS_IMETHOD EnableDragDrop(bool aEnable); - NS_IMETHOD SetParent(nsIWidget *aNewParent); - NS_IMETHOD Show(bool bState); - NS_IMETHOD IsVisible(bool & aState); - NS_IMETHOD IsEnabled(bool *aState); - NS_IMETHOD GetBounds(nsIntRect &aRect); - NS_IMETHOD GetScreenBounds(nsIntRect &aRect); - NS_IMETHOD GetClientBounds(nsIntRect &aRect); - NS_IMETHOD Invalidate(bool aEraseBackground = false, - bool aUpdateNCArea = false, - bool aIncludeChildren = false); - NS_IMETHOD Invalidate(const nsIntRect & aRect); - NS_IMETHOD DispatchEvent(mozilla::WidgetGUIEvent* aEvent, - nsEventStatus& aStatus); - NS_IMETHOD ConstrainPosition(bool aAllowSlop, int32_t *aX, int32_t *aY); - NS_IMETHOD Move(double aX, double aY); - NS_IMETHOD Resize(double aWidth, double aHeight, bool aRepaint); - NS_IMETHOD Resize(double aX, double aY, double aWidth, double aHeight, bool aRepaint); - NS_IMETHOD SetFocus(bool aRaise); - NS_IMETHOD Enable(bool aState); - NS_IMETHOD SetCursor(nsCursor aCursor); - NS_IMETHOD SetTitle(const nsAString& aTitle); - NS_IMETHOD CaptureRollupEvents(nsIRollupListener * aListener, - bool aDoCapture); - NS_IMETHOD ReparentNativeWidget(nsIWidget* aNewParent); - virtual nsresult SynthesizeNativeKeyEvent(int32_t aNativeKeyboardLayout, - int32_t aNativeKeyCode, - uint32_t aModifierFlags, - const nsAString& aCharacters, - const nsAString& aUnmodifiedCharacters, - nsIObserver* aObserver); - virtual nsresult SynthesizeNativeMouseEvent(mozilla::LayoutDeviceIntPoint aPoint, - uint32_t aNativeMessage, - uint32_t aModifierFlags, - nsIObserver* aObserver); - virtual nsresult SynthesizeNativeMouseScrollEvent(mozilla::LayoutDeviceIntPoint aPoint, - uint32_t aNativeMessage, - double aDeltaX, - double aDeltaY, - double aDeltaZ, - uint32_t aModifierFlags, - uint32_t aAdditionalFlags, - nsIObserver* aObserver); - virtual bool HasPendingInputEvent(); - virtual double GetDefaultScaleInternal(); - float GetDPI(); - mozilla::LayoutDeviceIntPoint CSSIntPointToLayoutDeviceIntPoint(const mozilla::CSSIntPoint &aCSSPoint); - void ChangedDPI(); - virtual uint32_t GetMaxTouchPoints() const override; - virtual bool IsVisible() const; - virtual bool IsEnabled() const; - // ShouldUseOffMainThreadCompositing is defined in base widget - virtual bool ShouldUseOffMainThreadCompositing(); - bool ShouldUseBasicManager(); - bool ShouldUseAPZC(); - virtual LayerManager* GetLayerManager(PLayerTransactionChild* aShadowManager = nullptr, - LayersBackend aBackendHint = mozilla::layers::LayersBackend::LAYERS_NONE, - LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT, - bool* aAllowRetaining = nullptr); - virtual void GetPreferredCompositorBackends(nsTArray& aHints) { aHints.AppendElement(mozilla::layers::LayersBackend::LAYERS_D3D11); } - - // IME related interfaces - NS_IMETHOD_(void) SetInputContext(const InputContext& aContext, - const InputContextAction& aAction); - NS_IMETHOD_(nsIWidget::InputContext) GetInputContext(); - NS_IMETHOD GetToggledKeyState(uint32_t aKeyCode, bool* aLEDState); - virtual nsIMEUpdatePreference GetIMEUpdatePreference() override; - - // FrameworkView helpers - void SizeModeChanged(); - void Activated(bool aActiveated); - void Paint(const nsIntRegion& aInvalidRegion); - - MetroWidget* MetroWidget::GetTopLevelWindow(bool aStopOnDialogOrPopup) { return this; } - virtual nsresult ConfigureChildren(const nsTArray& aConfigurations); - virtual void* GetNativeData(uint32_t aDataType); - virtual void FreeNativeData(void * data, uint32_t aDataType); - virtual mozilla::LayoutDeviceIntPoint WidgetToScreenOffset(); - - already_AddRefed GetPresShell(); - - void UserActivity(); - -#ifdef ACCESSIBILITY - mozilla::a11y::Accessible* DispatchAccessibleEvent(uint32_t aEventType); - mozilla::a11y::Accessible* GetAccessible(); -#endif // ACCESSIBILITY - - // needed for current nsIFilePicker - void PickerOpen(); - void PickerClosed(); - bool DestroyCalled() { return false; } - void SuppressBlurEvents(bool aSuppress); - bool BlurEventsSuppressed(); - - // needed for nsITaskbarWindowPreview - bool HasTaskbarIconBeenCreated() { return false; } - void SetHasTaskbarIconBeenCreated(bool created = true) { } - already_AddRefed GetTaskbarPreview() { return nullptr; } - void SetTaskbarPreview(nsITaskbarWindowPreview *preview) { } - WindowHook& GetWindowHook() { return mWindowHook; } - - void SetView(FrameworkView* aView); - void FindMetroWindow(); - virtual void SetTransparencyMode(nsTransparencyMode aMode); - virtual nsTransparencyMode GetTransparencyMode(); - - TouchBehaviorFlags ContentGetAllowedTouchBehavior(const LayoutDeviceIntPoint& aPoint); - - // apzc controller related api - void ApzcSetAllowedTouchBehavior(uint64_t aInputBlockId, nsTArray& aBehaviors); - - // Hit test a point to see if an apzc would consume input there - bool ApzHitTest(mozilla::ScreenIntPoint& pt); - // Transforms a coord so that it properly targets gecko content based - // on apzc transforms currently applied. - void ApzTransformGeckoCoordinate(const mozilla::ScreenIntPoint& pt, - mozilla::LayoutDeviceIntPoint* aRefPointOut); - // send ContentRecievedTouch calls to the apz with appropriate preventDefault params - void ApzContentConsumingTouch(uint64_t aInputBlockId); - void ApzContentIgnoringTouch(uint64_t aInputBlockId); - // Input handling - nsEventStatus ApzReceiveInputEvent(mozilla::WidgetInputEvent* aEvent, - ScrollableLayerGuid* aOutTargetGuid, - uint64_t* aOutInputBlockId); - // Callback for the APZController - void SetApzPendingResponseFlusher(APZPendingResponseFlusher* aFlusher); - -protected: - friend class FrameworkView; - - struct OleInitializeWrapper { - HRESULT const hr; - - OleInitializeWrapper() - : hr(::OleInitialize(nullptr)) - { - } - - ~OleInitializeWrapper() { - if (SUCCEEDED(hr)) { - ::OleFlushClipboard(); - ::OleUninitialize(); - } - } - }; - - // nsBaseWidget - void ConfigureAPZCTreeManager() override; - already_AddRefed NewRootContentController() override; - - void SetSubclass(); - void RemoveSubclass(); - nsIWidgetListener* GetPaintListener(); - - virtual nsresult NotifyIMEInternal( - const IMENotification& aIMENotification) override; - - // Async event dispatching - void DispatchAsyncScrollEvent(DispatchMsg* aEvent); - void DeliverNextScrollEvent(); - void DeliverNextKeyboardEvent(); - -protected: - OleInitializeWrapper mOleInitializeWrapper; - WindowHook mWindowHook; - Microsoft::WRL::ComPtr mView; - nsTransparencyMode mTransparencyMode; - nsIntRegion mInvalidatedRegion; - nsCOMPtr mIdleService; - HWND mWnd; - static HWND sICoreHwnd; - WNDPROC mMetroWndProc; - bool mTempBasicLayerInUse; - uint64_t mRootLayerTreeId; - nsDeque mEventQueue; - nsDeque mKeyEventQueue; - nsRefPtr mController; - nsRefPtr mNativeDragTarget; -}; diff --git a/widget/windows/winrt/ToastNotificationHandler.cpp b/widget/windows/winrt/ToastNotificationHandler.cpp deleted file mode 100644 index 1466cfef49f..00000000000 --- a/widget/windows/winrt/ToastNotificationHandler.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "ToastNotificationHandler.h" -#include "MetroUtils.h" -#include "mozilla/Services.h" -#include "FrameworkView.h" - -using namespace ABI::Windows::Foundation; -using namespace ABI::Windows::Data::Xml::Dom; -using namespace Microsoft::WRL; -using namespace Microsoft::WRL::Wrappers; -using namespace mozilla; -using namespace ABI::Windows::UI::Notifications; - -typedef __FITypedEventHandler_2_Windows__CUI__CNotifications__CToastNotification_IInspectable_t ToastActivationHandler; -typedef __FITypedEventHandler_2_Windows__CUI__CNotifications__CToastNotification_Windows__CUI__CNotifications__CToastDismissedEventArgs ToastDismissHandler; - -bool -ToastNotificationHandler::DisplayNotification(HSTRING title, - HSTRING msg, - HSTRING imagePath, - const nsAString& aCookie, - const nsAString& aAppId) -{ - mCookie = aCookie; - - Microsoft::WRL::ComPtr toastXml = - InitializeXmlForTemplate(ToastTemplateType::ToastTemplateType_ToastImageAndText03); - Microsoft::WRL::ComPtr toastTextElements, toastImageElements; - Microsoft::WRL::ComPtr titleTextNodeRoot, msgTextNodeRoot, imageNodeRoot, srcAttribute; - - HSTRING textNodeStr, imageNodeStr, srcNodeStr; - HSTRING_HEADER textHeader, imageHeader, srcHeader; - WindowsCreateStringReference(L"text", 4, &textHeader, &textNodeStr); - WindowsCreateStringReference(L"image", 5, &imageHeader, &imageNodeStr); - WindowsCreateStringReference(L"src", 3, &srcHeader, &srcNodeStr); - toastXml->GetElementsByTagName(textNodeStr, &toastTextElements); - toastXml->GetElementsByTagName(imageNodeStr, &toastImageElements); - - AssertRetHRESULT(toastTextElements->Item(0, &titleTextNodeRoot), false); - AssertRetHRESULT(toastTextElements->Item(1, &msgTextNodeRoot), false); - AssertRetHRESULT(toastImageElements->Item(0, &imageNodeRoot), false); - - Microsoft::WRL::ComPtr attributes; - AssertRetHRESULT(imageNodeRoot->get_Attributes(&attributes), false); - AssertRetHRESULT(attributes->GetNamedItem(srcNodeStr, &srcAttribute), false); - - SetNodeValueString(title, titleTextNodeRoot.Get(), toastXml.Get()); - SetNodeValueString(msg, msgTextNodeRoot.Get(), toastXml.Get()); - SetNodeValueString(imagePath, srcAttribute.Get(), toastXml.Get()); - - return CreateWindowsNotificationFromXml(toastXml.Get(), aAppId); -} - -bool -ToastNotificationHandler::DisplayTextNotification(HSTRING title, - HSTRING msg, - const nsAString& aCookie, - const nsAString& aAppId) -{ - mCookie = aCookie; - - Microsoft::WRL::ComPtr toastXml = - InitializeXmlForTemplate(ToastTemplateType::ToastTemplateType_ToastText03); - Microsoft::WRL::ComPtr toastTextElements; - Microsoft::WRL::ComPtr titleTextNodeRoot, msgTextNodeRoot; - - HSTRING textNodeStr; - HSTRING_HEADER textHeader; - WindowsCreateStringReference(L"text", 4, &textHeader, &textNodeStr); - toastXml->GetElementsByTagName(textNodeStr, &toastTextElements); - - AssertRetHRESULT(toastTextElements->Item(0, &titleTextNodeRoot), false); - AssertRetHRESULT(toastTextElements->Item(1, &msgTextNodeRoot), false); - - SetNodeValueString(title, titleTextNodeRoot.Get(), toastXml.Get()); - SetNodeValueString(msg, msgTextNodeRoot.Get(), toastXml.Get()); - - return CreateWindowsNotificationFromXml(toastXml.Get(), aAppId); -} - -Microsoft::WRL::ComPtr -ToastNotificationHandler::InitializeXmlForTemplate(ToastTemplateType templateType) { - Microsoft::WRL::ComPtr toastXml; - - AssertRetHRESULT(GetActivationFactory(HStringReference(RuntimeClass_Windows_UI_Notifications_ToastNotificationManager).Get(), - mToastNotificationManagerStatics.GetAddressOf()), nullptr); - - mToastNotificationManagerStatics->GetTemplateContent(templateType, &toastXml); - - return toastXml; -} - -bool -ToastNotificationHandler::CreateWindowsNotificationFromXml(IXmlDocument *toastXml, - const nsAString& aAppId) -{ - Microsoft::WRL::ComPtr notification; - Microsoft::WRL::ComPtr factory; - AssertRetHRESULT(GetActivationFactory(HStringReference(RuntimeClass_Windows_UI_Notifications_ToastNotification).Get(), - factory.GetAddressOf()), false); - AssertRetHRESULT(factory->CreateToastNotification(toastXml, ¬ification), - false); - - EventRegistrationToken activatedToken; - AssertRetHRESULT(notification->add_Activated(Callback(this, - &ToastNotificationHandler::OnActivate).Get(), &activatedToken), false); - EventRegistrationToken dismissedToken; - AssertRetHRESULT(notification->add_Dismissed(Callback(this, - &ToastNotificationHandler::OnDismiss).Get(), &dismissedToken), false); - - Microsoft::WRL::ComPtr notifier; - if (aAppId.IsEmpty()) { - AssertRetHRESULT(mToastNotificationManagerStatics->CreateToastNotifier( - ¬ifier), false); - } else { - AssertRetHRESULT(mToastNotificationManagerStatics->CreateToastNotifierWithId( - HStringReference(PromiseFlatString(aAppId).get()).Get(), - ¬ifier), false); - } - AssertRetHRESULT(notifier->Show(notification.Get()), false); - - MetroUtils::FireObserver("metro_native_toast_shown", mCookie.get()); - - return true; -} - -void ToastNotificationHandler::SetNodeValueString(HSTRING inputString, - Microsoft::WRL::ComPtr node, Microsoft::WRL::ComPtr xml) { - Microsoft::WRL::ComPtr inputText; - Microsoft::WRL::ComPtr inputTextNode, pAppendedChild; - - AssertHRESULT(xml->CreateTextNode(inputString, &inputText)); - AssertHRESULT(inputText.As(&inputTextNode)); - AssertHRESULT(node->AppendChild(inputTextNode.Get(), &pAppendedChild)); -} - -HRESULT ToastNotificationHandler::OnActivate(IToastNotification *notification, IInspectable *inspectable) { - MetroUtils::FireObserver("metro_native_toast_clicked", mCookie.get()); - return S_OK; -} - -HRESULT -ToastNotificationHandler::OnDismiss(IToastNotification *notification, - IToastDismissedEventArgs* aArgs) -{ - MetroUtils::FireObserver("metro_native_toast_dismissed", mCookie.get()); - delete this; - return S_OK; -} diff --git a/widget/windows/winrt/ToastNotificationHandler.h b/widget/windows/winrt/ToastNotificationHandler.h deleted file mode 100644 index 4935f8d4a06..00000000000 --- a/widget/windows/winrt/ToastNotificationHandler.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#pragma once - -#include -#include -#include "mozwrlbase.h" -#include "nsString.h" - - -class ToastNotificationHandler { - typedef ABI::Windows::UI::Notifications::IToastNotification IToastNotification; - typedef ABI::Windows::UI::Notifications::IToastDismissedEventArgs IToastDismissedEventArgs; - typedef ABI::Windows::UI::Notifications::IToastNotificationManagerStatics IToastNotificationManagerStatics; - typedef ABI::Windows::UI::Notifications::ToastTemplateType ToastTemplateType; - typedef ABI::Windows::Data::Xml::Dom::IXmlNode IXmlNode; - typedef ABI::Windows::Data::Xml::Dom::IXmlDocument IXmlDocument; - - void SetNodeValueString(HSTRING inputString,Microsoft::WRL::ComPtr node, - Microsoft::WRL::ComPtr xml); - public: - ToastNotificationHandler() {}; - ~ToastNotificationHandler() {}; - - bool DisplayNotification(HSTRING title, HSTRING msg, HSTRING imagePath, - const nsAString& aCookie, const nsAString& aAppId); - bool DisplayTextNotification(HSTRING title, HSTRING msg, - const nsAString& aCookie, - const nsAString& aAppId); - HRESULT OnActivate(IToastNotification *notification, IInspectable *inspectable); - HRESULT OnDismiss(IToastNotification *notification, - IToastDismissedEventArgs* aArgs); - - private: - nsString mCookie; - Microsoft::WRL::ComPtr mToastNotificationManagerStatics; - - bool CreateWindowsNotificationFromXml(IXmlDocument *toastXml, - const nsAString& aAppId); - Microsoft::WRL::ComPtr InitializeXmlForTemplate(ToastTemplateType templateType); -}; diff --git a/widget/windows/winrt/UIAAccessibilityBridge.cpp b/widget/windows/winrt/UIAAccessibilityBridge.cpp deleted file mode 100644 index 0603462f360..00000000000 --- a/widget/windows/winrt/UIAAccessibilityBridge.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#if defined(ACCESSIBILITY) - -#include "UIAAccessibilityBridge.h" -#include "MetroUtils.h" - -#include - -#include "nsIAccessibleEvent.h" -#include "nsIPersistentProperties2.h" - -// generated -#include "UIABridge.h" - -#include - -using namespace mozilla::a11y; - -namespace mozilla { -namespace widget { -namespace winrt { - -using namespace Microsoft::WRL; - -NS_IMPL_ISUPPORTS(AccessibilityBridge, nsIObserver) - -nsresult -AccessibilityBridge::Observe(nsISupports *aSubject, const char *aTopic, const char16_t *aData) -{ - nsCOMPtr ev = do_QueryInterface(aSubject); - if (!ev) { - return NS_OK; - } - - uint32_t eventType = 0; - ev->GetEventType(&eventType); - if (eventType == nsIAccessibleEvent::EVENT_FOCUS) { - Microsoft::WRL::ComPtr bridgePtr; - mBridge.As(&bridgePtr); - if (bridgePtr) { - bridgePtr->FocusChangeEvent(); - } - } - - return NS_OK; -} - -} } } - -#endif // ACCESSIBILITY diff --git a/widget/windows/winrt/UIAAccessibilityBridge.h b/widget/windows/winrt/UIAAccessibilityBridge.h deleted file mode 100644 index a541035d801..00000000000 --- a/widget/windows/winrt/UIAAccessibilityBridge.h +++ /dev/null @@ -1,80 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#pragma once - -#if defined(ACCESSIBILITY) - -#include "nsCOMPtr.h" -#include "nsIObserver.h" -#include "nsIObserverService.h" -#include "nsServiceManagerUtils.h" -#include "mozilla/a11y/Accessible.h" - -#include "mozwrlbase.h" - -namespace mozilla { -namespace widget { -namespace winrt { - -// Connects to our accessibility framework to receive -// events and query the dom. -class AccessibilityBridge : public nsIObserver -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIOBSERVER - - AccessibilityBridge() {} - - ~AccessibilityBridge() { - Disconnect(); - } - - bool Init(IUnknown* aBridge, mozilla::a11y::Accessible* aPtr) { - mAccess = aPtr; - mBridge = aBridge; - return Connect(); - } - - bool Connect() { - nsresult rv; - - nsCOMPtr observerService = - do_GetService("@mozilla.org/observer-service;1", &rv); - if (NS_FAILED(rv)) { - return false; - } - rv = observerService->AddObserver(this, "accessible-event", false); - if (NS_FAILED(rv)) { - return false; - } - return true; - } - - bool Connected() { - return mAccess ? true : false; - } - - void Disconnect() { - nsresult rv; - nsCOMPtr observerService = - do_GetService("@mozilla.org/observer-service;1", &rv); - if (NS_FAILED(rv)) { - NS_WARNING("failed to get observersvc on shutdown."); - return; - } - observerService->RemoveObserver(this, "accessible-event"); - mAccess = nullptr; - } - -private: - nsRefPtr mAccess; - Microsoft::WRL::ComPtr mBridge; -}; - -} } } - -#endif // ACCESSIBILITY diff --git a/widget/windows/winrt/UIABridge.cpp b/widget/windows/winrt/UIABridge.cpp deleted file mode 100644 index 14c17454bd5..00000000000 --- a/widget/windows/winrt/UIABridge.cpp +++ /dev/null @@ -1,801 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "UIABridge.h" -#include "MetroUtils.h" -#include "UIABridgePrivate.h" -#include "MetroWidget.h" -#include "WinUtils.h" - -#include -#include -#include - -#ifdef ACCESSIBILITY -using namespace mozilla::a11y; -#endif -using namespace mozilla::widget; -using namespace Microsoft::WRL; -using namespace Microsoft::WRL::Wrappers; -using namespace ABI::Windows::UI; -using namespace ABI::Windows::UI::Core; -using namespace ABI::Windows::Foundation; -using namespace ABI::Windows::System; - -//#define DEBUG_BRIDGE -#if !defined(DEBUG_BRIDGE) -#undef LogThread -#undef LogFunction -#define LogThread() -#define LogFunction() -#define BridgeLog(...) -#else -#define BridgeLog(...) WinUtils::Log(__VA_ARGS__) -#endif - -#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ - const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} -MIDL_DEFINE_GUID(IID, IID_IUIABridge, 0xc78b35b5, 0x5db, 0x43aa, 0xae, 0x73, 0x94, 0xc2, 0x33, 0xa9, 0x3c, 0x98); - -namespace mozilla { -namespace widget { -namespace winrt { - -#define ProviderOptions_UseClientCoordinates (ProviderOptions)0x100 - -static int gIDIndex = 2; -ComPtr gProviderRoot = nullptr; -static ComPtr gElement = nullptr; - -HRESULT -UIABridge_CreateInstance(IInspectable **retVal) -{ - HRESULT hr = E_OUTOFMEMORY; - *retVal = nullptr; - ComPtr spProvider = Make(); - if (spProvider != nullptr && - SUCCEEDED(hr = spProvider.Get()->QueryInterface(IID_PPV_ARGS(retVal))) && - SUCCEEDED(hr = spProvider.Get()->QueryInterface(IID_PPV_ARGS(&gProviderRoot)))) { - return S_OK; - } - return hr; -} - -HRESULT -UIATextElement_CreateInstance(IRawElementProviderFragmentRoot* aRoot) -{ - LogFunction(); - HRESULT hr = E_OUTOFMEMORY; - ComPtr spProvider = Make(); - if (spProvider != nullptr && - SUCCEEDED(hr = spProvider.Get()->QueryInterface(IID_PPV_ARGS(&gElement)))) { - spProvider->SetIndexID(gIDIndex++); - return S_OK; - } - return hr; -} - -// IUIABridge - -HRESULT -UIABridge::Init(IInspectable* aView, IInspectable* aWindow, LONG_PTR aInnerPtr) -{ - LogFunction(); - NS_ASSERTION(aView, "invalid framework view pointer"); - NS_ASSERTION(aWindow, "invalid window pointer"); - NS_ASSERTION(aInnerPtr, "invalid Accessible pointer"); - -#if defined(ACCESSIBILITY) - // init AccessibilityBridge and connect to accessibility - mAccBridge = new AccessibilityBridge(); - if (!mAccBridge->Init(CastToUnknown(), (Accessible*)aInnerPtr)) { - return E_FAIL; - } - - aWindow->QueryInterface(IID_PPV_ARGS(&mWindow)); - - if (FAILED(UIATextElement_CreateInstance(this))) - return E_FAIL; - - mAccessible = (Accessible*)aInnerPtr; - - return S_OK; -#endif - return E_FAIL; -} - -HRESULT -UIABridge::Disconnect() -{ - LogFunction(); -#if defined(ACCESSIBILITY) - mAccBridge->Disconnect(); - mAccessible = nullptr; -#endif - mWindow = nullptr; - gElement = nullptr; - gProviderRoot = nullptr; - return S_OK; -} - -bool -UIABridge::Connected() -{ - return !!mAccessible; -} - -// IUIAElement - -HRESULT -UIABridge::SetFocusInternal(LONG_PTR aAccessible) -{ - LogFunction(); - return S_OK; -} - -HRESULT -UIABridge::ClearFocus() -{ - LogFunction(); - return S_OK; -} - -static void -DumpChildInfo(nsRefPtr& aChild) -{ -#ifdef DEBUG - if (!aChild) { - return; - } - nsString str; - aChild->Name(str); - BridgeLog("name: %ls", str.BeginReading()); - aChild->Description(str); - BridgeLog("description: %ls", str.BeginReading()); -#endif -} - -static bool -ChildHasFocus(nsRefPtr& aChild) -{ - BridgeLog("Focus element flags: editable:%d focusable:%d readonly:%d", - ((aChild->NativeState() & mozilla::a11y::states::EDITABLE) > 0), - ((aChild->NativeState() & mozilla::a11y::states::FOCUSABLE) > 0), - ((aChild->NativeState() & mozilla::a11y::states::READONLY) > 0)); - return (((aChild->NativeState() & mozilla::a11y::states::EDITABLE) > 0) && - ((aChild->NativeState() & mozilla::a11y::states::READONLY) == 0)); -} - -HRESULT -UIABridge::FocusChangeEvent() -{ - LogFunction(); - if (!Connected()) { - return UIA_E_ELEMENTNOTAVAILABLE; - } - - nsRefPtr child = mAccessible->FocusedChild(); - if (!child) { - return S_OK; - } - - if (!ChildHasFocus(child)) { - ComPtr element; - gElement.As(&element); - if (!element) { - return S_OK; - } - element->ClearFocus(); - UiaRaiseAutomationEvent(this, UIA_AutomationFocusChangedEventId); - } - - return S_OK; -} - -// IRawElementProviderFragmentRoot - -HRESULT -UIABridge::ElementProviderFromPoint(double x, double y, IRawElementProviderFragment ** retVal) -{ - LogFunction(); - *retVal = nullptr; - if (!Connected()) { - return UIA_E_ELEMENTNOTAVAILABLE; - } - gElement.Get()->QueryInterface(IID_PPV_ARGS(retVal)); - return S_OK; -} - -// Windows calls this looking for the current focus element. Windows -// will call here before accessible sends us any observer events through -// the accessibility bridge, so update child focus information. -HRESULT -UIABridge::GetFocus(IRawElementProviderFragment ** retVal) -{ - LogFunction(); - if (!Connected()) { - return UIA_E_ELEMENTNOTAVAILABLE; - } - - nsRefPtr child = mAccessible->FocusedChild(); - if (!child) { - BridgeLog("mAccessible->GetFocusedChild failed."); - return S_OK; - } - - DumpChildInfo(child); - - ComPtr element; - gElement.As(&element); - if (!element) { - BridgeLog("gElement as IUIAElement failed."); - return S_OK; - } - - if (!ChildHasFocus(child)) { - element->ClearFocus(); - } else { - element->SetFocusInternal((LONG_PTR)child.get()); - element.Get()->QueryInterface(IID_PPV_ARGS(retVal)); - } - - return S_OK; -} - -// IRawElementProviderFragment - -HRESULT -UIABridge::Navigate(NavigateDirection direction, IRawElementProviderFragment ** retVal) -{ - LogFunction(); - if (!Connected()) { - return UIA_E_ELEMENTNOTAVAILABLE; - } - *retVal = nullptr; - - switch(direction) { - case NavigateDirection_Parent: - BridgeLog("UIABridge::Navigate NavigateDirection_Parent"); - break; - case NavigateDirection_NextSibling: - BridgeLog("UIABridge::Navigate NavigateDirection_NextSibling"); - break; - case NavigateDirection_PreviousSibling: - BridgeLog("UIABridge::Navigate NavigateDirection_PreviousSibling"); - break; - case NavigateDirection_FirstChild: - BridgeLog("UIABridge::Navigate NavigateDirection_FirstChild"); - gElement.Get()->QueryInterface(IID_PPV_ARGS(retVal)); - break; - case NavigateDirection_LastChild: - BridgeLog("UIABridge::Navigate NavigateDirection_LastChild"); - gElement.Get()->QueryInterface(IID_PPV_ARGS(retVal)); - break; - } - - // For the other directions (parent, next, previous) the default of nullptr is correct - return S_OK; -} - -HRESULT -UIABridge::GetRuntimeId(SAFEARRAY ** retVal) -{ - LogFunction(); - if (!Connected()) { - return UIA_E_ELEMENTNOTAVAILABLE; - } - - int runtimeId[2] = { UiaAppendRuntimeId, 1 }; // always 1 - *retVal = SafeArrayCreateVector(VT_I4, 0, ARRAYSIZE(runtimeId)); - if (*retVal != nullptr) { - for (long index = 0; index < ARRAYSIZE(runtimeId); ++index) { - SafeArrayPutElement(*retVal, &index, &runtimeId[index]); - } - } else { - return E_OUTOFMEMORY; - } - return S_OK; -} - -HRESULT -UIABridge::get_BoundingRectangle(UiaRect * retVal) -{ - LogFunction(); - if (!Connected() || !mWindow) { - return UIA_E_ELEMENTNOTAVAILABLE; - } - - // returns logical pixels - Rect bounds; - mWindow->get_Bounds(&bounds); - - // we need to return physical pixels - retVal->left = WinUtils::LogToPhys(bounds.X); - retVal->top = WinUtils::LogToPhys(bounds.Y); - retVal->width = WinUtils::LogToPhys(bounds.Width); - retVal->height = WinUtils::LogToPhys(bounds.Height); - - return S_OK; -} - -HRESULT -UIABridge::GetEmbeddedFragmentRoots(SAFEARRAY ** retVal) -{ - if (!Connected()) { - return UIA_E_ELEMENTNOTAVAILABLE; - } - // doesn't apply according to msdn. - *retVal = nullptr; - return S_OK; -} - -HRESULT -UIABridge::SetFocus() -{ - LogFunction(); - if (!Connected()) { - return UIA_E_ELEMENTNOTAVAILABLE; - } - return S_OK; -} - -HRESULT -UIABridge::get_FragmentRoot(IRawElementProviderFragmentRoot ** retVal) -{ - // we are the fragment root. Our children return us for this call. - return QueryInterface(IID_PPV_ARGS(retVal)); -} - -// IRawElementProviderSimple - -HRESULT -UIABridge::get_ProviderOptions(ProviderOptions * pRetVal) -{ - LogFunction(); - if (!Connected()) { - return E_FAIL; - } - *pRetVal = ProviderOptions_ServerSideProvider | - ProviderOptions_UseComThreading | - ProviderOptions_UseClientCoordinates; - return S_OK; -} - -HRESULT -UIABridge::GetPatternProvider(PATTERNID patternId, IUnknown **ppRetVal) -{ - LogFunction(); - BridgeLog("UIABridge::GetPatternProvider=%d", patternId); - - // The root window doesn't support any specific pattern - *ppRetVal = nullptr; - - return S_OK; -} - -HRESULT -UIABridge::GetPropertyValue(PROPERTYID idProp, VARIANT * pRetVal) -{ - pRetVal->vt = VT_EMPTY; - - switch (idProp) { - case UIA_AutomationIdPropertyId: - BridgeLog("UIABridge::GetPropertyValue: idProp=UIA_AutomationIdPropertyId"); - break; - case UIA_ControlTypePropertyId: - BridgeLog("UIABridge::GetPropertyValue: idProp=UIA_ControlTypePropertyId"); - break; - case UIA_IsKeyboardFocusablePropertyId: - BridgeLog("UIABridge::GetPropertyValue: idProp=UIA_IsKeyboardFocusablePropertyId"); - break; - case UIA_IsContentElementPropertyId: - BridgeLog("UIABridge::GetPropertyValue: idProp=UIA_IsContentElementPropertyId"); - break; - case UIA_IsControlElementPropertyId: - BridgeLog("UIABridge::GetPropertyValue: idProp=UIA_IsControlElementPropertyId"); - break; - case UIA_IsEnabledPropertyId: - BridgeLog("UIABridge::GetPropertyValue: idProp=UIA_IsEnabledPropertyId"); - break; - case UIA_HasKeyboardFocusPropertyId: - BridgeLog("UIABridge::GetPropertyValue: idProp=UIA_HasKeyboardFocusPropertyId"); - break; - case UIA_NamePropertyId: - BridgeLog("UIABridge::GetPropertyValue: idProp=UIA_NamePropertyId"); - break; - case UIA_IsPasswordPropertyId: - BridgeLog("UIABridge::GetPropertyValue: idProp=UIA_IsPasswordPropertyId"); - break; - case UIA_NativeWindowHandlePropertyId: - BridgeLog("UIABridge::GetPropertyValue: idProp=UIA_NativeWindowHandlePropertyId"); - break; - default: - BridgeLog("UIABridge::GetPropertyValue: idProp=%d", idProp); - break; - } - - if (!Connected()) { - return E_FAIL; - } - - switch (idProp) { - case UIA_AutomationIdPropertyId: - pRetVal->bstrVal = SysAllocString(L"MozillaAccessibilityBridge0001"); - pRetVal->vt = VT_BSTR; - break; - - case UIA_ControlTypePropertyId: - pRetVal->vt = VT_I4; - pRetVal->lVal = UIA_WindowControlTypeId; - break; - - case UIA_IsKeyboardFocusablePropertyId: - case UIA_IsContentElementPropertyId: - case UIA_IsControlElementPropertyId: - case UIA_IsEnabledPropertyId: - pRetVal->boolVal = VARIANT_TRUE; - pRetVal->vt = VT_BOOL; - break; - - case UIA_HasKeyboardFocusPropertyId: - pRetVal->vt = VT_BOOL; - pRetVal->boolVal = VARIANT_FALSE; - break; - - case UIA_NamePropertyId: - pRetVal->bstrVal = SysAllocString(L"MozillaAccessibilityBridge"); - pRetVal->vt = VT_BSTR; - break; - - case UIA_IsPasswordPropertyId: - pRetVal->vt = VT_BOOL; - pRetVal->boolVal = VARIANT_FALSE; - break; - - case UIA_NativeWindowHandlePropertyId: - pRetVal->vt = VT_I4; - pRetVal->lVal = (LONG)MetroWidget::GetICoreWindowHWND(); - break; - - default: - BridgeLog("UIABridge: Unhandled property"); - break; - } - return S_OK; -} - -HRESULT -UIABridge::get_HostRawElementProvider(IRawElementProviderSimple **ppRetVal) -{ - // We only have this in the root bridge - this is our parent ICoreWindow. - *ppRetVal = nullptr; - if (mWindow != nullptr) { - IInspectable *pHostAsInspectable = nullptr; - if (SUCCEEDED(mWindow->get_AutomationHostProvider(&pHostAsInspectable))) { - pHostAsInspectable->QueryInterface(ppRetVal); - pHostAsInspectable->Release(); - } - } - return S_OK; -} - -/////////////////////////////////////////////////////////////////////////////// -// Element - -HRESULT -UIATextElement::SetFocusInternal(LONG_PTR aAccessible) -{ - LogFunction(); -#if defined(ACCESSIBILITY) - NS_ASSERTION(mAccessItem, "Bad accessible pointer"); - if (mAccessItem == (Accessible*)aAccessible) { - return E_UNEXPECTED; - } - mAccessItem = (Accessible*)aAccessible; - return S_OK; -#endif - return E_FAIL; -} - -HRESULT -UIATextElement::ClearFocus() -{ - LogFunction(); - mAccessItem = nullptr; - return S_OK; -} - -// IRawElementProviderFragment - -HRESULT -UIATextElement::Navigate(NavigateDirection direction, IRawElementProviderFragment ** retVal) -{ - LogFunction(); - - *retVal = nullptr; - switch(direction) { - case NavigateDirection_Parent: - gProviderRoot.Get()->QueryInterface(IID_PPV_ARGS(retVal)); - break; - case NavigateDirection_NextSibling: - break; - case NavigateDirection_PreviousSibling: - break; - case NavigateDirection_FirstChild: - break; - case NavigateDirection_LastChild: - break; - } - return S_OK; -} - -HRESULT -UIATextElement::GetRuntimeId(SAFEARRAY ** retVal) -{ - LogFunction(); - int runtimeId[2] = { UiaAppendRuntimeId, mIndexID }; - *retVal = SafeArrayCreateVector(VT_I4, 0, ARRAYSIZE(runtimeId)); - if (*retVal != nullptr) { - for (long index = 0; index < ARRAYSIZE(runtimeId); ++index) { - SafeArrayPutElement(*retVal, &index, &runtimeId[index]); - } - } else { - return E_OUTOFMEMORY; - } - return S_OK; -} - -HRESULT -UIATextElement::get_BoundingRectangle(UiaRect * retVal) -{ - LogFunction(); - - if (!mAccessItem) { - return UIA_E_ELEMENTNOTAVAILABLE; - } - - // bounds are in physical pixels - nsIntRect rect = mAccessItem->Bounds(); - - retVal->left = rect.x; - retVal->top = rect.y; - retVal->width = rect.width; - retVal->height = rect.height; - - BridgeLog("get_BoundingRectangle: left=%d top=%d right=%d bottom=%d", rect.x, rect.y, rect.x + rect.width, rect.y + rect.height); - return S_OK; -} - -HRESULT -UIATextElement::GetEmbeddedFragmentRoots(SAFEARRAY ** retVal) -{ - *retVal = nullptr; - return S_OK; -} - -HRESULT -UIATextElement::SetFocus() -{ - LogFunction(); - return S_OK; -} - -HRESULT -UIATextElement::get_FragmentRoot(IRawElementProviderFragmentRoot ** retVal) -{ - return gProviderRoot.Get()->QueryInterface(IID_PPV_ARGS(retVal)); -} - -// IRawElementProviderSimple - -HRESULT -UIATextElement::get_ProviderOptions(ProviderOptions * pRetVal) -{ - *pRetVal = ProviderOptions_ServerSideProvider | - ProviderOptions_UseComThreading | - ProviderOptions_UseClientCoordinates; - return S_OK; -} - -HRESULT -UIATextElement::GetPatternProvider(PATTERNID patternId, IUnknown **ppRetVal) -{ - LogFunction(); - BridgeLog("UIATextElement::GetPatternProvider=%d", patternId); - - // UIA_ValuePatternId - 10002 - // UIA_TextPatternId - 10014 - // UIA_TextChildPatternId - 10029 - - *ppRetVal = nullptr; - if (patternId == UIA_TextPatternId) { - BridgeLog("** TextPattern requested from element."); - *ppRetVal = static_cast(this); - AddRef(); - return S_OK; - } else if (patternId == UIA_ValuePatternId) { - BridgeLog("** ValuePattern requested from element."); - *ppRetVal = static_cast(this); - AddRef(); - return S_OK; - } - - return S_OK; -} - -HRESULT -UIATextElement::GetPropertyValue(PROPERTYID idProp, VARIANT * pRetVal) -{ - pRetVal->vt = VT_EMPTY; - - // native hwnd, we don't have one for elements - if (idProp == 30020) { - return S_OK; - } - - switch (idProp) { - case UIA_AutomationIdPropertyId: - BridgeLog("UIATextElement::GetPropertyValue: idProp=UIA_AutomationIdPropertyId"); - break; - case UIA_ControlTypePropertyId: - BridgeLog("UIATextElement::GetPropertyValue: idProp=UIA_ControlTypePropertyId"); - break; - case UIA_IsKeyboardFocusablePropertyId: - BridgeLog("UIATextElement::GetPropertyValue: idProp=UIA_IsKeyboardFocusablePropertyId"); - break; - case UIA_IsContentElementPropertyId: - BridgeLog("UIATextElement::GetPropertyValue: idProp=UIA_IsContentElementPropertyId"); - break; - case UIA_IsControlElementPropertyId: - BridgeLog("UIATextElement::GetPropertyValue: idProp=UIA_IsControlElementPropertyId"); - break; - case UIA_IsEnabledPropertyId: - BridgeLog("UIATextElement::GetPropertyValue: idProp=UIA_IsEnabledPropertyId"); - break; - case UIA_HasKeyboardFocusPropertyId: - BridgeLog("UIATextElement::GetPropertyValue: idProp=UIA_HasKeyboardFocusPropertyId"); - break; - case UIA_NamePropertyId: - BridgeLog("UIATextElement::GetPropertyValue: idProp=UIA_NamePropertyId"); - break; - case UIA_IsPasswordPropertyId: - BridgeLog("UIATextElement::GetPropertyValue: idProp=UIA_IsPasswordPropertyId"); - break; - default: - BridgeLog("UIATextElement::GetPropertyValue: idProp=%d", idProp); - break; - } - - switch (idProp) { - case UIA_AutomationIdPropertyId: - pRetVal->bstrVal = SysAllocString(L"MozillaDocument0001"); - pRetVal->vt = VT_BSTR; - break; - - case UIA_ControlTypePropertyId: - pRetVal->vt = VT_I4; - pRetVal->lVal = UIA_EditControlTypeId; - break; - - case UIA_IsTextPatternAvailablePropertyId: - case UIA_IsKeyboardFocusablePropertyId: - case UIA_IsContentElementPropertyId: - case UIA_IsControlElementPropertyId: - case UIA_IsEnabledPropertyId: - pRetVal->boolVal = VARIANT_TRUE; - pRetVal->vt = VT_BOOL; - break; - - case UIA_LocalizedControlTypePropertyId: - case UIA_LabeledByPropertyId: - break; - - case UIA_HasKeyboardFocusPropertyId: - { - if (mAccessItem) { - if (mAccessItem->NativeState() & mozilla::a11y::states::FOCUSED) { - pRetVal->vt = VT_BOOL; - pRetVal->boolVal = VARIANT_TRUE; - return S_OK; - } - } - pRetVal->vt = VT_BOOL; - pRetVal->boolVal = VARIANT_FALSE; - break; - } - - case UIA_NamePropertyId: - pRetVal->bstrVal = SysAllocString(L"MozillaDocument"); - pRetVal->vt = VT_BSTR; - break; - - case UIA_IsPasswordPropertyId: - pRetVal->vt = VT_BOOL; - pRetVal->boolVal = VARIANT_FALSE; - break; - - default: - BridgeLog("UIATextElement: Unhandled property"); - break; - } - return S_OK; -} - -HRESULT -UIATextElement::get_HostRawElementProvider(IRawElementProviderSimple **ppRetVal) -{ - *ppRetVal = nullptr; - return S_OK; -} - -// ITextProvider - -HRESULT -UIATextElement::GetSelection(SAFEARRAY * *pRetVal) -{ - LogFunction(); - return E_NOTIMPL; -} - -HRESULT -UIATextElement::GetVisibleRanges(SAFEARRAY * *pRetVal) -{ - LogFunction(); - return E_NOTIMPL; -} - -HRESULT -UIATextElement::RangeFromChild(IRawElementProviderSimple *childElement, ITextRangeProvider **pRetVal) -{ - LogFunction(); - return E_NOTIMPL; -} - -HRESULT -UIATextElement::RangeFromPoint(UiaPoint point, ITextRangeProvider **pRetVal) -{ - LogFunction(); - return E_NOTIMPL; -} - -HRESULT -UIATextElement::get_DocumentRange(ITextRangeProvider **pRetVal) -{ - LogFunction(); - return E_NOTIMPL; -} - -HRESULT -UIATextElement::get_SupportedTextSelection(SupportedTextSelection *pRetVal) -{ - LogFunction(); - return E_NOTIMPL; -} - -// IValueProvider - -IFACEMETHODIMP -UIATextElement::SetValue(LPCWSTR val) -{ - LogFunction(); - return E_NOTIMPL; -} - -IFACEMETHODIMP -UIATextElement::get_Value(BSTR *pRetVal) -{ - LogFunction(); - return E_NOTIMPL; -} - -IFACEMETHODIMP -UIATextElement::get_IsReadOnly(BOOL *pRetVal) -{ - LogFunction(); - *pRetVal = FALSE; - return S_OK; -} - -} } } diff --git a/widget/windows/winrt/UIABridge.idl b/widget/windows/winrt/UIABridge.idl deleted file mode 100644 index 9b869b8e33b..00000000000 --- a/widget/windows/winrt/UIABridge.idl +++ /dev/null @@ -1,22 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#define DO_NO_IMPORTS 1 - -import "oaidl.idl"; -import "oleacc.idl"; -import "Inspectable.idl"; - - [uuid(C78B35B5-05DB-43AA-AE73-94C233A93C98)] - interface IUIABridge : IInspectable { - HRESULT Init([in] IInspectable* view, [in] IInspectable* window, [in] LONG_PTR inner); - HRESULT Disconnect(); - HRESULT FocusChangeEvent(); - }; - - [uuid(9F57311C-E8AE-4991-8D9F-E069EEE96D85)] - interface IUIAElement : IInspectable { - HRESULT SetFocusInternal([in] LONG_PTR accessible); - HRESULT ClearFocus(); - }; diff --git a/widget/windows/winrt/UIABridgePrivate.h b/widget/windows/winrt/UIABridgePrivate.h deleted file mode 100644 index 509d505c230..00000000000 --- a/widget/windows/winrt/UIABridgePrivate.h +++ /dev/null @@ -1,139 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#pragma once - -#include -#include -#include -#include -#include - -#include "mozwrlbase.h" - -#include "nsCOMPtr.h" -#include "mozilla/a11y/Accessible.h" -#include "UIAAccessibilityBridge.h" - -// generated -#include "UIABridge.h" - -namespace mozilla { -namespace widget { -namespace winrt { - -// represents the root window to UIA -[uuid("D3EDD951-0715-4501-A8E5-25D97EF35D5A")] -class UIABridge : public Microsoft::WRL::RuntimeClass, - IUIABridge, - IUIAElement, - IRawElementProviderSimple, - IRawElementProviderFragment, - IRawElementProviderFragmentRoot> -{ - typedef ABI::Windows::UI::Core::ICoreWindow ICoreWindow; - - InspectableClass(L"IUIABridge", BaseTrust); - -public: - UIABridge() {} - - // IUIABridge - IFACEMETHODIMP Init(IInspectable* view, IInspectable* window, LONG_PTR inner); - IFACEMETHODIMP Disconnect(); - IFACEMETHODIMP FocusChangeEvent(); - - // IUIAElement - IFACEMETHODIMP SetFocusInternal(LONG_PTR aAccessible); - IFACEMETHODIMP ClearFocus(); - - // IRawElementProviderFragmentRoot - IFACEMETHODIMP ElementProviderFromPoint(double x, double y, IRawElementProviderFragment ** retVal); - IFACEMETHODIMP GetFocus(IRawElementProviderFragment ** retVal); - - // IRawElementProviderFragment - IFACEMETHODIMP Navigate(NavigateDirection direction, IRawElementProviderFragment ** retVal); - IFACEMETHODIMP GetRuntimeId(SAFEARRAY ** retVal); - IFACEMETHODIMP get_BoundingRectangle(UiaRect * retVal); - IFACEMETHODIMP GetEmbeddedFragmentRoots(SAFEARRAY ** retVal); - IFACEMETHODIMP SetFocus(); - IFACEMETHODIMP get_FragmentRoot(IRawElementProviderFragmentRoot * * retVal); - - // IRawElementProviderSimple - IFACEMETHODIMP get_ProviderOptions(ProviderOptions * retVal); - IFACEMETHODIMP GetPatternProvider(PATTERNID iid, IUnknown * * retVal); - IFACEMETHODIMP GetPropertyValue(PROPERTYID idProp, VARIANT * retVal ); - IFACEMETHODIMP get_HostRawElementProvider(IRawElementProviderSimple ** retVal); - -protected: - bool Connected(); - -private: - Microsoft::WRL::ComPtr mWindow; -#if defined(ACCESSIBILITY) - nsRefPtr mAccBridge; - nsRefPtr mAccessible; -#endif -}; - -[uuid("4438135F-F624-43DE-A417-275CE7A1A0CD")] -class UIATextElement : public Microsoft::WRL::RuntimeClass, - IUIAElement, - IRawElementProviderSimple, - IRawElementProviderFragment, - ITextProvider, - IValueProvider > -{ - typedef ABI::Windows::Foundation::Rect Rect; - - InspectableClass(L"UIATextElement", BaseTrust); - -public: - UIATextElement() {} - - // IUIAElement - IFACEMETHODIMP SetFocusInternal(LONG_PTR aAccessible); - IFACEMETHODIMP ClearFocus(); - IFACEMETHODIMP FocusChangeEvent(); - - // IRawElementProviderFragment - IFACEMETHODIMP Navigate(NavigateDirection direction, IRawElementProviderFragment ** retVal); - IFACEMETHODIMP GetRuntimeId(SAFEARRAY ** retVal); - IFACEMETHODIMP get_BoundingRectangle(UiaRect * retVal); - IFACEMETHODIMP GetEmbeddedFragmentRoots(SAFEARRAY ** retVal); - IFACEMETHODIMP SetFocus(); - IFACEMETHODIMP get_FragmentRoot(IRawElementProviderFragmentRoot * * retVal); - - // IRawElementProviderSimple - IFACEMETHODIMP get_ProviderOptions(ProviderOptions * retVal); - IFACEMETHODIMP GetPatternProvider(PATTERNID iid, IUnknown * * retVal); - IFACEMETHODIMP GetPropertyValue(PROPERTYID idProp, VARIANT * retVal ); - IFACEMETHODIMP get_HostRawElementProvider(IRawElementProviderSimple ** retVal); - - // ITextProvider - IFACEMETHODIMP GetSelection(SAFEARRAY * *pRetVal); - IFACEMETHODIMP GetVisibleRanges(SAFEARRAY * *pRetVal); - IFACEMETHODIMP RangeFromChild(IRawElementProviderSimple *childElement, ITextRangeProvider **pRetVal); - IFACEMETHODIMP RangeFromPoint(UiaPoint point, ITextRangeProvider **pRetVal); - IFACEMETHODIMP get_DocumentRange(ITextRangeProvider **pRetVal); - IFACEMETHODIMP get_SupportedTextSelection(SupportedTextSelection *pRetVal); - - // IValueProvider - IFACEMETHODIMP SetValue(LPCWSTR val); - IFACEMETHODIMP get_Value(BSTR *pRetVal); - IFACEMETHODIMP get_IsReadOnly(BOOL *pRetVal); - - void SetIndexID(int id) { - mIndexID = id; - } - -private: - int mIndexID; - nsRefPtr mAccessItem; -}; - -} } } diff --git a/widget/windows/winrt/UIABridgePublic.h b/widget/windows/winrt/UIABridgePublic.h deleted file mode 100644 index e31b6a965af..00000000000 --- a/widget/windows/winrt/UIABridgePublic.h +++ /dev/null @@ -1,19 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#pragma once - -#include -#include -#include - -namespace mozilla { -namespace widget { -namespace winrt { - -// Factory function for UIABridge -HRESULT UIABridge_CreateInstance(IInspectable **retVal); - -} } } diff --git a/widget/windows/winrt/WakeLockListener.cpp b/widget/windows/winrt/WakeLockListener.cpp deleted file mode 100644 index 3286059ff2f..00000000000 --- a/widget/windows/winrt/WakeLockListener.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "WakeLockListener.h" -#include "MetroUtils.h" - -using namespace mozilla::widget::winrt; - -NS_IMPL_ISUPPORTS(WakeLockListener, nsIDOMMozWakeLockListener) - -NS_IMETHODIMP -WakeLockListener::Callback(const nsAString& aTopic, const nsAString& aState) -{ - if (!mDisplayRequest) { - if (FAILED(ActivateGenericInstance(RuntimeClass_Windows_System_Display_DisplayRequest, mDisplayRequest))) { - NS_WARNING("Failed to instantiate IDisplayRequest, wakelocks will be broken!"); - return NS_OK; - } - } - - if (aState.EqualsLiteral("locked-foreground")) { - mDisplayRequest->RequestActive(); - } else { - mDisplayRequest->RequestRelease(); - } - - return NS_OK; -} diff --git a/widget/windows/winrt/WakeLockListener.h b/widget/windows/winrt/WakeLockListener.h deleted file mode 100644 index ecf0483f234..00000000000 --- a/widget/windows/winrt/WakeLockListener.h +++ /dev/null @@ -1,25 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "mozwrlbase.h" - -#include "nscore.h" -#include "nsString.h" -#include "nsIDOMWakeLockListener.h" - -#include - -/* - * A wake lock is used by dom to prevent the device from turning off the - * screen when the user is viewing certain types of content, like video. - */ -class WakeLockListener : - public nsIDOMMozWakeLockListener { -public: - NS_DECL_ISUPPORTS; - NS_DECL_NSIDOMMOZWAKELOCKLISTENER; - -private: - Microsoft::WRL::ComPtr mDisplayRequest; -}; diff --git a/widget/windows/winrt/moz.build b/widget/windows/winrt/moz.build deleted file mode 100644 index be72f7038d9..00000000000 --- a/widget/windows/winrt/moz.build +++ /dev/null @@ -1,52 +0,0 @@ -# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -SOURCES += [ - 'APZController.cpp', - 'FrameworkView.cpp', - 'MetroApp.cpp', - 'MetroAppShell.cpp', - 'MetroContracts.cpp', - 'MetroInput.cpp', - 'MetroUtils.cpp', - 'MetroWidget.cpp', - 'nsMetroFilePicker.cpp', - 'nsWinMetroUtils.cpp', - 'ToastNotificationHandler.cpp', - 'UIAAccessibilityBridge.cpp', - 'UIABridge.cpp', - 'WakeLockListener.cpp', -] - -EXTRA_COMPONENTS += [ - 'MetroUIUtils.js', - 'MetroUIUtils.manifest', -] - -EXPORTS.mozilla.widget += [ - 'MetroD3DCheckHelper.h', -] - -include('/ipc/chromium/chromium-config.mozbuild') - -FINAL_LIBRARY = 'xul' - -LOCAL_INCLUDES += [ - '../', - '/layout/generic', - '/layout/xul', - '/toolkit/xre', - '/widget', - '/xpcom/base', -] - -DEFINES['MOZ_UNICODE'] = True - -for var in ('MOZ_ENABLE_D3D9_LAYER', 'MOZ_ENABLE_D3D10_LAYER'): - if CONFIG[var]: - DEFINES[var] = True - -CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS'] diff --git a/widget/windows/winrt/mozwrlbase.h b/widget/windows/winrt/mozwrlbase.h deleted file mode 100644 index d82be8f0431..00000000000 --- a/widget/windows/winrt/mozwrlbase.h +++ /dev/null @@ -1,77 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#pragma once - -/* - * Includes and it's children. Defines imports needed by - * corewrappers.h in the case where windows.h has already been - * included w/WINVER < 0x600. Also ups WINVER/_WIN32_WINNT prior - * to including wrl.h. Mozilla's build currently has WINVER set to - * 0x502 for XP support. - */ - -#if _WIN32_WINNT < 0x600 - -#include - -VOID -WINAPI -ReleaseSRWLockExclusive( - _Inout_ PSRWLOCK SRWLock - ); - -VOID -WINAPI -ReleaseSRWLockShared( - _Inout_ PSRWLOCK SRWLock - ); - -BOOL -WINAPI -InitializeCriticalSectionEx( - _Out_ LPCRITICAL_SECTION lpCriticalSection, - _In_ DWORD dwSpinCount, - _In_ DWORD Flags - ); - -VOID -WINAPI -InitializeSRWLock( - _Out_ PSRWLOCK SRWLock - ); - -VOID -WINAPI -AcquireSRWLockExclusive( - _Inout_ PSRWLOCK SRWLock - ); - -BOOLEAN -WINAPI -TryAcquireSRWLockExclusive( - _Inout_ PSRWLOCK SRWLock - ); - -BOOLEAN -WINAPI -TryAcquireSRWLockShared( - _Inout_ PSRWLOCK SRWLock - ); - -VOID -WINAPI -AcquireSRWLockShared( - _Inout_ PSRWLOCK SRWLock - ); - -#undef WINVER -#undef _WIN32_WINNT -#define WINVER 0x600 -#define _WIN32_WINNT 0x600 - -#endif // _WIN32_WINNT < 0x600 - -#include diff --git a/widget/windows/winrt/nsMetroFilePicker.cpp b/widget/windows/winrt/nsMetroFilePicker.cpp deleted file mode 100644 index 0d9097fa514..00000000000 --- a/widget/windows/winrt/nsMetroFilePicker.cpp +++ /dev/null @@ -1,484 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsMetroFilePicker.h" -#include "nsComponentManagerUtils.h" -#include "nsNetUtil.h" -#include "nsAutoPtr.h" -#include "MetroUtils.h" - -#include -#include - -using namespace ABI::Windows::Foundation; -using namespace ABI::Windows::Foundation::Collections; -using namespace ABI::Windows::Storage; -using namespace ABI::Windows::Storage::Pickers; -using namespace ABI::Windows::Storage::Streams; -using namespace ABI::Windows::UI; -using namespace ABI::Windows::UI::ViewManagement; -using namespace Microsoft::WRL; -using namespace Microsoft::WRL::Wrappers; -using namespace mozilla::widget::winrt; - -/////////////////////////////////////////////////////////////////////////////// -// nsIFilePicker - -nsMetroFilePicker::nsMetroFilePicker() -{ -} - -nsMetroFilePicker::~nsMetroFilePicker() -{ -} - -NS_IMPL_ISUPPORTS(nsMetroFilePicker, nsIFilePicker) - -NS_IMETHODIMP -nsMetroFilePicker::Init(nsIDOMWindow *parent, const nsAString& title, int16_t mode) -{ - mMode = mode; - HRESULT hr; - switch(mMode) { - case nsIFilePicker::modeOpen: - case nsIFilePicker::modeOpenMultiple: - hr = ActivateGenericInstance(RuntimeClass_Windows_Storage_Pickers_FileOpenPicker, mFileOpenPicker); - AssertRetHRESULT(hr, NS_ERROR_UNEXPECTED); - return NS_OK; - case nsIFilePicker::modeSave: - hr = ActivateGenericInstance(RuntimeClass_Windows_Storage_Pickers_FileSavePicker, mFileSavePicker); - AssertRetHRESULT(hr, NS_ERROR_UNEXPECTED); - return NS_OK; - default: - return NS_ERROR_NOT_IMPLEMENTED; - } -} - -NS_IMETHODIMP -nsMetroFilePicker::Show(int16_t *aReturnVal) -{ - // Metro file picker only offers an async variant which calls back to the - // UI thread, which is the main thread. We therefore can't call it - // synchronously from the main thread. - return NS_ERROR_NOT_IMPLEMENTED; -} - -HRESULT nsMetroFilePicker::OnPickSingleFile(IAsyncOperation* aFile, - AsyncStatus aStatus) -{ - if (aStatus != ABI::Windows::Foundation::AsyncStatus::Completed) { - if (mCallback) - mCallback->Done(nsIFilePicker::returnCancel); - return S_OK; - } - - HRESULT hr; - ComPtr file; - hr = aFile->GetResults(file.GetAddressOf()); - // When the user cancels hr == S_OK and file is nullptr - if (FAILED(hr) || !file) { - if (mCallback) - mCallback->Done(nsIFilePicker::returnCancel); - return S_OK; - } - ComPtr storageItem; - hr = file.As(&storageItem); - if (FAILED(hr)) { - if (mCallback) - mCallback->Done(nsIFilePicker::returnCancel); - return S_OK; - } - - HSTRING path; - if (FAILED(storageItem->get_Path(&path))) { - if (mCallback) - mCallback->Done(nsIFilePicker::returnCancel); - return S_OK; - } - WindowsDuplicateString(path, mFilePath.GetAddressOf()); - WindowsDeleteString(path); - - if (mCallback) { - mCallback->Done(nsIFilePicker::returnOK); - } - return S_OK; -} - -HRESULT nsMetroFilePicker::OnPickMultipleFiles(IAsyncOperation*>* aFileList, - AsyncStatus aStatus) -{ - if (aStatus != ABI::Windows::Foundation::AsyncStatus::Completed) { - if (mCallback) - mCallback->Done(nsIFilePicker::returnCancel); - return S_OK; - } - - HRESULT hr; - ComPtr> view; - hr = aFileList->GetResults(view.GetAddressOf()); - if (FAILED(hr)) { - if (mCallback) - mCallback->Done(nsIFilePicker::returnCancel); - return S_OK; - } - - unsigned int length; - view->get_Size(&length); - for (unsigned int idx = 0; idx < length; idx++) { - ComPtr file; - hr = view->GetAt(idx, file.GetAddressOf()); - if (FAILED(hr)) { - continue; - } - - ComPtr storageItem; - hr = file.As(&storageItem); - if (FAILED(hr)) { - continue; - } - - HSTRING path; - if (SUCCEEDED(storageItem->get_Path(&path))) { - nsCOMPtr file = - do_CreateInstance("@mozilla.org/file/local;1"); - unsigned int tmp; - if (NS_SUCCEEDED(file->InitWithPath( - nsAutoString(WindowsGetStringRawBuffer(path, &tmp))))) { - mFiles.AppendObject(file); - } - } - WindowsDeleteString(path); - } - - if (mCallback) { - mCallback->Done(nsIFilePicker::returnOK); - } - return S_OK; -} - -NS_IMETHODIMP -nsMetroFilePicker::Open(nsIFilePickerShownCallback *aCallback) -{ - HRESULT hr; - // Capture a reference to the callback which we'll also pass into the - // closure to ensure it's not freed. - mCallback = aCallback; - - // The filepicker cannot open when in snapped view, try to unsnapp - // before showing the filepicker. - ApplicationViewState viewState; - MetroUtils::GetViewState(viewState); - if (viewState == ApplicationViewState::ApplicationViewState_Snapped) { - bool unsnapped = SUCCEEDED(MetroUtils::TryUnsnap()); - NS_ENSURE_TRUE(unsnapped, NS_ERROR_FAILURE); - } - - switch(mMode) { - case nsIFilePicker::modeOpen: { - NS_ENSURE_ARG_POINTER(mFileOpenPicker); - - // Initiate the file picker operation - ComPtr> asyncOperation; - hr = mFileOpenPicker->PickSingleFileAsync(asyncOperation.GetAddressOf()); - AssertRetHRESULT(hr, NS_ERROR_FAILURE); - - // Subscribe to the completed event - ComPtr> - completedHandler(Callback>( - this, &nsMetroFilePicker::OnPickSingleFile)); - hr = asyncOperation->put_Completed(completedHandler.Get()); - AssertRetHRESULT(hr, NS_ERROR_UNEXPECTED); - break; - } - - case nsIFilePicker::modeOpenMultiple: { - NS_ENSURE_ARG_POINTER(mFileOpenPicker); - - typedef IVectorView StorageTemplate; - typedef IAsyncOperation AsyncCallbackTemplate; - typedef IAsyncOperationCompletedHandler HandlerTemplate; - - // Initiate the file picker operation - ComPtr asyncOperation; - hr = mFileOpenPicker->PickMultipleFilesAsync(asyncOperation.GetAddressOf()); - AssertRetHRESULT(hr, NS_ERROR_FAILURE); - - // Subscribe to the completed event - ComPtr completedHandler(Callback( - this, &nsMetroFilePicker::OnPickMultipleFiles)); - hr = asyncOperation->put_Completed(completedHandler.Get()); - AssertRetHRESULT(hr, NS_ERROR_UNEXPECTED); - break; - } - - case nsIFilePicker::modeSave: { - NS_ENSURE_ARG_POINTER(mFileSavePicker); - - // Set the default file name - mFileSavePicker->put_SuggestedFileName(HStringReference(mDefaultFilename.BeginReading()).Get()); - - // Set the default file extension - if (mDefaultExtension.Length() > 0) { - nsAutoString defaultFileExtension(mDefaultExtension); - - // Touch up the extansion format platform hands us. - if (defaultFileExtension[0] == L'*') { - defaultFileExtension.Cut(0, 1); - } else if (defaultFileExtension[0] != L'.') { - defaultFileExtension.Insert(L".", 0); - } - - // Sometimes the default file extension is not passed in correctly, - // so we purposfully ignore failures here. - HString ext; - ext.Set(defaultFileExtension.BeginReading()); - hr = mFileSavePicker->put_DefaultFileExtension(ext.Get()); - NS_ASSERTION(SUCCEEDED(hr), "put_DefaultFileExtension failed, bad format for extension?"); - - // Due to a bug in the WinRT file picker, the first file extension in the - // list is always used when saving a file. So we explicitly make sure the - // default extension is the first one in the list here. - if (mFirstTitle.Get()) { - ComPtr*>> map; - mFileSavePicker->get_FileTypeChoices(map.GetAddressOf()); - if (map) { - boolean found = false; - unsigned int index; - map->HasKey(mFirstTitle.Get(), &found); - if (found) { - ComPtr> list; - if (SUCCEEDED(map->Lookup(mFirstTitle.Get(), list.GetAddressOf()))) { - HString ext; - ext.Set(defaultFileExtension.get()); - found = false; - list->IndexOf(HStringReference(defaultFileExtension.get()).Get(), &index, &found); - if (found) { - list->RemoveAt(index); - list->InsertAt(0, HStringReference(defaultFileExtension.get()).Get()); - } - } - } - } - } - } - - // Dispatch the async show operation - ComPtr> asyncOperation; - hr = mFileSavePicker->PickSaveFileAsync(asyncOperation.GetAddressOf()); - AssertRetHRESULT(hr, NS_ERROR_FAILURE); - - // Subscribe to the completed event - ComPtr> - completedHandler(Callback>( - this, &nsMetroFilePicker::OnPickSingleFile)); - hr = asyncOperation->put_Completed(completedHandler.Get()); - AssertRetHRESULT(hr, NS_ERROR_UNEXPECTED); - break; - } - - case modeGetFolder: - return NS_ERROR_NOT_IMPLEMENTED; - - default: - return NS_ERROR_NOT_IMPLEMENTED; - } - return NS_OK; -} - -NS_IMETHODIMP -nsMetroFilePicker::GetFile(nsIFile **aFile) -{ - NS_ENSURE_ARG_POINTER(aFile); - *aFile = nullptr; - - if (WindowsIsStringEmpty(mFilePath.Get())) - return NS_OK; - - nsCOMPtr file(do_CreateInstance("@mozilla.org/file/local;1")); - NS_ENSURE_TRUE(file, NS_ERROR_FAILURE); - unsigned int length; - file->InitWithPath(nsAutoString(mFilePath.GetRawBuffer(&length))); - NS_ADDREF(*aFile = file); - return NS_OK; -} - -NS_IMETHODIMP -nsMetroFilePicker::GetFileURL(nsIURI **aFileURL) -{ - *aFileURL = nullptr; - nsCOMPtr file; - nsresult rv = GetFile(getter_AddRefs(file)); - if (!file) - return rv; - - return NS_NewFileURI(aFileURL, file); -} - -NS_IMETHODIMP -nsMetroFilePicker::GetFiles(nsISimpleEnumerator **aFiles) -{ - NS_ENSURE_ARG_POINTER(aFiles); - return NS_NewArrayEnumerator(aFiles, mFiles); -} - -// Set the filter index -NS_IMETHODIMP -nsMetroFilePicker::GetFilterIndex(int32_t *aFilterIndex) -{ - // No associated concept with a Metro file picker - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -nsMetroFilePicker::SetFilterIndex(int32_t aFilterIndex) -{ - // No associated concept with a Metro file picker - return NS_ERROR_NOT_IMPLEMENTED; -} - -// AFACT, it's up to use to supply the implementation of a vector list. -class MozHStringVector : public RuntimeClass> { - InspectableClass(L"MozHStringVector", TrustLevel::BaseTrust) - ~MozHStringVector() { - Clear(); - } - - // See IVector_impl in windows.foundation.collections.h -public: - STDMETHOD(GetAt)(unsigned aIndex, HSTRING* aString) { - if (aIndex >= mList.Length()) { - return E_INVALIDARG; - } - return WindowsDuplicateString(mList[aIndex], aString); - } - - STDMETHOD(get_Size)(unsigned int* aLength) { - if (!aLength) { - return E_INVALIDARG; - } - *aLength = mList.Length(); - return S_OK; - } - - STDMETHOD(Append)(HSTRING aString) { - HSTRING str; - if (FAILED(WindowsDuplicateString(aString, &str))) { - return E_INVALIDARG; - } - mList.AppendElement(str); - return S_OK; - } - - STDMETHOD(Clear)() { - int length = mList.Length(); - for (int idx = 0; idx < length; idx++) - WindowsDeleteString(mList[idx]); - mList.Clear(); - return S_OK; - } - - // interfaces picker code doesn't seem to need - STDMETHOD(GetView)(IVectorView **aView) { return E_NOTIMPL; } - STDMETHOD(IndexOf)(HSTRING aValue, unsigned *aIndex, boolean *found) { return E_NOTIMPL; } - STDMETHOD(SetAt)(unsigned aIndex, HSTRING aString) { return E_NOTIMPL; } - STDMETHOD(InsertAt)(unsigned aIndex, HSTRING aString) { return E_NOTIMPL; } - STDMETHOD(RemoveAt)(unsigned aIndex) { return E_NOTIMPL; } - STDMETHOD(RemoveAtEnd)() { return E_NOTIMPL; } - -private: - nsTArray mList; -}; - -nsresult -nsMetroFilePicker::ParseFiltersIntoVector(ComPtr>& aVector, - const nsAString& aFilter, - bool aAllowAll) -{ - const char16_t *beg = aFilter.BeginReading(); - const char16_t *end = aFilter.EndReading(); - for (const char16_t *cur = beg, *fileTypeStart = beg; cur <= end; ++cur) { - // Start of a a filetype, example: *.png - if (cur == end || char16_t(' ') == *cur) { - int32_t startPos = fileTypeStart - beg; - int32_t endPos = cur - fileTypeStart - (cur == end ? 0 : 1); - const nsAString& fileType = Substring(aFilter, - startPos, - endPos); - // There is no way to say show all files in Metro save file picker, so - // just use .data if * or *.* is specified. - if (fileType.IsEmpty() || - fileType.Equals(L"*") || - fileType.Equals(L"*.*")) { - HString str; - if (aAllowAll) { - str.Set(L"*"); - aVector->Append(str.Get()); - } else { - str.Set(L".data"); - aVector->Append(str.Get()); - } - } else { - nsAutoString filter(fileType); - if (filter[0] == L'*') { - filter.Cut(0, 1); - } else if (filter[0] != L'.') { - filter.Insert(L".", 0); - } - HString str; - str.Set(filter.BeginReading()); - aVector->Append(str.Get()); - } - - fileTypeStart = cur + 1; - } - } - return NS_OK; -} - -NS_IMETHODIMP -nsMetroFilePicker::AppendFilter(const nsAString& aTitle, - const nsAString& aFilter) -{ - HRESULT hr; - switch(mMode) { - case nsIFilePicker::modeOpen: - case nsIFilePicker::modeOpenMultiple: { - NS_ENSURE_ARG_POINTER(mFileOpenPicker); - ComPtr> list; - mFileOpenPicker->get_FileTypeFilter(list.GetAddressOf()); - nsresult rv = ParseFiltersIntoVector(list, aFilter, true); - NS_ENSURE_SUCCESS(rv, rv); - } - - case nsIFilePicker::modeSave: { - NS_ENSURE_ARG_POINTER(mFileSavePicker); - - ComPtr*>> map; - hr = mFileSavePicker->get_FileTypeChoices(map.GetAddressOf()); - AssertRetHRESULT(hr, NS_ERROR_FAILURE); - - HString key; - key.Set(aTitle.BeginReading()); - - ComPtr> saveTypes; - saveTypes = Make(); - nsresult rv = ParseFiltersIntoVector(saveTypes, aFilter, false); - NS_ENSURE_SUCCESS(rv, rv); - - if (WindowsIsStringEmpty(mFirstTitle.Get())) { - mFirstTitle.Set(key.Get()); - } - - boolean replaced; - map->Insert(key.Get(), saveTypes.Get(), &replaced); - } - break; - - default: - return NS_ERROR_FAILURE; - } - return NS_OK; -} - diff --git a/widget/windows/winrt/nsMetroFilePicker.h b/widget/windows/winrt/nsMetroFilePicker.h deleted file mode 100644 index 0117111dddb..00000000000 --- a/widget/windows/winrt/nsMetroFilePicker.h +++ /dev/null @@ -1,69 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nsMetroFilePicker_h__ -#define nsMetroFilePicker_h__ - -#include "../nsFilePicker.h" -#include "nsString.h" -#include "nsCOMArray.h" -#include "nsCOMPtr.h" -#include "nsILocalFile.h" - -#include "mozwrlbase.h" - -#include -#include -#include -#include -#include - -/** - * Metro file picker - */ - -class nsMetroFilePicker : - public nsBaseWinFilePicker -{ - typedef Microsoft::WRL::Wrappers::HString HString; - typedef ABI::Windows::Storage::StorageFile StorageFile; - typedef ABI::Windows::Foundation::AsyncStatus AsyncStatus; - -public: - nsMetroFilePicker(); - virtual ~nsMetroFilePicker(); - - NS_DECL_ISUPPORTS - - // nsIFilePicker (less what's in nsBaseFilePicker) - NS_IMETHOD GetFilterIndex(int32_t *aFilterIndex); - NS_IMETHOD SetFilterIndex(int32_t aFilterIndex); - NS_IMETHOD GetFile(nsIFile * *aFile); - NS_IMETHOD GetFileURL(nsIURI * *aFileURL); - NS_IMETHOD GetFiles(nsISimpleEnumerator **aFiles); - NS_IMETHOD Show(int16_t *aReturnVal); - NS_IMETHOD Open(nsIFilePickerShownCallback *aCallback); - NS_IMETHOD AppendFilter(const nsAString& aTitle, const nsAString& aFilter); - NS_IMETHOD Init(nsIDOMWindow *parent, const nsAString& title, - int16_t mode); - - // Async callbacks - HRESULT OnPickSingleFile(ABI::Windows::Foundation::IAsyncOperation* aFile, AsyncStatus aStatus); - HRESULT OnPickMultipleFiles(ABI::Windows::Foundation::IAsyncOperation*>* aFileList, AsyncStatus aStatus); - -private: - void InitNative(nsIWidget*, const nsAString&) {}; - nsresult ParseFiltersIntoVector(Microsoft::WRL::ComPtr>& aVector, - const nsAString& aFilter, - bool aAllowAll); - nsCOMArray mFiles; - Microsoft::WRL::ComPtr mFileOpenPicker; - Microsoft::WRL::ComPtr mFileSavePicker; - HString mFilePath; - HString mFirstTitle; - nsRefPtr mCallback; -}; - -#endif // nsMetroFilePicker_h__ diff --git a/widget/windows/winrt/nsWinMetroUtils.cpp b/widget/windows/winrt/nsWinMetroUtils.cpp deleted file mode 100644 index 67cff5dd533..00000000000 --- a/widget/windows/winrt/nsWinMetroUtils.cpp +++ /dev/null @@ -1,402 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsWinMetroUtils.h" -#include "MetroUtils.h" -#include "nsXULAppAPI.h" -#include "FrameworkView.h" -#include "MetroApp.h" -#include "ToastNotificationHandler.h" -#include "mozilla/Preferences.h" -#include "mozilla/WindowsVersion.h" -#include "nsIWindowsRegKey.h" -#include "mozilla/widget/MetroD3DCheckHelper.h" - -#include -#include -#include -#include - -using namespace ABI::Windows::Foundation; -using namespace ABI::Windows::UI::StartScreen; -using namespace ABI::Windows::UI::ViewManagement; -using namespace Microsoft::WRL; -using namespace Microsoft::WRL::Wrappers; -using namespace mozilla::widget::winrt; - -namespace mozilla { -namespace widget { -namespace winrt { -extern ComPtr sMetroApp; -extern nsTArray* sSettingsArray; -} } } - -namespace mozilla { -namespace widget { - -bool nsWinMetroUtils::sUpdatePending = false; - -NS_IMPL_ISUPPORTS(nsWinMetroUtils, nsIWinMetroUtils) - -nsWinMetroUtils::nsWinMetroUtils() -{ -} - -nsWinMetroUtils::~nsWinMetroUtils() -{ -} - -/** - * Pins a new tile to the Windows 8 start screen. - * - * @param aTileID An ID which can later be used to remove the tile - * @param aShortName A short name for the tile - * @param aDiplayName The name that will be displayed on the tile - * @param aActivationArgs The arguments to pass to the browser upon - * activation of the tile - * @param aTileImage An image for the normal tile view - * @param aSmallTileImage An image for the small tile view - */ -NS_IMETHODIMP -nsWinMetroUtils::PinTileAsync(const nsAString &aTileID, - const nsAString &aShortName, - const nsAString &aDisplayName, - const nsAString &aActivationArgs, - const nsAString &aTileImage, - const nsAString &aSmallTileImage) -{ - if (XRE_GetWindowsEnvironment() != WindowsEnvironmentType_Metro) { - NS_WARNING("PinTileAsync can't be called on the desktop."); - return NS_ERROR_FAILURE; - } - HRESULT hr; - - HString logoStr, smallLogoStr, displayName, shortName; - - logoStr.Set(aTileImage.BeginReading()); - smallLogoStr.Set(aSmallTileImage.BeginReading()); - displayName.Set(aDisplayName.BeginReading()); - shortName.Set(aShortName.BeginReading()); - - ComPtr logo, smallLogo; - AssertRetHRESULT(MetroUtils::CreateUri(logoStr, logo), NS_ERROR_FAILURE); - AssertRetHRESULT(MetroUtils::CreateUri(smallLogoStr, smallLogo), NS_ERROR_FAILURE); - - HString tileActivationArgumentsStr, tileIdStr; - tileActivationArgumentsStr.Set(aActivationArgs.BeginReading()); - tileIdStr.Set(aTileID.BeginReading()); - - ComPtr tileFactory; - ComPtr secondaryTile; - hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_UI_StartScreen_SecondaryTile).Get(), - tileFactory.GetAddressOf()); - AssertRetHRESULT(hr, NS_ERROR_FAILURE); - hr = tileFactory->CreateWithId(tileIdStr.Get(), secondaryTile.GetAddressOf()); - AssertRetHRESULT(hr, NS_ERROR_FAILURE); - - secondaryTile->put_Logo(logo.Get()); - secondaryTile->put_SmallLogo(smallLogo.Get()); - secondaryTile->put_DisplayName(displayName.Get()); - secondaryTile->put_ShortName(shortName.Get()); - secondaryTile->put_Arguments(tileActivationArgumentsStr.Get()); - secondaryTile->put_TileOptions(TileOptions::TileOptions_ShowNameOnLogo); - - // The tile is created and we can now attempt to pin the tile. - ComPtr> callback(Callback>( - sMetroApp.Get(), &MetroApp::OnAsyncTileCreated)); - ComPtr> operation; - AssertRetHRESULT(secondaryTile->RequestCreateAsync(operation.GetAddressOf()), NS_ERROR_FAILURE); - operation->put_Completed(callback.Get()); - return NS_OK; -} - -/** - * Unpins a tile from the Windows 8 start screen. - * - * @param aTileID An existing ID which was previously pinned - */ -NS_IMETHODIMP -nsWinMetroUtils::UnpinTileAsync(const nsAString &aTileID) -{ - if (XRE_GetWindowsEnvironment() != WindowsEnvironmentType_Metro) { - NS_WARNING("UnpinTileAsync can't be called on the desktop."); - return NS_ERROR_FAILURE; - } - HRESULT hr; - HString tileIdStr; - tileIdStr.Set(aTileID.BeginReading()); - - ComPtr tileFactory; - ComPtr secondaryTile; - hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_UI_StartScreen_SecondaryTile).Get(), - tileFactory.GetAddressOf()); - AssertRetHRESULT(hr, NS_ERROR_FAILURE); - hr = tileFactory->CreateWithId(tileIdStr.Get(), secondaryTile.GetAddressOf()); - AssertRetHRESULT(hr, NS_ERROR_FAILURE); - - // Attempt to unpin the tile - ComPtr> callback(Callback>( - sMetroApp.Get(), &MetroApp::OnAsyncTileCreated)); - ComPtr> operation; - AssertRetHRESULT(secondaryTile->RequestDeleteAsync(operation.GetAddressOf()), NS_ERROR_FAILURE); - operation->put_Completed(callback.Get()); - return NS_OK; -} - -/** - * Determines if a tile is pinned to the Windows 8 start screen. - * - * @param aTileID An ID which may have been pinned with pinTileAsync - * @param aIsPinned Out parameter for determining if the tile is pinned or not - */ -NS_IMETHODIMP -nsWinMetroUtils::IsTilePinned(const nsAString &aTileID, bool *aIsPinned) -{ - if (XRE_GetWindowsEnvironment() != WindowsEnvironmentType_Metro) { - NS_WARNING("IsTilePinned can't be called on the desktop."); - return NS_ERROR_FAILURE; - } - NS_ENSURE_ARG_POINTER(aIsPinned); - - HRESULT hr; - HString tileIdStr; - tileIdStr.Set(aTileID.BeginReading()); - - ComPtr tileStatics; - hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_UI_StartScreen_SecondaryTile).Get(), - tileStatics.GetAddressOf()); - AssertRetHRESULT(hr, NS_ERROR_FAILURE); - boolean result = false; - tileStatics->Exists(tileIdStr.Get(), &result); - *aIsPinned = result; - return NS_OK; -} - -/** - * Launches the specified application with the specified arguments and - * switches to Desktop mode if in metro mode. -*/ -NS_IMETHODIMP -nsWinMetroUtils::LaunchInDesktop(const nsAString &aPath, const nsAString &aArguments) -{ - SHELLEXECUTEINFOW sinfo; - memset(&sinfo, 0, sizeof(SHELLEXECUTEINFOW)); - sinfo.cbSize = sizeof(SHELLEXECUTEINFOW); - // Per the Metro style enabled desktop browser, for some reason, - // SEE_MASK_FLAG_LOG_USAGE is needed to change from immersive mode - // to desktop. - sinfo.fMask = SEE_MASK_FLAG_LOG_USAGE; - sinfo.hwnd = nullptr; - sinfo.lpFile = aPath.BeginReading(); - sinfo.lpParameters = aArguments.BeginReading(); - sinfo.lpVerb = L"open"; - sinfo.nShow = SW_SHOWNORMAL; - - if (!ShellExecuteEx(&sinfo)) { - return NS_ERROR_FAILURE; - } - return NS_OK; -} - -NS_IMETHODIMP -nsWinMetroUtils::ShowNativeToast(const nsAString &aTitle, - const nsAString &aMessage, const nsAString &anImage, - const nsAString &aCookie, const nsAString& aAppId) -{ - ToastNotificationHandler* notification_handler = - new ToastNotificationHandler; - - HSTRING title = HStringReference(aTitle.BeginReading()).Get(); - HSTRING msg = HStringReference(aMessage.BeginReading()).Get(); - - bool ret; - if (anImage.Length() > 0) { - HSTRING imagePath = HStringReference(anImage.BeginReading()).Get(); - ret = notification_handler->DisplayNotification(title, msg, imagePath, - aCookie, - aAppId); - } else { - ret = notification_handler->DisplayTextNotification(title, msg, aCookie, - aAppId); - } - - if (!ret) { - delete notification_handler; - return NS_ERROR_FAILURE; - } - - return NS_OK; -} - -NS_IMETHODIMP -nsWinMetroUtils::ShowSettingsFlyout() -{ - if (XRE_GetWindowsEnvironment() != WindowsEnvironmentType_Metro) { - NS_WARNING("Settings flyout can't be shown on the desktop."); - return NS_ERROR_FAILURE; - } - - HRESULT hr = MetroUtils::ShowSettingsFlyout(); - return SUCCEEDED(hr) ? NS_OK : NS_ERROR_FAILURE; -} - -NS_IMETHODIMP -nsWinMetroUtils::GetImmersive(bool *aImersive) -{ - *aImersive = - XRE_GetWindowsEnvironment() == WindowsEnvironmentType_Metro; - return NS_OK; -} - -NS_IMETHODIMP -nsWinMetroUtils::GetActivationURI(nsAString &aActivationURI) -{ - if (XRE_GetWindowsEnvironment() != WindowsEnvironmentType_Metro) { - return NS_ERROR_FAILURE; - } - FrameworkView::GetActivationURI(aActivationURI); - return NS_OK; -} - -NS_IMETHODIMP -nsWinMetroUtils::GetPreviousExecutionState(int32_t *out) -{ - if (XRE_GetWindowsEnvironment() != WindowsEnvironmentType_Metro) { - return NS_ERROR_FAILURE; - } - *out = FrameworkView::GetPreviousExecutionState(); - return NS_OK; -} - -NS_IMETHODIMP -nsWinMetroUtils::GetKeyboardVisible(bool *aImersive) -{ - *aImersive = FrameworkView::IsKeyboardVisible(); - return NS_OK; -} - -NS_IMETHODIMP -nsWinMetroUtils::GetKeyboardX(uint32_t *aX) -{ - *aX = static_cast(floor(FrameworkView::KeyboardVisibleRect().X)); - return NS_OK; -} - -NS_IMETHODIMP -nsWinMetroUtils::GetKeyboardY(uint32_t *aY) -{ - *aY = static_cast(floor(FrameworkView::KeyboardVisibleRect().Y)); - return NS_OK; -} - -NS_IMETHODIMP -nsWinMetroUtils::GetKeyboardWidth(uint32_t *aWidth) -{ - *aWidth = static_cast(ceil(FrameworkView::KeyboardVisibleRect().Width)); - return NS_OK; -} - -NS_IMETHODIMP -nsWinMetroUtils::GetKeyboardHeight(uint32_t *aHeight) -{ - *aHeight = static_cast(ceil(FrameworkView::KeyboardVisibleRect().Height)); - return NS_OK; -} - -NS_IMETHODIMP -nsWinMetroUtils::AddSettingsPanelEntry(const nsAString &aLabel, uint32_t *aId) -{ - NS_ENSURE_ARG_POINTER(aId); - if (!sSettingsArray) - return NS_ERROR_UNEXPECTED; - - *aId = sSettingsArray->Length(); - sSettingsArray->AppendElement(nsString(aLabel)); - return NS_OK; -} - -NS_IMETHODIMP -nsWinMetroUtils::SwapMouseButton(bool aValue, bool *aOriginalValue) -{ - *aOriginalValue = ::SwapMouseButton(aValue); - return NS_OK; -} - -NS_IMETHODIMP -nsWinMetroUtils::GetUpdatePending(bool *aUpdatePending) -{ - *aUpdatePending = sUpdatePending; - return NS_OK; -} - -NS_IMETHODIMP -nsWinMetroUtils::SetUpdatePending(bool aUpdatePending) -{ - sUpdatePending = aUpdatePending; - return NS_OK; -} - -NS_IMETHODIMP -nsWinMetroUtils::GetForeground(bool* aForeground) -{ - *aForeground = (::GetActiveWindow() == ::GetForegroundWindow()); - return NS_OK; -} - -NS_IMETHODIMP -nsWinMetroUtils::GetSupported(bool *aSupported) -{ - *aSupported = false; - if (!IsWin8OrLater()) { - return NS_OK; - } - - // if last_used_feature_level_idx is set, we've previously created a - // d3d device that's compatible. See gfxEindowsPlatform for details. - if (Preferences::GetInt("gfx.direct3d.last_used_feature_level_idx", -1) != -1) { - *aSupported = true; - return NS_OK; - } - - // if last_used_feature_level_idx isn't set, gfx hasn't attempted to create - // a device yet. This could be a case where d2d is pref'd off or blacklisted - // on desktop, or we tried to create a device and failed. This could also be - // a first run case where we haven't created an accelerated top level window - // yet. - - NS_NAMED_LITERAL_STRING(metroRegValueName, "MetroD3DAvailable"); - NS_NAMED_LITERAL_STRING(metroRegValuePath, "Software\\Mozilla\\Firefox"); - - // Check to see if the ceh launched us, it also does this check and caches - // a flag in the registry. - nsresult rv; - uint32_t value = 0; - nsCOMPtr regKey = - do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv); - if (NS_SUCCEEDED(rv)) { - rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER, - metroRegValuePath, - nsIWindowsRegKey::ACCESS_ALL); - if (NS_SUCCEEDED(rv)) { - rv = regKey->ReadIntValue(metroRegValueName, &value); - if (NS_SUCCEEDED(rv)) { - *aSupported = (bool)value; - return NS_OK; - } - - // If all else fails, do the check here. This call is costly but - // we shouldn't hit this except in rare situations where the - // ceh never launched the browser that's running. - value = D3DFeatureLevelCheck(); - regKey->WriteIntValue(metroRegValueName, value); - *aSupported = (bool)value; - return NS_OK; - } - } - return NS_OK; -} - -} // widget -} // mozilla diff --git a/widget/windows/winrt/nsWinMetroUtils.h b/widget/windows/winrt/nsWinMetroUtils.h deleted file mode 100644 index 41072725bac..00000000000 --- a/widget/windows/winrt/nsWinMetroUtils.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#pragma once - -#include "nsIWinMetroUtils.h" -#include "nsString.h" - -namespace mozilla { -namespace widget { - -class nsWinMetroUtils : public nsIWinMetroUtils -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIWINMETROUTILS - - nsWinMetroUtils(); - virtual ~nsWinMetroUtils(); - - static bool sUpdatePending; -}; - -} // widget -} // mozilla From 52716266381260e150a85d546d681645ba799161 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Thu, 23 Apr 2015 15:10:28 -0400 Subject: [PATCH 13/57] Bug 1039866 - Remove browser/metro. rs=gavin --- browser/metro/Makefile.in | 23 - .../metro/base/content/BrowserTouchHandler.js | 97 - .../metro/base/content/ContentAreaObserver.js | 361 --- browser/metro/base/content/ContextCommands.js | 436 ---- browser/metro/base/content/ContextUI.js | 399 ---- browser/metro/base/content/NavButtonSlider.js | 217 -- browser/metro/base/content/Site.js | 74 - browser/metro/base/content/TopSites.js | 158 -- browser/metro/base/content/Util.js | 430 ---- browser/metro/base/content/WebProgress.js | 244 -- browser/metro/base/content/appbar.js | 323 --- browser/metro/base/content/apzc.js | 153 -- browser/metro/base/content/bindings.css | 215 -- .../metro/base/content/bindings/appbar.xml | 77 - .../metro/base/content/bindings/bindings.xml | 356 --- .../metro/base/content/bindings/browser.js | 764 ------- .../metro/base/content/bindings/browser.xml | 1304 ----------- .../content/bindings/circularprogress.xml | 134 -- .../metro/base/content/bindings/console.xml | 50 - .../base/content/bindings/cssthrobber.xml | 40 - .../metro/base/content/bindings/dialog.xml | 109 - .../base/content/bindings/flyoutpanel.xml | 107 - browser/metro/base/content/bindings/grid.xml | 1125 ---------- .../base/content/bindings/notification.xml | 158 -- browser/metro/base/content/bindings/popup.xml | 37 - .../content/bindings/selectionoverlay.xml | 111 - .../base/content/bindings/tabprompts.xml | 45 - browser/metro/base/content/bindings/tabs.xml | 208 -- .../base/content/bindings/toggleswitch.xml | 144 -- .../metro/base/content/bindings/urlbar.xml | 937 -------- browser/metro/base/content/bookmarks.js | 76 - browser/metro/base/content/browser-scripts.js | 173 -- browser/metro/base/content/browser-ui.js | 1402 ------------ browser/metro/base/content/browser.js | 1639 -------------- browser/metro/base/content/browser.xul | 1396 ------------ browser/metro/base/content/commandUtil.js | 164 -- browser/metro/base/content/console.js | 352 --- .../contenthandlers/ConsoleAPIObserver.js | 118 - .../base/content/contenthandlers/Content.js | 585 ----- .../contenthandlers/ContextMenuHandler.js | 448 ---- .../content/contenthandlers/FormHelper.js | 751 ------- .../content/contenthandlers/PluginHelper.js | 95 - .../contenthandlers/SelectionHandler.js | 616 ------ browser/metro/base/content/cursor.css | 11 - .../metro/base/content/dbg-metro-actors.js | 37 - browser/metro/base/content/downloads.js | 656 ------ browser/metro/base/content/exceptions.js | 115 - .../content/flyoutpanels/AboutFlyoutPanel.js | 615 ------ .../content/flyoutpanels/FlyoutPanelsUI.js | 120 - .../content/flyoutpanels/PrefsFlyoutPanel.js | 120 - .../content/flyoutpanels/SearchFlyoutPanel.js | 60 - .../content/flyoutpanels/SettingsCharm.js | 86 - .../content/flyoutpanels/SyncFlyoutPanel.js | 367 --- .../base/content/helperui/AlertsHelper.js | 45 - .../helperui/ChromeSelectionHandler.js | 435 ---- .../base/content/helperui/FindHelperUI.js | 227 -- .../base/content/helperui/FormHelperUI.js | 249 --- .../metro/base/content/helperui/IndexedDB.js | 77 - .../base/content/helperui/ItemPinHelper.js | 59 - browser/metro/base/content/helperui/MenuUI.js | 571 ----- .../base/content/helperui/OfflineApps.js | 81 - .../base/content/helperui/SelectHelperUI.js | 169 -- .../content/helperui/SelectionHelperUI.js | 1186 ---------- browser/metro/base/content/input.js | 1052 --------- browser/metro/base/content/jsshell/shell.html | 770 ------- browser/metro/base/content/jsshell/shell.xul | 13 - .../content/library/SelectionPrototype.js | 1084 --------- .../base/content/pages/aboutAddons.xhtml | 36 - .../base/content/pages/aboutCertError.xhtml | 244 -- .../base/content/pages/aboutRights.xhtml | 97 - .../base/content/pages/blockedSite.xhtml | 194 -- browser/metro/base/content/pages/config.js | 632 ------ browser/metro/base/content/pages/config.xhtml | 81 - .../base/content/pages/crashprompt.xhtml | 389 ---- .../metro/base/content/pages/netError.xhtml | 368 ---- browser/metro/base/content/sanitize.js | 314 --- browser/metro/base/content/sanitizeUI.js | 88 - .../base/content/startui/BookmarksView.js | 385 ---- .../startui/FirstRunContentOverlay.xul | 68 - .../base/content/startui/FirstRunOverlay.xul | 70 - .../metro/base/content/startui/HistoryView.js | 323 --- .../base/content/startui/RemoteTabsView.js | 143 -- browser/metro/base/content/startui/Start.xul | 105 - browser/metro/base/content/startui/StartUI.js | 153 -- .../base/content/startui/TopSitesView.js | 320 --- .../base/content/startui/startui-scripts.js | 83 - browser/metro/base/jar.mn | 110 - browser/metro/base/moz.build | 16 - .../base/tests/mochiperf/browser_apzc.js | 225 -- .../base/tests/mochiperf/browser_deck_01.js | 53 - .../base/tests/mochiperf/browser_firstx.js | 29 - .../base/tests/mochiperf/browser_layers_01.js | 35 - .../tests/mochiperf/browser_miscgfx_01.js | 108 - .../base/tests/mochiperf/browser_msgmgr_01.js | 144 -- .../base/tests/mochiperf/browser_tabs_01.js | 48 - browser/metro/base/tests/mochiperf/head.js | 269 --- browser/metro/base/tests/mochiperf/metro.ini | 21 - .../base/tests/mochiperf/msgmanagerecho.js | 28 - .../base/tests/mochiperf/res/divs_test.html | 278 --- browser/metro/base/tests/mochiperf/res/fx.png | Bin 530082 -> 0 bytes .../base/tests/mochiperf/res/ripples.html | 254 --- .../base/tests/mochiperf/res/scroll_test.html | 1961 ----------------- .../tests/mochiperf/res/scroll_test_tall.html | 1961 ----------------- .../metro/base/tests/mochiperf/res/tide.mp4 | Bin 1403534 -> 0 bytes .../base/tests/mochiperf/res/tidevideo.html | 8 - .../tests/mochitest/browser_apzc_basic.js | 119 - .../base/tests/mochitest/browser_bookmarks.js | 245 -- .../tests/mochitest/browser_canonizeURL.js | 21 - .../browser_circular_progress_indicator.js | 57 - .../tests/mochitest/browser_colorUtils.js | 49 - .../mochitest/browser_context_menu_tests.js | 959 -------- .../browser_context_menu_tests_01.html | 14 - .../browser_context_menu_tests_02.html | 30 - .../browser_context_menu_tests_03.html | 88 - .../browser_context_menu_tests_04.html | 15 - .../browser_context_menu_tests_05.html | 15 - .../tests/mochitest/browser_context_ui.js | 288 --- .../tests/mochitest/browser_crashprompt.js | 222 -- .../base/tests/mochitest/browser_downloads.js | 389 ---- .../base/tests/mochitest/browser_findbar.html | 11 - .../base/tests/mochitest/browser_findbar.js | 132 -- .../base/tests/mochitest/browser_flyouts.js | 44 - .../mochitest/browser_form_auto_complete.html | 19 - .../mochitest/browser_form_auto_complete.js | 121 - .../tests/mochitest/browser_form_selects.html | 21 - .../tests/mochitest/browser_form_selects.js | 75 - .../base/tests/mochitest/browser_history.js | 272 --- .../tests/mochitest/browser_inputsource.js | 50 - .../tests/mochitest/browser_link_click.html | 10 - .../tests/mochitest/browser_link_click.js | 97 - .../mochitest/browser_menu_hoverstate.js | 147 -- .../tests/mochitest/browser_mouse_events.js | 51 - .../tests/mochitest/browser_notifications.js | 95 - .../mochitest/browser_onscreen_keyboard.html | 12 - .../mochitest/browser_onscreen_keyboard.js | 60 - .../base/tests/mochitest/browser_prefs_ui.js | 212 -- .../mochitest/browser_private_browsing.js | 37 - .../mochitest/browser_progress_indicator.xul | 15 - .../base/tests/mochitest/browser_prompt.js | 39 - .../tests/mochitest/browser_remotetabs.js | 43 - .../mochitest/browser_selection_basic.html | 109 - .../mochitest/browser_selection_basic.js | 360 --- .../browser_selection_caretfocus.html | 13 - .../mochitest/browser_selection_caretfocus.js | 90 - .../browser_selection_contenteditable.html | 27 - .../browser_selection_contenteditable.js | 75 - .../browser_selection_frame_content.html | 67 - .../browser_selection_frame_content.js | 220 -- ...lection_frame_in_scrollable_container.html | 33 - ...selection_frame_in_scrollable_container.js | 79 - .../browser_selection_frame_inputs.html | 82 - .../browser_selection_frame_inputs.js | 160 -- .../browser_selection_frame_textarea.html | 82 - .../browser_selection_frame_textarea.js | 256 --- .../mochitest/browser_selection_inputs.html | 8 - .../mochitest/browser_selection_inputs.js | 296 --- .../mochitest/browser_selection_textarea.html | 12 - .../mochitest/browser_selection_textarea.js | 115 - .../mochitest/browser_selection_urlbar.js | 415 ---- .../tests/mochitest/browser_sessionstore.js | 55 - .../tests/mochitest/browser_snappedState.js | 209 -- .../base/tests/mochitest/browser_tabs.js | 72 - .../tests/mochitest/browser_tabs_container.js | 117 - .../base/tests/mochitest/browser_test.js | 30 - .../base/tests/mochitest/browser_tilegrid.xul | 86 - .../base/tests/mochitest/browser_tiles.js | 675 ------ .../base/tests/mochitest/browser_topsites.js | 522 ----- .../tests/mochitest/browser_ui_telemetry.js | 77 - .../base/tests/mochitest/browser_urlbar.js | 379 ---- .../mochitest/browser_urlbar_highlightURLs.js | 171 -- .../mochitest/browser_urlbar_trimURLs.js | 141 -- browser/metro/base/tests/mochitest/head.js | 1070 --------- .../mochitest/helpers/BookmarksHelper.js | 101 - .../tests/mochitest/helpers/HistoryHelper.js | 94 - .../mochitest/helpers/ViewStateHelper.js | 66 - browser/metro/base/tests/mochitest/metro.ini | 95 - .../base/tests/mochitest/res/blankpage1.html | 14 - .../base/tests/mochitest/res/blankpage2.html | 14 - .../base/tests/mochitest/res/blankpage3.html | 14 - .../mochitest/res/documentindesignmode.html | 32 - .../base/tests/mochitest/res/image01.png | Bin 22083 -> 0 bytes .../base/tests/mochitest/res/testEngine.xml | 12 - .../base/tests/mochitest/res/textarea01.html | 24 - .../base/tests/mochitest/res/textblock01.html | 64 - .../base/tests/mochitest/res/textdivs01.html | 36 - .../base/tests/mochitest/res/textinput01.html | 14 - browser/metro/base/tests/unit/blank.xhtml | 5 - .../metro/base/tests/unit/test_util_extend.js | 41 - .../test_util_populateFragmentFromString.js | 86 - browser/metro/base/tests/unit/xpcshell.ini | 9 - browser/metro/components/AboutRedirector.js | 93 - browser/metro/components/AlertsService.js | 54 - browser/metro/components/BrowserCLH.js | 285 --- browser/metro/components/BrowserStartup.js | 121 - .../components/ContentDispatchChooser.js | 38 - .../components/ContentPermissionPrompt.js | 145 -- browser/metro/components/DirectoryProvider.js | 44 - browser/metro/components/DownloadManagerUI.js | 43 - browser/metro/components/HelperAppDialog.js | 302 --- .../metro/components/LoginManagerPrompter.js | 522 ----- browser/metro/components/PromptService.js | 103 - browser/metro/components/SafeBrowsing.js | 168 -- browser/metro/components/SessionStore.idl | 83 - browser/metro/components/SessionStore.js | 962 -------- browser/metro/components/Sidebar.js | 130 -- browser/metro/components/components.manifest | 83 - browser/metro/components/moz.build | 37 - browser/metro/defs.mk | 1 - browser/metro/locales/Makefile.in | 22 - .../locales/en-US/chrome/aboutAddons.dtd | 18 - .../locales/en-US/chrome/aboutCertError.dtd | 38 - .../metro/locales/en-US/chrome/aboutPanel.dtd | 52 - .../metro/locales/en-US/chrome/browser.dtd | 149 -- .../locales/en-US/chrome/browser.properties | 148 -- .../metro/locales/en-US/chrome/checkbox.dtd | 6 - browser/metro/locales/en-US/chrome/config.dtd | 16 - .../locales/en-US/chrome/config.properties | 10 - .../locales/en-US/chrome/crashprompt.dtd | 21 - .../en-US/chrome/passwordmgr.properties | 23 - .../metro/locales/en-US/chrome/phishing.dtd | 17 - .../locales/en-US/chrome/preferences.dtd | 41 - .../locales/en-US/chrome/region.properties | 19 - .../locales/en-US/chrome/searchPanel.dtd | 7 - browser/metro/locales/en-US/chrome/sync.dtd | 58 - .../locales/en-US/chrome/sync.properties | 15 - .../locales/generic/profile/bookmarks.json.in | 17 - browser/metro/locales/import/Makefile.in | 53 - browser/metro/locales/import/moz.build | 6 - browser/metro/locales/jar.mn | 45 - browser/metro/locales/moz.build | 10 - browser/metro/metroapp.ini.in | 21 - browser/metro/modules/ContentUtil.jsm | 106 - browser/metro/modules/CrossSlide.jsm | 280 --- browser/metro/modules/View.jsm | 157 -- browser/metro/modules/colorUtils.jsm | 173 -- browser/metro/modules/moz.build | 13 - browser/metro/moz.build | 24 - browser/metro/profile/metro.js | 681 ------ browser/metro/profile/moz.build | 10 - browser/metro/shell/Makefile.in | 6 - .../shell/commandexecutehandler/CEHHelper.cpp | 182 -- .../shell/commandexecutehandler/CEHHelper.h | 31 - .../CommandExecuteHandler.cpp | 952 -------- .../CommandExecuteHandler.def | 6 - .../CommandExecuteHandler.exe.manifest | 29 - .../CommandExecuteHandler.rc | 6 - .../shell/commandexecutehandler/Makefile.in | 11 - .../shell/commandexecutehandler/moz.build | 32 - browser/metro/shell/linktool/linktool.cpp | 296 --- browser/metro/shell/linktool/moz.build | 27 - browser/metro/shell/moz.build | 13 - browser/metro/shell/priconfig.xml | 44 - browser/metro/shell/resources.pri | Bin 6264 -> 0 bytes .../metro/shell/testing/metrotestharness.cpp | 398 ---- browser/metro/shell/testing/moz.build | 31 - .../metro/shell/tileresources/Resources.resw | 64 - .../metro/shell/tileresources/layout.resfiles | 47 - .../shell/tileresources/resources.resfiles | 1 - browser/metro/theme/about.css | 50 - browser/metro/theme/aboutAddons.css | 52 - browser/metro/theme/aboutPage.css | 72 - browser/metro/theme/browser.css | 1402 ------------ browser/metro/theme/circularprogress.css | 49 - browser/metro/theme/config.css | 345 --- browser/metro/theme/content.css | 186 -- browser/metro/theme/crashprompt.css | 134 -- browser/metro/theme/cssthrobber.css | 94 - browser/metro/theme/defines.inc | 123 -- browser/metro/theme/firstrun.css | 265 --- browser/metro/theme/firstruncontent.css | 205 -- browser/metro/theme/flyoutpanel.css | 92 - .../theme/images/aboutAddonsBackground.png | Bin 43723 -> 0 bytes .../images/aboutAddonsBackgroundFillSlice.png | Bin 2810 -> 0 bytes .../metro/theme/images/alert-downloads-30.png | Bin 416 -> 0 bytes browser/metro/theme/images/appbar-icons.png | Bin 9434 -> 0 bytes .../metro/theme/images/arrow-left-light.png | Bin 2344 -> 0 bytes .../theme/images/arrow-left-light@1.4x.png | Bin 3076 -> 0 bytes .../theme/images/arrow-left-light@1.8x.png | Bin 4011 -> 0 bytes browser/metro/theme/images/arrow-left.png | Bin 2175 -> 0 bytes .../metro/theme/images/arrow-left@1.4x.png | Bin 2785 -> 0 bytes .../metro/theme/images/arrow-left@1.8x.png | Bin 3496 -> 0 bytes .../metro/theme/images/arrow-top-light.png | Bin 2400 -> 0 bytes .../theme/images/arrow-top-light@1.4x.png | Bin 3158 -> 0 bytes .../theme/images/arrow-top-light@1.8x.png | Bin 4125 -> 0 bytes browser/metro/theme/images/arrow-top.png | Bin 2227 -> 0 bytes browser/metro/theme/images/arrow-top@1.4x.png | Bin 2877 -> 0 bytes browser/metro/theme/images/arrow-top@1.8x.png | Bin 3538 -> 0 bytes .../images/arrowbox-down-blue-filled.png | Bin 696 -> 0 bytes .../images/arrowbox-down-blue-filled@2x.png | Bin 1839 -> 0 bytes .../images/arrowbox-horiz-blue-filled.png | Bin 744 -> 0 bytes .../images/arrowbox-horiz-blue-filled@2x.png | Bin 1976 -> 0 bytes browser/metro/theme/images/arrowdown-16.png | Bin 246 -> 0 bytes .../metro/theme/images/arrowdowndark-16.png | Bin 286 -> 0 bytes browser/metro/theme/images/arrowleft-16.png | Bin 280 -> 0 bytes .../metro/theme/images/arrowleftdark-16.png | Bin 210 -> 0 bytes browser/metro/theme/images/arrowright-16.png | Bin 235 -> 0 bytes .../metro/theme/images/arrowrightdark-16.png | Bin 206 -> 0 bytes browser/metro/theme/images/arrowup-16.png | Bin 242 -> 0 bytes browser/metro/theme/images/arrowupdark-16.png | Bin 301 -> 0 bytes browser/metro/theme/images/autoscroll.png | Bin 2305 -> 0 bytes .../metro/theme/images/closetab-default.png | Bin 1161 -> 0 bytes .../theme/images/errorpage-blocked-site.png | Bin 2952 -> 0 bytes .../images/errorpage-blocked-site@1.4x.png | Bin 3989 -> 0 bytes .../images/errorpage-blocked-site@1.8x.png | Bin 5258 -> 0 bytes .../theme/images/errorpage-cert-untrusted.png | Bin 2942 -> 0 bytes .../images/errorpage-cert-untrusted@1.4x.png | Bin 3991 -> 0 bytes .../images/errorpage-cert-untrusted@1.8x.png | Bin 5256 -> 0 bytes .../metro/theme/images/errorpage-warning.png | Bin 1669 -> 0 bytes .../theme/images/errorpage-warning@1.4x.png | Bin 1886 -> 0 bytes .../theme/images/errorpage-warning@1.8x.png | Bin 2146 -> 0 bytes .../theme/images/exitfullscreen-hdpi.png | Bin 3409 -> 0 bytes .../metro/theme/images/favicon-default-32.png | Bin 268 -> 0 bytes .../metro/theme/images/firefox-watermark.png | Bin 8057 -> 0 bytes .../metro/theme/images/flyout-back-button.png | Bin 1863 -> 0 bytes .../metro/theme/images/fullscreen-hdpi.png | Bin 3382 -> 0 bytes .../theme/images/icon-autocomplete-search.png | Bin 338 -> 0 bytes .../images/icon-autocomplete-search@1.4x.png | Bin 459 -> 0 bytes .../images/icon-autocomplete-search@1.8x.png | Bin 574 -> 0 bytes .../theme/images/icons-identity-firefox.png | Bin 348 -> 0 bytes .../images/icons-identity-firefox@1.4x.png | Bin 503 -> 0 bytes .../images/icons-identity-firefox@1.8x.png | Bin 714 -> 0 bytes .../theme/images/identity-icons-generic.png | Bin 1748 -> 0 bytes .../theme/images/identity-icons-https-ev.png | Bin 233 -> 0 bytes .../images/identity-icons-https-mixed.png | Bin 442 -> 0 bytes .../theme/images/identity-icons-https.png | Bin 248 -> 0 bytes browser/metro/theme/images/infobar-close.png | Bin 3112 -> 0 bytes .../theme/images/infobar-geolocation.png | Bin 1144 -> 0 bytes browser/metro/theme/images/infobar-key.png | Bin 1001 -> 0 bytes browser/metro/theme/images/infobar-popup.png | Bin 1070 -> 0 bytes browser/metro/theme/images/lock.png | Bin 636 -> 0 bytes browser/metro/theme/images/mute-hdpi.png | Bin 2847 -> 0 bytes browser/metro/theme/images/navbar-back.png | Bin 1903 -> 0 bytes .../metro/theme/images/navbar-back@1.4x.png | Bin 2905 -> 0 bytes .../metro/theme/images/navbar-back@1.8x.png | Bin 4071 -> 0 bytes browser/metro/theme/images/navbar-close.png | Bin 3408 -> 0 bytes .../metro/theme/images/navbar-close@1.4x.png | Bin 4500 -> 0 bytes .../metro/theme/images/navbar-close@1.8x.png | Bin 5478 -> 0 bytes .../theme/images/navbar-contextual-clear.png | Bin 1578 -> 0 bytes .../images/navbar-contextual-clear@1.4x.png | Bin 2317 -> 0 bytes .../images/navbar-contextual-clear@1.8x.png | Bin 3181 -> 0 bytes .../theme/images/navbar-contextual-delete.png | Bin 1254 -> 0 bytes .../images/navbar-contextual-delete@1.4x.png | Bin 1931 -> 0 bytes .../images/navbar-contextual-delete@1.8x.png | Bin 2422 -> 0 bytes .../theme/images/navbar-contextual-hide.png | Bin 3185 -> 0 bytes .../images/navbar-contextual-hide@1.4x.png | Bin 4458 -> 0 bytes .../images/navbar-contextual-hide@1.8x.png | Bin 5746 -> 0 bytes .../theme/images/navbar-contextual-pin.png | Bin 1727 -> 0 bytes .../images/navbar-contextual-pin@1.4x.png | Bin 2552 -> 0 bytes .../images/navbar-contextual-pin@1.8x.png | Bin 3286 -> 0 bytes .../images/navbar-contextual-restore.png | Bin 1798 -> 0 bytes .../images/navbar-contextual-restore@1.4x.png | Bin 2658 -> 0 bytes .../images/navbar-contextual-restore@1.8x.png | Bin 3563 -> 0 bytes .../theme/images/navbar-contextual-unpin.png | Bin 1888 -> 0 bytes .../images/navbar-contextual-unpin@1.4x.png | Bin 2640 -> 0 bytes .../images/navbar-contextual-unpin@1.8x.png | Bin 3588 -> 0 bytes .../theme/images/navbar-download-finished.png | Bin 943 -> 0 bytes .../images/navbar-download-finished@1.4x.png | Bin 2169 -> 0 bytes .../images/navbar-download-finished@1.8x.png | Bin 1756 -> 0 bytes .../metro/theme/images/navbar-download.png | Bin 1654 -> 0 bytes .../theme/images/navbar-download@1.4x.png | Bin 2479 -> 0 bytes .../theme/images/navbar-download@1.8x.png | Bin 3551 -> 0 bytes browser/metro/theme/images/navbar-forward.png | Bin 1906 -> 0 bytes .../theme/images/navbar-forward@1.4x.png | Bin 2921 -> 0 bytes .../theme/images/navbar-forward@1.8x.png | Bin 4102 -> 0 bytes browser/metro/theme/images/navbar-menu.png | Bin 1608 -> 0 bytes .../metro/theme/images/navbar-menu@1.4x.png | Bin 2563 -> 0 bytes .../metro/theme/images/navbar-menu@1.8x.png | Bin 3873 -> 0 bytes browser/metro/theme/images/navbar-pin.png | Bin 2947 -> 0 bytes .../metro/theme/images/navbar-pin@1.4x.png | Bin 4273 -> 0 bytes .../metro/theme/images/navbar-pin@1.8x.png | Bin 5670 -> 0 bytes browser/metro/theme/images/navbar-star.png | Bin 2941 -> 0 bytes .../metro/theme/images/navbar-star@1.4x.png | Bin 4303 -> 0 bytes .../metro/theme/images/navbar-star@1.8x.png | Bin 5587 -> 0 bytes browser/metro/theme/images/newtab-default.png | Bin 1105 -> 0 bytes browser/metro/theme/images/overlay-back.png | Bin 2151 -> 0 bytes .../metro/theme/images/overlay-back@1.4x.png | Bin 2730 -> 0 bytes .../metro/theme/images/overlay-back@1.8x.png | Bin 3240 -> 0 bytes browser/metro/theme/images/overlay-plus.png | Bin 1535 -> 0 bytes .../metro/theme/images/overlay-plus@1.4x.png | Bin 1807 -> 0 bytes .../metro/theme/images/overlay-plus@1.8x.png | Bin 2011 -> 0 bytes browser/metro/theme/images/panel-dark.png | Bin 6463 -> 0 bytes browser/metro/theme/images/pause-hdpi.png | Bin 1359 -> 0 bytes browser/metro/theme/images/pinned-hdpi.png | Bin 1218 -> 0 bytes browser/metro/theme/images/pinned.png | Bin 999 -> 0 bytes browser/metro/theme/images/play-hdpi.png | Bin 2373 -> 0 bytes browser/metro/theme/images/plus-24.png | Bin 1407 -> 0 bytes browser/metro/theme/images/plus-34.png | Bin 3364 -> 0 bytes browser/metro/theme/images/popup-bg-hdpi.png | Bin 4277 -> 0 bytes .../theme/images/popup-selected-item-hdpi.png | Bin 486 -> 0 bytes .../metro/theme/images/progresscircle-bg.png | Bin 1373 -> 0 bytes browser/metro/theme/images/progresscircle.png | Bin 1945 -> 0 bytes .../theme/images/reader-plus-icon-xhdpi.png | Bin 274 -> 0 bytes browser/metro/theme/images/scrubber-hdpi.png | Bin 1982 -> 0 bytes .../metro/theme/images/search-clear-30.png | Bin 476 -> 0 bytes .../metro/theme/images/search-glass-30.png | Bin 1133 -> 0 bytes browser/metro/theme/images/search.png | Bin 858 -> 0 bytes .../metro/theme/images/selection-monocle.png | Bin 339 -> 0 bytes .../theme/images/selection-monocle@1.4x.png | Bin 394 -> 0 bytes .../theme/images/selection-monocle@1.8x.png | Bin 541 -> 0 bytes browser/metro/theme/images/tab-arrows.png | Bin 12484 -> 0 bytes browser/metro/theme/images/tab-crop.png | Bin 70702 -> 0 bytes browser/metro/theme/images/tab-overlay.png | Bin 2253 -> 0 bytes browser/metro/theme/images/textfield.png | Bin 166 -> 0 bytes .../theme/images/tile-selected-check-hdpi.png | Bin 666 -> 0 bytes .../images/tile-selected-check-rtl-hdpi.png | Bin 910 -> 0 bytes browser/metro/theme/images/unmute-hdpi.png | Bin 956 -> 0 bytes browser/metro/theme/images/urlbar-go.png | Bin 502 -> 0 bytes browser/metro/theme/images/urlbar-go@1.4x.png | Bin 644 -> 0 bytes browser/metro/theme/images/urlbar-go@1.8x.png | Bin 809 -> 0 bytes browser/metro/theme/images/urlbar-reload.png | Bin 576 -> 0 bytes .../metro/theme/images/urlbar-reload@1.4x.png | Bin 761 -> 0 bytes .../metro/theme/images/urlbar-reload@1.8x.png | Bin 1023 -> 0 bytes browser/metro/theme/images/urlbar-stop.png | Bin 362 -> 0 bytes .../metro/theme/images/urlbar-stop@1.4x.png | Bin 587 -> 0 bytes .../metro/theme/images/urlbar-stop@1.8x.png | Bin 687 -> 0 bytes browser/metro/theme/jar.mn | 176 -- browser/metro/theme/moz.build | 7 - browser/metro/theme/netError.css | 275 --- browser/metro/theme/platform.css | 926 -------- browser/metro/theme/start.css | 56 - browser/metro/theme/tiles.css | 431 ---- browser/metro/theme/touchcontrols.css | 213 -- 422 files changed, 58194 deletions(-) delete mode 100644 browser/metro/Makefile.in delete mode 100644 browser/metro/base/content/BrowserTouchHandler.js delete mode 100644 browser/metro/base/content/ContentAreaObserver.js delete mode 100644 browser/metro/base/content/ContextCommands.js delete mode 100644 browser/metro/base/content/ContextUI.js delete mode 100644 browser/metro/base/content/NavButtonSlider.js delete mode 100644 browser/metro/base/content/Site.js delete mode 100644 browser/metro/base/content/TopSites.js delete mode 100644 browser/metro/base/content/Util.js delete mode 100644 browser/metro/base/content/WebProgress.js delete mode 100644 browser/metro/base/content/appbar.js delete mode 100644 browser/metro/base/content/apzc.js delete mode 100644 browser/metro/base/content/bindings.css delete mode 100644 browser/metro/base/content/bindings/appbar.xml delete mode 100644 browser/metro/base/content/bindings/bindings.xml delete mode 100644 browser/metro/base/content/bindings/browser.js delete mode 100644 browser/metro/base/content/bindings/browser.xml delete mode 100644 browser/metro/base/content/bindings/circularprogress.xml delete mode 100644 browser/metro/base/content/bindings/console.xml delete mode 100644 browser/metro/base/content/bindings/cssthrobber.xml delete mode 100644 browser/metro/base/content/bindings/dialog.xml delete mode 100644 browser/metro/base/content/bindings/flyoutpanel.xml delete mode 100644 browser/metro/base/content/bindings/grid.xml delete mode 100644 browser/metro/base/content/bindings/notification.xml delete mode 100644 browser/metro/base/content/bindings/popup.xml delete mode 100644 browser/metro/base/content/bindings/selectionoverlay.xml delete mode 100644 browser/metro/base/content/bindings/tabprompts.xml delete mode 100644 browser/metro/base/content/bindings/tabs.xml delete mode 100644 browser/metro/base/content/bindings/toggleswitch.xml delete mode 100644 browser/metro/base/content/bindings/urlbar.xml delete mode 100644 browser/metro/base/content/bookmarks.js delete mode 100644 browser/metro/base/content/browser-scripts.js delete mode 100644 browser/metro/base/content/browser-ui.js delete mode 100644 browser/metro/base/content/browser.js delete mode 100644 browser/metro/base/content/browser.xul delete mode 100644 browser/metro/base/content/commandUtil.js delete mode 100644 browser/metro/base/content/console.js delete mode 100644 browser/metro/base/content/contenthandlers/ConsoleAPIObserver.js delete mode 100644 browser/metro/base/content/contenthandlers/Content.js delete mode 100644 browser/metro/base/content/contenthandlers/ContextMenuHandler.js delete mode 100644 browser/metro/base/content/contenthandlers/FormHelper.js delete mode 100644 browser/metro/base/content/contenthandlers/PluginHelper.js delete mode 100644 browser/metro/base/content/contenthandlers/SelectionHandler.js delete mode 100644 browser/metro/base/content/cursor.css delete mode 100644 browser/metro/base/content/dbg-metro-actors.js delete mode 100644 browser/metro/base/content/downloads.js delete mode 100644 browser/metro/base/content/exceptions.js delete mode 100644 browser/metro/base/content/flyoutpanels/AboutFlyoutPanel.js delete mode 100644 browser/metro/base/content/flyoutpanels/FlyoutPanelsUI.js delete mode 100644 browser/metro/base/content/flyoutpanels/PrefsFlyoutPanel.js delete mode 100644 browser/metro/base/content/flyoutpanels/SearchFlyoutPanel.js delete mode 100644 browser/metro/base/content/flyoutpanels/SettingsCharm.js delete mode 100644 browser/metro/base/content/flyoutpanels/SyncFlyoutPanel.js delete mode 100644 browser/metro/base/content/helperui/AlertsHelper.js delete mode 100644 browser/metro/base/content/helperui/ChromeSelectionHandler.js delete mode 100644 browser/metro/base/content/helperui/FindHelperUI.js delete mode 100644 browser/metro/base/content/helperui/FormHelperUI.js delete mode 100644 browser/metro/base/content/helperui/IndexedDB.js delete mode 100644 browser/metro/base/content/helperui/ItemPinHelper.js delete mode 100644 browser/metro/base/content/helperui/MenuUI.js delete mode 100644 browser/metro/base/content/helperui/OfflineApps.js delete mode 100644 browser/metro/base/content/helperui/SelectHelperUI.js delete mode 100644 browser/metro/base/content/helperui/SelectionHelperUI.js delete mode 100644 browser/metro/base/content/input.js delete mode 100644 browser/metro/base/content/jsshell/shell.html delete mode 100644 browser/metro/base/content/jsshell/shell.xul delete mode 100644 browser/metro/base/content/library/SelectionPrototype.js delete mode 100644 browser/metro/base/content/pages/aboutAddons.xhtml delete mode 100644 browser/metro/base/content/pages/aboutCertError.xhtml delete mode 100644 browser/metro/base/content/pages/aboutRights.xhtml delete mode 100644 browser/metro/base/content/pages/blockedSite.xhtml delete mode 100644 browser/metro/base/content/pages/config.js delete mode 100644 browser/metro/base/content/pages/config.xhtml delete mode 100644 browser/metro/base/content/pages/crashprompt.xhtml delete mode 100644 browser/metro/base/content/pages/netError.xhtml delete mode 100644 browser/metro/base/content/sanitize.js delete mode 100644 browser/metro/base/content/sanitizeUI.js delete mode 100644 browser/metro/base/content/startui/BookmarksView.js delete mode 100644 browser/metro/base/content/startui/FirstRunContentOverlay.xul delete mode 100644 browser/metro/base/content/startui/FirstRunOverlay.xul delete mode 100644 browser/metro/base/content/startui/HistoryView.js delete mode 100644 browser/metro/base/content/startui/RemoteTabsView.js delete mode 100644 browser/metro/base/content/startui/Start.xul delete mode 100644 browser/metro/base/content/startui/StartUI.js delete mode 100644 browser/metro/base/content/startui/TopSitesView.js delete mode 100644 browser/metro/base/content/startui/startui-scripts.js delete mode 100644 browser/metro/base/jar.mn delete mode 100644 browser/metro/base/moz.build delete mode 100644 browser/metro/base/tests/mochiperf/browser_apzc.js delete mode 100644 browser/metro/base/tests/mochiperf/browser_deck_01.js delete mode 100644 browser/metro/base/tests/mochiperf/browser_firstx.js delete mode 100644 browser/metro/base/tests/mochiperf/browser_layers_01.js delete mode 100644 browser/metro/base/tests/mochiperf/browser_miscgfx_01.js delete mode 100644 browser/metro/base/tests/mochiperf/browser_msgmgr_01.js delete mode 100644 browser/metro/base/tests/mochiperf/browser_tabs_01.js delete mode 100644 browser/metro/base/tests/mochiperf/head.js delete mode 100644 browser/metro/base/tests/mochiperf/metro.ini delete mode 100644 browser/metro/base/tests/mochiperf/msgmanagerecho.js delete mode 100644 browser/metro/base/tests/mochiperf/res/divs_test.html delete mode 100644 browser/metro/base/tests/mochiperf/res/fx.png delete mode 100644 browser/metro/base/tests/mochiperf/res/ripples.html delete mode 100644 browser/metro/base/tests/mochiperf/res/scroll_test.html delete mode 100644 browser/metro/base/tests/mochiperf/res/scroll_test_tall.html delete mode 100644 browser/metro/base/tests/mochiperf/res/tide.mp4 delete mode 100644 browser/metro/base/tests/mochiperf/res/tidevideo.html delete mode 100644 browser/metro/base/tests/mochitest/browser_apzc_basic.js delete mode 100644 browser/metro/base/tests/mochitest/browser_bookmarks.js delete mode 100644 browser/metro/base/tests/mochitest/browser_canonizeURL.js delete mode 100644 browser/metro/base/tests/mochitest/browser_circular_progress_indicator.js delete mode 100644 browser/metro/base/tests/mochitest/browser_colorUtils.js delete mode 100644 browser/metro/base/tests/mochitest/browser_context_menu_tests.js delete mode 100644 browser/metro/base/tests/mochitest/browser_context_menu_tests_01.html delete mode 100644 browser/metro/base/tests/mochitest/browser_context_menu_tests_02.html delete mode 100644 browser/metro/base/tests/mochitest/browser_context_menu_tests_03.html delete mode 100644 browser/metro/base/tests/mochitest/browser_context_menu_tests_04.html delete mode 100644 browser/metro/base/tests/mochitest/browser_context_menu_tests_05.html delete mode 100644 browser/metro/base/tests/mochitest/browser_context_ui.js delete mode 100644 browser/metro/base/tests/mochitest/browser_crashprompt.js delete mode 100644 browser/metro/base/tests/mochitest/browser_downloads.js delete mode 100644 browser/metro/base/tests/mochitest/browser_findbar.html delete mode 100644 browser/metro/base/tests/mochitest/browser_findbar.js delete mode 100644 browser/metro/base/tests/mochitest/browser_flyouts.js delete mode 100644 browser/metro/base/tests/mochitest/browser_form_auto_complete.html delete mode 100644 browser/metro/base/tests/mochitest/browser_form_auto_complete.js delete mode 100644 browser/metro/base/tests/mochitest/browser_form_selects.html delete mode 100644 browser/metro/base/tests/mochitest/browser_form_selects.js delete mode 100644 browser/metro/base/tests/mochitest/browser_history.js delete mode 100644 browser/metro/base/tests/mochitest/browser_inputsource.js delete mode 100644 browser/metro/base/tests/mochitest/browser_link_click.html delete mode 100644 browser/metro/base/tests/mochitest/browser_link_click.js delete mode 100644 browser/metro/base/tests/mochitest/browser_menu_hoverstate.js delete mode 100644 browser/metro/base/tests/mochitest/browser_mouse_events.js delete mode 100644 browser/metro/base/tests/mochitest/browser_notifications.js delete mode 100644 browser/metro/base/tests/mochitest/browser_onscreen_keyboard.html delete mode 100644 browser/metro/base/tests/mochitest/browser_onscreen_keyboard.js delete mode 100644 browser/metro/base/tests/mochitest/browser_prefs_ui.js delete mode 100644 browser/metro/base/tests/mochitest/browser_private_browsing.js delete mode 100644 browser/metro/base/tests/mochitest/browser_progress_indicator.xul delete mode 100644 browser/metro/base/tests/mochitest/browser_prompt.js delete mode 100644 browser/metro/base/tests/mochitest/browser_remotetabs.js delete mode 100644 browser/metro/base/tests/mochitest/browser_selection_basic.html delete mode 100644 browser/metro/base/tests/mochitest/browser_selection_basic.js delete mode 100644 browser/metro/base/tests/mochitest/browser_selection_caretfocus.html delete mode 100644 browser/metro/base/tests/mochitest/browser_selection_caretfocus.js delete mode 100644 browser/metro/base/tests/mochitest/browser_selection_contenteditable.html delete mode 100644 browser/metro/base/tests/mochitest/browser_selection_contenteditable.js delete mode 100644 browser/metro/base/tests/mochitest/browser_selection_frame_content.html delete mode 100644 browser/metro/base/tests/mochitest/browser_selection_frame_content.js delete mode 100644 browser/metro/base/tests/mochitest/browser_selection_frame_in_scrollable_container.html delete mode 100644 browser/metro/base/tests/mochitest/browser_selection_frame_in_scrollable_container.js delete mode 100644 browser/metro/base/tests/mochitest/browser_selection_frame_inputs.html delete mode 100644 browser/metro/base/tests/mochitest/browser_selection_frame_inputs.js delete mode 100644 browser/metro/base/tests/mochitest/browser_selection_frame_textarea.html delete mode 100644 browser/metro/base/tests/mochitest/browser_selection_frame_textarea.js delete mode 100644 browser/metro/base/tests/mochitest/browser_selection_inputs.html delete mode 100644 browser/metro/base/tests/mochitest/browser_selection_inputs.js delete mode 100644 browser/metro/base/tests/mochitest/browser_selection_textarea.html delete mode 100644 browser/metro/base/tests/mochitest/browser_selection_textarea.js delete mode 100644 browser/metro/base/tests/mochitest/browser_selection_urlbar.js delete mode 100644 browser/metro/base/tests/mochitest/browser_sessionstore.js delete mode 100644 browser/metro/base/tests/mochitest/browser_snappedState.js delete mode 100644 browser/metro/base/tests/mochitest/browser_tabs.js delete mode 100644 browser/metro/base/tests/mochitest/browser_tabs_container.js delete mode 100644 browser/metro/base/tests/mochitest/browser_test.js delete mode 100644 browser/metro/base/tests/mochitest/browser_tilegrid.xul delete mode 100644 browser/metro/base/tests/mochitest/browser_tiles.js delete mode 100644 browser/metro/base/tests/mochitest/browser_topsites.js delete mode 100644 browser/metro/base/tests/mochitest/browser_ui_telemetry.js delete mode 100644 browser/metro/base/tests/mochitest/browser_urlbar.js delete mode 100644 browser/metro/base/tests/mochitest/browser_urlbar_highlightURLs.js delete mode 100644 browser/metro/base/tests/mochitest/browser_urlbar_trimURLs.js delete mode 100644 browser/metro/base/tests/mochitest/head.js delete mode 100644 browser/metro/base/tests/mochitest/helpers/BookmarksHelper.js delete mode 100644 browser/metro/base/tests/mochitest/helpers/HistoryHelper.js delete mode 100644 browser/metro/base/tests/mochitest/helpers/ViewStateHelper.js delete mode 100644 browser/metro/base/tests/mochitest/metro.ini delete mode 100644 browser/metro/base/tests/mochitest/res/blankpage1.html delete mode 100644 browser/metro/base/tests/mochitest/res/blankpage2.html delete mode 100644 browser/metro/base/tests/mochitest/res/blankpage3.html delete mode 100644 browser/metro/base/tests/mochitest/res/documentindesignmode.html delete mode 100644 browser/metro/base/tests/mochitest/res/image01.png delete mode 100644 browser/metro/base/tests/mochitest/res/testEngine.xml delete mode 100644 browser/metro/base/tests/mochitest/res/textarea01.html delete mode 100644 browser/metro/base/tests/mochitest/res/textblock01.html delete mode 100644 browser/metro/base/tests/mochitest/res/textdivs01.html delete mode 100644 browser/metro/base/tests/mochitest/res/textinput01.html delete mode 100644 browser/metro/base/tests/unit/blank.xhtml delete mode 100644 browser/metro/base/tests/unit/test_util_extend.js delete mode 100644 browser/metro/base/tests/unit/test_util_populateFragmentFromString.js delete mode 100644 browser/metro/base/tests/unit/xpcshell.ini delete mode 100644 browser/metro/components/AboutRedirector.js delete mode 100644 browser/metro/components/AlertsService.js delete mode 100644 browser/metro/components/BrowserCLH.js delete mode 100644 browser/metro/components/BrowserStartup.js delete mode 100644 browser/metro/components/ContentDispatchChooser.js delete mode 100644 browser/metro/components/ContentPermissionPrompt.js delete mode 100644 browser/metro/components/DirectoryProvider.js delete mode 100644 browser/metro/components/DownloadManagerUI.js delete mode 100644 browser/metro/components/HelperAppDialog.js delete mode 100644 browser/metro/components/LoginManagerPrompter.js delete mode 100644 browser/metro/components/PromptService.js delete mode 100644 browser/metro/components/SafeBrowsing.js delete mode 100644 browser/metro/components/SessionStore.idl delete mode 100644 browser/metro/components/SessionStore.js delete mode 100644 browser/metro/components/Sidebar.js delete mode 100644 browser/metro/components/components.manifest delete mode 100644 browser/metro/components/moz.build delete mode 100644 browser/metro/defs.mk delete mode 100644 browser/metro/locales/Makefile.in delete mode 100644 browser/metro/locales/en-US/chrome/aboutAddons.dtd delete mode 100644 browser/metro/locales/en-US/chrome/aboutCertError.dtd delete mode 100644 browser/metro/locales/en-US/chrome/aboutPanel.dtd delete mode 100644 browser/metro/locales/en-US/chrome/browser.dtd delete mode 100644 browser/metro/locales/en-US/chrome/browser.properties delete mode 100644 browser/metro/locales/en-US/chrome/checkbox.dtd delete mode 100644 browser/metro/locales/en-US/chrome/config.dtd delete mode 100644 browser/metro/locales/en-US/chrome/config.properties delete mode 100644 browser/metro/locales/en-US/chrome/crashprompt.dtd delete mode 100644 browser/metro/locales/en-US/chrome/passwordmgr.properties delete mode 100644 browser/metro/locales/en-US/chrome/phishing.dtd delete mode 100644 browser/metro/locales/en-US/chrome/preferences.dtd delete mode 100644 browser/metro/locales/en-US/chrome/region.properties delete mode 100644 browser/metro/locales/en-US/chrome/searchPanel.dtd delete mode 100644 browser/metro/locales/en-US/chrome/sync.dtd delete mode 100644 browser/metro/locales/en-US/chrome/sync.properties delete mode 100644 browser/metro/locales/generic/profile/bookmarks.json.in delete mode 100644 browser/metro/locales/import/Makefile.in delete mode 100644 browser/metro/locales/import/moz.build delete mode 100644 browser/metro/locales/jar.mn delete mode 100644 browser/metro/locales/moz.build delete mode 100644 browser/metro/metroapp.ini.in delete mode 100644 browser/metro/modules/ContentUtil.jsm delete mode 100644 browser/metro/modules/CrossSlide.jsm delete mode 100644 browser/metro/modules/View.jsm delete mode 100644 browser/metro/modules/colorUtils.jsm delete mode 100644 browser/metro/modules/moz.build delete mode 100644 browser/metro/moz.build delete mode 100644 browser/metro/profile/metro.js delete mode 100644 browser/metro/profile/moz.build delete mode 100644 browser/metro/shell/Makefile.in delete mode 100644 browser/metro/shell/commandexecutehandler/CEHHelper.cpp delete mode 100644 browser/metro/shell/commandexecutehandler/CEHHelper.h delete mode 100644 browser/metro/shell/commandexecutehandler/CommandExecuteHandler.cpp delete mode 100644 browser/metro/shell/commandexecutehandler/CommandExecuteHandler.def delete mode 100644 browser/metro/shell/commandexecutehandler/CommandExecuteHandler.exe.manifest delete mode 100644 browser/metro/shell/commandexecutehandler/CommandExecuteHandler.rc delete mode 100644 browser/metro/shell/commandexecutehandler/Makefile.in delete mode 100644 browser/metro/shell/commandexecutehandler/moz.build delete mode 100644 browser/metro/shell/linktool/linktool.cpp delete mode 100644 browser/metro/shell/linktool/moz.build delete mode 100644 browser/metro/shell/moz.build delete mode 100644 browser/metro/shell/priconfig.xml delete mode 100644 browser/metro/shell/resources.pri delete mode 100644 browser/metro/shell/testing/metrotestharness.cpp delete mode 100644 browser/metro/shell/testing/moz.build delete mode 100644 browser/metro/shell/tileresources/Resources.resw delete mode 100644 browser/metro/shell/tileresources/layout.resfiles delete mode 100644 browser/metro/shell/tileresources/resources.resfiles delete mode 100644 browser/metro/theme/about.css delete mode 100644 browser/metro/theme/aboutAddons.css delete mode 100644 browser/metro/theme/aboutPage.css delete mode 100644 browser/metro/theme/browser.css delete mode 100644 browser/metro/theme/circularprogress.css delete mode 100644 browser/metro/theme/config.css delete mode 100644 browser/metro/theme/content.css delete mode 100644 browser/metro/theme/crashprompt.css delete mode 100644 browser/metro/theme/cssthrobber.css delete mode 100644 browser/metro/theme/defines.inc delete mode 100644 browser/metro/theme/firstrun.css delete mode 100644 browser/metro/theme/firstruncontent.css delete mode 100644 browser/metro/theme/flyoutpanel.css delete mode 100644 browser/metro/theme/images/aboutAddonsBackground.png delete mode 100644 browser/metro/theme/images/aboutAddonsBackgroundFillSlice.png delete mode 100644 browser/metro/theme/images/alert-downloads-30.png delete mode 100644 browser/metro/theme/images/appbar-icons.png delete mode 100644 browser/metro/theme/images/arrow-left-light.png delete mode 100644 browser/metro/theme/images/arrow-left-light@1.4x.png delete mode 100644 browser/metro/theme/images/arrow-left-light@1.8x.png delete mode 100644 browser/metro/theme/images/arrow-left.png delete mode 100644 browser/metro/theme/images/arrow-left@1.4x.png delete mode 100644 browser/metro/theme/images/arrow-left@1.8x.png delete mode 100644 browser/metro/theme/images/arrow-top-light.png delete mode 100644 browser/metro/theme/images/arrow-top-light@1.4x.png delete mode 100644 browser/metro/theme/images/arrow-top-light@1.8x.png delete mode 100644 browser/metro/theme/images/arrow-top.png delete mode 100644 browser/metro/theme/images/arrow-top@1.4x.png delete mode 100644 browser/metro/theme/images/arrow-top@1.8x.png delete mode 100644 browser/metro/theme/images/arrowbox-down-blue-filled.png delete mode 100644 browser/metro/theme/images/arrowbox-down-blue-filled@2x.png delete mode 100644 browser/metro/theme/images/arrowbox-horiz-blue-filled.png delete mode 100644 browser/metro/theme/images/arrowbox-horiz-blue-filled@2x.png delete mode 100644 browser/metro/theme/images/arrowdown-16.png delete mode 100644 browser/metro/theme/images/arrowdowndark-16.png delete mode 100644 browser/metro/theme/images/arrowleft-16.png delete mode 100644 browser/metro/theme/images/arrowleftdark-16.png delete mode 100644 browser/metro/theme/images/arrowright-16.png delete mode 100644 browser/metro/theme/images/arrowrightdark-16.png delete mode 100644 browser/metro/theme/images/arrowup-16.png delete mode 100644 browser/metro/theme/images/arrowupdark-16.png delete mode 100644 browser/metro/theme/images/autoscroll.png delete mode 100644 browser/metro/theme/images/closetab-default.png delete mode 100644 browser/metro/theme/images/errorpage-blocked-site.png delete mode 100644 browser/metro/theme/images/errorpage-blocked-site@1.4x.png delete mode 100644 browser/metro/theme/images/errorpage-blocked-site@1.8x.png delete mode 100644 browser/metro/theme/images/errorpage-cert-untrusted.png delete mode 100644 browser/metro/theme/images/errorpage-cert-untrusted@1.4x.png delete mode 100644 browser/metro/theme/images/errorpage-cert-untrusted@1.8x.png delete mode 100644 browser/metro/theme/images/errorpage-warning.png delete mode 100644 browser/metro/theme/images/errorpage-warning@1.4x.png delete mode 100644 browser/metro/theme/images/errorpage-warning@1.8x.png delete mode 100644 browser/metro/theme/images/exitfullscreen-hdpi.png delete mode 100644 browser/metro/theme/images/favicon-default-32.png delete mode 100644 browser/metro/theme/images/firefox-watermark.png delete mode 100644 browser/metro/theme/images/flyout-back-button.png delete mode 100644 browser/metro/theme/images/fullscreen-hdpi.png delete mode 100644 browser/metro/theme/images/icon-autocomplete-search.png delete mode 100644 browser/metro/theme/images/icon-autocomplete-search@1.4x.png delete mode 100644 browser/metro/theme/images/icon-autocomplete-search@1.8x.png delete mode 100644 browser/metro/theme/images/icons-identity-firefox.png delete mode 100644 browser/metro/theme/images/icons-identity-firefox@1.4x.png delete mode 100644 browser/metro/theme/images/icons-identity-firefox@1.8x.png delete mode 100644 browser/metro/theme/images/identity-icons-generic.png delete mode 100644 browser/metro/theme/images/identity-icons-https-ev.png delete mode 100644 browser/metro/theme/images/identity-icons-https-mixed.png delete mode 100644 browser/metro/theme/images/identity-icons-https.png delete mode 100644 browser/metro/theme/images/infobar-close.png delete mode 100644 browser/metro/theme/images/infobar-geolocation.png delete mode 100644 browser/metro/theme/images/infobar-key.png delete mode 100644 browser/metro/theme/images/infobar-popup.png delete mode 100644 browser/metro/theme/images/lock.png delete mode 100644 browser/metro/theme/images/mute-hdpi.png delete mode 100644 browser/metro/theme/images/navbar-back.png delete mode 100644 browser/metro/theme/images/navbar-back@1.4x.png delete mode 100644 browser/metro/theme/images/navbar-back@1.8x.png delete mode 100644 browser/metro/theme/images/navbar-close.png delete mode 100644 browser/metro/theme/images/navbar-close@1.4x.png delete mode 100644 browser/metro/theme/images/navbar-close@1.8x.png delete mode 100644 browser/metro/theme/images/navbar-contextual-clear.png delete mode 100644 browser/metro/theme/images/navbar-contextual-clear@1.4x.png delete mode 100644 browser/metro/theme/images/navbar-contextual-clear@1.8x.png delete mode 100644 browser/metro/theme/images/navbar-contextual-delete.png delete mode 100644 browser/metro/theme/images/navbar-contextual-delete@1.4x.png delete mode 100644 browser/metro/theme/images/navbar-contextual-delete@1.8x.png delete mode 100644 browser/metro/theme/images/navbar-contextual-hide.png delete mode 100644 browser/metro/theme/images/navbar-contextual-hide@1.4x.png delete mode 100644 browser/metro/theme/images/navbar-contextual-hide@1.8x.png delete mode 100644 browser/metro/theme/images/navbar-contextual-pin.png delete mode 100644 browser/metro/theme/images/navbar-contextual-pin@1.4x.png delete mode 100644 browser/metro/theme/images/navbar-contextual-pin@1.8x.png delete mode 100644 browser/metro/theme/images/navbar-contextual-restore.png delete mode 100644 browser/metro/theme/images/navbar-contextual-restore@1.4x.png delete mode 100644 browser/metro/theme/images/navbar-contextual-restore@1.8x.png delete mode 100644 browser/metro/theme/images/navbar-contextual-unpin.png delete mode 100644 browser/metro/theme/images/navbar-contextual-unpin@1.4x.png delete mode 100644 browser/metro/theme/images/navbar-contextual-unpin@1.8x.png delete mode 100644 browser/metro/theme/images/navbar-download-finished.png delete mode 100644 browser/metro/theme/images/navbar-download-finished@1.4x.png delete mode 100644 browser/metro/theme/images/navbar-download-finished@1.8x.png delete mode 100644 browser/metro/theme/images/navbar-download.png delete mode 100644 browser/metro/theme/images/navbar-download@1.4x.png delete mode 100644 browser/metro/theme/images/navbar-download@1.8x.png delete mode 100644 browser/metro/theme/images/navbar-forward.png delete mode 100644 browser/metro/theme/images/navbar-forward@1.4x.png delete mode 100644 browser/metro/theme/images/navbar-forward@1.8x.png delete mode 100644 browser/metro/theme/images/navbar-menu.png delete mode 100644 browser/metro/theme/images/navbar-menu@1.4x.png delete mode 100644 browser/metro/theme/images/navbar-menu@1.8x.png delete mode 100644 browser/metro/theme/images/navbar-pin.png delete mode 100644 browser/metro/theme/images/navbar-pin@1.4x.png delete mode 100644 browser/metro/theme/images/navbar-pin@1.8x.png delete mode 100644 browser/metro/theme/images/navbar-star.png delete mode 100644 browser/metro/theme/images/navbar-star@1.4x.png delete mode 100644 browser/metro/theme/images/navbar-star@1.8x.png delete mode 100644 browser/metro/theme/images/newtab-default.png delete mode 100644 browser/metro/theme/images/overlay-back.png delete mode 100644 browser/metro/theme/images/overlay-back@1.4x.png delete mode 100644 browser/metro/theme/images/overlay-back@1.8x.png delete mode 100644 browser/metro/theme/images/overlay-plus.png delete mode 100644 browser/metro/theme/images/overlay-plus@1.4x.png delete mode 100644 browser/metro/theme/images/overlay-plus@1.8x.png delete mode 100644 browser/metro/theme/images/panel-dark.png delete mode 100644 browser/metro/theme/images/pause-hdpi.png delete mode 100644 browser/metro/theme/images/pinned-hdpi.png delete mode 100644 browser/metro/theme/images/pinned.png delete mode 100644 browser/metro/theme/images/play-hdpi.png delete mode 100644 browser/metro/theme/images/plus-24.png delete mode 100644 browser/metro/theme/images/plus-34.png delete mode 100644 browser/metro/theme/images/popup-bg-hdpi.png delete mode 100644 browser/metro/theme/images/popup-selected-item-hdpi.png delete mode 100644 browser/metro/theme/images/progresscircle-bg.png delete mode 100644 browser/metro/theme/images/progresscircle.png delete mode 100644 browser/metro/theme/images/reader-plus-icon-xhdpi.png delete mode 100644 browser/metro/theme/images/scrubber-hdpi.png delete mode 100644 browser/metro/theme/images/search-clear-30.png delete mode 100644 browser/metro/theme/images/search-glass-30.png delete mode 100644 browser/metro/theme/images/search.png delete mode 100644 browser/metro/theme/images/selection-monocle.png delete mode 100644 browser/metro/theme/images/selection-monocle@1.4x.png delete mode 100644 browser/metro/theme/images/selection-monocle@1.8x.png delete mode 100644 browser/metro/theme/images/tab-arrows.png delete mode 100644 browser/metro/theme/images/tab-crop.png delete mode 100644 browser/metro/theme/images/tab-overlay.png delete mode 100644 browser/metro/theme/images/textfield.png delete mode 100644 browser/metro/theme/images/tile-selected-check-hdpi.png delete mode 100644 browser/metro/theme/images/tile-selected-check-rtl-hdpi.png delete mode 100644 browser/metro/theme/images/unmute-hdpi.png delete mode 100644 browser/metro/theme/images/urlbar-go.png delete mode 100644 browser/metro/theme/images/urlbar-go@1.4x.png delete mode 100644 browser/metro/theme/images/urlbar-go@1.8x.png delete mode 100644 browser/metro/theme/images/urlbar-reload.png delete mode 100644 browser/metro/theme/images/urlbar-reload@1.4x.png delete mode 100644 browser/metro/theme/images/urlbar-reload@1.8x.png delete mode 100644 browser/metro/theme/images/urlbar-stop.png delete mode 100644 browser/metro/theme/images/urlbar-stop@1.4x.png delete mode 100644 browser/metro/theme/images/urlbar-stop@1.8x.png delete mode 100644 browser/metro/theme/jar.mn delete mode 100644 browser/metro/theme/moz.build delete mode 100644 browser/metro/theme/netError.css delete mode 100644 browser/metro/theme/platform.css delete mode 100644 browser/metro/theme/start.css delete mode 100644 browser/metro/theme/tiles.css delete mode 100644 browser/metro/theme/touchcontrols.css diff --git a/browser/metro/Makefile.in b/browser/metro/Makefile.in deleted file mode 100644 index 33f60fea731..00000000000 --- a/browser/metro/Makefile.in +++ /dev/null @@ -1,23 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -include $(topsrcdir)/config/rules.mk - -######################################### -# application.ini - -GRE_BUILDID := $(shell cat $(DEPTH)/config/buildid) -DEFINES += -DGRE_BUILDID=$(GRE_BUILDID) -DMOZ_APP_BASENAME=$(MOZ_APP_BASENAME) - -# 'application.ini' breaks firefox build config. So we use something different. -metroapp.ini: metroapp.ini.in $(DEPTH)/config/buildid $(topsrcdir)/config/milestone.txt - $(RM) metroapp.ini - $(call py_action,preprocessor,$(DEFINES) $< -o $@) - -libs:: metroapp.ini - $(INSTALL) metroapp.ini $(FINAL_TARGET) - -######################################### - -GARBAGE += metroapp.ini diff --git a/browser/metro/base/content/BrowserTouchHandler.js b/browser/metro/base/content/BrowserTouchHandler.js deleted file mode 100644 index 6bffe8ac372..00000000000 --- a/browser/metro/base/content/BrowserTouchHandler.js +++ /dev/null @@ -1,97 +0,0 @@ -/* - * BrowserTouchHandler - * - * Receives touch events from our input event capturing in input.js - * and relays appropriate events to content. Also handles requests - * from content for UI. - */ - -const BrowserTouchHandler = { - _debugEvents: false, - - init: function init() { - // Misc. events we catch during the bubbling phase - document.addEventListener("PopupChanged", this, false); - document.addEventListener("CancelTouchSequence", this, false); - - // Messages sent from content.js - messageManager.addMessageListener("Content:ContextMenu", this); - messageManager.addMessageListener("Content:SelectionCaret", this); - }, - - // Content forwarding the contextmenu command - _onContentContextMenu: function _onContentContextMenu(aMessage) { - // Note, target here is the target of the message manager message, - // usually the browser. - // Touch input selection handling - if (!InputSourceHelper.isPrecise && - !SelectionHelperUI.isActive && - SelectionHelperUI.canHandleContextMenuMsg(aMessage)) { - SelectionHelperUI.openEditSession(aMessage.target, - aMessage.json.xPos, - aMessage.json.yPos); - return; - } - - // Check to see if we have context menu item(s) that apply to what - // was clicked on. - let contextInfo = { name: aMessage.name, - json: aMessage.json, - target: aMessage.target }; - if (ContextMenuUI.showContextMenu(contextInfo)) { - let event = document.createEvent("Events"); - event.initEvent("CancelTouchSequence", true, false); - document.dispatchEvent(event); - } else { - // Send the MozEdgeUIGesture to input.js to - // toggle the context ui. - let event = document.createEvent("Events"); - event.initEvent("MozEdgeUICompleted", true, false); - window.dispatchEvent(event); - } - }, - - /* - * Called when Content wants to initiate selection management - * due to a tap in a form input. - */ - _onCaretSelectionStarted: function _onCaretSelectionStarted(aMessage) { - SelectionHelperUI.attachToCaret(aMessage.target, - aMessage.json.xPos, - aMessage.json.yPos); - }, - - /* - * Events - */ - - handleEvent: function handleEvent(aEvent) { - // ignore content events we generate - if (aEvent.target == document) - return; - - if (this._debugEvents) - Util.dumpLn("BrowserTouchHandler:", aEvent.type); - - switch (aEvent.type) { - case "PopupChanged": - case "CancelTouchSequence": - if (!aEvent.detail) - ContextMenuUI.reset(); - break; - } - }, - - receiveMessage: function receiveMessage(aMessage) { - if (this._debugEvents) Util.dumpLn("BrowserTouchHandler:", aMessage.name); - switch (aMessage.name) { - // Content forwarding the contextmenu command - case "Content:ContextMenu": - this._onContentContextMenu(aMessage); - break; - case "Content:SelectionCaret": - this._onCaretSelectionStarted(aMessage); - break; - } - }, -}; diff --git a/browser/metro/base/content/ContentAreaObserver.js b/browser/metro/base/content/ContentAreaObserver.js deleted file mode 100644 index 9ba7b0a1597..00000000000 --- a/browser/metro/base/content/ContentAreaObserver.js +++ /dev/null @@ -1,361 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - - /* - * ContentAreaObserver manages tracking the viewable area within the browser. - * It also handles certain tasks like positioning of input elements within - * content when the viewable area changes. - * - * ContentAreaObserver creates styles that content can apply and also fires - * events when things change. The 'width' and 'height' properties of the - * styles are updated whenever various parts of the UI are resized. - * - * styles: window-width, window-height - * events: SizeChanged - * - * The innerWidth/innerHeight of the main chrome window. - * - * styles: content-width, content-height - * events: ContentSizeChanged - * - * The area of the window dedicated to web content; this is equal to the - * innerWidth/Height minus any toolbars or similar chrome. - * - * styles: viewable-width, viewable-height - * events: ViewableSizeChanged - * - * The portion of the content area that is not obscured by the on-screen - * keyboard. - * - * ContentAreaObserver also manages soft keyboard related events. Events - * fired include: - * - * KeyboardChanged - fired after the visibility of the soft keyboard changes - * and after any view related changes are made to accomidate view dim - * changes as a result. - * - * MozDeckOffsetChanging, MozDeckOffsetChanged - interim events fired when - * the browser deck is being repositioned to move focused elements out of - * the way of the keyboard. - */ - -var ContentAreaObserver = { - styles: {}, - _shiftAmount: 0, - _deckTransitioning: false, - - /* - * Properties - */ - - get width() { - return window.innerWidth || 1366; - }, - - get height() { - return window.innerHeight || 768; - }, - - get contentHeight() { - return this._getContentHeightForWindow(this.height); - }, - - get viewableHeight() { - return this._getViewableHeightForContent(this.contentHeight); - }, - - get isKeyboardOpened() { - return Services.metro.keyboardVisible; - }, - - get isKeyboardTransitioning() { - return this._deckTransitioning; - }, - - get viewstate() { - if (this.width < Services.prefs.getIntPref("browser.ui.snapped.maxWidth")) { - return "snapped"; - } - return (this.height > this.width) ? "portrait" : "landscape"; - }, - - /* - * Public apis - */ - - init: function init() { - window.addEventListener("resize", this, false); - - // Message manager msgs we listen for - messageManager.addMessageListener("Content:RepositionInfoResponse", this); - - // Observer msgs we listen for - Services.obs.addObserver(this, "metro_softkeyboard_shown", false); - Services.obs.addObserver(this, "metro_softkeyboard_hidden", false); - - // setup initial values for browser form repositioning - this.shiftBrowserDeck(0); - - // initialize our custom width and height styles - this._initStyles(); - - // apply default styling - this.update(); - }, - - shutdown: function shutdown() { - messageManager.removeMessageListener("Content:RepositionInfoResponse", this); - Services.obs.removeObserver(this, "metro_softkeyboard_shown"); - Services.obs.removeObserver(this, "metro_softkeyboard_hidden"); - }, - - update: function cao_update (width, height) { - let oldWidth = parseInt(this.styles["window-width"].width); - let oldHeight = parseInt(this.styles["window-height"].height); - - let newWidth = width || this.width; - let newHeight = height || this.height; - - if (newHeight == oldHeight && newWidth == oldWidth) { - return; - } - - this.styles["window-width"].width = newWidth + "px"; - this.styles["window-width"].maxWidth = newWidth + "px"; - this.styles["window-height"].height = newHeight + "px"; - this.styles["window-height"].maxHeight = newHeight + "px"; - - this._updateViewState(); - - this.updateContentArea(newWidth, this._getContentHeightForWindow(newHeight)); - this._dispatchBrowserEvent("SizeChanged"); - }, - - updateContentArea: function cao_updateContentArea (width, height) { - let oldHeight = parseInt(this.styles["content-height"].height); - let oldWidth = parseInt(this.styles["content-width"].width); - - let newWidth = width || this.width; - let newHeight = height || this.contentHeight; - - if (newHeight == oldHeight && newWidth == oldWidth) { - return; - } - - this.styles["content-height"].height = newHeight + "px"; - this.styles["content-height"].maxHeight = newHeight + "px"; - this.styles["content-width"].width = newWidth + "px"; - this.styles["content-width"].maxWidth = newWidth + "px"; - - this.updateViewableArea(newWidth, this._getViewableHeightForContent(newHeight)); - this._dispatchBrowserEvent("ContentSizeChanged"); - }, - - updateViewableArea: function cao_updateViewableArea (width, height) { - let oldHeight = parseInt(this.styles["viewable-height"].height); - let oldWidth = parseInt(this.styles["viewable-width"].width); - - let newWidth = width || this.width; - let newHeight = height || this.viewableHeight; - - if (newHeight == oldHeight && newWidth == oldWidth) { - return; - } - - this.styles["viewable-height"].height = newHeight + "px"; - this.styles["viewable-height"].maxHeight = newHeight + "px"; - this.styles["viewable-width"].width = newWidth + "px"; - this.styles["viewable-width"].maxWidth = newWidth + "px"; - - this.updateAppBarPosition(); - - // Update the back/tab button states. If the keyboard is up - // these are hidden. - BrowserUI._updateButtons(); - - this._dispatchBrowserEvent("ViewableSizeChanged"); - }, - - updateAppBarPosition: function updateAppBarPosition(aForceDown) { - // Adjust the app and find bar position above the soft keyboard - let keyboardHeight = aForceDown ? 0 : Services.metro.keyboardHeight; - Elements.navbar.style.bottom = keyboardHeight + "px"; - Elements.contextappbar.style.bottom = keyboardHeight + "px"; - Elements.findbar.style.bottom = keyboardHeight + "px"; - }, - - /* - * Called by BrowserUI right before we blur the nav bar edit. We use - * this to get a head start on shuffling app bars around before the - * soft keyboard transitions down. - */ - navBarWillBlur: function navBarWillBlur() { - this.updateAppBarPosition(true); - }, - - onBrowserCreated: function onBrowserCreated(aBrowser) { - let notificationBox = aBrowser.parentNode.parentNode; - notificationBox.classList.add("content-width"); - notificationBox.classList.add("content-height"); - }, - - /* - * Event handling - */ - - _onKeyboardDisplayChanging: function _onKeyboardDisplayChanging(aNewState) { - if (aNewState) { - Elements.stack.setAttribute("keyboardVisible", true); - } else { - Elements.stack.removeAttribute("keyboardVisible"); - } - - this.updateViewableArea(); - - if (!aNewState) { - this.shiftBrowserDeck(0); - return; - } - - // Request info about the target form element to see if we - // need to reposition the browser above the keyboard. - if (SelectionHelperUI.layerMode === 2 /*kContentLayer*/) { - Browser.selectedBrowser.messageManager.sendAsyncMessage("Browser:RepositionInfoRequest", { - viewHeight: this.viewableHeight, - }); - } - }, - - _onRepositionResponse: function _onRepositionResponse(aJsonMsg) { - if (!aJsonMsg.reposition || !this.isKeyboardOpened) { - this.shiftBrowserDeck(0); - return; - } - this.shiftBrowserDeck(aJsonMsg.raiseContent); - }, - - observe: function cao_observe(aSubject, aTopic, aData) { - // Note these are fired before the transition starts. Also per MS specs - // we should not do anything "heavy" here. We have about 100ms before - // windows just ignores the event and starts the animation. - switch (aTopic) { - case "metro_softkeyboard_hidden": - case "metro_softkeyboard_shown": - // Mark that we are in a transition state. Auto-complete and other - // popups will wait for an event before displaying anything. - this._deckTransitioning = true; - // This also insures tap events are delivered before we fire - // this event. Form repositioning requires the selection handler - // be running before we send this. - let self = this; - let state = aTopic == "metro_softkeyboard_shown"; - Util.executeSoon(function () { - self._onKeyboardDisplayChanging(state); - }); - break; - } - }, - - handleEvent: function cao_handleEvent(aEvent) { - switch (aEvent.type) { - case 'resize': - if (aEvent.target != window) - return; - ContentAreaObserver.update(); - break; - } - }, - - receiveMessage: function sh_receiveMessage(aMessage) { - switch (aMessage.name) { - case "Content:RepositionInfoResponse": - this._onRepositionResponse(aMessage.json); - break; - } - }, - - /* - * Internal helpers - */ - - _updateViewState: function (aState) { - let oldViewstate = Elements.windowState.getAttribute("viewstate"); - let viewstate = aState || this.viewstate; - if (viewstate != oldViewstate) { - Elements.windowState.setAttribute("viewstate", viewstate); - Services.obs.notifyObservers(null, "metro_viewstate_changed", viewstate); - } - }, - - shiftBrowserDeck: function (aAmount) { - if (aAmount == 0) { - this._deckTransitioning = false; - this._dispatchWindowEvent("KeyboardChanged", this.isKeyboardOpened); - } - - if (this._shiftAmount == aAmount) - return; - - this._shiftAmount = aAmount; - this._dispatchWindowEvent("MozDeckOffsetChanging", aAmount); - - // Elements.browsers is the deck all browsers sit in - let self = this; - Elements.browsers.addEventListener("transitionend", function () { - Elements.browsers.removeEventListener("transitionend", arguments.callee, true); - self._deckTransitioning = false; - self._dispatchWindowEvent("MozDeckOffsetChanged", aAmount); - self._dispatchWindowEvent("KeyboardChanged", self.isKeyboardOpened); - }, true); - - // selectAtPoint bug 858471 - //Elements.browsers.style.transform = "translateY(" + (-1 * aAmount) + "px)"; - Elements.browsers.style.marginTop = "" + (-1 * aAmount) + "px"; - }, - - _dispatchWindowEvent: function _dispatchWindowEvent(aEventName, aDetail) { - let event = document.createEvent("UIEvents"); - event.initUIEvent(aEventName, true, false, window, aDetail); - window.dispatchEvent(event); - }, - - _dispatchBrowserEvent: function (aName, aDetail) { - setTimeout(function() { - let event = document.createEvent("Events"); - event.initEvent(aName, true, false); - Elements.browsers.dispatchEvent(event); - }, 0); - }, - - _initStyles: function _initStyles() { - let stylesheet = document.styleSheets[0]; - for (let style of ["window-width", "window-height", - "content-height", "content-width", - "viewable-height", "viewable-width"]) { - let index = stylesheet.insertRule("." + style + " {}", stylesheet.cssRules.length); - this.styles[style] = stylesheet.cssRules[index].style; - } - }, - - _getContentHeightForWindow: function (windowHeight) { - return windowHeight; - }, - - _getViewableHeightForContent: function (contentHeight) { - let keyboardHeight = Services.metro.keyboardHeight; - return contentHeight - keyboardHeight; - }, - - _debugDumpDims: function _debugDumpDims() { - let width = parseInt(this.styles["window-width"].width); - let height = parseInt(this.styles["window-height"].height); - Util.dumpLn("window:", width, height); - width = parseInt(this.styles["content-width"].width); - height = parseInt(this.styles["content-height"].height); - Util.dumpLn("content:", width, height); - width = parseInt(this.styles["viewable-width"].width); - height = parseInt(this.styles["viewable-height"].height); - Util.dumpLn("viewable:", width, height); - } -}; diff --git a/browser/metro/base/content/ContextCommands.js b/browser/metro/base/content/ContextCommands.js deleted file mode 100644 index 02939458a45..00000000000 --- a/browser/metro/base/content/ContextCommands.js +++ /dev/null @@ -1,436 +0,0 @@ -// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - - /* - * context menu command handlers - */ - -var ContextCommands = { - _picker: null, - - get _ellipsis() { - delete this._ellipsis; - this._ellipsis = "\u2026"; - try { - this._ellipsis = Services.prefs.getComplexValue("intl.ellipsis", Ci.nsIPrefLocalizedString).data; - } catch (ex) { } - return this._ellipsis; - }, - - get clipboard() { - return Cc["@mozilla.org/widget/clipboardhelper;1"] - .getService(Ci.nsIClipboardHelper); - }, - - get docRef() { - return Browser.selectedBrowser.contentWindow.document; - }, - - /* - * Context menu handlers - */ - - // Text specific - - cut: function cc_cut() { - let target = ContextMenuUI.popupState.target; - - if (!target) { - return; - } - - if (target.localName === "browser") { - // content - if (ContextMenuUI.popupState.string) { - this.sendCommand("cut"); - - SelectionHelperUI.closeEditSession(true); - } - } else { - // chrome - CommandUpdater.doCommand("cmd_cut"); - } - - target.focus(); - }, - - copy: function cc_copy() { - let target = ContextMenuUI.popupState.target; - - if (!target) { - return; - } - - if (target.localName == "browser") { - // content - if (ContextMenuUI.popupState.string) { - this.sendCommand("copy"); - } - } else if (ContextMenuUI.popupState.string) { - this.clipboard.copyString(ContextMenuUI.popupState.string, this.docRef); - } else { - // chrome - CommandUpdater.doCommand("cmd_copy"); - } - - target.focus(); - }, - - paste: function cc_paste() { - let target = ContextMenuUI.popupState.target; - - if (!target) { - return; - } - - if (target.localName == "browser") { - // content - let x = ContextMenuUI.popupState.x; - let y = ContextMenuUI.popupState.y; - let json = {x: x, y: y, command: "paste" }; - target.messageManager.sendAsyncMessage("Browser:ContextCommand", json); - } else { - // chrome - CommandUpdater.doCommand("cmd_paste"); - target.focus(); - } - SelectionHelperUI.closeEditSession(); - }, - - pasteAndGo: function cc_pasteAndGo() { - let target = ContextMenuUI.popupState.target; - target.editor.selectAll(); - target.editor.paste(Ci.nsIClipboard.kGlobalClipboard); - BrowserUI.goToURI(); - }, - - select: function cc_select() { - SelectionHelperUI.openEditSession(ContextMenuUI.popupState.target, - ContextMenuUI.popupState.xPos, - ContextMenuUI.popupState.yPos, - true); - }, - - selectAll: function cc_selectAll() { - let target = ContextMenuUI.popupState.target; - if (target.localName == "browser") { - // content - let x = ContextMenuUI.popupState.xPos; - let y = ContextMenuUI.popupState.yPos; - let json = {x: x, y: y, command: "select-all" }; - target.messageManager.sendAsyncMessage("Browser:ContextCommand", json); - SelectionHelperUI.attachEditSession(target, x, y); - } else { - // chrome - target.editor.selectAll(); - target.focus(); - } - }, - - // called on display of the search text menu item - searchTextSetup: function cc_searchTextSetup(aRichListItem, aSearchString) { - let defaultURI; - let defaultName; - aSearchString = aSearchString.trim(); - try { - let defaultPB = Services.prefs.getDefaultBranch(null); - const nsIPLS = Ci.nsIPrefLocalizedString; - defaultName = defaultPB.getComplexValue("browser.search.defaultenginename", nsIPLS).data; - let defaultEngine = Services.search.getEngineByName(defaultName); - defaultURI = defaultEngine.getSubmission(aSearchString).uri.spec; - } catch (ex) { - Cu.reportError(ex); - return false; - } - let displayString = aSearchString; - if (displayString.length > 15) { - displayString = displayString.substring(0, 15) + this._ellipsis; - } - // label child node - let label = Services.strings - .createBundle("chrome://browser/locale/browser.properties") - .formatStringFromName("browser.search.contextTextSearchLabel2", - [defaultName, displayString], 2); - aRichListItem.childNodes[0].setAttribute("value", label); - aRichListItem.setAttribute("searchString", defaultURI); - return true; - }, - - searchText: function cc_searchText(aRichListItem) { - let defaultURI = aRichListItem.getAttribute("searchString"); - aRichListItem.childNodes[0].setAttribute("value", ""); - aRichListItem.setAttribute("searchString", ""); - BrowserUI.addAndShowTab(defaultURI, Browser.selectedTab); - }, - - // Link specific - - openLinkInNewTab: function cc_openLinkInNewTab() { - let url = ContextMenuUI.popupState.linkURL; - BrowserUI.openLinkInNewTab(url, false, Browser.selectedTab); - }, - - copyLink: function cc_copyLink() { - this.clipboard.copyString(ContextMenuUI.popupState.linkURL, - this.docRef); - }, - - bookmarkLink: function cc_bookmarkLink() { - let state = ContextMenuUI.popupState; - let uri = Util.makeURI(state.linkURL); - let title = state.linkTitle || state.linkURL; - - try { - Bookmarks.addForURI(uri, title); - } catch (e) { - return; - } - }, - - // Image specific - - saveImageToLib: function cc_saveImageToLib() { - this.saveToWinLibrary("Pict"); - }, - - copyImage: function cc_copyImage() { - // copy to clibboard - this.sendCommand("copy-image-contents"); - }, - - copyImageSrc: function cc_copyImageSrc() { - this.clipboard.copyString(ContextMenuUI.popupState.mediaURL, - this.docRef); - }, - - openImageInNewTab: function cc_openImageInNewTab() { - BrowserUI.addAndShowTab(ContextMenuUI.popupState.mediaURL, Browser.selectedTab); - }, - - // Video specific - - saveVideoToLib: function cc_saveVideoToLib() { - this.saveToWinLibrary("Vids"); - }, - - copyVideoSrc: function cc_copyVideoSrc() { - this.clipboard.copyString(ContextMenuUI.popupState.mediaURL, - this.docRef); - }, - - openVideoInNewTab: function cc_openVideoInNewTab() { - BrowserUI.addAndShowTab(ContextMenuUI.popupState.mediaURL, Browser.selectedTab); - }, - - // Bookmarks - - editBookmark: function cc_editBookmark() { - let target = ContextMenuUI.popupState.target; - target.startEditing(); - }, - - removeBookmark: function cc_removeBookmark() { - let target = ContextMenuUI.popupState.target; - target.remove(); - }, - - // App bar - - errorConsole: function cc_errorConsole() { - PanelUI.show("console-container"); - }, - - jsShell: function cc_jsShell() { - // XXX for debugging, this only works when running on the desktop. - if (!Services.metro.immersive) - window.openDialog("chrome://browser/content/shell.xul", "_blank", - "all=no,scrollbars=yes,resizable=yes,dialog=no"); - }, - - findInPage: function cc_findInPage() { - FindHelperUI.show(); - }, - - viewOnDesktop: function cc_viewOnDesktop() { - Appbar.onViewOnDesktop(); - }, - - // Checks for MS app store specific meta data, and if present opens - // the Windows Store to the appropriate app - openWindowsStoreLink: function cc_openWindowsStoreLink() { - let storeLink = this.getStoreLink(); - if (storeLink) { - Browser.selectedBrowser.contentWindow.document.location = storeLink; - } - }, - - getStoreLink: function cc_getStoreLink() { - let metaData = Browser.selectedBrowser.contentWindow.document.getElementsByTagName("meta"); - let msApplicationName = metaData.namedItem("msApplication-PackageFamilyName"); - if (msApplicationName) { - return "ms-windows-store:PDP?PFN=" + msApplicationName.getAttribute("content"); - } - return null; - }, - - getPageSource: function cc_getPageSource() { - let uri = Services.io.newURI(Browser.selectedBrowser.currentURI.spec, null, null); - if (!uri.schemeIs("view-source")) { - return "view-source:" + Browser.selectedBrowser.currentURI.spec; - } - return null; - }, - - viewPageSource: function cc_viewPageSource() { - let uri = this.getPageSource(); - if (uri) { - BrowserUI.addAndShowTab(uri, Browser.selectedTab); - } - }, - - /* - * Utilities - */ - - saveToWinLibrary: function cc_saveToWinLibrary(aType) { - let popupState = ContextMenuUI.popupState; - let browser = popupState.target; - - // ContentAreaUtils internalSave relies on various desktop related prefs, - // values, and functionality. We want to be more direct by saving the - // image to the users Windows Library. If users want to specify the - // save location they can use the context menu option 'Save (type) To'. - - let dirSvc = Components.classes["@mozilla.org/file/directory_service;1"] - .getService(Components.interfaces.nsIProperties); - let saveLocationPath = dirSvc.get(aType, Components.interfaces.nsIFile); - - let fileInfo = new ContentAreaUtils.FileInfo(); - ContentAreaUtils.initFileInfo(fileInfo, popupState.mediaURL, - browser.documentURI.originCharset, - null, null, null); - let filename = - ContentAreaUtils.getNormalizedLeafName(fileInfo.fileName, fileInfo.fileExt); - saveLocationPath.append(filename); - - // Start the background save process - ContentAreaUtils.internalPersist({ - sourceURI : fileInfo.uri, - sourceDocument : null, - sourceReferrer : browser.documentURI, - targetContentType : popupState.contentType, - targetFile : saveLocationPath, - sourceCacheKey : null, - sourcePostData : null, - bypassCache : false, - initiatingWindow : this.docRef.defaultView - }); - }, - - sendCommand: function sendCommand(aCommand) { - // Send via message manager over to ContextMenuHandler - let browser = ContextMenuUI.popupState.target; - browser.messageManager.sendAsyncMessage("Browser:ContextCommand", { command: aCommand }); - }, - - /* - * isAccessibleDirectory - * - * Test to see if the directory exists and is writable. - */ - isAccessibleDirectory: function isAccessibleDirectory(aDirectory) { - return aDirectory && aDirectory.exists() && aDirectory.isDirectory() && - aDirectory.isWritable(); - }, - - /* - * saveFileAs - * - * Browse for a location and then save a file to the local system using - * standard download prefs. - * - * @param aFileUriString path to file - */ - saveFileAs: function saveFileAs(aPopupState) { - let srcUri = null; - let mediaURL = aPopupState.mediaURL; - try { - srcUri = Util.makeURI(mediaURL, null, null); - } catch (ex) { - Util.dumpLn("could not parse:", mediaURL); - return; - } - - let picker = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); - let windowTitle = Strings.browser.GetStringFromName("browserForSaveLocation"); - - picker.init(window, windowTitle, Ci.nsIFilePicker.modeSave); - - // prefered filename - let fileName = mediaURL.substring(mediaURL.lastIndexOf("/") + 1); - if (fileName.length) - picker.defaultString = fileName; - - // prefered file extension - let fileExtension = mediaURL.substring(mediaURL.lastIndexOf(".") + 1); - if (fileExtension.length) - picker.defaultExtension = fileExtension; - picker.appendFilters(Ci.nsIFilePicker.filterImages); - - // prefered save location - Task.spawn(function() { - let preferredDir = yield Downloads.getPreferredDownloadsDirectory(); - picker.displayDirectory = new FileUtils.File(preferredDir); - - try { - let lastDir = Services.prefs.getComplexValue("browser.download.lastDir", Ci.nsILocalFile); - if (this.isAccessibleDirectory(lastDir)) - picker.displayDirectory = lastDir; - } - catch (e) { } - - this._picker = picker; - this._pickerUrl = mediaURL; - this._pickerContentDisp = aPopupState.contentDisposition; - this._contentType = aPopupState.contentType; - picker.open(ContextCommands); - }.bind(this)); - }, - - /* - * Filepicker callback - */ - done: function done(aSuccess) { - let picker = this._picker; - this._picker = null; - - if (aSuccess == Ci.nsIFilePicker.returnCancel) - return; - - let file = picker.file; - if (file == null) - return; - - try { - if (file.exists()) - file.remove(false); - } catch (e) {} - - ContentAreaUtils.internalSave(this._pickerUrl, null, null, - this._pickerContentDisp, - this._contentType, false, "SaveImageTitle", - new AutoChosen(file, Util.makeURI(this._pickerUrl, null, null)), - getBrowser().documentURI, this.docRef, true, null); - - var newDir = file.parent.QueryInterface(Ci.nsILocalFile); - Services.prefs.setComplexValue("browser.download.lastDir", Ci.nsILocalFile, newDir); - }, -}; - -function AutoChosen(aFileAutoChosen, aUriAutoChosen) { - this.file = aFileAutoChosen; - this.uri = aUriAutoChosen; -} - diff --git a/browser/metro/base/content/ContextUI.js b/browser/metro/base/content/ContextUI.js deleted file mode 100644 index 96248a1661c..00000000000 --- a/browser/metro/base/content/ContextUI.js +++ /dev/null @@ -1,399 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -// Fired when the tabtray is displayed -const kContextUITabsShowEvent = "MozContextUITabsShow"; -// add more as needed... - -/* - * Manages context UI (navbar, tabbar, appbar) and track visibility. Also - * tracks events that summon and hide the context UI. - */ -var ContextUI = { - _expandable: true, - _hidingId: 0, - - /******************************************* - * init - */ - - init: function init() { - Elements.browsers.addEventListener('URLChanged', this, true); - Elements.browsers.addEventListener("AlertActive", this, true); - Elements.browsers.addEventListener("AlertClose", this, true); - Elements.tabList.addEventListener('TabSelect', this, true); - Elements.panelUI.addEventListener('ToolPanelShown', this, false); - Elements.panelUI.addEventListener('ToolPanelHidden', this, false); - - Elements.tray.addEventListener("mousemove", this, false); - Elements.tray.addEventListener("mouseleave", this, false); - - window.addEventListener("touchstart", this, true); - window.addEventListener("mousedown", this, true); - window.addEventListener("MozEdgeUIStarted", this, true); - window.addEventListener("MozEdgeUICanceled", this, true); - window.addEventListener("MozEdgeUICompleted", this, true); - window.addEventListener("keypress", this, true); - window.addEventListener("KeyboardChanged", this, false); - window.addEventListener("MozFlyoutPanelShowing", this, false); - - Elements.tray.addEventListener("transitionend", this, true); - - Appbar.init(); - }, - - /******************************************* - * Context UI state getters & setters - */ - - // any visiblilty - get isVisible() { - return this.navbarVisible || this.tabbarVisible || this.contextAppbarVisible; - }, - - // navbar visiblilty - get navbarVisible() { - return (Elements.navbar.hasAttribute("visible") || - Elements.navbar.hasAttribute("startpage")); - }, - - // tabbar visiblilty - get tabbarVisible() { - return Elements.tray.hasAttribute("expanded"); - }, - - // appbar visiblilty - get contextAppbarVisible() { - return Elements.contextappbar.isShowing; - }, - - // currently not in use, for the always show tabs feature - get isExpandable() { return this._expandable; }, - set isExpandable(aFlag) { - this._expandable = aFlag; - if (!this._expandable) - this.dismiss(); - }, - - /******************************************* - * Public api - */ - - /* - * Toggle the current nav UI state. Fires context ui events. - */ - toggleNavUI: function () { - // The navbar is forced open when the start page is visible. appbar.js - // controls the "visible" property, and browser-ui controls the "startpage" - // property. Hence we rely on the tabbar for current toggle state. - if (this.tabbarVisible) { - this.dismiss(); - } else { - this.displayNavUI(); - } - }, - - /* - * Show the nav and tabs bar. Returns true if any non-visible UI - * was shown. Fires context ui events. - */ - displayNavUI: function () { - let shown = false; - - if (!this.navbarVisible) { - BrowserUI.updateURI(); - this.displayNavbar(); - shown = true; - } - - if (!this.tabbarVisible) { - this.displayTabs(); - shown = true; - } - - if (shown) { - ContentAreaObserver.updateContentArea(); - } - - return shown; - }, - - /* - * Dismiss any context UI currently visible. Returns true if any - * visible UI was dismissed. Fires context ui events. - */ - dismiss: function () { - let dismissed = false; - - this._clearDelayedTimeout(); - - // No assurances this will hide the nav bar. It may have the - // 'startpage' property set. This removes the 'visible' property. - if (this.navbarVisible) { - BrowserUI.blurNavBar(); - this.dismissNavbar(); - dismissed = true; - } - if (this.tabbarVisible) { - this.dismissTabs(); - dismissed = true; - } - if (Elements.contextappbar.isShowing) { - this.dismissContextAppbar(); - dismissed = true; - } - - if (dismissed) { - ContentAreaObserver.updateContentArea(); - } - - return dismissed; - }, - - /* - * Briefly show the tab bar and then hide it. Fires context ui events. - */ - peekTabs: function peekTabs(aDelay) { - if (!this.tabbarVisible) - this.displayTabs(); - - ContextUI.dismissTabsWithDelay(aDelay); - }, - - /* - * Dismiss tab bar after a delay. Fires context ui events. - */ - dismissTabsWithDelay: function (aDelay) { - aDelay = aDelay || kForegroundTabAnimationDelay; - this._clearDelayedTimeout(); - this._lastTimeoutDelay = aDelay; - this._hidingId = setTimeout(function () { - ContextUI.dismissTabs(); - }, aDelay); - }, - - /* - * Display the nav bar. - * - * @return false if we were already visible, and didn't do anything. - */ - displayNavbar: function () { - if (Elements.chromeState.getAttribute("navbar") == "visible") { - return false; - } - - Elements.navbar.show(); - Elements.chromeState.setAttribute("navbar", "visible"); - ContentAreaObserver.updateContentArea(); - return true; - }, - - // Display the tab tray - displayTabs: function () { - this._clearDelayedTimeout(); - this._setIsExpanded(true); - }, - - // Dismiss the navbar if visible. - dismissNavbar: function dismissNavbar() { - if (!BrowserUI.isStartTabVisible) { - Elements.autocomplete.closePopup(); - Elements.navbar.dismiss(); - Elements.chromeState.removeAttribute("navbar"); - ContentAreaObserver.updateContentArea(); - } - }, - - // Dismiss the tabstray if visible. - dismissTabs: function dimissTabs() { - this._clearDelayedTimeout(); - this._setIsExpanded(false); - }, - - // Dismiss the appbar if visible. - dismissContextAppbar: function dismissContextAppbar() { - Elements.contextappbar.dismiss(); - }, - - /******************************************* - * Internal utils - */ - - // tabtray state - _setIsExpanded: function _setIsExpanded(aFlag, setSilently) { - // if the tray can't be expanded, don't expand it. - if (!this.isExpandable || this.tabbarVisible == aFlag) - return; - - if (aFlag) - Elements.tray.setAttribute("expanded", "true"); - else - Elements.tray.removeAttribute("expanded"); - - if (!setSilently) - this._fire(kContextUITabsShowEvent); - }, - - _clearDelayedTimeout: function _clearDelayedTimeout() { - if (this._hidingId) { - clearTimeout(this._hidingId); - this._hidingId = 0; - this._delayedHide = false; - } - }, - - _resetDelayedTimeout: function () { - this._hidingId = setTimeout(function () { - ContextUI.dismissTabs(); - }, this._lastTimeoutDelay); - }, - - /******************************************* - * Events - */ - - _onEdgeUIStarted: function(aEvent) { - this._hasEdgeSwipeStarted = true; - this._clearDelayedTimeout(); - this.toggleNavUI(); - }, - - _onEdgeUICanceled: function(aEvent) { - this._hasEdgeSwipeStarted = false; - this.dismiss(); - }, - - _onEdgeUICompleted: function(aEvent) { - if (this._hasEdgeSwipeStarted) { - this._hasEdgeSwipeStarted = false; - return; - } - - this._clearDelayedTimeout(); - this.toggleNavUI(); - }, - - onDownInput: function onDownInput(aEvent) { - if (!this.isVisible) { - return; - } - - // Various ui element containers we do not update context ui for. - let whitelist = [ - // Clicks on tab bar elements should not close the tab bar. the tabbar - // handles this. - Elements.tabs, - // Don't let a click on an infobar button dismiss the appbar or navbar. - // Note the notification box should always hover above these other two - // bars. - Browser.getNotificationBox() - ]; - - if (whitelist.some(elem => elem.contains(aEvent.target))) { - return; - } - - // If a start tab is visible only dismiss the tab bar. - if (BrowserUI.isStartTabVisible) { - ContextUI.dismissTabs(); - return; - } - - // content, dismiss anything visible - if (aEvent.target.ownerDocument.defaultView.top == getBrowser().contentWindow) { - this.dismiss(); - return; - } - - // dismiss tabs and context app bar if visible - this.dismissTabs(); - this.dismissContextAppbar(); - }, - - onMouseMove: function (aEvent) { - if (this._hidingId) { - this._clearDelayedTimeout(); - this._delayedHide = true; - } - }, - - onMouseLeave: function (aEvent) { - if (this._delayedHide) { - this._delayedHide = false; - this._resetDelayedTimeout(); - } - }, - - handleEvent: function handleEvent(aEvent) { - switch (aEvent.type) { - case "URLChanged": - // "aEvent.detail" is a boolean value that indicates whether actual URL - // has changed ignoring URL fragment changes. - if (aEvent.target == Browser.selectedBrowser && aEvent.detail) { - this.displayNavbar(); - } - break; - case "MozEdgeUIStarted": - this._onEdgeUIStarted(aEvent); - break; - case "MozEdgeUICanceled": - this._onEdgeUICanceled(aEvent); - break; - case "MozEdgeUICompleted": - this._onEdgeUICompleted(aEvent); - break; - case "keypress": - if (String.fromCharCode(aEvent.which) == "z" && - aEvent.getModifierState("Win")) - this.toggleNavUI(); - break; - case "transitionend": - setTimeout(function () { - ContentAreaObserver.updateContentArea(); - }, 0); - break; - case "KeyboardChanged": - this.dismissTabs(); - break; - case "mousedown": - if (aEvent.button != 0) { - break; - } - this.onDownInput(aEvent); - break; - case "mousemove": - this.onMouseMove(aEvent); - break; - case "mouseleave": - this.onMouseLeave(aEvent); - break; - case "touchstart": - this.onDownInput(aEvent); - break; - case "ToolPanelShown": - case "ToolPanelHidden": - this.dismiss(); - break; - case "AlertActive": - case "AlertClose": - case "TabSelect": - ContentAreaObserver.updateContentArea(); - break; - case "MozFlyoutPanelShowing": - if (BrowserUI.isStartTabVisible) { - this.dismissTabs(); - this.dismissContextAppbar(); - } else { - this.dismiss(); - } - break; - } - }, - - _fire: function (name) { - let event = document.createEvent("Events"); - event.initEvent(name, true, true); - window.dispatchEvent(event); - } -}; diff --git a/browser/metro/base/content/NavButtonSlider.js b/browser/metro/base/content/NavButtonSlider.js deleted file mode 100644 index 73ab72401d1..00000000000 --- a/browser/metro/base/content/NavButtonSlider.js +++ /dev/null @@ -1,217 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * Handles nav overlay button positioning. - */ - -// minimum amount of movement using the mouse after which we cancel the button click handlers -const kOnClickMargin = 3; - -const kNavButtonPref = "browser.display.overlaynavbuttons"; - -var NavButtonSlider = { - _back: document.getElementById("overlay-back"), - _plus: document.getElementById("overlay-plus"), - _mouseMoveStarted: false, - _mouseDown: false, - _yPos: -1, - - get back() { - return this._back; - }, - - get plus() { - return this._plus; - }, - - /* - * custom dragger, see input.js - */ - - freeDrag: function freeDrag() { - return true; - }, - - isDraggable: function isDraggable(aTarget, aContent) { - return { x: false, y: true }; - }, - - dragStart: function dragStart(aX, aY, aTarget, aScroller) { - return true; - }, - - dragStop: function dragStop(aDx, aDy, aScroller) { - return true; - }, - - dragMove: function dragMove(aDx, aDy, aScroller, aIsKenetic, aClientX, aClientY) { - // Note if aIsKenetic is true this is synthetic movement, - // we don't want that so return false. - if (aIsKenetic) { - return false; - } - - this._updatePosition(aClientY); - - // return true if we moved, false otherwise. The result - // is used in deciding if we should repaint between drags. - return true; - }, - - /* - * logic - */ - - init: function init() { - // Touch drag support provided by input.js - this._back.customDragger = this; - this._plus.customDragger = this; - Elements.browsers.addEventListener("ContentSizeChanged", this, true); - let events = ["mousedown", "mouseup", "mousemove", "click", "touchstart", "touchmove", "touchend"]; - events.forEach(function (value) { - this._back.addEventListener(value, this, true); - this._plus.addEventListener(value, this, true); - }, this); - - this._updateStops(); - this._updateVisibility(); - Services.prefs.addObserver(kNavButtonPref, this, false); - }, - - observe: function (aSubject, aTopic, aData) { - if (aTopic == "nsPref:changed" && aData == kNavButtonPref) { - this._updateVisibility(); - } - }, - - _updateVisibility: function () { - if (Services.prefs.getBoolPref(kNavButtonPref)) { - this._back.removeAttribute("hidden"); - this._plus.removeAttribute("hidden"); - } else { - this._back.setAttribute("hidden", true); - this._plus.setAttribute("hidden", true); - } - }, - - _updateStops: function () { - this._contentHeight = ContentAreaObserver.contentHeight; - this._imageHeight = 118; - this._topStop = this._imageHeight * .7; - this._bottomStop = this._contentHeight - (this._imageHeight * .7); - - // Check to see if we need to move the slider into view - if (this._yPos != -1 && - (this._topStop > this._yPos || this._bottomStop < this._yPos)) { - this._back.style.top = "50%"; - this._plus.style.top = "50%"; - } - }, - - _getPosition: function _getPosition() { - this._yPos = parseInt(getComputedStyle(this._back).top); - }, - - _setPosition: function _setPosition() { - this._back.style.top = this._yPos + "px"; - this._plus.style.top = this._yPos + "px"; - }, - - _updatePosition: function (aClientY) { - if (this._topStop > aClientY || this._bottomStop < aClientY) - return; - this._yPos = aClientY; - this._setPosition(); - }, - - _updateOffset: function (aOffset) { - let newPos = this._yPos + aOffset; - if (this._topStop > newPos || this._bottomStop < newPos) - return; - this._yPos = newPos; - this._setPosition(); - }, - - /* - * Events - */ - - handleEvent: function handleEvent(aEvent) { - switch (aEvent.type) { - case "ContentSizeChanged": - this._updateStops(); - break; - - case "touchstart": - if (aEvent.touches.length != 1) - break; - aEvent.preventDefault(); - aEvent = aEvent.touches[0]; - case "mousedown": - this._getPosition(); - this._mouseDown = true; - this._mouseMoveStarted = false; - this._mouseY = aEvent.clientY; - if (aEvent.originalTarget) - aEvent.originalTarget.setCapture(); - this._back.setAttribute("mousedrag", true); - this._plus.setAttribute("mousedrag", true); - break; - - case "touchend": - if (aEvent.touches.length != 0) - break; - this._mouseDown = false; - this._back.removeAttribute("mousedrag"); - this._plus.removeAttribute("mousedrag"); - if (!this._mouseMoveStarted) { - if (aEvent.originalTarget == this._back) { - CommandUpdater.doCommand('cmd_back'); - } else { - CommandUpdater.doCommand('cmd_newTab'); - } - } - break; - case "mouseup": - this._mouseDown = false; - this._back.removeAttribute("mousedrag"); - this._plus.removeAttribute("mousedrag"); - break; - - case "touchmove": - if (aEvent.touches.length != 1) - break; - aEvent = aEvent.touches[0]; - case "mousemove": - // Check to be sure this is a drag operation - if (!this._mouseDown) { - return; - } - // Don't start a drag until we've passed a threshold - let dy = aEvent.clientY - this._mouseY; - if (!this._mouseMoveStarted && Math.abs(dy) < kOnClickMargin) { - return; - } - // Start dragging via the mouse - this._mouseMoveStarted = true; - this._mouseY = aEvent.clientY; - this._updateOffset(dy); - break; - case "click": - // Don't invoke the click action if we've moved the buttons via the mouse. - if (this._mouseMoveStarted) { - return; - } - if (aEvent.originalTarget == this._back) { - CommandUpdater.doCommand('cmd_back'); - } else { - CommandUpdater.doCommand('cmd_newTab'); - } - break; - } - }, -}; - - diff --git a/browser/metro/base/content/Site.js b/browser/metro/base/content/Site.js deleted file mode 100644 index 98fea8666cf..00000000000 --- a/browser/metro/base/content/Site.js +++ /dev/null @@ -1,74 +0,0 @@ -// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -'use strict'; - -/** - * dumb model class to provide default values for sites. - * link parameter/model object expected to have a .url property, and optionally .title - */ -function Site(aLink) { - if (!aLink.url) { - throw Cr.NS_ERROR_INVALID_ARG; - } - this._link = aLink; -} - -Site.prototype = { - icon: '', - get url() { - return this._link.url; - }, - get title() { - // use url if no title was recorded - return this._link.title || this._link.url; - }, - get label() { - // alias for .title - return this.title; - }, - get pinned() { - return NewTabUtils.pinnedLinks.isPinned(this); - }, - get contextActions() { - return [ - 'delete', // delete means hide here - this.pinned ? 'unpin' : 'pin' - ]; - }, - get blocked() { - return NewTabUtils.blockedLinks.isBlocked(this); - }, - get attributeValues() { - return { - value: this.url, - label: this.title, - pinned: this.pinned ? true : undefined, - selected: this.selected, - customColor: this.color, - customImage: this.backgroundImage, - iconURI: this.icon, - "data-contextactions": this.contextActions.join(',') - }; - }, - applyToTileNode: function(aNode) { - // apply this site's properties as attributes on a tile element - // the decorated node acts as a view-model for the tile binding - let attrs = this.attributeValues; - for (let key in attrs) { - if (undefined === attrs[key]) { - aNode.removeAttribute(key); - } else { - aNode.setAttribute(key, attrs[key]); - } - } - // is binding already applied? - if ('refresh' in aNode) { - // just update it - aNode.refresh(); - } else { - // these attribute values will get picked up later when the binding is applied - } - } -}; diff --git a/browser/metro/base/content/TopSites.js b/browser/metro/base/content/TopSites.js deleted file mode 100644 index 5da49bb925e..00000000000 --- a/browser/metro/base/content/TopSites.js +++ /dev/null @@ -1,158 +0,0 @@ -// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -'use strict'; - -/** - * singleton to provide data-level functionality to the views - */ -let TopSites = { - prepareCache: function(aForce){ - // front to the NewTabUtils' links cache - // -ensure NewTabUtils.links links are pre-cached - - // avoid re-fetching links data while a fetch is in flight - if (this._promisedCache && !aForce) { - return this._promisedCache; - } - let deferred = Promise.defer(); - this._promisedCache = deferred.promise; - - NewTabUtils.links.populateCache(function () { - deferred.resolve(); - this._promisedCache = null; - this._sites = null; // reset our sites cache so they are built anew - this._sitesDirty.clear(); - }.bind(this), true); - return this._promisedCache; - }, - - _sites: null, - _sitesDirty: new Set(), - getSites: function() { - if (this._sites) { - return this._sites; - } - - let links = NewTabUtils.links.getLinks(); - let sites = links.map(function(aLink){ - let site = new Site(aLink); - return site; - }); - - // reset state - this._sites = sites; - this._sitesDirty.clear(); - return this._sites; - }, - - /** - * Get list of top site as in need of update/re-render - * @param aSite Optionally add Site arguments to be refreshed/updated - */ - dirty: function() { - // add any arguments for more fine-grained updates rather than invalidating the whole collection - for (let i=0; i -1) { - NewTabUtils.pinnedLinks.pin(site, pinIndex); - } - } - // clear out the cache, we'll fetch and re-render - this._sites = null; - this._sitesDirty.clear(); - this.update(); - }, - - _linkFromNode: function _linkFromNode(aNode) { - return { - url: aNode.getAttribute("value"), - title: aNode.getAttribute("label") - }; - } -}; - diff --git a/browser/metro/base/content/Util.js b/browser/metro/base/content/Util.js deleted file mode 100644 index bb3512f0eb3..00000000000 --- a/browser/metro/base/content/Util.js +++ /dev/null @@ -1,430 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -let Cc = Components.classes; -let Ci = Components.interfaces; - -Components.utils.import("resource:///modules/ContentUtil.jsm"); - -let Util = { - /* - * General purpose utilities - */ - - getWindowUtils: function getWindowUtils(aWindow) { - return aWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils); - }, - - // Put the Mozilla networking code into a state that will kick the - // auto-connection process. - forceOnline: function forceOnline() { - Services.io.offline = false; - }, - - /* - * Timing utilties - */ - - // Executes aFunc after other events have been processed. - executeSoon: function executeSoon(aFunc) { - Services.tm.mainThread.dispatch({ - run: function() { - aFunc(); - } - }, Ci.nsIThread.DISPATCH_NORMAL); - }, - - /* - * Console printing utilities - */ - - // Like dump, but each arg is handled and there's an automatic newline - dumpLn: function dumpLn() { - for (let i = 0; i < arguments.length; i++) - dump(arguments[i] + " "); - dump("\n"); - }, - - /* - * Element utilities - */ - - transitionElementVisibility: function(aNodes, aVisible) { - // accept single node or a collection of nodes - aNodes = aNodes.length ? aNodes : [aNodes]; - let defd = Promise.defer(); - let pending = 0; - Array.forEach(aNodes, function(aNode) { - if (aVisible) { - aNode.hidden = false; - aNode.removeAttribute("fade"); // trigger transition to full opacity - } else { - aNode.setAttribute("fade", true); // trigger transition to 0 opacity - } - aNode.addEventListener("transitionend", function onTransitionEnd(aEvent){ - aNode.removeEventListener("transitionend", onTransitionEnd); - if (!aVisible) { - aNode.hidden = true; - } - pending--; - if (!pending){ - defd.resolve(true); - } - }, false); - pending++; - }); - return defd.promise; - }, - - isTextInput: function isTextInput(aElement) { - return ((aElement instanceof Ci.nsIDOMHTMLInputElement && - aElement.mozIsTextField(false)) || - aElement instanceof Ci.nsIDOMHTMLTextAreaElement); - }, - - /** - * Checks whether aElement's content can be edited either if it(or any of its - * parents) has "contenteditable" attribute set to "true" or aElement's - * ownerDocument is in design mode. - */ - isEditableContent: function isEditableContent(aElement) { - return !!aElement && (aElement.isContentEditable || - this.isOwnerDocumentInDesignMode(aElement)); - - }, - - isEditable: function isEditable(aElement) { - if (!aElement) { - return false; - } - - if (this.isTextInput(aElement) || this.isEditableContent(aElement)) { - return true; - } - - // If a body element is editable and the body is the child of an - // iframe or div we can assume this is an advanced HTML editor - if ((aElement instanceof Ci.nsIDOMHTMLIFrameElement || - aElement instanceof Ci.nsIDOMHTMLDivElement) && - aElement.contentDocument && - this.isEditableContent(aElement.contentDocument.body)) { - return true; - } - - return false; - }, - - /** - * Checks whether aElement's owner document has design mode turned on. - */ - isOwnerDocumentInDesignMode: function(aElement) { - return !!aElement && !!aElement.ownerDocument && - aElement.ownerDocument.designMode == "on"; - }, - - isMultilineInput: function isMultilineInput(aElement) { - return (aElement instanceof Ci.nsIDOMHTMLTextAreaElement); - }, - - isLink: function isLink(aElement) { - return ((aElement instanceof Ci.nsIDOMHTMLAnchorElement && aElement.href) || - (aElement instanceof Ci.nsIDOMHTMLAreaElement && aElement.href) || - aElement instanceof Ci.nsIDOMHTMLLinkElement || - aElement.getAttributeNS(kXLinkNamespace, "type") == "simple"); - }, - - isText: function isText(aElement) { - return (aElement instanceof Ci.nsIDOMHTMLParagraphElement || - aElement instanceof Ci.nsIDOMHTMLDivElement || - aElement instanceof Ci.nsIDOMHTMLLIElement || - aElement instanceof Ci.nsIDOMHTMLPreElement || - aElement instanceof Ci.nsIDOMHTMLHeadingElement || - aElement instanceof Ci.nsIDOMHTMLTableCellElement || - aElement instanceof Ci.nsIDOMHTMLBodyElement); - }, - - /* - * Rect and nsIDOMRect utilities - */ - - getCleanRect: function getCleanRect() { - return { - left: 0, top: 0, right: 0, bottom: 0 - }; - }, - - pointWithinRect: function pointWithinRect(aX, aY, aRect) { - return (aRect.left < aX && aRect.top < aY && - aRect.right > aX && aRect.bottom > aY); - }, - - pointWithinDOMRect: function pointWithinDOMRect(aX, aY, aRect) { - if (!aRect.width || !aRect.height) - return false; - return this.pointWithinRect(aX, aY, aRect); - }, - - isEmptyDOMRect: function isEmptyDOMRect(aRect) { - if ((aRect.bottom - aRect.top) <= 0 && - (aRect.right - aRect.left) <= 0) - return true; - return false; - }, - - // Dumps the details of a dom rect to the console - dumpDOMRect: function dumpDOMRect(aMsg, aRect) { - try { - Util.dumpLn(aMsg, - "left:" + Math.round(aRect.left) + ",", - "top:" + Math.round(aRect.top) + ",", - "right:" + Math.round(aRect.right) + ",", - "bottom:" + Math.round(aRect.bottom) + ",", - "width:" + Math.round(aRect.right - aRect.left) + ",", - "height:" + Math.round(aRect.bottom - aRect.top) ); - } catch (ex) { - Util.dumpLn("dumpDOMRect:", ex.message); - } - }, - - /* - * DownloadUtils.convertByteUnits returns [size, localized-unit-string] - * so they are joined for a single download size string. - */ - getDownloadSize: function dv__getDownloadSize (aSize) { - let [size, units] = DownloadUtils.convertByteUnits(aSize); - if (aSize > 0) - return size + units; - else - return Strings.browser.GetStringFromName("downloadsUnknownSize"); - }, - - /* - * URIs and schemes - */ - - makeURI: function makeURI(aURL, aOriginCharset, aBaseURI) { - return Services.io.newURI(aURL, aOriginCharset, aBaseURI); - }, - - makeURLAbsolute: function makeURLAbsolute(base, url) { - // Note: makeURI() will throw if url is not a valid URI - return this.makeURI(url, null, this.makeURI(base)).spec; - }, - - isLocalScheme: function isLocalScheme(aURL) { - return ((aURL.indexOf("about:") == 0 && - aURL != "about:blank" && - aURL != "about:empty" && - aURL != "about:start") || - aURL.indexOf("chrome:") == 0); - }, - - // Don't display anything in the urlbar for these special URIs. - isURLEmpty: function isURLEmpty(aURL) { - return (!aURL || - aURL == "about:blank" || - aURL == "about:empty" || - aURL == "about:home" || - aURL == "about:newtab" || - aURL.startsWith("about:newtab")); - }, - - // Title to use for emptyURL tabs. - getEmptyURLTabTitle: function getEmptyURLTabTitle() { - let browserStrings = Services.strings.createBundle("chrome://browser/locale/browser.properties"); - - return browserStrings.GetStringFromName("tabs.emptyTabTitle"); - }, - - // Don't remember these pages in the session store. - isURLMemorable: function isURLMemorable(aURL) { - return !(aURL == "about:blank" || - aURL == "about:empty" || - aURL == "about:start"); - }, - - /* - * Math utilities - */ - - clamp: function(num, min, max) { - return Math.max(min, Math.min(max, num)); - }, - - /* - * Screen and layout utilities - */ - - /* - * translateToTopLevelWindow - Given an element potentially within - * a subframe, calculate the offsets up to the top level browser. - */ - translateToTopLevelWindow: function translateToTopLevelWindow(aElement) { - let offsetX = 0; - let offsetY = 0; - let element = aElement; - while (element && - element.ownerDocument && - element.ownerDocument.defaultView != content) { - element = element.ownerDocument.defaultView.frameElement; - let rect = element.getBoundingClientRect(); - offsetX += rect.left; - offsetY += rect.top; - } - let win = null; - if (element == aElement) - win = content; - else - win = element.contentDocument.defaultView; - return { targetWindow: win, offsetX: offsetX, offsetY: offsetY }; - }, - - get displayDPI() { - delete this.displayDPI; - return this.displayDPI = this.getWindowUtils(window).displayDPI; - }, - - /* - * aViewHeight - the height of the viewable area in the browser - * aRect - a bounding rectangle of a selection or element. - * - * return - number of pixels for the browser to be shifted up by such - * that aRect is centered vertically within aViewHeight. - */ - centerElementInView: function centerElementInView(aViewHeight, aRect) { - // If the bottom of the target bounds is higher than the new height, - // there's no need to adjust. It will be above the keyboard. - if (aRect.bottom <= aViewHeight) { - return 0; - } - - // height of the target element - let targetHeight = aRect.bottom - aRect.top; - // height of the browser view. - let viewBottom = content.innerHeight; - - // If the target is shorter than the new content height, we can go ahead - // and center it. - if (targetHeight <= aViewHeight) { - // Try to center the element vertically in the new content area, but - // don't position such that the bottom of the browser view moves above - // the top of the chrome. We purposely do not resize the browser window - // by making it taller when trying to center elements that are near the - // lower bounds. This would trigger reflow which can cause content to - // shift around. - let splitMargin = Math.round((aViewHeight - targetHeight) * .5); - let distanceToPageBounds = viewBottom - aRect.bottom; - let distanceFromChromeTop = aRect.bottom - aViewHeight; - let distanceToCenter = - distanceFromChromeTop + Math.min(distanceToPageBounds, splitMargin); - return distanceToCenter; - } - }, - - /* - * Local system utilities - */ - - copyImageToClipboard: function Util_copyImageToClipboard(aImageLoadingContent) { - let image = aImageLoadingContent.QueryInterface(Ci.nsIImageLoadingContent); - if (!image) { - Util.dumpLn("copyImageToClipboard error: image is not an nsIImageLoadingContent"); - return; - } - try { - let xferable = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable); - xferable.init(null); - let imgRequest = aImageLoadingContent.getRequest(Ci.nsIImageLoadingContent.CURRENT_REQUEST); - let mimeType = imgRequest.mimeType; - let imgContainer = imgRequest.image; - let imgPtr = Cc["@mozilla.org/supports-interface-pointer;1"].createInstance(Ci.nsISupportsInterfacePointer); - imgPtr.data = imgContainer; - xferable.setTransferData(mimeType, imgPtr, null); - let clip = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard); - clip.setData(xferable, null, Ci.nsIClipboard.kGlobalClipboard); - } catch (e) { - Util.dumpLn(e.message); - } - }, -}; - - -/* - * Timeout - * - * Helper class to nsITimer that adds a little more pizazz. Callback can be an - * object with a notify method or a function. - */ -Util.Timeout = function(aCallback) { - this._callback = aCallback; - this._timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - this._type = null; -}; - -Util.Timeout.prototype = { - // Timer callback. Don't call this manually. - notify: function notify() { - if (this._type == this._timer.TYPE_ONE_SHOT) - this._type = null; - - if (this._callback.notify) - this._callback.notify(); - else - this._callback.apply(null); - }, - - // Helper function for once and interval. - _start: function _start(aDelay, aType, aCallback) { - if (aCallback) - this._callback = aCallback; - this.clear(); - this._timer.initWithCallback(this, aDelay, aType); - this._type = aType; - return this; - }, - - // Do the callback once. Cancels other timeouts on this object. - once: function once(aDelay, aCallback) { - return this._start(aDelay, this._timer.TYPE_ONE_SHOT, aCallback); - }, - - // Do the callback every aDelay msecs. Cancels other timeouts on this object. - interval: function interval(aDelay, aCallback) { - return this._start(aDelay, this._timer.TYPE_REPEATING_SLACK, aCallback); - }, - - // Clear any pending timeouts. - clear: function clear() { - if (this.isPending()) { - this._timer.cancel(); - this._type = null; - } - return this; - }, - - // If there is a pending timeout, call it and cancel the timeout. - flush: function flush() { - if (this.isPending()) { - this.notify(); - this.clear(); - } - return this; - }, - - // Return true if we are waiting for a callback. - isPending: function isPending() { - return this._type !== null; - } -}; - -// Mixin the ContentUtil module exports -{ - for (let name in ContentUtil) { - let copy = ContentUtil[name]; - if (copy !== undefined) - Util[name] = copy; - } -} - -this.Util = Util; diff --git a/browser/metro/base/content/WebProgress.js b/browser/metro/base/content/WebProgress.js deleted file mode 100644 index 7c9c5557508..00000000000 --- a/browser/metro/base/content/WebProgress.js +++ /dev/null @@ -1,244 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -// Progress heartbeat timer duration (ms) -const kHeartbeatDuration = 1000; -// Start and end progress screen css margins as percentages -const kProgressMarginStart = 30; -const kProgressMarginEnd = 70; - -const WebProgress = { - get _identityBox() { return document.getElementById("identity-box"); }, - - init: function init() { - messageManager.addMessageListener("Content:StateChange", this); - messageManager.addMessageListener("Content:LocationChange", this); - messageManager.addMessageListener("Content:SecurityChange", this); - - Elements.progress.addEventListener("transitionend", this, true); - Elements.tabList.addEventListener("TabSelect", this, true); - - let urlBar = document.getElementById("urlbar-edit"); - urlBar.addEventListener("input", this, false); - - return this; - }, - - receiveMessage: function receiveMessage(aMessage) { - let json = aMessage.json; - let tab = Browser.getTabForBrowser(aMessage.target); - - switch (aMessage.name) { - case "Content:StateChange": { - if (json.stateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW) { - if (json.stateFlags & Ci.nsIWebProgressListener.STATE_START) - this._windowStart(json, tab); - else if (json.stateFlags & Ci.nsIWebProgressListener.STATE_STOP) - this._windowStop(json, tab); - } - - if (json.stateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK) { - if (json.stateFlags & Ci.nsIWebProgressListener.STATE_START) - this._networkStart(json, tab); - else if (json.stateFlags & Ci.nsIWebProgressListener.STATE_STOP) - this._networkStop(json, tab); - } - - this._progressStep(tab); - break; - } - - case "Content:LocationChange": { - this._locationChange(json, tab); - this._progressStep(tab); - break; - } - - case "Content:SecurityChange": { - this._securityChange(json, tab); - this._progressStep(tab); - break; - } - } - }, - - handleEvent: function handleEvent(aEvent) { - switch (aEvent.type) { - case "transitionend": - this._progressTransEnd(aEvent); - break; - case "TabSelect": - this._onTabSelect(aEvent); - break; - case "input": - this._onUrlBarInput(aEvent); - break; - } - }, - - _securityChange: function _securityChange(aJson, aTab) { - let state = aJson.state; - let nsIWebProgressListener = Ci.nsIWebProgressListener; - - if (state & nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL) { - aTab._identityState = "verifiedIdentity"; - } else if (state & nsIWebProgressListener.STATE_IS_SECURE) { - aTab._identityState = "verifiedDomain"; - } else { - aTab._identityState = ""; - } - - if (aTab == Browser.selectedTab) { - this._identityBox.className = aTab._identityState; - } - }, - - _locationChange: function _locationChange(aJson, aTab) { - let spec = aJson.location; - let location = spec.split("#")[0]; // Ignore fragment identifier changes. - - if (aTab == Browser.selectedTab) { - BrowserUI.updateURI(); - BrowserUI.update(); - BrowserUI.updateStartURIAttributes(aJson.location); - } - - let locationHasChanged = (location != aTab.browser.lastLocation); - if (locationHasChanged) { - Browser.getNotificationBox(aTab.browser).removeTransientNotifications(); - aTab.browser.lastLocation = location; - aTab.browser.userTypedValue = ""; - aTab.browser.appIcon = { href: null, size:-1 }; - -#ifdef MOZ_CRASHREPORTER - if (CrashReporter.enabled) - CrashReporter.annotateCrashReport("URL", spec); -#endif - } - - let event = document.createEvent("UIEvents"); - event.initUIEvent("URLChanged", true, false, window, locationHasChanged); - aTab.browser.dispatchEvent(event); - }, - - _networkStart: function _networkStart(aJson, aTab) { - aTab.startLoading(); - - if (aTab == Browser.selectedTab) { - // NO_STARTUI_VISIBILITY since the current uri for the tab has not - // been updated yet. If we're coming off of the start page, this - // would briefly show StartUI until _locationChange is called. - BrowserUI.update(BrowserUI.NO_STARTUI_VISIBILITY); - } - }, - - _networkStop: function _networkStop(aJson, aTab) { - aTab.endLoading(); - - if (aTab == Browser.selectedTab) { - BrowserUI.update(); - } - }, - - _windowStart: function _windowStart(aJson, aTab) { - this._progressStart(aJson, aTab); - }, - - _windowStop: function _windowStop(aJson, aTab) { - this._progressStop(aJson, aTab); - }, - - _progressStart: function _progressStart(aJson, aTab) { - // We will get multiple calls from _windowStart, so - // only process once. - if (aTab._progressActive) - return; - - aTab._progressActive = true; - - // 'Whoosh' in - aTab._progressCount = kProgressMarginStart; - this._showProgressBar(aTab); - }, - - _showProgressBar: function (aTab) { - // display the track - if (aTab == Browser.selectedTab) { - Elements.progressContainer.removeAttribute("collapsed"); - Elements.progress.style.width = aTab._progressCount + "%"; - Elements.progress.removeAttribute("fade"); - } - - // Create a pulse timer to keep things moving even if we don't - // collect any state changes. - setTimeout(function() { - WebProgress._progressStepTimer(aTab); - }, kHeartbeatDuration, this); - }, - - _stepProgressCount: function _stepProgressCount(aTab) { - // Step toward the end margin in smaller slices as we get closer - let left = kProgressMarginEnd - aTab._progressCount; - let step = left * .05; - aTab._progressCount += Math.ceil(step); - - // Don't go past the 'whoosh out' margin. - if (aTab._progressCount > kProgressMarginEnd) { - aTab._progressCount = kProgressMarginEnd; - } - }, - - _progressStep: function _progressStep(aTab) { - if (!aTab._progressActive) - return; - this._stepProgressCount(aTab); - if (aTab == Browser.selectedTab) { - Elements.progress.style.width = aTab._progressCount + "%"; - } - }, - - _progressStepTimer: function _progressStepTimer(aTab) { - if (!aTab._progressActive) - return; - this._progressStep(aTab); - - setTimeout(function() { - WebProgress._progressStepTimer(aTab); - }, kHeartbeatDuration, this); - }, - - _progressStop: function _progressStop(aJson, aTab) { - aTab._progressActive = false; - // 'Whoosh out' and fade - if (aTab == Browser.selectedTab) { - Elements.progress.style.width = "100%"; - Elements.progress.setAttribute("fade", true); - } - }, - - _progressTransEnd: function _progressTransEnd(aEvent) { - if (!Elements.progress.hasAttribute("fade")) - return; - // Close out fade finished, reset - if (aEvent.propertyName == "opacity") { - Elements.progress.style.width = "0px"; - Elements.progressContainer.setAttribute("collapsed", true); - } - }, - - _onTabSelect: function(aEvent) { - let tab = Browser.getTabFromChrome(aEvent.originalTarget); - this._identityBox.className = tab._identityState || ""; - if (tab._progressActive) { - this._showProgressBar(tab); - } else { - Elements.progress.setAttribute("fade", true); - Elements.progressContainer.setAttribute("collapsed", true); - } - }, - - _onUrlBarInput: function(aEvent) { - Browser.selectedTab._identityState = this._identityBox.className = ""; - }, -}; diff --git a/browser/metro/base/content/appbar.js b/browser/metro/base/content/appbar.js deleted file mode 100644 index a0e13103d60..00000000000 --- a/browser/metro/base/content/appbar.js +++ /dev/null @@ -1,323 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -var Appbar = { - get starButton() { return document.getElementById('star-button'); }, - get pinButton() { return document.getElementById('pin-button'); }, - get menuButton() { return document.getElementById('menu-button'); }, - - // track selected/active richgrid/tilegroup - the context for contextual action buttons - activeTileset: null, - - init: function Appbar_init() { - // fired from appbar bindings - Elements.contextappbar.addEventListener('MozAppbarShowing', this, false); - Elements.contextappbar.addEventListener('MozAppbarDismissing', this, false); - - // fired when a context sensitive item (bookmarks) changes state - window.addEventListener('MozContextActionsChange', this, false); - - // browser events we need to update button state on - Elements.browsers.addEventListener('URLChanged', this, true); - Elements.tabList.addEventListener('TabSelect', this, true); - - // tilegroup selection events for all modules get bubbled up - window.addEventListener("selectionchange", this, false); - Services.obs.addObserver(this, "metro_on_async_tile_created", false); - - // gather appbar telemetry data - try { - UITelemetry.addSimpleMeasureFunction("metro-appbar", - this.getAppbarMeasures.bind(this)); - } catch (ex) { - // swallow exception that occurs if metro-appbar measure is already set up - } - }, - - observe: function(aSubject, aTopic, aData) { - switch (aTopic) { - case "metro_on_async_tile_created": - this._updatePinButton(); - break; - } - }, - - handleEvent: function Appbar_handleEvent(aEvent) { - switch (aEvent.type) { - case 'URLChanged': - case 'TabSelect': - this.update(); - this.flushActiveTileset(aEvent.lastTab); - break; - - case 'MozAppbarShowing': - this.update(); - break; - - case 'MozAppbarDismissing': - if (this.activeTileset && ('isBound' in this.activeTileset)) { - this.activeTileset.clearSelection(); - } - this._clearContextualActions(); - this.activeTileset = null; - break; - - case 'MozContextActionsChange': - let actions = aEvent.actions; - let setName = aEvent.target.contextSetName; - // could transition in old, new buttons? - this.showContextualActions(actions, setName); - break; - - case "selectionchange": - let nodeName = aEvent.target.nodeName; - if ('richgrid' === nodeName) { - this._onTileSelectionChanged(aEvent); - } - break; - } - }, - - flushActiveTileset: function flushActiveTileset(aTab) { - try { - let tab = aTab || Browser.selectedTab; - // Switching away from or loading a site into a startui tab that has actions - // pending, we consider this confirmation that the user wants to flush changes. - if (this.activeTileset && tab && tab.browser && tab.browser.currentURI.spec == kStartURI) { - ContextUI.dismiss(); - } - } catch (ex) {} - }, - - shutdown: function shutdown() { - this.flushActiveTileset(); - }, - - /* - * Called from various places when the visible content - * has changed such that button states may need to be - * updated. - */ - update: function update() { - this._updatePinButton(); - this._updateStarButton(); - }, - - onPinButton: function() { - if (this.pinButton.checked) { - Browser.pinSite(); - } else { - Browser.unpinSite(); - } - }, - - onStarButton: function(aValue) { - if (aValue === undefined) { - aValue = this.starButton.checked; - } - - if (aValue) { - Browser.starSite(function () { - Appbar._updateStarButton(); - }); - } else { - Browser.unstarSite(function () { - Appbar._updateStarButton(); - }); - } - }, - - onMenuButton: function(aEvent) { - let typesArray = []; - - if (BrowserUI.isPrivateBrowsingEnabled) { - typesArray.push("private-browsing"); - } - if (!BrowserUI.isStartTabVisible) { - typesArray.push("find-in-page"); - if (ContextCommands.getPageSource()) - typesArray.push("view-page-source"); - } - if (ContextCommands.getStoreLink()) - typesArray.push("ms-meta-data"); - if (ConsolePanelView.enabled) - typesArray.push("open-error-console"); - if (!Services.metro.immersive) - typesArray.push("open-jsshell"); - - typesArray.push("view-on-desktop"); - - var x = this.menuButton.getBoundingClientRect().left; - var y = Elements.toolbar.getBoundingClientRect().top; - ContextMenuUI.showContextMenu({ - json: { - types: typesArray, - string: '', - xPos: x, - yPos: y, - leftAligned: true, - bottomAligned: true - } - - }); - }, - - onViewOnDesktop: function() { - let appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"]. - getService(Components.interfaces.nsIAppStartup); - - Services.prefs.setBoolPref('browser.sessionstore.resume_session_once', true); - this._incrementCountableEvent("switch-to-desktop-button"); - appStartup.quit(Components.interfaces.nsIAppStartup.eAttemptQuit | - Components.interfaces.nsIAppStartup.eRestart); - }, - - onAutocompleteCloseButton: function () { - Elements.autocomplete.closePopup(); - }, - - dispatchContextualAction: function(aActionName){ - let activeTileset = this.activeTileset; - if (activeTileset && ('isBound' in this.activeTileset)) { - // fire event on the richgrid, others can listen - // but we keep coupling loose so grid doesn't need to know about appbar - let event = document.createEvent("Events"); - event.action = aActionName; - event.initEvent("context-action", true, true); // is cancelable - activeTileset.dispatchEvent(event); - if (!event.defaultPrevented) { - activeTileset.clearSelection(); - Elements.contextappbar.dismiss(); - } - } - }, - - showContextualActions: function(aVerbs, aSetName) { - // When the appbar is not visible, we want the icons to refresh right away - let immediate = !Elements.contextappbar.isShowing; - - if (aVerbs.length) { - Elements.contextappbar.show(); - } - - // Look up all of the buttons for the verbs that should be visible. - let idsToVisibleVerbs = new Map(); - for (let verb of aVerbs) { - let id = verb + "-selected-button"; - if (!document.getElementById(id)) { - throw new Error("Appbar.showContextualActions: no button for " + verb); - } - idsToVisibleVerbs.set(id, verb); - } - - // Sort buttons into 2 buckets - needing showing and needing hiding. - let toHide = [], toShow = []; - let buttons = Elements.contextappbar.getElementsByTagName("toolbarbutton"); - for (let button of buttons) { - let verb = idsToVisibleVerbs.get(button.id); - if (verb != undefined) { - // Button should be visible, and may or may not be showing. - this._updateContextualActionLabel(button, verb, aSetName); - if (button.hidden) { - toShow.push(button); - } - } else if (!button.hidden) { - // Button is visible, but shouldn't be. - toHide.push(button); - } - } - - if (immediate) { - toShow.forEach(function(element) { - element.removeAttribute("fade"); - element.hidden = false; - }); - toHide.forEach(function(element) { - element.setAttribute("fade", true); - element.hidden = true; - }); - return; - } - - return Task.spawn(function() { - if (toHide.length) { - yield Util.transitionElementVisibility(toHide, false); - } - if (toShow.length) { - yield Util.transitionElementVisibility(toShow, true); - } - }); - }, - - _clearContextualActions: function() { - this.showContextualActions([]); - }, - - _updateContextualActionLabel: function(aButton, aVerb, aSetName) { - // True if the action's label string contains the set name and - // thus has to be selected based on the list passed in. - let usesSetName = aButton.hasAttribute("label-uses-set-name"); - let name = "contextAppbar2." + aVerb + (usesSetName ? "." + aSetName : ""); - aButton.label = Strings.browser.GetStringFromName(name); - }, - - _onTileSelectionChanged: function _onTileSelectionChanged(aEvent){ - let activeTileset = aEvent.target; - - // deselect tiles in other tile groups, - // ensure previousyl-activeTileset is bound before calling methods on it - if (this.activeTileset && - ('isBound' in this.activeTileset) && - this.activeTileset !== activeTileset) { - this.activeTileset.clearSelection(); - } - // keep track of which view is the target/scope for the contextual actions - this.activeTileset = activeTileset; - - // ask the view for the list verbs/action-names it thinks are - // appropriate for the tiles selected - let contextActions = activeTileset.contextActions; - let verbs = [v for (v of contextActions)]; - - // fire event with these verbs as payload - let event = document.createEvent("Events"); - event.actions = verbs; - event.initEvent("MozContextActionsChange", true, false); - activeTileset.dispatchEvent(event); - - if (verbs.length) { - Elements.contextappbar.show(); // should be no-op if we're already showing - } else { - Elements.contextappbar.dismiss(); - } - }, - - // track certain appbar events and interactions for the UITelemetry probe - _countableEvents: {}, - - _incrementCountableEvent: function(aName) { - if (!(aName in this._countableEvents)) { - this._countableEvents[aName] = 0; - } - this._countableEvents[aName]++; - }, - - getAppbarMeasures: function() { - return { - countableEvents: this._countableEvents - }; - }, - - _updatePinButton: function() { - this.pinButton.checked = Browser.isSitePinned(); - }, - - _updateStarButton: function() { - Browser.isSiteStarredAsync(function (isStarred) { - this.starButton.checked = isStarred; - }.bind(this)); - }, - -}; diff --git a/browser/metro/base/content/apzc.js b/browser/metro/base/content/apzc.js deleted file mode 100644 index 49bb987c7a9..00000000000 --- a/browser/metro/base/content/apzc.js +++ /dev/null @@ -1,153 +0,0 @@ -// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -let Cc = Components.classes; -let Ci = Components.interfaces; -let Cu = Components.utils; -let Cr = Components.results; - -/** - * Misc. front end utilities for apzc management. - * the pref: layers.async-pan-zoom.enabled is true. - */ - -var APZCObserver = { - _debugEvents: false, - _enabled: false, - - get enabled() { - return this._enabled; - }, - - init: function() { - this._enabled = Services.prefs.getBoolPref(kAsyncPanZoomEnabled); - if (!this._enabled) { - return; - } - - let os = Services.obs; - os.addObserver(this, "apzc-transform-begin", false); - - Elements.tabList.addEventListener("TabSelect", this, true); - Elements.browsers.addEventListener("pageshow", this, true); - messageManager.addMessageListener("Content:ZoomToRect", this); - }, - - shutdown: function shutdown() { - if (!this._enabled) { - return; - } - - let os = Services.obs; - os.removeObserver(this, "apzc-transform-begin"); - - Elements.tabList.removeEventListener("TabSelect", this, true); - Elements.browsers.removeEventListener("pageshow", this, true); - messageManager.removeMessageListener("Content:ZoomToRect", this); - }, - - handleEvent: function APZC_handleEvent(aEvent) { - switch (aEvent.type) { - case 'TabSelect': - this._resetDisplayPort(); - break; - - case 'pageshow': - if (aEvent.target != Browser.selectedBrowser.contentDocument) { - break; - } - this._resetDisplayPort(); - break; - } - }, - - observe: function ao_observe(aSubject, aTopic, aData) { - if (aTopic == "apzc-transform-begin") { - // When we're panning, hide the main scrollbars by setting imprecise - // input (which sets a property on the browser which hides the scrollbar - // via CSS). This reduces jittering from left to right. We may be able - // to get rid of this once we implement axis locking in /gfx APZC. - if (InputSourceHelper.isPrecise) { - InputSourceHelper._imprecise(); - } - } - }, - - receiveMessage: function(aMessage) { - let json = aMessage.json; - let browser = aMessage.target; - switch (aMessage.name) { - case "Content:ZoomToRect": { - let { presShellId, viewId } = json; - let rect = Rect.fromRect(json.rect); - if (this.isRectZoomedIn(rect, browser.contentViewportBounds)) { - // If we're already zoomed in, zoom out instead. - rect = new Rect(0,0,0,0); - } - let data = [rect.x, rect.y, rect.width, rect.height, presShellId, viewId].join(","); - Services.obs.notifyObservers(null, "apzc-zoom-to-rect", data); - } - } - }, - - /** - * Check to see if the area of the rect visible in the viewport is - * approximately the max area of the rect we can show. - * Based on code from BrowserElementPanning.js - */ - isRectZoomedIn: function (aRect, aViewport) { - let overlap = aViewport.intersect(aRect); - let overlapArea = overlap.width * overlap.height; - let availHeight = Math.min(aRect.width * aViewport.height / aViewport.width, aRect.height); - let showing = overlapArea / (aRect.width * availHeight); - let ratioW = (aRect.width / aViewport.width); - let ratioH = (aRect.height / aViewport.height); - - return (showing > 0.9 && (ratioW > 0.9 || ratioH > 0.9)); - }, - - _resetDisplayPort: function () { - // Start off with something reasonable. The apzc will handle these - // calculations once scrolling starts. - let doc = Browser.selectedBrowser.contentDocument.documentElement; - // While running tests, sometimes this can be null. If we don't have a - // root document, there's no point in setting a scrollable display port. - if (!doc) { - return; - } - let win = Browser.selectedBrowser.contentWindow; - let factor = 0.2; - let portX = 0; - let portY = 0; - let portWidth = ContentAreaObserver.width; - let portHeight = ContentAreaObserver.height; - - if (portWidth < doc.scrollWidth) { - portWidth += ContentAreaObserver.width * factor; - if (portWidth > doc.scrollWidth) { - portWidth = doc.scrollWidth; - } - } - if (portHeight < doc.scrollHeight) { - portHeight += ContentAreaObserver.height * factor; - if (portHeight > doc.scrollHeight) { - portHeight = doc.scrollHeight; - } - } - if (win.scrollX > 0) { - portX -= ContentAreaObserver.width * factor; - } - if (win.scrollY > 0) { - portY -= ContentAreaObserver.height * factor; - } - let cwu = Browser.selectedBrowser.contentWindow - .QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindowUtils); - cwu.setDisplayPortForElement(portX, portY, - portWidth, portHeight, - Browser.selectedBrowser.contentDocument.documentElement, - 0); - } -}; diff --git a/browser/metro/base/content/bindings.css b/browser/metro/base/content/bindings.css deleted file mode 100644 index ced50744e1a..00000000000 --- a/browser/metro/base/content/bindings.css +++ /dev/null @@ -1,215 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -browser[tabmodalPromptShowing] { - -moz-user-focus: none !important; -} - -browser[remote="false"] { - -moz-binding: url("chrome://browser/content/bindings/browser.xml#local-browser"); -} - -browser[remote="true"] { - -moz-binding: url("chrome://browser/content/bindings/browser.xml#remote-browser"); -} - -#tabs { - -moz-binding: url("chrome://browser/content/bindings/tabs.xml#tablist"); -} - -documenttab { - -moz-binding: url("chrome://browser/content/bindings/tabs.xml#documenttab"); -} - -appbar { - -moz-binding: url('chrome://browser/content/bindings/appbar.xml#appbarBinding'); -} - -flyoutpanel { - -moz-binding: url('chrome://browser/content/bindings/flyoutpanel.xml#flyoutpanelBinding'); -} -cssthrobber { - -moz-binding: url('chrome://browser/content/bindings/cssthrobber.xml#cssthrobberBinding'); -} -label[linewrap] { - -moz-binding: url("chrome://browser/content/bindings/bindings.xml#line-wrap-label"); -} -label[linewrap].text-link, label[onclick][linewrap] { - -moz-binding: url("chrome://browser/content/bindings/bindings.xml#line-wrap-text-link"); -} - -settings { - -moz-binding: url("chrome://mozapps/content/extensions/setting.xml#settings"); -} -setting { - display: none; -} -autoscroller { - -moz-binding: url('chrome://browser/content/bindings/popup.xml#element-popup'); -} - -notificationbox { - -moz-binding: url('chrome://browser/content/bindings/notification.xml#notificationbox'); -} -notification { - -moz-binding: url('chrome://browser/content/bindings/notification.xml#notification'); -} - -circularprogressindicator { - -moz-binding: url('chrome://browser/content/bindings/circularprogress.xml#circular-progress-indicator'); -} - -setting[type="bool"] { - display: -moz-box; - -moz-binding: url("chrome://browser/content/bindings/toggleswitch.xml#setting-fulltoggle-bool"); -} - -setting[type="bool"][localized="true"] { - display: -moz-box; - -moz-binding: url("chrome://browser/content/bindings/toggleswitch.xml#setting-fulltoggle-localized-bool"); -} - -setting[type="boolint"] { - display: -moz-box; - -moz-binding: url("chrome://browser/content/bindings/toggleswitch.xml#setting-fulltoggle-boolint"); -} - -setting[type="integer"] { - display: -moz-box; - -moz-binding: url("chrome://mozapps/content/extensions/setting.xml#setting-integer"); -} - -setting[type="control"] { - display: -moz-box; - -moz-binding: url("chrome://mozapps/content/extensions/setting.xml#setting-control"); -} - -setting[type="string"] { - display: -moz-box; - -moz-binding: url("chrome://mozapps/content/extensions/setting.xml#setting-string"); -} - -setting[type="color"] { - display: -moz-box; - -moz-binding: url("chrome://mozapps/content/extensions/setting.xml#setting-color"); -} - -setting[type="file"], -setting[type="directory"] { - display: -moz-box; - -moz-binding: url("chrome://mozapps/content/extensions/setting.xml#setting-path"); -} - -setting[type="radio"], -setting[type="menulist"] { - display: -moz-box; - -moz-binding: url("chrome://mozapps/content/extensions/setting.xml#setting-multi"); -} - -#chrome-selection-overlay, -#content-selection-overlay { - -moz-binding: url("chrome://browser/content/bindings/selectionoverlay.xml#selection-binding"); -} - -#urlbar-edit { - -moz-binding: url("chrome://browser/content/bindings/urlbar.xml#urlbar"); -} - -#urlbar-autocomplete { - -moz-binding: url("chrome://browser/content/bindings/urlbar.xml#urlbar-autocomplete"); -} - -richgrid { - -moz-binding: url("chrome://browser/content/bindings/grid.xml#richgrid"); -} - -richgriditem { - -moz-binding: url("chrome://browser/content/bindings/grid.xml#richgrid-empty-item"); -} -richgriditem[value] { - -moz-binding: url("chrome://browser/content/bindings/grid.xml#richgrid-item"); -} - -placeitem { - -moz-binding: url("chrome://browser/content/bindings/bindings.xml#place-item"); - background-color: transparent; -} - -placeitem[type="folder"] { - -moz-binding: url("chrome://browser/content/bindings/bindings.xml#place-folder"); -} - -placelabel { - -moz-binding: url("chrome://browser/content/bindings/bindings.xml#place-label"); -} - -radio[type="toggle"] { - -moz-binding: url("chrome://global/content/bindings/radio.xml#radio"); -} - -radiogroup { - -moz-binding: url("chrome://global/content/bindings/radio.xml#radiogroup"); -} - -checkbox.toggleswitch { - -moz-binding: url("chrome://browser/content/bindings/toggleswitch.xml#checkbox-toggleswitch"); -} - -menulist { - -moz-binding: url("chrome://browser/content/bindings/bindings.xml#menulist"); -} - -.chrome-select-option { - -moz-binding: url("chrome://browser/content/bindings/bindings.xml#chrome-select-option"); -} - -/* richlist defaults ------------------------------------------------------- */ -richlistbox[batch] { - -moz-binding: url("chrome://browser/content/bindings/bindings.xml#richlistbox-batch"); -} - -richlistbox[bindingType="contextmenu"] { - -moz-binding: url("chrome://browser/content/bindings/bindings.xml#richlistbox-contextmenu"); -} - -richlistitem { - -moz-binding: url("chrome://browser/content/bindings/bindings.xml#richlistitem"); -} - -richlistitem[type="error"], -richlistitem[type="warning"] { - -moz-binding: url("chrome://browser/content/bindings/console.xml#error"); -} - -richlistitem[type="message"]{ - -moz-binding: url("chrome://browser/content/bindings/console.xml#message"); -} - -dialog { - -moz-binding: url("chrome://browser/content/bindings/dialog.xml#dialog"); -} - -/* Do not allow these to inherit from the toolkit binding */ -dialog.content-dialog { - -moz-binding: none; -} - -/* Disable context menus in textboxes */ -.textbox-input-box, -.textbox-input-box[spellcheck="true"] { - -moz-binding: url("chrome://browser/content/bindings/bindings.xml#input-box"); -} - -textbox { - -moz-binding: url("chrome://browser/content/bindings/bindings.xml#textbox"); -} - -/* used in about:config */ -textbox[type="search"] { - -moz-binding: url("chrome://browser/content/bindings/bindings.xml#search-textbox"); -} - -tabmodalprompt { - -moz-binding: url("chrome://browser/content/bindings/tabprompts.xml#tabmodalprompt"); -} diff --git a/browser/metro/base/content/bindings/appbar.xml b/browser/metro/base/content/bindings/appbar.xml deleted file mode 100644 index b2869b1914b..00000000000 --- a/browser/metro/base/content/bindings/appbar.xml +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - - - - - false - document.getAnonymousElementByAttribute(this, "anonid", "toolbar"); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/browser/metro/base/content/bindings/bindings.xml b/browser/metro/base/content/bindings/bindings.xml deleted file mode 100644 index 7f12dd456b0..00000000000 --- a/browser/metro/base/content/bindings/bindings.xml +++ /dev/null @@ -1,356 +0,0 @@ - - - - - -%browserDTD; -]> - - - - - - - 0.8) - this._insertItems(); - ]]> - - - - - - - this.scrollBoxObject.height; - [] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 || selectionEnd < aTextbox.textLength) - json.types.push("select-all"); - - let clipboard = Components.classes["@mozilla.org/widget/clipboard;1"]. - getService(Ci.nsIClipboard); - let flavors = ["text/unicode"]; - let hasData = clipboard.hasDataMatchingFlavors(flavors, flavors.length, Ci.nsIClipboard.kGlobalClipboard); - - if (hasData && (!aTextbox.readOnly || aIgnoreReadOnly)) { - json.types.push("paste"); - if (aTextbox.type == "url") { - json.types.push("paste-url"); - } - } - json.xPos = aEvent.clientX; - json.yPos = aEvent.clientY; - json.source = aEvent.mozInputSource; - ContextMenuUI.showContextMenu({ target: aTextbox, json: json }); - ]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/browser/metro/base/content/bindings/browser.js b/browser/metro/base/content/bindings/browser.js deleted file mode 100644 index 2b47302c937..00000000000 --- a/browser/metro/base/content/bindings/browser.js +++ /dev/null @@ -1,764 +0,0 @@ -// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -let Cc = Components.classes; -let Ci = Components.interfaces; -let Cu = Components.utils; - -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/FormData.jsm"); -Cu.import("resource://gre/modules/ScrollPosition.jsm"); -Cu.import("resource://gre/modules/Timer.jsm", this); - -let WebProgressListener = { - _lastLocation: null, - _firstPaint: false, - - init: function() { - let flags = Ci.nsIWebProgress.NOTIFY_LOCATION | - Ci.nsIWebProgress.NOTIFY_SECURITY | - Ci.nsIWebProgress.NOTIFY_STATE_WINDOW | - Ci.nsIWebProgress.NOTIFY_STATE_NETWORK | - Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT; - - let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebProgress); - webProgress.addProgressListener(this, flags); - }, - - onStateChange: function onStateChange(aWebProgress, aRequest, aStateFlags, aStatus) { - if (content != aWebProgress.DOMWindow) - return; - - sendAsyncMessage("Content:StateChange", { - contentWindowId: this.contentWindowId, - stateFlags: aStateFlags, - status: aStatus - }); - }, - - onLocationChange: function onLocationChange(aWebProgress, aRequest, aLocationURI, aFlags) { - if (content != aWebProgress.DOMWindow) - return; - - let spec = aLocationURI ? aLocationURI.spec : ""; - let location = spec.split("#")[0]; - - let charset = content.document.characterSet; - - sendAsyncMessage("Content:LocationChange", { - contentWindowId: this.contentWindowId, - documentURI: aWebProgress.DOMWindow.document.documentURIObject.spec, - location: spec, - canGoBack: docShell.canGoBack, - canGoForward: docShell.canGoForward, - charset: charset.toString() - }); - - this._firstPaint = false; - let self = this; - - // Keep track of hash changes - this.hashChanged = (location == this._lastLocation); - this._lastLocation = location; - - // When a new page is loaded fire a message for the first paint - addEventListener("MozAfterPaint", function(aEvent) { - removeEventListener("MozAfterPaint", arguments.callee, true); - - self._firstPaint = true; - let scrollOffset = ContentScroll.getScrollOffset(content); - sendAsyncMessage("Browser:FirstPaint", scrollOffset); - }, true); - }, - - onStatusChange: function onStatusChange(aWebProgress, aRequest, aStatus, aMessage) { - }, - - onSecurityChange: function onSecurityChange(aWebProgress, aRequest, aState) { - if (content != aWebProgress.DOMWindow) - return; - - let serialization = SecurityUI.getSSLStatusAsString(); - - sendAsyncMessage("Content:SecurityChange", { - contentWindowId: this.contentWindowId, - SSLStatusAsString: serialization, - state: aState - }); - }, - - get contentWindowId() { - return content.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindowUtils) - .currentInnerWindowID; - }, - - QueryInterface: function QueryInterface(aIID) { - if (aIID.equals(Ci.nsIWebProgressListener) || - aIID.equals(Ci.nsISupportsWeakReference) || - aIID.equals(Ci.nsISupports)) { - return this; - } - - throw Components.results.NS_ERROR_NO_INTERFACE; - } -}; - -WebProgressListener.init(); - - -let SecurityUI = { - getSSLStatusAsString: function() { - let status = docShell.securityUI.QueryInterface(Ci.nsISSLStatusProvider).SSLStatus; - - if (status) { - let serhelper = Cc["@mozilla.org/network/serialization-helper;1"] - .getService(Ci.nsISerializationHelper); - - status.QueryInterface(Ci.nsISerializable); - return serhelper.serializeToString(status); - } - - return null; - } -}; - -let WebNavigation = { - _webNavigation: docShell.QueryInterface(Ci.nsIWebNavigation), - _timer: null, - - init: function() { - addMessageListener("WebNavigation:GoBack", this); - addMessageListener("WebNavigation:GoForward", this); - addMessageListener("WebNavigation:GotoIndex", this); - addMessageListener("WebNavigation:LoadURI", this); - addMessageListener("WebNavigation:Reload", this); - addMessageListener("WebNavigation:Stop", this); - }, - - receiveMessage: function(message) { - switch (message.name) { - case "WebNavigation:GoBack": - this.goBack(); - break; - case "WebNavigation:GoForward": - this.goForward(); - break; - case "WebNavigation:GotoIndex": - this.gotoIndex(message); - break; - case "WebNavigation:LoadURI": - this.loadURI(message); - break; - case "WebNavigation:Reload": - this.reload(message); - break; - case "WebNavigation:Stop": - this.stop(message); - break; - } - }, - - goBack: function() { - if (this._webNavigation.canGoBack) - this._webNavigation.goBack(); - }, - - goForward: function() { - if (this._webNavigation.canGoForward) - this._webNavigation.goForward(); - }, - - gotoIndex: function(message) { - this._webNavigation.gotoIndex(message.index); - }, - - loadURI: function(message) { - let flags = message.json.flags || this._webNavigation.LOAD_FLAGS_NONE; - this._webNavigation.loadURI(message.json.uri, flags, null, null, null); - - let tabData = message.json; - if (tabData.entries) { - // We are going to load from history so kill the current load. We do not - // want the load added to the history anyway. We reload after resetting history - this._webNavigation.stop(this._webNavigation.STOP_ALL); - this._restoreHistory(tabData, 0); - } - }, - - reload: function(message) { - let flags = message.json.flags || this._webNavigation.LOAD_FLAGS_NONE; - this._webNavigation.reload(flags); - }, - - stop: function(message) { - let flags = message.json.flags || this._webNavigation.STOP_ALL; - this._webNavigation.stop(flags); - }, - - _restoreHistory: function _restoreHistory(aTabData, aCount) { - // We need to wait for the sessionHistory to be initialized and there - // is no good way to do this. We'll try a wait loop like desktop - try { - if (!this._webNavigation.sessionHistory) - throw new Error(); - } catch (ex) { - if (aCount < 10) { - let self = this; - this._timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - this._timer.initWithCallback(function(aTimer) { - self._timer = null; - self._restoreHistory(aTabData, aCount + 1); - }, 100, Ci.nsITimer.TYPE_ONE_SHOT); - return; - } - } - - let history = this._webNavigation.sessionHistory; - if (history.count > 0) - history.PurgeHistory(history.count); - history.QueryInterface(Ci.nsISHistoryInternal); - - // helper hashes for ensuring unique frame IDs and unique document - // identifiers. - let idMap = { used: {} }; - let docIdentMap = {}; - - for (let i = 0; i < aTabData.entries.length; i++) { - if (!aTabData.entries[i].url) - continue; - history.addEntry(this._deserializeHistoryEntry(aTabData.entries[i], idMap, docIdentMap), true); - } - - // We need to force set the active history item and cause it to reload since - // we stop the load above - let activeIndex = (aTabData.index || aTabData.entries.length) - 1; - history.getEntryAtIndex(activeIndex, true); - history.QueryInterface(Ci.nsISHistory).reloadCurrentEntry(); - }, - - _deserializeHistoryEntry: function _deserializeHistoryEntry(aEntry, aIdMap, aDocIdentMap) { - let shEntry = Cc["@mozilla.org/browser/session-history-entry;1"].createInstance(Ci.nsISHEntry); - - shEntry.setURI(Services.io.newURI(aEntry.url, null, null)); - shEntry.setTitle(aEntry.title || aEntry.url); - if (aEntry.subframe) - shEntry.setIsSubFrame(aEntry.subframe || false); - shEntry.loadType = Ci.nsIDocShellLoadInfo.loadHistory; - if (aEntry.contentType) - shEntry.contentType = aEntry.contentType; - if (aEntry.referrer) - shEntry.referrerURI = Services.io.newURI(aEntry.referrer, null, null); - - if (aEntry.cacheKey) { - let cacheKey = Cc["@mozilla.org/supports-PRUint32;1"].createInstance(Ci.nsISupportsPRUint32); - cacheKey.data = aEntry.cacheKey; - shEntry.cacheKey = cacheKey; - } - - if (aEntry.ID) { - // get a new unique ID for this frame (since the one from the last - // start might already be in use) - let id = aIdMap[aEntry.ID] || 0; - if (!id) { - for (id = Date.now(); id in aIdMap.used; id++); - aIdMap[aEntry.ID] = id; - aIdMap.used[id] = true; - } - shEntry.ID = id; - } - - if (aEntry.docshellID) - shEntry.docshellID = aEntry.docshellID; - - if (aEntry.structuredCloneState && aEntry.structuredCloneVersion) { - shEntry.stateData = - Cc["@mozilla.org/docshell/structured-clone-container;1"]. - createInstance(Ci.nsIStructuredCloneContainer); - - shEntry.stateData.initFromBase64(aEntry.structuredCloneState, aEntry.structuredCloneVersion); - } - - if (aEntry.scroll) { - let scrollPos = aEntry.scroll.split(","); - scrollPos = [parseInt(scrollPos[0]) || 0, parseInt(scrollPos[1]) || 0]; - shEntry.setScrollPosition(scrollPos[0], scrollPos[1]); - } - - let childDocIdents = {}; - if (aEntry.docIdentifier) { - // If we have a serialized document identifier, try to find an SHEntry - // which matches that doc identifier and adopt that SHEntry's - // BFCacheEntry. If we don't find a match, insert shEntry as the match - // for the document identifier. - let matchingEntry = aDocIdentMap[aEntry.docIdentifier]; - if (!matchingEntry) { - matchingEntry = {shEntry: shEntry, childDocIdents: childDocIdents}; - aDocIdentMap[aEntry.docIdentifier] = matchingEntry; - } else { - shEntry.adoptBFCacheEntry(matchingEntry.shEntry); - childDocIdents = matchingEntry.childDocIdents; - } - } - - if (aEntry.owner_b64) { - let ownerInput = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream); - let binaryData = atob(aEntry.owner_b64); - ownerInput.setData(binaryData, binaryData.length); - let binaryStream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(Ci.nsIObjectInputStream); - binaryStream.setInputStream(ownerInput); - try { // Catch possible deserialization exceptions - shEntry.owner = binaryStream.readObject(true); - } catch (ex) { dump(ex); } - } - - if (aEntry.children && shEntry instanceof Ci.nsISHContainer) { - for (let i = 0; i < aEntry.children.length; i++) { - if (!aEntry.children[i].url) - continue; - - // We're getting sessionrestore.js files with a cycle in the - // doc-identifier graph, likely due to bug 698656. (That is, we have - // an entry where doc identifier A is an ancestor of doc identifier B, - // and another entry where doc identifier B is an ancestor of A.) - // - // If we were to respect these doc identifiers, we'd create a cycle in - // the SHEntries themselves, which causes the docshell to loop forever - // when it looks for the root SHEntry. - // - // So as a hack to fix this, we restrict the scope of a doc identifier - // to be a node's siblings and cousins, and pass childDocIdents, not - // aDocIdents, to _deserializeHistoryEntry. That is, we say that two - // SHEntries with the same doc identifier have the same document iff - // they have the same parent or their parents have the same document. - - shEntry.AddChild(this._deserializeHistoryEntry(aEntry.children[i], aIdMap, childDocIdents), i); - } - } - - return shEntry; - }, - - sendHistory: function sendHistory() { - // We need to package up the session history and send it to the sessionstore - let entries = []; - let history = docShell.QueryInterface(Ci.nsIWebNavigation).sessionHistory; - for (let i = 0; i < history.count; i++) { - let entry = this._serializeHistoryEntry(history.getEntryAtIndex(i, false)); - - // If someone directly navigates to one of these URLs and they switch to Desktop, - // we need to make the page load-able. - if (entry.url == "about:home" || entry.url == "about:start") { - entry.url = "about:newtab"; - } - entries.push(entry); - } - let index = history.index + 1; - sendAsyncMessage("Content:SessionHistory", { entries: entries, index: index }); - }, - - _serializeHistoryEntry: function _serializeHistoryEntry(aEntry) { - let entry = { url: aEntry.URI.spec }; - - if (Util.isURLEmpty(entry.url)) { - entry.title = Util.getEmptyURLTabTitle(); - } else { - entry.title = aEntry.title; - } - - if (!(aEntry instanceof Ci.nsISHEntry)) - return entry; - - let cacheKey = aEntry.cacheKey; - if (cacheKey && cacheKey instanceof Ci.nsISupportsPRUint32 && cacheKey.data != 0) - entry.cacheKey = cacheKey.data; - - entry.ID = aEntry.ID; - entry.docshellID = aEntry.docshellID; - - if (aEntry.referrerURI) - entry.referrer = aEntry.referrerURI.spec; - - if (aEntry.contentType) - entry.contentType = aEntry.contentType; - - let x = {}, y = {}; - aEntry.getScrollPosition(x, y); - if (x.value != 0 || y.value != 0) - entry.scroll = x.value + "," + y.value; - - if (aEntry.owner) { - try { - let binaryStream = Cc["@mozilla.org/binaryoutputstream;1"].createInstance(Ci.nsIObjectOutputStream); - let pipe = Cc["@mozilla.org/pipe;1"].createInstance(Ci.nsIPipe); - pipe.init(false, false, 0, 0xffffffff, null); - binaryStream.setOutputStream(pipe.outputStream); - binaryStream.writeCompoundObject(aEntry.owner, Ci.nsISupports, true); - binaryStream.close(); - - // Now we want to read the data from the pipe's input end and encode it. - let scriptableStream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(Ci.nsIBinaryInputStream); - scriptableStream.setInputStream(pipe.inputStream); - let ownerBytes = scriptableStream.readByteArray(scriptableStream.available()); - // We can stop doing base64 encoding once our serialization into JSON - // is guaranteed to handle all chars in strings, including embedded - // nulls. - entry.owner_b64 = btoa(String.fromCharCode.apply(null, ownerBytes)); - } catch (e) { dump(e); } - } - - entry.docIdentifier = aEntry.BFCacheEntry.ID; - - if (aEntry.stateData != null) { - entry.structuredCloneState = aEntry.stateData.getDataAsBase64(); - entry.structuredCloneVersion = aEntry.stateData.formatVersion; - } - - if (!(aEntry instanceof Ci.nsISHContainer)) - return entry; - - if (aEntry.childCount > 0) { - entry.children = []; - for (let i = 0; i < aEntry.childCount; i++) { - let child = aEntry.GetChildAt(i); - if (child) - entry.children.push(this._serializeHistoryEntry(child)); - else // to maintain the correct frame order, insert a dummy entry - entry.children.push({ url: "about:blank" }); - - // don't try to restore framesets containing wyciwyg URLs (cf. bug 424689 and bug 450595) - if (/^wyciwyg:\/\//.test(entry.children[i].url)) { - delete entry.children; - break; - } - } - } - - return entry; - } -}; - -WebNavigation.init(); - - -let DOMEvents = { - _timeout: null, - _sessionEvents: new Set(), - _sessionEventMap: {"SessionStore:collectFormdata" : FormData.collect, - "SessionStore:collectScrollPosition" : ScrollPosition.collect}, - - init: function() { - addEventListener("DOMContentLoaded", this, false); - addEventListener("DOMTitleChanged", this, false); - addEventListener("DOMLinkAdded", this, false); - addEventListener("DOMWillOpenModalDialog", this, false); - addEventListener("DOMModalDialogClosed", this, true); - addEventListener("DOMWindowClose", this, false); - addEventListener("DOMPopupBlocked", this, false); - addEventListener("pageshow", this, false); - addEventListener("pagehide", this, false); - - addEventListener("input", this, true); - addEventListener("change", this, true); - addEventListener("scroll", this, true); - addMessageListener("SessionStore:restoreSessionTabData", this); - }, - - receiveMessage: function(message) { - switch (message.name) { - case "SessionStore:restoreSessionTabData": - if (message.json.formdata) - FormData.restore(content, message.json.formdata); - if (message.json.scroll) - ScrollPosition.restore(content, message.json.scroll.scroll); - break; - } - }, - - handleEvent: function(aEvent) { - let document = content.document; - switch (aEvent.type) { - case "DOMContentLoaded": - if (document.documentURIObject.spec == "about:blank") - return; - - sendAsyncMessage("DOMContentLoaded", { }); - - // Send the session history now too - WebNavigation.sendHistory(); - break; - - case "pageshow": - case "pagehide": { - if (aEvent.target.defaultView != content) - break; - - let util = aEvent.target.defaultView.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindowUtils); - - let json = { - contentWindowWidth: content.innerWidth, - contentWindowHeight: content.innerHeight, - windowId: util.outerWindowID, - persisted: aEvent.persisted - }; - - // Clear onload focus to prevent the VKB to be shown unexpectingly - // but only if the location has really changed and not only the - // fragment identifier - let contentWindowID = content.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils).currentInnerWindowID; - if (!WebProgressListener.hashChanged && contentWindowID == util.currentInnerWindowID) { - let focusManager = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager); - focusManager.clearFocus(content); - } - - sendAsyncMessage(aEvent.type, json); - break; - } - - case "DOMPopupBlocked": { - let util = aEvent.requestingWindow.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindowUtils); - let json = { - windowId: util.outerWindowID, - popupWindowURI: { - spec: aEvent.popupWindowURI.spec, - charset: aEvent.popupWindowURI.originCharset - }, - popupWindowFeatures: aEvent.popupWindowFeatures, - popupWindowName: aEvent.popupWindowName - }; - - sendAsyncMessage("DOMPopupBlocked", json); - break; - } - - case "DOMTitleChanged": - sendAsyncMessage("DOMTitleChanged", { title: document.title }); - break; - - case "DOMLinkAdded": - let target = aEvent.originalTarget; - if (!target.href || target.disabled) - return; - - let json = { - windowId: target.ownerDocument.defaultView.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils).currentInnerWindowID, - href: target.href, - charset: document.characterSet, - title: target.title, - rel: target.rel, - type: target.type - }; - - // rel=icon can also have a sizes attribute - if (target.hasAttribute("sizes")) - json.sizes = target.getAttribute("sizes"); - - sendAsyncMessage("DOMLinkAdded", json); - break; - - case "DOMWillOpenModalDialog": - case "DOMModalDialogClosed": - case "DOMWindowClose": - let retvals = sendSyncMessage(aEvent.type, { }); - for (let i in retvals) { - if (retvals[i].preventDefault) { - aEvent.preventDefault(); - break; - } - } - break; - case "input": - case "change": - this._sessionEvents.add("SessionStore:collectFormdata"); - this._sendUpdates(); - break; - case "scroll": - this._sessionEvents.add("SessionStore:collectScrollPosition"); - this._sendUpdates(); - break; - } - }, - - _sendUpdates: function() { - if (!this._timeout) { - // Wait a little before sending the message to batch multiple changes. - this._timeout = setTimeout(function() { - for (let eventType of this._sessionEvents) { - sendAsyncMessage(eventType, { - data: this._sessionEventMap[eventType](content) - }); - } - this._sessionEvents.clear(); - clearTimeout(this._timeout); - this._timeout = null; - }.bind(this), 1000); - } - } -}; - -DOMEvents.init(); - -let ContentScroll = { - // The most recent offset set by APZC for the root scroll frame - _scrollOffset: { x: 0, y: 0 }, - - init: function() { - addMessageListener("Content:SetWindowSize", this); - - addEventListener("pagehide", this, false); - addEventListener("MozScrolledAreaChanged", this, false); - }, - - getScrollOffset: function(aWindow) { - let cwu = aWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils); - let scrollX = {}, scrollY = {}; - cwu.getScrollXY(false, scrollX, scrollY); - return { x: scrollX.value, y: scrollY.value }; - }, - - getScrollOffsetForElement: function(aElement) { - if (aElement.parentNode == aElement.ownerDocument) - return this.getScrollOffset(aElement.ownerDocument.defaultView); - return { x: aElement.scrollLeft, y: aElement.scrollTop }; - }, - - receiveMessage: function(aMessage) { - let json = aMessage.json; - switch (aMessage.name) { - case "Content:SetWindowSize": { - let cwu = content.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils); - cwu.setCSSViewport(json.width, json.height); - sendAsyncMessage("Content:SetWindowSize:Complete", {}); - break; - } - } - }, - - handleEvent: function(aEvent) { - switch (aEvent.type) { - case "pagehide": - this._scrollOffset = { x: 0, y: 0 }; - break; - - case "MozScrolledAreaChanged": { - let doc = aEvent.originalTarget; - if (content != doc.defaultView) // We are only interested in root scroll pane changes - return; - - sendAsyncMessage("MozScrolledAreaChanged", { - width: aEvent.width, - height: aEvent.height, - left: aEvent.x + content.scrollX - }); - - // Send event only after painting to make sure content views in the parent process have - // been updated. - addEventListener("MozAfterPaint", function afterPaint() { - removeEventListener("MozAfterPaint", afterPaint, false); - sendAsyncMessage("Content:UpdateDisplayPort"); - }, false); - - break; - } - } - } -}; -this.ContentScroll = ContentScroll; - -ContentScroll.init(); - -let ContentActive = { - init: function() { - addMessageListener("Content:Activate", this); - addMessageListener("Content:Deactivate", this); - }, - - receiveMessage: function(aMessage) { - let json = aMessage.json; - switch (aMessage.name) { - case "Content:Deactivate": - docShell.isActive = false; - let cwu = content.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils); - if (json.keepviewport) - break; - cwu.setDisplayPortForElement(0, 0, 0, 0, content.document.documentElement, 0); - break; - - case "Content:Activate": - docShell.isActive = true; - break; - } - } -}; - -ContentActive.init(); - -/** - * Helper class for IndexedDB, child part. Listens using - * the observer service for events regarding IndexedDB - * prompts, and sends messages to the parent to actually - * show the prompts. - */ -let IndexedDB = { - _permissionsPrompt: "indexedDB-permissions-prompt", - _permissionsResponse: "indexedDB-permissions-response", - - waitingObservers: [], - - init: function IndexedDBPromptHelper_init() { - let os = Services.obs; - os.addObserver(this, this._permissionsPrompt, false); - addMessageListener("IndexedDB:Response", this); - }, - - observe: function IndexedDBPromptHelper_observe(aSubject, aTopic, aData) { - if (aTopic != this._permissionsPrompt) { - throw new Error("Unexpected topic!"); - } - - let requestor = aSubject.QueryInterface(Ci.nsIInterfaceRequestor); - let observer = requestor.getInterface(Ci.nsIObserver); - - let contentWindow = requestor.getInterface(Ci.nsIDOMWindow); - let contentDocument = contentWindow.document; - - // Remote to parent - sendAsyncMessage("IndexedDB:Prompt", { - topic: aTopic, - host: contentDocument.documentURIObject.asciiHost, - location: contentDocument.location.toString(), - data: aData, - observerId: this.addWaitingObserver(observer) - }); - }, - - receiveMessage: function(aMessage) { - let payload = aMessage.json; - switch (aMessage.name) { - case "IndexedDB:Response": - let observer = this.getAndRemoveWaitingObserver(payload.observerId); - observer.observe(null, payload.responseTopic, payload.permission); - } - }, - - addWaitingObserver: function(aObserver) { - let observerId = 0; - while (observerId in this.waitingObservers) - observerId++; - this.waitingObservers[observerId] = aObserver; - return observerId; - }, - - getAndRemoveWaitingObserver: function(aObserverId) { - let observer = this.waitingObservers[aObserverId]; - delete this.waitingObservers[aObserverId]; - return observer; - } -}; - -IndexedDB.init(); - diff --git a/browser/metro/base/content/bindings/browser.xml b/browser/metro/base/content/bindings/browser.xml deleted file mode 100644 index bd0253a9a23..00000000000 --- a/browser/metro/base/content/bindings/browser.xml +++ /dev/null @@ -1,1304 +0,0 @@ - - - - - - %findBarDTD; -]> - - - - - - - - binding. - this.removeEventListener("pageshow", this.onPageShow, true); - this.removeEventListener("pagehide", this.onPageHide, true); - this.removeEventListener("DOMPopupBlocked", this.onPopupBlocked, true); - - this.setAttribute("autoscrollpopup", "autoscrollerid"); - ]]> - - - [] - - - null - - - null - - null - - - Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - null - null - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 0 - - - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - false - - - - - - - - - - - - - - - - - - - null - - - - null - - - - - - - - - - - - - - - - - - - - - - - true - - - - - ({}) - - - - - = this.kDieTime) - this._die(); - else - // This doesn't need to be exact, just be sure to clean up at some point. - this._timeout = setTimeout(this._dieIfOld.bind(this), this.kDieTime); - }, - - /** Cleanup after ourselves. */ - _die: function() { - let timeout = this._timeout; - if (timeout) { - clearTimeout(timeout); - this._timeout = null; - } - - if (this._contentView && Math.abs(this._pixelsPannedSinceRefresh) > 0) - this._updateCacheViewport(); - - // We expect contentViews to contain our ID. If not, something bad - // happened. - delete this.self._contentViews[this._id]; - }, - - /** - * Given the cache size and the viewport size, this determines where the cache - * should start relative to the scroll position. This adjusts the position based - * on which direction the user is panning, so that we use our cache as - * effectively as possible. - * - * @param aDirection Negative means user is panning to the left or above - * Zero means user did not pan - * Positive means user is panning to the right or below - * @param aViewportSize The width or height of the viewport - * @param aCacheSize The width or height of the displayport - */ - _getRelativeCacheStart: function(aDirection, aViewportSize, aCacheSize) { - // Remember that this is relative to the viewport scroll position. - // Let's assume we are thinking about the y-axis. - // The extreme cases: - // |0| would mean that there is no content available above - // |aViewportSize - aCacheSize| would mean no content available below - // - // Taking the average of the extremes puts equal amounts of cache on the - // top and bottom of the viewport. If we think of this like a weighted - // average, .5 is the sweet spot where equals amounts of content are - // above and below the visible area. - // - // This weight is therefore how much of the cache is above (or to the - // left) the visible area. - let cachedAbove = .5; - - // If panning down, leave only 25% of the non-visible cache above. - if (aDirection > 0) - cachedAbove = .25; - - // If panning up, Leave 75% of the non-visible cache above. - if (aDirection < 0) - cachedAbove = .75; - - return (aViewportSize - aCacheSize) * cachedAbove; - }, - - /** Determine size of the pixel cache. */ - _getCacheSize: function(viewportSize) { - let self = this.self; - let contentView = this._contentView; - - let cacheWidth = self._cacheRatioWidth * viewportSize.width; - let cacheHeight = self._cacheRatioHeight * viewportSize.height; - let contentSize = this._getContentSize(); - let contentWidth = contentSize.width; - let contentHeight = contentSize.height; - - // There are common cases, such as long skinny pages, where our cache size is - // bigger than our content size. In those cases, we take that sliver of leftover - // space and apply it to the other dimension. - if (contentWidth < cacheWidth) { - cacheHeight += (cacheWidth - contentWidth) * cacheHeight / cacheWidth; - cacheWidth = contentWidth; - } else if (contentHeight < cacheHeight) { - cacheWidth += (cacheHeight - contentHeight) * cacheWidth / cacheHeight; - cacheHeight = contentHeight; - } - - return { width: cacheWidth, height: cacheHeight }; - }, - - _sendDisplayportUpdate: function(scrollX, scrollY) { - let self = this.self; - if (!self.active) - return; - - let contentView = this._contentView; - let viewportSize = this._getViewportSize(); - let cacheSize = this._getCacheSize(viewportSize); - let cacheX = this._getRelativeCacheStart(this._pixelsPannedSinceRefresh.x, viewportSize.width, cacheSize.width) + contentView.scrollX; - let cacheY = this._getRelativeCacheStart(this._pixelsPannedSinceRefresh.y, viewportSize.height, cacheSize.height) + contentView.scrollY; - let contentSize = this._getContentSize(); - - // Use our pixels efficiently and don't try to cache things outside of content - // boundaries (The left bound can be negative because of RTL). - - let rootScale = self.scale; - let leftBound = self._contentDocumentLeft * rootScale; - let bounds = new Rect(leftBound, 0, contentSize.width, contentSize.height); - let displayport = new Rect(cacheX, cacheY, cacheSize.width, cacheSize.height); - displayport.translateInside(bounds); - - self.messageManager.sendAsyncMessage("Content:SetCacheViewport", { - scrollX: Math.round(scrollX) / rootScale, - scrollY: Math.round(scrollY) / rootScale, - x: Math.round(displayport.x) / rootScale, - y: Math.round(displayport.y) / rootScale, - w: Math.round(displayport.width) / rootScale, - h: Math.round(displayport.height) / rootScale, - scale: rootScale, - id: contentView.id - }); - - this._pixelsPannedSinceRefresh.x = 0; - this._pixelsPannedSinceRefresh.y = 0; - }, - - _updateCSSViewport: function() { - let contentView = this._contentView; - this._sendDisplayportUpdate(contentView.scrollX, - contentView.scrollY); - }, - - /** - * The cache viewport is what parts of content is cached in the parent process for - * fast scrolling. This syncs that up with the current projection viewport. - */ - _updateCacheViewport: function() { - // Do not update scroll values for content. - if (this.isRoot()) - this._sendDisplayportUpdate(-1, -1); - else { - let contentView = this._contentView; - this._sendDisplayportUpdate(contentView.scrollX, - contentView.scrollY); - } - }, - - _getContentSize: function() { - let self = this.self; - return { width: this._contentView.contentWidth, - height: this._contentView.contentHeight }; - }, - - _getViewportSize: function() { - let self = this.self; - if (this.isRoot()) { - let bcr = self.getBoundingClientRect(); - return { width: bcr.width, height: bcr.height }; - } else { - return { width: this._contentView.viewportWidth, - height: this._contentView.viewportHeight }; - } - }, - - init: function(contentView) { - let self = this.self; - - this._contentView = contentView; - this._id = contentView.id; - this._scale = 1; - self._contentViews[this._id] = this; - - if (!this.isRoot()) { - // Non-root content views are short lived. - this._timeout = setTimeout(this._dieIfOld.bind(this), this.kDieTime); - // This iframe may not have a display port yet, so build up a cache - // immediately. - this._updateCacheViewport(); - } - }, - - isRoot: function() { - return this.self._contentViewManager.rootContentView == this._contentView; - }, - - scrollBy: function(x, y) { - let self = this.self; - - // Bounding content rectangle is in device pixels - let contentView = this._contentView; - let viewportSize = this._getViewportSize(); - let contentSize = this._getContentSize(); - // Calculate document dimensions in device pixels - let scrollRangeX = contentSize.width - viewportSize.width; - let scrollRangeY = contentSize.height - viewportSize.height; - - let leftOffset = self._contentDocumentLeft * this._scale; - x = Math.floor(Math.max(leftOffset, Math.min(scrollRangeX + leftOffset, contentView.scrollX + x))) - contentView.scrollX; - y = Math.floor(Math.max(0, Math.min(scrollRangeY, contentView.scrollY + y))) - contentView.scrollY; - - if (x == 0 && y == 0) - return; - - contentView.scrollBy(x, y); - - this._lastPanTime = Date.now(); - - this._pixelsPannedSinceRefresh.x += x; - this._pixelsPannedSinceRefresh.y += y; - if (Math.abs(this._pixelsPannedSinceRefresh.x) > 20 || - Math.abs(this._pixelsPannedSinceRefresh.y) > 20) - this._updateCacheViewport(); - }, - - scrollTo: function(x, y) { - let contentView = this._contentView; - this.scrollBy(x - contentView.scrollX, y - contentView.scrollY); - }, - - _setScale: function _setScale(scale) { - this._scale = scale; - this._contentView.setScale(scale, scale); - }, - - getPosition: function() { - let contentView = this._contentView; - return { x: contentView.scrollX, y: contentView.scrollY }; - } - }) - ]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - null - - - - - - - - diff --git a/browser/metro/base/content/bindings/circularprogress.xml b/browser/metro/base/content/bindings/circularprogress.xml deleted file mode 100644 index 38a2bec00d6..00000000000 --- a/browser/metro/base/content/bindings/circularprogress.xml +++ /dev/null @@ -1,134 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - document.getAnonymousElementByAttribute(this, "anonid", "progressRing"); - - - document.getAnonymousElementByAttribute(this, "anonid", - "progressNotification"); - - null - null - - - - - - - { - this.updateProgress(this.getAttribute("progress")) - } - this._img.src = PROGRESS_RING_IMG; - } - else if (this._img.complete) { - let ctx = this._progressCircleCtx; - ctx.clearRect(0, 0, - this._progressCanvas.width, this._progressCanvas.height); - - // Save the state, so we can undo the clipping - ctx.save(); - - ctx.beginPath(); - let center = this._progressCanvas.width / 2; - ctx.arc(center, center, center, startAngle, endAngle, false); - ctx.lineTo(center, center); - ctx.closePath(); - ctx.clip(); - - // Draw circle image. - ctx.translate(center, center); - ctx.rotate(endAngle); - ctx.drawImage(this._img, -center, -center); - - ctx.restore(); - } else { - // Image is still loading - } - return [startAngle, endAngle]; - ]]> - - - - - {}; - } - this._progressCircleCtx.clearRect(0, 0, - this._progressCanvas.width, this._progressCanvas.height); - this.removeAttribute("progress"); - ]]> - - - - - - - - - - - - - - - diff --git a/browser/metro/base/content/bindings/console.xml b/browser/metro/base/content/bindings/console.xml deleted file mode 100644 index 33ddf91e85b..00000000000 --- a/browser/metro/base/content/bindings/console.xml +++ /dev/null @@ -1,50 +0,0 @@ - - - - -%browserDTD; -]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/browser/metro/base/content/bindings/cssthrobber.xml b/browser/metro/base/content/bindings/cssthrobber.xml deleted file mode 100644 index c64b8d4380b..00000000000 --- a/browser/metro/base/content/bindings/cssthrobber.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - document.getAnonymousElementByAttribute(this, "anonid", "container"); - - - - - - - - diff --git a/browser/metro/base/content/bindings/dialog.xml b/browser/metro/base/content/bindings/dialog.xml deleted file mode 100644 index dd1152744b5..00000000000 --- a/browser/metro/base/content/bindings/dialog.xml +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/browser/metro/base/content/bindings/flyoutpanel.xml b/browser/metro/base/content/bindings/flyoutpanel.xml deleted file mode 100644 index 35d4bfeeb7e..00000000000 --- a/browser/metro/base/content/bindings/flyoutpanel.xml +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/browser/metro/base/content/bindings/grid.xml b/browser/metro/base/content/bindings/grid.xml deleted file mode 100644 index 5d875ee642a..00000000000 --- a/browser/metro/base/content/bindings/grid.xml +++ /dev/null @@ -1,1125 +0,0 @@ - - - - - - - - - - - - - - - - - - - - null - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1) { - verbSet.add('clear'); - } - // returns Set - return verbSet; - ]]> - - - - - - null - - - - - - - - - - - - - - - - - - - = 0) { - let selected = this.getItemAtIndex(val); - this.selectItem(selected); - } else { - this.selectNone(); - } - ]]> - - - - - - - - - - - - - - cnode.getAttribute("value")); - ]]> - - - - - - - - slotCount) { - let orphanNode = child; - child = orphanNode.nextSibling; - this.removeChild(orphanNode); - continue; - } - if (child.hasAttribute("value")) { - this._releaseSlot(child); - } - child = child.nextSibling; - childIndex++; - } - // create our quota of item slots - for (let count = this.childElementCount; count < slotCount; count++) { - this.appendChild( this._createItemElement() ); - } - - if (!aSkipArrange) - this.arrangeItems(); - ]]> - - - - - - - 0; count--) { - this.appendChild( this._createItemElement() ); - } - return this.children[anIndex]; - ]]> - - - - - - - - - - - - - - - - - - - - - - - 0 && !this.children[childIndex-1].hasAttribute("value")) { - insertedItem = this.children[childIndex-1]; - } else { - insertedItem = this.insertBefore(this._createItemElement(),existing); - } - } - if (!insertedItem) { - insertedItem = this._slotAt(anIndex); - } - insertedItem.setAttribute("value", aValue); - insertedItem.setAttribute("label", aLabel); - if (!aSkipArrange) - this.arrangeItems(); - return insertedItem; - ]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - = lowerBound && - this.selectedIndex < higherBound; - ]]> - - - - - - - - - - - - - - - - - - - - 0 - - 0 - - - - - - - - - - - - - - - - - null - 0 - 5 - - - - - this._scheduledArrangeItemsTries - ) { - this._scheduledArrangeItemsTimerId = setTimeout(this.arrangeItems.bind(this), aTime || 0); - // track how many times we've attempted arrangeItems - this._scheduledArrangeItemsTries++; - } - ]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "tiles.css" - - - width/height values - // The keys in this object are string-matched against the selectorText - // of rules in our stylesheet. Quoted values in a selector will always use " not ' - let typeSelectors = { - 'richgriditem' : "default", - 'richgriditem[tiletype="thumbnail"]': "thumbnail", - 'richgriditem[search]': "search", - 'richgriditem[compact]': "compact" - }; - let rules, sheet; - for (let i=0; (sheet=sheets[i]); i++) { - if (sheet.href && sheet.href.endsWith( this._tileStyleSheetName )) { - rules = sheet.cssRules; - break; - } - } - if (rules) { - // walk the stylesheet rules until we've matched all our selectors - for (let i=0, rule;(rule=rules[i]); i++) { - let type = rule.selectorText && typeSelectors[rule.selectorText]; - if (type) { - let sizes = typeSizes[type] = {}; - typeSelectors[type] = null; - delete typeSelectors[type]; - // we assume px unit for tile dimension values - sizes.width = parseInt(rule.style.getPropertyValue("width")); - sizes.height = parseInt(rule.style.getPropertyValue("height")); - } - if (!Object.keys(typeSelectors).length) - break; - } - } else { - throw new Error("Failed to find stylesheet to parse out richgriditem dimensions\n"); - } - return typeSizes; - ]]> - - - - - - - = 0 && anIndex < this.itemCount; - ]]> - - - - - - - - - - - - - - - - - - - - - - y) { - if (1 - y > x) { - angle = Math.ceil((.5 - y) * deflectY); - bendNode.style.transform = "perspective("+perspective+") rotateX(" + angle + "deg)"; - bendNode.style.transformOrigin = "center bottom"; - } else { - angle = Math.ceil((x - .5) * deflectX); - bendNode.style.transform = "perspective("+perspective+") rotateY(" + angle + "deg)"; - bendNode.style.transformOrigin = "left center"; - } - } else { - if (1 - y < x) { - angle = -Math.ceil((y - .5) * deflectY); - bendNode.style.transform = "perspective("+perspective+") rotateX(" + angle + "deg)"; - bendNode.style.transformOrigin = "center top"; - } else { - angle = -Math.ceil((.5 - x) * deflectX); - bendNode.style.transform = "perspective("+perspective+") rotateY(" + angle + "deg)"; - bendNode.style.transformOrigin = "right center"; - } - } - // mark when bend effect is applied - aItem.setAttribute("bending", true); - ]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - null - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/browser/metro/base/content/bindings/notification.xml b/browser/metro/base/content/bindings/notification.xml deleted file mode 100644 index 897d5c6243d..00000000000 --- a/browser/metro/base/content/bindings/notification.xml +++ /dev/null @@ -1,158 +0,0 @@ - - - - - -%notificationDTD; -]> - - - - - - - - - - - - - - - - - - - - - - - - - = 0; n--) { - if (notifications[n].priority < priority) - break; - insertPos = notifications[n]; - } - if (!insertPos) { - aItem.style.position = "fixed"; - aItem.style.top = "100%"; - aItem.style.marginTop = "-15px"; - aItem.style.opacity = "0"; - } - let label = aItem.label; - this.insertBefore(aItem, insertPos); - aItem.label = label; - - if (!insertPos) - this._showNotification(aItem, true, true); - - // Fire event for accessibility APIs - var event = document.createEvent("Events"); - event.initEvent("AlertActive", true, true); - aItem.dispatchEvent(event); - - return aItem; - ]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/browser/metro/base/content/bindings/popup.xml b/browser/metro/base/content/bindings/popup.xml deleted file mode 100644 index a0ccd490891..00000000000 --- a/browser/metro/base/content/bindings/popup.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/browser/metro/base/content/bindings/selectionoverlay.xml b/browser/metro/base/content/bindings/selectionoverlay.xml deleted file mode 100644 index eece717a1ed..00000000000 --- a/browser/metro/base/content/bindings/selectionoverlay.xml +++ /dev/null @@ -1,111 +0,0 @@ - - - - - - - - - - - - - - document.getAnonymousElementByAttribute(this, "anonid", "selection-overlay-inner").parentNode; - document.getAnonymousElementByAttribute(this, "anonid", "selection-overlay-debug"); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/browser/metro/base/content/bindings/tabprompts.xml b/browser/metro/base/content/bindings/tabprompts.xml deleted file mode 100644 index 0e50e1765c7..00000000000 --- a/browser/metro/base/content/bindings/tabprompts.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/browser/metro/base/content/bindings/tabs.xml b/browser/metro/base/content/bindings/tabs.xml deleted file mode 100644 index bedca4a478b..00000000000 --- a/browser/metro/base/content/bindings/tabs.xml +++ /dev/null @@ -1,208 +0,0 @@ - - - - -%browserDTD; -]> - - - - - - - - - - - - - - - - - - - - - - - - document.getAnonymousElementByAttribute(this, "anonid", "thumbnail-canvas"); - document.getAnonymousElementByAttribute(this, "anonid", "close"); - document.getAnonymousElementByAttribute(this, "anonid", "title"); - document.getAnonymousElementByAttribute(this, "anonid", "favicon"); - this.parentNode; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - document.getAnonymousElementByAttribute(this, "anonid", "tabs-scrollbox"); - null - - - - - - - - - - - - - - = 0) { - let child = this.strip.children[aIndex]; - this.strip.insertBefore(tab, child); - } else { - this.strip.appendChild(tab); - } - return tab; - ]]> - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/browser/metro/base/content/bindings/toggleswitch.xml b/browser/metro/base/content/bindings/toggleswitch.xml deleted file mode 100644 index 3a3f4e36366..00000000000 --- a/browser/metro/base/content/bindings/toggleswitch.xml +++ /dev/null @@ -1,144 +0,0 @@ - - - - - - %checkboxDTD; -]> - - - - - - - - - - - - - - - - - - - document.getAnonymousElementByAttribute(this, "anonid", "group"); - - - - document.getAnonymousElementByAttribute(this, "anonid", "on"); - - - - document.getAnonymousElementByAttribute(this, "anonid", "onlabel"); - - - - document.getAnonymousElementByAttribute(this, "anonid", "off"); - - - - document.getAnonymousElementByAttribute(this, "anonid", "offlabel"); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/browser/metro/base/content/bindings/urlbar.xml b/browser/metro/base/content/bindings/urlbar.xml deleted file mode 100644 index 7d93dba3788..00000000000 --- a/browser/metro/base/content/bindings/urlbar.xml +++ /dev/null @@ -1,937 +0,0 @@ - - - - - -%browserDTD; -]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 || this.valueIsTyped) - return selectedVal; - - // The selection doesn't span the full domain if it doesn't contain a slash and is - // followed by some character other than a slash. - if (!selectedVal.contains("/")) { - let remainder = inputVal.replace(selectedVal, ""); - if (remainder != "" && remainder[0] != "/") - return selectedVal; - } - - let uriFixup = Cc["@mozilla.org/docshell/urifixup;1"].getService(Ci.nsIURIFixup); - - let uri; - try { - uri = uriFixup.createFixupURI(inputVal, Ci.nsIURIFixup.FIXUP_FLAG_NONE); - } catch (e) {} - if (!uri) - return selectedVal; - - // Only copy exposable URIs - try { - uri = uriFixup.createExposableURI(uri); - } catch (ex) {} - - // If the entire URL is selected, just use the actual loaded URI. - if (inputVal == selectedVal) { - // ... but only if isn't a javascript: or data: URI, since those - // are hard to read when encoded - if (!uri.schemeIs("javascript") && !uri.schemeIs("data")) { - // Parentheses are known to confuse third-party applications (bug 458565). - selectedVal = uri.spec.replace(/[()]/g, function (c) escape(c)); - } - - return selectedVal; - } - - // Just the beginning of the URL is selected, check for a trimmed value - let spec = uri.spec; - let trimmedSpec = this._trimURL(spec); - if (spec != trimmedSpec) { - // Prepend the portion that trimURL removed from the beginning. - // This assumes trimURL will only truncate the URL at - // the beginning or end (or both). - let trimmedSegments = spec.split(trimmedSpec); - selectedVal = trimmedSegments[0] + selectedVal; - } - - return selectedVal; - ]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - = 0) { - aURL = aURL.substring(0, firstSlash) + suffix + aURL.substring(firstSlash + 1); - } else { - aURL = aURL + suffix; - } - aURL = "http://www." + aURL; - } - } - - return aURL; - ]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - null - - - - - - - - - - - - - - - - - - - - - - - - - - - = 0 || - this._searches.selectedIndex >= 0); - ]]> - - - - - - - - - - - - - - - - - - - - null - - document.getAnonymousElementByAttribute(this, 'anonid', 'results'); - document.getAnonymousElementByAttribute(this, 'anonid', 'results-container'); - - document.getAnonymousElementByAttribute(this, 'anonid', 'searches-header'); - document.getAnonymousElementByAttribute(this, 'anonid', 'searches'); - - - - - - - - - - - - - - - - - - - - - - - - - lastMatch) { - item.removeAttribute("value"); - item.removeAttribute("autocomplete"); - continue; - } - - let value = controller.getValueAt(i); - let label = controller.getCommentAt(i) || value; - let iconURI = controller.getImageAt(i); - - item.setAttribute("autocomplete", true); - item.setAttribute("label", label); - item.setAttribute("value", value); - item.setAttribute("iconURI", iconURI); - let xpFaviconURI = Services.io.newURI(iconURI.replace("moz-anno:favicon:",""), null, null); - Task.spawn(function() { - let colorInfo = yield ColorUtils.getForegroundAndBackgroundIconColors(xpFaviconURI); - if ( !(colorInfo && colorInfo.background && colorInfo.foreground) - || (item.getAttribute("iconURI") != iconURI) ) { - return; - } - let { background, foreground } = colorInfo; - item.style.color = foreground; //color text - item.setAttribute("customColor", background); - // when bound, use the setter to propogate the color change through the tile - if ('color' in item) { - item.color = background; - } - }).then(null, err => Components.utils.reportError(err)); - } - - this._results.arrangeItems(); - ]]> - - - - - - [] - - - - - - - - - - 0) - this._searches.removeItemAt(0, true); - - this._engines.forEach(function (anEngine) { - let item = this._searches.appendItem("", anEngine.name, true); - item.setAttribute("autocomplete", "true"); - item.setAttribute("search", "true"); - - let largeImage = anEngine.getIconURLBySize(74,74); - if (largeImage) { - item.setAttribute("iconsize", "large"); - item.setAttribute("iconURI", largeImage); - } else if (anEngine.iconURI && anEngine.iconURI.spec) { - item.setAttribute("iconURI", anEngine.iconURI.spec); - item.setAttribute("customColor", "#fff"); - } - }.bind(this)); - - this._searches.arrangeItems(); - ]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - = 0) { - let url = this.input.controller.getValueAt(this._results.selectedIndex); - this.input.value = url; - return this.input.submitURL(); - } - - if (this._isGridBound(this._searches) && - this._searches.selectedIndex >= 0) { - let engine = this._engines[this._searches.selectedIndex]; - return this.input.submitSearch(engine.name); - } - - return false; - ]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/browser/metro/base/content/bookmarks.js b/browser/metro/base/content/bookmarks.js deleted file mode 100644 index d7727126745..00000000000 --- a/browser/metro/base/content/bookmarks.js +++ /dev/null @@ -1,76 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -'use strict'; - -/** - * Utility singleton for manipulating bookmarks. - */ -var Bookmarks = { - get metroRoot() { - return PlacesUtils.annotations.getItemsWithAnnotation('metro/bookmarksRoot', {})[0]; - }, - - logging: false, - log: function(msg) { - if (this.logging) { - Services.console.logStringMessage(msg); - } - }, - - addForURI: function bh_addForURI(aURI, aTitle, callback) { - this.isURIBookmarked(aURI, function (isBookmarked) { - if (isBookmarked) - return; - - let bookmarkTitle = aTitle || aURI.spec; - let bookmarkService = PlacesUtils.bookmarks; - let bookmarkId = bookmarkService.insertBookmark(Bookmarks.metroRoot, - aURI, - bookmarkService.DEFAULT_INDEX, - bookmarkTitle); - - // XXX Used for browser-chrome tests - let event = document.createEvent("Events"); - event.initEvent("BookmarkCreated", true, false); - window.dispatchEvent(event); - - if (callback) - callback(bookmarkId); - }); - }, - - _isMetroBookmark: function(aItemId) { - return PlacesUtils.bookmarks.getFolderIdForItem(aItemId) == Bookmarks.metroRoot; - }, - - isURIBookmarked: function bh_isURIBookmarked(aURI, callback) { - if (!callback) - return; - PlacesUtils.asyncGetBookmarkIds(aURI, aItemIds => { - callback(aItemIds && aItemIds.length > 0 && aItemIds.some(this._isMetroBookmark)); - }); - }, - - removeForURI: function bh_removeForURI(aURI, callback) { - // XXX blargle xpconnect! might not matter, but a method on - // nsINavBookmarksService that takes an array of items to - // delete would be faster. better yet, a method that takes a URI! - PlacesUtils.asyncGetBookmarkIds(aURI, (aItemIds) => { - aItemIds.forEach((aItemId) => { - if (this._isMetroBookmark(aItemId)) { - PlacesUtils.bookmarks.removeItem(aItemId); - } - }); - - if (callback) - callback(); - - // XXX Used for browser-chrome tests - let event = document.createEvent("Events"); - event.initEvent("BookmarkRemoved", true, false); - window.dispatchEvent(event); - }); - } -}; diff --git a/browser/metro/base/content/browser-scripts.js b/browser/metro/base/content/browser-scripts.js deleted file mode 100644 index 774d4d19357..00000000000 --- a/browser/metro/base/content/browser-scripts.js +++ /dev/null @@ -1,173 +0,0 @@ -// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); - -/* - * JS modules - */ - -XPCOMUtils.defineLazyModuleGetter(this, "Downloads", - "resource://gre/modules/Downloads.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "FormHistory", - "resource://gre/modules/FormHistory.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "FileUtils", - "resource://gre/modules/FileUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "PageThumbs", - "resource://gre/modules/PageThumbs.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "PluralForm", - "resource://gre/modules/PluralForm.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils", - "resource://gre/modules/PlacesUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "NetUtil", - "resource://gre/modules/NetUtil.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "DownloadUtils", - "resource://gre/modules/DownloadUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "NewTabUtils", - "resource://gre/modules/NewTabUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "Promise", - "resource://gre/modules/Promise.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "ColorUtils", - "resource:///modules/colorUtils.jsm"); - -#ifdef NIGHTLY_BUILD -XPCOMUtils.defineLazyModuleGetter(this, "ShumwayUtils", - "resource://shumway/ShumwayUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "PdfJs", - "resource://pdf.js/PdfJs.jsm"); -#endif - -XPCOMUtils.defineLazyModuleGetter(this, "Task", - "resource://gre/modules/Task.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "OS", - "resource://gre/modules/osfile.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "UITelemetry", - "resource://gre/modules/UITelemetry.jsm"); - -#ifdef MOZ_UPDATER -XPCOMUtils.defineLazyModuleGetter(this, "AddonManager", - "resource://gre/modules/AddonManager.jsm"); -#endif - -/* - * Services - */ - -XPCOMUtils.defineLazyServiceGetter(this, "StyleSheetSvc", - "@mozilla.org/content/style-sheet-service;1", - "nsIStyleSheetService"); -XPCOMUtils.defineLazyServiceGetter(window, "gHistSvc", - "@mozilla.org/browser/nav-history-service;1", - "nsINavHistoryService", - "nsIBrowserHistory"); -XPCOMUtils.defineLazyServiceGetter(window, "gURIFixup", - "@mozilla.org/docshell/urifixup;1", - "nsIURIFixup"); -XPCOMUtils.defineLazyServiceGetter(window, "gFaviconService", - "@mozilla.org/browser/favicon-service;1", - "nsIFaviconService"); -XPCOMUtils.defineLazyServiceGetter(window, "gFocusManager", - "@mozilla.org/focus-manager;1", - "nsIFocusManager"); -XPCOMUtils.defineLazyServiceGetter(window, "gEventListenerService", - "@mozilla.org/eventlistenerservice;1", - "nsIEventListenerService"); -#ifdef MOZ_CRASHREPORTER -XPCOMUtils.defineLazyServiceGetter(this, "CrashReporter", - "@mozilla.org/xre/app-info;1", - "nsICrashReporter"); -#endif - -/* - * window.Rect is used by - * http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-Rect - * so it is not possible to set a lazy getter for Geometry.jsm. - */ -Cu.import("resource://gre/modules/Geometry.jsm"); -/* - * Browser scripts - */ -let ScriptContexts = {}; -[ - ["ContentAreaObserver", "chrome://browser/content/ContentAreaObserver.js"], - ["WebProgress", "chrome://browser/content/WebProgress.js"], - ["FindHelperUI", "chrome://browser/content/helperui/FindHelperUI.js"], - ["FormHelperUI", "chrome://browser/content/helperui/FormHelperUI.js"], - ["BrowserTouchHandler", "chrome://browser/content/BrowserTouchHandler.js"], - ["AlertsHelper", "chrome://browser/content/helperui/AlertsHelper.js"], - ["AutofillMenuUI", "chrome://browser/content/helperui/MenuUI.js"], - ["ContextMenuUI", "chrome://browser/content/helperui/MenuUI.js"], - ["MenuControlUI", "chrome://browser/content/helperui/MenuUI.js"], - ["MenuPopup", "chrome://browser/content/helperui/MenuUI.js"], - ["IndexedDB", "chrome://browser/content/helperui/IndexedDB.js"], - ["OfflineApps", "chrome://browser/content/helperui/OfflineApps.js"], - ["SelectHelperUI", "chrome://browser/content/helperui/SelectHelperUI.js"], - ["SelectionHelperUI", "chrome://browser/content/helperui/SelectionHelperUI.js"], - ["SelectionPrototype", "chrome://browser/content/library/SelectionPrototype.js"], - ["ChromeSelectionHandler", "chrome://browser/content/helperui/ChromeSelectionHandler.js"], - ["CommandUpdater", "chrome://browser/content/commandUtil.js"], - ["ContextCommands", "chrome://browser/content/ContextCommands.js"], - ["Bookmarks", "chrome://browser/content/bookmarks.js"], - ["MetroDownloadsView", "chrome://browser/content/downloads.js"], - ["ConsolePanelView", "chrome://browser/content/console.js"], - ["Site", "chrome://browser/content/Site.js"], - ["TopSites", "chrome://browser/content/TopSites.js"], - ["Sanitizer", "chrome://browser/content/sanitize.js"], - ["SanitizeUI", "chrome://browser/content/sanitizeUI.js"], - ["SSLExceptions", "chrome://browser/content/exceptions.js"], - ["ItemPinHelper", "chrome://browser/content/helperui/ItemPinHelper.js"], - ["NavButtonSlider", "chrome://browser/content/NavButtonSlider.js"], - ["ContextUI", "chrome://browser/content/ContextUI.js"], - ["FlyoutPanelsUI", "chrome://browser/content/flyoutpanels/FlyoutPanelsUI.js"], - ["SettingsCharm", "chrome://browser/content/flyoutpanels/SettingsCharm.js"], - ["APZCObserver", "chrome://browser/content/apzc.js"], -].forEach(function (aScript) { - let [name, script] = aScript; - XPCOMUtils.defineLazyGetter(window, name, function() { - let sandbox; - if (script in ScriptContexts) { - sandbox = ScriptContexts[script]; - } else { - sandbox = ScriptContexts[script] = {}; - Services.scriptloader.loadSubScript(script, sandbox); - } - return sandbox[name]; - }); -}); -#ifdef MOZ_SERVICES_SYNC -XPCOMUtils.defineLazyGetter(this, "Weave", function() { - Components.utils.import("resource://services-sync/main.js"); - return Weave; -}); -#endif - -/* - * Delay load some global scripts using a custom namespace - */ -XPCOMUtils.defineLazyGetter(this, "GlobalOverlay", function() { - let GlobalOverlay = {}; - Services.scriptloader.loadSubScript("chrome://global/content/globalOverlay.js", GlobalOverlay); - return GlobalOverlay; -}); - -XPCOMUtils.defineLazyGetter(this, "ContentAreaUtils", function() { - let ContentAreaUtils = {}; - Services.scriptloader.loadSubScript("chrome://global/content/contentAreaUtils.js", ContentAreaUtils); - return ContentAreaUtils; -}); diff --git a/browser/metro/base/content/browser-ui.js b/browser/metro/base/content/browser-ui.js deleted file mode 100644 index 277f397541b..00000000000 --- a/browser/metro/base/content/browser-ui.js +++ /dev/null @@ -1,1402 +0,0 @@ -// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -Cu.import("resource://gre/modules/devtools/dbg-server.jsm") -Cu.import("resource://gre/modules/WindowsPrefSync.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "LoginManagerParent", - "resource://gre/modules/LoginManagerParent.jsm"); - -/** - * Constants - */ - -// Devtools Messages -const debugServerStateChanged = "devtools.debugger.remote-enabled"; -const debugServerPortChanged = "devtools.debugger.remote-port"; - -// delay when showing the tab bar briefly after a new foreground tab opens -const kForegroundTabAnimationDelay = 1000; -// delay when showing the tab bar after opening a new background tab opens -const kBackgroundTabAnimationDelay = 3000; -// delay before closing tab bar after closing or selecting a tab -const kChangeTabAnimationDelay = 500; - -/** - * Cache of commonly used elements. - */ - -let Elements = {}; -[ - ["contentShowing", "bcast_contentShowing"], - ["urlbarState", "bcast_urlbarState"], - ["loadingState", "bcast_loadingState"], - ["windowState", "bcast_windowState"], - ["chromeState", "bcast_chromeState"], - ["mainKeyset", "mainKeyset"], - ["stack", "stack"], - ["tabList", "tabs"], - ["tabs", "tabs-container"], - ["controls", "browser-controls"], - ["panelUI", "panel-container"], - ["tray", "tray"], - ["toolbar", "toolbar"], - ["browsers", "browsers"], - ["navbar", "navbar"], - ["autocomplete", "urlbar-autocomplete"], - ["contextappbar", "contextappbar"], - ["findbar", "findbar"], - ["contentViewport", "content-viewport"], - ["progress", "progress-control"], - ["progressContainer", "progress-container"], - ["feedbackLabel", "feedback-label"], -].forEach(function (aElementGlobal) { - let [name, id] = aElementGlobal; - XPCOMUtils.defineLazyGetter(Elements, name, function() { - return document.getElementById(id); - }); -}); - -/** - * Cache of commonly used string bundles. - */ - -var Strings = {}; -[ - ["browser", "chrome://browser/locale/browser.properties"], - ["brand", "chrome://branding/locale/brand.properties"] -].forEach(function (aStringBundle) { - let [name, bundle] = aStringBundle; - XPCOMUtils.defineLazyGetter(Strings, name, function() { - return Services.strings.createBundle(bundle); - }); -}); - -var BrowserUI = { - get _edit() { return document.getElementById("urlbar-edit"); }, - get _back() { return document.getElementById("cmd_back"); }, - get _forward() { return document.getElementById("cmd_forward"); }, - - lastKnownGoodURL: "", // used when the user wants to escape unfinished url entry - ready: false, // used for tests to determine when delayed initialization is done - - init: function() { - // start the debugger now so we can use it on the startup code as well - if (Services.prefs.getBoolPref(debugServerStateChanged)) { - this.runDebugServer(); - } - Services.prefs.addObserver(debugServerStateChanged, this, false); - Services.prefs.addObserver(debugServerPortChanged, this, false); - Services.prefs.addObserver("app.crashreporter.autosubmit", this, false); - Services.prefs.addObserver("metro.private_browsing.enabled", this, false); - this.updatePrivateBrowsingUI(); - - Services.obs.addObserver(this, "handle-xul-text-link", false); - - // listen content messages - messageManager.addMessageListener("DOMTitleChanged", this); - messageManager.addMessageListener("DOMWillOpenModalDialog", this); - messageManager.addMessageListener("DOMWindowClose", this); - - messageManager.addMessageListener("Browser:OpenURI", this); - messageManager.addMessageListener("Browser:SaveAs:Return", this); - messageManager.addMessageListener("Content:StateChange", this); - - // listening escape to dismiss dialog on VK_ESCAPE - window.addEventListener("keypress", this, true); - - window.addEventListener("MozPrecisePointer", this, true); - window.addEventListener("MozImprecisePointer", this, true); - - window.addEventListener("AppCommand", this, true); - - Services.prefs.addObserver("browser.cache.disk_cache_ssl", this, false); - - // Init core UI modules - ContextUI.init(); - PanelUI.init(); - FlyoutPanelsUI.init(); - PageThumbs.init(); - NewTabUtils.init(); - SettingsCharm.init(); - NavButtonSlider.init(); - SelectionHelperUI.init(); -#ifdef NIGHTLY_BUILD - ShumwayUtils.init(); -#endif - - // We can delay some initialization until after startup. We wait until - // the first page is shown, then dispatch a UIReadyDelayed event. - messageManager.addMessageListener("pageshow", function onPageShow() { - if (getBrowser().currentURI.spec == "about:blank") - return; - - messageManager.removeMessageListener("pageshow", onPageShow); - - setTimeout(function() { - let event = document.createEvent("Events"); - event.initEvent("UIReadyDelayed", true, false); - window.dispatchEvent(event); - BrowserUI.ready = true; - }, 0); - }); - - // Only load IndexedDB.js when we actually need it. A general fix will happen in bug 647079. - messageManager.addMessageListener("IndexedDB:Prompt", function(aMessage) { - return IndexedDB.receiveMessage(aMessage); - }); - - // hook up telemetry ping for UI data - try { - UITelemetry.addSimpleMeasureFunction("metro-ui", - BrowserUI._getMeasures.bind(BrowserUI)); - } catch (ex) { - // swallow exception that occurs if metro-appbar measure is already set up - dump("Failed to addSimpleMeasureFunction in browser-ui: " + ex.message + "\n"); - } - - // Delay the panel UI and Sync initialization - window.addEventListener("UIReadyDelayed", function delayedInit(aEvent) { - Util.dumpLn("* delay load started..."); - window.removeEventListener("UIReadyDelayed", delayedInit, false); - - messageManager.addMessageListener("Browser:MozApplicationManifest", OfflineApps); - - try { - MetroDownloadsView.init(); - DialogUI.init(); - FormHelperUI.init(); - FindHelperUI.init(); - LoginManagerParent.init(); -#ifdef NIGHTLY_BUILD - PdfJs.init(); -#endif - } catch(ex) { - Util.dumpLn("Exception in delay load module:", ex.message); - } - - BrowserUI._initFirstRunContent(); - - // check for left over crash reports and submit them if found. - BrowserUI.startupCrashCheck(); - - Util.dumpLn("* delay load complete."); - }, false); - -#ifndef MOZ_OFFICIAL_BRANDING - setTimeout(function() { - let startup = Cc["@mozilla.org/toolkit/app-startup;1"].getService(Ci.nsIAppStartup).getStartupInfo(); - for (let name in startup) { - if (name != "process") - Services.console.logStringMessage("[timing] " + name + ": " + (startup[name] - startup.process) + "ms"); - } - }, 3000); -#endif - }, - - uninit: function() { - messageManager.removeMessageListener("DOMTitleChanged", this); - messageManager.removeMessageListener("DOMWillOpenModalDialog", this); - messageManager.removeMessageListener("DOMWindowClose", this); - - messageManager.removeMessageListener("Browser:OpenURI", this); - messageManager.removeMessageListener("Browser:SaveAs:Return", this); - messageManager.removeMessageListener("Content:StateChange", this); - - messageManager.removeMessageListener("Browser:MozApplicationManifest", OfflineApps); - - Services.prefs.removeObserver(debugServerStateChanged, this); - Services.prefs.removeObserver(debugServerPortChanged, this); - Services.prefs.removeObserver("app.crashreporter.autosubmit", this); - Services.prefs.removeObserver("metro.private_browsing.enabled", this); - - Services.obs.removeObserver(this, "handle-xul-text-link"); - - PanelUI.uninit(); - FlyoutPanelsUI.uninit(); - MetroDownloadsView.uninit(); - SettingsCharm.uninit(); - PageThumbs.uninit(); - if (WindowsPrefSync) { - WindowsPrefSync.uninit(); - } - this.stopDebugServer(); - }, - - /************************************ - * Devtools Debugger - */ - runDebugServer: function runDebugServer(aPort) { - let port = aPort || Services.prefs.getIntPref(debugServerPortChanged); - if (!DebuggerServer.initialized) { - DebuggerServer.init(); - DebuggerServer.addBrowserActors(); - DebuggerServer.addActors('chrome://browser/content/dbg-metro-actors.js'); - } - let listener = DebuggerServer.createListener(); - listener.portOrPath = port; - listener.open(); - }, - - stopDebugServer: function stopDebugServer() { - if (DebuggerServer.initialized) { - DebuggerServer.destroy(); - } - }, - - // If the server is not on, port changes have nothing to effect. The new value - // will be picked up if the server is started. - // To be consistent with desktop fx, if the port is changed while the server - // is running, restart server. - changeDebugPort:function changeDebugPort(aPort) { - if (DebuggerServer.initialized) { - this.stopDebugServer(); - this.runDebugServer(aPort); - } - }, - - /********************************* - * Content visibility - */ - - get isContentShowing() { - return Elements.contentShowing.getAttribute("disabled") != true; - }, - - showContent: function showContent(aURI) { - ContextUI.dismissTabs(); - ContextUI.dismissContextAppbar(); - FlyoutPanelsUI.hide(); - PanelUI.hide(); - }, - - /********************************* - * Crash reporting - */ - - get CrashSubmit() { - delete this.CrashSubmit; - Cu.import("resource://gre/modules/CrashSubmit.jsm", this); - return this.CrashSubmit; - }, - - get lastCrashID() { - return Cc["@mozilla.org/xre/runtime;1"].getService(Ci.nsIXULRuntime).lastRunCrashID; - }, - - startupCrashCheck: function startupCrashCheck() { -#ifdef MOZ_CRASHREPORTER - if (!CrashReporter.enabled) { - return; - } - - // Ensure that CrashReporter state matches pref - CrashReporter.submitReports = Services.prefs.getBoolPref("app.crashreporter.autosubmit"); - - BrowserUI.submitLastCrashReportOrShowPrompt(); -#endif - }, - - - /********************************* - * Navigation - */ - - // BrowserUI update bit flags - NO_STARTUI_VISIBILITY: 1, // don't change the start ui visibility - - /* - * Updates the overall state of startui visibility and the toolbar, but not - * the URL bar. - */ - update: function(aFlags) { - let flags = aFlags || 0; - if (!(flags & this.NO_STARTUI_VISIBILITY)) { - let uri = this.getDisplayURI(Browser.selectedBrowser); - this.updateStartURIAttributes(uri); - } - this._updateButtons(); - this._updateToolbar(); - }, - - /* Updates the URL bar. */ - updateURI: function(aOptions) { - let uri = this.getDisplayURI(Browser.selectedBrowser); - let cleanURI = Util.isURLEmpty(uri) ? "" : uri; - this._edit.value = cleanURI; - }, - - get isStartTabVisible() { - return this.isStartURI(); - }, - - isStartURI: function isStartURI(aURI) { - aURI = aURI || Browser.selectedBrowser.currentURI.spec; - return aURI.startsWith(kStartURI) || aURI == "about:start" || aURI == "about:home"; - }, - - updateStartURIAttributes: function (aURI) { - let wasStart = Elements.windowState.hasAttribute("startpage"); - aURI = aURI || Browser.selectedBrowser.currentURI.spec; - if (this.isStartURI(aURI)) { - ContextUI.displayNavbar(); - Elements.windowState.setAttribute("startpage", "true"); - } else if (aURI != "about:blank") { // about:blank is loaded briefly for new tabs; ignore it - Elements.windowState.removeAttribute("startpage"); - } - - let isStart = Elements.windowState.hasAttribute("startpage"); - if (wasStart != isStart) { - let event = document.createEvent("Events"); - event.initEvent("StartUIChange", true, true); - Browser.selectedBrowser.dispatchEvent(event); - } - }, - - getDisplayURI: function(browser) { - let uri = browser.currentURI; - let spec = uri.spec; - - try { - spec = gURIFixup.createExposableURI(uri).spec; - } catch (ex) {} - - try { - let charset = browser.characterSet; - let textToSubURI = Cc["@mozilla.org/intl/texttosuburi;1"]. - getService(Ci.nsITextToSubURI); - spec = textToSubURI.unEscapeNonAsciiURI(charset, spec); - } catch (ex) {} - - return spec; - }, - - goToURI: function(aURI) { - aURI = aURI || this._edit.value; - if (!aURI) - return; - - this._edit.value = aURI; - - // Make sure we're online before attempting to load - Util.forceOnline(); - - BrowserUI.showContent(aURI); - Browser.selectedBrowser.focus(); - - Task.spawn(function() { - let postData = {}; - let webNav = Ci.nsIWebNavigation; - let flags = webNav.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP | - webNav.LOAD_FLAGS_FIXUP_SCHEME_TYPOS; - aURI = yield Browser.getShortcutOrURI(aURI, postData); - Browser.loadURI(aURI, { flags: flags, postData: postData }); - - // Delay doing the fixup so the raw URI is passed to loadURIWithFlags - // and the proper third-party fixup can be done - let fixupFlags = Ci.nsIURIFixup.FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP | - Ci.nsIURIFixup.FIXUP_FLAG_FIX_SCHEME_TYPOS; - let uri = gURIFixup.createFixupURI(aURI, fixupFlags); - gHistSvc.markPageAsTyped(uri); - - BrowserUI._titleChanged(Browser.selectedBrowser); - }); - }, - - doOpenSearch: function doOpenSearch(aName) { - // save the current value of the urlbar - let searchValue = this._edit.value; - let engine = Services.search.getEngineByName(aName); - let submission = engine.getSubmission(searchValue, null); - - this._edit.value = submission.uri.spec; - - // Make sure we're online before attempting to load - Util.forceOnline(); - - BrowserUI.showContent(); - Browser.selectedBrowser.focus(); - - Task.spawn(function () { - Browser.loadURI(submission.uri.spec, { postData: submission.postData }); - - // loadURI may open a new tab, so get the selectedBrowser afterward. - Browser.selectedBrowser.userTypedValue = submission.uri.spec; - BrowserUI._titleChanged(Browser.selectedBrowser); - }); - }, - - /********************************* - * Tab management - */ - - /** - * Open a new tab in the foreground in response to a user action. - * See Browser.addTab for more documentation. - */ - addAndShowTab: function (aURI, aOwner, aParams) { - ContextUI.peekTabs(kForegroundTabAnimationDelay); - return Browser.addTab(aURI || kStartURI, true, aOwner, aParams); - }, - - addAndShowPrivateTab: function (aURI, aOwner) { - return this.addAndShowTab(aURI, aOwner, { private: true }); - }, - - get isPrivateBrowsingEnabled() { - return Services.prefs.getBoolPref("metro.private_browsing.enabled"); - }, - - updatePrivateBrowsingUI: function () { - let command = document.getElementById("cmd_newPrivateTab"); - if (this.isPrivateBrowsingEnabled) { - command.removeAttribute("disabled"); - } else { - command.setAttribute("disabled", "true"); - } - }, - - /** - * Open a new tab in response to clicking a link in an existing tab. - * See Browser.addTab for more documentation. - */ - openLinkInNewTab: function (aURI, aBringFront, aOwner) { - ContextUI.peekTabs(aBringFront ? kForegroundTabAnimationDelay - : kBackgroundTabAnimationDelay); - let params = null; - if (aOwner) { - params = { - referrerURI: aOwner.browser.documentURI, - charset: aOwner.browser.characterSet, - }; - } - let tab = Browser.addTab(aURI, aBringFront, aOwner, params); - Elements.tabList.strip.ensureElementIsVisible(tab.chromeTab); - return tab; - }, - - setOnTabAnimationEnd: function setOnTabAnimationEnd(aCallback) { - Elements.tabs.addEventListener("animationend", function onAnimationEnd() { - Elements.tabs.removeEventListener("animationend", onAnimationEnd); - aCallback(); - }); - }, - - closeTab: function closeTab(aTab) { - // If no tab is passed in, assume the current tab - let tab = aTab || Browser.selectedTab; - Browser.closeTab(tab); - }, - - animateClosingTab: function animateClosingTab(tabToClose) { - tabToClose.chromeTab.setAttribute("closing", "true"); - - let wasCollapsed = !ContextUI.tabbarVisible; - if (wasCollapsed) { - ContextUI.displayTabs(); - } - - this.setOnTabAnimationEnd(function() { - Browser.closeTab(tabToClose, { forceClose: true } ); - if (wasCollapsed) - ContextUI.dismissTabsWithDelay(kChangeTabAnimationDelay); - }); - }, - - /** - * Re-open a closed tab. - * @param aIndex - * The index of the tab (via nsSessionStore.getClosedTabData) - * @returns a reference to the reopened tab. - */ - undoCloseTab: function undoCloseTab(aIndex) { - var tab = null; - aIndex = aIndex || 0; - var ss = Cc["@mozilla.org/browser/sessionstore;1"]. - getService(Ci.nsISessionStore); - if (ss.getClosedTabCount(window) > (aIndex)) { - tab = ss.undoCloseTab(window, aIndex); - } - return tab; - }, - - // Useful for when we've received an event to close a particular DOM window. - // Since we don't have windows, we want to close the corresponding tab. - closeTabForBrowser: function closeTabForBrowser(aBrowser) { - // Find the relevant tab, and close it. - let browsers = Browser.browsers; - for (let i = 0; i < browsers.length; i++) { - if (browsers[i] == aBrowser) { - Browser.closeTab(Browser.getTabAtIndex(i)); - return { preventDefault: true }; - } - } - - return {}; - }, - - selectTab: function selectTab(aTab) { - Browser.selectedTab = aTab; - }, - - selectTabAndDismiss: function selectTabAndDismiss(aTab) { - this.selectTab(aTab); - ContextUI.dismissTabsWithDelay(kChangeTabAnimationDelay); - }, - - selectTabAtIndex: function selectTabAtIndex(aIndex) { - // count backwards for aIndex < 0 - if (aIndex < 0) - aIndex += Browser._tabs.length; - - if (aIndex >= 0 && aIndex < Browser._tabs.length) - Browser.selectedTab = Browser._tabs[aIndex]; - }, - - selectNextTab: function selectNextTab() { - if (Browser._tabs.length == 1 || !Browser.selectedTab) { - return; - } - - let tabIndex = Browser._tabs.indexOf(Browser.selectedTab) + 1; - if (tabIndex >= Browser._tabs.length) { - tabIndex = 0; - } - - Browser.selectedTab = Browser._tabs[tabIndex]; - }, - - selectPreviousTab: function selectPreviousTab() { - if (Browser._tabs.length == 1 || !Browser.selectedTab) { - return; - } - - let tabIndex = Browser._tabs.indexOf(Browser.selectedTab) - 1; - if (tabIndex < 0) { - tabIndex = Browser._tabs.length - 1; - } - - Browser.selectedTab = Browser._tabs[tabIndex]; - }, - - // Used for when we're about to open a modal dialog, - // and want to ensure the opening tab is in front. - selectTabForBrowser: function selectTabForBrowser(aBrowser) { - for (let i = 0; i < Browser.tabs.length; i++) { - if (Browser._tabs[i].browser == aBrowser) { - Browser.selectedTab = Browser.tabs[i]; - break; - } - } - }, - - updateUIFocus: function _updateUIFocus() { - if (Elements.contentShowing.getAttribute("disabled") == "true" && Browser.selectedBrowser) - Browser.selectedBrowser.messageManager.sendAsyncMessage("Browser:Blur", { }); - }, - - blurFocusedElement: function blurFocusedElement() { - let focusedElement = document.commandDispatcher.focusedElement; - if (focusedElement) - focusedElement.blur(); - }, - - blurNavBar: function blurNavBar() { - if (this._edit.focused) { - this._edit.blur(); - - // Advanced notice to CAO, so we can shuffle the nav bar in advance - // of the keyboard transition. - ContentAreaObserver.navBarWillBlur(); - - return true; - } - return false; - }, - - observe: function BrowserUI_observe(aSubject, aTopic, aData) { - switch (aTopic) { - case "handle-xul-text-link": - let handled = aSubject.QueryInterface(Ci.nsISupportsPRBool); - if (!handled.data) { - this.addAndShowTab(aData, Browser.selectedTab); - handled.data = true; - } - break; - case "nsPref:changed": - switch (aData) { - case "browser.cache.disk_cache_ssl": - this._sslDiskCacheEnabled = Services.prefs.getBoolPref(aData); - break; - case debugServerStateChanged: - if (Services.prefs.getBoolPref(aData)) { - this.runDebugServer(); - } else { - this.stopDebugServer(); - } - break; - case debugServerPortChanged: - this.changeDebugPort(Services.prefs.getIntPref(aData)); - break; - case "app.crashreporter.autosubmit": -#ifdef MOZ_CRASHREPORTER - CrashReporter.submitReports = Services.prefs.getBoolPref(aData); - - // The user explicitly set the autosubmit option, so there is no - // need to prompt them about crash reporting in the future - Services.prefs.setBoolPref("app.crashreporter.prompted", true); - - BrowserUI.submitLastCrashReportOrShowPrompt; -#endif - break; - case "metro.private_browsing.enabled": - this.updatePrivateBrowsingUI(); - break; - } - break; - } - }, - - submitLastCrashReportOrShowPrompt: function() { -#ifdef MOZ_CRASHREPORTER - let lastCrashID = this.lastCrashID; - if (lastCrashID && lastCrashID.length) { - if (Services.prefs.getBoolPref("app.crashreporter.autosubmit")) { - Util.dumpLn("Submitting last crash id:", lastCrashID); - let params = {}; - if (!Services.prefs.getBoolPref("app.crashreporter.submitURLs")) { - params['extraExtraKeyVals'] = { URL: '' }; - } - try { - this.CrashSubmit.submit(lastCrashID, params); - } catch (ex) { - Util.dumpLn(ex); - } - } else if (!Services.prefs.getBoolPref("app.crashreporter.prompted")) { - BrowserUI.addAndShowTab("about:crashprompt", null); - } - } -#endif - }, - - - - /********************************* - * Internal utils - */ - - _titleChanged: function(aBrowser) { - let url = this.getDisplayURI(aBrowser); - - let tabCaption; - if (aBrowser.contentTitle) { - tabCaption = aBrowser.contentTitle; - } else if (!Util.isURLEmpty(aBrowser.userTypedValue)) { - tabCaption = aBrowser.userTypedValue; - } else if (!Util.isURLEmpty(url)) { - tabCaption = url; - } else { - tabCaption = Util.getEmptyURLTabTitle(); - } - - let tab = Browser.getTabForBrowser(aBrowser); - if (tab) - tab.chromeTab.updateTitle(tabCaption); - }, - - _updateButtons: function _updateButtons() { - let browser = Browser.selectedBrowser; - if (!browser) { - return; - } - if (browser.canGoBack) { - this._back.removeAttribute("disabled"); - } else { - this._back.setAttribute("disabled", true); - } - if (browser.canGoForward) { - this._forward.removeAttribute("disabled"); - } else { - this._forward.setAttribute("disabled", true); - } - }, - - _updateToolbar: function _updateToolbar() { - if (Browser.selectedTab.isLoading()) { - Elements.loadingState.setAttribute("loading", true); - } else { - Elements.loadingState.removeAttribute("loading"); - } - }, - - _closeOrQuit: function _closeOrQuit() { - // Close active dialog, if we have one. If not then close the application. - if (!BrowserUI.isContentShowing()) { - BrowserUI.showContent(); - } else { - // Check to see if we should really close the window - if (Browser.closing()) { - window.close(); - let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"].getService(Ci.nsIAppStartup); - appStartup.quit(Ci.nsIAppStartup.eForceQuit); - } - } - }, - - _onPreciseInput: function _onPreciseInput() { - document.getElementById("bcast_preciseInput").setAttribute("input", "precise"); - let uri = Util.makeURI("chrome://browser/content/cursor.css"); - if (StyleSheetSvc.sheetRegistered(uri, Ci.nsIStyleSheetService.AGENT_SHEET)) { - StyleSheetSvc.unregisterSheet(uri, - Ci.nsIStyleSheetService.AGENT_SHEET); - } - }, - - _onImpreciseInput: function _onImpreciseInput() { - document.getElementById("bcast_preciseInput").setAttribute("input", "imprecise"); - let uri = Util.makeURI("chrome://browser/content/cursor.css"); - if (!StyleSheetSvc.sheetRegistered(uri, Ci.nsIStyleSheetService.AGENT_SHEET)) { - StyleSheetSvc.loadAndRegisterSheet(uri, - Ci.nsIStyleSheetService.AGENT_SHEET); - } - }, - - _getMeasures: function() { - let dimensions = { - "window-width": ContentAreaObserver.width, - "window-height": ContentAreaObserver.height - }; - return dimensions; - }, - - /********************************* - * Event handling - */ - - handleEvent: function handleEvent(aEvent) { - var target = aEvent.target; - switch (aEvent.type) { - // Window events - case "keypress": - if (aEvent.keyCode == aEvent.DOM_VK_ESCAPE) - this.handleEscape(aEvent); - break; - case "MozPrecisePointer": - this._onPreciseInput(); - break; - case "MozImprecisePointer": - this._onImpreciseInput(); - break; - case "AppCommand": - this.handleAppCommandEvent(aEvent); - break; - } - }, - - // Checks if various different parts of the UI is visible and closes - // them one at a time. - handleEscape: function (aEvent) { - aEvent.stopPropagation(); - aEvent.preventDefault(); - - if (this._edit.popupOpen) { - this._edit.endEditing(true); - return; - } - - // Check open popups - if (DialogUI._popup) { - DialogUI._hidePopup(); - return; - } - - // Check open panel - if (PanelUI.isVisible) { - PanelUI.hide(); - return; - } - - // Check content helper - if (FindHelperUI.isActive) { - FindHelperUI.hide(); - return; - } - - if (Browser.selectedTab.isLoading()) { - Browser.selectedBrowser.stop(); - return; - } - - if (ContextUI.dismiss()) { - return; - } - }, - - handleBackspace: function handleBackspace() { - switch (Services.prefs.getIntPref("browser.backspace_action")) { - case 0: - CommandUpdater.doCommand("cmd_back"); - break; - case 1: - CommandUpdater.doCommand("cmd_scrollPageUp"); - break; - } - }, - - handleShiftBackspace: function handleShiftBackspace() { - switch (Services.prefs.getIntPref("browser.backspace_action")) { - case 0: - CommandUpdater.doCommand("cmd_forward"); - break; - case 1: - CommandUpdater.doCommand("cmd_scrollPageDown"); - break; - } - }, - - openFile: function() { - try { - const nsIFilePicker = Ci.nsIFilePicker; - let fp = Cc["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker); - let self = this; - let fpCallback = function fpCallback_done(aResult) { - if (aResult == nsIFilePicker.returnOK) { - self.goToURI(fp.fileURL.spec); - } - }; - - let windowTitle = Strings.browser.GetStringFromName("browserForOpenLocation"); - fp.init(window, windowTitle, nsIFilePicker.modeOpen); - fp.appendFilters(nsIFilePicker.filterAll | nsIFilePicker.filterText | - nsIFilePicker.filterImages | nsIFilePicker.filterXML | - nsIFilePicker.filterHTML); - fp.open(fpCallback); - } catch (ex) { - dump ('BrowserUI openFile exception: ' + ex + '\n'); - } - }, - - savePage: function() { - Browser.savePage(); - }, - - receiveMessage: function receiveMessage(aMessage) { - let browser = aMessage.target; - let json = aMessage.json; - switch (aMessage.name) { - case "DOMTitleChanged": - this._titleChanged(browser); - break; - case "DOMWillOpenModalDialog": - this.selectTabForBrowser(browser); - break; - case "DOMWindowClose": - return this.closeTabForBrowser(browser); - break; - // XXX this and content's sender are a little warped - case "Browser:OpenURI": - let referrerURI = null; - if (json.referrer) - referrerURI = Services.io.newURI(json.referrer, null, null); - this.goToURI(json.uri); - break; - case "Content:StateChange": { - let tab = Browser.selectedTab; - if (this.shouldCaptureThumbnails(tab)) { - PageThumbs.captureAndStore(tab.browser); - let currPage = tab.browser.currentURI.spec; - Services.obs.notifyObservers(null, "Metro:RefreshTopsiteThumbnail", currPage); - } - break; - } - } - - return {}; - }, - - shouldCaptureThumbnails: function shouldCaptureThumbnails(aTab) { - // Capture only if it's the currently selected tab. - if (aTab != Browser.selectedTab) { - return false; - } - // Skip private tabs - if (aTab.isPrivate) { - return false; - } - // FIXME Bug 720575 - Don't capture thumbnails for SVG or XML documents as - // that currently regresses Talos SVG tests. - let browser = aTab.browser; - let doc = browser.contentDocument; - if (doc instanceof SVGDocument || doc instanceof XMLDocument) { - return false; - } - - // Don't capture pages in snapped mode, this produces 2/3 black - // thumbs or stretched out ones - // Ci.nsIWinMetroUtils.snapped is inaccessible on - // desktop/nonwindows systems - if(Elements.windowState.getAttribute("viewstate") == "snapped") { - return false; - } - // There's no point in taking screenshot of loading pages. - if (browser.docShell.busyFlags != Ci.nsIDocShell.BUSY_FLAGS_NONE) { - return false; - } - - // Don't take screenshots of about: pages. - if (browser.currentURI.schemeIs("about")) { - return false; - } - - // No valid document channel. We shouldn't take a screenshot. - let channel = browser.docShell.currentDocumentChannel; - if (!channel) { - return false; - } - - // Don't take screenshots of internally redirecting about: pages. - // This includes error pages. - let uri = channel.originalURI; - if (uri.schemeIs("about")) { - return false; - } - - // http checks - let httpChannel; - try { - httpChannel = channel.QueryInterface(Ci.nsIHttpChannel); - } catch (e) { /* Not an HTTP channel. */ } - - if (httpChannel) { - // Continue only if we have a 2xx status code. - try { - if (Math.floor(httpChannel.responseStatus / 100) != 2) { - return false; - } - } catch (e) { - // Can't get response information from the httpChannel - // because mResponseHead is not available. - return false; - } - - // Cache-Control: no-store. - if (httpChannel.isNoStoreResponse()) { - return false; - } - - // Don't capture HTTPS pages unless the user enabled it. - if (uri.schemeIs("https") && !this.sslDiskCacheEnabled) { - return false; - } - } - - return true; - }, - - _sslDiskCacheEnabled: null, - - get sslDiskCacheEnabled() { - if (this._sslDiskCacheEnabled === null) { - this._sslDiskCacheEnabled = Services.prefs.getBoolPref("browser.cache.disk_cache_ssl"); - } - return this._sslDiskCacheEnabled; - }, - - supportsCommand : function(cmd) { - var isSupported = false; - switch (cmd) { - case "cmd_back": - case "cmd_forward": - case "cmd_reload": - case "cmd_forceReload": - case "cmd_stop": - case "cmd_go": - case "cmd_home": - case "cmd_openLocation": - case "cmd_addBookmark": - case "cmd_bookmarks": - case "cmd_history": - case "cmd_remoteTabs": - case "cmd_quit": - case "cmd_close": - case "cmd_newTab": - case "cmd_newTabKey": - case "cmd_closeTab": - case "cmd_undoCloseTab": - case "cmd_actions": - case "cmd_panel": - case "cmd_reportingCrashesSubmitURLs": - case "cmd_flyout_back": - case "cmd_sanitize": - case "cmd_volumeLeft": - case "cmd_volumeRight": - case "cmd_openFile": - case "cmd_savePage": - isSupported = true; - break; - default: - isSupported = false; - break; - } - return isSupported; - }, - - isCommandEnabled : function(cmd) { - let elem = document.getElementById(cmd); - if (elem && elem.getAttribute("disabled") == "true") - return false; - return true; - }, - - doCommand : function(cmd) { - if (!this.isCommandEnabled(cmd)) - return; - let browser = getBrowser(); - switch (cmd) { - case "cmd_back": - browser.goBack(); - break; - case "cmd_forward": - browser.goForward(); - break; - case "cmd_reload": - browser.reload(); - break; - case "cmd_forceReload": - { - // Simulate a new page - browser.lastLocation = null; - - const reloadFlags = Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_PROXY | - Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE; - browser.reloadWithFlags(reloadFlags); - break; - } - case "cmd_stop": - browser.stop(); - break; - case "cmd_go": - this.goToURI(); - break; - case "cmd_home": - this.goToURI(Browser.getHomePage()); - break; - case "cmd_openLocation": - ContextUI.displayNavbar(); - this._edit.beginEditing(true); - this._edit.select(); - break; - case "cmd_addBookmark": - ContextUI.displayNavbar(); - Appbar.onStarButton(true); - break; - case "cmd_bookmarks": - PanelUI.show("bookmarks-container"); - break; - case "cmd_history": - PanelUI.show("history-container"); - break; - case "cmd_remoteTabs": -#ifdef MOZ_SERVICES_SYNC - if (Weave.Status.checkSetup() == Weave.CLIENT_NOT_CONFIGURED) { - FlyoutPanelsUI.show('SyncFlyoutPanel'); - } else { - PanelUI.show("remotetabs-container"); - } -#endif - break; - case "cmd_quit": - // Only close one window - this._closeOrQuit(); - break; - case "cmd_close": - this._closeOrQuit(); - break; - case "cmd_newTab": - this.addAndShowTab(); - break; - case "cmd_newTabKey": - this.addAndShowTab(); - // Make sure navbar is displayed before setting focus on url bar. Bug 907244 - ContextUI.displayNavbar(); - this._edit.beginEditing(false); - break; - case "cmd_closeTab": - this.closeTab(); - break; - case "cmd_undoCloseTab": - this.undoCloseTab(); - break; - case "cmd_sanitize": - this.confirmSanitizeDialog(); - break; - case "cmd_flyout_back": - FlyoutPanelsUI.onBackButton(); - break; - case "cmd_reportingCrashesSubmitURLs": - let urlCheckbox = document.getElementById("prefs-reporting-submitURLs"); - Services.prefs.setBoolPref('app.crashreporter.submitURLs', urlCheckbox.checked); - break; - case "cmd_panel": - PanelUI.toggle(); - break; - case "cmd_openFile": - this.openFile(); - break; - case "cmd_savePage": - this.savePage(); - break; - } - }, - - handleAppCommandEvent: function (aEvent) { - switch (aEvent.command) { - case "Back": - this.doCommand("cmd_back"); - break; - case "Forward": - this.doCommand("cmd_forward"); - break; - case "Reload": - this.doCommand("cmd_reload"); - break; - case "Stop": - this.doCommand("cmd_stop"); - break; - case "Home": - this.doCommand("cmd_home"); - break; - case "New": - this.doCommand("cmd_newTab"); - break; - case "Close": - this.doCommand("cmd_closeTab"); - break; - case "Find": - FindHelperUI.show(); - break; - case "Open": - this.doCommand("cmd_openFile"); - break; - case "Save": - this.doCommand("cmd_savePage"); - break; - case "Search": - this.doCommand("cmd_openLocation"); - break; - default: - return; - } - aEvent.stopPropagation(); - aEvent.preventDefault(); - }, - - confirmSanitizeDialog: function () { - let bundle = Services.strings.createBundle("chrome://browser/locale/browser.properties"); - let title = bundle.GetStringFromName("clearPrivateData.title2"); - let message = bundle.GetStringFromName("clearPrivateData.message3"); - let clearbutton = bundle.GetStringFromName("clearPrivateData.clearButton"); - - let prefsClearButton = document.getElementById("prefs-clear-data"); - prefsClearButton.disabled = true; - - let buttonPressed = Services.prompt.confirmEx( - null, - title, - message, - Ci.nsIPrompt.BUTTON_POS_0 * Ci.nsIPrompt.BUTTON_TITLE_IS_STRING + - Ci.nsIPrompt.BUTTON_POS_1 * Ci.nsIPrompt.BUTTON_TITLE_CANCEL, - clearbutton, - null, - null, - null, - { value: false }); - - // Clicking 'Clear' will call onSanitize(). - if (buttonPressed === 0) { - SanitizeUI.onSanitize(); - } - - prefsClearButton.disabled = false; - }, - - _initFirstRunContent: function () { - let dismissed = Services.prefs.getBoolPref("browser.firstrun-content.dismissed"); - let firstRunCount = Services.prefs.getIntPref("browser.firstrun.count"); - - if (!dismissed && firstRunCount > 0) { - document.loadOverlay("chrome://browser/content/FirstRunContentOverlay.xul", null); - } - }, - - firstRunContentDismiss: function() { - let firstRunElements = Elements.stack.querySelectorAll(".firstrun-content"); - for (let node of firstRunElements) { - node.parentNode.removeChild(node); - } - - Services.prefs.setBoolPref("browser.firstrun-content.dismissed", true); - }, -}; - -var PanelUI = { - get _panels() { return document.getElementById("panel-items"); }, - - get isVisible() { - return !Elements.panelUI.hidden; - }, - - views: { - "console-container": "ConsolePanelView", - }, - - init: function() { - // Perform core init soon - setTimeout(function () { - for each (let viewName in this.views) { - let view = window[viewName]; - if (view.init) - view.init(); - } - }.bind(this), 0); - - // Lazily run other initialization tasks when the views are shown - this._panels.addEventListener("ToolPanelShown", function(aEvent) { - let viewName = this.views[this._panels.selectedPanel.id]; - let view = window[viewName]; - if (view.show) - view.show(); - }.bind(this), true); - }, - - uninit: function() { - for each (let viewName in this.views) { - let view = window[viewName]; - if (view.uninit) - view.uninit(); - } - }, - - switchPane: function switchPane(aPanelId) { - BrowserUI.blurFocusedElement(); - - let panel = aPanelId ? document.getElementById(aPanelId) : this._panels.selectedPanel; - let oldPanel = this._panels.selectedPanel; - - if (oldPanel != panel) { - this._panels.selectedPanel = panel; - - this._fire("ToolPanelHidden", oldPanel); - } - - this._fire("ToolPanelShown", panel); - }, - - isPaneVisible: function isPaneVisible(aPanelId) { - return this.isVisible && this._panels.selectedPanel.id == aPanelId; - }, - - show: function show(aPanelId) { - Elements.panelUI.hidden = false; - Elements.contentShowing.setAttribute("disabled", "true"); - - this.switchPane(aPanelId); - }, - - hide: function hide() { - if (!this.isVisible) - return; - - Elements.panelUI.hidden = true; - Elements.contentShowing.removeAttribute("disabled"); - BrowserUI.blurFocusedElement(); - - this._fire("ToolPanelHidden", this._panels); - }, - - toggle: function toggle() { - if (this.isVisible) { - this.hide(); - } else { - this.show(); - } - }, - - _fire: function _fire(aName, anElement) { - let event = document.createEvent("Events"); - event.initEvent(aName, true, true); - anElement.dispatchEvent(event); - } -}; - -var DialogUI = { - _popup: null, - - init: function() { - window.addEventListener("mousedown", this, true); - }, - - /******************************************* - * Popups - */ - - pushPopup: function pushPopup(aPanel, aElements, aParent) { - this._hidePopup(); - this._popup = { "panel": aPanel, - "elements": (aElements instanceof Array) ? aElements : [aElements] }; - this._dispatchPopupChanged(true, aPanel); - }, - - popPopup: function popPopup(aPanel) { - if (!this._popup || aPanel != this._popup.panel) - return; - this._popup = null; - this._dispatchPopupChanged(false, aPanel); - }, - - _hidePopup: function _hidePopup() { - if (!this._popup) - return; - let panel = this._popup.panel; - if (panel.hide) - panel.hide(); - }, - - /******************************************* - * Events - */ - - handleEvent: function (aEvent) { - switch (aEvent.type) { - case "mousedown": - if (!this._isEventInsidePopup(aEvent)) - this._hidePopup(); - break; - default: - break; - } - }, - - _dispatchPopupChanged: function _dispatchPopupChanged(aVisible, aElement) { - let event = document.createEvent("UIEvents"); - event.initUIEvent("PopupChanged", true, true, window, aVisible); - aElement.dispatchEvent(event); - }, - - _isEventInsidePopup: function _isEventInsidePopup(aEvent) { - if (!this._popup) - return false; - let elements = this._popup.elements; - let targetNode = aEvent.target; - while (targetNode && elements.indexOf(targetNode) == -1) { - if (targetNode instanceof Element && targetNode.hasAttribute("for")) - targetNode = document.getElementById(targetNode.getAttribute("for")); - else - targetNode = targetNode.parentNode; - } - return targetNode ? true : false; - } -}; diff --git a/browser/metro/base/content/browser.js b/browser/metro/base/content/browser.js deleted file mode 100644 index aab0c9524b0..00000000000 --- a/browser/metro/base/content/browser.js +++ /dev/null @@ -1,1639 +0,0 @@ -// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -let Cc = Components.classes; -let Ci = Components.interfaces; -let Cu = Components.utils; -let Cr = Components.results; - -Cu.import("resource://gre/modules/PageThumbs.jsm"); - -// Page for which the start UI is shown -const kStartURI = "about:newtab"; - -// allow panning after this timeout on pages with registered touch listeners -const kTouchTimeout = 300; -const kSetInactiveStateTimeout = 100; - -const kTabThumbnailDelayCapture = 500; - -const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; - -// See grid.xml, we use this to cache style info across loads of the startui. -var _richgridTileSizes = {}; - -// Override sizeToContent in the main window. It breaks things (bug 565887) -window.sizeToContent = function() { - Cu.reportError("window.sizeToContent is not allowed in this window"); -} - -function getTabModalPromptBox(aWindow) { - let browser = Browser.getBrowserForWindow(aWindow); - return Browser.getTabModalPromptBox(browser); -} - -/* - * Returns the browser for the currently displayed tab. - */ -function getBrowser() { - return Browser.selectedBrowser; -} - -var Browser = { - _debugEvents: false, - _tabs: [], - _selectedTab: null, - _tabId: 0, - windowUtils: window.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindowUtils), - - get defaultBrowserWidth() { - return window.innerWidth; - }, - - startup: function startup() { - var self = this; - - try { - messageManager.loadFrameScript("chrome://browser/content/Util.js", true); - messageManager.loadFrameScript("chrome://browser/content/contenthandlers/Content.js", true); - messageManager.loadFrameScript("chrome://browser/content/contenthandlers/FormHelper.js", true); - messageManager.loadFrameScript("chrome://browser/content/library/SelectionPrototype.js", true); - messageManager.loadFrameScript("chrome://browser/content/contenthandlers/SelectionHandler.js", true); - messageManager.loadFrameScript("chrome://browser/content/contenthandlers/ContextMenuHandler.js", true); - messageManager.loadFrameScript("chrome://browser/content/contenthandlers/ConsoleAPIObserver.js", true); - messageManager.loadFrameScript("chrome://browser/content/contenthandlers/PluginHelper.js", true); - } catch (e) { - // XXX whatever is calling startup needs to dump errors! - dump("###########" + e + "\n"); - } - - if (!Services.metro) { - // Services.metro is only available on Windows Metro. We want to be able - // to test metro on other platforms, too, so we provide a minimal shim. - Services.metro = { - activationURI: "", - pinTileAsync: function () {}, - unpinTileAsync: function () {} - }; - } - - /* handles dispatching clicks on browser into clicks in content or zooms */ - Elements.browsers.customDragger = new Browser.MainDragger(); - - /* handles web progress management for open browsers */ - Elements.browsers.webProgress = WebProgress.init(); - - // Call InputSourceHelper first so global listeners get called before - // we start processing input in TouchModule. - InputSourceHelper.init(); - ClickEventHandler.init(); - - TouchModule.init(); - GestureModule.init(); - BrowserTouchHandler.init(); - PopupBlockerObserver.init(); - APZCObserver.init(); - - // Init the touch scrollbox - this.contentScrollbox = Elements.browsers; - this.contentScrollboxScroller = { - scrollBy: function(aDx, aDy) { - let view = getBrowser().getRootView(); - view.scrollBy(aDx, aDy); - }, - - scrollTo: function(aX, aY) { - let view = getBrowser().getRootView(); - view.scrollTo(aX, aY); - }, - - getPosition: function(aScrollX, aScrollY) { - let view = getBrowser().getRootView(); - let scroll = view.getPosition(); - aScrollX.value = scroll.x; - aScrollY.value = scroll.y; - } - }; - - ContentAreaObserver.init(); - - function fullscreenHandler() { - if (Browser.selectedBrowser.contentWindow.document.mozFullScreenElement) - Elements.stack.setAttribute("fullscreen", "true"); - else - Elements.stack.removeAttribute("fullscreen"); - } - window.addEventListener("mozfullscreenchange", fullscreenHandler, true); - - BrowserUI.init(); - - window.controllers.appendController(this); - window.controllers.appendController(BrowserUI); - - Services.obs.addObserver(SessionHistoryObserver, "browser:purge-session-history", false); - - window.QueryInterface(Ci.nsIDOMChromeWindow).browserDOMWindow = new nsBrowserAccess(); - - Elements.browsers.addEventListener("DOMUpdatePageReport", PopupBlockerObserver.onUpdatePageReport, false); - - // Make sure we're online before attempting to load - Util.forceOnline(); - - // If this is an intial window launch the commandline handler passes us the default - // page as an argument. - let commandURL = null; - try { - let argsObj = window.arguments[0].wrappedJSObject; - if (argsObj && argsObj.pageloadURL) { - // Talos tp-cmdline parameter - commandURL = argsObj.pageloadURL; - } else if (window.arguments && window.arguments[0]) { - // BrowserCLH paramerter - commandURL = window.arguments[0]; - } - } catch (ex) { - Util.dumpLn(ex); - } - - messageManager.addMessageListener("DOMLinkAdded", this); - messageManager.addMessageListener("Browser:FormSubmit", this); - messageManager.addMessageListener("Browser:CanUnload:Return", this); - messageManager.addMessageListener("scroll", this); - messageManager.addMessageListener("Browser:CertException", this); - messageManager.addMessageListener("Browser:BlockedSite", this); - - Task.spawn(function() { - // Activation URIs come from protocol activations, secondary tiles, and file activations - let activationURI = yield this.getShortcutOrURI(Services.metro.activationURI); - - let self = this; - function loadStartupURI() { - if (activationURI) { - let webNav = Ci.nsIWebNavigation; - let flags = webNav.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP | - webNav.LOAD_FLAGS_FIXUP_SCHEME_TYPOS; - self.addTab(activationURI, true, null, { flags: flags }); - } else { - let uri = commandURL || Browser.getHomePage(); - self.addTab(uri, true); - } - } - - // Should we restore the previous session (crash or some other event) - let ss = Cc["@mozilla.org/browser/sessionstore;1"] - .getService(Ci.nsISessionStore); - let shouldRestore = ss.shouldRestore(); - if (shouldRestore) { - let bringFront = false; - // First open any commandline URLs, except the homepage - if (activationURI && activationURI != kStartURI) { - this.addTab(activationURI, true, null, { flags: Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP }); - } else if (commandURL && commandURL != kStartURI) { - this.addTab(commandURL, true); - } else { - bringFront = true; - // Initial window resizes call functions that assume a tab is in the tab list - // and restored tabs are added too late. We add a dummy to to satisfy the resize - // code and then remove the dummy after the session has been restored. - let dummy = this.addTab("about:blank", true); - let dummyCleanup = { - observe: function(aSubject, aTopic, aData) { - Services.obs.removeObserver(dummyCleanup, "sessionstore-windows-restored"); - if (aData == "fail") - loadStartupURI(); - dummy.chromeTab.ignoreUndo = true; - Browser.closeTab(dummy, { forceClose: true }); - } - }; - Services.obs.addObserver(dummyCleanup, "sessionstore-windows-restored", false); - } - ss.restoreLastSession(bringFront); - } else { - loadStartupURI(); - } - - // Notify about our input type - InputSourceHelper.fireUpdate(); - - // Broadcast a UIReady message so add-ons know we are finished with startup - let event = document.createEvent("Events"); - event.initEvent("UIReady", true, false); - window.dispatchEvent(event); - }.bind(this)); - }, - - shutdown: function shutdown() { - APZCObserver.shutdown(); - BrowserUI.uninit(); - ClickEventHandler.uninit(); - ContentAreaObserver.shutdown(); - Appbar.shutdown(); - - messageManager.removeMessageListener("Browser:FormSubmit", this); - messageManager.removeMessageListener("scroll", this); - messageManager.removeMessageListener("Browser:CertException", this); - messageManager.removeMessageListener("Browser:BlockedSite", this); - - Services.obs.removeObserver(SessionHistoryObserver, "browser:purge-session-history"); - - window.controllers.removeController(this); - window.controllers.removeController(BrowserUI); - }, - - getHomePage: function getHomePage(aOptions) { - aOptions = aOptions || { useDefault: false }; - - let url = kStartURI; - try { - let prefs = aOptions.useDefault ? Services.prefs.getDefaultBranch(null) : Services.prefs; - url = prefs.getComplexValue("browser.startup.homepage", Ci.nsIPrefLocalizedString).data; - } - catch(e) { } - - return url; - }, - - get browsers() { - return this._tabs.map(function(tab) { return tab.browser; }); - }, - - /** - * Load a URI in the current tab, or a new tab if necessary. - * @param aURI String - * @param aParams Object with optional properties that will be passed to loadURIWithFlags: - * flags, referrerURI, charset, postData. - */ - loadURI: function loadURI(aURI, aParams) { - let browser = this.selectedBrowser; - - // We need to keep about: pages opening in new "local" tabs. We also want to spawn - // new "remote" tabs if opening web pages from a "local" about: page. - dump("loadURI=" + aURI + "\ncurrentURI=" + browser.currentURI.spec + "\n"); - - let params = aParams || {}; - try { - let flags = params.flags || Ci.nsIWebNavigation.LOAD_FLAGS_NONE; - let postData = ("postData" in params && params.postData) ? params.postData.value : null; - let referrerURI = "referrerURI" in params ? params.referrerURI : null; - let charset = "charset" in params ? params.charset : null; - dump("loading tab: " + aURI + "\n"); - browser.loadURIWithFlags(aURI, flags, referrerURI, charset, postData); - } catch(e) { - dump("Error: " + e + "\n"); - } - }, - - /** - * Determine if the given URL is a shortcut/keyword and, if so, expand it - * @param aURL String - * @param aPostDataRef Out param contains any required post data for a search - * @return {Promise} - * @result the expanded shortcut, or the original URL if not a shortcut - */ - getShortcutOrURI: function getShortcutOrURI(aURL, aPostDataRef) { - return Task.spawn(function() { - if (!aURL) - throw new Task.Result(aURL); - - let shortcutURL = null; - let keyword = aURL; - let param = ""; - - let offset = aURL.indexOf(" "); - if (offset > 0) { - keyword = aURL.substr(0, offset); - param = aURL.substr(offset + 1); - } - - if (!aPostDataRef) - aPostDataRef = {}; - - let engine = Services.search.getEngineByAlias(keyword); - if (engine) { - let submission = engine.getSubmission(param); - aPostDataRef.value = submission.postData; - throw new Task.Result(submission.uri.spec); - } - - try { - [shortcutURL, aPostDataRef.value] = PlacesUtils.getURLAndPostDataForKeyword(keyword); - } catch (e) {} - - if (!shortcutURL) - throw new Task.Result(aURL); - - let postData = ""; - if (aPostDataRef.value) - postData = unescape(aPostDataRef.value); - - if (/%s/i.test(shortcutURL) || /%s/i.test(postData)) { - let charset = ""; - const re = /^(.*)\&mozcharset=([a-zA-Z][_\-a-zA-Z0-9]+)\s*$/; - let matches = shortcutURL.match(re); - if (matches) - [, shortcutURL, charset] = matches; - else { - // Try to get the saved character-set. - try { - // makeURI throws if URI is invalid. - // Will return an empty string if character-set is not found. - charset = yield PlacesUtils.getCharsetForURI(Util.makeURI(shortcutURL)); - } catch (e) { dump("--- error " + e + "\n"); } - } - - let encodedParam = ""; - if (charset) - encodedParam = escape(convertFromUnicode(charset, param)); - else // Default charset is UTF-8 - encodedParam = encodeURIComponent(param); - - shortcutURL = shortcutURL.replace(/%s/g, encodedParam).replace(/%S/g, param); - - if (/%s/i.test(postData)) // POST keyword - aPostDataRef.value = getPostDataStream(postData, param, encodedParam, "application/x-www-form-urlencoded"); - } else if (param) { - // This keyword doesn't take a parameter, but one was provided. Just return - // the original URL. - aPostDataRef.value = null; - - throw new Task.Result(aURL); - } - - throw new Task.Result(shortcutURL); - }); - }, - - /** - * Return the currently active object - */ - get selectedBrowser() { - return (this._selectedTab && this._selectedTab.browser); - }, - - get tabs() { - return this._tabs; - }, - - getTabModalPromptBox: function(aBrowser) { - let browser = (aBrowser || getBrowser()); - let stack = browser.parentNode; - let self = this; - - let promptBox = { - appendPrompt : function(args, onCloseCallback) { - let newPrompt = document.createElementNS(XUL_NS, "tabmodalprompt"); - newPrompt.setAttribute("promptType", args.promptType); - stack.appendChild(newPrompt); - browser.setAttribute("tabmodalPromptShowing", true); - newPrompt.clientTop; // style flush to assure binding is attached - - let tab = self.getTabForBrowser(browser); - tab = tab.chromeTab; - - newPrompt.metroInit(args, tab, onCloseCallback); - return newPrompt; - }, - - removePrompt : function(aPrompt) { - stack.removeChild(aPrompt); - - let prompts = this.listPrompts(); - if (prompts.length) { - let prompt = prompts[prompts.length - 1]; - prompt.Dialog.setDefaultFocus(); - } else { - browser.removeAttribute("tabmodalPromptShowing"); - browser.focus(); - } - }, - - listPrompts : function(aPrompt) { - let els = stack.getElementsByTagNameNS(XUL_NS, "tabmodalprompt"); - // NodeList --> real JS array - let prompts = Array.slice(els); - return prompts; - }, - }; - - return promptBox; - }, - - getBrowserForWindowId: function getBrowserForWindowId(aWindowId) { - for (let i = 0; i < this.browsers.length; i++) { - if (this.browsers[i].contentWindowId == aWindowId) - return this.browsers[i]; - } - return null; - }, - - getBrowserForWindow: function(aWindow) { - let windowID = aWindow.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindowUtils).currentInnerWindowID; - return this.getBrowserForWindowId(windowID); - }, - - getTabForBrowser: function getTabForBrowser(aBrowser) { - let tabs = this._tabs; - for (let i = 0; i < tabs.length; i++) { - if (tabs[i].browser == aBrowser) - return tabs[i]; - } - return null; - }, - - getTabAtIndex: function getTabAtIndex(index) { - if (index >= this._tabs.length || index < 0) - return null; - return this._tabs[index]; - }, - - getTabFromChrome: function getTabFromChrome(chromeTab) { - for (var t = 0; t < this._tabs.length; t++) { - if (this._tabs[t].chromeTab == chromeTab) - return this._tabs[t]; - } - return null; - }, - - createTabId: function createTabId() { - return this._tabId++; - }, - - /** - * Create a new tab and add it to the tab list. - * - * If you are opening a new foreground tab in response to a user action, use - * BrowserUI.addAndShowTab which will also show the tab strip. - * - * @param aURI String specifying the URL to load. - * @param aBringFront Boolean (optional) Open the new tab in the foreground? - * @param aOwner Tab object (optional) The "parent" of the new tab. - * This is the tab responsible for opening the new tab. When the new tab - * is closed, we will return to a parent or "sibling" tab if possible. - * @param aParams Object (optional) with optional properties: - * index: Number specifying where in the tab list to insert the new tab. - * private: If true, the new tab should be have Private Browsing active. - * flags, postData, charset, referrerURI: See loadURIWithFlags. - */ - addTab: function browser_addTab(aURI, aBringFront, aOwner, aParams) { - let params = aParams || {}; - - if (aOwner && !('index' in params)) { - // Position the new tab to the right of its owner... - params.index = this._tabs.indexOf(aOwner) + 1; - // ...and to the right of any siblings. - while (this._tabs[params.index] && this._tabs[params.index].owner == aOwner) { - params.index++; - } - } - - let newTab = new Tab(aURI, params, aOwner); - - if (params.index >= 0) { - this._tabs.splice(params.index, 0, newTab); - } else { - this._tabs.push(newTab); - } - - if (aBringFront) - this.selectedTab = newTab; - - this._announceNewTab(newTab); - return newTab; - }, - - closeTab: function closeTab(aTab, aOptions) { - let tab = aTab instanceof XULElement ? this.getTabFromChrome(aTab) : aTab; - if (!tab) { - return; - } - - if (aOptions && "forceClose" in aOptions && aOptions.forceClose) { - this._doCloseTab(tab); - return; - } - - tab.browser.messageManager.sendAsyncMessage("Browser:CanUnload", {}); - }, - - savePage: function() { - ContentAreaUtils.saveDocument(this.selectedBrowser.contentWindow.document); - }, - - /* - * helper for addTab related methods. Fires events related to - * new tab creation. - */ - _announceNewTab: function (aTab) { - let event = document.createEvent("UIEvents"); - event.initUIEvent("TabOpen", true, false, window, 0); - aTab.chromeTab.dispatchEvent(event); - aTab.browser.messageManager.sendAsyncMessage("Browser:TabOpen"); - }, - - _doCloseTab: function _doCloseTab(aTab) { - if (this._tabs.length === 1) { - Browser.addTab(this.getHomePage()); - } - - let nextTab = this.getNextTab(aTab); - - // Tabs owned by the closed tab are now orphaned. - this._tabs.forEach(function(item, index, array) { - if (item.owner == aTab) - item.owner = null; - }); - - // tray tab - let event = document.createEvent("Events"); - event.initEvent("TabClose", true, false); - aTab.chromeTab.dispatchEvent(event); - - // tab window - event = document.createEvent("Events"); - event.initEvent("TabClose", true, false); - aTab.browser.contentWindow.dispatchEvent(event); - - aTab.browser.messageManager.sendAsyncMessage("Browser:TabClose"); - - let container = aTab.chromeTab.parentNode; - aTab.destroy(); - this._tabs.splice(this._tabs.indexOf(aTab), 1); - - this.selectedTab = nextTab; - - event = document.createEvent("Events"); - event.initEvent("TabRemove", true, false); - container.dispatchEvent(event); - }, - - getNextTab: function getNextTab(aTab) { - let tabIndex = this._tabs.indexOf(aTab); - if (tabIndex == -1) - return null; - - if (this._selectedTab == aTab || this._selectedTab.chromeTab.hasAttribute("closing")) { - let nextTabIndex = tabIndex + 1; - let nextTab = null; - - while (nextTabIndex < this._tabs.length && (!nextTab || nextTab.chromeTab.hasAttribute("closing"))) { - nextTab = this.getTabAtIndex(nextTabIndex); - nextTabIndex++; - } - - nextTabIndex = tabIndex - 1; - while (nextTabIndex >= 0 && (!nextTab || nextTab.chromeTab.hasAttribute("closing"))) { - nextTab = this.getTabAtIndex(nextTabIndex); - nextTabIndex--; - } - - if (!nextTab || nextTab.chromeTab.hasAttribute("closing")) - return null; - - // If the next tab is not a sibling, switch back to the parent. - if (aTab.owner && nextTab.owner != aTab.owner) - nextTab = aTab.owner; - - if (!nextTab) - return null; - - return nextTab; - } - - return this._selectedTab; - }, - - get selectedTab() { - return this._selectedTab; - }, - - set selectedTab(tab) { - if (tab instanceof XULElement) - tab = this.getTabFromChrome(tab); - - if (!tab) - return; - - if (this._selectedTab == tab) { - // Deck does not update its selectedIndex when children - // are removed. See bug 602708 - Elements.browsers.selectedPanel = tab.notification; - return; - } - - let isFirstTab = this._selectedTab == null; - let lastTab = this._selectedTab; - let browser = tab.browser; - - this._selectedTab = tab; - - if (lastTab) - lastTab.active = false; - - if (tab) - tab.active = true; - - BrowserUI.update(); - - if (isFirstTab) { - BrowserUI._titleChanged(browser); - } else { - // Update all of our UI to reflect the new tab's location - BrowserUI.updateURI(); - - let event = document.createEvent("Events"); - event.initEvent("TabSelect", true, false); - event.lastTab = lastTab; - tab.chromeTab.dispatchEvent(event); - } - - tab.lastSelected = Date.now(); - }, - - supportsCommand: function(cmd) { - return false; - }, - - isCommandEnabled: function(cmd) { - return false; - }, - - doCommand: function(cmd) { - }, - - getNotificationBox: function getNotificationBox(aBrowser) { - let browser = aBrowser || this.selectedBrowser; - return browser.parentNode.parentNode; - }, - - /** - * Handle cert exception message from content. - */ - _handleCertException: function _handleCertException(aMessage) { - let json = aMessage.json; - if (json.action == "leave") { - // Get the start page from the *default* pref branch, not the user's - let url = Browser.getHomePage({ useDefault: true }); - this.loadURI(url); - } else { - // Handle setting an cert exception and reloading the page - try { - // Add a new SSL exception for this URL - let uri = Services.io.newURI(json.url, null, null); - let sslExceptions = new SSLExceptions(); - - if (json.action == "permanent") - sslExceptions.addPermanentException(uri, window); - else - sslExceptions.addTemporaryException(uri, window); - } catch (e) { - dump("EXCEPTION handle content command: " + e + "\n" ); - } - - // Automatically reload after the exception was added - aMessage.target.reload(); - } - }, - - /** - * Handle blocked site message from content. - */ - _handleBlockedSite: function _handleBlockedSite(aMessage) { - let formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"].getService(Ci.nsIURLFormatter); - let json = aMessage.json; - switch (json.action) { - case "leave": { - // Get the start page from the *default* pref branch, not the user's - let url = Browser.getHomePage({ useDefault: true }); - this.loadURI(url); - break; - } - case "report-malware": { - // Get the stop badware "why is this blocked" report url, append the current url, and go there. - try { - let reportURL = formatter.formatURLPref("browser.safebrowsing.malware.reportURL"); - reportURL += json.url; - this.loadURI(reportURL); - } catch (e) { - Cu.reportError("Couldn't get malware report URL: " + e); - } - break; - } - case "report-phishing": { - // It's a phishing site, just link to the generic information page - let url = Services.urlFormatter.formatURLPref("app.support.baseURL"); - this.loadURI(url + "phishing-malware"); - break; - } - } - }, - - pinSite: function browser_pinSite() { - // Get a path to our app tile - var file = Components.classes["@mozilla.org/file/directory_service;1"]. - getService(Components.interfaces.nsIProperties). - get("CurProcD", Components.interfaces.nsIFile); - // Get rid of the current working directory's metro subidr - file = file.parent; - file.append("tileresources"); - file.append("VisualElements_logo.png"); - var ios = Components.classes["@mozilla.org/network/io-service;1"]. - getService(Components.interfaces.nsIIOService); - var uriSpec = ios.newFileURI(file).spec; - Services.metro.pinTileAsync(this._currentPageTileID, - Browser.selectedBrowser.contentTitle, // short name - Browser.selectedBrowser.contentTitle, // display name - "-url " + Browser.selectedBrowser.currentURI.spec, - uriSpec, uriSpec); - }, - - get _currentPageTileID() { - // We use a unique ID per URL, so just use an MD5 hash of the URL as the ID. - let hasher = Cc["@mozilla.org/security/hash;1"]. - createInstance(Ci.nsICryptoHash); - hasher.init(Ci.nsICryptoHash.MD5); - let stringStream = Cc["@mozilla.org/io/string-input-stream;1"]. - createInstance(Ci.nsIStringInputStream); - stringStream.data = Browser.selectedBrowser.currentURI.spec; - hasher.updateFromStream(stringStream, -1); - let hashASCII = hasher.finish(true); - // Replace '/' with a valid filesystem character - return ("FFTileID_" + hashASCII).replace(/\//g, '_'); - }, - - unpinSite: function browser_unpinSite() { - if (!Services.metro.immersive) - return; - - Services.metro.unpinTileAsync(this._currentPageTileID); - }, - - isSitePinned: function browser_isSitePinned() { - if (!Services.metro.immersive) - return false; - - return Services.metro.isTilePinned(this._currentPageTileID); - }, - - starSite: function browser_starSite(callback) { - let uri = this.selectedBrowser.currentURI; - let title = this.selectedBrowser.contentTitle; - - Bookmarks.addForURI(uri, title, callback); - }, - - unstarSite: function browser_unstarSite(callback) { - let uri = this.selectedBrowser.currentURI; - Bookmarks.removeForURI(uri, callback); - }, - - isSiteStarredAsync: function browser_isSiteStarredAsync(callback) { - let uri = this.selectedBrowser.currentURI; - Bookmarks.isURIBookmarked(uri, callback); - }, - - /** - * Convenience function for getting the scrollbox position off of a - * scrollBoxObject interface. Returns the actual values instead of the - * wrapping objects. - * - * @param scroller a scrollBoxObject on which to call scroller.getPosition() - */ - getScrollboxPosition: function getScrollboxPosition(scroller) { - let x = {}; - let y = {}; - scroller.getPosition(x, y); - return new Point(x.value, y.value); - }, - - forceChromeReflow: function forceChromeReflow() { - let dummy = getComputedStyle(document.documentElement, "").width; - }, - - receiveMessage: function receiveMessage(aMessage) { - let json = aMessage.json; - let browser = aMessage.target; - - switch (aMessage.name) { - case "DOMLinkAdded": { - // checks for an icon to use for a web app - // apple-touch-icon size is 57px and default size is 16px - let rel = json.rel.toLowerCase().split(" "); - if (rel.indexOf("icon") != -1) { - // We use the sizes attribute if available - // see http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#rel-icon - let size = 16; - if (json.sizes) { - let sizes = json.sizes.toLowerCase().split(" "); - sizes.forEach(function(item) { - if (item != "any") { - let [w, h] = item.split("x"); - size = Math.max(Math.min(w, h), size); - } - }); - } - if (size > browser.appIcon.size) { - browser.appIcon.href = json.href; - browser.appIcon.size = size; - } - } - else if ((rel.indexOf("apple-touch-icon") != -1) && (browser.appIcon.size < 57)) { - // XXX should we support apple-touch-icon-precomposed ? - // see http://developer.apple.com/safari/library/documentation/appleapplications/reference/safariwebcontent/configuringwebapplications/configuringwebapplications.html - browser.appIcon.href = json.href; - browser.appIcon.size = 57; - } - break; - } - case "Browser:FormSubmit": - browser.lastLocation = null; - break; - - case "Browser:CanUnload:Return": { - if (json.permit) { - let tab = this.getTabForBrowser(browser); - BrowserUI.animateClosingTab(tab); - } - break; - } - case "Browser:CertException": - this._handleCertException(aMessage); - break; - case "Browser:BlockedSite": - this._handleBlockedSite(aMessage); - break; - } - }, -}; - -Browser.MainDragger = function MainDragger() { - this._horizontalScrollbar = document.getElementById("horizontal-scroller"); - this._verticalScrollbar = document.getElementById("vertical-scroller"); - this._scrollScales = { x: 0, y: 0 }; - - Elements.browsers.addEventListener("PanBegin", this, false); - Elements.browsers.addEventListener("PanFinished", this, false); -}; - -Browser.MainDragger.prototype = { - isDraggable: function isDraggable(target, scroller) { - return { x: true, y: true }; - }, - - dragStart: function dragStart(clientX, clientY, target, scroller) { - let browser = getBrowser(); - let bcr = browser.getBoundingClientRect(); - this._contentView = browser.getViewAt(clientX - bcr.left, clientY - bcr.top); - }, - - dragStop: function dragStop(dx, dy, scroller) { - if (this._contentView && this._contentView._updateCacheViewport) - this._contentView._updateCacheViewport(); - this._contentView = null; - }, - - dragMove: function dragMove(dx, dy, scroller, aIsKinetic) { - let doffset = new Point(dx, dy); - - this._panContent(doffset); - - if (aIsKinetic && doffset.x != 0) - return false; - - this._updateScrollbars(); - - return !doffset.equals(dx, dy); - }, - - handleEvent: function handleEvent(aEvent) { - let browser = getBrowser(); - switch (aEvent.type) { - case "PanBegin": { - let width = ContentAreaObserver.width, height = ContentAreaObserver.height; - let contentWidth = browser.contentDocumentWidth * browser.scale; - let contentHeight = browser.contentDocumentHeight * browser.scale; - - // Allow a small margin on both sides to prevent adding scrollbars - // on small viewport approximation - const ALLOWED_MARGIN = 5; - const SCROLL_CORNER_SIZE = 8; - this._scrollScales = { - x: (width + ALLOWED_MARGIN) < contentWidth ? (width - SCROLL_CORNER_SIZE) / contentWidth : 0, - y: (height + ALLOWED_MARGIN) < contentHeight ? (height - SCROLL_CORNER_SIZE) / contentHeight : 0 - } - - this._showScrollbars(); - break; - } - case "PanFinished": - this._hideScrollbars(); - - // Update the scroll position of the content - browser._updateCSSViewport(); - break; - } - }, - - _panContent: function md_panContent(aOffset) { - if (this._contentView && !this._contentView.isRoot()) { - this._panContentView(this._contentView, aOffset); - // XXX we may need to have "escape borders" for iframe panning - // XXX does not deal with scrollables within scrollables - } - // Do content panning - this._panContentView(getBrowser().getRootView(), aOffset); - }, - - /** Pan scroller by the given amount. Updates doffset with leftovers. */ - _panContentView: function _panContentView(contentView, doffset) { - let pos0 = contentView.getPosition(); - contentView.scrollBy(doffset.x, doffset.y); - let pos1 = contentView.getPosition(); - doffset.subtract(pos1.x - pos0.x, pos1.y - pos0.y); - }, - - _updateScrollbars: function _updateScrollbars() { - let scaleX = this._scrollScales.x, scaleY = this._scrollScales.y; - let contentScroll = Browser.getScrollboxPosition(Browser.contentScrollboxScroller); - - if (scaleX) - this._horizontalScrollbar.style.MozTransform = - "translateX(" + Math.round(contentScroll.x * scaleX) + "px)"; - - if (scaleY) { - let y = Math.round(contentScroll.y * scaleY); - let x = 0; - - this._verticalScrollbar.style.MozTransform = - "translate(" + x + "px," + y + "px)"; - } - }, - - _showScrollbars: function _showScrollbars() { - this._updateScrollbars(); - let scaleX = this._scrollScales.x, scaleY = this._scrollScales.y; - if (scaleX) { - this._horizontalScrollbar.width = ContentAreaObserver.width * scaleX; - this._horizontalScrollbar.setAttribute("panning", "true"); - } - - if (scaleY) { - this._verticalScrollbar.height = ContentAreaObserver.height * scaleY; - this._verticalScrollbar.setAttribute("panning", "true"); - } - }, - - _hideScrollbars: function _hideScrollbars() { - this._scrollScales.x = 0; - this._scrollScales.y = 0; - this._horizontalScrollbar.removeAttribute("panning"); - this._verticalScrollbar.removeAttribute("panning"); - this._horizontalScrollbar.removeAttribute("width"); - this._verticalScrollbar.removeAttribute("height"); - this._horizontalScrollbar.style.MozTransform = ""; - this._verticalScrollbar.style.MozTransform = ""; - } -}; - - -function nsBrowserAccess() { } - -nsBrowserAccess.prototype = { - QueryInterface: function(aIID) { - if (aIID.equals(Ci.nsIBrowserDOMWindow) || aIID.equals(Ci.nsISupports)) - return this; - throw Cr.NS_NOINTERFACE; - }, - - _getOpenAction: function _getOpenAction(aURI, aOpener, aWhere, aContext) { - let where = aWhere; - /* - * aWhere: - * OPEN_DEFAULTWINDOW: default action - * OPEN_CURRENTWINDOW: current window/tab - * OPEN_NEWWINDOW: not allowed, converted to newtab below - * OPEN_NEWTAB: open a new tab - * OPEN_SWITCHTAB: open in an existing tab if it matches, otherwise open - * a new tab. afaict we always open these in the current tab. - */ - if (where == Ci.nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW) { - // query standard browser prefs indicating what to do for default action - switch (aContext) { - // indicates this is an open request from a 3rd party app. - case Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL : - where = Services.prefs.getIntPref("browser.link.open_external"); - break; - // internal request - default : - where = Services.prefs.getIntPref("browser.link.open_newwindow"); - } - } - if (where == Ci.nsIBrowserDOMWindow.OPEN_NEWWINDOW) { - Util.dumpLn("Invalid request - we can't open links in new windows."); - where = Ci.nsIBrowserDOMWindow.OPEN_NEWTAB; - } - return where; - }, - - _getBrowser: function _getBrowser(aURI, aOpener, aWhere, aContext) { - let isExternal = (aContext == Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL); - // We don't allow externals apps opening chrome docs - if (isExternal && aURI && aURI.schemeIs("chrome")) - return null; - - let location; - let browser; - let loadflags = isExternal ? - Ci.nsIWebNavigation.LOAD_FLAGS_FROM_EXTERNAL : - Ci.nsIWebNavigation.LOAD_FLAGS_NONE; - let openAction = this._getOpenAction(aURI, aOpener, aWhere, aContext); - - if (openAction == Ci.nsIBrowserDOMWindow.OPEN_NEWTAB) { - let owner = isExternal ? null : Browser.selectedTab; - let tab = BrowserUI.openLinkInNewTab("about:blank", true, owner); - browser = tab.browser; - } else { - browser = Browser.selectedBrowser; - } - - try { - let referrer; - if (aURI && browser) { - if (aOpener) { - location = aOpener.location; - referrer = Services.io.newURI(location, null, null); - } - browser.loadURIWithFlags(aURI.spec, loadflags, referrer, null, null); - } - browser.focus(); - } catch(e) { } - - return browser; - }, - - openURI: function browser_openURI(aURI, aOpener, aWhere, aContext) { - let browser = this._getBrowser(aURI, aOpener, aWhere, aContext); - return browser ? browser.contentWindow : null; - }, - - openURIInFrame: function browser_openURIInFrame(aURI, aParams, aWhere, aContext) { - let browser = this._getBrowser(aURI, null, aWhere, aContext); - return browser ? browser.QueryInterface(Ci.nsIFrameLoaderOwner) : null; - }, - - isTabContentWindow: function(aWindow) { - return Browser.browsers.some(function (browser) browser.contentWindow == aWindow); - }, -}; - -/** - * Handler for blocked popups, triggered by DOMUpdatePageReport events in browser.xml - */ -var PopupBlockerObserver = { - init: function init() { - Elements.browsers.addEventListener("mousedown", this, true); - }, - - handleEvent: function handleEvent(aEvent) { - switch (aEvent.type) { - case "mousedown": - let box = Browser.getNotificationBox(); - let notification = box.getNotificationWithValue("popup-blocked"); - if (notification && !notification.contains(aEvent.target)) - box.removeNotification(notification); - break; - } - }, - - onUpdatePageReport: function onUpdatePageReport(aEvent) { - var cBrowser = Browser.selectedBrowser; - if (aEvent.originalTarget != cBrowser) - return; - - if (!cBrowser.pageReport) - return; - - let result = Services.perms.testExactPermission(Browser.selectedBrowser.currentURI, "popup"); - if (result == Ci.nsIPermissionManager.DENY_ACTION) - return; - - // Only show the notification again if we've not already shown it. Since - // notifications are per-browser, we don't need to worry about re-adding - // it. - if (!cBrowser.pageReport.reported) { - if (Services.prefs.getBoolPref("privacy.popups.showBrowserMessage")) { - var brandShortName = Strings.brand.GetStringFromName("brandShortName"); - var popupCount = cBrowser.pageReport.length; - - let strings = Strings.browser; - let message = PluralForm.get(popupCount, strings.GetStringFromName("popupWarning.message")) - .replace("#1", brandShortName) - .replace("#2", popupCount); - - var notificationBox = Browser.getNotificationBox(); - var notification = notificationBox.getNotificationWithValue("popup-blocked"); - if (notification) { - notification.label = message; - } - else { - var buttons = [ - { - isDefault: false, - label: strings.GetStringFromName("popupButtonAllowOnce2"), - accessKey: "", - callback: function() { PopupBlockerObserver.showPopupsForSite(); } - }, - { - label: strings.GetStringFromName("popupButtonAlwaysAllow3"), - accessKey: "", - callback: function() { PopupBlockerObserver.allowPopupsForSite(true); } - }, - { - label: strings.GetStringFromName("popupButtonNeverWarn3"), - accessKey: "", - callback: function() { PopupBlockerObserver.allowPopupsForSite(false); } - } - ]; - - const priority = notificationBox.PRIORITY_WARNING_MEDIUM; - notificationBox.appendNotification(message, "popup-blocked", - "chrome://browser/skin/images/infobar-popup.png", - priority, buttons); - } - } - // Record the fact that we've reported this blocked popup, so we don't - // show it again. - cBrowser.pageReport.reported = true; - } - }, - - allowPopupsForSite: function allowPopupsForSite(aAllow) { - var currentURI = Browser.selectedBrowser.currentURI; - Services.perms.add(currentURI, "popup", aAllow - ? Ci.nsIPermissionManager.ALLOW_ACTION - : Ci.nsIPermissionManager.DENY_ACTION); - - Browser.getNotificationBox().removeCurrentNotification(); - }, - - showPopupsForSite: function showPopupsForSite() { - let uri = Browser.selectedBrowser.currentURI; - let pageReport = Browser.selectedBrowser.pageReport; - if (pageReport) { - for (let i = 0; i < pageReport.length; ++i) { - var popupURIspec = pageReport[i].popupWindowURI.spec; - - // Sometimes the popup URI that we get back from the pageReport - // isn't useful (for instance, netscape.com's popup URI ends up - // being "http://www.netscape.com", which isn't really the URI of - // the popup they're trying to show). This isn't going to be - // useful to the user, so we won't create a menu item for it. - if (popupURIspec == "" || !Util.isURLMemorable(popupURIspec) || popupURIspec == uri.spec) - continue; - - let popupFeatures = pageReport[i].popupWindowFeatures; - let popupName = pageReport[i].popupWindowName; - - Browser.addTab(popupURIspec, false, Browser.selectedTab); - } - } - } -}; - -var SessionHistoryObserver = { - observe: function sho_observe(aSubject, aTopic, aData) { - if (aTopic != "browser:purge-session-history") - return; - - let newTab = Browser.addTab("about:start", true); - let tab = Browser._tabs[0]; - while(tab != newTab) { - Browser.closeTab(tab, { forceClose: true } ); - tab = Browser._tabs[0]; - } - - PlacesUtils.history.removeAllPages(); - - // Clear undo history of the URL bar - BrowserUI._edit.editor.transactionManager.clear(); - } -}; - -function getNotificationBox(aBrowser) { - return Browser.getNotificationBox(aBrowser); -} - -function showDownloadManager(aWindowContext, aID, aReason) { - // TODO: Bug 883962: Toggle the downloads infobar as our current "download manager". -} - -function Tab(aURI, aParams, aOwner) { - this._id = null; - this._browser = null; - this._notification = null; - this._loading = false; - this._progressActive = false; - this._progressCount = 0; - this._chromeTab = null; - this._eventDeferred = null; - this._updateThumbnailTimeout = null; - - this._private = false; - if ("private" in aParams) { - this._private = aParams.private; - } else if (aOwner) { - this._private = aOwner._private; - } - - this.owner = aOwner || null; - - // Set to 0 since new tabs that have not been viewed yet are good tabs to - // toss if app needs more memory. - this.lastSelected = 0; - - // aParams is an object that contains some properties for the initial tab - // loading like flags, a referrerURI, a charset or even a postData. - this.create(aURI, aParams || {}, aOwner); - - // default tabs to inactive (i.e. no display port) - this.active = false; -} - -Tab.prototype = { - get browser() { - return this._browser; - }, - - get notification() { - return this._notification; - }, - - get chromeTab() { - return this._chromeTab; - }, - - get isPrivate() { - return this._private; - }, - - get pageShowPromise() { - return this._eventDeferred ? this._eventDeferred.promise : null; - }, - - startLoading: function startLoading() { - if (this._loading) { - let stack = new Error().stack; - throw "Already Loading!\n" + stack; - } - this._loading = true; - }, - - endLoading: function endLoading() { - this._loading = false; - this.updateFavicon(); - }, - - isLoading: function isLoading() { - return this._loading; - }, - - create: function create(aURI, aParams, aOwner) { - this._eventDeferred = Promise.defer(); - - this._chromeTab = Elements.tabList.addTab(aParams.index); - if (this.isPrivate) { - this._chromeTab.setAttribute("private", "true"); - } - - this._id = Browser.createTabId(); - let browser = this._createBrowser(aURI, null); - - let self = this; - function onPageShowEvent(aEvent) { - browser.removeEventListener("pageshow", onPageShowEvent); - if (self._eventDeferred) { - self._eventDeferred.resolve(self); - } - self._eventDeferred = null; - } - browser.addEventListener("pageshow", onPageShowEvent, true); - browser.addEventListener("DOMWindowCreated", this, false); - browser.addEventListener("StartUIChange", this, false); - Elements.browsers.addEventListener("SizeChanged", this, false); - - browser.messageManager.addMessageListener("Content:StateChange", this); - - if (aOwner) - this._copyHistoryFrom(aOwner); - this._loadUsingParams(browser, aURI, aParams); - }, - - updateViewport: function (aEvent) { - // is not yet supported; just use the browser size. - let browser = this.browser; - - // On the start page we add padding to keep the browser above the navbar. - let paddingBottom = parseInt(getComputedStyle(browser).paddingBottom, 10); - let height = browser.clientHeight - paddingBottom; - - browser.setWindowSize(browser.clientWidth, height); - }, - - handleEvent: function (aEvent) { - switch (aEvent.type) { - case "DOMWindowCreated": - case "StartUIChange": - this.updateViewport(); - break; - case "SizeChanged": - this.updateViewport(); - this._delayUpdateThumbnail(); - break; - case "AlertClose": { - if (this == Browser.selectedTab) { - this.updateViewport(); - } - break; - } - } - }, - - receiveMessage: function(aMessage) { - switch (aMessage.name) { - case "Content:StateChange": - // update the thumbnail now... - this.updateThumbnail(); - // ...and in a little while to capture page after load. - if (aMessage.json.stateFlags & Ci.nsIWebProgressListener.STATE_STOP) { - this._delayUpdateThumbnail(); - } - break; - } - }, - - _delayUpdateThumbnail: function() { - clearTimeout(this._updateThumbnailTimeout); - this._updateThumbnailTimeout = setTimeout(() => { - this.updateThumbnail(); - }, kTabThumbnailDelayCapture); - }, - - destroy: function destroy() { - this._browser.messageManager.removeMessageListener("Content:StateChange", this); - this._browser.removeEventListener("DOMWindowCreated", this, false); - this._browser.removeEventListener("StartUIChange", this, false); - Elements.browsers.removeEventListener("SizeChanged", this, false); - clearTimeout(this._updateThumbnailTimeout); - - Elements.tabList.removeTab(this._chromeTab); - this._chromeTab = null; - this._destroyBrowser(); - }, - - resurrect: function resurrect() { - let dead = this._browser; - let active = this.active; - - // Hold onto the session store data - let session = { data: dead.__SS_data, extra: dead.__SS_extdata }; - - // We need this data to correctly create and position the new browser - // If this browser is already a zombie, fallback to the session data - let currentURL = dead.__SS_restore ? session.data.entries[0].url : dead.currentURI.spec; - let sibling = dead.nextSibling; - - // Destory and re-create the browser - this._destroyBrowser(); - let browser = this._createBrowser(currentURL, sibling); - if (active) - this.active = true; - - // Reattach session store data and flag this browser so it is restored on select - browser.__SS_data = session.data; - browser.__SS_extdata = session.extra; - browser.__SS_restore = true; - }, - - _copyHistoryFrom: function _copyHistoryFrom(tab) { - let otherHistory = tab._browser._webNavigation.sessionHistory; - let history = this._browser._webNavigation.sessionHistory; - - // Ensure that history is initialized - history.QueryInterface(Ci.nsISHistoryInternal); - - for (let i = 0, length = otherHistory.index; i <= length; i++) - history.addEntry(otherHistory.getEntryAtIndex(i, false), true); - }, - - _loadUsingParams: function _loadUsingParams(aBrowser, aURI, aParams) { - let flags = aParams.flags || Ci.nsIWebNavigation.LOAD_FLAGS_NONE; - let postData = ("postData" in aParams && aParams.postData) ? aParams.postData.value : null; - let referrerURI = "referrerURI" in aParams ? aParams.referrerURI : null; - let charset = "charset" in aParams ? aParams.charset : null; - aBrowser.loadURIWithFlags(aURI, flags, referrerURI, charset, postData); - }, - - _createBrowser: function _createBrowser(aURI, aInsertBefore) { - if (this._browser) - throw "Browser already exists"; - - // Create a notification box around the browser. Note this includes - // the input overlay we use to shade content from input events when - // we're intercepting touch input. - let notification = this._notification = document.createElement("notificationbox"); - - let browser = this._browser = document.createElement("browser"); - browser.id = "browser-" + this._id; - this._chromeTab.linkedBrowser = browser; - - browser.setAttribute("type", "content-targetable"); - - let useRemote = Services.appinfo.browserTabsRemoteAutostart; - let useLocal = Util.isLocalScheme(aURI); - browser.setAttribute("remote", (!useLocal && useRemote) ? "true" : "false"); - - // Append the browser to the document, which should start the page load - let stack = document.createElementNS(XUL_NS, "stack"); - stack.className = "browserStack"; - stack.appendChild(browser); - stack.setAttribute("flex", "1"); - notification.appendChild(stack); - Elements.browsers.insertBefore(notification, aInsertBefore); - - notification.dir = "reverse"; - notification.addEventListener("AlertClose", this); - - // let the content area manager know about this browser. - ContentAreaObserver.onBrowserCreated(browser); - - if (this.isPrivate) { - let ctx = browser.docShell.QueryInterface(Ci.nsILoadContext); - ctx.usePrivateBrowsing = true; - } - - // stop about:blank from loading - browser.stop(); - - return browser; - }, - - _destroyBrowser: function _destroyBrowser() { - if (this._browser) { - let notification = this._notification; - notification.removeEventListener("AlertClose", this); - let browser = this._browser; - browser.active = false; - - this._notification = null; - this._browser = null; - this._loading = false; - - Elements.browsers.removeChild(notification); - } - }, - - updateThumbnail: function updateThumbnail() { - if (!this.isPrivate) { - PageThumbs.captureToCanvas(this.browser.contentWindow, this._chromeTab.thumbnailCanvas); - } - }, - - updateFavicon: function updateFavicon() { - this._chromeTab.updateFavicon(this._browser.mIconURL); - }, - - set active(aActive) { - if (!this._browser) - return; - - let notification = this._notification; - let browser = this._browser; - - if (aActive) { - notification.classList.add("active-tab-notificationbox"); - browser.setAttribute("type", "content-primary"); - Elements.browsers.selectedPanel = notification; - browser.active = true; - Elements.tabList.selectedTab = this._chromeTab; - browser.focus(); - } else { - notification.classList.remove("active-tab-notificationbox"); - browser.messageManager.sendAsyncMessage("Browser:Blur", { }); - browser.setAttribute("type", "content-targetable"); - browser.active = false; - } - }, - - get active() { - if (!this._browser) - return false; - return this._browser.getAttribute("type") == "content-primary"; - }, - - toString: function() { - return "[Tab " + (this._browser ? this._browser.currentURI.spec : "(no browser)") + "]"; - } -}; - -// Helper used to hide IPC / non-IPC differences for rendering to a canvas -function rendererFactory(aBrowser, aCanvas) { - let wrapper = {}; - - if (aBrowser.contentWindow) { - let ctx = aCanvas.getContext("2d"); - let draw = function(browser, aLeft, aTop, aWidth, aHeight, aColor, aFlags) { - ctx.drawWindow(browser.contentWindow, aLeft, aTop, aWidth, aHeight, aColor, aFlags); - let e = document.createEvent("HTMLEvents"); - e.initEvent("MozAsyncCanvasRender", true, true); - aCanvas.dispatchEvent(e); - }; - wrapper.checkBrowser = function(browser) { - return browser.contentWindow; - }; - wrapper.drawContent = function(callback) { - callback(ctx, draw); - }; - } - else { - let ctx = aCanvas.MozGetIPCContext("2d"); - let draw = function(browser, aLeft, aTop, aWidth, aHeight, aColor, aFlags) { - ctx.asyncDrawXULElement(browser, aLeft, aTop, aWidth, aHeight, aColor, aFlags); - }; - wrapper.checkBrowser = function(browser) { - return !browser.contentWindow; - }; - wrapper.drawContent = function(callback) { - callback(ctx, draw); - }; - } - - return wrapper; -}; - -// Based on ClickEventHandler from /browser/base/content/content.js -let ClickEventHandler = { - init: function () { - gEventListenerService.addSystemEventListener(Elements.browsers, "click", this, true); - }, - - uninit: function () { - gEventListenerService.removeSystemEventListener(Elements.browsers, "click", this, true); - }, - - handleEvent: function (aEvent) { - if (!aEvent.isTrusted || aEvent.defaultPrevented) { - return; - } - let [href, node] = this._hrefAndLinkNodeForClickEvent(aEvent); - if (href && (aEvent.button == 1 || aEvent.ctrlKey)) { - // Open link in a new tab for middle-click or ctrl-click - BrowserUI.openLinkInNewTab(href, aEvent.shiftKey, Browser.selectedTab); - } - }, - - /** - * Extracts linkNode and href for the current click target. - * - * @param event - * The click event. - * @return [href, linkNode]. - * - * @note linkNode will be null if the click wasn't on an anchor - * element (or XLink). - */ - _hrefAndLinkNodeForClickEvent: function(event) { - function isHTMLLink(aNode) { - return ((aNode instanceof content.HTMLAnchorElement && aNode.href) || - (aNode instanceof content.HTMLAreaElement && aNode.href) || - aNode instanceof content.HTMLLinkElement); - } - - let node = event.target; - while (node && !isHTMLLink(node)) { - node = node.parentNode; - } - - if (node) - return [node.href, node]; - - // If there is no linkNode, try simple XLink. - let href, baseURI; - node = event.target; - while (node && !href) { - if (node.nodeType == content.Node.ELEMENT_NODE) { - href = node.getAttributeNS("http://www.w3.org/1999/xlink", "href"); - if (href) - baseURI = node.ownerDocument.baseURIObject; - } - node = node.parentNode; - } - - // In case of XLink, we don't return the node we got href from since - // callers expect -like elements. - // Note: makeURI() will throw if aUri is not a valid URI. - return [href ? Services.io.newURI(href, null, baseURI).spec : null, null]; - } -}; diff --git a/browser/metro/base/content/browser.xul b/browser/metro/base/content/browser.xul deleted file mode 100644 index 7f7e5fafc52..00000000000 --- a/browser/metro/base/content/browser.xul +++ /dev/null @@ -1,1396 +0,0 @@ - - - - - - - - - - - - -%globalDTD; - -%browserDTD; - -%brandDTD; - -%prefsDTD; - -%aboutPanelDTD; - -%searchPanelDTD; -#ifdef MOZ_SERVICES_SYNC - -%syncBrandDTD; - -%syncDTD; -#endif - -%baseMenuOverlayDTD; -]> - - - - - - - - - - - - - - - -
- - - - diff --git a/browser/metro/base/content/jsshell/shell.xul b/browser/metro/base/content/jsshell/shell.xul deleted file mode 100644 index 5bb0cd2108b..00000000000 --- a/browser/metro/base/content/jsshell/shell.xul +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - diff --git a/browser/metro/base/content/library/SelectionPrototype.js b/browser/metro/base/content/library/SelectionPrototype.js deleted file mode 100644 index 4cd71546507..00000000000 --- a/browser/metro/base/content/library/SelectionPrototype.js +++ /dev/null @@ -1,1084 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -let Ci = Components.interfaces; -let Cc = Components.classes; - -/* - * SelectionPrototype - common base class used by both chrome and content selection logic. - */ - -// selection node parameters for various apis -this.kSelectionNodeAnchor = 1; -this.kSelectionNodeFocus = 2; - -// selection type property constants -this.kChromeSelector = 1; -this.kContentSelector = 2; - -dump("### SelectionPrototype.js loaded\n"); - -/* - http://mxr.mozilla.org/mozilla-central/source/docshell/base/nsIDocShell.idl - http://mxr.mozilla.org/mozilla-central/source/dom/base/nsISelectionDisplay.idl - http://mxr.mozilla.org/mozilla-central/source/dom/base/nsISelectionListener.idl - http://mxr.mozilla.org/mozilla-central/source/dom/base/nsISelectionPrivate.idl - http://mxr.mozilla.org/mozilla-central/source/dom/base/nsISelectionController.idl - http://mxr.mozilla.org/mozilla-central/source/dom/base/nsISelection.idl - http://mxr.mozilla.org/mozilla-central/source/dom/interfaces/core/nsIDOMDocument.idl#372 - rangeCount - getRangeAt - containsNode - http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html - http://mxr.mozilla.org/mozilla-central/source/dom/interfaces/range/nsIDOMRange.idl - http://mxr.mozilla.org/mozilla-central/source/dom/interfaces/core/nsIDOMDocument.idl#80 - content.document.createRange() - getBoundingClientRect - isPointInRange - http://mxr.mozilla.org/mozilla-central/source/dom/interfaces/core/nsIDOMNode.idl - http://mxr.mozilla.org/mozilla-central/source/dom/interfaces/base/nsIDOMWindowUtils.idl - setSelectionAtPoint - http://mxr.mozilla.org/mozilla-central/source/dom/interfaces/core/nsIDOMElement.idl - getClientRect - http://mxr.mozilla.org/mozilla-central/source/layout/generic/nsFrameSelection.h - http://mxr.mozilla.org/mozilla-central/source/editor/idl/nsIEditor.idl - http://mxr.mozilla.org/mozilla-central/source/dom/interfaces/base/nsIFocusManager.idl - http://mxr.mozilla.org/mozilla-central/source/toolkit/content/widgets/textbox.xml - http://mxr.mozilla.org/mozilla-central/source/dom/interfaces/xul/nsIDOMXULTextboxElement.idl - mEditor -*/ - -var SelectionPrototype = function() { } - -SelectionPrototype.prototype = { - _CARET_MODE: 1, // Single monocle mode (Collapsed caret). - _SELECTION_MODE: 2, // Double monocle mode (Selection w/Text). - - _debugEvents: false, - _cache: {}, - _targetElement: null, - _targetIsEditable: true, - _contentOffset: { x: 0, y: 0 }, - _contentWindow: null, - _debugOptions: { dumpRanges: false, displayRanges: false }, - _domWinUtils: null, - _selectionMoveActive: false, - _snap: false, - _type: 0, - - /************************************************* - * Properties - */ - - get isActive() { - return !!this._targetElement; - }, - - get targetIsEditable() { - return this._targetIsEditable || false; - }, - - /* - * snap - enable or disable word snap for the active marker when a - * SelectionMoveEnd event is received. Typically you would disable - * snap when zoom is < 1.0 for precision selection. defaults to off. - */ - get snap() { - return this._snap; - }, - - set snap(aValue) { - this._snap = aValue; - }, - - /* - * type - returns a constant indicating which module we're - * loaded into - chrome or content. - */ - set type(aValue) { - this._type = aValue; - }, - - get type() { - return this._type; - }, - - /************************************************* - * Messaging wrapper - */ - - /* - * sendAsync - * - * Wrapper over sendAsyncMessage in content, waps direct invocation on - * SelectionHelperUI in chrome. Should be overriden by objects that inherit - * our behavior. - */ - sendAsync: function sendAsync(aMsg, aJson) { - Util.dumpLn("Base sendAsync called on SelectionPrototype. This is a no-op."); - }, - - /************************************************* - * Common browser event handlers - */ - - /* - * _onCaretPositionUpdate - sets the current caret location based on - * a client coordinates. Messages back with updated monocle position - * information. - * - * @param aX, aY drag location in client coordinates. - */ - _onCaretPositionUpdate: function _onCaretPositionUpdate(aX, aY) { - this._onCaretMove(aX, aY); - - // Update the position of our selection monocles - this._updateSelectionUI("caret", false, false, true); - }, - - /* - * _onCaretMove - updates the current caret location based on a client - * coordinates. - * - * @param aX, aY drag location in client coordinates. - */ - _onCaretMove: function _onCaretMove(aX, aY) { - if (!this._targetIsEditable) { - this._onFail("Unexpected, caret position isn't supported with non-inputs."); - return; - } - - // SelectionHelperUI sends text input tap coordinates and a caret move - // event at the start of a monocle drag. caretPositionFromPoint isn't - // going to give us correct info if the coord is outside the edit bounds, - // so restrict the coordinates before we call cpfp. - let containedCoords = this._restrictCoordinateToEditBounds(aX, aY); - let cp = this._contentWindow.document.caretPositionFromPoint(containedCoords.xPos, - containedCoords.yPos); - if (cp) { - let input = cp.offsetNode; - let offset = cp.offset; - input.selectionStart = input.selectionEnd = offset; - } - }, - - /* - * Turning on or off various debug features. - */ - _onSelectionDebug: function _onSelectionDebug(aMsg) { - this._debugOptions = aMsg; - this._debugEvents = aMsg.dumpEvents; - }, - - /* - * Selection Changed notification listener. This allows us to respond to selection changes - * introduced programmatically by Gecko events, target-page support code, etc. - */ - notifySelectionChanged: function notifySelectionChanged(aDocument, aSelection, aReason) { - // Ignore user generated selectionChange notifications during monocle/marker movement. - if ((typeof SelectionHelperUI != "undefined") && SelectionHelperUI.hasActiveDrag) { - return; - } - - // Ignore selectionChange notifications, unless reason is mouseup, or unknown. - if (!(aReason & Ci.nsISelectionListener.MOUSEUP_REASON) && - (aReason != Ci.nsISelectionListener.NO_REASON)) { - return; - } - - // If in selection mode, and we have a selection, update it. - if (this._mode == this._SELECTION_MODE && !aSelection.isCollapsed) { - this._updateSelectionUI("update", true, true); - } - }, - - /************************************************* - * Selection api - */ - - /* - * _updateSelectionUI - * - * Informs SelectionHelperUI about selection marker position - * so that our selection monocles can be positioned properly. - * - * @param aSrcMsg string the message type that triggered this update. - * @param aUpdateStart bool update start marker position - * @param aUpdateEnd bool update end marker position - * @param aUpdateCaret bool update caret marker position, can be - * undefined, defaults to false. - */ - _updateSelectionUI: function _updateSelectionUI(aSrcMsg, aUpdateStart, aUpdateEnd, - aUpdateCaret) { - let selection = this._getSelection(); - - // If the range didn't have any text, let's bail - if (!selection) { - this._onFail("no selection was present"); - return; - } - - // Updates this._cache content selection position data which we send over - // to SelectionHelperUI. Note updateUIMarkerRects will fail if there isn't - // any selection in the page. This can happen when we start a monocle drag - // but haven't dragged enough to create selection. Just return. - try { - this._updateUIMarkerRects(selection); - } catch (ex) { - Util.dumpLn("_updateUIMarkerRects:", ex.message); - return; - } - - this._cache.src = aSrcMsg; - this._cache.updateStart = aUpdateStart; - this._cache.updateEnd = aUpdateEnd; - this._cache.updateCaret = aUpdateCaret || false; - this._cache.targetIsEditable = this._targetIsEditable; - - // Get monocles positioned correctly - this.sendAsync("Content:SelectionRange", this._cache); - }, - - /* - * _handleSelectionPoint(aSelectionInfo, aEndOfSelection) - * - * After a monocle moves to a new point in the document, determines - * what the target is and acts on its selection accordingly. If the - * monocle is within the bounds of the target, adds or subtracts selection - * at the monocle coordinates appropriately and then merges selection ranges - * into a single continuous selection. If the monocle is outside the bounds - * of the target and the underlying target is editable, uses the selection - * controller to advance selection and visibility within the control. - */ - _handleSelectionPoint: function _handleSelectionPoint(aSelectionInfo, - aEndOfSelection) { - let selection = this._getSelection(); - - let markerToChange = aSelectionInfo.change == "start" ? - aSelectionInfo.start : aSelectionInfo.end; - - if (selection.rangeCount == 0) { - this._onFail("selection.rangeCount == 0"); - return; - } - - // We expect continuous selection ranges. - if (selection.rangeCount > 1) { - this._setContinuousSelection(); - } - - // Adjust our y position up such that we are sending coordinates on - // the text line vs. below it where the monocle is positioned. - let halfLineHeight = this._queryHalfLineHeight(aSelectionInfo.start, - selection); - aSelectionInfo.start.yPos -= halfLineHeight; - aSelectionInfo.end.yPos -= halfLineHeight; - - let isSwapNeeded = false; - if (this._isSelectionSwapNeeded(aSelectionInfo.start, aSelectionInfo.end, - halfLineHeight)) { - [aSelectionInfo.start, aSelectionInfo.end] = - [aSelectionInfo.end, aSelectionInfo.start]; - - isSwapNeeded = true; - this.sendAsync("Content:SelectionSwap"); - } - - // Modify selection based on monocle movement - if (this._targetIsEditable && !Util.isEditableContent(this._targetElement)) { - if (isSwapNeeded) { - this._adjustEditableSelection("start", aSelectionInfo.start, - aEndOfSelection); - this._adjustEditableSelection("end", aSelectionInfo.end, - aEndOfSelection); - } else { - this._adjustEditableSelection(aSelectionInfo.change, markerToChange, - aEndOfSelection); - } - } else { - if (isSwapNeeded) { - this._adjustSelectionAtPoint("start", aSelectionInfo.start, - aEndOfSelection, true); - this._adjustSelectionAtPoint("end", aSelectionInfo.end, - aEndOfSelection, true); - } else { - this._adjustSelectionAtPoint(aSelectionInfo.change, markerToChange, - aEndOfSelection); - } - } - }, - - /** - * Checks whether we need to swap start and end markers depending the target - * element and monocle position. - * @param aStart Start monocle coordinates. - * @param aEnd End monocle coordinates - * @param aYThreshold Y-coordinate threshold used to eliminate slight - * differences in monocle vertical positions. - */ - _isSelectionSwapNeeded: function(aStart, aEnd, aYThreshold) { - let isSwapNeededByX = aStart.xPos > aEnd.xPos; - let isSwapNeededByY = aStart.yPos - aEnd.yPos > aYThreshold; - let onTheSameLine = Math.abs(aStart.yPos - aEnd.yPos) <= aYThreshold; - - if (this._targetIsEditable && - !Util.isEditableContent(this._targetElement)) { - - // If one of the markers is restricted to edit bounds, then we shouldn't - // swap it until we know its real position - if (aStart.restrictedToBounds && aEnd.restrictedToBounds) { - return false; - } - - // For multi line we should respect Y-coordinate - if (Util.isMultilineInput(this._targetElement)) { - return isSwapNeededByY || (isSwapNeededByX && onTheSameLine); - } - - return isSwapNeededByX; - } - - return isSwapNeededByY || (isSwapNeededByX && onTheSameLine); - }, - - /* - * _handleSelectionPoint helper methods - */ - - /* - * _adjustEditableSelection - * - * Based on a monocle marker and position, adds or subtracts from the - * existing selection in editable controls. Handles auto-scroll as well. - * - * @param the marker currently being manipulated - * @param aAdjustedClientPoint client point adjusted for line height. - * @param aEndOfSelection indicates if this is the end of a selection - * move, in which case we may want to snap to the end of a word or - * sentence. - */ - _adjustEditableSelection: function _adjustEditableSelection(aMarker, - aAdjustedClientPoint, - aEndOfSelection) { - // Test to see if we need to handle auto-scroll in cases where the - // monocle is outside the bounds of the control. This also handles - // adjusting selection if out-of-bounds is true. - let result = this.updateTextEditSelection(aAdjustedClientPoint); - - // If result.trigger is true, the monocle is outside the bounds of the - // control. - if (result.trigger) { - // _handleSelectionPoint is triggered by input movement, so if we've - // tested positive for out-of-bounds scrolling here, we need to set a - // recurring timer to keep the expected selection behavior going as - // long as the user keeps the monocle out of bounds. - this._setTextEditUpdateInterval(result.speed); - - // Smooth the selection - this._setContinuousSelection(); - - // Update the other monocle's position if we've dragged off to one side - this._updateSelectionUI("update", result.start, result.end); - } else { - // If we aren't out-of-bounds, clear the scroll timer if it exists. - this._clearTimers(); - - // Restrict the client point to the interior of the control. - let constrainedPoint = - this._constrainPointWithinControl(aAdjustedClientPoint); - - // Add or subtract selection - let cp = - this._contentWindow.document.caretPositionFromPoint(constrainedPoint.xPos, - constrainedPoint.yPos); - - // For textareas or if cpfp fails we fall back on the selectAtPoint - // logic (bugs 882149, 943071). - if (Util.isMultilineInput(this._targetElement) || !cp || - !this._offsetNodeIsValid(cp.offsetNode)) { - this._adjustSelectionAtPoint(aMarker, constrainedPoint, aEndOfSelection); - return; - } - - if (aMarker == "start") { - this._targetElement.selectionStart = cp.offset; - } else { - this._targetElement.selectionEnd = cp.offset; - } - } - }, - - /* - * Make sure caretPositionFromPoint gave us an offset node that equals our - * editable, or in the case of getBindingParent identifies an anonymous - * element in chrome content within our target element. (navbar) - */ - _offsetNodeIsValid: function (aNode) { - if (aNode == this._targetElement || - this._contentWindow.document.getBindingParent(aNode) == this._targetElement) { - return true; - } - return false; - }, - - /* - * _adjustSelectionAtPoint - * - * Based on a monocle marker and position, adds or subtracts from the - * existing selection at a point. - * - * Note: we are trying to move away from this api due to the overhead. - * - * @param the marker currently being manipulated - * @param aClientPoint the point designating the new start or end - * position for the selection. - * @param aEndOfSelection indicates if this is the end of a selection - * move, in which case we may want to snap to the end of a word or - * sentence. - * @param suppressSelectionUIUpdate Indicates that we don't want to update - * static monocle automatically as it's going to be be updated explicitly like - * in case with monocle swapping. - */ - _adjustSelectionAtPoint: function _adjustSelectionAtPoint(aMarker, - aClientPoint, aEndOfSelection, suppressSelectionUIUpdate) { - // Make a copy of the existing range, we may need to reset it. - this._backupRangeList(); - - // shrinkSelectionFromPoint takes sub-frame relative coordinates. - let framePoint = this._clientPointToFramePoint(aClientPoint); - - // Tests to see if the user is trying to shrink the selection, and if so - // collapses it down to the appropriate side such that our calls below - // will reset the selection to the proper range. - let shrunk = this._shrinkSelectionFromPoint(aMarker, framePoint); - - let selectResult = false; - try { - // If we're at the end of a selection (touchend) snap to the word. - let type = ((aEndOfSelection && this._snap) ? - Ci.nsIDOMWindowUtils.SELECT_WORD : - Ci.nsIDOMWindowUtils.SELECT_CHARACTER); - - // Select a character at the point. - selectResult = this._domWinUtils.selectAtPoint(framePoint.xPos, - framePoint.yPos, type); - - // selectAtPoint selects char back and forward and apparently can select - // content that is beyond selection boundaries that we had before it was - // shrunk that forces selection to always move forward or backward - // preventing monocle swapping. - if (selectResult && shrunk && this._rangeBackup) { - let selection = this._getSelection(); - - let currentSelection = this._extractUIRects( - selection.getRangeAt(selection.rangeCount - 1)).selection; - let previousSelection = this._extractUIRects( - this._rangeBackup[0]).selection; - - if (aMarker == "start" && - currentSelection.right > previousSelection.right) { - selectResult = false; - } - - if (aMarker == "end" && - currentSelection.left < previousSelection.left) { - selectResult = false; - } - } - } catch (ex) { - } - - // If selectAtPoint failed (which can happen if there's nothing to select) - // reset our range back before we shrunk it. - if (!selectResult) { - this._restoreRangeList(); - } - - this._freeRangeList(); - - // Smooth over the selection between all existing ranges. - this._setContinuousSelection(); - - // Update the other monocle's position. We do this because the dragging - // monocle may reset the static monocle to a new position if the dragging - // monocle drags ahead or behind the other. - this._updateSelectionUI("update", - aMarker == "end" && !suppressSelectionUIUpdate, - aMarker == "start" && !suppressSelectionUIUpdate); - }, - - /* - * _backupRangeList, _restoreRangeList, and _freeRangeList - * - * Utilities that manage a cloned copy of the existing selection. - */ - - _backupRangeList: function _backupRangeList() { - this._rangeBackup = new Array(); - for (let idx = 0; idx < this._getSelection().rangeCount; idx++) { - this._rangeBackup.push(this._getSelection().getRangeAt(idx).cloneRange()); - } - }, - - _restoreRangeList: function _restoreRangeList() { - if (this._rangeBackup == null) - return; - - // Remove every previously created selection range - this._getSelection().removeAllRanges(); - - for (let idx = 0; idx < this._rangeBackup.length; idx++) { - this._getSelection().addRange(this._rangeBackup[idx]); - } - this._freeRangeList(); - }, - - _freeRangeList: function _restoreRangeList() { - this._rangeBackup = null; - }, - - /* - * Constrains a selection point within a text input control bounds. - * - * @param aPoint - client coordinate point - * @param aMargin - added inner margin to respect, defaults to 0. - * @param aOffset - amount to push the resulting point inward, defaults to 0. - * @return new constrained point struct - */ - _constrainPointWithinControl: function _cpwc(aPoint, aMargin, aOffset) { - let margin = aMargin || 0; - let offset = aOffset || 0; - let bounds = this._getTargetBrowserRect(); - let point = { xPos: aPoint.xPos, yPos: aPoint.yPos }; - if (point.xPos <= (bounds.left + margin)) - point.xPos = bounds.left + offset; - if (point.xPos >= (bounds.right - margin)) - point.xPos = bounds.right - offset; - if (point.yPos <= (bounds.top + margin)) - point.yPos = bounds.top + offset; - if (point.yPos >= (bounds.bottom - margin)) - point.yPos = bounds.bottom - offset; - return point; - }, - - /* - * _pointOrientationToRect(aPoint, aRect) - * - * Returns a table representing which sides of target aPoint is offset - * from: { left: offset, top: offset, right: offset, bottom: offset } - * Works on client coordinates. - */ - _pointOrientationToRect: function _pointOrientationToRect(aPoint) { - let bounds = this._getTargetBrowserRect(); - let result = { left: 0, right: 0, top: 0, bottom: 0 }; - if (aPoint.xPos <= bounds.left) - result.left = bounds.left - aPoint.xPos; - if (aPoint.xPos >= bounds.right) - result.right = aPoint.xPos - bounds.right; - if (aPoint.yPos <= bounds.top) - result.top = bounds.top - aPoint.yPos; - if (aPoint.yPos >= bounds.bottom) - result.bottom = aPoint.yPos - bounds.bottom; - return result; - }, - - /* - * updateTextEditSelection(aPoint, aClientPoint) - * - * Checks to see if the monocle point is outside the bounds of the target - * edit. If so, use the selection controller to select and scroll the edit - * appropriately. - * - * @param aClientPoint raw pointer position - * @return { speed: 0.0 -> 1.0, - * trigger: true/false if out of bounds, - * start: true/false if updated position, - * end: true/false if updated position } - */ - updateTextEditSelection: function updateTextEditSelection(aClientPoint) { - if (aClientPoint == undefined) { - aClientPoint = this._rawSelectionPoint; - } - this._rawSelectionPoint = aClientPoint; - - let orientation = this._pointOrientationToRect(aClientPoint); - let result = { speed: 1, trigger: false, start: false, end: false }; - let ml = Util.isMultilineInput(this._targetElement); - - // This could be improved such that we only select to the beginning of - // the line when dragging left but not up. - if (orientation.left || (ml && orientation.top)) { - this._addEditSelection(kSelectionNodeAnchor); - result.speed = orientation.left + orientation.top; - result.trigger = true; - result.end = true; - } else if (orientation.right || (ml && orientation.bottom)) { - this._addEditSelection(kSelectionNodeFocus); - result.speed = orientation.right + orientation.bottom; - result.trigger = true; - result.start = true; - } - - // 'speed' is just total pixels offset, so clamp it to something - // reasonable callers can work with. - if (result.speed > 100) - result.speed = 100; - if (result.speed < 1) - result.speed = 1; - result.speed /= 100; - return result; - }, - - _setTextEditUpdateInterval: function _setTextEditUpdateInterval(aSpeedValue) { - let timeout = (75 - (aSpeedValue * 75)); - if (!this._scrollTimer) - this._scrollTimer = new Util.Timeout(); - this._scrollTimer.interval(timeout, this.scrollTimerCallback); - }, - - _clearTimers: function _clearTimers() { - if (this._scrollTimer) { - this._scrollTimer.clear(); - } - }, - - /* - * _addEditSelection - selection control call wrapper for text inputs. - * Adds selection on the anchor or focus side of selection in a text - * input. Scrolls the location into view as well. - * - * @param const selection node identifier - */ - _addEditSelection: function _addEditSelection(aLocation) { - let selCtrl = this._getSelectController(); - try { - if (aLocation == kSelectionNodeAnchor) { - let start = Math.max(this._targetElement.selectionStart - 1, 0); - this._targetElement.setSelectionRange(start, this._targetElement.selectionEnd, - "backward"); - } else { - let end = Math.min(this._targetElement.selectionEnd + 1, - this._targetElement.textLength); - this._targetElement.setSelectionRange(this._targetElement.selectionStart, - end, - "forward"); - } - selCtrl.scrollSelectionIntoView(Ci.nsISelectionController.SELECTION_NORMAL, - Ci.nsISelectionController.SELECTION_FOCUS_REGION, - Ci.nsISelectionController.SCROLL_SYNCHRONOUS); - } catch (ex) { Util.dumpLn(ex);} - }, - - _updateInputFocus: function _updateInputFocus(aMarker) { - try { - let selCtrl = this._getSelectController(); - this._targetElement.setSelectionRange(this._targetElement.selectionStart, - this._targetElement.selectionEnd, - aMarker == "start" ? - "backward" : "forward"); - selCtrl.scrollSelectionIntoView(Ci.nsISelectionController.SELECTION_NORMAL, - Ci.nsISelectionController.SELECTION_FOCUS_REGION, - Ci.nsISelectionController.SCROLL_SYNCHRONOUS); - } catch (ex) {} - }, - - /* - * _queryHalfLineHeight(aMarker, aSelection) - * - * Y offset applied to the coordinates of the selection position we send - * to dom utils. The selection marker sits below text, but we want the - * selection position to be on the text above the monocle. Since text - * height can vary across the entire selection range, we need the correct - * height based on the line the marker in question is moving on. - */ - _queryHalfLineHeight: function _queryHalfLineHeight(aMarker, aSelection) { - let rects = aSelection.getRangeAt(0).getClientRects(); - if (!rects.length) { - return 0; - } - - // We are assuming here that these rects are ordered correctly. - // From looking at the range code it appears they will be. - let height = 0; - if (aMarker == "start") { - // height of the first rect corresponding to the start marker: - height = rects[0].bottom - rects[0].top; - } else { - // height of the last rect corresponding to the end marker: - let len = rects.length - 1; - height = rects[len].bottom - rects[len].top; - } - return height / 2; - }, - - /* - * _setContinuousSelection() - * - * Smooths a selection with multiple ranges into a single - * continuous range. - */ - _setContinuousSelection: function _setContinuousSelection() { - let selection = this._getSelection(); - try { - if (selection.rangeCount > 1) { - let startRange = selection.getRangeAt(0); - if (this. _debugOptions.displayRanges) { - let clientRect = startRange.getBoundingClientRect(); - this._setDebugRect(clientRect, "red", false); - } - let newStartNode = null; - let newStartOffset = 0; - let newEndNode = null; - let newEndOffset = 0; - for (let idx = 1; idx < selection.rangeCount; idx++) { - let range = selection.getRangeAt(idx); - switch (startRange.compareBoundaryPoints(Ci.nsIDOMRange.START_TO_START, range)) { - case -1: // startRange is before - newStartNode = startRange.startContainer; - newStartOffset = startRange.startOffset; - break; - case 0: // startRange is equal - newStartNode = startRange.startContainer; - newStartOffset = startRange.startOffset; - break; - case 1: // startRange is after - newStartNode = range.startContainer; - newStartOffset = range.startOffset; - break; - } - switch (startRange.compareBoundaryPoints(Ci.nsIDOMRange.END_TO_END, range)) { - case -1: // startRange is before - newEndNode = range.endContainer; - newEndOffset = range.endOffset; - break; - case 0: // startRange is equal - newEndNode = range.endContainer; - newEndOffset = range.endOffset; - break; - case 1: // startRange is after - newEndNode = startRange.endContainer; - newEndOffset = startRange.endOffset; - break; - } - if (this. _debugOptions.displayRanges) { - let clientRect = range.getBoundingClientRect(); - this._setDebugRect(clientRect, "orange", false); - } - } - let range = content.document.createRange(); - range.setStart(newStartNode, newStartOffset); - range.setEnd(newEndNode, newEndOffset); - selection.addRange(range); - } - } catch (ex) { - Util.dumpLn("exception while modifying selection:", ex.message); - this._onFail("_handleSelectionPoint failed."); - return false; - } - return true; - }, - - /* - * _shrinkSelectionFromPoint(aMarker, aFramePoint) - * - * Tests to see if aFramePoint intersects the current selection and if so, - * collapses selection down to the opposite start or end point leaving a - * character of selection at the collapse point. - * - * @param aMarker the marker that is being relocated. ("start" or "end") - * @param aFramePoint position of the marker. - */ - _shrinkSelectionFromPoint: function _shrinkSelectionFromPoint(aMarker, aFramePoint) { - let result = false; - try { - let selection = this._getSelection(); - for (let range = 0; range < selection.rangeCount; range++) { - // relative to frame - let rects = selection.getRangeAt(range).getClientRects(); - for (let idx = 0; idx < rects.length; idx++) { - // Util.dumpLn("[" + idx + "]", aFramePoint.xPos, aFramePoint.yPos, rects[idx].left, - // rects[idx].top, rects[idx].right, rects[idx].bottom); - if (Util.pointWithinDOMRect(aFramePoint.xPos, aFramePoint.yPos, rects[idx])) { - result = true; - if (aMarker == "start") { - selection.collapseToEnd(); - } else { - selection.collapseToStart(); - } - // collapseToStart and collapseToEnd leave an empty range in the - // selection at the collapse point. Therefore we need to add some - // selection such that the selection added by selectAtPoint and - // the current empty range will get merged properly when we smooth - // the selection ranges out. - let selCtrl = this._getSelectController(); - // Expand the collapsed range such that it occupies a little space. - if (aMarker == "start") { - // State: focus = anchor (collapseToEnd does this) - selCtrl.characterMove(false, true); - // State: focus = (anchor - 1) - selection.collapseToStart(); - // State: focus = anchor and both are -1 from the original offset - selCtrl.characterMove(true, true); - // State: focus = anchor + 1, both have been moved back one char - } else { - selCtrl.characterMove(true, true); - } - break; - } - } - } - } catch (ex) { - Util.dumpLn("error shrinking selection:", ex.message); - } - return result; - }, - - /* - * _updateUIMarkerRects(aSelection) - * - * Extracts the rects of the current selection, clips them to any text - * input bounds, and stores them in the cache table we send over to - * SelectionHelperUI. - */ - _updateUIMarkerRects: function _updateUIMarkerRects(aSelection) { - this._cache = this._extractUIRects(aSelection.getRangeAt(0)); - if (this. _debugOptions.dumpRanges) { - Util.dumpLn("start:", "(" + this._cache.start.xPos + "," + - this._cache.start.yPos + ")"); - Util.dumpLn("end:", "(" + this._cache.end.xPos + "," + - this._cache.end.yPos + ")"); - Util.dumpLn("caret:", "(" + this._cache.caret.xPos + "," + - this._cache.caret.yPos + ")"); - } - this._restrictSelectionRectToEditBounds(); - }, - - /* - * _extractUIRects - Extracts selection and target element information - * used by SelectionHelperUI. Returns client relative coordinates. - * - * @return table containing various ui rects and information - */ - _extractUIRects: function _extractUIRects(aRange) { - let seldata = { - start: {}, end: {}, caret: {}, - selection: { left: 0, top: 0, right: 0, bottom: 0 }, - element: { left: 0, top: 0, right: 0, bottom: 0 } - }; - - // When in an iframe, aRange coordinates are relative to the frame origin. - let rects = aRange.getClientRects(); - - if (rects && rects.length) { - let startSet = false; - for (let idx = 0; idx < rects.length; idx++) { - if (this. _debugOptions.dumpRanges) Util.dumpDOMRect(idx, rects[idx]); - if (!startSet && !Util.isEmptyDOMRect(rects[idx])) { - seldata.start.xPos = rects[idx].left + this._contentOffset.x; - seldata.start.yPos = rects[idx].bottom + this._contentOffset.y; - seldata.caret = seldata.start; - startSet = true; - if (this. _debugOptions.dumpRanges) Util.dumpLn("start set"); - } - if (!Util.isEmptyDOMRect(rects[idx])) { - seldata.end.xPos = rects[idx].right + this._contentOffset.x; - seldata.end.yPos = rects[idx].bottom + this._contentOffset.y; - if (this. _debugOptions.dumpRanges) Util.dumpLn("end set"); - } - } - - // Store the client rect of selection - let r = aRange.getBoundingClientRect(); - seldata.selection.left = r.left + this._contentOffset.x; - seldata.selection.top = r.top + this._contentOffset.y; - seldata.selection.right = r.right + this._contentOffset.x; - seldata.selection.bottom = r.bottom + this._contentOffset.y; - } - - // Store the client rect of target element - let r = this._getTargetClientRect(); - seldata.element.left = r.left + this._contentOffset.x; - seldata.element.top = r.top + this._contentOffset.y; - seldata.element.right = r.right + this._contentOffset.x; - seldata.element.bottom = r.bottom + this._contentOffset.y; - - // If we don't have a range we can attach to let SelectionHelperUI know. - seldata.selectionRangeFound = !!rects.length; - - return seldata; - }, - - /** - * Updates point's coordinate with max\min available in accordance with the - * bounding rectangle. Returns true if point coordinates were actually updated, - * and false - otherwise. - * @param aPoint Target point which coordinates will be analyzed. - * @param aRectangle Target rectangle to bound to. - */ - _restrictPointToRectangle: function(aPoint, aRectangle) { - let restrictionWasRequired = false; - - if (aPoint.xPos < aRectangle.left) { - aPoint.xPos = aRectangle.left; - restrictionWasRequired = true; - } else if (aPoint.xPos > aRectangle.right) { - aPoint.xPos = aRectangle.right; - restrictionWasRequired = true; - } - - if (aPoint.yPos < aRectangle.top) { - aPoint.yPos = aRectangle.top; - restrictionWasRequired = true; - } else if (aPoint.yPos > aRectangle.bottom) { - aPoint.yPos = aRectangle.bottom; - restrictionWasRequired = true; - } - - return restrictionWasRequired; - }, - - /* - * Selection bounds will fall outside the bound of a control if the control - * can scroll. Clip UI cache data to the bounds of the target so monocles - * don't draw outside the control. - */ - _restrictSelectionRectToEditBounds: function _restrictSelectionRectToEditBounds() { - if (!this._targetIsEditable) - return; - - let targetRectangle = this._getTargetBrowserRect(); - this._cache.start.restrictedToBounds = this._restrictPointToRectangle( - this._cache.start, targetRectangle); - this._cache.end.restrictedToBounds = this._restrictPointToRectangle( - this._cache.end, targetRectangle); - this._restrictPointToRectangle(this._cache.caret, targetRectangle); - }, - - _restrictCoordinateToEditBounds: function _restrictCoordinateToEditBounds(aX, aY) { - let result = { - xPos: aX, - yPos: aY - }; - if (!this._targetIsEditable) - return result; - let bounds = this._getTargetBrowserRect(); - if (aX <= bounds.left) - result.xPos = bounds.left + 1; - if (aX >= bounds.right) - result.xPos = bounds.right - 1; - if (aY <= bounds.top) - result.yPos = bounds.top + 1; - if (aY >= bounds.bottom) - result.yPos = bounds.bottom - 1; - return result; - }, - - /************************************************* - * Utilities - */ - - /* - * Returns bounds of the element relative to the inner sub frame it sits - * in. - */ - _getTargetClientRect: function _getTargetClientRect() { - return this._targetElement.getBoundingClientRect(); - }, - - /* - * Returns bounds of the element relative to the top level browser. - */ - _getTargetBrowserRect: function _getTargetBrowserRect() { - let client = this._getTargetClientRect(); - return { - left: client.left + this._contentOffset.x, - top: client.top + this._contentOffset.y, - right: client.right + this._contentOffset.x, - bottom: client.bottom + this._contentOffset.y - }; - }, - - _clientPointToFramePoint: function _clientPointToFramePoint(aClientPoint) { - let point = { - xPos: aClientPoint.xPos - this._contentOffset.x, - yPos: aClientPoint.yPos - this._contentOffset.y - }; - return point; - }, - - /************************************************* - * Debug routines - */ - - _debugDumpSelection: function _debugDumpSelection(aNote, aSel) { - Util.dumpLn("--" + aNote + "--"); - Util.dumpLn("anchor:", aSel.anchorNode, aSel.anchorOffset); - Util.dumpLn("focus:", aSel.focusNode, aSel.focusOffset); - }, - - _debugDumpChildNodes: function _dumpChildNodes(aNode, aSpacing) { - for (let idx = 0; idx < aNode.childNodes.length; idx++) { - let node = aNode.childNodes.item(idx); - for (let spaceIdx = 0; spaceIdx < aSpacing; spaceIdx++) dump(" "); - Util.dumpLn("[" + idx + "]", node); - this._debugDumpChildNodes(node, aSpacing + 1); - } - }, - - _setDebugElementRect: function _setDebugElementRect(e, aScrollOffset, aColor) { - try { - if (e == null) { - Util.dumpLn("_setDebugElementRect(): passed in null element"); - return; - } - if (e.offsetWidth == 0 || e.offsetHeight== 0) { - Util.dumpLn("_setDebugElementRect(): passed in flat rect"); - return; - } - // e.offset values are positioned relative to the view. - this.sendAsync("Content:SelectionDebugRect", - { left:e.offsetLeft - aScrollOffset.x, - top:e.offsetTop - aScrollOffset.y, - right:e.offsetLeft + e.offsetWidth - aScrollOffset.x, - bottom:e.offsetTop + e.offsetHeight - aScrollOffset.y, - color:aColor, id: e.id }); - } catch(ex) { - Util.dumpLn("_setDebugElementRect():", ex.message); - } - }, - - /* - * Adds a debug rect to the selection overlay, useful in identifying - * locations for points and rects. Params are in client coordinates. - * - * Example: - * let rect = { left: aPoint.xPos - 1, top: aPoint.yPos - 1, - * right: aPoint.xPos + 1, bottom: aPoint.yPos + 1 }; - * this._setDebugRect(rect, "red"); - * - * In SelectionHelperUI, you'll need to turn on displayDebugLayer - * in init(). - */ - _setDebugRect: function _setDebugRect(aRect, aColor, aFill, aId) { - this.sendAsync("Content:SelectionDebugRect", - { left:aRect.left, top:aRect.top, - right:aRect.right, bottom:aRect.bottom, - color:aColor, fill: aFill, id: aId }); - }, - - /* - * Adds a small debug rect at the point specified. Params are in - * client coordinates. - * - * In SelectionHelperUI, you'll need to turn on displayDebugLayer - * in init(). - */ - _setDebugPoint: function _setDebugPoint(aX, aY, aColor) { - let rect = { left: aX - 2, top: aY - 2, - right: aX + 2, bottom: aY + 2 }; - this._setDebugRect(rect, aColor, true); - }, -}; -this.SelectionPrototype = SelectionPrototype; diff --git a/browser/metro/base/content/pages/aboutAddons.xhtml b/browser/metro/base/content/pages/aboutAddons.xhtml deleted file mode 100644 index 1fa4b7c2cbf..00000000000 --- a/browser/metro/base/content/pages/aboutAddons.xhtml +++ /dev/null @@ -1,36 +0,0 @@ - - - %htmlDTD; - - %brandDTD; - - %aboutAddonsDTD; -]> - - - - - - &aboutAddons.title; - - - - -
-
-
- &aboutAddons.messageTitle; -
-
- &aboutAddons.message; - &aboutAddons.goBackToStartStart; - &aboutAddons.goBacktoStartLink; - &aboutAddons.goBacktoStartEnd; -
-
-
- - diff --git a/browser/metro/base/content/pages/aboutCertError.xhtml b/browser/metro/base/content/pages/aboutCertError.xhtml deleted file mode 100644 index d425fffb0eb..00000000000 --- a/browser/metro/base/content/pages/aboutCertError.xhtml +++ /dev/null @@ -1,244 +0,0 @@ - - - - %htmlDTD; - - %globalDTD; - - %certerrorDTD; -]> - - - - - &certerror.pagetitle; - - - - - - - - - -
- - -
- - -
- -

&certerror.longpagetitle;

-
- - -
-
-

&certerror.introPara1;

-
- -
-

&certerror.whatShouldIDo.heading;

-
-

&certerror.whatShouldIDo.content;

- -
-
- - -
-

&certerror.technical.heading;

-

-

- -
-

&certerror.expert.heading;

-
-

&certerror.expert.content;

-

&certerror.expert.contentPara2;

- - -
-
-
- -
- - - - - diff --git a/browser/metro/base/content/pages/aboutRights.xhtml b/browser/metro/base/content/pages/aboutRights.xhtml deleted file mode 100644 index df29ae7ea60..00000000000 --- a/browser/metro/base/content/pages/aboutRights.xhtml +++ /dev/null @@ -1,97 +0,0 @@ - - - %htmlDTD; - - %brandDTD; - - %aboutRightsDTD; -]> - - - - - - &rights.pagetitle; - - - - - -

&rights.intro-header;

- -

&rights.intro;

- - - - - - - - - diff --git a/browser/metro/base/content/pages/blockedSite.xhtml b/browser/metro/base/content/pages/blockedSite.xhtml deleted file mode 100644 index 6745ab59b32..00000000000 --- a/browser/metro/base/content/pages/blockedSite.xhtml +++ /dev/null @@ -1,194 +0,0 @@ - - - - %htmlDTD; - - %globalDTD; - - %brandDTD; - - %blockedSiteDTD; -]> - - - - - - - - - - - - - - -
- -
- - -
- -

&safeb.blocked.phishingPage.title2;

-

&safeb.blocked.malwarePage.title;

-
-
- - -
-

&safeb.blocked.phishingPage.shortDesc2;

-

&safeb.blocked.malwarePage.shortDesc;

-
- - -
-

&safeb.blocked.phishingPage.longDesc2;

-

&safeb.blocked.malwarePage.longDesc;

-
-
- -
- - - - diff --git a/browser/metro/base/content/pages/config.js b/browser/metro/base/content/pages/config.js deleted file mode 100644 index 66b232583db..00000000000 --- a/browser/metro/base/content/pages/config.js +++ /dev/null @@ -1,632 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -const {classes: Cc, interfaces: Ci, manager: Cm, utils: Cu} = Components; -Cu.import("resource://gre/modules/Services.jsm"); - -const INITIAL_PAGE_DELAY = 500; // Initial pause on program start for scroll alignment -const PREFS_BUFFER_MAX = 100; // Max prefs buffer size for getPrefsBuffer() -const PAGE_SCROLL_TRIGGER = 200; // Triggers additional getPrefsBuffer() on user scroll-to-bottom -const FILTER_CHANGE_TRIGGER = 200; // Delay between responses to filterInput changes -const INNERHTML_VALUE_DELAY = 100; // Delay before providing prefs innerHTML value - -let gStringBundle = Services.strings.createBundle("chrome://browser/locale/config.properties"); -let gClipboardHelper = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper); - - -/* ============================== NewPrefDialog ============================== - * - * New Preference Dialog Object and methods - * - * Implements User Interfaces for creation of a single(new) Preference setting - * - */ -var NewPrefDialog = { - - _prefsShield: null, - - _newPrefsDialog: null, - _newPrefItem: null, - _prefNameInputElt: null, - _prefTypeSelectElt: null, - - _booleanValue: null, - _booleanToggle: null, - _stringValue: null, - _intValue: null, - - _positiveButton: null, - - get type() { - return this._prefTypeSelectElt.value; - }, - - set type(aType) { - this._prefTypeSelectElt.value = aType; - switch(this._prefTypeSelectElt.value) { - case "boolean": - this._prefTypeSelectElt.selectedIndex = 0; - break; - case "string": - this._prefTypeSelectElt.selectedIndex = 1; - break; - case "int": - this._prefTypeSelectElt.selectedIndex = 2; - break; - } - - this._newPrefItem.setAttribute("typestyle", aType); - }, - - // Init the NewPrefDialog - init: function AC_init() { - this._prefsShield = document.getElementById("prefs-shield"); - - this._newPrefsDialog = document.getElementById("new-pref-container"); - this._newPrefItem = document.getElementById("new-pref-item"); - this._prefNameInputElt = document.getElementById("new-pref-name"); - this._prefTypeSelectElt = document.getElementById("new-pref-type"); - - this._booleanValue = document.getElementById("new-pref-value-boolean"); - this._stringValue = document.getElementById("new-pref-value-string"); - this._intValue = document.getElementById("new-pref-value-int"); - - this._positiveButton = document.getElementById("positive-button"); - }, - - // Called to update positive button to display text ("Create"/"Change), and enabled/disabled status - // As new pref name is initially displayed, re-focused, or modifed during user input - _updatePositiveButton: function AC_updatePositiveButton(aPrefName) { - this._positiveButton.textContent = gStringBundle.GetStringFromName("newPref.createButton"); - this._positiveButton.setAttribute("disabled", true); - if (aPrefName == "") { - return; - } - - // If item already in list, it's being changed, else added - let item = document.querySelector(".pref-item[name=\"" + CSS.escape(aPrefName) + "\"]"); - if (item) { - this._positiveButton.textContent = gStringBundle.GetStringFromName("newPref.changeButton"); - } else { - this._positiveButton.removeAttribute("disabled"); - } - }, - - // When we want to cancel/hide an existing, or show a new pref dialog - toggleShowHide: function AC_toggleShowHide() { - if (this._newPrefsDialog.classList.contains("show")) { - this.hide(); - } else { - this._show(); - } - }, - - // When we want to show the new pref dialog / shield the prefs list - _show: function AC_show() { - this._newPrefsDialog.classList.add("show"); - this._prefsShield.setAttribute("shown", true); - - // Initial default field values - this._prefNameInputElt.value = ""; - this._updatePositiveButton(this._prefNameInputElt.value); - - this.type = "boolean"; - this._booleanValue.value = "false"; - this._stringValue.value = ""; - this._intValue.value = ""; - - this._prefNameInputElt.focus(); - - window.addEventListener("keypress", this.handleKeypress, false); - }, - - // When we want to cancel/hide the new pref dialog / un-shield the prefs list - hide: function AC_hide() { - this._newPrefsDialog.classList.remove("show"); - this._prefsShield.removeAttribute("shown"); - - window.removeEventListener("keypress", this.handleKeypress, false); - }, - - // Watch user key input so we can provide Enter key action, commit input values - handleKeypress: function AC_handleKeypress(aEvent) { - // Close our VKB on new pref enter key press - if (aEvent.keyCode == KeyEvent.DOM_VK_RETURN) - aEvent.target.blur(); - }, - - // New prefs create dialog only allows creating a non-existing preference, doesn't allow for - // Changing an existing one on-the-fly, tap existing/displayed line item pref for that - create: function AC_create(aEvent) { - if (this._positiveButton.getAttribute("disabled") == "true") { - return; - } - - switch(this.type) { - case "boolean": - Services.prefs.setBoolPref(this._prefNameInputElt.value, (this._booleanValue.value == "true") ? true : false); - break; - case "string": - Services.prefs.setCharPref(this._prefNameInputElt.value, this._stringValue.value); - break; - case "int": - Services.prefs.setIntPref(this._prefNameInputElt.value, this._intValue.value); - break; - } - - this.hide(); - }, - - // Display proper positive button text/state on new prefs name input focus - focusName: function AC_focusName(aEvent) { - this._updatePositiveButton(aEvent.target.value); - }, - - // Display proper positive button text/state as user changes new prefs name - updateName: function AC_updateName(aEvent) { - this._updatePositiveButton(aEvent.target.value); - }, - - // In new prefs dialog, bool prefs are , as they aren't yet tied to an - // Actual Services.prefs.*etBoolPref() - toggleBoolValue: function AC_toggleBoolValue() { - this._booleanValue.value = (this._booleanValue.value == "true" ? "false" : "true"); - } -} - - -/* ============================== AboutConfig ============================== - * - * Main AboutConfig object and methods - * - * Implements User Interfaces for maintenance of a list of Preference settings - * - */ -var AboutConfig = { - - filterInput: null, - _filterPrevInput: null, - _filterChangeTimer: null, - _prefsContainer: null, - _loadingContainer: null, - _list: null, - - // Init the main AboutConfig dialog - init: function AC_init() { - this.filterInput = document.getElementById("filter-input"); - this._prefsContainer = document.getElementById("prefs-container"); - this._loadingContainer = document.getElementById("loading-container"); - - let list = Services.prefs.getChildList(""); - this._list = list.sort().map( function AC_getMapPref(aPref) { - return new Pref(aPref); - }, this); - - // Display the current prefs list (retains searchFilter value) - this.bufferFilterInput(); - - // Setup the prefs observers - Services.prefs.addObserver("", this, false); - }, - - // Uninit the main AboutConfig dialog - uninit: function AC_uninit() { - // Remove the prefs observer - Services.prefs.removeObserver("", this); - }, - - // Clear the filterInput value, to display the entire list - clearFilterInput: function AC_clearFilterInput() { - this.filterInput.value = ""; - this.bufferFilterInput(); - }, - - // Buffer down rapid changes in filterInput value from keyboard - bufferFilterInput: function AC_bufferFilterInput() { - if (this._filterChangeTimer) { - clearTimeout(this._filterChangeTimer); - } - - this._filterChangeTimer = setTimeout((function() { - this._filterChangeTimer = null; - // Display updated prefs list when filterInput value settles - this._displayNewList(); - }).bind(this), FILTER_CHANGE_TRIGGER); - }, - - // Update displayed list when filterInput value changes - _displayNewList: function AC_displayNewList() { - // This survives the search filter value past a page refresh - this.filterInput.setAttribute("value", this.filterInput.value); - - // Don't start new filter search if same as last - if (this.filterInput.value == this._filterPrevInput) { - return; - } - this._filterPrevInput = this.filterInput.value; - - // Clear list item selection and prefs list, get first buffer, set scrolling on - this.selected = ""; - this._clearPrefsContainer(); - this._addMorePrefsToContainer(); - window.onscroll = this.onScroll.bind(this); - - // Pause for screen to settle, then ensure at top - setTimeout((function() { - window.scrollTo(0, 0); - }).bind(this), INITIAL_PAGE_DELAY); - }, - - // Clear the displayed preferences list - _clearPrefsContainer: function AC_clearPrefsContainer() { - // Quick clear the prefsContainer list - let empty = this._prefsContainer.cloneNode(false); - this._prefsContainer.parentNode.replaceChild(empty, this._prefsContainer); - this._prefsContainer = empty; - - // Quick clear the prefs li.HTML list - this._list.forEach(function(item) { - delete item.li; - }); - }, - - // Get a small manageable block of prefs items, and add them to the displayed list - _addMorePrefsToContainer: function AC_addMorePrefsToContainer() { - // Create filter regex - let filterExp = this.filterInput.value ? - new RegExp(this.filterInput.value, "i") : null; - - // Get a new block for the display list - let prefsBuffer = []; - for (let i = 0; i < this._list.length && prefsBuffer.length < PREFS_BUFFER_MAX; i++) { - if (!this._list[i].li && this._list[i].test(filterExp)) { - prefsBuffer.push(this._list[i]); - } - } - - // Add the new block to the displayed list - for (let i = 0; i < prefsBuffer.length; i++) { - this._prefsContainer.appendChild(prefsBuffer[i].getOrCreateNewLINode()); - } - - // Determine if anything left to add later by scrolling - let anotherPrefsBufferRemains = false; - for (let i = 0; i < this._list.length; i++) { - if (!this._list[i].li && this._list[i].test(filterExp)) { - anotherPrefsBufferRemains = true; - break; - } - } - - if (anotherPrefsBufferRemains) { - // If still more could be displayed, show the throbber - this._loadingContainer.style.display = "block"; - } else { - // If no more could be displayed, hide the throbber, and stop noticing scroll events - this._loadingContainer.style.display = "none"; - window.onscroll = null; - } - }, - - // If scrolling at the bottom, maybe add some more entries - onScroll: function AC_onScroll(aEvent) { - if (this._prefsContainer.scrollHeight - (window.pageYOffset + window.innerHeight) < PAGE_SCROLL_TRIGGER) { - if (!this._filterChangeTimer) { - this._addMorePrefsToContainer(); - } - } - }, - - // Return currently selected list item node - get selected() { - return document.querySelector(".pref-item.selected"); - }, - - // Set list item node as selected - set selected(aSelection) { - let currentSelection = this.selected; - if (aSelection == currentSelection) { - return; - } - - // Clear any previous selection - if (currentSelection) { - currentSelection.classList.remove("selected"); - currentSelection.removeEventListener("keypress", this.handleKeypress, false); - } - - // Set any current selection - if (aSelection) { - aSelection.classList.add("selected"); - aSelection.addEventListener("keypress", this.handleKeypress, false); - } - }, - - // Watch user key input so we can provide Enter key action, commit input values - handleKeypress: function AC_handleKeypress(aEvent) { - if (aEvent.keyCode == KeyEvent.DOM_VK_RETURN) - aEvent.target.blur(); - }, - - // Return the target list item node of an action event - getLINodeForEvent: function AC_getLINodeForEvent(aEvent) { - let node = aEvent.target; - while (node && node.nodeName != "li") { - node = node.parentNode; - } - - return node; - }, - - // Return a pref of a list item node - _getPrefForNode: function AC_getPrefForNode(aNode) { - let pref = aNode.getAttribute("name"); - - return new Pref(pref); - }, - - // When list item name or value are tapped - selectOrToggleBoolPref: function AC_selectOrToggleBoolPref(aEvent) { - let node = this.getLINodeForEvent(aEvent); - - // If not already selected, just do so - if (this.selected != node) { - this.selected = node; - return; - } - - // If already selected, and value is boolean, toggle it - let pref = this._getPrefForNode(node); - if (pref.type != Services.prefs.PREF_BOOL) { - return; - } - - this.toggleBoolPref(aEvent); - }, - - // When finalizing list input values due to blur - setIntOrStringPref: function AC_setIntOrStringPref(aEvent) { - let node = this.getLINodeForEvent(aEvent); - - // Skip if locked - let pref = this._getPrefForNode(node); - if (pref.locked) { - return; - } - - // Boolean inputs blur to remove focus from "button" - if (pref.type == Services.prefs.PREF_BOOL) { - return; - } - - // String and Int inputs change / commit on blur - pref.value = aEvent.target.value; - }, - - // When we reset a pref to it's default value (note resetting a user created pref will delete it) - resetDefaultPref: function AC_resetDefaultPref(aEvent) { - let node = this.getLINodeForEvent(aEvent); - - // If not already selected, do so - if (this.selected != node) { - this.selected = node; - } - - // Reset will handle any locked condition - let pref = this._getPrefForNode(node); - pref.reset(); - }, - - // When we want to toggle a bool pref - toggleBoolPref: function AC_toggleBoolPref(aEvent) { - let node = this.getLINodeForEvent(aEvent); - - // Skip if locked, or not boolean - let pref = this._getPrefForNode(node); - if (pref.locked) { - return; - } - - // Toggle, and blur to remove field focus - pref.value = !pref.value; - aEvent.target.blur(); - }, - - // When Int inputs have their Up or Down arrows toggled - incrOrDecrIntPref: function AC_incrOrDecrIntPref(aEvent, aInt) { - let node = this.getLINodeForEvent(aEvent); - - // Skip if locked - let pref = this._getPrefForNode(node); - if (pref.locked) { - return; - } - - pref.value += aInt; - }, - - // Observe preference changes - observe: function AC_observe(aSubject, aTopic, aPrefName) { - let pref = new Pref(aPrefName); - - // Ignore uninteresting changes, and avoid "private" preferences - if (aTopic != "nsPref:changed") { - return; - } - - // If pref type invalid, refresh display as user reset/removed an item from the list - if (pref.type == Services.prefs.PREF_INVALID) { - document.location.reload(); - return; - } - - // If pref not already in list, refresh display as it's being added - let item = document.querySelector(".pref-item[name=\"" + CSS.escape(pref.name) + "\"]"); - if (!item) { - document.location.reload(); - return; - } - - // Else we're modifying a pref - item.setAttribute("value", pref.value); - let input = item.querySelector("input"); - input.setAttribute("value", pref.value); - input.value = pref.value; - - pref.default ? - item.querySelector(".reset").setAttribute("disabled", "true") : - item.querySelector(".reset").removeAttribute("disabled"); - } -} - - -/* ============================== Pref ============================== - * - * Individual Preference object / methods - * - * Defines a Pref object, a document list item tied to Preferences Services - * And the methods by which they interact. - * - */ -function Pref(aName) { - this.name = aName; -} - -Pref.prototype = { - get type() { - return Services.prefs.getPrefType(this.name); - }, - - get value() { - switch (this.type) { - case Services.prefs.PREF_BOOL: - return Services.prefs.getBoolPref(this.name); - case Services.prefs.PREF_INT: - return Services.prefs.getIntPref(this.name); - case Services.prefs.PREF_STRING: - default: - return Services.prefs.getCharPref(this.name); - } - - }, - - set value(aPrefValue) { - switch (this.type) { - case Services.prefs.PREF_BOOL: - Services.prefs.setBoolPref(this.name, aPrefValue); - break; - case Services.prefs.PREF_INT: - Services.prefs.setIntPref(this.name, aPrefValue); - break; - case Services.prefs.PREF_STRING: - default: - Services.prefs.setCharPref(this.name, aPrefValue); - } - }, - - get default() { - return !Services.prefs.prefHasUserValue(this.name); - }, - - get locked() { - return Services.prefs.prefIsLocked(this.name); - }, - - reset: function AC_reset() { - Services.prefs.clearUserPref(this.name); - }, - - test: function AC_test(aValue) { - return aValue ? aValue.test(this.name) : true; - }, - - // Get existing or create new LI node for the pref - getOrCreateNewLINode: function AC_getOrCreateNewLINode() { - if (!this.li) { - this.li = document.createElement("li"); - - this.li.className = "pref-item"; - this.li.setAttribute("name", this.name); - - // Click callback to ensure list item selected even on no-action tap events - this.li.addEventListener("click", - function(aEvent) { - AboutConfig.selected = AboutConfig.getLINodeForEvent(aEvent); - }, - false - ); - - // Create list item outline, bind to object actions - this.li.innerHTML = - "
" + - this.name + - "
" + - "
" + - "" + - "" + - "
" + - gStringBundle.GetStringFromName("pref.resetButton") + - "
" + - "
" + - gStringBundle.GetStringFromName("pref.toggleButton") + - "
" + - "
" + - "
" + - "
" + - "
" + - "
"; - - // Delay providing the list item values, until the LI is returned and added to the document - setTimeout(this._valueSetup.bind(this), INNERHTML_VALUE_DELAY); - } - - return this.li; - }, - - // Initialize list item object values - _valueSetup: function AC_valueSetup() { - - this.li.setAttribute("type", this.type); - this.li.setAttribute("value", this.value); - - let valDiv = this.li.querySelector(".pref-value"); - valDiv.value = this.value; - - switch(this.type) { - case Services.prefs.PREF_BOOL: - valDiv.setAttribute("type", "button"); - this.li.querySelector(".up").setAttribute("disabled", true); - this.li.querySelector(".down").setAttribute("disabled", true); - break; - case Services.prefs.PREF_STRING: - valDiv.setAttribute("type", "text"); - this.li.querySelector(".up").setAttribute("disabled", true); - this.li.querySelector(".down").setAttribute("disabled", true); - this.li.querySelector(".toggle").setAttribute("disabled", true); - break; - case Services.prefs.PREF_INT: - valDiv.setAttribute("type", "number"); - this.li.querySelector(".toggle").setAttribute("disabled", true); - break; - } - - this.li.setAttribute("default", this.default); - if (this.default) { - this.li.querySelector(".reset").setAttribute("disabled", true); - } - - if (this.locked) { - valDiv.setAttribute("disabled", this.locked); - this.li.querySelector(".pref-name").setAttribute("locked", true); - } - } -} diff --git a/browser/metro/base/content/pages/config.xhtml b/browser/metro/base/content/pages/config.xhtml deleted file mode 100644 index 4c7bcab3fd1..00000000000 --- a/browser/metro/base/content/pages/config.xhtml +++ /dev/null @@ -1,81 +0,0 @@ - - - - - -%globalDTD; - -%configDTD; -]> - - - - - - - - - - - - -
-

&crashprompt.title;

-
-

&crashprompt.message;

-

- - - - - -

- -