Anatomy of a behaviors object

Hugh A. Cayless edited this page Jan 30, 2017 · 9 revisions
Clone this wiki locally

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": ["$@target"], "graphic": function(elt) { 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, ""); } return img; } }, ..., "add": ["`","´"], }

It contains a "handlers" object which contains either functions named for the element to be modified or arrays containing content to be inserted before and/or after the element. If an array is supplied, CETEIcean generates a function from it that will serve as a handler. Inside these functions, this will be the CETEI object. Handler functions take the element to be modified as a parameter and return an element to be appended to that parameter. They may also return nothing and simply modify the passed element, though in general we recommend "decorating" elements by modifying or adding to their content. If the element already has content, it will either be wrapped in a <span> with display:none set on it or the new content will be inserted into a Shadow DOM, so the old content will be invisible.

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 CETEIcean's rw() function, which rewrites relative URLs (because the context of the TEI source is probably different from that of the display). When a TEI <add> element is encountered, its content will be wrapped in "`" and "´" characters.

Note: If you are using the latest CETEIcean, behavior syntax has changed, and been greatly simplified. The following is an example of the way a behaviors object used to work. There is no longer any need to provide fallback methods for browsers that do not support element registration.

{
  "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);
    }, ...
  }
}