Skip to content

Anatomy of a behaviors object

Hugh A. Cayless edited this page Aug 3, 2016 · 27 revisions

CETEIcean behaviors

Behaviors are custom styles, event handlers, and widgets to be added to your TEI elements. CETEIcean has some default behaviors built in, but you can add to or override those by supplying your own behaviors object via the addBehaviors method. A behaviors object looks like this:

{
  "handlers": {
    "ptr": ["<a href=\"$rw@target\">$@target</a>"],
    "graphic": function() {
      let ceteicean = this;
      return function() {
        let shadow = this.createShadowRoot();
        let img = new Image();
        img.src = ceteicean.rw(this.getAttribute("url"));
        if (this.hasAttribute("width")) {
          img.width = this.getAttribute("width").replace(/[^.0-9]/g, "");
        }
        if (this.hasAttribute("height")) {
          img.height = this.getAttribute("height").replace(/[^.0-9]/g, "");
        }
        shadow.appendChild(img);
      }
    }, ...,
    "add": ["`","´"],
  },
  "fallbacks": {
    "graphic": function(elt) {
      let ceteicean = this;
      let content = new Image();
      content.src = ceteicean.rw(this.getAttribute("url"));
      if (elt.hasAttribute("width")) {
        content.width = elt.getAttribute("width").replace(/[^.0-9]/g, "");
      }
      if (elt.hasAttribute("height")) {
        content.height = elt.getAttribute("height").replace(/[^.0-9]/g, "");
      }
      elt.appendChild(content);
    }, ...
  }
}

It contains two subordinate objects, "handlers", and "fallbacks"; each of these contains either functions named for the element to be modified or arrays containing content to be inserted before and/or after the element. Handlers are called for browsers which support HTML5 Custom Elements, and fallbacks for browsers that don't, so you'll typically want to have a fallback for each handler function. If an array is supplied, CETEIcean generates a function from it that will serve either as a handler or fallback, so you don't need to supply a fallback function unless you want to do something different with it. Inside these functions, this will be the CETEI object. Handler functions return a function which will be called whenever a new matching element is created. Inside that function, this is the new element, so if we want to call any CETEIcean convenience methods, like rewriteRelativeUrl(), we need to bind the outer function's this to a new var, such as ceteicean. You don't have to rely on Web Components support in your handler functions if you don't want to. If your function returns a function that takes one parameter (the element to be customized), it will run fine as both a handler and a fallback, and be used by browsers that don't have Custom Elements support too.

If a one or two element array is supplied instead of a function, the array's contents will be inserted inside the element. If the elements contain no markup, they will be wrapped in an HTML <span>. The first array member will be inserted as the first child of the element, and the second (if any) as the last. These "decorators" provide an alternative to using :before and :after selectors with content in CSS, which cannot be selected, and therefore can't be copied and pasted.

In the example above, when a TEI <ptr> element is encountered, an HTML <a href=""> element will be inserted inside it, with the @target of the ptr as both link text and @href. The @href text will be piped through CETEI's rw() function, which rewrites relative URLs. When a TEI <add> element is encountered, its content will be wrapped in "`" and "´" characters. No fallback method need be supplied for either <ptr> or <add>.

Clone this wiki locally