UNPKG

@atlaskit/editor-plugin-interactivity

Version:

Interactivity plugin for @atlaskit/editor-core

105 lines (102 loc) 5.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.interactivityPlugin = void 0; var _react = require("react"); var _monitoring = require("@atlaskit/editor-common/monitoring"); var _fireInteractivityEvent = require("./analytics/fire-interactivity-event"); var _interactivityCollector = require("./collector/interactivity-collector"); /** * Reports session-to-date interaction latency distributions for full page editor sessions * as the `editor interactivity` operational event. * * The session runs for as long as the plugin's hook stays mounted, which is one editor * mount: `MountPluginHooks` in editor-core keys hook fibers by plugin name, so a preset * reconfigure — which destroys and recreates ProseMirror plugin views — leaves this hook, * and the session, in place. */ var interactivityPlugin = exports.interactivityPlugin = function interactivityPlugin(_ref) { var api = _ref.api; return { name: 'interactivity', usePluginHook: function usePluginHook(_ref2) { var editorView = _ref2.editorView, wrapperElement = _ref2.wrapperElement; var collectorRef = (0, _react.useRef)(undefined); (0, _react.useEffect)(function () { try { var _api$contextIdentifie2, _api$editorViewMode2; var collector = new _interactivityCollector.InteractivityCollector({ emit: function emit(snapshot) { var _api$analytics; return (0, _fireInteractivityEvent.fireInteractivityEvent)(api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions, snapshot); }, getObjectId: function getObjectId() { var _api$contextIdentifie; return api === null || api === void 0 || (_api$contextIdentifie = api.contextIdentifier) === null || _api$contextIdentifie === void 0 || (_api$contextIdentifie = _api$contextIdentifie.sharedState.currentState()) === null || _api$contextIdentifie === void 0 || (_api$contextIdentifie = _api$contextIdentifie.contextIdentifierProvider) === null || _api$contextIdentifie === void 0 ? void 0 : _api$contextIdentifie.objectId; }, getSessionMode: function getSessionMode() { var _api$editorViewMode; var mode = api === null || api === void 0 || (_api$editorViewMode = api.editorViewMode) === null || _api$editorViewMode === void 0 || (_api$editorViewMode = _api$editorViewMode.sharedState.currentState()) === null || _api$editorViewMode === void 0 ? void 0 : _api$editorViewMode.mode; if (mode === undefined) { return undefined; } return mode === 'view' ? 'reading' : 'editing'; }, // A destroyed view still answers, with the document it was destroyed with, so // both report nothing rather than a size the editor no longer has. getNodeSize: function getNodeSize() { return editorView.isDestroyed ? undefined : editorView.state.doc.nodeSize; }, // `getElementsByTagName` counts descendants in the browser engine, so this // cannot overflow the stack on very large documents. getEditorDomSize: function getEditorDomSize() { return editorView.isDestroyed ? undefined : editorView.dom.getElementsByTagName('*').length; } }); // Effects run in declaration order, so the one below always finds it. collectorRef.current = collector; if (!collector.start()) { return; } // Confluence live pages navigate and switch between reading and editing without // remounting the editor. A session covers one document in one mode, so either // change ends it and starts the next. var unsubscribeFromObjectId = api === null || api === void 0 || (_api$contextIdentifie2 = api.contextIdentifier) === null || _api$contextIdentifie2 === void 0 ? void 0 : _api$contextIdentifie2.sharedState.onChange(function () { return collector.onObjectIdChanged(); }); var unsubscribeFromViewMode = api === null || api === void 0 || (_api$editorViewMode2 = api.editorViewMode) === null || _api$editorViewMode2 === void 0 ? void 0 : _api$editorViewMode2.sharedState.onChange(function () { return collector.onViewModeChanged(); }); return function () { unsubscribeFromObjectId === null || unsubscribeFromObjectId === void 0 || unsubscribeFromObjectId(); unsubscribeFromViewMode === null || unsubscribeFromViewMode === void 0 || unsubscribeFromViewMode(); collector.stop(); }; } catch (error) { // Instrumentation must not fail the editor around it, but a failure that hits every // browser of one engine would be invisible without this. void (0, _monitoring.logException)(error, { location: 'editor-plugin-interactivity/start' }); return; } // `api` is deliberately not a dependency: a preset reconfigure hands out a new // proxy object, but the one captured here keeps resolving plugins from the same // live registry, and restarting the session on a reconfigure would split one // editor session in two. }, [editorView]); (0, _react.useEffect)(function () { try { var _collectorRef$current; (_collectorRef$current = collectorRef.current) === null || _collectorRef$current === void 0 || _collectorRef$current.setEditorRoot(wrapperElement); } catch (error) { void (0, _monitoring.logException)(error, { location: 'editor-plugin-interactivity/observe' }); } }, [wrapperElement]); } }; };