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

Side by Side Diff: Source/core/html/HTMLAnchorElement.cpp

Issue 236203005: Remove EditableLinkBehavior, which is always set to NeverLive by Chromium. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 8 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 | « Source/core/html/HTMLAnchorElement.h ('k') | Source/core/page/EventHandler.h » ('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, 2010 Apple Inc. All rights reserv ed. 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
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 double m_tapDownTimestamp; 102 double m_tapDownTimestamp;
103 bool m_hadHREFChanged; 103 bool m_hadHREFChanged;
104 bool m_hadTapUnconfirmed; 104 bool m_hadTapUnconfirmed;
105 bool m_hasIssuedPreconnect; 105 bool m_hasIssuedPreconnect;
106 }; 106 };
107 107
108 using namespace HTMLNames; 108 using namespace HTMLNames;
109 109
110 HTMLAnchorElement::HTMLAnchorElement(const QualifiedName& tagName, Document& doc ument) 110 HTMLAnchorElement::HTMLAnchorElement(const QualifiedName& tagName, Document& doc ument)
111 : HTMLElement(tagName, document) 111 : HTMLElement(tagName, document)
112 , m_hasRootEditableElementForSelectionOnMouseDown(false)
113 , m_wasShiftKeyDownOnMouseDown(false)
114 , m_linkRelations(0) 112 , m_linkRelations(0)
115 , m_cachedVisitedLinkHash(0) 113 , m_cachedVisitedLinkHash(0)
116 { 114 {
117 ScriptWrappable::init(this); 115 ScriptWrappable::init(this);
118 } 116 }
119 117
120 PassRefPtr<HTMLAnchorElement> HTMLAnchorElement::create(Document& document) 118 PassRefPtr<HTMLAnchorElement> HTMLAnchorElement::create(Document& document)
121 { 119 {
122 return adoptRef(new HTMLAnchorElement(aTag, document)); 120 return adoptRef(new HTMLAnchorElement(aTag, document));
123 } 121 }
124 122
125 PassRefPtr<HTMLAnchorElement> HTMLAnchorElement::create(const QualifiedName& tag Name, Document& document) 123 PassRefPtr<HTMLAnchorElement> HTMLAnchorElement::create(const QualifiedName& tag Name, Document& document)
126 { 124 {
127 return adoptRef(new HTMLAnchorElement(tagName, document)); 125 return adoptRef(new HTMLAnchorElement(tagName, document));
128 } 126 }
129 127
130 HTMLAnchorElement::~HTMLAnchorElement() 128 HTMLAnchorElement::~HTMLAnchorElement()
131 { 129 {
132 clearRootEditableElementForSelectionOnMouseDown();
133 } 130 }
134 131
135 bool HTMLAnchorElement::supportsFocus() const 132 bool HTMLAnchorElement::supportsFocus() const
136 { 133 {
137 if (rendererIsEditable()) 134 if (rendererIsEditable())
138 return HTMLElement::supportsFocus(); 135 return HTMLElement::supportsFocus();
139 // If not a link we should still be able to focus the element if it has tabI ndex. 136 // If not a link we should still be able to focus the element if it has tabI ndex.
140 return isLink() || HTMLElement::supportsFocus(); 137 return isLink() || HTMLElement::supportsFocus();
141 } 138 }
142 139
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 int y = absolutePosition.y(); 184 int y = absolutePosition.y();
188 url.append('?'); 185 url.append('?');
189 url.appendNumber(x); 186 url.appendNumber(x);
190 url.append(','); 187 url.append(',');
191 url.appendNumber(y); 188 url.appendNumber(y);
192 } 189 }
193 190
194 void HTMLAnchorElement::defaultEventHandler(Event* event) 191 void HTMLAnchorElement::defaultEventHandler(Event* event)
195 { 192 {
196 if (isLink()) { 193 if (isLink()) {
197 if (focused() && isEnterKeyKeydownEvent(event) && treatLinkAsLiveForEven tType(NonMouseEvent)) { 194 if (focused() && isEnterKeyKeydownEvent(event) && isLiveLink()) {
198 event->setDefaultHandled(); 195 event->setDefaultHandled();
199 dispatchSimulatedClick(event); 196 dispatchSimulatedClick(event);
200 return; 197 return;
201 } 198 }
202 199
203 prefetchEventHandler()->handleEvent(event); 200 prefetchEventHandler()->handleEvent(event);
204 201
205 if (isLinkClick(event) && treatLinkAsLiveForEventType(eventType(event))) { 202 if (isLinkClick(event) && isLiveLink()) {
206 handleClick(event); 203 handleClick(event);
207 prefetchEventHandler()->reset(); 204 prefetchEventHandler()->reset();
208 return; 205 return;
209 } 206 }
210
211 if (rendererIsEditable()) {
212 // This keeps track of the editable block that the selection was in (if it was in one) just before the link was clicked
213 // for the LiveWhenNotFocused editable link behavior
214 if (event->type() == EventTypeNames::mousedown && event->isMouseEven t() && toMouseEvent(event)->button() != RightButton && document().frame()) {
215 setRootEditableElementForSelectionOnMouseDown(document().frame() ->selection().rootEditableElement());
216 m_wasShiftKeyDownOnMouseDown = toMouseEvent(event)->shiftKey();
217 } else if (event->type() == EventTypeNames::mouseover) {
218 // These are cleared on mouseover and not mouseout because their values are needed for drag events,
219 // but drag events happen after mouse out events.
220 clearRootEditableElementForSelectionOnMouseDown();
221 m_wasShiftKeyDownOnMouseDown = false;
222 }
223 }
224 } 207 }
225 208
226 HTMLElement::defaultEventHandler(event); 209 HTMLElement::defaultEventHandler(event);
227 } 210 }
228 211
229 void HTMLAnchorElement::setActive(bool down) 212 void HTMLAnchorElement::setActive(bool down)
230 { 213 {
231 if (rendererIsEditable()) { 214 if (rendererIsEditable())
232 EditableLinkBehavior editableLinkBehavior = EditableLinkDefaultBehavior; 215 return;
233 if (Settings* settings = document().settings())
234 editableLinkBehavior = settings->editableLinkBehavior();
235
236 switch (editableLinkBehavior) {
237 default:
238 case EditableLinkDefaultBehavior:
239 case EditableLinkAlwaysLive:
240 break;
241
242 case EditableLinkNeverLive:
243 return;
244
245 // Don't set the link to be active if the current selection is in th e same editable block as
246 // this link
247 case EditableLinkLiveWhenNotFocused:
248 if (down && document().frame() && document().frame()->selection( ).rootEditableElement() == rootEditableElement())
249 return;
250 break;
251
252 case EditableLinkOnlyLiveWithShiftKey:
253 return;
254 }
255
256 }
257 216
258 ContainerNode::setActive(down); 217 ContainerNode::setActive(down);
259 } 218 }
260 219
261 void HTMLAnchorElement::parseAttribute(const QualifiedName& name, const AtomicSt ring& value) 220 void HTMLAnchorElement::parseAttribute(const QualifiedName& name, const AtomicSt ring& value)
262 { 221 {
263 if (name == hrefAttr) { 222 if (name == hrefAttr) {
264 bool wasLink = isLink(); 223 bool wasLink = isLink();
265 setIsLink(!value.isNull()); 224 setIsLink(!value.isNull());
266 if (wasLink != isLink()) { 225 if (wasLink != isLink()) {
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 } 344 }
386 345
387 346
388 String HTMLAnchorElement::text() 347 String HTMLAnchorElement::text()
389 { 348 {
390 return innerText(); 349 return innerText();
391 } 350 }
392 351
393 bool HTMLAnchorElement::isLiveLink() const 352 bool HTMLAnchorElement::isLiveLink() const
394 { 353 {
395 return isLink() && treatLinkAsLiveForEventType(m_wasShiftKeyDownOnMouseDown ? MouseEventWithShiftKey : MouseEventWithoutShiftKey); 354 return isLink() && !rendererIsEditable();
396 } 355 }
397 356
398 void HTMLAnchorElement::sendPings(const KURL& destinationURL) 357 void HTMLAnchorElement::sendPings(const KURL& destinationURL)
399 { 358 {
400 const AtomicString& pingValue = getAttribute(pingAttr); 359 const AtomicString& pingValue = getAttribute(pingAttr);
401 if (pingValue.isNull() || !document().settings() || !document().settings()-> hyperlinkAuditingEnabled()) 360 if (pingValue.isNull() || !document().settings() || !document().settings()-> hyperlinkAuditingEnabled())
402 return; 361 return;
403 362
404 UseCounter::count(document(), UseCounter::HTMLAnchorElementPingAttribute); 363 UseCounter::count(document(), UseCounter::HTMLAnchorElementPingAttribute);
405 364
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 frame->loader().client()->loadURLExternally(request, NavigationPolicyDow nload, fastGetAttribute(downloadAttr)); 397 frame->loader().client()->loadURLExternally(request, NavigationPolicyDow nload, fastGetAttribute(downloadAttr));
439 } else { 398 } else {
440 FrameLoadRequest frameRequest(&document(), request, target()); 399 FrameLoadRequest frameRequest(&document(), request, target());
441 frameRequest.setTriggeringEvent(event); 400 frameRequest.setTriggeringEvent(event);
442 if (hasRel(RelationNoReferrer)) 401 if (hasRel(RelationNoReferrer))
443 frameRequest.setShouldSendReferrer(NeverSendReferrer); 402 frameRequest.setShouldSendReferrer(NeverSendReferrer);
444 frame->loader().load(frameRequest); 403 frame->loader().load(frameRequest);
445 } 404 }
446 } 405 }
447 406
448 HTMLAnchorElement::EventType HTMLAnchorElement::eventType(Event* event)
449 {
450 if (!event->isMouseEvent())
451 return NonMouseEvent;
452 return toMouseEvent(event)->shiftKey() ? MouseEventWithShiftKey : MouseEvent WithoutShiftKey;
453 }
454
455 bool HTMLAnchorElement::treatLinkAsLiveForEventType(EventType eventType) const
456 {
457 if (!rendererIsEditable())
458 return true;
459
460 Settings* settings = document().settings();
461 if (!settings)
462 return true;
463
464 switch (settings->editableLinkBehavior()) {
465 case EditableLinkDefaultBehavior:
466 case EditableLinkAlwaysLive:
467 return true;
468
469 case EditableLinkNeverLive:
470 return false;
471
472 // If the selection prior to clicking on this link resided in the same edita ble block as this link,
473 // and the shift key isn't pressed, we don't want to follow the link.
474 case EditableLinkLiveWhenNotFocused:
475 return eventType == MouseEventWithShiftKey || (eventType == MouseEventWi thoutShiftKey && rootEditableElementForSelectionOnMouseDown() != rootEditableEle ment());
476
477 case EditableLinkOnlyLiveWithShiftKey:
478 return eventType == MouseEventWithShiftKey;
479 }
480
481 ASSERT_NOT_REACHED();
482 return false;
483 }
484
485 bool isEnterKeyKeydownEvent(Event* event) 407 bool isEnterKeyKeydownEvent(Event* event)
486 { 408 {
487 return event->type() == EventTypeNames::keydown && event->isKeyboardEvent() && toKeyboardEvent(event)->keyIdentifier() == "Enter"; 409 return event->type() == EventTypeNames::keydown && event->isKeyboardEvent() && toKeyboardEvent(event)->keyIdentifier() == "Enter";
488 } 410 }
489 411
490 bool isLinkClick(Event* event) 412 bool isLinkClick(Event* event)
491 { 413 {
492 return event->type() == EventTypeNames::click && (!event->isMouseEvent() || toMouseEvent(event)->button() != RightButton); 414 return event->type() == EventTypeNames::click && (!event->isMouseEvent() || toMouseEvent(event)->button() != RightButton);
493 } 415 }
494 416
495 bool HTMLAnchorElement::willRespondToMouseClickEvents() 417 bool HTMLAnchorElement::willRespondToMouseClickEvents()
496 { 418 {
497 return isLink() || HTMLElement::willRespondToMouseClickEvents(); 419 return isLink() || HTMLElement::willRespondToMouseClickEvents();
498 } 420 }
499 421
500 typedef HashMap<const HTMLAnchorElement*, RefPtr<Element> > RootEditableElementM ap;
501
502 static RootEditableElementMap& rootEditableElementMap()
503 {
504 DEFINE_STATIC_LOCAL(RootEditableElementMap, map, ());
505 return map;
506 }
507
508 Element* HTMLAnchorElement::rootEditableElementForSelectionOnMouseDown() const
509 {
510 if (!m_hasRootEditableElementForSelectionOnMouseDown)
511 return 0;
512 return rootEditableElementMap().get(this);
513 }
514
515 void HTMLAnchorElement::clearRootEditableElementForSelectionOnMouseDown()
516 {
517 if (!m_hasRootEditableElementForSelectionOnMouseDown)
518 return;
519 rootEditableElementMap().remove(this);
520 m_hasRootEditableElementForSelectionOnMouseDown = false;
521 }
522
523 void HTMLAnchorElement::setRootEditableElementForSelectionOnMouseDown(Element* e lement)
524 {
525 if (!element) {
526 clearRootEditableElementForSelectionOnMouseDown();
527 return;
528 }
529
530 rootEditableElementMap().set(this, element);
531 m_hasRootEditableElementForSelectionOnMouseDown = true;
532 }
533
534 HTMLAnchorElement::PrefetchEventHandler* HTMLAnchorElement::prefetchEventHandler () 422 HTMLAnchorElement::PrefetchEventHandler* HTMLAnchorElement::prefetchEventHandler ()
535 { 423 {
536 if (!m_prefetchEventHandler) 424 if (!m_prefetchEventHandler)
537 m_prefetchEventHandler = PrefetchEventHandler::create(this); 425 m_prefetchEventHandler = PrefetchEventHandler::create(this);
538 426
539 return m_prefetchEventHandler.get(); 427 return m_prefetchEventHandler.get();
540 } 428 }
541 429
542 HTMLAnchorElement::PrefetchEventHandler::PrefetchEventHandler(HTMLAnchorElement* anchorElement) 430 HTMLAnchorElement::PrefetchEventHandler::PrefetchEventHandler(HTMLAnchorElement* anchorElement)
543 : m_anchorElement(anchorElement) 431 : m_anchorElement(anchorElement)
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
697 preconnectToURL(url, motivation); 585 preconnectToURL(url, motivation);
698 m_hasIssuedPreconnect = true; 586 m_hasIssuedPreconnect = true;
699 } 587 }
700 588
701 bool HTMLAnchorElement::isInteractiveContent() const 589 bool HTMLAnchorElement::isInteractiveContent() const
702 { 590 {
703 return isLink(); 591 return isLink();
704 } 592 }
705 593
706 } 594 }
OLDNEW
« no previous file with comments | « Source/core/html/HTMLAnchorElement.h ('k') | Source/core/page/EventHandler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698