001    package 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    
023    import org.gwtbootstrap3.client.ui.base.HasHref;
024    import org.gwtbootstrap3.client.ui.base.HasTargetHistoryToken;
025    import org.gwtbootstrap3.client.ui.base.button.AbstractToggleButton;
026    import org.gwtbootstrap3.client.ui.constants.ButtonType;
027    
028    import com.google.gwt.core.client.GWT;
029    import com.google.gwt.dom.client.AnchorElement;
030    import com.google.gwt.dom.client.Document;
031    import com.google.gwt.dom.client.Element;
032    import com.google.gwt.user.client.DOM;
033    import com.google.gwt.user.client.Event;
034    import com.google.gwt.user.client.History;
035    import 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     */
044    public 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    }