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     */
016    package com.github.gwtbootstrap.client.ui;
017    
018    import com.google.gwt.dom.client.Document;
019    import 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
030    public 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    }