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