forked from cybrespace/pinafore
		
	use event delegation for better perf
This commit is contained in:
		
							parent
							
								
									08c19691a9
								
							
						
					
					
						commit
						e6304cbbf3
					
				
					 2 changed files with 68 additions and 2 deletions
				
			
		| 
						 | 
					@ -1,6 +1,9 @@
 | 
				
			||||||
<article class="status-article {{getClasses(originalStatus, timelineType, isStatusInOwnThread)}}"
 | 
					<article class="status-article {{getClasses(originalStatus, timelineType, isStatusInOwnThread)}}"
 | 
				
			||||||
         tabindex="0" on:click="onClickOrKeydown(event)" on:keydown="onClickOrKeydown(event)"
 | 
					         tabindex="0"
 | 
				
			||||||
         aria-posinset="{{index}}" aria-setsize="{{length}}"
 | 
					         delegate-click-key="{{delegateKey}}"
 | 
				
			||||||
 | 
					         delegate-keydown-key="{{delegateKey}}"
 | 
				
			||||||
 | 
					         aria-posinset="{{index}}"
 | 
				
			||||||
 | 
					         aria-setsize="{{length}}"
 | 
				
			||||||
         aria-label="Status by {{originalStatus.account.display_name || originalStatus.account.username}}"
 | 
					         aria-label="Status by {{originalStatus.account.display_name || originalStatus.account.username}}"
 | 
				
			||||||
         on:recalculateHeight>
 | 
					         on:recalculateHeight>
 | 
				
			||||||
  {{#if (notification && (notification.type === 'reblog' || notification.type === 'favourite')) || status.reblog}}
 | 
					  {{#if (notification && (notification.type === 'reblog' || notification.type === 'favourite')) || status.reblog}}
 | 
				
			||||||
| 
						 | 
					@ -87,8 +90,20 @@
 | 
				
			||||||
  import { store } from '../../_store/store'
 | 
					  import { store } from '../../_store/store'
 | 
				
			||||||
  import identity from 'lodash/identity'
 | 
					  import identity from 'lodash/identity'
 | 
				
			||||||
  import { goto } from 'sapper/runtime.js'
 | 
					  import { goto } from 'sapper/runtime.js'
 | 
				
			||||||
 | 
					  import { registerDelegate, unregisterDelegate } from '../../_utils/delegate'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  export default {
 | 
					  export default {
 | 
				
			||||||
 | 
					    oncreate() {
 | 
				
			||||||
 | 
					      let delegateKey = this.get('delegateKey')
 | 
				
			||||||
 | 
					      let onClickOrKeydown = this.onClickOrKeydown.bind(this)
 | 
				
			||||||
 | 
					      registerDelegate('click', delegateKey, onClickOrKeydown)
 | 
				
			||||||
 | 
					      registerDelegate('keydown', delegateKey, onClickOrKeydown)
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    ondestroy() {
 | 
				
			||||||
 | 
					      let delegateKey = this.get('delegateKey')
 | 
				
			||||||
 | 
					      unregisterDelegate('click', delegateKey)
 | 
				
			||||||
 | 
					      unregisterDelegate('keydown', delegateKey)
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    components: {
 | 
					    components: {
 | 
				
			||||||
      StatusSidebar,
 | 
					      StatusSidebar,
 | 
				
			||||||
      StatusHeader,
 | 
					      StatusHeader,
 | 
				
			||||||
| 
						 | 
					@ -132,6 +147,7 @@
 | 
				
			||||||
    computed: {
 | 
					    computed: {
 | 
				
			||||||
      originalStatus: (status) => status.reblog ? status.reblog : status,
 | 
					      originalStatus: (status) => status.reblog ? status.reblog : status,
 | 
				
			||||||
      statusId: (originalStatus) => originalStatus.id,
 | 
					      statusId: (originalStatus) => originalStatus.id,
 | 
				
			||||||
 | 
					      delegateKey: (statusId, timelineType, timelineValue) => `status-${timelineType}-${timelineValue}-${statusId}`,
 | 
				
			||||||
      contextualStatusId: ($currentInstance, timelineType, timelineValue, status, notification) => {
 | 
					      contextualStatusId: ($currentInstance, timelineType, timelineValue, status, notification) => {
 | 
				
			||||||
        return `${$currentInstance}/${timelineType}/${timelineValue}/${notification ? notification.id : ''}/${status.id}`
 | 
					        return `${$currentInstance}/${timelineType}/${timelineValue}/${notification ? notification.id : ''}/${status.id}`
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										50
									
								
								routes/_utils/delegate.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								routes/_utils/delegate.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,50 @@
 | 
				
			||||||
 | 
					// Delegate certain events to the global document for perf purposes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { mark, stop } from './marks'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const callbacks = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (process.browser && process.env.NODE_ENV !== 'production') {
 | 
				
			||||||
 | 
					  window.delegateCallbacks = callbacks
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function onEvent(e) {
 | 
				
			||||||
 | 
					  let { type, keyCode, target } = e
 | 
				
			||||||
 | 
					  if (!(type === 'click' || (type === 'keydown' && keyCode === 13))) {
 | 
				
			||||||
 | 
					    // we're not interested in any non-click or non-Enter events
 | 
				
			||||||
 | 
					    return
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  mark('delegate onEvent')
 | 
				
			||||||
 | 
					  let attr = `delegate-${type}-key`
 | 
				
			||||||
 | 
					  let key
 | 
				
			||||||
 | 
					  let element = target
 | 
				
			||||||
 | 
					  while (element) {
 | 
				
			||||||
 | 
					    if ((key = element.getAttribute(attr))) {
 | 
				
			||||||
 | 
					      break
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    element = element.parentElement
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (key && callbacks[type] && callbacks[type][key]) {
 | 
				
			||||||
 | 
					    callbacks[type][key](e)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  stop('delegate onEvent')
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function registerDelegate(type, key, callback) {
 | 
				
			||||||
 | 
					  mark('delegate registerDelegate')
 | 
				
			||||||
 | 
					  callbacks[type] = callbacks[type] || {}
 | 
				
			||||||
 | 
					  callbacks[type][key] = callback
 | 
				
			||||||
 | 
					  stop('delegate registerDelegate')
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function unregisterDelegate(type, key) {
 | 
				
			||||||
 | 
					  mark('delegate unregisterDelegate')
 | 
				
			||||||
 | 
					  callbacks[type] = callbacks[type] || {}
 | 
				
			||||||
 | 
					  delete callbacks[type][key]
 | 
				
			||||||
 | 
					  stop('delegate unregisterDelegate')
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (process.browser) {
 | 
				
			||||||
 | 
					  document.addEventListener('click', onEvent)
 | 
				
			||||||
 | 
					  document.addEventListener('keydown', onEvent)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue