]> git.immae.eu Git - github/shaarli/Shaarli.git/commitdiff
Edit link WIP + upgrade awesomplete
authorArthurHoaro <arthur@hoa.ro>
Tue, 7 Jun 2016 14:12:12 +0000 (16:12 +0200)
committerArthurHoaro <arthur@hoa.ro>
Sun, 7 Aug 2016 10:17:36 +0000 (12:17 +0200)
inc/awesomplete-multiple-tags.js
inc/awesomplete.js
inc/awesomplete.min.js
plugins/markdown/markdown.css
tpl/default/editlink.html [new file with mode: 0644]

index 4cc8429f474d9781bac6938157b956148b8dfa2f..faecb417858e3dd05487d5f3e7000f4d602a7bda 100644 (file)
@@ -1,13 +1,16 @@
 var awp = Awesomplete.$;
-awesomplete = new Awesomplete(awp('input[data-multiple]'), {
-    filter: function(text, input) {
-        return Awesomplete.FILTER_CONTAINS(text, input.match(/[^ ]*$/)[0]);
-    },
-    replace: function(text) {
-        var before = this.input.value.match(/^.+ \s*|/)[0];
-        this.input.value = before + text + " ";
-    },
-    minChars: 1
+var autocompleteFields = document.querySelectorAll('input[data-multiple]');
+[].forEach.call(autocompleteFields, function(autocompleteField) {
+    awesomplete = new Awesomplete(awp(autocompleteField), {
+        filter: function (text, input) {
+            return Awesomplete.FILTER_CONTAINS(text, input.match(/[^ ]*$/)[0]);
+        },
+        replace: function (text) {
+            var before = this.input.value.match(/^.+ \s*|/)[0];
+            this.input.value = before + text + " ";
+        },
+        minChars: 1
+    })
 });
 
 /**
index fae550e250f3e5c00a04bc0b28e50827ed4bce05..7303652a7fb26192222eaeae7d50f9206aae572d 100644 (file)
 
 (function () {
 
-    var _ = function (input, o) {
-        var me = this;
-
-        // Setup
-
-        this.input = $(input);
-        this.input.setAttribute("aria-autocomplete", "list");
-
-        o = o || {};
-
-        configure.call(this, {
-            minChars: 2,
-            maxItems: 10,
-            autoFirst: false,
-            filter: _.FILTER_CONTAINS,
-            sort: _.SORT_BYLENGTH,
-            item: function (text, input) {
-                return $.create("li", {
-                    innerHTML: text.replace(RegExp($.regExpEscape(input.trim()), "gi"), "<mark>$&</mark>"),
-                    "aria-selected": "false"
-                });
-            },
-            replace: function (text) {
-                this.input.value = text;
-            }
-        }, o);
-
-        this.index = -1;
-
-        // Create necessary elements
-
-        this.container = $.create("div", {
-            className: "awesomplete",
-            around: input
-        });
-
-        this.ul = $.create("ul", {
-            hidden: "",
-            inside: this.container
-        });
-
-        this.status = $.create("span", {
-            className: "visually-hidden",
-            role: "status",
-            "aria-live": "assertive",
-            "aria-relevant": "additions",
-            inside: this.container
-        });
-
-        // Bind events
-
-        $.bind(this.input, {
-            "input": this.evaluate.bind(this),
-            "blur": this.close.bind(this),
-            "keydown": function(evt) {
-                var c = evt.keyCode;
-
-                // If the dropdown `ul` is in view, then act on keydown for the following keys:
-                // Enter / Esc / Up / Down
-                if(me.opened) {
-                    if (c === 13 && me.selected) { // Enter
-                        evt.preventDefault();
-                        me.select();
-                    }
-                    else if (c === 27) { // Esc
-                        me.close();
-                    }
-                    else if (c === 38 || c === 40) { // Down/Up arrow
-                        evt.preventDefault();
-                        me[c === 38? "previous" : "next"]();
-                    }
-                }
-            }
-        });
-
-        $.bind(this.input.form, {"submit": this.close.bind(this)});
-
-        $.bind(this.ul, {"mousedown": function(evt) {
-            var li = evt.target;
-
-            if (li !== this) {
-
-                while (li && !/li/i.test(li.nodeName)) {
-                    li = li.parentNode;
-                }
-
-                if (li) {
-                    me.select(li);
-                }
-            }
-        }});
-
-        if (this.input.hasAttribute("list")) {
-            this.list = "#" + input.getAttribute("list");
-            input.removeAttribute("list");
-        }
-        else {
-            this.list = this.input.getAttribute("data-list") || o.list || [];
-        }
-
-        _.all.push(this);
-    };
-
-    _.prototype = {
-        set list(list) {
-            if (Array.isArray(list)) {
-                this._list = list;
-            }
-            else if (typeof list === "string" && list.indexOf(",") > -1) {
-                this._list = list.split(/\s*,\s*/);
-            }
-            else { // Element or CSS selector
-                list = $(list);
-
-                if (list && list.children) {
-                    this._list = slice.apply(list.children).map(function (el) {
-                        return el.innerHTML.trim();
-                    });
-                }
-            }
-
-            if (document.activeElement === this.input) {
-                this.evaluate();
-            }
-        },
-
-        get selected() {
-            return this.index > -1;
-        },
-
-        get opened() {
-            return this.ul && this.ul.getAttribute("hidden") == null;
-        },
-
-        close: function () {
-            this.ul.setAttribute("hidden", "");
-            this.index = -1;
-
-            $.fire(this.input, "awesomplete-close");
-        },
-
-        open: function () {
-            this.ul.removeAttribute("hidden");
-
-            if (this.autoFirst && this.index === -1) {
-                this.goto(0);
-            }
-
-            $.fire(this.input, "awesomplete-open");
-        },
-
-        next: function () {
-            var count = this.ul.children.length;
-
-            this.goto(this.index < count - 1? this.index + 1 : -1);
-        },
-
-        previous: function () {
-            var count = this.ul.children.length;
-
-            this.goto(this.selected? this.index - 1 : count - 1);
-        },
-
-        // Should not be used, highlights specific item without any checks!
-        goto: function (i) {
-            var lis = this.ul.children;
-
-            if (this.selected) {
-                lis[this.index].setAttribute("aria-selected", "false");
-            }
-
-            this.index = i;
-
-            if (i > -1 && lis.length > 0) {
-                lis[i].setAttribute("aria-selected", "true");
-                this.status.textContent = lis[i].textContent;
-            }
-
-            $.fire(this.input, "awesomplete-highlight");
-        },
-
-        select: function (selected) {
-            selected = selected || this.ul.children[this.index];
-
-            if (selected) {
-                var prevented;
-
-                $.fire(this.input, "awesomplete-select", {
-                    text: selected.textContent,
-                    preventDefault: function () {
-                        prevented = true;
-                    }
-                });
-
-                if (!prevented) {
-                    this.replace(selected.textContent);
-                    this.close();
-                    $.fire(this.input, "awesomplete-selectcomplete");
-                }
-            }
-        },
-
-        evaluate: function() {
-            var me = this;
-            var value = this.input.value;
-
-            if (value.length >= this.minChars && this._list.length > 0) {
-                this.index = -1;
-                // Populate list with options that match
-                this.ul.innerHTML = "";
-
-                this._list
-                    .filter(function(item) {
-                        return me.filter(item, value);
-                    })
-                    .sort(this.sort)
-                    .every(function(text, i) {
-                        me.ul.appendChild(me.item(text, value));
-
-                        return i < me.maxItems - 1;
-                    });
-
-                if (this.ul.children.length === 0) {
-                    this.close();
-                } else {
-                    this.open();
-                }
-            }
-            else {
-                this.close();
-            }
-        }
-    };
+var _ = function (input, o) {
+       var me = this;
+
+       // Setup
+
+       this.input = $(input);
+       this.input.setAttribute("autocomplete", "off");
+       this.input.setAttribute("aria-autocomplete", "list");
+
+       o = o || {};
+
+       configure(this, {
+               minChars: 2,
+               maxItems: 10,
+               autoFirst: false,
+               data: _.DATA,
+               filter: _.FILTER_CONTAINS,
+               sort: _.SORT_BYLENGTH,
+               item: _.ITEM,
+               replace: _.REPLACE
+       }, o);
+
+       this.index = -1;
+
+       // Create necessary elements
+
+       this.container = $.create("div", {
+               className: "awesomplete",
+               around: input
+       });
+
+       this.ul = $.create("ul", {
+               hidden: "hidden",
+               inside: this.container
+       });
+
+       this.status = $.create("span", {
+               className: "visually-hidden",
+               role: "status",
+               "aria-live": "assertive",
+               "aria-relevant": "additions",
+               inside: this.container
+       });
+
+       // Bind events
+
+       $.bind(this.input, {
+               "input": this.evaluate.bind(this),
+               "blur": this.close.bind(this),
+               "keydown": function(evt) {
+                       var c = evt.keyCode;
+
+                       // If the dropdown `ul` is in view, then act on keydown for the following keys:
+                       // Enter / Esc / Up / Down
+                       if(me.opened) {
+                               if (c === 13 && me.selected) { // Enter
+                                       evt.preventDefault();
+                                       me.select();
+                               }
+                               else if (c === 27) { // Esc
+                                       me.close();
+                               }
+                               else if (c === 38 || c === 40) { // Down/Up arrow
+                                       evt.preventDefault();
+                                       me[c === 38? "previous" : "next"]();
+                               }
+                       }
+               }
+       });
+
+       $.bind(this.input.form, {"submit": this.close.bind(this)});
+
+       $.bind(this.ul, {"mousedown": function(evt) {
+               var li = evt.target;
+
+               if (li !== this) {
+
+                       while (li && !/li/i.test(li.nodeName)) {
+                               li = li.parentNode;
+                       }
+
+                       if (li && evt.button === 0) {  // Only select on left click
+                               evt.preventDefault();
+                               me.select(li, evt.target);
+                       }
+               }
+       }});
+
+       if (this.input.hasAttribute("list")) {
+               this.list = "#" + this.input.getAttribute("list");
+               this.input.removeAttribute("list");
+       }
+       else {
+               this.list = this.input.getAttribute("data-list") || o.list || [];
+       }
+
+       _.all.push(this);
+};
+
+_.prototype = {
+       set list(list) {
+               if (Array.isArray(list)) {
+                       this._list = list;
+               }
+               else if (typeof list === "string" && list.indexOf(",") > -1) {
+                               this._list = list.split(/\s*,\s*/);
+               }
+               else { // Element or CSS selector
+                       list = $(list);
+
+                       if (list && list.children) {
+                               var items = [];
+                               slice.apply(list.children).forEach(function (el) {
+                                       if (!el.disabled) {
+                                               var text = el.textContent.trim();
+                                               var value = el.value || text;
+                                               var label = el.label || text;
+                                               if (value !== "") {
+                                                       items.push({ label: label, value: value });
+                                               }
+                                       }
+                               });
+                               this._list = items;
+                       }
+               }
+
+               if (document.activeElement === this.input) {
+                       this.evaluate();
+               }
+       },
+
+       get selected() {
+               return this.index > -1;
+       },
+
+       get opened() {
+               return !this.ul.hasAttribute("hidden");
+       },
+
+       close: function () {
+               this.ul.setAttribute("hidden", "");
+               this.index = -1;
+
+               $.fire(this.input, "awesomplete-close");
+       },
+
+       open: function () {
+               this.ul.removeAttribute("hidden");
+
+               if (this.autoFirst && this.index === -1) {
+                       this.goto(0);
+               }
+
+               $.fire(this.input, "awesomplete-open");
+       },
+
+       next: function () {
+               var count = this.ul.children.length;
+
+               this.goto(this.index < count - 1? this.index + 1 : -1);
+       },
+
+       previous: function () {
+               var count = this.ul.children.length;
+
+               this.goto(this.selected? this.index - 1 : count - 1);
+       },
+
+       // Should not be used, highlights specific item without any checks!
+       goto: function (i) {
+               var lis = this.ul.children;
+
+               if (this.selected) {
+                       lis[this.index].setAttribute("aria-selected", "false");
+               }
+
+               this.index = i;
+
+               if (i > -1 && lis.length > 0) {
+                       lis[i].setAttribute("aria-selected", "true");
+                       this.status.textContent = lis[i].textContent;
+
+                       $.fire(this.input, "awesomplete-highlight", {
+                               text: this.suggestions[this.index]
+                       });
+               }
+       },
+
+       select: function (selected, origin) {
+               if (selected) {
+                       this.index = $.siblingIndex(selected);
+               } else {
+                       selected = this.ul.children[this.index];
+               }
+
+               if (selected) {
+                       var suggestion = this.suggestions[this.index];
+
+                       var allowed = $.fire(this.input, "awesomplete-select", {
+                               text: suggestion,
+                               origin: origin || selected
+                       });
+
+                       if (allowed) {
+                               this.replace(suggestion);
+                               this.close();
+                               $.fire(this.input, "awesomplete-selectcomplete", {
+                                       text: suggestion
+                               });
+                       }
+               }
+       },
+
+       evaluate: function() {
+               var me = this;
+               var value = this.input.value;
+
+               if (value.length >= this.minChars && this._list.length > 0) {
+                       this.index = -1;
+                       // Populate list with options that match
+                       this.ul.innerHTML = "";
+
+                       this.suggestions = this._list
+                               .map(function(item) {
+                                       return new Suggestion(me.data(item, value));
+                               })
+                               .filter(function(item) {
+                                       return me.filter(item, value);
+                               })
+                               .sort(this.sort)
+                               .slice(0, this.maxItems);
+
+                       this.suggestions.forEach(function(text) {
+                                       me.ul.appendChild(me.item(text, value));
+                               });
+
+                       if (this.ul.children.length === 0) {
+                               this.close();
+                       } else {
+                               this.open();
+                       }
+               }
+               else {
+                       this.close();
+               }
+       }
+};
 
 // Static methods/properties
 
-    _.all = [];
+_.all = [];
 
-    _.FILTER_CONTAINS = function (text, input) {
-        return RegExp($.regExpEscape(input.trim()), "i").test(text);
-    };
+_.FILTER_CONTAINS = function (text, input) {
+       return RegExp($.regExpEscape(input.trim()), "i").test(text);
+};
 
-    _.FILTER_STARTSWITH = function (text, input) {
-        return RegExp("^" + $.regExpEscape(input.trim()), "i").test(text);
-    };
+_.FILTER_STARTSWITH = function (text, input) {
+       return RegExp("^" + $.regExpEscape(input.trim()), "i").test(text);
+};
 
-    _.SORT_BYLENGTH = function (a, b) {
-        if (a.length !== b.length) {
-            return a.length - b.length;
-        }
+_.SORT_BYLENGTH = function (a, b) {
+       if (a.length !== b.length) {
+               return a.length - b.length;
+       }
 
-        return a < b? -1 : 1;
-    };
+       return a < b? -1 : 1;
+};
+
+_.ITEM = function (text, input) {
+       var html = input === '' ? text : text.replace(RegExp($.regExpEscape(input.trim()), "gi"), "<mark>$&</mark>");
+       return $.create("li", {
+               innerHTML: html,
+               "aria-selected": "false"
+       });
+};
+
+_.REPLACE = function (text) {
+       this.input.value = text.value;
+};
+
+_.DATA = function (item/*, input*/) { return item; };
 
 // Private functions
 
-    function configure(properties, o) {
-        for (var i in properties) {
-            var initial = properties[i],
-                attrValue = this.input.getAttribute("data-" + i.toLowerCase());
-
-            if (typeof initial === "number") {
-                this[i] = +attrValue;
-            }
-            else if (initial === false) { // Boolean options must be false by default anyway
-                this[i] = attrValue !== null;
-            }
-            else if (initial instanceof Function) {
-                this[i] = null;
-            }
-            else {
-                this[i] = attrValue;
-            }
-
-            this[i] = this[i] || o[i] || initial;
-        }
-    }
+function Suggestion(data) {
+       var o = Array.isArray(data)
+         ? { label: data[0], value: data[1] }
+         : typeof data === "object" && "label" in data && "value" in data ? data : { label: data, value: data };
+
+       this.label = o.label || o.value;
+       this.value = o.value;
+}
+Object.defineProperty(Suggestion.prototype = Object.create(String.prototype), "length", {
+       get: function() { return this.label.length; }
+});
+Suggestion.prototype.toString = Suggestion.prototype.valueOf = function () {
+       return "" + this.label;
+};
+
+function configure(instance, properties, o) {
+       for (var i in properties) {
+               var initial = properties[i],
+                   attrValue = instance.input.getAttribute("data-" + i.toLowerCase());
+
+               if (typeof initial === "number") {
+                       instance[i] = parseInt(attrValue);
+               }
+               else if (initial === false) { // Boolean options must be false by default anyway
+                       instance[i] = attrValue !== null;
+               }
+               else if (initial instanceof Function) {
+                       instance[i] = null;
+               }
+               else {
+                       instance[i] = attrValue;
+               }
+
+               if (!instance[i] && instance[i] !== 0) {
+                       instance[i] = (i in o)? o[i] : initial;
+               }
+       }
+}
 
 // Helpers
 
-    var slice = Array.prototype.slice;
-
-    function $(expr, con) {
-        return typeof expr === "string"? (con || document).querySelector(expr) : expr || null;
-    }
-
-    function $$(expr, con) {
-        return slice.call((con || document).querySelectorAll(expr));
-    }
-
-    $.create = function(tag, o) {
-        var element = document.createElement(tag);
-
-        for (var i in o) {
-            var val = o[i];
-
-            if (i === "inside") {
-                $(val).appendChild(element);
-            }
-            else if (i === "around") {
-                var ref = $(val);
-                ref.parentNode.insertBefore(element, ref);
-                element.appendChild(ref);
-            }
-            else if (i in element) {
-                element[i] = val;
-            }
-            else {
-                element.setAttribute(i, val);
-            }
-        }
-
-        return element;
-    };
-
-    $.bind = function(element, o) {
-        if (element) {
-            for (var event in o) {
-                var callback = o[event];
-
-                event.split(/\s+/).forEach(function (event) {
-                    element.addEventListener(event, callback);
-                });
-            }
-        }
-    };
-
-    $.fire = function(target, type, properties) {
-        var evt = document.createEvent("HTMLEvents");
-
-        evt.initEvent(type, true, true );
-
-        for (var j in properties) {
-            evt[j] = properties[j];
-        }
-
-        target.dispatchEvent(evt);
-    };
-
-    $.regExpEscape = function (s) {
-        return s.replace(/[-\\^$*+?.()|[\]{}]/g, "\\$&");
-    }
+var slice = Array.prototype.slice;
+
+function $(expr, con) {
+       return typeof expr === "string"? (con || document).querySelector(expr) : expr || null;
+}
+
+function $$(expr, con) {
+       return slice.call((con || document).querySelectorAll(expr));
+}
+
+$.create = function(tag, o) {
+       var element = document.createElement(tag);
+
+       for (var i in o) {
+               var val = o[i];
+
+               if (i === "inside") {
+                       $(val).appendChild(element);
+               }
+               else if (i === "around") {
+                       var ref = $(val);
+                       ref.parentNode.insertBefore(element, ref);
+                       element.appendChild(ref);
+               }
+               else if (i in element) {
+                       element[i] = val;
+               }
+               else {
+                       element.setAttribute(i, val);
+               }
+       }
+
+       return element;
+};
+
+$.bind = function(element, o) {
+       if (element) {
+               for (var event in o) {
+                       var callback = o[event];
+
+                       event.split(/\s+/).forEach(function (event) {
+                               element.addEventListener(event, callback);
+                       });
+               }
+       }
+};
+
+$.fire = function(target, type, properties) {
+       var evt = document.createEvent("HTMLEvents");
+
+       evt.initEvent(type, true, true );
+
+       for (var j in properties) {
+               evt[j] = properties[j];
+       }
+
+       return target.dispatchEvent(evt);
+};
+
+$.regExpEscape = function (s) {
+       return s.replace(/[-\\^$*+?.()|[\]{}]/g, "\\$&");
+};
+
+$.siblingIndex = function (el) {
+       /* eslint-disable no-cond-assign */
+       for (var i = 0; el = el.previousElementSibling; i++);
+       return i;
+};
 
 // Initialization
 
-    function init() {
-        $$("input.awesomplete").forEach(function (input) {
-            new Awesomplete(input);
-        });
-    }
+function init() {
+       $$("input.awesomplete").forEach(function (input) {
+               new _(input);
+       });
+}
 
 // Are we in a browser? Check for Document constructor
-    if (typeof Document !== 'undefined') {
-        // DOM already loaded?
-        if (document.readyState !== "loading") {
-            init();
-        }
-        else {
-            // Wait for it
-            document.addEventListener("DOMContentLoaded", init);
-        }
-    }
-
-    _.$ = $;
-    _.$$ = $$;
+if (typeof Document !== "undefined") {
+       // DOM already loaded?
+       if (document.readyState !== "loading") {
+               init();
+       }
+       else {
+               // Wait for it
+               document.addEventListener("DOMContentLoaded", init);
+       }
+}
+
+_.$ = $;
+_.$$ = $$;
 
 // Make sure to export Awesomplete on self when in a browser
-    if (typeof self !== 'undefined') {
-        self.Awesomplete = _;
-    }
+if (typeof self !== "undefined") {
+       self.Awesomplete = _;
+}
 
 // Expose Awesomplete as a CJS module
-    if (typeof exports === 'object') {
-        module.exports = _;
-    }
+if (typeof module === "object" && module.exports) {
+       module.exports = _;
+}
 
-    return _;
+return _;
 
 }());
index 3bfb05e8558710e29fa6d79f4204f21819be7387..bd750c837f5e88f1252abcac3a29928bfd3c6d3e 100644 (file)
@@ -1,10 +1,12 @@
 // Awesomplete - Lea Verou - MIT license
-(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",
-    "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",
-    "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=
-    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<
-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=
-    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;
-    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,
-                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           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,
-    !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})();
+(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||
+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",
+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)});
+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*/);
+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&&
+-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",
+{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,
+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=
+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),
+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,"\\$&")};
+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
index 8f2c00512a7f90abe366418377e9609c9d6d965b..33702564741b861846e7a8c84c3570e50d2e5592 100644 (file)
     box-shadow: 0 -1px 0 #e5e5e5,0 0 1px rgba(0,0,0,0.12),0 1px 1px rgba(0,0,0,0.24);
 }
 
-.md_help {
-    color: white;
-}
-
 /*
  Remove header links style
  */
diff --git a/tpl/default/editlink.html b/tpl/default/editlink.html
new file mode 100644 (file)
index 0000000..f831655
--- /dev/null
@@ -0,0 +1,82 @@
+<!DOCTYPE html>
+<html>
+<head>
+  {include="includes"}
+</head>
+<body>
+  {if="$source !== 'firefoxsocialapi'"}
+    {include="page.header"}
+  {/if}
+  <div id="editlinkform" class="pure-g">
+    <div class="pure-u-lg-1-5 pure-u-1-8"></div>
+    <form method="post" name="linkform" class="page-form pure-u-lg-3-5 pure-u-3-4" >
+      <h2>Shaare</h2>
+      <input type="hidden" name="lf_linkdate" value="{$link.linkdate}">
+      <div>
+        <label for="lf_url">URL</label>
+      </div>
+      <div>
+        <input type="text" name="lf_url" id="lf_url" value="{$link.url}" class="lf_input">
+      </div>
+      <div>
+      <label for="lf_title">Title</label>
+      </div>
+      <div>
+        <input type="text" name="lf_title" id="lf_title" value="{$link.title}" class="lf_input">
+      </div>
+      <div>
+        <label for="lf_description">Description</label>
+      </div>
+      <div>
+        <textarea name="lf_description" id="lf_description">{$link.description}</textarea>
+      </div>
+      <div>
+        <label for="lf_tags">Tags</label>
+      </div>
+      <div>
+        <input type="text" name="lf_tags" id="lf_tags" value="{$link.tags}" class="lf_input"
+          data-list="{loop="$tags"}{$key}, {/loop}" data-multiple autocomplete="off" >
+      </div>
+
+      <div>
+        <input type="checkbox"  name="lf_private" id="lf_private"
+        {if="($link_is_new && $GLOBALS['privateLinkByDefault']==true) || $link.private == true"}
+          checked="checked"
+        {/if}>
+        &nbsp;<label for="lf_private">Private</label>
+      </div>
+
+      <div id="editlink-plugins">
+        {loop="$edit_link_plugin"}
+          {$value}
+        {/loop}
+      </div>
+
+      <div>
+        <input type="submit" value="Save" name="save_edit">
+        {if="!$link_is_new"}
+          <input type="submit" value="Delete" name="delete_link" class="delete-link">
+        {/if}
+      </div>
+
+      <input type="hidden" name="token" value="{$token}">
+      {if="$http_referer"}
+        <input type="hidden" name="returnurl" value="{$http_referer}">
+      {/if}
+    </form>
+  </div>
+  {if="$source !== 'firefoxsocialapi'"}
+    {include="page.footer"}
+  {/if}
+<script>
+  awesompleteUniqueTag('#lf_tags');
+  if (!'{$link.title}') {
+    document.linkform.lf_title.focus();
+  } else if (!'{$link.description}') {
+    document.linkform.lf_description.focus();
+  } else {
+    document.linkform.lf_tags.focus();
+  }
+</script>
+</body>
+</html>