diff --git a/app/components/SimpleEditor/ContainerEditor.js b/app/components/SimpleEditor/ContainerEditor.js index ae7c28db654b35a113057e2861f2b628476845bf..b28e25672fc85229056746745acb1edc6ed74b94 100644 --- a/app/components/SimpleEditor/ContainerEditor.js +++ b/app/components/SimpleEditor/ContainerEditor.js @@ -1,3 +1,4 @@ +import { each, keys, includes } from 'lodash' import { ContainerEditor as SubstanceContainerEditor, Surface, @@ -30,19 +31,17 @@ class ContainerEditor extends SubstanceContainerEditor { }.bind(this)) } + // open for editing + // TODO -- should maybe change to isEditable ? if (!this.props.disabled) { el.addClass('sm-enabled') el.setAttribute('contenteditable', true) } - if (this.props.canNotEdit) { - el.addEventListener('keydown', function (e) { - e.preventDefault() - if (e.keyCode === 13 || e.keyCode === 32) { - const documentSession = this.context.documentSession - documentSession.undo() - } - }) - el.addEventListener('contextmenu', event => event.preventDefault()) + + // editing locked, selection open (for comments) + if (this.isReadOnlyMode()) { + const documentSession = this.getDocumentSession() + documentSession.on('didUpdate', this.disableToolbar, this) } return el @@ -52,6 +51,8 @@ class ContainerEditor extends SubstanceContainerEditor { Surface.prototype.didMount.apply(this, arguments) this.container.on('nodes:changed', this.onContainerChange, this) if (this.isEmpty()) this.createText() + + if (this.isReadOnlyMode()) this.addTargetToLinks() } // create an empty paragraph with an empty node @@ -82,6 +83,33 @@ class ContainerEditor extends SubstanceContainerEditor { this.rerender() this.setSelection(newSel) } + + // only runs if editor is in read-only mode + // disables all tools, apart from comments + disableToolbar () { + const commandStates = this.getCommandStates() + + each(keys(commandStates), key => { + const allowed = ['comment', 'note', 'save', 'undo', 'redo'] + if (!includes(allowed, key)) commandStates[key].disabled = true + }) + } + + getCommandStates () { + const commandManager = this.context.commandManager + return commandManager.getCommandStates() + } + + isReadOnlyMode () { + return !this.isEditable() && this.isSelectable() + } + + addTargetToLinks () { + const allLinks = this.el.findAll('a') + each(allLinks, link => + link.attr('target', '_blank') + ) + } } export default ContainerEditor diff --git a/app/components/SimpleEditor/Editor.js b/app/components/SimpleEditor/Editor.js index 146ea851d7678044190450bd6f46c32e22c994f5..0b1a223fec00182d4cdf3f0971f7031c8e6c8ed6 100644 --- a/app/components/SimpleEditor/Editor.js +++ b/app/components/SimpleEditor/Editor.js @@ -1,6 +1,6 @@ import { ProseEditor, - // ProseEditorOverlayTools, + ProseEditorOverlayTools, ScrollPane, SplitPane, TOCProvider @@ -9,7 +9,7 @@ import { import Comments from './panes/Comments/CommentBoxList' import CommentsProvider from './panes/Comments/CommentsProvider' import ContainerEditor from './ContainerEditor' -import Overlay from './Overlay' +// import Overlay from './Overlay' import Notes from './panes/Notes/Notes' import NotesProvider from './panes/Notes/NotesProvider' import TableOfContents from './panes/TableOfContents/TableOfContents' @@ -70,7 +70,7 @@ class Editor extends ProseEditor { var contentPanel = $$(ScrollPane, { scrollbarPosition: 'right', - overlay: Overlay + overlay: ProseEditorOverlayTools }) .append(editorWithComments) .attr('id', 'content-panel') @@ -94,9 +94,11 @@ class Editor extends ProseEditor { } _renderEditor ($$) { - var configurator = this.props.configurator + const configurator = this.props.configurator + const editing = this.props.disabled ? 'selection' : 'full' + return $$(ContainerEditor, { - canNotEdit: this.props.disabled, + editing: editing, documentSession: this.documentSession, commands: configurator.getSurfaceCommandNames(), containerId: 'body', @@ -131,20 +133,19 @@ class Editor extends ProseEditor { } getChildContext () { - var doc = this.doc - // TODO -- check whether this is correct - var oldContext = Object.assign({}, super.getChildContext(), { Editor }) + const oldContext = super.getChildContext() + const doc = this.doc // toc provider - var tocProvider = new TOCProvider(doc, { + const tocProvider = new TOCProvider(doc, { containerId: 'body' }) // // notes provider - var notesProvider = new NotesProvider(doc) + const notesProvider = new NotesProvider(doc) // // comments provider - var commentsProvider = new CommentsProvider(doc, { + const commentsProvider = new CommentsProvider(doc, { commandManager: this.commandManager, comments: this.props.fragment.comments, containerId: this.props.containerId, @@ -155,10 +156,11 @@ class Editor extends ProseEditor { }) // attach all to context - return { ...oldContext, - tocProvider: tocProvider, - notesProvider: notesProvider, - commentsProvider: commentsProvider + return { + ...oldContext, + tocProvider, + notesProvider, + commentsProvider } } } diff --git a/app/components/SimpleEditor/Overlay.js b/app/components/SimpleEditor/Overlay.js deleted file mode 100644 index e32def516d9eb11cda23b3ab74f04fb4941861a9..0000000000000000000000000000000000000000 --- a/app/components/SimpleEditor/Overlay.js +++ /dev/null @@ -1,41 +0,0 @@ -import { ProseEditorOverlayTools } from 'substance' -import { each, includes, keys } from 'lodash' - -class Overlay extends ProseEditorOverlayTools { - render ($$) { - const surface = this.getSurface() - - if (surface && surface.props.canNotEdit) { - const commandStates = this.context.commandManager.getCommandStates() - each(keys(commandStates), (key) => { - const allowed = ['comment', 'save'] - if (!includes(allowed, key)) commandStates[key].disabled = true - }) - } - - let el = $$('div').addClass(this.getClassNames()) - let activeTools = this.getActiveTools() - - if (activeTools.length > 0) { - let toolsEl = $$('div').addClass('se-active-tools') - activeTools.forEach(tool => { - toolsEl.append( - $$(tool.Class, tool.toolProps).ref(tool.toolProps.name) - ) - }) - el.append(toolsEl) - } - return el - } - - getSurface () { - const surfaceManager = this.context.surfaceManager - return surfaceManager.getSurface('body') - } - - getClassNames () { - return 'sc-prose-editor-overlay-tools' - } -} - -export default Overlay diff --git a/app/components/SimpleEditor/SimpleEditor.jsx b/app/components/SimpleEditor/SimpleEditor.jsx index c7e3937eba6cf87065a9cb30ede29c1fdb4e9b10..c04ec07d7c74dfd1f8e63d96f54f4f155daf3e44 100644 --- a/app/components/SimpleEditor/SimpleEditor.jsx +++ b/app/components/SimpleEditor/SimpleEditor.jsx @@ -104,7 +104,7 @@ export default class SimpleEditor extends React.Component { let viewMode = !canEdit ? ( <Alert bsStyle='warning' className='view-mode'> - <span>Editor is in View Mode</span> + <span>Editor is in Read-Only Mode</span> </Alert> ) : null diff --git a/app/components/SimpleEditor/SimpleEditor.scss b/app/components/SimpleEditor/SimpleEditor.scss index 6787df711a1138b532885d2c5b5018e51cacab4e..f238082fc5f5b906fedc1f20fea6c027748ad539 100644 --- a/app/components/SimpleEditor/SimpleEditor.scss +++ b/app/components/SimpleEditor/SimpleEditor.scss @@ -14,6 +14,7 @@ $primary: #eee; $ultra-light-gray: #fafafa; $black: #000; +$shadow: rgba(0, 0, 0, .05); $teal: #46b9ba; $toolbar-active-bg: rgba(204, 204, 204, .75); $transparent-black: rgba(0, 0, 0, .75); @@ -24,9 +25,6 @@ $white: #fff; position: relative; .view-mode { - // background-color: $primary; - // border-bottom: 1px solid $border; - // border-top: 1px solid $border; height: 44px; position: fixed; right: 0; @@ -53,7 +51,6 @@ $white: #fff; background-color: $primary; border: 1px solid $border; border-right: 0; - // padding: 1px; padding-left: 0; button { @@ -114,7 +111,7 @@ $white: #fff; .sc-switch-text-type { margin-left: 1px; - width: 150px !important; + width: 150px; .se-toggle { background: transparent; @@ -203,7 +200,7 @@ $white: #fff; .se-context-section { background-color: $ultra-light-gray; border-left: 1px solid $light-gray; - box-shadow: inset 0 0 10px rgba(0, 0, 0, .05); + box-shadow: inset 0 0 10px $shadow; } .sc-comments-pane { diff --git a/app/components/SimpleEditor/elements/comment/CommentBubble.js b/app/components/SimpleEditor/elements/comment/CommentBubble.js index b8fefd04baebb47bab20cf255b90cd5bbd33492a..09c9b1a69e0339c1b35408da096b2e9781d5fc07 100644 --- a/app/components/SimpleEditor/elements/comment/CommentBubble.js +++ b/app/components/SimpleEditor/elements/comment/CommentBubble.js @@ -7,12 +7,11 @@ import { class CommentBubble extends Tool { render ($$) { + const mode = this.getMode() const title = 'Create a new comment' - let commands = this.getCommentState() - if (commands.mode !== 'create') return $$('div') - commands.active = true - this.setBubblePosition() + if (mode !== 'create') return $$('div') + const icon = $$(Icon, { icon: 'fa-comment' }) .addClass('sc-comment-icon') @@ -31,18 +30,23 @@ class CommentBubble extends Tool { // calculated relative to the overlay container, which gets positioned // wrong on resize (substance bug -- TODO) didMount () { + this.position() DefaultDOMElement.getBrowserWindow().on('resize', this.didUpdate, this) } didUpdate () { - if (this.el.getChildCount() === 0) return - this.setBubblePosition() + this.position() } dispose () { DefaultDOMElement.getBrowserWindow().off(this) } + position () { + if (this.el.getChildCount() === 0) return + this.setBubblePosition() + } + setBubblePosition () { // without this check, the editor will break on first load const surface = this.getSurface() diff --git a/app/components/SimpleEditor/elements/note/EditNoteTool.js b/app/components/SimpleEditor/elements/note/EditNoteTool.js index 31db2ddcb1ad209240f526833e740716a1c9e8eb..804bcae5f320810e755028bd2a11828164565534 100644 --- a/app/components/SimpleEditor/elements/note/EditNoteTool.js +++ b/app/components/SimpleEditor/elements/note/EditNoteTool.js @@ -9,20 +9,29 @@ class EditNoteTool extends Tool { const selected = this.getSelection() if (!selected.node) return el + const disabled = this.isEditorReadOnly() + // TODO -- on this.getLabel add a label to package and call it save note const icon = $$(Icon, { icon: 'fa-save' }) .addClass('sc-save-icon') - const save = $$('div').addClass('sc-save-area').append(icon).on('click', this.saveNote) - el.append( - $$('div').addClass('sc-edit-note-tool-container').append( + const save = $$('div') + .addClass('sc-save-area') + .append(icon) + .on('click', this.saveNote) + + const noteTool = $$('div') + .addClass('sc-edit-note-tool-container') + .append( $$(PromptTextArea, { + disabled: disabled, path: [selected.node.id, 'note-content'], placeholder: 'Type your note here' - }), - save + }) ) - ) + if (!disabled) noteTool.append(save) + + el.append(noteTool) // to properly adjust text area height depending on text this.setTextAreaHeight() @@ -86,6 +95,16 @@ class EditNoteTool extends Tool { } }) } + + getSurface () { + const surfaceManager = this.context.surfaceManager + return surfaceManager.getFocusedSurface() + } + + isEditorReadOnly () { + const surface = this.getSurface() + return surface.isReadOnlyMode() + } } EditNoteTool.type = 'edit-note' diff --git a/app/components/SimpleEditor/elements/note/PromptTextArea.js b/app/components/SimpleEditor/elements/note/PromptTextArea.js index ce4d2d6cec3cae64aaca298aa0a06ab08ba3cd86..fc6ca23278bd7819850a1286a07092296b3b73aa 100644 --- a/app/components/SimpleEditor/elements/note/PromptTextArea.js +++ b/app/components/SimpleEditor/elements/note/PromptTextArea.js @@ -4,20 +4,24 @@ import { Component } from 'substance' class TextArea extends Component { render ($$) { + const { disabled, path, placeholder, rows } = this.props + const documentSession = this.context.documentSession const doc = documentSession.getDocument() - const val = doc.get(this.props.path) + const val = doc.get(path) const el = $$('textarea') .attr({ - rows: this.props.rows || '1', // cols: this.props.columns || '40', - placeholder: this.props.placeholder || 'Type your text here' + placeholder: placeholder || 'Type your text here', + rows: rows || '1' }) .addClass('se-note-textarea') .append(val) .on('keyup', this.textAreaAdjust) + if (disabled) el.attr('disabled', 'true') + return el } diff --git a/app/components/SimpleEditor/elements/note/note.scss b/app/components/SimpleEditor/elements/note/note.scss index cd7a9841aab3974654ff371dade50cb2e783e3df..300847a5e8975757114ef56c34738dded8672775 100644 --- a/app/components/SimpleEditor/elements/note/note.scss +++ b/app/components/SimpleEditor/elements/note/note.scss @@ -56,5 +56,9 @@ $red: #591818; overflow: hidden; resize: none; width: 310px; + + &[disabled] { + border-right: 0; + } } }