canjs / can-util

Essential utilities used by lots of CanJS's projects.
https://canjs.com/doc/can-util.html
MIT License
10 stars 8 forks source link

Package: can-dom-attribute #395

Open andrejewski opened 6 years ago

andrejewski commented 6 years ago

Goals:

Call the different properties (textContent, value, values..) in can-dom-attribute "pseudo-attributes" where these pseudo attributes are listened to via .on.

var domAttribute = require('can-dom-attribute');
var myElement = document.createElement('div');

domAttribute.get(myElement, "values");
domAttribute.set(myElement, "values", ["hello", "world"]);
domAttribute.on(myElement, "values", function () {
  // values changed
});

There is a pseudo-attribute registry that we can call into if it's a registered attribute.

var domMutate = require('can-dom-mutate');
var domMutateNode = require('can-dom-mutate/node');
var domAttribute = {
  _registry: new AttributeRegistry(),
  addAttribute (attributeDefinition, attributeName) {
    domAttribute._registery.add(attributeDefinition, attributeName);
  }, 
  get (element, attributeName) {
    var customAttribute = domAttribute._registry.get(attributeName);
    return customAttribute
      ? customAttribute.get(element, attributeName)
      : element.getAttribute(attributeName);  
  },
  set (element, attributeName, attributeValue) {
    var customAttribute = domAttribute._registry.get(attributeName);
    customAttribute
      ? customAttribute.set(element, attributeName, attributeValue)
      : domMutateNode.setAttribute.call(element, attributeName, attributeValue);
  },
  on (element, attributeName, callback) {
    var customAttribute = domAttribute._registry.get(attributeName);
    return customAttribute
      ? customAttribute.on(element, attributeName, callback)
      : domMutate.onNodeAttributeChange(element, function (event) {
        if (event.attributeName === attributeName) callback();
      });
  }
}

AttributeDefinitions fit the following shape:

interface AttributeDefinition {
  defaultAttributeName: string;
  get (element: HTMLElement, attributeName: string): any;
  set (element: HTMLElement, attributeName: string, attributeValue: string): void;
  on (element: HTMLElement, attributeName: string, callback: () => void): void;
}

@justinbmeyer @phillipskevin @chasenlehara