@brightspace-ui/core 2.188.1 → 2.190.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.
@@ -1,12 +1,13 @@
|
|
1
1
|
import '../colors/colors.js';
|
2
2
|
import { codeStyles, createHtmlBlockRenderer as createCodeRenderer } from '../../helpers/prism.js';
|
3
|
-
import { css, html, LitElement, unsafeCSS } from 'lit';
|
3
|
+
import { css, html, LitElement, nothing, unsafeCSS } from 'lit';
|
4
4
|
import { classMap } from 'lit/directives/class-map.js';
|
5
5
|
import { createHtmlBlockRenderer as createMathRenderer } from '../../helpers/mathjax.js';
|
6
6
|
import { getFocusPseudoClass } from '../../helpers/focus.js';
|
7
7
|
import { HtmlAttributeObserverController } from '../../controllers/attributeObserver/htmlAttributeObserverController.js';
|
8
|
-
|
8
|
+
import { renderEmbeds } from '../../helpers/embeds.js';
|
9
9
|
import { requestInstance } from '../../mixins/provider/provider-mixin.js';
|
10
|
+
import { until } from 'lit/directives/until.js';
|
10
11
|
|
11
12
|
export const htmlBlockContentStyles = css`
|
12
13
|
.d2l-html-block-rendered {
|
@@ -231,7 +232,9 @@ class HtmlBlock extends LitElement {
|
|
231
232
|
};
|
232
233
|
|
233
234
|
return html`
|
234
|
-
<div class="${classMap(renderContainerClasses)}"
|
235
|
+
<div class="${classMap(renderContainerClasses)}">
|
236
|
+
${(this._embedsFeatureEnabled() && !this.noDeferredRendering) ? until(this._processEmbeds(), nothing) : nothing}
|
237
|
+
</div>
|
235
238
|
${this.noDeferredRendering ? html`<slot @slotchange="${this._handleSlotChange}"></slot>` : ''}
|
236
239
|
`;
|
237
240
|
}
|
@@ -270,11 +273,21 @@ class HtmlBlock extends LitElement {
|
|
270
273
|
return false;
|
271
274
|
}
|
272
275
|
|
276
|
+
_embedsFeatureEnabled() {
|
277
|
+
return window.D2L?.LP?.Web?.UI?.Flags.Flag('shield-7574-enable-embed-rendering-framework', true);
|
278
|
+
}
|
279
|
+
|
273
280
|
async _handleSlotChange(e) {
|
274
281
|
if (!e.target || !this.shadowRoot || !this.noDeferredRendering) return;
|
275
282
|
await this._renderInline(e.target);
|
276
283
|
}
|
277
284
|
|
285
|
+
async _processEmbeds() {
|
286
|
+
const htmlFragment = document.createRange().createContextualFragment(this.html);
|
287
|
+
await renderEmbeds(htmlFragment);
|
288
|
+
return htmlFragment;
|
289
|
+
}
|
290
|
+
|
278
291
|
async _processRenderers(elem) {
|
279
292
|
await this._contextObserverControllerInitialized;
|
280
293
|
const renderers = await getRenderers();
|
@@ -324,7 +337,7 @@ class HtmlBlock extends LitElement {
|
|
324
337
|
|
325
338
|
async _updateRenderContainer() {
|
326
339
|
const renderContainer = this.shadowRoot.querySelector('.d2l-html-block-rendered');
|
327
|
-
renderContainer.innerHTML = this.html;
|
340
|
+
if (!this._embedsFeatureEnabled()) renderContainer.innerHTML = this.html;
|
328
341
|
await this._processRenderers(renderContainer);
|
329
342
|
}
|
330
343
|
|
@@ -0,0 +1,102 @@
|
|
1
|
+
import { html, nothing, render } from 'lit';
|
2
|
+
import { ifDefined } from 'lit/directives/if-defined.js';
|
3
|
+
import { map } from 'lit/directives/map.js';
|
4
|
+
import { tryGetPluginByKey } from './plugins.js';
|
5
|
+
|
6
|
+
const embedTypeAttributeName = 'data-d2l-embed-type';
|
7
|
+
|
8
|
+
function tryGetEmbedRendererPlugin(embedType) {
|
9
|
+
const embedRendererPlugin = tryGetPluginByKey('d2l-html-embed-renderer', embedType);
|
10
|
+
if (!embedRendererPlugin) {
|
11
|
+
console.warn(`d2l-html-embed-renderer: Can't find plugin for ${embedType} embed type.`);
|
12
|
+
}
|
13
|
+
|
14
|
+
return embedRendererPlugin;
|
15
|
+
}
|
16
|
+
|
17
|
+
export async function createEmbedViewPlaceholder(embedType, props) {
|
18
|
+
const embedRendererPlugin = tryGetEmbedRendererPlugin(embedType);
|
19
|
+
if (!embedRendererPlugin) return;
|
20
|
+
|
21
|
+
const placeholderData = await embedRendererPlugin.getViewPlaceholderData(props);
|
22
|
+
const contents = placeholderData.contents
|
23
|
+
? map(Object.entries(placeholderData.contents), ([id, content]) => html`<template data-d2l-embed-template-id=${id}>${content}</template>`)
|
24
|
+
: nothing;
|
25
|
+
|
26
|
+
const properties = placeholderData.properties ? JSON.stringify(placeholderData.properties) : undefined;
|
27
|
+
|
28
|
+
return placeholderData.inline
|
29
|
+
? html`
|
30
|
+
<span data-d2l-embed-type="${embedType}" data-d2l-embed-props="${ifDefined(properties)}" style="${placeholderData.style}">
|
31
|
+
${contents}
|
32
|
+
</span>
|
33
|
+
` : html`
|
34
|
+
<div data-d2l-embed-type="${embedType}" data-d2l-embed-props="${ifDefined(properties)}" style="${placeholderData.style}">
|
35
|
+
${contents}
|
36
|
+
</div>
|
37
|
+
`;
|
38
|
+
}
|
39
|
+
|
40
|
+
export async function createEmbedEditorPlaceholder(embedType, props) {
|
41
|
+
const embedRendererPlugin = tryGetEmbedRendererPlugin(embedType);
|
42
|
+
if (!embedRendererPlugin) return;
|
43
|
+
|
44
|
+
const placeholderData = await embedRendererPlugin.getEditorPlaceholderData(props);
|
45
|
+
const text = placeholderData.text || nothing;
|
46
|
+
|
47
|
+
const properties = placeholderData.properties ? JSON.stringify(placeholderData.properties) : undefined;
|
48
|
+
|
49
|
+
return placeholderData.inline
|
50
|
+
? html`
|
51
|
+
<span
|
52
|
+
contentEditable="${ifDefined(placeholderData.contentEditable)}"
|
53
|
+
data-d2l-embed-type="${embedType}"
|
54
|
+
data-d2l-embed-props="${ifDefined(properties)}"
|
55
|
+
style="${placeholderData.style}">
|
56
|
+
${text}
|
57
|
+
</span>
|
58
|
+
` : html`
|
59
|
+
<div
|
60
|
+
contentEditable="${ifDefined(placeholderData.contentEditable)}"
|
61
|
+
data-d2l-embed-type="${embedType}"
|
62
|
+
data-d2l-embed-props="${ifDefined(properties)}"
|
63
|
+
style="${placeholderData.style}">
|
64
|
+
${text}
|
65
|
+
</div>
|
66
|
+
`;
|
67
|
+
}
|
68
|
+
|
69
|
+
export async function renderEmbeds(node) {
|
70
|
+
const placeholders = [...node.querySelectorAll(`div[${embedTypeAttributeName}], span[${embedTypeAttributeName}]`)];
|
71
|
+
if (placeholders.length === 0) return;
|
72
|
+
|
73
|
+
const processPlaceholder = async placeholder => {
|
74
|
+
const embedRendererPlugin = tryGetEmbedRendererPlugin(placeholder.dataset.d2lEmbedType);
|
75
|
+
if (!embedRendererPlugin) return;
|
76
|
+
|
77
|
+
const templates = [...placeholder.querySelectorAll('template[data-d2l-embed-template-id]')];
|
78
|
+
const processedTemplates = await Promise.all(templates.map(async template => {
|
79
|
+
const templateNode = template.content.cloneNode(true);
|
80
|
+
await renderEmbeds(templateNode);
|
81
|
+
return html`${templateNode}`;
|
82
|
+
}));
|
83
|
+
|
84
|
+
const processedTemplateContents = templates.reduce((acc, template, index) => {
|
85
|
+
acc[template.dataset.d2lEmbedTemplateId] = processedTemplates[index];
|
86
|
+
return acc;
|
87
|
+
}, {});
|
88
|
+
|
89
|
+
const props = JSON.parse(placeholder.dataset.d2lEmbedProps);
|
90
|
+
return embedRendererPlugin.renderView(processedTemplateContents, props);
|
91
|
+
};
|
92
|
+
|
93
|
+
const embeds = await Promise.all(placeholders.map(processPlaceholder));
|
94
|
+
placeholders.forEach((placeholder, index) => {
|
95
|
+
if (!embeds[index]) {
|
96
|
+
console.warn(`d2l-html-embed-renderer: Can't find valid embed for placeholder with ${placeholder.dataset.d2lEmbedType} embed type`);
|
97
|
+
}
|
98
|
+
|
99
|
+
render(embeds[index], placeholder.parentNode, { renderBefore: placeholder });
|
100
|
+
placeholder.remove();
|
101
|
+
});
|
102
|
+
}
|
@@ -61,9 +61,15 @@ static get localizeConfig() {
|
|
61
61
|
}
|
62
62
|
```
|
63
63
|
|
64
|
+
### Lifecycle
|
65
|
+
|
66
|
+
The `LocalizeMixin` blocks Lit component updates until the translations are loaded by returning `false` from `shouldUpdate()`. This means that the component is guaranteed to load valid terms [anywhere in the Lit lifecycle from `willUpdate()` onwards](https://lit.dev/docs/components/lifecycle/#reactive-update-cycle).
|
67
|
+
|
68
|
+
Two common patterns for using `localize()` are within `render()` to modify the component's rendering, and within `firstUpdated()` to modify a page's `document.title`.
|
69
|
+
|
64
70
|
### `localize()`
|
65
71
|
|
66
|
-
The `localize()` method is used to localize a piece of text
|
72
|
+
The `localize()` method is used to localize a piece of text.
|
67
73
|
|
68
74
|
If the localized string contains arguments, pass them as a key-value object as the 2nd parameter:
|
69
75
|
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@brightspace-ui/core",
|
3
|
-
"version": "2.
|
3
|
+
"version": "2.190.0",
|
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",
|