OLD | NEW |
---|---|
1 // Copyright (c) 2008, Google Inc. | 1 // Copyright (c) 2008, Google Inc. |
2 // All rights reserved. | 2 // All rights reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // met: |
7 // | 7 // |
8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
284 | 284 |
285 static void WeakSVGElementInstanceCallback(v8::Persistent<v8::Object> obj, | 285 static void WeakSVGElementInstanceCallback(v8::Persistent<v8::Object> obj, |
286 void* param) { | 286 void* param) { |
287 SVGElementInstance* instance = static_cast<SVGElementInstance*>(param); | 287 SVGElementInstance* instance = static_cast<SVGElementInstance*>(param); |
288 ASSERT(dom_svg_element_instance_map().contains(instance)); | 288 ASSERT(dom_svg_element_instance_map().contains(instance)); |
289 | 289 |
290 instance->deref(); | 290 instance->deref(); |
291 dom_svg_element_instance_map().forget(instance); | 291 dom_svg_element_instance_map().forget(instance); |
292 } | 292 } |
293 | 293 |
294 v8::Handle<v8::Object> V8Proxy::SVGElementInstanceToV8Object( | 294 v8::Handle<v8::Value> V8Proxy::SVGElementInstanceToV8Object( |
295 SVGElementInstance* instance) { | 295 SVGElementInstance* instance) { |
296 if (!instance) return v8::Handle<v8::Object>(); | 296 if (!instance) return v8::Null(); |
297 | 297 |
298 v8::Handle<v8::Object> existing_instance = | 298 v8::Handle<v8::Object> existing_instance = |
299 dom_svg_element_instance_map().get(instance); | 299 dom_svg_element_instance_map().get(instance); |
300 if (!existing_instance.IsEmpty()) { | 300 if (!existing_instance.IsEmpty()) { |
301 return existing_instance; | 301 return existing_instance; |
302 } | 302 } |
303 | 303 |
304 instance->ref(); | 304 instance->ref(); |
305 | 305 |
306 // Instantiate the V8 object and remember it | 306 // Instantiate the V8 object and remember it |
307 v8::Handle<v8::Object> result = | 307 v8::Handle<v8::Object> result = |
308 InstantiateV8Object(V8ClassIndex::SVGELEMENTINSTANCE, instance); | 308 InstantiateV8Object(V8ClassIndex::SVGELEMENTINSTANCE, |
309 V8ClassIndex::SVGELEMENTINSTANCE, | |
310 instance); | |
309 if (!result.IsEmpty()) { | 311 if (!result.IsEmpty()) { |
310 // Only update the DOM SVG element map if the result is non-empty. | 312 // Only update the DOM SVG element map if the result is non-empty. |
311 dom_svg_element_instance_map().set(instance, | 313 dom_svg_element_instance_map().set(instance, |
312 v8::Persistent<v8::Object>::New(result)); | 314 v8::Persistent<v8::Object>::New(result)); |
313 } | 315 } |
314 return result; | 316 return result; |
315 } | 317 } |
316 | 318 |
317 // SVG non-node elements may have a reference to a context node which | 319 // SVG non-node elements may have a reference to a context node which |
318 // should be notified when the element is changed | 320 // should be notified when the element is changed |
319 static void WeakSVGObjectWithContext(v8::Persistent<v8::Object> obj, | 321 static void WeakSVGObjectWithContext(v8::Persistent<v8::Object> obj, |
320 void* param); | 322 void* param); |
321 | 323 |
322 // Map of SVG objects with contexts to V8 objects | 324 // Map of SVG objects with contexts to V8 objects |
323 static DOMWrapperMap<Peerable>& dom_svg_object_with_context_map() { | 325 static DOMWrapperMap<Peerable>& dom_svg_object_with_context_map() { |
324 static DOMPeerableWrapperMap<Peerable> | 326 static DOMPeerableWrapperMap<Peerable> |
325 static_dom_svg_object_with_context_map(&WeakSVGObjectWithContext); | 327 static_dom_svg_object_with_context_map(&WeakSVGObjectWithContext); |
326 return static_dom_svg_object_with_context_map; | 328 return static_dom_svg_object_with_context_map; |
327 } | 329 } |
328 | 330 |
329 // Map of SVG objects with contexts to their contexts | 331 // Map of SVG objects with contexts to their contexts |
330 static HashMap<void*, SVGElement*>& svg_object_to_context_map() { | 332 static HashMap<void*, SVGElement*>& svg_object_to_context_map() { |
331 static HashMap<void*, SVGElement*> static_svg_object_to_context_map; | 333 static HashMap<void*, SVGElement*> static_svg_object_to_context_map; |
332 return static_svg_object_to_context_map; | 334 return static_svg_object_to_context_map; |
333 } | 335 } |
334 | 336 |
335 v8::Handle<v8::Object> V8Proxy::SVGObjectWithContextToV8Object( | 337 v8::Handle<v8::Value> V8Proxy::SVGObjectWithContextToV8Object( |
336 Peerable* object, V8ClassIndex::V8WrapperType type) { | 338 Peerable* object, V8ClassIndex::V8WrapperType type) { |
337 if (!object) return v8::Handle<v8::Object>(); | 339 if (!object) return v8::Null(); |
338 | 340 |
339 // Special case: SVGPathSegs need to be downcast to their real type | 341 // Special case: SVGPathSegs need to be downcast to their real type |
340 if (type == V8ClassIndex::SVGPATHSEG) { | 342 if (type == V8ClassIndex::SVGPATHSEG) { |
341 type = V8Custom::DowncastSVGPathSeg(object); | 343 type = V8Custom::DowncastSVGPathSeg(object); |
342 } | 344 } |
343 | 345 |
344 v8::Persistent<v8::Object> result = | 346 v8::Persistent<v8::Object> result = |
345 dom_svg_object_with_context_map().get(object); | 347 dom_svg_object_with_context_map().get(object); |
346 if (result.IsEmpty()) { | 348 if (result.IsEmpty()) { |
347 v8::Local<v8::Object> v8obj = InstantiateV8Object(type, object); | 349 v8::Local<v8::Object> v8obj = InstantiateV8Object(type, type, object); |
348 if (!v8obj.IsEmpty()) { | 350 if (!v8obj.IsEmpty()) { |
349 result = v8::Persistent<v8::Object>::New(v8obj); | 351 result = v8::Persistent<v8::Object>::New(v8obj); |
350 dom_svg_object_with_context_map().set(object, result); | 352 dom_svg_object_with_context_map().set(object, result); |
351 } | 353 } |
352 } | 354 } |
353 | 355 |
354 return result; | 356 return result; |
355 } | 357 } |
356 | 358 |
357 static void WeakSVGObjectWithContext(v8::Persistent<v8::Object> obj, | 359 static void WeakSVGObjectWithContext(v8::Persistent<v8::Object> obj, |
(...skipping 743 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1101 case V8ClassIndex::HTMLOPTIONSCOLLECTION: | 1103 case V8ClassIndex::HTMLOPTIONSCOLLECTION: |
1102 SetCollectionNamedGetter<HTMLOptionsCollection>(desc, V8ClassIndex::NODE); | 1104 SetCollectionNamedGetter<HTMLOptionsCollection>(desc, V8ClassIndex::NODE); |
1103 desc->InstanceTemplate()->SetIndexedPropertyHandler( | 1105 desc->InstanceTemplate()->SetIndexedPropertyHandler( |
1104 USE_INDEXED_PROPERTY_GETTER(HTMLOptionsCollection), | 1106 USE_INDEXED_PROPERTY_GETTER(HTMLOptionsCollection), |
1105 USE_INDEXED_PROPERTY_SETTER(HTMLOptionsCollection)); | 1107 USE_INDEXED_PROPERTY_SETTER(HTMLOptionsCollection)); |
1106 desc->InstanceTemplate()->SetCallAsFunctionHandler( | 1108 desc->InstanceTemplate()->SetCallAsFunctionHandler( |
1107 USE_CALLBACK(HTMLCollectionCallAsFunction)); | 1109 USE_CALLBACK(HTMLCollectionCallAsFunction)); |
1108 break; | 1110 break; |
1109 case V8ClassIndex::HTMLSELECTELEMENT: | 1111 case V8ClassIndex::HTMLSELECTELEMENT: |
1110 desc->InstanceTemplate()->SetNamedPropertyHandler( | 1112 desc->InstanceTemplate()->SetNamedPropertyHandler( |
1111 CollectionNamedPropertyGetter<HTMLSelectElement>, | 1113 NodeCollectionNamedPropertyGetter<HTMLSelectElement>, |
1112 0, | 1114 0, |
1113 0, | 1115 0, |
1114 0, | 1116 0, |
1115 0, | 1117 0, |
1116 v8::External::New(reinterpret_cast<void*>(V8ClassIndex::NODE))); | 1118 v8::External::New(reinterpret_cast<void*>(V8ClassIndex::NODE))); |
1117 desc->InstanceTemplate()->SetIndexedPropertyHandler( | 1119 desc->InstanceTemplate()->SetIndexedPropertyHandler( |
1118 CollectionIndexedPropertyGetter<HTMLSelectElement>, | 1120 NodeCollectionIndexedPropertyGetter<HTMLSelectElement>, |
1119 USE_INDEXED_PROPERTY_SETTER(HTMLSelectElementCollection), | 1121 USE_INDEXED_PROPERTY_SETTER(HTMLSelectElementCollection), |
1120 0, | 1122 0, |
1121 0, | 1123 0, |
1122 CollectionIndexedPropertyEnumerator<HTMLSelectElement>, | 1124 NodeCollectionIndexedPropertyEnumerator<HTMLSelectElement>, |
1123 v8::External::New(reinterpret_cast<void*>(V8ClassIndex::NODE))); | 1125 v8::External::New(reinterpret_cast<void*>(V8ClassIndex::NODE))); |
1124 break; | 1126 break; |
1125 case V8ClassIndex::HTMLDOCUMENT: { | 1127 case V8ClassIndex::HTMLDOCUMENT: { |
1126 desc->InstanceTemplate()->SetNamedPropertyHandler( | 1128 desc->InstanceTemplate()->SetNamedPropertyHandler( |
1127 USE_NAMED_PROPERTY_GETTER(HTMLDocument), | 1129 USE_NAMED_PROPERTY_GETTER(HTMLDocument), |
1128 USE_NAMED_PROPERTY_SETTER(HTMLDocument), | 1130 USE_NAMED_PROPERTY_SETTER(HTMLDocument), |
1129 0, | 1131 0, |
1130 USE_NAMED_PROPERTY_DELETER(HTMLDocument)); | 1132 USE_NAMED_PROPERTY_DELETER(HTMLDocument)); |
1131 | 1133 |
1132 // We add an extra internal field to all Document wrappers for | 1134 // We add an extra internal field to all Document wrappers for |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1178 USE_NAMED_PROPERTY_GETTER(HTMLFrameSetElement)); | 1180 USE_NAMED_PROPERTY_GETTER(HTMLFrameSetElement)); |
1179 break; | 1181 break; |
1180 case V8ClassIndex::HTMLFORMELEMENT: | 1182 case V8ClassIndex::HTMLFORMELEMENT: |
1181 desc->InstanceTemplate()->SetNamedPropertyHandler( | 1183 desc->InstanceTemplate()->SetNamedPropertyHandler( |
1182 USE_NAMED_PROPERTY_GETTER(HTMLFormElement)); | 1184 USE_NAMED_PROPERTY_GETTER(HTMLFormElement)); |
1183 desc->InstanceTemplate()->SetIndexedPropertyHandler( | 1185 desc->InstanceTemplate()->SetIndexedPropertyHandler( |
1184 USE_INDEXED_PROPERTY_GETTER(HTMLFormElement), | 1186 USE_INDEXED_PROPERTY_GETTER(HTMLFormElement), |
1185 0, | 1187 0, |
1186 0, | 1188 0, |
1187 0, | 1189 0, |
1188 CollectionIndexedPropertyEnumerator<HTMLFormElement>, | 1190 NodeCollectionIndexedPropertyEnumerator<HTMLFormElement>, |
1189 v8::External::New(reinterpret_cast<void*>(V8ClassIndex::NODE))); | 1191 v8::External::New(reinterpret_cast<void*>(V8ClassIndex::NODE))); |
1190 break; | 1192 break; |
1191 case V8ClassIndex::STYLESHEET: // fall through | 1193 case V8ClassIndex::STYLESHEET: // fall through |
1192 case V8ClassIndex::CSSSTYLESHEET: { | 1194 case V8ClassIndex::CSSSTYLESHEET: { |
1193 // We add an extra internal field to hold a reference to | 1195 // We add an extra internal field to hold a reference to |
1194 // the owner node. | 1196 // the owner node. |
1195 v8::Local<v8::ObjectTemplate> instance_template = | 1197 v8::Local<v8::ObjectTemplate> instance_template = |
1196 desc->InstanceTemplate(); | 1198 desc->InstanceTemplate(); |
1197 ASSERT(instance_template->InternalFieldCount() == | 1199 ASSERT(instance_template->InternalFieldCount() == |
1198 V8Custom::kDefaultWrapperInternalFieldCount); | 1200 V8Custom::kDefaultWrapperInternalFieldCount); |
(...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1801 return v8::Context::GetCurrent(); | 1803 return v8::Context::GetCurrent(); |
1802 } | 1804 } |
1803 | 1805 |
1804 | 1806 |
1805 v8::Handle<v8::Value> V8Proxy::ToV8Object(V8ClassIndex::V8WrapperType type, | 1807 v8::Handle<v8::Value> V8Proxy::ToV8Object(V8ClassIndex::V8WrapperType type, |
1806 void* imp) { | 1808 void* imp) { |
1807 ASSERT(type != V8ClassIndex::EVENTLISTENER); | 1809 ASSERT(type != V8ClassIndex::EVENTLISTENER); |
1808 ASSERT(type != V8ClassIndex::EVENTTARGET); | 1810 ASSERT(type != V8ClassIndex::EVENTTARGET); |
1809 ASSERT(type != V8ClassIndex::EVENT); | 1811 ASSERT(type != V8ClassIndex::EVENT); |
1810 | 1812 |
1811 if (!imp) return v8::Null(); | |
1812 | |
1813 #define MAKE_CASE(TYPE, NAME) case V8ClassIndex::TYPE: | 1813 #define MAKE_CASE(TYPE, NAME) case V8ClassIndex::TYPE: |
1814 | 1814 |
1815 switch (type) { | 1815 switch (type) { |
1816 NODE_WRAPPER_TYPES(MAKE_CASE) | 1816 NODE_WRAPPER_TYPES(MAKE_CASE) |
1817 HTMLELEMENT_TYPES(MAKE_CASE) | 1817 HTMLELEMENT_TYPES(MAKE_CASE) |
1818 #if ENABLE(SVG) | 1818 #if ENABLE(SVG) |
1819 SVGNODE_WRAPPER_TYPES(MAKE_CASE) | 1819 SVGNODE_WRAPPER_TYPES(MAKE_CASE) |
1820 SVGELEMENT_TYPES(MAKE_CASE) | 1820 SVGELEMENT_TYPES(MAKE_CASE) |
1821 #endif | 1821 #endif |
1822 return NodeToV8Object(static_cast<Node*>(imp)); | 1822 return NodeToV8Object(static_cast<Node*>(imp)); |
(...skipping 14 matching lines...) Expand all Loading... | |
1837 return SVGObjectWithContextToV8Object(static_cast<Peerable*>(imp), | 1837 return SVGObjectWithContextToV8Object(static_cast<Peerable*>(imp), |
1838 type); | 1838 type); |
1839 } | 1839 } |
1840 #endif | 1840 #endif |
1841 default: | 1841 default: |
1842 break; | 1842 break; |
1843 } | 1843 } |
1844 | 1844 |
1845 #undef MAKE_CASE | 1845 #undef MAKE_CASE |
1846 | 1846 |
1847 if (!imp) return v8::Null(); | |
1848 | |
1847 // Non DOM node | 1849 // Non DOM node |
1848 Peerable* obj = static_cast<Peerable*>(imp); | 1850 Peerable* obj = static_cast<Peerable*>(imp); |
1849 v8::Persistent<v8::Object> result = dom_object_map().get(obj); | 1851 v8::Persistent<v8::Object> result = dom_object_map().get(obj); |
1850 if (result.IsEmpty()) { | 1852 if (result.IsEmpty()) { |
1851 v8::Local<v8::Object> v8obj = InstantiateV8Object(type, imp); | 1853 v8::Local<v8::Object> v8obj = InstantiateV8Object(type, type, imp); |
1852 if (!v8obj.IsEmpty()) { | 1854 if (!v8obj.IsEmpty()) { |
1853 result = v8::Persistent<v8::Object>::New(v8obj); | 1855 result = v8::Persistent<v8::Object>::New(v8obj); |
1854 dom_object_map().set(obj, result); | 1856 dom_object_map().set(obj, result); |
1855 | 1857 |
1856 // Special case for Location and Navigator. Both Safari and FF let | 1858 // Special case for Location and Navigator. Both Safari and FF let |
1857 // Location and Navigator JS wrappers survive GC. To mimic their | 1859 // Location and Navigator JS wrappers survive GC. To mimic their |
1858 // behaviors, V8 creates hidden references from the DOMWindow to | 1860 // behaviors, V8 creates hidden references from the DOMWindow to |
1859 // location and navigator objects. These references get cleared | 1861 // location and navigator objects. These references get cleared |
1860 // when the DOMWindow is reused by a new page. | 1862 // when the DOMWindow is reused by a new page. |
1861 if (type == V8ClassIndex::LOCATION) { | 1863 if (type == V8ClassIndex::LOCATION) { |
(...skipping 23 matching lines...) Expand all Loading... | |
1885 ASSERT(!global.IsEmpty()); | 1887 ASSERT(!global.IsEmpty()); |
1886 // Look for real DOM wrapper. | 1888 // Look for real DOM wrapper. |
1887 global = LookupDOMWrapper(V8ClassIndex::DOMWINDOW, global); | 1889 global = LookupDOMWrapper(V8ClassIndex::DOMWINDOW, global); |
1888 ASSERT(global->GetInternalField(internal_index)->IsUndefined()); | 1890 ASSERT(global->GetInternalField(internal_index)->IsUndefined()); |
1889 global->SetInternalField(internal_index, jsobj); | 1891 global->SetInternalField(internal_index, jsobj); |
1890 } | 1892 } |
1891 | 1893 |
1892 | 1894 |
1893 V8ClassIndex::V8WrapperType V8Proxy::GetDOMWrapperType( | 1895 V8ClassIndex::V8WrapperType V8Proxy::GetDOMWrapperType( |
1894 v8::Handle<v8::Object> object) { | 1896 v8::Handle<v8::Object> object) { |
1895 if (!MaybeDOMWrapper(object)) { | 1897 ASSERT(MaybeDOMWrapper(object)); |
1896 return V8ClassIndex::INVALID_CLASS_INDEX; | |
1897 } | |
1898 | 1898 |
1899 v8::Handle<v8::Value> type = object->GetInternalField(1); | 1899 v8::Handle<v8::Value> type = |
1900 object->GetInternalField(V8Custom::kDOMWrapperTypeIndex); | |
1900 return V8ClassIndex::FromInt(type->Int32Value()); | 1901 return V8ClassIndex::FromInt(type->Int32Value()); |
1901 } | 1902 } |
1902 | 1903 |
1903 | 1904 |
1904 void* V8Proxy::FastToNativeObjectImpl(V8ClassIndex::V8WrapperType type, | 1905 void* V8Proxy::ToNativeObjectImpl(V8ClassIndex::V8WrapperType type, |
1905 v8::Handle<v8::Value> object) { | 1906 v8::Handle<v8::Value> object) { |
1906 // Native event listener is per frame, it cannot be handled | 1907 // Native event listener is per frame, it cannot be handled |
1907 // by this generic function. | 1908 // by this generic function. |
1908 ASSERT(type != V8ClassIndex::EVENTLISTENER); | 1909 ASSERT(type != V8ClassIndex::EVENTLISTENER); |
1909 ASSERT(type != V8ClassIndex::EVENTTARGET); | 1910 ASSERT(type != V8ClassIndex::EVENTTARGET); |
1910 | 1911 |
1911 ASSERT(MaybeDOMWrapper(object)); | 1912 ASSERT(MaybeDOMWrapper(object)); |
1912 | 1913 |
1914 switch (type) { | |
1913 #define MAKE_CASE(TYPE, NAME) case V8ClassIndex::TYPE: | 1915 #define MAKE_CASE(TYPE, NAME) case V8ClassIndex::TYPE: |
1914 switch (type) { | |
1915 NODE_WRAPPER_TYPES(MAKE_CASE) | 1916 NODE_WRAPPER_TYPES(MAKE_CASE) |
Mike Belshe
2008/09/23 00:36:13
I wonder if we shouldn't #ifndef NDEBUG these to a
Feng Qian
2008/09/23 21:46:04
Here I'd like to let it return NULL so the render
| |
1916 HTMLELEMENT_TYPES(MAKE_CASE) | 1917 HTMLELEMENT_TYPES(MAKE_CASE) |
1917 #if ENABLE(SVG) | 1918 #if ENABLE(SVG) |
1918 SVGNODE_WRAPPER_TYPES(MAKE_CASE) | 1919 SVGNODE_WRAPPER_TYPES(MAKE_CASE) |
1919 SVGELEMENT_TYPES(MAKE_CASE) | 1920 SVGELEMENT_TYPES(MAKE_CASE) |
1920 #endif | 1921 #endif |
1921 return FastDOMWrapperToNative<Node>(object); | 1922 ASSERT(false); |
1923 return NULL; | |
1922 case V8ClassIndex::XMLHTTPREQUEST: | 1924 case V8ClassIndex::XMLHTTPREQUEST: |
1923 return FastDOMWrapperToNative<XMLHttpRequest>(object); | 1925 return DOMWrapperToNative<XMLHttpRequest>(object); |
1924 case V8ClassIndex::EVENT: | 1926 case V8ClassIndex::EVENT: |
1925 return FastDOMWrapperToNative<Event>(object); | 1927 return DOMWrapperToNative<Event>(object); |
1926 case V8ClassIndex::CSSRULE: | 1928 case V8ClassIndex::CSSRULE: |
1927 return FastDOMWrapperToNative<CSSRule>(object); | 1929 return DOMWrapperToNative<CSSRule>(object); |
1928 default: | 1930 default: |
1929 break; | 1931 break; |
1930 } | 1932 } |
1931 #undef MAKE_CASE | 1933 #undef MAKE_CASE |
1932 | 1934 |
1933 return FastDOMWrapperToNative<Peerable>(object); | 1935 return DOMWrapperToNative<Peerable>(object); |
1934 } | 1936 } |
1935 | 1937 |
1936 | 1938 |
1937 v8::Handle<v8::Object> V8Proxy::LookupDOMWrapper( | 1939 v8::Handle<v8::Object> V8Proxy::LookupDOMWrapper( |
1938 V8ClassIndex::V8WrapperType type, v8::Handle<v8::Value> value) { | 1940 V8ClassIndex::V8WrapperType type, v8::Handle<v8::Value> value) { |
1939 if (value.IsEmpty()) return v8::Handle<v8::Object>(); | 1941 if (value.IsEmpty()) return v8::Handle<v8::Object>(); |
1940 | 1942 |
1941 v8::Handle<v8::FunctionTemplate> desc = V8Proxy::GetTemplate(type); | 1943 v8::Handle<v8::FunctionTemplate> desc = V8Proxy::GetTemplate(type); |
1942 while (value->IsObject()) { | 1944 while (value->IsObject()) { |
1943 v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(value); | 1945 v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(value); |
1944 if (desc->HasInstance(object)) | 1946 if (desc->HasInstance(object)) |
1945 return object; | 1947 return object; |
1946 | 1948 |
1947 value = object->GetPrototype(); | 1949 value = object->GetPrototype(); |
1948 } | 1950 } |
1949 return v8::Handle<v8::Object>(); | 1951 return v8::Handle<v8::Object>(); |
1950 } | 1952 } |
1951 | 1953 |
1952 | 1954 |
1953 void* V8Proxy::ToNativeObjectImpl(V8ClassIndex::V8WrapperType type, | |
1954 v8::Handle<v8::Value> object) { | |
1955 // Native event listener is per frame, it cannot be handled | |
1956 // by this generic function. | |
1957 ASSERT(type != V8ClassIndex::EVENTLISTENER); | |
1958 ASSERT(type != V8ClassIndex::EVENTTARGET); | |
1959 | |
1960 // It could be null, undefined, etc. | |
1961 if (!MaybeDOMWrapper(object)) | |
1962 return 0; | |
1963 | |
1964 #define MAKE_CASE(TYPE, NAME) case V8ClassIndex::TYPE: | |
1965 switch (type) { | |
1966 NODE_WRAPPER_TYPES(MAKE_CASE) | |
1967 HTMLELEMENT_TYPES(MAKE_CASE) | |
1968 #if ENABLE(SVG) | |
1969 SVGNODE_WRAPPER_TYPES(MAKE_CASE) | |
1970 SVGELEMENT_TYPES(MAKE_CASE) | |
1971 #endif | |
1972 return DOMWrapperToNative<Node>(object); | |
1973 case V8ClassIndex::XMLHTTPREQUEST: | |
1974 return DOMWrapperToNative<XMLHttpRequest>(object); | |
1975 case V8ClassIndex::EVENT: | |
1976 return DOMWrapperToNative<Event>(object); | |
1977 case V8ClassIndex::CSSRULE: | |
1978 return DOMWrapperToNative<CSSRule>(object); | |
1979 default: | |
1980 break; | |
1981 } | |
1982 #undef MAKE_CASE | |
1983 | |
1984 return DOMWrapperToNative<Peerable>(object); | |
1985 } | |
1986 | |
1987 | |
1988 NodeFilter* V8Proxy::ToNativeNodeFilter(v8::Handle<v8::Value> filter) { | 1955 NodeFilter* V8Proxy::ToNativeNodeFilter(v8::Handle<v8::Value> filter) { |
1989 // A NodeFilter is used when walking through a DOM tree or iterating tree | 1956 // A NodeFilter is used when walking through a DOM tree or iterating tree |
1990 // nodes. | 1957 // nodes. |
1991 // TODO: we may want to cache NodeFilterCondition and NodeFilter | 1958 // TODO: we may want to cache NodeFilterCondition and NodeFilter |
1992 // object, but it is minor. | 1959 // object, but it is minor. |
1993 // NodeFilter is passed to NodeIterator that has a ref counted pointer | 1960 // NodeFilter is passed to NodeIterator that has a ref counted pointer |
1994 // to NodeFilter. NodeFilter has a ref counted pointer to NodeFilterCondition. | 1961 // to NodeFilter. NodeFilter has a ref counted pointer to NodeFilterCondition. |
1995 // In NodeFilterCondition, filter object is persisted in its constructor, | 1962 // In NodeFilterCondition, filter object is persisted in its constructor, |
1996 // and disposed in its destructor. No need to use peer field in this case. | 1963 // and disposed in its destructor. No need to use peer field in this case. |
1997 if (!filter->IsFunction()) return 0; | 1964 if (!filter->IsFunction()) return 0; |
1998 | 1965 |
1999 NodeFilterCondition* cond = new V8NodeFilterCondition(filter); | 1966 NodeFilterCondition* cond = new V8NodeFilterCondition(filter); |
2000 return new NodeFilter(cond); | 1967 return new NodeFilter(cond); |
2001 } | 1968 } |
2002 | 1969 |
2003 | 1970 |
2004 v8::Local<v8::Object> V8Proxy::InstantiateV8Object( | 1971 v8::Local<v8::Object> V8Proxy::InstantiateV8Object( |
2005 V8ClassIndex::V8WrapperType type, void* imp) { | 1972 V8ClassIndex::V8WrapperType desc_type, |
2006 V8ClassIndex::V8WrapperType wrapper_type = type; | 1973 V8ClassIndex::V8WrapperType cptr_type, |
1974 void* imp) { | |
2007 // Make a special case for document.all | 1975 // Make a special case for document.all |
2008 if (type == V8ClassIndex::HTMLCOLLECTION && | 1976 if (desc_type == V8ClassIndex::HTMLCOLLECTION && |
2009 static_cast<HTMLCollection*>(imp)->type() == HTMLCollection::DocAll) { | 1977 static_cast<HTMLCollection*>(imp)->type() == HTMLCollection::DocAll) { |
2010 wrapper_type = V8ClassIndex::UNDETECTABLEHTMLCOLLECTION; | 1978 desc_type = V8ClassIndex::UNDETECTABLEHTMLCOLLECTION; |
2011 } | 1979 } |
2012 | 1980 |
2013 // Special case for HTMLInputElements that support selection. | 1981 // Special case for HTMLInputElements that support selection. |
2014 if (type == V8ClassIndex::HTMLINPUTELEMENT) { | 1982 if (desc_type == V8ClassIndex::HTMLINPUTELEMENT) { |
2015 HTMLInputElement* element = static_cast<HTMLInputElement*>(imp); | 1983 HTMLInputElement* element = static_cast<HTMLInputElement*>(imp); |
2016 if (element->canHaveSelection()) { | 1984 if (element->canHaveSelection()) { |
2017 wrapper_type = V8ClassIndex::HTMLSELECTIONINPUTELEMENT; | 1985 desc_type = V8ClassIndex::HTMLSELECTIONINPUTELEMENT; |
2018 } | 1986 } |
2019 } | 1987 } |
2020 | 1988 |
2021 v8::Persistent<v8::FunctionTemplate> desc = GetTemplate(wrapper_type); | 1989 v8::Persistent<v8::FunctionTemplate> desc = GetTemplate(desc_type); |
2022 v8::Local<v8::Function> function = desc->GetFunction(); | 1990 v8::Local<v8::Function> function = desc->GetFunction(); |
2023 v8::Local<v8::Object> instance = SafeAllocation::NewInstance(function); | 1991 v8::Local<v8::Object> instance = SafeAllocation::NewInstance(function); |
2024 if (!instance.IsEmpty()) { | 1992 if (!instance.IsEmpty()) { |
2025 // Avoid setting the DOM wrapper for failed allocations. | 1993 // Avoid setting the DOM wrapper for failed allocations. |
2026 SetDOMWrapper(instance, V8ClassIndex::ToInt(type), imp); | 1994 SetDOMWrapper(instance, V8ClassIndex::ToInt(cptr_type), imp); |
2027 } | 1995 } |
2028 return instance; | 1996 return instance; |
2029 } | 1997 } |
2030 | 1998 |
2031 v8::Handle<v8::Value> V8Proxy::CheckNewLegal(const v8::Arguments& args) { | 1999 v8::Handle<v8::Value> V8Proxy::CheckNewLegal(const v8::Arguments& args) { |
2032 if (!AllowAllocation::m_current) { | 2000 if (!AllowAllocation::m_current) { |
2033 return ThrowError(TYPE_ERROR, "Illegal constructor"); | 2001 return ThrowError(TYPE_ERROR, "Illegal constructor"); |
2034 } else { | 2002 } else { |
2035 return args.This(); | 2003 return args.This(); |
2036 } | 2004 } |
2037 } | 2005 } |
2038 | 2006 |
2039 | 2007 |
2040 v8::Handle<v8::Value> V8Proxy::WrapCPointer(void* cptr) { | 2008 v8::Handle<v8::Value> V8Proxy::WrapCPointer(void* cptr) { |
2041 // Represent void* as int | 2009 // Represent void* as int |
2042 int addr = reinterpret_cast<int>(cptr); | 2010 int addr = reinterpret_cast<int>(cptr); |
2043 if ((addr & 0x01) == 0) { | 2011 ASSERT((addr & 0x01) == 0); // the address must be aligned. |
2044 return v8::Number::New(addr >> 1); | 2012 return v8::Integer::New(addr >> 1); |
2045 } else { | |
2046 return v8::External::New(cptr); | |
2047 } | |
2048 } | 2013 } |
2049 | 2014 |
2050 | 2015 |
2051 void* V8Proxy::ExtractCPointerImpl(v8::Handle<v8::Value> obj) { | 2016 void* V8Proxy::ExtractCPointerImpl(v8::Handle<v8::Value> obj) { |
2052 if (obj->IsNumber()) { | 2017 ASSERT(obj->IsNumber()); |
2053 int addr = obj->Int32Value(); | 2018 int addr = obj->Int32Value(); |
2054 return reinterpret_cast<void*>(addr << 1); | 2019 return reinterpret_cast<void*>(addr << 1); |
2055 } else if (obj->IsExternal()) { | |
2056 return v8::Handle<v8::External>::Cast(obj)->Value(); | |
2057 } | |
2058 ASSERT(false); | |
2059 return 0; | |
2060 } | 2020 } |
2061 | 2021 |
2062 | 2022 |
2063 bool V8Proxy::SetDOMWrapper(v8::Handle<v8::Object> obj, int type, void* cptr) { | 2023 void V8Proxy::SetDOMWrapper(v8::Handle<v8::Object> obj, int type, void* cptr) { |
2064 ASSERT(obj->InternalFieldCount() >= 2); | 2024 ASSERT(obj->InternalFieldCount() >= 2); |
2065 obj->SetInternalField(V8Custom::kDOMWrapperObjectIndex, WrapCPointer(cptr)); | 2025 obj->SetInternalField(V8Custom::kDOMWrapperObjectIndex, WrapCPointer(cptr)); |
2066 obj->SetInternalField(V8Custom::kDOMWrapperTypeIndex, v8::Integer::New(type)); | 2026 obj->SetInternalField(V8Custom::kDOMWrapperTypeIndex, v8::Integer::New(type)); |
2067 return true; | |
2068 } | 2027 } |
2069 | 2028 |
2070 | 2029 |
2030 #ifndef NDEBUG | |
2071 bool V8Proxy::MaybeDOMWrapper(v8::Handle<v8::Value> value) { | 2031 bool V8Proxy::MaybeDOMWrapper(v8::Handle<v8::Value> value) { |
2072 if (value.IsEmpty() || !value->IsObject()) return false; | 2032 if (value.IsEmpty() || !value->IsObject()) return false; |
2073 | 2033 |
2074 v8::Handle<v8::Object> obj = v8::Handle<v8::Object>::Cast(value); | 2034 v8::Handle<v8::Object> obj = v8::Handle<v8::Object>::Cast(value); |
2075 if (obj->InternalFieldCount() < V8Custom::kDefaultWrapperInternalFieldCount) | 2035 if (obj->InternalFieldCount() == 0) return false; |
2076 return false; | 2036 |
2037 ASSERT(obj->InternalFieldCount() >= | |
2038 V8Custom::kDefaultWrapperInternalFieldCount); | |
2039 | |
2040 v8::Handle<v8::Value> type = | |
2041 obj->GetInternalField(V8Custom::kDOMWrapperTypeIndex); | |
2042 ASSERT(type->IsInt32()); | |
2043 ASSERT(V8ClassIndex::INVALID_CLASS_INDEX < type->Int32Value() && | |
2044 type->Int32Value() < V8ClassIndex::CLASSINDEX_END); | |
2077 | 2045 |
2078 v8::Handle<v8::Value> wrapper = | 2046 v8::Handle<v8::Value> wrapper = |
2079 obj->GetInternalField(V8Custom::kDOMWrapperObjectIndex); | 2047 obj->GetInternalField(V8Custom::kDOMWrapperObjectIndex); |
2080 if (!wrapper->IsNumber() && !wrapper->IsExternal()) return false; | 2048 ASSERT(wrapper->IsNumber() || wrapper->IsExternal()); |
2049 | |
2050 return true; | |
2051 } | |
2052 #endif | |
2053 | |
2054 | |
2055 bool V8Proxy::IsDOMEventWrapper(v8::Handle<v8::Value> value) { | |
2056 if (value.IsEmpty() || !value->IsObject()) return false; | |
2057 | |
2058 v8::Handle<v8::Object> obj = v8::Handle<v8::Object>::Cast(value); | |
2059 if (obj->InternalFieldCount() == 0) return false; | |
2060 | |
2061 ASSERT(obj->InternalFieldCount() >= | |
2062 V8Custom::kDefaultWrapperInternalFieldCount); | |
2063 | |
2064 v8::Handle<v8::Value> wrapper = | |
2065 obj->GetInternalField(V8Custom::kDOMWrapperObjectIndex); | |
2066 ASSERT(wrapper->IsNumber() || wrapper->IsExternal()); | |
2081 | 2067 |
2082 v8::Handle<v8::Value> type = | 2068 v8::Handle<v8::Value> type = |
2083 obj->GetInternalField(V8Custom::kDOMWrapperTypeIndex); | 2069 obj->GetInternalField(V8Custom::kDOMWrapperTypeIndex); |
2084 if (!type->IsNumber()) return false; | 2070 ASSERT(type->IsInt32()); |
2071 ASSERT(V8ClassIndex::INVALID_CLASS_INDEX < type->Int32Value() && | |
2072 type->Int32Value() < V8ClassIndex::CLASSINDEX_END); | |
2085 | 2073 |
2086 return true; | 2074 // All kinds of events use EVENT as dom type in JS wrappers. |
2075 // See EventToV8Object | |
2076 return V8ClassIndex::FromInt(type->Int32Value()) == V8ClassIndex::EVENT; | |
2087 } | 2077 } |
2088 | 2078 |
2089 | 2079 |
2090 #define FOR_EACH_TAG(macro) \ | 2080 #define FOR_EACH_TAG(macro) \ |
2091 macro(a, ANCHOR) \ | 2081 macro(a, ANCHOR) \ |
2092 macro(applet, APPLET) \ | 2082 macro(applet, APPLET) \ |
2093 macro(area, AREA) \ | 2083 macro(area, AREA) \ |
2094 macro(base, BASE) \ | 2084 macro(base, BASE) \ |
2095 macro(basefont, BASEFONT) \ | 2085 macro(basefont, BASEFONT) \ |
2096 macro(blockquote, BLOCKQUOTE) \ | 2086 macro(blockquote, BLOCKQUOTE) \ |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2322 else if (event->isUIEvent()) | 2312 else if (event->isUIEvent()) |
2323 type = V8ClassIndex::UIEVENT; | 2313 type = V8ClassIndex::UIEVENT; |
2324 else if (event->isMutationEvent()) | 2314 else if (event->isMutationEvent()) |
2325 type = V8ClassIndex::MUTATIONEVENT; | 2315 type = V8ClassIndex::MUTATIONEVENT; |
2326 else if (event->isOverflowEvent()) | 2316 else if (event->isOverflowEvent()) |
2327 type = V8ClassIndex::OVERFLOWEVENT; | 2317 type = V8ClassIndex::OVERFLOWEVENT; |
2328 else if (event->isProgressEvent()) | 2318 else if (event->isProgressEvent()) |
2329 type = V8ClassIndex::PROGRESSEVENT; | 2319 type = V8ClassIndex::PROGRESSEVENT; |
2330 | 2320 |
2331 // Set the peer object for future access. | 2321 // Set the peer object for future access. |
2332 v8::Handle<v8::Object> result = InstantiateV8Object(type, event); | 2322 v8::Handle<v8::Object> result = |
2323 InstantiateV8Object(type, V8ClassIndex::EVENT, event); | |
2333 if (result.IsEmpty()) { | 2324 if (result.IsEmpty()) { |
2334 // Instantiation failed. Avoid updating the DOM object map and | 2325 // Instantiation failed. Avoid updating the DOM object map and |
2335 // return null which is already handled by callers of this function | 2326 // return null which is already handled by callers of this function |
2336 // in case the event is NULL. | 2327 // in case the event is NULL. |
2337 return v8::Null(); | 2328 return v8::Null(); |
2338 } | 2329 } |
2339 | 2330 |
2340 dom_object_map().set(event, v8::Persistent<v8::Object>::New(result)); | 2331 dom_object_map().set(event, v8::Persistent<v8::Object>::New(result)); |
2341 | 2332 |
2342 return result; | 2333 return result; |
2343 } | 2334 } |
2344 | 2335 |
2345 | 2336 |
2346 v8::Handle<v8::Object> V8Proxy::NodeToV8Object(Node* node) { | 2337 // Caller checks node is not null. |
2347 if (!node) return v8::Handle<v8::Object>(); | 2338 v8::Handle<v8::Value> V8Proxy::NodeToV8Object(Node* node) { |
2339 if (!node) return v8::Null(); | |
2348 | 2340 |
2349 v8::Handle<v8::Object> peer = dom_node_map().get(node); | 2341 v8::Handle<v8::Object> peer = dom_node_map().get(node); |
2350 if (!peer.IsEmpty()) { | 2342 if (!peer.IsEmpty()) { |
2351 return peer; | 2343 return peer; |
2352 } | 2344 } |
2353 | 2345 |
2354 bool is_document = false; // document type node has special handling | 2346 bool is_document = false; // document type node has special handling |
2355 V8ClassIndex::V8WrapperType type; | 2347 V8ClassIndex::V8WrapperType type; |
2356 | 2348 |
2357 switch (node->nodeType()) { | 2349 switch (node->nodeType()) { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2409 break; | 2401 break; |
2410 case Node::ENTITY_REFERENCE_NODE: | 2402 case Node::ENTITY_REFERENCE_NODE: |
2411 type = V8ClassIndex::ENTITYREFERENCE; | 2403 type = V8ClassIndex::ENTITYREFERENCE; |
2412 break; | 2404 break; |
2413 default: | 2405 default: |
2414 type = V8ClassIndex::NODE; | 2406 type = V8ClassIndex::NODE; |
2415 } | 2407 } |
2416 | 2408 |
2417 // Set the peer object for future access. | 2409 // Set the peer object for future access. |
2418 // InstantiateV8Object automatically casts node to Peerable*. | 2410 // InstantiateV8Object automatically casts node to Peerable*. |
2419 v8::Local<v8::Object> result = InstantiateV8Object(type, node); | 2411 v8::Local<v8::Object> result = |
2412 InstantiateV8Object(type, V8ClassIndex::NODE, node); | |
2420 if (result.IsEmpty()) { | 2413 if (result.IsEmpty()) { |
2421 // If instantiation failed it's important not to add the result | 2414 // If instantiation failed it's important not to add the result |
2422 // to the DOM node map. Instead we return an empty handle, which | 2415 // to the DOM node map. Instead we return an empty handle, which |
2423 // should already be handled by callers of this function in case | 2416 // should already be handled by callers of this function in case |
2424 // the node is NULL. | 2417 // the node is NULL. |
2425 return result; | 2418 return result; |
2426 } | 2419 } |
2427 | 2420 |
2428 dom_node_map().set(node, v8::Persistent<v8::Object>::New(result)); | 2421 dom_node_map().set(node, v8::Persistent<v8::Object>::New(result)); |
2429 | 2422 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2500 // TODO(fqian): can a user take a lazy event listener and set to other places? | 2493 // TODO(fqian): can a user take a lazy event listener and set to other places? |
2501 V8AbstractEventListener* v8listener = | 2494 V8AbstractEventListener* v8listener = |
2502 static_cast<V8AbstractEventListener*>(listener); | 2495 static_cast<V8AbstractEventListener*>(listener); |
2503 return v8listener->GetListenerObject(); | 2496 return v8listener->GetListenerObject(); |
2504 } | 2497 } |
2505 | 2498 |
2506 | 2499 |
2507 v8::Handle<v8::Value> V8Proxy::DOMImplementationToV8Object( | 2500 v8::Handle<v8::Value> V8Proxy::DOMImplementationToV8Object( |
2508 DOMImplementation* impl) { | 2501 DOMImplementation* impl) { |
2509 v8::Handle<v8::Object> result = | 2502 v8::Handle<v8::Object> result = |
2510 InstantiateV8Object(V8ClassIndex::DOMIMPLEMENTATION, impl); | 2503 InstantiateV8Object(V8ClassIndex::DOMIMPLEMENTATION, |
2504 V8ClassIndex::DOMIMPLEMENTATION, | |
2505 impl); | |
2511 if (result.IsEmpty()) { | 2506 if (result.IsEmpty()) { |
2512 // If the instantiation failed, we ignore it and return null instead | 2507 // If the instantiation failed, we ignore it and return null instead |
2513 // of returning an empty handle. | 2508 // of returning an empty handle. |
2514 return v8::Null(); | 2509 return v8::Null(); |
2515 } | 2510 } |
2516 return result; | 2511 return result; |
2517 } | 2512 } |
2518 | 2513 |
2519 | 2514 |
2520 v8::Handle<v8::Object> V8Proxy::StyleSheetToV8Object(StyleSheet* sheet) { | 2515 v8::Handle<v8::Value> V8Proxy::StyleSheetToV8Object(StyleSheet* sheet) { |
2521 if (!sheet) return v8::Handle<v8::Object>(); | 2516 if (!sheet) return v8::Null(); |
2522 | 2517 |
2523 v8::Handle<v8::Object> peer = dom_object_map().get(sheet); | 2518 v8::Handle<v8::Object> peer = dom_object_map().get(sheet); |
2524 if (!peer.IsEmpty()) { | 2519 if (!peer.IsEmpty()) { |
2525 return peer; | 2520 return peer; |
2526 } | 2521 } |
2527 | 2522 |
2528 V8ClassIndex::V8WrapperType type = V8ClassIndex::STYLESHEET; | 2523 V8ClassIndex::V8WrapperType type = V8ClassIndex::STYLESHEET; |
2529 if (sheet->isCSSStyleSheet()) type = V8ClassIndex::CSSSTYLESHEET; | 2524 if (sheet->isCSSStyleSheet()) type = V8ClassIndex::CSSSTYLESHEET; |
2530 | 2525 |
2531 v8::Handle<v8::Object> result = InstantiateV8Object(type, sheet); | 2526 v8::Handle<v8::Object> result = |
2527 InstantiateV8Object(type, V8ClassIndex::STYLESHEET, sheet); | |
2532 if (!result.IsEmpty()) { | 2528 if (!result.IsEmpty()) { |
2533 // Only update the DOM object map if the result is non-empty. | 2529 // Only update the DOM object map if the result is non-empty. |
2534 dom_object_map().set(sheet, v8::Persistent<v8::Object>::New(result)); | 2530 dom_object_map().set(sheet, v8::Persistent<v8::Object>::New(result)); |
2535 } | 2531 } |
2536 | 2532 |
2537 // Add a hidden reference from stylesheet object to its owner node. | 2533 // Add a hidden reference from stylesheet object to its owner node. |
2538 Node* owner_node = sheet->ownerNode(); | 2534 Node* owner_node = sheet->ownerNode(); |
2539 if (owner_node) { | 2535 if (owner_node) { |
2540 v8::Handle<v8::Object> owner = NodeToV8Object(owner_node); | 2536 v8::Handle<v8::Object> owner = |
2537 v8::Handle<v8::Object>::Cast(NodeToV8Object(owner_node)); | |
2541 result->SetInternalField(V8Custom::kStyleSheetOwnerNodeIndex, owner); | 2538 result->SetInternalField(V8Custom::kStyleSheetOwnerNodeIndex, owner); |
2542 } | 2539 } |
2543 | 2540 |
2544 return result; | 2541 return result; |
2545 } | 2542 } |
2546 | 2543 |
2547 | 2544 |
2548 v8::Handle<v8::Object> V8Proxy::CSSValueToV8Object(CSSValue* value) { | 2545 v8::Handle<v8::Value> V8Proxy::CSSValueToV8Object(CSSValue* value) { |
2549 if (!value) return v8::Handle<v8::Object>(); | 2546 if (!value) return v8::Null(); |
2550 | 2547 |
2551 v8::Handle<v8::Object> peer = dom_object_map().get(value); | 2548 v8::Handle<v8::Object> peer = dom_object_map().get(value); |
2552 if (!peer.IsEmpty()) { | 2549 if (!peer.IsEmpty()) { |
2553 return peer; | 2550 return peer; |
2554 } | 2551 } |
2555 | 2552 |
2556 V8ClassIndex::V8WrapperType type; | 2553 V8ClassIndex::V8WrapperType type; |
2557 | 2554 |
2558 if (value->isValueList()) | 2555 if (value->isValueList()) |
2559 type = V8ClassIndex::CSSVALUELIST; | 2556 type = V8ClassIndex::CSSVALUELIST; |
2560 else if (value->isPrimitiveValue()) | 2557 else if (value->isPrimitiveValue()) |
2561 type = V8ClassIndex::CSSPRIMITIVEVALUE; | 2558 type = V8ClassIndex::CSSPRIMITIVEVALUE; |
2562 #if ENABLE(SVG) | 2559 #if ENABLE(SVG) |
2563 else if (value->isSVGPaint()) | 2560 else if (value->isSVGPaint()) |
2564 type = V8ClassIndex::SVGPAINT; | 2561 type = V8ClassIndex::SVGPAINT; |
2565 else if (value->isSVGColor()) | 2562 else if (value->isSVGColor()) |
2566 type = V8ClassIndex::SVGCOLOR; | 2563 type = V8ClassIndex::SVGCOLOR; |
2567 #endif | 2564 #endif |
2568 else | 2565 else |
2569 type = V8ClassIndex::CSSVALUE; | 2566 type = V8ClassIndex::CSSVALUE; |
2570 | 2567 |
2571 v8::Handle<v8::Object> result = InstantiateV8Object(type, value); | 2568 v8::Handle<v8::Object> result = |
2569 InstantiateV8Object(type, V8ClassIndex::CSSVALUE, value); | |
2572 if (!result.IsEmpty()) { | 2570 if (!result.IsEmpty()) { |
2573 // Only update the DOM object map if the result is non-empty. | 2571 // Only update the DOM object map if the result is non-empty. |
2574 dom_object_map().set(value, v8::Persistent<v8::Object>::New(result)); | 2572 dom_object_map().set(value, v8::Persistent<v8::Object>::New(result)); |
2575 } | 2573 } |
2576 return result; | 2574 return result; |
2577 } | 2575 } |
2578 | 2576 |
2579 | 2577 |
2580 v8::Handle<v8::Object> V8Proxy::CSSRuleToV8Object(CSSRule* rule) { | 2578 v8::Handle<v8::Value> V8Proxy::CSSRuleToV8Object(CSSRule* rule) { |
2581 if (!rule) return v8::Handle<v8::Object>(); | 2579 if (!rule) return v8::Null(); |
2582 | 2580 |
2583 v8::Handle<v8::Object> peer = dom_object_map().get(rule); | 2581 v8::Handle<v8::Object> peer = dom_object_map().get(rule); |
2584 if (!peer.IsEmpty()) { | 2582 if (!peer.IsEmpty()) { |
2585 return peer; | 2583 return peer; |
2586 } | 2584 } |
2587 | 2585 |
2588 V8ClassIndex::V8WrapperType type; | 2586 V8ClassIndex::V8WrapperType type; |
2589 | 2587 |
2590 switch (rule->type()) { | 2588 switch (rule->type()) { |
2591 case CSSRule::STYLE_RULE: | 2589 case CSSRule::STYLE_RULE: |
(...skipping 12 matching lines...) Expand all Loading... | |
2604 type = V8ClassIndex::CSSFONTFACERULE; | 2602 type = V8ClassIndex::CSSFONTFACERULE; |
2605 break; | 2603 break; |
2606 case CSSRule::PAGE_RULE: | 2604 case CSSRule::PAGE_RULE: |
2607 type = V8ClassIndex::CSSPAGERULE; | 2605 type = V8ClassIndex::CSSPAGERULE; |
2608 break; | 2606 break; |
2609 default: // CSSRule::UNKNOWN_RULE | 2607 default: // CSSRule::UNKNOWN_RULE |
2610 type = V8ClassIndex::CSSRULE; | 2608 type = V8ClassIndex::CSSRULE; |
2611 } | 2609 } |
2612 | 2610 |
2613 // Set the peer object for future access. | 2611 // Set the peer object for future access. |
2614 v8::Handle<v8::Object> result = InstantiateV8Object(type, rule); | 2612 v8::Handle<v8::Object> result = |
2613 InstantiateV8Object(type, V8ClassIndex::CSSRULE, rule); | |
2615 if (!result.IsEmpty()) { | 2614 if (!result.IsEmpty()) { |
2616 // Only update the DOM object map if the result is non-empty. | 2615 // Only update the DOM object map if the result is non-empty. |
2617 dom_object_map().set(rule, v8::Persistent<v8::Object>::New(result)); | 2616 dom_object_map().set(rule, v8::Persistent<v8::Object>::New(result)); |
2618 } | 2617 } |
2619 return result; | 2618 return result; |
2620 } | 2619 } |
2621 | 2620 |
2622 v8::Handle<v8::Object> V8Proxy::WindowToV8Object(DOMWindow* window) { | 2621 v8::Handle<v8::Value> V8Proxy::WindowToV8Object(DOMWindow* window) { |
2622 if (!window) return v8::Null(); | |
2623 | |
2623 // Initializes environment of a frame, and return the global object | 2624 // Initializes environment of a frame, and return the global object |
2624 // of the frame. | 2625 // of the frame. |
2625 Frame* frame = window->frame(); | 2626 Frame* frame = window->frame(); |
2626 if (!frame) return v8::Handle<v8::Object>(); | 2627 if (!frame) return v8::Handle<v8::Object>(); |
2627 | 2628 |
2628 v8::Handle<v8::Context> context = GetContext(frame); | 2629 v8::Handle<v8::Context> context = GetContext(frame); |
2629 if (context.IsEmpty()) return v8::Handle<v8::Object>(); | 2630 if (context.IsEmpty()) return v8::Handle<v8::Object>(); |
2630 | 2631 |
2631 v8::Handle<v8::Object> global = context->Global(); | 2632 v8::Handle<v8::Object> global = context->Global(); |
2632 ASSERT(!global.IsEmpty()); | 2633 ASSERT(!global.IsEmpty()); |
(...skipping 18 matching lines...) Expand all Loading... | |
2651 global->Set(v8::String::New(name), instance); | 2652 global->Set(v8::String::New(name), instance); |
2652 } | 2653 } |
2653 | 2654 |
2654 | 2655 |
2655 void V8Proxy::ProcessConsoleMessages() { | 2656 void V8Proxy::ProcessConsoleMessages() { |
2656 ConsoleMessageManager::ProcessDelayedMessages(); | 2657 ConsoleMessageManager::ProcessDelayedMessages(); |
2657 } | 2658 } |
2658 | 2659 |
2659 | 2660 |
2660 } // namespace WebCore | 2661 } // namespace WebCore |
OLD | NEW |