diff options
Diffstat (limited to 'assets/vintage')
-rw-r--r-- | assets/vintage/css/shaarli.css | 61 | ||||
-rw-r--r-- | assets/vintage/js/base.js | 45 |
2 files changed, 88 insertions, 18 deletions
diff --git a/assets/vintage/css/shaarli.css b/assets/vintage/css/shaarli.css index 1688dce0..33e178af 100644 --- a/assets/vintage/css/shaarli.css +++ b/assets/vintage/css/shaarli.css | |||
@@ -1122,6 +1122,16 @@ ul.errors { | |||
1122 | float: left; | 1122 | float: left; |
1123 | } | 1123 | } |
1124 | 1124 | ||
1125 | ul.warnings { | ||
1126 | color: orange; | ||
1127 | float: left; | ||
1128 | } | ||
1129 | |||
1130 | ul.successes { | ||
1131 | color: green; | ||
1132 | float: left; | ||
1133 | } | ||
1134 | |||
1125 | #pluginsadmin { | 1135 | #pluginsadmin { |
1126 | width: 80%; | 1136 | width: 80%; |
1127 | padding: 20px 0 0 20px; | 1137 | padding: 20px 0 0 20px; |
@@ -1248,3 +1258,54 @@ ul.errors { | |||
1248 | width: 0%; | 1258 | width: 0%; |
1249 | height: 10px; | 1259 | height: 10px; |
1250 | } | 1260 | } |
1261 | |||
1262 | .loading-input { | ||
1263 | position: relative; | ||
1264 | } | ||
1265 | |||
1266 | @keyframes around { | ||
1267 | 0% { | ||
1268 | transform: rotate(0deg); | ||
1269 | } | ||
1270 | |||
1271 | 100% { | ||
1272 | transform: rotate(360deg); | ||
1273 | } | ||
1274 | } | ||
1275 | |||
1276 | .loading-input .icon-container { | ||
1277 | position: absolute; | ||
1278 | right: 60px; | ||
1279 | top: calc(50% - 10px); | ||
1280 | } | ||
1281 | |||
1282 | .loading-input .loader { | ||
1283 | position: relative; | ||
1284 | height: 20px; | ||
1285 | width: 20px; | ||
1286 | display: inline-block; | ||
1287 | animation: around 5.4s infinite; | ||
1288 | } | ||
1289 | |||
1290 | .loading-input .loader::after, | ||
1291 | .loading-input .loader::before { | ||
1292 | content: ""; | ||
1293 | background: #eee; | ||
1294 | position: absolute; | ||
1295 | display: inline-block; | ||
1296 | width: 100%; | ||
1297 | height: 100%; | ||
1298 | border-width: 2px; | ||
1299 | border-color: #333 #333 transparent transparent; | ||
1300 | border-style: solid; | ||
1301 | border-radius: 20px; | ||
1302 | box-sizing: border-box; | ||
1303 | top: 0; | ||
1304 | left: 0; | ||
1305 | animation: around 0.7s ease-in-out infinite; | ||
1306 | } | ||
1307 | |||
1308 | .loading-input .loader::after { | ||
1309 | animation: around 0.7s ease-in-out 0.1s infinite; | ||
1310 | background: transparent; | ||
1311 | } | ||
diff --git a/assets/vintage/js/base.js b/assets/vintage/js/base.js index 66830b59..55f1c37d 100644 --- a/assets/vintage/js/base.js +++ b/assets/vintage/js/base.js | |||
@@ -2,29 +2,38 @@ import Awesomplete from 'awesomplete'; | |||
2 | import 'awesomplete/awesomplete.css'; | 2 | import 'awesomplete/awesomplete.css'; |
3 | 3 | ||
4 | (() => { | 4 | (() => { |
5 | const awp = Awesomplete.$; | ||
6 | const autocompleteFields = document.querySelectorAll('input[data-multiple]'); | 5 | const autocompleteFields = document.querySelectorAll('input[data-multiple]'); |
6 | const tagsSeparatorElement = document.querySelector('input[name="tags_separator"]'); | ||
7 | const tagsSeparator = tagsSeparatorElement ? tagsSeparatorElement.value || ' ' : ' '; | ||
8 | |||
7 | [...autocompleteFields].forEach((autocompleteField) => { | 9 | [...autocompleteFields].forEach((autocompleteField) => { |
8 | const awesomplete = new Awesomplete(awp(autocompleteField)); | 10 | const awesome = new Awesomplete(Awesomplete.$(autocompleteField)); |
9 | awesomplete.filter = (text, input) => Awesomplete.FILTER_CONTAINS(text, input.match(/[^ ]*$/)[0]); | 11 | |
10 | awesomplete.replace = (text) => { | 12 | // Tags are separated by separator |
11 | const before = awesomplete.input.value.match(/^.+ \s*|/)[0]; | 13 | awesome.filter = (text, input) => Awesomplete.FILTER_CONTAINS( |
12 | awesomplete.input.value = `${before}${text} `; | 14 | text, |
15 | input.match(new RegExp(`[^${tagsSeparator}]*$`))[0], | ||
16 | ); | ||
17 | // Insert new selected tag in the input | ||
18 | awesome.replace = (text) => { | ||
19 | const before = awesome.input.value.match(new RegExp(`^.+${tagsSeparator}+|`))[0]; | ||
20 | awesome.input.value = `${before}${text}${tagsSeparator}`; | ||
13 | }; | 21 | }; |
14 | awesomplete.minChars = 1; | 22 | // Highlight found items |
23 | awesome.item = (text, input) => Awesomplete.ITEM(text, input.match(new RegExp(`[^${tagsSeparator}]*$`))[0]); | ||
15 | 24 | ||
16 | autocompleteField.addEventListener('input', () => { | 25 | // Don't display already selected items |
17 | const proposedTags = autocompleteField.getAttribute('data-list').replace(/,/g, '').split(' '); | 26 | // WARNING: pseudo classes does not seem to work with string litterals... |
18 | const reg = /(\w+) /g; | 27 | const reg = new RegExp(`([^${tagsSeparator}]+)${tagsSeparator}`, 'g'); |
19 | let match; | 28 | let match; |
20 | while ((match = reg.exec(autocompleteField.value)) !== null) { | 29 | awesome.data = (item, input) => { |
21 | const id = proposedTags.indexOf(match[1]); | 30 | while ((match = reg.exec(input))) { |
22 | if (id !== -1) { | 31 | if (item === match[1]) { |
23 | proposedTags.splice(id, 1); | 32 | return ''; |
24 | } | 33 | } |
25 | } | 34 | } |
26 | 35 | return item; | |
27 | awesomplete.list = proposedTags; | 36 | }; |
28 | }); | 37 | awesome.minChars = 1; |
29 | }); | 38 | }); |
30 | })(); | 39 | })(); |