From 8c4c4259d4f9a856c8c7773591b40be9aef97bb1 Mon Sep 17 00:00:00 2001 From: Markus Heiser Date: Thu, 25 Nov 2021 10:03:12 +0100 Subject: [PATCH 1/3] [mod] gruntfile: do some polish (no functional change) - remove unused 'path' constant - fix indentation - Put all image tasks at the end, where it is easy to list which image is processed. Suggested -by: @dalf https://github.com/searxng/searxng/pull/541#discussion_r756247157 Signed-off-by: Markus Heiser --- searx/static/themes/simple/gruntfile.js | 48 +++++++++++++++---------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/searx/static/themes/simple/gruntfile.js b/searx/static/themes/simple/gruntfile.js index 006d64417..83989397d 100644 --- a/searx/static/themes/simple/gruntfile.js +++ b/searx/static/themes/simple/gruntfile.js @@ -2,8 +2,6 @@ module.exports = function(grunt) { - const path = require('path'); - grunt.initConfig({ _brand: '../../../../src/brand', @@ -13,7 +11,16 @@ module.exports = function(grunt) { watch: { scripts: { files: ['gruntfile.js', 'src/**'], - tasks: ['eslint', 'copy', 'concat', 'svg2jinja', 'uglify', 'image', 'less:development', 'less:production'] + tasks: [ + 'eslint', + 'copy', + 'concat', + 'uglify', + 'less:development', + 'less:production', + 'image', + 'svg2jinja' + ] } }, eslint: { @@ -78,14 +85,18 @@ module.exports = function(grunt) { }, files: { 'js/searxng.head.js': ['src/js/head/*.js'], - 'js/searxng.js': ['src/js/main/*.js', '../__common__/js/*.js', './node_modules/autocomplete-js/dist/autocomplete.js'] + 'js/searxng.js': [ + 'src/js/main/*.js', + '../__common__/js/*.js', + './node_modules/autocomplete-js/dist/autocomplete.js' + ] } } }, uglify: { options: { output: { - comments: 'some' + comments: 'some' }, ie8: false, warnings: true, @@ -100,16 +111,6 @@ module.exports = function(grunt) { } } }, - image: { - svg4web: { - options: { - svgo: ['--config', 'svg4web.svgo.js'] - }, - files: { - '<%= _templates %>/__common__/searxng-wordmark.min.svg': '<%= _brand %>/searxng-wordmark.svg' - } - } - }, less: { development: { options: { @@ -137,6 +138,16 @@ module.exports = function(grunt) { } }, }, + image: { + svg4web: { + options: { + svgo: ['--config', 'svg4web.svgo.js'] + }, + files: { + '<%= _templates %>/__common__/searxng-wordmark.min.svg': '<%= _brand %>/searxng-wordmark.svg' + } + } + }, svg2jinja: { all: { src: { @@ -165,7 +176,6 @@ module.exports = function(grunt) { }, }); - grunt.registerMultiTask('svg2jinja', 'Create Jinja2 macro', function() { const ejs = require('ejs'), svgo = require('svgo'); const icons = {} @@ -240,10 +250,10 @@ module.exports = function(grunt) { 'stylelint', 'copy', 'concat', - 'svg2jinja', 'uglify', - 'image', 'less:development', - 'less:production' + 'less:production', + 'image', + 'svg2jinja', ]); }; From 59f4c792b498ef399dad5643576327da8ed122f2 Mon Sep 17 00:00:00 2001 From: Alexandre Flament Date: Tue, 23 Nov 2021 20:18:09 +0100 Subject: [PATCH 2/3] [mod] simple theme: use sharp instead of convert to create .png from .svg define a custom grunt task, since grunt-sharp is too old (it can't be installed). in gruntfile.js, the image tasks are moved at the end the build chain. Signed-off-by: Markus Heiser --- manage | 30 ------------------ searx/static/themes/simple/gruntfile.js | 41 +++++++++++++++++++++++++ searx/static/themes/simple/package.json | 1 + 3 files changed, 42 insertions(+), 30 deletions(-) diff --git a/manage b/manage index ec8e13c0a..1236cb31c 100755 --- a/manage +++ b/manage @@ -708,42 +708,12 @@ themes.oscar() { themes.simple() { local static="searx/static/themes/simple" ( set -e - convert_if_newer "src/brand/searxng-wordmark.svg" "$static/img/favicon.png" \ - -transparent white -resize 64x64 build_msg GRUNT "theme: simple" npm --prefix searx/static/themes/simple run build ) dump_return $? } -convert_if_newer() { - - # usage: convert_if_newer [, ...] - # - # convert_if_newer "path/to/origin.svg" "path/to/converted.png" -resize 100x100 - # - # Run's ImageMagik' convert comand to generate from , if - # is newer than . The command line is to convert is:: - # - # convert [, ...] - - local src_file="$1" && shift - local dst_file="$1" && shift - - if [[ "${src_file}" -nt "${dst_file}" ]]; then - if ! required_commands convert; then - info_msg "to install build tools use::" - info_msg " sudo -H ./utils/searx.sh install buildhost" - die 1 "install needed build tools first" - fi - build_msg CONVERT "${src_file}" "$@" "${dst_file}" - convert "${src_file}" "$@" "${dst_file}" - else - build_msg CONVERT "${dst_file} (up-to-date)" - fi -} - - PYLINT_FILES=() while IFS= read -r line; do PYLINT_FILES+=("$line") diff --git a/searx/static/themes/simple/gruntfile.js b/searx/static/themes/simple/gruntfile.js index 83989397d..d51316dcf 100644 --- a/searx/static/themes/simple/gruntfile.js +++ b/searx/static/themes/simple/gruntfile.js @@ -2,6 +2,8 @@ module.exports = function(grunt) { + const eachAsync = require('each-async'); + grunt.initConfig({ _brand: '../../../../src/brand', @@ -19,6 +21,7 @@ module.exports = function(grunt) { 'less:development', 'less:production', 'image', + 'svg2png', 'svg2jinja' ] } @@ -148,6 +151,13 @@ module.exports = function(grunt) { } } }, + svg2png: { + favicon: { + files: { + 'img/favicon.png': '<%= _brand %>/searxng-wordmark.svg' + } + } + }, svg2jinja: { all: { src: { @@ -232,6 +242,36 @@ module.exports = function(grunt) { grunt.log.ok(this.data.dest + " created"); }); + grunt.registerMultiTask('svg2png', 'Convert SVG to PNG', function () { + const sharp = require('sharp'), done = this.async(); + eachAsync(this.files, async (file, _index, next) => { + try { + if (file.src.length != 1) { + next("this task supports only one source per destination"); + } + const info = await sharp(file.src[0]) + .png({ + force: true, + compressionLevel: 9, + palette: true, + }) + .toFile(file.dest); + grunt.log.ok(file.dest + ' created (' + info.size + ' bytes, ' + info.width + 'px * ' + info.height + 'px)'); + next(); + } catch (error) { + grunt.fatal(error); + next(error); + } + }, error => { + if (error) { + grunt.fatal(error); + done(error); + } else { + done(); + } + }); + }); + grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-contrib-copy'); grunt.loadNpmTasks('grunt-contrib-uglify'); @@ -254,6 +294,7 @@ module.exports = function(grunt) { 'less:development', 'less:production', 'image', + 'svg2png', 'svg2jinja', ]); }; diff --git a/searx/static/themes/simple/package.json b/searx/static/themes/simple/package.json index 25797b8fe..0cf6c4f64 100644 --- a/searx/static/themes/simple/package.json +++ b/searx/static/themes/simple/package.json @@ -16,6 +16,7 @@ "ionicons": "^6.0.0", "less": "^4.1.1", "less-plugin-clean-css": "^1.5.1", + "sharp": "^0.29.3", "stylelint": "^13.13.1", "stylelint-config-standard": "^22.0.0", "ejs": "^3.1.6", From 8154dd2a2e7f0749b592882901774af9f3af05b8 Mon Sep 17 00:00:00 2001 From: Markus Heiser Date: Sun, 28 Nov 2021 20:07:49 +0100 Subject: [PATCH 3/3] [build] /static --- searx/static/themes/simple/img/favicon.png | Bin 11114 -> 5096 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/searx/static/themes/simple/img/favicon.png b/searx/static/themes/simple/img/favicon.png index 3b961014b92ecd5d15f4abf58222fb5dae85e977..b90d44fd869468f44c5ed70cad109327fc3989ca 100644 GIT binary patch literal 5096 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