Chris@18
|
1 /**
|
Chris@18
|
2 * @file
|
Chris@18
|
3 * Provides styles for CKEditor inside off-canvas dialogs.
|
Chris@18
|
4 */
|
Chris@18
|
5
|
Chris@18
|
6 (($, CKEDITOR) => {
|
Chris@18
|
7 /**
|
Chris@18
|
8 * Takes a string of CKEditor CSS and modifies it for use in off-canvas.
|
Chris@18
|
9 *
|
Chris@18
|
10 * @param {string} originalCss
|
Chris@18
|
11 * The CSS rules from CKEditor.
|
Chris@18
|
12 * @return {string}
|
Chris@18
|
13 * The rules from originalCss with extra specificity for off-canvas.
|
Chris@18
|
14 */
|
Chris@18
|
15 const convertToOffCanvasCss = originalCss => {
|
Chris@18
|
16 const selectorPrefix = '#drupal-off-canvas ';
|
Chris@18
|
17 const skinPath = `${CKEDITOR.basePath}${CKEDITOR.skinName}/`;
|
Chris@18
|
18 const css = originalCss
|
Chris@18
|
19 .substring(originalCss.indexOf('*/') + 2)
|
Chris@18
|
20 .trim()
|
Chris@18
|
21 .replace(/}/g, `}${selectorPrefix}`)
|
Chris@18
|
22 .replace(/,/g, `,${selectorPrefix}`)
|
Chris@18
|
23 .replace(/url\(/g, skinPath);
|
Chris@18
|
24 return `${selectorPrefix}${css}`;
|
Chris@18
|
25 };
|
Chris@18
|
26
|
Chris@18
|
27 /**
|
Chris@18
|
28 * Inserts CSS rules into DOM.
|
Chris@18
|
29 *
|
Chris@18
|
30 * @param {string} cssToInsert
|
Chris@18
|
31 * CSS rules to be inserted
|
Chris@18
|
32 */
|
Chris@18
|
33 const insertCss = cssToInsert => {
|
Chris@18
|
34 const offCanvasCss = document.createElement('style');
|
Chris@18
|
35 offCanvasCss.innerHTML = cssToInsert;
|
Chris@18
|
36 offCanvasCss.setAttribute('id', 'ckeditor-off-canvas-reset');
|
Chris@18
|
37 document.body.appendChild(offCanvasCss);
|
Chris@18
|
38 };
|
Chris@18
|
39
|
Chris@18
|
40 /**
|
Chris@18
|
41 * Adds CSS so CKEditor is styled properly in off-canvas.
|
Chris@18
|
42 */
|
Chris@18
|
43 const addCkeditorOffCanvasCss = () => {
|
Chris@18
|
44 // If #ckeditor-off-canvas-reset exists, this has already run.
|
Chris@18
|
45 if (document.getElementById('ckeditor-off-canvas-reset')) {
|
Chris@18
|
46 return;
|
Chris@18
|
47 }
|
Chris@18
|
48 // CKEDITOR.skin.getPath() requires the CKEDITOR.skinName property.
|
Chris@18
|
49 // @see https://stackoverflow.com/a/17336982
|
Chris@18
|
50 CKEDITOR.skinName = CKEDITOR.skin.name;
|
Chris@18
|
51
|
Chris@18
|
52 // Get the paths to the css CKEditor is using.
|
Chris@18
|
53 const editorCssPath = CKEDITOR.skin.getPath('editor');
|
Chris@18
|
54 const dialogCssPath = CKEDITOR.skin.getPath('dialog');
|
Chris@18
|
55
|
Chris@18
|
56 // The key for cached CSS in localStorage is based on the CSS paths.
|
Chris@18
|
57 const storedOffCanvasCss = window.localStorage.getItem(
|
Chris@18
|
58 `Drupal.off-canvas.css.${editorCssPath}${dialogCssPath}`,
|
Chris@18
|
59 );
|
Chris@18
|
60
|
Chris@18
|
61 // See if CSS is cached in localStorage, and use that when available.
|
Chris@18
|
62 if (storedOffCanvasCss) {
|
Chris@18
|
63 insertCss(storedOffCanvasCss);
|
Chris@18
|
64 return;
|
Chris@18
|
65 }
|
Chris@18
|
66
|
Chris@18
|
67 // If CSS unavailable in localStorage, get the files via AJAX and parse.
|
Chris@18
|
68 $.when($.get(editorCssPath), $.get(dialogCssPath)).done(
|
Chris@18
|
69 (editorCss, dialogCss) => {
|
Chris@18
|
70 const offCanvasEditorCss = convertToOffCanvasCss(editorCss[0]);
|
Chris@18
|
71 const offCanvasDialogCss = convertToOffCanvasCss(dialogCss[0]);
|
Chris@18
|
72 const cssToInsert = `#drupal-off-canvas .cke_inner * {background: transparent;}
|
Chris@18
|
73 ${offCanvasEditorCss}
|
Chris@18
|
74 ${offCanvasDialogCss}`;
|
Chris@18
|
75 insertCss(cssToInsert);
|
Chris@18
|
76
|
Chris@18
|
77 // The localStorage key for accessing the cached CSS is based on the
|
Chris@18
|
78 // paths of the CKEditor CSS files. This prevents localStorage from
|
Chris@18
|
79 // providing outdated CSS. If new files are used due to using a new
|
Chris@18
|
80 // skin, a new localStorage key is created.
|
Chris@18
|
81 //
|
Chris@18
|
82 // The CSS paths also include the cache-busting query string that is
|
Chris@18
|
83 // stored in state and CKEDITOR.timestamp. This query string changes on
|
Chris@18
|
84 // update and cache clear and prevents localStorage from providing
|
Chris@18
|
85 // stale CKEditor CSS.
|
Chris@18
|
86 //
|
Chris@18
|
87 // Before adding the CSS rules to localStorage, there is a check that
|
Chris@18
|
88 // confirms the cache-busting query (CKEDITOR.timestamp) is in the CSS
|
Chris@18
|
89 // paths. This prevents localStorage from caching something unbustable.
|
Chris@18
|
90 //
|
Chris@18
|
91 // @see ckeditor_library_info_alter()
|
Chris@18
|
92 if (
|
Chris@18
|
93 CKEDITOR.timestamp &&
|
Chris@18
|
94 editorCssPath.indexOf(CKEDITOR.timestamp) !== -1 &&
|
Chris@18
|
95 dialogCssPath.indexOf(CKEDITOR.timestamp) !== -1
|
Chris@18
|
96 ) {
|
Chris@18
|
97 window.localStorage.setItem(
|
Chris@18
|
98 `Drupal.off-canvas.css.${editorCssPath}${dialogCssPath}`,
|
Chris@18
|
99 cssToInsert,
|
Chris@18
|
100 );
|
Chris@18
|
101 }
|
Chris@18
|
102 },
|
Chris@18
|
103 );
|
Chris@18
|
104 };
|
Chris@18
|
105
|
Chris@18
|
106 addCkeditorOffCanvasCss();
|
Chris@18
|
107 })(jQuery, CKEDITOR);
|