Chromium Code Reviews| 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 |