Ghost/ghost/admin/app/templates/editor.hbs
Kevin Ansfield 61cf4d46db Koenig reboot - rich text (#952)
refs https://github.com/TryGhost/Ghost/issues/9311

Koenig is being fully rebooted, first port of call is to focus on getting the rich-text only aspect of mobiledoc-kit working with our popup toolbar.

- renames old koenig implementation (used for reference, will eventually be deleted)
- new `{{koenig-editor}}` mobiledoc-kit component implementation based on ember-mobiledoc-editor
  - markdown text expansions
- new `{{gh-koenig-edtor}}` that wraps our title+editor and handles keyboard navigation between the two
  - clicks below content will focus the editor
- new `{{koenig-toolbar}}` component for the popup formatting toolbar with improved behaviour and simplified code
2018-01-30 10:01:07 +00:00

183 lines
7.3 KiB
Handlebars

{{#if post}}
{{#gh-editor
tagName="section"
class="gh-editor gh-view"
navIsClosed=navIsClosed
as |editor|
}}
<header class="gh-editor-header {{editor.headerClass}}">
<div class="gh-editor-status">
{{gh-editor-post-status
post=post
isSaving=(or autosave.isRunning saveTasks.isRunning)
}}
</div>
{{#gh-scheduled-post-countdown post=post as |post countdown|}}
<time datetime="{{post.publishedAtUTC}}" class="gh-notification gh-notification-schedule" data-test-schedule-countdown>
Post will be published {{countdown}}.
</time>
{{/gh-scheduled-post-countdown}}
<section class="view-actions">
{{#unless post.isNew}}
{{gh-publishmenu
post=post
saveTask=save
setSaveType=(action "setSaveType")
onOpen=(action "cancelAutosave")}}
{{/unless}}
<button type="button" class="post-settings" title="Settings" {{action "openSettingsMenu" target=ui}} data-test-psm-trigger>
{{inline-svg "settings"}}
</button>
</section>
</header>
{{#if useKoenig}}
{{!--
gh-koenig-editor acts as a wrapper around the title input and
koenig editor canvas to support Ghost-specific editor behaviour
--}}
{{gh-koenig-editor
title=(readonly post.titleScratch)
titlePlaceholder="Story Title"
onTitleChange=(action "updateTitleScratch")
onTitleBlur=(action (perform saveTitle))
body=(readonly post.scratch)
bodyPlaceholder="Begin writing your story..."
bodyAutofocus=shouldFocusEditor
onBodyChange=(action "updateScratch")
}}
{{else}}
{{!--
NOTE: title is part of the markdown editor container so that it has
access to the markdown editor's "focus" action
--}}
{{#gh-markdown-editor
tabindex="2"
placeholder="Begin writing your story..."
autofocus=shouldFocusEditor
uploadedImageUrls=editor.uploadedImageUrls
mobiledoc=(readonly post.scratch)
isFullScreen=editor.isFullScreen
onChange=(action "updateScratch")
onFullScreenToggle=(action editor.toggleFullScreen)
onPreviewToggle=(action editor.togglePreview)
onSplitScreenToggle=(action editor.toggleSplitScreen)
onImageFilesSelected=(action editor.uploadImages)
imageMimeTypes=editor.imageMimeTypes
as |markdown|
}}
<div class="gh-markdown-editor-pane">
{{gh-textarea post.titleScratch
class="gh-editor-title"
placeholder="Post Title"
tabindex="1"
autoExpand=".gh-markdown-editor-pane"
update=(action "updateTitleScratch")
focusOut=(action (perform saveTitle))
keyEvents=(hash
9=(action markdown.focus 'bottom')
13=(action markdown.focus 'top')
)
data-test-editor-title-input=true
}}
{{markdown.editor}}
</div>
{{#if markdown.isSplitScreen}}
<div class="gh-markdown-editor-preview">
<h1 class="gh-markdown-editor-preview-title">{{post.titleScratch}}</h1>
<div class="gh-markdown-editor-preview-content"></div>
</div>
{{/if}}
{{gh-tour-item "using-the-editor"
target=".gh-editor-footer"
throbberAttachment="top left"
throbberOffset="0 20%"
popoverTriangleClass="bottom"
}}
{{/gh-markdown-editor}}
{{!-- TODO: put tool/status bar in here so that scroll area can be fixed --}}
<footer class="gh-editor-footer"></footer>
{{!-- files are dragged over editor pane --}}
{{#if editor.isDraggedOver}}
<div class="drop-target gh-editor-drop-target">
<div class="drop-target-message">
<h3>Drop image(s) here to upload</h3>
</div>
</div>
{{/if}}
{{!-- files have been dropped ready to be uploaded --}}
{{#if editor.droppedFiles}}
{{#gh-uploader
files=editor.droppedFiles
accept=editor.imageMimeTypes
extensions=editor.imageExtensions
onComplete=(action editor.uploadComplete)
onCancel=(action editor.uploadCancelled)
as |upload|
}}
<div class="gh-editor-image-upload {{if upload.errors "-error"}}">
<div class="gh-editor-image-upload-content">
{{#if upload.errors}}
<h3>Upload failed</h3>
{{#each upload.errors as |error|}}
<div class="failed">{{error.fileName}} - {{error.message}}</div>
{{/each}}
<button class="gh-btn gh-btn-grey gh-btn-icon" {{action upload.cancel}}>
<span>{{inline-svg "close"}} Close</span>
</button>
{{else}}
<h3>Uploading {{pluralize upload.files.length "image"}}...</h3>
{{upload.progressBar}}
{{/if}}
</div>
</div>
{{/gh-uploader}}
{{/if}}
{{/if}} {{!-- end Koenig conditional --}}
{{/gh-editor}}
{{#if showDeletePostModal}}
{{gh-fullscreen-modal "delete-post"
model=(hash post=post onSuccess=(route-action 'redirectToContentScreen'))
close=(action "toggleDeletePostModal")
modifier="action wide"}}
{{/if}}
{{#if showLeaveEditorModal}}
{{gh-fullscreen-modal "leave-editor"
confirm=(action "leaveEditor")
close=(action "toggleLeaveEditorModal")
modifier="action wide"}}
{{/if}}
{{#if showReAuthenticateModal}}
{{gh-fullscreen-modal "re-authenticate"
close=(action "toggleReAuthenticateModal")
modifier="action wide"}}
{{/if}}
{{#liquid-wormhole}}
{{gh-post-settings-menu
post=post
showSettingsMenu=ui.showSettingsMenu
deletePost=(action "toggleDeletePostModal")
updateSlug=updateSlug
savePost=savePost
}}
{{/liquid-wormhole}}
{{/if}}
{{outlet}}