Skip to content

Commit

Permalink
perf(directives): better update mechanism
Browse files Browse the repository at this point in the history
  • Loading branch information
rstoenescu committed Jul 31, 2020
1 parent fbe228b commit 5a1e4d6
Show file tree
Hide file tree
Showing 13 changed files with 314 additions and 232 deletions.
28 changes: 19 additions & 9 deletions ui/src/directives/ClosePopup.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,24 @@ function getDepth (value) {
return isNaN(depth) ? 0 : depth
}

function destroy (el) {
const ctx = el.__qclosepopup
if (ctx !== void 0) {
el.removeEventListener('click', ctx.handler)
el.removeEventListener('keyup', ctx.handlerKey)
delete el.__qclosepopup
}
}

export default {
name: 'close-popup',

bind (el, { value }, vnode) {
if (el.__qclosepopup !== void 0) {
destroy(el)
el.__qclosepopup_destroyed = true
}

const ctx = {
depth: getDepth(value),

Expand All @@ -39,10 +53,6 @@ export default {
}
}

if (el.__qclosepopup !== void 0) {
el.__qclosepopup_old = el.__qclosepopup
}

el.__qclosepopup = ctx

el.addEventListener('click', ctx.handler)
Expand All @@ -56,11 +66,11 @@ export default {
},

unbind (el) {
const ctx = el.__qclosepopup_old || el.__qclosepopup
if (ctx !== void 0) {
el.removeEventListener('click', ctx.handler)
el.removeEventListener('keyup', ctx.handlerKey)
delete el[el.__qclosepopup_old ? '__qclosepopup_old' : '__qclosepopup']
if (el.__qclosepopup_destroyed === void 0) {
destroy(el)
}
else {
delete el.__qclosepopup_destroyed
}
}
}
41 changes: 23 additions & 18 deletions ui/src/directives/GoBack.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
import { client } from '../plugins/Platform.js'
import { isKeyCode } from '../utils/key-composition.js'

function destroy (el) {
const ctx = el.__qgoback
if (ctx !== void 0) {
el.removeEventListener('click', ctx.goBack)
el.removeEventListener('keyup', ctx.goBackKey)
delete el.__qgoback
}
}

export default {
name: 'go-back',

bind (el, { value, modifiers }, vnode) {
if (el.__qgoback !== void 0) {
destroy(el)
el.__qgoback_destroyed = true
}

const ctx = {
value,

Expand All @@ -31,35 +45,26 @@ export default {
}
}

if (el.__qgoback) {
el.__qgoback_old = el.__qgoback
}

el.__qgoback = ctx

el.addEventListener('click', ctx.goBack)
el.addEventListener('keyup', ctx.goBackKey)
},

update (el, { value, oldValue, modifiers }) {
update (el, { value, oldValue }) {
const ctx = el.__qgoback

if (ctx !== void 0) {
if (value !== oldValue) {
ctx.value = value
}

if (ctx.single !== modifiers.single) {
ctx.single = modifiers.single
}
if (ctx !== void 0 && value !== oldValue) {
ctx.value = value
}
},

unbind (el) {
const ctx = el.__qgoback_old || el.__qgoback
if (ctx !== void 0) {
el.removeEventListener('click', ctx.goBack)
el.removeEventListener('keyup', ctx.goBackKey)
delete el[el.__qgoback_old ? '__qgoback_old' : '__qgoback']
if (el.__qgoback_destroyed === void 0) {
destroy(el)
}
else {
delete el.__qgoback_destroyed
}
}
}
30 changes: 22 additions & 8 deletions ui/src/directives/Intersection.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ const defaultCfg = {
rootMargin: '0px'
}

function update (el, ctx, { modifiers, value }) {
ctx.once = modifiers.once

function update (el, ctx, value) {
let handler, cfg, changed

if (typeof value === 'function') {
Expand Down Expand Up @@ -70,16 +68,32 @@ function destroy (el) {
export default {
name: 'intersection',

inserted (el, binding) {
const ctx = {}
update(el, ctx, binding)
inserted (el, { modifiers, value }) {
if (el.__qvisible !== void 0) {
destroy(el)
el.__qvisible_destroyed = true
}

const ctx = {
once: modifiers.once === true
}

update(el, ctx, value)

el.__qvisible = ctx
},

update (el, binding) {
const ctx = el.__qvisible
ctx !== void 0 && update(el, ctx, binding)
ctx !== void 0 && update(el, ctx, binding.value)
},

unbind: destroy
unbind (el) {
if (el.__qvisible_destroyed === void 0) {
destroy(el)
}
else {
delete el.__qvisible_destroyed
}
}
}
2 changes: 1 addition & 1 deletion ui/src/directives/Morph.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ export default {
destroy(el)
}
else {
delete el.__qmorph__old
delete el.__qmorph_destroyed
}
}
}
75 changes: 38 additions & 37 deletions ui/src/directives/Mutation.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { isDeepEqual } from '../utils/is.js'

const defaultCfg = {
childList: true,
subtree: true,
Expand All @@ -9,38 +7,20 @@ const defaultCfg = {
characterDataOldValue: true
}

function update (el, ctx, { modifiers: { once, ...mod }, value }) {
let changed

ctx.once = once

if (ctx.handler !== value) {
changed = true
ctx.handler = value
}
function update (el, ctx, value) {
ctx.handler = value
ctx.observer !== void 0 && ctx.observer.disconnect()

if (ctx.opts === void 0 || isDeepEqual(mod, ctx.mod) === false) {
changed = true
ctx.mod = mod
ctx.opts = Object.keys(mod).length === 0
? defaultCfg
: mod
}

if (changed === true) {
ctx.observer !== void 0 && ctx.observer.disconnect()

ctx.observer = new MutationObserver(list => {
if (typeof ctx.handler === 'function') {
const res = ctx.handler(list)
if (res === false || ctx.once === true) {
destroy(el)
}
ctx.observer = new MutationObserver(list => {
if (typeof ctx.handler === 'function') {
const res = ctx.handler(list)
if (res === false || ctx.once === true) {
destroy(el)
}
})
}
})

ctx.observer.observe(el, ctx.opts)
}
ctx.observer.observe(el, ctx.opts)
}

function destroy (el) {
Expand All @@ -55,16 +35,37 @@ function destroy (el) {
export default {
name: 'mutation',

inserted (el, binding) {
const ctx = {}
update(el, ctx, binding)
inserted (el, { modifiers: { once, ...mod }, value }) {
if (el.__qmutation !== void 0) {
destroy(el)
el.__qmutation_destroyed = true
}

const ctx = {
once,
opts: Object.keys(mod).length === 0
? defaultCfg
: mod
}

update(el, ctx, value)

el.__qmutation = ctx
},

update (el, binding) {
update (el, { oldValue, value }) {
const ctx = el.__qmutation
ctx !== void 0 && update(el, ctx, binding)
if (ctx !== void 0 && oldValue !== value) {
update(el, ctx, value)
}
},

unbind: destroy
unbind (el) {
if (el.__qmutation_destroyed === void 0) {
destroy(el)
}
else {
delete el.__qmutation_destroyed
}
}
}
60 changes: 37 additions & 23 deletions ui/src/directives/Ripple.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,26 +61,37 @@ function showRipple (evt, el, ctx, forceCenter) {
}, 50)
}

function updateCtx (ctx, { value, modifiers, arg }) {
ctx.enabled = value !== false

if (ctx.enabled === true) {
const cfg = Object.assign({}, $q.config.ripple, modifiers, value)
ctx.modifiers = {
early: cfg.early === true,
stop: cfg.stop === true,
center: cfg.center === true,
color: cfg.color || arg,
keyCodes: [].concat(cfg.keyCodes || 13)
}
function updateModifiers (ctx, { modifiers, value, arg }) {
const cfg = Object.assign({}, $q.config.ripple, modifiers, value)
ctx.modifiers = {
early: cfg.early === true,
stop: cfg.stop === true,
center: cfg.center === true,
color: cfg.color || arg,
keyCodes: [].concat(cfg.keyCodes || 13)
}
}

function destroy (el) {
const ctx = el.__qripple
if (ctx !== void 0) {
ctx.abort.forEach(fn => { fn() })
cleanEvt(ctx, 'main')
delete el._qripple
}
}

export default {
name: 'ripple',

inserted (el, binding) {
if (el.__qripple !== void 0) {
destroy(el)
el.__qripple_destroyed = true
}

const ctx = {
enabled: binding.value !== false,
modifiers: {},
abort: [],

Expand Down Expand Up @@ -112,11 +123,7 @@ export default {
}, 300)
}

updateCtx(ctx, binding)

if (el.__qripple) {
el.__qripple_old = el.__qripple
}
updateModifiers(ctx, binding)

el.__qripple = ctx

Expand All @@ -130,15 +137,22 @@ export default {
},

update (el, binding) {
el.__qripple !== void 0 && updateCtx(el.__qripple, binding)
const ctx = el.__qripple
if (ctx !== void 0 && binding.oldValue !== binding.value) {
ctx.enabled = binding.value !== false

if (ctx.enabled === true && Object(binding.value) === binding.value) {
updateModifiers(ctx, binding)
}
}
},

unbind (el) {
const ctx = el.__qripple_old || el.__qripple
if (ctx !== void 0) {
ctx.abort.forEach(fn => { fn() })
cleanEvt(ctx, 'main')
delete el[el.__qripple_old ? '__qripple_old' : '__qripple']
if (el.__qripple_destroyed === void 0) {
destroy(el)
}
else {
delete el.__qripple_destroyed
}
}
}
Loading

0 comments on commit 5a1e4d6

Please sign in to comment.