Quellcode durchsuchen

[enh] add simple theme (WIP)

Alexandre Flament vor 8 Jahren
Ursprung
Commit
10a24bdc2c
85 geänderte Dateien mit 11902 neuen und 6 gelöschten Zeilen
  1. 10
    0
      .gitattributes
  2. 3
    2
      .travis.yml
  3. 7
    3
      manage.sh
  4. 1
    0
      searx/plugins/doai_rewrite.py
  5. 1
    0
      searx/plugins/https_rewrite.py
  6. 1
    0
      searx/plugins/infinite_scroll.py
  7. 1
    0
      searx/plugins/search_on_category_select.py
  8. 1
    0
      searx/plugins/tracker_url_remover.py
  9. 1
    0
      searx/static/themes/simple/.jshintignore
  10. 2049
    0
      searx/static/themes/simple/css/searx-rtl.css
  11. 1
    0
      searx/static/themes/simple/css/searx-rtl.min.css
  12. 2045
    0
      searx/static/themes/simple/css/searx.css
  13. 1
    0
      searx/static/themes/simple/css/searx.min.css
  14. 134
    0
      searx/static/themes/simple/fonts/ion.css
  15. BIN
      searx/static/themes/simple/fonts/ion.eot
  16. 261
    0
      searx/static/themes/simple/fonts/ion.html
  17. 97
    0
      searx/static/themes/simple/fonts/ion.svg
  18. BIN
      searx/static/themes/simple/fonts/ion.ttf
  19. BIN
      searx/static/themes/simple/fonts/ion.woff
  20. BIN
      searx/static/themes/simple/fonts/ion.woff2
  21. 150
    0
      searx/static/themes/simple/gruntfile.js
  22. BIN
      searx/static/themes/simple/img/favicon.png
  23. BIN
      searx/static/themes/simple/img/loader.gif
  24. BIN
      searx/static/themes/simple/img/logo_searx_a.png
  25. BIN
      searx/static/themes/simple/img/searx.png
  26. 203
    0
      searx/static/themes/simple/img/searx_logo.svg
  27. 1534
    0
      searx/static/themes/simple/js/searx.js
  28. 4
    0
      searx/static/themes/simple/js/searx.min.js
  29. 1
    0
      searx/static/themes/simple/js/searx.min.js.map
  30. 155
    0
      searx/static/themes/simple/js/searx_src/00_searx_toolkit.js
  31. 536
    0
      searx/static/themes/simple/js/searx_src/autocomplete.js
  32. 151
    0
      searx/static/themes/simple/js/searx_src/searx_imageresult.js
  33. 360
    0
      searx/static/themes/simple/js/searx_src/searx_keyboard.js
  34. 175
    0
      searx/static/themes/simple/js/searx_src/searx_mapresult.js
  35. 63
    0
      searx/static/themes/simple/js/searx_src/searx_results.js
  36. 94
    0
      searx/static/themes/simple/js/searx_src/searx_search.js
  37. BIN
      searx/static/themes/simple/leaflet/images/layers-2x.png
  38. BIN
      searx/static/themes/simple/leaflet/images/layers.png
  39. BIN
      searx/static/themes/simple/leaflet/images/marker-icon-2x-green.png
  40. BIN
      searx/static/themes/simple/leaflet/images/marker-icon-2x-orange.png
  41. BIN
      searx/static/themes/simple/leaflet/images/marker-icon-2x-red.png
  42. BIN
      searx/static/themes/simple/leaflet/images/marker-icon-2x.png
  43. BIN
      searx/static/themes/simple/leaflet/images/marker-icon-green.png
  44. BIN
      searx/static/themes/simple/leaflet/images/marker-icon-orange.png
  45. BIN
      searx/static/themes/simple/leaflet/images/marker-icon-red.png
  46. BIN
      searx/static/themes/simple/leaflet/images/marker-icon.png
  47. BIN
      searx/static/themes/simple/leaflet/images/marker-shadow.png
  48. 624
    0
      searx/static/themes/simple/leaflet/leaflet.css
  49. 9
    0
      searx/static/themes/simple/leaflet/leaflet.js
  50. 67
    0
      searx/static/themes/simple/less/autocomplete.less
  51. 83
    0
      searx/static/themes/simple/less/code.less
  52. 135
    0
      searx/static/themes/simple/less/definitions.less
  53. 43
    0
      searx/static/themes/simple/less/index.less
  54. 174
    0
      searx/static/themes/simple/less/ion.less
  55. 62
    0
      searx/static/themes/simple/less/mixins.less
  56. 447
    0
      searx/static/themes/simple/less/normalize.less
  57. 78
    0
      searx/static/themes/simple/less/preferences.less
  58. 232
    0
      searx/static/themes/simple/less/search.less
  59. 8
    0
      searx/static/themes/simple/less/stats.less
  60. 6
    0
      searx/static/themes/simple/less/style-rtl.less
  61. 709
    0
      searx/static/themes/simple/less/style.less
  62. 346
    0
      searx/static/themes/simple/less/toolkit.less
  63. 1
    0
      searx/static/themes/simple/magnet.svg
  64. 20
    0
      searx/static/themes/simple/package.json
  65. 1
    1
      searx/templates/oscar/preferences.html
  66. 9
    0
      searx/templates/simple/404.html
  67. 4
    0
      searx/templates/simple/about.html
  68. 61
    0
      searx/templates/simple/base.html
  69. 8
    0
      searx/templates/simple/categories.html
  70. 12
    0
      searx/templates/simple/index.html
  71. 46
    0
      searx/templates/simple/infobox.html
  72. 8
    0
      searx/templates/simple/languages.html
  73. 86
    0
      searx/templates/simple/macros.html
  74. 190
    0
      searx/templates/simple/preferences.html
  75. 13
    0
      searx/templates/simple/result_templates/code.html
  76. 17
    0
      searx/templates/simple/result_templates/default.html
  77. 4
    0
      searx/templates/simple/result_templates/images.html
  78. 71
    0
      searx/templates/simple/result_templates/map.html
  79. 24
    0
      searx/templates/simple/result_templates/torrent.html
  80. 15
    0
      searx/templates/simple/result_templates/videos.html
  81. 151
    0
      searx/templates/simple/results.html
  82. 16
    0
      searx/templates/simple/search.html
  83. 40
    0
      searx/templates/simple/simple.spec.txt
  84. 25
    0
      searx/templates/simple/stats.html
  85. 17
    0
      searx/templates/simple/time-range.html

+ 10
- 0
.gitattributes Datei anzeigen

@@ -0,0 +1,10 @@
1
+searx/static/css/bootstrap.min.css -diff
2
+searx/static/js/bootstrap.min.js -diff
3
+searx/static/themes/oscar/css/logicodev.min.css -diff
4
+searx/static/themes/oscar/css/leaflet.min.css -diff
5
+searx/static/themes/oscar/css/pointhi.min.css -diff
6
+searx/static/themes/oscar/js/searx.min.js -diff
7
+searx/static/themes/simple/css/searx.min.css -diff
8
+searx/static/themes/simple/css/searx-rtl.min.css -diff
9
+searx/static/themes/simple/js/searx.min.js -diff
10
+searx/static/themes/simple/js/searx.min.js.map -diff

+ 3
- 2
.travis.yml Datei anzeigen

@@ -13,10 +13,11 @@ python:
13 13
 before_install:
14 14
   - "export DISPLAY=:99.0"
15 15
   - "sh -e /etc/init.d/xvfb start"
16
-  - npm install less grunt-cli
16
+  - npm install less less-plugin-clean-css grunt-cli
17 17
   - ( cd searx/static/themes/oscar;npm install; cd - )
18
+  - ( cd searx/static/themes/simple;npm install; cd - )
18 19
   - mkdir -p ~/drivers; export PATH=~/drivers:$PATH;
19
-  - GECKODRIVER_URL="https://github.com/mozilla/geckodriver/releases/download/v0.11.1/geckodriver-v0.11.1-linux64.tar.gz";
20
+  - GECKODRIVER_URL="https://github.com/mozilla/geckodriver/releases/download/v0.14.0/geckodriver-v0.14.0-linux64.tar.gz";
20 21
   - FILE=`mktemp`; wget "$GECKODRIVER_URL" -qO $FILE && tar xz -C ~/drivers -f $FILE geckodriver; rm $FILE; chmod 777 ~/drivers/geckodriver;
21 22
 install:
22 23
   - ./manage.sh update_dev_packages

+ 7
- 3
manage.sh Datei anzeigen

@@ -22,7 +22,7 @@ check_geckodriver() {
22 22
     if [ -z $NOTFOUND ]; then
23 23
 	return
24 24
     fi
25
-    GECKODRIVER_VERSION="v0.11.1"
25
+    GECKODRIVER_VERSION="v0.14.0"
26 26
     PLATFORM=`python -c "import platform; print platform.system().lower(), platform.architecture()[0]"`
27 27
     case $PLATFORM in
28 28
 	"linux 32bit" | "linux2 32bit") ARCH="linux32";;
@@ -49,7 +49,7 @@ pep8_check() {
49 49
     # ignored rules:
50 50
     #  E402 module level import not at top of file
51 51
     #  W503 line break before binary operator
52
-    pep8 --max-line-length=120 --ignore "E402,W503" "$SEARX_DIR" "$BASE_DIR/tests"
52
+    pep8 --exclude=searx/static --max-line-length=120 --ignore "E402,W503" "$SEARX_DIR" "$BASE_DIR/tests"
53 53
 }
54 54
 
55 55
 unit_tests() {
@@ -79,7 +79,8 @@ tests() {
79 79
 }
80 80
 
81 81
 build_style() {
82
-    lessc -x "$BASE_DIR/searx/static/$1" "$BASE_DIR/searx/static/$2"
82
+    # lessc -x "$BASE_DIR/searx/static/$1" "$BASE_DIR/searx/static/$2"
83
+    lessc --clean-css="--s1 --advanced --compatibility=ie9" "$BASE_DIR/searx/static/$1" "$BASE_DIR/searx/static/$2"
83 84
 }
84 85
 
85 86
 styles() {
@@ -92,10 +93,13 @@ styles() {
92 93
 	build_style themes/oscar/less/pointhi/oscar.less themes/oscar/css/pointhi.min.css
93 94
 	build_style themes/oscar/less/logicodev/oscar.less themes/oscar/css/logicodev.min.css
94 95
 	build_style themes/pix-art/less/style.less themes/pix-art/css/style.css
96
+	build_style themes/simple/less/style.less themes/simple/css/searx.min.css
97
+	build_style themes/simple/less/style-rtl.less themes/simple/css/searx-rtl.min.css
95 98
 }
96 99
 
97 100
 grunt_build() {
98 101
 	grunt --gruntfile "$SEARX_DIR/static/themes/oscar/gruntfile.js"
102
+	grunt --gruntfile "$SEARX_DIR/static/themes/simple/gruntfile.js"
99 103
 }
100 104
 
101 105
 locales() {

+ 1
- 0
searx/plugins/doai_rewrite.py Datei anzeigen

@@ -7,6 +7,7 @@ regex = re.compile(r'10\.\d{4,9}/[^\s]+')
7 7
 name = gettext('DOAI rewrite')
8 8
 description = gettext('Avoid paywalls by redirecting to open-access versions of publications when available')
9 9
 default_on = False
10
+preference_section = 'privacy'
10 11
 
11 12
 
12 13
 def extract_doi(url):

+ 1
- 0
searx/plugins/https_rewrite.py Datei anzeigen

@@ -31,6 +31,7 @@ if sys.version_info[0] == 3:
31 31
 name = "HTTPS rewrite"
32 32
 description = gettext('Rewrite HTTP links to HTTPS if possible')
33 33
 default_on = True
34
+preference_section = 'privacy'
34 35
 
35 36
 if 'SEARX_HTTPS_REWRITE_PATH' in environ:
36 37
     rules_path = environ['SEARX_rules_path']

+ 1
- 0
searx/plugins/infinite_scroll.py Datei anzeigen

@@ -3,6 +3,7 @@ from flask_babel import gettext
3 3
 name = gettext('Infinite scroll')
4 4
 description = gettext('Automatically load next page when scrolling to bottom of current page')
5 5
 default_on = False
6
+preference_section = 'ui'
6 7
 
7 8
 js_dependencies = ('plugins/js/infinite_scroll.js',)
8 9
 css_dependencies = ('plugins/css/infinite_scroll.css',)

+ 1
- 0
searx/plugins/search_on_category_select.py Datei anzeigen

@@ -19,5 +19,6 @@ name = gettext('Search on category select')
19 19
 description = gettext('Perform search immediately if a category selected. '
20 20
                       'Disable to select multiple categories. (JavaScript required)')
21 21
 default_on = True
22
+preference_section = 'ui'
22 23
 
23 24
 js_dependencies = ('plugins/js/search_on_category_select.js',)

+ 1
- 0
searx/plugins/tracker_url_remover.py Datei anzeigen

@@ -26,6 +26,7 @@ regexes = {re.compile(r'utm_[^&]+&?'),
26 26
 name = gettext('Tracker URL remover')
27 27
 description = gettext('Remove trackers arguments from the returned URL')
28 28
 default_on = True
29
+preference_section = 'privacy'
29 30
 
30 31
 
31 32
 def on_result(request, search, result):

+ 1
- 0
searx/static/themes/simple/.jshintignore Datei anzeigen

@@ -0,0 +1 @@
1
+js/searx_src/autocomplete.js

+ 2049
- 0
searx/static/themes/simple/css/searx-rtl.css
Datei-Diff unterdrückt, da er zu groß ist
Datei anzeigen


+ 1
- 0
searx/static/themes/simple/css/searx-rtl.min.css
Datei-Diff unterdrückt, da er zu groß ist
Datei anzeigen


+ 2045
- 0
searx/static/themes/simple/css/searx.css
Datei-Diff unterdrückt, da er zu groß ist
Datei anzeigen


+ 1
- 0
searx/static/themes/simple/css/searx.min.css
Datei-Diff unterdrückt, da er zu groß ist
Datei anzeigen


+ 134
- 0
searx/static/themes/simple/fonts/ion.css Datei anzeigen

@@ -0,0 +1,134 @@
1
+/* Generated by grunt-webfont */
2
+
3
+
4
+@font-face {
5
+	font-family:"ion";
6
+	src:url("../fonts/ion.eot?94af7082ea096aefe3a7b6642834716e");
7
+	src:url("../fonts/ion.eot?#iefix") format("embedded-opentype"),
8
+		url("../fonts/ion.woff2?94af7082ea096aefe3a7b6642834716e") format("woff2"),
9
+		url("../fonts/ion.woff?94af7082ea096aefe3a7b6642834716e") format("woff"),
10
+		url("../fonts/ion.ttf?94af7082ea096aefe3a7b6642834716e") format("truetype"),
11
+		url("../fonts/ion.svg?94af7082ea096aefe3a7b6642834716e#ion") format("svg");
12
+	font-weight:normal;
13
+	font-style:normal;
14
+}
15
+
16
+.ion-icon {
17
+	
18
+		font-family:"ion";
19
+	
20
+	display:inline-block;
21
+	vertical-align:middle;
22
+	line-height:1;
23
+	font-weight:normal;
24
+	font-style:normal;
25
+	speak:none;
26
+	text-decoration:inherit;
27
+	text-transform:none;
28
+	text-rendering:auto;
29
+	-webkit-font-smoothing:antialiased;
30
+	-moz-osx-font-smoothing:grayscale;
31
+}
32
+
33
+
34
+/* Icons */
35
+
36
+
37
+.ion-navicon-round:before {
38
+	content:"\f101";
39
+}
40
+
41
+
42
+.ion-search:before {
43
+	content:"\f102";
44
+}
45
+
46
+
47
+.ion-play:before {
48
+	content:"\f103";
49
+}
50
+
51
+
52
+.ion-link:before {
53
+	content:"\f104";
54
+}
55
+
56
+
57
+.ion-chevron-up:before {
58
+	content:"\f105";
59
+}
60
+
61
+
62
+.ion-chevron-left:before {
63
+	content:"\f106";
64
+}
65
+
66
+
67
+.ion-chevron-right:before {
68
+	content:"\f107";
69
+}
70
+
71
+
72
+.ion-arrow-down-a:before {
73
+	content:"\f108";
74
+}
75
+
76
+
77
+.ion-arrow-up-a:before {
78
+	content:"\f109";
79
+}
80
+
81
+
82
+.ion-arrow-swap:before {
83
+	content:"\f10a";
84
+}
85
+
86
+
87
+.ion-arrow-dropdown:before {
88
+	content:"\f10b";
89
+}
90
+
91
+
92
+.ion-globe:before {
93
+	content:"\f10c";
94
+}
95
+
96
+
97
+.ion-time:before {
98
+	content:"\f10d";
99
+}
100
+
101
+
102
+.ion-location:before {
103
+	content:"\f10e";
104
+}
105
+
106
+
107
+.ion-warning:before {
108
+	content:"\f10f";
109
+}
110
+
111
+
112
+.ion-error:before {
113
+	content:"\f110";
114
+}
115
+
116
+
117
+.ion-film-outline:before {
118
+	content:"\f111";
119
+}
120
+
121
+
122
+.ion-music-note:before {
123
+	content:"\f112";
124
+}
125
+
126
+
127
+.ion-more-vertical:before {
128
+	content:"\f113";
129
+}
130
+
131
+
132
+.ion-magnet:before {
133
+	content:"\f114";
134
+}

BIN
searx/static/themes/simple/fonts/ion.eot Datei anzeigen


+ 261
- 0
searx/static/themes/simple/fonts/ion.html Datei anzeigen

@@ -0,0 +1,261 @@
1
+<!doctype html>
2
+<html>
3
+	<head>
4
+		<meta charset="utf-8">
5
+		<title>ion</title>
6
+		<style>
7
+		body {
8
+			margin:0;
9
+			padding:10px 20px;
10
+			background:#fff;
11
+			color:#222;
12
+			}
13
+		h1, div, footer {
14
+			font-family:"Helvetica Neue", Arial, sans-serif;
15
+			}
16
+		h1 {
17
+			margin:0 0 20px;
18
+			font-size:32px;
19
+			font-weight:normal;
20
+			}
21
+		h1 small {
22
+			font-size: 0.8em;
23
+			padding-left: 2em;
24
+		}
25
+		.icons {
26
+			margin-bottom:40px;
27
+			-webkit-column-count:5;
28
+			   -moz-column-count:5;
29
+			        column-count:5;
30
+			-webkit-column-gap:20px;
31
+			   -moz-column-gap:20px;
32
+			        column-gap:20px;
33
+			}
34
+		.icons__item,
35
+		.icons__item i {
36
+			line-height:2em;
37
+			cursor:pointer;
38
+			overflow:hidden;
39
+			}
40
+		.icons__item:hover {
41
+			color:#3c90be;
42
+			}
43
+		.icons__item i {
44
+			display:inline-block;
45
+			width:32px;
46
+			text-align:center;
47
+			}
48
+		.icons__item:hover i {
49
+			-webkit-transform:scale(1.5);
50
+			        transform:scale(1.5);
51
+			}
52
+		footer {
53
+			margin-top:40px;
54
+			font-size:14px;
55
+			color:#999;
56
+			}
57
+
58
+		/* Generated by grunt-webfont */
59
+
60
+
61
+@font-face {
62
+	font-family:"ion";
63
+	src:url("ion.eot?94af7082ea096aefe3a7b6642834716e");
64
+	src:url("ion.eot?#iefix") format("embedded-opentype"),
65
+		url("ion.woff2?94af7082ea096aefe3a7b6642834716e") format("woff2"),
66
+		url("ion.woff?94af7082ea096aefe3a7b6642834716e") format("woff"),
67
+		url("ion.ttf?94af7082ea096aefe3a7b6642834716e") format("truetype"),
68
+		url("ion.svg?94af7082ea096aefe3a7b6642834716e#ion") format("svg");
69
+	font-weight:normal;
70
+	font-style:normal;
71
+}
72
+
73
+.ion-icon {
74
+	
75
+		font-family:"ion";
76
+	
77
+	display:inline-block;
78
+	vertical-align:middle;
79
+	line-height:1;
80
+	font-weight:normal;
81
+	font-style:normal;
82
+	speak:none;
83
+	text-decoration:inherit;
84
+	text-transform:none;
85
+	text-rendering:auto;
86
+	-webkit-font-smoothing:antialiased;
87
+	-moz-osx-font-smoothing:grayscale;
88
+}
89
+
90
+
91
+/* Icons */
92
+
93
+
94
+.ion-navicon-round:before {
95
+	content:"\f101";
96
+}
97
+
98
+
99
+.ion-search:before {
100
+	content:"\f102";
101
+}
102
+
103
+
104
+.ion-play:before {
105
+	content:"\f103";
106
+}
107
+
108
+
109
+.ion-link:before {
110
+	content:"\f104";
111
+}
112
+
113
+
114
+.ion-chevron-up:before {
115
+	content:"\f105";
116
+}
117
+
118
+
119
+.ion-chevron-left:before {
120
+	content:"\f106";
121
+}
122
+
123
+
124
+.ion-chevron-right:before {
125
+	content:"\f107";
126
+}
127
+
128
+
129
+.ion-arrow-down-a:before {
130
+	content:"\f108";
131
+}
132
+
133
+
134
+.ion-arrow-up-a:before {
135
+	content:"\f109";
136
+}
137
+
138
+
139
+.ion-arrow-swap:before {
140
+	content:"\f10a";
141
+}
142
+
143
+
144
+.ion-arrow-dropdown:before {
145
+	content:"\f10b";
146
+}
147
+
148
+
149
+.ion-globe:before {
150
+	content:"\f10c";
151
+}
152
+
153
+
154
+.ion-time:before {
155
+	content:"\f10d";
156
+}
157
+
158
+
159
+.ion-location:before {
160
+	content:"\f10e";
161
+}
162
+
163
+
164
+.ion-warning:before {
165
+	content:"\f10f";
166
+}
167
+
168
+
169
+.ion-error:before {
170
+	content:"\f110";
171
+}
172
+
173
+
174
+.ion-film-outline:before {
175
+	content:"\f111";
176
+}
177
+
178
+
179
+.ion-music-note:before {
180
+	content:"\f112";
181
+}
182
+
183
+
184
+.ion-more-vertical:before {
185
+	content:"\f113";
186
+}
187
+
188
+
189
+.ion-magnet:before {
190
+	content:"\f114";
191
+}
192
+
193
+		</style>
194
+	</head>
195
+	<body>
196
+		<h1>ion</h1>
197
+
198
+		<div class="icons" id="icons">
199
+			
200
+				<div class="icons__item" data-name="navicon-round"><i class="ion-icon ion-navicon-round"></i> ion-navicon-round</div>
201
+			
202
+				<div class="icons__item" data-name="search"><i class="ion-icon ion-search"></i> ion-search</div>
203
+			
204
+				<div class="icons__item" data-name="play"><i class="ion-icon ion-play"></i> ion-play</div>
205
+			
206
+				<div class="icons__item" data-name="link"><i class="ion-icon ion-link"></i> ion-link</div>
207
+			
208
+				<div class="icons__item" data-name="chevron-up"><i class="ion-icon ion-chevron-up"></i> ion-chevron-up</div>
209
+			
210
+				<div class="icons__item" data-name="chevron-left"><i class="ion-icon ion-chevron-left"></i> ion-chevron-left</div>
211
+			
212
+				<div class="icons__item" data-name="chevron-right"><i class="ion-icon ion-chevron-right"></i> ion-chevron-right</div>
213
+			
214
+				<div class="icons__item" data-name="arrow-down-a"><i class="ion-icon ion-arrow-down-a"></i> ion-arrow-down-a</div>
215
+			
216
+				<div class="icons__item" data-name="arrow-up-a"><i class="ion-icon ion-arrow-up-a"></i> ion-arrow-up-a</div>
217
+			
218
+				<div class="icons__item" data-name="arrow-swap"><i class="ion-icon ion-arrow-swap"></i> ion-arrow-swap</div>
219
+			
220
+				<div class="icons__item" data-name="arrow-dropdown"><i class="ion-icon ion-arrow-dropdown"></i> ion-arrow-dropdown</div>
221
+			
222
+				<div class="icons__item" data-name="globe"><i class="ion-icon ion-globe"></i> ion-globe</div>
223
+			
224
+				<div class="icons__item" data-name="time"><i class="ion-icon ion-time"></i> ion-time</div>
225
+			
226
+				<div class="icons__item" data-name="location"><i class="ion-icon ion-location"></i> ion-location</div>
227
+			
228
+				<div class="icons__item" data-name="warning"><i class="ion-icon ion-warning"></i> ion-warning</div>
229
+			
230
+				<div class="icons__item" data-name="error"><i class="ion-icon ion-error"></i> ion-error</div>
231
+			
232
+				<div class="icons__item" data-name="film-outline"><i class="ion-icon ion-film-outline"></i> ion-film-outline</div>
233
+			
234
+				<div class="icons__item" data-name="music-note"><i class="ion-icon ion-music-note"></i> ion-music-note</div>
235
+			
236
+				<div class="icons__item" data-name="more-vertical"><i class="ion-icon ion-more-vertical"></i> ion-more-vertical</div>
237
+			
238
+				<div class="icons__item" data-name="magnet"><i class="ion-icon ion-magnet"></i> ion-magnet</div>
239
+			
240
+		</div>
241
+
242
+		
243
+
244
+		<h1>Usage</h1>
245
+		<pre><code>&lt;i class=&quot;ion-icon ion-<span id="name">name</span>&quot;&gt;&lt;/i&gt;</code></pre>
246
+		
247
+
248
+		<footer>Generated by <a href="https://github.com/sapegin/grunt-webfont">grunt-webfont</a>.</footer>
249
+
250
+		<script>
251
+		(function() {
252
+			document.getElementById('icons').onclick = function(e) {
253
+				e = e || window.event;
254
+				var name = e.target.getAttribute('data-name') || e.target.parentNode.getAttribute('data-name');
255
+				document.getElementById('name').innerHTML = name;
256
+				
257
+			}
258
+		})();
259
+		</script>
260
+	</body>
261
+</html>

+ 97
- 0
searx/static/themes/simple/fonts/ion.svg Datei anzeigen

@@ -0,0 +1,97 @@
1
+<?xml version="1.0" standalone="no"?>
2
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
3
+<!--
4
+2017-5-26: Created.
5
+-->
6
+<svg xmlns="http://www.w3.org/2000/svg">
7
+<metadata>
8
+Created by FontForge 20120731 at Fri May 26 22:22:55 2017
9
+ By alexandre,,,
10
+
11
+</metadata>
12
+<defs>
13
+<font id="ion" horiz-adv-x="512" >
14
+  <font-face 
15
+    font-family="ion"
16
+    font-weight="500"
17
+    font-stretch="normal"
18
+    units-per-em="512"
19
+    panose-1="2 0 6 9 0 0 0 0 0 0"
20
+    ascent="448"
21
+    descent="-64"
22
+    bbox="31.9799 -31.9632 479.993 415.9"
23
+    underline-thickness="25.6"
24
+    underline-position="-51.2"
25
+    unicode-range="U+F101-F114"
26
+  />
27
+    <missing-glyph />
28
+    <glyph glyph-name="arrow-down-a" unicode="&#xf108;" 
29
+d="M256.5 -0.5l-192 192h112v192h160v-192h112z" />
30
+    <glyph glyph-name="arrow-dropdown" unicode="&#xf10b;" 
31
+d="M128 256h256l-128 -128z" />
32
+    <glyph glyph-name="arrow-swap" unicode="&#xf10a;" 
33
+d="M64 120c0 4.40039 3.59961 7.99999 8 7.99999h248v64l128 -96l-128 -96v64h-248c-4.40039 0 -8 3.59961 -8 8v48zM448 264c0 -4.40039 -3.59961 -8 -8 -8h-248v-64l-128 96l128 96v-64h248c4.40039 0 8 -3.59961 8 -8v-48z" />
34
+    <glyph glyph-name="arrow-up-a" unicode="&#xf109;" 
35
+d="M256.5 383.5l192 -192h-112v-192h-160v192h-112z" />
36
+    <glyph glyph-name="chevron-left" unicode="&#xf106;" 
37
+d="M213.7 192l167.2 -174.2c4.19922 -4.2998 4.09961 -11.3994 -0.200195 -15.7998l-29.9004 -30.5996c-4.2998 -4.40039 -11.2998 -4.5 -15.5 -0.200191l-204.2 212.7c-2.09961 2.19922 -3.09961 5.09961 -3 8.09961c-0.199219 2.90039 0.800781 5.90039 3 8.09961
38
+l204.2 212.601c4.2002 4.2998 11.2002 4.2002 15.5 -0.200195l29.9004 -30.5996c4.2998 -4.40039 4.39941 -11.5 0.200195 -15.8008l-167.2 -174.1v0v0z" />
39
+    <glyph glyph-name="chevron-right" unicode="&#xf107;" 
40
+d="M298.3 192v0v0l-167.2 174.1c-4.19922 4.30078 -4.09961 11.4004 0.200195 15.8008l29.9004 30.5996c4.2998 4.40039 11.2998 4.5 15.5 0.200195l204.2 -212.7c2.19922 -2.2002 3.19922 -5.2002 3 -8.09961c0.0996094 -3 -0.900391 -5.90039 -3 -8.10059l-204.2 -212.6
41
+c-4.2002 -4.29981 -11.2002 -4.2002 -15.5 0.200191l-29.9004 30.5996c-4.2998 4.40039 -4.39941 11.5 -0.200195 15.7998z" />
42
+    <glyph glyph-name="chevron-up" unicode="&#xf105;" 
43
+d="M256 234.3l-174.2 -167.2c-4.2998 -4.19922 -11.3994 -4.09961 -15.7998 0.200195l-30.5996 29.9004c-4.40039 4.2998 -4.5 11.2998 -0.200195 15.5l212.7 204.2c2.19922 2.09961 5.09961 3.09961 8.09961 3c2.90039 0.199219 5.90039 -0.800781 8.09961 -3l212.7 -204.2
44
+c4.2998 -4.2002 4.20016 -11.2002 -0.200226 -15.5l-30.5996 -29.9004c-4.40039 -4.2998 -11.5 -4.39941 -15.7998 -0.200195l-174.2 167.2v0v0z" />
45
+    <glyph glyph-name="error" unicode="&#xf110;" 
46
+d="M256 400c114.4 0 208 -93.6006 208 -208c0 -114.399 -93.5996 -208 -208 -208s-208 93.6006 -208 208c0 114.399 93.5996 208 208 208zM280 88v40h-48v-40h48zM280 176v128h-48v-128h48z" />
47
+    <glyph glyph-name="film-outline" unicode="&#xf111;" 
48
+d="M56 360h400v-336h-400v336zM128 40v48h-56v-48h56zM128 104v48h-56v-48h56zM128 168v48h-56v-48h56zM128 232v48h-56v-48h56zM128 296v48h-56v-48h56zM368 40v144h-224v-144h224zM368 200v144h-224v-144h224zM440 40v48h-56v-48h56zM440 104v48h-56v-48h56zM440 168v48
49
+h-56v-48h56zM440 232v48h-56v-48h56zM440 296v48h-56v-48h56z" />
50
+    <glyph glyph-name="globe" unicode="&#xf10c;" 
51
+d="M256 400c114.875 0 208 -93.125 208 -208c0 -114.875 -93.125 -208 -208 -208c-114.876 0 -208 93.125 -208 208c0 114.875 93.124 208 208 208zM234.451 15.001c6.04297 15.0449 19.9453 28.6484 7.27342 39.1172c-8.17285 6.75 -15.6123 13.6279 -23.1104 21.125
52
+c-2.47461 2.47363 -9.9082 19.7109 -8.35156 22.3916c5.10254 8.78613 5.76367 14.8613 8.12988 24.7236c2.94336 12.2627 -3.33398 15.4434 -13.3828 21.8389c-15.2256 9.68848 -28.9629 22.4844 -43.3223 33.4941c-7.11621 5.45508 -17.4355 10.0986 -20.0186 18.9521
53
+c-2.64062 9.05078 -3.97363 20.2598 -9.40039 28.0781c-13.9277 20.0752 -11.5791 34.9678 -9.93945 58.7627c0.449219 6.52637 -1.30371 15.6572 -2.01367 24.1748c-27.5654 -32.2354 -42.6016 -72.7891 -42.6016 -115.659c0 -47.6221 18.5439 -92.3926 52.2178 -126.067
54
+c28.541 -28.54 65.0557 -46.2061 104.52 -50.9316zM382.067 65.9326c23.0352 23.0381 38.9873 51.2695 46.7686 82.0527c-8.34668 -1.19141 -18.3838 2.22754 -18.3838 2.22754s-21.7363 23.707 -23.5244 44.5723c-1.85645 21.667 0.498047 38.3945 -2.89551 56.8105
55
+c-2.87988 15.624 -19.2803 31.5 -26.6729 46.3018c-6.92188 13.8555 -13.7334 27.7031 -20.2646 41.7451c2.25098 -0.848633 4.90039 -1.40234 6.96484 -2.62305c4.99902 0.636719 9.43066 1.22949 13.4629 1.59082c-22.5381 15.6758 -48.2725 25.8418 -75.5225 29.7998
56
+v-8.33887l3.55273 -9.27734l-13.7793 -12.9951l-8.6748 2.79492l-9.92383 10.2334l-9.94434 11.8008l-14.084 5.66016c-15.7227 -2.36133 -30.9336 -6.78711 -45.3096 -13.1523c0.360352 -2.30762 0.662109 -4.64453 0.662109 -7.13281
57
+c7.17383 2.98926 15.2764 5.04883 22.4502 8.03906c2.96289 1.23438 12.7529 -7.1748 15.6221 -8.96777c-4.0957 -4.70996 -20.5576 -15.4434 -21.3574 -21.3574c-0.317383 -2.33984 6.50586 -6.06348 6.45117 -9.69141
58
+c-0.0878906 -5.74609 -0.173828 -11.4912 -0.259766 -17.2373c3.24414 2.76172 20.0332 20.3672 21.9404 20.8594c12.7256 3.2832 34.3916 -17.7646 36.249 -25.1934c1.8584 -7.42871 -21.6514 -23.6826 -32.6113 -34.0469
59
+c-8.39941 -7.94434 -24.8086 -12.5137 -19.8037 -24.2285c1.62695 -3.80957 10.0498 -20.0156 5.21191 -24.0586c-5.92188 -4.94824 -14.7686 8.97656 -17.3418 12.0938c-8.1543 9.87695 -25.626 6.02539 -37.9082 6.47852c0 -17.4209 -0.757812 -31.1885 14.9219 -42.9971
60
+c15.1953 -11.4434 29.5977 -24.7061 47.0781 -32.3389c12.7637 -5.57129 35.7158 6.53613 47.0205 -1.41699c15.8672 -11.165 29.3066 -21.624 47.1611 -29.375c7.93359 -3.44531 32.418 -19.8828 25.3525 -30.7812c-4.96582 -7.66211 -9.87305 -14.8848 -13.5771 -23.2168
61
+c-3.70703 -8.34375 -12.5957 -18.876 -19.6924 -24.3525c-8.15918 -6.29199 -16.9551 -17.1455 -21.8955 -29.3623c34.8574 6.5957 66.9229 23.4482 92.5566 49.0811z" />
62
+    <glyph glyph-name="link" unicode="&#xf104;" 
63
+d="M256.5 240h-0.5v0h0.5zM368.5 288c44.2002 0 79.5 -35.2998 79.5 -79.5v-32c0 -44.2002 -35.2998 -80.5 -79.5 -80.5h-112c-32.7002 0 -61 19.7998 -73.5996 48c-4.40039 10 -6.90039 21 -6.90039 32.5v31.5h48v-31.5c0 -17.5996 14.9004 -32.5 32.5 -32.5h112
64
+c17.5996 0 31.5 14.9004 31.5 32.5v32c0 17.5996 -13.9004 31.5 -31.5 31.5h-0.5h-16.4004c-5.59961 31 -31.5996 48 -31.5996 48h48.5zM329.6 240c4.10059 -9.59961 6.40039 -20.2998 6.40039 -31.5v-32v-0.5h-48v0.5v32c0 17.5996 -13.9004 31.5 -31.5 31.5h-0.5h-111.5
65
+c-17.5996 0 -32.5 -13.9004 -32.5 -31.5v-32c0 -17.5996 14.9004 -32.5 32.5 -32.5h15.4004c6.2998 -31 32.0996 -48 32.0996 -48h-47.5c-44.2002 0 -80.5 36.2998 -80.5 80.5v32c0 44.2002 36.2998 79.5 80.5 79.5h112c33 0 61 -19.7002 73.0996 -48z" />
66
+    <glyph glyph-name="location" unicode="&#xf10e;" 
67
+d="M256 384c65.9004 0 119.3 -53.7002 119.3 -120c0 -114.6 -119.3 -264 -119.3 -264s-119.3 149.4 -119.3 264c0 66.2998 53.3994 120 119.3 120zM256 205.8c31.2002 0 56.4004 25.4004 56.4004 56.7002c0 31.4004 -25.2002 56.7998 -56.4004 56.7998
68
+c-31.0996 0 -56.4004 -25.5 -56.4004 -56.7998s25.2002 -56.7002 56.4004 -56.7002z" />
69
+    <glyph glyph-name="magnet" unicode="&#xf114;" 
70
+d="M270.208 177.19h0.0126953v87.8721c0.345703 4.8125 -3.85254 22.8994 -14.0674 35.1738c-10.4697 12.5312 -23.6543 22.3496 -51.3662 22.7588c-27.7246 -0.396484 -40.8955 -10.2275 -51.3789 -22.7588c-10.1895 -12.2744 -14.4131 -30.3486 -14.0674 -35.1738
71
+v-87.8848h-64v87.8848c0.371094 21.8369 7.83398 48.7422 27.8271 74.7773c19.6865 25.7666 55.2188 47.6035 101.645 47.207c46.3877 0.421875 81.9199 -21.415 101.619 -47.1943c19.9941 -26.0352 27.4434 -52.9277 27.8018 -74.7646v-87.8975h-64.0254zM334.233 99.3789
72
+h0.0253906l-64.0508 -0.0126953v65.0244h64.0254v-65.0117zM75.3408 99.3662v65.0244h64v-65.0244h-64z" />
73
+    <glyph glyph-name="more-vertical" unicode="&#xf113;" 
74
+d="M296 312c0 -22.002 -17.998 -40 -40 -40s-40 17.998 -40 40s17.998 40 40 40s40 -17.998 40 -40zM296 72c0 -22.002 -17.998 -40 -40 -40s-40 17.998 -40 40s17.998 40 40 40s40 -17.998 40 -40zM296 192c0 -22.002 -17.998 -40 -40 -40s-40 17.998 -40 40
75
+s17.998 40 40 40s40 -17.998 40 -40z" />
76
+    <glyph glyph-name="music-note" unicode="&#xf112;" 
77
+d="M426 415.9c12.0996 0 22 -9.5 22.0996 -21.2002v-302.8c0 -24.7002 -3 -42.9004 -12 -54.9004h-0.199219c-9.10059 -15 -25 -21 -43.2002 -21h-37.2002c-28.2998 0 -51.2002 19.9004 -51.2002 48s22.9004 48 51.2002 48h60.5v192l-208 -38v-232
78
+c0 -8.2998 -3.40039 -27 -13 -41.0996c-1 -1.80078 -2.09961 -3.40039 -3.40039 -5c-0.5 -0.600586 -0.899414 -1.5 -1.5 -2.10059c-0.0996094 -0.0996094 -0.299805 -0.0996103 -0.399414 -0.200196c-9.40039 -10.5996 -23 -17.5 -38.2998 -17.5h-36.2002
79
+c-28.2002 0 -51.2998 20 -51.2998 48s23.0996 48 51.0996 48v-0.0996094h61v286.5c1 14.5 13.5 27.9004 27.2998 31.5996l217.601 33.2002s2.89941 0.600586 5.09961 0.600586z" />
80
+    <glyph glyph-name="navicon-round" unicode="&#xf101;" 
81
+d="M417.4 224c16.8994 0 30.5996 -14.2998 30.5996 -32s-13.7002 -32 -30.5996 -32h-322.801c-16.8994 0 -30.5996 14.2998 -30.5996 32s13.7002 32 30.5996 32h322.801zM417.4 352c16.8994 0 30.5996 -14.2998 30.5996 -32s-13.7002 -32 -30.5996 -32h-322.801
82
+c-16.8994 0 -30.5996 14.2998 -30.5996 32s13.7002 32 30.5996 32h322.801zM417.4 96c16.8994 0 30.5996 -14.2998 30.5996 -32s-13.7002 -32 -30.5996 -32h-322.801c-16.8994 0 -30.5996 14.2998 -30.5996 32s13.7002 32 30.5996 32h322.801z" />
83
+    <glyph glyph-name="play" unicode="&#xf103;" 
84
+d="M405.2 215.1c6.59961 -5.59961 10.7998 -13.7998 10.7998 -23.0996s-4.2002 -17.5996 -10.7998 -23.0996l-278.101 -165.5c-3.69922 -2 -7.09962 -3.40039 -11.1992 -3.40039c-10.9004 0 -19.8008 9 -19.8008 20h-0.0996094v344h0.0996094c0 11 8.90039 20 19.8008 20
85
+c4 0 7.49999 -1.2002 10.8994 -3.2002z" />
86
+    <glyph glyph-name="search" unicode="&#xf102;" 
87
+d="M445 61.2998c4 -4 4 -10.3994 0 -14.5l-43.2998 -43.7998c-1.90039 -2 -4.60059 -3.09961 -7.2998 -3.09961c-2.7002 0 -5.40039 1.19922 -7.30078 3.09961l-84.3994 85.5996c-24.6006 -14.6992 -52.2002 -22.3994 -80.1006 -22.3994
88
+c-87.3994 0 -158.6 71.2998 -158.6 158.899c0 87.6006 71.2002 158.9 158.6 158.9c87.4004 0 158.601 -71.2998 158.601 -158.9c0 -27 -7.2002 -53.7998 -21 -77.8994zM222.6 322.1c-53.3994 0 -96.7998 -43.5 -96.7998 -97s43.4004 -97 96.7998 -97
89
+c53.4004 0 96.8008 43.5 96.8008 97s-43.4004 97 -96.8008 97z" />
90
+    <glyph glyph-name="time" unicode="&#xf10d;" 
91
+d="M256 405c117.149 0 213 -95.8506 213 -213c0 -117.149 -94.7891 -213 -213 -213s-213 95.8506 -213 213c0 117.149 94.7891 213 213 213zM256 21.5996c93.7178 0 170.4 76.6826 170.4 170.4s-76.6826 170.4 -170.4 170.4s-170.4 -76.6836 -170.4 -170.4
92
+s76.6826 -170.4 170.4 -170.4zM266.65 298.5v-111.824l95.8496 -56.4434l-15.9746 -26.625l-111.825 67.0928v127.8h31.9502z" />
93
+    <glyph glyph-name="warning" unicode="&#xf10f;" 
94
+d="M476.7 25.7998c2.7998 -4.89941 4.7998 -13 1.7998 -17.8994c-2.90039 -4.90039 -8.20016 -7.90039 -14 -7.90039h-417.1c-5.80078 0 -11.1006 3 -14 7.90039c-2.90039 4.89941 -0.900391 12.8994 1.89941 17.8994l206.601 349.5c2.7998 5 8.1992 8.7002 14.0996 8.7002
95
+c5.7998 0 11.2002 -3.7002 14.0996 -8.7002zM288 48v48h-64v-48h64zM288 128v144h-64v-144h64z" />
96
+  </font>
97
+</defs></svg>

BIN
searx/static/themes/simple/fonts/ion.ttf Datei anzeigen


BIN
searx/static/themes/simple/fonts/ion.woff Datei anzeigen


BIN
searx/static/themes/simple/fonts/ion.woff2 Datei anzeigen


+ 150
- 0
searx/static/themes/simple/gruntfile.js Datei anzeigen

@@ -0,0 +1,150 @@
1
+module.exports = function(grunt) {
2
+
3
+  const path = require('path');
4
+
5
+  grunt.initConfig({
6
+    pkg: grunt.file.readJSON('package.json'),
7
+    watch: {
8
+      scripts: {
9
+        files: ['<%= jshint.files %>', 'less/*.less'],
10
+        tasks: ['jshint', 'concat', 'uglify', 'webfont', 'less:development', 'less:production']
11
+      }
12
+    },
13
+    concat: {
14
+      options: {
15
+        separator: ';'
16
+      },
17
+      dist: {
18
+        src: ['js/searx_src/*.js'],
19
+        dest: 'js/searx.js'
20
+      }
21
+    },
22
+    uglify: {
23
+      options: {
24
+        banner: '/*! simple/searx.min.js | <%= grunt.template.today("dd-mm-yyyy") %> | https://github.com/asciimoo/searx */\n',
25
+        preserveComments: 'some',
26
+        sourceMap: true
27
+      },
28
+      dist: {
29
+        files: {
30
+          'js/searx.min.js': ['<%= concat.dist.dest %>']
31
+        }
32
+      }
33
+    },
34
+    jshint: {
35
+      files: ['js/searx_src/*.js'],
36
+      options: {
37
+        proto: true,
38
+        // options here to override JSHint defaults
39
+        globals: {
40
+          browser: true,
41
+          jQuery: false,
42
+          devel: true
43
+        }
44
+      }
45
+    },
46
+    less: {
47
+      development: {
48
+        options: {
49
+          paths: ["less"],
50
+          banner: '/*! searx | <%= grunt.template.today("dd-mm-yyyy") %> | https://github.com/asciimoo/searx */\n'
51
+        },
52
+        files: {
53
+          "css/searx.css": "less/style.less",
54
+          "css/searx-rtl.css": "less/style-rtl.less"
55
+        }
56
+      },
57
+      production: {
58
+        options: {
59
+          paths: ["less"],
60
+          plugins: [
61
+            new (require('less-plugin-clean-css'))({
62
+              advanced: true,
63
+              compatibility: 'ie8'
64
+            })
65
+          ],
66
+          banner: '/*! searx | <%= grunt.template.today("dd-mm-yyyy") %> | https://github.com/asciimoo/searx */\n'
67
+        },
68
+        files: {
69
+          "css/searx.min.css": "less/style.less",
70
+          "css/searx-rtl.min.css": "less/style-rtl.less"
71
+        }
72
+      },
73
+    },
74
+    webfont: {
75
+      icons: {
76
+        // src: 'node_modules/ionicons-npm/src/*.svg',
77
+        src: [
78
+          'node_modules/ionicons-npm/src/navicon-round.svg',
79
+          'node_modules/ionicons-npm/src/search.svg',
80
+          'node_modules/ionicons-npm/src/play.svg',
81
+          'node_modules/ionicons-npm/src/link.svg',
82
+          'node_modules/ionicons-npm/src/chevron-up.svg',
83
+          'node_modules/ionicons-npm/src/chevron-left.svg',
84
+          'node_modules/ionicons-npm/src/chevron-right.svg',
85
+          'node_modules/ionicons-npm/src/arrow-down-a.svg',
86
+          'node_modules/ionicons-npm/src/arrow-up-a.svg',
87
+          'node_modules/ionicons-npm/src/arrow-swap.svg',
88
+          'node_modules/ionicons-npm/src/telephone.svg',
89
+          'node_modules/ionicons-npm/src/android-arrow-dropdown.svg',
90
+          'node_modules/ionicons-npm/src/android-globe.svg',
91
+          'node_modules/ionicons-npm/src/android-time.svg',
92
+          'node_modules/ionicons-npm/src/location.svg',
93
+          'node_modules/ionicons-npm/src/alert-circled.svg',
94
+          'node_modules/ionicons-npm/src/android-alert.svg',
95
+          'node_modules/ionicons-npm/src/ios-film-outline.svg',
96
+          'node_modules/ionicons-npm/src/music-note.svg',
97
+          'node_modules/ionicons-npm/src/ion-close-round.svg',
98
+          'node_modules/ionicons-npm/src/android-more-vertical.svg',
99
+          'magnet.svg'
100
+        ],
101
+        dest: 'fonts',
102
+        destLess: 'less',
103
+        options: {
104
+          font: 'ion',
105
+          hashes : true,
106
+          syntax: 'bem',
107
+          styles : 'font,icon',
108
+          types : 'eot,woff2,woff,ttf,svg',
109
+          order : 'eot,woff2,woff,ttf,svg',
110
+          stylesheets : ['css', 'less'],
111
+          relativeFontPath : '../fonts/',
112
+          autoHint : false,
113
+          normalize : false,
114
+          // ligatures : true,
115
+          optimize : true,
116
+          // fontHeight : 400,
117
+          rename : function(name) {
118
+            basename = path.basename(name);
119
+            if (basename === 'android-alert.svg') {
120
+              return 'error.svg';
121
+            }
122
+            if (basename === 'alert-circled.svg') {
123
+              return 'warning.svg';
124
+            }
125
+            if (basename === 'ion-close-round.svg') {
126
+              return 'close.svg';
127
+            }
128
+            return basename.replace(/(ios|md|android)-/i, '');
129
+          },
130
+          templateOptions: {
131
+            baseClass: 'ion-icon',
132
+            classPrefix: 'ion-'
133
+          }
134
+        }
135
+      }
136
+    }
137
+  });
138
+
139
+  grunt.loadNpmTasks('grunt-contrib-watch');
140
+  grunt.loadNpmTasks('grunt-contrib-uglify');
141
+  grunt.loadNpmTasks('grunt-contrib-jshint');
142
+  grunt.loadNpmTasks('grunt-contrib-concat');
143
+  grunt.loadNpmTasks('grunt-contrib-less');
144
+  grunt.loadNpmTasks('grunt-contrib-cssmin');
145
+  grunt.loadNpmTasks('grunt-webfont');
146
+
147
+  grunt.registerTask('test', ['jshint']);
148
+
149
+  grunt.registerTask('default', ['jshint', 'concat', 'uglify', 'less:development', 'less:production']);
150
+};

BIN
searx/static/themes/simple/img/favicon.png Datei anzeigen


BIN
searx/static/themes/simple/img/loader.gif Datei anzeigen


BIN
searx/static/themes/simple/img/logo_searx_a.png Datei anzeigen


BIN
searx/static/themes/simple/img/searx.png Datei anzeigen


+ 203
- 0
searx/static/themes/simple/img/searx_logo.svg Datei anzeigen

@@ -0,0 +1,203 @@
1
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
3
+
4
+<svg
5
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
6
+   xmlns:cc="http://creativecommons.org/ns#"
7
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
8
+   xmlns:svg="http://www.w3.org/2000/svg"
9
+   xmlns="http://www.w3.org/2000/svg"
10
+   xmlns:xlink="http://www.w3.org/1999/xlink"
11
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
12
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
13
+   width="744.09448819"
14
+   height="1052.3622047"
15
+   id="svg2"
16
+   version="1.1"
17
+   inkscape:version="0.48.4 r9939"
18
+   sodipodi:docname="searx_logo.svg"
19
+   inkscape:export-filename="/home/a/magnif.png"
20
+   inkscape:export-xdpi="203.1774"
21
+   inkscape:export-ydpi="203.1774">
22
+  <defs
23
+     id="defs4">
24
+    <linearGradient
25
+       inkscape:collect="always"
26
+       id="linearGradient3857">
27
+      <stop
28
+         style="stop-color:#ffffff;stop-opacity:1;"
29
+         offset="0"
30
+         id="stop3859" />
31
+      <stop
32
+         style="stop-color:#ffffff;stop-opacity:0;"
33
+         offset="1"
34
+         id="stop3861" />
35
+    </linearGradient>
36
+    <linearGradient
37
+       id="linearGradient3790">
38
+      <stop
39
+         style="stop-color:#a9a9a9;stop-opacity:1;"
40
+         offset="0"
41
+         id="stop3792" />
42
+      <stop
43
+         style="stop-color:#000000;stop-opacity:1;"
44
+         offset="1"
45
+         id="stop3794" />
46
+    </linearGradient>
47
+    <radialGradient
48
+       inkscape:collect="always"
49
+       xlink:href="#linearGradient3790"
50
+       id="radialGradient3798"
51
+       cx="294.45947"
52
+       cy="208.37973"
53
+       fx="294.45947"
54
+       fy="208.37973"
55
+       r="107.58125"
56
+       gradientUnits="userSpaceOnUse" />
57
+    <linearGradient
58
+       inkscape:collect="always"
59
+       xlink:href="#linearGradient3857"
60
+       id="linearGradient3865"
61
+       x1="120.68947"
62
+       y1="239.61774"
63
+       x2="120.68947"
64
+       y2="602.17517"
65
+       gradientUnits="userSpaceOnUse" />
66
+    <linearGradient
67
+       inkscape:collect="always"
68
+       xlink:href="#linearGradient3790"
69
+       id="linearGradient3912"
70
+       x1="186.74416"
71
+       y1="354.42426"
72
+       x2="255.84358"
73
+       y2="254.35953"
74
+       gradientUnits="userSpaceOnUse"
75
+       gradientTransform="matrix(1.2227304,0,0,0.89945099,-289.31433,113.40259)" />
76
+    <filter
77
+       inkscape:collect="always"
78
+       id="filter4024"
79
+       x="-0.12996517"
80
+       width="1.2599303"
81
+       y="-0.14709377"
82
+       height="1.2941875">
83
+      <feGaussianBlur
84
+         inkscape:collect="always"
85
+         stdDeviation="6.4759344"
86
+         id="feGaussianBlur4026" />
87
+    </filter>
88
+    <filter
89
+       inkscape:collect="always"
90
+       id="filter3983"
91
+       x="-1.0608404"
92
+       width="3.1216809"
93
+       y="-0.31017202"
94
+       height="1.620344">
95
+      <feGaussianBlur
96
+         inkscape:collect="always"
97
+         stdDeviation="9.392858"
98
+         id="feGaussianBlur3985" />
99
+    </filter>
100
+  </defs>
101
+  <sodipodi:namedview
102
+     id="base"
103
+     pagecolor="#ffffff"
104
+     bordercolor="#666666"
105
+     borderopacity="1.0"
106
+     inkscape:pageopacity="0.0"
107
+     inkscape:pageshadow="2"
108
+     inkscape:zoom="1.979899"
109
+     inkscape:cx="30.708726"
110
+     inkscape:cy="948.08556"
111
+     inkscape:document-units="px"
112
+     inkscape:current-layer="layer1"
113
+     showgrid="false"
114
+     inkscape:window-width="1364"
115
+     inkscape:window-height="663"
116
+     inkscape:window-x="0"
117
+     inkscape:window-y="30"
118
+     inkscape:window-maximized="0"
119
+     showguides="true"
120
+     inkscape:guide-bbox="true" />
121
+  <metadata
122
+     id="metadata7">
123
+    <rdf:RDF>
124
+      <cc:Work
125
+         rdf:about="">
126
+        <dc:format>image/svg+xml</dc:format>
127
+        <dc:type
128
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
129
+        <dc:title />
130
+      </cc:Work>
131
+    </rdf:RDF>
132
+  </metadata>
133
+  <g
134
+     inkscape:label="Layer 1"
135
+     inkscape:groupmode="layer"
136
+     id="layer1">
137
+    <path
138
+       style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
139
+       d="m 70.523181,34.870671 c -7.11959,15.242893 -10.17798,31.779192 -8.22563,48.814566 5.01677,43.774133 41.675309,79.324503 91.536109,95.162893 -6.62576,-22.40752 -5.34093,-44.9362 2.6395,-65.84431 C 108.73618,98.821131 74.828141,70.195435 70.523181,34.870671 z"
140
+       id="path3814-0-7"
141
+       inkscape:connector-curvature="0" />
142
+    <path
143
+       style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
144
+       d="m 303.77876,36.21406 c 7.11959,15.242893 10.17798,31.779192 8.22563,48.814566 -5.01677,43.774134 -41.67531,79.324504 -91.53611,95.162894 6.62576,-22.40752 5.34093,-44.9362 -2.6395,-65.84431 47.73698,-14.18269 81.64502,-42.808386 85.94998,-78.13315 z"
145
+       id="path3814-0"
146
+       inkscape:connector-curvature="0" />
147
+    <path
148
+       transform="matrix(0.6556593,-0.75505688,0.75505688,0.6556593,0,0)"
149
+       style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
150
+       d="m -5.0905523,259.06055 18.4167573,0 c 6.220455,0 11.228257,16.68196 11.228257,37.40349 l 0,172.83701 c 0,20.72153 -5.007802,37.40349 -11.228257,37.40349 l -18.4167573,0 c -6.2204547,0 -11.2282577,-16.68196 -11.2282577,-37.40349 l 0,-172.83701 c 0,-20.72153 5.007803,-37.40349 11.2282577,-37.40349 z"
151
+       id="rect3804" />
152
+    <path
153
+       sodipodi:type="arc"
154
+       style="fill:url(#radialGradient3798);fill-opacity:1;fill-rule:nonzero;stroke:none"
155
+       id="path2987"
156
+       sodipodi:cx="294.45947"
157
+       sodipodi:cy="208.37973"
158
+       sodipodi:rx="107.58125"
159
+       sodipodi:ry="107.58125"
160
+       d="m 402.04073,208.37973 a 107.58125,107.58125 0 1 1 -215.16251,0 107.58125,107.58125 0 1 1 215.16251,0 z"
161
+       transform="translate(-107.07617,-60.609153)" />
162
+    <path
163
+       sodipodi:type="arc"
164
+       style="fill:url(#linearGradient3865);fill-opacity:1;fill-rule:nonzero;stroke:none"
165
+       id="path3757"
166
+       sodipodi:cx="131.82491"
167
+       sodipodi:cy="299.29346"
168
+       sodipodi:rx="101.52033"
169
+       sodipodi:ry="101.52033"
170
+       d="m 233.34524,299.29346 a 101.52033,101.52033 0 1 1 -203.040667,0 101.52033,101.52033 0 1 1 203.040667,0 z"
171
+       transform="matrix(0.76865672,0,0,0.76865672,85.80266,-82.535889)" />
172
+    <path
173
+       sodipodi:type="arc"
174
+       style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none"
175
+       id="path3800"
176
+       sodipodi:cx="183.34268"
177
+       sodipodi:cy="156.35687"
178
+       sodipodi:rx="27.274118"
179
+       sodipodi:ry="27.274118"
180
+       d="m 210.6168,156.35687 a 27.274118,27.274118 0 1 1 -54.54824,0 27.274118,27.274118 0 1 1 54.54824,0 z"
181
+       transform="translate(5,-7.1428572)" />
182
+    <path
183
+       sodipodi:type="arc"
184
+       style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
185
+       id="path3802"
186
+       sodipodi:cx="197.9899"
187
+       sodipodi:cy="203.32896"
188
+       sodipodi:rx="5.5558391"
189
+       sodipodi:ry="5.5558391"
190
+       d="m 203.54574,203.32896 a 5.5558391,5.5558391 0 1 1 -11.11168,0 5.5558391,5.5558391 0 1 1 11.11168,0 z"
191
+       transform="translate(1.4847712,-63.564549)" />
192
+    <rect
193
+       style="fill:#ffffff;fill-opacity:0.82211531000000004;fill-rule:nonzero;stroke:none;filter:url(#filter4024)"
194
+       id="rect3916"
195
+       width="2.2392972"
196
+       height="159.43797"
197
+       x="19.525793"
198
+       y="337.8396"
199
+       rx="2.8666623"
200
+       ry="9.0007057"
201
+       transform="matrix(0.74466525,-0.84318084,0.84318084,0.74466525,-35.543204,-26.349917)" />
202
+  </g>
203
+</svg>

+ 1534
- 0
searx/static/themes/simple/js/searx.js
Datei-Diff unterdrückt, da er zu groß ist
Datei anzeigen


+ 4
- 0
searx/static/themes/simple/js/searx.min.js
Datei-Diff unterdrückt, da er zu groß ist
Datei anzeigen


+ 1
- 0
searx/static/themes/simple/js/searx.min.js.map
Datei-Diff unterdrückt, da er zu groß ist
Datei anzeigen


+ 155
- 0
searx/static/themes/simple/js/searx_src/00_searx_toolkit.js Datei anzeigen

@@ -0,0 +1,155 @@
1
+/**
2
+* searx is free software: you can redistribute it and/or modify
3
+* it under the terms of the GNU Affero General Public License as published by
4
+* the Free Software Foundation, either version 3 of the License, or
5
+* (at your option) any later version.
6
+*
7
+* searx is distributed in the hope that it will be useful,
8
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
+* GNU Affero General Public License for more details.
11
+*
12
+* You should have received a copy of the GNU Affero General Public License
13
+* along with searx. If not, see < http://www.gnu.org/licenses/ >.
14
+*
15
+* (C) 2017 by Alexandre Flament, <alex@al-f.net>
16
+*
17
+*/
18
+(function(w, d, searx) {
19
+
20
+  'use strict';
21
+
22
+  // not invented here tookit with bugs fixed elsewhere
23
+  // purposes : be just good enough and as small as possible
24
+
25
+  // from https://plainjs.com/javascript/events/live-binding-event-handlers-14/
26
+  if (w.Element) {
27
+    (function(ElementPrototype) {
28
+      ElementPrototype.matches = ElementPrototype.matches ||
29
+      ElementPrototype.matchesSelector ||
30
+      ElementPrototype.webkitMatchesSelector ||
31
+      ElementPrototype.msMatchesSelector ||
32
+      function(selector) {
33
+        var node = this, nodes = (node.parentNode || node.document).querySelectorAll(selector), i = -1;
34
+        while (nodes[++i] && nodes[i] != node);
35
+        return !!nodes[i];
36
+      };
37
+    })(Element.prototype);
38
+  }
39
+
40
+  function callbackSafe(callback, el, e) {
41
+    try {
42
+      callback.call(el, e);
43
+    } catch (exception) {
44
+      console.log(exception);
45
+    }
46
+  }
47
+
48
+  searx = searx || {};
49
+
50
+  searx.on = function(obj, eventType, callback, useCapture) {
51
+    useCapture = useCapture || false;
52
+    if (typeof obj !== 'string') {
53
+      // obj HTMLElement, HTMLDocument
54
+      obj.addEventListener(eventType, callback, useCapture);
55
+    } else {
56
+      // obj is a selector
57
+      d.addEventListener(eventType, function(e) {
58
+        var el = e.target || e.srcElement, found = false;
59
+        while (el && el.matches && el !== d && !(found = el.matches(obj))) el = el.parentElement;
60
+        if (found) callbackSafe(callback, el, e);
61
+      }, useCapture);
62
+    }
63
+  };
64
+
65
+  searx.ready = function(callback) {
66
+    if (document.readyState != 'loading') {
67
+      callback.call(w);
68
+    } else {
69
+      w.addEventListener('DOMContentLoaded', callback.bind(w));
70
+    }
71
+  };
72
+
73
+  searx.http = function(method, url, callback) {
74
+    var req = new XMLHttpRequest(),
75
+    resolve = function() {},
76
+    reject = function() {},
77
+    promise = {
78
+      then: function(callback) { resolve = callback; return promise; },
79
+      catch: function(callback) { reject = callback; return promise; }
80
+    };
81
+
82
+    try {
83
+      req.open(method, url, true);
84
+
85
+      // On load
86
+      req.onload = function() {
87
+        if (req.status == 200) {
88
+          resolve(req.response, req.responseType);
89
+        } else {
90
+          reject(Error(req.statusText));
91
+        }
92
+      };
93
+
94
+      // Handle network errors
95
+      req.onerror = function() {
96
+        reject(Error("Network Error"));
97
+      };
98
+
99
+      req.onabort = function() {
100
+        reject(Error("Transaction is aborted"));
101
+      };
102
+
103
+      // Make the request
104
+      req.send();
105
+    } catch (ex) {
106
+      reject(ex);
107
+    }
108
+
109
+    return promise;
110
+  };
111
+
112
+  searx.loadStyle = function(src) {
113
+    var path = searx.staticPath + src,
114
+    id = "style_" + src.replace('.', '_'),
115
+    s = d.getElementById(id);
116
+    if (s === null) {
117
+      s = d.createElement('link');
118
+      s.setAttribute('id', id);
119
+      s.setAttribute('rel', 'stylesheet');
120
+      s.setAttribute('type', 'text/css');
121
+      s.setAttribute('href', path);
122
+      d.body.appendChild(s);
123
+    }
124
+  };
125
+
126
+  searx.loadScript = function(src, callback) {
127
+    var path = searx.staticPath + src,
128
+    id = "script_" + src.replace('.', '_'),
129
+    s = d.getElementById(id);
130
+    if (s === null) {
131
+      s = d.createElement('script');
132
+      s.setAttribute('id', id);
133
+      s.setAttribute('src', path);
134
+      s.onload = callback;
135
+      s.onerror = function() {
136
+        s.setAttribute('error', '1');
137
+      };
138
+      d.body.appendChild(s);
139
+    } else if (!s.hasAttribute('error')) {
140
+      try {
141
+        callback.apply(s, []);
142
+      } catch (exception) {
143
+        console.log(exception);
144
+      }
145
+    } else {
146
+      console.log("callback not executed : script '" + path + "' not loaded.");
147
+    }
148
+  };
149
+
150
+  searx.on('.close', 'click', function(e) {
151
+    var el = e.target || e.srcElement;
152
+    this.parentNode.style.display="None";
153
+  });
154
+  return searx;
155
+})(window, document, window.searx);

+ 536
- 0
searx/static/themes/simple/js/searx_src/autocomplete.js Datei anzeigen

@@ -0,0 +1,536 @@
1
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.AutoComplete = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
2
+/*
3
+ * @license MIT
4
+ *
5
+ * Autocomplete.js v2.6.3
6
+ * Developed by Baptiste Donaux
7
+ * http://autocomplete-js.com
8
+ *
9
+ * (c) 2017, Baptiste Donaux
10
+ */
11
+"use strict";
12
+var ConditionOperator;
13
+(function (ConditionOperator) {
14
+    ConditionOperator[ConditionOperator["AND"] = 0] = "AND";
15
+    ConditionOperator[ConditionOperator["OR"] = 1] = "OR";
16
+})(ConditionOperator || (ConditionOperator = {}));
17
+var EventType;
18
+(function (EventType) {
19
+    EventType[EventType["KEYDOWN"] = 0] = "KEYDOWN";
20
+    EventType[EventType["KEYUP"] = 1] = "KEYUP";
21
+})(EventType || (EventType = {}));
22
+/**
23
+ * Core
24
+ *
25
+ * @class
26
+ * @author Baptiste Donaux <baptiste.donaux@gmail.com> @baptistedonaux
27
+ */
28
+var AutoComplete = (function () {
29
+    // Constructor
30
+    function AutoComplete(params, selector) {
31
+        if (params === void 0) { params = {}; }
32
+        if (selector === void 0) { selector = "[data-autocomplete]"; }
33
+        if (Array.isArray(selector)) {
34
+            selector.forEach(function (s) {
35
+                new AutoComplete(params, s);
36
+            });
37
+        }
38
+        else if (typeof selector == "string") {
39
+            var elements = document.querySelectorAll(selector);
40
+            Array.prototype.forEach.call(elements, function (input) {
41
+                new AutoComplete(params, input);
42
+            });
43
+        }
44
+        else {
45
+            var specificParams = AutoComplete.merge(AutoComplete.defaults, params, {
46
+                DOMResults: document.createElement("div")
47
+            });
48
+            AutoComplete.prototype.create(specificParams, selector);
49
+            return specificParams;
50
+        }
51
+    }
52
+    AutoComplete.prototype.create = function (params, element) {
53
+        params.Input = element;
54
+        if (params.Input.nodeName.match(/^INPUT$/i) && (params.Input.hasAttribute("type") === false || params.Input.getAttribute("type").match(/^TEXT|SEARCH$/i))) {
55
+            params.Input.setAttribute("autocomplete", "off");
56
+            params._Position(params);
57
+            params.Input.parentNode.appendChild(params.DOMResults);
58
+            params.$Listeners = {
59
+                blur: params._Blur.bind(params),
60
+                destroy: AutoComplete.prototype.destroy.bind(null, params),
61
+                focus: params._Focus.bind(params),
62
+                keyup: AutoComplete.prototype.event.bind(null, params, EventType.KEYUP),
63
+                keydown: AutoComplete.prototype.event.bind(null, params, EventType.KEYDOWN),
64
+                position: params._Position.bind(params)
65
+            };
66
+            for (var event in params.$Listeners) {
67
+                params.Input.addEventListener(event, params.$Listeners[event]);
68
+            }
69
+        }
70
+    };
71
+    AutoComplete.prototype.getEventsByType = function (params, type) {
72
+        var mappings = {};
73
+        for (var key in params.KeyboardMappings) {
74
+            var event = EventType.KEYUP;
75
+            if (params.KeyboardMappings[key].Event !== undefined) {
76
+                event = params.KeyboardMappings[key].Event;
77
+            }
78
+            if (event == type) {
79
+                mappings[key] = params.KeyboardMappings[key];
80
+            }
81
+        }
82
+        return mappings;
83
+    };
84
+    AutoComplete.prototype.event = function (params, type, event) {
85
+        var eventIdentifier = function (condition) {
86
+            if ((match === true && mapping.Operator == ConditionOperator.AND) || (match === false && mapping.Operator == ConditionOperator.OR)) {
87
+                condition = AutoComplete.merge({
88
+                    Not: false
89
+                }, condition);
90
+                if (condition.hasOwnProperty("Is")) {
91
+                    if (condition.Is == event.keyCode) {
92
+                        match = !condition.Not;
93
+                    }
94
+                    else {
95
+                        match = condition.Not;
96
+                    }
97
+                }
98
+                else if (condition.hasOwnProperty("From") && condition.hasOwnProperty("To")) {
99
+                    if (event.keyCode >= condition.From && event.keyCode <= condition.To) {
100
+                        match = !condition.Not;
101
+                    }
102
+                    else {
103
+                        match = condition.Not;
104
+                    }
105
+                }
106
+            }
107
+        };
108
+        for (var name in AutoComplete.prototype.getEventsByType(params, type)) {
109
+            var mapping = AutoComplete.merge({
110
+                Operator: ConditionOperator.AND
111
+            }, params.KeyboardMappings[name]), match = ConditionOperator.AND == mapping.Operator;
112
+            mapping.Conditions.forEach(eventIdentifier);
113
+            if (match === true) {
114
+                mapping.Callback.call(params, event);
115
+            }
116
+        }
117
+    };
118
+    AutoComplete.prototype.makeRequest = function (params, callback) {
119
+        var propertyHttpHeaders = Object.getOwnPropertyNames(params.HttpHeaders), request = new XMLHttpRequest(), method = params._HttpMethod(), url = params._Url(), queryParams = params._Pre(), queryParamsStringify = encodeURIComponent(params._QueryArg()) + "=" + encodeURIComponent(queryParams);
120
+        if (method.match(/^GET$/i)) {
121
+            if (url.indexOf("?") !== -1) {
122
+                url += "&" + queryParamsStringify;
123
+            }
124
+            else {
125
+                url += "?" + queryParamsStringify;
126
+            }
127
+        }
128
+        request.open(method, url, true);
129
+        for (var i = propertyHttpHeaders.length - 1; i >= 0; i--) {
130
+            request.setRequestHeader(propertyHttpHeaders[i], params.HttpHeaders[propertyHttpHeaders[i]]);
131
+        }
132
+        request.onreadystatechange = function () {
133
+            if (request.readyState == 4 && request.status == 200) {
134
+                params.$Cache[queryParams] = request.response;
135
+                callback(request.response);
136
+            }
137
+        };
138
+        return request;
139
+    };
140
+    AutoComplete.prototype.ajax = function (params, request, timeout) {
141
+        if (timeout === void 0) { timeout = true; }
142
+        if (params.$AjaxTimer) {
143
+            window.clearTimeout(params.$AjaxTimer);
144
+        }
145
+        if (timeout === true) {
146
+            params.$AjaxTimer = window.setTimeout(AutoComplete.prototype.ajax.bind(null, params, request, false), params.Delay);
147
+        }
148
+        else {
149
+            if (params.Request) {
150
+                params.Request.abort();
151
+            }
152
+            params.Request = request;
153
+            params.Request.send(params._QueryArg() + "=" + params._Pre());
154
+        }
155
+    };
156
+    AutoComplete.prototype.cache = function (params, callback) {
157
+        var response = params._Cache(params._Pre());
158
+        if (response === undefined) {
159
+            var request = AutoComplete.prototype.makeRequest(params, callback);
160
+            AutoComplete.prototype.ajax(params, request);
161
+        }
162
+        else {
163
+            callback(response);
164
+        }
165
+    };
166
+    AutoComplete.prototype.destroy = function (params) {
167
+        for (var event in params.$Listeners) {
168
+            params.Input.removeEventListener(event, params.$Listeners[event]);
169
+        }
170
+        params.DOMResults.parentNode.removeChild(params.DOMResults);
171
+    };
172
+    return AutoComplete;
173
+}());
174
+AutoComplete.merge = function () {
175
+    var merge = {}, tmp;
176
+    for (var i = 0; i < arguments.length; i++) {
177
+        for (tmp in arguments[i]) {
178
+            merge[tmp] = arguments[i][tmp];
179
+        }
180
+    }
181
+    return merge;
182
+};
183
+AutoComplete.defaults = {
184
+    Delay: 150,
185
+    EmptyMessage: "No result here",
186
+    Highlight: {
187
+        getRegex: function (value) {
188
+            return new RegExp(value, "ig");
189
+        },
190
+        transform: function (value) {
191
+            return "<strong>" + value + "</strong>";
192
+        }
193
+    },
194
+    HttpHeaders: {
195
+        "Content-type": "application/x-www-form-urlencoded"
196
+    },
197
+    Limit: 0,
198
+    MinChars: 0,
199
+    HttpMethod: "GET",
200
+    QueryArg: "q",
201
+    Url: null,
202
+    KeyboardMappings: {
203
+        "Enter": {
204
+            Conditions: [{
205
+                    Is: 13,
206
+                    Not: false
207
+                }],
208
+            Callback: function (event) {
209
+                if (this.DOMResults.getAttribute("class").indexOf("open") != -1) {
210
+                    var liActive = this.DOMResults.querySelector("li.active");
211
+                    if (liActive !== null) {
212
+                        event.preventDefault();
213
+                        this._Select(liActive);
214
+                        this.DOMResults.setAttribute("class", "autocomplete");
215
+                    }
216
+                }
217
+            },
218
+            Operator: ConditionOperator.AND,
219
+            Event: EventType.KEYDOWN
220
+        },
221
+        "KeyUpAndDown_down": {
222
+            Conditions: [{
223
+                    Is: 38,
224
+                    Not: false
225
+                },
226
+                {
227
+                    Is: 40,
228
+                    Not: false
229
+                }],
230
+            Callback: function (event) {
231
+                event.preventDefault();
232
+            },
233
+            Operator: ConditionOperator.OR,
234
+            Event: EventType.KEYDOWN
235
+        },
236
+        "KeyUpAndDown_up": {
237
+            Conditions: [{
238
+                    Is: 38,
239
+                    Not: false
240
+                },
241
+                {
242
+                    Is: 40,
243
+                    Not: false
244
+                }],
245
+            Callback: function (event) {
246
+                event.preventDefault();
247
+                var first = this.DOMResults.querySelector("li:first-child:not(.locked)"), last = this.DOMResults.querySelector("li:last-child:not(.locked)"), active = this.DOMResults.querySelector("li.active");
248
+                if (active) {
249
+                    var currentIndex = Array.prototype.indexOf.call(active.parentNode.children, active), position = currentIndex + (event.keyCode - 39), lisCount = this.DOMResults.getElementsByTagName("li").length;
250
+                    if (position < 0) {
251
+                        position = lisCount - 1;
252
+                    }
253
+                    else if (position >= lisCount) {
254
+                        position = 0;
255
+                    }
256
+                    active.classList.remove("active");
257
+                    active.parentElement.children.item(position).classList.add("active");
258
+                }
259
+                else if (last && event.keyCode == 38) {
260
+                    last.classList.add("active");
261
+                }
262
+                else if (first) {
263
+                    first.classList.add("active");
264
+                }
265
+            },
266
+            Operator: ConditionOperator.OR,
267
+            Event: EventType.KEYUP
268
+        },
269
+        "AlphaNum": {
270
+            Conditions: [{
271
+                    Is: 13,
272
+                    Not: true
273
+                }, {
274
+                    From: 35,
275
+                    To: 40,
276
+                    Not: true
277
+                }],
278
+            Callback: function () {
279
+                var oldValue = this.Input.getAttribute("data-autocomplete-old-value"), currentValue = this._Pre();
280
+                if (currentValue !== "" && currentValue.length >= this._MinChars()) {
281
+                    if (!oldValue || currentValue != oldValue) {
282
+                        this.DOMResults.setAttribute("class", "autocomplete open");
283
+                    }
284
+                    AutoComplete.prototype.cache(this, function (response) {
285
+                        this._Render(this._Post(response));
286
+                        this._Open();
287
+                    }.bind(this));
288
+                }
289
+            },
290
+            Operator: ConditionOperator.AND,
291
+            Event: EventType.KEYUP
292
+        }
293
+    },
294
+    DOMResults: null,
295
+    Request: null,
296
+    Input: null,
297
+    /**
298
+     * Return the message when no result returns
299
+     */
300
+    _EmptyMessage: function () {
301
+        var emptyMessage = "";
302
+        if (this.Input.hasAttribute("data-autocomplete-empty-message")) {
303
+            emptyMessage = this.Input.getAttribute("data-autocomplete-empty-message");
304
+        }
305
+        else if (this.EmptyMessage !== false) {
306
+            emptyMessage = this.EmptyMessage;
307
+        }
308
+        else {
309
+            emptyMessage = "";
310
+        }
311
+        return emptyMessage;
312
+    },
313
+    /**
314
+     * Returns the maximum number of results
315
+     */
316
+    _Limit: function () {
317
+        var limit = this.Input.getAttribute("data-autocomplete-limit");
318
+        if (isNaN(limit) || limit === null) {
319
+            return this.Limit;
320
+        }
321
+        return parseInt(limit, 10);
322
+    },
323
+    /**
324
+     * Returns the minimum number of characters entered before firing ajax
325
+     */
326
+    _MinChars: function () {
327
+        var minchars = this.Input.getAttribute("data-autocomplete-minchars");
328
+        if (isNaN(minchars) || minchars === null) {
329
+            return this.MinChars;
330
+        }
331
+        return parseInt(minchars, 10);
332
+    },
333
+    /**
334
+     * Apply transformation on labels response
335
+     */
336
+    _Highlight: function (label) {
337
+        return label.replace(this.Highlight.getRegex(this._Pre()), this.Highlight.transform);
338
+    },
339
+    /**
340
+     * Returns the HHTP method to use
341
+     */
342
+    _HttpMethod: function () {
343
+        if (this.Input.hasAttribute("data-autocomplete-method")) {
344
+            return this.Input.getAttribute("data-autocomplete-method");
345
+        }
346
+        return this.HttpMethod;
347
+    },
348
+    /**
349
+     * Returns the query param to use
350
+     */
351
+    _QueryArg: function () {
352
+        if (this.Input.hasAttribute("data-autocomplete-param-name")) {
353
+            return this.Input.getAttribute("data-autocomplete-param-name");
354
+        }
355
+        return this.QueryArg;
356
+    },
357
+    /**
358
+     * Returns the URL to use for AJAX request
359
+     */
360
+    _Url: function () {
361
+        if (this.Input.hasAttribute("data-autocomplete")) {
362
+            return this.Input.getAttribute("data-autocomplete");
363
+        }
364
+        return this.Url;
365
+    },
366
+    /**
367
+     * Manage the close
368
+     */
369
+    _Blur: function (now) {
370
+        if (now === true) {
371
+            this.DOMResults.setAttribute("class", "autocomplete");
372
+            this.Input.setAttribute("data-autocomplete-old-value", this.Input.value);
373
+        }
374
+        else {
375
+            var params = this;
376
+            setTimeout(function () {
377
+                params._Blur(true);
378
+            }, 150);
379
+        }
380
+    },
381
+    /**
382
+     * Manage the cache
383
+     */
384
+    _Cache: function (value) {
385
+        return this.$Cache[value];
386
+    },
387
+    /**
388
+     * Manage the open
389
+     */
390
+    _Focus: function () {
391
+        var oldValue = this.Input.getAttribute("data-autocomplete-old-value");
392
+        if ((!oldValue || this.Input.value != oldValue) && this._MinChars() <= this.Input.value.length) {
393
+            this.DOMResults.setAttribute("class", "autocomplete open");
394
+        }
395
+    },
396
+    /**
397
+     * Bind all results item if one result is opened
398
+     */
399
+    _Open: function () {
400
+        var params = this;
401
+        Array.prototype.forEach.call(this.DOMResults.getElementsByTagName("li"), function (li) {
402
+            if (li.getAttribute("class") != "locked") {
403
+		            li.onclick = function (event) {
404
+                    params._Select(li);
405
+                };
406
+                li.onmouseenter = function () {
407
+                    var active = params.DOMResults.querySelector("li.active");
408
+                    if (active !== li) {
409
+                        if (active !== null) {
410
+                            active.classList.remove("active");
411
+                        }
412
+                        li.classList.add("active");
413
+                    }
414
+                };
415
+            }
416
+        });
417
+    },
418
+    /**
419
+     * Position the results HTML element
420
+     */
421
+    _Position: function () {
422
+        this.DOMResults.setAttribute("class", "autocomplete");
423
+        this.DOMResults.setAttribute("style", "top:" + (this.Input.offsetTop + this.Input.offsetHeight) + "px;left:" + this.Input.offsetLeft + "px;width:" + this.Input.clientWidth + "px;");
424
+    },
425
+    /**
426
+     * Execute the render of results DOM element
427
+     */
428
+    _Render: function (response) {
429
+        var ul;
430
+        if (typeof response == "string") {
431
+            ul = this._RenderRaw(response);
432
+        }
433
+        else {
434
+            ul = this._RenderResponseItems(response);
435
+        }
436
+        if (this.DOMResults.hasChildNodes()) {
437
+            this.DOMResults.removeChild(this.DOMResults.childNodes[0]);
438
+        }
439
+        this.DOMResults.appendChild(ul);
440
+    },
441
+    /**
442
+     * ResponseItems[] rendering
443
+     */
444
+    _RenderResponseItems: function (response) {
445
+        var ul = document.createElement("ul"), li = document.createElement("li"), limit = this._Limit();
446
+        // Order
447
+        if (limit < 0) {
448
+            response = response.reverse();
449
+        }
450
+        else if (limit === 0) {
451
+            limit = response.length;
452
+        }
453
+        for (var item = 0; item < Math.min(Math.abs(limit), response.length); item++) {
454
+            li.innerHTML = response[item].Label;
455
+            li.setAttribute("data-autocomplete-value", response[item].Value);
456
+            ul.appendChild(li);
457
+            li = document.createElement("li");
458
+        }
459
+        return ul;
460
+    },
461
+    /**
462
+     * string response rendering (RAW HTML)
463
+     */
464
+    _RenderRaw: function (response) {
465
+        var ul = document.createElement("ul"), li = document.createElement("li");
466
+        if (response.length > 0) {
467
+            this.DOMResults.innerHTML = response;
468
+        }
469
+        else {
470
+            var emptyMessage = this._EmptyMessage();
471
+            if (emptyMessage !== "") {
472
+                li.innerHTML = emptyMessage;
473
+                li.setAttribute("class", "locked");
474
+                ul.appendChild(li);
475
+            }
476
+        }
477
+        return ul;
478
+    },
479
+    /**
480
+     * Deal with request response
481
+     */
482
+    _Post: function (response) {
483
+        try {
484
+            var returnResponse = [];
485
+            //JSON return
486
+            var json = JSON.parse(response);
487
+            if (Object.keys(json).length === 0) {
488
+                return "";
489
+            }
490
+            if (Array.isArray(json)) {
491
+                for (var i = 0; i < Object.keys(json).length; i++) {
492
+                    returnResponse[returnResponse.length] = { "Value": json[i], "Label": this._Highlight(json[i]) };
493
+                }
494
+            }
495
+            else {
496
+                for (var value in json) {
497
+                    returnResponse.push({
498
+                        "Value": value,
499
+                        "Label": this._Highlight(json[value])
500
+                    });
501
+                }
502
+            }
503
+            return returnResponse;
504
+        }
505
+        catch (event) {
506
+            //HTML return
507
+            return response;
508
+        }
509
+    },
510
+    /**
511
+     * Return the autocomplete value to send (before request)
512
+     */
513
+    _Pre: function () {
514
+        return this.Input.value;
515
+    },
516
+    /**
517
+     * Choice one result item
518
+     */
519
+    _Select: function (item) {
520
+	console.log('test test test');
521
+        if (item.hasAttribute("data-autocomplete-value")) {
522
+            this.Input.value = item.getAttribute("data-autocomplete-value");
523
+        }
524
+        else {
525
+            this.Input.value = item.innerHTML;
526
+        }
527
+        this.Input.setAttribute("data-autocomplete-old-value", this.Input.value);
528
+    },
529
+    $AjaxTimer: null,
530
+    $Cache: {},
531
+    $Listeners: {}
532
+};
533
+module.exports = AutoComplete;
534
+
535
+},{}]},{},[1])(1)
536
+});

+ 151
- 0
searx/static/themes/simple/js/searx_src/searx_imageresult.js Datei anzeigen

@@ -0,0 +1,151 @@
1
+/**
2
+*
3
+* Google Image Layout v0.0.1
4
+* Description, by Anh Trinh.
5
+* Heavily modified for searx
6
+* http://trinhtrunganh.com
7
+*
8
+* @license Free to use under the MIT License.
9
+*
10
+*/
11
+(function(w, d) {
12
+  'use strict';
13
+  
14
+  function ImageLayout(container_selector, results_selector, img_selector, maxHeight) {
15
+    this.container_selector = container_selector;
16
+    this.results_selector = results_selector;
17
+    this.img_selector = img_selector;
18
+    this.margin = 10;
19
+    this.maxHeight = maxHeight;
20
+    this._alignAllDone = true;
21
+  }
22
+
23
+  /**
24
+  * Get the height that make all images fit the container
25
+  *
26
+  * width = w1 + w2 + w3 + ... = r1*h + r2*h + r3*h + ...
27
+  *
28
+  * @param  {[type]} images the images to be calculated
29
+  * @param  {[type]} width  the container witdth
30
+  * @param  {[type]} margin the margin between each image
31
+  *
32
+  * @return {[type]}        the height
33
+  */
34
+  ImageLayout.prototype._getHeigth = function(images, width) {
35
+    var r = 0,
36
+    img;
37
+
38
+    width -= images.length * this.margin;
39
+    for (var i = 0; i < images.length; i++) {
40
+      img = images[i];
41
+      if ((img.naturalWidth > 0) && (img.naturalHeight > 0)) {
42
+        r += img.naturalWidth / img.naturalHeight;
43
+      } else {
44
+        // assume that not loaded images are square
45
+        r += 1;
46
+      }
47
+    }
48
+
49
+    return width / r; //have to round down because Firefox will automatically roundup value with number of decimals > 3
50
+  };
51
+
52
+  ImageLayout.prototype._setSize = function(images, height) {
53
+    var img, imgWidth, imagesLength = images.length;
54
+    for (var i = 0; i < imagesLength; i++) {
55
+      img = images[i];
56
+      if ((img.naturalWidth > 0) && (img.naturalHeight > 0)) {
57
+        imgWidth = height * img.naturalWidth / img.naturalHeight;
58
+      } else {
59
+        // not loaded image : make it square as _getHeigth said it
60
+        imgWidth = height;
61
+      }
62
+      img.style.width = imgWidth + 'px';
63
+      img.style.height = height + 'px';
64
+      img.style.marginLeft = '3px';
65
+      img.style.marginTop = '3px';
66
+      img.style.marginRight = this.margin - 7 + 'px'; // -4 is the negative margin of the inline element
67
+      img.style.marginBottom = this.margin - 7 + 'px';
68
+    }
69
+  };
70
+
71
+  ImageLayout.prototype._alignImgs = function(imgGroup) {
72
+    var slice, h,
73
+    containerWidth = d.querySelector(this.container_selector).clientWidth;
74
+
75
+    w: while (imgGroup.length > 0) {
76
+      for (var i = 1; i <= imgGroup.length; i++) {
77
+        slice = imgGroup.slice(0, i);
78
+        h = this._getHeigth(slice, containerWidth);
79
+        if (h < this.maxHeight) {
80
+          this._setSize(slice, h);
81
+          imgGroup = imgGroup.slice(i);
82
+          continue w;
83
+        }
84
+      }
85
+      this._setSize(slice, Math.min(this.maxHeight, h));
86
+      break;
87
+    }
88
+  };
89
+
90
+  ImageLayout.prototype.align = function(results_selector) {
91
+    var results_selectorNode = d.querySelectorAll(this.results_selector),
92
+    results_length = results_selectorNode.length,
93
+    previous = null,
94
+    current = null,
95
+    imgGroup = [];
96
+    for (var i = 0; i < results_length; i++) {
97
+      current = results_selectorNode[i];
98
+      if (current.previousElementSibling !== previous && imgGroup.length > 0) {
99
+        // the current image is not conected to previous one
100
+        // so the current image is the start of a new group of images.
101
+        // so call _alignImgs to align the current group
102
+        this._alignImgs(imgGroup);
103
+        // and start a new empty group of images
104
+        imgGroup = [];
105
+      }
106
+      // add the current image to the group (only the img tag)
107
+      imgGroup.push(current.querySelector(this.img_selector));
108
+      // update the previous variable
109
+      previous = current;
110
+    }
111
+    // align the remaining images
112
+    if (imgGroup.length > 0) {
113
+      this._alignImgs(imgGroup);
114
+    }
115
+  };
116
+
117
+  ImageLayout.prototype.watch = function() {
118
+    var i, img, imgGroup, imgNodeLength,
119
+    obj = this,
120
+    results_nodes = d.querySelectorAll(this.results_selector),
121
+    results_length = results_nodes.length;
122
+
123
+    function align(e) {
124
+      obj.align();
125
+    }
126
+
127
+    function throttleAlign(e) {
128
+      if (obj._alignAllDone) {
129
+        obj._alignAllDone = false;
130
+        setTimeout(function() {
131
+          obj.align();
132
+          obj._alignAllDone = true;
133
+        }, 100);
134
+      }
135
+    }
136
+
137
+    w.addEventListener('resize', throttleAlign);
138
+    w.addEventListener('pageshow', align);
139
+
140
+    for (i = 0; i < results_length; i++) {
141
+      img = results_nodes[i].querySelector(this.img_selector);
142
+      if (typeof img !== 'undefined') {
143
+        img.addEventListener('load', throttleAlign);
144
+        img.addEventListener('error', throttleAlign);
145
+      }
146
+    }
147
+  };
148
+
149
+  w.searx.ImageLayout = ImageLayout;
150
+
151
+})(window, document);

+ 360
- 0
searx/static/themes/simple/js/searx_src/searx_keyboard.js Datei anzeigen

@@ -0,0 +1,360 @@
1
+searx.ready(function() {
2
+
3
+  searx.on('.result', 'click', function() {
4
+    highlightResult(this)(true);
5
+  });
6
+
7
+  searx.on('.result a', 'focus', function(e) {
8
+    var el = e.target;
9
+    while (el !== undefined) {
10
+      if (el.classList.contains('result')) {
11
+        if (el.getAttribute("data-vim-selected") === null) {
12
+          highlightResult(el)(true);
13
+        }
14
+        break;
15
+      }
16
+      el = el.parentNode;
17
+    }
18
+  }, true);
19
+
20
+  var vimKeys = {
21
+    27: {
22
+      key: 'Escape',
23
+      fun: removeFocus,
24
+      des: 'remove focus from the focused input',
25
+      cat: 'Control'
26
+    },
27
+    73: {
28
+      key: 'i',
29
+      fun: searchInputFocus,
30
+      des: 'focus on the search input',
31
+      cat: 'Control'
32
+    },
33
+    66: {
34
+      key: 'b',
35
+      fun: scrollPage(-window.innerHeight),
36
+      des: 'scroll one page up',
37
+      cat: 'Navigation'
38
+    },
39
+    70: {
40
+      key: 'f',
41
+      fun: scrollPage(window.innerHeight),
42
+      des: 'scroll one page down',
43
+      cat: 'Navigation'
44
+    },
45
+    85: {
46
+      key: 'u',
47
+      fun: scrollPage(-window.innerHeight / 2),
48
+      des: 'scroll half a page up',
49
+      cat: 'Navigation'
50
+    },
51
+    68: {
52
+      key: 'd',
53
+      fun: scrollPage(window.innerHeight / 2),
54
+      des: 'scroll half a page down',
55
+      cat: 'Navigation'
56
+    },
57
+    71: {
58
+      key: 'g',
59
+      fun: scrollPageTo(-document.body.scrollHeight, 'top'),
60
+      des: 'scroll to the top of the page',
61
+      cat: 'Navigation'
62
+    },
63
+    86: {
64
+      key: 'v',
65
+      fun: scrollPageTo(document.body.scrollHeight, 'bottom'),
66
+      des: 'scroll to the bottom of the page',
67
+      cat: 'Navigation'
68
+    },
69
+    75: {
70
+      key: 'k',
71
+      fun: highlightResult('up'),
72
+      des: 'select previous search result',
73
+      cat: 'Results'
74
+    },
75
+    74: {
76
+      key: 'j',
77
+      fun: highlightResult('down'),
78
+      des: 'select next search result',
79
+      cat: 'Results'
80
+    },
81
+    80: {
82
+      key: 'p',
83
+      fun: pageButtonClick(0),
84
+      des: 'go to previous page',
85
+      cat: 'Results'
86
+    },
87
+    78: {
88
+      key: 'n',
89
+      fun: pageButtonClick(1),
90
+      des: 'go to next page',
91
+      cat: 'Results'
92
+    },
93
+    79: {
94
+      key: 'o',
95
+      fun: openResult(false),
96
+      des: 'open search result',
97
+      cat: 'Results'
98
+    },
99
+    84: {
100
+      key: 't',
101
+      fun: openResult(true),
102
+      des: 'open the result in a new tab',
103
+      cat: 'Results'
104
+    },
105
+    82: {
106
+      key: 'r',
107
+      fun: reloadPage,
108
+      des: 'reload page from the server',
109
+      cat: 'Control'
110
+    },
111
+    72: {
112
+      key: 'h',
113
+      fun: toggleHelp,
114
+      des: 'toggle help window',
115
+      cat: 'Other'
116
+    }
117
+  };
118
+
119
+  searx.on(document, "keyup", function(e) {
120
+    // check for modifiers so we don't break browser's hotkeys
121
+    if (vimKeys.hasOwnProperty(e.keyCode) && !e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey) {
122
+      var tagName = e.target.tagName.toLowerCase();
123
+      if (e.keyCode === 27) {
124
+        if (tagName === 'input' || tagName === 'select' || tagName === 'textarea') {
125
+          vimKeys[e.keyCode].fun();
126
+        }
127
+      } else {
128
+        if (e.target === document.body || tagName === 'a' || tagName === 'button') {
129
+          vimKeys[e.keyCode].fun();
130
+        }
131
+      }
132
+    }
133
+  });
134
+
135
+  function highlightResult(which) {
136
+    return function(noScroll) {
137
+      var current = document.querySelector('.result[data-vim-selected]'),
138
+      effectiveWhich = which;
139
+      if (current === null) {
140
+        // no selection : choose the first one
141
+        current = document.querySelector('.result');
142
+        if (current === null) {
143
+          // no first one : there are no results
144
+          return;
145
+        }
146
+        // replace up/down actions by selecting first one
147
+        if (which === "down" || which === "up") {
148
+          effectiveWhich = current;
149
+        }
150
+      }
151
+
152
+      var next, results = document.querySelectorAll('.result');
153
+
154
+      if (typeof effectiveWhich !== 'string') {
155
+        next = effectiveWhich;
156
+      } else {
157
+        switch (effectiveWhich) {
158
+          case 'visible':
159
+          var top = document.documentElement.scrollTop || document.body.scrollTop;
160
+          var bot = top + document.documentElement.clientHeight;
161
+
162
+          for (var i = 0; i < results.length; i++) {
163
+            next = results[i];
164
+            var etop = next.offsetTop;
165
+            var ebot = etop + next.clientHeight;
166
+
167
+            if ((ebot <= bot) && (etop > top)) {
168
+              break;
169
+            }
170
+          }
171
+          break;
172
+          case 'down':
173
+          next = current.nextElementSibling;
174
+          if (next === null) {
175
+            next = results[0];
176
+          }
177
+          break;
178
+          case 'up':
179
+          next = current.previousElementSibling;
180
+          if (next === null) {
181
+            next = results[results.length - 1];
182
+          }
183
+          break;
184
+          case 'bottom':
185
+          next = results[results.length - 1];
186
+          break;
187
+          case 'top':
188
+          /* falls through */
189
+          default:
190
+          next = results[0];
191
+        }
192
+      }
193
+
194
+      if (next) {
195
+        current.removeAttribute('data-vim-selected');
196
+        next.setAttribute('data-vim-selected', 'true');
197
+        var link = next.querySelector('h3 a') || next.querySelector('a');
198
+        if (link !== null) {
199
+          link.focus();
200
+        }
201
+        if (!noScroll) {
202
+          scrollPageToSelected();
203
+        }
204
+      }
205
+    };
206
+  }
207
+
208
+  function reloadPage() {
209
+    document.location.reload(true);
210
+  }
211
+
212
+  function removeFocus() {
213
+    if (document.activeElement) {
214
+      document.activeElement.blur();
215
+    }
216
+  }
217
+
218
+  function pageButtonClick(num) {
219
+    return function() {
220
+      var buttons = $('div#pagination button[type="submit"]');
221
+      if (buttons.length !== 2) {
222
+        console.log('page navigation with this theme is not supported');
223
+        return;
224
+      }
225
+      if (num >= 0 && num < buttons.length) {
226
+        buttons[num].click();
227
+      } else {
228
+        console.log('pageButtonClick(): invalid argument');
229
+      }
230
+    };
231
+  }
232
+
233
+  function scrollPageToSelected() {
234
+    var sel = document.querySelector('.result[data-vim-selected]');
235
+    if (sel === null) {
236
+      return;
237
+    }
238
+    var wtop = document.documentElement.scrollTop || document.body.scrollTop,
239
+    wheight = document.documentElement.clientHeight,
240
+    etop = sel.offsetTop,
241
+    ebot = etop + sel.clientHeight,
242
+    offset = 120;
243
+    // first element ?
244
+    if ((sel.previousElementSibling === null) && (ebot < wheight)) {
245
+      // set to the top of page if the first element
246
+      // is fully included in the viewport
247
+      window.scroll(window.scrollX, 0);
248
+      return;
249
+    }
250
+    if (wtop > (etop - offset)) {
251
+      window.scroll(window.scrollX, etop - offset);
252
+    } else {
253
+      var wbot = wtop + wheight;
254
+      if (wbot < (ebot + offset)) {
255
+        window.scroll(window.scrollX, ebot - wheight + offset);
256
+      }
257
+    }
258
+  }
259
+
260
+  function scrollPage(amount) {
261
+    return function() {
262
+      window.scrollBy(0, amount);
263
+      highlightResult('visible')();
264
+    };
265
+  }
266
+
267
+  function scrollPageTo(position, nav) {
268
+    return function() {
269
+      window.scrollTo(0, position);
270
+      highlightResult(nav)();
271
+    };
272
+  }
273
+
274
+  function searchInputFocus() {
275
+    window.scrollTo(0, 0);
276
+    document.querySelector('#q').focus();
277
+  }
278
+
279
+  function openResult(newTab) {
280
+    return function() {
281
+      var link = document.querySelector('.result[data-vim-selected] h3 a');
282
+      if (link !== null) {
283
+        var url = link.getAttribute('href');
284
+        if (newTab) {
285
+          window.open(url);
286
+        } else {
287
+          window.location.href = url;
288
+        }
289
+      }
290
+    };
291
+  }
292
+
293
+  function toggleHelp() {
294
+    var helpPanel = document.querySelector('#vim-hotkeys-help');
295
+    if (helpPanel.length) {
296
+      helpPanel.classList.toggle('hidden');
297
+      return;
298
+    }
299
+
300
+    var categories = {};
301
+
302
+    for (var k in vimKeys) {
303
+      var key = vimKeys[k];
304
+      categories[key.cat] = categories[key.cat] || [];
305
+      categories[key.cat].push(key);
306
+    }
307
+
308
+    var sorted = Object.keys(categories).sort(function(a, b) {
309
+      return categories[b].length - categories[a].length;
310
+    });
311
+
312
+    if (sorted.length === 0) {
313
+      return;
314
+    }
315
+
316
+    var html = '<div id="vim-hotkeys-help" class="well vim-hotkeys-help">';
317
+    html += '<div class="container-fluid">';
318
+
319
+    html += '<div class="row">';
320
+    html += '<div class="col-sm-12">';
321
+    html += '<h3>How to navigate searx with Vim-like hotkeys</h3>';
322
+    html += '</div>'; // col-sm-12
323
+    html += '</div>'; // row
324
+
325
+    for (var i = 0; i < sorted.length; i++) {
326
+      var cat = categories[sorted[i]];
327
+
328
+      var lastCategory = i === (sorted.length - 1);
329
+      var first = i % 2 === 0;
330
+
331
+      if (first) {
332
+        html += '<div class="row dflex">';
333
+      }
334
+      html += '<div class="col-sm-' + (first && lastCategory ? 12 : 6) + ' dflex">';
335
+
336
+      html += '<div class="panel panel-default iflex">';
337
+      html += '<div class="panel-heading">' + cat[0].cat + '</div>';
338
+      html += '<div class="panel-body">';
339
+      html += '<ul class="list-unstyled">';
340
+
341
+      for (var cj in cat) {
342
+        html += '<li><kbd>' + cat[cj].key + '</kbd> ' + cat[cj].des + '</li>';
343
+      }
344
+
345
+      html += '</ul>';
346
+      html += '</div>'; // panel-body
347
+      html += '</div>'; // panel
348
+      html += '</div>'; // col-sm-*
349
+
350
+      if (!first || lastCategory) {
351
+        html += '</div>'; // row
352
+      }
353
+    }
354
+
355
+    html += '</div>'; // container-fluid
356
+    html += '</div>'; // vim-hotkeys-help
357
+
358
+    $('body').append(html);
359
+  }
360
+});

+ 175
- 0
searx/static/themes/simple/js/searx_src/searx_mapresult.js Datei anzeigen

@@ -0,0 +1,175 @@
1
+/**
2
+* searx is free software: you can redistribute it and/or modify
3
+* it under the terms of the GNU Affero General Public License as published by
4
+* the Free Software Foundation, either version 3 of the License, or
5
+* (at your option) any later version.
6
+*
7
+* searx is distributed in the hope that it will be useful,
8
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
+* GNU Affero General Public License for more details.
11
+*
12
+* You should have received a copy of the GNU Affero General Public License
13
+* along with searx. If not, see < http://www.gnu.org/licenses/ >.
14
+*
15
+* (C) 2014 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>
16
+* (C) 2017 by Alexandre Flament, <alex@al-f.net>
17
+*/
18
+(function (w, d, searx) {
19
+  'use strict';
20
+
21
+  searx.ready(function () {
22
+    searx.on('.searx_overpass_request', 'click', function(event) {
23
+      // no more request
24
+      this.classList.remove("searx_overpass_request");
25
+
26
+      //
27
+      var overpass_url = "https://overpass-api.de/api/interpreter?data=";
28
+      var query_start = overpass_url + "[out:json][timeout:25];(";
29
+      var query_end = ");out meta;";
30
+
31
+      var osm_id = this.dataset.osmId;
32
+      var osm_type = this.dataset.osmType;
33
+      var result_table = d.querySelector("#" + this.dataset.resultTable);
34
+      var result_table_loadicon = d.querySelector("#" + this.dataset.resultTableLoadicon);
35
+
36
+      // tags which can be ignored
37
+      var osm_ignore_tags = [ "addr:city", "addr:country", "addr:housenumber", "addr:postcode", "addr:street" ];
38
+
39
+      if(osm_id && osm_type && result_table) {
40
+        var query = null;
41
+        switch(osm_type) {
42
+          case 'node':
43
+          query = query_start + "node(" + osm_id + ");" + query_end;
44
+          break;
45
+          case 'way':
46
+          query = query_start + "way(" + osm_id + ");" + query_end;
47
+          break;
48
+          case 'relation':
49
+          query = query_start + "relation(" + osm_id + ");" + query_end;
50
+          break;
51
+          default:
52
+          break;
53
+        }
54
+        if(query) {
55
+          // console.log(query);
56
+          searx.http( 'GET', query ).then(function(html, contentType) {
57
+            html = JSON.parse(html);
58
+            if(html && html.elements && html.elements[0]) {
59
+              var element = html.elements[0];
60
+              var newHtml = "";
61
+              for (var row in element.tags) {
62
+                if(element.tags.name === null || osm_ignore_tags.indexOf(row) == -1) {
63
+                  newHtml += "<tr><td>" + row + "</td><td>";
64
+                  switch(row) {
65
+                    case "phone":
66
+                    case "fax":
67
+                    newHtml += "<a href=\"tel:" + element.tags[row].replace(/ /g,'') + "\">" + element.tags[row] + "</a>";
68
+                    break;
69
+                    case "email":
70
+                    newHtml += "<a href=\"mailto:" + element.tags[row] + "\">" + element.tags[row] + "</a>";
71
+                    break;
72
+                    case "website":
73
+                    case "url":
74
+                    newHtml += "<a href=\"" + element.tags[row] + "\">" + element.tags[row] + "</a>";
75
+                    break;
76
+                    case "wikidata":
77
+                    newHtml += "<a href=\"https://www.wikidata.org/wiki/" + element.tags[row] + "\">" + element.tags[row] + "</a>";
78
+                    break;
79
+                    case "wikipedia":
80
+                    if(element.tags[row].indexOf(":") != -1) {
81
+                      newHtml += "<a href=\"https://" + element.tags[row].substring(0,element.tags[row].indexOf(":")) + ".wikipedia.org/wiki/" + element.tags[row].substring(element.tags[row].indexOf(":")+1) + "\">" + element.tags[row] + "</a>";
82
+                      break;
83
+                    }
84
+                    /* jshint ignore:start */
85
+                    default:
86
+                    /* jshint ignore:end */
87
+                    newHtml += element.tags[row];
88
+                    break;
89
+                  }
90
+                  newHtml += "</td></tr>";
91
+                }
92
+              }
93
+              result_table_loadicon.classList.add('invisible');
94
+              result_table.classList.remove('invisible');
95
+              result_table.querySelector("tbody").innerHTML = newHtml;
96
+            }
97
+          })
98
+          .catch(function() {
99
+            result_table_loadicon.innerHTML = result_table_loadicon.innerHTML + "<p class=\"text-muted\">could not load data!</p>";
100
+          });
101
+        }
102
+      }
103
+
104
+      // this event occour only once per element
105
+      event.preventDefault();
106
+    });
107
+
108
+    searx.on('.searx_init_map', 'click', function(event) {
109
+      // no more request
110
+      this.classList.remove("searx_init_map");
111
+
112
+      //
113
+      var leaflet_target = this.dataset.leafletTarget;
114
+      var map_lon = parseFloat(this.dataset.mapLon);
115
+      var map_lat = parseFloat(this.dataset.mapLat);
116
+      var map_zoom = parseFloat(this.dataset.mapZoom);
117
+      var map_boundingbox = JSON.parse(this.dataset.mapBoundingbox);
118
+      var map_geojson = JSON.parse(this.dataset.mapGeojson);
119
+
120
+      searx.loadStyle('leaflet/leaflet.css');
121
+      searx.loadScript('leaflet/leaflet.js', function() {
122
+        var map_bounds = null;
123
+        if(map_boundingbox) {
124
+          var southWest = L.latLng(map_boundingbox[0], map_boundingbox[2]);
125
+          var northEast = L.latLng(map_boundingbox[1], map_boundingbox[3]);
126
+          map_bounds = L.latLngBounds(southWest, northEast);
127
+        }
128
+
129
+        // init map
130
+        var map = L.map(leaflet_target);
131
+        // create the tile layer with correct attribution
132
+        var osmMapnikUrl='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
133
+        var osmMapnikAttrib='Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors';
134
+        var osmMapnik = new L.TileLayer(osmMapnikUrl, {minZoom: 1, maxZoom: 19, attribution: osmMapnikAttrib});
135
+        var osmWikimediaUrl='https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png';
136
+        var osmWikimediaAttrib = 'Wikimedia maps beta | Maps data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors';
137
+        var osmWikimedia = new L.TileLayer(osmWikimediaUrl, {minZoom: 1, maxZoom: 19, attribution: osmWikimediaAttrib});
138
+        // init map view
139
+        if(map_bounds) {
140
+          // TODO hack: https://github.com/Leaflet/Leaflet/issues/2021
141
+          // Still useful ?
142
+          setTimeout(function () {
143
+            map.fitBounds(map_bounds, {
144
+              maxZoom:17
145
+            });
146
+          }, 0);
147
+        } else if (map_lon && map_lat) {
148
+          if(map_zoom) {
149
+            map.setView(new L.latLng(map_lat, map_lon),map_zoom);
150
+          } else {
151
+            map.setView(new L.latLng(map_lat, map_lon),8);
152
+          }
153
+        }
154
+
155
+        map.addLayer(osmMapnik);
156
+
157
+        var baseLayers = {
158
+          "OSM Mapnik": osmMapnik/*,
159
+          "OSM Wikimedia": osmWikimedia*/
160
+        };
161
+
162
+        L.control.layers(baseLayers).addTo(map);
163
+
164
+        if(map_geojson) {
165
+          L.geoJson(map_geojson).addTo(map);
166
+        } /*else if(map_bounds) {
167
+          L.rectangle(map_bounds, {color: "#ff7800", weight: 3, fill:false}).addTo(map);
168
+        }*/
169
+      });
170
+
171
+      // this event occour only once per element
172
+      event.preventDefault();
173
+    });
174
+  });
175
+})(window, document, window.searx);

+ 63
- 0
searx/static/themes/simple/js/searx_src/searx_results.js Datei anzeigen

@@ -0,0 +1,63 @@
1
+/**
2
+* searx is free software: you can redistribute it and/or modify
3
+* it under the terms of the GNU Affero General Public License as published by
4
+* the Free Software Foundation, either version 3 of the License, or
5
+* (at your option) any later version.
6
+*
7
+* searx is distributed in the hope that it will be useful,
8
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
+* GNU Affero General Public License for more details.
11
+*
12
+* You should have received a copy of the GNU Affero General Public License
13
+* along with searx. If not, see < http://www.gnu.org/licenses/ >.
14
+*
15
+* (C) 2017 by Alexandre Flament, <alex@al-f.net>
16
+*/
17
+(function(w, d, searx) {
18
+  'use strict';
19
+
20
+  searx.ready(function() {
21
+    searx.image_thumbnail_layout = new searx.ImageLayout('#urls', '#urls .result-images', 'img.image_thumbnail', 200);
22
+    searx.image_thumbnail_layout.watch();
23
+
24
+    searx.on('.btn-collapse', 'click', function(event) {
25
+      var btnLabelCollapsed = this.getAttribute('data-btn-text-collapsed');
26
+      var btnLabelNotCollapsed = this.getAttribute('data-btn-text-not-collapsed');
27
+      var target = this.getAttribute('data-target');
28
+      var targetElement = d.querySelector(target);
29
+      var html = this.innerHTML;
30
+      if (this.classList.contains('collapsed')) {
31
+        html = html.replace(btnLabelCollapsed, btnLabelNotCollapsed);
32
+      } else {
33
+        html = html.replace(btnLabelNotCollapsed, btnLabelCollapsed);
34
+      }
35
+      this.innerHTML = html;
36
+      this.classList.toggle('collapsed');
37
+      targetElement.classList.toggle('invisible');
38
+    });
39
+
40
+    searx.on('.media-loader', 'click', function(event) {
41
+      var target = this.getAttribute('data-target');
42
+      var iframe_load = d.querySelector(target + ' > iframe');
43
+      var srctest = iframe_load.getAttribute('src');
44
+      if (srctest === null || srctest === undefined || srctest === false) {
45
+        iframe_load.setAttribute('src', iframe_load.getAttribute('data-src'));
46
+      }
47
+    });
48
+
49
+    w.addEventListener('scroll', function() {
50
+      var e = d.getElementById('backToTop'),
51
+      scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
52
+      if (e !== null) {
53
+        if (scrollTop >= 200) {
54
+          e.style.opacity = 1;
55
+        } else {
56
+          e.style.opacity = 0;
57
+        }
58
+      }
59
+    });
60
+
61
+  });
62
+
63
+})(window, document, window.searx);

+ 94
- 0
searx/static/themes/simple/js/searx_src/searx_search.js Datei anzeigen

@@ -0,0 +1,94 @@
1
+/**
2
+* searx is free software: you can redistribute it and/or modify
3
+* it under the terms of the GNU Affero General Public License as published by
4
+* the Free Software Foundation, either version 3 of the License, or
5
+* (at your option) any later version.
6
+*
7
+* searx is distributed in the hope that it will be useful,
8
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
+* GNU Affero General Public License for more details.
11
+*
12
+* You should have received a copy of the GNU Affero General Public License
13
+* along with searx. If not, see < http://www.gnu.org/licenses/ >.
14
+*
15
+* (C) 2017 by Alexandre Flament, <alex@al-f.net>
16
+*/
17
+(function(w, d, searx) {
18
+  'use strict';
19
+
20
+  var firstFocus = true, qinput_id = "q", qinput;
21
+
22
+  function placeCursorAtEnd(element) {
23
+    if (element.setSelectionRange) {
24
+      var len = element.value.length;
25
+      element.setSelectionRange(len, len);
26
+    }
27
+  }
28
+
29
+  function submitIfQuery() {
30
+    if (qinput.value.length  > 0) {
31
+      var search = document.getElementById('search');
32
+      setTimeout(search.submit.bind(search), 0);
33
+    }
34
+  }
35
+
36
+  searx.ready(function() {
37
+    qinput = d.getElementById(qinput_id);
38
+
39
+    function placeCursorAtEndOnce(e) {
40
+      if (firstFocus) {
41
+        placeCursorAtEnd(qinput);
42
+        firstFocus = false;
43
+      } else {
44
+        // e.preventDefault();
45
+      }
46
+    }
47
+
48
+    if (qinput !== null) {
49
+      // autocompleter
50
+      if (searx.autocompleter) {
51
+        searx.autocomplete = AutoComplete.call(w, {
52
+          Url: "./autocompleter",
53
+          EmptyMessage: searx.noItemFound,
54
+          HttpMethod: searx.method,
55
+          MinChars: 4,
56
+          Delay: 300,
57
+        }, "#" + qinput_id);
58
+
59
+        // hack, see : https://github.com/autocompletejs/autocomplete.js/issues/37
60
+        w.addEventListener('resize', function() {
61
+          var event = new CustomEvent("position");
62
+          qinput.dispatchEvent(event);
63
+        });
64
+      }
65
+
66
+      qinput.addEventListener('focus', placeCursorAtEndOnce, false);
67
+      qinput.focus();
68
+    }
69
+
70
+    // vanilla js version of search_on_category_select.js
71
+    if (qinput !== null && searx.search_on_category_select) {
72
+      d.querySelector('.help').className='invisible';
73
+
74
+      searx.on('#categories input', 'change', function(e) {
75
+        var i, categories = d.querySelectorAll('#categories input[type="checkbox"]');
76
+        for(i=0; i<categories.length; i++) {
77
+          if (categories[i] !== this && categories[i].checked) {
78
+            categories[i].click();
79
+          }
80
+        }
81
+        if (! this.checked) {
82
+          this.click();
83
+        }
84
+        submitIfQuery();
85
+        return false;
86
+      });
87
+
88
+      searx.on(d.getElementById('time_range'), 'change', submitIfQuery);
89
+      searx.on(d.getElementById('language'), 'change', submitIfQuery);
90
+    }
91
+
92
+  });
93
+
94
+})(window, document, window.searx);

BIN
searx/static/themes/simple/leaflet/images/layers-2x.png Datei anzeigen


BIN
searx/static/themes/simple/leaflet/images/layers.png Datei anzeigen


BIN
searx/static/themes/simple/leaflet/images/marker-icon-2x-green.png Datei anzeigen


BIN
searx/static/themes/simple/leaflet/images/marker-icon-2x-orange.png Datei anzeigen


BIN
searx/static/themes/simple/leaflet/images/marker-icon-2x-red.png Datei anzeigen


BIN
searx/static/themes/simple/leaflet/images/marker-icon-2x.png Datei anzeigen


BIN
searx/static/themes/simple/leaflet/images/marker-icon-green.png Datei anzeigen


BIN
searx/static/themes/simple/leaflet/images/marker-icon-orange.png Datei anzeigen


BIN
searx/static/themes/simple/leaflet/images/marker-icon-red.png Datei anzeigen


BIN
searx/static/themes/simple/leaflet/images/marker-icon.png Datei anzeigen


BIN
searx/static/themes/simple/leaflet/images/marker-shadow.png Datei anzeigen


+ 624
- 0
searx/static/themes/simple/leaflet/leaflet.css Datei anzeigen

@@ -0,0 +1,624 @@
1
+/* required styles */
2
+
3
+.leaflet-pane,
4
+.leaflet-tile,
5
+.leaflet-marker-icon,
6
+.leaflet-marker-shadow,
7
+.leaflet-tile-container,
8
+.leaflet-pane > svg,
9
+.leaflet-pane > canvas,
10
+.leaflet-zoom-box,
11
+.leaflet-image-layer,
12
+.leaflet-layer {
13
+	position: absolute;
14
+	left: 0;
15
+	top: 0;
16
+	}
17
+.leaflet-container {
18
+	overflow: hidden;
19
+	}
20
+.leaflet-tile,
21
+.leaflet-marker-icon,
22
+.leaflet-marker-shadow {
23
+	-webkit-user-select: none;
24
+	   -moz-user-select: none;
25
+	        user-select: none;
26
+	  -webkit-user-drag: none;
27
+	}
28
+/* Safari renders non-retina tile on retina better with this, but Chrome is worse */
29
+.leaflet-safari .leaflet-tile {
30
+	image-rendering: -webkit-optimize-contrast;
31
+	}
32
+/* hack that prevents hw layers "stretching" when loading new tiles */
33
+.leaflet-safari .leaflet-tile-container {
34
+	width: 1600px;
35
+	height: 1600px;
36
+	-webkit-transform-origin: 0 0;
37
+	}
38
+.leaflet-marker-icon,
39
+.leaflet-marker-shadow {
40
+	display: block;
41
+	}
42
+/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */
43
+/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */
44
+.leaflet-container .leaflet-overlay-pane svg,
45
+.leaflet-container .leaflet-marker-pane img,
46
+.leaflet-container .leaflet-shadow-pane img,
47
+.leaflet-container .leaflet-tile-pane img,
48
+.leaflet-container img.leaflet-image-layer {
49
+	max-width: none !important;
50
+	}
51
+
52
+.leaflet-container.leaflet-touch-zoom {
53
+	-ms-touch-action: pan-x pan-y;
54
+	touch-action: pan-x pan-y;
55
+	}
56
+.leaflet-container.leaflet-touch-drag {
57
+	-ms-touch-action: pinch-zoom;
58
+	}
59
+.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom {
60
+	-ms-touch-action: none;
61
+	touch-action: none;
62
+}
63
+.leaflet-tile {
64
+	filter: inherit;
65
+	visibility: hidden;
66
+	}
67
+.leaflet-tile-loaded {
68
+	visibility: inherit;
69
+	}
70
+.leaflet-zoom-box {
71
+	width: 0;
72
+	height: 0;
73
+	-moz-box-sizing: border-box;
74
+	     box-sizing: border-box;
75
+	z-index: 800;
76
+	}
77
+/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
78
+.leaflet-overlay-pane svg {
79
+	-moz-user-select: none;
80
+	}
81
+
82
+.leaflet-pane         { z-index: 400; }
83
+
84
+.leaflet-tile-pane    { z-index: 200; }
85
+.leaflet-overlay-pane { z-index: 400; }
86
+.leaflet-shadow-pane  { z-index: 500; }
87
+.leaflet-marker-pane  { z-index: 600; }
88
+.leaflet-tooltip-pane   { z-index: 650; }
89
+.leaflet-popup-pane   { z-index: 700; }
90
+
91
+.leaflet-map-pane canvas { z-index: 100; }
92
+.leaflet-map-pane svg    { z-index: 200; }
93
+
94
+.leaflet-vml-shape {
95
+	width: 1px;
96
+	height: 1px;
97
+	}
98
+.lvml {
99
+	behavior: url(#default#VML);
100
+	display: inline-block;
101
+	position: absolute;
102
+	}
103
+
104
+
105
+/* control positioning */
106
+
107
+.leaflet-control {
108
+	position: relative;
109
+	z-index: 800;
110
+	pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
111
+	pointer-events: auto;
112
+	}
113
+.leaflet-top,
114
+.leaflet-bottom {
115
+	position: absolute;
116
+	z-index: 1000;
117
+	pointer-events: none;
118
+	}
119
+.leaflet-top {
120
+	top: 0;
121
+	}
122
+.leaflet-right {
123
+	right: 0;
124
+	}
125
+.leaflet-bottom {
126
+	bottom: 0;
127
+	}
128
+.leaflet-left {
129
+	left: 0;
130
+	}
131
+.leaflet-control {
132
+	float: left;
133
+	clear: both;
134
+	}
135
+.leaflet-right .leaflet-control {
136
+	float: right;
137
+	}
138
+.leaflet-top .leaflet-control {
139
+	margin-top: 10px;
140
+	}
141
+.leaflet-bottom .leaflet-control {
142
+	margin-bottom: 10px;
143
+	}
144
+.leaflet-left .leaflet-control {
145
+	margin-left: 10px;
146
+	}
147
+.leaflet-right .leaflet-control {
148
+	margin-right: 10px;
149
+	}
150
+
151
+
152
+/* zoom and fade animations */
153
+
154
+.leaflet-fade-anim .leaflet-tile {
155
+	will-change: opacity;
156
+	}
157
+.leaflet-fade-anim .leaflet-popup {
158
+	opacity: 0;
159
+	-webkit-transition: opacity 0.2s linear;
160
+	   -moz-transition: opacity 0.2s linear;
161
+	     -o-transition: opacity 0.2s linear;
162
+	        transition: opacity 0.2s linear;
163
+	}
164
+.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
165
+	opacity: 1;
166
+	}
167
+.leaflet-zoom-animated {
168
+	-webkit-transform-origin: 0 0;
169
+	    -ms-transform-origin: 0 0;
170
+	        transform-origin: 0 0;
171
+	}
172
+.leaflet-zoom-anim .leaflet-zoom-animated {
173
+	will-change: transform;
174
+	}
175
+.leaflet-zoom-anim .leaflet-zoom-animated {
176
+	-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
177
+	   -moz-transition:    -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
178
+	     -o-transition:      -o-transform 0.25s cubic-bezier(0,0,0.25,1);
179
+	        transition:         transform 0.25s cubic-bezier(0,0,0.25,1);
180
+	}
181
+.leaflet-zoom-anim .leaflet-tile,
182
+.leaflet-pan-anim .leaflet-tile {
183
+	-webkit-transition: none;
184
+	   -moz-transition: none;
185
+	     -o-transition: none;
186
+	        transition: none;
187
+	}
188
+
189
+.leaflet-zoom-anim .leaflet-zoom-hide {
190
+	visibility: hidden;
191
+	}
192
+
193
+
194
+/* cursors */
195
+
196
+.leaflet-interactive {
197
+	cursor: pointer;
198
+	}
199
+.leaflet-grab {
200
+	cursor: -webkit-grab;
201
+	cursor:    -moz-grab;
202
+	}
203
+.leaflet-crosshair,
204
+.leaflet-crosshair .leaflet-interactive {
205
+	cursor: crosshair;
206
+	}
207
+.leaflet-popup-pane,
208
+.leaflet-control {
209
+	cursor: auto;
210
+	}
211
+.leaflet-dragging .leaflet-grab,
212
+.leaflet-dragging .leaflet-grab .leaflet-interactive,
213
+.leaflet-dragging .leaflet-marker-draggable {
214
+	cursor: move;
215
+	cursor: -webkit-grabbing;
216
+	cursor:    -moz-grabbing;
217
+	}
218
+
219
+/* marker & overlays interactivity */
220
+.leaflet-marker-icon,
221
+.leaflet-marker-shadow,
222
+.leaflet-image-layer,
223
+.leaflet-pane > svg path,
224
+.leaflet-tile-container {
225
+	pointer-events: none;
226
+	}
227
+
228
+.leaflet-marker-icon.leaflet-interactive,
229
+.leaflet-image-layer.leaflet-interactive,
230
+.leaflet-pane > svg path.leaflet-interactive {
231
+	pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
232
+	pointer-events: auto;
233
+	}
234
+
235
+/* visual tweaks */
236
+
237
+.leaflet-container {
238
+	background: #ddd;
239
+	outline: 0;
240
+	}
241
+.leaflet-container a {
242
+	color: #0078A8;
243
+	}
244
+.leaflet-container a.leaflet-active {
245
+	outline: 2px solid orange;
246
+	}
247
+.leaflet-zoom-box {
248
+	border: 2px dotted #38f;
249
+	background: rgba(255,255,255,0.5);
250
+	}
251
+
252
+
253
+/* general typography */
254
+.leaflet-container {
255
+	font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
256
+	}
257
+
258
+
259
+/* general toolbar styles */
260
+
261
+.leaflet-bar {
262
+	box-shadow: 0 1px 5px rgba(0,0,0,0.65);
263
+	border-radius: 4px;
264
+	}
265
+.leaflet-bar a,
266
+.leaflet-bar a:hover {
267
+	background-color: #fff;
268
+	border-bottom: 1px solid #ccc;
269
+	width: 26px;
270
+	height: 26px;
271
+	line-height: 26px;
272
+	display: block;
273
+	text-align: center;
274
+	text-decoration: none;
275
+	color: black;
276
+	}
277
+.leaflet-bar a,
278
+.leaflet-control-layers-toggle {
279
+	background-position: 50% 50%;
280
+	background-repeat: no-repeat;
281
+	display: block;
282
+	}
283
+.leaflet-bar a:hover {
284
+	background-color: #f4f4f4;
285
+	}
286
+.leaflet-bar a:first-child {
287
+	border-top-left-radius: 4px;
288
+	border-top-right-radius: 4px;
289
+	}
290
+.leaflet-bar a:last-child {
291
+	border-bottom-left-radius: 4px;
292
+	border-bottom-right-radius: 4px;
293
+	border-bottom: none;
294
+	}
295
+.leaflet-bar a.leaflet-disabled {
296
+	cursor: default;
297
+	background-color: #f4f4f4;
298
+	color: #bbb;
299
+	}
300
+
301
+.leaflet-touch .leaflet-bar a {
302
+	width: 30px;
303
+	height: 30px;
304
+	line-height: 30px;
305
+	}
306
+
307
+
308
+/* zoom control */
309
+
310
+.leaflet-control-zoom-in,
311
+.leaflet-control-zoom-out {
312
+	font: bold 18px 'Lucida Console', Monaco, monospace;
313
+	text-indent: 1px;
314
+	}
315
+.leaflet-control-zoom-out {
316
+	font-size: 20px;
317
+	}
318
+
319
+.leaflet-touch .leaflet-control-zoom-in {
320
+	font-size: 22px;
321
+	}
322
+.leaflet-touch .leaflet-control-zoom-out {
323
+	font-size: 24px;
324
+	}
325
+
326
+
327
+/* layers control */
328
+
329
+.leaflet-control-layers {
330
+	box-shadow: 0 1px 5px rgba(0,0,0,0.4);
331
+	background: #fff;
332
+	border-radius: 5px;
333
+	}
334
+.leaflet-control-layers-toggle {
335
+	background-image: url(images/layers.png);
336
+	width: 36px;
337
+	height: 36px;
338
+	}
339
+.leaflet-retina .leaflet-control-layers-toggle {
340
+	background-image: url(images/layers-2x.png);
341
+	background-size: 26px 26px;
342
+	}
343
+.leaflet-touch .leaflet-control-layers-toggle {
344
+	width: 44px;
345
+	height: 44px;
346
+	}
347
+.leaflet-control-layers .leaflet-control-layers-list,
348
+.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
349
+	display: none;
350
+	}
351
+.leaflet-control-layers-expanded .leaflet-control-layers-list {
352
+	display: block;
353
+	position: relative;
354
+	}
355
+.leaflet-control-layers-expanded {
356
+	padding: 6px 10px 6px 6px;
357
+	color: #333;
358
+	background: #fff;
359
+	}
360
+.leaflet-control-layers-scrollbar {
361
+	overflow-y: scroll;
362
+	padding-right: 5px;
363
+	}
364
+.leaflet-control-layers-selector {
365
+	margin-top: 2px;
366
+	position: relative;
367
+	top: 1px;
368
+	}
369
+.leaflet-control-layers label {
370
+	display: block;
371
+	}
372
+.leaflet-control-layers-separator {
373
+	height: 0;
374
+	border-top: 1px solid #ddd;
375
+	margin: 5px -10px 5px -6px;
376
+	}
377
+
378
+/* Default icon URLs */
379
+.leaflet-default-icon-path {
380
+	background-image: url(images/marker-icon.png);
381
+	}
382
+
383
+
384
+/* attribution and scale controls */
385
+
386
+.leaflet-container .leaflet-control-attribution {
387
+	background: #fff;
388
+	background: rgba(255, 255, 255, 0.7);
389
+	margin: 0;
390
+	}
391
+.leaflet-control-attribution,
392
+.leaflet-control-scale-line {
393
+	padding: 0 5px;
394
+	color: #333;
395
+	}
396
+.leaflet-control-attribution a {
397
+	text-decoration: none;
398
+	}
399
+.leaflet-control-attribution a:hover {
400
+	text-decoration: underline;
401
+	}
402
+.leaflet-container .leaflet-control-attribution,
403
+.leaflet-container .leaflet-control-scale {
404
+	font-size: 11px;
405
+	}
406
+.leaflet-left .leaflet-control-scale {
407
+	margin-left: 5px;
408
+	}
409
+.leaflet-bottom .leaflet-control-scale {
410
+	margin-bottom: 5px;
411
+	}
412
+.leaflet-control-scale-line {
413
+	border: 2px solid #777;
414
+	border-top: none;
415
+	line-height: 1.1;
416
+	padding: 2px 5px 1px;
417
+	font-size: 11px;
418
+	white-space: nowrap;
419
+	overflow: hidden;
420
+	-moz-box-sizing: border-box;
421
+	     box-sizing: border-box;
422
+
423
+	background: #fff;
424
+	background: rgba(255, 255, 255, 0.5);
425
+	}
426
+.leaflet-control-scale-line:not(:first-child) {
427
+	border-top: 2px solid #777;
428
+	border-bottom: none;
429
+	margin-top: -2px;
430
+	}
431
+.leaflet-control-scale-line:not(:first-child):not(:last-child) {
432
+	border-bottom: 2px solid #777;
433
+	}
434
+
435
+.leaflet-touch .leaflet-control-attribution,
436
+.leaflet-touch .leaflet-control-layers,
437
+.leaflet-touch .leaflet-bar {
438
+	box-shadow: none;
439
+	}
440
+.leaflet-touch .leaflet-control-layers,
441
+.leaflet-touch .leaflet-bar {
442
+	border: 2px solid rgba(0,0,0,0.2);
443
+	background-clip: padding-box;
444
+	}
445
+
446
+
447
+/* popup */
448
+
449
+.leaflet-popup {
450
+	position: absolute;
451
+	text-align: center;
452
+	margin-bottom: 20px;
453
+	}
454
+.leaflet-popup-content-wrapper {
455
+	padding: 1px;
456
+	text-align: left;
457
+	border-radius: 12px;
458
+	}
459
+.leaflet-popup-content {
460
+	margin: 13px 19px;
461
+	line-height: 1.4;
462
+	}
463
+.leaflet-popup-content p {
464
+	margin: 18px 0;
465
+	}
466
+.leaflet-popup-tip-container {
467
+	width: 40px;
468
+	height: 20px;
469
+	position: absolute;
470
+	left: 50%;
471
+	margin-left: -20px;
472
+	overflow: hidden;
473
+	pointer-events: none;
474
+	}
475
+.leaflet-popup-tip {
476
+	width: 17px;
477
+	height: 17px;
478
+	padding: 1px;
479
+
480
+	margin: -10px auto 0;
481
+
482
+	-webkit-transform: rotate(45deg);
483
+	   -moz-transform: rotate(45deg);
484
+	    -ms-transform: rotate(45deg);
485
+	     -o-transform: rotate(45deg);
486
+	        transform: rotate(45deg);
487
+	}
488
+.leaflet-popup-content-wrapper,
489
+.leaflet-popup-tip {
490
+	background: white;
491
+	color: #333;
492
+	box-shadow: 0 3px 14px rgba(0,0,0,0.4);
493
+	}
494
+.leaflet-container a.leaflet-popup-close-button {
495
+	position: absolute;
496
+	top: 0;
497
+	right: 0;
498
+	padding: 4px 4px 0 0;
499
+	border: none;
500
+	text-align: center;
501
+	width: 18px;
502
+	height: 14px;
503
+	font: 16px/14px Tahoma, Verdana, sans-serif;
504
+	color: #c3c3c3;
505
+	text-decoration: none;
506
+	font-weight: bold;
507
+	background: transparent;
508
+	}
509
+.leaflet-container a.leaflet-popup-close-button:hover {
510
+	color: #999;
511
+	}
512
+.leaflet-popup-scrolled {
513
+	overflow: auto;
514
+	border-bottom: 1px solid #ddd;
515
+	border-top: 1px solid #ddd;
516
+	}
517
+
518
+.leaflet-oldie .leaflet-popup-content-wrapper {
519
+	zoom: 1;
520
+	}
521
+.leaflet-oldie .leaflet-popup-tip {
522
+	width: 24px;
523
+	margin: 0 auto;
524
+
525
+	-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
526
+	filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
527
+	}
528
+.leaflet-oldie .leaflet-popup-tip-container {
529
+	margin-top: -1px;
530
+	}
531
+
532
+.leaflet-oldie .leaflet-control-zoom,
533
+.leaflet-oldie .leaflet-control-layers,
534
+.leaflet-oldie .leaflet-popup-content-wrapper,
535
+.leaflet-oldie .leaflet-popup-tip {
536
+	border: 1px solid #999;
537
+	}
538
+
539
+
540
+/* div icon */
541
+
542
+.leaflet-div-icon {
543
+	background: #fff;
544
+	border: 1px solid #666;
545
+	}
546
+
547
+
548
+/* Tooltip */
549
+/* Base styles for the element that has a tooltip */
550
+.leaflet-tooltip {
551
+	position: absolute;
552
+	padding: 6px;
553
+	background-color: #fff;
554
+	border: 1px solid #fff;
555
+	border-radius: 3px;
556
+	color: #222;
557
+	white-space: nowrap;
558
+	-webkit-user-select: none;
559
+	-moz-user-select: none;
560
+	-ms-user-select: none;
561
+	user-select: none;
562
+	pointer-events: none;
563
+	box-shadow: 0 1px 3px rgba(0,0,0,0.4);
564
+	}
565
+.leaflet-tooltip.leaflet-clickable {
566
+	cursor: pointer;
567
+	pointer-events: auto;
568
+	}
569
+.leaflet-tooltip-top:before,
570
+.leaflet-tooltip-bottom:before,
571
+.leaflet-tooltip-left:before,
572
+.leaflet-tooltip-right:before {
573
+	position: absolute;
574
+	pointer-events: none;
575
+	border: 6px solid transparent;
576
+	background: transparent;
577
+	content: "";
578
+	}
579
+
580
+/* Directions */
581
+
582
+.leaflet-tooltip-bottom {
583
+	margin-top: 6px;
584
+}
585
+.leaflet-tooltip-top {
586
+	margin-top: -6px;
587
+}
588
+.leaflet-tooltip-bottom:before,
589
+.leaflet-tooltip-top:before {
590
+	left: 50%;
591
+	margin-left: -6px;
592
+	}
593
+.leaflet-tooltip-top:before {
594
+	bottom: 0;
595
+	margin-bottom: -12px;
596
+	border-top-color: #fff;
597
+	}
598
+.leaflet-tooltip-bottom:before {
599
+	top: 0;
600
+	margin-top: -12px;
601
+	margin-left: -6px;
602
+	border-bottom-color: #fff;
603
+	}
604
+.leaflet-tooltip-left {
605
+	margin-left: -6px;
606
+}
607
+.leaflet-tooltip-right {
608
+	margin-left: 6px;
609
+}
610
+.leaflet-tooltip-left:before,
611
+.leaflet-tooltip-right:before {
612
+	top: 50%;
613
+	margin-top: -6px;
614
+	}
615
+.leaflet-tooltip-left:before {
616
+	right: 0;
617
+	margin-right: -12px;
618
+	border-left-color: #fff;
619
+	}
620
+.leaflet-tooltip-right:before {
621
+	left: 0;
622
+	margin-left: -12px;
623
+	border-right-color: #fff;
624
+	}

+ 9
- 0
searx/static/themes/simple/leaflet/leaflet.js
Datei-Diff unterdrückt, da er zu groß ist
Datei anzeigen


+ 67
- 0
searx/static/themes/simple/less/autocomplete.less Datei anzeigen

@@ -0,0 +1,67 @@
1
+@background_color:  white;
2
+
3
+.autocomplete {
4
+    position: absolute;
5
+    max-height: 0;
6
+    overflow-y: hidden;
7
+    text-align: left;
8
+
9
+    &:active, &:focus, &:hover {
10
+      background-color: @background_color;
11
+    }
12
+
13
+    &:empty {
14
+        display: none;
15
+    }
16
+
17
+    > ul {
18
+        list-style-type: none;
19
+        margin: 0;
20
+        padding: 0;
21
+
22
+        > li {
23
+            cursor: pointer;
24
+            padding: 5px 0 5px 10px;
25
+
26
+            &.active, &:active, &:focus {
27
+                background-color: @color-base;
28
+
29
+                a:active, a:focus, a:hover {
30
+                    text-decoration: none;
31
+                }
32
+            }
33
+
34
+            &.locked {
35
+                cursor: inherit;
36
+            }
37
+        }
38
+    }
39
+
40
+    &.open {
41
+        display: block;
42
+        background-color: @background_color;
43
+        border: 1px solid @color-base;
44
+        max-height: 500px;
45
+        overflow-y: auto;
46
+        z-index:100;
47
+
48
+        &:empty {
49
+            display: none;
50
+        }
51
+    }
52
+}
53
+
54
+
55
+@media screen and (max-width: @results-width) {
56
+
57
+  .autocomplete {
58
+    bottom: 0;
59
+  }
60
+
61
+  .autocomplete > ul > li {
62
+    padding: 7px 0 7px 10px;
63
+    border-bottom: 1px solid @color-result-top-border;
64
+    text-align: left;
65
+  }
66
+
67
+}

+ 83
- 0
searx/static/themes/simple/less/code.less Datei anzeigen

@@ -0,0 +1,83 @@
1
+.highlight .hll { background-color: #ffffcc }
2
+.highlight  { background: #f8f8f8; }
3
+.highlight .c { color: #408080; font-style: italic } /* Comment */
4
+.highlight .err { border: 1px solid #FF0000 } /* Error */
5
+.highlight .k { color: #008000; font-weight: bold } /* Keyword */
6
+.highlight .o { color: #666666 } /* Operator */
7
+.highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */
8
+.highlight .cp { color: #BC7A00 } /* Comment.Preproc */
9
+.highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */
10
+.highlight .cs { color: #408080; font-style: italic } /* Comment.Special */
11
+.highlight .gd { color: #A00000 } /* Generic.Deleted */
12
+.highlight .ge { font-style: italic } /* Generic.Emph */
13
+.highlight .gr { color: #FF0000 } /* Generic.Error */
14
+.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
15
+.highlight .gi { color: #00A000 } /* Generic.Inserted */
16
+.highlight .go { color: #888888 } /* Generic.Output */
17
+.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
18
+.highlight .gs { font-weight: bold } /* Generic.Strong */
19
+.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
20
+.highlight .gt { color: #0044DD } /* Generic.Traceback */
21
+.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
22
+.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
23
+.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
24
+.highlight .kp { color: #008000 } /* Keyword.Pseudo */
25
+.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
26
+.highlight .kt { color: #B00040 } /* Keyword.Type */
27
+.highlight .m { color: #666666 } /* Literal.Number */
28
+.highlight .s { color: #BA2121 } /* Literal.String */
29
+.highlight .na { color: #7D9029 } /* Name.Attribute */
30
+.highlight .nb { color: #008000 } /* Name.Builtin */
31
+.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */
32
+.highlight .no { color: #880000 } /* Name.Constant */
33
+.highlight .nd { color: #AA22FF } /* Name.Decorator */
34
+.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */
35
+.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
36
+.highlight .nf { color: #0000FF } /* Name.Function */
37
+.highlight .nl { color: #A0A000 } /* Name.Label */
38
+.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
39
+.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
40
+.highlight .nv { color: #19177C } /* Name.Variable */
41
+.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
42
+.highlight .w { color: #bbbbbb } /* Text.Whitespace */
43
+.highlight .mf { color: #666666 } /* Literal.Number.Float */
44
+.highlight .mh { color: #666666 } /* Literal.Number.Hex */
45
+.highlight .mi { color: #666666 } /* Literal.Number.Integer */
46
+.highlight .mo { color: #666666 } /* Literal.Number.Oct */
47
+.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */
48
+.highlight .sc { color: #BA2121 } /* Literal.String.Char */
49
+.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
50
+.highlight .s2 { color: #BA2121 } /* Literal.String.Double */
51
+.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
52
+.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */
53
+.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
54
+.highlight .sx { color: #008000 } /* Literal.String.Other */
55
+.highlight .sr { color: #BB6688 } /* Literal.String.Regex */
56
+.highlight .s1 { color: #BA2121 } /* Literal.String.Single */
57
+.highlight .ss { color: #19177C } /* Literal.String.Symbol */
58
+.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
59
+.highlight .vc { color: #19177C } /* Name.Variable.Class */
60
+.highlight .vg { color: #19177C } /* Name.Variable.Global */
61
+.highlight .vi { color: #19177C } /* Name.Variable.Instance */
62
+.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
63
+
64
+.highlight pre {
65
+    overflow: auto;
66
+}
67
+
68
+.highlight .lineno {
69
+    -webkit-touch-callout: none;
70
+    -webkit-user-select: none;
71
+    -khtml-user-select: none;
72
+    -moz-user-select: none;
73
+    -ms-user-select: none;
74
+    user-select: none;
75
+    cursor: default;
76
+    
77
+    &::selection {
78
+        background: transparent; /* WebKit/Blink Browsers */
79
+    }
80
+    &::-moz-selection {
81
+        background: transparent; /* Gecko Browsers */
82
+    }
83
+}

+ 135
- 0
searx/static/themes/simple/less/definitions.less Datei anzeigen

@@ -0,0 +1,135 @@
1
+/*
2
+ * searx, A privacy-respecting, hackable metasearch engine
3
+ *
4
+ * To change the colors of the site, simple edit this variables
5
+ */
6
+
7
+/// Basic Colors
8
+
9
+@color-base: #3498DB;
10
+@color-base-dark: #084999;
11
+@color-base-light: #ECF0F1;
12
+@color-highlight: #094089;
13
+@color-black: #000000;
14
+
15
+///
16
+@color-error: #db3434;
17
+@color-error-background: lighten(@color-error, 40%);
18
+
19
+@color-warning: #dbba34;
20
+@color-warning-background: lighten(@color-warning, 40%);
21
+
22
+/// General
23
+
24
+@color-font: #444;
25
+@color-font-light: #888;
26
+
27
+@color-red: #25a55b;
28
+
29
+@color-url-font: #29314d;
30
+@color-url-visited-font: #684898;
31
+@results-width: 50em;
32
+@search-width: 40em;
33
+
34
+//
35
+@color-a-font: @color-base;
36
+@color-a-font-hover: @color-base;
37
+
38
+
39
+/// Start-Screen
40
+
41
+
42
+
43
+/// Search-Input
44
+
45
+@color-search-border: @color-base;
46
+@color-search-background: #FFF;
47
+@color-search-font: #222;
48
+
49
+/// Autocompleter
50
+
51
+@color-autocompleter-choices-background: #FFF;
52
+@color-autocompleter-choices-border: @color-base;
53
+@color-autocompleter-choices-border-left-right: @color-base;
54
+@color-autocompleter-choices-border-bottom: @color-base;
55
+
56
+@color-autocompleter-choices-font: #444;
57
+
58
+/// Answers
59
+@color-answers-border: @color-base-dark;
60
+
61
+// Selected
62
+@color-autocompleter-selected-background: #444;
63
+@color-autocompleter-selected-font: #FFF;
64
+@color-autocompleter-selected-queried-font: #9FCFFF;
65
+
66
+/// Categories
67
+
68
+@color-categories-item-selected: @color-base;
69
+@color-categories-item-selected-font: #FFF;
70
+
71
+@color-categories-item-border-selected: @color-base-dark;
72
+@color-categories-item-border-unselected: #E8E7E6;
73
+@color-categories-item-border-unselected-hover: @color-base;
74
+
75
+
76
+/// Results
77
+
78
+@color-suggestions-button-background: @color-base;
79
+@color-suggestions-button-font: #FFF;
80
+
81
+@color-download-button-background: @color-base;
82
+@color-download-button-font: #FFF;
83
+
84
+@color-result-search-background: @color-base-light;
85
+
86
+@color-result-definition-border: gray;
87
+@color-result-torrent-border: lightgray;
88
+@color-result-top-border: #E8E7E6;
89
+
90
+// Link to result
91
+@color-result-link-font: @color-base-dark;
92
+@color-result-link-visited-font: @color-url-visited-font;
93
+
94
+// Url to result
95
+@color-result-url-font: @color-red;
96
+
97
+// Publish Date
98
+@color-result-publishdate-font: @color-font-light;
99
+
100
+// Images
101
+@color-result-image-span-background-hover: rgba(0, 0, 0, 0.6);
102
+@color-result-image-span-font: #FFF;
103
+
104
+// Search-URL
105
+@color-result-search-url-border: #888;
106
+@color-result-search-url-font: #444;
107
+
108
+
109
+/// Settings
110
+
111
+@color-settings-fieldset: @color-base;
112
+@color-settings-table-striped: #dbdbdb;
113
+@color-settings-tr-hover: #ececec;
114
+
115
+// Labels
116
+@color-settings-label-allowed-background: #E74C3C;
117
+@color-settings-label-allowed-font: #FFF;
118
+
119
+@color-settings-label-deny-background: #2ECC71;
120
+@color-settings-label-deny-font: @color-font;
121
+
122
+@color-settings-return-background: @color-base;
123
+@color-settings-return-font: #FFF;
124
+
125
+/// Other
126
+
127
+@color-engines-font: @color-font-light;
128
+@color-percentage-div-background: #444;
129
+
130
+/// Load fonts from this directory.
131
+@icon-font-path:          "../../../fonts/";
132
+//** File name for all font files.
133
+@icon-font-name:          "glyphicons-halflings-regular";
134
+//** Element ID within SVG icon file.
135
+@icon-font-svg-id:        "glyphicons_halflingsregular";

+ 43
- 0
searx/static/themes/simple/less/index.less Datei anzeigen

@@ -0,0 +1,43 @@
1
+.index {
2
+
3
+  text-align: center;
4
+
5
+  .title {
6
+    background: url('../img/searx.png') no-repeat;
7
+    width: 100%;
8
+    min-height: 80px;
9
+    background-position: center;
10
+  }
11
+
12
+  h1 {
13
+    font-size: 5em;
14
+    visibility: hidden;
15
+  }
16
+
17
+  #search {
18
+    margin: 0 auto;
19
+    background: inherit;
20
+    border: inherit;
21
+  }
22
+
23
+  .search_filters {
24
+    display: block;
25
+    margin: 1em 0;
26
+  }
27
+
28
+  .category label {
29
+    padding: 6px 10px;
30
+    border-bottom: initial !important;
31
+  }
32
+
33
+}
34
+
35
+@media screen and (max-width: 75em) {
36
+
37
+  div.title {
38
+    h1 {
39
+      font-size: 1em;
40
+    }
41
+  }
42
+
43
+}

+ 174
- 0
searx/static/themes/simple/less/ion.less Datei anzeigen

@@ -0,0 +1,174 @@
1
+// Generated by grunt-webfont
2
+
3
+
4
+@font-face {
5
+	font-family:"ion";
6
+	src:url("../fonts/ion.eot?94af7082ea096aefe3a7b6642834716e");
7
+	src:url("../fonts/ion.eot?#iefix") format("embedded-opentype"),
8
+		url("../fonts/ion.woff2?94af7082ea096aefe3a7b6642834716e") format("woff2"),
9
+		url("../fonts/ion.woff?94af7082ea096aefe3a7b6642834716e") format("woff"),
10
+		url("../fonts/ion.ttf?94af7082ea096aefe3a7b6642834716e") format("truetype"),
11
+		url("../fonts/ion.svg?94af7082ea096aefe3a7b6642834716e#ion") format("svg");
12
+	font-weight:normal;
13
+	font-style:normal;
14
+}
15
+
16
+.ion-icon {
17
+	&:before {
18
+		font-family:"ion";
19
+	}
20
+	display:inline-block;
21
+	vertical-align:middle;
22
+	line-height:1;
23
+	font-weight:normal;
24
+	font-style:normal;
25
+	speak:none;
26
+	text-decoration:inherit;
27
+	text-transform:none;
28
+	text-rendering:auto;
29
+	-webkit-font-smoothing:antialiased;
30
+	-moz-osx-font-smoothing:grayscale;
31
+}
32
+
33
+
34
+// Icons
35
+
36
+.ion-navicon-round {
37
+	&:before {
38
+		content:"\f101";
39
+	}
40
+}
41
+
42
+
43
+.ion-search {
44
+	&:before {
45
+		content:"\f102";
46
+	}
47
+}
48
+
49
+
50
+.ion-play {
51
+	&:before {
52
+		content:"\f103";
53
+	}
54
+}
55
+
56
+
57
+.ion-link {
58
+	&:before {
59
+		content:"\f104";
60
+	}
61
+}
62
+
63
+
64
+.ion-chevron-up {
65
+	&:before {
66
+		content:"\f105";
67
+	}
68
+}
69
+
70
+
71
+.ion-chevron-left {
72
+	&:before {
73
+		content:"\f106";
74
+	}
75
+}
76
+
77
+
78
+.ion-chevron-right {
79
+	&:before {
80
+		content:"\f107";
81
+	}
82
+}
83
+
84
+
85
+.ion-arrow-down-a {
86
+	&:before {
87
+		content:"\f108";
88
+	}
89
+}
90
+
91
+
92
+.ion-arrow-up-a {
93
+	&:before {
94
+		content:"\f109";
95
+	}
96
+}
97
+
98
+
99
+.ion-arrow-swap {
100
+	&:before {
101
+		content:"\f10a";
102
+	}
103
+}
104
+
105
+
106
+.ion-arrow-dropdown {
107
+	&:before {
108
+		content:"\f10b";
109
+	}
110
+}
111
+
112
+
113
+.ion-globe {
114
+	&:before {
115
+		content:"\f10c";
116
+	}
117
+}
118
+
119
+
120
+.ion-time {
121
+	&:before {
122
+		content:"\f10d";
123
+	}
124
+}
125
+
126
+
127
+.ion-location {
128
+	&:before {
129
+		content:"\f10e";
130
+	}
131
+}
132
+
133
+
134
+.ion-warning {
135
+	&:before {
136
+		content:"\f10f";
137
+	}
138
+}
139
+
140
+
141
+.ion-error {
142
+	&:before {
143
+		content:"\f110";
144
+	}
145
+}
146
+
147
+
148
+.ion-film-outline {
149
+	&:before {
150
+		content:"\f111";
151
+	}
152
+}
153
+
154
+
155
+.ion-music-note {
156
+	&:before {
157
+		content:"\f112";
158
+	}
159
+}
160
+
161
+
162
+.ion-more-vertical {
163
+	&:before {
164
+		content:"\f113";
165
+	}
166
+}
167
+
168
+
169
+.ion-magnet {
170
+	&:before {
171
+		content:"\f114";
172
+	}
173
+}
174
+

+ 62
- 0
searx/static/themes/simple/less/mixins.less Datei anzeigen

@@ -0,0 +1,62 @@
1
+/*
2
+* searx, A privacy-respecting, hackable metasearch engine
3
+*/
4
+
5
+// Mixins
6
+.text-size-adjust (@property: 100%) {
7
+	-webkit-text-size-adjust: @property;
8
+	-ms-text-size-adjust: @property;
9
+	-moz-text-size-adjust: @property;
10
+	text-size-adjust: @property;
11
+}
12
+
13
+.rounded-corners (@radius: 4px) {
14
+	-webkit-border-radius: @radius;
15
+	-moz-border-radius: @radius;
16
+	border-radius: @radius;
17
+}
18
+
19
+// disable user selection
20
+.disable-user-select () {
21
+	-webkit-touch-callout: none;
22
+	-webkit-user-select: none;
23
+	-khtml-user-select: none;
24
+	-moz-user-select: none;
25
+	-ms-user-select: none;
26
+	user-select: none;
27
+}
28
+
29
+// select all on focus
30
+.select-all-on-focus() {
31
+	-webkit-user-select: all;
32
+	-moz-user-select: all;
33
+	-ms-user-select: all;
34
+	user-select: all;
35
+}
36
+
37
+// see https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Advanced_layouts_with_flexbox
38
+.flexbox() {
39
+  display: -webkit-box;
40
+  display: -moz-box;
41
+  display: -webkit-flex;
42
+  display: -ms-flexbox;
43
+  display: flex;
44
+}
45
+
46
+.inline-flex() {
47
+	display: -webkit-inline-box;
48
+	display: -moz-inline-box;
49
+	display: -webkit-inline-flex;
50
+	display: -ms-inline-flexbox;
51
+	display: inline-flex;
52
+}
53
+
54
+.flex-direction-row() {
55
+	-webkit-box-direction: normal;
56
+	-webkit-box-orient: horizontal;
57
+	-moz-box-direction: normal;
58
+	-moz-box-orient: horizontal;
59
+	-webkit-flex-direction: row;
60
+	-ms-flex-direction: row;
61
+	flex-direction: row;
62
+}

+ 447
- 0
searx/static/themes/simple/less/normalize.less Datei anzeigen

@@ -0,0 +1,447 @@
1
+/*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */
2
+
3
+/* Document
4
+   ========================================================================== */
5
+
6
+/**
7
+ * 1. Correct the line height in all browsers.
8
+ * 2. Prevent adjustments of font size after orientation changes in
9
+ *    IE on Windows Phone and in iOS.
10
+ */
11
+
12
+html {
13
+  line-height: 1.15; /* 1 */
14
+  -ms-text-size-adjust: 100%; /* 2 */
15
+  -webkit-text-size-adjust: 100%; /* 2 */
16
+}
17
+
18
+/* Sections
19
+   ========================================================================== */
20
+
21
+/**
22
+ * Remove the margin in all browsers (opinionated).
23
+ */
24
+
25
+body {
26
+  margin: 0;
27
+}
28
+
29
+/**
30
+ * Add the correct display in IE 9-.
31
+ */
32
+
33
+article,
34
+aside,
35
+footer,
36
+header,
37
+nav,
38
+section {
39
+  display: block;
40
+}
41
+
42
+/**
43
+ * Correct the font size and margin on `h1` elements within `section` and
44
+ * `article` contexts in Chrome, Firefox, and Safari.
45
+ */
46
+
47
+h1 {
48
+  font-size: 2em;
49
+  margin: 0.67em 0;
50
+}
51
+
52
+/* Grouping content
53
+   ========================================================================== */
54
+
55
+/**
56
+ * Add the correct display in IE 9-.
57
+ * 1. Add the correct display in IE.
58
+ */
59
+
60
+figcaption,
61
+figure,
62
+main { /* 1 */
63
+  display: block;
64
+}
65
+
66
+/**
67
+ * Add the correct margin in IE 8.
68
+ */
69
+
70
+figure {
71
+  margin: 1em 40px;
72
+}
73
+
74
+/**
75
+ * 1. Add the correct box sizing in Firefox.
76
+ * 2. Show the overflow in Edge and IE.
77
+ */
78
+
79
+hr {
80
+  box-sizing: content-box; /* 1 */
81
+  height: 0; /* 1 */
82
+  overflow: visible; /* 2 */
83
+}
84
+
85
+/**
86
+ * 1. Correct the inheritance and scaling of font size in all browsers.
87
+ * 2. Correct the odd `em` font sizing in all browsers.
88
+ */
89
+
90
+pre {
91
+  font-family: monospace, monospace; /* 1 */
92
+  font-size: 1em; /* 2 */
93
+}
94
+
95
+/* Text-level semantics
96
+   ========================================================================== */
97
+
98
+/**
99
+ * 1. Remove the gray background on active links in IE 10.
100
+ * 2. Remove gaps in links underline in iOS 8+ and Safari 8+.
101
+ */
102
+
103
+a {
104
+  background-color: transparent; /* 1 */
105
+  -webkit-text-decoration-skip: objects; /* 2 */
106
+}
107
+
108
+/**
109
+ * 1. Remove the bottom border in Chrome 57- and Firefox 39-.
110
+ * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
111
+ */
112
+
113
+abbr[title] {
114
+  border-bottom: none; /* 1 */
115
+  text-decoration: underline; /* 2 */
116
+  text-decoration: underline dotted; /* 2 */
117
+}
118
+
119
+/**
120
+ * Prevent the duplicate application of `bolder` by the next rule in Safari 6.
121
+ */
122
+
123
+b,
124
+strong {
125
+  font-weight: inherit;
126
+}
127
+
128
+/**
129
+ * Add the correct font weight in Chrome, Edge, and Safari.
130
+ */
131
+
132
+b,
133
+strong {
134
+  font-weight: bolder;
135
+}
136
+
137
+/**
138
+ * 1. Correct the inheritance and scaling of font size in all browsers.
139
+ * 2. Correct the odd `em` font sizing in all browsers.
140
+ */
141
+
142
+code,
143
+kbd,
144
+samp {
145
+  font-family: monospace, monospace; /* 1 */
146
+  font-size: 1em; /* 2 */
147
+}
148
+
149
+/**
150
+ * Add the correct font style in Android 4.3-.
151
+ */
152
+
153
+dfn {
154
+  font-style: italic;
155
+}
156
+
157
+/**
158
+ * Add the correct background and color in IE 9-.
159
+ */
160
+
161
+mark {
162
+  background-color: #ff0;
163
+  color: #000;
164
+}
165
+
166
+/**
167
+ * Add the correct font size in all browsers.
168
+ */
169
+
170
+small {
171
+  font-size: 80%;
172
+}
173
+
174
+/**
175
+ * Prevent `sub` and `sup` elements from affecting the line height in
176
+ * all browsers.
177
+ */
178
+
179
+sub,
180
+sup {
181
+  font-size: 75%;
182
+  line-height: 0;
183
+  position: relative;
184
+  vertical-align: baseline;
185
+}
186
+
187
+sub {
188
+  bottom: -0.25em;
189
+}
190
+
191
+sup {
192
+  top: -0.5em;
193
+}
194
+
195
+/* Embedded content
196
+   ========================================================================== */
197
+
198
+/**
199
+ * Add the correct display in IE 9-.
200
+ */
201
+
202
+audio,
203
+video {
204
+  display: inline-block;
205
+}
206
+
207
+/**
208
+ * Add the correct display in iOS 4-7.
209
+ */
210
+
211
+audio:not([controls]) {
212
+  display: none;
213
+  height: 0;
214
+}
215
+
216
+/**
217
+ * Remove the border on images inside links in IE 10-.
218
+ */
219
+
220
+img {
221
+  border-style: none;
222
+}
223
+
224
+/**
225
+ * Hide the overflow in IE.
226
+ */
227
+
228
+svg:not(:root) {
229
+  overflow: hidden;
230
+}
231
+
232
+/* Forms
233
+   ========================================================================== */
234
+
235
+/**
236
+ * 1. Change the font styles in all browsers (opinionated).
237
+ * 2. Remove the margin in Firefox and Safari.
238
+ */
239
+
240
+button,
241
+input,
242
+optgroup,
243
+select,
244
+textarea {
245
+  font-family: sans-serif; /* 1 */
246
+  font-size: 100%; /* 1 */
247
+  line-height: 1.15; /* 1 */
248
+  margin: 0; /* 2 */
249
+}
250
+
251
+/**
252
+ * Show the overflow in IE.
253
+ * 1. Show the overflow in Edge.
254
+ */
255
+
256
+button,
257
+input { /* 1 */
258
+  overflow: visible;
259
+}
260
+
261
+/**
262
+ * Remove the inheritance of text transform in Edge, Firefox, and IE.
263
+ * 1. Remove the inheritance of text transform in Firefox.
264
+ */
265
+
266
+button,
267
+select { /* 1 */
268
+  text-transform: none;
269
+}
270
+
271
+/**
272
+ * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
273
+ *    controls in Android 4.
274
+ * 2. Correct the inability to style clickable types in iOS and Safari.
275
+ */
276
+
277
+button,
278
+html [type="button"], /* 1 */
279
+[type="reset"],
280
+[type="submit"] {
281
+  -webkit-appearance: button; /* 2 */
282
+}
283
+
284
+/**
285
+ * Remove the inner border and padding in Firefox.
286
+ */
287
+
288
+button::-moz-focus-inner,
289
+[type="button"]::-moz-focus-inner,
290
+[type="reset"]::-moz-focus-inner,
291
+[type="submit"]::-moz-focus-inner {
292
+  border-style: none;
293
+  padding: 0;
294
+}
295
+
296
+/**
297
+ * Restore the focus styles unset by the previous rule.
298
+ */
299
+
300
+button:-moz-focusring,
301
+[type="button"]:-moz-focusring,
302
+[type="reset"]:-moz-focusring,
303
+[type="submit"]:-moz-focusring {
304
+  outline: 1px dotted ButtonText;
305
+}
306
+
307
+/**
308
+ * Correct the padding in Firefox.
309
+ */
310
+
311
+fieldset {
312
+  padding: 0.35em 0.75em 0.625em;
313
+}
314
+
315
+/**
316
+ * 1. Correct the text wrapping in Edge and IE.
317
+ * 2. Correct the color inheritance from `fieldset` elements in IE.
318
+ * 3. Remove the padding so developers are not caught out when they zero out
319
+ *    `fieldset` elements in all browsers.
320
+ */
321
+
322
+legend {
323
+  box-sizing: border-box; /* 1 */
324
+  color: inherit; /* 2 */
325
+  display: table; /* 1 */
326
+  max-width: 100%; /* 1 */
327
+  padding: 0; /* 3 */
328
+  white-space: normal; /* 1 */
329
+}
330
+
331
+/**
332
+ * 1. Add the correct display in IE 9-.
333
+ * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera.
334
+ */
335
+
336
+progress {
337
+  display: inline-block; /* 1 */
338
+  vertical-align: baseline; /* 2 */
339
+}
340
+
341
+/**
342
+ * Remove the default vertical scrollbar in IE.
343
+ */
344
+
345
+textarea {
346
+  overflow: auto;
347
+}
348
+
349
+/**
350
+ * 1. Add the correct box sizing in IE 10-.
351
+ * 2. Remove the padding in IE 10-.
352
+ */
353
+
354
+[type="checkbox"],
355
+[type="radio"] {
356
+  box-sizing: border-box; /* 1 */
357
+  padding: 0; /* 2 */
358
+}
359
+
360
+/**
361
+ * Correct the cursor style of increment and decrement buttons in Chrome.
362
+ */
363
+
364
+[type="number"]::-webkit-inner-spin-button,
365
+[type="number"]::-webkit-outer-spin-button {
366
+  height: auto;
367
+}
368
+
369
+/**
370
+ * 1. Correct the odd appearance in Chrome and Safari.
371
+ * 2. Correct the outline style in Safari.
372
+ */
373
+
374
+[type="search"] {
375
+  -webkit-appearance: textfield; /* 1 */
376
+  outline-offset: -2px; /* 2 */
377
+}
378
+
379
+/**
380
+ * Remove the inner padding and cancel buttons in Chrome and Safari on macOS.
381
+ */
382
+
383
+[type="search"]::-webkit-search-cancel-button,
384
+[type="search"]::-webkit-search-decoration {
385
+  -webkit-appearance: none;
386
+}
387
+
388
+/**
389
+ * 1. Correct the inability to style clickable types in iOS and Safari.
390
+ * 2. Change font properties to `inherit` in Safari.
391
+ */
392
+
393
+::-webkit-file-upload-button {
394
+  -webkit-appearance: button; /* 1 */
395
+  font: inherit; /* 2 */
396
+}
397
+
398
+/* Interactive
399
+   ========================================================================== */
400
+
401
+/*
402
+ * Add the correct display in IE 9-.
403
+ * 1. Add the correct display in Edge, IE, and Firefox.
404
+ */
405
+
406
+details, /* 1 */
407
+menu {
408
+  display: block;
409
+}
410
+
411
+/*
412
+ * Add the correct display in all browsers.
413
+ */
414
+
415
+summary {
416
+  display: list-item;
417
+}
418
+
419
+/* Scripting
420
+   ========================================================================== */
421
+
422
+/**
423
+ * Add the correct display in IE 9-.
424
+ */
425
+
426
+canvas {
427
+  display: inline-block;
428
+}
429
+
430
+/**
431
+ * Add the correct display in IE.
432
+ */
433
+
434
+template {
435
+  display: none;
436
+}
437
+
438
+/* Hidden
439
+   ========================================================================== */
440
+
441
+/**
442
+ * Add the correct display in IE 10-.
443
+ */
444
+
445
+[hidden] {
446
+  display: none;
447
+}

+ 78
- 0
searx/static/themes/simple/less/preferences.less Datei anzeigen

@@ -0,0 +1,78 @@
1
+#main_preferences {
2
+  form {
3
+      width: 100%;
4
+  }
5
+
6
+  fieldset {
7
+  	margin: 8px;
8
+    border: none;
9
+  }
10
+
11
+  legend {
12
+    margin: 0;
13
+    padding: 5px 0 0 0;
14
+    display: block;
15
+    float:left;
16
+    width: 300px;
17
+  }
18
+
19
+  .value {
20
+    margin: 0;
21
+    padding: 0;
22
+    float:left;
23
+    width: 15em;
24
+  }
25
+
26
+  .description {
27
+    margin: 0;
28
+    padding: 5px 0 0 0;
29
+    float:left;
30
+    width: 50%;
31
+    color: darken(#dcdcdc, 30%);
32
+    font-size: 90%;
33
+  }
34
+
35
+  select {
36
+    width: 200px;
37
+    font-size: inherit !important;
38
+  }
39
+
40
+  table {
41
+    border-collapse: collapse;
42
+  }
43
+
44
+  table td {
45
+    text-align: center;
46
+  }
47
+
48
+  .name, .shortcut {
49
+    text-align: left;
50
+  }
51
+
52
+  .preferences_back {
53
+    background: none repeat scroll 0 0 @color-settings-return-background;
54
+    color: white;
55
+    border: 0 none;
56
+    .rounded-corners;
57
+    cursor: pointer;
58
+    display: inline-block;
59
+    margin: 2px 4px;
60
+    padding: 0.5em;
61
+
62
+    a {
63
+      display: block;
64
+      color: @color-settings-return-font;
65
+    }
66
+
67
+    a::first-letter {
68
+      text-transform: uppercase;
69
+    }
70
+  }
71
+
72
+}
73
+
74
+@media screen and (max-width: 75em) {
75
+  .preferences_back {
76
+	   clear: both;
77
+   }
78
+}

+ 232
- 0
searx/static/themes/simple/less/search.less Datei anzeigen

@@ -0,0 +1,232 @@
1
+/*
2
+* searx, A privacy-respecting, hackable metasearch engine
3
+*/
4
+
5
+#search  {
6
+  padding: 0 2em;
7
+  margin: 0;
8
+  background: #f7f7f7;
9
+  border-bottom: 1px solid #d7d7d7;
10
+}
11
+
12
+#search_wrapper {
13
+  padding: 10px 0;
14
+}
15
+
16
+.search_box {
17
+  margin: 0 12px 0 0;
18
+  display: inline-flex;
19
+  flex-direction: row;
20
+
21
+  white-space: nowrap;
22
+  /*
23
+  &:has(q:focus) {
24
+  box-shadow: 0px 0px 5px #CCC;
25
+}
26
+*/
27
+}
28
+
29
+#q, #send_search {
30
+  display: block !important;
31
+  border-collapse: separate;
32
+  box-sizing: border-box;
33
+  position: relative;
34
+
35
+  margin: 0;
36
+  padding: 2px;
37
+  height: 2.2em;
38
+  background: none repeat scroll 0 0 @color-search-background;
39
+  border: 1px solid @color-search-border;
40
+  border-radius: 0px;
41
+  outline: none;
42
+  color: @color-search-font;
43
+  font-size: 16px;
44
+  z-index: 2;
45
+}
46
+
47
+#q {
48
+  outline: medium none;
49
+  padding-left: 8px;
50
+  padding-right: 0px !important;
51
+  border-right: none;
52
+  width: @search-width;
53
+}
54
+
55
+#send_search {
56
+  border-left: none;
57
+  width: 2.2em;
58
+
59
+  &:hover {
60
+    cursor: pointer;
61
+    background-color: @color-search-border;
62
+    color: @color-base-light;
63
+  }
64
+}
65
+
66
+.no-js #send_search {
67
+  width: auto !important;
68
+}
69
+
70
+.search_filters {
71
+  display: inline-block;
72
+  vertical-align: middle;
73
+}
74
+
75
+@media screen and (max-width: 75em) {
76
+
77
+  #categories {
78
+    font-size: 90%;
79
+    clear: both;
80
+
81
+    .checkbox_container {
82
+      margin-top: 2px;
83
+      margin: auto;
84
+    }
85
+  }
86
+
87
+  html.touch {
88
+    #main_index, #main_results {
89
+
90
+      #categories_container {
91
+        width: 1000px;
92
+        width: -moz-max-content;
93
+        width: -webkit-max-content;
94
+        width: max-content;
95
+
96
+        .category {
97
+          display: inline-block;
98
+          width: auto;
99
+        }
100
+      }
101
+
102
+      #categories {
103
+        width: 100%;
104
+        margin: 0;
105
+        text-align: left;
106
+        overflow-x: scroll;
107
+        overflow-y: hidden;
108
+        -webkit-overflow-scrolling: touch;
109
+      }
110
+    }
111
+  }
112
+
113
+}
114
+
115
+@media screen and (max-width: @results-width) {
116
+
117
+  #search {
118
+    width: 100%;
119
+    margin: 0;
120
+    padding: 0.1em 0 0 0;
121
+  }
122
+
123
+  #search_wrapper {
124
+    width: 100%;
125
+    margin: 0 0 0.7em 0;
126
+    padding: 0;
127
+  }
128
+
129
+  .search_box {
130
+    // hack, should bew 100% ?
131
+    width: 99%;
132
+    margin: 0.1em;
133
+    padding: 0 0.1em 0 0;
134
+    display: flex;
135
+    flex-direction: row;
136
+  }
137
+
138
+  #q {
139
+    width: auto !important;
140
+    flex: 1;
141
+  }
142
+
143
+  .search_filters {
144
+    display: block;
145
+    margin: 0.5em;
146
+  }
147
+
148
+  .language, .time_range {
149
+    width: 45%;
150
+  }
151
+
152
+  .category {
153
+    display: block;
154
+    width: 90%;
155
+
156
+    label {
157
+      border-bottom: 0;
158
+    }
159
+  }
160
+
161
+}
162
+
163
+#categories {
164
+  margin: 0 10px 0 0;
165
+  .disable-user-select;
166
+
167
+  &::-webkit-scrollbar {
168
+    width: 0;
169
+    height: 0;
170
+  }
171
+}
172
+
173
+.category {
174
+  display: inline-block;
175
+  position: relative;
176
+  margin: 0 3px;
177
+  padding: 0px;
178
+
179
+  input {
180
+    display: none;
181
+  }
182
+
183
+  label {
184
+    cursor: pointer;
185
+    padding: 4px 10px;
186
+    margin: 0;
187
+    display: block;
188
+    text-transform: capitalize;
189
+    font-size: 0.9em;
190
+    border-bottom: 2px solid transparent;
191
+    .disable-user-select;
192
+  }
193
+
194
+  input[type="checkbox"]:focus + label {
195
+    box-shadow: 0px 0px 8px #3498DB;
196
+  }
197
+
198
+  /*label:hover {
199
+  border-bottom: 2px solid @color-categories-item-border-unselected-hover;
200
+  }*/
201
+
202
+  input[type="checkbox"]:checked + label {
203
+    background: @color-categories-item-selected;
204
+    color: @color-categories-item-selected-font;
205
+    border-bottom: 2px solid @color-categories-item-border-selected;
206
+  }
207
+}
208
+
209
+#categories_container {
210
+
211
+  position: relative;
212
+
213
+  .help {
214
+    position: absolute;
215
+    width: 100%;
216
+    bottom: -20px;
217
+    overflow: hidden;
218
+
219
+    opacity: 0;
220
+    transition: opacity 1s ease;
221
+
222
+    font-size: 0.8em;
223
+    text-position: center;
224
+    background: white;
225
+  }
226
+
227
+  &:hover .help {
228
+    opacity: 0.8;
229
+    transition: opacity 1s ease;
230
+  }
231
+
232
+}

+ 8
- 0
searx/static/themes/simple/less/stats.less Datei anzeigen

@@ -0,0 +1,8 @@
1
+.percentage {
2
+  position: relative;
3
+  width: 300px;
4
+
5
+  div {
6
+    background: @color-percentage-div-background;
7
+  }
8
+}

+ 6
- 0
searx/static/themes/simple/less/style-rtl.less Datei anzeigen

@@ -0,0 +1,6 @@
1
+@import "style.less";
2
+
3
+#search_submit {
4
+	left: 1px;
5
+	right:auto;
6
+}

+ 709
- 0
searx/static/themes/simple/less/style.less Datei anzeigen

@@ -0,0 +1,709 @@
1
+/*
2
+* searx, A privacy-respecting, hackable metasearch engine
3
+*
4
+* To convert "style.less" to "style.css" run: $make styles
5
+*/
6
+
7
+@import "normalize.less";
8
+
9
+@import "definitions.less";
10
+
11
+@import "mixins.less";
12
+
13
+@import "code.less";
14
+
15
+@import "toolkit.less";
16
+
17
+@import "autocomplete.less";
18
+
19
+// ion-icon
20
+@import "ion.less";
21
+
22
+.ion-icon-big {
23
+  .ion-icon;
24
+  font-size: 149%;
25
+}
26
+
27
+// for index.html template
28
+@import "index.less";
29
+
30
+// for preferences.html template
31
+@import "preferences.less";
32
+
33
+// Search-Field
34
+@import "search.less";
35
+
36
+// Main LESS-Code
37
+html {
38
+  font-family: arial, sans-serif;
39
+  font-size: 0.9em;
40
+  .text-size-adjust;
41
+  color: @color-font;
42
+  padding: 0;
43
+  margin: 0;
44
+}
45
+
46
+body, main {
47
+  padding: 0;
48
+  margin: 0;
49
+}
50
+
51
+main {
52
+  width: 100%;
53
+  // position: absolute;
54
+}
55
+
56
+footer {
57
+  // position:absolute;
58
+	bottom:0;
59
+	width:100%;
60
+	height:50px;
61
+}
62
+
63
+#main_preferences, #main_about, #main_stats {
64
+  margin: 3em;
65
+  width: auto;
66
+}
67
+
68
+footer {
69
+  bottom: 0;
70
+  height: 3em;
71
+  margin: 1em 0;
72
+  padding: 1em 0;
73
+  clear: both;
74
+  width: 100%;
75
+  text-align: center;
76
+
77
+  p {
78
+    font-size: 0.9em;
79
+  }
80
+}
81
+
82
+#main_preferences h1, #main_stats h1 {
83
+  background: url('../img/searx.png') no-repeat;
84
+  background-size: auto 75%;
85
+  min-height: 40px;
86
+  margin: 0 auto;
87
+
88
+  span {
89
+      visibility: hidden;
90
+  }
91
+}
92
+
93
+input[type="submit"], #results button[type="submit"] {
94
+  padding: 0.5rem;
95
+  margin: 2px 4px;
96
+  display: inline-block;
97
+  background: @color-download-button-background;
98
+  color: @color-download-button-font;
99
+  .rounded-corners;
100
+  border: 0;
101
+  cursor: pointer;
102
+}
103
+
104
+a {
105
+  text-decoration: none;
106
+  color: @color-url-font;
107
+
108
+  &:visited {
109
+    color: @color-url-visited-font;
110
+
111
+    .highlight {
112
+      color: @color-url-visited-font;
113
+    }
114
+  }
115
+}
116
+
117
+article[data-vim-selected] {
118
+  background: #f7f7f7;
119
+}
120
+
121
+article[data-vim-selected]::before {
122
+  position: absolute;
123
+  left: 1em;
124
+  padding: 2px;
125
+  content: ">";
126
+  font-weight: bold;
127
+  color: @color-base;
128
+}
129
+
130
+article.result-images[data-vim-selected] {
131
+  background: @color-base;
132
+}
133
+
134
+article.result-images[data-vim-selected]::before {
135
+  display: none;
136
+  content: "";
137
+}
138
+
139
+.result {
140
+  margin: 19px 0 18px 0;
141
+  padding: 0;
142
+
143
+  h3 {
144
+    font-size: 1.1em;
145
+    word-wrap:break-word;
146
+    margin: 5px 0 1px 0;
147
+    padding: 0;
148
+    margin-bottom: 0;
149
+
150
+    a {
151
+      color: @color-result-link-font;
152
+      font-weight: normal;
153
+      font-size: 1.1em;
154
+
155
+      &:visited {
156
+        color: @color-result-link-visited-font;
157
+      }
158
+
159
+      &:focus, &:hover {
160
+        text-decoration: underline;
161
+        border: none;
162
+        -webkit-box-shadow: none;
163
+        box-shadow: none;
164
+        outline:none;
165
+      }
166
+    }
167
+  }
168
+
169
+  .cache_link, .proxyfied_link {
170
+    font-size: 0.9em !important;
171
+  }
172
+
173
+  .content, .stat, .altlink {
174
+    font-size: 0.9em;
175
+    margin: 0;
176
+    padding: 0;
177
+    max-width: 54em;
178
+    word-wrap:break-word;
179
+    line-height: 1.24;
180
+
181
+    .highlight {
182
+      color: @color-black;
183
+      background: inherit;
184
+      font-weight: bold;
185
+    }
186
+  }
187
+
188
+  .codelines {
189
+    .highlight {
190
+      color: inherit;
191
+      background: inherit;
192
+      font-weight: normal;
193
+    }
194
+  }
195
+
196
+  .url {
197
+    font-size: 0.9em;
198
+    margin: 0 0 3px 0;
199
+    padding: 0;
200
+    max-width: 54em;
201
+    word-wrap:break-word;
202
+    color: @color-result-url-font;
203
+  }
204
+
205
+  .published_date {
206
+    font-size: 0.8em;
207
+    color: @color-result-publishdate-font;
208
+  }
209
+
210
+  img {
211
+
212
+    &.thumbnail {
213
+      float: left;
214
+      padding: 0 5px 10px 0;
215
+      width: 20em;
216
+      min-width: 20em;
217
+      min-height: 8em;
218
+      // background: @color-base-light;
219
+    }
220
+
221
+    &.image {
222
+      float: left;
223
+      padding: 0 5px 10px 0;
224
+      width: 100px;
225
+      max-height: 100px;
226
+      object-fit: scale-down;
227
+      object-position: right top;
228
+    }
229
+
230
+  }
231
+
232
+  .break {
233
+      clear: both;
234
+  }
235
+
236
+}
237
+
238
+.category-social .image {
239
+  width: auto !important;
240
+  min-width: 48px;
241
+  min-height: 48px;
242
+  padding: 0 5px 25px 0 !important;
243
+}
244
+
245
+.result-videos .content {
246
+  overflow: hidden;
247
+}
248
+
249
+.engines {
250
+  float: right;
251
+  color: @color-engines-font;
252
+
253
+  span {
254
+    font-size: smaller;
255
+    margin: 0 0.5em 0 0;
256
+  }
257
+}
258
+
259
+.small_font {
260
+  font-size: 0.8em;
261
+}
262
+
263
+.highlight {
264
+  color: @color-highlight;
265
+  background: inherit;
266
+  font-weight: bold;
267
+}
268
+
269
+.result-images {
270
+  display: inline-block;
271
+  margin: 0;
272
+  padding: 0;
273
+  position: relative;
274
+  max-height: 200px;
275
+
276
+  img {
277
+    float: inherit;
278
+    margin: 0;
279
+    padding: 0;
280
+    border: none;
281
+    max-height: 200px;
282
+    background: @color-base-dark;
283
+  }
284
+
285
+  span a {
286
+    display: none;
287
+    color: @color-result-image-span-font;
288
+  }
289
+
290
+  &:hover span a {
291
+    display: block;
292
+    position: absolute;
293
+    bottom: 0;
294
+    right: 0;
295
+    padding: 4px;
296
+    margin: 0 0 4px 4px;
297
+    background-color: @color-result-image-span-background-hover;
298
+    font-size: 0.7em;
299
+  }
300
+}
301
+
302
+.torrent_result {
303
+  border-left: 10px solid @color-result-torrent-border;
304
+  padding-left: 3px;
305
+
306
+  p {
307
+    margin: 3px;
308
+    font-size: 0.8em;
309
+  }
310
+
311
+  a {
312
+    color: @color-result-link-font;
313
+
314
+    &:hover {
315
+      text-decoration: underline;
316
+    }
317
+
318
+    &:visited {
319
+      color: @color-result-link-visited-font;
320
+    }
321
+  }
322
+}
323
+
324
+#results {
325
+  margin: 2em 2em 20px 2em;
326
+  padding: 0;
327
+  width: @results-width;
328
+}
329
+
330
+#suggestions {
331
+
332
+  .wrapper {
333
+    display: flex;
334
+    flex-flow: row wrap;
335
+    justify-content: flex-end;
336
+
337
+    form {
338
+      display: inline-block;
339
+      flex: 1 1 50%;
340
+    }
341
+  }
342
+}
343
+
344
+#suggestions, #answers, #corrections {
345
+  max-width: @results-width;
346
+}
347
+
348
+#suggestions, #answers, #infoboxes, #corrections {
349
+
350
+  input {
351
+    padding: 0;
352
+    margin: 3px;
353
+    font-size: 0.9em;
354
+    display: inline-block;
355
+    background: transparent;
356
+    color: @color-result-search-url-font;
357
+    cursor: pointer;
358
+  }
359
+
360
+  input[type="submit"], .infobox .url a {
361
+    color: @color-result-link-font;
362
+    text-decoration: none;
363
+    font-size: 0.9rem;
364
+
365
+    &:hover {
366
+      text-decoration: underline;
367
+    }
368
+  }
369
+
370
+}
371
+
372
+#corrections {
373
+  display: flex;
374
+  flex-flow: row wrap;
375
+  margin: 1em 0;
376
+
377
+  h4, input[type="submit"] {
378
+    display: inline-block;
379
+    margin: 0 0.5em 0 0;
380
+  }
381
+
382
+  input[type="submit"]::after {
383
+    content: ", "
384
+  }
385
+
386
+}
387
+
388
+#suggestions .title, #search_url .title, #apis .title {
389
+  margin: 2em 0 0.5em 0;
390
+  color: @color-font;
391
+}
392
+
393
+#answers {
394
+  margin: 10px 8px 10px 8px;
395
+  border: 1px solid #ddd;
396
+  padding: 0.9em;
397
+  box-shadow: 0px 0px 5px #CCC;
398
+
399
+  h4 {
400
+    display: none;
401
+  }
402
+
403
+  .answer {
404
+    display: block;
405
+    font-size: 1.2em;
406
+    font-weight: bold;
407
+  }
408
+}
409
+
410
+#answers, #infoboxes {
411
+  form {
412
+    min-width: 210px;
413
+  }
414
+}
415
+
416
+#sidebar {
417
+  position: absolute;
418
+  top: 100px;
419
+  left: 57em;
420
+
421
+  margin: 0px 2px 5px 5px;
422
+  padding: 0px 2px 2px;
423
+  max-width: 25em;
424
+  word-wrap: break-word;
425
+
426
+  .infobox {
427
+    margin: 10px 0 10px;
428
+    border: 1px solid #ddd;
429
+    padding: 0.9em;
430
+    font-size: 0.9em;
431
+    box-shadow: 0px 0px 5px #CCC;
432
+
433
+    h2 {
434
+      margin: 0 0 .5em 0;
435
+    }
436
+
437
+    img {
438
+      max-width: 100%;
439
+      max-height: 12em;
440
+      display: block;
441
+      margin: 0;
442
+      padding: 0;
443
+    }
444
+
445
+    dl {
446
+      margin: 0.5em 0;
447
+    }
448
+
449
+    dt {
450
+      display: inline;
451
+      margin: 0.5em 0.25em 0.5em 0;
452
+      padding: 0;
453
+      font-weight: bold;
454
+    }
455
+
456
+    dd {
457
+      display: inline;
458
+      margin: 0.5em 0;
459
+      padding: 0;
460
+    }
461
+
462
+    input {
463
+      font-size: 1em;
464
+    }
465
+
466
+    br {
467
+      clear: both;
468
+    }
469
+
470
+    .attributes, .urls {
471
+      clear: both;
472
+    }
473
+
474
+  }
475
+}
476
+
477
+#search_url {
478
+  margin-top: 8px;
479
+
480
+  div {
481
+    display: block;
482
+    border: 1px solid @color-result-search-url-border;
483
+    padding: 4px;
484
+    color: @color-result-search-url-font;
485
+    width: 100%;
486
+    display: block;
487
+    margin: 0.1em;
488
+    overflow: hidden;
489
+    height: 1.2em;
490
+    line-height: 1.2em;
491
+
492
+    pre {
493
+      display: block;
494
+      width: 200em;
495
+      font-size: 0.8em;
496
+      word-break: break-all;
497
+      margin: 0.1em;
498
+      .select-all-on-focus();
499
+    }
500
+  }
501
+}
502
+
503
+#linkto_preferences {
504
+  position: absolute;
505
+  right: 10px;
506
+  top: 0.9em;
507
+  padding: 0;
508
+  border: 0;
509
+  display: block;
510
+
511
+  font-size: 1.2em;
512
+  color: @color-search-font;
513
+
514
+  a:link *, a:hover *, a:visited *, a:active * {
515
+    color: @color-search-font;
516
+  }
517
+}
518
+
519
+#pagination {
520
+  clear: both;
521
+
522
+  br {
523
+    clear: both;
524
+  }
525
+}
526
+
527
+#apis {
528
+  margin-top: 8px;
529
+  clear: both;
530
+}
531
+
532
+#backToTop {
533
+  border: 1px solid #ddd;
534
+  margin: 0 0 0 2em;
535
+  padding: 0;
536
+  font-size: 1em;
537
+  box-shadow: 0px 0px 5px #CCC;
538
+  background: white;
539
+  position: fixed;
540
+  bottom: 85px;
541
+  left: @results-width;
542
+  transition: opacity 0.5s;
543
+  opacity: 0;
544
+
545
+  a {
546
+    display: block;
547
+    margin: 0;
548
+    padding: 0.6em;
549
+  }
550
+}
551
+
552
+@media screen and (max-width: 75em) {
553
+
554
+  #main_preferences, #main_about, #main_stats {
555
+    margin: 0.5em;
556
+    width: auto;
557
+  }
558
+
559
+  #suggestions, #answers {
560
+    margin-top: 1em;
561
+  }
562
+
563
+  #infoboxes {
564
+    position: inherit;
565
+    max-width: inherit;
566
+
567
+    .infobox {
568
+      clear:both;
569
+
570
+      img {
571
+        float: left;
572
+        max-width: 10em;
573
+        margin: 0.5em 0.5em 0.5em 0;
574
+      }
575
+    }
576
+
577
+  }
578
+
579
+  #sidebar {
580
+    position: static;
581
+    max-width: @results-width;
582
+    margin: 0 0 2px 0;
583
+    padding: 0;
584
+    float: none;
585
+    border: none;
586
+    width: auto;
587
+
588
+    input {
589
+      border: 0;
590
+    }
591
+  }
592
+
593
+  #apis {
594
+    display: none;
595
+  }
596
+
597
+  #search_url {
598
+    display: none;
599
+  }
600
+
601
+  .result {
602
+    border-bottom: 1px solid @color-result-top-border;
603
+    margin: 0;
604
+    padding-top: 8px;
605
+    padding-bottom: 6px;
606
+
607
+    h3 {
608
+      margin: 0 0 1px 0;
609
+    }
610
+
611
+    .thumbnail {
612
+      max-width: 98%;
613
+    }
614
+
615
+    .url {
616
+
617
+      span.url {
618
+        display: block;
619
+        white-space: nowrap;
620
+        text-overflow: ellipsis;
621
+        overflow: hidden;
622
+        width: 100%;
623
+      }
624
+
625
+      a {
626
+        float: right;
627
+        padding: 0 0.5em;
628
+      }
629
+
630
+    }
631
+
632
+    .engines {
633
+      float: right;
634
+      padding: 0 0 3px 0;
635
+    }
636
+  }
637
+
638
+  .result-images {
639
+    border-bottom: none !important;
640
+  }
641
+
642
+  .image_result {
643
+    max-width: 98%;
644
+    img {
645
+      max-width: 98%;
646
+    }
647
+  }
648
+}
649
+
650
+
651
+@media screen and (max-width: @results-width) {
652
+
653
+  article[data-vim-selected]::before {
654
+    display: none;
655
+    content: "";
656
+  }
657
+
658
+  #linkto_preferences {
659
+    display: none;
660
+    postion: fixed !important;
661
+    top: 100px;
662
+    right: 0px;
663
+  }
664
+
665
+  #sidebar {
666
+    margin: 0 5px 2px 5px;
667
+  }
668
+
669
+  #corrections {
670
+    margin: 1em 5px 1em 5px;
671
+  }
672
+
673
+  #results {
674
+    margin: 0;
675
+    padding: 0;
676
+    width: initial;
677
+  }
678
+
679
+  #backToTop {
680
+    left: 40em;
681
+    bottom: 35px;
682
+  }
683
+
684
+  .result {
685
+    padding: 8px 10px 6px 10px;
686
+  }
687
+
688
+  .result-images {
689
+    margin: 0;
690
+    padding: 0;
691
+    border: none;
692
+  }
693
+
694
+}
695
+
696
+@media screen and (max-width: 35em) {
697
+
698
+  .result-videos {
699
+
700
+    img.thumbnail {
701
+      float: none !important;
702
+    }
703
+    .content {
704
+      overflow: inherit;
705
+    }
706
+
707
+  }
708
+
709
+}

+ 346
- 0
searx/static/themes/simple/less/toolkit.less Datei anzeigen

@@ -0,0 +1,346 @@
1
+// other solution :  http://stackoverflow.com/questions/1577598/how-to-hide-parts-of-html-when-javascript-is-disabled/13857783#13857783
2
+html.no-js .hide_if_nojs {
3
+  display: none;
4
+}
5
+
6
+html.js .show_if_nojs {
7
+  display: none;
8
+}
9
+
10
+.center {
11
+  text-align: center;
12
+}
13
+
14
+.right {
15
+  float: right ;
16
+}
17
+
18
+.left {
19
+  float: left;
20
+}
21
+
22
+.invisible {
23
+  display: none;
24
+}
25
+
26
+.danger {
27
+  background-color: @color-error-background;
28
+}
29
+
30
+.badge {
31
+  display: inline-block;
32
+  color: #fff;
33
+  background-color: #777;
34
+  text-align: center;
35
+  white-space: nowrap;
36
+  vertical-align: baseline;
37
+  min-width: 10px;
38
+  padding: 1px 5px;
39
+  border-radius: 5px;
40
+}
41
+
42
+// table
43
+table {
44
+
45
+  width: 100%;
46
+
47
+  &.striped {
48
+    tr {
49
+      border-bottom: 1px solid @color-settings-tr-hover;
50
+    }
51
+  }
52
+}
53
+
54
+th {
55
+  padding: 0.4em;
56
+}
57
+
58
+td {
59
+  padding: 0 4px;
60
+}
61
+
62
+tr {
63
+  &:hover {
64
+    background: @color-settings-tr-hover;
65
+  }
66
+}
67
+
68
+// dialog
69
+.dialog() {
70
+  position: relative;
71
+  width: 70%;
72
+  padding: 1em 1em 1em 2.7em;
73
+  margin: 0em 8% 1em 8%;
74
+  border: 1px solid black;
75
+  border-radius: 4px;
76
+  text-align: left;
77
+
78
+  &:before {
79
+    position: absolute;
80
+    top: 0.5em;
81
+    left: 0.5em;
82
+    font-family:"ion";
83
+    font-size: 1.5em;
84
+  }
85
+
86
+  .close {
87
+    float:right;
88
+    position: relative;
89
+    top: -3px;
90
+    color: inherit;
91
+    font-size: 1.5em;
92
+  }
93
+
94
+  ul, ol, p {
95
+    margin: 1px 0 0 0;
96
+  }
97
+
98
+}
99
+
100
+.dialog-error {
101
+  .dialog();
102
+  color: @color-error;
103
+  background: @color-error-background;
104
+  border-color: @color-error;
105
+  .ion-error();
106
+}
107
+
108
+.dialog-warning {
109
+  .dialog();
110
+  color: @color-warning;
111
+  background: @color-warning-background;
112
+  border-color: @color-warning;
113
+  .ion-warning();
114
+}
115
+
116
+// btn-collapse
117
+.btn-collapse {
118
+  cursor: pointer;
119
+}
120
+
121
+//
122
+.scrollx {
123
+  overflow-x: auto;
124
+  overflow-y: hidden;
125
+  display: block;
126
+  padding: 0;
127
+  margin: 0;
128
+  border: none;
129
+}
130
+
131
+// tabs
132
+.tabs .tabs > label {
133
+  font-size: 90%;
134
+}
135
+
136
+.tabs {
137
+  .flexbox();
138
+  flex-wrap: wrap;
139
+  width: 100%;
140
+  min-width: 100%;
141
+
142
+  & > * {
143
+    order: 2;
144
+  }
145
+
146
+  & > input[type=radio] {
147
+    display: none;
148
+  }
149
+
150
+  & > label {
151
+    order: 1;
152
+    padding: 0.7em;
153
+    margin: 0 0.7em;
154
+    letter-spacing:0.5px;
155
+    text-transform: uppercase;
156
+
157
+    border: solid white;
158
+    border-width: 0px 0px 2px 0;
159
+
160
+    .disable-user-select();
161
+    cursor: pointer;
162
+  }
163
+
164
+  & > label:hover {
165
+    border-bottom: 2px solid @color-categories-item-border-selected;
166
+  }
167
+
168
+  & > section {
169
+    min-width: 100%;
170
+    padding: 0.7rem 0;
171
+    box-sizing: border-box;
172
+    border-top: 1px solid black;
173
+    display: none;
174
+  }
175
+
176
+  // default selection
177
+  & > label:last-of-type {
178
+    border-bottom: 2px solid @color-categories-item-border-selected;
179
+    background: @color-categories-item-selected;
180
+    color: @color-categories-item-selected-font;
181
+    font-weight: bold;
182
+    letter-spacing:-0.1px;
183
+  }
184
+
185
+  & > section:last-of-type {
186
+    display: block;
187
+  }
188
+
189
+}
190
+
191
+html body .tabs > input:checked {
192
+  ~ section {
193
+    display: none;
194
+  }
195
+  ~ label {
196
+    position: inherited;
197
+    background: inherit;
198
+    border-bottom: 2px solid transparent;
199
+    font-weight: normal;
200
+    color: inherit;
201
+
202
+    &:hover {
203
+      border-bottom: 2px solid @color-categories-item-border-selected;
204
+    }
205
+  }
206
+  + label {
207
+    border-bottom: 2px solid @color-categories-item-border-selected;
208
+    background: @color-categories-item-selected;
209
+    color: @color-categories-item-selected-font;
210
+    font-weight: bold;
211
+    letter-spacing:-0.1px;
212
+  }
213
+  + label + section {
214
+    display: block;
215
+  }
216
+}
217
+
218
+// select
219
+select {
220
+  height: 28px;
221
+  margin: 0 1em 0 0;
222
+  padding: 2px 8px 2px 0 !important;
223
+  color: @color-search-font;
224
+  font-size: 12px;
225
+  z-index: 2;
226
+
227
+  &:hover, &:focus {
228
+    cursor: pointer;
229
+  }
230
+}
231
+
232
+@supports ((background-position-x: 100%) and ((appearance: none) or (-webkit-appearance: none) or (-moz-appearance: none))) {
233
+
234
+  select {
235
+    appearance: none;
236
+    -webkit-appearance: none;
237
+    -moz-appearance: none;
238
+    border: none;
239
+    border-bottom: 1px solid #d7d7d7;
240
+    background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeD0iMHB4IiB5PSIwcHgiIHdpZHRoPSI1MTJweCIgaGVpZ2h0PSI1MTJweCIgdmlld0JveD0iMCAwIDUxMiA1MTIiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDUxMiA1MTIiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxnPjxwb2x5Z29uIHBvaW50cz0iMTI4LDE5MiAyNTYsMzIwIDM4NCwxOTIiLz48L2c+PC9zdmc+Cg==) no-repeat;
241
+    background-position-x: 105%;
242
+    background-size: 2em;
243
+    background-origin: content-box;
244
+    outline: medium none;
245
+
246
+    &:hover, &:focus {
247
+      border-bottom: 1px solid @color-search-border;
248
+    }
249
+
250
+  }
251
+
252
+}
253
+
254
+// checkbox-onoff
255
+@supports (border-radius: 50px) {
256
+  .checkbox-onoff {
257
+    display: inline-block;
258
+    width: 40px;
259
+    height: 10px;
260
+    background: #dcdcdc;
261
+    margin: 8px auto;
262
+    position: relative;
263
+    border-radius: 50px;
264
+    label {
265
+      display: block;
266
+      width: 20px;
267
+      height: 20px;
268
+      position: absolute;
269
+      top: -5px;
270
+      cursor: pointer;
271
+      border-radius: 50px;
272
+      box-shadow: 0px 3px 5px 0px rgba(0, 0, 0, 0.3);
273
+      transition: all 0.4s ease;
274
+
275
+      left: 27px;
276
+      background-color: #3498DB;
277
+    }
278
+    input[type=checkbox] {
279
+      visibility: hidden;
280
+      &:checked + label {
281
+        left: -5px;
282
+        background: #dcdcdc;
283
+      }
284
+    }
285
+  }
286
+}
287
+
288
+// checkbox
289
+@supports (transform: rotate(-45deg)) {
290
+  .checkbox {
291
+    width: 20px;
292
+    position: relative;
293
+    margin: 20px auto;
294
+    label {
295
+      width: 20px;
296
+      height: 20px;
297
+      cursor: pointer;
298
+      position: absolute;
299
+      top: 0;
300
+      left: 0;
301
+      background: white;
302
+      border-radius: 4px;
303
+      box-shadow: inset 0px 1px 1px white, 0px 1px 4px rgba(0,0,0,0.5);
304
+      &:after {
305
+        content: '';
306
+        width: 9px;
307
+        height: 5px;
308
+        position: absolute;
309
+        top: 4px;
310
+        left: 4px;
311
+        border: 3px solid #333;
312
+        border-top: none;
313
+        border-right: none;
314
+        background: transparent;
315
+        opacity: 0;
316
+        transform: rotate(-45deg);
317
+      }
318
+    }
319
+
320
+    input[type=checkbox] {
321
+      visibility: hidden;
322
+      &:checked + label:after {
323
+        border-color: #3498DB;
324
+        opacity: 1;
325
+      }
326
+    }
327
+
328
+    // disabled : can't be focused, show only the check mark
329
+    input[disabled] + label  {
330
+      background-color: transparent !important;
331
+      box-shadow: none !important;
332
+      cursor: inherit;;
333
+    }
334
+
335
+    // if not checked and possible to checked then display a "light" check mark on hover
336
+    input:not(:checked):not([readonly]):not([disabled]) + label:hover::after {
337
+      opacity: 0.5;
338
+    }
339
+  }
340
+}
341
+
342
+@media screen and (max-width: 50em) {
343
+  .tabs > label {
344
+    width: 100%;
345
+  }
346
+}

+ 1
- 0
searx/static/themes/simple/magnet.svg Datei anzeigen

@@ -0,0 +1 @@
1
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" viewBox="0 0 32 40" enable-background="new 0 0 32 32" xml:space="preserve"><path d="M21.11,21.157h5.002v-6.867c-0.028-1.706-0.61-3.807-2.172-5.841c-1.539-2.014-4.315-3.72-7.939-3.687  C12.374,4.731,9.598,6.437,8.06,8.45c-1.562,2.034-2.145,4.136-2.174,5.842v6.866h5v-6.866c-0.027-0.377,0.303-1.789,1.099-2.748  c0.819-0.979,1.848-1.747,4.014-1.778c2.165,0.032,3.195,0.799,4.013,1.778c0.798,0.959,1.126,2.372,1.099,2.748V21.157  L21.11,21.157z M26.112,27.236c0,0,0-2.354,0-5.079H21.11c0,2.727,0,5.08,0,5.08l5.004-0.001H26.112z M5.886,27.237h5  c0,0,0-2.354,0-5.08h-5C5.886,24.884,5.886,27.237,5.886,27.237z"/><text x="0" y="47" fill="#000000" font-size="5px" font-weight="bold" font-family="'Helvetica Neue', Helvetica, Arial-Unicode, Arial, Sans-serif">Created by Dmitry Baranovskiy</text><text x="0" y="52" fill="#000000" font-size="5px" font-weight="bold" font-family="'Helvetica Neue', Helvetica, Arial-Unicode, Arial, Sans-serif">from the Noun Project</text></svg>

+ 20
- 0
searx/static/themes/simple/package.json Datei anzeigen

@@ -0,0 +1,20 @@
1
+{
2
+  "devDependencies": {
3
+    "grunt": "~1.0.1",
4
+    "grunt-contrib-concat": "~1.0.1",
5
+    "grunt-contrib-cssmin": "^2.2.1",
6
+    "grunt-contrib-jshint": "~1.1.0",
7
+    "grunt-contrib-less": "^1.4.1",
8
+    "grunt-contrib-uglify": "~3.0.1",
9
+    "grunt-contrib-watch": "~1.0.0",
10
+    "grunt-webfont": "^1.6.0",
11
+    "ionicons-npm": "^2.0.1",
12
+    "jslint": "^0.10.3",
13
+    "less-plugin-clean-css": "^1.5.1"
14
+  },
15
+  "scripts": {
16
+    "build": "npm install && grunt",
17
+    "start": "grunt watch",
18
+    "test": "grunt"
19
+  }
20
+}

+ 1
- 1
searx/templates/oscar/preferences.html Datei anzeigen

@@ -171,7 +171,7 @@
171 171
                                         {{ checkbox_toggle('engine_' + search_engine.name|replace(' ', '_') + '__' + categ|replace(' ', '_'), (search_engine.name, categ) in disabled_engines) }}
172 172
                                     </td>
173 173
                                     <th>{{ search_engine.name }}</th>
174
-				    <td>{{ shortcuts[search_engine.name] }}</td>
174
+				    <td class="name">{{ shortcuts[search_engine.name] }}</td>
175 175
 				    <td><input type="checkbox" {{ "checked" if current_language == 'all' or current_language in search_engine.supported_languages or current_language.split('-')[0] in search_engine.supported_languages else ""}} readonly="readonly" disabled="disabled"></td>
176 176
 				    <td><input type="checkbox" {{ "checked" if search_engine.safesearch==True else ""}} readonly="readonly" disabled="disabled"></td>
177 177
 				    <td><input type="checkbox" {{ "checked" if search_engine.time_range_support==True else ""}} readonly="readonly" disabled="disabled"></td>

+ 9
- 0
searx/templates/simple/404.html Datei anzeigen

@@ -0,0 +1,9 @@
1
+{% extends "simple/base.html" %}
2
+{% block content %}
3
+<div class="center">
4
+    <h1>{{ _('Page not found') }}</h1>
5
+    {% autoescape false %}
6
+    <p>{{ _('Go to %(search_page)s.', search_page='<a href="{}">{}</a>'.decode('utf-8').format(url_for('index'), _('search page'))) }}</p>
7
+    {% endautoescape %}
8
+</div>
9
+{% endblock %}

+ 4
- 0
searx/templates/simple/about.html Datei anzeigen

@@ -0,0 +1,4 @@
1
+{% extends 'simple/base.html' %}
2
+{% block content %}
3
+{% include '__common__/about.html' %}
4
+{% endblock %}

+ 61
- 0
searx/templates/simple/base.html Datei anzeigen

@@ -0,0 +1,61 @@
1
+<!DOCTYPE html>
2
+<html class="no-js" lang="en" {% if rtl %} dir="rtl"{% endif %}>
3
+<head>
4
+  <meta charset="UTF-8" />
5
+  <meta name="description" content="searx - a privacy-respecting, hackable metasearch engine">
6
+  <meta name="keywords" content="searx, search, search engine, metasearch, meta search">
7
+  <meta name="generator" content="searx/{{ searx_version }}">
8
+  <meta name="referrer" content="no-referrer">
9
+  <meta name="robots" content="noarchive">
10
+  <meta name="viewport" content="width=device-width, maximum-scale=1.0, user-scalable=1">
11
+  <meta name="HandheldFriendly" content="True">
12
+  <meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">
13
+  <title>{% block title %}{% endblock %}searx</title>
14
+  {% if rtl %}
15
+  <link rel="stylesheet" href="{{ url_for('static', filename='css/searx-rtl.min.css') }}" type="text/css" media="screen" />
16
+  {% else %}
17
+  <link rel="stylesheet" href="{{ url_for('static', filename='css/searx.min.css') }}" type="text/css" media="screen" />
18
+  {% endif %}
19
+  {% block styles %}{% endblock %}
20
+  {% block meta %}{% endblock %}
21
+  {% block head %}
22
+  <link title="{{ instance_name }}" type="application/opensearchdescription+xml" rel="search" href="{{ url_for('opensearch') }}"/>
23
+  {% endblock %}
24
+  <link rel="shortcut icon" href="{{ url_for('static', filename='img/favicon.png') }}" />
25
+  <script type="text/javascript">
26
+    var searx = {
27
+      autocompleter: {% if autocomplete %}true{% else %}false{% endif %},
28
+      method: "{{ method or 'POST' }}",
29
+      touch: (("ontouchstart" in window) || window.DocumentTouch && document instanceof DocumentTouch) || false,
30
+      staticPath: "{{ url_for('static', filename='themes/simple') }}/",
31
+      noItemFound: "{{ _('No item found') }}",
32
+      search_on_category_select: {{ 'true' if 'plugins/js/search_on_category_select.js' in scripts else 'false'}},
33
+      infinite_scroll: {{ 'true' if 'plugins/js/infinite_scroll.js' in scripts else 'false' }}
34
+    };
35
+    document.getElementsByTagName("html")[0].className = (searx.touch)?"js touch":"js";
36
+  </script>
37
+</head>
38
+<body>
39
+  <main id="main_{{  self._TemplateReference__context.name|replace("simple/", "")|replace(".html", "") }}">
40
+    {% if errors %}
41
+        <div class="dialog-error" role="alert">
42
+            <a href="#" class="close" aria-label="close" title="close">×</a>
43
+            <ul>
44
+            {% for message in errors %}
45
+                <li>{{ message }}</li>
46
+            {% endfor %}
47
+            </ul>
48
+        </div>
49
+    {% endif %}
50
+
51
+    {% block content %}
52
+    {% endblock %}
53
+  </main>
54
+  <footer>
55
+    <p>{{ _('Powered by') }} <a href="{{ url_for('about') }}">searx</a> - {{ searx_version }} - {{ _('a privacy-respecting, hackable metasearch engine') }}</p>
56
+  </footer>
57
+  <!--[if gte IE 9]>-->
58
+  <script src="{{ url_for('static', filename='js/searx.min.js') }}" ></script>
59
+  <!--<![endif]-->
60
+</body>
61
+</html>

+ 8
- 0
searx/templates/simple/categories.html Datei anzeigen

@@ -0,0 +1,8 @@
1
+<div id="categories">{{- '' -}}
2
+    <div id="categories_container">
3
+        {%- for category in categories -%}
4
+        <div class="category"><input type="checkbox" id="checkbox_{{ category|replace(' ', '_') }}" name="category_{{ category }}"{% if category in selected_categories %} checked="checked"{% endif %}/><label for="checkbox_{{ category|replace(' ', '_') }}" class="tooltips">{{ _(category) }}</label></div>
5
+        {%- endfor -%}
6
+        {%- if display_tooltip %}<div class="help">{{ _('Click on the magnifier to perform search') }}</div>{% endif -%}
7
+    </div>{{- '' -}}
8
+</div>

+ 12
- 0
searx/templates/simple/index.html Datei anzeigen

@@ -0,0 +1,12 @@
1
+{% extends "simple/base.html" %}
2
+{% from 'simple/macros.html' import icon %}
3
+{% block meta %}
4
+	<link rel="preload" href="{{ url_for('static', filename='img/searx.png') }}" as="image" />
5
+{% endblock %}
6
+{% block content %}
7
+<nav id="linkto_preferences"><a href="{{ url_for('preferences') }}">{{ icon('navicon-round') }}</a></nav>
8
+<div class="index">
9
+    <div class="title"><h1>searx</h1></div>
10
+    {% include 'simple/search.html' %}
11
+</div>
12
+{% endblock %}

+ 46
- 0
searx/templates/simple/infobox.html Datei anzeigen

@@ -0,0 +1,46 @@
1
+<aside class="infobox">
2
+  <h2><bdi>{{ infobox.infobox }}</bdi></h2>
3
+  {% if infobox.img_src %}<img src="{{ image_proxify(infobox.img_src) }}" title="{{ infobox.infobox|striptags }}" alt="{{ infobox.infobox|striptags }}" />{% endif %}
4
+  <p><bdi>{{ infobox.entity }}</bdi></p>
5
+  <p><bdi>{{ infobox.content | safe }}</bdi></p>
6
+  {% if infobox.attributes %}
7
+  <div class="attributes">
8
+    {% for attribute in infobox.attributes %}
9
+    <dl>
10
+      <dt><bdi>{{ attribute.label }} :</bdi></dt>
11
+      {%- if attribute.image -%}
12
+      <dd><img src="{{ image_proxify(attribute.image.src) }}" alt="{{ attribute.image.alt }}" /></dd>
13
+      {%- else -%}
14
+      <dd><bdi>{{ attribute.value }}</bdi></dd>
15
+      {%- endif -%}
16
+    </dl>
17
+    {% endfor %}      
18
+  </div>
19
+  {% endif %}
20
+  
21
+  {% if infobox.urls %}
22
+  <div class="urls">
23
+    <ul>
24
+      {%- for url in infobox.urls -%}
25
+      <li class="url"><bdi><a href="{{ url.url }}" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}>{{ url.title }}</a></bdi></li>
26
+      {%- endfor -%}
27
+    </ul>
28
+  </div>
29
+  {% endif %}
30
+
31
+  {% if infobox.relatedTopics %}
32
+  <div class="relatedTopics">
33
+    {% for topic in infobox.relatedTopics %}
34
+    <div>
35
+      <h3><bdi>{{ topic.name }}</bdi></h3>
36
+      {% for suggestion in topic.suggestions %}
37
+      <form method="{{ method or 'POST' }}" action="{{ url_for('index') }}">
38
+        <input type="hidden" name="q" value="{{ suggestion }}">
39
+        <input type="submit" value="{{ suggestion }}" />
40
+      </form>
41
+      {% endfor %}
42
+    </div>
43
+    {% endfor %}
44
+  </div>
45
+  {% endif %}
46
+</aside>

+ 8
- 0
searx/templates/simple/languages.html Datei anzeigen

@@ -0,0 +1,8 @@
1
+<select class="language" id="language" name="language" tabindex="2">{{- '' -}}
2
+	<option value="all" {% if current_language == 'all' %}selected="selected"{% endif %}>{{ _('Default language') }}</option>
3
+	{%- for lang_id,lang_name,country_name,english_name in language_codes | sort(attribute=1) -%}
4
+	<option value="{{ lang_id }}" {% if lang_id == current_language %}selected="selected"{% endif %}>
5
+		{{- lang_name }} {% if country_name %}({{ country_name }}) {% endif %}- {{ lang_id -}}
6
+	</option>
7
+	{%- endfor -%}
8
+</select>

+ 86
- 0
searx/templates/simple/macros.html Datei anzeigen

@@ -0,0 +1,86 @@
1
+<!-- Draw glyphicon icon from bootstrap-theme -->
2
+{% macro icon(action) -%}
3
+    <span class="ion-icon-big ion-{{ action }}"></span>
4
+{%- endmacro %}
5
+
6
+{% macro icon_small(action) -%}
7
+    <span class="ion-icon ion-{{ action }}"></span>
8
+{%- endmacro %}
9
+
10
+<!-- Draw favicon -->
11
+<!-- TODO: using url_for methode -->
12
+{% macro draw_favicon(favicon) -%}
13
+    <img width="14" height="14" class="favicon" src="static/themes/simple/img/icons/{{ favicon }}.png" alt="{{ favicon }}" />
14
+{%- endmacro %}
15
+
16
+{% macro result_open_link(url, classes='') -%}
17
+    <a href="{{ url }}" {% if classes %}class="{{ classes }}" {% endif %}{% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}>
18
+{%- endmacro %}
19
+
20
+{%- macro result_close_link() -%}
21
+    </a>
22
+{%- endmacro %}
23
+
24
+{%- macro result_link(url, title, classes='') -%}
25
+    {{ result_open_link(url, classes) }}{{ title }}{{ result_close_link() }}
26
+{%- endmacro -%}
27
+
28
+<!-- Draw result header -->
29
+{% macro result_header(result, favicons, image_proxify) -%}
30
+<article class="result {% if result['template'] %}result-{{ result.template|replace('.html', '') }}{% else %}result-default{% endif %} {% if result['category'] %}category-{{ result['category'] }}{% endif %}">
31
+  {%- if result.img_src %}{{ result_open_link(result.url) }}<img class="image" src="{{ image_proxify(result.img_src) }}" alt="{{ result.title|striptags }}" title="{{ result.title|striptags }}" class="image" />{{ result_close_link() }}{% endif -%}
32
+  {%- if result.thumbnail %}{{ result_open_link(result.url) }}<img class="thumbnail" src="{{ image_proxify(result.thumbnail) }}" title="{{ result.title|striptags }}" alt="{{ result.title|striptags }}"/>{{ result_close_link() }}{% endif -%}
33
+  <h3>{{ result_link(result.url, result.title|safe) }}</h3>
34
+{%- endmacro -%}
35
+
36
+<!-- Draw result sub header -->
37
+{%- macro result_sub_header(result) -%}
38
+  {% if result.publishedDate %}<time class="published_date" datetime="{{ result.pubdate }}" >{{ result.publishedDate }}</time>{% endif %}
39
+{%- endmacro -%}
40
+
41
+<!-- Draw result sub footer -->
42
+{%- macro result_sub_footer(result, proxify) -%}
43
+<div class="engines">{% for engine in result.engines %}<span>{{ engine }}</span>{% endfor %}</div>{{- '' -}}
44
+<p class="url"><span class="url">{{ result.pretty_url }}</span>{{ result_link("https://web.archive.org/web/" + result.url, icon('link') + _('cached'), "cache_link") }}&lrm; {% if proxify %} {{ result_link(proxify(result.url), icon('link') + _('proxied'), "proxyfied_link") }} {% endif %}</p>{{- '' -}}
45
+<div class="break"></div>{{- '' -}}
46
+{%- endmacro -%}
47
+
48
+<!-- Draw result footer -->
49
+{%- macro result_footer(result) -%}
50
+</article>
51
+{%- endmacro -%}
52
+
53
+<!-- -->
54
+{%- macro tabs_open() -%}
55
+<div class="tabs" role="tablist">
56
+{%- endmacro -%}
57
+
58
+{%- macro tab_header(name, id, label) -%}
59
+<input type="radio" name="{{ name }}" id="tab_{{ id }}"/>
60
+<label for="tab_{{ id }}" role="tab"
61
+       aria-controls="panel{{ id }}">{{ label }}</label>
62
+<section id="tab-content{{ id }}" role="tabpanel"
63
+         aria-labelledby="{{ label }}" aria-hidden="false">
64
+{%- endmacro -%}
65
+
66
+{%- macro tab_footer() -%}
67
+</section>
68
+{%- endmacro -%}
69
+
70
+{%- macro tabs_close() -%}
71
+</div>
72
+{%- endmacro -%}
73
+
74
+{%- macro checkbox_onoff(name, checked) -%}
75
+<div class="checkbox-onoff">{{- '' -}}
76
+    <input type="checkbox" value="None" id="{{ name }}" name="{{ name }}" {% if checked %}checked{% endif %}/>{{- '' -}}
77
+    <label for="{{ name }}"></label>{{- '' -}}
78
+</div>
79
+{%- endmacro -%}
80
+
81
+{%- macro checkbox(name, checked, readonly, disabled) -%}
82
+<div class="checkbox">{{- '' -}}
83
+    <input type="checkbox" value="None" id="{{ name }}" name="{{ name }}" {% if checked %}checked{% endif %}{% if readonly %} readonly="readonly" {% endif %}{% if disabled %} disabled="disabled" {% endif %}/>{{- '' -}}
84
+    <label for="{{ name }}"></label>{{- '' -}}
85
+</div>
86
+{%- endmacro -%}

+ 190
- 0
searx/templates/simple/preferences.html Datei anzeigen

@@ -0,0 +1,190 @@
1
+{% from 'simple/macros.html' import tabs_open, tabs_close, tab_header, tab_footer, checkbox_onoff, checkbox %}
2
+
3
+{% extends "simple/base.html" %}
4
+
5
+{%- macro plugin_preferences(section) -%}
6
+{%- for plugin in plugins -%}
7
+{%- if plugin.preference_section == section -%}
8
+<fieldset>{{- '' -}}
9
+    <legend>{{ _(plugin.name) }}</legend>{{- '' -}}
10
+    <div class="value">
11
+      {{- checkbox_onoff('plugin_' + plugin.id, plugin.id not in allowed_plugins) -}}
12
+    </div>{{- '' -}}
13
+    <div class="description">
14
+      {{- _(plugin.description) -}}
15
+    </div>{{- '' -}}
16
+</fieldset>
17
+{%- endif -%}
18
+{%- endfor -%}
19
+{%- endmacro -%}
20
+
21
+{% block head %} {% endblock %}
22
+{% block content %}
23
+
24
+<a href="{{ url_for('index') }}"><h1><span>searx</span></h1></a>
25
+
26
+<h2>{{ _('Preferences') }}</h2>
27
+
28
+<form id="search_form" method="post" action="{{ url_for('preferences') }}">
29
+
30
+{{ tabs_open() }}
31
+
32
+{{ tab_header('maintab', 'general', _('General')) }}
33
+  <fieldset>
34
+    <legend>{{ _('Default categories') }}</legend>
35
+    {% set display_tooltip = false %}
36
+    {% include 'simple/categories.html' %}
37
+  </fieldset>
38
+  <fieldset>
39
+    <legend>{{ _('Search language') }}</legend>
40
+    <p class="value">{{- '' -}}
41
+      <select name='language'>{{- '' -}}
42
+        <option value="all" {% if current_language == 'all' %}selected="selected"{% endif %}>{{ _('Default language') }}</option>
43
+        {%- for lang_id,lang_name,country_name,english_name in language_codes | sort(attribute=1) -%}
44
+        <option value="{{ lang_id }}" {% if lang_id == current_language %}selected="selected"{% endif %}>{{ lang_name }} {% if country_name %}({{ country_name }}) {% endif %}- {{ lang_id }}</option>
45
+        {%- endfor -%}
46
+      </select>{{- '' -}}
47
+    </p>
48
+    <div class="description">{{ _('What language do you prefer for search?') }}</div>
49
+  </fieldset>
50
+  <fieldset>
51
+    <legend>{{ _('Autocomplete') }}</legend>
52
+    <p class="value">
53
+      <select name="autocomplete">
54
+        <option value=""> - </option>
55
+        {% for backend in autocomplete_backends %}
56
+        <option value="{{ backend }}" {% if backend == autocomplete %}selected="selected"{% endif %}>{{ backend }}</option>
57
+        {% endfor %}
58
+      </select>
59
+    </p>
60
+    <div class="description">{{ _('Find stuff as you type') }}</div>
61
+  </fieldset>
62
+  <fieldset>
63
+    <legend>{{ _('SafeSearch') }}</legend>
64
+    <p class="value">
65
+      <select name='safesearch'>
66
+        <option value="2" {% if safesearch == '2' %}selected="selected"{% endif %}>{{ _('Strict') }}</option>
67
+        <option value="1" {% if safesearch == '1' %}selected="selected"{% endif %}>{{ _('Moderate') }}</option>
68
+        <option value="0" {% if safesearch == '0' %}selected="selected"{% endif %}>{{ _('None') }}</option>
69
+      </select>
70
+    </p>
71
+    <div class="description">{{ _('Filter content') }}</p>
72
+  </fieldset>
73
+  {{ plugin_preferences('general') }}
74
+  {{ tab_footer() }}
75
+
76
+  {{ tab_header('maintab', 'engines', _('Engines')) }}
77
+    <p>{{ _('Currently used search engines') }}</p>
78
+
79
+    {{ tabs_open() }}
80
+    {% for categ in all_categories %}
81
+
82
+    {{ tab_header('enginetab', 'category' + categ, _(categ)) }}
83
+    <div class="scrollx">
84
+    <table class="striped">
85
+      <tr>
86
+        <th class="engine_checkbox">{{ _("Allow") }}</th>
87
+        <th class="name">{{ _("Engine name") }}</th>
88
+        <th class="shortcut">{{ _("Shortcut") }}</th>
89
+        <th>{{ _("Supports selected language") }}</th>
90
+        <th>{{ _("SafeSearch") }}</th>
91
+        <th>{{ _("Time range") }}</th>
92
+        <th>{{ _("Avg. time") }}</th>
93
+        <th>{{ _("Max time") }}</th>
94
+      </tr>
95
+      {% for search_engine in engines_by_category[categ] %}
96
+
97
+      {% if not search_engine.private %}
98
+      {% set engine_id = 'engine_' + search_engine.name|replace(' ', '_') + '__' + categ|replace(' ', '_') %}
99
+      <tr>
100
+        <td class="engine_checkbox">{{ checkbox_onoff(engine_id, (search_engine.name, categ) in disabled_engines) }}</td>
101
+        <th class="name">{{ search_engine.name }}</th>
102
+        <td class="shortcut">{{ shortcuts[search_engine.name] }}</td>
103
+        <td>{{ checkbox(engine_id + '_supported_languages', current_language == 'all' or current_language in search_engine.supported_languages or current_language.split('-')[0] in search_engine.supported_languages, true, true) }}</td>
104
+        <td>{{ checkbox(engine_id + '_safesearch', search_engine.safesearch==True, true, true) }}</td>
105
+        <td>{{ checkbox(engine_id + '_time_range_support', search_engine.time_range_support==True, true, true) }}</td>
106
+        <td class="{{ 'danger' if stats[search_engine.name]['warn_time'] else '' }}">{{ 'N/A' if stats[search_engine.name].time==None else stats[search_engine.name].time }}</td>
107
+        <td class="{{ 'danger' if stats[search_engine.name]['warn_timeout'] else '' }}">{{ search_engine.timeout }}</td>
108
+      </tr>
109
+      {% endif %}
110
+      {% endfor %}
111
+    </table>
112
+    <div>
113
+    {{ tab_footer() }}
114
+    {% endfor %}
115
+    {{ tabs_close() }}
116
+  {{ tab_footer() }}
117
+
118
+  {{ tab_header('maintab', 'ui', _('User interface')) }}
119
+  <fieldset>
120
+    <legend>{{ _('Interface language') }}</legend>
121
+    <p class="value">
122
+      <select name='locale'>
123
+        {% for locale_id,locale_name in locales.items() | sort %}
124
+        <option value="{{ locale_id }}" {% if locale_id == current_locale %}selected="selected"{% endif %}>{{ locale_name }}</option>
125
+        {% endfor %}
126
+      </select>
127
+    </p>
128
+    <div class="description">{{ _('Change the language of the layout') }}</div>
129
+  </fieldset>
130
+  <fieldset>
131
+    <legend>{{ _('Themes') }}</legend>
132
+    <p class="value">
133
+      <select name="theme">
134
+        {%- for name in themes -%}
135
+        <option value="{{ name }}" {% if name == theme %}selected="selected"{% endif %}>{{ name }}</option>
136
+        {%- endfor -%}
137
+      </select>
138
+    </p>
139
+    <div class="description">{{ _('Change searx layout') }}</div>
140
+  </fieldset>
141
+  <fieldset>
142
+    <legend>{{ _('Results on new tabs') }}</legend>
143
+    <p class="value">
144
+      <select name='results_on_new_tab'>
145
+        <option value="1" {% if results_on_new_tab %}selected="selected"{% endif %}>{{ _('On') }}</option>
146
+        <option value="0" {% if not results_on_new_tab %}selected="selected"{% endif %}>{{ _('Off')}}</option>
147
+      </select>
148
+    </p>
149
+    <div class="description">{{_('Open result links on new browser tabs') }}</div>
150
+  </fieldset>
151
+  {{ plugin_preferences('ui') }}
152
+  {{ tab_footer() }}
153
+
154
+  {{ tab_header('maintab', 'privacy', _('Privacy')) }}
155
+  <fieldset>
156
+    <legend>{{ _('Method') }}</legend>
157
+    <p class="value">
158
+      <select name='method'>
159
+        <option value="POST" {% if method == 'POST' %}selected="selected"{% endif %}>POST</option>
160
+        <option value="GET" {% if method == 'GET' %}selected="selected"{% endif %}>GET</option>
161
+      </select>
162
+    </p>
163
+    <div class="description">{{ _('Search language') }}</div>
164
+  </fieldset>
165
+  <fieldset>
166
+    <legend>{{ _('Image proxy') }}</legend>
167
+    <p class="value">
168
+      <select name='image_proxy'>
169
+        <option value="1" {% if image_proxy %}selected="selected"{% endif %}>{{ _('Enabled') }}</option>
170
+        <option value="" {% if not image_proxy %}selected="selected"{% endif %}>{{ _('Disabled') }}</option>
171
+      </select>
172
+    </p>
173
+    <div class="description">{{ _('Proxying image results through searx') }}</div>
174
+  </fieldset>
175
+  {{ plugin_preferences('privacy') }}
176
+  {{ tab_footer() }}
177
+
178
+  {{ tabs_close() }}
179
+
180
+  <p class="small_font">{{ _('These settings are stored in your cookies, this allows us not to store this data about you.') }}
181
+    <br />
182
+    {{ _("These cookies serve your sole convenience, we don't use these cookies to track you.") }}
183
+  </p>
184
+
185
+  <input type="submit" value="{{ _('save') }}" />
186
+  <div class="{% if rtl %}left{% else %}right{% endif %} preferences_back"><a href="{{ url_for('clear_cookies') }}">{{ _('Reset defaults') }}</a></div>
187
+  <div class="{% if rtl %}left{% else %}right{% endif %} preferences_back"><a href="{{ url_for('index') }}">{{ _('back') }}</a></div>
188
+
189
+</form>
190
+{% endblock %}

+ 13
- 0
searx/templates/simple/result_templates/code.html Datei anzeigen

@@ -0,0 +1,13 @@
1
+{% from 'simple/macros.html' import result_header, result_sub_header, result_sub_footer, result_footer, result_footer_rtl %}
2
+
3
+{{ result_header(result, favicons, image_proxify) -}}
4
+{{- result_sub_header(result) -}}
5
+{%- if result.content %}{{ result.content|safe }}{% endif %}</p>
6
+{%- if result.repository -%}
7
+<p class="content"><a href="{{ result.repository|safe }}" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}>{{ result.repository }}</a></p>
8
+{%- endif -%}
9
+<div dir="ltr" class="codelines">
10
+    {{- result.codelines|code_highlighter(result.code_language)|safe -}}
11
+</div>{{- '' -}}
12
+{{- result_sub_footer(result, proxify) -}}
13
+{{ result_footer(result) }}

+ 17
- 0
searx/templates/simple/result_templates/default.html Datei anzeigen

@@ -0,0 +1,17 @@
1
+{% from 'simple/macros.html' import result_header, result_sub_header, result_sub_footer, result_footer, result_footer_rtl %}
2
+
3
+{{ result_header(result, favicons, image_proxify) -}}
4
+{{- result_sub_header(result) -}}
5
+{% if result.embedded -%}
6
+<p class="altlink"> &bull; <a class="btn-collapse collapsed media-loader disabled_if_nojs" data-target="#result-media-{{ index }}" data-btn-text-collapsed="{{ _('show media') }}" data-btn-text-not-collapsed="{{ _('hide media') }}">{{ icon('music-note') }} {{ _('show media') }}</a></p>
7
+{%- endif %}
8
+<p class="content">
9
+  {%- if result.content %}{{ result.content|safe }}{% endif -%}
10
+</p>
11
+{{- result_sub_footer(result, proxify) -}}
12
+{% if result.embedded -%}
13
+<div id="result-media-{{ index }}" class="invisible">
14
+   {{- result.embedded|safe -}}
15
+</div>
16
+{%- endif %}
17
+{{- result_footer(result) }}

+ 4
- 0
searx/templates/simple/result_templates/images.html Datei anzeigen

@@ -0,0 +1,4 @@
1
+<article class="result result-images {% if result['category'] %}category-{{ result['category'] }}{% endif %}">
2
+        <a href="{{ result.img_src }}" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}><img class="image_thumbnail" src="{% if result.thumbnail_src %}{{ image_proxify(result.thumbnail_src) }}{% else %}{{ image_proxify(result.img_src) }}{% endif %}" title="{{ result.title|striptags }}" alt="{{ result.title|striptags }}" /></a>
3
+        <span class="url"><a href="{{ result.url }}" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %} class="small_font">{{ result.parsed_url[0] }}://{{ result.parsed_url[1] }}</a></span>
4
+</article>

+ 71
- 0
searx/templates/simple/result_templates/map.html Datei anzeigen

@@ -0,0 +1,71 @@
1
+{% from 'simple/macros.html' import result_header, result_sub_header, result_sub_footer, result_footer, result_footer_rtl, icon %}
2
+
3
+{{ result_header(result, favicons, image_proxify) -}}
4
+{{- result_sub_header(result) -}}
5
+
6
+{%- if (result.latitude and result.longitude) or result.boundingbox -%}
7
+    <small> &bull; <a class="btn-collapse collapsed searx_init_map hide_if_nojs" data-target="#result-map-{{ index }}" data-btn-text-collapsed="{{ _('show map') }}" data-btn-text-not-collapsed="{{ _('hide map') }}" data-leaflet-target="osm-map-{{ index }}" data-map-lon="{{ result.longitude }}" data-map-lat="{{ result.latitude }}" {% if result.boundingbox %}data-map-boundingbox='{{ result.boundingbox|tojson|safe }}'{% endif %} {% if result.geojson %}data-map-geojson='{{ result.geojson|tojson|safe }}'{% endif %}>{{ icon( 'globe') }} {{ _('show map') }}</a></small>
8
+{%- endif -%}
9
+
10
+{%- if result.osm and (result.osm.type and result.osm.id) -%}
11
+    <small> &bull; <a class="btn-collapse collapsed hide_if_nojs searx_overpass_request" data-target="#result-overpass-{{ index }}" data-btn-text-collapsed="{{ _('show details') }}" data-btn-text-not-collapsed="{{ _('hide details') }}" data-osm-type="{{ result.osm.type }}" data-osm-id="{{ result.osm.id }}" data-result-table="result-overpass-table-{{ index }}" data-result-table-loadicon="result-overpass-table-loading-{{ index }}">{{ icon('location') }} {{ _('show details') }}</a></small>
12
+{%- endif -%}
13
+{#-
14
+{% if (result.latitude and result.longitude) %}
15
+    <small> &bull; <a class="btn-collapse disabled_if_nojs" data-target="#result-geodata-{{ index }}" data-btn-text-collapsed="{{ _('show geodata') }}" data-btn-text-not-collapsed="{{ _('hide geodata') }}">{{ icon('location') }} {{ _('show geodata') }}</a></small>
16
+{% endif %}
17
+-#}
18
+
19
+{%- if result.address -%}
20
+<p itemscope itemtype="http://schema.org/PostalAddress" class="content">
21
+    {%- if result.address.name -%}
22
+        <strong itemprop="name">{{ result.address.name }}</strong><br/>
23
+    {%- endif -%}
24
+    {% if result.address.road -%}
25
+        <span itemprop="streetAddress">
26
+            {% if result.address.house_number %}{{ result.address.house_number }}, {% endif %}
27
+            {{ result.address.road }}
28
+        </span><br/>
29
+    {%- endif %}
30
+    {%- if result.address.locality -%}
31
+        <span itemprop="addressLocality">{{ result.address.locality }}</span>
32
+        {% if result.address.postcode %}, <span itemprop="postalCode">{{ result.address.postcode }}</span>{% endif %}
33
+        <br/>
34
+    {%- endif -%}
35
+    {%- if result.address.country -%}
36
+        <span itemprop="addressCountry">{{ result.address.country }}</span>
37
+    {%- endif -%}
38
+</p>
39
+{%- endif -%}
40
+
41
+{%- if result.content %}<p class="content">{{ result.content|safe }}</p>{% endif -%}
42
+
43
+{{- result_sub_footer(result, proxify) -}}
44
+
45
+{% if result.osm and (result.osm.type and result.osm.id) -%}
46
+    <div class="result-content invisible" id="result-overpass-{{ index }}"{% if rtl %} dir="ltr"{% endif %}>
47
+        <div id="result-overpass-table-loading-{{ index }}"><img src="{{ url_for('static', filename='img/loader.gif') }}" alt="Loading ..."/></div>
48
+        <table id="result-overpass-table-{{ index }}">
49
+          <thead>
50
+            <tr><th>key</th><th>value</th></tr>
51
+          </thead>
52
+          <tbody>
53
+          </tbody>
54
+        </table>
55
+    </div>
56
+{%- endif %}
57
+
58
+{#-
59
+{% if (result.latitude and result.longitude) -%}
60
+    <div id="result-geodata-{{ index }}" class="invisible">
61
+        <strong>Longitude:</strong> {{ result.longitude }} <br/>
62
+        <strong>Latitude:</strong> {{ result.latitude }}
63
+    </div>
64
+{%- endif %}
65
+-#}
66
+
67
+{% if (result.latitude and result.longitude) or result.boundingbox -%}
68
+    <div id="result-map-{{ index }}" class="invisible"><div id="osm-map-{{ index }}" style="height:300px; width:100%; margin: 10px 0;" ></div></div>
69
+{%- endif %}
70
+
71
+{{- result_footer(result) }}

+ 24
- 0
searx/templates/simple/result_templates/torrent.html Datei anzeigen

@@ -0,0 +1,24 @@
1
+{% from 'simple/macros.html' import result_header, result_sub_header, result_sub_footer, result_footer, result_footer_rtl, result_link %}
2
+
3
+{{ result_header(result, favicons, image_proxify) -}}
4
+{{- result_sub_header(result) -}}
5
+
6
+{% if result.magnetlink %}<p class="altlink"> &bull; {{ result_link(result.magnetlink, icon('magnet') + _('magnet link'), "magnetlink") }}</p>{% endif %}
7
+{% if result.torrentfile %}<p class="altlink"> &bull; {{ result_link(result.torrentfile, icon('download-alt') + _('torrent file'), "torrentfile") }}</p>{% endif %}
8
+
9
+{% if result.seed %}<p class="stat"> &bull; {{ icon('arrow-swap') }} {{ _('Seeder') }} <span class="badge">{{ result.seed }}</span> &bull; {{ _('Leecher') }} <span class="badge">{{ result.leech }}</span></p>{% endif %}
10
+
11
+{%- if result.filesize %}<p class="stat">{{ icon('floppy-disk') }} {{ _('Filesize') }}<span class="badge">
12
+    {%- if result.filesize < 1024 %}{{ result.filesize }} {{ _('Bytes') }}
13
+    {%- elif result.filesize < 1024*1024 %}{{ '{0:0.2f}'.format(result.filesize/1024) }} {{ _('kiB') }}
14
+    {%- elif result.filesize < 1024*1024*1024 %}{{ '{0:0.2f}'.format(result.filesize/1024/1024) }} {{ _('MiB') }}
15
+    {%- elif result.filesize < 1024*1024*1024*1024 %}{{ '{0:0.2f}'.format(result.filesize/1024/1024/1024) }} {{ _('GiB') }}
16
+    {%- else %}{{ '{0:0.2f}'.format(result.filesize/1024/1024/1024/1024) }} {{ _('TiB') }}{% endif -%}
17
+    </span></p>
18
+{%- endif -%}
19
+
20
+{%- if result.files %}<p class="stat">{{ icon('file') }} {{ _('Number of Files') }} <span class="badge">{{ result.files }}</span></p>{% endif -%}
21
+
22
+{%- if result.content %}<p class="content">{{ result.content|safe }}</p>{% endif -%}
23
+{{- result_sub_footer(result, proxify) -}}
24
+{{- result_footer(result) }}

+ 15
- 0
searx/templates/simple/result_templates/videos.html Datei anzeigen

@@ -0,0 +1,15 @@
1
+{% from 'simple/macros.html' import result_header, result_sub_header, result_sub_footer, result_footer, result_footer_rtl %}
2
+
3
+{{ result_header(result, favicons, image_proxify) }}
4
+{{ result_sub_header(result) }}
5
+{% if result.embedded -%}
6
+<p class="altlink"> &bull; <a class="btn-collapse collapsed media-loader disabled_if_nojs" data-target="#result-video-{{ index }}" data-btn-text-collapsed="{{ _('show video') }}" data-btn-text-not-collapsed="{{ _('hide video') }}">{{ icon('film-outline') }} {{ _('show video') }}</a></p>
7
+{%- endif %}
8
+{% if result.content %}<p class="content">{{ result.content|safe }}</p>{% endif %}
9
+{{- result_sub_footer(result, proxify) -}}
10
+{% if result.embedded -%}
11
+<div id="result-video-{{ index }}" class="invisible">
12
+   {{- result.embedded|safe -}}
13
+</div>
14
+{%- endif %}
15
+{{ result_footer(result) }}

+ 151
- 0
searx/templates/simple/results.html Datei anzeigen

@@ -0,0 +1,151 @@
1
+{% extends "simple/base.html" %}
2
+{% from 'simple/macros.html' import icon, icon_small %}
3
+{% block title %}{{ q|e }} - {% endblock %}
4
+{% block meta %}<link rel="alternate" type="application/rss+xml" title="Searx search: {{ q|e }}" href="{{ url_for('index') }}?q={{ q|urlencode }}&amp;categories={{ selected_categories|join(",") | replace(' ','+') }}&amp;pageno={{ pageno }}&amp;time_range={{ time_range }}&amp;language={{ current_language }}&amp;safesearch={{ safesearch }}&amp;format=rss">{% endblock %}
5
+{% block content %}
6
+<nav id="linkto_preferences"><a href="{{ url_for('preferences') }}">{{ icon('navicon-round') }}</a></nav>
7
+{% include 'simple/search.html' %}
8
+<div id="results">
9
+    {% if answers %}
10
+    <div id="answers"><h4 class="title">{{ _('Answers') }} : </h4>
11
+        {% for answer in answers -%}
12
+        <div class="answer">{{ answer }}</div>
13
+        {%- endfor %}
14
+    </div>
15
+    {% endif %}
16
+
17
+    <div id="sidebar">
18
+
19
+        {% if number_of_results != '0' -%}
20
+        <p id="result_count"><small>{{ _('Number of results') }}: {{ number_of_results }}</small></p>
21
+        {%- endif %}
22
+
23
+        {% if unresponsive_engines and results|length >= 1 %}
24
+	<div class="dialog-error" role="alert">
25
+	  <p><strong>{{ _('Error!') }}</strong> {{ _('Engines cannot retrieve results') }}:</p>
26
+	  <p>{% for engine_name, error_type in unresponsive_engines %}
27
+	  {{ engine_name }} ({{ error_type }}){% if not loop.last %}, {% endif %}
28
+	  {% endfor %}</p>
29
+	</div>
30
+	{% endif %}
31
+
32
+        {% if infoboxes %}
33
+        <div id="infoboxes">
34
+	         {% for infobox in infoboxes %}
35
+               {% include 'simple/infobox.html' %}
36
+	         {% endfor %}
37
+        </div>
38
+        {% endif %}
39
+
40
+        {% if suggestions %}
41
+        <div id="suggestions">
42
+	  <h4 class="title">{{ _('Suggestions') }} : </h4>
43
+	  <div class="wrapper">
44
+            {% for suggestion in suggestions %}
45
+            <form method="{{ method or 'POST' }}" action="{{ url_for('index') }}">
46
+              <input type="hidden" name="q" value="{{ suggestion }}">
47
+              <input type="hidden" name="language" value="{{ current_language }}">
48
+              <input type="hidden" name="safesearch" value="{{ safesearch }}">
49
+              <input type="hidden" name="theme" value="{{ theme }}">
50
+              <input type="submit" class="suggestion" value="&bull; {{ suggestion }}">
51
+            </form>
52
+            {% endfor %}
53
+	  </div>
54
+        </div>
55
+        {% endif %}
56
+
57
+        <div id="search_url">
58
+            <h4 class="title">{{ _('Search URL') }} :</h4>
59
+            <div><pre>{{ base_url }}?q={{ q|urlencode }}&amp;language={{ current_language }}&amp;time_range={{ time_range }}&amp;safesearch={{ safesearch }}{% if pageno > 1 %}&amp;pageno={{ pageno }}{% endif %}{% if selected_categories %}&amp;categories={{ selected_categories|join(",") | replace(' ','+') }}{% endif %}</pre></div>
60
+        </div>
61
+        <div id="apis">
62
+          <h4 class="title">{{ _('Download results') }}</h4>
63
+          {% for output_type in ('csv', 'json', 'rss') %}
64
+	  <div class="left">
65
+            <form method="{{ method or 'POST' }}" action="{{ url_for('index') }}">
66
+              <input type="hidden" name="q" value="{{ q|e }}">
67
+              {% for category in selected_categories %}
68
+              <input type="hidden" name="category_{{ category }}" value="1">
69
+              {% endfor %}
70
+              <input type="hidden" name="pageno" value="{{ pageno }}">
71
+              <input type="hidden" name="time_range" value="{{ time_range }}">
72
+              <input type="hidden" name="language" value="{{ current_language }}">
73
+              <input type="hidden" name="safesearch" value="{{ safesearch }}">
74
+              <input type="hidden" name="format" value="{{ output_type }}">
75
+              <input type="submit" value="{{ output_type }}">
76
+            </form>
77
+	  </div>
78
+          {% endfor %}
79
+        </div>
80
+    </div>
81
+
82
+    {% if corrections %}
83
+    <div id="corrections">
84
+      <h4>{{ _('Try searching for:') }}</h4>
85
+      {% for correction in corrections %}
86
+      <div class="left">
87
+	<form method="{{ method or 'POST' }}" action="{{ url_for('index') }}" role="navigation">
88
+          <input type="hidden" name="q" value="{{ correction }}">
89
+          <input type="hidden" name="time_range" value="{{ time_range }}">
90
+          <input type="hidden" name="language" value="{{ current_language }}">
91
+          <input type="hidden" name="safesearch" value="{{ safesearch }}">
92
+          <input type="hidden" name="theme" value="{{ theme }}">
93
+          <input type="submit" value="{{ correction }}">
94
+	</form>
95
+      </div>
96
+      {% endfor %}
97
+    </div>
98
+    {% endif %}
99
+
100
+    <div id="urls">
101
+    {% for result in results %}
102
+        {% set index = loop.index %}
103
+        {% if result['template'] %}
104
+            {% include get_result_template('simple', result['template']) %}
105
+        {% else %}
106
+            {% include 'simple/result_templates/default.html' %}
107
+        {% endif %}
108
+    {% endfor %}
109
+    {% if not results and not answers %}
110
+        {% include 'simple/messages/no_results.html' %}
111
+    {% endif %}
112
+    </div>
113
+    <div id="backToTop">
114
+      <a href="#">{{ icon_small('chevron-up') }}</a>
115
+    </div>
116
+    {% if paging %}
117
+    <nav id="pagination">
118
+        {% if pageno > 1 %}
119
+            <form method="{{ method or 'POST' }}" action="{{ url_for('index') }}">
120
+                <div class="{% if rtl %}right{% else %}left{% endif %}">
121
+                  <input type="hidden" name="q" value="{{ q|e }}" >
122
+                  {% for category in selected_categories %}
123
+                  <input type="hidden" name="category_{{ category }}" value="1" >
124
+                  {% endfor %}
125
+                  <input type="hidden" name="pageno" value="{{ pageno-1 }}" >
126
+                  <input type="hidden" name="time_range" value="{{ time_range }}" >
127
+                  <input type="hidden" name="language" value="{{ current_language }}" >
128
+                  <input type="hidden" name="safesearch" value="{{ safesearch }}" >
129
+                  <input type="hidden" name="theme" value="{{ theme }}" >
130
+		  <button type="submit">{{ icon_small('chevron-left') }} {{ _('previous page') }}</button>
131
+                </div>
132
+            </form>
133
+        {% endif %}
134
+        <form method="{{ method or 'POST' }}" action="{{ url_for('index') }}">
135
+            <div class="{% if rtl %}left{% else %}right{% endif %}">
136
+              <input type="hidden" name="q" value="{{ q|e }}" >
137
+              {% for category in selected_categories %}
138
+              <input type="hidden" name="category_{{ category }}" value="1" >
139
+              {% endfor %}
140
+              <input type="hidden" name="pageno" value="{{ pageno+1 }}" >
141
+              <input type="hidden" name="time_range" value="{{ time_range }}" >
142
+              <input type="hidden" name="language" value="{{ current_language }}" >
143
+              <input type="hidden" name="safesearch" value="{{ safesearch }}" >
144
+              <input type="hidden" name="theme" value="{{ theme }}" >
145
+	       <button type="submit">{{ _('next page') }} {{ icon_small('chevron-right') }}</button>
146
+            </div>
147
+        </form>
148
+    </nav>
149
+    {% endif %}
150
+</div>
151
+{% endblock %}

+ 16
- 0
searx/templates/simple/search.html Datei anzeigen

@@ -0,0 +1,16 @@
1
+<form id="search" method="{{ method or 'POST' }}" action="{{ url_for('index') }}">
2
+  <div id="search_wrapper">
3
+    <div class="search_box">
4
+      <input id="q" name="q" type="text" placeholder="{{ _('Search for...') }}" tabindex="1" autocomplete="off" spellcheck="false" dir="auto" {% if q %}value="{{ q }}"{% endif %} >
5
+      <button id="send_search" type="submit" tabindex="-1"><span class="hide_if_nojs">{{ icon('search') }}</span><span class="show_if_nojs">{{ _('Start search') }}</span></button>
6
+    </div>
7
+    <div class="search_filters">
8
+      {% include 'simple/languages.html' %}
9
+      {% include 'simple/time-range.html' %}
10
+    </div>
11
+  </div>
12
+  {% set display_tooltip = true %}
13
+  {% include 'simple/categories.html' %}
14
+  <input type="hidden" name="safesearch" value="{{ safesearch }}" >
15
+  <input type="hidden" name="theme" value="{{ theme }}" >
16
+</form>

+ 40
- 0
searx/templates/simple/simple.spec.txt Datei anzeigen

@@ -0,0 +1,40 @@
1
+#container
2
+	.search
3
+		#search_form
4
+				
5
+#results
6
+
7
+	#sidebar
8
+		#result-count
9
+			.title
10
+			.content
11
+
12
+		.infobox	
13
+			h2
14
+			img
15
+			p
16
+			div#attributes
17
+				table
18
+					tbody
19
+						tr
20
+							td
21
+							td
22
+			div#urls
23
+				ul
24
+					li
25
+
26
+		#suggestions
27
+			.title
28
+			.suggestion
29
+
30
+		#search_url
31
+			.title
32
+			input
33
+
34
+		#apis
35
+			.title
36
+			.api-link
37
+
38
+	.result
39
+		
40
+	

+ 25
- 0
searx/templates/simple/stats.html Datei anzeigen

@@ -0,0 +1,25 @@
1
+{% extends "simple/base.html" %}
2
+{% block head %} {% endblock %}
3
+{% block content %}
4
+
5
+<a href="{{ url_for('index') }}"><h1><span>searx</span></h1></a>
6
+
7
+<h2>{{ _('Engine stats') }}</h2>
8
+
9
+{% for stat_name,stat_category in stats %}
10
+<div class="left">
11
+    <table>
12
+        <tr colspan="3">
13
+            <th>{{ stat_name }}</th>
14
+        </tr>
15
+        {% for engine in stat_category %}
16
+        <tr>
17
+            <td>{{ engine.name }}</td>
18
+            <td>{{ '%.02f'|format(engine.avg) }}</td>
19
+            <td class="percentage"><div style="width: {{ engine.percentage }}%">&nbsp;</div></td>
20
+        </tr>
21
+        {% endfor %}
22
+    </table>
23
+</div>
24
+{% endfor %}
25
+{% endblock %}

+ 17
- 0
searx/templates/simple/time-range.html Datei anzeigen

@@ -0,0 +1,17 @@
1
+<select name="time_range" id="time_range" class="time_range" tabindex="3">{{- '' -}}
2
+    <option id="time-range-anytime" value="" {{ "selected" if time_range=="" or not time_range  else ""}}>
3
+        {{- _('Anytime') -}}
4
+    </option>{{- '' -}}
5
+    <option id="time-range-day" value="day" {{ "selected" if time_range=="day" else ""}}>
6
+        {{- _('Last day') -}}
7
+    </option>{{- '' -}}
8
+    <option id="time-range-week" value="week" {{ "selected" if time_range=="week" else ""}}>
9
+        {{- _('Last week') -}}
10
+    </option>{{- '' -}}
11
+    <option id="time-range-month" value="month" {{ "selected" if time_range=="month" else ""}}>
12
+        {{- _('Last month') -}}
13
+    </option>{{- '' -}}
14
+    <option id="time-range-year" value="year" {{ "selected" if time_range=="year" else ""}}>
15
+        {{- _('Last year') -}}
16
+    </option>{{- '' -}}
17
+</select>