001: /*
002: * Copyright (c) 2002-2008 Gargoyle Software Inc. All rights reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * 1. Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: * 2. Redistributions in binary form must reproduce the above copyright notice,
010: * this list of conditions and the following disclaimer in the documentation
011: * and/or other materials provided with the distribution.
012: * 3. The end-user documentation included with the redistribution, if any, must
013: * include the following acknowledgment:
014: *
015: * "This product includes software developed by Gargoyle Software Inc.
016: * (http://www.GargoyleSoftware.com/)."
017: *
018: * Alternately, this acknowledgment may appear in the software itself, if
019: * and wherever such third-party acknowledgments normally appear.
020: * 4. The name "Gargoyle Software" must not be used to endorse or promote
021: * products derived from this software without prior written permission.
022: * For written permission, please contact info@GargoyleSoftware.com.
023: * 5. Products derived from this software may not be called "HtmlUnit", nor may
024: * "HtmlUnit" appear in their name, without prior written permission of
025: * Gargoyle Software Inc.
026: *
027: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
028: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
029: * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GARGOYLE
030: * SOFTWARE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
031: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
032: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
033: * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
034: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
035: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
036: * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
037: */
038: package com.gargoylesoftware.htmlunit.html;
039:
040: import java.io.IOException;
041: import java.net.MalformedURLException;
042: import java.net.URL;
043: import java.util.Map;
044:
045: import com.gargoylesoftware.htmlunit.Page;
046: import com.gargoylesoftware.htmlunit.TextUtil;
047: import com.gargoylesoftware.htmlunit.WebRequestSettings;
048: import com.gargoylesoftware.htmlunit.WebWindow;
049:
050: /**
051: * Wrapper for the html element "a"
052: *
053: * @version $Revision: 2132 $
054: * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
055: * @author David K. Taylor
056: * @author <a href="mailto:cse@dynabean.de">Christian Sell</a>
057: * @author Ahmed Ashour
058: */
059: public class HtmlAnchor extends FocusableElement {
060:
061: private static final long serialVersionUID = 7968778206454737178L;
062:
063: /** the HTML tag represented by this element */
064: public static final String TAG_NAME = "a";
065:
066: /**
067: * Create an instance
068: *
069: * @param page The page that contains this element
070: * @param attributes the initial attributes
071: * @deprecated You should not directly construct HtmlAnchor.
072: */
073: //TODO: to be removed, deprecated after 1.11
074: public HtmlAnchor(final HtmlPage page, final Map attributes) {
075: this (null, TAG_NAME, page, attributes);
076: }
077:
078: /**
079: * Create an instance
080: *
081: * @param namespaceURI the URI that identifies an XML namespace.
082: * @param qualifiedName The qualified name of the element type to instantiate
083: * @param page The page that contains this element
084: * @param attributes the initial attributes
085: */
086: HtmlAnchor(final String namespaceURI, final String qualifiedName,
087: final HtmlPage page, final Map attributes) {
088: super (namespaceURI, qualifiedName, page, attributes);
089: }
090:
091: /**
092: * Same as {@link #doClickAction(Page)} except that it accepts an href suffix needed when a click is
093: * performed on an image map to pass information on the click position.
094: * @param defaultPage The default page to return if the action does not load a new page.
095: * @param hrefSuffix the suffix to add to the anchor's href attribute (for instance coordinates from an image map)
096: * @return The page that is currently loaded after execution of this method
097: * @throws IOException If an IO error occurred
098: */
099: protected Page doClickAction(final Page defaultPage,
100: final String hrefSuffix) throws IOException {
101: final String href = getHrefAttribute() + hrefSuffix;
102:
103: getLog().debug(
104: "do click action in window '"
105: + defaultPage.getEnclosingWindow().getName()
106: + "', using href '" + href + "'");
107:
108: if (href != null && href.length() > 0 && !href.startsWith("#")) {
109: final HtmlPage page = getPage();
110: if (TextUtil.startsWithIgnoreCase(href, "javascript:")) {
111: return page.executeJavaScriptIfPossible(href,
112: "javascript url", getStartLineNumber())
113: .getNewPage();
114: } else {
115: final URL url = page.getFullyQualifiedUrl(href);
116: final WebRequestSettings settings = new WebRequestSettings(
117: url);
118: settings.addAdditionalHeader("Referer", page
119: .getWebResponse().getUrl().toExternalForm());
120: getLog().debug(
121: "Getting page for " + url.toExternalForm()
122: + ", derived from href '" + href
123: + "', using the originating url "
124: + page.getWebResponse().getUrl());
125: return page.getWebClient().getPage(
126: page.getEnclosingWindow(),
127: page.getResolvedTarget(getTargetAttribute()),
128: settings);
129: }
130: } else {
131: return defaultPage;
132: }
133: }
134:
135: /**
136: * This method will be called if there either wasn't an onclick handler or
137: * there was but the result of that handler was true. This is the default
138: * behavior of clicking the element. For this anchor element, the default
139: * behavior is to open the HREF page, or execute the HREF if it is a
140: * javascript: URL.
141: *
142: * @param defaultPage The default page to return if the action does not
143: * load a new page.
144: * @return The page that is currently loaded after execution of this method
145: * @throws IOException If an IO error occurred
146: */
147: protected Page doClickAction(final Page defaultPage)
148: throws IOException {
149: return doClickAction(defaultPage, "");
150: }
151:
152: /**
153: * Return the value of the attribute "charset". Refer to the
154: * <a href='http://www.w3.org/TR/html401/'>HTML 4.01</a>
155: * documentation for details on the use of this attribute.
156: *
157: * @return The value of the attribute "charset"
158: * or an empty string if that attribute isn't defined.
159: */
160: public final String getCharsetAttribute() {
161: return getAttributeValue("charset");
162: }
163:
164: /**
165: * Return the value of the attribute "type". Refer to the
166: * <a href='http://www.w3.org/TR/html401/'>HTML 4.01</a>
167: * documentation for details on the use of this attribute.
168: *
169: * @return The value of the attribute "type"
170: * or an empty string if that attribute isn't defined.
171: */
172: public final String getTypeAttribute() {
173: return getAttributeValue("type");
174: }
175:
176: /**
177: * Return the value of the attribute "name". Refer to the
178: * <a href='http://www.w3.org/TR/html401/'>HTML 4.01</a>
179: * documentation for details on the use of this attribute.
180: *
181: * @return The value of the attribute "name"
182: * or an empty string if that attribute isn't defined.
183: */
184: public final String getNameAttribute() {
185: return getAttributeValue("name");
186: }
187:
188: /**
189: * Return the value of the attribute "href". Refer to the
190: * <a href='http://www.w3.org/TR/html401/'>HTML 4.01</a>
191: * documentation for details on the use of this attribute.
192: *
193: * @return The value of the attribute "href"
194: * or an empty string if that attribute isn't defined.
195: */
196: public final String getHrefAttribute() {
197: return getAttributeValue("href").trim();
198: }
199:
200: /**
201: * Return the value of the attribute "hreflang". Refer to the
202: * <a href='http://www.w3.org/TR/html401/'>HTML 4.01</a>
203: * documentation for details on the use of this attribute.
204: *
205: * @return The value of the attribute "hreflang"
206: * or an empty string if that attribute isn't defined.
207: */
208: public final String getHrefLangAttribute() {
209: return getAttributeValue("hreflang");
210: }
211:
212: /**
213: * Return the value of the attribute "rel". Refer to the
214: * <a href='http://www.w3.org/TR/html401/'>HTML 4.01</a>
215: * documentation for details on the use of this attribute.
216: *
217: * @return The value of the attribute "rel"
218: * or an empty string if that attribute isn't defined.
219: */
220: public final String getRelAttribute() {
221: return getAttributeValue("rel");
222: }
223:
224: /**
225: * Return the value of the attribute "rev". Refer to the
226: * <a href='http://www.w3.org/TR/html401/'>HTML 4.01</a>
227: * documentation for details on the use of this attribute.
228: *
229: * @return The value of the attribute "rev"
230: * or an empty string if that attribute isn't defined.
231: */
232: public final String getRevAttribute() {
233: return getAttributeValue("rev");
234: }
235:
236: /**
237: * Return the value of the attribute "accesskey". Refer to the
238: * <a href='http://www.w3.org/TR/html401/'>HTML 4.01</a>
239: * documentation for details on the use of this attribute.
240: *
241: * @return The value of the attribute "accesskey"
242: * or an empty string if that attribute isn't defined.
243: */
244: public final String getAccessKeyAttribute() {
245: return getAttributeValue("accesskey");
246: }
247:
248: /**
249: * Return the value of the attribute "shape". Refer to the
250: * <a href='http://www.w3.org/TR/html401/'>HTML 4.01</a>
251: * documentation for details on the use of this attribute.
252: *
253: * @return The value of the attribute "shape"
254: * or an empty string if that attribute isn't defined.
255: */
256: public final String getShapeAttribute() {
257: return getAttributeValue("shape");
258: }
259:
260: /**
261: * Return the value of the attribute "coords". Refer to the
262: * <a href='http://www.w3.org/TR/html401/'>HTML 4.01</a>
263: * documentation for details on the use of this attribute.
264: *
265: * @return The value of the attribute "coords"
266: * or an empty string if that attribute isn't defined.
267: */
268: public final String getCoordsAttribute() {
269: return getAttributeValue("coords");
270: }
271:
272: /**
273: * Return the value of the attribute "tabindex". Refer to the
274: * <a href='http://www.w3.org/TR/html401/'>HTML 4.01</a>
275: * documentation for details on the use of this attribute.
276: *
277: * @return The value of the attribute "tabindex"
278: * or an empty string if that attribute isn't defined.
279: */
280: public final String getTabIndexAttribute() {
281: return getAttributeValue("tabindex");
282: }
283:
284: /**
285: * Return the value of the attribute "onfocus". Refer to the
286: * <a href='http://www.w3.org/TR/html401/'>HTML 4.01</a>
287: * documentation for details on the use of this attribute.
288: *
289: * @return The value of the attribute "onfocus"
290: * or an empty string if that attribute isn't defined.
291: */
292: public final String getOnFocusAttribute() {
293: return getAttributeValue("onfocus");
294: }
295:
296: /**
297: * Return the value of the attribute "onblur". Refer to the
298: * <a href='http://www.w3.org/TR/html401/'>HTML 4.01</a>
299: * documentation for details on the use of this attribute.
300: *
301: * @return The value of the attribute "onblur"
302: * or an empty string if that attribute isn't defined.
303: */
304: public final String getOnBlurAttribute() {
305: return getAttributeValue("onblur");
306: }
307:
308: /**
309: * Return the value of the attribute "target". Refer to the
310: * <a href='http://www.w3.org/TR/html401/'>HTML 4.01</a>
311: * documentation for details on the use of this attribute.
312: *
313: * @return The value of the attribute "target"
314: * or an empty string if that attribute isn't defined.
315: */
316: public final String getTargetAttribute() {
317: return getAttributeValue("target");
318: }
319:
320: /**
321: * Open this link in a new window, much as web browsers do when you
322: * shift-click a link or use the context menu to open in a new window.
323: *
324: * It should be noted that even web browsers will sometimes not give the
325: * expected result when using this method of following links. Links that
326: * have no real href and rely on javascript to do their work will fail.
327: *
328: * @return The Page opened by this link, nested in a new TopLevelWindow
329: * @throws MalformedURLException if the href could not be converted to a valid URL
330: */
331: public final Page openLinkInNewWindow()
332: throws MalformedURLException {
333: final URL target = getPage().getFullyQualifiedUrl(
334: getHrefAttribute());
335: final WebWindow newWindow = getPage().getWebClient()
336: .openWindow(target,
337: "HtmlAnchor.openLinkInNewWindow() target");
338: return newWindow.getEnclosedPage();
339: }
340: }
|