| 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 Dirk Mueller (mueller@kde.org) | 4 * (C) 2001 Dirk Mueller (mueller@kde.org) |
| 5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) | 5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) |
| 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All r
ights reserved. | 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All r
ights reserved. |
| 7 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t
orchmobile.com/) | 7 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t
orchmobile.com/) |
| 8 * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved. | 8 * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved. |
| 9 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) | 9 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) |
| 10 * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved. | 10 * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved. |
| (...skipping 1026 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1037 | 1037 |
| 1038 // FIXME: We should update style on our ancestor chain before proceeding | 1038 // FIXME: We should update style on our ancestor chain before proceeding |
| 1039 // however doing so currently causes several tests to crash, as LocalFrame::
setDocument calls Document::attach | 1039 // however doing so currently causes several tests to crash, as LocalFrame::
setDocument calls Document::attach |
| 1040 // before setting the LocalDOMWindow on the LocalFrame, or the SecurityOrigi
n on the document. The attach, in turn | 1040 // before setting the LocalDOMWindow on the LocalFrame, or the SecurityOrigi
n on the document. The attach, in turn |
| 1041 // resolves style (here) and then when we resolve style on the parent chain,
we may end up | 1041 // resolves style (here) and then when we resolve style on the parent chain,
we may end up |
| 1042 // re-attaching our containing iframe, which when asked HTMLFrameElementBase
::isURLAllowed | 1042 // re-attaching our containing iframe, which when asked HTMLFrameElementBase
::isURLAllowed |
| 1043 // hits a null-dereference due to security code always assuming the document
has a SecurityOrigin. | 1043 // hits a null-dereference due to security code always assuming the document
has a SecurityOrigin. |
| 1044 | 1044 |
| 1045 updateStyle(change); | 1045 updateStyle(change); |
| 1046 | 1046 |
| 1047 // As a result of the style recalculation, the currently hovered element mig
ht have been | |
| 1048 // detached (for example, by setting display:none in the :hover style), sche
dule another mouseMove event | |
| 1049 // to check if any other elements ended up under the mouse pointer due to re
-layout. | |
| 1050 if (hoverNode() && !hoverNode()->renderer() && frame()) | |
| 1051 frame()->eventHandler().dispatchFakeMouseMoveEventSoon(); | |
| 1052 | |
| 1053 if (m_focusedElement && !m_focusedElement->isFocusable()) | 1047 if (m_focusedElement && !m_focusedElement->isFocusable()) |
| 1054 clearFocusedElementSoon(); | 1048 clearFocusedElementSoon(); |
| 1055 | 1049 |
| 1056 ASSERT(!m_timeline->hasOutdatedAnimationPlayer()); | 1050 ASSERT(!m_timeline->hasOutdatedAnimationPlayer()); |
| 1057 | 1051 |
| 1058 TRACE_EVENT_END1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Recalculat
eStyles", "elementCount", m_styleRecalcElementCounter); | 1052 TRACE_EVENT_END1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Recalculat
eStyles", "elementCount", m_styleRecalcElementCounter); |
| 1059 TRACE_EVENT_END1("blink", "Document::updateRenderTree", "elementCount", m_st
yleRecalcElementCounter); | 1053 TRACE_EVENT_END1("blink", "Document::updateRenderTree", "elementCount", m_st
yleRecalcElementCounter); |
| 1060 } | 1054 } |
| 1061 | 1055 |
| 1062 void Document::updateStyle(StyleRecalcChange change) | 1056 void Document::updateStyle(StyleRecalcChange change) |
| (...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1503 } | 1497 } |
| 1504 | 1498 |
| 1505 String Document::outgoingReferrer() | 1499 String Document::outgoingReferrer() |
| 1506 { | 1500 { |
| 1507 // See http://www.whatwg.org/specs/web-apps/current-work/#fetching-resources | 1501 // See http://www.whatwg.org/specs/web-apps/current-work/#fetching-resources |
| 1508 // for why we walk the parent chain for srcdoc documents. | 1502 // for why we walk the parent chain for srcdoc documents. |
| 1509 Document* referrerDocument = this; | 1503 Document* referrerDocument = this; |
| 1510 return referrerDocument->m_url.strippedForUseAsReferrer(); | 1504 return referrerDocument->m_url.strippedForUseAsReferrer(); |
| 1511 } | 1505 } |
| 1512 | 1506 |
| 1513 MouseEventWithHitTestResults Document::prepareMouseEvent(const HitTestRequest& r
equest, const LayoutPoint& documentPoint, const PlatformMouseEvent& event) | |
| 1514 { | |
| 1515 ASSERT(!renderView() || renderView()->isRenderView()); | |
| 1516 | |
| 1517 // RenderView::hitTest causes a layout, and we don't want to hit that until
the first | |
| 1518 // layout because until then, there is nothing shown on the screen - the use
r can't | |
| 1519 // have intentionally clicked on something belonging to this page. Furthermo
re, | |
| 1520 // mousemove events before the first layout should not lead to a premature l
ayout() | |
| 1521 // happening, which could show a flash of white. | |
| 1522 // See also the similar code in EventHandler::hitTestResultAtPoint. | |
| 1523 if (!renderView() || !view() || !view()->didFirstLayout()) | |
| 1524 return MouseEventWithHitTestResults(event, HitTestResult(LayoutPoint()))
; | |
| 1525 | |
| 1526 HitTestResult result(documentPoint); | |
| 1527 renderView()->hitTest(request, result); | |
| 1528 | |
| 1529 if (!request.readOnly()) | |
| 1530 updateHoverActiveState(request, result.innerElement(), &event); | |
| 1531 | |
| 1532 return MouseEventWithHitTestResults(event, result); | |
| 1533 } | |
| 1534 | |
| 1535 PassRefPtr<Node> Document::cloneNode(bool deep) | 1507 PassRefPtr<Node> Document::cloneNode(bool deep) |
| 1536 { | 1508 { |
| 1537 RefPtr<Document> clone = cloneDocumentWithoutChildren(); | 1509 RefPtr<Document> clone = cloneDocumentWithoutChildren(); |
| 1538 if (deep) | 1510 if (deep) |
| 1539 cloneChildNodes(clone.get()); | 1511 cloneChildNodes(clone.get()); |
| 1540 return clone.release(); | 1512 return clone.release(); |
| 1541 } | 1513 } |
| 1542 | 1514 |
| 1543 PassRefPtr<Document> Document::cloneDocumentWithoutChildren() | 1515 PassRefPtr<Document> Document::cloneDocumentWithoutChildren() |
| 1544 { | 1516 { |
| (...skipping 826 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2371 | 2343 |
| 2372 LayoutRect visibleContentRect = view()->visibleContentRect(); | 2344 LayoutRect visibleContentRect = view()->visibleContentRect(); |
| 2373 rect.move(-FloatSize(visibleContentRect.x().toFloat(), visibleContentRect.y(
).toFloat())); | 2345 rect.move(-FloatSize(visibleContentRect.x().toFloat(), visibleContentRect.y(
).toFloat())); |
| 2374 } | 2346 } |
| 2375 | 2347 |
| 2376 void Document::decrementActiveParserCount() | 2348 void Document::decrementActiveParserCount() |
| 2377 { | 2349 { |
| 2378 --m_activeParserCount; | 2350 --m_activeParserCount; |
| 2379 } | 2351 } |
| 2380 | 2352 |
| 2381 static RenderObject* nearestCommonHoverAncestor(RenderObject* obj1, RenderObject
* obj2) | |
| 2382 { | |
| 2383 if (!obj1 || !obj2) | |
| 2384 return 0; | |
| 2385 | |
| 2386 for (RenderObject* currObj1 = obj1; currObj1; currObj1 = currObj1->hoverAnce
stor()) { | |
| 2387 for (RenderObject* currObj2 = obj2; currObj2; currObj2 = currObj2->hover
Ancestor()) { | |
| 2388 if (currObj1 == currObj2) | |
| 2389 return currObj1; | |
| 2390 } | |
| 2391 } | |
| 2392 | |
| 2393 return 0; | |
| 2394 } | |
| 2395 | |
| 2396 void Document::updateHoverActiveState(const HitTestRequest& request, Element* in
nerElement, const PlatformMouseEvent* event) | |
| 2397 { | |
| 2398 ASSERT(!request.readOnly()); | |
| 2399 | |
| 2400 if (request.active() && m_frame) | |
| 2401 m_frame->eventHandler().notifyElementActivated(); | |
| 2402 | |
| 2403 Element* innerElementInDocument = innerElement; | |
| 2404 | |
| 2405 Element* oldActiveElement = activeHoverElement(); | |
| 2406 if (oldActiveElement && !request.active()) { | |
| 2407 // The oldActiveElement renderer is null, dropped on :active by setting
display: none, | |
| 2408 // for instance. We still need to clear the ActiveChain as the mouse is
released. | |
| 2409 for (Node* node = oldActiveElement; node; node = NodeRenderingTraversal:
:parent(node)) { | |
| 2410 ASSERT(!node->isTextNode()); | |
| 2411 node->setActive(false); | |
| 2412 m_userActionElements.setInActiveChain(node, false); | |
| 2413 } | |
| 2414 setActiveHoverElement(nullptr); | |
| 2415 } else { | |
| 2416 Element* newActiveElement = innerElementInDocument; | |
| 2417 if (!oldActiveElement && newActiveElement && request.active() && !reques
t.touchMove()) { | |
| 2418 // We are setting the :active chain and freezing it. If future moves
happen, they | |
| 2419 // will need to reference this chain. | |
| 2420 for (Node* node = newActiveElement; node; node = NodeRenderingTraver
sal::parent(node)) { | |
| 2421 ASSERT(!node->isTextNode()); | |
| 2422 m_userActionElements.setInActiveChain(node, true); | |
| 2423 } | |
| 2424 setActiveHoverElement(newActiveElement); | |
| 2425 } | |
| 2426 } | |
| 2427 // If the mouse has just been pressed, set :active on the chain. Those (and
only those) | |
| 2428 // nodes should remain :active until the mouse is released. | |
| 2429 bool allowActiveChanges = !oldActiveElement && activeHoverElement(); | |
| 2430 | |
| 2431 // If the mouse is down and if this is a mouse move event, we want to restri
ct changes in | |
| 2432 // :hover/:active to only apply to elements that are in the :active chain th
at we froze | |
| 2433 // at the time the mouse went down. | |
| 2434 bool mustBeInActiveChain = request.active() && request.move(); | |
| 2435 | |
| 2436 RefPtr<Node> oldHoverNode = hoverNode(); | |
| 2437 | |
| 2438 // Check to see if the hovered node has changed. | |
| 2439 // If it hasn't, we do not need to do anything. | |
| 2440 Node* newHoverNode = innerElementInDocument; | |
| 2441 while (newHoverNode && !newHoverNode->renderer()) | |
| 2442 newHoverNode = newHoverNode->parentOrShadowHostNode(); | |
| 2443 | |
| 2444 // Update our current hover node. | |
| 2445 setHoverNode(newHoverNode); | |
| 2446 | |
| 2447 // We have two different objects. Fetch their renderers. | |
| 2448 RenderObject* oldHoverObj = oldHoverNode ? oldHoverNode->renderer() : 0; | |
| 2449 RenderObject* newHoverObj = newHoverNode ? newHoverNode->renderer() : 0; | |
| 2450 | |
| 2451 // Locate the common ancestor render object for the two renderers. | |
| 2452 RenderObject* ancestor = nearestCommonHoverAncestor(oldHoverObj, newHoverObj
); | |
| 2453 RefPtr<Node> ancestorNode(ancestor ? ancestor->node() : 0); | |
| 2454 | |
| 2455 Vector<RefPtr<Node>, 32> nodesToRemoveFromChain; | |
| 2456 Vector<RefPtr<Node>, 32> nodesToAddToChain; | |
| 2457 | |
| 2458 if (oldHoverObj != newHoverObj) { | |
| 2459 // If the old hovered node is not nil but it's renderer is, it was proba
bly detached as part of the :hover style | |
| 2460 // (for instance by setting display:none in the :hover pseudo-class). In
this case, the old hovered element (and its ancestors) | |
| 2461 // must be updated, to ensure it's normal style is re-applied. | |
| 2462 if (oldHoverNode && !oldHoverObj) { | |
| 2463 for (Node* node = oldHoverNode.get(); node; node = node->parentNode(
)) { | |
| 2464 if (!mustBeInActiveChain || (node->isElementNode() && toElement(
node)->inActiveChain())) | |
| 2465 nodesToRemoveFromChain.append(node); | |
| 2466 } | |
| 2467 | |
| 2468 } | |
| 2469 | |
| 2470 // The old hover path only needs to be cleared up to (and not including)
the common ancestor; | |
| 2471 for (RenderObject* curr = oldHoverObj; curr && curr != ancestor; curr =
curr->hoverAncestor()) { | |
| 2472 if (curr->node() && !curr->isText() && (!mustBeInActiveChain || curr
->node()->inActiveChain())) | |
| 2473 nodesToRemoveFromChain.append(curr->node()); | |
| 2474 } | |
| 2475 } | |
| 2476 | |
| 2477 // Now set the hover state for our new object up to the root. | |
| 2478 for (RenderObject* curr = newHoverObj; curr; curr = curr->hoverAncestor()) { | |
| 2479 if (curr->node() && !curr->isText() && (!mustBeInActiveChain || curr->no
de()->inActiveChain())) | |
| 2480 nodesToAddToChain.append(curr->node()); | |
| 2481 } | |
| 2482 | |
| 2483 // mouseenter and mouseleave events do not bubble, so they are dispatched if
f there is a capturing | |
| 2484 // event handler on an ancestor or a normal event handler on the element its
elf. This special | |
| 2485 // handling is necessary to avoid O(n^2) capturing event handler checks. We'
ll check the previously | |
| 2486 // hovered node's ancestor tree for 'mouseleave' handlers here, then check t
he newly hovered node's | |
| 2487 // ancestor tree for 'mouseenter' handlers after dispatching the 'mouseleave
' events (as the handler | |
| 2488 // for 'mouseleave' might set a capturing 'mouseenter' handler, odd as that
might be). | |
| 2489 bool ancestorHasCapturingMouseleaveListener = false; | |
| 2490 if (event && newHoverNode != oldHoverNode.get()) { | |
| 2491 for (Node* node = oldHoverNode.get(); node; node = node->parentOrShadowH
ostNode()) { | |
| 2492 if (node->hasCapturingEventListeners(EventTypeNames::mouseleave)) { | |
| 2493 ancestorHasCapturingMouseleaveListener = true; | |
| 2494 break; | |
| 2495 } | |
| 2496 } | |
| 2497 } | |
| 2498 | |
| 2499 size_t removeCount = nodesToRemoveFromChain.size(); | |
| 2500 for (size_t i = 0; i < removeCount; ++i) { | |
| 2501 nodesToRemoveFromChain[i]->setHovered(false); | |
| 2502 if (event && (ancestorHasCapturingMouseleaveListener || nodesToRemoveFro
mChain[i]->hasEventListeners(EventTypeNames::mouseleave))) | |
| 2503 nodesToRemoveFromChain[i]->dispatchMouseEvent(*event, EventTypeNames
::mouseleave, 0, newHoverNode); | |
| 2504 } | |
| 2505 | |
| 2506 bool ancestorHasCapturingMouseenterListener = false; | |
| 2507 if (event && newHoverNode != oldHoverNode.get()) { | |
| 2508 for (Node* node = newHoverNode; node; node = node->parentOrShadowHostNod
e()) { | |
| 2509 if (node->hasCapturingEventListeners(EventTypeNames::mouseenter)) { | |
| 2510 ancestorHasCapturingMouseenterListener = true; | |
| 2511 break; | |
| 2512 } | |
| 2513 } | |
| 2514 } | |
| 2515 | |
| 2516 bool sawCommonAncestor = false; | |
| 2517 size_t addCount = nodesToAddToChain.size(); | |
| 2518 for (size_t i = 0; i < addCount; ++i) { | |
| 2519 // Elements past the common ancestor do not change hover state, but migh
t change active state. | |
| 2520 if (ancestorNode && nodesToAddToChain[i] == ancestorNode) | |
| 2521 sawCommonAncestor = true; | |
| 2522 if (allowActiveChanges) | |
| 2523 nodesToAddToChain[i]->setActive(true); | |
| 2524 if (!sawCommonAncestor) { | |
| 2525 nodesToAddToChain[i]->setHovered(true); | |
| 2526 if (event && (ancestorHasCapturingMouseenterListener || nodesToAddTo
Chain[i]->hasEventListeners(EventTypeNames::mouseenter))) | |
| 2527 nodesToAddToChain[i]->dispatchMouseEvent(*event, EventTypeNames:
:mouseenter, 0, oldHoverNode.get()); | |
| 2528 } | |
| 2529 } | |
| 2530 } | |
| 2531 | |
| 2532 Document& Document::ensureTemplateDocument() | 2353 Document& Document::ensureTemplateDocument() |
| 2533 { | 2354 { |
| 2534 if (isTemplateDocument()) | 2355 if (isTemplateDocument()) |
| 2535 return *this; | 2356 return *this; |
| 2536 | 2357 |
| 2537 if (m_templateDocument) | 2358 if (m_templateDocument) |
| 2538 return *m_templateDocument; | 2359 return *m_templateDocument; |
| 2539 | 2360 |
| 2540 if (isHTMLDocument()) { | 2361 if (isHTMLDocument()) { |
| 2541 DocumentInit init = DocumentInit::fromContext(contextDocument(), blankUR
L()); | 2362 DocumentInit init = DocumentInit::fromContext(contextDocument(), blankUR
L()); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2619 using namespace blink; | 2440 using namespace blink; |
| 2620 void showLiveDocumentInstances() | 2441 void showLiveDocumentInstances() |
| 2621 { | 2442 { |
| 2622 WeakDocumentSet& set = liveDocumentSet(); | 2443 WeakDocumentSet& set = liveDocumentSet(); |
| 2623 fprintf(stderr, "There are %u documents currently alive:\n", set.size()); | 2444 fprintf(stderr, "There are %u documents currently alive:\n", set.size()); |
| 2624 for (WeakDocumentSet::const_iterator it = set.begin(); it != set.end(); ++it
) { | 2445 for (WeakDocumentSet::const_iterator it = set.begin(); it != set.end(); ++it
) { |
| 2625 fprintf(stderr, "- Document %p URL: %s\n", *it, (*it)->url().string().ut
f8().data()); | 2446 fprintf(stderr, "- Document %p URL: %s\n", *it, (*it)->url().string().ut
f8().data()); |
| 2626 } | 2447 } |
| 2627 } | 2448 } |
| 2628 #endif | 2449 #endif |
| OLD | NEW |