001package org.gwtbootstrap3.client.ui;
002
003/*
004 * #%L
005 * GwtBootstrap3
006 * %%
007 * Copyright (C) 2013 GwtBootstrap3
008 * %%
009 * Licensed under the Apache License, Version 2.0 (the "License");
010 * you may not use this file except in compliance with the License.
011 * You may obtain a copy of the License at
012 * 
013 *      http://www.apache.org/licenses/LICENSE-2.0
014 * 
015 * Unless required by applicable law or agreed to in writing, software
016 * distributed under the License is distributed on an "AS IS" BASIS,
017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018 * See the License for the specific language governing permissions and
019 * limitations under the License.
020 * #L%
021 */
022
023import org.gwtbootstrap3.client.ui.base.HasHref;
024import org.gwtbootstrap3.client.ui.base.HasTargetHistoryToken;
025import org.gwtbootstrap3.client.ui.base.button.AbstractToggleButton;
026import org.gwtbootstrap3.client.ui.constants.ButtonType;
027
028import com.google.gwt.core.client.GWT;
029import com.google.gwt.dom.client.AnchorElement;
030import com.google.gwt.dom.client.Document;
031import com.google.gwt.dom.client.Element;
032import com.google.gwt.user.client.DOM;
033import com.google.gwt.user.client.Event;
034import com.google.gwt.user.client.History;
035import com.google.gwt.user.client.ui.impl.HyperlinkImpl;
036
037/**
038 * Button based on {@code <a>} element.
039 *
040 * @author Sven Jacobs
041 * @see Button
042 * @see org.gwtbootstrap3.client.ui.base.button.AbstractToggleButton
043 */
044public class AnchorButton extends AbstractToggleButton implements HasHref, HasTargetHistoryToken {
045
046    private String targetHistoryToken;
047
048    private static HyperlinkImpl impl = GWT.create(HyperlinkImpl.class);
049
050    public AnchorButton(final ButtonType type) {
051        super(type);
052        setHref(EMPTY_HREF);
053        sinkEvents(Event.ONCLICK);
054    }
055
056    @Override
057    public void onBrowserEvent(Event event) {
058        super.onBrowserEvent(event);
059        if (getTargetHistoryToken() != null) {
060            // implementation is based on Hyperlink#onBrowserEvent
061            if (DOM.eventGetType(event) == Event.ONCLICK && impl.handleAsClick(event)) {
062                History.newItem(getTargetHistoryToken());
063                event.preventDefault();
064            }
065        }
066    }
067
068    /**
069     * Set the target history token for the widget. Note, that you should use either {@link #setTargetHistoryToken(String)}
070     * or {@link #setHref(String)}, but not both as {@link #setHref(String)} resets the target history token.
071     * @param targetHistoryToken String target history token of the widget
072     */
073    @Override
074    public void setTargetHistoryToken(final String targetHistoryToken) {
075        this.targetHistoryToken = targetHistoryToken;
076        if (targetHistoryToken != null) {
077            final String hash = History.encodeHistoryToken(targetHistoryToken);
078            getAnchorElement().setHref("#" + hash);
079        }
080    }
081
082    /**
083     * Get the target history token for the widget. May return {@code null} if no history token has been set or if
084     * it has been reset by {@link #setHref(String)}
085     * @return String the widget's target history token
086     */
087    @Override
088    public String getTargetHistoryToken() {
089        return targetHistoryToken;
090    }
091
092    public AnchorButton() {
093        this(ButtonType.DEFAULT);
094    }
095
096    /**
097     * Set's the HREF of the widget. Note, that you should use either {@link #setTargetHistoryToken(String)}
098     * or {@link #setHref(String)}, but not both as {@link #setHref(String)} resets the target history token.
099     * @param href String href
100     */
101    @Override
102    public void setHref(final String href) {
103        this.targetHistoryToken = null;
104        getAnchorElement().setHref(href);
105    }
106
107    @Override
108    public String getHref() {
109        return getAnchorElement().getHref();
110    }
111
112    @Override
113    protected Element createElement() {
114        return Document.get().createAnchorElement();
115    }
116
117    private AnchorElement getAnchorElement() {
118        return AnchorElement.as(getElement());
119    }
120}