Skip to content

Commit

Permalink
perf: lazy rule precedence calculation
Browse files Browse the repository at this point in the history
  • Loading branch information
kripod committed Jul 21, 2020
1 parent 046145a commit a1eff01
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 25 deletions.
51 changes: 28 additions & 23 deletions packages/otion/src/createInstance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ import {
import { minifyCondition, minifyValue } from "./minify";
import {
PROPERTY_ACCEPTS_UNITLESS_VALUES,
PROPERTY_PRECEDENCE_FIX_GROUPS,
PROPERTY_PRECEDENCE_CORRECTION_GROUPS,
} from "./propertyMatchers";
import { PRECEDENCES_BY_PSEUDO_CLASS } from "./pseudos";

const MAX_CLASS_NAME_LENGTH = 9;
export const PRECEDENCE_GROUP_COUNT = 36;

function toHyphenLower(match: string): string {
return `-${match.toLowerCase()}`;
Expand Down Expand Up @@ -100,6 +101,10 @@ export function createInstance(): OtionInstance {
let prefix: (property: string, value: string) => string;
let insertedIdentNames: Set<string>;

const lastRuleIndexesByPrecedenceGroup = new Uint16Array(
PRECEDENCE_GROUP_COUNT,
);

function checkSetup(): void {
if (!injector || !prefix || !insertedIdentNames) {
throw new Error(
Expand Down Expand Up @@ -173,29 +178,29 @@ export function createInstance(): OtionInstance {
const declarations = serializeDeclarationList(property, value);
const className = `_${hash(cssTextHead + declarations)}`;

// The property's baseline precedence is based on dash (`-`) counting
const unprefixedProperty =
property[0] !== "-"
? property
: property.slice(property.indexOf("-", 1)) + 1;
let precedence = 1;
let position = 1; // First character of the property can't be `-`
while (
// eslint-disable-next-line no-cond-assign
(position = unprefixedProperty.indexOf("-", position) + 1) > 0
) {
++precedence;
}

// Handle properties which don't conform to the rule above
const matches = PROPERTY_PRECEDENCE_FIX_GROUPS.exec(
unprefixedProperty,
);
const scopeSelector = `.${className}`.repeat(
precedence + (matches ? +!!matches[1] || -!!matches[2] : 0),
);

if (!insertedIdentNames.has(className)) {
// The property's baseline precedence is based on dash (`-`) counting
const unprefixedProperty =
property[0] !== "-"
? property
: property.slice(property.indexOf("-", 1)) + 1;
const correctiveMatches = PROPERTY_PRECEDENCE_CORRECTION_GROUPS.exec(
unprefixedProperty,
);
let precedence =
(correctiveMatches
? +!!correctiveMatches[1] /* +1 */ ||
-!!correctiveMatches[2] /* -1 */
: 0) + 1;
let position = 1; // First character of the property can't be `-`
while (
// eslint-disable-next-line no-cond-assign
(position = unprefixedProperty.indexOf("-", position) + 1) > 0
) {
++precedence;
}

const scopeSelector = `.${className}`.repeat(precedence);
injector.insert(
`${
cssTextHead.slice(0, classSelectorStartIndex) +
Expand Down
4 changes: 2 additions & 2 deletions packages/otion/src/propertyMatchers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,10 @@ export const propertiesAcceptingUnitlessValues = [
"initial-letter",
];

export const PROPERTY_PRECEDENCE_FIX_GROUPS = /^(?:(border-(?!w|c|sty)|[tlbr].{2,4}m?$|c.{7}$)|([fl].{5}l|g.{8}$|pl))/;
export const PROPERTY_PRECEDENCE_CORRECTION_GROUPS = /^(?:(border-(?!w|c|sty)|[tlbr].{2,4}m?$|c.{7}$)|([fl].{5}l|g.{8}$|pl))/;

// TODO: Add tests to match everything below, with no conflicting longhands
export const propertiesByPrecedenceFixGroup = {
export const propertiesByPrecedenceCorrectionGroup = {
"+1": [
/* ^border-(?!w|c|sty) */
"border-!(width,color,style)",
Expand Down

0 comments on commit a1eff01

Please sign in to comment.