mirror of
https://github.com/home-assistant/home-assistant.io.git
synced 2025-07-25 10:17:23 +00:00
Issue 2282 performance (#2287)
* switch components page to flexbox and mustachejs * greatly improved website performance * only load images when actually showing the box * removed isotope JS * Apply compression to HTML
This commit is contained in:
parent
38906c5216
commit
889d8d6dfd
11
_config.yml
11
_config.yml
@ -117,6 +117,17 @@ google_analytics_tracking_id: UA-57927901-1
|
|||||||
# Facebook Like
|
# Facebook Like
|
||||||
facebook_like: true
|
facebook_like: true
|
||||||
|
|
||||||
|
# Liquid template compressor
|
||||||
|
compress_html:
|
||||||
|
clippings: []
|
||||||
|
comments: []
|
||||||
|
endings: []
|
||||||
|
ignore:
|
||||||
|
envs: []
|
||||||
|
blanklines: true
|
||||||
|
profile: false
|
||||||
|
startings: []
|
||||||
|
|
||||||
social:
|
social:
|
||||||
visible: false
|
visible: false
|
||||||
facebook:
|
facebook:
|
||||||
|
249
sass/custom/_component_page.scss
Normal file
249
sass/custom/_component_page.scss
Normal file
@ -0,0 +1,249 @@
|
|||||||
|
#components-page{
|
||||||
|
.component-search{
|
||||||
|
margin-bottom: 24px;
|
||||||
|
|
||||||
|
input{
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
background-color: #fefefe;
|
||||||
|
border-radius: 2px;
|
||||||
|
border: 1px solid;
|
||||||
|
border-color: #7c7c7c #c3c3c3 #ddd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: $lap-end) {
|
||||||
|
#components-page {
|
||||||
|
.filter-button-group {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 8px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
|
||||||
|
&.current {
|
||||||
|
background-color: #3A5561;
|
||||||
|
background-image: linear-gradient(to bottom, #3A5561,#3F6B7D);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width: $desk-start) {
|
||||||
|
#components-page {
|
||||||
|
.filter-button-group {
|
||||||
|
.featured {
|
||||||
|
margin: 12px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.added_in_current_version {
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.added_two_versions_ago {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
display: block;
|
||||||
|
background: 0;
|
||||||
|
color: black;
|
||||||
|
box-shadow: none;
|
||||||
|
text-shadow: none;
|
||||||
|
padding: 2px;
|
||||||
|
|
||||||
|
&.current {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// styles for the cards
|
||||||
|
.hass-option-cards {
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -webkit-flexbox;
|
||||||
|
display: -webkit-flex;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: flex-start;
|
||||||
|
margin: -4px; // grid trick, has to match option-card's margin
|
||||||
|
|
||||||
|
p.note{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-card {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
width: 210px;
|
||||||
|
height: 142px;
|
||||||
|
display: inline-block;
|
||||||
|
background-color: #fefefe;
|
||||||
|
margin: 4px;
|
||||||
|
border-radius: 2px;
|
||||||
|
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2);
|
||||||
|
padding: 8px;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
.img-container {
|
||||||
|
height: 50px;
|
||||||
|
margin: 8px 0;
|
||||||
|
font: 0/0 a;
|
||||||
|
|
||||||
|
&:before { /* create a full-height inline block pseudo=element */
|
||||||
|
content: ' ';
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle; /* vertical alignment of the inline element */
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 50px;
|
||||||
|
box-shadow: none;
|
||||||
|
border: none;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #000;
|
||||||
|
line-height: 1.3em;
|
||||||
|
height: 2.6em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.category {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #AAA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fade-in animation
|
||||||
|
&.show-items .option-card{
|
||||||
|
opacity:0;
|
||||||
|
-webkit-animation:new-item-animation .2s linear forwards;
|
||||||
|
-o-animation:new-item-animation .2s linear forwards;
|
||||||
|
animation:new-item-animation .2s linear forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fade-out animation
|
||||||
|
&.remove-items .option-card{
|
||||||
|
-webkit-animation:removed-item-animation .2s cubic-bezier(.55,-0.04,.91,.94) forwards;
|
||||||
|
-o-animation:removed-item-animation .2s cubic-bezier(.55,-0.04,.91,.94) forwards;
|
||||||
|
animation:removed-item-animation .2s cubic-bezier(.55,-0.04,.91,.94) forwards
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// animations for fade-in and fade-out effects of option-cards
|
||||||
|
@keyframes new-item-animation {
|
||||||
|
from {
|
||||||
|
opacity:0;
|
||||||
|
-webkit-transform:scale(0);
|
||||||
|
-ms-transform:scale(0);
|
||||||
|
-o-transform:scale(0);
|
||||||
|
transform:scale(0)
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity:1;
|
||||||
|
-webkit-transform:scale(1);
|
||||||
|
-ms-transform:scale(1);
|
||||||
|
-o-transform:scale(1);
|
||||||
|
transform:scale(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@-webkit-keyframes new-item-animation {
|
||||||
|
from {
|
||||||
|
opacity:0;
|
||||||
|
-webkit-transform:scale(0);
|
||||||
|
transform:scale(0)
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity:1;
|
||||||
|
-webkit-transform:scale(1);
|
||||||
|
transform:scale(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@-o-keyframes new-item-animation {
|
||||||
|
from {
|
||||||
|
opacity:0;
|
||||||
|
-o-transform:scale(0);
|
||||||
|
transform:scale(0)
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity:1;
|
||||||
|
-o-transform:scale(1);
|
||||||
|
transform:scale(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// space blocker animation
|
||||||
|
@keyframes openspace {
|
||||||
|
to {
|
||||||
|
height:auto
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes openspace {
|
||||||
|
to {
|
||||||
|
height:auto
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@-o-keyframes openspace {
|
||||||
|
to {
|
||||||
|
height:auto
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// removal animation
|
||||||
|
@keyframes removed-item-animation {
|
||||||
|
from {
|
||||||
|
opacity:1;
|
||||||
|
-webkit-transform:scale(1);
|
||||||
|
-ms-transform:scale(1);
|
||||||
|
-o-transform:scale(1);
|
||||||
|
transform:scale(1)
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
-webkit-transform:scale(0);
|
||||||
|
-ms-transform:scale(0);
|
||||||
|
-o-transform:scale(0);
|
||||||
|
transform:scale(0);
|
||||||
|
opacity:0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@-webkit-keyframes removed-item-animation {
|
||||||
|
from {
|
||||||
|
opacity:1;
|
||||||
|
-webkit-transform:scale(1);
|
||||||
|
transform:scale(1)
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
-webkit-transform:scale(0);
|
||||||
|
transform:scale(0);
|
||||||
|
opacity:0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@-o-keyframes removed-item-animation {
|
||||||
|
from {
|
||||||
|
opacity:1;
|
||||||
|
-o-transform:scale(1);
|
||||||
|
transform:scale(1)
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
-o-transform:scale(0);
|
||||||
|
transform:scale(0);
|
||||||
|
opacity:0
|
||||||
|
}
|
||||||
|
}
|
@ -306,147 +306,6 @@ p.note {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#components-page {
|
|
||||||
.isotope-item {
|
|
||||||
z-index: 2;
|
|
||||||
}
|
|
||||||
.isotope-hidden.isotope-item {
|
|
||||||
pointer-events: none;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
.isotope,
|
|
||||||
.isotope .isotope-item {
|
|
||||||
-webkit-transition-duration: 0.8s;
|
|
||||||
-moz-transition-duration: 0.8s;
|
|
||||||
transition-duration: 0.8s;
|
|
||||||
}
|
|
||||||
.isotope {
|
|
||||||
-webkit-transition-property: height, width;
|
|
||||||
-moz-transition-property: height, width;
|
|
||||||
transition-property: height, width;
|
|
||||||
}
|
|
||||||
.isotope .isotope-item {
|
|
||||||
-webkit-transition-property: -webkit-transform, opacity;
|
|
||||||
-moz-transition-property: -moz-transform, opacity;
|
|
||||||
transition-property: transform, opacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.component-search{
|
|
||||||
margin-bottom: 24px;
|
|
||||||
|
|
||||||
input{
|
|
||||||
width: 100%;
|
|
||||||
padding: 10px;
|
|
||||||
|
|
||||||
background-color: #fefefe;
|
|
||||||
border-radius: 2px;
|
|
||||||
border: 1px solid;
|
|
||||||
border-color: #7c7c7c #c3c3c3 #ddd;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: $lap-end) {
|
|
||||||
#components-page {
|
|
||||||
.filter-button-group {
|
|
||||||
margin-bottom: 16px;
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
display: inline-block;
|
|
||||||
margin-right: 8px;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
|
|
||||||
&.current {
|
|
||||||
background-color: #3A5561;
|
|
||||||
background-image: linear-gradient(to bottom, #3A5561,#3F6B7D);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (min-width: $desk-start) {
|
|
||||||
#components-page {
|
|
||||||
.filter-button-group {
|
|
||||||
.featured {
|
|
||||||
margin: 12px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.added_in_current_version {
|
|
||||||
margin-top: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.added_two_versions_ago {
|
|
||||||
margin-bottom: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
display: block;
|
|
||||||
background: 0;
|
|
||||||
color: black;
|
|
||||||
box-shadow: none;
|
|
||||||
text-shadow: none;
|
|
||||||
padding: 2px;
|
|
||||||
|
|
||||||
&.current {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.hass-option-cards {
|
|
||||||
.option-card {
|
|
||||||
display: inline-block;
|
|
||||||
width: 202px;
|
|
||||||
height: 142px;
|
|
||||||
background-color: #fefefe;
|
|
||||||
margin-right: 4px;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
border-radius: 2px;
|
|
||||||
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2);
|
|
||||||
padding: 8px;
|
|
||||||
text-align: center;
|
|
||||||
text-decoration: none;
|
|
||||||
|
|
||||||
.img-container {
|
|
||||||
height: 50px;
|
|
||||||
margin: 8px 0;
|
|
||||||
font: 0/0 a;
|
|
||||||
|
|
||||||
&:before { /* create a full-height inline block pseudo=element */
|
|
||||||
content: ' ';
|
|
||||||
display: inline-block;
|
|
||||||
vertical-align: middle; /* vertical alignment of the inline element */
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
max-width: 100%;
|
|
||||||
max-height: 50px;
|
|
||||||
box-shadow: none;
|
|
||||||
border: none;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
text-decoration: none;
|
|
||||||
font-size: 18px;
|
|
||||||
color: #000;
|
|
||||||
line-height: 1.3em;
|
|
||||||
height: 2.6em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.category {
|
|
||||||
font-size: 14px;
|
|
||||||
color: #AAA;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.aside-module {
|
.aside-module {
|
||||||
.section {
|
.section {
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
@import 'oscailte/oscailte';
|
@import 'oscailte/oscailte';
|
||||||
@import 'custom/paulus';
|
@import 'custom/paulus';
|
||||||
|
@import 'custom/component_page';
|
||||||
@import 'custom/syntax';
|
@import 'custom/syntax';
|
||||||
|
10
source/_layouts/compress.html
Normal file
10
source/_layouts/compress.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
# Jekyll layout that compresses HTML
|
||||||
|
# v3.0.2
|
||||||
|
# http://jch.penibelst.de/
|
||||||
|
# © 2014–2015 Anatol Broder
|
||||||
|
# MIT License
|
||||||
|
---
|
||||||
|
|
||||||
|
{% capture _LINE_FEED %}
|
||||||
|
{% endcapture %}{% if site.compress_html.ignore.envs contains jekyll.environment %}{{ content }}{% else %}{% capture _content %}{{ content }}{% endcapture %}{% assign _profile = site.compress_html.profile %}{% if site.compress_html.endings == "all" %}{% assign _endings = "html head body li dt dd p rt rp optgroup option colgroup caption thead tbody tfoot tr td th" | split: " " %}{% else %}{% assign _endings = site.compress_html.endings %}{% endif %}{% for _element in _endings %}{% capture _end %}</{{ _element }}>{% endcapture %}{% assign _content = _content | remove: _end %}{% endfor %}{% if _profile and _endings %}{% assign _profile_endings = _content | size | plus: 1 %}{% endif %}{% for _element in site.compress_html.startings %}{% capture _start %}<{{ _element }}>{% endcapture %}{% assign _content = _content | remove: _start %}{% endfor %}{% if _profile and site.compress_html.startings %}{% assign _profile_startings = _content | size | plus: 1 %}{% endif %}{% if site.compress_html.comments == "all" %}{% assign _comments = "<!-- -->" | split: " " %}{% else %}{% assign _comments = site.compress_html.comments %}{% endif %}{% if _comments.size == 2 %}{% capture _comment_befores %}.{{ _content }}{% endcapture %}{% assign _comment_befores = _comment_befores | split: _comments.first %}{% for _comment_before in _comment_befores %}{% if forloop.first %}{% continue %}{% endif %}{% capture _comment_outside %}{% if _carry %}{{ _comments.first }}{% endif %}{{ _comment_before }}{% endcapture %}{% capture _comment %}{% unless _carry %}{{ _comments.first }}{% endunless %}{{ _comment_outside | split: _comments.last | first }}{% if _comment_outside contains _comments.last %}{{ _comments.last }}{% assign _carry = false %}{% else %}{% assign _carry = true %}{% endif %}{% endcapture %}{% assign _content = _content | remove_first: _comment %}{% endfor %}{% if _profile %}{% assign _profile_comments = _content | size | plus: 1 %}{% endif %}{% endif %}{% assign _pre_befores = _content | split: "<pre" %}{% assign _content = "" %}{% for _pre_before in _pre_befores %}{% assign _pres = _pre_before | split: "</pre>" %}{% assign _pres_after = "" %}{% if _pres.size != 0 %}{% if site.compress_html.blanklines %}{% assign _lines = _pres.last | split: _LINE_FEED %}{% capture _pres_after %}{% for _line in _lines %}{% assign _trimmed = _line | split: " " | join: " " %}{% if _trimmed != empty or forloop.last %}{% unless forloop.first %}{{ _LINE_FEED }}{% endunless %}{{ _line }}{% endif %}{% endfor %}{% endcapture %}{% else %}{% assign _pres_after = _pres.last | split: " " | join: " " %}{% endif %}{% endif %}{% capture _content %}{{ _content }}{% if _pre_before contains "</pre>" %}<pre{{ _pres.first }}</pre>{% endif %}{% unless _pre_before contains "</pre>" and _pres.size == 1 %}{{ _pres_after }}{% endunless %}{% endcapture %}{% endfor %}{% if _profile %}{% assign _profile_collapse = _content | size | plus: 1 %}{% endif %}{% if site.compress_html.clippings == "all" %}{% assign _clippings = "html head title base link meta style body article section nav aside h1 h2 h3 h4 h5 h6 hgroup header footer address p hr blockquote ol ul li dl dt dd figure figcaption main div table caption colgroup col tbody thead tfoot tr td th" | split: " " %}{% else %}{% assign _clippings = site.compress_html.clippings %}{% endif %}{% for _element in _clippings %}{% assign _edges = " <e;<e; </e>;</e>;</e> ;</e>" | replace: "e", _element | split: ";" %}{% assign _content = _content | replace: _edges[0], _edges[1] | replace: _edges[2], _edges[3] | replace: _edges[4], _edges[5] %}{% endfor %}{% if _profile and _clippings %}{% assign _profile_clippings = _content | size | plus: 1 %}{% endif %}{{ _content }}{% if _profile %} <table id="compress_html_profile_{{ site.time | date: "%Y%m%d" }}" class="compress_html_profile"> <thead> <tr> <td>Step <td>Bytes <tbody> <tr> <td>raw <td>{{ content | size }}{% if _profile_endings %} <tr> <td>endings <td>{{ _profile_endings }}{% endif %}{% if _profile_startings %} <tr> <td>startings <td>{{ _profile_startings }}{% endif %}{% if _profile_comments %} <tr> <td>comments <td>{{ _profile_comments }}{% endif %}{% if _profile_collapse %} <tr> <td>collapse <td>{{ _profile_collapse }}{% endif %}{% if _profile_clippings %} <tr> <td>clippings <td>{{ _profile_clippings }}{% endif %} </table>{% endif %}{% endif %}
|
@ -1,3 +1,7 @@
|
|||||||
|
---
|
||||||
|
layout: compress
|
||||||
|
---
|
||||||
|
|
||||||
{% capture root_url %}{{ site.root | strip_slash }}{% endcapture %}{% include site/head.html %}
|
{% capture root_url %}{{ site.root | strip_slash }}{% endcapture %}{% include site/head.html %}
|
||||||
|
|
||||||
<body {% if page.body_id %} id="{{ page.body_id }}"{% endif %}>
|
<body {% if page.body_id %} id="{{ page.body_id }}"{% endif %}>
|
||||||
|
@ -40,14 +40,11 @@ Support for these components is provided by the Home Assistant community.
|
|||||||
<a href='#added_one_version_ago' class="btn added_one_version_ago">Added in {{ added_one_ago_version }} ({{ one_ago_version_components_count }})</a>
|
<a href='#added_one_version_ago' class="btn added_one_version_ago">Added in {{ added_one_ago_version }} ({{ one_ago_version_components_count }})</a>
|
||||||
<a href='#added_two_versions_ago' class="btn added_two_versions_ago">Added in {{ added_two_ago_version }} ({{ two_ago_version_components_count }})</a>
|
<a href='#added_two_versions_ago' class="btn added_two_versions_ago">Added in {{ added_two_ago_version }} ({{ two_ago_version_components_count }})</a>
|
||||||
|
|
||||||
{% for category in categories %}
|
{% for category in categories %}
|
||||||
{% if category and category != 'Other' %}
|
{% if category and category != 'Other' %}
|
||||||
<a href='#{{ category | slugify }}' class="btn">
|
<a href='#{{ category | slugify }}' class="btn">{{ category }} ({{ components | where: 'ha_category', category | size }})</a>
|
||||||
{{ category }}
|
{% endif %}
|
||||||
({{ components | where: 'ha_category', category | size }})
|
{% endfor %}
|
||||||
</a>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
<a href='#other' class="btn">Other</a>
|
<a href='#other' class="btn">Other</a>
|
||||||
</div>
|
</div>
|
||||||
@ -58,27 +55,7 @@ Support for these components is provided by the Home Assistant community.
|
|||||||
<input type="text" name="search" id="search" class="search" placeholder="Search components...">
|
<input type="text" name="search" id="search" class="search" placeholder="Search components...">
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="hass-option-cards" id="componentContainer">
|
<div class="hass-option-cards" id="componentContainer"> </div>
|
||||||
{% for component in components %}
|
|
||||||
{% if component.ha_category %}
|
|
||||||
{% assign sliced_version = component.ha_release | split: '.' %}
|
|
||||||
{% assign minor_version = sliced_version[1]|plus: 0 %}
|
|
||||||
<a href='{{ component.url }}'
|
|
||||||
class='option-card {{ component.ha_category | slugify }}{% if minor_version == site.current_minor_version %} added_in_current_version{% elsif minor_version == added_one_ago_minor_version %} added_one_version_ago{% elsif minor_version == added_two_ago_minor_version %} added_two_versions_ago{% endif %}{% if component.featured %} featured{% endif %}'
|
|
||||||
data-title="{{component.title| downcase}}"
|
|
||||||
data-ha_category="{{component.ha_category | downcase}}"
|
|
||||||
{% unless component.featured %}style='display: none'{% endunless %}>
|
|
||||||
<div class='img-container'>
|
|
||||||
{% if component.logo %}
|
|
||||||
<img src='/images/supported_brands/{{ component.logo }}'>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
<div class='title'>{{ component.title }}</div>
|
|
||||||
<div class='category'>{{ component.ha_category }}</div>
|
|
||||||
</a>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -91,47 +68,141 @@ Support for these components is provided by the Home Assistant community.
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endcomment %}
|
{% endcomment %}
|
||||||
|
|
||||||
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
|
<script type="text/javascript" src="https://code.jquery.com/jquery-2.2.4.js"></script>
|
||||||
<script>
|
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/2.3.0/mustache.min.js"></script>
|
||||||
// undo initial hiding of non-featured cards
|
|
||||||
|
{% raw %}
|
||||||
|
<script id="component-template" type="text/x-custom-template">
|
||||||
|
{{#components}}
|
||||||
|
<a href="{{url}}" class="option-card">
|
||||||
|
<div class="img-container">{{{image}}}</div>
|
||||||
|
<div class='title'>{{title}}</div>
|
||||||
|
<div class='category'>{{cat}}</div>
|
||||||
|
</a>
|
||||||
|
{{/components}}
|
||||||
|
{{^components}}
|
||||||
|
<p class='note'>Nothing found!</p>
|
||||||
|
{{/components}}
|
||||||
|
</script>
|
||||||
|
{% endraw %}
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
var current_minor_version = {{site.current_minor_version}};
|
||||||
|
var added_one_ago_minor_version = {{added_one_ago_minor_version}};
|
||||||
|
var added_two_ago_minor_version = {{added_two_ago_minor_version}};
|
||||||
|
// This object contains all components we have
|
||||||
|
var allComponents = [
|
||||||
|
{% for component in components %}
|
||||||
|
{% if component.ha_category %}
|
||||||
|
{% assign sliced_version = component.ha_release | split: '.' %}
|
||||||
|
{% assign minor_version = sliced_version[1]|plus: 0 %}
|
||||||
|
{url:"{{ component.url }}", title:"{{component.title}}", cat:"{{component.ha_category | slugify}}", featured: {% if component.featured %}true{% else %}false{% endif %}, v: {{minor_version}}, logo: "{{component.logo}}"},
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
false
|
||||||
|
];
|
||||||
|
allComponents.pop(); // remove placeholder element at the end
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript">
|
||||||
(function(){
|
(function(){
|
||||||
var hash = location.hash;
|
var template = $('#component-template').html();
|
||||||
if (hash !== '') {
|
Mustache.parse(template); // make future calls to render faster
|
||||||
if (hash === '#all' || hash.indexOf('#search/') === 0) {
|
|
||||||
jQuery('#componentContainer a').show();
|
function init() {
|
||||||
} else {
|
// do the lowerCase transformation once
|
||||||
jQuery('#componentContainer .featured').hide();
|
for (i=0; i < (allComponents.length); i++) {
|
||||||
jQuery('#componentContainer .' + hash.substr(1)).show();
|
allComponents[i].titleLC = allComponents[i].title.toLowerCase();
|
||||||
|
allComponents[i].catLC = allComponents[i].cat.toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hash.indexOf('#search/') === 0) {
|
// sort the components alphabetically
|
||||||
|
allComponents.sort(function(a, b){
|
||||||
|
return a.titleLC.localeCompare(b.titleLC);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (location.hash !== '' && location.hash.indexOf('#search/') === 0) {
|
||||||
// set default value in search from URL
|
// set default value in search from URL
|
||||||
jQuery('.component-search input').val(decodeURIComponent(hash).substring(8));
|
jQuery('.component-search input').val(decodeURIComponent(location.hash).substring(8));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})();
|
init();
|
||||||
</script>
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.isotope/2.2.2/isotope.pkgd.min.js"></script>
|
/**
|
||||||
<script>
|
* filter all components, based on the location's hash and render them into the component box
|
||||||
$(window).load(function(){
|
*/
|
||||||
var $isotope = $('#componentContainer').isotope({
|
function applyFilter() {
|
||||||
filter: '.featured',
|
var rendered, i, filter, search;
|
||||||
animationOptions: {
|
var hash = location.hash || '';
|
||||||
duration: 750,
|
var data = {
|
||||||
easing: 'linear',
|
components: [],
|
||||||
queue: false
|
image: function () {
|
||||||
},
|
if(this.logo === '') {
|
||||||
masonry: {
|
return '';
|
||||||
columnWidth: 210
|
} else {
|
||||||
},
|
return '<img src="/images/supported_brands/' + this.logo + '">';
|
||||||
getSortData: {
|
}
|
||||||
title: function( itemElem ) {
|
|
||||||
var title = $( itemElem ).find('.title').text();
|
|
||||||
return title ? title.toLowerCase() : '';
|
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
sortBy: 'title'
|
|
||||||
});
|
// fade-out css effect on the old elements. This is actually not visible on fast browsers
|
||||||
|
$('#componentContainer').addClass('remove-items');
|
||||||
|
|
||||||
|
if (hash.indexOf('#search/') === -1) {
|
||||||
|
// reset search box when not searching
|
||||||
|
jQuery('.component-search input').val(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hash === '#all') {
|
||||||
|
// shortcut: no need to filter
|
||||||
|
data.components = allComponents;
|
||||||
|
} else {
|
||||||
|
if (hash.indexOf('#search/') === 0) {
|
||||||
|
// search through title and category
|
||||||
|
search = decodeURIComponent(hash).substring(8).toLowerCase();
|
||||||
|
filter = function(comp) {
|
||||||
|
return (comp.titleLC.indexOf(search) !== -1) ||
|
||||||
|
(comp.catLC.indexOf(search) !== -1);
|
||||||
|
};
|
||||||
|
|
||||||
|
} else if(hash === '#featured' || hash === '') {
|
||||||
|
// only show those with featured = true
|
||||||
|
filter = function(comp) {
|
||||||
|
return comp.featured;
|
||||||
|
};
|
||||||
|
|
||||||
|
} else if(hash === '#added_in_current_version' || hash === '#added_one_version_ago' || hash === '#added_two_versions_ago') {
|
||||||
|
// compare against a version
|
||||||
|
search = current_minor_version;
|
||||||
|
if (hash === '#added_one_version_ago') {
|
||||||
|
search = added_one_ago_minor_version;
|
||||||
|
} else if (hash === '#added_two_versions_ago') {
|
||||||
|
search = added_two_ago_minor_version;
|
||||||
|
}
|
||||||
|
filter = function(comp) {
|
||||||
|
return comp.v === search;
|
||||||
|
};
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// regular filter categories
|
||||||
|
search = hash.substring(1);
|
||||||
|
filter = function(comp) {
|
||||||
|
return comp.catLC === search;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// filter all components using the filter function
|
||||||
|
for (i=0; i < (allComponents.length); i++) {
|
||||||
|
if (filter(allComponents[i])) {
|
||||||
|
data.components.push(allComponents[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rendered = Mustache.render(template, data);
|
||||||
|
|
||||||
|
// remove previous elements and css classes, add the new stuff and then trigger the fade-in css animation
|
||||||
|
$('#componentContainer').html('').removeClass('show-items remove-items').html(rendered).addClass('show-items');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* update the browser location hash. This enables users to use the browser-history
|
* update the browser location hash. This enables users to use the browser-history
|
||||||
@ -144,53 +215,6 @@ $(window).load(function(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* filter all components, based on the location's hash
|
|
||||||
*/
|
|
||||||
function applyFilter() {
|
|
||||||
var hash = location.hash;
|
|
||||||
var filter;
|
|
||||||
|
|
||||||
if (hash == '') {
|
|
||||||
filter = '.featured';
|
|
||||||
hash = '#featured';
|
|
||||||
|
|
||||||
} else if (hash === '#all') {
|
|
||||||
// show all elements
|
|
||||||
filter = '*';
|
|
||||||
|
|
||||||
} else if (hash.indexOf('#search/') === 0) {
|
|
||||||
// search for the given string
|
|
||||||
var text = decodeURIComponent(hash).substring(8).toLowerCase();
|
|
||||||
text = text.replace(/[(\?|\&\{\}\(\))]/gi, '').toLowerCase();
|
|
||||||
|
|
||||||
if(text && text.length === 0){
|
|
||||||
filter = '*';
|
|
||||||
} else {
|
|
||||||
filter = function() {
|
|
||||||
var title = $(this).data('title');
|
|
||||||
var cat = $(this).data('ha_category');
|
|
||||||
return title.indexOf(text) != -1 || cat.indexOf(text) != -1;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
filter = '.' + hash.substr(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hash.indexOf('#search/') === 0) {
|
|
||||||
// reset the search field when no longer searching
|
|
||||||
$('.component-search input').val(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
$('.filter-button-group a.current').removeClass('current');
|
|
||||||
$('.filter-button-group a[href="'+hash+'"]').addClass('current');
|
|
||||||
|
|
||||||
$isotope.isotope({
|
|
||||||
filter: filter
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// update view by filter selection
|
// update view by filter selection
|
||||||
jQuery('.filter-button-group a').click(function() {
|
jQuery('.filter-button-group a').click(function() {
|
||||||
updateHash(this.getAttribute('href'));
|
updateHash(this.getAttribute('href'));
|
||||||
@ -198,6 +222,36 @@ $(window).load(function(){
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple debounce implementation, based on http://davidwalsh.name/javascript-debounce-function
|
||||||
|
*/
|
||||||
|
function debounce(func, wait, immediate) {
|
||||||
|
var timeout;
|
||||||
|
return function() {
|
||||||
|
var context = this, args = arguments;
|
||||||
|
var later = function() {
|
||||||
|
timeout = null;
|
||||||
|
if (!immediate) {
|
||||||
|
func.apply(context, args);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var callNow = immediate && !timeout;
|
||||||
|
clearTimeout(timeout);
|
||||||
|
timeout = setTimeout(later, wait);
|
||||||
|
if (callNow) {
|
||||||
|
func.apply(context, args);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
// update view by search text
|
||||||
|
$('.component-search input').keyup(debounce(function() {
|
||||||
|
var text = $(this).val();
|
||||||
|
// sanitize input
|
||||||
|
text = text.replace(/[(\?|\&\{\}\(\))]/gi, '');
|
||||||
|
updateHash('#search/' + text);
|
||||||
|
applyFilter();
|
||||||
|
}, 500));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple debounce implementation, based on http://davidwalsh.name/javascript-debounce-function
|
* Simple debounce implementation, based on http://davidwalsh.name/javascript-debounce-function
|
||||||
@ -231,8 +285,7 @@ $(window).load(function(){
|
|||||||
}, 500));
|
}, 500));
|
||||||
|
|
||||||
window.addEventListener('hashchange', applyFilter);
|
window.addEventListener('hashchange', applyFilter);
|
||||||
|
|
||||||
// initialize from URL
|
|
||||||
applyFilter();
|
applyFilter();
|
||||||
});
|
|
||||||
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user