Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 4 * (C) 2001 Peter Kelly (pmk@post.com) | 4 * (C) 2001 Peter Kelly (pmk@post.com) |
| 5 * (C) 2001 Dirk Mueller (mueller@kde.org) | 5 * (C) 2001 Dirk Mueller (mueller@kde.org) |
| 6 * (C) 2007 David Smith (catfish.man@gmail.com) | 6 * (C) 2007 David Smith (catfish.man@gmail.com) |
| 7 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013 Apple Inc. All rights reserved. | 7 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013 Apple Inc. All rights reserved. |
| 8 * (C) 2007 Eric Seidel (eric@webkit.org) | 8 * (C) 2007 Eric Seidel (eric@webkit.org) |
| 9 * | 9 * |
| 10 * This library is free software; you can redistribute it and/or | 10 * This library is free software; you can redistribute it and/or |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 23 * Boston, MA 02110-1301, USA. | 23 * Boston, MA 02110-1301, USA. |
| 24 */ | 24 */ |
| 25 | 25 |
| 26 #include "config.h" | 26 #include "config.h" |
| 27 #include "core/dom/Element.h" | 27 #include "core/dom/Element.h" |
| 28 | 28 |
| 29 #include "bindings/core/v8/DOMDataStore.h" | 29 #include "bindings/core/v8/DOMDataStore.h" |
| 30 #include "bindings/core/v8/Dictionary.h" | 30 #include "bindings/core/v8/Dictionary.h" |
| 31 #include "bindings/core/v8/ExceptionMessages.h" | 31 #include "bindings/core/v8/ExceptionMessages.h" |
| 32 #include "bindings/core/v8/ExceptionState.h" | 32 #include "bindings/core/v8/ExceptionState.h" |
| 33 #include "bindings/core/v8/ScriptFunctionCall.h" | |
| 34 #include "bindings/core/v8/ToV8.h" | |
| 33 #include "bindings/core/v8/V8DOMWrapper.h" | 35 #include "bindings/core/v8/V8DOMWrapper.h" |
| 34 #include "bindings/core/v8/V8PerContextData.h" | 36 #include "bindings/core/v8/V8PerContextData.h" |
| 35 #include "core/CSSValueKeywords.h" | 37 #include "core/CSSValueKeywords.h" |
| 36 #include "core/SVGNames.h" | 38 #include "core/SVGNames.h" |
| 37 #include "core/XLinkNames.h" | 39 #include "core/XLinkNames.h" |
| 38 #include "core/XMLNames.h" | 40 #include "core/XMLNames.h" |
| 39 #include "core/animation/AnimationTimeline.h" | 41 #include "core/animation/AnimationTimeline.h" |
| 40 #include "core/animation/css/CSSAnimations.h" | 42 #include "core/animation/css/CSSAnimations.h" |
| 41 #include "core/css/CSSImageValue.h" | 43 #include "core/css/CSSImageValue.h" |
| 42 #include "core/css/CSSStyleSheet.h" | 44 #include "core/css/CSSStyleSheet.h" |
| (...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 470 if (!layoutObject()) | 472 if (!layoutObject()) |
| 471 return; | 473 return; |
| 472 | 474 |
| 473 LayoutRect bounds = boundingBox(); | 475 LayoutRect bounds = boundingBox(); |
| 474 if (centerIfNeeded) | 476 if (centerIfNeeded) |
| 475 layoutObject()->scrollRectToVisible(bounds, ScrollAlignment::alignCenter IfNeeded, ScrollAlignment::alignCenterIfNeeded); | 477 layoutObject()->scrollRectToVisible(bounds, ScrollAlignment::alignCenter IfNeeded, ScrollAlignment::alignCenterIfNeeded); |
| 476 else | 478 else |
| 477 layoutObject()->scrollRectToVisible(bounds, ScrollAlignment::alignToEdge IfNeeded, ScrollAlignment::alignToEdgeIfNeeded); | 479 layoutObject()->scrollRectToVisible(bounds, ScrollAlignment::alignToEdge IfNeeded, ScrollAlignment::alignToEdgeIfNeeded); |
| 478 } | 480 } |
| 479 | 481 |
| 480 void Element::distributeScroll(ScrollState& scrollState) | 482 // Returns true iff a V8 method existed and was called. |
| 483 static bool callScrollCustomizationV8Method(Element* element, | |
| 484 ScrollState& scrollState, String methodName) | |
| 485 { | |
| 486 ASSERT(RuntimeEnabledFeatures::scrollCustomizationEnabled()); | |
| 487 | |
| 488 LocalFrame* frame = element->document().frame(); | |
| 489 if (!frame) | |
| 490 return false; | |
| 491 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
| |
| 492 ScriptState::Scope scope(scriptState); | |
| 493 | |
| 494 v8::Handle<v8::Object> creationContext = scriptState->context()->Global(); | |
| 495 ScriptValue thisWrapper = ScriptValue(scriptState, toV8(element, creationCon text, scriptState->isolate())); | |
| 496 ScriptValue scrollStateWrapper = ScriptValue(scriptState, toV8(&scrollState, creationContext, scriptState->isolate())); | |
| 497 | |
| 498 v8::Handle<v8::Object> thisObject = v8::Handle<v8::Object>::Cast(thisWrapper .v8Value()); | |
| 499 v8::Local<v8::Value> functionValue = thisObject->Get(v8String(scriptState->i solate(), methodName)); | |
| 500 ASSERT(functionValue->IsFunction()); | |
| 501 v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(functionVal ue); | |
| 502 | |
| 503 // Native methods should avoid the performance overhead of a v8 method call. | |
| 504 if (function->ScriptId() == v8::UnboundScript::kNoScriptId) | |
| 505 return false; | |
| 506 | |
| 507 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.
| |
| 508 functionCall.appendArgument(scrollStateWrapper); | |
| 509 functionCall.call(); | |
| 510 return true; | |
| 511 } | |
| 512 | |
| 513 void Element::distributeScrollNative(ScrollState& scrollState) | |
| 481 { | 514 { |
| 482 ASSERT(RuntimeEnabledFeatures::scrollCustomizationEnabled()); | 515 ASSERT(RuntimeEnabledFeatures::scrollCustomizationEnabled()); |
| 483 if (scrollState.fullyConsumed()) | 516 if (scrollState.fullyConsumed()) |
| 484 return; | 517 return; |
| 485 | 518 |
| 486 scrollState.distributeToScrollChainDescendant(); | 519 scrollState.distributeToScrollChainDescendant(); |
| 487 | 520 |
| 488 // If the scroll doesn't propagate, and we're currently scrolling | 521 // If the scroll doesn't propagate, and we're currently scrolling |
| 489 // an element other than this one, prevent the scroll from | 522 // an element other than this one, prevent the scroll from |
| 490 // propagating to this element. | 523 // propagating to this element. |
| 491 if (!scrollState.shouldPropagate() | 524 if (!scrollState.shouldPropagate() |
| 492 && scrollState.deltaConsumedForScrollSequence() | 525 && scrollState.deltaConsumedForScrollSequence() |
| 493 && scrollState.currentNativeScrollingElement() != this) { | 526 && scrollState.currentNativeScrollingElement() != this) { |
| 494 return; | 527 return; |
| 495 } | 528 } |
| 496 | 529 |
| 497 const double deltaX = scrollState.deltaX(); | 530 const double deltaX = scrollState.deltaX(); |
| 498 const double deltaY = scrollState.deltaY(); | 531 const double deltaY = scrollState.deltaY(); |
| 499 | 532 |
| 500 applyScroll(scrollState); | 533 callApplyScroll(scrollState); |
| 501 | 534 |
| 502 if (deltaX != scrollState.deltaX() || deltaY != scrollState.deltaY()) | 535 if (deltaX != scrollState.deltaX() || deltaY != scrollState.deltaY()) |
| 503 scrollState.setCurrentNativeScrollingElement(this); | 536 scrollState.setCurrentNativeScrollingElement(this); |
| 504 } | 537 } |
| 505 | 538 |
| 506 void Element::applyScroll(ScrollState& scrollState) | 539 void Element::callDistributeScroll(ScrollState& scrollState) |
| 540 { | |
| 541 if (!callScrollCustomizationV8Method(this, scrollState, "distributeScroll")) | |
| 542 distributeScrollNative(scrollState); | |
| 543 }; | |
| 544 | |
| 545 void Element::distributeScroll(ScrollState* scrollState) | |
| 546 { | |
| 547 ASSERT(scrollState); | |
| 548 distributeScrollNative(*scrollState); | |
| 549 } | |
| 550 | |
| 551 void Element::applyScrollNative(ScrollState& scrollState) | |
| 507 { | 552 { |
| 508 ASSERT(RuntimeEnabledFeatures::scrollCustomizationEnabled()); | 553 ASSERT(RuntimeEnabledFeatures::scrollCustomizationEnabled()); |
| 554 document().updateLayoutIgnorePendingStylesheets(); | |
| 555 | |
| 509 if (scrollState.fullyConsumed()) | 556 if (scrollState.fullyConsumed()) |
| 510 return; | 557 return; |
| 511 | 558 |
| 512 const double deltaX = scrollState.deltaX(); | 559 const double deltaX = scrollState.deltaX(); |
| 513 const double deltaY = scrollState.deltaY(); | 560 const double deltaY = scrollState.deltaY(); |
| 514 bool scrolled = false; | 561 bool scrolled = false; |
| 515 | 562 |
| 516 // Handle the documentElement separately, as it scrolls the FrameView. | 563 // Handle the scrollingElement separately, as it scrolls the FrameView. |
| 517 if (this == document().documentElement()) { | 564 if (this == document().scrollingElement()) { |
| 518 FloatSize delta(deltaX, deltaY); | 565 FloatSize delta(deltaX, deltaY); |
| 519 if (document().frame()->applyScrollDelta(delta, scrollState.isBeginning( ))) { | 566 if (document().frame()->applyScrollDelta(delta, scrollState.isBeginning( ))) { |
| 520 scrolled = true; | 567 scrolled = true; |
| 521 scrollState.consumeDeltaNative(scrollState.deltaX(), scrollState.del taY()); | 568 scrollState.consumeDeltaNative(scrollState.deltaX(), scrollState.del taY()); |
| 522 } | 569 } |
| 523 } else { | 570 } else { |
| 524 if (!layoutObject()) | 571 if (!layoutObject()) |
| 525 return; | 572 return; |
| 526 LayoutBox* curBox = layoutObject()->enclosingBox(); | 573 LayoutBox* curBox = layoutObject()->enclosingBox(); |
| 527 // FIXME: Native scrollers should only consume the scroll they | 574 // FIXME: Native scrollers should only consume the scroll they |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 542 | 589 |
| 543 // We need to setCurrentNativeScrollingElement in both the | 590 // We need to setCurrentNativeScrollingElement in both the |
| 544 // distributeScroll and applyScroll default implementations so | 591 // distributeScroll and applyScroll default implementations so |
| 545 // that if JS overrides one of these methods, but not the | 592 // that if JS overrides one of these methods, but not the |
| 546 // other, this bookkeeping remains accurate. | 593 // other, this bookkeeping remains accurate. |
| 547 scrollState.setCurrentNativeScrollingElement(this); | 594 scrollState.setCurrentNativeScrollingElement(this); |
| 548 if (scrollState.fromUserInput()) | 595 if (scrollState.fromUserInput()) |
| 549 document().frame()->view()->setWasScrolledByUser(true); | 596 document().frame()->view()->setWasScrolledByUser(true); |
| 550 }; | 597 }; |
| 551 | 598 |
| 599 void Element::callApplyScroll(ScrollState& scrollState) | |
| 600 { | |
| 601 if (!callScrollCustomizationV8Method(this, scrollState, "applyScroll")) | |
| 602 applyScrollNative(scrollState); | |
| 603 }; | |
| 604 | |
| 605 void Element::applyScroll(ScrollState* scrollState) | |
| 606 { | |
| 607 ASSERT(scrollState); | |
| 608 applyScrollNative(*scrollState); | |
| 609 } | |
| 610 | |
| 552 static float localZoomForLayoutObject(LayoutObject& layoutObject) | 611 static float localZoomForLayoutObject(LayoutObject& layoutObject) |
| 553 { | 612 { |
| 554 // FIXME: This does the wrong thing if two opposing zooms are in effect and canceled each | 613 // FIXME: This does the wrong thing if two opposing zooms are in effect and canceled each |
| 555 // other out, but the alternative is that we'd have to crawl up the whole la yout tree every | 614 // other out, but the alternative is that we'd have to crawl up the whole la yout tree every |
| 556 // time (or store an additional bit in the ComputedStyle to indicate that a zoom was specified). | 615 // time (or store an additional bit in the ComputedStyle to indicate that a zoom was specified). |
| 557 float zoomFactor = 1; | 616 float zoomFactor = 1; |
| 558 if (layoutObject.style()->effectiveZoom() != 1) { | 617 if (layoutObject.style()->effectiveZoom() != 1) { |
| 559 // Need to find the nearest enclosing LayoutObject that set up | 618 // Need to find the nearest enclosing LayoutObject that set up |
| 560 // a differing zoom, and then we divide our result by it to eliminate th e zoom. | 619 // a differing zoom, and then we divide our result by it to eliminate th e zoom. |
| 561 LayoutObject* prev = &layoutObject; | 620 LayoutObject* prev = &layoutObject; |
| (...skipping 2888 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3450 { | 3509 { |
| 3451 #if ENABLE(OILPAN) | 3510 #if ENABLE(OILPAN) |
| 3452 if (hasRareData()) | 3511 if (hasRareData()) |
| 3453 visitor->trace(elementRareData()); | 3512 visitor->trace(elementRareData()); |
| 3454 visitor->trace(m_elementData); | 3513 visitor->trace(m_elementData); |
| 3455 #endif | 3514 #endif |
| 3456 ContainerNode::trace(visitor); | 3515 ContainerNode::trace(visitor); |
| 3457 } | 3516 } |
| 3458 | 3517 |
| 3459 } // namespace blink | 3518 } // namespace blink |
| OLD | NEW |