From 26105034da4fcce7ac883c899d781f016559310d Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 8 Nov 2018 00:38:48 +0800 Subject: switch to vuepress --- node_modules/csso/lib/utils/clone.js | 23 ++ node_modules/csso/lib/utils/list.js | 389 +++++++++++++++++++++ node_modules/csso/lib/utils/names.js | 73 ++++ node_modules/csso/lib/utils/translate.js | 178 ++++++++++ .../csso/lib/utils/translateWithSourceMap.js | 291 +++++++++++++++ node_modules/csso/lib/utils/walk.js | 189 ++++++++++ 6 files changed, 1143 insertions(+) create mode 100644 node_modules/csso/lib/utils/clone.js create mode 100644 node_modules/csso/lib/utils/list.js create mode 100644 node_modules/csso/lib/utils/names.js create mode 100644 node_modules/csso/lib/utils/translate.js create mode 100644 node_modules/csso/lib/utils/translateWithSourceMap.js create mode 100644 node_modules/csso/lib/utils/walk.js (limited to 'node_modules/csso/lib/utils') diff --git a/node_modules/csso/lib/utils/clone.js b/node_modules/csso/lib/utils/clone.js new file mode 100644 index 00000000..7592e9e4 --- /dev/null +++ b/node_modules/csso/lib/utils/clone.js @@ -0,0 +1,23 @@ +var List = require('./list'); + +module.exports = function clone(node) { + var result = {}; + + for (var key in node) { + var value = node[key]; + + if (value) { + if (Array.isArray(value)) { + value = value.slice(0); + } else if (value instanceof List) { + value = new List(value.map(clone)); + } else if (value.constructor === Object) { + value = clone(value); + } + } + + result[key] = value; + } + + return result; +}; diff --git a/node_modules/csso/lib/utils/list.js b/node_modules/csso/lib/utils/list.js new file mode 100644 index 00000000..30d14871 --- /dev/null +++ b/node_modules/csso/lib/utils/list.js @@ -0,0 +1,389 @@ +// +// item item item item +// /------\ /------\ /------\ /------\ +// | data | | data | | data | | data | +// null <--+-prev |<---+-prev |<---+-prev |<---+-prev | +// | next-+--->| next-+--->| next-+--->| next-+--> null +// \------/ \------/ \------/ \------/ +// ^ ^ +// | list | +// | /------\ | +// \--------------+-head | | +// | tail-+--------------/ +// \------/ +// + +function createItem(data) { + return { + data: data, + next: null, + prev: null + }; +} + +var List = function(values) { + this.cursor = null; + this.head = null; + this.tail = null; + + if (Array.isArray(values)) { + var cursor = null; + + for (var i = 0; i < values.length; i++) { + var item = createItem(values[i]); + + if (cursor !== null) { + cursor.next = item; + } else { + this.head = item; + } + + item.prev = cursor; + cursor = item; + } + + this.tail = cursor; + } +}; + +Object.defineProperty(List.prototype, 'size', { + get: function() { + var size = 0; + var cursor = this.head; + + while (cursor) { + size++; + cursor = cursor.next; + } + + return size; + } +}); + +List.createItem = createItem; +List.prototype.createItem = createItem; + +List.prototype.toArray = function() { + var cursor = this.head; + var result = []; + + while (cursor) { + result.push(cursor.data); + cursor = cursor.next; + } + + return result; +}; +List.prototype.toJSON = function() { + return this.toArray(); +}; + +List.prototype.isEmpty = function() { + return this.head === null; +}; + +List.prototype.first = function() { + return this.head && this.head.data; +}; + +List.prototype.last = function() { + return this.tail && this.tail.data; +}; + +List.prototype.each = function(fn, context) { + var item; + var cursor = { + prev: null, + next: this.head, + cursor: this.cursor + }; + + if (context === undefined) { + context = this; + } + + // push cursor + this.cursor = cursor; + + while (cursor.next !== null) { + item = cursor.next; + cursor.next = item.next; + + fn.call(context, item.data, item, this); + } + + // pop cursor + this.cursor = this.cursor.cursor; +}; + +List.prototype.eachRight = function(fn, context) { + var item; + var cursor = { + prev: this.tail, + next: null, + cursor: this.cursor + }; + + if (context === undefined) { + context = this; + } + + // push cursor + this.cursor = cursor; + + while (cursor.prev !== null) { + item = cursor.prev; + cursor.prev = item.prev; + + fn.call(context, item.data, item, this); + } + + // pop cursor + this.cursor = this.cursor.cursor; +}; + +List.prototype.nextUntil = function(start, fn, context) { + if (start === null) { + return; + } + + var item; + var cursor = { + prev: null, + next: start, + cursor: this.cursor + }; + + if (context === undefined) { + context = this; + } + + // push cursor + this.cursor = cursor; + + while (cursor.next !== null) { + item = cursor.next; + cursor.next = item.next; + + if (fn.call(context, item.data, item, this)) { + break; + } + } + + // pop cursor + this.cursor = this.cursor.cursor; +}; + +List.prototype.prevUntil = function(start, fn, context) { + if (start === null) { + return; + } + + var item; + var cursor = { + prev: start, + next: null, + cursor: this.cursor + }; + + if (context === undefined) { + context = this; + } + + // push cursor + this.cursor = cursor; + + while (cursor.prev !== null) { + item = cursor.prev; + cursor.prev = item.prev; + + if (fn.call(context, item.data, item, this)) { + break; + } + } + + // pop cursor + this.cursor = this.cursor.cursor; +}; + +List.prototype.some = function(fn, context) { + var cursor = this.head; + + if (context === undefined) { + context = this; + } + + while (cursor !== null) { + if (fn.call(context, cursor.data, cursor, this)) { + return true; + } + + cursor = cursor.next; + } + + return false; +}; + +List.prototype.map = function(fn, context) { + var result = []; + var cursor = this.head; + + if (context === undefined) { + context = this; + } + + while (cursor !== null) { + result.push(fn.call(context, cursor.data, cursor, this)); + cursor = cursor.next; + } + + return result; +}; + +List.prototype.copy = function() { + var result = new List(); + var cursor = this.head; + + while (cursor !== null) { + result.insert(createItem(cursor.data)); + cursor = cursor.next; + } + + return result; +}; + +List.prototype.updateCursors = function(prevOld, prevNew, nextOld, nextNew) { + var cursor = this.cursor; + + while (cursor !== null) { + if (prevNew === true || cursor.prev === prevOld) { + cursor.prev = prevNew; + } + + if (nextNew === true || cursor.next === nextOld) { + cursor.next = nextNew; + } + + cursor = cursor.cursor; + } +}; + +List.prototype.insert = function(item, before) { + if (before !== undefined && before !== null) { + // prev before + // ^ + // item + this.updateCursors(before.prev, item, before, item); + + if (before.prev === null) { + // insert to the beginning of list + if (this.head !== before) { + throw new Error('before doesn\'t below to list'); + } + + // since head points to before therefore list doesn't empty + // no need to check tail + this.head = item; + before.prev = item; + item.next = before; + + this.updateCursors(null, item); + } else { + + // insert between two items + before.prev.next = item; + item.prev = before.prev; + + before.prev = item; + item.next = before; + } + } else { + // tail + // ^ + // item + this.updateCursors(this.tail, item, null, item); + + // insert to end of the list + if (this.tail !== null) { + // if list has a tail, then it also has a head, but head doesn't change + + // last item -> new item + this.tail.next = item; + + // last item <- new item + item.prev = this.tail; + } else { + // if list has no a tail, then it also has no a head + // in this case points head to new item + this.head = item; + } + + // tail always start point to new item + this.tail = item; + } +}; + +List.prototype.remove = function(item) { + // item + // ^ + // prev next + this.updateCursors(item, item.prev, item, item.next); + + if (item.prev !== null) { + item.prev.next = item.next; + } else { + if (this.head !== item) { + throw new Error('item doesn\'t below to list'); + } + + this.head = item.next; + } + + if (item.next !== null) { + item.next.prev = item.prev; + } else { + if (this.tail !== item) { + throw new Error('item doesn\'t below to list'); + } + + this.tail = item.prev; + } + + item.prev = null; + item.next = null; + + return item; +}; + +List.prototype.appendList = function(list) { + // ignore empty lists + if (list.head === null) { + return; + } + + this.updateCursors(this.tail, list.tail, null, list.head); + + // insert to end of the list + if (this.tail !== null) { + // if destination list has a tail, then it also has a head, + // but head doesn't change + + // dest tail -> source head + this.tail.next = list.head; + + // dest tail <- source head + list.head.prev = this.tail; + } else { + // if list has no a tail, then it also has no a head + // in this case points head to new item + this.head = list.head; + } + + // tail always start point to new item + this.tail = list.tail; + + list.head = null; + list.tail = null; +}; + +module.exports = List; diff --git a/node_modules/csso/lib/utils/names.js b/node_modules/csso/lib/utils/names.js new file mode 100644 index 00000000..27277711 --- /dev/null +++ b/node_modules/csso/lib/utils/names.js @@ -0,0 +1,73 @@ +var hasOwnProperty = Object.prototype.hasOwnProperty; +var knownKeywords = Object.create(null); +var knownProperties = Object.create(null); + +function getVendorPrefix(string) { + if (string[0] === '-') { + // skip 2 chars to avoid wrong match with variables names + var secondDashIndex = string.indexOf('-', 2); + + if (secondDashIndex !== -1) { + return string.substr(0, secondDashIndex + 1); + } + } + + return ''; +} + +function getKeywordInfo(keyword) { + if (hasOwnProperty.call(knownKeywords, keyword)) { + return knownKeywords[keyword]; + } + + var lowerCaseKeyword = keyword.toLowerCase(); + var vendor = getVendorPrefix(lowerCaseKeyword); + var name = lowerCaseKeyword; + + if (vendor) { + name = name.substr(vendor.length); + } + + return knownKeywords[keyword] = Object.freeze({ + vendor: vendor, + prefix: vendor, + name: name + }); +} + +function getPropertyInfo(property) { + if (hasOwnProperty.call(knownProperties, property)) { + return knownProperties[property]; + } + + var lowerCaseProperty = property.toLowerCase(); + var hack = lowerCaseProperty[0]; + + if (hack === '*' || hack === '_' || hack === '$') { + lowerCaseProperty = lowerCaseProperty.substr(1); + } else if (hack === '/' && property[1] === '/') { + hack = '//'; + lowerCaseProperty = lowerCaseProperty.substr(2); + } else { + hack = ''; + } + + var vendor = getVendorPrefix(lowerCaseProperty); + var name = lowerCaseProperty; + + if (vendor) { + name = name.substr(vendor.length); + } + + return knownProperties[property] = Object.freeze({ + hack: hack, + vendor: vendor, + prefix: hack + vendor, + name: name + }); +} + +module.exports = { + keyword: getKeywordInfo, + property: getPropertyInfo +}; diff --git a/node_modules/csso/lib/utils/translate.js b/node_modules/csso/lib/utils/translate.js new file mode 100644 index 00000000..ae7beebe --- /dev/null +++ b/node_modules/csso/lib/utils/translate.js @@ -0,0 +1,178 @@ +function each(list) { + if (list.head === null) { + return ''; + } + + if (list.head === list.tail) { + return translate(list.head.data); + } + + return list.map(translate).join(''); +} + +function eachDelim(list, delimeter) { + if (list.head === null) { + return ''; + } + + if (list.head === list.tail) { + return translate(list.head.data); + } + + return list.map(translate).join(delimeter); +} + +function translate(node) { + switch (node.type) { + case 'StyleSheet': + return each(node.rules); + + case 'Atrule': + var nodes = ['@', node.name]; + + if (node.expression && !node.expression.sequence.isEmpty()) { + nodes.push(' ', translate(node.expression)); + } + + if (node.block) { + nodes.push('{', translate(node.block), '}'); + } else { + nodes.push(';'); + } + + return nodes.join(''); + + case 'Ruleset': + return translate(node.selector) + '{' + translate(node.block) + '}'; + + case 'Selector': + return eachDelim(node.selectors, ','); + + case 'SimpleSelector': + var nodes = node.sequence.map(function(node) { + // add extra spaces around /deep/ combinator since comment beginning/ending may to be produced + if (node.type === 'Combinator' && node.name === '/deep/') { + return ' ' + translate(node) + ' '; + } + + return translate(node); + }); + + return nodes.join(''); + + case 'Block': + return eachDelim(node.declarations, ';'); + + case 'Declaration': + return translate(node.property) + ':' + translate(node.value); + + case 'Property': + return node.name; + + case 'Value': + return node.important + ? each(node.sequence) + '!important' + : each(node.sequence); + + case 'Attribute': + var result = translate(node.name); + var flagsPrefix = ' '; + + if (node.operator !== null) { + result += node.operator; + + if (node.value !== null) { + result += translate(node.value); + + // space between string and flags is not required + if (node.value.type === 'String') { + flagsPrefix = ''; + } + } + } + + if (node.flags !== null) { + result += flagsPrefix + node.flags; + } + + return '[' + result + ']'; + + case 'FunctionalPseudo': + return ':' + node.name + '(' + eachDelim(node.arguments, ',') + ')'; + + case 'Function': + return node.name + '(' + eachDelim(node.arguments, ',') + ')'; + + case 'Negation': + return ':not(' + eachDelim(node.sequence, ',') + ')'; + + case 'Braces': + return node.open + each(node.sequence) + node.close; + + case 'Argument': + case 'AtruleExpression': + return each(node.sequence); + + case 'Url': + return 'url(' + translate(node.value) + ')'; + + case 'Progid': + return translate(node.value); + + case 'Combinator': + return node.name; + + case 'Identifier': + return node.name; + + case 'PseudoClass': + return ':' + node.name; + + case 'PseudoElement': + return '::' + node.name; + + case 'Class': + return '.' + node.name; + + case 'Id': + return '#' + node.name; + + case 'Hash': + return '#' + node.value; + + case 'Dimension': + return node.value + node.unit; + + case 'Nth': + return node.value; + + case 'Number': + return node.value; + + case 'String': + return node.value; + + case 'Operator': + return node.value; + + case 'Raw': + return node.value; + + case 'Unknown': + return node.value; + + case 'Percentage': + return node.value + '%'; + + case 'Space': + return ' '; + + case 'Comment': + return '/*' + node.value + '*/'; + + default: + throw new Error('Unknown node type: ' + node.type); + } +} + +module.exports = translate; diff --git a/node_modules/csso/lib/utils/translateWithSourceMap.js b/node_modules/csso/lib/utils/translateWithSourceMap.js new file mode 100644 index 00000000..819b7af0 --- /dev/null +++ b/node_modules/csso/lib/utils/translateWithSourceMap.js @@ -0,0 +1,291 @@ +var SourceMapGenerator = require('source-map').SourceMapGenerator; +var SourceNode = require('source-map').SourceNode; + +// Our own implementation of SourceNode#toStringWithSourceMap, +// since SourceNode doesn't allow multiple references to original source. +// Also, as we know structure of result we could be optimize generation +// (currently it's ~40% faster). +function walk(node, fn) { + for (var chunk, i = 0; i < node.children.length; i++) { + chunk = node.children[i]; + + if (chunk instanceof SourceNode) { + // this is a hack, because source maps doesn't support for 1(generated):N(original) + // if (chunk.merged) { + // fn('', chunk); + // } + + walk(chunk, fn); + } else { + fn(chunk, node); + } + } +} + +function generateSourceMap(root) { + var map = new SourceMapGenerator(); + var css = ''; + var sourceMappingActive = false; + var lastOriginalLine = null; + var lastOriginalColumn = null; + var lastIndexOfNewline; + var generated = { + line: 1, + column: 0 + }; + var activatedMapping = { + generated: generated + }; + + walk(root, function(chunk, original) { + if (original.line !== null && + original.column !== null) { + if (lastOriginalLine !== original.line || + lastOriginalColumn !== original.column) { + map.addMapping({ + source: original.source, + original: original, + generated: generated + }); + } + + lastOriginalLine = original.line; + lastOriginalColumn = original.column; + sourceMappingActive = true; + } else if (sourceMappingActive) { + map.addMapping(activatedMapping); + sourceMappingActive = false; + } + + css += chunk; + + lastIndexOfNewline = chunk.lastIndexOf('\n'); + if (lastIndexOfNewline !== -1) { + generated.line += chunk.match(/\n/g).length; + generated.column = chunk.length - lastIndexOfNewline - 1; + } else { + generated.column += chunk.length; + } + }); + + return { + css: css, + map: map + }; +} + +function createAnonymousSourceNode(children) { + return new SourceNode( + null, + null, + null, + children + ); +} + +function createSourceNode(info, children) { + if (info.primary) { + // special marker node to add several references to original + // var merged = createSourceNode(info.merged, []); + // merged.merged = true; + // children.unshift(merged); + + // use recursion, because primary can also has a primary/merged info + return createSourceNode(info.primary, children); + } + + return new SourceNode( + info.line, + info.column - 1, + info.source, + children + ); +} + +function each(list) { + if (list.head === null) { + return ''; + } + + if (list.head === list.tail) { + return translate(list.head.data); + } + + return list.map(translate).join(''); +} + +function eachDelim(list, delimeter) { + if (list.head === null) { + return ''; + } + + if (list.head === list.tail) { + return translate(list.head.data); + } + + return list.map(translate).join(delimeter); +} + +function translate(node) { + switch (node.type) { + case 'StyleSheet': + return createAnonymousSourceNode(node.rules.map(translate)); + + case 'Atrule': + var nodes = ['@', node.name]; + + if (node.expression && !node.expression.sequence.isEmpty()) { + nodes.push(' ', translate(node.expression)); + } + + if (node.block) { + nodes.push('{', translate(node.block), '}'); + } else { + nodes.push(';'); + } + + return createSourceNode(node.info, nodes); + + case 'Ruleset': + return createAnonymousSourceNode([ + translate(node.selector), '{', translate(node.block), '}' + ]); + + case 'Selector': + return createAnonymousSourceNode(node.selectors.map(translate)).join(','); + + case 'SimpleSelector': + var nodes = node.sequence.map(function(node) { + // add extra spaces around /deep/ combinator since comment beginning/ending may to be produced + if (node.type === 'Combinator' && node.name === '/deep/') { + return ' ' + translate(node) + ' '; + } + + return translate(node); + }); + + return createSourceNode(node.info, nodes); + + case 'Block': + return createAnonymousSourceNode(node.declarations.map(translate)).join(';'); + + case 'Declaration': + return createSourceNode( + node.info, + [translate(node.property), ':', translate(node.value)] + ); + + case 'Property': + return node.name; + + case 'Value': + return node.important + ? each(node.sequence) + '!important' + : each(node.sequence); + + case 'Attribute': + var result = translate(node.name); + var flagsPrefix = ' '; + + if (node.operator !== null) { + result += node.operator; + + if (node.value !== null) { + result += translate(node.value); + + // space between string and flags is not required + if (node.value.type === 'String') { + flagsPrefix = ''; + } + } + } + + if (node.flags !== null) { + result += flagsPrefix + node.flags; + } + + return '[' + result + ']'; + + case 'FunctionalPseudo': + return ':' + node.name + '(' + eachDelim(node.arguments, ',') + ')'; + + case 'Function': + return node.name + '(' + eachDelim(node.arguments, ',') + ')'; + + case 'Negation': + return ':not(' + eachDelim(node.sequence, ',') + ')'; + + case 'Braces': + return node.open + each(node.sequence) + node.close; + + case 'Argument': + case 'AtruleExpression': + return each(node.sequence); + + case 'Url': + return 'url(' + translate(node.value) + ')'; + + case 'Progid': + return translate(node.value); + + case 'Combinator': + return node.name; + + case 'Identifier': + return node.name; + + case 'PseudoClass': + return ':' + node.name; + + case 'PseudoElement': + return '::' + node.name; + + case 'Class': + return '.' + node.name; + + case 'Id': + return '#' + node.name; + + case 'Hash': + return '#' + node.value; + + case 'Dimension': + return node.value + node.unit; + + case 'Nth': + return node.value; + + case 'Number': + return node.value; + + case 'String': + return node.value; + + case 'Operator': + return node.value; + + case 'Raw': + return node.value; + + case 'Unknown': + return node.value; + + case 'Percentage': + return node.value + '%'; + + case 'Space': + return ' '; + + case 'Comment': + return '/*' + node.value + '*/'; + + default: + throw new Error('Unknown node type: ' + node.type); + } +} + +module.exports = function(node) { + return generateSourceMap( + createAnonymousSourceNode(translate(node)) + ); +}; diff --git a/node_modules/csso/lib/utils/walk.js b/node_modules/csso/lib/utils/walk.js new file mode 100644 index 00000000..a7948eb8 --- /dev/null +++ b/node_modules/csso/lib/utils/walk.js @@ -0,0 +1,189 @@ +function walkRules(node, item, list) { + switch (node.type) { + case 'StyleSheet': + var oldStylesheet = this.stylesheet; + this.stylesheet = node; + + node.rules.each(walkRules, this); + + this.stylesheet = oldStylesheet; + break; + + case 'Atrule': + if (node.block !== null) { + walkRules.call(this, node.block); + } + + this.fn(node, item, list); + break; + + case 'Ruleset': + this.fn(node, item, list); + break; + } + +} + +function walkRulesRight(node, item, list) { + switch (node.type) { + case 'StyleSheet': + var oldStylesheet = this.stylesheet; + this.stylesheet = node; + + node.rules.eachRight(walkRulesRight, this); + + this.stylesheet = oldStylesheet; + break; + + case 'Atrule': + if (node.block !== null) { + walkRulesRight.call(this, node.block); + } + + this.fn(node, item, list); + break; + + case 'Ruleset': + this.fn(node, item, list); + break; + } +} + +function walkAll(node, item, list) { + switch (node.type) { + case 'StyleSheet': + var oldStylesheet = this.stylesheet; + this.stylesheet = node; + + node.rules.each(walkAll, this); + + this.stylesheet = oldStylesheet; + break; + + case 'Atrule': + if (node.expression !== null) { + walkAll.call(this, node.expression); + } + if (node.block !== null) { + walkAll.call(this, node.block); + } + break; + + case 'Ruleset': + this.ruleset = node; + + if (node.selector !== null) { + walkAll.call(this, node.selector); + } + walkAll.call(this, node.block); + + this.ruleset = null; + break; + + case 'Selector': + var oldSelector = this.selector; + this.selector = node; + + node.selectors.each(walkAll, this); + + this.selector = oldSelector; + break; + + case 'Block': + node.declarations.each(walkAll, this); + break; + + case 'Declaration': + this.declaration = node; + + walkAll.call(this, node.property); + walkAll.call(this, node.value); + + this.declaration = null; + break; + + case 'Attribute': + walkAll.call(this, node.name); + if (node.value !== null) { + walkAll.call(this, node.value); + } + break; + + case 'FunctionalPseudo': + case 'Function': + this['function'] = node; + + node.arguments.each(walkAll, this); + + this['function'] = null; + break; + + case 'AtruleExpression': + this.atruleExpression = node; + + node.sequence.each(walkAll, this); + + this.atruleExpression = null; + break; + + case 'Value': + case 'Argument': + case 'SimpleSelector': + case 'Braces': + case 'Negation': + node.sequence.each(walkAll, this); + break; + + case 'Url': + case 'Progid': + walkAll.call(this, node.value); + break; + + // nothig to do with + // case 'Property': + // case 'Combinator': + // case 'Dimension': + // case 'Hash': + // case 'Identifier': + // case 'Nth': + // case 'Class': + // case 'Id': + // case 'Percentage': + // case 'PseudoClass': + // case 'PseudoElement': + // case 'Space': + // case 'Number': + // case 'String': + // case 'Operator': + // case 'Raw': + } + + this.fn(node, item, list); +} + +function createContext(root, fn) { + var context = { + fn: fn, + root: root, + stylesheet: null, + atruleExpression: null, + ruleset: null, + selector: null, + declaration: null, + function: null + }; + + return context; +} + +module.exports = { + all: function(root, fn) { + walkAll.call(createContext(root, fn), root); + }, + rules: function(root, fn) { + walkRules.call(createContext(root, fn), root); + }, + rulesRight: function(root, fn) { + walkRulesRight.call(createContext(root, fn), root); + } +}; -- cgit v1.2.3