Code Monkey home page Code Monkey logo

dom-mutator's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Forkers

osandvik bttf

dom-mutator's Issues

Options to turn off persistence features

There are 2 persistence features when calling mutate:

  1. Apply to future elements
  2. Re-apply when the element is changed externally

Both of these have a performance cost and should have options to disable on a case-by-case basis.

Infinite loop when appendHTML is given invalid HTML

mutate("div", "appendHTML", "<b>foo");

When a mutation comes in, we compare the actual HTML to the desired HTML to see if we need to re-apply the mutation. When setting innerHTML, the browser transforms the string passed in to valid HTML (e.g. <b>foo becomes <b>foo</b>). So this comparison check always fails and we always append to the end, which in turn causes another mutation and an infinite loop of appending.

A possible fix is to first set innerHTML on a temporary detached element and then read it back out to get the transformed HTML.

Reverting and re-applying the same mutation quickly does not work

document.body.innerHTML = '<div>foo</div>';
const revert = mutate('div', 'addClass', 'hello');
await sleep();

revert();
mutate('div', 'addClass', 'hello');
await sleep();

// The below fails, it actually equals `<div>foo</div>`
expect(document.body.innerHTML).toEqual('<div class="hello">foo</div>');

Optimize performance for single-element selectors

If you call mutate("#myid", ...), once a matching element is found, we can stop waiting for new elements to appear, since ids are unique on a page.

  • [^,]*#id - id match (with optional narrowing prefix)
  • body or html - specific elements that can only exist once on a page

We can also add an optional 4th argument to mutate with config options, one of which explicitly says to only match the first element found.

Infinite loop when 2 mutations affect the same element

Currently, there's an infinite loop when 2 mutations affect the same attribute of the same element. This only affects mutation types setAttribute, appendHTML, and setHTML.

Examples:

// Can break even with different selectors and mutation types
mutate('p', 'setHTML', 'foo');
mutate('p.myclass', 'appendHTML', 'bar');

// setAttribute can also conflict with addClass and removeClass
mutate('p', 'addClass', 'foo');
mutate('p', 'setAttribute', 'class="bar"');

The mutations don't necessarily have to have the same selector either, one could target div another could target .class and they both could reference the same element.

One solution is to keep a Map of Element to attribute handler. If a new mutation affects the same attribute as an existing mutation, revert the old mutation first.

Reverting setHTML does not restore original DOM nodes

We store the original innerHTML to revert, but this creates new DOM nodes instead of reverting to the old ones. This breaks things like React that are using element references and also breaks event listeners.

Instead, we can store the original children nodes and restore them

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.