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

Side by Side Diff: WebCore/html/HTMLAnchorElement.cpp

Issue 3366025: Merge 67246 - 2010-09-109 Peter Kasting <pkasting@google.com>... (Closed) Base URL: http://svn.webkit.org/repository/webkit/branches/chromium/517/
Patch Set: Created 10 years, 3 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
« no previous file with comments | « WebCore/html/HTMLAnchorElement.h ('k') | WebCore/svg/SVGAElement.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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) 2000 Simon Hausmann <hausmann@kde.org> 4 * (C) 2000 Simon Hausmann <hausmann@kde.org>
5 * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 5 * Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserv ed.
6 * (C) 2006 Graham Dennis (graham.dennis@gmail.com) 6 * (C) 2006 Graham Dennis (graham.dennis@gmail.com)
7 * 7 *
8 * This library is free software; you can redistribute it and/or 8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public 9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either 10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version. 11 * version 2 of the License, or (at your option) any later version.
12 * 12 *
13 * This library is distributed in the hope that it will be useful, 13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 98
99 if (!document()->frame()) 99 if (!document()->frame())
100 return false; 100 return false;
101 101
102 if (!document()->frame()->eventHandler()->tabsToLinks(event)) 102 if (!document()->frame()->eventHandler()->tabsToLinks(event))
103 return false; 103 return false;
104 104
105 return hasNonEmptyBoundingBox(); 105 return hasNonEmptyBoundingBox();
106 } 106 }
107 107
108 void HTMLAnchorElement::defaultEventHandler(Event* evt) 108 static void appendServerMapMousePosition(String& url, Event* event)
109 { 109 {
110 // React on clicks and on keypresses. 110 if (!event->isMouseEvent())
111 // Don't make this KEYUP_EVENT again, it makes khtml follow links it shouldn 't, 111 return;
112 // when pressing Enter in the combo.
113 if (isLink() && (evt->type() == eventNames().clickEvent || (evt->type() == e ventNames().keydownEvent && focused()))) {
114 MouseEvent* e = 0;
115 if (evt->type() == eventNames().clickEvent && evt->isMouseEvent())
116 e = static_cast<MouseEvent*>(evt);
117 112
118 KeyboardEvent* k = 0; 113 ASSERT(event->target());
119 if (evt->type() == eventNames().keydownEvent && evt->isKeyboardEvent()) 114 Node* target = event->target()->toNode();
120 k = static_cast<KeyboardEvent*>(evt); 115 ASSERT(target);
116 if (!target->hasTagName(imgTag))
117 return;
121 118
122 if (e && e->button() == RightButton) { 119 HTMLImageElement* imageElement = static_cast<HTMLImageElement*>(event->targe t()->toNode());
123 HTMLElement::defaultEventHandler(evt); 120 if (!imageElement || !imageElement->isServerMap())
121 return;
122
123 RenderImage* renderer = toRenderImage(imageElement->renderer());
124 if (!renderer)
125 return;
126
127 // FIXME: This should probably pass true for useTransforms.
128 FloatPoint absolutePosition = renderer->absoluteToLocal(FloatPoint(static_ca st<MouseEvent*>(event)->pageX(), static_cast<MouseEvent*>(event)->pageY()));
129 int x = absolutePosition.x();
130 int y = absolutePosition.y();
131 url += "?";
132 url += String::number(x);
133 url += ",";
134 url += String::number(y);
135 }
136
137 void HTMLAnchorElement::defaultEventHandler(Event* event)
138 {
139 if (isLink()) {
140 if (focused() && isEnterKeyKeydownEvent(event) && treatLinkAsLiveForEven tType(NonMouseEvent)) {
141 event->setDefaultHandled();
142 dispatchSimulatedClick(event);
124 return; 143 return;
125 } 144 }
126 145
127 // If the link is editable, then we need to check the settings to see wh ether or not to follow the link 146 if (isLinkClick(event) && treatLinkAsLiveForEventType(eventType(event))) {
128 if (isContentEditable()) { 147 String url = deprecatedParseURL(getAttribute(hrefAttr));
129 EditableLinkBehavior editableLinkBehavior = EditableLinkDefaultBehav ior; 148 appendServerMapMousePosition(url, event);
130 if (Settings* settings = document()->settings()) 149 handleLinkClick(event, document(), url, getAttribute(targetAttr), ha sRel(RelationNoReferrer));
131 editableLinkBehavior = settings->editableLinkBehavior();
132
133 switch (editableLinkBehavior) {
134 // Always follow the link (Safari 2.0 behavior)
135 default:
136 case EditableLinkDefaultBehavior:
137 case EditableLinkAlwaysLive:
138 break;
139
140 case EditableLinkNeverLive:
141 HTMLElement::defaultEventHandler(evt);
142 return;
143
144 // If the selection prior to clicking on this link resided in th e same editable block as this link,
145 // and the shift key isn't pressed, we don't want to follow the link
146 case EditableLinkLiveWhenNotFocused:
147 if (e && !e->shiftKey() && m_rootEditableElementForSelection OnMouseDown == rootEditableElement()) {
148 HTMLElement::defaultEventHandler(evt);
149 return;
150 }
151 break;
152
153 // Only follow the link if the shift key is down (WinIE/Firefox behavior)
154 case EditableLinkOnlyLiveWithShiftKey:
155 if (e && !e->shiftKey()) {
156 HTMLElement::defaultEventHandler(evt);
157 return;
158 }
159 break;
160 }
161 }
162
163 if (k) {
164 if (k->keyIdentifier() != "Enter") {
165 HTMLElement::defaultEventHandler(evt);
166 return;
167 }
168 evt->setDefaultHandled();
169 dispatchSimulatedClick(evt);
170 return; 150 return;
171 } 151 }
172 152
173 String url = deprecatedParseURL(getAttribute(hrefAttr)); 153 if (isContentEditable()) {
174 154 // This keeps track of the editable block that the selection was in (if it was in one) just before the link was clicked
175 ASSERT(evt->target()); 155 // for the LiveWhenNotFocused editable link behavior
176 ASSERT(evt->target()->toNode()); 156 if (event->type() == eventNames().mousedownEvent && event->isMouseEv ent() && static_cast<MouseEvent*>(event)->button() != RightButton && document()- >frame() && document()->frame()->selection()) {
177 if (evt->target()->toNode()->hasTagName(imgTag)) { 157 m_rootEditableElementForSelectionOnMouseDown = document()->frame ()->selection()->rootEditableElement();
178 HTMLImageElement* img = static_cast<HTMLImageElement*>(evt->target() ->toNode()); 158 m_wasShiftKeyDownOnMouseDown = static_cast<MouseEvent*>(event)-> shiftKey();
179 if (img && img->isServerMap()) { 159 } else if (event->type() == eventNames().mouseoverEvent) {
180 RenderImage* r = toRenderImage(img->renderer()); 160 // These are cleared on mouseover and not mouseout because their values are needed for drag events,
181 if (r && e) { 161 // but drag events happen after mouse out events.
182 // FIXME: broken with transforms 162 m_rootEditableElementForSelectionOnMouseDown = 0;
183 FloatPoint absPos = r->localToAbsolute(); 163 m_wasShiftKeyDownOnMouseDown = false;
184 int x = e->pageX() - absPos.x();
185 int y = e->pageY() - absPos.y();
186 url += "?";
187 url += String::number(x);
188 url += ",";
189 url += String::number(y);
190 } else {
191 evt->setDefaultHandled();
192 HTMLElement::defaultEventHandler(evt);
193 return;
194 }
195 } 164 }
196 } 165 }
197
198 if (!evt->defaultPrevented() && document()->frame())
199 document()->frame()->loader()->urlSelected(document()->completeURL(u rl), getAttribute(targetAttr), evt, false, false, true, hasRel(RelationNoReferre r) ? NoReferrer : SendReferrer);
200
201 evt->setDefaultHandled();
202 } else if (isLink() && isContentEditable()) {
203 // This keeps track of the editable block that the selection was in (if it was in one) just before the link was clicked
204 // for the LiveWhenNotFocused editable link behavior
205 if (evt->type() == eventNames().mousedownEvent && evt->isMouseEvent() && static_cast<MouseEvent*>(evt)->button() != RightButton && document()->frame() & & document()->frame()->selection()) {
206 MouseEvent* e = static_cast<MouseEvent*>(evt);
207
208 m_rootEditableElementForSelectionOnMouseDown = document()->frame()-> selection()->rootEditableElement();
209 m_wasShiftKeyDownOnMouseDown = e && e->shiftKey();
210 } else if (evt->type() == eventNames().mouseoverEvent) {
211 // These are cleared on mouseover and not mouseout because their val ues are needed for drag events, but these happen
212 // after mouse out events.
213 m_rootEditableElementForSelectionOnMouseDown = 0;
214 m_wasShiftKeyDownOnMouseDown = false;
215 }
216 } 166 }
217 167
218 HTMLElement::defaultEventHandler(evt); 168 HTMLElement::defaultEventHandler(event);
219 } 169 }
220 170
221 void HTMLAnchorElement::setActive(bool down, bool pause) 171 void HTMLAnchorElement::setActive(bool down, bool pause)
222 { 172 {
223 if (isContentEditable()) { 173 if (isContentEditable()) {
224 EditableLinkBehavior editableLinkBehavior = EditableLinkDefaultBehavior; 174 EditableLinkBehavior editableLinkBehavior = EditableLinkDefaultBehavior;
225 if (Settings* settings = document()->settings()) 175 if (Settings* settings = document()->settings())
226 editableLinkBehavior = settings->editableLinkBehavior(); 176 editableLinkBehavior = settings->editableLinkBehavior();
227 177
228 switch (editableLinkBehavior) { 178 switch (editableLinkBehavior) {
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 return innerText(); 455 return innerText();
506 } 456 }
507 457
508 String HTMLAnchorElement::toString() const 458 String HTMLAnchorElement::toString() const
509 { 459 {
510 return href().string(); 460 return href().string();
511 } 461 }
512 462
513 bool HTMLAnchorElement::isLiveLink() const 463 bool HTMLAnchorElement::isLiveLink() const
514 { 464 {
515 if (!isLink()) 465 return isLink() && treatLinkAsLiveForEventType(m_wasShiftKeyDownOnMouseDown ? MouseEventWithShiftKey : MouseEventWithoutShiftKey);
516 return false; 466 }
467
468 HTMLAnchorElement::EventType HTMLAnchorElement::eventType(Event* event)
469 {
470 if (!event->isMouseEvent())
471 return NonMouseEvent;
472 return static_cast<MouseEvent*>(event)->shiftKey() ? MouseEventWithShiftKey : MouseEventWithoutShiftKey;
473 }
474
475 bool HTMLAnchorElement::treatLinkAsLiveForEventType(EventType eventType) const
476 {
517 if (!isContentEditable()) 477 if (!isContentEditable())
518 return true; 478 return true;
519
520 EditableLinkBehavior editableLinkBehavior = EditableLinkDefaultBehavior;
521 if (Settings* settings = document()->settings())
522 editableLinkBehavior = settings->editableLinkBehavior();
523
524 switch (editableLinkBehavior) {
525 default:
526 case EditableLinkDefaultBehavior:
527 case EditableLinkAlwaysLive:
528 return true;
529 479
530 case EditableLinkNeverLive: 480 Settings* settings = document()->settings();
531 return false; 481 if (!settings)
482 return true;
532 483
533 // Don't set the link to be live if the current selection is in the same editable block as 484 switch (settings->editableLinkBehavior()) {
534 // this link or if the shift key is down 485 case EditableLinkDefaultBehavior:
535 case EditableLinkLiveWhenNotFocused: 486 case EditableLinkAlwaysLive:
536 return m_wasShiftKeyDownOnMouseDown || m_rootEditableElementForSelec tionOnMouseDown != rootEditableElement(); 487 return true;
537 488
538 case EditableLinkOnlyLiveWithShiftKey: 489 case EditableLinkNeverLive:
539 return m_wasShiftKeyDownOnMouseDown; 490 return false;
491
492 // If the selection prior to clicking on this link resided in the same edita ble block as this link,
493 // and the shift key isn't pressed, we don't want to follow the link.
494 case EditableLinkLiveWhenNotFocused:
495 return eventType == MouseEventWithShiftKey || (eventType == MouseEventWi thoutShiftKey && m_rootEditableElementForSelectionOnMouseDown != rootEditableEle ment());
496
497 case EditableLinkOnlyLiveWithShiftKey:
498 return eventType == MouseEventWithShiftKey;
540 } 499 }
500
501 ASSERT_NOT_REACHED();
502 return false;
503 }
504
505 bool isEnterKeyKeydownEvent(Event* event)
506 {
507 return event->type() == eventNames().keydownEvent && event->isKeyboardEvent( ) && static_cast<KeyboardEvent*>(event)->keyIdentifier() == "Enter";
508 }
509
510 bool isMiddleMouseButtonEvent(Event* event)
511 {
512 return event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == MiddleButton;
513 }
514
515 bool isLinkClick(Event* event)
516 {
517 return event->type() == eventNames().clickEvent && (!event->isMouseEvent() | | static_cast<MouseEvent*>(event)->button() != RightButton);
518 }
519
520 void handleLinkClick(Event* event, Document* document, const String& url, const String& target, bool hideReferrer)
521 {
522 event->setDefaultHandled();
523
524 Frame* frame = document->frame();
525 if (!frame)
526 return;
527 frame->loader()->urlSelected(document->completeURL(url), target, event, fals e, false, true, hideReferrer ? NoReferrer : SendReferrer);
541 } 528 }
542 529
543 } 530 }
OLDNEW
« no previous file with comments | « WebCore/html/HTMLAnchorElement.h ('k') | WebCore/svg/SVGAElement.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698