Socket
Socket
Sign inDemoInstall

rtlcss

Package Overview
Dependencies
Maintainers
1
Versions
67
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

rtlcss - npm Package Compare versions

Comparing version 3.4.0 to 3.5.0

133

bin/rtlcss.js
#!/usr/bin/env node
'use strict'
const path = require('path')
const fs = require('fs')
const chalk = require('chalk')
const mkdirp = require('mkdirp')
const picocolors = require('picocolors')
const postcss = require('postcss')
const rtlcss = require('../lib/rtlcss')
const configLoader = require('../lib/config-loader')
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}
`
let input, output, directory, ext, config, currentErrorcode, arg

@@ -17,41 +33,23 @@ const args = process.argv.slice(2)

process.on('exit', function () { process.reallyExit(currentErrorcode) })
process.on('exit', () => { process.reallyExit(currentErrorcode) })
function printWarning (...args) {
console.warn(chalk.yellow(...args))
console.warn(picocolors.yellow(...args))
}
function printInfo (...args) {
console.info(chalk.green(...args))
console.info(picocolors.green(...args))
}
function printError (...args) {
console.error(chalk.red(...args))
console.error(picocolors.red(...args))
}
function printHelp () {
console.log('Usage: rtlcss [option option=parameter ...] [source] [destination]')
console.log('')
/* eslint-disable no-multi-spaces, comma-spacing */
const options = [
'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.\n\t\t Default: ".rtl.css".',
'-s,--silent' , 'Silent mode, no warnings or errors are printed.'
]
/* eslint-enable no-multi-spaces, comma-spacing */
for (let x = 0; x < options.length; x++) {
console.log(options[x++], '\t', options[x])
}
console.log('')
console.log('*If no destination is specified, output will be written to the same input folder as {source}.rtl.{ext}')
console.log('')
printInfo('RTLCSS version: ' + version)
printInfo('Report issues to: ' + bugs.url)
console.log(HELP_TEXT)
printInfo(`RTLCSS version: ${version}`)
printInfo(`Report issues to: ${bugs.url}`)
}
while ((arg = args.shift())) {

@@ -66,3 +64,3 @@ switch (arg) {

case '--version':
printInfo('rtlcss version: ' + version)
printInfo(`rtlcss version: ${version}`)
shouldBreak = true

@@ -91,3 +89,3 @@ break

case '--silent':
console.log = console.info = console.warn = function () {}
console.log = console.info = console.warn = () => {}
break

@@ -100,3 +98,3 @@ case '-':

if (arg[0] === '-') {
printError('rtlcss: unknown option. ' + arg)
printError(`rtlcss: unknown option. ${arg}`)
shouldBreak = true

@@ -137,3 +135,4 @@ } else if (!input) {

if (directory !== true) {
output = path.extname(input) ? input.replace(/\.[^.]*$/, function (ext) { return '.rtl' + ext }) : input + '.rtl'
const extension = path.extname(input)
output = extension ? input.replace(extension, `.rtl${extension}`) : `${input}.rtl`
} else {

@@ -144,9 +143,11 @@ output = input

const processCSSFile = function (e, data, outputName) {
if (e) {
printError('rtlcss: ' + e.message)
const processCSSFile = (error, data, outputName) => {
if (error) {
printError(`rtlcss: ${error.message}`)
return
}
let result
const opt = { map: false }
if (input !== '-') {

@@ -156,2 +157,3 @@ opt.from = input

}
if (!config) {

@@ -164,2 +166,3 @@ printWarning('rtlcss: Warning! No config present, using defaults.')

}
result = postcss([rtlcss.configure(config)]).process(data, opt)

@@ -173,19 +176,27 @@ }

}
printInfo('Saving:', savePath)
fs.writeFile(savePath, result.css, 'utf8', function (err) { err && printError(err) })
fs.writeFile(savePath, result.css, (err) => {
if (err) printError(err)
})
if (result.map) {
fs.writeFile(savePath + '.map', result.map, 'utf8', function (err) { err && printError(err) })
fs.writeFile(`${savePath}.map`, result.map, (err) => {
if (err) printError(err)
})
}
} else {
process.stdout.write(result.css + '\n')
process.stdout.write(`${result.css}\n`)
}
}
const walk = function (dir, done) {
fs.readdir(dir, function (error, list) {
const walk = (dir, done) => {
fs.readdir(dir, (error, list) => {
if (error) {
return done(error)
}
let i = 0
;(function next () {
let i = 0;
(function next () {
let file = list[i++]

@@ -195,8 +206,9 @@ if (!file) {

}
file = dir + path.sep + file
fs.stat(file, function (err, stat) {
fs.stat(file, (err, stat) => {
if (err) {
printError(err)
} else if (stat && stat.isDirectory()) {
walk(file, function (err) {
walk(file, (err) => {
if (err) {

@@ -209,4 +221,4 @@ printError(err)

} else {
// process only *.css
if (/\.(css)$/.test(file)) {
// process only *.css files
if (file.endsWith('.css')) {
// compute output directory

@@ -217,3 +229,3 @@ const relativePath = path.relative(input, file).split(path.sep)

// set rtl file name
// set rtl filename
const rtlFile = path.join(output, relativePath.join(path.sep))

@@ -224,7 +236,7 @@

if (!fs.existsSync(dirName)) {
mkdirp.sync(dirName)
fs.mkdirSync(dirName, { recursive: true })
}
// read and process the file.
fs.readFile(file, 'utf8', function (e, data) {
fs.readFile(file, 'utf8', (e, data) => {
try {

@@ -238,2 +250,3 @@ processCSSFile(e, data, rtlFile)

}
next()

@@ -248,9 +261,9 @@ }

if (directory !== true) {
fs.stat(input, function (error, stat) {
fs.stat(input, (error, stat) => {
if (error) {
printError(error)
} else if (stat && stat.isDirectory()) {
printError('rtlcss: Input expected to be a file, use -d option to process a directory.')
printError('rtlcss: Input expected to be a file, use the -d option to process a directory.')
} else {
fs.readFile(input, 'utf8', function (e, data) {
fs.readFile(input, 'utf8', (e, data) => {
try {

@@ -266,5 +279,5 @@ processCSSFile(e, data)

} else {
walk(input, function (error) {
walk(input, (error) => {
if (error) {
printError('rtlcss: ' + error)
printError(`rtlcss: ${error}`)
}

@@ -278,10 +291,10 @@ })

let buffer = ''
process.stdin.on('data', function (data) {
process.stdin.on('data', (data) => {
buffer += data
})
process.on('SIGINT', function () {
process.on('SIGINT', () => {
processCSSFile(false, buffer)
process.exit()
})
process.stdin.on('end', function () {
process.stdin.on('end', () => {
processCSSFile(false, buffer)

@@ -288,0 +301,0 @@ })

@@ -0,1 +1,5 @@

# 3.5.0 - 02 Nov. 2021
* Update dependencies. **Thanks @XhmikosR**
* Internal code cleanup/formatting. **Thanks @XhmikosR**
# 3.4.0 - 18 Oct. 2021

@@ -2,0 +6,0 @@ * Support flipping `object-position`.

'use strict'
const fs = require('fs')
const path = require('path')
const findup = require('find-up')
const findUp = require('find-up')
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 = function (configFilePath, cwd, overrides) {
const readConfig = (configFilePath) => {
return JSON.parse(stripJSONComments(fs.readFileSync(configFilePath, 'utf-8').trim()))
}
module.exports.load = (configFilePath, cwd, overrides) => {
if (configFilePath) {
return override(
JSON.parse(
stripJSONComments(
fs.readFileSync(configFilePath, 'utf-8').trim())), overrides)
return override(readConfig(configFilePath), overrides)
}

@@ -19,9 +27,10 @@

config = loadConfig(directory)
if (!config) {
const evns = [process.env.USERPROFILE, process.env.HOMEPATH, process.env.HOME]
for (let x = 0; x < evns.length; x++) {
if (!evns[x]) {
for (const environment of environments) {
if (!environment) {
continue
}
config = loadConfig(evns[x])
config = loadConfig(environment)
if (config) {

@@ -36,2 +45,3 @@ break

}
return config

@@ -41,7 +51,7 @@ }

function loadConfig (cwd) {
for (let x = 0; x < configSources.length; x++) {
for (const source of configSources) {
let foundPath
const source = configSources[x]
try {
foundPath = findup.sync(source, { cwd })
foundPath = findUp.sync(source, { cwd })
} catch (e) {

@@ -53,8 +63,7 @@ continue

const configFilePath = path.normalize(foundPath)
try {
config = JSON.parse(
stripJSONComments(
fs.readFileSync(configFilePath, 'utf-8').trim()))
config = readConfig(configFilePath)
} catch (e) {
throw new Error(e + ' ' + configFilePath)
throw new Error(`${e} ${configFilePath}`)
}

@@ -77,3 +86,3 @@

if (Object.prototype.hasOwnProperty.call(from, p)) {
if (Object.prototype.hasOwnProperty.call(to, p) && (typeof to[p] === 'object')) {
if (Object.prototype.hasOwnProperty.call(to, p) && typeof to[p] === 'object') {
override(to[p], from[p])

@@ -86,3 +95,4 @@ } else {

}
return to
}
'use strict'
let options

@@ -6,2 +7,6 @@ const config = {}

function sort (arr) {
return arr.sort((a, b) => a.priority - b.priority)
}
function optionOrDefault (option, def) {

@@ -32,4 +37,3 @@ return option in options ? options[option] : def

let hasLeftRight, hasLtrRtl
for (let x = 0; x < config.stringMap.length; x++) {
const map = config.stringMap[x]
for (const map of config.stringMap) {
if (hasLeftRight && hasLtrRtl) {

@@ -43,2 +47,3 @@ break

}
if (!hasLeftRight) {

@@ -54,2 +59,3 @@ config.stringMap.push({

}
if (!hasLtrRtl) {

@@ -65,3 +71,4 @@ config.stringMap.push({

}
config.stringMap.sort(function (a, b) { return a.priority - b.priority })
sort(config.stringMap)
}

@@ -73,5 +80,6 @@

if (Array.isArray(plugins)) {
if (!plugins.some(function (plugin) { return plugin.name === 'rtlcss' })) {
if (!plugins.some((plugin) => plugin.name === 'rtlcss')) {
config.plugins.push(corePlugin)
}
config.plugins = config.plugins.concat(plugins)

@@ -81,9 +89,15 @@ } else if (!plugins || plugins.name !== 'rtlcss') {

}
config.plugins.sort(function (a, b) { return a.priority - b.priority })
sort(config.plugins)
// hooks
config.hooks = { pre: function () {}, post: function () {} }
config.hooks = {
pre () {},
post () {}
}
if (typeof hooks.pre === 'function') {
config.hooks.pre = hooks.pre
}
if (typeof hooks.post === 'function') {

@@ -95,2 +109,3 @@ config.hooks.post = hooks.post

}
module.exports.configure = main
'use strict'
module.exports = function (comment) {
module.exports = (comment) => {
let pos = 0

@@ -43,3 +44,4 @@ let value = comment.text

}
return meta
}
'use strict'
const config = require('./config.js')
const util = require('./util.js')
module.exports = {

@@ -12,3 +14,3 @@ name: 'rtlcss',

endNode: null,
begin: function (node, metadata, context) {
begin (node, metadata, context) {
// find the ending node in case of self closing directive

@@ -20,4 +22,6 @@ if (!this.endNode && metadata.begin && metadata.end) {

}
this.endNode = n
}
let prevent = true

@@ -27,5 +31,6 @@ if (node.type === 'comment' && node.text.match(/^\s*!?\s*rtl:end:ignore/)) {

}
return prevent
},
end: function (node, metadata, context) {
end (node, metadata, context) {
// end if:

@@ -39,2 +44,3 @@ // 1. block directive and the node is comment

}
return false

@@ -45,7 +51,7 @@ }

expect: { rule: true },
begin: function (node, metadata, context) {
begin (node, metadata, context) {
node.selector = context.util.applyStringMap(node.selector, false)
return false
},
end: function (node, context) {
end (node, context) {
return true

@@ -56,5 +62,5 @@ }

expect: { self: true },
begin: function (node, metadata, context) {
begin (node, metadata, context) {
const nodes = context.postcss.parse(metadata.param, { from: node.source.input.from })
nodes.walk(function (node) {
nodes.walk((node) => {
node[context.symbol] = true

@@ -65,3 +71,3 @@ })

},
end: function (node, context) {
end (node, context) {
return true

@@ -72,3 +78,3 @@ }

expect: { atrule: true, rule: true, decl: true },
begin: function (node, metadata, context) {
begin (node, metadata, context) {
let prevent = false

@@ -82,5 +88,6 @@ switch (node.type) {

}
return prevent
},
end: function (node, metadata, context) {
end (node, metadata, context) {
return true

@@ -92,3 +99,3 @@ }

stack: [],
begin: function (node, metadata, context) {
begin (node, metadata, context) {
this.stack.push(util.extend({}, context.config))

@@ -99,4 +106,5 @@ let options

} catch (e) {
throw node.error('Invlaid options object', { details: e })
throw node.error('Invalid options object', { details: e })
}
context.config = config.configure(options, context.config.plugins)

@@ -106,3 +114,3 @@ context.util = util.configure(context.config)

},
end: function (node, metadata, context) {
end (node, metadata, context) {
const config = this.stack.pop()

@@ -113,2 +121,3 @@ if (config && !metadata.begin) {

}
return true

@@ -119,15 +128,12 @@ }

expect: { self: true },
expr: {
fn: /function([^(]*)\(([^()]*?)\)[^{]*\{([^]*)\}/ig,
rx: /\/([^/]*)\/(.*)/ig
},
stack: [],
begin: function (node, metadata, context) {
begin (node, metadata, context) {
this.stack.push(util.extend({}, context.config))
let configuration
try {
configuration = eval('(' + metadata.param + ')') // eslint-disable-line no-eval
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)

@@ -137,3 +143,3 @@ context.util = util.configure(context.config)

},
end: function (node, metadata, context) {
end (node, metadata, context) {
const config = this.stack.pop()

@@ -144,2 +150,3 @@ if (config && !metadata.begin) {

}
return true

@@ -152,3 +159,3 @@ }

name: 'ignore',
action: function (decl, expr, context) {
action (decl, expr, context) {
return true

@@ -159,14 +166,12 @@ }

name: 'prepend',
action: function (decl, expr, context) {
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, function (m, v) {
raw.replace(expr, (m, v) => {
prefix += v
})
if (hasRawValue) {
decl.value = decl.raws.value.raw = prefix + decl.raws.value.raw
} else {
decl.value = prefix + decl.value
}
decl.value = hasRawValue
? (decl.raws.value.raw = prefix + decl.raws.value.raw)
: prefix + decl.value
return true

@@ -177,14 +182,10 @@ }

name: 'append',
action: function (decl, expr, context) {
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, function (m, v) {
raw.replace(expr, (m, v) => {
suffix = v + suffix
})
if (hasRawValue) {
decl.value = decl.raws.value.raw = decl.raws.value.raw + suffix
} else {
decl.value = decl.value + suffix
}
decl.value = hasRawValue ? (decl.raws.value.raw += suffix) : decl.value + suffix
return true

@@ -195,13 +196,7 @@ }

name: 'insert',
action: function (decl, expr, context) {
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, function (match, value) {
return hasRawValue ? value + match : value
})
if (hasRawValue) {
decl.value = decl.raws.value.raw = result
} else {
decl.value = result
}
const result = raw.replace(expr, (match, value) => hasRawValue ? value + match : value)
decl.value = hasRawValue ? (decl.raws.value.raw = result) : result
return true

@@ -212,11 +207,9 @@ }

name: '',
action: function (decl, expr, context) {
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, function (match, value) {
if (hasRawValue) {
decl.value = decl.raws.value.raw = value + match
} else {
decl.value = value
}
raw.replace(expr, (match, value) => {
decl.value = hasRawValue
? (decl.raws.value.raw = value + match)
: value
})

@@ -232,4 +225,4 @@ return true

expr: /^--/im,
action: function (prop, value) {
return { prop: prop, value: value }
action (prop, value) {
return { prop, value }
}

@@ -240,4 +233,4 @@ },

expr: /direction/im,
action: function (prop, value, context) {
return { prop: prop, value: context.util.swapLtrRtl(value) }
action (prop, value, context) {
return { prop, value: context.util.swapLtrRtl(value) }
}

@@ -248,4 +241,4 @@ },

expr: /left/im,
action: function (prop, value, context) {
return { prop: prop.replace(this.expr, function () { return 'right' }), value: value }
action (prop, value, context) {
return { prop: prop.replace(this.expr, () => 'right'), value }
}

@@ -256,4 +249,4 @@ },

expr: /right/im,
action: function (prop, value, context) {
return { prop: prop.replace(this.expr, function () { return 'left' }), value: value }
action (prop, value, context) {
return { prop: prop.replace(this.expr, () => 'left'), value }
}

@@ -265,3 +258,3 @@ },

cache: null,
action: function (prop, value, context) {
action (prop, value, context) {
if (this.cache === null) {

@@ -272,2 +265,3 @@ this.cache = {

}
const state = context.util.guardFunctions(value)

@@ -277,7 +271,6 @@ const result = state.value.match(this.cache.match)

let i = 0
state.value = state.value.replace(this.cache.match, function () {
return result[(4 - i++) % 4]
})
state.value = state.value.replace(this.cache.match, () => result[(4 - i++) % 4])
}
return { prop: prop, value: context.util.unguardFunctions(state) }
return { prop, value: context.util.unguardFunctions(state) }
}

@@ -289,3 +282,3 @@ },

cache: null,
flip: function (value) {
flip (value) {
const parts = value.match(this.cache.match)

@@ -298,12 +291,9 @@ let i

if (parts[0] !== parts[1]) {
value = value.replace(this.cache.match, function () {
return parts[i--]
})
value = value.replace(this.cache.match, () => parts[i--])
}
break
case 3:
// preserve leading whitespace.
value = value.replace(this.cache.white, function (m) {
return m + parts[1] + ' '
})
value = value.replace(this.cache.white, (m) => `${m + parts[1]} `)
break

@@ -313,12 +303,12 @@ case 4:

if (parts[0] !== parts[1] || parts[2] !== parts[3]) {
value = value.replace(this.cache.match, function () {
return parts[(5 - i++) % 4]
})
value = value.replace(this.cache.match, () => parts[(5 - i++) % 4])
}
break
}
}
return value
},
action: function (prop, value, context) {
action (prop, value, context) {
if (this.cache === null) {

@@ -331,7 +321,6 @@ this.cache = {

}
const state = context.util.guardFunctions(value)
state.value = state.value.replace(this.cache.slash, function (m) {
return this.flip(m)
}.bind(this))
return { prop: prop, value: context.util.unguardFunctions(state) }
state.value = state.value.replace(this.cache.slash, (m) => this.flip(m))
return { prop, value: context.util.unguardFunctions(state) }
}

@@ -343,3 +332,3 @@ },

cache: null,
action: function (prop, value, context) {
action (prop, value, context) {
if (this.cache === null) {

@@ -350,7 +339,8 @@ this.cache = {

}
const colorSafe = context.util.guardHexColors(value)
const funcSafe = context.util.guardFunctions(colorSafe.value)
funcSafe.value = funcSafe.value.replace(this.cache.replace, function (m) { return context.util.negate(m) })
funcSafe.value = funcSafe.value.replace(this.cache.replace, (m) => context.util.negate(m))
colorSafe.value = context.util.unguardFunctions(funcSafe)
return { prop: prop, value: context.util.unguardHexColors(colorSafe) }
return { prop, value: context.util.unguardHexColors(colorSafe) }
}

@@ -362,3 +352,3 @@ },

cache: null,
flip: function (value, context) {
flip (value, context) {
if (value === '0') {

@@ -371,5 +361,6 @@ value = '100%'

}
return value
},
action: function (prop, value, context) {
action (prop, value, context) {
if (this.cache === null) {

@@ -383,2 +374,3 @@ this.cache = {

}
if (value.match(this.cache.xKeyword)) {

@@ -391,7 +383,8 @@ value = context.util.swapLeftRight(value)

parts[0] = this.flip(parts[0], context)
state.value = state.value.replace(this.cache.match, function () { return parts.shift() })
state.value = state.value.replace(this.cache.match, () => parts.shift())
value = context.util.unguardFunctions(state)
}
}
return { prop: prop, value: value }
return { prop, value }
}

@@ -403,10 +396,8 @@ },

cache: null,
flip: function (value, process, context) {
flip (value, process, context) {
let i = 0
return value.replace(this.cache.unit, function (num) {
return process(++i, num)
})
return value.replace(this.cache.unit, (num) => process(++i, num))
},
flipMatrix: function (value, context) {
return this.flip(value, function (i, num) {
flipMatrix (value, context) {
return this.flip(value, (i, num) => {
if (i === 2 || i === 3 || i === 5) {

@@ -418,4 +409,4 @@ return context.util.negate(num)

},
flipMatrix3D: function (value, context) {
return this.flip(value, function (i, num) {
flipMatrix3D (value, context) {
return this.flip(value, (i, num) => {
if (i === 2 || i === 4 || i === 5 || i === 13) {

@@ -427,11 +418,12 @@ return context.util.negate(num)

},
flipRotate3D: function (value, context) {
return this.flip(value, function (i, num) {
flipRotate3D (value, context) {
return this.flip(value, (i, num) => {
if (i === 1 || i === 4) {
return context.util.negate(num)
}
return num
}, context)
},
action: function (prop, value, context) {
action (prop, value, context) {
if (this.cache === null) {

@@ -447,6 +439,7 @@ this.cache = {

}
const state = context.util.guardFunctions(value)
return {
prop: prop,
value: context.util.unguardFunctions(state, function (v, n) {
prop,
value: context.util.unguardFunctions(state, (v, n) => {
if (n.length) {

@@ -466,3 +459,3 @@ if (n.match(this.cache.matrix3D)) {

return v
}.bind(this))
})
}

@@ -474,4 +467,4 @@ }

expr: /transition(-property)?$/i,
action: function (prop, value, context) {
return { prop: prop, value: context.util.swapLeftRight(value) }
action (prop, value, context) {
return { prop, value: context.util.swapLeftRight(value) }
}

@@ -483,3 +476,3 @@ },

cache: null,
flip: function (value, context) {
flip (value, context) {
const state = util.saveTokens(value, true)

@@ -500,8 +493,9 @@ const parts = state.value.match(this.cache.match)

: context.util.swapLeftRight(parts[0])))
state.value = state.value.replace(this.cache.match, function () { return parts.shift() })
state.value = state.value.replace(this.cache.match, () => parts.shift())
}
}
return util.restoreTokens(state)
},
update: function (context, value, name) {
update (context, value, name) {
if (name.match(this.cache.gradient)) {

@@ -517,3 +511,3 @@ value = context.util.swapLeftRight(value)

},
action: function (prop, value, context) {
action (prop, value, context) {
if (this.cache === null) {

@@ -530,2 +524,3 @@ this.cache = {

}
const colorSafe = context.util.guardHexColors(value)

@@ -540,6 +535,7 @@ const funcSafe = context.util.guardFunctions(colorSafe.value)

}
funcSafe.value = parts.join(',')
colorSafe.value = context.util.unguardFunctions(funcSafe, this.update.bind(this, context))
return {
prop: prop,
prop,
value: context.util.unguardHexColors(colorSafe)

@@ -552,4 +548,4 @@ }

expr: /float|clear|text-align/i,
action: function (prop, value, context) {
return { prop: prop, value: context.util.swapLeftRight(value) }
action (prop, value, context) {
return { prop, value: context.util.swapLeftRight(value) }
}

@@ -561,3 +557,3 @@ },

cache: null,
update: function (context, value, name) {
update (context, value, name) {
if ((context.config.processUrls === true || context.config.processUrls.decl === true) && name.match(this.cache.url)) {

@@ -568,8 +564,10 @@ value = context.util.applyStringMap(value, true)

},
flip: function (value) {
return value.replace(this.cache.replace, function (s, m) {
return s.replace(m, m.replace(this.cache.e, '*').replace(this.cache.w, 'e').replace(this.cache.star, 'w'))
}.bind(this))
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: function (prop, value, context) {
action (prop, value, context) {
if (this.cache === null) {

@@ -584,10 +582,10 @@ this.cache = {

}
const state = context.util.guardFunctions(value)
const parts = state.value.split(',')
for (let x = 0; x < parts.length; x++) {
parts[x] = this.flip(parts[x])
}
state.value = parts.join(',')
state.value = state.value.split(',')
.map((part) => this.flip(part))
.join(',')
return {
prop: prop,
prop,
value: context.util.unguardFunctions(state, this.update.bind(this, context))

@@ -594,0 +592,0 @@ }

@@ -1,2 +0,2 @@

/*
/**
* RTLCSS https://github.com/MohammadYounes/rtlcss

@@ -6,4 +6,6 @@ * Framework for transforming Cascading Style Sheets (CSS) from Left-To-Right (LTR) to Right-To-Left (RTL).

* Licensed under MIT <https://opensource.org/licenses/mit-license.php>
* */
*/
'use strict'
const postcss = require('postcss')

@@ -14,3 +16,3 @@ const state = require('./state.js')

module.exports = function (options, plugins, hooks) {
module.exports = (options, plugins, hooks) => {
const processed = Symbol('processed')

@@ -20,3 +22,3 @@ const configuration = config.configure(options, plugins, hooks)

// provides access to postcss
postcss: postcss,
postcss,
// provides access to the current configuration

@@ -35,3 +37,3 @@ config: configuration,

let prevent = false
state.walk(function (current) {
state.walk((current) => {
// check if current directive is expecting this node

@@ -43,2 +45,3 @@ if (!current.metadata.blacklist && current.directive.expect[node.type]) {

}
// if should end? end it.

@@ -53,4 +56,6 @@ if (current.metadata.end && current.directive.end(node, current.metadata, context)) {

}
return false
}
return {

@@ -69,8 +74,8 @@ postcssPlugin: 'rtlcss',

AtRule (node, { result }) {
if (shouldProcess(node, result)) {
if (shouldProcess(node, result) &&
// @rules requires url flipping only
if (context.config.processUrls === true || context.config.processUrls.atrule === true) {
const params = context.util.applyStringMap(node.params, true)
node.params = params
}
(context.config.processUrls === true || context.config.processUrls.atrule === true)
) {
const params = context.util.applyStringMap(node.params, true)
node.params = params
}

@@ -80,7 +85,7 @@ },

if (shouldProcess(node, result)) {
state.parse(node, result, function (current) {
state.parse(node, result, (current) => {
let push = true
if (current.directive === null) {
current.preserve = !context.config.clean
context.util.each(context.config.plugins, function (plugin) {
context.util.each(context.config.plugins, (plugin) => {
const blacklist = context.config.blacklist[plugin.name]

@@ -92,8 +97,11 @@ if (blacklist && blacklist[current.metadata.name] === true) {

}
if (current.metadata.begin) {
result.warn('directive "' + plugin.name + '.' + current.metadata.name + '" is blacklisted.', { node: current.source })
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]

@@ -106,2 +114,3 @@ if (current.directive) {

}
if (current.directive) {

@@ -112,12 +121,15 @@ if (!current.metadata.begin && current.metadata.end) {

}
push = false
} else if (current.directive.expect.self && current.directive.begin(node, current.metadata, context)) {
if (current.metadata.end && current.directive.end(node, current.metadata, context)) {
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 })
result.warn(`unsupported directive "${current.metadata.name}".`, { node: current.source })
}
return push

@@ -130,29 +142,30 @@ })

// if broken by a matching value directive .. break
if (!context.util.each(context.config.plugins,
function (plugin) {
return context.util.each(plugin.directives.value, function (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.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)
}
if (hasRawValue) {
node.value = node.raws.value.raw = context.util.trimDirective(node.raws.value.raw)
}
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.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)
}
flipped++
// break
return false
if (hasRawValue) {
node.value = node.raws.value.raw = context.util.trimDirective(node.raws.value.raw)
}
}
flipped++
// break
return false
}
})
})) return
}
})
})) return
// loop over all plugins/property processors
context.util.each(context.config.plugins, function (plugin) {
return context.util.each(plugin.processors, function (processor) {
context.util.each(context.config.plugins, (plugin) => {
return context.util.each(plugin.processors, (processor) => {
const alias = context.config.aliases[node.prop]

@@ -165,2 +178,3 @@ if ((alias || node.prop).match(processor.expr)) {

}
const pair = processor.action(node.prop, state.value, context)

@@ -174,2 +188,3 @@ state.value = pair.value

}
// match found, break

@@ -199,8 +214,10 @@ return false

OnceExit (root, { result }) {
state.walk(function (item) {
result.warn('unclosed directive "' + item.metadata.name + '".', { node: item.source })
state.walk((item) => {
result.warn(`unclosed directive "${item.metadata.name}".`, { node: item.source })
})
Object.keys(toBeRenamed).forEach(function (key) {
for (const key of Object.keys(toBeRenamed)) {
result.warn('renaming skipped due to lack of a matching pair.', { node: toBeRenamed[key] })
})
}
context.config.hooks.post(root, postcss)

@@ -207,0 +224,0 @@ }

'use strict'
const directiveParser = require('./directive-parser.js')
module.exports = {
stack: [],
pop: function (current) {
pop (current) {
const index = this.stack.indexOf(current)

@@ -10,2 +12,3 @@ if (index !== -1) {

}
if (!current.preserve) {

@@ -15,3 +18,3 @@ current.source.remove()

},
parse: function (node, lazyResult, callback) {
parse (node, lazyResult, callback) {
let current

@@ -21,15 +24,15 @@ const metadata = directiveParser(node)

if (!metadata.begin && metadata.end) {
this.walk(function (item) {
this.walk((item) => {
if (metadata.name === item.metadata.name) {
this.pop(item)
current = { metadata: metadata, directive: item.directive, source: node, preserve: item.preserve }
current = { metadata, directive: item.directive, source: node, preserve: item.preserve }
return false
}
}.bind(this))
})
} else {
current = { metadata: metadata, directive: null, source: node, preserve: null }
current = { metadata, directive: null, source: node, preserve: null }
}
if (current === undefined) {
lazyResult.warn('found end "' + metadata.name + '" without a matching begin.', { node: node })
lazyResult.warn(`found end "${metadata.name}" without a matching begin.`, { node: node })
} else if (callback(current)) {

@@ -42,3 +45,3 @@ this.stack.push(current)

},
walk: function (callback) {
walk (callback) {
let len = this.stack.length

@@ -45,0 +48,0 @@ while (--len > -1) {

'use strict'
let config

@@ -6,3 +7,3 @@ let tokenId = 0

const CHAR_COMMENT_REPLACEMENT = '\uFFFD' // �
const CHAR_TOKEN_REPLACEMENT = '\u00A4'// ¤
const CHAR_TOKEN_REPLACEMENT = '\u00A4' // ¤
const CHAR_TOKEN_START = '\u00AB' // «

@@ -35,6 +36,5 @@ const CHAR_TOKEN_END = '\u00BB' // »

function compare (what, to, ignoreCase) {
if (ignoreCase) {
return what.toLowerCase() === to.toLowerCase()
}
return what === to
return ignoreCase
? what.toLowerCase() === to.toLowerCase()
: what === to
}

@@ -47,6 +47,7 @@

module.exports = {
extend: function (dest, src) {
extend (dest, src) {
if (typeof dest === 'undefined' || typeof dest !== 'object') {
dest = {}
}
for (const prop in src) {

@@ -57,24 +58,23 @@ if (!Object.prototype.hasOwnProperty.call(dest, prop)) {

}
return dest
},
swap: function (value, a, b, options) {
let expr = escapeRegExp(a) + '|' + escapeRegExp(b)
swap (value, a, b, options) {
let expr = `${escapeRegExp(a)}|${escapeRegExp(b)}`
options = options || DEFAULT_STRING_MAP_OPTIONS
const greedy = Object.prototype.hasOwnProperty.call(options, 'greedy') ? options.greedy : config.greedy
if (!greedy) {
expr = '\\b(' + expr + ')\\b'
}
if (!greedy) expr = `\\b(${expr})\\b`
const flags = options.ignoreCase ? 'img' : 'mg'
return value.replace(new RegExp(expr, flags), function (m) { return compare(m, a, options.ignoreCase) ? b : a })
return value.replace(new RegExp(expr, flags), (m) => compare(m, a, options.ignoreCase) ? b : a)
},
swapLeftRight: function (value) {
swapLeftRight (value) {
return this.swap(value, 'left', 'right')
},
swapLtrRtl: function (value) {
swapLtrRtl (value) {
return this.swap(value, 'ltr', 'rtl')
},
applyStringMap: function (value, isUrl) {
applyStringMap (value, isUrl) {
let result = value
for (let x = 0; x < config.stringMap.length; x++) {
const map = config.stringMap[x]
for (const map of config.stringMap) {
const options = this.extend(map.options, DEFAULT_STRING_MAP_OPTIONS)

@@ -89,2 +89,3 @@ if (options.scope === '*' || (isUrl && options.scope === 'url') || (!isUrl && options.scope === 'selector')) {

}
if (map.exclusive === true) {

@@ -95,39 +96,47 @@ break

}
return result
},
negate: function (value) {
negate (value) {
const state = this.saveTokens(value)
state.value = state.value.replace(REGEX_NEGATE_ONE, function (num) {
return REGEX_TOKEN_REPLACEMENT.test(num) ? num.replace(REGEX_TOKEN_REPLACEMENT, function (m) { return '(-1*' + m + ')' }) : parseFloat(num) * -1
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: function (value) {
negateAll (value) {
const state = this.saveTokens(value)
state.value = state.value.replace(REGEX_NEGATE_ALL, function (num) {
return REGEX_TOKEN_REPLACEMENT.test(num) ? num.replace(REGEX_TOKEN_REPLACEMENT, function (m) { return '(-1*' + m + ')' }) : parseFloat(num) * -1
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: function (value) {
complement (value) {
const state = this.saveTokens(value)
state.value = state.value.replace(REGEX_COMPLEMENT, function (num) {
return REGEX_TOKEN_REPLACEMENT.test(num) ? num.replace(REGEX_TOKEN_REPLACEMENT, function (m) { return '(100% - ' + m + ')' }) : 100 - parseFloat(num)
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: function (value) {
return config.useCalc ? 'calc(100% - ' + value + ')' : value
flipLength (value) {
return config.useCalc ? `calc(100% - ${value})` : value
},
save: function (what, who, replacement, restorer, exclude) {
save (what, who, replacement, restorer, exclude) {
const state = {
value: who,
store: [],
replacement: replacement,
restorer: restorer
replacement,
restorer
}
state.value = state.value.replace(what, function (c) {
state.value = state.value.replace(what, (c) => {
if (exclude && c.match(exclude)) {
return c
}
state.store.push(c)

@@ -138,5 +147,5 @@ return state.replacement

},
restore: function (state) {
restore (state) {
let index = 0
const result = state.value.replace(state.restorer, function () {
const result = state.value.replace(state.restorer, () => {
return state.store[index++]

@@ -147,9 +156,9 @@ })

},
saveComments: function (value) {
saveComments (value) {
return this.save(REGEX_COMMENT, value, CHAR_COMMENT_REPLACEMENT, REGEX_COMMENT_REPLACEMENT)
},
restoreComments: function (state) {
restoreComments (state) {
return this.restore(state)
},
saveTokens: function (value, excludeCalc) {
saveTokens (value, excludeCalc) {
return excludeCalc === true

@@ -159,6 +168,6 @@ ? this.save(REGEX_TOKENS_WITH_NAME, value, CHAR_TOKEN_REPLACEMENT, REGEX_TOKEN_REPLACEMENT, REGEX_CALC)

},
restoreTokens: function (state) {
restoreTokens (state) {
return this.restore(state)
},
guard: function (what, who, indexed) {
guard (what, who, indexed) {
const state = {

@@ -173,48 +182,55 @@ value: who,

while (what.test(state.value)) {
state.value = state.value.replace(what, function (m) { state.store.push(m); return state.token + ':' + state.store.length + CHAR_TOKEN_END })
state.value = state.value.replace(what, (m) => {
state.store.push(m)
return `${state.token}:${state.store.length}${CHAR_TOKEN_END}`
})
}
} else {
state.value = state.value.replace(what, function (m) { state.store.push(m); return state.token + CHAR_TOKEN_END })
state.value = state.value.replace(what, (m) => {
state.store.push(m)
return state.token + CHAR_TOKEN_END
})
}
return state
},
unguard: function (state, callback) {
unguard (state, callback) {
if (state.indexed === true) {
const detokenizer = new RegExp('(\\w*?)' + state.token + ':(\\d+)' + CHAR_TOKEN_END, 'i')
while (detokenizer.test(state.value)) {
state.value = state.value.replace(detokenizer, function (match, name, index) {
state.value = state.value.replace(detokenizer, (match, name, index) => {
const value = state.store[index - 1]
if (typeof callback === 'function') {
return name + callback(value, name)
}
return name + value
return typeof callback === 'function'
? name + callback(value, name)
: name + value
})
}
return state.value
}
return state.value.replace(new RegExp('(\\w*?)' + state.token + CHAR_TOKEN_END, 'i'), function (match, name) {
return state.value.replace(new RegExp('(\\w*?)' + state.token + CHAR_TOKEN_END, 'i'), (match, name) => {
const value = state.store.shift()
if (typeof callback === 'function') {
return name + callback(value, name)
}
return name + value
return typeof callback === 'function'
? name + callback(value, name)
: name + value
})
},
guardHexColors: function (value) {
guardHexColors (value) {
return this.guard(REGEX_HEX_COLOR, value, true)
},
unguardHexColors: function (state, callback) {
unguardHexColors (state, callback) {
return this.unguard(state, callback)
},
guardFunctions: function (value) {
guardFunctions (value) {
return this.guard(REGEX_FUNCTION, value, true)
},
unguardFunctions: function (state, callback) {
unguardFunctions (state, callback) {
return this.unguard(state, callback)
},
trimDirective: function (value) {
trimDirective (value) {
return value.replace(REGEX_DIRECTIVE, '')
},
regexCache: {},
regexDirective: function (name) {
regexDirective (name) {
// /(?:\/\*(?:!)?rtl:ignore(?::)?)([^]*?)(?:\*\/)/img

@@ -224,15 +240,16 @@ this.regexCache[name] = this.regexCache[name] || new RegExp('(?:\\/\\*\\s*(?:!)?\\s*rtl:' + (name ? escapeRegExp(name) + '(?::)?' : '') + ')([^]*?)(?:\\*\\/)', 'img')

},
regex: function (what, options) {
regex (what, options) {
what = what || []
let expression = ''
for (let x = 0; x < what.length; x++) {
switch (what[x]) {
for (const exp of what) {
switch (exp) {
case 'percent':
expression += '|(' + PATTERN_NUMBER + '%)'
expression += `|(${PATTERN_NUMBER}%)`
break
case 'length':
expression += '|(' + PATTERN_NUMBER + ')(?:ex|ch|r?em|vh|vw|vmin|vmax|px|mm|cm|in|pt|pc)?'
expression += `|(${PATTERN_NUMBER})(?:ex|ch|r?em|vh|vw|vmin|vmax|px|mm|cm|in|pt|pc)?`
break
case 'number':
expression += '|(' + PATTERN_NUMBER + ')'
expression += `|(${PATTERN_NUMBER})`
break

@@ -243,11 +260,13 @@ case 'position':

case 'calc':
expression += '|(calc' + PATTERN_TOKEN + ')'
expression += `|(calc${PATTERN_TOKEN})`
break
}
}
return new RegExp(expression.slice(1), options)
},
isLastOfType: function (node) {
isLastOfType (node) {
let isLast = true
let next = node.next()
while (next) {

@@ -258,4 +277,6 @@ if (next.type === node.type) {

}
next = next.next()
}
return isLast

@@ -267,8 +288,9 @@ },

*/
each: function (array, callback) {
for (let len = 0; len < array.length; len++) {
if (callback(array[len]) === false) {
each (array, callback) {
for (const element of array) {
if (callback(element) === false) {
return false
}
}
return true

@@ -275,0 +297,0 @@ }

{
"author": "Mohammad Younes",
"name": "rtlcss",
"version": "3.4.0",
"version": "3.5.0",
"description": "Framework for transforming cascading style sheets (CSS) from left-to-right (LTR) to right-to-left (RTL)",

@@ -31,15 +31,11 @@ "homepage": "https://rtlcss.com/",

"dependencies": {
"chalk": "^4.1.0",
"find-up": "^5.0.0",
"mkdirp": "^1.0.4",
"postcss": "^8.2.4",
"picocolors": "^1.0.0",
"postcss": "^8.3.11",
"strip-json-comments": "^3.1.1"
},
"devDependencies": {
"mocha": "^9.1.2",
"mocha": "^9.1.3",
"standard": "^16.0.4"
},
"peerDependencies": {
"postcss": "^8.2.4"
},
"scripts": {

@@ -46,0 +42,0 @@ "main": "node ./lib/rtlcss.js",

@@ -9,3 +9,3 @@ # RTLCSS

[![npm version](https://img.shields.io/npm/v/rtlcss)](https://www.npmjs.com/package/rtlcss)
[![Build Status](https://github.com/MohammadYounes/rtlcss/workflows/CI/badge.svg?branch=master)](https://github.com/MohammadYounes/rtlcss/actions?query=workflow%3ACI+branch%3Amaster)
[![Build Status](https://img.shields.io/github/workflow/status/MohammadYounes/rtlcss/CI/master?label=CI&logo=github)](https://github.com/MohammadYounes/rtlcss/actions?query=workflow%3ACI+branch%3Amaster)
[![Dependencies](https://img.shields.io/david/MohammadYounes/rtlcss)](https://david-dm.org/MohammadYounes/rtlcss)

@@ -37,2 +37,2 @@

RTLCSS is saving you and your team a tremendous amount of time and effort? [Buy Me a Coffee ☕](https://www.paypal.me/MohammadYounes)
RTLCSS is saving you and your team a tremendous amount of time and effort? [Buy Me a Coffee ☕](https://www.paypal.me/MohammadYounes)
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc