1 /** 2 * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) 3 * 4 * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org) 5 * (C) 1999 Antti Koivisto (koivisto (at) kde.org) 6 * (C) 2000 Simon Hausmann <hausmann (at) kde.org> 7 * Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved. 8 * (C) 2006 Graham Dennis (graham.dennis (at) gmail.com) 9 * 10 * This library is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU Library General Public 12 * License as published by the Free Software Foundation; either 13 * version 2 of the License, or (at your option) any later version. 14 * 15 * This library is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * Library General Public License for more details. 19 * 20 * You should have received a copy of the GNU Library General Public License 21 * along with this library; see the file COPYING.LIB. If not, write to 22 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 23 * Boston, MA 02110-1301, USA. 24 * 25 */ 26 27 #include "config.h" 28 29 #if ENABLE(WML) 30 #include "WMLAElement.h" 31 32 #include "DNS.h" 33 #include "Event.h" 34 #include "EventHandler.h" 35 #include "EventNames.h" 36 #include "Frame.h" 37 #include "FrameLoader.h" 38 #include "HTMLNames.h" 39 #include "KeyboardEvent.h" 40 #include "MappedAttribute.h" 41 #include "MouseEvent.h" 42 #include "RenderBox.h" 43 #include "WMLNames.h" 44 45 namespace WebCore { 46 47 using namespace WMLNames; 48 49 WMLAElement::WMLAElement(const QualifiedName& tagName, Document* doc) 50 : WMLElement(tagName, doc) 51 { 52 } 53 54 void WMLAElement::parseMappedAttribute(MappedAttribute* attr) 55 { 56 if (attr->name() == HTMLNames::hrefAttr) { 57 bool wasLink = isLink(); 58 setIsLink(!attr->isNull()); 59 if (wasLink != isLink()) 60 setNeedsStyleRecalc(); 61 if (isLink() && document()->isDNSPrefetchEnabled()) { 62 String value = attr->value(); 63 if (protocolIs(value, "http") || protocolIs(value, "https") || value.startsWith("//")) 64 prefetchDNS(document()->completeURL(value).host()); 65 } 66 } else if (attr->name() == HTMLNames::nameAttr 67 || attr->name() == HTMLNames::titleAttr 68 || attr->name() == HTMLNames::relAttr) { 69 // Do nothing. 70 } else 71 WMLElement::parseMappedAttribute(attr); 72 } 73 74 bool WMLAElement::supportsFocus() const 75 { 76 return isLink() || WMLElement::supportsFocus(); 77 } 78 79 bool WMLAElement::isMouseFocusable() const 80 { 81 return false; 82 } 83 84 bool WMLAElement::isKeyboardFocusable(KeyboardEvent* event) const 85 { 86 if (!isFocusable()) 87 return false; 88 89 if (!document()->frame()) 90 return false; 91 92 if (!document()->frame()->eventHandler()->tabsToLinks(event)) 93 return false; 94 95 if (!renderer() || !renderer()->isBoxModelObject()) 96 return false; 97 98 // Before calling absoluteRects, check for the common case where the renderer 99 // is non-empty, since this is a faster check and almost always returns true. 100 RenderBoxModelObject* box = toRenderBoxModelObject(renderer()); 101 if (!box->borderBoundingBox().isEmpty()) 102 return true; 103 104 Vector<IntRect> rects; 105 FloatPoint absPos = renderer()->localToAbsolute(); 106 renderer()->absoluteRects(rects, absPos.x(), absPos.y()); 107 size_t n = rects.size(); 108 for (size_t i = 0; i < n; ++i) 109 if (!rects[i].isEmpty()) 110 return true; 111 112 return false; 113 } 114 115 void WMLAElement::defaultEventHandler(Event* event) 116 { 117 if (isLink() && (event->type() == eventNames().clickEvent || (event->type() == eventNames().keydownEvent && focused()))) { 118 MouseEvent* e = 0; 119 if (event->type() == eventNames().clickEvent && event->isMouseEvent()) 120 e = static_cast<MouseEvent*>(event); 121 122 KeyboardEvent* k = 0; 123 if (event->type() == eventNames().keydownEvent && event->isKeyboardEvent()) 124 k = static_cast<KeyboardEvent*>(event); 125 126 if (e && e->button() == RightButton) { 127 WMLElement::defaultEventHandler(event); 128 return; 129 } 130 131 if (k) { 132 if (k->keyIdentifier() != "Enter") { 133 WMLElement::defaultEventHandler(event); 134 return; 135 } 136 137 event->setDefaultHandled(); 138 dispatchSimulatedClick(event); 139 return; 140 } 141 142 if (!event->defaultPrevented() && document()->frame()) { 143 String url = document()->completeURL(deprecatedParseURL(getAttribute(HTMLNames::hrefAttr))); 144 document()->frame()->loader()->urlSelected(url, target(), event, false, false, true, SendReferrer); 145 } 146 147 event->setDefaultHandled(); 148 } 149 150 WMLElement::defaultEventHandler(event); 151 } 152 153 void WMLAElement::accessKeyAction(bool sendToAnyElement) 154 { 155 // send the mouse button events if the caller specified sendToAnyElement 156 dispatchSimulatedClick(0, sendToAnyElement); 157 } 158 159 bool WMLAElement::isURLAttribute(Attribute *attr) const 160 { 161 return attr->name() == HTMLNames::hrefAttr; 162 } 163 164 String WMLAElement::target() const 165 { 166 return getAttribute(HTMLNames::targetAttr); 167 } 168 169 } 170 171 #endif 172