Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix re-use data between postcss listeners (#103) #107

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 75 additions & 62 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,18 @@ const defaults = {
rootValue: 16,
unitPrecision: 5,
selectorBlackList: [],
propList: ["font", "font-size", "line-height", "letter-spacing", "word-spacing"],
propList: [
"font",
"font-size",
"line-height",
"letter-spacing",
"word-spacing"
],
replace: true,
mediaQuery: false,
minPixelValue: 0,
exclude: null,
unit: "px",
unit: "px"
};

const legacyOptions = {
Expand All @@ -20,7 +26,7 @@ const legacyOptions = {
selector_black_list: "selectorBlackList",
prop_white_list: "propList",
media_query: "mediaQuery",
propWhiteList: "propList",
propWhiteList: "propList"
};

function convertLegacyOptions(options) {
Expand All @@ -36,7 +42,7 @@ function convertLegacyOptions(options) {
delete options["prop_white_list"];
delete options.propWhiteList;
}
Object.keys(legacyOptions).forEach((key) => {
Object.keys(legacyOptions).forEach(key => {
if (Reflect.has(options, key)) {
options[legacyOptions[key]] = options[key];
delete options[key];
Expand All @@ -61,12 +67,12 @@ function toFixed(number, precision) {
}

function declarationExists(decls, prop, value) {
return decls.some((decl) => decl.prop === prop && decl.value === value);
return decls.some(decl => decl.prop === prop && decl.value === value);
}

function blacklistedSelector(blacklist, selector) {
if (typeof selector !== "string") return;
return blacklist.some((regex) => {
return blacklist.some(regex => {
if (typeof regex === "string") {
return selector.indexOf(regex) !== -1;
}
Expand All @@ -85,31 +91,31 @@ function createPropListMatcher(propList) {
notExact: filterPropList.notExact(propList),
notContain: filterPropList.notContain(propList),
notStartWith: filterPropList.notStartWith(propList),
notEndWith: filterPropList.notEndWith(propList),
notEndWith: filterPropList.notEndWith(propList)
};
return (prop) => {
return prop => {
if (matchAll) return true;
return (
(hasWild ||
lists.exact.indexOf(prop) > -1 ||
lists.contain.some(function (m) {
lists.contain.some(function(m) {
return prop.indexOf(m) > -1;
}) ||
lists.startWith.some(function (m) {
lists.startWith.some(function(m) {
return prop.indexOf(m) === 0;
}) ||
lists.endWith.some(function (m) {
lists.endWith.some(function(m) {
return prop.indexOf(m) === prop.length - m.length;
})) &&
!(
lists.notExact.indexOf(prop) > -1 ||
lists.notContain.some(function (m) {
lists.notContain.some(function(m) {
return prop.indexOf(m) > -1;
}) ||
lists.notStartWith.some(function (m) {
lists.notStartWith.some(function(m) {
return prop.indexOf(m) === 0;
}) ||
lists.notEndWith.some(function (m) {
lists.notEndWith.some(function(m) {
return prop.indexOf(m) === prop.length - m.length;
})
)
Expand All @@ -122,62 +128,69 @@ module.exports = (options = {}) => {
const opts = Object.assign({}, defaults, options);
const satisfyPropList = createPropListMatcher(opts.propList);
const exclude = opts.exclude;
let isExcludeFile = false;
let pxReplace;
return {
postcssPlugin: "postcss-pxtorem",
Once(css) {
const filePath = css.source.input.file;
if (
exclude &&
((type.isFunction(exclude) && exclude(filePath)) ||
(type.isString(exclude) && filePath.indexOf(exclude) !== -1) ||
filePath.match(exclude) !== null)
) {
isExcludeFile = true;
} else {
isExcludeFile = false;
}
prepare() {
let isExcludeFile = false;
let pxReplace;
return {
Once(css) {
const filePath = css.source.input.file;
if (
exclude &&
((type.isFunction(exclude) && exclude(filePath)) ||
(type.isString(exclude) && filePath.indexOf(exclude) !== -1) ||
filePath.match(exclude) !== null)
) {
isExcludeFile = true;
} else {
isExcludeFile = false;
}

const rootValue =
typeof opts.rootValue === "function"
? opts.rootValue(css.source.input)
: opts.rootValue;
pxReplace = createPxReplace(
rootValue,
opts.unitPrecision,
opts.minPixelValue,
);
},
Declaration(decl) {
if (isExcludeFile) return;
const rootValue =
typeof opts.rootValue === "function"
? opts.rootValue(css.source.input)
: opts.rootValue;
pxReplace = createPxReplace(
rootValue,
opts.unitPrecision,
opts.minPixelValue
);
},
Declaration(decl) {
if (isExcludeFile) return;

if (
decl.value.indexOf(opts.unit) === -1 ||
!satisfyPropList(decl.prop) ||
blacklistedSelector(opts.selectorBlackList, decl.parent.selector)
)
return;
if (
decl.value.indexOf(opts.unit) === -1 ||
!satisfyPropList(decl.prop) ||
blacklistedSelector(opts.selectorBlackList, decl.parent.selector)
)
return;

const value = decl.value.replace(pxRegex(opts.unit), pxReplace);
const value = decl.value.replace(pxRegex(opts.unit), pxReplace);

// if rem unit already exists, do not add or replace
if (declarationExists(decl.parent, decl.prop, value)) return;
// if rem unit already exists, do not add or replace
if (declarationExists(decl.parent, decl.prop, value)) return;

if (opts.replace) {
decl.value = value;
} else {
decl.cloneAfter({ value: value });
}
},
AtRule(atRule) {
if (isExcludeFile) return;
if (opts.replace) {
decl.value = value;
} else {
decl.cloneAfter({ value: value });
}
},
AtRule(atRule) {
if (isExcludeFile) return;

if (opts.mediaQuery && atRule.name === "media") {
if (atRule.params.indexOf(opts.unit) === -1) return;
atRule.params = atRule.params.replace(pxRegex(opts.unit), pxReplace);
}
},
if (opts.mediaQuery && atRule.name === "media") {
if (atRule.params.indexOf(opts.unit) === -1) return;
atRule.params = atRule.params.replace(
pxRegex(opts.unit),
pxReplace
);
}
}
};
}
};
};
module.exports.postcss = true;