| 1 |
- {"version":3,"file":"hackmd-agent.cjs","sources":["../../../node_modules/penpal/lib/constants.js","../../../node_modules/penpal/lib/errorCodes.js","../../../node_modules/penpal/lib/createDestructor.js","../../../node_modules/penpal/lib/errorSerialization.js","../../../node_modules/penpal/lib/connectCallReceiver.js","../../../node_modules/penpal/lib/generateId.js","../../../node_modules/penpal/lib/connectCallSender.js","../../../node_modules/penpal/lib/createLogger.js","../../../node_modules/penpal/lib/connectToParent.js","../../../node_modules/throttle-debounce/esm/index.js","../src/hackmd-agent.js"],"sourcesContent":["\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.DATA_CLONE_ERROR = exports.MESSAGE = exports.REJECTED = exports.FULFILLED = exports.REPLY = exports.CALL = exports.HANDSHAKE_REPLY = exports.HANDSHAKE = void 0;\nconst HANDSHAKE = 'handshake';\nexports.HANDSHAKE = HANDSHAKE;\nconst HANDSHAKE_REPLY = 'handshake-reply';\nexports.HANDSHAKE_REPLY = HANDSHAKE_REPLY;\nconst CALL = 'call';\nexports.CALL = CALL;\nconst REPLY = 'reply';\nexports.REPLY = REPLY;\nconst FULFILLED = 'fulfilled';\nexports.FULFILLED = FULFILLED;\nconst REJECTED = 'rejected';\nexports.REJECTED = REJECTED;\nconst MESSAGE = 'message';\nexports.MESSAGE = MESSAGE;\nconst DATA_CLONE_ERROR = 'DataCloneError';\nexports.DATA_CLONE_ERROR = DATA_CLONE_ERROR;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.ERR_NO_IFRAME_SRC = exports.ERR_NOT_IN_IFRAME = exports.ERR_CONNECTION_TIMEOUT = exports.ERR_CONNECTION_DESTROYED = void 0;\nconst ERR_CONNECTION_DESTROYED = 'ConnectionDestroyed';\nexports.ERR_CONNECTION_DESTROYED = ERR_CONNECTION_DESTROYED;\nconst ERR_CONNECTION_TIMEOUT = 'ConnectionTimeout';\nexports.ERR_CONNECTION_TIMEOUT = ERR_CONNECTION_TIMEOUT;\nconst ERR_NOT_IN_IFRAME = 'NotInIframe';\nexports.ERR_NOT_IN_IFRAME = ERR_NOT_IN_IFRAME;\nconst ERR_NO_IFRAME_SRC = 'NoIframeSrc';\nexports.ERR_NO_IFRAME_SRC = ERR_NO_IFRAME_SRC;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _default = () => {\n const callbacks = [];\n let destroyed = false;\n return {\n destroy() {\n destroyed = true;\n callbacks.forEach(callback => {\n callback();\n });\n },\n\n onDestroy(callback) {\n destroyed ? callback() : callbacks.push(callback);\n }\n\n };\n};\n\nexports.default = _default;\nmodule.exports = exports.default;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.deserializeError = exports.serializeError = void 0;\n\n/**\n * Converts an error object into a plain object.\n * @param {Error} Error object.\n * @returns {Object}\n */\nconst serializeError = (_ref) => {\n let name = _ref.name,\n message = _ref.message,\n stack = _ref.stack;\n return {\n name,\n message,\n stack\n };\n};\n/**\n * Converts a plain object into an error object.\n * @param {Object} Object with error properties.\n * @returns {Error}\n */\n\n\nexports.serializeError = serializeError;\n\nconst deserializeError = obj => {\n const deserializedError = new Error();\n Object.keys(obj).forEach(key => deserializedError[key] = obj[key]);\n return deserializedError;\n};\n\nexports.deserializeError = deserializeError;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _constants = require(\"./constants\");\n\nvar _errorSerialization = require(\"./errorSerialization\");\n\n/**\n * Listens for \"call\" messages coming from the remote, executes the corresponding method, and\n * responds with the return value.\n * @param {Object} info Information about the local and remote windows.\n * @param {Object} methods The keys are the names of the methods that can be called by the remote\n * while the values are the method functions.\n * @param {Promise} destructionPromise A promise resolved when destroy() is called on the penpal\n * connection.\n * @returns {Function} A function that may be called to disconnect the receiver.\n */\nvar _default = (info, methods, log) => {\n const localName = info.localName,\n local = info.local,\n remote = info.remote,\n originForSending = info.originForSending,\n originForReceiving = info.originForReceiving;\n let destroyed = false;\n log(`${localName}: Connecting call receiver`);\n\n const handleMessageEvent = event => {\n if (event.source !== remote || event.data.penpal !== _constants.CALL) {\n return;\n }\n\n if (event.origin !== originForReceiving) {\n log(`${localName} received message from origin ${event.origin} which did not match expected origin ${originForReceiving}`);\n return;\n }\n\n const _event$data = event.data,\n methodName = _event$data.methodName,\n args = _event$data.args,\n id = _event$data.id;\n log(`${localName}: Received ${methodName}() call`);\n\n const createPromiseHandler = resolution => {\n return returnValue => {\n log(`${localName}: Sending ${methodName}() reply`);\n\n if (destroyed) {\n // It's possible to throw an error here, but it would need to be thrown asynchronously\n // and would only be catchable using window.onerror. This is because the consumer\n // is merely returning a value from their method and not calling any function\n // that they could wrap in a try-catch. Even if the consumer were to catch the error,\n // the value of doing so is questionable. Instead, we'll just log a message.\n log(`${localName}: Unable to send ${methodName}() reply due to destroyed connection`);\n return;\n }\n\n const message = {\n penpal: _constants.REPLY,\n id,\n resolution,\n returnValue\n };\n\n if (resolution === _constants.REJECTED && returnValue instanceof Error) {\n message.returnValue = (0, _errorSerialization.serializeError)(returnValue);\n message.returnValueIsError = true;\n }\n\n try {\n remote.postMessage(message, originForSending);\n } catch (err) {\n // If a consumer attempts to send an object that's not cloneable (e.g., window),\n // we want to ensure the receiver's promise gets rejected.\n if (err.name === _constants.DATA_CLONE_ERROR) {\n remote.postMessage({\n penpal: _constants.REPLY,\n id,\n resolution: _constants.REJECTED,\n returnValue: (0, _errorSerialization.serializeError)(err),\n returnValueIsError: true\n }, originForSending);\n }\n\n throw err;\n }\n };\n };\n\n new Promise(resolve => resolve(methods[methodName].apply(methods, args))).then(createPromiseHandler(_constants.FULFILLED), createPromiseHandler(_constants.REJECTED));\n };\n\n local.addEventListener(_constants.MESSAGE, handleMessageEvent);\n return () => {\n destroyed = true;\n local.removeEventListener(_constants.MESSAGE, handleMessageEvent);\n };\n};\n\nexports.default = _default;\nmodule.exports = exports.default;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\nlet id = 0;\n/**\n * @return {number} A unique ID (not universally unique)\n */\n\nvar _default = () => ++id;\n\nexports.default = _default;\nmodule.exports = exports.default;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _constants = require(\"./constants\");\n\nvar _errorCodes = require(\"./errorCodes\");\n\nvar _generateId = _interopRequireDefault(require(\"./generateId\"));\n\nvar _errorSerialization = require(\"./errorSerialization\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/**\n * Augments an object with methods that match those defined by the remote. When these methods are\n * called, a \"call\" message will be sent to the remote, the remote's corresponding method will be\n * executed, and the method's return value will be returned via a message.\n * @param {Object} callSender Sender object that should be augmented with methods.\n * @param {Object} info Information about the local and remote windows.\n * @param {Array} methodNames Names of methods available to be called on the remote.\n * @param {Promise} destructionPromise A promise resolved when destroy() is called on the penpal\n * connection.\n * @returns {Object} The call sender object with methods that may be called.\n */\nvar _default = (callSender, info, methodNames, destroyConnection, log) => {\n const localName = info.localName,\n local = info.local,\n remote = info.remote,\n originForSending = info.originForSending,\n originForReceiving = info.originForReceiving;\n let destroyed = false;\n log(`${localName}: Connecting call sender`);\n\n const createMethodProxy = methodName => {\n return function () {\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n log(`${localName}: Sending ${methodName}() call`); // This handles the case where the iframe has been removed from the DOM\n // (and therefore its window closed), the consumer has not yet\n // called destroy(), and the user calls a method exposed by\n // the remote. We detect the iframe has been removed and force\n // a destroy() immediately so that the consumer sees the error saying\n // the connection has been destroyed. We wrap this check in a try catch\n // because Edge throws an \"Object expected\" error when accessing\n // contentWindow.closed on a contentWindow from an iframe that's been\n // removed from the DOM.\n\n let iframeRemoved;\n\n try {\n if (remote.closed) {\n iframeRemoved = true;\n }\n } catch (e) {\n iframeRemoved = true;\n }\n\n if (iframeRemoved) {\n destroyConnection();\n }\n\n if (destroyed) {\n const error = new Error(`Unable to send ${methodName}() call due ` + `to destroyed connection`);\n error.code = _errorCodes.ERR_CONNECTION_DESTROYED;\n throw error;\n }\n\n return new Promise((resolve, reject) => {\n const id = (0, _generateId.default)();\n\n const handleMessageEvent = event => {\n if (event.source !== remote || event.data.penpal !== _constants.REPLY || event.data.id !== id) {\n return;\n }\n\n if (event.origin !== originForReceiving) {\n log(`${localName} received message from origin ${event.origin} which did not match expected origin ${originForReceiving}`);\n return;\n }\n\n log(`${localName}: Received ${methodName}() reply`);\n local.removeEventListener(_constants.MESSAGE, handleMessageEvent);\n let returnValue = event.data.returnValue;\n\n if (event.data.returnValueIsError) {\n returnValue = (0, _errorSerialization.deserializeError)(returnValue);\n }\n\n (event.data.resolution === _constants.FULFILLED ? resolve : reject)(returnValue);\n };\n\n local.addEventListener(_constants.MESSAGE, handleMessageEvent);\n remote.postMessage({\n penpal: _constants.CALL,\n id,\n methodName,\n args\n }, originForSending);\n });\n };\n };\n\n methodNames.reduce((api, methodName) => {\n api[methodName] = createMethodProxy(methodName);\n return api;\n }, callSender);\n return () => {\n destroyed = true;\n };\n};\n\nexports.default = _default;\nmodule.exports = exports.default;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _default = debug => {\n return function () {\n if (debug) {\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n console.log('[Penpal]', ...args); // eslint-disable-line no-console\n }\n };\n};\n\nexports.default = _default;\nmodule.exports = exports.default;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _constants = require(\"./constants\");\n\nvar _errorCodes = require(\"./errorCodes\");\n\nvar _createDestructor2 = _interopRequireDefault(require(\"./createDestructor\"));\n\nvar _connectCallReceiver = _interopRequireDefault(require(\"./connectCallReceiver\"));\n\nvar _connectCallSender = _interopRequireDefault(require(\"./connectCallSender\"));\n\nvar _createLogger = _interopRequireDefault(require(\"./createLogger\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/**\n * @typedef {Object} Parent\n * @property {Promise} promise A promise which will be resolved once a connection has\n * been established.\n */\n\n/**\n * Attempts to establish communication with the parent window.\n * @param {Object} options\n * @param {string} [options.parentOrigin=*] Valid parent origin used to restrict communication.\n * @param {Object} [options.methods={}] Methods that may be called by the parent window.\n * @param {Number} [options.timeout] The amount of time, in milliseconds, Penpal should wait\n * for the parent to respond before rejecting the connection promise.\n * @return {Parent}\n */\nvar _default = function _default() {\n let _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n _ref$parentOrigin = _ref.parentOrigin,\n parentOrigin = _ref$parentOrigin === void 0 ? '*' : _ref$parentOrigin,\n _ref$methods = _ref.methods,\n methods = _ref$methods === void 0 ? {} : _ref$methods,\n timeout = _ref.timeout,\n debug = _ref.debug;\n\n const log = (0, _createLogger.default)(debug);\n\n if (window === window.top) {\n const error = new Error('connectToParent() must be called within an iframe');\n error.code = _errorCodes.ERR_NOT_IN_IFRAME;\n throw error;\n }\n\n const _createDestructor = (0, _createDestructor2.default)(),\n destroy = _createDestructor.destroy,\n onDestroy = _createDestructor.onDestroy;\n\n const child = window;\n const parent = child.parent;\n const promise = new Promise((resolveConnectionPromise, reject) => {\n let connectionTimeoutId;\n\n if (timeout !== undefined) {\n connectionTimeoutId = setTimeout(() => {\n const error = new Error(`Connection to parent timed out after ${timeout}ms`);\n error.code = _errorCodes.ERR_CONNECTION_TIMEOUT;\n reject(error);\n destroy();\n }, timeout);\n }\n\n const handleMessageEvent = event => {\n // Under niche scenarios, we get into this function after\n // the iframe has been removed from the DOM. In Edge, this\n // results in \"Object expected\" errors being thrown when we\n // try to access properties on window (global properties).\n // For this reason, we try to access a global up front (clearTimeout)\n // and if it fails we can assume the iframe has been removed\n // and we ignore the message event.\n try {\n clearTimeout();\n } catch (e) {\n return;\n }\n\n if (event.source !== parent || event.data.penpal !== _constants.HANDSHAKE_REPLY) {\n return;\n }\n\n if (parentOrigin !== '*' && parentOrigin !== event.origin) {\n log(`Child received handshake reply from origin ${event.origin} which did not match expected origin ${parentOrigin}`);\n return;\n }\n\n log('Child: Received handshake reply');\n child.removeEventListener(_constants.MESSAGE, handleMessageEvent);\n const info = {\n localName: 'Child',\n local: child,\n remote: parent,\n originForSending: event.origin === 'null' ? '*' : event.origin,\n originForReceiving: event.origin\n };\n const callSender = {};\n const destroyCallReceiver = (0, _connectCallReceiver.default)(info, methods, log);\n onDestroy(destroyCallReceiver);\n const destroyCallSender = (0, _connectCallSender.default)(callSender, info, event.data.methodNames, destroy, log);\n onDestroy(destroyCallSender);\n clearTimeout(connectionTimeoutId);\n resolveConnectionPromise(callSender);\n };\n\n child.addEventListener(_constants.MESSAGE, handleMessageEvent);\n onDestroy(() => {\n child.removeEventListener(_constants.MESSAGE, handleMessageEvent);\n const error = new Error('Connection destroyed');\n error.code = _errorCodes.ERR_CONNECTION_DESTROYED;\n reject(error);\n });\n log('Child: Sending handshake');\n parent.postMessage({\n penpal: _constants.HANDSHAKE,\n methodNames: Object.keys(methods)\n }, parentOrigin);\n });\n return {\n promise,\n destroy\n };\n};\n\nexports.default = _default;\nmodule.exports = exports.default;","/* eslint-disable no-undefined,no-param-reassign,no-shadow */\n\n/**\n * Throttle execution of a function. Especially useful for rate limiting\n * execution of handlers on events like resize and scroll.\n *\n * @param {number} delay - A zero-or-greater delay in milliseconds. For event callbacks, values around 100 or 250 (or even higher)\n * are most useful.\n * @param {Function} callback - A function to be executed after delay milliseconds. The `this` context and all arguments are passed through,\n * as-is, to `callback` when the throttled-function is executed.\n * @param {object} [options] - An object to configure options.\n * @param {boolean} [options.noTrailing] - Optional, defaults to false. If noTrailing is true, callback will only execute every `delay` milliseconds\n * while the throttled-function is being called. If noTrailing is false or unspecified, callback will be executed\n * one final time after the last throttled-function call. (After the throttled-function has not been called for\n * `delay` milliseconds, the internal counter is reset).\n * @param {boolean} [options.noLeading] - Optional, defaults to false. If noLeading is false, the first throttled-function call will execute callback\n * immediately. If noLeading is true, the first the callback execution will be skipped. It should be noted that\n * callback will never executed if both noLeading = true and noTrailing = true.\n * @param {boolean} [options.debounceMode] - If `debounceMode` is true (at begin), schedule `clear` to execute after `delay` ms. If `debounceMode` is\n * false (at end), schedule `callback` to execute after `delay` ms.\n *\n * @returns {Function} A new, throttled, function.\n */\nfunction throttle (delay, callback, options) {\n var _ref = options || {},\n _ref$noTrailing = _ref.noTrailing,\n noTrailing = _ref$noTrailing === void 0 ? false : _ref$noTrailing,\n _ref$noLeading = _ref.noLeading,\n noLeading = _ref$noLeading === void 0 ? false : _ref$noLeading,\n _ref$debounceMode = _ref.debounceMode,\n debounceMode = _ref$debounceMode === void 0 ? undefined : _ref$debounceMode;\n /*\n * After wrapper has stopped being called, this timeout ensures that\n * `callback` is executed at the proper times in `throttle` and `end`\n * debounce modes.\n */\n\n\n var timeoutID;\n var cancelled = false; // Keep track of the last time `callback` was executed.\n\n var lastExec = 0; // Function to clear existing timeout\n\n function clearExistingTimeout() {\n if (timeoutID) {\n clearTimeout(timeoutID);\n }\n } // Function to cancel next exec\n\n\n function cancel(options) {\n var _ref2 = options || {},\n _ref2$upcomingOnly = _ref2.upcomingOnly,\n upcomingOnly = _ref2$upcomingOnly === void 0 ? false : _ref2$upcomingOnly;\n\n clearExistingTimeout();\n cancelled = !upcomingOnly;\n }\n /*\n * The `wrapper` function encapsulates all of the throttling / debouncing\n * functionality and when executed will limit the rate at which `callback`\n * is executed.\n */\n\n\n function wrapper() {\n for (var _len = arguments.length, arguments_ = new Array(_len), _key = 0; _key < _len; _key++) {\n arguments_[_key] = arguments[_key];\n }\n\n var self = this;\n var elapsed = Date.now() - lastExec;\n\n if (cancelled) {\n return;\n } // Execute `callback` and update the `lastExec` timestamp.\n\n\n function exec() {\n lastExec = Date.now();\n callback.apply(self, arguments_);\n }\n /*\n * If `debounceMode` is true (at begin) this is used to clear the flag\n * to allow future `callback` executions.\n */\n\n\n function clear() {\n timeoutID = undefined;\n }\n\n if (!noLeading && debounceMode && !timeoutID) {\n /*\n * Since `wrapper` is being called for the first time and\n * `debounceMode` is true (at begin), execute `callback`\n * and noLeading != true.\n */\n exec();\n }\n\n clearExistingTimeout();\n\n if (debounceMode === undefined && elapsed > delay) {\n if (noLeading) {\n /*\n * In throttle mode with noLeading, if `delay` time has\n * been exceeded, update `lastExec` and schedule `callback`\n * to execute after `delay` ms.\n */\n lastExec = Date.now();\n\n if (!noTrailing) {\n timeoutID = setTimeout(debounceMode ? clear : exec, delay);\n }\n } else {\n /*\n * In throttle mode without noLeading, if `delay` time has been exceeded, execute\n * `callback`.\n */\n exec();\n }\n } else if (noTrailing !== true) {\n /*\n * In trailing throttle mode, since `delay` time has not been\n * exceeded, schedule `callback` to execute `delay` ms after most\n * recent execution.\n *\n * If `debounceMode` is true (at begin), schedule `clear` to execute\n * after `delay` ms.\n *\n * If `debounceMode` is false (at end), schedule `callback` to\n * execute after `delay` ms.\n */\n timeoutID = setTimeout(debounceMode ? clear : exec, debounceMode === undefined ? delay - elapsed : delay);\n }\n }\n\n wrapper.cancel = cancel; // Return the wrapper function.\n\n return wrapper;\n}\n\n/* eslint-disable no-undefined */\n/**\n * Debounce execution of a function. Debouncing, unlike throttling,\n * guarantees that a function is only executed a single time, either at the\n * very beginning of a series of calls, or at the very end.\n *\n * @param {number} delay - A zero-or-greater delay in milliseconds. For event callbacks, values around 100 or 250 (or even higher) are most useful.\n * @param {Function} callback - A function to be executed after delay milliseconds. The `this` context and all arguments are passed through, as-is,\n * to `callback` when the debounced-function is executed.\n * @param {object} [options] - An object to configure options.\n * @param {boolean} [options.atBegin] - Optional, defaults to false. If atBegin is false or unspecified, callback will only be executed `delay` milliseconds\n * after the last debounced-function call. If atBegin is true, callback will be executed only at the first debounced-function call.\n * (After the throttled-function has not been called for `delay` milliseconds, the internal counter is reset).\n *\n * @returns {Function} A new, debounced function.\n */\n\nfunction debounce (delay, callback, options) {\n var _ref = options || {},\n _ref$atBegin = _ref.atBegin,\n atBegin = _ref$atBegin === void 0 ? false : _ref$atBegin;\n\n return throttle(delay, callback, {\n debounceMode: atBegin !== false\n });\n}\n\nexport { debounce, throttle };\n//# sourceMappingURL=index.js.map\n","/**\n * GROWI agent for HackMD\n *\n * This file will be transpiled as a single JS\n * and should be load from HackMD head via 'routes/hackmd.js' route\n *\n * USAGE:\n * <script src=\"${hostname of GROWI}/_hackmd/load-agent\"></script>\n *\n * @author Yuki Takei <yuki@weseek.co.jp>\n */\nimport connectToParent from 'penpal/lib/connectToParent';\nimport { debounce } from 'throttle-debounce';\n\nconst DEBUG_PENPAL = false;\n\n/* eslint-disable no-console */\n\nconst allowedOrigin = '<%= origin %>'; // will be replaced by ejs\n\n\n/**\n * return the value of CodeMirror\n */\nfunction getValueOfCodemirror() {\n // get CodeMirror instance\n const editor = window.editor;\n return editor.doc.getValue();\n}\n\n/**\n * set the specified document to CodeMirror\n * @param {string} value\n */\nfunction setValueToCodemirror(value) {\n // get CodeMirror instance\n const editor = window.editor;\n editor.doc.setValue(value);\n}\n\n/**\n * set the specified document to CodeMirror on window loaded\n * @param {string} value\n */\nfunction setValueToCodemirrorOnInit(newValue) {\n if (window.cmClient != null) {\n setValueToCodemirror(newValue);\n return;\n }\n\n const intervalId = setInterval(() => {\n if (window.cmClient != null) {\n clearInterval(intervalId);\n setValueToCodemirror(newValue);\n }\n }, 250);\n\n}\n\n/**\n * postMessage to GROWI to notify body changes\n * @param {string} body\n */\nfunction postParentToNotifyBodyChanges(body) {\n window.growi.notifyBodyChanges(body);\n}\n// generate debounced function\nconst debouncedPostParentToNotifyBodyChanges = debounce(800, postParentToNotifyBodyChanges);\n\n/**\n * postMessage to GROWI to save with shortcut\n * @param {string} document\n */\nfunction postParentToSaveWithShortcut(document) {\n window.growi.saveWithShortcut(document);\n}\n\nfunction addEventListenersToCodemirror() {\n // get CodeMirror instance\n const codemirror = window.CodeMirror;\n // get CodeMirror editor instance\n const editor = window.editor;\n\n // e.g. 404 not found\n if (codemirror == null || editor == null) {\n return;\n }\n\n // == change event\n editor.on('change', (cm, change) => {\n if (change.origin === 'ignoreHistory') {\n // do nothing because this operation triggered by other user\n return;\n }\n debouncedPostParentToNotifyBodyChanges(cm.doc.getValue());\n });\n\n // == save event\n // Reset save commands and Cmd-S/Ctrl-S shortcuts that initialized by HackMD\n codemirror.commands.save = function(cm) {\n postParentToSaveWithShortcut(cm.doc.getValue());\n };\n delete editor.options.extraKeys['Cmd-S'];\n delete editor.options.extraKeys['Ctrl-S'];\n}\n\nfunction connectToParentWithPenpal() {\n const connection = connectToParent({\n parentOrigin: allowedOrigin,\n // Methods child is exposing to parent\n methods: {\n getValue() {\n return getValueOfCodemirror();\n },\n setValue(newValue) {\n setValueToCodemirror(newValue);\n },\n setValueOnInit(newValue) {\n setValueToCodemirrorOnInit(newValue);\n },\n },\n debug: DEBUG_PENPAL,\n });\n connection.promise\n .then((parent) => {\n window.growi = parent;\n })\n .catch((err) => {\n console.log(err);\n });\n}\n\n/**\n * main\n */\n(function() {\n // check HackMD is in iframe\n if (window === window.parent) {\n console.log('[GROWI] Loading agent for HackMD is not processed because currently not in iframe');\n return;\n }\n\n console.log('[HackMD] Loading GROWI agent for HackMD...');\n\n window.addEventListener('load', () => {\n addEventListenersToCodemirror();\n });\n\n connectToParentWithPenpal();\n\n console.log('[HackMD] GROWI agent for HackMD has successfully loaded.');\n}());\n"],"names":["constants","HANDSHAKE","HANDSHAKE_REPLY","CALL","REPLY","FULFILLED","REJECTED","MESSAGE","DATA_CLONE_ERROR","errorCodes","ERR_CONNECTION_DESTROYED","ERR_CONNECTION_TIMEOUT","ERR_NOT_IN_IFRAME","ERR_NO_IFRAME_SRC","exports","_default","callbacks","destroyed","callback","module","errorSerialization","serializeError","_ref","name","message","stack","deserializeError","obj","deserializedError","key","_constants","require$$0","_errorSerialization","require$$1","info","methods","log","localName","local","remote","originForSending","originForReceiving","handleMessageEvent","event","_event$data","methodName","args","id","createPromiseHandler","resolution","returnValue","err","resolve","_errorCodes","_generateId","_interopRequireDefault","require$$2","require$$3","callSender","methodNames","destroyConnection","createMethodProxy","_len","_key","iframeRemoved","error","reject","api","debug","_createDestructor2","_connectCallReceiver","_connectCallSender","require$$4","_createLogger","require$$5","_ref$parentOrigin","parentOrigin","_ref$methods","timeout","_createDestructor","destroy","onDestroy","child","parent","resolveConnectionPromise","connectionTimeoutId","destroyCallReceiver","destroyCallSender","throttle","delay","options","_ref$noTrailing","noTrailing","_ref$noLeading","noLeading","_ref$debounceMode","debounceMode","timeoutID","cancelled","lastExec","clearExistingTimeout","cancel","_ref2","_ref2$upcomingOnly","upcomingOnly","wrapper","arguments_","self","elapsed","exec","clear","debounce","_ref$atBegin","atBegin","DEBUG_PENPAL","allowedOrigin","getValueOfCodemirror","setValueToCodemirror","value","setValueToCodemirrorOnInit","newValue","intervalId","postParentToNotifyBodyChanges","body","debouncedPostParentToNotifyBodyChanges","postParentToSaveWithShortcut","document","addEventListenersToCodemirror","codemirror","editor","cm","change","connectToParentWithPenpal","connectToParent"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9]}
|