“use strict”; const cssom = require(“cssom”); const whatwgEncoding = require(“whatwg-encoding”); const whatwgURL = require(“whatwg-url”); const resourceLoader = require(“../../browser/resource-loader”);

exports.fetchStylesheet = (elementImpl, urlString, sheet) => {

const parsedURL = whatwgURL.parseURL(urlString);
return fetchStylesheetInternal(elementImpl, urlString, parsedURL, sheet);

};

exports.evaluateStylesheet = (elementImpl, data, sheet, baseURL) => {

let newStyleSheet;
try {
  newStyleSheet = cssom.parse(data);
} catch (e) {
  if (elementImpl._ownerDocument._defaultView) {
    const error = new Error("Could not parse CSS stylesheet");
    error.detail = data;
    error.type = "css parsing";

    elementImpl._ownerDocument._defaultView._virtualConsole.emit("jsdomError", error);
  }

  elementImpl._ownerDocument.styleSheets.push(sheet);
  return;
}

const spliceArgs = newStyleSheet.cssRules;
spliceArgs.unshift(0, sheet.cssRules.length);
Array.prototype.splice.apply(sheet.cssRules, spliceArgs);

scanForImportRules(elementImpl, sheet.cssRules, baseURL);

elementImpl._ownerDocument.styleSheets.push(sheet);

};

function fetchStylesheetInternal(elementImpl, urlString, parsedURL, sheet) {

let defaultEncoding = elementImpl._ownerDocument._encoding;
if (elementImpl.localName === "link" && elementImpl.hasAttribute("charset")) {
  defaultEncoding = whatwgEncoding.labelToName(elementImpl.getAttribute("charset"));
}

resourceLoader.load(elementImpl, urlString, { defaultEncoding }, data => {
  // TODO: MIME type checking?
  exports.evaluateStylesheet(elementImpl, data, sheet, parsedURL);
});

}

function scanForImportRules(elementImpl, cssRules, baseURL) {

if (!cssRules) {
  return;
}

for (let i = 0; i < cssRules.length; ++i) {
  if (cssRules[i].cssRules) {
    // @media rule: keep searching inside it.
    scanForImportRules(elementImpl, cssRules[i].cssRules, baseURL);
  } else if (cssRules[i].href) {
    // @import rule: fetch the resource and evaluate it.
    // See http://dev.w3.org/csswg/cssom/#css-import-rule
    //     If loading of the style sheet fails its cssRules list is simply
    //     empty. I.e. an @import rule always has an associated style sheet.
    const parsed = whatwgURL.parseURL(cssRules[i].href, { baseURL });
    if (parsed === "failure") {
      const window = elementImpl._ownerDocument._defaultView;
      if (window) {
        const error = new Error(`Could not parse CSS @import URL ${cssRules[i].href} relative to base URL ` +
                                `"${whatwgURL.serializeURL(baseURL)}"`);
        error.type = "css @import URL parsing";
        window._virtualConsole.emit("jsdomError", error);
      }
    } else {
      fetchStylesheetInternal(elementImpl, whatwgURL.serializeURL(parsed), parsed, elementImpl.sheet);
    }
  }
}

}