I'm writing some javascript that's GNOME javascript, which is more-or-less spidermonkey. Think of it as spidermonkey code that will never be run outside of spidermonkey, so no need to worry about cross-browser compatibility etc.
Basically I have a class Folks.Individual that is not subclassable, but I want to simulate subclassing it by just patching it, adding a few getters to it. (For those that are interested, it is a GObject obtained via gobject introspection and in my version of GJS you can't subclass a GObject).
Notes:
contactSys.get_individual(contactID) returns the Folks.Individual I'm patchingemail, aliasText, and online that return some values.let contact = new Contact(id);, and simply want to use contact as if it were a Folks.Individual, plus the extra properties I patch in.If the properties I wanted to patch were not dynamic, I'd just do it like so:
let contact = contactSys.get_individual(contactID);
contact.email = ....;
contact.aliasText = ....;
contact.online = ....;
I simply want a convenience function about the above such that I can call let contact = new Contact(contactID) and it will return contact with the email, aliasText and online properties patched in (as getters though).
This is how I've done it at the moment. My question is, is this the "proper" way to do it? Should I be using this instead of contact within Contact()? Should I be doing something with Folks.Individual.prototype instead and calling it a Contact?
function Contact (contactID) {
let contactSys = Shell.ContactSystem.get_default(),
contact = contactSys.get_individual(contactID); // <-- this is a Folks.Individual
contact._contactSys = contactSys;
/* these are defined as getters in case the underlying values change */
Object.defineProperty(contact, 'email', {get: function () {
return contact._contactSys.get_email_for_display(this);
}});
Object.defineProperty(contact, 'aliasText', {get: function () {
return contact.alias ||
contact.full_name ||
contact.nickname ||
contact.email ||
_("Unknown");
}});
Object.defineProperty(contact, 'online', {get: function () {
return contact.presence_type === Folks.PresenceType.AVAILABLE ||
contact.presence_type === Folks.PresenceType.AWAY ||
contact.presence_type === Folks.PresenceType.EXTENDED_AWAY ||
contact.presence_type === Folks.PresenceType.BUSY;
}});
return contact;
}
Remember - I can't subclass Folks.Individual, so I'll settle for patching instances of it with a wrapper function new Contact(contactID) so that I can treat it as if it were a subclass. I just want to know if there's a standard way of doing this.
cheers!
At the very least you can probably do 'online' a bit more succinctly and efficiently:
var ONLINE = Folks.PresenceType.AVAILABLE |
Folks.PresenceType.AWAY |
Folks.PresenceType.EXTENDED_AWAY |
Folks.PresenceType.BUSY;
Object.defineProperty(contact, 'online', {
get: function(){ return (this.presence_type & ONLINE) > 0 }
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With