*
* TODO: support error code in the backend for AJAX requests
*/
+ var tagList = document.querySelector('input[name="taglist"]');
+ var existingTags = tagList ? tagList.value.split(' ') : [];
+ var awesomepletes = [];
+
// Display/Hide rename form
var renameTagButtons = document.querySelectorAll('.rename-tag');
[].forEach.call(renameTagButtons, function(rename) {
event.preventDefault();
var block = findParent(event.target, 'div', {'class': 'tag-list-item'});
var form = block.querySelector('.rename-tag-form');
- form.style.display = form.style.display == 'none' ? 'block' : 'none';
+ if (form.style.display == 'none' || form.style.display == '') {
+ form.style.display = 'block';
+ } else {
+ form.style.display = 'none';
+ }
+ block.querySelector('input').focus();
});
});
block.setAttribute('data-tag', totag);
input.setAttribute('name', totag);
input.setAttribute('value', totag);
- input.parentNode.style.display = 'none';
+ findParent(input, 'div', {'class': 'rename-tag-form'}).style.display = 'none';
block.querySelector('a.tag-link').innerHTML = htmlEntities(totag);
block.querySelector('a.tag-link').setAttribute('href', '?searchtags='+ encodeURIComponent(totag));
block.querySelector('a.rename-tag').setAttribute('href', '?do=changetag&fromtag='+ encodeURIComponent(totag));
+
+ // Refresh awesomplete values
+ for (var key in existingTags) {
+ if (existingTags[key] == fromtag) {
+ existingTags[key] = totag;
+ }
+ }
+ awesomepletes = updateAwesompleteList('.rename-tag-input', existingTags, awesomepletes);
}
};
xhr.send('renametag=1&fromtag='+ encodeURIComponent(fromtag) +'&totag='+ encodeURIComponent(totag) +'&token='+ token);
// Validate input with enter key
var renameTagInputs = document.querySelectorAll('.rename-tag-input');
[].forEach.call(renameTagInputs, function(rename) {
+
rename.addEventListener('keypress', function(event) {
if (event.keyCode === 13) { // enter
findParent(event.target, 'div', {'class': 'tag-list-item'}).querySelector('.validate-rename-tag').click();
}
});
});
+
+ updateAwesompleteList('.rename-tag-input', existingTags, awesomepletes);
};
+/**
+ * Find a parent element according to its tag and its attributes
+ *
+ * @param element Element where to start the search
+ * @param tagName Expected parent tag name
+ * @param attributes Associative array of expected attributes (name=>value).
+ *
+ * @returns Found element or null.
+ */
function findParent(element, tagName, attributes)
{
while (element) {
return null;
}
+/**
+ * Ajax request to refresh the CSRF token.
+ */
function refreshToken()
{
var xhr = new XMLHttpRequest();
xhr.send();
}
+/**
+ * Update awesomplete list of tag for all elements matching the given selector
+ *
+ * @param selector CSS selector
+ * @param tags Array of tags
+ * @param instances List of existing awesomplete instances
+ */
+function updateAwesompleteList(selector, tags, instances)
+{
+ // First load: create Awesomplete instances
+ if (instances.length == 0) {
+ var elements = document.querySelectorAll(selector);
+ [].forEach.call(elements, function (element) {
+ instances.push(new Awesomplete(
+ element,
+ {'list': tags}
+ ));
+ });
+ } else {
+ // Update awesomplete tag list
+ for (var key in instances) {
+ instances[key].list = tags;
+ }
+ }
+ return instances;
+}
+
/**
* html_entities in JS
*
function activateFirefoxSocial(node) {
var loc = location.href;
- var baseURL = loc.substring(0, loc.lastIndexOf("/"));
+ var baseURL = loc.substring(0, loc.lastIndexOf("/") + 1);
// Keeping the data separated (ie. not in the DOM) so that it's maintainable and diffable.
var data = {
icon32URL: baseURL + "/images/favicon.ico",
icon64URL: baseURL + "/images/favicon.ico",
- shareURL: baseURL + "{noparse}?post=%{url}&title=%{title}&description=%{text}&source=firefoxsocialapi{/noparse}",
+ shareURL: baseURL + "?post=%{url}&title=%{title}&description=%{text}&source=firefoxsocialapi",
homepageURL: baseURL
};
node.setAttribute("data-service", JSON.stringify(data));