0.1.26 • Published 1 year ago

@charles-evolv/catalyst-dev v0.1.26

Weekly downloads
-
License
ISC
Repository
github
Last release
1 year ago

Catalyst

A library to streamline writing Evolv AI experiments

Goals

The goals for this framework are to provide the following:

  1. Maintain classes and references to elements that persist through mutations.
  2. Handle idemponency.
  3. Sandbox experiments to prevent namespace collisions.
  4. Queue functions to run in response to SPA changes or mutations.
  5. Experiment specific setTimeout and setInterval calls that handle SPA navigation automatically.
  6. Simplify coding and support declarative where possible.
  7. Allow simple experiments to remain simple and support more complex tests (model view rendering)
  8. Simplify things like Mutation Observer.

Installation

Add the NPM integration connector @evolv-delivery/catalyst.

Setup

Add the following json config at environment level to enable the framework across a site

{
    "pages": ["/"]
}

renderRule

Deprecated as of 0.6.0, use catalyst instead


catalyst

The core Catalyst object containing sandboxes, selectors, instrumentation, global mutation observer, as well as the store and app repositories for assets and functions that can be shared between variants.

Adding a new property to the catalyst object creates a new sandbox allowing for multiple experiments to run on the page simultaneously without collisions.

New syntax provides a different selector for a single element $ vs. a group of elements $$. The $$ selector used for instrument items prior to 0.6.0 has been renamed to $i. For this to work the following should appear at the top the context and each variant so that they all are working within the same sandbox.

var rule = evolv.catalyst.experiment_name;
var store = rule.store;
var $ = rule.select;
var $$ = rule.selectAll;
var $i = rule.selectInstrument;
var log = rule.log;

rule.log(), rule.warn(), rule.debug()

New in 0.6.0 - Safe and enhanced logging to the console. Uses console.info or console.warn under the hood due to VBG restricting console.log, adding the following features:

  • Automatically silenced in production so logging can be built into experiment code and revealed by setting the log level in local storage.
  • Prefixing with [evolv-sandbox] to distinguish logs from multiple simultaneous experiments.
  • Optional log color to visually distinguish Catalyst logs from the host site.
SyntaxDescriptionNotes
log(<arguments>)Strings or variables separated by commas, displayed at log level normal and debuglog('heading:', heading)Added in 0.6.0
warn(<arguments>)Strings or variables separated by commas, displayed at log level normal and debugwarn('Selector not found', selector)Added in 0.6.0
debug(<arguments>)Strings or variables separated by commas, displayed at log level debugdebug('Selector found after', then - performance.now(), 'ms')Added in 0.6.0

Log levels are set in two locations, a default for the environment and a local storage key. Log levels can be overridden in experiment code though it is not recommended as overrides in experiment code will not be silenced in production.

VCG

Environment NameEnvironment IdDefault log level
Productionb02d16aa80silent
Stagingadd8459f1cnormal
Development55e68a2ba9normal
Prototypeeee20e49aenormal
verizon qab5d276c11bnormal

VBG

Environment NameEnvironment IdDefault log level
Production13d2e2d4fbsilent
QA Testing4271e3bfc8normal
UAT6bfb40849enormal

Local Storage Options

The key evolv:catalyst-logs can be set to silent, normal, or debug with an optional color flag.

keyvaluedescription
evolv:catalyst-logssilentSilences all logs
normalDisplays log and warn messages
debugDisplays log, warn, and debug messages
colorEnables color prefixes, log and warn messages are orange, debug messages are light orangeSetting evolv:catalyst-logs to debug color displays all logs and with color prefixes.

Experiment Log Level Override

Warning: log level overrides in experiment code will not be silenced in production

const rule = window.evolv.catalyst.xyz;
const { log, warn, debug } = rule;

rule.logs = 'debug';
rule.logColor = true; // Default is false

rule.id

New in 0.6.0 - The id for the current context. Declared at the context level, assigning this value initializes the active key listener for SPA handling. This is an alternative to rule.isActive().

SyntaxDescriptionNotes
rule.id = <context id><context id>: The id of the current contextAdded in 0.6.0

Within the context level of an experiment the id can be found attached to the this object.

// In this example the context id is 'context_id'
console.log(this.key) // Output: web.context_id

const rule = window.evolv.catalyst.xyz
rule.id = this.key.split('.')[1] // context_id

The context id can also be found in the metamodel. If the metamodel was created in the Web Editor context_id would be a randomly generated hash, if using a build process like the project scaffold you would manually assign it.

web:
    context_id:
        _id: context_id

The context key also corresponds to the class added to the html element when the experiment is active.

<html class="evolv_web_context_id evolv_web_context_id_variable">

rule.isActive()

Declared at the context level code, defines criteria for determining whether the current context is active. Assigning this function initializes the active key listener for SPA handling.

SyntaxDescriptionNotes
rule.isActive = <function><function>: A function that returns true when the current context is active

The standard method for determining if the current context is active has been to check the html element for the context key.

// In this example the context id is 'context_id'

const rule = window.evolv.catalyst.xyz
rule.isActive = () => {
    return Array.from(document.querySelector('html').classList).includes(
        'evolv_web_context_id'
    );
};


rule.instrument.add()

New in 0.6.0 - Replaces rule.store.instrumentDOM(). Accepts an instrument key, select function, and options or an array of these inputs and adds an entry in rule.instrument.queue.

SyntaxDescriptionNotes
rule.instrument.add(<key>, <select>, <options>)<key>: A string for reference, can contain dashes or underscores but no white space<select>: A function that returns an ENode() => $('h1')<options>: and object containing valid options
rule.instrument.add(<array>)<array>: An array containing arrays of arguments (see example below).
OptionDescriptionNotes
typeString containing either single or multi, defaults to multi. Specifies whether the instrument should return an ENode containing a single element or multiple. Respected by rule.selectInstrument and rule.whenItem. Provides a slight performance improvement when set to single
asClassString: Replaces the default class namenull: Disables adding instrument class
onConnectAn array of callbacks to be executed whenever a selected element is connected
onDisconnectAn array of callbacks to be executed whenever a selected element is disconnected

Note: Calling rule.instrument.add() triggers the processing of the instrumentation, so for instrumenting multiple items the array approach is much more performant than calling successive rule.instrument.add() functions.

const rule = window.evolv.catalyst['ab-test']
const $ = rule.select;
const $$ = rule.selectAll;
const $i = rule.selectInstrument;

rule.instrument.add('body', () => $(document.body))

rule.instrument.add([
    ['page', () => $('#page'), {type: 'single'}]
    ['page-heading', () => $i('page').find('h1'), {type: 'single'}],
    ['section-headings', () => $$('h2')],
    ['buttons', () => $$('button'), {asClass: 'button'}], // Applies class 'evolv-button' instead of 'evolv-buttons'
    ['links', () => $$('a'), {asClass: null}], // Applies no class
]);

rule.$()

The default $ selector prior to 0.6.0. Now a proxy for rule.selectAll().


rule.$$()

The default instrument selector prior to 0.6.0. Now a proxy for rule.selectInstrument().


rule.select()

New in 0.6.0 - Typically assigned to $, accepts a variety of inputs and returns an ENode containing a single element.

SyntaxDescriptionNotes
$(<selector>, <context>)<selector>: String containing CSS selectorContext (optional): Element, default is document$('p'), $('.some-class'), $('.parent > [attr=some-attribute]'
$(<XPath>, <context>)Selector: String containing XPath selector Context (optional): Element, default is document$('//p'), $('//button[contains(text(),"Go")]'), $('//h3[contains(text(),"Heading")]/parent::*/parent::*')
$(<ENode>)Another ENode, returns a new ENode containing the first element of the original ENode`var pageHeading = $('h1'); var pageHeadingRef = $(pageHeading)
$(<element>)A variable referencing an element$(document.body)
$(<array>)An array of elements, returns an ENode containing the first element of the arrayvar everyLi = Array.from(document.querySelectorAll('li')); $(everyLi)
$(<HTML>)Creates a new ENode from an HTML string containing a single parent element$('<div class="evolv-card"><h3>Heading</h3><p>Some text.</p></div>')Note: Prior to v.0.6.0$('<div class="sibling-1"></div><div class="sibling-2"></div>') would return an ENode only containing the first div
$()Creates a new empty ENodevar a = $() // a.el: []

rule.selectAll()

New in 0.6.0 - Typically assigned to $$, accepts a variety of inputs and returns an ENode containing all matching elements.

SyntaxDescriptionNotes
$(<selector>, <context>)Selector: String containing CSS selectorContext (optional): Element, default is document$('p'), $('.some-class'), $('.parent > [attr=some-attribute]'
$(<XPath>, <context>)Selector: String containing XPath selector Context (optional): Element, default is document$('//p'), $('//button[contains(text(),"Go")]'), $('//h3[contains(text(),"Heading")]/parent::*/parent::*')
$(<ENode>)Another ENode, returns a new ENode referencing the original ENodevar pageHeading = $('h1'); var pageHeadingRef = $(pageHeading)
$(<element>)A variable referencing an element$(document.body)
$(<array>)An array of elements, returns an ENode the arrayvar everyLi = Array.from(document.querySelectorAll('li')); $(everyLi)
$(<HTML>)Creates a new ENode from an HTML string$('<div class="evolv-card"><h3>Heading</h3><p>Some text.</p></div>')Note: Prior to v.0.6.0$('<div class="sibling-1"></div><div class="sibling-2"></div>') would return an ENode only containing the first div
$()Creates a new empty ENodevar a = $() // a.el: []

rule.selectInstrument()

New in 0.6.0 - Typically assigned to $i, accepts a key for rule.instrument.queue and returns the referenced ENode. If the instrument item has the option { type: 'single' } will return an ENode with the first element of the referenced ENode.

SyntaxDescriptionNotes
$(<key>)String containing a key for rule.instrument.queue$$('page-heading'), $$('promo').find('p'), $$('product').parent()
var rule = window.evolv.catalyst.ab_test;
var $ = rule.select;
var $i = rule.selectInstrument;

rule.instrument.add('page-heading', () => $('h1'))

var pageHeading = $i('page-heading'); // Output: pageHeading.el Array(1) 0: h1.evolv-page-heading

rule.key()


rule.track()

Applies a variant-specific attribute to the body to allow you define all the variant CSS at the context level. If multiple variants are active simultaneously they will be space-delimited in the attribute. New in 0.6.0 - Attribute will be removed with SPA navigation away from the page.

New in 0.6.0 - Also applies a variant-specific class to the body element;

Note: With 11 or more variants it's easy to misapply styles because body[evolv-ab_test*='1-1'] matches <body evolv-ab_text="11-1"> this can solved by using brackets around your variant identifiers. For example: rule.track('[1-1]'). This issue does not exist if you reference the new class instead of the attribute.

SyntaxDescriptionNotes
rule.track(<variant>)String containing a variant keyrule.track('1-1'), rule.track('c1v1')

Context JS:

var rule = window.evolv.catalyst['ab-test'];

Context SASS

body.evolv-ab-test-c1v1 {
    .evolv {
        &-heading {
            font-size: 3rem;
        }
    }
}

body.evolv-ab-test-c1v2 {
    .evolv {
        &-heading {
            font-size: 4rem;
        }
    }
}

Variant C1V1 JS:

var rule = window.evolv.catalyst['ab-test'];
rule.track('c1v1');

Variant C2V2 JS:

var rule = window.evolv.catalyst['ab-test'];
rule.track('c1v2');

Target HTML where variant C1V1 and C2V2 are active:

<body class="evolv-ab-test-c1v1 evolv-ab-test-c1v2" evolv-ab_test="c1v1 c1v2">
    <h1 class="evolv-heading">Heading</h1>
    <!-- Here the h1 would receives the styles from both variants -->
    ...
</body>

rule.whenContext()

New in 0.6.0 - Listens for evolv.client.getActiveKeys and fires a callback when the sandbox state changes to active or inactive. Useful for SPA cleanup functions.

SyntaxDescriptionNotes
rule.whenContext(<state>).then(<callback>)<state>: String containing active or inactive<callback>: Callback to be added to the onActivate or onDeactivate queue
const rule = window.evolv.catalyst['ab-test'];
const $ = rule.select;

rule.key = 'abtest' // Assigning the context key initiates the active key listener

function makeThings() {
    $('h1').afterMe('<p class="evolv-subheading">New Subheading</p>')
}

function cleanUp() {
    $('.evolv-subheading').el[0].remove();
}

rule.whenContext('active').then(() => makeThings());
rule.whenContext('inactive').then(() => cleanUp());

rule.whenMutate()

New in 0.6.0 - Fires a callback when there is a change detected on the page. More specifically this fires after processing the instrument queue which is debounced, so it doesn't fire on every mutation but when a mutation or cluster of mutations happen and then stop for at least 1/60th of a second. Can replace many instances that would have required rule.watch() without having to add another mutation observer to the page. Is that better for performance? Nobody knows.

SyntaxDescriptionNotes
rule.whenMutate().then(<callback>)<callback>: Callback to added to the onMutate queue
// In this example there's a price on the page that can change dynamically so we create a function that updates the price and set it to fire whenever there's a mutation on the page.

const rule = window.evolv.catalyst.xyz;
const $ = rule.select;

function updatePrice() {
    const price = $('.price');
    const priceString = price.text();

    const newPrice = $('.evolv-price');
    const newPriceString = `The price is currently ${price}`;

    price.addClass('evolv-display-none');

    if (!newPrice.exists()) {
        $(`<p class="evolv-price">${newPriceString}</p>`).insertAfter(price)
    } else {
        newPrice.text(newPriceString)
    }
}

updatePrice();

rule.onMutate().then(updatePrice);

.whenItem()

The whenItem() method will wait for the selector associated with the specified instrument key and passes the found ENode to a callback. Has two options for how callbacks are applied. rule.whenDOM().then() applies a callback to an ENode containing each element found individually. rule.whenDOM().thenInBulk() applies a callback to an ENode containing a group of elements if they are discovered at one time. New in 0.6.0 - Does not allow a the same callback to be applied to the same selector more than once, allowing when methods to be nested without creating duplicate listeners. If the instrument item has the option { type: 'single' } will return an ENode with the first element of the referenced ENode.

SyntaxDescriptionNotes
rule.whenItem(<instrument key>)String containing a key to the instrument.queue objectrule.whenItem('product')
.then(ENode => callback(<ENode>))Executes a callback on each new element found in the ENode
.thenInBulk(ENode => callback(<ENode>))Executes a callback on the group of elements in the ENode
const rule = window.evolv.catalyst['ab-test'];

rule.instrument.add([
    ['page-heading', () => $('h1')],
    ['button', () => $('button')],
    ['h2', () => $('h2')]
]);

rule.whenItem('page-heading').then((pageHeading) =>
    pageHeading.text('New improved heading')
);
// <h1 class="evolv-page-heading">New improved heading</h1>

rule.whenItem('buttons').then(buttons => console.log(buttons));
// Output:
//      ENode {el: [button.evolv-button], length: 1}
//      ENode {el: [button.evolv-button], length: 1}
//      ENode {el: [button.evolv-button], length: 1} 

rule.whenItem('h2').thenInBulk(h2 => console.log(h2));
// Output:
//      ENode {el: [h2.evolv-h2, h2.evolv-h2, h2.evolv-h2], length: 3}

rule.whenDOM()

Waits for the specified selector or ENode to be selectable on the page and will apply a callback to each element when found. Has two options for how callbacks are applied. rule.whenDOM().then() applies a callback to each element found individually. rule.whenDOM().thenInBulk() applies a callback to a group of elements if they are discovered at one time. New in 0.6.0 - Does not allow a the same callback to be applied to the same selector more than once, allowing when methods to be nested without creating duplicate listeners.

SyntaxDescriptionNotes
rule.whenDOM(<selector>)String containing CSS selectorrule.whenDOM('.product').then(el => {})
rule.whenDOM(<ENode>)ENoderule.whenDOM($('button')).then(button => button.addClass('evolv-button')Added in 0.6.0
.then(<ENode> => callback(<ENode>))Creates an ENode for each new element found and passes them to a callback
.thenInBulk(<ENode> => callback(<ENode>))Creates an ENode containing the group of elements found and passes it to a callback
rule.whenDOM('h1').then((h1) => h1.text('New improved heading'));

rule.whenElement()

New in 0.6.0 - A wrapper for rule.whenDOM that executes a callback on the first element (not the ENode) meeting the selection criteria.

SyntaxDescriptionNotes
rule.whenElement(<selector>)String containing CSS selectorrule.whenElement('.product').then(product => {}).then(<element> => callback(<element>))
rule.whenElement(<ENode>)ENoderule.whenElement($('button')).then(button => button.classList.add('evolv-button').then(<element> => callback(<element>))
const rule = window.evolv.catalyst.xyz;

rule.whenElement('.product img').then(img => img.style.width = '100%');
// Will only adjust the first product image found

rule.whenElements()

New in 0.6.0 - A wrapper for rule.whenDOM that executes a callback on each element (not ENode) meeting the selection criteria.

SyntaxDescriptionNotes
rule.whenElement(<selector>).then(<element> => <callback(<element>)>)String containing CSS selectorrule.whenElement('.product').then(product => {})
rule.whenElement(<ENode>)ENoderule.whenElement($('button')).then(button => button.classList.add('evolv-button').then(<element> => callback(<element>))
const rule = window.evolv.catalyst.xyz;

rule.whenElements('.product img').then(img => img.style.width = '100%');
// Will change the width of every product image found

rule.waitUntil()

New in 0.6.0 - Accepts a condition and passes a the result to a callback when it evaluates truthy. Useful for waiting for a window property to be assigned before running code. Behind the scenes it uses a global interval polling function using requestAnimationFrame() that is shared between all sandbox.

SyntaxDescriptionNotes
rule.waitUntil(<condition>)<condition>: a function that returns truthy
const rule = window.evolv.catalyst.xyz;
const log = rule.log

rule.waitUntil(() => window.x).then(x => log('x:', x));

setTimeout(() => window.x = 100, 3000);

// After 3 seconds x will be assigned and you will see in the console:
// [evolv-xyz] x: 100

rule.store

A object to house assets, variables, templates, icons, etc to be used in your experiment and shared between variants. It has the benefit of:

  • Only accessible from within the experiment sandbox so it doesn't pollute the global scope
  • Allows assets to be defined in the context and used in variants
  • Contains .instrumentDOM() method Deprecated, use rule.instrument.add() instead (add link here)

Context:

var rule = evolv.renderRule.ab_test;
var store = rule.store;

store.icons = {
    circle: `<svg width="100" height="100"><circle cx="50" cy="50" r="50" /></svg>`,
};

Variant:

$('#circle-text').prepend($(store.icons.circle));

rule.store.instrumentDOM()

The instrumentDOM() method finds the elements passed into it, caches them, and applies classes. Instrumented objects can accessed by their associated key using the rule.$$() or rule.whenItem() methods.

store.instrumentDOM({
    'devices-section': {
        get dom() {
            return $('#devicesSection');
        },
        asClass: 'devices', // Optional, applies class 'evolv-devices' to the element instead of the default 'evolv-devices-section' from the key
    },
    'pod-parent': {
        get dom() {
            return $$('devices-section')
                .find('[id*=mvo_ovr_devices]')
                .first()
                .parent();
        },
    },
});

ENodes

A jQuery-like object for selecting and manipulating DOM elements. Every ENode stores elements in an array named el and contains a suite of methods.

var products = $('.product');
console.log(products.el); // [ div.product, div.product, div.product ]

filter()

The filter() method creates a new array containing all of the elements that match the provided selector. Internally it uses the Array.prototype.matches() method to evaluate the elements.

SyntaxDescriptionReturns
ENode.filter(selector)String containing CSS selectorENode

Example:

<h2 class="heading heading-1">Heading 1</h2>
<h2 class="heading heading-2">Heading 2</h2>
<h2 class="heading heading-3">Heading 3</h2>
$('.heading').filter(':not(.heading-3)');

// Expected output: ENode containing [ h2.heading-1, h2.heading-2 ]

contains()

The contains() method returns the elements in an ENode that contain the specified string. The method is case sensitive.

SyntaxDescriptionReturnsNotes
ENode.contains(text)String containing textENode
ENode.contains(regex)Regular expressionENodeAdded in 0.6.0

Example:

<button id="learn-more">Learn more</button>
<button id="checkout">Checkout</button>
const button = $('button');    // Output: ENode containing [ button#checkout, button#learn-more  ]
button.contains('Checkout');   // Output: ENode containing [ button#checkout ]
button.contains(/Learn more/); // Output: ENode containing [ button#learn-more ]

find()

The find() method returns the all elements that match the specified child selector.

SyntaxDescriptionReturns
ENode.find(selector)String containing CSS selectorENode

Example:

<ul id="sidebar">
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
</ul>
$('#sidebar').find('li');
// Output: ENode containing [ li, li, li, li, li ]

closest()

The closest() method returns the nearest ancestor element found that matches the specified selector.

SyntaxDescriptionReturns
ENode.closest(selector)String containing CSS selectorENode
<div id="sidebar-wrap">
    <ul id="sidebar">
        <li>Lorum ipsum</li>
        <li>Lorum ipsum</li>
        <li>Lorum ipsum</li>
        <li>Lorum ipsum</li>
        <li>Lorum ipsum</li>
    </ul>
</div>
$('li').closest('#sidebar-wrap');
// Output: ENode containing [ div#sidebar-wrap ]

parent()

The parent() method returns the parent element(s) of the associated ENode.

SyntaxDescriptionReturns
ENode.parent()No argumentsENode
<ul id="list-1">
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
</ul>
<ul id="list-2">
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
</ul>
$('li').parent();
// Output: ENode containing [ ul#list-1, ul#list-2 ]

children()

The children() method returns the child elements of the associated ENode. If passed a selector it will filter the results to match.

SyntaxDescriptionReturns
ENode.children()No argumentsENode
ENode.children(selector)String containing CSS selectorENode
<ul id="sidebar">
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
</ul>
$('ul').children();
// Output: ENode containing [ li, li, li, li, li ]

$('ul').children(':not(:last-child)');
// Output: ENode containing [ li, li, li, li ]

addClass()

The addClass() method adds classes to elements in the associated ENode.

SyntaxDescriptionReturns
ENode.addClass()String containing list of space-separated classesENode
<ul id="sidebar">
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
</ul>
$('ul').addClass('evolv-sidebar');
// Output: ENode containing [ ul#sidebar.evolv-sidebar ]

$('li:first-child').addClass('evolv-first-item evolv-margin-0');
// Output: ENode containing [ li.evolv-first-item.evolv-margin-0, li, li ]

removeClass()

The removeClass() method removes classes of on the specified selector. Unlike addClass() remove class only accepts a single class name.

SyntaxDescriptionReturns
ENode.removeClass()String containing single class nameENode
<ul id="sidebar" class="evolv-sidebar">
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
</ul>
$('ul').removeClass('evolv-sidebar');
// Output: ENode containing [ ul#sidebar ]

append()

The append() method attaches elements before the end of the first element of the associated ENode. It returns the original ENode.

SyntaxDescription
ENode.append(selector)String containing CSS selector
ENode.append(XPath)String containing XPath selector (coming soon!)
ENode.append(ENode)Another ENode
ENode.append(element)A variable referencing a DOM element
ENode.append(array)An array of DOM elements
ENode.append(HTML)String containing HTML with a single parent element
<ul id="sidebar">
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
</ul>
$('ul').append('<li class="evolv-new-list-item">Lorum ipsum</li>');

Output:

<ul id="sidebar">
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li class="evolv-new-list-item">Lorum ipsum</li>
</ul>

prepend()

The prepend() method attaches elements after the beginning of the first element of the associated ENode. It returns the original ENode.

SyntaxDescription
ENode.prepend(selector)String containing CSS selector
ENode.prepend(XPath)String containing XPath selector (coming soon!)
ENode.prepend(ENode)Another ENode
ENode.prepend(element)A variable referencing a DOM element
ENode.prepend(array)An array of DOM elements
ENode.prepend(HTML)String containing HTML with a single parent element
<ul id="sidebar">
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
</ul>
$('ul').prepend('<li class="evolv-new-list-item">Lorum ipsum</li>');

Output:

<ul id="sidebar">
    <li class="evolv-new-list-item">Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
</ul>

beforeMe()

The beforeMe() method attaches elements as siblings before the beginning of the first element of the associated ENode. It returns the original ENode.

SyntaxDescription
ENode.beforeMe(selector)String containing CSS selector
ENode.beforeMe(ENode)Another ENode
<ul id="sidebar">
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
</ul>
$('ul').beforeMe('<div class="evolv-above-sidebar">Above sidebar</div>');

Output:

<div class="evolv-above-sidebar">Above sidebar</div>
<ul id="sidebar">
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
</ul>

afterMe()

The afterMe() method attaches elements as siblings after the end of the first element of the associated ENode. It returns the original ENode.

SyntaxDescription
ENode.afterMe(selector)String containing CSS selector
ENode.afterMe(ENode)Another ENode
<ul id="sidebar">
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
</ul>
$('ul').afterMe('<div class="evolv-below-sidebar">Below sidebar</div>');

Output:

<ul id="sidebar">
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
</ul>
<div class="evolv-below-sidebar">Below sidebar</div>

insertBefore()

The insertBefore() method attaches the first element in the associated ENode as a sibling before the passed element. It returns the original ENode.

SyntaxDescription
ENode.insertBefore(selector)String containing CSS selector
ENode.insertBefore(ENode)Another ENode
<ul id="sidebar">
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
</ul>
$('ul > :first-child').insertBefore($('<li>New first child</li>'));

Output:

<ul id="sidebar">
    <li>New first child</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
</ul>

insertAfter()

The insertAfter() method attaches the first element in the associated ENode as a sibling after the passed element. It returns the original ENode.

SyntaxDescription
ENode.insertAfter(selector)String containing CSS selector
ENode.insertAfter(ENode)Another ENode
<ul id="sidebar">
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
</ul>
$('ul > :last-child').insertAfter($('<li>New last child</li>'));

Output:

<ul id="sidebar">
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>Lorum ipsum</li>
    <li>New last child</li>
</ul>

wrap()

Wraps each element of an ENode with the specified element. Returns the original ENode.

SyntaxDescriptionReturns
ENode.wrap(HTML)String containing an HTML elementENode (self)
<div class="item">Item</div>
<div class="item">Item</div>
<div class="item">Item</div>
<div class="item">Item</div>
$('div').wrap('<div class="evolv-item-wrap"></div>');

Output:

<div class="evolv-item-wrap">
    <div class="item">Item</div>
</div>
<div class="evolv-item-wrap">
    <div class="item">Item</div>
</div>
<div class="evolv-item-wrap">
    <div class="item">Item</div>
</div>
<div class="evolv-item-wrap">
    <div class="item">Item</div>
</div>

wrapAll()

Wraps all of the elements of an ENode with the specified element. Returns the original ENode.

SyntaxDescriptionReturns
ENode.wrap(HTML)String containing an HTML elementENode (self)
<div class="item">Item</div>
<div class="item">Item</div>
<div class="item">Item</div>
<div class="item">Item</div>
$('div').wrapAll('<div class="evolv-item-wrap"></div>');

Output:

<div class="evolv-item-wrap">
    <div class="item">Item</div>
    <div class="item">Item</div>
    <div class="item">Item</div>
    <div class="item">Item</div>
</div>

markOnce()

Returns a new ENode filtered to remove elements containing the specified attribute, then adds the attribute to the remaining elements. Useful for ensuring code only executes once on a desired element.

SyntaxDescriptionReturns
ENode.markOnce(attribute)String containing attributenew ENode
<ul id="sidebar">
    <li evolv="true">First list item</li>
    <li evolv="true">Second list item</li>
    <li evolv="true">Third list item</li>
    <li>Fourth list item</li>
</ul>
$('li').markOnce('evolv');
// Output: ENode.el: Array(1) 0: <li evolv="true">Fourth list item</li>

on()

The on() method adds event listeners to the specified selector.

SyntaxDescriptionReturns
ENode.on(event, function)Event: String containing event tag or multiple event tags separated by a spaceFunction: A function to be fired on the eventENode (self)
<button>Continue</button>
$('button').on('click', (event) => {
    console.log('test');
});
// Output: Prints "test" to the console every time the button is clicked

// Add multiple event tag example here

html()

Returns a string of the inner HTML of the associated ENode. If the ENode contains multiple elements this method will return a single concatenated string of the inner HTML of all the elements. If a parameter is provided, it will set the inner HTML of the associated ENode.

SyntaxDescriptionReturns
ENode.html()EmptyString
ENode.html(HTML)String containing HTMLENode (self)
<button><span>Continue</span></button>

<ul id="sidebar">
    <li><span>First</span></li>
    <li><span>Second</span></li>
    <li><span>Third</span></li>
</ul>
$('button').html();
// Output: "<span>Continue</span>"

$('button').html('<span>Pre-order</span>');
// Output: ENode.el: Array(1) 0: <button><span>Pre-order</span></button>

$('li').html();
// Output: "<li><span>First</span></li><li><span>Second</span></li><li><span>Third</span></li>"

$('li').html('<span>List item</span>');
// Output: ENode.el: Array(3)
//           0: <li><span>List item</span></li>
//           1: <li><span>List item</span></li>
//           2: <li><span>List item</span></li>

text()

Returns the text of the associated ENode. If the ENode contains multiple elements this method will return a single space-separated concatenated string of the text content of all the elements. If a parameter is provided, it will set the text content for the associated ENode.

SyntaxDescriptionReturns
ENode.text()EmptyString
ENode.text(text)String containing textENode (self)
<button>Continue</button>

<ul id="sidebar">
    <li>First</li>
    <li>Second</li>
    <li>Third</li>
</ul>
$('button').text();
// Output: "Continue"

$('button').text('Pre-order');
// Output: ENode.el: Array(1) 0: <button>Pre-order</button>

$('li').text();
// Output: "First Second Third"

$('li').text('List item');
// Output: ENode.el: Array(3)
//           0: <li>List item</li>
//           1: <li>List item</li>
//           2: <li>List item</li>

attr()

Returns the specified attribute on the associated ENode. If the ENode contains multiple elements it will return a space-separated concatenated string of all the attribute values. If a parameter is provided, it will set the attribute content.

SyntaxDescriptionReturns
ENode.attr()EmptyString
ENode.attr(object)Object of format { attribute: value }ENode (self)
<button aria-label="Continue">Continue</button>

<ul id="sidebar">
    <li data-testid="first">First</li>
    <li data-testid="second">Second</li>
    <li data-testid="third">Third</li>
</ul>
$('button').attr('aria-label');
// Output: "Continue"

$('button').attr({ 'aria-label': 'Pre-order' });
// Output: ENode.el: Array(1) 0: <button aria-label="Pre-order">Continue</button>

$('li').attr('data-testid');
// Output: "first second third"

$('li').attr({ 'data-testid': 'list-item' });
// Output: ENode.el: Array(3)
//           0: <li data-testid="list-item">First</li>
//           1: <li data-testid="list-item">Second</li>
//           2: <li data-testid="list-item">Third</li>

each()

Iterates over each element in an ENode and executes a callback function. Returns the original ENode.

SyntaxDescriptionReturns
ENode.each(callback)Callback function of the form (ENode) => {}. Optional index and array parameters coming soon!ENode (self)
<ul id="sidebar">
    <li>First</li>
    <li>Second</li>
    <li>Third</li>
</ul>
$('li').each((item) => {
    var itemText = item.text();
    item.text(itemText + 'item');
});

Output:

<ul id="sidebar">
    <li>First item</li>
    <li>Second item</li>
    <li>Third item</li>
</ul>

watch()

Waits for changes on the associated ENode before executing the callback function.

SyntaxDescriptionReturns
ENode.wait(config).then(callback)Config: MutationObserver configuration, see defaults belowCallback: function of the form (mutations) => {}Callback execution

Default config:

{
    attributes: false,
    childList: true,
    characterData: false,
    subtree: true,
}
<ul id="sidebar">
    <li>First</li>
    <li>Second</li>
    <li>Third</li>
</ul>
$('#sidebar').watch(() =>{
  $("li").each( elem => {
    elem.text("test");
  }
});
// Output: will change all the li elements to have the text "test" when the contents of the ul are modified in anyway

firstDom()

Returns the first element in the ENode. Equivalent to ENode.el[0].

SyntaxDescriptionReturns
ENode.firstDom()No parametersHTML Element
<ul id="sidebar">
    <li>First</li>
    <li>Second</li>
    <li>Third</li>
</ul>
$('li').firstDom();
// Output: <li>First</li>

lastDom()

Returns the last element in the ENode. Equivalent to ENode.el.slice(-1).

SyntaxDescriptionReturns
ENode.lastDom()No parametersHTML Element
<ul id="sidebar">
    <li>First</li>
    <li>Second</li>
    <li>Third</li>
</ul>
$('li').lastDom();
// Output: <li>Third</li>

first()

Returns an ENode containing the first child element in the ENode.

SyntaxDescriptionReturns
ENode.first()No parametersNew ENode
<ul id="sidebar">
    <li>First</li>
    <li>Second</li>
    <li>Third</li>
</ul>
$('li').first();
// Output: ENode.el: Array(1) 0: <li>First</li>

last()

Returns an ENode containing the last child element in the ENode.

SyntaxDescriptionReturns
ENode.last()No parametersNew ENode
<ul id="sidebar">
    <li>First</li>
    <li>Second</li>
    <li>Third</li>
</ul>
$('li').last();
// Output: ENode.el: Array(1) 0: <li>Third</li>
0.1.26

1 year ago

0.1.24

1 year ago

0.1.23

1 year ago

0.1.22

1 year ago

0.1.21

1 year ago

0.1.20

1 year ago

0.1.19

1 year ago

0.1.18

1 year ago

0.1.17

1 year ago

0.1.16

1 year ago

0.1.15

1 year ago

0.1.14

1 year ago

0.1.13

1 year ago

0.1.12

2 years ago

0.1.11

2 years ago

0.1.10

2 years ago

0.1.9

2 years ago

0.1.8

2 years ago

0.1.7

2 years ago

0.1.6

2 years ago

0.1.5

2 years ago

0.1.4

2 years ago

0.1.3

2 years ago

0.1.2

2 years ago

0.1.1

2 years ago

0.1.0

2 years ago