nsresult
nsXBLPrototypeResources::FlushSkinSheets()
{
    if (mStyleSheetList.Count() == 0)
        return NS_OK;

    nsresult rv;
    // XXXbz should be getting loader off the document or something
    nsCOMPtr<nsICSSLoader> loader = do_CreateInstance(kCSSLoaderCID, &rv);
    if (NS_FAILED(rv)) return rv;

    // We have scoped stylesheets.  Reload any chrome stylesheets we
    // encounter.  (If they aren't skin sheets, it doesn't matter, since
    // they'll still be in the chrome cache.
    mRuleProcessor = nsnull;

    nsCOMArray<nsICSSStyleSheet> oldSheets(mStyleSheetList);
    mStyleSheetList.Clear();

    PRInt32 i;
    PRInt32 count = oldSheets.Count();
    for (i = 0; i < count; i++) {
        nsICSSStyleSheet* oldSheet = oldSheets[i];

        nsCOMPtr<nsIURI> uri;
        oldSheet->GetSheetURI(getter_AddRefs(uri));

        nsCOMPtr<nsICSSStyleSheet> newSheet;
        if (IsChromeURI(uri)) {
            if (NS_FAILED(loader->LoadSheetSync(uri, getter_AddRefs(newSheet))))
                continue;
        }
        else {
            newSheet = oldSheet;
        }

        mStyleSheetList.AppendObject(newSheet);
    }
    mRuleProcessor = new nsCSSRuleProcessor(mStyleSheetList);

    return NS_OK;
}
nsresult
nsXBLPrototypeResources::FlushSkinSheets()
{
  if (mStyleSheetList.Length() == 0)
    return NS_OK;

  nsCOMPtr<nsIDocument> doc =
    mLoader->mBinding->XBLDocumentInfo()->GetDocument();
  mozilla::css::Loader* cssLoader = doc->CSSLoader();

  // We have scoped stylesheets.  Reload any chrome stylesheets we
  // encounter.  (If they aren't skin sheets, it doesn't matter, since
  // they'll still be in the chrome cache.
  mRuleProcessor = nsnull;

  sheet_array_type oldSheets(mStyleSheetList);
  mStyleSheetList.Clear();

  for (sheet_array_type::size_type i = 0, count = oldSheets.Length();
       i < count; ++i) {
    nsCSSStyleSheet* oldSheet = oldSheets[i];

    nsIURI* uri = oldSheet->GetSheetURI();

    nsRefPtr<nsCSSStyleSheet> newSheet;
    if (IsChromeURI(uri)) {
      if (NS_FAILED(cssLoader->LoadSheetSync(uri, getter_AddRefs(newSheet))))
        continue;
    }
    else {
      newSheet = oldSheet;
    }

    mStyleSheetList.AppendElement(newSheet);
  }
  mRuleProcessor = new nsCSSRuleProcessor(mStyleSheetList, 
                                          nsStyleSet::eDocSheet);

  return NS_OK;
}
// XXXbsmedberg: move this to windowmediator
nsresult nsChromeRegistry::RefreshWindow(nsIDOMWindowInternal* aWindow)
{
    // Deal with our subframes first.
    nsCOMPtr<nsIDOMWindowCollection> frames;
    aWindow->GetFrames(getter_AddRefs(frames));
    PRUint32 length;
    frames->GetLength(&length);
    PRUint32 j;
    for (j = 0; j < length; j++) {
        nsCOMPtr<nsIDOMWindow> childWin;
        frames->Item(j, getter_AddRefs(childWin));
        nsCOMPtr<nsIDOMWindowInternal> childInt(do_QueryInterface(childWin));
        RefreshWindow(childInt);
    }

    nsresult rv;
    // Get the DOM document.
    nsCOMPtr<nsIDOMDocument> domDocument;
    aWindow->GetDocument(getter_AddRefs(domDocument));
    if (!domDocument)
        return NS_OK;

    nsCOMPtr<nsIDocument> document = do_QueryInterface(domDocument);
    if (!document)
        return NS_OK;

    // Deal with the agent sheets first.  Have to do all the style sets by hand.
    nsCOMPtr<nsIPresShell> shell = document->GetShell();
    if (shell) {
        // Reload only the chrome URL agent style sheets.
        nsCOMArray<nsIStyleSheet> agentSheets;
        rv = shell->GetAgentStyleSheets(agentSheets);
        NS_ENSURE_SUCCESS(rv, rv);

        nsCOMArray<nsIStyleSheet> newAgentSheets;
        for (PRInt32 l = 0; l < agentSheets.Count(); ++l) {
            nsIStyleSheet *sheet = agentSheets[l];

            nsIURI* uri = sheet->GetSheetURI();

            if (IsChromeURI(uri)) {
                // Reload the sheet.
                nsRefPtr<nsCSSStyleSheet> newSheet;
                rv = document->LoadChromeSheetSync(uri, PR_TRUE,
                                                   getter_AddRefs(newSheet));
                if (NS_FAILED(rv)) return rv;
                if (newSheet) {
                    rv = newAgentSheets.AppendObject(newSheet) ? NS_OK : NS_ERROR_FAILURE;
                    if (NS_FAILED(rv)) return rv;
                }
            }
            else {  // Just use the same sheet.
                rv = newAgentSheets.AppendObject(sheet) ? NS_OK : NS_ERROR_FAILURE;
                if (NS_FAILED(rv)) return rv;
            }
        }

        rv = shell->SetAgentStyleSheets(newAgentSheets);
        NS_ENSURE_SUCCESS(rv, rv);
    }

    // Build an array of nsIURIs of style sheets we need to load.
    nsCOMArray<nsIStyleSheet> oldSheets;
    nsCOMArray<nsIStyleSheet> newSheets;

    PRInt32 count = document->GetNumberOfStyleSheets();

    // Iterate over the style sheets.
    PRInt32 i;
    for (i = 0; i < count; i++) {
        // Get the style sheet
        nsIStyleSheet *styleSheet = document->GetStyleSheetAt(i);

        if (!oldSheets.AppendObject(styleSheet)) {
            return NS_ERROR_OUT_OF_MEMORY;
        }
    }

    // Iterate over our old sheets and kick off a sync load of the new
    // sheet if and only if it's a chrome URL.
    for (i = 0; i < count; i++) {
        nsRefPtr<nsCSSStyleSheet> sheet = do_QueryObject(oldSheets[i]);
        nsIURI* uri = sheet ? sheet->GetOriginalURI() : nsnull;

        if (uri && IsChromeURI(uri)) {
            // Reload the sheet.
            nsRefPtr<nsCSSStyleSheet> newSheet;
            // XXX what about chrome sheets that have a title or are disabled?  This
            // only works by sheer dumb luck.
            document->LoadChromeSheetSync(uri, PR_FALSE, getter_AddRefs(newSheet));
            // Even if it's null, we put in in there.
            newSheets.AppendObject(newSheet);
        }
        else {
            // Just use the same sheet.
            newSheets.AppendObject(sheet);
        }
    }

    // Now notify the document that multiple sheets have been added and removed.
    document->UpdateStyleSheets(oldSheets, newSheets);
    return NS_OK;
}