A simple library for serializable highlights.
import Accent from 'accent';
const accent = new Accent();
accent.highlightCurrentSelection()
.then(highlight => {
highlight.scrollIntoView();
}).catch(err => {
console.log(err);
});
/* or */
accent.highlightFromString('Hello, world!')
.then(highlight => {
highlight.scrollIntoView();
}).catch(err => {
console.log(err);
});
npm install accent --save
accent
is an instance of Highlighter
.
By default, when a highlight is clicked it will gain focus and a click to any element except the highlight's will cause it to lose focus. A focused highlight has the class accent--focus
.
Note: Every
async
method has a synchronous method. For a method with namefunc
, the method will be calledfuncSync
. Use with caution, these will block the browser.
Asynchronously highlights the current selection. If the selection is collapsed, the returned promise resolves to null.
accent.selection().then(highlight => {
if (highlight) getSelection().isCollapsed; // true, because the selection gets cleared
});
Asynchronously highlights range
. If the range is collapsed, the returned promise resolves to null.
accent.range(range).then(highlight => {
if (highlight) highlight.toString() === range.toString(); // true, if `range` didn't change
});
Asynchronously highlights the first occurrence of string
in the document's body, starting at fromIndex
. The default value of fromIndex
is 0. If the string isn't found, the returned promise resolves to null.
accent.string('foo').then(highlight => {
if (highlight) highlight.toString(); // 'foo'
});
Asynchronously deserializes and highlights serialization
. serialization
can be a serialized highlight or an array of serialized highlights. If given a serialized highlight and it is not found, the returned promise will resolve to null. If given an an array of serialized highlights and one or more are not found, the returned promise will resolve to an array with null values where the found highlights would've been.
// http://www.example.com/
const serialization = [{
text: 'Example',
index: 6,
range: {
startContainer: '/html/body/div/h1/text()',
startOffset: 0,
endContainer: '/html/body/div/h1/text()',
endOffset: 7,
},
}];
accent.deserialize(serialization).then(highlights => {
JSON.stringify(highlights[0].serialize()) === JSON.stringify(json); // true
});
Removes focus from the currently focused highlight, if there is one, and focuses highlight
. This adds the class accent--focus
to highlight
.
// http://www.example.com/
accent.string('Example').then(highlight => {
accent.focus(highlight);
highlight.hasClass('accent--focus'); // true
})
Removes focus from the currently focused highlight, if there is one. This removes the class accent--focus
from the highlight.
// http://www.example.com/
accent.string('Example').then(highlight => {
accent.focus(highlight);
highlight.hasClass('accent--focus'); // true
accent.blur();
highlight.hasClass('accent--focus'); // false
})
Returns the currently focused highlight or null if no highlight is currently focused.
// http://www.example.com/
accent.string('Example').then(highlight => {
accent.focus(highlight);
accent.getFocused() === highlight; // true
})
Returns an array of all the highlights. The optional function callback
will be passed each highlight. If callback
returns a promise then this function will wait for it to resolve.
accent.highlights(highlight => {
// do something with `highlight`...
}).then(highlights => {
accent.serialize() === JSON.stringify(highlights.map(highlight => JSON.parse(highlight.serialize()))); // true
});
An alias for accent.highlights(highlight => highlight.unmount())
.
accent.unmount(); // no highlights present in the document
An alias for accent.highlights(highlight => highlight.mount())
.
accent.mount().then(() => {
// all highlights present in the document
});
Returns a serialization of all the highlights.
accent.serialize(); // []
// http://www.example.com/
accent.string('Example').then(() => {
accent.serialize(); // [{ text: 'Example', index: 6, range: { startContainer: '/html/body/div/h1/text()', startOffset: 0, endContainer: '/html/body/div/h1/text()', endOffset: 7 } }]
});
Registers handler
to events
. events
is a whitespace delimited string of event names. handler
is a function that will be called each time a registered event is fired.
accent.on('highlight', highlight => {
// do something with `highlight`...
});
The following events can be tracked with accent.on(events, handler)
:
Event Name | Handler Arguments | Event Description |
---|---|---|
highlight |
highlight |
highlight was just created and mounted |
focus |
highlight |
highlight was just focused |
blur |
highlight |
highlight just lost focus |
Removes handler
from events
. events
is a whitespace delimited string of event names. handler
is a function that was previously registered with accent.on(events, handler)
. If only events
is provided, all handlers will be removed from events
. If no parameters are provided, all handlers are removed from all events. handler
can only be provided together with events
.
const handler = highlight => {};
accent.on('highlight', handler); // 1 `highlight` event registered
accent.on('highlight', highlight => {}); // 2 `highlight` events registered
accent.off('highlight', handler); // 1 `highlight` events registered
accent.off('highlight'); // 0 events registered
accent.on('highlight', handler); // 1 `highlight` event registered
accent.on('highlight', highlight => {}); // 2 `highlight` events registered
accent.off(); // 0 events registered
Every highlight
is an instance of Highlight
.
By default, when the mouse enters a highlight it will get the class accent-hover
and will lose it when the mouse leaves.
Note: Every
async
method has a synchronous method. For a method with namefunc
, the method will be calledfuncSync
. Use with caution, these will block the browser.
Returns the text of this highlight.
accent.string('foo').then(highlight => {
if (highlight) highlight.toString(); // `foo`
});
Asynchronously inserts this highlight into the DOM.
accent.selection().then(highlight => {
if (highlight) {
highlight.unmount(); // removes `highlight` from the DOM
highlight.mount(); // inserts `highlight` into the DOM
}
});
Removes this highlight from the DOM.
accent.selection().then(highlight => {
if (highlight) highlight.unmount(); // removes `highlight` from the DOM
});
Asynchronously merges highlight
into this highlight. If the highlights don't form a continuous range, this method will throw an error. The new highlight contains all the listeners, classes, and attributes of this highlight. Mounts the new highlight only if this highlight was mounted.
// http://www.example.com/
Promise.all([accent.string('Example Do'), accent.string('le Domain')]).then(highlights => {
return highlights[0].merge(highlights[1]);
}).then(highlight => {
highlight.toString(); // 'Example Domain'
});
Returns a serialization of this highlight.
// http://www.example.com/
accent.string('Example').then(highlight => {
highlight.serialize(); // { text: 'Example', index: 6, range: { startContainer: '/html/body/div/h1/text()', startOffset: 0, endContainer: '/html/body/div/h1/text()', endOffset: 7 } }
});
Registers handler
to events
. events
is a whitespace delimited string of event names. handler
is a function that will be called each time a registered event is fired. See https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener for useCapture
.
accent.on('highlight', highlight => {
highlight.on('mount', () => {
highlight.addClass('accent--yellow');
});
});
The following events can be tracked with highlight.on(events, handler[, useCapture])
:
Event Name | Supports useCapture |
Handler Arguments | Event Description |
---|---|---|---|
mount |
no | highlight |
highlight was just mounted |
unmount |
no | highlight |
highlight was just unmounted |
click |
yes | event , highlight |
mouse was clicked on top of highlight |
dblclick |
yes | event , highlight |
mouse was clicked on top of highlight in quick succession |
mousedown |
yes | event , highlight |
mouse was pressed on top of highlight |
mouseup |
yes | event , highlight |
mouse was released on top of highlight |
mouseenter |
yes | event , highlight |
mouse entered highlight |
mouseleave |
yes | event , highlight |
mouse left highlight |
mousemove |
yes | event , highlight |
mouse moved on top of highlight |
Note: See https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent for more details on the
event
handler argument.
Removes handler
from events
. events
is a whitespace delimited string of event names. handler
is a function that was previously registered with highlight.on(events, handler)
. If only events
is provided, all handlers will be removed from events
. If no parameters are provided, all handlers are removed from all events. handler
can only be provided together with events
.
const handler = highlight => highlight.addClass('accent--green');
accent.on('highlight', highlight => {
highlight.on('mousedown', handler); // 1 'mousedown' event registered
highlight.on('mouseup', highlight => highlight.removeClass('accent-green')); // 1 'mousedown' and 1 'mouseup' event registered
highlight.off('mousedown', handler); // 1 'mouseup' event registered
highlight.off('mouseup'); // 0 events registered
highlight.on('mousedown', handler); // 1 'mousedown' event registered
highlight.on('mouseup', highlight => highlight.removeClass('accent-green')); // 1 'mousedown' and 1 'mouseup' event registered
highlight.off(); // 0 events registered
});
Returns a ClientRect for this highlight.
// http://www.example.com/
accent.string('Example').then(highlight => {
highlight.getBoundingClientRect(); // { width: 131.453125, height: 38, top: 151.4375, right: 471.453125, bottom: 189.4375, left: 340 }
});
Scrolls the viewport so that this highlight's bounding rectangle is centered vertically and horizontally in the viewport. If passed a number duration
, then the scroll will be linear and last duration
ms.
accent.selection().then(highlight => {
if (highlight) highlight.scrollIntoView();
});
Returns true if this highlight has any class in className
, else false. className
is a whitespace delimited string of class names.
accent.on('highlight', highlight => highlight.addClass('accent--yellow'));
accent.selection().then(highlight => {
if (highlight) highlight.hasClass('accent--yellow'); // true
});
Adds all classes in className
to this highlight. className
is a whitespace delimited string of class names.
accent.on('highlight', highlight => {
highlight.addClass('accent--yellow');
highlight.hasClass('accent--yellow'); // true
});
Removes all classes in className
from this highlight. className
is a whitespace delimited string of class names.
accent.on('highlight', highlight => {
highlight.addClass('accent--yellow');
highlight.removeClass('accent--yellow');
highlight.hasClass('accent--yellow'); // false
});
Toggles all classes in className
in this highlight. className
is a whitespace delimited string of class names.
accent.on('highlight', highlight => {
highlight.toggleClass('accent--yellow');
highlight.hasClass('accent--yellow'); // true
highlight.toggleClass('accent--yellow');
highlight.hasClass('accent--yellow'); // false
});
If value
is passed, sets the value of the attribute attributeName
to value
in this highlight. If only attributeName
is passed, returns the value of the attribute attributeName
if this highlight contains it, else null. attributeName
is a string and can't contain any whitespace characters.
accent.selection().then(highlight => {
if (highlight) {
highlight.attr('data-accent-id', '1');
highlight.attr('data-accent-id'); // '1'
}
});
Removes the attribute attributeName
from this highlight. attributeName
is a string and can't contain any whitespace characters.
accent.selection().then(highlight => {
if (highlight) {
highlight.attr('data-accent-id', '1');
highlight.attr('data-accent-id'); // '1'
highlight.removeAttribute('data-accent-id');
highlight.attr('data-accent-id'); // null
}
});
Alias for highlight.attr(`data-${key}`, value)
.
accent.selection().then(highlight => {
if (highlight) {
highlight.attr('data-accent-id', '1');
highlight.data('accent-id'); // '1'
highlight.data('accent-id', '2');
highlight.attr('data-accent-id'); // '2'
}
});
Alias for highlight.removeAttribute(`data-${key}`)
.
accent.selection().then(highlight => {
if (highlight) {
highlight.attr('data-accent-id', '1');
highlight.attr('data-accent-id'); // '1'
highlight.removeData('accent-id');
highlight.attr('data-accent-id'); // null
}
});