diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 00000000..37cfad78
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,12 @@
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+indent_size = 4
+indent_style = space
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.md]
+trim_trailing_whitespace = false
diff --git a/DevLauncher.js b/DevLauncher.js
index 22d8f15c..c1e02a61 100644
--- a/DevLauncher.js
+++ b/DevLauncher.js
@@ -1,5 +1,8 @@
import {} from "./js/lib/lightning-web.js";
-import maf from "./js/src/maf.js";
+// MODIFICATION: removed this lib reference as it is making http calls to a metrological endpoint
+// that is not needed by applications and it also presents potential security concerns
+// additionall lib makes api call just by importing is which hamers testability
+// import maf from "./js/src/maf.js";
import ux from "./js/src/ux.js";
export default class DevLauncher {
@@ -28,7 +31,7 @@ export default class DevLauncher {
}, targetTime - currentTime);
};
}
-
+
launch(appType, lightningOptions, options = {}) {
this._appType = appType;
this._options = options;
@@ -68,6 +71,8 @@ export default class DevLauncher {
_addStyles() {
const style = document.createElement('style');
+ // MODIFICATION - removeds hardcoded black background.
+ // This should be specified by applications not framework
style.innerText = `
*,body{
margin:0;
@@ -77,10 +82,6 @@ export default class DevLauncher {
canvas {
position: absolute;
z-index: 2;
-}
-
-body {
- background: black;
}`;
document.head.appendChild(style);
}
@@ -100,7 +101,10 @@ body {
}
_getLightningOptions(customOptions = {}) {
- let options = {stage: {w: 1920, h: 1080, clearColor: 0x00000000, canvas2d: false}, debug: false, keys: this._getNavigationKeys()};
+ // MODIFICATION - dont need these default mappings - just need an empty array to make
+ // sure the web key event handler is registered properly - this should be changed to allow
+ // application to set the handlers if desired rather than hardcoding
+ let options = {stage: {w: 1920, h: 1080, clearColor: 0x00000000, canvas2d: false}, debug: false, keys: {}};
const config = options.stage;
if (ux.Ui.hasOption("720") || window.innerHeight === 720) {
@@ -122,30 +126,29 @@ body {
}
}
-
options = lng.tools.ObjMerger.merge(options, customOptions);
return options;
}
- _getNavigationKeys() {
- return {
- 8: "Back",
- 13: "Enter",
- 27: "Menu",
- 37: "Left",
- 38: "Up",
- 39: "Right",
- 40: "Down",
- 174: "ChannelDown",
- 175: "ChannelUp",
- 178: "Stop",
- 250: "PlayPause",
- 191: "Search", // Use "/" for keyboard
- 409: "Search"
- };
- }
-
+ // MODIFICATION - no longer used.
+ // _getNavigationKeys() {
+ // return {
+ // 8: "Back",
+ // 13: "Enter",
+ // 27: "Menu",
+ // 37: "Left",
+ // 38: "Up",
+ // 39: "Right",
+ // 40: "Down",
+ // 174: "ChannelDown",
+ // 175: "ChannelUp",
+ // 178: "Stop",
+ // 250: "PlayPause",
+ // 191: "Search", // Use "/" for keyboard
+ // // 409: "Search"
+ // };
+ // }
}
-DevLauncher._uxPath = "./node_modules/wpe-lightning-sdk/";
\ No newline at end of file
+DevLauncher._uxPath = "./node_modules/wpe-lightning-sdk/";
diff --git a/dist/spark/DevLauncher.mjs b/dist/spark/DevLauncher.mjs
index 1e9319d0..d6408844 100644
--- a/dist/spark/DevLauncher.mjs
+++ b/dist/spark/DevLauncher.mjs
@@ -1,11 +1,17 @@
import ux from "./src/ux.mjs";
import lng from 'wpe-lightning-spark';
import fetch from "node-fetch";
+// MODIFICATION - per direction from spark team - this script dependency is not needed
+// import keyboard from "./src/keyboard.mjs";
export default class DevLauncher {
- constructor() {
- }
+ // MODIFICATION - per spark team keyboard is not needed by spark runtime
+ // constructor() {
+ // keyboard((event) => {
+ // this._handleKey(event);
+ // });
+ // }
launch(appType, lightningOptions, options = {}) {
this._appType = appType;
@@ -14,11 +20,29 @@ export default class DevLauncher {
}
_handleKey(event) {
- this._ui._receiveKeydown(event);
+ this._ui._receiveKeydown(
+ // MODIFICATION: normalizes spark key event to the same structure
+ // as web keyboard event so that we can have "consistent" key handling code
+ // across platforms
+ this._normalizeKeyEvent(event));
+ }
+
+ // MODIFICATION: normalize key event to the same structure as web event
+ // so that we can have consistent key handling across platforms - this is
+ // as simple implementation for example purposes
+ _normalizeKeyEvent(keyEvent) {
+ const f = keyEvent.flags;
+ return {
+ keyCode: keyEvent.keyCode,
+ altKey: f === 48 || f === 56,
+ ctrlKey: f === 16 || f === 48 || f === 24 || f === 56,
+ shiftKey: f === 8 || f === 136 || f === 24 || f === 56,
+ };
}
_start(lightningOptions = {}) {
- this._openFirewall();
+ // MODIFICATION - remove call to metro rest endpoint.
+ // this._openFirewall();
this._lightningOptions = this._getLightningOptions(lightningOptions);
return this._startApp();
}
@@ -30,55 +54,55 @@ export default class DevLauncher {
this._ui.startApp(this._appType);
}
- _loadInspector() {
- if (this._options.useInspector) {
- /* Attach the inspector to create a fake DOM that shows where lightning elements can be found. */
- return this.loadScript(DevLauncher._uxPath + "../wpe-lightning/devtools/lightning-inspect.js");
- } else {
- return Promise.resolve();
- }
- }
+ // MODIFICATION - remove this code as inspector requires browser to work
+ // _loadInspector() {
+ // if (this._options.useInspector) {
+ // /* Attach the inspector to create a fake DOM that shows where lightning elements can be found. */
+ // return this.loadScript(DevLauncher._uxPath + "../wpe-lightning/devtools/lightning-inspect.js");
+ // } else {
+ // return Promise.resolve();
+ // }
+ // }
- _openFirewall() {
- // Fetch app store to ensure that proxy/image servers firewall is opened.
- //fetch(`http://widgets.metrological.com/${encodeURIComponent(ux.Ui.getOption('operator') || 'metrological')}/nl/test`).then(() => {});
- }
+ // MODIFICATION - no longer used
+ // _openFirewall() {
+ // Fetch app store to ensure that proxy/image servers firewall is opened.
+ // fetch(`http://widgets.metrological.com/${encodeURIComponent(ux.Ui.getOption('operator') || 'metrological')}/nl/test`).then(() => {});
+ // }
_getLightningOptions(customOptions = {}) {
- let options = {stage: {w: 1920, h: 1080}, debug: false, keys: this._getNavigationKeys()};
-
- const config = options.stage;
- if (customOptions.h === 720) {
- config['w'] = 1280;
- config['h'] = 720;
- config['precision'] = 0.6666666667;
- } else {
- config['w'] = 1920;
- config['h'] = 1080;
-
- config.useImageWorker = true;
- }
-
- options = lng.tools.ObjMerger.merge(options, customOptions);
-
- return options;
- }
-
- _getNavigationKeys() {
- return {
- 8: "Back",
- 13: "Enter",
- 27: "Menu",
- 37: "Left",
- 38: "Up",
- 39: "Right",
- 40: "Down",
- 174: "ChannelDown",
- 175: "ChannelUp",
- 178: "Stop",
- 250: "PlayPause",
- 191: "Search", // Use "/" for keyboard
- 409: "Search"
+ // MODIFICATION - this file is spark aware - per spark team
+ // the resolution will always be 1280x720 - if not this should be externalized
+ // so applications can set accordingly
+ let options = {
+ stage: {
+ w: 1280, h: 720,
+ precision: 0.6666666667,
+ },
+ debug: false,
+ // MODIFICATION - dont need these mappings, commenting out the property
+ // disables the confusing "no key handler registered" console message
+ // keys: this._getNavigationKeys(),
};
+ return lng.tools.ObjMerger.merge(options, customOptions);
}
+
+ // MODIFICATION - no longer referenced
+ // _getNavigationKeys() {
+ // return {
+ // 8: "Back",
+ // 13: "Enter",
+ // 27: "Menu",
+ // 37: "Left",
+ // 38: "Up",
+ // 39: "Right",
+ // 40: "Down",
+ // 174: "ChannelDown",
+ // 175: "ChannelUp",
+ // 178: "Stop",
+ // 250: "PlayPause",
+ // 191: "Search", // Use "/" for keyboard
+ // 409: "Search"
+ // };
+ // }
}
diff --git a/dist/web/index.html b/dist/web/index.html
index 6a7835e9..cb0ac0ad 100644
--- a/dist/web/index.html
+++ b/dist/web/index.html
@@ -1,9 +1,12 @@
+
+
+
Lightning App
@@ -17,10 +20,6 @@
position: absolute;
z-index: 2;
}
-
- body {
- background: black;
- }
diff --git a/dist/web/js/init.js b/dist/web/js/init.js
index 0565b7b8..b571f68d 100644
--- a/dist/web/js/init.js
+++ b/dist/web/js/init.js
@@ -18,22 +18,23 @@ function startApp() {
};
}
- var navigationKeys = {
- 8: "Back",
- 13: "Enter",
- 27: "Back",
- 10009: "Back",
- 37: "Left",
- 38: "Up",
- 39: "Right",
- 40: "Down",
- 174: "ChannelDown",
- 175: "ChannelUp",
- 178: "Stop",
- 250: "PlayPause",
- 191: "Search", // Use "/" for keyboard
- 409: "Search"
- };
+ // MODIFICATION - no longer used.
+ // var navigationKeys = {
+ // 8: "Back",
+ // 13: "Enter",
+ // 27: "Back",
+ // 10009: "Back",
+ // 37: "Left",
+ // 38: "Up",
+ // 39: "Right",
+ // 40: "Down",
+ // 174: "ChannelDown",
+ // 175: "ChannelUp",
+ // 178: "Stop",
+ // 250: "PlayPause",
+ // 191: "Search", // Use "/" for keyboard
+ // 409: "Search"
+ // };
const memoryPressure = parseInt(ux.Ui.getOption('memoryPressure')) || 16e6;
console.log('GPU memory pressure: ' + memoryPressure);
@@ -43,10 +44,14 @@ function startApp() {
w: 1920,
h: 1080,
clearColor: ux.Ui.getOption('transparentBg') === "0" ? 0xFF000000 : 0x00000000,
- defaultFontFace: 'RobotoRegular',
+ // MODIFICATION - default font face should be specified by applications
+ // defaultFontFace: 'RobotoRegular',
memoryPressure: memoryPressure,
canvas2d: ux.Ui.hasOption('c2d')
- }, debug: false, keys: navigationKeys
+ // MODIFICATION - dont need these default mappings - just need an empty array to make
+ // sure the web key event handler is registered properly - this should be changed to allow
+ // application to set the handlers if desired rather than hardcoding
+ }, debug: false, keys: {}
};
const config = options.stage;
@@ -109,10 +114,10 @@ function loadScript(src) {
});
}
-
+// MODIFICATION - removing call to metrological cause its a potentiual security issue
// Fetch app store to ensure that proxy/image servers firewall is opened.
-fetch('http://widgets.metrological.com/metrological/nl/test').then(function(){
-});
+// fetch('http://widgets.metrological.com/metrological/nl/test').then(function(){
+// });
const supportsEs6 = isSupportingES6();
const folder = supportsEs6 ? "src" : "src.es5";
@@ -134,4 +139,4 @@ loadPolyfill.then(function() {
console.error(e);
}).then(function() {
startApp();
-});
\ No newline at end of file
+});
diff --git a/js/src/Ui.js b/js/src/Ui.js
index daaab80a..92a1fd98 100644
--- a/js/src/Ui.js
+++ b/js/src/Ui.js
@@ -1,18 +1,28 @@
-import Mediaplayer from "./Mediaplayer.js";
-import NoopMediaplayer from "./NoopMediaplayer.js";
+// MODIFICATION - not all applications need the media player.
+// application should include this for themselves instead of hardcoded
+// dependency in the framwework.
+// import Mediaplayer from "./Mediaplayer.js";
+// import NoopMediaplayer from "./NoopMediaplayer.js";
import ScaledImageTexture from "./ScaledImageTexture.js";
export default class Ui extends lng.Application {
constructor(options) {
- options.defaultFontFace = options.defaultFontFace || "RobotoRegular";
+ // MODIFICATION - removed reference to hardcoded Roboto font face
+ // application should be required to define it or it should fall back
+ // on system default
+ //
+ // RobotoRegular was being served from metrological endpoints which may
+ // present some security concerns for consuming applications
+ options.defaultFontFace = options.defaultFontFace;
super(options);
this._options = options;
}
static _template() {
return {
- Mediaplayer: {type: lng.Utils.isWeb ? Mediaplayer : NoopMediaplayer, textureMode: Ui.hasOption('texture')},
+ // MODIFICATION - removed reference to media player.
+ // Mediaplayer: {type: lng.Utils.isWeb ? Mediaplayer : NoopMediaplayer, textureMode: Ui.hasOption('texture')},
AppWrapper: {}
};
}
@@ -25,12 +35,14 @@ export default class Ui extends lng.Application {
return !Ui.hasOption("noImageServer");
}
- get mediaplayer() {
- return this.tag("Mediaplayer");
- }
+ // MODIFICATION - removed reference to media player.
+ // get mediaplayer() {
+ // return this.tag("Mediaplayer");
+ // }
_active() {
- this.tag('Mediaplayer').skipRenderToTexture = this._options.skipRenderToTexture;
+ // MODIFICATION - removed reference to media player.
+ // this.tag('Mediaplayer').skipRenderToTexture = this._options.skipRenderToTexture;
}
startApp(appClass) {
@@ -40,11 +52,19 @@ export default class Ui extends lng.Application {
stopApp() {
}
- _handleBack() {
- if (lng.Utils.isWeb) {
- window.close();
- }
- }
+ // MODIFICATION - window close doesnt work in all environemtns and
+ // can throw an unhandled error
+ //
+ // Also using _handleBack subtly requires clients of this class to register a back handler
+ // correctly which is not documented
+ //
+ // Additionally in our case the keycode that signifies
+ // application exit is context specific and may not map to keyCode 8 as hardcoded by framework
+ // _handleBack() {
+ // if (lng.Utils.isWeb) {
+ // window.close();
+ // }
+ // }
static loadFonts(fonts) {
if (lng.Utils.isNode) {
@@ -64,10 +84,13 @@ export default class Ui extends lng.Application {
}
static getFonts() {
+ // MODIFICATION - prevent loading of unneeded fonts
+ // need a way to let application's specify the fonts to use if specified at this level
+
return [
- {family: 'RobotoRegular', url: Ui.getPath('fonts/roboto-regular.ttf'), descriptors: {}},
- {family: 'Material-Icons', url: Ui.getPath('fonts/Material-Icons.ttf'), descriptors: {}}
- ]
+ // {family: 'RobotoRegular', url: Ui.getPath('fonts/roboto-regular.ttf'), descriptors: {}},
+ // {family: 'Material-Icons', url: Ui.getPath('fonts/Material-Icons.ttf'), descriptors: {}}
+ ];
}
static _states() {
@@ -121,12 +144,13 @@ export default class Ui extends lng.Application {
_setFocusSettings(settings) {
settings.clearColor = this.stage.getOption('clearColor');
- settings.mediaplayer = {
- consumer: null,
- stream: null,
- hide: false,
- videoPos: [0, 0, 1920, 1080]
- };
+ // MODIFICATION - removed reference to media player
+ // settings.mediaplayer = {
+ // consumer: null,
+ // stream: null,
+ // hide: false,
+ // videoPos: [0, 0, 1920, 1080]
+ // };
}
_handleFocusSettings(settings) {
@@ -135,13 +159,16 @@ export default class Ui extends lng.Application {
this.stage.setClearColor(settings.clearColor);
}
- if (this.tag("Mediaplayer").attached) {
- this.tag("Mediaplayer").updateSettings(settings.mediaplayer);
- }
+ // MODIFICATION - removed reference to media player
+ // if (this.tag("Mediaplayer").attached) {
+ // this.tag("Mediaplayer").updateSettings(settings.mediaplayer);
+ // }
}
static getProxyUrl(url, opts = {}) {
- return this._getCdnProtocol() + "://cdn.metrological.com/proxy" + this.getQueryString(url, opts);
+ throw new Error("DONT USE");
+ // MODIFICATION - removing call out to a metrological cdn - security concerns
+ //return this._getCdnProtocol() + "://cdn.metrological.com/proxy" + this.getQueryString(url, opts);
}
static getImage(url, opts = {}) {
@@ -153,12 +180,15 @@ export default class Ui extends lng.Application {
}
static getQrUrl(url, opts = {}) {
- return this._getCdnProtocol() + "://cdn.metrological.com/qr" + this.getQueryString(url, opts, "q");
+ throw new Error("DONT USE");
+ // MODIFICATION - removing call out to a metrological cdn - security concerns
+ //return this._getCdnProtocol() + "://cdn.metrological.com/qr" + this.getQueryString(url, opts, "q");
}
- static _getCdnProtocol() {
- return lng.Utils.isWeb && location.protocol === "https:" ? "https" : "http";
- }
+ // MODIFICATION - unused code, no longer needed
+ // static _getCdnProtocol() {
+ // return lng.Utils.isWeb && location.protocol === "https:" ? "https" : "http";
+ // }
static hasOption(name) {
if (lng.Utils.isNode) {
@@ -176,15 +206,16 @@ export default class Ui extends lng.Application {
return new URL(document.location.href).searchParams.get(name);
}
- static getQueryString(url, opts, key = "url") {
- let str = `?operator=${encodeURIComponent(this.getOption('operator') || 'metrological')}`;
- const keys = Object.keys(opts);
- keys.forEach(key => {
- str += "&" + encodeURIComponent(key) + "=" + encodeURIComponent("" + opts[key]);
- });
- str += `&${key}=${encodeURIComponent(url)}`;
- return str;
- }
+ // MODIFICATION - unused code, no longer needed
+ // static getQueryString(url, opts, key = "url") {
+ // let str = `?operator=${encodeURIComponent(this.getOption('operator') || 'metrological')}`;
+ // const keys = Object.keys(opts);
+ // keys.forEach(key => {
+ // str += "&" + encodeURIComponent(key) + "=" + encodeURIComponent("" + opts[key]);
+ // });
+ // str += `&${key}=${encodeURIComponent(url)}`;
+ // return str;
+ // }
}