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

Side by Side Diff: sky/engine/core/page/TouchDisambiguation.cpp

Issue 866283003: Remove TouchDisambiguation and WindowFocusAllowedIndicator (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
(Empty)
1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "sky/engine/config.h"
32
33 #include "sky/engine/core/page/TouchDisambiguation.h"
34
35 #include <algorithm>
36 #include <cmath>
37 #include "sky/engine/core/dom/Document.h"
38 #include "sky/engine/core/dom/Element.h"
39 #include "sky/engine/core/dom/NodeTraversal.h"
40 #include "sky/engine/core/frame/FrameView.h"
41 #include "sky/engine/core/frame/LocalFrame.h"
42 #include "sky/engine/core/page/EventHandler.h"
43 #include "sky/engine/core/rendering/HitTestResult.h"
44 #include "sky/engine/core/rendering/RenderBlock.h"
45
46 namespace blink {
47
48 static IntRect boundingBoxForEventNodes(Node* eventNode)
49 {
50 if (!eventNode->document().view())
51 return IntRect();
52
53 IntRect result;
54 Node* node = eventNode;
55 while (node) {
56 // Skip the whole sub-tree if the node doesn't propagate events.
57 if (node != eventNode && node->willRespondToMouseClickEvents()) {
58 node = NodeTraversal::nextSkippingChildren(*node, eventNode);
59 continue;
60 }
61 result.unite(node->pixelSnappedBoundingBox());
62 node = NodeTraversal::next(*node, eventNode);
63 }
64 return eventNode->document().view()->contentsToWindow(result);
65 }
66
67 static float scoreTouchTarget(IntPoint touchPoint, int padding, IntRect bounding Box)
68 {
69 if (boundingBox.isEmpty())
70 return 0;
71
72 float reciprocalPadding = 1.f / padding;
73 float score = 1;
74
75 IntSize distance = boundingBox.differenceToPoint(touchPoint);
76 score *= std::max((padding - abs(distance.width())) * reciprocalPadding, 0.f );
77 score *= std::max((padding - abs(distance.height())) * reciprocalPadding, 0. f);
78
79 return score;
80 }
81
82 struct TouchTargetData {
83 IntRect windowBoundingBox;
84 float score;
85 };
86
87 void findGoodTouchTargets(const IntRect& touchBox, LocalFrame* mainFrame, Vector <IntRect>& goodTargets, Vector<RawPtr<Node> >& highlightNodes)
88 {
89 goodTargets.clear();
90
91 int touchPointPadding = ceil(std::max(touchBox.width(), touchBox.height()) * 0.5);
92
93 IntPoint touchPoint = touchBox.center();
94 IntPoint contentsPoint = mainFrame->view()->windowToContents(touchPoint);
95
96 HitTestResult result = mainFrame->eventHandler().hitTestResultAtPoint(conten tsPoint, HitTestRequest::ReadOnly | HitTestRequest::Active, IntSize(touchPointPa dding, touchPointPadding));
97 const ListHashSet<RefPtr<Node> >& hitResults = result.rectBasedTestResult();
98
99 // Blacklist nodes that are container of disambiguated nodes.
100 // It is not uncommon to have a clickable <div> that contains other clickabl e objects.
101 // This heuristic avoids excessive disambiguation in that case.
102 HashSet<RawPtr<Node> > blackList;
103 for (ListHashSet<RefPtr<Node> >::const_iterator it = hitResults.begin(); it != hitResults.end(); ++it) {
104 // Ignore any Nodes that can't be clicked on.
105 RenderObject* renderer = it->get()->renderer();
106 if (!renderer || !it->get()->willRespondToMouseClickEvents())
107 continue;
108
109 // Blacklist all of the Node's containers.
110 for (RenderBlock* container = renderer->containingBlock(); container; co ntainer = container->containingBlock()) {
111 Node* containerNode = container->node();
112 if (!containerNode)
113 continue;
114 if (!blackList.add(containerNode).isNewEntry)
115 break;
116 }
117 }
118
119 HashMap<RawPtr<Node>, TouchTargetData> touchTargets;
120 float bestScore = 0;
121 for (ListHashSet<RefPtr<Node> >::const_iterator it = hitResults.begin(); it != hitResults.end(); ++it) {
122 for (Node* node = it->get(); node; node = node->parentNode()) {
123 if (blackList.contains(node))
124 continue;
125 if (node->isDocumentNode())
126 break;
127 if (node->willRespondToMouseClickEvents()) {
128 TouchTargetData& targetData = touchTargets.add(node, TouchTarget Data()).storedValue->value;
129 targetData.windowBoundingBox = boundingBoxForEventNodes(node);
130 targetData.score = scoreTouchTarget(touchPoint, touchPointPaddin g, targetData.windowBoundingBox);
131 bestScore = std::max(bestScore, targetData.score);
132 break;
133 }
134 }
135 }
136
137 for (HashMap<RawPtr<Node>, TouchTargetData>::iterator it = touchTargets.begi n(); it != touchTargets.end(); ++it) {
138 // Currently the scoring function uses the overlap area with the fat poi nt as the score.
139 // We ignore the candidates that has less than 1/2 overlap (we consider not really ambiguous enough) than the best candidate to avoid excessive popups.
140 if (it->value.score < bestScore * 0.5)
141 continue;
142 goodTargets.append(it->value.windowBoundingBox);
143 highlightNodes.append(it->key);
144 }
145 }
146
147 } // namespace blink
OLDNEW
« no previous file with comments | « sky/engine/core/page/TouchDisambiguation.h ('k') | sky/engine/core/page/WindowFocusAllowedIndicator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698