diff --git a/routes/_components/status/Status.html b/routes/_components/status/Status.html index 7d07f44a..c0f3e16e 100644 --- a/routes/_components/status/Status.html +++ b/routes/_components/status/Status.html @@ -113,8 +113,12 @@ import { goto } from 'sapper/runtime.js' import { registerClickDelegate, unregisterClickDelegate } from '../../_utils/delegate' import { classname } from '../../_utils/classname' + import { checkDomAncestors } from '../../_utils/checkDomAncestors' const INPUT_TAGS = new Set(['a', 'button', 'input', 'textarea']) + const isUserInputElement = node => INPUT_TAGS.has(node.localName) + const isToolbar = node => node.classList.contains('status-toolbar') + const isStatusArticle = node => node.classList.contains('status-article') export default { oncreate() { @@ -146,17 +150,26 @@ store: () => store, methods: { onClickOrKeydown(e) { - let { type, keyCode } = e - let { localName, parentElement } = e.target + let { type, keyCode, target } = e - if ((type === 'click' || (type === 'keydown' && keyCode === 13)) && - !INPUT_TAGS.has(localName) && - !INPUT_TAGS.has(parentElement.localName) && - !INPUT_TAGS.has(parentElement.parentElement.localName)) { - e.preventDefault() - e.stopPropagation() - goto(`/statuses/${this.get('originalStatusId')}`) + let isClick = type === 'click' + let isEnter = type === 'keydown' && keyCode === 13 + if (!isClick && !isEnter) { + return } + if (checkDomAncestors(target, isUserInputElement, isStatusArticle)) { + // this element or any ancestors up to the status-article element is + // a user input element + return + } + if (checkDomAncestors(target, isToolbar, isStatusArticle)) { + // this element or any of its ancestors is the toolbar + return + } + + e.preventDefault() + e.stopPropagation() + goto(`/statuses/${this.get('originalStatusId')}`) } }, computed: { diff --git a/routes/_utils/checkDomAncestors.js b/routes/_utils/checkDomAncestors.js new file mode 100644 index 00000000..fb54dc5c --- /dev/null +++ b/routes/_utils/checkDomAncestors.js @@ -0,0 +1,16 @@ +// Check if some condition applies for a node or any of its ancestors, +// stopping at an element that returns true for the given stopFunc. Returns +// false if none match +export function checkDomAncestors (node, checkFunc, stopFunc) { + let thisNode = node + while (thisNode) { + if (stopFunc(thisNode)) { + break + } + if (checkFunc(thisNode)) { + return true + } + thisNode = thisNode.parentElement + } + return false +}