This commit is contained in:
2024-03-22 03:47:51 +05:30
parent 8bcf3d211e
commit 89819f6fe2
28440 changed files with 3211033 additions and 2 deletions

21
node_modules/rtlcss/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014-2016 Mohammad Younes
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

35
node_modules/rtlcss/README.md generated vendored Normal file
View File

@@ -0,0 +1,35 @@
# RTLCSS
[![Join the chat at https://gitter.im/MohammadYounes/rtlcss](https://img.shields.io/gitter/room/MohammadYounes/rtlcss?color=%2340aa8b)](https://gitter.im/MohammadYounes/rtlcss)
<img src="https://github.com/MohammadYounes/rtlcss/blob/master/.github/logo.svg" alt="" align="right" width="100" height="100" title="RTLCSS">
[![GitHub version](https://img.shields.io/github/v/tag/MohammadYounes/rtlcss)](https://github.com/MohammadYounes/rtlcss/releases)
[![npm version](https://img.shields.io/npm/v/rtlcss)](https://www.npmjs.com/package/rtlcss)
[![CI Status](https://img.shields.io/github/actions/workflow/status/MohammadYounes/rtlcss/ci.yml?branch=master&label=CI)](https://github.com/MohammadYounes/rtlcss/actions/workflows/ci.yml?query=branch%3Amaster)
[![js-standard-style](https://img.shields.io/badge/code%20style-standard-blue)](https://standardjs.com/)
[![editor](https://img.shields.io/badge/editor-vscode-blue)](https://code.visualstudio.com/)
[![Twitter](https://img.shields.io/badge/follow-%40rtlcss-blue)](https://twitter.com/rtlcss)
RTLCSS is a framework for converting Left-To-Right (LTR) Cascading Style Sheets(CSS) to Right-To-Left (RTL).
## Documentation
Visit <https://rtlcss.com/learn/>
## Playground
Visit <https://rtlcss.com/playground/>
## Bugs and Issues
Have a bug or a feature request? please feel free to [open a new issue](https://github.com/MohammadYounes/rtlcss/issues/new).
## Release Notes
To view changes in recent versions, see the [CHANGELOG](CHANGELOG.md).
## Support
RTLCSS is saving you and your team a tremendous amount of time and effort? [Buy Me a Coffee ☕](https://www.paypal.me/MohammadYounes)

290
node_modules/rtlcss/bin/rtlcss.js generated vendored Executable file
View File

@@ -0,0 +1,290 @@
#!/usr/bin/env node
'use strict'
const path = require('path')
const fs = require('fs')
const picocolors = require('picocolors')
const postcss = require('postcss')
const rtlcss = require('../lib/rtlcss.js')
const configLoader = require('../lib/config-loader.js')
const { version, bugs } = require('../package.json')
const HELP_TEXT = `Usage: rtlcss [option option=parameter ...] [source] [destination]
Option Description
-------------- ----------------------------------------------
-h,--help Print help (this message) and exit.
-v,--version Print version number and exit.
-c,--config Path to configuration settings file.
- ,--stdin Read from stdin stream.
-d,--directory Process all *.css files from input directory (recursive).
-e,--ext Used with -d option to set the output files extension.
Default: ".rtl.css".
-s,--silent Silent mode, no warnings or errors are printed.
*If no destination is specified, output will be written to the same input folder as {source}.rtl.{ext}
`
const ErrorCodes = Object.freeze({
Ok: 0,
ArgumentError: 1,
ProcessingError: 2
})
let input, output, directory, ext, config
let currentErrorcode = ErrorCodes.Ok
const args = process.argv.slice(2)
process.on('exit', () => { process.reallyExit(currentErrorcode) })
function printWarning (...args) {
args.forEach(a => console.warn(picocolors.yellow(a)))
}
function printInfo (...args) {
args.forEach(a => console.info(picocolors.green(a)))
}
function printError (...args) {
args.forEach(a => console.error(picocolors.red(a)))
}
function printHelp () {
console.log(HELP_TEXT)
printInfo(`RTLCSS version: ${version}`)
printInfo(`Report issues to: ${bugs.url}`)
}
function processCSSFile (error, data, outputName) {
if (error) {
printError(`rtlcss: ${error.message}`)
return
}
let result
const opt = { map: false }
if (input !== '-') {
opt.from = input
opt.to = output
}
if (!config) {
printWarning('rtlcss: Warning! No config present, using defaults.')
result = postcss([rtlcss]).process(data, opt)
} else {
if ('map' in config === true && input !== '-') {
opt.map = config.map
}
result = postcss([rtlcss.configure(config)]).process(data, opt)
}
if (output) {
const savePath = directory !== true ? output : outputName
printInfo('Saving:', savePath)
fs.writeFile(savePath, result.css, (err) => {
if (err) printError(err)
})
if (result.map) {
fs.writeFile(`${savePath}.map`, result.map, (err) => {
if (err) printError(err)
})
}
} else {
process.stdout.write(`${result.css}\n`)
}
}
function walk (dir, done) {
fs.readdir(dir, (error, list) => {
if (error) {
return done(error)
}
let i = 0;
(function next () {
let file = list[i++]
if (!file) {
return done(null)
}
file = path.join(dir, file)
fs.stat(file, (err, stat) => {
if (err) {
printError(err)
} else if (stat && stat.isDirectory()) {
walk(file, (err) => {
if (err) {
printError(err)
} else {
next()
}
})
} else {
// process only *.css files
if (path.extname(file) === '.css') {
// TODO: this could probably be simplified
// compute output directory
const relativePath = path.relative(input, file).split(path.sep)
relativePath.pop()
relativePath.push(path.basename(file).replace('.css', ext || '.rtl.css'))
// set rtl filename
const rtlFile = path.join(output, relativePath.join(path.sep))
// create output directory if it does not exist
const dirName = path.dirname(rtlFile)
if (!fs.existsSync(dirName)) {
fs.mkdirSync(dirName, { recursive: true })
}
// read and process the file.
fs.readFile(file, 'utf8', (e, data) => {
try {
processCSSFile(e, data, rtlFile)
} catch (e) {
currentErrorcode = ErrorCodes.ProcessingError
printError(`rtlcss: error processing file ${file}`)
printError(e)
}
})
}
next()
}
})
})()
})
}
function main () {
let arg
while ((arg = args.shift())) {
switch (arg) {
case '-h':
case '--help':
printHelp()
return
case '-v':
case '--version':
printInfo(`rtlcss version: ${version}`)
return
case '-c':
case '--config':
arg = args.shift()
try {
config = configLoader.load(path.resolve(arg))
} catch (e) {
printError(`rtlcss: invalid config file. ${e}`)
currentErrorcode = ErrorCodes.ArgumentError
return
}
break
case '-d':
case '--directory':
directory = true
break
case '-e':
case '--ext':
ext = args.shift()
break
case '-s':
case '--silent':
console.log = console.info = console.warn = () => {}
break
case '-':
case '--stdin':
input = '-'
break
default:
if (arg[0] === '-') {
printError(`rtlcss: unknown option. ${arg}`)
currentErrorcode = ErrorCodes.ArgumentError
return
}
if (!input) {
input = path.resolve(arg)
} else if (!output) {
output = path.resolve(arg)
}
break
}
}
if (!directory && !input) {
printError('rtlcss: no input file\n')
printHelp()
currentErrorcode = ErrorCodes.ArgumentError
return
}
if (!config && input !== '-') {
try {
const cwd = directory !== true ? path.dirname(input) : input
config = configLoader.load(null, cwd)
} catch (error) {
printError(`rtlcss: invalid config file. ${error}`)
currentErrorcode = ErrorCodes.ArgumentError
}
}
if (!output && input !== '-') {
if (directory !== true) {
const extension = path.extname(input)
output = extension ? input.replace(extension, `.rtl${extension}`) : `${input}.rtl`
} else {
output = input
}
}
if (input !== '-') {
if (directory !== true) {
fs.stat(input, (error, stat) => {
if (error) {
printError(error)
} else if (stat && stat.isDirectory()) {
printError('rtlcss: Input expected to be a file, use the -d option to process a directory.')
} else {
fs.readFile(input, 'utf8', (err, data) => {
try {
processCSSFile(err, data)
} catch (err) {
currentErrorcode = ErrorCodes.ProcessingError
printError(`rtlcss: error processing file ${input}`)
printError(err)
}
})
}
})
} else {
walk(input, (error) => {
if (error) {
printError(`rtlcss: ${error}`)
}
})
}
} else {
process.stdin.resume()
process.stdin.setEncoding('utf8')
let buffer = ''
process.stdin.on('data', (data) => {
buffer += data
})
process.on('SIGINT', () => {
processCSSFile(false, buffer)
process.exit()
})
process.stdin.on('end', () => {
processCSSFile(false, buffer)
})
}
}
main()

85
node_modules/rtlcss/lib/config-loader.js generated vendored Normal file
View File

@@ -0,0 +1,85 @@
'use strict'
const fs = require('fs')
const path = require('path')
const escalade = require('escalade/sync')
const stripJSONComments = require('strip-json-comments')
let config = {}
const configSources = ['package.json', '.rtlcssrc', '.rtlcss.json']
const environments = [
process.env.USERPROFILE,
process.env.HOMEPATH,
process.env.HOME
]
module.exports.load = (configFilePath, cwd, overrides) => {
if (configFilePath) {
return override(readConfig(configFilePath), overrides)
}
const directory = cwd || process.cwd()
config = loadConfig(directory)
if (!config) {
for (const environment of environments) {
if (!environment) {
continue
}
config = loadConfig(environment)
if (config) {
break
}
}
}
if (config) {
override(config, overrides)
}
return config
}
function readConfig (configFilePath) {
try {
const data = fs.readFileSync(path.normalize(configFilePath), 'utf-8')
return JSON.parse(stripJSONComments(data.trim()))
} catch (error) {
throw new Error(`${error} ${configFilePath}`)
}
}
function loadConfig (cwd) {
for (const source of configSources) {
const foundPath = escalade(cwd, (dir, names) => names.includes(source) && source)
if (foundPath) {
config = readConfig(foundPath)
if (source === 'package.json') {
config = config.rtlcssConfig
}
if (config) {
return config
}
}
}
}
function override (to, from) {
if (to && from) {
for (const p in from) {
if (Object.prototype.hasOwnProperty.call(from, p)) {
if (Object.prototype.hasOwnProperty.call(to, p) && typeof to[p] === 'object') {
override(to[p], from[p])
} else {
to[p] = from[p]
}
}
}
}
return to
}

103
node_modules/rtlcss/lib/config.js generated vendored Normal file
View File

@@ -0,0 +1,103 @@
'use strict'
const corePlugin = require('./plugin.js')
const defaultOptions = {
autoRename: false,
autoRenameStrict: false,
blacklist: {},
clean: true,
greedy: false,
processUrls: false,
stringMap: [],
useCalc: false,
aliases: {},
processEnv: true
}
function sort (arr) {
return arr.sort((a, b) => a.priority - b.priority)
}
function setupStringMap (stringMap) {
if (!Array.isArray(stringMap)) {
return
}
let hasLeftRight = false
let hasLtrRtl = false
for (const map of stringMap) {
if (hasLeftRight && hasLtrRtl) {
break
} else if (map.name === 'left-right') {
hasLeftRight = true
} else if (map.name === 'ltr-rtl') {
hasLtrRtl = true
}
}
if (!hasLeftRight) {
stringMap.push({
name: 'left-right',
priority: 100,
exclusive: false,
search: ['left', 'Left', 'LEFT'],
replace: ['right', 'Right', 'RIGHT'],
options: { scope: '*', ignoreCase: false }
})
}
if (!hasLtrRtl) {
stringMap.push({
name: 'ltr-rtl',
priority: 100,
exclusive: false,
search: ['ltr', 'Ltr', 'LTR'],
replace: ['rtl', 'Rtl', 'RTL'],
options: { scope: '*', ignoreCase: false }
})
}
return sort(stringMap)
}
function setupPlugins (plugins) {
const newPlugins = []
if (!plugins || !plugins.some((plugin) => plugin.name === 'rtlcss')) {
newPlugins.push(corePlugin)
}
return sort([...newPlugins, ...plugins])
}
function setupHooks (hooks) {
const newHooks = {
pre () {},
post () {}
}
if (typeof hooks.pre === 'function') {
newHooks.pre = hooks.pre
}
if (typeof hooks.post === 'function') {
newHooks.post = hooks.post
}
return newHooks
}
module.exports.configure = (opts = {}, plugins = [], hooks = {}) => {
const config = { ...defaultOptions, ...opts }
// string map
config.stringMap = setupStringMap(config.stringMap)
// plugins
config.plugins = setupPlugins(plugins)
// hooks
config.hooks = setupHooks(hooks)
return config
}

43
node_modules/rtlcss/lib/directive-parser.js generated vendored Normal file
View File

@@ -0,0 +1,43 @@
'use strict'
module.exports = (comment) => {
const match = comment.text.match(/^\s*!?\s*rtl:/)
if (!match) return
let value = comment.text.slice(match[0].length)
let pos = value.indexOf(':')
const meta = {
source: comment,
name: '',
param: '',
begin: true,
end: true,
blacklist: false,
preserve: false
}
if (pos !== -1) {
meta.name = value.slice(0, pos)
// begin/end are always true, unless one of them actually exists.
meta.begin = meta.name !== 'end'
meta.end = meta.name !== 'begin'
if (meta.name === 'begin' || meta.name === 'end') {
value = value.slice(meta.name.length + 1)
pos = value.indexOf(':')
if (pos !== -1) {
meta.name = value.slice(0, pos)
meta.param = value.slice(pos + 1)
} else {
meta.name = value
}
} else {
meta.param = value.slice(pos + 1)
}
} else {
meta.name = value
}
return meta
}

543
node_modules/rtlcss/lib/plugin.js generated vendored Normal file
View File

@@ -0,0 +1,543 @@
'use strict'
const config = require('./config.js')
const util = require('./util.js')
module.exports = {
name: 'rtlcss',
priority: 100,
directives: {
control: {
ignore: {
expect: { atrule: true, comment: true, decl: true, rule: true },
endNode: null,
begin (node, metadata, context) {
// find the ending node in case of self-closing directive
if (this.endNode === null && metadata.begin && metadata.end) {
let n = node
while (n && n.nodes) {
n = n.nodes[n.nodes.length - 1]
}
this.endNode = n
}
return node.type !== 'comment' || !/^\s*!?\s*rtl:end:ignore/.test(node.text)
},
end (node, metadata, context) {
// end if:
// 1. block directive and the node is comment
// 2. self-closing directive and node is endNode
if ((metadata.begin !== metadata.end && node.type === 'comment') || (metadata.begin && metadata.end && node === this.endNode)) {
// clear ending node
this.endNode = null
return true
}
return false
}
},
rename: {
expect: { rule: true },
begin (node, metadata, context) {
node.selector = context.util.applyStringMap(node.selector, false)
return false
},
end (node, context) {
return true
}
},
raw: {
expect: { self: true },
begin (node, metadata, context) {
const nodes = context.postcss.parse(metadata.param, { from: node.source.input.from })
nodes.walk((node) => {
node[context.symbol] = true
})
node.parent.insertBefore(node, nodes)
return true
},
end (node, context) {
return true
}
},
remove: {
expect: { atrule: true, rule: true, decl: true },
begin (node, metadata, context) {
let prevent = false
switch (node.type) {
case 'atrule':
case 'rule':
case 'decl':
prevent = true
node.remove()
}
return prevent
},
end (node, metadata, context) {
return true
}
},
options: {
expect: { self: true },
stack: [],
begin (node, metadata, context) {
this.stack.push(util.extend({}, context.config))
let options
try {
options = JSON.parse(metadata.param)
} catch (e) {
throw node.error('Invalid options object', { details: e })
}
context.config = config.configure(options, context.config.plugins)
context.util = util.configure(context.config)
return true
},
end (node, metadata, context) {
const config = this.stack.pop()
if (config && !metadata.begin) {
context.config = config
context.util = util.configure(context.config)
}
return true
}
},
config: {
expect: { self: true },
stack: [],
begin (node, metadata, context) {
this.stack.push(util.extend({}, context.config))
let configuration
try {
configuration = eval(`(${metadata.param})`) // eslint-disable-line no-eval
} catch (e) {
throw node.error('Invalid config object', { details: e })
}
context.config = config.configure(configuration.options, configuration.plugins)
context.util = util.configure(context.config)
return true
},
end (node, metadata, context) {
const config = this.stack.pop()
if (config && !metadata.begin) {
context.config = config
context.util = util.configure(context.config)
}
return true
}
}
},
value: [
{
name: 'ignore',
action (decl, expr, context) {
return true
}
},
{
name: 'prepend',
action (decl, expr, context) {
let prefix = ''
const hasRawValue = decl.raws.value && decl.raws.value.raw
const raw = `${decl.raws.between.substr(1).trim()}${hasRawValue ? decl.raws.value.raw : decl.value}${decl.important ? decl.raws.important.substr(9).trim() : ''}`
raw.replace(expr, (m, v) => {
prefix += v
})
decl.value = hasRawValue
? (decl.raws.value.raw = prefix + decl.raws.value.raw)
: prefix + decl.value
return true
}
},
{
name: 'append',
action (decl, expr, context) {
let suffix = ''
const hasRawValue = decl.raws.value && decl.raws.value.raw
const raw = `${decl.raws.between.substr(1).trim()}${hasRawValue ? decl.raws.value.raw : decl.value}${decl.important ? decl.raws.important.substr(9).trim() : ''}`
raw.replace(expr, (m, v) => {
suffix = v + suffix
})
decl.value = hasRawValue ? (decl.raws.value.raw += suffix) : decl.value + suffix
return true
}
},
{
name: 'insert',
action (decl, expr, context) {
const hasRawValue = decl.raws.value && decl.raws.value.raw
const raw = `${decl.raws.between.substr(1).trim()}${hasRawValue ? decl.raws.value.raw : decl.value}${decl.important ? decl.raws.important.substr(9).trim() : ''}`
const result = raw.replace(expr, (match, value) => value + match)
decl.value = hasRawValue ? (decl.raws.value.raw = result) : result
return true
}
},
{
name: '',
action (decl, expr, context) {
const hasRawValue = decl.raws.value && decl.raws.value.raw
const raw = `${decl.raws.between.substr(1).trim()}${hasRawValue ? decl.raws.value.raw : ''}${decl.important ? decl.raws.important.substr(9).trim() : ''}`
raw.replace(expr, (match, value) => {
decl.value = hasRawValue
? (decl.raws.value.raw = value + match)
: value
})
return true
}
}
]
},
processors: [
{
name: 'variable',
expr: /^--/im,
action (prop, value) {
return { prop, value }
}
},
{
name: 'direction',
expr: /direction/im,
action (prop, value, context) {
return { prop, value: context.util.swapLtrRtl(value) }
}
},
{
name: 'left',
expr: /left/im,
action (prop, value, context) {
return { prop: prop.replace(this.expr, 'right'), value }
}
},
{
name: 'right',
expr: /right/im,
action (prop, value, context) {
return { prop: prop.replace(this.expr, 'left'), value }
}
},
{
name: 'four-value syntax',
expr: /^(margin|padding|border-(color|style|width))$/ig,
cache: null,
action (prop, value, context) {
if (this.cache === null) {
this.cache = {
match: /[^\s\uFFFD]+/g
}
}
const state = context.util.guardFunctions(value)
const result = state.value.match(this.cache.match)
if (result && result.length === 4 && (state.store.length > 0 || result[1] !== result[3])) {
let i = 0
state.value = state.value.replace(this.cache.match, () => result[(4 - i++) % 4])
}
return { prop, value: context.util.unguardFunctions(state) }
}
},
{
name: 'border radius',
expr: /border-radius/ig,
cache: null,
flip (value) {
const parts = value.match(this.cache.match)
if (!parts) return value
let i
switch (parts.length) {
case 2:
i = 1
if (parts[0] !== parts[1]) {
value = value.replace(this.cache.match, () => parts[i--])
}
break
case 3:
// preserve leading whitespace.
value = value.replace(this.cache.white, (m) => `${m + parts[1]} `)
break
case 4:
i = 0
if (parts[0] !== parts[1] || parts[2] !== parts[3]) {
value = value.replace(this.cache.match, () => parts[(5 - i++) % 4])
}
break
}
return value
},
action (prop, value, context) {
if (this.cache === null) {
this.cache = {
match: /[^\s\uFFFD]+/g,
slash: /[^/]+/g,
white: /(^\s*)/
}
}
const state = context.util.guardFunctions(value)
state.value = state.value.replace(this.cache.slash, (m) => this.flip(m))
return { prop, value: context.util.unguardFunctions(state) }
}
},
{
name: 'shadow',
expr: /shadow/ig,
cache: null,
action (prop, value, context) {
if (this.cache === null) {
this.cache = {
replace: /[^,]+/g
}
}
const colorSafe = context.util.guardHexColors(value)
const funcSafe = context.util.guardFunctions(colorSafe.value)
funcSafe.value = funcSafe.value.replace(this.cache.replace, (m) => context.util.negate(m))
colorSafe.value = context.util.unguardFunctions(funcSafe)
return { prop, value: context.util.unguardHexColors(colorSafe) }
}
},
{
name: 'transform and perspective origin',
expr: /(?:transform|perspective)-origin/ig,
cache: null,
flip (value, context) {
if (value === '0') {
value = '100%'
} else if (value.match(this.cache.percent)) {
value = context.util.complement(value)
} else if (value.match(this.cache.length)) {
value = context.util.flipLength(value)
}
return value
},
action (prop, value, context) {
if (this.cache === null) {
this.cache = {
match: context.util.regex(['func', 'percent', 'length'], 'g'),
percent: context.util.regex(['func', 'percent'], 'i'),
length: context.util.regex(['length'], 'gi'),
xKeyword: /(left|right|center)/i
}
}
if (value.match(this.cache.xKeyword)) {
value = context.util.swapLeftRight(value)
} else {
const state = context.util.guardFunctions(value)
const parts = state.value.match(this.cache.match)
if (parts && parts.length > 0) {
parts[0] = this.flip(parts[0], context)
state.value = state.value.replace(this.cache.match, () => parts.shift())
value = context.util.unguardFunctions(state)
}
}
return { prop, value }
}
},
{
name: 'transform',
expr: /^(?!text-).*?transform$/ig,
cache: null,
flip (value, process, context) {
let i = 0
return value.replace(this.cache.unit, (num) => process(++i, num))
},
flipMatrix (value, context) {
return this.flip(
value,
(i, num) => i === 2 || i === 3 || i === 5 ? context.util.negate(num) : num,
context
)
},
flipMatrix3D (value, context) {
return this.flip(
value,
(i, num) => i === 2 || i === 4 || i === 5 || i === 13 ? context.util.negate(num) : num,
context
)
},
flipRotate3D (value, context) {
return this.flip(
value,
(i, num) => i === 1 || i === 4 ? context.util.negate(num) : num,
context
)
},
action (prop, value, context) {
if (this.cache === null) {
this.cache = {
negatable: /((translate)(x|3d)?|rotate(z|y)?)$/ig,
unit: context.util.regex(['func', 'number'], 'g'),
matrix: /matrix$/i,
matrix3D: /matrix3d$/i,
skewXY: /skew(x|y)?$/i,
rotate3D: /rotate3d$/i
}
}
const state = context.util.guardFunctions(value)
return {
prop,
value: context.util.unguardFunctions(state, (v, n) => {
if (n.length === 0) return v
if (n.match(this.cache.matrix3D)) {
v = this.flipMatrix3D(v, context)
} else if (n.match(this.cache.matrix)) {
v = this.flipMatrix(v, context)
} else if (n.match(this.cache.rotate3D)) {
v = this.flipRotate3D(v, context)
} else if (n.match(this.cache.skewXY)) {
v = context.util.negateAll(v)
} else if (n.match(this.cache.negatable)) {
v = context.util.negate(v)
}
return v
})
}
}
},
{
name: 'transition',
expr: /transition(-property)?$/i,
action (prop, value, context) {
return { prop, value: context.util.swapLeftRight(value) }
}
},
{
name: 'background',
expr: /(background|object)(-position(-x)?|-image)?$/i,
cache: null,
flip (value, context, isPositionX) {
const state = util.saveTokens(value, true)
const parts = state.value.match(this.cache.match)
if (!parts || parts.length === 0) return util.restoreTokens(state)
const keywords = (state.value.match(this.cache.position) || '').length
if (/* edge offsets */ parts.length >= 3 || /* keywords only */ keywords === 2) {
state.value = util.swapLeftRight(state.value)
} else {
if (parts[0] === '0') {
parts[0] = '100%'
} else if (parts[0].match(this.cache.percent)) {
parts[0] = context.util.complement(parts[0])
} else if (parts[0].match(this.cache.length)) {
if (isPositionX) {
parts[0] = context.util.flipLength(parts[0])
} else if (parts.length === 1) { // X 50% ==> left X top 50%
parts[0] = `right ${parts[0]} top 50%`
} else if (!keywords && parts.length === 2) { // X Y ==> left X top Y
parts[0] = `right ${parts[0]}`
parts[1] = `top ${parts[1]}`
}
} else {
parts[0] = context.util.swapLeftRight(parts[0])
}
state.value = state.value.replace(this.cache.match, () => parts.shift())
}
return util.restoreTokens(state)
},
update (context, value, name) {
if (name.match(this.cache.gradient)) {
value = context.util.swapLeftRight(value)
if (value.match(this.cache.angle)) {
value = context.util.negate(value)
}
} else if ((context.config.processUrls === true || context.config.processUrls.decl === true) && name.match(this.cache.url)) {
value = context.util.applyStringMap(value, true)
}
return value
},
action (prop, value, context) {
if (this.cache === null) {
this.cache = {
match: context.util.regex(['position', 'percent', 'length', 'calc'], 'ig'),
percent: context.util.regex(['func', 'percent'], 'i'),
position: context.util.regex(['position'], 'g'),
length: context.util.regex(['length'], 'gi'),
gradient: /gradient$/i,
angle: /\d+(deg|g?rad|turn)/i,
url: /^url/i
}
}
const colorSafe = context.util.guardHexColors(value)
const funcSafe = context.util.guardFunctions(colorSafe.value)
const parts = funcSafe.value.split(',')
const lprop = prop.toLowerCase()
if (lprop !== 'background-image') {
for (let x = 0; x < parts.length; x++) {
parts[x] = this.flip(parts[x], context, lprop.endsWith('-x'))
}
}
funcSafe.value = parts.join(',')
colorSafe.value = context.util.unguardFunctions(funcSafe, this.update.bind(this, context))
return {
prop,
value: context.util.unguardHexColors(colorSafe)
}
}
},
{
name: 'keyword',
expr: /float|clear|text-align|justify-(content|items|self)/i,
action (prop, value, context) {
return { prop, value: context.util.swapLeftRight(value) }
}
},
{
name: 'cursor',
expr: /cursor/i,
cache: null,
update (context, value, name) {
return (context.config.processUrls === true || context.config.processUrls.decl === true) && name.match(this.cache.url)
? context.util.applyStringMap(value, true)
: value
},
flip (value) {
return value.replace(this.cache.replace, (s, m) => {
return s.replace(m, m.replace(this.cache.e, '*')
.replace(this.cache.w, 'e')
.replace(this.cache.star, 'w'))
})
},
action (prop, value, context) {
if (this.cache === null) {
this.cache = {
replace: /\b(ne|nw|se|sw|nesw|nwse)-resize/ig,
url: /^url/i,
e: /e/i,
w: /w/i,
star: /\*/i
}
}
const state = context.util.guardFunctions(value)
state.value = state.value.split(',')
.map((part) => this.flip(part))
.join(',')
return {
prop,
value: context.util.unguardFunctions(state, this.update.bind(this, context))
}
}
}
]
}

236
node_modules/rtlcss/lib/rtlcss.js generated vendored Normal file
View File

@@ -0,0 +1,236 @@
/**
* RTLCSS https://github.com/MohammadYounes/rtlcss
* Framework for transforming Cascading Style Sheets (CSS) from Left-To-Right (LTR) to Right-To-Left (RTL).
* Copyright 2017 Mohammad Younes.
* Licensed under MIT <https://opensource.org/licenses/mit-license.php>
*/
'use strict'
const postcss = require('postcss')
const state = require('./state.js')
const config = require('./config.js')
const util = require('./util.js')
module.exports = (options, plugins, hooks) => {
const processed = Symbol('processed')
const configuration = config.configure(options, plugins, hooks)
const context = {
// provides access to postcss
postcss,
// provides access to the current configuration
config: configuration,
// provides access to utilities object
util: util.configure(configuration),
// processed symbol
symbol: processed
}
let flipped = 0
const toBeRenamed = {}
function shouldProcess (node, result) {
if (node[processed]) return false
let prevent = false
state.walk((current) => {
// check if current directive is expecting this node
if (!current.metadata.blacklist && current.directive.expect[node.type]) {
// perform action and prevent further processing if result equals true
if (current.directive.begin(node, current.metadata, context)) {
prevent = true
}
// if should end? end it.
if (current.metadata.end && current.directive.end(node, current.metadata, context)) {
state.pop(current)
}
}
})
node[processed] = true
return !prevent
}
return {
postcssPlugin: 'rtlcss',
Once (root) {
context.config.hooks.pre(root, postcss)
shouldProcess(root)
},
Rule (node) {
if (shouldProcess(node)) {
// new rule, reset flipped decl count to zero
flipped = 0
}
},
AtRule (node) {
if (shouldProcess(node) &&
// @rules requires url flipping only
(context.config.processUrls === true || context.config.processUrls.atrule === true)
) {
node.params = context.util.applyStringMap(node.params, true)
}
},
Comment (node, { result }) {
if (!shouldProcess(node)) return
state.parse(node, result, (current) => {
let push = true
if (current.directive === null) {
current.preserve = !context.config.clean
context.util.each(context.config.plugins, (plugin) => {
const blacklist = context.config.blacklist[plugin.name]
if (blacklist && blacklist[current.metadata.name] === true) {
current.metadata.blacklist = true
if (current.metadata.end) {
push = false
}
if (current.metadata.begin) {
result.warn(`directive "${plugin.name}.${current.metadata.name}" is blacklisted.`, { node: current.source })
}
// break each
return false
}
current.directive = plugin.directives.control[current.metadata.name]
if (current.directive) {
// break each
return false
}
})
}
if (current.directive) {
if (!current.metadata.begin && current.metadata.end) {
if (current.directive.end(node, current.metadata, context)) {
state.pop(current)
}
push = false
} else if (
current.directive.expect.self && current.directive.begin(node, current.metadata, context) &&
current.metadata.end && current.directive.end(node, current.metadata, context)
) {
push = false
}
} else if (!current.metadata.blacklist) {
push = false
result.warn(`unsupported directive "${current.metadata.name}".`, { node: current.source })
}
return push
})
},
Declaration (node, { result }) {
if (!shouldProcess(node)) return
// if broken by a matching value directive .. break
if (!context.util.each(context.config.plugins, (plugin) => {
return context.util.each(plugin.directives.value, (directive) => {
const hasRawValue = node.raws.value && node.raws.value.raw
const expr = context.util.regexDirective(directive.name)
if (expr.test(`${node.raws.between}${hasRawValue ? node.raws.value.raw : node.value}${node.important && node.raws.important ? node.raws.important : ''}`)) {
expr.lastIndex = 0
if (directive.action(node, expr, context)) {
if (context.config.clean) {
node.raws.between = context.util.trimDirective(node.raws.between)
if (node.important && node.raws.important) {
node.raws.important = context.util.trimDirective(node.raws.important)
}
node.value = hasRawValue
? (node.raws.value.raw = context.util.trimDirective(node.raws.value.raw))
: context.util.trimDirective(node.value)
}
flipped++
// break
return false
}
}
})
})) return
// loop over all plugins/property processors
context.util.each(context.config.plugins, (plugin) => {
return context.util.each(plugin.processors, (processor) => {
const alias = context.config.aliases[node.prop]
if ((alias || node.prop).match(processor.expr)) {
const raw = node.raws.value && node.raws.value.raw ? node.raws.value.raw : node.value
const state = context.util.saveComments(raw)
if (context.config.processEnv) {
state.value = context.util.swap(state.value, 'safe-area-inset-left', 'safe-area-inset-right', { ignoreCase: false })
}
const pair = processor.action(node.prop, state.value, context)
state.value = pair.value
pair.value = context.util.restoreComments(state)
if ((!alias && pair.prop !== node.prop) || pair.value !== raw) {
flipped++
node.prop = pair.prop
node.value = pair.value
}
// match found, break
return false
}
})
})
// if last decl, apply auto rename
// decl. may be found inside @rules
if (!(context.config.autoRename && !flipped && node.parent.type === 'rule' && context.util.isLastOfType(node))) {
return
}
const renamed = context.util.applyStringMap(node.parent.selector)
if (context.config.autoRenameStrict === true) {
const pair = toBeRenamed[renamed]
if (pair) {
pair.selector = node.parent.selector
node.parent.selector = renamed
} else {
toBeRenamed[node.parent.selector] = node.parent
}
} else {
node.parent.selector = renamed
}
},
OnceExit (root, { result }) {
state.walk((item) => {
result.warn(`unclosed directive "${item.metadata.name}".`, { node: item.source })
})
for (const value of Object.values(toBeRenamed)) {
result.warn('renaming skipped due to lack of a matching pair.', { node: value })
}
context.config.hooks.post(root, postcss)
}
}
}
module.exports.postcss = true
/**
* Creates a new RTLCSS instance, process the input and return its result.
* @param {String} css A string containing input CSS.
* @param {Object} options An object containing RTLCSS settings.
* @param {Object|Array} plugins An array containing a list of RTLCSS plugins or a single RTLCSS plugin.
* @param {Object} hooks An object containing pre/post hooks.
* @returns {String} A string contining the RTLed css.
*/
module.exports.process = function (css, options, plugins, hooks) {
return postcss([this(options, plugins, hooks)]).process(css).css
}
/**
* Creates a new instance of RTLCSS using the passed configuration object
* @param {Object} config An object containing RTLCSS options, plugins and hooks.
* @returns {Object} A new RTLCSS instance.
*/
module.exports.configure = function (config = {}) {
return postcss([this(config.options, config.plugins, config.hooks)])
}

60
node_modules/rtlcss/lib/state.js generated vendored Normal file
View File

@@ -0,0 +1,60 @@
'use strict'
const directiveParser = require('./directive-parser.js')
module.exports = {
stack: [],
pop (current) {
const index = this.stack.indexOf(current)
if (index !== -1) {
this.stack.splice(index, 1)
}
if (!current.preserve) {
current.source.remove()
}
},
parse (node, lazyResult, callback) {
const metadata = directiveParser(node)
if (!metadata) return
let current
if (!metadata.begin && metadata.end) {
this.walk((item) => {
if (metadata.name === item.metadata.name) {
this.pop(item)
current = {
metadata,
directive: item.directive,
source: node,
preserve: item.preserve
}
return false
}
})
} else {
current = {
metadata,
directive: null,
source: node,
preserve: null
}
}
if (current === undefined) {
lazyResult.warn(`found end "${metadata.name}" without a matching begin.`, { node })
} else if (callback(current)) {
this.stack.push(current)
} else if (!current.preserve) {
current.source.remove()
}
},
walk (callback) {
let len = this.stack.length
while (--len > -1) {
if (!callback(this.stack[len])) {
break
}
}
}
}

266
node_modules/rtlcss/lib/util.js generated vendored Normal file
View File

@@ -0,0 +1,266 @@
'use strict'
let config
let tokenId = 0
const CHAR_COMMENT_REPLACEMENT = '\uFFFD' // <20>
const CHAR_TOKEN_REPLACEMENT = '\u00A4' // ¤
const CHAR_TOKEN_START = '\u00AB' // «
const CHAR_TOKEN_END = '\u00BB' // »
const REGEX_COMMENT_REPLACEMENT = new RegExp(CHAR_COMMENT_REPLACEMENT, 'ig')
const REGEX_TOKEN_REPLACEMENT = new RegExp(CHAR_TOKEN_REPLACEMENT, 'ig')
const PATTERN_NUMBER = '\\-?(\\d*?\\.\\d+|\\d+)'
const PATTERN_NUMBER_WITH_CALC = '(calc' + CHAR_TOKEN_REPLACEMENT + ')|(' + PATTERN_NUMBER + ')(?!d\\()'
const PATTERN_TOKEN = CHAR_TOKEN_START + '\\d+:\\d+' + CHAR_TOKEN_END // «offset:index»
const PATTERN_TOKEN_WITH_NAME = '\\w*?' + CHAR_TOKEN_START + '\\d+:\\d+' + CHAR_TOKEN_END // «offset:index»
const REGEX_COMMENT = /\/\*[^]*?\*\//igm // non-greedy
const REGEX_DIRECTIVE = /\/\*\s*!?\s*rtl:[^]*?\*\//img
const REGEX_ESCAPE = /[.*+?^${}()|[\]\\]/g
const REGEX_FUNCTION = /\([^()]+\)/i
const REGEX_HEX_COLOR = /#[a-f0-9]{3,6}/ig
const REGEX_CALC = /calc/
const REGEX_TOKENS = new RegExp(PATTERN_TOKEN, 'ig')
const REGEX_TOKENS_WITH_NAME = new RegExp(PATTERN_TOKEN_WITH_NAME, 'ig')
const REGEX_COMPLEMENT = new RegExp(PATTERN_NUMBER_WITH_CALC, 'i')
const REGEX_NEGATE_ALL = new RegExp(PATTERN_NUMBER_WITH_CALC, 'ig')
const REGEX_NEGATE_ONE = new RegExp(PATTERN_NUMBER_WITH_CALC, 'i')
const DEFAULT_STRING_MAP_OPTIONS = { scope: '*', ignoreCase: true }
function compare (what, to, ignoreCase) {
return ignoreCase
? what.toLowerCase() === to.toLowerCase()
: what === to
}
function escapeRegExp (string) {
return string.replace(REGEX_ESCAPE, '\\$&')
}
module.exports = {
extend (dest, src) {
if (typeof dest === 'undefined' || typeof dest !== 'object') {
dest = {}
}
for (const prop in src) {
if (!Object.prototype.hasOwnProperty.call(dest, prop)) {
dest[prop] = src[prop]
}
}
return dest
},
swap (value, a, b, options = DEFAULT_STRING_MAP_OPTIONS) {
let expr = `${escapeRegExp(a)}|${escapeRegExp(b)}`
const greedy = Object.prototype.hasOwnProperty.call(options, 'greedy') ? options.greedy : config.greedy
if (!greedy) expr = `\\b(${expr})\\b`
const flags = options.ignoreCase ? 'img' : 'mg'
return value.replace(new RegExp(expr, flags), (m) => compare(m, a, options.ignoreCase) ? b : a)
},
swapLeftRight (value) {
return this.swap(value, 'left', 'right')
},
swapLtrRtl (value) {
return this.swap(value, 'ltr', 'rtl')
},
applyStringMap (value, isUrl) {
let result = value
for (const map of config.stringMap) {
const options = this.extend(map.options, DEFAULT_STRING_MAP_OPTIONS)
if (options.scope === '*' || (isUrl && options.scope === 'url') || (!isUrl && options.scope === 'selector')) {
if (Array.isArray(map.search) && Array.isArray(map.replace)) {
for (let mapIndex = 0; mapIndex < map.search.length; mapIndex++) {
result = this.swap(result, map.search[mapIndex], map.replace[mapIndex % map.search.length], options)
}
} else {
result = this.swap(result, map.search, map.replace, options)
}
if (map.exclusive === true) {
break
}
}
}
return result
},
negate (value) {
const state = this.saveTokens(value)
state.value = state.value.replace(REGEX_NEGATE_ONE, (num) => {
return REGEX_TOKEN_REPLACEMENT.test(num)
? num.replace(REGEX_TOKEN_REPLACEMENT, (m) => '(-1*' + m + ')')
: Number.parseFloat(num) * -1
})
return this.restoreTokens(state)
},
negateAll (value) {
const state = this.saveTokens(value)
state.value = state.value.replace(REGEX_NEGATE_ALL, (num) => {
return REGEX_TOKEN_REPLACEMENT.test(num)
? num.replace(REGEX_TOKEN_REPLACEMENT, (m) => '(-1*' + m + ')')
: Number.parseFloat(num) * -1
})
return this.restoreTokens(state)
},
complement (value) {
const state = this.saveTokens(value)
state.value = state.value.replace(REGEX_COMPLEMENT, (num) => {
return REGEX_TOKEN_REPLACEMENT.test(num)
? num.replace(REGEX_TOKEN_REPLACEMENT, (m) => '(100% - ' + m + ')')
: 100 - Number.parseFloat(num)
})
return this.restoreTokens(state)
},
flipLength (value) {
return config.useCalc ? `calc(100% - ${value})` : value
},
save (what, who, replacement, restorer, exclude) {
const state = {
value: who,
store: [],
replacement,
restorer
}
state.value = state.value.replace(what, (c) => {
if (exclude && exclude.test(c)) {
return c
}
state.store.push(c)
return state.replacement
})
return state
},
restore (state) {
let index = 0
const result = state.value.replace(state.restorer, () => state.store[index++])
state.store.length = 0
return result
},
saveComments (value) {
return this.save(REGEX_COMMENT, value, CHAR_COMMENT_REPLACEMENT, REGEX_COMMENT_REPLACEMENT)
},
restoreComments (state) {
return this.restore(state)
},
saveTokens (value, excludeCalc) {
return excludeCalc === true
? this.save(REGEX_TOKENS_WITH_NAME, value, CHAR_TOKEN_REPLACEMENT, REGEX_TOKEN_REPLACEMENT, REGEX_CALC)
: this.save(REGEX_TOKENS, value, CHAR_TOKEN_REPLACEMENT, REGEX_TOKEN_REPLACEMENT)
},
restoreTokens (state) {
return this.restore(state)
},
guard (what, who) {
const state = {
value: who,
store: [],
offset: tokenId++,
token: CHAR_TOKEN_START + tokenId
}
while (what.test(state.value)) {
state.value = state.value.replace(what, (m) => {
state.store.push(m)
return `${state.token}:${state.store.length}${CHAR_TOKEN_END}`
})
}
return state
},
unguard (state, callback) {
const detokenizer = new RegExp('(\\w*?)' + state.token + ':(\\d+)' + CHAR_TOKEN_END, 'i')
while (detokenizer.test(state.value)) {
state.value = state.value.replace(detokenizer, (match, name, index) => {
const value = state.store[index - 1]
return typeof callback === 'function'
? name + callback(value, name)
: name + value
})
}
return state.value
},
guardHexColors (value) {
return this.guard(REGEX_HEX_COLOR, value)
},
unguardHexColors (state, callback) {
return this.unguard(state, callback)
},
guardFunctions (value) {
return this.guard(REGEX_FUNCTION, value)
},
unguardFunctions (state, callback) {
return this.unguard(state, callback)
},
trimDirective (value) {
return value.replace(REGEX_DIRECTIVE, '')
},
regexCache: {},
regexDirective (name) {
// /(?:\/\*(?:!)?rtl:ignore(?::)?)([^]*?)(?:\*\/)/img
this.regexCache[name] = this.regexCache[name] || new RegExp('(?:\\/\\*\\s*(?:!)?\\s*rtl:' + (name ? escapeRegExp(name) + '(?::)?' : '') + ')([^]*?)(?:\\*\\/)', 'img')
return this.regexCache[name]
},
regex (what, options) {
let expression = ''
for (const exp of what) {
switch (exp) {
case 'percent':
expression += `|(${PATTERN_NUMBER}%)`
break
case 'length':
expression += `|(${PATTERN_NUMBER})(?:ex|ch|r?em|vh|vw|vmin|vmax|px|mm|cm|in|pt|pc)?`
break
case 'number':
expression += `|(${PATTERN_NUMBER})`
break
case 'position':
expression += '|(left|center|right|top|bottom)'
break
case 'calc':
expression += `|(calc${PATTERN_TOKEN})`
break
case 'func':
expression += `|(\\w+${PATTERN_TOKEN})`
break
}
}
return new RegExp(expression.slice(1), options)
},
isLastOfType (node) {
let isLast = true
let next = node.next()
while (next) {
if (next.type === node.type) {
isLast = false
break
}
next = next.next()
}
return isLast
},
/**
* Simple breakable each returning false if the callback returns false
* otherwise it returns true
*/
each (array, callback) {
return !array.some((element) => callback(element) === false)
}
}
module.exports.configure = function (configuration) {
config = configuration
return this
}

59
node_modules/rtlcss/package.json generated vendored Normal file
View File

@@ -0,0 +1,59 @@
{
"author": "Mohammad Younes",
"name": "rtlcss",
"version": "4.1.1",
"description": "Framework for transforming cascading style sheets (CSS) from left-to-right (LTR) to right-to-left (RTL)",
"homepage": "https://rtlcss.com/",
"bugs": {
"url": "https://github.com/MohammadYounes/rtlcss/issues"
},
"license": "MIT",
"keywords": [
"rtl",
"css",
"ltr",
"rtlcss",
"framework",
"style",
"mirror",
"flip",
"convert",
"transform"
],
"repository": {
"type": "git",
"url": "git+https://github.com/MohammadYounes/rtlcss.git"
},
"bin": {
"rtlcss": "bin/rtlcss.js"
},
"main": "./lib/rtlcss.js",
"files": [
"bin/*.js",
"lib/*.js"
],
"dependencies": {
"escalade": "^3.1.1",
"picocolors": "^1.0.0",
"postcss": "^8.4.21",
"strip-json-comments": "^3.1.1"
},
"devDependencies": {
"c8": "^7.13.0",
"mocha": "^9.2.2",
"standard": "^17.0.0"
},
"engines": {
"node": ">=12.0.0"
},
"scripts": {
"main": "node ./lib/rtlcss.js",
"lint": "standard",
"lint:fix": "npm run lint -- --fix",
"mocha": "mocha",
"mocha:special": "mocha --fgrep \"# Special\"",
"test": "npm run lint && npm run main && npm run mocha",
"test:ci": "npm run main && npm run mocha",
"coverage": "c8 npm run mocha"
}
}