| // 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 "modules/screen_orientation/ScreenOrientation.h" |
| |
| #include "bindings/core/v8/ScriptPromise.h" |
| #include "bindings/core/v8/ScriptPromiseResolver.h" |
| #include "core/dom/DOMException.h" |
| #include "core/dom/Document.h" |
| #include "core/dom/ExceptionCode.h" |
| #include "core/frame/LocalFrame.h" |
| #include "modules/EventTargetModules.h" |
| #include "modules/screen_orientation/LockOrientationCallback.h" |
| #include "modules/screen_orientation/ScreenOrientationController.h" |
| #include "public/platform/WebScreenOrientationType.h" |
| |
| // This code assumes that WebScreenOrientationType values are included in WebScreenOrientationLockType. |
| #define COMPILE_ASSERT_MATCHING_ENUM(enum1, enum2) \ |
| COMPILE_ASSERT(static_cast<unsigned>(blink::enum1) == static_cast<unsigned>(blink::enum2), mismatching_types) |
| COMPILE_ASSERT_MATCHING_ENUM(WebScreenOrientationPortraitPrimary, WebScreenOrientationLockPortraitPrimary); |
| COMPILE_ASSERT_MATCHING_ENUM(WebScreenOrientationPortraitSecondary, WebScreenOrientationLockPortraitSecondary); |
| COMPILE_ASSERT_MATCHING_ENUM(WebScreenOrientationLandscapePrimary, WebScreenOrientationLockLandscapePrimary); |
| COMPILE_ASSERT_MATCHING_ENUM(WebScreenOrientationLandscapeSecondary, WebScreenOrientationLockLandscapeSecondary); |
| |
| namespace blink { |
| |
| struct ScreenOrientationInfo { |
| const AtomicString& name; |
| unsigned orientation; |
| }; |
| |
| static ScreenOrientationInfo* orientationsMap(unsigned& length) |
| { |
| 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, landscapePrimary, ("landscape-primary", AtomicString::ConstructFromLiteral)); |
| DEFINE_STATIC_LOCAL(const AtomicString, landscapeSecondary, ("landscape-secondary", AtomicString::ConstructFromLiteral)); |
| DEFINE_STATIC_LOCAL(const AtomicString, any, ("any", AtomicString::ConstructFromLiteral)); |
| DEFINE_STATIC_LOCAL(const AtomicString, portrait, ("portrait", AtomicString::ConstructFromLiteral)); |
| DEFINE_STATIC_LOCAL(const AtomicString, landscape, ("landscape", AtomicString::ConstructFromLiteral)); |
| DEFINE_STATIC_LOCAL(const AtomicString, natural, ("natural", AtomicString::ConstructFromLiteral)); |
| |
| static ScreenOrientationInfo orientationMap[] = { |
| { portraitPrimary, WebScreenOrientationLockPortraitPrimary }, |
| { portraitSecondary, WebScreenOrientationLockPortraitSecondary }, |
| { landscapePrimary, WebScreenOrientationLockLandscapePrimary }, |
| { landscapeSecondary, WebScreenOrientationLockLandscapeSecondary }, |
| { any, WebScreenOrientationLockAny }, |
| { portrait, WebScreenOrientationLockPortrait }, |
| { landscape, WebScreenOrientationLockLandscape }, |
| { natural, WebScreenOrientationLockNatural } |
| }; |
| length = WTF_ARRAY_LENGTH(orientationMap); |
| |
| return orientationMap; |
| } |
| |
| const AtomicString& ScreenOrientation::orientationTypeToString(WebScreenOrientationType orientation) |
| { |
| unsigned length = 0; |
| ScreenOrientationInfo* orientationMap = orientationsMap(length); |
| for (unsigned i = 0; i < length; ++i) { |
| if (static_cast<unsigned>(orientation) == orientationMap[i].orientation) |
| return orientationMap[i].name; |
| } |
| |
| ASSERT_NOT_REACHED(); |
| return nullAtom; |
| } |
| |
| static WebScreenOrientationLockType stringToOrientationLock(const AtomicString& orientationLockString) |
| { |
| unsigned length = 0; |
| ScreenOrientationInfo* orientationMap = orientationsMap(length); |
| for (unsigned i = 0; i < length; ++i) { |
| if (orientationMap[i].name == orientationLockString) |
| return static_cast<WebScreenOrientationLockType>(orientationMap[i].orientation); |
| } |
| |
| ASSERT_NOT_REACHED(); |
| return WebScreenOrientationLockDefault; |
| } |
| |
| // static |
| ScreenOrientation* ScreenOrientation::create(LocalFrame* frame) |
| { |
| ASSERT(frame); |
| |
| ScreenOrientation* orientation = adoptRefCountedGarbageCollectedWillBeNoop(new ScreenOrientation(frame)); |
| ASSERT(orientation->controller()); |
| // FIXME: ideally, we would like to provide the ScreenOrientationController |
| // the case where it is not defined but for the moment, it is eagerly |
| // created when the LocalFrame is created so we shouldn't be in that |
| // situtaion. |
| // In order to create the ScreenOrientationController lazily, we would need |
| // to be able to access WebFrameClient from modules/. |
| |
| orientation->controller()->setOrientation(orientation); |
| return orientation; |
| } |
| |
| ScreenOrientation::ScreenOrientation(LocalFrame* frame) |
| : DOMWindowProperty(frame) |
| , m_type(WebScreenOrientationUndefined) |
| , m_angle(0) |
| { |
| ScriptWrappable::init(this); |
| } |
| |
| ScreenOrientation::~ScreenOrientation() |
| { |
| } |
| |
| const WTF::AtomicString& ScreenOrientation::interfaceName() const |
| { |
| return EventTargetNames::ScreenOrientation; |
| } |
| |
| ExecutionContext* ScreenOrientation::executionContext() const |
| { |
| if (!m_frame) |
| return 0; |
| return m_frame->document(); |
| } |
| |
| String ScreenOrientation::type() const |
| { |
| return orientationTypeToString(m_type); |
| } |
| |
| unsigned short ScreenOrientation::angle() const |
| { |
| return m_angle; |
| } |
| |
| void ScreenOrientation::setType(WebScreenOrientationType type) |
| { |
| m_type = type; |
| } |
| |
| void ScreenOrientation::setAngle(unsigned short angle) |
| { |
| m_angle = angle; |
| } |
| |
| ScriptPromise ScreenOrientation::lock(ScriptState* state, const AtomicString& lockString) |
| { |
| RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(state); |
| ScriptPromise promise = resolver->promise(); |
| |
| Document* document = m_frame ? m_frame->document() : 0; |
| |
| if (!document || !controller()) { |
| RefPtrWillBeRawPtr<DOMException> exception = DOMException::create(InvalidStateError, "The object is no longer associated to a document."); |
| resolver->reject(exception); |
| return promise; |
| } |
| |
| if (document->isSandboxed(SandboxOrientationLock)) { |
| RefPtrWillBeRawPtr<DOMException> exception = DOMException::create(SecurityError, "The document is sandboxed and lacks the 'allow-orientation-lock' flag."); |
| resolver->reject(exception); |
| return promise; |
| } |
| |
| controller()->lock(stringToOrientationLock(lockString), new LockOrientationCallback(resolver)); |
| return promise; |
| } |
| |
| void ScreenOrientation::unlock() |
| { |
| if (!controller()) |
| return; |
| |
| controller()->unlock(); |
| } |
| |
| ScreenOrientationController* ScreenOrientation::controller() |
| { |
| if (!m_frame) |
| return 0; |
| |
| return ScreenOrientationController::from(*m_frame); |
| } |
| |
| void ScreenOrientation::trace(Visitor* visitor) |
| { |
| EventTargetWithInlineData::trace(visitor); |
| } |
| |
| } // namespace blink |