servel 0.11.0 → 0.12.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 +4 -4
- data/bin/servel +4 -5
- data/lib/servel.rb +3 -1
- data/lib/servel/app.rb +2 -1
- data/lib/servel/entry.rb +11 -2
- data/lib/servel/entry_factory.rb +28 -13
- data/lib/servel/haml_context.rb +20 -2
- data/lib/servel/home_app.rb +11 -11
- data/lib/servel/index.rb +90 -42
- data/lib/servel/instrumentation.rb +26 -0
- data/lib/servel/templates/_gallery.haml +10 -10
- data/lib/servel/templates/_listing.haml +8 -4
- data/lib/servel/templates/css/common.css +24 -24
- data/lib/servel/templates/css/gallery-text.css +39 -39
- data/lib/servel/templates/css/gallery.css +8 -29
- data/lib/servel/templates/css/home.css +15 -15
- data/lib/servel/templates/css/index.css +14 -14
- data/lib/servel/templates/css/listing.css +71 -55
- data/lib/servel/templates/css/normalize.css +447 -447
- data/lib/servel/templates/home.haml +18 -18
- data/lib/servel/templates/index.haml +23 -21
- data/lib/servel/templates/js/gallery.js +21 -2
- data/lib/servel/templates/js/listing.js +26 -0
- data/lib/servel/templates/js/ume.js +63 -63
- data/lib/servel/templates/js/url-search-params.js +2 -0
- data/lib/servel/version.rb +1 -1
- data/servel.gemspec +2 -1
- metadata +24 -7
@@ -1,18 +1,18 @@
|
|
1
|
-
!!!
|
2
|
-
%html
|
3
|
-
%head
|
4
|
-
%meta{charset: 'utf-8'}
|
5
|
-
%title Browse Listings
|
6
|
-
%meta{name: 'viewport', content: 'width=device-width, height=device-height, user-scalable=no'}
|
7
|
-
:css
|
8
|
-
#{include('css/normalize.css')}
|
9
|
-
#{include('css/common.css')}
|
10
|
-
#{include('css/home.css')}
|
11
|
-
%body
|
12
|
-
#home
|
13
|
-
%h1 Browse Listings
|
14
|
-
%ul#roots
|
15
|
-
- roots.each do |root|
|
16
|
-
%li
|
17
|
-
%a{href: root}= root
|
18
|
-
%a.new-tab{href: root, target: "_blank"} (New Tab)
|
1
|
+
!!!
|
2
|
+
%html
|
3
|
+
%head
|
4
|
+
%meta{charset: 'utf-8'}
|
5
|
+
%title Browse Listings
|
6
|
+
%meta{name: 'viewport', content: 'width=device-width, height=device-height, user-scalable=no'}
|
7
|
+
:css
|
8
|
+
#{include('css/normalize.css')}
|
9
|
+
#{include('css/common.css')}
|
10
|
+
#{include('css/home.css')}
|
11
|
+
%body
|
12
|
+
#home
|
13
|
+
%h1 Browse Listings
|
14
|
+
%ul#roots
|
15
|
+
- roots.each do |root|
|
16
|
+
%li
|
17
|
+
%a{href: root}= root
|
18
|
+
%a.new-tab{href: root, target: "_blank"} (New Tab)
|
@@ -1,21 +1,23 @@
|
|
1
|
-
!!!
|
2
|
-
%html
|
3
|
-
%head
|
4
|
-
%meta{charset: 'utf-8'}
|
5
|
-
%title Listing of #{url_root}#{url_path}
|
6
|
-
%meta{name: 'viewport', content: 'width=device-width, height=device-height, user-scalable=no'}
|
7
|
-
:css
|
8
|
-
#{include('css/normalize.css')}
|
9
|
-
#{include('css/common.css')}
|
10
|
-
#{include('css/index.css')}
|
11
|
-
#{include('css/listing.css')}
|
12
|
-
#{include('css/gallery.css')}
|
13
|
-
#{include('css/gallery-text.css')}
|
14
|
-
|
15
|
-
:javascript
|
16
|
-
#{include('js/
|
17
|
-
#{include('js/
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
1
|
+
!!!
|
2
|
+
%html
|
3
|
+
%head
|
4
|
+
%meta{charset: 'utf-8'}
|
5
|
+
%title Listing of #{url_root}#{url_path}
|
6
|
+
%meta{name: 'viewport', content: 'width=device-width, height=device-height, user-scalable=no'}
|
7
|
+
:css
|
8
|
+
#{include('css/normalize.css')}
|
9
|
+
#{include('css/common.css')}
|
10
|
+
#{include('css/index.css')}
|
11
|
+
#{include('css/listing.css')}
|
12
|
+
#{include('css/gallery.css')}
|
13
|
+
#{include('css/gallery-text.css')}
|
14
|
+
|
15
|
+
:javascript
|
16
|
+
#{include('js/url-search-params.js')}
|
17
|
+
#{include('js/listing.js')}
|
18
|
+
#{include('js/ume.js')}
|
19
|
+
#{include('js/gallery.js')}
|
20
|
+
%body
|
21
|
+
- if files.any? { |f| f.media? }
|
22
|
+
#gallery!= partial('gallery')
|
23
|
+
#listing!= partial('listing', { url_root: url_root, url_path: url_path, directories: directories, files: files, sort: sort })
|
@@ -1,9 +1,11 @@
|
|
1
1
|
var $;
|
2
2
|
|
3
3
|
var Gallery = (function() {
|
4
|
+
var TYPES = ["image", "video", "audio", "text"];
|
4
5
|
var urls = [];
|
5
6
|
var types = [];
|
6
7
|
var currentIndex = 0;
|
8
|
+
var $gallery;
|
7
9
|
|
8
10
|
function initItems() {
|
9
11
|
var links = document.querySelectorAll("#listing a.default.media");
|
@@ -26,12 +28,27 @@ var Gallery = (function() {
|
|
26
28
|
http.send();
|
27
29
|
}
|
28
30
|
|
31
|
+
function clearContent() {
|
32
|
+
for(var i = 0; i < TYPES.length; i++) {
|
33
|
+
var type = TYPES[i];
|
34
|
+
|
35
|
+
$gallery.classList.remove(type);
|
36
|
+
|
37
|
+
if(type == "text") {
|
38
|
+
$("#text-content").innerHTML = "";
|
39
|
+
}
|
40
|
+
else {
|
41
|
+
$("#" + type).src = "about:none";
|
42
|
+
}
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
29
46
|
function render() {
|
47
|
+
clearContent();
|
48
|
+
|
30
49
|
var url = urls[currentIndex];
|
31
50
|
var type = types[currentIndex];
|
32
51
|
|
33
|
-
var $gallery = $("#gallery");
|
34
|
-
$gallery.classList.remove("image", "video", "audio", "text");
|
35
52
|
$gallery.classList.add(type);
|
36
53
|
|
37
54
|
if(type == "text") {
|
@@ -129,6 +146,8 @@ var Gallery = (function() {
|
|
129
146
|
}
|
130
147
|
|
131
148
|
function init() {
|
149
|
+
$gallery = $("#gallery");
|
150
|
+
|
132
151
|
initItems();
|
133
152
|
initEvents();
|
134
153
|
render();
|
@@ -0,0 +1,26 @@
|
|
1
|
+
function initListing() {
|
2
|
+
$ = document.querySelector.bind(document);
|
3
|
+
|
4
|
+
function applySort(sortable) {
|
5
|
+
var params = new URLSearchParams(location.search.slice(1));
|
6
|
+
params.set("_servel_sort_method", sortable.dataset.sortMethod);
|
7
|
+
params.set("_servel_sort_direction", sortable.dataset.sortDirection);
|
8
|
+
|
9
|
+
if('sortActive' in sortable.dataset) {
|
10
|
+
params.set("_servel_sort_direction", sortable.dataset.sortDirection == "asc" ? "desc" : "asc");
|
11
|
+
}
|
12
|
+
|
13
|
+
location.href = location.pathname + "?" + params.toString();
|
14
|
+
}
|
15
|
+
|
16
|
+
document.body.addEventListener("click", function(e) {
|
17
|
+
if(!e.target) return;
|
18
|
+
|
19
|
+
if(e.target.closest("th.sortable")) {
|
20
|
+
e.preventDefault();
|
21
|
+
applySort(e.target.closest("th.sortable"));
|
22
|
+
}
|
23
|
+
});
|
24
|
+
}
|
25
|
+
|
26
|
+
window.addEventListener("DOMContentLoaded", initListing);
|
@@ -1,63 +1,63 @@
|
|
1
|
-
var ume = (function() {
|
2
|
-
function normalise(text) {
|
3
|
-
return text.replace(/\s+/g, " ").trim();
|
4
|
-
}
|
5
|
-
|
6
|
-
function escapeEntities(text) {
|
7
|
-
return text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
8
|
-
}
|
9
|
-
|
10
|
-
const BOLD_ITALIC_REGEX = /(?:(\W|^)(\*)|(\*)(\W|$)|(\W|^)(_)|(_)(\W|$))/;
|
11
|
-
|
12
|
-
function parseInlines(text) {
|
13
|
-
const parts = text.split(BOLD_ITALIC_REGEX);
|
14
|
-
|
15
|
-
if(parts.filter(function(part) { return part == "*"; }).length % 2 != 0) return text;
|
16
|
-
if(parts.filter(function(part) { return part == "_"; }).length % 2 != 0) return text;
|
17
|
-
|
18
|
-
var inBold = false;
|
19
|
-
var inItalic = false;
|
20
|
-
var html = [];
|
21
|
-
|
22
|
-
for(const part of parts) {
|
23
|
-
if(part == "*") {
|
24
|
-
inBold = !inBold;
|
25
|
-
html.push(inBold ? "<b>" : "</b>"); //Note that in_bold has been inverted, so this is inverted as well
|
26
|
-
}
|
27
|
-
else if(part == "_") {
|
28
|
-
inItalic = !inItalic;
|
29
|
-
html.push(inItalic ? "<i>" : "</i>"); //Note that in_italic has been inverted, so this is inverted as well
|
30
|
-
}
|
31
|
-
else {
|
32
|
-
html.push(part);
|
33
|
-
}
|
34
|
-
}
|
35
|
-
|
36
|
-
return html.join("");
|
37
|
-
}
|
38
|
-
|
39
|
-
function parseHeading(text) {
|
40
|
-
const parts = text.match(/^(#+) (.*)$/);
|
41
|
-
return "<h" + parts[1].length + ">" + parseInlines(parts[2]) + "</h" + parts[1].length + ">";
|
42
|
-
}
|
43
|
-
|
44
|
-
function parseParagraph(text) {
|
45
|
-
return "<p>" + parseInlines(text) + "</p>";
|
46
|
-
}
|
47
|
-
|
48
|
-
return function(text) {
|
49
|
-
const nodes = text.split(/(\r?\n){2,}/g);
|
50
|
-
var html = [];
|
51
|
-
|
52
|
-
for(const node of nodes) {
|
53
|
-
const cleanedNode = escapeEntities(normalise(node));
|
54
|
-
|
55
|
-
if(cleanedNode.startsWith("#")) html.push(parseHeading(cleanedNode));
|
56
|
-
else html.push(parseParagraph(cleanedNode));
|
57
|
-
}
|
58
|
-
|
59
|
-
return html.join("");
|
60
|
-
}
|
61
|
-
})();
|
62
|
-
|
63
|
-
if(typeof module === "object" && typeof module.exports === "object") module.exports = ume;
|
1
|
+
var ume = (function() {
|
2
|
+
function normalise(text) {
|
3
|
+
return text.replace(/\s+/g, " ").trim();
|
4
|
+
}
|
5
|
+
|
6
|
+
function escapeEntities(text) {
|
7
|
+
return text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
8
|
+
}
|
9
|
+
|
10
|
+
const BOLD_ITALIC_REGEX = /(?:(\W|^)(\*)|(\*)(\W|$)|(\W|^)(_)|(_)(\W|$))/;
|
11
|
+
|
12
|
+
function parseInlines(text) {
|
13
|
+
const parts = text.split(BOLD_ITALIC_REGEX);
|
14
|
+
|
15
|
+
if(parts.filter(function(part) { return part == "*"; }).length % 2 != 0) return text;
|
16
|
+
if(parts.filter(function(part) { return part == "_"; }).length % 2 != 0) return text;
|
17
|
+
|
18
|
+
var inBold = false;
|
19
|
+
var inItalic = false;
|
20
|
+
var html = [];
|
21
|
+
|
22
|
+
for(const part of parts) {
|
23
|
+
if(part == "*") {
|
24
|
+
inBold = !inBold;
|
25
|
+
html.push(inBold ? "<b>" : "</b>"); //Note that in_bold has been inverted, so this is inverted as well
|
26
|
+
}
|
27
|
+
else if(part == "_") {
|
28
|
+
inItalic = !inItalic;
|
29
|
+
html.push(inItalic ? "<i>" : "</i>"); //Note that in_italic has been inverted, so this is inverted as well
|
30
|
+
}
|
31
|
+
else {
|
32
|
+
html.push(part);
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
return html.join("");
|
37
|
+
}
|
38
|
+
|
39
|
+
function parseHeading(text) {
|
40
|
+
const parts = text.match(/^(#+) (.*)$/);
|
41
|
+
return "<h" + parts[1].length + ">" + parseInlines(parts[2]) + "</h" + parts[1].length + ">";
|
42
|
+
}
|
43
|
+
|
44
|
+
function parseParagraph(text) {
|
45
|
+
return "<p>" + parseInlines(text) + "</p>";
|
46
|
+
}
|
47
|
+
|
48
|
+
return function(text) {
|
49
|
+
const nodes = text.split(/(\r?\n){2,}/g);
|
50
|
+
var html = [];
|
51
|
+
|
52
|
+
for(const node of nodes) {
|
53
|
+
const cleanedNode = escapeEntities(normalise(node));
|
54
|
+
|
55
|
+
if(cleanedNode.startsWith("#")) html.push(parseHeading(cleanedNode));
|
56
|
+
else html.push(parseParagraph(cleanedNode));
|
57
|
+
}
|
58
|
+
|
59
|
+
return html.join("");
|
60
|
+
}
|
61
|
+
})();
|
62
|
+
|
63
|
+
if(typeof module === "object" && typeof module.exports === "object") module.exports = ume;
|
@@ -0,0 +1,2 @@
|
|
1
|
+
/*! (C) Andrea Giammarchi - Mit Style License */
|
2
|
+
var URLSearchParams=URLSearchParams||function(){"use strict";function URLSearchParams(query){var index,key,value,pairs,i,length,dict=Object.create(null);this[secret]=dict;if(!query)return;if(typeof query==="string"){if(query.charAt(0)==="?"){query=query.slice(1)}for(pairs=query.split("&"),i=0,length=pairs.length;i<length;i++){value=pairs[i];index=value.indexOf("=");if(-1<index){appendTo(dict,decode(value.slice(0,index)),decode(value.slice(index+1)))}else if(value.length){appendTo(dict,decode(value),"")}}}else{if(isArray(query)){for(i=0,length=query.length;i<length;i++){value=query[i];appendTo(dict,value[0],value[1])}}else{for(key in query){appendTo(dict,key,query[key])}}}}var isArray=Array.isArray,URLSearchParamsProto=URLSearchParams.prototype,find=/[!'\(\)~]|%20|%00/g,plus=/\+/g,replace={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+","%00":"\0"},replacer=function(match){return replace[match]},secret="__URLSearchParams__:"+Math.random();function appendTo(dict,name,value){if(name in dict){dict[name].push(""+value)}else{dict[name]=isArray(value)?value:[""+value]}}function decode(str){return decodeURIComponent(str.replace(plus," "))}function encode(str){return encodeURIComponent(str).replace(find,replacer)}URLSearchParamsProto.append=function append(name,value){appendTo(this[secret],name,value)};URLSearchParamsProto["delete"]=function del(name){delete this[secret][name]};URLSearchParamsProto.get=function get(name){var dict=this[secret];return name in dict?dict[name][0]:null};URLSearchParamsProto.getAll=function getAll(name){var dict=this[secret];return name in dict?dict[name].slice(0):[]};URLSearchParamsProto.has=function has(name){return name in this[secret]};URLSearchParamsProto.set=function set(name,value){this[secret][name]=[""+value]};URLSearchParamsProto.forEach=function forEach(callback,thisArg){var dict=this[secret];Object.getOwnPropertyNames(dict).forEach(function(name){dict[name].forEach(function(value){callback.call(thisArg,value,name,this)},this)},this)};URLSearchParamsProto.toJSON=function toJSON(){return{}};URLSearchParamsProto.toString=function toString(){var dict=this[secret],query=[],i,key,name,value;for(key in dict){name=encode(key);for(i=0,value=dict[key];i<value.length;i++){query.push(name+"="+encode(value[i]))}}return query.join("&")};var dP=Object.defineProperty,gOPD=Object.getOwnPropertyDescriptor,createSearchParamsPollute=function(search){function append(name,value){URLSearchParamsProto.append.call(this,name,value);name=this.toString();search.set.call(this._usp,name?"?"+name:"")}function del(name){URLSearchParamsProto["delete"].call(this,name);name=this.toString();search.set.call(this._usp,name?"?"+name:"")}function set(name,value){URLSearchParamsProto.set.call(this,name,value);name=this.toString();search.set.call(this._usp,name?"?"+name:"")}return function(sp,value){sp.append=append;sp["delete"]=del;sp.set=set;return dP(sp,"_usp",{configurable:true,writable:true,value:value})}},createSearchParamsCreate=function(polluteSearchParams){return function(obj,sp){dP(obj,"_searchParams",{configurable:true,writable:true,value:polluteSearchParams(sp,obj)});return sp}},updateSearchParams=function(sp){var append=sp.append;sp.append=URLSearchParamsProto.append;URLSearchParams.call(sp,sp._usp.search.slice(1));sp.append=append},verifySearchParams=function(obj,Class){if(!(obj instanceof Class))throw new TypeError("'searchParams' accessed on an object that "+"does not implement interface "+Class.name)},upgradeClass=function(Class){var ClassProto=Class.prototype,searchParams=gOPD(ClassProto,"searchParams"),href=gOPD(ClassProto,"href"),search=gOPD(ClassProto,"search"),createSearchParams;if(!searchParams&&search&&search.set){createSearchParams=createSearchParamsCreate(createSearchParamsPollute(search));Object.defineProperties(ClassProto,{href:{get:function(){return href.get.call(this)},set:function(value){var sp=this._searchParams;href.set.call(this,value);if(sp)updateSearchParams(sp)}},search:{get:function(){return search.get.call(this)},set:function(value){var sp=this._searchParams;search.set.call(this,value);if(sp)updateSearchParams(sp)}},searchParams:{get:function(){verifySearchParams(this,Class);return this._searchParams||createSearchParams(this,new URLSearchParams(this.search.slice(1)))},set:function(sp){verifySearchParams(this,Class);createSearchParams(this,sp)}}})}};upgradeClass(HTMLAnchorElement);if(/^function|object$/.test(typeof URL)&&URL.prototype)upgradeClass(URL);return URLSearchParams}();(function(URLSearchParamsProto){var iterable=function(){try{return!!Symbol.iterator}catch(error){return false}}();if(!("forEach"in URLSearchParamsProto)){URLSearchParamsProto.forEach=function forEach(callback,thisArg){var names=Object.create(null);this.toString().replace(/=[\s\S]*?(?:&|$)/g,"=").split("=").forEach(function(name){if(!name.length||name in names)return;(names[name]=this.getAll(name)).forEach(function(value){callback.call(thisArg,value,name,this)},this)},this)}}if(!("keys"in URLSearchParamsProto)){URLSearchParamsProto.keys=function keys(){var items=[];this.forEach(function(value,name){items.push(name)});var iterator={next:function(){var value=items.shift();return{done:value===undefined,value:value}}};if(iterable){iterator[Symbol.iterator]=function(){return iterator}}return iterator}}if(!("values"in URLSearchParamsProto)){URLSearchParamsProto.values=function values(){var items=[];this.forEach(function(value){items.push(value)});var iterator={next:function(){var value=items.shift();return{done:value===undefined,value:value}}};if(iterable){iterator[Symbol.iterator]=function(){return iterator}}return iterator}}if(!("entries"in URLSearchParamsProto)){URLSearchParamsProto.entries=function entries(){var items=[];this.forEach(function(value,name){items.push([name,value])});var iterator={next:function(){var value=items.shift();return{done:value===undefined,value:value}}};if(iterable){iterator[Symbol.iterator]=function(){return iterator}}return iterator}}if(iterable&&!(Symbol.iterator in URLSearchParamsProto)){URLSearchParamsProto[Symbol.iterator]=URLSearchParamsProto.entries}if(!("sort"in URLSearchParamsProto)){URLSearchParamsProto.sort=function sort(){var entries=this.entries(),entry=entries.next(),done=entry.done,keys=[],values=Object.create(null),i,key,value;while(!done){value=entry.value;key=value[0];keys.push(key);if(!(key in values)){values[key]=[]}values[key].push(value[1]);entry=entries.next();done=entry.done}keys.sort();for(i=0;i<keys.length;i++){this["delete"](keys[i])}for(i=0;i<keys.length;i++){key=keys[i];this.append(key,values[key].shift())}}}})(URLSearchParams.prototype);
|
data/lib/servel/version.rb
CHANGED
data/servel.gemspec
CHANGED
@@ -26,6 +26,7 @@ Gem::Specification.new do |spec|
|
|
26
26
|
spec.add_dependency "rack", "~> 2.0"
|
27
27
|
spec.add_dependency "puma"
|
28
28
|
spec.add_dependency "naturalsorter"
|
29
|
-
spec.add_dependency "
|
29
|
+
spec.add_dependency "hamlit"
|
30
30
|
spec.add_dependency "activesupport"
|
31
|
+
spec.add_dependency "lru_redux"
|
31
32
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: servel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brenton "B-Train" Fletcher
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-05-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -81,19 +81,19 @@ dependencies:
|
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: hamlit
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - "
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
89
|
+
version: '0'
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- - "
|
94
|
+
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '
|
96
|
+
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: activesupport
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -108,6 +108,20 @@ dependencies:
|
|
108
108
|
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: lru_redux
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
111
125
|
description: Serves files and directories over HTTP.
|
112
126
|
email:
|
113
127
|
- i@bloople.net
|
@@ -132,6 +146,7 @@ files:
|
|
132
146
|
- lib/servel/haml_context.rb
|
133
147
|
- lib/servel/home_app.rb
|
134
148
|
- lib/servel/index.rb
|
149
|
+
- lib/servel/instrumentation.rb
|
135
150
|
- lib/servel/templates/_gallery.haml
|
136
151
|
- lib/servel/templates/_listing.haml
|
137
152
|
- lib/servel/templates/css/common.css
|
@@ -144,7 +159,9 @@ files:
|
|
144
159
|
- lib/servel/templates/home.haml
|
145
160
|
- lib/servel/templates/index.haml
|
146
161
|
- lib/servel/templates/js/gallery.js
|
162
|
+
- lib/servel/templates/js/listing.js
|
147
163
|
- lib/servel/templates/js/ume.js
|
164
|
+
- lib/servel/templates/js/url-search-params.js
|
148
165
|
- lib/servel/version.rb
|
149
166
|
- servel.gemspec
|
150
167
|
homepage: http://bloople.net/
|