Skip to content

Commit

Permalink
Merge pull request #959 from pulsar-edit/refactor-style-manager
Browse files Browse the repository at this point in the history
[core] Simplify/Cleanup `StyleManager`
  • Loading branch information
confused-Techie authored Apr 15, 2024
2 parents 41d8915 + 83f98e9 commit cf7040e
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 81 deletions.
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

0 comments on commit cf7040e

Please sign in to comment.