Skip to main content

extracts-content.js

Path: js/extracts-content.js | Language: JavaScript | Lines: ~1,178

Content type definitions and fill functions for the extract/popup system


Overview

This module defines the content types that the extract system can display. While extracts.js provides the pop-frame infrastructure (popups/popins), this file specifies what content appears for each kind of link. Each content type is a five-element array registered into Extracts.targetTypeDefinitions:

  1. Type name (e.g., "LOCAL_PAGE")
  2. Predicate function name (e.g., "isLocalPageLink")
  3. Target classes to add (e.g., "has-content")
  4. Fill function name (e.g., "localPageForTarget")
  5. Pop-frame classes (string or function returning string)

For each type, the module provides a predicate (isXxxLink) that tests whether a link matches, a fill function (xxxForTarget) that returns a DocumentFragment with an include-link for transclusion, and optional testTarget_, preparePopup_, rewritePopFrameContent_, titleForPopFrame_, and updatePopFrame_ hooks.

The ordering of type definitions matters: types are inserted before "LOCAL_PAGE" (or "ANNOTATION_PARTIAL" for LOCAL_PAGE itself), so more specific types (annotations, videos, images) match before the generic local-page fallback.


Public API

Content Type Definitions

Each type is registered via Extracts.targetTypeDefinitions.insertBefore(...):

Type NamePredicateFill FunctionUse Case
LOCAL_PAGEisLocalPageLinklocalPageForTargetSame-site pages, anchors
AUX_LINKSisAuxLinksLinkauxLinksForTargetBacklinks, similars, bibliography
DROPCAP_INFOisDropcapInfoLinkdropcapInfoForTargetDrop-cap letter info
FOOTNOTEisFootnoteLinkfootnoteForTargetFootnote/sidenote refs
CITATION_CONTEXTisCitationContextLinkcitationContextForTargetFootnote back-links
REMOTE_IMAGEisRemoteImageLinkremoteImageForTargetExternal images
REMOTE_VIDEOisRemoteVideoLinkremoteVideoForTargetYouTube, Vimeo
CONTENT_TRANSFORMisContentTransformLinkcontentTransformForTargetTweets, Wikipedia, GitHub issues
LOCAL_VIDEOisLocalVideoLinklocalVideoForTargetSelf-hosted videos
LOCAL_AUDIOisLocalAudioLinklocalAudioForTargetSelf-hosted audio
LOCAL_IMAGEisLocalImageLinklocalImageForTargetSelf-hosted images
LOCAL_DOCUMENTisLocalDocumentLinklocalDocumentForTargetPDFs, HTML embeds
LOCAL_CODE_FILEisLocalCodeFileLinklocalCodeFileForTargetCode files
FOREIGN_SITEisForeignSiteLinkforeignSiteForTargetExternal iframes

Extracts.setUpContentLoadEventsWithin(container)

Sets up preloading for content-bearing links within container. On desktop (Popups), adds mouseenter listeners with a 25ms delay to preload content before popup spawn. On mobile (Popins), adds click listeners.

Called by: extracts.js during setup Calls: Content.load(), Content.cachedDataExists()


Internal Architecture

Type Definition Registration

All types insert themselves before "LOCAL_PAGE" in the definitions array, ensuring specific matchers (images, videos) take precedence over the generic page handler:

Extracts.targetTypeDefinitions.insertBefore([
"LOCAL_VIDEO",
"isLocalVideoLink",
"has-content",
"localVideoForTarget",
(popFrame) => ["video object", ...].join(" ")
], (def => def[0] == "LOCAL_PAGE"));

Fill Function Pattern

All fill functions follow the same pattern: synthesize an include-link with appropriate classes and return it wrapped in a DocumentFragment:

localVideoForTarget: (target) => {
return newDocument(synthesizeIncludeLink(target, {
"class": "include-caption-not include-strict include-spinner-not"
}));
}

The include-link is later processed by transclude.js to actually fetch and inject the content.

Lifecycle Hooks

For each type FOO, the following optional hooks can be defined:

HookWhen CalledPurpose
testTarget_FOOAfter predicate matchesAdditional exclusion logic
preparePopFrame_FOOBefore popup/popin spawnsModify pop-frame, return null to cancel
preparePopup_FOOBefore popup spawnsPopup-specific preparation
preparePopin_FOOBefore popin spawnsPopin-specific preparation
titleForPopFrame_FOOWhen setting titleReturns title HTML
updatePopFrame_FOOAfter content loadsAdd classes, update title
rewritePopFrameContent_FOOAfter injectionDOM manipulations
rewritePopupContent_FOOAfter injectionPopup-specific rewrites
rewritePopinContent_FOOAfter injectionPopin-specific rewrites

Key Patterns

Local Page Content Detection

isLocalPageLink distinguishes between anchor-links to the current page and links to other site pages:

isLocalPageLink: (target) => {
return (Content.contentTypes.localPage.matches(target)
&& (isAnchorLink(target) || target.pathname != location.pathname));
}

Full-Page vs. Section Display

localPageForTarget decides whether to show an entire page or just a targeted section based on:

  • Whether the link is an anchor-link
  • Whether target document is already displayed (e.g., in another popup)
  • Whether the link is from a TOC
let fullPage = !(isAnchorLink(target)
&& (target.closest(".TOC") || Extracts.targetDocument(target)));

Several types suppress popup creation when the target is already visible:

// FOOTNOTE: Don't spawn if sidenote visible
if (Notes.allNotesForCitation(target).findIndex(note =>
Popups.isVisible(note)) !== -1)
return null;

// CITATION_CONTEXT: Don't spawn if citation visible
if (targetElement && Popups.isVisible(targetElement))
return null;

Object Resizing in Popups

resizeObjectInObjectPopup() scales images/videos to fit popup constraints while optionally loosening aspect ratio limits for non-standard media:

if (options.loosenSizeConstraints) {
let popupMaxArea = popupMaxWidth * popupMaxHeight;
popupMaxWidth = Math.sqrt(popupMaxArea / (popupHeight / popupWidth));
popupMaxHeight = popupMaxWidth * (popupHeight / popupWidth);
// Clamp to window dimensions...
}

Transclude Synchronization

For local page popups, preparePopFrame_LOCAL_PAGE sets up a handler to synchronize transclusions: when a transclude fires inside a popup, the same transclude in the cached source content also fires.


Configuration

CSS Custom Properties

Used by resizeObjectInObjectPopup():

  • --GW-popups-popup-max-width — Maximum popup width
  • --GW-popups-popup-max-height — Maximum popup height
  • --GW-popups-popup-border-width — Border thickness

Constants

Extracts.contentLoadHoverDelay = 25;  // ms before preload on hover

Pop-Frame Class Functions

Several types compute their pop-frame classes dynamically:

(popFrame) => [
"footnote",
(Extracts.popFrameProvider == Popups ? "mini-title-bar" : "no-footer-bar")
].join(" ")

Integration Points

Dependencies

  • Content.contentTypes.* — Type matchers (localPage.matches(), etc.)
  • Content.load() / Content.cachedDataExists() — Content fetching
  • Content.referenceDataForLink() — Metadata retrieval
  • Transclude.fillTemplateNamed() — Title templating
  • AuxLinks.auxLinksLinkType() — Aux-link type detection
  • Notes.noteNumber() / Notes.allNotesForCitation() — Footnote utilities
  • Popups.isVisible() — Visibility checks
  • synthesizeIncludeLink() — Creates transclusion links
  • newDocument() — DocumentFragment wrapper

Events Listened

  • GW.contentDidInject — Triggers transclude sync in source content
  • Popups.popupWillDespawn / Popins.popinWillDespawn — Cleanup handlers

Events Fired

None directly; relies on events from extracts.js and transclude.js.

Shared State

  • Extracts.targetTypeDefinitions — Registry of content types
  • Extracts.popFrameProvider — Either Popups or Popins
  • Extracts.rootDocument — Root document reference

See Also