com.google.gwt.user.client.ui.Hyperlink.java Source code

Java tutorial

Introduction

Here is the source code for com.google.gwt.user.client.ui.Hyperlink.java

Source

/*
 * Copyright 2008 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.user.client.ui;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.i18n.client.HasDirection.Direction;
import com.google.gwt.i18n.shared.DirectionEstimator;
import com.google.gwt.i18n.shared.HasDirectionEstimator;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.ui.impl.HyperlinkImpl;

/**
 * A widget that serves as an "internal" hyperlink. That is, it is a link to
 * another state of the running application. When clicked, it will create a new
 * history frame using {@link com.google.gwt.user.client.History#newItem}, but
 * without reloading the page.
 * 
 * <p>
 * If you want an HTML hyperlink (&lt;a&gt; tag) without interacting with the
 * history system, use {@link Anchor} instead.
 * </p>
 * 
 * <p>
 * Being a true hyperlink, it is also possible for the user to "right-click,
 * open link in new window", which will cause the application to be loaded in a
 * new window at the state specified by the hyperlink.
 * </p>
 * 
 * <p>
 * <h3>Built-in Bidi Text Support</h3> This widget is capable of automatically
 * adjusting its direction according to its content. This feature is controlled
 * by {@link #setDirectionEstimator} or passing a DirectionEstimator parameter
 * to the constructor, and is off by default.
 * </p>
 *
 * <p>
 * <img class='gallery' src='doc-files/Hyperlink.png'/>
 * </p>
 * 
 * <h3>CSS Style Rules</h3>
 * <ul class='css'>
 * <li>.gwt-Hyperlink { }</li>
 * </ul>
 * 
 * <p>
 * <h3>Example</h3> {@example com.google.gwt.examples.HistoryExample}
 * </p>
 * 
 * @see Anchor
 */
// Nick - just super-override so we can turn off history triggering
@SuppressWarnings("deprecation")
public class Hyperlink extends Widget
        implements HasHTML, SourcesClickEvents, HasClickHandlers, HasDirectionEstimator, HasDirectionalSafeHtml {
    public static final DirectionEstimator DEFAULT_DIRECTION_ESTIMATOR = DirectionalTextHelper.DEFAULT_DIRECTION_ESTIMATOR;

    private static HyperlinkImpl impl = GWT.create(HyperlinkImpl.class);

    protected final DirectionalTextHelper directionalTextHelper;

    private final Element anchorElem = DOM.createAnchor();

    private String targetHistoryToken;

    /**
     * Creates an empty hyperlink.
     */
    public Hyperlink() {
        this(DOM.createDiv());
    }

    /**
     * Creates a hyperlink with its html and target history token specified.
     *
     * @param html
     *            the hyperlink's safe html
     * @param dir
     *            the html's direction
     * @param targetHistoryToken
     *            the history token to which it will link
     * @see #setTargetHistoryToken
     */
    public Hyperlink(SafeHtml html, Direction dir, String targetHistoryToken) {
        this(html.asString(), true, dir, targetHistoryToken);
    }

    /**
     * Creates a hyperlink with its html and target history token specified.
     *
     * @param html
     *            the hyperlink's safe html
     * @param directionEstimator
     *            A DirectionEstimator object used for automatic direction
     *            adjustment. For convenience,
     *            {@link #DEFAULT_DIRECTION_ESTIMATOR} can be used.
     * @param targetHistoryToken
     *            the history token to which it will link
     * @see #setTargetHistoryToken
     */
    public Hyperlink(SafeHtml html, DirectionEstimator directionEstimator, String targetHistoryToken) {
        this(html.asString(), true, directionEstimator, targetHistoryToken);
    }

    /**
     * Creates a hyperlink with its html and target history token specified.
     *
     * @param html
     *            the hyperlink's safe html
     * @param targetHistoryToken
     *            the history token to which it will link
     * @see #setTargetHistoryToken
     */
    public Hyperlink(SafeHtml html, String targetHistoryToken) {
        this(html.asString(), true, targetHistoryToken);
    }

    /**
     * Creates a hyperlink with its text and target history token specified.
     *
     * @param text
     *            the hyperlink's text
     * @param asHTML
     *            <code>true</code> to treat the specified text as html
     * @param targetHistoryToken
     *            the history token to which it will link
     * @see #setTargetHistoryToken
     */
    public Hyperlink(String text, boolean asHTML, String targetHistoryToken) {
        this();
        directionalTextHelper.setTextOrHtml(text, asHTML);
        setTargetHistoryToken(targetHistoryToken);
    }

    /**
     * Creates a hyperlink with its text and target history token specified.
     * 
     * @param text
     *            the hyperlink's text
     * @param dir
     *            the text's direction
     * @param targetHistoryToken
     *            the history token to which it will link, which may not be null
     *            (use {@link Anchor} instead if you don't need history
     *            processing)
     */
    public Hyperlink(String text, Direction dir, String targetHistoryToken) {
        this(text, false, dir, targetHistoryToken);
    }

    /**
     * Creates a hyperlink with its text and target history token specified.
     * 
     * @param text
     *            the hyperlink's text
     * @param directionEstimator
     *            A DirectionEstimator object used for automatic direction
     *            adjustment. For convenience,
     *            {@link #DEFAULT_DIRECTION_ESTIMATOR} can be used.
     * @param targetHistoryToken
     *            the history token to which it will link, which may not be null
     *            (use {@link Anchor} instead if you don't need history
     *            processing)
     */
    public Hyperlink(String text, DirectionEstimator directionEstimator, String targetHistoryToken) {
        this(text, false, directionEstimator, targetHistoryToken);
    }

    /**
     * Creates a hyperlink with its text and target history token specified.
     *
     * @param text
     *            the hyperlink's text
     * @param targetHistoryToken
     *            the history token to which it will link, which may not be null
     *            (use {@link Anchor} instead if you don't need history
     *            processing)
     */
    public Hyperlink(String text, String targetHistoryToken) {
        this(text, false, targetHistoryToken);
    }

    /**
     * Creates a hyperlink with its text target history token specified.
     *
     * @param text
     *            the hyperlink's text
     * @param asHTML
     *            <code>true</code> to treat the specified text as html
     * @param dir
     *            the text's direction
     * @param targetHistoryToken
     *            the history token to which it will link
     * @see #setTargetHistoryToken
     */
    private Hyperlink(String text, boolean asHTML, Direction dir, String targetHistoryToken) {
        this();
        directionalTextHelper.setTextOrHtml(text, dir, asHTML);
        setTargetHistoryToken(targetHistoryToken);
    }

    /**
     * Creates a hyperlink with its text and target history token specified.
     *
     * @param text
     *            the hyperlink's text
     * @param asHTML
     *            <code>true</code> to treat the specified text as html
     * @param directionEstimator
     *            A DirectionEstimator object used for automatic direction
     *            adjustment. For convenience,
     *            {@link #DEFAULT_DIRECTION_ESTIMATOR} can be used.
     * @param targetHistoryToken
     *            the history token to which it will link
     * @see #setTargetHistoryToken
     */
    private Hyperlink(String text, boolean asHTML, DirectionEstimator directionEstimator,
            String targetHistoryToken) {
        this();
        directionalTextHelper.setDirectionEstimator(directionEstimator);
        directionalTextHelper.setTextOrHtml(text, asHTML);
        setTargetHistoryToken(targetHistoryToken);
    }

    protected Hyperlink(Element elem) {
        if (elem == null) {
            setElement(anchorElem);
        } else {
            setElement(elem);
            DOM.appendChild(getElement(), anchorElem);
        }
        sinkEvents(Event.ONCLICK);
        setStyleName("gwt-Hyperlink");
        directionalTextHelper = new DirectionalTextHelper(anchorElem, /* is inline */ true);
    }

    /**
     * @deprecated Use {@link Anchor#addClickHandler} instead and call
     *             History.newItem from the handler if you need to process the
     *             click before the history token is set.
     */
    @Deprecated
    public HandlerRegistration addClickHandler(ClickHandler handler) {
        return addHandler(handler, ClickEvent.getType());
    }

    /**
     * @deprecated Use {@link Anchor#addClickHandler} instead and call
     *             History.newItem from the handler if you need to process the
     *             click before the history token is set.
     */
    @Deprecated
    public void addClickListener(ClickListener listener) {
        ListenerWrapper.WrappedClickListener.add(this, listener);
    }

    public DirectionEstimator getDirectionEstimator() {
        return directionalTextHelper.getDirectionEstimator();
    }

    public String getHTML() {
        return directionalTextHelper.getTextOrHtml(true);
    }

    /**
     * Gets the history token referenced by this hyperlink.
     * 
     * @return the target history token
     * @see #setTargetHistoryToken
     */
    public String getTargetHistoryToken() {
        return targetHistoryToken;
    }

    public String getText() {
        return directionalTextHelper.getTextOrHtml(false);
    }

    public Direction getTextDirection() {
        return directionalTextHelper.getTextDirection();
    }

    @Override
    public void onBrowserEvent(Event event) {
        super.onBrowserEvent(event);
        if (DOM.eventGetType(event) == Event.ONCLICK && impl.handleAsClick(event)) {
            History.newItem(getTargetHistoryToken());
            event.preventDefault();
        }
    }

    /**
     * @deprecated Use the {@link HandlerRegistration#removeHandler} method on
     *             the object returned by an add*Handler method instead
     */
    @Deprecated
    public void removeClickListener(ClickListener listener) {
        ListenerWrapper.WrappedClickListener.remove(this, listener);
    }

    /**
     * {@inheritDoc}
     * <p>
     * See note at {@link #setDirectionEstimator(DirectionEstimator)}.
     */
    public void setDirectionEstimator(boolean enabled) {
        directionalTextHelper.setDirectionEstimator(enabled);
    }

    /**
     * {@inheritDoc}
     * <p>
     * Note: DirectionEstimator should be set before the widget has any content;
     * it's highly recommended to set it using a constructor. Reason: if the
     * widget already has non-empty content, this will update its direction
     * according to the new estimator's result. This may cause flicker, and thus
     * should be avoided.
     */
    public void setDirectionEstimator(DirectionEstimator directionEstimator) {
        directionalTextHelper.setDirectionEstimator(directionEstimator);
    }

    /**
     * For compatibility - if old code uses Hyperlink, but the refs are really
     * full links
     */
    public void setHref(String href) {
        anchorElem.setPropertyString("href", href);
    }

    public void setHTML(SafeHtml html) {
        setHTML(html.asString());
    }

    public void setHTML(SafeHtml html, Direction dir) {
        directionalTextHelper.setTextOrHtml(html.asString(), dir, true);
    }

    public void setHTML(String html) {
        directionalTextHelper.setTextOrHtml(html, true);
    }

    /**
     * Sets the history token referenced by this hyperlink. This is the history
     * token that will be passed to {@link History#newItem} when this link is
     * clicked.
     *
     * @param targetHistoryToken
     *            the new history token, which may not be null (use
     *            {@link Anchor} instead if you don't need history processing)
     */
    public void setTargetHistoryToken(String targetHistoryToken) {
        assert targetHistoryToken != null : "targetHistoryToken must not be null, consider using Anchor instead";
        this.targetHistoryToken = targetHistoryToken;
        String hash = History.encodeHistoryTokenWithHash(targetHistoryToken);
        anchorElem.setPropertyString("href", hash);
    }

    public void setText(String text) {
        directionalTextHelper.setTextOrHtml(text, false);
    }

    public void setText(String text, Direction dir) {
        directionalTextHelper.setTextOrHtml(text, dir, false);
    }

    /**
     * <b>Affected Elements:</b>
     * <ul>
     * <li>-wrapper = the div around the link.</li>
     * </ul>
     * 
     * @see UIObject#onEnsureDebugId(String)
     */
    @Override
    protected void onEnsureDebugId(String baseID) {
        ensureDebugId(anchorElem, "", baseID);
        ensureDebugId(getElement(), baseID, "wrapper");
    }

    protected void superOnBrowserEvent(Event event) {
        super.onBrowserEvent(event);
    }
}