1
0
Fork 0
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:
Harvey Kandola 2017-02-28 13:43:46 +00:00
parent 9d720a1c65
commit b8a0444f18
6 changed files with 122 additions and 46 deletions

View file

@ -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;
}

View file

@ -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() {

View file

@ -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);
}

View file

@ -1,4 +1,4 @@
.section-markdown-editor, .section-markdown-preview {
.section-markdown-preview {
width: 100%;
margin: 0;
padding: 0;

View file

@ -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>

View file

@ -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}}