@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)}"></div>
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 in the component's `render()` method.
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.188.1",
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",