Socket
Socket
Sign inDemoInstall

dom-mutator

Package Overview
Dependencies
0
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.3.1 to 0.3.2

4

dist/dom-mutator.cjs.development.js

@@ -283,3 +283,3 @@ 'use strict';

var newElements = new Set();
var nodes = document.body.querySelectorAll(mutation.selector);
var nodes = document.querySelectorAll(mutation.selector);
nodes.forEach(function (el) {

@@ -328,3 +328,3 @@ newElements.add(el);

refreshAllElementSets();
observer.observe(document.body, {
observer.observe(document.documentElement, {
childList: true,

@@ -331,0 +331,0 @@ subtree: true,

@@ -1,2 +0,2 @@

"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var t=/^[a-zA-Z:_][a-zA-Z0-9:_.-]*$/,e={revert:function(){}},n=new Map,r=new Set;function u(t){var e=n.get(t);return e||n.set(t,e={el:t,attributes:{}}),e}function i(t,e,n,r,u){var i=n(t),a={isDirty:!1,originalValue:i,virtualValue:i,mutations:[],el:t,observer:new MutationObserver((function(){var e=n(t);e!==a.virtualValue&&(a.originalValue=e,u(a))})),runMutations:u,setValue:r,getCurrentValue:n};return a.observer.observe(t,function(t){return"html"===t?{childList:!0,subtree:!0,attributes:!0,characterData:!0}:{childList:!1,subtree:!1,attributes:!0,attributeFilter:[t]}}(e)),a}function a(t){var e=t.originalValue;return t.mutations.forEach((function(t){return e=t.mutate(e)})),e}function s(t,e){var n=e.getCurrentValue(e.el);e.virtualValue=t,t!==n&&(e.isDirty=!0,V||(V=!0,requestAnimationFrame(k)))}function o(t){s(function(t){return v||(v=document.createElement("div")),v.innerHTML=t,v.innerHTML}(a(t)),t)}function l(t){var e=function(t,e){return e.mutations.forEach((function(e){return e.mutate(t)})),t}(new Set(t.originalValue.split(/\s+/).filter(Boolean)),t);s(Array.from(e).filter(Boolean).join(" "),t)}function c(t){s(a(t),t)}var f=function(t){return t.innerHTML},m=function(t,e){return t.innerHTML=e};function d(t){var e=u(t);return e.html||(e.html=i(t,"html",f,m,o)),e.html}var v,b=function(t,e){return e?t.className=e:t.removeAttribute("class")},h=function(t){return t.className};function p(t){var e=u(t);return e.classes||(e.classes=i(t,"class",h,b,l)),e.classes}function M(t,e){var n=u(t);return n.attributes[e]||(n.attributes[e]=i(t,e,(function(t){return t.getAttribute(e)||""}),(function(t,n){return n?t.setAttribute(e,n):t.removeAttribute(e)}),c)),n.attributes[e]}function y(t,e,r){if(r.isDirty){r.isDirty=!1;var u=r.virtualValue;r.mutations.length||function(t,e){var r,u,i=n.get(t);if(i)if("html"===e)null==(r=i.html)||null==(u=r.observer)||u.disconnect(),delete i.html;else if("class"===e){var a,s;null==(a=i.classes)||null==(s=a.observer)||s.disconnect(),delete i.classes}else{var o,l,c;null==(o=i.attributes)||null==(l=o[e])||null==(c=l.observer)||c.disconnect(),delete i.attributes[e]}}(t,e),r.setValue(t,u)}}var w,V=!1;function g(t,e){t.html&&y(e,"html",t.html),t.classes&&y(e,"class",t.classes),Object.keys(t.attributes).forEach((function(n){y(e,n,t.attributes[n])}))}function k(){V=!1,n.forEach(g)}function A(t,e){if(t.elements.delete(e),"html"===t.kind){var n=d(e),r=n.mutations.indexOf(t);-1!==r&&n.mutations.splice(r,1),n.runMutations(n)}else if("class"===t.kind){var u=p(e),i=u.mutations.indexOf(t);-1!==i&&u.mutations.splice(i,1),u.runMutations(u)}else if("attribute"===t.kind){var a=M(e,t.attribute),s=a.mutations.indexOf(t);-1!==s&&a.mutations.splice(s,1),a.runMutations(a)}}function E(t){var e=new Set(t.elements),n=new Set;document.body.querySelectorAll(t.selector).forEach((function(r){n.add(r),e.has(r)||function(t,e){if(t.elements.add(e),"html"===t.kind){var n=d(e);n.mutations.push(t),n.runMutations(n)}else if("class"===t.kind){var r=p(e);r.mutations.push(t),r.runMutations(r)}else if("attribute"===t.kind){var u=M(e,t.attribute);u.mutations.push(t),u.runMutations(u)}}(t,r)})),e.forEach((function(e){n.has(e)||A(t,e)}))}function S(){r.forEach(E)}function O(){"undefined"!=typeof document&&(w||(w=new MutationObserver((function(){S()}))),S(),w.observe(document.body,{childList:!0,subtree:!0,attributes:!1,characterData:!1}))}function x(t){return"undefined"==typeof document?e:(r.add(t),E(t),{revert:function(){var e;e=t,new Set(e.elements).forEach((function(t){A(e,t)})),e.elements.clear(),r.delete(e)}})}function L(t,e){return x({kind:"html",elements:new Set,mutate:e,selector:t})}function D(t,e){return x({kind:"class",elements:new Set,mutate:e,selector:t})}function j(n,r,u){return t.test(r)?x("class"===r||"className"===r?{kind:"class",elements:new Set,mutate:function(t){var e=u(Array.from(t).join(" "));t.clear(),e.split(/\s+/g).filter(Boolean).forEach((function(e){t.add(e)}))},selector:n}:{kind:"attribute",attribute:r,elements:new Set,mutate:u,selector:n}):e}O();var H={html:L,classes:D,attribute:j,declarative:function(t){var n=t.selector,r=t.action,u=t.value,i=t.attribute;if("html"===i){if("append"===r)return L(n,(function(t){return t+u}));if("set"===r)return L(n,(function(){return u}))}else if("class"===i){if("append"===r)return D(n,(function(t){return t.add(u)}));if("remove"===r)return D(n,(function(t){return t.delete(u)}));if("set"===r)return D(n,(function(t){t.clear(),t.add(u)}))}else{if("append"===r)return j(n,i,(function(t){return t+u}));if("set"===r)return j(n,i,(function(){return u}))}return e}};exports.connectGlobalObserver=O,exports.default=H,exports.disconnectGlobalObserver=function(){w&&w.disconnect()};
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var t=/^[a-zA-Z:_][a-zA-Z0-9:_.-]*$/,e={revert:function(){}},n=new Map,r=new Set;function u(t){var e=n.get(t);return e||n.set(t,e={el:t,attributes:{}}),e}function i(t,e,n,r,u){var i=n(t),a={isDirty:!1,originalValue:i,virtualValue:i,mutations:[],el:t,observer:new MutationObserver((function(){var e=n(t);e!==a.virtualValue&&(a.originalValue=e,u(a))})),runMutations:u,setValue:r,getCurrentValue:n};return a.observer.observe(t,function(t){return"html"===t?{childList:!0,subtree:!0,attributes:!0,characterData:!0}:{childList:!1,subtree:!1,attributes:!0,attributeFilter:[t]}}(e)),a}function a(t){var e=t.originalValue;return t.mutations.forEach((function(t){return e=t.mutate(e)})),e}function s(t,e){var n=e.getCurrentValue(e.el);e.virtualValue=t,t!==n&&(e.isDirty=!0,g||(g=!0,requestAnimationFrame(y)))}function o(t){s(function(t){return v||(v=document.createElement("div")),v.innerHTML=t,v.innerHTML}(a(t)),t)}function l(t){var e=function(t,e){return e.mutations.forEach((function(e){return e.mutate(t)})),t}(new Set(t.originalValue.split(/\s+/).filter(Boolean)),t);s(Array.from(e).filter(Boolean).join(" "),t)}function c(t){s(a(t),t)}var f=function(t){return t.innerHTML},m=function(t,e){return t.innerHTML=e};function d(t){var e=u(t);return e.html||(e.html=i(t,"html",f,m,o)),e.html}var v,b=function(t,e){return e?t.className=e:t.removeAttribute("class")},h=function(t){return t.className};function p(t){var e=u(t);return e.classes||(e.classes=i(t,"class",h,b,l)),e.classes}function M(t,e){var n=u(t);return n.attributes[e]||(n.attributes[e]=i(t,e,(function(t){return t.getAttribute(e)||""}),(function(t,n){return n?t.setAttribute(e,n):t.removeAttribute(e)}),c)),n.attributes[e]}function w(t,e,r){if(r.isDirty){r.isDirty=!1;var u=r.virtualValue;r.mutations.length||function(t,e){var r,u,i=n.get(t);if(i)if("html"===e)null==(r=i.html)||null==(u=r.observer)||u.disconnect(),delete i.html;else if("class"===e){var a,s;null==(a=i.classes)||null==(s=a.observer)||s.disconnect(),delete i.classes}else{var o,l,c;null==(o=i.attributes)||null==(l=o[e])||null==(c=l.observer)||c.disconnect(),delete i.attributes[e]}}(t,e),r.setValue(t,u)}}var V,g=!1;function k(t,e){t.html&&w(e,"html",t.html),t.classes&&w(e,"class",t.classes),Object.keys(t.attributes).forEach((function(n){w(e,n,t.attributes[n])}))}function y(){g=!1,n.forEach(k)}function E(t,e){if(t.elements.delete(e),"html"===t.kind){var n=d(e),r=n.mutations.indexOf(t);-1!==r&&n.mutations.splice(r,1),n.runMutations(n)}else if("class"===t.kind){var u=p(e),i=u.mutations.indexOf(t);-1!==i&&u.mutations.splice(i,1),u.runMutations(u)}else if("attribute"===t.kind){var a=M(e,t.attribute),s=a.mutations.indexOf(t);-1!==s&&a.mutations.splice(s,1),a.runMutations(a)}}function A(t){var e=new Set(t.elements),n=new Set;document.querySelectorAll(t.selector).forEach((function(r){n.add(r),e.has(r)||function(t,e){if(t.elements.add(e),"html"===t.kind){var n=d(e);n.mutations.push(t),n.runMutations(n)}else if("class"===t.kind){var r=p(e);r.mutations.push(t),r.runMutations(r)}else if("attribute"===t.kind){var u=M(e,t.attribute);u.mutations.push(t),u.runMutations(u)}}(t,r)})),e.forEach((function(e){n.has(e)||E(t,e)}))}function S(){r.forEach(A)}function O(){"undefined"!=typeof document&&(V||(V=new MutationObserver((function(){S()}))),S(),V.observe(document.documentElement,{childList:!0,subtree:!0,attributes:!1,characterData:!1}))}function x(t){return"undefined"==typeof document?e:(r.add(t),A(t),{revert:function(){var e;e=t,new Set(e.elements).forEach((function(t){E(e,t)})),e.elements.clear(),r.delete(e)}})}function L(t,e){return x({kind:"html",elements:new Set,mutate:e,selector:t})}function D(t,e){return x({kind:"class",elements:new Set,mutate:e,selector:t})}function j(n,r,u){return t.test(r)?x("class"===r||"className"===r?{kind:"class",elements:new Set,mutate:function(t){var e=u(Array.from(t).join(" "));t.clear(),e.split(/\s+/g).filter(Boolean).forEach((function(e){t.add(e)}))},selector:n}:{kind:"attribute",attribute:r,elements:new Set,mutate:u,selector:n}):e}O();var H={html:L,classes:D,attribute:j,declarative:function(t){var n=t.selector,r=t.action,u=t.value,i=t.attribute;if("html"===i){if("append"===r)return L(n,(function(t){return t+u}));if("set"===r)return L(n,(function(){return u}))}else if("class"===i){if("append"===r)return D(n,(function(t){return t.add(u)}));if("remove"===r)return D(n,(function(t){return t.delete(u)}));if("set"===r)return D(n,(function(t){t.clear(),t.add(u)}))}else{if("append"===r)return j(n,i,(function(t){return t+u}));if("set"===r)return j(n,i,(function(){return u}))}return e}};exports.connectGlobalObserver=O,exports.default=H,exports.disconnectGlobalObserver=function(){V&&V.disconnect()};
//# sourceMappingURL=dom-mutator.cjs.production.min.js.map

@@ -279,3 +279,3 @@ var validAttributeName = /^[a-zA-Z:_][a-zA-Z0-9:_.-]*$/;

var newElements = new Set();
var nodes = document.body.querySelectorAll(mutation.selector);
var nodes = document.querySelectorAll(mutation.selector);
nodes.forEach(function (el) {

@@ -324,3 +324,3 @@ newElements.add(el);

refreshAllElementSets();
observer.observe(document.body, {
observer.observe(document.documentElement, {
childList: true,

@@ -327,0 +327,0 @@ subtree: true,

{
"version": "0.3.1",
"version": "0.3.2",
"license": "MIT",

@@ -4,0 +4,0 @@ "main": "dist/index.js",

# DOM Mutator
Apply persistent DOM mutations on top of anything (static HTML, React, Vue, etc.)
For those times you need to apply persistent DOM changes on top of HTML you don’t control.
View demo: https://growthbook.github.io/dom-mutator/
```ts
const mutation = mutate.html("#greeting", html => html + ' world');
// works even if the selector doesn't exist yet
document.body.innerHTML += "<div id='greeting'>hello</div>";
// "hello world"
// re-applies if there's an external change
document.getElementById('greeting').innerHTML = 'hola';
// "hola world"
// Revert to the last externally set value
mutation.revert();
// "hola"
```
```ts
import mutate from "dom-mutator";

@@ -12,3 +33,3 @@

mutate.attr(".get-started", "title", (oldVal) => "This is my new title attribute");
mutate.attribute(".get-started", "title", (oldVal) => "This is my new title attribute");
```

@@ -20,75 +41,116 @@

* Super fast and light-weight (1Kb gzipped)
* Mutations will apply to elements that match the selector (even ones that don't exist yet)
* Mutations persist even if the underlying element is updated externally (e.g. by a React render)
* Persists mutations even if the underlying element is updated externally (e.g. by a React render)
* Picks up new matching elements that are added to the DOM
* Easily remove a mutation at any time
`yarn add dom-mutator` OR `npm install --save dom-mutator`.
![Build Status](https://github.com/growthbook/dom-mutator/workflows/CI/badge.svg)
## Basic Usage
## Installation
innerHTML example:
Install with npm or yarn (recommended):
```ts
`yarn add dom-mutator` OR `npm install --save dom-mutator`.
```js
import mutate from "dom-mutator";
...
```
// Mutate the innerHTML of an element
const stop = mutate.html("#greeting", html => html + ' world');
OR use with unpkg:
// works even if the selector doesn't exist yet
document.body.innerHTML += "<div id='greeting'>hello</div>";
```html
<script type="module">
import mutate from "https://unpkg.com/dom-mutator/dist/dom-mutator.esm.js";
...
</script>
```
//**** div innerHTML = "hello world" at this point!
## Usage
// mutation persists even if there is an external change
document.getElementById('greeting').innerHTML = 'hola';
There are 4 mutate methods available: `html`, `classes`, `attribute`, and `declarative`.
//**** div innerHTML = "hola world"
### html
// Stop mutating the element
stop();
Mutate an element's innerHTML
//**** div innerHTML = "hola" (the last externally set value)
```ts
// Signature
mutate.html(selector: string, (oldInnerHTML: string) => string);
// Example
mutate.html("h1", x => x.toUpperCase());
```
## Available Mutation Types
### classes
The `mutate` object has a few different methods you can call:
Mutate the set of classes for an element
- html
- classList
- attr
```ts
// Signature
mutate.classes(selector: string, (classes: Set<string>) => void);
// Example
mutate.classes("h1", (classes) => {
classes.add("green");
classes.remove("red");
});
```
### attribute
Mutate the value of an HTML element's attribute
```ts
mutate.html("h1", html => html.toUpperCase());
// Signature
mutate.attribute(selector: string, attribute: string, (oldValue: string) => string);
mutate.classList("div.greeting", classes => classes.add("new-class"));
mutate.attr(".get-started", "title", oldVal => "This is my new title attribute");
// Example
mutate.attribute(".link", "href", (href) => href + "?foo");
```
### Declarative Mutations
### declarative
If you don't need the full flexibility required by callback functions or you need to serialize the list of mutations in JSON, you can use the `declarative` method:
Mutate the html, classes, or attributes using a declarative syntax instead of callbacks.
Perfect for serialization.
```ts
// Signature
mutate.declarative({
selector: "h1",
action: "set",
attribute: "html",
value: "hello world"
selector: string,
action: "set" | "append" | "remove",
attribute: "html" | "class" | string,
value: string
});
// Examples
const mutations = [
{
selector: "h1",
action: "set",
attribute: "html",
value: "new text"
},
{
selector: ".get-started",
action: "remove",
attribute: "class",
value: "green"
},
{
selector: "a",
action: "append",
attribute: "href",
value: "?foo"
}
];
mutations.forEach(m=>mutate.declarative(m));
```
There are 3 supported "actions": `append`, `set`, and `remove`. The `remove` action can only be used with the `class` attribute.
## How it Works
When you call `mutate`, we start watching the document for elements matching the selector to appear. We do this with a single shared MutationObserver on the body.
When you create a mutation, we start watching the document for elements matching the selector to appear. We do this with a single shared MutationObserver on the body.
When a matching element is found, we attach a separate MutationObserver filtered to the exact attribute being mutated. If an external change happens (e.g. from a React render), we re-apply your mutation on top of the new baseline value.
When `stop` is called, we undo the change and go back to the last externally set value. We also disconnect the element's MutationObserver to save resources.
When `revert` is called, we undo the change and go back to the last externally set value. We also disconnect the element's MutationObserver to save resources.

@@ -95,0 +157,0 @@ ## Pausing / Resuming the Global MutationObserver

@@ -282,5 +282,4 @@ const validAttributeName = /^[a-zA-Z:_][a-zA-Z0-9:_.-]*$/;

const existingEls = new Set(mutation.elements);
const newElements: Set<Element> = new Set();
const nodes = document.body.querySelectorAll(mutation.selector);
const nodes = document.querySelectorAll(mutation.selector);
nodes.forEach(el => {

@@ -329,3 +328,3 @@ newElements.add(el);

refreshAllElementSets();
observer.observe(document.body, {
observer.observe(document.documentElement, {
childList: true,

@@ -332,0 +331,0 @@ subtree: true,

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc