Commit d0da616d authored by Benjamin Franzke's avatar Benjamin Franzke
Browse files

[TASK] Update to Lit v2-rc1

Lit is the umbrella term for the next major
lit-html (v2) and lit-element (v3) versions.
Therefore we will refer to these components as
*Lit* in TYPO3 from now on as well.

These two libraries also have been migrated into
a single entry point module named `lit`.
It is officially described as:
> The main module exports the core pieces needed for component
> development: LitElement, html, css, and the most

lit-html v2 and lit-element v3 are mostly compatible
to the previous major versions. Main changes are

 * Deprecation of the `lit-element` entry point in
   favor of the new `lit` module
 * @internalProperty changed to @state
 * shadow css declaration via static property
   instead of static getter method
 * The CSSResult type declaration is gone
 * Directive (currently unused in TYPO3) API has changed

Related testing framework change is:
https://github.com/TYPO3/testing-framework/pull/229

Commands used:

  rm -rf typo3/sysext/core/Resources/Public/JavaScript/Contrib/{@lit,lit-element,lit-html,lit}/
  yarn add lit@^2.0.0-rc.1 lit-html@^2.0.0-rc.2 lit-element@^3.0.0-rc.1
  yarn add --dev rollup@^2.32.0 @rollup/plugin-replace
  grunt build
  git add typo3/sysext/core/Resources/Public/JavaScript/Contrib/{@lit,lit-element,lit-html,lit}/

  composer require --dev typo3/testing-framework:^6.8.1
  composer require --dev typo3/testing-framework:^6.8.1 \
    --no-update --working-dir=typo3/sysext/core

Resolves: #93965
Releases: master
Change-Id: I9b659d851e6ad9dc3cc649bd40aab886b86fb0f8
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/68104

Tested-by: Oliver Hader's avatarOliver Hader <oliver.hader@typo3.org>
Tested-by: default avatarTYPO3com <noreply@typo3.com>
Tested-by: core-ci's avatarcore-ci <typo3@b13.com>
Tested-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
Tested-by: Benjamin Franzke's avatarBenjamin Franzke <bfr@qbus.de>
Reviewed-by: Oliver Hader's avatarOliver Hader <oliver.hader@typo3.org>
Reviewed-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
Reviewed-by: Benjamin Franzke's avatarBenjamin Franzke <bfr@qbus.de>
parent 0005bc5b
......@@ -451,37 +451,43 @@ module.exports = function (grunt) {
},
rollup: {
options: {
format: 'amd',
onwarn: function(warning) {
if (warning.code === 'THIS_IS_UNDEFINED' && grunt.file.match('*/lit-html/directives/async-*.js')) {
// lit-html's Symbol.asyncIterator polyfill in async-{append/replace}.js contains
// a global check for `this`: `(this && this.__asyncValues) || function (o) {`.
// rollup will rewrite that to `function (o) {` and warn about rewriting `this`.
// The rewrite is perfectly ok, the AMD module will act as a singleton, so no
// global window object is needed here. The warning is therefore silenced.
return;
}
console.warn( warning.message );
}
format: 'amd'
},
'lit-html': {
options: {
preserveModules: true,
plugins: () => [
require('@rollup/plugin-replace')({ values: { 'globalThis': 'window' }, preventAssignment: false }),
{
name: 'terser',
renderChunk: code => require('terser').minify(code, grunt.config.get('terser.options'))
renderChunk: code => require('terser').minify(code, {...grunt.config.get('terser.options'), ...{mangle: false}})
}
]
},
files: {
'<%= paths.core %>Public/JavaScript/Contrib/lit-html': [
'node_modules/lit-html/lit-html.js',
'node_modules/lit-html/*.js',
'node_modules/lit-html/directives/*.js',
'node_modules/lit-html/lib/*.js',
]
}
},
'@lit/reactive-element': {
options: {
preserveModules: true,
plugins: () => [
require('@rollup/plugin-replace')({ values: { 'globalThis': 'window' }, preventAssignment: false }),
{
name: 'terser',
renderChunk: code => require('terser').minify(code, {...grunt.config.get('terser.options'), ...{mangle: false}})
},
]
},
files: {
'<%= paths.core %>Public/JavaScript/Contrib/@lit/reactive-element': [
'node_modules/@lit/reactive-element/*.js',
'node_modules/@lit/reactive-element/decorators/*.js',
// omitted, empty
'!node_modules/lit-html/lib/render-options.js',
'!node_modules/lit-html/lib/template-processor.js',
'!node_modules/@lit/reactive-element/reactive-controller.js'
]
}
},
......@@ -489,18 +495,16 @@ module.exports = function (grunt) {
options: {
preserveModules: true,
plugins: () => [
require('@rollup/plugin-replace')({ values: { 'globalThis': 'window' }, preventAssignment: false }),
{
name: 'terser',
renderChunk: code => require('terser').minify(code, grunt.config.get('terser.options'))
renderChunk: code => require('terser').minify(code, {...grunt.config.get('terser.options'), ...{mangle: false}})
},
{
name: 'externals',
resolveId: (source) => {
if (source === 'lit-html/lit-html.js') {
return {id: 'lit-html', external: true}
}
if (source === 'lit-html/lib/shady-render.js') {
return {id: 'lit-html/lib/shady-render', external: true}
if (source.startsWith('lit-html') || source.startsWith('@lit/reactive-element')) {
return {id: source.replace(/\.js$/, ''), external: true}
}
return null
}
......@@ -509,8 +513,36 @@ module.exports = function (grunt) {
},
files: {
'<%= paths.core %>Public/JavaScript/Contrib/lit-element': [
'node_modules/lit-element/lit-element.js',
'node_modules/lit-element/lib/*.js',
'node_modules/lit-element/*.js',
'node_modules/lit-element/decorators/*.js',
]
}
},
'lit': {
options: {
preserveModules: true,
plugins: () => [
require('@rollup/plugin-replace')({ values: { 'globalThis': 'window' }, preventAssignment: false }),
{
name: 'terser',
renderChunk: code => require('terser').minify(code, {...grunt.config.get('terser.options'), ...{mangle: false}})
},
{
name: 'externals',
resolveId: (source) => {
if (source.startsWith('lit-html') || source.startsWith('lit-element') || source.startsWith('@lit/reactive-element')) {
return {id: source.replace(/\.js$/, ''), external: true}
}
return null
}
}
]
},
files: {
'<%= paths.core %>Public/JavaScript/Contrib/lit': [
'node_modules/lit/*.js',
'node_modules/lit/decorators/*.js',
'node_modules/lit/directives/*.js',
]
}
},
......
......@@ -12,13 +12,22 @@
*/
import module = require('module');
import {html, css, unsafeCSS, customElement, property, LitElement, TemplateResult, CSSResult} from 'lit-element';
import {unsafeHTML} from 'lit-html/directives/unsafe-html';
import {until} from 'lit-html/directives/until';
import {html, css, unsafeCSS, LitElement, TemplateResult, CSSResult} from 'lit';
import {customElement, property} from 'lit/decorators';
import {unsafeHTML} from 'lit/directives/unsafe-html';
import {until} from 'lit/directives/until';
import {Sizes, States, MarkupIdentifiers} from '../Enum/IconTypes';
import Icons = require('../Icons');
import 'TYPO3/CMS/Backend/Element/SpinnerElement';
const iconUnifyModifier = 0.86;
const iconSize = (identifier: CSSResult, size: number) => css`
:host([size=${identifier}]),
:host([raw]) .icon-size-${identifier} {
font-size: ${size}px;
}
`;
/**
* Module: TYPO3/CMS/Backend/Element/IconElement
*
......@@ -45,17 +54,7 @@ export class IconElement extends LitElement {
*/
@property({type: String}) raw?: string = null;
public static get styles(): CSSResult[]
{
const iconUnifyModifier = 0.86;
const iconSize = (identifier: CSSResult, size: number) => css`
:host([size=${identifier}]),
:host([raw]) .icon-size-${identifier} {
font-size: ${size}px;
}
`;
return [
static styles = [
css`
:host {
display: flex;
......@@ -137,14 +136,12 @@ export class IconElement extends LitElement {
transform: rotate(360deg);
}
}
`,
iconSize(unsafeCSS(Sizes.small), 16),
iconSize(unsafeCSS(Sizes.default), 32),
iconSize(unsafeCSS(Sizes.large), 48),
iconSize(unsafeCSS(Sizes.mega), 64),
];
}
public render(): TemplateResult {
if (this.raw) {
......
......@@ -11,7 +11,8 @@
* The TYPO3 project - inspiring people to share!
*/
import {html, css, customElement, property, LitElement, TemplateResult, CSSResult} from 'lit-element';
import {html, css, LitElement, TemplateResult} from 'lit';
import {customElement, property} from 'lit/decorators';
import {Sizes} from '../Enum/IconTypes';
/**
......@@ -25,9 +26,7 @@ import {Sizes} from '../Enum/IconTypes';
export class SpinnerElement extends LitElement {
@property({type: String}) size: Sizes = Sizes.default;
public static get styles(): CSSResult
{
return css`
static styles = css`
:host {
font-size: 32px;
width: 1em;
......@@ -60,7 +59,6 @@ export class SpinnerElement extends LitElement {
100% { transform: rotate(360deg); }
}
`;
}
public render(): TemplateResult {
return html`<div class="spinner"></div>`
......
......@@ -11,7 +11,8 @@
* The TYPO3 project - inspiring people to share!
*/
import {html, customElement, property, LitElement, TemplateResult} from 'lit-element';
import {html, LitElement, TemplateResult} from 'lit';
import {customElement, property} from 'lit/decorators';
import {lll} from 'TYPO3/CMS/Core/lit-helper';
import 'TYPO3/CMS/Backend/Element/IconElement';
......
......@@ -14,7 +14,7 @@
import * as d3selection from 'd3-selection';
import {SvgTree, SvgTreeSettings, TreeNodeSelection} from '../../SvgTree';
import {TreeNode} from '../../Tree/TreeNode';
import {customElement} from 'lit-element';
import {customElement} from 'lit/decorators';
interface SelectTreeSettings extends SvgTreeSettings {
exclusiveNodesIdentifiers: '';
......
......@@ -13,7 +13,8 @@
import type {SelectTree} from './SelectTree';
import {Tooltip} from 'bootstrap';
import {html, customElement, LitElement, TemplateResult} from 'lit-element';
import {html, LitElement, TemplateResult} from 'lit';
import {customElement} from 'lit/decorators';
import {lll} from 'TYPO3/CMS/Core/lit-helper';
import 'TYPO3/CMS/Backend/Element/IconElement';
import './SelectTree';
......
......@@ -11,7 +11,8 @@
* The TYPO3 project - inspiring people to share!
*/
import {customElement, property, LitElement} from 'lit-element';
import {LitElement} from 'lit';
import {customElement, property} from 'lit/decorators';
import FormEngine = require('TYPO3/CMS/Backend/FormEngine');
enum UpdateMode {
......
......@@ -16,8 +16,8 @@ import Viewport = require('./Viewport');
import Icons = require('./Icons');
import 'jquery/autocomplete';
import './Input/Clearable';
import {html, render} from 'lit-html';
import {unsafeHTML} from 'lit-html/directives/unsafe-html';
import {html, render} from 'lit';
import {unsafeHTML} from 'lit/directives/unsafe-html';
import {renderHTML} from 'TYPO3/CMS/Core/lit-helper';
enum Identifiers {
......
......@@ -11,9 +11,10 @@
* The TYPO3 project - inspiring people to share!
*/
import {LitElement, html, customElement, property, internalProperty} from 'lit-element';
import {classMap} from 'lit-html/directives/class-map';
import {ifDefined} from 'lit-html/directives/if-defined';
import {LitElement, html} from 'lit';
import {customElement, property, state} from 'lit/decorators';
import {classMap} from 'lit/directives/class-map';
import {ifDefined} from 'lit/directives/if-defined';
import {AbstractAction} from './ActionButton/AbstractAction';
import {SeverityEnum} from './Enum/Severity';
import Severity = require('./Severity');
......@@ -136,8 +137,8 @@ class NotificationMessage extends LitElement {
@property() duration: number = 0;
@property({type: Array, attribute: false}) actions: Array<Action> = [];
@internalProperty() visible: boolean = false;
@internalProperty() executingAction: number = -1;
@state() visible: boolean = false;
@state() executingAction: number = -1;
createRenderRoot(): Element|ShadowRoot {
return this;
......
......@@ -11,8 +11,9 @@
* The TYPO3 project - inspiring people to share!
*/
import {html, customElement, property, query, LitElement, TemplateResult, PropertyValues} from 'lit-element';
import {until} from 'lit-html/directives/until';
import {html, LitElement, TemplateResult, PropertyValues} from 'lit';
import {customElement, property, query} from 'lit/decorators';
import {until} from 'lit/directives/until';
import {lll} from 'TYPO3/CMS/Core/lit-helper';
import {PageTree} from './PageTree';
import {TreeNode} from './../Tree/TreeNode';
......
......@@ -11,7 +11,8 @@
* The TYPO3 project - inspiring people to share!
*/
import {html, property, internalProperty, LitElement, TemplateResult, customElement} from 'lit-element';
import {html, LitElement, TemplateResult} from 'lit';
import {customElement, property, state} from 'lit/decorators';
import {TreeNode} from './Tree/TreeNode';
import * as d3selection from 'd3-selection';
import AjaxRequest from 'TYPO3/CMS/Core/Ajax/AjaxRequest';
......@@ -56,7 +57,7 @@ export interface SvgTreeWrapper extends HTMLElement {
export class SvgTree extends LitElement {
@property({type: Object}) setup?: {[keys: string]: any} = null;
@internalProperty() settings: SvgTreeSettings = {
@state() settings: SvgTreeSettings = {
showIcons: false,
marginTop: 15,
nodeHeight: 20,
......
......@@ -11,7 +11,7 @@
* The TYPO3 project - inspiring people to share!
*/
import {html, TemplateResult} from 'lit-element';
import {html, TemplateResult} from 'lit';
import {renderNodes} from 'TYPO3/CMS/Core/lit-helper';
import * as d3drag from 'd3-drag';
import * as d3selection from 'd3-selection';
......
......@@ -11,7 +11,8 @@
* The TYPO3 project - inspiring people to share!
*/
import {customElement, html, LitElement, query, TemplateResult} from 'lit-element';
import {html, LitElement, TemplateResult} from 'lit';
import {customElement, query} from 'lit/decorators';
import AjaxRequest from 'TYPO3/CMS/Core/Ajax/AjaxRequest';
import {AjaxResponse} from 'TYPO3/CMS/Core/Ajax/AjaxResponse';
import {TreeNode} from './TreeNode';
......
......@@ -11,7 +11,8 @@
* The TYPO3 project - inspiring people to share!
*/
import {html, customElement, query, LitElement, TemplateResult} from 'lit-element';
import {html, LitElement, TemplateResult} from 'lit';
import {customElement, query} from 'lit/decorators';
import {FileStorageTree} from './FileStorageTree';
import 'TYPO3/CMS/Backend/Element/IconElement';
import {TreeNode} from 'TYPO3/CMS/Backend/Tree/TreeNode';
......
......@@ -11,14 +11,15 @@
* The TYPO3 project - inspiring people to share!
*/
import {customElement, html, LitElement, query, property, TemplateResult} from 'lit-element';
import {html, LitElement, TemplateResult} from 'lit';
import {customElement, property, query} from 'lit/decorators';
import {until} from 'lit/directives/until';
import {lll} from 'TYPO3/CMS/Core/lit-helper';
import {PageTree} from '../PageTree/PageTree';
import AjaxRequest from 'TYPO3/CMS/Core/Ajax/AjaxRequest';
import {AjaxResponse} from 'TYPO3/CMS/Core/Ajax/AjaxResponse';
import {TreeNode} from './TreeNode';
import {TreeNodeSelection, Toolbar} from '../SvgTree';
import {until} from 'lit-html/directives/until';
import ElementBrowser = require('TYPO3/CMS/Recordlist/ElementBrowser');
import LinkBrowser = require('TYPO3/CMS/Recordlist/LinkBrowser');
import 'TYPO3/CMS/Backend/Element/IconElement';
......
......@@ -11,7 +11,8 @@
* The TYPO3 project - inspiring people to share!
*/
import {html, customElement, property, internalProperty, eventOptions, LitElement, TemplateResult} from 'lit-element';
import {html, LitElement, TemplateResult} from 'lit';
import {customElement, /*eventOptions,*/ property, state} from 'lit/decorators';
import {lll} from 'TYPO3/CMS/Core/lit-helper';
import Persistent = require('../Storage/Persistent');
import 'TYPO3/CMS/Backend/Element/IconElement';
......@@ -31,7 +32,7 @@ class ResizableNavigation extends LitElement {
@property({attribute: 'parent', converter: selectorConverter}) parentContainer: HTMLElement;
@property({attribute: 'navigation', converter: selectorConverter}) navigationContainer: HTMLElement;
@internalProperty() resizing: boolean = false;
@state() resizing: boolean = false;
public connectedCallback(): void {
super.connectedCallback();
......
......@@ -14,7 +14,7 @@
import DeferredAction = require('TYPO3/CMS/Backend/ActionButton/DeferredAction');
import ImmediateAction = require('TYPO3/CMS/Backend/ActionButton/ImmediateAction');
import Notification = require('TYPO3/CMS/Backend/Notification');
import type {LitElement} from 'lit-element';
import type {LitElement} from 'lit';
describe('TYPO3/CMS/Backend/Notification:', () => {
beforeEach((): void => {
......
......@@ -11,8 +11,8 @@
* The TYPO3 project - inspiring people to share!
*/
import {render, html, TemplateResult} from 'lit-html';
import {customElement, property, LitElement} from 'lit-element';
import {render, html, TemplateResult, LitElement} from 'lit';
import {customElement, property} from 'lit/decorators';
import Modal = require('TYPO3/CMS/Backend/Modal');
enum Selectors {
......@@ -56,7 +56,7 @@ class MfaTotpUrlButton extends LitElement {
<p>${this.description}</p>
<pre>${this.url}</pre>
`,
currentModal[0].querySelector(Selectors.modalBody)
currentModal[0].querySelector(Selectors.modalBody) as HTMLElement
);
}
});
......
......@@ -11,8 +11,7 @@
* The TYPO3 project - inspiring people to share!
*/
import type {TemplateResult} from 'lit-html';
import {render} from 'lit-html';
import {render, TemplateResult} from 'lit/html';
/**
* @internal
......
......@@ -12,7 +12,8 @@
*/
import CodeMirror from 'codemirror';
import {LitElement, html, css, customElement, property, internalProperty, CSSResult} from 'lit-element';
import {LitElement, html, css, CSSResult} from 'lit';
import {customElement, property, state} from 'lit/decorators';
import FormEngine = require('TYPO3/CMS/Backend/FormEngine');
import 'TYPO3/CMS/Backend/Element/SpinnerElement'
......@@ -27,11 +28,9 @@ export class CodeMirrorElement extends LitElement {
@property() label: string;
@property({type: Array}) addons: string[] = [];
@property({type: Object}) options: { [key: string]: any[] } = {};
@internalProperty() loaded: boolean = false;
@state() loaded: boolean = false;
public static get styles(): CSSResult
{
return css`
static styles = css`
:host {
display: block;
position: relative;
......@@ -43,7 +42,6 @@ export class CodeMirrorElement extends LitElement {
transform: translate(-50%, -50%);
}
`;
}
render() {
return html`
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment