diff --git a/.bowerrc b/.bowerrc deleted file mode 100644 index 1b4ec29..0000000 --- a/.bowerrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "directory" : "material/lib" -} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 81d84ed..6cd8cf3 100644 --- a/.gitignore +++ b/.gitignore @@ -2,12 +2,9 @@ *.sublime-project *.sublime-workspace -# Removes external libraries' files. -material/lib - # Removes some useless build files. -material/build/lib.css -material/build/sass.css +material/dist/* +!material/dist # Removes the user defined template. material/extra.html diff --git a/CHANGELOG.md b/CHANGELOG.md index e58c580..ba8770a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,10 +4,35 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). -## vX.X.X +## v?.?.? +Be careful, one important change comes with this release: the `build` folder is not anymore part of the code repository. So if you use to update the theme with `git pull`, you now need to do + +```bash +$ git pull +$ npm install +$ gulp build +``` + +This will install build tools and process files. I'll now attach ready-to-use built theme to each release, similarly to what is done for Shaarli. + +**Known issue:** the build process outputs scary errors due to new version of *uncss* not understanding properly some links containing RainTPL markup. This doesn't prevent it from working properly so you can ignore. + +### Changed +- Processed JS and CSS files are not anymore in code repository. +- Reorganisation of directories in order to keep `/material` directory clean. +- Updated dependencies. +- Updated Gulp to v4. + +### Removed +- Bower. Front-end dependencies are now also retrieved with NPM. + + +## [v0.10.2-patch.2](https://github.com/kalvn/Shaarli-Material/releases/tag/v0.10.2-patch.2) - 2018-11-06 ### Fixed - HTML class added in the wrong place. - RainTPL escaping in linklist page. +- Open Graph description containing html tags. + ## [v0.10.2](https://github.com/kalvn/Shaarli-Material/releases/tag/v0.10.2) - 2018-11-04 ### Added @@ -19,6 +44,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Thumbnails on link list and daily pages - Daily previous link not disabled properly when on oldest day + ## [v0.9.5](https://github.com/kalvn/Shaarli-Material/releases/tag/v0.9.5) - 2018-02-08 ### Changed - Optimizes bookmarklet popup size and enables scrollbars diff --git a/README.md b/README.md index 37b7c93..5c4cb3a 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,7 @@ This theme uses a few Javascript libraries. - [awesomplete](http://leaverou.github.io/awesomplete/) - [blazy](http://dinbror.dk/blazy/) - [Sortable](http://rubaxa.github.io/Sortable/) +- [Salvattore](https://salvattore.js.org/) ## Demo @@ -94,19 +95,22 @@ A read-only demo is available on my personal Shaarli : [https://links.kalvn.net] ## Develop and debug -To tweak this theme, you'll need to install Javascript and CSS libraries. To do this, install bower and run this command from inside the `material` folder: +To tweak this theme, you'll need to install dependencies and to build JavaScript and CSS libraries. To do this, install [Node.js and NPM](https://nodejs.org) and run this from the root folder: -```shell -bower install +```bash +$ npm install +$ gulp ``` -Then, if you want to compile those files via Gulp, first adapt the `gulp.js` file to your needs. Then, install Gulp and nodejs if it's not done already and run the following command from the root folder: -```shell -npm install -gulp +## Build for production + +```bash +$ npm install +$ gulp build ``` + ------------------------------------------------------------------------------ You can download Shaarli via the Github project page: https://github.com/shaarli/Shaarli diff --git a/bower.json b/bower.json deleted file mode 100644 index 83eaefd..0000000 --- a/bower.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "Shaarli Material Theme", - "dependencies": { - "jquery": ">=1.11.0 <2.0.0", - "bootstrap": ">=3.3.0 <4.0.0", - "moment": ">=2.9.0", - "blazy": ">=1.3.0", - "Sortable": "~1.4.2", - "awesomplete": "^1.1.1", - "salvattore": "^1.0.9" - } -} diff --git a/gulpfile.js b/gulpfile.js index 6a0cb4c..dd34238 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -8,12 +8,13 @@ var gulp = require("gulp"), autoprefixer = require('gulp-autoprefixer'), plumber = require('gulp-plumber'), uglify = require('gulp-uglify'), - uncss = require('gulp-uncss'), - copy = require('gulp-copy'), replace = require('gulp-replace'), addsrc = require('gulp-add-src'), merge = require('merge-stream'), sass = require('gulp-sass'); +var postcss = require('gulp-postcss'); +var uncss = require('postcss-uncss'); +var del = require('del'); var onError = function(err){ console.log('ERROR: ' + err.toString()); @@ -23,28 +24,31 @@ var onError = function(err){ /*****************/ /*** Variables ***/ /*****************/ -var ROOT = 'material/'; -var BUILD_FOLDER = ROOT + 'build'; +var DIR_ROOT = './'; +var DIR_SRC = DIR_ROOT + 'src/'; +var DIR_THEME = DIR_ROOT + 'material/'; +var DIR_LIB = DIR_ROOT + 'node_modules/'; +var DIR_DIST = DIR_THEME + 'dist/'; -var SCSS_SELECTOR = ROOT + 'scss/**/*.scss'; +var SCSS_SELECTOR = DIR_SRC + 'scss/**/*.scss'; var CSS_LIB = [ - ROOT + 'lib/bootstrap/dist/css/bootstrap.min.css' + DIR_LIB + 'bootstrap/dist/css/bootstrap.min.css' ]; var CSS_LIB_NO_UNCSS = [ - ROOT + 'lib/awesomplete/awesomplete.css' + DIR_LIB + 'awesomplete/awesomplete.css' ]; -var JS_SELECTOR = ROOT + 'src/*.js' +var JS_SELECTOR = DIR_SRC + 'js/*.js' var JS_LIB = [ - ROOT + 'lib/jquery/dist/jquery.min.js', - ROOT + 'lib/awesomplete/awesomplete.min.js', - ROOT + 'lib/blazy/blazy.min.js', - ROOT + 'lib/moment/min/moment.min.js', - ROOT + 'lib/Sortable/Sortable.min.js', - ROOT + 'lib/salvattore/dist/salvattore.min.js' + DIR_LIB + 'jquery/dist/jquery.min.js', + DIR_LIB + 'awesomplete/awesomplete.min.js', + DIR_LIB + 'blazy/blazy.min.js', + DIR_LIB + 'moment/min/moment.min.js', + DIR_LIB + 'sortablejs/Sortable.min.js', + DIR_LIB + 'salvattore/dist/salvattore.min.js' ]; -var BOOTSTRAP_FONTS = ROOT + 'lib/bootstrap/dist/fonts/*'; +var BOOTSTRAP_FONTS = DIR_LIB + 'bootstrap/dist/fonts/*'; /*************/ /*** Tasks ***/ @@ -58,34 +62,40 @@ gulp.task('js', function(){ .pipe(concat('scripts.js')) .pipe(uglify()) .pipe(rename('scripts.min.js')) - .pipe(gulp.dest(BUILD_FOLDER)); + .pipe(gulp.dest(DIR_DIST)); }); gulp.task('sass', function(){ - return gulp.src(ROOT + 'scss/styles.scss') + return gulp.src(DIR_SRC + 'scss/styles.scss') .pipe(plumber({ errorHandler: onError })) .pipe(sass()) .pipe(concat('sass.css')) - .pipe(gulp.dest(BUILD_FOLDER)); + .pipe(gulp.dest(DIR_DIST)); }); gulp.task('csslib', function(){ + var plugins = [ + uncss({ + html: [DIR_THEME + '*.html'] + }), + ]; return gulp.src(CSS_LIB) + .pipe(plumber({ + errorHandler: onError + })) .pipe(concat('lib.css')) .pipe(replace(/\.\.\/fonts\//g, 'fonts/')) - .pipe(uncss({ - html: [ROOT + '/*.html'] - })) + .pipe(postcss(plugins)) .pipe(addsrc.append(CSS_LIB_NO_UNCSS)) .pipe(concat('lib.css')) - .pipe(gulp.dest(BUILD_FOLDER)); + .pipe(gulp.dest(DIR_DIST)); }); // Merge css from sass and lib. -gulp.task('css', ['sass', 'csslib'], function(){ - return gulp.src([BUILD_FOLDER + '/lib.css', BUILD_FOLDER + '/sass.css']) +gulp.task('css', gulp.series('sass', 'csslib', function(){ + return gulp.src([DIR_DIST + '/lib.css', DIR_DIST + '/sass.css']) .pipe(plumber({ errorHandler: onError })) @@ -96,15 +106,30 @@ gulp.task('css', ['sass', 'csslib'], function(){ })) .pipe(minifyCSS()) .pipe(rename('styles.min.css')) - .pipe(gulp.dest(BUILD_FOLDER)); + .pipe(gulp.dest(DIR_DIST)); +})); + +gulp.task('assets', function () { + return gulp.src(DIR_SRC + 'assets/**/*') + .pipe(plumber({ + errorHandler: onError + })) + .pipe(gulp.dest(DIR_DIST)); }); -gulp.task('static', function(){ +gulp.task('static', gulp.series('assets', function(){ return gulp.src(BOOTSTRAP_FONTS) .pipe(plumber({ errorHandler: onError })) - .pipe(copy(BUILD_FOLDER + '/fonts/', {prefix: 5})); + .pipe(gulp.dest(DIR_DIST + 'fonts/')); +})); + +gulp.task('clean', function(){ + return del([ + DIR_DIST + 'lib.css', + DIR_DIST + 'sass.css' + ]); }); @@ -112,11 +137,12 @@ gulp.task('static', function(){ /*** Watchlist ***/ /*****************/ gulp.task('watch', function() { - gulp.watch(JS_SELECTOR, ['js']); - gulp.watch(SCSS_SELECTOR, ['css']); + gulp.watch(JS_SELECTOR).on('change', gulp.series('js')); + gulp.watch(SCSS_SELECTOR).on('change', gulp.series('css')); }); /************************/ /*** Boot instruction ***/ /************************/ -gulp.task('default', ['watch', 'css', 'js', 'static']); \ No newline at end of file +gulp.task('default', gulp.parallel('watch', 'css', 'js', 'static')); +gulp.task('build', gulp.series(gulp.parallel('css', 'js', 'static'), 'clean')); diff --git a/material/404.html b/material/404.html index 4526b54..437b906 100644 --- a/material/404.html +++ b/material/404.html @@ -5,7 +5,7 @@ {include="page.header"}
- Nothing found + Nothing found
Sorry... We found nothing here. That's a 404.

{$error_message}

diff --git a/material/build/fonts/glyphicons-halflings-regular.eot b/material/build/fonts/glyphicons-halflings-regular.eot deleted file mode 100644 index b93a495..0000000 Binary files a/material/build/fonts/glyphicons-halflings-regular.eot and /dev/null differ diff --git a/material/build/fonts/glyphicons-halflings-regular.svg b/material/build/fonts/glyphicons-halflings-regular.svg deleted file mode 100644 index 94fb549..0000000 --- a/material/build/fonts/glyphicons-halflings-regular.svg +++ /dev/null @@ -1,288 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/material/build/fonts/glyphicons-halflings-regular.ttf b/material/build/fonts/glyphicons-halflings-regular.ttf deleted file mode 100644 index 1413fc6..0000000 Binary files a/material/build/fonts/glyphicons-halflings-regular.ttf and /dev/null differ diff --git a/material/build/fonts/glyphicons-halflings-regular.woff b/material/build/fonts/glyphicons-halflings-regular.woff deleted file mode 100644 index 9e61285..0000000 Binary files a/material/build/fonts/glyphicons-halflings-regular.woff and /dev/null differ diff --git a/material/build/fonts/glyphicons-halflings-regular.woff2 b/material/build/fonts/glyphicons-halflings-regular.woff2 deleted file mode 100644 index 64539b5..0000000 Binary files a/material/build/fonts/glyphicons-halflings-regular.woff2 and /dev/null differ diff --git a/material/build/scripts.min.js b/material/build/scripts.min.js deleted file mode 100644 index d8e5ebb..0000000 --- a/material/build/scripts.min.js +++ /dev/null @@ -1,7 +0,0 @@ -!function(e,t){"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){function n(e){var t=!!e&&"length"in e&&e.length,n=he.type(e);return"function"!==n&&!he.isWindow(e)&&("array"===n||0===t||"number"==typeof t&&t>0&&t-1 in e)}function i(e,t,n){if(he.isFunction(t))return he.grep(e,function(e,i){return!!t.call(e,i,e)!==n});if(t.nodeType)return he.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(ke.test(t))return he.filter(t,e,n);t=he.filter(t,e)}return he.grep(e,function(e){return he.inArray(e,t)>-1!==n})}function r(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}function o(e){var t={};return he.each(e.match(Me)||[],function(e,n){t[n]=!0}),t}function a(){ie.addEventListener?(ie.removeEventListener("DOMContentLoaded",s),e.removeEventListener("load",s)):(ie.detachEvent("onreadystatechange",s),e.detachEvent("onload",s))}function s(){(ie.addEventListener||"load"===e.event.type||"complete"===ie.readyState)&&(a(),he.ready())}function l(e,t,n){if(void 0===n&&1===e.nodeType){var i="data-"+t.replace(Ye,"-$1").toLowerCase();if(n=e.getAttribute(i),"string"==typeof n){try{n="true"===n||"false"!==n&&("null"===n?null:+n+""===n?+n:Le.test(n)?he.parseJSON(n):n)}catch(r){}he.data(e,t,n)}else n=void 0}return n}function u(e){var t;for(t in e)if(("data"!==t||!he.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}function c(e,t,n,i){if(Oe(e)){var r,o,a=he.expando,s=e.nodeType,l=s?he.cache:e,u=s?e[a]:e[a]&&a;if(u&&l[u]&&(i||l[u].data)||void 0!==n||"string"!=typeof t)return u||(u=s?e[a]=ne.pop()||he.guid++:a),l[u]||(l[u]=s?{}:{toJSON:he.noop}),"object"!=typeof t&&"function"!=typeof t||(i?l[u]=he.extend(l[u],t):l[u].data=he.extend(l[u].data,t)),o=l[u],i||(o.data||(o.data={}),o=o.data),void 0!==n&&(o[he.camelCase(t)]=n),"string"==typeof t?(r=o[t],null==r&&(r=o[he.camelCase(t)])):r=o,r}}function d(e,t,n){if(Oe(e)){var i,r,o=e.nodeType,a=o?he.cache:e,s=o?e[he.expando]:he.expando;if(a[s]){if(t&&(i=n?a[s]:a[s].data)){he.isArray(t)?t=t.concat(he.map(t,he.camelCase)):t in i?t=[t]:(t=he.camelCase(t),t=t in i?[t]:t.split(" ")),r=t.length;for(;r--;)delete i[t[r]];if(n?!u(i):!he.isEmptyObject(i))return}(n||(delete a[s].data,u(a[s])))&&(o?he.cleanData([e],!0):de.deleteExpando||a!=a.window?delete a[s]:a[s]=void 0)}}}function f(e,t,n,i){var r,o=1,a=20,s=i?function(){return i.cur()}:function(){return he.css(e,t,"")},l=s(),u=n&&n[3]||(he.cssNumber[t]?"":"px"),c=(he.cssNumber[t]||"px"!==u&&+l)&&He.exec(he.css(e,t));if(c&&c[3]!==u){u=u||c[3],n=n||[],c=+l||1;do o=o||".5",c/=o,he.style(e,t,c+u);while(o!==(o=s()/l)&&1!==o&&--a)}return n&&(c=+c||+l||0,r=n[1]?c+(n[1]+1)*n[2]:+n[2],i&&(i.unit=u,i.start=c,i.end=r)),r}function h(e){var t=Be.split("|"),n=e.createDocumentFragment();if(n.createElement)for(;t.length;)n.createElement(t.pop());return n}function p(e,t){var n,i,r=0,o="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):void 0;if(!o)for(o=[],n=e.childNodes||e;null!=(i=n[r]);r++)!t||he.nodeName(i,t)?o.push(i):he.merge(o,p(i,t));return void 0===t||t&&he.nodeName(e,t)?he.merge([e],o):o}function m(e,t){for(var n,i=0;null!=(n=e[i]);i++)he._data(n,"globalEval",!t||he._data(t[i],"globalEval"))}function g(e){$e.test(e.type)&&(e.defaultChecked=e.checked)}function v(e,t,n,i,r){for(var o,a,s,l,u,c,d,f=e.length,v=h(t),y=[],b=0;f>b;b++)if(a=e[b],a||0===a)if("object"===he.type(a))he.merge(y,a.nodeType?[a]:a);else if(ze.test(a)){for(l=l||v.appendChild(t.createElement("div")),u=(We.exec(a)||["",""])[1].toLowerCase(),d=Ue[u]||Ue._default,l.innerHTML=d[1]+he.htmlPrefilter(a)+d[2],o=d[0];o--;)l=l.lastChild;if(!de.leadingWhitespace&&qe.test(a)&&y.push(t.createTextNode(qe.exec(a)[0])),!de.tbody)for(a="table"!==u||Ve.test(a)?""!==d[1]||Ve.test(a)?0:l:l.firstChild,o=a&&a.childNodes.length;o--;)he.nodeName(c=a.childNodes[o],"tbody")&&!c.childNodes.length&&a.removeChild(c);for(he.merge(y,l.childNodes),l.textContent="";l.firstChild;)l.removeChild(l.firstChild);l=v.lastChild}else y.push(t.createTextNode(a));for(l&&v.removeChild(l),de.appendChecked||he.grep(p(y,"input"),g),b=0;a=y[b++];)if(i&&he.inArray(a,i)>-1)r&&r.push(a);else if(s=he.contains(a.ownerDocument,a),l=p(v.appendChild(a),"script"),s&&m(l),n)for(o=0;a=l[o++];)Ie.test(a.type||"")&&n.push(a);return l=null,v}function y(){return!0}function b(){return!1}function w(){try{return ie.activeElement}catch(e){}}function _(e,t,n,i,r,o){var a,s;if("object"==typeof t){"string"!=typeof n&&(i=i||n,n=void 0);for(s in t)_(e,s,n,i,t[s],o);return e}if(null==i&&null==r?(r=n,i=n=void 0):null==r&&("string"==typeof n?(r=i,i=void 0):(r=i,i=n,n=void 0)),r===!1)r=b;else if(!r)return e;return 1===o&&(a=r,r=function(e){return he().off(e),a.apply(this,arguments)},r.guid=a.guid||(a.guid=he.guid++)),e.each(function(){he.event.add(this,t,r,i,n)})}function x(e,t){return he.nodeName(e,"table")&&he.nodeName(11!==t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function k(e){return e.type=(null!==he.find.attr(e,"type"))+"/"+e.type,e}function S(e){var t=rt.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function T(e,t){if(1===t.nodeType&&he.hasData(e)){var n,i,r,o=he._data(e),a=he._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(i=0,r=s[n].length;r>i;i++)he.event.add(t,n,s[n][i])}a.data&&(a.data=he.extend({},a.data))}}function C(e,t){var n,i,r;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!de.noCloneEvent&&t[he.expando]){r=he._data(t);for(i in r.events)he.removeEvent(t,i,r.handle);t.removeAttribute(he.expando)}"script"===n&&t.text!==e.text?(k(t).text=e.text,S(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),de.html5Clone&&e.innerHTML&&!he.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&$e.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:"input"!==n&&"textarea"!==n||(t.defaultValue=e.defaultValue)}}function D(e,t,n,i){t=oe.apply([],t);var r,o,a,s,l,u,c=0,d=e.length,f=d-1,h=t[0],m=he.isFunction(h);if(m||d>1&&"string"==typeof h&&!de.checkClone&&it.test(h))return e.each(function(r){var o=e.eq(r);m&&(t[0]=h.call(this,r,o.html())),D(o,t,n,i)});if(d&&(u=v(t,e[0].ownerDocument,!1,e,i),r=u.firstChild,1===u.childNodes.length&&(u=r),r||i)){for(s=he.map(p(u,"script"),k),a=s.length;d>c;c++)o=u,c!==f&&(o=he.clone(o,!0,!0),a&&he.merge(s,p(o,"script"))),n.call(e[c],o,c);if(a)for(l=s[s.length-1].ownerDocument,he.map(s,S),c=0;a>c;c++)o=s[c],Ie.test(o.type||"")&&!he._data(o,"globalEval")&&he.contains(l,o)&&(o.src?he._evalUrl&&he._evalUrl(o.src):he.globalEval((o.text||o.textContent||o.innerHTML||"").replace(ot,"")));u=r=null}return e}function E(e,t,n){for(var i,r=t?he.filter(t,e):e,o=0;null!=(i=r[o]);o++)n||1!==i.nodeType||he.cleanData(p(i)),i.parentNode&&(n&&he.contains(i.ownerDocument,i)&&m(p(i,"script")),i.parentNode.removeChild(i));return e}function M(e,t){var n=he(t.createElement(e)).appendTo(t.body),i=he.css(n[0],"display");return n.detach(),i}function N(e){var t=ie,n=ut[e];return n||(n=M(e,t),"none"!==n&&n||(lt=(lt||he("