Code Monkey home page Code Monkey logo

sauron-style's Introduction

SauronStyle ๐Ÿ‘

JavaScript library to observe style changes on any DOM element. For an observed element, on every computed style change returns a difference object.

Works on top of window.MutationObserver and window.getComputedStyle so if your target browsers do not support these global interfaces, unfortunately, it won't help you.

โš ๏ธ Current implementation is SLOW! Don't try to use it on many elements. What is many exactly? Depends on your clients' performance, but likely it's something over 50-100 elements at once on a usual modern laptop.

Quick Browser Usage Guide

  1. Clone the repository
  2. Build the library: yarn build:prod
  3. Copy build/sauron-style.min.js to somewhere in your project
  4. Connect it with to your page: <script src="sauron-style.min.js"></script>

And observe an element you're interested in:

const sauronStyle = new SauronStyle(document.querySelector('#item'))
sauronStyle.subscribe(diff => {
  console.log(diff)
})

Assumptions and How It Works

SauronStyle watches element attribute changes, such as class and style. Apparently, any change of those might cause computed CSS changes as well. In the same way changes to parent elements can affect the styling of an observable element. Consider, for instance, class orange applied to a parent when a stylesheet has the following line:

.orange .watchedElement {
  height: 250px;
}

Without observing parent element class attribute changes we won't be able to spot such a change on .watchedElement.

Another way of affecting element representation is via external stylesheets. They could be added by inserting style or link elements into a document or removing any of them. This is also watched by SauronStyle.

Since getComputedStyle method is used, reported changes are always sent in resolved form. For example, setting transform: rotate(-2deg) for an element will cause the following difference to be reported:

{
  transform: {
    cur: "matrix(0.999391, -0.0348995, 0.0348995, 0.999391, 0, 0)",
    prev: "none"
  }
}

Another drawback of using computed style watching is that not only longhand CSS props are updated but also shorthand ones, and vice versa. For example, setting background: red will cause the following difference:

{
  background: {
    cur: "rgb(255, 255, 0) none repeat scroll 0% 0% / auto padding-box border-box",
    prev: "rgba(0, 0, 0, 0) none repeat scroll 0% 0% / auto padding-box border-box"
  },
  backgroundColor: {
    cur: "rgb(255, 255, 0)",
    prev: "rgba(0, 0, 0, 0)"
  }
}

Written above means you should use the difference with care.

โš ๏ธ Low Performance

Currently, performance is one of the strong considerations about project viability. Due to getComputedStyle usage, the library is inherently slow - on my MacBook 2013, it takes about 1-5ms to get a copy of computed styles for 1 element.

Be extremely careful when adding listeners to more than 50-100 elements!

If the library becomes used widely, I'll possibly think about implementing smarter style difference algorithms but the worst-case scenario performance will always gravitate towards asymptote, i.e. be slow.

ToDo

  • not covered cases:
    • handle transitions on parents with account for browser differences
    • pseudo-classes like :hover and :focus
  • split library into modules
  • lint
  • test it:
    • write unit tests
    • add integration tests
    • performance tests
  • set up build:
    • make it work for browsers
    • CommonJS
    • import
  • add CI (try travis?)
    • add deploy to some (free) CDN
  • promo

sauron-style's People

Contributors

oleggromov avatar

Stargazers

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

Watchers

 avatar  avatar  avatar

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.