Chromium Code Reviews| Index: Source/core/dom/Element.cpp |
| diff --git a/Source/core/dom/Element.cpp b/Source/core/dom/Element.cpp |
| index 8a3c55dc5d609d6304bf5fcb54fc2baa967b7c1f..09b3732fa8e3d9fbec6a1e10e32fb450d8d2301b 100644 |
| --- a/Source/core/dom/Element.cpp |
| +++ b/Source/core/dom/Element.cpp |
| @@ -30,6 +30,8 @@ |
| #include "bindings/core/v8/Dictionary.h" |
| #include "bindings/core/v8/ExceptionMessages.h" |
| #include "bindings/core/v8/ExceptionState.h" |
| +#include "bindings/core/v8/ScriptFunctionCall.h" |
| +#include "bindings/core/v8/ToV8.h" |
| #include "bindings/core/v8/V8DOMWrapper.h" |
| #include "bindings/core/v8/V8PerContextData.h" |
| #include "core/CSSValueKeywords.h" |
| @@ -477,7 +479,38 @@ void Element::scrollIntoViewIfNeeded(bool centerIfNeeded) |
| layoutObject()->scrollRectToVisible(bounds, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded); |
| } |
| -void Element::distributeScroll(ScrollState& scrollState) |
| +// Returns true iff a V8 method existed and was called. |
| +static bool callScrollCustomizationV8Method(Element* element, |
| + ScrollState& scrollState, String methodName) |
| +{ |
| + ASSERT(RuntimeEnabledFeatures::scrollCustomizationEnabled()); |
| + |
| + LocalFrame* frame = element->document().frame(); |
| + if (!frame) |
| + return false; |
| + ScriptState* scriptState = ScriptState::forMainWorld(frame); |
|
haraken
2015/06/09 00:07:13
Why can we assume the main world?
tdresser
2015/06/09 14:27:42
We're okay if scroll customization methods can onl
haraken
2015/06/09 15:16:38
That is not OK. Unless you have a strong reason to
tdresser
2015/06/26 14:53:15
callScrollCustomizationV8Method is never called fr
|
| + ScriptState::Scope scope(scriptState); |
| + |
| + v8::Handle<v8::Object> creationContext = scriptState->context()->Global(); |
| + ScriptValue thisWrapper = ScriptValue(scriptState, toV8(element, creationContext, scriptState->isolate())); |
| + ScriptValue scrollStateWrapper = ScriptValue(scriptState, toV8(&scrollState, creationContext, scriptState->isolate())); |
| + |
| + v8::Handle<v8::Object> thisObject = v8::Handle<v8::Object>::Cast(thisWrapper.v8Value()); |
| + v8::Local<v8::Value> functionValue = thisObject->Get(v8String(scriptState->isolate(), methodName)); |
| + ASSERT(functionValue->IsFunction()); |
| + v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(functionValue); |
| + |
| + // Native methods should avoid the performance overhead of a v8 method call. |
| + if (function->ScriptId() == v8::UnboundScript::kNoScriptId) |
| + return false; |
| + |
| + ScriptFunctionCall functionCall(thisWrapper, methodName); |
|
haraken
2015/06/09 00:07:12
ScriptFunctionCall is an abstraction for devtools.
tdresser
2015/06/09 14:27:42
Done.
|
| + functionCall.appendArgument(scrollStateWrapper); |
| + functionCall.call(); |
| + return true; |
| +} |
| + |
| +void Element::distributeScrollNative(ScrollState& scrollState) |
| { |
| ASSERT(RuntimeEnabledFeatures::scrollCustomizationEnabled()); |
| if (scrollState.fullyConsumed()) |
| @@ -497,15 +530,29 @@ void Element::distributeScroll(ScrollState& scrollState) |
| const double deltaX = scrollState.deltaX(); |
| const double deltaY = scrollState.deltaY(); |
| - applyScroll(scrollState); |
| + callApplyScroll(scrollState); |
| if (deltaX != scrollState.deltaX() || deltaY != scrollState.deltaY()) |
| scrollState.setCurrentNativeScrollingElement(this); |
| } |
| -void Element::applyScroll(ScrollState& scrollState) |
| +void Element::callDistributeScroll(ScrollState& scrollState) |
| +{ |
| + if (!callScrollCustomizationV8Method(this, scrollState, "distributeScroll")) |
| + distributeScrollNative(scrollState); |
| +}; |
| + |
| +void Element::distributeScroll(ScrollState* scrollState) |
| +{ |
| + ASSERT(scrollState); |
| + distributeScrollNative(*scrollState); |
| +} |
| + |
| +void Element::applyScrollNative(ScrollState& scrollState) |
| { |
| ASSERT(RuntimeEnabledFeatures::scrollCustomizationEnabled()); |
| + document().updateLayoutIgnorePendingStylesheets(); |
| + |
| if (scrollState.fullyConsumed()) |
| return; |
| @@ -513,8 +560,8 @@ void Element::applyScroll(ScrollState& scrollState) |
| const double deltaY = scrollState.deltaY(); |
| bool scrolled = false; |
| - // Handle the documentElement separately, as it scrolls the FrameView. |
| - if (this == document().documentElement()) { |
| + // Handle the scrollingElement separately, as it scrolls the FrameView. |
| + if (this == document().scrollingElement()) { |
| FloatSize delta(deltaX, deltaY); |
| if (document().frame()->applyScrollDelta(delta, scrollState.isBeginning())) { |
| scrolled = true; |
| @@ -549,6 +596,18 @@ void Element::applyScroll(ScrollState& scrollState) |
| document().frame()->view()->setWasScrolledByUser(true); |
| }; |
| +void Element::callApplyScroll(ScrollState& scrollState) |
| +{ |
| + if (!callScrollCustomizationV8Method(this, scrollState, "applyScroll")) |
| + applyScrollNative(scrollState); |
| +}; |
| + |
| +void Element::applyScroll(ScrollState* scrollState) |
| +{ |
| + ASSERT(scrollState); |
| + applyScrollNative(*scrollState); |
| +} |
| + |
| static float localZoomForLayoutObject(LayoutObject& layoutObject) |
| { |
| // FIXME: This does the wrong thing if two opposing zooms are in effect and canceled each |