arco 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4bf0684bfe3cbb64808bdb1510ae705f1a09f0127829bed124b86b2da7c17b77
4
- data.tar.gz: 3f080301fc5926c6646bc1ddc3a7584b91103d02f57d2b2df146527cdfe60729
3
+ metadata.gz: 68442f33429b4c0570935805e885391d45067dc5092c9ac62b11c36dc379771d
4
+ data.tar.gz: 9eae7b1b7444cfda65c3a103065e2d97d6fa64a815b1741263863edb9447fc9c
5
5
  SHA512:
6
- metadata.gz: 83b1d07dc317b935e82b75bc556ff9358f9b8b09142c040850a5f69e43d749f7914c7398f42cc126d8d6151f408d7715241729743a222b2fa9b47b6d4e8c6df5
7
- data.tar.gz: 9f474532ebcb6223393c9886b16073115538411ea73047b07bcfd3a9fd975af8a2379ad198b2c382e3bd380f1ee2f4369d7196137a4cbbfeb9e5d79322f34da6
6
+ metadata.gz: 392488a776a9552e52302d698ba45f20a62c8e094cf0530463963166d9da3f9f6d710c1bd903f5445bb74059d3397dfca2a320ce9f241428c8333e88abff750b
7
+ data.tar.gz: 67392ddc73ba81c236951406cfc94e5997adcd2332e4c046307447bd122a533d0c3f46ec488c00ddb0db1d2909ba341cc3838b59e59f29a0fac4c2ec863ab841
data/README.md CHANGED
@@ -83,6 +83,7 @@ permalink: /projects/post-title
83
83
  source-url: https://project.source/link/
84
84
  cover-image: /assets/image-for-front-page.png
85
85
  image: /assets/image-for-top-of-post.png
86
+ tags: [tags, which, relate, to, post]
86
87
  mathjax: true | false
87
88
  ---
88
89
  ```
@@ -91,6 +92,24 @@ mathjax: true | false
91
92
 
92
93
  Simply add your favicon `favicon.png` to the root of your site.
93
94
 
95
+ ### Lazy loading
96
+
97
+ In order to enable lazy loading on an image you must add a `data-echo` attribute like so:
98
+
99
+ ```html
100
+ <img src="/assets/placeholder-for-image.png" alt="alt-text" data-echo="/assets/actual-image.png" />
101
+ ```
102
+
103
+ ### Image lightbox
104
+
105
+ In order to open an image in a fullscreen lightbox on click, you must wrap the image in a link tag like so:
106
+
107
+ ```html
108
+ <a href="/assets/actual-image.png">
109
+ <img src="/assets/placeholder-for-image.png" alt="alt-text" data-echo="/assets/actual-image.png" />
110
+ </a>
111
+ ```
112
+
94
113
  ### Markdown features
95
114
 
96
115
  [Check here](https://meebuhs.github.io/projects/arco) for examples of the supported markdown features.
@@ -0,0 +1,146 @@
1
+ <script>
2
+ (function (root, factory) {
3
+ if (typeof define === 'function' && define.amd) {
4
+ define(function() {
5
+ return factory(root);
6
+ });
7
+ } else if (typeof exports === 'object') {
8
+ module.exports = factory;
9
+ } else {
10
+ root.echo = factory(root);
11
+ }
12
+ })(this, function (root) {
13
+
14
+ 'use strict';
15
+
16
+ var echo = {};
17
+
18
+ var callback = function () {};
19
+
20
+ var offset, poll, delay, useDebounce, unload;
21
+
22
+ var isHidden = function (element) {
23
+ return (element.offsetParent === null);
24
+ };
25
+
26
+ var inView = function (element, view) {
27
+ if (isHidden(element)) {
28
+ return false;
29
+ }
30
+
31
+ var box = element.getBoundingClientRect();
32
+ return (box.right >= view.l && box.bottom >= view.t && box.left <= view.r && box.top <= view.b);
33
+ };
34
+
35
+ var debounceOrThrottle = function () {
36
+ if(!useDebounce && !!poll) {
37
+ return;
38
+ }
39
+ clearTimeout(poll);
40
+ poll = setTimeout(function(){
41
+ echo.render();
42
+ poll = null;
43
+ }, delay);
44
+ };
45
+
46
+ echo.init = function (opts) {
47
+ opts = opts || {};
48
+ var offsetAll = opts.offset || 0;
49
+ var offsetVertical = opts.offsetVertical || offsetAll;
50
+ var offsetHorizontal = opts.offsetHorizontal || offsetAll;
51
+ var optionToInt = function (opt, fallback) {
52
+ return parseInt(opt || fallback, 10);
53
+ };
54
+ offset = {
55
+ t: optionToInt(opts.offsetTop, offsetVertical),
56
+ b: optionToInt(opts.offsetBottom, offsetVertical),
57
+ l: optionToInt(opts.offsetLeft, offsetHorizontal),
58
+ r: optionToInt(opts.offsetRight, offsetHorizontal)
59
+ };
60
+ delay = optionToInt(opts.throttle, 250);
61
+ useDebounce = opts.debounce !== false;
62
+ unload = !!opts.unload;
63
+ callback = opts.callback || callback;
64
+ echo.render();
65
+ if (document.addEventListener) {
66
+ root.addEventListener('scroll', debounceOrThrottle, false);
67
+ root.addEventListener('load', debounceOrThrottle, false);
68
+ } else {
69
+ root.attachEvent('onscroll', debounceOrThrottle);
70
+ root.attachEvent('onload', debounceOrThrottle);
71
+ }
72
+ };
73
+
74
+ echo.render = function (context) {
75
+ var nodes = (context || document).querySelectorAll('[data-echo], [data-echo-background]');
76
+ var length = nodes.length;
77
+ var src, elem;
78
+ var view = {
79
+ l: 0 - offset.l,
80
+ t: 0 - offset.t,
81
+ b: (root.innerHeight || document.documentElement.clientHeight) + offset.b,
82
+ r: (root.innerWidth || document.documentElement.clientWidth) + offset.r
83
+ };
84
+ for (var i = 0; i < length; i++) {
85
+ elem = nodes[i];
86
+ if (inView(elem, view)) {
87
+
88
+ if (unload) {
89
+ elem.setAttribute('data-echo-placeholder', elem.src);
90
+ }
91
+
92
+ if (elem.getAttribute('data-echo-background') !== null) {
93
+ elem.style.backgroundImage = 'url(' + elem.getAttribute('data-echo-background') + ')';
94
+ }
95
+ else if (elem.src !== (src = elem.getAttribute('data-echo'))) {
96
+ elem.src = src;
97
+ }
98
+
99
+ if (!unload) {
100
+ elem.removeAttribute('data-echo');
101
+ elem.removeAttribute('data-echo-background');
102
+ }
103
+
104
+ callback(elem, 'load');
105
+ }
106
+ else if (unload && !!(src = elem.getAttribute('data-echo-placeholder'))) {
107
+
108
+ if (elem.getAttribute('data-echo-background') !== null) {
109
+ elem.style.backgroundImage = 'url(' + src + ')';
110
+ }
111
+ else {
112
+ elem.src = src;
113
+ }
114
+
115
+ elem.removeAttribute('data-echo-placeholder');
116
+ callback(elem, 'unload');
117
+ }
118
+ }
119
+ if (!length) {
120
+ echo.detach();
121
+ }
122
+ };
123
+
124
+ echo.detach = function () {
125
+ if (document.removeEventListener) {
126
+ root.removeEventListener('scroll', debounceOrThrottle);
127
+ } else {
128
+ root.detachEvent('onscroll', debounceOrThrottle);
129
+ }
130
+ clearTimeout(poll);
131
+ };
132
+
133
+ return echo;
134
+
135
+ });
136
+ </script>
137
+ <script>
138
+ echo.init({
139
+ offset: 2500,
140
+ throttle: 250,
141
+ unload: false,
142
+ callback: function (element, op) {
143
+ //console.log(element, 'has been', op + 'ed')
144
+ }
145
+ });
146
+ </script>
@@ -11,8 +11,11 @@
11
11
  <body>
12
12
  {% include sidebar.html %}
13
13
  {{ content }}
14
+ {% include lazyload.html %}
15
+ <script type="text/javascript" src="/assets/lightbox/lightbox.js"></script>
16
+ <link rel="stylesheet" href="/assets/lightbox/lightbox.css">
17
+ <script src="/assets/js/sidebar.js"></script>
18
+ <script src="/assets/js/fade-transitions.js"></script>
19
+ <script>fadeInPage();</script>
14
20
  </body>
15
- <script src="/assets/js/sidebar.js"></script>
16
- <script src="/assets/js/fade-transitions.js"></script>
17
- <script>fadeInPage();</script>
18
21
  </html>
@@ -0,0 +1,94 @@
1
+ #lightbox {width: 100%; height: 100%; position: fixed; top: 0; left: 0; background: rgba(0,0,0,0.85); z-index: 9999999; line-height: 0; cursor: pointer; display: none;}
2
+ #lightbox .img {
3
+ position: relative;
4
+ top: 50%;
5
+ left: 50%;
6
+ -ms-transform: translateX(-50%) translateY(-50%);
7
+ -webkit-transform: translate(-50%,-50%);
8
+ transform: translate(-50%,-50%);
9
+ max-width: 100%;
10
+ max-height: 100%;
11
+ }
12
+ #lightbox .img img {opacity: 0; pointer-events: none; width: auto;}
13
+ @media screen and (min-width: 1200px) {
14
+ #lightbox .img {
15
+ max-width: 1200px;
16
+ }
17
+ }
18
+ @media screen and (min-height: 1200px) {
19
+ #lightbox .img {
20
+ max-height: 1200px;
21
+ }
22
+ }
23
+ #lightbox span {display: block; position: fixed; bottom: 13px; height: 1.5em; line-height: 1.4em; width: 100%; text-align: center; color: white; text-shadow:
24
+ -1px -1px 0 #000,
25
+ 1px -1px 0 #000,
26
+ -1px 1px 0 #000,
27
+ 1px 1px 0 #000;
28
+ }
29
+
30
+ #lightbox span {display: none;}
31
+
32
+ #lightbox .videoWrapperContainer {
33
+ position: relative;
34
+ top: 50%;
35
+ left: 50%;
36
+ -ms-transform: translateX(-50%) translateY(-50%);
37
+ -webkit-transform: translate(-50%,-50%);
38
+ transform: translate(-50%,-50%);
39
+ max-width: 900px;
40
+ max-height: 100%;
41
+ }
42
+ #lightbox .videoWrapperContainer .videoWrapper {
43
+ height: 0;
44
+ line-height: 0;
45
+ margin: 0;
46
+ padding: 0;
47
+ position: relative;
48
+ padding-bottom: 56.333%; /* custom */
49
+ background: black;
50
+ }
51
+ #lightbox .videoWrapper iframe {
52
+ position: absolute;
53
+ top: 0;
54
+ left: 0;
55
+ width: 100%;
56
+ height: 100%;
57
+ border: 0;
58
+ display: block;
59
+ }
60
+ #lightbox #prev, #lightbox #next {height: 50px; line-height: 36px; display: none; margin-top: -25px; position: fixed; top: 50%; padding: 0 15px; cursor: pointer; text-decoration: none; z-index: 99; color: white; font-size: 60px;}
61
+ #lightbox.gallery #prev, #lightbox.gallery #next {display: block;}
62
+ #lightbox #prev {left: 0;}
63
+ #lightbox #next {right: 0;}
64
+ #lightbox #close {height: 50px; width: 50px; position: fixed; cursor: pointer; text-decoration: none; z-index: 99; right: 0; top: 0;}
65
+ #lightbox #close:after, #lightbox #close:before {position: absolute; margin-top: 22px; margin-left: 14px; content: ""; height: 3px; background: white; width: 23px;
66
+ -webkit-transform-origin: 50% 50%;
67
+ -moz-transform-origin: 50% 50%;
68
+ -o-transform-origin: 50% 50%;
69
+ transform-origin: 50% 50%;
70
+ /* Safari */
71
+ -webkit-transform: rotate(-45deg);
72
+ /* Firefox */
73
+ -moz-transform: rotate(-45deg);
74
+ /* IE */
75
+ -ms-transform: rotate(-45deg);
76
+ /* Opera */
77
+ -o-transform: rotate(-45deg);
78
+ }
79
+ #lightbox #close:after {
80
+ /* Safari */
81
+ -webkit-transform: rotate(45deg);
82
+ /* Firefox */
83
+ -moz-transform: rotate(45deg);
84
+ /* IE */
85
+ -ms-transform: rotate(45deg);
86
+ /* Opera */
87
+ -o-transform: rotate(45deg);
88
+ }
89
+ #lightbox, #lightbox * {
90
+ -webkit-user-select: none;
91
+ -moz-user-select: none;
92
+ -ms-user-select: none;
93
+ user-select: none;
94
+ }
@@ -0,0 +1,141 @@
1
+ function is_youtubelink(url) {
2
+ var p = /^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;
3
+ return (url.match(p)) ? RegExp.$1 : false;
4
+ }
5
+ function is_imagelink(url) {
6
+ var p = /([a-z\-_0-9\/\:\.]*\.(jpg|jpeg|png|gif))/i;
7
+ return (url.match(p)) ? true : false;
8
+ }
9
+ function is_vimeolink(url,el) {
10
+ var id = false;
11
+ var xmlhttp = new XMLHttpRequest();
12
+ xmlhttp.onreadystatechange = function() {
13
+ if (xmlhttp.readyState == XMLHttpRequest.DONE) { // XMLHttpRequest.DONE == 4
14
+ if (xmlhttp.status == 200) {
15
+ var response = JSON.parse(xmlhttp.responseText);
16
+ id = response.video_id;
17
+ console.log(id);
18
+ el.classList.add('lightbox-vimeo');
19
+ el.setAttribute('data-id',id);
20
+
21
+ el.addEventListener("click", function(event) {
22
+ event.preventDefault();
23
+ document.getElementById('lightbox').innerHTML = '<a id="close"></a><a id="next">&rsaquo;</a><a id="prev">&lsaquo;</a><div class="videoWrapperContainer"><div class="videoWrapper"><iframe src="https://player.vimeo.com/video/'+el.getAttribute('data-id')+'/?autoplay=1&byline=0&title=0&portrait=0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe></div></div>';
24
+ document.getElementById('lightbox').style.display = 'block';
25
+
26
+ setGallery(this);
27
+ });
28
+ }
29
+ else if (xmlhttp.status == 400) {
30
+ alert('There was an error 400');
31
+ }
32
+ else {
33
+ alert('something else other than 200 was returned');
34
+ }
35
+ }
36
+ };
37
+ xmlhttp.open("GET", 'https://vimeo.com/api/oembed.json?url='+url, true);
38
+ xmlhttp.send();
39
+ }
40
+ function setGallery(el) {
41
+ var elements = document.body.querySelectorAll(".gallery");
42
+ elements.forEach(element => {
43
+ element.classList.remove('gallery');
44
+ });
45
+ if(el.closest('ul, p')) {
46
+ var link_elements = el.closest('ul, p').querySelectorAll("a[class*='lightbox-']");
47
+ link_elements.forEach(link_element => {
48
+ link_element.classList.remove('current');
49
+ });
50
+ link_elements.forEach(link_element => {
51
+ if(el.getAttribute('href') == link_element.getAttribute('href')) {
52
+ link_element.classList.add('current');
53
+ }
54
+ });
55
+ if(link_elements.length>1) {
56
+ document.getElementById('lightbox').classList.add('gallery');
57
+ link_elements.forEach(link_element => {
58
+ link_element.classList.add('gallery');
59
+ });
60
+ }
61
+ var currentkey;
62
+ var gallery_elements = document.querySelectorAll('a.gallery');
63
+ Object.keys(gallery_elements).forEach(function (k) {
64
+ if(gallery_elements[k].classList.contains('current')) currentkey = k;
65
+ });
66
+ if(currentkey==(gallery_elements.length-1)) var nextkey = 0;
67
+ else var nextkey = parseInt(currentkey)+1;
68
+ if(currentkey==0) var prevkey = parseInt(gallery_elements.length-1);
69
+ else var prevkey = parseInt(currentkey)-1;
70
+ document.getElementById('next').addEventListener("click", function() {
71
+ gallery_elements[nextkey].click();
72
+ });
73
+ document.getElementById('prev').addEventListener("click", function() {
74
+ gallery_elements[prevkey].click();
75
+ });
76
+ }
77
+ }
78
+
79
+ document.addEventListener("DOMContentLoaded", function() {
80
+
81
+ //create lightbox div in the footer
82
+ var newdiv = document.createElement("div");
83
+ newdiv.setAttribute('id',"lightbox");
84
+ document.body.appendChild(newdiv);
85
+
86
+ //add classes to links to be able to initiate lightboxes
87
+ var elements = document.querySelectorAll('a');
88
+ elements.forEach(element => {
89
+ var url = element.getAttribute('href');
90
+ if(url) {
91
+ if(url.indexOf('vimeo') !== -1 && !element.classList.contains('no-lightbox')) {
92
+ is_vimeolink(url,element);
93
+ }
94
+ if(is_youtubelink(url) && !element.classList.contains('no-lightbox')) {
95
+ element.classList.add('lightbox-youtube');
96
+ element.setAttribute('data-id',is_youtubelink(url));
97
+ }
98
+ if(is_imagelink(url) && !element.classList.contains('no-lightbox')) {
99
+ element.classList.add('lightbox-image');
100
+ var href = element.getAttribute('href');
101
+ var filename = href.split('/').pop();
102
+ var split = filename.split(".");
103
+ var name = split[0];
104
+ element.setAttribute('title',name);
105
+ }
106
+ }
107
+ });
108
+
109
+ //remove the clicked lightbox
110
+ document.getElementById('lightbox').addEventListener("click", function(event) {
111
+ if(event.target.id != 'next' && event.target.id != 'prev'){
112
+ this.innerHTML = '';
113
+ document.getElementById('lightbox').style.display = 'none';
114
+ }
115
+ });
116
+
117
+ //add the youtube lightbox on click
118
+ var elements = document.querySelectorAll('a.lightbox-youtube');
119
+ elements.forEach(element => {
120
+ element.addEventListener("click", function(event) {
121
+ event.preventDefault();
122
+ document.getElementById('lightbox').innerHTML = '<a id="close"></a><a id="next">&rsaquo;</a><a id="prev">&lsaquo;</a><div class="videoWrapperContainer"><div class="videoWrapper"><iframe src="https://www.youtube.com/embed/'+this.getAttribute('data-id')+'?autoplay=1&showinfo=0&rel=0"></iframe></div>';
123
+ document.getElementById('lightbox').style.display = 'block';
124
+
125
+ setGallery(this);
126
+ });
127
+ });
128
+
129
+ //add the image lightbox on click
130
+ var elements = document.querySelectorAll('a.lightbox-image');
131
+ elements.forEach(element => {
132
+ element.addEventListener("click", function(event) {
133
+ event.preventDefault();
134
+ document.getElementById('lightbox').innerHTML = '<a id="close"></a><a id="next">&rsaquo;</a><a id="prev">&lsaquo;</a><div class="img" style="background: url(\''+this.getAttribute('href')+'\') center center / contain no-repeat;" title="'+this.getAttribute('title')+'" ><img src="'+this.getAttribute('href')+'" alt="'+this.getAttribute('title')+'" /></div><span>'+this.getAttribute('title')+'</span>';
135
+ document.getElementById('lightbox').style.display = 'block';
136
+
137
+ setGallery(this);
138
+ });
139
+ });
140
+
141
+ });
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arco
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - meebuhs
@@ -42,6 +42,7 @@ files:
42
42
  - _config.yml
43
43
  - _includes/cover.html
44
44
  - _includes/footer.html
45
+ - _includes/lazyload.html
45
46
  - _includes/mathjax.html
46
47
  - _includes/sidebar.html
47
48
  - _layouts/404.html
@@ -78,6 +79,8 @@ files:
78
79
  - assets/js/fade-transitions.js
79
80
  - assets/js/post-grid-init.js
80
81
  - assets/js/sidebar.js
82
+ - assets/lightbox/lightbox.css
83
+ - assets/lightbox/lightbox.js
81
84
  homepage: https://github.com/meebuhs/arco
82
85
  licenses:
83
86
  - MIT