Skip to content

tylergaw/css-typed-om

 
 

Repository files navigation

CSS Typed Object Model Polyfill

Warning

This is a fork of the original css-typed-om to continue the excellent foundation built there. It's still uncertain if we will merge this fork back into the original at some point or if it will remain a separate fork. Also note, this is heavy work-in-progress, if you use this in production, things are guaranteed to break or not work at all. See Feature Implementation Status below for details.

A polyfill for using CSS Typed OM in unsupported browsers and jsdom.

Usage

Warning

TODO: This needs to be upated for this fork. The only way to install with npm right now is via GitHub.

npm install css-typed-om

Polyfill the window object:

import polyfill from "css-typed-om";
polyfill(window);

Feature Implementation Status

This is a work in progress. We don't have 100% of the CSS Typed OM features implemented. This table breaks down the status of features. This is also a rough roadmap to a complete polyfill.

Feature Implemented Notes
StylePropertyMapReadyOnly
StylePropertyMapReadyOnly ✅ Yes
StylePropertyMapReadyOnly.size ✅ Yes
StylePropertyMapReadyOnly.entries() ✅ Yes
StylePropertyMapReadyOnly.forEach() ✅ Yes
StylePropertyMapReadyOnly.get() ✅ Yes
StylePropertyMapReadyOnly.getAll() ❌ No Not 100% sure what it's supposed to do
StylePropertyMapReadyOnly.has() ✅ Yes
StylePropertyMapReadyOnly.keys() ✅ Yes
StylePropertyMapReadyOnly.values() ✅ Yes
StylePropertyMap
StylePropertyMap ✅ Yes
StylePropertyMap.append() ❌ No
StylePropertyMap.clear() ❌ No
StylePropertyMap.delete() ❌ No
StylePropertyMap.set() ✅ Yes
StylePropertyMap.size ✅ Yes Inherited from StylePropertyMapReadOnly
StylePropertyMap.entries() ✅ Yes Inherited from StylePropertyMapReadOnly
StylePropertyMap.forEach() ✅ Yes Inherited from StylePropertyMapReadOnly
StylePropertyMap.get() ✅ Yes Inherited from StylePropertyMapReadOnly
StylePropertyMap.getAll() ❌ No Inherited from StylePropertyMapReadOnly
StylePropertyMap.has() ✅ Yes Inherited from StylePropertyMapReadOnly
StylePropertyMap.keys() ✅ Yes Inherited from StylePropertyMapReadOnly
StylePropertyMap.values() ✅ Yes Inherited from StylePropertyMapReadOnly
CSSStyleValue
CSSStyleValue ✅ Yes
CSSStyleValue.parse() ⚠️ Partially Bare minimum functionality. 🧪 Needs tests
CSSStyleValue.parseAll() ❌ No
CSSStyleValue.toString() ❌ No Stringifier to value
CSSImageValue
CSSImageValue ❌ No
CSSImageValue.parse() ❌ No Inherits from CSSStyleValue
CSSImageValue.parseAll() ❌ No Inherits from CSSStyleValue
CSSImageValue.toString() ❌ No Inherits from CSSStyleValue
CSSKeywordValue
CSSKeywordValue ✅ Yes
CSSKeywordValue() constructor ✅ Yes 🧪 Needs tests
CSSKeywordValue.value ✅ Yes 🧪 Needs tests
CSSKeywordValue.toString() ✅ Yes 🧪 Needs tests
CSSKeywordValue.parse() ❌ No Inherits from CSSStyleValue
CSSKeywordValue.parseAll() ❌ No Inherits from CSSStyleValue
CSSNumericValue
CSSNumericValue ✅ Yes
CSSNumericValue.parse() ❌ No Inherits from CSSStyleValue
CSSNumericValue.parseAll() ❌ No Inherits from CSSStyleValue
CSSNumericValue.add() ✅ Yes 🧪 Needs tests
CSSNumericValue.div() ✅ Yes 🧪 Needs tests
CSSNumericValue.equals() ❌ No
CSSNumericValue.max() ✅ Yes 🧪 Needs tests
CSSNumericValue.min() ✅ Yes 🧪 Needs tests
CSSNumericValue.mul() ✅ Yes 🧪 Needs tests
CSSNumericValue.sub() ✅ Yes 🧪 Needs tests
CSSNumericValue.to() ❌ No
CSSNumericValue.toSum() ❌ No
CSSNumericValue.type() ❌ No
CSSTransformValue
CSSTransformValue ❌ No
CSSTransformValue() constructor ❌ No
CSSTransformValue.length ❌ No
CSSTransformValue.is2D ❌ No
CSSTransformValue.toMatrix() ❌ No
CSSTransformValue.entries() ❌ No
CSSTransformValue.forEach() ❌ No
CSSTransformValue.keys() ❌ No
CSSTransformValue.values() ❌ No
CSSTransformValue.toString() ❌ No Inherits from CSSStyleValue
CSSTransformValue.parse() ❌ No Inherits from CSSStyleValue
CSSTransformValue.parseAll() ❌ No Inherits from CSSStyleValue
CSSUnparsedValue
CSSUnparsedValue ✅ Yes
CSSUnparsedValue() constructor ✅ Yes
CSSUnparsedValue.length ✅ Yes
CSSUnparsedValue.entries() ✅ Yes
CSSUnparsedValue.forEach() ✅ Yes
CSSUnparsedValue.keys() ✅ Yes
CSSUnparsedValue.values() ✅ Yes
CSSUnparsedValue.toString() ❌ No Inherits from CSSStyleValue
CSSUnitValue Inherits from CSSNumericValue, has same static and instance methods
CSSUnitValue ✅ Yes
CSSUnitValue() constructor ✅ Yes 🧪 Needs tests
CSSUnitValue.value ✅ Yes 🧪 Needs tests
CSSUnitValue.unit ✅ Yes 🧪 Needs tests
CSSUnitValue.toString() ✅ Yes 🧪 Needs tests
CSSUnitValue.parse() ❌ No Inherits from CSSStyleValue
CSSUnitValue.parseAll() ❌ No Inherits from CSSStyleValue
CSSMathValue Inherits from CSSNumericValue, has same static and instance methods
CSSMathValue ❌ No
CSSMathValue.operator ❌ No
CSSMathInvert Inherits from CSSMathValue, has same static and instance methods
CSSMathInvert ✅ Yes
CSSMathInvert() constructor ⚠️ Partially Needs exception handling. 🧪 Needs tests
CSSMathInvert.value ✅ Yes 🧪 Needs tests
CSSMathInvert.toString() ✅ Yes 🧪 Needs tests
CSSMathInvert.parse() ❌ No Inherits from CSSStyleValue
CSSMathInvert.parseAll() ❌ No Inherits from CSSStyleValue
CSSMathMax Inherits from CSSMathValue, has same static and instance methods
CSSMathMax ✅ Yes
CSSMathMax() constructor ⚠️ Partially Needs exception handling. 🧪 Needs tests
CSSMathMax.values ✅ Yes 🧪 Needs tests
CSSMathMax.toString() ✅ Yes 🧪 Needs tests
CSSMathMax.parse() ❌ No Inherits from CSSStyleValue
CSSMathMax.parseAll() ❌ No Inherits from CSSStyleValue
CSSMathMin Inherits from CSSMathValue, has same static and instance methods
CSSMathMin ✅ Yes
CSSMathMin() constructor ⚠️ Partially Needs exception handling. 🧪 Needs tests
CSSMathMin.values ✅ Yes 🧪 Needs tests
CSSMathMin.toString() ✅ Yes 🧪 Needs tests
CSSMathMin.parse() ❌ No Inherits from CSSStyleValue
CSSMathMin.parseAll() ❌ No Inherits from CSSStyleValue
CSSMathNegate Inherits from CSSMathValue, has same static and instance methods
TODO: Complete this section
CSSMathProduct Inherits from CSSMathValue, has same static and instance methods
TODO: Complete this section
CSSMathSum Inherits from CSSMathValue, has same static and instance methods
TODO: Complete this section

Warning

NOTE: Below here is still being reformated and some things need to be documented in Feature Implementation Status.

CSS Typed OM usage

// Element styles
document.body.attributeStyleMap.set("padding-top", CSS.px(42));
document.body.attributeStyleMap.get("padding-top"); /* CSSUnitValue {
  value: 42,
  unit: 'px'
}.toString() => 42px */

document.body.attributeStyleMap.set("opacity", 0.3);
typeof document.body.attributeStyleMap.get("opacity").value; // number
document.body.attributeStyleMap.get("opacity").unit; // "number"

// Stylesheet rules
document.styleSheets[0].cssRules[0].styleMap.set("padding-top", "100px");
document.styleSheets[0].cssRules[0].styleMap.get(
  "padding-top",
); /* CSSUnitValue {
  value: 100,
  unit: 'px'
}.toString() => 100px */

// Math products
CSS.px(15).add(CSS.rem(10), CSS.em(5)); /* CSSMathSum {
  operator: "sum",
  values: [
    CSSUnitValue { value: 15, unit: 'px' },
    CSSUnitValue { value: 10, unit: 'rem' },
    CSSUnitValu { value: 5, unit: 'em' }
  ]
}.toString() => calc(15px + 10rem + 5em) */

CSS.px(15).mul(CSS.rem(10), CSS.em(5)); /* CSSMathProduct {
  operator: "product",
  values: [
    CSSUnitValue { value: 15, unit: 'px' },
    CSSUnitValue { value: 10, unit: 'rem' },
    CSSUnitValu { value: 5, unit: 'em' }
  ]
}.toString() => calc(15px * 10rem * 5em) */

CSS.px(15).sub(CSS.rem(10), CSS.em(5)); /* CSSMathSum {
  operator: "sum",
  values: [
    CSSUnitValue { value: 15, unit: 'px' },
    CSSUnitValue { value: -10, unit: 'rem' },
    CSSUnitValu { value: -5, unit: 'em' }
  ]
}.toString() => calc(15px + -10rem + -5em) */

CSS.px(15).div(CSS.rem(10), CSS.em(5)); /* CSSMathProduct {
  operator: "product",
  values: [
    CSSUnitValue { value: 15, unit: 'px' },
    CSSMathInvert {
      operator: 'invert',
      value: CSSUnitValue { value: 10, unit: 'rem' }
    },
    CSSMathInvert {
      operator: 'invert',
      value: CSSUnitValue { value: 5, unit: 'em' }
    }
  ]
}.toString() => calc(15px / 10rem / 5em) */

CSS.px(15).max(CSS.rem(10), CSS.em(5)); /* CSSMathMax {
  operator: 'max',
  values: [
    CSSUnitValue { value: 15, unit: 'px' },
    CSSUnitValue { value: 10, unit: 'rem' },
    CSSUnitValu { value: 5, unit: 'em' }
  ],
}.toString() => max(15px, 10rem, 5em) */

CSS.px(15).min(CSS.rem(10), CSS.em(5)); /* CSSMathMin {
  operator: 'min',
  values: [
    CSSUnitValue { value: 15, unit: 'px' },
    CSSUnitValue { value: 10, unit: 'rem' },
    CSSUnitValu { value: 5, unit: 'em' }
  ],
}.toString() => min(15px, 10rem, 5em) */

polyfill

The polyfill function adds CSS Typed OM interfaces to window if they do not already exist:

It then adds the following functions to CSS if they do not already exist:

  • number
  • percent
  • em
  • ex
  • ch
  • rem
  • vw
  • vh
  • vmin
  • vmax
  • cm
  • mm
  • in
  • pt
  • pc
  • px
  • Q
  • deg
  • grad
  • rad
  • turn
  • s
  • ms
  • Hz
  • kHz
  • dpi
  • dpcm
  • dppx
  • fr

The new CSSUnitValue instances returned by these methods extend CSSNumericValue, which allow them to use the following methods:

  • add
  • div
  • max
  • min
  • mul
  • sub

The result of these transforms may be a new CSSUnitValue instance or a new CSSMathProduct, CSSMathMax, CSSMathMin, or CSSMathSum instance.

They all stringify back into compliant CSS.

About

A polyfill for using CSS Typed OM in unsupported browsers and jsdom.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • JavaScript 99.8%
  • Shell 0.2%