diff --git a/build-scripts/gulp/app.js b/build-scripts/gulp/app.js index 0536b14a30..37aad5fe34 100644 --- a/build-scripts/gulp/app.js +++ b/build-scripts/gulp/app.js @@ -20,7 +20,7 @@ gulp.task( "gen-service-worker-dev", "gen-icons", "gen-pages-dev", - "gen-index-html-dev", + "gen-index-app-dev", "build-translations" ), "copy-static", @@ -44,7 +44,7 @@ gulp.task( ), gulp.parallel( "gen-pages-prod", - "gen-index-html-prod", + "gen-index-app-prod", "gen-service-worker-prod" ) ) diff --git a/build-scripts/gulp/demo.js b/build-scripts/gulp/demo.js index cbe23e326c..b2d40e17ae 100644 --- a/build-scripts/gulp/demo.js +++ b/build-scripts/gulp/demo.js @@ -16,7 +16,12 @@ gulp.task( process.env.NODE_ENV = "development"; }, "clean-demo", - gulp.parallel("gen-icons", "gen-icons-demo", "build-translations"), + gulp.parallel( + "gen-icons", + "gen-icons-demo", + "gen-index-demo-dev", + "build-translations" + ), "copy-static-demo", "webpack-dev-server-demo" ) @@ -31,6 +36,7 @@ gulp.task( "clean-demo", gulp.parallel("gen-icons", "gen-icons-demo", "build-translations"), "copy-static-demo", - "webpack-prod-demo" + "webpack-prod-demo", + "gen-index-demo-prod" ) ); diff --git a/build-scripts/gulp/entry-html.js b/build-scripts/gulp/entry-html.js index 235a7336d5..eb26093925 100644 --- a/build-scripts/gulp/entry-html.js +++ b/build-scripts/gulp/entry-html.js @@ -11,13 +11,19 @@ const config = require("../paths.js"); const templatePath = (tpl) => path.resolve(config.polymer_dir, "src/html/", `${tpl}.html.template`); +const demoTemplatePath = (tpl) => + path.resolve(config.demo_dir, "src/html/", `${tpl}.html.template`); + const readFile = (pth) => fs.readFileSync(pth).toString(); -const renderTemplate = (pth, data = {}) => { - const compiled = template(readFile(templatePath(pth))); +const renderTemplate = (pth, data = {}, pathFunc = templatePath) => { + const compiled = template(readFile(pathFunc(pth))); return compiled({ ...data, renderTemplate }); }; +const renderDemoTemplate = (pth, data = {}) => + renderTemplate(pth, data, demoTemplatePath); + const minifyHtml = (content) => minify(content, { collapseWhitespace: true, @@ -66,7 +72,7 @@ gulp.task("gen-pages-prod", (done) => { done(); }); -gulp.task("gen-index-html-dev", (done) => { +gulp.task("gen-index-app-dev", (done) => { // In dev mode we don't mangle names, so we hardcode urls. That way we can // run webpack as last in watch mode, which blocks output. const content = renderTemplate("index", { @@ -86,7 +92,7 @@ gulp.task("gen-index-html-dev", (done) => { done(); }); -gulp.task("gen-index-html-prod", (done) => { +gulp.task("gen-index-app-prod", (done) => { const latestManifest = require(path.resolve(config.output, "manifest.json")); const es5Manifest = require(path.resolve(config.output_es5, "manifest.json")); const content = renderTemplate("index", { @@ -106,3 +112,52 @@ gulp.task("gen-index-html-prod", (done) => { fs.outputFileSync(path.resolve(config.root, "index.html"), minified); done(); }); + +gulp.task("gen-index-demo-dev", (done) => { + // In dev mode we don't mangle names, so we hardcode urls. That way we can + // run webpack as last in watch mode, which blocks output. + const content = renderDemoTemplate("index", { + latestDemoJS: "/frontend_latest/main.js", + + es5Compatibility: "/frontend_es5/compatibility.js", + es5DemoJS: "/frontend_es5/main.js", + }); + + fs.outputFileSync(path.resolve(config.demo_root, "index.html"), content); + done(); +}); + +gulp.task("gen-index-demo-dev", (done) => { + // In dev mode we don't mangle names, so we hardcode urls. That way we can + // run webpack as last in watch mode, which blocks output. + const content = renderDemoTemplate("index", { + latestDemoJS: "/frontend_latest/main.js", + + es5Compatibility: "/frontend_es5/compatibility.js", + es5DemoJS: "/frontend_es5/main.js", + }); + + fs.outputFileSync(path.resolve(config.demo_root, "index.html"), content); + done(); +}); + +gulp.task("gen-index-demo-prod", (done) => { + const latestManifest = require(path.resolve( + config.demo_output, + "manifest.json" + )); + const es5Manifest = require(path.resolve( + config.demo_output_es5, + "manifest.json" + )); + const content = renderDemoTemplate("index", { + latestDemoJS: latestManifest["main.js"], + + es5Compatibility: es5Manifest["compatibility.js"], + es5DemoJS: es5Manifest["main.js"], + }); + const minified = minifyHtml(content).replace(/#THEMEC/g, "{{ theme_color }}"); + + fs.outputFileSync(path.resolve(config.demo_root, "index.html"), minified); + done(); +}); diff --git a/build-scripts/paths.js b/build-scripts/paths.js index f078c80da9..356a3fa38a 100644 --- a/build-scripts/paths.js +++ b/build-scripts/paths.js @@ -13,5 +13,5 @@ module.exports = { demo_root: path.resolve(__dirname, "../demo/dist"), demo_static: path.resolve(__dirname, "../demo/dist/static"), demo_output: path.resolve(__dirname, "../demo/dist/frontend_latest"), - demo_output_es5: path.resolve(__dirname, "../demo/frontend_es5"), + demo_output_es5: path.resolve(__dirname, "../demo/dist/frontend_es5"), }; diff --git a/build-scripts/webpack.js b/build-scripts/webpack.js index a29e6ec85a..7ff8a260dd 100644 --- a/build-scripts/webpack.js +++ b/build-scripts/webpack.js @@ -20,6 +20,12 @@ version = version[0]; const genMode = (isProdBuild) => (isProdBuild ? "production" : "development"); const genDevTool = (isProdBuild) => isProdBuild ? "cheap-source-map" : "inline-cheap-module-source-map"; +const genFilename = (isProdBuild, dontHash = new Set()) => ({ chunk }) => { + if (!isProdBuild || dontHash.has(chunk.name)) { + return `${chunk.name}.js`; + } + return `${chunk.name}.${chunk.hash.substr(0, 8)}.js`; +}; const genChunkFilename = (isProdBuild, isStatsBuild) => isProdBuild && !isStatsBuild ? "chunk.[chunkhash].js" : "[name].chunk.js"; @@ -158,14 +164,7 @@ const createAppConfig = ({ isProdBuild, latestBuild, isStatsBuild }) => { }), ].filter(Boolean), output: { - filename: ({ chunk }) => { - const dontHash = new Set([ - // Files who'se names should not be hashed. - // We currently have none. - ]); - if (!isProdBuild || dontHash.has(chunk.name)) return `${chunk.name}.js`; - return `${chunk.name}.${chunk.hash.substr(0, 8)}.js`; - }, + filename: genFilename(isProdBuild), chunkFilename: genChunkFilename(isProdBuild, isStatsBuild), path: latestBuild ? paths.output : paths.output_es5, publicPath: latestBuild ? "/frontend_latest/" : "/frontend_es5/", @@ -187,6 +186,7 @@ const createDemoConfig = ({ isProdBuild, latestBuild, isStatsBuild }) => { }, optimization: optimization(latestBuild), plugins: [ + new ManifestPlugin(), new webpack.DefinePlugin({ __DEV__: !isProdBuild, __BUILD__: JSON.stringify(latestBuild ? "latest" : "es5"), @@ -201,7 +201,7 @@ const createDemoConfig = ({ isProdBuild, latestBuild, isStatsBuild }) => { ].filter(Boolean), resolve, output: { - filename: "[name].js", + filename: genFilename(isProdBuild), chunkFilename: genChunkFilename(isProdBuild, isStatsBuild), path: path.resolve( paths.demo_root, diff --git a/demo/script/gen-icons.js b/demo/script/gen-icons.js deleted file mode 100755 index b3c20a842a..0000000000 --- a/demo/script/gen-icons.js +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env node -const fs = require("fs"); -const { - findIcons, - generateIconset, - genMDIIcons, -} = require("../../build-scripts/gulp/gen-icons.js"); - -function genHademoIcons() { - const iconNames = findIcons("./src", "hademo"); - fs.writeFileSync("./hademo-icons.html", generateIconset("hademo", iconNames)); -} - -genMDIIcons(); -genHademoIcons(); diff --git a/demo/public/index.html b/demo/src/html/index.html.template similarity index 77% rename from demo/public/index.html rename to demo/src/html/index.html.template index 4878fe8d43..75d35675d0 100644 --- a/demo/public/index.html +++ b/demo/src/html/index.html.template @@ -95,43 +95,17 @@
- + <%= renderTemplate('_js_base') %> - + diff --git a/setup.py b/setup.py index 7e6c52420e..bb2dc9862d 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages setup( name="home-assistant-frontend", - version="20190509.0", + version="20190510.0", description="The Home Assistant frontend", url="https://github.com/home-assistant/home-assistant-polymer", author="The Home Assistant Authors", diff --git a/src/common/feature-detect/support-web-components.ts b/src/common/feature-detect/support-web-components.ts new file mode 100644 index 0000000000..607b3713ca --- /dev/null +++ b/src/common/feature-detect/support-web-components.ts @@ -0,0 +1,2 @@ +export const webComponentsSupported = + "customElements" in window && "content" in document.createElement("template"); diff --git a/src/entrypoints/custom-panel.ts b/src/entrypoints/custom-panel.ts index d6f0a33d74..9e14dc52c1 100644 --- a/src/entrypoints/custom-panel.ts +++ b/src/entrypoints/custom-panel.ts @@ -5,6 +5,7 @@ import { setCustomPanelProperties } from "../util/custom-panel/set-custom-panel- import { fireEvent } from "../common/dom/fire_event"; import { PolymerElement } from "@polymer/polymer"; import { CustomPanelInfo } from "../data/panel_custom"; +import { webComponentsSupported } from "../common/feature-detect/support-web-components"; declare global { interface Window { @@ -12,18 +13,13 @@ declare global { } } -const webComponentsSupported = - "customElements" in window && - "import" in document.createElement("link") && - "content" in document.createElement("template"); - let es5Loaded: Promise | undefined; window.loadES5Adapter = () => { if (!es5Loaded) { es5Loaded = Promise.all([ loadJS( - `${__STATIC_PATH__}/polyfills/custom-elements-es5-adapter.js` + `${__STATIC_PATH__}polyfills/custom-elements-es5-adapter.js` ).catch(), import(/* webpackChunkName: "compat" */ "./compatibility"), ]); @@ -50,7 +46,7 @@ function initialize(panel: CustomPanelInfo, properties: {}) { if (!webComponentsSupported) { start = start.then(() => - loadJS(`${__STATIC_PATH__}/polyfills/webcomponents-bundle.js`) + loadJS(`${__STATIC_PATH__}polyfills/webcomponents-bundle.js`) ); } diff --git a/translations/ca.json b/translations/ca.json index 49f6d5e4f8..3e13f40049 100644 --- a/translations/ca.json +++ b/translations/ca.json @@ -603,6 +603,12 @@ "device_unavailable": "dispositiu no disponible", "entity_unavailable": "entitat no disponible", "no_area": "Sense àrea" + }, + "config_flow": { + "external_step": { + "description": "Aquest pas requereix que visitis un lloc web extern per completar-lo.", + "open_site": "Vés al lloc web" + } } }, "zha": { diff --git a/translations/de.json b/translations/de.json index a418a81078..8a2a8e33c7 100644 --- a/translations/de.json +++ b/translations/de.json @@ -603,6 +603,12 @@ "device_unavailable": "Gerät nicht verfügbar", "entity_unavailable": "Entität nicht verfügbar", "no_area": "Kein Bereich" + }, + "config_flow": { + "external_step": { + "description": "Für diesen Schritt musst du eine externe Website besuchen, um den Vorgang abzuschließen.", + "open_site": "Website öffnen" + } } }, "zha": { @@ -855,6 +861,11 @@ "required_fields": "Fülle alle Pflichtfelder aus.", "password_not_match": "Passwörter stimmen nicht überein" } + }, + "integration": { + "intro": "Geräte und Dienste werden in Home Assistant als Integrationen dargestellt. Sie können jetzt oder später über die Konfigurationsseite eingerichtet werden.", + "more_integrations": "Mehr", + "finish": "Fertig" } }, "lovelace": { diff --git a/translations/it.json b/translations/it.json index 642837262e..8c71c84a8b 100644 --- a/translations/it.json +++ b/translations/it.json @@ -925,7 +925,8 @@ }, "sidebar": { "log_out": "Esci", - "developer_tools": "Strumenti per gli sviluppatori" + "developer_tools": "Strumenti per gli sviluppatori", + "external_app_configuration": "Configurazione dell'App" }, "common": { "loading": "Caricamento", diff --git a/translations/lb.json b/translations/lb.json index 0dbf1b7053..7119a3d743 100644 --- a/translations/lb.json +++ b/translations/lb.json @@ -603,6 +603,12 @@ "device_unavailable": "Apparat net erreechbar", "entity_unavailable": "Entitéit net erreechbar", "no_area": "Kee Beräich" + }, + "config_flow": { + "external_step": { + "description": "Fir dës Etapp ofzeschléisse muss dir eng externe Internetsäit besichen.", + "open_site": "Internetsäit opmaachen" + } } }, "zha": { diff --git a/translations/nb.json b/translations/nb.json index 7901bad924..8d34f34c0c 100644 --- a/translations/nb.json +++ b/translations/nb.json @@ -603,6 +603,12 @@ "device_unavailable": "enheten er utilgjengelig", "entity_unavailable": "oppføringen er utilgjengelig", "no_area": "Ingen område" + }, + "config_flow": { + "external_step": { + "description": "Dette trinnet krever at du besøker et eksternt nettsted som skal fylles ut.", + "open_site": "Åpne nettsted" + } } }, "zha": { @@ -855,6 +861,11 @@ "required_fields": "Fyll ut alle nødvendige felt", "password_not_match": "Passordene er ikke like" } + }, + "integration": { + "intro": "Enheter og tjenester er representert i Home Assistant som integrasjoner. Du kan sette dem opp nå, eller gjøre det senere fra konfigurasjonen skjermen.", + "more_integrations": "Mer", + "finish": "Fullfør" } }, "lovelace": { @@ -873,6 +884,8 @@ "hold": "Hold:", "tap": "Trykk:", "navigate_to": "Naviger til {location}", + "toggle": "Veksle {name}", + "call_service": "Kall tjeneste {navn}", "more_info": "Vis mer info: {name}" } }, @@ -931,7 +944,8 @@ }, "sidebar": { "log_out": "Logg ut", - "developer_tools": "Utviklerverktøy" + "developer_tools": "Utviklerverktøy", + "external_app_configuration": "Appkonfigurasjon" }, "common": { "loading": "Laster", diff --git a/translations/ru.json b/translations/ru.json index 3584cc6437..590b71840b 100644 --- a/translations/ru.json +++ b/translations/ru.json @@ -603,6 +603,12 @@ "device_unavailable": "устройство недоступно", "entity_unavailable": "объект недоступен", "no_area": "Не указано" + }, + "config_flow": { + "external_step": { + "description": "Для завершения этого шага требуется посетить внешний веб-сайт.", + "open_site": "Открыть веб-сайт" + } } }, "zha": { @@ -858,7 +864,7 @@ }, "integration": { "intro": "Устройства и сервисы представлены в Home Assistant как интеграции. Вы можете добавить их сейчас или сделать это позже в разделе настроек.", - "more_integrations": "Все интеграции", + "more_integrations": "Ещё", "finish": "Готово" } }, diff --git a/translations/zh-Hant.json b/translations/zh-Hant.json index 4d3761ee47..6dfc63d41a 100644 --- a/translations/zh-Hant.json +++ b/translations/zh-Hant.json @@ -603,6 +603,12 @@ "device_unavailable": "裝置不可用", "entity_unavailable": "物件不可用", "no_area": "無分區" + }, + "config_flow": { + "external_step": { + "description": "此步驟將需要開啟外部網站方能完成。", + "open_site": "開啟網站" + } } }, "zha": {