Index: Source/modules/screen_orientation/ScreenOrientation.cpp |
diff --git a/Source/modules/screen_orientation/ScreenOrientation.cpp b/Source/modules/screen_orientation/ScreenOrientation.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..7cb981aaf34670e8a07165a7a2a63ca11e8e523d |
--- /dev/null |
+++ b/Source/modules/screen_orientation/ScreenOrientation.cpp |
@@ -0,0 +1,218 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "config.h" |
+#include "ScreenOrientation.h" |
+ |
+#include "core/frame/Frame.h" |
+#include "core/frame/Screen.h" |
+#include "core/page/ChromeClient.h" |
+#include "modules/screen_orientation/ScreenOrientationClient.h" |
+#include "modules/screen_orientation/ScreenOrientationController.h" |
+ |
+namespace WebCore { |
+ |
+ScreenOrientation::ScreenOrientation(Screen* screen) |
+ : DOMWindowProperty(screen->frame()) |
+ , PageLifecycleObserver(page()) |
+ , ActiveDOMObject(frame() ? frame()->document() : 0) |
abarth-chromium
2014/02/15 18:44:27
What are the consequences of passing 0 to ActiveDO
|
+ , m_screen(screen) |
+ , m_orientationLockTimer(this, &ScreenOrientation::orientationLockTimerFired) |
+ , m_lockedOrientations(OrientationAny) |
+{ |
+ ScreenOrientationController* controller = ScreenOrientationController::from(page()); |
+ if (controller) |
+ controller->addObserver(this); |
+} |
+ |
+ScreenOrientation::~ScreenOrientation() |
+{ |
+} |
+ |
+const char* ScreenOrientation::supplementName() |
+{ |
+ return "ScreenOrientation"; |
+} |
+ |
+void ScreenOrientation::orientationLockTimerFired(Timer<ScreenOrientation>*) |
+{ |
+ ScreenOrientationClient* client = ScreenOrientationController::clientFrom(page()); |
+ if (!client) |
+ return; |
+ |
+ client->lockOrientation(m_lockedOrientations); |
+} |
+ |
+void ScreenOrientation::didCommitLoad(Frame*) |
+{ |
+ // New page loaded, unlock screen orientation. |
+ unlockOrientation(); |
+} |
abarth-chromium
2014/02/15 18:44:27
Is this object a Frame-lifetime object or a Docume
|
+ |
+void ScreenOrientation::willDestroyGlobalObjectInFrame() |
+{ |
+ m_screen = 0; |
+ DOMWindowProperty::willDestroyGlobalObjectInFrame(); |
+} |
+ |
+void ScreenOrientation::willDetachGlobalObjectFromFrame() |
+{ |
+ m_screen = 0; |
+ DOMWindowProperty::willDetachGlobalObjectFromFrame(); |
+} |
abarth-chromium
2014/02/15 18:44:27
These don't make much sense. We're a supplement o
|
+ |
+void ScreenOrientation::stop() |
+{ |
+ ScreenOrientationController* controller = ScreenOrientationController::from(page()); |
+ if (controller) |
+ controller->removeObserver(this); |
abarth-chromium
2014/02/15 18:44:27
What are the consequences of |controller| being ze
|
+} |
+ |
+Page* ScreenOrientation::page() const |
+{ |
+ return frame() ? frame()->page() : 0; |
+} |
+ |
+ScreenOrientation* ScreenOrientation::from(Screen* screen) |
+{ |
+ ScreenOrientation* supplement = static_cast<ScreenOrientation*>(Supplement<Screen>::from(screen, supplementName())); |
+ if (!supplement) { |
+ ASSERT(screen); |
+ supplement = new ScreenOrientation(screen); |
+ supplement->suspendIfNeeded(); |
+ provideTo(screen, supplementName(), adoptPtr(supplement)); |
+ } |
+ return supplement; |
+} |
+ |
+struct ScreenOrientationInfo { |
+ const AtomicString& name; |
+ ScreenOrientationValues orientation; |
+}; |
+ |
+static ScreenOrientationInfo* allowedOrientationsMap(unsigned& length) |
+{ |
+ DEFINE_STATIC_LOCAL(const AtomicString, portrait, ("portrait", AtomicString::ConstructFromLiteral)); |
+ DEFINE_STATIC_LOCAL(const AtomicString, portraitPrimary, ("portrait-primary", AtomicString::ConstructFromLiteral)); |
+ DEFINE_STATIC_LOCAL(const AtomicString, portraitSecondary, ("portrait-secondary", AtomicString::ConstructFromLiteral)); |
+ DEFINE_STATIC_LOCAL(const AtomicString, landscape, ("landscape", AtomicString::ConstructFromLiteral)); |
+ DEFINE_STATIC_LOCAL(const AtomicString, landscapePrimary, ("landscape-primary", AtomicString::ConstructFromLiteral)); |
+ DEFINE_STATIC_LOCAL(const AtomicString, landscapeSecondary, ("landscape-secondary", AtomicString::ConstructFromLiteral)); |
+ |
+ static ScreenOrientationInfo orientationMap[] = { |
+ { portrait, OrientationPortrait }, |
+ { portraitPrimary, OrientationPortraitPrimary }, |
+ { portraitSecondary, OrientationPortraitSecondary }, |
+ { landscape, OrientationLandscape }, |
+ { landscapePrimary, OrientationLandscapePrimary }, |
+ { landscapeSecondary, OrientationLandscapeSecondary } |
+ }; |
+ length = WTF_ARRAY_LENGTH(orientationMap); |
+ return orientationMap; |
+} |
+ |
+const AtomicString& ScreenOrientation::orientationToString(ScreenOrientationValue orientation) |
+{ |
+ unsigned length = 0; |
+ ScreenOrientationInfo* orientationMap = allowedOrientationsMap(length); |
+ for (unsigned i = 0; i < length; ++i) { |
+ if (orientationMap[i].orientation == orientation) |
+ return orientationMap[i].name; |
+ } |
+ // We do no handle OrientationInvalid and OrientationAny but this is fine because screen.orientation |
+ // should never return these and WebScreenOrientation does not define those values. |
+ ASSERT_NOT_REACHED(); |
+ return nullAtom; |
+} |
+ |
+ScreenOrientationValues ScreenOrientation::stringToOrientationValues(const AtomicString& orientation) |
+{ |
+ unsigned length = 0; |
+ ScreenOrientationInfo* orientationMap = allowedOrientationsMap(length); |
+ for (unsigned i = 0; i < length; ++i) { |
+ if (orientationMap[i].name == orientation) |
+ return orientationMap[i].orientation; |
+ } |
+ return OrientationInvalid; |
+} |
+ |
+const AtomicString& ScreenOrientation::orientation(Screen* screen) |
+{ |
+ ScreenOrientation* screenOrientation = ScreenOrientation::from(screen); |
+ ASSERT(screenOrientation); |
+ |
+ ScreenOrientationController* controller = ScreenOrientationController::from(screenOrientation->page()); |
+ if (!controller) |
+ return orientationToString(OrientationPortraitPrimary); |
+ |
+ return orientationToString(controller->orientation()); |
+} |
+ |
+bool ScreenOrientation::lockOrientation(Screen* screen, const Vector<String>& orientationsVector) |
+{ |
+ ScreenOrientationValues orientations = OrientationInvalid; |
+ |
+ for (unsigned i = 0; i < orientationsVector.size(); ++i) { |
+ ScreenOrientationValues inputOrientation = stringToOrientationValues(AtomicString(orientationsVector[i])); |
+ if (inputOrientation == OrientationInvalid) |
+ return false; |
+ orientations |= inputOrientation; |
+ } |
+ |
+ if (!orientations) |
+ return false; |
+ |
+ ScreenOrientation* screenOrientation = ScreenOrientation::from(screen); |
+ ASSERT(screenOrientation); |
+ screenOrientation->lockOrientationAsync(orientations); |
+ return true; |
+} |
+ |
+bool ScreenOrientation::lockOrientation(Screen* screen, const AtomicString& orientationString) |
+{ |
+ ScreenOrientationValues orientation = stringToOrientationValues(orientationString); |
+ if (!orientation) |
+ return false; |
+ |
+ ScreenOrientation* screenOrientation = ScreenOrientation::from(screen); |
+ ASSERT(screenOrientation); |
+ screenOrientation->lockOrientationAsync(orientation); |
+ return true; |
+} |
+ |
+void ScreenOrientation::lockOrientationAsync(ScreenOrientationValues orientations) |
+{ |
+ ASSERT(!(orientations & OrientationInvalid)); |
+ |
+ m_lockedOrientations = orientations; |
+ if (!m_orientationLockTimer.isActive()) |
+ m_orientationLockTimer.startOneShot(0); |
+} |
+ |
+void ScreenOrientation::unlockOrientation(Screen* screen) |
+{ |
+ ScreenOrientation* screenOrientation = ScreenOrientation::from(screen); |
+ ASSERT(screenOrientation); |
+ screenOrientation->unlockOrientation(); |
+} |
+ |
+void ScreenOrientation::unlockOrientation() |
+{ |
+ if (m_lockedOrientations == OrientationAny) |
+ return; // Not currently locked. |
+ |
+ m_lockedOrientations = OrientationAny; |
+ |
+ ScreenOrientationClient* client = ScreenOrientationController::clientFrom(page()); |
+ if (client) |
+ client->unlockOrientation(); |
+} |
+ |
+void ScreenOrientation::orientationChanged() |
+{ |
+ if (m_screen) |
+ m_screen->dispatchEvent(Event::create(EventTypeNames::orientationchange)); |
+} |
+ |
+} // namespace WebCore |