Problem/Motivation
In #2952390: Off-canvas styles override CKEditor's reset and theme, a patch was committed that uses localStorage to cache previously processed CSS files. The localStorage key is based on the full path to the CSS file, including the query param, i.e. Drupal.off-canvas.css.http://drupal.localhost/core/assets/vendor/ckeditor/skins/moono-lisa/editor.css?t=pv9p89http://drupal.localhost/core/assets/vendor/ckeditor/skins/moono-lisa/dialog.css?t=pv9p89
. If a user visits a site enough times without clearing their browser's localStorage, their browser's localStorage limit (on mine it's 5MB) will have been met, which throws an error like:
Failed to set the [...] property on 'Storage': Setting the value of [...] exceeded the quota.
Proposed resolution
Expire older items from the localStorage cache, or stop using localStorage for this use case. The CSS file for CKEditor could be quite large so putting it all in localStorage doesn't seem efficient.
Remaining tasks
Determine a path forward and write a patch.
User interface changes
None.
API changes
None.
Data model changes
None.
Release notes snippet
None.
Comment | File | Size | Author |
---|---|---|---|
#32 | reroll_diff_30-32.txt | 1.59 KB | AndyF |
#32 | 3070745-32-9.0.patch | 3.69 KB | AndyF |
#30 | 3070745-30.patch | 3.68 KB | AndyF |
#25 | 3070745-25.patch | 3.54 KB | AndyF |
#23 | 3070745-23.patch | 3.69 KB | AndyF |
Comments
Comment #2
cilefen CreditAttribution: cilefen as a volunteer commented#3076641: Can't edit or save content with very long texts
Comment #3
droplet CreditAttribution: droplet commentedthat patch has few problems:
1.
Should be 2 keys
CKEDITOR_TIMESTAMP: pwr2i2
CKEDITOR_CSS_RESET: css
2.
This is even loaded or inserted even the CKEDITOR hasn't used inside the Tray or starting to use Tray
3.
A bit odd to inserted into BODY and bottom.
4.
Possible hit cross-origin and can't load.
$.when($.get(editorCssPath), $.get(dialogCssPath))
5.
I know @nod_ put a lot of effort to get rid of the shorthand function.
$.when($.get(editorCssPath), $.get(dialogCssPath)).done(
Comment #4
olli CreditAttribution: olli commentedHere is a patch that removes previous items before adding a new one.
Comment #6
super_romeo CreditAttribution: super_romeo as a volunteer commentedComment #7
claudiu.cristeaClosed #3098917: CKEDITOR error for Drupal 8.8.0 as it duplicates this one.
Comment #8
ocastle CreditAttribution: ocastle at Full Bundle commentedPatch #4 seems to have solved the issue for me. No longer receiving the console error.
Comment #9
tedbow@olli thanks for the patch. 1 suggestion
I think it would simpler to use
Object.keys()
like
Comment #10
jedgar1mx CreditAttribution: jedgar1mx commented#4 works Thanks
Comment #11
ravi.shankar CreditAttribution: ravi.shankar at OpenSense Labs commentedHere I have made changes as suggested in comment #9.
Comment #12
interdruper CreditAttribution: interdruper at Interdruper commented#11 fixes the problem for me. Thanks.
Comment #13
tedbow+1 on the RTBC, It address my only suggesting in #9. Thanks @ravi.shankar
@interdruper thanks for reporting that it fixed the issue.
In the future though when you set a patch to
Reviewed & tested by the community
make it clear that you have reviewed the patch and that it addresses any outstanding feedback on the issue.If you aren't able to review the patch reporting that it fixed the problem is very helpful.. It is just not "Reviewed & tested by the community"
Comment #14
alexpottCan we add an assertion to
\Drupal\Tests\ckeditor\FunctionalJavascript\CKEditorIntegrationTest::testOffCanvasStyles()
to prove this is fixed?Comment #15
AndyF CreditAttribution: AndyF at Fabb commentedThanks @alexpott, I've added a test for that. It could probably be made a bit quicker by using
_drupal_flush_css_js()
but I thought that might be considered a little dirty (: Also it evalsObject.keys()
in the browser session, which AFAICT is fine from a compatibility PoV, but I can see that it's transformed in our ES6 files so thought I should highlight it.IIUC as the patch stands if you cache any styles, than you'll always have some cached styles, even if you've stopped using the site. I was just wondering if it made sense to switch to using session storage? It's a trade-off: as I understand it this would mean multiple parsing and storage of styles if there are multiple tabs open or if you close a tab and revisit the site later while the cache would still be valid; but on the positive it wouldn't need any cache invalidation logic and wouldn't leave a permanent footprint. Just a thought...
Thanks!
Comment #16
AndyF CreditAttribution: AndyF at Fabb commentedUpdate tags
Comment #18
AndyF CreditAttribution: AndyF at Fabb commentedTests pass and fail as expected, moving to need review.
Comment #19
tedbow@AndyF thanks for the test! Looks mostly good.
I think we should be even more explicit here.
This just tests for sure that there is only 1 key not that it is not the same as the key before.
Before this whole new code but we should tests the keys but instead of returning
.length
from the JS we should return the actually keys and do$this->assertCount(1, $cached_keys);
Then after instead here we could do
So we would know before and after there was 1 key and it is different after.
We could store the JS string as a var since we would use the exact same JS 2x
Comment #20
AndyF CreditAttribution: AndyF at Fabb commentedThanks for the review @tedbow! I've updated it to also test that the cache is actually busted.
Comment #22
tedbow@AndyF thanks updating the test.! 1 more suggestion. sorry trying to look at this test like I didn't know how the tested code is written.
So because we never do
$this->assertCount(1, $old_keys);
When we assert
assertNotEquals()
we don't 100% know that the $new_keys aren't in the $old_keys array.It could be the $old_keys array had a count of 2 and it contained the 1 element in the $new_keys array.
If we knew that
count($old_keys) === 1
we could be sure when we$this->assertNotEquals($old_keys, $new_keys);
They aren't just not equal because $old_keys has some extra element.I know this couldn't be the case now but putting this 1 extra check in makes sure that if something changes in the JS and this happens this test will stop passing(as it should)
Comment #23
AndyF CreditAttribution: AndyF at Fabb commentedThanks again @tedbow for the thoughtful review!
👍 Understood, updated.
Comment #24
tedbowThis looks great now! Thanks
I think this is now out of sync
I ran
yarn build:js
and this filed changed a bunch.
This should be run and updated.
besides the last point I think this is RTBC
Comment #25
AndyF CreditAttribution: AndyF at Fabb commentedThanks @tedbow, it looks like #11 only updated the ES6 (which led me to incorrectly say in #15 that
Object.keys()
gets transformed, turns out it doesn't). I've attached the regenerated JS, cheers!Comment #26
tedbow@AndyF thanks!
I ran
yarn build:js
locally and now no changes were made!
Comment #28
AndyF CreditAttribution: AndyF at Fabb commentedI think that's the random test failure from #3066447: [random test failure] Random failures building media library form after uploading image (WidgetUploadTest): moving back to RTBC, thanks.
Comment #29
catchIf we have to reset the css/js query string anyway, do we need to flush all caches? And if we do, could we add a comment explaining why both are necessary?
Comment #30
AndyF CreditAttribution: AndyF at Fabb commentedThanks @catch. As I understand it we just need
ckeditor_library_info_alter()
to run again to update the timestamp indrupalSettings
(the test fails without the cache clear). Here's an updated patch, cheers!Comment #31
catchThis now needs a 9.0.x version of the patch.
Comment #32
AndyF CreditAttribution: AndyF at Fabb commentedThanks, here's #30 rolled against 9.0.x.
Comment #33
AndyF CreditAttribution: AndyF at Fabb commentedTests pass - as it's a reroll I think it's ok to put back to RTBC, thanks!
Comment #35
catchUpdating credit.
Comment #39
catchCommitted 8d5200a and pushed to 9.1.x, cherry-picked to 9.0.x, 8.9.x and 8.8.x. Thanks!