diff --git a/css/button.css b/css/button.css
index 974e3223..b75191d0 100644
--- a/css/button.css
+++ b/css/button.css
@@ -40,7 +40,7 @@ input[type="reset"]:focus,
input[type="submit"]:hover,
input[type="submit"]:focus {
background-color: var(--gray-03);
- border-bottom-color: rgb(var(--accent));
+ border-bottom-color: var(--gray-08);
color: var(--white);
outline: 0;
}
@@ -51,6 +51,7 @@ input[type="button"]:active,
input[type="reset"]:active,
input[type="submit"]:active {
background-color: var(--gray-04);
+ border-bottom-color: rgb(var(--accent));
color: var(--white);
transition: none;
}
diff --git a/css/form.css b/css/form.css
index 9c934808..ba0fbcc8 100644
--- a/css/form.css
+++ b/css/form.css
@@ -72,7 +72,7 @@ input[type="search"]:hover,
input[type="tel"]:hover,
input[type="text"]:hover {
background-color: var(--gray-16);
- border-color: rgb(var(--accent));
+ border-color: var(--gray-10);
color: var(--black);
outline: 0;
}
@@ -300,17 +300,32 @@ input[type="checkbox"]:focus+.input-label-button,
input[type="radio"]:hover+.input-label-button,
input[type="radio"]:focus+.input-label-button {
background-color: var(--gray-03);
- border-bottom-color: rgb(var(--accent));
+ border-bottom-color: var(--gray-10);
color: var(--white);
outline: 0;
}
+input[type="color"]:active+.input-label-button,
+input[type="checkbox"]:active+.input-label-button,
+input[type="radio"]:active+.input-label-button {
+ border-bottom-color: rgb(var(--accent));
+}
+
input[type="color"]:checked+.input-label-button,
input[type="checkbox"]:checked+.input-label-button,
input[type="radio"]:checked+.input-label-button {
border-bottom-color: rgb(var(--accent));
}
+input[type="color"][disabled]+.input-label-button,
+input[type="checkbox"][disabled]+.input-label-button,
+input[type="radio"][disabled]+.input-label-button {
+ background-color: var(--gray-02);
+ border-color: transparent;
+ color: var(--gray-04);
+ cursor: default;
+}
+
input[type="checkbox"][disabled]+label,
input[type="radio"][disabled]+label {
color: var(--gray-04);
diff --git a/css/header.css b/css/header.css
index ccc4c85a..0f60d419 100644
--- a/css/header.css
+++ b/css/header.css
@@ -19,9 +19,6 @@
}
.header-item {
- margin-left: var(--gutter);
- margin-right: var(--gutter);
- margin-bottom: 1em;
margin: var(--gutter);
display: flex;
flex-wrap: nowrap;
diff --git a/css/link.css b/css/link.css
index 04a26a00..eb3aec7a 100644
--- a/css/link.css
+++ b/css/link.css
@@ -230,6 +230,16 @@
text-overflow: ellipsis;
}
+.link-empty {
+ grid-column-start: 1;
+ grid-column-end: -1;
+ text-align: center;
+}
+
+.link-empty-heading {
+ color: var(--gray-04);
+}
+
.is-link-block .link-name {
text-align: center;
}
diff --git a/index.html b/index.html
index 39d3621c..2ae8ed69 100644
--- a/index.html
+++ b/index.html
@@ -70,7 +70,7 @@
-
-
+
diff --git a/js/bookmarks.js b/js/bookmarks.js
index ec0174d8..871d3b73 100644
--- a/js/bookmarks.js
+++ b/js/bookmarks.js
@@ -134,14 +134,16 @@ var bookmarks = (function() {
var get = function(timeStamp) {
var _singleBookmark = function() {
+ var found = false;
for (var i = 0; i < all.length; i++) {
if (all[i].timeStamp === timeStamp) {
- return all[i];
+ found = all[i];
};
};
+ return found;
};
var _allBookmarks = function() {
- var by = {
+ var action = {
none: function(array) {
return helper.sortObject(array, "timeStamp");
},
@@ -152,9 +154,9 @@ var bookmarks = (function() {
return helper.sortObject(array, "letter");
}
};
- return by[state.get().link.sort](all);
+ return action[state.get().link.sort](all);
};
- if (timeStamp) {
+ if (timeStamp && typeof timeStamp == "number") {
return _singleBookmark(timeStamp);
} else {
return _allBookmarks();
diff --git a/js/control.js b/js/control.js
index 63d21706..5db0d0ef 100644
--- a/js/control.js
+++ b/js/control.js
@@ -108,7 +108,19 @@ var control = (function() {
_layout();
};
- var _dependents = function() {
+ var dependents = function() {
+ var _edit = function() {
+ if (bookmarks.get().length > 0) {
+ helper.e(".control-edit").disabled = false;
+ } else {
+ helper.e(".control-edit").disabled = true;
+ helper.e(".control-edit").checked = false;
+ state.change({
+ path: "edit.active",
+ value: false
+ });
+ };
+ };
var _date = function() {
var activeCount = 0;
var toCheck = [state.get().header.date.show.date, state.get().header.date.show.day, state.get().header.date.show.month, state.get().header.date.show.year];
@@ -180,6 +192,7 @@ var control = (function() {
helper.e(".control-header-search-engine-custom-url").disabled = true;
};
};
+ _edit();
_date();
_clock();
_search();
@@ -198,6 +211,7 @@ var control = (function() {
value: this.checked
});
render();
+ dependents();
data.save();
}, false);
helper.e(".control-layout-theme").addEventListener("change", function() {
@@ -252,7 +266,7 @@ var control = (function() {
value: this.checked
});
render();
- _dependents();
+ dependents();
header.render();
data.save();
}, false);
@@ -262,7 +276,7 @@ var control = (function() {
value: this.checked
});
render();
- _dependents();
+ dependents();
header.render();
data.save();
}, false);
@@ -273,7 +287,7 @@ var control = (function() {
value: this.value
});
render();
- _dependents();
+ dependents();
search.update();
data.save();
}, false);
@@ -292,7 +306,7 @@ var control = (function() {
value: this.checked
});
render();
- _dependents();
+ dependents();
date.clear();
date.render();
header.render();
@@ -304,7 +318,7 @@ var control = (function() {
value: this.checked
});
render();
- _dependents();
+ dependents();
date.clear();
date.render();
header.render();
@@ -316,7 +330,7 @@ var control = (function() {
value: this.checked
});
render();
- _dependents();
+ dependents();
date.clear();
date.render();
header.render();
@@ -328,7 +342,7 @@ var control = (function() {
value: this.checked
});
render();
- _dependents();
+ dependents();
date.clear();
date.render();
header.render();
@@ -340,7 +354,7 @@ var control = (function() {
value: this.checked
});
render();
- _dependents();
+ dependents();
date.clear();
date.render();
header.render();
@@ -365,7 +379,7 @@ var control = (function() {
value: this.checked
});
render();
- _dependents();
+ dependents();
clock.clear();
clock.render();
header.render();
@@ -377,7 +391,7 @@ var control = (function() {
value: this.checked
});
render();
- _dependents();
+ dependents();
clock.clear();
clock.render();
header.render();
@@ -389,7 +403,7 @@ var control = (function() {
value: this.checked
});
render();
- _dependents();
+ dependents();
clock.clear();
clock.render();
header.render();
@@ -410,7 +424,7 @@ var control = (function() {
path: "header.clock.hour24",
value: this.checked
});
- _dependents();
+ dependents();
clock.clear();
clock.render();
header.render();
@@ -508,15 +522,16 @@ var control = (function() {
var init = function() {
_bind();
update();
- _dependents();
+ dependents();
render();
};
// exposed methods
return {
init: init,
- update: update,
- render: render
+ render: render,
+ dependents: dependents,
+ update: update
};
})();
diff --git a/js/data.js b/js/data.js
index 053a76f7..962e285f 100644
--- a/js/data.js
+++ b/js/data.js
@@ -10,7 +10,7 @@ var data = (function() {
return localStorage.getItem(key);
};
- var clear = function(key) {
+ var remove = function(key) {
localStorage.removeItem(key);
};
@@ -24,6 +24,10 @@ var data = (function() {
console.log("data saved");
};
+ var wipe = function() {
+ remove(saveName);
+ };
+
var load = function() {
var data = JSON.parse(get(saveName));
return data;
@@ -48,14 +52,10 @@ var data = (function() {
_checkForSavedData(load());
};
- var wipe = function() {
- clear(saveName);
- };
-
return {
init: init,
save: save,
- clear: clear,
+ remove: remove,
set: set,
get: get,
load: load,
diff --git a/js/helper.js b/js/helper.js
index a297c069..20477989 100644
--- a/js/helper.js
+++ b/js/helper.js
@@ -113,10 +113,7 @@ var helper = (function() {
var makeNode = function(override) {
var options = {
tag: null,
- classes: null,
text: null,
- url: null,
- index: null,
attr: null
};
if (override) {
diff --git a/js/link.js b/js/link.js
index 736089f9..556cdd38 100644
--- a/js/link.js
+++ b/js/link.js
@@ -3,7 +3,8 @@ var link = (function() {
var _bind = function(override) {
var options = {
element: null,
- action: null
+ action: null,
+ bookmarkData: null
};
if (override) {
options = helper.applyOptions(options, override);
@@ -11,88 +12,98 @@ var link = (function() {
var action = {
edit: function() {
options.element.addEventListener("click", function() {
- edit(this);
+ edit(options.bookmarkData);
}, false);
},
- delete: function() {
+ remove: function() {
options.element.addEventListener("click", function() {
- remove(this);
+ remove(options.bookmarkData);
+ control.dependents();
+ control.render();
}, false);
}
};
if (options.element != null) {
action[options.action]();
- }
+ };
};
- var add = function() {
- state.get().link.action = "add";
- var form = _makeLinkForm();
- modal.render({
- heading: "Add a new bookmark",
- action: save,
- actionText: "Add",
- size: "small",
- content: form
- });
- };
-
- var edit = function(button) {
- state.get().link.action = "edit";
- state.get().link.editObject = bookmarks.get(parseInt(button.closest(".link-item").dataset.timeStamp, 10));
- var currentBookmark = bookmarks.get(state.get().link.editObject.timeStamp);
+ var edit = function(bookmarkData) {
+ var currentBookmark = bookmarks.get(bookmarkData.timeStamp);
var form = _makeLinkForm();
form.querySelector(".link-form-input-letter").value = currentBookmark.letter;
form.querySelector(".link-form-input-name").value = currentBookmark.name;
form.querySelector(".link-form-input-url").value = currentBookmark.url;
modal.render({
heading: "Edit " + currentBookmark.name,
- action: save,
+ action: function() {
+ save({
+ action: "edit",
+ form: form,
+ bookmarkData: bookmarkData
+ });
+ },
actionText: "Save",
size: "small",
content: form
});
};
- var save = function(button) {
- var action = {
- add: function(newLinkData) {
- newLinkData.timeStamp = new Date().getTime();
- bookmarks.add(newLinkData);
+ var add = function() {
+ var form = _makeLinkForm();
+ modal.render({
+ heading: "Add a new bookmark",
+ action: function() {
+ save({
+ action: "add",
+ form: form
+ });
+ control.dependents();
+ control.render();
},
- edit: function(newLinkData) {
- newLinkData.timeStamp = state.get().link.editObject.timeStamp;
- bookmarks.edit(newLinkData, state.get().link.editObject.timeStamp);
- }
- };
- var form = helper.e(".link-form");
- var newLinkData = {
- letter: form.querySelector(".link-form-input-letter").value,
- name: form.querySelector(".link-form-input-name").value,
- url: form.querySelector(".link-form-input-url").value
- };
- action[state.get().link.action](newLinkData);
- state.get().link.editObject = null;
- state.get().link.action = null;
- clear();
- if (state.get().header.search.searching) {
- search.render();
- } else {
- render();
- };
- data.save();
+ actionText: "Add",
+ size: "small",
+ content: form
+ });
};
- var remove = function(button) {
- var timeStamp = parseInt(button.closest(".link-item").dataset.timeStamp, 10);
- bookmarks.remove(timeStamp);
- clear();
- if (state.get().header.search.searching) {
- search.render();
- } else {
- render();
+ var save = function(override) {
+ var options = {
+ action: null,
+ form: null,
+ bookmarkData: null
};
+ if (override) {
+ options = helper.applyOptions(options, override);
+ };
+ var action = {
+ add: function() {
+ var newBookmarkData = {
+ letter: options.form.querySelector(".link-form-input-letter").value,
+ name: options.form.querySelector(".link-form-input-name").value,
+ url: options.form.querySelector(".link-form-input-url").value,
+ timeStamp: new Date().getTime()
+ };
+ bookmarks.add(newBookmarkData);
+ },
+ edit: function() {
+ options.bookmarkData.letter = options.form.querySelector(".link-form-input-letter").value;
+ options.bookmarkData.name = options.form.querySelector(".link-form-input-name").value;
+ options.bookmarkData.url = options.form.querySelector(".link-form-input-url").value;
+ bookmarks.edit(options.bookmarkData, options.bookmarkData.timeStamp);
+ }
+ };
+ action[options.action]();
data.save();
+ clear();
+ render();
+ };
+
+ var remove = function(bookmarkData) {
+ bookmarks.remove(bookmarkData.timeStamp);
+ data.save();
+ clear();
+ render();
};
var _makeLinkForm = function() {
@@ -212,9 +223,6 @@ var link = (function() {
attr: [{
key: "class",
value: "link-item"
- }, {
- key: "data-time-stamp",
- value: data.timeStamp
}]
});
var linkOptions = {
@@ -286,7 +294,7 @@ var link = (function() {
tag: "button",
attr: [{
key: "class",
- value: "button button-small link-control-item link-edit"
+ value: "button button-small link-control-item"
}, {
key: "tabindex",
value: -1
@@ -299,17 +307,17 @@ var link = (function() {
value: "button-icon icon-edit"
}]
});
- var linkDelete = helper.makeNode({
+ var linkRemove = helper.makeNode({
tag: "button",
attr: [{
key: "class",
- value: "button button-small link-control-item link-delete"
+ value: "button button-small link-control-item"
}, {
key: "tabindex",
value: -1
}]
});
- var linkDeleteIcon = helper.makeNode({
+ var linkRemoveIcon = helper.makeNode({
tag: "span",
attr: [{
key: "class",
@@ -319,9 +327,9 @@ var link = (function() {
linkPanelFront.appendChild(linkLetter);
linkPanelFront.appendChild(linkName);
linkEdit.appendChild(linkEditIcon);
- linkDelete.appendChild(linkDeleteIcon);
+ linkRemove.appendChild(linkRemoveIcon);
linkControl.appendChild(linkEdit);
- linkControl.appendChild(linkDelete);
+ linkControl.appendChild(linkRemove);
linkUrl.appendChild(linkUrlText);
linkPanelBack.appendChild(linkUrl);
linkPanelBack.appendChild(linkControl);
@@ -329,21 +337,105 @@ var link = (function() {
linkItem.appendChild(linkPanelBack);
_bind({
element: linkEdit,
- action: "edit"
+ action: "edit",
+ bookmarkData: data
});
_bind({
- element: linkDelete,
- action: "delete"
+ element: linkRemove,
+ action: "remove",
+ bookmarkData: data
});
return linkItem;
};
- var render = function(array) {
- var linkArea = helper.e(".link-area");
- var bookmarksToRender = array || bookmarks.get();
- bookmarksToRender.forEach(function(arrayItem) {
- linkArea.appendChild(_makeLink(arrayItem));
+ var _makeEmptySearch = function() {
+ var searchInput = helper.e(".search-input");
+ var div = helper.makeNode({
+ tag: "div",
+ attr: [{
+ key: "class",
+ value: "link-empty"
+ }]
});
+ var h1 = helper.makeNode({
+ tag: "h1",
+ attr: [{
+ key: "class",
+ value: "link-empty-heading"
+ }],
+ text: "No matching bookmarks found"
+ });
+ div.appendChild(h1);
+ return div;
+ };
+
+ var _makeEmptyBookmarks = function() {
+ var searchInput = helper.e(".search-input");
+ var div = helper.makeNode({
+ tag: "div",
+ attr: [{
+ key: "class",
+ value: "link-empty"
+ }]
+ });
+ var h1 = helper.makeNode({
+ tag: "h1",
+ attr: [{
+ key: "class",
+ value: "link-empty-heading"
+ }],
+ text: "No bookmarks added"
+ });
+ div.appendChild(h1);
+ return div;
+ };
+
+ var render = function() {
+ var linkArea = helper.e(".link-area");
+ var bookmarksToRender = false;
+ if (state.get().header.search.searching) {
+ bookmarksToRender = search.get();
+ } else {
+ bookmarksToRender = bookmarks.get();
+ };
+ var action = {
+ render: {
+ bookmarks: function(array) {
+ array.forEach(function(arrayItem, index) {
+ linkArea.appendChild(_makeLink(arrayItem));
+ });
+ },
+ empty: {
+ search: function() {
+ linkArea.appendChild(_makeEmptySearch());
+ },
+ bookmarks: function() {
+ linkArea.appendChild(_makeEmptyBookmarks());
+ }
+ }
+ }
+ };
+ // if searching
+ if (state.get().header.search.searching) {
+ // if bookmarks exist to be searched
+ if (bookmarksToRender.total > 0) {
+ // if matching bookmarks found
+ if (bookmarksToRender.matching.length > 0) {
+ action.render.bookmarks(bookmarksToRender.matching);
+ } else {
+ action.render.empty.search();
+ };
+ } else {
+ action.render.empty.bookmarks();
+ };
+ } else {
+ // if bookmarks exist
+ if (bookmarksToRender.length > 0) {
+ action.render.bookmarks(bookmarksToRender);
+ } else {
+ action.render.empty.bookmarks();
+ };
+ };
};
var tabIndex = function() {
diff --git a/js/search.js b/js/search.js
index c33671dc..83c2d025 100644
--- a/js/search.js
+++ b/js/search.js
@@ -6,7 +6,8 @@ var search = (function() {
searchInput.addEventListener("input", function() {
_toggle(this);
_searchClear();
- render();
+ link.clear();
+ link.render();
}, false);
searchClear.addEventListener("click", function() {
_toggle(this);
@@ -17,9 +18,15 @@ var search = (function() {
var _toggle = function(input) {
if (input.value != "") {
- state.get().header.search.searching = true;
+ state.change({
+ path: "header.search.searching",
+ value: true
+ })
} else {
- state.get().header.search.searching = false;
+ state.change({
+ path: "header.search.searching",
+ value: false
+ })
};
};
@@ -33,22 +40,21 @@ var search = (function() {
};
};
- var render = function() {
+ var get = function() {
var searchInput = helper.e(".search-input");
if (state.get().header.search.searching) {
- var searchedBookmarks = [];
+ var searchedBookmarks = {
+ total: 0,
+ matching: []
+ };
+ searchedBookmarks.total = bookmarks.get().length;
bookmarks.get().forEach(function(arrayItem, index) {
- if (arrayItem.url.replace(/^https?\:\/\//i, "").replace(/\/$/, "").toLowerCase().includes(searchInput.value.toLowerCase()) || arrayItem.name.toLowerCase().includes(searchInput.value.toLowerCase())) {
- var copy = JSON.parse(JSON.stringify(arrayItem));
- copy.index = index;
- searchedBookmarks.push(copy);
+ if (arrayItem.url.replace(/^https?\:\/\//i, "").replace(/\/$/, "").toLowerCase().includes(searchInput.value.toLowerCase().replace(/\s/g, "")) || arrayItem.name.toLowerCase().includes(searchInput.value.toLowerCase().replace(/\s/g, ""))) {
+ var bookmarkDataCopy = JSON.parse(JSON.stringify(arrayItem));
+ searchedBookmarks.matching.push(bookmarkDataCopy);
};
});
- link.clear();
- link.render(searchedBookmarks);
- } else {
- link.clear();
- link.render();
+ return searchedBookmarks;
};
};
@@ -73,7 +79,7 @@ var search = (function() {
// exposed methods
return {
init: init,
- render: render,
+ get: get,
update: update,
clear: clear
};
diff --git a/js/state.js b/js/state.js
index 2c54aceb..236e71e2 100644
--- a/js/state.js
+++ b/js/state.js
@@ -54,7 +54,6 @@ var state = (function() {
},
link: {
editObject: null,
- action: null,
newTab: false,
style: "block",
sort: "none"
diff --git a/js/version.js b/js/version.js
index a2e13ee5..9de8d1b6 100644
--- a/js/version.js
+++ b/js/version.js
@@ -1,5 +1,6 @@
var version = (function() {
+ // version is normally bumped when the state needs changing or any new functionality is added
var current = "2.1.0";
var get = function() {