完成世界书、骰子、apiconfig页面处理
This commit is contained in:
161
frontend/node_modules/stylis/README.md
generated
vendored
Normal file
161
frontend/node_modules/stylis/README.md
generated
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
# STYLIS
|
||||
|
||||
[](https://github.com/thysultan/stylis.js)
|
||||
|
||||
A Light–weight CSS Preprocessor.
|
||||
|
||||
[](https://coveralls.io/github/thysultan/stylis.js)
|
||||
[](https://bundlephobia.com/result?p=stylis)
|
||||
[](https://github.com/thysultan/stylis.js/blob/master/LICENSE)
|
||||
[](https://www.npmjs.com/package/stylis)
|
||||
|
||||
## Installation
|
||||
|
||||
* Use a Direct Download: `<script src=stylis.js></script>`
|
||||
* Use a CDN: `<script src=unpkg.com/stylis></script>`
|
||||
* Use NPM: `npm install stylis --save`
|
||||
|
||||
## Features
|
||||
|
||||
- nesting `a { &:hover {} }`
|
||||
- selector namespacing
|
||||
- vendor prefixing (flex-box, etc...)
|
||||
- minification
|
||||
- esm module compatible
|
||||
- tree-shaking-able
|
||||
|
||||
## Abstract Syntax Structure
|
||||
|
||||
```js
|
||||
const declaration = {
|
||||
value: 'color:red;',
|
||||
type: 'decl',
|
||||
props: 'color',
|
||||
children: 'red',
|
||||
line: 1, column: 1
|
||||
}
|
||||
|
||||
const comment = {
|
||||
value: '/*@noflip*/',
|
||||
type: 'comm',
|
||||
props: '/',
|
||||
children: '@noflip',
|
||||
line: 1, column: 1
|
||||
}
|
||||
|
||||
const ruleset = {
|
||||
value: 'h1,h2',
|
||||
type: 'rule',
|
||||
props: ['h1', 'h2'],
|
||||
children: [/* ... */],
|
||||
line: 1, column: 1
|
||||
}
|
||||
|
||||
const atruleset = {
|
||||
value: '@media (max-width:100), (min-width:100)',
|
||||
type: '@media',
|
||||
props: ['(max-width:100)', '(min-width:100)'],
|
||||
children: [/* ... */],
|
||||
line: 1, column: 1
|
||||
}
|
||||
```
|
||||
|
||||
## Example:
|
||||
|
||||
```js
|
||||
import {compile, serialize, stringify} from 'stylis'
|
||||
|
||||
serialize(compile(`h1{all:unset}`), stringify)
|
||||
```
|
||||
|
||||
### Compile
|
||||
|
||||
```js
|
||||
compile('h1{all:unset}') === [{value: 'h1', type: 'rule', props: ['h1'], children: [/* ... */]}]
|
||||
compile('--foo:unset;') === [{value: '--foo:unset;', type: 'decl', props: '--foo', children: 'unset'}]
|
||||
```
|
||||
|
||||
### Tokenize
|
||||
|
||||
```js
|
||||
tokenize('h1 h2 h3 [h4 h5] fn(args) "a b c"') === ['h1', 'h2', 'h3', '[h4 h5]', 'fn', '(args)', '"a b c"']
|
||||
```
|
||||
|
||||
### Serialize
|
||||
|
||||
```js
|
||||
serialize(compile('h1{all:unset}'), stringify)
|
||||
```
|
||||
|
||||
### Vendor Prefixing
|
||||
|
||||
```js
|
||||
import {compile, serialize, stringify, middleware, prefixer } from 'stylis';
|
||||
|
||||
serialize(compile('div{display:flex;}'), middleware([prefixer, stringify]))
|
||||
```
|
||||
|
||||
|
||||
## Middleware
|
||||
|
||||
The middleware helper is a convenient helper utility, that for all intents and purposes you can do without if you intend to implement your own traversal logic. The `stringify` middleware is one such middleware that can be used in conjunction with it.
|
||||
|
||||
Elements passed to middlewares have a `root` property that is the immediate root/parent of the current element **in the compiled output**, so it references the parent in the already expanded CSS-like structure. Elements have also `parent` property that is the immediate parent of the current element **from the input structure** (structure representing the input string).
|
||||
|
||||
### Traversal
|
||||
|
||||
```js
|
||||
serialize(compile('h1{all:unset}'), middleware([(element, index, children) => {
|
||||
assert(children === element.root.children && children[index] === element.children)
|
||||
}, stringify])) === 'h1{all:unset;}'
|
||||
```
|
||||
|
||||
The abstract syntax tree also includes an additional `return` property for more niche uses.
|
||||
|
||||
### Prefixing
|
||||
|
||||
```js
|
||||
serialize(compile('h1{all:unset}'), middleware([(element, index, children, callback) => {
|
||||
if (element.type === 'decl' && element.props === 'all' && element.children === 'unset')
|
||||
element.return = 'color:red;' + element.value
|
||||
}, stringify])) === 'h1{color:red;all:unset;}'
|
||||
```
|
||||
|
||||
```js
|
||||
serialize(compile('h1{all:unset}'), middleware([(element, index, children, callback) => {
|
||||
if (element.type === 'rule' && element.props.indexOf('h1') > -1)
|
||||
return serialize([{...element, props: ['h2', 'h3']}], callback)
|
||||
}, stringify])) === 'h2,h3{all:unset;}h1{all:unset;}'
|
||||
```
|
||||
|
||||
### Reading
|
||||
|
||||
```js
|
||||
serialize(compile('h1{all:unset}'), middleware([stringify, (element, index, children) => {
|
||||
assert(element.return === 'h1{all:unset;}')
|
||||
}])) === 'h1{all:unset;color:red;}'
|
||||
```
|
||||
|
||||
The middlewares in [src/Middleware.js](src/Middleware.js) dive into tangible examples of how you might implement a middleware, alternatively you could also create your own middleware system as `compile` returns all the nessessary structure to fork from.
|
||||
|
||||
## Variables
|
||||
|
||||
CSS variables are supported but a note should be made about the exotic use of css variables. The css spec mentions the following
|
||||
|
||||
>The allowed syntax for custom properties is extremely permissive. The <declaration-value> production matches any sequence of one or more tokens, so long as the sequence does not contain <bad-string-token>, <bad-url-token>, unmatched <)-token>, <]-token>, or <}-token>, or top-level <semicolon-token> tokens or <delim-token> tokens with a value of "!".
|
||||
|
||||
That is to say css variables according to the spec allows: `--foo: if(x > 5) this.width = 10;` and while this value is obviously useless as a variable, and would be invalid in any normal property, it still might be read and acted on by JavaScript and this is supported by Stylis, however things become slightly undefined when we start to include the `{` and `}` productions in our use of exotic css variables.
|
||||
|
||||
For example consider the following: `--foo: {};`
|
||||
|
||||
While this is valid CSS and supported. It is unclear what should happen when the rule collides with the implicit block termination rule that allows i.e `h1{color:red}`(notice the omitted semicolon) to also be a valid CSS production. This results in the following contradiction in: `h1{--example: {}` is it to be treated as `h1{--foo:{;}` or `h1{--foo:{}` the later of which is an unterminated block or in the following: `h1{--foo:{} h1{color:red;}` should it be `h1 {--foo:{}h1{color:red;};` where `{}h1{color:red;` is part of the css variable `--foo` and not a new rule or should it be something else?
|
||||
|
||||
Nevertheless Stylis still supports the exotic forms highlighted in the spec, however you should consider it as a general rule to delimit such exotic uses of variables in strings or parentheses i.e: `h1{--foo:'{'}` or `h1{--foo:({)}`.
|
||||
|
||||
## Benchmark
|
||||
|
||||
Stylis is at-least 2X faster than its predecesor.
|
||||
|
||||
### License
|
||||
|
||||
Stylis is [MIT licensed](./LICENSE).
|
||||
2
frontend/node_modules/stylis/dist/stylis.mjs
generated
vendored
Normal file
2
frontend/node_modules/stylis/dist/stylis.mjs
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
1
frontend/node_modules/stylis/dist/stylis.mjs.map
generated
vendored
Normal file
1
frontend/node_modules/stylis/dist/stylis.mjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
7
frontend/node_modules/stylis/index.js
generated
vendored
Normal file
7
frontend/node_modules/stylis/index.js
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
export * from './src/Enum.js'
|
||||
export * from './src/Utility.js'
|
||||
export * from './src/Parser.js'
|
||||
export * from './src/Prefixer.js'
|
||||
export * from './src/Tokenizer.js'
|
||||
export * from './src/Serializer.js'
|
||||
export * from './src/Middleware.js'
|
||||
112
frontend/node_modules/stylis/src/Middleware.js
generated
vendored
Normal file
112
frontend/node_modules/stylis/src/Middleware.js
generated
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
import {MS, MOZ, WEBKIT, RULESET, KEYFRAMES, DECLARATION} from './Enum.js'
|
||||
import {match, charat, substr, strlen, sizeof, replace, combine, filter, assign} from './Utility.js'
|
||||
import {copy, lift, tokenize} from './Tokenizer.js'
|
||||
import {serialize} from './Serializer.js'
|
||||
import {prefix} from './Prefixer.js'
|
||||
|
||||
/**
|
||||
* @param {function[]} collection
|
||||
* @return {function}
|
||||
*/
|
||||
export function middleware (collection) {
|
||||
var length = sizeof(collection)
|
||||
|
||||
return function (element, index, children, callback) {
|
||||
var output = ''
|
||||
|
||||
for (var i = 0; i < length; i++)
|
||||
output += collection[i](element, index, children, callback) || ''
|
||||
|
||||
return output
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {function} callback
|
||||
* @return {function}
|
||||
*/
|
||||
export function rulesheet (callback) {
|
||||
return function (element) {
|
||||
if (!element.root)
|
||||
if (element = element.return)
|
||||
callback(element)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {object} element
|
||||
* @param {number} index
|
||||
* @param {object[]} children
|
||||
* @param {function} callback
|
||||
*/
|
||||
export function prefixer (element, index, children, callback) {
|
||||
if (element.length > -1)
|
||||
if (!element.return)
|
||||
switch (element.type) {
|
||||
case DECLARATION: element.return = prefix(element.value, element.length, children)
|
||||
return
|
||||
case KEYFRAMES:
|
||||
return serialize([copy(element, {value: replace(element.value, '@', '@' + WEBKIT)})], callback)
|
||||
case RULESET:
|
||||
if (element.length)
|
||||
return combine(children = element.props, function (value) {
|
||||
switch (match(value, callback = /(::plac\w+|:read-\w+)/)) {
|
||||
// :read-(only|write)
|
||||
case ':read-only': case ':read-write':
|
||||
lift(copy(element, {props: [replace(value, /:(read-\w+)/, ':' + MOZ + '$1')]}))
|
||||
lift(copy(element, {props: [value]}))
|
||||
assign(element, {props: filter(children, callback)})
|
||||
break
|
||||
// :placeholder
|
||||
case '::placeholder':
|
||||
lift(copy(element, {props: [replace(value, /:(plac\w+)/, ':' + WEBKIT + 'input-$1')]}))
|
||||
lift(copy(element, {props: [replace(value, /:(plac\w+)/, ':' + MOZ + '$1')]}))
|
||||
lift(copy(element, {props: [replace(value, /:(plac\w+)/, MS + 'input-$1')]}))
|
||||
lift(copy(element, {props: [value]}))
|
||||
assign(element, {props: filter(children, callback)})
|
||||
break
|
||||
}
|
||||
|
||||
return ''
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {object} element
|
||||
* @param {number} index
|
||||
* @param {object[]} children
|
||||
*/
|
||||
export function namespace (element) {
|
||||
switch (element.type) {
|
||||
case RULESET:
|
||||
element.props = element.props.map(function (value) {
|
||||
return combine(tokenize(value), function (value, index, children) {
|
||||
switch (charat(value, 0)) {
|
||||
// \f
|
||||
case 12:
|
||||
return substr(value, 1, strlen(value))
|
||||
// \0 ( + > ~
|
||||
case 0: case 40: case 43: case 62: case 126:
|
||||
return value
|
||||
// :
|
||||
case 58:
|
||||
if (children[++index] === 'global')
|
||||
children[index] = '', children[++index] = '\f' + substr(children[index], index = 1, -1)
|
||||
// \s
|
||||
case 32:
|
||||
return index === 1 ? '' : value
|
||||
default:
|
||||
switch (index) {
|
||||
case 0: element = value
|
||||
return sizeof(children) > 1 ? '' : value
|
||||
case index = sizeof(children) - 1: case 2:
|
||||
return index === 2 ? value + element + element : value + element
|
||||
default:
|
||||
return value
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
202
frontend/node_modules/stylis/src/Parser.js
generated
vendored
Normal file
202
frontend/node_modules/stylis/src/Parser.js
generated
vendored
Normal file
@@ -0,0 +1,202 @@
|
||||
import {COMMENT, RULESET, DECLARATION} from './Enum.js'
|
||||
import {abs, charat, trim, from, sizeof, strlen, substr, append, replace, indexof} from './Utility.js'
|
||||
import {node, char, prev, next, peek, token, caret, alloc, dealloc, delimit, whitespace, escaping, identifier, commenter} from './Tokenizer.js'
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @return {object[]}
|
||||
*/
|
||||
export function compile (value) {
|
||||
return dealloc(parse('', null, null, null, [''], value = alloc(value), 0, [0], value))
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @param {object} root
|
||||
* @param {object?} parent
|
||||
* @param {string[]} rule
|
||||
* @param {string[]} rules
|
||||
* @param {string[]} rulesets
|
||||
* @param {number[]} pseudo
|
||||
* @param {number[]} points
|
||||
* @param {string[]} declarations
|
||||
* @return {object}
|
||||
*/
|
||||
export function parse (value, root, parent, rule, rules, rulesets, pseudo, points, declarations) {
|
||||
var index = 0
|
||||
var offset = 0
|
||||
var length = pseudo
|
||||
var atrule = 0
|
||||
var property = 0
|
||||
var previous = 0
|
||||
var variable = 1
|
||||
var scanning = 1
|
||||
var ampersand = 1
|
||||
var character = 0
|
||||
var type = ''
|
||||
var props = rules
|
||||
var children = rulesets
|
||||
var reference = rule
|
||||
var characters = type
|
||||
|
||||
while (scanning)
|
||||
switch (previous = character, character = next()) {
|
||||
// (
|
||||
case 40:
|
||||
if (previous != 108 && charat(characters, length - 1) == 58) {
|
||||
if (indexof(characters += replace(delimit(character), '&', '&\f'), '&\f', abs(index ? points[index - 1] : 0)) != -1)
|
||||
ampersand = -1
|
||||
break
|
||||
}
|
||||
// " ' [
|
||||
case 34: case 39: case 91:
|
||||
characters += delimit(character)
|
||||
break
|
||||
// \t \n \r \s
|
||||
case 9: case 10: case 13: case 32:
|
||||
characters += whitespace(previous)
|
||||
break
|
||||
// \
|
||||
case 92:
|
||||
characters += escaping(caret() - 1, 7)
|
||||
continue
|
||||
// /
|
||||
case 47:
|
||||
switch (peek()) {
|
||||
case 42: case 47:
|
||||
append(comment(commenter(next(), caret()), root, parent, declarations), declarations)
|
||||
if ((token(previous || 1) == 5 || token(peek() || 1) == 5) && strlen(characters) && substr(characters, -1, void 0) !== ' ') characters += ' '
|
||||
break
|
||||
default:
|
||||
characters += '/'
|
||||
}
|
||||
break
|
||||
// {
|
||||
case 123 * variable:
|
||||
points[index++] = strlen(characters) * ampersand
|
||||
// } ; \0
|
||||
case 125 * variable: case 59: case 0:
|
||||
switch (character) {
|
||||
// \0 }
|
||||
case 0: case 125: scanning = 0
|
||||
// ;
|
||||
case 59 + offset: if (ampersand == -1) characters = replace(characters, /\f/g, '')
|
||||
if (property > 0 && (strlen(characters) - length || (variable === 0 && previous === 47)))
|
||||
append(property > 32 ? declaration(characters + ';', rule, parent, length - 1, declarations) : declaration(replace(characters, ' ', '') + ';', rule, parent, length - 2, declarations), declarations)
|
||||
break
|
||||
// @ ;
|
||||
case 59: characters += ';'
|
||||
// { rule/at-rule
|
||||
default:
|
||||
append(reference = ruleset(characters, root, parent, index, offset, rules, points, type, props = [], children = [], length, rulesets), rulesets)
|
||||
|
||||
if (character === 123)
|
||||
if (offset === 0)
|
||||
parse(characters, root, reference, reference, props, rulesets, length, points, children)
|
||||
else {
|
||||
switch (atrule) {
|
||||
// c(ontainer)
|
||||
case 99:
|
||||
if (charat(characters, 3) === 110) break
|
||||
// l(ayer)
|
||||
case 108:
|
||||
if (charat(characters, 2) === 97) break
|
||||
default:
|
||||
offset = 0
|
||||
// d(ocument) m(edia) s(upports)
|
||||
case 100: case 109: case 115:
|
||||
}
|
||||
if (offset) parse(value, reference, reference, rule && append(ruleset(value, reference, reference, 0, 0, rules, points, type, rules, props = [], length, children), children), rules, children, length, points, rule ? props : children)
|
||||
else parse(characters, reference, reference, reference, [''], children, 0, points, children)
|
||||
}
|
||||
}
|
||||
|
||||
index = offset = property = 0, variable = ampersand = 1, type = characters = '', length = pseudo
|
||||
break
|
||||
// :
|
||||
case 58:
|
||||
length = 1 + strlen(characters), property = previous
|
||||
default:
|
||||
if (variable < 1)
|
||||
if (character == 123)
|
||||
--variable
|
||||
else if (character == 125 && variable++ == 0 && prev() == 125)
|
||||
continue
|
||||
|
||||
switch (characters += from(character), character * variable) {
|
||||
// &
|
||||
case 38:
|
||||
ampersand = offset > 0 ? 1 : (characters += '\f', -1)
|
||||
break
|
||||
// ,
|
||||
case 44:
|
||||
points[index++] = (strlen(characters) - 1) * ampersand, ampersand = 1
|
||||
break
|
||||
// @
|
||||
case 64:
|
||||
// -
|
||||
if (peek() === 45)
|
||||
characters += delimit(next())
|
||||
|
||||
atrule = peek(), offset = length = strlen(type = characters += identifier(caret())), character++
|
||||
break
|
||||
// -
|
||||
case 45:
|
||||
if (previous === 45 && strlen(characters) == 2)
|
||||
variable = 0
|
||||
}
|
||||
}
|
||||
|
||||
return rulesets
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @param {object} root
|
||||
* @param {object?} parent
|
||||
* @param {number} index
|
||||
* @param {number} offset
|
||||
* @param {string[]} rules
|
||||
* @param {number[]} points
|
||||
* @param {string} type
|
||||
* @param {string[]} props
|
||||
* @param {string[]} children
|
||||
* @param {number} length
|
||||
* @param {object[]} siblings
|
||||
* @return {object}
|
||||
*/
|
||||
export function ruleset (value, root, parent, index, offset, rules, points, type, props, children, length, siblings) {
|
||||
var post = offset - 1
|
||||
var rule = offset === 0 ? rules : ['']
|
||||
var size = sizeof(rule)
|
||||
|
||||
for (var i = 0, j = 0, k = 0; i < index; ++i)
|
||||
for (var x = 0, y = substr(value, post + 1, post = abs(j = points[i])), z = value; x < size; ++x)
|
||||
if (z = trim(j > 0 ? rule[x] + ' ' + y : replace(y, /&\f/g, rule[x])))
|
||||
props[k++] = z
|
||||
|
||||
return node(value, root, parent, offset === 0 ? RULESET : type, props, children, length, siblings)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} value
|
||||
* @param {object} root
|
||||
* @param {object?} parent
|
||||
* @param {object[]} siblings
|
||||
* @return {object}
|
||||
*/
|
||||
export function comment (value, root, parent, siblings) {
|
||||
return node(value, root, parent, COMMENT, from(char()), substr(value, 2, -2), 0, siblings)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @param {object} root
|
||||
* @param {object?} parent
|
||||
* @param {number} length
|
||||
* @param {object[]} siblings
|
||||
* @return {object}
|
||||
*/
|
||||
export function declaration (value, root, parent, length, siblings) {
|
||||
return node(value, root, parent, DECLARATION, substr(value, 0, length), substr(value, length + 1, -1), length, siblings)
|
||||
}
|
||||
35
frontend/node_modules/stylis/src/Serializer.js
generated
vendored
Normal file
35
frontend/node_modules/stylis/src/Serializer.js
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
import {IMPORT, LAYER, COMMENT, RULESET, DECLARATION, KEYFRAMES, NAMESPACE} from './Enum.js'
|
||||
import {strlen} from './Utility.js'
|
||||
|
||||
/**
|
||||
* @param {object[]} children
|
||||
* @param {function} callback
|
||||
* @return {string}
|
||||
*/
|
||||
export function serialize (children, callback) {
|
||||
var output = ''
|
||||
|
||||
for (var i = 0; i < children.length; i++)
|
||||
output += callback(children[i], i, children, callback) || ''
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {object} element
|
||||
* @param {number} index
|
||||
* @param {object[]} children
|
||||
* @param {function} callback
|
||||
* @return {string}
|
||||
*/
|
||||
export function stringify (element, index, children, callback) {
|
||||
switch (element.type) {
|
||||
case LAYER: if (element.children.length) break
|
||||
case IMPORT: case NAMESPACE: case DECLARATION: return element.return = element.return || element.value
|
||||
case COMMENT: return ''
|
||||
case KEYFRAMES: return element.return = element.value + '{' + serialize(element.children, callback) + '}'
|
||||
case RULESET: if (!strlen(element.value = element.props.join(','))) return ''
|
||||
}
|
||||
|
||||
return strlen(children = serialize(element.children, callback)) ? element.return = element.value + '{' + children + '}' : ''
|
||||
}
|
||||
257
frontend/node_modules/stylis/src/Tokenizer.js
generated
vendored
Normal file
257
frontend/node_modules/stylis/src/Tokenizer.js
generated
vendored
Normal file
@@ -0,0 +1,257 @@
|
||||
import {from, trim, charat, strlen, substr, append, assign} from './Utility.js'
|
||||
|
||||
export var line = 1
|
||||
export var column = 1
|
||||
export var length = 0
|
||||
export var position = 0
|
||||
export var character = 0
|
||||
export var characters = ''
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @param {object | null} root
|
||||
* @param {object | null} parent
|
||||
* @param {string} type
|
||||
* @param {string[] | string} props
|
||||
* @param {object[] | string} children
|
||||
* @param {object[]} siblings
|
||||
* @param {number} length
|
||||
*/
|
||||
export function node (value, root, parent, type, props, children, length, siblings) {
|
||||
return {value: value, root: root, parent: parent, type: type, props: props, children: children, line: line, column: column, length: length, return: '', siblings: siblings}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {object} root
|
||||
* @param {object} props
|
||||
* @return {object}
|
||||
*/
|
||||
export function copy (root, props) {
|
||||
return assign(node('', null, null, '', null, null, 0, root.siblings), root, {length: -root.length}, props)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {object} root
|
||||
*/
|
||||
export function lift (root) {
|
||||
while (root.root)
|
||||
root = copy(root.root, {children: [root]})
|
||||
|
||||
append(root, root.siblings)
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {number}
|
||||
*/
|
||||
export function char () {
|
||||
return character
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {number}
|
||||
*/
|
||||
export function prev () {
|
||||
character = position > 0 ? charat(characters, --position) : 0
|
||||
|
||||
if (column--, character === 10)
|
||||
column = 1, line--
|
||||
|
||||
return character
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {number}
|
||||
*/
|
||||
export function next () {
|
||||
character = position < length ? charat(characters, position++) : 0
|
||||
|
||||
if (column++, character === 10)
|
||||
column = 1, line++
|
||||
|
||||
return character
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {number}
|
||||
*/
|
||||
export function peek () {
|
||||
return charat(characters, position)
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {number}
|
||||
*/
|
||||
export function caret () {
|
||||
return position
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} begin
|
||||
* @param {number} end
|
||||
* @return {string}
|
||||
*/
|
||||
export function slice (begin, end) {
|
||||
return substr(characters, begin, end)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} type
|
||||
* @return {number}
|
||||
*/
|
||||
export function token (type) {
|
||||
switch (type) {
|
||||
// \0 \t \n \r \s whitespace token
|
||||
case 0: case 9: case 10: case 13: case 32:
|
||||
return 5
|
||||
// ! + , / > @ ~ isolate token
|
||||
case 33: case 43: case 44: case 47: case 62: case 64: case 126:
|
||||
// ; { } breakpoint token
|
||||
case 59: case 123: case 125:
|
||||
return 4
|
||||
// : accompanied token
|
||||
case 58:
|
||||
return 3
|
||||
// " ' ( [ opening delimit token
|
||||
case 34: case 39: case 40: case 91:
|
||||
return 2
|
||||
// ) ] closing delimit token
|
||||
case 41: case 93:
|
||||
return 1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @return {any[]}
|
||||
*/
|
||||
export function alloc (value) {
|
||||
return line = column = 1, length = strlen(characters = value), position = 0, []
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} value
|
||||
* @return {any}
|
||||
*/
|
||||
export function dealloc (value) {
|
||||
return characters = '', value
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} type
|
||||
* @return {string}
|
||||
*/
|
||||
export function delimit (type) {
|
||||
return trim(slice(position - 1, delimiter(type === 91 ? type + 2 : type === 40 ? type + 1 : type)))
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @return {string[]}
|
||||
*/
|
||||
export function tokenize (value) {
|
||||
return dealloc(tokenizer(alloc(value)))
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} type
|
||||
* @return {string}
|
||||
*/
|
||||
export function whitespace (type) {
|
||||
while (character = peek())
|
||||
if (character < 33)
|
||||
next()
|
||||
else
|
||||
break
|
||||
|
||||
return token(type) > 2 || token(character) > 3 ? '' : ' '
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string[]} children
|
||||
* @return {string[]}
|
||||
*/
|
||||
export function tokenizer (children) {
|
||||
while (next())
|
||||
switch (token(character)) {
|
||||
case 0: append(identifier(position - 1), children)
|
||||
break
|
||||
case 2: append(delimit(character), children)
|
||||
break
|
||||
default: append(from(character), children)
|
||||
}
|
||||
|
||||
return children
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} index
|
||||
* @param {number} count
|
||||
* @return {string}
|
||||
*/
|
||||
export function escaping (index, count) {
|
||||
while (--count && next())
|
||||
// not 0-9 A-F a-f
|
||||
if (character < 48 || character > 102 || (character > 57 && character < 65) || (character > 70 && character < 97))
|
||||
break
|
||||
|
||||
return slice(index, caret() + (count < 6 && peek() == 32 && next() == 32))
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} type
|
||||
* @return {number}
|
||||
*/
|
||||
export function delimiter (type) {
|
||||
while (next())
|
||||
switch (character) {
|
||||
// ] ) " '
|
||||
case type:
|
||||
return position
|
||||
// " '
|
||||
case 34: case 39:
|
||||
if (type !== 34 && type !== 39)
|
||||
delimiter(character)
|
||||
break
|
||||
// (
|
||||
case 40:
|
||||
if (type === 41)
|
||||
delimiter(type)
|
||||
break
|
||||
// \
|
||||
case 92:
|
||||
next()
|
||||
break
|
||||
}
|
||||
|
||||
return position
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} type
|
||||
* @param {number} index
|
||||
* @return {number}
|
||||
*/
|
||||
export function commenter (type, index) {
|
||||
while (next())
|
||||
// //
|
||||
if (type + character === 47 + 10)
|
||||
break
|
||||
// /*
|
||||
else if (type + character === 42 + 42 && peek() === 47)
|
||||
break
|
||||
|
||||
return '/*' + slice(index, position - 1) + '*' + from(type === 47 ? type : next())
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} index
|
||||
* @return {string}
|
||||
*/
|
||||
export function identifier (index) {
|
||||
while (!token(peek()))
|
||||
next()
|
||||
|
||||
return slice(index, position)
|
||||
}
|
||||
Reference in New Issue
Block a user