npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

dom-interceptor

v0.5.0

Published

patch DOM APIs to intercept calls to them

Downloads

8

Readme

dom interceptor Build Status Code Climate

See the NPM module.

## Background

This library is designed for use with AngularHintDom, a runtime hinting tool that depends on detecting manipulation of the DOM in AngularJS applications to warn developers about best practices. The goal of this library is to explore different ways of 'intercepting' or patching DOM APIs in order to provide this hinting.

To provide this service, the library creates a main manipulationListener that is used by AngularHintDom. This listener is the interceptor that listens for use of certain DOM APIs.

Previously this library contained other methods for patching individual element properties and using proxies that are not used by the current manipulationListener. These methods were developed as part of an exploration of how to effectively listen for DOM manipulation.

Especially, the library aims to detect the use of methods such as:

  • retrieval methods such as document.getElementById()
  • element.remove
  • element.insertBefore
  • element.appendChild

Originally, other manipulative methods like element.innerHTML and element.parentElement were also identified as goal methods for the overall manipulationListener to detect. However, detecting these DOM APIs in certain browsers requires patching of individual elements (Firefox attaches properties like .innerHTML to Element.prototype so patching get/set properties of the prototypes would be sufficient in that browser). In an earlier iteration, methods patchExistingElements() and patchElementProperties() were implemented to fill this need. However, for the best effort goal of detecting DOM manipulation, patching individual elements was deemed too heavy-handed, dangerous, and costly in terms of performance. For example, some browsers such as Safari do not allow the patching of element properties. Moreover, these patched elements do not have the same behavior as unpatched elements.

A better solution than patchExistingElements() or patchElementProperties() for providing this interception on the level of individual elements is to use proxies. In one iteration, the method patchAccess() used the harmony-reflect library to provide this service.

However, proxies are still considered experimental javascript. In Chrome for instance this javascript feature can only be enabled by setting the flag chrome://flags/#enable-javascript-harmony. Hence, these features are not used be the current manipulationListener. Instead, the manipulationListener provides a 'best-effort' detection of the majority of DOM API calls by patching functions on the prototypes of Element, Node, and Document.

## API

####addManipulationListener

#####Use as: addManipulationListener(newListener)

Add a listener - a function - that will be fired when use of DOM APIs is detected.

####Example

var domInterceptor = require('dom-interceptor');
var listenerFunction = function(message) {
  console.log(message);
};
//Will console.log the given message when manipulation is detected
domInterceptor.addManipulationListener(listenerFunction);

####Params Param | Type | Description --- | --- | --- newListener | function | A function that will be triggered when use of DOM APIs is detected

####enableLineNumbers

#####Use as: enableLineNumbers(stackTraceLocation)

Enable the listener message passed to the given listener to include the line number of the call that manipulated the DOM. A stackTraceLocation is required in order to pick a line from the stack trace that is not within the domInterceptor code.

####Example

var domInterceptor = require('dom-interceptor');
domInterceptor.enableLineNumbers(3);

####Params Param | Type | Description --- | --- | --- stackTraceLocation | number | The line of the stack trace that is of interest to the user

####patchOnePrototype

#####Use as: patchOnePrototype(type, typeName)

Patch all functions on a given type.prototype to trigger the manipulationListener when called.

####Example

var domInterceptor = require('dom-interceptor');
domInterceptor.patchOnePrototype(Document, 'Document');
//Triggers the manipulationListener
document.getElementById('foo');

####Params Param | Type | Description --- | --- | --- type| function | A function whose prototype should be patched. typeName | String | The string name of the function whose prototype should be patched

####removeManipulationListener

#####Use as: removeManipulationListener()

Remove the manipulationListener.

####Example

var domInterceptor = require('dom-interceptor');
var listenerFunction = function(message) {
  console.log(message);
};
//Will console.log the given message when manipulation is detected
domInterceptor.addManipulationListener(listenerFunction);
//triggers console.log
document.getElementById('foo');

domInterceptor.removeManipulationListener();
//does not trigger console.log
document.getElementById('foo');

####unpatchOnePrototype

#####Use as: unpatchOnePrototype(type, typeName)

Unpatch all functions on a given type.prototype that had been patched to trigger the manipulationListener.

####Example

var domInterceptor = require('dom-interceptor');
domInterceptor.patchOnePrototype(Document, 'Document');
//Triggers the manipulationListener
document.getElementById('foo');
domInterceptor.unpatchOnePrototype(Document, 'Document');
//Does not trigger the manipulationListener
document.getElementById('foo');

####Params Param | Type | Description --- | --- | --- type| function | A function whose prototype should be unpatched. typeName | String | The string name of the function whose prototype should be unpatched

License

Apache 2.0