-
Notifications
You must be signed in to change notification settings - Fork 22
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
Rewrite project to make it smaller, faster and more understandable #72
Conversation
* Finish fixing tests for IE11 * Move code to the src directory
Codecov Report
@@ Coverage Diff @@
## master #72 +/- ##
===========================================
+ Coverage 0 90.86% +90.86%
===========================================
Files 0 5 +5
Lines 0 186 +186
Branches 0 33 +33
===========================================
+ Hits 0 169 +169
- Misses 0 4 +4
- Partials 0 13 +13
Continue to review full report at Codecov.
|
Nice, I’ve actually been meaning to make a ton of these changes but haven’t had the time. I definitely think this constitutes a breaking change so well increment the major version before releasing. There’s a lot here, so it might take me a few days to put it through it’s paces, but my first skim looked good. Not entirely sure about all ES5, but I’ll let it sink in. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a cursory look at this. I'll dive in deeper a bit later.
package.json
Outdated
"typecheck": "tsc --noEmit" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/calebdwilliams/adoptedStyleSheets.git" | ||
}, | ||
"author": "Caleb D. Williams <[email protected]>", | ||
"authors": [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't technically think this is valid in package.json. Can you revert but add a contributors? You certainly deserve credit and I'm more than happy to give it where it's due; really appreciate the effort here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh right. I replaced it with contributors
instead.
src/ConstructedStyleSheet.ts
Outdated
clearRules(basic); | ||
|
||
if (sanitized) { | ||
basic.insertRule(sanitized, 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless I'm missing something this will fail if there is more than one rule in the stylesheet. Changing the test to
headingStyles
.replace(
` h1 {
color: tomato;
} body { background: mediumaquamarine; }`,
)
.then(sheet => {
console.log(`${sheet} styles have been replaced.`);
console.assert(sheet === headingStyles, 'not the same', 'yass');
});
will throw, hence the original innerHTML
call. We could potentially parse the thing with a regexp and see if insertRule is faster, but I doubt it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, thanks! I replaced it with the basic.ownerNode.textContent = sanitized
. It will do all the parsing job for us and still allow using restyleAdopter
with insertRule
approach.
src/Location.ts
Outdated
removedSheets.forEach(function (sheet) { | ||
// Type Note: any removed sheet is already initialized, so there cannot be | ||
// missing adopter for this location. | ||
/*#__INLINE__*/ removeNode(getAdopterByLocation(sheet, self)!); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these /*#__INLINE__*/
comments necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are not but it would allow Terser to understand that these functions can be inlined. I don't want to do that manually because of readability but it would be nice if we give user a chance to reduce some bytes during the minification.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just checked: you're right, they are unnecessary; Terser does inlining based on amount of function calls. So, I removed them.
} | ||
|
||
/*#__PURE__*/ | ||
export function insertAllRules(from: CSSStyleSheet, to: CSSStyleSheet): void { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably want to use this above instead of this.insertRule
. I still wonder about the performance about these two and if it might cause unwanted flash of styles. Should this be in a requestAnimationFrame
? Again, I'm mostly just thinking out loud. I will test these either this weekend or early next week.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried both current and requestAnimationFrame
approaches and don't see any specific difference in visualization and the flame chart. Could you test it as well? I think I would add requestAnimationFrame
call anyway just to be sure it works at correct time.
@Lodin Also, I really think modern syntax like |
Well, I'm ok with it. Just thought that if we try to avoid any compilation artifacts it may be better to use ES5 approach as much as possible. However, I agree with your arguments. |
* Fix issue with multiple rules replacement. * Use let/const and arrow functions wherever possible. * Use "contributors" in package.json
@Lodin, let me know when you're happy with this PR and I'll do a final review. |
@calebdwilliams, it's ready, actually. I'm not going to do further changes before your review. |
@Lodin, I'm ready to merge/publish this, but I would like to do it as a major version/prerelease. In order to do that, I'd prefer to keep it in a different branch for a bit first. Would you mind setting that up so I can merge/release? Great work here, thanks for all your contributions to this project! |
@calebdwilliams, great news! What the branch would you like to use then? Also, what the version should it have? |
I’d keep it simple like 3.0-rc or something like that (I’m not picky). I’ll take care of the version number when I publish it. |
Looks like I can re-direct the PR only if the branch exists. Could you please create a |
@Lodin done |
@calebdwilliams, I have re-directed the PR to the |
@Lodin this has been released as [email protected]. |
This PR introduces a new approach for initializing and supporting the Constructible Style Sheets. It aims to make code smaller, faster and more clear to understand.
Approach
Now we have two logic entrypoints associated with the specific class:
CSSStyleSheet
implementation (associated withConstructedStyleSheet
class).adoptedStyleSheets
property (associated withLocation
class).Details
iframe
element is not used anymore. Instead, the in-memory HTML document created bydocument.implementation.createHTMLDocument()
is used. Thanks to that improvement, we no longer need to rely on the document loading status; in-memory document can be created even in<head>
.replace
andreplaceSync
) are done viaCSSStyleSheet.insertRule
.adoptedStyleSheets
property (Document
andShadowRoot
) is wrapped with the associatedLocation
class instance that watches internal DOM tree and connects (initialzies) each added element; it also disconnects each removed element.ConstructedStyleSheet
no more reveals the internal stylesheet; instead, it imitates theCSSStyleSheet
behavior.adoptedStyleSheets
property works closer to specification and doesn't allow adding non-constructable style sheet.WeakMap
. ForConstructedStyleSheet
it allows avoiding access to internal properties by the end user; forLocation
it reduces the size of the polyfill when minified.husky
package is replaced withsimple-git-hooks
due to license and performance issues.size-limit
package for checking the project size with limit of 2 kB.@rollup/plugin-typescript
is used only becausebabel
does not supportdeclare class A {}
along withfunction A() {}
which is necessary for correct typings of internal classes.@rollup/plugin-typescript
only removes types. For tests, to add coverage@rollup/plugin-babel
is used.Size
size-limit
): 2.12 kB.size-limit
): 1.82 kB.Special thanks
Special thanks to @platosha for suggesting the idea of
document.implementation.createHTMLDocument()
.Breaking changes?
In theory, it shouldn't affect the users because both versions comply the specification of Constructible Style Sheets. Howerver, I would suggest to release it as
beta
first to get the initial user feedback.I would also suggest to merge #34 first. With it, we will be able to run tests in all browsers including Safari and IE11.