Plugins¶
The components that lab.js
provides differ with regard to their behavior during a study – some might be responsable for presenting information to participants, others might be in charge of the overall study flow.
It is, however, sometimes desirable to provide functionality that can be combined with any type of component, regardless of the specific type and stimulus modality it represents. This is what plugins are for.
Overview and motivation¶
Plugins hook into any component, and are then notified of events on that component. They are then free to react to each of these events in any way.
For example, it might be helpful to create a plugin that ensures that part of the study is presented in fullscreen mode – part being be a single html.Screen()
or html.Form()
, or a larger chunk of the experiment, as represented by a flow.Sequence()
or flow.Loop()
. In each case, such a plugin would ensure that the fullscreen mode is entered at the beginning of its activity, that the standard display is restored afterwards, and it would respond gracefully if the user exits the fullscreen view.
The advantage of this setup is that similar functionality (in this case, fullscreen handling) need not be implemented anew with every component. It thereby reduces the need for specialized components that cover any possible combination of functionality, such as a (hypothetical) flow.FullscreenSequence
or the like. Similarly, plugins can be used to pull out functionality that is not universally used, and would add complexity to the core.Component()
. Thus, plugins serve to reduce the bulk of the library code, and offer a flexible method of implementing custom functionality with the existing components.
Usage¶
Any number of plugins can be added to a component upon initialization via the plugins
option:
const c = new lab.core.Component({
plugins: [
new lab.plugins.Logger(),
]
})
After construction, plugins can be added using the commands c.plugins.add()
and c.plugins.remove()
.
Caution
This API (plugin addition and removal after construction) is tentative and may change as the library evolves.
Built-in plugins¶
-
class
plugins.
Logger
([options])¶ This basic plugin outputs any events triggered on a specific component to the browser console. It accepts a single option, a
title
that is output with every debug message.
-
class
plugins.
Debug
()¶ This plugin provides a debug overlay for any study, specifically a real-time view of the study state and the collected data. It is added in the builder preview to provide a means of checking the data.
-
class
plugins.
Metadata
()¶ Collects technical metadata regarding the user’s browser and saves it in the
meta
column. The data isJSON
-encoded and contains the following keys:location
:URL
under which the study was accesseduserAgent
: Browser identificationplatform
: Operating system, if provided by the browserlanguage
: Browser language preferences, e.g.en-US
locale
: Active browser locale, e.g.en-UK
timeZone
: User time zone, e.g.Europe/Berlin
timezoneOffset
: Offset from local time toUTC
, in minutes, e.g.-60
screen_width
andscreen_height
: Monitor resolutionscroll_width
andscroll_height
: Size of the window content (in pixels)window_innerWidth
andwindow_innerHeight
: Size of the browser viewport, that is, the portion of the page that is visibledevicePixelRatio
: Scaling factor that maps virtual onto physical pixels, for example on high-resolution screens or when the page zoom level is changed. This affects most of the screen measurements reported above, which are in virtual pixels. To convert to physical pixels, multiply the values by this scaling ratio.
-
class
plugins.
Transmit
([options])¶ Transmits collected data over the course of the study. Whenever new data are
committed
, all changed columns aretransmit()
to aurl
supplied in the options (required), along with anymetadata
, which can be specified in the options as an object (optionally). At theend()
of the component, the entire dataset is saved in the same way.
User-defined plugins¶
Users can define their own plugins to provide custom functionality. Plugins are JavaScript objects that are defined by one commonality only: They provide a handle
method that his called whenever an event is triggered on the associated component. The method receives two parameters, the context
which represents the component on which the event was triggered, and the event
, a string representing the type of event (e.g. prepare
, run
etc.).
In addition to the component event, the handle method will be called with the plugin:init
event when the plugin is added to the component, and plugin:removal
when the plugin is removed. It is the responsability of the plug-in to take care of all intervening coordination with the document and the linked component.
As an example, consider the plugins.Logger()
, shown here in its entirety:
class Logger {
constructor(options) {
this.title = options.title
}
handle(context, event) {
console.log(`Component ${ this.title } received ${ event }`)
}
}
Caution
As with the above API, some details of the custom plugin messages might be subject to changes. In particular, the plugin:removal
event might be renamed.