1 /* 2 * Copyright (C) 2007-2009 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include "config.h" 32 #include "V8Document.h" 33 34 #include "CanvasRenderingContext.h" 35 #include "Document.h" 36 #include "ExceptionCode.h" 37 #include "Node.h" 38 #include "XPathNSResolver.h" 39 #include "XPathResult.h" 40 41 #include "V8Binding.h" 42 #include "V8CanvasRenderingContext2D.h" 43 #include "V8CustomXPathNSResolver.h" 44 #include "V8DOMImplementation.h" 45 #include "V8HTMLDocument.h" 46 #include "V8IsolatedContext.h" 47 #include "V8Node.h" 48 #include "V8Proxy.h" 49 #include "V8SVGDocument.h" 50 #include "V8WebGLRenderingContext.h" 51 #include "V8XPathNSResolver.h" 52 #include "V8XPathResult.h" 53 54 #include <wtf/RefPtr.h> 55 56 namespace WebCore { 57 58 #if ENABLE(XPATH) 59 v8::Handle<v8::Value> V8Document::evaluateCallback(const v8::Arguments& args) 60 { 61 INC_STATS("DOM.Document.evaluate()"); 62 63 RefPtr<Document> document = V8Document::toNative(args.Holder()); 64 ExceptionCode ec = 0; 65 String expression = toWebCoreString(args[0]); 66 RefPtr<Node> contextNode; 67 if (V8Node::HasInstance(args[1])) 68 contextNode = V8Node::toNative(v8::Handle<v8::Object>::Cast(args[1])); 69 70 RefPtr<XPathNSResolver> resolver = V8DOMWrapper::getXPathNSResolver(args[2], V8Proxy::retrieve(V8Proxy::retrieveFrameForCallingContext())); 71 if (!resolver && !args[2]->IsNull() && !args[2]->IsUndefined()) 72 return throwError(TYPE_MISMATCH_ERR); 73 74 int type = toInt32(args[3]); 75 RefPtr<XPathResult> inResult; 76 if (V8XPathResult::HasInstance(args[4])) 77 inResult = V8XPathResult::toNative(v8::Handle<v8::Object>::Cast(args[4])); 78 79 v8::TryCatch exceptionCatcher; 80 RefPtr<XPathResult> result = document->evaluate(expression, contextNode.get(), resolver.get(), type, inResult.get(), ec); 81 if (exceptionCatcher.HasCaught()) 82 return throwError(exceptionCatcher.Exception()); 83 84 if (ec) 85 return throwError(ec); 86 87 return toV8(result.release()); 88 } 89 #endif 90 91 v8::Handle<v8::Value> V8Document::getCSSCanvasContextCallback(const v8::Arguments& args) 92 { 93 INC_STATS("DOM.Document.getCSSCanvasContext"); 94 v8::Handle<v8::Object> holder = args.Holder(); 95 Document* imp = V8Document::toNative(holder); 96 String contextId = toWebCoreString(args[0]); 97 String name = toWebCoreString(args[1]); 98 int width = toInt32(args[2]); 99 int height = toInt32(args[3]); 100 CanvasRenderingContext* result = imp->getCSSCanvasContext(contextId, name, width, height); 101 if (!result) 102 return v8::Undefined(); 103 if (result->is2d()) 104 return toV8(static_cast<CanvasRenderingContext2D*>(result)); 105 #if ENABLE(3D_CANVAS) 106 else if (result->is3d()) 107 return toV8(static_cast<WebGLRenderingContext*>(result)); 108 #endif // ENABLE(3D_CANVAS) 109 ASSERT_NOT_REACHED(); 110 return v8::Undefined(); 111 } 112 113 114 // DOMImplementation is a singleton in WebCore. If we use our normal 115 // mapping from DOM objects to V8 wrappers, the same wrapper will be 116 // shared for all frames in the same process. This is a major 117 // security problem. Therefore, we generate a DOMImplementation 118 // wrapper per document and store it in an internal field of the 119 // document. Since the DOMImplementation object is a singleton, we do 120 // not have to do anything to keep the DOMImplementation object alive 121 // for the lifetime of the wrapper. 122 v8::Handle<v8::Value> V8Document::implementationAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) 123 { 124 ASSERT(info.Holder()->InternalFieldCount() >= internalFieldCount); 125 126 // Check if the internal field already contains a wrapper. 127 v8::Local<v8::Value> implementation = info.Holder()->GetInternalField(V8Document::implementationIndex); 128 if (!implementation->IsUndefined()) 129 return implementation; 130 131 // Generate a wrapper. 132 Document* document = V8Document::toNative(info.Holder()); 133 v8::Handle<v8::Value> wrapper = toV8(document->implementation()); 134 135 // Store the wrapper in the internal field. 136 info.Holder()->SetInternalField(implementationIndex, wrapper); 137 138 return wrapper; 139 } 140 141 v8::Handle<v8::Value> toV8(Document* impl, bool forceNewObject) 142 { 143 if (!impl) 144 return v8::Null(); 145 if (impl->isHTMLDocument()) 146 return toV8(static_cast<HTMLDocument*>(impl), forceNewObject); 147 #if ENABLE(SVG) 148 if (impl->isSVGDocument()) 149 return toV8(static_cast<SVGDocument*>(impl), forceNewObject); 150 #endif 151 v8::Handle<v8::Object> wrapper = V8Document::wrap(impl, forceNewObject); 152 if (wrapper.IsEmpty()) 153 return wrapper; 154 if (!V8IsolatedContext::getEntered()) { 155 if (V8Proxy* proxy = V8Proxy::retrieve(impl->frame())) 156 proxy->windowShell()->updateDocumentWrapper(wrapper); 157 } 158 return wrapper; 159 } 160 161 } // namespace WebCore 162