@brightspace-ui/core 2.27.0 → 2.28.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,47 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <title>d2l-html-block (code samples)</title>
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <meta charset="UTF-8">
7
+ <link rel="stylesheet" href="../../demo/styles.css" type="text/css">
8
+ <script type="module">
9
+ import '../../colors/colors.js';
10
+ import '../../typography/typography.js';
11
+ import '../html-block.js';
12
+ </script>
13
+ <style>
14
+ html {
15
+ font-size: 20px;
16
+ }
17
+ body {
18
+ padding: 1rem;
19
+ }
20
+ </style>
21
+ </head>
22
+ <body class="d2l-typography">
23
+
24
+ <h1 class="d2l-heading-2">d2l-html-block (code)</h1>
25
+
26
+ <h2 class="d2l-heading-3">Block Samples</h2>
27
+
28
+ <d2l-html-block>
29
+ <pre class="d2l-code d2l-code-dark"><code class="language-javascript">function helloGrumpy(name) {
30
+ console.log(`Hi there ${name}.`);
31
+ }
32
+ helloGrumpy('Wizard');</code></pre>
33
+ <br>
34
+ <pre class="d2l-code d2l-code-dark"><code class="language-javascript line-numbers">function helloGrumpy(name) {
35
+ console.log(`Hi there ${name}. Here's some really long text to test overflowing the bounding container.`);
36
+ }
37
+ helloGrumpy('Wizard');</code></pre>
38
+ </d2l-html-block>
39
+
40
+ <h2 class="d2l-heading-3">Inline Samples</h2>
41
+
42
+ <d2l-html-block>
43
+ The best type of donuts are he kind you assign in code, for example: <code class="d2l-code d2l-code-dark language-javascript">const jelly = 'donuts';</code>. The next best type of thing you can assign in code is stuff you can ferment. <code class="d2l-code d2l-code-dark language-javascript">let beer = hopsAndWater.map(ingredients => ferment(ingredients));</code>
44
+ </d2l-html-block>
45
+
46
+ </body>
47
+ </html>
@@ -1,4 +1,5 @@
1
1
  import '../colors/colors.js';
2
+ import { codeStyles, HtmlBlockCodeRenderer } from '../../helpers/prism.js';
2
3
  import { css, LitElement } from 'lit';
3
4
  import { HtmlAttributeObserverController } from '../../controllers/attributeObserver/htmlAttributeObserverController.js';
4
5
  import { HtmlBlockMathRenderer } from '../../helpers/mathjax.js';
@@ -111,6 +112,7 @@ export const htmlBlockContentStyles = css`
111
112
  mjx-assistive-mml math {
112
113
  position: absolute;
113
114
  }
115
+ ${codeStyles}
114
116
  `;
115
117
 
116
118
  let renderers;
@@ -118,8 +120,8 @@ let renderers;
118
120
  const getRenderers = () => {
119
121
  if (renderers) return renderers;
120
122
  const tempRenderers = requestInstance(document, 'html-block-renderers');
121
- const htmlBlockMathRenderer = new HtmlBlockMathRenderer();
122
- renderers = (tempRenderers ? [ htmlBlockMathRenderer, ...tempRenderers ] : [ htmlBlockMathRenderer ]);
123
+ const defaultRenderers = [ new HtmlBlockMathRenderer(), new HtmlBlockCodeRenderer() ];
124
+ renderers = (tempRenderers ? [ ...defaultRenderers, ...tempRenderers ] : defaultRenderers);
123
125
  return renderers;
124
126
  };
125
127
 
@@ -227,10 +227,9 @@ export const labelStyles = css`
227
227
 
228
228
  export const blockquoteStyles = css`
229
229
  .d2l-blockquote {
230
- color: var(--d2l-color-tungsten);
231
230
  font-size: 0.8rem;
232
231
  font-weight: 400;
233
- line-height: 1.2rem;
232
+ line-height: 1.4rem;
234
233
  margin: 0;
235
234
  margin-right: 1.2rem;
236
235
  padding: 0;
@@ -238,24 +237,26 @@ export const blockquoteStyles = css`
238
237
  padding-top: 0.5rem;
239
238
  position: relative;
240
239
  }
241
-
242
240
  .d2l-blockquote::before {
243
241
  content: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTEiIGhlaWdodD0iMTEiIHZpZXdCb3g9IjAgMCAyMiAyMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+PGRlZnM+PHBhdGggaWQ9ImEiIGQ9Ik0wIDBoMjR2MjRIMHoiLz48L2RlZnM+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEgLTEpIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxtYXNrIGlkPSJiIiBmaWxsPSIjZmZmIj48dXNlIHhsaW5rOmhyZWY9IiNhIi8+PC9tYXNrPjxwYXRoIGQ9Ik02IDIyLjY2N0E0LjY2NyA0LjY2NyAwIDAgMCAxMC42NjcgMThjMC0xLjIyNy0uNTU5LTIuNS0xLjMzNC0zLjMzM0M4LjQ4MSAxMy43NSA3LjM1IDEzLjMzMyA2IDEzLjMzM2MtLjQxMSAwIDEuMzMzLTYuNjY2IDMtOSAxLjY2Ny0yLjMzMyAxLjMzMy0zIC4zMzMtM0M4IDEuMzMzIDUuMjUzIDQuNTg2IDQgNy4yNTUgMS43NzMgMTIgMS4zMzMgMTUuMzkyIDEuMzMzIDE4QTQuNjY3IDQuNjY3IDAgMCAwIDYgMjIuNjY3em0xMiAwQTQuNjY3IDQuNjY3IDAgMCAwIDIyLjY2NyAxOGMwLTEuMjI3LS41NTktMi41LTEuMzM0LTMuMzMzLS44NTItLjkxNy0xLjk4My0xLjMzNC0zLjMzMy0xLjMzNC0uNDExIDAgMS4zMzMtNi42NjYgMy05IDEuNjY3LTIuMzMzIDEuMzMzLTMgLjMzMy0zLTEuMzMzIDAtNC4wOCAzLjI1My01LjMzMyA1LjkyMkMxMy43NzMgMTIgMTMuMzMzIDE1LjM5MiAxMy4zMzMgMThBNC42NjcgNC42NjcgMCAwIDAgMTggMjIuNjY3eiIgZmlsbD0iI0QzRDlFMyIgbWFzaz0idXJsKCNiKSIvPjwvZz48L3N2Zz4=");
244
242
  left: 0;
245
243
  position: absolute;
246
244
  top: 0;
247
245
  }
248
-
249
246
  :host([dir="rtl"]) .d2l-blockquote {
250
247
  margin-left: 1.2rem;
251
248
  margin-right: 0;
252
249
  padding-left: 0;
253
250
  padding-right: 1.2rem;
254
251
  }
255
-
256
252
  :host([dir="rtl"]) .d2l-blockquote::before {
257
253
  left: initial;
258
254
  right: 0;
259
255
  transform: scaleX(-1);
260
256
  }
257
+ @media (max-width: 615px) {
258
+ .d2l-blockquote {
259
+ line-height: 1.2rem;
260
+ }
261
+ }
261
262
  `;
@@ -112,41 +112,10 @@ if (!document.head.querySelector('#d2l-typography-font-face')) {
112
112
  margin: 1.5rem 0 1.5rem 0;
113
113
  }
114
114
 
115
- @media (max-width: 615px) {
116
-
117
- .d2l-typography .d2l-body-standard {
118
- font-size: 0.8rem;
119
- line-height: 1.2rem;
120
- }
121
-
122
- .d2l-typography .d2l-body-small {
123
- font-size: 0.6rem;
124
- line-height: 0.9rem;
125
- }
126
-
127
- .d2l-typography .d2l-heading-1 {
128
- font-size: 1.5rem;
129
- line-height: 1.8rem;
130
- }
131
-
132
- .d2l-typography .d2l-heading-2 {
133
- font-size: 1rem;
134
- font-weight: 700;
135
- line-height: 1.5rem;
136
- }
137
-
138
- .d2l-typography .d2l-heading-3 {
139
- font-size: 0.8rem;
140
- line-height: 1.2rem;
141
- }
142
-
143
- }
144
-
145
115
  .d2l-typography .d2l-blockquote {
146
- color: var(--d2l-color-tungsten);
147
116
  font-size: 0.8rem;
148
117
  font-weight: 400;
149
- line-height: 1.2rem;
118
+ line-height: 1.4rem;
150
119
  margin: 0;
151
120
  margin-right: 1.2rem;
152
121
  padding: 0;
@@ -176,6 +145,40 @@ if (!document.head.querySelector('#d2l-typography-font-face')) {
176
145
  right: 0;
177
146
  transform: scaleX(-1);
178
147
  }
148
+
149
+ @media (max-width: 615px) {
150
+
151
+ .d2l-typography .d2l-body-standard {
152
+ font-size: 0.8rem;
153
+ line-height: 1.2rem;
154
+ }
155
+
156
+ .d2l-typography .d2l-body-small {
157
+ font-size: 0.6rem;
158
+ line-height: 0.9rem;
159
+ }
160
+
161
+ .d2l-typography .d2l-heading-1 {
162
+ font-size: 1.5rem;
163
+ line-height: 1.8rem;
164
+ }
165
+
166
+ .d2l-typography .d2l-heading-2 {
167
+ font-size: 1rem;
168
+ font-weight: 700;
169
+ line-height: 1.5rem;
170
+ }
171
+
172
+ .d2l-typography .d2l-heading-3 {
173
+ font-size: 0.8rem;
174
+ line-height: 1.2rem;
175
+ }
176
+
177
+ .d2l-typography .d2l-blockquote {
178
+ line-height: 1.2rem;
179
+ }
180
+
181
+ }
179
182
  `;
180
183
  document.head.appendChild(style);
181
184
  }
@@ -0,0 +1,417 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <title>Prism Helper</title>
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <meta charset="UTF-8">
7
+ <link rel="stylesheet" href="../../components/demo/styles.css" type="text/css">
8
+ <script type="module">
9
+ import '../../components/colors/colors.js';
10
+ import '../../components/switch/switch.js';
11
+ import '../../components/typography/typography.js';
12
+ import { codeStyles, formatCodeElement } from '../prism.js';
13
+ import { css, html, LitElement } from 'lit';
14
+ import { classMap } from 'lit/directives/class-map.js';
15
+
16
+ class DemoPrism extends LitElement {
17
+ static get properties() {
18
+ return {
19
+ dark: { type: Boolean, reflect: true }
20
+ };
21
+ }
22
+ static get styles() {
23
+ return [codeStyles, css`
24
+ :host {
25
+ display: block;
26
+ }
27
+ `];
28
+ }
29
+ render() {
30
+ const classes = { 'd2l-code': true, 'd2l-code-dark': this.dark };
31
+ return html`
32
+ <pre class="${classMap(classes)}"><code class="language-javascript line-numbers">function helloGrumpy(name) {
33
+ console.log(\`Hi there \${name}. Here's some really long text to test overflowing the bounding container.\`);
34
+ }
35
+ helloGrumpy('Wizard');
36
+ </code></pre>
37
+
38
+ <pre class="${classMap(classes)}"><code class="language-bash line-numbers">#!/bin/bash
39
+ if [ -d $directory ]; then
40
+ echo "Directory exists"
41
+ else
42
+ echo "Directory does not exists"
43
+ fi</code></pre>
44
+
45
+ <pre class="${classMap(classes)}"><code class="language-css line-numbers">.grumpy > img {
46
+ height: 100%;
47
+ width: 100%;
48
+ }</code></pre>
49
+
50
+ <pre class="${classMap(classes)}"><code class="language-json line-numbers">{
51
+ "jinxed": "gnomes",
52
+ "grumpy": [ "wizards" ]
53
+ }
54
+ </code></pre>
55
+
56
+ <pre class="${classMap(classes)}"><code class="language-sql line-numbers">DECLARE @MyCounter INT; /* keyword, variable, punctuation */
57
+
58
+ SELECT AVG(Calories) AS AverageCalories FROM Desserts; /* keyword, function */
59
+
60
+ SELECT * FROM Desserts /* keyword, operator */
61
+
62
+ SET ROWCOUNT 4; /* keyword, number */
63
+
64
+ SET @Hidden = FALSE; /* keyword, variable, boolean */
65
+
66
+ SET @Donuts = 'Yummy'; /* keyword, variable, string */
67
+ </code></pre>
68
+ `;
69
+ }
70
+ updated(changedProperties) {
71
+ super.updated(changedProperties);
72
+ this.shadowRoot.querySelectorAll('pre').forEach(code => formatCodeElement(code));
73
+ }
74
+ }
75
+ customElements.define('d2l-demo-prism', DemoPrism);
76
+ </script>
77
+ <style>
78
+ html {
79
+ font-size: 20px;
80
+ }
81
+ body {
82
+ padding: 1rem;
83
+ }
84
+ .heading-container {
85
+ display: flex;
86
+ }
87
+ .heading-container > h1 {
88
+ flex: auto;
89
+ }
90
+ .heading-container > d2l-switch {
91
+ align-self: center;
92
+ flex: none;
93
+ }
94
+ table {
95
+ font-family: 'Lato', 'Lucida Sans Unicode', 'Lucida Grande', sans-serif;
96
+ font-size: 16px;
97
+ }
98
+ th {
99
+ text-align: left;
100
+ }
101
+ tr > td:first-child {
102
+ width: 300px;
103
+ }
104
+ </style>
105
+ </head>
106
+ <body class="d2l-typography">
107
+
108
+ <!-- This page intentionally does not use d2l-demo-page so we can properly demo/test the loader without PrismJS being loaded by those components -->
109
+
110
+ <div class="heading-container">
111
+ <h1 class="d2l-heading-2">Prism Helper</h1>
112
+ <d2l-switch text="Dark" on text-position="start" on></d2l-switch>
113
+ </div>
114
+
115
+ <h2 class="d2l-heading-3">Tokens</h2>
116
+
117
+ <table style="width: 100%;">
118
+ <thead>
119
+ <tr>
120
+ <th>Token</th>
121
+ <th>Example</th>
122
+ </tr>
123
+ </thead>
124
+ <tbody>
125
+ <tr>
126
+ <td>keyword</td>
127
+ <td>
128
+ <pre class="d2l-code d2l-code-dark"><code class="language-javascript">import { stuff } from 'some/where.js';</code></pre>
129
+ </td>
130
+ </tr>
131
+ <tr>
132
+ <td>builtin</td>
133
+ <td>
134
+ <pre class="d2l-code d2l-code-dark"><code class="language-python">pi = round(float('3.14159'), 2)</code></pre>
135
+ </td>
136
+ </tr>
137
+ <tr>
138
+ <td>class-name</td>
139
+ <td>
140
+ <pre class="d2l-code d2l-code-dark"><code class="language-javascript">class Wizard extends Human { /* ... */ }</code></pre>
141
+ </td>
142
+ </tr>
143
+ <tr>
144
+ <td>function</td>
145
+ <td>
146
+ <pre class="d2l-code d2l-code-dark"><code class="language-javascript">function helloGrumpy(name) { /* ... */ }
147
+ helloGrumpy('Wizard');</code></pre>
148
+ </td>
149
+ </tr>
150
+ <tr>
151
+ <td>parameter</td>
152
+ <td>
153
+ <pre class="d2l-code d2l-code-dark"><code class="language-javascript">function helloGrumpy(name) { /* ... */ }</code></pre>
154
+ </td>
155
+ </tr>
156
+ <tr>
157
+ <td>boolean</td>
158
+ <td>
159
+ <pre class="d2l-code d2l-code-dark"><code class="language-javascript">const wizardsLikeBeer = false;</code></pre>
160
+ </td>
161
+ </tr>
162
+ <tr>
163
+ <td>number</td>
164
+ <td>
165
+ <pre class="d2l-code d2l-code-dark"><code class="language-javascript">const favouriteNumber = 3.14159;</code></pre>
166
+ </td>
167
+ </tr>
168
+ <tr>
169
+ <td>string</td>
170
+ <td>
171
+ <pre class="d2l-code d2l-code-dark"><code class="language-javascript">const hiGrumpy = 'Hi Grumpy!';</code></pre>
172
+ </td>
173
+ </tr>
174
+ <tr>
175
+ <td>template-string, template-punctuation</td>
176
+ <td>
177
+ <pre class="d2l-code d2l-code-dark"><code class="language-javascript">const hiGrumpy = `Hi Grumpy!`;</code></pre>
178
+ </td>
179
+ </tr>
180
+ <tr>
181
+ <td>interpolation, interpolation-punctuation</td>
182
+ <td>
183
+ <pre class="d2l-code d2l-code-dark"><code class="language-javascript">console.log(`Hi there ${name}.`);</code></pre>
184
+ </td>
185
+ </tr>
186
+ <tr>
187
+ <td>char</td>
188
+ <td>
189
+ <pre class="d2l-code d2l-code-dark"><code class="language-javascript"></code></pre>
190
+ </td>
191
+ </tr>
192
+ <tr>
193
+ <td>symbol</td>
194
+ <td>
195
+ <pre class="d2l-code d2l-code-dark"><code class="language-javascript"></code></pre>
196
+ </td>
197
+ </tr>
198
+ <tr>
199
+ <td>regex</td>
200
+ <td>
201
+ <pre class="d2l-code d2l-code-dark"><code class="language-javascript">let entity = /&amp;#x?[\da-f]{1,8};/;</code></pre>
202
+ </td>
203
+ </tr>
204
+ <tr>
205
+ <td>url</td>
206
+ <td>
207
+ <pre class="d2l-code d2l-code-dark"><code class="language-css">body { background: url("wizard.png"); }</code></pre>
208
+ </td>
209
+ </tr>
210
+ <tr>
211
+ <td>operator</td>
212
+ <td>
213
+ <pre class="d2l-code d2l-code-dark"><code class="language-javascript">x += (y + 4 &gt;&gt; -z === w) ? b ** c : ~a;</code></pre>
214
+ </td>
215
+ </tr>
216
+ <tr>
217
+ <td>variable</td>
218
+ <td>
219
+ <pre class="d2l-code d2l-code-dark"><code class="language-sql">DECLARE @MyCounter INT;</code></pre>
220
+ </td>
221
+ </tr>
222
+ <tr>
223
+ <td>constant</td>
224
+ <td>
225
+ <pre class="d2l-code d2l-code-dark"><code class="language-javascript">const PI = 3.14159;</code></pre>
226
+ </td>
227
+ </tr>
228
+ <tr>
229
+ <td>property</td>
230
+ <td>
231
+ <pre class="d2l-code d2l-code-dark"><code class="language-css">.grumpy > img { height: 100%; }</code></pre>
232
+ </td>
233
+ </tr>
234
+ <tr>
235
+ <td>punctuation</td>
236
+ <td>
237
+ <pre class="d2l-code d2l-code-dark"><code class="language-javascript">import { stuff } from 'some/where.js';</code></pre>
238
+ </td>
239
+ </tr>
240
+ <tr>
241
+ <td>important</td>
242
+ <td>
243
+ <pre class="d2l-code d2l-code-dark"><code class="language-css">.grumpy > img { height: 100% !important; }</code></pre>
244
+ </td>
245
+ </tr>
246
+ <tr>
247
+ <td>comment</td>
248
+ <td>
249
+ <pre class="d2l-code d2l-code-dark"><code class="language-javascript">/* grump wizards */</code></pre>
250
+ </td>
251
+ </tr>
252
+ <tr>
253
+ <td>tag</td>
254
+ <td>
255
+ <pre class="d2l-code d2l-code-dark"><code class="language-markup">&lt;h1&gt;Grumpy Wizards&lt;/h1&gt;</code></pre>
256
+ </td>
257
+ </tr>
258
+ <tr>
259
+ <td>attr-name, attr-value</td>
260
+ <td>
261
+ <pre class="d2l-code d2l-code-dark"><code class="language-markup">&lt;h1 class="dangerous"&gt;Grumpy Wizards&lt;/h1&gt;</code></pre>
262
+ </td>
263
+ </tr>
264
+ <tr>
265
+ <td>namespace</td>
266
+ <td>
267
+ <pre class="d2l-code d2l-code-dark"><code class="language-java">throw new java.lang.UnsupportedOperationException();</code></pre>
268
+ </td>
269
+ </tr>
270
+ <tr>
271
+ <td>prolog</td>
272
+ <td>
273
+ <pre class="d2l-code d2l-code-dark"><code class="language-markup">&lt?xml version="1.0" encoding="utf-8"?&gt;</code></pre>
274
+ </td>
275
+ </tr>
276
+ <tr>
277
+ <td>doctype</td>
278
+ <td>
279
+ <pre class="d2l-code d2l-code-dark"><code class="language-markup">&lt;!DOCTYPE html&gt;</code></pre>
280
+ </td>
281
+ </tr>
282
+ <tr>
283
+ <td>cdata</td>
284
+ <td>
285
+ <pre class="d2l-code d2l-code-dark"><code class="language-markup">&lt;![CDATA[ grumpy wizards eat donuts ]]&gt;</code></pre>
286
+ </td>
287
+ </tr>
288
+ <tr>
289
+ <td>entity</td>
290
+ <td>
291
+ <pre class="d2l-code d2l-code-dark"><code class="language-markup">&amp;pound; &amp;#163;</code></pre>
292
+ </td>
293
+ </tr>
294
+ <tr>
295
+ <td>atrule</td>
296
+ <td>
297
+ <pre class="d2l-code d2l-code-dark"><code class="language-css">@media (prefers-reduced-motion: reduce) { /* no animations */ }</code></pre>
298
+ </td>
299
+ </tr>
300
+ <tr>
301
+ <td>selector</td>
302
+ <td>
303
+ <pre class="d2l-code d2l-code-dark"><code class="language-css">.grumpy > img { /* ... */ }</code></pre>
304
+ </td>
305
+ </tr>
306
+ <tr>
307
+ <td>null</td>
308
+ <td>
309
+ <pre class="d2l-code d2l-code-dark"><code class="language-json">{ "fritter": null }</code></pre>
310
+ </td>
311
+ </tr>
312
+ </tbody>
313
+ </table>
314
+
315
+ <h2 class="d2l-heading-3">More Samples (Global Scope)</h2>
316
+
317
+ <pre class="d2l-code"><code class="language-javascript line-numbers">// comment
318
+ /* comment */
319
+
320
+ import { stuff } from 'some/where.js'; // keyword, punctuation, string
321
+
322
+ function helloGrumpy(name) { // keyword, function, parameter
323
+ console.log(`Hi there ${name}.`); // template-string, template-punctuation, interpolation, interpolation-punctuation
324
+ }
325
+
326
+ class Wizard extends Human { } // keyword, class-name
327
+
328
+ const grumpy = new Wizard(); // keyword, operator, class-name
329
+
330
+ let wizardFoods = [...donuts, ... cakes, ...pies]; // keyword, operator
331
+
332
+ const wizardsLikeBeer = false; // keyword, operator, boolean
333
+
334
+ const favouriteNumber = 3.14159; // keyword, operator, number
335
+
336
+ const PI = 3.14159; // keyword, operator, constant
337
+
338
+ const regex = /[^\w\s]/g; // keyword, operator, regex, regex-delimiter, regex-source, regex-flags
339
+ </code></pre>
340
+
341
+ <pre class="d2l-code"><code class="language-css line-numbers">.grumpy > img { /* selector */
342
+ background-image: url("smile.png"); /* property, url, string */
343
+ height: 100%; /* property, punctuation */
344
+ width: var(--some-var); /* property, punctuation, function */
345
+ }
346
+ @font-face { /* atrule, rule */
347
+ font-family: 'Lato'; /* property, punctuation, string */
348
+ font-style: normal;
349
+ src: local('Lato Regular'); /* property, function, string */
350
+ }
351
+ @media (prefers-reduced-motion: reduce) { /* atrule, rule, property */
352
+ :host([opened]), :host([opened-above]) {
353
+ animation: none !important; /* property, important */
354
+ }
355
+ }
356
+ </code></pre>
357
+
358
+ <pre class="d2l-code"><code class="language-markup line-numbers">&lt;!DOCTYPE html&gt; &lt;!-- doctype, doctype-tag, name --&gt;
359
+ &lt;html&gt; &lt;!-- tag, punctuation --&gt;
360
+ &lt;body class="typography"&gt; &lt;!-- attr-name, attr-value --&gt;
361
+ &lt;![CDATA[ some cdata section ]]&gt; &lt;!-- cdata --&gt;
362
+ &lt;div style="color: blue;"&gt; &lt;!-- attr-name, attr-value, attr-equals, value, css, property --&gt;
363
+ &amp;pound; &lt;!-- entity, named-entity --&gt;
364
+ &amp;#163; &lt;!-- entity --&gt;
365
+ &lt;/div&gt;
366
+ &lt;/body&gt;
367
+ &lt;/html&gt;
368
+ </code></pre>
369
+
370
+ <pre class="d2l-code d2l-code-dark"><code class="language-sql line-numbers">DECLARE @MyCounter INT; /* keyword, variable, punctuation */
371
+
372
+ SELECT AVG(Calories) AS AverageCalories FROM Desserts; /* keyword, function */
373
+
374
+ SELECT * FROM Desserts /* keyword, operator */
375
+
376
+ SET ROWCOUNT 4; /* keyword, number */
377
+
378
+ SET @Hidden = FALSE; /* keyword, variable, boolean */
379
+
380
+ SET @Donuts = 'Yummy'; /* keyword, variable, string */
381
+ </code></pre>
382
+
383
+ <pre class="d2l-code d2l-code-dark"><code class="language-json line-numbers">{ /* punctuation */
384
+ "jinxed": "gnomes", /* property, operator, string */
385
+ "grumpy": [ "wizards" ],
386
+ "jelly": 99, /* property, operator, number */
387
+ "donut": true, /* property, operator, boolean */
388
+ "fritter": null /* property, operator, null, keyword */
389
+ }
390
+ </code></pre>
391
+
392
+ <h2 class="d2l-heading-3">More Samples (Web Component Scope)</h2>
393
+
394
+ <d2l-demo-prism dark></d2l-demo-prism>
395
+
396
+ <script type="module">
397
+ import { formatCodeElement } from '../prism.js';
398
+
399
+ const formatCodeElements = () => {
400
+ const darkSwitch = document.querySelector('d2l-switch');
401
+ const codeElements = document.querySelectorAll('pre');
402
+ codeElements.forEach(codeElement => {
403
+ if (darkSwitch.on) codeElement.classList.add('d2l-code-dark');
404
+ else codeElement.classList.remove('d2l-code-dark');
405
+ formatCodeElement(codeElement);
406
+ });
407
+ document.querySelector('d2l-demo-prism').dark = darkSwitch.on;
408
+ };
409
+
410
+ formatCodeElements();
411
+
412
+ const darkSwitch = document.querySelector('d2l-switch');
413
+ darkSwitch.addEventListener('change', formatCodeElements);
414
+
415
+ </script>
416
+ </body>
417
+ </html>
@@ -0,0 +1,430 @@
1
+ import { css, unsafeCSS } from 'lit-element/lit-element.js';
2
+
3
+ window.Prism = window.Prism || {};
4
+ Prism.manual = true;
5
+
6
+ const prismLocation = 'https://s.brightspace.com/lib/prismjs/1.28.0';
7
+ //const prismLocation = '/node_modules/prismjs'; // for local debugging
8
+
9
+ // If adding a language, check its Prism dependencies and modify languageDependencies below if necessary
10
+ export const codeLanguages = new Map();
11
+ codeLanguages.set('arduino', 'Arduino');
12
+ codeLanguages.set('armasm', 'ARM Assembly');
13
+ codeLanguages.set('bash', 'Bash');
14
+ codeLanguages.set('c', 'C');
15
+ codeLanguages.set('clike', 'C-like');
16
+ codeLanguages.set('cpp', 'C++');
17
+ codeLanguages.set('csharp', 'C#');
18
+ codeLanguages.set('css', 'CSS');
19
+ codeLanguages.set('haskell', 'Haskell');
20
+ codeLanguages.set('java', 'Java');
21
+ codeLanguages.set('javascript', 'JavaScript');
22
+ codeLanguages.set('json', 'JSON');
23
+ codeLanguages.set('kotlin', 'Kotlin');
24
+ codeLanguages.set('latex', 'LaTeX');
25
+ codeLanguages.set('markup', 'Markup');
26
+ codeLanguages.set('matlab', 'MATLAB');
27
+ codeLanguages.set('plain', 'Plain Text');
28
+ codeLanguages.set('python', 'Python');
29
+ codeLanguages.set('r', 'R');
30
+ codeLanguages.set('racket', 'Racket');
31
+ codeLanguages.set('sql', 'SQL');
32
+ codeLanguages.set('wolfram', 'Wolfram');
33
+
34
+ export const colorModes = {
35
+ LIGHT: 'light',
36
+ DARK: 'dark'
37
+ };
38
+
39
+ const darkColors = Object.freeze({
40
+ background: '#2d2d2d',
41
+ language: '#6e7376',
42
+ lineNumbers: '#ffffff',
43
+ lineNumbersSeparator: '#999999',
44
+ tokenDefault: '#cccccc',
45
+ tokenComment: '#808080',
46
+ tokenPunctuation: '#d4d4d4',
47
+ tokenNumber: '#d4d4d4',
48
+ tokenUrl: '#d4d4d4',
49
+ tokenOperator: '#d4d4d4',
50
+ tokenInterpolation: '#9cdcfe',
51
+ tokenAttributeName: '#9cdcfe',
52
+ tokenConstant: '#9cdcfe',
53
+ tokenProperty: '#9cdcfe',
54
+ tokenTag: '#569cd6',
55
+ tokenBoolean: '#569cd6',
56
+ tokenEntity: '#569cd6',
57
+ tokenInterpolationPunctuation: '#569cd6',
58
+ tokenFunction: '#dcdcaa',
59
+ tokenClassName: '#4ec9b0',
60
+ tokenSymbol: '#4ec9b0',
61
+ tokenBuiltin: '#c586c0',
62
+ tokenKeyword: '#c586c0',
63
+ tokenAtRule: '#c586c0',
64
+ tokenSelector: '#d7ba7d',
65
+ tokenImportant: '#d16969',
66
+ tokenRegex: '#d16969',
67
+ tokenString: '#ce9178',
68
+ tokenChar: '#ce9178',
69
+ tokenAttributeValue: '#ce9178'
70
+ });
71
+
72
+ const lightColors = Object.freeze({
73
+ background: '#f2f1f1',
74
+ language: '#1b1b1b',
75
+ lineNumbers: '#1b1b1b',
76
+ lineNumbersSeparator: '#1b1b1b',
77
+ tokenDefault: '#1b1b1b',
78
+ tokenComment: '#9e9e9e',
79
+ tokenPunctuation: '#9e9e9e',
80
+ tokenNumber: '#007936',
81
+ tokenUrl: '#9e9e9e',
82
+ tokenOperator: '#9e9e9e',
83
+ tokenInterpolation: '#872bff',
84
+ tokenAttributeName: '#d30038',
85
+ tokenConstant: '#007936',
86
+ tokenProperty: '#d30038',
87
+ tokenTag: '#007936',
88
+ tokenBoolean: '#007936',
89
+ tokenEntity: 'inherit',
90
+ tokenInterpolationPunctuation: '#872bff',
91
+ tokenFunction: '#d30038',
92
+ tokenClassName: '#d30038',
93
+ tokenSymbol: '#007936',
94
+ tokenBuiltin: '#872bff',
95
+ tokenKeyword: '#0069c2',
96
+ tokenAtRule: '#007936',
97
+ tokenSelector: '#872bff',
98
+ tokenImportant: 'inherit',
99
+ tokenRegex: 'inherit',
100
+ tokenString: '#007936',
101
+ tokenChar: '#007936',
102
+ tokenAttributeValue: '#007936'
103
+ });
104
+
105
+ export const getCodeColors = mode => {
106
+ return mode === colorModes.DARK ? darkColors : lightColors;
107
+ };
108
+
109
+ const generateColorVariables = mode => {
110
+ const colors = getCodeColors(mode);
111
+ const keySelector = mode === colorModes.DARK ? '.d2l-code-dark' : '.d2l-code';
112
+ return `
113
+ pre[class*="language-"]${keySelector},
114
+ code[class*="language-"]${keySelector} {
115
+ --d2l-code-background: ${colors.background};
116
+ --d2l-code-language: ${colors.language};
117
+ --d2l-code-line-numbers: ${colors.lineNumbers};
118
+ --d2l-code-line-numbers-separator: ${colors.lineNumbersSeparator};
119
+ --d2l-code-token-atrule: ${colors.tokenAtRule};
120
+ --d2l-code-token-attribute-name: ${colors.tokenAttributeName};
121
+ --d2l-code-token-attribute-value: ${colors.tokenAttributeValue};
122
+ --d2l-code-token-boolean: ${colors.tokenBoolean};
123
+ --d2l-code-token-builtin: ${colors.tokenBuiltin};
124
+ --d2l-code-token-char: ${colors.tokenChar};
125
+ --d2l-code-token-class-name: ${colors.tokenClassName};
126
+ --d2l-code-token-comment: ${colors.tokenComment};
127
+ --d2l-code-token-constant: ${colors.tokenConstant};
128
+ --d2l-code-token-default: ${colors.tokenDefault};
129
+ --d2l-code-token-entity: ${colors.tokenEntity};
130
+ --d2l-code-token-function: ${colors.tokenFunction};
131
+ --d2l-code-token-important: ${colors.tokenImportant};
132
+ --d2l-code-token-interpolation: ${colors.tokenInterpolation};
133
+ --d2l-code-token-interpolation-punctuation: ${colors.tokenInterpolationPunctuation};
134
+ --d2l-code-token-keyword: ${colors.tokenKeyword};
135
+ --d2l-code-token-number: ${colors.tokenNumber};
136
+ --d2l-code-token-operator: ${colors.tokenOperator};
137
+ --d2l-code-token-property: ${colors.tokenProperty};
138
+ --d2l-code-token-punctuation: ${colors.tokenPunctuation};
139
+ --d2l-code-token-regex: ${colors.tokenRegex};
140
+ --d2l-code-token-selector: ${colors.tokenSelector};
141
+ --d2l-code-token-string: ${colors.tokenString};
142
+ --d2l-code-token-symbol: ${colors.tokenSymbol};
143
+ --d2l-code-token-tag: ${colors.tokenTag};
144
+ --d2l-code-token-url: ${colors.tokenUrl};
145
+ }
146
+ `;
147
+ };
148
+
149
+ export const codeStyles = css`
150
+
151
+ ${unsafeCSS(generateColorVariables(colorModes.LIGHT))}
152
+
153
+ ${unsafeCSS(generateColorVariables(colorModes.DARK))}
154
+
155
+ pre[class*="language-"].d2l-code,
156
+ pre[class*="language-"].d2l-code > code[class*="language-"],
157
+ code[class*="language-"].d2l-code {
158
+ font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
159
+ line-height: 1.5;
160
+ text-shadow: none;
161
+ }
162
+
163
+ pre[class*="language-"].d2l-code > code[class*="language-"],
164
+ code[class*="language-"].d2l-code {
165
+ color: var(--d2l-code-token-default);
166
+ -webkit-hyphens: none;
167
+ -moz-hyphens: none;
168
+ -ms-hyphens: none;
169
+ hyphens: none;
170
+ white-space: pre;
171
+ word-break: normal;
172
+ word-spacing: normal;
173
+ word-wrap: normal;
174
+ }
175
+
176
+ pre[class*="language-"].d2l-code {
177
+ background-color: var(--d2l-code-background);
178
+ border-radius: 6px;
179
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2);
180
+ font-size: 14px;
181
+ margin: 0.5em 0;
182
+ overflow: auto;
183
+ padding: 1em;
184
+ position: relative;
185
+ -moz-tab-size: 4;
186
+ -o-tab-size: 4;
187
+ tab-size: 4;
188
+ text-align: left;
189
+ }
190
+
191
+ pre[class*="language-"].d2l-code::before {
192
+ color: var(--d2l-code-language);
193
+ content: attr(data-language);
194
+ font-family: 'Lato', 'Lucida Sans Unicode', 'Lucida Grande', sans-serif;
195
+ margin: 0.1rem 0.4rem;
196
+ position: absolute;
197
+ right: 0;
198
+ top: 0;
199
+ }
200
+
201
+ code[class*="language-"].d2l-code {
202
+ background-color: var(--d2l-code-background);
203
+ border-radius: 6px;
204
+ padding: 0.1em;
205
+ white-space: normal;
206
+ }
207
+
208
+ .token.comment,
209
+ .token.block-comment,
210
+ .token.prolog,
211
+ .token.doctype,
212
+ .token.cdata {
213
+ color: var(--d2l-code-token-comment);
214
+ }
215
+
216
+ .token.punctuation { color: var(--d2l-code-token-punctuation); }
217
+ .token.number { color: var(--d2l-code-token-number); }
218
+ .token.operator { color: var(--d2l-code-token-operator); }
219
+
220
+ .token.interpolation { color: var(--d2l-code-token-interpolation); }
221
+ .token.attr-name { color: var(--d2l-code-token-attribute-name); }
222
+ .token.constant { color: var(--d2l-code-token-constant); }
223
+ .token.property { color: var(--d2l-code-token-property); }
224
+
225
+ .token.tag { color: var(--d2l-code-token-tag); }
226
+ .token.boolean { color: var(--d2l-code-token-boolean); }
227
+ .token.entity { color: var(--d2l-code-token-entity); }
228
+ .token.interpolation-punctuation { color: var(--d2l-code-token-interpolation-punctuation); }
229
+
230
+ .token.function { color: var(--d2l-code-token-function); }
231
+
232
+ .token.class-name { color: var(--d2l-code-token-class-name); }
233
+ .token.symbol { color: var(--d2l-code-token-symbol); }
234
+
235
+ .token.builtin { color: var(--d2l-code-token-builtin); }
236
+ .token.keyword { color: var(--d2l-code-token-keyword); }
237
+ .token.atrule { color: var(--d2l-code-token-atrule); }
238
+
239
+ .token.selector { color: var(--d2l-code-token-selector); }
240
+
241
+ .token.important { color: var(--d2l-code-token-important); }
242
+ .token.regex { color: var(--d2l-code-token-regex); }
243
+
244
+ .token.string { color: var(--d2l-code-token-string); }
245
+ .token.char { color: var(--d2l-code-token-char); }
246
+ .token.attr-value { color: var(--d2l-code-token-attribute-value); }
247
+
248
+ .token.url { color: var(--d2l-code-token-url); }
249
+
250
+ .language-css .token.string,
251
+ .style .token.string,
252
+ .token.entity,
253
+ .token.operator,
254
+ .token.url {
255
+ background-color: transparent;
256
+ }
257
+
258
+ pre[class*="language-"].line-numbers {
259
+ counter-reset: linenumber;
260
+ padding-left: 3.8em;
261
+ position: relative;
262
+ }
263
+
264
+ pre[class*="language-"].line-numbers > code {
265
+ position: relative;
266
+ white-space: inherit;
267
+ }
268
+
269
+ .line-numbers .line-numbers-rows {
270
+ border-right: 1px solid var(--d2l-code-line-numbers-separator);
271
+ font-size: 100%;
272
+ left: -3.8em;
273
+ letter-spacing: -1px;
274
+ pointer-events: none;
275
+ position: absolute;
276
+ top: 0;
277
+ -webkit-user-select: none;
278
+ -moz-user-select: none;
279
+ -ms-user-select: none;
280
+ user-select: none;
281
+ width: 3em; /* works for line-numbers below 1000 lines */
282
+ }
283
+
284
+ .line-numbers-rows > span {
285
+ counter-increment: linenumber;
286
+ display: block;
287
+ }
288
+
289
+ .line-numbers-rows > span::before {
290
+ color: var(--d2l-code-line-numbers);
291
+ content: counter(linenumber);
292
+ display: block;
293
+ padding-right: 0.8em;
294
+ text-align: right;
295
+ }
296
+ `;
297
+
298
+ const getLanguageInfo = elem => {
299
+ const classes = elem.classList;
300
+ for (let i = 0; i < classes.length; i++) {
301
+ if (classes[i].startsWith('language-')) {
302
+ const key = classes[i].substring(9);
303
+ const desc = codeLanguages.get(key);
304
+ if (desc) return { key: key, desc: desc };
305
+ }
306
+ }
307
+ return { key: 'plain', desc: codeLanguages.get('plain') };
308
+ };
309
+
310
+ const languageDependencies = {
311
+ arduino: [ 'cpp' ],
312
+ cpp: [ 'c' ],
313
+ racket: [ 'scheme' ]
314
+ };
315
+
316
+ const languagesLoaded = {
317
+ clike: Promise.resolve(),
318
+ css: Promise.resolve(),
319
+ javascript: Promise.resolve(),
320
+ markup: Promise.resolve(),
321
+ plain: Promise.resolve()
322
+ };
323
+
324
+ const loadLanguage = async key => {
325
+ if (languagesLoaded[key]) return languagesLoaded[key];
326
+
327
+ // Prism languages can extend other anguages and must be loaded in order
328
+
329
+ // eslint-disable-next-line no-async-promise-executor
330
+ languagesLoaded[key] = new Promise(async resolve => {
331
+ if (languageDependencies[key]) {
332
+ await Promise.all(languageDependencies[key].map(dependencyKey => loadLanguage(dependencyKey)));
333
+ }
334
+
335
+ const script = document.createElement('script');
336
+ script.async = 'async';
337
+ script.onload = resolve;
338
+ script.src = `${prismLocation}/components/prism-${key}.min.js`;
339
+ document.head.appendChild(script);
340
+ });
341
+
342
+ return languagesLoaded[key];
343
+ };
344
+
345
+ const pluginsLoaded = {};
346
+
347
+ const loadPlugin = async plugin => {
348
+ if (pluginsLoaded[plugin]) return pluginsLoaded[plugin];
349
+
350
+ pluginsLoaded[plugin] = new Promise(resolve => {
351
+ const script = document.createElement('script');
352
+ script.async = 'async';
353
+ script.onload = resolve;
354
+ script.src = `${prismLocation}/plugins/${plugin}/prism-${plugin}.min.js`;
355
+ document.head.appendChild(script);
356
+ });
357
+
358
+ return pluginsLoaded[plugin];
359
+ };
360
+
361
+ let prismLoaded;
362
+
363
+ const loadPrism = () => {
364
+ if (prismLoaded) return prismLoaded;
365
+
366
+ prismLoaded = Promise.all([
367
+ new Promise(resolve => {
368
+ const script = document.createElement('script');
369
+ script.async = 'async';
370
+ script.onload = resolve;
371
+ script.src = `${prismLocation}/prism.js`;
372
+ document.head.appendChild(script);
373
+ }),
374
+ new Promise(resolve => {
375
+ const style = document.createElement('style');
376
+ style.textContent = codeStyles.cssText;
377
+ style.onload = resolve;
378
+ document.head.appendChild(style);
379
+ })
380
+ ]);
381
+
382
+ return prismLoaded;
383
+ };
384
+
385
+ const getCodeElement = elem => {
386
+ if (!elem) return;
387
+ if (elem.tagName === 'CODE') return elem;
388
+ if (elem.tagName !== 'PRE') return;
389
+ return elem.querySelector('code');
390
+ };
391
+
392
+ export async function formatCodeElement(elem) {
393
+ const code = getCodeElement(elem);
394
+
395
+ if (code.className.indexOf('language-') === -1) return;
396
+
397
+ const languageInfo = getLanguageInfo(code);
398
+ const lineNumbers = elem.classList.contains('line-numbers') || code.classList.contains('line-numbers');
399
+
400
+ await loadPrism(); // must be loaded before loading plugins or languages
401
+ await Promise.all([
402
+ loadLanguage(languageInfo.key),
403
+ lineNumbers ? loadPlugin('line-numbers') : null
404
+ ]);
405
+
406
+ if (!elem.dataset.language && languageInfo.key !== 'plain') elem.dataset.language = languageInfo.desc;
407
+ Prism.highlightElement(code);
408
+
409
+ return elem;
410
+ }
411
+
412
+ export class HtmlBlockCodeRenderer {
413
+
414
+ get canRenderInline() {
415
+ return true;
416
+ }
417
+
418
+ async render(elem) {
419
+ const codeElements = [...elem.querySelectorAll('.d2l-code')];
420
+ if (codeElements.length === 0) return elem;
421
+
422
+ // wait; formatting is not synchronous due to lazy loading of Prism, languages, plugins
423
+ await Promise.all(codeElements.map(codeElement => {
424
+ return formatCodeElement(codeElement);
425
+ }));
426
+
427
+ return elem;
428
+ }
429
+
430
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brightspace-ui/core",
3
- "version": "2.27.0",
3
+ "version": "2.28.1",
4
4
  "description": "A collection of accessible, free, open-source web components for building Brightspace applications",
5
5
  "type": "module",
6
6
  "repository": "https://github.com/BrightspaceUI/core.git",