Defer loading of dev tools

This commit is contained in:
Paulus Schoutsen 2016-07-12 08:59:07 -07:00
parent 78c8e680b2
commit e7ee8c54bd
24 changed files with 484 additions and 474 deletions

View File

@ -21,7 +21,8 @@ function md5(filename) {
var appPaths = ['/', '/states', '/logbook', '/history', '/map',
'/devService', '/devState', '/devEvent', '/devInfo', '/devTemplate'];
var fingerprinted = ['frontend.html', 'mdi.html', 'core.js', 'partial-map.html'];
var fingerprinted = ['frontend.html', 'mdi.html', 'core.js', 'partial-map.html',
'dev-tools.html'];
var dynamicUrlToDependencies = {};

View File

@ -16,24 +16,27 @@ function minifyHTML(html) {
});
}
var toProcess = [
const baseVulcanOptions = {
inlineScripts: true,
inlineCss: true,
implicitStrip: true,
stripComments: true,
};
const toProcess = [
{
source: 'src/home-assistant.html',
output: 'frontend.html',
vulcan: new Vulcanize({
vulcan: new Vulcanize(Object.assign({}, baseVulcanOptions, {
stripExcludes: [
'bower_components/font-roboto/roboto.html',
],
inlineScripts: true,
inlineCss: true,
implicitStrip: true,
stripComments: true,
}),
})),
},
{
source: 'src/layouts/partial-map.html',
output: 'partial-map.html',
vulcan: new Vulcanize({
vulcan: new Vulcanize(Object.assign({}, baseVulcanOptions, {
stripExcludes: [
'bower_components/polymer/polymer.html',
'bower_components/paper-toolbar/paper-toolbar.html',
@ -41,16 +44,28 @@ var toProcess = [
'bower_components/iron-icon/iron-icon.html',
'bower_components/iron-image/iron-image.html',
],
inlineScripts: true,
inlineCss: true,
implicitStrip: true,
stripComments: true,
}),
})),
},
{
source: 'src/entry-points/dev-tools.html',
output: 'dev-tools.html',
vulcan: new Vulcanize(Object.assign({}, baseVulcanOptions, {
stripExcludes: [
'bower_components/polymer/polymer.html',
'bower_components/paper-button/paper-button.html',
'bower_components/paper-input/paper-input.html',
'bower_components/paper-icon-button/paper-icon-button.html',
'bower_components/paper-spinner/paper-spinner.html',
'bower_components/paper-toolbar/paper-toolbar.html',
'bower_components/paper-menu/paper-menu.html',
'bower_components/paper-scroll-header-panel/paper-scroll-header-panel.html',
],
})),
},
];
toProcess.forEach(function (info) {
info.vulcan.process(info.source, function (err, inlinedHtml) {
toProcess.forEach(info => {
info.vulcan.process(info.source, (err, inlinedHtml) => {
if (err !== null) {
console.error(info.source, err);
return;

View File

@ -2,8 +2,6 @@
<link rel="import" href="../../bower_components/paper-menu/paper-menu.html">
<link rel="import" href="domain-icon.html">
<dom-module id="services-list">
<style>
ul {
@ -33,3 +31,47 @@
</ul>
</template>
</dom-module>
<script>
Polymer({
is: 'services-list',
behaviors: [window.hassBehavior],
properties: {
hass: {
type: Object,
},
serviceDomains: {
type: Array,
bindNuclear: function (hass) {
return hass.serviceGetters.entityMap;
},
},
},
computeDomains(serviceDomains) {
return serviceDomains
.valueSeq()
.map(function (domain) { return domain.domain; })
.sort()
.toJS();
},
computeServices(serviceDomains, domain) {
return serviceDomains
.get(domain)
.get('services')
.keySeq()
.toArray();
},
serviceClicked(ev) {
ev.preventDefault();
this.fire(
'service-selected', { domain: ev.model.domain,
service: ev.model.service });
},
});
</script>

View File

@ -1,43 +0,0 @@
import Polymer from '../polymer';
import './domain-icon';
export default new Polymer({
is: 'services-list',
behaviors: [window.hassBehavior],
properties: {
hass: {
type: Object,
},
serviceDomains: {
type: Array,
bindNuclear: hass => hass.serviceGetters.entityMap,
},
},
computeDomains(serviceDomains) {
return serviceDomains
.valueSeq()
.map((domain) => domain.domain)
.sort()
.toJS();
},
computeServices(serviceDomains, domain) {
return serviceDomains
.get(domain)
.get('services')
.keySeq()
.toArray();
},
serviceClicked(ev) {
ev.preventDefault();
this.fire(
'service-selected', { domain: ev.model.domain,
service: ev.model.service });
},
});

View File

@ -1,4 +1,4 @@
import HomeAssistant from '../home-assistant-js/dist/homeassistant.es6';
import HomeAssistant from '../../home-assistant-js/dist/homeassistant.es6';
const hass = new HomeAssistant();

View File

@ -0,0 +1,5 @@
<link rel='import' href='../layouts/partial-dev-call-service.html'>
<link rel='import' href='../layouts/partial-dev-fire-event.html'>
<link rel='import' href='../layouts/partial-dev-set-state.html'>
<link rel='import' href='../layouts/partial-dev-template.html'>
<link rel='import' href='../layouts/partial-dev-info.html'>

View File

@ -5,11 +5,6 @@
<link rel='import' href='../layouts/partial-logbook.html'>
<link rel='import' href='../layouts/partial-history.html'>
<!-- <link rel='import' href='../layouts/partial-map.html'> -->
<link rel='import' href='../layouts/partial-dev-call-service.html'>
<link rel='import' href='../layouts/partial-dev-fire-event.html'>
<link rel='import' href='../layouts/partial-dev-set-state.html'>
<link rel='import' href='../layouts/partial-dev-template.html'>
<link rel='import' href='../layouts/partial-dev-info.html'>
<link rel='import' href='../managers/notification-manager.html'>
<link rel="import" href="../dialogs/more-info-dialog.html">
<link rel="import" href="../dialogs/ha-voice-command-dialog.html">

View File

@ -3,12 +3,6 @@ import Polymer from '../polymer';
import '../layouts/partial-cards';
import '../layouts/partial-logbook';
import '../layouts/partial-history';
// import '../layouts/partial-map';
import '../layouts/partial-dev-call-service';
import '../layouts/partial-dev-fire-event';
import '../layouts/partial-dev-set-state';
import '../layouts/partial-dev-template';
import '../layouts/partial-dev-info';
import '../managers/notification-manager';
import '../dialogs/more-info-dialog';
import '../dialogs/ha-voice-command-dialog';
@ -110,9 +104,10 @@ export default new Polymer({
if (this.narrow) {
this.$.drawer.closeDrawer();
}
if (window.deferredLoading[newValue]) {
this.importHref(window.deferredLoading[newValue]);
window.deferredLoading[newValue] = false;
const key = newValue.substr(0, 3) === 'dev' ? 'dev' : newValue;
if (window.deferredLoading[key]) {
this.importHref(window.deferredLoading[key]);
window.deferredLoading[key] = false;
}
},

View File

@ -32,3 +32,29 @@
</paper-scroll-header-panel>
</template>
</dom-module>
<script>
Polymer({
is: 'partial-base',
properties: {
narrow: {
type: Boolean,
value: false,
},
showMenu: {
type: Boolean,
value: false,
},
},
computeMenuButtonClass: function (narrow, showMenu) {
return !narrow && showMenu ? 'menu-icon invisible' : 'menu-icon';
},
toggleMenu: function () {
this.fire('open-menu');
},
});
</script>

View File

@ -1,25 +0,0 @@
import Polymer from '../polymer';
export default new Polymer({
is: 'partial-base',
properties: {
narrow: {
type: Boolean,
value: false,
},
showMenu: {
type: Boolean,
value: false,
},
},
computeMenuButtonClass(narrow, showMenu) {
return !narrow && showMenu ? 'menu-icon invisible' : 'menu-icon';
},
toggleMenu() {
this.fire('open-menu');
},
});

View File

@ -1,6 +1,5 @@
import Polymer from '../polymer';
import './partial-base';
import '../components/ha-cards';
export default new Polymer({

View File

@ -61,3 +61,87 @@
</partial-base>
</template>
</dom-module>
<script>
Polymer({
is: 'partial-dev-call-service',
properties: {
hass: {
type: Object,
},
narrow: {
type: Boolean,
value: false,
},
showMenu: {
type: Boolean,
value: false,
},
domain: {
type: String,
value: '',
},
service: {
type: String,
value: '',
},
serviceData: {
type: String,
value: '',
},
description: {
type: String,
computed: 'computeDescription(hass, domain, service)',
},
},
computeDescription: function (hass, domain, service) {
return hass.reactor.evaluate([
hass.serviceGetters.entityMap,
function (map) {
if (map.has(domain) && map.get(domain).get('services').has(service)) {
return JSON.stringify(
map
.get(domain)
.get('services')
.get(service)
.toJS(),
null, 2);
}
return 'No description available';
},
]);
},
serviceSelected: function (ev) {
this.domain = ev.detail.domain;
this.service = ev.detail.service;
},
callService: function () {
var serviceData;
try {
serviceData = this.serviceData ? JSON.parse(this.serviceData) : {};
} catch (err) {
/* eslint-disable no-alert */
alert('Error parsing JSON: ' + err);
/* eslint-enable no-alert */
return;
}
this.hass.serviceActions.callService(this.domain, this.service, serviceData);
},
computeFormClasses: function (narrow) {
return narrow ?
'content fit' : 'content fit layout horizontal';
},
});
</script>

View File

@ -1,85 +0,0 @@
import Polymer from '../polymer';
import './partial-base';
import '../components/services-list';
export default new Polymer({
is: 'partial-dev-call-service',
properties: {
hass: {
type: Object,
},
narrow: {
type: Boolean,
value: false,
},
showMenu: {
type: Boolean,
value: false,
},
domain: {
type: String,
value: '',
},
service: {
type: String,
value: '',
},
serviceData: {
type: String,
value: '',
},
description: {
type: String,
computed: 'computeDescription(hass, domain, service)',
},
},
computeDescription(hass, domain, service) {
return hass.reactor.evaluate([
hass.serviceGetters.entityMap,
map => {
if (map.has(domain) && map.get(domain).get('services').has(service)) {
return JSON.stringify(
map
.get(domain)
.get('services')
.get(service)
.toJS(),
null, 2);
}
return 'No description available';
},
]);
},
serviceSelected(ev) {
this.domain = ev.detail.domain;
this.service = ev.detail.service;
},
callService() {
let serviceData;
try {
serviceData = this.serviceData ? JSON.parse(this.serviceData) : {};
} catch (err) {
/* eslint-disable no-alert */
alert(`Error parsing JSON: ${err}`);
/* eslint-enable no-alert */
return;
}
this.hass.serviceActions.callService(this.domain, this.service, serviceData);
},
computeFormClasses(narrow) {
return `content fit ${narrow ? '' : 'layout horizontal'}`;
},
});

View File

@ -56,3 +56,59 @@
</template>
</dom-module>
<script>
Polymer({
is: 'partial-dev-fire-event',
properties: {
hass: {
type: Object,
},
narrow: {
type: Boolean,
value: false,
},
showMenu: {
type: Boolean,
value: false,
},
eventType: {
type: String,
value: '',
},
eventData: {
type: String,
value: '',
},
},
eventSelected: function (ev) {
this.eventType = ev.detail.eventType;
},
fireEvent: function () {
var eventData;
try {
eventData = this.eventData ? JSON.parse(this.eventData) : {};
} catch (err) {
/* eslint-disable no-alert */
alert('Error parsing JSON: ' + err);
/* eslint-enable no-alert */
return;
}
this.hass.eventActions.fireEvent(this.eventType, eventData);
},
computeFormClasses: function (narrow) {
return narrow ?
'content fit' : 'content fit layout horizontal';
},
});
</script>

View File

@ -1,56 +0,0 @@
import Polymer from '../polymer';
import './partial-base';
export default new Polymer({
is: 'partial-dev-fire-event',
properties: {
hass: {
type: Object,
},
narrow: {
type: Boolean,
value: false,
},
showMenu: {
type: Boolean,
value: false,
},
eventType: {
type: String,
value: '',
},
eventData: {
type: String,
value: '',
},
},
eventSelected(ev) {
this.eventType = ev.detail.eventType;
},
fireEvent() {
let eventData;
try {
eventData = this.eventData ? JSON.parse(this.eventData) : {};
} catch (err) {
/* eslint-disable no-alert */
alert(`Error parsing JSON: ${err}`);
/* eslint-enable no-alert */
return;
}
this.hass.eventActions.fireEvent(this.eventType, eventData);
},
computeFormClasses(narrow) {
return `content fit ${narrow ? '' : 'layout horizontal'}`;
},
});

View File

@ -89,3 +89,64 @@
</partial-base>
</template>
</dom-module>
<script>
Polymer({
is: 'partial-dev-info',
behaviors: [window.hassBehavior],
properties: {
hass: {
type: Object,
},
narrow: {
type: Boolean,
value: false,
},
showMenu: {
type: Boolean,
value: false,
},
hassVersion: {
type: String,
bindNuclear: function (hass) {
return hass.configGetters.serverVersion;
},
},
polymerVersion: {
type: String,
value: Polymer.version,
},
nuclearVersion: {
type: String,
value: '1.3.0',
},
errorLog: {
type: String,
value: '',
},
},
attached: function () {
this.refreshErrorLog();
},
refreshErrorLog: function (ev) {
if (ev) ev.preventDefault();
this.errorLog = 'Loading error log…';
this.hass.errorLogActions.fetchErrorLog().then(
function (log) {
this.errorLog = log || 'No errors have been reported.';
}.bind(this));
},
});
</script>

View File

@ -1,58 +0,0 @@
import Polymer from '../polymer';
import './partial-base';
export default new Polymer({
is: 'partial-dev-info',
behaviors: [window.hassBehavior],
properties: {
hass: {
type: Object,
},
narrow: {
type: Boolean,
value: false,
},
showMenu: {
type: Boolean,
value: false,
},
hassVersion: {
type: String,
bindNuclear: hass => hass.configGetters.serverVersion,
},
polymerVersion: {
type: String,
value: Polymer.version,
},
nuclearVersion: {
type: String,
value: '1.3.0',
},
errorLog: {
type: String,
value: '',
},
},
attached() {
this.refreshErrorLog();
},
refreshErrorLog(ev) {
if (ev) ev.preventDefault();
this.errorLog = 'Loading error log…';
this.hass.errorLogActions.fetchErrorLog().then(
log => { this.errorLog = log || 'No errors have been reported.'; });
},
});

View File

@ -57,3 +57,80 @@
</partial-base>
</template>
</dom-module>
<script>
Polymer({
is: 'partial-dev-set-state',
properties: {
hass: {
type: Object,
},
narrow: {
type: Boolean,
value: false,
},
showMenu: {
type: Boolean,
value: false,
},
entityId: {
type: String,
value: '',
},
state: {
type: String,
value: '',
},
stateAttributes: {
type: String,
value: '',
},
},
setStateData: function (stateData) {
var value = stateData ? JSON.stringify(stateData, null, ' ') : '';
this.$.inputData.value = value;
// not according to the spec but it works...
this.$.inputDataWrapper.update(this.$.inputData);
},
entitySelected: function (ev) {
var state = this.hass.reactor.evaluate(this.hass.entityGetters.byId(ev.detail.entityId));
this.entityId = state.entityId;
this.state = state.state;
this.stateAttributes = JSON.stringify(state.attributes, null, ' ');
},
handleSetState: function () {
var attr;
try {
attr = this.stateAttributes ? JSON.parse(this.stateAttributes) : {};
} catch (err) {
/* eslint-disable no-alert */
alert('Error parsing JSON: ' + err);
/* eslint-enable no-alert */
return;
}
this.hass.entityActions.save({
entityId: this.entityId,
state: this.state,
attributes: attr,
});
},
computeFormClasses: function (narrow) {
return narrow ?
'content fit' : 'content fit layout horizontal';
},
});
</script>

View File

@ -1,77 +0,0 @@
import Polymer from '../polymer';
import './partial-base';
export default new Polymer({
is: 'partial-dev-set-state',
properties: {
hass: {
type: Object,
},
narrow: {
type: Boolean,
value: false,
},
showMenu: {
type: Boolean,
value: false,
},
entityId: {
type: String,
value: '',
},
state: {
type: String,
value: '',
},
stateAttributes: {
type: String,
value: '',
},
},
setStateData(stateData) {
const value = stateData ? JSON.stringify(stateData, null, ' ') : '';
this.$.inputData.value = value;
// not according to the spec but it works...
this.$.inputDataWrapper.update(this.$.inputData);
},
entitySelected(ev) {
const state = this.hass.reactor.evaluate(this.hass.entityGetters.byId(ev.detail.entityId));
this.entityId = state.entityId;
this.state = state.state;
this.stateAttributes = JSON.stringify(state.attributes, null, ' ');
},
handleSetState() {
let attr;
try {
attr = this.stateAttributes ? JSON.parse(this.stateAttributes) : {};
} catch (err) {
/* eslint-disable no-alert */
alert(`Error parsing JSON: ${err}`);
/* eslint-enable no-alert */
return;
}
this.hass.entityActions.save({
entityId: this.entityId,
state: this.state,
attributes: attr,
});
},
computeFormClasses(narrow) {
return `content fit ${narrow ? '' : 'layout horizontal'}`;
},
});

View File

@ -77,3 +77,96 @@
</partial-base>
</template>
</dom-module>
<script>
Polymer({
is: 'partial-dev-template',
behaviors: [window.hassBehavior],
properties: {
hass: {
type: Object,
},
narrow: {
type: Boolean,
value: false,
},
showMenu: {
type: Boolean,
value: false,
},
error: {
type: Boolean,
value: false,
},
rendering: {
type: Boolean,
value: false,
},
template: {
type: String,
/* eslint-disable max-len */
value: '{%- if is_state("device_tracker.paulus", "home") and \n' +
' is_state("device_tracker.anne_therese", "home") -%}\n' +
'\n' +
' You are both home, you silly\n' +
'\n' +
'{%- else -%}\n' +
'\n' +
' Anne Therese is at {{ states("device_tracker.anne_therese") }} and ' +
'Paulus is at {{ states("device_tracker.paulus") }}\n' +
'\n' +
'{%- endif %}\n' +
'\n' +
'For loop example:\n' +
'\n' +
'{% for state in states.sensor -%}\n' +
' {%- if loop.first %}The {% elif loop.last %} and the {% else %}, the {% endif -%}\n' +
' {{ state.name | lower }} is {{state.state}} {{- state.attributes.unit_of_measurement}}\n' +
'{%- endfor -%}.',
/* eslint-enable max-len */
observer: 'templateChanged',
},
processed: {
type: String,
value: '',
},
},
computeFormClasses: function (narrow) {
return narrow ?
'content fit' : 'content fit layout horizontal';
},
computeRenderedClasses: function (error) {
return error ? 'error rendered' : 'rendered';
},
templateChanged: function () {
if (this.error) {
this.error = false;
}
this.debounce('render-template', this.renderTemplate.bind(this), 500);
},
renderTemplate: function () {
this.rendering = true;
this.hass.templateActions.render(this.template).then(function (processed) {
this.processed = processed;
this.rendering = false;
}.bind(this), function (error) {
this.processed = error.message;
this.error = true;
this.rendering = false;
}.bind(this));
},
});
</script>

View File

@ -1,93 +0,0 @@
import Polymer from '../polymer';
import './partial-base';
export default new Polymer({
is: 'partial-dev-template',
behaviors: [window.hassBehavior],
properties: {
hass: {
type: Object,
},
narrow: {
type: Boolean,
value: false,
},
showMenu: {
type: Boolean,
value: false,
},
error: {
type: Boolean,
value: false,
},
rendering: {
type: Boolean,
value: false,
},
template: {
type: String,
/* eslint-disable max-len */
value: '{%- if is_state("device_tracker.paulus", "home") and \n' +
' is_state("device_tracker.anne_therese", "home") -%}\n' +
'\n' +
' You are both home, you silly\n' +
'\n' +
'{%- else -%}\n' +
'\n' +
' Anne Therese is at {{ states("device_tracker.anne_therese") }} and ' +
'Paulus is at {{ states("device_tracker.paulus") }}\n' +
'\n' +
'{%- endif %}\n' +
'\n' +
'For loop example:\n' +
'\n' +
'{% for state in states.sensor -%}\n' +
' {%- if loop.first %}The {% elif loop.last %} and the {% else %}, the {% endif -%}\n' +
' {{ state.name | lower }} is {{state.state}} {{- state.attributes.unit_of_measurement}}\n' +
'{%- endfor -%}.',
/* eslint-enable max-len */
observer: 'templateChanged',
},
processed: {
type: String,
value: '',
},
},
computeFormClasses(narrow) {
return `content fit ${narrow ? '' : 'layout horizontal'}`;
},
computeRenderedClasses(error) {
return error ? 'error rendered' : 'rendered';
},
templateChanged() {
if (this.error) {
this.error = false;
}
this.debounce('render-template', this.renderTemplate, 500);
},
renderTemplate() {
this.rendering = true;
this.hass.templateActions.render(this.template).then(processed => {
this.processed = processed;
this.rendering = false;
}, error => {
this.processed = error.message;
this.error = true;
this.rendering = false;
});
},
});

View File

@ -1,6 +1,5 @@
import Polymer from '../polymer';
import './partial-base';
import '../components/state-history-charts';
export default new Polymer({

View File

@ -1,6 +1,5 @@
import Polymer from '../polymer';
import './partial-base';
import '../components/logbook-entry';
export default new Polymer({

View File

@ -9,7 +9,7 @@ var definePlugin = new webpack.DefinePlugin({
module.exports = {
entry: {
_ui_compiled: './src/home-assistant.js',
_core_compiled: './src/app-core.js',
_core_compiled: './src/entry-points/app-core.js',
_demo_data_compiled: './home-assistant-js/demo_data/expose_window.js',
},
output: {