Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(257)

Side by Side Diff: sky/engine/core/dom/Document.cpp

Issue 870073003: Remove mouse events from Sky (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698