Chromium Code Reviews| 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..28a48e045876db01994bf97703c6aa1b4bc405f8 |
| --- /dev/null |
| +++ b/Source/core/dom/CompositorProxy.cpp |
| @@ -0,0 +1,143 @@ |
| +// 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/DOMNodeIds.h" |
| +#include "core/dom/ExecutionContext.h" |
| + |
| +namespace blink { |
| + |
| +struct AttributeFlagMapping { |
| + const char* name; |
| + unsigned length; |
| + CompositorProxy::Attributes attribute; |
| +}; |
| + |
| +static AttributeFlagMapping allowedAttributes[] = { |
| + { "opacity", 7, CompositorProxy::Attributes::OPACITY }, |
| + { "scrollleft", 10, CompositorProxy::Attributes::SCROLL_LEFT }, |
| + { "scrolltop", 9, CompositorProxy::Attributes::SCROLL_TOP }, |
| + { "touch", 5, CompositorProxy::Attributes::TOUCH }, |
| + { "transform", 8, CompositorProxy::Attributes::TRANSFORM }, |
| +}; |
| + |
| +static bool CompareAttributeName(const AttributeFlagMapping& attribute, StringImpl* attributeLower) |
| +{ |
| + ASSERT(attributeLower->is8Bit()); |
| + return memcmp(attribute.name, attributeLower->characters8(), std::min(attribute.length, attributeLower->length())) < 0; |
| +} |
| + |
| +static CompositorProxy::Attributes attributeFlagForName(const String& attributeName) |
| +{ |
| + CompositorProxy::Attributes attributeFlag = CompositorProxy::Attributes::NONE; |
| + const String attributeLower = attributeName.lower(); |
| + const AttributeFlagMapping* start = allowedAttributes; |
| + const AttributeFlagMapping* end = allowedAttributes + WTF_ARRAY_LENGTH(allowedAttributes); |
| + if (attributeLower.impl()->is8Bit()) { |
| + const AttributeFlagMapping* match = std::lower_bound(start, end, attributeLower.impl(), CompareAttributeName); |
| + if (match != end) |
| + attributeFlag = match->attribute; |
| + } |
| + return attributeFlag; |
| +} |
| + |
| +static CompositorProxy::AttributesBitfield attributesBitfieldFromNames(const Vector<String>& attributeArray) |
| +{ |
| + CompositorProxy::AttributesBitfield attributesBitfield(0); |
| + for (const auto& attribute : attributeArray) { |
| + switch (attributeFlagForName(attribute)) { |
| + case CompositorProxy::Attributes::OPACITY: |
| + attributesBitfield.m_attributes.m_opacity = true; |
|
esprehn
2015/03/27 23:48:42
Hmm this is a bit worse I guess since you need all
sadrul
2015/03/28 02:12:39
Done.
|
| + break; |
| + case CompositorProxy::Attributes::SCROLL_LEFT: |
| + attributesBitfield.m_attributes.m_scrollLeft = true; |
| + break; |
| + case CompositorProxy::Attributes::SCROLL_TOP: |
| + attributesBitfield.m_attributes.m_scrollTop = true; |
| + break; |
| + case CompositorProxy::Attributes::TOUCH: |
| + attributesBitfield.m_attributes.m_touch = true; |
| + break; |
| + case CompositorProxy::Attributes::TRANSFORM: |
| + attributesBitfield.m_attributes.m_transform = true; |
| + break; |
| + case CompositorProxy::Attributes::NONE: |
| + break; |
| + } |
| + } |
| + return attributesBitfield; |
| +} |
| + |
| +#if ENABLE(ASSERT) |
| +static bool sanityCheckAttributeFlags(uint32_t attributeFlags) |
| +{ |
| + uint32_t sanityCheckAttributes = attributeFlags; |
| + for (unsigned i = 0; i < arraysize(allowedAttributes); ++i) { |
| + sanityCheckAttributes &= ~static_cast<uint32_t>(allowedAttributes[i].attribute); |
| + } |
| + return !sanityCheckAttributes; |
| +} |
| +#endif |
| + |
| +CompositorProxy* CompositorProxy::create(ExecutionContext* context, Element* element, const 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; |
| + } |
| + |
| + return new CompositorProxy(*element, attributeArray); |
| +} |
| + |
| +CompositorProxy* CompositorProxy::create(uint64_t elementId, uint32_t attributeFlags) |
| +{ |
| + return new CompositorProxy(elementId, attributeFlags); |
| +} |
| + |
| +CompositorProxy::CompositorProxy(Element& element, const Vector<String>& attributeArray) |
| + : m_elementId(DOMNodeIds::idForNode(&element)) |
| + , m_bitfieldsSupported(attributesBitfieldFromNames(attributeArray)) |
| +{ |
| + ASSERT(isMainThread()); |
| + ASSERT(m_bitfieldsSupported.m_flags); |
| + ASSERT(sanityCheckAttributeFlags(m_bitfieldsSupported.m_flags)); |
| +} |
| + |
| +CompositorProxy::CompositorProxy(uint64_t elementId, uint32_t attributeFlags) |
| + : m_elementId(elementId) |
| + , m_bitfieldsSupported(attributeFlags) |
| +{ |
| + ASSERT(!isMainThread()); |
| + ASSERT(sanityCheckAttributeFlags(m_bitfieldsSupported.m_flags)); |
| +} |
| + |
| +CompositorProxy::~CompositorProxy() |
| +{ |
| +} |
| + |
| +bool CompositorProxy::supports(const String& attributeName) const |
| +{ |
| + switch (attributeFlagForName(attributeName)) { |
| + case CompositorProxy::Attributes::OPACITY: |
| + return m_bitfieldsSupported.m_attributes.m_opacity; |
| + case CompositorProxy::Attributes::SCROLL_LEFT: |
| + return m_bitfieldsSupported.m_attributes.m_scrollLeft; |
| + case CompositorProxy::Attributes::SCROLL_TOP: |
| + return m_bitfieldsSupported.m_attributes.m_scrollTop; |
| + case CompositorProxy::Attributes::TOUCH: |
| + return m_bitfieldsSupported.m_attributes.m_touch; |
| + case CompositorProxy::Attributes::TRANSFORM: |
| + return m_bitfieldsSupported.m_attributes.m_transform; |
| + case CompositorProxy::Attributes::NONE: |
| + break; |
| + } |
| + return false; |
| +} |
| + |
| +} // namespace blink |