@brightspace-ui/core 1.203.0 → 1.206.0
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.
- package/components/button/README.md +1 -1
- package/components/card/card.js +9 -8
- package/components/html-block/demo/html-block.html +7 -9
- package/components/html-block/html-block.js +62 -22
- package/helpers/htmlAttributeObserverController.js +26 -15
- package/helpers/mathjax.js +28 -14
- package/package.json +1 -1
|
@@ -38,7 +38,7 @@ The `d2l-button` element can be used just like the native button element, but al
|
|
|
38
38
|

|
|
39
39
|
<!-- docs: end hidden content -->
|
|
40
40
|
|
|
41
|
-
<!-- docs: demo live name:
|
|
41
|
+
<!-- docs: demo live name:d2l-button -->
|
|
42
42
|
```html
|
|
43
43
|
<script type="module">
|
|
44
44
|
import '@brightspace-ui/core/components/button/button.js';
|
package/components/card/card.js
CHANGED
|
@@ -82,7 +82,6 @@ class Card extends RtlMixin(LitElement) {
|
|
|
82
82
|
box-sizing: border-box;
|
|
83
83
|
display: inline-block;
|
|
84
84
|
position: relative;
|
|
85
|
-
transition: transform 300ms ease-out 50ms, box-shadow 0.2s;
|
|
86
85
|
z-index: 0;
|
|
87
86
|
}
|
|
88
87
|
.d2l-card-container {
|
|
@@ -185,10 +184,6 @@ class Card extends RtlMixin(LitElement) {
|
|
|
185
184
|
border: none;
|
|
186
185
|
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.03);
|
|
187
186
|
}
|
|
188
|
-
:host(:hover),
|
|
189
|
-
:host([subtle]:hover) {
|
|
190
|
-
transform: translateY(-4px);
|
|
191
|
-
}
|
|
192
187
|
:host(:hover) {
|
|
193
188
|
box-shadow: 0 2px 14px 1px rgba(0, 0, 0, 0.06);
|
|
194
189
|
}
|
|
@@ -203,7 +198,6 @@ class Card extends RtlMixin(LitElement) {
|
|
|
203
198
|
:host([subtle][_active]:hover) {
|
|
204
199
|
border-color: transparent;
|
|
205
200
|
box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px var(--d2l-color-celestine);
|
|
206
|
-
transform: translateY(-4px);
|
|
207
201
|
}
|
|
208
202
|
/* .d2l-card-link-container-hover is used to only color/underline when
|
|
209
203
|
hovering the anchor; these styles are not applied when hovering actions */
|
|
@@ -225,9 +219,16 @@ class Card extends RtlMixin(LitElement) {
|
|
|
225
219
|
box-shadow: none;
|
|
226
220
|
transform: none;
|
|
227
221
|
}
|
|
228
|
-
@media (prefers-reduced-motion:
|
|
222
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
229
223
|
:host {
|
|
230
|
-
transition:
|
|
224
|
+
transition: transform 300ms ease-out 50ms, box-shadow 0.2s;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
:host(:hover),
|
|
228
|
+
:host([subtle]:hover),
|
|
229
|
+
:host([_active]:hover),
|
|
230
|
+
:host([subtle][_active]:hover) {
|
|
231
|
+
transform: translateY(-4px);
|
|
231
232
|
}
|
|
232
233
|
}
|
|
233
234
|
`];
|
|
@@ -9,10 +9,8 @@
|
|
|
9
9
|
import '../html-block.js';
|
|
10
10
|
import { provideInstance } from '../../../mixins/provider-mixin.js';
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
async elem => {
|
|
15
|
-
|
|
12
|
+
class DemoReplacementRenderer {
|
|
13
|
+
async render(elem) {
|
|
16
14
|
const elemsToReplace = elem.querySelectorAll('[data-replace-me-id]');
|
|
17
15
|
if (elemsToReplace.length === 0) return elem;
|
|
18
16
|
|
|
@@ -32,15 +30,15 @@
|
|
|
32
30
|
});
|
|
33
31
|
|
|
34
32
|
return elem;
|
|
35
|
-
|
|
36
33
|
}
|
|
37
|
-
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// demo replacement renderer for html-block
|
|
37
|
+
provideInstance(document, 'html-block-renderers', [ new DemoReplacementRenderer() ]);
|
|
38
38
|
|
|
39
39
|
</script>
|
|
40
40
|
<script>
|
|
41
|
-
|
|
42
|
-
document.getElementsByTagName('html')[0].dataset.mathjaxContext = JSON.stringify({ renderLatex: true });
|
|
43
|
-
}
|
|
41
|
+
document.getElementsByTagName('html')[0].dataset.mathjaxContext = JSON.stringify({ renderLatex: window.location.search.indexOf('latex=true') !== -1 });
|
|
44
42
|
</script>
|
|
45
43
|
</head>
|
|
46
44
|
<body unresolved>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import '../colors/colors.js';
|
|
2
2
|
import { css, LitElement } from 'lit-element/lit-element.js';
|
|
3
|
-
import {
|
|
3
|
+
import { HtmlAttributeObserverController } from '../../helpers/htmlAttributeObserverController.js';
|
|
4
|
+
import { HtmlBlockMathRenderer } from '../../helpers/mathjax.js';
|
|
4
5
|
import { requestInstance } from '../../mixins/provider-mixin.js';
|
|
5
6
|
|
|
6
7
|
export const htmlBlockContentStyles = css`
|
|
@@ -106,6 +107,7 @@ let renderers;
|
|
|
106
107
|
const getRenderers = () => {
|
|
107
108
|
if (renderers) return renderers;
|
|
108
109
|
const tempRenderers = requestInstance(document, 'html-block-renderers');
|
|
110
|
+
const htmlBlockMathRenderer = new HtmlBlockMathRenderer();
|
|
109
111
|
renderers = (tempRenderers ? [ htmlBlockMathRenderer, ...tempRenderers ] : [ htmlBlockMathRenderer ]);
|
|
110
112
|
return renderers;
|
|
111
113
|
};
|
|
@@ -135,8 +137,22 @@ class HtmlBlock extends LitElement {
|
|
|
135
137
|
`];
|
|
136
138
|
}
|
|
137
139
|
|
|
140
|
+
constructor() {
|
|
141
|
+
super();
|
|
142
|
+
|
|
143
|
+
const rendererContextAttributes = getRenderers().reduce((attrs, currentRenderer) => {
|
|
144
|
+
if (currentRenderer.contextAttributes) currentRenderer.contextAttributes.forEach(attr => attrs.push(attr));
|
|
145
|
+
return attrs;
|
|
146
|
+
}, []);
|
|
147
|
+
|
|
148
|
+
if (rendererContextAttributes.length === 0) return;
|
|
149
|
+
this._contextObserverController = new HtmlAttributeObserverController(this, ...rendererContextAttributes);
|
|
150
|
+
}
|
|
151
|
+
|
|
138
152
|
connectedCallback() {
|
|
139
153
|
super.connectedCallback();
|
|
154
|
+
if (this._contextObserverController) this._contextObserverController.hostConnected();
|
|
155
|
+
|
|
140
156
|
if (!this._templateObserver) return;
|
|
141
157
|
|
|
142
158
|
const template = this.querySelector('template');
|
|
@@ -145,6 +161,7 @@ class HtmlBlock extends LitElement {
|
|
|
145
161
|
|
|
146
162
|
disconnectedCallback() {
|
|
147
163
|
super.disconnectedCallback();
|
|
164
|
+
if (this._contextObserverController) this._contextObserverController.hostDisconnected();
|
|
148
165
|
if (this._templateObserver) this._templateObserver.disconnect();
|
|
149
166
|
}
|
|
150
167
|
|
|
@@ -155,6 +172,36 @@ class HtmlBlock extends LitElement {
|
|
|
155
172
|
|
|
156
173
|
this.shadowRoot.innerHTML += '<div class="d2l-html-block-rendered"></div><slot></slot>';
|
|
157
174
|
|
|
175
|
+
this.shadowRoot.querySelector('slot').addEventListener('slotchange', async e => {
|
|
176
|
+
|
|
177
|
+
const template = e.target.assignedNodes({ flatten: true })
|
|
178
|
+
.find(node => (node.nodeType === Node.ELEMENT_NODE && node.tagName === 'TEMPLATE'));
|
|
179
|
+
|
|
180
|
+
this._stamp(template);
|
|
181
|
+
|
|
182
|
+
});
|
|
183
|
+
this._renderContainer = this.shadowRoot.querySelector('.d2l-html-block-rendered');
|
|
184
|
+
this._context = this._contextObserverController ? { ...this._contextObserverController.values } : {};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
updated() {
|
|
188
|
+
super.updated();
|
|
189
|
+
if (this._contextObserverController && this._contextObjectHasChanged()) {
|
|
190
|
+
const template = this.querySelector('template');
|
|
191
|
+
this._stamp(template);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
_contextObjectHasChanged() {
|
|
196
|
+
if (this._context.size !== this._contextObserverController.values.size) return true;
|
|
197
|
+
for (const [attr, val] of this._context) {
|
|
198
|
+
if (!this._contextObserverController.values.has(attr)) return true;
|
|
199
|
+
if (this._contextObserverController.values.get(attr) !== val) return true;
|
|
200
|
+
}
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
_stamp(template) {
|
|
158
205
|
const stampHTML = async template => {
|
|
159
206
|
const fragment = template ? document.importNode(template.content, true) : null;
|
|
160
207
|
if (fragment) {
|
|
@@ -162,8 +209,14 @@ class HtmlBlock extends LitElement {
|
|
|
162
209
|
let temp = document.createElement('div');
|
|
163
210
|
temp.appendChild(fragment);
|
|
164
211
|
|
|
165
|
-
for (const
|
|
166
|
-
|
|
212
|
+
for (const renderer of getRenderers()) {
|
|
213
|
+
if (this._contextObserverController && renderer.contextAttributes) {
|
|
214
|
+
const contextValues = new Map();
|
|
215
|
+
renderer.contextAttributes.forEach(attr => contextValues.set(attr, this._contextObserverController.values.get(attr)));
|
|
216
|
+
temp = await renderer.render(temp, contextValues);
|
|
217
|
+
} else {
|
|
218
|
+
temp = await renderer.render(temp);
|
|
219
|
+
}
|
|
167
220
|
}
|
|
168
221
|
this._renderContainer.innerHTML = temp.innerHTML;
|
|
169
222
|
|
|
@@ -172,26 +225,13 @@ class HtmlBlock extends LitElement {
|
|
|
172
225
|
}
|
|
173
226
|
};
|
|
174
227
|
|
|
175
|
-
this.
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
if (this._templateObserver) this._templateObserver.disconnect();
|
|
181
|
-
if (template) {
|
|
182
|
-
this._templateObserver = new MutationObserver(() => stampHTML(template));
|
|
183
|
-
this._templateObserver.observe(template.content, { attributes: true, childList: true, subtree: true });
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
stampHTML(template);
|
|
187
|
-
|
|
188
|
-
});
|
|
189
|
-
this._renderContainer = this.shadowRoot.querySelector('.d2l-html-block-rendered');
|
|
190
|
-
|
|
191
|
-
}
|
|
228
|
+
if (this._templateObserver) this._templateObserver.disconnect();
|
|
229
|
+
if (template) {
|
|
230
|
+
this._templateObserver = new MutationObserver(() => stampHTML(template));
|
|
231
|
+
this._templateObserver.observe(template.content, { attributes: true, childList: true, subtree: true });
|
|
232
|
+
}
|
|
192
233
|
|
|
193
|
-
|
|
194
|
-
return getRenderers();
|
|
234
|
+
stampHTML(template);
|
|
195
235
|
}
|
|
196
236
|
|
|
197
237
|
}
|
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
const controllerCallbacks = new Map();
|
|
2
2
|
|
|
3
3
|
const contextObserver = new MutationObserver(mutations => {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
controllerCallbacks.forEach(callback => callback(
|
|
5
|
+
mutations.map(mutation => mutation.attributeName)
|
|
6
|
+
));
|
|
7
7
|
});
|
|
8
8
|
|
|
9
9
|
export class HtmlAttributeObserverController {
|
|
10
10
|
|
|
11
|
-
constructor(host,
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
constructor(host, ...attributes) {
|
|
12
|
+
if (attributes.length === 0) throw new Error(
|
|
13
|
+
'Can\'t construct controller; must supply at least one observed attribute.'
|
|
14
|
+
);
|
|
14
15
|
|
|
15
|
-
this.
|
|
16
|
+
this._host = host;
|
|
17
|
+
this._attributes = attributes;
|
|
18
|
+
this.values = new Map();
|
|
16
19
|
}
|
|
17
20
|
|
|
18
21
|
hostConnected() {
|
|
19
|
-
this.
|
|
20
|
-
? document.documentElement.getAttribute(this._attribute)
|
|
21
|
-
: undefined;
|
|
22
|
+
this._updateAttributeValues(this._attributes);
|
|
22
23
|
if (controllerCallbacks.size === 0) contextObserver.observe(document.documentElement, { attributes: true });
|
|
23
24
|
controllerCallbacks.set(this, this._handleContextChange.bind(this));
|
|
24
25
|
}
|
|
@@ -27,12 +28,22 @@ export class HtmlAttributeObserverController {
|
|
|
27
28
|
controllerCallbacks.delete(this);
|
|
28
29
|
}
|
|
29
30
|
|
|
30
|
-
_handleContextChange(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
: undefined;
|
|
31
|
+
_handleContextChange(attributeNames) {
|
|
32
|
+
const attributes = attributeNames.filter(attr => this._attributes.includes(attr));
|
|
33
|
+
if (attributes.length === 0) return;
|
|
34
|
+
this._updateAttributeValues(attributes);
|
|
35
35
|
this._host.requestUpdate();
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
_updateAttributeValues(names) {
|
|
39
|
+
names.forEach(name => {
|
|
40
|
+
this.values.set(
|
|
41
|
+
name,
|
|
42
|
+
document.documentElement.hasAttribute(name)
|
|
43
|
+
? document.documentElement.getAttribute(name)
|
|
44
|
+
: undefined
|
|
45
|
+
);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
38
49
|
}
|
package/helpers/mathjax.js
CHANGED
|
@@ -1,24 +1,38 @@
|
|
|
1
|
+
const mathjaxContextAttribute = 'data-mathjax-context';
|
|
2
|
+
|
|
1
3
|
let mathJaxLoaded;
|
|
2
4
|
|
|
3
|
-
export
|
|
4
|
-
const context = JSON.parse(document.documentElement.getAttribute('data-mathjax-context')) || {};
|
|
5
|
-
const isLatexSupported = context.renderLatex;
|
|
5
|
+
export class HtmlBlockMathRenderer {
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
get contextAttributes() {
|
|
8
|
+
return [mathjaxContextAttribute];
|
|
9
|
+
}
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
async render(elem, contextValues) {
|
|
12
|
+
if (!contextValues) return elem;
|
|
13
|
+
const contextVal = contextValues.get(mathjaxContextAttribute);
|
|
14
|
+
if (contextVal === undefined) return elem;
|
|
15
|
+
|
|
16
|
+
const context = JSON.parse(contextVal) || {};
|
|
17
|
+
const isLatexSupported = context.renderLatex;
|
|
18
|
+
|
|
19
|
+
if (!elem.querySelector('math') && !(isLatexSupported && /\$\$|\\\(|\\\[|\\begin{|\\ref{|\\eqref{/.test(elem.innerHTML))) return elem;
|
|
20
|
+
|
|
21
|
+
const mathJaxConfig = {
|
|
22
|
+
renderLatex: isLatexSupported,
|
|
23
|
+
outputScale: context.outputScale || 1
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
await loadMathJax(mathJaxConfig);
|
|
13
27
|
|
|
14
|
-
|
|
28
|
+
const temp = document.createElement('div');
|
|
29
|
+
temp.attachShadow({ mode: 'open' });
|
|
30
|
+
temp.shadowRoot.innerHTML = `<div><mjx-doc><mjx-head></mjx-head><mjx-body>${elem.innerHTML}</mjx-body></mjx-doc></div>`;
|
|
15
31
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
32
|
+
window.MathJax.typesetShadow(temp.shadowRoot);
|
|
33
|
+
return temp.shadowRoot.firstChild;
|
|
34
|
+
}
|
|
19
35
|
|
|
20
|
-
window.MathJax.typesetShadow(temp.shadowRoot);
|
|
21
|
-
return temp.shadowRoot.firstChild;
|
|
22
36
|
}
|
|
23
37
|
|
|
24
38
|
export function loadMathJax(mathJaxConfig) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brightspace-ui/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.206.0",
|
|
4
4
|
"description": "A collection of accessible, free, open-source web components for building Brightspace applications",
|
|
5
5
|
"repository": "https://github.com/BrightspaceUI/core.git",
|
|
6
6
|
"publishConfig": {
|