@stylable/core
Version:
CSS for Components
183 lines • 8.05 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.setMetaNamespace = exports.defaultProcessNamespace = exports.parseNamespace = exports.hooks = exports.diagnostics = void 0;
const path_1 = __importDefault(require("path"));
const feature_1 = require("./feature");
const plugable_record_1 = require("../helpers/plugable-record");
const string_1 = require("../helpers/string");
const string_2 = require("../helpers/string");
const postcss_value_parser_1 = __importDefault(require("postcss-value-parser"));
const murmurhash_1 = require("../murmurhash");
const diagnostics_1 = require("../diagnostics");
exports.diagnostics = {
INVALID_NAMESPACE_DEF: (0, diagnostics_1.createDiagnosticReporter)('11007', 'error', () => 'invalid @st-namespace'),
EMPTY_NAMESPACE_DEF: (0, diagnostics_1.createDiagnosticReporter)('11008', 'error', () => '@st-namespace must contain at least one character or digit'),
EXTRA_DEFINITION: (0, diagnostics_1.createDiagnosticReporter)('11012', 'error', () => '@st-namespace must contain a single string definition'),
INVALID_NAMESPACE_VALUE: (0, diagnostics_1.createDiagnosticReporter)('11013', 'error', () => '@st-namespace must contain only letters, numbers or dashes'),
INVALID_NAMESPACE_REFERENCE: (0, diagnostics_1.createDiagnosticReporter)('11010', 'error', () => 'st-namespace-reference dose not have any value'),
NATIVE_OVERRIDE_DEPRECATION: (0, diagnostics_1.createDiagnosticReporter)('11014', 'info', () => '@namespace will stop working in version 6, use @st-namespace instead'),
};
const dataKey = plugable_record_1.plugableRecord.key('namespace');
// HOOKS
exports.hooks = (0, feature_1.createFeature)({
metaInit({ meta }) {
plugable_record_1.plugableRecord.set(meta.data, dataKey, {
namespaces: [],
usedNativeNamespace: [],
usedNativeNamespaceNodes: [],
foundStNamespace: false,
});
},
analyzeAtRule({ context, atRule }) {
const isSTNamespace = atRule.name === 'st-namespace';
const isNamespace = atRule.name === 'namespace';
if (!isSTNamespace && !isNamespace) {
return;
}
const data = plugable_record_1.plugableRecord.getUnsafe(context.meta.data, dataKey);
if (data.foundStNamespace && isNamespace) {
// ignore @namespace once @st-namespace was found
return;
}
const diag = isSTNamespace ? context.diagnostics : undefined;
const match = parseNamespace(atRule, diag);
if (match) {
data.namespaces.push(match);
if (isNamespace) {
data.usedNativeNamespace.push(atRule.params);
data.usedNativeNamespaceNodes.push(atRule);
}
else {
// clear @namespace matches once @st-namespace if found
data.usedNativeNamespace.length = 0;
data.usedNativeNamespaceNodes.length = 0;
// mark to prevent any further @namespace collection
data.foundStNamespace = true;
}
}
},
analyzeDone(context) {
const { usedNativeNamespaceNodes } = plugable_record_1.plugableRecord.getUnsafe(context.meta.data, dataKey);
for (const node of usedNativeNamespaceNodes) {
context.diagnostics.report(exports.diagnostics.NATIVE_OVERRIDE_DEPRECATION(), {
node,
});
}
},
prepareAST({ context, node, toRemove }) {
// remove @st-namespace or @namespace that was used as @st-namespace
const { usedNativeNamespace } = plugable_record_1.plugableRecord.getUnsafe(context.meta.data, dataKey);
if (node.type === 'atrule' &&
(node.name === 'st-namespace' ||
(node.name === 'namespace' && usedNativeNamespace.includes(node.params)))) {
toRemove.push(node);
}
},
});
// API
function parseNamespace(node, diag) {
const { nodes } = (0, postcss_value_parser_1.default)(node.params);
if (!nodes.length) {
// empty params (not even empty quotes)
diag?.report(exports.diagnostics.EMPTY_NAMESPACE_DEF(), { node });
return;
}
let isInvalid = false;
let namespace = undefined;
for (const valueNode of nodes) {
switch (valueNode.type) {
case 'string': {
if (namespace === undefined) {
// first namespace
if (!isInvalid) {
namespace = (0, string_2.stripQuotation)(valueNode.value);
}
}
else {
// extra definition - mark as invalid and clear namespace
diag?.report(exports.diagnostics.EXTRA_DEFINITION(), {
node,
word: postcss_value_parser_1.default.stringify(valueNode),
});
isInvalid = true;
namespace = undefined;
}
break;
}
case 'comment':
case 'space':
// do nothing
break;
default: {
// invalid definition - mark as invalid and clear namespace
diag?.report(exports.diagnostics.EXTRA_DEFINITION(), {
node,
word: postcss_value_parser_1.default.stringify(valueNode),
});
isInvalid = true;
namespace = undefined;
}
}
}
if (namespace === undefined) {
// no namespace found
diag?.report(exports.diagnostics.INVALID_NAMESPACE_DEF(), {
node,
});
return;
}
if (namespace !== undefined && namespace.trim() === '') {
// empty namespace found
diag?.report(exports.diagnostics.EMPTY_NAMESPACE_DEF(), {
node,
});
return;
}
// check namespace is a valid ident start with no conflicts with stylable namespacing
const transformedNamespace = (0, string_1.string2varname)(namespace);
if (namespace !== transformedNamespace) {
// invalid namespace found
diag?.report(exports.diagnostics.INVALID_NAMESPACE_VALUE(), {
node,
word: namespace,
});
return;
}
return namespace;
}
exports.parseNamespace = parseNamespace;
function defaultProcessNamespace(namespace, origin, _source) {
return namespace + (0, murmurhash_1.murmurhash3_32_gc)(origin); // .toString(36);
}
exports.defaultProcessNamespace = defaultProcessNamespace;
function setMetaNamespace(context, resolveNamespace) {
const meta = context.meta;
// resolve namespace
const { namespaces } = plugable_record_1.plugableRecord.getUnsafe(meta.data, dataKey);
const namespace = namespaces[namespaces.length - 1] || (0, string_1.filename2varname)(path_1.default.basename(meta.source)) || 's';
// resolve path origin
let pathToSource;
let length = meta.sourceAst.nodes.length;
while (length--) {
const node = meta.sourceAst.nodes[length];
if (node.type === 'comment' && node.text.includes('st-namespace-reference')) {
const i = node.text.indexOf('=');
if (i === -1) {
context.diagnostics.report(exports.diagnostics.INVALID_NAMESPACE_REFERENCE(), {
node,
});
}
else {
pathToSource = (0, string_2.stripQuotation)(node.text.slice(i + 1));
}
break;
}
}
// generate final namespace
meta.namespace = resolveNamespace(namespace, pathToSource ? path_1.default.resolve(path_1.default.dirname(meta.source), pathToSource) : meta.source, meta.source);
}
exports.setMetaNamespace = setMetaNamespace;
//# sourceMappingURL=st-namespace.js.map