diff --git a/app/app/components/section/base-editor-inline.js b/app/app/components/section/base-editor-inline.js index ce968fc1..2ce3a97a 100644 --- a/app/app/components/section/base-editor-inline.js +++ b/app/app/components/section/base-editor-inline.js @@ -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; } diff --git a/app/app/components/section/code/type-editor.js b/app/app/components/section/code/type-editor.js index dc7e5b78..2bf87e5a 100644 --- a/app/app/components/section/code/type-editor.js +++ b/app/app/components/section/code/type-editor.js @@ -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() { diff --git a/app/app/components/section/markdown/type-editor.js b/app/app/components/section/markdown/type-editor.js index 6728c85d..f532be08 100644 --- a/app/app/components/section/markdown/type-editor.js +++ b/app/app/components/section/markdown/type-editor.js @@ -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("", ""); + + cleanBody = cleanBody.replace('
');
+        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);
 		}
diff --git a/app/app/styles/section/markdown.scss b/app/app/styles/section/markdown.scss
index c2ef35f8..b0546d64 100644
--- a/app/app/styles/section/markdown.scss
+++ b/app/app/styles/section/markdown.scss
@@ -1,4 +1,4 @@
-.section-markdown-editor, .section-markdown-preview {
+.section-markdown-preview {
 	width: 100%;
 	margin: 0;
 	padding: 0;
diff --git a/app/app/templates/components/section/base-editor-inline.hbs b/app/app/templates/components/section/base-editor-inline.hbs
index 8437a3dc..d853d78e 100644
--- a/app/app/templates/components/section/base-editor-inline.hbs
+++ b/app/app/templates/components/section/base-editor-inline.hbs
@@ -1,7 +1,7 @@
 
- {{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"}}
{{#if busy}} @@ -10,12 +10,12 @@
check
-
+
close
-