Index: Source/core/dom/CompositorProxy.cpp |
diff --git a/Source/core/dom/CompositorProxy.cpp b/Source/core/dom/CompositorProxy.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..088ee933df679f4246e048335c280b1375a8c8f8 |
--- /dev/null |
+++ b/Source/core/dom/CompositorProxy.cpp |
@@ -0,0 +1,120 @@ |
+// Copyright 2015 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 "core/dom/CompositorProxy.h" |
+ |
+#include "bindings/core/v8/ExceptionMessages.h" |
+#include "bindings/core/v8/ExceptionState.h" |
+#include "core/dom/ExecutionContext.h" |
+ |
+namespace blink { |
+ |
+typedef WTF::HashMap<uint64_t, Element*> ElementMap; |
+static ElementMap* gElementMap = 0; |
+ |
+typedef WTF::HashMap<Element*, uint64_t> ElementIdMap; |
+static ElementIdMap* gElementIdMap = 0; |
+ |
+static uint64_t nextCompositorProxyId() |
+{ |
+ static uint64_t s_nextId = 0; |
+ return ++s_nextId; |
+} |
+ |
+static uint64_t compositorProxyIdForElement(Element* element) |
+{ |
+ ASSERT(gElementIdMap); |
+ if (!gElementIdMap->contains(element)) |
+ gElementIdMap->add(element, nextCompositorProxyId()); |
+ return gElementIdMap->get(element); |
+} |
+ |
+static struct { |
+ const char* name; |
+ CompositorProxy::Attributes attribute; |
+} allowedAttributes[] = { |
+ { "opacity", CompositorProxy::Attributes::OPACITY }, |
+ { "scrolltop", CompositorProxy::Attributes::SCROLL_TOP }, |
+ { "touch", CompositorProxy::Attributes::TOUCH }, |
+ { "transform", CompositorProxy::Attributes::TRANSFORM }, |
+}; |
+ |
+CompositorProxy* CompositorProxy::create(ExecutionContext* context, Element* element, Vector<String>& attributeArray, ExceptionState& exceptionState) |
+{ |
+ if (!context->isDocument()) { |
+ exceptionState.throwTypeError(ExceptionMessages::failedToConstruct("CompositorProxy", "Can only be created from the main context.")); |
+ exceptionState.throwIfNeeded(); |
+ return nullptr; |
+ } |
+ |
+ uint32_t attributeFlags = 0; |
+ for (const auto& attribute : attributeArray) { |
+ Attributes currentAttribute = Attributes::NONE; |
+ for (unsigned i = 0; i < arraysize(allowedAttributes); ++i) { |
+ if (attribute.lower() == allowedAttributes[i].name) { |
+ currentAttribute = allowedAttributes[i].attribute; |
+ } |
+ } |
+ if (currentAttribute == Attributes::NONE) { |
+ exceptionState.throwTypeError("Unknown attribute'" + attribute + "'"); |
+ exceptionState.throwIfNeeded(); |
+ return nullptr; |
+ } |
+ attributeFlags |= static_cast<uint32_t>(currentAttribute); |
+ } |
+ |
+ ASSERT(attributeFlags); |
+ if (!gElementMap) { |
+ ASSERT(!gElementIdMap); |
+ gElementMap = new ElementMap; |
+ gElementIdMap = new ElementIdMap; |
+ } else { |
+ ASSERT(gElementIdMap); |
+ } |
+ return new CompositorProxy(element, attributeFlags); |
+} |
+ |
+CompositorProxy* CompositorProxy::create(uint64_t elementId, uint32_t attributeFlags) |
+{ |
+ ASSERT(!isMainThread()); |
+#ifndef NDEBUG |
+ uint32_t sanityCheckAttributes = attributeFlags; |
+ for (unsigned i = 0; i < arraysize(allowedAttributes); ++i) { |
+ sanityCheckAttributes &= ~static_cast<uint32_t>(allowedAttributes[i].attribute); |
+ } |
+ ASSERT(!sanityCheckAttributes); |
+#endif |
+ return new CompositorProxy(elementId, attributeFlags); |
+} |
+ |
+CompositorProxy::CompositorProxy(Element* element, uint32_t attributeFlags) |
+ : m_elementId(compositorProxyIdForElement(element)) |
+ , m_attributes(attributeFlags) |
+{ |
+ ASSERT(isMainThread()); |
+ ASSERT(gElementMap); |
+ gElementMap->add(m_elementId, element); |
+} |
+ |
+CompositorProxy::CompositorProxy(uint64_t elementId, uint32_t attributeFlags) |
+ : m_elementId(elementId) |
+ , m_attributes(attributeFlags) |
+{ |
+} |
+ |
+CompositorProxy::~CompositorProxy() |
+{ |
+} |
+ |
+void CompositorProxy::notifyElementGone(Element* element) |
+{ |
+ ASSERT(isMainThread()); |
+ if (!gElementMap) |
+ return; |
+ |
+ gElementMap->remove(gElementIdMap->take(element)); |
+} |
+ |
+} // namespace blink |