Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Static Public Member Functions | Public Attributes | Protected Member Functions | Protected Attributes
nsScriptLoader Class Reference

#include <nsScriptLoader.h>

Inheritance diagram for nsScriptLoader:
Inheritance graph
[legend]
Collaboration diagram for nsScriptLoader:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 nsScriptLoader ()
virtual ~nsScriptLoader ()
void AddExecuteBlocker ()
 Add/remove blocker.
void RemoveExecuteBlocker ()
void ProcessPendingReqests ()
void init (in nsIDocument aDocument)
 Initialize loader with a document.
void dropDocumentReference ()
 The loader maintains a strong reference to the document with which it is initialized.
void addObserver (in nsIScriptLoaderObserver aObserver)
 Add an observer for all scripts loaded through this loader.
void removeObserver (in nsIScriptLoaderObserver aObserver)
 Remove an observer.
void processScriptElement (in nsIScriptElement aElement, in nsIScriptLoaderObserver aObserver)
 Process a script element.
nsIScriptElement getCurrentScript ()
 Gets the currently executing script.
void onStreamComplete (in nsIStreamLoader loader, in nsISupports ctxt, in nsresult status, in unsigned long resultLength,[const, array, size_is(resultLength)] in octet result)

Static Public Member Functions

NS_DECL_ISUPPORTS
NS_DECL_NSISCRIPTLOADER static
NS_DECL_NSISTREAMLOADEROBSERVER
nsresult 
ConvertToUTF16 (nsIChannel *aChannel, const PRUint8 *aData, PRUint32 aLength, const nsString &aHintCharset, nsIDocument *aDocument, nsString &aString)
 Convert the given buffer to a UTF-16 string.
static PRBool ShouldExecuteScript (nsIDocument *aDocument, nsIChannel *aChannel)
 Check whether it's OK to execute a script loaded via aChannel in aDocument.

Public Attributes

attribute boolean enabled
 Whether the loader is enabled or not.

Protected Member Functions

PRBool InNonScriptingContainer (nsIScriptElement *aScriptElement)
PRBool IsScriptEventHandler (nsIScriptElement *aScriptElement)
void FireErrorNotification (nsresult aResult, nsIScriptElement *aElement, nsIScriptLoaderObserver *aObserver)
nsresult ProcessRequest (nsScriptLoadRequest *aRequest)
void FireScriptAvailable (nsresult aResult, nsScriptLoadRequest *aRequest, const nsAFlatString &aScript)
void FireScriptEvaluated (nsresult aResult, nsScriptLoadRequest *aRequest)
nsresult EvaluateScript (nsScriptLoadRequest *aRequest, const nsAFlatString &aScript)
virtual void ProcessPendingRequestsAsync ()
nsresult DoProcessScriptElement (nsIScriptElement *aElement, nsIScriptLoaderObserver *aObserver, PRBool *aFireErrorNotification)

Protected Attributes

nsIDocumentmDocument
nsCOMArray
< nsIScriptLoaderObserver
mObservers
nsCOMArray< nsScriptLoadRequestmPendingRequests
nsCOMPtr< nsIScriptElementmCurrentScript
PRBool mEnabled
PRBool mHadPendingScripts
PRUint32 mBlockerCount

Detailed Description

Definition at line 57 of file nsScriptLoader.h.


Constructor & Destructor Documentation

Definition at line 185 of file nsScriptLoader.cpp.

Here is the call graph for this function:


Member Function Documentation

Add/remove blocker.

Blockers will stop scripts from executing, but not from loading. NOTE! Calling RemoveExecuteBlocker could potentially execute pending scripts synchronously. In other words, it should not be done at 'unsafe' times

Definition at line 91 of file nsScriptLoader.h.

Here is the call graph for this function:

Add an observer for all scripts loaded through this loader.

Parameters:
aObserverobserver for all script processing.
nsresult nsScriptLoader::ConvertToUTF16 ( nsIChannel aChannel,
const PRUint8 aData,
PRUint32  aLength,
const nsString aHintCharset,
nsIDocument aDocument,
nsString aString 
) [static]

Convert the given buffer to a UTF-16 string.

Parameters:
aChannelChannel corresponding to the data. May be null.
aDataThe data to convert
aLengthLength of the data
aHintCharsetHint for the character set (e.g., from a charset attribute). May be the empty string.
aDocumentDocument which the data is loaded for. Must not be null.
aString[out] Data as converted to unicode

Definition at line 867 of file nsScriptLoader.cpp.

{
  if (!aLength) {
    aString.Truncate();
    return NS_OK;
  }

  nsCAutoString characterSet;

  nsresult rv = NS_OK;
  if (aChannel) {
    rv = aChannel->GetContentCharset(characterSet);
  }

  if (!aHintCharset.IsEmpty() && (NS_FAILED(rv) || characterSet.IsEmpty())) {
    // charset name is always ASCII.
    LossyCopyUTF16toASCII(aHintCharset, characterSet);
  }

  if (NS_FAILED(rv) || characterSet.IsEmpty()) {
    DetectByteOrderMark(aData, aLength, characterSet);
  }

  if (characterSet.IsEmpty()) {
    // charset from document default
    characterSet = aDocument->GetDocumentCharacterSet();
  }

  if (characterSet.IsEmpty()) {
    // fall back to ISO-8859-1, see bug 118404
    characterSet.AssignLiteral("ISO-8859-1");
  }

  nsCOMPtr<nsICharsetConverterManager> charsetConv =
    do_GetService(kCharsetConverterManagerCID, &rv);

  nsCOMPtr<nsIUnicodeDecoder> unicodeDecoder;

  if (NS_SUCCEEDED(rv) && charsetConv) {
    rv = charsetConv->GetUnicodeDecoder(characterSet.get(),
                                        getter_AddRefs(unicodeDecoder));
    if (NS_FAILED(rv)) {
      // fall back to ISO-8859-1 if charset is not supported. (bug 230104)
      rv = charsetConv->GetUnicodeDecoderRaw("ISO-8859-1",
                                             getter_AddRefs(unicodeDecoder));
    }
  }

  // converts from the charset to unicode
  if (NS_SUCCEEDED(rv)) {
    PRInt32 unicodeLength = 0;

    rv = unicodeDecoder->GetMaxLength(NS_REINTERPRET_CAST(const char*, aData),
                                      aLength, &unicodeLength);
    if (NS_SUCCEEDED(rv)) {
      if (!EnsureStringLength(aString, unicodeLength))
        return NS_ERROR_OUT_OF_MEMORY;

      PRUnichar *ustr = aString.BeginWriting();

      PRInt32 consumedLength = 0;
      PRInt32 originalLength = aLength;
      PRInt32 convertedLength = 0;
      PRInt32 bufferLength = unicodeLength;
      do {
        rv = unicodeDecoder->Convert(NS_REINTERPRET_CAST(const char*, aData),
                                     (PRInt32 *) &aLength, ustr,
                                     &unicodeLength);
        if (NS_FAILED(rv)) {
          // if we failed, we consume one byte, replace it with U+FFFD
          // and try the conversion again.
          ustr[unicodeLength++] = (PRUnichar)0xFFFD;
          ustr += unicodeLength;

          unicodeDecoder->Reset();
        }
        aData += ++aLength;
        consumedLength += aLength;
        aLength = originalLength - consumedLength;
        convertedLength += unicodeLength;
        unicodeLength = bufferLength - convertedLength;
      } while (NS_FAILED(rv) && (originalLength > consumedLength) && (bufferLength > convertedLength));
      aString.SetLength(convertedLength);
    }
  }
  return rv;
}

Here is the call graph for this function:

nsresult nsScriptLoader::DoProcessScriptElement ( nsIScriptElement aElement,
nsIScriptLoaderObserver aObserver,
PRBool aFireErrorNotification 
) [protected]

Definition at line 370 of file nsScriptLoader.cpp.

{
  // Default to firing the error notification until we've actually gotten to
  // loading or running the script.
  *aFireErrorNotification = PR_TRUE;
  
  NS_ENSURE_ARG(aElement);

  // We need a document to evaluate scripts.
  NS_ENSURE_TRUE(mDocument, NS_ERROR_FAILURE);

  // Check to see that the element is not in a container that
  // suppresses script evaluation within it and that we should be
  // evaluating scripts for this document in the first place.
  if (!mEnabled || !mDocument->IsScriptEnabled() ||
      InNonScriptingContainer(aElement)) {
    return NS_ERROR_NOT_AVAILABLE;
  }

  // Check that the script is not an eventhandler
  if (IsScriptEventHandler(aElement)) {
    return NS_CONTENT_SCRIPT_IS_EVENTHANDLER;
  }

  // Script evaluation can also be disabled in the current script
  // context even though it's enabled in the document.
  nsIScriptGlobalObject *globalObject = mDocument->GetScriptGlobalObject();
  if (globalObject)
  {
    nsIScriptContext *context = globalObject->GetContext();

    // If scripts aren't enabled in the current context, there's no
    // point in going on.
    if (context && !context->GetScriptsEnabled()) {
      return NS_ERROR_NOT_AVAILABLE;
    }
  }

  PRBool isJavaScript = PR_TRUE;
  PRBool hasE4XOption = PR_FALSE;
  const char* jsVersionString = nsnull;
  nsAutoString language, type, src;

  // "language" is a deprecated attribute of HTML, so we check it only for
  // HTML script elements.
  nsCOMPtr<nsIDOMHTMLScriptElement> htmlScriptElement =
    do_QueryInterface(aElement);
  if (htmlScriptElement) {
    // Check the language attribute first, so type can trump language.
    htmlScriptElement->GetAttribute(NS_LITERAL_STRING("language"), language);
    if (!language.IsEmpty()) {
      isJavaScript = nsParserUtils::IsJavaScriptLanguage(language,
                                                         &jsVersionString);

      // IE, Opera, etc. do not respect language version, so neither should
      // we at this late date in the browser wars saga.  Note that this change
      // affects HTML but not XUL or SVG (but note also that XUL has its own
      // code to check nsParserUtils::IsJavaScriptLanguage -- that's probably
      // a separate bug, one we may not be able to fix short of XUL2).  See
      // bug 255895 (https://bugzilla.mozilla.org/show_bug.cgi?id=255895).
      jsVersionString = ::JS_VersionToString(JSVERSION_DEFAULT);
    }
  }

  nsresult rv = NS_OK;

  // Check the type attribute to determine language and version.
  aElement->GetScriptType(type);
  if (!type.IsEmpty()) {
    nsCOMPtr<nsIMIMEHeaderParam> mimeHdrParser =
      do_GetService("@mozilla.org/network/mime-hdrparam;1");
    NS_ENSURE_TRUE(mimeHdrParser, NS_ERROR_FAILURE);

    NS_ConvertUTF16toUTF8 typeAndParams(type);

    nsAutoString mimeType;
    rv = mimeHdrParser->GetParameter(typeAndParams, nsnull,
                                     EmptyCString(), PR_FALSE, nsnull,
                                     mimeType);
    NS_ENSURE_SUCCESS(rv, rv);

    // Table ordered from most to least likely JS MIME types.
    // See bug 62485, feel free to add <script type="..."> survey data to it,
    // or to a new bug once 62485 is closed.
    static const char *jsTypes[] = {
      "text/javascript",
      "text/ecmascript",
      "application/javascript",
      "application/ecmascript",
      "application/x-javascript",
      nsnull
    };

    isJavaScript = PR_FALSE;
    for (PRInt32 i = 0; jsTypes[i]; i++) {
      if (mimeType.LowerCaseEqualsASCII(jsTypes[i])) {
        isJavaScript = PR_TRUE;
        break;
      }
    }

    if (isJavaScript) {
      JSVersion jsVersion = JSVERSION_DEFAULT;
      nsAutoString value;
      rv = mimeHdrParser->GetParameter(typeAndParams, "version",
                                       EmptyCString(), PR_FALSE, nsnull,
                                       value);
      if (NS_FAILED(rv)) {
        if (rv != NS_ERROR_INVALID_ARG)
          return rv;
      } else {
        if (value.Length() != 3 || value[0] != '1' || value[1] != '.')
          jsVersion = JSVERSION_UNKNOWN;
        else switch (value[2]) {
          case '0': jsVersion = JSVERSION_1_0; break;
          case '1': jsVersion = JSVERSION_1_1; break;
          case '2': jsVersion = JSVERSION_1_2; break;
          case '3': jsVersion = JSVERSION_1_3; break;
          case '4': jsVersion = JSVERSION_1_4; break;
          case '5': jsVersion = JSVERSION_1_5; break;
          case '6': jsVersion = JSVERSION_1_6; break;
          case '7': jsVersion = JSVERSION_1_7; break;
          default:  jsVersion = JSVERSION_UNKNOWN;
        }
      }
      jsVersionString = ::JS_VersionToString(jsVersion);

      rv = mimeHdrParser->GetParameter(typeAndParams, "e4x",
                                       EmptyCString(), PR_FALSE, nsnull,
                                       value);
      if (NS_FAILED(rv)) {
        if (rv != NS_ERROR_INVALID_ARG)
          return rv;
      } else {
        if (value.Length() == 1 && value[0] == '1')
          hasE4XOption = PR_TRUE;
      }
    }
  }

  // If this isn't JavaScript, we don't know how to evaluate.
  // XXX How and where should we deal with other scripting languages?
  //     See bug 255942 (https://bugzilla.mozilla.org/show_bug.cgi?id=255942).
  if (!isJavaScript) {
    return NS_ERROR_NOT_AVAILABLE;
  }

  // Create a request object for this script
  nsRefPtr<nsScriptLoadRequest> request = new nsScriptLoadRequest(aElement, aObserver, jsVersionString, hasE4XOption);
  NS_ENSURE_TRUE(request, NS_ERROR_OUT_OF_MEMORY);

  // First check to see if this is an external script
  nsCOMPtr<nsIURI> scriptURI = aElement->GetScriptURI();
  if (scriptURI) {
    // Check that the containing page is allowed to load this URI.
    nsIPrincipal *docPrincipal = mDocument->GetPrincipal();
    NS_ENSURE_TRUE(docPrincipal, NS_ERROR_UNEXPECTED);
    rv = nsContentUtils::GetSecurityManager()->
      CheckLoadURIWithPrincipal(docPrincipal, scriptURI,
                                nsIScriptSecurityManager::ALLOW_CHROME);

    NS_ENSURE_SUCCESS(rv, rv);

    // After the security manager, the content-policy stuff gets a veto
    if (globalObject) {
      PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
      nsIURI *docURI = mDocument->GetDocumentURI();
      rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_SCRIPT,
                                     scriptURI,
                                     docURI,
                                     aElement,
                                     NS_LossyConvertUCS2toASCII(type),
                                     nsnull,    //extra
                                     &shouldLoad);
      if (NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad)) {
        if (NS_FAILED(rv) || shouldLoad != nsIContentPolicy::REJECT_TYPE) {
          return NS_ERROR_CONTENT_BLOCKED;
        }
        return NS_ERROR_CONTENT_BLOCKED_SHOW_ALT;
      }

      request->mURI = scriptURI;
      request->mIsInline = PR_FALSE;
      request->mWasPending = PR_TRUE;
      request->mLoading = PR_TRUE;

      // Add the request to our pending requests list
      mPendingRequests.AppendObject(request);

      nsCOMPtr<nsILoadGroup> loadGroup = mDocument->GetDocumentLoadGroup();
      nsCOMPtr<nsIStreamLoader> loader;

      nsIDocShell *docshell = globalObject->GetDocShell();

      nsCOMPtr<nsIInterfaceRequestor> prompter(do_QueryInterface(docshell));

      nsCOMPtr<nsIChannel> channel;
      rv = NS_NewChannel(getter_AddRefs(channel),
                         scriptURI, nsnull, loadGroup,
                         prompter, nsIRequest::LOAD_NORMAL);
      if (NS_SUCCEEDED(rv)) {
        nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
        if (httpChannel) {
          // HTTP content negotation has little value in this context.
          httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
                                        NS_LITERAL_CSTRING("*/*"),
                                        PR_FALSE);
          httpChannel->SetReferrer(mDocument->GetDocumentURI());
        }
        rv = NS_NewStreamLoader(getter_AddRefs(loader), channel, this, request);
      }
      if (NS_FAILED(rv)) {
        mPendingRequests.RemoveObject(request);
        return rv;
      }

      // At this point we've successfully started the load, so we need not call
      // FireErrorNotification anymore.
      *aFireErrorNotification = PR_FALSE;
    }
  } else {
    request->mLoading = PR_FALSE;
    request->mIsInline = PR_TRUE;
    request->mURI = mDocument->GetDocumentURI();

    request->mLineNo = aElement->GetScriptLineNumber();

    // If we've got existing pending requests, add ourselves
    // to this list.
    if (mPendingRequests.Count() > 0 || mBlockerCount > 0) {
      request->mWasPending = PR_TRUE;
      NS_ENSURE_TRUE(mPendingRequests.AppendObject(request),
                     NS_ERROR_OUT_OF_MEMORY);
    }
    else {
      request->mWasPending = PR_FALSE;
      rv = ProcessRequest(request);
    }

    // We're either going to, or have run this inline script, so we shouldn't
    // call FireErrorNotification for it.
    *aFireErrorNotification = PR_FALSE;
  }

  return rv;
}

Here is the call graph for this function:

The loader maintains a strong reference to the document with which it is initialized.

This call forces the reference to be dropped.

nsresult nsScriptLoader::EvaluateScript ( nsScriptLoadRequest aRequest,
const nsAFlatString aScript 
) [protected]

Definition at line 719 of file nsScriptLoader.cpp.

{
  nsresult rv = NS_OK;

  // We need a document to evaluate scripts.
  if (!mDocument) {
    return NS_ERROR_FAILURE;
  }

  nsIScriptGlobalObject *globalObject = mDocument->GetScriptGlobalObject();

  nsCOMPtr<nsPIDOMWindow> pwin(do_QueryInterface(globalObject));
  NS_ENSURE_TRUE(pwin && pwin->IsInnerWindow(), NS_ERROR_FAILURE);

  // Make sure context is a strong reference since we access it after
  // we've executed a script, which may cause all other references to
  // the context to go away.
  nsCOMPtr<nsIScriptContext> context = globalObject->GetContext();
  if (!context) {
    return NS_ERROR_FAILURE;
  }

  nsIPrincipal *principal = mDocument->GetPrincipal();
  // We can survive without a principal, but we really should
  // have one.
  NS_ASSERTION(principal, "principal required for document");

  nsCAutoString url;

  if (aRequest->mURI) {
    rv = aRequest->mURI->GetSpec(url);
    if (NS_FAILED(rv)) {
      return rv;
    }
  }

  PRBool oldProcessingScriptTag = context->GetProcessingScriptTag();
  context->SetProcessingScriptTag(PR_TRUE);

  JSContext *cx = (JSContext *)context->GetNativeContext();
  uint32 options = ::JS_GetOptions(cx);
  JSBool changed = (aRequest->mHasE4XOption ^ !!(options & JSOPTION_XML));
  if (changed) {
    ::JS_SetOptions(cx,
                    aRequest->mHasE4XOption
                    ? options | JSOPTION_XML
                    : options & ~JSOPTION_XML);
  }

  // Update our current script.
  nsCOMPtr<nsIScriptElement> oldCurrent = mCurrentScript;
  mCurrentScript = aRequest->mElement;

  PRBool isUndefined;
  rv = context->EvaluateString(aScript, globalObject->GetGlobalJSObject(),
                               principal, url.get(), aRequest->mLineNo,
                               aRequest->mJSVersion, nsnull, &isUndefined);

  // Put the old script back in case it wants to do anything else.
  mCurrentScript = oldCurrent;

  ::JS_ReportPendingException(cx);
  if (changed) {
    ::JS_SetOptions(cx, options);
  }

  context->SetProcessingScriptTag(oldProcessingScriptTag);

  nsCOMPtr<nsIXPCNativeCallContext> ncc;
  nsContentUtils::XPConnect()->
    GetCurrentNativeCallContext(getter_AddRefs(ncc));

  if (ncc) {
    ncc->SetExceptionWasThrown(PR_FALSE);
  }

  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsScriptLoader::FireErrorNotification ( nsresult  aResult,
nsIScriptElement aElement,
nsIScriptLoaderObserver aObserver 
) [protected]

Definition at line 631 of file nsScriptLoader.cpp.

{
  PRInt32 count = mObservers.Count();
  for (PRInt32 i = 0; i < count; i++) {
    nsCOMPtr<nsIScriptLoaderObserver> observer = mObservers[i];

    if (observer) {
      observer->ScriptAvailable(aResult, aElement,
                                PR_TRUE, PR_FALSE,
                                nsnull, 0,
                                EmptyString());
    }
  }

  if (aObserver) {
    aObserver->ScriptAvailable(aResult, aElement,
                               PR_TRUE, PR_FALSE,
                               nsnull, 0,
                               EmptyString());
  }
}

Here is the call graph for this function:

void nsScriptLoader::FireScriptAvailable ( nsresult  aResult,
nsScriptLoadRequest aRequest,
const nsAFlatString aScript 
) [protected]

Definition at line 682 of file nsScriptLoader.cpp.

{
  PRInt32 count = mObservers.Count();
  for (PRInt32 i = 0; i < count; i++) {
    nsCOMPtr<nsIScriptLoaderObserver> observer = mObservers[i];

    if (observer) {
      observer->ScriptAvailable(aResult, aRequest->mElement,
                                aRequest->mIsInline, aRequest->mWasPending,
                                aRequest->mURI, aRequest->mLineNo,
                                aScript);
    }
  }

  aRequest->FireScriptAvailable(aResult, aScript);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsScriptLoader::FireScriptEvaluated ( nsresult  aResult,
nsScriptLoadRequest aRequest 
) [protected]

Definition at line 702 of file nsScriptLoader.cpp.

{
  PRInt32 count = mObservers.Count();
  for (PRInt32 i = 0; i < count; i++) {
    nsCOMPtr<nsIScriptLoaderObserver> observer = mObservers[i];

    if (observer) {
      observer->ScriptEvaluated(aResult, aRequest->mElement,
                                aRequest->mIsInline, aRequest->mWasPending);
    }
  }

  aRequest->FireScriptEvaluated(aResult);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Gets the currently executing script.

This is useful if you want to generate a unique key based on the currently executing script.

void nsIScriptLoader::init ( in nsIDocument  aDocument) [inherited]

Initialize loader with a document.

The container of this document will be used for getting script evaluation information, including the context in which to do the evaluation. The loader maintains a strong reference to the document.

Parameters:
aDocumentThe document to use as the basis for script processing.

Definition at line 250 of file nsScriptLoader.cpp.

{
  nsCOMPtr<nsIDOMNode> node(do_QueryInterface(aScriptElement));
  nsCOMPtr<nsIDOMNode> parent;

  node->GetParentNode(getter_AddRefs(parent));
  while (parent) {
    nsCOMPtr<nsIContent> content(do_QueryInterface(parent));
    if (!content) {
      break;
    }

    nsINodeInfo *nodeInfo = content->GetNodeInfo();
    NS_ASSERTION(nodeInfo, "element without node info");

    if (nodeInfo) {
      nsIAtom *localName = nodeInfo->NameAtom();

      // XXX noframes and noembed are currently unconditionally not
      // displayed and processed. This might change if we support either
      // prefs or per-document container settings for not allowing
      // frames or plugins.
      if (content->IsContentOfType(nsIContent::eHTML) &&
          ((localName == nsHTMLAtoms::iframe) ||
           (localName == nsHTMLAtoms::noframes) ||
           (localName == nsHTMLAtoms::noembed))) {
        return PR_TRUE;
      }
    }

    node = parent;
    node->GetParentNode(getter_AddRefs(parent));
  }

  return PR_FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 296 of file nsScriptLoader.cpp.

{
  nsCOMPtr<nsIContent> contElement = do_QueryInterface(aScriptElement);
  if (!contElement ||
      !contElement->HasAttr(kNameSpaceID_None, nsHTMLAtoms::_event) ||
      !contElement->HasAttr(kNameSpaceID_None, nsHTMLAtoms::_for)) {
      return PR_FALSE;
  }

  nsAutoString str;
  nsresult rv = contElement->GetAttr(kNameSpaceID_None, nsHTMLAtoms::_for,
                                     str);
  NS_ENSURE_SUCCESS(rv, PR_FALSE);

  const nsAString& for_str = nsContentUtils::TrimWhitespace(str);

  if (!for_str.LowerCaseEqualsLiteral("window")) {
    return PR_TRUE;
  }

  // We found for="window", now check for event="onload".

  rv = contElement->GetAttr(kNameSpaceID_None, nsHTMLAtoms::_event, str);
  NS_ENSURE_SUCCESS(rv, PR_FALSE);

  const nsAString& event_str = nsContentUtils::TrimWhitespace(str, PR_FALSE);

  if (event_str.Length() < 6) {
    // String too short, can't be "onload".

    return PR_TRUE;
  }

  if (!StringBeginsWith(event_str, NS_LITERAL_STRING("onload"),
                        nsCaseInsensitiveStringComparator())) {
    // It ain't "onload.*".

    return PR_TRUE;
  }

  nsAutoString::const_iterator start, end;
  event_str.BeginReading(start);
  event_str.EndReading(end);

  start.advance(6); // advance past "onload"

  if (start != end && *start != '(' && *start != ' ') {
    // We got onload followed by something other than space or
    // '('. Not good enough.

    return PR_TRUE;
  }

  return PR_FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsIStreamLoaderObserver::onStreamComplete ( in nsIStreamLoader  loader,
in nsISupports  ctxt,
in nsresult  status,
in unsigned long  resultLength,
[const, array, size_is(resultLength)] in octet  result 
) [inherited]

Definition at line 822 of file nsScriptLoader.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 800 of file nsScriptLoader.cpp.

{
  if (mPendingRequests.Count()) {
    nsCOMPtr<nsIEventQueue> uiThreadQueue;
    NS_GetMainEventQ(getter_AddRefs(uiThreadQueue));
    if (!uiThreadQueue) {
      return;
    }

    PLEvent *evt = new nsScriptLoaderEvent(this);
    if (!evt) {
      return;
    }

    nsresult rv = uiThreadQueue->PostEvent(evt);
    if (NS_FAILED(rv)) {
      PL_DestroyEvent(evt);
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 656 of file nsScriptLoader.cpp.

{
  NS_ENSURE_ARG(aRequest);
  nsAFlatString* script;
  nsAutoString textData;

  // If there's no script text, we try to get it from the element
  if (aRequest->mIsInline) {
    // XXX This is inefficient - GetText makes multiple
    // copies.
    aRequest->mElement->GetScriptText(textData);

    script = &textData;
  }
  else {
    script = &aRequest->mScriptText;
  }

  FireScriptAvailable(NS_OK, aRequest, *script);
  nsresult rv = EvaluateScript(aRequest, *script);
  FireScriptEvaluated(rv, aRequest);

  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Process a script element.

This will include both loading the source of the element if it is not inline and evaluating the script itself.

Parameters:
aElementThe element representing the script to be loaded and evaluated.
aObserverAn observer for this script load only

Definition at line 97 of file nsScriptLoader.h.

  {
    if (!--mBlockerCount) {
      // If there were pending scripts then the newly added scripts will
      // execute once whatever event triggers the pending scripts fires.
      // However, due to synchronous loads and pushed event queues it's
      // possible that the requests that were there have already been processed
      // if so we need to process any new requests asynchronously.
      // Ideally that should be fixed such that it can't happen.
      if (mHadPendingScripts) {
        ProcessPendingRequestsAsync();
      }
      else {
        ProcessPendingReqests();
      }
    }
  }

Here is the call graph for this function:

Remove an observer.

Parameters:
aObserverobserver to be removed
PRBool nsScriptLoader::ShouldExecuteScript ( nsIDocument aDocument,
nsIChannel aChannel 
) [static]

Check whether it's OK to execute a script loaded via aChannel in aDocument.

Definition at line 1093 of file nsScriptLoader.cpp.

{
  if (!aChannel) {
    return PR_FALSE;
  }

  PRBool hasCert;
  nsIPrincipal *docPrincipal = aDocument->GetPrincipal();
  docPrincipal->GetHasCertificate(&hasCert);
  if (!hasCert) {
    return PR_TRUE;
  }

  nsCOMPtr<nsIPrincipal> channelPrincipal;
  nsresult rv = GetChannelPrincipal(aChannel,
                                    getter_AddRefs(channelPrincipal));
  NS_ENSURE_SUCCESS(rv, PR_FALSE);

  NS_ASSERTION(channelPrincipal, "Gotta have a principal here!");

  // If the document principal is a cert principal and is not the same
  // as the channel principal, then we don't execute the script.
  PRBool equal;
  rv = docPrincipal->Equals(channelPrincipal, &equal);
  return NS_SUCCEEDED(rv) && equal;
}

Here is the call graph for this function:


Member Data Documentation

Whether the loader is enabled or not.

When disabled, processing of new script elements is disabled. Any call to processScriptElement() will fail with a return code of NS_ERROR_NOT_AVAILABLE. Note that this DOES NOT disable currently loading or executing scripts.

Definition at line 105 of file nsIScriptLoader.idl.

Definition at line 154 of file nsScriptLoader.h.

Definition at line 151 of file nsScriptLoader.h.

Definition at line 148 of file nsScriptLoader.h.

Definition at line 152 of file nsScriptLoader.h.

Definition at line 153 of file nsScriptLoader.h.

Definition at line 149 of file nsScriptLoader.h.

Definition at line 150 of file nsScriptLoader.h.


The documentation for this class was generated from the following files: