Changeset 13726 in webkit
- Timestamp:
- Apr 7, 2006 1:31:17 AM (18 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r13723 r13726 1 2006-04-07 Maciej Stachowiak <mjs@apple.com> 2 3 Reviewed by Anders. 4 5 Added test case for incidental fix from this change: 6 7 - Convert Element JS bindings to be almost completely autogenerated 8 http://bugzilla.opendarwin.org/show_bug.cgi?id=8227 9 10 * fast/dom/Element/dimension-properties-unrendered-expected.txt: Added. 11 * fast/dom/Element/dimension-properties-unrendered.html: Added. 12 * fast/dom/Element/resources/dimension-properties-unrendered.js: Added. 13 1 14 2006-04-06 Beth Dakin <bdakin@apple.com> 2 15 -
trunk/WebCore/ChangeLog
r13723 r13726 1 2006-04-06 Maciej Stachowiak <mjs@apple.com> 2 3 Reviewed by Anders. 4 5 - Convert Element JS bindings to be almost completely autogenerated 6 http://bugzilla.opendarwin.org/show_bug.cgi?id=8227 7 8 * dom/Element.idl: Declare full interface in IDL. 9 * dom/Element.h: 10 (WebCore::Element::tagQName): Renamed from tagName, so the real DOM 11 method can be called tagName. 12 (WebCore::Element::tagName): inline alias for nodeName. 13 * dom/Element.cpp: 14 (WebCore::Element::scrollByUnits): Moved logic from JS bindings to 15 core DOM. 16 (WebCore::Element::scrollByLines): ditto 17 (WebCore::Element::scrollByPages): ditto 18 (WebCore::Element::offsetLeft): ditto, plus make unrendered elements return 0 not undefined 19 (WebCore::Element::offsetTop): ditto, plus make unrendered elements return 0 not undefined 20 (WebCore::Element::offsetWidth): ditto, plus make unrendered elements return 0 not undefined 21 (WebCore::Element::offsetHeight): ditto, plus make unrendered elements return 0 not undefined 22 (WebCore::Element::offsetParent): ditto 23 (WebCore::Element::clientWidth): ditto, plus make unrendered elements return 0 not undefined 24 (WebCore::Element::clientHeight): ditto, plus make unrendered elements return 0 not undefined 25 (WebCore::Element::scrollLeft): ditto 26 (WebCore::Element::scrollTop): ditto 27 (WebCore::Element::setScrollLeft): ditto 28 (WebCore::Element::setScrollTop): ditto 29 (WebCore::Element::scrollWidth): ditto, plus make unrendered elements return 0 not undefined 30 (WebCore::Element::scrollHeight): ditto, plus make unrendered elements return 0 not undefined 31 32 * bindings/scripts/CodeGeneratorJS.pm: Added support for 33 ConvertUndefinedToTrue, for benefit of scroll methods where 34 omitted arguments should be treated as true. However, maybe 35 explicit overloading in the IDL would be a better long-term 36 approach for optional arguments. 37 38 * khtml/ecma/kjs_binding.cpp: 39 (KJS::valueToStringWithNullCheck): fixed formatting 40 (KJS::valueToBooleanTreatUndefinedAsTrue): added for binding of scrollIntoView 41 (isn't this lame?) 42 * khtml/ecma/kjs_binding.h: 43 (KJS::toJS): fixed formatting, added new stuff 44 * khtml/ecma/kjs_dom.cpp: 45 (KJS::DOMElement::getValueProperty): removed most of contents 46 (KJS::DOMElement::putValueProperty): ditto 47 (KJS::DOMElementProtoFunc::callAsFunction): ditto 48 49 * css/cssstyleselector.cpp: 50 (WebCore::CSSStyleSelector::canShareStyleWithElement): updated for rename 51 of tagName to tagQName 52 (WebCore::CSSStyleSelector::checkOneSelector): ditto 53 * dom/Document.cpp: 54 (WebCore::Document::importNode): ditto 55 * editing/ApplyStyleCommand.cpp: 56 (WebCore::ApplyStyleCommand::removeInlineStyle): ditto 57 (WebCore::areIdenticalElements): ditto 58 * html/HTMLElement.cpp: 59 (WebCore::HTMLElement::inEitherTagList): ditto 60 (WebCore::HTMLElement::inInlineTagList): ditto 61 (WebCore::HTMLElement::inBlockTagList): ditto 62 1 63 2006-04-06 Beth Dakin <bdakin@apple.com> 2 64 -
trunk/WebCore/bindings/scripts/CodeGeneratorJS.pm
r13706 r13726 800 800 801 801 if ($type eq "boolean") { 802 return "$value->toBoolean(exec)"; 802 my $conv = $signature->extendedAttributes->{"ConvertUndefinedToTrue"}; 803 if (defined $conv) { 804 return "valueToBooleanTreatUndefinedAsTrue(exec, $value)"; 805 } else { 806 return "$value->toBoolean(exec)"; 807 } 803 808 } elsif ($type eq "unsigned long" or $type eq "long") { 804 809 return "$value->toInt32(exec)"; -
trunk/WebCore/css/cssstyleselector.cpp
r13687 r13726 620 620 if (n->isStyledElement()) { 621 621 StyledElement* s = static_cast<StyledElement*>(n); 622 if (s->renderer() && (s->tag Name() == element->tagName()) && !s->hasID() &&622 if (s->renderer() && (s->tagQName() == element->tagQName()) && !s->hasID() && 623 623 (s->hasClass() == element->hasClass()) && !s->inlineStyleDecl() && 624 624 (s->hasMappedAttributes() == styledElement->hasMappedAttributes()) && … … 1301 1301 // first-of-type matches the first element of its type! 1302 1302 if (e->parentNode() && e->parentNode()->isElementNode()) { 1303 const QualifiedName& type = e->tag Name();1303 const QualifiedName& type = e->tagQName(); 1304 1304 Node *n = e->previousSibling(); 1305 1305 while (n) { … … 1327 1327 // last-of-type matches the last element of its type! 1328 1328 if (e->parentNode() && e->parentNode()->isElementNode()) { 1329 const QualifiedName& type = e->tag Name();1329 const QualifiedName& type = e->tagQName(); 1330 1330 Node *n = e->nextSibling(); 1331 1331 while (n) { … … 1358 1358 // If both first-of-type and last-of-type apply, then only-of-type applies. 1359 1359 if (e->parentNode() && e->parentNode()->isElementNode()) { 1360 const QualifiedName& type = e->tag Name();1360 const QualifiedName& type = e->tagQName(); 1361 1361 Node *n = e->previousSibling(); 1362 1362 while (n && !static_cast<Element*>(n)->hasTagName(type)) -
trunk/WebCore/dom/Document.cpp
r13715 r13726 476 476 case ELEMENT_NODE: { 477 477 Element *oldElement = static_cast<Element *>(importedNode); 478 RefPtr<Element> newElement = createElementNS(oldElement->namespaceURI(), oldElement->tag Name().toString(), ec);478 RefPtr<Element> newElement = createElementNS(oldElement->namespaceURI(), oldElement->tagQName().toString(), ec); 479 479 480 480 if (ec != 0) -
trunk/WebCore/dom/Element.cpp
r13630 r13726 152 152 } 153 153 154 void Element::scrollByUnits(int units, KWQScrollGranularity granularity) 155 { 156 document()->updateLayoutIgnorePendingStylesheets(); 157 if (RenderObject *rend = renderer()) { 158 if (rend->hasOverflowClip()) { 159 KWQScrollDirection direction = KWQScrollDown; 160 if (units < 0) { 161 direction = KWQScrollUp; 162 units = -units; 163 } 164 rend->layer()->scroll(direction, granularity, units); 165 } 166 } 167 } 168 169 void Element::scrollByLines(int lines) 170 { 171 scrollByUnits(lines, KWQScrollLine); 172 } 173 174 void Element::scrollByPages(int pages) 175 { 176 scrollByUnits(pages, KWQScrollPage); 177 } 178 179 int Element::offsetLeft() 180 { 181 document()->updateLayoutIgnorePendingStylesheets(); 182 if (RenderObject* rend = renderer()) 183 return rend->offsetLeft(); 184 return 0; 185 } 186 187 int Element::offsetTop() 188 { 189 document()->updateLayoutIgnorePendingStylesheets(); 190 if (RenderObject* rend = renderer()) 191 return rend->offsetTop(); 192 return 0; 193 } 194 195 int Element::offsetWidth() 196 { 197 document()->updateLayoutIgnorePendingStylesheets(); 198 if (RenderObject* rend = renderer()) 199 return rend->offsetWidth(); 200 return 0; 201 } 202 203 int Element::offsetHeight() 204 { 205 document()->updateLayoutIgnorePendingStylesheets(); 206 if (RenderObject* rend = renderer()) 207 return rend->offsetHeight(); 208 return 0; 209 } 210 211 Element* Element::offsetParent() 212 { 213 document()->updateLayoutIgnorePendingStylesheets(); 214 if (RenderObject* rend = renderer()) 215 return static_cast<Element*>(rend->offsetParent()->element()); 216 return 0; 217 } 218 219 int Element::clientWidth() 220 { 221 document()->updateLayoutIgnorePendingStylesheets(); 222 if (RenderObject* rend = renderer()) 223 return rend->clientWidth(); 224 return 0; 225 } 226 227 int Element::clientHeight() 228 { 229 document()->updateLayoutIgnorePendingStylesheets(); 230 if (RenderObject* rend = renderer()) 231 return rend->clientHeight(); 232 return 0; 233 } 234 235 int Element::scrollLeft() 236 { 237 document()->updateLayoutIgnorePendingStylesheets(); 238 RenderObject* rend = renderer(); 239 if (rend && rend->layer()) 240 return rend->layer()->scrollXOffset(); 241 return 0; 242 } 243 244 int Element::scrollTop() 245 { 246 document()->updateLayoutIgnorePendingStylesheets(); 247 RenderObject* rend = renderer(); 248 if (rend && rend->layer()) 249 return rend->layer()->scrollYOffset(); 250 return 0; 251 } 252 253 void Element::setScrollLeft(int newLeft) 254 { 255 RenderObject *rend = renderer(); 256 if (rend && rend->hasOverflowClip()) 257 rend->layer()->scrollToXOffset(newLeft); 258 } 259 260 void Element::setScrollTop(int newTop) 261 { 262 RenderObject *rend = renderer(); 263 if (rend && rend->hasOverflowClip()) 264 rend->layer()->scrollToYOffset(newTop); 265 } 266 267 int Element::scrollWidth() 268 { 269 document()->updateLayoutIgnorePendingStylesheets(); 270 if (RenderObject* rend = renderer()) 271 return rend->scrollWidth(); 272 return 0; 273 } 274 275 int Element::scrollHeight() 276 { 277 document()->updateLayoutIgnorePendingStylesheets(); 278 if (RenderObject* rend = renderer()) 279 return rend->scrollHeight(); 280 return 0; 281 } 282 154 283 static inline bool inHTMLDocument(const Element* e) 155 284 { -
trunk/WebCore/dom/Element.h
r13555 r13726 31 31 #include "Attr.h" 32 32 #include "QualifiedName.h" 33 #include "KWQScrollBar.h" 33 34 34 35 namespace WebCore { … … 69 70 void scrollIntoViewIfNeeded(bool centerIfNeeded); 70 71 72 void scrollByUnits(int units, KWQScrollGranularity granularity); 73 void scrollByLines(int lines); 74 void scrollByPages(int pages); 75 76 int offsetLeft(); 77 int offsetTop(); 78 int offsetWidth(); 79 int offsetHeight(); 80 Element* offsetParent(); 81 int clientWidth(); 82 int clientHeight(); 83 int scrollLeft(); 84 int scrollTop(); 85 void setScrollLeft(int); 86 void setScrollTop(int); 87 int scrollWidth(); 88 int scrollHeight(); 89 71 90 void removeAttribute(const String &name, ExceptionCode& ec); 72 91 void removeAttributeNS(const String &namespaceURI, const String& localName, ExceptionCode&); … … 80 99 virtual CSSStyleDeclaration *style(); 81 100 82 virtual const QualifiedName& tagName() const { return m_tagName; } 101 const QualifiedName& tagQName() const { return m_tagName; } 102 String tagName() const { return nodeName(); } 83 103 virtual bool hasTagName(const QualifiedName& tagName) const { return m_tagName.matches(tagName); } 84 104 -
trunk/WebCore/dom/Element.idl
r13611 r13726 22 22 interface [LegacyParent=KJS::DOMElement] Element : EventTargetNode { 23 23 24 // DOM Level 1 24 // DOM Level 1 Core 25 25 26 NodeList getElementsByTagName(in DOMString name);26 readonly attribute [ConvertNullStringTo=Null] DOMString tagName; 27 27 28 // ConvertNullStringTo=Null is used here since if the attribute isn't present at all29 // the function should return null and not "".30 28 [ConvertNullStringTo=Null] DOMString getAttribute(in DOMString name); 31 29 … … 45 43 raises(DOMException); 46 44 47 // DOM Level 245 NodeList getElementsByTagName(in DOMString name); 48 46 49 NodeList getElementsByTagNameNS(in [ConvertNullToNullString] DOMString namespaceURI, 50 in DOMString localName); 51 52 boolean hasAttribute(in DOMString name); 53 54 boolean hasAttributeNS(in [ConvertNullToNullString] DOMString namespaceURI, 55 in DOMString localName); 47 // DOM Level 2 Core 56 48 57 49 DOMString getAttributeNS(in [ConvertNullToNullString] DOMString namespaceURI, … … 67 59 raises(DOMException); 68 60 61 NodeList getElementsByTagNameNS(in [ConvertNullToNullString] DOMString namespaceURI, 62 in DOMString localName); 63 69 64 Attr getAttributeNodeNS(in [ConvertNullToNullString] DOMString namespaceURI, 70 65 in DOMString localName); … … 73 68 raises(DOMException); 74 69 75 // extensions70 boolean hasAttribute(in DOMString name); 76 71 77 void focus();78 void blur();72 boolean hasAttributeNS(in [ConvertNullToNullString] DOMString namespaceURI, 73 in DOMString localName); 79 74 80 75 readonly attribute CSSStyleDeclaration style; 81 76 82 // IE-only extensions 77 // Common extensions 78 79 readonly attribute long offsetLeft; 80 81 readonly attribute long offsetTop; 82 83 readonly attribute long offsetWidth; 84 85 readonly attribute long offsetHeight; 86 87 readonly attribute Element offsetParent; 88 89 readonly attribute long clientWidth; 90 91 readonly attribute long clientHeight; 92 93 attribute long scrollLeft; 94 95 attribute long scrollTop; 96 97 readonly attribute long scrollWidth; 98 99 readonly attribute long scrollHeight; 100 101 void focus(); 102 103 void blur(); 104 105 void scrollIntoView(in [ConvertUndefinedToTrue] boolean alignWithTop); 106 107 // IE extensions 83 108 84 109 Node insertAdjacentElement(in DOMString position, … … 88 113 boolean contains(in Element element); 89 114 115 // WebKit extensions 116 117 void scrollIntoViewIfNeeded(in [ConvertUndefinedToTrue] boolean alignWithTop); 118 119 void scrollByLines(in long lines); 120 121 void scrollByPages(in long pages); 122 90 123 }; 91 124 -
trunk/WebCore/editing/ApplyStyleCommand.cpp
r13532 r13726 900 900 Node *prev = elem->traversePreviousNodePostOrder(); 901 901 Node *next = elem->traverseNextNode(); 902 if (m_styledInlineElement && elem->hasTagName(m_styledInlineElement->tag Name()))902 if (m_styledInlineElement && elem->hasTagName(m_styledInlineElement->tagQName())) 903 903 removeNodePreservingChildren(elem); 904 904 if (isHTMLStyleNode(style.get(), elem)) … … 1027 1027 Element *secondElement = static_cast<Element *>(second); 1028 1028 1029 if (!firstElement->tag Name().matches(secondElement->tagName()))1029 if (!firstElement->tagQName().matches(secondElement->tagQName())) 1030 1030 return false; 1031 1031 -
trunk/WebCore/html/HTMLElement.cpp
r13581 r13726 751 751 if (newChild->isHTMLElement()) { 752 752 const HTMLElement* child = static_cast<const HTMLElement*>(newChild); 753 if (inlineTagList()->contains(child->tag Name().localName().impl()))753 if (inlineTagList()->contains(child->tagQName().localName().impl())) 754 754 return true; 755 if (blockTagList()->contains(child->tag Name().localName().impl()))755 if (blockTagList()->contains(child->tagQName().localName().impl())) 756 756 return true; 757 return !isRecognizedTagName(child->tag Name()); // Accept custom html tags757 return !isRecognizedTagName(child->tagQName()); // Accept custom html tags 758 758 } 759 759 … … 768 768 if (newChild->isHTMLElement()) { 769 769 const HTMLElement* child = static_cast<const HTMLElement*>(newChild); 770 if (inlineTagList()->contains(child->tag Name().localName().impl()))770 if (inlineTagList()->contains(child->tagQName().localName().impl())) 771 771 return true; 772 return !isRecognizedTagName(child->tag Name()); // Accept custom html tags772 return !isRecognizedTagName(child->tagQName()); // Accept custom html tags 773 773 } 774 774 … … 783 783 if (newChild->isHTMLElement()) { 784 784 const HTMLElement* child = static_cast<const HTMLElement*>(newChild); 785 return (blockTagList()->contains(child->tag Name().localName().impl()));785 return (blockTagList()->contains(child->tagQName().localName().impl())); 786 786 } 787 787 -
trunk/WebCore/khtml/ecma/kjs_binding.cpp
r13706 r13726 256 256 } 257 257 258 String valueToStringWithNullCheck(ExecState *exec, JSValue *val)258 String valueToStringWithNullCheck(ExecState* exec, JSValue* val) 259 259 { 260 260 if (val->isNull()) 261 261 return String(); 262 262 return val->toString(exec); 263 } 264 265 bool valueToBooleanTreatUndefinedAsTrue(ExecState* exec, JSValue* val) 266 { 267 if (val->isUndefined()) 268 return true; 269 return val->toBoolean(exec); 263 270 } 264 271 -
trunk/WebCore/khtml/ecma/kjs_binding.h
r13706 r13726 157 157 * Get a String object or a null String if the value is null 158 158 */ 159 WebCore::String valueToStringWithNullCheck(ExecState* exec, JSValue *val);159 WebCore::String valueToStringWithNullCheck(ExecState* exec, JSValue* val); 160 160 161 template <typename T> inline JSValue* toJS(ExecState* exec, PassRefPtr<T> ptr) { return toJS(exec, ptr.get()); } 161 bool valueToBooleanTreatUndefinedAsTrue(ExecState* exec, JSValue* val); 162 163 template <typename T> inline JSValue* toJS(ExecState* exec, PassRefPtr<T> ptr) { return toJS(exec, ptr.get()); } 162 164 163 165 } // namespace -
trunk/WebCore/khtml/ecma/kjs_dom.cpp
r13706 r13726 805 805 806 806 /* Source for DOMElementProtoTable. Use "make hashtables" to regenerate. 807 @begin DOMElementProtoTable 8 808 scrollIntoView DOMElement::ScrollIntoView DontDelete|Function 1 809 scrollIntoViewIfNeeded DOMElement::ScrollIntoViewIfNeeded DontDelete|Function 1 810 811 # extension for Safari RSS 812 scrollByLines DOMElement::ScrollByLines DontDelete|Function 1 813 scrollByPages DOMElement::ScrollByPages DontDelete|Function 1 807 @begin DOMElementProtoTable 1 814 808 @end 815 809 */ … … 819 813 const ClassInfo DOMElement::info = { "Element", &DOMEventTargetNode::info, &DOMElementTable, 0 }; 820 814 /* Source for DOMElementTable. Use "make hashtables" to regenerate. 821 @begin DOMElementTable 17 822 tagName DOMElement::TagName DontDelete|ReadOnly 823 824 # IE extensions 825 offsetLeft DOMElement::OffsetLeft DontDelete|ReadOnly 826 offsetTop DOMElement::OffsetTop DontDelete|ReadOnly 827 offsetWidth DOMElement::OffsetWidth DontDelete|ReadOnly 828 offsetHeight DOMElement::OffsetHeight DontDelete|ReadOnly 829 offsetParent DOMElement::OffsetParent DontDelete|ReadOnly 830 clientWidth DOMElement::ClientWidth DontDelete|ReadOnly 831 clientHeight DOMElement::ClientHeight DontDelete|ReadOnly 832 scrollLeft DOMElement::ScrollLeft DontDelete 833 scrollTop DOMElement::ScrollTop DontDelete 834 scrollWidth DOMElement::ScrollWidth DontDelete|ReadOnly 835 scrollHeight DOMElement::ScrollHeight DontDelete|ReadOnly 815 @begin DOMElementTable 1 836 816 @end 837 817 */ … … 849 829 JSValue *DOMElement::getValueProperty(ExecState *exec, int token) const 850 830 { 851 Element *element = static_cast<Element *>(impl());852 switch (token) {853 case TagName:854 return jsStringOrNull(element->nodeName());855 856 default:857 // no DOM standard -- IE extension858 859 // Make sure our layout is up to date before we allow a query on these attributes.860 element->document()->updateLayoutIgnorePendingStylesheets();861 862 RenderObject *rend = element->renderer();863 864 switch (token) {865 case OffsetLeft:866 return rend ? jsNumber(rend->offsetLeft()) : static_cast<JSValue *>(jsUndefined());867 case OffsetTop:868 return rend ? jsNumber(rend->offsetTop()) : static_cast<JSValue *>(jsUndefined());869 case OffsetWidth:870 return rend ? jsNumber(rend->offsetWidth()) : static_cast<JSValue *>(jsUndefined());871 case OffsetHeight:872 return rend ? jsNumber(rend->offsetHeight()) : static_cast<JSValue *>(jsUndefined());873 case OffsetParent: {874 RenderObject* par = rend ? rend->offsetParent() : 0;875 return toJS(exec, par ? par->element() : 0);876 }877 case ClientWidth:878 return rend ? jsNumber(rend->clientWidth()) : static_cast<JSValue *>(jsUndefined());879 case ClientHeight:880 return rend ? jsNumber(rend->clientHeight()) : static_cast<JSValue *>(jsUndefined());881 case ScrollWidth:882 return rend ? jsNumber(rend->scrollWidth()) : static_cast<JSValue *>(jsUndefined());883 case ScrollHeight:884 return rend ? jsNumber(rend->scrollHeight()) : static_cast<JSValue *>(jsUndefined());885 case ScrollLeft:886 return jsNumber(rend && rend->layer() ? rend->layer()->scrollXOffset() : 0);887 case ScrollTop:888 return jsNumber(rend && rend->layer() ? rend->layer()->scrollYOffset() : 0);889 }890 }891 892 831 return jsUndefined(); 893 832 } … … 900 839 void DOMElement::putValueProperty(ExecState *exec, int token, JSValue *value, int /*attr*/) 901 840 { 902 WebCore::Node& node = *m_impl;903 switch (token) {904 case ScrollTop: {905 RenderObject *rend = node.renderer();906 if (rend && rend->hasOverflowClip())907 rend->layer()->scrollToYOffset(value->toInt32(exec));908 break;909 }910 case ScrollLeft: {911 RenderObject *rend = node.renderer();912 if (rend && rend->hasOverflowClip())913 rend->layer()->scrollToXOffset(value->toInt32(exec));914 break;915 }916 }917 841 } 918 842 … … 956 880 if (!thisObj->inherits(&KJS::DOMElement::info)) 957 881 return throwError(exec, TypeError); 958 DOMExceptionTranslator exception(exec);959 WebCore::Node& node = *static_cast<DOMNode*>(thisObj)->impl();960 Element &element = static_cast<Element &>(node);961 962 switch(id) {963 case DOMElement::ScrollIntoView:964 element.scrollIntoView(args[0]->isUndefinedOrNull() || args[0]->toBoolean(exec));965 return jsUndefined();966 case DOMElement::ScrollIntoViewIfNeeded:967 element.scrollIntoViewIfNeeded(args[0]->isUndefinedOrNull() || args[0]->toBoolean(exec));968 return jsUndefined();969 case DOMElement::ScrollByLines:970 case DOMElement::ScrollByPages:971 element.document()->updateLayoutIgnorePendingStylesheets();972 if (RenderObject *rend = element.renderer())973 if (rend->hasOverflowClip()) {974 KWQScrollDirection direction = KWQScrollDown;975 int multiplier = args[0]->toInt32(exec);976 if (multiplier < 0) {977 direction = KWQScrollUp;978 multiplier = -multiplier;979 }980 KWQScrollGranularity granularity = id == DOMElement::ScrollByLines ? KWQScrollLine : KWQScrollPage;981 rend->layer()->scroll(direction, granularity, multiplier);982 }983 return jsUndefined();984 }985 882 986 883 return jsUndefined();
Note: See TracChangeset
for help on using the changeset viewer.