コード例 #1
0
nsresult
nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument *aOldDocument,
                                       nsICSSLoaderObserver* aObserver,
                                       bool* aWillNotify,
                                       bool* aIsAlternate,
                                       bool aForceUpdate)
{
  *aWillNotify = false;

  if (mStyleSheet && aOldDocument) {
    // We're removing the link element from the document, unload the
    // stylesheet.  We want to do this even if updates are disabled, since
    // otherwise a sheet with a stale linking element pointer will be hanging
    // around -- not good!
    aOldDocument->BeginUpdate(UPDATE_STYLE);
    aOldDocument->RemoveStyleSheet(mStyleSheet);
    aOldDocument->EndUpdate(UPDATE_STYLE);
    nsStyleLinkElement::SetStyleSheet(nullptr);
  }

  nsCOMPtr<nsIContent> thisContent;
  QueryInterface(NS_GET_IID(nsIContent), getter_AddRefs(thisContent));

  NS_ENSURE_TRUE(thisContent, NS_ERROR_FAILURE);

  // When static documents are created, stylesheets are cloned manually.
  if (mDontLoadStyle || !mUpdatesEnabled ||
      thisContent->OwnerDoc()->IsStaticDocument()) {
    return NS_OK;
  }

  nsCOMPtr<nsIDocument> doc = thisContent->GetDocument();

  if (!doc || !doc->CSSLoader()->GetEnabled()) {
    return NS_OK;
  }

  bool isInline;
  nsCOMPtr<nsIURI> uri = GetStyleSheetURL(&isInline);

  if (!aForceUpdate && mStyleSheet && !isInline && uri) {
    nsIURI* oldURI = mStyleSheet->GetSheetURI();
    if (oldURI) {
      bool equal;
      nsresult rv = oldURI->Equals(uri, &equal);
      if (NS_SUCCEEDED(rv) && equal) {
        return NS_OK; // We already loaded this stylesheet
      }
    }
  }

  if (mStyleSheet) {
    doc->BeginUpdate(UPDATE_STYLE);
    doc->RemoveStyleSheet(mStyleSheet);
    doc->EndUpdate(UPDATE_STYLE);
    nsStyleLinkElement::SetStyleSheet(nullptr);
  }

  if (!uri && !isInline) {
    return NS_OK; // If href is empty and this is not inline style then just bail
  }

  nsAutoString title, type, media;
  bool isAlternate;

  GetStyleSheetInfo(title, type, media, &isAlternate);

  if (!type.LowerCaseEqualsLiteral("text/css")) {
    return NS_OK;
  }

  bool doneLoading = false;
  nsresult rv = NS_OK;
  if (isInline) {
    nsAutoString text;
    nsContentUtils::GetNodeTextContent(thisContent, false, text);

    // Parse the style sheet.
    rv = doc->CSSLoader()->
      LoadInlineStyle(thisContent, text, mLineNumber, title, media,
                      aObserver, &doneLoading, &isAlternate);
  }
  else {
    // XXXbz clone the URI here to work around content policies modifying URIs.
    nsCOMPtr<nsIURI> clonedURI;
    uri->Clone(getter_AddRefs(clonedURI));
    NS_ENSURE_TRUE(clonedURI, NS_ERROR_OUT_OF_MEMORY);
    rv = doc->CSSLoader()->
      LoadStyleLink(thisContent, clonedURI, title, media, isAlternate,
                    GetCORSMode(), aObserver, &isAlternate);
    if (NS_FAILED(rv)) {
      // Don't propagate LoadStyleLink() errors further than this, since some
      // consumers (e.g. nsXMLContentSink) will completely abort on innocuous
      // things like a stylesheet load being blocked by the security system.
      doneLoading = true;
      isAlternate = false;
      rv = NS_OK;
    }
  }

  NS_ENSURE_SUCCESS(rv, rv);

  *aWillNotify = !doneLoading;
  *aIsAlternate = isAlternate;

  return NS_OK;
}
コード例 #2
0
NS_IMETHODIMP
nsStyleLinkElement::UpdateStyleSheet(nsIDocument *aOldDocument,
                                     nsICSSLoaderObserver* aObserver)
{
  if (mStyleSheet && aOldDocument) {
    // We're removing the link element from the document, unload the
    // stylesheet.  We want to do this even if updates are disabled, since
    // otherwise a sheet with a stale linking element pointer will be hanging
    // around -- not good!
    aOldDocument->BeginUpdate(UPDATE_STYLE);
    aOldDocument->RemoveStyleSheet(mStyleSheet);
    aOldDocument->EndUpdate(UPDATE_STYLE);
    nsStyleLinkElement::SetStyleSheet(nsnull);
  }

  if (mDontLoadStyle || !mUpdatesEnabled) {
    return NS_OK;
  }

  // Keep a strong ref to the parser so it's still around when we pass it
  // to the CSS loader. Release strong ref in mParser so we don't hang on
  // to the parser once we start the load or if we fail to load the
  // stylesheet.
  nsCOMPtr<nsIParser> parser = mParser;
  mParser = nsnull;

  nsCOMPtr<nsIContent> thisContent;
  QueryInterface(NS_GET_IID(nsIContent), getter_AddRefs(thisContent));

  NS_ENSURE_TRUE(thisContent, NS_ERROR_FAILURE);

  nsCOMPtr<nsIDocument> doc = thisContent->GetDocument();

  if (!doc) {
    return NS_OK;
  }

  nsCOMPtr<nsIURI> uri;
  PRBool isInline;
  GetStyleSheetURL(&isInline, getter_AddRefs(uri));

  if (mStyleSheet && !isInline && uri) {
    nsCOMPtr<nsIURI> oldURI;

    mStyleSheet->GetSheetURI(getter_AddRefs(oldURI));
    if (oldURI) {
      PRBool equal;
      nsresult rv = oldURI->Equals(uri, &equal);
      if (NS_SUCCEEDED(rv) && equal) {
        return NS_OK; // We already loaded this stylesheet
      }
    }
  }

  if (mStyleSheet) {
    doc->BeginUpdate(UPDATE_STYLE);
    doc->RemoveStyleSheet(mStyleSheet);
    doc->EndUpdate(UPDATE_STYLE);
    nsStyleLinkElement::SetStyleSheet(nsnull);
  }

  if (!uri && !isInline) {
    return NS_OK; // If href is empty and this is not inline style then just bail
  }

  nsAutoString title, type, media;
  PRBool isAlternate;

  GetStyleSheetInfo(title, type, media, &isAlternate);

  if (!type.LowerCaseEqualsLiteral("text/css")) {
    return NS_OK;
  }

  PRBool blockParser = kBlockByDefault;
  if (isAlternate) {
    blockParser = PR_FALSE;
  }

  /* NOTE: no longer honoring the important keyword to indicate blocking
           as it is proprietary and unnecessary since all non-alternate 
           will block the parser now  -mja
    if (-1 != linkTypes.IndexOf("important")) {
      blockParser = PR_TRUE;
    }
  */

  if (!isAlternate && !title.IsEmpty()) {  // possibly preferred sheet
    nsAutoString prefStyle;
    doc->GetHeaderData(nsHTMLAtoms::headerDefaultStyle, prefStyle);

    if (prefStyle.IsEmpty()) {
      doc->SetHeaderData(nsHTMLAtoms::headerDefaultStyle, title);
    }
  }

  PRBool doneLoading;
  nsresult rv = NS_OK;
  if (isInline) {
    PRUint32 count = thisContent->GetChildCount();

    nsAutoString content;

    PRUint32 i;
    for (i = 0; i < count; ++i) {
      nsIContent *node = thisContent->GetChildAt(i);
      nsCOMPtr<nsIDOMText> tc = do_QueryInterface(node);
      // Ignore nodes that are not DOMText.
      if (!tc) {
        nsCOMPtr<nsIDOMComment> comment = do_QueryInterface(node);
        if (comment)
          // Skip a comment
          continue;
        break;
      }

      nsAutoString tcString;
      tc->GetData(tcString);
      content.Append(tcString);
    }

    // Use of the stream will be done before parsing returns.  So it will go
    // out of scope before |content| does.
    nsCOMPtr<nsIUnicharInputStream> uin;
    rv = NS_NewStringUnicharInputStream(getter_AddRefs(uin), &content,
                                        PR_FALSE);
    if (NS_FAILED(rv)) {
      return rv;
    }

    // Now that we have a url and a unicode input stream, parse the
    // style sheet.
    rv = doc->CSSLoader()->
      LoadInlineStyle(thisContent, uin, mLineNumber, title, media,
                      ((blockParser) ? parser.get() : nsnull),
                      doneLoading, aObserver);
  }
  else {
    rv = doc->CSSLoader()->
      LoadStyleLink(thisContent, uri, title, media,
                    ((blockParser) ? parser.get() : nsnull),
                    doneLoading, aObserver);
  }

  if (NS_SUCCEEDED(rv) && blockParser && !doneLoading) {
    rv = NS_ERROR_HTMLPARSER_BLOCK;
  }

  return rv;
}
コード例 #3
0
nsresult
nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument *aOldDocument,
                                       nsICSSLoaderObserver* aObserver,
                                       PRBool* aWillNotify,
                                       PRBool* aIsAlternate,
                                       PRBool aForceUpdate)
{
  *aWillNotify = PR_FALSE;

  if (mStyleSheet && aOldDocument) {
    // We're removing the link element from the document, unload the
    // stylesheet.  We want to do this even if updates are disabled, since
    // otherwise a sheet with a stale linking element pointer will be hanging
    // around -- not good!
    aOldDocument->BeginUpdate(UPDATE_STYLE);
    aOldDocument->RemoveStyleSheet(mStyleSheet);
    aOldDocument->EndUpdate(UPDATE_STYLE);
    mStyleSheet = nsnull;
  }

  if (mDontLoadStyle || !mUpdatesEnabled) {
    return NS_OK;
  }

  nsCOMPtr<nsIContent> thisContent;
  QueryInterface(NS_GET_IID(nsIContent), getter_AddRefs(thisContent));

  NS_ENSURE_TRUE(thisContent, NS_ERROR_FAILURE);

  nsCOMPtr<nsIDocument> doc = thisContent->GetDocument();

  if (!doc) {
    return NS_OK;
  }

  PRBool enabled = PR_FALSE;
  doc->CSSLoader()->GetEnabled(&enabled);
  if (!enabled) {
    return NS_OK;
  }

  nsCOMPtr<nsIURI> uri;
  PRBool isInline;
  GetStyleSheetURL(&isInline, getter_AddRefs(uri));

  if (!aForceUpdate && mStyleSheet && !isInline && uri) {
    nsCOMPtr<nsIURI> oldURI;

    mStyleSheet->GetSheetURI(getter_AddRefs(oldURI));
    if (oldURI) {
      PRBool equal;
      nsresult rv = oldURI->Equals(uri, &equal);
      if (NS_SUCCEEDED(rv) && equal) {
        return NS_OK; // We already loaded this stylesheet
      }
    }
  }

  if (mStyleSheet) {
    doc->BeginUpdate(UPDATE_STYLE);
    doc->RemoveStyleSheet(mStyleSheet);
    doc->EndUpdate(UPDATE_STYLE);
    mStyleSheet = nsnull;
  }

  if (!uri && !isInline) {
    return NS_OK; // If href is empty and this is not inline style then just bail
  }

  nsAutoString title, type, media;
  PRBool isAlternate;

  GetStyleSheetInfo(title, type, media, &isAlternate);

  if (!type.LowerCaseEqualsLiteral("text/css")) {
    return NS_OK;
  }

  PRBool doneLoading = PR_FALSE;
  nsresult rv = NS_OK;
  if (isInline) {
    nsAutoString content;
    nsContentUtils::GetNodeTextContent(thisContent, PR_FALSE, content);

    nsCOMPtr<nsIUnicharInputStream> uin;
    rv = nsSimpleUnicharStreamFactory::GetInstance()->
      CreateInstanceFromString(content, getter_AddRefs(uin));
    if (NS_FAILED(rv)) {
      return rv;
    }

    // Now that we have a url and a unicode input stream, parse the
    // style sheet.
    rv = doc->CSSLoader()->
      LoadInlineStyle(thisContent, uin, mLineNumber, title, media,
                      aObserver, &doneLoading, &isAlternate);
  }
  else {
    rv = doc->CSSLoader()->
      LoadStyleLink(thisContent, uri, title, media, isAlternate, aObserver,
                    &isAlternate);
    if (rv == NS_ERROR_FILE_NOT_FOUND) {
      doneLoading = PR_TRUE;
      rv = NS_OK;
    }
  }

  NS_ENSURE_SUCCESS(rv, rv);

  *aWillNotify = !doneLoading;
  *aIsAlternate = isAlternate;

  return NS_OK;
}