diff --git a/api/js/etemplate/CustomHtmlElements/multi-video.js b/api/js/etemplate/CustomHtmlElements/multi-video.js index 70ddfdea01..5d0119a36c 100644 --- a/api/js/etemplate/CustomHtmlElements/multi-video.js +++ b/api/js/etemplate/CustomHtmlElements/multi-video.js @@ -294,7 +294,7 @@ class multi_video extends HTMLElement { get paused() { - return this.__getActiveVideo()[0]?.node?.paused; + return this.__getActiveVideo()[0] ? (this.__getActiveVideo()[0].node ? this.__getActiveVideo()[0].node.paused : undefined) : undefined; } /** * set muted attribute @@ -313,7 +313,8 @@ class multi_video extends HTMLElement { get muted() { - return this.__getActiveVideo()[0]?.node?.muted; + + return this.__getActiveVideo()[0] ? (this.__getActiveVideo()[0].node ? this.__getActiveVideo()[0].node.muted : undefined) : undefined;; } /** * get video ended attribute @@ -321,7 +322,7 @@ class multi_video extends HTMLElement { get ended() { - return this._videos[this._videos.length - 1]?.node?.ended; + return this._videos[this._videos.length - 1] ? (this._videos[this._videos.length - 1].node ? this._videos[this._videos.length - 1].node.ended : undefined) : undefined; } /** * set playbackRate @@ -340,7 +341,7 @@ class multi_video extends HTMLElement { get playbackRate() { - return this.__getActiveVideo()[0]?.node?.playbackRate; + return this.__getActiveVideo()[0] ? (this.__getActiveVideo()[0].node ? this.__getActiveVideo()[0].node.playbackRate : undefined) : undefined; } /** * set volume @@ -358,7 +359,7 @@ class multi_video extends HTMLElement { get volume() { - return this.__getActiveVideo()[0]?.node?.volume; + return this.__getActiveVideo()[0] ? (this.__getActiveVideo()[0].node ? this.__getActiveVideo()[0].node.volume : undefined) : undefined; } /************************************************* METHODES ******************************************/ @@ -369,7 +370,7 @@ class multi_video extends HTMLElement { play() { this.__playing = true; - return this.__getActiveVideo()[0]?.node?.play(); + return this.__getActiveVideo()[0] ? (this.__getActiveVideo()[0].node ? this.__getActiveVideo()[0].node.play() : undefined) : undefined; } /** * pause video @@ -378,7 +379,7 @@ class multi_video extends HTMLElement { pause() { this.__playing = false; - this.__getActiveVideo()[0]?.node?.pause(); + this.__getActiveVideo()[0] ? (this.__getActiveVideo()[0].node ? this.__getActiveVideo()[0].node.pause() : undefined) : undefined; } } // Define the new multi-video element diff --git a/api/js/etemplate/CustomHtmlElements/pdf-player.js b/api/js/etemplate/CustomHtmlElements/pdf-player.js index 7f37305ee6..37c33b1648 100644 --- a/api/js/etemplate/CustomHtmlElements/pdf-player.js +++ b/api/js/etemplate/CustomHtmlElements/pdf-player.js @@ -8,383 +8,379 @@ * @author Hadi Nategh * @copyright EGroupware GmbH */ - -/*egw:uses - /node_modules/pdfjs-dist/legacy/build/pdf.js; - /node_modules/pdfjs-dist/legacy/build/pdf.worker.js; - -*/ - // Unfortunately compiled version of module:ES2015 TS would break webcomponent constructor. -// Since we don't have ES2020 available on 21.1 we have to use JS format using require and a legacy pdfjs lib instead of TS (used in master) -var pdfjslib = require("pdfjs-dist/legacy/build/pdf"); -var pdfjs = pdfjslib['pdfjs-dist/build/pdf']; +// Since we don't have ES2020 available on 21.1 we have to use dynamic import. -pdfjs.GlobalWorkerOptions.workerSrc = 'node_modules/pdfjs-dist/legacy/build/pdf.worker.js'; +import(egw.webserverUrl+"/node_modules/@bundled-es-modules/pdfjs-dist/build/pdf.js").then((_module)=>{ + const pdfjs = _module.default; + pdfjs.GlobalWorkerOptions.workerSrc = egw.webserverUrl+'/node_modules/@bundled-es-modules/pdfjs-dist/build/pdf.worker.js'; -/* - This web component allows to display and play pdf file like a video player widget/element. Its attributes and - methodes are mostley identical as video html. No controls attribute supported yet. -*/ -class pdf_player extends HTMLElement { - /** - * shadow dom container - * @private - */ - _shadow = null; - /** - * wrapper container holds canvas - * @private - */ + /* + This web component allows to display and play pdf file like a video player widget/element. Its attributes and + methodes are mostley identical as video html. No controls attribute supported yet. + */ + class pdf_player extends HTMLElement { + /** + * shadow dom container + * @private + */ + _shadow = null; + /** + * wrapper container holds canvas + * @private + */ - /** - * keeps duration time internally - * @private - */ - _duration = 0; - /** - * keeps currentTime internally - * @private - */ + /** + * keeps duration time internally + * @private + */ + _duration = 0; + /** + * keeps currentTime internally + * @private + */ - _currentTime = 0; - /** - * Keeps playing state internally - * @private - */ + _currentTime = 0; + /** + * Keeps playing state internally + * @private + */ - __playing = false; - /** - * keeps playing interval id - * @private - */ + __playing = false; + /** + * keeps playing interval id + * @private + */ - __playingInterval = 0; - /** - * keeps play back rate - * @private - */ + __playingInterval = 0; + /** + * keeps play back rate + * @private + */ - _playBackRate = 1000; - /** - * keeps ended state of playing pdf - * @private - */ + _playBackRate = 1000; + /** + * keeps ended state of playing pdf + * @private + */ - _ended = false; - /** - * keep paused state - * @private - */ + _ended = false; + /** + * keep paused state + * @private + */ - _paused = false; - /** - * keeps pdf doc states - * @private - */ + _paused = false; + /** + * keeps pdf doc states + * @private + */ - __pdfViewState = { - pdf: null, - currentPage: 1, - zoom: 1 - }; + __pdfViewState = { + pdf: null, + currentPage: 1, + zoom: 1 + }; - constructor() { - super(); // Create a shadow root + constructor() { + super(); // Create a shadow root - this._shadow = this.attachShadow({ - mode: 'open' - }); // Create wrapper + this._shadow = this.attachShadow({ + mode: 'open' + }); // Create wrapper - this._wrapper = document.createElement('div'); + this._wrapper = document.createElement('div'); - this._wrapper.setAttribute('class', 'wrapper'); // Create some CSS to apply to the shadow dom + this._wrapper.setAttribute('class', 'wrapper'); // Create some CSS to apply to the shadow dom - this._style = document.createElement('style'); - this._style.textContent = '.wrapper {' + 'width: 100%;' + 'height: auto;' + 'display: block;' + '}' + '.wrapper canvas {' + 'width: 100%;' + 'height: auto;' + '}'; // attach to the shadow dom + this._style = document.createElement('style'); + this._style.textContent = '.wrapper {' + 'width: 100%;' + 'height: auto;' + 'display: block;' + '}' + '.wrapper canvas {' + 'width: 100%;' + 'height: auto;' + '}'; // attach to the shadow dom - this._shadow.appendChild(this._style); + this._shadow.appendChild(this._style); - this._shadow.appendChild(this._wrapper); - } - /** - * set observable attributes - * @return {string[]} - */ - - - static get observedAttributes() { - return ['src', 'type']; - } - /** - * Gets called on observable attributes changes - * @param name attribute name - * @param _ - * @param newVal new value - */ - - - attributeChangedCallback(name, _, newVal) { - switch (name) { - case 'src': - this.__buildPDFView(newVal); - - break; - - case 'type': - // do nothing - break; + this._shadow.appendChild(this._wrapper); } - } - /** - * init/update pdf tag - * @param _value - * @private - */ + /** + * set observable attributes + * @return {string[]} + */ - __buildPDFView(_value) { - this._canvas = document.createElement('canvas'); + static get observedAttributes() { + return ['src', 'type']; + } + /** + * Gets called on observable attributes changes + * @param name attribute name + * @param _ + * @param newVal new value + */ - this._wrapper.appendChild(this._canvas); - let longTask = pdfjs.getDocument(_value); - longTask.promise.then(pdf => { - this.__pdfViewState.pdf = pdf; - this._duration = this.__pdfViewState.pdf._pdfInfo.numPages; // initiate the pdf file viewer for the first time after loading + attributeChangedCallback(name, _, newVal) { + switch (name) { + case 'src': + this.__buildPDFView(newVal); - this.__render(1).then(_ => { - this.__pushEvent('loadedmetadata'); + break; + + case 'type': + // do nothing + break; + } + } + /** + * init/update pdf tag + * @param _value + * @private + */ + + + __buildPDFView(_value) { + this._canvas = document.createElement('canvas'); + + this._wrapper.appendChild(this._canvas); + + let longTask = pdfjs.getDocument(_value); + longTask.promise.then(pdf => { + this.__pdfViewState.pdf = pdf; + this._duration = this.__pdfViewState.pdf._pdfInfo.numPages; // initiate the pdf file viewer for the first time after loading + + this.__render(1).then(_ => { + this.__pushEvent('loadedmetadata'); + }); }); - }); - } - /** - * Render given page from pdf into the canvas container - * - * @param _page - * @private - */ + } + /** + * Render given page from pdf into the canvas container + * + * @param _page + * @private + */ - __render(_page) { - if (!this.__pdfViewState.pdf) return; - let p = _page || this.__pdfViewState.currentPage; - let self = this; - return this.__pdfViewState.pdf.getPage(p).then(page => { - let canvasContext = self._canvas.getContext('2d'); + __render(_page) { + if (!this.__pdfViewState.pdf) return; + let p = _page || this.__pdfViewState.currentPage; + let self = this; + return this.__pdfViewState.pdf.getPage(p).then(page => { + let canvasContext = self._canvas.getContext('2d'); - let viewport = page.getViewport({ - scale: self.__pdfViewState.zoom + let viewport = page.getViewport({ + scale: self.__pdfViewState.zoom + }); + self._canvas.width = viewport.width; + self._canvas.height = viewport.height; + page.render({ + canvasContext: canvasContext, + viewport: viewport + }); }); - self._canvas.width = viewport.width; - self._canvas.height = viewport.height; - page.render({ - canvasContext: canvasContext, - viewport: viewport + } + /** + * Creates event and dispatches it + * @param _name + */ + + + __pushEvent(_name) { + let event = document.createEvent("Event"); + event.initEvent(_name, true, true); + this.dispatchEvent(event); + } + /**************************** PUBLIC ATTRIBUTES & METHODES *************************************************/ + + /****************************** ATTRIBUTES **************************************/ + + /** + * set src + * @param _value + */ + + + set src(_value) { + Array.from(this._wrapper.children).forEach(_ch => { + _ch.remove(); }); - }); - } - /** - * Creates event and dispatches it - * @param _name - */ + + this.__buildPDFView(_value); + } + /** + * get src + * @return string returns comma separated sources + */ - __pushEvent(_name) { - let event = document.createEvent("Event"); - event.initEvent(_name, true, true); - this.dispatchEvent(event); - } - /**************************** PUBLIC ATTRIBUTES & METHODES *************************************************/ - - /****************************** ATTRIBUTES **************************************/ - - /** - * set src - * @param _value - */ + get src() { + return this.src; + } + /** + * currentTime + * @param _time + */ - set src(_value) { - Array.from(this._wrapper.children).forEach(_ch => { - _ch.remove(); - }); + set currentTime(_time) { + let time = Math.floor(_time < 1 ? 1 : _time); - this.__buildPDFView(_value); - } - /** - * get src - * @return string returns comma separated sources - */ + if (time > this._duration) { + // set ended state to true as it's the last page of pdf + this._ended = true; // don't go further because it's litterally the last page + + return; + } // set ended state to false as it's not the end of the pdf - get src() { - return this.src; - } - /** - * currentTime - * @param _time - */ + this._ended = false; + this._currentTime = time; + this.__pdfViewState.currentPage = time; + + this.__render(time); + } + /** + * get currentTime + * @return {number} + */ - set currentTime(_time) { - let time = Math.floor(_time < 1 ? 1 : _time); + get currentTime() { + return this._currentTime; + } + /** + * get duration time + */ - if (time > this._duration) { - // set ended state to true as it's the last page of pdf - this._ended = true; // don't go further because it's litterally the last page + get duration() { + return this._duration; + } + /** + * get paused attribute + */ + + + get paused() { + return this._paused; + } + /** + * set muted attribute + * @param _value + */ + + + set muted(_value) { return; - } // set ended state to false as it's not the end of the pdf + } + /** + * get muted attribute + */ - this._ended = false; - this._currentTime = time; - this.__pdfViewState.currentPage = time; + get muted() { + return true; + } - this.__render(time); - } - /** - * get currentTime - * @return {number} - */ + set ended(_value) { + this._ended = _value; + } + /** + * get ended attribute + */ - get currentTime() { - return this._currentTime; - } - /** - * get duration time - */ + get ended() { + return this._ended; + } + /** + * set playbackRate + * @param _value + */ - get duration() { - return this._duration; - } - /** - * get paused attribute - */ + set playbackRate(_value) { + this._playBackRate = _value * 1000; + } + /** + * get playbackRate + */ - get paused() { - return this._paused; - } - /** - * set muted attribute - * @param _value - */ + get playbackRate() { + return this._playBackRate; + } + /** + * set volume + */ - set muted(_value) { - return; - } - /** - * get muted attribute - */ + set volume(_value) { + return; + } + /** + * get volume + */ - get muted() { - return true; - } + get volume() { + return 0; + } + /************************************************* METHODES ******************************************/ - set ended(_value) { - this._ended = _value; - } - /** - * get ended attribute - */ + /** + * Play + */ - get ended() { - return this._ended; - } - /** - * set playbackRate - * @param _value - */ + play() { + this.__playing = true; + let self = this; + return new Promise(function (_resolve, _reject) { + self.__playingInterval = window.setInterval(_ => { + if (self.currentTime >= self._duration) { + self.ended = true; + self.pause(); + } + + self.currentTime += 1; + + self.__pushEvent('timeupdate'); + }, self._playBackRate); + + _resolve(); + }); + } + /** + * pause + */ - set playbackRate(_value) { - this._playBackRate = _value * 1000; - } - /** - * get playbackRate - */ + pause() { + this.__playing = false; + this._paused = true; + window.clearInterval(this.__playingInterval); + } + /** + * seek previous page + */ - get playbackRate() { - return this._playBackRate; - } - /** - * set volume - */ + prevPage() { + this.currentTime -= 1; + } + /** + * seek next page + */ - set volume(_value) { - return; - } - /** - * get volume - */ + nextPage() { + this.currentTime += 1; + } + + } // Define pdf-player element - get volume() { - return 0; - } - /************************************************* METHODES ******************************************/ - - /** - * Play - */ + customElements.define('pdf-player', pdf_player); +}); - play() { - this.__playing = true; - let self = this; - return new Promise(function (_resolve, _reject) { - self.__playingInterval = window.setInterval(_ => { - if (self.currentTime >= self._duration) { - self.ended = true; - self.pause(); - } - - self.currentTime += 1; - - self.__pushEvent('timeupdate'); - }, self._playBackRate); - - _resolve(); - }); - } - /** - * pause - */ - - - pause() { - this.__playing = false; - this._paused = true; - window.clearInterval(this.__playingInterval); - } - /** - * seek previous page - */ - - - prevPage() { - this.currentTime -= 1; - } - /** - * seek next page - */ - - - nextPage() { - this.currentTime += 1; - } - -} // Define pdf-player element - - -customElements.define('pdf-player', pdf_player); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index dfe5f764cd..89c7c15715 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,17 +9,23 @@ "version": "21.1.20210316", "license": "GPL-2.0", "devDependencies": { + "@bundled-es-modules/pdfjs-dist": "^2.5.207-rc1", "@types/jquery": "^3.5.5", "@types/jqueryui": "^1.12.14", "grunt": "^1.3.0", "grunt-contrib-cssmin": "^2.2.1", "grunt-newer": "^1.3.0", "grunt-terser": "^1.0.0", - "pdfjs-dist": "^2.13.216", "terser": "^4.8.0", "typescript": "^3.9.7" } }, + "node_modules/@bundled-es-modules/pdfjs-dist": { + "version": "2.5.207-rc1", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/pdfjs-dist/-/pdfjs-dist-2.5.207-rc1.tgz", + "integrity": "sha512-e/UVP1g6dwjQLnu4MPf/mlESCIvyr/KgpoMUyxGcv4evCIuJwKR/fcfhG3p1NYo+49gJsd0hL2yz9kzhkCZ32A==", + "dev": true + }, "node_modules/@types/jquery": { "version": "3.5.5", "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.5.tgz", @@ -1990,23 +1996,6 @@ "node": ">=0.10.0" } }, - "node_modules/pdfjs-dist": { - "version": "2.13.216", - "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-2.13.216.tgz", - "integrity": "sha512-qn/9a/3IHIKZarTK6ajeeFXBkG15Lg1Fx99PxU09PAU2i874X8mTcHJYyDJxu7WDfNhV6hM7bRQBZU384anoqQ==", - "dev": true, - "dependencies": { - "web-streams-polyfill": "^3.2.0" - }, - "peerDependencies": { - "worker-loader": "^3.0.8" - }, - "peerDependenciesMeta": { - "worker-loader": { - "optional": true - } - } - }, "node_modules/posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", @@ -2640,15 +2629,6 @@ "node": ">= 0.10" } }, - "node_modules/web-streams-polyfill": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.0.tgz", - "integrity": "sha512-EqPmREeOzttaLRm5HS7io98goBgZ7IVz79aDvqjD0kYXLtFZTc0T/U6wHTPKyIjb+MdN7DFIIX6hgdBEpWmfPA==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, "node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -2669,6 +2649,12 @@ } }, "dependencies": { + "@bundled-es-modules/pdfjs-dist": { + "version": "2.5.207-rc1", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/pdfjs-dist/-/pdfjs-dist-2.5.207-rc1.tgz", + "integrity": "sha512-e/UVP1g6dwjQLnu4MPf/mlESCIvyr/KgpoMUyxGcv4evCIuJwKR/fcfhG3p1NYo+49gJsd0hL2yz9kzhkCZ32A==", + "dev": true + }, "@types/jquery": { "version": "3.5.5", "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.5.tgz", @@ -4250,15 +4236,6 @@ "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", "dev": true }, - "pdfjs-dist": { - "version": "2.13.216", - "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-2.13.216.tgz", - "integrity": "sha512-qn/9a/3IHIKZarTK6ajeeFXBkG15Lg1Fx99PxU09PAU2i874X8mTcHJYyDJxu7WDfNhV6hM7bRQBZU384anoqQ==", - "dev": true, - "requires": { - "web-streams-polyfill": "^3.2.0" - } - }, "posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", @@ -4772,12 +4749,6 @@ "homedir-polyfill": "^1.0.1" } }, - "web-streams-polyfill": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.0.tgz", - "integrity": "sha512-EqPmREeOzttaLRm5HS7io98goBgZ7IVz79aDvqjD0kYXLtFZTc0T/U6wHTPKyIjb+MdN7DFIIX6hgdBEpWmfPA==", - "dev": true - }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", diff --git a/package.json b/package.json index 3bb3ae95b2..a72a571a1a 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "devDependencies": { "@types/jquery": "^3.5.5", "@types/jqueryui": "^1.12.14", - "pdfjs-dist": "^2.13.216", + "@bundled-es-modules/pdfjs-dist": "^2.5.207-rc1", "grunt": "^1.3.0", "grunt-contrib-cssmin": "^2.2.1", "grunt-newer": "^1.3.0",