-
Notifications
You must be signed in to change notification settings - Fork 918
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor(BaseClass): reduces amount of created objects/functions #1613
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,181 +1,130 @@ | ||
var VARS_FIELD = typeof Symbol === 'undefined' ? '__vars' + Date.now() : Symbol.for('vars'); | ||
var SUBSCRIPTIONS_FIELD = typeof Symbol === 'undefined' ? '__subs' + Date.now() : Symbol.for('subscriptions'); | ||
|
||
var _globalListeners = {}; | ||
function BaseClass() { | ||
this[VARS_FIELD] = {}; | ||
this[SUBSCRIPTIONS_FIELD] = {}; | ||
this.errorHandler = this.errorHandler.bind(this); | ||
|
||
function globalEventListener(e) { | ||
var eventName = e.type; | ||
if (!_globalListeners[eventName]) { | ||
return; | ||
} | ||
|
||
var hashCode = e.myself.hashCode; | ||
if (!hashCode || !_globalListeners[eventName][hashCode]) { | ||
return; | ||
} | ||
var callbacks = _globalListeners[eventName][hashCode]; | ||
for (var i = 0; i < callbacks.length; i++) { | ||
callbacks[i].listener(e); | ||
} | ||
Object.defineProperty(this, 'hashCode', { value: Math.floor(Date.now() * Math.random()) }) | ||
} | ||
|
||
var BaseClass = function() { | ||
var self = this; | ||
var _vars = {}; | ||
BaseClass.prototype = { | ||
empty: function() { | ||
var vars = this[VARS_FIELD]; | ||
|
||
var hashCode = Math.floor(Date.now() * Math.random()); | ||
Object.keys(vars).forEach(function(name) { | ||
vars[name] = null; | ||
}); | ||
}, | ||
|
||
get: function(key) { | ||
return this[VARS_FIELD].hasOwnProperty(key) ? this[VARS_FIELD][key] : null; | ||
}, | ||
|
||
set: function(key, value, noNotify) { | ||
var prev = this.get(key); | ||
|
||
this[VARS_FIELD][key] = value; | ||
|
||
Object.defineProperty(self, "hashCode", { | ||
value: hashCode, | ||
writable: false | ||
}); | ||
self.empty = function() { | ||
for (var key in Object.keys(_vars)) { | ||
_vars[key] = null; | ||
delete _vars[key]; | ||
} | ||
}; | ||
|
||
self.get = function(key) { | ||
return key in _vars ? _vars[key] : null; | ||
}; | ||
self.set = function(key, value, noNotify) { | ||
var prev = _vars[key]; | ||
_vars[key] = value; | ||
if (!noNotify && prev !== value) { | ||
self.trigger(key + "_changed", prev, value); | ||
this.trigger(key + '_changed', prev, value); | ||
} | ||
}; | ||
self.bindTo = function(key, target, targetKey, noNotify) { | ||
targetKey = targetKey === undefined || targetKey === null ? key : targetKey; | ||
self.on(key + "_changed", function(prevValue, newValue) { | ||
target.set(targetKey, newValue, noNotify === true); | ||
|
||
return this; | ||
}, | ||
|
||
bindTo: function(key, target, targetKey, noNotify) { | ||
var targetKey = targetKey || key; | ||
|
||
this.on(key + '_changed', function(oldValue, value) { | ||
target.set(targetKey, value, noNotify); | ||
}); | ||
}; | ||
}, | ||
|
||
self.trigger = function(eventName) { | ||
if (!eventName || !_globalListeners[eventName] || !_globalListeners[eventName][hashCode]) { | ||
return; | ||
trigger: function(eventName) { | ||
if (!eventName || !this[SUBSCRIPTIONS_FIELD][eventName]) { | ||
return this; | ||
} | ||
|
||
var args = []; | ||
for (var i = 1; i < arguments.length; i++) { | ||
args.push(arguments[i]); | ||
} | ||
var event = document.createEvent('Event'); | ||
event.initEvent(eventName, false, false); | ||
event.mydata = args; | ||
event.myself = self; | ||
|
||
var callbacks = _globalListeners[eventName][hashCode]; | ||
for (var i = 0; i < callbacks.length; i++) { | ||
callbacks[i].listener(event); | ||
} | ||
}; | ||
self.on = function(eventName, callback) { | ||
if (!eventName || !callback || typeof callback !== "function") { | ||
return; | ||
var listeners = this[SUBSCRIPTIONS_FIELD][eventName]; | ||
var i = listeners.length; | ||
var args = Array.prototype.slice.call(arguments, 1); | ||
|
||
while (i--) { | ||
listeners[i].apply(this, args); | ||
} | ||
|
||
_globalListeners[eventName] = _globalListeners[eventName] || {}; | ||
return this; | ||
}, | ||
|
||
var listener = function(e) { | ||
if (!e.myself || e.myself !== self) { | ||
return; | ||
} | ||
var evt = Object.create(e); | ||
var mydata = evt.mydata; | ||
delete evt.mydata; | ||
delete evt.myself; | ||
self.event = evt; | ||
callback.apply(self, mydata); | ||
on: function(eventName, listener) { | ||
this[SUBSCRIPTIONS_FIELD][eventName] = this[SUBSCRIPTIONS_FIELD][eventName] || []; | ||
var topic = this[SUBSCRIPTIONS_FIELD][eventName]; | ||
var index = topic.push(listener); | ||
var self = this; | ||
|
||
return function() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you tell me why do you return this function?
I think this is not common way... map.on(plugin.google.maps.event.MAP_READY, onMapReady)(); |
||
self.off(eventName, listener); | ||
}; | ||
if (!(hashCode in _globalListeners[eventName])) { | ||
document.addEventListener(eventName, globalEventListener, false); | ||
_globalListeners[eventName][hashCode] = []; | ||
} | ||
_globalListeners[eventName][hashCode].push({ | ||
'callback': callback, | ||
'listener': listener | ||
}); | ||
}; | ||
self.addEventListener = self.on; | ||
|
||
self.off = function(eventName, callback) { | ||
var i, j, callbacks; | ||
if (typeof eventName === "string") { | ||
if (eventName in _globalListeners) { | ||
|
||
if (typeof callback === "function") { | ||
callbacks = _globalListeners[eventName][hashCode] ||[]; | ||
for (i = 0; i < callbacks.length; i++) { | ||
if (callbacks[i].callback === callback) { | ||
callbacks.splice(i, 1); | ||
break; | ||
} | ||
} | ||
if (callbacks.length === 0) { | ||
delete _globalListeners[eventName][hashCode]; | ||
} | ||
} else { | ||
delete _globalListeners[eventName][hashCode]; | ||
} | ||
if (Object.keys(_globalListeners[eventName]) === 0) { | ||
document.removeEventListener(eventName, globalEventListener); | ||
} | ||
} | ||
} else { | ||
//Remove all event listeners | ||
var eventNames = Object.keys(_globalListeners); | ||
for (j = 0; j < eventNames.length; j++) { | ||
eventName = eventNames[j]; | ||
delete _globalListeners[eventName][hashCode]; | ||
if (Object.keys(_globalListeners[eventName]) === 0) { | ||
document.removeEventListener(eventName, globalEventListener); | ||
} | ||
}, | ||
|
||
off: function(eventName, listener) { | ||
if (!eventName && !listener) { | ||
this[SUBSCRIPTIONS_FIELD] = {}; | ||
} else if (eventName && !listener) { | ||
this[SUBSCRIPTIONS_FIELD][eventName] = null; | ||
} else if (this[SUBSCRIPTIONS_FIELD][eventName]) { | ||
var index = this[SUBSCRIPTIONS_FIELD][eventName].indexOf(listener); | ||
|
||
if (index !== -1) { | ||
this[SUBSCRIPTIONS_FIELD][eventName].splice(index, 1); | ||
} | ||
} | ||
}; | ||
|
||
self.removeEventListener = self.off; | ||
|
||
return this; | ||
}, | ||
|
||
self.one = function(eventName, callback) { | ||
one: function(eventName, listener) { | ||
var unlisten = this.on(eventName, function() { | ||
unlisten(); | ||
listener.apply(this, arguments); | ||
}); | ||
|
||
var listener = function(e) { | ||
if (!e.myself || e.myself !== self) { | ||
return; | ||
} | ||
var evt = Object.create(e); | ||
var mydata = evt.mydata; | ||
delete evt.mydata; | ||
delete evt.myself; | ||
self.event = evt; | ||
callback.apply(self, mydata); | ||
self.off(eventName, callback); | ||
}; | ||
return this; | ||
}, | ||
|
||
_globalListeners[eventName] = _globalListeners[eventName] || {}; | ||
destroy: function() { | ||
this.off(); | ||
this.empty(); | ||
}, | ||
|
||
if (!(hashCode in _globalListeners[eventName])) { | ||
document.addEventListener(eventName, globalEventListener, false); | ||
_globalListeners[eventName][hashCode] = []; | ||
errorHandler: function(error) { | ||
if (error) { | ||
console.log(error); | ||
this.trigger('error', error instanceof Error ? error : createError(error)); | ||
} | ||
_globalListeners[eventName][hashCode].push({ | ||
'callback': callback, | ||
'listener': listener | ||
}); | ||
}; | ||
self.addEventListenerOnce = self.one; | ||
|
||
self.errorHandler = function(msg) { | ||
if (msg) { | ||
console.log(msg); | ||
self.trigger('error', msg); | ||
} | ||
return false; | ||
}; | ||
|
||
return self; | ||
} | ||
}; | ||
|
||
BaseClass.prototype.addEventListener = BaseClass.prototype.on; | ||
BaseClass.prototype.addEventListenerOnce = BaseClass.prototype.one; | ||
BaseClass.prototype.removeEventListener = BaseClass.prototype.off; | ||
|
||
function createError(message, methodName, args) { | ||
var error = new Error(methodName ? [ | ||
'Got error with message: "', message, '" ', | ||
'after calling "', methodName, '"' | ||
].join('') : message); | ||
|
||
Object.defineProperties(error, { | ||
methodName: { value: methodName }, | ||
args: { value: args } | ||
}); | ||
|
||
return error; | ||
} | ||
|
||
module.exports = BaseClass; |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be
return this[VARS_FIELD].hasOwnProperty(key) ? this[VARS_FIELD][key] : undefined
.The null === undefined always false.