18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (C) 1999 Antti Koivisto (koivisto@kde.org) 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (C) 2000 Simon Hausmann <hausmann@kde.org> 568513a70bcd92384395513322f1b801e7bf9c729Steve Block * Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (C) 2006 Graham Dennis (graham.dennis@gmail.com) 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version. 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful, 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details. 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB. If not, write to 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA. 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLAnchorElement.h" 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 27e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block#include "Attribute.h" 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "EventNames.h" 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Frame.h" 30cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#include "FrameLoaderTypes.h" 318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLImageElement.h" 328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLNames.h" 33a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "HTMLParserIdioms.h" 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "KeyboardEvent.h" 358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "MouseEvent.h" 368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "Page.h" 37bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#include "PingLoader.h" 388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderImage.h" 39dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "ResourceHandle.h" 408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Settings.h" 41a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "UserGestureIndicator.h" 428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore { 448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace HTMLNames; 468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockHTMLAnchorElement::HTMLAnchorElement(const QualifiedName& tagName, Document* document) 4806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen : HTMLElement(tagName, document) 498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_wasShiftKeyDownOnMouseDown(false) 50cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block , m_linkRelations(0) 518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 54231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockPassRefPtr<HTMLAnchorElement> HTMLAnchorElement::create(Document* document) 558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 56231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return adoptRef(new HTMLAnchorElement(aTag, document)); 578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 59231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockPassRefPtr<HTMLAnchorElement> HTMLAnchorElement::create(const QualifiedName& tagName, Document* document) 608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 61231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return adoptRef(new HTMLAnchorElement(tagName, document)); 628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 64643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// This function does not allow leading spaces before the port number. 65643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic unsigned parsePortFromStringPosition(const String& value, unsigned portStart, unsigned& portEnd) 66643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 67643ca7872b450ea4efacab6188849e5aac2ba161Steve Block portEnd = portStart; 68643ca7872b450ea4efacab6188849e5aac2ba161Steve Block while (isASCIIDigit(value[portEnd])) 69643ca7872b450ea4efacab6188849e5aac2ba161Steve Block ++portEnd; 70643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return value.substring(portStart, portEnd - portStart).toUInt(); 71643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 72643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 73231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockbool HTMLAnchorElement::supportsFocus() const 748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 752bde8e466a4451c7319e3a072d118917957d6554Steve Block if (rendererIsEditable()) 76231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return HTMLElement::supportsFocus(); 77231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // If not a link we should still be able to focus the element if it has tabIndex. 78231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return isLink() || HTMLElement::supportsFocus(); 798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLAnchorElement::isMouseFocusable() const 828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 83231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Anchor elements should be mouse focusable, https://bugs.webkit.org/show_bug.cgi?id=26856 84e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block#if !PLATFORM(GTK) && !PLATFORM(QT) && !PLATFORM(EFL) 85231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (isLink()) 86643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // Only allow links with tabIndex or contentEditable to be mouse focusable. 87643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return HTMLElement::supportsFocus(); 888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 89643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 90231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Allow tab index etc to control focus. 91231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return HTMLElement::isMouseFocusable(); 928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLAnchorElement::isKeyboardFocusable(KeyboardEvent* event) const 958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 96231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!isLink()) 97231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return HTMLElement::isKeyboardFocusable(event); 98231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!isFocusable()) 1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!document()->frame()) 1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!document()->frame()->eventHandler()->tabsToLinks(event)) 1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 10821939df44de1705786c545cd1bf519d47250322dBen Murdoch return hasNonEmptyBoundingBox(); 1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11168513a70bcd92384395513322f1b801e7bf9c729Steve Blockstatic void appendServerMapMousePosition(String& url, Event* event) 1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 11368513a70bcd92384395513322f1b801e7bf9c729Steve Block if (!event->isMouseEvent()) 11468513a70bcd92384395513322f1b801e7bf9c729Steve Block return; 1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11668513a70bcd92384395513322f1b801e7bf9c729Steve Block ASSERT(event->target()); 11768513a70bcd92384395513322f1b801e7bf9c729Steve Block Node* target = event->target()->toNode(); 11868513a70bcd92384395513322f1b801e7bf9c729Steve Block ASSERT(target); 11968513a70bcd92384395513322f1b801e7bf9c729Steve Block if (!target->hasTagName(imgTag)) 12068513a70bcd92384395513322f1b801e7bf9c729Steve Block return; 1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 12268513a70bcd92384395513322f1b801e7bf9c729Steve Block HTMLImageElement* imageElement = static_cast<HTMLImageElement*>(event->target()->toNode()); 12368513a70bcd92384395513322f1b801e7bf9c729Steve Block if (!imageElement || !imageElement->isServerMap()) 12468513a70bcd92384395513322f1b801e7bf9c729Steve Block return; 1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 12668513a70bcd92384395513322f1b801e7bf9c729Steve Block RenderImage* renderer = toRenderImage(imageElement->renderer()); 12768513a70bcd92384395513322f1b801e7bf9c729Steve Block if (!renderer) 12868513a70bcd92384395513322f1b801e7bf9c729Steve Block return; 1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 13068513a70bcd92384395513322f1b801e7bf9c729Steve Block // FIXME: This should probably pass true for useTransforms. 13168513a70bcd92384395513322f1b801e7bf9c729Steve Block FloatPoint absolutePosition = renderer->absoluteToLocal(FloatPoint(static_cast<MouseEvent*>(event)->pageX(), static_cast<MouseEvent*>(event)->pageY())); 13268513a70bcd92384395513322f1b801e7bf9c729Steve Block int x = absolutePosition.x(); 13368513a70bcd92384395513322f1b801e7bf9c729Steve Block int y = absolutePosition.y(); 13468513a70bcd92384395513322f1b801e7bf9c729Steve Block url += "?"; 13568513a70bcd92384395513322f1b801e7bf9c729Steve Block url += String::number(x); 13668513a70bcd92384395513322f1b801e7bf9c729Steve Block url += ","; 13768513a70bcd92384395513322f1b801e7bf9c729Steve Block url += String::number(y); 13868513a70bcd92384395513322f1b801e7bf9c729Steve Block} 1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 14068513a70bcd92384395513322f1b801e7bf9c729Steve Blockvoid HTMLAnchorElement::defaultEventHandler(Event* event) 14168513a70bcd92384395513322f1b801e7bf9c729Steve Block{ 14268513a70bcd92384395513322f1b801e7bf9c729Steve Block if (isLink()) { 14368513a70bcd92384395513322f1b801e7bf9c729Steve Block if (focused() && isEnterKeyKeydownEvent(event) && treatLinkAsLiveForEventType(NonMouseEvent)) { 14468513a70bcd92384395513322f1b801e7bf9c729Steve Block event->setDefaultHandled(); 14568513a70bcd92384395513322f1b801e7bf9c729Steve Block dispatchSimulatedClick(event); 1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 14968513a70bcd92384395513322f1b801e7bf9c729Steve Block if (isLinkClick(event) && treatLinkAsLiveForEventType(eventType(event))) { 150a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch String url = stripLeadingAndTrailingHTMLSpaces(getAttribute(hrefAttr)); 15168513a70bcd92384395513322f1b801e7bf9c729Steve Block appendServerMapMousePosition(url, event); 15268513a70bcd92384395513322f1b801e7bf9c729Steve Block handleLinkClick(event, document(), url, getAttribute(targetAttr), hasRel(RelationNoReferrer)); 153bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen sendPings(document()->completeURL(url)); 15468513a70bcd92384395513322f1b801e7bf9c729Steve Block return; 1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1572bde8e466a4451c7319e3a072d118917957d6554Steve Block if (rendererIsEditable()) { 15868513a70bcd92384395513322f1b801e7bf9c729Steve Block // This keeps track of the editable block that the selection was in (if it was in one) just before the link was clicked 15968513a70bcd92384395513322f1b801e7bf9c729Steve Block // for the LiveWhenNotFocused editable link behavior 16068513a70bcd92384395513322f1b801e7bf9c729Steve Block if (event->type() == eventNames().mousedownEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() != RightButton && document()->frame() && document()->frame()->selection()) { 16168513a70bcd92384395513322f1b801e7bf9c729Steve Block m_rootEditableElementForSelectionOnMouseDown = document()->frame()->selection()->rootEditableElement(); 16268513a70bcd92384395513322f1b801e7bf9c729Steve Block m_wasShiftKeyDownOnMouseDown = static_cast<MouseEvent*>(event)->shiftKey(); 16368513a70bcd92384395513322f1b801e7bf9c729Steve Block } else if (event->type() == eventNames().mouseoverEvent) { 16468513a70bcd92384395513322f1b801e7bf9c729Steve Block // These are cleared on mouseover and not mouseout because their values are needed for drag events, 16568513a70bcd92384395513322f1b801e7bf9c729Steve Block // but drag events happen after mouse out events. 16668513a70bcd92384395513322f1b801e7bf9c729Steve Block m_rootEditableElementForSelectionOnMouseDown = 0; 16768513a70bcd92384395513322f1b801e7bf9c729Steve Block m_wasShiftKeyDownOnMouseDown = false; 16868513a70bcd92384395513322f1b801e7bf9c729Steve Block } 1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 17268513a70bcd92384395513322f1b801e7bf9c729Steve Block HTMLElement::defaultEventHandler(event); 1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLAnchorElement::setActive(bool down, bool pause) 1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1772bde8e466a4451c7319e3a072d118917957d6554Steve Block if (rendererIsEditable()) { 1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project EditableLinkBehavior editableLinkBehavior = EditableLinkDefaultBehavior; 1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (Settings* settings = document()->settings()) 1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project editableLinkBehavior = settings->editableLinkBehavior(); 1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch switch (editableLinkBehavior) { 1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project default: 1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case EditableLinkDefaultBehavior: 1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case EditableLinkAlwaysLive: 1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case EditableLinkNeverLive: 1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Don't set the link to be active if the current selection is in the same editable block as 1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // this link 1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case EditableLinkLiveWhenNotFocused: 194dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch if (down && document()->frame() && document()->frame()->selection()->rootEditableElement() == rootEditableElement()) 1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case EditableLinkOnlyLiveWithShiftKey: 1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ContainerNode::setActive(down, pause); 2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 207e78cbe89e6f337f2f1fe40315be88f742b547151Steve Blockvoid HTMLAnchorElement::parseMappedAttribute(Attribute* attr) 2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (attr->name() == hrefAttr) { 2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool wasLink = isLink(); 2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project setIsLink(!attr->isNull()); 2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (wasLink != isLink()) 2135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian setNeedsStyleRecalc(); 2145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (isLink()) { 215a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch String parsedURL = stripLeadingAndTrailingHTMLSpaces(attr->value()); 2165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (document()->isDNSPrefetchEnabled()) { 2175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (protocolIs(parsedURL, "http") || protocolIs(parsedURL, "https") || parsedURL.startsWith("//")) 218dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ResourceHandle::prepareForURL(document()->completeURL(parsedURL)); 2195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 2205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (document()->page() && !document()->page()->javaScriptURLsAreAllowed() && protocolIsJavaScript(parsedURL)) { 22121939df44de1705786c545cd1bf519d47250322dBen Murdoch clearIsLink(); 2225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian attr->setValue(nullAtom); 2235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else if (attr->name() == nameAttr || 226cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block attr->name() == titleAttr) { 2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Do nothing. 228cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } else if (attr->name() == relAttr) 229cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block setRel(attr->value()); 230cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block else 2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HTMLElement::parseMappedAttribute(attr); 2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLAnchorElement::accessKeyAction(bool sendToAnyElement) 2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // send the mouse button events if the caller specified sendToAnyElement 2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project dispatchSimulatedClick(0, sendToAnyElement); 2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLAnchorElement::isURLAttribute(Attribute *attr) const 2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return attr->name() == hrefAttr; 2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLAnchorElement::canStartSelection() const 2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: We probably want this same behavior in SVGAElement too 2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!isLink()) 2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return HTMLElement::canStartSelection(); 2502bde8e466a4451c7319e3a072d118917957d6554Steve Block return rendererIsEditable(); 2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochbool HTMLAnchorElement::draggable() const 2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // Should be draggable if we have an href attribute. 2560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch const AtomicString& value = getAttribute(draggableAttr); 2570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (equalIgnoringCase(value, "true")) 2580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return true; 2590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (equalIgnoringCase(value, "false")) 2600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return false; 2610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return hasAttribute(hrefAttr); 2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectKURL HTMLAnchorElement::href() const 2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 266a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return document()->completeURL(stripLeadingAndTrailingHTMLSpaces(getAttribute(hrefAttr))); 2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 269635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid HTMLAnchorElement::setHref(const AtomicString& value) 2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project setAttribute(hrefAttr, value); 2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 274cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockbool HTMLAnchorElement::hasRel(uint32_t relation) const 275cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{ 276cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return m_linkRelations & relation; 277cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block} 278cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 279cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockvoid HTMLAnchorElement::setRel(const String& value) 280cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{ 281cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block m_linkRelations = 0; 282643ca7872b450ea4efacab6188849e5aac2ba161Steve Block SpaceSplitString newLinkRelations(value, true); 283cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // FIXME: Add link relations as they are implemented 284cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (newLinkRelations.contains("noreferrer")) 285cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block m_linkRelations |= RelationNoReferrer; 286cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block} 287cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 288635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectconst AtomicString& HTMLAnchorElement::name() const 2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return getAttribute(nameAttr); 2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectshort HTMLAnchorElement::tabIndex() const 2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Skip the supportsFocus check in HTMLElement. 2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return Element::tabIndex(); 2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectString HTMLAnchorElement::target() const 3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return getAttribute(targetAttr); 3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectString HTMLAnchorElement::hash() const 3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch String fragmentIdentifier = href().fragmentIdentifier(); 3070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return fragmentIdentifier.isEmpty() ? "" : "#" + fragmentIdentifier; 3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 310643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid HTMLAnchorElement::setHash(const String& value) 311643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 312643ca7872b450ea4efacab6188849e5aac2ba161Steve Block KURL url = href(); 313643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (value[0] == '#') 314643ca7872b450ea4efacab6188849e5aac2ba161Steve Block url.setFragmentIdentifier(value.substring(1)); 315643ca7872b450ea4efacab6188849e5aac2ba161Steve Block else 316643ca7872b450ea4efacab6188849e5aac2ba161Steve Block url.setFragmentIdentifier(value); 317643ca7872b450ea4efacab6188849e5aac2ba161Steve Block setHref(url.string()); 318643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 319643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectString HTMLAnchorElement::host() const 3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 322231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block const KURL& url = href(); 323231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (url.hostEnd() == url.pathStart()) 324231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return url.host(); 325643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (isDefaultPortForProtocol(url.port(), url.protocol())) 326231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return url.host(); 327231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return url.host() + ":" + String::number(url.port()); 3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 330643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid HTMLAnchorElement::setHost(const String& value) 331643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 332643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (value.isEmpty()) 333643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return; 334643ca7872b450ea4efacab6188849e5aac2ba161Steve Block KURL url = href(); 335643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (!url.canSetHostOrPort()) 336643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return; 337643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 338f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick size_t separator = value.find(':'); 339643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (!separator) 340643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return; 341643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 342f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (separator == notFound) 343643ca7872b450ea4efacab6188849e5aac2ba161Steve Block url.setHostAndPort(value); 344643ca7872b450ea4efacab6188849e5aac2ba161Steve Block else { 345643ca7872b450ea4efacab6188849e5aac2ba161Steve Block unsigned portEnd; 346643ca7872b450ea4efacab6188849e5aac2ba161Steve Block unsigned port = parsePortFromStringPosition(value, separator + 1, portEnd); 347643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (!port) { 348643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // http://dev.w3.org/html5/spec/infrastructure.html#url-decomposition-idl-attributes 349643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // specifically goes against RFC 3986 (p3.2) and 350643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // requires setting the port to "0" if it is set to empty string. 351643ca7872b450ea4efacab6188849e5aac2ba161Steve Block url.setHostAndPort(value.substring(0, separator + 1) + "0"); 352643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } else { 353643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (isDefaultPortForProtocol(port, url.protocol())) 354643ca7872b450ea4efacab6188849e5aac2ba161Steve Block url.setHostAndPort(value.substring(0, separator)); 355643ca7872b450ea4efacab6188849e5aac2ba161Steve Block else 356643ca7872b450ea4efacab6188849e5aac2ba161Steve Block url.setHostAndPort(value.substring(0, portEnd)); 357643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 358643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 359643ca7872b450ea4efacab6188849e5aac2ba161Steve Block setHref(url.string()); 360643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 361643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 3628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectString HTMLAnchorElement::hostname() const 3638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 364231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return href().host(); 3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 367643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid HTMLAnchorElement::setHostname(const String& value) 368643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 369643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // Before setting new value: 370643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // Remove all leading U+002F SOLIDUS ("/") characters. 371643ca7872b450ea4efacab6188849e5aac2ba161Steve Block unsigned i = 0; 372643ca7872b450ea4efacab6188849e5aac2ba161Steve Block unsigned hostLength = value.length(); 373643ca7872b450ea4efacab6188849e5aac2ba161Steve Block while (value[i] == '/') 374643ca7872b450ea4efacab6188849e5aac2ba161Steve Block i++; 375643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 376643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (i == hostLength) 377643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return; 378643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 379643ca7872b450ea4efacab6188849e5aac2ba161Steve Block KURL url = href(); 380643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (!url.canSetHostOrPort()) 381643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return; 382643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 383643ca7872b450ea4efacab6188849e5aac2ba161Steve Block url.setHost(value.substring(i)); 384643ca7872b450ea4efacab6188849e5aac2ba161Steve Block setHref(url.string()); 385643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 386643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 3878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectString HTMLAnchorElement::pathname() const 3888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return href().path(); 3908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 392643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid HTMLAnchorElement::setPathname(const String& value) 393643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 394643ca7872b450ea4efacab6188849e5aac2ba161Steve Block KURL url = href(); 395643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (!url.canSetPathname()) 396643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return; 397643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 398643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (value[0] == '/') 399643ca7872b450ea4efacab6188849e5aac2ba161Steve Block url.setPath(value); 400643ca7872b450ea4efacab6188849e5aac2ba161Steve Block else 401643ca7872b450ea4efacab6188849e5aac2ba161Steve Block url.setPath("/" + value); 402643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 403643ca7872b450ea4efacab6188849e5aac2ba161Steve Block setHref(url.string()); 404643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 405643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 4068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectString HTMLAnchorElement::port() const 4078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 408c57e584da242d96ba18578a71f4634adc9d1fff6Steve Block if (href().hasPort()) 409c57e584da242d96ba18578a71f4634adc9d1fff6Steve Block return String::number(href().port()); 410c57e584da242d96ba18578a71f4634adc9d1fff6Steve Block 411c57e584da242d96ba18578a71f4634adc9d1fff6Steve Block return ""; 4128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 414643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid HTMLAnchorElement::setPort(const String& value) 415643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 416643ca7872b450ea4efacab6188849e5aac2ba161Steve Block KURL url = href(); 417643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (!url.canSetHostOrPort()) 418643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return; 419643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 420643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // http://dev.w3.org/html5/spec/infrastructure.html#url-decomposition-idl-attributes 421643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // specifically goes against RFC 3986 (p3.2) and 422643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // requires setting the port to "0" if it is set to empty string. 423643ca7872b450ea4efacab6188849e5aac2ba161Steve Block unsigned port = value.toUInt(); 424643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (isDefaultPortForProtocol(port, url.protocol())) 425643ca7872b450ea4efacab6188849e5aac2ba161Steve Block url.removePort(); 426643ca7872b450ea4efacab6188849e5aac2ba161Steve Block else 427643ca7872b450ea4efacab6188849e5aac2ba161Steve Block url.setPort(port); 428643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 429643ca7872b450ea4efacab6188849e5aac2ba161Steve Block setHref(url.string()); 430643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 431643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 4328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectString HTMLAnchorElement::protocol() const 4338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return href().protocol() + ":"; 4358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 437643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid HTMLAnchorElement::setProtocol(const String& value) 438643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 439643ca7872b450ea4efacab6188849e5aac2ba161Steve Block KURL url = href(); 440d0825bca7fe65beaee391d30da42e937db621564Steve Block url.setProtocol(value); 441643ca7872b450ea4efacab6188849e5aac2ba161Steve Block setHref(url.string()); 442643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 443643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 4448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectString HTMLAnchorElement::search() const 4458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian String query = href().query(); 4478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return query.isEmpty() ? "" : "?" + query; 4488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 450bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenString HTMLAnchorElement::origin() const 451bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen{ 452bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen RefPtr<SecurityOrigin> origin = SecurityOrigin::create(href()); 453bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen return origin->toString(); 454bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen} 455bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 456a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochString HTMLAnchorElement::getParameter(const String& name) const 457a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 458a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ParsedURLParameters parameters; 459a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch href().copyParsedQueryTo(parameters); 460a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return parameters.get(name); 461a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 462a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 463643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid HTMLAnchorElement::setSearch(const String& value) 464643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 465643ca7872b450ea4efacab6188849e5aac2ba161Steve Block KURL url = href(); 466643ca7872b450ea4efacab6188849e5aac2ba161Steve Block String newSearch = (value[0] == '?') ? value.substring(1) : value; 467643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // Make sure that '#' in the query does not leak to the hash. 468643ca7872b450ea4efacab6188849e5aac2ba161Steve Block url.setQuery(newSearch.replace('#', "%23")); 469643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 470643ca7872b450ea4efacab6188849e5aac2ba161Steve Block setHref(url.string()); 471643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 472643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 4738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectString HTMLAnchorElement::text() const 4748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return innerText(); 4768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectString HTMLAnchorElement::toString() const 4798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return href().string(); 4818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLAnchorElement::isLiveLink() const 4848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 48568513a70bcd92384395513322f1b801e7bf9c729Steve Block return isLink() && treatLinkAsLiveForEventType(m_wasShiftKeyDownOnMouseDown ? MouseEventWithShiftKey : MouseEventWithoutShiftKey); 48668513a70bcd92384395513322f1b801e7bf9c729Steve Block} 48768513a70bcd92384395513322f1b801e7bf9c729Steve Block 488bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid HTMLAnchorElement::sendPings(const KURL& destinationURL) 489bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen{ 490bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (!hasAttribute(pingAttr) || !document()->settings()->hyperlinkAuditingEnabled()) 491bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen return; 492bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 493bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen SpaceSplitString pingURLs(getAttribute(pingAttr), true); 494bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen for (unsigned i = 0; i < pingURLs.size(); i++) 495bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen PingLoader::sendPing(document()->frame(), document()->completeURL(pingURLs[i]), destinationURL); 496bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen} 497bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 49868513a70bcd92384395513322f1b801e7bf9c729Steve BlockHTMLAnchorElement::EventType HTMLAnchorElement::eventType(Event* event) 49968513a70bcd92384395513322f1b801e7bf9c729Steve Block{ 50068513a70bcd92384395513322f1b801e7bf9c729Steve Block if (!event->isMouseEvent()) 50168513a70bcd92384395513322f1b801e7bf9c729Steve Block return NonMouseEvent; 50268513a70bcd92384395513322f1b801e7bf9c729Steve Block return static_cast<MouseEvent*>(event)->shiftKey() ? MouseEventWithShiftKey : MouseEventWithoutShiftKey; 50368513a70bcd92384395513322f1b801e7bf9c729Steve Block} 50468513a70bcd92384395513322f1b801e7bf9c729Steve Block 50568513a70bcd92384395513322f1b801e7bf9c729Steve Blockbool HTMLAnchorElement::treatLinkAsLiveForEventType(EventType eventType) const 50668513a70bcd92384395513322f1b801e7bf9c729Steve Block{ 5072bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!rendererIsEditable()) 5088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 50968513a70bcd92384395513322f1b801e7bf9c729Steve Block 51068513a70bcd92384395513322f1b801e7bf9c729Steve Block Settings* settings = document()->settings(); 51168513a70bcd92384395513322f1b801e7bf9c729Steve Block if (!settings) 51268513a70bcd92384395513322f1b801e7bf9c729Steve Block return true; 51368513a70bcd92384395513322f1b801e7bf9c729Steve Block 51468513a70bcd92384395513322f1b801e7bf9c729Steve Block switch (settings->editableLinkBehavior()) { 51568513a70bcd92384395513322f1b801e7bf9c729Steve Block case EditableLinkDefaultBehavior: 51668513a70bcd92384395513322f1b801e7bf9c729Steve Block case EditableLinkAlwaysLive: 51768513a70bcd92384395513322f1b801e7bf9c729Steve Block return true; 51868513a70bcd92384395513322f1b801e7bf9c729Steve Block 51968513a70bcd92384395513322f1b801e7bf9c729Steve Block case EditableLinkNeverLive: 52068513a70bcd92384395513322f1b801e7bf9c729Steve Block return false; 52168513a70bcd92384395513322f1b801e7bf9c729Steve Block 52268513a70bcd92384395513322f1b801e7bf9c729Steve Block // If the selection prior to clicking on this link resided in the same editable block as this link, 52368513a70bcd92384395513322f1b801e7bf9c729Steve Block // and the shift key isn't pressed, we don't want to follow the link. 52468513a70bcd92384395513322f1b801e7bf9c729Steve Block case EditableLinkLiveWhenNotFocused: 52568513a70bcd92384395513322f1b801e7bf9c729Steve Block return eventType == MouseEventWithShiftKey || (eventType == MouseEventWithoutShiftKey && m_rootEditableElementForSelectionOnMouseDown != rootEditableElement()); 52668513a70bcd92384395513322f1b801e7bf9c729Steve Block 52768513a70bcd92384395513322f1b801e7bf9c729Steve Block case EditableLinkOnlyLiveWithShiftKey: 52868513a70bcd92384395513322f1b801e7bf9c729Steve Block return eventType == MouseEventWithShiftKey; 5298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 53068513a70bcd92384395513322f1b801e7bf9c729Steve Block 53168513a70bcd92384395513322f1b801e7bf9c729Steve Block ASSERT_NOT_REACHED(); 53268513a70bcd92384395513322f1b801e7bf9c729Steve Block return false; 53368513a70bcd92384395513322f1b801e7bf9c729Steve Block} 53468513a70bcd92384395513322f1b801e7bf9c729Steve Block 53568513a70bcd92384395513322f1b801e7bf9c729Steve Blockbool isEnterKeyKeydownEvent(Event* event) 53668513a70bcd92384395513322f1b801e7bf9c729Steve Block{ 537ceeeab6161d7d8bf970ecf98affa4f4966df6f01John Reck#if OS(ANDROID) 538ceeeab6161d7d8bf970ecf98affa4f4966df6f01John Reck return event->type() == eventNames().keyupEvent && event->isKeyboardEvent() && static_cast<KeyboardEvent*>(event)->keyIdentifier() == "Enter"; 539ceeeab6161d7d8bf970ecf98affa4f4966df6f01John Reck#else 54068513a70bcd92384395513322f1b801e7bf9c729Steve Block return event->type() == eventNames().keydownEvent && event->isKeyboardEvent() && static_cast<KeyboardEvent*>(event)->keyIdentifier() == "Enter"; 541ceeeab6161d7d8bf970ecf98affa4f4966df6f01John Reck#endif 54268513a70bcd92384395513322f1b801e7bf9c729Steve Block} 54368513a70bcd92384395513322f1b801e7bf9c729Steve Block 54468513a70bcd92384395513322f1b801e7bf9c729Steve Blockbool isMiddleMouseButtonEvent(Event* event) 54568513a70bcd92384395513322f1b801e7bf9c729Steve Block{ 54668513a70bcd92384395513322f1b801e7bf9c729Steve Block return event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == MiddleButton; 54768513a70bcd92384395513322f1b801e7bf9c729Steve Block} 54868513a70bcd92384395513322f1b801e7bf9c729Steve Block 54968513a70bcd92384395513322f1b801e7bf9c729Steve Blockbool isLinkClick(Event* event) 55068513a70bcd92384395513322f1b801e7bf9c729Steve Block{ 5512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return event->type() == eventNames().clickEvent && (!event->isMouseEvent() || static_cast<MouseEvent*>(event)->button() != RightButton); 55268513a70bcd92384395513322f1b801e7bf9c729Steve Block} 55368513a70bcd92384395513322f1b801e7bf9c729Steve Block 55468513a70bcd92384395513322f1b801e7bf9c729Steve Blockvoid handleLinkClick(Event* event, Document* document, const String& url, const String& target, bool hideReferrer) 55568513a70bcd92384395513322f1b801e7bf9c729Steve Block{ 55668513a70bcd92384395513322f1b801e7bf9c729Steve Block event->setDefaultHandled(); 55768513a70bcd92384395513322f1b801e7bf9c729Steve Block 55868513a70bcd92384395513322f1b801e7bf9c729Steve Block Frame* frame = document->frame(); 55968513a70bcd92384395513322f1b801e7bf9c729Steve Block if (!frame) 56068513a70bcd92384395513322f1b801e7bf9c729Steve Block return; 561a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch frame->loader()->urlSelected(document->completeURL(url), target, event, false, false, hideReferrer ? NoReferrer : SendReferrer); 5628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 565