[webkit-changes] cvs commit: WebCore/khtml/ecma xmlhttprequest.cpp xmlhttprequest.h

Adele adele at opensource.apple.com
Mon Dec 19 11:17:33 PST 2005


adele       05/12/19 11:17:33

  Modified:    .        ChangeLog
               khtml/ecma xmlhttprequest.cpp xmlhttprequest.h
  Log:
          Reviewed by Darin, committed by Adele.
  
          - fix http://bugzilla.opendarwin.org/show_bug.cgi?id=5744
            XMLHttpRequest does not apply page encoding after assigning via innerHtml
  
          * khtml/ecma/xmlhttprequest.cpp:
          (getMIMEType): A helper function to get MIME type from a Content-Type string.
          (getCharset): A helper function to get charset from a Content-Type string.
          (KJS::XMLHttpRequest::getValueProperty): Factored out responseIsXML().
          (KJS::XMLHttpRequest::getResponseHeader): Return QString instead of JSValue
            (to get rid of unnecessary JSLocks).
          (KJS::XMLHttpRequest::responseIsXML): A new method that analyses Content-Type.
          (KJS::XMLHttpRequest::slotData): Use a correct charset for responses, see bug for details.
          (KJS::XMLHttpRequestProtoFunc::callAsFunction): Update for getResponseHeader() changes
          * khtml/ecma/xmlhttprequest.h:
  
  Revision  Changes    Path
  1.2       +17 -0     WebCore/ChangeLog
  
  Index: ChangeLog
  ===================================================================
  RCS file: /cvs/root/WebCore/ChangeLog,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ChangeLog	19 Dec 2005 19:16:44 -0000	1.1
  +++ ChangeLog	19 Dec 2005 19:17:32 -0000	1.2
  @@ -1,2 +1,19 @@
  +2005-12-19  Alexey Proskuryakov  <ap at nypop.com>
  +
  +        Reviewed by Darin, committed by Adele.
  +
  +        - fix http://bugzilla.opendarwin.org/show_bug.cgi?id=5744
  +          XMLHttpRequest does not apply page encoding after assigning via innerHtml
  +
  +        * khtml/ecma/xmlhttprequest.cpp:
  +        (getMIMEType): A helper function to get MIME type from a Content-Type string.
  +        (getCharset): A helper function to get charset from a Content-Type string.
  +        (KJS::XMLHttpRequest::getValueProperty): Factored out responseIsXML().
  +        (KJS::XMLHttpRequest::getResponseHeader): Return QString instead of JSValue
  +          (to get rid of unnecessary JSLocks).
  +        (KJS::XMLHttpRequest::responseIsXML): A new method that analyses Content-Type.
  +        (KJS::XMLHttpRequest::slotData): Use a correct charset for responses, see bug for details.
  +        (KJS::XMLHttpRequestProtoFunc::callAsFunction): Update for getResponseHeader() changes
  +        * khtml/ecma/xmlhttprequest.h:
   
   == Rolled over to ChangeLog-2005-12-19 ==
  
  
  
  1.53      +83 -32    WebCore/khtml/ecma/xmlhttprequest.cpp
  
  Index: xmlhttprequest.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/ecma/xmlhttprequest.cpp,v
  retrieving revision 1.52
  retrieving revision 1.53
  diff -u -r1.52 -r1.53
  --- xmlhttprequest.cpp	16 Dec 2005 08:08:14 -0000	1.52
  +++ xmlhttprequest.cpp	19 Dec 2005 19:17:32 -0000	1.53
  @@ -49,6 +49,50 @@
   
   using khtml::Decoder;
   
  +static inline QString getMIMEType(const QString& contentTypeString)
  +{
  +    return QStringList::split(";", contentTypeString, true)[0].stripWhiteSpace();
  +}
  +
  +static QString getCharset(const QString& contentTypeString)
  +{
  +    int pos = 0;
  +    int length = (int)contentTypeString.length();
  +    
  +    while (pos < length) {
  +        pos = contentTypeString.find("charset", pos, false);
  +        if (pos <= 0)
  +            return QString();
  +        
  +        // is what we found a beginning of a word?
  +        if (contentTypeString[pos-1] > ' ' && contentTypeString[pos-1] != ';') {
  +            pos += 7;
  +            continue;
  +        }
  +        
  +        pos += 7;
  +
  +        // skip whitespace
  +        while (pos != length && contentTypeString[pos] <= ' ')
  +            ++pos;
  +    
  +        if (contentTypeString[pos++] != '=') // this "charset" substring wasn't a parameter name, but there may be others
  +            continue;
  +
  +        while (pos != length && (contentTypeString[pos] <= ' ' || contentTypeString[pos] == '"' || contentTypeString[pos] == '\''))
  +            ++pos;
  +
  +        // we don't handle spaces within quoted parameter values, because charset names cannot have any
  +        int endpos = pos;
  +        while (pos != length && contentTypeString[endpos] > ' ' && contentTypeString[endpos] != '"' && contentTypeString[endpos] != '\'' && contentTypeString[endpos] != ';')
  +            ++endpos;
  +    
  +        return contentTypeString.mid(pos, endpos-pos);
  +    }
  +    
  +    return QString();
  +}
  +
   namespace KJS {
   
   ////////////////////// XMLHttpRequest Object ////////////////////////
  @@ -137,21 +181,9 @@
       if (state != Completed) {
         return jsUndefined();
       }
  +
       if (!createdDocument) {
  -      QString mimeType;
  -      
  -      if (MIMETypeOverride.isEmpty()) {
  -        JSValue *header = getResponseHeader("Content-Type");
  -        if (header->isUndefined()) {
  -          mimeType = "text/xml";
  -        } else {
  -	  mimeType = QStringList::split(";", header->toString(exec).qstring(), true)[0].stripWhiteSpace();
  -        }
  -      } else {
  -        mimeType = MIMETypeOverride;
  -      }
  -      
  -      if (typeIsXML = DOMImplementationImpl::isXMLMIMEType(mimeType)) {
  +      if (typeIsXML = responseIsXML()) {
   	responseXML = doc->implementation()->createDocument();
   
   	DocumentImpl *docImpl = responseXML.get();
  @@ -422,11 +454,10 @@
     return jsString(responseHeaders.mid(endOfLine + 1) + "\n");
   }
   
  -JSValue *XMLHttpRequest::getResponseHeader(const QString& name) const
  +QString XMLHttpRequest::getResponseHeader(const QString& name) const
   {
  -  if (responseHeaders.isEmpty()) {
  -    return jsUndefined();
  -  }
  +  if (responseHeaders.isEmpty())
  +    return QString();
   
     QRegExp headerLinePattern(name + ":", false);
   
  @@ -440,14 +471,23 @@
       headerLinePos = headerLinePattern.match(responseHeaders, headerLinePos + 1, &matchLength);
     }
   
  -
  -  if (headerLinePos == -1) {
  -    return jsUndefined();
  -  }
  +  if (headerLinePos == -1)
  +    return QString();
       
     int endOfLine = responseHeaders.find("\n", headerLinePos + matchLength);
  +  
  +  return responseHeaders.mid(headerLinePos + matchLength, endOfLine - (headerLinePos + matchLength)).stripWhiteSpace();
  +}
   
  -  return jsString(responseHeaders.mid(headerLinePos + matchLength, endOfLine - (headerLinePos + matchLength)).stripWhiteSpace());
  +bool XMLHttpRequest::responseIsXML() const
  +{
  +    QString mimeType = getMIMEType(MIMETypeOverride);
  +    if (mimeType.isEmpty())
  +        mimeType = getMIMEType(getResponseHeader("Content-Type"));
  +    if (mimeType.isEmpty())
  +      mimeType = "text/xml";
  +    
  +    return DOMImplementationImpl::isXMLMIMEType(mimeType);
   }
   
   JSValue *XMLHttpRequest::getStatus() const
  @@ -548,21 +588,27 @@
     }
   }
   
  -void XMLHttpRequest::slotData( KIO::Job*, const char *data, int len )
  +void XMLHttpRequest::slotData(KIO::Job*, const char *data, int len)
   {
  -  if (state < Loaded) {
  +  if (responseHeaders.isEmpty() && job)
       responseHeaders = job->queryMetaData("HTTP-Headers");
  -    encoding = job->queryMetaData("charset");
  +
  +  if (state < Loaded)
       changeState(Loaded);
  -  }
     
  -
  -  if ( decoder == NULL ) {
  +  if (decoder == NULL) {
  +    encoding = getCharset(MIMETypeOverride);
  +    if (encoding.isEmpty())
  +      encoding = getCharset(getResponseHeader("Content-Type"));
  +    if (encoding.isEmpty() && job)
  +      encoding = job->queryMetaData("charset");
  +    
       decoder = new Decoder;
  -    if (!encoding.isNull())
  +    if (!encoding.isEmpty())
         decoder->setEncoding(encoding.latin1(), Decoder::EncodingFromHTTPHeader);
       else {
  -      // FIXME: Inherit the default encoding from the parent document?
  +      // only allow Decoder to look inside the response if it's XML
  +      decoder->setEncoding("UTF-8", responseIsXML() ? Decoder::DefaultEncoding : Decoder::EncodingFromHTTPHeader);
       }
     }
     if (len == 0)
  @@ -647,8 +693,13 @@
       if (args.size() != 1) {
         return jsUndefined();
       }
  +    
  +    QString header = request->getResponseHeader(args[0]->toString(exec).qstring());
  +
  +    if (header.isNull())
  +      return jsUndefined();
   
  -    return request->getResponseHeader(args[0]->toString(exec).qstring());
  +    return jsString(header);
     }
     case XMLHttpRequest::Open:
       {
  
  
  
  1.24      +8 -7      WebCore/khtml/ecma/xmlhttprequest.h
  
  Index: xmlhttprequest.h
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/ecma/xmlhttprequest.h,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- xmlhttprequest.h	11 Dec 2005 02:06:08 -0000	1.23
  +++ xmlhttprequest.h	19 Dec 2005 19:17:32 -0000	1.24
  @@ -44,11 +44,11 @@
   
     // these exact numeric values are important because JS expects them
     enum XMLHttpRequestState {
  -    Uninitialized = 0,
  -    Loading = 1,
  -    Loaded = 2,
  -    Interactive = 3,
  -    Completed = 4
  +    Uninitialized = 0,  // open() has not been called yet
  +    Loading = 1,        // send() has not been called yet
  +    Loaded = 2,         // send() has been called, headers and status are available
  +    Interactive = 3,    // Downloading, responseText holds the partial data
  +    Completed = 4       // Finished with all operations
     };
   
     class XMLHttpRequestConstructorImp : public JSObject {
  @@ -101,8 +101,9 @@
       void abort();
       void setRequestHeader(const QString& name, const QString &value);
       JSValue *getAllResponseHeaders() const;
  -    JSValue *getResponseHeader(const QString& name) const;
  -
  +    QString getResponseHeader(const QString& name) const;
  +    bool responseIsXML() const;
  +    
       void changeState(XMLHttpRequestState newState);
   
       static QPtrDict< QPtrDict<XMLHttpRequest> > &requestsByDocument();
  
  
  



More information about the webkit-changes mailing list