001    /*
002     * Copyright 2006 Google Inc.
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005     * use this file except in compliance with the License. You may obtain a copy of
006     * 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, WITHOUT
012     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013     * License for the specific language governing permissions and limitations under
014     * the License.
015     */
016    package com.google.gwt.user.client.impl;
017    
018    import com.google.gwt.user.client.EventListener;
019    import com.google.gwt.user.client.Element;
020    import com.google.gwt.user.client.Event;
021    
022    /**
023     * Native implementation associated with {@link com.google.gwt.user.client.Dom}.
024     */
025    public abstract class DOMImpl {
026    
027      public native void appendChild(Element parent, Element child) /*-{
028        parent.appendChild(child);
029      }-*/;
030    
031      public abstract boolean compare(Element elem1, Element elem2);
032    
033      public native Element createElement(String tag) /*-{
034        return $doc.createElement(tag);
035      }-*/;
036    
037      public native Element createInputElement(String type) /*-{
038        var e = $doc.createElement("INPUT");
039        e.type = type;
040        return e;
041      }-*/;
042    
043      public abstract Element createInputRadioElement(String group);
044    
045      public native void eventCancelBubble(Event evt, boolean cancel) /*-{
046        evt.cancelBubble = cancel;
047      }-*/;
048    
049      public native boolean eventGetAltKey(Event evt) /*-{
050        return evt.altKey;
051      }-*/;
052    
053      public native int eventGetButton(Event evt) /*-{
054        return evt.button;
055      }-*/;
056    
057      public native int eventGetClientX(Event evt) /*-{
058        return evt.clientX;
059      }-*/;
060    
061      public native int eventGetClientY(Event evt) /*-{
062        return evt.clientY;
063      }-*/;
064    
065      public native boolean eventGetCtrlKey(Event evt) /*-{
066        return evt.ctrlKey;
067      }-*/;
068    
069      public native Element eventGetFromElement(Event evt) /*-{
070        return evt.fromElement ? evt.fromElement : null;
071      }-*/;
072    
073      public native char eventGetKeyCode(Event evt) /*-{
074        return evt.keyCode;
075      }-*/;
076    
077      public native boolean eventGetRepeat(Event evt) /*-{
078        return evt.repeat;
079      }-*/;
080    
081      public native int eventGetScreenX(Event evt) /*-{
082        return evt.screenX;
083      }-*/;
084    
085      public native int eventGetScreenY(Event evt) /*-{
086        return evt.screenY;
087      }-*/;
088    
089      public native boolean eventGetShiftKey(Event evt) /*-{
090        return evt.shiftKey;
091      }-*/;
092    
093      public abstract Element eventGetTarget(Event evt);
094    
095      public native Element eventGetToElement(Event evt) /*-{
096        return evt.toElement ? evt.toElement : null;
097      }-*/;
098    
099      public native String eventGetType(Event evt) /*-{
100        return evt.type;
101      }-*/;
102    
103      public native int eventGetTypeInt(Event evt) /*-{
104        switch (evt.type) {
105          case "blur": return 0x01000;
106          case "change": return 0x00400;
107          case "click": return 0x00001;
108          case "dblclick": return 0x00002;
109          case "focus": return 0x00800;
110          case "keydown": return 0x00080;
111          case "keypress": return 0x00100;
112          case "keyup": return 0x00200;
113          case "load": return 0x08000;
114          case "losecapture": return 0x02000;
115          case "mousedown": return 0x00004;
116          case "mousemove": return 0x00040;
117          case "mouseout": return 0x00020;
118          case "mouseover": return 0x00010;
119          case "mouseup": return 0x00008;
120          case "scroll": return 0x04000;
121          case "error": return 0x10000;
122        }
123      }-*/;
124    
125      public abstract void eventPreventDefault(Event evt);
126    
127      public native void eventSetKeyCode(Event evt, char key) /*-{
128        evt.keyCode = key;
129      }-*/;
130    
131      public abstract String eventToString(Event evt);
132    
133      public native int getAbsoluteLeft(Element elem) /*-{
134        var left = 0;
135        while (elem) {
136          left += elem.offsetLeft - elem.scrollLeft;
137          elem = elem.offsetParent;
138        }
139        return left + $doc.body.scrollLeft;
140      }-*/;
141    
142      public native int getAbsoluteTop(Element elem) /*-{
143        var top = 0;
144        while (elem) {
145          top += elem.offsetTop - elem.scrollTop;
146          elem = elem.offsetParent;
147        }
148        return top + $doc.body.scrollTop;
149      }-*/;
150      
151      public native String getAttribute(Element elem, String attr) /*-{
152        var ret = elem[attr];
153        return (ret === undefined) ? null : String(ret);
154      }-*/;
155    
156      public abstract Element getChild(Element elem, int index); 
157    
158      public abstract int getChildCount(Element elem);
159    
160      public abstract int getChildIndex(Element parent, Element child);
161    
162      public native Element getElementById(String id) /*-{
163        var elem = $doc.getElementById(id);
164        return elem ? elem : null;
165      }-*/;
166    
167      public native int getEventsSunk(Element elem) /*-{
168        return elem.__eventBits ? elem.__eventBits : 0;
169      }-*/;
170    
171      public abstract Element getFirstChild(Element elem);
172    
173      public native String getInnerHTML(Element elem) /*-{
174        var ret = elem.innerHTML;
175        return (ret === undefined) ? null : ret;
176      }-*/;
177    
178      public native String getInnerText(Element node) /*-{
179        // To mimic IE's 'innerText' property in the W3C DOM, we need to recursively
180        // concatenate all child text nodes (depth first).
181        var text = '', child = node.firstChild;
182        while (child) {
183          if (child.nodeType == 1){ // 1 == Element node
184            text += this.@com.google.gwt.user.client.impl.DOMImpl::getInnerText(Lcom/google/gwt/user/client/Element;)(child);
185          } else if (child.nodeValue) {
186            text += child.nodeValue;
187          }
188          child = child.nextSibling;
189        }
190        return text;
191      }-*/;
192    
193      public native int getIntAttribute(Element elem, String attr) /*-{
194        return parseInt(elem[attr]);
195      }-*/;
196    
197      public native int getIntStyleAttribute(Element elem, String attr) /*-{
198        var i = parseInt(elem.style[attr]);
199        if (!i)
200          return 0;
201        return i;
202      }-*/;
203    
204      public abstract Element getNextSibling(Element elem);
205    
206      public abstract Element getParent(Element elem);
207    
208      public native String getStyleAttribute(Element elem, String attr) /*-{
209        var ret = elem.style[attr];
210        return (ret === undefined) ? null : ret;
211      }-*/;
212    
213      public abstract void init();
214    
215      public abstract void insertChild(Element parent, Element child,
216          int index);
217    
218      public abstract boolean isOrHasChild(Element parent, Element child);
219    
220      public abstract void releaseCapture(Element elem);
221    
222      public native void removeChild(Element parent, Element child) /*-{
223        parent.removeChild(child);
224      }-*/;
225    
226      public native void setAttribute(Element elem, String attr, String value) /*-{
227        elem[attr] = value;
228      }-*/;
229    
230      public native void setBooleanAttribute(Element elem, String attr,
231          boolean value) /*-{
232        elem[attr] = value;
233      }-*/;
234    
235      public abstract void setCapture(Element elem);
236    
237      public native void setEventListener(Element elem,
238          EventListener listener) /*-{
239        elem.__listener = listener;
240      }-*/;
241    
242      public native void setInnerHTML(Element elem, String html) /*-{
243        if (!html)
244          html = '';
245        elem.innerHTML = html;
246      }-*/;
247    
248      public native void setInnerText(Element elem, String text) /*-{
249        // Remove all children first.
250        while (elem.firstChild)
251          elem.removeChild(elem.firstChild);
252    
253        // Add a new text node.
254        elem.appendChild($doc.createTextNode(text));
255      }-*/;
256    
257      public native void setStyleAttribute(Element elem, String attr,
258          String value) /*-{
259        elem.style[attr] = value;
260      }-*/;
261    
262      public abstract void sinkEvents(Element elem, int eventBits);
263    
264      public abstract String toString(Element elem);
265    
266      protected native void elementSetIntAttribute(Element elem, String attr,
267          int value) /*-{
268        elem[attr] = value;
269      }-*/;
270    }