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) 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 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 } | 162 } |
163 | 163 |
164 bool HTMLAnchorElement::isKeyboardFocusable() const | 164 bool HTMLAnchorElement::isKeyboardFocusable() const |
165 { | 165 { |
166 if (!isLink()) | 166 if (!isLink()) |
167 return HTMLElement::isKeyboardFocusable(); | 167 return HTMLElement::isKeyboardFocusable(); |
168 | 168 |
169 if (!isFocusable()) | 169 if (!isFocusable()) |
170 return false; | 170 return false; |
171 | 171 |
172 Page* page = document()->page(); | 172 Page* page = document().page(); |
173 if (!page) | 173 if (!page) |
174 return false; | 174 return false; |
175 | 175 |
176 if (!page->chrome().client().tabsToLinks()) | 176 if (!page->chrome().client().tabsToLinks()) |
177 return false; | 177 return false; |
178 | 178 |
179 if (isInCanvasSubtree()) | 179 if (isInCanvasSubtree()) |
180 return true; | 180 return true; |
181 | 181 |
182 return hasNonEmptyBoundingBox(); | 182 return hasNonEmptyBoundingBox(); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 | 224 |
225 if (isLinkClick(event) && treatLinkAsLiveForEventType(eventType(event)))
{ | 225 if (isLinkClick(event) && treatLinkAsLiveForEventType(eventType(event)))
{ |
226 handleClick(event); | 226 handleClick(event); |
227 prefetchEventHandler()->reset(); | 227 prefetchEventHandler()->reset(); |
228 return; | 228 return; |
229 } | 229 } |
230 | 230 |
231 if (rendererIsEditable()) { | 231 if (rendererIsEditable()) { |
232 // This keeps track of the editable block that the selection was in
(if it was in one) just before the link was clicked | 232 // This keeps track of the editable block that the selection was in
(if it was in one) just before the link was clicked |
233 // for the LiveWhenNotFocused editable link behavior | 233 // for the LiveWhenNotFocused editable link behavior |
234 if (event->type() == eventNames().mousedownEvent && event->isMouseEv
ent() && toMouseEvent(event)->button() != RightButton && document()->frame() &&
document()->frame()->selection()) { | 234 if (event->type() == eventNames().mousedownEvent && event->isMouseEv
ent() && toMouseEvent(event)->button() != RightButton && document().frame() && d
ocument().frame()->selection()) { |
235 setRootEditableElementForSelectionOnMouseDown(document()->frame(
)->selection()->rootEditableElement()); | 235 setRootEditableElementForSelectionOnMouseDown(document().frame()
->selection()->rootEditableElement()); |
236 m_wasShiftKeyDownOnMouseDown = toMouseEvent(event)->shiftKey(); | 236 m_wasShiftKeyDownOnMouseDown = toMouseEvent(event)->shiftKey(); |
237 } else if (event->type() == eventNames().mouseoverEvent) { | 237 } else if (event->type() == eventNames().mouseoverEvent) { |
238 // These are cleared on mouseover and not mouseout because their
values are needed for drag events, | 238 // These are cleared on mouseover and not mouseout because their
values are needed for drag events, |
239 // but drag events happen after mouse out events. | 239 // but drag events happen after mouse out events. |
240 clearRootEditableElementForSelectionOnMouseDown(); | 240 clearRootEditableElementForSelectionOnMouseDown(); |
241 m_wasShiftKeyDownOnMouseDown = false; | 241 m_wasShiftKeyDownOnMouseDown = false; |
242 } | 242 } |
243 } | 243 } |
244 } | 244 } |
245 | 245 |
246 HTMLElement::defaultEventHandler(event); | 246 HTMLElement::defaultEventHandler(event); |
247 } | 247 } |
248 | 248 |
249 void HTMLAnchorElement::setActive(bool down, bool pause) | 249 void HTMLAnchorElement::setActive(bool down, bool pause) |
250 { | 250 { |
251 if (rendererIsEditable()) { | 251 if (rendererIsEditable()) { |
252 EditableLinkBehavior editableLinkBehavior = EditableLinkDefaultBehavior; | 252 EditableLinkBehavior editableLinkBehavior = EditableLinkDefaultBehavior; |
253 if (Settings* settings = document()->settings()) | 253 if (Settings* settings = document().settings()) |
254 editableLinkBehavior = settings->editableLinkBehavior(); | 254 editableLinkBehavior = settings->editableLinkBehavior(); |
255 | 255 |
256 switch (editableLinkBehavior) { | 256 switch (editableLinkBehavior) { |
257 default: | 257 default: |
258 case EditableLinkDefaultBehavior: | 258 case EditableLinkDefaultBehavior: |
259 case EditableLinkAlwaysLive: | 259 case EditableLinkAlwaysLive: |
260 break; | 260 break; |
261 | 261 |
262 case EditableLinkNeverLive: | 262 case EditableLinkNeverLive: |
263 return; | 263 return; |
264 | 264 |
265 // Don't set the link to be active if the current selection is in th
e same editable block as | 265 // Don't set the link to be active if the current selection is in th
e same editable block as |
266 // this link | 266 // this link |
267 case EditableLinkLiveWhenNotFocused: | 267 case EditableLinkLiveWhenNotFocused: |
268 if (down && document()->frame() && document()->frame()->selectio
n()->rootEditableElement() == rootEditableElement()) | 268 if (down && document().frame() && document().frame()->selection(
)->rootEditableElement() == rootEditableElement()) |
269 return; | 269 return; |
270 break; | 270 break; |
271 | 271 |
272 case EditableLinkOnlyLiveWithShiftKey: | 272 case EditableLinkOnlyLiveWithShiftKey: |
273 return; | 273 return; |
274 } | 274 } |
275 | 275 |
276 } | 276 } |
277 | 277 |
278 ContainerNode::setActive(down, pause); | 278 ContainerNode::setActive(down, pause); |
279 } | 279 } |
280 | 280 |
281 void HTMLAnchorElement::parseAttribute(const QualifiedName& name, const AtomicSt
ring& value) | 281 void HTMLAnchorElement::parseAttribute(const QualifiedName& name, const AtomicSt
ring& value) |
282 { | 282 { |
283 if (name == hrefAttr) { | 283 if (name == hrefAttr) { |
284 bool wasLink = isLink(); | 284 bool wasLink = isLink(); |
285 setIsLink(!value.isNull()); | 285 setIsLink(!value.isNull()); |
286 if (wasLink != isLink()) { | 286 if (wasLink != isLink()) { |
287 didAffectSelector(AffectedSelectorLink | AffectedSelectorVisited | A
ffectedSelectorEnabled); | 287 didAffectSelector(AffectedSelectorLink | AffectedSelectorVisited | A
ffectedSelectorEnabled); |
288 if (wasLink && treeScope()->adjustedFocusedElement() == this) { | 288 if (wasLink && treeScope()->adjustedFocusedElement() == this) { |
289 // We might want to call blur(), but it's dangerous to dispatch | 289 // We might want to call blur(), but it's dangerous to dispatch |
290 // events here. | 290 // events here. |
291 document()->setNeedsFocusedElementCheck(); | 291 document().setNeedsFocusedElementCheck(); |
292 } | 292 } |
293 } | 293 } |
294 if (isLink()) { | 294 if (isLink()) { |
295 String parsedURL = stripLeadingAndTrailingHTMLSpaces(value); | 295 String parsedURL = stripLeadingAndTrailingHTMLSpaces(value); |
296 if (document()->isDNSPrefetchEnabled()) { | 296 if (document().isDNSPrefetchEnabled()) { |
297 if (protocolIs(parsedURL, "http") || protocolIs(parsedURL, "http
s") || parsedURL.startsWith("//")) | 297 if (protocolIs(parsedURL, "http") || protocolIs(parsedURL, "http
s") || parsedURL.startsWith("//")) |
298 prefetchDNS(document()->completeURL(parsedURL).host()); | 298 prefetchDNS(document().completeURL(parsedURL).host()); |
299 } | 299 } |
300 | 300 |
301 if (wasLink) | 301 if (wasLink) |
302 prefetchEventHandler()->didChangeHREF(); | 302 prefetchEventHandler()->didChangeHREF(); |
303 } | 303 } |
304 invalidateCachedVisitedLinkHash(); | 304 invalidateCachedVisitedLinkHash(); |
305 } else if (name == nameAttr || name == titleAttr) { | 305 } else if (name == nameAttr || name == titleAttr) { |
306 // Do nothing. | 306 // Do nothing. |
307 } else if (name == relAttr) | 307 } else if (name == relAttr) |
308 setRel(value); | 308 setRel(value); |
(...skipping 25 matching lines...) Expand all Loading... |
334 const AtomicString& value = getAttribute(draggableAttr); | 334 const AtomicString& value = getAttribute(draggableAttr); |
335 if (equalIgnoringCase(value, "true")) | 335 if (equalIgnoringCase(value, "true")) |
336 return true; | 336 return true; |
337 if (equalIgnoringCase(value, "false")) | 337 if (equalIgnoringCase(value, "false")) |
338 return false; | 338 return false; |
339 return hasAttribute(hrefAttr); | 339 return hasAttribute(hrefAttr); |
340 } | 340 } |
341 | 341 |
342 KURL HTMLAnchorElement::href() const | 342 KURL HTMLAnchorElement::href() const |
343 { | 343 { |
344 return document()->completeURL(stripLeadingAndTrailingHTMLSpaces(getAttribut
e(hrefAttr))); | 344 return document().completeURL(stripLeadingAndTrailingHTMLSpaces(getAttribute
(hrefAttr))); |
345 } | 345 } |
346 | 346 |
347 void HTMLAnchorElement::setHref(const AtomicString& value) | 347 void HTMLAnchorElement::setHref(const AtomicString& value) |
348 { | 348 { |
349 setAttribute(hrefAttr, value); | 349 setAttribute(hrefAttr, value); |
350 } | 350 } |
351 | 351 |
352 bool HTMLAnchorElement::hasRel(uint32_t relation) const | 352 bool HTMLAnchorElement::hasRel(uint32_t relation) const |
353 { | 353 { |
354 return m_linkRelations & relation; | 354 return m_linkRelations & relation; |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
553 return href().string(); | 553 return href().string(); |
554 } | 554 } |
555 | 555 |
556 bool HTMLAnchorElement::isLiveLink() const | 556 bool HTMLAnchorElement::isLiveLink() const |
557 { | 557 { |
558 return isLink() && treatLinkAsLiveForEventType(m_wasShiftKeyDownOnMouseDown
? MouseEventWithShiftKey : MouseEventWithoutShiftKey); | 558 return isLink() && treatLinkAsLiveForEventType(m_wasShiftKeyDownOnMouseDown
? MouseEventWithShiftKey : MouseEventWithoutShiftKey); |
559 } | 559 } |
560 | 560 |
561 void HTMLAnchorElement::sendPings(const KURL& destinationURL) | 561 void HTMLAnchorElement::sendPings(const KURL& destinationURL) |
562 { | 562 { |
563 if (!hasAttribute(pingAttr) || !document()->settings() || !document()->setti
ngs()->hyperlinkAuditingEnabled()) | 563 if (!hasAttribute(pingAttr) || !document().settings() || !document().setting
s()->hyperlinkAuditingEnabled()) |
564 return; | 564 return; |
565 | 565 |
566 SpaceSplitString pingURLs(getAttribute(pingAttr), false); | 566 SpaceSplitString pingURLs(getAttribute(pingAttr), false); |
567 for (unsigned i = 0; i < pingURLs.size(); i++) | 567 for (unsigned i = 0; i < pingURLs.size(); i++) |
568 PingLoader::sendPing(document()->frame(), document()->completeURL(pingUR
Ls[i]), destinationURL); | 568 PingLoader::sendPing(document().frame(), document().completeURL(pingURLs
[i]), destinationURL); |
569 } | 569 } |
570 | 570 |
571 void HTMLAnchorElement::handleClick(Event* event) | 571 void HTMLAnchorElement::handleClick(Event* event) |
572 { | 572 { |
573 event->setDefaultHandled(); | 573 event->setDefaultHandled(); |
574 | 574 |
575 Frame* frame = document()->frame(); | 575 Frame* frame = document().frame(); |
576 if (!frame) | 576 if (!frame) |
577 return; | 577 return; |
578 | 578 |
579 StringBuilder url; | 579 StringBuilder url; |
580 url.append(stripLeadingAndTrailingHTMLSpaces(fastGetAttribute(hrefAttr))); | 580 url.append(stripLeadingAndTrailingHTMLSpaces(fastGetAttribute(hrefAttr))); |
581 appendServerMapMousePosition(url, event); | 581 appendServerMapMousePosition(url, event); |
582 KURL completedURL = document()->completeURL(url.toString()); | 582 KURL completedURL = document().completeURL(url.toString()); |
583 | 583 |
584 ResourceRequest request(completedURL); | 584 ResourceRequest request(completedURL); |
585 if (prefetchEventHandler()->hasIssuedPreconnect()) | 585 if (prefetchEventHandler()->hasIssuedPreconnect()) |
586 frame->loader()->client()->dispatchWillRequestAfterPreconnect(request); | 586 frame->loader()->client()->dispatchWillRequestAfterPreconnect(request); |
587 if (hasAttribute(downloadAttr)) { | 587 if (hasAttribute(downloadAttr)) { |
588 if (!hasRel(RelationNoReferrer)) { | 588 if (!hasRel(RelationNoReferrer)) { |
589 String referrer = SecurityPolicy::generateReferrerHeader(document()-
>referrerPolicy(), completedURL, frame->loader()->outgoingReferrer()); | 589 String referrer = SecurityPolicy::generateReferrerHeader(document().
referrerPolicy(), completedURL, frame->loader()->outgoingReferrer()); |
590 if (!referrer.isEmpty()) | 590 if (!referrer.isEmpty()) |
591 request.setHTTPReferrer(referrer); | 591 request.setHTTPReferrer(referrer); |
592 } | 592 } |
593 | 593 |
594 frame->loader()->client()->loadURLExternally(request, NavigationPolicyDo
wnload, fastGetAttribute(downloadAttr)); | 594 frame->loader()->client()->loadURLExternally(request, NavigationPolicyDo
wnload, fastGetAttribute(downloadAttr)); |
595 } else { | 595 } else { |
596 FrameLoadRequest frameRequest(document()->securityOrigin(), request, tar
get()); | 596 FrameLoadRequest frameRequest(document().securityOrigin(), request, targ
et()); |
597 frameRequest.setTriggeringEvent(event); | 597 frameRequest.setTriggeringEvent(event); |
598 if (hasRel(RelationNoReferrer)) | 598 if (hasRel(RelationNoReferrer)) |
599 frameRequest.setShouldSendReferrer(NeverSendReferrer); | 599 frameRequest.setShouldSendReferrer(NeverSendReferrer); |
600 frame->loader()->load(frameRequest); | 600 frame->loader()->load(frameRequest); |
601 } | 601 } |
602 | 602 |
603 sendPings(completedURL); | 603 sendPings(completedURL); |
604 } | 604 } |
605 | 605 |
606 HTMLAnchorElement::EventType HTMLAnchorElement::eventType(Event* event) | 606 HTMLAnchorElement::EventType HTMLAnchorElement::eventType(Event* event) |
607 { | 607 { |
608 if (!event->isMouseEvent()) | 608 if (!event->isMouseEvent()) |
609 return NonMouseEvent; | 609 return NonMouseEvent; |
610 return toMouseEvent(event)->shiftKey() ? MouseEventWithShiftKey : MouseEvent
WithoutShiftKey; | 610 return toMouseEvent(event)->shiftKey() ? MouseEventWithShiftKey : MouseEvent
WithoutShiftKey; |
611 } | 611 } |
612 | 612 |
613 bool HTMLAnchorElement::treatLinkAsLiveForEventType(EventType eventType) const | 613 bool HTMLAnchorElement::treatLinkAsLiveForEventType(EventType eventType) const |
614 { | 614 { |
615 if (!rendererIsEditable()) | 615 if (!rendererIsEditable()) |
616 return true; | 616 return true; |
617 | 617 |
618 Settings* settings = document()->settings(); | 618 Settings* settings = document().settings(); |
619 if (!settings) | 619 if (!settings) |
620 return true; | 620 return true; |
621 | 621 |
622 switch (settings->editableLinkBehavior()) { | 622 switch (settings->editableLinkBehavior()) { |
623 case EditableLinkDefaultBehavior: | 623 case EditableLinkDefaultBehavior: |
624 case EditableLinkAlwaysLive: | 624 case EditableLinkAlwaysLive: |
625 return true; | 625 return true; |
626 | 626 |
627 case EditableLinkNeverLive: | 627 case EditableLinkNeverLive: |
628 return false; | 628 return false; |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
815 { | 815 { |
816 if (m_hadHREFChanged) | 816 if (m_hadHREFChanged) |
817 return false; | 817 return false; |
818 | 818 |
819 if (m_anchorElement->hasEventListeners(eventNames().clickEvent)) | 819 if (m_anchorElement->hasEventListeners(eventNames().clickEvent)) |
820 return false; | 820 return false; |
821 | 821 |
822 if (!url.protocolIsInHTTPFamily()) | 822 if (!url.protocolIsInHTTPFamily()) |
823 return false; | 823 return false; |
824 | 824 |
825 Document* document = m_anchorElement->document(); | 825 Document& document = m_anchorElement->document(); |
826 if (!document) | 826 |
| 827 if (!document.securityOrigin()->canDisplay(url)) |
827 return false; | 828 return false; |
828 | 829 |
829 if (!document->securityOrigin()->canDisplay(url)) | 830 if (url.hasFragmentIdentifier() && equalIgnoringFragmentIdentifier(document.
url(), url)) |
830 return false; | 831 return false; |
831 | 832 |
832 if (url.hasFragmentIdentifier() && equalIgnoringFragmentIdentifier(document-
>url(), url)) | 833 Frame* frame = document.frame(); |
833 return false; | |
834 | |
835 Frame* frame = document->frame(); | |
836 if (!frame) | 834 if (!frame) |
837 return false; | 835 return false; |
838 | 836 |
839 // Links which create new window/tab are avoided because they may require us
er approval interaction. | 837 // Links which create new window/tab are avoided because they may require us
er approval interaction. |
840 if (!m_anchorElement->target().isEmpty()) | 838 if (!m_anchorElement->target().isEmpty()) |
841 return false; | 839 return false; |
842 | 840 |
843 return true; | 841 return true; |
844 } | 842 } |
845 | 843 |
846 void HTMLAnchorElement::PrefetchEventHandler::prefetch(WebKit::WebPreconnectMoti
vation motivation) | 844 void HTMLAnchorElement::PrefetchEventHandler::prefetch(WebKit::WebPreconnectMoti
vation motivation) |
847 { | 845 { |
848 const KURL& url = m_anchorElement->href(); | 846 const KURL& url = m_anchorElement->href(); |
849 | 847 |
850 if (!shouldPrefetch(url)) | 848 if (!shouldPrefetch(url)) |
851 return; | 849 return; |
852 | 850 |
853 // The precision of current MouseOver trigger is too low to actually trigger
preconnects. | 851 // The precision of current MouseOver trigger is too low to actually trigger
preconnects. |
854 if (motivation == WebKit::WebPreconnectMotivationLinkMouseOver) | 852 if (motivation == WebKit::WebPreconnectMotivationLinkMouseOver) |
855 return; | 853 return; |
856 | 854 |
857 preconnectToURL(url, motivation); | 855 preconnectToURL(url, motivation); |
858 m_hasIssuedPreconnect = true; | 856 m_hasIssuedPreconnect = true; |
859 } | 857 } |
860 | 858 |
861 } | 859 } |
OLD | NEW |