mirror of
https://github.com/documize/community.git
synced 2025-07-24 15:49:44 +02:00
all new markdown experience
This commit is contained in:
parent
9d720a1c65
commit
b8a0444f18
6 changed files with 122 additions and 46 deletions
|
@ -18,7 +18,6 @@ const {
|
|||
|
||||
export default Ember.Component.extend({
|
||||
drop: null,
|
||||
tip: "Short and concise title",
|
||||
busy: false,
|
||||
|
||||
hasNameError: computed.empty('page.title'),
|
||||
|
@ -26,6 +25,14 @@ export default Ember.Component.extend({
|
|||
let page = this.get('page');
|
||||
return `page-editor-${page.id}`;
|
||||
}),
|
||||
cancelId: Ember.computed('page', function () {
|
||||
let page = this.get('page');
|
||||
return `cancel-edits-button-${page.id}`;
|
||||
}),
|
||||
dialogId: Ember.computed('page', function () {
|
||||
let page = this.get('page');
|
||||
return `discard-edits-dialog-${page.id}`;
|
||||
}),
|
||||
|
||||
didRender() {
|
||||
let self = this;
|
||||
|
@ -54,16 +61,16 @@ export default Ember.Component.extend({
|
|||
actions: {
|
||||
onCancel() {
|
||||
if (this.attrs.isDirty() !== null && this.attrs.isDirty()) {
|
||||
$(".discard-edits-dialog").css("display", "block");
|
||||
|
||||
let page = this.get('page');
|
||||
$('#' + this.get('dialogId')).css("display", "block");
|
||||
|
||||
let drop = new Drop({
|
||||
target: $("#editor-cancel" + page.get('id'))[0],
|
||||
content: $(".cancel-edits-dialog-" + page.get('id'))[0],
|
||||
target: $('#' + this.get('cancelId'))[0],
|
||||
content: $('#' + this.get('dialogId'))[0],
|
||||
classes: 'drop-theme-basic',
|
||||
position: "bottom right",
|
||||
openOn: "always",
|
||||
constrainToWindow: true,
|
||||
constrainToScrollParent: false,
|
||||
tetherOptions: {
|
||||
offset: "5px 0",
|
||||
targetOffset: "10px 0"
|
||||
|
@ -80,11 +87,7 @@ export default Ember.Component.extend({
|
|||
},
|
||||
|
||||
onAction() {
|
||||
if (this.get('busy')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is.empty(this.get('page.title'))) {
|
||||
if (this.get('busy') || is.empty(this.get('page.title'))) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,9 +15,9 @@ import TooltipMixin from '../../../mixins/tooltip';
|
|||
export default Ember.Component.extend(TooltipMixin, {
|
||||
isDirty: false,
|
||||
pageBody: "",
|
||||
codeEditor: null,
|
||||
syntaxOptions: [],
|
||||
codeSyntax: null,
|
||||
codeEditor: null,
|
||||
editorId: Ember.computed('page', function () {
|
||||
let page = this.get('page');
|
||||
return `code-editor-${page.id}`;
|
||||
|
@ -116,7 +116,7 @@ export default Ember.Component.extend(TooltipMixin, {
|
|||
},
|
||||
|
||||
isDirty() {
|
||||
return this.get('isDirty');
|
||||
return this.get('isDirty') || (this.get('codeEditor').getDoc().isClean() === false);
|
||||
},
|
||||
|
||||
onCancel() {
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
// https://documize.com
|
||||
|
||||
import Ember from 'ember';
|
||||
import miscUtil from '../../../utils/misc';
|
||||
import TooltipMixin from '../../../mixins/tooltip';
|
||||
|
||||
const {
|
||||
|
@ -19,10 +18,12 @@ const {
|
|||
|
||||
export default Ember.Component.extend(TooltipMixin, {
|
||||
link: service(),
|
||||
editMode: true,
|
||||
isDirty: false,
|
||||
pageBody: "",
|
||||
pagePreview: "",
|
||||
editMode: true,
|
||||
codeSyntax: null,
|
||||
codeEditor: null,
|
||||
|
||||
editorId: Ember.computed('page', function () {
|
||||
let page = this.get('page');
|
||||
return `markdown-editor-${page.id}`;
|
||||
|
@ -36,23 +37,89 @@ export default Ember.Component.extend(TooltipMixin, {
|
|||
return `markdown-tooltip-${page.id}`;
|
||||
}),
|
||||
|
||||
didReceiveAttrs() {
|
||||
this.set("pageBody", this.get("meta.rawBody"));
|
||||
},
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
|
||||
let self = this;
|
||||
CodeMirror.modeURL = "/codemirror/mode/%N/%N.js";
|
||||
|
||||
let rawBody = this.get('meta.rawBody');
|
||||
let cleanBody = rawBody.replace("</pre>", "");
|
||||
|
||||
cleanBody = cleanBody.replace('<pre class="code-mirror cm-s-solarized cm-s-dark" data-lang="', "");
|
||||
let startPos = cleanBody.indexOf('">');
|
||||
let syntax = {
|
||||
mode: "markdown",
|
||||
name: "Markdown"
|
||||
};
|
||||
|
||||
if (startPos !== -1) {
|
||||
syntax = cleanBody.substring(0, startPos);
|
||||
cleanBody = cleanBody.substring(startPos + 2);
|
||||
}
|
||||
|
||||
this.set('pageBody', cleanBody);
|
||||
|
||||
let opts = [];
|
||||
|
||||
_.each(_.sortBy(CodeMirror.modeInfo, 'name'), function(item) {
|
||||
let i = {
|
||||
mode: item.mode,
|
||||
name: item.name
|
||||
};
|
||||
opts.pushObject(i);
|
||||
|
||||
if (item.mode === syntax) {
|
||||
self.set('codeSyntax', i);
|
||||
}
|
||||
});
|
||||
|
||||
this.set('syntaxOptions', opts);
|
||||
|
||||
// default check
|
||||
if (is.null(this.get("codeSyntax"))) {
|
||||
this.set("codeSyntax", opts.findBy("mode", "markdown"));
|
||||
}
|
||||
},
|
||||
|
||||
didInsertElement() {
|
||||
$("#" + this.get('editorId')).off("keyup").on("keyup", () => {
|
||||
this.set('isDirty', true);
|
||||
});
|
||||
this.attachEditor();
|
||||
},
|
||||
|
||||
willDestroyElement() {
|
||||
this.set('codeEditor', null);
|
||||
this.destroyTooltips();
|
||||
// $("#" + this.get('editorId')).off("keyup");
|
||||
},
|
||||
|
||||
getBody() {
|
||||
return this.get('codeEditor').getDoc().getValue();
|
||||
},
|
||||
|
||||
didRender() {
|
||||
this.addTooltip(document.getElementById(this.get('tooltipId')));
|
||||
},
|
||||
|
||||
willDestroyElement() {
|
||||
this.destroyTooltips();
|
||||
$("#" + this.get('editorId')).off("keyup");
|
||||
attachEditor() {
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById(this.get('editorId')), {
|
||||
theme: "solarized light",
|
||||
lineNumbers: true,
|
||||
lineWrapping: true,
|
||||
indentUnit: 4,
|
||||
tabSize: 4,
|
||||
value: "",
|
||||
dragDrop: false,
|
||||
extraKeys: {"Enter": "newlineAndIndentContinueMarkdownList"}
|
||||
});
|
||||
|
||||
this.set('codeEditor', editor);
|
||||
|
||||
let syntax = this.get("codeSyntax");
|
||||
|
||||
if (is.not.undefined(syntax)) {
|
||||
CodeMirror.autoLoadMode(editor, syntax.mode);
|
||||
editor.setOption("mode", syntax.mode);
|
||||
}
|
||||
},
|
||||
|
||||
actions: {
|
||||
|
@ -61,12 +128,10 @@ export default Ember.Component.extend(TooltipMixin, {
|
|||
|
||||
Ember.run.schedule('afterRender', () => {
|
||||
if (this.get('editMode')) {
|
||||
$("#" + this.get('editorId')).off("keyup").on("keyup", () => {
|
||||
this.set('isDirty', true);
|
||||
});
|
||||
this.attachEditor();
|
||||
} else {
|
||||
let md = window.markdownit({ linkify: true });
|
||||
let result = md.render(this.get("pageBody"));
|
||||
let result = md.render(this.getBody());
|
||||
|
||||
this.set('pagePreview', result);
|
||||
}
|
||||
|
@ -75,15 +140,13 @@ export default Ember.Component.extend(TooltipMixin, {
|
|||
|
||||
onInsertLink(link) {
|
||||
let linkMarkdown = this.get('link').buildLink(link);
|
||||
|
||||
miscUtil.insertAtCursor($("#" + this.get('editorId'))[0], linkMarkdown);
|
||||
this.set('pageBody', $("#" + this.get('editorId')).val());
|
||||
this.get('codeEditor').getDoc().replaceSelection(linkMarkdown);
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
isDirty() {
|
||||
return this.get('isDirty');
|
||||
return this.get('codeEditor').getDoc().isClean() === false;
|
||||
},
|
||||
|
||||
onCancel() {
|
||||
|
@ -94,7 +157,7 @@ export default Ember.Component.extend(TooltipMixin, {
|
|||
let page = this.get('page');
|
||||
let meta = this.get('meta');
|
||||
page.set('title', title);
|
||||
meta.set('rawBody', this.get("pageBody"));
|
||||
meta.set('rawBody', this.getBody());
|
||||
|
||||
this.attrs.onAction(page, meta);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.section-markdown-editor, .section-markdown-preview {
|
||||
.section-markdown-preview {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<div class="document-editor">
|
||||
<div class="toolbar">
|
||||
<div class="input-inline input-transparent edit-title pull-left">
|
||||
{{focus-input type="text" id=pageId value=page.title class=(if hasNameError 'error-inline') placeholder=tip class="mousetrap"}}
|
||||
{{focus-input type="text" id=pageId value=page.title class=(if hasNameError 'error-inline') placeholder="Name" class="mousetrap"}}
|
||||
</div>
|
||||
<div class="buttons pull-right">
|
||||
{{#if busy}}
|
||||
|
@ -10,12 +10,12 @@
|
|||
<div class="round-button-mono" {{action 'onAction'}}>
|
||||
<i class="material-icons color-green">check</i>
|
||||
</div>
|
||||
<div class="round-button-mono" {{action 'onCancel'}} id="editor-cancel-{{page.id}}">
|
||||
<div class="round-button-mono" {{action 'onCancel'}} id={{cancelId}}>
|
||||
<i class="material-icons color-gray">close</i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
<div class="dropdown-dialog cancel-edits-dialog" id="cancel-edits-dialog">
|
||||
<div class="dropdown-dialog cancel-edits-dialog" id={{dialogId}}>
|
||||
<div class="content">
|
||||
<p>Do you want to cancel editing and lose unsaved changes?</p>
|
||||
</div>
|
||||
|
|
|
@ -1,13 +1,23 @@
|
|||
{{#section/base-editor-inline document=document folder=folder page=page isDirty=(action 'isDirty') onCancel=(action 'onCancel') onAction=(action 'onAction')}}
|
||||
{{#section/base-editor-inline document=document folder=folder page=page tip="Concise name that describes code snippet" isDirty=(action 'isDirty') onCancel=(action 'onCancel') onAction=(action 'onAction')}}
|
||||
<style>
|
||||
.CodeMirror {
|
||||
height: auto;
|
||||
font-size: 17px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="section-markdown-preview-button round-button-mono" id={{tooltipId}} {{action 'toggleMode'}} data-tooltip="Toggle Preview" data-tooltip-position="top center">
|
||||
<i class="material-icons color-gray">visibility</i>
|
||||
</div>
|
||||
{{document/edit-tools document=document folder=folder page=page onInsertLink=(action 'onInsertLink')}}
|
||||
{{#if editMode}}
|
||||
{{focus-textarea id=editorId class="mousetrap wysiwyg section-markdown-preview" value=pageBody}}
|
||||
{{else}}
|
||||
<div class="mousetrap wysiwyg section-markdown-preview">
|
||||
{{{pagePreview}}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div class="section-code-editor">
|
||||
{{#if editMode}}
|
||||
{{focus-textarea value=pageBody id=editorId class="mousetrap"}}
|
||||
{{else}}
|
||||
<div class="mousetrap wysiwyg section-markdown-preview">
|
||||
{{{pagePreview}}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/section/base-editor-inline}}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue