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