| Index: Source/core/dom/Element.cpp
|
| diff --git a/Source/core/dom/Element.cpp b/Source/core/dom/Element.cpp
|
| index e5d02e214565b7a4ee7a6111baaf595f74fcb4f6..c66987018fc3df02e2433e6d3177bf2c31d91ffa 100644
|
| --- a/Source/core/dom/Element.cpp
|
| +++ b/Source/core/dom/Element.cpp
|
| @@ -109,8 +109,11 @@
|
| #include "core/svg/SVGElement.h"
|
| #include "platform/EventDispatchForbiddenScope.h"
|
| #include "platform/RuntimeEnabledFeatures.h"
|
| +#include "platform/TraceEvent.h"
|
| #include "platform/UserGestureIndicator.h"
|
| #include "platform/scroll/ScrollableArea.h"
|
| +#include "platform/transforms/MatrixTransformOperation.h"
|
| +#include "public/platform/WebTeleportCallback.h"
|
| #include "wtf/BitVector.h"
|
| #include "wtf/HashFunctions.h"
|
| #include "wtf/text/CString.h"
|
| @@ -119,6 +122,9 @@
|
|
|
| namespace blink {
|
|
|
| +typedef WTF::HashMap<const Element*, OwnPtr<Vector<String> > > BoundAnimatedPropertyMap;
|
| +static BoundAnimatedPropertyMap* gBoundAnimatedPropertyMap = 0;
|
| +
|
| using namespace HTMLNames;
|
| using namespace XMLNames;
|
|
|
| @@ -147,6 +153,8 @@ Element::Element(const QualifiedName& tagName, Document* document, ConstructionT
|
| Element::~Element()
|
| {
|
| ASSERT(needsAttach());
|
| + if (gBoundAnimatedPropertyMap)
|
| + gBoundAnimatedPropertyMap->remove(this);
|
|
|
| #if !ENABLE(OILPAN)
|
| if (hasRareData())
|
| @@ -2673,6 +2681,165 @@ void Element::requestPointerLock()
|
| document().page()->pointerLockController().requestPointerLock(this);
|
| }
|
|
|
| +String Element::bindAnimatedProperty(const String& propertyName, ExceptionState& exceptionState)
|
| +{
|
| + static uint64_t nextBoundId = 1;
|
| + TRACE_EVENT0("teleport", "Element::bindAnimatedProperty");
|
| + if (propertyName != "transform" && propertyName != "opacity" && propertyName != "scrollTop" && propertyName != "pendingScrollDelta") {
|
| + exceptionState.throwTypeError("The given property, '" + propertyName + "' cannot be bound");
|
| + return "";
|
| + }
|
| +
|
| + String token;
|
| + if (getBoundAnimatedProperty(propertyName, token))
|
| + return token;
|
| +
|
| + if (!gBoundAnimatedPropertyMap)
|
| + gBoundAnimatedPropertyMap = new BoundAnimatedPropertyMap();
|
| +
|
| + gBoundAnimatedPropertyMap->add(this, adoptPtr(new Vector<String>()));
|
| + token = String::number(WTF::intHash(nextBoundId++)) + ":" + propertyName;
|
| + gBoundAnimatedPropertyMap->get(this)->append(token);
|
| +
|
| + setNeedsCompositingUpdate();
|
| +
|
| + return token;
|
| +}
|
| +
|
| +void Element::unbindAnimatedProperty(const String& propertyName, ExceptionState& exceptionState)
|
| +{
|
| + TRACE_EVENT0("teleport", "Element::unbindAnimatedProperty");
|
| + String token;
|
| + if (!getBoundAnimatedProperty(propertyName, token)) {
|
| + exceptionState.throwTypeError("Cannot unbind a property that has not been bound.");
|
| + return;
|
| + }
|
| +
|
| + Vector<String>& boundProperties = *gBoundAnimatedPropertyMap->get(this);
|
| + boundProperties.remove(boundProperties.find(token));
|
| + RenderBoxModelObject* renderer = renderBoxModelObject();
|
| + if (renderer && renderer->hasLayer())
|
| + renderer->layer()->unbindAnimatedProperties();
|
| +
|
| + setNeedsCompositingUpdate();
|
| +}
|
| +
|
| +void Element::updateBoundAnimatedPropertiesIfNeeded()
|
| +{
|
| + if (!gBoundAnimatedPropertyMap)
|
| + return;
|
| +
|
| + BoundAnimatedPropertyMap::const_iterator iter = gBoundAnimatedPropertyMap->begin();
|
| + for (; iter != gBoundAnimatedPropertyMap->end(); ++iter) {
|
| + RenderBoxModelObject* renderer = iter->key->renderBoxModelObject();
|
| + if (renderer && renderer->hasLayer())
|
| + renderer->layer()->bindAnimatedProperties(*iter->value);
|
| + }
|
| +}
|
| +
|
| +void Element::applyToBoundAnimatedProperties(const WebVector<WebTeleportValue>& values)
|
| +{
|
| + TRACE_EVENT0("teleport,teleport-backchannel", "Element::applyToBoundAnimatedProperties");
|
| +
|
| + // FIXME: we need to store this stuff and apply it during style.
|
| + if (!gBoundAnimatedPropertyMap)
|
| + return;
|
| +
|
| + BoundAnimatedPropertyMap::const_iterator iter = gBoundAnimatedPropertyMap->begin();
|
| + for (; iter != gBoundAnimatedPropertyMap->end(); ++iter) {
|
| + const Vector<String>& properties = *iter->value;
|
| + for (size_t i = 0; i < values.size(); ++i) {
|
| + const WebTeleportValue& value = values[i];
|
| + String id = value.id;
|
| + size_t j = properties.find(id);
|
| + if (j == kNotFound)
|
| + continue;
|
| +
|
| + if (!iter->key->renderer())
|
| + continue;
|
| +
|
| + RenderStyle* style = iter->key->renderer()->style();
|
| + if (!style)
|
| + continue;
|
| +
|
| + RefPtr<RenderStyle> updated = RenderStyle::clone(style);
|
| +
|
| + switch (value.type) {
|
| + case WebTeleportValue::ValueTypeTransform: {
|
| + TransformOperations operations;
|
| + operations.operations().append(MatrixTransformOperation::create(
|
| + TransformationMatrix(
|
| + value.value.matrix[0],
|
| + value.value.matrix[4],
|
| + value.value.matrix[8],
|
| + value.value.matrix[12],
|
| + value.value.matrix[1],
|
| + value.value.matrix[5],
|
| + value.value.matrix[9],
|
| + value.value.matrix[13],
|
| + value.value.matrix[2],
|
| + value.value.matrix[6],
|
| + value.value.matrix[10],
|
| + value.value.matrix[14],
|
| + value.value.matrix[3],
|
| + value.value.matrix[7],
|
| + value.value.matrix[11],
|
| + value.value.matrix[15])));
|
| + updated->setTransform(operations);
|
| + break;
|
| + }
|
| + case WebTeleportValue::ValueTypeOpacity: {
|
| + updated->setOpacity(value.value.scalar);
|
| + break;
|
| + }
|
| + case WebTeleportValue::ValueTypeScrollTop: {
|
| + const_cast<Element*>(iter->key)->setScrollTop(static_cast<int>(value.value.scalar));
|
| + break;
|
| + }
|
| + case WebTeleportValue::ValueTypePendingScrollDelta: {
|
| + // const_cast<Element*>(iter->key)->setPendingScrollDelta(static_cast<int>(value.value.scalar));
|
| + // TODO
|
| + break;
|
| + }
|
| + case WebTeleportValue::ValueTypeTimestamp:
|
| + case WebTeleportValue::ValueTypeError:
|
| + break;
|
| + default:
|
| + RELEASE_ASSERT_NOT_REACHED();
|
| + }
|
| +
|
| + iter->key->renderer()->setStyle(updated.release());
|
| + }
|
| + }
|
| +}
|
| +
|
| +bool Element::getBoundAnimatedProperty(const String& propertyName, String& token) const
|
| +{
|
| + if (!gBoundAnimatedPropertyMap)
|
| + return false;
|
| +
|
| + BoundAnimatedPropertyMap::const_iterator iter = gBoundAnimatedPropertyMap->find(this);
|
| + if (iter == gBoundAnimatedPropertyMap->end())
|
| + return false;
|
| +
|
| + Vector<String>& boundProperties = *iter->value;
|
| + for (size_t i = 0; i < boundProperties.size(); ++i) {
|
| + Vector<String> components;
|
| + boundProperties[i].split(":", components);
|
| + if (components[1] == propertyName) {
|
| + token = boundProperties[i];
|
| + return true;
|
| + }
|
| + }
|
| +
|
| + return false;
|
| +}
|
| +
|
| +bool Element::hasBoundAnimatedProperty() const
|
| +{
|
| + return gBoundAnimatedPropertyMap && gBoundAnimatedPropertyMap->contains(this);
|
| +}
|
| +
|
| SpellcheckAttributeState Element::spellcheckAttributeState() const
|
| {
|
| const AtomicString& value = fastGetAttribute(spellcheckAttr);
|
|
|