| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2008, 2009 Google Inc. All rights reserved. | 2 * Copyright (C) 2008, 2009 Google Inc. 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 1201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1212 if (value.IsEmpty()) | 1212 if (value.IsEmpty()) |
| 1213 return v8::Local<v8::Function>(); | 1213 return v8::Local<v8::Function>(); |
| 1214 // Hotmail fix, see comments above. | 1214 // Hotmail fix, see comments above. |
| 1215 value->Set(v8::String::New("__proto__"), m_objectPrototype); | 1215 value->Set(v8::String::New("__proto__"), m_objectPrototype); |
| 1216 return value; | 1216 return value; |
| 1217 } | 1217 } |
| 1218 | 1218 |
| 1219 v8::Local<v8::Object> V8Proxy::createWrapperFromCache(V8ClassIndex::V8WrapperTyp
e type) | 1219 v8::Local<v8::Object> V8Proxy::createWrapperFromCache(V8ClassIndex::V8WrapperTyp
e type) |
| 1220 { | 1220 { |
| 1221 int classIndex = V8ClassIndex::ToInt(type); | 1221 int classIndex = V8ClassIndex::ToInt(type); |
| 1222 v8::Local<v8::Value> cachedObject = m_wrapperBoilerplates->Get(v8::Integer::
New(classIndex)); | 1222 v8::Local<v8::Object> clone(m_wrapperBoilerplates->CloneElementAt(classIndex
)); |
| 1223 if (cachedObject->IsObject()) { | 1223 if (!clone.IsEmpty()) |
| 1224 v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(cachedObject)
; | 1224 return clone; |
| 1225 return object->Clone(); | |
| 1226 } | |
| 1227 | 1225 |
| 1228 // Not in cache. | 1226 // Not in cache. |
| 1229 initContextIfNeeded(); | 1227 initContextIfNeeded(); |
| 1230 v8::Context::Scope scope(m_context); | 1228 v8::Context::Scope scope(m_context); |
| 1231 v8::Local<v8::Function> function = getConstructor(type); | 1229 v8::Local<v8::Function> function = getConstructor(type); |
| 1232 v8::Local<v8::Object> instance = SafeAllocation::newInstance(function); | 1230 v8::Local<v8::Object> instance = SafeAllocation::newInstance(function); |
| 1233 if (!instance.IsEmpty()) { | 1231 if (!instance.IsEmpty()) { |
| 1234 m_wrapperBoilerplates->Set(v8::Integer::New(classIndex), instance); | 1232 m_wrapperBoilerplates->Set(v8::Integer::New(classIndex), instance); |
| 1235 return instance->Clone(); | 1233 return instance->Clone(); |
| 1236 } | 1234 } |
| (...skipping 1163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2400 // to NodeFilter. NodeFilter has a ref counted pointer to NodeFilterConditio
n. | 2398 // to NodeFilter. NodeFilter has a ref counted pointer to NodeFilterConditio
n. |
| 2401 // In NodeFilterCondition, filter object is persisted in its constructor, | 2399 // In NodeFilterCondition, filter object is persisted in its constructor, |
| 2402 // and disposed in its destructor. | 2400 // and disposed in its destructor. |
| 2403 if (!filter->IsFunction()) | 2401 if (!filter->IsFunction()) |
| 2404 return 0; | 2402 return 0; |
| 2405 | 2403 |
| 2406 NodeFilterCondition* condition = new V8NodeFilterCondition(filter); | 2404 NodeFilterCondition* condition = new V8NodeFilterCondition(filter); |
| 2407 return NodeFilter::create(condition); | 2405 return NodeFilter::create(condition); |
| 2408 } | 2406 } |
| 2409 | 2407 |
| 2410 v8::Local<v8::Object> V8Proxy::instantiateV8Object(V8ClassIndex::V8WrapperType d
escriptorType, V8ClassIndex::V8WrapperType cptrType, void* impl) | 2408 v8::Local<v8::Object> V8Proxy::instantiateV8Object(V8Proxy* proxy, V8ClassIndex:
:V8WrapperType descriptorType, V8ClassIndex::V8WrapperType cptrType, void* impl) |
| 2411 { | 2409 { |
| 2412 // Make a special case for document.all | 2410 // Make a special case for document.all |
| 2413 if (descriptorType == V8ClassIndex::HTMLCOLLECTION && static_cast<HTMLCollec
tion*>(impl)->type() == DocAll) | 2411 if (descriptorType == V8ClassIndex::HTMLCOLLECTION && static_cast<HTMLCollec
tion*>(impl)->type() == DocAll) |
| 2414 descriptorType = V8ClassIndex::UNDETECTABLEHTMLCOLLECTION; | 2412 descriptorType = V8ClassIndex::UNDETECTABLEHTMLCOLLECTION; |
| 2415 | 2413 |
| 2416 V8Proxy* proxy = V8Proxy::retrieve(); | 2414 if (!proxy) |
| 2415 V8Proxy* proxy = V8Proxy::retrieve(); |
| 2417 v8::Local<v8::Object> instance; | 2416 v8::Local<v8::Object> instance; |
| 2418 if (proxy) | 2417 if (proxy) |
| 2419 instance = proxy->createWrapperFromCache(descriptorType); | 2418 instance = proxy->createWrapperFromCache(descriptorType); |
| 2420 else { | 2419 else { |
| 2421 v8::Local<v8::Function> function = getTemplate(descriptorType)->GetFunct
ion(); | 2420 v8::Local<v8::Function> function = getTemplate(descriptorType)->GetFunct
ion(); |
| 2422 instance = SafeAllocation::newInstance(function); | 2421 instance = SafeAllocation::newInstance(function); |
| 2423 } | 2422 } |
| 2424 if (!instance.IsEmpty()) { | 2423 if (!instance.IsEmpty()) { |
| 2425 // Avoid setting the DOM wrapper for failed allocations. | 2424 // Avoid setting the DOM wrapper for failed allocations. |
| 2426 setDOMWrapper(instance, V8ClassIndex::ToInt(cptrType), impl); | 2425 setDOMWrapper(instance, V8ClassIndex::ToInt(cptrType), impl); |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2777 // in case the event is NULL. | 2776 // in case the event is NULL. |
| 2778 return v8::Null(); | 2777 return v8::Null(); |
| 2779 } | 2778 } |
| 2780 | 2779 |
| 2781 event->ref(); // fast ref | 2780 event->ref(); // fast ref |
| 2782 setJSWrapperForDOMObject(event, v8::Persistent<v8::Object>::New(result)); | 2781 setJSWrapperForDOMObject(event, v8::Persistent<v8::Object>::New(result)); |
| 2783 | 2782 |
| 2784 return result; | 2783 return result; |
| 2785 } | 2784 } |
| 2786 | 2785 |
| 2786 |
| 2787 static const V8ClassIndex::V8WrapperType mapping[] = { |
| 2788 V8ClassIndex::INVALID_CLASS_INDEX, // NONE |
| 2789 V8ClassIndex::INVALID_CLASS_INDEX, // ELEMENT_NODE needs special treatment |
| 2790 V8ClassIndex::ATTR, // ATTRIBUTE_NODE |
| 2791 V8ClassIndex::TEXT, // TEXT_NODE |
| 2792 V8ClassIndex::CDATASECTION, // CDATA_SECTION_NODE |
| 2793 V8ClassIndex::ENTITYREFERENCE, // ENTITY_REFERENCE_NODE |
| 2794 V8ClassIndex::ENTITY, // ENTITY_NODE |
| 2795 V8ClassIndex::PROCESSINGINSTRUCTION, // PROCESSING_INSTRUCTION_NODE |
| 2796 V8ClassIndex::COMMENT, // COMMENT_NODE |
| 2797 V8ClassIndex::INVALID_CLASS_INDEX, // DOCUMENT_NODE needs special treatment |
| 2798 V8ClassIndex::DOCUMENTTYPE, // DOCUMENT_TYPE_NODE |
| 2799 V8ClassIndex::DOCUMENTFRAGMENT, // DOCUMENT_FRAGMENT_NODE |
| 2800 V8ClassIndex::NOTATION, // NOTATION_NODE |
| 2801 V8ClassIndex::NODE, // XPATH_NAMESPACE_NODE |
| 2802 }; |
| 2803 |
| 2787 // Caller checks node is not null. | 2804 // Caller checks node is not null. |
| 2788 v8::Handle<v8::Value> V8Proxy::convertNodeToV8Object(Node* node) | 2805 v8::Handle<v8::Value> V8Proxy::convertNodeToV8Object(Node* node) |
| 2789 { | 2806 { |
| 2790 if (!node) | 2807 if (!node) |
| 2791 return v8::Null(); | 2808 return v8::Null(); |
| 2792 | 2809 |
| 2793 // Find the context to which the node belongs and create the wrapper | 2810 // Find a proxy for this node. |
| 2794 // in that context. If the node is not in a document, the current | |
| 2795 // context is used. | |
| 2796 // | 2811 // |
| 2797 // Getting the context might initialize the context which can instantiate | 2812 // Note that if proxy is found, we might initialize the context which can |
| 2798 // a document wrapper. Therefore, we get the context before checking if | 2813 // instantiate a document wrapper. Therefore, we get the proxy before |
| 2799 // the node already has a wrapper. | 2814 // checking if the node already has a wrapper. |
| 2800 v8::Local<v8::Context> v8Context; | 2815 V8Proxy* proxy = 0; |
| 2801 Document* document = node->document(); | 2816 Document* document = node->document(); |
| 2802 if (document) | 2817 if (document) { |
| 2803 v8Context = V8Proxy::context(document->frame()); | 2818 Frame* frame = document->frame(); |
| 2819 proxy = retrieve(frame); |
| 2820 if (proxy) |
| 2821 proxy->initContextIfNeeded(); |
| 2822 } |
| 2804 | 2823 |
| 2805 v8::Handle<v8::Object> wrapper = getDOMNodeMap().get(node); | 2824 DOMWrapperMap<Node>& domNodeMap = proxy ? proxy->m_domNodeMap : getDOMNodeMa
p(); |
| 2825 v8::Handle<v8::Object> wrapper = domNodeMap.get(node); |
| 2806 if (!wrapper.IsEmpty()) | 2826 if (!wrapper.IsEmpty()) |
| 2807 return wrapper; | 2827 return wrapper; |
| 2808 | 2828 |
| 2809 bool isDocument = false; // document type node has special handling | 2829 bool isDocument = false; // document type node has special handling |
| 2810 V8ClassIndex::V8WrapperType type; | 2830 V8ClassIndex::V8WrapperType type; |
| 2811 | 2831 |
| 2812 switch (node->nodeType()) { | 2832 Node::NodeType nodeType = node->nodeType(); |
| 2813 case Node::ELEMENT_NODE: | 2833 if (nodeType == Node::ELEMENT_NODE) { |
| 2814 if (node->isHTMLElement()) | 2834 if (node->isHTMLElement()) |
| 2815 type = htmlElementType(static_cast<HTMLElement*>(node)); | 2835 type = htmlElementType(static_cast<HTMLElement*>(node)); |
| 2816 #if ENABLE(SVG) | 2836 #if ENABLE(SVG) |
| 2817 else if (node->isSVGElement()) | 2837 else if (node->isSVGElement()) |
| 2818 type = svgElementType(static_cast<SVGElement*>(node)); | 2838 type = svgElementType(static_cast<SVGElement*>(node)); |
| 2819 #endif | 2839 #endif |
| 2820 else | 2840 else |
| 2821 type = V8ClassIndex::ELEMENT; | 2841 type = V8ClassIndex::ELEMENT; |
| 2822 break; | 2842 } else if (nodeType == Node::DOCUMENT_NODE) { |
| 2823 case Node::ATTRIBUTE_NODE: | 2843 isDocument = true; |
| 2824 type = V8ClassIndex::ATTR; | 2844 Document* document = static_cast<Document*>(node); |
| 2825 break; | 2845 if (document->isHTMLDocument()) |
| 2826 case Node::TEXT_NODE: | 2846 type = V8ClassIndex::HTMLDOCUMENT; |
| 2827 type = V8ClassIndex::TEXT; | |
| 2828 break; | |
| 2829 case Node::CDATA_SECTION_NODE: | |
| 2830 type = V8ClassIndex::CDATASECTION; | |
| 2831 break; | |
| 2832 case Node::ENTITY_NODE: | |
| 2833 type = V8ClassIndex::ENTITY; | |
| 2834 break; | |
| 2835 case Node::PROCESSING_INSTRUCTION_NODE: | |
| 2836 type = V8ClassIndex::PROCESSINGINSTRUCTION; | |
| 2837 break; | |
| 2838 case Node::COMMENT_NODE: | |
| 2839 type = V8ClassIndex::COMMENT; | |
| 2840 break; | |
| 2841 case Node::DOCUMENT_NODE: { | |
| 2842 isDocument = true; | |
| 2843 Document* document = static_cast<Document*>(node); | |
| 2844 if (document->isHTMLDocument()) | |
| 2845 type = V8ClassIndex::HTMLDOCUMENT; | |
| 2846 #if ENABLE(SVG) | 2847 #if ENABLE(SVG) |
| 2847 else if (document->isSVGDocument()) | 2848 else if (document->isSVGDocument()) |
| 2848 type = V8ClassIndex::SVGDOCUMENT; | 2849 type = V8ClassIndex::SVGDOCUMENT; |
| 2849 #endif | 2850 #endif |
| 2850 else | 2851 else |
| 2851 type = V8ClassIndex::DOCUMENT; | 2852 type = V8ClassIndex::DOCUMENT; |
| 2852 break; | 2853 } else { |
| 2854 ASSERT(nodeType < sizeof(mapping)/sizeof(mapping[0])); |
| 2855 type = mapping[nodeType]; |
| 2856 ASSERT(type != V8ClassIndex::INVALID_CLASS_INDEX); |
| 2853 } | 2857 } |
| 2854 case Node::DOCUMENT_TYPE_NODE: | 2858 |
| 2855 type = V8ClassIndex::DOCUMENTTYPE; | 2859 v8::Local<v8::Context> v8Context; |
| 2856 break; | 2860 if (proxy) |
| 2857 case Node::NOTATION_NODE: | 2861 v8Context = proxy->context(); |
| 2858 type = V8ClassIndex::NOTATION; | |
| 2859 break; | |
| 2860 case Node::DOCUMENT_FRAGMENT_NODE: | |
| 2861 type = V8ClassIndex::DOCUMENTFRAGMENT; | |
| 2862 break; | |
| 2863 case Node::ENTITY_REFERENCE_NODE: | |
| 2864 type = V8ClassIndex::ENTITYREFERENCE; | |
| 2865 break; | |
| 2866 default: | |
| 2867 type = V8ClassIndex::NODE; | |
| 2868 } | |
| 2869 | 2862 |
| 2870 // Enter the node's context and create the wrapper in that context. | 2863 // Enter the node's context and create the wrapper in that context. |
| 2871 if (!v8Context.IsEmpty()) | 2864 if (!v8Context.IsEmpty()) |
| 2872 v8Context->Enter(); | 2865 v8Context->Enter(); |
| 2873 | 2866 |
| 2874 v8::Local<v8::Object> result = instantiateV8Object(type, V8ClassIndex::NODE,
node); | 2867 v8::Local<v8::Object> result = instantiateV8Object(proxy, type, V8ClassIndex
::NODE, node); |
| 2875 | 2868 |
| 2876 // Exit the node's context if it was entered. | 2869 // Exit the node's context if it was entered. |
| 2877 if (!v8Context.IsEmpty()) | 2870 if (!v8Context.IsEmpty()) |
| 2878 v8Context->Exit(); | 2871 v8Context->Exit(); |
| 2879 | 2872 |
| 2880 if (result.IsEmpty()) { | 2873 if (result.IsEmpty()) { |
| 2881 // If instantiation failed it's important not to add the result | 2874 // If instantiation failed it's important not to add the result |
| 2882 // to the DOM node map. Instead we return an empty handle, which | 2875 // to the DOM node map. Instead we return an empty handle, which |
| 2883 // should already be handled by callers of this function in case | 2876 // should already be handled by callers of this function in case |
| 2884 // the node is NULL. | 2877 // the node is NULL. |
| 2885 return result; | 2878 return result; |
| 2886 } | 2879 } |
| 2887 | 2880 |
| 2888 node->ref(); | 2881 node->ref(); |
| 2889 setJSWrapperForDOMNode(node, v8::Persistent<v8::Object>::New(result)); | 2882 domNodeMap.set(node, v8::Persistent<v8::Object>::New(result)); |
| 2890 | 2883 |
| 2891 if (isDocument) { | 2884 if (isDocument) { |
| 2892 Document* document = static_cast<Document*>(node); | |
| 2893 V8Proxy* proxy = V8Proxy::retrieve(document->frame()); | |
| 2894 if (proxy) | 2885 if (proxy) |
| 2895 proxy->updateDocumentWrapper(result); | 2886 proxy->updateDocumentWrapper(result); |
| 2896 | 2887 |
| 2897 if (type == V8ClassIndex::HTMLDOCUMENT) { | 2888 if (type == V8ClassIndex::HTMLDOCUMENT) { |
| 2898 // Create marker object and insert it in two internal fields. | 2889 // Create marker object and insert it in two internal fields. |
| 2899 // This is used to implement temporary shadowing of | 2890 // This is used to implement temporary shadowing of |
| 2900 // document.all. | 2891 // document.all. |
| 2901 ASSERT(result->InternalFieldCount() == V8Custom::kHTMLDocumentIntern
alFieldCount); | 2892 ASSERT(result->InternalFieldCount() == V8Custom::kHTMLDocumentIntern
alFieldCount); |
| 2902 v8::Local<v8::Object> marker = v8::Object::New(); | 2893 v8::Local<v8::Object> marker = v8::Object::New(); |
| 2903 result->SetInternalField(V8Custom::kHTMLDocumentMarkerIndex, marker)
; | 2894 result->SetInternalField(V8Custom::kHTMLDocumentMarkerIndex, marker)
; |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3246 int V8Proxy::contextDebugId(v8::Handle<v8::Context> context) | 3237 int V8Proxy::contextDebugId(v8::Handle<v8::Context> context) |
| 3247 { | 3238 { |
| 3248 v8::HandleScope scope; | 3239 v8::HandleScope scope; |
| 3249 if (!context->GetData()->IsObject()) | 3240 if (!context->GetData()->IsObject()) |
| 3250 return -1; | 3241 return -1; |
| 3251 v8::Handle<v8::Value> data = context->GetData()->ToObject()->Get( v8::String
::New(kContextDebugDataValue)); | 3242 v8::Handle<v8::Value> data = context->GetData()->ToObject()->Get( v8::String
::New(kContextDebugDataValue)); |
| 3252 return data->IsInt32() ? data->Int32Value() : -1; | 3243 return data->IsInt32() ? data->Int32Value() : -1; |
| 3253 } | 3244 } |
| 3254 | 3245 |
| 3255 } // namespace WebCore | 3246 } // namespace WebCore |
| OLD | NEW |