diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..ca025f4 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,12 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "prettier": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", + "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", + "dev": true + } + } +} diff --git a/prose/.prettierrc b/prose/.prettierrc new file mode 100644 index 0000000..222861c --- /dev/null +++ b/prose/.prettierrc @@ -0,0 +1,4 @@ +{ + "tabWidth": 2, + "useTabs": false +} diff --git a/prose/prose.js b/prose/prose.js index 7c21116..af53583 100644 --- a/prose/prose.js +++ b/prose/prose.js @@ -28,6 +28,7 @@ let $content = document.querySelector("#content"); class ProseMirrorView { constructor(target, content) { + let typingTimer; let localDraft = localStorage.getItem(window.draftKey); if (localDraft != null) { content = localDraft; @@ -66,8 +67,9 @@ class ProseMirrorView { ], }), dispatchTransaction(transaction) { + let newState = this.state.apply(transaction); const newContent = writeAsMarkdownSerializer - .serialize(transaction.doc) + .serialize(newState.doc) // Replace all \\\ns ( not followed by a \n ) with \n .replaceAll(/\\\n(?!\n)/g, "\n"); $content.value = newContent; @@ -76,8 +78,8 @@ class ProseMirrorView { draft = "# " + $title.value + "\n\n"; } draft += newContent; - localStorage.setItem(window.draftKey, draft); - let newState = this.state.apply(transaction); + clearTimeout(typingTimer); + typingTimer = setTimeout(doneTyping, doneTypingInterval); this.updateState(newState); }, }); diff --git a/static/js/prose.bundle.js b/static/js/prose.bundle.js index 7c79102..28b98c2 100644 --- a/static/js/prose.bundle.js +++ b/static/js/prose.bundle.js @@ -1176,7 +1176,7 @@ eval("module.exports = function (module) {\n if (!module.webpackPolyfill) {\n /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var prosemirror_view__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! prosemirror-view */ \"./node_modules/prosemirror-view/dist/index.es.js\");\n/* harmony import */ var prosemirror_state__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! prosemirror-state */ \"./node_modules/prosemirror-state/dist/index.es.js\");\n/* harmony import */ var prosemirror_example_setup__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! prosemirror-example-setup */ \"./node_modules/prosemirror-example-setup/dist/index.es.js\");\n/* harmony import */ var prosemirror_keymap__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! prosemirror-keymap */ \"./node_modules/prosemirror-keymap/dist/index.es.js\");\n/* harmony import */ var _markdownParser__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./markdownParser */ \"./markdownParser.js\");\n/* harmony import */ var _markdownSerializer__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./markdownSerializer */ \"./markdownSerializer.js\");\n/* harmony import */ var _schema__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./schema */ \"./schema.js\");\n/* harmony import */ var _menu__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./menu */ \"./menu.js\");\nfunction _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance\"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n// class MarkdownView {\n// constructor(target, content) {\n// this.textarea = target.appendChild(document.createElement(\"textarea\"))\n// this.textarea.value = content\n// }\n// get content() { return this.textarea.value }\n// focus() { this.textarea.focus() }\n// destroy() { this.textarea.remove() }\n// }\n\n\n\n\n\n\n\n\nvar $title = document.querySelector(\"#title\");\nvar $content = document.querySelector(\"#content\"); // Bugs:\n// 1. When there's just an empty line and a hard break is inserted with shift-enter then two enters are inserted \n// which do not show up in the markdown ( maybe bc. they are training enters )\n\nvar ProseMirrorView = /*#__PURE__*/function () {\n function ProseMirrorView(target, content) {\n _classCallCheck(this, ProseMirrorView);\n\n var localDraft = localStorage.getItem(window.draftKey);\n\n if (localDraft != null) {\n content = localDraft;\n }\n\n if (content.indexOf(\"# \") === 0) {\n var eol = content.indexOf(\"\\n\");\n var title = content.substring(\"# \".length, eol);\n content = content.substring(eol + \"\\n\\n\".length);\n $title.value = title;\n }\n\n var doc = _markdownParser__WEBPACK_IMPORTED_MODULE_4__[\"writeAsMarkdownParser\"].parse( // Replace all \"solo\" \\n's with \\\\\\n for correct markdown parsing\n content.replaceAll(/(?