diff options
| author | rr- | 2016-08-22 01:25:10 +0200 |
|---|---|---|
| committer | rr- | 2016-08-22 01:40:30 +0200 |
| commit | d5e197e6ea353e1d635c33b95cd342d51c5baf76 (patch) | |
| tree | cd7277f5b7cdaf3cd1fa403efee9fe617d956b10 /client/js | |
| parent | 44b2d9b830ad28c2d66ce7359191d24578b0a1c1 (diff) | |
client/general: add empty href for link buttons
In e464e69 I removed href='#' but I noticed that it broke some things.
Readding href serves two purposes:
- it makes links reachable with Tab key
- it makes links clickable with Enter key
The alternative to this approach was to introduce [tabindex] and [role]
attributes. But not only using tabindex=0 with <a/> is questionable,
it'd require adding a keyboard handler that'd intercept space and return
key presses and simulated link clicks. Since it's best to leave this
kind of thing to the native UI, I went with readding hrefs instead. I
believe that hash hrefs, even though being a common practice, are silly,
so I decided to settle down with empty hrefs.
As a bonus, I added a snippet that prevents middle mouse clicks from
opening such links/buttons in new tabs, which was the motivation for
e464e69.
Diffstat (limited to 'client/js')
| -rw-r--r-- | client/js/controls/auto_complete_control.js | 1 | ||||
| -rw-r--r-- | client/js/controls/post_edit_sidebar_control.js | 5 | ||||
| -rw-r--r-- | client/js/controls/tag_input_control.js | 4 | ||||
| -rw-r--r-- | client/js/util/views.js | 8 | ||||
| -rw-r--r-- | client/js/views/post_upload_view.js | 1 |
5 files changed, 19 insertions, 0 deletions
diff --git a/client/js/controls/auto_complete_control.js b/client/js/controls/auto_complete_control.js index d8bc83a..fd3fc47 100644 --- a/client/js/controls/auto_complete_control.js +++ b/client/js/controls/auto_complete_control.js @@ -215,6 +215,7 @@ class AutoCompleteControl { const listItem = document.createElement('li'); const link = document.createElement('a'); link.innerHTML = resultItem.caption; + link.setAtribute('href', ''); link.setAttribute('data-key', resultItem.value); link.addEventListener( 'mouseenter', diff --git a/client/js/controls/post_edit_sidebar_control.js b/client/js/controls/post_edit_sidebar_control.js index 670f8c5..b3fd7b5 100644 --- a/client/js/controls/post_edit_sidebar_control.js +++ b/client/js/controls/post_edit_sidebar_control.js @@ -146,12 +146,14 @@ class PostEditSidebarControl extends events.EventTarget { } _evtRemoveThumbnailClick(e) { + e.preventDefault(); this._thumbnailFileDropper.reset(); this._newPostThumbnail = null; this._thumbnailRemovalLinkNode.style.display = 'none'; } _evtFeatureClick(e) { + e.preventDefault(); if (confirm('Are you sure you want to feature this post?')) { this.dispatchEvent(new CustomEvent('feature', { detail: { @@ -162,6 +164,7 @@ class PostEditSidebarControl extends events.EventTarget { } _evtDeleteClick(e) { + e.preventDefault(); if (confirm('Are you sure you want to delete this post?')) { this.dispatchEvent(new CustomEvent('delete', { detail: { @@ -195,6 +198,7 @@ class PostEditSidebarControl extends events.EventTarget { } _evtAddNoteClick(e) { + e.preventDefault(); if (e.target.classList.contains('inactive')) { return; } @@ -203,6 +207,7 @@ class PostEditSidebarControl extends events.EventTarget { } _evtDeleteNoteClick(e) { + e.preventDefault(); if (e.target.classList.contains('inactive')) { return; } diff --git a/client/js/controls/tag_input_control.js b/client/js/controls/tag_input_control.js index 6546fcd..4bc3d08 100644 --- a/client/js/controls/tag_input_control.js +++ b/client/js/controls/tag_input_control.js @@ -251,6 +251,7 @@ class TagInputControl extends events.EventTarget { } _evtAddTagButtonClick(e) { + e.preventDefault(); this.addTag(this._tagInputNode.value, SOURCE_USER_INPUT); this._tagInputNode.value = ''; } @@ -324,6 +325,7 @@ class TagInputControl extends events.EventTarget { const removalLinkNode = document.createElement('a'); removalLinkNode.classList.add('append'); + removalLinkNode.setAttribute('href', '') removalLinkNode.setAttribute('data-pseudo-content', '×'); removalLinkNode.addEventListener('click', e => { e.preventDefault(); @@ -387,6 +389,7 @@ class TagInputControl extends events.EventTarget { const addLinkNode = document.createElement('a'); addLinkNode.textContent = tagName; addLinkNode.classList.add('add-tag'); + addLinkNode.setAttribute('href', ''); if (actualTag) { addLinkNode.classList.add( misc.makeCssName(actualTag.category, 'tag')); @@ -405,6 +408,7 @@ class TagInputControl extends events.EventTarget { const removeLinkNode = document.createElement('a'); removeLinkNode.classList.add('remove-tag'); removeLinkNode.classList.add('append'); + removeLinkNode.setAttribute('href', ''); removeLinkNode.setAttribute('data-pseudo-content', '×'); removeLinkNode.addEventListener('click', e => { e.preventDefault(); diff --git a/client/js/util/views.js b/client/js/util/views.js index e6daf51..1887cd3 100644 --- a/client/js/util/views.js +++ b/client/js/util/views.js @@ -476,6 +476,14 @@ document.addEventListener('input', e => { } }); +// prevent opening buttons in new tabs +document.addEventListener('click', e => { + if (e.target.getAttribute('href') === '' && e.which === 2) { + console.log('prevented'); + e.preventDefault(); + } +}); + module.exports = misc.arrayToObject([ htmlToDom, getTemplate, diff --git a/client/js/views/post_upload_view.js b/client/js/views/post_upload_view.js index 5ae241d..26a4329 100644 --- a/client/js/views/post_upload_view.js +++ b/client/js/views/post_upload_view.js @@ -206,6 +206,7 @@ class PostUploadView extends events.EventTarget { } _evtRemoveClick(e, uploadable) { + e.preventDefault(); this.removeUploadable(uploadable); } |