Repository files navigation

emitr

A simple emitter for Node.js and the browser.

Build Status

The inspirations in making this implementation were the events in backbone, and the EventEmitter in Node.js.

If we hadn't required the ability to pass context into on and off, we probably would have gone with LucidJS. Not leaking memory is difficult enough when building large applications; forcing people to keep extra objects around just so they can clean up after themselves is ugly enough that it discourages people from doing something important.

While I haven't come across this exact combination of focussed microlibrary combined with context, the only unusual feature of this Emitter (and deliberately so) is that it allows you to listen to and dispatch objects rather than just strings. Related to this is type based events, which I describe later.

Getting It

In Node.js:

npm install --save emitr

then:

varemitr=require('emitr');

For the browser, download the latest release, and refer to it from your script tag:

<scripttype="text/javascript" src="dist/emitr.js"></script>

Making an Emitter

While you can directly create a new Emitter (with new emitr(), or use standard prototypical inheritance to inherit from it, usually you will want to mix the Emitter methods in to your own classes or objects.

functionMyEmitter(){};emitr.mixInto(MyEmitter);varemitter=newMyEmitter();

Standard Emitter Features

The big three methods are provided:

on:

// Basic example:emitter.on('some-event',function(){// By default, 'this' is set to emitter inside here.// you can change that by providing a context argument.});// Example using context:functionMyObject(){}MyObject.prototype.onBoom=function(){// in this example, 'this' is set to 'obj'.};varobj=newMyObject();emitter.on('end-of-the-world',obj.onBoom,obj);

The poorly (but commonly) named off:

// clears all listeners registered on emitter.emitter.off();// clears all listeners for 'some-event'.emitter.off('some-event');// removes the listener added with// emitter.on('some-event', callback);emitter.off('some-event',callback);// removes the listener added with// emitter.on('some-event', callback, context);emitter.off('some-event',callback,context);// removes all listeners registered with a context of context.emitter.off(null,null,context);// oremitter.clearListeners(context);

trigger (sometimes called emit or fire or notify):

// All listeners registered for the 'end-of-the-world' event// will get called with alienSpacecraft as their first argument.emitters.trigger('end-of-the-world',alienSpacecraft);

once is another function that is commonly provided by Emitters:

// Once behaves similarly to .on, but the listener is only// ever called once.emitter.once('some-event',function(){// this function will only be called once.});emitter.trigger('some-event');emitter.trigger('some-event');

Extra Features

This Emitter provides two extra features.

MetaEvents

The emitter will also trigger special events that you can listen to in certain circumstances. The event emitter in node does a similar thing, firing newListener and removeListener events at the appropriate time.

There are three meta events which are:

  • emitr.meta.AddListenerEvent, triggered when a listener is added.
  • emitr.meta.RemoveListenerEvent, triggered when a listener is removed.
  • emitr.meta.DeadEvent, triggered when an event is fired but no listeners receive it.
// In this example, I use an AddListenerEvent metaevent to// create 'sticky' events behaviour for the ready event.functionDocument(){this.isReady=false;this.on(Emitter.meta.AddListenerEvent,function(addEvent){if(this.isReady){addEvent.listener.call(addEvent.context);}},this);}Emitter.mixInto(Document);Document.prototype.makeReady=function(){this.isReady=true;this.trigger('ready');};vardoc=newDocument();doc.makeReady();// Even though makeReady was called before this 'on',// the listener will still be called.doc.on('ready',function(){console.log('ready now');});

Type Based Events

The Events themselves in normal usage are usually string identifiers and then a list of arguments, almost like an algebraic data type - a tag and then a tuple of data items. In an object language like javascript, it seems more natural to dispatch event objects instead and listen for them based on their type.

functionMouseEvent(x,y){this.x=x;this.y=y;}emitter.on(MouseEvent,function(event){// in here, event is the instance of MouseEvent that// we trigger the emitter with.});emitter.trigger(newMouseEvent(100,99));

It obeys the Liskov Substitution Principle, so a listener will also get notified of events that are subclasses of the event type it is registered for.

functionClickEvent(button,x,y){MouseEvent.call(this,x,y);this.button=button;}ClickEvent.prototype=Object.create(MouseEvent.prototype);emitter.on(MouseEvent,function(event){// in here, event is the instance of ClickEvent that// we trigger the emitter with.});emitter.trigger(newClickEvent("right",101,100));

About

A simple emitter for node and the browser

Resources

Stars

5 stars

Watchers

16 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

emitr

A simple emitter for Node.js and the browser.

Build Status

The inspirations in making this implementation were the events in backbone, and the EventEmitter in Node.js.

If we hadn't required the ability to pass context into on and off, we probably would have gone with LucidJS. Not leaking memory is difficult enough when building large applications; forcing people to keep extra objects around just so they can clean up after themselves is ugly enough that it discourages people from doing something important.

While I haven't come across this exact combination of focussed microlibrary combined with context, the only unusual feature of this Emitter (and deliberately so) is that it allows you to listen to and dispatch objects rather than just strings. Related to this is type based events, which I describe later.

Getting It

In Node.js:

npm install --save emitr

then:

varemitr=require('emitr');

For the browser, download the latest release, and refer to it from your script tag:

<scripttype="text/javascript" src="dist/emitr.js"></script>

Making an Emitter

While you can directly create a new Emitter (with new emitr(), or use standard prototypical inheritance to inherit from it, usually you will want to mix the Emitter methods in to your own classes or objects.

functionMyEmitter(){};emitr.mixInto(MyEmitter);varemitter=newMyEmitter();

Standard Emitter Features

The big three methods are provided:

on:

// Basic example:emitter.on('some-event',function(){// By default, 'this' is set to emitter inside here.// you can change that by providing a context argument.});// Example using context:functionMyObject(){}MyObject.prototype.onBoom=function(){// in this example, 'this' is set to 'obj'.};varobj=newMyObject();emitter.on('end-of-the-world',obj.onBoom,obj);

The poorly (but commonly) named off:

// clears all listeners registered on emitter.emitter.off();// clears all listeners for 'some-event'.emitter.off('some-event');// removes the listener added with// emitter.on('some-event', callback);emitter.off('some-event',callback);// removes the listener added with// emitter.on('some-event', callback, context);emitter.off('some-event',callback,context);// removes all listeners registered with a context of context.emitter.off(null,null,context);// oremitter.clearListeners(context);

trigger (sometimes called emit or fire or notify):

// All listeners registered for the 'end-of-the-world' event// will get called with alienSpacecraft as their first argument.emitters.trigger('end-of-the-world',alienSpacecraft);

once is another function that is commonly provided by Emitters:

// Once behaves similarly to .on, but the listener is only// ever called once.emitter.once('some-event',function(){// this function will only be called once.});emitter.trigger('some-event');emitter.trigger('some-event');

Extra Features

This Emitter provides two extra features.

MetaEvents

The emitter will also trigger special events that you can listen to in certain circumstances. The event emitter in node does a similar thing, firing newListener and removeListener events at the appropriate time.

There are three meta events which are:

  • emitr.meta.AddListenerEvent, triggered when a listener is added.
  • emitr.meta.RemoveListenerEvent, triggered when a listener is removed.
  • emitr.meta.DeadEvent, triggered when an event is fired but no listeners receive it.
// In this example, I use an AddListenerEvent metaevent to// create 'sticky' events behaviour for the ready event.functionDocument(){this.isReady=false;this.on(Emitter.meta.AddListenerEvent,function(addEvent){if(this.isReady){addEvent.listener.call(addEvent.context);}},this);}Emitter.mixInto(Document);Document.prototype.makeReady=function(){this.isReady=true;this.trigger('ready');};vardoc=newDocument();doc.makeReady();// Even though makeReady was called before this 'on',// the listener will still be called.doc.on('ready',function(){console.log('ready now');});

Type Based Events

The Events themselves in normal usage are usually string identifiers and then a list of arguments, almost like an algebraic data type - a tag and then a tuple of data items. In an object language like javascript, it seems more natural to dispatch event objects instead and listen for them based on their type.

functionMouseEvent(x,y){this.x=x;this.y=y;}emitter.on(MouseEvent,function(event){// in here, event is the instance of MouseEvent that// we trigger the emitter with.});emitter.trigger(newMouseEvent(100,99));

It obeys the Liskov Substitution Principle, so a listener will also get notified of events that are subclasses of the event type it is registered for.

functionClickEvent(button,x,y){MouseEvent.call(this,x,y);this.button=button;}ClickEvent.prototype=Object.create(MouseEvent.prototype);emitter.on(MouseEvent,function(event){// in here, event is the instance of ClickEvent that// we trigger the emitter with.});emitter.trigger(newClickEvent("right",101,100));

About

A simple emitter for node and the browser

Resources

Stars

5 stars

Watchers

16 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

emitr

A simple emitter for Node.js and the browser.

Build Status

The inspirations in making this implementation were the events in backbone, and the EventEmitter in Node.js.

If we hadn't required the ability to pass context into on and off, we probably would have gone with LucidJS. Not leaking memory is difficult enough when building large applications; forcing people to keep extra objects around just so they can clean up after themselves is ugly enough that it discourages people from doing something important.

While I haven't come across this exact combination of focussed microlibrary combined with context, the only unusual feature of this Emitter (and deliberately so) is that it allows you to listen to and dispatch objects rather than just strings. Related to this is type based events, which I describe later.

Getting It

In Node.js:

npm install --save emitr

then:

varemitr=require('emitr');

For the browser, download the latest release, and refer to it from your script tag:

<scripttype="text/javascript" src="dist/emitr.js"></script>

Making an Emitter

While you can directly create a new Emitter (with new emitr(), or use standard prototypical inheritance to inherit from it, usually you will want to mix the Emitter methods in to your own classes or objects.

functionMyEmitter(){};emitr.mixInto(MyEmitter);varemitter=newMyEmitter();

Standard Emitter Features

The big three methods are provided:

on:

// Basic example:emitter.on('some-event',function(){// By default, 'this' is set to emitter inside here.// you can change that by providing a context argument.});// Example using context:functionMyObject(){}MyObject.prototype.onBoom=function(){// in this example, 'this' is set to 'obj'.};varobj=newMyObject();emitter.on('end-of-the-world',obj.onBoom,obj);

The poorly (but commonly) named off:

// clears all listeners registered on emitter.emitter.off();// clears all listeners for 'some-event'.emitter.off('some-event');// removes the listener added with// emitter.on('some-event', callback);emitter.off('some-event',callback);// removes the listener added with// emitter.on('some-event', callback, context);emitter.off('some-event',callback,context);// removes all listeners registered with a context of context.emitter.off(null,null,context);// oremitter.clearListeners(context);

trigger (sometimes called emit or fire or notify):

// All listeners registered for the 'end-of-the-world' event// will get called with alienSpacecraft as their first argument.emitters.trigger('end-of-the-world',alienSpacecraft);

once is another function that is commonly provided by Emitters:

// Once behaves similarly to .on, but the listener is only// ever called once.emitter.once('some-event',function(){// this function will only be called once.});emitter.trigger('some-event');emitter.trigger('some-event');

Extra Features

This Emitter provides two extra features.

MetaEvents

The emitter will also trigger special events that you can listen to in certain circumstances. The event emitter in node does a similar thing, firing newListener and removeListener events at the appropriate time.

There are three meta events which are:

  • emitr.meta.AddListenerEvent, triggered when a listener is added.
  • emitr.meta.RemoveListenerEvent, triggered when a listener is removed.
  • emitr.meta.DeadEvent, triggered when an event is fired but no listeners receive it.
// In this example, I use an AddListenerEvent metaevent to// create 'sticky' events behaviour for the ready event.functionDocument(){this.isReady=false;this.on(Emitter.meta.AddListenerEvent,function(addEvent){if(this.isReady){addEvent.listener.call(addEvent.context);}},this);}Emitter.mixInto(Document);Document.prototype.makeReady=function(){this.isReady=true;this.trigger('ready');};vardoc=newDocument();doc.makeReady();// Even though makeReady was called before this 'on',// the listener will still be called.doc.on('ready',function(){console.log('ready now');});

Type Based Events

The Events themselves in normal usage are usually string identifiers and then a list of arguments, almost like an algebraic data type - a tag and then a tuple of data items. In an object language like javascript, it seems more natural to dispatch event objects instead and listen for them based on their type.

functionMouseEvent(x,y){this.x=x;this.y=y;}emitter.on(MouseEvent,function(event){// in here, event is the instance of MouseEvent that// we trigger the emitter with.});emitter.trigger(newMouseEvent(100,99));

It obeys the Liskov Substitution Principle, so a listener will also get notified of events that are subclasses of the event type it is registered for.

functionClickEvent(button,x,y){MouseEvent.call(this,x,y);this.button=button;}ClickEvent.prototype=Object.create(MouseEvent.prototype);emitter.on(MouseEvent,function(event){// in here, event is the instance of ClickEvent that// we trigger the emitter with.});emitter.trigger(newClickEvent("right",101,100));

About

A simple emitter for node and the browser

Resources

Stars

5 stars

Watchers

16 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

emitr

A simple emitter for Node.js and the browser.

Build Status

The inspirations in making this implementation were the events in backbone, and the EventEmitter in Node.js.

If we hadn't required the ability to pass context into on and off, we probably would have gone with LucidJS. Not leaking memory is difficult enough when building large applications; forcing people to keep extra objects around just so they can clean up after themselves is ugly enough that it discourages people from doing something important.

While I haven't come across this exact combination of focussed microlibrary combined with context, the only unusual feature of this Emitter (and deliberately so) is that it allows you to listen to and dispatch objects rather than just strings. Related to this is type based events, which I describe later.

Getting It

In Node.js:

npm install --save emitr

then:

varemitr=require('emitr');

For the browser, download the latest release, and refer to it from your script tag:

<scripttype="text/javascript" src="dist/emitr.js"></script>

Making an Emitter

While you can directly create a new Emitter (with new emitr(), or use standard prototypical inheritance to inherit from it, usually you will want to mix the Emitter methods in to your own classes or objects.

functionMyEmitter(){};emitr.mixInto(MyEmitter);varemitter=newMyEmitter();

Standard Emitter Features

The big three methods are provided:

on:

// Basic example:emitter.on('some-event',function(){// By default, 'this' is set to emitter inside here.// you can change that by providing a context argument.});// Example using context:functionMyObject(){}MyObject.prototype.onBoom=function(){// in this example, 'this' is set to 'obj'.};varobj=newMyObject();emitter.on('end-of-the-world',obj.onBoom,obj);

The poorly (but commonly) named off:

// clears all listeners registered on emitter.emitter.off();// clears all listeners for 'some-event'.emitter.off('some-event');// removes the listener added with// emitter.on('some-event', callback);emitter.off('some-event',callback);// removes the listener added with// emitter.on('some-event', callback, context);emitter.off('some-event',callback,context);// removes all listeners registered with a context of context.emitter.off(null,null,context);// oremitter.clearListeners(context);

trigger (sometimes called emit or fire or notify):

// All listeners registered for the 'end-of-the-world' event// will get called with alienSpacecraft as their first argument.emitters.trigger('end-of-the-world',alienSpacecraft);

once is another function that is commonly provided by Emitters:

// Once behaves similarly to .on, but the listener is only// ever called once.emitter.once('some-event',function(){// this function will only be called once.});emitter.trigger('some-event');emitter.trigger('some-event');

Extra Features

This Emitter provides two extra features.

MetaEvents

The emitter will also trigger special events that you can listen to in certain circumstances. The event emitter in node does a similar thing, firing newListener and removeListener events at the appropriate time.

There are three meta events which are:

  • emitr.meta.AddListenerEvent, triggered when a listener is added.
  • emitr.meta.RemoveListenerEvent, triggered when a listener is removed.
  • emitr.meta.DeadEvent, triggered when an event is fired but no listeners receive it.
// In this example, I use an AddListenerEvent metaevent to// create 'sticky' events behaviour for the ready event.functionDocument(){this.isReady=false;this.on(Emitter.meta.AddListenerEvent,function(addEvent){if(this.isReady){addEvent.listener.call(addEvent.context);}},this);}Emitter.mixInto(Document);Document.prototype.makeReady=function(){this.isReady=true;this.trigger('ready');};vardoc=newDocument();doc.makeReady();// Even though makeReady was called before this 'on',// the listener will still be called.doc.on('ready',function(){console.log('ready now');});

Type Based Events

The Events themselves in normal usage are usually string identifiers and then a list of arguments, almost like an algebraic data type - a tag and then a tuple of data items. In an object language like javascript, it seems more natural to dispatch event objects instead and listen for them based on their type.

functionMouseEvent(x,y){this.x=x;this.y=y;}emitter.on(MouseEvent,function(event){// in here, event is the instance of MouseEvent that// we trigger the emitter with.});emitter.trigger(newMouseEvent(100,99));

It obeys the Liskov Substitution Principle, so a listener will also get notified of events that are subclasses of the event type it is registered for.

functionClickEvent(button,x,y){MouseEvent.call(this,x,y);this.button=button;}ClickEvent.prototype=Object.create(MouseEvent.prototype);emitter.on(MouseEvent,function(event){// in here, event is the instance of ClickEvent that// we trigger the emitter with.});emitter.trigger(newClickEvent("right",101,100));

About

A simple emitter for node and the browser

Resources

Stars

5 stars

Watchers

16 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

emitr

A simple emitter for Node.js and the browser.

Build Status

The inspirations in making this implementation were the events in backbone, and the EventEmitter in Node.js.

If we hadn't required the ability to pass context into on and off, we probably would have gone with LucidJS. Not leaking memory is difficult enough when building large applications; forcing people to keep extra objects around just so they can clean up after themselves is ugly enough that it discourages people from doing something important.

While I haven't come across this exact combination of focussed microlibrary combined with context, the only unusual feature of this Emitter (and deliberately so) is that it allows you to listen to and dispatch objects rather than just strings. Related to this is type based events, which I describe later.

Getting It

In Node.js:

npm install --save emitr

then:

varemitr=require('emitr');

For the browser, download the latest release, and refer to it from your script tag:

<scripttype="text/javascript" src="dist/emitr.js"></script>

Making an Emitter

While you can directly create a new Emitter (with new emitr(), or use standard prototypical inheritance to inherit from it, usually you will want to mix the Emitter methods in to your own classes or objects.

functionMyEmitter(){};emitr.mixInto(MyEmitter);varemitter=newMyEmitter();

Standard Emitter Features

The big three methods are provided:

on:

// Basic example:emitter.on('some-event',function(){// By default, 'this' is set to emitter inside here.// you can change that by providing a context argument.});// Example using context:functionMyObject(){}MyObject.prototype.onBoom=function(){// in this example, 'this' is set to 'obj'.};varobj=newMyObject();emitter.on('end-of-the-world',obj.onBoom,obj);

The poorly (but commonly) named off:

// clears all listeners registered on emitter.emitter.off();// clears all listeners for 'some-event'.emitter.off('some-event');// removes the listener added with// emitter.on('some-event', callback);emitter.off('some-event',callback);// removes the listener added with// emitter.on('some-event', callback, context);emitter.off('some-event',callback,context);// removes all listeners registered with a context of context.emitter.off(null,null,context);// oremitter.clearListeners(context);

trigger (sometimes called emit or fire or notify):

// All listeners registered for the 'end-of-the-world' event// will get called with alienSpacecraft as their first argument.emitters.trigger('end-of-the-world',alienSpacecraft);

once is another function that is commonly provided by Emitters:

// Once behaves similarly to .on, but the listener is only// ever called once.emitter.once('some-event',function(){// this function will only be called once.});emitter.trigger('some-event');emitter.trigger('some-event');

Extra Features

This Emitter provides two extra features.

MetaEvents

The emitter will also trigger special events that you can listen to in certain circumstances. The event emitter in node does a similar thing, firing newListener and removeListener events at the appropriate time.

There are three meta events which are:

  • emitr.meta.AddListenerEvent, triggered when a listener is added.
  • emitr.meta.RemoveListenerEvent, triggered when a listener is removed.
  • emitr.meta.DeadEvent, triggered when an event is fired but no listeners receive it.
// In this example, I use an AddListenerEvent metaevent to// create 'sticky' events behaviour for the ready event.functionDocument(){this.isReady=false;this.on(Emitter.meta.AddListenerEvent,function(addEvent){if(this.isReady){addEvent.listener.call(addEvent.context);}},this);}Emitter.mixInto(Document);Document.prototype.makeReady=function(){this.isReady=true;this.trigger('ready');};vardoc=newDocument();doc.makeReady();// Even though makeReady was called before this 'on',// the listener will still be called.doc.on('ready',function(){console.log('ready now');});

Type Based Events

The Events themselves in normal usage are usually string identifiers and then a list of arguments, almost like an algebraic data type - a tag and then a tuple of data items. In an object language like javascript, it seems more natural to dispatch event objects instead and listen for them based on their type.

functionMouseEvent(x,y){this.x=x;this.y=y;}emitter.on(MouseEvent,function(event){// in here, event is the instance of MouseEvent that// we trigger the emitter with.});emitter.trigger(newMouseEvent(100,99));

It obeys the Liskov Substitution Principle, so a listener will also get notified of events that are subclasses of the event type it is registered for.

functionClickEvent(button,x,y){MouseEvent.call(this,x,y);this.button=button;}ClickEvent.prototype=Object.create(MouseEvent.prototype);emitter.on(MouseEvent,function(event){// in here, event is the instance of ClickEvent that// we trigger the emitter with.});emitter.trigger(newClickEvent("right",101,100));

About

A simple emitter for node and the browser

Resources

Stars

5 stars

Watchers

16 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

emitr

A simple emitter for Node.js and the browser.

Build Status

The inspirations in making this implementation were the events in backbone, and the EventEmitter in Node.js.

If we hadn't required the ability to pass context into on and off, we probably would have gone with LucidJS. Not leaking memory is difficult enough when building large applications; forcing people to keep extra objects around just so they can clean up after themselves is ugly enough that it discourages people from doing something important.

While I haven't come across this exact combination of focussed microlibrary combined with context, the only unusual feature of this Emitter (and deliberately so) is that it allows you to listen to and dispatch objects rather than just strings. Related to this is type based events, which I describe later.

Getting It

In Node.js:

npm install --save emitr

then:

varemitr=require('emitr');

For the browser, download the latest release, and refer to it from your script tag:

<scripttype="text/javascript" src="dist/emitr.js"></script>

Making an Emitter

While you can directly create a new Emitter (with new emitr(), or use standard prototypical inheritance to inherit from it, usually you will want to mix the Emitter methods in to your own classes or objects.

functionMyEmitter(){};emitr.mixInto(MyEmitter);varemitter=newMyEmitter();

Standard Emitter Features

The big three methods are provided:

on:

// Basic example:emitter.on('some-event',function(){// By default, 'this' is set to emitter inside here.// you can change that by providing a context argument.});// Example using context:functionMyObject(){}MyObject.prototype.onBoom=function(){// in this example, 'this' is set to 'obj'.};varobj=newMyObject();emitter.on('end-of-the-world',obj.onBoom,obj);

The poorly (but commonly) named off:

// clears all listeners registered on emitter.emitter.off();// clears all listeners for 'some-event'.emitter.off('some-event');// removes the listener added with// emitter.on('some-event', callback);emitter.off('some-event',callback);// removes the listener added with// emitter.on('some-event', callback, context);emitter.off('some-event',callback,context);// removes all listeners registered with a context of context.emitter.off(null,null,context);// oremitter.clearListeners(context);

trigger (sometimes called emit or fire or notify):

// All listeners registered for the 'end-of-the-world' event// will get called with alienSpacecraft as their first argument.emitters.trigger('end-of-the-world',alienSpacecraft);

once is another function that is commonly provided by Emitters:

// Once behaves similarly to .on, but the listener is only// ever called once.emitter.once('some-event',function(){// this function will only be called once.});emitter.trigger('some-event');emitter.trigger('some-event');

Extra Features

This Emitter provides two extra features.

MetaEvents

The emitter will also trigger special events that you can listen to in certain circumstances. The event emitter in node does a similar thing, firing newListener and removeListener events at the appropriate time.

There are three meta events which are:

  • emitr.meta.AddListenerEvent, triggered when a listener is added.
  • emitr.meta.RemoveListenerEvent, triggered when a listener is removed.
  • emitr.meta.DeadEvent, triggered when an event is fired but no listeners receive it.
// In this example, I use an AddListenerEvent metaevent to// create 'sticky' events behaviour for the ready event.functionDocument(){this.isReady=false;this.on(Emitter.meta.AddListenerEvent,function(addEvent){if(this.isReady){addEvent.listener.call(addEvent.context);}},this);}Emitter.mixInto(Document);Document.prototype.makeReady=function(){this.isReady=true;this.trigger('ready');};vardoc=newDocument();doc.makeReady();// Even though makeReady was called before this 'on',// the listener will still be called.doc.on('ready',function(){console.log('ready now');});

Type Based Events

The Events themselves in normal usage are usually string identifiers and then a list of arguments, almost like an algebraic data type - a tag and then a tuple of data items. In an object language like javascript, it seems more natural to dispatch event objects instead and listen for them based on their type.

functionMouseEvent(x,y){this.x=x;this.y=y;}emitter.on(MouseEvent,function(event){// in here, event is the instance of MouseEvent that// we trigger the emitter with.});emitter.trigger(newMouseEvent(100,99));

It obeys the Liskov Substitution Principle, so a listener will also get notified of events that are subclasses of the event type it is registered for.

functionClickEvent(button,x,y){MouseEvent.call(this,x,y);this.button=button;}ClickEvent.prototype=Object.create(MouseEvent.prototype);emitter.on(MouseEvent,function(event){// in here, event is the instance of ClickEvent that// we trigger the emitter with.});emitter.trigger(newClickEvent("right",101,100));

About

A simple emitter for node and the browser

Resources

Stars

5 stars

Watchers

16 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

emitr

A simple emitter for Node.js and the browser.

Build Status

The inspirations in making this implementation were the events in backbone, and the EventEmitter in Node.js.

If we hadn't required the ability to pass context into on and off, we probably would have gone with LucidJS. Not leaking memory is difficult enough when building large applications; forcing people to keep extra objects around just so they can clean up after themselves is ugly enough that it discourages people from doing something important.

While I haven't come across this exact combination of focussed microlibrary combined with context, the only unusual feature of this Emitter (and deliberately so) is that it allows you to listen to and dispatch objects rather than just strings. Related to this is type based events, which I describe later.

Getting It

In Node.js:

npm install --save emitr

then:

varemitr=require('emitr');

For the browser, download the latest release, and refer to it from your script tag:

<scripttype="text/javascript" src="dist/emitr.js"></script>

Making an Emitter

While you can directly create a new Emitter (with new emitr(), or use standard prototypical inheritance to inherit from it, usually you will want to mix the Emitter methods in to your own classes or objects.

functionMyEmitter(){};emitr.mixInto(MyEmitter);varemitter=newMyEmitter();

Standard Emitter Features

The big three methods are provided:

on:

// Basic example:emitter.on('some-event',function(){// By default, 'this' is set to emitter inside here.// you can change that by providing a context argument.});// Example using context:functionMyObject(){}MyObject.prototype.onBoom=function(){// in this example, 'this' is set to 'obj'.};varobj=newMyObject();emitter.on('end-of-the-world',obj.onBoom,obj);

The poorly (but commonly) named off:

// clears all listeners registered on emitter.emitter.off();// clears all listeners for 'some-event'.emitter.off('some-event');// removes the listener added with// emitter.on('some-event', callback);emitter.off('some-event',callback);// removes the listener added with// emitter.on('some-event', callback, context);emitter.off('some-event',callback,context);// removes all listeners registered with a context of context.emitter.off(null,null,context);// oremitter.clearListeners(context);

trigger (sometimes called emit or fire or notify):

// All listeners registered for the 'end-of-the-world' event// will get called with alienSpacecraft as their first argument.emitters.trigger('end-of-the-world',alienSpacecraft);

once is another function that is commonly provided by Emitters:

// Once behaves similarly to .on, but the listener is only// ever called once.emitter.once('some-event',function(){// this function will only be called once.});emitter.trigger('some-event');emitter.trigger('some-event');

Extra Features

This Emitter provides two extra features.

MetaEvents

The emitter will also trigger special events that you can listen to in certain circumstances. The event emitter in node does a similar thing, firing newListener and removeListener events at the appropriate time.

There are three meta events which are:

  • emitr.meta.AddListenerEvent, triggered when a listener is added.
  • emitr.meta.RemoveListenerEvent, triggered when a listener is removed.
  • emitr.meta.DeadEvent, triggered when an event is fired but no listeners receive it.
// In this example, I use an AddListenerEvent metaevent to// create 'sticky' events behaviour for the ready event.functionDocument(){this.isReady=false;this.on(Emitter.meta.AddListenerEvent,function(addEvent){if(this.isReady){addEvent.listener.call(addEvent.context);}},this);}Emitter.mixInto(Document);Document.prototype.makeReady=function(){this.isReady=true;this.trigger('ready');};vardoc=newDocument();doc.makeReady();// Even though makeReady was called before this 'on',// the listener will still be called.doc.on('ready',function(){console.log('ready now');});

Type Based Events

The Events themselves in normal usage are usually string identifiers and then a list of arguments, almost like an algebraic data type - a tag and then a tuple of data items. In an object language like javascript, it seems more natural to dispatch event objects instead and listen for them based on their type.

functionMouseEvent(x,y){this.x=x;this.y=y;}emitter.on(MouseEvent,function(event){// in here, event is the instance of MouseEvent that// we trigger the emitter with.});emitter.trigger(newMouseEvent(100,99));

It obeys the Liskov Substitution Principle, so a listener will also get notified of events that are subclasses of the event type it is registered for.

functionClickEvent(button,x,y){MouseEvent.call(this,x,y);this.button=button;}ClickEvent.prototype=Object.create(MouseEvent.prototype);emitter.on(MouseEvent,function(event){// in here, event is the instance of ClickEvent that// we trigger the emitter with.});emitter.trigger(newClickEvent("right",101,100));

About

A simple emitter for node and the browser

Resources

Stars

5 stars

Watchers

16 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

emitr

A simple emitter for Node.js and the browser.

Build Status

The inspirations in making this implementation were the events in backbone, and the EventEmitter in Node.js.

If we hadn't required the ability to pass context into on and off, we probably would have gone with LucidJS. Not leaking memory is difficult enough when building large applications; forcing people to keep extra objects around just so they can clean up after themselves is ugly enough that it discourages people from doing something important.

While I haven't come across this exact combination of focussed microlibrary combined with context, the only unusual feature of this Emitter (and deliberately so) is that it allows you to listen to and dispatch objects rather than just strings. Related to this is type based events, which I describe later.

Getting It

In Node.js:

npm install --save emitr

then:

varemitr=require('emitr');

For the browser, download the latest release, and refer to it from your script tag:

<scripttype="text/javascript" src="dist/emitr.js"></script>

Making an Emitter

While you can directly create a new Emitter (with new emitr(), or use standard prototypical inheritance to inherit from it, usually you will want to mix the Emitter methods in to your own classes or objects.

functionMyEmitter(){};emitr.mixInto(MyEmitter);varemitter=newMyEmitter();

Standard Emitter Features

The big three methods are provided:

on:

// Basic example:emitter.on('some-event',function(){// By default, 'this' is set to emitter inside here.// you can change that by providing a context argument.});// Example using context:functionMyObject(){}MyObject.prototype.onBoom=function(){// in this example, 'this' is set to 'obj'.};varobj=newMyObject();emitter.on('end-of-the-world',obj.onBoom,obj);

The poorly (but commonly) named off:

// clears all listeners registered on emitter.emitter.off();// clears all listeners for 'some-event'.emitter.off('some-event');// removes the listener added with// emitter.on('some-event', callback);emitter.off('some-event',callback);// removes the listener added with// emitter.on('some-event', callback, context);emitter.off('some-event',callback,context);// removes all listeners registered with a context of context.emitter.off(null,null,context);// oremitter.clearListeners(context);

trigger (sometimes called emit or fire or notify):

// All listeners registered for the 'end-of-the-world' event// will get called with alienSpacecraft as their first argument.emitters.trigger('end-of-the-world',alienSpacecraft);

once is another function that is commonly provided by Emitters:

// Once behaves similarly to .on, but the listener is only// ever called once.emitter.once('some-event',function(){// this function will only be called once.});emitter.trigger('some-event');emitter.trigger('some-event');

Extra Features

This Emitter provides two extra features.

MetaEvents

The emitter will also trigger special events that you can listen to in certain circumstances. The event emitter in node does a similar thing, firing newListener and removeListener events at the appropriate time.

There are three meta events which are:

  • emitr.meta.AddListenerEvent, triggered when a listener is added.
  • emitr.meta.RemoveListenerEvent, triggered when a listener is removed.
  • emitr.meta.DeadEvent, triggered when an event is fired but no listeners receive it.
// In this example, I use an AddListenerEvent metaevent to// create 'sticky' events behaviour for the ready event.functionDocument(){this.isReady=false;this.on(Emitter.meta.AddListenerEvent,function(addEvent){if(this.isReady){addEvent.listener.call(addEvent.context);}},this);}Emitter.mixInto(Document);Document.prototype.makeReady=function(){this.isReady=true;this.trigger('ready');};vardoc=newDocument();doc.makeReady();// Even though makeReady was called before this 'on',// the listener will still be called.doc.on('ready',function(){console.log('ready now');});

Type Based Events

The Events themselves in normal usage are usually string identifiers and then a list of arguments, almost like an algebraic data type - a tag and then a tuple of data items. In an object language like javascript, it seems more natural to dispatch event objects instead and listen for them based on their type.

functionMouseEvent(x,y){this.x=x;this.y=y;}emitter.on(MouseEvent,function(event){// in here, event is the instance of MouseEvent that// we trigger the emitter with.});emitter.trigger(newMouseEvent(100,99));

It obeys the Liskov Substitution Principle, so a listener will also get notified of events that are subclasses of the event type it is registered for.

functionClickEvent(button,x,y){MouseEvent.call(this,x,y);this.button=button;}ClickEvent.prototype=Object.create(MouseEvent.prototype);emitter.on(MouseEvent,function(event){// in here, event is the instance of ClickEvent that// we trigger the emitter with.});emitter.trigger(newClickEvent("right",101,100));

About

A simple emitter for node and the browser

Resources

Stars

5 stars

Watchers

16 watching

Forks

Releases

Packages

Used by

Contributors

Languages