Skip to content

Instantly share code, notes, and snippets.

@dak
Last active August 29, 2015 14:05
Show Gist options
  • Save dak/4214a2f4abdcb48af15b to your computer and use it in GitHub Desktop.
Save dak/4214a2f4abdcb48af15b to your computer and use it in GitHub Desktop.
Options for Linking to Numbered Elements

Objective

References to Tables, Figures, and other elements on a page should be named for that element. For example, the link to the 3rd figure on a page should read "Figure 3" (and that Figure should also be labeled as such).

Problem

The HTML webview uses to display content does not include the desired numbering scheme, nor does it include any metadata on the elements that can be used to divine the appropriate numbers.

Currently, webview uses CSS counters to label all the elements, relying on a pseudo element to to place the counter number for the element before it as a label.

For example:

figcaption::before {
  content: "Figure " counter(figure) ".";
}

However, all of the references to those elements are simply labeled as [link] in the HTML. Additionally, there's no way to use JavaScript to determine the content of a pseudo element or what the counter is at for a specific element, so the [link] text can not be easily replaced with the correct text to reference the element to which it links.

Note:

window.getComputedStyle(figure, ':before').content
window.getComputedStyle(figure, ':before').getPropertyCSSValue('content').cssText

only returns "'Figure ' counter(figure) '.'" rather than the computed content. It's not clear if this is correct behavior or a bug, but either way it does not currently work in any browser tested.

Solutions

Option #1 - Duplicate CSS Counter in JavaScript

Method

Have webview count the elements using an algorithm similar to what CSS's counter uses, and then replace the [link] text with the capitalized element name and the element's count.

An Alternative similar method includes using JavaScript to number both links and elements, which would require even more processing, but give slightly more flexibility and reduce the likelihood of mismatching numbers.

See: http://stackoverflow.com/questions/2651739/how-to-access-css-generated-content-with-javascript

Pros

  • Potentially allows CSS to continue to be used to number elements.
  • Flexible

Cons

  • Slow processing, as the entire DOM tree has to be crawled for each numbered element
  • Every time a numbered element is added, moved, or removed in the editor, the entire media body has to be re-rendered, or when dropping in to the editor, the page needs to be re-rendered to revert to [link] text.

Option #2 - Add metadata to elements with transform

Method

Transform the HTML being sent to webview to include data- attributes that numbers all of the elements and links in advance. [link] text should ideally also be transformed to the name of the element being linked to, such as Figure (with or without the number included).

Pros

  • Uses CSS for all numbering

Cons

  • Would require additional processing similar to option #1 after any numbered element was moved to update all the data- attributes, although could potentially be done without a full re-render to redraw the DOM more easily.

Option #3 - Use a short title instead of numbers for elements

Method

Reference "numbered" elements using a short title instead of a number and include that title in the transform for reference links and the elements themselves.

Pros

  • No additional processing required
  • Works without any additional changes in the editor
  • Figures and tables could still be numbered, but their links would reference the title

Cons

  • Non-standard method of "numbering" tables and figures
  • Potentially harder for readers to find by scanning a page since there would be no approximate reference to where to expect the element (although would be easier to search for)

Option #4 - Shadow DOM

Method

Use the Shadow DOM to implement counters and links.

See: http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/

Cons

  • Currently only supported by Chrome
  • More research required to determine if this solution is even applicable
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment