{"id":15093133,"url":"https://github.com/angular/dom-interceptor","last_synced_at":"2025-10-06T11:31:23.905Z","repository":{"id":18110576,"uuid":"21180904","full_name":"angular/dom-interceptor","owner":"angular","description":"patch DOM APIs to intercept calls to them","archived":true,"fork":false,"pushed_at":"2014-08-05T17:57:07.000Z","size":996,"stargazers_count":9,"open_issues_count":1,"forks_count":9,"subscribers_count":10,"default_branch":"master","last_synced_at":"2024-05-09T10:10:14.733Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/angular.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-06-24T21:06:51.000Z","updated_at":"2024-02-26T17:10:20.000Z","dependencies_parsed_at":"2022-09-13T08:41:09.749Z","dependency_job_id":null,"html_url":"https://github.com/angular/dom-interceptor","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/angular%2Fdom-interceptor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/angular%2Fdom-interceptor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/angular%2Fdom-interceptor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/angular%2Fdom-interceptor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/angular","download_url":"https://codeload.github.com/angular/dom-interceptor/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219877267,"owners_count":16554853,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-09-25T11:03:47.377Z","updated_at":"2025-10-06T11:31:18.548Z","avatar_url":"https://github.com/angular.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# dom interceptor [![Build Status](https://travis-ci.org/angular/dom-interceptor.svg?branch=master)](https://travis-ci.org/angular/dom-interceptor) [![Code Climate](https://codeclimate.com/github/angular/dom-interceptor/badges/gpa.svg)](https://codeclimate.com/github/angular/dom-interceptor)\n\n  - [Background](#background)\n  - [API](#api)\n\nSee the [NPM module](https://www.npmjs.org/package/dom-interceptor).\n\n##\u003ca name=\"background\"\u003e\u003c/a\u003e Background\n\nThis library is designed for use with [AngularHintDom](https://github.com/angular/angular-hint-dom), 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\nlibrary is to explore different ways of 'intercepting' or patching `DOM` APIs in order to provide this hinting.\n\nTo 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.\n\nPreviously 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.\n\nEspecially, the library aims to detect the use of methods such as:\n  - retrieval methods such as `document.getElementById()`\n  - `element.remove`\n  - `element.insertBefore`\n  - `element.appendChild`\n\nOriginally, 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\nas Safari do not allow the patching of element properties. Moreover, these patched elements do not have the same behavior as unpatched elements.\n\nA better solution than patchExistingElements() or patchElementProperties() for providing this interception on\nthe level of individual elements is to use proxies. In one iteration, the method `patchAccess()` used the [harmony-reflect library](https://github.com/tvcutsem/harmony-reflect) to provide this service.\n\nHowever, 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\nby patching functions on the prototypes of `Element`, `Node`, and `Document`.\n\n##\u003ca name=\"api\"\u003e\u003c/a\u003e API\n\n####[addManipulationListener](https://github.com/angular/dom-interceptor/blob/master/dom-interceptor.js#L7)\n----------------\n#####Use as: addManipulationListener(newListener)\n\nAdd a `listener` - a function - that will be fired when use of DOM APIs is detected.\n\n####Example\n\n```javascript\nvar domInterceptor = require('dom-interceptor');\nvar listenerFunction = function(message) {\n  console.log(message);\n};\n//Will console.log the given message when manipulation is detected\ndomInterceptor.addManipulationListener(listenerFunction);\n```\n\n####Params\nParam | Type | Description\n---   | ---  | ---\nnewListener | function | A function that will be triggered when use of DOM APIs is detected\n\n\n####[enableLineNumbers](https://github.com/angular/dom-interceptor/blob/master/dom-interceptor.js#L38)\n----------------\n#####Use as: enableLineNumbers(stackTraceLocation)\n\nEnable the listener message passed to the given listener to include the line number of the call that\nmanipulated the DOM. A `stackTraceLocation` is required in order to pick a line from the stack\ntrace that is not within the domInterceptor code.\n\n####Example\n\n```javascript\nvar domInterceptor = require('dom-interceptor');\ndomInterceptor.enableLineNumbers(3);\n```\n\n####Params\nParam | Type | Description\n---   | ---  | ---\nstackTraceLocation | number | The line of the stack trace that is of interest to the user\n\n####[patchOnePrototype](https://github.com/angular/dom-interceptor/blob/master/dom-interceptor.js#L79)\n----------------\n#####Use as: patchOnePrototype(type, typeName)\n\nPatch all functions on a given type.prototype to trigger the manipulationListener when called.\n\n####Example\n\n```javascript\nvar domInterceptor = require('dom-interceptor');\ndomInterceptor.patchOnePrototype(Document, 'Document');\n//Triggers the manipulationListener\ndocument.getElementById('foo');\n```\n\n####Params\nParam | Type | Description\n---   | ---  | ---\ntype| function | A function whose prototype should be patched.\ntypeName | String | The string name of the function whose prototype should be patched\n\n####[removeManipulationListener](https://github.com/angular/dom-interceptor/blob/master/dom-interceptor.js#L153)\n----------------\n#####Use as: removeManipulationListener()\n\nRemove the manipulationListener.\n\n####Example\n\n```javascript\nvar domInterceptor = require('dom-interceptor');\nvar listenerFunction = function(message) {\n  console.log(message);\n};\n//Will console.log the given message when manipulation is detected\ndomInterceptor.addManipulationListener(listenerFunction);\n//triggers console.log\ndocument.getElementById('foo');\n\ndomInterceptor.removeManipulationListener();\n//does not trigger console.log\ndocument.getElementById('foo');\n```\n\n####[unpatchOnePrototype](https://github.com/angular/dom-interceptor/blob/master/dom-interceptor.js#L166)\n----------------\n#####Use as: unpatchOnePrototype(type, typeName)\n\nUnpatch all functions on a given type.prototype that had been patched to trigger the manipulationListener.\n\n####Example\n\n```javascript\nvar domInterceptor = require('dom-interceptor');\ndomInterceptor.patchOnePrototype(Document, 'Document');\n//Triggers the manipulationListener\ndocument.getElementById('foo');\ndomInterceptor.unpatchOnePrototype(Document, 'Document');\n//Does not trigger the manipulationListener\ndocument.getElementById('foo');\n```\n\n####Params\nParam | Type | Description\n---   | ---  | ---\ntype| function | A function whose prototype should be unpatched.\ntypeName | String | The string name of the function whose prototype should be unpatched\n\n## License\nApache 2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fangular%2Fdom-interceptor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fangular%2Fdom-interceptor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fangular%2Fdom-interceptor/lists"}