mirror of
				https://github.com/home-assistant/frontend.git
				synced 2025-10-30 22:19:55 +00:00 
			
		
		
		
	Compare commits
	
		
			2 Commits
		
	
	
		
			20230705.1
			...
			restructur
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | d60639f99d | ||
|   | 693b621dd5 | 
| @@ -1,39 +0,0 @@ | |||||||
| [modern] |  | ||||||
| # Support for dynamic import is the main litmus test for serving modern builds. |  | ||||||
| # Although officially a ES2020 feature, browsers implemented it early, so this |  | ||||||
| # enables all of ES2017 and some features in ES2018. |  | ||||||
| supports es6-module-dynamic-import |  | ||||||
|  |  | ||||||
| # Exclude Safari 11-12 because of a bug in tagged template literals |  | ||||||
| # https://bugs.webkit.org/show_bug.cgi?id=190756 |  | ||||||
| # Note: Dropping version 11 also enables several more ES2018 features |  | ||||||
| not Safari < 13 |  | ||||||
| not iOS < 13 |  | ||||||
|  |  | ||||||
| # Exclude KaiOS, QQ, and UC browsers due to lack of sufficient feature support data |  | ||||||
| # Babel ignores these automatically, but we need here for Webpack to output ESM with dynamic imports |  | ||||||
| not KaiOS > 0 |  | ||||||
| not QQAndroid > 0 |  | ||||||
| not UCAndroid > 0 |  | ||||||
|  |  | ||||||
| # Exclude unsupported browsers |  | ||||||
| not dead |  | ||||||
|  |  | ||||||
| [legacy] |  | ||||||
| # Legacy builds are served when modern requirements are not met and support browsers: |  | ||||||
| # - released in the last 7 years + current alpha/beta versionss |  | ||||||
| # - with global utilization above 0.05% |  | ||||||
| # The lattermost query ensures that support for popular old browsers is not dropped too early |  | ||||||
| # (e.g. IE 11, Android 4.4, or Samsung 4). |  | ||||||
| # |  | ||||||
| # In addition, legacy browsers must support some minimum features that cannot be polyfilled: |  | ||||||
| # - ES5 (strict mode) |  | ||||||
| # - web sockets to communicate with backend |  | ||||||
| # - inline SVG used widely in buttons, widgets, etc. |  | ||||||
| # - custom events used for most user interactions |  | ||||||
| # - CSS flexbox used in the majority of the layout |  | ||||||
| # Nearly all of these are redundant with the above rules. |  | ||||||
| # As of May 2023, only web sockets must be added to the query. |  | ||||||
| unreleased versions |  | ||||||
| last 7 years |  | ||||||
| > 0.05% and supports websockets |  | ||||||
| @@ -1,13 +1,20 @@ | |||||||
| { | { | ||||||
|   "name": "Home Assistant Frontend", |   "name": "Home Assistant Frontend", | ||||||
|   "build": { |   "image": "mcr.microsoft.com/devcontainers/python:0-3.10", | ||||||
|     "dockerfile": "Dockerfile", |  | ||||||
|     "context": ".." |  | ||||||
|   }, |  | ||||||
|   "appPort": "8124:8123", |   "appPort": "8124:8123", | ||||||
|   "postStartCommand": "script/bootstrap", |   "postCreateCommand": "script/bootstrap", | ||||||
|   "containerEnv": { |   "containerEnv": { | ||||||
|     "WORKSPACE_DIRECTORY": "${containerWorkspaceFolder}" |     "WORKSPACE_DIRECTORY": "${containerWorkspaceFolder}", | ||||||
|  |     "DEVCONTAINER": "true" | ||||||
|  |   }, | ||||||
|  |   "remoteUser": "vscode", | ||||||
|  |   "remoteEnv": { | ||||||
|  |     "PATH": "${containerEnv:PATH}:${containerWorkspaceFolder}/node_modules/.bin:/home/vscode/.local/bin" | ||||||
|  |   }, | ||||||
|  |   "features": { | ||||||
|  |     "ghcr.io/devcontainers/features/node:1": { | ||||||
|  |       "version": "16" | ||||||
|  |     } | ||||||
|   }, |   }, | ||||||
|   "customizations": { |   "customizations": { | ||||||
|     "vscode": { |     "vscode": { | ||||||
| @@ -1,7 +0,0 @@ | |||||||
| # See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.148.1/containers/python-3/.devcontainer/base.Dockerfile |  | ||||||
| FROM mcr.microsoft.com/vscode/devcontainers/python:0-3.11 |  | ||||||
|  |  | ||||||
| ENV \ |  | ||||||
|   DEBIAN_FRONTEND=noninteractive \ |  | ||||||
|   DEVCONTAINER=true \ |  | ||||||
|   PATH=$PATH:./node_modules/.bin |  | ||||||
| @@ -5,7 +5,6 @@ | |||||||
|     "plugin:@typescript-eslint/recommended", |     "plugin:@typescript-eslint/recommended", | ||||||
|     "plugin:wc/recommended", |     "plugin:wc/recommended", | ||||||
|     "plugin:lit/all", |     "plugin:lit/all", | ||||||
|     "plugin:lit-a11y/recommended", |  | ||||||
|     "prettier" |     "prettier" | ||||||
|   ], |   ], | ||||||
|   "parser": "@typescript-eslint/parser", |   "parser": "@typescript-eslint/parser", | ||||||
| @@ -20,7 +19,7 @@ | |||||||
|   "settings": { |   "settings": { | ||||||
|     "import/resolver": { |     "import/resolver": { | ||||||
|       "webpack": { |       "webpack": { | ||||||
|         "config": "./webpack.config.cjs" |         "config": "./webpack.config.js" | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
| @@ -66,10 +65,7 @@ | |||||||
|     "import/extensions": [ |     "import/extensions": [ | ||||||
|       "error", |       "error", | ||||||
|       "ignorePackages", |       "ignorePackages", | ||||||
|       { |       { "ts": "never", "js": "never" } | ||||||
|         "ts": "never", |  | ||||||
|         "js": "never" |  | ||||||
|       } |  | ||||||
|     ], |     ], | ||||||
|     "no-restricted-syntax": ["error", "LabeledStatement", "WithStatement"], |     "no-restricted-syntax": ["error", "LabeledStatement", "WithStatement"], | ||||||
|     "object-curly-newline": "off", |     "object-curly-newline": "off", | ||||||
| @@ -116,14 +112,7 @@ | |||||||
|     ], |     ], | ||||||
|     "unused-imports/no-unused-imports": "error", |     "unused-imports/no-unused-imports": "error", | ||||||
|     "lit/attribute-value-entities": "off", |     "lit/attribute-value-entities": "off", | ||||||
|     "lit/no-template-map": "off", |     "lit/no-template-map": "off" | ||||||
|     "lit/no-native-attributes": "warn", |  | ||||||
|     "lit/no-this-assign-in-render": "warn", |  | ||||||
|     "lit-a11y/click-events-have-key-events": ["off"], |  | ||||||
|     "lit-a11y/no-autofocus": "off", |  | ||||||
|     "lit-a11y/alt-text": "warn", |  | ||||||
|     "lit-a11y/anchor-is-valid": "warn", |  | ||||||
|     "lit-a11y/role-has-required-aria-attrs": "warn" |  | ||||||
|   }, |   }, | ||||||
|   "plugins": ["disable", "unused-imports"], |   "plugins": ["disable", "unused-imports"], | ||||||
|   "processor": "disable/disable" |   "processor": "disable/disable" | ||||||
|   | |||||||
							
								
								
									
										10
									
								
								.github/dependabot.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								.github/dependabot.yml
									
									
									
									
										vendored
									
									
								
							| @@ -6,3 +6,13 @@ updates: | |||||||
|       interval: weekly |       interval: weekly | ||||||
|       time: "06:00" |       time: "06:00" | ||||||
|     open-pull-requests-limit: 10 |     open-pull-requests-limit: 10 | ||||||
|  |   - package-ecosystem: "npm" | ||||||
|  |     directory: "/" | ||||||
|  |     schedule: | ||||||
|  |       interval: "daily" | ||||||
|  |       time: "06:00" | ||||||
|  |     open-pull-requests-limit: 5 | ||||||
|  |     ignore: | ||||||
|  |       # Ignore rollup and plugins until everything else is updated | ||||||
|  |       - dependency-name: "*rollup*" | ||||||
|  |       - dependency-name: "@rollup/*" | ||||||
|   | |||||||
							
								
								
									
										5
									
								
								.github/release-drafter.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.github/release-drafter.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,8 +1,3 @@ | |||||||
| categories: |  | ||||||
|   - title: 'Dependency updates' |  | ||||||
|     collapse-after: 3 |  | ||||||
|     labels: |  | ||||||
|       - 'dependencies' |  | ||||||
| template: | | template: | | ||||||
|   ## What's Changed |   ## What's Changed | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										23
									
								
								.github/workflows/cast_deployment.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										23
									
								
								.github/workflows/cast_deployment.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -9,6 +9,7 @@ on: | |||||||
|       - master |       - master | ||||||
|  |  | ||||||
| env: | env: | ||||||
|  |   NODE_VERSION: 16 | ||||||
|   NODE_OPTIONS: --max_old_space_size=6144 |   NODE_OPTIONS: --max_old_space_size=6144 | ||||||
|  |  | ||||||
| jobs: | jobs: | ||||||
| @@ -21,18 +22,20 @@ jobs: | |||||||
|       url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }} |       url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }} | ||||||
|     steps: |     steps: | ||||||
|       - name: Check out files from GitHub |       - name: Check out files from GitHub | ||||||
|         uses: actions/checkout@v3.5.3 |         uses: actions/checkout@v3.3.0 | ||||||
|         with: |         with: | ||||||
|           ref: dev |           ref: dev | ||||||
|  |  | ||||||
|       - name: Setup Node |       - name: Set up Node ${{ env.NODE_VERSION }} | ||||||
|         uses: actions/setup-node@v3.6.0 |         uses: actions/setup-node@v3.6.0 | ||||||
|         with: |         with: | ||||||
|           node-version-file: ".nvmrc" |           node-version: ${{ env.NODE_VERSION }} | ||||||
|           cache: yarn |           cache: yarn | ||||||
|  |  | ||||||
|       - name: Install dependencies |       - name: Install dependencies | ||||||
|         run: yarn install --immutable |         run: yarn install | ||||||
|  |         env: | ||||||
|  |           CI: true | ||||||
|  |  | ||||||
|       - name: Build Cast |       - name: Build Cast | ||||||
|         run: ./node_modules/.bin/gulp build-cast |         run: ./node_modules/.bin/gulp build-cast | ||||||
| @@ -57,18 +60,20 @@ jobs: | |||||||
|       url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }} |       url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }} | ||||||
|     steps: |     steps: | ||||||
|       - name: Check out files from GitHub |       - name: Check out files from GitHub | ||||||
|         uses: actions/checkout@v3.5.3 |         uses: actions/checkout@v3.3.0 | ||||||
|         with: |         with: | ||||||
|           ref: master |           ref: master | ||||||
|  |  | ||||||
|       - name: Setup Node |       - name: Set up Node ${{ env.NODE_VERSION }} | ||||||
|         uses: actions/setup-node@v3.6.0 |         uses: actions/setup-node@v3.6.0 | ||||||
|         with: |         with: | ||||||
|           node-version-file: ".nvmrc" |           node-version: ${{ env.NODE_VERSION }} | ||||||
|           cache: yarn |           cache: yarn | ||||||
|  |  | ||||||
|       - name: Install dependencies |       - name: Install dependencies | ||||||
|         run: yarn install --immutable |         run: yarn install | ||||||
|  |         env: | ||||||
|  |           CI: true | ||||||
|  |  | ||||||
|       - name: Build Cast |       - name: Build Cast | ||||||
|         run: ./node_modules/.bin/gulp build-cast |         run: ./node_modules/.bin/gulp build-cast | ||||||
| @@ -82,4 +87,4 @@ jobs: | |||||||
|           args: deploy --dir=cast/dist --prod |           args: deploy --dir=cast/dist --prod | ||||||
|         env: |         env: | ||||||
|           NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} |           NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} | ||||||
|           NETLIFY_SITE_ID: ${{ secrets.NETLIFY_CAST_SITE_ID }} |           NETLIFY_SITE_ID: ${{ secrets.NETLIFY_CAST_SITE_ID }} | ||||||
							
								
								
									
										59
									
								
								.github/workflows/ci.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										59
									
								
								.github/workflows/ci.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -11,86 +11,87 @@ on: | |||||||
|       - master |       - master | ||||||
|  |  | ||||||
| env: | env: | ||||||
|  |   NODE_VERSION: 16 | ||||||
|   NODE_OPTIONS: --max_old_space_size=6144 |   NODE_OPTIONS: --max_old_space_size=6144 | ||||||
|   GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |   GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||||||
|  |  | ||||||
| concurrency: |  | ||||||
|   group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} |  | ||||||
|   cancel-in-progress: true |  | ||||||
|  |  | ||||||
| jobs: | jobs: | ||||||
|   lint: |   lint: | ||||||
|     name: Lint and check format |  | ||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
|     steps: |     steps: | ||||||
|       - name: Check out files from GitHub |       - name: Check out files from GitHub | ||||||
|         uses: actions/checkout@v3.5.3 |         uses: actions/checkout@v3.3.0 | ||||||
|       - name: Setup Node |       - name: Set up Node ${{ env.NODE_VERSION }} | ||||||
|         uses: actions/setup-node@v3.6.0 |         uses: actions/setup-node@v3.6.0 | ||||||
|         with: |         with: | ||||||
|           node-version-file: ".nvmrc" |           node-version: ${{ env.NODE_VERSION }} | ||||||
|           cache: yarn |           cache: yarn | ||||||
|       - name: Install dependencies |       - name: Install dependencies | ||||||
|         run: yarn install --immutable |         run: yarn install | ||||||
|       - name: Check for duplicate dependencies |         env: | ||||||
|         run: yarn dedupe --check |           CI: true | ||||||
|       - name: Build resources |       - name: Build resources | ||||||
|         run: ./node_modules/.bin/gulp gen-icons-json build-translations build-locale-data gather-gallery-pages |         run: ./node_modules/.bin/gulp gen-icons-json build-translations build-locale-data gather-gallery-pages | ||||||
|       - name: Run eslint |       - name: Run eslint | ||||||
|         run: yarn run lint:eslint --quiet |         run: yarn run lint:eslint | ||||||
|       - name: Run tsc |       - name: Run tsc | ||||||
|         run: yarn run lint:types |         run: yarn run lint:types | ||||||
|       - name: Run prettier |       - name: Run prettier | ||||||
|         run: yarn run lint:prettier |         run: yarn run lint:prettier | ||||||
|  |       - name: Check for duplicate dependencies | ||||||
|  |         run: yarn dedupe --check | ||||||
|   test: |   test: | ||||||
|     name: Run tests |  | ||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
|     steps: |     steps: | ||||||
|       - name: Check out files from GitHub |       - name: Check out files from GitHub | ||||||
|         uses: actions/checkout@v3.5.3 |         uses: actions/checkout@v3.3.0 | ||||||
|       - name: Setup Node |       - name: Set up Node ${{ env.NODE_VERSION }} | ||||||
|         uses: actions/setup-node@v3.6.0 |         uses: actions/setup-node@v3.6.0 | ||||||
|         with: |         with: | ||||||
|           node-version-file: ".nvmrc" |           node-version: ${{ env.NODE_VERSION }} | ||||||
|           cache: yarn |           cache: yarn | ||||||
|       - name: Install dependencies |       - name: Install dependencies | ||||||
|         run: yarn install --immutable |         run: yarn install | ||||||
|  |         env: | ||||||
|  |           CI: true | ||||||
|       - name: Build resources |       - name: Build resources | ||||||
|         run: ./node_modules/.bin/gulp build-translations build-locale-data |         run: ./node_modules/.bin/gulp build-translations build-locale-data | ||||||
|       - name: Run Tests |       - name: Run Tests | ||||||
|         run: yarn run test |         run: yarn run test | ||||||
|   build: |   build: | ||||||
|     name: Build frontend |  | ||||||
|     needs: [lint, test] |  | ||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
|  |     needs: [lint, test] | ||||||
|     steps: |     steps: | ||||||
|       - name: Check out files from GitHub |       - name: Check out files from GitHub | ||||||
|         uses: actions/checkout@v3.5.3 |         uses: actions/checkout@v3.3.0 | ||||||
|       - name: Setup Node |       - name: Set up Node ${{ env.NODE_VERSION }} | ||||||
|         uses: actions/setup-node@v3.6.0 |         uses: actions/setup-node@v3.6.0 | ||||||
|         with: |         with: | ||||||
|           node-version-file: ".nvmrc" |           node-version: ${{ env.NODE_VERSION }} | ||||||
|           cache: yarn |           cache: yarn | ||||||
|       - name: Install dependencies |       - name: Install dependencies | ||||||
|         run: yarn install --immutable |         run: yarn install | ||||||
|  |         env: | ||||||
|  |           CI: true | ||||||
|       - name: Build Application |       - name: Build Application | ||||||
|         run: ./node_modules/.bin/gulp build-app |         run: ./node_modules/.bin/gulp build-app | ||||||
|         env: |         env: | ||||||
|           IS_TEST: "true" |           IS_TEST: "true" | ||||||
|   supervisor: |   supervisor: | ||||||
|     name: Build supervisor |  | ||||||
|     needs: [lint, test] |  | ||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
|  |     needs: [lint, test] | ||||||
|     steps: |     steps: | ||||||
|       - name: Check out files from GitHub |       - name: Check out files from GitHub | ||||||
|         uses: actions/checkout@v3.5.3 |         uses: actions/checkout@v3.3.0 | ||||||
|       - name: Setup Node |       - name: Set up Node ${{ env.NODE_VERSION }} | ||||||
|         uses: actions/setup-node@v3.6.0 |         uses: actions/setup-node@v3.6.0 | ||||||
|         with: |         with: | ||||||
|           node-version-file: ".nvmrc" |           node-version: ${{ env.NODE_VERSION }} | ||||||
|           cache: yarn |           cache: yarn | ||||||
|       - name: Install dependencies |       - name: Install dependencies | ||||||
|         run: yarn install --immutable |         run: yarn install | ||||||
|  |         env: | ||||||
|  |           CI: true | ||||||
|       - name: Build Application |       - name: Build Application | ||||||
|         run: ./node_modules/.bin/gulp build-hassio |         run: ./node_modules/.bin/gulp build-hassio | ||||||
|         env: |         env: | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								.github/workflows/codeql-analysis.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/codeql-analysis.yml
									
									
									
									
										vendored
									
									
								
							| @@ -23,7 +23,7 @@ jobs: | |||||||
|  |  | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout repository |     - name: Checkout repository | ||||||
|       uses: actions/checkout@v3.5.3 |       uses: actions/checkout@v3.3.0 | ||||||
|       with: |       with: | ||||||
|         # We must fetch at least the immediate parents so that if this is |         # We must fetch at least the immediate parents so that if this is | ||||||
|         # a pull request then we can checkout the head. |         # a pull request then we can checkout the head. | ||||||
|   | |||||||
							
								
								
									
										27
									
								
								.github/workflows/demo_deployment.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										27
									
								
								.github/workflows/demo_deployment.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -10,30 +10,33 @@ on: | |||||||
|       - master |       - master | ||||||
|  |  | ||||||
| env: | env: | ||||||
|  |   NODE_VERSION: 16 | ||||||
|   NODE_OPTIONS: --max_old_space_size=6144 |   NODE_OPTIONS: --max_old_space_size=6144 | ||||||
|  |  | ||||||
| jobs: | jobs: | ||||||
|   deploy_dev: |   deploy_dev: | ||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
|     name: Demo Development |     name: Demo Development | ||||||
|     if: github.event_name != 'push' || github.ref_name != 'master' |     if: github.event_name != 'push' || github.ref != 'master' | ||||||
|     environment: |     environment: | ||||||
|       name: Demo Development |       name: Demo Development | ||||||
|       url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }} |       url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }} | ||||||
|     steps: |     steps: | ||||||
|       - name: Check out files from GitHub |       - name: Check out files from GitHub | ||||||
|         uses: actions/checkout@v3.5.3 |         uses: actions/checkout@v3.3.0 | ||||||
|         with: |         with: | ||||||
|           ref: dev |           ref: dev | ||||||
|  |  | ||||||
|       - name: Setup Node |       - name: Set up Node ${{ env.NODE_VERSION }} | ||||||
|         uses: actions/setup-node@v3.6.0 |         uses: actions/setup-node@v3.6.0 | ||||||
|         with: |         with: | ||||||
|           node-version-file: ".nvmrc" |           node-version: ${{ env.NODE_VERSION }} | ||||||
|           cache: yarn |           cache: yarn | ||||||
|  |  | ||||||
|       - name: Install dependencies |       - name: Install dependencies | ||||||
|         run: yarn install --immutable |         run: yarn install | ||||||
|  |         env: | ||||||
|  |           CI: true | ||||||
|  |  | ||||||
|       - name: Build Demo |       - name: Build Demo | ||||||
|         run: ./node_modules/.bin/gulp build-demo |         run: ./node_modules/.bin/gulp build-demo | ||||||
| @@ -52,24 +55,26 @@ jobs: | |||||||
|   deploy_master: |   deploy_master: | ||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
|     name: Demo Production |     name: Demo Production | ||||||
|     if: github.event_name == 'push' && github.ref_name == 'master' |     if: github.event_name == 'push' && github.ref == 'master' | ||||||
|     environment: |     environment: | ||||||
|       name: Demo Production |       name: Demo Production | ||||||
|       url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }} |       url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }} | ||||||
|     steps: |     steps: | ||||||
|       - name: Check out files from GitHub |       - name: Check out files from GitHub | ||||||
|         uses: actions/checkout@v3.5.3 |         uses: actions/checkout@v3.3.0 | ||||||
|         with: |         with: | ||||||
|           ref: master |           ref: master | ||||||
|  |  | ||||||
|       - name: Setup Node |       - name: Set up Node ${{ env.NODE_VERSION }} | ||||||
|         uses: actions/setup-node@v3.6.0 |         uses: actions/setup-node@v3.6.0 | ||||||
|         with: |         with: | ||||||
|           node-version-file: ".nvmrc" |           node-version: ${{ env.NODE_VERSION }} | ||||||
|           cache: yarn |           cache: yarn | ||||||
|  |  | ||||||
|       - name: Install dependencies |       - name: Install dependencies | ||||||
|         run: yarn install --immutable |         run: yarn install | ||||||
|  |         env: | ||||||
|  |           CI: true | ||||||
|  |  | ||||||
|       - name: Build Demo |       - name: Build Demo | ||||||
|         run: ./node_modules/.bin/gulp build-demo |         run: ./node_modules/.bin/gulp build-demo | ||||||
| @@ -83,4 +88,4 @@ jobs: | |||||||
|           args: deploy --dir=demo/dist --prod |           args: deploy --dir=demo/dist --prod | ||||||
|         env: |         env: | ||||||
|           NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} |           NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} | ||||||
|           NETLIFY_SITE_ID: ${{ secrets.NETLIFY_DEMO_SITE_ID }} |           NETLIFY_SITE_ID: ${{ secrets.NETLIFY_DEMO_SITE_ID }} | ||||||
							
								
								
									
										11
									
								
								.github/workflows/design_deployment.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								.github/workflows/design_deployment.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -6,6 +6,7 @@ on: | |||||||
|     - cron: "0 0 * * *" |     - cron: "0 0 * * *" | ||||||
|  |  | ||||||
| env: | env: | ||||||
|  |   NODE_VERSION: 16 | ||||||
|   NODE_OPTIONS: --max_old_space_size=6144 |   NODE_OPTIONS: --max_old_space_size=6144 | ||||||
|  |  | ||||||
| jobs: | jobs: | ||||||
| @@ -16,16 +17,18 @@ jobs: | |||||||
|       url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }} |       url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }} | ||||||
|     steps: |     steps: | ||||||
|       - name: Check out files from GitHub |       - name: Check out files from GitHub | ||||||
|         uses: actions/checkout@v3.5.3 |         uses: actions/checkout@v3.3.0 | ||||||
|  |  | ||||||
|       - name: Setup Node |       - name: Set up Node ${{ env.NODE_VERSION }} | ||||||
|         uses: actions/setup-node@v3.6.0 |         uses: actions/setup-node@v3.6.0 | ||||||
|         with: |         with: | ||||||
|           node-version-file: ".nvmrc" |           node-version: ${{ env.NODE_VERSION }} | ||||||
|           cache: yarn |           cache: yarn | ||||||
|  |  | ||||||
|       - name: Install dependencies |       - name: Install dependencies | ||||||
|         run: yarn install --immutable |         run: yarn install | ||||||
|  |         env: | ||||||
|  |           CI: true | ||||||
|  |  | ||||||
|       - name: Build Gallery |       - name: Build Gallery | ||||||
|         run: ./node_modules/.bin/gulp build-gallery |         run: ./node_modules/.bin/gulp build-gallery | ||||||
|   | |||||||
							
								
								
									
										11
									
								
								.github/workflows/design_preview.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								.github/workflows/design_preview.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -11,6 +11,7 @@ on: | |||||||
|       - dev |       - dev | ||||||
|  |  | ||||||
| env: | env: | ||||||
|  |   NODE_VERSION: 16 | ||||||
|   NODE_OPTIONS: --max_old_space_size=6144 |   NODE_OPTIONS: --max_old_space_size=6144 | ||||||
|  |  | ||||||
| jobs: | jobs: | ||||||
| @@ -21,16 +22,18 @@ jobs: | |||||||
|     if: github.repository == 'home-assistant/frontend' && contains(github.event.pull_request.labels.*.name, 'needs design preview') |     if: github.repository == 'home-assistant/frontend' && contains(github.event.pull_request.labels.*.name, 'needs design preview') | ||||||
|     steps: |     steps: | ||||||
|       - name: Check out files from GitHub |       - name: Check out files from GitHub | ||||||
|         uses: actions/checkout@v3.5.3 |         uses: actions/checkout@v3.3.0 | ||||||
|  |  | ||||||
|       - name: Setup Node |       - name: Set up Node ${{ env.NODE_VERSION }} | ||||||
|         uses: actions/setup-node@v3.6.0 |         uses: actions/setup-node@v3.6.0 | ||||||
|         with: |         with: | ||||||
|           node-version-file: ".nvmrc" |           node-version: ${{ env.NODE_VERSION }} | ||||||
|           cache: yarn |           cache: yarn | ||||||
|  |  | ||||||
|       - name: Install dependencies |       - name: Install dependencies | ||||||
|         run: yarn install --immutable |         run: yarn install | ||||||
|  |         env: | ||||||
|  |           CI: true | ||||||
|  |  | ||||||
|       - name: Build Gallery |       - name: Build Gallery | ||||||
|         run: ./node_modules/.bin/gulp build-gallery |         run: ./node_modules/.bin/gulp build-gallery | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								.github/workflows/lock.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/lock.yml
									
									
									
									
										vendored
									
									
								
							| @@ -9,7 +9,7 @@ jobs: | |||||||
|   lock: |   lock: | ||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
|     steps: |     steps: | ||||||
|       - uses: dessant/lock-threads@v4.0.1 |       - uses: dessant/lock-threads@v4.0.0 | ||||||
|         with: |         with: | ||||||
|           github-token: ${{ github.token }} |           github-token: ${{ github.token }} | ||||||
|           issue-lock-inactive-days: "30" |           issue-lock-inactive-days: "30" | ||||||
|   | |||||||
							
								
								
									
										11
									
								
								.github/workflows/nightly.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								.github/workflows/nightly.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -6,7 +6,8 @@ on: | |||||||
|     - cron: "0 1 * * *" |     - cron: "0 1 * * *" | ||||||
|  |  | ||||||
| env: | env: | ||||||
|   PYTHON_VERSION: "3.11" |   PYTHON_VERSION: "3.10" | ||||||
|  |   NODE_VERSION: 16 | ||||||
|   NODE_OPTIONS: --max_old_space_size=6144 |   NODE_OPTIONS: --max_old_space_size=6144 | ||||||
|  |  | ||||||
| permissions: | permissions: | ||||||
| @@ -20,17 +21,17 @@ jobs: | |||||||
|       contents: write |       contents: write | ||||||
|     steps: |     steps: | ||||||
|       - name: Checkout the repository |       - name: Checkout the repository | ||||||
|         uses: actions/checkout@v3.5.3 |         uses: actions/checkout@v3.3.0 | ||||||
|  |  | ||||||
|       - name: Set up Python ${{ env.PYTHON_VERSION }} |       - name: Set up Python ${{ env.PYTHON_VERSION }} | ||||||
|         uses: actions/setup-python@v4 |         uses: actions/setup-python@v4 | ||||||
|         with: |         with: | ||||||
|           python-version: ${{ env.PYTHON_VERSION }} |           python-version: ${{ env.PYTHON_VERSION }} | ||||||
|  |  | ||||||
|       - name: Setup Node |       - name: Set up Node ${{ env.NODE_VERSION }} | ||||||
|         uses: actions/setup-node@v3.6.0 |         uses: actions/setup-node@v3.6.0 | ||||||
|         with: |         with: | ||||||
|           node-version-file: ".nvmrc" |           node-version: ${{ env.NODE_VERSION }} | ||||||
|           cache: yarn |           cache: yarn | ||||||
|  |  | ||||||
|       - name: Install dependencies |       - name: Install dependencies | ||||||
| @@ -42,7 +43,7 @@ jobs: | |||||||
|           LOKALISE_TOKEN: ${{ secrets.LOKALISE_TOKEN }} |           LOKALISE_TOKEN: ${{ secrets.LOKALISE_TOKEN }} | ||||||
|  |  | ||||||
|       - name: Bump version |       - name: Bump version | ||||||
|         run: script/version_bump.cjs nightly |         run: script/version_bump.js nightly | ||||||
|  |  | ||||||
|       - name: Build nightly Python wheels |       - name: Build nightly Python wheels | ||||||
|         run: | |         run: | | ||||||
|   | |||||||
							
								
								
									
										9
									
								
								.github/workflows/release-drafter.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								.github/workflows/release-drafter.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -5,17 +5,8 @@ on: | |||||||
|     branches: |     branches: | ||||||
|       - dev |       - dev | ||||||
|  |  | ||||||
| permissions: |  | ||||||
|   contents: read |  | ||||||
|  |  | ||||||
| jobs: | jobs: | ||||||
|   update_release_draft: |   update_release_draft: | ||||||
|     permissions: |  | ||||||
|       # write permission for contents is required to create a github release |  | ||||||
|       contents: write |  | ||||||
|       # write permission for pull-requests is required for autolabeler |  | ||||||
|       # otherwise, read permission is required at least |  | ||||||
|       pull-requests: read |  | ||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
|     steps: |     steps: | ||||||
|       - uses: release-drafter/release-drafter@v5 |       - uses: release-drafter/release-drafter@v5 | ||||||
|   | |||||||
							
								
								
									
										13
									
								
								.github/workflows/release.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										13
									
								
								.github/workflows/release.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -6,7 +6,8 @@ on: | |||||||
|       - published |       - published | ||||||
|  |  | ||||||
| env: | env: | ||||||
|   PYTHON_VERSION: "3.11" |   PYTHON_VERSION: "3.10" | ||||||
|  |   NODE_VERSION: 16 | ||||||
|   NODE_OPTIONS: --max_old_space_size=6144 |   NODE_OPTIONS: --max_old_space_size=6144 | ||||||
|  |  | ||||||
| # Set default workflow permissions | # Set default workflow permissions | ||||||
| @@ -23,7 +24,7 @@ jobs: | |||||||
|       contents: write # Required to upload release assets |       contents: write # Required to upload release assets | ||||||
|     steps: |     steps: | ||||||
|       - name: Checkout the repository |       - name: Checkout the repository | ||||||
|         uses: actions/checkout@v3.5.3 |         uses: actions/checkout@v3.3.0 | ||||||
|  |  | ||||||
|       - name: Verify version |       - name: Verify version | ||||||
|         uses: home-assistant/actions/helpers/verify-version@master |         uses: home-assistant/actions/helpers/verify-version@master | ||||||
| @@ -33,10 +34,10 @@ jobs: | |||||||
|         with: |         with: | ||||||
|           python-version: ${{ env.PYTHON_VERSION }} |           python-version: ${{ env.PYTHON_VERSION }} | ||||||
|  |  | ||||||
|       - name: Setup Node |       - name: Set up Node ${{ env.NODE_VERSION }} | ||||||
|         uses: actions/setup-node@v3.6.0 |         uses: actions/setup-node@v3.6.0 | ||||||
|         with: |         with: | ||||||
|           node-version-file: ".nvmrc" |           node-version: ${{ env.NODE_VERSION }} | ||||||
|           cache: yarn |           cache: yarn | ||||||
|  |  | ||||||
|       - name: Install dependencies |       - name: Install dependencies | ||||||
| @@ -74,9 +75,9 @@ jobs: | |||||||
|           echo "home-assistant-frontend==$version" > ./requirements.txt |           echo "home-assistant-frontend==$version" > ./requirements.txt | ||||||
|  |  | ||||||
|       - name: Build wheels |       - name: Build wheels | ||||||
|         uses: home-assistant/wheels@2023.04.0 |         uses: home-assistant/wheels@2022.10.1 | ||||||
|         with: |         with: | ||||||
|           abi: cp311 |           abi: cp310 | ||||||
|           tag: musllinux_1_2 |           tag: musllinux_1_2 | ||||||
|           arch: amd64 |           arch: amd64 | ||||||
|           wheels-key: ${{ secrets.WHEELS_KEY }} |           wheels-key: ${{ secrets.WHEELS_KEY }} | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								.github/workflows/stale.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/stale.yml
									
									
									
									
										vendored
									
									
								
							| @@ -10,7 +10,7 @@ jobs: | |||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
|     steps: |     steps: | ||||||
|       - name: 90 days stale policy |       - name: 90 days stale policy | ||||||
|         uses: actions/stale@v8.0.0 |         uses: actions/stale@v7.0.0 | ||||||
|         with: |         with: | ||||||
|           repo-token: ${{ secrets.GITHUB_TOKEN }} |           repo-token: ${{ secrets.GITHUB_TOKEN }} | ||||||
|           days-before-stale: 90 |           days-before-stale: 90 | ||||||
|   | |||||||
							
								
								
									
										6
									
								
								.github/workflows/translations.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.github/workflows/translations.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -7,15 +7,19 @@ on: | |||||||
|     paths: |     paths: | ||||||
|       - src/translations/en.json |       - src/translations/en.json | ||||||
|  |  | ||||||
|  | env: | ||||||
|  |   NODE_VERSION: 16 | ||||||
|  |  | ||||||
| jobs: | jobs: | ||||||
|   upload: |   upload: | ||||||
|     name: Upload |     name: Upload | ||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
|     steps: |     steps: | ||||||
|       - name: Checkout the repository |       - name: Checkout the repository | ||||||
|         uses: actions/checkout@v3.5.3 |         uses: actions/checkout@v3.3.0 | ||||||
|  |  | ||||||
|       - name: Upload Translations |       - name: Upload Translations | ||||||
|         run: | |         run: | | ||||||
|           export LOKALISE_TOKEN="${{ secrets.LOKALISE_TOKEN }}" |           export LOKALISE_TOKEN="${{ secrets.LOKALISE_TOKEN }}" | ||||||
|  |  | ||||||
|           ./script/translations_upload_base |           ./script/translations_upload_base | ||||||
|   | |||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -1,39 +0,0 @@ | |||||||
| diff --git a/modular/sortable.complete.esm.js b/modular/sortable.complete.esm.js |  | ||||||
| index 02e9f2d6bebeb430fe6e7c1cc3f9c3c9df051f14..bb8268b0844a1faa4108cc92c0be2a3dbaf23f83 100644 |  | ||||||
| --- a/modular/sortable.complete.esm.js |  | ||||||
| +++ b/modular/sortable.complete.esm.js |  | ||||||
| @@ -1657,7 +1657,7 @@ Sortable.prototype = |  | ||||||
|            target = parent; // store last element |  | ||||||
|          } |  | ||||||
|          /* jshint boss:true */ |  | ||||||
| -        while (parent = parent.parentNode); |  | ||||||
| +        while (parent = parent.parentNode || parent.getRootNode().host); |  | ||||||
|        } |  | ||||||
|   |  | ||||||
|        _unhideGhostForTarget(); |  | ||||||
| diff --git a/modular/sortable.core.esm.js b/modular/sortable.core.esm.js |  | ||||||
| index b04c8b4634f7c6b4ef1aadbb48afe6564306dea9..39a107163c8c336ebd669b5ea8a936af87e1c1e7 100644 |  | ||||||
| --- a/modular/sortable.core.esm.js |  | ||||||
| +++ b/modular/sortable.core.esm.js |  | ||||||
| @@ -1657,7 +1657,7 @@ Sortable.prototype = |  | ||||||
|            target = parent; // store last element |  | ||||||
|          } |  | ||||||
|          /* jshint boss:true */ |  | ||||||
| -        while (parent = parent.parentNode); |  | ||||||
| +        while (parent = parent.parentNode || parent.getRootNode().host); |  | ||||||
|        } |  | ||||||
|   |  | ||||||
|        _unhideGhostForTarget(); |  | ||||||
| diff --git a/modular/sortable.esm.js b/modular/sortable.esm.js |  | ||||||
| index 6ec7ed1bb557e21c2578200161e989c65d23150b..0a05475a22904472fac6c13f524c674da76584b0 100644 |  | ||||||
| --- a/modular/sortable.esm.js |  | ||||||
| +++ b/modular/sortable.esm.js |  | ||||||
| @@ -1657,7 +1657,7 @@ Sortable.prototype = |  | ||||||
|            target = parent; // store last element |  | ||||||
|          } |  | ||||||
|          /* jshint boss:true */ |  | ||||||
| -        while (parent = parent.parentNode); |  | ||||||
| +        while (parent = parent.parentNode || parent.getRootNode().host); |  | ||||||
|        } |  | ||||||
|   |  | ||||||
|        _unhideGhostForTarget(); |  | ||||||
							
								
								
									
										823
									
								
								.yarn/releases/yarn-3.3.1.cjs
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										823
									
								
								.yarn/releases/yarn-3.3.1.cjs
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										874
									
								
								.yarn/releases/yarn-3.6.1.cjs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										874
									
								
								.yarn/releases/yarn-3.6.1.cjs
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -1,5 +1,3 @@ | |||||||
| defaultSemverRangePrefix: "" |  | ||||||
|  |  | ||||||
| nodeLinker: node-modules | nodeLinker: node-modules | ||||||
|  |  | ||||||
| plugins: | plugins: | ||||||
| @@ -8,4 +6,4 @@ plugins: | |||||||
|   - path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs |   - path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs | ||||||
|     spec: "@yarnpkg/plugin-interactive-tools" |     spec: "@yarnpkg/plugin-interactive-tools" | ||||||
|  |  | ||||||
| yarnPath: .yarn/releases/yarn-3.6.1.cjs | yarnPath: .yarn/releases/yarn-3.3.1.cjs | ||||||
|   | |||||||
| @@ -1,15 +1,6 @@ | |||||||
| const path = require("path"); | const path = require("path"); | ||||||
| const env = require("./env.cjs"); | const env = require("./env.js"); | ||||||
| const paths = require("./paths.cjs"); | const paths = require("./paths.js"); | ||||||
| 
 |  | ||||||
| // GitHub base URL to use for production source maps
 |  | ||||||
| // Nightly builds use the commit SHA, otherwise assumes there is a tag that matches the version
 |  | ||||||
| module.exports.sourceMapURL = () => { |  | ||||||
|   const ref = env.version().endsWith("dev") |  | ||||||
|     ? process.env.GITHUB_SHA || "dev" |  | ||||||
|     : env.version(); |  | ||||||
|   return `https://raw.githubusercontent.com/home-assistant/frontend/${ref}`; |  | ||||||
| }; |  | ||||||
| 
 | 
 | ||||||
| // Files from NPM Packages that should not be imported
 | // Files from NPM Packages that should not be imported
 | ||||||
| // eslint-disable-next-line unused-imports/no-unused-vars
 | // eslint-disable-next-line unused-imports/no-unused-vars
 | ||||||
| @@ -62,94 +53,60 @@ module.exports.definedVars = ({ isProdBuild, latestBuild, defineOverlay }) => ({ | |||||||
|   ...defineOverlay, |   ...defineOverlay, | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| module.exports.htmlMinifierOptions = { | module.exports.terserOptions = (latestBuild) => ({ | ||||||
|   caseSensitive: true, |  | ||||||
|   collapseWhitespace: true, |  | ||||||
|   conservativeCollapse: true, |  | ||||||
|   decodeEntities: true, |  | ||||||
|   removeComments: true, |  | ||||||
|   removeRedundantAttributes: true, |  | ||||||
|   minifyCSS: { |  | ||||||
|     compatibility: "*,-properties.zeroUnits", |  | ||||||
|   }, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| module.exports.terserOptions = ({ latestBuild, isTestBuild }) => ({ |  | ||||||
|   safari10: !latestBuild, |   safari10: !latestBuild, | ||||||
|   ecma: latestBuild ? 2015 : 5, |   ecma: latestBuild ? undefined : 5, | ||||||
|   module: latestBuild, |   output: { comments: false }, | ||||||
|   format: { comments: false }, |  | ||||||
|   sourceMap: !isTestBuild, |  | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| module.exports.babelOptions = ({ latestBuild, isProdBuild, isTestBuild }) => ({ | module.exports.babelOptions = ({ latestBuild }) => ({ | ||||||
|   babelrc: false, |   babelrc: false, | ||||||
|   compact: false, |   compact: false, | ||||||
|   assumptions: { |  | ||||||
|     privateFieldsAsProperties: true, |  | ||||||
|     setPublicClassFields: true, |  | ||||||
|     setSpreadProperties: true, |  | ||||||
|   }, |  | ||||||
|   browserslistEnv: latestBuild ? "modern" : "legacy", |  | ||||||
|   // Must be unambiguous because some dependencies are CommonJS only
 |  | ||||||
|   sourceType: "unambiguous", |  | ||||||
|   presets: [ |   presets: [ | ||||||
|     [ |     !latestBuild && [ | ||||||
|       "@babel/preset-env", |       "@babel/preset-env", | ||||||
|       { |       { | ||||||
|         useBuiltIns: latestBuild ? false : "entry", |         useBuiltIns: "entry", | ||||||
|         corejs: latestBuild ? false : { version: "3.31", proposals: true }, |         corejs: "3.15", | ||||||
|         bugfixes: true, |         bugfixes: true, | ||||||
|       }, |       }, | ||||||
|     ], |     ], | ||||||
|     "@babel/preset-typescript", |     "@babel/preset-typescript", | ||||||
|   ], |   ].filter(Boolean), | ||||||
|   plugins: [ |   plugins: [ | ||||||
|     [ |     [ | ||||||
|       path.resolve( |       path.resolve( | ||||||
|         paths.polymer_dir, |         paths.polymer_dir, | ||||||
|         "build-scripts/babel-plugins/inline-constants-plugin.cjs" |         "build-scripts/babel-plugins/inline-constants-plugin.js" | ||||||
|       ), |       ), | ||||||
|       { |       { | ||||||
|         modules: ["@mdi/js"], |         modules: ["@mdi/js"], | ||||||
|         ignoreModuleNotFound: true, |         ignoreModuleNotFound: true, | ||||||
|       }, |       }, | ||||||
|     ], |     ], | ||||||
|     // Minify template literals for production
 |     // Part of ES2018. Converts {...a, b: 2} to Object.assign({}, a, {b: 2})
 | ||||||
|     isProdBuild && [ |     !latestBuild && [ | ||||||
|       "template-html-minifier", |       "@babel/plugin-proposal-object-rest-spread", | ||||||
|       { |       { loose: true, useBuiltIns: true }, | ||||||
|         modules: { |  | ||||||
|           lit: [ |  | ||||||
|             "html", |  | ||||||
|             { name: "svg", encapsulation: "svg" }, |  | ||||||
|             { name: "css", encapsulation: "style" }, |  | ||||||
|           ], |  | ||||||
|           "@polymer/polymer/lib/utils/html-tag": ["html"], |  | ||||||
|         }, |  | ||||||
|         strictCSS: true, |  | ||||||
|         htmlMinifier: module.exports.htmlMinifierOptions, |  | ||||||
|         failOnError: true, // we can turn this off in case of false positives
 |  | ||||||
|       }, |  | ||||||
|     ], |     ], | ||||||
|     // Import helpers and regenerator from runtime package
 |     // Only support the syntax, Webpack will handle it.
 | ||||||
|     [ |     "@babel/plugin-syntax-import-meta", | ||||||
|       "@babel/plugin-transform-runtime", |     "@babel/plugin-syntax-dynamic-import", | ||||||
|       { version: require("../package.json").dependencies["@babel/runtime"] }, |     "@babel/plugin-syntax-top-level-await", | ||||||
|     ], |     "@babel/plugin-proposal-optional-chaining", | ||||||
|     // Support  some proposals still in TC39 process
 |     "@babel/plugin-proposal-nullish-coalescing-operator", | ||||||
|     ["@babel/plugin-proposal-decorators", { decoratorsBeforeExport: true }], |     ["@babel/plugin-proposal-decorators", { decoratorsBeforeExport: true }], | ||||||
|  |     ["@babel/plugin-proposal-private-methods", { loose: true }], | ||||||
|  |     ["@babel/plugin-proposal-private-property-in-object", { loose: true }], | ||||||
|  |     ["@babel/plugin-proposal-class-properties", { loose: true }], | ||||||
|   ].filter(Boolean), |   ].filter(Boolean), | ||||||
|   exclude: [ |   exclude: [ | ||||||
|     // \\ for Windows, / for Mac OS and Linux
 |     // \\ for Windows, / for Mac OS and Linux
 | ||||||
|     /node_modules[\\/]core-js/, |     /node_modules[\\/]core-js/, | ||||||
|     /node_modules[\\/]webpack[\\/]buildin/, |     /node_modules[\\/]webpack[\\/]buildin/, | ||||||
|   ], |   ], | ||||||
|   sourceMaps: !isTestBuild, |  | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| const nameSuffix = (latestBuild) => (latestBuild ? "-latest" : "-es5"); |  | ||||||
| 
 |  | ||||||
| const outputPath = (outputRoot, latestBuild) => | const outputPath = (outputRoot, latestBuild) => | ||||||
|   path.resolve(outputRoot, latestBuild ? "frontend_latest" : "frontend_es5"); |   path.resolve(outputRoot, latestBuild ? "frontend_latest" : "frontend_es5"); | ||||||
| 
 | 
 | ||||||
| @@ -157,32 +114,29 @@ const publicPath = (latestBuild, root = "") => | |||||||
|   latestBuild ? `${root}/frontend_latest/` : `${root}/frontend_es5/`; |   latestBuild ? `${root}/frontend_latest/` : `${root}/frontend_es5/`; | ||||||
| 
 | 
 | ||||||
| /* | /* | ||||||
|   BundleConfig { | BundleConfig { | ||||||
|     // Object with entrypoints that need to be bundled
 |   // Object with entrypoints that need to be bundled
 | ||||||
|     entry: { [name: string]: pathToFile }, |   entry: { [name: string]: pathToFile }, | ||||||
|     // Folder where bundled files need to be written
 |   // Folder where bundled files need to be written
 | ||||||
|     outputPath: string, |   outputPath: string, | ||||||
|     // absolute url-path where bundled files can be found
 |   // absolute url-path where bundled files can be found
 | ||||||
|     publicPath: string, |   publicPath: string, | ||||||
|     // extra definitions that we need to replace in source
 |   // extra definitions that we need to replace in source
 | ||||||
|     defineOverlay: {[name: string]: value }, |   defineOverlay: {[name: string]: value }, | ||||||
|     // if this is a production build
 |   // if this is a production build
 | ||||||
|     isProdBuild: boolean, |   isProdBuild: boolean, | ||||||
|     // If we're targeting latest browsers
 |   // If we're targeting latest browsers
 | ||||||
|     latestBuild: boolean, |   latestBuild: boolean, | ||||||
|     // If we're doing a stats build (create nice chunk names)
 |   // If we're doing a stats build (create nice chunk names)
 | ||||||
|     isStatsBuild: boolean, |   isStatsBuild: boolean, | ||||||
|     // If it's just a test build in CI, skip time on source map generation
 |   // Names of entrypoints that should not be hashed
 | ||||||
|     isTestBuild: boolean, |   dontHash: Set<string> | ||||||
|     // Names of entrypoints that should not be hashed
 | } | ||||||
|     dontHash: Set<string> | */ | ||||||
|   } |  | ||||||
|   */ |  | ||||||
| 
 | 
 | ||||||
| module.exports.config = { | module.exports.config = { | ||||||
|   app({ isProdBuild, latestBuild, isStatsBuild, isTestBuild, isWDS }) { |   app({ isProdBuild, latestBuild, isStatsBuild, isWDS }) { | ||||||
|     return { |     return { | ||||||
|       name: "app" + nameSuffix(latestBuild), |  | ||||||
|       entry: { |       entry: { | ||||||
|         service_worker: "./src/entrypoints/service_worker.ts", |         service_worker: "./src/entrypoints/service_worker.ts", | ||||||
|         app: "./src/entrypoints/app.ts", |         app: "./src/entrypoints/app.ts", | ||||||
| @@ -196,14 +150,12 @@ module.exports.config = { | |||||||
|       isProdBuild, |       isProdBuild, | ||||||
|       latestBuild, |       latestBuild, | ||||||
|       isStatsBuild, |       isStatsBuild, | ||||||
|       isTestBuild, |  | ||||||
|       isWDS, |       isWDS, | ||||||
|     }; |     }; | ||||||
|   }, |   }, | ||||||
| 
 | 
 | ||||||
|   demo({ isProdBuild, latestBuild, isStatsBuild }) { |   demo({ isProdBuild, latestBuild, isStatsBuild }) { | ||||||
|     return { |     return { | ||||||
|       name: "demo" + nameSuffix(latestBuild), |  | ||||||
|       entry: { |       entry: { | ||||||
|         main: path.resolve(paths.demo_dir, "src/entrypoint.ts"), |         main: path.resolve(paths.demo_dir, "src/entrypoint.ts"), | ||||||
|       }, |       }, | ||||||
| @@ -233,7 +185,6 @@ module.exports.config = { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return { |     return { | ||||||
|       name: "cast" + nameSuffix(latestBuild), |  | ||||||
|       entry, |       entry, | ||||||
|       outputPath: outputPath(paths.cast_output_root, latestBuild), |       outputPath: outputPath(paths.cast_output_root, latestBuild), | ||||||
|       publicPath: publicPath(latestBuild), |       publicPath: publicPath(latestBuild), | ||||||
| @@ -245,9 +196,8 @@ module.exports.config = { | |||||||
|     }; |     }; | ||||||
|   }, |   }, | ||||||
| 
 | 
 | ||||||
|   hassio({ isProdBuild, latestBuild, isStatsBuild, isTestBuild }) { |   hassio({ isProdBuild, latestBuild }) { | ||||||
|     return { |     return { | ||||||
|       name: "supervisor" + nameSuffix(latestBuild), |  | ||||||
|       entry: { |       entry: { | ||||||
|         entrypoint: path.resolve(paths.hassio_dir, "src/entrypoint.ts"), |         entrypoint: path.resolve(paths.hassio_dir, "src/entrypoint.ts"), | ||||||
|       }, |       }, | ||||||
| @@ -255,19 +205,15 @@ module.exports.config = { | |||||||
|       publicPath: publicPath(latestBuild, paths.hassio_publicPath), |       publicPath: publicPath(latestBuild, paths.hassio_publicPath), | ||||||
|       isProdBuild, |       isProdBuild, | ||||||
|       latestBuild, |       latestBuild, | ||||||
|       isStatsBuild, |  | ||||||
|       isTestBuild, |  | ||||||
|       isHassioBuild: true, |       isHassioBuild: true, | ||||||
|       defineOverlay: { |       defineOverlay: { | ||||||
|         __SUPERVISOR__: true, |         __SUPERVISOR__: true, | ||||||
|         __STATIC_PATH__: `"${paths.hassio_publicPath}/static/"`, |  | ||||||
|       }, |       }, | ||||||
|     }; |     }; | ||||||
|   }, |   }, | ||||||
| 
 | 
 | ||||||
|   gallery({ isProdBuild, latestBuild }) { |   gallery({ isProdBuild, latestBuild }) { | ||||||
|     return { |     return { | ||||||
|       name: "gallery" + nameSuffix(latestBuild), |  | ||||||
|       entry: { |       entry: { | ||||||
|         entrypoint: path.resolve(paths.gallery_dir, "src/entrypoint.js"), |         entrypoint: path.resolve(paths.gallery_dir, "src/entrypoint.js"), | ||||||
|       }, |       }, | ||||||
| @@ -1,6 +1,6 @@ | |||||||
| const fs = require("fs"); | const fs = require("fs"); | ||||||
| const path = require("path"); | const path = require("path"); | ||||||
| const paths = require("./paths.cjs"); | const paths = require("./paths.js"); | ||||||
| 
 | 
 | ||||||
| module.exports = { | module.exports = { | ||||||
|   useRollup() { |   useRollup() { | ||||||
| @@ -17,7 +17,7 @@ module.exports = { | |||||||
|   isStatsBuild() { |   isStatsBuild() { | ||||||
|     return process.env.STATS === "1"; |     return process.env.STATS === "1"; | ||||||
|   }, |   }, | ||||||
|   isTestBuild() { |   isTest() { | ||||||
|     return process.env.IS_TEST === "true"; |     return process.env.IS_TEST === "true"; | ||||||
|   }, |   }, | ||||||
|   isNetlify() { |   isNetlify() { | ||||||
| @@ -1,16 +1,19 @@ | |||||||
| import gulp from "gulp"; | // Run HA develop mode | ||||||
| import env from "../env.cjs"; | const gulp = require("gulp"); | ||||||
| import "./clean.js"; |  | ||||||
| import "./compress.js"; | const env = require("../env"); | ||||||
| import "./entry-html.js"; |  | ||||||
| import "./gather-static.js"; | require("./clean.js"); | ||||||
| import "./gen-icons-json.js"; | require("./translations.js"); | ||||||
| import "./locale-data.js"; | require("./locale-data.js"); | ||||||
| import "./rollup.js"; | require("./gen-icons-json.js"); | ||||||
| import "./service-worker.js"; | require("./gather-static.js"); | ||||||
| import "./translations.js"; | require("./compress.js"); | ||||||
| import "./wds.js"; | require("./webpack.js"); | ||||||
| import "./webpack.js"; | require("./service-worker.js"); | ||||||
|  | require("./entry-html.js"); | ||||||
|  | require("./rollup.js"); | ||||||
|  | require("./wds.js"); | ||||||
|  |  | ||||||
| gulp.task( | gulp.task( | ||||||
|   "develop-app", |   "develop-app", | ||||||
| @@ -22,7 +25,8 @@ gulp.task( | |||||||
|     gulp.parallel( |     gulp.parallel( | ||||||
|       "gen-service-worker-app-dev", |       "gen-service-worker-app-dev", | ||||||
|       "gen-icons-json", |       "gen-icons-json", | ||||||
|       "gen-pages-app-dev", |       "gen-pages-dev", | ||||||
|  |       "gen-index-app-dev", | ||||||
|       "build-translations", |       "build-translations", | ||||||
|       "build-locale-data" |       "build-locale-data" | ||||||
|     ), |     ), | ||||||
| @@ -46,7 +50,11 @@ gulp.task( | |||||||
|     "copy-static-app", |     "copy-static-app", | ||||||
|     env.useRollup() ? "rollup-prod-app" : "webpack-prod-app", |     env.useRollup() ? "rollup-prod-app" : "webpack-prod-app", | ||||||
|     // Don't compress running tests |     // Don't compress running tests | ||||||
|     ...(env.isTestBuild() ? [] : ["compress-app"]), |     ...(env.isTest() ? [] : ["compress-app"]), | ||||||
|     gulp.parallel("gen-pages-app-prod", "gen-service-worker-app-prod") |     gulp.parallel( | ||||||
|  |       "gen-pages-prod", | ||||||
|  |       "gen-index-app-prod", | ||||||
|  |       "gen-service-worker-app-prod" | ||||||
|  |     ) | ||||||
|   ) |   ) | ||||||
| ); | ); | ||||||
|   | |||||||
| @@ -1,12 +1,14 @@ | |||||||
| import gulp from "gulp"; | const gulp = require("gulp"); | ||||||
| import env from "../env.cjs"; |  | ||||||
| import "./clean.js"; | const env = require("../env"); | ||||||
| import "./entry-html.js"; |  | ||||||
| import "./gather-static.js"; | require("./clean.js"); | ||||||
| import "./rollup.js"; | require("./translations.js"); | ||||||
| import "./service-worker.js"; | require("./gather-static.js"); | ||||||
| import "./translations.js"; | require("./webpack.js"); | ||||||
| import "./webpack.js"; | require("./service-worker.js"); | ||||||
|  | require("./entry-html.js"); | ||||||
|  | require("./rollup.js"); | ||||||
|  |  | ||||||
| gulp.task( | gulp.task( | ||||||
|   "develop-cast", |   "develop-cast", | ||||||
| @@ -18,7 +20,7 @@ gulp.task( | |||||||
|     "translations-enable-merge-backend", |     "translations-enable-merge-backend", | ||||||
|     gulp.parallel("gen-icons-json", "build-translations", "build-locale-data"), |     gulp.parallel("gen-icons-json", "build-translations", "build-locale-data"), | ||||||
|     "copy-static-cast", |     "copy-static-cast", | ||||||
|     "gen-pages-cast-dev", |     "gen-index-cast-dev", | ||||||
|     env.useRollup() ? "rollup-dev-server-cast" : "webpack-dev-server-cast" |     env.useRollup() ? "rollup-dev-server-cast" : "webpack-dev-server-cast" | ||||||
|   ) |   ) | ||||||
| ); | ); | ||||||
| @@ -34,6 +36,6 @@ gulp.task( | |||||||
|     gulp.parallel("gen-icons-json", "build-translations", "build-locale-data"), |     gulp.parallel("gen-icons-json", "build-translations", "build-locale-data"), | ||||||
|     "copy-static-cast", |     "copy-static-cast", | ||||||
|     env.useRollup() ? "rollup-prod-cast" : "webpack-prod-cast", |     env.useRollup() ? "rollup-prod-cast" : "webpack-prod-cast", | ||||||
|     "gen-pages-cast-prod" |     "gen-index-cast-prod" | ||||||
|   ) |   ) | ||||||
| ); | ); | ||||||
|   | |||||||
| @@ -1,37 +1,37 @@ | |||||||
| import { deleteSync } from "del"; | const del = import("del"); | ||||||
| import gulp from "gulp"; | const gulp = require("gulp"); | ||||||
| import paths from "../paths.cjs"; | const paths = require("../paths"); | ||||||
| import "./translations.js"; | require("./translations"); | ||||||
|  |  | ||||||
| gulp.task( | gulp.task( | ||||||
|   "clean", |   "clean", | ||||||
|   gulp.parallel("clean-translations", async () => |   gulp.parallel("clean-translations", async () => | ||||||
|     deleteSync([paths.app_output_root, paths.build_dir]) |     (await del).deleteSync([paths.app_output_root, paths.build_dir]) | ||||||
|   ) |   ) | ||||||
| ); | ); | ||||||
|  |  | ||||||
| gulp.task( | gulp.task( | ||||||
|   "clean-demo", |   "clean-demo", | ||||||
|   gulp.parallel("clean-translations", async () => |   gulp.parallel("clean-translations", async () => | ||||||
|     deleteSync([paths.demo_output_root, paths.build_dir]) |     (await del).deleteSync([paths.demo_output_root, paths.build_dir]) | ||||||
|   ) |   ) | ||||||
| ); | ); | ||||||
|  |  | ||||||
| gulp.task( | gulp.task( | ||||||
|   "clean-cast", |   "clean-cast", | ||||||
|   gulp.parallel("clean-translations", async () => |   gulp.parallel("clean-translations", async () => | ||||||
|     deleteSync([paths.cast_output_root, paths.build_dir]) |     (await del).deleteSync([paths.cast_output_root, paths.build_dir]) | ||||||
|   ) |   ) | ||||||
| ); | ); | ||||||
|  |  | ||||||
| gulp.task("clean-hassio", async () => | gulp.task("clean-hassio", async () => | ||||||
|   deleteSync([paths.hassio_output_root, paths.build_dir]) |   (await del).deleteSync([paths.hassio_output_root, paths.build_dir]) | ||||||
| ); | ); | ||||||
|  |  | ||||||
| gulp.task( | gulp.task( | ||||||
|   "clean-gallery", |   "clean-gallery", | ||||||
|   gulp.parallel("clean-translations", async () => |   gulp.parallel("clean-translations", async () => | ||||||
|     deleteSync([ |     (await del).deleteSync([ | ||||||
|       paths.gallery_output_root, |       paths.gallery_output_root, | ||||||
|       paths.gallery_build, |       paths.gallery_build, | ||||||
|       paths.build_dir, |       paths.build_dir, | ||||||
|   | |||||||
| @@ -1,10 +1,10 @@ | |||||||
| // Tasks to compress | // Tasks to compress | ||||||
|  |  | ||||||
| import gulp from "gulp"; | const gulp = require("gulp"); | ||||||
| import zopfli from "gulp-zopfli-green"; | const zopfli = require("gulp-zopfli-green"); | ||||||
| import merge from "merge-stream"; | const merge = require("merge-stream"); | ||||||
| import path from "path"; | const path = require("path"); | ||||||
| import paths from "../paths.cjs"; | const paths = require("../paths"); | ||||||
|  |  | ||||||
| const zopfliOptions = { threshold: 150 }; | const zopfliOptions = { threshold: 150 }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,13 +1,16 @@ | |||||||
| import gulp from "gulp"; | // Run demo develop mode | ||||||
| import env from "../env.cjs"; | const gulp = require("gulp"); | ||||||
| import "./clean.js"; |  | ||||||
| import "./entry-html.js"; | const env = require("../env"); | ||||||
| import "./gather-static.js"; |  | ||||||
| import "./gen-icons-json.js"; | require("./clean.js"); | ||||||
| import "./rollup.js"; | require("./translations.js"); | ||||||
| import "./service-worker.js"; | require("./gen-icons-json.js"); | ||||||
| import "./translations.js"; | require("./gather-static.js"); | ||||||
| import "./webpack.js"; | require("./webpack.js"); | ||||||
|  | require("./service-worker.js"); | ||||||
|  | require("./entry-html.js"); | ||||||
|  | require("./rollup.js"); | ||||||
|  |  | ||||||
| gulp.task( | gulp.task( | ||||||
|   "develop-demo", |   "develop-demo", | ||||||
| @@ -19,7 +22,7 @@ gulp.task( | |||||||
|     "translations-enable-merge-backend", |     "translations-enable-merge-backend", | ||||||
|     gulp.parallel( |     gulp.parallel( | ||||||
|       "gen-icons-json", |       "gen-icons-json", | ||||||
|       "gen-pages-demo-dev", |       "gen-index-demo-dev", | ||||||
|       "build-translations", |       "build-translations", | ||||||
|       "build-locale-data" |       "build-locale-data" | ||||||
|     ), |     ), | ||||||
| @@ -40,6 +43,6 @@ gulp.task( | |||||||
|     gulp.parallel("gen-icons-json", "build-translations", "build-locale-data"), |     gulp.parallel("gen-icons-json", "build-translations", "build-locale-data"), | ||||||
|     "copy-static-demo", |     "copy-static-demo", | ||||||
|     env.useRollup() ? "rollup-prod-demo" : "webpack-prod-demo", |     env.useRollup() ? "rollup-prod-demo" : "webpack-prod-demo", | ||||||
|     "gen-pages-demo-prod" |     "gen-index-demo-prod" | ||||||
|   ) |   ) | ||||||
| ); | ); | ||||||
|   | |||||||
| @@ -1,7 +1,6 @@ | |||||||
| import fs from "fs/promises"; | const gulp = require("gulp"); | ||||||
| import gulp from "gulp"; | const fs = require("fs/promises"); | ||||||
| import mapStream from "map-stream"; | const mapStream = require("map-stream"); | ||||||
| import transform from "gulp-json-transform"; |  | ||||||
| 
 | 
 | ||||||
| const inDirFrontend = "translations/frontend"; | const inDirFrontend = "translations/frontend"; | ||||||
| const inDirBackend = "translations/backend"; | const inDirBackend = "translations/backend"; | ||||||
| @@ -42,31 +41,7 @@ function checkHtml() { | |||||||
|   }); |   }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function convertBackendTranslations(data, _file) { | // Backend translations do not currently pass HTML check so are excluded here for now
 | ||||||
|   const output = { component: {} }; |  | ||||||
|   if (!data.component) { |  | ||||||
|     return output; |  | ||||||
|   } |  | ||||||
|   Object.keys(data.component).forEach((domain) => { |  | ||||||
|     if (!("entity_component" in data.component[domain])) { |  | ||||||
|       return; |  | ||||||
|     } |  | ||||||
|     output.component[domain] = { entity_component: {} }; |  | ||||||
|     Object.keys(data.component[domain].entity_component).forEach((key) => { |  | ||||||
|       output.component[domain].entity_component[key] = |  | ||||||
|         data.component[domain].entity_component[key]; |  | ||||||
|     }); |  | ||||||
|   }); |  | ||||||
|   return output; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| gulp.task("convert-backend-translations", function () { |  | ||||||
|   return gulp |  | ||||||
|     .src([`${inDirBackend}/*.json`]) |  | ||||||
|     .pipe(transform((data, file) => convertBackendTranslations(data, file))) |  | ||||||
|     .pipe(gulp.dest(inDirBackend)); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| gulp.task("check-translations-html", function () { | gulp.task("check-translations-html", function () { | ||||||
|   return gulp.src([`${inDirFrontend}/*.json`]).pipe(checkHtml()); |   return gulp.src([`${inDirFrontend}/*.json`]).pipe(checkHtml()); | ||||||
| }); | }); | ||||||
| @@ -1,233 +1,344 @@ | |||||||
| // Tasks to generate entry HTML | // Tasks to generate entry HTML | ||||||
|  | const gulp = require("gulp"); | ||||||
|  | const fs = require("fs-extra"); | ||||||
|  | const path = require("path"); | ||||||
|  | const template = require("lodash.template"); | ||||||
|  | const minify = require("html-minifier").minify; | ||||||
|  | const paths = require("../paths.js"); | ||||||
|  | const env = require("../env.js"); | ||||||
|  |  | ||||||
| import fs from "fs-extra"; | const templatePath = (tpl) => | ||||||
| import gulp from "gulp"; |   path.resolve(paths.polymer_dir, "src/html/", `${tpl}.html.template`); | ||||||
| import { minify } from "html-minifier-terser"; |  | ||||||
| import template from "lodash.template"; |  | ||||||
| import path from "path"; |  | ||||||
| import { htmlMinifierOptions, terserOptions } from "../bundle.cjs"; |  | ||||||
| import env from "../env.cjs"; |  | ||||||
| import paths from "../paths.cjs"; |  | ||||||
|  |  | ||||||
| const renderTemplate = (templateFile, data = {}) => { | const readFile = (pth) => fs.readFileSync(pth).toString(); | ||||||
|   const compiled = template( |  | ||||||
|     fs.readFileSync(templateFile, { encoding: "utf-8" }) | const renderTemplate = (pth, data = {}, pathFunc = templatePath) => { | ||||||
|   ); |   const compiled = template(readFile(pathFunc(pth))); | ||||||
|   return compiled({ |   return compiled({ | ||||||
|     ...data, |     ...data, | ||||||
|     useRollup: env.useRollup(), |     useRollup: env.useRollup(), | ||||||
|     useWDS: env.useWDS(), |     useWDS: env.useWDS(), | ||||||
|     // Resolve any child/nested templates relative to the parent and pass the same data |     renderTemplate, | ||||||
|     renderTemplate: (childTemplate) => |  | ||||||
|       renderTemplate( |  | ||||||
|         path.resolve(path.dirname(templateFile), childTemplate), |  | ||||||
|         data |  | ||||||
|       ), |  | ||||||
|   }); |   }); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| const WRAP_TAGS = { ".js": "script", ".css": "style" }; | const renderDemoTemplate = (pth, data = {}) => | ||||||
|  |   renderTemplate(pth, data, (tpl) => | ||||||
| const minifyHtml = (content, ext) => { |     path.resolve(paths.demo_dir, "src/html/", `${tpl}.html.template`) | ||||||
|   const wrapTag = WRAP_TAGS[ext] || ""; |  | ||||||
|   const begTag = wrapTag && `<${wrapTag}>`; |  | ||||||
|   const endTag = wrapTag && `</${wrapTag}>`; |  | ||||||
|   return minify(begTag + content + endTag, { |  | ||||||
|     ...htmlMinifierOptions, |  | ||||||
|     conservativeCollapse: false, |  | ||||||
|     minifyJS: terserOptions({ |  | ||||||
|       latestBuild: false, // Shared scripts should be ES5 |  | ||||||
|       isTestBuild: true, // Don't need source maps |  | ||||||
|     }), |  | ||||||
|   }).then((wrapped) => |  | ||||||
|     wrapTag ? wrapped.slice(begTag.length, -endTag.length) : wrapped |  | ||||||
|   ); |   ); | ||||||
| }; |  | ||||||
|  |  | ||||||
| // Function to generate a dev task for each project's configuration | const renderCastTemplate = (pth, data = {}) => | ||||||
| // Note Currently WDS paths are hard-coded to only work for app |   renderTemplate(pth, data, (tpl) => | ||||||
| const genPagesDevTask = |     path.resolve(paths.cast_dir, "src/html/", `${tpl}.html.template`) | ||||||
|   ( |   ); | ||||||
|     pageEntries, |  | ||||||
|     inputRoot, |  | ||||||
|     outputRoot, |  | ||||||
|     useWDS = false, |  | ||||||
|     inputSub = "src/html", |  | ||||||
|     publicRoot = "" |  | ||||||
|   ) => |  | ||||||
|   async () => { |  | ||||||
|     for (const [page, entries] of Object.entries(pageEntries)) { |  | ||||||
|       const content = renderTemplate( |  | ||||||
|         path.resolve(inputRoot, inputSub, `${page}.template`), |  | ||||||
|         { |  | ||||||
|           latestEntryJS: entries.map((entry) => |  | ||||||
|             useWDS |  | ||||||
|               ? `http://localhost:8000/src/entrypoints/${entry}.ts` |  | ||||||
|               : `${publicRoot}/frontend_latest/${entry}.js` |  | ||||||
|           ), |  | ||||||
|           es5EntryJS: entries.map( |  | ||||||
|             (entry) => `${publicRoot}/frontend_es5/${entry}.js` |  | ||||||
|           ), |  | ||||||
|           latestCustomPanelJS: useWDS |  | ||||||
|             ? "http://localhost:8000/src/entrypoints/custom-panel.ts" |  | ||||||
|             : `${publicRoot}/frontend_latest/custom-panel.js`, |  | ||||||
|           es5CustomPanelJS: `${publicRoot}/frontend_es5/custom-panel.js`, |  | ||||||
|         } |  | ||||||
|       ); |  | ||||||
|       fs.outputFileSync(path.resolve(outputRoot, page), content); |  | ||||||
|     } |  | ||||||
|   }; |  | ||||||
|  |  | ||||||
| // Same as previous but for production builds | const renderGalleryTemplate = (pth, data = {}) => | ||||||
| // (includes minification and hashed file names from manifest) |   renderTemplate(pth, data, (tpl) => | ||||||
| const genPagesProdTask = |     path.resolve(paths.gallery_dir, "src/html/", `${tpl}.html.template`) | ||||||
|   ( |   ); | ||||||
|     pageEntries, |  | ||||||
|     inputRoot, | const minifyHtml = (content) => | ||||||
|     outputRoot, |   minify(content, { | ||||||
|     outputLatest, |     collapseWhitespace: true, | ||||||
|     outputES5, |     minifyJS: true, | ||||||
|     inputSub = "src/html" |     minifyCSS: true, | ||||||
|   ) => |     removeComments: true, | ||||||
|   async () => { |   }); | ||||||
|     const latestManifest = fs.readJsonSync( |  | ||||||
|       path.resolve(outputLatest, "manifest.json") | const PAGES = ["onboarding", "authorize"]; | ||||||
|  |  | ||||||
|  | gulp.task("gen-pages-dev", (done) => { | ||||||
|  |   for (const page of PAGES) { | ||||||
|  |     const content = renderTemplate(page, { | ||||||
|  |       latestPageJS: `/frontend_latest/${page}.js`, | ||||||
|  |  | ||||||
|  |       es5PageJS: `/frontend_es5/${page}.js`, | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     fs.outputFileSync( | ||||||
|  |       path.resolve(paths.app_output_root, `${page}.html`), | ||||||
|  |       content | ||||||
|     ); |     ); | ||||||
|     const es5Manifest = outputES5 |   } | ||||||
|       ? fs.readJsonSync(path.resolve(outputES5, "manifest.json")) |   done(); | ||||||
|       : {}; | }); | ||||||
|     const minifiedHTML = []; |  | ||||||
|     for (const [page, entries] of Object.entries(pageEntries)) { |  | ||||||
|       const content = renderTemplate( |  | ||||||
|         path.resolve(inputRoot, inputSub, `${page}.template`), |  | ||||||
|         { |  | ||||||
|           latestEntryJS: entries.map((entry) => latestManifest[`${entry}.js`]), |  | ||||||
|           es5EntryJS: entries.map((entry) => es5Manifest[`${entry}.js`]), |  | ||||||
|           latestCustomPanelJS: latestManifest["custom-panel.js"], |  | ||||||
|           es5CustomPanelJS: es5Manifest["custom-panel.js"], |  | ||||||
|         } |  | ||||||
|       ); |  | ||||||
|       minifiedHTML.push( |  | ||||||
|         minifyHtml(content, path.extname(page)).then((minified) => |  | ||||||
|           fs.outputFileSync(path.resolve(outputRoot, page), minified) |  | ||||||
|         ) |  | ||||||
|       ); |  | ||||||
|     } |  | ||||||
|     await Promise.all(minifiedHTML); |  | ||||||
|   }; |  | ||||||
|  |  | ||||||
| // Map HTML pages to their required entrypoints | gulp.task("gen-pages-prod", (done) => { | ||||||
| const APP_PAGE_ENTRIES = { |   const latestManifest = require(path.resolve( | ||||||
|   "authorize.html": ["authorize"], |  | ||||||
|   "onboarding.html": ["onboarding"], |  | ||||||
|   "index.html": ["core", "app"], |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| gulp.task( |  | ||||||
|   "gen-pages-app-dev", |  | ||||||
|   genPagesDevTask( |  | ||||||
|     APP_PAGE_ENTRIES, |  | ||||||
|     paths.polymer_dir, |  | ||||||
|     paths.app_output_root, |  | ||||||
|     env.useWDS() |  | ||||||
|   ) |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| gulp.task( |  | ||||||
|   "gen-pages-app-prod", |  | ||||||
|   genPagesProdTask( |  | ||||||
|     APP_PAGE_ENTRIES, |  | ||||||
|     paths.polymer_dir, |  | ||||||
|     paths.app_output_root, |  | ||||||
|     paths.app_output_latest, |     paths.app_output_latest, | ||||||
|     paths.app_output_es5 |     "manifest.json" | ||||||
|   ) |   )); | ||||||
| ); |   const es5Manifest = require(path.resolve( | ||||||
|  |     paths.app_output_es5, | ||||||
|  |     "manifest.json" | ||||||
|  |   )); | ||||||
|  |  | ||||||
| const CAST_PAGE_ENTRIES = { |   for (const page of PAGES) { | ||||||
|   "faq.html": ["launcher"], |     const content = renderTemplate(page, { | ||||||
|   "index.html": ["launcher"], |       latestPageJS: latestManifest[`${page}.js`], | ||||||
|   "media.html": ["media"], |  | ||||||
|   "receiver.html": ["receiver"], |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| gulp.task( |       es5PageJS: es5Manifest[`${page}.js`], | ||||||
|   "gen-pages-cast-dev", |     }); | ||||||
|   genPagesDevTask(CAST_PAGE_ENTRIES, paths.cast_dir, paths.cast_output_root) |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| gulp.task( |     fs.outputFileSync( | ||||||
|   "gen-pages-cast-prod", |       path.resolve(paths.app_output_root, `${page}.html`), | ||||||
|   genPagesProdTask( |       minifyHtml(content) | ||||||
|     CAST_PAGE_ENTRIES, |     ); | ||||||
|     paths.cast_dir, |   } | ||||||
|     paths.cast_output_root, |   done(); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | gulp.task("gen-index-app-dev", (done) => { | ||||||
|  |   let latestAppJS; | ||||||
|  |   let latestCoreJS; | ||||||
|  |   let latestCustomPanelJS; | ||||||
|  |  | ||||||
|  |   if (env.useWDS()) { | ||||||
|  |     latestAppJS = "http://localhost:8000/src/entrypoints/app.ts"; | ||||||
|  |     latestCoreJS = "http://localhost:8000/src/entrypoints/core.ts"; | ||||||
|  |     latestCustomPanelJS = | ||||||
|  |       "http://localhost:8000/src/entrypoints/custom-panel.ts"; | ||||||
|  |   } else { | ||||||
|  |     latestAppJS = "/frontend_latest/app.js"; | ||||||
|  |     latestCoreJS = "/frontend_latest/core.js"; | ||||||
|  |     latestCustomPanelJS = "/frontend_latest/custom-panel.js"; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   const content = renderTemplate("index", { | ||||||
|  |     latestAppJS, | ||||||
|  |     latestCoreJS, | ||||||
|  |     latestCustomPanelJS, | ||||||
|  |  | ||||||
|  |     es5AppJS: "/frontend_es5/app.js", | ||||||
|  |     es5CoreJS: "/frontend_es5/core.js", | ||||||
|  |     es5CustomPanelJS: "/frontend_es5/custom-panel.js", | ||||||
|  |   }).replace(/#THEMEC/g, "{{ theme_color }}"); | ||||||
|  |  | ||||||
|  |   fs.outputFileSync(path.resolve(paths.app_output_root, "index.html"), content); | ||||||
|  |   done(); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | gulp.task("gen-index-app-prod", (done) => { | ||||||
|  |   const latestManifest = require(path.resolve( | ||||||
|  |     paths.app_output_latest, | ||||||
|  |     "manifest.json" | ||||||
|  |   )); | ||||||
|  |   const es5Manifest = require(path.resolve( | ||||||
|  |     paths.app_output_es5, | ||||||
|  |     "manifest.json" | ||||||
|  |   )); | ||||||
|  |   const content = renderTemplate("index", { | ||||||
|  |     latestAppJS: latestManifest["app.js"], | ||||||
|  |     latestCoreJS: latestManifest["core.js"], | ||||||
|  |     latestCustomPanelJS: latestManifest["custom-panel.js"], | ||||||
|  |  | ||||||
|  |     es5AppJS: es5Manifest["app.js"], | ||||||
|  |     es5CoreJS: es5Manifest["core.js"], | ||||||
|  |     es5CustomPanelJS: es5Manifest["custom-panel.js"], | ||||||
|  |   }); | ||||||
|  |   const minified = minifyHtml(content).replace(/#THEMEC/g, "{{ theme_color }}"); | ||||||
|  |  | ||||||
|  |   fs.outputFileSync( | ||||||
|  |     path.resolve(paths.app_output_root, "index.html"), | ||||||
|  |     minified | ||||||
|  |   ); | ||||||
|  |   done(); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | gulp.task("gen-index-cast-dev", (done) => { | ||||||
|  |   const contentReceiver = renderCastTemplate("receiver", { | ||||||
|  |     latestReceiverJS: "/frontend_latest/receiver.js", | ||||||
|  |   }); | ||||||
|  |   fs.outputFileSync( | ||||||
|  |     path.resolve(paths.cast_output_root, "receiver.html"), | ||||||
|  |     contentReceiver | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  |   const contentMedia = renderCastTemplate("media", { | ||||||
|  |     latestMediaJS: "/frontend_latest/media.js", | ||||||
|  |     es5MediaJS: "/frontend_es5/media.js", | ||||||
|  |   }); | ||||||
|  |   fs.outputFileSync( | ||||||
|  |     path.resolve(paths.cast_output_root, "media.html"), | ||||||
|  |     contentMedia | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  |   const contentFAQ = renderCastTemplate("launcher-faq", { | ||||||
|  |     latestLauncherJS: "/frontend_latest/launcher.js", | ||||||
|  |     es5LauncherJS: "/frontend_es5/launcher.js", | ||||||
|  |   }); | ||||||
|  |   fs.outputFileSync( | ||||||
|  |     path.resolve(paths.cast_output_root, "faq.html"), | ||||||
|  |     contentFAQ | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  |   const contentLauncher = renderCastTemplate("launcher", { | ||||||
|  |     latestLauncherJS: "/frontend_latest/launcher.js", | ||||||
|  |     es5LauncherJS: "/frontend_es5/launcher.js", | ||||||
|  |   }); | ||||||
|  |   fs.outputFileSync( | ||||||
|  |     path.resolve(paths.cast_output_root, "index.html"), | ||||||
|  |     contentLauncher | ||||||
|  |   ); | ||||||
|  |   done(); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | gulp.task("gen-index-cast-prod", (done) => { | ||||||
|  |   const latestManifest = require(path.resolve( | ||||||
|     paths.cast_output_latest, |     paths.cast_output_latest, | ||||||
|     paths.cast_output_es5 |     "manifest.json" | ||||||
|   ) |   )); | ||||||
| ); |   const es5Manifest = require(path.resolve( | ||||||
|  |     paths.cast_output_es5, | ||||||
|  |     "manifest.json" | ||||||
|  |   )); | ||||||
|  |  | ||||||
| const DEMO_PAGE_ENTRIES = { "index.html": ["main"] }; |   const contentReceiver = renderCastTemplate("receiver", { | ||||||
|  |     latestReceiverJS: latestManifest["receiver.js"], | ||||||
|  |   }); | ||||||
|  |   fs.outputFileSync( | ||||||
|  |     path.resolve(paths.cast_output_root, "receiver.html"), | ||||||
|  |     contentReceiver | ||||||
|  |   ); | ||||||
|  |  | ||||||
| gulp.task( |   const contentMedia = renderCastTemplate("media", { | ||||||
|   "gen-pages-demo-dev", |     latestMediaJS: latestManifest["media.js"], | ||||||
|   genPagesDevTask(DEMO_PAGE_ENTRIES, paths.demo_dir, paths.demo_output_root) |     es5MediaJS: es5Manifest["media.js"], | ||||||
| ); |   }); | ||||||
|  |   fs.outputFileSync( | ||||||
|  |     path.resolve(paths.cast_output_root, "media.html"), | ||||||
|  |     contentMedia | ||||||
|  |   ); | ||||||
|  |  | ||||||
| gulp.task( |   const contentFAQ = renderCastTemplate("launcher-faq", { | ||||||
|   "gen-pages-demo-prod", |     latestLauncherJS: latestManifest["launcher.js"], | ||||||
|   genPagesProdTask( |     es5LauncherJS: es5Manifest["launcher.js"], | ||||||
|     DEMO_PAGE_ENTRIES, |   }); | ||||||
|     paths.demo_dir, |   fs.outputFileSync( | ||||||
|     paths.demo_output_root, |     path.resolve(paths.cast_output_root, "faq.html"), | ||||||
|  |     contentFAQ | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  |   const contentLauncher = renderCastTemplate("launcher", { | ||||||
|  |     latestLauncherJS: latestManifest["launcher.js"], | ||||||
|  |     es5LauncherJS: es5Manifest["launcher.js"], | ||||||
|  |   }); | ||||||
|  |   fs.outputFileSync( | ||||||
|  |     path.resolve(paths.cast_output_root, "index.html"), | ||||||
|  |     contentLauncher | ||||||
|  |   ); | ||||||
|  |   done(); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | gulp.task("gen-index-demo-dev", (done) => { | ||||||
|  |   const content = renderDemoTemplate("index", { | ||||||
|  |     latestDemoJS: "/frontend_latest/main.js", | ||||||
|  |  | ||||||
|  |     es5DemoJS: "/frontend_es5/main.js", | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   fs.outputFileSync( | ||||||
|  |     path.resolve(paths.demo_output_root, "index.html"), | ||||||
|  |     content | ||||||
|  |   ); | ||||||
|  |   done(); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | gulp.task("gen-index-demo-prod", (done) => { | ||||||
|  |   const latestManifest = require(path.resolve( | ||||||
|     paths.demo_output_latest, |     paths.demo_output_latest, | ||||||
|     paths.demo_output_es5 |     "manifest.json" | ||||||
|   ) |   )); | ||||||
| ); |   const es5Manifest = require(path.resolve( | ||||||
|  |     paths.demo_output_es5, | ||||||
|  |     "manifest.json" | ||||||
|  |   )); | ||||||
|  |   const content = renderDemoTemplate("index", { | ||||||
|  |     latestDemoJS: latestManifest["main.js"], | ||||||
|  |  | ||||||
| const GALLERY_PAGE_ENTRIES = { "index.html": ["entrypoint"] }; |     es5DemoJS: es5Manifest["main.js"], | ||||||
|  |   }); | ||||||
|  |   const minified = minifyHtml(content); | ||||||
|  |  | ||||||
| gulp.task( |   fs.outputFileSync( | ||||||
|   "gen-pages-gallery-dev", |     path.resolve(paths.demo_output_root, "index.html"), | ||||||
|   genPagesDevTask( |     minified | ||||||
|     GALLERY_PAGE_ENTRIES, |   ); | ||||||
|     paths.gallery_dir, |   done(); | ||||||
|     paths.gallery_output_root | }); | ||||||
|   ) |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| gulp.task( | gulp.task("gen-index-gallery-dev", (done) => { | ||||||
|   "gen-pages-gallery-prod", |   const content = renderGalleryTemplate("index", { | ||||||
|   genPagesProdTask( |     latestGalleryJS: "./frontend_latest/entrypoint.js", | ||||||
|     GALLERY_PAGE_ENTRIES, |   }); | ||||||
|     paths.gallery_dir, |  | ||||||
|     paths.gallery_output_root, |  | ||||||
|     paths.gallery_output_latest |  | ||||||
|   ) |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| const HASSIO_PAGE_ENTRIES = { "entrypoint.js": ["entrypoint"] }; |   fs.outputFileSync( | ||||||
|  |     path.resolve(paths.gallery_output_root, "index.html"), | ||||||
|  |     content | ||||||
|  |   ); | ||||||
|  |   done(); | ||||||
|  | }); | ||||||
|  |  | ||||||
| gulp.task( | gulp.task("gen-index-gallery-prod", (done) => { | ||||||
|   "gen-pages-hassio-dev", |   const latestManifest = require(path.resolve( | ||||||
|   genPagesDevTask( |     paths.gallery_output_latest, | ||||||
|     HASSIO_PAGE_ENTRIES, |     "manifest.json" | ||||||
|     paths.hassio_dir, |   )); | ||||||
|     paths.hassio_output_root, |   const content = renderGalleryTemplate("index", { | ||||||
|     undefined, |     latestGalleryJS: latestManifest["entrypoint.js"], | ||||||
|     "src", |   }); | ||||||
|     paths.hassio_publicPath |   const minified = minifyHtml(content); | ||||||
|   ) |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| gulp.task( |   fs.outputFileSync( | ||||||
|   "gen-pages-hassio-prod", |     path.resolve(paths.gallery_output_root, "index.html"), | ||||||
|   genPagesProdTask( |     minified | ||||||
|     HASSIO_PAGE_ENTRIES, |   ); | ||||||
|     paths.hassio_dir, |   done(); | ||||||
|     paths.hassio_output_root, | }); | ||||||
|  |  | ||||||
|  | gulp.task("gen-index-hassio-dev", async () => { | ||||||
|  |   writeHassioEntrypoint( | ||||||
|  |     `${paths.hassio_publicPath}/frontend_latest/entrypoint.js`, | ||||||
|  |     `${paths.hassio_publicPath}/frontend_es5/entrypoint.js` | ||||||
|  |   ); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | gulp.task("gen-index-hassio-prod", async () => { | ||||||
|  |   const latestManifest = require(path.resolve( | ||||||
|     paths.hassio_output_latest, |     paths.hassio_output_latest, | ||||||
|  |     "manifest.json" | ||||||
|  |   )); | ||||||
|  |   const es5Manifest = require(path.resolve( | ||||||
|     paths.hassio_output_es5, |     paths.hassio_output_es5, | ||||||
|     "src" |     "manifest.json" | ||||||
|   ) |   )); | ||||||
| ); |   writeHassioEntrypoint( | ||||||
|  |     latestManifest["entrypoint.js"], | ||||||
|  |     es5Manifest["entrypoint.js"] | ||||||
|  |   ); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | function writeHassioEntrypoint(latestEntrypoint, es5Entrypoint) { | ||||||
|  |   fs.mkdirSync(paths.hassio_output_root, { recursive: true }); | ||||||
|  |   // Safari 12 and below does not have a compliant ES2015 implementation of template literals, so we ship ES5 | ||||||
|  |   fs.writeFileSync( | ||||||
|  |     path.resolve(paths.hassio_output_root, "entrypoint.js"), | ||||||
|  |     ` | ||||||
|  | function loadES5() { | ||||||
|  |   var el = document.createElement('script'); | ||||||
|  |   el.src = '${es5Entrypoint}'; | ||||||
|  |   document.body.appendChild(el); | ||||||
|  | } | ||||||
|  | if (/.*Version\\/(?:11|12)(?:\\.\\d+)*.*Safari\\//.test(navigator.userAgent)) { | ||||||
|  |     loadES5(); | ||||||
|  | } else { | ||||||
|  |   try { | ||||||
|  |     new Function("import('${latestEntrypoint}')")(); | ||||||
|  |   } catch (err) { | ||||||
|  |     loadES5(); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |   `, | ||||||
|  |     { encoding: "utf-8" } | ||||||
|  |   ); | ||||||
|  | } | ||||||
|   | |||||||
| @@ -1,15 +1,14 @@ | |||||||
| // Task to download the latest Lokalise translations from the nightly workflow artifacts | // Task to download the latest Lokalise translations from the nightly workflow artifacts | ||||||
|  |  | ||||||
| import { createOAuthDeviceAuth } from "@octokit/auth-oauth-device"; | const del = import("del"); | ||||||
| import { retry } from "@octokit/plugin-retry"; | const fs = require("fs/promises"); | ||||||
| import { Octokit } from "@octokit/rest"; | const path = require("path"); | ||||||
| import { deleteAsync } from "del"; | const process = require("process"); | ||||||
| import { mkdir, readFile, writeFile } from "fs/promises"; | const gulp = require("gulp"); | ||||||
| import gulp from "gulp"; | const jszip = require("jszip"); | ||||||
| import jszip from "jszip"; | const tar = require("tar"); | ||||||
| import path from "path"; | const { Octokit } = require("@octokit/rest"); | ||||||
| import process from "process"; | const { createOAuthDeviceAuth } = require("@octokit/auth-oauth-device"); | ||||||
| import tar from "tar"; |  | ||||||
|  |  | ||||||
| const MAX_AGE = 24; // hours | const MAX_AGE = 24; // hours | ||||||
| const OWNER = "home-assistant"; | const OWNER = "home-assistant"; | ||||||
| @@ -38,7 +37,7 @@ gulp.task("fetch-nightly-translations", async function () { | |||||||
|   // and stop if they are not old enough |   // and stop if they are not old enough | ||||||
|   let currentArtifact; |   let currentArtifact; | ||||||
|   try { |   try { | ||||||
|     currentArtifact = JSON.parse(await readFile(ARTIFACT_FILE, "utf-8")); |     currentArtifact = JSON.parse(await fs.readFile(ARTIFACT_FILE, "utf-8")); | ||||||
|     const currentAge = |     const currentAge = | ||||||
|       (Date.now() - Date.parse(currentArtifact.created_at)) / 3600000; |       (Date.now() - Date.parse(currentArtifact.created_at)) / 3600000; | ||||||
|     if (currentAge < MAX_AGE) { |     if (currentAge < MAX_AGE) { | ||||||
| @@ -53,7 +52,7 @@ gulp.task("fetch-nightly-translations", async function () { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   // To store file writing promises |   // To store file writing promises | ||||||
|   const createExtractDir = mkdir(EXTRACT_DIR, { recursive: true }); |   const createExtractDir = fs.mkdir(EXTRACT_DIR, { recursive: true }); | ||||||
|   const writings = []; |   const writings = []; | ||||||
|  |  | ||||||
|   // Authenticate to GitHub using GitHub action token if it exists, |   // Authenticate to GitHub using GitHub action token if it exists, | ||||||
| @@ -63,7 +62,7 @@ gulp.task("fetch-nightly-translations", async function () { | |||||||
|     tokenAuth = { token: process.env.GITHUB_TOKEN }; |     tokenAuth = { token: process.env.GITHUB_TOKEN }; | ||||||
|   } else { |   } else { | ||||||
|     try { |     try { | ||||||
|       tokenAuth = JSON.parse(await readFile(TOKEN_FILE, "utf-8")); |       tokenAuth = JSON.parse(await fs.readFile(TOKEN_FILE, "utf-8")); | ||||||
|     } catch { |     } catch { | ||||||
|       if (!allowTokenSetup) { |       if (!allowTokenSetup) { | ||||||
|         console.log("No token found so  build wil continue with English only"); |         console.log("No token found so  build wil continue with English only"); | ||||||
| @@ -88,7 +87,7 @@ gulp.task("fetch-nightly-translations", async function () { | |||||||
|       tokenAuth = await auth({ type: "oauth" }); |       tokenAuth = await auth({ type: "oauth" }); | ||||||
|       writings.push( |       writings.push( | ||||||
|         createExtractDir.then( |         createExtractDir.then( | ||||||
|           writeFile(TOKEN_FILE, JSON.stringify(tokenAuth, null, 2)) |           fs.writeFile(TOKEN_FILE, JSON.stringify(tokenAuth, null, 2)) | ||||||
|         ) |         ) | ||||||
|       ); |       ); | ||||||
|     } |     } | ||||||
| @@ -96,7 +95,7 @@ gulp.task("fetch-nightly-translations", async function () { | |||||||
|  |  | ||||||
|   // Authenticate with token and request workflow runs from GitHub |   // Authenticate with token and request workflow runs from GitHub | ||||||
|   console.log("Fetching new translations..."); |   console.log("Fetching new translations..."); | ||||||
|   const octokit = new (Octokit.plugin(retry))({ |   const octokit = new Octokit({ | ||||||
|     userAgent: "Fetch Nightly Translations", |     userAgent: "Fetch Nightly Translations", | ||||||
|     auth: tokenAuth.token, |     auth: tokenAuth.token, | ||||||
|   }); |   }); | ||||||
| @@ -132,13 +131,17 @@ gulp.task("fetch-nightly-translations", async function () { | |||||||
|   } |   } | ||||||
|   writings.push( |   writings.push( | ||||||
|     createExtractDir.then( |     createExtractDir.then( | ||||||
|       writeFile(ARTIFACT_FILE, JSON.stringify(latestArtifact, null, 2)) |       fs.writeFile(ARTIFACT_FILE, JSON.stringify(latestArtifact, null, 2)) | ||||||
|     ) |     ) | ||||||
|   ); |   ); | ||||||
|  |  | ||||||
|   // Remove the current translations |   // Remove the current translations | ||||||
|   const deleteCurrent = Promise.all(writings).then( |   const deleteCurrent = Promise.all(writings).then( | ||||||
|     deleteAsync([`${EXTRACT_DIR}/*`, `!${ARTIFACT_FILE}`, `!${TOKEN_FILE}`]) |     (await del).deleteAsync([ | ||||||
|  |       `${EXTRACT_DIR}/*`, | ||||||
|  |       `!${ARTIFACT_FILE}`, | ||||||
|  |       `!${TOKEN_FILE}`, | ||||||
|  |     ]) | ||||||
|   ); |   ); | ||||||
|  |  | ||||||
|   // Get the download URL and follow the redirect to download (stored as ArrayBuffer) |   // Get the download URL and follow the redirect to download (stored as ArrayBuffer) | ||||||
|   | |||||||
| @@ -1,23 +1,26 @@ | |||||||
| import fs from "fs"; | // Run demo develop mode | ||||||
| import { glob } from "glob"; | const gulp = require("gulp"); | ||||||
| import gulp from "gulp"; | const fs = require("fs"); | ||||||
| import yaml from "js-yaml"; | const path = require("path"); | ||||||
| import { marked } from "marked"; | const { marked } = require("marked"); | ||||||
| import path from "path"; | const glob = require("glob"); | ||||||
| import env from "../env.cjs"; | const yaml = require("js-yaml"); | ||||||
| import paths from "../paths.cjs"; |  | ||||||
| import "./clean.js"; | const env = require("../env"); | ||||||
| import "./entry-html.js"; | const paths = require("../paths"); | ||||||
| import "./gather-static.js"; |  | ||||||
| import "./gen-icons-json.js"; | require("./clean.js"); | ||||||
| import "./rollup.js"; | require("./translations.js"); | ||||||
| import "./service-worker.js"; | require("./gen-icons-json.js"); | ||||||
| import "./translations.js"; | require("./gather-static.js"); | ||||||
| import "./webpack.js"; | require("./webpack.js"); | ||||||
|  | require("./service-worker.js"); | ||||||
|  | require("./entry-html.js"); | ||||||
|  | require("./rollup.js"); | ||||||
|  |  | ||||||
| gulp.task("gather-gallery-pages", async function gatherPages() { | gulp.task("gather-gallery-pages", async function gatherPages() { | ||||||
|   const pageDir = path.resolve(paths.gallery_dir, "src/pages"); |   const pageDir = path.resolve(paths.gallery_dir, "src/pages"); | ||||||
|   const files = await glob(path.resolve(pageDir, "**/*")); |   const files = glob.sync(path.resolve(pageDir, "**/*")); | ||||||
|  |  | ||||||
|   const galleryBuild = path.resolve(paths.gallery_dir, "build"); |   const galleryBuild = path.resolve(paths.gallery_dir, "build"); | ||||||
|   fs.mkdirSync(galleryBuild, { recursive: true }); |   fs.mkdirSync(galleryBuild, { recursive: true }); | ||||||
| @@ -86,7 +89,9 @@ gulp.task("gather-gallery-pages", async function gatherPages() { | |||||||
|  |  | ||||||
|   // Generate sidebar |   // Generate sidebar | ||||||
|   const sidebarPath = path.resolve(paths.gallery_dir, "sidebar.js"); |   const sidebarPath = path.resolve(paths.gallery_dir, "sidebar.js"); | ||||||
|   const sidebar = (await import(sidebarPath)).default; |   // To make watch work during development | ||||||
|  |   delete require.cache[sidebarPath]; | ||||||
|  |   const sidebar = require(sidebarPath); | ||||||
|  |  | ||||||
|   const pagesToProcess = {}; |   const pagesToProcess = {}; | ||||||
|   for (const key of processed) { |   for (const key of processed) { | ||||||
| @@ -156,7 +161,7 @@ gulp.task( | |||||||
|       "gather-gallery-pages" |       "gather-gallery-pages" | ||||||
|     ), |     ), | ||||||
|     "copy-static-gallery", |     "copy-static-gallery", | ||||||
|     "gen-pages-gallery-dev", |     "gen-index-gallery-dev", | ||||||
|     gulp.parallel( |     gulp.parallel( | ||||||
|       env.useRollup() |       env.useRollup() | ||||||
|         ? "rollup-dev-server-gallery" |         ? "rollup-dev-server-gallery" | ||||||
| @@ -190,6 +195,6 @@ gulp.task( | |||||||
|     ), |     ), | ||||||
|     "copy-static-gallery", |     "copy-static-gallery", | ||||||
|     env.useRollup() ? "rollup-prod-gallery" : "webpack-prod-gallery", |     env.useRollup() ? "rollup-prod-gallery" : "webpack-prod-gallery", | ||||||
|     "gen-pages-gallery-prod" |     "gen-index-gallery-prod" | ||||||
|   ) |   ) | ||||||
| ); | ); | ||||||
|   | |||||||
| @@ -1,9 +1,9 @@ | |||||||
| // Gulp task to gather all static files. | // Gulp task to gather all static files. | ||||||
|  |  | ||||||
| import fs from "fs-extra"; | const gulp = require("gulp"); | ||||||
| import gulp from "gulp"; | const path = require("path"); | ||||||
| import path from "path"; | const fs = require("fs-extra"); | ||||||
| import paths from "../paths.cjs"; | const paths = require("../paths"); | ||||||
|  |  | ||||||
| const npmPath = (...parts) => | const npmPath = (...parts) => | ||||||
|   path.resolve(paths.polymer_dir, "node_modules", ...parts); |   path.resolve(paths.polymer_dir, "node_modules", ...parts); | ||||||
| @@ -111,10 +111,9 @@ gulp.task("copy-translations-supervisor", async () => { | |||||||
|   copyTranslations(staticDir); |   copyTranslations(staticDir); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| gulp.task("copy-static-supervisor", async () => { | gulp.task("copy-locale-data-supervisor", async () => { | ||||||
|   const staticDir = paths.hassio_output_static; |   const staticDir = paths.hassio_output_static; | ||||||
|   copyLocaleData(staticDir); |   copyLocaleData(staticDir); | ||||||
|   copyFonts(staticDir); |  | ||||||
| }); | }); | ||||||
|  |  | ||||||
| gulp.task("copy-static-app", async () => { | gulp.task("copy-static-app", async () => { | ||||||
|   | |||||||
| @@ -1,15 +1,17 @@ | |||||||
| import fs from "fs"; | const gulp = require("gulp"); | ||||||
| import gulp from "gulp"; | const path = require("path"); | ||||||
| import hash from "object-hash"; | const fs = require("fs"); | ||||||
| import path from "path"; | const hash = require("object-hash"); | ||||||
| import paths from "../paths.cjs"; |  | ||||||
|  |  | ||||||
| const ICON_PACKAGE_PATH = path.resolve("node_modules/@mdi/svg/"); | const ICON_PACKAGE_PATH = path.resolve( | ||||||
|  |   __dirname, | ||||||
|  |   "../../node_modules/@mdi/svg/" | ||||||
|  | ); | ||||||
| const META_PATH = path.resolve(ICON_PACKAGE_PATH, "meta.json"); | const META_PATH = path.resolve(ICON_PACKAGE_PATH, "meta.json"); | ||||||
| const PACKAGE_PATH = path.resolve(ICON_PACKAGE_PATH, "package.json"); | const PACKAGE_PATH = path.resolve(ICON_PACKAGE_PATH, "package.json"); | ||||||
| const ICON_PATH = path.resolve(ICON_PACKAGE_PATH, "svg"); | const ICON_PATH = path.resolve(ICON_PACKAGE_PATH, "svg"); | ||||||
| const OUTPUT_DIR = path.resolve(paths.build_dir, "mdi"); | const OUTPUT_DIR = path.resolve(__dirname, "../../build/mdi"); | ||||||
| const REMOVED_ICONS_PATH = new URL("../removedIcons.json", import.meta.url); | const REMOVED_ICONS_PATH = path.resolve(__dirname, "../removedIcons.json"); | ||||||
|  |  | ||||||
| const encoding = "utf8"; | const encoding = "utf8"; | ||||||
|  |  | ||||||
| @@ -132,11 +134,11 @@ gulp.task("gen-icons-json", (done) => { | |||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   const file = fs.readFileSync(PACKAGE_PATH, { encoding }); |   const file = fs.readFileSync(PACKAGE_PATH, { encoding }); | ||||||
|   const packageMeta = JSON.parse(file); |   const package = JSON.parse(file); | ||||||
|  |  | ||||||
|   fs.writeFileSync( |   fs.writeFileSync( | ||||||
|     path.resolve(OUTPUT_DIR, "iconMetadata.json"), |     path.resolve(OUTPUT_DIR, "iconMetadata.json"), | ||||||
|     JSON.stringify({ version: packageMeta.version, parts }) |     JSON.stringify({ version: package.version, parts }) | ||||||
|   ); |   ); | ||||||
|  |  | ||||||
|   fs.writeFileSync( |   fs.writeFileSync( | ||||||
|   | |||||||
| @@ -1,13 +1,15 @@ | |||||||
| import gulp from "gulp"; | const gulp = require("gulp"); | ||||||
| import env from "../env.cjs"; |  | ||||||
| import "./clean.js"; | const env = require("../env"); | ||||||
| import "./compress.js"; |  | ||||||
| import "./entry-html.js"; | require("./clean.js"); | ||||||
| import "./gather-static.js"; | require("./gen-icons-json.js"); | ||||||
| import "./gen-icons-json.js"; | require("./webpack.js"); | ||||||
| import "./rollup.js"; | require("./compress.js"); | ||||||
| import "./translations.js"; | require("./rollup.js"); | ||||||
| import "./webpack.js"; | require("./gather-static.js"); | ||||||
|  | require("./translations.js"); | ||||||
|  | require("./gen-icons-json.js"); | ||||||
|  |  | ||||||
| gulp.task( | gulp.task( | ||||||
|   "develop-hassio", |   "develop-hassio", | ||||||
| @@ -17,11 +19,11 @@ gulp.task( | |||||||
|     }, |     }, | ||||||
|     "clean-hassio", |     "clean-hassio", | ||||||
|     "gen-dummy-icons-json", |     "gen-dummy-icons-json", | ||||||
|     "gen-pages-hassio-dev", |     "gen-index-hassio-dev", | ||||||
|     "build-supervisor-translations", |     "build-supervisor-translations", | ||||||
|     "copy-translations-supervisor", |     "copy-translations-supervisor", | ||||||
|     "build-locale-data", |     "build-locale-data", | ||||||
|     "copy-static-supervisor", |     "copy-locale-data-supervisor", | ||||||
|     env.useRollup() ? "rollup-watch-hassio" : "webpack-watch-hassio" |     env.useRollup() ? "rollup-watch-hassio" : "webpack-watch-hassio" | ||||||
|   ) |   ) | ||||||
| ); | ); | ||||||
| @@ -37,10 +39,10 @@ gulp.task( | |||||||
|     "build-supervisor-translations", |     "build-supervisor-translations", | ||||||
|     "copy-translations-supervisor", |     "copy-translations-supervisor", | ||||||
|     "build-locale-data", |     "build-locale-data", | ||||||
|     "copy-static-supervisor", |     "copy-locale-data-supervisor", | ||||||
|     env.useRollup() ? "rollup-prod-hassio" : "webpack-prod-hassio", |     env.useRollup() ? "rollup-prod-hassio" : "webpack-prod-hassio", | ||||||
|     "gen-pages-hassio-prod", |     "gen-index-hassio-prod", | ||||||
|     ...// Don't compress running tests |     ...// Don't compress running tests | ||||||
|     (env.isTestBuild() ? [] : ["compress-hassio"]) |     (env.isTest() ? [] : ["compress-hassio"]) | ||||||
|   ) |   ) | ||||||
| ); | ); | ||||||
|   | |||||||
| @@ -1,23 +1,24 @@ | |||||||
| import { deleteSync } from "del"; | const del = import("del"); | ||||||
| import fs from "fs"; | const path = require("path"); | ||||||
| import gulp from "gulp"; | const gulp = require("gulp"); | ||||||
| import path from "path"; | const fs = require("fs"); | ||||||
| import paths from "../paths.cjs"; | const paths = require("../paths"); | ||||||
|  |  | ||||||
| const outDir = "build/locale-data"; | const outDir = "build/locale-data"; | ||||||
|  |  | ||||||
| gulp.task("clean-locale-data", async () => deleteSync([outDir])); | gulp.task("clean-locale-data", async () => (await del).deleteSync([outDir])); | ||||||
|  |  | ||||||
| gulp.task("ensure-locale-data-build-dir", async () => { | gulp.task("ensure-locale-data-build-dir", (done) => { | ||||||
|   fs.mkdirSync(outDir, { recursive: true }); |   if (!fs.existsSync(outDir)) { | ||||||
|  |     fs.mkdirSync(outDir, { recursive: true }); | ||||||
|  |   } | ||||||
|  |   done(); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| const modules = { | const modules = { | ||||||
|   "intl-relativetimeformat": "RelativeTimeFormat", |   "intl-relativetimeformat": "RelativeTimeFormat", | ||||||
|   "intl-datetimeformat": "DateTimeFormat", |   "intl-datetimeformat": "DateTimeFormat", | ||||||
|   "intl-numberformat": "NumberFormat", |   "intl-numberformat": "NumberFormat", | ||||||
|   "intl-displaynames": "DisplayNames", |  | ||||||
|   "intl-listformat": "ListFormat", |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| gulp.task("create-locale-data", (done) => { | gulp.task("create-locale-data", (done) => { | ||||||
| @@ -29,14 +30,11 @@ gulp.task("create-locale-data", (done) => { | |||||||
|   Object.entries(modules).forEach(([module, className]) => { |   Object.entries(modules).forEach(([module, className]) => { | ||||||
|     Object.keys(translationMeta).forEach((lang) => { |     Object.keys(translationMeta).forEach((lang) => { | ||||||
|       try { |       try { | ||||||
|         const localeData = fs |         const localeData = String( | ||||||
|           .readFileSync( |           fs.readFileSync( | ||||||
|             path.resolve( |             require.resolve(`@formatjs/${module}/locale-data/${lang}.js`) | ||||||
|               paths.polymer_dir, |  | ||||||
|               `node_modules/@formatjs/${module}/locale-data/${lang}.js` |  | ||||||
|             ), |  | ||||||
|             "utf-8" |  | ||||||
|           ) |           ) | ||||||
|  |         ) | ||||||
|           .replace( |           .replace( | ||||||
|             new RegExp( |             new RegExp( | ||||||
|               `\\/\\*\\s*@generated\\s*\\*\\/\\s*\\/\\/\\s*prettier-ignore\\s*if\\s*\\(Intl\\.${className}\\s*&&\\s*typeof\\s*Intl\\.${className}\\.__addLocaleData\\s*===\\s*'function'\\)\\s*{\\s*Intl\\.${className}\\.__addLocaleData\\(`, |               `\\/\\*\\s*@generated\\s*\\*\\/\\s*\\/\\/\\s*prettier-ignore\\s*if\\s*\\(Intl\\.${className}\\s*&&\\s*typeof\\s*Intl\\.${className}\\.__addLocaleData\\s*===\\s*'function'\\)\\s*{\\s*Intl\\.${className}\\.__addLocaleData\\(`, | ||||||
| @@ -47,13 +45,15 @@ gulp.task("create-locale-data", (done) => { | |||||||
|           .replace(/\)\s*}/im, ""); |           .replace(/\)\s*}/im, ""); | ||||||
|         // make sure we have valid JSON |         // make sure we have valid JSON | ||||||
|         JSON.parse(localeData); |         JSON.parse(localeData); | ||||||
|         fs.mkdirSync(path.join(outDir, module), { recursive: true }); |         if (!fs.existsSync(path.join(outDir, module))) { | ||||||
|  |           fs.mkdirSync(path.join(outDir, module), { recursive: true }); | ||||||
|  |         } | ||||||
|         fs.writeFileSync( |         fs.writeFileSync( | ||||||
|           path.join(outDir, `${module}/${lang}.json`), |           path.join(outDir, `${module}/${lang}.json`), | ||||||
|           localeData |           localeData | ||||||
|         ); |         ); | ||||||
|       } catch (e) { |       } catch (e) { | ||||||
|         if (e.code !== "ENOENT") { |         if (e.code !== "MODULE_NOT_FOUND") { | ||||||
|           throw e; |           throw e; | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|   | |||||||
| @@ -1,14 +1,13 @@ | |||||||
| // Tasks to run Rollup | // Tasks to run Rollup | ||||||
|  | const path = require("path"); | ||||||
| import log from "fancy-log"; | const gulp = require("gulp"); | ||||||
| import gulp from "gulp"; | const rollup = require("rollup"); | ||||||
| import http from "http"; | const handler = require("serve-handler"); | ||||||
| import open from "open"; | const http = require("http"); | ||||||
| import path from "path"; | const log = require("fancy-log"); | ||||||
| import { rollup } from "rollup"; | const open = require("open"); | ||||||
| import handler from "serve-handler"; | const rollupConfig = require("../rollup"); | ||||||
| import paths from "../paths.cjs"; | const paths = require("../paths"); | ||||||
| import rollupConfig from "../rollup.cjs"; |  | ||||||
|  |  | ||||||
| const bothBuilds = (createConfigFunc, params) => | const bothBuilds = (createConfigFunc, params) => | ||||||
|   gulp.series( |   gulp.series( | ||||||
| @@ -47,7 +46,7 @@ function createServer(serveOptions) { | |||||||
|   ); |   ); | ||||||
| } | } | ||||||
|  |  | ||||||
| function watchRollup(createConfig, extraWatchSrc = [], serveOptions = null) { | function watchRollup(createConfig, extraWatchSrc = [], serveOptions) { | ||||||
|   const { inputOptions, outputOptions } = createConfig({ |   const { inputOptions, outputOptions } = createConfig({ | ||||||
|     isProdBuild: false, |     isProdBuild: false, | ||||||
|     latestBuild: true, |     latestBuild: true, | ||||||
|   | |||||||
| @@ -1,12 +1,11 @@ | |||||||
| // Generate service worker. | // Generate service worker. | ||||||
| // Based on manifest, create a file with the content as service_worker.js | // Based on manifest, create a file with the content as service_worker.js | ||||||
|  | const gulp = require("gulp"); | ||||||
| import fs from "fs-extra"; | const path = require("path"); | ||||||
| import gulp from "gulp"; | const fs = require("fs-extra"); | ||||||
| import path from "path"; | const workboxBuild = require("workbox-build"); | ||||||
| import sourceMapUrl from "source-map-url"; | const sourceMapUrl = require("source-map-url"); | ||||||
| import workboxBuild from "workbox-build"; | const paths = require("../paths.js"); | ||||||
| import paths from "../paths.cjs"; |  | ||||||
|  |  | ||||||
| const swDest = path.resolve(paths.app_output_root, "service_worker.js"); | const swDest = path.resolve(paths.app_output_root, "service_worker.js"); | ||||||
|  |  | ||||||
| @@ -29,9 +28,10 @@ self.addEventListener('install', (event) => { | |||||||
|  |  | ||||||
| gulp.task("gen-service-worker-app-prod", async () => { | gulp.task("gen-service-worker-app-prod", async () => { | ||||||
|   // Read bundled source file |   // Read bundled source file | ||||||
|   const bundleManifestLatest = fs.readJsonSync( |   const bundleManifestLatest = require(path.resolve( | ||||||
|     path.resolve(paths.app_output_latest, "manifest.json") |     paths.app_output_latest, | ||||||
|   ); |     "manifest.json" | ||||||
|  |   )); | ||||||
|   let serviceWorkerContent = fs.readFileSync( |   let serviceWorkerContent = fs.readFileSync( | ||||||
|     paths.app_output_root + bundleManifestLatest["service_worker.js"], |     paths.app_output_root + bundleManifestLatest["service_worker.js"], | ||||||
|     "utf-8" |     "utf-8" | ||||||
| @@ -46,9 +46,10 @@ gulp.task("gen-service-worker-app-prod", async () => { | |||||||
|   ); |   ); | ||||||
|  |  | ||||||
|   // Remove ES5 |   // Remove ES5 | ||||||
|   const bundleManifestES5 = fs.readJsonSync( |   const bundleManifestES5 = require(path.resolve( | ||||||
|     path.resolve(paths.app_output_es5, "manifest.json") |     paths.app_output_es5, | ||||||
|   ); |     "manifest.json" | ||||||
|  |   )); | ||||||
|   fs.removeSync(paths.app_output_root + bundleManifestES5["service_worker.js"]); |   fs.removeSync(paths.app_output_root + bundleManifestES5["service_worker.js"]); | ||||||
|   fs.removeSync( |   fs.removeSync( | ||||||
|     paths.app_output_root + bundleManifestES5["service_worker.js.map"] |     paths.app_output_root + bundleManifestES5["service_worker.js.map"] | ||||||
|   | |||||||
| @@ -1,24 +1,19 @@ | |||||||
| import { createHash } from "crypto"; | const del = import("del"); | ||||||
| import { deleteSync } from "del"; | const crypto = require("crypto"); | ||||||
| import { | const path = require("path"); | ||||||
|   mkdirSync, | const source = require("vinyl-source-stream"); | ||||||
|   readdirSync, | const vinylBuffer = require("vinyl-buffer"); | ||||||
|   readFileSync, | const gulp = require("gulp"); | ||||||
|   renameSync, | const fs = require("fs"); | ||||||
|   writeFile, | const flatmap = require("gulp-flatmap"); | ||||||
| } from "fs"; | const merge = require("gulp-merge-json"); | ||||||
| import gulp from "gulp"; | const rename = require("gulp-rename"); | ||||||
| import flatmap from "gulp-flatmap"; | const transform = require("gulp-json-transform"); | ||||||
| import transform from "gulp-json-transform"; | const { mapFiles } = require("../util"); | ||||||
| import merge from "gulp-merge-json"; | const env = require("../env"); | ||||||
| import rename from "gulp-rename"; | const paths = require("../paths"); | ||||||
| import path from "path"; |  | ||||||
| import vinylBuffer from "vinyl-buffer"; | require("./fetch-nightly-translations"); | ||||||
| import source from "vinyl-source-stream"; |  | ||||||
| import env from "../env.cjs"; |  | ||||||
| import paths from "../paths.cjs"; |  | ||||||
| import { mapFiles } from "../util.cjs"; |  | ||||||
| import "./fetch-nightly-translations.js"; |  | ||||||
|  |  | ||||||
| const inFrontendDir = "translations/frontend"; | const inFrontendDir = "translations/frontend"; | ||||||
| const inBackendDir = "translations/backend"; | const inBackendDir = "translations/backend"; | ||||||
| @@ -38,12 +33,7 @@ gulp.task( | |||||||
|  |  | ||||||
| // Panel translations which should be split from the core translations. | // Panel translations which should be split from the core translations. | ||||||
| const TRANSLATION_FRAGMENTS = Object.keys( | const TRANSLATION_FRAGMENTS = Object.keys( | ||||||
|   JSON.parse( |   require("../../src/translations/en.json").ui.panel | ||||||
|     readFileSync( |  | ||||||
|       path.resolve(paths.polymer_dir, "src/translations/en.json"), |  | ||||||
|       "utf-8" |  | ||||||
|     ) |  | ||||||
|   ).ui.panel |  | ||||||
| ); | ); | ||||||
|  |  | ||||||
| function recursiveFlatten(prefix, data) { | function recursiveFlatten(prefix, data) { | ||||||
| @@ -130,14 +120,17 @@ function lokaliseTransform(data, original, file) { | |||||||
|   return output; |   return output; | ||||||
| } | } | ||||||
|  |  | ||||||
| gulp.task("clean-translations", async () => deleteSync([workDir])); | gulp.task("clean-translations", async () => (await del).deleteSync([workDir])); | ||||||
|  |  | ||||||
| gulp.task("ensure-translations-build-dir", async () => { | gulp.task("ensure-translations-build-dir", (done) => { | ||||||
|   mkdirSync(workDir, { recursive: true }); |   if (!fs.existsSync(workDir)) { | ||||||
|  |     fs.mkdirSync(workDir, { recursive: true }); | ||||||
|  |   } | ||||||
|  |   done(); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| gulp.task("create-test-metadata", (cb) => { | gulp.task("create-test-metadata", (cb) => { | ||||||
|   writeFile( |   fs.writeFile( | ||||||
|     workDir + "/testMetadata.json", |     workDir + "/testMetadata.json", | ||||||
|     JSON.stringify({ |     JSON.stringify({ | ||||||
|       test: { |       test: { | ||||||
| @@ -310,14 +303,15 @@ const fingerprints = {}; | |||||||
|  |  | ||||||
| gulp.task("build-translation-fingerprints", () => { | gulp.task("build-translation-fingerprints", () => { | ||||||
|   // Fingerprint full file of each language |   // Fingerprint full file of each language | ||||||
|   const files = readdirSync(fullDir); |   const files = fs.readdirSync(fullDir); | ||||||
|  |  | ||||||
|   for (let i = 0; i < files.length; i++) { |   for (let i = 0; i < files.length; i++) { | ||||||
|     fingerprints[files[i].split(".")[0]] = { |     fingerprints[files[i].split(".")[0]] = { | ||||||
|       // In dev we create fake hashes |       // In dev we create fake hashes | ||||||
|       hash: env.isProdBuild() |       hash: env.isProdBuild() | ||||||
|         ? createHash("md5") |         ? crypto | ||||||
|             .update(readFileSync(path.join(fullDir, files[i]), "utf-8")) |             .createHash("md5") | ||||||
|  |             .update(fs.readFileSync(path.join(fullDir, files[i]), "utf-8")) | ||||||
|             .digest("hex") |             .digest("hex") | ||||||
|         : "dev", |         : "dev", | ||||||
|     }; |     }; | ||||||
| @@ -333,7 +327,7 @@ gulp.task("build-translation-fingerprints", () => { | |||||||
|         throw new Error(`Unable to find hash for ${filename}`); |         throw new Error(`Unable to find hash for ${filename}`); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       renameSync( |       fs.renameSync( | ||||||
|         filename, |         filename, | ||||||
|         `${parsed.dir}/${parsed.name}-${fingerprints[parsed.name].hash}${ |         `${parsed.dir}/${parsed.name}-${fingerprints[parsed.name].hash}${ | ||||||
|           parsed.ext |           parsed.ext | ||||||
|   | |||||||
| @@ -1,7 +1,8 @@ | |||||||
| import gulp from "gulp"; | // Tasks to run Rollup | ||||||
| import { startDevServer } from "@web/dev-server"; | const gulp = require("gulp"); | ||||||
|  | const { startDevServer } = require("@web/dev-server"); | ||||||
|  |  | ||||||
| gulp.task("wds-watch-app", async () => { | gulp.task("wds-watch-app", () => { | ||||||
|   startDevServer({ |   startDevServer({ | ||||||
|     config: { |     config: { | ||||||
|       watch: true, |       watch: true, | ||||||
|   | |||||||
| @@ -1,20 +1,18 @@ | |||||||
| // Tasks to run webpack. | // Tasks to run webpack. | ||||||
|  | const fs = require("fs"); | ||||||
| import log from "fancy-log"; | const gulp = require("gulp"); | ||||||
| import fs from "fs"; | const webpack = require("webpack"); | ||||||
| import gulp from "gulp"; | const WebpackDevServer = require("webpack-dev-server"); | ||||||
| import path from "path"; | const log = require("fancy-log"); | ||||||
| import webpack from "webpack"; | const path = require("path"); | ||||||
| import WebpackDevServer from "webpack-dev-server"; | const paths = require("../paths"); | ||||||
| import env from "../env.cjs"; | const { | ||||||
| import paths from "../paths.cjs"; |  | ||||||
| import { |  | ||||||
|   createAppConfig, |   createAppConfig, | ||||||
|   createCastConfig, |  | ||||||
|   createDemoConfig, |   createDemoConfig, | ||||||
|   createGalleryConfig, |   createCastConfig, | ||||||
|   createHassioConfig, |   createHassioConfig, | ||||||
| } from "../webpack.cjs"; |   createGalleryConfig, | ||||||
|  | } = require("../webpack"); | ||||||
|  |  | ||||||
| const bothBuilds = (createConfigFunc, params) => [ | const bothBuilds = (createConfigFunc, params) => [ | ||||||
|   createConfigFunc({ ...params, latestBuild: true }), |   createConfigFunc({ ...params, latestBuild: true }), | ||||||
| @@ -106,8 +104,6 @@ gulp.task("webpack-prod-app", () => | |||||||
|   prodBuild( |   prodBuild( | ||||||
|     bothBuilds(createAppConfig, { |     bothBuilds(createAppConfig, { | ||||||
|       isProdBuild: true, |       isProdBuild: true, | ||||||
|       isStatsBuild: env.isStatsBuild(), |  | ||||||
|       isTestBuild: env.isTestBuild(), |  | ||||||
|     }) |     }) | ||||||
|   ) |   ) | ||||||
| ); | ); | ||||||
| @@ -165,8 +161,6 @@ gulp.task("webpack-prod-hassio", () => | |||||||
|   prodBuild( |   prodBuild( | ||||||
|     bothBuilds(createHassioConfig, { |     bothBuilds(createHassioConfig, { | ||||||
|       isProdBuild: true, |       isProdBuild: true, | ||||||
|       isStatsBuild: env.isStatsBuild(), |  | ||||||
|       isTestBuild: env.isTestBuild(), |  | ||||||
|     }) |     }) | ||||||
|   ) |   ) | ||||||
| ); | ); | ||||||
|   | |||||||
| @@ -1,59 +0,0 @@ | |||||||
| #!/usr/bin/env node |  | ||||||
| // Script to print Babel plugins and Core JS polyfills that will be used by browserslist environments |  | ||||||
|  |  | ||||||
| import { version as babelVersion } from "@babel/core"; |  | ||||||
| import presetEnv from "@babel/preset-env"; |  | ||||||
| import compilationTargets from "@babel/helper-compilation-targets"; |  | ||||||
| import coreJSCompat from "core-js-compat"; |  | ||||||
| import { logPlugin } from "@babel/preset-env/lib/debug.js"; |  | ||||||
| import { babelOptions } from "./bundle.cjs"; |  | ||||||
|  |  | ||||||
| const detailsOpen = (heading) => |  | ||||||
|   `<details>\n<summary><h4>${heading}</h4></summary>\n`; |  | ||||||
| const detailsClose = "</details>\n"; |  | ||||||
|  |  | ||||||
| const dummyAPI = { |  | ||||||
|   version: babelVersion, |  | ||||||
|   assertVersion: () => {}, |  | ||||||
|   caller: (callback) => |  | ||||||
|     callback({ |  | ||||||
|       name: "Dummy Bundler", |  | ||||||
|       supportsStaticESM: true, |  | ||||||
|       supportsDynamicImport: true, |  | ||||||
|       supportsTopLevelAwait: true, |  | ||||||
|       supportsExportNamespaceFrom: true, |  | ||||||
|     }), |  | ||||||
|   targets: () => ({}), |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| for (const buildType of ["Modern", "Legacy"]) { |  | ||||||
|   const browserslistEnv = buildType.toLowerCase(); |  | ||||||
|   const babelOpts = babelOptions({ latestBuild: browserslistEnv === "modern" }); |  | ||||||
|   const presetEnvOpts = babelOpts.presets[0][1]; |  | ||||||
|  |  | ||||||
|   // Invoking preset-env in debug mode will log the included plugins |  | ||||||
|   console.log(detailsOpen(`${buildType} Build Babel Plugins`)); |  | ||||||
|   presetEnv.default(dummyAPI, { |  | ||||||
|     ...presetEnvOpts, |  | ||||||
|     browserslistEnv, |  | ||||||
|     debug: true, |  | ||||||
|   }); |  | ||||||
|   console.log(detailsClose); |  | ||||||
|  |  | ||||||
|   // Manually log the Core-JS polyfills using the same technique |  | ||||||
|   if (presetEnvOpts.useBuiltIns) { |  | ||||||
|     console.log(detailsOpen(`${buildType} Build Core-JS Polyfills`)); |  | ||||||
|     const targets = compilationTargets.default(babelOpts?.targets, { |  | ||||||
|       browserslistEnv, |  | ||||||
|     }); |  | ||||||
|     const polyfillList = coreJSCompat({ targets }).list; |  | ||||||
|     console.log( |  | ||||||
|       "The following %i polyfills may be injected by Babel:\n", |  | ||||||
|       polyfillList.length |  | ||||||
|     ); |  | ||||||
|     for (const polyfill of polyfillList) { |  | ||||||
|       logPlugin(polyfill, targets, coreJSCompat.data); |  | ||||||
|     } |  | ||||||
|     console.log(detailsClose); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @@ -1 +1,30 @@ | |||||||
| [] | [ | ||||||
|  |   { | ||||||
|  |     "path": "M20,20H7A2,2 0 0,1 5,18V8.94L2.23,5.64C2.09,5.47 2,5.24 2,5A1,1 0 0,1 3,4H20A2,2 0 0,1 22,6V18A2,2 0 0,1 20,20M8.5,7A0.5,0.5 0 0,0 8,7.5V8.5A0.5,0.5 0 0,0 8.5,9H18.5A0.5,0.5 0 0,0 19,8.5V7.5A0.5,0.5 0 0,0 18.5,7H8.5M8.5,11A0.5,0.5 0 0,0 8,11.5V12.5A0.5,0.5 0 0,0 8.5,13H18.5A0.5,0.5 0 0,0 19,12.5V11.5A0.5,0.5 0 0,0 18.5,11H8.5M8.5,15A0.5,0.5 0 0,0 8,15.5V16.5A0.5,0.5 0 0,0 8.5,17H13.5A0.5,0.5 0 0,0 14,16.5V15.5A0.5,0.5 0 0,0 13.5,15H8.5Z", | ||||||
|  |     "name": "android-messages" | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "path": "M4,6H2V20A2,2 0 0,0 4,22H18V20H4V6M20,2H8A2,2 0 0,0 6,4V16A2,2 0 0,0 8,18H20A2,2 0 0,0 22,16V4A2,2 0 0,0 20,2M20,12L17.5,10.5L15,12V4H20V12Z", | ||||||
|  |     "name": "book-variant-multiple" | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "path": "M21,14H3V4H21M21,2H3C1.89,2 1,2.89 1,4V16A2,2 0 0,0 3,18H10L8,21V22H16V21L14,18H21A2,2 0 0,0 23,16V4C23,2.89 22.1,2 21,2Z", | ||||||
|  |     "name": "desktop-mac" | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "path": "M21,14V4H3V14H21M21,2A2,2 0 0,1 23,4V16A2,2 0 0,1 21,18H14L16,21V22H8V21L10,18H3C1.89,18 1,17.1 1,16V4C1,2.89 1.89,2 3,2H21M4,5H15V10H4V5M16,5H20V7H16V5M20,8V13H16V8H20M4,11H9V13H4V11M10,11H15V13H10V11Z", | ||||||
|  |     "name": "desktop-mac-dashboard" | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "path": "M22,24L16.75,19L17.38,21H4.5A2.5,2.5 0 0,1 2,18.5V3.5A2.5,2.5 0 0,1 4.5,1H19.5A2.5,2.5 0 0,1 22,3.5V24M12,6.8C9.32,6.8 7.44,7.95 7.44,7.95C8.47,7.03 10.27,6.5 10.27,6.5L10.1,6.33C8.41,6.36 6.88,7.53 6.88,7.53C5.16,11.12 5.27,14.22 5.27,14.22C6.67,16.03 8.75,15.9 8.75,15.9L9.46,15C8.21,14.73 7.42,13.62 7.42,13.62C7.42,13.62 9.3,14.9 12,14.9C14.7,14.9 16.58,13.62 16.58,13.62C16.58,13.62 15.79,14.73 14.54,15L15.25,15.9C15.25,15.9 17.33,16.03 18.73,14.22C18.73,14.22 18.84,11.12 17.12,7.53C17.12,7.53 15.59,6.36 13.9,6.33L13.73,6.5C13.73,6.5 15.53,7.03 16.56,7.95C16.56,7.95 14.68,6.8 12,6.8M9.93,10.59C10.58,10.59 11.11,11.16 11.1,11.86C11.1,12.55 10.58,13.13 9.93,13.13C9.29,13.13 8.77,12.55 8.77,11.86C8.77,11.16 9.28,10.59 9.93,10.59M14.1,10.59C14.75,10.59 15.27,11.16 15.27,11.86C15.27,12.55 14.75,13.13 14.1,13.13C13.46,13.13 12.94,12.55 12.94,11.86C12.94,11.16 13.45,10.59 14.1,10.59Z", | ||||||
|  |     "name": "discord" | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "path": "M8.06,7.78C7.5,7.78 7.17,7.73 7.08,7.64L6.66,13.73C7.19,14.05 7.88,14.3 8.72,14.5C9.56,14.71 10.78,14.77 12.38,14.67C13.97,14.58 15.63,14.23 17.34,13.64L16.55,4.22C15.67,5.09 14.38,5.91 12.66,6.66C11.13,7.31 9.81,7.69 8.72,7.78H8.06M7.97,5.34C7.28,5.94 7,6.34 7.13,6.56C7.22,6.78 7.7,6.84 8.58,6.75C9.67,6.66 10.91,6.31 12.28,5.72C13.22,5.31 14.03,4.88 14.72,4.41C15.41,3.94 15.88,3.55 16.13,3.23C16.38,2.92 16.47,2.7 16.41,2.58C16.34,2.42 16.03,2.34 15.47,2.34C14.34,2.34 12.94,2.7 11.25,3.42C9.81,4.05 8.72,4.69 7.97,5.34M17.34,2.2C17.41,2.33 17.44,2.47 17.44,2.63L18.61,17C18.61,18.73 18,20.09 16.83,21.07C15.64,22.05 14.03,22.55 12,22.55C10,22.55 8.4,22.04 7.2,21C6,20 5.39,18.64 5.39,16.92L6.09,6.47C6.09,6.22 6.2,5.94 6.42,5.63C6.64,5.31 6.84,5.06 7.03,4.88L7.36,4.59C8.33,3.78 9.5,3.08 10.88,2.5C11.81,2.08 12.73,1.77 13.62,1.57C14.5,1.37 15.3,1.3 16,1.38C16.71,1.46 17.16,1.73 17.34,2.2Z", | ||||||
|  |     "name": "google-home" | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "path": "M19.25,19H4.75V3H19.25M14,22H10V21H14M18,0H6A3,3 0 0,0 3,3V21A3,3 0 0,0 6,24H18A3,3 0 0,0 21,21V3A3,3 0 0,0 18,0Z", | ||||||
|  |     "name": "tablet-android" | ||||||
|  |   } | ||||||
|  | ] | ||||||
|   | |||||||
| @@ -103,7 +103,7 @@ module.exports = function (opts = {}) { | |||||||
|         } |         } | ||||||
|         delete optionsObject.type; |         delete optionsObject.type; | ||||||
| 
 | 
 | ||||||
|         if (!/^.*\//.test(workerFile)) { |         if (!new RegExp("^.*/").test(workerFile)) { | ||||||
|           this.warn( |           this.warn( | ||||||
|             `Paths passed to the Worker constructor must be relative or absolute, i.e. start with /, ./ or ../ (just like dynamic import!). Ignoring "${workerFile}".` |             `Paths passed to the Worker constructor must be relative or absolute, i.e. start with /, ./ or ../ (just like dynamic import!). Ignoring "${workerFile}".` | ||||||
|           ); |           ); | ||||||
| @@ -3,18 +3,18 @@ const path = require("path"); | |||||||
| const commonjs = require("@rollup/plugin-commonjs"); | const commonjs = require("@rollup/plugin-commonjs"); | ||||||
| const resolve = require("@rollup/plugin-node-resolve"); | const resolve = require("@rollup/plugin-node-resolve"); | ||||||
| const json = require("@rollup/plugin-json"); | const json = require("@rollup/plugin-json"); | ||||||
| const { babel } = require("@rollup/plugin-babel"); | const babel = require("@rollup/plugin-babel").babel; | ||||||
| const replace = require("@rollup/plugin-replace"); | const replace = require("@rollup/plugin-replace"); | ||||||
| const visualizer = require("rollup-plugin-visualizer"); | const visualizer = require("rollup-plugin-visualizer"); | ||||||
| const { string } = require("rollup-plugin-string"); | const { string } = require("rollup-plugin-string"); | ||||||
| const { terser } = require("rollup-plugin-terser"); | const { terser } = require("rollup-plugin-terser"); | ||||||
| const manifest = require("./rollup-plugins/manifest-plugin.cjs"); | const manifest = require("./rollup-plugins/manifest-plugin"); | ||||||
| const worker = require("./rollup-plugins/worker-plugin.cjs"); | const worker = require("./rollup-plugins/worker-plugin"); | ||||||
| const dontHashPlugin = require("./rollup-plugins/dont-hash-plugin.cjs"); | const dontHashPlugin = require("./rollup-plugins/dont-hash-plugin"); | ||||||
| const ignore = require("./rollup-plugins/ignore-plugin.cjs"); | const ignore = require("./rollup-plugins/ignore-plugin"); | ||||||
| 
 | 
 | ||||||
| const bundle = require("./bundle.cjs"); | const bundle = require("./bundle"); | ||||||
| const paths = require("./paths.cjs"); | const paths = require("./paths"); | ||||||
| 
 | 
 | ||||||
| const extensions = [".js", ".ts"]; | const extensions = [".js", ".ts"]; | ||||||
| 
 | 
 | ||||||
| @@ -39,18 +39,11 @@ const createRollupConfig = ({ | |||||||
|   inputOptions: { |   inputOptions: { | ||||||
|     input: entry, |     input: entry, | ||||||
|     // Some entry points contain no JavaScript. This setting silences a warning about that.
 |     // Some entry points contain no JavaScript. This setting silences a warning about that.
 | ||||||
|     // https://rollupjs.org/configuration-options/#preserveentrysignatures
 |     // https://rollupjs.org/guide/en/#preserveentrysignatures
 | ||||||
|     preserveEntrySignatures: false, |     preserveEntrySignatures: false, | ||||||
|     plugins: [ |     plugins: [ | ||||||
|       ignore({ |       ignore({ | ||||||
|         files: bundle |         files: bundle.emptyPackages({ latestBuild }), | ||||||
|           .emptyPackages({ latestBuild }) |  | ||||||
|           // TEMP HACK: Makes Rollup build work again
 |  | ||||||
|           .concat( |  | ||||||
|             require.resolve( |  | ||||||
|               "@webcomponents/scoped-custom-element-registry/scoped-custom-element-registry.min" |  | ||||||
|             ) |  | ||||||
|           ), |  | ||||||
|       }), |       }), | ||||||
|       resolve({ |       resolve({ | ||||||
|         extensions, |         extensions, | ||||||
| @@ -61,7 +54,7 @@ const createRollupConfig = ({ | |||||||
|       commonjs(), |       commonjs(), | ||||||
|       json(), |       json(), | ||||||
|       babel({ |       babel({ | ||||||
|         ...bundle.babelOptions({ latestBuild, isProdBuild }), |         ...bundle.babelOptions({ latestBuild }), | ||||||
|         extensions, |         extensions, | ||||||
|         babelHelpers: isWDS ? "inline" : "bundled", |         babelHelpers: isWDS ? "inline" : "bundled", | ||||||
|       }), |       }), | ||||||
| @@ -76,7 +69,7 @@ const createRollupConfig = ({ | |||||||
|         }), |         }), | ||||||
|       !isWDS && worker(), |       !isWDS && worker(), | ||||||
|       !isWDS && dontHashPlugin({ dontHash }), |       !isWDS && dontHashPlugin({ dontHash }), | ||||||
|       !isWDS && isProdBuild && terser(bundle.terserOptions({ latestBuild })), |       !isWDS && isProdBuild && terser(bundle.terserOptions(latestBuild)), | ||||||
|       !isWDS && |       !isWDS && | ||||||
|         isStatsBuild && |         isStatsBuild && | ||||||
|         visualizer({ |         visualizer({ | ||||||
| @@ -90,20 +83,20 @@ const createRollupConfig = ({ | |||||||
|    * @type { import("rollup").OutputOptions } |    * @type { import("rollup").OutputOptions } | ||||||
|    */ |    */ | ||||||
|   outputOptions: { |   outputOptions: { | ||||||
|     // https://rollupjs.org/configuration-options/#output-dir
 |     // https://rollupjs.org/guide/en/#outputdir
 | ||||||
|     dir: outputPath, |     dir: outputPath, | ||||||
|     // https://rollupjs.org/configuration-options/#output-format
 |     // https://rollupjs.org/guide/en/#outputformat
 | ||||||
|     format: latestBuild ? "es" : "systemjs", |     format: latestBuild ? "es" : "systemjs", | ||||||
|     // https://rollupjs.org/configuration-options/#output-externallivebindings
 |     // https://rollupjs.org/guide/en/#outputexternallivebindings
 | ||||||
|     externalLiveBindings: false, |     externalLiveBindings: false, | ||||||
|     // https://rollupjs.org/configuration-options/#output-entryfilenames
 |     // https://rollupjs.org/guide/en/#outputentryfilenames
 | ||||||
|     // https://rollupjs.org/configuration-options/#output-chunkfilenames
 |     // https://rollupjs.org/guide/en/#outputchunkfilenames
 | ||||||
|     // https://rollupjs.org/configuration-options/#output-assetfilenames
 |     // https://rollupjs.org/guide/en/#outputassetfilenames
 | ||||||
|     entryFileNames: |     entryFileNames: | ||||||
|       isProdBuild && !isStatsBuild ? "[name]-[hash].js" : "[name].js", |       isProdBuild && !isStatsBuild ? "[name]-[hash].js" : "[name].js", | ||||||
|     chunkFileNames: isProdBuild && !isStatsBuild ? "c.[hash].js" : "[name].js", |     chunkFileNames: isProdBuild && !isStatsBuild ? "c.[hash].js" : "[name].js", | ||||||
|     assetFileNames: isProdBuild && !isStatsBuild ? "a.[hash].js" : "[name].js", |     assetFileNames: isProdBuild && !isStatsBuild ? "a.[hash].js" : "[name].js", | ||||||
|     // https://rollupjs.org/configuration-options/#output-sourcemap
 |     // https://rollupjs.org/guide/en/#outputsourcemap
 | ||||||
|     sourcemap: isProdBuild ? true : "inline", |     sourcemap: isProdBuild ? true : "inline", | ||||||
|   }, |   }, | ||||||
| }); | }); | ||||||
| @@ -142,5 +135,4 @@ module.exports = { | |||||||
|   createCastConfig, |   createCastConfig, | ||||||
|   createHassioConfig, |   createHassioConfig, | ||||||
|   createGalleryConfig, |   createGalleryConfig, | ||||||
|   createRollupConfig, |  | ||||||
| }; | }; | ||||||
| @@ -4,8 +4,8 @@ const TerserPlugin = require("terser-webpack-plugin"); | |||||||
| const { WebpackManifestPlugin } = require("webpack-manifest-plugin"); | const { WebpackManifestPlugin } = require("webpack-manifest-plugin"); | ||||||
| const log = require("fancy-log"); | const log = require("fancy-log"); | ||||||
| const WebpackBar = require("webpackbar"); | const WebpackBar = require("webpackbar"); | ||||||
| const paths = require("./paths.cjs"); | const paths = require("./paths.js"); | ||||||
| const bundle = require("./bundle.cjs"); | const bundle = require("./bundle.js"); | ||||||
| 
 | 
 | ||||||
| class LogStartCompilePlugin { | class LogStartCompilePlugin { | ||||||
|   ignoredFirst = false; |   ignoredFirst = false; | ||||||
| @@ -22,7 +22,6 @@ class LogStartCompilePlugin { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const createWebpackConfig = ({ | const createWebpackConfig = ({ | ||||||
|   name, |  | ||||||
|   entry, |   entry, | ||||||
|   outputPath, |   outputPath, | ||||||
|   publicPath, |   publicPath, | ||||||
| @@ -30,7 +29,6 @@ const createWebpackConfig = ({ | |||||||
|   isProdBuild, |   isProdBuild, | ||||||
|   latestBuild, |   latestBuild, | ||||||
|   isStatsBuild, |   isStatsBuild, | ||||||
|   isTestBuild, |  | ||||||
|   isHassioBuild, |   isHassioBuild, | ||||||
|   dontHash, |   dontHash, | ||||||
| }) => { | }) => { | ||||||
| @@ -39,16 +37,10 @@ const createWebpackConfig = ({ | |||||||
|   } |   } | ||||||
|   const ignorePackages = bundle.ignorePackages({ latestBuild }); |   const ignorePackages = bundle.ignorePackages({ latestBuild }); | ||||||
|   return { |   return { | ||||||
|     name, |  | ||||||
|     mode: isProdBuild ? "production" : "development", |     mode: isProdBuild ? "production" : "development", | ||||||
|     target: `browserslist:${latestBuild ? "modern" : "legacy"}`, |     target: ["web", latestBuild ? "es2017" : "es5"], | ||||||
|     // For tests/CI, source maps are skipped to gain build speed
 |     devtool: isProdBuild | ||||||
|     // For production, generate source maps for accurate stack traces without source code
 |       ? "cheap-module-source-map" | ||||||
|     // For development, generate "cheap" versions that can map to original line numbers
 |  | ||||||
|     devtool: isTestBuild |  | ||||||
|       ? false |  | ||||||
|       : isProdBuild |  | ||||||
|       ? "nosources-source-map" |  | ||||||
|       : "eval-cheap-module-source-map", |       : "eval-cheap-module-source-map", | ||||||
|     entry, |     entry, | ||||||
|     node: false, |     node: false, | ||||||
| @@ -59,14 +51,11 @@ const createWebpackConfig = ({ | |||||||
|           use: { |           use: { | ||||||
|             loader: "babel-loader", |             loader: "babel-loader", | ||||||
|             options: { |             options: { | ||||||
|               ...bundle.babelOptions({ latestBuild, isProdBuild, isTestBuild }), |               ...bundle.babelOptions({ latestBuild }), | ||||||
|               cacheDirectory: !isProdBuild, |               cacheDirectory: !isProdBuild, | ||||||
|               cacheCompression: false, |               cacheCompression: false, | ||||||
|             }, |             }, | ||||||
|           }, |           }, | ||||||
|           resolve: { |  | ||||||
|             fullySpecified: false, |  | ||||||
|           }, |  | ||||||
|         }, |         }, | ||||||
|         { |         { | ||||||
|           test: /\.css$/, |           test: /\.css$/, | ||||||
| @@ -79,18 +68,11 @@ const createWebpackConfig = ({ | |||||||
|         new TerserPlugin({ |         new TerserPlugin({ | ||||||
|           parallel: true, |           parallel: true, | ||||||
|           extractComments: true, |           extractComments: true, | ||||||
|           terserOptions: bundle.terserOptions({ latestBuild, isTestBuild }), |           terserOptions: bundle.terserOptions(latestBuild), | ||||||
|         }), |         }), | ||||||
|       ], |       ], | ||||||
|       moduleIds: isProdBuild && !isStatsBuild ? "deterministic" : "named", |       moduleIds: isProdBuild && !isStatsBuild ? "deterministic" : "named", | ||||||
|       chunkIds: isProdBuild && !isStatsBuild ? "deterministic" : "named", |       chunkIds: isProdBuild && !isStatsBuild ? "deterministic" : "named", | ||||||
|       splitChunks: { |  | ||||||
|         // Disable splitting for web workers with ESM output
 |  | ||||||
|         // Imports of external chunks are broken
 |  | ||||||
|         chunks: latestBuild |  | ||||||
|           ? (chunk) => !chunk.canBeInitial() && !/^.+-worker$/.test(chunk.name) |  | ||||||
|           : undefined, |  | ||||||
|       }, |  | ||||||
|     }, |     }, | ||||||
|     plugins: [ |     plugins: [ | ||||||
|       !isStatsBuild && new WebpackBar({ fancy: !isProdBuild }), |       !isStatsBuild && new WebpackBar({ fancy: !isProdBuild }), | ||||||
| @@ -139,17 +121,6 @@ const createWebpackConfig = ({ | |||||||
|         ), |         ), | ||||||
|         path.resolve(paths.polymer_dir, "src/util/empty.js") |         path.resolve(paths.polymer_dir, "src/util/empty.js") | ||||||
|       ), |       ), | ||||||
|       // See `src/resources/intl-polyfill-legacy.ts` for explanation
 |  | ||||||
|       !latestBuild && |  | ||||||
|         new webpack.NormalModuleReplacementPlugin( |  | ||||||
|           new RegExp( |  | ||||||
|             path.resolve(paths.polymer_dir, "src/resources/intl-polyfill.ts") |  | ||||||
|           ), |  | ||||||
|           path.resolve( |  | ||||||
|             paths.polymer_dir, |  | ||||||
|             "src/resources/intl-polyfill-legacy.ts" |  | ||||||
|           ) |  | ||||||
|         ), |  | ||||||
|       !isProdBuild && new LogStartCompilePlugin(), |       !isProdBuild && new LogStartCompilePlugin(), | ||||||
|     ].filter(Boolean), |     ].filter(Boolean), | ||||||
|     resolve: { |     resolve: { | ||||||
| @@ -167,58 +138,31 @@ const createWebpackConfig = ({ | |||||||
|         "lit/polyfill-support$": "lit/polyfill-support.js", |         "lit/polyfill-support$": "lit/polyfill-support.js", | ||||||
|         "@lit-labs/virtualizer/layouts/grid": |         "@lit-labs/virtualizer/layouts/grid": | ||||||
|           "@lit-labs/virtualizer/layouts/grid.js", |           "@lit-labs/virtualizer/layouts/grid.js", | ||||||
|         "@lit-labs/virtualizer/polyfills/resize-observer-polyfill/ResizeObserver": |  | ||||||
|           "@lit-labs/virtualizer/polyfills/resize-observer-polyfill/ResizeObserver.js", |  | ||||||
|       }, |       }, | ||||||
|     }, |     }, | ||||||
|     output: { |     output: { | ||||||
|       module: latestBuild, |       filename: ({ chunk }) => { | ||||||
|       filename: ({ chunk }) => |         if (!isProdBuild || isStatsBuild || dontHash.has(chunk.name)) { | ||||||
|         !isProdBuild || isStatsBuild || dontHash.has(chunk.name) |           return `${chunk.name}.js`; | ||||||
|           ? "[name].js" |         } | ||||||
|           : "[name]-[contenthash].js", |         return `${chunk.name}.${chunk.hash.substr(0, 8)}.js`; | ||||||
|  |       }, | ||||||
|       chunkFilename: |       chunkFilename: | ||||||
|         isProdBuild && !isStatsBuild ? "[id]-[contenthash].js" : "[name].js", |         isProdBuild && !isStatsBuild ? "[chunkhash:8].js" : "[id].chunk.js", | ||||||
|       assetModuleFilename: |  | ||||||
|         isProdBuild && !isStatsBuild ? "[id]-[contenthash][ext]" : "[id][ext]", |  | ||||||
|       hashFunction: "xxhash64", |  | ||||||
|       hashDigest: "base64url", |  | ||||||
|       hashDigestLength: 11, // full length of 64 bit base64url
 |  | ||||||
|       path: outputPath, |       path: outputPath, | ||||||
|       publicPath, |       publicPath, | ||||||
|       // To silence warning in worker plugin
 |       // To silence warning in worker plugin
 | ||||||
|       globalObject: "self", |       globalObject: "self", | ||||||
|       // Since production source maps don't include sources, we need to point to them elsewhere
 |  | ||||||
|       // For dependencies, just provide the path (no source in browser)
 |  | ||||||
|       // Otherwise, point to the raw code on GitHub for browser to load
 |  | ||||||
|       devtoolModuleFilenameTemplate: |  | ||||||
|         !isTestBuild && isProdBuild |  | ||||||
|           ? (info) => { |  | ||||||
|               const sourcePath = info.resourcePath.replace(/^\.\//, ""); |  | ||||||
|               if ( |  | ||||||
|                 sourcePath.startsWith("node_modules") || |  | ||||||
|                 sourcePath.startsWith("webpack") |  | ||||||
|               ) { |  | ||||||
|                 return `no-source/${sourcePath}`; |  | ||||||
|               } |  | ||||||
|               return `${bundle.sourceMapURL()}/${sourcePath}`; |  | ||||||
|             } |  | ||||||
|           : undefined, |  | ||||||
|     }, |     }, | ||||||
|     experiments: { |     experiments: { | ||||||
|       outputModule: true, |       topLevelAwait: true, | ||||||
|     }, |     }, | ||||||
|   }; |   }; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const createAppConfig = ({ | const createAppConfig = ({ isProdBuild, latestBuild, isStatsBuild }) => | ||||||
|   isProdBuild, |  | ||||||
|   latestBuild, |  | ||||||
|   isStatsBuild, |  | ||||||
|   isTestBuild, |  | ||||||
| }) => |  | ||||||
|   createWebpackConfig( |   createWebpackConfig( | ||||||
|     bundle.config.app({ isProdBuild, latestBuild, isStatsBuild, isTestBuild }) |     bundle.config.app({ isProdBuild, latestBuild, isStatsBuild }) | ||||||
|   ); |   ); | ||||||
| 
 | 
 | ||||||
| const createDemoConfig = ({ isProdBuild, latestBuild, isStatsBuild }) => | const createDemoConfig = ({ isProdBuild, latestBuild, isStatsBuild }) => | ||||||
| @@ -229,20 +173,8 @@ const createDemoConfig = ({ isProdBuild, latestBuild, isStatsBuild }) => | |||||||
| const createCastConfig = ({ isProdBuild, latestBuild }) => | const createCastConfig = ({ isProdBuild, latestBuild }) => | ||||||
|   createWebpackConfig(bundle.config.cast({ isProdBuild, latestBuild })); |   createWebpackConfig(bundle.config.cast({ isProdBuild, latestBuild })); | ||||||
| 
 | 
 | ||||||
| const createHassioConfig = ({ | const createHassioConfig = ({ isProdBuild, latestBuild }) => | ||||||
|   isProdBuild, |   createWebpackConfig(bundle.config.hassio({ isProdBuild, latestBuild })); | ||||||
|   latestBuild, |  | ||||||
|   isStatsBuild, |  | ||||||
|   isTestBuild, |  | ||||||
| }) => |  | ||||||
|   createWebpackConfig( |  | ||||||
|     bundle.config.hassio({ |  | ||||||
|       isProdBuild, |  | ||||||
|       latestBuild, |  | ||||||
|       isStatsBuild, |  | ||||||
|       isTestBuild, |  | ||||||
|     }) |  | ||||||
|   ); |  | ||||||
| 
 | 
 | ||||||
| const createGalleryConfig = ({ isProdBuild, latestBuild }) => | const createGalleryConfig = ({ isProdBuild, latestBuild }) => | ||||||
|   createWebpackConfig(bundle.config.gallery({ isProdBuild, latestBuild })); |   createWebpackConfig(bundle.config.gallery({ isProdBuild, latestBuild })); | ||||||
| @@ -253,5 +185,4 @@ module.exports = { | |||||||
|   createCastConfig, |   createCastConfig, | ||||||
|   createHassioConfig, |   createHassioConfig, | ||||||
|   createGalleryConfig, |   createGalleryConfig, | ||||||
|   createWebpackConfig, |  | ||||||
| }; | }; | ||||||
| @@ -1,5 +1,5 @@ | |||||||
| import rollup from "../build-scripts/rollup.cjs"; | const rollup = require("../build-scripts/rollup.js"); | ||||||
| import env from "../build-scripts/env.cjs"; | const env = require("../build-scripts/env.js"); | ||||||
|  |  | ||||||
| const config = rollup.createCastConfig({ | const config = rollup.createCastConfig({ | ||||||
|   isProdBuild: env.isProdBuild(), |   isProdBuild: env.isProdBuild(), | ||||||
| @@ -7,4 +7,4 @@ const config = rollup.createCastConfig({ | |||||||
|   isStatsBuild: env.isStatsBuild(), |   isStatsBuild: env.isStatsBuild(), | ||||||
| }); | }); | ||||||
|  |  | ||||||
| export default { ...config.inputOptions, output: config.outputOptions }; | module.exports = { ...config.inputOptions, output: config.outputOptions }; | ||||||
|   | |||||||
| @@ -1,24 +0,0 @@ | |||||||
| <meta property="fb:app_id" content="338291289691179" /> |  | ||||||
| <meta property="og:title" content="Home Assistant Cast" /> |  | ||||||
| <meta property="og:site_name" content="Home Assistant Cast" /> |  | ||||||
| <meta property="og:url" content="https://cast.home-assistant.io/" /> |  | ||||||
| <meta property="og:type" content="website" /> |  | ||||||
| <meta |  | ||||||
|   property="og:description" |  | ||||||
|   content="Show Home Assistant on your Chromecast or Google Assistant devices with a screen." |  | ||||||
| /> |  | ||||||
| <meta |  | ||||||
|   property="og:image" |  | ||||||
|   content="https://cast.home-assistant.io/images/google-nest-hub.png" |  | ||||||
| /> |  | ||||||
| <meta name="twitter:card" content="summary_large_image" /> |  | ||||||
| <meta name="twitter:site" content="@home_assistant" /> |  | ||||||
| <meta name="twitter:title" content="Home Assistant Cast" /> |  | ||||||
| <meta |  | ||||||
|   name="twitter:description" |  | ||||||
|   content="Show Home Assistant on your Chromecast or Google Assistant devices with a screen." |  | ||||||
| /> |  | ||||||
| <meta |  | ||||||
|   name="twitter:image" |  | ||||||
|   content="https://cast.home-assistant.io/images/google-nest-hub.png" |  | ||||||
| /> |  | ||||||
| @@ -1,35 +0,0 @@ | |||||||
| <!DOCTYPE html> |  | ||||||
| <html> |  | ||||||
|   <head> |  | ||||||
|     <title>Home Assistant Cast</title> |  | ||||||
|     <link rel="manifest" href="/manifest.json" /> |  | ||||||
|     <link rel="icon" href="/images/ha-cast-icon.png" type="image/png" /> |  | ||||||
|     <%= renderTemplate("../../../src/html/_style_base.html.template") %> |  | ||||||
|     <style> |  | ||||||
|       body { |  | ||||||
|         background-color: #e5e5e5; |  | ||||||
|       } |  | ||||||
|     </style> |  | ||||||
|     <%= renderTemplate("_social_meta.html.template") %> |  | ||||||
|   </head> |  | ||||||
|   <body> |  | ||||||
|     <%= renderTemplate("../../../src/html/_js_base.html.template") %> |  | ||||||
|     <hc-connect></hc-connect> |  | ||||||
|     <script> |  | ||||||
|       <% for (const entry of latestEntryJS) { %> |  | ||||||
|         import("<%= entry %>"); |  | ||||||
|       <% } %> |  | ||||||
|       window.latestJS = true; |  | ||||||
|     </script> |  | ||||||
|     <%= renderTemplate("../../../src/html/_script_load_es5.html.template") %> |  | ||||||
|     <script> |  | ||||||
|     (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ |  | ||||||
|     (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), |  | ||||||
|     m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) |  | ||||||
|     })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); |  | ||||||
|  |  | ||||||
|     ga('create', 'UA-57927901-9', 'auto'); |  | ||||||
|     ga('send', 'pageview', location.pathname.includes("auth_callback") === -1 ? location.pathname : "/"); |  | ||||||
|     </script> |  | ||||||
|   </body> |  | ||||||
| </html> |  | ||||||
| @@ -3,7 +3,7 @@ | |||||||
|   <head> |   <head> | ||||||
|     <title>Home Assistant Cast - FAQ</title> |     <title>Home Assistant Cast - FAQ</title> | ||||||
|     <link rel="icon" href="/images/ha-cast-icon.png" type="image/png" /> |     <link rel="icon" href="/images/ha-cast-icon.png" type="image/png" /> | ||||||
|     <%= renderTemplate("../../../src/html/_style_base.html.template") %> |     <%= renderTemplate('_style_base') %> | ||||||
|     <style> |     <style> | ||||||
|       body { |       body { | ||||||
|         background-color: #e5e5e5; |         background-color: #e5e5e5; | ||||||
| @@ -35,14 +35,25 @@ | |||||||
|     /> |     /> | ||||||
|   </head> |   </head> | ||||||
|   <body> |   <body> | ||||||
|     <%= renderTemplate("../../../src/html/_js_base.html.template") %> |     <%= renderTemplate('_js_base') %> | ||||||
|  | 
 | ||||||
|     <script> |     <script> | ||||||
|       <% for (const entry of latestEntryJS) { %> |       import("<%= latestLauncherJS %>"); | ||||||
|         import("<%= entry %>"); |  | ||||||
|       <% } %> |  | ||||||
|       window.latestJS = true; |       window.latestJS = true; | ||||||
|     </script> |     </script> | ||||||
|     <%= renderTemplate("../../../src/html/_script_load_es5.html.template") %> | 
 | ||||||
|  |     <script> | ||||||
|  |       if (!window.latestJS) { | ||||||
|  |         <% if (useRollup) { %> | ||||||
|  |           _ls("/static/js/s.min.js").onload = function() { | ||||||
|  |             System.import("<%= es5LauncherJS %>"); | ||||||
|  |           }; | ||||||
|  |         <% } else { %> | ||||||
|  |           _ls("<%= es5LauncherJS %>"); | ||||||
|  |         <% } %> | ||||||
|  |       } | ||||||
|  |     </script> | ||||||
|  | 
 | ||||||
|     <hc-layout subtitle="FAQ"> |     <hc-layout subtitle="FAQ"> | ||||||
|       <style> |       <style> | ||||||
|         a { |         a { | ||||||
							
								
								
									
										57
									
								
								cast/src/html/launcher.html.template
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								cast/src/html/launcher.html.template
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | |||||||
|  | <!DOCTYPE html> | ||||||
|  | <html> | ||||||
|  |   <head> | ||||||
|  |     <title>Home Assistant Cast</title> | ||||||
|  |     <link rel="manifest" href="/manifest.json" /> | ||||||
|  |     <link rel="icon" href="/images/ha-cast-icon.png" type="image/png" /> | ||||||
|  |     <%= renderTemplate('_style_base') %> | ||||||
|  |     <style> | ||||||
|  |       body { | ||||||
|  |         background-color: #e5e5e5; | ||||||
|  |       } | ||||||
|  |     </style> | ||||||
|  |     <meta property="fb:app_id" content="338291289691179"> | ||||||
|  |     <meta property="og:title" content="Home Assistant Cast"> | ||||||
|  |     <meta property="og:site_name" content="Home Assistant Cast"> | ||||||
|  |     <meta property="og:url" content="https://cast.home-assistant.io/"> | ||||||
|  |     <meta property="og:type" content="website"> | ||||||
|  |     <meta property="og:description" content="Show Home Assistant on your Chromecast or Google Assistant devices with a screen."> | ||||||
|  |     <meta property="og:image" content="https://cast.home-assistant.io/images/google-nest-hub.png"> | ||||||
|  |     <meta name="twitter:card" content="summary_large_image"> | ||||||
|  |     <meta name="twitter:site" content="@home_assistant"> | ||||||
|  |     <meta name="twitter:title" content="Home Assistant Cast"> | ||||||
|  |     <meta name="twitter:description" content="Show Home Assistant on your Chromecast or Google Assistant devices with a screen."> | ||||||
|  |     <meta name="twitter:image" content="https://cast.home-assistant.io/images/google-nest-hub.png"> | ||||||
|  |   </head> | ||||||
|  |   <body> | ||||||
|  |     <%= renderTemplate('_js_base') %> | ||||||
|  |  | ||||||
|  |     <hc-connect></hc-connect> | ||||||
|  |  | ||||||
|  |     <script> | ||||||
|  |       import("<%= latestLauncherJS %>"); | ||||||
|  |       window.latestJS = true; | ||||||
|  |     </script> | ||||||
|  |  | ||||||
|  |     <script> | ||||||
|  |       if (!window.latestJS) { | ||||||
|  |         <% if (useRollup) { %> | ||||||
|  |           _ls("/static/js/s.min.js").onload = function() { | ||||||
|  |             System.import("<%= es5LauncherJS %>"); | ||||||
|  |           }; | ||||||
|  |         <% } else { %> | ||||||
|  |           _ls("<%= es5LauncherJS %>"); | ||||||
|  |         <% } %> | ||||||
|  |       } | ||||||
|  |     </script> | ||||||
|  |     <script> | ||||||
|  |     (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ | ||||||
|  |     (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), | ||||||
|  |     m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) | ||||||
|  |     })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); | ||||||
|  |  | ||||||
|  |     ga('create', 'UA-57927901-9', 'auto'); | ||||||
|  |     ga('send', 'pageview', location.pathname.includes("auth_callback") === -1 ? location.pathname : "/"); | ||||||
|  |     </script> | ||||||
|  |   </body> | ||||||
|  | </html> | ||||||
| @@ -22,14 +22,25 @@ | |||||||
|     </script> |     </script> | ||||||
|   </head> |   </head> | ||||||
|   <body> |   <body> | ||||||
|     <%= renderTemplate("../../../src/html/_js_base.html.template") %> |     <%= renderTemplate('_js_base') %> | ||||||
|  |  | ||||||
|     <cast-media-player></cast-media-player> |     <cast-media-player></cast-media-player> | ||||||
|  |  | ||||||
|     <script> |     <script> | ||||||
|       <% for (const entry of latestEntryJS) { %> |       import("<%= latestMediaJS %>"); | ||||||
|         import("<%= entry %>"); |  | ||||||
|       <% } %> |  | ||||||
|       window.latestJS = true; |       window.latestJS = true; | ||||||
|     </script> |     </script> | ||||||
|     <%= renderTemplate("../../../src/html/_script_load_es5.html.template") %> |  | ||||||
|  |     <script> | ||||||
|  |       if (!window.latestJS) { | ||||||
|  |         <% if (useRollup) { %> | ||||||
|  |           _ls("/static/js/s.min.js").onload = function() { | ||||||
|  |             System.import("<%= es5MediaJS %>"); | ||||||
|  |           }; | ||||||
|  |         <% } else { %> | ||||||
|  |           _ls("<%= es5MediaJS %>"); | ||||||
|  |         <% } %> | ||||||
|  |       } | ||||||
|  |     </script> | ||||||
|   </body> |   </body> | ||||||
| </html> | </html> | ||||||
|   | |||||||
| @@ -1,10 +1,8 @@ | |||||||
| <!DOCTYPE html> | <!DOCTYPE html> | ||||||
| <html> | <html> | ||||||
|   <script src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script> |   <script src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script> | ||||||
|   <% for (const entry of latestEntryJS) { %> |   <script type="module" src="<%= latestReceiverJS %>"></script> | ||||||
|     <script type="module" src="<%= entry %>"></script> |   <%= renderTemplate('_style_base') %> | ||||||
|   <% } %> |  | ||||||
|   <%= renderTemplate("../../../src/html/_style_base.html.template") %> |  | ||||||
|   <style> |   <style> | ||||||
|     body { |     body { | ||||||
|       background-color: white; |       background-color: white; | ||||||
|   | |||||||
| @@ -181,7 +181,7 @@ class HcCast extends LitElement { | |||||||
|   private async _handlePickView(ev: Event) { |   private async _handlePickView(ev: Event) { | ||||||
|     const path = (ev.currentTarget as any).getAttribute("data-path"); |     const path = (ev.currentTarget as any).getAttribute("data-path"); | ||||||
|     await ensureConnectedCastSession(this.castManager!, this.auth!); |     await ensureConnectedCastSession(this.castManager!, this.auth!); | ||||||
|     castSendShowLovelaceView(this.castManager, this.auth.data.hassUrl, path); |     castSendShowLovelaceView(this.castManager, path, this.auth.data.hassUrl); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private async _handleLogout() { |   private async _handleLogout() { | ||||||
|   | |||||||
| @@ -190,7 +190,7 @@ export class HcConnect extends LitElement { | |||||||
|  |  | ||||||
|   private _handleInputKeyDown(ev: KeyboardEvent) { |   private _handleInputKeyDown(ev: KeyboardEvent) { | ||||||
|     // Handle pressing enter. |     // Handle pressing enter. | ||||||
|     if (ev.key === "Enter") { |     if (ev.keyCode === 13) { | ||||||
|       this._handleConnect(); |       this._handleConnect(); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -1,21 +1,19 @@ | |||||||
| import { framework } from "../receiver/cast_framework"; | const castContext = cast.framework.CastReceiverContext.getInstance(); | ||||||
|  |  | ||||||
| const castContext = framework.CastReceiverContext.getInstance(); |  | ||||||
|  |  | ||||||
| const playerManager = castContext.getPlayerManager(); | const playerManager = castContext.getPlayerManager(); | ||||||
|  |  | ||||||
| playerManager.setMessageInterceptor( | playerManager.setMessageInterceptor( | ||||||
|   framework.messages.MessageType.LOAD, |   cast.framework.messages.MessageType.LOAD, | ||||||
|   (loadRequestData) => { |   (loadRequestData) => { | ||||||
|     const media = loadRequestData.media; |     const media = loadRequestData.media; | ||||||
|     // Special handling if it came from Google Assistant |     // Special handling if it came from Google Assistant | ||||||
|     if (media.entity) { |     if (media.entity) { | ||||||
|       media.contentId = media.entity; |       media.contentId = media.entity; | ||||||
|       media.streamType = framework.messages.StreamType.LIVE; |       media.streamType = cast.framework.messages.StreamType.LIVE; | ||||||
|       media.contentType = "application/vnd.apple.mpegurl"; |       media.contentType = "application/vnd.apple.mpegurl"; | ||||||
|       // @ts-ignore |       // @ts-ignore | ||||||
|       media.hlsVideoSegmentFormat = |       media.hlsVideoSegmentFormat = | ||||||
|         framework.messages.HlsVideoSegmentFormat.FMP4; |         cast.framework.messages.HlsVideoSegmentFormat.FMP4; | ||||||
|     } |     } | ||||||
|     return loadRequestData; |     return loadRequestData; | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -1,3 +1,2 @@ | |||||||
| import { framework } from "./cast_framework"; | /* eslint-disable no-undef */ | ||||||
|  | export const castContext = cast.framework.CastReceiverContext.getInstance(); | ||||||
| export const castContext = framework.CastReceiverContext.getInstance(); |  | ||||||
|   | |||||||
| @@ -1,3 +0,0 @@ | |||||||
| import type { cast as ReceiverCast } from "chromecast-caf-receiver"; |  | ||||||
|  |  | ||||||
| export const framework = (cast as unknown as typeof ReceiverCast).framework; |  | ||||||
| @@ -1,4 +1,4 @@ | |||||||
| import { framework } from "./cast_framework"; | /* eslint-disable no-undef */ | ||||||
| import { CAST_NS } from "../../../src/cast/const"; | import { CAST_NS } from "../../../src/cast/const"; | ||||||
| import { HassMessage } from "../../../src/cast/receiver_messages"; | import { HassMessage } from "../../../src/cast/receiver_messages"; | ||||||
| import "../../../src/resources/custom-card-support"; | import "../../../src/resources/custom-card-support"; | ||||||
| @@ -34,14 +34,14 @@ const setTouchControlsVisibility = (visible: boolean) => { | |||||||
| let timeOut: number | undefined; | let timeOut: number | undefined; | ||||||
|  |  | ||||||
| const playDummyMedia = (viewTitle?: string) => { | const playDummyMedia = (viewTitle?: string) => { | ||||||
|   const loadRequestData = new framework.messages.LoadRequestData(); |   const loadRequestData = new cast.framework.messages.LoadRequestData(); | ||||||
|   loadRequestData.autoplay = true; |   loadRequestData.autoplay = true; | ||||||
|   loadRequestData.media = new framework.messages.MediaInformation(); |   loadRequestData.media = new cast.framework.messages.MediaInformation(); | ||||||
|   loadRequestData.media.contentId = |   loadRequestData.media.contentId = | ||||||
|     "https://cast.home-assistant.io/images/google-nest-hub.png"; |     "https://cast.home-assistant.io/images/google-nest-hub.png"; | ||||||
|   loadRequestData.media.contentType = "image/jpeg"; |   loadRequestData.media.contentType = "image/jpeg"; | ||||||
|   loadRequestData.media.streamType = framework.messages.StreamType.NONE; |   loadRequestData.media.streamType = cast.framework.messages.StreamType.NONE; | ||||||
|   const metadata = new framework.messages.GenericMediaMetadata(); |   const metadata = new cast.framework.messages.GenericMediaMetadata(); | ||||||
|   metadata.title = viewTitle; |   metadata.title = viewTitle; | ||||||
|   loadRequestData.media.metadata = metadata; |   loadRequestData.media.metadata = metadata; | ||||||
|  |  | ||||||
| @@ -86,10 +86,10 @@ const showMediaPlayer = () => { | |||||||
|   } |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| const options = new framework.CastReceiverOptions(); | const options = new cast.framework.CastReceiverOptions(); | ||||||
| options.disableIdleTimeout = true; | options.disableIdleTimeout = true; | ||||||
| options.customNamespaces = { | options.customNamespaces = { | ||||||
|   [CAST_NS]: framework.system.MessageType.JSON, |   [CAST_NS]: cast.framework.system.MessageType.JSON, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| castContext.addCustomMessageListener( | castContext.addCustomMessageListener( | ||||||
| @@ -98,7 +98,8 @@ castContext.addCustomMessageListener( | |||||||
|   (ev: ReceivedMessage<HassMessage>) => { |   (ev: ReceivedMessage<HassMessage>) => { | ||||||
|     // We received a show Lovelace command, stop media from playing, hide media player and show Lovelace controller |     // We received a show Lovelace command, stop media from playing, hide media player and show Lovelace controller | ||||||
|     if ( |     if ( | ||||||
|       playerManager.getPlayerState() !== framework.messages.PlayerState.IDLE |       playerManager.getPlayerState() !== | ||||||
|  |       cast.framework.messages.PlayerState.IDLE | ||||||
|     ) { |     ) { | ||||||
|       playerManager.stop(); |       playerManager.stop(); | ||||||
|     } else { |     } else { | ||||||
| @@ -113,7 +114,7 @@ castContext.addCustomMessageListener( | |||||||
| const playerManager = castContext.getPlayerManager(); | const playerManager = castContext.getPlayerManager(); | ||||||
|  |  | ||||||
| playerManager.setMessageInterceptor( | playerManager.setMessageInterceptor( | ||||||
|   framework.messages.MessageType.LOAD, |   cast.framework.messages.MessageType.LOAD, | ||||||
|   (loadRequestData) => { |   (loadRequestData) => { | ||||||
|     if ( |     if ( | ||||||
|       loadRequestData.media.contentId === |       loadRequestData.media.contentId === | ||||||
| @@ -127,24 +128,25 @@ playerManager.setMessageInterceptor( | |||||||
|     // Special handling if it came from Google Assistant |     // Special handling if it came from Google Assistant | ||||||
|     if (media.entity) { |     if (media.entity) { | ||||||
|       media.contentId = media.entity; |       media.contentId = media.entity; | ||||||
|       media.streamType = framework.messages.StreamType.LIVE; |       media.streamType = cast.framework.messages.StreamType.LIVE; | ||||||
|       media.contentType = "application/vnd.apple.mpegurl"; |       media.contentType = "application/vnd.apple.mpegurl"; | ||||||
|       // @ts-ignore |       // @ts-ignore | ||||||
|       media.hlsVideoSegmentFormat = |       media.hlsVideoSegmentFormat = | ||||||
|         framework.messages.HlsVideoSegmentFormat.FMP4; |         cast.framework.messages.HlsVideoSegmentFormat.FMP4; | ||||||
|     } |     } | ||||||
|     return loadRequestData; |     return loadRequestData; | ||||||
|   } |   } | ||||||
| ); | ); | ||||||
|  |  | ||||||
| playerManager.addEventListener( | playerManager.addEventListener( | ||||||
|   framework.events.EventType.MEDIA_STATUS, |   cast.framework.events.EventType.MEDIA_STATUS, | ||||||
|   (event) => { |   (event) => { | ||||||
|     if ( |     if ( | ||||||
|       event.mediaStatus?.playerState === framework.messages.PlayerState.IDLE && |       event.mediaStatus?.playerState === | ||||||
|  |         cast.framework.messages.PlayerState.IDLE && | ||||||
|       event.mediaStatus?.idleReason && |       event.mediaStatus?.idleReason && | ||||||
|       event.mediaStatus?.idleReason !== |       event.mediaStatus?.idleReason !== | ||||||
|         framework.messages.IdleReason.INTERRUPTED |         cast.framework.messages.IdleReason.INTERRUPTED | ||||||
|     ) { |     ) { | ||||||
|       // media finished or stopped, return to default Lovelace |       // media finished or stopped, return to default Lovelace | ||||||
|       showLovelaceController(); |       showLovelaceController(); | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| import { html, nothing } from "lit"; | import { html, TemplateResult } from "lit"; | ||||||
| import { customElement, property, state } from "lit/decorators"; | import { customElement, property, state } from "lit/decorators"; | ||||||
| import { mockHistory } from "../../../../demo/src/stubs/history"; | import { mockHistory } from "../../../../demo/src/stubs/history"; | ||||||
| import { LovelaceConfig } from "../../../../src/data/lovelace"; | import { LovelaceConfig } from "../../../../src/data/lovelace"; | ||||||
| @@ -18,9 +18,9 @@ class HcDemo extends HassElement { | |||||||
|  |  | ||||||
|   @state() private _lovelaceConfig?: LovelaceConfig; |   @state() private _lovelaceConfig?: LovelaceConfig; | ||||||
|  |  | ||||||
|   protected render() { |   protected render(): TemplateResult { | ||||||
|     if (!this._lovelaceConfig) { |     if (!this._lovelaceConfig) { | ||||||
|       return nothing; |       return html``; | ||||||
|     } |     } | ||||||
|     return html` |     return html` | ||||||
|       <hc-lovelace |       <hc-lovelace | ||||||
|   | |||||||
| @@ -252,22 +252,6 @@ export class HcMain extends HassElement { | |||||||
|       msg.urlPath = null; |       msg.urlPath = null; | ||||||
|     } |     } | ||||||
|     this._lovelacePath = msg.viewPath; |     this._lovelacePath = msg.viewPath; | ||||||
|     if (msg.urlPath === "energy") { |  | ||||||
|       this._lovelaceConfig = { |  | ||||||
|         views: [ |  | ||||||
|           { |  | ||||||
|             strategy: { |  | ||||||
|               type: "energy", |  | ||||||
|               options: { show_date_selection: true }, |  | ||||||
|             }, |  | ||||||
|           }, |  | ||||||
|         ], |  | ||||||
|       }; |  | ||||||
|       this._urlPath = "energy"; |  | ||||||
|       this._lovelacePath = 0; |  | ||||||
|       this._sendStatus(); |  | ||||||
|       return; |  | ||||||
|     } |  | ||||||
|     if (!this._unsubLovelace || this._urlPath !== msg.urlPath) { |     if (!this._unsubLovelace || this._urlPath !== msg.urlPath) { | ||||||
|       this._urlPath = msg.urlPath; |       this._urlPath = msg.urlPath; | ||||||
|       this._lovelaceConfig = undefined; |       this._lovelaceConfig = undefined; | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| import webpack from "../build-scripts/webpack.cjs"; | const { createCastConfig } = require("../build-scripts/webpack.js"); | ||||||
| import env from "../build-scripts/env.cjs"; | const { isProdBuild, isStatsBuild } = require("../build-scripts/env.js"); | ||||||
|  |  | ||||||
| export default webpack.createCastConfig({ | module.exports = createCastConfig({ | ||||||
|   isProdBuild: env.isProdBuild(), |   isProdBuild: isProdBuild(), | ||||||
|   isStatsBuild: env.isStatsBuild(), |   isStatsBuild: isStatsBuild(), | ||||||
|   latestBuild: true, |   latestBuild: true, | ||||||
| }); | }); | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| import rollup from "../build-scripts/rollup.cjs"; | const rollup = require("../build-scripts/rollup.js"); | ||||||
| import env from "../build-scripts/env.cjs"; | const env = require("../build-scripts/env.js"); | ||||||
|  |  | ||||||
| const config = rollup.createDemoConfig({ | const config = rollup.createDemoConfig({ | ||||||
|   isProdBuild: env.isProdBuild(), |   isProdBuild: env.isProdBuild(), | ||||||
| @@ -7,4 +7,4 @@ const config = rollup.createDemoConfig({ | |||||||
|   isStatsBuild: env.isStatsBuild(), |   isStatsBuild: env.isStatsBuild(), | ||||||
| }); | }); | ||||||
|  |  | ||||||
| export default { ...config.inputOptions, output: config.outputOptions }; | module.exports = { ...config.inputOptions, output: config.outputOptions }; | ||||||
|   | |||||||
| @@ -6,9 +6,6 @@ set -e | |||||||
|  |  | ||||||
| cd "$(dirname "$0")/.." | cd "$(dirname "$0")/.." | ||||||
|  |  | ||||||
| export STATS=1 | STATS=1 NODE_ENV=production ../node_modules/.bin/webpack --profile --json > compilation-stats.json | ||||||
| statsfile="compilation-stats-demo.json" | npx webpack-bundle-analyzer compilation-stats.json dist/frontend_latest | ||||||
|  | rm compilation-stats.json | ||||||
| ./node_modules/.bin/webpack-cli --profile --node-env=production --json=$statsfile |  | ||||||
| npx webpack-bundle-analyzer $statsfile dist/frontend_latest |  | ||||||
| rm -f $statsfile |  | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| import { mdiTelevision } from "@mdi/js"; | import { mdiTelevision } from "@mdi/js"; | ||||||
| import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; | import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; | ||||||
| import { customElement, state } from "lit/decorators"; | import { customElement, state } from "lit/decorators"; | ||||||
| import { CastManager } from "../../../src/cast/cast_manager"; | import { CastManager } from "../../../src/cast/cast_manager"; | ||||||
| import { castSendShowDemo } from "../../../src/cast/receiver_messages"; | import { castSendShowDemo } from "../../../src/cast/receiver_messages"; | ||||||
| @@ -20,12 +20,12 @@ class CastDemoRow extends LitElement implements LovelaceRow { | |||||||
|     // No config possible. |     // No config possible. | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   protected render() { |   protected render(): TemplateResult { | ||||||
|     if ( |     if ( | ||||||
|       !this._castManager || |       !this._castManager || | ||||||
|       this._castManager.castState === "NO_DEVICES_AVAILABLE" |       this._castManager.castState === "NO_DEVICES_AVAILABLE" | ||||||
|     ) { |     ) { | ||||||
|       return nothing; |       return html``; | ||||||
|     } |     } | ||||||
|     return html` |     return html` | ||||||
|       <ha-svg-icon .path=${mdiTelevision}></ha-svg-icon> |       <ha-svg-icon .path=${mdiTelevision}></ha-svg-icon> | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| import "@material/mwc-button"; | import "@material/mwc-button"; | ||||||
| import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; | import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; | ||||||
| import { customElement, property, state } from "lit/decorators"; | import { property, state } from "lit/decorators"; | ||||||
| import { until } from "lit/directives/until"; | import { until } from "lit/directives/until"; | ||||||
| import "../../../src/components/ha-card"; | import "../../../src/components/ha-card"; | ||||||
| import "../../../src/components/ha-circular-progress"; | import "../../../src/components/ha-circular-progress"; | ||||||
| @@ -14,7 +14,6 @@ import { | |||||||
|   setDemoConfig, |   setDemoConfig, | ||||||
| } from "../configs/demo-configs"; | } from "../configs/demo-configs"; | ||||||
|  |  | ||||||
| @customElement("ha-demo-card") |  | ||||||
| export class HADemoCard extends LitElement implements LovelaceCard { | export class HADemoCard extends LitElement implements LovelaceCard { | ||||||
|   @property({ attribute: false }) public lovelace?: Lovelace; |   @property({ attribute: false }) public lovelace?: Lovelace; | ||||||
|  |  | ||||||
| @@ -30,9 +29,9 @@ export class HADemoCard extends LitElement implements LovelaceCard { | |||||||
|  |  | ||||||
|   public setConfig(_config: LovelaceCardConfig) {} |   public setConfig(_config: LovelaceCardConfig) {} | ||||||
|  |  | ||||||
|   protected render() { |   protected render(): TemplateResult { | ||||||
|     if (this._hidden) { |     if (this._hidden) { | ||||||
|       return nothing; |       return html``; | ||||||
|     } |     } | ||||||
|     return html` |     return html` | ||||||
|       <ha-card> |       <ha-card> | ||||||
| @@ -155,3 +154,5 @@ declare global { | |||||||
|     "ha-demo-card": HADemoCard; |     "ha-demo-card": HADemoCard; | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | customElements.define("ha-demo-card", HADemoCard); | ||||||
|   | |||||||
| @@ -1,6 +1,4 @@ | |||||||
| // Compat needs to be first import | // Compat needs to be first import | ||||||
| import "../../src/resources/compatibility"; |  | ||||||
| import { customElement } from "lit/decorators"; |  | ||||||
| import { isNavigationClick } from "../../src/common/dom/is-navigation-click"; | import { isNavigationClick } from "../../src/common/dom/is-navigation-click"; | ||||||
| import { navigate } from "../../src/common/navigate"; | import { navigate } from "../../src/common/navigate"; | ||||||
| import { | import { | ||||||
| @@ -8,6 +6,7 @@ import { | |||||||
|   provideHass, |   provideHass, | ||||||
| } from "../../src/fake_data/provide_hass"; | } from "../../src/fake_data/provide_hass"; | ||||||
| import { HomeAssistantAppEl } from "../../src/layouts/home-assistant"; | import { HomeAssistantAppEl } from "../../src/layouts/home-assistant"; | ||||||
|  | import "../../src/resources/compatibility"; | ||||||
| import { HomeAssistant } from "../../src/types"; | import { HomeAssistant } from "../../src/types"; | ||||||
| import { selectedDemoConfig } from "./configs/demo-configs"; | import { selectedDemoConfig } from "./configs/demo-configs"; | ||||||
| import { mockAuth } from "./stubs/auth"; | import { mockAuth } from "./stubs/auth"; | ||||||
| @@ -27,8 +26,7 @@ import { mockSystemLog } from "./stubs/system_log"; | |||||||
| import { mockTemplate } from "./stubs/template"; | import { mockTemplate } from "./stubs/template"; | ||||||
| import { mockTranslations } from "./stubs/translations"; | import { mockTranslations } from "./stubs/translations"; | ||||||
|  |  | ||||||
| @customElement("ha-demo") | class HaDemo extends HomeAssistantAppEl { | ||||||
| export class HaDemo extends HomeAssistantAppEl { |  | ||||||
|   protected async _initializeHass() { |   protected async _initializeHass() { | ||||||
|     const initial: Partial<MockHomeAssistant> = { |     const initial: Partial<MockHomeAssistant> = { | ||||||
|       panelUrl: (this as any)._panelUrl, |       panelUrl: (this as any)._panelUrl, | ||||||
| @@ -73,7 +71,6 @@ export class HaDemo extends HomeAssistantAppEl { | |||||||
|         entity_category: null, |         entity_category: null, | ||||||
|         has_entity_name: false, |         has_entity_name: false, | ||||||
|         unique_id: "co2_intensity", |         unique_id: "co2_intensity", | ||||||
|         options: null, |  | ||||||
|       }, |       }, | ||||||
|       { |       { | ||||||
|         config_entry_id: "co2signal", |         config_entry_id: "co2signal", | ||||||
| @@ -89,7 +86,6 @@ export class HaDemo extends HomeAssistantAppEl { | |||||||
|         entity_category: null, |         entity_category: null, | ||||||
|         has_entity_name: false, |         has_entity_name: false, | ||||||
|         unique_id: "grid_fossil_fuel_percentage", |         unique_id: "grid_fossil_fuel_percentage", | ||||||
|         options: null, |  | ||||||
|       }, |       }, | ||||||
|     ]); |     ]); | ||||||
|  |  | ||||||
| @@ -125,6 +121,8 @@ export class HaDemo extends HomeAssistantAppEl { | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | customElements.define("ha-demo", HaDemo); | ||||||
|  |  | ||||||
| declare global { | declare global { | ||||||
|   interface HTMLElementTagNameMap { |   interface HTMLElementTagNameMap { | ||||||
|     "ha-demo": HaDemo; |     "ha-demo": HaDemo; | ||||||
|   | |||||||
| @@ -1,26 +0,0 @@ | |||||||
| <meta property="fb:app_id" content="338291289691179" /> |  | ||||||
| <meta property="og:title" content="Home Assistant Demo" /> |  | ||||||
| <meta property="og:site_name" content="Home Assistant" /> |  | ||||||
| <meta property="og:url" content="https://demo.home-assistant.io/" /> |  | ||||||
| <meta property="og:type" content="website" /> |  | ||||||
| <meta |  | ||||||
|   property="og:description" |  | ||||||
|   content="Open source home automation that puts local control and privacy first." |  | ||||||
| /> |  | ||||||
| <meta |  | ||||||
|   property="og:image" |  | ||||||
|   content="https://www.home-assistant.io/images/default-social.png" |  | ||||||
| /> |  | ||||||
|  |  | ||||||
| <meta name="twitter:card" content="summary_large_image" /> |  | ||||||
| <meta name="twitter:site" content="@home_assistant" /> |  | ||||||
|  |  | ||||||
| <meta name="twitter:title" content="Home Assistant" /> |  | ||||||
| <meta |  | ||||||
|   name="twitter:description" |  | ||||||
|   content="Open source home automation that puts local control and privacy first." |  | ||||||
| /> |  | ||||||
| <meta |  | ||||||
|   name="twitter:image" |  | ||||||
|   content="https://www.home-assistant.io/images/default-social.png" |  | ||||||
| /> |  | ||||||
| @@ -1,8 +1,9 @@ | |||||||
| <!DOCTYPE html> | <!DOCTYPE html> | ||||||
| <html> | <html> | ||||||
|   <head> |   <head> | ||||||
|     <title>Home Assistant Demo</title> |     <meta charset="utf-8" /> | ||||||
|     <%= renderTemplate("../../../src/html/_header.html.template") %> |     <link rel="manifest" href="/manifest.json" crossorigin="use-credentials" /> | ||||||
|  |     <link rel="icon" href="/static/icons/favicon.ico" /> | ||||||
|     <link rel="mask-icon" href="/static/icons/mask-icon.svg" color="#03a9f4" /> |     <link rel="mask-icon" href="/static/icons/mask-icon.svg" color="#03a9f4" /> | ||||||
|     <link |     <link | ||||||
|       rel="apple-touch-icon" |       rel="apple-touch-icon" | ||||||
| @@ -34,7 +35,33 @@ | |||||||
|       content="width=device-width, initial-scale=1, shrink-to-fit=no" |       content="width=device-width, initial-scale=1, shrink-to-fit=no" | ||||||
|     /> |     /> | ||||||
|     <meta name="theme-color" content="#03a9f4" /> |     <meta name="theme-color" content="#03a9f4" /> | ||||||
|     <%= renderTemplate("_social_meta.html.template") %> |     <meta property="fb:app_id" content="338291289691179" /> | ||||||
|  |     <meta property="og:title" content="Home Assistant Demo" /> | ||||||
|  |     <meta property="og:site_name" content="Home Assistant" /> | ||||||
|  |     <meta property="og:url" content="https://demo.home-assistant.io/" /> | ||||||
|  |     <meta property="og:type" content="website" /> | ||||||
|  |     <meta | ||||||
|  |       property="og:description" | ||||||
|  |       content="Open source home automation that puts local control and privacy first." | ||||||
|  |     /> | ||||||
|  |     <meta | ||||||
|  |       property="og:image" | ||||||
|  |       content="https://www.home-assistant.io/images/default-social.png" | ||||||
|  |     /> | ||||||
|  |  | ||||||
|  |     <meta name="twitter:card" content="summary_large_image" /> | ||||||
|  |     <meta name="twitter:site" content="@home_assistant" /> | ||||||
|  |  | ||||||
|  |     <meta name="twitter:title" content="Home Assistant" /> | ||||||
|  |     <meta | ||||||
|  |       name="twitter:description" | ||||||
|  |       content="Open source home automation that puts local control and privacy first." | ||||||
|  |     /> | ||||||
|  |     <meta | ||||||
|  |       name="twitter:image" | ||||||
|  |       content="https://www.home-assistant.io/images/default-social.png" | ||||||
|  |     /> | ||||||
|  |     <title>Home Assistant Demo</title> | ||||||
|     <style> |     <style> | ||||||
|       html { |       html { | ||||||
|         background-color: var(--primary-background-color, #fafafa); |         background-color: var(--primary-background-color, #fafafa); | ||||||
| @@ -80,19 +107,29 @@ | |||||||
|       </svg> |       </svg> | ||||||
|       <div id="ha-launch-screen-info-box" class="ha-launch-screen-spacer"></div> |       <div id="ha-launch-screen-info-box" class="ha-launch-screen-spacer"></div> | ||||||
|     </div> |     </div> | ||||||
|  |  | ||||||
|     <ha-demo></ha-demo> |     <ha-demo></ha-demo> | ||||||
|     <%= renderTemplate("../../../src/html/_js_base.html.template") %> |  | ||||||
|     <%= renderTemplate("../../../src/html/_preload_roboto.html.template") %> |     <%= renderTemplate('_js_base') %> | ||||||
|  |     <%= renderTemplate('_preload_roboto') %> | ||||||
|  |  | ||||||
|     <script> |     <script> | ||||||
|       // Safari 12 and below does not have a compliant ES2015 implementation of template literals, so we ship ES5 |       import("<%= latestDemoJS %>"); | ||||||
|       if (!isS11_12) { |       window.latestJS = true; | ||||||
|         <% for (const entry of latestEntryJS) { %> |     </script> | ||||||
|           import("<%= entry %>"); |  | ||||||
|  |     <script> | ||||||
|  |       if (!window.latestJS) { | ||||||
|  |         <% if (useRollup) { %> | ||||||
|  |           _ls("/static/js/s.min.js").onload = function() { | ||||||
|  |             System.import("<%= es5DemoJS %>"); | ||||||
|  |           }; | ||||||
|  |         <% } else { %> | ||||||
|  |           _ls("<%= es5DemoJS %>"); | ||||||
|         <% } %> |         <% } %> | ||||||
|         window.latestJS = true; |  | ||||||
|       } |       } | ||||||
|     </script> |     </script> | ||||||
|     <%= renderTemplate("../../../src/html/_script_load_es5.html.template") %> |  | ||||||
|     <script> |     <script> | ||||||
|       var _gaq = [["_setAccount", "UA-57927901-5"], ["_trackPageview"]]; |       var _gaq = [["_setAccount", "UA-57927901-5"], ["_trackPageview"]]; | ||||||
|       (function (d, t) { |       (function (d, t) { | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| import { MockHomeAssistant } from "../../../src/fake_data/provide_hass"; | import { MockHomeAssistant } from "../../../src/fake_data/provide_hass"; | ||||||
|  |  | ||||||
| export const mockConfigEntries = (hass: MockHomeAssistant) => { | export const mockConfigEntries = (hass: MockHomeAssistant) => { | ||||||
|   hass.mockWS("config_entries/get_matching", () => [ |   hass.mockWS("config_entries/get", () => [ | ||||||
|     { |     { | ||||||
|       entry_id: "co2signal", |       entry_id: "co2signal", | ||||||
|       domain: "co2signal", |       domain: "co2signal", | ||||||
|   | |||||||
| @@ -1,19 +1,39 @@ | |||||||
| import { HassEntity } from "home-assistant-js-websocket"; | import { HassEntity } from "home-assistant-js-websocket"; | ||||||
| import { HistoryStates } from "../../../src/data/history"; |  | ||||||
| import { MockHomeAssistant } from "../../../src/fake_data/provide_hass"; | import { MockHomeAssistant } from "../../../src/fake_data/provide_hass"; | ||||||
|  |  | ||||||
| const generateStateHistory = ( | interface HistoryQueryParams { | ||||||
|   state: HassEntity, |   filter_entity_id: string; | ||||||
|   deltas, |   end_time: string; | ||||||
|   start_date: Date, | } | ||||||
|   end_date: Date |  | ||||||
| ) => { | const parseQuery = <T>(queryString: string) => { | ||||||
|  |   const query: any = {}; | ||||||
|  |   const items = queryString.split("&"); | ||||||
|  |   for (const item of items) { | ||||||
|  |     const parts = item.split("="); | ||||||
|  |     const key = decodeURIComponent(parts[0]); | ||||||
|  |     const value = parts.length > 1 ? decodeURIComponent(parts[1]) : undefined; | ||||||
|  |     query[key] = value; | ||||||
|  |   } | ||||||
|  |   return query as T; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | const getTime = (minutesAgo) => { | ||||||
|  |   const ts = new Date(Date.now() - minutesAgo * 60 * 1000); | ||||||
|  |   return ts.toISOString(); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | const randomTimeAdjustment = (diff) => Math.random() * diff - diff / 2; | ||||||
|  |  | ||||||
|  | const maxTime = 1440; | ||||||
|  |  | ||||||
|  | const generateHistory = (state, deltas) => { | ||||||
|   const changes = |   const changes = | ||||||
|     typeof deltas[0] === "object" |     typeof deltas[0] === "object" | ||||||
|       ? deltas |       ? deltas | ||||||
|       : deltas.map((st) => ({ state: st })); |       : deltas.map((st) => ({ state: st })); | ||||||
|  |  | ||||||
|   const timeDiff = (end_date.getTime() - start_date.getTime()) / changes.length; |   const timeDiff = 900 / changes.length; | ||||||
|  |  | ||||||
|   return changes.map((change, index) => { |   return changes.map((change, index) => { | ||||||
|     let attributes; |     let attributes; | ||||||
| @@ -27,13 +47,17 @@ const generateStateHistory = ( | |||||||
|       attributes = { ...state.attributes, ...change.attributes }; |       attributes = { ...state.attributes, ...change.attributes }; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     const time = start_date.getTime() + timeDiff * index; |     const time = | ||||||
|  |       index === 0 | ||||||
|  |         ? getTime(maxTime) | ||||||
|  |         : getTime(maxTime - index * timeDiff + randomTimeAdjustment(timeDiff)); | ||||||
|  |  | ||||||
|     return { |     return { | ||||||
|       a: attributes, |       attributes, | ||||||
|       s: change.state || state.state, |       entity_id: state.entity_id, | ||||||
|       lc: time / 1000, |       state: change.state || state.state, | ||||||
|       lu: time / 1000, |       last_changed: time, | ||||||
|  |       last_updated: time, | ||||||
|     }; |     }; | ||||||
|   }); |   }); | ||||||
| }; | }; | ||||||
| @@ -41,29 +65,15 @@ const generateStateHistory = ( | |||||||
| const incrementalUnits = ["clients", "queries", "ads"]; | const incrementalUnits = ["clients", "queries", "ads"]; | ||||||
|  |  | ||||||
| export const mockHistory = (mockHass: MockHomeAssistant) => { | export const mockHistory = (mockHass: MockHomeAssistant) => { | ||||||
|   mockHass.mockWS( |   mockHass.mockAPI( | ||||||
|     "history/stream", |     new RegExp("history/period/.+"), | ||||||
|     ( |     (hass, _method, path, _parameters) => { | ||||||
|       { |       const params = parseQuery<HistoryQueryParams>(path.split("?")[1]); | ||||||
|         entity_ids, |       const entities = params.filter_entity_id.split(","); | ||||||
|         start_time, |  | ||||||
|         end_time, |  | ||||||
|       }: { |  | ||||||
|         entity_ids: string[]; |  | ||||||
|         start_time: string; |  | ||||||
|         end_time?: string; |  | ||||||
|       }, |  | ||||||
|       hass, |  | ||||||
|       onChange |  | ||||||
|     ) => { |  | ||||||
|       const states: HistoryStates = {}; |  | ||||||
|  |  | ||||||
|       const start = new Date(start_time); |       const results: HassEntity[][] = []; | ||||||
|       const end = end_time ? new Date(end_time) : new Date(); |  | ||||||
|  |  | ||||||
|       for (const entityId of entity_ids) { |  | ||||||
|         states[entityId] = []; |  | ||||||
|  |  | ||||||
|  |       for (const entityId of entities) { | ||||||
|         const state = hass.states[entityId]; |         const state = hass.states[entityId]; | ||||||
|  |  | ||||||
|         if (!state) { |         if (!state) { | ||||||
| @@ -71,12 +81,7 @@ export const mockHistory = (mockHass: MockHomeAssistant) => { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (!state.attributes.unit_of_measurement) { |         if (!state.attributes.unit_of_measurement) { | ||||||
|           states[entityId] = generateStateHistory( |           results.push(generateHistory(state, [state.state])); | ||||||
|             state, |  | ||||||
|             [state.state], |  | ||||||
|             start, |  | ||||||
|             end |  | ||||||
|           ); |  | ||||||
|           continue; |           continue; | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -115,23 +120,17 @@ export const mockHistory = (mockHass: MockHomeAssistant) => { | |||||||
|             numberState - diff + Math.floor(Math.random() * 2 * diff); |             numberState - diff + Math.floor(Math.random() * 2 * diff); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         states[entityId] = generateStateHistory( |         results.push( | ||||||
|           state, |           generateHistory( | ||||||
|           Array.from({ length: statesToGenerate }, genFunc), |             { | ||||||
|           start, |               entity_id: state.entity_id, | ||||||
|           end |               attributes: state.attributes, | ||||||
|  |             }, | ||||||
|  |             Array.from({ length: statesToGenerate }, genFunc) | ||||||
|  |           ) | ||||||
|         ); |         ); | ||||||
|       } |       } | ||||||
|  |       return results; | ||||||
|       setTimeout(() => { |  | ||||||
|         onChange?.({ |  | ||||||
|           states, |  | ||||||
|           start_time: start, |  | ||||||
|           end_time: end, |  | ||||||
|         }); |  | ||||||
|       }, 1); |  | ||||||
|  |  | ||||||
|       return () => {}; |  | ||||||
|     } |     } | ||||||
|   ); |   ); | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -15,7 +15,6 @@ import { MockHomeAssistant } from "../../../src/fake_data/provide_hass"; | |||||||
| const generateMeanStatistics = ( | const generateMeanStatistics = ( | ||||||
|   start: Date, |   start: Date, | ||||||
|   end: Date, |   end: Date, | ||||||
|   // eslint-disable-next-line @typescript-eslint/default-param-last |  | ||||||
|   period: "5minute" | "hour" | "day" | "month" = "hour", |   period: "5minute" | "hour" | "day" | "month" = "hour", | ||||||
|   initValue: number, |   initValue: number, | ||||||
|   maxDiff: number |   maxDiff: number | ||||||
| @@ -52,7 +51,6 @@ const generateMeanStatistics = ( | |||||||
| const generateSumStatistics = ( | const generateSumStatistics = ( | ||||||
|   start: Date, |   start: Date, | ||||||
|   end: Date, |   end: Date, | ||||||
|   // eslint-disable-next-line @typescript-eslint/default-param-last |  | ||||||
|   period: "5minute" | "hour" | "day" | "month" = "hour", |   period: "5minute" | "hour" | "day" | "month" = "hour", | ||||||
|   initValue: number, |   initValue: number, | ||||||
|   maxDiff: number |   maxDiff: number | ||||||
| @@ -88,7 +86,6 @@ const generateSumStatistics = ( | |||||||
| const generateCurvedStatistics = ( | const generateCurvedStatistics = ( | ||||||
|   start: Date, |   start: Date, | ||||||
|   end: Date, |   end: Date, | ||||||
|   // eslint-disable-next-line @typescript-eslint/default-param-last |  | ||||||
|   _period: "5minute" | "hour" | "day" | "month" = "hour", |   _period: "5minute" | "hour" | "day" | "month" = "hour", | ||||||
|   initValue: number, |   initValue: number, | ||||||
|   maxDiff: number, |   maxDiff: number, | ||||||
|   | |||||||
| @@ -1,11 +1,12 @@ | |||||||
| import webpack from "../build-scripts/webpack.cjs"; | const { createDemoConfig } = require("../build-scripts/webpack.js"); | ||||||
| import env from "../build-scripts/env.cjs"; | const { isProdBuild, isStatsBuild } = require("../build-scripts/env.js"); | ||||||
|  |  | ||||||
| // File just used for stats builds | // File just used for stats builds | ||||||
|  |  | ||||||
| const latestBuild = true; | const latestBuild = true; | ||||||
|  |  | ||||||
| export default webpack.createDemoConfig({ | module.exports = createDemoConfig({ | ||||||
|   isProdBuild: env.isProdBuild(), |   isProdBuild: isProdBuild(), | ||||||
|   isStatsBuild: env.isStatsBuild(), |   isStatsBuild: isStatsBuild(), | ||||||
|   latestBuild, |   latestBuild, | ||||||
| }); | }); | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| import rollup from "../build-scripts/rollup.cjs"; | const rollup = require("../build-scripts/rollup.js"); | ||||||
| import env from "../build-scripts/env.cjs"; | const env = require("../build-scripts/env.js"); | ||||||
|  |  | ||||||
| const config = rollup.createGalleryConfig({ | const config = rollup.createGalleryConfig({ | ||||||
|   isProdBuild: env.isProdBuild(), |   isProdBuild: env.isProdBuild(), | ||||||
| @@ -7,4 +7,4 @@ const config = rollup.createGalleryConfig({ | |||||||
|   isStatsBuild: env.isStatsBuild(), |   isStatsBuild: env.isStatsBuild(), | ||||||
| }); | }); | ||||||
|  |  | ||||||
| export default { ...config.inputOptions, output: config.outputOptions }; | module.exports = { ...config.inputOptions, output: config.outputOptions }; | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| export default [ | module.exports = [ | ||||||
|   { |   { | ||||||
|     // This section has no header and so all page links are shown directly in the sidebar |     // This section has no header and so all page links are shown directly in the sidebar | ||||||
|     category: "concepts", |     category: "concepts", | ||||||
| @@ -45,10 +45,6 @@ export default [ | |||||||
|     header: "Users", |     header: "Users", | ||||||
|     pages: ["user-types", "configuration-menu"], |     pages: ["user-types", "configuration-menu"], | ||||||
|   }, |   }, | ||||||
|   { |  | ||||||
|     category: "date-time", |  | ||||||
|     header: "Date and Time", |  | ||||||
|   }, |  | ||||||
|   { |   { | ||||||
|     category: "design.home-assistant.io", |     category: "design.home-assistant.io", | ||||||
|     header: "About", |     header: "About", | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| import { css, html, nothing } from "lit"; | import { html, css } from "lit"; | ||||||
| import { customElement, property } from "lit/decorators"; | import { customElement, property } from "lit/decorators"; | ||||||
| import { until } from "lit/directives/until"; | import { until } from "lit/directives/until"; | ||||||
| import { HaMarkdown } from "../../../src/components/ha-markdown"; | import { HaMarkdown } from "../../../src/components/ha-markdown"; | ||||||
| @@ -10,7 +10,7 @@ class PageDescription extends HaMarkdown { | |||||||
|  |  | ||||||
|   render() { |   render() { | ||||||
|     if (!PAGES[this.page].description) { |     if (!PAGES[this.page].description) { | ||||||
|       return nothing; |       return html``; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return html` |     return html` | ||||||
|   | |||||||
| @@ -1,24 +0,0 @@ | |||||||
| import type { ControlSelectOption } from "../../../src/components/ha-control-select"; |  | ||||||
|  |  | ||||||
| export const timeOptions: ControlSelectOption[] = [ |  | ||||||
|   { |  | ||||||
|     value: "now", |  | ||||||
|     label: "Now", |  | ||||||
|   }, |  | ||||||
|   { |  | ||||||
|     value: "00:15:30", |  | ||||||
|     label: "12:15:30 AM", |  | ||||||
|   }, |  | ||||||
|   { |  | ||||||
|     value: "06:15:30", |  | ||||||
|     label: "06:15:30 AM", |  | ||||||
|   }, |  | ||||||
|   { |  | ||||||
|     value: "12:15:30", |  | ||||||
|     label: "12:15:30 PM", |  | ||||||
|   }, |  | ||||||
|   { |  | ||||||
|     value: "18:15:30", |  | ||||||
|     label: "06:15:30 PM", |  | ||||||
|   }, |  | ||||||
| ]; |  | ||||||
| @@ -1,3 +1,5 @@ | |||||||
|  | import "@polymer/polymer/lib/elements/dom-if"; | ||||||
|  | import "@polymer/polymer/lib/elements/dom-repeat"; | ||||||
| import "../../src/resources/ha-style"; | import "../../src/resources/ha-style"; | ||||||
| import "../../src/resources/roboto"; | import "../../src/resources/roboto"; | ||||||
| import "./ha-gallery"; | import "./ha-gallery"; | ||||||
|   | |||||||
| @@ -8,9 +8,8 @@ | |||||||
|     /> |     /> | ||||||
|     <meta name="theme-color" content="#2157BC" /> |     <meta name="theme-color" content="#2157BC" /> | ||||||
|     <title>Home Assistant Design</title> |     <title>Home Assistant Design</title> | ||||||
|     <% for (const entry of latestEntryJS) { %> |  | ||||||
|       <script type="module" src="<%= entry %>"></script> |     <script type="module" src="<%= latestGalleryJS %>"></script> | ||||||
|     <% } %> |  | ||||||
|     <style> |     <style> | ||||||
|       body { |       body { | ||||||
|         font-family: Roboto, Noto, sans-serif; |         font-family: Roboto, Noto, sans-serif; | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| import { dump } from "js-yaml"; | import { dump } from "js-yaml"; | ||||||
| import { css, html, LitElement, nothing } from "lit"; | import { html, css, LitElement, TemplateResult } from "lit"; | ||||||
| import { customElement, property, state } from "lit/decorators"; | import { customElement, property, state } from "lit/decorators"; | ||||||
| import "../../../../src/components/ha-card"; | import "../../../../src/components/ha-card"; | ||||||
| import "../../../../src/components/ha-yaml-editor"; | import "../../../../src/components/ha-yaml-editor"; | ||||||
| @@ -127,16 +127,16 @@ export class DemoAutomationDescribeAction extends LitElement { | |||||||
|  |  | ||||||
|   @state() _action = initialAction; |   @state() _action = initialAction; | ||||||
|  |  | ||||||
|   protected render() { |   protected render(): TemplateResult { | ||||||
|     if (!this.hass) { |     if (!this.hass) { | ||||||
|       return nothing; |       return html``; | ||||||
|     } |     } | ||||||
|     return html` |     return html` | ||||||
|       <ha-card header="Actions"> |       <ha-card header="Actions"> | ||||||
|         <div class="action"> |         <div class="action"> | ||||||
|           <span> |           <span> | ||||||
|             ${this._action |             ${this._action | ||||||
|               ? describeAction(this.hass, [], this._action) |               ? describeAction(this.hass, this._action) | ||||||
|               : "<invalid YAML>"} |               : "<invalid YAML>"} | ||||||
|           </span> |           </span> | ||||||
|           <ha-yaml-editor |           <ha-yaml-editor | ||||||
| @@ -149,7 +149,7 @@ export class DemoAutomationDescribeAction extends LitElement { | |||||||
|         ${ACTIONS.map( |         ${ACTIONS.map( | ||||||
|           (conf) => html` |           (conf) => html` | ||||||
|             <div class="action"> |             <div class="action"> | ||||||
|               <span>${describeAction(this.hass, [], conf as any)}</span> |               <span>${describeAction(this.hass, conf as any)}</span> | ||||||
|               <pre>${dump(conf)}</pre> |               <pre>${dump(conf)}</pre> | ||||||
|             </div> |             </div> | ||||||
|           ` |           ` | ||||||
| @@ -162,7 +162,6 @@ export class DemoAutomationDescribeAction extends LitElement { | |||||||
|     super.firstUpdated(changedProps); |     super.firstUpdated(changedProps); | ||||||
|     const hass = provideHass(this); |     const hass = provideHass(this); | ||||||
|     hass.updateTranslations(null, "en"); |     hass.updateTranslations(null, "en"); | ||||||
|     hass.updateTranslations("config", "en"); |  | ||||||
|     hass.addEntities(ENTITIES); |     hass.addEntities(ENTITIES); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| import { dump } from "js-yaml"; | import { dump } from "js-yaml"; | ||||||
| import { css, html, LitElement, nothing } from "lit"; | import { css, html, LitElement, TemplateResult } from "lit"; | ||||||
| import { customElement, property, state } from "lit/decorators"; | import { customElement, property, state } from "lit/decorators"; | ||||||
| import "../../../../src/components/ha-card"; | import "../../../../src/components/ha-card"; | ||||||
| import "../../../../src/components/ha-yaml-editor"; | import "../../../../src/components/ha-yaml-editor"; | ||||||
| @@ -53,9 +53,9 @@ export class DemoAutomationDescribeCondition extends LitElement { | |||||||
|  |  | ||||||
|   @state() _condition = initialCondition; |   @state() _condition = initialCondition; | ||||||
|  |  | ||||||
|   protected render() { |   protected render(): TemplateResult { | ||||||
|     if (!this.hass) { |     if (!this.hass) { | ||||||
|       return nothing; |       return html``; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return html` |     return html` | ||||||
| @@ -63,7 +63,7 @@ export class DemoAutomationDescribeCondition extends LitElement { | |||||||
|         <div class="condition"> |         <div class="condition"> | ||||||
|           <span> |           <span> | ||||||
|             ${this._condition |             ${this._condition | ||||||
|               ? describeCondition(this._condition, this.hass, []) |               ? describeCondition(this._condition, this.hass) | ||||||
|               : "<invalid YAML>"} |               : "<invalid YAML>"} | ||||||
|           </span> |           </span> | ||||||
|           <ha-yaml-editor |           <ha-yaml-editor | ||||||
| @@ -76,7 +76,7 @@ export class DemoAutomationDescribeCondition extends LitElement { | |||||||
|         ${conditions.map( |         ${conditions.map( | ||||||
|           (conf) => html` |           (conf) => html` | ||||||
|             <div class="condition"> |             <div class="condition"> | ||||||
|               <span>${describeCondition(conf as any, this.hass, [])}</span> |               <span>${describeCondition(conf as any, this.hass)}</span> | ||||||
|               <pre>${dump(conf)}</pre> |               <pre>${dump(conf)}</pre> | ||||||
|             </div> |             </div> | ||||||
|           ` |           ` | ||||||
| @@ -89,7 +89,6 @@ export class DemoAutomationDescribeCondition extends LitElement { | |||||||
|     super.firstUpdated(changedProps); |     super.firstUpdated(changedProps); | ||||||
|     const hass = provideHass(this); |     const hass = provideHass(this); | ||||||
|     hass.updateTranslations(null, "en"); |     hass.updateTranslations(null, "en"); | ||||||
|     hass.updateTranslations("config", "en"); |  | ||||||
|     hass.addEntities(ENTITIES); |     hass.addEntities(ENTITIES); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| import { dump } from "js-yaml"; | import { dump } from "js-yaml"; | ||||||
| import { css, html, LitElement, nothing } from "lit"; | import { css, html, LitElement, TemplateResult } from "lit"; | ||||||
| import { customElement, property, state } from "lit/decorators"; | import { customElement, property, state } from "lit/decorators"; | ||||||
| import "../../../../src/components/ha-card"; | import "../../../../src/components/ha-card"; | ||||||
| import "../../../../src/components/ha-yaml-editor"; | import "../../../../src/components/ha-yaml-editor"; | ||||||
| @@ -40,9 +40,7 @@ const triggers = [ | |||||||
|   }, |   }, | ||||||
|   { platform: "sun", event: "sunset" }, |   { platform: "sun", event: "sunset" }, | ||||||
|   { platform: "time_pattern" }, |   { platform: "time_pattern" }, | ||||||
|   { platform: "time_pattern", hours: "*", minutes: "/5", seconds: "10" }, |  | ||||||
|   { platform: "webhook" }, |   { platform: "webhook" }, | ||||||
|   { platform: "persistent_notification" }, |  | ||||||
|   { |   { | ||||||
|     platform: "zone", |     platform: "zone", | ||||||
|     entity_id: "person.person", |     entity_id: "person.person", | ||||||
| @@ -52,11 +50,6 @@ const triggers = [ | |||||||
|   { platform: "tag" }, |   { platform: "tag" }, | ||||||
|   { platform: "time", at: "15:32" }, |   { platform: "time", at: "15:32" }, | ||||||
|   { platform: "template" }, |   { platform: "template" }, | ||||||
|   { platform: "conversation", command: "Turn on the lights" }, |  | ||||||
|   { |  | ||||||
|     platform: "conversation", |  | ||||||
|     command: ["Turn on the lights", "Turn the lights on"], |  | ||||||
|   }, |  | ||||||
|   { platform: "event", event_type: "homeassistant_started" }, |   { platform: "event", event_type: "homeassistant_started" }, | ||||||
| ]; | ]; | ||||||
|  |  | ||||||
| @@ -71,9 +64,9 @@ export class DemoAutomationDescribeTrigger extends LitElement { | |||||||
|  |  | ||||||
|   @state() _trigger = initialTrigger; |   @state() _trigger = initialTrigger; | ||||||
|  |  | ||||||
|   protected render() { |   protected render(): TemplateResult { | ||||||
|     if (!this.hass) { |     if (!this.hass) { | ||||||
|       return nothing; |       return html``; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return html` |     return html` | ||||||
| @@ -81,7 +74,7 @@ export class DemoAutomationDescribeTrigger extends LitElement { | |||||||
|         <div class="trigger"> |         <div class="trigger"> | ||||||
|           <span> |           <span> | ||||||
|             ${this._trigger |             ${this._trigger | ||||||
|               ? describeTrigger(this._trigger, this.hass, []) |               ? describeTrigger(this._trigger, this.hass) | ||||||
|               : "<invalid YAML>"} |               : "<invalid YAML>"} | ||||||
|           </span> |           </span> | ||||||
|           <ha-yaml-editor |           <ha-yaml-editor | ||||||
| @@ -93,7 +86,7 @@ export class DemoAutomationDescribeTrigger extends LitElement { | |||||||
|         ${triggers.map( |         ${triggers.map( | ||||||
|           (conf) => html` |           (conf) => html` | ||||||
|             <div class="trigger"> |             <div class="trigger"> | ||||||
|               <span>${describeTrigger(conf as any, this.hass, [])}</span> |               <span>${describeTrigger(conf as any, this.hass)}</span> | ||||||
|               <pre>${dump(conf)}</pre> |               <pre>${dump(conf)}</pre> | ||||||
|             </div> |             </div> | ||||||
|           ` |           ` | ||||||
| @@ -106,7 +99,6 @@ export class DemoAutomationDescribeTrigger extends LitElement { | |||||||
|     super.firstUpdated(changedProps); |     super.firstUpdated(changedProps); | ||||||
|     const hass = provideHass(this); |     const hass = provideHass(this); | ||||||
|     hass.updateTranslations(null, "en"); |     hass.updateTranslations(null, "en"); | ||||||
|     hass.updateTranslations("config", "en"); |  | ||||||
|     hass.addEntities(ENTITIES); |     hass.addEntities(ENTITIES); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -19,13 +19,11 @@ import { HaTemplateTrigger } from "../../../../src/panels/config/automation/trig | |||||||
| import { HaTimeTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-time"; | import { HaTimeTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-time"; | ||||||
| import { HaTimePatternTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-time_pattern"; | import { HaTimePatternTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-time_pattern"; | ||||||
| import { HaWebhookTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-webhook"; | import { HaWebhookTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-webhook"; | ||||||
| import { HaPersistentNotificationTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-persistent_notification"; |  | ||||||
| import { HaZoneTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-zone"; | import { HaZoneTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-zone"; | ||||||
| import { HaDeviceTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-device"; | import { HaDeviceTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-device"; | ||||||
| import { HaStateTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-state"; | import { HaStateTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-state"; | ||||||
| import { HaMQTTTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-mqtt"; | import { HaMQTTTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-mqtt"; | ||||||
| import "../../../../src/panels/config/automation/trigger/ha-automation-trigger"; | import "../../../../src/panels/config/automation/trigger/ha-automation-trigger"; | ||||||
| import { HaConversationTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-conversation"; |  | ||||||
|  |  | ||||||
| const SCHEMAS: { name: string; triggers: Trigger[] }[] = [ | const SCHEMAS: { name: string; triggers: Trigger[] }[] = [ | ||||||
|   { |   { | ||||||
| @@ -74,16 +72,6 @@ const SCHEMAS: { name: string; triggers: Trigger[] }[] = [ | |||||||
|     triggers: [{ platform: "webhook", ...HaWebhookTrigger.defaultConfig }], |     triggers: [{ platform: "webhook", ...HaWebhookTrigger.defaultConfig }], | ||||||
|   }, |   }, | ||||||
|  |  | ||||||
|   { |  | ||||||
|     name: "Persistent Notification", |  | ||||||
|     triggers: [ |  | ||||||
|       { |  | ||||||
|         platform: "persistent_notification", |  | ||||||
|         ...HaPersistentNotificationTrigger.defaultConfig, |  | ||||||
|       }, |  | ||||||
|     ], |  | ||||||
|   }, |  | ||||||
|  |  | ||||||
|   { |   { | ||||||
|     name: "Zone", |     name: "Zone", | ||||||
|     triggers: [{ platform: "zone", ...HaZoneTrigger.defaultConfig }], |     triggers: [{ platform: "zone", ...HaZoneTrigger.defaultConfig }], | ||||||
| @@ -113,16 +101,6 @@ const SCHEMAS: { name: string; triggers: Trigger[] }[] = [ | |||||||
|     name: "Device Trigger", |     name: "Device Trigger", | ||||||
|     triggers: [{ platform: "device", ...HaDeviceTrigger.defaultConfig }], |     triggers: [{ platform: "device", ...HaDeviceTrigger.defaultConfig }], | ||||||
|   }, |   }, | ||||||
|   { |  | ||||||
|     name: "Sentence", |  | ||||||
|     triggers: [ |  | ||||||
|       { platform: "conversation", ...HaConversationTrigger.defaultConfig }, |  | ||||||
|       { |  | ||||||
|         platform: "conversation", |  | ||||||
|         command: ["Turn on the lights", "Turn the lights on"], |  | ||||||
|       }, |  | ||||||
|     ], |  | ||||||
|   }, |  | ||||||
| ]; | ]; | ||||||
|  |  | ||||||
| @customElement("demo-automation-editor-trigger") | @customElement("demo-automation-editor-trigger") | ||||||
|   | |||||||
| @@ -1,6 +1,5 @@ | |||||||
| /* eslint-disable lit/no-template-arrow */ | /* eslint-disable lit/no-template-arrow */ | ||||||
|  | import { html, css, LitElement, TemplateResult } from "lit"; | ||||||
| import { css, html, LitElement, nothing } from "lit"; |  | ||||||
| import { customElement, property } from "lit/decorators"; | import { customElement, property } from "lit/decorators"; | ||||||
| import "../../../../src/components/ha-card"; | import "../../../../src/components/ha-card"; | ||||||
| import "../../../../src/components/trace/hat-script-graph"; | import "../../../../src/components/trace/hat-script-graph"; | ||||||
| @@ -30,9 +29,9 @@ const traces: DemoTrace[] = [ | |||||||
| export class DemoAutomationTraceTimeline extends LitElement { | export class DemoAutomationTraceTimeline extends LitElement { | ||||||
|   @property({ attribute: false }) hass?: HomeAssistant; |   @property({ attribute: false }) hass?: HomeAssistant; | ||||||
|  |  | ||||||
|   protected render() { |   protected render(): TemplateResult { | ||||||
|     if (!this.hass) { |     if (!this.hass) { | ||||||
|       return nothing; |       return html``; | ||||||
|     } |     } | ||||||
|     return html` |     return html` | ||||||
|       ${traces.map( |       ${traces.map( | ||||||
|   | |||||||
| @@ -1,15 +1,14 @@ | |||||||
| /* eslint-disable lit/no-template-arrow */ | /* eslint-disable lit/no-template-arrow */ | ||||||
|  | import { html, css, LitElement, TemplateResult } from "lit"; | ||||||
| import { css, html, LitElement, nothing } from "lit"; |  | ||||||
| import { customElement, property, state } from "lit/decorators"; |  | ||||||
| import "../../../../src/components/ha-card"; | import "../../../../src/components/ha-card"; | ||||||
| import "../../../../src/components/trace/hat-script-graph"; | import "../../../../src/components/trace/hat-script-graph"; | ||||||
| import "../../../../src/components/trace/hat-trace-timeline"; | import "../../../../src/components/trace/hat-trace-timeline"; | ||||||
|  | import { customElement, property, state } from "lit/decorators"; | ||||||
| import { provideHass } from "../../../../src/fake_data/provide_hass"; | import { provideHass } from "../../../../src/fake_data/provide_hass"; | ||||||
| import { HomeAssistant } from "../../../../src/types"; | import { HomeAssistant } from "../../../../src/types"; | ||||||
|  | import { DemoTrace } from "../../data/traces/types"; | ||||||
| import { basicTrace } from "../../data/traces/basic_trace"; | import { basicTrace } from "../../data/traces/basic_trace"; | ||||||
| import { motionLightTrace } from "../../data/traces/motion-light-trace"; | import { motionLightTrace } from "../../data/traces/motion-light-trace"; | ||||||
| import { DemoTrace } from "../../data/traces/types"; |  | ||||||
|  |  | ||||||
| const traces: DemoTrace[] = [basicTrace, motionLightTrace]; | const traces: DemoTrace[] = [basicTrace, motionLightTrace]; | ||||||
|  |  | ||||||
| @@ -19,9 +18,9 @@ export class DemoAutomationTrace extends LitElement { | |||||||
|  |  | ||||||
|   @state() private _selected = {}; |   @state() private _selected = {}; | ||||||
|  |  | ||||||
|   protected render() { |   protected render(): TemplateResult { | ||||||
|     if (!this.hass) { |     if (!this.hass) { | ||||||
|       return nothing; |       return html``; | ||||||
|     } |     } | ||||||
|     return html` |     return html` | ||||||
|       ${traces.map( |       ${traces.map( | ||||||
|   | |||||||
| @@ -156,6 +156,18 @@ The `title ` option should not be used without a description. | |||||||
|  |  | ||||||
| *Documentation coming soon* | *Documentation coming soon* | ||||||
|  |  | ||||||
|  | **Right to left** | ||||||
|  |  | ||||||
|  | <ha-alert alert-type="success" rtl> | ||||||
|  |   This is an info alert — check it out! | ||||||
|  | </ha-alert> | ||||||
|  |  | ||||||
|  | ```html | ||||||
|  | <ha-alert alert-type="success" rtl> | ||||||
|  |   This is an info alert — check it out! | ||||||
|  | </ha-alert> | ||||||
|  | ``` | ||||||
|  |  | ||||||
| ### API | ### API | ||||||
| **Properties/Attributes** | **Properties/Attributes** | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										3
									
								
								gallery/src/pages/components/ha-bar-slider.markdown
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								gallery/src/pages/components/ha-bar-slider.markdown
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | --- | ||||||
|  | title: Bar Slider | ||||||
|  | --- | ||||||
| @@ -2,7 +2,7 @@ import { css, html, LitElement, TemplateResult } from "lit"; | |||||||
| import { customElement, state } from "lit/decorators"; | import { customElement, state } from "lit/decorators"; | ||||||
| import { ifDefined } from "lit/directives/if-defined"; | import { ifDefined } from "lit/directives/if-defined"; | ||||||
| import { repeat } from "lit/directives/repeat"; | import { repeat } from "lit/directives/repeat"; | ||||||
| import "../../../../src/components/ha-control-slider"; | import "../../../../src/components/ha-bar-slider"; | ||||||
| import "../../../../src/components/ha-card"; | import "../../../../src/components/ha-card"; | ||||||
| 
 | 
 | ||||||
| const sliders: { | const sliders: { | ||||||
| @@ -46,7 +46,7 @@ const sliders: { | |||||||
|   }, |   }, | ||||||
| ]; | ]; | ||||||
| 
 | 
 | ||||||
| @customElement("demo-components-ha-control-slider") | @customElement("demo-components-ha-bar-slider") | ||||||
| export class DemoHaBarSlider extends LitElement { | export class DemoHaBarSlider extends LitElement { | ||||||
|   @state() private value = 50; |   @state() private value = 50; | ||||||
| 
 | 
 | ||||||
| @@ -86,7 +86,7 @@ export class DemoHaBarSlider extends LitElement { | |||||||
|             <div class="card-content"> |             <div class="card-content"> | ||||||
|               <label id=${id}>${label}</label> |               <label id=${id}>${label}</label> | ||||||
|               <pre>Config: ${JSON.stringify(config)}</pre> |               <pre>Config: ${JSON.stringify(config)}</pre> | ||||||
|               <ha-control-slider |               <ha-bar-slider | ||||||
|                 .value=${this.value} |                 .value=${this.value} | ||||||
|                 .mode=${config.mode} |                 .mode=${config.mode} | ||||||
|                 class=${ifDefined(config.class)} |                 class=${ifDefined(config.class)} | ||||||
| @@ -94,7 +94,7 @@ export class DemoHaBarSlider extends LitElement { | |||||||
|                 @slider-moved=${this.handleSliderMoved} |                 @slider-moved=${this.handleSliderMoved} | ||||||
|                 aria-labelledby=${id} |                 aria-labelledby=${id} | ||||||
|               > |               > | ||||||
|               </ha-control-slider> |               </ha-bar-slider> | ||||||
|             </div> |             </div> | ||||||
|           </ha-card> |           </ha-card> | ||||||
|         `;
 |         `;
 | ||||||
| @@ -106,7 +106,7 @@ export class DemoHaBarSlider extends LitElement { | |||||||
|             ${repeat(sliders, (slider) => { |             ${repeat(sliders, (slider) => { | ||||||
|               const { id, label, ...config } = slider; |               const { id, label, ...config } = slider; | ||||||
|               return html` |               return html` | ||||||
|                 <ha-control-slider |                 <ha-bar-slider | ||||||
|                   .value=${this.value} |                   .value=${this.value} | ||||||
|                   .mode=${config.mode} |                   .mode=${config.mode} | ||||||
|                   vertical |                   vertical | ||||||
| @@ -115,7 +115,7 @@ export class DemoHaBarSlider extends LitElement { | |||||||
|                   @slider-moved=${this.handleSliderMoved} |                   @slider-moved=${this.handleSliderMoved} | ||||||
|                   aria-label=${label} |                   aria-label=${label} | ||||||
|                 > |                 > | ||||||
|                 </ha-control-slider> |                 </ha-bar-slider> | ||||||
|               `;
 |               `;
 | ||||||
|             })} |             })} | ||||||
|           </div> |           </div> | ||||||
| @@ -141,11 +141,11 @@ export class DemoHaBarSlider extends LitElement { | |||||||
|         font-weight: 600; |         font-weight: 600; | ||||||
|       } |       } | ||||||
|       .custom { |       .custom { | ||||||
|         --control-slider-color: #ffcf4c; |         --slider-bar-color: #ffcf4c; | ||||||
|         --control-slider-background: #ffcf4c; |         --slider-bar-background: #ffcf4c; | ||||||
|         --control-slider-background-opacity: 0.2; |         --slider-bar-background-opacity: 0.2; | ||||||
|         --control-slider-thickness: 100px; |         --slider-bar-thickness: 100px; | ||||||
|         --control-slider-border-radius: 24px; |         --slider-bar-border-radius: 24px; | ||||||
|       } |       } | ||||||
|       .vertical-sliders { |       .vertical-sliders { | ||||||
|         height: 300px; |         height: 300px; | ||||||
| @@ -165,6 +165,6 @@ export class DemoHaBarSlider extends LitElement { | |||||||
| 
 | 
 | ||||||
| declare global { | declare global { | ||||||
|   interface HTMLElementTagNameMap { |   interface HTMLElementTagNameMap { | ||||||
|     "demo-components-ha-control-slider": DemoHaBarSlider; |     "demo-components-ha-bar-slider": DemoHaBarSlider; | ||||||
|   } |   } | ||||||
| } | } | ||||||
							
								
								
									
										3
									
								
								gallery/src/pages/components/ha-bar-switch.markdown
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								gallery/src/pages/components/ha-bar-switch.markdown
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | --- | ||||||
|  | title: Bar Switch | ||||||
|  | --- | ||||||
| @@ -8,7 +8,7 @@ import { css, html, LitElement, TemplateResult } from "lit"; | |||||||
| import { customElement, state } from "lit/decorators"; | import { customElement, state } from "lit/decorators"; | ||||||
| import { ifDefined } from "lit/directives/if-defined"; | import { ifDefined } from "lit/directives/if-defined"; | ||||||
| import { repeat } from "lit/directives/repeat"; | import { repeat } from "lit/directives/repeat"; | ||||||
| import "../../../../src/components/ha-control-switch"; | import "../../../../src/components/ha-bar-switch"; | ||||||
| import "../../../../src/components/ha-card"; | import "../../../../src/components/ha-card"; | ||||||
| 
 | 
 | ||||||
| const switches: { | const switches: { | ||||||
| @@ -39,8 +39,8 @@ const switches: { | |||||||
|   }, |   }, | ||||||
| ]; | ]; | ||||||
| 
 | 
 | ||||||
| @customElement("demo-components-ha-control-switch") | @customElement("demo-components-ha-bar-switch") | ||||||
| export class DemoHaControlSwitch extends LitElement { | export class DemoHaBarSwitch extends LitElement { | ||||||
|   @state() private checked = false; |   @state() private checked = false; | ||||||
| 
 | 
 | ||||||
|   handleValueChanged(e: any) { |   handleValueChanged(e: any) { | ||||||
| @@ -56,7 +56,7 @@ export class DemoHaControlSwitch extends LitElement { | |||||||
|             <div class="card-content"> |             <div class="card-content"> | ||||||
|               <label id=${id}>${label}</label> |               <label id=${id}>${label}</label> | ||||||
|               <pre>Config: ${JSON.stringify(config)}</pre> |               <pre>Config: ${JSON.stringify(config)}</pre> | ||||||
|               <ha-control-switch |               <ha-bar-switch | ||||||
|                 .checked=${this.checked} |                 .checked=${this.checked} | ||||||
|                 class=${ifDefined(config.class)} |                 class=${ifDefined(config.class)} | ||||||
|                 @change=${this.handleValueChanged} |                 @change=${this.handleValueChanged} | ||||||
| @@ -66,7 +66,7 @@ export class DemoHaControlSwitch extends LitElement { | |||||||
|                 disabled=${ifDefined(config.disabled)} |                 disabled=${ifDefined(config.disabled)} | ||||||
|                 reversed=${ifDefined(config.reversed)} |                 reversed=${ifDefined(config.reversed)} | ||||||
|               > |               > | ||||||
|               </ha-control-switch> |               </ha-bar-switch> | ||||||
|             </div> |             </div> | ||||||
|           </ha-card> |           </ha-card> | ||||||
|         `;
 |         `;
 | ||||||
| @@ -78,7 +78,7 @@ export class DemoHaControlSwitch extends LitElement { | |||||||
|             ${repeat(switches, (sw) => { |             ${repeat(switches, (sw) => { | ||||||
|               const { id, label, ...config } = sw; |               const { id, label, ...config } = sw; | ||||||
|               return html` |               return html` | ||||||
|                 <ha-control-switch |                 <ha-bar-switch | ||||||
|                   .checked=${this.checked} |                   .checked=${this.checked} | ||||||
|                   vertical |                   vertical | ||||||
|                   class=${ifDefined(config.class)} |                   class=${ifDefined(config.class)} | ||||||
| @@ -89,7 +89,7 @@ export class DemoHaControlSwitch extends LitElement { | |||||||
|                   disabled=${ifDefined(config.disabled)} |                   disabled=${ifDefined(config.disabled)} | ||||||
|                   reversed=${ifDefined(config.reversed)} |                   reversed=${ifDefined(config.reversed)} | ||||||
|                 > |                 > | ||||||
|                 </ha-control-switch> |                 </ha-bar-switch> | ||||||
|               `;
 |               `;
 | ||||||
|             })} |             })} | ||||||
|           </div> |           </div> | ||||||
| @@ -115,11 +115,11 @@ export class DemoHaControlSwitch extends LitElement { | |||||||
|         font-weight: 600; |         font-weight: 600; | ||||||
|       } |       } | ||||||
|       .custom { |       .custom { | ||||||
|         --control-switch-on-color: var(--green-color); |         --switch-bar-on-color: var(--green-color); | ||||||
|         --control-switch-off-color: var(--red-color); |         --switch-bar-off-color: var(--red-color); | ||||||
|         --control-switch-thickness: 100px; |         --switch-bar-thickness: 100px; | ||||||
|         --control-switch-border-radius: 24px; |         --switch-bar-border-radius: 24px; | ||||||
|         --control-switch-padding: 6px; |         --switch-bar-padding: 6px; | ||||||
|         --mdc-icon-size: 24px; |         --mdc-icon-size: 24px; | ||||||
|       } |       } | ||||||
|       .vertical-switches { |       .vertical-switches { | ||||||
| @@ -140,6 +140,6 @@ export class DemoHaControlSwitch extends LitElement { | |||||||
| 
 | 
 | ||||||
| declare global { | declare global { | ||||||
|   interface HTMLElementTagNameMap { |   interface HTMLElementTagNameMap { | ||||||
|     "demo-components-ha-control-switch": DemoHaControlSwitch; |     "demo-components-ha-bar-switch": DemoHaBarSwitch; | ||||||
|   } |   } | ||||||
| } | } | ||||||
| @@ -1,3 +0,0 @@ | |||||||
| --- |  | ||||||
| title: Control Button |  | ||||||
| --- |  | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user