Some checks failed
Tests / Tests (push) Has been cancelled
ESLint Check / ESLint Check and Report Upload (push) Has been cancelled
Prettier Check / Format Check (push) Has been cancelled
Prettier Check / Format Code (push) Has been cancelled
ESLint Check / Build Base for Bundle Size Comparison (push) Has been cancelled
- docs/integration/superrpa-integration.zh_CN.md: complete integration guide - rrweb-simple-ext/: minimal Chrome extension for page recording - replay.html: standalone drag-and-drop replay viewer - CLAUDE.md: project instructions Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
12733 lines
391 KiB
JavaScript
12733 lines
391 KiB
JavaScript
(function (g, f) {
|
|
if ("object" == typeof exports && "object" == typeof module) {
|
|
module.exports = f();
|
|
} else if ("function" == typeof define && define.amd) {
|
|
define("rrwebRecord", [], f);
|
|
} else if ("object" == typeof exports) {
|
|
exports["rrwebRecord"] = f();
|
|
} else {
|
|
g["rrwebRecord"] = f();
|
|
}
|
|
}(this, () => {
|
|
var exports = {};
|
|
var module = { exports };
|
|
"use strict";
|
|
var __defProp = Object.defineProperty;
|
|
var __defProps = Object.defineProperties;
|
|
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
var __spreadValues = (a, b) => {
|
|
for (var prop in b || (b = {}))
|
|
if (__hasOwnProp.call(b, prop))
|
|
__defNormalProp(a, prop, b[prop]);
|
|
if (__getOwnPropSymbols)
|
|
for (var prop of __getOwnPropSymbols(b)) {
|
|
if (__propIsEnum.call(b, prop))
|
|
__defNormalProp(a, prop, b[prop]);
|
|
}
|
|
return a;
|
|
};
|
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
var __objRest = (source, exclude) => {
|
|
var target = {};
|
|
for (var prop in source)
|
|
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
target[prop] = source[prop];
|
|
if (source != null && __getOwnPropSymbols)
|
|
for (var prop of __getOwnPropSymbols(source)) {
|
|
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
target[prop] = source[prop];
|
|
}
|
|
return target;
|
|
};
|
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
var __defProp2 = Object.defineProperty;
|
|
var __defNormalProp2 = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
var __publicField = (obj, key, value) => __defNormalProp2(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
var _a;
|
|
var __defProp$1 = Object.defineProperty;
|
|
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
var NodeType$3 = /* @__PURE__ */ ((NodeType2) => {
|
|
NodeType2[NodeType2["Document"] = 0] = "Document";
|
|
NodeType2[NodeType2["DocumentType"] = 1] = "DocumentType";
|
|
NodeType2[NodeType2["Element"] = 2] = "Element";
|
|
NodeType2[NodeType2["Text"] = 3] = "Text";
|
|
NodeType2[NodeType2["CDATA"] = 4] = "CDATA";
|
|
NodeType2[NodeType2["Comment"] = 5] = "Comment";
|
|
return NodeType2;
|
|
})(NodeType$3 || {});
|
|
const testableAccessors$1 = {
|
|
Node: [
|
|
"childNodes",
|
|
"parentNode",
|
|
"parentElement",
|
|
"textContent",
|
|
"ownerDocument"
|
|
],
|
|
ShadowRoot: ["host", "styleSheets"],
|
|
Element: ["shadowRoot", "querySelector", "querySelectorAll"],
|
|
MutationObserver: []
|
|
};
|
|
const testableMethods$1 = {
|
|
Node: ["contains", "getRootNode"],
|
|
ShadowRoot: ["getSelection"],
|
|
Element: [],
|
|
MutationObserver: ["constructor"]
|
|
};
|
|
const untaintedBasePrototype$1 = {};
|
|
const isAngularZonePresent$1 = () => {
|
|
return !!globalThis.Zone;
|
|
};
|
|
function getUntaintedPrototype$1(key) {
|
|
if (untaintedBasePrototype$1[key])
|
|
return untaintedBasePrototype$1[key];
|
|
const defaultObj = globalThis[key];
|
|
const defaultPrototype = defaultObj.prototype;
|
|
const accessorNames = key in testableAccessors$1 ? testableAccessors$1[key] : void 0;
|
|
const isUntaintedAccessors = Boolean(
|
|
accessorNames && // @ts-expect-error 2345
|
|
accessorNames.every(
|
|
(accessor) => {
|
|
var _a2, _b;
|
|
return Boolean(
|
|
(_b = (_a2 = Object.getOwnPropertyDescriptor(defaultPrototype, accessor)) == null ? void 0 : _a2.get) == null ? void 0 : _b.toString().includes("[native code]")
|
|
);
|
|
}
|
|
)
|
|
);
|
|
const methodNames = key in testableMethods$1 ? testableMethods$1[key] : void 0;
|
|
const isUntaintedMethods = Boolean(
|
|
methodNames && methodNames.every(
|
|
// @ts-expect-error 2345
|
|
(method) => {
|
|
var _a2;
|
|
return typeof defaultPrototype[method] === "function" && ((_a2 = defaultPrototype[method]) == null ? void 0 : _a2.toString().includes("[native code]"));
|
|
}
|
|
)
|
|
);
|
|
if (isUntaintedAccessors && isUntaintedMethods && !isAngularZonePresent$1()) {
|
|
untaintedBasePrototype$1[key] = defaultObj.prototype;
|
|
return defaultObj.prototype;
|
|
}
|
|
try {
|
|
const iframeEl = document.createElement("iframe");
|
|
document.body.appendChild(iframeEl);
|
|
const win = iframeEl.contentWindow;
|
|
if (!win) return defaultObj.prototype;
|
|
const untaintedObject = win[key].prototype;
|
|
document.body.removeChild(iframeEl);
|
|
if (!untaintedObject) return defaultPrototype;
|
|
return untaintedBasePrototype$1[key] = untaintedObject;
|
|
} catch (e) {
|
|
return defaultPrototype;
|
|
}
|
|
}
|
|
const untaintedAccessorCache$1 = {};
|
|
function getUntaintedAccessor$1(key, instance, accessor) {
|
|
var _a2;
|
|
const cacheKey = `${key}.${String(accessor)}`;
|
|
if (untaintedAccessorCache$1[cacheKey])
|
|
return untaintedAccessorCache$1[cacheKey].call(
|
|
instance
|
|
);
|
|
const untaintedPrototype = getUntaintedPrototype$1(key);
|
|
const untaintedAccessor = (_a2 = Object.getOwnPropertyDescriptor(
|
|
untaintedPrototype,
|
|
accessor
|
|
)) == null ? void 0 : _a2.get;
|
|
if (!untaintedAccessor) return instance[accessor];
|
|
untaintedAccessorCache$1[cacheKey] = untaintedAccessor;
|
|
return untaintedAccessor.call(instance);
|
|
}
|
|
const untaintedMethodCache$1 = {};
|
|
function getUntaintedMethod$1(key, instance, method) {
|
|
const cacheKey = `${key}.${String(method)}`;
|
|
if (untaintedMethodCache$1[cacheKey])
|
|
return untaintedMethodCache$1[cacheKey].bind(
|
|
instance
|
|
);
|
|
const untaintedPrototype = getUntaintedPrototype$1(key);
|
|
const untaintedMethod = untaintedPrototype[method];
|
|
if (typeof untaintedMethod !== "function") return instance[method];
|
|
untaintedMethodCache$1[cacheKey] = untaintedMethod;
|
|
return untaintedMethod.bind(instance);
|
|
}
|
|
function ownerDocument$1(n2) {
|
|
return getUntaintedAccessor$1("Node", n2, "ownerDocument");
|
|
}
|
|
function childNodes$1(n2) {
|
|
return getUntaintedAccessor$1("Node", n2, "childNodes");
|
|
}
|
|
function parentNode$1(n2) {
|
|
return getUntaintedAccessor$1("Node", n2, "parentNode");
|
|
}
|
|
function parentElement$1(n2) {
|
|
return getUntaintedAccessor$1("Node", n2, "parentElement");
|
|
}
|
|
function textContent$1(n2) {
|
|
return getUntaintedAccessor$1("Node", n2, "textContent");
|
|
}
|
|
function contains$1(n2, other) {
|
|
return getUntaintedMethod$1("Node", n2, "contains")(other);
|
|
}
|
|
function getRootNode$1(n2) {
|
|
return getUntaintedMethod$1("Node", n2, "getRootNode")();
|
|
}
|
|
function host$1(n2) {
|
|
if (!n2 || !("host" in n2)) return null;
|
|
return getUntaintedAccessor$1("ShadowRoot", n2, "host");
|
|
}
|
|
function styleSheets$1(n2) {
|
|
return n2.styleSheets;
|
|
}
|
|
function shadowRoot$1(n2) {
|
|
if (!n2 || !("shadowRoot" in n2)) return null;
|
|
return getUntaintedAccessor$1("Element", n2, "shadowRoot");
|
|
}
|
|
function querySelector$1(n2, selectors) {
|
|
return getUntaintedAccessor$1("Element", n2, "querySelector")(selectors);
|
|
}
|
|
function querySelectorAll$1(n2, selectors) {
|
|
return getUntaintedAccessor$1("Element", n2, "querySelectorAll")(selectors);
|
|
}
|
|
function mutationObserverCtor$1() {
|
|
return getUntaintedPrototype$1("MutationObserver").constructor;
|
|
}
|
|
function patch$1(source, name, replacement) {
|
|
try {
|
|
if (!(name in source)) {
|
|
return () => {
|
|
};
|
|
}
|
|
const original = source[name];
|
|
const wrapped = replacement(original);
|
|
if (typeof wrapped === "function") {
|
|
wrapped.prototype = wrapped.prototype || {};
|
|
Object.defineProperties(wrapped, {
|
|
__rrweb_original__: {
|
|
enumerable: false,
|
|
value: original
|
|
}
|
|
});
|
|
}
|
|
source[name] = wrapped;
|
|
return () => {
|
|
source[name] = original;
|
|
};
|
|
} catch (e) {
|
|
return () => {
|
|
};
|
|
}
|
|
}
|
|
const index$1 = {
|
|
ownerDocument: ownerDocument$1,
|
|
childNodes: childNodes$1,
|
|
parentNode: parentNode$1,
|
|
parentElement: parentElement$1,
|
|
textContent: textContent$1,
|
|
contains: contains$1,
|
|
getRootNode: getRootNode$1,
|
|
host: host$1,
|
|
styleSheets: styleSheets$1,
|
|
shadowRoot: shadowRoot$1,
|
|
querySelector: querySelector$1,
|
|
querySelectorAll: querySelectorAll$1,
|
|
mutationObserver: mutationObserverCtor$1,
|
|
patch: patch$1
|
|
};
|
|
function isElement(n2) {
|
|
return n2.nodeType === n2.ELEMENT_NODE;
|
|
}
|
|
function isShadowRoot(n2) {
|
|
const hostEl = (
|
|
// anchor and textarea elements also have a `host` property
|
|
// but only shadow roots have a `mode` property
|
|
n2 && "host" in n2 && "mode" in n2 && index$1.host(n2) || null
|
|
);
|
|
return Boolean(
|
|
hostEl && "shadowRoot" in hostEl && index$1.shadowRoot(hostEl) === n2
|
|
);
|
|
}
|
|
function isNativeShadowDom(shadowRoot2) {
|
|
return Object.prototype.toString.call(shadowRoot2) === "[object ShadowRoot]";
|
|
}
|
|
function fixBrowserCompatibilityIssuesInCSS(cssText) {
|
|
if (cssText.includes(" background-clip: text;") && !cssText.includes(" -webkit-background-clip: text;")) {
|
|
cssText = cssText.replace(
|
|
/\sbackground-clip:\s*text;/g,
|
|
" -webkit-background-clip: text; background-clip: text;"
|
|
);
|
|
}
|
|
return cssText;
|
|
}
|
|
function escapeImportStatement(rule2) {
|
|
const { cssText } = rule2;
|
|
if (cssText.split('"').length < 3) return cssText;
|
|
const statement = ["@import", `url(${JSON.stringify(rule2.href)})`];
|
|
if (rule2.layerName === "") {
|
|
statement.push(`layer`);
|
|
} else if (rule2.layerName) {
|
|
statement.push(`layer(${rule2.layerName})`);
|
|
}
|
|
if (rule2.supportsText) {
|
|
statement.push(`supports(${rule2.supportsText})`);
|
|
}
|
|
if (rule2.media.length) {
|
|
statement.push(rule2.media.mediaText);
|
|
}
|
|
return statement.join(" ") + ";";
|
|
}
|
|
function stringifyStylesheet(s2) {
|
|
try {
|
|
const rules2 = s2.rules || s2.cssRules;
|
|
if (!rules2) {
|
|
return null;
|
|
}
|
|
let sheetHref = s2.href;
|
|
if (!sheetHref && s2.ownerNode) {
|
|
sheetHref = s2.ownerNode.baseURI;
|
|
}
|
|
const stringifiedRules = Array.from(
|
|
rules2,
|
|
(rule2) => stringifyRule(rule2, sheetHref)
|
|
).join("");
|
|
return fixBrowserCompatibilityIssuesInCSS(stringifiedRules);
|
|
} catch (error) {
|
|
return null;
|
|
}
|
|
}
|
|
function stringifyRule(rule2, sheetHref) {
|
|
if (isCSSImportRule(rule2)) {
|
|
let importStringified;
|
|
try {
|
|
importStringified = // for same-origin stylesheets,
|
|
// we can access the imported stylesheet rules directly
|
|
stringifyStylesheet(rule2.styleSheet) || // work around browser issues with the raw string `@import url(...)` statement
|
|
escapeImportStatement(rule2);
|
|
} catch (error) {
|
|
importStringified = rule2.cssText;
|
|
}
|
|
if (rule2.styleSheet.href) {
|
|
return absolutifyURLs(importStringified, rule2.styleSheet.href);
|
|
}
|
|
return importStringified;
|
|
} else {
|
|
let ruleStringified = rule2.cssText;
|
|
if (isCSSStyleRule(rule2) && rule2.selectorText.includes(":")) {
|
|
ruleStringified = fixSafariColons(ruleStringified);
|
|
}
|
|
if (sheetHref) {
|
|
return absolutifyURLs(ruleStringified, sheetHref);
|
|
}
|
|
return ruleStringified;
|
|
}
|
|
}
|
|
function fixSafariColons(cssStringified) {
|
|
const regex = /(\[(?:[\w-]+)[^\\])(:(?:[\w-]+)\])/gm;
|
|
return cssStringified.replace(regex, "$1\\$2");
|
|
}
|
|
function isCSSImportRule(rule2) {
|
|
return "styleSheet" in rule2;
|
|
}
|
|
function isCSSStyleRule(rule2) {
|
|
return "selectorText" in rule2;
|
|
}
|
|
class Mirror {
|
|
constructor() {
|
|
__publicField$1(this, "idNodeMap", /* @__PURE__ */ new Map());
|
|
__publicField$1(this, "nodeMetaMap", /* @__PURE__ */ new WeakMap());
|
|
}
|
|
getId(n2) {
|
|
var _a2;
|
|
if (!n2) return -1;
|
|
const id = (_a2 = this.getMeta(n2)) == null ? void 0 : _a2.id;
|
|
return id != null ? id : -1;
|
|
}
|
|
getNode(id) {
|
|
return this.idNodeMap.get(id) || null;
|
|
}
|
|
getIds() {
|
|
return Array.from(this.idNodeMap.keys());
|
|
}
|
|
getMeta(n2) {
|
|
return this.nodeMetaMap.get(n2) || null;
|
|
}
|
|
// removes the node from idNodeMap
|
|
// doesn't remove the node from nodeMetaMap
|
|
removeNodeFromMap(n2) {
|
|
const id = this.getId(n2);
|
|
this.idNodeMap.delete(id);
|
|
if (n2.childNodes) {
|
|
n2.childNodes.forEach(
|
|
(childNode) => this.removeNodeFromMap(childNode)
|
|
);
|
|
}
|
|
}
|
|
has(id) {
|
|
return this.idNodeMap.has(id);
|
|
}
|
|
hasNode(node2) {
|
|
return this.nodeMetaMap.has(node2);
|
|
}
|
|
add(n2, meta) {
|
|
const id = meta.id;
|
|
this.idNodeMap.set(id, n2);
|
|
this.nodeMetaMap.set(n2, meta);
|
|
}
|
|
replace(id, n2) {
|
|
const oldNode = this.getNode(id);
|
|
if (oldNode) {
|
|
const meta = this.nodeMetaMap.get(oldNode);
|
|
if (meta) this.nodeMetaMap.set(n2, meta);
|
|
}
|
|
this.idNodeMap.set(id, n2);
|
|
}
|
|
reset() {
|
|
this.idNodeMap = /* @__PURE__ */ new Map();
|
|
this.nodeMetaMap = /* @__PURE__ */ new WeakMap();
|
|
}
|
|
}
|
|
function createMirror$2() {
|
|
return new Mirror();
|
|
}
|
|
function maskInputValue({
|
|
element,
|
|
maskInputOptions,
|
|
tagName,
|
|
type,
|
|
value,
|
|
maskInputFn
|
|
}) {
|
|
let text = value || "";
|
|
const actualType = type && toLowerCase(type);
|
|
if (maskInputOptions[tagName.toLowerCase()] || actualType && maskInputOptions[actualType]) {
|
|
if (maskInputFn) {
|
|
text = maskInputFn(text, element);
|
|
} else {
|
|
text = "*".repeat(text.length);
|
|
}
|
|
}
|
|
return text;
|
|
}
|
|
function toLowerCase(str) {
|
|
return str.toLowerCase();
|
|
}
|
|
const ORIGINAL_ATTRIBUTE_NAME = "__rrweb_original__";
|
|
function is2DCanvasBlank(canvas) {
|
|
const ctx = canvas.getContext("2d");
|
|
if (!ctx) return true;
|
|
const chunkSize = 50;
|
|
for (let x = 0; x < canvas.width; x += chunkSize) {
|
|
for (let y = 0; y < canvas.height; y += chunkSize) {
|
|
const getImageData = ctx.getImageData;
|
|
const originalGetImageData = ORIGINAL_ATTRIBUTE_NAME in getImageData ? getImageData[ORIGINAL_ATTRIBUTE_NAME] : getImageData;
|
|
const pixelBuffer = new Uint32Array(
|
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access
|
|
originalGetImageData.call(
|
|
ctx,
|
|
x,
|
|
y,
|
|
Math.min(chunkSize, canvas.width - x),
|
|
Math.min(chunkSize, canvas.height - y)
|
|
).data.buffer
|
|
);
|
|
if (pixelBuffer.some((pixel) => pixel !== 0)) return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
function getInputType(element) {
|
|
const type = element.type;
|
|
return element.hasAttribute("data-rr-is-password") ? "password" : type ? (
|
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
toLowerCase(type)
|
|
) : null;
|
|
}
|
|
function extractFileExtension(path, baseURL) {
|
|
var _a2;
|
|
let url;
|
|
try {
|
|
url = new URL(path, baseURL != null ? baseURL : window.location.href);
|
|
} catch (err) {
|
|
return null;
|
|
}
|
|
const regex = /\.([0-9a-z]+)(?:$)/i;
|
|
const match = url.pathname.match(regex);
|
|
return (_a2 = match == null ? void 0 : match[1]) != null ? _a2 : null;
|
|
}
|
|
function extractOrigin(url) {
|
|
let origin = "";
|
|
if (url.indexOf("//") > -1) {
|
|
origin = url.split("/").slice(0, 3).join("/");
|
|
} else {
|
|
origin = url.split("/")[0];
|
|
}
|
|
origin = origin.split("?")[0];
|
|
return origin;
|
|
}
|
|
const URL_IN_CSS_REF = /url\((?:(')([^']*)'|(")(.*?)"|([^)]*))\)/gm;
|
|
const URL_PROTOCOL_MATCH = /^(?:[a-z+]+:)?\/\//i;
|
|
const URL_WWW_MATCH = /^www\..*/i;
|
|
const DATA_URI = /^(data:)([^,]*),(.*)/i;
|
|
function absolutifyURLs(cssText, href) {
|
|
return (cssText || "").replace(
|
|
URL_IN_CSS_REF,
|
|
(origin, quote1, path1, quote2, path2, path3) => {
|
|
const filePath = path1 || path2 || path3;
|
|
const maybeQuote = quote1 || quote2 || "";
|
|
if (!filePath) {
|
|
return origin;
|
|
}
|
|
if (URL_PROTOCOL_MATCH.test(filePath) || URL_WWW_MATCH.test(filePath)) {
|
|
return `url(${maybeQuote}${filePath}${maybeQuote})`;
|
|
}
|
|
if (DATA_URI.test(filePath)) {
|
|
return `url(${maybeQuote}${filePath}${maybeQuote})`;
|
|
}
|
|
if (filePath[0] === "/") {
|
|
return `url(${maybeQuote}${extractOrigin(href) + filePath}${maybeQuote})`;
|
|
}
|
|
const stack = href.split("/");
|
|
const parts = filePath.split("/");
|
|
stack.pop();
|
|
for (const part of parts) {
|
|
if (part === ".") {
|
|
continue;
|
|
} else if (part === "..") {
|
|
stack.pop();
|
|
} else {
|
|
stack.push(part);
|
|
}
|
|
}
|
|
return `url(${maybeQuote}${stack.join("/")}${maybeQuote})`;
|
|
}
|
|
);
|
|
}
|
|
function normalizeCssString(cssText, _testNoPxNorm = false) {
|
|
if (_testNoPxNorm) {
|
|
return cssText.replace(/(\/\*[^*]*\*\/)|[\s;]/g, "");
|
|
} else {
|
|
return cssText.replace(/(\/\*[^*]*\*\/)|[\s;]/g, "").replace(/0px/g, "0");
|
|
}
|
|
}
|
|
function splitCssText(cssText, style, _testNoPxNorm = false) {
|
|
const childNodes2 = Array.from(style.childNodes);
|
|
const splits = [];
|
|
let iterCount = 0;
|
|
if (childNodes2.length > 1 && cssText && typeof cssText === "string") {
|
|
let cssTextNorm = normalizeCssString(cssText, _testNoPxNorm);
|
|
const normFactor = cssTextNorm.length / cssText.length;
|
|
for (let i2 = 1; i2 < childNodes2.length; i2++) {
|
|
if (childNodes2[i2].textContent && typeof childNodes2[i2].textContent === "string") {
|
|
const textContentNorm = normalizeCssString(
|
|
childNodes2[i2].textContent,
|
|
_testNoPxNorm
|
|
);
|
|
const jLimit = 100;
|
|
let j = 3;
|
|
for (; j < textContentNorm.length; j++) {
|
|
if (
|
|
// keep consuming css identifiers (to get a decent chunk more quickly)
|
|
textContentNorm[j].match(/[a-zA-Z0-9]/) || // substring needs to be unique to this section
|
|
textContentNorm.indexOf(textContentNorm.substring(0, j), 1) !== -1
|
|
) {
|
|
continue;
|
|
}
|
|
break;
|
|
}
|
|
for (; j < textContentNorm.length; j++) {
|
|
let startSubstring = textContentNorm.substring(0, j);
|
|
let cssNormSplits = cssTextNorm.split(startSubstring);
|
|
let splitNorm = -1;
|
|
if (cssNormSplits.length === 2) {
|
|
splitNorm = cssNormSplits[0].length;
|
|
} else if (cssNormSplits.length > 2 && cssNormSplits[0] === "" && childNodes2[i2 - 1].textContent !== "") {
|
|
splitNorm = cssTextNorm.indexOf(startSubstring, 1);
|
|
} else if (cssNormSplits.length === 1) {
|
|
startSubstring = startSubstring.substring(
|
|
0,
|
|
startSubstring.length - 1
|
|
);
|
|
cssNormSplits = cssTextNorm.split(startSubstring);
|
|
if (cssNormSplits.length <= 1) {
|
|
splits.push(cssText);
|
|
return splits;
|
|
}
|
|
j = jLimit + 1;
|
|
} else if (j === textContentNorm.length - 1) {
|
|
splitNorm = cssTextNorm.indexOf(startSubstring);
|
|
}
|
|
if (cssNormSplits.length >= 2 && j > jLimit) {
|
|
const prevTextContent = childNodes2[i2 - 1].textContent;
|
|
if (prevTextContent && typeof prevTextContent === "string") {
|
|
const prevMinLength = normalizeCssString(prevTextContent).length;
|
|
splitNorm = cssTextNorm.indexOf(startSubstring, prevMinLength);
|
|
}
|
|
if (splitNorm === -1) {
|
|
splitNorm = cssNormSplits[0].length;
|
|
}
|
|
}
|
|
if (splitNorm !== -1) {
|
|
let k = Math.floor(splitNorm / normFactor);
|
|
for (; k > 0 && k < cssText.length; ) {
|
|
iterCount += 1;
|
|
if (iterCount > 50 * childNodes2.length) {
|
|
splits.push(cssText);
|
|
return splits;
|
|
}
|
|
const normPart = normalizeCssString(
|
|
cssText.substring(0, k),
|
|
_testNoPxNorm
|
|
);
|
|
if (normPart.length === splitNorm) {
|
|
splits.push(cssText.substring(0, k));
|
|
cssText = cssText.substring(k);
|
|
cssTextNorm = cssTextNorm.substring(splitNorm);
|
|
break;
|
|
} else if (normPart.length < splitNorm) {
|
|
k += Math.max(
|
|
1,
|
|
Math.floor((splitNorm - normPart.length) / normFactor)
|
|
);
|
|
} else {
|
|
k -= Math.max(
|
|
1,
|
|
Math.floor((normPart.length - splitNorm) * normFactor)
|
|
);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
splits.push(cssText);
|
|
return splits;
|
|
}
|
|
function markCssSplits(cssText, style) {
|
|
return splitCssText(cssText, style).join("/* rr_split */");
|
|
}
|
|
let _id = 1;
|
|
const tagNameRegex = new RegExp("[^a-z0-9-_:]");
|
|
const IGNORED_NODE = -2;
|
|
function genId() {
|
|
return _id++;
|
|
}
|
|
function getValidTagName$1(element) {
|
|
if (element instanceof HTMLFormElement) {
|
|
return "form";
|
|
}
|
|
const processedTagName = toLowerCase(element.tagName);
|
|
if (tagNameRegex.test(processedTagName)) {
|
|
return "div";
|
|
}
|
|
return processedTagName;
|
|
}
|
|
let canvasService;
|
|
let canvasCtx;
|
|
const SRCSET_NOT_SPACES = /^[^ \t\n\r\u000c]+/;
|
|
const SRCSET_COMMAS_OR_SPACES = /^[, \t\n\r\u000c]+/;
|
|
function getAbsoluteSrcsetString(doc, attributeValue) {
|
|
if (attributeValue.trim() === "") {
|
|
return attributeValue;
|
|
}
|
|
let pos = 0;
|
|
function collectCharacters(regEx) {
|
|
let chars2;
|
|
const match = regEx.exec(attributeValue.substring(pos));
|
|
if (match) {
|
|
chars2 = match[0];
|
|
pos += chars2.length;
|
|
return chars2;
|
|
}
|
|
return "";
|
|
}
|
|
const output = [];
|
|
while (true) {
|
|
collectCharacters(SRCSET_COMMAS_OR_SPACES);
|
|
if (pos >= attributeValue.length) {
|
|
break;
|
|
}
|
|
let url = collectCharacters(SRCSET_NOT_SPACES);
|
|
if (url.slice(-1) === ",") {
|
|
url = absoluteToDoc(doc, url.substring(0, url.length - 1));
|
|
output.push(url);
|
|
} else {
|
|
let descriptorsStr = "";
|
|
url = absoluteToDoc(doc, url);
|
|
let inParens = false;
|
|
while (true) {
|
|
const c2 = attributeValue.charAt(pos);
|
|
if (c2 === "") {
|
|
output.push((url + descriptorsStr).trim());
|
|
break;
|
|
} else if (!inParens) {
|
|
if (c2 === ",") {
|
|
pos += 1;
|
|
output.push((url + descriptorsStr).trim());
|
|
break;
|
|
} else if (c2 === "(") {
|
|
inParens = true;
|
|
}
|
|
} else {
|
|
if (c2 === ")") {
|
|
inParens = false;
|
|
}
|
|
}
|
|
descriptorsStr += c2;
|
|
pos += 1;
|
|
}
|
|
}
|
|
}
|
|
return output.join(", ");
|
|
}
|
|
const cachedDocument = /* @__PURE__ */ new WeakMap();
|
|
function absoluteToDoc(doc, attributeValue) {
|
|
if (!attributeValue || attributeValue.trim() === "") {
|
|
return attributeValue;
|
|
}
|
|
return getHref(doc, attributeValue);
|
|
}
|
|
function isSVGElement(el) {
|
|
return Boolean(el.tagName === "svg" || el.ownerSVGElement);
|
|
}
|
|
function getHref(doc, customHref) {
|
|
let a2 = cachedDocument.get(doc);
|
|
if (!a2) {
|
|
a2 = doc.createElement("a");
|
|
cachedDocument.set(doc, a2);
|
|
}
|
|
if (!customHref) {
|
|
customHref = "";
|
|
} else if (customHref.startsWith("blob:") || customHref.startsWith("data:")) {
|
|
return customHref;
|
|
}
|
|
a2.setAttribute("href", customHref);
|
|
return a2.href;
|
|
}
|
|
function transformAttribute(doc, tagName, name, value) {
|
|
if (!value) {
|
|
return value;
|
|
}
|
|
if (name === "src" || name === "href" && !(tagName === "use" && value[0] === "#")) {
|
|
return absoluteToDoc(doc, value);
|
|
} else if (name === "xlink:href" && value[0] !== "#") {
|
|
return absoluteToDoc(doc, value);
|
|
} else if (name === "background" && ["table", "td", "th"].includes(tagName)) {
|
|
return absoluteToDoc(doc, value);
|
|
} else if (name === "srcset") {
|
|
return getAbsoluteSrcsetString(doc, value);
|
|
} else if (name === "style") {
|
|
return absolutifyURLs(value, getHref(doc));
|
|
} else if (tagName === "object" && name === "data") {
|
|
return absoluteToDoc(doc, value);
|
|
}
|
|
return value;
|
|
}
|
|
function ignoreAttribute(tagName, name, _value) {
|
|
return ["video", "audio"].includes(tagName) && name === "autoplay";
|
|
}
|
|
function _isBlockedElement(element, blockClass, blockSelector) {
|
|
try {
|
|
if (typeof blockClass === "string") {
|
|
if (element.classList.contains(blockClass)) {
|
|
return true;
|
|
}
|
|
} else {
|
|
for (let eIndex = element.classList.length; eIndex--; ) {
|
|
const className = element.classList[eIndex];
|
|
if (blockClass.test(className)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
if (blockSelector) {
|
|
return element.matches(blockSelector);
|
|
}
|
|
} catch (e2) {
|
|
}
|
|
return false;
|
|
}
|
|
function classMatchesRegex(node2, regex, checkAncestors) {
|
|
if (!node2) return false;
|
|
if (node2.nodeType !== node2.ELEMENT_NODE) {
|
|
if (!checkAncestors) return false;
|
|
return classMatchesRegex(index$1.parentNode(node2), regex, checkAncestors);
|
|
}
|
|
for (let eIndex = node2.classList.length; eIndex--; ) {
|
|
const className = node2.classList[eIndex];
|
|
if (regex.test(className)) {
|
|
return true;
|
|
}
|
|
}
|
|
if (!checkAncestors) return false;
|
|
return classMatchesRegex(index$1.parentNode(node2), regex, checkAncestors);
|
|
}
|
|
function needMaskingText(node2, maskTextClass, maskTextSelector, checkAncestors) {
|
|
let el;
|
|
if (isElement(node2)) {
|
|
el = node2;
|
|
if (!index$1.childNodes(el).length) {
|
|
return false;
|
|
}
|
|
} else if (index$1.parentElement(node2) === null) {
|
|
return false;
|
|
} else {
|
|
el = index$1.parentElement(node2);
|
|
}
|
|
try {
|
|
if (typeof maskTextClass === "string") {
|
|
if (checkAncestors) {
|
|
if (el.closest(`.${maskTextClass}`)) return true;
|
|
} else {
|
|
if (el.classList.contains(maskTextClass)) return true;
|
|
}
|
|
} else {
|
|
if (classMatchesRegex(el, maskTextClass, checkAncestors)) return true;
|
|
}
|
|
if (maskTextSelector) {
|
|
if (checkAncestors) {
|
|
if (el.closest(maskTextSelector)) return true;
|
|
} else {
|
|
if (el.matches(maskTextSelector)) return true;
|
|
}
|
|
}
|
|
} catch (e2) {
|
|
}
|
|
return false;
|
|
}
|
|
function onceIframeLoaded(iframeEl, listener, iframeLoadTimeout) {
|
|
const win = iframeEl.contentWindow;
|
|
if (!win) {
|
|
return;
|
|
}
|
|
let fired = false;
|
|
let readyState;
|
|
try {
|
|
readyState = win.document.readyState;
|
|
} catch (error) {
|
|
return;
|
|
}
|
|
if (readyState !== "complete") {
|
|
const timer = setTimeout(() => {
|
|
if (!fired) {
|
|
listener();
|
|
fired = true;
|
|
}
|
|
}, iframeLoadTimeout);
|
|
iframeEl.addEventListener("load", () => {
|
|
clearTimeout(timer);
|
|
fired = true;
|
|
listener();
|
|
});
|
|
return;
|
|
}
|
|
const blankUrl = "about:blank";
|
|
if (win.location.href !== blankUrl || iframeEl.src === blankUrl || iframeEl.src === "") {
|
|
setTimeout(listener, 0);
|
|
return iframeEl.addEventListener("load", listener);
|
|
}
|
|
iframeEl.addEventListener("load", listener);
|
|
}
|
|
function onceStylesheetLoaded(link, listener, styleSheetLoadTimeout) {
|
|
let fired = false;
|
|
let styleSheetLoaded;
|
|
try {
|
|
styleSheetLoaded = link.sheet;
|
|
} catch (error) {
|
|
return;
|
|
}
|
|
if (styleSheetLoaded) return;
|
|
const timer = setTimeout(() => {
|
|
if (!fired) {
|
|
listener();
|
|
fired = true;
|
|
}
|
|
}, styleSheetLoadTimeout);
|
|
link.addEventListener("load", () => {
|
|
clearTimeout(timer);
|
|
fired = true;
|
|
listener();
|
|
});
|
|
}
|
|
function serializeNode(n2, options) {
|
|
const {
|
|
doc,
|
|
mirror: mirror2,
|
|
blockClass,
|
|
blockSelector,
|
|
needsMask,
|
|
inlineStylesheet,
|
|
maskInputOptions = {},
|
|
maskTextFn,
|
|
maskInputFn,
|
|
dataURLOptions = {},
|
|
inlineImages,
|
|
recordCanvas,
|
|
keepIframeSrcFn,
|
|
newlyAddedElement = false,
|
|
cssCaptured = false
|
|
} = options;
|
|
const rootId = getRootId(doc, mirror2);
|
|
switch (n2.nodeType) {
|
|
case n2.DOCUMENT_NODE:
|
|
if (n2.compatMode !== "CSS1Compat") {
|
|
return {
|
|
type: NodeType$3.Document,
|
|
childNodes: [],
|
|
compatMode: n2.compatMode
|
|
// probably "BackCompat"
|
|
};
|
|
} else {
|
|
return {
|
|
type: NodeType$3.Document,
|
|
childNodes: []
|
|
};
|
|
}
|
|
case n2.DOCUMENT_TYPE_NODE:
|
|
return {
|
|
type: NodeType$3.DocumentType,
|
|
name: n2.name,
|
|
publicId: n2.publicId,
|
|
systemId: n2.systemId,
|
|
rootId
|
|
};
|
|
case n2.ELEMENT_NODE:
|
|
return serializeElementNode(n2, {
|
|
doc,
|
|
blockClass,
|
|
blockSelector,
|
|
inlineStylesheet,
|
|
maskInputOptions,
|
|
maskInputFn,
|
|
dataURLOptions,
|
|
inlineImages,
|
|
recordCanvas,
|
|
keepIframeSrcFn,
|
|
newlyAddedElement,
|
|
rootId
|
|
});
|
|
case n2.TEXT_NODE:
|
|
return serializeTextNode(n2, {
|
|
doc,
|
|
needsMask,
|
|
maskTextFn,
|
|
rootId,
|
|
cssCaptured
|
|
});
|
|
case n2.CDATA_SECTION_NODE:
|
|
return {
|
|
type: NodeType$3.CDATA,
|
|
textContent: "",
|
|
rootId
|
|
};
|
|
case n2.COMMENT_NODE:
|
|
return {
|
|
type: NodeType$3.Comment,
|
|
textContent: index$1.textContent(n2) || "",
|
|
rootId
|
|
};
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
function getRootId(doc, mirror2) {
|
|
if (!mirror2.hasNode(doc)) return void 0;
|
|
const docId = mirror2.getId(doc);
|
|
return docId === 1 ? void 0 : docId;
|
|
}
|
|
function serializeTextNode(n2, options) {
|
|
const { needsMask, maskTextFn, rootId, cssCaptured } = options;
|
|
const parent = index$1.parentNode(n2);
|
|
const parentTagName = parent && parent.tagName;
|
|
let textContent2 = "";
|
|
const isStyle = parentTagName === "STYLE" ? true : void 0;
|
|
const isScript = parentTagName === "SCRIPT" ? true : void 0;
|
|
if (isScript) {
|
|
textContent2 = "SCRIPT_PLACEHOLDER";
|
|
} else if (!cssCaptured) {
|
|
textContent2 = index$1.textContent(n2);
|
|
if (isStyle && textContent2) {
|
|
textContent2 = absolutifyURLs(textContent2, getHref(options.doc));
|
|
}
|
|
}
|
|
if (!isStyle && !isScript && textContent2 && needsMask) {
|
|
textContent2 = maskTextFn ? maskTextFn(textContent2, index$1.parentElement(n2)) : textContent2.replace(/[\S]/g, "*");
|
|
}
|
|
return {
|
|
type: NodeType$3.Text,
|
|
textContent: textContent2 || "",
|
|
rootId
|
|
};
|
|
}
|
|
function serializeElementNode(n2, options) {
|
|
const {
|
|
doc,
|
|
blockClass,
|
|
blockSelector,
|
|
inlineStylesheet,
|
|
maskInputOptions = {},
|
|
maskInputFn,
|
|
dataURLOptions = {},
|
|
inlineImages,
|
|
recordCanvas,
|
|
keepIframeSrcFn,
|
|
newlyAddedElement = false,
|
|
rootId
|
|
} = options;
|
|
const needBlock = _isBlockedElement(n2, blockClass, blockSelector);
|
|
const tagName = getValidTagName$1(n2);
|
|
let attributes = {};
|
|
const len = n2.attributes.length;
|
|
for (let i2 = 0; i2 < len; i2++) {
|
|
const attr = n2.attributes[i2];
|
|
if (!ignoreAttribute(tagName, attr.name, attr.value)) {
|
|
attributes[attr.name] = transformAttribute(
|
|
doc,
|
|
tagName,
|
|
toLowerCase(attr.name),
|
|
attr.value
|
|
);
|
|
}
|
|
}
|
|
if (tagName === "link" && inlineStylesheet) {
|
|
const stylesheet = Array.from(doc.styleSheets).find((s2) => {
|
|
return s2.href === n2.href;
|
|
});
|
|
let cssText = null;
|
|
if (stylesheet) {
|
|
cssText = stringifyStylesheet(stylesheet);
|
|
}
|
|
if (cssText) {
|
|
delete attributes.rel;
|
|
delete attributes.href;
|
|
attributes._cssText = cssText;
|
|
}
|
|
}
|
|
if (tagName === "style" && n2.sheet) {
|
|
let cssText = stringifyStylesheet(
|
|
n2.sheet
|
|
);
|
|
if (cssText) {
|
|
if (n2.childNodes.length > 1) {
|
|
cssText = markCssSplits(cssText, n2);
|
|
}
|
|
attributes._cssText = cssText;
|
|
}
|
|
}
|
|
if (["input", "textarea", "select"].includes(tagName)) {
|
|
const value = n2.value;
|
|
const checked = n2.checked;
|
|
if (attributes.type !== "radio" && attributes.type !== "checkbox" && attributes.type !== "submit" && attributes.type !== "button" && value) {
|
|
attributes.value = maskInputValue({
|
|
element: n2,
|
|
type: getInputType(n2),
|
|
tagName,
|
|
value,
|
|
maskInputOptions,
|
|
maskInputFn
|
|
});
|
|
} else if (checked) {
|
|
attributes.checked = checked;
|
|
}
|
|
}
|
|
if (tagName === "option") {
|
|
if (n2.selected && !maskInputOptions["select"]) {
|
|
attributes.selected = true;
|
|
} else {
|
|
delete attributes.selected;
|
|
}
|
|
}
|
|
if (tagName === "dialog" && n2.open) {
|
|
attributes.rr_open_mode = n2.matches("dialog:modal") ? "modal" : "non-modal";
|
|
}
|
|
if (tagName === "canvas" && recordCanvas) {
|
|
if (n2.__context === "2d") {
|
|
if (!is2DCanvasBlank(n2)) {
|
|
attributes.rr_dataURL = n2.toDataURL(
|
|
dataURLOptions.type,
|
|
dataURLOptions.quality
|
|
);
|
|
}
|
|
} else if (!("__context" in n2)) {
|
|
const canvasDataURL = n2.toDataURL(
|
|
dataURLOptions.type,
|
|
dataURLOptions.quality
|
|
);
|
|
const blankCanvas = doc.createElement("canvas");
|
|
blankCanvas.width = n2.width;
|
|
blankCanvas.height = n2.height;
|
|
const blankCanvasDataURL = blankCanvas.toDataURL(
|
|
dataURLOptions.type,
|
|
dataURLOptions.quality
|
|
);
|
|
if (canvasDataURL !== blankCanvasDataURL) {
|
|
attributes.rr_dataURL = canvasDataURL;
|
|
}
|
|
}
|
|
}
|
|
if (tagName === "img" && inlineImages) {
|
|
if (!canvasService) {
|
|
canvasService = doc.createElement("canvas");
|
|
canvasCtx = canvasService.getContext("2d");
|
|
}
|
|
const image = n2;
|
|
const imageSrc = image.currentSrc || image.getAttribute("src") || "<unknown-src>";
|
|
const priorCrossOrigin = image.crossOrigin;
|
|
const recordInlineImage = () => {
|
|
image.removeEventListener("load", recordInlineImage);
|
|
try {
|
|
canvasService.width = image.naturalWidth;
|
|
canvasService.height = image.naturalHeight;
|
|
canvasCtx.drawImage(image, 0, 0);
|
|
attributes.rr_dataURL = canvasService.toDataURL(
|
|
dataURLOptions.type,
|
|
dataURLOptions.quality
|
|
);
|
|
} catch (err) {
|
|
if (image.crossOrigin !== "anonymous") {
|
|
image.crossOrigin = "anonymous";
|
|
if (image.complete && image.naturalWidth !== 0)
|
|
recordInlineImage();
|
|
else image.addEventListener("load", recordInlineImage);
|
|
return;
|
|
} else {
|
|
console.warn(
|
|
`Cannot inline img src=${imageSrc}! Error: ${err}`
|
|
);
|
|
}
|
|
}
|
|
if (image.crossOrigin === "anonymous") {
|
|
priorCrossOrigin ? attributes.crossOrigin = priorCrossOrigin : image.removeAttribute("crossorigin");
|
|
}
|
|
};
|
|
if (image.complete && image.naturalWidth !== 0) recordInlineImage();
|
|
else image.addEventListener("load", recordInlineImage);
|
|
}
|
|
if (["audio", "video"].includes(tagName)) {
|
|
const mediaAttributes = attributes;
|
|
mediaAttributes.rr_mediaState = n2.paused ? "paused" : "played";
|
|
mediaAttributes.rr_mediaCurrentTime = n2.currentTime;
|
|
mediaAttributes.rr_mediaPlaybackRate = n2.playbackRate;
|
|
mediaAttributes.rr_mediaMuted = n2.muted;
|
|
mediaAttributes.rr_mediaLoop = n2.loop;
|
|
mediaAttributes.rr_mediaVolume = n2.volume;
|
|
}
|
|
if (!newlyAddedElement) {
|
|
if (n2.scrollLeft) {
|
|
attributes.rr_scrollLeft = n2.scrollLeft;
|
|
}
|
|
if (n2.scrollTop) {
|
|
attributes.rr_scrollTop = n2.scrollTop;
|
|
}
|
|
}
|
|
if (needBlock) {
|
|
const { width, height } = n2.getBoundingClientRect();
|
|
attributes = {
|
|
class: attributes.class,
|
|
rr_width: `${width}px`,
|
|
rr_height: `${height}px`
|
|
};
|
|
}
|
|
if (tagName === "iframe" && !keepIframeSrcFn(attributes.src)) {
|
|
if (!n2.contentDocument) {
|
|
attributes.rr_src = attributes.src;
|
|
}
|
|
delete attributes.src;
|
|
}
|
|
let isCustomElement;
|
|
try {
|
|
if (customElements.get(tagName)) isCustomElement = true;
|
|
} catch (e2) {
|
|
}
|
|
return {
|
|
type: NodeType$3.Element,
|
|
tagName,
|
|
attributes,
|
|
childNodes: [],
|
|
isSVG: isSVGElement(n2) || void 0,
|
|
needBlock,
|
|
rootId,
|
|
isCustom: isCustomElement
|
|
};
|
|
}
|
|
function lowerIfExists(maybeAttr) {
|
|
if (maybeAttr === void 0 || maybeAttr === null) {
|
|
return "";
|
|
} else {
|
|
return maybeAttr.toLowerCase();
|
|
}
|
|
}
|
|
function slimDOMDefaults(_slimDOMOptions) {
|
|
if (_slimDOMOptions === true || _slimDOMOptions === "all") {
|
|
return {
|
|
script: true,
|
|
comment: true,
|
|
headFavicon: true,
|
|
headWhitespace: true,
|
|
headMetaSocial: true,
|
|
headMetaRobots: true,
|
|
headMetaHttpEquiv: true,
|
|
headMetaVerification: true,
|
|
// the following are off for slimDOMOptions === true,
|
|
// as they destroy some (hidden) info:
|
|
headMetaAuthorship: _slimDOMOptions === "all",
|
|
headMetaDescKeywords: _slimDOMOptions === "all",
|
|
headTitleMutations: _slimDOMOptions === "all"
|
|
};
|
|
} else if (_slimDOMOptions) {
|
|
return _slimDOMOptions;
|
|
}
|
|
return {};
|
|
}
|
|
function slimDOMExcluded(sn, slimDOMOptions) {
|
|
if (slimDOMOptions.comment && sn.type === NodeType$3.Comment) {
|
|
return true;
|
|
} else if (sn.type === NodeType$3.Element) {
|
|
if (slimDOMOptions.script && // script tag
|
|
(sn.tagName === "script" || // (module)preload link
|
|
sn.tagName === "link" && (sn.attributes.rel === "preload" && sn.attributes.as === "script" || sn.attributes.rel === "modulepreload") || // prefetch link
|
|
sn.tagName === "link" && sn.attributes.rel === "prefetch" && typeof sn.attributes.href === "string" && extractFileExtension(sn.attributes.href) === "js")) {
|
|
return true;
|
|
} else if (slimDOMOptions.headFavicon && (sn.tagName === "link" && sn.attributes.rel === "shortcut icon" || sn.tagName === "meta" && (lowerIfExists(sn.attributes.name).match(
|
|
/^msapplication-tile(image|color)$/
|
|
) || lowerIfExists(sn.attributes.name) === "application-name" || lowerIfExists(sn.attributes.rel) === "icon" || lowerIfExists(sn.attributes.rel) === "apple-touch-icon" || lowerIfExists(sn.attributes.rel) === "shortcut icon"))) {
|
|
return true;
|
|
} else if (sn.tagName === "meta") {
|
|
if (slimDOMOptions.headMetaDescKeywords && lowerIfExists(sn.attributes.name).match(/^description|keywords$/)) {
|
|
return true;
|
|
} else if (slimDOMOptions.headMetaSocial && (lowerIfExists(sn.attributes.property).match(/^(og|twitter|fb):/) || // og = opengraph (facebook)
|
|
lowerIfExists(sn.attributes.name).match(/^(og|twitter):/) || lowerIfExists(sn.attributes.name) === "pinterest")) {
|
|
return true;
|
|
} else if (slimDOMOptions.headMetaRobots && (lowerIfExists(sn.attributes.name) === "robots" || lowerIfExists(sn.attributes.name) === "googlebot" || lowerIfExists(sn.attributes.name) === "bingbot")) {
|
|
return true;
|
|
} else if (slimDOMOptions.headMetaHttpEquiv && sn.attributes["http-equiv"] !== void 0) {
|
|
return true;
|
|
} else if (slimDOMOptions.headMetaAuthorship && (lowerIfExists(sn.attributes.name) === "author" || lowerIfExists(sn.attributes.name) === "generator" || lowerIfExists(sn.attributes.name) === "framework" || lowerIfExists(sn.attributes.name) === "publisher" || lowerIfExists(sn.attributes.name) === "progid" || lowerIfExists(sn.attributes.property).match(/^article:/) || lowerIfExists(sn.attributes.property).match(/^product:/))) {
|
|
return true;
|
|
} else if (slimDOMOptions.headMetaVerification && (lowerIfExists(sn.attributes.name) === "google-site-verification" || lowerIfExists(sn.attributes.name) === "yandex-verification" || lowerIfExists(sn.attributes.name) === "csrf-token" || lowerIfExists(sn.attributes.name) === "p:domain_verify" || lowerIfExists(sn.attributes.name) === "verify-v1" || lowerIfExists(sn.attributes.name) === "verification" || lowerIfExists(sn.attributes.name) === "shopify-checkout-api-token")) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
function serializeNodeWithId(n2, options) {
|
|
const {
|
|
doc,
|
|
mirror: mirror2,
|
|
blockClass,
|
|
blockSelector,
|
|
maskTextClass,
|
|
maskTextSelector,
|
|
skipChild = false,
|
|
inlineStylesheet = true,
|
|
maskInputOptions = {},
|
|
maskTextFn,
|
|
maskInputFn,
|
|
slimDOMOptions,
|
|
dataURLOptions = {},
|
|
inlineImages = false,
|
|
recordCanvas = false,
|
|
onSerialize,
|
|
onIframeLoad,
|
|
iframeLoadTimeout = 5e3,
|
|
onStylesheetLoad,
|
|
stylesheetLoadTimeout = 5e3,
|
|
keepIframeSrcFn = () => false,
|
|
newlyAddedElement = false,
|
|
cssCaptured = false
|
|
} = options;
|
|
let { needsMask } = options;
|
|
let { preserveWhiteSpace = true } = options;
|
|
if (!needsMask) {
|
|
const checkAncestors = needsMask === void 0;
|
|
needsMask = needMaskingText(
|
|
n2,
|
|
maskTextClass,
|
|
maskTextSelector,
|
|
checkAncestors
|
|
);
|
|
}
|
|
const _serializedNode = serializeNode(n2, {
|
|
doc,
|
|
mirror: mirror2,
|
|
blockClass,
|
|
blockSelector,
|
|
needsMask,
|
|
inlineStylesheet,
|
|
maskInputOptions,
|
|
maskTextFn,
|
|
maskInputFn,
|
|
dataURLOptions,
|
|
inlineImages,
|
|
recordCanvas,
|
|
keepIframeSrcFn,
|
|
newlyAddedElement,
|
|
cssCaptured
|
|
});
|
|
if (!_serializedNode) {
|
|
console.warn(n2, "not serialized");
|
|
return null;
|
|
}
|
|
let id;
|
|
if (mirror2.hasNode(n2)) {
|
|
id = mirror2.getId(n2);
|
|
} else if (slimDOMExcluded(_serializedNode, slimDOMOptions) || !preserveWhiteSpace && _serializedNode.type === NodeType$3.Text && !_serializedNode.textContent.replace(/^\s+|\s+$/gm, "").length) {
|
|
id = IGNORED_NODE;
|
|
} else {
|
|
id = genId();
|
|
}
|
|
const serializedNode = Object.assign(_serializedNode, { id });
|
|
mirror2.add(n2, serializedNode);
|
|
if (id === IGNORED_NODE) {
|
|
return null;
|
|
}
|
|
if (onSerialize) {
|
|
onSerialize(n2);
|
|
}
|
|
let recordChild = !skipChild;
|
|
if (serializedNode.type === NodeType$3.Element) {
|
|
recordChild = recordChild && !serializedNode.needBlock;
|
|
delete serializedNode.needBlock;
|
|
const shadowRootEl = index$1.shadowRoot(n2);
|
|
if (shadowRootEl && isNativeShadowDom(shadowRootEl))
|
|
serializedNode.isShadowHost = true;
|
|
}
|
|
if ((serializedNode.type === NodeType$3.Document || serializedNode.type === NodeType$3.Element) && recordChild) {
|
|
if (slimDOMOptions.headWhitespace && serializedNode.type === NodeType$3.Element && serializedNode.tagName === "head") {
|
|
preserveWhiteSpace = false;
|
|
}
|
|
const bypassOptions = {
|
|
doc,
|
|
mirror: mirror2,
|
|
blockClass,
|
|
blockSelector,
|
|
needsMask,
|
|
maskTextClass,
|
|
maskTextSelector,
|
|
skipChild,
|
|
inlineStylesheet,
|
|
maskInputOptions,
|
|
maskTextFn,
|
|
maskInputFn,
|
|
slimDOMOptions,
|
|
dataURLOptions,
|
|
inlineImages,
|
|
recordCanvas,
|
|
preserveWhiteSpace,
|
|
onSerialize,
|
|
onIframeLoad,
|
|
iframeLoadTimeout,
|
|
onStylesheetLoad,
|
|
stylesheetLoadTimeout,
|
|
keepIframeSrcFn,
|
|
cssCaptured: false
|
|
};
|
|
if (serializedNode.type === NodeType$3.Element && serializedNode.tagName === "textarea" && serializedNode.attributes.value !== void 0) ;
|
|
else {
|
|
if (serializedNode.type === NodeType$3.Element && serializedNode.attributes._cssText !== void 0 && typeof serializedNode.attributes._cssText === "string") {
|
|
bypassOptions.cssCaptured = true;
|
|
}
|
|
for (const childN of Array.from(index$1.childNodes(n2))) {
|
|
const serializedChildNode = serializeNodeWithId(childN, bypassOptions);
|
|
if (serializedChildNode) {
|
|
serializedNode.childNodes.push(serializedChildNode);
|
|
}
|
|
}
|
|
}
|
|
let shadowRootEl = null;
|
|
if (isElement(n2) && (shadowRootEl = index$1.shadowRoot(n2))) {
|
|
for (const childN of Array.from(index$1.childNodes(shadowRootEl))) {
|
|
const serializedChildNode = serializeNodeWithId(childN, bypassOptions);
|
|
if (serializedChildNode) {
|
|
isNativeShadowDom(shadowRootEl) && (serializedChildNode.isShadow = true);
|
|
serializedNode.childNodes.push(serializedChildNode);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
const parent = index$1.parentNode(n2);
|
|
if (parent && isShadowRoot(parent) && isNativeShadowDom(parent)) {
|
|
serializedNode.isShadow = true;
|
|
}
|
|
if (serializedNode.type === NodeType$3.Element && serializedNode.tagName === "iframe") {
|
|
onceIframeLoaded(
|
|
n2,
|
|
() => {
|
|
const iframeDoc = n2.contentDocument;
|
|
if (iframeDoc && onIframeLoad) {
|
|
const serializedIframeNode = serializeNodeWithId(iframeDoc, {
|
|
doc: iframeDoc,
|
|
mirror: mirror2,
|
|
blockClass,
|
|
blockSelector,
|
|
needsMask,
|
|
maskTextClass,
|
|
maskTextSelector,
|
|
skipChild: false,
|
|
inlineStylesheet,
|
|
maskInputOptions,
|
|
maskTextFn,
|
|
maskInputFn,
|
|
slimDOMOptions,
|
|
dataURLOptions,
|
|
inlineImages,
|
|
recordCanvas,
|
|
preserveWhiteSpace,
|
|
onSerialize,
|
|
onIframeLoad,
|
|
iframeLoadTimeout,
|
|
onStylesheetLoad,
|
|
stylesheetLoadTimeout,
|
|
keepIframeSrcFn
|
|
});
|
|
if (serializedIframeNode) {
|
|
onIframeLoad(
|
|
n2,
|
|
serializedIframeNode
|
|
);
|
|
}
|
|
}
|
|
},
|
|
iframeLoadTimeout
|
|
);
|
|
}
|
|
if (serializedNode.type === NodeType$3.Element && serializedNode.tagName === "link" && typeof serializedNode.attributes.rel === "string" && (serializedNode.attributes.rel === "stylesheet" || serializedNode.attributes.rel === "preload" && typeof serializedNode.attributes.href === "string" && extractFileExtension(serializedNode.attributes.href) === "css")) {
|
|
onceStylesheetLoaded(
|
|
n2,
|
|
() => {
|
|
if (onStylesheetLoad) {
|
|
const serializedLinkNode = serializeNodeWithId(n2, {
|
|
doc,
|
|
mirror: mirror2,
|
|
blockClass,
|
|
blockSelector,
|
|
needsMask,
|
|
maskTextClass,
|
|
maskTextSelector,
|
|
skipChild: false,
|
|
inlineStylesheet,
|
|
maskInputOptions,
|
|
maskTextFn,
|
|
maskInputFn,
|
|
slimDOMOptions,
|
|
dataURLOptions,
|
|
inlineImages,
|
|
recordCanvas,
|
|
preserveWhiteSpace,
|
|
onSerialize,
|
|
onIframeLoad,
|
|
iframeLoadTimeout,
|
|
onStylesheetLoad,
|
|
stylesheetLoadTimeout,
|
|
keepIframeSrcFn
|
|
});
|
|
if (serializedLinkNode) {
|
|
onStylesheetLoad(
|
|
n2,
|
|
serializedLinkNode
|
|
);
|
|
}
|
|
}
|
|
},
|
|
stylesheetLoadTimeout
|
|
);
|
|
}
|
|
return serializedNode;
|
|
}
|
|
function snapshot(n2, options) {
|
|
const {
|
|
mirror: mirror2 = new Mirror(),
|
|
blockClass = "rr-block",
|
|
blockSelector = null,
|
|
maskTextClass = "rr-mask",
|
|
maskTextSelector = null,
|
|
inlineStylesheet = true,
|
|
inlineImages = false,
|
|
recordCanvas = false,
|
|
maskAllInputs = false,
|
|
maskTextFn,
|
|
maskInputFn,
|
|
slimDOM = false,
|
|
dataURLOptions,
|
|
preserveWhiteSpace,
|
|
onSerialize,
|
|
onIframeLoad,
|
|
iframeLoadTimeout,
|
|
onStylesheetLoad,
|
|
stylesheetLoadTimeout,
|
|
keepIframeSrcFn = () => false
|
|
} = options;
|
|
const maskInputOptions = maskAllInputs === true ? {
|
|
color: true,
|
|
date: true,
|
|
"datetime-local": true,
|
|
email: true,
|
|
month: true,
|
|
number: true,
|
|
range: true,
|
|
search: true,
|
|
tel: true,
|
|
text: true,
|
|
time: true,
|
|
url: true,
|
|
week: true,
|
|
textarea: true,
|
|
select: true,
|
|
password: true
|
|
} : maskAllInputs === false ? {
|
|
password: true
|
|
} : maskAllInputs;
|
|
const slimDOMOptions = slimDOMDefaults(slimDOM);
|
|
return serializeNodeWithId(n2, {
|
|
doc: n2,
|
|
mirror: mirror2,
|
|
blockClass,
|
|
blockSelector,
|
|
maskTextClass,
|
|
maskTextSelector,
|
|
skipChild: false,
|
|
inlineStylesheet,
|
|
maskInputOptions,
|
|
maskTextFn,
|
|
maskInputFn,
|
|
slimDOMOptions,
|
|
dataURLOptions,
|
|
inlineImages,
|
|
recordCanvas,
|
|
preserveWhiteSpace,
|
|
onSerialize,
|
|
onIframeLoad,
|
|
iframeLoadTimeout,
|
|
onStylesheetLoad,
|
|
stylesheetLoadTimeout,
|
|
keepIframeSrcFn,
|
|
newlyAddedElement: false
|
|
});
|
|
}
|
|
function getDefaultExportFromCjs$1(x) {
|
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
|
|
}
|
|
function getAugmentedNamespace$1(n2) {
|
|
if (n2.__esModule) return n2;
|
|
var f2 = n2.default;
|
|
if (typeof f2 == "function") {
|
|
var a2 = function a22() {
|
|
if (this instanceof a22) {
|
|
return Reflect.construct(f2, arguments, this.constructor);
|
|
}
|
|
return f2.apply(this, arguments);
|
|
};
|
|
a2.prototype = f2.prototype;
|
|
} else a2 = {};
|
|
Object.defineProperty(a2, "__esModule", { value: true });
|
|
Object.keys(n2).forEach(function(k) {
|
|
var d = Object.getOwnPropertyDescriptor(n2, k);
|
|
Object.defineProperty(a2, k, d.get ? d : {
|
|
enumerable: true,
|
|
get: function() {
|
|
return n2[k];
|
|
}
|
|
});
|
|
});
|
|
return a2;
|
|
}
|
|
var picocolors_browser$1 = { exports: {} };
|
|
var hasRequiredPicocolors_browser$1;
|
|
function requirePicocolors_browser$1() {
|
|
if (hasRequiredPicocolors_browser$1) return picocolors_browser$1.exports;
|
|
hasRequiredPicocolors_browser$1 = 1;
|
|
var x = String;
|
|
var create = function() {
|
|
return { isColorSupported: false, reset: x, bold: x, dim: x, italic: x, underline: x, inverse: x, hidden: x, strikethrough: x, black: x, red: x, green: x, yellow: x, blue: x, magenta: x, cyan: x, white: x, gray: x, bgBlack: x, bgRed: x, bgGreen: x, bgYellow: x, bgBlue: x, bgMagenta: x, bgCyan: x, bgWhite: x };
|
|
};
|
|
picocolors_browser$1.exports = create();
|
|
picocolors_browser$1.exports.createColors = create;
|
|
return picocolors_browser$1.exports;
|
|
}
|
|
const __viteBrowserExternal$2 = {};
|
|
const __viteBrowserExternal$1$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
__proto__: null,
|
|
default: __viteBrowserExternal$2
|
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
const require$$2$1 = /* @__PURE__ */ getAugmentedNamespace$1(__viteBrowserExternal$1$1);
|
|
var cssSyntaxError$1;
|
|
var hasRequiredCssSyntaxError$1;
|
|
function requireCssSyntaxError$1() {
|
|
if (hasRequiredCssSyntaxError$1) return cssSyntaxError$1;
|
|
hasRequiredCssSyntaxError$1 = 1;
|
|
let pico = /* @__PURE__ */ requirePicocolors_browser$1();
|
|
let terminalHighlight = require$$2$1;
|
|
class CssSyntaxError extends Error {
|
|
constructor(message, line, column, source, file, plugin) {
|
|
super(message);
|
|
this.name = "CssSyntaxError";
|
|
this.reason = message;
|
|
if (file) {
|
|
this.file = file;
|
|
}
|
|
if (source) {
|
|
this.source = source;
|
|
}
|
|
if (plugin) {
|
|
this.plugin = plugin;
|
|
}
|
|
if (typeof line !== "undefined" && typeof column !== "undefined") {
|
|
if (typeof line === "number") {
|
|
this.line = line;
|
|
this.column = column;
|
|
} else {
|
|
this.line = line.line;
|
|
this.column = line.column;
|
|
this.endLine = column.line;
|
|
this.endColumn = column.column;
|
|
}
|
|
}
|
|
this.setMessage();
|
|
if (Error.captureStackTrace) {
|
|
Error.captureStackTrace(this, CssSyntaxError);
|
|
}
|
|
}
|
|
setMessage() {
|
|
this.message = this.plugin ? this.plugin + ": " : "";
|
|
this.message += this.file ? this.file : "<css input>";
|
|
if (typeof this.line !== "undefined") {
|
|
this.message += ":" + this.line + ":" + this.column;
|
|
}
|
|
this.message += ": " + this.reason;
|
|
}
|
|
showSourceCode(color) {
|
|
if (!this.source) return "";
|
|
let css = this.source;
|
|
if (color == null) color = pico.isColorSupported;
|
|
if (terminalHighlight) {
|
|
if (color) css = terminalHighlight(css);
|
|
}
|
|
let lines = css.split(/\r?\n/);
|
|
let start = Math.max(this.line - 3, 0);
|
|
let end = Math.min(this.line + 2, lines.length);
|
|
let maxWidth = String(end).length;
|
|
let mark, aside;
|
|
if (color) {
|
|
let { bold, gray, red } = pico.createColors(true);
|
|
mark = (text) => bold(red(text));
|
|
aside = (text) => gray(text);
|
|
} else {
|
|
mark = aside = (str) => str;
|
|
}
|
|
return lines.slice(start, end).map((line, index2) => {
|
|
let number = start + 1 + index2;
|
|
let gutter = " " + (" " + number).slice(-maxWidth) + " | ";
|
|
if (number === this.line) {
|
|
let spacing = aside(gutter.replace(/\d/g, " ")) + line.slice(0, this.column - 1).replace(/[^\t]/g, " ");
|
|
return mark(">") + aside(gutter) + line + "\n " + spacing + mark("^");
|
|
}
|
|
return " " + aside(gutter) + line;
|
|
}).join("\n");
|
|
}
|
|
toString() {
|
|
let code = this.showSourceCode();
|
|
if (code) {
|
|
code = "\n\n" + code + "\n";
|
|
}
|
|
return this.name + ": " + this.message + code;
|
|
}
|
|
}
|
|
cssSyntaxError$1 = CssSyntaxError;
|
|
CssSyntaxError.default = CssSyntaxError;
|
|
return cssSyntaxError$1;
|
|
}
|
|
var symbols$1 = {};
|
|
var hasRequiredSymbols$1;
|
|
function requireSymbols$1() {
|
|
if (hasRequiredSymbols$1) return symbols$1;
|
|
hasRequiredSymbols$1 = 1;
|
|
symbols$1.isClean = Symbol("isClean");
|
|
symbols$1.my = Symbol("my");
|
|
return symbols$1;
|
|
}
|
|
var stringifier$1;
|
|
var hasRequiredStringifier$1;
|
|
function requireStringifier$1() {
|
|
if (hasRequiredStringifier$1) return stringifier$1;
|
|
hasRequiredStringifier$1 = 1;
|
|
const DEFAULT_RAW = {
|
|
after: "\n",
|
|
beforeClose: "\n",
|
|
beforeComment: "\n",
|
|
beforeDecl: "\n",
|
|
beforeOpen: " ",
|
|
beforeRule: "\n",
|
|
colon: ": ",
|
|
commentLeft: " ",
|
|
commentRight: " ",
|
|
emptyBody: "",
|
|
indent: " ",
|
|
semicolon: false
|
|
};
|
|
function capitalize(str) {
|
|
return str[0].toUpperCase() + str.slice(1);
|
|
}
|
|
class Stringifier {
|
|
constructor(builder) {
|
|
this.builder = builder;
|
|
}
|
|
atrule(node2, semicolon) {
|
|
let name = "@" + node2.name;
|
|
let params = node2.params ? this.rawValue(node2, "params") : "";
|
|
if (typeof node2.raws.afterName !== "undefined") {
|
|
name += node2.raws.afterName;
|
|
} else if (params) {
|
|
name += " ";
|
|
}
|
|
if (node2.nodes) {
|
|
this.block(node2, name + params);
|
|
} else {
|
|
let end = (node2.raws.between || "") + (semicolon ? ";" : "");
|
|
this.builder(name + params + end, node2);
|
|
}
|
|
}
|
|
beforeAfter(node2, detect) {
|
|
let value;
|
|
if (node2.type === "decl") {
|
|
value = this.raw(node2, null, "beforeDecl");
|
|
} else if (node2.type === "comment") {
|
|
value = this.raw(node2, null, "beforeComment");
|
|
} else if (detect === "before") {
|
|
value = this.raw(node2, null, "beforeRule");
|
|
} else {
|
|
value = this.raw(node2, null, "beforeClose");
|
|
}
|
|
let buf = node2.parent;
|
|
let depth = 0;
|
|
while (buf && buf.type !== "root") {
|
|
depth += 1;
|
|
buf = buf.parent;
|
|
}
|
|
if (value.includes("\n")) {
|
|
let indent = this.raw(node2, null, "indent");
|
|
if (indent.length) {
|
|
for (let step = 0; step < depth; step++) value += indent;
|
|
}
|
|
}
|
|
return value;
|
|
}
|
|
block(node2, start) {
|
|
let between = this.raw(node2, "between", "beforeOpen");
|
|
this.builder(start + between + "{", node2, "start");
|
|
let after;
|
|
if (node2.nodes && node2.nodes.length) {
|
|
this.body(node2);
|
|
after = this.raw(node2, "after");
|
|
} else {
|
|
after = this.raw(node2, "after", "emptyBody");
|
|
}
|
|
if (after) this.builder(after);
|
|
this.builder("}", node2, "end");
|
|
}
|
|
body(node2) {
|
|
let last = node2.nodes.length - 1;
|
|
while (last > 0) {
|
|
if (node2.nodes[last].type !== "comment") break;
|
|
last -= 1;
|
|
}
|
|
let semicolon = this.raw(node2, "semicolon");
|
|
for (let i2 = 0; i2 < node2.nodes.length; i2++) {
|
|
let child = node2.nodes[i2];
|
|
let before = this.raw(child, "before");
|
|
if (before) this.builder(before);
|
|
this.stringify(child, last !== i2 || semicolon);
|
|
}
|
|
}
|
|
comment(node2) {
|
|
let left = this.raw(node2, "left", "commentLeft");
|
|
let right = this.raw(node2, "right", "commentRight");
|
|
this.builder("/*" + left + node2.text + right + "*/", node2);
|
|
}
|
|
decl(node2, semicolon) {
|
|
let between = this.raw(node2, "between", "colon");
|
|
let string = node2.prop + between + this.rawValue(node2, "value");
|
|
if (node2.important) {
|
|
string += node2.raws.important || " !important";
|
|
}
|
|
if (semicolon) string += ";";
|
|
this.builder(string, node2);
|
|
}
|
|
document(node2) {
|
|
this.body(node2);
|
|
}
|
|
raw(node2, own, detect) {
|
|
let value;
|
|
if (!detect) detect = own;
|
|
if (own) {
|
|
value = node2.raws[own];
|
|
if (typeof value !== "undefined") return value;
|
|
}
|
|
let parent = node2.parent;
|
|
if (detect === "before") {
|
|
if (!parent || parent.type === "root" && parent.first === node2) {
|
|
return "";
|
|
}
|
|
if (parent && parent.type === "document") {
|
|
return "";
|
|
}
|
|
}
|
|
if (!parent) return DEFAULT_RAW[detect];
|
|
let root2 = node2.root();
|
|
if (!root2.rawCache) root2.rawCache = {};
|
|
if (typeof root2.rawCache[detect] !== "undefined") {
|
|
return root2.rawCache[detect];
|
|
}
|
|
if (detect === "before" || detect === "after") {
|
|
return this.beforeAfter(node2, detect);
|
|
} else {
|
|
let method = "raw" + capitalize(detect);
|
|
if (this[method]) {
|
|
value = this[method](root2, node2);
|
|
} else {
|
|
root2.walk((i2) => {
|
|
value = i2.raws[own];
|
|
if (typeof value !== "undefined") return false;
|
|
});
|
|
}
|
|
}
|
|
if (typeof value === "undefined") value = DEFAULT_RAW[detect];
|
|
root2.rawCache[detect] = value;
|
|
return value;
|
|
}
|
|
rawBeforeClose(root2) {
|
|
let value;
|
|
root2.walk((i2) => {
|
|
if (i2.nodes && i2.nodes.length > 0) {
|
|
if (typeof i2.raws.after !== "undefined") {
|
|
value = i2.raws.after;
|
|
if (value.includes("\n")) {
|
|
value = value.replace(/[^\n]+$/, "");
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
});
|
|
if (value) value = value.replace(/\S/g, "");
|
|
return value;
|
|
}
|
|
rawBeforeComment(root2, node2) {
|
|
let value;
|
|
root2.walkComments((i2) => {
|
|
if (typeof i2.raws.before !== "undefined") {
|
|
value = i2.raws.before;
|
|
if (value.includes("\n")) {
|
|
value = value.replace(/[^\n]+$/, "");
|
|
}
|
|
return false;
|
|
}
|
|
});
|
|
if (typeof value === "undefined") {
|
|
value = this.raw(node2, null, "beforeDecl");
|
|
} else if (value) {
|
|
value = value.replace(/\S/g, "");
|
|
}
|
|
return value;
|
|
}
|
|
rawBeforeDecl(root2, node2) {
|
|
let value;
|
|
root2.walkDecls((i2) => {
|
|
if (typeof i2.raws.before !== "undefined") {
|
|
value = i2.raws.before;
|
|
if (value.includes("\n")) {
|
|
value = value.replace(/[^\n]+$/, "");
|
|
}
|
|
return false;
|
|
}
|
|
});
|
|
if (typeof value === "undefined") {
|
|
value = this.raw(node2, null, "beforeRule");
|
|
} else if (value) {
|
|
value = value.replace(/\S/g, "");
|
|
}
|
|
return value;
|
|
}
|
|
rawBeforeOpen(root2) {
|
|
let value;
|
|
root2.walk((i2) => {
|
|
if (i2.type !== "decl") {
|
|
value = i2.raws.between;
|
|
if (typeof value !== "undefined") return false;
|
|
}
|
|
});
|
|
return value;
|
|
}
|
|
rawBeforeRule(root2) {
|
|
let value;
|
|
root2.walk((i2) => {
|
|
if (i2.nodes && (i2.parent !== root2 || root2.first !== i2)) {
|
|
if (typeof i2.raws.before !== "undefined") {
|
|
value = i2.raws.before;
|
|
if (value.includes("\n")) {
|
|
value = value.replace(/[^\n]+$/, "");
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
});
|
|
if (value) value = value.replace(/\S/g, "");
|
|
return value;
|
|
}
|
|
rawColon(root2) {
|
|
let value;
|
|
root2.walkDecls((i2) => {
|
|
if (typeof i2.raws.between !== "undefined") {
|
|
value = i2.raws.between.replace(/[^\s:]/g, "");
|
|
return false;
|
|
}
|
|
});
|
|
return value;
|
|
}
|
|
rawEmptyBody(root2) {
|
|
let value;
|
|
root2.walk((i2) => {
|
|
if (i2.nodes && i2.nodes.length === 0) {
|
|
value = i2.raws.after;
|
|
if (typeof value !== "undefined") return false;
|
|
}
|
|
});
|
|
return value;
|
|
}
|
|
rawIndent(root2) {
|
|
if (root2.raws.indent) return root2.raws.indent;
|
|
let value;
|
|
root2.walk((i2) => {
|
|
let p = i2.parent;
|
|
if (p && p !== root2 && p.parent && p.parent === root2) {
|
|
if (typeof i2.raws.before !== "undefined") {
|
|
let parts = i2.raws.before.split("\n");
|
|
value = parts[parts.length - 1];
|
|
value = value.replace(/\S/g, "");
|
|
return false;
|
|
}
|
|
}
|
|
});
|
|
return value;
|
|
}
|
|
rawSemicolon(root2) {
|
|
let value;
|
|
root2.walk((i2) => {
|
|
if (i2.nodes && i2.nodes.length && i2.last.type === "decl") {
|
|
value = i2.raws.semicolon;
|
|
if (typeof value !== "undefined") return false;
|
|
}
|
|
});
|
|
return value;
|
|
}
|
|
rawValue(node2, prop) {
|
|
let value = node2[prop];
|
|
let raw = node2.raws[prop];
|
|
if (raw && raw.value === value) {
|
|
return raw.raw;
|
|
}
|
|
return value;
|
|
}
|
|
root(node2) {
|
|
this.body(node2);
|
|
if (node2.raws.after) this.builder(node2.raws.after);
|
|
}
|
|
rule(node2) {
|
|
this.block(node2, this.rawValue(node2, "selector"));
|
|
if (node2.raws.ownSemicolon) {
|
|
this.builder(node2.raws.ownSemicolon, node2, "end");
|
|
}
|
|
}
|
|
stringify(node2, semicolon) {
|
|
if (!this[node2.type]) {
|
|
throw new Error(
|
|
"Unknown AST node type " + node2.type + ". Maybe you need to change PostCSS stringifier."
|
|
);
|
|
}
|
|
this[node2.type](node2, semicolon);
|
|
}
|
|
}
|
|
stringifier$1 = Stringifier;
|
|
Stringifier.default = Stringifier;
|
|
return stringifier$1;
|
|
}
|
|
var stringify_1$1;
|
|
var hasRequiredStringify$1;
|
|
function requireStringify$1() {
|
|
if (hasRequiredStringify$1) return stringify_1$1;
|
|
hasRequiredStringify$1 = 1;
|
|
let Stringifier = requireStringifier$1();
|
|
function stringify(node2, builder) {
|
|
let str = new Stringifier(builder);
|
|
str.stringify(node2);
|
|
}
|
|
stringify_1$1 = stringify;
|
|
stringify.default = stringify;
|
|
return stringify_1$1;
|
|
}
|
|
var node$1;
|
|
var hasRequiredNode$1;
|
|
function requireNode$1() {
|
|
if (hasRequiredNode$1) return node$1;
|
|
hasRequiredNode$1 = 1;
|
|
let { isClean, my } = requireSymbols$1();
|
|
let CssSyntaxError = requireCssSyntaxError$1();
|
|
let Stringifier = requireStringifier$1();
|
|
let stringify = requireStringify$1();
|
|
function cloneNode(obj, parent) {
|
|
let cloned = new obj.constructor();
|
|
for (let i2 in obj) {
|
|
if (!Object.prototype.hasOwnProperty.call(obj, i2)) {
|
|
continue;
|
|
}
|
|
if (i2 === "proxyCache") continue;
|
|
let value = obj[i2];
|
|
let type = typeof value;
|
|
if (i2 === "parent" && type === "object") {
|
|
if (parent) cloned[i2] = parent;
|
|
} else if (i2 === "source") {
|
|
cloned[i2] = value;
|
|
} else if (Array.isArray(value)) {
|
|
cloned[i2] = value.map((j) => cloneNode(j, cloned));
|
|
} else {
|
|
if (type === "object" && value !== null) value = cloneNode(value);
|
|
cloned[i2] = value;
|
|
}
|
|
}
|
|
return cloned;
|
|
}
|
|
class Node2 {
|
|
constructor(defaults = {}) {
|
|
this.raws = {};
|
|
this[isClean] = false;
|
|
this[my] = true;
|
|
for (let name in defaults) {
|
|
if (name === "nodes") {
|
|
this.nodes = [];
|
|
for (let node2 of defaults[name]) {
|
|
if (typeof node2.clone === "function") {
|
|
this.append(node2.clone());
|
|
} else {
|
|
this.append(node2);
|
|
}
|
|
}
|
|
} else {
|
|
this[name] = defaults[name];
|
|
}
|
|
}
|
|
}
|
|
addToError(error) {
|
|
error.postcssNode = this;
|
|
if (error.stack && this.source && /\n\s{4}at /.test(error.stack)) {
|
|
let s2 = this.source;
|
|
error.stack = error.stack.replace(
|
|
/\n\s{4}at /,
|
|
`$&${s2.input.from}:${s2.start.line}:${s2.start.column}$&`
|
|
);
|
|
}
|
|
return error;
|
|
}
|
|
after(add) {
|
|
this.parent.insertAfter(this, add);
|
|
return this;
|
|
}
|
|
assign(overrides = {}) {
|
|
for (let name in overrides) {
|
|
this[name] = overrides[name];
|
|
}
|
|
return this;
|
|
}
|
|
before(add) {
|
|
this.parent.insertBefore(this, add);
|
|
return this;
|
|
}
|
|
cleanRaws(keepBetween) {
|
|
delete this.raws.before;
|
|
delete this.raws.after;
|
|
if (!keepBetween) delete this.raws.between;
|
|
}
|
|
clone(overrides = {}) {
|
|
let cloned = cloneNode(this);
|
|
for (let name in overrides) {
|
|
cloned[name] = overrides[name];
|
|
}
|
|
return cloned;
|
|
}
|
|
cloneAfter(overrides = {}) {
|
|
let cloned = this.clone(overrides);
|
|
this.parent.insertAfter(this, cloned);
|
|
return cloned;
|
|
}
|
|
cloneBefore(overrides = {}) {
|
|
let cloned = this.clone(overrides);
|
|
this.parent.insertBefore(this, cloned);
|
|
return cloned;
|
|
}
|
|
error(message, opts = {}) {
|
|
if (this.source) {
|
|
let { end, start } = this.rangeBy(opts);
|
|
return this.source.input.error(
|
|
message,
|
|
{ column: start.column, line: start.line },
|
|
{ column: end.column, line: end.line },
|
|
opts
|
|
);
|
|
}
|
|
return new CssSyntaxError(message);
|
|
}
|
|
getProxyProcessor() {
|
|
return {
|
|
get(node2, prop) {
|
|
if (prop === "proxyOf") {
|
|
return node2;
|
|
} else if (prop === "root") {
|
|
return () => node2.root().toProxy();
|
|
} else {
|
|
return node2[prop];
|
|
}
|
|
},
|
|
set(node2, prop, value) {
|
|
if (node2[prop] === value) return true;
|
|
node2[prop] = value;
|
|
if (prop === "prop" || prop === "value" || prop === "name" || prop === "params" || prop === "important" || /* c8 ignore next */
|
|
prop === "text") {
|
|
node2.markDirty();
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
}
|
|
markDirty() {
|
|
if (this[isClean]) {
|
|
this[isClean] = false;
|
|
let next = this;
|
|
while (next = next.parent) {
|
|
next[isClean] = false;
|
|
}
|
|
}
|
|
}
|
|
next() {
|
|
if (!this.parent) return void 0;
|
|
let index2 = this.parent.index(this);
|
|
return this.parent.nodes[index2 + 1];
|
|
}
|
|
positionBy(opts, stringRepresentation) {
|
|
let pos = this.source.start;
|
|
if (opts.index) {
|
|
pos = this.positionInside(opts.index, stringRepresentation);
|
|
} else if (opts.word) {
|
|
stringRepresentation = this.toString();
|
|
let index2 = stringRepresentation.indexOf(opts.word);
|
|
if (index2 !== -1) pos = this.positionInside(index2, stringRepresentation);
|
|
}
|
|
return pos;
|
|
}
|
|
positionInside(index2, stringRepresentation) {
|
|
let string = stringRepresentation || this.toString();
|
|
let column = this.source.start.column;
|
|
let line = this.source.start.line;
|
|
for (let i2 = 0; i2 < index2; i2++) {
|
|
if (string[i2] === "\n") {
|
|
column = 1;
|
|
line += 1;
|
|
} else {
|
|
column += 1;
|
|
}
|
|
}
|
|
return { column, line };
|
|
}
|
|
prev() {
|
|
if (!this.parent) return void 0;
|
|
let index2 = this.parent.index(this);
|
|
return this.parent.nodes[index2 - 1];
|
|
}
|
|
rangeBy(opts) {
|
|
let start = {
|
|
column: this.source.start.column,
|
|
line: this.source.start.line
|
|
};
|
|
let end = this.source.end ? {
|
|
column: this.source.end.column + 1,
|
|
line: this.source.end.line
|
|
} : {
|
|
column: start.column + 1,
|
|
line: start.line
|
|
};
|
|
if (opts.word) {
|
|
let stringRepresentation = this.toString();
|
|
let index2 = stringRepresentation.indexOf(opts.word);
|
|
if (index2 !== -1) {
|
|
start = this.positionInside(index2, stringRepresentation);
|
|
end = this.positionInside(index2 + opts.word.length, stringRepresentation);
|
|
}
|
|
} else {
|
|
if (opts.start) {
|
|
start = {
|
|
column: opts.start.column,
|
|
line: opts.start.line
|
|
};
|
|
} else if (opts.index) {
|
|
start = this.positionInside(opts.index);
|
|
}
|
|
if (opts.end) {
|
|
end = {
|
|
column: opts.end.column,
|
|
line: opts.end.line
|
|
};
|
|
} else if (typeof opts.endIndex === "number") {
|
|
end = this.positionInside(opts.endIndex);
|
|
} else if (opts.index) {
|
|
end = this.positionInside(opts.index + 1);
|
|
}
|
|
}
|
|
if (end.line < start.line || end.line === start.line && end.column <= start.column) {
|
|
end = { column: start.column + 1, line: start.line };
|
|
}
|
|
return { end, start };
|
|
}
|
|
raw(prop, defaultType) {
|
|
let str = new Stringifier();
|
|
return str.raw(this, prop, defaultType);
|
|
}
|
|
remove() {
|
|
if (this.parent) {
|
|
this.parent.removeChild(this);
|
|
}
|
|
this.parent = void 0;
|
|
return this;
|
|
}
|
|
replaceWith(...nodes) {
|
|
if (this.parent) {
|
|
let bookmark = this;
|
|
let foundSelf = false;
|
|
for (let node2 of nodes) {
|
|
if (node2 === this) {
|
|
foundSelf = true;
|
|
} else if (foundSelf) {
|
|
this.parent.insertAfter(bookmark, node2);
|
|
bookmark = node2;
|
|
} else {
|
|
this.parent.insertBefore(bookmark, node2);
|
|
}
|
|
}
|
|
if (!foundSelf) {
|
|
this.remove();
|
|
}
|
|
}
|
|
return this;
|
|
}
|
|
root() {
|
|
let result2 = this;
|
|
while (result2.parent && result2.parent.type !== "document") {
|
|
result2 = result2.parent;
|
|
}
|
|
return result2;
|
|
}
|
|
toJSON(_, inputs) {
|
|
let fixed = {};
|
|
let emitInputs = inputs == null;
|
|
inputs = inputs || /* @__PURE__ */ new Map();
|
|
let inputsNextIndex = 0;
|
|
for (let name in this) {
|
|
if (!Object.prototype.hasOwnProperty.call(this, name)) {
|
|
continue;
|
|
}
|
|
if (name === "parent" || name === "proxyCache") continue;
|
|
let value = this[name];
|
|
if (Array.isArray(value)) {
|
|
fixed[name] = value.map((i2) => {
|
|
if (typeof i2 === "object" && i2.toJSON) {
|
|
return i2.toJSON(null, inputs);
|
|
} else {
|
|
return i2;
|
|
}
|
|
});
|
|
} else if (typeof value === "object" && value.toJSON) {
|
|
fixed[name] = value.toJSON(null, inputs);
|
|
} else if (name === "source") {
|
|
let inputId = inputs.get(value.input);
|
|
if (inputId == null) {
|
|
inputId = inputsNextIndex;
|
|
inputs.set(value.input, inputsNextIndex);
|
|
inputsNextIndex++;
|
|
}
|
|
fixed[name] = {
|
|
end: value.end,
|
|
inputId,
|
|
start: value.start
|
|
};
|
|
} else {
|
|
fixed[name] = value;
|
|
}
|
|
}
|
|
if (emitInputs) {
|
|
fixed.inputs = [...inputs.keys()].map((input2) => input2.toJSON());
|
|
}
|
|
return fixed;
|
|
}
|
|
toProxy() {
|
|
if (!this.proxyCache) {
|
|
this.proxyCache = new Proxy(this, this.getProxyProcessor());
|
|
}
|
|
return this.proxyCache;
|
|
}
|
|
toString(stringifier2 = stringify) {
|
|
if (stringifier2.stringify) stringifier2 = stringifier2.stringify;
|
|
let result2 = "";
|
|
stringifier2(this, (i2) => {
|
|
result2 += i2;
|
|
});
|
|
return result2;
|
|
}
|
|
warn(result2, text, opts) {
|
|
let data = { node: this };
|
|
for (let i2 in opts) data[i2] = opts[i2];
|
|
return result2.warn(text, data);
|
|
}
|
|
get proxyOf() {
|
|
return this;
|
|
}
|
|
}
|
|
node$1 = Node2;
|
|
Node2.default = Node2;
|
|
return node$1;
|
|
}
|
|
var declaration$1;
|
|
var hasRequiredDeclaration$1;
|
|
function requireDeclaration$1() {
|
|
if (hasRequiredDeclaration$1) return declaration$1;
|
|
hasRequiredDeclaration$1 = 1;
|
|
let Node2 = requireNode$1();
|
|
class Declaration extends Node2 {
|
|
constructor(defaults) {
|
|
if (defaults && typeof defaults.value !== "undefined" && typeof defaults.value !== "string") {
|
|
defaults = __spreadProps(__spreadValues({}, defaults), { value: String(defaults.value) });
|
|
}
|
|
super(defaults);
|
|
this.type = "decl";
|
|
}
|
|
get variable() {
|
|
return this.prop.startsWith("--") || this.prop[0] === "$";
|
|
}
|
|
}
|
|
declaration$1 = Declaration;
|
|
Declaration.default = Declaration;
|
|
return declaration$1;
|
|
}
|
|
var nonSecure$1;
|
|
var hasRequiredNonSecure$1;
|
|
function requireNonSecure$1() {
|
|
if (hasRequiredNonSecure$1) return nonSecure$1;
|
|
hasRequiredNonSecure$1 = 1;
|
|
let urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
|
|
let customAlphabet = (alphabet, defaultSize = 21) => {
|
|
return (size = defaultSize) => {
|
|
let id = "";
|
|
let i2 = size;
|
|
while (i2--) {
|
|
id += alphabet[Math.random() * alphabet.length | 0];
|
|
}
|
|
return id;
|
|
};
|
|
};
|
|
let nanoid = (size = 21) => {
|
|
let id = "";
|
|
let i2 = size;
|
|
while (i2--) {
|
|
id += urlAlphabet[Math.random() * 64 | 0];
|
|
}
|
|
return id;
|
|
};
|
|
nonSecure$1 = { nanoid, customAlphabet };
|
|
return nonSecure$1;
|
|
}
|
|
var previousMap$1;
|
|
var hasRequiredPreviousMap$1;
|
|
function requirePreviousMap$1() {
|
|
if (hasRequiredPreviousMap$1) return previousMap$1;
|
|
hasRequiredPreviousMap$1 = 1;
|
|
let { SourceMapConsumer, SourceMapGenerator } = require$$2$1;
|
|
let { existsSync, readFileSync } = require$$2$1;
|
|
let { dirname, join } = require$$2$1;
|
|
function fromBase64(str) {
|
|
if (Buffer) {
|
|
return Buffer.from(str, "base64").toString();
|
|
} else {
|
|
return window.atob(str);
|
|
}
|
|
}
|
|
class PreviousMap {
|
|
constructor(css, opts) {
|
|
if (opts.map === false) return;
|
|
this.loadAnnotation(css);
|
|
this.inline = this.startWith(this.annotation, "data:");
|
|
let prev = opts.map ? opts.map.prev : void 0;
|
|
let text = this.loadMap(opts.from, prev);
|
|
if (!this.mapFile && opts.from) {
|
|
this.mapFile = opts.from;
|
|
}
|
|
if (this.mapFile) this.root = dirname(this.mapFile);
|
|
if (text) this.text = text;
|
|
}
|
|
consumer() {
|
|
if (!this.consumerCache) {
|
|
this.consumerCache = new SourceMapConsumer(this.text);
|
|
}
|
|
return this.consumerCache;
|
|
}
|
|
decodeInline(text) {
|
|
let baseCharsetUri = /^data:application\/json;charset=utf-?8;base64,/;
|
|
let baseUri = /^data:application\/json;base64,/;
|
|
let charsetUri = /^data:application\/json;charset=utf-?8,/;
|
|
let uri = /^data:application\/json,/;
|
|
if (charsetUri.test(text) || uri.test(text)) {
|
|
return decodeURIComponent(text.substr(RegExp.lastMatch.length));
|
|
}
|
|
if (baseCharsetUri.test(text) || baseUri.test(text)) {
|
|
return fromBase64(text.substr(RegExp.lastMatch.length));
|
|
}
|
|
let encoding = text.match(/data:application\/json;([^,]+),/)[1];
|
|
throw new Error("Unsupported source map encoding " + encoding);
|
|
}
|
|
getAnnotationURL(sourceMapString) {
|
|
return sourceMapString.replace(/^\/\*\s*# sourceMappingURL=/, "").trim();
|
|
}
|
|
isMap(map) {
|
|
if (typeof map !== "object") return false;
|
|
return typeof map.mappings === "string" || typeof map._mappings === "string" || Array.isArray(map.sections);
|
|
}
|
|
loadAnnotation(css) {
|
|
let comments = css.match(/\/\*\s*# sourceMappingURL=/gm);
|
|
if (!comments) return;
|
|
let start = css.lastIndexOf(comments.pop());
|
|
let end = css.indexOf("*/", start);
|
|
if (start > -1 && end > -1) {
|
|
this.annotation = this.getAnnotationURL(css.substring(start, end));
|
|
}
|
|
}
|
|
loadFile(path) {
|
|
this.root = dirname(path);
|
|
if (existsSync(path)) {
|
|
this.mapFile = path;
|
|
return readFileSync(path, "utf-8").toString().trim();
|
|
}
|
|
}
|
|
loadMap(file, prev) {
|
|
if (prev === false) return false;
|
|
if (prev) {
|
|
if (typeof prev === "string") {
|
|
return prev;
|
|
} else if (typeof prev === "function") {
|
|
let prevPath = prev(file);
|
|
if (prevPath) {
|
|
let map = this.loadFile(prevPath);
|
|
if (!map) {
|
|
throw new Error(
|
|
"Unable to load previous source map: " + prevPath.toString()
|
|
);
|
|
}
|
|
return map;
|
|
}
|
|
} else if (prev instanceof SourceMapConsumer) {
|
|
return SourceMapGenerator.fromSourceMap(prev).toString();
|
|
} else if (prev instanceof SourceMapGenerator) {
|
|
return prev.toString();
|
|
} else if (this.isMap(prev)) {
|
|
return JSON.stringify(prev);
|
|
} else {
|
|
throw new Error(
|
|
"Unsupported previous source map format: " + prev.toString()
|
|
);
|
|
}
|
|
} else if (this.inline) {
|
|
return this.decodeInline(this.annotation);
|
|
} else if (this.annotation) {
|
|
let map = this.annotation;
|
|
if (file) map = join(dirname(file), map);
|
|
return this.loadFile(map);
|
|
}
|
|
}
|
|
startWith(string, start) {
|
|
if (!string) return false;
|
|
return string.substr(0, start.length) === start;
|
|
}
|
|
withContent() {
|
|
return !!(this.consumer().sourcesContent && this.consumer().sourcesContent.length > 0);
|
|
}
|
|
}
|
|
previousMap$1 = PreviousMap;
|
|
PreviousMap.default = PreviousMap;
|
|
return previousMap$1;
|
|
}
|
|
var input$1;
|
|
var hasRequiredInput$1;
|
|
function requireInput$1() {
|
|
if (hasRequiredInput$1) return input$1;
|
|
hasRequiredInput$1 = 1;
|
|
let { SourceMapConsumer, SourceMapGenerator } = require$$2$1;
|
|
let { fileURLToPath, pathToFileURL } = require$$2$1;
|
|
let { isAbsolute, resolve } = require$$2$1;
|
|
let { nanoid } = /* @__PURE__ */ requireNonSecure$1();
|
|
let terminalHighlight = require$$2$1;
|
|
let CssSyntaxError = requireCssSyntaxError$1();
|
|
let PreviousMap = requirePreviousMap$1();
|
|
let fromOffsetCache = Symbol("fromOffsetCache");
|
|
let sourceMapAvailable = Boolean(SourceMapConsumer && SourceMapGenerator);
|
|
let pathAvailable = Boolean(resolve && isAbsolute);
|
|
class Input {
|
|
constructor(css, opts = {}) {
|
|
if (css === null || typeof css === "undefined" || typeof css === "object" && !css.toString) {
|
|
throw new Error(`PostCSS received ${css} instead of CSS string`);
|
|
}
|
|
this.css = css.toString();
|
|
if (this.css[0] === "\uFEFF" || this.css[0] === "\uFFFE") {
|
|
this.hasBOM = true;
|
|
this.css = this.css.slice(1);
|
|
} else {
|
|
this.hasBOM = false;
|
|
}
|
|
if (opts.from) {
|
|
if (!pathAvailable || /^\w+:\/\//.test(opts.from) || isAbsolute(opts.from)) {
|
|
this.file = opts.from;
|
|
} else {
|
|
this.file = resolve(opts.from);
|
|
}
|
|
}
|
|
if (pathAvailable && sourceMapAvailable) {
|
|
let map = new PreviousMap(this.css, opts);
|
|
if (map.text) {
|
|
this.map = map;
|
|
let file = map.consumer().file;
|
|
if (!this.file && file) this.file = this.mapResolve(file);
|
|
}
|
|
}
|
|
if (!this.file) {
|
|
this.id = "<input css " + nanoid(6) + ">";
|
|
}
|
|
if (this.map) this.map.file = this.from;
|
|
}
|
|
error(message, line, column, opts = {}) {
|
|
let result2, endLine, endColumn;
|
|
if (line && typeof line === "object") {
|
|
let start = line;
|
|
let end = column;
|
|
if (typeof start.offset === "number") {
|
|
let pos = this.fromOffset(start.offset);
|
|
line = pos.line;
|
|
column = pos.col;
|
|
} else {
|
|
line = start.line;
|
|
column = start.column;
|
|
}
|
|
if (typeof end.offset === "number") {
|
|
let pos = this.fromOffset(end.offset);
|
|
endLine = pos.line;
|
|
endColumn = pos.col;
|
|
} else {
|
|
endLine = end.line;
|
|
endColumn = end.column;
|
|
}
|
|
} else if (!column) {
|
|
let pos = this.fromOffset(line);
|
|
line = pos.line;
|
|
column = pos.col;
|
|
}
|
|
let origin = this.origin(line, column, endLine, endColumn);
|
|
if (origin) {
|
|
result2 = new CssSyntaxError(
|
|
message,
|
|
origin.endLine === void 0 ? origin.line : { column: origin.column, line: origin.line },
|
|
origin.endLine === void 0 ? origin.column : { column: origin.endColumn, line: origin.endLine },
|
|
origin.source,
|
|
origin.file,
|
|
opts.plugin
|
|
);
|
|
} else {
|
|
result2 = new CssSyntaxError(
|
|
message,
|
|
endLine === void 0 ? line : { column, line },
|
|
endLine === void 0 ? column : { column: endColumn, line: endLine },
|
|
this.css,
|
|
this.file,
|
|
opts.plugin
|
|
);
|
|
}
|
|
result2.input = { column, endColumn, endLine, line, source: this.css };
|
|
if (this.file) {
|
|
if (pathToFileURL) {
|
|
result2.input.url = pathToFileURL(this.file).toString();
|
|
}
|
|
result2.input.file = this.file;
|
|
}
|
|
return result2;
|
|
}
|
|
fromOffset(offset) {
|
|
let lastLine, lineToIndex;
|
|
if (!this[fromOffsetCache]) {
|
|
let lines = this.css.split("\n");
|
|
lineToIndex = new Array(lines.length);
|
|
let prevIndex = 0;
|
|
for (let i2 = 0, l2 = lines.length; i2 < l2; i2++) {
|
|
lineToIndex[i2] = prevIndex;
|
|
prevIndex += lines[i2].length + 1;
|
|
}
|
|
this[fromOffsetCache] = lineToIndex;
|
|
} else {
|
|
lineToIndex = this[fromOffsetCache];
|
|
}
|
|
lastLine = lineToIndex[lineToIndex.length - 1];
|
|
let min = 0;
|
|
if (offset >= lastLine) {
|
|
min = lineToIndex.length - 1;
|
|
} else {
|
|
let max = lineToIndex.length - 2;
|
|
let mid;
|
|
while (min < max) {
|
|
mid = min + (max - min >> 1);
|
|
if (offset < lineToIndex[mid]) {
|
|
max = mid - 1;
|
|
} else if (offset >= lineToIndex[mid + 1]) {
|
|
min = mid + 1;
|
|
} else {
|
|
min = mid;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return {
|
|
col: offset - lineToIndex[min] + 1,
|
|
line: min + 1
|
|
};
|
|
}
|
|
mapResolve(file) {
|
|
if (/^\w+:\/\//.test(file)) {
|
|
return file;
|
|
}
|
|
return resolve(this.map.consumer().sourceRoot || this.map.root || ".", file);
|
|
}
|
|
origin(line, column, endLine, endColumn) {
|
|
if (!this.map) return false;
|
|
let consumer = this.map.consumer();
|
|
let from = consumer.originalPositionFor({ column, line });
|
|
if (!from.source) return false;
|
|
let to;
|
|
if (typeof endLine === "number") {
|
|
to = consumer.originalPositionFor({ column: endColumn, line: endLine });
|
|
}
|
|
let fromUrl;
|
|
if (isAbsolute(from.source)) {
|
|
fromUrl = pathToFileURL(from.source);
|
|
} else {
|
|
fromUrl = new URL(
|
|
from.source,
|
|
this.map.consumer().sourceRoot || pathToFileURL(this.map.mapFile)
|
|
);
|
|
}
|
|
let result2 = {
|
|
column: from.column,
|
|
endColumn: to && to.column,
|
|
endLine: to && to.line,
|
|
line: from.line,
|
|
url: fromUrl.toString()
|
|
};
|
|
if (fromUrl.protocol === "file:") {
|
|
if (fileURLToPath) {
|
|
result2.file = fileURLToPath(fromUrl);
|
|
} else {
|
|
throw new Error(`file: protocol is not available in this PostCSS build`);
|
|
}
|
|
}
|
|
let source = consumer.sourceContentFor(from.source);
|
|
if (source) result2.source = source;
|
|
return result2;
|
|
}
|
|
toJSON() {
|
|
let json = {};
|
|
for (let name of ["hasBOM", "css", "file", "id"]) {
|
|
if (this[name] != null) {
|
|
json[name] = this[name];
|
|
}
|
|
}
|
|
if (this.map) {
|
|
json.map = __spreadValues({}, this.map);
|
|
if (json.map.consumerCache) {
|
|
json.map.consumerCache = void 0;
|
|
}
|
|
}
|
|
return json;
|
|
}
|
|
get from() {
|
|
return this.file || this.id;
|
|
}
|
|
}
|
|
input$1 = Input;
|
|
Input.default = Input;
|
|
if (terminalHighlight && terminalHighlight.registerInput) {
|
|
terminalHighlight.registerInput(Input);
|
|
}
|
|
return input$1;
|
|
}
|
|
var mapGenerator$1;
|
|
var hasRequiredMapGenerator$1;
|
|
function requireMapGenerator$1() {
|
|
if (hasRequiredMapGenerator$1) return mapGenerator$1;
|
|
hasRequiredMapGenerator$1 = 1;
|
|
let { SourceMapConsumer, SourceMapGenerator } = require$$2$1;
|
|
let { dirname, relative, resolve, sep } = require$$2$1;
|
|
let { pathToFileURL } = require$$2$1;
|
|
let Input = requireInput$1();
|
|
let sourceMapAvailable = Boolean(SourceMapConsumer && SourceMapGenerator);
|
|
let pathAvailable = Boolean(dirname && resolve && relative && sep);
|
|
class MapGenerator {
|
|
constructor(stringify, root2, opts, cssString) {
|
|
this.stringify = stringify;
|
|
this.mapOpts = opts.map || {};
|
|
this.root = root2;
|
|
this.opts = opts;
|
|
this.css = cssString;
|
|
this.originalCSS = cssString;
|
|
this.usesFileUrls = !this.mapOpts.from && this.mapOpts.absolute;
|
|
this.memoizedFileURLs = /* @__PURE__ */ new Map();
|
|
this.memoizedPaths = /* @__PURE__ */ new Map();
|
|
this.memoizedURLs = /* @__PURE__ */ new Map();
|
|
}
|
|
addAnnotation() {
|
|
let content;
|
|
if (this.isInline()) {
|
|
content = "data:application/json;base64," + this.toBase64(this.map.toString());
|
|
} else if (typeof this.mapOpts.annotation === "string") {
|
|
content = this.mapOpts.annotation;
|
|
} else if (typeof this.mapOpts.annotation === "function") {
|
|
content = this.mapOpts.annotation(this.opts.to, this.root);
|
|
} else {
|
|
content = this.outputFile() + ".map";
|
|
}
|
|
let eol = "\n";
|
|
if (this.css.includes("\r\n")) eol = "\r\n";
|
|
this.css += eol + "/*# sourceMappingURL=" + content + " */";
|
|
}
|
|
applyPrevMaps() {
|
|
for (let prev of this.previous()) {
|
|
let from = this.toUrl(this.path(prev.file));
|
|
let root2 = prev.root || dirname(prev.file);
|
|
let map;
|
|
if (this.mapOpts.sourcesContent === false) {
|
|
map = new SourceMapConsumer(prev.text);
|
|
if (map.sourcesContent) {
|
|
map.sourcesContent = null;
|
|
}
|
|
} else {
|
|
map = prev.consumer();
|
|
}
|
|
this.map.applySourceMap(map, from, this.toUrl(this.path(root2)));
|
|
}
|
|
}
|
|
clearAnnotation() {
|
|
if (this.mapOpts.annotation === false) return;
|
|
if (this.root) {
|
|
let node2;
|
|
for (let i2 = this.root.nodes.length - 1; i2 >= 0; i2--) {
|
|
node2 = this.root.nodes[i2];
|
|
if (node2.type !== "comment") continue;
|
|
if (node2.text.indexOf("# sourceMappingURL=") === 0) {
|
|
this.root.removeChild(i2);
|
|
}
|
|
}
|
|
} else if (this.css) {
|
|
this.css = this.css.replace(/\n*?\/\*#[\S\s]*?\*\/$/gm, "");
|
|
}
|
|
}
|
|
generate() {
|
|
this.clearAnnotation();
|
|
if (pathAvailable && sourceMapAvailable && this.isMap()) {
|
|
return this.generateMap();
|
|
} else {
|
|
let result2 = "";
|
|
this.stringify(this.root, (i2) => {
|
|
result2 += i2;
|
|
});
|
|
return [result2];
|
|
}
|
|
}
|
|
generateMap() {
|
|
if (this.root) {
|
|
this.generateString();
|
|
} else if (this.previous().length === 1) {
|
|
let prev = this.previous()[0].consumer();
|
|
prev.file = this.outputFile();
|
|
this.map = SourceMapGenerator.fromSourceMap(prev, {
|
|
ignoreInvalidMapping: true
|
|
});
|
|
} else {
|
|
this.map = new SourceMapGenerator({
|
|
file: this.outputFile(),
|
|
ignoreInvalidMapping: true
|
|
});
|
|
this.map.addMapping({
|
|
generated: { column: 0, line: 1 },
|
|
original: { column: 0, line: 1 },
|
|
source: this.opts.from ? this.toUrl(this.path(this.opts.from)) : "<no source>"
|
|
});
|
|
}
|
|
if (this.isSourcesContent()) this.setSourcesContent();
|
|
if (this.root && this.previous().length > 0) this.applyPrevMaps();
|
|
if (this.isAnnotation()) this.addAnnotation();
|
|
if (this.isInline()) {
|
|
return [this.css];
|
|
} else {
|
|
return [this.css, this.map];
|
|
}
|
|
}
|
|
generateString() {
|
|
this.css = "";
|
|
this.map = new SourceMapGenerator({
|
|
file: this.outputFile(),
|
|
ignoreInvalidMapping: true
|
|
});
|
|
let line = 1;
|
|
let column = 1;
|
|
let noSource = "<no source>";
|
|
let mapping = {
|
|
generated: { column: 0, line: 0 },
|
|
original: { column: 0, line: 0 },
|
|
source: ""
|
|
};
|
|
let lines, last;
|
|
this.stringify(this.root, (str, node2, type) => {
|
|
this.css += str;
|
|
if (node2 && type !== "end") {
|
|
mapping.generated.line = line;
|
|
mapping.generated.column = column - 1;
|
|
if (node2.source && node2.source.start) {
|
|
mapping.source = this.sourcePath(node2);
|
|
mapping.original.line = node2.source.start.line;
|
|
mapping.original.column = node2.source.start.column - 1;
|
|
this.map.addMapping(mapping);
|
|
} else {
|
|
mapping.source = noSource;
|
|
mapping.original.line = 1;
|
|
mapping.original.column = 0;
|
|
this.map.addMapping(mapping);
|
|
}
|
|
}
|
|
lines = str.match(/\n/g);
|
|
if (lines) {
|
|
line += lines.length;
|
|
last = str.lastIndexOf("\n");
|
|
column = str.length - last;
|
|
} else {
|
|
column += str.length;
|
|
}
|
|
if (node2 && type !== "start") {
|
|
let p = node2.parent || { raws: {} };
|
|
let childless = node2.type === "decl" || node2.type === "atrule" && !node2.nodes;
|
|
if (!childless || node2 !== p.last || p.raws.semicolon) {
|
|
if (node2.source && node2.source.end) {
|
|
mapping.source = this.sourcePath(node2);
|
|
mapping.original.line = node2.source.end.line;
|
|
mapping.original.column = node2.source.end.column - 1;
|
|
mapping.generated.line = line;
|
|
mapping.generated.column = column - 2;
|
|
this.map.addMapping(mapping);
|
|
} else {
|
|
mapping.source = noSource;
|
|
mapping.original.line = 1;
|
|
mapping.original.column = 0;
|
|
mapping.generated.line = line;
|
|
mapping.generated.column = column - 1;
|
|
this.map.addMapping(mapping);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
isAnnotation() {
|
|
if (this.isInline()) {
|
|
return true;
|
|
}
|
|
if (typeof this.mapOpts.annotation !== "undefined") {
|
|
return this.mapOpts.annotation;
|
|
}
|
|
if (this.previous().length) {
|
|
return this.previous().some((i2) => i2.annotation);
|
|
}
|
|
return true;
|
|
}
|
|
isInline() {
|
|
if (typeof this.mapOpts.inline !== "undefined") {
|
|
return this.mapOpts.inline;
|
|
}
|
|
let annotation = this.mapOpts.annotation;
|
|
if (typeof annotation !== "undefined" && annotation !== true) {
|
|
return false;
|
|
}
|
|
if (this.previous().length) {
|
|
return this.previous().some((i2) => i2.inline);
|
|
}
|
|
return true;
|
|
}
|
|
isMap() {
|
|
if (typeof this.opts.map !== "undefined") {
|
|
return !!this.opts.map;
|
|
}
|
|
return this.previous().length > 0;
|
|
}
|
|
isSourcesContent() {
|
|
if (typeof this.mapOpts.sourcesContent !== "undefined") {
|
|
return this.mapOpts.sourcesContent;
|
|
}
|
|
if (this.previous().length) {
|
|
return this.previous().some((i2) => i2.withContent());
|
|
}
|
|
return true;
|
|
}
|
|
outputFile() {
|
|
if (this.opts.to) {
|
|
return this.path(this.opts.to);
|
|
} else if (this.opts.from) {
|
|
return this.path(this.opts.from);
|
|
} else {
|
|
return "to.css";
|
|
}
|
|
}
|
|
path(file) {
|
|
if (this.mapOpts.absolute) return file;
|
|
if (file.charCodeAt(0) === 60) return file;
|
|
if (/^\w+:\/\//.test(file)) return file;
|
|
let cached = this.memoizedPaths.get(file);
|
|
if (cached) return cached;
|
|
let from = this.opts.to ? dirname(this.opts.to) : ".";
|
|
if (typeof this.mapOpts.annotation === "string") {
|
|
from = dirname(resolve(from, this.mapOpts.annotation));
|
|
}
|
|
let path = relative(from, file);
|
|
this.memoizedPaths.set(file, path);
|
|
return path;
|
|
}
|
|
previous() {
|
|
if (!this.previousMaps) {
|
|
this.previousMaps = [];
|
|
if (this.root) {
|
|
this.root.walk((node2) => {
|
|
if (node2.source && node2.source.input.map) {
|
|
let map = node2.source.input.map;
|
|
if (!this.previousMaps.includes(map)) {
|
|
this.previousMaps.push(map);
|
|
}
|
|
}
|
|
});
|
|
} else {
|
|
let input2 = new Input(this.originalCSS, this.opts);
|
|
if (input2.map) this.previousMaps.push(input2.map);
|
|
}
|
|
}
|
|
return this.previousMaps;
|
|
}
|
|
setSourcesContent() {
|
|
let already = {};
|
|
if (this.root) {
|
|
this.root.walk((node2) => {
|
|
if (node2.source) {
|
|
let from = node2.source.input.from;
|
|
if (from && !already[from]) {
|
|
already[from] = true;
|
|
let fromUrl = this.usesFileUrls ? this.toFileUrl(from) : this.toUrl(this.path(from));
|
|
this.map.setSourceContent(fromUrl, node2.source.input.css);
|
|
}
|
|
}
|
|
});
|
|
} else if (this.css) {
|
|
let from = this.opts.from ? this.toUrl(this.path(this.opts.from)) : "<no source>";
|
|
this.map.setSourceContent(from, this.css);
|
|
}
|
|
}
|
|
sourcePath(node2) {
|
|
if (this.mapOpts.from) {
|
|
return this.toUrl(this.mapOpts.from);
|
|
} else if (this.usesFileUrls) {
|
|
return this.toFileUrl(node2.source.input.from);
|
|
} else {
|
|
return this.toUrl(this.path(node2.source.input.from));
|
|
}
|
|
}
|
|
toBase64(str) {
|
|
if (Buffer) {
|
|
return Buffer.from(str).toString("base64");
|
|
} else {
|
|
return window.btoa(unescape(encodeURIComponent(str)));
|
|
}
|
|
}
|
|
toFileUrl(path) {
|
|
let cached = this.memoizedFileURLs.get(path);
|
|
if (cached) return cached;
|
|
if (pathToFileURL) {
|
|
let fileURL = pathToFileURL(path).toString();
|
|
this.memoizedFileURLs.set(path, fileURL);
|
|
return fileURL;
|
|
} else {
|
|
throw new Error(
|
|
"`map.absolute` option is not available in this PostCSS build"
|
|
);
|
|
}
|
|
}
|
|
toUrl(path) {
|
|
let cached = this.memoizedURLs.get(path);
|
|
if (cached) return cached;
|
|
if (sep === "\\") {
|
|
path = path.replace(/\\/g, "/");
|
|
}
|
|
let url = encodeURI(path).replace(/[#?]/g, encodeURIComponent);
|
|
this.memoizedURLs.set(path, url);
|
|
return url;
|
|
}
|
|
}
|
|
mapGenerator$1 = MapGenerator;
|
|
return mapGenerator$1;
|
|
}
|
|
var comment$1;
|
|
var hasRequiredComment$1;
|
|
function requireComment$1() {
|
|
if (hasRequiredComment$1) return comment$1;
|
|
hasRequiredComment$1 = 1;
|
|
let Node2 = requireNode$1();
|
|
class Comment extends Node2 {
|
|
constructor(defaults) {
|
|
super(defaults);
|
|
this.type = "comment";
|
|
}
|
|
}
|
|
comment$1 = Comment;
|
|
Comment.default = Comment;
|
|
return comment$1;
|
|
}
|
|
var container$1;
|
|
var hasRequiredContainer$1;
|
|
function requireContainer$1() {
|
|
if (hasRequiredContainer$1) return container$1;
|
|
hasRequiredContainer$1 = 1;
|
|
let { isClean, my } = requireSymbols$1();
|
|
let Declaration = requireDeclaration$1();
|
|
let Comment = requireComment$1();
|
|
let Node2 = requireNode$1();
|
|
let parse, Rule, AtRule, Root;
|
|
function cleanSource(nodes) {
|
|
return nodes.map((i2) => {
|
|
if (i2.nodes) i2.nodes = cleanSource(i2.nodes);
|
|
delete i2.source;
|
|
return i2;
|
|
});
|
|
}
|
|
function markDirtyUp(node2) {
|
|
node2[isClean] = false;
|
|
if (node2.proxyOf.nodes) {
|
|
for (let i2 of node2.proxyOf.nodes) {
|
|
markDirtyUp(i2);
|
|
}
|
|
}
|
|
}
|
|
class Container extends Node2 {
|
|
append(...children) {
|
|
for (let child of children) {
|
|
let nodes = this.normalize(child, this.last);
|
|
for (let node2 of nodes) this.proxyOf.nodes.push(node2);
|
|
}
|
|
this.markDirty();
|
|
return this;
|
|
}
|
|
cleanRaws(keepBetween) {
|
|
super.cleanRaws(keepBetween);
|
|
if (this.nodes) {
|
|
for (let node2 of this.nodes) node2.cleanRaws(keepBetween);
|
|
}
|
|
}
|
|
each(callback) {
|
|
if (!this.proxyOf.nodes) return void 0;
|
|
let iterator = this.getIterator();
|
|
let index2, result2;
|
|
while (this.indexes[iterator] < this.proxyOf.nodes.length) {
|
|
index2 = this.indexes[iterator];
|
|
result2 = callback(this.proxyOf.nodes[index2], index2);
|
|
if (result2 === false) break;
|
|
this.indexes[iterator] += 1;
|
|
}
|
|
delete this.indexes[iterator];
|
|
return result2;
|
|
}
|
|
every(condition) {
|
|
return this.nodes.every(condition);
|
|
}
|
|
getIterator() {
|
|
if (!this.lastEach) this.lastEach = 0;
|
|
if (!this.indexes) this.indexes = {};
|
|
this.lastEach += 1;
|
|
let iterator = this.lastEach;
|
|
this.indexes[iterator] = 0;
|
|
return iterator;
|
|
}
|
|
getProxyProcessor() {
|
|
return {
|
|
get(node2, prop) {
|
|
if (prop === "proxyOf") {
|
|
return node2;
|
|
} else if (!node2[prop]) {
|
|
return node2[prop];
|
|
} else if (prop === "each" || typeof prop === "string" && prop.startsWith("walk")) {
|
|
return (...args) => {
|
|
return node2[prop](
|
|
...args.map((i2) => {
|
|
if (typeof i2 === "function") {
|
|
return (child, index2) => i2(child.toProxy(), index2);
|
|
} else {
|
|
return i2;
|
|
}
|
|
})
|
|
);
|
|
};
|
|
} else if (prop === "every" || prop === "some") {
|
|
return (cb) => {
|
|
return node2[prop](
|
|
(child, ...other) => cb(child.toProxy(), ...other)
|
|
);
|
|
};
|
|
} else if (prop === "root") {
|
|
return () => node2.root().toProxy();
|
|
} else if (prop === "nodes") {
|
|
return node2.nodes.map((i2) => i2.toProxy());
|
|
} else if (prop === "first" || prop === "last") {
|
|
return node2[prop].toProxy();
|
|
} else {
|
|
return node2[prop];
|
|
}
|
|
},
|
|
set(node2, prop, value) {
|
|
if (node2[prop] === value) return true;
|
|
node2[prop] = value;
|
|
if (prop === "name" || prop === "params" || prop === "selector") {
|
|
node2.markDirty();
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
}
|
|
index(child) {
|
|
if (typeof child === "number") return child;
|
|
if (child.proxyOf) child = child.proxyOf;
|
|
return this.proxyOf.nodes.indexOf(child);
|
|
}
|
|
insertAfter(exist, add) {
|
|
let existIndex = this.index(exist);
|
|
let nodes = this.normalize(add, this.proxyOf.nodes[existIndex]).reverse();
|
|
existIndex = this.index(exist);
|
|
for (let node2 of nodes) this.proxyOf.nodes.splice(existIndex + 1, 0, node2);
|
|
let index2;
|
|
for (let id in this.indexes) {
|
|
index2 = this.indexes[id];
|
|
if (existIndex < index2) {
|
|
this.indexes[id] = index2 + nodes.length;
|
|
}
|
|
}
|
|
this.markDirty();
|
|
return this;
|
|
}
|
|
insertBefore(exist, add) {
|
|
let existIndex = this.index(exist);
|
|
let type = existIndex === 0 ? "prepend" : false;
|
|
let nodes = this.normalize(add, this.proxyOf.nodes[existIndex], type).reverse();
|
|
existIndex = this.index(exist);
|
|
for (let node2 of nodes) this.proxyOf.nodes.splice(existIndex, 0, node2);
|
|
let index2;
|
|
for (let id in this.indexes) {
|
|
index2 = this.indexes[id];
|
|
if (existIndex <= index2) {
|
|
this.indexes[id] = index2 + nodes.length;
|
|
}
|
|
}
|
|
this.markDirty();
|
|
return this;
|
|
}
|
|
normalize(nodes, sample) {
|
|
if (typeof nodes === "string") {
|
|
nodes = cleanSource(parse(nodes).nodes);
|
|
} else if (typeof nodes === "undefined") {
|
|
nodes = [];
|
|
} else if (Array.isArray(nodes)) {
|
|
nodes = nodes.slice(0);
|
|
for (let i2 of nodes) {
|
|
if (i2.parent) i2.parent.removeChild(i2, "ignore");
|
|
}
|
|
} else if (nodes.type === "root" && this.type !== "document") {
|
|
nodes = nodes.nodes.slice(0);
|
|
for (let i2 of nodes) {
|
|
if (i2.parent) i2.parent.removeChild(i2, "ignore");
|
|
}
|
|
} else if (nodes.type) {
|
|
nodes = [nodes];
|
|
} else if (nodes.prop) {
|
|
if (typeof nodes.value === "undefined") {
|
|
throw new Error("Value field is missed in node creation");
|
|
} else if (typeof nodes.value !== "string") {
|
|
nodes.value = String(nodes.value);
|
|
}
|
|
nodes = [new Declaration(nodes)];
|
|
} else if (nodes.selector) {
|
|
nodes = [new Rule(nodes)];
|
|
} else if (nodes.name) {
|
|
nodes = [new AtRule(nodes)];
|
|
} else if (nodes.text) {
|
|
nodes = [new Comment(nodes)];
|
|
} else {
|
|
throw new Error("Unknown node type in node creation");
|
|
}
|
|
let processed = nodes.map((i2) => {
|
|
if (!i2[my]) Container.rebuild(i2);
|
|
i2 = i2.proxyOf;
|
|
if (i2.parent) i2.parent.removeChild(i2);
|
|
if (i2[isClean]) markDirtyUp(i2);
|
|
if (typeof i2.raws.before === "undefined") {
|
|
if (sample && typeof sample.raws.before !== "undefined") {
|
|
i2.raws.before = sample.raws.before.replace(/\S/g, "");
|
|
}
|
|
}
|
|
i2.parent = this.proxyOf;
|
|
return i2;
|
|
});
|
|
return processed;
|
|
}
|
|
prepend(...children) {
|
|
children = children.reverse();
|
|
for (let child of children) {
|
|
let nodes = this.normalize(child, this.first, "prepend").reverse();
|
|
for (let node2 of nodes) this.proxyOf.nodes.unshift(node2);
|
|
for (let id in this.indexes) {
|
|
this.indexes[id] = this.indexes[id] + nodes.length;
|
|
}
|
|
}
|
|
this.markDirty();
|
|
return this;
|
|
}
|
|
push(child) {
|
|
child.parent = this;
|
|
this.proxyOf.nodes.push(child);
|
|
return this;
|
|
}
|
|
removeAll() {
|
|
for (let node2 of this.proxyOf.nodes) node2.parent = void 0;
|
|
this.proxyOf.nodes = [];
|
|
this.markDirty();
|
|
return this;
|
|
}
|
|
removeChild(child) {
|
|
child = this.index(child);
|
|
this.proxyOf.nodes[child].parent = void 0;
|
|
this.proxyOf.nodes.splice(child, 1);
|
|
let index2;
|
|
for (let id in this.indexes) {
|
|
index2 = this.indexes[id];
|
|
if (index2 >= child) {
|
|
this.indexes[id] = index2 - 1;
|
|
}
|
|
}
|
|
this.markDirty();
|
|
return this;
|
|
}
|
|
replaceValues(pattern, opts, callback) {
|
|
if (!callback) {
|
|
callback = opts;
|
|
opts = {};
|
|
}
|
|
this.walkDecls((decl) => {
|
|
if (opts.props && !opts.props.includes(decl.prop)) return;
|
|
if (opts.fast && !decl.value.includes(opts.fast)) return;
|
|
decl.value = decl.value.replace(pattern, callback);
|
|
});
|
|
this.markDirty();
|
|
return this;
|
|
}
|
|
some(condition) {
|
|
return this.nodes.some(condition);
|
|
}
|
|
walk(callback) {
|
|
return this.each((child, i2) => {
|
|
let result2;
|
|
try {
|
|
result2 = callback(child, i2);
|
|
} catch (e2) {
|
|
throw child.addToError(e2);
|
|
}
|
|
if (result2 !== false && child.walk) {
|
|
result2 = child.walk(callback);
|
|
}
|
|
return result2;
|
|
});
|
|
}
|
|
walkAtRules(name, callback) {
|
|
if (!callback) {
|
|
callback = name;
|
|
return this.walk((child, i2) => {
|
|
if (child.type === "atrule") {
|
|
return callback(child, i2);
|
|
}
|
|
});
|
|
}
|
|
if (name instanceof RegExp) {
|
|
return this.walk((child, i2) => {
|
|
if (child.type === "atrule" && name.test(child.name)) {
|
|
return callback(child, i2);
|
|
}
|
|
});
|
|
}
|
|
return this.walk((child, i2) => {
|
|
if (child.type === "atrule" && child.name === name) {
|
|
return callback(child, i2);
|
|
}
|
|
});
|
|
}
|
|
walkComments(callback) {
|
|
return this.walk((child, i2) => {
|
|
if (child.type === "comment") {
|
|
return callback(child, i2);
|
|
}
|
|
});
|
|
}
|
|
walkDecls(prop, callback) {
|
|
if (!callback) {
|
|
callback = prop;
|
|
return this.walk((child, i2) => {
|
|
if (child.type === "decl") {
|
|
return callback(child, i2);
|
|
}
|
|
});
|
|
}
|
|
if (prop instanceof RegExp) {
|
|
return this.walk((child, i2) => {
|
|
if (child.type === "decl" && prop.test(child.prop)) {
|
|
return callback(child, i2);
|
|
}
|
|
});
|
|
}
|
|
return this.walk((child, i2) => {
|
|
if (child.type === "decl" && child.prop === prop) {
|
|
return callback(child, i2);
|
|
}
|
|
});
|
|
}
|
|
walkRules(selector, callback) {
|
|
if (!callback) {
|
|
callback = selector;
|
|
return this.walk((child, i2) => {
|
|
if (child.type === "rule") {
|
|
return callback(child, i2);
|
|
}
|
|
});
|
|
}
|
|
if (selector instanceof RegExp) {
|
|
return this.walk((child, i2) => {
|
|
if (child.type === "rule" && selector.test(child.selector)) {
|
|
return callback(child, i2);
|
|
}
|
|
});
|
|
}
|
|
return this.walk((child, i2) => {
|
|
if (child.type === "rule" && child.selector === selector) {
|
|
return callback(child, i2);
|
|
}
|
|
});
|
|
}
|
|
get first() {
|
|
if (!this.proxyOf.nodes) return void 0;
|
|
return this.proxyOf.nodes[0];
|
|
}
|
|
get last() {
|
|
if (!this.proxyOf.nodes) return void 0;
|
|
return this.proxyOf.nodes[this.proxyOf.nodes.length - 1];
|
|
}
|
|
}
|
|
Container.registerParse = (dependant) => {
|
|
parse = dependant;
|
|
};
|
|
Container.registerRule = (dependant) => {
|
|
Rule = dependant;
|
|
};
|
|
Container.registerAtRule = (dependant) => {
|
|
AtRule = dependant;
|
|
};
|
|
Container.registerRoot = (dependant) => {
|
|
Root = dependant;
|
|
};
|
|
container$1 = Container;
|
|
Container.default = Container;
|
|
Container.rebuild = (node2) => {
|
|
if (node2.type === "atrule") {
|
|
Object.setPrototypeOf(node2, AtRule.prototype);
|
|
} else if (node2.type === "rule") {
|
|
Object.setPrototypeOf(node2, Rule.prototype);
|
|
} else if (node2.type === "decl") {
|
|
Object.setPrototypeOf(node2, Declaration.prototype);
|
|
} else if (node2.type === "comment") {
|
|
Object.setPrototypeOf(node2, Comment.prototype);
|
|
} else if (node2.type === "root") {
|
|
Object.setPrototypeOf(node2, Root.prototype);
|
|
}
|
|
node2[my] = true;
|
|
if (node2.nodes) {
|
|
node2.nodes.forEach((child) => {
|
|
Container.rebuild(child);
|
|
});
|
|
}
|
|
};
|
|
return container$1;
|
|
}
|
|
var document$1$1;
|
|
var hasRequiredDocument$1;
|
|
function requireDocument$1() {
|
|
if (hasRequiredDocument$1) return document$1$1;
|
|
hasRequiredDocument$1 = 1;
|
|
let Container = requireContainer$1();
|
|
let LazyResult, Processor;
|
|
class Document2 extends Container {
|
|
constructor(defaults) {
|
|
super(__spreadValues({ type: "document" }, defaults));
|
|
if (!this.nodes) {
|
|
this.nodes = [];
|
|
}
|
|
}
|
|
toResult(opts = {}) {
|
|
let lazy = new LazyResult(new Processor(), this, opts);
|
|
return lazy.stringify();
|
|
}
|
|
}
|
|
Document2.registerLazyResult = (dependant) => {
|
|
LazyResult = dependant;
|
|
};
|
|
Document2.registerProcessor = (dependant) => {
|
|
Processor = dependant;
|
|
};
|
|
document$1$1 = Document2;
|
|
Document2.default = Document2;
|
|
return document$1$1;
|
|
}
|
|
var warnOnce$1;
|
|
var hasRequiredWarnOnce$1;
|
|
function requireWarnOnce$1() {
|
|
if (hasRequiredWarnOnce$1) return warnOnce$1;
|
|
hasRequiredWarnOnce$1 = 1;
|
|
let printed = {};
|
|
warnOnce$1 = function warnOnce2(message) {
|
|
if (printed[message]) return;
|
|
printed[message] = true;
|
|
if (typeof console !== "undefined" && console.warn) {
|
|
console.warn(message);
|
|
}
|
|
};
|
|
return warnOnce$1;
|
|
}
|
|
var warning$1;
|
|
var hasRequiredWarning$1;
|
|
function requireWarning$1() {
|
|
if (hasRequiredWarning$1) return warning$1;
|
|
hasRequiredWarning$1 = 1;
|
|
class Warning {
|
|
constructor(text, opts = {}) {
|
|
this.type = "warning";
|
|
this.text = text;
|
|
if (opts.node && opts.node.source) {
|
|
let range = opts.node.rangeBy(opts);
|
|
this.line = range.start.line;
|
|
this.column = range.start.column;
|
|
this.endLine = range.end.line;
|
|
this.endColumn = range.end.column;
|
|
}
|
|
for (let opt in opts) this[opt] = opts[opt];
|
|
}
|
|
toString() {
|
|
if (this.node) {
|
|
return this.node.error(this.text, {
|
|
index: this.index,
|
|
plugin: this.plugin,
|
|
word: this.word
|
|
}).message;
|
|
}
|
|
if (this.plugin) {
|
|
return this.plugin + ": " + this.text;
|
|
}
|
|
return this.text;
|
|
}
|
|
}
|
|
warning$1 = Warning;
|
|
Warning.default = Warning;
|
|
return warning$1;
|
|
}
|
|
var result$1;
|
|
var hasRequiredResult$1;
|
|
function requireResult$1() {
|
|
if (hasRequiredResult$1) return result$1;
|
|
hasRequiredResult$1 = 1;
|
|
let Warning = requireWarning$1();
|
|
class Result {
|
|
constructor(processor2, root2, opts) {
|
|
this.processor = processor2;
|
|
this.messages = [];
|
|
this.root = root2;
|
|
this.opts = opts;
|
|
this.css = void 0;
|
|
this.map = void 0;
|
|
}
|
|
toString() {
|
|
return this.css;
|
|
}
|
|
warn(text, opts = {}) {
|
|
if (!opts.plugin) {
|
|
if (this.lastPlugin && this.lastPlugin.postcssPlugin) {
|
|
opts.plugin = this.lastPlugin.postcssPlugin;
|
|
}
|
|
}
|
|
let warning2 = new Warning(text, opts);
|
|
this.messages.push(warning2);
|
|
return warning2;
|
|
}
|
|
warnings() {
|
|
return this.messages.filter((i2) => i2.type === "warning");
|
|
}
|
|
get content() {
|
|
return this.css;
|
|
}
|
|
}
|
|
result$1 = Result;
|
|
Result.default = Result;
|
|
return result$1;
|
|
}
|
|
var tokenize$1;
|
|
var hasRequiredTokenize$1;
|
|
function requireTokenize$1() {
|
|
if (hasRequiredTokenize$1) return tokenize$1;
|
|
hasRequiredTokenize$1 = 1;
|
|
const SINGLE_QUOTE = "'".charCodeAt(0);
|
|
const DOUBLE_QUOTE = '"'.charCodeAt(0);
|
|
const BACKSLASH = "\\".charCodeAt(0);
|
|
const SLASH = "/".charCodeAt(0);
|
|
const NEWLINE = "\n".charCodeAt(0);
|
|
const SPACE = " ".charCodeAt(0);
|
|
const FEED = "\f".charCodeAt(0);
|
|
const TAB = " ".charCodeAt(0);
|
|
const CR = "\r".charCodeAt(0);
|
|
const OPEN_SQUARE = "[".charCodeAt(0);
|
|
const CLOSE_SQUARE = "]".charCodeAt(0);
|
|
const OPEN_PARENTHESES = "(".charCodeAt(0);
|
|
const CLOSE_PARENTHESES = ")".charCodeAt(0);
|
|
const OPEN_CURLY = "{".charCodeAt(0);
|
|
const CLOSE_CURLY = "}".charCodeAt(0);
|
|
const SEMICOLON = ";".charCodeAt(0);
|
|
const ASTERISK = "*".charCodeAt(0);
|
|
const COLON = ":".charCodeAt(0);
|
|
const AT = "@".charCodeAt(0);
|
|
const RE_AT_END = /[\t\n\f\r "#'()/;[\\\]{}]/g;
|
|
const RE_WORD_END = /[\t\n\f\r !"#'():;@[\\\]{}]|\/(?=\*)/g;
|
|
const RE_BAD_BRACKET = /.[\r\n"'(/\\]/;
|
|
const RE_HEX_ESCAPE = /[\da-f]/i;
|
|
tokenize$1 = function tokenizer(input2, options = {}) {
|
|
let css = input2.css.valueOf();
|
|
let ignore = options.ignoreErrors;
|
|
let code, next, quote, content, escape;
|
|
let escaped, escapePos, prev, n2, currentToken;
|
|
let length = css.length;
|
|
let pos = 0;
|
|
let buffer = [];
|
|
let returned = [];
|
|
function position() {
|
|
return pos;
|
|
}
|
|
function unclosed(what) {
|
|
throw input2.error("Unclosed " + what, pos);
|
|
}
|
|
function endOfFile() {
|
|
return returned.length === 0 && pos >= length;
|
|
}
|
|
function nextToken(opts) {
|
|
if (returned.length) return returned.pop();
|
|
if (pos >= length) return;
|
|
let ignoreUnclosed = opts ? opts.ignoreUnclosed : false;
|
|
code = css.charCodeAt(pos);
|
|
switch (code) {
|
|
case NEWLINE:
|
|
case SPACE:
|
|
case TAB:
|
|
case CR:
|
|
case FEED: {
|
|
next = pos;
|
|
do {
|
|
next += 1;
|
|
code = css.charCodeAt(next);
|
|
} while (code === SPACE || code === NEWLINE || code === TAB || code === CR || code === FEED);
|
|
currentToken = ["space", css.slice(pos, next)];
|
|
pos = next - 1;
|
|
break;
|
|
}
|
|
case OPEN_SQUARE:
|
|
case CLOSE_SQUARE:
|
|
case OPEN_CURLY:
|
|
case CLOSE_CURLY:
|
|
case COLON:
|
|
case SEMICOLON:
|
|
case CLOSE_PARENTHESES: {
|
|
let controlChar = String.fromCharCode(code);
|
|
currentToken = [controlChar, controlChar, pos];
|
|
break;
|
|
}
|
|
case OPEN_PARENTHESES: {
|
|
prev = buffer.length ? buffer.pop()[1] : "";
|
|
n2 = css.charCodeAt(pos + 1);
|
|
if (prev === "url" && n2 !== SINGLE_QUOTE && n2 !== DOUBLE_QUOTE && n2 !== SPACE && n2 !== NEWLINE && n2 !== TAB && n2 !== FEED && n2 !== CR) {
|
|
next = pos;
|
|
do {
|
|
escaped = false;
|
|
next = css.indexOf(")", next + 1);
|
|
if (next === -1) {
|
|
if (ignore || ignoreUnclosed) {
|
|
next = pos;
|
|
break;
|
|
} else {
|
|
unclosed("bracket");
|
|
}
|
|
}
|
|
escapePos = next;
|
|
while (css.charCodeAt(escapePos - 1) === BACKSLASH) {
|
|
escapePos -= 1;
|
|
escaped = !escaped;
|
|
}
|
|
} while (escaped);
|
|
currentToken = ["brackets", css.slice(pos, next + 1), pos, next];
|
|
pos = next;
|
|
} else {
|
|
next = css.indexOf(")", pos + 1);
|
|
content = css.slice(pos, next + 1);
|
|
if (next === -1 || RE_BAD_BRACKET.test(content)) {
|
|
currentToken = ["(", "(", pos];
|
|
} else {
|
|
currentToken = ["brackets", content, pos, next];
|
|
pos = next;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case SINGLE_QUOTE:
|
|
case DOUBLE_QUOTE: {
|
|
quote = code === SINGLE_QUOTE ? "'" : '"';
|
|
next = pos;
|
|
do {
|
|
escaped = false;
|
|
next = css.indexOf(quote, next + 1);
|
|
if (next === -1) {
|
|
if (ignore || ignoreUnclosed) {
|
|
next = pos + 1;
|
|
break;
|
|
} else {
|
|
unclosed("string");
|
|
}
|
|
}
|
|
escapePos = next;
|
|
while (css.charCodeAt(escapePos - 1) === BACKSLASH) {
|
|
escapePos -= 1;
|
|
escaped = !escaped;
|
|
}
|
|
} while (escaped);
|
|
currentToken = ["string", css.slice(pos, next + 1), pos, next];
|
|
pos = next;
|
|
break;
|
|
}
|
|
case AT: {
|
|
RE_AT_END.lastIndex = pos + 1;
|
|
RE_AT_END.test(css);
|
|
if (RE_AT_END.lastIndex === 0) {
|
|
next = css.length - 1;
|
|
} else {
|
|
next = RE_AT_END.lastIndex - 2;
|
|
}
|
|
currentToken = ["at-word", css.slice(pos, next + 1), pos, next];
|
|
pos = next;
|
|
break;
|
|
}
|
|
case BACKSLASH: {
|
|
next = pos;
|
|
escape = true;
|
|
while (css.charCodeAt(next + 1) === BACKSLASH) {
|
|
next += 1;
|
|
escape = !escape;
|
|
}
|
|
code = css.charCodeAt(next + 1);
|
|
if (escape && code !== SLASH && code !== SPACE && code !== NEWLINE && code !== TAB && code !== CR && code !== FEED) {
|
|
next += 1;
|
|
if (RE_HEX_ESCAPE.test(css.charAt(next))) {
|
|
while (RE_HEX_ESCAPE.test(css.charAt(next + 1))) {
|
|
next += 1;
|
|
}
|
|
if (css.charCodeAt(next + 1) === SPACE) {
|
|
next += 1;
|
|
}
|
|
}
|
|
}
|
|
currentToken = ["word", css.slice(pos, next + 1), pos, next];
|
|
pos = next;
|
|
break;
|
|
}
|
|
default: {
|
|
if (code === SLASH && css.charCodeAt(pos + 1) === ASTERISK) {
|
|
next = css.indexOf("*/", pos + 2) + 1;
|
|
if (next === 0) {
|
|
if (ignore || ignoreUnclosed) {
|
|
next = css.length;
|
|
} else {
|
|
unclosed("comment");
|
|
}
|
|
}
|
|
currentToken = ["comment", css.slice(pos, next + 1), pos, next];
|
|
pos = next;
|
|
} else {
|
|
RE_WORD_END.lastIndex = pos + 1;
|
|
RE_WORD_END.test(css);
|
|
if (RE_WORD_END.lastIndex === 0) {
|
|
next = css.length - 1;
|
|
} else {
|
|
next = RE_WORD_END.lastIndex - 2;
|
|
}
|
|
currentToken = ["word", css.slice(pos, next + 1), pos, next];
|
|
buffer.push(currentToken);
|
|
pos = next;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
pos++;
|
|
return currentToken;
|
|
}
|
|
function back(token) {
|
|
returned.push(token);
|
|
}
|
|
return {
|
|
back,
|
|
endOfFile,
|
|
nextToken,
|
|
position
|
|
};
|
|
};
|
|
return tokenize$1;
|
|
}
|
|
var atRule$1;
|
|
var hasRequiredAtRule$1;
|
|
function requireAtRule$1() {
|
|
if (hasRequiredAtRule$1) return atRule$1;
|
|
hasRequiredAtRule$1 = 1;
|
|
let Container = requireContainer$1();
|
|
class AtRule extends Container {
|
|
constructor(defaults) {
|
|
super(defaults);
|
|
this.type = "atrule";
|
|
}
|
|
append(...children) {
|
|
if (!this.proxyOf.nodes) this.nodes = [];
|
|
return super.append(...children);
|
|
}
|
|
prepend(...children) {
|
|
if (!this.proxyOf.nodes) this.nodes = [];
|
|
return super.prepend(...children);
|
|
}
|
|
}
|
|
atRule$1 = AtRule;
|
|
AtRule.default = AtRule;
|
|
Container.registerAtRule(AtRule);
|
|
return atRule$1;
|
|
}
|
|
var root$1;
|
|
var hasRequiredRoot$1;
|
|
function requireRoot$1() {
|
|
if (hasRequiredRoot$1) return root$1;
|
|
hasRequiredRoot$1 = 1;
|
|
let Container = requireContainer$1();
|
|
let LazyResult, Processor;
|
|
class Root extends Container {
|
|
constructor(defaults) {
|
|
super(defaults);
|
|
this.type = "root";
|
|
if (!this.nodes) this.nodes = [];
|
|
}
|
|
normalize(child, sample, type) {
|
|
let nodes = super.normalize(child);
|
|
if (sample) {
|
|
if (type === "prepend") {
|
|
if (this.nodes.length > 1) {
|
|
sample.raws.before = this.nodes[1].raws.before;
|
|
} else {
|
|
delete sample.raws.before;
|
|
}
|
|
} else if (this.first !== sample) {
|
|
for (let node2 of nodes) {
|
|
node2.raws.before = sample.raws.before;
|
|
}
|
|
}
|
|
}
|
|
return nodes;
|
|
}
|
|
removeChild(child, ignore) {
|
|
let index2 = this.index(child);
|
|
if (!ignore && index2 === 0 && this.nodes.length > 1) {
|
|
this.nodes[1].raws.before = this.nodes[index2].raws.before;
|
|
}
|
|
return super.removeChild(child);
|
|
}
|
|
toResult(opts = {}) {
|
|
let lazy = new LazyResult(new Processor(), this, opts);
|
|
return lazy.stringify();
|
|
}
|
|
}
|
|
Root.registerLazyResult = (dependant) => {
|
|
LazyResult = dependant;
|
|
};
|
|
Root.registerProcessor = (dependant) => {
|
|
Processor = dependant;
|
|
};
|
|
root$1 = Root;
|
|
Root.default = Root;
|
|
Container.registerRoot(Root);
|
|
return root$1;
|
|
}
|
|
var list_1$1;
|
|
var hasRequiredList$1;
|
|
function requireList$1() {
|
|
if (hasRequiredList$1) return list_1$1;
|
|
hasRequiredList$1 = 1;
|
|
let list = {
|
|
comma(string) {
|
|
return list.split(string, [","], true);
|
|
},
|
|
space(string) {
|
|
let spaces = [" ", "\n", " "];
|
|
return list.split(string, spaces);
|
|
},
|
|
split(string, separators, last) {
|
|
let array = [];
|
|
let current = "";
|
|
let split = false;
|
|
let func = 0;
|
|
let inQuote = false;
|
|
let prevQuote = "";
|
|
let escape = false;
|
|
for (let letter of string) {
|
|
if (escape) {
|
|
escape = false;
|
|
} else if (letter === "\\") {
|
|
escape = true;
|
|
} else if (inQuote) {
|
|
if (letter === prevQuote) {
|
|
inQuote = false;
|
|
}
|
|
} else if (letter === '"' || letter === "'") {
|
|
inQuote = true;
|
|
prevQuote = letter;
|
|
} else if (letter === "(") {
|
|
func += 1;
|
|
} else if (letter === ")") {
|
|
if (func > 0) func -= 1;
|
|
} else if (func === 0) {
|
|
if (separators.includes(letter)) split = true;
|
|
}
|
|
if (split) {
|
|
if (current !== "") array.push(current.trim());
|
|
current = "";
|
|
split = false;
|
|
} else {
|
|
current += letter;
|
|
}
|
|
}
|
|
if (last || current !== "") array.push(current.trim());
|
|
return array;
|
|
}
|
|
};
|
|
list_1$1 = list;
|
|
list.default = list;
|
|
return list_1$1;
|
|
}
|
|
var rule$1;
|
|
var hasRequiredRule$1;
|
|
function requireRule$1() {
|
|
if (hasRequiredRule$1) return rule$1;
|
|
hasRequiredRule$1 = 1;
|
|
let Container = requireContainer$1();
|
|
let list = requireList$1();
|
|
class Rule extends Container {
|
|
constructor(defaults) {
|
|
super(defaults);
|
|
this.type = "rule";
|
|
if (!this.nodes) this.nodes = [];
|
|
}
|
|
get selectors() {
|
|
return list.comma(this.selector);
|
|
}
|
|
set selectors(values) {
|
|
let match = this.selector ? this.selector.match(/,\s*/) : null;
|
|
let sep = match ? match[0] : "," + this.raw("between", "beforeOpen");
|
|
this.selector = values.join(sep);
|
|
}
|
|
}
|
|
rule$1 = Rule;
|
|
Rule.default = Rule;
|
|
Container.registerRule(Rule);
|
|
return rule$1;
|
|
}
|
|
var parser$1;
|
|
var hasRequiredParser$1;
|
|
function requireParser$1() {
|
|
if (hasRequiredParser$1) return parser$1;
|
|
hasRequiredParser$1 = 1;
|
|
let Declaration = requireDeclaration$1();
|
|
let tokenizer = requireTokenize$1();
|
|
let Comment = requireComment$1();
|
|
let AtRule = requireAtRule$1();
|
|
let Root = requireRoot$1();
|
|
let Rule = requireRule$1();
|
|
const SAFE_COMMENT_NEIGHBOR = {
|
|
empty: true,
|
|
space: true
|
|
};
|
|
function findLastWithPosition(tokens) {
|
|
for (let i2 = tokens.length - 1; i2 >= 0; i2--) {
|
|
let token = tokens[i2];
|
|
let pos = token[3] || token[2];
|
|
if (pos) return pos;
|
|
}
|
|
}
|
|
class Parser {
|
|
constructor(input2) {
|
|
this.input = input2;
|
|
this.root = new Root();
|
|
this.current = this.root;
|
|
this.spaces = "";
|
|
this.semicolon = false;
|
|
this.createTokenizer();
|
|
this.root.source = { input: input2, start: { column: 1, line: 1, offset: 0 } };
|
|
}
|
|
atrule(token) {
|
|
let node2 = new AtRule();
|
|
node2.name = token[1].slice(1);
|
|
if (node2.name === "") {
|
|
this.unnamedAtrule(node2, token);
|
|
}
|
|
this.init(node2, token[2]);
|
|
let type;
|
|
let prev;
|
|
let shift;
|
|
let last = false;
|
|
let open = false;
|
|
let params = [];
|
|
let brackets = [];
|
|
while (!this.tokenizer.endOfFile()) {
|
|
token = this.tokenizer.nextToken();
|
|
type = token[0];
|
|
if (type === "(" || type === "[") {
|
|
brackets.push(type === "(" ? ")" : "]");
|
|
} else if (type === "{" && brackets.length > 0) {
|
|
brackets.push("}");
|
|
} else if (type === brackets[brackets.length - 1]) {
|
|
brackets.pop();
|
|
}
|
|
if (brackets.length === 0) {
|
|
if (type === ";") {
|
|
node2.source.end = this.getPosition(token[2]);
|
|
node2.source.end.offset++;
|
|
this.semicolon = true;
|
|
break;
|
|
} else if (type === "{") {
|
|
open = true;
|
|
break;
|
|
} else if (type === "}") {
|
|
if (params.length > 0) {
|
|
shift = params.length - 1;
|
|
prev = params[shift];
|
|
while (prev && prev[0] === "space") {
|
|
prev = params[--shift];
|
|
}
|
|
if (prev) {
|
|
node2.source.end = this.getPosition(prev[3] || prev[2]);
|
|
node2.source.end.offset++;
|
|
}
|
|
}
|
|
this.end(token);
|
|
break;
|
|
} else {
|
|
params.push(token);
|
|
}
|
|
} else {
|
|
params.push(token);
|
|
}
|
|
if (this.tokenizer.endOfFile()) {
|
|
last = true;
|
|
break;
|
|
}
|
|
}
|
|
node2.raws.between = this.spacesAndCommentsFromEnd(params);
|
|
if (params.length) {
|
|
node2.raws.afterName = this.spacesAndCommentsFromStart(params);
|
|
this.raw(node2, "params", params);
|
|
if (last) {
|
|
token = params[params.length - 1];
|
|
node2.source.end = this.getPosition(token[3] || token[2]);
|
|
node2.source.end.offset++;
|
|
this.spaces = node2.raws.between;
|
|
node2.raws.between = "";
|
|
}
|
|
} else {
|
|
node2.raws.afterName = "";
|
|
node2.params = "";
|
|
}
|
|
if (open) {
|
|
node2.nodes = [];
|
|
this.current = node2;
|
|
}
|
|
}
|
|
checkMissedSemicolon(tokens) {
|
|
let colon = this.colon(tokens);
|
|
if (colon === false) return;
|
|
let founded = 0;
|
|
let token;
|
|
for (let j = colon - 1; j >= 0; j--) {
|
|
token = tokens[j];
|
|
if (token[0] !== "space") {
|
|
founded += 1;
|
|
if (founded === 2) break;
|
|
}
|
|
}
|
|
throw this.input.error(
|
|
"Missed semicolon",
|
|
token[0] === "word" ? token[3] + 1 : token[2]
|
|
);
|
|
}
|
|
colon(tokens) {
|
|
let brackets = 0;
|
|
let token, type, prev;
|
|
for (let [i2, element] of tokens.entries()) {
|
|
token = element;
|
|
type = token[0];
|
|
if (type === "(") {
|
|
brackets += 1;
|
|
}
|
|
if (type === ")") {
|
|
brackets -= 1;
|
|
}
|
|
if (brackets === 0 && type === ":") {
|
|
if (!prev) {
|
|
this.doubleColon(token);
|
|
} else if (prev[0] === "word" && prev[1] === "progid") {
|
|
continue;
|
|
} else {
|
|
return i2;
|
|
}
|
|
}
|
|
prev = token;
|
|
}
|
|
return false;
|
|
}
|
|
comment(token) {
|
|
let node2 = new Comment();
|
|
this.init(node2, token[2]);
|
|
node2.source.end = this.getPosition(token[3] || token[2]);
|
|
node2.source.end.offset++;
|
|
let text = token[1].slice(2, -2);
|
|
if (/^\s*$/.test(text)) {
|
|
node2.text = "";
|
|
node2.raws.left = text;
|
|
node2.raws.right = "";
|
|
} else {
|
|
let match = text.match(/^(\s*)([^]*\S)(\s*)$/);
|
|
node2.text = match[2];
|
|
node2.raws.left = match[1];
|
|
node2.raws.right = match[3];
|
|
}
|
|
}
|
|
createTokenizer() {
|
|
this.tokenizer = tokenizer(this.input);
|
|
}
|
|
decl(tokens, customProperty) {
|
|
let node2 = new Declaration();
|
|
this.init(node2, tokens[0][2]);
|
|
let last = tokens[tokens.length - 1];
|
|
if (last[0] === ";") {
|
|
this.semicolon = true;
|
|
tokens.pop();
|
|
}
|
|
node2.source.end = this.getPosition(
|
|
last[3] || last[2] || findLastWithPosition(tokens)
|
|
);
|
|
node2.source.end.offset++;
|
|
while (tokens[0][0] !== "word") {
|
|
if (tokens.length === 1) this.unknownWord(tokens);
|
|
node2.raws.before += tokens.shift()[1];
|
|
}
|
|
node2.source.start = this.getPosition(tokens[0][2]);
|
|
node2.prop = "";
|
|
while (tokens.length) {
|
|
let type = tokens[0][0];
|
|
if (type === ":" || type === "space" || type === "comment") {
|
|
break;
|
|
}
|
|
node2.prop += tokens.shift()[1];
|
|
}
|
|
node2.raws.between = "";
|
|
let token;
|
|
while (tokens.length) {
|
|
token = tokens.shift();
|
|
if (token[0] === ":") {
|
|
node2.raws.between += token[1];
|
|
break;
|
|
} else {
|
|
if (token[0] === "word" && /\w/.test(token[1])) {
|
|
this.unknownWord([token]);
|
|
}
|
|
node2.raws.between += token[1];
|
|
}
|
|
}
|
|
if (node2.prop[0] === "_" || node2.prop[0] === "*") {
|
|
node2.raws.before += node2.prop[0];
|
|
node2.prop = node2.prop.slice(1);
|
|
}
|
|
let firstSpaces = [];
|
|
let next;
|
|
while (tokens.length) {
|
|
next = tokens[0][0];
|
|
if (next !== "space" && next !== "comment") break;
|
|
firstSpaces.push(tokens.shift());
|
|
}
|
|
this.precheckMissedSemicolon(tokens);
|
|
for (let i2 = tokens.length - 1; i2 >= 0; i2--) {
|
|
token = tokens[i2];
|
|
if (token[1].toLowerCase() === "!important") {
|
|
node2.important = true;
|
|
let string = this.stringFrom(tokens, i2);
|
|
string = this.spacesFromEnd(tokens) + string;
|
|
if (string !== " !important") node2.raws.important = string;
|
|
break;
|
|
} else if (token[1].toLowerCase() === "important") {
|
|
let cache = tokens.slice(0);
|
|
let str = "";
|
|
for (let j = i2; j > 0; j--) {
|
|
let type = cache[j][0];
|
|
if (str.trim().indexOf("!") === 0 && type !== "space") {
|
|
break;
|
|
}
|
|
str = cache.pop()[1] + str;
|
|
}
|
|
if (str.trim().indexOf("!") === 0) {
|
|
node2.important = true;
|
|
node2.raws.important = str;
|
|
tokens = cache;
|
|
}
|
|
}
|
|
if (token[0] !== "space" && token[0] !== "comment") {
|
|
break;
|
|
}
|
|
}
|
|
let hasWord = tokens.some((i2) => i2[0] !== "space" && i2[0] !== "comment");
|
|
if (hasWord) {
|
|
node2.raws.between += firstSpaces.map((i2) => i2[1]).join("");
|
|
firstSpaces = [];
|
|
}
|
|
this.raw(node2, "value", firstSpaces.concat(tokens), customProperty);
|
|
if (node2.value.includes(":") && !customProperty) {
|
|
this.checkMissedSemicolon(tokens);
|
|
}
|
|
}
|
|
doubleColon(token) {
|
|
throw this.input.error(
|
|
"Double colon",
|
|
{ offset: token[2] },
|
|
{ offset: token[2] + token[1].length }
|
|
);
|
|
}
|
|
emptyRule(token) {
|
|
let node2 = new Rule();
|
|
this.init(node2, token[2]);
|
|
node2.selector = "";
|
|
node2.raws.between = "";
|
|
this.current = node2;
|
|
}
|
|
end(token) {
|
|
if (this.current.nodes && this.current.nodes.length) {
|
|
this.current.raws.semicolon = this.semicolon;
|
|
}
|
|
this.semicolon = false;
|
|
this.current.raws.after = (this.current.raws.after || "") + this.spaces;
|
|
this.spaces = "";
|
|
if (this.current.parent) {
|
|
this.current.source.end = this.getPosition(token[2]);
|
|
this.current.source.end.offset++;
|
|
this.current = this.current.parent;
|
|
} else {
|
|
this.unexpectedClose(token);
|
|
}
|
|
}
|
|
endFile() {
|
|
if (this.current.parent) this.unclosedBlock();
|
|
if (this.current.nodes && this.current.nodes.length) {
|
|
this.current.raws.semicolon = this.semicolon;
|
|
}
|
|
this.current.raws.after = (this.current.raws.after || "") + this.spaces;
|
|
this.root.source.end = this.getPosition(this.tokenizer.position());
|
|
}
|
|
freeSemicolon(token) {
|
|
this.spaces += token[1];
|
|
if (this.current.nodes) {
|
|
let prev = this.current.nodes[this.current.nodes.length - 1];
|
|
if (prev && prev.type === "rule" && !prev.raws.ownSemicolon) {
|
|
prev.raws.ownSemicolon = this.spaces;
|
|
this.spaces = "";
|
|
}
|
|
}
|
|
}
|
|
// Helpers
|
|
getPosition(offset) {
|
|
let pos = this.input.fromOffset(offset);
|
|
return {
|
|
column: pos.col,
|
|
line: pos.line,
|
|
offset
|
|
};
|
|
}
|
|
init(node2, offset) {
|
|
this.current.push(node2);
|
|
node2.source = {
|
|
input: this.input,
|
|
start: this.getPosition(offset)
|
|
};
|
|
node2.raws.before = this.spaces;
|
|
this.spaces = "";
|
|
if (node2.type !== "comment") this.semicolon = false;
|
|
}
|
|
other(start) {
|
|
let end = false;
|
|
let type = null;
|
|
let colon = false;
|
|
let bracket = null;
|
|
let brackets = [];
|
|
let customProperty = start[1].startsWith("--");
|
|
let tokens = [];
|
|
let token = start;
|
|
while (token) {
|
|
type = token[0];
|
|
tokens.push(token);
|
|
if (type === "(" || type === "[") {
|
|
if (!bracket) bracket = token;
|
|
brackets.push(type === "(" ? ")" : "]");
|
|
} else if (customProperty && colon && type === "{") {
|
|
if (!bracket) bracket = token;
|
|
brackets.push("}");
|
|
} else if (brackets.length === 0) {
|
|
if (type === ";") {
|
|
if (colon) {
|
|
this.decl(tokens, customProperty);
|
|
return;
|
|
} else {
|
|
break;
|
|
}
|
|
} else if (type === "{") {
|
|
this.rule(tokens);
|
|
return;
|
|
} else if (type === "}") {
|
|
this.tokenizer.back(tokens.pop());
|
|
end = true;
|
|
break;
|
|
} else if (type === ":") {
|
|
colon = true;
|
|
}
|
|
} else if (type === brackets[brackets.length - 1]) {
|
|
brackets.pop();
|
|
if (brackets.length === 0) bracket = null;
|
|
}
|
|
token = this.tokenizer.nextToken();
|
|
}
|
|
if (this.tokenizer.endOfFile()) end = true;
|
|
if (brackets.length > 0) this.unclosedBracket(bracket);
|
|
if (end && colon) {
|
|
if (!customProperty) {
|
|
while (tokens.length) {
|
|
token = tokens[tokens.length - 1][0];
|
|
if (token !== "space" && token !== "comment") break;
|
|
this.tokenizer.back(tokens.pop());
|
|
}
|
|
}
|
|
this.decl(tokens, customProperty);
|
|
} else {
|
|
this.unknownWord(tokens);
|
|
}
|
|
}
|
|
parse() {
|
|
let token;
|
|
while (!this.tokenizer.endOfFile()) {
|
|
token = this.tokenizer.nextToken();
|
|
switch (token[0]) {
|
|
case "space":
|
|
this.spaces += token[1];
|
|
break;
|
|
case ";":
|
|
this.freeSemicolon(token);
|
|
break;
|
|
case "}":
|
|
this.end(token);
|
|
break;
|
|
case "comment":
|
|
this.comment(token);
|
|
break;
|
|
case "at-word":
|
|
this.atrule(token);
|
|
break;
|
|
case "{":
|
|
this.emptyRule(token);
|
|
break;
|
|
default:
|
|
this.other(token);
|
|
break;
|
|
}
|
|
}
|
|
this.endFile();
|
|
}
|
|
precheckMissedSemicolon() {
|
|
}
|
|
raw(node2, prop, tokens, customProperty) {
|
|
let token, type;
|
|
let length = tokens.length;
|
|
let value = "";
|
|
let clean = true;
|
|
let next, prev;
|
|
for (let i2 = 0; i2 < length; i2 += 1) {
|
|
token = tokens[i2];
|
|
type = token[0];
|
|
if (type === "space" && i2 === length - 1 && !customProperty) {
|
|
clean = false;
|
|
} else if (type === "comment") {
|
|
prev = tokens[i2 - 1] ? tokens[i2 - 1][0] : "empty";
|
|
next = tokens[i2 + 1] ? tokens[i2 + 1][0] : "empty";
|
|
if (!SAFE_COMMENT_NEIGHBOR[prev] && !SAFE_COMMENT_NEIGHBOR[next]) {
|
|
if (value.slice(-1) === ",") {
|
|
clean = false;
|
|
} else {
|
|
value += token[1];
|
|
}
|
|
} else {
|
|
clean = false;
|
|
}
|
|
} else {
|
|
value += token[1];
|
|
}
|
|
}
|
|
if (!clean) {
|
|
let raw = tokens.reduce((all, i2) => all + i2[1], "");
|
|
node2.raws[prop] = { raw, value };
|
|
}
|
|
node2[prop] = value;
|
|
}
|
|
rule(tokens) {
|
|
tokens.pop();
|
|
let node2 = new Rule();
|
|
this.init(node2, tokens[0][2]);
|
|
node2.raws.between = this.spacesAndCommentsFromEnd(tokens);
|
|
this.raw(node2, "selector", tokens);
|
|
this.current = node2;
|
|
}
|
|
spacesAndCommentsFromEnd(tokens) {
|
|
let lastTokenType;
|
|
let spaces = "";
|
|
while (tokens.length) {
|
|
lastTokenType = tokens[tokens.length - 1][0];
|
|
if (lastTokenType !== "space" && lastTokenType !== "comment") break;
|
|
spaces = tokens.pop()[1] + spaces;
|
|
}
|
|
return spaces;
|
|
}
|
|
// Errors
|
|
spacesAndCommentsFromStart(tokens) {
|
|
let next;
|
|
let spaces = "";
|
|
while (tokens.length) {
|
|
next = tokens[0][0];
|
|
if (next !== "space" && next !== "comment") break;
|
|
spaces += tokens.shift()[1];
|
|
}
|
|
return spaces;
|
|
}
|
|
spacesFromEnd(tokens) {
|
|
let lastTokenType;
|
|
let spaces = "";
|
|
while (tokens.length) {
|
|
lastTokenType = tokens[tokens.length - 1][0];
|
|
if (lastTokenType !== "space") break;
|
|
spaces = tokens.pop()[1] + spaces;
|
|
}
|
|
return spaces;
|
|
}
|
|
stringFrom(tokens, from) {
|
|
let result2 = "";
|
|
for (let i2 = from; i2 < tokens.length; i2++) {
|
|
result2 += tokens[i2][1];
|
|
}
|
|
tokens.splice(from, tokens.length - from);
|
|
return result2;
|
|
}
|
|
unclosedBlock() {
|
|
let pos = this.current.source.start;
|
|
throw this.input.error("Unclosed block", pos.line, pos.column);
|
|
}
|
|
unclosedBracket(bracket) {
|
|
throw this.input.error(
|
|
"Unclosed bracket",
|
|
{ offset: bracket[2] },
|
|
{ offset: bracket[2] + 1 }
|
|
);
|
|
}
|
|
unexpectedClose(token) {
|
|
throw this.input.error(
|
|
"Unexpected }",
|
|
{ offset: token[2] },
|
|
{ offset: token[2] + 1 }
|
|
);
|
|
}
|
|
unknownWord(tokens) {
|
|
throw this.input.error(
|
|
"Unknown word",
|
|
{ offset: tokens[0][2] },
|
|
{ offset: tokens[0][2] + tokens[0][1].length }
|
|
);
|
|
}
|
|
unnamedAtrule(node2, token) {
|
|
throw this.input.error(
|
|
"At-rule without name",
|
|
{ offset: token[2] },
|
|
{ offset: token[2] + token[1].length }
|
|
);
|
|
}
|
|
}
|
|
parser$1 = Parser;
|
|
return parser$1;
|
|
}
|
|
var parse_1$1;
|
|
var hasRequiredParse$1;
|
|
function requireParse$1() {
|
|
if (hasRequiredParse$1) return parse_1$1;
|
|
hasRequiredParse$1 = 1;
|
|
let Container = requireContainer$1();
|
|
let Parser = requireParser$1();
|
|
let Input = requireInput$1();
|
|
function parse(css, opts) {
|
|
let input2 = new Input(css, opts);
|
|
let parser2 = new Parser(input2);
|
|
try {
|
|
parser2.parse();
|
|
} catch (e2) {
|
|
if (true) {
|
|
if (e2.name === "CssSyntaxError" && opts && opts.from) {
|
|
if (/\.scss$/i.test(opts.from)) {
|
|
e2.message += "\nYou tried to parse SCSS with the standard CSS parser; try again with the postcss-scss parser";
|
|
} else if (/\.sass/i.test(opts.from)) {
|
|
e2.message += "\nYou tried to parse Sass with the standard CSS parser; try again with the postcss-sass parser";
|
|
} else if (/\.less$/i.test(opts.from)) {
|
|
e2.message += "\nYou tried to parse Less with the standard CSS parser; try again with the postcss-less parser";
|
|
}
|
|
}
|
|
}
|
|
throw e2;
|
|
}
|
|
return parser2.root;
|
|
}
|
|
parse_1$1 = parse;
|
|
parse.default = parse;
|
|
Container.registerParse(parse);
|
|
return parse_1$1;
|
|
}
|
|
var lazyResult$1;
|
|
var hasRequiredLazyResult$1;
|
|
function requireLazyResult$1() {
|
|
if (hasRequiredLazyResult$1) return lazyResult$1;
|
|
hasRequiredLazyResult$1 = 1;
|
|
let { isClean, my } = requireSymbols$1();
|
|
let MapGenerator = requireMapGenerator$1();
|
|
let stringify = requireStringify$1();
|
|
let Container = requireContainer$1();
|
|
let Document2 = requireDocument$1();
|
|
let warnOnce2 = requireWarnOnce$1();
|
|
let Result = requireResult$1();
|
|
let parse = requireParse$1();
|
|
let Root = requireRoot$1();
|
|
const TYPE_TO_CLASS_NAME = {
|
|
atrule: "AtRule",
|
|
comment: "Comment",
|
|
decl: "Declaration",
|
|
document: "Document",
|
|
root: "Root",
|
|
rule: "Rule"
|
|
};
|
|
const PLUGIN_PROPS = {
|
|
AtRule: true,
|
|
AtRuleExit: true,
|
|
Comment: true,
|
|
CommentExit: true,
|
|
Declaration: true,
|
|
DeclarationExit: true,
|
|
Document: true,
|
|
DocumentExit: true,
|
|
Once: true,
|
|
OnceExit: true,
|
|
postcssPlugin: true,
|
|
prepare: true,
|
|
Root: true,
|
|
RootExit: true,
|
|
Rule: true,
|
|
RuleExit: true
|
|
};
|
|
const NOT_VISITORS = {
|
|
Once: true,
|
|
postcssPlugin: true,
|
|
prepare: true
|
|
};
|
|
const CHILDREN = 0;
|
|
function isPromise(obj) {
|
|
return typeof obj === "object" && typeof obj.then === "function";
|
|
}
|
|
function getEvents(node2) {
|
|
let key = false;
|
|
let type = TYPE_TO_CLASS_NAME[node2.type];
|
|
if (node2.type === "decl") {
|
|
key = node2.prop.toLowerCase();
|
|
} else if (node2.type === "atrule") {
|
|
key = node2.name.toLowerCase();
|
|
}
|
|
if (key && node2.append) {
|
|
return [
|
|
type,
|
|
type + "-" + key,
|
|
CHILDREN,
|
|
type + "Exit",
|
|
type + "Exit-" + key
|
|
];
|
|
} else if (key) {
|
|
return [type, type + "-" + key, type + "Exit", type + "Exit-" + key];
|
|
} else if (node2.append) {
|
|
return [type, CHILDREN, type + "Exit"];
|
|
} else {
|
|
return [type, type + "Exit"];
|
|
}
|
|
}
|
|
function toStack(node2) {
|
|
let events;
|
|
if (node2.type === "document") {
|
|
events = ["Document", CHILDREN, "DocumentExit"];
|
|
} else if (node2.type === "root") {
|
|
events = ["Root", CHILDREN, "RootExit"];
|
|
} else {
|
|
events = getEvents(node2);
|
|
}
|
|
return {
|
|
eventIndex: 0,
|
|
events,
|
|
iterator: 0,
|
|
node: node2,
|
|
visitorIndex: 0,
|
|
visitors: []
|
|
};
|
|
}
|
|
function cleanMarks(node2) {
|
|
node2[isClean] = false;
|
|
if (node2.nodes) node2.nodes.forEach((i2) => cleanMarks(i2));
|
|
return node2;
|
|
}
|
|
let postcss2 = {};
|
|
class LazyResult {
|
|
constructor(processor2, css, opts) {
|
|
this.stringified = false;
|
|
this.processed = false;
|
|
let root2;
|
|
if (typeof css === "object" && css !== null && (css.type === "root" || css.type === "document")) {
|
|
root2 = cleanMarks(css);
|
|
} else if (css instanceof LazyResult || css instanceof Result) {
|
|
root2 = cleanMarks(css.root);
|
|
if (css.map) {
|
|
if (typeof opts.map === "undefined") opts.map = {};
|
|
if (!opts.map.inline) opts.map.inline = false;
|
|
opts.map.prev = css.map;
|
|
}
|
|
} else {
|
|
let parser2 = parse;
|
|
if (opts.syntax) parser2 = opts.syntax.parse;
|
|
if (opts.parser) parser2 = opts.parser;
|
|
if (parser2.parse) parser2 = parser2.parse;
|
|
try {
|
|
root2 = parser2(css, opts);
|
|
} catch (error) {
|
|
this.processed = true;
|
|
this.error = error;
|
|
}
|
|
if (root2 && !root2[my]) {
|
|
Container.rebuild(root2);
|
|
}
|
|
}
|
|
this.result = new Result(processor2, root2, opts);
|
|
this.helpers = __spreadProps(__spreadValues({}, postcss2), { postcss: postcss2, result: this.result });
|
|
this.plugins = this.processor.plugins.map((plugin) => {
|
|
if (typeof plugin === "object" && plugin.prepare) {
|
|
return __spreadValues(__spreadValues({}, plugin), plugin.prepare(this.result));
|
|
} else {
|
|
return plugin;
|
|
}
|
|
});
|
|
}
|
|
async() {
|
|
if (this.error) return Promise.reject(this.error);
|
|
if (this.processed) return Promise.resolve(this.result);
|
|
if (!this.processing) {
|
|
this.processing = this.runAsync();
|
|
}
|
|
return this.processing;
|
|
}
|
|
catch(onRejected) {
|
|
return this.async().catch(onRejected);
|
|
}
|
|
finally(onFinally) {
|
|
return this.async().then(onFinally, onFinally);
|
|
}
|
|
getAsyncError() {
|
|
throw new Error("Use process(css).then(cb) to work with async plugins");
|
|
}
|
|
handleError(error, node2) {
|
|
let plugin = this.result.lastPlugin;
|
|
try {
|
|
if (node2) node2.addToError(error);
|
|
this.error = error;
|
|
if (error.name === "CssSyntaxError" && !error.plugin) {
|
|
error.plugin = plugin.postcssPlugin;
|
|
error.setMessage();
|
|
} else if (plugin.postcssVersion) {
|
|
if (true) {
|
|
let pluginName = plugin.postcssPlugin;
|
|
let pluginVer = plugin.postcssVersion;
|
|
let runtimeVer = this.result.processor.version;
|
|
let a2 = pluginVer.split(".");
|
|
let b = runtimeVer.split(".");
|
|
if (a2[0] !== b[0] || parseInt(a2[1]) > parseInt(b[1])) {
|
|
console.error(
|
|
"Unknown error from PostCSS plugin. Your current PostCSS version is " + runtimeVer + ", but " + pluginName + " uses " + pluginVer + ". Perhaps this is the source of the error below."
|
|
);
|
|
}
|
|
}
|
|
}
|
|
} catch (err) {
|
|
if (console && console.error) console.error(err);
|
|
}
|
|
return error;
|
|
}
|
|
prepareVisitors() {
|
|
this.listeners = {};
|
|
let add = (plugin, type, cb) => {
|
|
if (!this.listeners[type]) this.listeners[type] = [];
|
|
this.listeners[type].push([plugin, cb]);
|
|
};
|
|
for (let plugin of this.plugins) {
|
|
if (typeof plugin === "object") {
|
|
for (let event in plugin) {
|
|
if (!PLUGIN_PROPS[event] && /^[A-Z]/.test(event)) {
|
|
throw new Error(
|
|
`Unknown event ${event} in ${plugin.postcssPlugin}. Try to update PostCSS (${this.processor.version} now).`
|
|
);
|
|
}
|
|
if (!NOT_VISITORS[event]) {
|
|
if (typeof plugin[event] === "object") {
|
|
for (let filter in plugin[event]) {
|
|
if (filter === "*") {
|
|
add(plugin, event, plugin[event][filter]);
|
|
} else {
|
|
add(
|
|
plugin,
|
|
event + "-" + filter.toLowerCase(),
|
|
plugin[event][filter]
|
|
);
|
|
}
|
|
}
|
|
} else if (typeof plugin[event] === "function") {
|
|
add(plugin, event, plugin[event]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
this.hasListener = Object.keys(this.listeners).length > 0;
|
|
}
|
|
async runAsync() {
|
|
this.plugin = 0;
|
|
for (let i2 = 0; i2 < this.plugins.length; i2++) {
|
|
let plugin = this.plugins[i2];
|
|
let promise = this.runOnRoot(plugin);
|
|
if (isPromise(promise)) {
|
|
try {
|
|
await promise;
|
|
} catch (error) {
|
|
throw this.handleError(error);
|
|
}
|
|
}
|
|
}
|
|
this.prepareVisitors();
|
|
if (this.hasListener) {
|
|
let root2 = this.result.root;
|
|
while (!root2[isClean]) {
|
|
root2[isClean] = true;
|
|
let stack = [toStack(root2)];
|
|
while (stack.length > 0) {
|
|
let promise = this.visitTick(stack);
|
|
if (isPromise(promise)) {
|
|
try {
|
|
await promise;
|
|
} catch (e2) {
|
|
let node2 = stack[stack.length - 1].node;
|
|
throw this.handleError(e2, node2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (this.listeners.OnceExit) {
|
|
for (let [plugin, visitor] of this.listeners.OnceExit) {
|
|
this.result.lastPlugin = plugin;
|
|
try {
|
|
if (root2.type === "document") {
|
|
let roots = root2.nodes.map(
|
|
(subRoot) => visitor(subRoot, this.helpers)
|
|
);
|
|
await Promise.all(roots);
|
|
} else {
|
|
await visitor(root2, this.helpers);
|
|
}
|
|
} catch (e2) {
|
|
throw this.handleError(e2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
this.processed = true;
|
|
return this.stringify();
|
|
}
|
|
runOnRoot(plugin) {
|
|
this.result.lastPlugin = plugin;
|
|
try {
|
|
if (typeof plugin === "object" && plugin.Once) {
|
|
if (this.result.root.type === "document") {
|
|
let roots = this.result.root.nodes.map(
|
|
(root2) => plugin.Once(root2, this.helpers)
|
|
);
|
|
if (isPromise(roots[0])) {
|
|
return Promise.all(roots);
|
|
}
|
|
return roots;
|
|
}
|
|
return plugin.Once(this.result.root, this.helpers);
|
|
} else if (typeof plugin === "function") {
|
|
return plugin(this.result.root, this.result);
|
|
}
|
|
} catch (error) {
|
|
throw this.handleError(error);
|
|
}
|
|
}
|
|
stringify() {
|
|
if (this.error) throw this.error;
|
|
if (this.stringified) return this.result;
|
|
this.stringified = true;
|
|
this.sync();
|
|
let opts = this.result.opts;
|
|
let str = stringify;
|
|
if (opts.syntax) str = opts.syntax.stringify;
|
|
if (opts.stringifier) str = opts.stringifier;
|
|
if (str.stringify) str = str.stringify;
|
|
let map = new MapGenerator(str, this.result.root, this.result.opts);
|
|
let data = map.generate();
|
|
this.result.css = data[0];
|
|
this.result.map = data[1];
|
|
return this.result;
|
|
}
|
|
sync() {
|
|
if (this.error) throw this.error;
|
|
if (this.processed) return this.result;
|
|
this.processed = true;
|
|
if (this.processing) {
|
|
throw this.getAsyncError();
|
|
}
|
|
for (let plugin of this.plugins) {
|
|
let promise = this.runOnRoot(plugin);
|
|
if (isPromise(promise)) {
|
|
throw this.getAsyncError();
|
|
}
|
|
}
|
|
this.prepareVisitors();
|
|
if (this.hasListener) {
|
|
let root2 = this.result.root;
|
|
while (!root2[isClean]) {
|
|
root2[isClean] = true;
|
|
this.walkSync(root2);
|
|
}
|
|
if (this.listeners.OnceExit) {
|
|
if (root2.type === "document") {
|
|
for (let subRoot of root2.nodes) {
|
|
this.visitSync(this.listeners.OnceExit, subRoot);
|
|
}
|
|
} else {
|
|
this.visitSync(this.listeners.OnceExit, root2);
|
|
}
|
|
}
|
|
}
|
|
return this.result;
|
|
}
|
|
then(onFulfilled, onRejected) {
|
|
if (true) {
|
|
if (!("from" in this.opts)) {
|
|
warnOnce2(
|
|
"Without `from` option PostCSS could generate wrong source map and will not find Browserslist config. Set it to CSS file path or to `undefined` to prevent this warning."
|
|
);
|
|
}
|
|
}
|
|
return this.async().then(onFulfilled, onRejected);
|
|
}
|
|
toString() {
|
|
return this.css;
|
|
}
|
|
visitSync(visitors, node2) {
|
|
for (let [plugin, visitor] of visitors) {
|
|
this.result.lastPlugin = plugin;
|
|
let promise;
|
|
try {
|
|
promise = visitor(node2, this.helpers);
|
|
} catch (e2) {
|
|
throw this.handleError(e2, node2.proxyOf);
|
|
}
|
|
if (node2.type !== "root" && node2.type !== "document" && !node2.parent) {
|
|
return true;
|
|
}
|
|
if (isPromise(promise)) {
|
|
throw this.getAsyncError();
|
|
}
|
|
}
|
|
}
|
|
visitTick(stack) {
|
|
let visit2 = stack[stack.length - 1];
|
|
let { node: node2, visitors } = visit2;
|
|
if (node2.type !== "root" && node2.type !== "document" && !node2.parent) {
|
|
stack.pop();
|
|
return;
|
|
}
|
|
if (visitors.length > 0 && visit2.visitorIndex < visitors.length) {
|
|
let [plugin, visitor] = visitors[visit2.visitorIndex];
|
|
visit2.visitorIndex += 1;
|
|
if (visit2.visitorIndex === visitors.length) {
|
|
visit2.visitors = [];
|
|
visit2.visitorIndex = 0;
|
|
}
|
|
this.result.lastPlugin = plugin;
|
|
try {
|
|
return visitor(node2.toProxy(), this.helpers);
|
|
} catch (e2) {
|
|
throw this.handleError(e2, node2);
|
|
}
|
|
}
|
|
if (visit2.iterator !== 0) {
|
|
let iterator = visit2.iterator;
|
|
let child;
|
|
while (child = node2.nodes[node2.indexes[iterator]]) {
|
|
node2.indexes[iterator] += 1;
|
|
if (!child[isClean]) {
|
|
child[isClean] = true;
|
|
stack.push(toStack(child));
|
|
return;
|
|
}
|
|
}
|
|
visit2.iterator = 0;
|
|
delete node2.indexes[iterator];
|
|
}
|
|
let events = visit2.events;
|
|
while (visit2.eventIndex < events.length) {
|
|
let event = events[visit2.eventIndex];
|
|
visit2.eventIndex += 1;
|
|
if (event === CHILDREN) {
|
|
if (node2.nodes && node2.nodes.length) {
|
|
node2[isClean] = true;
|
|
visit2.iterator = node2.getIterator();
|
|
}
|
|
return;
|
|
} else if (this.listeners[event]) {
|
|
visit2.visitors = this.listeners[event];
|
|
return;
|
|
}
|
|
}
|
|
stack.pop();
|
|
}
|
|
walkSync(node2) {
|
|
node2[isClean] = true;
|
|
let events = getEvents(node2);
|
|
for (let event of events) {
|
|
if (event === CHILDREN) {
|
|
if (node2.nodes) {
|
|
node2.each((child) => {
|
|
if (!child[isClean]) this.walkSync(child);
|
|
});
|
|
}
|
|
} else {
|
|
let visitors = this.listeners[event];
|
|
if (visitors) {
|
|
if (this.visitSync(visitors, node2.toProxy())) return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
warnings() {
|
|
return this.sync().warnings();
|
|
}
|
|
get content() {
|
|
return this.stringify().content;
|
|
}
|
|
get css() {
|
|
return this.stringify().css;
|
|
}
|
|
get map() {
|
|
return this.stringify().map;
|
|
}
|
|
get messages() {
|
|
return this.sync().messages;
|
|
}
|
|
get opts() {
|
|
return this.result.opts;
|
|
}
|
|
get processor() {
|
|
return this.result.processor;
|
|
}
|
|
get root() {
|
|
return this.sync().root;
|
|
}
|
|
get [Symbol.toStringTag]() {
|
|
return "LazyResult";
|
|
}
|
|
}
|
|
LazyResult.registerPostcss = (dependant) => {
|
|
postcss2 = dependant;
|
|
};
|
|
lazyResult$1 = LazyResult;
|
|
LazyResult.default = LazyResult;
|
|
Root.registerLazyResult(LazyResult);
|
|
Document2.registerLazyResult(LazyResult);
|
|
return lazyResult$1;
|
|
}
|
|
var noWorkResult$1;
|
|
var hasRequiredNoWorkResult$1;
|
|
function requireNoWorkResult$1() {
|
|
if (hasRequiredNoWorkResult$1) return noWorkResult$1;
|
|
hasRequiredNoWorkResult$1 = 1;
|
|
let MapGenerator = requireMapGenerator$1();
|
|
let stringify = requireStringify$1();
|
|
let warnOnce2 = requireWarnOnce$1();
|
|
let parse = requireParse$1();
|
|
const Result = requireResult$1();
|
|
class NoWorkResult {
|
|
constructor(processor2, css, opts) {
|
|
css = css.toString();
|
|
this.stringified = false;
|
|
this._processor = processor2;
|
|
this._css = css;
|
|
this._opts = opts;
|
|
this._map = void 0;
|
|
let root2;
|
|
let str = stringify;
|
|
this.result = new Result(this._processor, root2, this._opts);
|
|
this.result.css = css;
|
|
let self2 = this;
|
|
Object.defineProperty(this.result, "root", {
|
|
get() {
|
|
return self2.root;
|
|
}
|
|
});
|
|
let map = new MapGenerator(str, root2, this._opts, css);
|
|
if (map.isMap()) {
|
|
let [generatedCSS, generatedMap] = map.generate();
|
|
if (generatedCSS) {
|
|
this.result.css = generatedCSS;
|
|
}
|
|
if (generatedMap) {
|
|
this.result.map = generatedMap;
|
|
}
|
|
} else {
|
|
map.clearAnnotation();
|
|
this.result.css = map.css;
|
|
}
|
|
}
|
|
async() {
|
|
if (this.error) return Promise.reject(this.error);
|
|
return Promise.resolve(this.result);
|
|
}
|
|
catch(onRejected) {
|
|
return this.async().catch(onRejected);
|
|
}
|
|
finally(onFinally) {
|
|
return this.async().then(onFinally, onFinally);
|
|
}
|
|
sync() {
|
|
if (this.error) throw this.error;
|
|
return this.result;
|
|
}
|
|
then(onFulfilled, onRejected) {
|
|
if (true) {
|
|
if (!("from" in this._opts)) {
|
|
warnOnce2(
|
|
"Without `from` option PostCSS could generate wrong source map and will not find Browserslist config. Set it to CSS file path or to `undefined` to prevent this warning."
|
|
);
|
|
}
|
|
}
|
|
return this.async().then(onFulfilled, onRejected);
|
|
}
|
|
toString() {
|
|
return this._css;
|
|
}
|
|
warnings() {
|
|
return [];
|
|
}
|
|
get content() {
|
|
return this.result.css;
|
|
}
|
|
get css() {
|
|
return this.result.css;
|
|
}
|
|
get map() {
|
|
return this.result.map;
|
|
}
|
|
get messages() {
|
|
return [];
|
|
}
|
|
get opts() {
|
|
return this.result.opts;
|
|
}
|
|
get processor() {
|
|
return this.result.processor;
|
|
}
|
|
get root() {
|
|
if (this._root) {
|
|
return this._root;
|
|
}
|
|
let root2;
|
|
let parser2 = parse;
|
|
try {
|
|
root2 = parser2(this._css, this._opts);
|
|
} catch (error) {
|
|
this.error = error;
|
|
}
|
|
if (this.error) {
|
|
throw this.error;
|
|
} else {
|
|
this._root = root2;
|
|
return root2;
|
|
}
|
|
}
|
|
get [Symbol.toStringTag]() {
|
|
return "NoWorkResult";
|
|
}
|
|
}
|
|
noWorkResult$1 = NoWorkResult;
|
|
NoWorkResult.default = NoWorkResult;
|
|
return noWorkResult$1;
|
|
}
|
|
var processor$1;
|
|
var hasRequiredProcessor$1;
|
|
function requireProcessor$1() {
|
|
if (hasRequiredProcessor$1) return processor$1;
|
|
hasRequiredProcessor$1 = 1;
|
|
let NoWorkResult = requireNoWorkResult$1();
|
|
let LazyResult = requireLazyResult$1();
|
|
let Document2 = requireDocument$1();
|
|
let Root = requireRoot$1();
|
|
class Processor {
|
|
constructor(plugins = []) {
|
|
this.version = "8.4.38";
|
|
this.plugins = this.normalize(plugins);
|
|
}
|
|
normalize(plugins) {
|
|
let normalized = [];
|
|
for (let i2 of plugins) {
|
|
if (i2.postcss === true) {
|
|
i2 = i2();
|
|
} else if (i2.postcss) {
|
|
i2 = i2.postcss;
|
|
}
|
|
if (typeof i2 === "object" && Array.isArray(i2.plugins)) {
|
|
normalized = normalized.concat(i2.plugins);
|
|
} else if (typeof i2 === "object" && i2.postcssPlugin) {
|
|
normalized.push(i2);
|
|
} else if (typeof i2 === "function") {
|
|
normalized.push(i2);
|
|
} else if (typeof i2 === "object" && (i2.parse || i2.stringify)) {
|
|
if (true) {
|
|
throw new Error(
|
|
"PostCSS syntaxes cannot be used as plugins. Instead, please use one of the syntax/parser/stringifier options as outlined in your PostCSS runner documentation."
|
|
);
|
|
}
|
|
} else {
|
|
throw new Error(i2 + " is not a PostCSS plugin");
|
|
}
|
|
}
|
|
return normalized;
|
|
}
|
|
process(css, opts = {}) {
|
|
if (!this.plugins.length && !opts.parser && !opts.stringifier && !opts.syntax) {
|
|
return new NoWorkResult(this, css, opts);
|
|
} else {
|
|
return new LazyResult(this, css, opts);
|
|
}
|
|
}
|
|
use(plugin) {
|
|
this.plugins = this.plugins.concat(this.normalize([plugin]));
|
|
return this;
|
|
}
|
|
}
|
|
processor$1 = Processor;
|
|
Processor.default = Processor;
|
|
Root.registerProcessor(Processor);
|
|
Document2.registerProcessor(Processor);
|
|
return processor$1;
|
|
}
|
|
var fromJSON_1$1;
|
|
var hasRequiredFromJSON$1;
|
|
function requireFromJSON$1() {
|
|
if (hasRequiredFromJSON$1) return fromJSON_1$1;
|
|
hasRequiredFromJSON$1 = 1;
|
|
let Declaration = requireDeclaration$1();
|
|
let PreviousMap = requirePreviousMap$1();
|
|
let Comment = requireComment$1();
|
|
let AtRule = requireAtRule$1();
|
|
let Input = requireInput$1();
|
|
let Root = requireRoot$1();
|
|
let Rule = requireRule$1();
|
|
function fromJSON(json, inputs) {
|
|
if (Array.isArray(json)) return json.map((n2) => fromJSON(n2));
|
|
let _a2 = json, { inputs: ownInputs } = _a2, defaults = __objRest(_a2, ["inputs"]);
|
|
if (ownInputs) {
|
|
inputs = [];
|
|
for (let input2 of ownInputs) {
|
|
let inputHydrated = __spreadProps(__spreadValues({}, input2), { __proto__: Input.prototype });
|
|
if (inputHydrated.map) {
|
|
inputHydrated.map = __spreadProps(__spreadValues({}, inputHydrated.map), {
|
|
__proto__: PreviousMap.prototype
|
|
});
|
|
}
|
|
inputs.push(inputHydrated);
|
|
}
|
|
}
|
|
if (defaults.nodes) {
|
|
defaults.nodes = json.nodes.map((n2) => fromJSON(n2, inputs));
|
|
}
|
|
if (defaults.source) {
|
|
let _b = defaults.source, { inputId } = _b, source = __objRest(_b, ["inputId"]);
|
|
defaults.source = source;
|
|
if (inputId != null) {
|
|
defaults.source.input = inputs[inputId];
|
|
}
|
|
}
|
|
if (defaults.type === "root") {
|
|
return new Root(defaults);
|
|
} else if (defaults.type === "decl") {
|
|
return new Declaration(defaults);
|
|
} else if (defaults.type === "rule") {
|
|
return new Rule(defaults);
|
|
} else if (defaults.type === "comment") {
|
|
return new Comment(defaults);
|
|
} else if (defaults.type === "atrule") {
|
|
return new AtRule(defaults);
|
|
} else {
|
|
throw new Error("Unknown node type: " + json.type);
|
|
}
|
|
}
|
|
fromJSON_1$1 = fromJSON;
|
|
fromJSON.default = fromJSON;
|
|
return fromJSON_1$1;
|
|
}
|
|
var postcss_1$1;
|
|
var hasRequiredPostcss$1;
|
|
function requirePostcss$1() {
|
|
if (hasRequiredPostcss$1) return postcss_1$1;
|
|
hasRequiredPostcss$1 = 1;
|
|
let CssSyntaxError = requireCssSyntaxError$1();
|
|
let Declaration = requireDeclaration$1();
|
|
let LazyResult = requireLazyResult$1();
|
|
let Container = requireContainer$1();
|
|
let Processor = requireProcessor$1();
|
|
let stringify = requireStringify$1();
|
|
let fromJSON = requireFromJSON$1();
|
|
let Document2 = requireDocument$1();
|
|
let Warning = requireWarning$1();
|
|
let Comment = requireComment$1();
|
|
let AtRule = requireAtRule$1();
|
|
let Result = requireResult$1();
|
|
let Input = requireInput$1();
|
|
let parse = requireParse$1();
|
|
let list = requireList$1();
|
|
let Rule = requireRule$1();
|
|
let Root = requireRoot$1();
|
|
let Node2 = requireNode$1();
|
|
function postcss2(...plugins) {
|
|
if (plugins.length === 1 && Array.isArray(plugins[0])) {
|
|
plugins = plugins[0];
|
|
}
|
|
return new Processor(plugins);
|
|
}
|
|
postcss2.plugin = function plugin(name, initializer) {
|
|
let warningPrinted = false;
|
|
function creator(...args) {
|
|
if (console && console.warn && !warningPrinted) {
|
|
warningPrinted = true;
|
|
console.warn(
|
|
name + ": postcss.plugin was deprecated. Migration guide:\nhttps://evilmartians.com/chronicles/postcss-8-plugin-migration"
|
|
);
|
|
if (process.env.LANG && process.env.LANG.startsWith("cn")) {
|
|
console.warn(
|
|
name + ": \u91CC\u9762 postcss.plugin \u88AB\u5F03\u7528. \u8FC1\u79FB\u6307\u5357:\nhttps://www.w3ctech.com/topic/2226"
|
|
);
|
|
}
|
|
}
|
|
let transformer = initializer(...args);
|
|
transformer.postcssPlugin = name;
|
|
transformer.postcssVersion = new Processor().version;
|
|
return transformer;
|
|
}
|
|
let cache;
|
|
Object.defineProperty(creator, "postcss", {
|
|
get() {
|
|
if (!cache) cache = creator();
|
|
return cache;
|
|
}
|
|
});
|
|
creator.process = function(css, processOpts, pluginOpts) {
|
|
return postcss2([creator(pluginOpts)]).process(css, processOpts);
|
|
};
|
|
return creator;
|
|
};
|
|
postcss2.stringify = stringify;
|
|
postcss2.parse = parse;
|
|
postcss2.fromJSON = fromJSON;
|
|
postcss2.list = list;
|
|
postcss2.comment = (defaults) => new Comment(defaults);
|
|
postcss2.atRule = (defaults) => new AtRule(defaults);
|
|
postcss2.decl = (defaults) => new Declaration(defaults);
|
|
postcss2.rule = (defaults) => new Rule(defaults);
|
|
postcss2.root = (defaults) => new Root(defaults);
|
|
postcss2.document = (defaults) => new Document2(defaults);
|
|
postcss2.CssSyntaxError = CssSyntaxError;
|
|
postcss2.Declaration = Declaration;
|
|
postcss2.Container = Container;
|
|
postcss2.Processor = Processor;
|
|
postcss2.Document = Document2;
|
|
postcss2.Comment = Comment;
|
|
postcss2.Warning = Warning;
|
|
postcss2.AtRule = AtRule;
|
|
postcss2.Result = Result;
|
|
postcss2.Input = Input;
|
|
postcss2.Rule = Rule;
|
|
postcss2.Root = Root;
|
|
postcss2.Node = Node2;
|
|
LazyResult.registerPostcss(postcss2);
|
|
postcss_1$1 = postcss2;
|
|
postcss2.default = postcss2;
|
|
return postcss_1$1;
|
|
}
|
|
var postcssExports$1 = requirePostcss$1();
|
|
const postcss$1 = /* @__PURE__ */ getDefaultExportFromCjs$1(postcssExports$1);
|
|
postcss$1.stringify;
|
|
postcss$1.fromJSON;
|
|
postcss$1.plugin;
|
|
postcss$1.parse;
|
|
postcss$1.list;
|
|
postcss$1.document;
|
|
postcss$1.comment;
|
|
postcss$1.atRule;
|
|
postcss$1.rule;
|
|
postcss$1.decl;
|
|
postcss$1.root;
|
|
postcss$1.CssSyntaxError;
|
|
postcss$1.Declaration;
|
|
postcss$1.Container;
|
|
postcss$1.Processor;
|
|
postcss$1.Document;
|
|
postcss$1.Comment;
|
|
postcss$1.Warning;
|
|
postcss$1.AtRule;
|
|
postcss$1.Result;
|
|
postcss$1.Input;
|
|
postcss$1.Rule;
|
|
postcss$1.Root;
|
|
postcss$1.Node;
|
|
var __defProp22 = Object.defineProperty;
|
|
var __defNormalProp22 = (obj, key, value) => key in obj ? __defProp22(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
var __publicField2 = (obj, key, value) => __defNormalProp22(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
function getDefaultExportFromCjs(x) {
|
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
|
|
}
|
|
function getAugmentedNamespace(n2) {
|
|
if (n2.__esModule) return n2;
|
|
var f2 = n2.default;
|
|
if (typeof f2 == "function") {
|
|
var a2 = function a22() {
|
|
if (this instanceof a22) {
|
|
return Reflect.construct(f2, arguments, this.constructor);
|
|
}
|
|
return f2.apply(this, arguments);
|
|
};
|
|
a2.prototype = f2.prototype;
|
|
} else a2 = {};
|
|
Object.defineProperty(a2, "__esModule", { value: true });
|
|
Object.keys(n2).forEach(function(k) {
|
|
var d = Object.getOwnPropertyDescriptor(n2, k);
|
|
Object.defineProperty(a2, k, d.get ? d : {
|
|
enumerable: true,
|
|
get: function() {
|
|
return n2[k];
|
|
}
|
|
});
|
|
});
|
|
return a2;
|
|
}
|
|
var picocolors_browser = { exports: {} };
|
|
var hasRequiredPicocolors_browser;
|
|
function requirePicocolors_browser() {
|
|
if (hasRequiredPicocolors_browser) return picocolors_browser.exports;
|
|
hasRequiredPicocolors_browser = 1;
|
|
var x = String;
|
|
var create = function() {
|
|
return { isColorSupported: false, reset: x, bold: x, dim: x, italic: x, underline: x, inverse: x, hidden: x, strikethrough: x, black: x, red: x, green: x, yellow: x, blue: x, magenta: x, cyan: x, white: x, gray: x, bgBlack: x, bgRed: x, bgGreen: x, bgYellow: x, bgBlue: x, bgMagenta: x, bgCyan: x, bgWhite: x };
|
|
};
|
|
picocolors_browser.exports = create();
|
|
picocolors_browser.exports.createColors = create;
|
|
return picocolors_browser.exports;
|
|
}
|
|
const __viteBrowserExternal = {};
|
|
const __viteBrowserExternal$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
__proto__: null,
|
|
default: __viteBrowserExternal
|
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
const require$$2 = /* @__PURE__ */ getAugmentedNamespace(__viteBrowserExternal$1);
|
|
var cssSyntaxError;
|
|
var hasRequiredCssSyntaxError;
|
|
function requireCssSyntaxError() {
|
|
if (hasRequiredCssSyntaxError) return cssSyntaxError;
|
|
hasRequiredCssSyntaxError = 1;
|
|
let pico = /* @__PURE__ */ requirePicocolors_browser();
|
|
let terminalHighlight = require$$2;
|
|
class CssSyntaxError extends Error {
|
|
constructor(message, line, column, source, file, plugin) {
|
|
super(message);
|
|
this.name = "CssSyntaxError";
|
|
this.reason = message;
|
|
if (file) {
|
|
this.file = file;
|
|
}
|
|
if (source) {
|
|
this.source = source;
|
|
}
|
|
if (plugin) {
|
|
this.plugin = plugin;
|
|
}
|
|
if (typeof line !== "undefined" && typeof column !== "undefined") {
|
|
if (typeof line === "number") {
|
|
this.line = line;
|
|
this.column = column;
|
|
} else {
|
|
this.line = line.line;
|
|
this.column = line.column;
|
|
this.endLine = column.line;
|
|
this.endColumn = column.column;
|
|
}
|
|
}
|
|
this.setMessage();
|
|
if (Error.captureStackTrace) {
|
|
Error.captureStackTrace(this, CssSyntaxError);
|
|
}
|
|
}
|
|
setMessage() {
|
|
this.message = this.plugin ? this.plugin + ": " : "";
|
|
this.message += this.file ? this.file : "<css input>";
|
|
if (typeof this.line !== "undefined") {
|
|
this.message += ":" + this.line + ":" + this.column;
|
|
}
|
|
this.message += ": " + this.reason;
|
|
}
|
|
showSourceCode(color) {
|
|
if (!this.source) return "";
|
|
let css = this.source;
|
|
if (color == null) color = pico.isColorSupported;
|
|
if (terminalHighlight) {
|
|
if (color) css = terminalHighlight(css);
|
|
}
|
|
let lines = css.split(/\r?\n/);
|
|
let start = Math.max(this.line - 3, 0);
|
|
let end = Math.min(this.line + 2, lines.length);
|
|
let maxWidth = String(end).length;
|
|
let mark, aside;
|
|
if (color) {
|
|
let { bold, gray, red } = pico.createColors(true);
|
|
mark = (text) => bold(red(text));
|
|
aside = (text) => gray(text);
|
|
} else {
|
|
mark = aside = (str) => str;
|
|
}
|
|
return lines.slice(start, end).map((line, index2) => {
|
|
let number = start + 1 + index2;
|
|
let gutter = " " + (" " + number).slice(-maxWidth) + " | ";
|
|
if (number === this.line) {
|
|
let spacing = aside(gutter.replace(/\d/g, " ")) + line.slice(0, this.column - 1).replace(/[^\t]/g, " ");
|
|
return mark(">") + aside(gutter) + line + "\n " + spacing + mark("^");
|
|
}
|
|
return " " + aside(gutter) + line;
|
|
}).join("\n");
|
|
}
|
|
toString() {
|
|
let code = this.showSourceCode();
|
|
if (code) {
|
|
code = "\n\n" + code + "\n";
|
|
}
|
|
return this.name + ": " + this.message + code;
|
|
}
|
|
}
|
|
cssSyntaxError = CssSyntaxError;
|
|
CssSyntaxError.default = CssSyntaxError;
|
|
return cssSyntaxError;
|
|
}
|
|
var symbols = {};
|
|
var hasRequiredSymbols;
|
|
function requireSymbols() {
|
|
if (hasRequiredSymbols) return symbols;
|
|
hasRequiredSymbols = 1;
|
|
symbols.isClean = Symbol("isClean");
|
|
symbols.my = Symbol("my");
|
|
return symbols;
|
|
}
|
|
var stringifier;
|
|
var hasRequiredStringifier;
|
|
function requireStringifier() {
|
|
if (hasRequiredStringifier) return stringifier;
|
|
hasRequiredStringifier = 1;
|
|
const DEFAULT_RAW = {
|
|
after: "\n",
|
|
beforeClose: "\n",
|
|
beforeComment: "\n",
|
|
beforeDecl: "\n",
|
|
beforeOpen: " ",
|
|
beforeRule: "\n",
|
|
colon: ": ",
|
|
commentLeft: " ",
|
|
commentRight: " ",
|
|
emptyBody: "",
|
|
indent: " ",
|
|
semicolon: false
|
|
};
|
|
function capitalize(str) {
|
|
return str[0].toUpperCase() + str.slice(1);
|
|
}
|
|
class Stringifier {
|
|
constructor(builder) {
|
|
this.builder = builder;
|
|
}
|
|
atrule(node2, semicolon) {
|
|
let name = "@" + node2.name;
|
|
let params = node2.params ? this.rawValue(node2, "params") : "";
|
|
if (typeof node2.raws.afterName !== "undefined") {
|
|
name += node2.raws.afterName;
|
|
} else if (params) {
|
|
name += " ";
|
|
}
|
|
if (node2.nodes) {
|
|
this.block(node2, name + params);
|
|
} else {
|
|
let end = (node2.raws.between || "") + (semicolon ? ";" : "");
|
|
this.builder(name + params + end, node2);
|
|
}
|
|
}
|
|
beforeAfter(node2, detect) {
|
|
let value;
|
|
if (node2.type === "decl") {
|
|
value = this.raw(node2, null, "beforeDecl");
|
|
} else if (node2.type === "comment") {
|
|
value = this.raw(node2, null, "beforeComment");
|
|
} else if (detect === "before") {
|
|
value = this.raw(node2, null, "beforeRule");
|
|
} else {
|
|
value = this.raw(node2, null, "beforeClose");
|
|
}
|
|
let buf = node2.parent;
|
|
let depth = 0;
|
|
while (buf && buf.type !== "root") {
|
|
depth += 1;
|
|
buf = buf.parent;
|
|
}
|
|
if (value.includes("\n")) {
|
|
let indent = this.raw(node2, null, "indent");
|
|
if (indent.length) {
|
|
for (let step = 0; step < depth; step++) value += indent;
|
|
}
|
|
}
|
|
return value;
|
|
}
|
|
block(node2, start) {
|
|
let between = this.raw(node2, "between", "beforeOpen");
|
|
this.builder(start + between + "{", node2, "start");
|
|
let after;
|
|
if (node2.nodes && node2.nodes.length) {
|
|
this.body(node2);
|
|
after = this.raw(node2, "after");
|
|
} else {
|
|
after = this.raw(node2, "after", "emptyBody");
|
|
}
|
|
if (after) this.builder(after);
|
|
this.builder("}", node2, "end");
|
|
}
|
|
body(node2) {
|
|
let last = node2.nodes.length - 1;
|
|
while (last > 0) {
|
|
if (node2.nodes[last].type !== "comment") break;
|
|
last -= 1;
|
|
}
|
|
let semicolon = this.raw(node2, "semicolon");
|
|
for (let i2 = 0; i2 < node2.nodes.length; i2++) {
|
|
let child = node2.nodes[i2];
|
|
let before = this.raw(child, "before");
|
|
if (before) this.builder(before);
|
|
this.stringify(child, last !== i2 || semicolon);
|
|
}
|
|
}
|
|
comment(node2) {
|
|
let left = this.raw(node2, "left", "commentLeft");
|
|
let right = this.raw(node2, "right", "commentRight");
|
|
this.builder("/*" + left + node2.text + right + "*/", node2);
|
|
}
|
|
decl(node2, semicolon) {
|
|
let between = this.raw(node2, "between", "colon");
|
|
let string = node2.prop + between + this.rawValue(node2, "value");
|
|
if (node2.important) {
|
|
string += node2.raws.important || " !important";
|
|
}
|
|
if (semicolon) string += ";";
|
|
this.builder(string, node2);
|
|
}
|
|
document(node2) {
|
|
this.body(node2);
|
|
}
|
|
raw(node2, own, detect) {
|
|
let value;
|
|
if (!detect) detect = own;
|
|
if (own) {
|
|
value = node2.raws[own];
|
|
if (typeof value !== "undefined") return value;
|
|
}
|
|
let parent = node2.parent;
|
|
if (detect === "before") {
|
|
if (!parent || parent.type === "root" && parent.first === node2) {
|
|
return "";
|
|
}
|
|
if (parent && parent.type === "document") {
|
|
return "";
|
|
}
|
|
}
|
|
if (!parent) return DEFAULT_RAW[detect];
|
|
let root2 = node2.root();
|
|
if (!root2.rawCache) root2.rawCache = {};
|
|
if (typeof root2.rawCache[detect] !== "undefined") {
|
|
return root2.rawCache[detect];
|
|
}
|
|
if (detect === "before" || detect === "after") {
|
|
return this.beforeAfter(node2, detect);
|
|
} else {
|
|
let method = "raw" + capitalize(detect);
|
|
if (this[method]) {
|
|
value = this[method](root2, node2);
|
|
} else {
|
|
root2.walk((i2) => {
|
|
value = i2.raws[own];
|
|
if (typeof value !== "undefined") return false;
|
|
});
|
|
}
|
|
}
|
|
if (typeof value === "undefined") value = DEFAULT_RAW[detect];
|
|
root2.rawCache[detect] = value;
|
|
return value;
|
|
}
|
|
rawBeforeClose(root2) {
|
|
let value;
|
|
root2.walk((i2) => {
|
|
if (i2.nodes && i2.nodes.length > 0) {
|
|
if (typeof i2.raws.after !== "undefined") {
|
|
value = i2.raws.after;
|
|
if (value.includes("\n")) {
|
|
value = value.replace(/[^\n]+$/, "");
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
});
|
|
if (value) value = value.replace(/\S/g, "");
|
|
return value;
|
|
}
|
|
rawBeforeComment(root2, node2) {
|
|
let value;
|
|
root2.walkComments((i2) => {
|
|
if (typeof i2.raws.before !== "undefined") {
|
|
value = i2.raws.before;
|
|
if (value.includes("\n")) {
|
|
value = value.replace(/[^\n]+$/, "");
|
|
}
|
|
return false;
|
|
}
|
|
});
|
|
if (typeof value === "undefined") {
|
|
value = this.raw(node2, null, "beforeDecl");
|
|
} else if (value) {
|
|
value = value.replace(/\S/g, "");
|
|
}
|
|
return value;
|
|
}
|
|
rawBeforeDecl(root2, node2) {
|
|
let value;
|
|
root2.walkDecls((i2) => {
|
|
if (typeof i2.raws.before !== "undefined") {
|
|
value = i2.raws.before;
|
|
if (value.includes("\n")) {
|
|
value = value.replace(/[^\n]+$/, "");
|
|
}
|
|
return false;
|
|
}
|
|
});
|
|
if (typeof value === "undefined") {
|
|
value = this.raw(node2, null, "beforeRule");
|
|
} else if (value) {
|
|
value = value.replace(/\S/g, "");
|
|
}
|
|
return value;
|
|
}
|
|
rawBeforeOpen(root2) {
|
|
let value;
|
|
root2.walk((i2) => {
|
|
if (i2.type !== "decl") {
|
|
value = i2.raws.between;
|
|
if (typeof value !== "undefined") return false;
|
|
}
|
|
});
|
|
return value;
|
|
}
|
|
rawBeforeRule(root2) {
|
|
let value;
|
|
root2.walk((i2) => {
|
|
if (i2.nodes && (i2.parent !== root2 || root2.first !== i2)) {
|
|
if (typeof i2.raws.before !== "undefined") {
|
|
value = i2.raws.before;
|
|
if (value.includes("\n")) {
|
|
value = value.replace(/[^\n]+$/, "");
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
});
|
|
if (value) value = value.replace(/\S/g, "");
|
|
return value;
|
|
}
|
|
rawColon(root2) {
|
|
let value;
|
|
root2.walkDecls((i2) => {
|
|
if (typeof i2.raws.between !== "undefined") {
|
|
value = i2.raws.between.replace(/[^\s:]/g, "");
|
|
return false;
|
|
}
|
|
});
|
|
return value;
|
|
}
|
|
rawEmptyBody(root2) {
|
|
let value;
|
|
root2.walk((i2) => {
|
|
if (i2.nodes && i2.nodes.length === 0) {
|
|
value = i2.raws.after;
|
|
if (typeof value !== "undefined") return false;
|
|
}
|
|
});
|
|
return value;
|
|
}
|
|
rawIndent(root2) {
|
|
if (root2.raws.indent) return root2.raws.indent;
|
|
let value;
|
|
root2.walk((i2) => {
|
|
let p = i2.parent;
|
|
if (p && p !== root2 && p.parent && p.parent === root2) {
|
|
if (typeof i2.raws.before !== "undefined") {
|
|
let parts = i2.raws.before.split("\n");
|
|
value = parts[parts.length - 1];
|
|
value = value.replace(/\S/g, "");
|
|
return false;
|
|
}
|
|
}
|
|
});
|
|
return value;
|
|
}
|
|
rawSemicolon(root2) {
|
|
let value;
|
|
root2.walk((i2) => {
|
|
if (i2.nodes && i2.nodes.length && i2.last.type === "decl") {
|
|
value = i2.raws.semicolon;
|
|
if (typeof value !== "undefined") return false;
|
|
}
|
|
});
|
|
return value;
|
|
}
|
|
rawValue(node2, prop) {
|
|
let value = node2[prop];
|
|
let raw = node2.raws[prop];
|
|
if (raw && raw.value === value) {
|
|
return raw.raw;
|
|
}
|
|
return value;
|
|
}
|
|
root(node2) {
|
|
this.body(node2);
|
|
if (node2.raws.after) this.builder(node2.raws.after);
|
|
}
|
|
rule(node2) {
|
|
this.block(node2, this.rawValue(node2, "selector"));
|
|
if (node2.raws.ownSemicolon) {
|
|
this.builder(node2.raws.ownSemicolon, node2, "end");
|
|
}
|
|
}
|
|
stringify(node2, semicolon) {
|
|
if (!this[node2.type]) {
|
|
throw new Error(
|
|
"Unknown AST node type " + node2.type + ". Maybe you need to change PostCSS stringifier."
|
|
);
|
|
}
|
|
this[node2.type](node2, semicolon);
|
|
}
|
|
}
|
|
stringifier = Stringifier;
|
|
Stringifier.default = Stringifier;
|
|
return stringifier;
|
|
}
|
|
var stringify_1;
|
|
var hasRequiredStringify;
|
|
function requireStringify() {
|
|
if (hasRequiredStringify) return stringify_1;
|
|
hasRequiredStringify = 1;
|
|
let Stringifier = requireStringifier();
|
|
function stringify(node2, builder) {
|
|
let str = new Stringifier(builder);
|
|
str.stringify(node2);
|
|
}
|
|
stringify_1 = stringify;
|
|
stringify.default = stringify;
|
|
return stringify_1;
|
|
}
|
|
var node;
|
|
var hasRequiredNode;
|
|
function requireNode() {
|
|
if (hasRequiredNode) return node;
|
|
hasRequiredNode = 1;
|
|
let { isClean, my } = requireSymbols();
|
|
let CssSyntaxError = requireCssSyntaxError();
|
|
let Stringifier = requireStringifier();
|
|
let stringify = requireStringify();
|
|
function cloneNode(obj, parent) {
|
|
let cloned = new obj.constructor();
|
|
for (let i2 in obj) {
|
|
if (!Object.prototype.hasOwnProperty.call(obj, i2)) {
|
|
continue;
|
|
}
|
|
if (i2 === "proxyCache") continue;
|
|
let value = obj[i2];
|
|
let type = typeof value;
|
|
if (i2 === "parent" && type === "object") {
|
|
if (parent) cloned[i2] = parent;
|
|
} else if (i2 === "source") {
|
|
cloned[i2] = value;
|
|
} else if (Array.isArray(value)) {
|
|
cloned[i2] = value.map((j) => cloneNode(j, cloned));
|
|
} else {
|
|
if (type === "object" && value !== null) value = cloneNode(value);
|
|
cloned[i2] = value;
|
|
}
|
|
}
|
|
return cloned;
|
|
}
|
|
class Node2 {
|
|
constructor(defaults = {}) {
|
|
this.raws = {};
|
|
this[isClean] = false;
|
|
this[my] = true;
|
|
for (let name in defaults) {
|
|
if (name === "nodes") {
|
|
this.nodes = [];
|
|
for (let node2 of defaults[name]) {
|
|
if (typeof node2.clone === "function") {
|
|
this.append(node2.clone());
|
|
} else {
|
|
this.append(node2);
|
|
}
|
|
}
|
|
} else {
|
|
this[name] = defaults[name];
|
|
}
|
|
}
|
|
}
|
|
addToError(error) {
|
|
error.postcssNode = this;
|
|
if (error.stack && this.source && /\n\s{4}at /.test(error.stack)) {
|
|
let s2 = this.source;
|
|
error.stack = error.stack.replace(
|
|
/\n\s{4}at /,
|
|
`$&${s2.input.from}:${s2.start.line}:${s2.start.column}$&`
|
|
);
|
|
}
|
|
return error;
|
|
}
|
|
after(add) {
|
|
this.parent.insertAfter(this, add);
|
|
return this;
|
|
}
|
|
assign(overrides = {}) {
|
|
for (let name in overrides) {
|
|
this[name] = overrides[name];
|
|
}
|
|
return this;
|
|
}
|
|
before(add) {
|
|
this.parent.insertBefore(this, add);
|
|
return this;
|
|
}
|
|
cleanRaws(keepBetween) {
|
|
delete this.raws.before;
|
|
delete this.raws.after;
|
|
if (!keepBetween) delete this.raws.between;
|
|
}
|
|
clone(overrides = {}) {
|
|
let cloned = cloneNode(this);
|
|
for (let name in overrides) {
|
|
cloned[name] = overrides[name];
|
|
}
|
|
return cloned;
|
|
}
|
|
cloneAfter(overrides = {}) {
|
|
let cloned = this.clone(overrides);
|
|
this.parent.insertAfter(this, cloned);
|
|
return cloned;
|
|
}
|
|
cloneBefore(overrides = {}) {
|
|
let cloned = this.clone(overrides);
|
|
this.parent.insertBefore(this, cloned);
|
|
return cloned;
|
|
}
|
|
error(message, opts = {}) {
|
|
if (this.source) {
|
|
let { end, start } = this.rangeBy(opts);
|
|
return this.source.input.error(
|
|
message,
|
|
{ column: start.column, line: start.line },
|
|
{ column: end.column, line: end.line },
|
|
opts
|
|
);
|
|
}
|
|
return new CssSyntaxError(message);
|
|
}
|
|
getProxyProcessor() {
|
|
return {
|
|
get(node2, prop) {
|
|
if (prop === "proxyOf") {
|
|
return node2;
|
|
} else if (prop === "root") {
|
|
return () => node2.root().toProxy();
|
|
} else {
|
|
return node2[prop];
|
|
}
|
|
},
|
|
set(node2, prop, value) {
|
|
if (node2[prop] === value) return true;
|
|
node2[prop] = value;
|
|
if (prop === "prop" || prop === "value" || prop === "name" || prop === "params" || prop === "important" || /* c8 ignore next */
|
|
prop === "text") {
|
|
node2.markDirty();
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
}
|
|
markDirty() {
|
|
if (this[isClean]) {
|
|
this[isClean] = false;
|
|
let next = this;
|
|
while (next = next.parent) {
|
|
next[isClean] = false;
|
|
}
|
|
}
|
|
}
|
|
next() {
|
|
if (!this.parent) return void 0;
|
|
let index2 = this.parent.index(this);
|
|
return this.parent.nodes[index2 + 1];
|
|
}
|
|
positionBy(opts, stringRepresentation) {
|
|
let pos = this.source.start;
|
|
if (opts.index) {
|
|
pos = this.positionInside(opts.index, stringRepresentation);
|
|
} else if (opts.word) {
|
|
stringRepresentation = this.toString();
|
|
let index2 = stringRepresentation.indexOf(opts.word);
|
|
if (index2 !== -1) pos = this.positionInside(index2, stringRepresentation);
|
|
}
|
|
return pos;
|
|
}
|
|
positionInside(index2, stringRepresentation) {
|
|
let string = stringRepresentation || this.toString();
|
|
let column = this.source.start.column;
|
|
let line = this.source.start.line;
|
|
for (let i2 = 0; i2 < index2; i2++) {
|
|
if (string[i2] === "\n") {
|
|
column = 1;
|
|
line += 1;
|
|
} else {
|
|
column += 1;
|
|
}
|
|
}
|
|
return { column, line };
|
|
}
|
|
prev() {
|
|
if (!this.parent) return void 0;
|
|
let index2 = this.parent.index(this);
|
|
return this.parent.nodes[index2 - 1];
|
|
}
|
|
rangeBy(opts) {
|
|
let start = {
|
|
column: this.source.start.column,
|
|
line: this.source.start.line
|
|
};
|
|
let end = this.source.end ? {
|
|
column: this.source.end.column + 1,
|
|
line: this.source.end.line
|
|
} : {
|
|
column: start.column + 1,
|
|
line: start.line
|
|
};
|
|
if (opts.word) {
|
|
let stringRepresentation = this.toString();
|
|
let index2 = stringRepresentation.indexOf(opts.word);
|
|
if (index2 !== -1) {
|
|
start = this.positionInside(index2, stringRepresentation);
|
|
end = this.positionInside(index2 + opts.word.length, stringRepresentation);
|
|
}
|
|
} else {
|
|
if (opts.start) {
|
|
start = {
|
|
column: opts.start.column,
|
|
line: opts.start.line
|
|
};
|
|
} else if (opts.index) {
|
|
start = this.positionInside(opts.index);
|
|
}
|
|
if (opts.end) {
|
|
end = {
|
|
column: opts.end.column,
|
|
line: opts.end.line
|
|
};
|
|
} else if (typeof opts.endIndex === "number") {
|
|
end = this.positionInside(opts.endIndex);
|
|
} else if (opts.index) {
|
|
end = this.positionInside(opts.index + 1);
|
|
}
|
|
}
|
|
if (end.line < start.line || end.line === start.line && end.column <= start.column) {
|
|
end = { column: start.column + 1, line: start.line };
|
|
}
|
|
return { end, start };
|
|
}
|
|
raw(prop, defaultType) {
|
|
let str = new Stringifier();
|
|
return str.raw(this, prop, defaultType);
|
|
}
|
|
remove() {
|
|
if (this.parent) {
|
|
this.parent.removeChild(this);
|
|
}
|
|
this.parent = void 0;
|
|
return this;
|
|
}
|
|
replaceWith(...nodes) {
|
|
if (this.parent) {
|
|
let bookmark = this;
|
|
let foundSelf = false;
|
|
for (let node2 of nodes) {
|
|
if (node2 === this) {
|
|
foundSelf = true;
|
|
} else if (foundSelf) {
|
|
this.parent.insertAfter(bookmark, node2);
|
|
bookmark = node2;
|
|
} else {
|
|
this.parent.insertBefore(bookmark, node2);
|
|
}
|
|
}
|
|
if (!foundSelf) {
|
|
this.remove();
|
|
}
|
|
}
|
|
return this;
|
|
}
|
|
root() {
|
|
let result2 = this;
|
|
while (result2.parent && result2.parent.type !== "document") {
|
|
result2 = result2.parent;
|
|
}
|
|
return result2;
|
|
}
|
|
toJSON(_, inputs) {
|
|
let fixed = {};
|
|
let emitInputs = inputs == null;
|
|
inputs = inputs || /* @__PURE__ */ new Map();
|
|
let inputsNextIndex = 0;
|
|
for (let name in this) {
|
|
if (!Object.prototype.hasOwnProperty.call(this, name)) {
|
|
continue;
|
|
}
|
|
if (name === "parent" || name === "proxyCache") continue;
|
|
let value = this[name];
|
|
if (Array.isArray(value)) {
|
|
fixed[name] = value.map((i2) => {
|
|
if (typeof i2 === "object" && i2.toJSON) {
|
|
return i2.toJSON(null, inputs);
|
|
} else {
|
|
return i2;
|
|
}
|
|
});
|
|
} else if (typeof value === "object" && value.toJSON) {
|
|
fixed[name] = value.toJSON(null, inputs);
|
|
} else if (name === "source") {
|
|
let inputId = inputs.get(value.input);
|
|
if (inputId == null) {
|
|
inputId = inputsNextIndex;
|
|
inputs.set(value.input, inputsNextIndex);
|
|
inputsNextIndex++;
|
|
}
|
|
fixed[name] = {
|
|
end: value.end,
|
|
inputId,
|
|
start: value.start
|
|
};
|
|
} else {
|
|
fixed[name] = value;
|
|
}
|
|
}
|
|
if (emitInputs) {
|
|
fixed.inputs = [...inputs.keys()].map((input2) => input2.toJSON());
|
|
}
|
|
return fixed;
|
|
}
|
|
toProxy() {
|
|
if (!this.proxyCache) {
|
|
this.proxyCache = new Proxy(this, this.getProxyProcessor());
|
|
}
|
|
return this.proxyCache;
|
|
}
|
|
toString(stringifier2 = stringify) {
|
|
if (stringifier2.stringify) stringifier2 = stringifier2.stringify;
|
|
let result2 = "";
|
|
stringifier2(this, (i2) => {
|
|
result2 += i2;
|
|
});
|
|
return result2;
|
|
}
|
|
warn(result2, text, opts) {
|
|
let data = { node: this };
|
|
for (let i2 in opts) data[i2] = opts[i2];
|
|
return result2.warn(text, data);
|
|
}
|
|
get proxyOf() {
|
|
return this;
|
|
}
|
|
}
|
|
node = Node2;
|
|
Node2.default = Node2;
|
|
return node;
|
|
}
|
|
var declaration;
|
|
var hasRequiredDeclaration;
|
|
function requireDeclaration() {
|
|
if (hasRequiredDeclaration) return declaration;
|
|
hasRequiredDeclaration = 1;
|
|
let Node2 = requireNode();
|
|
class Declaration extends Node2 {
|
|
constructor(defaults) {
|
|
if (defaults && typeof defaults.value !== "undefined" && typeof defaults.value !== "string") {
|
|
defaults = __spreadProps(__spreadValues({}, defaults), { value: String(defaults.value) });
|
|
}
|
|
super(defaults);
|
|
this.type = "decl";
|
|
}
|
|
get variable() {
|
|
return this.prop.startsWith("--") || this.prop[0] === "$";
|
|
}
|
|
}
|
|
declaration = Declaration;
|
|
Declaration.default = Declaration;
|
|
return declaration;
|
|
}
|
|
var nonSecure;
|
|
var hasRequiredNonSecure;
|
|
function requireNonSecure() {
|
|
if (hasRequiredNonSecure) return nonSecure;
|
|
hasRequiredNonSecure = 1;
|
|
let urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
|
|
let customAlphabet = (alphabet, defaultSize = 21) => {
|
|
return (size = defaultSize) => {
|
|
let id = "";
|
|
let i2 = size;
|
|
while (i2--) {
|
|
id += alphabet[Math.random() * alphabet.length | 0];
|
|
}
|
|
return id;
|
|
};
|
|
};
|
|
let nanoid = (size = 21) => {
|
|
let id = "";
|
|
let i2 = size;
|
|
while (i2--) {
|
|
id += urlAlphabet[Math.random() * 64 | 0];
|
|
}
|
|
return id;
|
|
};
|
|
nonSecure = { nanoid, customAlphabet };
|
|
return nonSecure;
|
|
}
|
|
var previousMap;
|
|
var hasRequiredPreviousMap;
|
|
function requirePreviousMap() {
|
|
if (hasRequiredPreviousMap) return previousMap;
|
|
hasRequiredPreviousMap = 1;
|
|
let { SourceMapConsumer, SourceMapGenerator } = require$$2;
|
|
let { existsSync, readFileSync } = require$$2;
|
|
let { dirname, join } = require$$2;
|
|
function fromBase64(str) {
|
|
if (Buffer) {
|
|
return Buffer.from(str, "base64").toString();
|
|
} else {
|
|
return window.atob(str);
|
|
}
|
|
}
|
|
class PreviousMap {
|
|
constructor(css, opts) {
|
|
if (opts.map === false) return;
|
|
this.loadAnnotation(css);
|
|
this.inline = this.startWith(this.annotation, "data:");
|
|
let prev = opts.map ? opts.map.prev : void 0;
|
|
let text = this.loadMap(opts.from, prev);
|
|
if (!this.mapFile && opts.from) {
|
|
this.mapFile = opts.from;
|
|
}
|
|
if (this.mapFile) this.root = dirname(this.mapFile);
|
|
if (text) this.text = text;
|
|
}
|
|
consumer() {
|
|
if (!this.consumerCache) {
|
|
this.consumerCache = new SourceMapConsumer(this.text);
|
|
}
|
|
return this.consumerCache;
|
|
}
|
|
decodeInline(text) {
|
|
let baseCharsetUri = /^data:application\/json;charset=utf-?8;base64,/;
|
|
let baseUri = /^data:application\/json;base64,/;
|
|
let charsetUri = /^data:application\/json;charset=utf-?8,/;
|
|
let uri = /^data:application\/json,/;
|
|
if (charsetUri.test(text) || uri.test(text)) {
|
|
return decodeURIComponent(text.substr(RegExp.lastMatch.length));
|
|
}
|
|
if (baseCharsetUri.test(text) || baseUri.test(text)) {
|
|
return fromBase64(text.substr(RegExp.lastMatch.length));
|
|
}
|
|
let encoding = text.match(/data:application\/json;([^,]+),/)[1];
|
|
throw new Error("Unsupported source map encoding " + encoding);
|
|
}
|
|
getAnnotationURL(sourceMapString) {
|
|
return sourceMapString.replace(/^\/\*\s*# sourceMappingURL=/, "").trim();
|
|
}
|
|
isMap(map) {
|
|
if (typeof map !== "object") return false;
|
|
return typeof map.mappings === "string" || typeof map._mappings === "string" || Array.isArray(map.sections);
|
|
}
|
|
loadAnnotation(css) {
|
|
let comments = css.match(/\/\*\s*# sourceMappingURL=/gm);
|
|
if (!comments) return;
|
|
let start = css.lastIndexOf(comments.pop());
|
|
let end = css.indexOf("*/", start);
|
|
if (start > -1 && end > -1) {
|
|
this.annotation = this.getAnnotationURL(css.substring(start, end));
|
|
}
|
|
}
|
|
loadFile(path) {
|
|
this.root = dirname(path);
|
|
if (existsSync(path)) {
|
|
this.mapFile = path;
|
|
return readFileSync(path, "utf-8").toString().trim();
|
|
}
|
|
}
|
|
loadMap(file, prev) {
|
|
if (prev === false) return false;
|
|
if (prev) {
|
|
if (typeof prev === "string") {
|
|
return prev;
|
|
} else if (typeof prev === "function") {
|
|
let prevPath = prev(file);
|
|
if (prevPath) {
|
|
let map = this.loadFile(prevPath);
|
|
if (!map) {
|
|
throw new Error(
|
|
"Unable to load previous source map: " + prevPath.toString()
|
|
);
|
|
}
|
|
return map;
|
|
}
|
|
} else if (prev instanceof SourceMapConsumer) {
|
|
return SourceMapGenerator.fromSourceMap(prev).toString();
|
|
} else if (prev instanceof SourceMapGenerator) {
|
|
return prev.toString();
|
|
} else if (this.isMap(prev)) {
|
|
return JSON.stringify(prev);
|
|
} else {
|
|
throw new Error(
|
|
"Unsupported previous source map format: " + prev.toString()
|
|
);
|
|
}
|
|
} else if (this.inline) {
|
|
return this.decodeInline(this.annotation);
|
|
} else if (this.annotation) {
|
|
let map = this.annotation;
|
|
if (file) map = join(dirname(file), map);
|
|
return this.loadFile(map);
|
|
}
|
|
}
|
|
startWith(string, start) {
|
|
if (!string) return false;
|
|
return string.substr(0, start.length) === start;
|
|
}
|
|
withContent() {
|
|
return !!(this.consumer().sourcesContent && this.consumer().sourcesContent.length > 0);
|
|
}
|
|
}
|
|
previousMap = PreviousMap;
|
|
PreviousMap.default = PreviousMap;
|
|
return previousMap;
|
|
}
|
|
var input;
|
|
var hasRequiredInput;
|
|
function requireInput() {
|
|
if (hasRequiredInput) return input;
|
|
hasRequiredInput = 1;
|
|
let { SourceMapConsumer, SourceMapGenerator } = require$$2;
|
|
let { fileURLToPath, pathToFileURL } = require$$2;
|
|
let { isAbsolute, resolve } = require$$2;
|
|
let { nanoid } = /* @__PURE__ */ requireNonSecure();
|
|
let terminalHighlight = require$$2;
|
|
let CssSyntaxError = requireCssSyntaxError();
|
|
let PreviousMap = requirePreviousMap();
|
|
let fromOffsetCache = Symbol("fromOffsetCache");
|
|
let sourceMapAvailable = Boolean(SourceMapConsumer && SourceMapGenerator);
|
|
let pathAvailable = Boolean(resolve && isAbsolute);
|
|
class Input {
|
|
constructor(css, opts = {}) {
|
|
if (css === null || typeof css === "undefined" || typeof css === "object" && !css.toString) {
|
|
throw new Error(`PostCSS received ${css} instead of CSS string`);
|
|
}
|
|
this.css = css.toString();
|
|
if (this.css[0] === "\uFEFF" || this.css[0] === "\uFFFE") {
|
|
this.hasBOM = true;
|
|
this.css = this.css.slice(1);
|
|
} else {
|
|
this.hasBOM = false;
|
|
}
|
|
if (opts.from) {
|
|
if (!pathAvailable || /^\w+:\/\//.test(opts.from) || isAbsolute(opts.from)) {
|
|
this.file = opts.from;
|
|
} else {
|
|
this.file = resolve(opts.from);
|
|
}
|
|
}
|
|
if (pathAvailable && sourceMapAvailable) {
|
|
let map = new PreviousMap(this.css, opts);
|
|
if (map.text) {
|
|
this.map = map;
|
|
let file = map.consumer().file;
|
|
if (!this.file && file) this.file = this.mapResolve(file);
|
|
}
|
|
}
|
|
if (!this.file) {
|
|
this.id = "<input css " + nanoid(6) + ">";
|
|
}
|
|
if (this.map) this.map.file = this.from;
|
|
}
|
|
error(message, line, column, opts = {}) {
|
|
let result2, endLine, endColumn;
|
|
if (line && typeof line === "object") {
|
|
let start = line;
|
|
let end = column;
|
|
if (typeof start.offset === "number") {
|
|
let pos = this.fromOffset(start.offset);
|
|
line = pos.line;
|
|
column = pos.col;
|
|
} else {
|
|
line = start.line;
|
|
column = start.column;
|
|
}
|
|
if (typeof end.offset === "number") {
|
|
let pos = this.fromOffset(end.offset);
|
|
endLine = pos.line;
|
|
endColumn = pos.col;
|
|
} else {
|
|
endLine = end.line;
|
|
endColumn = end.column;
|
|
}
|
|
} else if (!column) {
|
|
let pos = this.fromOffset(line);
|
|
line = pos.line;
|
|
column = pos.col;
|
|
}
|
|
let origin = this.origin(line, column, endLine, endColumn);
|
|
if (origin) {
|
|
result2 = new CssSyntaxError(
|
|
message,
|
|
origin.endLine === void 0 ? origin.line : { column: origin.column, line: origin.line },
|
|
origin.endLine === void 0 ? origin.column : { column: origin.endColumn, line: origin.endLine },
|
|
origin.source,
|
|
origin.file,
|
|
opts.plugin
|
|
);
|
|
} else {
|
|
result2 = new CssSyntaxError(
|
|
message,
|
|
endLine === void 0 ? line : { column, line },
|
|
endLine === void 0 ? column : { column: endColumn, line: endLine },
|
|
this.css,
|
|
this.file,
|
|
opts.plugin
|
|
);
|
|
}
|
|
result2.input = { column, endColumn, endLine, line, source: this.css };
|
|
if (this.file) {
|
|
if (pathToFileURL) {
|
|
result2.input.url = pathToFileURL(this.file).toString();
|
|
}
|
|
result2.input.file = this.file;
|
|
}
|
|
return result2;
|
|
}
|
|
fromOffset(offset) {
|
|
let lastLine, lineToIndex;
|
|
if (!this[fromOffsetCache]) {
|
|
let lines = this.css.split("\n");
|
|
lineToIndex = new Array(lines.length);
|
|
let prevIndex = 0;
|
|
for (let i2 = 0, l2 = lines.length; i2 < l2; i2++) {
|
|
lineToIndex[i2] = prevIndex;
|
|
prevIndex += lines[i2].length + 1;
|
|
}
|
|
this[fromOffsetCache] = lineToIndex;
|
|
} else {
|
|
lineToIndex = this[fromOffsetCache];
|
|
}
|
|
lastLine = lineToIndex[lineToIndex.length - 1];
|
|
let min = 0;
|
|
if (offset >= lastLine) {
|
|
min = lineToIndex.length - 1;
|
|
} else {
|
|
let max = lineToIndex.length - 2;
|
|
let mid;
|
|
while (min < max) {
|
|
mid = min + (max - min >> 1);
|
|
if (offset < lineToIndex[mid]) {
|
|
max = mid - 1;
|
|
} else if (offset >= lineToIndex[mid + 1]) {
|
|
min = mid + 1;
|
|
} else {
|
|
min = mid;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return {
|
|
col: offset - lineToIndex[min] + 1,
|
|
line: min + 1
|
|
};
|
|
}
|
|
mapResolve(file) {
|
|
if (/^\w+:\/\//.test(file)) {
|
|
return file;
|
|
}
|
|
return resolve(this.map.consumer().sourceRoot || this.map.root || ".", file);
|
|
}
|
|
origin(line, column, endLine, endColumn) {
|
|
if (!this.map) return false;
|
|
let consumer = this.map.consumer();
|
|
let from = consumer.originalPositionFor({ column, line });
|
|
if (!from.source) return false;
|
|
let to;
|
|
if (typeof endLine === "number") {
|
|
to = consumer.originalPositionFor({ column: endColumn, line: endLine });
|
|
}
|
|
let fromUrl;
|
|
if (isAbsolute(from.source)) {
|
|
fromUrl = pathToFileURL(from.source);
|
|
} else {
|
|
fromUrl = new URL(
|
|
from.source,
|
|
this.map.consumer().sourceRoot || pathToFileURL(this.map.mapFile)
|
|
);
|
|
}
|
|
let result2 = {
|
|
column: from.column,
|
|
endColumn: to && to.column,
|
|
endLine: to && to.line,
|
|
line: from.line,
|
|
url: fromUrl.toString()
|
|
};
|
|
if (fromUrl.protocol === "file:") {
|
|
if (fileURLToPath) {
|
|
result2.file = fileURLToPath(fromUrl);
|
|
} else {
|
|
throw new Error(`file: protocol is not available in this PostCSS build`);
|
|
}
|
|
}
|
|
let source = consumer.sourceContentFor(from.source);
|
|
if (source) result2.source = source;
|
|
return result2;
|
|
}
|
|
toJSON() {
|
|
let json = {};
|
|
for (let name of ["hasBOM", "css", "file", "id"]) {
|
|
if (this[name] != null) {
|
|
json[name] = this[name];
|
|
}
|
|
}
|
|
if (this.map) {
|
|
json.map = __spreadValues({}, this.map);
|
|
if (json.map.consumerCache) {
|
|
json.map.consumerCache = void 0;
|
|
}
|
|
}
|
|
return json;
|
|
}
|
|
get from() {
|
|
return this.file || this.id;
|
|
}
|
|
}
|
|
input = Input;
|
|
Input.default = Input;
|
|
if (terminalHighlight && terminalHighlight.registerInput) {
|
|
terminalHighlight.registerInput(Input);
|
|
}
|
|
return input;
|
|
}
|
|
var mapGenerator;
|
|
var hasRequiredMapGenerator;
|
|
function requireMapGenerator() {
|
|
if (hasRequiredMapGenerator) return mapGenerator;
|
|
hasRequiredMapGenerator = 1;
|
|
let { SourceMapConsumer, SourceMapGenerator } = require$$2;
|
|
let { dirname, relative, resolve, sep } = require$$2;
|
|
let { pathToFileURL } = require$$2;
|
|
let Input = requireInput();
|
|
let sourceMapAvailable = Boolean(SourceMapConsumer && SourceMapGenerator);
|
|
let pathAvailable = Boolean(dirname && resolve && relative && sep);
|
|
class MapGenerator {
|
|
constructor(stringify, root2, opts, cssString) {
|
|
this.stringify = stringify;
|
|
this.mapOpts = opts.map || {};
|
|
this.root = root2;
|
|
this.opts = opts;
|
|
this.css = cssString;
|
|
this.originalCSS = cssString;
|
|
this.usesFileUrls = !this.mapOpts.from && this.mapOpts.absolute;
|
|
this.memoizedFileURLs = /* @__PURE__ */ new Map();
|
|
this.memoizedPaths = /* @__PURE__ */ new Map();
|
|
this.memoizedURLs = /* @__PURE__ */ new Map();
|
|
}
|
|
addAnnotation() {
|
|
let content;
|
|
if (this.isInline()) {
|
|
content = "data:application/json;base64," + this.toBase64(this.map.toString());
|
|
} else if (typeof this.mapOpts.annotation === "string") {
|
|
content = this.mapOpts.annotation;
|
|
} else if (typeof this.mapOpts.annotation === "function") {
|
|
content = this.mapOpts.annotation(this.opts.to, this.root);
|
|
} else {
|
|
content = this.outputFile() + ".map";
|
|
}
|
|
let eol = "\n";
|
|
if (this.css.includes("\r\n")) eol = "\r\n";
|
|
this.css += eol + "/*# sourceMappingURL=" + content + " */";
|
|
}
|
|
applyPrevMaps() {
|
|
for (let prev of this.previous()) {
|
|
let from = this.toUrl(this.path(prev.file));
|
|
let root2 = prev.root || dirname(prev.file);
|
|
let map;
|
|
if (this.mapOpts.sourcesContent === false) {
|
|
map = new SourceMapConsumer(prev.text);
|
|
if (map.sourcesContent) {
|
|
map.sourcesContent = null;
|
|
}
|
|
} else {
|
|
map = prev.consumer();
|
|
}
|
|
this.map.applySourceMap(map, from, this.toUrl(this.path(root2)));
|
|
}
|
|
}
|
|
clearAnnotation() {
|
|
if (this.mapOpts.annotation === false) return;
|
|
if (this.root) {
|
|
let node2;
|
|
for (let i2 = this.root.nodes.length - 1; i2 >= 0; i2--) {
|
|
node2 = this.root.nodes[i2];
|
|
if (node2.type !== "comment") continue;
|
|
if (node2.text.indexOf("# sourceMappingURL=") === 0) {
|
|
this.root.removeChild(i2);
|
|
}
|
|
}
|
|
} else if (this.css) {
|
|
this.css = this.css.replace(/\n*?\/\*#[\S\s]*?\*\/$/gm, "");
|
|
}
|
|
}
|
|
generate() {
|
|
this.clearAnnotation();
|
|
if (pathAvailable && sourceMapAvailable && this.isMap()) {
|
|
return this.generateMap();
|
|
} else {
|
|
let result2 = "";
|
|
this.stringify(this.root, (i2) => {
|
|
result2 += i2;
|
|
});
|
|
return [result2];
|
|
}
|
|
}
|
|
generateMap() {
|
|
if (this.root) {
|
|
this.generateString();
|
|
} else if (this.previous().length === 1) {
|
|
let prev = this.previous()[0].consumer();
|
|
prev.file = this.outputFile();
|
|
this.map = SourceMapGenerator.fromSourceMap(prev, {
|
|
ignoreInvalidMapping: true
|
|
});
|
|
} else {
|
|
this.map = new SourceMapGenerator({
|
|
file: this.outputFile(),
|
|
ignoreInvalidMapping: true
|
|
});
|
|
this.map.addMapping({
|
|
generated: { column: 0, line: 1 },
|
|
original: { column: 0, line: 1 },
|
|
source: this.opts.from ? this.toUrl(this.path(this.opts.from)) : "<no source>"
|
|
});
|
|
}
|
|
if (this.isSourcesContent()) this.setSourcesContent();
|
|
if (this.root && this.previous().length > 0) this.applyPrevMaps();
|
|
if (this.isAnnotation()) this.addAnnotation();
|
|
if (this.isInline()) {
|
|
return [this.css];
|
|
} else {
|
|
return [this.css, this.map];
|
|
}
|
|
}
|
|
generateString() {
|
|
this.css = "";
|
|
this.map = new SourceMapGenerator({
|
|
file: this.outputFile(),
|
|
ignoreInvalidMapping: true
|
|
});
|
|
let line = 1;
|
|
let column = 1;
|
|
let noSource = "<no source>";
|
|
let mapping = {
|
|
generated: { column: 0, line: 0 },
|
|
original: { column: 0, line: 0 },
|
|
source: ""
|
|
};
|
|
let lines, last;
|
|
this.stringify(this.root, (str, node2, type) => {
|
|
this.css += str;
|
|
if (node2 && type !== "end") {
|
|
mapping.generated.line = line;
|
|
mapping.generated.column = column - 1;
|
|
if (node2.source && node2.source.start) {
|
|
mapping.source = this.sourcePath(node2);
|
|
mapping.original.line = node2.source.start.line;
|
|
mapping.original.column = node2.source.start.column - 1;
|
|
this.map.addMapping(mapping);
|
|
} else {
|
|
mapping.source = noSource;
|
|
mapping.original.line = 1;
|
|
mapping.original.column = 0;
|
|
this.map.addMapping(mapping);
|
|
}
|
|
}
|
|
lines = str.match(/\n/g);
|
|
if (lines) {
|
|
line += lines.length;
|
|
last = str.lastIndexOf("\n");
|
|
column = str.length - last;
|
|
} else {
|
|
column += str.length;
|
|
}
|
|
if (node2 && type !== "start") {
|
|
let p = node2.parent || { raws: {} };
|
|
let childless = node2.type === "decl" || node2.type === "atrule" && !node2.nodes;
|
|
if (!childless || node2 !== p.last || p.raws.semicolon) {
|
|
if (node2.source && node2.source.end) {
|
|
mapping.source = this.sourcePath(node2);
|
|
mapping.original.line = node2.source.end.line;
|
|
mapping.original.column = node2.source.end.column - 1;
|
|
mapping.generated.line = line;
|
|
mapping.generated.column = column - 2;
|
|
this.map.addMapping(mapping);
|
|
} else {
|
|
mapping.source = noSource;
|
|
mapping.original.line = 1;
|
|
mapping.original.column = 0;
|
|
mapping.generated.line = line;
|
|
mapping.generated.column = column - 1;
|
|
this.map.addMapping(mapping);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
isAnnotation() {
|
|
if (this.isInline()) {
|
|
return true;
|
|
}
|
|
if (typeof this.mapOpts.annotation !== "undefined") {
|
|
return this.mapOpts.annotation;
|
|
}
|
|
if (this.previous().length) {
|
|
return this.previous().some((i2) => i2.annotation);
|
|
}
|
|
return true;
|
|
}
|
|
isInline() {
|
|
if (typeof this.mapOpts.inline !== "undefined") {
|
|
return this.mapOpts.inline;
|
|
}
|
|
let annotation = this.mapOpts.annotation;
|
|
if (typeof annotation !== "undefined" && annotation !== true) {
|
|
return false;
|
|
}
|
|
if (this.previous().length) {
|
|
return this.previous().some((i2) => i2.inline);
|
|
}
|
|
return true;
|
|
}
|
|
isMap() {
|
|
if (typeof this.opts.map !== "undefined") {
|
|
return !!this.opts.map;
|
|
}
|
|
return this.previous().length > 0;
|
|
}
|
|
isSourcesContent() {
|
|
if (typeof this.mapOpts.sourcesContent !== "undefined") {
|
|
return this.mapOpts.sourcesContent;
|
|
}
|
|
if (this.previous().length) {
|
|
return this.previous().some((i2) => i2.withContent());
|
|
}
|
|
return true;
|
|
}
|
|
outputFile() {
|
|
if (this.opts.to) {
|
|
return this.path(this.opts.to);
|
|
} else if (this.opts.from) {
|
|
return this.path(this.opts.from);
|
|
} else {
|
|
return "to.css";
|
|
}
|
|
}
|
|
path(file) {
|
|
if (this.mapOpts.absolute) return file;
|
|
if (file.charCodeAt(0) === 60) return file;
|
|
if (/^\w+:\/\//.test(file)) return file;
|
|
let cached = this.memoizedPaths.get(file);
|
|
if (cached) return cached;
|
|
let from = this.opts.to ? dirname(this.opts.to) : ".";
|
|
if (typeof this.mapOpts.annotation === "string") {
|
|
from = dirname(resolve(from, this.mapOpts.annotation));
|
|
}
|
|
let path = relative(from, file);
|
|
this.memoizedPaths.set(file, path);
|
|
return path;
|
|
}
|
|
previous() {
|
|
if (!this.previousMaps) {
|
|
this.previousMaps = [];
|
|
if (this.root) {
|
|
this.root.walk((node2) => {
|
|
if (node2.source && node2.source.input.map) {
|
|
let map = node2.source.input.map;
|
|
if (!this.previousMaps.includes(map)) {
|
|
this.previousMaps.push(map);
|
|
}
|
|
}
|
|
});
|
|
} else {
|
|
let input2 = new Input(this.originalCSS, this.opts);
|
|
if (input2.map) this.previousMaps.push(input2.map);
|
|
}
|
|
}
|
|
return this.previousMaps;
|
|
}
|
|
setSourcesContent() {
|
|
let already = {};
|
|
if (this.root) {
|
|
this.root.walk((node2) => {
|
|
if (node2.source) {
|
|
let from = node2.source.input.from;
|
|
if (from && !already[from]) {
|
|
already[from] = true;
|
|
let fromUrl = this.usesFileUrls ? this.toFileUrl(from) : this.toUrl(this.path(from));
|
|
this.map.setSourceContent(fromUrl, node2.source.input.css);
|
|
}
|
|
}
|
|
});
|
|
} else if (this.css) {
|
|
let from = this.opts.from ? this.toUrl(this.path(this.opts.from)) : "<no source>";
|
|
this.map.setSourceContent(from, this.css);
|
|
}
|
|
}
|
|
sourcePath(node2) {
|
|
if (this.mapOpts.from) {
|
|
return this.toUrl(this.mapOpts.from);
|
|
} else if (this.usesFileUrls) {
|
|
return this.toFileUrl(node2.source.input.from);
|
|
} else {
|
|
return this.toUrl(this.path(node2.source.input.from));
|
|
}
|
|
}
|
|
toBase64(str) {
|
|
if (Buffer) {
|
|
return Buffer.from(str).toString("base64");
|
|
} else {
|
|
return window.btoa(unescape(encodeURIComponent(str)));
|
|
}
|
|
}
|
|
toFileUrl(path) {
|
|
let cached = this.memoizedFileURLs.get(path);
|
|
if (cached) return cached;
|
|
if (pathToFileURL) {
|
|
let fileURL = pathToFileURL(path).toString();
|
|
this.memoizedFileURLs.set(path, fileURL);
|
|
return fileURL;
|
|
} else {
|
|
throw new Error(
|
|
"`map.absolute` option is not available in this PostCSS build"
|
|
);
|
|
}
|
|
}
|
|
toUrl(path) {
|
|
let cached = this.memoizedURLs.get(path);
|
|
if (cached) return cached;
|
|
if (sep === "\\") {
|
|
path = path.replace(/\\/g, "/");
|
|
}
|
|
let url = encodeURI(path).replace(/[#?]/g, encodeURIComponent);
|
|
this.memoizedURLs.set(path, url);
|
|
return url;
|
|
}
|
|
}
|
|
mapGenerator = MapGenerator;
|
|
return mapGenerator;
|
|
}
|
|
var comment;
|
|
var hasRequiredComment;
|
|
function requireComment() {
|
|
if (hasRequiredComment) return comment;
|
|
hasRequiredComment = 1;
|
|
let Node2 = requireNode();
|
|
class Comment extends Node2 {
|
|
constructor(defaults) {
|
|
super(defaults);
|
|
this.type = "comment";
|
|
}
|
|
}
|
|
comment = Comment;
|
|
Comment.default = Comment;
|
|
return comment;
|
|
}
|
|
var container;
|
|
var hasRequiredContainer;
|
|
function requireContainer() {
|
|
if (hasRequiredContainer) return container;
|
|
hasRequiredContainer = 1;
|
|
let { isClean, my } = requireSymbols();
|
|
let Declaration = requireDeclaration();
|
|
let Comment = requireComment();
|
|
let Node2 = requireNode();
|
|
let parse, Rule, AtRule, Root;
|
|
function cleanSource(nodes) {
|
|
return nodes.map((i2) => {
|
|
if (i2.nodes) i2.nodes = cleanSource(i2.nodes);
|
|
delete i2.source;
|
|
return i2;
|
|
});
|
|
}
|
|
function markDirtyUp(node2) {
|
|
node2[isClean] = false;
|
|
if (node2.proxyOf.nodes) {
|
|
for (let i2 of node2.proxyOf.nodes) {
|
|
markDirtyUp(i2);
|
|
}
|
|
}
|
|
}
|
|
class Container extends Node2 {
|
|
append(...children) {
|
|
for (let child of children) {
|
|
let nodes = this.normalize(child, this.last);
|
|
for (let node2 of nodes) this.proxyOf.nodes.push(node2);
|
|
}
|
|
this.markDirty();
|
|
return this;
|
|
}
|
|
cleanRaws(keepBetween) {
|
|
super.cleanRaws(keepBetween);
|
|
if (this.nodes) {
|
|
for (let node2 of this.nodes) node2.cleanRaws(keepBetween);
|
|
}
|
|
}
|
|
each(callback) {
|
|
if (!this.proxyOf.nodes) return void 0;
|
|
let iterator = this.getIterator();
|
|
let index2, result2;
|
|
while (this.indexes[iterator] < this.proxyOf.nodes.length) {
|
|
index2 = this.indexes[iterator];
|
|
result2 = callback(this.proxyOf.nodes[index2], index2);
|
|
if (result2 === false) break;
|
|
this.indexes[iterator] += 1;
|
|
}
|
|
delete this.indexes[iterator];
|
|
return result2;
|
|
}
|
|
every(condition) {
|
|
return this.nodes.every(condition);
|
|
}
|
|
getIterator() {
|
|
if (!this.lastEach) this.lastEach = 0;
|
|
if (!this.indexes) this.indexes = {};
|
|
this.lastEach += 1;
|
|
let iterator = this.lastEach;
|
|
this.indexes[iterator] = 0;
|
|
return iterator;
|
|
}
|
|
getProxyProcessor() {
|
|
return {
|
|
get(node2, prop) {
|
|
if (prop === "proxyOf") {
|
|
return node2;
|
|
} else if (!node2[prop]) {
|
|
return node2[prop];
|
|
} else if (prop === "each" || typeof prop === "string" && prop.startsWith("walk")) {
|
|
return (...args) => {
|
|
return node2[prop](
|
|
...args.map((i2) => {
|
|
if (typeof i2 === "function") {
|
|
return (child, index2) => i2(child.toProxy(), index2);
|
|
} else {
|
|
return i2;
|
|
}
|
|
})
|
|
);
|
|
};
|
|
} else if (prop === "every" || prop === "some") {
|
|
return (cb) => {
|
|
return node2[prop](
|
|
(child, ...other) => cb(child.toProxy(), ...other)
|
|
);
|
|
};
|
|
} else if (prop === "root") {
|
|
return () => node2.root().toProxy();
|
|
} else if (prop === "nodes") {
|
|
return node2.nodes.map((i2) => i2.toProxy());
|
|
} else if (prop === "first" || prop === "last") {
|
|
return node2[prop].toProxy();
|
|
} else {
|
|
return node2[prop];
|
|
}
|
|
},
|
|
set(node2, prop, value) {
|
|
if (node2[prop] === value) return true;
|
|
node2[prop] = value;
|
|
if (prop === "name" || prop === "params" || prop === "selector") {
|
|
node2.markDirty();
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
}
|
|
index(child) {
|
|
if (typeof child === "number") return child;
|
|
if (child.proxyOf) child = child.proxyOf;
|
|
return this.proxyOf.nodes.indexOf(child);
|
|
}
|
|
insertAfter(exist, add) {
|
|
let existIndex = this.index(exist);
|
|
let nodes = this.normalize(add, this.proxyOf.nodes[existIndex]).reverse();
|
|
existIndex = this.index(exist);
|
|
for (let node2 of nodes) this.proxyOf.nodes.splice(existIndex + 1, 0, node2);
|
|
let index2;
|
|
for (let id in this.indexes) {
|
|
index2 = this.indexes[id];
|
|
if (existIndex < index2) {
|
|
this.indexes[id] = index2 + nodes.length;
|
|
}
|
|
}
|
|
this.markDirty();
|
|
return this;
|
|
}
|
|
insertBefore(exist, add) {
|
|
let existIndex = this.index(exist);
|
|
let type = existIndex === 0 ? "prepend" : false;
|
|
let nodes = this.normalize(add, this.proxyOf.nodes[existIndex], type).reverse();
|
|
existIndex = this.index(exist);
|
|
for (let node2 of nodes) this.proxyOf.nodes.splice(existIndex, 0, node2);
|
|
let index2;
|
|
for (let id in this.indexes) {
|
|
index2 = this.indexes[id];
|
|
if (existIndex <= index2) {
|
|
this.indexes[id] = index2 + nodes.length;
|
|
}
|
|
}
|
|
this.markDirty();
|
|
return this;
|
|
}
|
|
normalize(nodes, sample) {
|
|
if (typeof nodes === "string") {
|
|
nodes = cleanSource(parse(nodes).nodes);
|
|
} else if (typeof nodes === "undefined") {
|
|
nodes = [];
|
|
} else if (Array.isArray(nodes)) {
|
|
nodes = nodes.slice(0);
|
|
for (let i2 of nodes) {
|
|
if (i2.parent) i2.parent.removeChild(i2, "ignore");
|
|
}
|
|
} else if (nodes.type === "root" && this.type !== "document") {
|
|
nodes = nodes.nodes.slice(0);
|
|
for (let i2 of nodes) {
|
|
if (i2.parent) i2.parent.removeChild(i2, "ignore");
|
|
}
|
|
} else if (nodes.type) {
|
|
nodes = [nodes];
|
|
} else if (nodes.prop) {
|
|
if (typeof nodes.value === "undefined") {
|
|
throw new Error("Value field is missed in node creation");
|
|
} else if (typeof nodes.value !== "string") {
|
|
nodes.value = String(nodes.value);
|
|
}
|
|
nodes = [new Declaration(nodes)];
|
|
} else if (nodes.selector) {
|
|
nodes = [new Rule(nodes)];
|
|
} else if (nodes.name) {
|
|
nodes = [new AtRule(nodes)];
|
|
} else if (nodes.text) {
|
|
nodes = [new Comment(nodes)];
|
|
} else {
|
|
throw new Error("Unknown node type in node creation");
|
|
}
|
|
let processed = nodes.map((i2) => {
|
|
if (!i2[my]) Container.rebuild(i2);
|
|
i2 = i2.proxyOf;
|
|
if (i2.parent) i2.parent.removeChild(i2);
|
|
if (i2[isClean]) markDirtyUp(i2);
|
|
if (typeof i2.raws.before === "undefined") {
|
|
if (sample && typeof sample.raws.before !== "undefined") {
|
|
i2.raws.before = sample.raws.before.replace(/\S/g, "");
|
|
}
|
|
}
|
|
i2.parent = this.proxyOf;
|
|
return i2;
|
|
});
|
|
return processed;
|
|
}
|
|
prepend(...children) {
|
|
children = children.reverse();
|
|
for (let child of children) {
|
|
let nodes = this.normalize(child, this.first, "prepend").reverse();
|
|
for (let node2 of nodes) this.proxyOf.nodes.unshift(node2);
|
|
for (let id in this.indexes) {
|
|
this.indexes[id] = this.indexes[id] + nodes.length;
|
|
}
|
|
}
|
|
this.markDirty();
|
|
return this;
|
|
}
|
|
push(child) {
|
|
child.parent = this;
|
|
this.proxyOf.nodes.push(child);
|
|
return this;
|
|
}
|
|
removeAll() {
|
|
for (let node2 of this.proxyOf.nodes) node2.parent = void 0;
|
|
this.proxyOf.nodes = [];
|
|
this.markDirty();
|
|
return this;
|
|
}
|
|
removeChild(child) {
|
|
child = this.index(child);
|
|
this.proxyOf.nodes[child].parent = void 0;
|
|
this.proxyOf.nodes.splice(child, 1);
|
|
let index2;
|
|
for (let id in this.indexes) {
|
|
index2 = this.indexes[id];
|
|
if (index2 >= child) {
|
|
this.indexes[id] = index2 - 1;
|
|
}
|
|
}
|
|
this.markDirty();
|
|
return this;
|
|
}
|
|
replaceValues(pattern, opts, callback) {
|
|
if (!callback) {
|
|
callback = opts;
|
|
opts = {};
|
|
}
|
|
this.walkDecls((decl) => {
|
|
if (opts.props && !opts.props.includes(decl.prop)) return;
|
|
if (opts.fast && !decl.value.includes(opts.fast)) return;
|
|
decl.value = decl.value.replace(pattern, callback);
|
|
});
|
|
this.markDirty();
|
|
return this;
|
|
}
|
|
some(condition) {
|
|
return this.nodes.some(condition);
|
|
}
|
|
walk(callback) {
|
|
return this.each((child, i2) => {
|
|
let result2;
|
|
try {
|
|
result2 = callback(child, i2);
|
|
} catch (e2) {
|
|
throw child.addToError(e2);
|
|
}
|
|
if (result2 !== false && child.walk) {
|
|
result2 = child.walk(callback);
|
|
}
|
|
return result2;
|
|
});
|
|
}
|
|
walkAtRules(name, callback) {
|
|
if (!callback) {
|
|
callback = name;
|
|
return this.walk((child, i2) => {
|
|
if (child.type === "atrule") {
|
|
return callback(child, i2);
|
|
}
|
|
});
|
|
}
|
|
if (name instanceof RegExp) {
|
|
return this.walk((child, i2) => {
|
|
if (child.type === "atrule" && name.test(child.name)) {
|
|
return callback(child, i2);
|
|
}
|
|
});
|
|
}
|
|
return this.walk((child, i2) => {
|
|
if (child.type === "atrule" && child.name === name) {
|
|
return callback(child, i2);
|
|
}
|
|
});
|
|
}
|
|
walkComments(callback) {
|
|
return this.walk((child, i2) => {
|
|
if (child.type === "comment") {
|
|
return callback(child, i2);
|
|
}
|
|
});
|
|
}
|
|
walkDecls(prop, callback) {
|
|
if (!callback) {
|
|
callback = prop;
|
|
return this.walk((child, i2) => {
|
|
if (child.type === "decl") {
|
|
return callback(child, i2);
|
|
}
|
|
});
|
|
}
|
|
if (prop instanceof RegExp) {
|
|
return this.walk((child, i2) => {
|
|
if (child.type === "decl" && prop.test(child.prop)) {
|
|
return callback(child, i2);
|
|
}
|
|
});
|
|
}
|
|
return this.walk((child, i2) => {
|
|
if (child.type === "decl" && child.prop === prop) {
|
|
return callback(child, i2);
|
|
}
|
|
});
|
|
}
|
|
walkRules(selector, callback) {
|
|
if (!callback) {
|
|
callback = selector;
|
|
return this.walk((child, i2) => {
|
|
if (child.type === "rule") {
|
|
return callback(child, i2);
|
|
}
|
|
});
|
|
}
|
|
if (selector instanceof RegExp) {
|
|
return this.walk((child, i2) => {
|
|
if (child.type === "rule" && selector.test(child.selector)) {
|
|
return callback(child, i2);
|
|
}
|
|
});
|
|
}
|
|
return this.walk((child, i2) => {
|
|
if (child.type === "rule" && child.selector === selector) {
|
|
return callback(child, i2);
|
|
}
|
|
});
|
|
}
|
|
get first() {
|
|
if (!this.proxyOf.nodes) return void 0;
|
|
return this.proxyOf.nodes[0];
|
|
}
|
|
get last() {
|
|
if (!this.proxyOf.nodes) return void 0;
|
|
return this.proxyOf.nodes[this.proxyOf.nodes.length - 1];
|
|
}
|
|
}
|
|
Container.registerParse = (dependant) => {
|
|
parse = dependant;
|
|
};
|
|
Container.registerRule = (dependant) => {
|
|
Rule = dependant;
|
|
};
|
|
Container.registerAtRule = (dependant) => {
|
|
AtRule = dependant;
|
|
};
|
|
Container.registerRoot = (dependant) => {
|
|
Root = dependant;
|
|
};
|
|
container = Container;
|
|
Container.default = Container;
|
|
Container.rebuild = (node2) => {
|
|
if (node2.type === "atrule") {
|
|
Object.setPrototypeOf(node2, AtRule.prototype);
|
|
} else if (node2.type === "rule") {
|
|
Object.setPrototypeOf(node2, Rule.prototype);
|
|
} else if (node2.type === "decl") {
|
|
Object.setPrototypeOf(node2, Declaration.prototype);
|
|
} else if (node2.type === "comment") {
|
|
Object.setPrototypeOf(node2, Comment.prototype);
|
|
} else if (node2.type === "root") {
|
|
Object.setPrototypeOf(node2, Root.prototype);
|
|
}
|
|
node2[my] = true;
|
|
if (node2.nodes) {
|
|
node2.nodes.forEach((child) => {
|
|
Container.rebuild(child);
|
|
});
|
|
}
|
|
};
|
|
return container;
|
|
}
|
|
var document$1;
|
|
var hasRequiredDocument;
|
|
function requireDocument() {
|
|
if (hasRequiredDocument) return document$1;
|
|
hasRequiredDocument = 1;
|
|
let Container = requireContainer();
|
|
let LazyResult, Processor;
|
|
class Document2 extends Container {
|
|
constructor(defaults) {
|
|
super(__spreadValues({ type: "document" }, defaults));
|
|
if (!this.nodes) {
|
|
this.nodes = [];
|
|
}
|
|
}
|
|
toResult(opts = {}) {
|
|
let lazy = new LazyResult(new Processor(), this, opts);
|
|
return lazy.stringify();
|
|
}
|
|
}
|
|
Document2.registerLazyResult = (dependant) => {
|
|
LazyResult = dependant;
|
|
};
|
|
Document2.registerProcessor = (dependant) => {
|
|
Processor = dependant;
|
|
};
|
|
document$1 = Document2;
|
|
Document2.default = Document2;
|
|
return document$1;
|
|
}
|
|
var warnOnce;
|
|
var hasRequiredWarnOnce;
|
|
function requireWarnOnce() {
|
|
if (hasRequiredWarnOnce) return warnOnce;
|
|
hasRequiredWarnOnce = 1;
|
|
let printed = {};
|
|
warnOnce = function warnOnce2(message) {
|
|
if (printed[message]) return;
|
|
printed[message] = true;
|
|
if (typeof console !== "undefined" && console.warn) {
|
|
console.warn(message);
|
|
}
|
|
};
|
|
return warnOnce;
|
|
}
|
|
var warning;
|
|
var hasRequiredWarning;
|
|
function requireWarning() {
|
|
if (hasRequiredWarning) return warning;
|
|
hasRequiredWarning = 1;
|
|
class Warning {
|
|
constructor(text, opts = {}) {
|
|
this.type = "warning";
|
|
this.text = text;
|
|
if (opts.node && opts.node.source) {
|
|
let range = opts.node.rangeBy(opts);
|
|
this.line = range.start.line;
|
|
this.column = range.start.column;
|
|
this.endLine = range.end.line;
|
|
this.endColumn = range.end.column;
|
|
}
|
|
for (let opt in opts) this[opt] = opts[opt];
|
|
}
|
|
toString() {
|
|
if (this.node) {
|
|
return this.node.error(this.text, {
|
|
index: this.index,
|
|
plugin: this.plugin,
|
|
word: this.word
|
|
}).message;
|
|
}
|
|
if (this.plugin) {
|
|
return this.plugin + ": " + this.text;
|
|
}
|
|
return this.text;
|
|
}
|
|
}
|
|
warning = Warning;
|
|
Warning.default = Warning;
|
|
return warning;
|
|
}
|
|
var result;
|
|
var hasRequiredResult;
|
|
function requireResult() {
|
|
if (hasRequiredResult) return result;
|
|
hasRequiredResult = 1;
|
|
let Warning = requireWarning();
|
|
class Result {
|
|
constructor(processor2, root2, opts) {
|
|
this.processor = processor2;
|
|
this.messages = [];
|
|
this.root = root2;
|
|
this.opts = opts;
|
|
this.css = void 0;
|
|
this.map = void 0;
|
|
}
|
|
toString() {
|
|
return this.css;
|
|
}
|
|
warn(text, opts = {}) {
|
|
if (!opts.plugin) {
|
|
if (this.lastPlugin && this.lastPlugin.postcssPlugin) {
|
|
opts.plugin = this.lastPlugin.postcssPlugin;
|
|
}
|
|
}
|
|
let warning2 = new Warning(text, opts);
|
|
this.messages.push(warning2);
|
|
return warning2;
|
|
}
|
|
warnings() {
|
|
return this.messages.filter((i2) => i2.type === "warning");
|
|
}
|
|
get content() {
|
|
return this.css;
|
|
}
|
|
}
|
|
result = Result;
|
|
Result.default = Result;
|
|
return result;
|
|
}
|
|
var tokenize;
|
|
var hasRequiredTokenize;
|
|
function requireTokenize() {
|
|
if (hasRequiredTokenize) return tokenize;
|
|
hasRequiredTokenize = 1;
|
|
const SINGLE_QUOTE = "'".charCodeAt(0);
|
|
const DOUBLE_QUOTE = '"'.charCodeAt(0);
|
|
const BACKSLASH = "\\".charCodeAt(0);
|
|
const SLASH = "/".charCodeAt(0);
|
|
const NEWLINE = "\n".charCodeAt(0);
|
|
const SPACE = " ".charCodeAt(0);
|
|
const FEED = "\f".charCodeAt(0);
|
|
const TAB = " ".charCodeAt(0);
|
|
const CR = "\r".charCodeAt(0);
|
|
const OPEN_SQUARE = "[".charCodeAt(0);
|
|
const CLOSE_SQUARE = "]".charCodeAt(0);
|
|
const OPEN_PARENTHESES = "(".charCodeAt(0);
|
|
const CLOSE_PARENTHESES = ")".charCodeAt(0);
|
|
const OPEN_CURLY = "{".charCodeAt(0);
|
|
const CLOSE_CURLY = "}".charCodeAt(0);
|
|
const SEMICOLON = ";".charCodeAt(0);
|
|
const ASTERISK = "*".charCodeAt(0);
|
|
const COLON = ":".charCodeAt(0);
|
|
const AT = "@".charCodeAt(0);
|
|
const RE_AT_END = /[\t\n\f\r "#'()/;[\\\]{}]/g;
|
|
const RE_WORD_END = /[\t\n\f\r !"#'():;@[\\\]{}]|\/(?=\*)/g;
|
|
const RE_BAD_BRACKET = /.[\r\n"'(/\\]/;
|
|
const RE_HEX_ESCAPE = /[\da-f]/i;
|
|
tokenize = function tokenizer(input2, options = {}) {
|
|
let css = input2.css.valueOf();
|
|
let ignore = options.ignoreErrors;
|
|
let code, next, quote, content, escape;
|
|
let escaped, escapePos, prev, n2, currentToken;
|
|
let length = css.length;
|
|
let pos = 0;
|
|
let buffer = [];
|
|
let returned = [];
|
|
function position() {
|
|
return pos;
|
|
}
|
|
function unclosed(what) {
|
|
throw input2.error("Unclosed " + what, pos);
|
|
}
|
|
function endOfFile() {
|
|
return returned.length === 0 && pos >= length;
|
|
}
|
|
function nextToken(opts) {
|
|
if (returned.length) return returned.pop();
|
|
if (pos >= length) return;
|
|
let ignoreUnclosed = opts ? opts.ignoreUnclosed : false;
|
|
code = css.charCodeAt(pos);
|
|
switch (code) {
|
|
case NEWLINE:
|
|
case SPACE:
|
|
case TAB:
|
|
case CR:
|
|
case FEED: {
|
|
next = pos;
|
|
do {
|
|
next += 1;
|
|
code = css.charCodeAt(next);
|
|
} while (code === SPACE || code === NEWLINE || code === TAB || code === CR || code === FEED);
|
|
currentToken = ["space", css.slice(pos, next)];
|
|
pos = next - 1;
|
|
break;
|
|
}
|
|
case OPEN_SQUARE:
|
|
case CLOSE_SQUARE:
|
|
case OPEN_CURLY:
|
|
case CLOSE_CURLY:
|
|
case COLON:
|
|
case SEMICOLON:
|
|
case CLOSE_PARENTHESES: {
|
|
let controlChar = String.fromCharCode(code);
|
|
currentToken = [controlChar, controlChar, pos];
|
|
break;
|
|
}
|
|
case OPEN_PARENTHESES: {
|
|
prev = buffer.length ? buffer.pop()[1] : "";
|
|
n2 = css.charCodeAt(pos + 1);
|
|
if (prev === "url" && n2 !== SINGLE_QUOTE && n2 !== DOUBLE_QUOTE && n2 !== SPACE && n2 !== NEWLINE && n2 !== TAB && n2 !== FEED && n2 !== CR) {
|
|
next = pos;
|
|
do {
|
|
escaped = false;
|
|
next = css.indexOf(")", next + 1);
|
|
if (next === -1) {
|
|
if (ignore || ignoreUnclosed) {
|
|
next = pos;
|
|
break;
|
|
} else {
|
|
unclosed("bracket");
|
|
}
|
|
}
|
|
escapePos = next;
|
|
while (css.charCodeAt(escapePos - 1) === BACKSLASH) {
|
|
escapePos -= 1;
|
|
escaped = !escaped;
|
|
}
|
|
} while (escaped);
|
|
currentToken = ["brackets", css.slice(pos, next + 1), pos, next];
|
|
pos = next;
|
|
} else {
|
|
next = css.indexOf(")", pos + 1);
|
|
content = css.slice(pos, next + 1);
|
|
if (next === -1 || RE_BAD_BRACKET.test(content)) {
|
|
currentToken = ["(", "(", pos];
|
|
} else {
|
|
currentToken = ["brackets", content, pos, next];
|
|
pos = next;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case SINGLE_QUOTE:
|
|
case DOUBLE_QUOTE: {
|
|
quote = code === SINGLE_QUOTE ? "'" : '"';
|
|
next = pos;
|
|
do {
|
|
escaped = false;
|
|
next = css.indexOf(quote, next + 1);
|
|
if (next === -1) {
|
|
if (ignore || ignoreUnclosed) {
|
|
next = pos + 1;
|
|
break;
|
|
} else {
|
|
unclosed("string");
|
|
}
|
|
}
|
|
escapePos = next;
|
|
while (css.charCodeAt(escapePos - 1) === BACKSLASH) {
|
|
escapePos -= 1;
|
|
escaped = !escaped;
|
|
}
|
|
} while (escaped);
|
|
currentToken = ["string", css.slice(pos, next + 1), pos, next];
|
|
pos = next;
|
|
break;
|
|
}
|
|
case AT: {
|
|
RE_AT_END.lastIndex = pos + 1;
|
|
RE_AT_END.test(css);
|
|
if (RE_AT_END.lastIndex === 0) {
|
|
next = css.length - 1;
|
|
} else {
|
|
next = RE_AT_END.lastIndex - 2;
|
|
}
|
|
currentToken = ["at-word", css.slice(pos, next + 1), pos, next];
|
|
pos = next;
|
|
break;
|
|
}
|
|
case BACKSLASH: {
|
|
next = pos;
|
|
escape = true;
|
|
while (css.charCodeAt(next + 1) === BACKSLASH) {
|
|
next += 1;
|
|
escape = !escape;
|
|
}
|
|
code = css.charCodeAt(next + 1);
|
|
if (escape && code !== SLASH && code !== SPACE && code !== NEWLINE && code !== TAB && code !== CR && code !== FEED) {
|
|
next += 1;
|
|
if (RE_HEX_ESCAPE.test(css.charAt(next))) {
|
|
while (RE_HEX_ESCAPE.test(css.charAt(next + 1))) {
|
|
next += 1;
|
|
}
|
|
if (css.charCodeAt(next + 1) === SPACE) {
|
|
next += 1;
|
|
}
|
|
}
|
|
}
|
|
currentToken = ["word", css.slice(pos, next + 1), pos, next];
|
|
pos = next;
|
|
break;
|
|
}
|
|
default: {
|
|
if (code === SLASH && css.charCodeAt(pos + 1) === ASTERISK) {
|
|
next = css.indexOf("*/", pos + 2) + 1;
|
|
if (next === 0) {
|
|
if (ignore || ignoreUnclosed) {
|
|
next = css.length;
|
|
} else {
|
|
unclosed("comment");
|
|
}
|
|
}
|
|
currentToken = ["comment", css.slice(pos, next + 1), pos, next];
|
|
pos = next;
|
|
} else {
|
|
RE_WORD_END.lastIndex = pos + 1;
|
|
RE_WORD_END.test(css);
|
|
if (RE_WORD_END.lastIndex === 0) {
|
|
next = css.length - 1;
|
|
} else {
|
|
next = RE_WORD_END.lastIndex - 2;
|
|
}
|
|
currentToken = ["word", css.slice(pos, next + 1), pos, next];
|
|
buffer.push(currentToken);
|
|
pos = next;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
pos++;
|
|
return currentToken;
|
|
}
|
|
function back(token) {
|
|
returned.push(token);
|
|
}
|
|
return {
|
|
back,
|
|
endOfFile,
|
|
nextToken,
|
|
position
|
|
};
|
|
};
|
|
return tokenize;
|
|
}
|
|
var atRule;
|
|
var hasRequiredAtRule;
|
|
function requireAtRule() {
|
|
if (hasRequiredAtRule) return atRule;
|
|
hasRequiredAtRule = 1;
|
|
let Container = requireContainer();
|
|
class AtRule extends Container {
|
|
constructor(defaults) {
|
|
super(defaults);
|
|
this.type = "atrule";
|
|
}
|
|
append(...children) {
|
|
if (!this.proxyOf.nodes) this.nodes = [];
|
|
return super.append(...children);
|
|
}
|
|
prepend(...children) {
|
|
if (!this.proxyOf.nodes) this.nodes = [];
|
|
return super.prepend(...children);
|
|
}
|
|
}
|
|
atRule = AtRule;
|
|
AtRule.default = AtRule;
|
|
Container.registerAtRule(AtRule);
|
|
return atRule;
|
|
}
|
|
var root;
|
|
var hasRequiredRoot;
|
|
function requireRoot() {
|
|
if (hasRequiredRoot) return root;
|
|
hasRequiredRoot = 1;
|
|
let Container = requireContainer();
|
|
let LazyResult, Processor;
|
|
class Root extends Container {
|
|
constructor(defaults) {
|
|
super(defaults);
|
|
this.type = "root";
|
|
if (!this.nodes) this.nodes = [];
|
|
}
|
|
normalize(child, sample, type) {
|
|
let nodes = super.normalize(child);
|
|
if (sample) {
|
|
if (type === "prepend") {
|
|
if (this.nodes.length > 1) {
|
|
sample.raws.before = this.nodes[1].raws.before;
|
|
} else {
|
|
delete sample.raws.before;
|
|
}
|
|
} else if (this.first !== sample) {
|
|
for (let node2 of nodes) {
|
|
node2.raws.before = sample.raws.before;
|
|
}
|
|
}
|
|
}
|
|
return nodes;
|
|
}
|
|
removeChild(child, ignore) {
|
|
let index2 = this.index(child);
|
|
if (!ignore && index2 === 0 && this.nodes.length > 1) {
|
|
this.nodes[1].raws.before = this.nodes[index2].raws.before;
|
|
}
|
|
return super.removeChild(child);
|
|
}
|
|
toResult(opts = {}) {
|
|
let lazy = new LazyResult(new Processor(), this, opts);
|
|
return lazy.stringify();
|
|
}
|
|
}
|
|
Root.registerLazyResult = (dependant) => {
|
|
LazyResult = dependant;
|
|
};
|
|
Root.registerProcessor = (dependant) => {
|
|
Processor = dependant;
|
|
};
|
|
root = Root;
|
|
Root.default = Root;
|
|
Container.registerRoot(Root);
|
|
return root;
|
|
}
|
|
var list_1;
|
|
var hasRequiredList;
|
|
function requireList() {
|
|
if (hasRequiredList) return list_1;
|
|
hasRequiredList = 1;
|
|
let list = {
|
|
comma(string) {
|
|
return list.split(string, [","], true);
|
|
},
|
|
space(string) {
|
|
let spaces = [" ", "\n", " "];
|
|
return list.split(string, spaces);
|
|
},
|
|
split(string, separators, last) {
|
|
let array = [];
|
|
let current = "";
|
|
let split = false;
|
|
let func = 0;
|
|
let inQuote = false;
|
|
let prevQuote = "";
|
|
let escape = false;
|
|
for (let letter of string) {
|
|
if (escape) {
|
|
escape = false;
|
|
} else if (letter === "\\") {
|
|
escape = true;
|
|
} else if (inQuote) {
|
|
if (letter === prevQuote) {
|
|
inQuote = false;
|
|
}
|
|
} else if (letter === '"' || letter === "'") {
|
|
inQuote = true;
|
|
prevQuote = letter;
|
|
} else if (letter === "(") {
|
|
func += 1;
|
|
} else if (letter === ")") {
|
|
if (func > 0) func -= 1;
|
|
} else if (func === 0) {
|
|
if (separators.includes(letter)) split = true;
|
|
}
|
|
if (split) {
|
|
if (current !== "") array.push(current.trim());
|
|
current = "";
|
|
split = false;
|
|
} else {
|
|
current += letter;
|
|
}
|
|
}
|
|
if (last || current !== "") array.push(current.trim());
|
|
return array;
|
|
}
|
|
};
|
|
list_1 = list;
|
|
list.default = list;
|
|
return list_1;
|
|
}
|
|
var rule;
|
|
var hasRequiredRule;
|
|
function requireRule() {
|
|
if (hasRequiredRule) return rule;
|
|
hasRequiredRule = 1;
|
|
let Container = requireContainer();
|
|
let list = requireList();
|
|
class Rule extends Container {
|
|
constructor(defaults) {
|
|
super(defaults);
|
|
this.type = "rule";
|
|
if (!this.nodes) this.nodes = [];
|
|
}
|
|
get selectors() {
|
|
return list.comma(this.selector);
|
|
}
|
|
set selectors(values) {
|
|
let match = this.selector ? this.selector.match(/,\s*/) : null;
|
|
let sep = match ? match[0] : "," + this.raw("between", "beforeOpen");
|
|
this.selector = values.join(sep);
|
|
}
|
|
}
|
|
rule = Rule;
|
|
Rule.default = Rule;
|
|
Container.registerRule(Rule);
|
|
return rule;
|
|
}
|
|
var parser;
|
|
var hasRequiredParser;
|
|
function requireParser() {
|
|
if (hasRequiredParser) return parser;
|
|
hasRequiredParser = 1;
|
|
let Declaration = requireDeclaration();
|
|
let tokenizer = requireTokenize();
|
|
let Comment = requireComment();
|
|
let AtRule = requireAtRule();
|
|
let Root = requireRoot();
|
|
let Rule = requireRule();
|
|
const SAFE_COMMENT_NEIGHBOR = {
|
|
empty: true,
|
|
space: true
|
|
};
|
|
function findLastWithPosition(tokens) {
|
|
for (let i2 = tokens.length - 1; i2 >= 0; i2--) {
|
|
let token = tokens[i2];
|
|
let pos = token[3] || token[2];
|
|
if (pos) return pos;
|
|
}
|
|
}
|
|
class Parser {
|
|
constructor(input2) {
|
|
this.input = input2;
|
|
this.root = new Root();
|
|
this.current = this.root;
|
|
this.spaces = "";
|
|
this.semicolon = false;
|
|
this.createTokenizer();
|
|
this.root.source = { input: input2, start: { column: 1, line: 1, offset: 0 } };
|
|
}
|
|
atrule(token) {
|
|
let node2 = new AtRule();
|
|
node2.name = token[1].slice(1);
|
|
if (node2.name === "") {
|
|
this.unnamedAtrule(node2, token);
|
|
}
|
|
this.init(node2, token[2]);
|
|
let type;
|
|
let prev;
|
|
let shift;
|
|
let last = false;
|
|
let open = false;
|
|
let params = [];
|
|
let brackets = [];
|
|
while (!this.tokenizer.endOfFile()) {
|
|
token = this.tokenizer.nextToken();
|
|
type = token[0];
|
|
if (type === "(" || type === "[") {
|
|
brackets.push(type === "(" ? ")" : "]");
|
|
} else if (type === "{" && brackets.length > 0) {
|
|
brackets.push("}");
|
|
} else if (type === brackets[brackets.length - 1]) {
|
|
brackets.pop();
|
|
}
|
|
if (brackets.length === 0) {
|
|
if (type === ";") {
|
|
node2.source.end = this.getPosition(token[2]);
|
|
node2.source.end.offset++;
|
|
this.semicolon = true;
|
|
break;
|
|
} else if (type === "{") {
|
|
open = true;
|
|
break;
|
|
} else if (type === "}") {
|
|
if (params.length > 0) {
|
|
shift = params.length - 1;
|
|
prev = params[shift];
|
|
while (prev && prev[0] === "space") {
|
|
prev = params[--shift];
|
|
}
|
|
if (prev) {
|
|
node2.source.end = this.getPosition(prev[3] || prev[2]);
|
|
node2.source.end.offset++;
|
|
}
|
|
}
|
|
this.end(token);
|
|
break;
|
|
} else {
|
|
params.push(token);
|
|
}
|
|
} else {
|
|
params.push(token);
|
|
}
|
|
if (this.tokenizer.endOfFile()) {
|
|
last = true;
|
|
break;
|
|
}
|
|
}
|
|
node2.raws.between = this.spacesAndCommentsFromEnd(params);
|
|
if (params.length) {
|
|
node2.raws.afterName = this.spacesAndCommentsFromStart(params);
|
|
this.raw(node2, "params", params);
|
|
if (last) {
|
|
token = params[params.length - 1];
|
|
node2.source.end = this.getPosition(token[3] || token[2]);
|
|
node2.source.end.offset++;
|
|
this.spaces = node2.raws.between;
|
|
node2.raws.between = "";
|
|
}
|
|
} else {
|
|
node2.raws.afterName = "";
|
|
node2.params = "";
|
|
}
|
|
if (open) {
|
|
node2.nodes = [];
|
|
this.current = node2;
|
|
}
|
|
}
|
|
checkMissedSemicolon(tokens) {
|
|
let colon = this.colon(tokens);
|
|
if (colon === false) return;
|
|
let founded = 0;
|
|
let token;
|
|
for (let j = colon - 1; j >= 0; j--) {
|
|
token = tokens[j];
|
|
if (token[0] !== "space") {
|
|
founded += 1;
|
|
if (founded === 2) break;
|
|
}
|
|
}
|
|
throw this.input.error(
|
|
"Missed semicolon",
|
|
token[0] === "word" ? token[3] + 1 : token[2]
|
|
);
|
|
}
|
|
colon(tokens) {
|
|
let brackets = 0;
|
|
let token, type, prev;
|
|
for (let [i2, element] of tokens.entries()) {
|
|
token = element;
|
|
type = token[0];
|
|
if (type === "(") {
|
|
brackets += 1;
|
|
}
|
|
if (type === ")") {
|
|
brackets -= 1;
|
|
}
|
|
if (brackets === 0 && type === ":") {
|
|
if (!prev) {
|
|
this.doubleColon(token);
|
|
} else if (prev[0] === "word" && prev[1] === "progid") {
|
|
continue;
|
|
} else {
|
|
return i2;
|
|
}
|
|
}
|
|
prev = token;
|
|
}
|
|
return false;
|
|
}
|
|
comment(token) {
|
|
let node2 = new Comment();
|
|
this.init(node2, token[2]);
|
|
node2.source.end = this.getPosition(token[3] || token[2]);
|
|
node2.source.end.offset++;
|
|
let text = token[1].slice(2, -2);
|
|
if (/^\s*$/.test(text)) {
|
|
node2.text = "";
|
|
node2.raws.left = text;
|
|
node2.raws.right = "";
|
|
} else {
|
|
let match = text.match(/^(\s*)([^]*\S)(\s*)$/);
|
|
node2.text = match[2];
|
|
node2.raws.left = match[1];
|
|
node2.raws.right = match[3];
|
|
}
|
|
}
|
|
createTokenizer() {
|
|
this.tokenizer = tokenizer(this.input);
|
|
}
|
|
decl(tokens, customProperty) {
|
|
let node2 = new Declaration();
|
|
this.init(node2, tokens[0][2]);
|
|
let last = tokens[tokens.length - 1];
|
|
if (last[0] === ";") {
|
|
this.semicolon = true;
|
|
tokens.pop();
|
|
}
|
|
node2.source.end = this.getPosition(
|
|
last[3] || last[2] || findLastWithPosition(tokens)
|
|
);
|
|
node2.source.end.offset++;
|
|
while (tokens[0][0] !== "word") {
|
|
if (tokens.length === 1) this.unknownWord(tokens);
|
|
node2.raws.before += tokens.shift()[1];
|
|
}
|
|
node2.source.start = this.getPosition(tokens[0][2]);
|
|
node2.prop = "";
|
|
while (tokens.length) {
|
|
let type = tokens[0][0];
|
|
if (type === ":" || type === "space" || type === "comment") {
|
|
break;
|
|
}
|
|
node2.prop += tokens.shift()[1];
|
|
}
|
|
node2.raws.between = "";
|
|
let token;
|
|
while (tokens.length) {
|
|
token = tokens.shift();
|
|
if (token[0] === ":") {
|
|
node2.raws.between += token[1];
|
|
break;
|
|
} else {
|
|
if (token[0] === "word" && /\w/.test(token[1])) {
|
|
this.unknownWord([token]);
|
|
}
|
|
node2.raws.between += token[1];
|
|
}
|
|
}
|
|
if (node2.prop[0] === "_" || node2.prop[0] === "*") {
|
|
node2.raws.before += node2.prop[0];
|
|
node2.prop = node2.prop.slice(1);
|
|
}
|
|
let firstSpaces = [];
|
|
let next;
|
|
while (tokens.length) {
|
|
next = tokens[0][0];
|
|
if (next !== "space" && next !== "comment") break;
|
|
firstSpaces.push(tokens.shift());
|
|
}
|
|
this.precheckMissedSemicolon(tokens);
|
|
for (let i2 = tokens.length - 1; i2 >= 0; i2--) {
|
|
token = tokens[i2];
|
|
if (token[1].toLowerCase() === "!important") {
|
|
node2.important = true;
|
|
let string = this.stringFrom(tokens, i2);
|
|
string = this.spacesFromEnd(tokens) + string;
|
|
if (string !== " !important") node2.raws.important = string;
|
|
break;
|
|
} else if (token[1].toLowerCase() === "important") {
|
|
let cache = tokens.slice(0);
|
|
let str = "";
|
|
for (let j = i2; j > 0; j--) {
|
|
let type = cache[j][0];
|
|
if (str.trim().indexOf("!") === 0 && type !== "space") {
|
|
break;
|
|
}
|
|
str = cache.pop()[1] + str;
|
|
}
|
|
if (str.trim().indexOf("!") === 0) {
|
|
node2.important = true;
|
|
node2.raws.important = str;
|
|
tokens = cache;
|
|
}
|
|
}
|
|
if (token[0] !== "space" && token[0] !== "comment") {
|
|
break;
|
|
}
|
|
}
|
|
let hasWord = tokens.some((i2) => i2[0] !== "space" && i2[0] !== "comment");
|
|
if (hasWord) {
|
|
node2.raws.between += firstSpaces.map((i2) => i2[1]).join("");
|
|
firstSpaces = [];
|
|
}
|
|
this.raw(node2, "value", firstSpaces.concat(tokens), customProperty);
|
|
if (node2.value.includes(":") && !customProperty) {
|
|
this.checkMissedSemicolon(tokens);
|
|
}
|
|
}
|
|
doubleColon(token) {
|
|
throw this.input.error(
|
|
"Double colon",
|
|
{ offset: token[2] },
|
|
{ offset: token[2] + token[1].length }
|
|
);
|
|
}
|
|
emptyRule(token) {
|
|
let node2 = new Rule();
|
|
this.init(node2, token[2]);
|
|
node2.selector = "";
|
|
node2.raws.between = "";
|
|
this.current = node2;
|
|
}
|
|
end(token) {
|
|
if (this.current.nodes && this.current.nodes.length) {
|
|
this.current.raws.semicolon = this.semicolon;
|
|
}
|
|
this.semicolon = false;
|
|
this.current.raws.after = (this.current.raws.after || "") + this.spaces;
|
|
this.spaces = "";
|
|
if (this.current.parent) {
|
|
this.current.source.end = this.getPosition(token[2]);
|
|
this.current.source.end.offset++;
|
|
this.current = this.current.parent;
|
|
} else {
|
|
this.unexpectedClose(token);
|
|
}
|
|
}
|
|
endFile() {
|
|
if (this.current.parent) this.unclosedBlock();
|
|
if (this.current.nodes && this.current.nodes.length) {
|
|
this.current.raws.semicolon = this.semicolon;
|
|
}
|
|
this.current.raws.after = (this.current.raws.after || "") + this.spaces;
|
|
this.root.source.end = this.getPosition(this.tokenizer.position());
|
|
}
|
|
freeSemicolon(token) {
|
|
this.spaces += token[1];
|
|
if (this.current.nodes) {
|
|
let prev = this.current.nodes[this.current.nodes.length - 1];
|
|
if (prev && prev.type === "rule" && !prev.raws.ownSemicolon) {
|
|
prev.raws.ownSemicolon = this.spaces;
|
|
this.spaces = "";
|
|
}
|
|
}
|
|
}
|
|
// Helpers
|
|
getPosition(offset) {
|
|
let pos = this.input.fromOffset(offset);
|
|
return {
|
|
column: pos.col,
|
|
line: pos.line,
|
|
offset
|
|
};
|
|
}
|
|
init(node2, offset) {
|
|
this.current.push(node2);
|
|
node2.source = {
|
|
input: this.input,
|
|
start: this.getPosition(offset)
|
|
};
|
|
node2.raws.before = this.spaces;
|
|
this.spaces = "";
|
|
if (node2.type !== "comment") this.semicolon = false;
|
|
}
|
|
other(start) {
|
|
let end = false;
|
|
let type = null;
|
|
let colon = false;
|
|
let bracket = null;
|
|
let brackets = [];
|
|
let customProperty = start[1].startsWith("--");
|
|
let tokens = [];
|
|
let token = start;
|
|
while (token) {
|
|
type = token[0];
|
|
tokens.push(token);
|
|
if (type === "(" || type === "[") {
|
|
if (!bracket) bracket = token;
|
|
brackets.push(type === "(" ? ")" : "]");
|
|
} else if (customProperty && colon && type === "{") {
|
|
if (!bracket) bracket = token;
|
|
brackets.push("}");
|
|
} else if (brackets.length === 0) {
|
|
if (type === ";") {
|
|
if (colon) {
|
|
this.decl(tokens, customProperty);
|
|
return;
|
|
} else {
|
|
break;
|
|
}
|
|
} else if (type === "{") {
|
|
this.rule(tokens);
|
|
return;
|
|
} else if (type === "}") {
|
|
this.tokenizer.back(tokens.pop());
|
|
end = true;
|
|
break;
|
|
} else if (type === ":") {
|
|
colon = true;
|
|
}
|
|
} else if (type === brackets[brackets.length - 1]) {
|
|
brackets.pop();
|
|
if (brackets.length === 0) bracket = null;
|
|
}
|
|
token = this.tokenizer.nextToken();
|
|
}
|
|
if (this.tokenizer.endOfFile()) end = true;
|
|
if (brackets.length > 0) this.unclosedBracket(bracket);
|
|
if (end && colon) {
|
|
if (!customProperty) {
|
|
while (tokens.length) {
|
|
token = tokens[tokens.length - 1][0];
|
|
if (token !== "space" && token !== "comment") break;
|
|
this.tokenizer.back(tokens.pop());
|
|
}
|
|
}
|
|
this.decl(tokens, customProperty);
|
|
} else {
|
|
this.unknownWord(tokens);
|
|
}
|
|
}
|
|
parse() {
|
|
let token;
|
|
while (!this.tokenizer.endOfFile()) {
|
|
token = this.tokenizer.nextToken();
|
|
switch (token[0]) {
|
|
case "space":
|
|
this.spaces += token[1];
|
|
break;
|
|
case ";":
|
|
this.freeSemicolon(token);
|
|
break;
|
|
case "}":
|
|
this.end(token);
|
|
break;
|
|
case "comment":
|
|
this.comment(token);
|
|
break;
|
|
case "at-word":
|
|
this.atrule(token);
|
|
break;
|
|
case "{":
|
|
this.emptyRule(token);
|
|
break;
|
|
default:
|
|
this.other(token);
|
|
break;
|
|
}
|
|
}
|
|
this.endFile();
|
|
}
|
|
precheckMissedSemicolon() {
|
|
}
|
|
raw(node2, prop, tokens, customProperty) {
|
|
let token, type;
|
|
let length = tokens.length;
|
|
let value = "";
|
|
let clean = true;
|
|
let next, prev;
|
|
for (let i2 = 0; i2 < length; i2 += 1) {
|
|
token = tokens[i2];
|
|
type = token[0];
|
|
if (type === "space" && i2 === length - 1 && !customProperty) {
|
|
clean = false;
|
|
} else if (type === "comment") {
|
|
prev = tokens[i2 - 1] ? tokens[i2 - 1][0] : "empty";
|
|
next = tokens[i2 + 1] ? tokens[i2 + 1][0] : "empty";
|
|
if (!SAFE_COMMENT_NEIGHBOR[prev] && !SAFE_COMMENT_NEIGHBOR[next]) {
|
|
if (value.slice(-1) === ",") {
|
|
clean = false;
|
|
} else {
|
|
value += token[1];
|
|
}
|
|
} else {
|
|
clean = false;
|
|
}
|
|
} else {
|
|
value += token[1];
|
|
}
|
|
}
|
|
if (!clean) {
|
|
let raw = tokens.reduce((all, i2) => all + i2[1], "");
|
|
node2.raws[prop] = { raw, value };
|
|
}
|
|
node2[prop] = value;
|
|
}
|
|
rule(tokens) {
|
|
tokens.pop();
|
|
let node2 = new Rule();
|
|
this.init(node2, tokens[0][2]);
|
|
node2.raws.between = this.spacesAndCommentsFromEnd(tokens);
|
|
this.raw(node2, "selector", tokens);
|
|
this.current = node2;
|
|
}
|
|
spacesAndCommentsFromEnd(tokens) {
|
|
let lastTokenType;
|
|
let spaces = "";
|
|
while (tokens.length) {
|
|
lastTokenType = tokens[tokens.length - 1][0];
|
|
if (lastTokenType !== "space" && lastTokenType !== "comment") break;
|
|
spaces = tokens.pop()[1] + spaces;
|
|
}
|
|
return spaces;
|
|
}
|
|
// Errors
|
|
spacesAndCommentsFromStart(tokens) {
|
|
let next;
|
|
let spaces = "";
|
|
while (tokens.length) {
|
|
next = tokens[0][0];
|
|
if (next !== "space" && next !== "comment") break;
|
|
spaces += tokens.shift()[1];
|
|
}
|
|
return spaces;
|
|
}
|
|
spacesFromEnd(tokens) {
|
|
let lastTokenType;
|
|
let spaces = "";
|
|
while (tokens.length) {
|
|
lastTokenType = tokens[tokens.length - 1][0];
|
|
if (lastTokenType !== "space") break;
|
|
spaces = tokens.pop()[1] + spaces;
|
|
}
|
|
return spaces;
|
|
}
|
|
stringFrom(tokens, from) {
|
|
let result2 = "";
|
|
for (let i2 = from; i2 < tokens.length; i2++) {
|
|
result2 += tokens[i2][1];
|
|
}
|
|
tokens.splice(from, tokens.length - from);
|
|
return result2;
|
|
}
|
|
unclosedBlock() {
|
|
let pos = this.current.source.start;
|
|
throw this.input.error("Unclosed block", pos.line, pos.column);
|
|
}
|
|
unclosedBracket(bracket) {
|
|
throw this.input.error(
|
|
"Unclosed bracket",
|
|
{ offset: bracket[2] },
|
|
{ offset: bracket[2] + 1 }
|
|
);
|
|
}
|
|
unexpectedClose(token) {
|
|
throw this.input.error(
|
|
"Unexpected }",
|
|
{ offset: token[2] },
|
|
{ offset: token[2] + 1 }
|
|
);
|
|
}
|
|
unknownWord(tokens) {
|
|
throw this.input.error(
|
|
"Unknown word",
|
|
{ offset: tokens[0][2] },
|
|
{ offset: tokens[0][2] + tokens[0][1].length }
|
|
);
|
|
}
|
|
unnamedAtrule(node2, token) {
|
|
throw this.input.error(
|
|
"At-rule without name",
|
|
{ offset: token[2] },
|
|
{ offset: token[2] + token[1].length }
|
|
);
|
|
}
|
|
}
|
|
parser = Parser;
|
|
return parser;
|
|
}
|
|
var parse_1;
|
|
var hasRequiredParse;
|
|
function requireParse() {
|
|
if (hasRequiredParse) return parse_1;
|
|
hasRequiredParse = 1;
|
|
let Container = requireContainer();
|
|
let Parser = requireParser();
|
|
let Input = requireInput();
|
|
function parse(css, opts) {
|
|
let input2 = new Input(css, opts);
|
|
let parser2 = new Parser(input2);
|
|
try {
|
|
parser2.parse();
|
|
} catch (e2) {
|
|
if (true) {
|
|
if (e2.name === "CssSyntaxError" && opts && opts.from) {
|
|
if (/\.scss$/i.test(opts.from)) {
|
|
e2.message += "\nYou tried to parse SCSS with the standard CSS parser; try again with the postcss-scss parser";
|
|
} else if (/\.sass/i.test(opts.from)) {
|
|
e2.message += "\nYou tried to parse Sass with the standard CSS parser; try again with the postcss-sass parser";
|
|
} else if (/\.less$/i.test(opts.from)) {
|
|
e2.message += "\nYou tried to parse Less with the standard CSS parser; try again with the postcss-less parser";
|
|
}
|
|
}
|
|
}
|
|
throw e2;
|
|
}
|
|
return parser2.root;
|
|
}
|
|
parse_1 = parse;
|
|
parse.default = parse;
|
|
Container.registerParse(parse);
|
|
return parse_1;
|
|
}
|
|
var lazyResult;
|
|
var hasRequiredLazyResult;
|
|
function requireLazyResult() {
|
|
if (hasRequiredLazyResult) return lazyResult;
|
|
hasRequiredLazyResult = 1;
|
|
let { isClean, my } = requireSymbols();
|
|
let MapGenerator = requireMapGenerator();
|
|
let stringify = requireStringify();
|
|
let Container = requireContainer();
|
|
let Document2 = requireDocument();
|
|
let warnOnce2 = requireWarnOnce();
|
|
let Result = requireResult();
|
|
let parse = requireParse();
|
|
let Root = requireRoot();
|
|
const TYPE_TO_CLASS_NAME = {
|
|
atrule: "AtRule",
|
|
comment: "Comment",
|
|
decl: "Declaration",
|
|
document: "Document",
|
|
root: "Root",
|
|
rule: "Rule"
|
|
};
|
|
const PLUGIN_PROPS = {
|
|
AtRule: true,
|
|
AtRuleExit: true,
|
|
Comment: true,
|
|
CommentExit: true,
|
|
Declaration: true,
|
|
DeclarationExit: true,
|
|
Document: true,
|
|
DocumentExit: true,
|
|
Once: true,
|
|
OnceExit: true,
|
|
postcssPlugin: true,
|
|
prepare: true,
|
|
Root: true,
|
|
RootExit: true,
|
|
Rule: true,
|
|
RuleExit: true
|
|
};
|
|
const NOT_VISITORS = {
|
|
Once: true,
|
|
postcssPlugin: true,
|
|
prepare: true
|
|
};
|
|
const CHILDREN = 0;
|
|
function isPromise(obj) {
|
|
return typeof obj === "object" && typeof obj.then === "function";
|
|
}
|
|
function getEvents(node2) {
|
|
let key = false;
|
|
let type = TYPE_TO_CLASS_NAME[node2.type];
|
|
if (node2.type === "decl") {
|
|
key = node2.prop.toLowerCase();
|
|
} else if (node2.type === "atrule") {
|
|
key = node2.name.toLowerCase();
|
|
}
|
|
if (key && node2.append) {
|
|
return [
|
|
type,
|
|
type + "-" + key,
|
|
CHILDREN,
|
|
type + "Exit",
|
|
type + "Exit-" + key
|
|
];
|
|
} else if (key) {
|
|
return [type, type + "-" + key, type + "Exit", type + "Exit-" + key];
|
|
} else if (node2.append) {
|
|
return [type, CHILDREN, type + "Exit"];
|
|
} else {
|
|
return [type, type + "Exit"];
|
|
}
|
|
}
|
|
function toStack(node2) {
|
|
let events;
|
|
if (node2.type === "document") {
|
|
events = ["Document", CHILDREN, "DocumentExit"];
|
|
} else if (node2.type === "root") {
|
|
events = ["Root", CHILDREN, "RootExit"];
|
|
} else {
|
|
events = getEvents(node2);
|
|
}
|
|
return {
|
|
eventIndex: 0,
|
|
events,
|
|
iterator: 0,
|
|
node: node2,
|
|
visitorIndex: 0,
|
|
visitors: []
|
|
};
|
|
}
|
|
function cleanMarks(node2) {
|
|
node2[isClean] = false;
|
|
if (node2.nodes) node2.nodes.forEach((i2) => cleanMarks(i2));
|
|
return node2;
|
|
}
|
|
let postcss2 = {};
|
|
class LazyResult {
|
|
constructor(processor2, css, opts) {
|
|
this.stringified = false;
|
|
this.processed = false;
|
|
let root2;
|
|
if (typeof css === "object" && css !== null && (css.type === "root" || css.type === "document")) {
|
|
root2 = cleanMarks(css);
|
|
} else if (css instanceof LazyResult || css instanceof Result) {
|
|
root2 = cleanMarks(css.root);
|
|
if (css.map) {
|
|
if (typeof opts.map === "undefined") opts.map = {};
|
|
if (!opts.map.inline) opts.map.inline = false;
|
|
opts.map.prev = css.map;
|
|
}
|
|
} else {
|
|
let parser2 = parse;
|
|
if (opts.syntax) parser2 = opts.syntax.parse;
|
|
if (opts.parser) parser2 = opts.parser;
|
|
if (parser2.parse) parser2 = parser2.parse;
|
|
try {
|
|
root2 = parser2(css, opts);
|
|
} catch (error) {
|
|
this.processed = true;
|
|
this.error = error;
|
|
}
|
|
if (root2 && !root2[my]) {
|
|
Container.rebuild(root2);
|
|
}
|
|
}
|
|
this.result = new Result(processor2, root2, opts);
|
|
this.helpers = __spreadProps(__spreadValues({}, postcss2), { postcss: postcss2, result: this.result });
|
|
this.plugins = this.processor.plugins.map((plugin) => {
|
|
if (typeof plugin === "object" && plugin.prepare) {
|
|
return __spreadValues(__spreadValues({}, plugin), plugin.prepare(this.result));
|
|
} else {
|
|
return plugin;
|
|
}
|
|
});
|
|
}
|
|
async() {
|
|
if (this.error) return Promise.reject(this.error);
|
|
if (this.processed) return Promise.resolve(this.result);
|
|
if (!this.processing) {
|
|
this.processing = this.runAsync();
|
|
}
|
|
return this.processing;
|
|
}
|
|
catch(onRejected) {
|
|
return this.async().catch(onRejected);
|
|
}
|
|
finally(onFinally) {
|
|
return this.async().then(onFinally, onFinally);
|
|
}
|
|
getAsyncError() {
|
|
throw new Error("Use process(css).then(cb) to work with async plugins");
|
|
}
|
|
handleError(error, node2) {
|
|
let plugin = this.result.lastPlugin;
|
|
try {
|
|
if (node2) node2.addToError(error);
|
|
this.error = error;
|
|
if (error.name === "CssSyntaxError" && !error.plugin) {
|
|
error.plugin = plugin.postcssPlugin;
|
|
error.setMessage();
|
|
} else if (plugin.postcssVersion) {
|
|
if (true) {
|
|
let pluginName = plugin.postcssPlugin;
|
|
let pluginVer = plugin.postcssVersion;
|
|
let runtimeVer = this.result.processor.version;
|
|
let a2 = pluginVer.split(".");
|
|
let b = runtimeVer.split(".");
|
|
if (a2[0] !== b[0] || parseInt(a2[1]) > parseInt(b[1])) {
|
|
console.error(
|
|
"Unknown error from PostCSS plugin. Your current PostCSS version is " + runtimeVer + ", but " + pluginName + " uses " + pluginVer + ". Perhaps this is the source of the error below."
|
|
);
|
|
}
|
|
}
|
|
}
|
|
} catch (err) {
|
|
if (console && console.error) console.error(err);
|
|
}
|
|
return error;
|
|
}
|
|
prepareVisitors() {
|
|
this.listeners = {};
|
|
let add = (plugin, type, cb) => {
|
|
if (!this.listeners[type]) this.listeners[type] = [];
|
|
this.listeners[type].push([plugin, cb]);
|
|
};
|
|
for (let plugin of this.plugins) {
|
|
if (typeof plugin === "object") {
|
|
for (let event in plugin) {
|
|
if (!PLUGIN_PROPS[event] && /^[A-Z]/.test(event)) {
|
|
throw new Error(
|
|
`Unknown event ${event} in ${plugin.postcssPlugin}. Try to update PostCSS (${this.processor.version} now).`
|
|
);
|
|
}
|
|
if (!NOT_VISITORS[event]) {
|
|
if (typeof plugin[event] === "object") {
|
|
for (let filter in plugin[event]) {
|
|
if (filter === "*") {
|
|
add(plugin, event, plugin[event][filter]);
|
|
} else {
|
|
add(
|
|
plugin,
|
|
event + "-" + filter.toLowerCase(),
|
|
plugin[event][filter]
|
|
);
|
|
}
|
|
}
|
|
} else if (typeof plugin[event] === "function") {
|
|
add(plugin, event, plugin[event]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
this.hasListener = Object.keys(this.listeners).length > 0;
|
|
}
|
|
async runAsync() {
|
|
this.plugin = 0;
|
|
for (let i2 = 0; i2 < this.plugins.length; i2++) {
|
|
let plugin = this.plugins[i2];
|
|
let promise = this.runOnRoot(plugin);
|
|
if (isPromise(promise)) {
|
|
try {
|
|
await promise;
|
|
} catch (error) {
|
|
throw this.handleError(error);
|
|
}
|
|
}
|
|
}
|
|
this.prepareVisitors();
|
|
if (this.hasListener) {
|
|
let root2 = this.result.root;
|
|
while (!root2[isClean]) {
|
|
root2[isClean] = true;
|
|
let stack = [toStack(root2)];
|
|
while (stack.length > 0) {
|
|
let promise = this.visitTick(stack);
|
|
if (isPromise(promise)) {
|
|
try {
|
|
await promise;
|
|
} catch (e2) {
|
|
let node2 = stack[stack.length - 1].node;
|
|
throw this.handleError(e2, node2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (this.listeners.OnceExit) {
|
|
for (let [plugin, visitor] of this.listeners.OnceExit) {
|
|
this.result.lastPlugin = plugin;
|
|
try {
|
|
if (root2.type === "document") {
|
|
let roots = root2.nodes.map(
|
|
(subRoot) => visitor(subRoot, this.helpers)
|
|
);
|
|
await Promise.all(roots);
|
|
} else {
|
|
await visitor(root2, this.helpers);
|
|
}
|
|
} catch (e2) {
|
|
throw this.handleError(e2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
this.processed = true;
|
|
return this.stringify();
|
|
}
|
|
runOnRoot(plugin) {
|
|
this.result.lastPlugin = plugin;
|
|
try {
|
|
if (typeof plugin === "object" && plugin.Once) {
|
|
if (this.result.root.type === "document") {
|
|
let roots = this.result.root.nodes.map(
|
|
(root2) => plugin.Once(root2, this.helpers)
|
|
);
|
|
if (isPromise(roots[0])) {
|
|
return Promise.all(roots);
|
|
}
|
|
return roots;
|
|
}
|
|
return plugin.Once(this.result.root, this.helpers);
|
|
} else if (typeof plugin === "function") {
|
|
return plugin(this.result.root, this.result);
|
|
}
|
|
} catch (error) {
|
|
throw this.handleError(error);
|
|
}
|
|
}
|
|
stringify() {
|
|
if (this.error) throw this.error;
|
|
if (this.stringified) return this.result;
|
|
this.stringified = true;
|
|
this.sync();
|
|
let opts = this.result.opts;
|
|
let str = stringify;
|
|
if (opts.syntax) str = opts.syntax.stringify;
|
|
if (opts.stringifier) str = opts.stringifier;
|
|
if (str.stringify) str = str.stringify;
|
|
let map = new MapGenerator(str, this.result.root, this.result.opts);
|
|
let data = map.generate();
|
|
this.result.css = data[0];
|
|
this.result.map = data[1];
|
|
return this.result;
|
|
}
|
|
sync() {
|
|
if (this.error) throw this.error;
|
|
if (this.processed) return this.result;
|
|
this.processed = true;
|
|
if (this.processing) {
|
|
throw this.getAsyncError();
|
|
}
|
|
for (let plugin of this.plugins) {
|
|
let promise = this.runOnRoot(plugin);
|
|
if (isPromise(promise)) {
|
|
throw this.getAsyncError();
|
|
}
|
|
}
|
|
this.prepareVisitors();
|
|
if (this.hasListener) {
|
|
let root2 = this.result.root;
|
|
while (!root2[isClean]) {
|
|
root2[isClean] = true;
|
|
this.walkSync(root2);
|
|
}
|
|
if (this.listeners.OnceExit) {
|
|
if (root2.type === "document") {
|
|
for (let subRoot of root2.nodes) {
|
|
this.visitSync(this.listeners.OnceExit, subRoot);
|
|
}
|
|
} else {
|
|
this.visitSync(this.listeners.OnceExit, root2);
|
|
}
|
|
}
|
|
}
|
|
return this.result;
|
|
}
|
|
then(onFulfilled, onRejected) {
|
|
if (true) {
|
|
if (!("from" in this.opts)) {
|
|
warnOnce2(
|
|
"Without `from` option PostCSS could generate wrong source map and will not find Browserslist config. Set it to CSS file path or to `undefined` to prevent this warning."
|
|
);
|
|
}
|
|
}
|
|
return this.async().then(onFulfilled, onRejected);
|
|
}
|
|
toString() {
|
|
return this.css;
|
|
}
|
|
visitSync(visitors, node2) {
|
|
for (let [plugin, visitor] of visitors) {
|
|
this.result.lastPlugin = plugin;
|
|
let promise;
|
|
try {
|
|
promise = visitor(node2, this.helpers);
|
|
} catch (e2) {
|
|
throw this.handleError(e2, node2.proxyOf);
|
|
}
|
|
if (node2.type !== "root" && node2.type !== "document" && !node2.parent) {
|
|
return true;
|
|
}
|
|
if (isPromise(promise)) {
|
|
throw this.getAsyncError();
|
|
}
|
|
}
|
|
}
|
|
visitTick(stack) {
|
|
let visit2 = stack[stack.length - 1];
|
|
let { node: node2, visitors } = visit2;
|
|
if (node2.type !== "root" && node2.type !== "document" && !node2.parent) {
|
|
stack.pop();
|
|
return;
|
|
}
|
|
if (visitors.length > 0 && visit2.visitorIndex < visitors.length) {
|
|
let [plugin, visitor] = visitors[visit2.visitorIndex];
|
|
visit2.visitorIndex += 1;
|
|
if (visit2.visitorIndex === visitors.length) {
|
|
visit2.visitors = [];
|
|
visit2.visitorIndex = 0;
|
|
}
|
|
this.result.lastPlugin = plugin;
|
|
try {
|
|
return visitor(node2.toProxy(), this.helpers);
|
|
} catch (e2) {
|
|
throw this.handleError(e2, node2);
|
|
}
|
|
}
|
|
if (visit2.iterator !== 0) {
|
|
let iterator = visit2.iterator;
|
|
let child;
|
|
while (child = node2.nodes[node2.indexes[iterator]]) {
|
|
node2.indexes[iterator] += 1;
|
|
if (!child[isClean]) {
|
|
child[isClean] = true;
|
|
stack.push(toStack(child));
|
|
return;
|
|
}
|
|
}
|
|
visit2.iterator = 0;
|
|
delete node2.indexes[iterator];
|
|
}
|
|
let events = visit2.events;
|
|
while (visit2.eventIndex < events.length) {
|
|
let event = events[visit2.eventIndex];
|
|
visit2.eventIndex += 1;
|
|
if (event === CHILDREN) {
|
|
if (node2.nodes && node2.nodes.length) {
|
|
node2[isClean] = true;
|
|
visit2.iterator = node2.getIterator();
|
|
}
|
|
return;
|
|
} else if (this.listeners[event]) {
|
|
visit2.visitors = this.listeners[event];
|
|
return;
|
|
}
|
|
}
|
|
stack.pop();
|
|
}
|
|
walkSync(node2) {
|
|
node2[isClean] = true;
|
|
let events = getEvents(node2);
|
|
for (let event of events) {
|
|
if (event === CHILDREN) {
|
|
if (node2.nodes) {
|
|
node2.each((child) => {
|
|
if (!child[isClean]) this.walkSync(child);
|
|
});
|
|
}
|
|
} else {
|
|
let visitors = this.listeners[event];
|
|
if (visitors) {
|
|
if (this.visitSync(visitors, node2.toProxy())) return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
warnings() {
|
|
return this.sync().warnings();
|
|
}
|
|
get content() {
|
|
return this.stringify().content;
|
|
}
|
|
get css() {
|
|
return this.stringify().css;
|
|
}
|
|
get map() {
|
|
return this.stringify().map;
|
|
}
|
|
get messages() {
|
|
return this.sync().messages;
|
|
}
|
|
get opts() {
|
|
return this.result.opts;
|
|
}
|
|
get processor() {
|
|
return this.result.processor;
|
|
}
|
|
get root() {
|
|
return this.sync().root;
|
|
}
|
|
get [Symbol.toStringTag]() {
|
|
return "LazyResult";
|
|
}
|
|
}
|
|
LazyResult.registerPostcss = (dependant) => {
|
|
postcss2 = dependant;
|
|
};
|
|
lazyResult = LazyResult;
|
|
LazyResult.default = LazyResult;
|
|
Root.registerLazyResult(LazyResult);
|
|
Document2.registerLazyResult(LazyResult);
|
|
return lazyResult;
|
|
}
|
|
var noWorkResult;
|
|
var hasRequiredNoWorkResult;
|
|
function requireNoWorkResult() {
|
|
if (hasRequiredNoWorkResult) return noWorkResult;
|
|
hasRequiredNoWorkResult = 1;
|
|
let MapGenerator = requireMapGenerator();
|
|
let stringify = requireStringify();
|
|
let warnOnce2 = requireWarnOnce();
|
|
let parse = requireParse();
|
|
const Result = requireResult();
|
|
class NoWorkResult {
|
|
constructor(processor2, css, opts) {
|
|
css = css.toString();
|
|
this.stringified = false;
|
|
this._processor = processor2;
|
|
this._css = css;
|
|
this._opts = opts;
|
|
this._map = void 0;
|
|
let root2;
|
|
let str = stringify;
|
|
this.result = new Result(this._processor, root2, this._opts);
|
|
this.result.css = css;
|
|
let self2 = this;
|
|
Object.defineProperty(this.result, "root", {
|
|
get() {
|
|
return self2.root;
|
|
}
|
|
});
|
|
let map = new MapGenerator(str, root2, this._opts, css);
|
|
if (map.isMap()) {
|
|
let [generatedCSS, generatedMap] = map.generate();
|
|
if (generatedCSS) {
|
|
this.result.css = generatedCSS;
|
|
}
|
|
if (generatedMap) {
|
|
this.result.map = generatedMap;
|
|
}
|
|
} else {
|
|
map.clearAnnotation();
|
|
this.result.css = map.css;
|
|
}
|
|
}
|
|
async() {
|
|
if (this.error) return Promise.reject(this.error);
|
|
return Promise.resolve(this.result);
|
|
}
|
|
catch(onRejected) {
|
|
return this.async().catch(onRejected);
|
|
}
|
|
finally(onFinally) {
|
|
return this.async().then(onFinally, onFinally);
|
|
}
|
|
sync() {
|
|
if (this.error) throw this.error;
|
|
return this.result;
|
|
}
|
|
then(onFulfilled, onRejected) {
|
|
if (true) {
|
|
if (!("from" in this._opts)) {
|
|
warnOnce2(
|
|
"Without `from` option PostCSS could generate wrong source map and will not find Browserslist config. Set it to CSS file path or to `undefined` to prevent this warning."
|
|
);
|
|
}
|
|
}
|
|
return this.async().then(onFulfilled, onRejected);
|
|
}
|
|
toString() {
|
|
return this._css;
|
|
}
|
|
warnings() {
|
|
return [];
|
|
}
|
|
get content() {
|
|
return this.result.css;
|
|
}
|
|
get css() {
|
|
return this.result.css;
|
|
}
|
|
get map() {
|
|
return this.result.map;
|
|
}
|
|
get messages() {
|
|
return [];
|
|
}
|
|
get opts() {
|
|
return this.result.opts;
|
|
}
|
|
get processor() {
|
|
return this.result.processor;
|
|
}
|
|
get root() {
|
|
if (this._root) {
|
|
return this._root;
|
|
}
|
|
let root2;
|
|
let parser2 = parse;
|
|
try {
|
|
root2 = parser2(this._css, this._opts);
|
|
} catch (error) {
|
|
this.error = error;
|
|
}
|
|
if (this.error) {
|
|
throw this.error;
|
|
} else {
|
|
this._root = root2;
|
|
return root2;
|
|
}
|
|
}
|
|
get [Symbol.toStringTag]() {
|
|
return "NoWorkResult";
|
|
}
|
|
}
|
|
noWorkResult = NoWorkResult;
|
|
NoWorkResult.default = NoWorkResult;
|
|
return noWorkResult;
|
|
}
|
|
var processor;
|
|
var hasRequiredProcessor;
|
|
function requireProcessor() {
|
|
if (hasRequiredProcessor) return processor;
|
|
hasRequiredProcessor = 1;
|
|
let NoWorkResult = requireNoWorkResult();
|
|
let LazyResult = requireLazyResult();
|
|
let Document2 = requireDocument();
|
|
let Root = requireRoot();
|
|
class Processor {
|
|
constructor(plugins = []) {
|
|
this.version = "8.4.38";
|
|
this.plugins = this.normalize(plugins);
|
|
}
|
|
normalize(plugins) {
|
|
let normalized = [];
|
|
for (let i2 of plugins) {
|
|
if (i2.postcss === true) {
|
|
i2 = i2();
|
|
} else if (i2.postcss) {
|
|
i2 = i2.postcss;
|
|
}
|
|
if (typeof i2 === "object" && Array.isArray(i2.plugins)) {
|
|
normalized = normalized.concat(i2.plugins);
|
|
} else if (typeof i2 === "object" && i2.postcssPlugin) {
|
|
normalized.push(i2);
|
|
} else if (typeof i2 === "function") {
|
|
normalized.push(i2);
|
|
} else if (typeof i2 === "object" && (i2.parse || i2.stringify)) {
|
|
if (true) {
|
|
throw new Error(
|
|
"PostCSS syntaxes cannot be used as plugins. Instead, please use one of the syntax/parser/stringifier options as outlined in your PostCSS runner documentation."
|
|
);
|
|
}
|
|
} else {
|
|
throw new Error(i2 + " is not a PostCSS plugin");
|
|
}
|
|
}
|
|
return normalized;
|
|
}
|
|
process(css, opts = {}) {
|
|
if (!this.plugins.length && !opts.parser && !opts.stringifier && !opts.syntax) {
|
|
return new NoWorkResult(this, css, opts);
|
|
} else {
|
|
return new LazyResult(this, css, opts);
|
|
}
|
|
}
|
|
use(plugin) {
|
|
this.plugins = this.plugins.concat(this.normalize([plugin]));
|
|
return this;
|
|
}
|
|
}
|
|
processor = Processor;
|
|
Processor.default = Processor;
|
|
Root.registerProcessor(Processor);
|
|
Document2.registerProcessor(Processor);
|
|
return processor;
|
|
}
|
|
var fromJSON_1;
|
|
var hasRequiredFromJSON;
|
|
function requireFromJSON() {
|
|
if (hasRequiredFromJSON) return fromJSON_1;
|
|
hasRequiredFromJSON = 1;
|
|
let Declaration = requireDeclaration();
|
|
let PreviousMap = requirePreviousMap();
|
|
let Comment = requireComment();
|
|
let AtRule = requireAtRule();
|
|
let Input = requireInput();
|
|
let Root = requireRoot();
|
|
let Rule = requireRule();
|
|
function fromJSON(json, inputs) {
|
|
if (Array.isArray(json)) return json.map((n2) => fromJSON(n2));
|
|
let _a2 = json, { inputs: ownInputs } = _a2, defaults = __objRest(_a2, ["inputs"]);
|
|
if (ownInputs) {
|
|
inputs = [];
|
|
for (let input2 of ownInputs) {
|
|
let inputHydrated = __spreadProps(__spreadValues({}, input2), { __proto__: Input.prototype });
|
|
if (inputHydrated.map) {
|
|
inputHydrated.map = __spreadProps(__spreadValues({}, inputHydrated.map), {
|
|
__proto__: PreviousMap.prototype
|
|
});
|
|
}
|
|
inputs.push(inputHydrated);
|
|
}
|
|
}
|
|
if (defaults.nodes) {
|
|
defaults.nodes = json.nodes.map((n2) => fromJSON(n2, inputs));
|
|
}
|
|
if (defaults.source) {
|
|
let _b = defaults.source, { inputId } = _b, source = __objRest(_b, ["inputId"]);
|
|
defaults.source = source;
|
|
if (inputId != null) {
|
|
defaults.source.input = inputs[inputId];
|
|
}
|
|
}
|
|
if (defaults.type === "root") {
|
|
return new Root(defaults);
|
|
} else if (defaults.type === "decl") {
|
|
return new Declaration(defaults);
|
|
} else if (defaults.type === "rule") {
|
|
return new Rule(defaults);
|
|
} else if (defaults.type === "comment") {
|
|
return new Comment(defaults);
|
|
} else if (defaults.type === "atrule") {
|
|
return new AtRule(defaults);
|
|
} else {
|
|
throw new Error("Unknown node type: " + json.type);
|
|
}
|
|
}
|
|
fromJSON_1 = fromJSON;
|
|
fromJSON.default = fromJSON;
|
|
return fromJSON_1;
|
|
}
|
|
var postcss_1;
|
|
var hasRequiredPostcss;
|
|
function requirePostcss() {
|
|
if (hasRequiredPostcss) return postcss_1;
|
|
hasRequiredPostcss = 1;
|
|
let CssSyntaxError = requireCssSyntaxError();
|
|
let Declaration = requireDeclaration();
|
|
let LazyResult = requireLazyResult();
|
|
let Container = requireContainer();
|
|
let Processor = requireProcessor();
|
|
let stringify = requireStringify();
|
|
let fromJSON = requireFromJSON();
|
|
let Document2 = requireDocument();
|
|
let Warning = requireWarning();
|
|
let Comment = requireComment();
|
|
let AtRule = requireAtRule();
|
|
let Result = requireResult();
|
|
let Input = requireInput();
|
|
let parse = requireParse();
|
|
let list = requireList();
|
|
let Rule = requireRule();
|
|
let Root = requireRoot();
|
|
let Node2 = requireNode();
|
|
function postcss2(...plugins) {
|
|
if (plugins.length === 1 && Array.isArray(plugins[0])) {
|
|
plugins = plugins[0];
|
|
}
|
|
return new Processor(plugins);
|
|
}
|
|
postcss2.plugin = function plugin(name, initializer) {
|
|
let warningPrinted = false;
|
|
function creator(...args) {
|
|
if (console && console.warn && !warningPrinted) {
|
|
warningPrinted = true;
|
|
console.warn(
|
|
name + ": postcss.plugin was deprecated. Migration guide:\nhttps://evilmartians.com/chronicles/postcss-8-plugin-migration"
|
|
);
|
|
if (process.env.LANG && process.env.LANG.startsWith("cn")) {
|
|
console.warn(
|
|
name + ": \u91CC\u9762 postcss.plugin \u88AB\u5F03\u7528. \u8FC1\u79FB\u6307\u5357:\nhttps://www.w3ctech.com/topic/2226"
|
|
);
|
|
}
|
|
}
|
|
let transformer = initializer(...args);
|
|
transformer.postcssPlugin = name;
|
|
transformer.postcssVersion = new Processor().version;
|
|
return transformer;
|
|
}
|
|
let cache;
|
|
Object.defineProperty(creator, "postcss", {
|
|
get() {
|
|
if (!cache) cache = creator();
|
|
return cache;
|
|
}
|
|
});
|
|
creator.process = function(css, processOpts, pluginOpts) {
|
|
return postcss2([creator(pluginOpts)]).process(css, processOpts);
|
|
};
|
|
return creator;
|
|
};
|
|
postcss2.stringify = stringify;
|
|
postcss2.parse = parse;
|
|
postcss2.fromJSON = fromJSON;
|
|
postcss2.list = list;
|
|
postcss2.comment = (defaults) => new Comment(defaults);
|
|
postcss2.atRule = (defaults) => new AtRule(defaults);
|
|
postcss2.decl = (defaults) => new Declaration(defaults);
|
|
postcss2.rule = (defaults) => new Rule(defaults);
|
|
postcss2.root = (defaults) => new Root(defaults);
|
|
postcss2.document = (defaults) => new Document2(defaults);
|
|
postcss2.CssSyntaxError = CssSyntaxError;
|
|
postcss2.Declaration = Declaration;
|
|
postcss2.Container = Container;
|
|
postcss2.Processor = Processor;
|
|
postcss2.Document = Document2;
|
|
postcss2.Comment = Comment;
|
|
postcss2.Warning = Warning;
|
|
postcss2.AtRule = AtRule;
|
|
postcss2.Result = Result;
|
|
postcss2.Input = Input;
|
|
postcss2.Rule = Rule;
|
|
postcss2.Root = Root;
|
|
postcss2.Node = Node2;
|
|
LazyResult.registerPostcss(postcss2);
|
|
postcss_1 = postcss2;
|
|
postcss2.default = postcss2;
|
|
return postcss_1;
|
|
}
|
|
var postcssExports = requirePostcss();
|
|
const postcss = /* @__PURE__ */ getDefaultExportFromCjs(postcssExports);
|
|
postcss.stringify;
|
|
postcss.fromJSON;
|
|
postcss.plugin;
|
|
postcss.parse;
|
|
postcss.list;
|
|
postcss.document;
|
|
postcss.comment;
|
|
postcss.atRule;
|
|
postcss.rule;
|
|
postcss.decl;
|
|
postcss.root;
|
|
postcss.CssSyntaxError;
|
|
postcss.Declaration;
|
|
postcss.Container;
|
|
postcss.Processor;
|
|
postcss.Document;
|
|
postcss.Comment;
|
|
postcss.Warning;
|
|
postcss.AtRule;
|
|
postcss.Result;
|
|
postcss.Input;
|
|
postcss.Rule;
|
|
postcss.Root;
|
|
postcss.Node;
|
|
class BaseRRNode {
|
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
constructor(..._args) {
|
|
__publicField2(this, "parentElement", null);
|
|
__publicField2(this, "parentNode", null);
|
|
__publicField2(this, "ownerDocument");
|
|
__publicField2(this, "firstChild", null);
|
|
__publicField2(this, "lastChild", null);
|
|
__publicField2(this, "previousSibling", null);
|
|
__publicField2(this, "nextSibling", null);
|
|
__publicField2(this, "ELEMENT_NODE", 1);
|
|
__publicField2(this, "TEXT_NODE", 3);
|
|
__publicField2(this, "nodeType");
|
|
__publicField2(this, "nodeName");
|
|
__publicField2(this, "RRNodeType");
|
|
}
|
|
get childNodes() {
|
|
const childNodes2 = [];
|
|
let childIterator = this.firstChild;
|
|
while (childIterator) {
|
|
childNodes2.push(childIterator);
|
|
childIterator = childIterator.nextSibling;
|
|
}
|
|
return childNodes2;
|
|
}
|
|
contains(node2) {
|
|
if (!(node2 instanceof BaseRRNode)) return false;
|
|
else if (node2.ownerDocument !== this.ownerDocument) return false;
|
|
else if (node2 === this) return true;
|
|
while (node2.parentNode) {
|
|
if (node2.parentNode === this) return true;
|
|
node2 = node2.parentNode;
|
|
}
|
|
return false;
|
|
}
|
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
appendChild(_newChild) {
|
|
throw new Error(
|
|
`RRDomException: Failed to execute 'appendChild' on 'RRNode': This RRNode type does not support this method.`
|
|
);
|
|
}
|
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
insertBefore(_newChild, _refChild) {
|
|
throw new Error(
|
|
`RRDomException: Failed to execute 'insertBefore' on 'RRNode': This RRNode type does not support this method.`
|
|
);
|
|
}
|
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
removeChild(_node) {
|
|
throw new Error(
|
|
`RRDomException: Failed to execute 'removeChild' on 'RRNode': This RRNode type does not support this method.`
|
|
);
|
|
}
|
|
toString() {
|
|
return "RRNode";
|
|
}
|
|
}
|
|
const testableAccessors = {
|
|
Node: [
|
|
"childNodes",
|
|
"parentNode",
|
|
"parentElement",
|
|
"textContent",
|
|
"ownerDocument"
|
|
],
|
|
ShadowRoot: ["host", "styleSheets"],
|
|
Element: ["shadowRoot", "querySelector", "querySelectorAll"],
|
|
MutationObserver: []
|
|
};
|
|
const testableMethods = {
|
|
Node: ["contains", "getRootNode"],
|
|
ShadowRoot: ["getSelection"],
|
|
Element: [],
|
|
MutationObserver: ["constructor"]
|
|
};
|
|
const untaintedBasePrototype = {};
|
|
const isAngularZonePresent = () => {
|
|
return !!globalThis.Zone;
|
|
};
|
|
function getUntaintedPrototype(key) {
|
|
if (untaintedBasePrototype[key])
|
|
return untaintedBasePrototype[key];
|
|
const defaultObj = globalThis[key];
|
|
const defaultPrototype = defaultObj.prototype;
|
|
const accessorNames = key in testableAccessors ? testableAccessors[key] : void 0;
|
|
const isUntaintedAccessors = Boolean(
|
|
accessorNames && // @ts-expect-error 2345
|
|
accessorNames.every(
|
|
(accessor) => {
|
|
var _a2, _b;
|
|
return Boolean(
|
|
(_b = (_a2 = Object.getOwnPropertyDescriptor(defaultPrototype, accessor)) == null ? void 0 : _a2.get) == null ? void 0 : _b.toString().includes("[native code]")
|
|
);
|
|
}
|
|
)
|
|
);
|
|
const methodNames = key in testableMethods ? testableMethods[key] : void 0;
|
|
const isUntaintedMethods = Boolean(
|
|
methodNames && methodNames.every(
|
|
// @ts-expect-error 2345
|
|
(method) => {
|
|
var _a2;
|
|
return typeof defaultPrototype[method] === "function" && ((_a2 = defaultPrototype[method]) == null ? void 0 : _a2.toString().includes("[native code]"));
|
|
}
|
|
)
|
|
);
|
|
if (isUntaintedAccessors && isUntaintedMethods && !isAngularZonePresent()) {
|
|
untaintedBasePrototype[key] = defaultObj.prototype;
|
|
return defaultObj.prototype;
|
|
}
|
|
try {
|
|
const iframeEl = document.createElement("iframe");
|
|
document.body.appendChild(iframeEl);
|
|
const win = iframeEl.contentWindow;
|
|
if (!win) return defaultObj.prototype;
|
|
const untaintedObject = win[key].prototype;
|
|
document.body.removeChild(iframeEl);
|
|
if (!untaintedObject) return defaultPrototype;
|
|
return untaintedBasePrototype[key] = untaintedObject;
|
|
} catch (e) {
|
|
return defaultPrototype;
|
|
}
|
|
}
|
|
const untaintedAccessorCache = {};
|
|
function getUntaintedAccessor(key, instance, accessor) {
|
|
var _a2;
|
|
const cacheKey = `${key}.${String(accessor)}`;
|
|
if (untaintedAccessorCache[cacheKey])
|
|
return untaintedAccessorCache[cacheKey].call(
|
|
instance
|
|
);
|
|
const untaintedPrototype = getUntaintedPrototype(key);
|
|
const untaintedAccessor = (_a2 = Object.getOwnPropertyDescriptor(
|
|
untaintedPrototype,
|
|
accessor
|
|
)) == null ? void 0 : _a2.get;
|
|
if (!untaintedAccessor) return instance[accessor];
|
|
untaintedAccessorCache[cacheKey] = untaintedAccessor;
|
|
return untaintedAccessor.call(instance);
|
|
}
|
|
const untaintedMethodCache = {};
|
|
function getUntaintedMethod(key, instance, method) {
|
|
const cacheKey = `${key}.${String(method)}`;
|
|
if (untaintedMethodCache[cacheKey])
|
|
return untaintedMethodCache[cacheKey].bind(
|
|
instance
|
|
);
|
|
const untaintedPrototype = getUntaintedPrototype(key);
|
|
const untaintedMethod = untaintedPrototype[method];
|
|
if (typeof untaintedMethod !== "function") return instance[method];
|
|
untaintedMethodCache[cacheKey] = untaintedMethod;
|
|
return untaintedMethod.bind(instance);
|
|
}
|
|
function ownerDocument(n2) {
|
|
return getUntaintedAccessor("Node", n2, "ownerDocument");
|
|
}
|
|
function childNodes(n2) {
|
|
return getUntaintedAccessor("Node", n2, "childNodes");
|
|
}
|
|
function parentNode(n2) {
|
|
return getUntaintedAccessor("Node", n2, "parentNode");
|
|
}
|
|
function parentElement(n2) {
|
|
return getUntaintedAccessor("Node", n2, "parentElement");
|
|
}
|
|
function textContent(n2) {
|
|
return getUntaintedAccessor("Node", n2, "textContent");
|
|
}
|
|
function contains(n2, other) {
|
|
return getUntaintedMethod("Node", n2, "contains")(other);
|
|
}
|
|
function getRootNode(n2) {
|
|
return getUntaintedMethod("Node", n2, "getRootNode")();
|
|
}
|
|
function host(n2) {
|
|
if (!n2 || !("host" in n2)) return null;
|
|
return getUntaintedAccessor("ShadowRoot", n2, "host");
|
|
}
|
|
function styleSheets(n2) {
|
|
return n2.styleSheets;
|
|
}
|
|
function shadowRoot(n2) {
|
|
if (!n2 || !("shadowRoot" in n2)) return null;
|
|
return getUntaintedAccessor("Element", n2, "shadowRoot");
|
|
}
|
|
function querySelector(n2, selectors) {
|
|
return getUntaintedAccessor("Element", n2, "querySelector")(selectors);
|
|
}
|
|
function querySelectorAll(n2, selectors) {
|
|
return getUntaintedAccessor("Element", n2, "querySelectorAll")(selectors);
|
|
}
|
|
function mutationObserverCtor() {
|
|
return getUntaintedPrototype("MutationObserver").constructor;
|
|
}
|
|
function patch(source, name, replacement) {
|
|
try {
|
|
if (!(name in source)) {
|
|
return () => {
|
|
};
|
|
}
|
|
const original = source[name];
|
|
const wrapped = replacement(original);
|
|
if (typeof wrapped === "function") {
|
|
wrapped.prototype = wrapped.prototype || {};
|
|
Object.defineProperties(wrapped, {
|
|
__rrweb_original__: {
|
|
enumerable: false,
|
|
value: original
|
|
}
|
|
});
|
|
}
|
|
source[name] = wrapped;
|
|
return () => {
|
|
source[name] = original;
|
|
};
|
|
} catch (e) {
|
|
return () => {
|
|
};
|
|
}
|
|
}
|
|
const index = {
|
|
ownerDocument,
|
|
childNodes,
|
|
parentNode,
|
|
parentElement,
|
|
textContent,
|
|
contains,
|
|
getRootNode,
|
|
host,
|
|
styleSheets,
|
|
shadowRoot,
|
|
querySelector,
|
|
querySelectorAll,
|
|
mutationObserver: mutationObserverCtor,
|
|
patch
|
|
};
|
|
function on(type, fn, target = document) {
|
|
const options = { capture: true, passive: true };
|
|
target.addEventListener(type, fn, options);
|
|
return () => target.removeEventListener(type, fn, options);
|
|
}
|
|
const DEPARTED_MIRROR_ACCESS_WARNING = "Please stop import mirror directly. Instead of that,\r\nnow you can use replayer.getMirror() to access the mirror instance of a replayer,\r\nor you can use record.mirror to access the mirror instance during recording.";
|
|
let _mirror = {
|
|
map: {},
|
|
getId() {
|
|
console.error(DEPARTED_MIRROR_ACCESS_WARNING);
|
|
return -1;
|
|
},
|
|
getNode() {
|
|
console.error(DEPARTED_MIRROR_ACCESS_WARNING);
|
|
return null;
|
|
},
|
|
removeNodeFromMap() {
|
|
console.error(DEPARTED_MIRROR_ACCESS_WARNING);
|
|
},
|
|
has() {
|
|
console.error(DEPARTED_MIRROR_ACCESS_WARNING);
|
|
return false;
|
|
},
|
|
reset() {
|
|
console.error(DEPARTED_MIRROR_ACCESS_WARNING);
|
|
}
|
|
};
|
|
if (typeof window !== "undefined" && window.Proxy && window.Reflect) {
|
|
_mirror = new Proxy(_mirror, {
|
|
get(target, prop, receiver) {
|
|
if (prop === "map") {
|
|
console.error(DEPARTED_MIRROR_ACCESS_WARNING);
|
|
}
|
|
return Reflect.get(target, prop, receiver);
|
|
}
|
|
});
|
|
}
|
|
function throttle(func, wait, options = {}) {
|
|
let timeout = null;
|
|
let previous = 0;
|
|
return function(...args) {
|
|
const now = Date.now();
|
|
if (!previous && options.leading === false) {
|
|
previous = now;
|
|
}
|
|
const remaining = wait - (now - previous);
|
|
const context = this;
|
|
if (remaining <= 0 || remaining > wait) {
|
|
if (timeout) {
|
|
clearTimeout(timeout);
|
|
timeout = null;
|
|
}
|
|
previous = now;
|
|
func.apply(context, args);
|
|
} else if (!timeout && options.trailing !== false) {
|
|
timeout = setTimeout(() => {
|
|
previous = options.leading === false ? 0 : Date.now();
|
|
timeout = null;
|
|
func.apply(context, args);
|
|
}, remaining);
|
|
}
|
|
};
|
|
}
|
|
function hookSetter(target, key, d, isRevoked, win = window) {
|
|
const original = win.Object.getOwnPropertyDescriptor(target, key);
|
|
win.Object.defineProperty(
|
|
target,
|
|
key,
|
|
isRevoked ? d : {
|
|
set(value) {
|
|
setTimeout(() => {
|
|
d.set.call(this, value);
|
|
}, 0);
|
|
if (original && original.set) {
|
|
original.set.call(this, value);
|
|
}
|
|
}
|
|
}
|
|
);
|
|
return () => hookSetter(target, key, original || {}, true);
|
|
}
|
|
let nowTimestamp = Date.now;
|
|
if (!/* @__PURE__ */ /[1-9][0-9]{12}/.test(Date.now().toString())) {
|
|
nowTimestamp = () => (/* @__PURE__ */ new Date()).getTime();
|
|
}
|
|
function getWindowScroll(win) {
|
|
var _a2, _b, _c, _d;
|
|
const doc = win.document;
|
|
return {
|
|
left: doc.scrollingElement ? doc.scrollingElement.scrollLeft : win.pageXOffset !== void 0 ? win.pageXOffset : doc.documentElement.scrollLeft || (doc == null ? void 0 : doc.body) && ((_a2 = index.parentElement(doc.body)) == null ? void 0 : _a2.scrollLeft) || ((_b = doc == null ? void 0 : doc.body) == null ? void 0 : _b.scrollLeft) || 0,
|
|
top: doc.scrollingElement ? doc.scrollingElement.scrollTop : win.pageYOffset !== void 0 ? win.pageYOffset : (doc == null ? void 0 : doc.documentElement.scrollTop) || (doc == null ? void 0 : doc.body) && ((_c = index.parentElement(doc.body)) == null ? void 0 : _c.scrollTop) || ((_d = doc == null ? void 0 : doc.body) == null ? void 0 : _d.scrollTop) || 0
|
|
};
|
|
}
|
|
function getWindowHeight() {
|
|
return window.innerHeight || document.documentElement && document.documentElement.clientHeight || document.body && document.body.clientHeight;
|
|
}
|
|
function getWindowWidth() {
|
|
return window.innerWidth || document.documentElement && document.documentElement.clientWidth || document.body && document.body.clientWidth;
|
|
}
|
|
function closestElementOfNode(node2) {
|
|
if (!node2) {
|
|
return null;
|
|
}
|
|
const el = node2.nodeType === node2.ELEMENT_NODE ? node2 : index.parentElement(node2);
|
|
return el;
|
|
}
|
|
function isBlocked(node2, blockClass, blockSelector, checkAncestors) {
|
|
if (!node2) {
|
|
return false;
|
|
}
|
|
const el = closestElementOfNode(node2);
|
|
if (!el) {
|
|
return false;
|
|
}
|
|
try {
|
|
if (typeof blockClass === "string") {
|
|
if (el.classList.contains(blockClass)) return true;
|
|
if (checkAncestors && el.closest("." + blockClass) !== null) return true;
|
|
} else {
|
|
if (classMatchesRegex(el, blockClass, checkAncestors)) return true;
|
|
}
|
|
} catch (e2) {
|
|
}
|
|
if (blockSelector) {
|
|
if (el.matches(blockSelector)) return true;
|
|
if (checkAncestors && el.closest(blockSelector) !== null) return true;
|
|
}
|
|
return false;
|
|
}
|
|
function isSerialized(n2, mirror2) {
|
|
return mirror2.getId(n2) !== -1;
|
|
}
|
|
function isIgnored(n2, mirror2, slimDOMOptions) {
|
|
if (n2.tagName === "TITLE" && slimDOMOptions.headTitleMutations) {
|
|
return true;
|
|
}
|
|
return mirror2.getId(n2) === IGNORED_NODE;
|
|
}
|
|
function isAncestorRemoved(target, mirror2) {
|
|
if (isShadowRoot(target)) {
|
|
return false;
|
|
}
|
|
const id = mirror2.getId(target);
|
|
if (!mirror2.has(id)) {
|
|
return true;
|
|
}
|
|
const parent = index.parentNode(target);
|
|
if (parent && parent.nodeType === target.DOCUMENT_NODE) {
|
|
return false;
|
|
}
|
|
if (!parent) {
|
|
return true;
|
|
}
|
|
return isAncestorRemoved(parent, mirror2);
|
|
}
|
|
function legacy_isTouchEvent(event) {
|
|
return Boolean(event.changedTouches);
|
|
}
|
|
function polyfill$1(win = window) {
|
|
if ("NodeList" in win && !win.NodeList.prototype.forEach) {
|
|
win.NodeList.prototype.forEach = Array.prototype.forEach;
|
|
}
|
|
if ("DOMTokenList" in win && !win.DOMTokenList.prototype.forEach) {
|
|
win.DOMTokenList.prototype.forEach = Array.prototype.forEach;
|
|
}
|
|
}
|
|
function isSerializedIframe(n2, mirror2) {
|
|
return Boolean(n2.nodeName === "IFRAME" && mirror2.getMeta(n2));
|
|
}
|
|
function isSerializedStylesheet(n2, mirror2) {
|
|
return Boolean(
|
|
n2.nodeName === "LINK" && n2.nodeType === n2.ELEMENT_NODE && n2.getAttribute && n2.getAttribute("rel") === "stylesheet" && mirror2.getMeta(n2)
|
|
);
|
|
}
|
|
function hasShadowRoot(n2) {
|
|
if (!n2) return false;
|
|
if (n2 instanceof BaseRRNode && "shadowRoot" in n2) {
|
|
return Boolean(n2.shadowRoot);
|
|
}
|
|
return Boolean(index.shadowRoot(n2));
|
|
}
|
|
class StyleSheetMirror {
|
|
constructor() {
|
|
__publicField(this, "id", 1);
|
|
__publicField(this, "styleIDMap", /* @__PURE__ */ new WeakMap());
|
|
__publicField(this, "idStyleMap", /* @__PURE__ */ new Map());
|
|
}
|
|
getId(stylesheet) {
|
|
var _a2;
|
|
return (_a2 = this.styleIDMap.get(stylesheet)) != null ? _a2 : -1;
|
|
}
|
|
has(stylesheet) {
|
|
return this.styleIDMap.has(stylesheet);
|
|
}
|
|
/**
|
|
* @returns If the stylesheet is in the mirror, returns the id of the stylesheet. If not, return the new assigned id.
|
|
*/
|
|
add(stylesheet, id) {
|
|
if (this.has(stylesheet)) return this.getId(stylesheet);
|
|
let newId;
|
|
if (id === void 0) {
|
|
newId = this.id++;
|
|
} else newId = id;
|
|
this.styleIDMap.set(stylesheet, newId);
|
|
this.idStyleMap.set(newId, stylesheet);
|
|
return newId;
|
|
}
|
|
getStyle(id) {
|
|
return this.idStyleMap.get(id) || null;
|
|
}
|
|
reset() {
|
|
this.styleIDMap = /* @__PURE__ */ new WeakMap();
|
|
this.idStyleMap = /* @__PURE__ */ new Map();
|
|
this.id = 1;
|
|
}
|
|
generateId() {
|
|
return this.id++;
|
|
}
|
|
}
|
|
function getShadowHost(n2) {
|
|
var _a2;
|
|
let shadowHost = null;
|
|
if ("getRootNode" in n2 && ((_a2 = index.getRootNode(n2)) == null ? void 0 : _a2.nodeType) === Node.DOCUMENT_FRAGMENT_NODE && index.host(index.getRootNode(n2)))
|
|
shadowHost = index.host(index.getRootNode(n2));
|
|
return shadowHost;
|
|
}
|
|
function getRootShadowHost(n2) {
|
|
let rootShadowHost = n2;
|
|
let shadowHost;
|
|
while (shadowHost = getShadowHost(rootShadowHost))
|
|
rootShadowHost = shadowHost;
|
|
return rootShadowHost;
|
|
}
|
|
function shadowHostInDom(n2) {
|
|
const doc = index.ownerDocument(n2);
|
|
if (!doc) return false;
|
|
const shadowHost = getRootShadowHost(n2);
|
|
return index.contains(doc, shadowHost);
|
|
}
|
|
function inDom(n2) {
|
|
const doc = index.ownerDocument(n2);
|
|
if (!doc) return false;
|
|
return index.contains(doc, n2) || shadowHostInDom(n2);
|
|
}
|
|
var EventType = /* @__PURE__ */ ((EventType2) => {
|
|
EventType2[EventType2["DomContentLoaded"] = 0] = "DomContentLoaded";
|
|
EventType2[EventType2["Load"] = 1] = "Load";
|
|
EventType2[EventType2["FullSnapshot"] = 2] = "FullSnapshot";
|
|
EventType2[EventType2["IncrementalSnapshot"] = 3] = "IncrementalSnapshot";
|
|
EventType2[EventType2["Meta"] = 4] = "Meta";
|
|
EventType2[EventType2["Custom"] = 5] = "Custom";
|
|
EventType2[EventType2["Plugin"] = 6] = "Plugin";
|
|
return EventType2;
|
|
})(EventType || {});
|
|
var IncrementalSource = /* @__PURE__ */ ((IncrementalSource2) => {
|
|
IncrementalSource2[IncrementalSource2["Mutation"] = 0] = "Mutation";
|
|
IncrementalSource2[IncrementalSource2["MouseMove"] = 1] = "MouseMove";
|
|
IncrementalSource2[IncrementalSource2["MouseInteraction"] = 2] = "MouseInteraction";
|
|
IncrementalSource2[IncrementalSource2["Scroll"] = 3] = "Scroll";
|
|
IncrementalSource2[IncrementalSource2["ViewportResize"] = 4] = "ViewportResize";
|
|
IncrementalSource2[IncrementalSource2["Input"] = 5] = "Input";
|
|
IncrementalSource2[IncrementalSource2["TouchMove"] = 6] = "TouchMove";
|
|
IncrementalSource2[IncrementalSource2["MediaInteraction"] = 7] = "MediaInteraction";
|
|
IncrementalSource2[IncrementalSource2["StyleSheetRule"] = 8] = "StyleSheetRule";
|
|
IncrementalSource2[IncrementalSource2["CanvasMutation"] = 9] = "CanvasMutation";
|
|
IncrementalSource2[IncrementalSource2["Font"] = 10] = "Font";
|
|
IncrementalSource2[IncrementalSource2["Log"] = 11] = "Log";
|
|
IncrementalSource2[IncrementalSource2["Drag"] = 12] = "Drag";
|
|
IncrementalSource2[IncrementalSource2["StyleDeclaration"] = 13] = "StyleDeclaration";
|
|
IncrementalSource2[IncrementalSource2["Selection"] = 14] = "Selection";
|
|
IncrementalSource2[IncrementalSource2["AdoptedStyleSheet"] = 15] = "AdoptedStyleSheet";
|
|
IncrementalSource2[IncrementalSource2["CustomElement"] = 16] = "CustomElement";
|
|
return IncrementalSource2;
|
|
})(IncrementalSource || {});
|
|
var MouseInteractions = /* @__PURE__ */ ((MouseInteractions2) => {
|
|
MouseInteractions2[MouseInteractions2["MouseUp"] = 0] = "MouseUp";
|
|
MouseInteractions2[MouseInteractions2["MouseDown"] = 1] = "MouseDown";
|
|
MouseInteractions2[MouseInteractions2["Click"] = 2] = "Click";
|
|
MouseInteractions2[MouseInteractions2["ContextMenu"] = 3] = "ContextMenu";
|
|
MouseInteractions2[MouseInteractions2["DblClick"] = 4] = "DblClick";
|
|
MouseInteractions2[MouseInteractions2["Focus"] = 5] = "Focus";
|
|
MouseInteractions2[MouseInteractions2["Blur"] = 6] = "Blur";
|
|
MouseInteractions2[MouseInteractions2["TouchStart"] = 7] = "TouchStart";
|
|
MouseInteractions2[MouseInteractions2["TouchMove_Departed"] = 8] = "TouchMove_Departed";
|
|
MouseInteractions2[MouseInteractions2["TouchEnd"] = 9] = "TouchEnd";
|
|
MouseInteractions2[MouseInteractions2["TouchCancel"] = 10] = "TouchCancel";
|
|
return MouseInteractions2;
|
|
})(MouseInteractions || {});
|
|
var PointerTypes = /* @__PURE__ */ ((PointerTypes2) => {
|
|
PointerTypes2[PointerTypes2["Mouse"] = 0] = "Mouse";
|
|
PointerTypes2[PointerTypes2["Pen"] = 1] = "Pen";
|
|
PointerTypes2[PointerTypes2["Touch"] = 2] = "Touch";
|
|
return PointerTypes2;
|
|
})(PointerTypes || {});
|
|
var CanvasContext = /* @__PURE__ */ ((CanvasContext2) => {
|
|
CanvasContext2[CanvasContext2["2D"] = 0] = "2D";
|
|
CanvasContext2[CanvasContext2["WebGL"] = 1] = "WebGL";
|
|
CanvasContext2[CanvasContext2["WebGL2"] = 2] = "WebGL2";
|
|
return CanvasContext2;
|
|
})(CanvasContext || {});
|
|
var MediaInteractions = /* @__PURE__ */ ((MediaInteractions2) => {
|
|
MediaInteractions2[MediaInteractions2["Play"] = 0] = "Play";
|
|
MediaInteractions2[MediaInteractions2["Pause"] = 1] = "Pause";
|
|
MediaInteractions2[MediaInteractions2["Seeked"] = 2] = "Seeked";
|
|
MediaInteractions2[MediaInteractions2["VolumeChange"] = 3] = "VolumeChange";
|
|
MediaInteractions2[MediaInteractions2["RateChange"] = 4] = "RateChange";
|
|
return MediaInteractions2;
|
|
})(MediaInteractions || {});
|
|
var NodeType = /* @__PURE__ */ ((NodeType2) => {
|
|
NodeType2[NodeType2["Document"] = 0] = "Document";
|
|
NodeType2[NodeType2["DocumentType"] = 1] = "DocumentType";
|
|
NodeType2[NodeType2["Element"] = 2] = "Element";
|
|
NodeType2[NodeType2["Text"] = 3] = "Text";
|
|
NodeType2[NodeType2["CDATA"] = 4] = "CDATA";
|
|
NodeType2[NodeType2["Comment"] = 5] = "Comment";
|
|
return NodeType2;
|
|
})(NodeType || {});
|
|
function isNodeInLinkedList(n2) {
|
|
return "__ln" in n2;
|
|
}
|
|
class DoubleLinkedList {
|
|
constructor() {
|
|
__publicField(this, "length", 0);
|
|
__publicField(this, "head", null);
|
|
__publicField(this, "tail", null);
|
|
}
|
|
get(position) {
|
|
if (position >= this.length) {
|
|
throw new Error("Position outside of list range");
|
|
}
|
|
let current = this.head;
|
|
for (let index2 = 0; index2 < position; index2++) {
|
|
current = (current == null ? void 0 : current.next) || null;
|
|
}
|
|
return current;
|
|
}
|
|
addNode(n2) {
|
|
const node2 = {
|
|
value: n2,
|
|
previous: null,
|
|
next: null
|
|
};
|
|
n2.__ln = node2;
|
|
if (n2.previousSibling && isNodeInLinkedList(n2.previousSibling)) {
|
|
const current = n2.previousSibling.__ln.next;
|
|
node2.next = current;
|
|
node2.previous = n2.previousSibling.__ln;
|
|
n2.previousSibling.__ln.next = node2;
|
|
if (current) {
|
|
current.previous = node2;
|
|
}
|
|
} else if (n2.nextSibling && isNodeInLinkedList(n2.nextSibling) && n2.nextSibling.__ln.previous) {
|
|
const current = n2.nextSibling.__ln.previous;
|
|
node2.previous = current;
|
|
node2.next = n2.nextSibling.__ln;
|
|
n2.nextSibling.__ln.previous = node2;
|
|
if (current) {
|
|
current.next = node2;
|
|
}
|
|
} else {
|
|
if (this.head) {
|
|
this.head.previous = node2;
|
|
}
|
|
node2.next = this.head;
|
|
this.head = node2;
|
|
}
|
|
if (node2.next === null) {
|
|
this.tail = node2;
|
|
}
|
|
this.length++;
|
|
}
|
|
removeNode(n2) {
|
|
const current = n2.__ln;
|
|
if (!this.head) {
|
|
return;
|
|
}
|
|
if (!current.previous) {
|
|
this.head = current.next;
|
|
if (this.head) {
|
|
this.head.previous = null;
|
|
} else {
|
|
this.tail = null;
|
|
}
|
|
} else {
|
|
current.previous.next = current.next;
|
|
if (current.next) {
|
|
current.next.previous = current.previous;
|
|
} else {
|
|
this.tail = current.previous;
|
|
}
|
|
}
|
|
if (n2.__ln) {
|
|
delete n2.__ln;
|
|
}
|
|
this.length--;
|
|
}
|
|
}
|
|
const moveKey = (id, parentId) => `${id}@${parentId}`;
|
|
class MutationBuffer {
|
|
constructor() {
|
|
__publicField(this, "frozen", false);
|
|
__publicField(this, "locked", false);
|
|
__publicField(this, "texts", []);
|
|
__publicField(this, "attributes", []);
|
|
__publicField(this, "attributeMap", /* @__PURE__ */ new WeakMap());
|
|
__publicField(this, "removes", []);
|
|
__publicField(this, "mapRemoves", []);
|
|
__publicField(this, "movedMap", {});
|
|
__publicField(this, "addedSet", /* @__PURE__ */ new Set());
|
|
__publicField(this, "movedSet", /* @__PURE__ */ new Set());
|
|
__publicField(this, "droppedSet", /* @__PURE__ */ new Set());
|
|
__publicField(this, "removesSubTreeCache", /* @__PURE__ */ new Set());
|
|
__publicField(this, "mutationCb");
|
|
__publicField(this, "blockClass");
|
|
__publicField(this, "blockSelector");
|
|
__publicField(this, "maskTextClass");
|
|
__publicField(this, "maskTextSelector");
|
|
__publicField(this, "inlineStylesheet");
|
|
__publicField(this, "maskInputOptions");
|
|
__publicField(this, "maskTextFn");
|
|
__publicField(this, "maskInputFn");
|
|
__publicField(this, "keepIframeSrcFn");
|
|
__publicField(this, "recordCanvas");
|
|
__publicField(this, "inlineImages");
|
|
__publicField(this, "slimDOMOptions");
|
|
__publicField(this, "dataURLOptions");
|
|
__publicField(this, "doc");
|
|
__publicField(this, "mirror");
|
|
__publicField(this, "iframeManager");
|
|
__publicField(this, "stylesheetManager");
|
|
__publicField(this, "shadowDomManager");
|
|
__publicField(this, "canvasManager");
|
|
__publicField(this, "processedNodeManager");
|
|
__publicField(this, "unattachedDoc");
|
|
__publicField(this, "processMutations", (mutations) => {
|
|
mutations.forEach(this.processMutation);
|
|
this.emit();
|
|
});
|
|
__publicField(this, "emit", () => {
|
|
if (this.frozen || this.locked) {
|
|
return;
|
|
}
|
|
const adds = [];
|
|
const addedIds = /* @__PURE__ */ new Set();
|
|
const addList = new DoubleLinkedList();
|
|
const getNextId = (n2) => {
|
|
let ns = n2;
|
|
let nextId = IGNORED_NODE;
|
|
while (nextId === IGNORED_NODE) {
|
|
ns = ns && ns.nextSibling;
|
|
nextId = ns && this.mirror.getId(ns);
|
|
}
|
|
return nextId;
|
|
};
|
|
const pushAdd = (n2) => {
|
|
const parent = index.parentNode(n2);
|
|
if (!parent || !inDom(n2)) {
|
|
return;
|
|
}
|
|
let cssCaptured = false;
|
|
if (n2.nodeType === Node.TEXT_NODE) {
|
|
const parentTag = parent.tagName;
|
|
if (parentTag === "TEXTAREA") {
|
|
return;
|
|
} else if (parentTag === "STYLE" && this.addedSet.has(parent)) {
|
|
cssCaptured = true;
|
|
}
|
|
}
|
|
const parentId = isShadowRoot(parent) ? this.mirror.getId(getShadowHost(n2)) : this.mirror.getId(parent);
|
|
const nextId = getNextId(n2);
|
|
if (parentId === -1 || nextId === -1) {
|
|
return addList.addNode(n2);
|
|
}
|
|
const sn = serializeNodeWithId(n2, {
|
|
doc: this.doc,
|
|
mirror: this.mirror,
|
|
blockClass: this.blockClass,
|
|
blockSelector: this.blockSelector,
|
|
maskTextClass: this.maskTextClass,
|
|
maskTextSelector: this.maskTextSelector,
|
|
skipChild: true,
|
|
newlyAddedElement: true,
|
|
inlineStylesheet: this.inlineStylesheet,
|
|
maskInputOptions: this.maskInputOptions,
|
|
maskTextFn: this.maskTextFn,
|
|
maskInputFn: this.maskInputFn,
|
|
slimDOMOptions: this.slimDOMOptions,
|
|
dataURLOptions: this.dataURLOptions,
|
|
recordCanvas: this.recordCanvas,
|
|
inlineImages: this.inlineImages,
|
|
onSerialize: (currentN) => {
|
|
if (isSerializedIframe(currentN, this.mirror)) {
|
|
this.iframeManager.addIframe(currentN);
|
|
}
|
|
if (isSerializedStylesheet(currentN, this.mirror)) {
|
|
this.stylesheetManager.trackLinkElement(
|
|
currentN
|
|
);
|
|
}
|
|
if (hasShadowRoot(n2)) {
|
|
this.shadowDomManager.addShadowRoot(index.shadowRoot(n2), this.doc);
|
|
}
|
|
},
|
|
onIframeLoad: (iframe, childSn) => {
|
|
this.iframeManager.attachIframe(iframe, childSn);
|
|
this.shadowDomManager.observeAttachShadow(iframe);
|
|
},
|
|
onStylesheetLoad: (link, childSn) => {
|
|
this.stylesheetManager.attachLinkElement(link, childSn);
|
|
},
|
|
cssCaptured
|
|
});
|
|
if (sn) {
|
|
adds.push({
|
|
parentId,
|
|
nextId,
|
|
node: sn
|
|
});
|
|
addedIds.add(sn.id);
|
|
}
|
|
};
|
|
while (this.mapRemoves.length) {
|
|
this.mirror.removeNodeFromMap(this.mapRemoves.shift());
|
|
}
|
|
for (const n2 of this.movedSet) {
|
|
if (isParentRemoved(this.removesSubTreeCache, n2, this.mirror) && !this.movedSet.has(index.parentNode(n2))) {
|
|
continue;
|
|
}
|
|
pushAdd(n2);
|
|
}
|
|
for (const n2 of this.addedSet) {
|
|
if (!isAncestorInSet(this.droppedSet, n2) && !isParentRemoved(this.removesSubTreeCache, n2, this.mirror)) {
|
|
pushAdd(n2);
|
|
} else if (isAncestorInSet(this.movedSet, n2)) {
|
|
pushAdd(n2);
|
|
} else {
|
|
this.droppedSet.add(n2);
|
|
}
|
|
}
|
|
let candidate = null;
|
|
while (addList.length) {
|
|
let node2 = null;
|
|
if (candidate) {
|
|
const parentId = this.mirror.getId(index.parentNode(candidate.value));
|
|
const nextId = getNextId(candidate.value);
|
|
if (parentId !== -1 && nextId !== -1) {
|
|
node2 = candidate;
|
|
}
|
|
}
|
|
if (!node2) {
|
|
let tailNode = addList.tail;
|
|
while (tailNode) {
|
|
const _node = tailNode;
|
|
tailNode = tailNode.previous;
|
|
if (_node) {
|
|
const parentId = this.mirror.getId(index.parentNode(_node.value));
|
|
const nextId = getNextId(_node.value);
|
|
if (nextId === -1) continue;
|
|
else if (parentId !== -1) {
|
|
node2 = _node;
|
|
break;
|
|
} else {
|
|
const unhandledNode = _node.value;
|
|
const parent = index.parentNode(unhandledNode);
|
|
if (parent && parent.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
|
|
const shadowHost = index.host(parent);
|
|
const parentId2 = this.mirror.getId(shadowHost);
|
|
if (parentId2 !== -1) {
|
|
node2 = _node;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!node2) {
|
|
while (addList.head) {
|
|
addList.removeNode(addList.head.value);
|
|
}
|
|
break;
|
|
}
|
|
candidate = node2.previous;
|
|
addList.removeNode(node2.value);
|
|
pushAdd(node2.value);
|
|
}
|
|
const payload = {
|
|
texts: this.texts.map((text) => {
|
|
const n2 = text.node;
|
|
const parent = index.parentNode(n2);
|
|
if (parent && parent.tagName === "TEXTAREA") {
|
|
this.genTextAreaValueMutation(parent);
|
|
}
|
|
return {
|
|
id: this.mirror.getId(n2),
|
|
value: text.value
|
|
};
|
|
}).filter((text) => !addedIds.has(text.id)).filter((text) => this.mirror.has(text.id)),
|
|
attributes: this.attributes.map((attribute) => {
|
|
const { attributes } = attribute;
|
|
if (typeof attributes.style === "string") {
|
|
const diffAsStr = JSON.stringify(attribute.styleDiff);
|
|
const unchangedAsStr = JSON.stringify(attribute._unchangedStyles);
|
|
if (diffAsStr.length < attributes.style.length) {
|
|
if ((diffAsStr + unchangedAsStr).split("var(").length === attributes.style.split("var(").length) {
|
|
attributes.style = attribute.styleDiff;
|
|
}
|
|
}
|
|
}
|
|
return {
|
|
id: this.mirror.getId(attribute.node),
|
|
attributes
|
|
};
|
|
}).filter((attribute) => !addedIds.has(attribute.id)).filter((attribute) => this.mirror.has(attribute.id)),
|
|
removes: this.removes,
|
|
adds
|
|
};
|
|
if (!payload.texts.length && !payload.attributes.length && !payload.removes.length && !payload.adds.length) {
|
|
return;
|
|
}
|
|
this.texts = [];
|
|
this.attributes = [];
|
|
this.attributeMap = /* @__PURE__ */ new WeakMap();
|
|
this.removes = [];
|
|
this.addedSet = /* @__PURE__ */ new Set();
|
|
this.movedSet = /* @__PURE__ */ new Set();
|
|
this.droppedSet = /* @__PURE__ */ new Set();
|
|
this.removesSubTreeCache = /* @__PURE__ */ new Set();
|
|
this.movedMap = {};
|
|
this.mutationCb(payload);
|
|
});
|
|
__publicField(this, "genTextAreaValueMutation", (textarea) => {
|
|
let item = this.attributeMap.get(textarea);
|
|
if (!item) {
|
|
item = {
|
|
node: textarea,
|
|
attributes: {},
|
|
styleDiff: {},
|
|
_unchangedStyles: {}
|
|
};
|
|
this.attributes.push(item);
|
|
this.attributeMap.set(textarea, item);
|
|
}
|
|
const value = Array.from(
|
|
index.childNodes(textarea),
|
|
(cn) => index.textContent(cn) || ""
|
|
).join("");
|
|
item.attributes.value = maskInputValue({
|
|
element: textarea,
|
|
maskInputOptions: this.maskInputOptions,
|
|
tagName: textarea.tagName,
|
|
type: getInputType(textarea),
|
|
value,
|
|
maskInputFn: this.maskInputFn
|
|
});
|
|
});
|
|
__publicField(this, "processMutation", (m) => {
|
|
if (isIgnored(m.target, this.mirror, this.slimDOMOptions)) {
|
|
return;
|
|
}
|
|
switch (m.type) {
|
|
case "characterData": {
|
|
const value = index.textContent(m.target);
|
|
if (!isBlocked(m.target, this.blockClass, this.blockSelector, false) && value !== m.oldValue) {
|
|
this.texts.push({
|
|
value: needMaskingText(
|
|
m.target,
|
|
this.maskTextClass,
|
|
this.maskTextSelector,
|
|
true
|
|
// checkAncestors
|
|
) && value ? this.maskTextFn ? this.maskTextFn(value, closestElementOfNode(m.target)) : value.replace(/[\S]/g, "*") : value,
|
|
node: m.target
|
|
});
|
|
}
|
|
break;
|
|
}
|
|
case "attributes": {
|
|
const target = m.target;
|
|
let attributeName = m.attributeName;
|
|
let value = m.target.getAttribute(attributeName);
|
|
if (attributeName === "value") {
|
|
const type = getInputType(target);
|
|
value = maskInputValue({
|
|
element: target,
|
|
maskInputOptions: this.maskInputOptions,
|
|
tagName: target.tagName,
|
|
type,
|
|
value,
|
|
maskInputFn: this.maskInputFn
|
|
});
|
|
}
|
|
if (isBlocked(m.target, this.blockClass, this.blockSelector, false) || value === m.oldValue) {
|
|
return;
|
|
}
|
|
let item = this.attributeMap.get(m.target);
|
|
if (target.tagName === "IFRAME" && attributeName === "src" && !this.keepIframeSrcFn(value)) {
|
|
if (!target.contentDocument) {
|
|
attributeName = "rr_src";
|
|
} else {
|
|
return;
|
|
}
|
|
}
|
|
if (!item) {
|
|
item = {
|
|
node: m.target,
|
|
attributes: {},
|
|
styleDiff: {},
|
|
_unchangedStyles: {}
|
|
};
|
|
this.attributes.push(item);
|
|
this.attributeMap.set(m.target, item);
|
|
}
|
|
if (attributeName === "type" && target.tagName === "INPUT" && (m.oldValue || "").toLowerCase() === "password") {
|
|
target.setAttribute("data-rr-is-password", "true");
|
|
}
|
|
if (!ignoreAttribute(target.tagName, attributeName)) {
|
|
item.attributes[attributeName] = transformAttribute(
|
|
this.doc,
|
|
toLowerCase(target.tagName),
|
|
toLowerCase(attributeName),
|
|
value
|
|
);
|
|
if (attributeName === "style") {
|
|
if (!this.unattachedDoc) {
|
|
try {
|
|
this.unattachedDoc = document.implementation.createHTMLDocument();
|
|
} catch (e2) {
|
|
this.unattachedDoc = this.doc;
|
|
}
|
|
}
|
|
const old = this.unattachedDoc.createElement("span");
|
|
if (m.oldValue) {
|
|
old.setAttribute("style", m.oldValue);
|
|
}
|
|
for (const pname of Array.from(target.style)) {
|
|
const newValue = target.style.getPropertyValue(pname);
|
|
const newPriority = target.style.getPropertyPriority(pname);
|
|
if (newValue !== old.style.getPropertyValue(pname) || newPriority !== old.style.getPropertyPriority(pname)) {
|
|
if (newPriority === "") {
|
|
item.styleDiff[pname] = newValue;
|
|
} else {
|
|
item.styleDiff[pname] = [newValue, newPriority];
|
|
}
|
|
} else {
|
|
item._unchangedStyles[pname] = [newValue, newPriority];
|
|
}
|
|
}
|
|
for (const pname of Array.from(old.style)) {
|
|
if (target.style.getPropertyValue(pname) === "") {
|
|
item.styleDiff[pname] = false;
|
|
}
|
|
}
|
|
} else if (attributeName === "open" && target.tagName === "DIALOG") {
|
|
if (target.matches("dialog:modal")) {
|
|
item.attributes["rr_open_mode"] = "modal";
|
|
} else {
|
|
item.attributes["rr_open_mode"] = "non-modal";
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case "childList": {
|
|
if (isBlocked(m.target, this.blockClass, this.blockSelector, true))
|
|
return;
|
|
if (m.target.tagName === "TEXTAREA") {
|
|
this.genTextAreaValueMutation(m.target);
|
|
return;
|
|
}
|
|
m.addedNodes.forEach((n2) => this.genAdds(n2, m.target));
|
|
m.removedNodes.forEach((n2) => {
|
|
const nodeId = this.mirror.getId(n2);
|
|
const parentId = isShadowRoot(m.target) ? this.mirror.getId(index.host(m.target)) : this.mirror.getId(m.target);
|
|
if (isBlocked(m.target, this.blockClass, this.blockSelector, false) || isIgnored(n2, this.mirror, this.slimDOMOptions) || !isSerialized(n2, this.mirror)) {
|
|
return;
|
|
}
|
|
if (this.addedSet.has(n2)) {
|
|
deepDelete(this.addedSet, n2);
|
|
this.droppedSet.add(n2);
|
|
} else if (this.addedSet.has(m.target) && nodeId === -1) ;
|
|
else if (isAncestorRemoved(m.target, this.mirror)) ;
|
|
else if (this.movedSet.has(n2) && this.movedMap[moveKey(nodeId, parentId)]) {
|
|
deepDelete(this.movedSet, n2);
|
|
} else {
|
|
this.removes.push({
|
|
parentId,
|
|
id: nodeId,
|
|
isShadow: isShadowRoot(m.target) && isNativeShadowDom(m.target) ? true : void 0
|
|
});
|
|
processRemoves(n2, this.removesSubTreeCache);
|
|
}
|
|
this.mapRemoves.push(n2);
|
|
});
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
__publicField(this, "genAdds", (n2, target) => {
|
|
if (this.processedNodeManager.inOtherBuffer(n2, this)) return;
|
|
if (this.addedSet.has(n2) || this.movedSet.has(n2)) return;
|
|
if (this.mirror.hasNode(n2)) {
|
|
if (isIgnored(n2, this.mirror, this.slimDOMOptions)) {
|
|
return;
|
|
}
|
|
this.movedSet.add(n2);
|
|
let targetId = null;
|
|
if (target && this.mirror.hasNode(target)) {
|
|
targetId = this.mirror.getId(target);
|
|
}
|
|
if (targetId && targetId !== -1) {
|
|
this.movedMap[moveKey(this.mirror.getId(n2), targetId)] = true;
|
|
}
|
|
} else {
|
|
this.addedSet.add(n2);
|
|
this.droppedSet.delete(n2);
|
|
}
|
|
if (!isBlocked(n2, this.blockClass, this.blockSelector, false)) {
|
|
index.childNodes(n2).forEach((childN) => this.genAdds(childN));
|
|
if (hasShadowRoot(n2)) {
|
|
index.childNodes(index.shadowRoot(n2)).forEach((childN) => {
|
|
this.processedNodeManager.add(childN, this);
|
|
this.genAdds(childN, n2);
|
|
});
|
|
}
|
|
}
|
|
});
|
|
}
|
|
init(options) {
|
|
[
|
|
"mutationCb",
|
|
"blockClass",
|
|
"blockSelector",
|
|
"maskTextClass",
|
|
"maskTextSelector",
|
|
"inlineStylesheet",
|
|
"maskInputOptions",
|
|
"maskTextFn",
|
|
"maskInputFn",
|
|
"keepIframeSrcFn",
|
|
"recordCanvas",
|
|
"inlineImages",
|
|
"slimDOMOptions",
|
|
"dataURLOptions",
|
|
"doc",
|
|
"mirror",
|
|
"iframeManager",
|
|
"stylesheetManager",
|
|
"shadowDomManager",
|
|
"canvasManager",
|
|
"processedNodeManager"
|
|
].forEach((key) => {
|
|
this[key] = options[key];
|
|
});
|
|
}
|
|
freeze() {
|
|
this.frozen = true;
|
|
this.canvasManager.freeze();
|
|
}
|
|
unfreeze() {
|
|
this.frozen = false;
|
|
this.canvasManager.unfreeze();
|
|
this.emit();
|
|
}
|
|
isFrozen() {
|
|
return this.frozen;
|
|
}
|
|
lock() {
|
|
this.locked = true;
|
|
this.canvasManager.lock();
|
|
}
|
|
unlock() {
|
|
this.locked = false;
|
|
this.canvasManager.unlock();
|
|
this.emit();
|
|
}
|
|
reset() {
|
|
this.shadowDomManager.reset();
|
|
this.canvasManager.reset();
|
|
}
|
|
}
|
|
function deepDelete(addsSet, n2) {
|
|
addsSet.delete(n2);
|
|
index.childNodes(n2).forEach((childN) => deepDelete(addsSet, childN));
|
|
}
|
|
function processRemoves(n2, cache) {
|
|
const queue = [n2];
|
|
while (queue.length) {
|
|
const next = queue.pop();
|
|
if (cache.has(next)) continue;
|
|
cache.add(next);
|
|
index.childNodes(next).forEach((n22) => queue.push(n22));
|
|
}
|
|
return;
|
|
}
|
|
function isParentRemoved(removes, n2, mirror2) {
|
|
if (removes.size === 0) return false;
|
|
return _isParentRemoved(removes, n2);
|
|
}
|
|
function _isParentRemoved(removes, n2, _mirror2) {
|
|
const node2 = index.parentNode(n2);
|
|
if (!node2) return false;
|
|
return removes.has(node2);
|
|
}
|
|
function isAncestorInSet(set, n2) {
|
|
if (set.size === 0) return false;
|
|
return _isAncestorInSet(set, n2);
|
|
}
|
|
function _isAncestorInSet(set, n2) {
|
|
const parent = index.parentNode(n2);
|
|
if (!parent) {
|
|
return false;
|
|
}
|
|
if (set.has(parent)) {
|
|
return true;
|
|
}
|
|
return _isAncestorInSet(set, parent);
|
|
}
|
|
let errorHandler;
|
|
function registerErrorHandler(handler) {
|
|
errorHandler = handler;
|
|
}
|
|
function unregisterErrorHandler() {
|
|
errorHandler = void 0;
|
|
}
|
|
const callbackWrapper = (cb) => {
|
|
if (!errorHandler) {
|
|
return cb;
|
|
}
|
|
const rrwebWrapped = (...rest) => {
|
|
try {
|
|
return cb(...rest);
|
|
} catch (error) {
|
|
if (errorHandler && errorHandler(error) === true) {
|
|
return;
|
|
}
|
|
throw error;
|
|
}
|
|
};
|
|
return rrwebWrapped;
|
|
};
|
|
const mutationBuffers = [];
|
|
function getEventTarget(event) {
|
|
try {
|
|
if ("composedPath" in event) {
|
|
const path = event.composedPath();
|
|
if (path.length) {
|
|
return path[0];
|
|
}
|
|
} else if ("path" in event && event.path.length) {
|
|
return event.path[0];
|
|
}
|
|
} catch (e) {
|
|
}
|
|
return event && event.target;
|
|
}
|
|
function initMutationObserver(options, rootEl) {
|
|
const mutationBuffer = new MutationBuffer();
|
|
mutationBuffers.push(mutationBuffer);
|
|
mutationBuffer.init(options);
|
|
const observer = new (mutationObserverCtor())(
|
|
callbackWrapper(mutationBuffer.processMutations.bind(mutationBuffer))
|
|
);
|
|
observer.observe(rootEl, {
|
|
attributes: true,
|
|
attributeOldValue: true,
|
|
characterData: true,
|
|
characterDataOldValue: true,
|
|
childList: true,
|
|
subtree: true
|
|
});
|
|
return observer;
|
|
}
|
|
function initMoveObserver({
|
|
mousemoveCb,
|
|
sampling,
|
|
doc,
|
|
mirror: mirror2
|
|
}) {
|
|
if (sampling.mousemove === false) {
|
|
return () => {
|
|
};
|
|
}
|
|
const threshold = typeof sampling.mousemove === "number" ? sampling.mousemove : 50;
|
|
const callbackThreshold = typeof sampling.mousemoveCallback === "number" ? sampling.mousemoveCallback : 500;
|
|
let positions = [];
|
|
let timeBaseline;
|
|
const wrappedCb = throttle(
|
|
callbackWrapper(
|
|
(source) => {
|
|
const totalOffset = Date.now() - timeBaseline;
|
|
mousemoveCb(
|
|
positions.map((p) => {
|
|
p.timeOffset -= totalOffset;
|
|
return p;
|
|
}),
|
|
source
|
|
);
|
|
positions = [];
|
|
timeBaseline = null;
|
|
}
|
|
),
|
|
callbackThreshold
|
|
);
|
|
const updatePosition = callbackWrapper(
|
|
throttle(
|
|
callbackWrapper((evt) => {
|
|
const target = getEventTarget(evt);
|
|
const { clientX, clientY } = legacy_isTouchEvent(evt) ? evt.changedTouches[0] : evt;
|
|
if (!timeBaseline) {
|
|
timeBaseline = nowTimestamp();
|
|
}
|
|
positions.push({
|
|
x: clientX,
|
|
y: clientY,
|
|
id: mirror2.getId(target),
|
|
timeOffset: nowTimestamp() - timeBaseline
|
|
});
|
|
wrappedCb(
|
|
typeof DragEvent !== "undefined" && evt instanceof DragEvent ? IncrementalSource.Drag : evt instanceof MouseEvent ? IncrementalSource.MouseMove : IncrementalSource.TouchMove
|
|
);
|
|
}),
|
|
threshold,
|
|
{
|
|
trailing: false
|
|
}
|
|
)
|
|
);
|
|
const handlers = [
|
|
on("mousemove", updatePosition, doc),
|
|
on("touchmove", updatePosition, doc),
|
|
on("drag", updatePosition, doc)
|
|
];
|
|
return callbackWrapper(() => {
|
|
handlers.forEach((h) => h());
|
|
});
|
|
}
|
|
function initMouseInteractionObserver({
|
|
mouseInteractionCb,
|
|
doc,
|
|
mirror: mirror2,
|
|
blockClass,
|
|
blockSelector,
|
|
sampling
|
|
}) {
|
|
if (sampling.mouseInteraction === false) {
|
|
return () => {
|
|
};
|
|
}
|
|
const disableMap = sampling.mouseInteraction === true || sampling.mouseInteraction === void 0 ? {} : sampling.mouseInteraction;
|
|
const handlers = [];
|
|
let currentPointerType = null;
|
|
const getHandler = (eventKey) => {
|
|
return (event) => {
|
|
const target = getEventTarget(event);
|
|
if (isBlocked(target, blockClass, blockSelector, true)) {
|
|
return;
|
|
}
|
|
let pointerType = null;
|
|
let thisEventKey = eventKey;
|
|
if ("pointerType" in event) {
|
|
switch (event.pointerType) {
|
|
case "mouse":
|
|
pointerType = PointerTypes.Mouse;
|
|
break;
|
|
case "touch":
|
|
pointerType = PointerTypes.Touch;
|
|
break;
|
|
case "pen":
|
|
pointerType = PointerTypes.Pen;
|
|
break;
|
|
}
|
|
if (pointerType === PointerTypes.Touch) {
|
|
if (MouseInteractions[eventKey] === MouseInteractions.MouseDown) {
|
|
thisEventKey = "TouchStart";
|
|
} else if (MouseInteractions[eventKey] === MouseInteractions.MouseUp) {
|
|
thisEventKey = "TouchEnd";
|
|
}
|
|
} else if (pointerType === PointerTypes.Pen) ;
|
|
} else if (legacy_isTouchEvent(event)) {
|
|
pointerType = PointerTypes.Touch;
|
|
}
|
|
if (pointerType !== null) {
|
|
currentPointerType = pointerType;
|
|
if (thisEventKey.startsWith("Touch") && pointerType === PointerTypes.Touch || thisEventKey.startsWith("Mouse") && pointerType === PointerTypes.Mouse) {
|
|
pointerType = null;
|
|
}
|
|
} else if (MouseInteractions[eventKey] === MouseInteractions.Click) {
|
|
pointerType = currentPointerType;
|
|
currentPointerType = null;
|
|
}
|
|
const e2 = legacy_isTouchEvent(event) ? event.changedTouches[0] : event;
|
|
if (!e2) {
|
|
return;
|
|
}
|
|
const id = mirror2.getId(target);
|
|
const { clientX, clientY } = e2;
|
|
callbackWrapper(mouseInteractionCb)(__spreadValues({
|
|
type: MouseInteractions[thisEventKey],
|
|
id,
|
|
x: clientX,
|
|
y: clientY
|
|
}, pointerType !== null && { pointerType }));
|
|
};
|
|
};
|
|
Object.keys(MouseInteractions).filter(
|
|
(key) => Number.isNaN(Number(key)) && !key.endsWith("_Departed") && disableMap[key] !== false
|
|
).forEach((eventKey) => {
|
|
let eventName = toLowerCase(eventKey);
|
|
const handler = getHandler(eventKey);
|
|
if (window.PointerEvent) {
|
|
switch (MouseInteractions[eventKey]) {
|
|
case MouseInteractions.MouseDown:
|
|
case MouseInteractions.MouseUp:
|
|
eventName = eventName.replace(
|
|
"mouse",
|
|
"pointer"
|
|
);
|
|
break;
|
|
case MouseInteractions.TouchStart:
|
|
case MouseInteractions.TouchEnd:
|
|
return;
|
|
}
|
|
}
|
|
handlers.push(on(eventName, handler, doc));
|
|
});
|
|
return callbackWrapper(() => {
|
|
handlers.forEach((h) => h());
|
|
});
|
|
}
|
|
function initScrollObserver({
|
|
scrollCb,
|
|
doc,
|
|
mirror: mirror2,
|
|
blockClass,
|
|
blockSelector,
|
|
sampling
|
|
}) {
|
|
const updatePosition = callbackWrapper(
|
|
throttle(
|
|
callbackWrapper((evt) => {
|
|
const target = getEventTarget(evt);
|
|
if (!target || isBlocked(target, blockClass, blockSelector, true)) {
|
|
return;
|
|
}
|
|
const id = mirror2.getId(target);
|
|
if (target === doc && doc.defaultView) {
|
|
const scrollLeftTop = getWindowScroll(doc.defaultView);
|
|
scrollCb({
|
|
id,
|
|
x: scrollLeftTop.left,
|
|
y: scrollLeftTop.top
|
|
});
|
|
} else {
|
|
scrollCb({
|
|
id,
|
|
x: target.scrollLeft,
|
|
y: target.scrollTop
|
|
});
|
|
}
|
|
}),
|
|
sampling.scroll || 100
|
|
)
|
|
);
|
|
return on("scroll", updatePosition, doc);
|
|
}
|
|
function initViewportResizeObserver({ viewportResizeCb }, { win }) {
|
|
let lastH = -1;
|
|
let lastW = -1;
|
|
const updateDimension = callbackWrapper(
|
|
throttle(
|
|
callbackWrapper(() => {
|
|
const height = getWindowHeight();
|
|
const width = getWindowWidth();
|
|
if (lastH !== height || lastW !== width) {
|
|
viewportResizeCb({
|
|
width: Number(width),
|
|
height: Number(height)
|
|
});
|
|
lastH = height;
|
|
lastW = width;
|
|
}
|
|
}),
|
|
200
|
|
)
|
|
);
|
|
return on("resize", updateDimension, win);
|
|
}
|
|
const INPUT_TAGS = ["INPUT", "TEXTAREA", "SELECT"];
|
|
const lastInputValueMap = /* @__PURE__ */ new WeakMap();
|
|
function initInputObserver({
|
|
inputCb,
|
|
doc,
|
|
mirror: mirror2,
|
|
blockClass,
|
|
blockSelector,
|
|
ignoreClass,
|
|
ignoreSelector,
|
|
maskInputOptions,
|
|
maskInputFn,
|
|
sampling,
|
|
userTriggeredOnInput
|
|
}) {
|
|
function eventHandler(event) {
|
|
let target = getEventTarget(event);
|
|
const userTriggered = event.isTrusted;
|
|
const tagName = target && target.tagName;
|
|
if (target && tagName === "OPTION") {
|
|
target = index.parentElement(target);
|
|
}
|
|
if (!target || !tagName || INPUT_TAGS.indexOf(tagName) < 0 || isBlocked(target, blockClass, blockSelector, true)) {
|
|
return;
|
|
}
|
|
if (target.classList.contains(ignoreClass) || ignoreSelector && target.matches(ignoreSelector)) {
|
|
return;
|
|
}
|
|
let text = target.value;
|
|
let isChecked = false;
|
|
const type = getInputType(target) || "";
|
|
if (type === "radio" || type === "checkbox") {
|
|
isChecked = target.checked;
|
|
} else if (maskInputOptions[tagName.toLowerCase()] || maskInputOptions[type]) {
|
|
text = maskInputValue({
|
|
element: target,
|
|
maskInputOptions,
|
|
tagName,
|
|
type,
|
|
value: text,
|
|
maskInputFn
|
|
});
|
|
}
|
|
cbWithDedup(
|
|
target,
|
|
userTriggeredOnInput ? { text, isChecked, userTriggered } : { text, isChecked }
|
|
);
|
|
const name = target.name;
|
|
if (type === "radio" && name && isChecked) {
|
|
doc.querySelectorAll(`input[type="radio"][name="${name}"]`).forEach((el) => {
|
|
if (el !== target) {
|
|
const text2 = el.value;
|
|
cbWithDedup(
|
|
el,
|
|
userTriggeredOnInput ? { text: text2, isChecked: !isChecked, userTriggered: false } : { text: text2, isChecked: !isChecked }
|
|
);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
function cbWithDedup(target, v2) {
|
|
const lastInputValue = lastInputValueMap.get(target);
|
|
if (!lastInputValue || lastInputValue.text !== v2.text || lastInputValue.isChecked !== v2.isChecked) {
|
|
lastInputValueMap.set(target, v2);
|
|
const id = mirror2.getId(target);
|
|
callbackWrapper(inputCb)(__spreadProps(__spreadValues({}, v2), {
|
|
id
|
|
}));
|
|
}
|
|
}
|
|
const events = sampling.input === "last" ? ["change"] : ["input", "change"];
|
|
const handlers = events.map(
|
|
(eventName) => on(eventName, callbackWrapper(eventHandler), doc)
|
|
);
|
|
const currentWindow = doc.defaultView;
|
|
if (!currentWindow) {
|
|
return () => {
|
|
handlers.forEach((h) => h());
|
|
};
|
|
}
|
|
const propertyDescriptor = currentWindow.Object.getOwnPropertyDescriptor(
|
|
currentWindow.HTMLInputElement.prototype,
|
|
"value"
|
|
);
|
|
const hookProperties = [
|
|
[currentWindow.HTMLInputElement.prototype, "value"],
|
|
[currentWindow.HTMLInputElement.prototype, "checked"],
|
|
[currentWindow.HTMLSelectElement.prototype, "value"],
|
|
[currentWindow.HTMLTextAreaElement.prototype, "value"],
|
|
// Some UI library use selectedIndex to set select value
|
|
[currentWindow.HTMLSelectElement.prototype, "selectedIndex"],
|
|
[currentWindow.HTMLOptionElement.prototype, "selected"]
|
|
];
|
|
if (propertyDescriptor && propertyDescriptor.set) {
|
|
handlers.push(
|
|
...hookProperties.map(
|
|
(p) => hookSetter(
|
|
p[0],
|
|
p[1],
|
|
{
|
|
set() {
|
|
callbackWrapper(eventHandler)({
|
|
target: this,
|
|
isTrusted: false
|
|
// userTriggered to false as this could well be programmatic
|
|
});
|
|
}
|
|
},
|
|
false,
|
|
currentWindow
|
|
)
|
|
)
|
|
);
|
|
}
|
|
return callbackWrapper(() => {
|
|
handlers.forEach((h) => h());
|
|
});
|
|
}
|
|
function getNestedCSSRulePositions(rule2) {
|
|
const positions = [];
|
|
function recurse(childRule, pos) {
|
|
if (hasNestedCSSRule("CSSGroupingRule") && childRule.parentRule instanceof CSSGroupingRule || hasNestedCSSRule("CSSMediaRule") && childRule.parentRule instanceof CSSMediaRule || hasNestedCSSRule("CSSSupportsRule") && childRule.parentRule instanceof CSSSupportsRule || hasNestedCSSRule("CSSConditionRule") && childRule.parentRule instanceof CSSConditionRule) {
|
|
const rules2 = Array.from(
|
|
childRule.parentRule.cssRules
|
|
);
|
|
const index2 = rules2.indexOf(childRule);
|
|
pos.unshift(index2);
|
|
return recurse(childRule.parentRule, pos);
|
|
} else if (childRule.parentStyleSheet) {
|
|
const rules2 = Array.from(childRule.parentStyleSheet.cssRules);
|
|
const index2 = rules2.indexOf(childRule);
|
|
pos.unshift(index2);
|
|
}
|
|
return pos;
|
|
}
|
|
return recurse(rule2, positions);
|
|
}
|
|
function getIdAndStyleId(sheet, mirror2, styleMirror) {
|
|
let id, styleId;
|
|
if (!sheet) return {};
|
|
if (sheet.ownerNode) id = mirror2.getId(sheet.ownerNode);
|
|
else styleId = styleMirror.getId(sheet);
|
|
return {
|
|
styleId,
|
|
id
|
|
};
|
|
}
|
|
function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetManager }, { win }) {
|
|
if (!win.CSSStyleSheet || !win.CSSStyleSheet.prototype) {
|
|
return () => {
|
|
};
|
|
}
|
|
const insertRule = win.CSSStyleSheet.prototype.insertRule;
|
|
win.CSSStyleSheet.prototype.insertRule = new Proxy(insertRule, {
|
|
apply: callbackWrapper(
|
|
(target, thisArg, argumentsList) => {
|
|
const [rule2, index2] = argumentsList;
|
|
const { id, styleId } = getIdAndStyleId(
|
|
thisArg,
|
|
mirror2,
|
|
stylesheetManager.styleMirror
|
|
);
|
|
if (id && id !== -1 || styleId && styleId !== -1) {
|
|
styleSheetRuleCb({
|
|
id,
|
|
styleId,
|
|
adds: [{ rule: rule2, index: index2 }]
|
|
});
|
|
}
|
|
return target.apply(thisArg, argumentsList);
|
|
}
|
|
)
|
|
});
|
|
win.CSSStyleSheet.prototype.addRule = function(selector, styleBlock, index2 = this.cssRules.length) {
|
|
const rule2 = `${selector} { ${styleBlock} }`;
|
|
return win.CSSStyleSheet.prototype.insertRule.apply(this, [rule2, index2]);
|
|
};
|
|
const deleteRule = win.CSSStyleSheet.prototype.deleteRule;
|
|
win.CSSStyleSheet.prototype.deleteRule = new Proxy(deleteRule, {
|
|
apply: callbackWrapper(
|
|
(target, thisArg, argumentsList) => {
|
|
const [index2] = argumentsList;
|
|
const { id, styleId } = getIdAndStyleId(
|
|
thisArg,
|
|
mirror2,
|
|
stylesheetManager.styleMirror
|
|
);
|
|
if (id && id !== -1 || styleId && styleId !== -1) {
|
|
styleSheetRuleCb({
|
|
id,
|
|
styleId,
|
|
removes: [{ index: index2 }]
|
|
});
|
|
}
|
|
return target.apply(thisArg, argumentsList);
|
|
}
|
|
)
|
|
});
|
|
win.CSSStyleSheet.prototype.removeRule = function(index2) {
|
|
return win.CSSStyleSheet.prototype.deleteRule.apply(this, [index2]);
|
|
};
|
|
let replace;
|
|
if (win.CSSStyleSheet.prototype.replace) {
|
|
replace = win.CSSStyleSheet.prototype.replace;
|
|
win.CSSStyleSheet.prototype.replace = new Proxy(replace, {
|
|
apply: callbackWrapper(
|
|
(target, thisArg, argumentsList) => {
|
|
const [text] = argumentsList;
|
|
const { id, styleId } = getIdAndStyleId(
|
|
thisArg,
|
|
mirror2,
|
|
stylesheetManager.styleMirror
|
|
);
|
|
if (id && id !== -1 || styleId && styleId !== -1) {
|
|
styleSheetRuleCb({
|
|
id,
|
|
styleId,
|
|
replace: text
|
|
});
|
|
}
|
|
return target.apply(thisArg, argumentsList);
|
|
}
|
|
)
|
|
});
|
|
}
|
|
let replaceSync;
|
|
if (win.CSSStyleSheet.prototype.replaceSync) {
|
|
replaceSync = win.CSSStyleSheet.prototype.replaceSync;
|
|
win.CSSStyleSheet.prototype.replaceSync = new Proxy(replaceSync, {
|
|
apply: callbackWrapper(
|
|
(target, thisArg, argumentsList) => {
|
|
const [text] = argumentsList;
|
|
const { id, styleId } = getIdAndStyleId(
|
|
thisArg,
|
|
mirror2,
|
|
stylesheetManager.styleMirror
|
|
);
|
|
if (id && id !== -1 || styleId && styleId !== -1) {
|
|
styleSheetRuleCb({
|
|
id,
|
|
styleId,
|
|
replaceSync: text
|
|
});
|
|
}
|
|
return target.apply(thisArg, argumentsList);
|
|
}
|
|
)
|
|
});
|
|
}
|
|
const supportedNestedCSSRuleTypes = {};
|
|
if (canMonkeyPatchNestedCSSRule("CSSGroupingRule")) {
|
|
supportedNestedCSSRuleTypes.CSSGroupingRule = win.CSSGroupingRule;
|
|
} else {
|
|
if (canMonkeyPatchNestedCSSRule("CSSMediaRule")) {
|
|
supportedNestedCSSRuleTypes.CSSMediaRule = win.CSSMediaRule;
|
|
}
|
|
if (canMonkeyPatchNestedCSSRule("CSSConditionRule")) {
|
|
supportedNestedCSSRuleTypes.CSSConditionRule = win.CSSConditionRule;
|
|
}
|
|
if (canMonkeyPatchNestedCSSRule("CSSSupportsRule")) {
|
|
supportedNestedCSSRuleTypes.CSSSupportsRule = win.CSSSupportsRule;
|
|
}
|
|
}
|
|
const unmodifiedFunctions = {};
|
|
Object.entries(supportedNestedCSSRuleTypes).forEach(([typeKey, type]) => {
|
|
unmodifiedFunctions[typeKey] = {
|
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
insertRule: type.prototype.insertRule,
|
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
deleteRule: type.prototype.deleteRule
|
|
};
|
|
type.prototype.insertRule = new Proxy(
|
|
unmodifiedFunctions[typeKey].insertRule,
|
|
{
|
|
apply: callbackWrapper(
|
|
(target, thisArg, argumentsList) => {
|
|
const [rule2, index2] = argumentsList;
|
|
const { id, styleId } = getIdAndStyleId(
|
|
thisArg.parentStyleSheet,
|
|
mirror2,
|
|
stylesheetManager.styleMirror
|
|
);
|
|
if (id && id !== -1 || styleId && styleId !== -1) {
|
|
styleSheetRuleCb({
|
|
id,
|
|
styleId,
|
|
adds: [
|
|
{
|
|
rule: rule2,
|
|
index: [
|
|
...getNestedCSSRulePositions(thisArg),
|
|
index2 || 0
|
|
// defaults to 0
|
|
]
|
|
}
|
|
]
|
|
});
|
|
}
|
|
return target.apply(thisArg, argumentsList);
|
|
}
|
|
)
|
|
}
|
|
);
|
|
type.prototype.deleteRule = new Proxy(
|
|
unmodifiedFunctions[typeKey].deleteRule,
|
|
{
|
|
apply: callbackWrapper(
|
|
(target, thisArg, argumentsList) => {
|
|
const [index2] = argumentsList;
|
|
const { id, styleId } = getIdAndStyleId(
|
|
thisArg.parentStyleSheet,
|
|
mirror2,
|
|
stylesheetManager.styleMirror
|
|
);
|
|
if (id && id !== -1 || styleId && styleId !== -1) {
|
|
styleSheetRuleCb({
|
|
id,
|
|
styleId,
|
|
removes: [
|
|
{ index: [...getNestedCSSRulePositions(thisArg), index2] }
|
|
]
|
|
});
|
|
}
|
|
return target.apply(thisArg, argumentsList);
|
|
}
|
|
)
|
|
}
|
|
);
|
|
});
|
|
return callbackWrapper(() => {
|
|
win.CSSStyleSheet.prototype.insertRule = insertRule;
|
|
win.CSSStyleSheet.prototype.deleteRule = deleteRule;
|
|
replace && (win.CSSStyleSheet.prototype.replace = replace);
|
|
replaceSync && (win.CSSStyleSheet.prototype.replaceSync = replaceSync);
|
|
Object.entries(supportedNestedCSSRuleTypes).forEach(([typeKey, type]) => {
|
|
type.prototype.insertRule = unmodifiedFunctions[typeKey].insertRule;
|
|
type.prototype.deleteRule = unmodifiedFunctions[typeKey].deleteRule;
|
|
});
|
|
});
|
|
}
|
|
function initAdoptedStyleSheetObserver({
|
|
mirror: mirror2,
|
|
stylesheetManager
|
|
}, host2) {
|
|
var _a2, _b, _c;
|
|
let hostId = null;
|
|
if (host2.nodeName === "#document") hostId = mirror2.getId(host2);
|
|
else hostId = mirror2.getId(index.host(host2));
|
|
const patchTarget = host2.nodeName === "#document" ? (_a2 = host2.defaultView) == null ? void 0 : _a2.Document : (_c = (_b = host2.ownerDocument) == null ? void 0 : _b.defaultView) == null ? void 0 : _c.ShadowRoot;
|
|
const originalPropertyDescriptor = (patchTarget == null ? void 0 : patchTarget.prototype) ? Object.getOwnPropertyDescriptor(
|
|
patchTarget == null ? void 0 : patchTarget.prototype,
|
|
"adoptedStyleSheets"
|
|
) : void 0;
|
|
if (hostId === null || hostId === -1 || !patchTarget || !originalPropertyDescriptor)
|
|
return () => {
|
|
};
|
|
Object.defineProperty(host2, "adoptedStyleSheets", {
|
|
configurable: originalPropertyDescriptor.configurable,
|
|
enumerable: originalPropertyDescriptor.enumerable,
|
|
get() {
|
|
var _a3;
|
|
return (_a3 = originalPropertyDescriptor.get) == null ? void 0 : _a3.call(this);
|
|
},
|
|
set(sheets) {
|
|
var _a3;
|
|
const result2 = (_a3 = originalPropertyDescriptor.set) == null ? void 0 : _a3.call(this, sheets);
|
|
if (hostId !== null && hostId !== -1) {
|
|
try {
|
|
stylesheetManager.adoptStyleSheets(sheets, hostId);
|
|
} catch (e2) {
|
|
}
|
|
}
|
|
return result2;
|
|
}
|
|
});
|
|
return callbackWrapper(() => {
|
|
Object.defineProperty(host2, "adoptedStyleSheets", {
|
|
configurable: originalPropertyDescriptor.configurable,
|
|
enumerable: originalPropertyDescriptor.enumerable,
|
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
get: originalPropertyDescriptor.get,
|
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
set: originalPropertyDescriptor.set
|
|
});
|
|
});
|
|
}
|
|
function initStyleDeclarationObserver({
|
|
styleDeclarationCb,
|
|
mirror: mirror2,
|
|
ignoreCSSAttributes,
|
|
stylesheetManager
|
|
}, { win }) {
|
|
const setProperty = win.CSSStyleDeclaration.prototype.setProperty;
|
|
win.CSSStyleDeclaration.prototype.setProperty = new Proxy(setProperty, {
|
|
apply: callbackWrapper(
|
|
(target, thisArg, argumentsList) => {
|
|
var _a2;
|
|
const [property, value, priority] = argumentsList;
|
|
if (ignoreCSSAttributes.has(property)) {
|
|
return setProperty.apply(thisArg, [property, value, priority]);
|
|
}
|
|
const { id, styleId } = getIdAndStyleId(
|
|
(_a2 = thisArg.parentRule) == null ? void 0 : _a2.parentStyleSheet,
|
|
mirror2,
|
|
stylesheetManager.styleMirror
|
|
);
|
|
if (id && id !== -1 || styleId && styleId !== -1) {
|
|
styleDeclarationCb({
|
|
id,
|
|
styleId,
|
|
set: {
|
|
property,
|
|
value,
|
|
priority
|
|
},
|
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
index: getNestedCSSRulePositions(thisArg.parentRule)
|
|
});
|
|
}
|
|
return target.apply(thisArg, argumentsList);
|
|
}
|
|
)
|
|
});
|
|
const removeProperty = win.CSSStyleDeclaration.prototype.removeProperty;
|
|
win.CSSStyleDeclaration.prototype.removeProperty = new Proxy(removeProperty, {
|
|
apply: callbackWrapper(
|
|
(target, thisArg, argumentsList) => {
|
|
var _a2;
|
|
const [property] = argumentsList;
|
|
if (ignoreCSSAttributes.has(property)) {
|
|
return removeProperty.apply(thisArg, [property]);
|
|
}
|
|
const { id, styleId } = getIdAndStyleId(
|
|
(_a2 = thisArg.parentRule) == null ? void 0 : _a2.parentStyleSheet,
|
|
mirror2,
|
|
stylesheetManager.styleMirror
|
|
);
|
|
if (id && id !== -1 || styleId && styleId !== -1) {
|
|
styleDeclarationCb({
|
|
id,
|
|
styleId,
|
|
remove: {
|
|
property
|
|
},
|
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
index: getNestedCSSRulePositions(thisArg.parentRule)
|
|
});
|
|
}
|
|
return target.apply(thisArg, argumentsList);
|
|
}
|
|
)
|
|
});
|
|
return callbackWrapper(() => {
|
|
win.CSSStyleDeclaration.prototype.setProperty = setProperty;
|
|
win.CSSStyleDeclaration.prototype.removeProperty = removeProperty;
|
|
});
|
|
}
|
|
function initMediaInteractionObserver({
|
|
mediaInteractionCb,
|
|
blockClass,
|
|
blockSelector,
|
|
mirror: mirror2,
|
|
sampling,
|
|
doc
|
|
}) {
|
|
const handler = callbackWrapper(
|
|
(type) => throttle(
|
|
callbackWrapper((event) => {
|
|
const target = getEventTarget(event);
|
|
if (!target || isBlocked(target, blockClass, blockSelector, true)) {
|
|
return;
|
|
}
|
|
const { currentTime, volume, muted, playbackRate, loop } = target;
|
|
mediaInteractionCb({
|
|
type,
|
|
id: mirror2.getId(target),
|
|
currentTime,
|
|
volume,
|
|
muted,
|
|
playbackRate,
|
|
loop
|
|
});
|
|
}),
|
|
sampling.media || 500
|
|
)
|
|
);
|
|
const handlers = [
|
|
on("play", handler(MediaInteractions.Play), doc),
|
|
on("pause", handler(MediaInteractions.Pause), doc),
|
|
on("seeked", handler(MediaInteractions.Seeked), doc),
|
|
on("volumechange", handler(MediaInteractions.VolumeChange), doc),
|
|
on("ratechange", handler(MediaInteractions.RateChange), doc)
|
|
];
|
|
return callbackWrapper(() => {
|
|
handlers.forEach((h) => h());
|
|
});
|
|
}
|
|
function initFontObserver({ fontCb, doc }) {
|
|
const win = doc.defaultView;
|
|
if (!win) {
|
|
return () => {
|
|
};
|
|
}
|
|
const handlers = [];
|
|
const fontMap = /* @__PURE__ */ new WeakMap();
|
|
const originalFontFace = win.FontFace;
|
|
win.FontFace = function FontFace2(family, source, descriptors) {
|
|
const fontFace = new originalFontFace(family, source, descriptors);
|
|
fontMap.set(fontFace, {
|
|
family,
|
|
buffer: typeof source !== "string",
|
|
descriptors,
|
|
fontSource: typeof source === "string" ? source : JSON.stringify(Array.from(new Uint8Array(source)))
|
|
});
|
|
return fontFace;
|
|
};
|
|
const restoreHandler = patch(
|
|
doc.fonts,
|
|
"add",
|
|
function(original) {
|
|
return function(fontFace) {
|
|
setTimeout(
|
|
callbackWrapper(() => {
|
|
const p = fontMap.get(fontFace);
|
|
if (p) {
|
|
fontCb(p);
|
|
fontMap.delete(fontFace);
|
|
}
|
|
}),
|
|
0
|
|
);
|
|
return original.apply(this, [fontFace]);
|
|
};
|
|
}
|
|
);
|
|
handlers.push(() => {
|
|
win.FontFace = originalFontFace;
|
|
});
|
|
handlers.push(restoreHandler);
|
|
return callbackWrapper(() => {
|
|
handlers.forEach((h) => h());
|
|
});
|
|
}
|
|
function initSelectionObserver(param) {
|
|
const { doc, mirror: mirror2, blockClass, blockSelector, selectionCb } = param;
|
|
let collapsed = true;
|
|
const updateSelection = callbackWrapper(() => {
|
|
const selection = doc.getSelection();
|
|
if (!selection || collapsed && (selection == null ? void 0 : selection.isCollapsed)) return;
|
|
collapsed = selection.isCollapsed || false;
|
|
const ranges = [];
|
|
const count = selection.rangeCount || 0;
|
|
for (let i2 = 0; i2 < count; i2++) {
|
|
const range = selection.getRangeAt(i2);
|
|
const { startContainer, startOffset, endContainer, endOffset } = range;
|
|
const blocked = isBlocked(startContainer, blockClass, blockSelector, true) || isBlocked(endContainer, blockClass, blockSelector, true);
|
|
if (blocked) continue;
|
|
ranges.push({
|
|
start: mirror2.getId(startContainer),
|
|
startOffset,
|
|
end: mirror2.getId(endContainer),
|
|
endOffset
|
|
});
|
|
}
|
|
selectionCb({ ranges });
|
|
});
|
|
updateSelection();
|
|
return on("selectionchange", updateSelection);
|
|
}
|
|
function initCustomElementObserver({
|
|
doc,
|
|
customElementCb
|
|
}) {
|
|
const win = doc.defaultView;
|
|
if (!win || !win.customElements) return () => {
|
|
};
|
|
const restoreHandler = patch(
|
|
win.customElements,
|
|
"define",
|
|
function(original) {
|
|
return function(name, constructor, options) {
|
|
try {
|
|
customElementCb({
|
|
define: {
|
|
name
|
|
}
|
|
});
|
|
} catch (e2) {
|
|
console.warn(`Custom element callback failed for ${name}`);
|
|
}
|
|
return original.apply(this, [name, constructor, options]);
|
|
};
|
|
}
|
|
);
|
|
return restoreHandler;
|
|
}
|
|
function mergeHooks(o2, hooks) {
|
|
const {
|
|
mutationCb,
|
|
mousemoveCb,
|
|
mouseInteractionCb,
|
|
scrollCb,
|
|
viewportResizeCb,
|
|
inputCb,
|
|
mediaInteractionCb,
|
|
styleSheetRuleCb,
|
|
styleDeclarationCb,
|
|
canvasMutationCb,
|
|
fontCb,
|
|
selectionCb,
|
|
customElementCb
|
|
} = o2;
|
|
o2.mutationCb = (...p) => {
|
|
if (hooks.mutation) {
|
|
hooks.mutation(...p);
|
|
}
|
|
mutationCb(...p);
|
|
};
|
|
o2.mousemoveCb = (...p) => {
|
|
if (hooks.mousemove) {
|
|
hooks.mousemove(...p);
|
|
}
|
|
mousemoveCb(...p);
|
|
};
|
|
o2.mouseInteractionCb = (...p) => {
|
|
if (hooks.mouseInteraction) {
|
|
hooks.mouseInteraction(...p);
|
|
}
|
|
mouseInteractionCb(...p);
|
|
};
|
|
o2.scrollCb = (...p) => {
|
|
if (hooks.scroll) {
|
|
hooks.scroll(...p);
|
|
}
|
|
scrollCb(...p);
|
|
};
|
|
o2.viewportResizeCb = (...p) => {
|
|
if (hooks.viewportResize) {
|
|
hooks.viewportResize(...p);
|
|
}
|
|
viewportResizeCb(...p);
|
|
};
|
|
o2.inputCb = (...p) => {
|
|
if (hooks.input) {
|
|
hooks.input(...p);
|
|
}
|
|
inputCb(...p);
|
|
};
|
|
o2.mediaInteractionCb = (...p) => {
|
|
if (hooks.mediaInteaction) {
|
|
hooks.mediaInteaction(...p);
|
|
}
|
|
mediaInteractionCb(...p);
|
|
};
|
|
o2.styleSheetRuleCb = (...p) => {
|
|
if (hooks.styleSheetRule) {
|
|
hooks.styleSheetRule(...p);
|
|
}
|
|
styleSheetRuleCb(...p);
|
|
};
|
|
o2.styleDeclarationCb = (...p) => {
|
|
if (hooks.styleDeclaration) {
|
|
hooks.styleDeclaration(...p);
|
|
}
|
|
styleDeclarationCb(...p);
|
|
};
|
|
o2.canvasMutationCb = (...p) => {
|
|
if (hooks.canvasMutation) {
|
|
hooks.canvasMutation(...p);
|
|
}
|
|
canvasMutationCb(...p);
|
|
};
|
|
o2.fontCb = (...p) => {
|
|
if (hooks.font) {
|
|
hooks.font(...p);
|
|
}
|
|
fontCb(...p);
|
|
};
|
|
o2.selectionCb = (...p) => {
|
|
if (hooks.selection) {
|
|
hooks.selection(...p);
|
|
}
|
|
selectionCb(...p);
|
|
};
|
|
o2.customElementCb = (...c2) => {
|
|
if (hooks.customElement) {
|
|
hooks.customElement(...c2);
|
|
}
|
|
customElementCb(...c2);
|
|
};
|
|
}
|
|
function initObservers(o2, hooks = {}) {
|
|
const currentWindow = o2.doc.defaultView;
|
|
if (!currentWindow) {
|
|
return () => {
|
|
};
|
|
}
|
|
mergeHooks(o2, hooks);
|
|
let mutationObserver;
|
|
if (o2.recordDOM) {
|
|
mutationObserver = initMutationObserver(o2, o2.doc);
|
|
}
|
|
const mousemoveHandler = initMoveObserver(o2);
|
|
const mouseInteractionHandler = initMouseInteractionObserver(o2);
|
|
const scrollHandler = initScrollObserver(o2);
|
|
const viewportResizeHandler = initViewportResizeObserver(o2, {
|
|
win: currentWindow
|
|
});
|
|
const inputHandler = initInputObserver(o2);
|
|
const mediaInteractionHandler = initMediaInteractionObserver(o2);
|
|
let styleSheetObserver = () => {
|
|
};
|
|
let adoptedStyleSheetObserver = () => {
|
|
};
|
|
let styleDeclarationObserver = () => {
|
|
};
|
|
let fontObserver = () => {
|
|
};
|
|
if (o2.recordDOM) {
|
|
styleSheetObserver = initStyleSheetObserver(o2, { win: currentWindow });
|
|
adoptedStyleSheetObserver = initAdoptedStyleSheetObserver(o2, o2.doc);
|
|
styleDeclarationObserver = initStyleDeclarationObserver(o2, {
|
|
win: currentWindow
|
|
});
|
|
if (o2.collectFonts) {
|
|
fontObserver = initFontObserver(o2);
|
|
}
|
|
}
|
|
const selectionObserver = initSelectionObserver(o2);
|
|
const customElementObserver = initCustomElementObserver(o2);
|
|
const pluginHandlers = [];
|
|
for (const plugin of o2.plugins) {
|
|
pluginHandlers.push(
|
|
plugin.observer(plugin.callback, currentWindow, plugin.options)
|
|
);
|
|
}
|
|
return callbackWrapper(() => {
|
|
mutationBuffers.forEach((b) => b.reset());
|
|
mutationObserver == null ? void 0 : mutationObserver.disconnect();
|
|
mousemoveHandler();
|
|
mouseInteractionHandler();
|
|
scrollHandler();
|
|
viewportResizeHandler();
|
|
inputHandler();
|
|
mediaInteractionHandler();
|
|
styleSheetObserver();
|
|
adoptedStyleSheetObserver();
|
|
styleDeclarationObserver();
|
|
fontObserver();
|
|
selectionObserver();
|
|
customElementObserver();
|
|
pluginHandlers.forEach((h) => h());
|
|
});
|
|
}
|
|
function hasNestedCSSRule(prop) {
|
|
return typeof window[prop] !== "undefined";
|
|
}
|
|
function canMonkeyPatchNestedCSSRule(prop) {
|
|
return Boolean(
|
|
typeof window[prop] !== "undefined" && // Note: Generally, this check _shouldn't_ be necessary
|
|
// However, in some scenarios (e.g. jsdom) this can sometimes fail, so we check for it here
|
|
window[prop].prototype && "insertRule" in window[prop].prototype && "deleteRule" in window[prop].prototype
|
|
);
|
|
}
|
|
class CrossOriginIframeMirror {
|
|
constructor(generateIdFn) {
|
|
__publicField(this, "iframeIdToRemoteIdMap", /* @__PURE__ */ new WeakMap());
|
|
__publicField(this, "iframeRemoteIdToIdMap", /* @__PURE__ */ new WeakMap());
|
|
this.generateIdFn = generateIdFn;
|
|
}
|
|
getId(iframe, remoteId, idToRemoteMap, remoteToIdMap) {
|
|
const idToRemoteIdMap = idToRemoteMap || this.getIdToRemoteIdMap(iframe);
|
|
const remoteIdToIdMap = remoteToIdMap || this.getRemoteIdToIdMap(iframe);
|
|
let id = idToRemoteIdMap.get(remoteId);
|
|
if (!id) {
|
|
id = this.generateIdFn();
|
|
idToRemoteIdMap.set(remoteId, id);
|
|
remoteIdToIdMap.set(id, remoteId);
|
|
}
|
|
return id;
|
|
}
|
|
getIds(iframe, remoteId) {
|
|
const idToRemoteIdMap = this.getIdToRemoteIdMap(iframe);
|
|
const remoteIdToIdMap = this.getRemoteIdToIdMap(iframe);
|
|
return remoteId.map(
|
|
(id) => this.getId(iframe, id, idToRemoteIdMap, remoteIdToIdMap)
|
|
);
|
|
}
|
|
getRemoteId(iframe, id, map) {
|
|
const remoteIdToIdMap = map || this.getRemoteIdToIdMap(iframe);
|
|
if (typeof id !== "number") return id;
|
|
const remoteId = remoteIdToIdMap.get(id);
|
|
if (!remoteId) return -1;
|
|
return remoteId;
|
|
}
|
|
getRemoteIds(iframe, ids) {
|
|
const remoteIdToIdMap = this.getRemoteIdToIdMap(iframe);
|
|
return ids.map((id) => this.getRemoteId(iframe, id, remoteIdToIdMap));
|
|
}
|
|
reset(iframe) {
|
|
if (!iframe) {
|
|
this.iframeIdToRemoteIdMap = /* @__PURE__ */ new WeakMap();
|
|
this.iframeRemoteIdToIdMap = /* @__PURE__ */ new WeakMap();
|
|
return;
|
|
}
|
|
this.iframeIdToRemoteIdMap.delete(iframe);
|
|
this.iframeRemoteIdToIdMap.delete(iframe);
|
|
}
|
|
getIdToRemoteIdMap(iframe) {
|
|
let idToRemoteIdMap = this.iframeIdToRemoteIdMap.get(iframe);
|
|
if (!idToRemoteIdMap) {
|
|
idToRemoteIdMap = /* @__PURE__ */ new Map();
|
|
this.iframeIdToRemoteIdMap.set(iframe, idToRemoteIdMap);
|
|
}
|
|
return idToRemoteIdMap;
|
|
}
|
|
getRemoteIdToIdMap(iframe) {
|
|
let remoteIdToIdMap = this.iframeRemoteIdToIdMap.get(iframe);
|
|
if (!remoteIdToIdMap) {
|
|
remoteIdToIdMap = /* @__PURE__ */ new Map();
|
|
this.iframeRemoteIdToIdMap.set(iframe, remoteIdToIdMap);
|
|
}
|
|
return remoteIdToIdMap;
|
|
}
|
|
}
|
|
class IframeManager {
|
|
constructor(options) {
|
|
__publicField(this, "iframes", /* @__PURE__ */ new WeakMap());
|
|
__publicField(this, "crossOriginIframeMap", /* @__PURE__ */ new WeakMap());
|
|
__publicField(this, "crossOriginIframeMirror", new CrossOriginIframeMirror(genId));
|
|
__publicField(this, "crossOriginIframeStyleMirror");
|
|
__publicField(this, "crossOriginIframeRootIdMap", /* @__PURE__ */ new WeakMap());
|
|
__publicField(this, "mirror");
|
|
__publicField(this, "mutationCb");
|
|
__publicField(this, "wrappedEmit");
|
|
__publicField(this, "loadListener");
|
|
__publicField(this, "stylesheetManager");
|
|
__publicField(this, "recordCrossOriginIframes");
|
|
this.mutationCb = options.mutationCb;
|
|
this.wrappedEmit = options.wrappedEmit;
|
|
this.stylesheetManager = options.stylesheetManager;
|
|
this.recordCrossOriginIframes = options.recordCrossOriginIframes;
|
|
this.crossOriginIframeStyleMirror = new CrossOriginIframeMirror(
|
|
this.stylesheetManager.styleMirror.generateId.bind(
|
|
this.stylesheetManager.styleMirror
|
|
)
|
|
);
|
|
this.mirror = options.mirror;
|
|
if (this.recordCrossOriginIframes) {
|
|
window.addEventListener("message", this.handleMessage.bind(this));
|
|
}
|
|
}
|
|
addIframe(iframeEl) {
|
|
this.iframes.set(iframeEl, true);
|
|
if (iframeEl.contentWindow)
|
|
this.crossOriginIframeMap.set(iframeEl.contentWindow, iframeEl);
|
|
}
|
|
addLoadListener(cb) {
|
|
this.loadListener = cb;
|
|
}
|
|
attachIframe(iframeEl, childSn) {
|
|
var _a2, _b;
|
|
this.mutationCb({
|
|
adds: [
|
|
{
|
|
parentId: this.mirror.getId(iframeEl),
|
|
nextId: null,
|
|
node: childSn
|
|
}
|
|
],
|
|
removes: [],
|
|
texts: [],
|
|
attributes: [],
|
|
isAttachIframe: true
|
|
});
|
|
if (this.recordCrossOriginIframes)
|
|
(_a2 = iframeEl.contentWindow) == null ? void 0 : _a2.addEventListener(
|
|
"message",
|
|
this.handleMessage.bind(this)
|
|
);
|
|
(_b = this.loadListener) == null ? void 0 : _b.call(this, iframeEl);
|
|
if (iframeEl.contentDocument && iframeEl.contentDocument.adoptedStyleSheets && iframeEl.contentDocument.adoptedStyleSheets.length > 0)
|
|
this.stylesheetManager.adoptStyleSheets(
|
|
iframeEl.contentDocument.adoptedStyleSheets,
|
|
this.mirror.getId(iframeEl.contentDocument)
|
|
);
|
|
}
|
|
handleMessage(message) {
|
|
const crossOriginMessageEvent = message;
|
|
if (crossOriginMessageEvent.data.type !== "rrweb" || // To filter out the rrweb messages which are forwarded by some sites.
|
|
crossOriginMessageEvent.origin !== crossOriginMessageEvent.data.origin)
|
|
return;
|
|
const iframeSourceWindow = message.source;
|
|
if (!iframeSourceWindow) return;
|
|
const iframeEl = this.crossOriginIframeMap.get(message.source);
|
|
if (!iframeEl) return;
|
|
const transformedEvent = this.transformCrossOriginEvent(
|
|
iframeEl,
|
|
crossOriginMessageEvent.data.event
|
|
);
|
|
if (transformedEvent)
|
|
this.wrappedEmit(
|
|
transformedEvent,
|
|
crossOriginMessageEvent.data.isCheckout
|
|
);
|
|
}
|
|
transformCrossOriginEvent(iframeEl, e2) {
|
|
var _a2;
|
|
switch (e2.type) {
|
|
case EventType.FullSnapshot: {
|
|
this.crossOriginIframeMirror.reset(iframeEl);
|
|
this.crossOriginIframeStyleMirror.reset(iframeEl);
|
|
this.replaceIdOnNode(e2.data.node, iframeEl);
|
|
const rootId = e2.data.node.id;
|
|
this.crossOriginIframeRootIdMap.set(iframeEl, rootId);
|
|
this.patchRootIdOnNode(e2.data.node, rootId);
|
|
return {
|
|
timestamp: e2.timestamp,
|
|
type: EventType.IncrementalSnapshot,
|
|
data: {
|
|
source: IncrementalSource.Mutation,
|
|
adds: [
|
|
{
|
|
parentId: this.mirror.getId(iframeEl),
|
|
nextId: null,
|
|
node: e2.data.node
|
|
}
|
|
],
|
|
removes: [],
|
|
texts: [],
|
|
attributes: [],
|
|
isAttachIframe: true
|
|
}
|
|
};
|
|
}
|
|
case EventType.Meta:
|
|
case EventType.Load:
|
|
case EventType.DomContentLoaded: {
|
|
return false;
|
|
}
|
|
case EventType.Plugin: {
|
|
return e2;
|
|
}
|
|
case EventType.Custom: {
|
|
this.replaceIds(
|
|
e2.data.payload,
|
|
iframeEl,
|
|
["id", "parentId", "previousId", "nextId"]
|
|
);
|
|
return e2;
|
|
}
|
|
case EventType.IncrementalSnapshot: {
|
|
switch (e2.data.source) {
|
|
case IncrementalSource.Mutation: {
|
|
e2.data.adds.forEach((n2) => {
|
|
this.replaceIds(n2, iframeEl, [
|
|
"parentId",
|
|
"nextId",
|
|
"previousId"
|
|
]);
|
|
this.replaceIdOnNode(n2.node, iframeEl);
|
|
const rootId = this.crossOriginIframeRootIdMap.get(iframeEl);
|
|
rootId && this.patchRootIdOnNode(n2.node, rootId);
|
|
});
|
|
e2.data.removes.forEach((n2) => {
|
|
this.replaceIds(n2, iframeEl, ["parentId", "id"]);
|
|
});
|
|
e2.data.attributes.forEach((n2) => {
|
|
this.replaceIds(n2, iframeEl, ["id"]);
|
|
});
|
|
e2.data.texts.forEach((n2) => {
|
|
this.replaceIds(n2, iframeEl, ["id"]);
|
|
});
|
|
return e2;
|
|
}
|
|
case IncrementalSource.Drag:
|
|
case IncrementalSource.TouchMove:
|
|
case IncrementalSource.MouseMove: {
|
|
e2.data.positions.forEach((p) => {
|
|
this.replaceIds(p, iframeEl, ["id"]);
|
|
});
|
|
return e2;
|
|
}
|
|
case IncrementalSource.ViewportResize: {
|
|
return false;
|
|
}
|
|
case IncrementalSource.MediaInteraction:
|
|
case IncrementalSource.MouseInteraction:
|
|
case IncrementalSource.Scroll:
|
|
case IncrementalSource.CanvasMutation:
|
|
case IncrementalSource.Input: {
|
|
this.replaceIds(e2.data, iframeEl, ["id"]);
|
|
return e2;
|
|
}
|
|
case IncrementalSource.StyleSheetRule:
|
|
case IncrementalSource.StyleDeclaration: {
|
|
this.replaceIds(e2.data, iframeEl, ["id"]);
|
|
this.replaceStyleIds(e2.data, iframeEl, ["styleId"]);
|
|
return e2;
|
|
}
|
|
case IncrementalSource.Font: {
|
|
return e2;
|
|
}
|
|
case IncrementalSource.Selection: {
|
|
e2.data.ranges.forEach((range) => {
|
|
this.replaceIds(range, iframeEl, ["start", "end"]);
|
|
});
|
|
return e2;
|
|
}
|
|
case IncrementalSource.AdoptedStyleSheet: {
|
|
this.replaceIds(e2.data, iframeEl, ["id"]);
|
|
this.replaceStyleIds(e2.data, iframeEl, ["styleIds"]);
|
|
(_a2 = e2.data.styles) == null ? void 0 : _a2.forEach((style) => {
|
|
this.replaceStyleIds(style, iframeEl, ["styleId"]);
|
|
});
|
|
return e2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
replace(iframeMirror, obj, iframeEl, keys) {
|
|
for (const key of keys) {
|
|
if (!Array.isArray(obj[key]) && typeof obj[key] !== "number") continue;
|
|
if (Array.isArray(obj[key])) {
|
|
obj[key] = iframeMirror.getIds(
|
|
iframeEl,
|
|
obj[key]
|
|
);
|
|
} else {
|
|
obj[key] = iframeMirror.getId(iframeEl, obj[key]);
|
|
}
|
|
}
|
|
return obj;
|
|
}
|
|
replaceIds(obj, iframeEl, keys) {
|
|
return this.replace(this.crossOriginIframeMirror, obj, iframeEl, keys);
|
|
}
|
|
replaceStyleIds(obj, iframeEl, keys) {
|
|
return this.replace(this.crossOriginIframeStyleMirror, obj, iframeEl, keys);
|
|
}
|
|
replaceIdOnNode(node2, iframeEl) {
|
|
this.replaceIds(node2, iframeEl, ["id", "rootId"]);
|
|
if ("childNodes" in node2) {
|
|
node2.childNodes.forEach((child) => {
|
|
this.replaceIdOnNode(child, iframeEl);
|
|
});
|
|
}
|
|
}
|
|
patchRootIdOnNode(node2, rootId) {
|
|
if (node2.type !== NodeType.Document && !node2.rootId) node2.rootId = rootId;
|
|
if ("childNodes" in node2) {
|
|
node2.childNodes.forEach((child) => {
|
|
this.patchRootIdOnNode(child, rootId);
|
|
});
|
|
}
|
|
}
|
|
}
|
|
class ShadowDomManager {
|
|
constructor(options) {
|
|
__publicField(this, "shadowDoms", /* @__PURE__ */ new WeakSet());
|
|
__publicField(this, "mutationCb");
|
|
__publicField(this, "scrollCb");
|
|
__publicField(this, "bypassOptions");
|
|
__publicField(this, "mirror");
|
|
__publicField(this, "restoreHandlers", []);
|
|
this.mutationCb = options.mutationCb;
|
|
this.scrollCb = options.scrollCb;
|
|
this.bypassOptions = options.bypassOptions;
|
|
this.mirror = options.mirror;
|
|
this.init();
|
|
}
|
|
init() {
|
|
this.reset();
|
|
this.patchAttachShadow(Element, document);
|
|
}
|
|
addShadowRoot(shadowRoot2, doc) {
|
|
if (!isNativeShadowDom(shadowRoot2)) return;
|
|
if (this.shadowDoms.has(shadowRoot2)) return;
|
|
this.shadowDoms.add(shadowRoot2);
|
|
const observer = initMutationObserver(
|
|
__spreadProps(__spreadValues({}, this.bypassOptions), {
|
|
doc,
|
|
mutationCb: this.mutationCb,
|
|
mirror: this.mirror,
|
|
shadowDomManager: this
|
|
}),
|
|
shadowRoot2
|
|
);
|
|
this.restoreHandlers.push(() => observer.disconnect());
|
|
this.restoreHandlers.push(
|
|
initScrollObserver(__spreadProps(__spreadValues({}, this.bypassOptions), {
|
|
scrollCb: this.scrollCb,
|
|
// https://gist.github.com/praveenpuglia/0832da687ed5a5d7a0907046c9ef1813
|
|
// scroll is not allowed to pass the boundary, so we need to listen the shadow document
|
|
doc: shadowRoot2,
|
|
mirror: this.mirror
|
|
}))
|
|
);
|
|
setTimeout(() => {
|
|
if (shadowRoot2.adoptedStyleSheets && shadowRoot2.adoptedStyleSheets.length > 0)
|
|
this.bypassOptions.stylesheetManager.adoptStyleSheets(
|
|
shadowRoot2.adoptedStyleSheets,
|
|
this.mirror.getId(index.host(shadowRoot2))
|
|
);
|
|
this.restoreHandlers.push(
|
|
initAdoptedStyleSheetObserver(
|
|
{
|
|
mirror: this.mirror,
|
|
stylesheetManager: this.bypassOptions.stylesheetManager
|
|
},
|
|
shadowRoot2
|
|
)
|
|
);
|
|
}, 0);
|
|
}
|
|
/**
|
|
* Monkey patch 'attachShadow' of an IFrameElement to observe newly added shadow doms.
|
|
*/
|
|
observeAttachShadow(iframeElement) {
|
|
if (!iframeElement.contentWindow || !iframeElement.contentDocument) return;
|
|
this.patchAttachShadow(
|
|
iframeElement.contentWindow.Element,
|
|
iframeElement.contentDocument
|
|
);
|
|
}
|
|
/**
|
|
* Patch 'attachShadow' to observe newly added shadow doms.
|
|
*/
|
|
patchAttachShadow(element, doc) {
|
|
const manager = this;
|
|
this.restoreHandlers.push(
|
|
patch(
|
|
element.prototype,
|
|
"attachShadow",
|
|
function(original) {
|
|
return function(option) {
|
|
const sRoot = original.call(this, option);
|
|
const shadowRootEl = index.shadowRoot(this);
|
|
if (shadowRootEl && inDom(this))
|
|
manager.addShadowRoot(shadowRootEl, doc);
|
|
return sRoot;
|
|
};
|
|
}
|
|
)
|
|
);
|
|
}
|
|
reset() {
|
|
this.restoreHandlers.forEach((handler) => {
|
|
try {
|
|
handler();
|
|
} catch (e2) {
|
|
}
|
|
});
|
|
this.restoreHandlers = [];
|
|
this.shadowDoms = /* @__PURE__ */ new WeakSet();
|
|
}
|
|
}
|
|
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
var lookup = typeof Uint8Array === "undefined" ? [] : new Uint8Array(256);
|
|
for (var i$1 = 0; i$1 < chars.length; i$1++) {
|
|
lookup[chars.charCodeAt(i$1)] = i$1;
|
|
}
|
|
var encode = function(arraybuffer) {
|
|
var bytes = new Uint8Array(arraybuffer), i2, len = bytes.length, base64 = "";
|
|
for (i2 = 0; i2 < len; i2 += 3) {
|
|
base64 += chars[bytes[i2] >> 2];
|
|
base64 += chars[(bytes[i2] & 3) << 4 | bytes[i2 + 1] >> 4];
|
|
base64 += chars[(bytes[i2 + 1] & 15) << 2 | bytes[i2 + 2] >> 6];
|
|
base64 += chars[bytes[i2 + 2] & 63];
|
|
}
|
|
if (len % 3 === 2) {
|
|
base64 = base64.substring(0, base64.length - 1) + "=";
|
|
} else if (len % 3 === 1) {
|
|
base64 = base64.substring(0, base64.length - 2) + "==";
|
|
}
|
|
return base64;
|
|
};
|
|
const canvasVarMap = /* @__PURE__ */ new Map();
|
|
function variableListFor$1(ctx, ctor) {
|
|
let contextMap = canvasVarMap.get(ctx);
|
|
if (!contextMap) {
|
|
contextMap = /* @__PURE__ */ new Map();
|
|
canvasVarMap.set(ctx, contextMap);
|
|
}
|
|
if (!contextMap.has(ctor)) {
|
|
contextMap.set(ctor, []);
|
|
}
|
|
return contextMap.get(ctor);
|
|
}
|
|
const saveWebGLVar = (value, win, ctx) => {
|
|
if (!value || !(isInstanceOfWebGLObject(value, win) || typeof value === "object"))
|
|
return;
|
|
const name = value.constructor.name;
|
|
const list = variableListFor$1(ctx, name);
|
|
let index2 = list.indexOf(value);
|
|
if (index2 === -1) {
|
|
index2 = list.length;
|
|
list.push(value);
|
|
}
|
|
return index2;
|
|
};
|
|
function serializeArg(value, win, ctx) {
|
|
if (value instanceof Array) {
|
|
return value.map((arg) => serializeArg(arg, win, ctx));
|
|
} else if (value === null) {
|
|
return value;
|
|
} else if (value instanceof Float32Array || value instanceof Float64Array || value instanceof Int32Array || value instanceof Uint32Array || value instanceof Uint8Array || value instanceof Uint16Array || value instanceof Int16Array || value instanceof Int8Array || value instanceof Uint8ClampedArray) {
|
|
const name = value.constructor.name;
|
|
return {
|
|
rr_type: name,
|
|
args: [Object.values(value)]
|
|
};
|
|
} else if (
|
|
// SharedArrayBuffer disabled on most browsers due to spectre.
|
|
// More info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/SharedArrayBuffer
|
|
// value instanceof SharedArrayBuffer ||
|
|
value instanceof ArrayBuffer
|
|
) {
|
|
const name = value.constructor.name;
|
|
const base64 = encode(value);
|
|
return {
|
|
rr_type: name,
|
|
base64
|
|
};
|
|
} else if (value instanceof DataView) {
|
|
const name = value.constructor.name;
|
|
return {
|
|
rr_type: name,
|
|
args: [
|
|
serializeArg(value.buffer, win, ctx),
|
|
value.byteOffset,
|
|
value.byteLength
|
|
]
|
|
};
|
|
} else if (value instanceof HTMLImageElement) {
|
|
const name = value.constructor.name;
|
|
const { src } = value;
|
|
return {
|
|
rr_type: name,
|
|
src
|
|
};
|
|
} else if (value instanceof HTMLCanvasElement) {
|
|
const name = "HTMLImageElement";
|
|
const src = value.toDataURL();
|
|
return {
|
|
rr_type: name,
|
|
src
|
|
};
|
|
} else if (value instanceof ImageData) {
|
|
const name = value.constructor.name;
|
|
return {
|
|
rr_type: name,
|
|
args: [serializeArg(value.data, win, ctx), value.width, value.height]
|
|
};
|
|
} else if (isInstanceOfWebGLObject(value, win) || typeof value === "object") {
|
|
const name = value.constructor.name;
|
|
const index2 = saveWebGLVar(value, win, ctx);
|
|
return {
|
|
rr_type: name,
|
|
index: index2
|
|
};
|
|
}
|
|
return value;
|
|
}
|
|
const serializeArgs = (args, win, ctx) => {
|
|
return args.map((arg) => serializeArg(arg, win, ctx));
|
|
};
|
|
const isInstanceOfWebGLObject = (value, win) => {
|
|
const webGLConstructorNames = [
|
|
"WebGLActiveInfo",
|
|
"WebGLBuffer",
|
|
"WebGLFramebuffer",
|
|
"WebGLProgram",
|
|
"WebGLRenderbuffer",
|
|
"WebGLShader",
|
|
"WebGLShaderPrecisionFormat",
|
|
"WebGLTexture",
|
|
"WebGLUniformLocation",
|
|
"WebGLVertexArrayObject",
|
|
// In old Chrome versions, value won't be an instanceof WebGLVertexArrayObject.
|
|
"WebGLVertexArrayObjectOES"
|
|
];
|
|
const supportedWebGLConstructorNames = webGLConstructorNames.filter(
|
|
(name) => typeof win[name] === "function"
|
|
);
|
|
return Boolean(
|
|
supportedWebGLConstructorNames.find(
|
|
(name) => value instanceof win[name]
|
|
)
|
|
);
|
|
};
|
|
function initCanvas2DMutationObserver(cb, win, blockClass, blockSelector) {
|
|
const handlers = [];
|
|
const props2D = Object.getOwnPropertyNames(
|
|
win.CanvasRenderingContext2D.prototype
|
|
);
|
|
for (const prop of props2D) {
|
|
try {
|
|
if (typeof win.CanvasRenderingContext2D.prototype[prop] !== "function") {
|
|
continue;
|
|
}
|
|
const restoreHandler = patch(
|
|
win.CanvasRenderingContext2D.prototype,
|
|
prop,
|
|
function(original) {
|
|
return function(...args) {
|
|
if (!isBlocked(this.canvas, blockClass, blockSelector, true)) {
|
|
setTimeout(() => {
|
|
const recordArgs = serializeArgs(args, win, this);
|
|
cb(this.canvas, {
|
|
type: CanvasContext["2D"],
|
|
property: prop,
|
|
args: recordArgs
|
|
});
|
|
}, 0);
|
|
}
|
|
return original.apply(this, args);
|
|
};
|
|
}
|
|
);
|
|
handlers.push(restoreHandler);
|
|
} catch (e) {
|
|
const hookHandler = hookSetter(
|
|
win.CanvasRenderingContext2D.prototype,
|
|
prop,
|
|
{
|
|
set(v2) {
|
|
cb(this.canvas, {
|
|
type: CanvasContext["2D"],
|
|
property: prop,
|
|
args: [v2],
|
|
setter: true
|
|
});
|
|
}
|
|
}
|
|
);
|
|
handlers.push(hookHandler);
|
|
}
|
|
}
|
|
return () => {
|
|
handlers.forEach((h) => h());
|
|
};
|
|
}
|
|
function getNormalizedContextName(contextType) {
|
|
return contextType === "experimental-webgl" ? "webgl" : contextType;
|
|
}
|
|
function initCanvasContextObserver(win, blockClass, blockSelector, setPreserveDrawingBufferToTrue) {
|
|
const handlers = [];
|
|
try {
|
|
const restoreHandler = patch(
|
|
win.HTMLCanvasElement.prototype,
|
|
"getContext",
|
|
function(original) {
|
|
return function(contextType, ...args) {
|
|
if (!isBlocked(this, blockClass, blockSelector, true)) {
|
|
const ctxName = getNormalizedContextName(contextType);
|
|
if (!("__context" in this)) this.__context = ctxName;
|
|
if (setPreserveDrawingBufferToTrue && ["webgl", "webgl2"].includes(ctxName)) {
|
|
if (args[0] && typeof args[0] === "object") {
|
|
const contextAttributes = args[0];
|
|
if (!contextAttributes.preserveDrawingBuffer) {
|
|
contextAttributes.preserveDrawingBuffer = true;
|
|
}
|
|
} else {
|
|
args.splice(0, 1, {
|
|
preserveDrawingBuffer: true
|
|
});
|
|
}
|
|
}
|
|
}
|
|
return original.apply(this, [contextType, ...args]);
|
|
};
|
|
}
|
|
);
|
|
handlers.push(restoreHandler);
|
|
} catch (e) {
|
|
console.error("failed to patch HTMLCanvasElement.prototype.getContext");
|
|
}
|
|
return () => {
|
|
handlers.forEach((h) => h());
|
|
};
|
|
}
|
|
function patchGLPrototype(prototype, type, cb, blockClass, blockSelector, win) {
|
|
const handlers = [];
|
|
const props = Object.getOwnPropertyNames(prototype);
|
|
for (const prop of props) {
|
|
if (
|
|
//prop.startsWith('get') || // e.g. getProgramParameter, but too risky
|
|
[
|
|
"isContextLost",
|
|
"canvas",
|
|
"drawingBufferWidth",
|
|
"drawingBufferHeight"
|
|
].includes(prop)
|
|
) {
|
|
continue;
|
|
}
|
|
try {
|
|
if (typeof prototype[prop] !== "function") {
|
|
continue;
|
|
}
|
|
const restoreHandler = patch(
|
|
prototype,
|
|
prop,
|
|
function(original) {
|
|
return function(...args) {
|
|
const result2 = original.apply(this, args);
|
|
saveWebGLVar(result2, win, this);
|
|
if ("tagName" in this.canvas && !isBlocked(this.canvas, blockClass, blockSelector, true)) {
|
|
const recordArgs = serializeArgs(args, win, this);
|
|
const mutation = {
|
|
type,
|
|
property: prop,
|
|
args: recordArgs
|
|
};
|
|
cb(this.canvas, mutation);
|
|
}
|
|
return result2;
|
|
};
|
|
}
|
|
);
|
|
handlers.push(restoreHandler);
|
|
} catch (e) {
|
|
const hookHandler = hookSetter(prototype, prop, {
|
|
set(v2) {
|
|
cb(this.canvas, {
|
|
type,
|
|
property: prop,
|
|
args: [v2],
|
|
setter: true
|
|
});
|
|
}
|
|
});
|
|
handlers.push(hookHandler);
|
|
}
|
|
}
|
|
return handlers;
|
|
}
|
|
function initCanvasWebGLMutationObserver(cb, win, blockClass, blockSelector) {
|
|
const handlers = [];
|
|
if (typeof win.WebGLRenderingContext !== "undefined") {
|
|
handlers.push(
|
|
...patchGLPrototype(
|
|
win.WebGLRenderingContext.prototype,
|
|
CanvasContext.WebGL,
|
|
cb,
|
|
blockClass,
|
|
blockSelector,
|
|
win
|
|
)
|
|
);
|
|
}
|
|
if (typeof win.WebGL2RenderingContext !== "undefined") {
|
|
handlers.push(
|
|
...patchGLPrototype(
|
|
win.WebGL2RenderingContext.prototype,
|
|
CanvasContext.WebGL2,
|
|
cb,
|
|
blockClass,
|
|
blockSelector,
|
|
win
|
|
)
|
|
);
|
|
}
|
|
return () => {
|
|
handlers.forEach((h) => h());
|
|
};
|
|
}
|
|
const jsContent = '(function() {\n "use strict";\n var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";\n var lookup = typeof Uint8Array === "undefined" ? [] : new Uint8Array(256);\n for (var i = 0; i < chars.length; i++) {\n lookup[chars.charCodeAt(i)] = i;\n }\n var encode = function(arraybuffer) {\n var bytes = new Uint8Array(arraybuffer), i2, len = bytes.length, base64 = "";\n for (i2 = 0; i2 < len; i2 += 3) {\n base64 += chars[bytes[i2] >> 2];\n base64 += chars[(bytes[i2] & 3) << 4 | bytes[i2 + 1] >> 4];\n base64 += chars[(bytes[i2 + 1] & 15) << 2 | bytes[i2 + 2] >> 6];\n base64 += chars[bytes[i2 + 2] & 63];\n }\n if (len % 3 === 2) {\n base64 = base64.substring(0, base64.length - 1) + "=";\n } else if (len % 3 === 1) {\n base64 = base64.substring(0, base64.length - 2) + "==";\n }\n return base64;\n };\n const lastBlobMap = /* @__PURE__ */ new Map();\n const transparentBlobMap = /* @__PURE__ */ new Map();\n async function getTransparentBlobFor(width, height, dataURLOptions) {\n const id = `${width}-${height}`;\n if ("OffscreenCanvas" in globalThis) {\n if (transparentBlobMap.has(id)) return transparentBlobMap.get(id);\n const offscreen = new OffscreenCanvas(width, height);\n offscreen.getContext("2d");\n const blob = await offscreen.convertToBlob(dataURLOptions);\n const arrayBuffer = await blob.arrayBuffer();\n const base64 = encode(arrayBuffer);\n transparentBlobMap.set(id, base64);\n return base64;\n } else {\n return "";\n }\n }\n const worker = self;\n worker.onmessage = async function(e) {\n if ("OffscreenCanvas" in globalThis) {\n const { id, bitmap, width, height, dataURLOptions } = e.data;\n const transparentBase64 = getTransparentBlobFor(\n width,\n height,\n dataURLOptions\n );\n const offscreen = new OffscreenCanvas(width, height);\n const ctx = offscreen.getContext("2d");\n ctx.drawImage(bitmap, 0, 0);\n bitmap.close();\n const blob = await offscreen.convertToBlob(dataURLOptions);\n const type = blob.type;\n const arrayBuffer = await blob.arrayBuffer();\n const base64 = encode(arrayBuffer);\n if (!lastBlobMap.has(id) && await transparentBase64 === base64) {\n lastBlobMap.set(id, base64);\n return worker.postMessage({ id });\n }\n if (lastBlobMap.get(id) === base64) return worker.postMessage({ id });\n worker.postMessage({\n id,\n type,\n base64,\n width,\n height\n });\n lastBlobMap.set(id, base64);\n } else {\n return worker.postMessage({ id: e.data.id });\n }\n };\n})();\n//# sourceMappingURL=image-bitmap-data-url-worker-IJpC7g_b.js.map\n';
|
|
const blob = typeof self !== "undefined" && self.Blob && new Blob([jsContent], { type: "text/javascript;charset=utf-8" });
|
|
function WorkerWrapper(options) {
|
|
let objURL;
|
|
try {
|
|
objURL = blob && (self.URL || self.webkitURL).createObjectURL(blob);
|
|
if (!objURL) throw "";
|
|
const worker = new Worker(objURL, {
|
|
name: options == null ? void 0 : options.name
|
|
});
|
|
worker.addEventListener("error", () => {
|
|
(self.URL || self.webkitURL).revokeObjectURL(objURL);
|
|
});
|
|
return worker;
|
|
} catch (e2) {
|
|
return new Worker(
|
|
"data:text/javascript;charset=utf-8," + encodeURIComponent(jsContent),
|
|
{
|
|
name: options == null ? void 0 : options.name
|
|
}
|
|
);
|
|
} finally {
|
|
objURL && (self.URL || self.webkitURL).revokeObjectURL(objURL);
|
|
}
|
|
}
|
|
class CanvasManager {
|
|
constructor(options) {
|
|
__publicField(this, "pendingCanvasMutations", /* @__PURE__ */ new Map());
|
|
__publicField(this, "rafStamps", { latestId: 0, invokeId: null });
|
|
__publicField(this, "mirror");
|
|
__publicField(this, "mutationCb");
|
|
__publicField(this, "resetObservers");
|
|
__publicField(this, "frozen", false);
|
|
__publicField(this, "locked", false);
|
|
__publicField(this, "processMutation", (target, mutation) => {
|
|
const newFrame = this.rafStamps.invokeId && this.rafStamps.latestId !== this.rafStamps.invokeId;
|
|
if (newFrame || !this.rafStamps.invokeId)
|
|
this.rafStamps.invokeId = this.rafStamps.latestId;
|
|
if (!this.pendingCanvasMutations.has(target)) {
|
|
this.pendingCanvasMutations.set(target, []);
|
|
}
|
|
this.pendingCanvasMutations.get(target).push(mutation);
|
|
});
|
|
const {
|
|
sampling = "all",
|
|
win,
|
|
blockClass,
|
|
blockSelector,
|
|
recordCanvas,
|
|
dataURLOptions
|
|
} = options;
|
|
this.mutationCb = options.mutationCb;
|
|
this.mirror = options.mirror;
|
|
if (recordCanvas && sampling === "all")
|
|
this.initCanvasMutationObserver(win, blockClass, blockSelector);
|
|
if (recordCanvas && typeof sampling === "number")
|
|
this.initCanvasFPSObserver(sampling, win, blockClass, blockSelector, {
|
|
dataURLOptions
|
|
});
|
|
}
|
|
reset() {
|
|
this.pendingCanvasMutations.clear();
|
|
this.resetObservers && this.resetObservers();
|
|
}
|
|
freeze() {
|
|
this.frozen = true;
|
|
}
|
|
unfreeze() {
|
|
this.frozen = false;
|
|
}
|
|
lock() {
|
|
this.locked = true;
|
|
}
|
|
unlock() {
|
|
this.locked = false;
|
|
}
|
|
initCanvasFPSObserver(fps, win, blockClass, blockSelector, options) {
|
|
const canvasContextReset = initCanvasContextObserver(
|
|
win,
|
|
blockClass,
|
|
blockSelector,
|
|
true
|
|
);
|
|
const snapshotInProgressMap = /* @__PURE__ */ new Map();
|
|
const worker = new WorkerWrapper();
|
|
worker.onmessage = (e2) => {
|
|
const { id } = e2.data;
|
|
snapshotInProgressMap.set(id, false);
|
|
if (!("base64" in e2.data)) return;
|
|
const { base64, type, width, height } = e2.data;
|
|
this.mutationCb({
|
|
id,
|
|
type: CanvasContext["2D"],
|
|
commands: [
|
|
{
|
|
property: "clearRect",
|
|
// wipe canvas
|
|
args: [0, 0, width, height]
|
|
},
|
|
{
|
|
property: "drawImage",
|
|
// draws (semi-transparent) image
|
|
args: [
|
|
{
|
|
rr_type: "ImageBitmap",
|
|
args: [
|
|
{
|
|
rr_type: "Blob",
|
|
data: [{ rr_type: "ArrayBuffer", base64 }],
|
|
type
|
|
}
|
|
]
|
|
},
|
|
0,
|
|
0
|
|
]
|
|
}
|
|
]
|
|
});
|
|
};
|
|
const timeBetweenSnapshots = 1e3 / fps;
|
|
let lastSnapshotTime = 0;
|
|
let rafId;
|
|
const getCanvas = () => {
|
|
const matchedCanvas = [];
|
|
win.document.querySelectorAll("canvas").forEach((canvas) => {
|
|
if (!isBlocked(canvas, blockClass, blockSelector, true)) {
|
|
matchedCanvas.push(canvas);
|
|
}
|
|
});
|
|
return matchedCanvas;
|
|
};
|
|
const takeCanvasSnapshots = (timestamp) => {
|
|
if (lastSnapshotTime && timestamp - lastSnapshotTime < timeBetweenSnapshots) {
|
|
rafId = requestAnimationFrame(takeCanvasSnapshots);
|
|
return;
|
|
}
|
|
lastSnapshotTime = timestamp;
|
|
getCanvas().forEach(async (canvas) => {
|
|
var _a2;
|
|
const id = this.mirror.getId(canvas);
|
|
if (snapshotInProgressMap.get(id)) return;
|
|
if (canvas.width === 0 || canvas.height === 0) return;
|
|
snapshotInProgressMap.set(id, true);
|
|
if (["webgl", "webgl2"].includes(canvas.__context)) {
|
|
const context = canvas.getContext(canvas.__context);
|
|
if (((_a2 = context == null ? void 0 : context.getContextAttributes()) == null ? void 0 : _a2.preserveDrawingBuffer) === false) {
|
|
context.clear(context.COLOR_BUFFER_BIT);
|
|
}
|
|
}
|
|
const bitmap = await createImageBitmap(canvas);
|
|
worker.postMessage(
|
|
{
|
|
id,
|
|
bitmap,
|
|
width: canvas.width,
|
|
height: canvas.height,
|
|
dataURLOptions: options.dataURLOptions
|
|
},
|
|
[bitmap]
|
|
);
|
|
});
|
|
rafId = requestAnimationFrame(takeCanvasSnapshots);
|
|
};
|
|
rafId = requestAnimationFrame(takeCanvasSnapshots);
|
|
this.resetObservers = () => {
|
|
canvasContextReset();
|
|
cancelAnimationFrame(rafId);
|
|
};
|
|
}
|
|
initCanvasMutationObserver(win, blockClass, blockSelector) {
|
|
this.startRAFTimestamping();
|
|
this.startPendingCanvasMutationFlusher();
|
|
const canvasContextReset = initCanvasContextObserver(
|
|
win,
|
|
blockClass,
|
|
blockSelector,
|
|
false
|
|
);
|
|
const canvas2DReset = initCanvas2DMutationObserver(
|
|
this.processMutation.bind(this),
|
|
win,
|
|
blockClass,
|
|
blockSelector
|
|
);
|
|
const canvasWebGL1and2Reset = initCanvasWebGLMutationObserver(
|
|
this.processMutation.bind(this),
|
|
win,
|
|
blockClass,
|
|
blockSelector
|
|
);
|
|
this.resetObservers = () => {
|
|
canvasContextReset();
|
|
canvas2DReset();
|
|
canvasWebGL1and2Reset();
|
|
};
|
|
}
|
|
startPendingCanvasMutationFlusher() {
|
|
requestAnimationFrame(() => this.flushPendingCanvasMutations());
|
|
}
|
|
startRAFTimestamping() {
|
|
const setLatestRAFTimestamp = (timestamp) => {
|
|
this.rafStamps.latestId = timestamp;
|
|
requestAnimationFrame(setLatestRAFTimestamp);
|
|
};
|
|
requestAnimationFrame(setLatestRAFTimestamp);
|
|
}
|
|
flushPendingCanvasMutations() {
|
|
this.pendingCanvasMutations.forEach(
|
|
(_values, canvas) => {
|
|
const id = this.mirror.getId(canvas);
|
|
this.flushPendingCanvasMutationFor(canvas, id);
|
|
}
|
|
);
|
|
requestAnimationFrame(() => this.flushPendingCanvasMutations());
|
|
}
|
|
flushPendingCanvasMutationFor(canvas, id) {
|
|
if (this.frozen || this.locked) {
|
|
return;
|
|
}
|
|
const valuesWithType = this.pendingCanvasMutations.get(canvas);
|
|
if (!valuesWithType || id === -1) return;
|
|
const values = valuesWithType.map((value) => {
|
|
const _a2 = value, { type: type2 } = _a2, rest = __objRest(_a2, ["type"]);
|
|
return rest;
|
|
});
|
|
const { type } = valuesWithType[0];
|
|
this.mutationCb({ id, type, commands: values });
|
|
this.pendingCanvasMutations.delete(canvas);
|
|
}
|
|
}
|
|
class StylesheetManager {
|
|
constructor(options) {
|
|
__publicField(this, "trackedLinkElements", /* @__PURE__ */ new WeakSet());
|
|
__publicField(this, "mutationCb");
|
|
__publicField(this, "adoptedStyleSheetCb");
|
|
__publicField(this, "styleMirror", new StyleSheetMirror());
|
|
this.mutationCb = options.mutationCb;
|
|
this.adoptedStyleSheetCb = options.adoptedStyleSheetCb;
|
|
}
|
|
attachLinkElement(linkEl, childSn) {
|
|
if ("_cssText" in childSn.attributes)
|
|
this.mutationCb({
|
|
adds: [],
|
|
removes: [],
|
|
texts: [],
|
|
attributes: [
|
|
{
|
|
id: childSn.id,
|
|
attributes: childSn.attributes
|
|
}
|
|
]
|
|
});
|
|
this.trackLinkElement(linkEl);
|
|
}
|
|
trackLinkElement(linkEl) {
|
|
if (this.trackedLinkElements.has(linkEl)) return;
|
|
this.trackedLinkElements.add(linkEl);
|
|
this.trackStylesheetInLinkElement(linkEl);
|
|
}
|
|
adoptStyleSheets(sheets, hostId) {
|
|
if (sheets.length === 0) return;
|
|
const adoptedStyleSheetData = {
|
|
id: hostId,
|
|
styleIds: []
|
|
};
|
|
const styles = [];
|
|
for (const sheet of sheets) {
|
|
let styleId;
|
|
if (!this.styleMirror.has(sheet)) {
|
|
styleId = this.styleMirror.add(sheet);
|
|
styles.push({
|
|
styleId,
|
|
rules: Array.from(sheet.rules || CSSRule, (r2, index2) => ({
|
|
rule: stringifyRule(r2, sheet.href),
|
|
index: index2
|
|
}))
|
|
});
|
|
} else styleId = this.styleMirror.getId(sheet);
|
|
adoptedStyleSheetData.styleIds.push(styleId);
|
|
}
|
|
if (styles.length > 0) adoptedStyleSheetData.styles = styles;
|
|
this.adoptedStyleSheetCb(adoptedStyleSheetData);
|
|
}
|
|
reset() {
|
|
this.styleMirror.reset();
|
|
this.trackedLinkElements = /* @__PURE__ */ new WeakSet();
|
|
}
|
|
// TODO: take snapshot on stylesheet reload by applying event listener
|
|
trackStylesheetInLinkElement(_linkEl) {
|
|
}
|
|
}
|
|
class ProcessedNodeManager {
|
|
constructor() {
|
|
__publicField(this, "nodeMap", /* @__PURE__ */ new WeakMap());
|
|
__publicField(this, "active", false);
|
|
}
|
|
inOtherBuffer(node2, thisBuffer) {
|
|
const buffers = this.nodeMap.get(node2);
|
|
return buffers && Array.from(buffers).some((buffer) => buffer !== thisBuffer);
|
|
}
|
|
add(node2, buffer) {
|
|
if (!this.active) {
|
|
this.active = true;
|
|
requestAnimationFrame(() => {
|
|
this.nodeMap = /* @__PURE__ */ new WeakMap();
|
|
this.active = false;
|
|
});
|
|
}
|
|
this.nodeMap.set(node2, (this.nodeMap.get(node2) || /* @__PURE__ */ new Set()).add(buffer));
|
|
}
|
|
destroy() {
|
|
}
|
|
}
|
|
let wrappedEmit;
|
|
let takeFullSnapshot$1;
|
|
let canvasManager;
|
|
let recording = false;
|
|
try {
|
|
if (Array.from([1], (x) => x * 2)[0] !== 2) {
|
|
const cleanFrame = document.createElement("iframe");
|
|
document.body.appendChild(cleanFrame);
|
|
Array.from = ((_a = cleanFrame.contentWindow) == null ? void 0 : _a.Array.from) || Array.from;
|
|
document.body.removeChild(cleanFrame);
|
|
}
|
|
} catch (err) {
|
|
console.debug("Unable to override Array.from", err);
|
|
}
|
|
const mirror = createMirror$2();
|
|
function record(options = {}) {
|
|
const {
|
|
emit,
|
|
checkoutEveryNms,
|
|
checkoutEveryNth,
|
|
blockClass = "rr-block",
|
|
blockSelector = null,
|
|
ignoreClass = "rr-ignore",
|
|
ignoreSelector = null,
|
|
maskTextClass = "rr-mask",
|
|
maskTextSelector = null,
|
|
inlineStylesheet = true,
|
|
maskAllInputs,
|
|
maskInputOptions: _maskInputOptions,
|
|
slimDOMOptions: _slimDOMOptions,
|
|
maskInputFn,
|
|
maskTextFn,
|
|
hooks,
|
|
packFn,
|
|
sampling = {},
|
|
dataURLOptions = {},
|
|
mousemoveWait,
|
|
recordDOM = true,
|
|
recordCanvas = false,
|
|
recordCrossOriginIframes = false,
|
|
recordAfter = options.recordAfter === "DOMContentLoaded" ? options.recordAfter : "load",
|
|
userTriggeredOnInput = false,
|
|
collectFonts = false,
|
|
inlineImages = false,
|
|
plugins,
|
|
keepIframeSrcFn = () => false,
|
|
ignoreCSSAttributes = /* @__PURE__ */ new Set([]),
|
|
errorHandler: errorHandler2
|
|
} = options;
|
|
registerErrorHandler(errorHandler2);
|
|
const inEmittingFrame = recordCrossOriginIframes ? window.parent === window : true;
|
|
let passEmitsToParent = false;
|
|
if (!inEmittingFrame) {
|
|
try {
|
|
if (window.parent.document) {
|
|
passEmitsToParent = false;
|
|
}
|
|
} catch (e2) {
|
|
passEmitsToParent = true;
|
|
}
|
|
}
|
|
if (inEmittingFrame && !emit) {
|
|
throw new Error("emit function is required");
|
|
}
|
|
if (!inEmittingFrame && !passEmitsToParent) {
|
|
return () => {
|
|
};
|
|
}
|
|
if (mousemoveWait !== void 0 && sampling.mousemove === void 0) {
|
|
sampling.mousemove = mousemoveWait;
|
|
}
|
|
mirror.reset();
|
|
const maskInputOptions = maskAllInputs === true ? {
|
|
color: true,
|
|
date: true,
|
|
"datetime-local": true,
|
|
email: true,
|
|
month: true,
|
|
number: true,
|
|
range: true,
|
|
search: true,
|
|
tel: true,
|
|
text: true,
|
|
time: true,
|
|
url: true,
|
|
week: true,
|
|
textarea: true,
|
|
select: true,
|
|
password: true
|
|
} : _maskInputOptions !== void 0 ? _maskInputOptions : { password: true };
|
|
const slimDOMOptions = slimDOMDefaults(_slimDOMOptions);
|
|
polyfill$1();
|
|
let lastFullSnapshotEvent;
|
|
let incrementalSnapshotCount = 0;
|
|
const eventProcessor = (e2) => {
|
|
for (const plugin of plugins || []) {
|
|
if (plugin.eventProcessor) {
|
|
e2 = plugin.eventProcessor(e2);
|
|
}
|
|
}
|
|
if (packFn && // Disable packing events which will be emitted to parent frames.
|
|
!passEmitsToParent) {
|
|
e2 = packFn(e2);
|
|
}
|
|
return e2;
|
|
};
|
|
wrappedEmit = (r2, isCheckout) => {
|
|
var _a2;
|
|
const e2 = r2;
|
|
e2.timestamp = nowTimestamp();
|
|
if (((_a2 = mutationBuffers[0]) == null ? void 0 : _a2.isFrozen()) && e2.type !== EventType.FullSnapshot && !(e2.type === EventType.IncrementalSnapshot && e2.data.source === IncrementalSource.Mutation)) {
|
|
mutationBuffers.forEach((buf) => buf.unfreeze());
|
|
}
|
|
if (inEmittingFrame) {
|
|
emit == null ? void 0 : emit(eventProcessor(e2), isCheckout);
|
|
} else if (passEmitsToParent) {
|
|
const message = {
|
|
type: "rrweb",
|
|
event: eventProcessor(e2),
|
|
origin: window.location.origin,
|
|
isCheckout
|
|
};
|
|
window.parent.postMessage(message, "*");
|
|
}
|
|
if (e2.type === EventType.FullSnapshot) {
|
|
lastFullSnapshotEvent = e2;
|
|
incrementalSnapshotCount = 0;
|
|
} else if (e2.type === EventType.IncrementalSnapshot) {
|
|
if (e2.data.source === IncrementalSource.Mutation && e2.data.isAttachIframe) {
|
|
return;
|
|
}
|
|
incrementalSnapshotCount++;
|
|
const exceedCount = checkoutEveryNth && incrementalSnapshotCount >= checkoutEveryNth;
|
|
const exceedTime = checkoutEveryNms && e2.timestamp - lastFullSnapshotEvent.timestamp > checkoutEveryNms;
|
|
if (exceedCount || exceedTime) {
|
|
takeFullSnapshot$1(true);
|
|
}
|
|
}
|
|
};
|
|
const wrappedMutationEmit = (m) => {
|
|
wrappedEmit({
|
|
type: EventType.IncrementalSnapshot,
|
|
data: __spreadValues({
|
|
source: IncrementalSource.Mutation
|
|
}, m)
|
|
});
|
|
};
|
|
const wrappedScrollEmit = (p) => wrappedEmit({
|
|
type: EventType.IncrementalSnapshot,
|
|
data: __spreadValues({
|
|
source: IncrementalSource.Scroll
|
|
}, p)
|
|
});
|
|
const wrappedCanvasMutationEmit = (p) => wrappedEmit({
|
|
type: EventType.IncrementalSnapshot,
|
|
data: __spreadValues({
|
|
source: IncrementalSource.CanvasMutation
|
|
}, p)
|
|
});
|
|
const wrappedAdoptedStyleSheetEmit = (a2) => wrappedEmit({
|
|
type: EventType.IncrementalSnapshot,
|
|
data: __spreadValues({
|
|
source: IncrementalSource.AdoptedStyleSheet
|
|
}, a2)
|
|
});
|
|
const stylesheetManager = new StylesheetManager({
|
|
mutationCb: wrappedMutationEmit,
|
|
adoptedStyleSheetCb: wrappedAdoptedStyleSheetEmit
|
|
});
|
|
const iframeManager = new IframeManager({
|
|
mirror,
|
|
mutationCb: wrappedMutationEmit,
|
|
stylesheetManager,
|
|
recordCrossOriginIframes,
|
|
wrappedEmit
|
|
});
|
|
for (const plugin of plugins || []) {
|
|
if (plugin.getMirror)
|
|
plugin.getMirror({
|
|
nodeMirror: mirror,
|
|
crossOriginIframeMirror: iframeManager.crossOriginIframeMirror,
|
|
crossOriginIframeStyleMirror: iframeManager.crossOriginIframeStyleMirror
|
|
});
|
|
}
|
|
const processedNodeManager = new ProcessedNodeManager();
|
|
canvasManager = new CanvasManager({
|
|
recordCanvas,
|
|
mutationCb: wrappedCanvasMutationEmit,
|
|
win: window,
|
|
blockClass,
|
|
blockSelector,
|
|
mirror,
|
|
sampling: sampling.canvas,
|
|
dataURLOptions
|
|
});
|
|
const shadowDomManager = new ShadowDomManager({
|
|
mutationCb: wrappedMutationEmit,
|
|
scrollCb: wrappedScrollEmit,
|
|
bypassOptions: {
|
|
blockClass,
|
|
blockSelector,
|
|
maskTextClass,
|
|
maskTextSelector,
|
|
inlineStylesheet,
|
|
maskInputOptions,
|
|
dataURLOptions,
|
|
maskTextFn,
|
|
maskInputFn,
|
|
recordCanvas,
|
|
inlineImages,
|
|
sampling,
|
|
slimDOMOptions,
|
|
iframeManager,
|
|
stylesheetManager,
|
|
canvasManager,
|
|
keepIframeSrcFn,
|
|
processedNodeManager
|
|
},
|
|
mirror
|
|
});
|
|
takeFullSnapshot$1 = (isCheckout = false) => {
|
|
if (!recordDOM) {
|
|
return;
|
|
}
|
|
wrappedEmit(
|
|
{
|
|
type: EventType.Meta,
|
|
data: {
|
|
href: window.location.href,
|
|
width: getWindowWidth(),
|
|
height: getWindowHeight()
|
|
}
|
|
},
|
|
isCheckout
|
|
);
|
|
stylesheetManager.reset();
|
|
shadowDomManager.init();
|
|
mutationBuffers.forEach((buf) => buf.lock());
|
|
const node2 = snapshot(document, {
|
|
mirror,
|
|
blockClass,
|
|
blockSelector,
|
|
maskTextClass,
|
|
maskTextSelector,
|
|
inlineStylesheet,
|
|
maskAllInputs: maskInputOptions,
|
|
maskTextFn,
|
|
maskInputFn,
|
|
slimDOM: slimDOMOptions,
|
|
dataURLOptions,
|
|
recordCanvas,
|
|
inlineImages,
|
|
onSerialize: (n2) => {
|
|
if (isSerializedIframe(n2, mirror)) {
|
|
iframeManager.addIframe(n2);
|
|
}
|
|
if (isSerializedStylesheet(n2, mirror)) {
|
|
stylesheetManager.trackLinkElement(n2);
|
|
}
|
|
if (hasShadowRoot(n2)) {
|
|
shadowDomManager.addShadowRoot(index.shadowRoot(n2), document);
|
|
}
|
|
},
|
|
onIframeLoad: (iframe, childSn) => {
|
|
iframeManager.attachIframe(iframe, childSn);
|
|
shadowDomManager.observeAttachShadow(iframe);
|
|
},
|
|
onStylesheetLoad: (linkEl, childSn) => {
|
|
stylesheetManager.attachLinkElement(linkEl, childSn);
|
|
},
|
|
keepIframeSrcFn
|
|
});
|
|
if (!node2) {
|
|
return console.warn("Failed to snapshot the document");
|
|
}
|
|
wrappedEmit(
|
|
{
|
|
type: EventType.FullSnapshot,
|
|
data: {
|
|
node: node2,
|
|
initialOffset: getWindowScroll(window)
|
|
}
|
|
},
|
|
isCheckout
|
|
);
|
|
mutationBuffers.forEach((buf) => buf.unlock());
|
|
if (document.adoptedStyleSheets && document.adoptedStyleSheets.length > 0)
|
|
stylesheetManager.adoptStyleSheets(
|
|
document.adoptedStyleSheets,
|
|
mirror.getId(document)
|
|
);
|
|
};
|
|
try {
|
|
const handlers = [];
|
|
const observe = (doc) => {
|
|
var _a2;
|
|
return callbackWrapper(initObservers)(
|
|
{
|
|
mutationCb: wrappedMutationEmit,
|
|
mousemoveCb: (positions, source) => wrappedEmit({
|
|
type: EventType.IncrementalSnapshot,
|
|
data: {
|
|
source,
|
|
positions
|
|
}
|
|
}),
|
|
mouseInteractionCb: (d) => wrappedEmit({
|
|
type: EventType.IncrementalSnapshot,
|
|
data: __spreadValues({
|
|
source: IncrementalSource.MouseInteraction
|
|
}, d)
|
|
}),
|
|
scrollCb: wrappedScrollEmit,
|
|
viewportResizeCb: (d) => wrappedEmit({
|
|
type: EventType.IncrementalSnapshot,
|
|
data: __spreadValues({
|
|
source: IncrementalSource.ViewportResize
|
|
}, d)
|
|
}),
|
|
inputCb: (v2) => wrappedEmit({
|
|
type: EventType.IncrementalSnapshot,
|
|
data: __spreadValues({
|
|
source: IncrementalSource.Input
|
|
}, v2)
|
|
}),
|
|
mediaInteractionCb: (p) => wrappedEmit({
|
|
type: EventType.IncrementalSnapshot,
|
|
data: __spreadValues({
|
|
source: IncrementalSource.MediaInteraction
|
|
}, p)
|
|
}),
|
|
styleSheetRuleCb: (r2) => wrappedEmit({
|
|
type: EventType.IncrementalSnapshot,
|
|
data: __spreadValues({
|
|
source: IncrementalSource.StyleSheetRule
|
|
}, r2)
|
|
}),
|
|
styleDeclarationCb: (r2) => wrappedEmit({
|
|
type: EventType.IncrementalSnapshot,
|
|
data: __spreadValues({
|
|
source: IncrementalSource.StyleDeclaration
|
|
}, r2)
|
|
}),
|
|
canvasMutationCb: wrappedCanvasMutationEmit,
|
|
fontCb: (p) => wrappedEmit({
|
|
type: EventType.IncrementalSnapshot,
|
|
data: __spreadValues({
|
|
source: IncrementalSource.Font
|
|
}, p)
|
|
}),
|
|
selectionCb: (p) => {
|
|
wrappedEmit({
|
|
type: EventType.IncrementalSnapshot,
|
|
data: __spreadValues({
|
|
source: IncrementalSource.Selection
|
|
}, p)
|
|
});
|
|
},
|
|
customElementCb: (c2) => {
|
|
wrappedEmit({
|
|
type: EventType.IncrementalSnapshot,
|
|
data: __spreadValues({
|
|
source: IncrementalSource.CustomElement
|
|
}, c2)
|
|
});
|
|
},
|
|
blockClass,
|
|
ignoreClass,
|
|
ignoreSelector,
|
|
maskTextClass,
|
|
maskTextSelector,
|
|
maskInputOptions,
|
|
inlineStylesheet,
|
|
sampling,
|
|
recordDOM,
|
|
recordCanvas,
|
|
inlineImages,
|
|
userTriggeredOnInput,
|
|
collectFonts,
|
|
doc,
|
|
maskInputFn,
|
|
maskTextFn,
|
|
keepIframeSrcFn,
|
|
blockSelector,
|
|
slimDOMOptions,
|
|
dataURLOptions,
|
|
mirror,
|
|
iframeManager,
|
|
stylesheetManager,
|
|
shadowDomManager,
|
|
processedNodeManager,
|
|
canvasManager,
|
|
ignoreCSSAttributes,
|
|
plugins: ((_a2 = plugins == null ? void 0 : plugins.filter((p) => p.observer)) == null ? void 0 : _a2.map((p) => ({
|
|
observer: p.observer,
|
|
options: p.options,
|
|
callback: (payload) => wrappedEmit({
|
|
type: EventType.Plugin,
|
|
data: {
|
|
plugin: p.name,
|
|
payload
|
|
}
|
|
})
|
|
}))) || []
|
|
},
|
|
hooks
|
|
);
|
|
};
|
|
iframeManager.addLoadListener((iframeEl) => {
|
|
try {
|
|
handlers.push(observe(iframeEl.contentDocument));
|
|
} catch (error) {
|
|
console.warn(error);
|
|
}
|
|
});
|
|
const init = () => {
|
|
takeFullSnapshot$1();
|
|
handlers.push(observe(document));
|
|
recording = true;
|
|
};
|
|
if (["interactive", "complete"].includes(document.readyState)) {
|
|
init();
|
|
} else {
|
|
handlers.push(
|
|
on("DOMContentLoaded", () => {
|
|
wrappedEmit({
|
|
type: EventType.DomContentLoaded,
|
|
data: {}
|
|
});
|
|
if (recordAfter === "DOMContentLoaded") init();
|
|
})
|
|
);
|
|
handlers.push(
|
|
on(
|
|
"load",
|
|
() => {
|
|
wrappedEmit({
|
|
type: EventType.Load,
|
|
data: {}
|
|
});
|
|
if (recordAfter === "load") init();
|
|
},
|
|
window
|
|
)
|
|
);
|
|
}
|
|
return () => {
|
|
handlers.forEach((handler) => {
|
|
try {
|
|
handler();
|
|
} catch (error) {
|
|
const msg = String(error).toLowerCase();
|
|
if (!msg.includes("cross-origin")) {
|
|
console.warn(error);
|
|
}
|
|
}
|
|
});
|
|
processedNodeManager.destroy();
|
|
recording = false;
|
|
unregisterErrorHandler();
|
|
};
|
|
} catch (error) {
|
|
console.warn(error);
|
|
}
|
|
}
|
|
record.addCustomEvent = (tag, payload) => {
|
|
if (!recording) {
|
|
throw new Error("please add custom event after start recording");
|
|
}
|
|
wrappedEmit({
|
|
type: EventType.Custom,
|
|
data: {
|
|
tag,
|
|
payload
|
|
}
|
|
});
|
|
};
|
|
record.freezePage = () => {
|
|
mutationBuffers.forEach((buf) => buf.freeze());
|
|
};
|
|
record.takeFullSnapshot = (isCheckout) => {
|
|
if (!recording) {
|
|
throw new Error("please take full snapshot after start recording");
|
|
}
|
|
takeFullSnapshot$1(isCheckout);
|
|
};
|
|
record.mirror = mirror;
|
|
var n;
|
|
!function(t2) {
|
|
t2[t2.NotStarted = 0] = "NotStarted", t2[t2.Running = 1] = "Running", t2[t2.Stopped = 2] = "Stopped";
|
|
}(n || (n = {}));
|
|
exports.record = record;
|
|
if (typeof module.exports == "object" && typeof exports == "object") {
|
|
var __cp = (to, from, except, desc) => {
|
|
if ((from && typeof from === "object") || typeof from === "function") {
|
|
for (let key of Object.getOwnPropertyNames(from)) {
|
|
if (!Object.prototype.hasOwnProperty.call(to, key) && key !== except)
|
|
Object.defineProperty(to, key, {
|
|
get: () => from[key],
|
|
enumerable: !(desc = Object.getOwnPropertyDescriptor(from, key)) || desc.enumerable,
|
|
});
|
|
}
|
|
}
|
|
return to;
|
|
};
|
|
module.exports = __cp(module.exports, exports);
|
|
}
|
|
return module.exports;
|
|
}))
|
|
//# sourceMappingURL=record.umd.cjs.map
|