From 8aac1519c43df1afdc798d1150385df36c4d09b9 Mon Sep 17 00:00:00 2001 From: Stephen Margheim Date: Tue, 24 Nov 2015 15:26:16 -0500 Subject: [PATCH 01/18] Add dropdown option to initialization to specify the element to hold the item results --- awesomplete.js | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/awesomplete.js b/awesomplete.js index fe4d0c38..d24105b4 100644 --- a/awesomplete.js +++ b/awesomplete.js @@ -22,6 +22,7 @@ var _ = function (input, o) { minChars: 2, maxItems: 10, autoFirst: false, + dropdown: null, filter: _.FILTER_CONTAINS, sort: _.SORT_BYLENGTH, item: function (text, input) { @@ -45,10 +46,17 @@ var _ = function (input, o) { around: input }); - this.ul = $.create("ul", { - hidden: "", - inside: this.container - }); + this.ul = this.dropdown ? + $.set(this.dropdown, { + hidden: '', + className: 'awesomplete-dropdown', + inside: this.container + }) : + $.create('ul', { + hidden: '', + className: 'awesomplete-dropdown', + inside: this.container + }); this.status = $.create("span", { className: "visually-hidden", @@ -301,9 +309,7 @@ function $$(expr, con) { return slice.call((con || document).querySelectorAll(expr)); } -$.create = function(tag, o) { - var element = document.createElement(tag); - +$.set(element, o) { for (var i in o) { var val = o[i]; @@ -324,6 +330,12 @@ $.create = function(tag, o) { } return element; +} + +$.create = function(tag, o) { + var element = document.createElement(tag); + + return $.set(element, o); }; $.bind = function(element, o) { From b94055951b25d05ebdf76f8f29913f8992b85115 Mon Sep 17 00:00:00 2001 From: Stephen Margheim Date: Tue, 24 Nov 2015 15:29:04 -0500 Subject: [PATCH 02/18] Add .awesomplete-dropdown class to all ul selector statements --- awesomplete.css | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/awesomplete.css b/awesomplete.css index c9d5e94c..abb153b9 100644 --- a/awesomplete.css +++ b/awesomplete.css @@ -14,7 +14,8 @@ div.awesomplete > input { display: block; } -div.awesomplete > ul { +div.awesomplete > ul, +div.awesomplete > .awesomplete-dropdown { position: absolute; left: 0; z-index: 1; @@ -32,7 +33,9 @@ div.awesomplete > ul { } div.awesomplete > ul[hidden], -div.awesomplete > ul:empty { +div.awesomplete > ul:empty, +div.awesomplete > .awesomplete-dropdown[hidden], +div.awesomplete > .awesomplete-dropdown:empty { display: none; } @@ -41,9 +44,11 @@ div.awesomplete > ul:empty { transition: .3s cubic-bezier(.4,.2,.5,1.4); transform-origin: 1.43em -.43em; } - + div.awesomplete > ul[hidden], - div.awesomplete > ul:empty { + div.awesomplete > ul:empty, + div.awesomplete > .awesomplete-dropdown[hidden], + div.awesomplete > .awesomplete-dropdown:empty { opacity: 0; transform: scale(0); display: block; @@ -52,7 +57,8 @@ div.awesomplete > ul:empty { } /* Pointer */ - div.awesomplete > ul:before { + div.awesomplete > ul:before, + div.awesomplete > .awesomplete-dropdown:before { content: ""; position: absolute; top: -.43em; @@ -67,31 +73,34 @@ div.awesomplete > ul:empty { transform: rotate(45deg); } - div.awesomplete > ul > li { + div.awesomplete > ul > li, + div.awesomplete > .awesomplete-dropdown > li { position: relative; padding: .2em .5em; cursor: pointer; } - - div.awesomplete > ul > li:hover { + + div.awesomplete > ul > li:hover, + div.awesomplete > .awesomplete-dropdown > li:hover { background: hsl(200, 40%, 80%); color: black; } - - div.awesomplete > ul > li[aria-selected="true"] { + + div.awesomplete > ul > li[aria-selected="true"], + div.awesomplete > .awesomplete-dropdown > li[aria-selected="true"] { background: hsl(205, 40%, 40%); color: white; } - + div.awesomplete mark { background: hsl(65, 100%, 50%); } - + div.awesomplete li:hover mark { background: hsl(68, 100%, 41%); } - + div.awesomplete li[aria-selected="true"] mark { background: hsl(86, 100%, 21%); color: inherit; - } \ No newline at end of file + } From 925c0d355b45c2384549802adbbcb89a9426437b Mon Sep 17 00:00:00 2001 From: Stephen Margheim Date: Tue, 24 Nov 2015 15:38:26 -0500 Subject: [PATCH 03/18] Add documentation --- index.html | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/index.html b/index.html index 84901b22..840fc3ac 100644 --- a/index.html +++ b/index.html @@ -183,6 +183,13 @@

Customize

Boolean false + + dropdown + data-dropdown + Selector pointing to a DOM element where autocomplete results will be inserted. + String + null + From eb32d0acb0dd0869f5ae893090dfe648a515363f Mon Sep 17 00:00:00 2001 From: Stephen Margheim Date: Tue, 24 Nov 2015 15:39:32 -0500 Subject: [PATCH 04/18] Fix erroneous typo --- awesomplete.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/awesomplete.js b/awesomplete.js index d24105b4..0c0037b6 100644 --- a/awesomplete.js +++ b/awesomplete.js @@ -309,7 +309,7 @@ function $$(expr, con) { return slice.call((con || document).querySelectorAll(expr)); } -$.set(element, o) { +$.set = function(element, o) { for (var i in o) { var val = o[i]; From 28d022c80b49166ad3d46c0f4dac7c557936263a Mon Sep 17 00:00:00 2001 From: Stephen Margheim Date: Tue, 29 Mar 2016 10:28:02 -0400 Subject: [PATCH 05/18] Update JS given @LeaVerou's comments --- awesomplete.js | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/awesomplete.js b/awesomplete.js index 0c0037b6..90b045f3 100644 --- a/awesomplete.js +++ b/awesomplete.js @@ -22,7 +22,12 @@ var _ = function (input, o) { minChars: 2, maxItems: 10, autoFirst: false, +<<<<<<< Updated upstream dropdown: null, +======= + ul: null, + data: _.DATA, +>>>>>>> Stashed changes filter: _.FILTER_CONTAINS, sort: _.SORT_BYLENGTH, item: function (text, input) { @@ -41,11 +46,13 @@ var _ = function (input, o) { // Create necessary elements - this.container = $.create("div", { + this.container = document.createElement("div"); + $.set(this.container, { className: "awesomplete", around: input }); +<<<<<<< Updated upstream this.ul = this.dropdown ? $.set(this.dropdown, { hidden: '', @@ -57,8 +64,17 @@ var _ = function (input, o) { className: 'awesomplete-dropdown', inside: this.container }); +======= + this.ul = $(this.ul) || document.createElement("ul"); + $.set(this.ul, { + hidden: "hidden", + className: 'awesomplete-dropdown', + inside: this.container + }) +>>>>>>> Stashed changes - this.status = $.create("span", { + this.status = document.createElement("span"); + $.set(this.status, { className: "visually-hidden", role: "status", "aria-live": "assertive", @@ -271,6 +287,23 @@ _.SORT_BYLENGTH = function (a, b) { return a < b? -1 : 1; }; +<<<<<<< Updated upstream +======= +_.ITEM = function (text, input) { + var html = input === '' ? text : text.replace(RegExp($.regExpEscape(input.trim()), "gi"), "$&"); + return $.set(document.createElement("li"), { + innerHTML: html, + "aria-selected": "false" + }); +}; + +_.REPLACE = function (text) { + this.input.value = text.value; +}; + +_.DATA = function (item/*, input*/) { return item; }; + +>>>>>>> Stashed changes // Private functions function configure(properties, o) { From 7ade63df12c37d30d120a0fa016cf7f99e21c59e Mon Sep 17 00:00:00 2001 From: Stephen Margheim Date: Tue, 29 Mar 2016 10:29:14 -0400 Subject: [PATCH 06/18] Remove git collisions --- awesomplete.js | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/awesomplete.js b/awesomplete.js index 90b045f3..78fb41a4 100644 --- a/awesomplete.js +++ b/awesomplete.js @@ -22,12 +22,8 @@ var _ = function (input, o) { minChars: 2, maxItems: 10, autoFirst: false, -<<<<<<< Updated upstream - dropdown: null, -======= ul: null, data: _.DATA, ->>>>>>> Stashed changes filter: _.FILTER_CONTAINS, sort: _.SORT_BYLENGTH, item: function (text, input) { @@ -52,26 +48,12 @@ var _ = function (input, o) { around: input }); -<<<<<<< Updated upstream - this.ul = this.dropdown ? - $.set(this.dropdown, { - hidden: '', - className: 'awesomplete-dropdown', - inside: this.container - }) : - $.create('ul', { - hidden: '', - className: 'awesomplete-dropdown', - inside: this.container - }); -======= this.ul = $(this.ul) || document.createElement("ul"); $.set(this.ul, { hidden: "hidden", className: 'awesomplete-dropdown', inside: this.container }) ->>>>>>> Stashed changes this.status = document.createElement("span"); $.set(this.status, { @@ -287,8 +269,6 @@ _.SORT_BYLENGTH = function (a, b) { return a < b? -1 : 1; }; -<<<<<<< Updated upstream -======= _.ITEM = function (text, input) { var html = input === '' ? text : text.replace(RegExp($.regExpEscape(input.trim()), "gi"), "$&"); return $.set(document.createElement("li"), { @@ -303,7 +283,6 @@ _.REPLACE = function (text) { _.DATA = function (item/*, input*/) { return item; }; ->>>>>>> Stashed changes // Private functions function configure(properties, o) { From 71c83dd0b0adbaff360acb728048c7f847dd6c93 Mon Sep 17 00:00:00 2001 From: Stephen Margheim Date: Tue, 29 Mar 2016 10:32:17 -0400 Subject: [PATCH 07/18] Add back some closing semicolons --- awesomplete.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/awesomplete.js b/awesomplete.js index 9f02d426..a14cd89f 100644 --- a/awesomplete.js +++ b/awesomplete.js @@ -45,7 +45,7 @@ var _ = function (input, o) { hidden: "hidden", className: 'awesomplete-dropdown', inside: this.container - }) + }); this.status = document.createElement("span"); $.set(this.status, { @@ -368,7 +368,7 @@ $.set = function(element, o) { } return element; -} +}; $.bind = function(element, o) { if (element) { From 484676934e5917cabfdbb620531a011024783cd0 Mon Sep 17 00:00:00 2001 From: Stephen Margheim Date: Tue, 29 Mar 2016 10:33:02 -0400 Subject: [PATCH 08/18] Update docs to use ul for option name --- index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index c07365b5..01e87569 100644 --- a/index.html +++ b/index.html @@ -207,8 +207,8 @@

Customize

false - dropdown - data-dropdown + ul + data-ul Selector pointing to a DOM element where autocomplete results will be inserted. String null From d10a0b0ef60606a07da09cae40dae5b4be5ea52b Mon Sep 17 00:00:00 2001 From: Stephen Margheim Date: Tue, 29 Mar 2016 10:36:05 -0400 Subject: [PATCH 09/18] Fix one line in CSS where new classname wasn't being used --- awesomplete.css | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/awesomplete.css b/awesomplete.css index abb153b9..03d35001 100644 --- a/awesomplete.css +++ b/awesomplete.css @@ -40,7 +40,8 @@ div.awesomplete > .awesomplete-dropdown:empty { } @supports (transform: scale(0)) { - div.awesomplete > ul { + div.awesomplete > ul, + div.awesomplete > .awesomplete-dropdown { transition: .3s cubic-bezier(.4,.2,.5,1.4); transform-origin: 1.43em -.43em; } From 4b07b6566b854d0778b9e01ef95f79002fa5c748 Mon Sep 17 00:00:00 2001 From: Stephen Margheim Date: Tue, 29 Mar 2016 10:43:33 -0400 Subject: [PATCH 10/18] Update createSpec tests to be setSpec tests, now testing the $.set method --- test/helpers/{createSpec.js => setSpec.js} | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) rename test/helpers/{createSpec.js => setSpec.js} (85%) diff --git a/test/helpers/createSpec.js b/test/helpers/setSpec.js similarity index 85% rename from test/helpers/createSpec.js rename to test/helpers/setSpec.js index a9ef31e1..f64476ef 100644 --- a/test/helpers/createSpec.js +++ b/test/helpers/setSpec.js @@ -1,29 +1,29 @@ -describe("Awesomplete.$.create", function () { +describe("Awesomplete.$.set", function () { $.fixture("options"); - subject(function () { return Awesomplete.$.create(this.tag, this.options || {}) }); + subject(function () { return Awesomplete.$.set(this.tag, this.options || {}) }); - def("tag", "div"); + def("tag", document.createElement("div")); - it("creates DOM element", function () { + it("sets DOM element", function () { expect(this.subject instanceof HTMLElement).toBe(true); }); describe("with various tag names", function () { - it("creates
    element", function () { - this.tag = "ul"; + it("sets
      element", function () { + this.tag = document.createElement("ul"); expect(this.subject.tagName).toEqual("UL"); }); - it("creates
    • element", function () { - this.tag = "li"; + it("sets
    • element", function () { + this.tag = document.createElement("li"); expect(this.subject.tagName).toEqual("LI"); }); }); describe("without options", function () { - it("creates element without any attributes", function () { + it("sets element without any attributes", function () { expect(this.subject.attributes.length).toEqual(0); }); }); From 38703ba1fdac1607e22dd0244d00c6233800ba29 Mon Sep 17 00:00:00 2001 From: Stephen Margheim Date: Tue, 29 Mar 2016 11:24:35 -0400 Subject: [PATCH 11/18] Make container optionally set --- awesomplete.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/awesomplete.js b/awesomplete.js index a14cd89f..c1e21cd4 100644 --- a/awesomplete.js +++ b/awesomplete.js @@ -22,6 +22,7 @@ var _ = function (input, o) { minChars: 2, maxItems: 10, autoFirst: false, + container: null, ul: null, data: _.DATA, filter: _.FILTER_CONTAINS, @@ -34,7 +35,7 @@ var _ = function (input, o) { // Create necessary elements - this.container = document.createElement("div"); + this.container = $(this.container) || document.createElement("div"); $.set(this.container, { className: "awesomplete", around: input From 150519458d455252d1a57dc29a41e96f760be346 Mon Sep 17 00:00:00 2001 From: Stephen Margheim Date: Tue, 29 Mar 2016 11:24:55 -0400 Subject: [PATCH 12/18] Use internal reference to input --- awesomplete.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/awesomplete.js b/awesomplete.js index c1e21cd4..843507d3 100644 --- a/awesomplete.js +++ b/awesomplete.js @@ -38,7 +38,7 @@ var _ = function (input, o) { this.container = $(this.container) || document.createElement("div"); $.set(this.container, { className: "awesomplete", - around: input + around: this.input }); this.ul = $(this.ul) || document.createElement("ul"); From 005aa78081da5fdce910d66cd998dadc79deac86 Mon Sep 17 00:00:00 2001 From: Stephen Margheim Date: Tue, 29 Mar 2016 11:25:35 -0400 Subject: [PATCH 13/18] When wrapping element "around" another, check if element already the parentNode Avoids DOM Error 3 --- awesomplete.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/awesomplete.js b/awesomplete.js index 843507d3..8aa43cec 100644 --- a/awesomplete.js +++ b/awesomplete.js @@ -357,7 +357,9 @@ $.set = function(element, o) { } else if (i === "around") { var ref = $(val); - ref.parentNode.insertBefore(element, ref); + if (ref.parentNode && ref.parentNode !== element) { + ref.parentNode.insertBefore(element, ref); + } element.appendChild(ref); } else if (i in element) { From 4d2b9f2a60099d03abc2769969a8d7729a9861a7 Mon Sep 17 00:00:00 2001 From: Stephen Margheim Date: Tue, 29 Mar 2016 11:34:06 -0400 Subject: [PATCH 14/18] Handle className more intelligently when setting attributes --- awesomplete.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/awesomplete.js b/awesomplete.js index 8aa43cec..35f5cced 100644 --- a/awesomplete.js +++ b/awesomplete.js @@ -362,6 +362,9 @@ $.set = function(element, o) { } element.appendChild(ref); } + else if (i === "className") { + element.classList.add(val); + } else if (i in element) { element[i] = val; } From 479bb1461e18a45ec5c07a6e1b4167098ac503fa Mon Sep 17 00:00:00 2001 From: Stephen Margheim Date: Tue, 29 Mar 2016 11:40:20 -0400 Subject: [PATCH 15/18] Update CSS to handle non-divs with new container className --- awesomplete.css | 51 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/awesomplete.css b/awesomplete.css index 03d35001..d2aae4bf 100644 --- a/awesomplete.css +++ b/awesomplete.css @@ -5,17 +5,21 @@ clip: rect(0, 0, 0, 0); } -div.awesomplete { +div.awesomplete, +.awesomplete-container { display: inline-block; position: relative; } -div.awesomplete > input { +div.awesomplete > input, +.awesomplete-container > input { display: block; } div.awesomplete > ul, -div.awesomplete > .awesomplete-dropdown { +div.awesomplete > .awesomplete-dropdown, +.awesomplete-container > ul, +.awesomplete-container > .awesomplete-dropdown { position: absolute; left: 0; z-index: 1; @@ -35,13 +39,19 @@ div.awesomplete > .awesomplete-dropdown { div.awesomplete > ul[hidden], div.awesomplete > ul:empty, div.awesomplete > .awesomplete-dropdown[hidden], -div.awesomplete > .awesomplete-dropdown:empty { +div.awesomplete > .awesomplete-dropdown:empty, +.awesomplete-container > ul[hidden], +.awesomplete-container > ul:empty, +.awesomplete-container > .awesomplete-dropdown[hidden], +.awesomplete-container > .awesomplete-dropdown:empty { display: none; } @supports (transform: scale(0)) { div.awesomplete > ul, - div.awesomplete > .awesomplete-dropdown { + div.awesomplete > .awesomplete-dropdown, + .awesomplete-container > ul, + .awesomplete-container > .awesomplete-dropdown { transition: .3s cubic-bezier(.4,.2,.5,1.4); transform-origin: 1.43em -.43em; } @@ -49,7 +59,11 @@ div.awesomplete > .awesomplete-dropdown:empty { div.awesomplete > ul[hidden], div.awesomplete > ul:empty, div.awesomplete > .awesomplete-dropdown[hidden], - div.awesomplete > .awesomplete-dropdown:empty { + div.awesomplete > .awesomplete-dropdown:empty, + .awesomplete-container > ul[hidden], + .awesomplete-container > ul:empty, + .awesomplete-container > .awesomplete-dropdown[hidden], + .awesomplete-container > .awesomplete-dropdown:empty { opacity: 0; transform: scale(0); display: block; @@ -59,7 +73,9 @@ div.awesomplete > .awesomplete-dropdown:empty { /* Pointer */ div.awesomplete > ul:before, - div.awesomplete > .awesomplete-dropdown:before { + div.awesomplete > .awesomplete-dropdown:before, + .awesomplete-container > ul:before, + .awesomplete-container > .awesomplete-dropdown:before { content: ""; position: absolute; top: -.43em; @@ -75,33 +91,42 @@ div.awesomplete > .awesomplete-dropdown:empty { } div.awesomplete > ul > li, - div.awesomplete > .awesomplete-dropdown > li { + div.awesomplete > .awesomplete-dropdown > li, + .awesomplete-container > ul > li, + .awesomplete-container > .awesomplete-dropdown > li { position: relative; padding: .2em .5em; cursor: pointer; } div.awesomplete > ul > li:hover, - div.awesomplete > .awesomplete-dropdown > li:hover { + div.awesomplete > .awesomplete-dropdown > li:hover, + .awesomplete-container > ul > li:hover, + .awesomplete-container > .awesomplete-dropdown > li:hover { background: hsl(200, 40%, 80%); color: black; } div.awesomplete > ul > li[aria-selected="true"], - div.awesomplete > .awesomplete-dropdown > li[aria-selected="true"] { + div.awesomplete > .awesomplete-dropdown > li[aria-selected="true"], + .awesomplete-container > ul > li[aria-selected="true"], + .awesomplete-container > .awesomplete-dropdown > li[aria-selected="true"] { background: hsl(205, 40%, 40%); color: white; } - div.awesomplete mark { + div.awesomplete mark, + .awesomplete-container mark { background: hsl(65, 100%, 50%); } - div.awesomplete li:hover mark { + div.awesomplete li:hover mark, + .awesomplete-container li:hover mark { background: hsl(68, 100%, 41%); } - div.awesomplete li[aria-selected="true"] mark { + div.awesomplete li[aria-selected="true"] mark, + .awesomplete-container li[aria-selected="true"] mark { background: hsl(86, 100%, 21%); color: inherit; } From 73ea9e02f5e068302ed807e008d5b8a6f91b0d0c Mon Sep 17 00:00:00 2001 From: Stephen Margheim Date: Tue, 29 Mar 2016 11:40:37 -0400 Subject: [PATCH 16/18] Add documentation on new container option --- index.html | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/index.html b/index.html index 01e87569..d8637f97 100644 --- a/index.html +++ b/index.html @@ -206,6 +206,13 @@

      Customize

      Boolean false + + container + data-container + Selector pointing to the DOM element wrapping the input. + String + null + ul data-ul From 97d38503d494c1d3ef88407ae9ffb184ba3a98ba Mon Sep 17 00:00:00 2001 From: Stephen Margheim Date: Tue, 29 Mar 2016 11:40:55 -0400 Subject: [PATCH 17/18] Change default className of container --- awesomplete.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/awesomplete.js b/awesomplete.js index 35f5cced..e5a82a72 100644 --- a/awesomplete.js +++ b/awesomplete.js @@ -37,7 +37,7 @@ var _ = function (input, o) { this.container = $(this.container) || document.createElement("div"); $.set(this.container, { - className: "awesomplete", + className: "awesomplete-container", around: this.input }); From e44679f2f25369cb527d79a12a23ccf110acb547 Mon Sep 17 00:00:00 2001 From: Stephen Margheim Date: Tue, 29 Mar 2016 11:42:23 -0400 Subject: [PATCH 18/18] Update container className check to use new className --- test/init/htmlSpec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/init/htmlSpec.js b/test/init/htmlSpec.js index 25350c64..da8d99a6 100644 --- a/test/init/htmlSpec.js +++ b/test/init/htmlSpec.js @@ -16,7 +16,7 @@ describe("Html modifications", function () { describe("HTML tweaks", function () { it("creates container", function () { expect(this.subject.container instanceof HTMLElement).toBe(true); - expect(this.subject.container.className).toBe("awesomplete"); + expect(this.subject.container.className).toBe("awesomplete-container"); }); it("places input inside container", function () {