LCOV - code coverage report
Current view: directory - dom/workers - XMLHttpRequest.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 316 18 5.7 %
Date: 2012-06-02 Functions: 45 2 4.4 %

       1                 : /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is Web Workers.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  *   The Mozilla Foundation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 2011
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Ben Turner <bent.mozilla@gmail.com> (Original Author)
      24                 :  *
      25                 :  * Alternatively, the contents of this file may be used under the terms of
      26                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      27                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      29                 :  * of those above. If you wish to allow use of your version of this file only
      30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      31                 :  * use your version of this file under the terms of the MPL, indicate your
      32                 :  * decision by deleting the provisions above and replace them with the notice
      33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      34                 :  * the provisions above, a recipient may use your version of this file under
      35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      36                 :  *
      37                 :  * ***** END LICENSE BLOCK ***** */
      38                 : 
      39                 : #include "XMLHttpRequest.h"
      40                 : 
      41                 : #include "jsapi.h"
      42                 : #include "jsfriendapi.h"
      43                 : 
      44                 : #include "Exceptions.h"
      45                 : #include "WorkerPrivate.h"
      46                 : #include "XMLHttpRequestPrivate.h"
      47                 : 
      48                 : #include "WorkerInlines.h"
      49                 : 
      50                 : #define PROPERTY_FLAGS \
      51                 :   (JSPROP_ENUMERATE | JSPROP_SHARED)
      52                 : 
      53                 : #define FUNCTION_FLAGS \
      54                 :   JSPROP_ENUMERATE
      55                 : 
      56                 : #define CONSTANT_FLAGS \
      57                 :   (JSPROP_ENUMERATE | JSPROP_SHARED | JSPROP_PERMANENT | JSPROP_READONLY)
      58                 : 
      59                 : USING_WORKERS_NAMESPACE
      60                 : 
      61                 : using mozilla::dom::workers::xhr::XMLHttpRequestPrivate;
      62                 : 
      63                 : namespace {
      64                 : 
      65                 : class XMLHttpRequestUpload : public events::EventTarget
      66                 : {
      67                 :   static JSClass sClass;
      68                 :   static JSPropertySpec sProperties[];
      69                 : 
      70                 :   enum
      71                 :   {
      72                 :     STRING_onabort = 0,
      73                 :     STRING_onerror,
      74                 :     STRING_onload,
      75                 :     STRING_onloadstart,
      76                 :     STRING_onprogress,
      77                 :     STRING_onloadend,
      78                 :     STRING_ontimeout,
      79                 : 
      80                 :     STRING_COUNT
      81                 :   };
      82                 : 
      83                 :   static const char* const sEventStrings[STRING_COUNT];
      84                 : 
      85                 :   enum SLOT {
      86                 :     SLOT_xhrParent = 0,
      87                 : 
      88                 :     SLOT_COUNT
      89                 :   };
      90                 : 
      91                 : public:
      92                 :   static JSClass*
      93               0 :   Class()
      94                 :   {
      95               0 :     return &sClass;
      96                 :   }
      97                 : 
      98                 :   static JSObject*
      99               0 :   InitClass(JSContext* aCx, JSObject* aObj, JSObject* aParentProto)
     100                 :   {
     101                 :     return JS_InitClass(aCx, aObj, aParentProto, &sClass, Construct, 0,
     102               0 :                         sProperties, NULL, NULL, NULL);
     103                 :   }
     104                 : 
     105                 :   static JSObject*
     106               0 :   Create(JSContext* aCx, JSObject* aParentObj)
     107                 :   {
     108               0 :     JS_ASSERT(aParentObj);
     109                 : 
     110               0 :     JSObject* obj = JS_NewObject(aCx, &sClass, NULL, NULL);
     111               0 :     if (obj) {
     112               0 :       JS_SetReservedSlot(obj, SLOT_xhrParent, OBJECT_TO_JSVAL(aParentObj));
     113               0 :       XMLHttpRequestUpload* priv = new XMLHttpRequestUpload();
     114               0 :       SetJSPrivateSafeish(obj, priv);
     115                 :     }
     116               0 :     return obj;
     117                 :   }
     118                 : 
     119                 :   static bool
     120                 :   UpdateState(JSContext* aCx, JSObject* aObj, const xhr::StateData& aNewState);
     121                 : 
     122                 : private:
     123               0 :   XMLHttpRequestUpload()
     124               0 :   {
     125               0 :     MOZ_COUNT_CTOR(mozilla::dom::workers::xhr::XMLHttpRequestUpload);
     126               0 :   }
     127                 : 
     128               0 :   ~XMLHttpRequestUpload()
     129               0 :   {
     130               0 :     MOZ_COUNT_DTOR(mozilla::dom::workers::xhr::XMLHttpRequestUpload);
     131               0 :   }
     132                 : 
     133                 :   static XMLHttpRequestUpload*
     134               0 :   GetPrivate(JSObject* aObj)
     135                 :   {
     136               0 :     if (aObj) {
     137               0 :       JSClass* classPtr = JS_GetClass(aObj);
     138               0 :       if (classPtr == &sClass) {
     139               0 :         return GetJSPrivateSafeish<XMLHttpRequestUpload>(aObj);
     140                 :       }
     141                 :     }
     142               0 :     return NULL;
     143                 :   }
     144                 : 
     145                 :   static XMLHttpRequestUpload*
     146               0 :   GetInstancePrivate(JSContext* aCx, JSObject* aObj, const char* aFunctionName)
     147                 :   {
     148               0 :     XMLHttpRequestUpload* priv = GetPrivate(aObj);
     149               0 :     if (priv) {
     150               0 :       return priv;
     151                 :     }
     152                 : 
     153                 :     JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL,
     154                 :                          JSMSG_INCOMPATIBLE_PROTO, sClass.name, aFunctionName,
     155               0 :                          JS_GetClass(aObj)->name);
     156               0 :     return NULL;
     157                 :   }
     158                 : 
     159                 :   static JSBool
     160               0 :   Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
     161                 :   {
     162                 :     JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL, JSMSG_WRONG_CONSTRUCTOR,
     163               0 :                          sClass.name);
     164               0 :     return false;
     165                 :   }
     166                 : 
     167                 :   static void
     168               0 :   Finalize(JSContext* aCx, JSObject* aObj)
     169                 :   {
     170               0 :     JS_ASSERT(JS_GetClass(aObj) == &sClass);
     171               0 :     XMLHttpRequestUpload* priv = GetPrivate(aObj);
     172               0 :     if (priv) {
     173               0 :       priv->FinalizeInstance(aCx);
     174               0 :       delete priv;
     175                 :     }
     176               0 :   }
     177                 : 
     178                 :   static void
     179               0 :   Trace(JSTracer* aTrc, JSObject* aObj)
     180                 :   {
     181               0 :     JS_ASSERT(JS_GetClass(aObj) == &sClass);
     182               0 :     XMLHttpRequestUpload* priv = GetPrivate(aObj);
     183               0 :     if (priv) {
     184               0 :       priv->TraceInstance(aTrc);
     185                 :     }
     186               0 :   }
     187                 : 
     188                 :   static JSBool
     189               0 :   GetEventListener(JSContext* aCx, JSObject* aObj, jsid aIdval, jsval* aVp)
     190                 :   {
     191               0 :     JS_ASSERT(JSID_IS_INT(aIdval));
     192               0 :     JS_ASSERT(JSID_TO_INT(aIdval) >= 0 && JSID_TO_INT(aIdval) < STRING_COUNT);
     193                 : 
     194               0 :     const char* name = sEventStrings[JSID_TO_INT(aIdval)];
     195                 : 
     196               0 :     XMLHttpRequestUpload* priv = GetInstancePrivate(aCx, aObj, name);
     197               0 :     if (!priv) {
     198               0 :       return false;
     199                 :     }
     200                 : 
     201               0 :     return priv->GetEventListenerOnEventTarget(aCx, name + 2, aVp);
     202                 :   }
     203                 : 
     204                 :   static JSBool
     205               0 :   SetEventListener(JSContext* aCx, JSObject* aObj, jsid aIdval, JSBool aStrict,
     206                 :                    jsval* aVp)
     207                 :   {
     208               0 :     JS_ASSERT(JSID_IS_INT(aIdval));
     209               0 :     JS_ASSERT(JSID_TO_INT(aIdval) >= 0 && JSID_TO_INT(aIdval) < STRING_COUNT);
     210                 : 
     211               0 :     const char* name = sEventStrings[JSID_TO_INT(aIdval)];
     212                 : 
     213               0 :     XMLHttpRequestUpload* priv = GetInstancePrivate(aCx, aObj, name);
     214               0 :     if (!priv) {
     215               0 :       return false;
     216                 :     }
     217                 : 
     218               0 :     return priv->SetEventListenerOnEventTarget(aCx, name + 2, aVp);
     219                 :   }
     220                 : };
     221                 : 
     222                 : JSClass XMLHttpRequestUpload::sClass = {
     223                 :   "XMLHttpRequestUpload",
     224                 :   JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_HAS_RESERVED_SLOTS(SLOT_COUNT),
     225                 :   JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
     226                 :   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, Finalize,
     227                 :   NULL, NULL, NULL, NULL, Trace
     228                 : };
     229                 : 
     230                 : JSPropertySpec XMLHttpRequestUpload::sProperties[] = {
     231            1464 :   { sEventStrings[STRING_onabort], STRING_onabort, PROPERTY_FLAGS,
     232                 :     GetEventListener, SetEventListener },
     233            1464 :   { sEventStrings[STRING_onerror], STRING_onerror, PROPERTY_FLAGS,
     234                 :     GetEventListener, SetEventListener },
     235            1464 :   { sEventStrings[STRING_onload], STRING_onload, PROPERTY_FLAGS,
     236                 :     GetEventListener, SetEventListener },
     237            1464 :   { sEventStrings[STRING_onloadstart], STRING_onloadstart, PROPERTY_FLAGS,
     238                 :     GetEventListener, SetEventListener },
     239            1464 :   { sEventStrings[STRING_onprogress], STRING_onprogress, PROPERTY_FLAGS,
     240                 :     GetEventListener, SetEventListener },
     241            1464 :   { sEventStrings[STRING_onloadend], STRING_onloadend, PROPERTY_FLAGS,
     242                 :     GetEventListener, SetEventListener },
     243            1464 :   { sEventStrings[STRING_ontimeout], STRING_ontimeout, PROPERTY_FLAGS,
     244                 :     GetEventListener, SetEventListener },
     245                 :   { 0, 0, 0, NULL, NULL }
     246           10248 : };
     247                 : 
     248                 : const char* const XMLHttpRequestUpload::sEventStrings[STRING_COUNT] = {
     249                 :   "onabort",
     250                 :   "onerror",
     251                 :   "onload",
     252                 :   "onloadstart",
     253                 :   "onprogress",
     254                 :   "onloadend",
     255                 :   "ontimeout"
     256                 : };
     257                 : 
     258                 : class XMLHttpRequest
     259                 : {
     260                 :   static JSClass sClass;
     261                 :   static JSPropertySpec sProperties[];
     262                 :   static JSFunctionSpec sFunctions[];
     263                 :   static JSPropertySpec sStaticProperties[];
     264                 : 
     265                 :   enum SLOT {
     266                 :     SLOT_channel = 0,
     267                 :     SLOT_responseXML,
     268                 :     SLOT_responseText,
     269                 :     SLOT_status,
     270                 :     SLOT_statusText,
     271                 :     SLOT_readyState,
     272                 :     SLOT_response,
     273                 :     SLOT_multipart,
     274                 :     SLOT_mozBackgroundRequest,
     275                 :     SLOT_withCredentials,
     276                 :     SLOT_upload,
     277                 :     SLOT_responseType,
     278                 :     SLOT_timeout,
     279                 : 
     280                 :     SLOT_COUNT
     281                 :   };
     282                 : 
     283                 :   enum {
     284                 :     UNSENT = 0,
     285                 :     OPENED = 1,
     286                 :     HEADERS_RECEIVED = 2,
     287                 :     LOADING = 3,
     288                 :     DONE = 4
     289                 :   };
     290                 : 
     291                 :   enum
     292                 :   {
     293                 :     STRING_onreadystatechange = 0,
     294                 :     STRING_onabort,
     295                 :     STRING_onerror,
     296                 :     STRING_onload,
     297                 :     STRING_onloadstart,
     298                 :     STRING_onprogress,
     299                 :     STRING_onloadend,
     300                 :     STRING_ontimeout,
     301                 : 
     302                 :     STRING_COUNT
     303                 :   };
     304                 : 
     305                 :   static const char* const sEventStrings[STRING_COUNT];
     306                 : 
     307                 : public:
     308                 :   static JSClass*
     309               0 :   Class()
     310                 :   {
     311               0 :     return &sClass;
     312                 :   }
     313                 : 
     314                 :   static JSObject*
     315               0 :   InitClass(JSContext* aCx, JSObject* aObj, JSObject* aParentProto)
     316                 :   {
     317                 :     JSObject* proto = JS_InitClass(aCx, aObj, aParentProto, &sClass, Construct,
     318                 :                                    0, sProperties, sFunctions,
     319               0 :                                    sStaticProperties, NULL);
     320               0 :     if (proto && !JS_DefineProperties(aCx, proto, sStaticProperties)) {
     321               0 :       return NULL;
     322                 :     }
     323                 : 
     324               0 :     return proto;
     325                 :   }
     326                 : 
     327                 :   static bool
     328               0 :   UpdateState(JSContext* aCx, JSObject* aObj, const xhr::StateData& aNewState)
     329                 :   {
     330               0 :     JS_ASSERT(GetPrivate(aObj));
     331                 : 
     332                 : #define HANDLE_STATE_VALUE(_member, _slot) \
     333                 :   if (aNewState. _member##Exception || !JSVAL_IS_VOID(aNewState. _member)) { \
     334                 :     JS_SetReservedSlot(aObj, _slot, aNewState. _member);                     \
     335                 :   }
     336                 : 
     337               0 :     HANDLE_STATE_VALUE(mResponseText, SLOT_responseText)
     338               0 :     HANDLE_STATE_VALUE(mStatus, SLOT_status)
     339               0 :     HANDLE_STATE_VALUE(mStatusText, SLOT_statusText)
     340               0 :     HANDLE_STATE_VALUE(mReadyState, SLOT_readyState)
     341               0 :     HANDLE_STATE_VALUE(mResponse, SLOT_response)
     342                 : 
     343                 : #undef HANDLE_STATE_VALUE
     344                 : 
     345               0 :     return true;
     346                 :   }
     347                 : 
     348                 : private:
     349                 :   // No instance of this class should ever be created so these are explicitly
     350                 :   // left without an implementation to prevent linking in case someone tries to
     351                 :   // make one.
     352                 :   XMLHttpRequest();
     353                 :   ~XMLHttpRequest();
     354                 : 
     355                 :   static XMLHttpRequestPrivate*
     356               0 :   GetPrivate(JSObject* aObj)
     357                 :   {
     358               0 :     if (aObj) {
     359               0 :       JSClass* classPtr = JS_GetClass(aObj);
     360               0 :       if (classPtr == &sClass) {
     361               0 :         return GetJSPrivateSafeish<XMLHttpRequestPrivate>(aObj);
     362                 :       }
     363                 :     }
     364               0 :     return NULL;
     365                 :   }
     366                 : 
     367                 :   static XMLHttpRequestPrivate*
     368               0 :   GetInstancePrivate(JSContext* aCx, JSObject* aObj, const char* aFunctionName)
     369                 :   {
     370               0 :     XMLHttpRequestPrivate* priv = GetPrivate(aObj);
     371               0 :     if (priv) {
     372               0 :       return priv;
     373                 :     }
     374                 : 
     375                 :     JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL,
     376                 :                          JSMSG_INCOMPATIBLE_PROTO, sClass.name, aFunctionName,
     377               0 :                          JS_GetClass(aObj)->name);
     378               0 :     return NULL;
     379                 :   }
     380                 : 
     381                 :   static JSBool
     382               0 :   Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
     383                 :   {
     384               0 :     JSObject* obj = JS_NewObject(aCx, &sClass, NULL, NULL);
     385               0 :     if (!obj) {
     386               0 :       return false;
     387                 :     }
     388                 : 
     389               0 :     JSString* textStr = JS_NewStringCopyN(aCx, "text", 4);
     390               0 :     if (!textStr) {
     391               0 :       return false;
     392                 :     }
     393                 : 
     394               0 :     jsval emptyString = JS_GetEmptyStringValue(aCx);
     395               0 :     jsval zero = INT_TO_JSVAL(0);
     396                 : 
     397               0 :     JS_SetReservedSlot(obj, SLOT_channel, JSVAL_NULL);
     398               0 :     JS_SetReservedSlot(obj, SLOT_responseXML, JSVAL_NULL);
     399               0 :     JS_SetReservedSlot(obj, SLOT_responseText, emptyString);
     400               0 :     JS_SetReservedSlot(obj, SLOT_status, zero);
     401               0 :     JS_SetReservedSlot(obj, SLOT_statusText, emptyString);
     402               0 :     JS_SetReservedSlot(obj, SLOT_readyState, zero);
     403               0 :     JS_SetReservedSlot(obj, SLOT_multipart, JSVAL_FALSE);
     404               0 :     JS_SetReservedSlot(obj, SLOT_mozBackgroundRequest, JSVAL_FALSE);
     405               0 :     JS_SetReservedSlot(obj, SLOT_withCredentials, JSVAL_FALSE);
     406               0 :     JS_SetReservedSlot(obj, SLOT_upload, JSVAL_NULL);
     407               0 :     JS_SetReservedSlot(obj, SLOT_responseType, STRING_TO_JSVAL(textStr));
     408               0 :     JS_SetReservedSlot(obj, SLOT_timeout, zero);
     409                 : 
     410               0 :     WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(aCx);
     411               0 :     XMLHttpRequestPrivate* priv = new XMLHttpRequestPrivate(obj, workerPrivate);
     412               0 :     SetJSPrivateSafeish(obj, priv);
     413                 : 
     414               0 :     JS_SET_RVAL(aCx, aVp, OBJECT_TO_JSVAL(obj));
     415               0 :     return true;
     416                 :   }
     417                 : 
     418                 :   static void
     419               0 :   Finalize(JSContext* aCx, JSObject* aObj)
     420                 :   {
     421               0 :     JS_ASSERT(JS_GetClass(aObj) == &sClass);
     422               0 :     XMLHttpRequestPrivate* priv = GetPrivate(aObj);
     423               0 :     if (priv) {
     424               0 :       priv->FinalizeInstance(aCx);
     425               0 :       delete priv;
     426                 :     }
     427               0 :   }
     428                 : 
     429                 :   static void
     430               0 :   Trace(JSTracer* aTrc, JSObject* aObj)
     431                 :   {
     432               0 :     JS_ASSERT(JS_GetClass(aObj) == &sClass);
     433               0 :     XMLHttpRequestPrivate* priv = GetPrivate(aObj);
     434               0 :     if (priv) {
     435               0 :       priv->TraceInstance(aTrc);
     436                 :     }
     437               0 :   }
     438                 : 
     439                 :   static JSBool
     440               0 :   GetProperty(JSContext* aCx, JSObject* aObj, jsid aIdval, jsval* aVp)
     441                 :   {
     442               0 :     JS_ASSERT(JSID_IS_INT(aIdval));
     443                 : 
     444               0 :     int32 slot = JSID_TO_INT(aIdval);
     445               0 :     const char*& name = sProperties[slot].name;
     446                 : 
     447               0 :     if (!GetInstancePrivate(aCx, aObj, name)) {
     448               0 :       return false;
     449                 :     }
     450                 : 
     451               0 :     jsval rval = JS_GetReservedSlot(aObj, slot);
     452                 : 
     453               0 :     if (JSVAL_IS_VOID(rval)) {
     454                 :       // Throw an exception.
     455               0 :       exceptions::ThrowDOMExceptionForCode(aCx, INVALID_STATE_ERR);
     456               0 :       return false;
     457                 :     }
     458                 : 
     459               0 :     *aVp = rval;
     460               0 :     return true;
     461                 :   }
     462                 : 
     463                 :   static JSBool
     464               0 :   GetConstant(JSContext* aCx, JSObject* aObj, jsid idval, jsval* aVp)
     465                 :   {
     466               0 :     JS_ASSERT(JSID_IS_INT(idval));
     467               0 :     JS_ASSERT(JSID_TO_INT(idval) >= UNSENT &&
     468               0 :               JSID_TO_INT(idval) <= DONE);
     469                 : 
     470               0 :     *aVp = INT_TO_JSVAL(JSID_TO_INT(idval));
     471               0 :     return true;
     472                 :   }
     473                 : 
     474                 :   static JSBool
     475               0 :   GetUpload(JSContext* aCx, JSObject* aObj, jsid aIdval, jsval* aVp)
     476                 :   {
     477               0 :     JS_ASSERT(JSID_IS_INT(aIdval));
     478                 : 
     479               0 :     int32 slot = JSID_TO_INT(aIdval);
     480                 : 
     481                 :     XMLHttpRequestPrivate* priv =
     482               0 :       GetInstancePrivate(aCx, aObj, sProperties[slot].name);
     483               0 :     if (!priv) {
     484               0 :       return false;
     485                 :     }
     486                 : 
     487               0 :     jsval uploadVal = JS_GetReservedSlot(aObj, slot);
     488                 : 
     489               0 :     if (JSVAL_IS_NULL(uploadVal)) {
     490               0 :       JSObject* uploadObj = XMLHttpRequestUpload::Create(aCx, aObj);
     491               0 :       if (!uploadObj) {
     492               0 :         return false;
     493                 :       }
     494                 : 
     495               0 :       uploadVal = OBJECT_TO_JSVAL(uploadObj);
     496                 : 
     497               0 :       JS_SetReservedSlot(aObj, slot, uploadVal);
     498                 : 
     499               0 :       priv->SetUploadObject(uploadObj);
     500                 :     }
     501                 : 
     502               0 :     JS_ASSERT(!JSVAL_IS_PRIMITIVE(uploadVal));
     503                 : 
     504               0 :     *aVp = uploadVal;
     505               0 :     return true;
     506                 :   }
     507                 : 
     508                 : #define IMPL_SETTER(_name)                                                     \
     509                 :   static JSBool                                                                \
     510                 :   Set##_name (JSContext* aCx, JSObject* aObj, jsid aIdval, JSBool aStrict,     \
     511                 :               jsval* aVp)                                                      \
     512                 :   {                                                                            \
     513                 :     JS_ASSERT(JSID_IS_INT(aIdval));                                            \
     514                 :                                                                                \
     515                 :     int32 slot = JSID_TO_INT(aIdval);                                          \
     516                 :                                                                                \
     517                 :     XMLHttpRequestPrivate* priv =                                              \
     518                 :       GetInstancePrivate(aCx, aObj, sProperties[slot].name);                   \
     519                 :     if (!priv) {                                                               \
     520                 :       return false;                                                            \
     521                 :     }                                                                          \
     522                 :                                                                                \
     523                 :     jsval oldVal = JS_GetReservedSlot(aObj, slot);                             \
     524                 :                                                                                \
     525                 :     jsval rval = *aVp;                                                         \
     526                 :     if (!priv->Set##_name (aCx, oldVal, &rval))                                \
     527                 :       return false;                                                            \
     528                 :     JS_SetReservedSlot(aObj, slot, rval);                                      \
     529                 :                                                                                \
     530                 :     *aVp = rval;                                                               \
     531                 :     return true;                                                               \
     532                 :   }
     533                 : 
     534               0 :   IMPL_SETTER(Multipart)
     535               0 :   IMPL_SETTER(MozBackgroundRequest)
     536               0 :   IMPL_SETTER(WithCredentials)
     537               0 :   IMPL_SETTER(ResponseType)
     538               0 :   IMPL_SETTER(Timeout)
     539                 : 
     540                 : #undef IMPL_SETTER
     541                 : 
     542                 :   static JSBool
     543               0 :   GetEventListener(JSContext* aCx, JSObject* aObj, jsid aIdval, jsval* aVp)
     544                 :   {
     545               0 :     JS_ASSERT(JSID_IS_INT(aIdval));
     546               0 :     JS_ASSERT(JSID_TO_INT(aIdval) >= 0 && JSID_TO_INT(aIdval) < STRING_COUNT);
     547                 : 
     548               0 :     const char* name = sEventStrings[JSID_TO_INT(aIdval)];
     549                 : 
     550               0 :     XMLHttpRequestPrivate* priv = GetInstancePrivate(aCx, aObj, name);
     551               0 :     if (!priv) {
     552               0 :       return false;
     553                 :     }
     554                 : 
     555               0 :     return priv->GetEventListenerOnEventTarget(aCx, name + 2, aVp);
     556                 :   }
     557                 : 
     558                 :   static JSBool
     559               0 :   SetEventListener(JSContext* aCx, JSObject* aObj, jsid aIdval, JSBool aStrict,
     560                 :                    jsval* aVp)
     561                 :   {
     562               0 :     JS_ASSERT(JSID_IS_INT(aIdval));
     563               0 :     JS_ASSERT(JSID_TO_INT(aIdval) >= 0 && JSID_TO_INT(aIdval) < STRING_COUNT);
     564                 : 
     565               0 :     const char* name = sEventStrings[JSID_TO_INT(aIdval)];
     566                 : 
     567               0 :     XMLHttpRequestPrivate* priv = GetInstancePrivate(aCx, aObj, name);
     568               0 :     if (!priv) {
     569               0 :       return false;
     570                 :     }
     571                 : 
     572               0 :     return priv->SetEventListenerOnEventTarget(aCx, name + 2, aVp);
     573                 :   }
     574                 : 
     575                 :   static JSBool
     576               0 :   Abort(JSContext* aCx, unsigned aArgc, jsval* aVp)
     577                 :   {
     578               0 :     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     579               0 :     if (!obj) {
     580               0 :       return false;
     581                 :     }
     582                 : 
     583                 :     XMLHttpRequestPrivate* priv =
     584               0 :       GetInstancePrivate(aCx, obj, sFunctions[0].name);
     585               0 :     if (!priv) {
     586               0 :       return false;
     587                 :     }
     588                 : 
     589               0 :     return priv->Abort(aCx);
     590                 :   }
     591                 : 
     592                 :   static JSBool
     593               0 :   GetAllResponseHeaders(JSContext* aCx, unsigned aArgc, jsval* aVp)
     594                 :   {
     595               0 :     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     596               0 :     if (!obj) {
     597               0 :       return false;
     598                 :     }
     599                 : 
     600                 :     XMLHttpRequestPrivate* priv =
     601               0 :       GetInstancePrivate(aCx, obj, sFunctions[1].name);
     602               0 :     if (!priv) {
     603               0 :       return false;
     604                 :     }
     605                 : 
     606               0 :     JSString* responseHeaders = priv->GetAllResponseHeaders(aCx);
     607               0 :     if (!responseHeaders) {
     608               0 :       return false;
     609                 :     }
     610                 : 
     611               0 :     JS_SET_RVAL(aCx, aVp, STRING_TO_JSVAL(responseHeaders));
     612               0 :     return true;
     613                 :   }
     614                 : 
     615                 :   static JSBool
     616               0 :   GetResponseHeader(JSContext* aCx, unsigned aArgc, jsval* aVp)
     617                 :   {
     618               0 :     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     619               0 :     if (!obj) {
     620               0 :       return false;
     621                 :     }
     622                 : 
     623                 :     XMLHttpRequestPrivate* priv =
     624               0 :       GetInstancePrivate(aCx, obj, sFunctions[2].name);
     625               0 :     if (!priv) {
     626               0 :       return false;
     627                 :     }
     628                 : 
     629                 :     jsval headerVal;
     630               0 :     if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "v", &headerVal)) {
     631               0 :       return false;
     632                 :     }
     633                 : 
     634                 :     JSString* header;
     635               0 :     if (JSVAL_IS_NULL(headerVal)) {
     636               0 :       header = JSVAL_TO_STRING(JS_GetEmptyStringValue(aCx));
     637                 :     }
     638                 :     else {
     639               0 :       header = JS_ValueToString(aCx, headerVal);
     640               0 :       if (!header) {
     641               0 :         return false;
     642                 :       }
     643                 :     }
     644                 : 
     645               0 :     JSString* value = priv->GetResponseHeader(aCx, header);
     646               0 :     if (!value) {
     647               0 :       return false;
     648                 :     }
     649                 :   
     650               0 :     JS_SET_RVAL(aCx, aVp, STRING_TO_JSVAL(value));
     651               0 :     return true;
     652                 :   }
     653                 : 
     654                 :   static JSBool
     655               0 :   Open(JSContext* aCx, unsigned aArgc, jsval* aVp)
     656                 :   {
     657               0 :     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     658               0 :     if (!obj) {
     659               0 :       return false;
     660                 :     }
     661                 : 
     662                 :     XMLHttpRequestPrivate* priv =
     663               0 :       GetInstancePrivate(aCx, obj, sFunctions[3].name);
     664               0 :     if (!priv) {
     665               0 :       return false;
     666                 :     }
     667                 : 
     668                 :     JSString* method, *url;
     669               0 :     JSBool async = true;
     670               0 :     JSString* user = JS_GetEmptyString(JS_GetRuntime(aCx));
     671               0 :     JSString* password = user;
     672               0 :     if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "SS/bSS", &method,
     673               0 :                              &url, &async, &user, &password)) {
     674               0 :       return false;
     675                 :     }
     676                 : 
     677               0 :     return priv->Open(aCx, method, url, async, user, password);
     678                 :   }
     679                 : 
     680                 :   static JSBool
     681               0 :   Send(JSContext* aCx, unsigned aArgc, jsval* aVp)
     682                 :   {
     683               0 :     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     684               0 :     if (!obj) {
     685               0 :       return false;
     686                 :     }
     687                 : 
     688                 :     XMLHttpRequestPrivate* priv =
     689               0 :       GetInstancePrivate(aCx, obj, sFunctions[4].name);
     690               0 :     if (!priv) {
     691               0 :       return false;
     692                 :     }
     693                 : 
     694               0 :     jsval body = aArgc ? JS_ARGV(aCx, aVp)[0] : JSVAL_VOID;
     695                 : 
     696               0 :     return priv->Send(aCx, !!aArgc, body);
     697                 :   }
     698                 : 
     699                 :   static JSBool
     700               0 :   SendAsBinary(JSContext* aCx, unsigned aArgc, jsval* aVp)
     701                 :   {
     702               0 :     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     703               0 :     if (!obj) {
     704               0 :       return false;
     705                 :     }
     706                 : 
     707                 :     XMLHttpRequestPrivate* priv =
     708               0 :       GetInstancePrivate(aCx, obj, sFunctions[5].name);
     709               0 :     if (!priv) {
     710               0 :       return false;
     711                 :     }
     712                 : 
     713                 :     jsval bodyVal;
     714               0 :     if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "v", &bodyVal)) {
     715               0 :       return false;
     716                 :     }
     717                 : 
     718                 :     JSString* body;
     719               0 :     if (JSVAL_IS_NULL(bodyVal)) {
     720               0 :       body = JSVAL_TO_STRING(JS_GetEmptyStringValue(aCx));
     721                 :     }
     722                 :     else {
     723               0 :       body = JS_ValueToString(aCx, bodyVal);
     724               0 :       if (!body) {
     725               0 :         return false;
     726                 :       }
     727                 :     }
     728                 : 
     729               0 :     return priv->SendAsBinary(aCx, body);
     730                 :   }
     731                 : 
     732                 :   static JSBool
     733               0 :   SetRequestHeader(JSContext* aCx, unsigned aArgc, jsval* aVp)
     734                 :   {
     735               0 :     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     736               0 :     if (!obj) {
     737               0 :       return false;
     738                 :     }
     739                 : 
     740                 :     XMLHttpRequestPrivate* priv =
     741               0 :       GetInstancePrivate(aCx, obj, sFunctions[6].name);
     742               0 :     if (!priv) {
     743               0 :       return false;
     744                 :     }
     745                 : 
     746                 :     JSString* header, *value;
     747               0 :     if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "SS", &header,
     748               0 :                              &value)) {
     749               0 :       return false;
     750                 :     }
     751                 : 
     752               0 :     return priv->SetRequestHeader(aCx, header, value);
     753                 :   }
     754                 : 
     755                 :   static JSBool
     756               0 :   OverrideMimeType(JSContext* aCx, unsigned aArgc, jsval* aVp)
     757                 :   {
     758               0 :     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     759               0 :     if (!obj) {
     760               0 :       return false;
     761                 :     }
     762                 : 
     763                 :     XMLHttpRequestPrivate* priv =
     764               0 :       GetInstancePrivate(aCx, obj, sFunctions[7].name);
     765               0 :     if (!priv) {
     766               0 :       return false;
     767                 :     }
     768                 : 
     769                 :     JSString* mimeType;
     770               0 :     if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "S", &mimeType)) {
     771               0 :       return false;
     772                 :     }
     773                 : 
     774               0 :     return priv->OverrideMimeType(aCx, mimeType);
     775                 :   }
     776                 : };
     777                 : 
     778                 : JSClass XMLHttpRequest::sClass = {
     779                 :   "XMLHttpRequest",
     780                 :   JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_HAS_RESERVED_SLOTS(SLOT_COUNT),
     781                 :   JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
     782                 :   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, Finalize,
     783                 :   NULL, NULL, NULL, NULL, Trace
     784                 : };
     785                 : 
     786                 : JSPropertySpec XMLHttpRequest::sProperties[] = {
     787                 : 
     788                 : #define GENERIC_READONLY_PROPERTY(_name) \
     789                 :   { #_name, SLOT_##_name, PROPERTY_FLAGS, GetProperty, \
     790                 :     js_GetterOnlyPropertyStub },
     791                 : 
     792                 :   GENERIC_READONLY_PROPERTY(channel)
     793                 :   GENERIC_READONLY_PROPERTY(responseXML)
     794                 :   GENERIC_READONLY_PROPERTY(responseText)
     795                 :   GENERIC_READONLY_PROPERTY(status)
     796                 :   GENERIC_READONLY_PROPERTY(statusText)
     797                 :   GENERIC_READONLY_PROPERTY(readyState)
     798                 :   GENERIC_READONLY_PROPERTY(response)
     799                 : 
     800                 :   { "multipart", SLOT_multipart, PROPERTY_FLAGS, GetProperty, SetMultipart },
     801                 :   { "mozBackgroundRequest", SLOT_mozBackgroundRequest, PROPERTY_FLAGS,
     802                 :     GetProperty, SetMozBackgroundRequest },
     803                 :   { "withCredentials", SLOT_withCredentials, PROPERTY_FLAGS, GetProperty,
     804                 :     SetWithCredentials },
     805                 :   { "upload", SLOT_upload, PROPERTY_FLAGS, GetUpload,
     806                 :     js_GetterOnlyPropertyStub },
     807                 :   { "responseType", SLOT_responseType, PROPERTY_FLAGS, GetProperty,
     808                 :     SetResponseType },
     809                 :   { "timeout", SLOT_timeout, PROPERTY_FLAGS, GetProperty,
     810                 :     SetTimeout },
     811            1464 :   { sEventStrings[STRING_onreadystatechange], STRING_onreadystatechange,
     812                 :     PROPERTY_FLAGS, GetEventListener, SetEventListener },
     813            1464 :   { sEventStrings[STRING_onabort], STRING_onabort, PROPERTY_FLAGS,
     814                 :     GetEventListener, SetEventListener },
     815            1464 :   { sEventStrings[STRING_onerror], STRING_onerror, PROPERTY_FLAGS,
     816                 :     GetEventListener, SetEventListener },
     817            1464 :   { sEventStrings[STRING_onload], STRING_onload, PROPERTY_FLAGS,
     818                 :     GetEventListener, SetEventListener },
     819            1464 :   { sEventStrings[STRING_onloadstart], STRING_onloadstart, PROPERTY_FLAGS,
     820                 :     GetEventListener, SetEventListener },
     821            1464 :   { sEventStrings[STRING_onprogress], STRING_onprogress, PROPERTY_FLAGS,
     822                 :     GetEventListener, SetEventListener },
     823            1464 :   { sEventStrings[STRING_onloadend], STRING_onloadend, PROPERTY_FLAGS,
     824                 :     GetEventListener, SetEventListener },
     825            1464 :   { sEventStrings[STRING_ontimeout], STRING_ontimeout, PROPERTY_FLAGS,
     826                 :     GetEventListener, SetEventListener },
     827                 : 
     828                 : #undef GENERIC_READONLY_PROPERTY
     829                 : 
     830                 :   { 0, 0, 0, NULL, NULL }
     831           11712 : };
     832                 : 
     833                 : JSFunctionSpec XMLHttpRequest::sFunctions[] = {
     834                 :   JS_FN("abort", Abort, 0, FUNCTION_FLAGS),
     835                 :   JS_FN("getAllResponseHeaders", GetAllResponseHeaders, 0, FUNCTION_FLAGS),
     836                 :   JS_FN("getResponseHeader", GetResponseHeader, 1, FUNCTION_FLAGS),
     837                 :   JS_FN("open", Open, 2, FUNCTION_FLAGS),
     838                 :   JS_FN("send", Send, 0, FUNCTION_FLAGS),
     839                 :   JS_FN("sendAsBinary", SendAsBinary, 1, FUNCTION_FLAGS),
     840                 :   JS_FN("setRequestHeader", SetRequestHeader, 2, FUNCTION_FLAGS),
     841                 :   JS_FN("overrideMimeType", OverrideMimeType, 1, FUNCTION_FLAGS),
     842                 :   JS_FS_END
     843                 : };
     844                 : 
     845                 : JSPropertySpec XMLHttpRequest::sStaticProperties[] = {
     846                 :   { "UNSENT", UNSENT, CONSTANT_FLAGS, GetConstant, NULL },
     847                 :   { "OPENED", OPENED, CONSTANT_FLAGS, GetConstant, NULL },
     848                 :   { "HEADERS_RECEIVED", HEADERS_RECEIVED, CONSTANT_FLAGS, GetConstant, NULL },
     849                 :   { "LOADING", LOADING, CONSTANT_FLAGS, GetConstant, NULL },
     850                 :   { "DONE", DONE, CONSTANT_FLAGS, GetConstant, NULL },
     851                 :   { 0, 0, 0, NULL, NULL }
     852                 : };
     853                 : 
     854                 : const char* const XMLHttpRequest::sEventStrings[STRING_COUNT] = {
     855                 :   "onreadystatechange",
     856                 :   "onabort",
     857                 :   "onerror",
     858                 :   "onload",
     859                 :   "onloadstart",
     860                 :   "onprogress",
     861                 :   "onloadend",
     862                 :   "ontimeout"
     863                 : };
     864                 : 
     865                 : // static
     866                 : bool
     867               0 : XMLHttpRequestUpload::UpdateState(JSContext* aCx, JSObject* aObj,
     868                 :                                   const xhr::StateData& aNewState)
     869                 : {
     870               0 :   JS_ASSERT(JS_GetClass(aObj) == &sClass);
     871                 : 
     872               0 :   jsval parentVal = JS_GetReservedSlot(aObj, SLOT_xhrParent);
     873                 : 
     874               0 :   if (!JSVAL_IS_PRIMITIVE(parentVal)) {
     875                 :     return XMLHttpRequest::UpdateState(aCx, JSVAL_TO_OBJECT(parentVal),
     876               0 :                                        aNewState);
     877                 :   }
     878                 : 
     879               0 :   return true;
     880                 : }
     881                 : 
     882                 : } // anonymous namespace
     883                 : 
     884                 : BEGIN_WORKERS_NAMESPACE
     885                 : 
     886                 : namespace xhr {
     887                 : 
     888                 : bool
     889               0 : InitClasses(JSContext* aCx, JSObject* aGlobal, JSObject* aProto)
     890                 : {
     891               0 :   return XMLHttpRequest::InitClass(aCx, aGlobal, aProto) &&
     892               0 :          XMLHttpRequestUpload::InitClass(aCx, aGlobal, aProto);
     893                 : }
     894                 : 
     895                 : bool
     896               0 : UpdateXHRState(JSContext* aCx, JSObject* aObj, bool aIsUpload,
     897                 :                const StateData& aNewState)
     898                 : {
     899                 :   return aIsUpload ?
     900                 :          XMLHttpRequestUpload::UpdateState(aCx, aObj, aNewState) :
     901               0 :          XMLHttpRequest::UpdateState(aCx, aObj, aNewState);
     902                 : }
     903                 : 
     904                 : } // namespace xhr
     905                 : 
     906                 : bool
     907               0 : ClassIsXMLHttpRequest(JSClass* aClass)
     908                 : {
     909               0 :   return XMLHttpRequest::Class() == aClass ||
     910               0 :          XMLHttpRequestUpload::Class() == aClass;
     911                 : }
     912                 : 
     913            4392 : END_WORKERS_NAMESPACE

Generated by: LCOV version 1.7