Commit 2b6ecf7a authored by Robert Knight's avatar Robert Knight Committed by Lyza Danger Gardner

Convert remaining files in src/sidebar/ to ES modules

Use the convert-to-es-modules script to convert the remaining
CommonJS/Node module files in src/sidebar/ to ES modules.
parent f5a9fcb8
...@@ -275,7 +275,7 @@ const defaultOpts = { ...@@ -275,7 +275,7 @@ const defaultOpts = {
* @return {Thread} - The root thread, whose children are the top-level * @return {Thread} - The root thread, whose children are the top-level
* annotations to display. * annotations to display.
*/ */
function buildThread(annotations, opts) { export default function buildThread(annotations, opts) {
opts = Object.assign({}, defaultOpts, opts); opts = Object.assign({}, defaultOpts, opts);
let thread = threadAnnotations(annotations); let thread = threadAnnotations(annotations);
...@@ -358,5 +358,3 @@ function buildThread(annotations, opts) { ...@@ -358,5 +358,3 @@ function buildThread(annotations, opts) {
return thread; return thread;
} }
module.exports = buildThread;
const warnOnce = require('../shared/warn-once'); import warnOnce from '../shared/warn-once';
/** /**
* Return the mapped methods that can be called remotely via this server. * Return the mapped methods that can be called remotely via this server.
...@@ -93,7 +93,7 @@ function start(store, settings, $window) { ...@@ -93,7 +93,7 @@ function start(store, settings, $window) {
} }
} }
module.exports = { export default {
server: { server: {
start: start, start: start,
}, },
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* This module defines the set of global events that are dispatched * This module defines the set of global events that are dispatched
* on $rootScope * on $rootScope
*/ */
module.exports = { export default {
// Internal state changes // Internal state changes
FRAME_CONNECTED: 'frameConnected', FRAME_CONNECTED: 'frameConnected',
......
const url = require('../url'); import * as url from '../url';
describe('url.encode', function() { describe('url.encode', function() {
it('urlencodes its input', function() { it('urlencodes its input', function() {
......
/** /**
* URL encode a string, dealing appropriately with null values. * URL encode a string, dealing appropriately with null values.
*/ */
function encode(str) { export function encode(str) {
if (str) { if (str) {
return window.encodeURIComponent(str); return window.encodeURIComponent(str);
} }
return ''; return '';
} }
module.exports = {
encode: encode,
};
let loaded = false; let loaded = false;
function loadGoogleAnalytics(trackingId) { export default function loadGoogleAnalytics(trackingId) {
// small measure to make we do not accidentally // small measure to make we do not accidentally
// load the analytics scripts more than once // load the analytics scripts more than once
if (loaded) { if (loaded) {
...@@ -47,5 +47,3 @@ function loadGoogleAnalytics(trackingId) { ...@@ -47,5 +47,3 @@ function loadGoogleAnalytics(trackingId) {
/* eslint-enable */ /* eslint-enable */
} }
module.exports = loadGoogleAnalytics;
const serviceConfig = require('./service-config'); import serviceConfig from './service-config';
/** /**
* Function that returns apiUrl from the settings object. * Function that returns apiUrl from the settings object.
...@@ -8,7 +8,7 @@ const serviceConfig = require('./service-config'); ...@@ -8,7 +8,7 @@ const serviceConfig = require('./service-config');
* @throws {Error} If the settings has a service but the service doesn't have an apiUrl * @throws {Error} If the settings has a service but the service doesn't have an apiUrl
* *
*/ */
function getApiUrl(settings) { export default function getApiUrl(settings) {
const service = serviceConfig(settings); const service = serviceConfig(settings);
if (service) { if (service) {
...@@ -22,5 +22,3 @@ function getApiUrl(settings) { ...@@ -22,5 +22,3 @@ function getApiUrl(settings) {
} }
return settings.apiUrl; return settings.apiUrl;
} }
module.exports = getApiUrl;
const queryString = require('query-string'); import * as queryString from 'query-string';
/** /**
* Return the app configuration specified by the frame embedding the Hypothesis * Return the app configuration specified by the frame embedding the Hypothesis
* client. * client.
*/ */
function hostPageConfig(window) { export default function hostPageConfig(window) {
const configStr = window.location.hash.slice(1); const configStr = window.location.hash.slice(1);
const configJSON = queryString.parse(configStr).config; const configJSON = queryString.parse(configStr).config;
const config = JSON.parse(configJSON || '{}'); const config = JSON.parse(configJSON || '{}');
...@@ -62,5 +62,3 @@ function hostPageConfig(window) { ...@@ -62,5 +62,3 @@ function hostPageConfig(window) {
return result; return result;
}, {}); }, {});
} }
module.exports = hostPageConfig;
import { jsonConfigsFrom } from '../shared/settings';
import crossOriginRPC from './cross-origin-rpc.js';
import addAnalytics from './ga'; import addAnalytics from './ga';
import serviceConfig from './service-config';
import disableOpenerForExternalLinks from './util/disable-opener-for-external-links'; import disableOpenerForExternalLinks from './util/disable-opener-for-external-links';
import { fetchConfig } from './util/fetch-config'; import { fetchConfig } from './util/fetch-config';
import serviceConfig from './service-config';
import { jsonConfigsFrom } from '../shared/settings';
import crossOriginRPC from './cross-origin-rpc.js';
import * as sentry from './util/sentry'; import * as sentry from './util/sentry';
// Read settings rendered into sidebar app HTML by service/extension. // Read settings rendered into sidebar app HTML by service/extension.
...@@ -29,6 +30,7 @@ disableOpenerForExternalLinks(document.body); ...@@ -29,6 +30,7 @@ disableOpenerForExternalLinks(document.body);
import angular from 'angular'; import angular from 'angular';
// Angular addons which export the Angular module name via `module.exports`. // Angular addons which export the Angular module name via `module.exports`.
import angularRoute from 'angular-route'; import angularRoute from 'angular-route';
import angularToastr from 'angular-toastr'; import angularToastr from 'angular-toastr';
...@@ -114,6 +116,7 @@ function sendPageView(analytics) { ...@@ -114,6 +116,7 @@ function sendPageView(analytics) {
} }
// Preact UI components that are wrapped for use within Angular templates. // Preact UI components that are wrapped for use within Angular templates.
import AnnotationActionBar from './components/annotation-action-bar'; import AnnotationActionBar from './components/annotation-action-bar';
import AnnotationBody from './components/annotation-body'; import AnnotationBody from './components/annotation-body';
import AnnotationHeader from './components/annotation-header'; import AnnotationHeader from './components/annotation-header';
...@@ -135,6 +138,7 @@ import TagList from './components/tag-list'; ...@@ -135,6 +138,7 @@ import TagList from './components/tag-list';
import TopBar from './components/top-bar'; import TopBar from './components/top-bar';
// Remaining UI components that are still built with Angular. // Remaining UI components that are still built with Angular.
import annotation from './components/annotation'; import annotation from './components/annotation';
import annotationThread from './components/annotation-thread'; import annotationThread from './components/annotation-thread';
import annotationViewerContent from './components/annotation-viewer-content'; import annotationViewerContent from './components/annotation-viewer-content';
...@@ -144,6 +148,7 @@ import streamContent from './components/stream-content'; ...@@ -144,6 +148,7 @@ import streamContent from './components/stream-content';
import threadList from './components/thread-list'; import threadList from './components/thread-list';
// Angular directives. // Angular directives.
import hAutofocusDirective from './directive/h-autofocus'; import hAutofocusDirective from './directive/h-autofocus';
import hBrandingDirective from './directive/h-branding'; import hBrandingDirective from './directive/h-branding';
import hOnTouchDirective from './directive/h-on-touch'; import hOnTouchDirective from './directive/h-on-touch';
...@@ -151,39 +156,44 @@ import hTooltipDirective from './directive/h-tooltip'; ...@@ -151,39 +156,44 @@ import hTooltipDirective from './directive/h-tooltip';
import windowScrollDirective from './directive/window-scroll'; import windowScrollDirective from './directive/window-scroll';
// Services. // Services.
import bridgeService from '../shared/bridge';
import analyticsService from './services/analytics'; import analyticsService from './services/analytics';
import annotationMapperService from './services/annotation-mapper'; import annotationMapperService from './services/annotation-mapper';
import annotationsService from './services/annotations'; import annotationsService from './services/annotations';
import apiService from './services/api'; import apiService from './services/api';
import apiRoutesService from './services/api-routes'; import apiRoutesService from './services/api-routes';
import authService from './services/oauth-auth';
import bridgeService from '../shared/bridge';
import featuresService from './services/features'; import featuresService from './services/features';
import flashService from './services/flash'; import flashService from './services/flash';
import frameSyncService from './services/frame-sync'; import frameSyncService from './services/frame-sync';
import groupsService from './services/groups'; import groupsService from './services/groups';
import localStorageService from './services/local-storage'; import localStorageService from './services/local-storage';
import authService from './services/oauth-auth';
import permissionsService from './services/permissions'; import permissionsService from './services/permissions';
import rootThreadService from './services/root-thread'; import rootThreadService from './services/root-thread';
import searchFilterService from './services/search-filter'; import searchFilterService from './services/search-filter';
import serviceUrlService from './services/service-url'; import serviceUrlService from './services/service-url';
import sessionService from './services/session'; import sessionService from './services/session';
import streamerService from './services/streamer';
import streamFilterService from './services/stream-filter'; import streamFilterService from './services/stream-filter';
import streamerService from './services/streamer';
import tagsService from './services/tags'; import tagsService from './services/tags';
import unicodeService from './services/unicode'; import unicodeService from './services/unicode';
import viewFilterService from './services/view-filter'; import viewFilterService from './services/view-filter';
// Redux store. // Redux store.
import store from './store'; import store from './store';
// Utilities. // Utilities.
import Discovery from '../shared/discovery'; import Discovery from '../shared/discovery';
import { encode as urlEncodeFilter } from './filter/url';
import OAuthClient from './util/oauth-client'; import OAuthClient from './util/oauth-client';
import VirtualThreadList from './virtual-thread-list';
import * as random from './util/random'; import * as random from './util/random';
import * as time from './util/time'; import * as time from './util/time';
import { encode as urlEncodeFilter } from './filter/url'; import VirtualThreadList from './virtual-thread-list';
function startAngularApp(config) { function startAngularApp(config) {
angular angular
......
/* eslint no-console: "off" */ /* eslint no-console: "off" */
const queryString = require('query-string'); import * as queryString from 'query-string';
const Socket = require('./websocket'); import Socket from './websocket';
/** /**
* Return a URL with a cache-busting query string parameter added. * Return a URL with a cache-busting query string parameter added.
...@@ -66,7 +66,7 @@ function reloadExternalStyleSheets(changed) { ...@@ -66,7 +66,7 @@ function reloadExternalStyleSheets(changed) {
* the 'livereloadserver' query string parameter is * the 'livereloadserver' query string parameter is
* used. * used.
*/ */
function connect(url) { export function connect(url) {
const conn = new Socket(url); const conn = new Socket(url);
conn.on('open', function() { conn.on('open', function() {
console.log('Live reload client listening'); console.log('Live reload client listening');
...@@ -94,7 +94,3 @@ function connect(url) { ...@@ -94,7 +94,3 @@ function connect(url) {
console.error('Error connecting to live reload server:', err); console.error('Error connecting to live reload server:', err);
}); });
} }
module.exports = {
connect: connect,
};
...@@ -85,7 +85,7 @@ function replaceText(state, pos, length, text) { ...@@ -85,7 +85,7 @@ function replaceText(state, pos, length, text) {
* @param {LinkType} linkType - The type of link to insert. * @param {LinkType} linkType - The type of link to insert.
* @return {EditorState} - The new state of the input field. * @return {EditorState} - The new state of the input field.
*/ */
function convertSelectionToLink(state, linkType) { export function convertSelectionToLink(state, linkType) {
if (typeof linkType === 'undefined') { if (typeof linkType === 'undefined') {
linkType = LinkType.ANCHOR_LINK; linkType = LinkType.ANCHOR_LINK;
} }
...@@ -140,7 +140,7 @@ function convertSelectionToLink(state, linkType) { ...@@ -140,7 +140,7 @@ function convertSelectionToLink(state, linkType) {
* 'suffix' if the input text is empty. * 'suffix' if the input text is empty.
* @return {EditorState} The new state of the input field. * @return {EditorState} The new state of the input field.
*/ */
function toggleSpanStyle(state, prefix, suffix, placeholder) { export function toggleSpanStyle(state, prefix, suffix, placeholder) {
if (typeof suffix === 'undefined') { if (typeof suffix === 'undefined') {
suffix = prefix; suffix = prefix;
} }
...@@ -234,7 +234,7 @@ function transformLines(state, start, end, callback) { ...@@ -234,7 +234,7 @@ function transformLines(state, start, end, callback) {
* of the selection. * of the selection.
* @return {EditorState} - The new state of the input field. * @return {EditorState} - The new state of the input field.
*/ */
function toggleBlockStyle(state, prefix) { export function toggleBlockStyle(state, prefix) {
const start = state.selectionStart; const start = state.selectionStart;
const end = state.selectionEnd; const end = state.selectionEnd;
...@@ -265,9 +265,4 @@ function toggleBlockStyle(state, prefix) { ...@@ -265,9 +265,4 @@ function toggleBlockStyle(state, prefix) {
} }
} }
module.exports = { export { LinkType };
toggleSpanStyle: toggleSpanStyle,
toggleBlockStyle: toggleBlockStyle,
convertSelectionToLink: convertSelectionToLink,
LinkType: LinkType,
};
const queryString = require('query-string'); import * as queryString from 'query-string';
/** /**
* Return an HTML5 audio player with the given src URL. * Return an HTML5 audio player with the given src URL.
...@@ -321,7 +321,7 @@ function replaceLinkWithEmbed(link) { ...@@ -321,7 +321,7 @@ function replaceLinkWithEmbed(link) {
* embeds of the same media. * embeds of the same media.
* *
*/ */
function replaceLinksWithEmbeds(element) { export function replaceLinksWithEmbeds(element) {
let links = element.getElementsByTagName('a'); let links = element.getElementsByTagName('a');
// `links` is a "live list" of the <a> element children of `element`. // `links` is a "live list" of the <a> element children of `element`.
...@@ -335,7 +335,3 @@ function replaceLinksWithEmbeds(element) { ...@@ -335,7 +335,3 @@ function replaceLinksWithEmbeds(element) {
replaceLinkWithEmbed(links[i]); replaceLinkWithEmbed(links[i]);
} }
} }
module.exports = {
replaceLinksWithEmbeds: replaceLinksWithEmbeds,
};
const createDOMPurify = require('dompurify'); import createDOMPurify from 'dompurify';
const escapeHtml = require('escape-html'); import escapeHtml from 'escape-html';
const katex = require('katex'); import * as katex from 'katex';
const showdown = require('showdown'); import showdown from 'showdown';
const DOMPurify = createDOMPurify(window); const DOMPurify = createDOMPurify(window);
...@@ -129,7 +129,7 @@ function insertMath(html, mathBlocks) { ...@@ -129,7 +129,7 @@ function insertMath(html, mathBlocks) {
}, html); }, html);
} }
function renderMathAndMarkdown(markdown) { export default function renderMathAndMarkdown(markdown) {
// KaTeX takes care of escaping its input, so we want to avoid passing its // KaTeX takes care of escaping its input, so we want to avoid passing its
// output through the HTML sanitizer. Therefore we first extract the math // output through the HTML sanitizer. Therefore we first extract the math
// blocks from the input, render and sanitize the remaining markdown and then // blocks from the input, render and sanitize the remaining markdown and then
...@@ -139,5 +139,3 @@ function renderMathAndMarkdown(markdown) { ...@@ -139,5 +139,3 @@ function renderMathAndMarkdown(markdown) {
const mathAndMarkdownHTML = insertMath(markdownHTML, mathInfo.mathBlocks); const mathAndMarkdownHTML = insertMath(markdownHTML, mathInfo.mathBlocks);
return mathAndMarkdownHTML; return mathAndMarkdownHTML;
} }
module.exports = renderMathAndMarkdown;
const EventEmitter = require('tiny-emitter'); import EventEmitter from 'tiny-emitter';
/** /**
* Client for the Hypothesis search API. * Client for the Hypothesis search API.
* *
* SearchClient handles paging through results, canceling search etc. * SearchClient handles paging through results, canceling search etc.
*/ */
class SearchClient extends EventEmitter { export default class SearchClient extends EventEmitter {
/** /**
* @param {Object} searchFn - Function for querying the search API * @param {Object} searchFn - Function for querying the search API
* @param {Object} opts - Search options * @param {Object} opts - Search options
...@@ -100,5 +100,3 @@ class SearchClient extends EventEmitter { ...@@ -100,5 +100,3 @@ class SearchClient extends EventEmitter {
this.emit('end'); this.emit('end');
} }
} }
module.exports = SearchClient;
...@@ -5,11 +5,9 @@ ...@@ -5,11 +5,9 @@
* @param {Object} settings - The settings object which would contain the services array. * @param {Object} settings - The settings object which would contain the services array.
*/ */
function serviceConfig(settings) { export default function serviceConfig(settings) {
if (!Array.isArray(settings.services) || settings.services.length === 0) { if (!Array.isArray(settings.services) || settings.services.length === 0) {
return null; return null;
} }
return settings.services[0]; return settings.services[0];
} }
module.exports = serviceConfig;
/** /**
* Return a fake annotation with the basic properties filled in. * Return a fake annotation with the basic properties filled in.
*/ */
function defaultAnnotation() { export function defaultAnnotation() {
return { return {
id: 'deadbeef', id: 'deadbeef',
created: '2015-05-10T20:18:56.613388+00:00', created: '2015-05-10T20:18:56.613388+00:00',
...@@ -18,7 +18,7 @@ function defaultAnnotation() { ...@@ -18,7 +18,7 @@ function defaultAnnotation() {
/** /**
* Return a fake annotation created by a third-party user. * Return a fake annotation created by a third-party user.
*/ */
function thirdPartyAnnotation() { export function thirdPartyAnnotation() {
return Object.assign(defaultAnnotation(), { return Object.assign(defaultAnnotation(), {
user: 'acct:ben@publisher.org', user: 'acct:ben@publisher.org',
}); });
...@@ -27,7 +27,7 @@ function thirdPartyAnnotation() { ...@@ -27,7 +27,7 @@ function thirdPartyAnnotation() {
/** /**
* Return a fake public annotation with the basic properties filled in. * Return a fake public annotation with the basic properties filled in.
*/ */
function publicAnnotation() { export function publicAnnotation() {
return { return {
id: 'pubann', id: 'pubann',
document: { document: {
...@@ -48,7 +48,7 @@ function publicAnnotation() { ...@@ -48,7 +48,7 @@ function publicAnnotation() {
* Components will never see this data structure, as it will have been * Components will never see this data structure, as it will have been
* amended by store reducers. * amended by store reducers.
*/ */
function newAnnotation() { export function newAnnotation() {
return { return {
id: undefined, id: undefined,
$highlight: undefined, $highlight: undefined,
...@@ -61,7 +61,7 @@ function newAnnotation() { ...@@ -61,7 +61,7 @@ function newAnnotation() {
} }
/** Return a new reply */ /** Return a new reply */
function newReply() { export function newReply() {
return { return {
id: undefined, id: undefined,
$highlight: undefined, $highlight: undefined,
...@@ -73,7 +73,7 @@ function newReply() { ...@@ -73,7 +73,7 @@ function newReply() {
} }
/** Return a new annotation which has no tags or text. */ /** Return a new annotation which has no tags or text. */
function newEmptyAnnotation() { export function newEmptyAnnotation() {
return { return {
id: undefined, id: undefined,
$highlight: undefined, $highlight: undefined,
...@@ -87,7 +87,7 @@ function newEmptyAnnotation() { ...@@ -87,7 +87,7 @@ function newEmptyAnnotation() {
/** Return an annotation domain model object for a new highlight /** Return an annotation domain model object for a new highlight
* (newly-created client-side, not yet saved to the server). * (newly-created client-side, not yet saved to the server).
*/ */
function newHighlight() { export function newHighlight() {
return { return {
id: undefined, id: undefined,
$highlight: true, $highlight: true,
...@@ -99,7 +99,7 @@ function newHighlight() { ...@@ -99,7 +99,7 @@ function newHighlight() {
/** Return an annotation domain model object for an existing annotation /** Return an annotation domain model object for an existing annotation
* received from the server. * received from the server.
*/ */
function oldAnnotation() { export function oldAnnotation() {
return { return {
id: 'annotation_id', id: 'annotation_id',
$highlight: undefined, $highlight: undefined,
...@@ -113,7 +113,7 @@ function oldAnnotation() { ...@@ -113,7 +113,7 @@ function oldAnnotation() {
/** Return an annotation domain model object for an existing highlight /** Return an annotation domain model object for an existing highlight
* received from the server. * received from the server.
*/ */
function oldHighlight() { export function oldHighlight() {
return { return {
id: 'annotation_id', id: 'annotation_id',
$highlight: undefined, $highlight: undefined,
...@@ -127,7 +127,7 @@ function oldHighlight() { ...@@ -127,7 +127,7 @@ function oldHighlight() {
/** Return an annotation domain model object for an existing page note /** Return an annotation domain model object for an existing page note
* received from the server. * received from the server.
*/ */
function oldPageNote() { export function oldPageNote() {
return { return {
highlight: undefined, highlight: undefined,
target: [{ source: 'http://example.org' }], target: [{ source: 'http://example.org' }],
...@@ -140,7 +140,7 @@ function oldPageNote() { ...@@ -140,7 +140,7 @@ function oldPageNote() {
/** Return an annotation domain model object for an existing reply /** Return an annotation domain model object for an existing reply
* received from the server. * received from the server.
*/ */
function oldReply() { export function oldReply() {
return { return {
highlight: undefined, highlight: undefined,
target: ['foo'], target: ['foo'],
...@@ -161,7 +161,7 @@ function oldReply() { ...@@ -161,7 +161,7 @@ function oldReply() {
* *
* @param {ModerationState} modInfo * @param {ModerationState} modInfo
*/ */
function moderatedAnnotation(modInfo) { export function moderatedAnnotation(modInfo) {
return Object.assign(defaultAnnotation(), { return Object.assign(defaultAnnotation(), {
id: 'ann-id', id: 'ann-id',
hidden: !!modInfo.hidden, hidden: !!modInfo.hidden,
...@@ -170,18 +170,3 @@ function moderatedAnnotation(modInfo) { ...@@ -170,18 +170,3 @@ function moderatedAnnotation(modInfo) {
}, },
}); });
} }
module.exports = {
defaultAnnotation: defaultAnnotation,
publicAnnotation: publicAnnotation,
moderatedAnnotation: moderatedAnnotation,
newAnnotation: newAnnotation,
newEmptyAnnotation: newEmptyAnnotation,
newHighlight: newHighlight,
newReply: newReply,
oldAnnotation: oldAnnotation,
oldHighlight: oldHighlight,
oldPageNote: oldPageNote,
oldReply: oldReply,
thirdPartyAnnotation: thirdPartyAnnotation,
};
...@@ -8,14 +8,18 @@ sinon.assert.expose(assert, { prefix: null }); ...@@ -8,14 +8,18 @@ sinon.assert.expose(assert, { prefix: null });
// the directive tests rely on angular.element() returning // the directive tests rely on angular.element() returning
// a full version of jQuery. // a full version of jQuery.
// //
const jQuery = require('jquery');
require('angular'); import jQuery from 'jquery';
require('angular-mocks');
import 'angular';
import 'angular-mocks';
window.jQuery = window.$ = jQuery; window.jQuery = window.$ = jQuery;
// Configure Enzyme for UI tests. // Configure Enzyme for UI tests.
require('preact/debug'); import 'preact/debug';
const { configure } = require('enzyme');
const { Adapter } = require('enzyme-adapter-preact-pure'); import { configure } from 'enzyme';
import { Adapter } from 'enzyme-adapter-preact-pure';
configure({ adapter: new Adapter() }); configure({ adapter: new Adapter() });
const buildThread = require('../build-thread'); import buildThread from '../build-thread';
const metadata = require('../util/annotation-metadata'); import * as metadata from '../util/annotation-metadata';
// Fixture with two top level annotations, one note and one reply // Fixture with two top level annotations, one note and one reply
const SIMPLE_FIXTURE = [ const SIMPLE_FIXTURE = [
......
const crossOriginRPC = require('../cross-origin-rpc'); import crossOriginRPC from '../cross-origin-rpc';
const { $imports } = require('../cross-origin-rpc'); import { $imports } from '../cross-origin-rpc';
describe('crossOriginRPC', function() { describe('crossOriginRPC', function() {
describe('server', function() { describe('server', function() {
......
const redux = require('redux'); import * as redux from 'redux';
/** /**
* Utility function that creates a fake Redux store for use in tests. * Utility function that creates a fake Redux store for use in tests.
...@@ -11,7 +11,7 @@ const redux = require('redux'); ...@@ -11,7 +11,7 @@ const redux = require('redux');
* returned store. * returned store.
* @return {Object} Redux store * @return {Object} Redux store
*/ */
function fakeStore(initialState, methods) { export default function fakeStore(initialState, methods) {
function update(state, action) { function update(state, action) {
if (action.state) { if (action.state) {
return Object.assign({}, state, action.state); return Object.assign({}, state, action.state);
...@@ -28,5 +28,3 @@ function fakeStore(initialState, methods) { ...@@ -28,5 +28,3 @@ function fakeStore(initialState, methods) {
return Object.assign(store, methods); return Object.assign(store, methods);
} }
module.exports = fakeStore;
const getApiUrl = require('../get-api-url'); import getApiUrl from '../get-api-url';
describe('sidebar.getApiUrl', function() { describe('sidebar.getApiUrl', function() {
context('when there is a service object in settings', function() { context('when there is a service object in settings', function() {
......
const Chance = require('chance'); import Chance from 'chance';
const chance = new Chance(); const chance = new Chance();
function group() { export function group() {
const id = chance.hash({ length: 15 }); const id = chance.hash({ length: 15 });
const name = chance.string(); const name = chance.string();
const group = { const group = {
...@@ -15,7 +16,7 @@ function group() { ...@@ -15,7 +16,7 @@ function group() {
return group; return group;
} }
function organization(options = {}) { export function organization(options = {}) {
const org = { const org = {
id: chance.hash({ length: 15 }), id: chance.hash({ length: 15 }),
name: chance.string(), name: chance.string(),
...@@ -24,7 +25,7 @@ function organization(options = {}) { ...@@ -24,7 +25,7 @@ function organization(options = {}) {
return Object.assign(org, options); return Object.assign(org, options);
} }
function defaultOrganization() { export function defaultOrganization() {
return { return {
id: '__default__', id: '__default__',
name: 'Hypothesis', name: 'Hypothesis',
...@@ -32,16 +33,9 @@ function defaultOrganization() { ...@@ -32,16 +33,9 @@ function defaultOrganization() {
}; };
} }
function expandedGroup(options = {}) { export function expandedGroup(options = {}) {
const expanded = group(); const expanded = group();
expanded.organization = organization(); expanded.organization = organization();
return Object.assign(expanded, options); return Object.assign(expanded, options);
} }
module.exports = {
group,
expandedGroup,
organization,
defaultOrganization,
};
const hostPageConfig = require('../host-config'); import hostPageConfig from '../host-config';
function fakeWindow(config) { function fakeWindow(config) {
return { return {
......
const commands = require('../markdown-commands'); import * as commands from '../markdown-commands';
/** /**
* Convert a string containing '<sel>' and '</sel>' markers * Convert a string containing '<sel>' and '</sel>' markers
......
const mediaEmbedder = require('../media-embedder.js'); import * as mediaEmbedder from '../media-embedder.js';
describe('media-embedder', function() { describe('media-embedder', function() {
function domElement(html) { function domElement(html) {
......
const renderMarkdown = require('../render-markdown'); import renderMarkdown from '../render-markdown';
const { $imports } = require('../render-markdown'); import { $imports } from '../render-markdown';
describe('render-markdown', function() { describe('render-markdown', function() {
let render; let render;
......
const SearchClient = require('../search-client'); import SearchClient from '../search-client';
function awaitEvent(emitter, event) { function awaitEvent(emitter, event) {
return new Promise(function(resolve) { return new Promise(function(resolve) {
......
const serviceConfig = require('../service-config'); import serviceConfig from '../service-config';
describe('serviceConfig', function() { describe('serviceConfig', function() {
it('returns null if services is not an array', function() { it('returns null if services is not an array', function() {
......
const VirtualThreadList = require('../virtual-thread-list'); import VirtualThreadList from '../virtual-thread-list';
const { $imports } = require('../virtual-thread-list'); import { $imports } from '../virtual-thread-list';
describe('VirtualThreadList', function() { describe('VirtualThreadList', function() {
let lastState; let lastState;
......
const Socket = require('../websocket'); import Socket from '../websocket';
describe('websocket wrapper', function() { describe('websocket wrapper', function() {
let fakeSocket; let fakeSocket;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* uiConstants is a set of globally used constants across the application. * uiConstants is a set of globally used constants across the application.
*/ */
module.exports = { export default {
PANEL_HELP: 'help', PANEL_HELP: 'help',
PANEL_SHARE_ANNOTATIONS: 'shareGroupAnnotations', PANEL_SHARE_ANNOTATIONS: 'shareGroupAnnotations',
TAB_ANNOTATIONS: 'annotation', TAB_ANNOTATIONS: 'annotation',
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* into a {username, provider} object or null if the input does not * into a {username, provider} object or null if the input does not
* match the expected form. * match the expected form.
*/ */
function parseAccountID(user) { export function parseAccountID(user) {
if (!user) { if (!user) {
return null; return null;
} }
...@@ -20,7 +20,7 @@ function parseAccountID(user) { ...@@ -20,7 +20,7 @@ function parseAccountID(user) {
/** /**
* Returns the username part of an account ID or an empty string. * Returns the username part of an account ID or an empty string.
*/ */
function username(user) { export function username(user) {
const account = parseAccountID(user); const account = parseAccountID(user);
if (!account) { if (!account) {
return ''; return '';
...@@ -31,7 +31,7 @@ function username(user) { ...@@ -31,7 +31,7 @@ function username(user) {
/** /**
* Returns true if the authority is of a 3rd party user. * Returns true if the authority is of a 3rd party user.
*/ */
function isThirdPartyUser(user, authDomain) { export function isThirdPartyUser(user, authDomain) {
const account = parseAccountID(user); const account = parseAccountID(user);
if (!account) { if (!account) {
...@@ -40,9 +40,3 @@ function isThirdPartyUser(user, authDomain) { ...@@ -40,9 +40,3 @@ function isThirdPartyUser(user, authDomain) {
return account.provider !== authDomain; return account.provider !== authDomain;
} }
module.exports = {
isThirdPartyUser: isThirdPartyUser,
parseAccountID: parseAccountID,
username: username,
};
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* uri, domain and title. * uri, domain and title.
* *
*/ */
function documentMetadata(annotation) { export function documentMetadata(annotation) {
const uri = annotation.uri; const uri = annotation.uri;
let domain = new URL(uri).hostname; let domain = new URL(uri).hostname;
let title = domain; let title = domain;
...@@ -34,7 +34,7 @@ function documentMetadata(annotation) { ...@@ -34,7 +34,7 @@ function documentMetadata(annotation) {
* Return the domain and title of an annotation for display on an annotation * Return the domain and title of an annotation for display on an annotation
* card. * card.
*/ */
function domainAndTitle(annotation) { export function domainAndTitle(annotation) {
return { return {
domain: domainTextFromAnnotation(annotation), domain: domainTextFromAnnotation(annotation),
titleText: titleTextFromAnnotation(annotation), titleText: titleTextFromAnnotation(annotation),
...@@ -89,7 +89,7 @@ function titleTextFromAnnotation(annotation) { ...@@ -89,7 +89,7 @@ function titleTextFromAnnotation(annotation) {
} }
/** Return `true` if the given annotation is a reply, `false` otherwise. */ /** Return `true` if the given annotation is a reply, `false` otherwise. */
function isReply(annotation) { export function isReply(annotation) {
return (annotation.references || []).length > 0; return (annotation.references || []).length > 0;
} }
...@@ -98,12 +98,12 @@ function isReply(annotation) { ...@@ -98,12 +98,12 @@ function isReply(annotation) {
* "New" means this annotation has been newly created client-side and not * "New" means this annotation has been newly created client-side and not
* saved to the server yet. * saved to the server yet.
*/ */
function isNew(annotation) { export function isNew(annotation) {
return !annotation.id; return !annotation.id;
} }
/** Return `true` if the given annotation is public, `false` otherwise. */ /** Return `true` if the given annotation is public, `false` otherwise. */
function isPublic(annotation) { export function isPublic(annotation) {
let isPublic = false; let isPublic = false;
if (!annotation.permissions) { if (!annotation.permissions) {
...@@ -141,7 +141,7 @@ function hasSelector(annotation) { ...@@ -141,7 +141,7 @@ function hasSelector(annotation) {
* Returns false if anchoring is still in process but the flag indicating that * Returns false if anchoring is still in process but the flag indicating that
* the initial timeout allowed for anchoring has expired. * the initial timeout allowed for anchoring has expired.
*/ */
function isWaitingToAnchor(annotation) { export function isWaitingToAnchor(annotation) {
return ( return (
hasSelector(annotation) && hasSelector(annotation) &&
typeof annotation.$orphan === 'undefined' && typeof annotation.$orphan === 'undefined' &&
...@@ -158,7 +158,7 @@ function isWaitingToAnchor(annotation) { ...@@ -158,7 +158,7 @@ function isWaitingToAnchor(annotation) {
* @param {Object} annotation * @param {Object} annotation
* @return {boolean} * @return {boolean}
*/ */
function isHighlight(annotation) { export function isHighlight(annotation) {
// `$highlight` is an ephemeral attribute set by the `annotator` on new // `$highlight` is an ephemeral attribute set by the `annotator` on new
// annotation objects (created by clicking the "highlight" button). // annotation objects (created by clicking the "highlight" button).
// It is not persisted and cannot be relied upon, but if it IS present, // It is not persisted and cannot be relied upon, but if it IS present,
...@@ -187,17 +187,17 @@ function isHighlight(annotation) { ...@@ -187,17 +187,17 @@ function isHighlight(annotation) {
} }
/** Return `true` if the given annotation is an orphan. */ /** Return `true` if the given annotation is an orphan. */
function isOrphan(annotation) { export function isOrphan(annotation) {
return hasSelector(annotation) && annotation.$orphan; return hasSelector(annotation) && annotation.$orphan;
} }
/** Return `true` if the given annotation is a page note. */ /** Return `true` if the given annotation is a page note. */
function isPageNote(annotation) { export function isPageNote(annotation) {
return !hasSelector(annotation) && !isReply(annotation); return !hasSelector(annotation) && !isReply(annotation);
} }
/** Return `true` if the given annotation is a top level annotation, `false` otherwise. */ /** Return `true` if the given annotation is a top level annotation, `false` otherwise. */
function isAnnotation(annotation) { export function isAnnotation(annotation) {
return !!(hasSelector(annotation) && !isOrphan(annotation)); return !!(hasSelector(annotation) && !isOrphan(annotation));
} }
...@@ -207,7 +207,7 @@ function isAnnotation(annotation) { ...@@ -207,7 +207,7 @@ function isAnnotation(annotation) {
* the document, where lower numbers mean closer to the * the document, where lower numbers mean closer to the
* start. * start.
*/ */
function location(annotation) { export function location(annotation) {
if (annotation) { if (annotation) {
const targets = annotation.target || []; const targets = annotation.target || [];
for (let i = 0; i < targets.length; i++) { for (let i = 0; i < targets.length; i++) {
...@@ -228,7 +228,7 @@ function location(annotation) { ...@@ -228,7 +228,7 @@ function location(annotation) {
* *
* @return {number|null} * @return {number|null}
*/ */
function flagCount(ann) { export function flagCount(ann) {
if (!ann.moderation) { if (!ann.moderation) {
return null; return null;
} }
...@@ -240,7 +240,7 @@ function flagCount(ann) { ...@@ -240,7 +240,7 @@ function flagCount(ann) {
* *
* @return {string|null} * @return {string|null}
*/ */
function quote(ann) { export function quote(ann) {
if (ann.target.length === 0) { if (ann.target.length === 0) {
return null; return null;
} }
...@@ -251,19 +251,3 @@ function quote(ann) { ...@@ -251,19 +251,3 @@ function quote(ann) {
const quoteSel = target.selector.find(s => s.type === 'TextQuoteSelector'); const quoteSel = target.selector.find(s => s.type === 'TextQuoteSelector');
return quoteSel ? quoteSel.exact : null; return quoteSel ? quoteSel.exact : null;
} }
module.exports = {
documentMetadata: documentMetadata,
domainAndTitle: domainAndTitle,
flagCount: flagCount,
isAnnotation: isAnnotation,
isHighlight: isHighlight,
isNew: isNew,
isOrphan: isOrphan,
isPageNote: isPageNote,
isPublic: isPublic,
isReply: isReply,
isWaitingToAnchor: isWaitingToAnchor,
location: location,
quote,
};
const serviceConfig = require('../service-config'); import serviceConfig from '../service-config';
/** /**
* Is the sharing of annotations enabled? Check for any defined `serviceConfig`, * Is the sharing of annotations enabled? Check for any defined `serviceConfig`,
...@@ -7,7 +7,7 @@ const serviceConfig = require('../service-config'); ...@@ -7,7 +7,7 @@ const serviceConfig = require('../service-config');
* @param {object} settings * @param {object} settings
* @return {boolean} * @return {boolean}
*/ */
function sharingEnabled(settings) { export function sharingEnabled(settings) {
const serviceConfig_ = serviceConfig(settings); const serviceConfig_ = serviceConfig(settings);
if (serviceConfig_ === null) { if (serviceConfig_ === null) {
return true; return true;
...@@ -25,7 +25,7 @@ function sharingEnabled(settings) { ...@@ -25,7 +25,7 @@ function sharingEnabled(settings) {
* @param {object} annotation * @param {object} annotation
* @return {string|undefined} * @return {string|undefined}
*/ */
function shareURI(annotation) { export function shareURI(annotation) {
const links = annotation.links; const links = annotation.links;
return links && (links.incontext || links.html); return links && (links.incontext || links.html);
} }
...@@ -38,12 +38,6 @@ function shareURI(annotation) { ...@@ -38,12 +38,6 @@ function shareURI(annotation) {
* @param {object} settings * @param {object} settings
* @return {boolean} * @return {boolean}
*/ */
function isShareable(annotation, settings) { export function isShareable(annotation, settings) {
return !!(sharingEnabled(settings) && shareURI(annotation)); return !!(sharingEnabled(settings) && shareURI(annotation));
} }
module.exports = {
sharingEnabled,
shareURI,
isShareable,
};
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* @param {Array} ary * @param {Array} ary
* @param {Function} predicate * @param {Function} predicate
*/ */
function countIf(ary, predicate) { export function countIf(ary, predicate) {
return ary.reduce(function(count, item) { return ary.reduce(function(count, item) {
return predicate(item) ? count + 1 : count; return predicate(item) ? count + 1 : count;
}, 0); }, 0);
...@@ -19,7 +19,7 @@ function countIf(ary, predicate) { ...@@ -19,7 +19,7 @@ function countIf(ary, predicate) {
* @param {Array} ary * @param {Array} ary
* @param {Function} mapFn * @param {Function} mapFn
*/ */
function filterMap(ary, mapFn) { export function filterMap(ary, mapFn) {
return ary.reduce(function(newArray, item) { return ary.reduce(function(newArray, item) {
const mapped = mapFn(item); const mapped = mapFn(item);
if (mapped) { if (mapped) {
...@@ -34,15 +34,9 @@ function filterMap(ary, mapFn) { ...@@ -34,15 +34,9 @@ function filterMap(ary, mapFn) {
* *
* @param {string[]} list - List of keys for the set. * @param {string[]} list - List of keys for the set.
*/ */
function toSet(list) { export function toSet(list) {
return list.reduce(function(set, key) { return list.reduce(function(set, key) {
set[key] = true; set[key] = true;
return set; return set;
}, {}); }, {});
} }
module.exports = {
countIf: countIf,
filterMap: filterMap,
toSet: toSet,
};
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* This function may throw an exception if the browser rejects the attempt * This function may throw an exception if the browser rejects the attempt
* to copy text. * to copy text.
*/ */
function copyText(text) { export function copyText(text) {
const temp = document.createElement('pre'); const temp = document.createElement('pre');
temp.className = 'copy-text'; temp.className = 'copy-text';
temp.textContent = text; temp.textContent = text;
...@@ -26,5 +26,3 @@ function copyText(text) { ...@@ -26,5 +26,3 @@ function copyText(text) {
temp.remove(); temp.remove();
} }
} }
module.exports = { copyText };
...@@ -6,7 +6,7 @@ let formatter; ...@@ -6,7 +6,7 @@ let formatter;
* Returns a standard human-readable representation * Returns a standard human-readable representation
* of a date and time. * of a date and time.
*/ */
function format(date) { export function format(date) {
if (typeof Intl !== 'undefined' && Intl.DateTimeFormat) { if (typeof Intl !== 'undefined' && Intl.DateTimeFormat) {
if (!formatter) { if (!formatter) {
formatter = new Intl.DateTimeFormat(undefined, { formatter = new Intl.DateTimeFormat(undefined, {
...@@ -26,7 +26,3 @@ function format(date) { ...@@ -26,7 +26,3 @@ function format(date) {
return date.toDateString() + ' ' + date.toLocaleTimeString(); return date.toDateString() + ' ' + date.toLocaleTimeString();
} }
} }
module.exports = {
format: format,
};
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* *
* @param {Element} root - Root element * @param {Element} root - Root element
*/ */
function disableOpenerForExternalLinks(root) { export default function disableOpenerForExternalLinks(root) {
root.addEventListener('click', event => { root.addEventListener('click', event => {
if (event.target.tagName === 'A') { if (event.target.tagName === 'A') {
const linkEl = event.target; const linkEl = event.target;
...@@ -25,5 +25,3 @@ function disableOpenerForExternalLinks(root) { ...@@ -25,5 +25,3 @@ function disableOpenerForExternalLinks(root) {
} }
}); });
} }
module.exports = disableOpenerForExternalLinks;
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* @param {boolean} [options.useCapture] * @param {boolean} [options.useCapture]
* @return {function} Function which removes the event listeners. * @return {function} Function which removes the event listeners.
*/ */
function listen(element, events, listener, { useCapture = false } = {}) { export function listen(element, events, listener, { useCapture = false } = {}) {
if (!Array.isArray(events)) { if (!Array.isArray(events)) {
events = [events]; events = [events];
} }
...@@ -21,7 +21,3 @@ function listen(element, events, listener, { useCapture = false } = {}) { ...@@ -21,7 +21,3 @@ function listen(element, events, listener, { useCapture = false } = {}) {
); );
}; };
} }
module.exports = {
listen,
};
const getApiUrl = require('../get-api-url'); import getApiUrl from '../get-api-url';
const hostConfig = require('../host-config'); import hostConfig from '../host-config';
const postMessageJsonRpc = require('./postmessage-json-rpc');
import * as postMessageJsonRpc from './postmessage-json-rpc';
function ancestors(window_) { function ancestors(window_) {
if (window_ === window_.top) { if (window_ === window_.top) {
...@@ -57,7 +58,7 @@ function fetchConfigFromAncestorFrame(origin, window_ = window) { ...@@ -57,7 +58,7 @@ function fetchConfigFromAncestorFrame(origin, window_ = window) {
* @param {Window} window_ - Test seam. * @param {Window} window_ - Test seam.
* @return {Promise<Object>} - The merged settings. * @return {Promise<Object>} - The merged settings.
*/ */
function fetchConfig(appConfig, window_ = window) { export function fetchConfig(appConfig, window_ = window) {
const hostPageConfig = hostConfig(window_); const hostPageConfig = hostConfig(window_);
let embedderConfig; let embedderConfig;
...@@ -74,7 +75,3 @@ function fetchConfig(appConfig, window_ = window) { ...@@ -74,7 +75,3 @@ function fetchConfig(appConfig, window_ = window) {
return mergedConfig; return mergedConfig;
}); });
} }
module.exports = {
fetchConfig,
};
function orgName(group) { export function orgName(group) {
return group.organization && group.organization.name; return group.organization && group.organization.name;
} }
function trackViewGroupActivity(analytics) { export function trackViewGroupActivity(analytics) {
analytics.track(analytics.events.GROUP_VIEW_ACTIVITY); analytics.track(analytics.events.GROUP_VIEW_ACTIVITY);
} }
module.exports = {
orgName,
trackViewGroupActivity,
};
const immutable = require('seamless-immutable'); import immutable from 'seamless-immutable';
// TODO: Update when this is a property available on the API response // TODO: Update when this is a property available on the API response
const DEFAULT_ORG_ID = '__default__'; const DEFAULT_ORG_ID = '__default__';
...@@ -79,7 +79,7 @@ function organizations(groups) { ...@@ -79,7 +79,7 @@ function organizations(groups) {
* @param {Array<Group>} groups * @param {Array<Group>} groups
* @return {Array<Object>} - groups sorted by which organization they're in * @return {Array<Object>} - groups sorted by which organization they're in
*/ */
function groupsByOrganization(groups) { export default function groupsByOrganization(groups) {
const orgs = organizations(groups); const orgs = organizations(groups);
const defaultOrganizationGroups = []; const defaultOrganizationGroups = [];
const sortedGroups = []; const sortedGroups = [];
...@@ -101,5 +101,3 @@ function groupsByOrganization(groups) { ...@@ -101,5 +101,3 @@ function groupsByOrganization(groups) {
return sortedGroups; return sortedGroups;
} }
module.exports = groupsByOrganization;
const escapeStringRegexp = require('escape-string-regexp'); import escapeStringRegexp from 'escape-string-regexp';
/** /**
* Combine groups from multiple api calls together to form a unique list of groups. * Combine groups from multiple api calls together to form a unique list of groups.
...@@ -10,7 +10,7 @@ const escapeStringRegexp = require('escape-string-regexp'); ...@@ -10,7 +10,7 @@ const escapeStringRegexp = require('escape-string-regexp');
* @param {Group[]} featuredGroups - all other groups, may include some duplicates from the userGroups * @param {Group[]} featuredGroups - all other groups, may include some duplicates from the userGroups
* @param {string} uri - uri of the current page * @param {string} uri - uri of the current page
*/ */
function combineGroups(userGroups, featuredGroups, uri) { export function combineGroups(userGroups, featuredGroups, uri) {
const worldGroup = featuredGroups.find(g => g.id === '__world__'); const worldGroup = featuredGroups.find(g => g.id === '__world__');
if (worldGroup) { if (worldGroup) {
userGroups.unshift(worldGroup); userGroups.unshift(worldGroup);
...@@ -59,7 +59,3 @@ function uriMatchesScopes(uri, scopes) { ...@@ -59,7 +59,3 @@ function uriMatchesScopes(uri, scopes) {
) !== undefined ) !== undefined
); );
} }
module.exports = {
combineGroups,
};
...@@ -9,4 +9,4 @@ const isSidebar = (window_ = window) => { ...@@ -9,4 +9,4 @@ const isSidebar = (window_ = window) => {
); );
}; };
module.exports = isSidebar; export default isSidebar;
const serviceConfig = require('../service-config'); import serviceConfig from '../service-config';
/** /**
* Return `true` if the first configured service is a "third-party" service. * Return `true` if the first configured service is a "third-party" service.
...@@ -11,7 +11,7 @@ const serviceConfig = require('../service-config'); ...@@ -11,7 +11,7 @@ const serviceConfig = require('../service-config');
* @param {Object} settings - the sidebar settings object * @param {Object} settings - the sidebar settings object
* *
*/ */
function isThirdPartyService(settings) { export default function isThirdPartyService(settings) {
const service = serviceConfig(settings); const service = serviceConfig(settings);
if (service === null) { if (service === null) {
...@@ -24,5 +24,3 @@ function isThirdPartyService(settings) { ...@@ -24,5 +24,3 @@ function isThirdPartyService(settings) {
return service.authority !== settings.authDomain; return service.authority !== settings.authDomain;
} }
module.exports = isThirdPartyService;
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* The argument to the input function may be of any type and is compared * The argument to the input function may be of any type and is compared
* using reference equality. * using reference equality.
*/ */
function memoize(fn) { export default function memoize(fn) {
if (fn.length !== 1) { if (fn.length !== 1) {
throw new Error('Memoize input must be a function of one argument'); throw new Error('Memoize input must be a function of one argument');
} }
...@@ -22,5 +22,3 @@ function memoize(fn) { ...@@ -22,5 +22,3 @@ function memoize(fn) {
return lastResult; return lastResult;
}; };
} }
module.exports = memoize;
const queryString = require('query-string'); import * as queryString from 'query-string';
const random = require('./random'); import * as random from './random';
/** /**
* An object holding the details of an access token from the tokenUrl endpoint. * An object holding the details of an access token from the tokenUrl endpoint.
...@@ -57,7 +57,7 @@ function generateState() { ...@@ -57,7 +57,7 @@ function generateState() {
* OAuthClient handles interaction with the annotation service's OAuth * OAuthClient handles interaction with the annotation service's OAuth
* endpoints. * endpoints.
*/ */
class OAuthClient { export default class OAuthClient {
/** /**
* Create a new OAuthClient * Create a new OAuthClient
* *
...@@ -260,5 +260,3 @@ class OAuthClient { ...@@ -260,5 +260,3 @@ class OAuthClient {
); );
} }
} }
module.exports = OAuthClient;
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* element when a change in its size is detected. * element when a change in its size is detected.
* @return {() => void} * @return {() => void}
*/ */
function observeElementSize(element, onSizeChanged) { export default function observeElementSize(element, onSizeChanged) {
if (typeof ResizeObserver !== 'undefined') { if (typeof ResizeObserver !== 'undefined') {
const observer = new ResizeObserver(() => const observer = new ResizeObserver(() =>
onSizeChanged(element.clientWidth, element.clientHeight) onSizeChanged(element.clientWidth, element.clientHeight)
...@@ -59,5 +59,3 @@ function observeElementSize(element, onSizeChanged) { ...@@ -59,5 +59,3 @@ function observeElementSize(element, onSizeChanged) {
observer.disconnect(); observer.disconnect();
}; };
} }
module.exports = observeElementSize;
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* @param {Function} handler - Event handler * @param {Function} handler - Event handler
* @return {Object} Props to spread into a React element * @return {Object} Props to spread into a React element
*/ */
function onActivate(role, handler) { export function onActivate(role, handler) {
return { return {
// Support mouse activation. // Support mouse activation.
onClick: handler, onClick: handler,
...@@ -28,5 +28,3 @@ function onActivate(role, handler) { ...@@ -28,5 +28,3 @@ function onActivate(role, handler) {
tabIndex: 0, tabIndex: 0,
}; };
} }
module.exports = { onActivate };
const { generateHexString } = require('./random'); import { generateHexString } from './random';
/** Generate a random ID to associate RPC requests and responses. */ /** Generate a random ID to associate RPC requests and responses. */
function generateId() { function generateId() {
...@@ -26,7 +26,7 @@ function createTimeout(delay, message) { ...@@ -26,7 +26,7 @@ function createTimeout(delay, message) {
* @param [id] id - Test seam. * @param [id] id - Test seam.
* @return {Promise<any>} - A Promise for the response to the call * @return {Promise<any>} - A Promise for the response to the call
*/ */
function call( export function call(
frame, frame,
origin, origin,
method, method,
...@@ -96,7 +96,3 @@ function call( ...@@ -96,7 +96,3 @@ function call(
throw err; throw err;
}); });
} }
module.exports = {
call,
};
...@@ -11,7 +11,7 @@ function byteToHex(val) { ...@@ -11,7 +11,7 @@ function byteToHex(val) {
* @param {number} - An even-numbered length string to generate. * @param {number} - An even-numbered length string to generate.
* @return {string} * @return {string}
*/ */
function generateHexString(len) { export function generateHexString(len) {
const crypto = window.crypto || window.msCrypto; /* IE 11 */ const crypto = window.crypto || window.msCrypto; /* IE 11 */
const bytes = new Uint8Array(len / 2); const bytes = new Uint8Array(len / 2);
crypto.getRandomValues(bytes); crypto.getRandomValues(bytes);
...@@ -19,7 +19,3 @@ function generateHexString(len) { ...@@ -19,7 +19,3 @@ function generateHexString(len) {
.map(byteToHex) .map(byteToHex)
.join(''); .join('');
} }
module.exports = {
generateHexString,
};
const retry = require('retry'); import retry from 'retry';
/** /**
* Retry a Promise-returning operation until it succeeds or * Retry a Promise-returning operation until it succeeds or
...@@ -10,7 +10,7 @@ const retry = require('retry'); ...@@ -10,7 +10,7 @@ const retry = require('retry');
* @return A promise for the first successful result of the operation, if * @return A promise for the first successful result of the operation, if
* it succeeds within the allowed number of attempts. * it succeeds within the allowed number of attempts.
*/ */
function retryPromiseOperation(opFn, options) { export function retryPromiseOperation(opFn, options) {
return new Promise(function(resolve, reject) { return new Promise(function(resolve, reject) {
const operation = retry.operation(options); const operation = retry.operation(options);
operation.attempt(function() { operation.attempt(function() {
...@@ -27,7 +27,3 @@ function retryPromiseOperation(opFn, options) { ...@@ -27,7 +27,3 @@ function retryPromiseOperation(opFn, options) {
}); });
}); });
} }
module.exports = {
retryPromiseOperation: retryPromiseOperation,
};
...@@ -11,7 +11,13 @@ ...@@ -11,7 +11,13 @@
* @param {Function} fn - Callback to invoke with setTimeout * @param {Function} fn - Callback to invoke with setTimeout
* @param {number} delay - Delay argument to pass to setTimeout * @param {number} delay - Delay argument to pass to setTimeout
*/ */
function scopeTimeout($scope, fn, delay, setTimeoutFn, clearTimeoutFn) { export default function scopeTimeout(
$scope,
fn,
delay,
setTimeoutFn,
clearTimeoutFn
) {
setTimeoutFn = setTimeoutFn || setTimeout; setTimeoutFn = setTimeoutFn || setTimeout;
clearTimeoutFn = clearTimeoutFn || clearTimeout; clearTimeoutFn = clearTimeoutFn || clearTimeout;
...@@ -24,5 +30,3 @@ function scopeTimeout($scope, fn, delay, setTimeoutFn, clearTimeoutFn) { ...@@ -24,5 +30,3 @@ function scopeTimeout($scope, fn, delay, setTimeoutFn, clearTimeoutFn) {
clearTimeoutFn(id); clearTimeoutFn(id);
}); });
} }
module.exports = scopeTimeout;
const Sentry = require('@sentry/browser'); import * as Sentry from '@sentry/browser';
const warnOnce = require('../../shared/warn-once'); import warnOnce from '../../shared/warn-once';
/** /**
* @typedef SentryConfig * @typedef SentryConfig
...@@ -35,7 +35,7 @@ function currentScriptOrigin() { ...@@ -35,7 +35,7 @@ function currentScriptOrigin() {
* *
* @param {SentryConfig} config * @param {SentryConfig} config
*/ */
function init(config) { export function init(config) {
// Only send events for errors which can be attributed to our code. This // Only send events for errors which can be attributed to our code. This
// reduces noise in Sentry caused by errors triggered by eg. script tags added // reduces noise in Sentry caused by errors triggered by eg. script tags added
// by browser extensions. The downside is that this may cause us to miss errors // by browser extensions. The downside is that this may cause us to miss errors
...@@ -105,21 +105,13 @@ function init(config) { ...@@ -105,21 +105,13 @@ function init(config) {
* *
* @param {import('@sentry/browser').User|null} user * @param {import('@sentry/browser').User|null} user
*/ */
function setUserInfo(user) { export function setUserInfo(user) {
Sentry.setUser(user); Sentry.setUser(user);
} }
/** /**
* Reset metrics used for client-side event filtering. * Reset metrics used for client-side event filtering.
*/ */
function reset() { export function reset() {
eventsSent = 0; eventsSent = 0;
} }
module.exports = {
init,
setUserInfo,
// Test helpers.
reset,
};
...@@ -12,8 +12,8 @@ ...@@ -12,8 +12,8 @@
* https://reactjs.org/docs/hooks-reference.html#usecontext * https://reactjs.org/docs/hooks-reference.html#usecontext
*/ */
const { useContext } = require('preact/hooks'); import { createContext, createElement } from 'preact';
const { createContext, createElement } = require('preact'); import { useContext } from 'preact/hooks';
const fallbackInjector = { const fallbackInjector = {
get(service) { get(service) {
...@@ -54,7 +54,7 @@ const ServiceContext = createContext(fallbackInjector); ...@@ -54,7 +54,7 @@ const ServiceContext = createContext(fallbackInjector);
* // Wrap `MyComponent` to inject any services it needs. * // Wrap `MyComponent` to inject any services it needs.
* module.exports = withServices(MyComponent); * module.exports = withServices(MyComponent);
*/ */
function withServices(Component) { export function withServices(Component) {
if (!Component.injectedProps) { if (!Component.injectedProps) {
// This component doesn't depend on any services, so there is no need // This component doesn't depend on any services, so there is no need
// to wrap it. // to wrap it.
...@@ -108,13 +108,9 @@ function withServices(Component) { ...@@ -108,13 +108,9 @@ function withServices(Component) {
* *
* @param {string} service - Name of the service to look up * @param {string} service - Name of the service to look up
*/ */
function useService(service) { export function useService(service) {
const injector = useContext(ServiceContext); const injector = useContext(ServiceContext);
return injector.get(service); return injector.get(service);
} }
module.exports = { export { ServiceContext };
ServiceContext,
withServices,
useService,
};
const serviceConfig = require('../service-config'); import serviceConfig from '../service-config';
/** /**
* Returns true if the sidebar tutorial has to be shown to a user for a given session. * Returns true if the sidebar tutorial has to be shown to a user for a given session.
* @deprecated To be removed once preact help/tutorial panel is in place * @deprecated To be removed once preact help/tutorial panel is in place
*/ */
function shouldShowSidebarTutorial(sessionState) { export function shouldShowSidebarTutorial(sessionState) {
if (sessionState.preferences.show_sidebar_tutorial) { if (sessionState.preferences.show_sidebar_tutorial) {
return true; return true;
} }
...@@ -29,7 +29,7 @@ function shouldShowSidebarTutorial(sessionState) { ...@@ -29,7 +29,7 @@ function shouldShowSidebarTutorial(sessionState) {
* @param {Object} settings - app configuration/settings * @param {Object} settings - app configuration/settings
* @return {boolean} - Tutorial panel should be displayed automatically * @return {boolean} - Tutorial panel should be displayed automatically
*/ */
function shouldAutoDisplayTutorial(isSidebar, sessionState, settings) { export function shouldAutoDisplayTutorial(isSidebar, sessionState, settings) {
const shouldShowBasedOnProfile = const shouldShowBasedOnProfile =
typeof sessionState.preferences === 'object' && typeof sessionState.preferences === 'object' &&
!!sessionState.preferences.show_sidebar_tutorial; !!sessionState.preferences.show_sidebar_tutorial;
...@@ -38,8 +38,3 @@ function shouldAutoDisplayTutorial(isSidebar, sessionState, settings) { ...@@ -38,8 +38,3 @@ function shouldAutoDisplayTutorial(isSidebar, sessionState, settings) {
isSidebar && !service.onHelpRequestProvided && shouldShowBasedOnProfile isSidebar && !service.onHelpRequestProvided && shouldShowBasedOnProfile
); );
} }
module.exports = {
shouldShowSidebarTutorial: shouldShowSidebarTutorial,
shouldAutoDisplayTutorial: shouldAutoDisplayTutorial,
};
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* store if the criteria is met or `null` otherwise. * store if the criteria is met or `null` otherwise.
* @return {Promise<T>} * @return {Promise<T>}
*/ */
function awaitStateChange(store, selector) { export function awaitStateChange(store, selector) {
const result = selector(store); const result = selector(store);
if (result !== null) { if (result !== null) {
return Promise.resolve(result); return Promise.resolve(result);
...@@ -24,5 +24,3 @@ function awaitStateChange(store, selector) { ...@@ -24,5 +24,3 @@ function awaitStateChange(store, selector) {
}); });
}); });
} }
module.exports = { awaitStateChange };
// Functions that determine which tab an annotation should be displayed in. // Functions that determine which tab an annotation should be displayed in.
const metadata = require('./annotation-metadata'); import uiConstants from '../ui-constants';
const uiConstants = require('../ui-constants');
import * as metadata from './annotation-metadata';
/** /**
* Return the tab in which an annotation should be displayed. * Return the tab in which an annotation should be displayed.
* *
* @param {Annotation} ann * @param {Annotation} ann
*/ */
function tabForAnnotation(ann) { export function tabForAnnotation(ann) {
if (metadata.isOrphan(ann)) { if (metadata.isOrphan(ann)) {
return uiConstants.TAB_ORPHANS; return uiConstants.TAB_ORPHANS;
} else if (metadata.isPageNote(ann)) { } else if (metadata.isPageNote(ann)) {
...@@ -24,7 +25,7 @@ function tabForAnnotation(ann) { ...@@ -24,7 +25,7 @@ function tabForAnnotation(ann) {
* @param {Annotation} ann * @param {Annotation} ann
* @param {number} tab - The TAB_* value indicating the tab * @param {number} tab - The TAB_* value indicating the tab
*/ */
function shouldShowInTab(ann, tab) { export function shouldShowInTab(ann, tab) {
if (metadata.isWaitingToAnchor(ann)) { if (metadata.isWaitingToAnchor(ann)) {
// Until this annotation anchors or fails to anchor, we do not know which // Until this annotation anchors or fails to anchor, we do not know which
// tab it should be displayed in. // tab it should be displayed in.
...@@ -32,8 +33,3 @@ function shouldShowInTab(ann, tab) { ...@@ -32,8 +33,3 @@ function shouldShowInTab(ann, tab) {
} }
return tabForAnnotation(ann) === tab; return tabForAnnotation(ann) === tab;
} }
module.exports = {
shouldShowInTab: shouldShowInTab,
tabForAnnotation: tabForAnnotation,
};
const { parseAccountID, username, isThirdPartyUser } = require('../account-id'); import { parseAccountID, username, isThirdPartyUser } from '../account-id';
describe('sidebar.util.account-id', function() { describe('sidebar.util.account-id', function() {
const term = 'acct:hacker@example.com'; const term = 'acct:hacker@example.com';
......
const annotationMetadata = require('../annotation-metadata'); import * as fixtures from '../../test/annotation-fixtures';
const fixtures = require('../../test/annotation-fixtures'); import * as annotationMetadata from '../annotation-metadata';
const documentMetadata = annotationMetadata.documentMetadata; const documentMetadata = annotationMetadata.documentMetadata;
const domainAndTitle = annotationMetadata.domainAndTitle; const domainAndTitle = annotationMetadata.domainAndTitle;
......
const sharingUtil = require('../annotation-sharing'); import * as sharingUtil from '../annotation-sharing';
describe('sidebar.util.annotation-sharing', () => { describe('sidebar.util.annotation-sharing', () => {
let fakeAnnotation; let fakeAnnotation;
......
const { copyText } = require('../copy-to-clipboard'); import { copyText } from '../copy-to-clipboard';
describe('copy-to-clipboard', () => { describe('copy-to-clipboard', () => {
beforeEach(() => { beforeEach(() => {
......
const disableOpenerForExternalLinks = require('../disable-opener-for-external-links'); import disableOpenerForExternalLinks from '../disable-opener-for-external-links';
describe('sidebar.util.disable-opener-for-external-links', () => { describe('sidebar.util.disable-opener-for-external-links', () => {
let containerEl; let containerEl;
......
const { listen } = require('../dom'); import { listen } from '../dom';
describe('sidebar/util/dom', () => { describe('sidebar/util/dom', () => {
const createElement = () => ({ const createElement = () => ({
......
class FakeWindow { export default class FakeWindow {
constructor() { constructor() {
this.callbacks = []; this.callbacks = [];
...@@ -49,5 +49,3 @@ class FakeWindow { ...@@ -49,5 +49,3 @@ class FakeWindow {
this.trigger(evt); this.trigger(evt);
} }
} }
module.exports = FakeWindow;
const { import { assertPromiseIsRejected } from '../../../shared/test/promise-util';
assertPromiseIsRejected, import { fetchConfig, $imports } from '../fetch-config';
} = require('../../../shared/test/promise-util');
const { fetchConfig, $imports } = require('../fetch-config');
describe('sidebar.util.fetch-config', () => { describe('sidebar.util.fetch-config', () => {
let fakeHostConfig; let fakeHostConfig;
......
const groupListItemCommon = require('../group-list-item-common'); import { events } from '../../services/analytics';
import * as groupListItemCommon from '../group-list-item-common';
const { events } = require('../../services/analytics');
describe('sidebar/util/groupListItemCommon', () => { describe('sidebar/util/groupListItemCommon', () => {
describe('trackViewGroupActivity', () => { describe('trackViewGroupActivity', () => {
......
const groupsByOrganization = require('../group-organizations'); import * as orgFixtures from '../../test/group-fixtures';
const orgFixtures = require('../../test/group-fixtures'); import groupsByOrganization from '../group-organizations';
describe('group-organizations', function() { describe('group-organizations', function() {
context('when sorting organizations and their contained groups', function() { context('when sorting organizations and their contained groups', function() {
......
const { combineGroups } = require('../groups'); import { combineGroups } from '../groups';
describe('sidebar.util.groups', () => { describe('sidebar.util.groups', () => {
describe('combineGroups', () => { describe('combineGroups', () => {
......
const isSidebar = require('../is-sidebar'); import isSidebar from '../is-sidebar';
describe('sidebar.utils.is-sidebar', () => { describe('sidebar.utils.is-sidebar', () => {
[ [
......
const isThirdPartyService = require('../is-third-party-service'); import isThirdPartyService from '../is-third-party-service';
const { $imports } = require('../is-third-party-service'); import { $imports } from '../is-third-party-service';
describe('sidebar.util.isThirdPartyService', () => { describe('sidebar.util.isThirdPartyService', () => {
let fakeServiceConfig; let fakeServiceConfig;
......
const memoize = require('../memoize'); import memoize from '../memoize';
describe('memoize', function() { describe('memoize', function() {
let count = 0; let count = 0;
......
const fetchMock = require('fetch-mock'); import fetchMock from 'fetch-mock';
const { stringify } = require('query-string'); import { stringify } from 'query-string';
const sinon = require('sinon'); import sinon from 'sinon';
const OAuthClient = require('../oauth-client'); import OAuthClient from '../oauth-client';
const FakeWindow = require('./fake-window');
import FakeWindow from './fake-window';
const fixtures = { const fixtures = {
tokenResponse: { tokenResponse: {
......
const observeElementSize = require('../observe-element-size'); import observeElementSize from '../observe-element-size';
/** /**
* Wait for a condition to become true. * Wait for a condition to become true.
......
const EventEmitter = require('tiny-emitter'); import EventEmitter from 'tiny-emitter';
const { import { assertPromiseIsRejected } from '../../../shared/test/promise-util';
assertPromiseIsRejected, import { call } from '../postmessage-json-rpc';
} = require('../../../shared/test/promise-util');
const { call } = require('../postmessage-json-rpc');
class FakeWindow { class FakeWindow {
constructor() { constructor() {
......
const random = require('../random'); import * as random from '../random';
describe('sidebar.util.random', () => { describe('sidebar.util.random', () => {
describe('#generateHexString', () => { describe('#generateHexString', () => {
......
const retryUtil = require('../retry'); import { toResult } from '../../../shared/test/promise-util';
const { toResult } = require('../../../shared/test/promise-util'); import * as retryUtil from '../retry';
describe('sidebar.util.retry', function() { describe('sidebar.util.retry', function() {
describe('.retryPromiseOperation', function() { describe('.retryPromiseOperation', function() {
......
const scopeTimeout = require('../scope-timeout'); import scopeTimeout from '../scope-timeout';
function FakeScope() { function FakeScope() {
this.listeners = {}; this.listeners = {};
......
const sentry = require('../sentry'); import * as sentry from '../sentry';
describe('sidebar/util/sentry', () => { describe('sidebar/util/sentry', () => {
let fakeDocumentReferrer; let fakeDocumentReferrer;
......
const { mount } = require('enzyme'); import { mount } from 'enzyme';
const propTypes = require('prop-types'); import { createElement, render } from 'preact';
const { createElement, render } = require('preact'); import propTypes from 'prop-types';
const { import { ServiceContext, withServices, useService } from '../service-context';
ServiceContext,
withServices,
useService,
} = require('../service-context');
describe('service-context', () => { describe('service-context', () => {
describe('withServices', () => { describe('withServices', () => {
......
const sessionUtil = require('../session'); import * as sessionUtil from '../session';
describe('sidebar/util/session', () => { describe('sidebar/util/session', () => {
describe('#shouldShowSidebarTutorial', () => { describe('#shouldShowSidebarTutorial', () => {
......
const fakeStore = require('../../test/fake-redux-store'); import fakeStore from '../../test/fake-redux-store';
const stateUtil = require('../state'); import * as stateUtil from '../state';
describe('sidebar/util/state', function() { describe('sidebar/util/state', function() {
let store; let store;
......
const fixtures = require('../../test/annotation-fixtures'); import * as fixtures from '../../test/annotation-fixtures';
const uiConstants = require('../../ui-constants'); import uiConstants from '../../ui-constants';
const tabs = require('../tabs'); import * as tabs from '../tabs';
describe('tabs', function() { describe('tabs', function() {
describe('tabForAnnotation', function() { describe('tabForAnnotation', function() {
......
const { applyTheme } = require('../theme'); import { applyTheme } from '../theme';
describe('sidebar/util/theme/applyTheme', () => { describe('sidebar/util/theme/applyTheme', () => {
let fakeSettings; let fakeSettings;
......
const time = require('../time'); import * as time from '../time';
const second = 1000; const second = 1000;
const minute = second * 60; const minute = second * 60;
......
const urlUtil = require('../url'); import * as urlUtil from '../url';
describe('sidebar/util/url', function() { describe('sidebar/util/url', function() {
describe('replaceURLParams()', function() { describe('replaceURLParams()', function() {
......
const VersionData = require('../version-data'); import VersionData from '../version-data';
describe('VersionData', () => { describe('VersionData', () => {
let clock; let clock;
......
const angular = require('angular'); import angular from 'angular';
const { Component, createElement } = require('preact'); import { Component, createElement } from 'preact';
const { useContext } = require('preact/hooks'); import { useContext } from 'preact/hooks';
const propTypes = require('prop-types'); import propTypes from 'prop-types';
const { ServiceContext } = require('../service-context'); import { createDirective } from '../../directive/test/util';
const wrapReactComponent = require('../wrap-react-component'); import { ServiceContext } from '../service-context';
const { createDirective } = require('../../directive/test/util'); import wrapReactComponent from '../wrap-react-component';
// Saved `onDblClick` prop from last render of `Button`. // Saved `onDblClick` prop from last render of `Button`.
// This makes it easy to call it with different arguments. // This makes it easy to call it with different arguments.
......
...@@ -45,7 +45,7 @@ const supportedThemeProperties = { ...@@ -45,7 +45,7 @@ const supportedThemeProperties = {
* // only one of those has a value in the `settings` object, so: * // only one of those has a value in the `settings` object, so:
* applyTheme(themeProperties, settings); // -> { color: '#ffc '} * applyTheme(themeProperties, settings); // -> { color: '#ffc '}
*/ */
function applyTheme(themeProperties, settings) { export function applyTheme(themeProperties, settings) {
const style = {}; const style = {};
if (!settings.branding) { if (!settings.branding) {
return style; return style;
...@@ -61,7 +61,3 @@ function applyTheme(themeProperties, settings) { ...@@ -61,7 +61,3 @@ function applyTheme(themeProperties, settings) {
return style; return style;
} }
module.exports = {
applyTheme,
};
...@@ -14,7 +14,7 @@ let formatters = {}; ...@@ -14,7 +14,7 @@ let formatters = {};
/** /**
* Clears the cache of formatters. * Clears the cache of formatters.
*/ */
function clearFormatters() { export function clearFormatters() {
formatters = {}; formatters = {};
} }
...@@ -166,7 +166,7 @@ function getBreakpoint(date, now) { ...@@ -166,7 +166,7 @@ function getBreakpoint(date, now) {
* @return {Number|null} - ms until next update or `null` if no update * @return {Number|null} - ms until next update or `null` if no update
* should occur * should occur
*/ */
function nextFuzzyUpdate(date, now) { export function nextFuzzyUpdate(date, now) {
if (!date) { if (!date) {
return null; return null;
} }
...@@ -199,7 +199,7 @@ function nextFuzzyUpdate(date, now) { ...@@ -199,7 +199,7 @@ function nextFuzzyUpdate(date, now) {
* @param {UpdateCallback} callback - A callback function to call when the timestamp changes. * @param {UpdateCallback} callback - A callback function to call when the timestamp changes.
* @return {Function} A function that cancels the automatic refresh. * @return {Function} A function that cancels the automatic refresh.
*/ */
function decayingInterval(date, callback) { export function decayingInterval(date, callback) {
let timer; let timer;
const timeStamp = date ? new Date(date) : null; const timeStamp = date ? new Date(date) : null;
...@@ -235,16 +235,9 @@ function decayingInterval(date, callback) { ...@@ -235,16 +235,9 @@ function decayingInterval(date, callback) {
* param is present for dependency injection during test. * param is present for dependency injection during test.
* @return {string} A 'fuzzy' string describing the relative age of the date. * @return {string} A 'fuzzy' string describing the relative age of the date.
*/ */
function toFuzzyString(date, now, Intl) { export function toFuzzyString(date, now, Intl) {
if (!date) { if (!date) {
return ''; return '';
} }
return getBreakpoint(date, now).formatFn(date, now, Intl); return getBreakpoint(date, now).formatFn(date, now, Intl);
} }
module.exports = {
clearFormatters: clearFormatters, // For testing
decayingInterval: decayingInterval,
nextFuzzyUpdate: nextFuzzyUpdate, // For testing
toFuzzyString: toFuzzyString,
};
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* replaceURLParams('/things/:id', {id: 'foo', q: 'bar'}) => * replaceURLParams('/things/:id', {id: 'foo', q: 'bar'}) =>
* {url: '/things/foo', params: {q: 'bar'}} * {url: '/things/foo', params: {q: 'bar'}}
*/ */
function replaceURLParams(url, params) { export function replaceURLParams(url, params) {
const unusedParams = {}; const unusedParams = {};
for (const param in params) { for (const param in params) {
if (params.hasOwnProperty(param)) { if (params.hasOwnProperty(param)) {
...@@ -29,11 +29,6 @@ function replaceURLParams(url, params) { ...@@ -29,11 +29,6 @@ function replaceURLParams(url, params) {
* @param {string} relativeURL * @param {string} relativeURL
* @param {string} baseURL * @param {string} baseURL
*/ */
function resolve(relativeURL, baseURL) { export function resolve(relativeURL, baseURL) {
return new URL(relativeURL, baseURL).href; return new URL(relativeURL, baseURL).href;
} }
module.exports = {
replaceURLParams: replaceURLParams,
resolve: resolve,
};
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
* @property {DocMetadata} metadata - document metadata * @property {DocMetadata} metadata - document metadata
*/ */
class VersionData { export default class VersionData {
/** /**
* @param {UserInfo} userInfo * @param {UserInfo} userInfo
* @param {DocumentInfo} documentInfo * @param {DocumentInfo} documentInfo
...@@ -78,5 +78,3 @@ class VersionData { ...@@ -78,5 +78,3 @@ class VersionData {
return encodeURIComponent(this.asFormattedString()); return encodeURIComponent(this.asFormattedString());
} }
} }
module.exports = VersionData;
const { createElement, render } = require('preact'); import { createElement, render } from 'preact';
const { ServiceContext } = require('./service-context');
import { ServiceContext } from './service-context';
function useExpressionBinding(propName) { function useExpressionBinding(propName) {
return propName.match(/^on[A-Z]/); return propName.match(/^on[A-Z]/);
...@@ -109,7 +110,7 @@ class ReactController { ...@@ -109,7 +110,7 @@ class ReactController {
* @return {Object} - * @return {Object} -
* An AngularJS component spec for use with `angular.component(...)` * An AngularJS component spec for use with `angular.component(...)`
*/ */
function wrapReactComponent(type) { export default function wrapReactComponent(type) {
if (!type.propTypes) { if (!type.propTypes) {
throw new Error( throw new Error(
`React component ${type.name} does not specify its inputs using "propTypes"` `React component ${type.name} does not specify its inputs using "propTypes"`
...@@ -135,5 +136,3 @@ function wrapReactComponent(type) { ...@@ -135,5 +136,3 @@ function wrapReactComponent(type) {
controller: createController, controller: createController,
}; };
} }
module.exports = wrapReactComponent;
const EventEmitter = require('tiny-emitter'); import debounce from 'lodash.debounce';
const debounce = require('lodash.debounce'); import EventEmitter from 'tiny-emitter';
/** /**
* @typedef Options * @typedef Options
...@@ -24,7 +24,7 @@ const debounce = require('lodash.debounce'); ...@@ -24,7 +24,7 @@ const debounce = require('lodash.debounce');
* the number of watchers (functions created by template expressions or * the number of watchers (functions created by template expressions or
* '$scope.$watch' calls) that have to be run on every '$scope.$digest()' cycle. * '$scope.$watch' calls) that have to be run on every '$scope.$digest()' cycle.
*/ */
class VirtualThreadList extends EventEmitter { export default class VirtualThreadList extends EventEmitter {
/* /*
* @param {Window} container - The Window displaying the list of annotation threads. * @param {Window} container - The Window displaying the list of annotation threads.
* @param {Thread} rootThread - The initial Thread object for the top-level * @param {Thread} rootThread - The initial Thread object for the top-level
...@@ -211,5 +211,3 @@ class VirtualThreadList extends EventEmitter { ...@@ -211,5 +211,3 @@ class VirtualThreadList extends EventEmitter {
}; };
} }
} }
module.exports = VirtualThreadList;
const retry = require('retry'); import retry from 'retry';
const EventEmitter = require('tiny-emitter'); import EventEmitter from 'tiny-emitter';
// see https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent // see https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent
const CLOSE_NORMAL = 1000; const CLOSE_NORMAL = 1000;
...@@ -16,7 +16,7 @@ const RECONNECT_MIN_DELAY = 1000; ...@@ -16,7 +16,7 @@ const RECONNECT_MIN_DELAY = 1000;
* - Uses the standard EventEmitter API for reporting open, close, error * - Uses the standard EventEmitter API for reporting open, close, error
* and message events. * and message events.
*/ */
class Socket extends EventEmitter { export default class Socket extends EventEmitter {
constructor(url) { constructor(url) {
super(); super();
...@@ -131,5 +131,3 @@ class Socket extends EventEmitter { ...@@ -131,5 +131,3 @@ class Socket extends EventEmitter {
connect(); connect();
} }
} }
module.exports = Socket;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment