diff --git a/README.md b/README.md index c023c887..a3791f4f 100644 --- a/README.md +++ b/README.md @@ -382,6 +382,8 @@ All the options are optional, and a default value will be used if any of them is | stringMap | `PluginStringMap[]` | Check below | An array of strings maps that will be used to make the replacements of the declarations' URLs and to match the names of the rules if `processRuleNames` is `true` | | greedy | `boolean` | `false` | When greedy is `true`, the matches of `stringMap` will not take into account word boundaries | | aliases | `Record` | `{}` | A strings map to treat some declarations as others | +| plugins | `Array<{name: string, key?: string}>` | `[]` | A list of RTLCSS plugins | +| hooks | `{pre?: function, post?: function}` | `{}` | RTLCSS hooks | --- @@ -1447,6 +1449,108 @@ const options = { --- +#### plugins + +
Expand +

+ +RTLCSS support to extend itself via [plugins](https://rtlcss.com/learn/extending-rtlcss/writing-a-plugin/) + +##### input + +```css +.test { + background-position: 0 100%; +} +``` + +##### Convert `0` to `100%` (default) + +##### output + +```css +.test { + background-position: 100% 100%; +} +``` + +##### Set a plugin to avoid flipping + +```javascript +const options = { + plugins: [ + { + name: 'ignore-background', + priority: 99, // above the core RTLCSS plugin which has a priority value of 100 + directives: { + control: {}, + value: [] + }, + processors: [{ + expr: /(background|object)(-position(-x)?|-image)?$/i, + action: (prop, value) => ({prop, value})} + ] + } + ] +}; +``` + +##### output + +```css +.test { + background-position: 0 100%; +} +``` + +

+ +
+ +--- + +#### hooks + +
Expand +

+ +RTLCSS support to set up [hooks](https://rtlcss.com/learn/usage-guide/hooks/) before of after processing the CSS. + +##### input + +```css +body { + direction: ltr; +} +``` + +##### Set a plugin to add comments + +```javascript +const options = { + hooks: { + post(root, postcss) { + root.insertBefore(root.nodes[0], postcss.comment({text: 'Generated by RTLCSS'})); + } + } +}; +``` + +##### output + +```css +/* Generated by RTLCSS */ +body { + direction: ltr; +} +``` + +

+ +
+ +--- + Control Directives --- diff --git a/src/@types/index.ts b/src/@types/index.ts index 4bcc49e0..7f61bc07 100644 --- a/src/@types/index.ts +++ b/src/@types/index.ts @@ -3,6 +3,7 @@ import { AtRule, Declaration } from 'postcss'; +import {Plugin, HookOptions} from 'rtlcss'; export enum Mode { combined = 'combined', @@ -58,6 +59,8 @@ export interface PluginOptions { stringMap?: PluginStringMap[]; greedy?: boolean; aliases?: Record; + plugins?: Plugin[]; + hooks?: HookOptions; } export interface PluginOptionsNormalized extends Omit, 'stringMap' | 'prefixSelectorTransformer'> { diff --git a/src/data/store.ts b/src/data/store.ts index 8d23ee7f..faf403d7 100644 --- a/src/data/store.ts +++ b/src/data/store.ts @@ -143,7 +143,9 @@ const defaultOptions = (): PluginOptionsNormalized => ({ useCalc: false, stringMap: getRTLCSSStringMap(defaultStringMap), greedy: false, - aliases: {} + aliases: {}, + plugins: [], + hooks: {} }); const store: Store = { @@ -217,7 +219,7 @@ const normalizeOptions = (options: PluginOptions): PluginOptionsNormalized => { if (options.aliases && isObjectWithStringKeys(options.aliases)) { returnOptions.aliases = options.aliases; } - return returnOptions; + return {...returnOptions, plugins: options.plugins, hooks: options.hooks}; }; const initStore = (options: PluginOptions): void => { diff --git a/src/parsers/atrules.ts b/src/parsers/atrules.ts index fedb647f..a4228234 100644 --- a/src/parsers/atrules.ts +++ b/src/parsers/atrules.ts @@ -77,7 +77,7 @@ const addToIgnoreKeyframesInDiffMode = (node: Node): void => { export const parseKeyFrames = (css: Root): void => { - const { source, processUrls, useCalc, stringMap, processKeyFrames } = store.options; + const { source, processUrls, useCalc, stringMap, processKeyFrames, plugins, hooks } = store.options; if (!processKeyFrames) { return; @@ -115,7 +115,7 @@ export const parseKeyFrames = (css: Root): void => { } const atRuleString = atRule.toString(); - const atRuleFlippedString = rtlcss.process(atRuleString, { processUrls, useCalc, stringMap }); + const atRuleFlippedString = rtlcss.process(atRuleString, { processUrls, useCalc, stringMap }, plugins, hooks); if (atRuleString === atRuleFlippedString) { addToIgnoreKeyframesInDiffMode(atRule); diff --git a/src/parsers/declarations.ts b/src/parsers/declarations.ts index 5e5b9b7c..2bf29c1a 100644 --- a/src/parsers/declarations.ts +++ b/src/parsers/declarations.ts @@ -59,7 +59,9 @@ export const parseDeclarations = ( useCalc, stringMap, greedy, - aliases + aliases, + plugins, + hooks } = store.options; const deleteDeclarations: Declaration[] = []; @@ -160,7 +162,7 @@ export const parseDeclarations = ( stringMap, greedy, aliases - }); + }, plugins, hooks); /* the source could be undefined in certain cases but not during the tests */ /* istanbul ignore next */