diff --git a/packages/provider/assets/index.html.ejs b/packages/provider/assets/index.html.ejs index 3d35a5f69accc3305eae3ac28c870d9bf881eb7f..632576144de80430c2485daad1c5c71449f32f8a 100644 --- a/packages/provider/assets/index.html.ejs +++ b/packages/provider/assets/index.html.ejs @@ -1,7 +1,8 @@ <!doctype html> -<html> +<html lang="de"> <head> <meta charset="UTF-8"> + <title>Provider Demo 1</title> <script type="module" src="dbp-provider.js"></script> <script type="module" src="dbp-provider-demo.js"></script> <!-- @@ -19,9 +20,16 @@ </head> <body> + <pre><dbp-provider id="root" root="1" availability="global" ></dbp-provider></pre> <dbp-provider id="root" root="1" availability="global" lang="de"> <dbp-provider-demo id="provider-demo" subscribe="lang:lang"></dbp-provider-demo> </dbp-provider> + <hr> + <ul> + <li>multiple, explicit providers</li> + <li><a href="/index2.html">automatic generated provider</a></li> + <li><a href="/index3.html">explicit provider</a></li> + </ul> <p>version: <span style="color: white; background-color: black;"><%= buildInfo.info %></span></p> </body> </html> diff --git a/packages/provider/assets/index2.html.ejs b/packages/provider/assets/index2.html.ejs new file mode 100644 index 0000000000000000000000000000000000000000..1f85931d5d12b851a156550549c2540b5ead4a80 --- /dev/null +++ b/packages/provider/assets/index2.html.ejs @@ -0,0 +1,23 @@ +<!doctype html> +<html lang="de"> +<head> + <meta charset="UTF-8"> + <title>Provider Demo 2a</title> + <script type="module" src="dbp-provider.js"></script> + <script type="module" src="dbp-provider-demo2.js"></script> + <style> + body { padding: 50px;} + </style> +</head> + +<body> + <dbp-provider-demo2 id="provider-demo" subscribe="lang:lang"></dbp-provider-demo2> + <hr> + <ul> + <li><a href="/index.html">multiple, explicit providers</a></li> + <li>automatic generated provider</li> + <li><a href="/index3.html">explicit provider</a></li> + </ul> + <p>version: <span style="color: white; background-color: black;"><%= buildInfo.info %></span></p> +</body> +</html> diff --git a/packages/provider/assets/index3.html.ejs b/packages/provider/assets/index3.html.ejs new file mode 100644 index 0000000000000000000000000000000000000000..eeae9af581c64ac2efbff6b44365ea3d30d255ca --- /dev/null +++ b/packages/provider/assets/index3.html.ejs @@ -0,0 +1,26 @@ +<!doctype html> +<html lang="de"> +<head> + <meta charset="UTF-8"> + <title>Provider Demo 2b</title> + <script type="module" src="dbp-provider.js"></script> + <script type="module" src="dbp-provider-demo2.js"></script> + <style> + body { padding: 50px;} + </style> +</head> + +<body> +<pre><dbp-provider id="child-of-body" root="1" lang="de" ></dbp-provider></pre> + <dbp-provider id="child-of-body" root="1" lang="de"> + <dbp-provider-demo2 id="provider-demo" subscribe="lang:lang"></dbp-provider-demo2> + </dbp-provider> + <hr> + <ul> + <li><a href="/index.html">multiple, explicit providers</a></li> + <li><a href="/index2.html">automatic generated provider</a></li> + <li>explicit provider</li> + </ul> + <p>version: <span style="color: white; background-color: black;"><%= buildInfo.info %></span></p> +</body> +</html> diff --git a/packages/provider/rollup.config.js b/packages/provider/rollup.config.js index 75560d89d352a8bca7770c648b1fd2cc1815cc85..9e5b29024f15cf86bb7bc58ad65b382c2c0583a2 100644 --- a/packages/provider/rollup.config.js +++ b/packages/provider/rollup.config.js @@ -41,7 +41,7 @@ function getBuildInfo() { export default (async () => { return { - input: (build != 'test') ? ['src/dbp-provider.js', 'src/dbp-provider-demo.js'] : glob.sync('test/**/*.js'), + input: (build !== 'test') ? ['src/dbp-provider.js', 'src/dbp-provider-demo.js', 'src/dbp-provider-demo2.js'] : glob.sync('test/**/*.js'), output: { dir: 'dist', entryFileNames: '[name].js', @@ -94,6 +94,8 @@ export default (async () => { copy({ targets: [ {src: 'assets/index.html', dest: 'dist'}, + {src: 'assets/index2.html', dest: 'dist'}, + {src: 'assets/index3.html', dest: 'dist'}, {src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), dest: 'dist/' + await getDistPath('@dbp-toolkit/common', 'icons')}, {src: 'assets/favicon.ico', dest:'dist'}, ], diff --git a/packages/provider/src/adapter-lit-element.js b/packages/provider/src/adapter-lit-element.js index bcdf0929d479be253bd3c937117df3869dcc1fe6..cee656aa87b177797ec47d4bb2b84fab5f1f42b8 100644 --- a/packages/provider/src/adapter-lit-element.js +++ b/packages/provider/src/adapter-lit-element.js @@ -1,8 +1,50 @@ import {LitElement} from "lit-element"; +import {Provider} from '@dbp-toolkit/provider'; export class AdapterLitElement extends LitElement { + static inititialized=false; + static pingEventListener = false; + + ping() { + if (AdapterLitElement.inititialized) { + return; + } + console.log('ping'); + AdapterLitElement.pingEventListener = window.addEventListener('ping', e => AdapterLitElement.addRootProvider(e), false); + const event = new CustomEvent('ping', + { + bubbles: true, + composed: true, + detail: { + callback: () => { + console.log('ping by some Provider cancelled.'); + window.removeEventListener('ping', AdapterLitElement.pingEventListener, false); + } + } + }); + this.dispatchEvent(event); + + AdapterLitElement.inititialized = true; + } + + static addRootProvider(/*e*/) { + console.log('pong'); + //console.dir(e); + window.removeEventListener('ping', this.pingEventListener, false); + this.pingEventListener = false; + + window.dbpProvider = new Provider(); + window.dbpProvider.root = true; + window.dbpProvider.id = 'magic-root-provider'; + window.addEventListener('subscribe', window.dbpProvider.subscribing.bind(window.dbpProvider), false); + window.addEventListener('unsubscribe', window.dbpProvider.unsubscribing.bind(window.dbpProvider), false); + window.addEventListener('set-property', window.dbpProvider.settingProperty.bind(window.dbpProvider), false); + + } + constructor() { super(); + this.ping(); this.connected = false; this.deferSubscribe = false; this.deferUnSubscribe = false; diff --git a/packages/provider/src/dbp-provider-demo.js b/packages/provider/src/dbp-provider-demo.js index 10a482fb5cdd9e3a17597528f42c178824cf6e85..d2277a784323c7cfea7afebc87e65002d3cd4401 100644 --- a/packages/provider/src/dbp-provider-demo.js +++ b/packages/provider/src/dbp-provider-demo.js @@ -71,10 +71,8 @@ class ProviderDemo extends ScopedElementsMixin(DBPLitElement) { render() { return html` <section class="section"> - <p>${i18n.t('demo.provider_description', {id: "root", description: "is the top most in hierarchy"})}</p> - <pre><dbp-provider id="root" root="1" availability="global" ></dbp-provider></pre> <div class="container"> - <h1 class="title">${i18n.t('demo.provider')}-Demo</h1> + <h1 class="title">${i18n.t('demo.provider')}-Demo 1</h1> </div> <div class="container"> <dbp-auth-keycloak lang="${this.lang}" url="https://auth-dev.tugraz.at/auth" realm="tugraz" client-id="auth-dev-mw-frontend-local" load-person try-login></dbp-auth-keycloak> @@ -127,7 +125,6 @@ class DemoConsumer extends DBPLitElement { // default values this.foo = 100; this.bar = 900; - this.ping = 0; this.borderColor = 'green'; this.status = 'local'; @@ -150,7 +147,6 @@ class DemoConsumer extends DBPLitElement { bar: { type: String }, gong: { type: String }, borderColor: { type: String, attribute: 'border-color' }, - ping: { type: String } }; } diff --git a/packages/provider/src/dbp-provider-demo2.js b/packages/provider/src/dbp-provider-demo2.js new file mode 100644 index 0000000000000000000000000000000000000000..8369171b2ce50cf9b68c08f41dcc81e4ed207efc --- /dev/null +++ b/packages/provider/src/dbp-provider-demo2.js @@ -0,0 +1,188 @@ +import {i18n} from './i18n.js'; +import {css, html} from 'lit-element'; +import {ScopedElementsMixin} from '@open-wc/scoped-elements'; +import {AuthKeycloak, LoginButton} from '@dbp-toolkit/auth'; +import * as commonUtils from '@dbp-toolkit/common/utils'; +import * as commonStyles from '@dbp-toolkit/common/styles'; +import {Provider} from '@dbp-toolkit/provider'; +import {LanguageSelect} from '@dbp-toolkit/language-select'; +import DBPLitElement from "@dbp-toolkit/common/dbp-lit-element"; + + +class ProviderDemo2 extends ScopedElementsMixin(DBPLitElement) { + + constructor() { + super(); + this.lang = 'de'; + } + + static get scopedElements() { + return { + 'dbp-auth-keycloak': AuthKeycloak, + 'dbp-login-button': LoginButton, + 'dbp-language-select': LanguageSelect, + 'dbp-provider': Provider, + 'dbp-consumer2': DemoConsumer2, + }; + } + + static get properties() { + return { + ...super.properties, + lang: { type: String }, + }; + } + + connectedCallback() { + super.connectedCallback(); + i18n.changeLanguage(this.lang); + + } + + attributeChangedCallback(name, oldValue, newValue) { + console.log('ProviderDemo (' + this.id + ') attributeChangesCallback( ' + name + ', ' + oldValue + ', ' + newValue + ')'); + switch(name) { + case 'lang': + this.lang = newValue; + i18n.changeLanguage(this.lang); + break; + default: + super.attributeChangedCallback(name, oldValue, newValue); + } + this.render(); + } + + static get styles() { + // language=css + return [ + commonStyles.getThemeCSS(), + commonStyles.getGeneralCSS(), + css` + h1.title {margin-bottom: 1em;} + div.container {margin-bottom: 1.5em; padding-left:20px;} + ` + ]; + } + + get id() { + return this.getAttribute('id'); + } + + render() { + return html` + <section class="section"> + <div class="container"> + <h1 class="title">${i18n.t('demo.provider')}-Demo 2</h1> + </div> + <div class="container"> + <dbp-auth-keycloak lang="${this.lang}" url="https://auth-dev.tugraz.at/auth" realm="tugraz" client-id="auth-dev-mw-frontend-local" load-person try-login></dbp-auth-keycloak> + <dbp-login-button lang="${this.lang}" show-image></dbp-login-button> + <dbp-language-select></dbp-language-select> + </div> + <div class="container"> + <h2>${i18n.t('demo.consumer')}</h2> + <p>${i18n.t('demo.consumer_description', {id: "c1", subscriptions: "border-color, lang"})}</p> + <pre><dbp-consumer2 id="c1" subscribe="border-color:bc,lang:lang" ></dbp-consumer></pre> + <dbp-consumer2 id="c1" subscribe="border-color:bc,lang:lang"></dbp-consumer2> + </div> + </section> + `; + } +} + +commonUtils.defineCustomElement('dbp-provider-demo2', ProviderDemo2); + +// ======================================================= + +class DemoConsumer2 extends DBPLitElement { + constructor() { + super(); + + this.lang = 'de'; + // default values + this.foo = 100; + this.bar = 900; + this.borderColor = 'green'; + + this.status = 'local'; + + console.log('DemoConsumer2 constructor()'); + } + + connectedCallback() { + super.connectedCallback(); + i18n.changeLanguage(this.lang); + console.log('DemoConsumer2(' + this.id + ') connectedCallback()'); + this.render(); + } + + static get properties() { + return { + ...super.properties, + lang: { type: String }, + foo: { type: String }, + bar: { type: String }, + gong: { type: String }, + borderColor: { type: String, attribute: 'border-color' }, + }; + } + + attributeChangedCallback(name, oldValue, newValue) { + if (oldValue === newValue) { + return; + } + + console.log('DemoConsumer2(' + this.id + ') attributeChangesCallback( ' + name + ', ' + oldValue + ', ' + newValue + ')'); + switch(name) { + case 'lang': + this.lang = newValue; + i18n.changeLanguage(this.lang); + break; + case 'foo': + this.foo = parseInt(newValue); + break; + case 'bar': + this.bar = parseInt(newValue); + break; + case 'status': + this.status = newValue; + break; + case 'border-color': + this['border-color'] = newValue; + break; + default: + super.attributeChangedCallback(name, oldValue, newValue); + } + this.render(); + } + + get id() { + return this.getAttribute('id'); + } + + render() { + if (! this.connected) { + return `not connected!`; + } + console.log('DemoConsumer2(' + this.id + ') render()'); + + const sum = this.foo + this.bar; + return html` + <div style="border: ${this['border-color']} dotted; padding: 10px;"> + <table style="width:200px;"> + <tr style="background-color: #aaa;"> + <th style="text-align: left;">${i18n.t('consumer.item')}</th> + <th style="text-align: right;">${i18n.t('consumer.price')}</th> + </tr> + <tr><td>foo</td><td style="text-align: right;">${this.foo}</td></tr> + <tr><td>bar</td><td style="text-align: right;">${this.bar}</td></tr> + <tr><td>${i18n.t('consumer.sum')}</td><td style="text-align: right;">${sum}</td></tr> + </table> + <p>Status: <b>${this.status}</b></p> + </div> + `; + } + +} + +customElements.define('dbp-consumer2', DemoConsumer2); diff --git a/packages/provider/src/provider.js b/packages/provider/src/provider.js index fc3aff38c9ac5b246e7b773cf6bb4e8dbb5576fa..37543679f3d59ed7292c0fe77079330d9b0121b4 100644 --- a/packages/provider/src/provider.js +++ b/packages/provider/src/provider.js @@ -37,51 +37,12 @@ export class Provider extends HTMLElement { const that = this; - this.addEventListener('subscribe', function (e) { - const name = e.detail.name; - if (that.hasProperty(name) || that.root) { - console.log('Provider(' + that.id + ') eventListener("subscribe",..) name "' + name + '" found.'); - that.callbackStore.push({name: name, callback: e.detail.callback, sender: e.detail.sender}); - - e.detail.callback(that.getProperty(name)); - e.stopPropagation(); - } - }, false); - - this.addEventListener('unsubscribe', function (e) { - const name = e.detail.name; - const sender = e.detail.sender; - if (that.hasProperty(name) || that.root) { - console.log('Provider(' + that.id + ') eventListener("unsubscribe",..) name "' + name + '" found.'); - that.callbackStore.forEach(item => { - if (item.sender === sender && item.name === name) { - const index = that.callbackStore.indexOf(item); - that.callbackStore.splice(index, 1); - console.log('Provider(' + that.id + ') eventListener for name "' + name + '" removed.'); - } - }); - - e.stopPropagation(); - } - }, false); - - // listen to property changes - this.addEventListener('set-property', function (e) { - const name = e.detail.name; - const value = e.detail.value; - - if (that.hasProperty(name) || that.root) { - console.log('Provider(' + that.id + ') eventListener("set-property",..) name "' + name + '" found.'); - that.setProperty(name, value); - - that.callbackStore.forEach(item => { - if (item.name === name) { - item.callback(value); - } - }); - - e.stopPropagation(); - } + this.addEventListener('subscribe', this.subscribing.bind(this), false); + this.addEventListener('unsubscribe', this.unsubscribing.bind(this), false); + this.addEventListener('set-property', this.settingProperty.bind(this), false); + this.addEventListener('ping', function (e) { + e.stopPropagation(); + e.detail.callback(); }, false); // Options for the observer (which mutations to observe) @@ -132,4 +93,54 @@ export class Provider extends HTMLElement { get id() { return this.getAttribute('id'); } + + set id(id) { + this.setAttribute('id', id); + } + + subscribing (e) { + const name = e.detail.name; + if (this.hasProperty(name) || this.root) { + console.log('Provider(' + this.id + ') eventListener("subscribe",..) name "' + name + '" found.'); + this.callbackStore.push({name: name, callback: e.detail.callback, sender: e.detail.sender}); + + e.detail.callback(this.getProperty(name)); + e.stopPropagation(); + } + } + + unsubscribing (e) { + const name = e.detail.name; + const sender = e.detail.sender; + if (this.hasProperty(name) || this.root) { + console.log('Provider(' + this.id + ') eventListener("unsubscribe",..) name "' + name + '" found.'); + this.callbackStore.forEach(item => { + if (item.sender === sender && item.name === name) { + const index = this.callbackStore.indexOf(item); + this.callbackStore.splice(index, 1); + console.log('Provider(' + this.id + ') eventListener for name "' + name + '" removed.'); + } + }); + + e.stopPropagation(); + } + } + + settingProperty (e) { + const name = e.detail.name; + const value = e.detail.value; + + if (this.hasProperty(name) || this.root) { + console.log('Provider(' + this.id + ') eventListener("set-property",..) name "' + name + '" found.'); + this.setProperty(name, value); + + this.callbackStore.forEach(item => { + if (item.name === name) { + item.callback(value); + } + }); + + e.stopPropagation(); + } + } }