diff options
author | ArthurHoaro <arthur@hoa.ro> | 2016-06-07 16:12:12 +0200 |
---|---|---|
committer | ArthurHoaro <arthur@hoa.ro> | 2016-08-07 12:17:36 +0200 |
commit | f791ba634e733811b3e10bb662e30cd5ba0b29e3 (patch) | |
tree | 7e76730965d3544bac2dcca460ea729273df8d7b | |
parent | 09d6e7e0503535f64f374f570037b0dbff09be7b (diff) | |
download | Shaarli-f791ba634e733811b3e10bb662e30cd5ba0b29e3.tar.gz Shaarli-f791ba634e733811b3e10bb662e30cd5ba0b29e3.tar.zst Shaarli-f791ba634e733811b3e10bb662e30cd5ba0b29e3.zip |
Edit link WIP + upgrade awesomplete
-rw-r--r-- | inc/awesomplete-multiple-tags.js | 21 | ||||
-rw-r--r-- | inc/awesomplete.js | 759 | ||||
-rw-r--r-- | inc/awesomplete.min.js | 20 | ||||
-rw-r--r-- | plugins/markdown/markdown.css | 4 | ||||
-rw-r--r-- | tpl/default/editlink.html | 82 |
5 files changed, 510 insertions, 376 deletions
diff --git a/inc/awesomplete-multiple-tags.js b/inc/awesomplete-multiple-tags.js index 4cc8429f..faecb417 100644 --- a/inc/awesomplete-multiple-tags.js +++ b/inc/awesomplete-multiple-tags.js | |||
@@ -1,13 +1,16 @@ | |||
1 | var awp = Awesomplete.$; | 1 | var awp = Awesomplete.$; |
2 | awesomplete = new Awesomplete(awp('input[data-multiple]'), { | 2 | var autocompleteFields = document.querySelectorAll('input[data-multiple]'); |
3 | filter: function(text, input) { | 3 | [].forEach.call(autocompleteFields, function(autocompleteField) { |
4 | return Awesomplete.FILTER_CONTAINS(text, input.match(/[^ ]*$/)[0]); | 4 | awesomplete = new Awesomplete(awp(autocompleteField), { |
5 | }, | 5 | filter: function (text, input) { |
6 | replace: function(text) { | 6 | return Awesomplete.FILTER_CONTAINS(text, input.match(/[^ ]*$/)[0]); |
7 | var before = this.input.value.match(/^.+ \s*|/)[0]; | 7 | }, |
8 | this.input.value = before + text + " "; | 8 | replace: function (text) { |
9 | }, | 9 | var before = this.input.value.match(/^.+ \s*|/)[0]; |
10 | minChars: 1 | 10 | this.input.value = before + text + " "; |
11 | }, | ||
12 | minChars: 1 | ||
13 | }) | ||
11 | }); | 14 | }); |
12 | 15 | ||
13 | /** | 16 | /** |
diff --git a/inc/awesomplete.js b/inc/awesomplete.js index fae550e2..7303652a 100644 --- a/inc/awesomplete.js +++ b/inc/awesomplete.js | |||
@@ -7,382 +7,433 @@ | |||
7 | 7 | ||
8 | (function () { | 8 | (function () { |
9 | 9 | ||
10 | var _ = function (input, o) { | 10 | var _ = function (input, o) { |
11 | var me = this; | 11 | var me = this; |
12 | 12 | ||
13 | // Setup | 13 | // Setup |
14 | 14 | ||
15 | this.input = $(input); | 15 | this.input = $(input); |
16 | this.input.setAttribute("aria-autocomplete", "list"); | 16 | this.input.setAttribute("autocomplete", "off"); |
17 | 17 | this.input.setAttribute("aria-autocomplete", "list"); | |
18 | o = o || {}; | 18 | |
19 | 19 | o = o || {}; | |
20 | configure.call(this, { | 20 | |
21 | minChars: 2, | 21 | configure(this, { |
22 | maxItems: 10, | 22 | minChars: 2, |
23 | autoFirst: false, | 23 | maxItems: 10, |
24 | filter: _.FILTER_CONTAINS, | 24 | autoFirst: false, |
25 | sort: _.SORT_BYLENGTH, | 25 | data: _.DATA, |
26 | item: function (text, input) { | 26 | filter: _.FILTER_CONTAINS, |
27 | return $.create("li", { | 27 | sort: _.SORT_BYLENGTH, |
28 | innerHTML: text.replace(RegExp($.regExpEscape(input.trim()), "gi"), "<mark>$&</mark>"), | 28 | item: _.ITEM, |
29 | "aria-selected": "false" | 29 | replace: _.REPLACE |
30 | }); | 30 | }, o); |
31 | }, | 31 | |
32 | replace: function (text) { | 32 | this.index = -1; |
33 | this.input.value = text; | 33 | |
34 | } | 34 | // Create necessary elements |
35 | }, o); | 35 | |
36 | 36 | this.container = $.create("div", { | |
37 | this.index = -1; | 37 | className: "awesomplete", |
38 | 38 | around: input | |
39 | // Create necessary elements | 39 | }); |
40 | 40 | ||
41 | this.container = $.create("div", { | 41 | this.ul = $.create("ul", { |
42 | className: "awesomplete", | 42 | hidden: "hidden", |
43 | around: input | 43 | inside: this.container |
44 | }); | 44 | }); |
45 | 45 | ||
46 | this.ul = $.create("ul", { | 46 | this.status = $.create("span", { |
47 | hidden: "", | 47 | className: "visually-hidden", |
48 | inside: this.container | 48 | role: "status", |
49 | }); | 49 | "aria-live": "assertive", |
50 | 50 | "aria-relevant": "additions", | |
51 | this.status = $.create("span", { | 51 | inside: this.container |
52 | className: "visually-hidden", | 52 | }); |
53 | role: "status", | 53 | |
54 | "aria-live": "assertive", | 54 | // Bind events |
55 | "aria-relevant": "additions", | 55 | |
56 | inside: this.container | 56 | $.bind(this.input, { |
57 | }); | 57 | "input": this.evaluate.bind(this), |
58 | 58 | "blur": this.close.bind(this), | |
59 | // Bind events | 59 | "keydown": function(evt) { |
60 | 60 | var c = evt.keyCode; | |
61 | $.bind(this.input, { | 61 | |
62 | "input": this.evaluate.bind(this), | 62 | // If the dropdown `ul` is in view, then act on keydown for the following keys: |
63 | "blur": this.close.bind(this), | 63 | // Enter / Esc / Up / Down |
64 | "keydown": function(evt) { | 64 | if(me.opened) { |
65 | var c = evt.keyCode; | 65 | if (c === 13 && me.selected) { // Enter |
66 | 66 | evt.preventDefault(); | |
67 | // If the dropdown `ul` is in view, then act on keydown for the following keys: | 67 | me.select(); |
68 | // Enter / Esc / Up / Down | 68 | } |
69 | if(me.opened) { | 69 | else if (c === 27) { // Esc |
70 | if (c === 13 && me.selected) { // Enter | 70 | me.close(); |
71 | evt.preventDefault(); | 71 | } |
72 | me.select(); | 72 | else if (c === 38 || c === 40) { // Down/Up arrow |
73 | } | 73 | evt.preventDefault(); |
74 | else if (c === 27) { // Esc | 74 | me[c === 38? "previous" : "next"](); |
75 | me.close(); | 75 | } |
76 | } | 76 | } |
77 | else if (c === 38 || c === 40) { // Down/Up arrow | 77 | } |
78 | evt.preventDefault(); | 78 | }); |
79 | me[c === 38? "previous" : "next"](); | 79 | |
80 | } | 80 | $.bind(this.input.form, {"submit": this.close.bind(this)}); |
81 | } | 81 | |
82 | } | 82 | $.bind(this.ul, {"mousedown": function(evt) { |
83 | }); | 83 | var li = evt.target; |
84 | 84 | ||
85 | $.bind(this.input.form, {"submit": this.close.bind(this)}); | 85 | if (li !== this) { |
86 | 86 | ||
87 | $.bind(this.ul, {"mousedown": function(evt) { | 87 | while (li && !/li/i.test(li.nodeName)) { |
88 | var li = evt.target; | 88 | li = li.parentNode; |
89 | 89 | } | |
90 | if (li !== this) { | 90 | |
91 | 91 | if (li && evt.button === 0) { // Only select on left click | |
92 | while (li && !/li/i.test(li.nodeName)) { | 92 | evt.preventDefault(); |
93 | li = li.parentNode; | 93 | me.select(li, evt.target); |
94 | } | 94 | } |
95 | 95 | } | |
96 | if (li) { | 96 | }}); |
97 | me.select(li); | 97 | |
98 | } | 98 | if (this.input.hasAttribute("list")) { |
99 | } | 99 | this.list = "#" + this.input.getAttribute("list"); |
100 | }}); | 100 | this.input.removeAttribute("list"); |
101 | 101 | } | |
102 | if (this.input.hasAttribute("list")) { | 102 | else { |
103 | this.list = "#" + input.getAttribute("list"); | 103 | this.list = this.input.getAttribute("data-list") || o.list || []; |
104 | input.removeAttribute("list"); | 104 | } |
105 | } | 105 | |
106 | else { | 106 | _.all.push(this); |
107 | this.list = this.input.getAttribute("data-list") || o.list || []; | 107 | }; |
108 | } | 108 | |
109 | 109 | _.prototype = { | |
110 | _.all.push(this); | 110 | set list(list) { |
111 | }; | 111 | if (Array.isArray(list)) { |
112 | 112 | this._list = list; | |
113 | _.prototype = { | 113 | } |
114 | set list(list) { | 114 | else if (typeof list === "string" && list.indexOf(",") > -1) { |
115 | if (Array.isArray(list)) { | 115 | this._list = list.split(/\s*,\s*/); |
116 | this._list = list; | 116 | } |
117 | } | 117 | else { // Element or CSS selector |
118 | else if (typeof list === "string" && list.indexOf(",") > -1) { | 118 | list = $(list); |
119 | this._list = list.split(/\s*,\s*/); | 119 | |
120 | } | 120 | if (list && list.children) { |
121 | else { // Element or CSS selector | 121 | var items = []; |
122 | list = $(list); | 122 | slice.apply(list.children).forEach(function (el) { |
123 | 123 | if (!el.disabled) { | |
124 | if (list && list.children) { | 124 | var text = el.textContent.trim(); |
125 | this._list = slice.apply(list.children).map(function (el) { | 125 | var value = el.value || text; |
126 | return el.innerHTML.trim(); | 126 | var label = el.label || text; |
127 | }); | 127 | if (value !== "") { |
128 | } | 128 | items.push({ label: label, value: value }); |
129 | } | 129 | } |
130 | 130 | } | |
131 | if (document.activeElement === this.input) { | 131 | }); |
132 | this.evaluate(); | 132 | this._list = items; |
133 | } | 133 | } |
134 | }, | 134 | } |
135 | 135 | ||
136 | get selected() { | 136 | if (document.activeElement === this.input) { |
137 | return this.index > -1; | 137 | this.evaluate(); |
138 | }, | 138 | } |
139 | 139 | }, | |
140 | get opened() { | 140 | |
141 | return this.ul && this.ul.getAttribute("hidden") == null; | 141 | get selected() { |
142 | }, | 142 | return this.index > -1; |
143 | 143 | }, | |
144 | close: function () { | 144 | |
145 | this.ul.setAttribute("hidden", ""); | 145 | get opened() { |
146 | this.index = -1; | 146 | return !this.ul.hasAttribute("hidden"); |
147 | 147 | }, | |
148 | $.fire(this.input, "awesomplete-close"); | 148 | |
149 | }, | 149 | close: function () { |
150 | 150 | this.ul.setAttribute("hidden", ""); | |
151 | open: function () { | 151 | this.index = -1; |
152 | this.ul.removeAttribute("hidden"); | 152 | |
153 | 153 | $.fire(this.input, "awesomplete-close"); | |
154 | if (this.autoFirst && this.index === -1) { | 154 | }, |
155 | this.goto(0); | 155 | |
156 | } | 156 | open: function () { |
157 | 157 | this.ul.removeAttribute("hidden"); | |
158 | $.fire(this.input, "awesomplete-open"); | 158 | |
159 | }, | 159 | if (this.autoFirst && this.index === -1) { |
160 | 160 | this.goto(0); | |
161 | next: function () { | 161 | } |
162 | var count = this.ul.children.length; | 162 | |
163 | 163 | $.fire(this.input, "awesomplete-open"); | |
164 | this.goto(this.index < count - 1? this.index + 1 : -1); | 164 | }, |
165 | }, | 165 | |
166 | 166 | next: function () { | |
167 | previous: function () { | 167 | var count = this.ul.children.length; |
168 | var count = this.ul.children.length; | 168 | |
169 | 169 | this.goto(this.index < count - 1? this.index + 1 : -1); | |
170 | this.goto(this.selected? this.index - 1 : count - 1); | 170 | }, |
171 | }, | 171 | |
172 | 172 | previous: function () { | |
173 | // Should not be used, highlights specific item without any checks! | 173 | var count = this.ul.children.length; |
174 | goto: function (i) { | 174 | |
175 | var lis = this.ul.children; | 175 | this.goto(this.selected? this.index - 1 : count - 1); |
176 | 176 | }, | |
177 | if (this.selected) { | 177 | |
178 | lis[this.index].setAttribute("aria-selected", "false"); | 178 | // Should not be used, highlights specific item without any checks! |
179 | } | 179 | goto: function (i) { |
180 | 180 | var lis = this.ul.children; | |
181 | this.index = i; | 181 | |
182 | 182 | if (this.selected) { | |
183 | if (i > -1 && lis.length > 0) { | 183 | lis[this.index].setAttribute("aria-selected", "false"); |
184 | lis[i].setAttribute("aria-selected", "true"); | 184 | } |
185 | this.status.textContent = lis[i].textContent; | 185 | |
186 | } | 186 | this.index = i; |
187 | 187 | ||
188 | $.fire(this.input, "awesomplete-highlight"); | 188 | if (i > -1 && lis.length > 0) { |
189 | }, | 189 | lis[i].setAttribute("aria-selected", "true"); |
190 | 190 | this.status.textContent = lis[i].textContent; | |
191 | select: function (selected) { | 191 | |
192 | selected = selected || this.ul.children[this.index]; | 192 | $.fire(this.input, "awesomplete-highlight", { |
193 | 193 | text: this.suggestions[this.index] | |
194 | if (selected) { | 194 | }); |
195 | var prevented; | 195 | } |
196 | 196 | }, | |
197 | $.fire(this.input, "awesomplete-select", { | 197 | |
198 | text: selected.textContent, | 198 | select: function (selected, origin) { |
199 | preventDefault: function () { | 199 | if (selected) { |
200 | prevented = true; | 200 | this.index = $.siblingIndex(selected); |
201 | } | 201 | } else { |
202 | }); | 202 | selected = this.ul.children[this.index]; |
203 | 203 | } | |
204 | if (!prevented) { | 204 | |
205 | this.replace(selected.textContent); | 205 | if (selected) { |
206 | this.close(); | 206 | var suggestion = this.suggestions[this.index]; |
207 | $.fire(this.input, "awesomplete-selectcomplete"); | 207 | |
208 | } | 208 | var allowed = $.fire(this.input, "awesomplete-select", { |
209 | } | 209 | text: suggestion, |
210 | }, | 210 | origin: origin || selected |
211 | 211 | }); | |
212 | evaluate: function() { | 212 | |
213 | var me = this; | 213 | if (allowed) { |
214 | var value = this.input.value; | 214 | this.replace(suggestion); |
215 | 215 | this.close(); | |
216 | if (value.length >= this.minChars && this._list.length > 0) { | 216 | $.fire(this.input, "awesomplete-selectcomplete", { |
217 | this.index = -1; | 217 | text: suggestion |
218 | // Populate list with options that match | 218 | }); |
219 | this.ul.innerHTML = ""; | 219 | } |
220 | 220 | } | |
221 | this._list | 221 | }, |
222 | .filter(function(item) { | 222 | |
223 | return me.filter(item, value); | 223 | evaluate: function() { |
224 | }) | 224 | var me = this; |
225 | .sort(this.sort) | 225 | var value = this.input.value; |
226 | .every(function(text, i) { | 226 | |
227 | me.ul.appendChild(me.item(text, value)); | 227 | if (value.length >= this.minChars && this._list.length > 0) { |
228 | 228 | this.index = -1; | |
229 | return i < me.maxItems - 1; | 229 | // Populate list with options that match |
230 | }); | 230 | this.ul.innerHTML = ""; |
231 | 231 | ||
232 | if (this.ul.children.length === 0) { | 232 | this.suggestions = this._list |
233 | this.close(); | 233 | .map(function(item) { |
234 | } else { | 234 | return new Suggestion(me.data(item, value)); |
235 | this.open(); | 235 | }) |
236 | } | 236 | .filter(function(item) { |
237 | } | 237 | return me.filter(item, value); |
238 | else { | 238 | }) |
239 | this.close(); | 239 | .sort(this.sort) |
240 | } | 240 | .slice(0, this.maxItems); |
241 | } | 241 | |
242 | }; | 242 | this.suggestions.forEach(function(text) { |
243 | me.ul.appendChild(me.item(text, value)); | ||
244 | }); | ||
245 | |||
246 | if (this.ul.children.length === 0) { | ||
247 | this.close(); | ||
248 | } else { | ||
249 | this.open(); | ||
250 | } | ||
251 | } | ||
252 | else { | ||
253 | this.close(); | ||
254 | } | ||
255 | } | ||
256 | }; | ||
243 | 257 | ||
244 | // Static methods/properties | 258 | // Static methods/properties |
245 | 259 | ||
246 | _.all = []; | 260 | _.all = []; |
247 | 261 | ||
248 | _.FILTER_CONTAINS = function (text, input) { | 262 | _.FILTER_CONTAINS = function (text, input) { |
249 | return RegExp($.regExpEscape(input.trim()), "i").test(text); | 263 | return RegExp($.regExpEscape(input.trim()), "i").test(text); |
250 | }; | 264 | }; |
251 | 265 | ||
252 | _.FILTER_STARTSWITH = function (text, input) { | 266 | _.FILTER_STARTSWITH = function (text, input) { |
253 | return RegExp("^" + $.regExpEscape(input.trim()), "i").test(text); | 267 | return RegExp("^" + $.regExpEscape(input.trim()), "i").test(text); |
254 | }; | 268 | }; |
255 | 269 | ||
256 | _.SORT_BYLENGTH = function (a, b) { | 270 | _.SORT_BYLENGTH = function (a, b) { |
257 | if (a.length !== b.length) { | 271 | if (a.length !== b.length) { |
258 | return a.length - b.length; | 272 | return a.length - b.length; |
259 | } | 273 | } |
260 | 274 | ||
261 | return a < b? -1 : 1; | 275 | return a < b? -1 : 1; |
262 | }; | 276 | }; |
277 | |||
278 | _.ITEM = function (text, input) { | ||
279 | var html = input === '' ? text : text.replace(RegExp($.regExpEscape(input.trim()), "gi"), "<mark>$&</mark>"); | ||
280 | return $.create("li", { | ||
281 | innerHTML: html, | ||
282 | "aria-selected": "false" | ||
283 | }); | ||
284 | }; | ||
285 | |||
286 | _.REPLACE = function (text) { | ||
287 | this.input.value = text.value; | ||
288 | }; | ||
289 | |||
290 | _.DATA = function (item/*, input*/) { return item; }; | ||
263 | 291 | ||
264 | // Private functions | 292 | // Private functions |
265 | 293 | ||
266 | function configure(properties, o) { | 294 | function Suggestion(data) { |
267 | for (var i in properties) { | 295 | var o = Array.isArray(data) |
268 | var initial = properties[i], | 296 | ? { label: data[0], value: data[1] } |
269 | attrValue = this.input.getAttribute("data-" + i.toLowerCase()); | 297 | : typeof data === "object" && "label" in data && "value" in data ? data : { label: data, value: data }; |
270 | 298 | ||
271 | if (typeof initial === "number") { | 299 | this.label = o.label || o.value; |
272 | this[i] = +attrValue; | 300 | this.value = o.value; |
273 | } | 301 | } |
274 | else if (initial === false) { // Boolean options must be false by default anyway | 302 | Object.defineProperty(Suggestion.prototype = Object.create(String.prototype), "length", { |
275 | this[i] = attrValue !== null; | 303 | get: function() { return this.label.length; } |
276 | } | 304 | }); |
277 | else if (initial instanceof Function) { | 305 | Suggestion.prototype.toString = Suggestion.prototype.valueOf = function () { |
278 | this[i] = null; | 306 | return "" + this.label; |
279 | } | 307 | }; |
280 | else { | 308 | |
281 | this[i] = attrValue; | 309 | function configure(instance, properties, o) { |
282 | } | 310 | for (var i in properties) { |
283 | 311 | var initial = properties[i], | |
284 | this[i] = this[i] || o[i] || initial; | 312 | attrValue = instance.input.getAttribute("data-" + i.toLowerCase()); |
285 | } | 313 | |
286 | } | 314 | if (typeof initial === "number") { |
315 | instance[i] = parseInt(attrValue); | ||
316 | } | ||
317 | else if (initial === false) { // Boolean options must be false by default anyway | ||
318 | instance[i] = attrValue !== null; | ||
319 | } | ||
320 | else if (initial instanceof Function) { | ||
321 | instance[i] = null; | ||
322 | } | ||
323 | else { | ||
324 | instance[i] = attrValue; | ||
325 | } | ||
326 | |||
327 | if (!instance[i] && instance[i] !== 0) { | ||
328 | instance[i] = (i in o)? o[i] : initial; | ||
329 | } | ||
330 | } | ||
331 | } | ||
287 | 332 | ||
288 | // Helpers | 333 | // Helpers |
289 | 334 | ||
290 | var slice = Array.prototype.slice; | 335 | var slice = Array.prototype.slice; |
291 | 336 | ||
292 | function $(expr, con) { | 337 | function $(expr, con) { |
293 | return typeof expr === "string"? (con || document).querySelector(expr) : expr || null; | 338 | return typeof expr === "string"? (con || document).querySelector(expr) : expr || null; |
294 | } | 339 | } |
295 | 340 | ||
296 | function $$(expr, con) { | 341 | function $$(expr, con) { |
297 | return slice.call((con || document).querySelectorAll(expr)); | 342 | return slice.call((con || document).querySelectorAll(expr)); |
298 | } | 343 | } |
299 | 344 | ||
300 | $.create = function(tag, o) { | 345 | $.create = function(tag, o) { |
301 | var element = document.createElement(tag); | 346 | var element = document.createElement(tag); |
302 | 347 | ||
303 | for (var i in o) { | 348 | for (var i in o) { |
304 | var val = o[i]; | 349 | var val = o[i]; |
305 | 350 | ||
306 | if (i === "inside") { | 351 | if (i === "inside") { |
307 | $(val).appendChild(element); | 352 | $(val).appendChild(element); |
308 | } | 353 | } |
309 | else if (i === "around") { | 354 | else if (i === "around") { |
310 | var ref = $(val); | 355 | var ref = $(val); |
311 | ref.parentNode.insertBefore(element, ref); | 356 | ref.parentNode.insertBefore(element, ref); |
312 | element.appendChild(ref); | 357 | element.appendChild(ref); |
313 | } | 358 | } |
314 | else if (i in element) { | 359 | else if (i in element) { |
315 | element[i] = val; | 360 | element[i] = val; |
316 | } | 361 | } |
317 | else { | 362 | else { |
318 | element.setAttribute(i, val); | 363 | element.setAttribute(i, val); |
319 | } | 364 | } |
320 | } | 365 | } |
321 | 366 | ||
322 | return element; | 367 | return element; |
323 | }; | 368 | }; |
324 | 369 | ||
325 | $.bind = function(element, o) { | 370 | $.bind = function(element, o) { |
326 | if (element) { | 371 | if (element) { |
327 | for (var event in o) { | 372 | for (var event in o) { |
328 | var callback = o[event]; | 373 | var callback = o[event]; |
329 | 374 | ||
330 | event.split(/\s+/).forEach(function (event) { | 375 | event.split(/\s+/).forEach(function (event) { |
331 | element.addEventListener(event, callback); | 376 | element.addEventListener(event, callback); |
332 | }); | 377 | }); |
333 | } | 378 | } |
334 | } | 379 | } |
335 | }; | 380 | }; |
336 | 381 | ||
337 | $.fire = function(target, type, properties) { | 382 | $.fire = function(target, type, properties) { |
338 | var evt = document.createEvent("HTMLEvents"); | 383 | var evt = document.createEvent("HTMLEvents"); |
339 | 384 | ||
340 | evt.initEvent(type, true, true ); | 385 | evt.initEvent(type, true, true ); |
341 | 386 | ||
342 | for (var j in properties) { | 387 | for (var j in properties) { |
343 | evt[j] = properties[j]; | 388 | evt[j] = properties[j]; |
344 | } | 389 | } |
345 | 390 | ||
346 | target.dispatchEvent(evt); | 391 | return target.dispatchEvent(evt); |
347 | }; | 392 | }; |
348 | 393 | ||
349 | $.regExpEscape = function (s) { | 394 | $.regExpEscape = function (s) { |
350 | return s.replace(/[-\\^$*+?.()|[\]{}]/g, "\\$&"); | 395 | return s.replace(/[-\\^$*+?.()|[\]{}]/g, "\\$&"); |
351 | } | 396 | }; |
397 | |||
398 | $.siblingIndex = function (el) { | ||
399 | /* eslint-disable no-cond-assign */ | ||
400 | for (var i = 0; el = el.previousElementSibling; i++); | ||
401 | return i; | ||
402 | }; | ||
352 | 403 | ||
353 | // Initialization | 404 | // Initialization |
354 | 405 | ||
355 | function init() { | 406 | function init() { |
356 | $$("input.awesomplete").forEach(function (input) { | 407 | $$("input.awesomplete").forEach(function (input) { |
357 | new Awesomplete(input); | 408 | new _(input); |
358 | }); | 409 | }); |
359 | } | 410 | } |
360 | 411 | ||
361 | // Are we in a browser? Check for Document constructor | 412 | // Are we in a browser? Check for Document constructor |
362 | if (typeof Document !== 'undefined') { | 413 | if (typeof Document !== "undefined") { |
363 | // DOM already loaded? | 414 | // DOM already loaded? |
364 | if (document.readyState !== "loading") { | 415 | if (document.readyState !== "loading") { |
365 | init(); | 416 | init(); |
366 | } | 417 | } |
367 | else { | 418 | else { |
368 | // Wait for it | 419 | // Wait for it |
369 | document.addEventListener("DOMContentLoaded", init); | 420 | document.addEventListener("DOMContentLoaded", init); |
370 | } | 421 | } |
371 | } | 422 | } |
372 | 423 | ||
373 | _.$ = $; | 424 | _.$ = $; |
374 | _.$$ = $$; | 425 | _.$$ = $$; |
375 | 426 | ||
376 | // Make sure to export Awesomplete on self when in a browser | 427 | // Make sure to export Awesomplete on self when in a browser |
377 | if (typeof self !== 'undefined') { | 428 | if (typeof self !== "undefined") { |
378 | self.Awesomplete = _; | 429 | self.Awesomplete = _; |
379 | } | 430 | } |
380 | 431 | ||
381 | // Expose Awesomplete as a CJS module | 432 | // Expose Awesomplete as a CJS module |
382 | if (typeof exports === 'object') { | 433 | if (typeof module === "object" && module.exports) { |
383 | module.exports = _; | 434 | module.exports = _; |
384 | } | 435 | } |
385 | 436 | ||
386 | return _; | 437 | return _; |
387 | 438 | ||
388 | }()); | 439 | }()); |
diff --git a/inc/awesomplete.min.js b/inc/awesomplete.min.js index 3bfb05e8..bd750c83 100644 --- a/inc/awesomplete.min.js +++ b/inc/awesomplete.min.js | |||
@@ -1,10 +1,12 @@ | |||
1 | // Awesomplete - Lea Verou - MIT license | 1 | // Awesomplete - Lea Verou - MIT license |
2 | (function(){function m(a,b){for(var c in a){var f=a[c],e=this.input.getAttribute("data-"+c.toLowerCase());this[c]="number"===typeof f?+e:!1===f?null!==e:f instanceof Function?null:e;this[c]=this[c]||b[c]||f}}function d(a,b){return"string"===typeof a?(b||document).querySelector(a):a||null}function h(a,b){return k.call((b||document).querySelectorAll(a))}function l(){h("input.awesomplete").forEach(function(a){new Awesomplete(a)})}var g=self.Awesomplete=function(a,b){var c=this;this.input=d(a);this.input.setAttribute("aria-autocomplete", | 2 | (function(){function h(a){a=Array.isArray(a)?{label:a[0],value:a[1]}:"object"===typeof a&&"label"in a&&"value"in a?a:{label:a,value:a};this.label=a.label||a.value;this.value=a.value}function n(a,b,d){for(var g in b){var f=b[g],c=a.input.getAttribute("data-"+g.toLowerCase());a[g]="number"===typeof f?parseInt(c):!1===f?null!==c:f instanceof Function?null:c;a[g]||0===a[g]||(a[g]=g in d?d[g]:f)}}function c(a,b){return"string"===typeof a?(b||document).querySelector(a):a||null}function k(a,b){return l.call((b|| |
3 | "list");b=b||{};m.call(this,{minChars:2,maxItems:10,autoFirst:!1,filter:g.FILTER_CONTAINS,sort:g.SORT_BYLENGTH,item:function(a,b){return d.create("li",{innerHTML:a.replace(RegExp(d.regExpEscape(b.trim()),"gi"),"<mark>$&</mark>"),"aria-selected":"false"})},replace:function(a){this.input.value=a}},b);this.index=-1;this.container=d.create("div",{className:"awesomplete",around:a});this.ul=d.create("ul",{hidden:"",inside:this.container});this.status=d.create("span",{className:"visually-hidden",role:"status", | 3 | document).querySelectorAll(a))}function m(){k("input.awesomplete").forEach(function(a){new e(a)})}var e=function(a,b){var d=this;this.input=c(a);this.input.setAttribute("autocomplete","off");this.input.setAttribute("aria-autocomplete","list");b=b||{};n(this,{minChars:2,maxItems:10,autoFirst:!1,data:e.DATA,filter:e.FILTER_CONTAINS,sort:e.SORT_BYLENGTH,item:e.ITEM,replace:e.REPLACE},b);this.index=-1;this.container=c.create("div",{className:"awesomplete",around:a});this.ul=c.create("ul",{hidden:"hidden", |
4 | "aria-live":"assertive","aria-relevant":"additions",inside:this.container});d.bind(this.input,{input:this.evaluate.bind(this),blur:this.close.bind(this),keydown:function(a){var b=a.keyCode;if(c.opened)if(13===b&&c.selected)a.preventDefault(),c.select();else if(27===b)c.close();else if(38===b||40===b)a.preventDefault(),c[38===b?"previous":"next"]()}});d.bind(this.input.form,{submit:this.close.bind(this)});d.bind(this.ul,{mousedown:function(a){a=a.target;if(a!==this){for(;a&&!/li/i.test(a.nodeName);)a= | 4 | inside:this.container});this.status=c.create("span",{className:"visually-hidden",role:"status","aria-live":"assertive","aria-relevant":"additions",inside:this.container});c.bind(this.input,{input:this.evaluate.bind(this),blur:this.close.bind(this),keydown:function(a){var b=a.keyCode;if(d.opened)if(13===b&&d.selected)a.preventDefault(),d.select();else if(27===b)d.close();else if(38===b||40===b)a.preventDefault(),d[38===b?"previous":"next"]()}});c.bind(this.input.form,{submit:this.close.bind(this)}); |
5 | a.parentNode;a&&c.select(a)}}});this.input.hasAttribute("list")?(this.list="#"+a.getAttribute("list"),a.removeAttribute("list")):this.list=this.input.getAttribute("data-list")||b.list||[];g.all.push(this)};g.prototype={set list(a){Array.isArray(a)?this._list=a:"string"===typeof a&&-1<a.indexOf(",")?this._list=a.split(/\s*,\s*/):(a=d(a))&&a.children&&(this._list=k.apply(a.children).map(function(a){return a.innerHTML.trim()}));document.activeElement===this.input&&this.evaluate()},get selected(){return-1< | 5 | c.bind(this.ul,{mousedown:function(a){var b=a.target;if(b!==this){for(;b&&!/li/i.test(b.nodeName);)b=b.parentNode;b&&0===a.button&&(a.preventDefault(),d.select(b,a.target))}}});this.input.hasAttribute("list")?(this.list="#"+this.input.getAttribute("list"),this.input.removeAttribute("list")):this.list=this.input.getAttribute("data-list")||b.list||[];e.all.push(this)};e.prototype={set list(a){if(Array.isArray(a))this._list=a;else if("string"===typeof a&&-1<a.indexOf(","))this._list=a.split(/\s*,\s*/); |
6 | this.index},get opened(){return this.ul&&null==this.ul.getAttribute("hidden")},close:function(){this.ul.setAttribute("hidden","");this.index=-1;d.fire(this.input,"awesomplete-close")},open:function(){this.ul.removeAttribute("hidden");this.autoFirst&&-1===this.index&&this.goto(0);d.fire(this.input,"awesomplete-open")},next:function(){this.goto(this.index<this.ul.children.length-1?this.index+1:-1)},previous:function(){var a=this.ul.children.length;this.goto(this.selected?this.index-1:a-1)},goto:function(a){var b= | 6 | else if((a=c(a))&&a.children){var b=[];l.apply(a.children).forEach(function(a){if(!a.disabled){var c=a.textContent.trim(),f=a.value||c;a=a.label||c;""!==f&&b.push({label:a,value:f})}});this._list=b}document.activeElement===this.input&&this.evaluate()},get selected(){return-1<this.index},get opened(){return!this.ul.hasAttribute("hidden")},close:function(){this.ul.setAttribute("hidden","");this.index=-1;c.fire(this.input,"awesomplete-close")},open:function(){this.ul.removeAttribute("hidden");this.autoFirst&& |
7 | this.ul.children;this.selected&&b[this.index].setAttribute("aria-selected","false");this.index=a;-1<a&&0<b.length&&(b[a].setAttribute("aria-selected","true"),this.status.textContent=b[a].textContent)},select:function(a){if(a=a||this.ul.children[this.index]){var b;d.fire(this.input,"awesomplete-select",{text:a.textContent,preventDefault:function(){b=!0}});b||(this.replace(a.textContent),this.close(),d.fire(this.input,"awesomplete-selectcomplete"))}},evaluate:function(){var a=this,b=this.input.value; | 7 | -1===this.index&&this["goto"](0);c.fire(this.input,"awesomplete-open")},next:function(){this["goto"](this.index<this.ul.children.length-1?this.index+1:-1)},previous:function(){var a=this.ul.children.length;this["goto"](this.selected?this.index-1:a-1)},"goto":function(a){var b=this.ul.children;this.selected&&b[this.index].setAttribute("aria-selected","false");this.index=a;-1<a&&0<b.length&&(b[a].setAttribute("aria-selected","true"),this.status.textContent=b[a].textContent,c.fire(this.input,"awesomplete-highlight", |
8 | b.length>=this.minChars&&0<this._list.length?(this.index=-1,this.ul.innerHTML="",this._list.filter(function(c){return a.filter(c,b)}).sort(this.sort).every(function(c,d){a.ul.appendChild(a.item(c,b));return d<a.maxItems-1}),0===this.ul.children.length?this.close():this.open()):this.close()}};g.all=[];g.FILTER_CONTAINS=function(a,b){return RegExp(d.regExpEscape(b.trim()),"i").test(a)};g.FILTER_STARTSWITH=function(a,b){return RegExp("^"+d.regExpEscape(b.trim()),"i").test(a)};g.SORT_BYLENGTH=function(a, | 8 | {text:this.suggestions[this.index]}))},select:function(a,b){a?this.index=c.siblingIndex(a):a=this.ul.children[this.index];if(a){var d=this.suggestions[this.index];c.fire(this.input,"awesomplete-select",{text:d,origin:b||a})&&(this.replace(d),this.close(),c.fire(this.input,"awesomplete-selectcomplete",{text:d}))}},evaluate:function(){var a=this,b=this.input.value;b.length>=this.minChars&&0<this._list.length?(this.index=-1,this.ul.innerHTML="",this.suggestions=this._list.map(function(d){return new h(a.data(d, |
9 | b){return a.length!==b.length?a.length-b.length:a<b?-1:1};var k=Array.prototype.slice;d.create=function(a,b){var c=document.createElement(a),f;for(f in b){var e=b[f];"inside"===f?d(e).appendChild(c):"around"===f?(e=d(e),e.parentNode.insertBefore(c,e),c.appendChild(e)):f in c?c[f]=e:c.setAttribute(f,e)}return c};d.bind=function(a,b){if(a)for(var c in b){var d=b[c];c.split(/\s+/).forEach(function(b){a.addEventListener(b,d)})}};d.fire=function(a,b,c){var d=document.createEvent("HTMLEvents");d.initEvent(b, | 9 | b))}).filter(function(d){return a.filter(d,b)}).sort(this.sort).slice(0,this.maxItems),this.suggestions.forEach(function(d){a.ul.appendChild(a.item(d,b))}),0===this.ul.children.length?this.close():this.open()):this.close()}};e.all=[];e.FILTER_CONTAINS=function(a,b){return RegExp(c.regExpEscape(b.trim()),"i").test(a)};e.FILTER_STARTSWITH=function(a,b){return RegExp("^"+c.regExpEscape(b.trim()),"i").test(a)};e.SORT_BYLENGTH=function(a,b){return a.length!==b.length?a.length-b.length:a<b?-1:1};e.ITEM= |
10 | !0,!0);for(var e in c)d[e]=c[e];a.dispatchEvent(d)};d.regExpEscape=function(a){return a.replace(/[-\\^$*+?.()|[\]{}]/g,"\\$&")};"loading"!==document.readyState?l():document.addEventListener("DOMContentLoaded",l);g.$=d;g.$$=h})(); | 10 | function(a,b){var d=""===b?a:a.replace(RegExp(c.regExpEscape(b.trim()),"gi"),"<mark>$&</mark>");return c.create("li",{innerHTML:d,"aria-selected":"false"})};e.REPLACE=function(a){this.input.value=a.value};e.DATA=function(a){return a};Object.defineProperty(h.prototype=Object.create(String.prototype),"length",{get:function(){return this.label.length}});h.prototype.toString=h.prototype.valueOf=function(){return""+this.label};var l=Array.prototype.slice;c.create=function(a,b){var d=document.createElement(a), |
11 | g;for(g in b){var f=b[g];"inside"===g?c(f).appendChild(d):"around"===g?(f=c(f),f.parentNode.insertBefore(d,f),d.appendChild(f)):g in d?d[g]=f:d.setAttribute(g,f)}return d};c.bind=function(a,b){if(a)for(var d in b){var c=b[d];d.split(/\s+/).forEach(function(b){a.addEventListener(b,c)})}};c.fire=function(a,b,c){var e=document.createEvent("HTMLEvents");e.initEvent(b,!0,!0);for(var f in c)e[f]=c[f];return a.dispatchEvent(e)};c.regExpEscape=function(a){return a.replace(/[-\\^$*+?.()|[\]{}]/g,"\\$&")}; | ||
12 | c.siblingIndex=function(a){for(var b=0;a=a.previousElementSibling;b++);return b};"undefined"!==typeof Document&&("loading"!==document.readyState?m():document.addEventListener("DOMContentLoaded",m));e.$=c;e.$$=k;"undefined"!==typeof self&&(self.Awesomplete=e);"object"===typeof module&&module.exports&&(module.exports=e);return e})(); \ No newline at end of file | ||
diff --git a/plugins/markdown/markdown.css b/plugins/markdown/markdown.css index 8f2c0051..33702564 100644 --- a/plugins/markdown/markdown.css +++ b/plugins/markdown/markdown.css | |||
@@ -150,10 +150,6 @@ | |||
150 | box-shadow: 0 -1px 0 #e5e5e5,0 0 1px rgba(0,0,0,0.12),0 1px 1px rgba(0,0,0,0.24); | 150 | box-shadow: 0 -1px 0 #e5e5e5,0 0 1px rgba(0,0,0,0.12),0 1px 1px rgba(0,0,0,0.24); |
151 | } | 151 | } |
152 | 152 | ||
153 | .md_help { | ||
154 | color: white; | ||
155 | } | ||
156 | |||
157 | /* | 153 | /* |
158 | Remove header links style | 154 | Remove header links style |
159 | */ | 155 | */ |
diff --git a/tpl/default/editlink.html b/tpl/default/editlink.html new file mode 100644 index 00000000..f831655c --- /dev/null +++ b/tpl/default/editlink.html | |||
@@ -0,0 +1,82 @@ | |||
1 | <!DOCTYPE html> | ||
2 | <html> | ||
3 | <head> | ||
4 | {include="includes"} | ||
5 | </head> | ||
6 | <body> | ||
7 | {if="$source !== 'firefoxsocialapi'"} | ||
8 | {include="page.header"} | ||
9 | {/if} | ||
10 | <div id="editlinkform" class="pure-g"> | ||
11 | <div class="pure-u-lg-1-5 pure-u-1-8"></div> | ||
12 | <form method="post" name="linkform" class="page-form pure-u-lg-3-5 pure-u-3-4" > | ||
13 | <h2>Shaare</h2> | ||
14 | <input type="hidden" name="lf_linkdate" value="{$link.linkdate}"> | ||
15 | <div> | ||
16 | <label for="lf_url">URL</label> | ||
17 | </div> | ||
18 | <div> | ||
19 | <input type="text" name="lf_url" id="lf_url" value="{$link.url}" class="lf_input"> | ||
20 | </div> | ||
21 | <div> | ||
22 | <label for="lf_title">Title</label> | ||
23 | </div> | ||
24 | <div> | ||
25 | <input type="text" name="lf_title" id="lf_title" value="{$link.title}" class="lf_input"> | ||
26 | </div> | ||
27 | <div> | ||
28 | <label for="lf_description">Description</label> | ||
29 | </div> | ||
30 | <div> | ||
31 | <textarea name="lf_description" id="lf_description">{$link.description}</textarea> | ||
32 | </div> | ||
33 | <div> | ||
34 | <label for="lf_tags">Tags</label> | ||
35 | </div> | ||
36 | <div> | ||
37 | <input type="text" name="lf_tags" id="lf_tags" value="{$link.tags}" class="lf_input" | ||
38 | data-list="{loop="$tags"}{$key}, {/loop}" data-multiple autocomplete="off" > | ||
39 | </div> | ||
40 | |||
41 | <div> | ||
42 | <input type="checkbox" name="lf_private" id="lf_private" | ||
43 | {if="($link_is_new && $GLOBALS['privateLinkByDefault']==true) || $link.private == true"} | ||
44 | checked="checked" | ||
45 | {/if}> | ||
46 | <label for="lf_private">Private</label> | ||
47 | </div> | ||
48 | |||
49 | <div id="editlink-plugins"> | ||
50 | {loop="$edit_link_plugin"} | ||
51 | {$value} | ||
52 | {/loop} | ||
53 | </div> | ||
54 | |||
55 | <div> | ||
56 | <input type="submit" value="Save" name="save_edit"> | ||
57 | {if="!$link_is_new"} | ||
58 | <input type="submit" value="Delete" name="delete_link" class="delete-link"> | ||
59 | {/if} | ||
60 | </div> | ||
61 | |||
62 | <input type="hidden" name="token" value="{$token}"> | ||
63 | {if="$http_referer"} | ||
64 | <input type="hidden" name="returnurl" value="{$http_referer}"> | ||
65 | {/if} | ||
66 | </form> | ||
67 | </div> | ||
68 | {if="$source !== 'firefoxsocialapi'"} | ||
69 | {include="page.footer"} | ||
70 | {/if} | ||
71 | <script> | ||
72 | awesompleteUniqueTag('#lf_tags'); | ||
73 | if (!'{$link.title}') { | ||
74 | document.linkform.lf_title.focus(); | ||
75 | } else if (!'{$link.description}') { | ||
76 | document.linkform.lf_description.focus(); | ||
77 | } else { | ||
78 | document.linkform.lf_tags.focus(); | ||
79 | } | ||
80 | </script> | ||
81 | </body> | ||
82 | </html> | ||