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

[core] Simplify/Cleanup StyleManager #959

Merged
merged 3 commits into from
Apr 15, 2024
Merged
Show file tree
Hide file tree
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
55 changes: 33 additions & 22 deletions spec/style-manager-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,98 +147,109 @@ describe('StyleManager', () => {
// go looking for cached files, and will always use the css provided

it('does not upgrade already wrapped math', () => {
let upgradedSheet = mathStyleManager.upgradeDeprecatedMathUsageForStyleSheet(
let upgradedSheet = mathStyleManager.upgradeStyleSheet(
"p { padding: calc(10px/2); }",
{}
{},
"math"
);
expect(upgradedSheet.source).toEqual("p { padding: calc(10px/2); }");
});

it('does not upgrade negative numbers', () => {
let upgradedSheet = mathStyleManager.upgradeDeprecatedMathUsageForStyleSheet(
let upgradedSheet = mathStyleManager.upgradeStyleSheet(
"p { padding: 0 -1px; }",
{}
{},
"math"
);
expect(upgradedSheet.source).toEqual("p { padding: 0 -1px; }");
});

it('upgrades simple division', () => {
let upgradedSheet = mathStyleManager.upgradeDeprecatedMathUsageForStyleSheet(
let upgradedSheet = mathStyleManager.upgradeStyleSheet(
"p { padding: 10px/2; }",
{}
{},
"math"
);
expect(upgradedSheet.source).toEqual("p { padding: calc(10px/2); }");
});

it('upgrades multi parameter math', () => {
let upgradedSheet = mathStyleManager.upgradeDeprecatedMathUsageForStyleSheet(
let upgradedSheet = mathStyleManager.upgradeStyleSheet(
"p { padding: 0 10px/2 5em; }",
{}
{},
"math"
);
expect(upgradedSheet.source).toEqual("p { padding: 0 calc(10px/2) 5em; }");
});

it('upgrades math with spaces', () => {
let upgradedSheet = mathStyleManager.upgradeDeprecatedMathUsageForStyleSheet(
let upgradedSheet = mathStyleManager.upgradeStyleSheet(
"p { padding: 10px / 2; }",
{}
{},
"math"
);
expect(upgradedSheet.source).toEqual("p { padding: calc(10px / 2); }");
});

it('upgrades multiple math expressions in a single line', () => {
let upgradedSheet = mathStyleManager.upgradeDeprecatedMathUsageForStyleSheet(
let upgradedSheet = mathStyleManager.upgradeStyleSheet(
"p { padding: 10px/2 10px/3; }",
{}
{},
"math"
);
expect(upgradedSheet.source).toEqual("p { padding: calc(10px/2) calc(10px/3); }");
});

it('does not upgrade base64 strings', () => {
// Regression Check
let upgradedSheet = mathStyleManager.upgradeDeprecatedMathUsageForStyleSheet(
let upgradedSheet = mathStyleManager.upgradeStyleSheet(
"p { cursor: -webkit-image-set(url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAAL0lEQVQoz2NgCD3x//9/BhBYBWdhgFVAiVW4JBFKGIa4AqD0//9D3pt4I4tAdAMAHTQ/j5Zom30AAAAASUVORK5CYII=')); }",
{}
{},
"math"
);
expect(upgradedSheet.source).toEqual(
"p { cursor: -webkit-image-set(url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAAL0lEQVQoz2NgCD3x//9/BhBYBWdhgFVAiVW4JBFKGIa4AqD0//9D3pt4I4tAdAMAHTQ/j5Zom30AAAAASUVORK5CYII=')); }"
);
});

it('does not modify hsl function where `/` is valid', () => {
let upgradedSheet = mathStyleManager.upgradeDeprecatedMathUsageForStyleSheet(
let upgradedSheet = mathStyleManager.upgradeStyleSheet(
"p { caret-color: hsl(228deg 4% 24% / 0.8); }",
{}
{},
"math"
);
expect(upgradedSheet.source).toEqual(
"p { caret-color: hsl(228deg 4% 24% / 0.8); }"
);
});

it('does not modify acos function, where math is valid', () => {
let upgradedSheet = mathStyleManager.upgradeDeprecatedMathUsageForStyleSheet(
let upgradedSheet = mathStyleManager.upgradeStyleSheet(
"p { transform: rotate(acos(2 * 0.125)); }",
{}
{},
"math"
);
expect(upgradedSheet.source).toEqual(
"p { transform: rotate(acos(2 * 0.125)); }"
);
});

it('recognizes valid less variables: right side', () => {
let upgradedSheet = mathStyleManager.upgradeDeprecatedMathUsageForStyleSheet(
let upgradedSheet = mathStyleManager.upgradeStyleSheet(
"p { padding: @size + 12px; }",
{}
{},
"math"
);
expect(upgradedSheet.source).toEqual(
"p { padding: calc(@size + 12px); }"
);
});

it('recognizes valid less variables: left side', () => {
let upgradedSheet = mathStyleManager.upgradeDeprecatedMathUsageForStyleSheet(
let upgradedSheet = mathStyleManager.upgradeStyleSheet(
"p { padding: 12px + @size; }",
{}
{},
"math"
);
expect(upgradedSheet.source).toEqual(
"p { padding: calc(12px + @size); }"
Expand Down
112 changes: 53 additions & 59 deletions src/style-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,50 +144,54 @@ module.exports = class StyleManager {
}
}

if (params.skipDeprecatedSelectorsTransformation) {
styleElement.textContent = source;
} else {
const transformed = this.upgradeDeprecatedSelectorsForStyleSheet(
source,
params.context
let textContent = source
let deprecationMessages = [];

if (!params.skipDeprecatedSelectorsTransformation) {
const transformed = this.upgradeStyleSheet(
textContent,
params.context,
transformDeprecatedShadowDOMSelectors
);
styleElement.textContent = transformed.source;
if (transformed.deprecationMessage) {
this.deprecationsBySourcePath[params.sourcePath] = {
message: transformed.deprecationMessage
};
this.emitter.emit('did-update-deprecations');
}

textContent = transformed.source;
deprecationMessages.push(transformed.deprecationMessage);
}

if (!params.skipDeprecatedMathUsageTransformation) {
const transformed = this.upgradeDeprecatedMathUsageForStyleSheet(
styleElement.textContent,
params.context
const transformed = this.upgradeStyleSheet(
textContent,
params.context,
transformDeprecatedMathUsage
);
styleElement.textContent = transformed.source;
if (transformed.deprecationMessage) {
// Now we may already have a deprecation message from upgrading deprecated
// selectors, so we want to check if the message already exists for this
// source path, and add to it, otherwise we can create a new one
if (typeof this.deprecationsBySourcePath[params.sourcePath]?.message === "string") {
this.deprecationsBySourcePath[params.sourcePath].message += `\n${transformed.deprecationMessage}`;
this.emitter.emit('did-update-deprecations');
} else {
// lets create a new deprecation
this.deprecationsBySourcePath[params.sourcePath] = {
message: transformed.deprecationMessage
};
this.emitter.emit('did-update-deprecations');
}
}

textContent = transformed.source;
deprecationMessages.push(transformed.deprecationMessage);
}

// Once done with any and all transformations we can apply our new textContent
styleElement.textContent = textContent;

// Reduce the deprecation messages array to remove any null, undefined, or empty text values
// Anything not 'truthy'
deprecationMessages = deprecationMessages.filter((ele) => ele);

if (deprecationMessages.length > 0) {
// we do in fact have deprecations
let deprecationMsg = deprecationMessages.join("\n");

this.deprecationsBySourcePath[params.sourcePath] = {
message: deprecationMsg
};
this.emitter.emit("did-update-deprecations");
}

if (updated) {
this.emitter.emit('did-update-style-element', styleElement);
this.emitter.emit("did-update-style-element", styleElement);
} else {
this.addStyleElement(styleElement);
}

return new Disposable(() => {
this.removeStyleElement(styleElement);
});
Expand Down Expand Up @@ -226,46 +230,36 @@ module.exports = class StyleManager {
}
}

upgradeDeprecatedSelectorsForStyleSheet(styleSheet, context) {
if (this.cacheDirPath != null) {
const hash = crypto.createHash('sha1');
if (context != null) {
hash.update(context);
}
hash.update(styleSheet);
const cacheFilePath = path.join(this.cacheDirPath, hash.digest('hex'));
try {
return JSON.parse(fs.readFileSync(cacheFilePath));
} catch (e) {
const transformed = transformDeprecatedShadowDOMSelectors(
styleSheet,
context
);
fs.writeFileSync(cacheFilePath, JSON.stringify(transformed));
return transformed;
}
} else {
return transformDeprecatedShadowDOMSelectors(styleSheet, context);
// Wrapper function useful for applying any upgrades due to deprecations
upgradeStyleSheet(styleSheet, context, upgradeName) {
let cb;

// Allows us to utilize a direct callback, or if calling from outside
// StyleManager we can define a string that works
if (upgradeName === "math") {
cb = upgradeDeprecatedMathUsageForStyleSheet;
} else if (upgradeName === "selector") {
cb = transformDeprecatedShadowDOMSelectors;
} else if (typeof upgradeName === "function") {
cb = upgradeName;
}
}

upgradeDeprecatedMathUsageForStyleSheet(styleSheet, context) {
if (this.cacheDirPath != null) {
const hash = crypto.createHash('sha1');
const hash = crypto.createHash("sha1");
if (context != null) {
hash.update(context);
}
hash.update(styleSheet);
const cacheFilePath = path.join(this.cacheDirPath, hash.digest('hex'));
const cacheFilePath = path.join(this.cacheDirPath, hash.digest("hex"));
try {
return JSON.parse(fs.readFileSync(cacheFilePath));
} catch(e) {
const transformed = transformDeprecatedMathUsage(styleSheet, context);
const transformed = cb(styleSheet, context);
fs.writeFileSync(cacheFilePath, JSON.stringify(transformed));
return transformed;
}
} else {
return transformDeprecatedMathUsage(styleSheet, context);
return cb(styleSheet, context);
}
}

Expand Down
Loading