1 /* 2 * Copyright (C) 2008, 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 "V8XMLHttpRequest.h" 33 34 #include "Frame.h" 35 #include "V8Binding.h" 36 #include "V8Blob.h" 37 #include "V8Document.h" 38 #include "V8HTMLDocument.h" 39 #include "V8Proxy.h" 40 #include "V8Utilities.h" 41 #include "WorkerContext.h" 42 #include "WorkerContextExecutionProxy.h" 43 #include "XMLHttpRequest.h" 44 45 namespace WebCore { 46 47 v8::Handle<v8::Value> V8XMLHttpRequest::responseTextAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) 48 { 49 INC_STATS("DOM.XMLHttpRequest.responsetext._get"); 50 XMLHttpRequest* xmlHttpRequest = V8XMLHttpRequest::toNative(info.Holder()); 51 return xmlHttpRequest->responseText().v8StringOrNull(); 52 } 53 54 v8::Handle<v8::Value> V8XMLHttpRequest::addEventListenerCallback(const v8::Arguments& args) 55 { 56 INC_STATS("DOM.XMLHttpRequest.addEventListener()"); 57 XMLHttpRequest* xmlHttpRequest = V8XMLHttpRequest::toNative(args.Holder()); 58 59 RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(xmlHttpRequest, args[1], false, ListenerFindOrCreate); 60 if (listener) { 61 String type = toWebCoreString(args[0]); 62 bool useCapture = args[2]->BooleanValue(); 63 xmlHttpRequest->addEventListener(type, listener, useCapture); 64 65 createHiddenDependency(args.Holder(), args[1], cacheIndex); 66 } 67 return v8::Undefined(); 68 } 69 70 v8::Handle<v8::Value> V8XMLHttpRequest::removeEventListenerCallback(const v8::Arguments& args) 71 { 72 INC_STATS("DOM.XMLHttpRequest.removeEventListener()"); 73 XMLHttpRequest* xmlHttpRequest = V8XMLHttpRequest::toNative(args.Holder()); 74 75 RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(xmlHttpRequest, args[1], false, ListenerFindOnly); 76 if (listener) { 77 String type = toWebCoreString(args[0]); 78 bool useCapture = args[2]->BooleanValue(); 79 xmlHttpRequest->removeEventListener(type, listener.get(), useCapture); 80 81 removeHiddenDependency(args.Holder(), args[1], cacheIndex); 82 } 83 84 return v8::Undefined(); 85 } 86 87 v8::Handle<v8::Value> V8XMLHttpRequest::openCallback(const v8::Arguments& args) 88 { 89 INC_STATS("DOM.XMLHttpRequest.open()"); 90 // Four cases: 91 // open(method, url) 92 // open(method, url, async) 93 // open(method, url, async, user) 94 // open(method, url, async, user, passwd) 95 96 if (args.Length() < 2) 97 return throwError("Not enough arguments", V8Proxy::SyntaxError); 98 99 XMLHttpRequest* xmlHttpRequest = V8XMLHttpRequest::toNative(args.Holder()); 100 101 String method = toWebCoreString(args[0]); 102 String urlstring = toWebCoreString(args[1]); 103 ScriptExecutionContext* context = getScriptExecutionContext(); 104 if (!context) 105 return v8::Undefined(); 106 107 KURL url = context->completeURL(urlstring); 108 109 bool async = (args.Length() < 3) ? true : args[2]->BooleanValue(); 110 111 ExceptionCode ec = 0; 112 String user, passwd; 113 if (args.Length() >= 4 && !args[3]->IsUndefined()) { 114 user = toWebCoreStringWithNullCheck(args[3]); 115 116 if (args.Length() >= 5 && !args[4]->IsUndefined()) { 117 passwd = toWebCoreStringWithNullCheck(args[4]); 118 xmlHttpRequest->open(method, url, async, user, passwd, ec); 119 } else 120 xmlHttpRequest->open(method, url, async, user, ec); 121 } else 122 xmlHttpRequest->open(method, url, async, ec); 123 124 if (ec) 125 return throwError(ec); 126 127 return v8::Undefined(); 128 } 129 130 static bool IsDocumentType(v8::Handle<v8::Value> value) 131 { 132 // FIXME: add other document types. 133 return V8Document::HasInstance(value) || V8HTMLDocument::HasInstance(value); 134 } 135 136 v8::Handle<v8::Value> V8XMLHttpRequest::sendCallback(const v8::Arguments& args) 137 { 138 INC_STATS("DOM.XMLHttpRequest.send()"); 139 XMLHttpRequest* xmlHttpRequest = V8XMLHttpRequest::toNative(args.Holder()); 140 141 ExceptionCode ec = 0; 142 if (args.Length() < 1) 143 xmlHttpRequest->send(ec); 144 else { 145 v8::Handle<v8::Value> arg = args[0]; 146 if (IsDocumentType(arg)) { 147 v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(arg); 148 Document* document = V8Document::toNative(object); 149 ASSERT(document); 150 xmlHttpRequest->send(document, ec); 151 } else if (V8Blob::HasInstance(arg)) { 152 v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(arg); 153 Blob* blob = V8Blob::toNative(object); 154 ASSERT(blob); 155 xmlHttpRequest->send(blob, ec); 156 } else 157 xmlHttpRequest->send(toWebCoreStringWithNullCheck(arg), ec); 158 } 159 160 if (ec) 161 return throwError(ec); 162 163 return v8::Undefined(); 164 } 165 166 v8::Handle<v8::Value> V8XMLHttpRequest::setRequestHeaderCallback(const v8::Arguments& args) 167 { 168 INC_STATS("DOM.XMLHttpRequest.setRequestHeader()"); 169 if (args.Length() < 2) 170 return throwError("Not enough arguments", V8Proxy::SyntaxError); 171 172 XMLHttpRequest* xmlHttpRequest = V8XMLHttpRequest::toNative(args.Holder()); 173 ExceptionCode ec = 0; 174 String header = toWebCoreString(args[0]); 175 String value = toWebCoreString(args[1]); 176 xmlHttpRequest->setRequestHeader(header, value, ec); 177 if (ec) 178 return throwError(ec); 179 return v8::Undefined(); 180 } 181 182 v8::Handle<v8::Value> V8XMLHttpRequest::getResponseHeaderCallback(const v8::Arguments& args) 183 { 184 INC_STATS("DOM.XMLHttpRequest.getResponseHeader()"); 185 if (args.Length() < 1) 186 return throwError("Not enough arguments", V8Proxy::SyntaxError); 187 188 XMLHttpRequest* xmlHttpRequest = V8XMLHttpRequest::toNative(args.Holder()); 189 ExceptionCode ec = 0; 190 String header = toWebCoreString(args[0]); 191 String result = xmlHttpRequest->getResponseHeader(header, ec); 192 if (ec) 193 return throwError(ec); 194 return v8StringOrNull(result); 195 } 196 197 v8::Handle<v8::Value> V8XMLHttpRequest::overrideMimeTypeCallback(const v8::Arguments& args) 198 { 199 INC_STATS("DOM.XMLHttpRequest.overrideMimeType()"); 200 if (args.Length() < 1) 201 return throwError("Not enough arguments", V8Proxy::SyntaxError); 202 203 XMLHttpRequest* xmlHttpRequest = V8XMLHttpRequest::toNative(args.Holder()); 204 String value = toWebCoreString(args[0]); 205 xmlHttpRequest->overrideMimeType(value); 206 return v8::Undefined(); 207 } 208 209 v8::Handle<v8::Value> V8XMLHttpRequest::dispatchEventCallback(const v8::Arguments& args) 210 { 211 INC_STATS("DOM.XMLHttpRequest.dispatchEvent()"); 212 return v8::Undefined(); 213 } 214 215 } // namespace WebCore 216