001/*
002 *  Copyright 2012 GWT-Bootstrap
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package com.github.gwtbootstrap.client.ui;
017
018import com.google.gwt.dom.client.Document;
019import com.google.gwt.dom.client.Element;
020
021//@formatter:off
022/**
023 * {@linkplain Navbar} uses this class for the scrollspy.
024 * 
025 * @since 2.0.4.0
026 * @author Carlos Alexandro Becker
027 * @see <a href="http://twitter.github.com/bootstrap/javascript.html#scrollspy">Twitter Bootstrap ScrollSpy</a>
028 */
029//@formatter:on
030public class Scrollspy {
031
032        private Navbar navbar;
033        
034        /** spy target element */
035        private Element spyElement;
036
037        /** data-target */
038        private String target;
039
040        /** data-offset */
041        private Integer offset;
042        
043        private boolean configured;
044
045        /**
046         * 
047         * @param navbar
048         *            The navbar that will be spied.
049         */
050        public Scrollspy(Navbar navbar) {
051                super();
052                this.navbar = navbar;
053                
054                if(navbar.getId() != null && navbar.getId().length() > 0) {
055                        setTarget("#" + navbar.getId());
056                }
057        }
058        
059        /**
060         * Create Empty Scrollspy
061         */
062        public Scrollspy() {
063            super();
064        }
065
066        /**
067         * Get navbar
068         * @return nabvar.
069         */
070        public Navbar getNavbar() {
071                return navbar;
072        }
073
074        /**
075         * set navbar
076         * @param navbar
077         */
078        public void setNavbar(Navbar navbar) {
079                this.navbar = navbar;
080        }
081        
082        /**
083         * set data-target.
084         * <p>
085         * If set this,{@link #spyElement} is set {@code data-target} attribute this {@code target} when {@link #configure()} is called.
086         * </p>
087         * @param target
088         *                               data-target value.like this,{@code #some-id} {@code .some-classes}
089         * 
090         * @see <a href="http://twitter.github.com/bootstrap/javascript.html#scrollspy">Twitter Bootstrap ScrollSpy Options</a>
091         */
092        public void setTarget(String target) {
093                this.target = target;
094                
095        }
096        
097        /**
098         * set spy target element.
099         * <p>
100         * If set this,Scrollspy set some setting to this argment 
101         * when {@link #configure()} is called.<br/>
102         * 
103         * If don't set this,Scrollspy set some setting to {@code body} tag.
104         * </p>
105         * 
106         * @param element
107         *                               spy target element.
108         * @see <a href="http://twitter.github.com/bootstrap/javascript.html#scrollspy">Twitter Bootstrap ScrollSpy Options</a>
109         */
110        public void setSpyElement(Element element) {
111                this.spyElement = element;
112        }
113        
114        /**
115         * set data-offset.
116         * <p>
117         * If set this,{@link #spyElement} is set {@code data-offset} attribute this {@code target} when {@link #configure()} is called.
118         * </p>
119         * @param target
120         *                               data-offset value.
121         * @see <a href="http://twitter.github.com/bootstrap/javascript.html#scrollspy">Twitter Bootstrap ScrollSpy Options</a>
122         */
123        public void setOffset(Integer offset) {
124                this.offset = offset;
125        }
126
127        /**
128         * Configure the scrollspy in the configured navbar.
129         */
130        public void configure() {
131                
132                Element spyTargetElement = getSpyElement();
133                
134                assert spyTargetElement != null : "houston, we need a spy element here!";
135                
136                jsConfigure(spyTargetElement , target, offset == null ? -1 : offset );
137                
138                configured = true;
139        }
140        
141        public boolean isConfigured() {
142                return configured;
143        }
144        
145        public Element getSpyElement() {
146                return spyElement != null ? spyElement : Document.get().getBody();
147        }
148        
149        public void refresh() {
150            refresh(getSpyElement());
151        }
152        
153        private native void refresh(Element e) /*-{
154            $wnd.jQuery(e).scrollspy('refresh');
155        }-*/;
156        
157        
158    private native void jsConfigure(Element e, String target,int offset) /*-{
159        var $this = $wnd.jQuery(e);
160        if($this.data('scrollspy')) {
161            $this.data('scrollspy').$scrollElement.off('scroll.scroll.data-api');
162            $this.removeData('spy');
163            $this.removeData('target');
164            $this.removeData('offset');
165            $this.removeData('scrollspy');
166        }
167        
168        var applyOptions = false;
169        var options = {};
170        if(target) {
171            options.target = target;
172            applyOptions = true;
173        }
174        
175        if(offset != -1) {
176            options.offset = offset;
177            applyOptions = true;
178        }
179        
180        
181        if(applyOptions) {
182            $this.scrollspy(options);
183        } else {
184            $this.scrollspy();
185        }
186        }-*/;
187
188}