nightTab/js/link.js
2019-06-14 20:15:10 +01:00

676 lines
23 KiB
JavaScript

var link = (function() {
var _previousFocusLink = null;
var _returnToPreviousFocusLink = function() {
if (_previousFocusLink != null) {
var linkPanelFront = helper.eA(".link-panel-front");
if (linkPanelFront.length > 0) {
if (_previousFocusLink >= 0) {
linkPanelFront[_previousFocusLink].focus();
} else {
linkPanelFront[0].focus();
};
} else {
helper.e("body").focus();
};
_previousFocusLink = null;
};
};
var stagedBookmarkData = {
display: null,
letter: null,
icon: {
name: null,
prefix: null,
label: null
},
name: null,
url: null,
timeStamp: null,
accent: {
override: null,
color: {
r: null,
g: null,
b: null
}
}
};
var initStagedBookmarkData = function() {
link.stagedBookmarkData.display = "letter";
link.stagedBookmarkData.accent.override = false;
};
var resetStagedBookmarkData = function() {
link.stagedBookmarkData.display = null;
link.stagedBookmarkData.letter = null;
link.stagedBookmarkData.icon.name = null;
link.stagedBookmarkData.icon.prefix = null;
link.stagedBookmarkData.icon.label = null;
link.stagedBookmarkData.name = null;
link.stagedBookmarkData.url = null;
link.stagedBookmarkData.timeStamp = null;
link.stagedBookmarkData.accent.override = null;
link.stagedBookmarkData.accent.color.r = null;
link.stagedBookmarkData.accent.color.g = null;
link.stagedBookmarkData.accent.color.b = null;
};
var add = function() {
initStagedBookmarkData();
var form = _makeLinkForm();
modal.render({
heading: "Add a new bookmark",
successAction: function() {
link.stagedBookmarkData.timeStamp = new Date().getTime();
bookmarks.add(JSON.parse(JSON.stringify(link.stagedBookmarkData)));
data.save();
clear();
render.item.all();
render.tabIndex();
control.dependents();
control.render();
resetStagedBookmarkData();
},
cancelAction: function() {
resetStagedBookmarkData();
autoSuggest.destroy();
},
actionText: "Add",
size: "small",
content: form
});
};
var edit = function(bookmarkData) {
link.stagedBookmarkData = JSON.parse(JSON.stringify(bookmarkData));
var form = _makeLinkForm();
if (link.stagedBookmarkData.display == "letter" || link.stagedBookmarkData.display == null) {
form.querySelector(".link-form-input-letter").removeAttribute("disabled");
form.querySelector(".link-form-input-icon").setAttribute("disabled", "");
form.querySelector(".form-group-text").setAttribute("disabled", "");
form.querySelector(".link-form-input-icon").setAttribute("disabled", "");
form.querySelector(".link-form-input-helper-icon").setAttribute("disabled", "");
form.querySelector(".link-form-icon-clear").setAttribute("disabled", "");
form.querySelector(".link-form-text-icon").tabIndex = -1;
} else if (link.stagedBookmarkData.display == "icon") {
form.querySelector(".link-form-input-letter").setAttribute("disabled", "");
form.querySelector(".link-form-input-icon").removeAttribute("disabled");
form.querySelector(".form-group-text").removeAttribute("disabled");
form.querySelector(".link-form-input-icon").removeAttribute("disabled");
form.querySelector(".link-form-input-helper-icon").removeAttribute("disabled");
form.querySelector(".link-form-icon-clear").removeAttribute("disabled");
form.querySelector(".link-form-input-display-icon").checked = true;
form.querySelector(".link-form-text-icon").tabIndex = 1;
};
if (link.stagedBookmarkData.icon.name != null && link.stagedBookmarkData.icon.prefix != null && link.stagedBookmarkData.icon.label != null) {
form.querySelector(".link-form-text-icon").appendChild(helper.node("span|class:link-form-icon " + link.stagedBookmarkData.icon.prefix + " fa-" + link.stagedBookmarkData.icon.name));
};
form.querySelector(".link-form-input-letter").value = link.stagedBookmarkData.letter;
form.querySelector(".link-form-input-icon").value = link.stagedBookmarkData.icon.label;
form.querySelector(".link-form-input-name").value = link.stagedBookmarkData.name;
form.querySelector(".link-form-input-url").value = link.stagedBookmarkData.url;
if (link.stagedBookmarkData.accent.override) {
form.querySelector(".link-form-input-color").value = helper.rgbToHex(link.stagedBookmarkData.accent.color);
};
modal.render({
heading: "Edit " + link.stagedBookmarkData.name,
successAction: function() {
bookmarks.edit(JSON.parse(JSON.stringify(link.stagedBookmarkData)));
data.save();
clear();
render.item.all();
render.tabIndex();
_returnToPreviousFocusLink();
resetStagedBookmarkData();
},
cancelAction: function() {
_returnToPreviousFocusLink();
resetStagedBookmarkData();
},
actionText: "Save",
size: "small",
content: form
});
};
var remove = function(bookmarkData) {
modal.render({
heading: "Remove " + bookmarkData.name + " bookmark",
content: "Are you sure you want to remove this bookmark? This can not be undone.",
successAction: function() {
_previousFocusLink = _previousFocusLink - 1;
bookmarks.remove(bookmarkData);
_checkCount();
data.save();
clear();
render.item.all();
control.dependents();
control.render();
_returnToPreviousFocusLink();
},
cancelAction: function() {
_returnToPreviousFocusLink();
},
actionText: "Remove",
size: "small"
});
};
var _checkCount = function() {
if (bookmarks.get().length <= 0) {
helper.setObject({
object: state.get(),
path: "link.edit",
newValue: false
});
};
};
var _makeLinkForm = function() {
var form = helper.node("form|class:link-form");
var fieldset = helper.node("fieldset");
var letterFormIndet = helper.node("div|class:form-indent");
var letterInputWrap = helper.node("div|class:input-wrap");
var letterInput = helper.node("input|type:text,class:link-form-input-letter mb-0,id:link-form-input-letter,placeholder:E,tabindex:1,autocomplete:off,autocorrect:off,autocapitalize:off,spellcheck:false");
var iconFormIndet = helper.node("div|class:form-indent");
var iconFormGroupWrap = helper.node("div|class:input-wrap");
var iconFormGroup = helper.node("div|class:form-group auto-suggest-wrapper");
var iconInput = helper.node("input|type:text,class:link-form-input-icon auto-suggest-input,id:link-form-input-icon,placeholder:Search for Brands or Icons,tabindex:1,autocomplete:off,autocorrect:off,autocapitalize:off,spellcheck:false,disabled");
var iconFormGroupText = helper.node("div|class:form-group-text link-form-text-icon,tabindex:-1,disabled");
var iconFormGroupClear = helper.node("button|class:link-form-icon-clear button mb-0,type:button,tabindex:1,disabled");
var iconFormGroupClearIcon = helper.node("span|class:icon-close");
var iconPara = helper.node("p:Refer to the \"Free\" and \"Brand\" icons from FontAwesome for full set of icons supported.|class:link-form-input-helper-icon input-helper small muted,disabled");
var nameInputWrap = helper.node("div|class:input-wrap");
var nameLabel = helper.node("label:Name|for:link-form-input-name");
var nameInput = helper.node("input|type:text,class:link-form-input-name mb-0,id:link-form-input-name,placeholder:Example,tabindex:1,autocomplete:off,autocorrect:off,autocapitalize:off,spellcheck:false");
var urlInputWrap = helper.node("div|class:input-wrap");
var urlLabel = helper.node("label:URL|for:link-form-input-url");
var urlInput = helper.node("input|type:text,class:link-form-input-url mb-0,id:link-form-input-url,placeholder:https://www.example.com/,tabindex:1,autocomplete:off,autocorrect:off,autocapitalize:off,spellcheck:false");
var colorWrap = helper.node("div|class:input-wrap");
var colorFormGroup = helper.node("div|class:form-group");
var colorLabel = helper.node("label:Accent override|for:link-form-input-color");
var colorInput = helper.node("input|id:link-form-input-color,class:link-form-input-color mb-0,type:color,value:" + helper.rgbToHex(state.get().theme.accent.current) + ",tabindex:1");
var colorButtonRefresh = helper.node("button|class:button mb-0,type:button,tabindex:1");
var colorButtonRefreshIcon = helper.node("span|class:icon-refresh");
var colorPara = helper.node("p:Use this colour to override the global Accent colour.|class:input-helper small muted");
var letterRadioInputWrap = helper.node("div|class:input-wrap");
var letterRadioInput = helper.node("input|class:link-form-input-display-letter,id:link-form-input-display-letter,type:radio,name:link-form-input-display,tabindex:1,checked,value:letter");
var letterRadioLable = helper.node("label:Letters|for:link-form-input-display-letter");
var iconRadioInputWrap = helper.node("div|class:input-wrap");
var iconRadioInput = helper.node("input|class:link-form-input-display-icon,id:link-form-input-display-icon,type:radio,name:link-form-input-display,tabindex:1,value:icon");
var iconRadioLable = helper.node("label:Icon|for:link-form-input-display-icon");
letterRadioInputWrap.appendChild(letterRadioInput);
letterRadioInputWrap.appendChild(letterRadioLable);
fieldset.appendChild(letterRadioInputWrap);
letterInputWrap.appendChild(letterInput);
letterFormIndet.appendChild(letterInputWrap);
fieldset.appendChild(letterFormIndet);
iconRadioInputWrap.appendChild(iconRadioInput);
iconRadioInputWrap.appendChild(iconRadioLable);
fieldset.appendChild(iconRadioInputWrap);
iconFormGroupClear.appendChild(iconFormGroupClearIcon);
iconFormGroup.appendChild(iconInput);
iconFormGroup.appendChild(iconFormGroupText);
iconFormGroup.appendChild(iconFormGroupClear);
iconFormGroupWrap.appendChild(iconFormGroup);
iconFormGroupWrap.appendChild(iconPara);
iconFormIndet.appendChild(iconFormGroupWrap);
fieldset.appendChild(iconFormIndet);
fieldset.appendChild(helper.node("hr"));
nameInputWrap.appendChild(nameLabel);
nameInputWrap.appendChild(nameInput);
fieldset.appendChild(nameInputWrap);
urlInputWrap.appendChild(urlLabel);
urlInputWrap.appendChild(urlInput);
fieldset.appendChild(urlInputWrap);
fieldset.appendChild(helper.node("hr"));
colorFormGroup.appendChild(colorInput);
colorButtonRefresh.appendChild(colorButtonRefreshIcon);
colorFormGroup.appendChild(colorButtonRefresh);
colorWrap.appendChild(colorLabel);
colorWrap.appendChild(colorFormGroup);
colorWrap.appendChild(colorPara);
fieldset.appendChild(colorWrap);
form.appendChild(fieldset);
letterRadioInput.addEventListener("change", function(event) {
link.stagedBookmarkData.display = this.value;
}, false);
iconRadioInput.addEventListener("change", function(event) {
link.stagedBookmarkData.display = this.value;
}, false);
letterInput.addEventListener("input", function(event) {
link.stagedBookmarkData.letter = this.value;
}, false);
nameInput.addEventListener("input", function(event) {
link.stagedBookmarkData.name = this.value;
}, false);
urlInput.addEventListener("input", function(event) {
link.stagedBookmarkData.url = this.value;
}, false);
colorInput.addEventListener("change", function(event) {
link.stagedBookmarkData.accent.override = true;
link.stagedBookmarkData.accent.color = helper.hexToRgb(this.value);
}, false);
colorButtonRefresh.addEventListener("click", function(event) {
colorInput.value = helper.rgbToHex(state.get().theme.accent.current);
link.stagedBookmarkData.accent.override = false;
link.stagedBookmarkData.accent.color = {
r: null,
g: null,
b: null
};
}, false);
iconFormGroupClear.addEventListener("click", function(event) {
link.stagedBookmarkData.icon.name = null;
link.stagedBookmarkData.icon.prefix = null;
link.stagedBookmarkData.icon.label = null;
var existingIcon = helper.e(".link-form-icon");
if (existingIcon) {
existingIcon.remove();
};
iconInput.value = "";
}, false);
letterRadioInput.addEventListener("change", function(event) {
letterInput.removeAttribute("disabled");
iconInput.setAttribute("disabled", "");
iconFormGroupText.setAttribute("disabled", "");
iconPara.setAttribute("disabled", "");
iconFormGroupClear.setAttribute("disabled", "");
iconFormGroupText.tabIndex = -1;
}, false);
iconRadioInput.addEventListener("change", function(event) {
letterInput.setAttribute("disabled", "");
iconInput.removeAttribute("disabled");
iconFormGroupText.removeAttribute("disabled");
iconPara.removeAttribute("disabled");
iconFormGroupClear.removeAttribute("disabled");
iconFormGroupText.tabIndex = 1;
}, false);
autoSuggest.bind({
input: iconInput,
type: "fontawesomeIcon",
postFocus: iconFormGroupText
});
return form;
};
var _makeLink = function(data, index) {
var linkItemOptions = {
tag: "div",
attr: [{
key: "class",
value: "link-item"
}]
};
if (data.accent.override) {
linkItemOptions.attr.push({
key: "style",
value: "--theme-accent: " + data.accent.color.r + ", " + data.accent.color.g + ", " + data.accent.color.b
});
};
var linkItem = helper.makeNode(linkItemOptions);
var linkPanelFrontOptions = {
tag: "a",
attr: [{
key: "class",
value: "link-panel-front"
}, {
key: "href",
value: data.url
}, {
key: "tabindex",
value: 1
}]
};
if (state.get().link.newTab) {
linkPanelFrontOptions.attr.push({
key: "target",
value: "_blank"
});
};
var linkPanelFront = helper.makeNode(linkPanelFrontOptions);
var linkPanelBack = helper.makeNode({
tag: "div",
attr: [{
key: "class",
value: "link-panel-back"
}]
});
var linkDisplay = helper.makeNode({
tag: "div",
attr: [{
key: "class",
value: "link-display"
}]
});
var linkDisplayLetter = null;
var linkDisplayIcon = null;
if (data.display == "letter") {
linkDisplayLetter = helper.makeNode({
tag: "p",
text: data.letter,
attr: [{
key: "class",
value: "link-display-letter"
}]
});
} else if (data.display == "icon" && data.icon.prefix != null && data.icon.name != null) {
linkDisplayIcon = helper.makeNode({
tag: "div",
attr: [{
key: "class",
value: "link-display-icon " + data.icon.prefix + " fa-" + data.icon.name
}]
});
};
var linkName = helper.makeNode({
tag: "p",
text: data.name,
attr: [{
key: "class",
value: "link-name"
}]
});
var linkUrl = helper.makeNode({
tag: "div",
attr: [{
key: "class",
value: "link-url"
}]
});
var url = "";
if (data.url != null) {
url = data.url.replace(/^https?\:\/\//i, "").replace(/\/$/, "");
};
var linkUrlText = helper.makeNode({
tag: "p",
text: url,
attr: [{
key: "class",
value: "link-url-text"
}, {
key: "title",
value: url
}]
});
var linkControl = helper.makeNode({
tag: "div",
attr: [{
key: "class",
value: "link-control"
}]
});
var linkEdit = helper.makeNode({
tag: "button",
attr: [{
key: "class",
value: "button button-small link-control-item"
}, {
key: "tabindex",
value: -1
}]
});
var linkEditIcon = helper.makeNode({
tag: "span",
attr: [{
key: "class",
value: "button-icon icon-edit"
}]
});
var linkRemove = helper.makeNode({
tag: "button",
attr: [{
key: "class",
value: "button button-small link-control-item"
}, {
key: "tabindex",
value: -1
}]
});
var linkRemoveIcon = helper.makeNode({
tag: "span",
attr: [{
key: "class",
value: "button-icon icon-close"
}]
});
if (data.display == "letter") {
linkDisplay.appendChild(linkDisplayLetter);
} else if (data.display == "icon" && data.icon.prefix != null && data.icon.name != null) {
linkDisplay.appendChild(linkDisplayIcon);
};
linkPanelFront.appendChild(linkDisplay);
linkPanelFront.appendChild(linkName);
linkEdit.appendChild(linkEditIcon);
linkRemove.appendChild(linkRemoveIcon);
linkControl.appendChild(linkEdit);
linkControl.appendChild(linkRemove);
linkUrl.appendChild(linkUrlText);
linkPanelBack.appendChild(linkUrl);
linkPanelBack.appendChild(linkControl);
linkItem.appendChild(linkPanelFront);
linkItem.appendChild(linkPanelBack);
linkEdit.addEventListener("click", function() {
_previousFocusLink = index;
edit(data);
}, false);
linkRemove.addEventListener("click", function() {
_previousFocusLink = index;
remove(data);
}, false);
return linkItem;
};
var autoSuggestIconAction = function(autoSuggestData) {
link.stagedBookmarkData.icon.label = autoSuggestData.label;
link.stagedBookmarkData.icon.name = autoSuggestData.name;
if (autoSuggestData.styles.includes("solid")) {
link.stagedBookmarkData.icon.prefix = "fas";
} else if (autoSuggestData.styles.includes("brands")) {
link.stagedBookmarkData.icon.prefix = "fab";
};
var existingIcon = helper.e(".link-form-icon");
if (existingIcon) {
existingIcon.remove();
};
helper.e(".link-form-input-icon").value = autoSuggestData.label;
helper.e(".link-form-text-icon").appendChild(helper.node("span|class:link-form-icon " + link.stagedBookmarkData.icon.prefix + " fa-" + link.stagedBookmarkData.icon.name));
helper.e(".link-form-text-icon").focus();
};
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 clear = function() {
var linkArea = helper.e(".link-area");
while (linkArea.lastChild) {
linkArea.removeChild(linkArea.lastChild);
};
};
var render = {
area: {
width: function() {
_renderAreaWidth();
}
},
item: {
all: function() {
_renderItemAll();
},
display: {
letter: function() {
_renderItemDisplayLetter();
},
icon: function() {
_renderItemDisplayIcon();
}
},
name: function() {
_renderItemName();
},
size: function() {
_renderItemSize();
}
},
tabIndex: function() {
_renderTabIndex();
}
};
var _renderAreaWidth = function() {
var html = helper.e("html");
html.style.setProperty("--link-area-width", state.get().link.area.width + "%");
};
var _renderItemAll = function() {
var linkArea = helper.e(".link-area");
var bookmarksToRender = false;
if (state.get().search) {
bookmarksToRender = search.get();
} else {
bookmarksToRender = bookmarks.get();
};
var action = {
render: {
bookmarks: function(array) {
array.forEach(function(arrayItem, index) {
linkArea.appendChild(_makeLink(arrayItem, index));
});
},
empty: {
search: function() {
linkArea.appendChild(_makeEmptySearch());
},
bookmarks: function() {
linkArea.appendChild(_makeEmptyBookmarks());
}
}
}
};
// if searching
if (state.get().search) {
// 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 _renderItemDisplayLetter = function() {
var html = helper.e("html");
html.style.setProperty("--link-item-display-letter-size", state.get().link.item.display.letter.size + "em");
};
var _renderItemDisplayIcon = function() {
var html = helper.e("html");
html.style.setProperty("--link-item-display-icon-size", state.get().link.item.display.icon.size + "em");
};
var _renderItemName = function() {
var html = helper.e("html");
html.style.setProperty("--link-item-name-size", state.get().link.item.name.size + "em");
};
var _renderItemSize = function() {
var html = helper.e("html");
html.style.setProperty("--link-item-size", state.get().link.item.size + "em");
};
var _renderTabIndex = function() {
var allLinkControlItem = helper.eA(".link-control-item");
if (state.get().link.edit) {
allLinkControlItem.forEach(function(arrayItem, index) {
arrayItem.tabIndex = 1;
});
} else {
allLinkControlItem.forEach(function(arrayItem, index) {
arrayItem.tabIndex = -1;
});
};
};
var init = function() {
render.area.width();
render.item.all();
render.item.size();
render.item.display.letter();
render.item.display.icon();
render.item.name();
};
// exposed methods
return {
stagedBookmarkData: stagedBookmarkData,
autoSuggestIconAction: autoSuggestIconAction,
init: init,
clear: clear,
add: add,
edit: edit,
remove: remove,
render: render
};
})();