diff options
author | Paul Martin <paul@paulsputer.com> | 2016-01-11 12:25:06 +0000 |
---|---|---|
committer | Paul Martin <paul@paulsputer.com> | 2016-03-27 17:09:16 +0100 |
commit | 2754961708ff0eb6030faf6db2edf8fbdae227d5 (patch) | |
tree | 827f0904a9e8a5db2282986230b374c42cfd69c1 /src/main/js/editor.dev.js | |
parent | 86401c3ff40c137a937a3dd83f12022fce5529b4 (diff) | |
download | gitblit-2754961708ff0eb6030faf6db2edf8fbdae227d5.tar.gz gitblit-2754961708ff0eb6030faf6db2edf8fbdae227d5.zip |
Document edit capability via ProseMirror submodule #974
+ New docEdit page with links from docPage and docList
+ Bespoke menu system with full screen edit mode
+ npm required for building client side scripts
+ Ant script added for BuildUI which performs npm commands
+ Update font-awesome to 4.5.0
+ Factor out to JGitUtils common code in BranchTicketService for EditFilePage
+ getTreeEntries
+ commitIndex
+ Merge capability for document editing
Diffstat (limited to 'src/main/js/editor.dev.js')
-rw-r--r-- | src/main/js/editor.dev.js | 271 |
1 files changed, 271 insertions, 0 deletions
diff --git a/src/main/js/editor.dev.js b/src/main/js/editor.dev.js new file mode 100644 index 00000000..62b6b4cc --- /dev/null +++ b/src/main/js/editor.dev.js @@ -0,0 +1,271 @@ +attachDocumentEditor = function (editorElement, commitDialogElement) +{ + var edit = require("./prosemirror/dist/edit") + require("./prosemirror/dist/inputrules/autoinput") + require("./prosemirror/dist/menu/menubar") + require("./prosemirror/dist/markdown") + var _menu = require("./prosemirror/dist/menu/menu") + + + var content = document.querySelector('#editor'); + content.style.display = "none"; + + var gitblitCommands = new _menu.MenuCommandGroup("gitblitCommands"); + var viewCommands = new _menu.MenuCommandGroup("viewCommands"); + var textCommands = new _menu.MenuCommandGroup("textCommands"); + var insertCommands = new _menu.MenuCommandGroup("insertCommands"); + + var menuItems = [gitblitCommands, viewCommands, textCommands, _menu.inlineGroup, _menu.blockGroup, _menu.historyGroup, insertCommands]; + + const updateCmd = Object.create(null); + + updateCmd["GitblitCommit"] = { + label: "GitblitCommit", + run: function() { + commitDialogElement.modal({show:true}); + editorElement.value = pm.getContent('markdown'); + }, + menu: { + group: "gitblitCommands", rank: 10, + display: { + render: function(cmd, pm) { return renderFontAwesomeIcon(cmd, pm, "fa-save"); } + } + } + }; + + updateCmd["FullScreen"] = { + label: "Toggle Fullscreen", + derive: "toggle", + run: function(pm) { + //Maintain the scroll context + var initialScroll = window.scrollY; + var navs = [document.querySelector("div.repositorynavbar"), document.querySelector("div.navbar"), document.querySelector("div.docnav")]; + var offset = navs.reduce(function(p, c) { return p + c.offsetHeight; }, 0); + navs.forEach(function(e) { e.classList.toggle("forceHide"); }); + + if (!toggleFullScreen(document.documentElement)) { + offset = 60; + } else { + offset -= 60; + } + + pm.signal("commandsChanged"); + + //Browsers don't seem to accept a scrollTo straight after a full screen + setTimeout(function(){window.scrollTo(0, Math.max(0,initialScroll - offset));}, 100); + + }, + menu: { + group: "viewCommands", rank: 11, + display: { + render: function(cmd, pm) { return renderFontAwesomeIcon(cmd, pm, "fa-arrows-alt"); } + } + }, + active: function active(pm) { return getFullScreenElement() ? true : false; } + }; + + updateCmd["heading1"] = { + derive: "toggle", + run: function(pm) { + var selection = pm.selection; + var from = selection.from; + var to = selection.to; + var attr = {name:"make", level:1}; + + var node = pm.doc.path(from.path); + if (node && node.hasMarkup(pm.schema.nodes.heading, attr)) { + return pm.tr.setBlockType(from, to, pm.schema.nodes.paragraph, {}).apply(pm.apply.scroll); + } else { + return pm.tr.setBlockType(from, to, pm.schema.nodes.heading, attr).apply(pm.apply.scroll); + } + + }, + active: function active(pm) { + var node = pm.doc.path(pm.selection.from.path); + if (node && node.hasMarkup(pm.schema.nodes.heading, {name:"make", level:1})) { + return true; + } + return false; + }, + menu: { + group: "textCommands", rank: 1, + display: { + render: function(cmd, pm) { return renderFontAwesomeIcon(cmd, pm, "fa-header fa-header-x fa-header-1"); } + }, + }, + select: function(){return true;} + }; + + updateCmd["heading2"] = { + derive: "toggle", + run: function(pm) { + var selection = pm.selection; + var from = selection.from; + var to = selection.to; + var attr = {name:"make", level:2}; + + var node = pm.doc.path(from.path); + if (node && node.hasMarkup(pm.schema.nodes.heading, attr)) { + return pm.tr.setBlockType(from, to, pm.schema.nodes.paragraph, {}).apply(pm.apply.scroll); + } else { + return pm.tr.setBlockType(from, to, pm.schema.nodes.heading, attr).apply(pm.apply.scroll); + } + + }, + active: function active(pm) { + var node = pm.doc.path(pm.selection.from.path); + if (node && node.hasMarkup(pm.schema.nodes.heading, {name:"make", level:2})) { + return true; + } + return false; + }, + menu: { + group: "textCommands", rank: 2, + display: { + render: function(cmd, pm) { return renderFontAwesomeIcon(cmd, pm, "fa-header fa-header-x fa-header-2"); } + }, + }, + select: function(){return true;} + }; + + updateCmd["heading3"] = { + derive: "toggle", + run: function(pm) { + var selection = pm.selection; + var from = selection.from; + var to = selection.to; + var attr = {name:"make", level:3}; + + var node = pm.doc.path(from.path); + if (node && node.hasMarkup(pm.schema.nodes.heading, attr)) { + return pm.tr.setBlockType(from, to, pm.schema.nodes.paragraph, {}).apply(pm.apply.scroll); + } else { + return pm.tr.setBlockType(from, to, pm.schema.nodes.heading, attr).apply(pm.apply.scroll); + } + + }, + active: function active(pm) { + var node = pm.doc.path(pm.selection.from.path); + if (node && node.hasMarkup(pm.schema.nodes.heading, {name:"make", level:3})) { + return true; + } + return false; + }, + menu: { + group: "textCommands", rank: 3, + display: { + render: function(cmd, pm) { return renderFontAwesomeIcon(cmd, pm, "fa-header fa-header-x fa-header-3"); } + }, + }, + select: function(){return true;} + }; + + updateCmd["strong:toggle"] = { + menu: { + group: "textCommands", rank: 4, + display: { + render: function(cmd, pm) { return renderFontAwesomeIcon(cmd, pm, "fa-bold"); } + } + }, + select: function(){return true;} + }; + + updateCmd["em:toggle"] = { + menu: { + group: "textCommands", rank: 5, + display: { + render: function(cmd, pm) { return renderFontAwesomeIcon(cmd, pm, "fa-italic"); } + } + }, + select: function(){return true;} + }; + + updateCmd["code:toggle"] = { + menu: { + group: "textCommands", rank: 6, + display: { + render: function(cmd, pm) { return renderFontAwesomeIcon(cmd, pm, "fa-code"); } + } + }, + select: function(){return true;} + }; + + updateCmd["image:insert"] = { + menu: { + group: "insertCommands", rank: 1, + display: { + render: function(cmd, pm) { return renderFontAwesomeIcon(cmd, pm, "fa-picture-o"); } + } + } + }; + + var pm = window.pm = new edit.ProseMirror({ + place: document.querySelector('#visualEditor'), + autoInput: true, + doc: content.value, + menuBar: { float:true, content: menuItems}, + commands: edit.CommandSet.default.update(updateCmd), + docFormat: "markdown" + }); + + + var scrollStart = document.querySelector(".ProseMirror").offsetTop; + + + var ticking = false; + window.addEventListener("scroll", function() { + var scrollPosition = window.scrollY; + if (!ticking) { + window.requestAnimationFrame(function() { + if (!getFullScreenElement() && (scrollPosition > scrollStart)) { + document.querySelector(".ProseMirror-menubar").classList.add("scrolling"); + } else { + document.querySelector(".ProseMirror-menubar").classList.remove("scrolling"); + } + ticking = false; + }); + } + ticking = true; + }); +} + +function renderFontAwesomeIcon(cmd, pm, classNames) { + var node = document.createElement("div"); + node.className = "ProseMirror-icon"; + var icon = document.createElement("i"); + icon.setAttribute("class", "fa fa-fw " + classNames); + + //TODO: try modify parent to simplify css border etc + var active = cmd.active(pm); + + if (active || cmd.spec.invert) node.classList.add("ProseMirror-menu-active"); + node.appendChild(icon); + return node; +} + + + +function getFullScreenElement() { + return document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement; +} + +function toggleFullScreen(e) { + if (getFullScreenElement()) { + if (document.exitFullscreen) { document.exitFullscreen(); } + else if (document.msExitFullscreen) { document.msExitFullscreen(); } + else if (document.mozCancelFullScreen) { document.mozCancelFullScreen(); } + else if (document.webkitExitFullscreen) { document.webkitExitFullscreen(); } + return true; + } else { + if (e.requestFullscreen) { e.requestFullscreen(); } + else if (e.msRequestFullscreen) { e.msRequestFullscreen(); } + else if (e.mozRequestFullScreen) { e.mozRequestFullScreen(); } + else if (e.webkitRequestFullscreen) { e.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT); } + } + return false; +} + +commitChanges = function() { + document.querySelector('form#documentEditor').submit(); +} + |