{I" class:ETI"ProcessedAsset;FI"logical_path;TI"7blogelator/components/markdown_editor_component.js;FI" pathname;TI"x/Users/brian/github/codelation/blogelator/app/assets/javascripts/blogelator/components/markdown_editor_component.js;FI"content_type;TI"application/javascript;TI" mtime;Tl+•ÃJSI" length;Ti5I" digest;TI"%1756a527b3825b09287892fe85b56612;FI" source;TI"5 (function() { "use strict"; App.MarkdownEditorComponent = Ember.Component.extend({ classNames: ['blogelator-markdown-editor'], parseDelay: 100, resizeDelay: 50, scrollDelay: 10, didInsertElement: function() { var textArea = this.$('textarea')[0], editor = CodeMirror.fromTextArea(textArea, { autoCloseBrackets: true, indentWithTabs: false, lineWrapping: true, mode: 'gfm', smartIndent: false, tabSize: 2 }); // Replace tab with spaces editor.addKeyMap({ Tab: function(cm) { var spaces = new Array(cm.getOption("indentUnit") + 1).join(" "); cm.replaceSelection(spaces, "end", "+input"); } }); this.set('editor', editor); // Capture Command/Ctrl + S var self = this; $(this.get('element')).on('keydown', function(e) { if (e.keyCode === 83 && (e.metaKey || e.ctrlKey)) { self.sendAction(); return false; } }); }, editorDidChange: function() { var editor = this.get('editor'), preview = this.$('.html-preview .post'), parseContext = { name: 'parseMarkdown' }, parseDelay = this.get('parseDelay'), scrollContext = { name: 'scrollViewport' }, scrollDelay = this.get('scrollDelay'), viewport = $(this.get('element')), self = this; // Set initial editor value from component content editor.setValue(this.get('content')); // Syncs the preview scroll top from editor scroll top var syncEditorScrolling = function() { var viewportHeight = viewport.height(), editorScrollInfo = editor.getScrollInfo(), codeHeight = editorScrollInfo.height - viewportHeight, codeTop = editorScrollInfo.top, previewHeight = preview[0].scrollHeight - viewportHeight, ratio = previewHeight / codeHeight; preview.scrollTop(codeTop * ratio); }; // Syncs the component content w/ the new editor value // And syncs scrolling after a change occurs var updateContent = function() { self.set('content', editor.getValue()); Ember.run.debounce(scrollContext, syncEditorScrolling, scrollDelay); }; // Update preview on change editor.on('change', function() { Ember.run.debounce(parseContext, updateContent, parseDelay); }); // Scroll preview when markdown is scrolled editor.on('scroll', function() { Ember.run.debounce(scrollContext, syncEditorScrolling, scrollDelay); }); // Handle image drag and drop uploading this._addInlineAttach(editor); }.observes('editor'), html: function() { var content = this.get('content'); if (Ember.isNone(content)) { content = ''; } return marked(content); }.property('content'), willDestroyElement: function() { // Remove scrolling observers var editor = this.get('editor'); editor.off('change'); editor.off('scroll'); // Remove Command/Ctrl + S observer $(this.get('element')).off('keydown'); }, _addInlineAttach: function(editor) { function CodeMirrorEditor(instance) { var codeMirror = instance; return { getValue: function() { return codeMirror.getValue(); }, setValue: function(val) { var cursor = codeMirror.getCursor(); codeMirror.setValue(val); codeMirror.setCursor(cursor); } }; } CodeMirrorEditor.prototype = new inlineAttach.Editor(); var inlineAttachInstance, inlineAttachEditor = new CodeMirrorEditor(editor); inlineAttachInstance = new inlineAttach({ customUploadHandler: function(file) { var formData = new FormData(), filename = 'image-', extension = 'png', uploadUrl = (App.get('appPath') === '/' ? '/' : App.get('appPath') + '/') + 'api/images'; // Attach the file. If coming from clipboard, add a default filename (only works in Chrome for now) // http://stackoverflow.com/questions/6664967/how-to-give-a-blob-uploaded-as-formdata-a-file-name if (file.name) { var fileNameMatches = file.name.match(/\.(.+)$/); if (fileNameMatches) { extension = fileNameMatches[1]; filename = file.name.replace('.' + extension, '-'); } } formData.append('file', file, filename + Date.now() + '.' + extension); $.ajax({ url: uploadUrl, data: formData, processData: false, contentType: false, type: 'POST', success: function(data){ inlineAttachInstance.onUploadedFile(data); }, error: function() { inlineAttachInstance.onErrorUploading(); } }); return false; }, urlText: "![image]({filename})" }, inlineAttachEditor); editor.setOption('onDragEvent', function(data, e) { if (e.type === "drop") { e.stopPropagation(); e.preventDefault(); return inlineAttachInstance.onDrop(e); } }); } }); })(); ;TI"dependency_digest;TI"%d1dee6bb593e591b0851c83ffc661001;FI"required_paths;T[I"l/Users/brian/github/codelation/blogelator/vendor/assets/javascripts/blogelator/codemirror/codemirror.js;FI"o/Users/brian/github/codelation/blogelator/vendor/assets/javascripts/blogelator/codemirror/closebrackets.js;FI"i/Users/brian/github/codelation/blogelator/vendor/assets/javascripts/blogelator/codemirror/overlay.js;FI"j/Users/brian/github/codelation/blogelator/vendor/assets/javascripts/blogelator/codemirror/markdown.js;FI"e/Users/brian/github/codelation/blogelator/vendor/assets/javascripts/blogelator/codemirror/gfm.js;FI"n/Users/brian/github/codelation/blogelator/vendor/assets/javascripts/blogelator/codemirror/coffeescript.js;FI"e/Users/brian/github/codelation/blogelator/vendor/assets/javascripts/blogelator/codemirror/css.js;FI"k/Users/brian/github/codelation/blogelator/vendor/assets/javascripts/blogelator/codemirror/htmlmixed.js;FI"l/Users/brian/github/codelation/blogelator/vendor/assets/javascripts/blogelator/codemirror/javascript.js;FI"e/Users/brian/github/codelation/blogelator/vendor/assets/javascripts/blogelator/codemirror/php.js;FI"f/Users/brian/github/codelation/blogelator/vendor/assets/javascripts/blogelator/codemirror/ruby.js;FI"f/Users/brian/github/codelation/blogelator/vendor/assets/javascripts/blogelator/codemirror/sass.js;FI"e/Users/brian/github/codelation/blogelator/vendor/assets/javascripts/blogelator/codemirror/xml.js;FI"f/Users/brian/github/codelation/blogelator/vendor/assets/javascripts/blogelator/codemirror/yaml.js;FI"d/Users/brian/github/codelation/blogelator/vendor/assets/javascripts/blogelator/inline-attach.js;FI"]/Users/brian/github/codelation/blogelator/vendor/assets/javascripts/blogelator/marked.js;FI"x/Users/brian/github/codelation/blogelator/app/assets/javascripts/blogelator/components/markdown_editor_component.js;FI"dependency_paths;T[{I" path;TI"x/Users/brian/github/codelation/blogelator/app/assets/javascripts/blogelator/components/markdown_editor_component.js;FI" mtime;TI"2014-04-13T12:04:21-05:00;TI" digest;TI"%b1b3f73cd7359fe31f21943ef0e6c4ac;F{@-I"l/Users/brian/github/codelation/blogelator/vendor/assets/javascripts/blogelator/codemirror/codemirror.js;F@/I"2014-02-23T08:54:12-06:00;T@1I"%926fc672385f501803fb4c53ec077c52;F{@-I"o/Users/brian/github/codelation/blogelator/vendor/assets/javascripts/blogelator/codemirror/closebrackets.js;F@/I"2014-02-25T23:19:02-06:00;T@1I"%7ee32b4aaeb1dfe1ab01f9538f85503e;F{@-I"i/Users/brian/github/codelation/blogelator/vendor/assets/javascripts/blogelator/codemirror/overlay.js;F@/I"2014-02-21T15:22:50-06:00;T@1I"%f6b491f86ba7c7101e10018a0be781ba;F{@-I"j/Users/brian/github/codelation/blogelator/vendor/assets/javascripts/blogelator/codemirror/markdown.js;F@/I"2014-02-21T15:22:50-06:00;T@1I"%b46074b370f22fe77814adc9c9e73ecc;F{@-I"e/Users/brian/github/codelation/blogelator/vendor/assets/javascripts/blogelator/codemirror/gfm.js;F@/I"2014-02-21T15:22:50-06:00;T@1I"%4475cf3750008c5b99203558cdead667;F{@-I"n/Users/brian/github/codelation/blogelator/vendor/assets/javascripts/blogelator/codemirror/coffeescript.js;F@/I"2014-02-21T15:22:50-06:00;T@1I"%182ae735198c84bf4274aa44171410db;F{@-I"e/Users/brian/github/codelation/blogelator/vendor/assets/javascripts/blogelator/codemirror/css.js;F@/I"2014-02-21T15:22:50-06:00;T@1I"%cd5c7a46bbc0b533823b7f94575199db;F{@-I"k/Users/brian/github/codelation/blogelator/vendor/assets/javascripts/blogelator/codemirror/htmlmixed.js;F@/I"2014-02-21T15:22:50-06:00;T@1I"%d9af332115628a7d70ec2742ba20a215;F{@-I"l/Users/brian/github/codelation/blogelator/vendor/assets/javascripts/blogelator/codemirror/javascript.js;F@/I"2014-02-21T15:22:50-06:00;T@1I"%11d91022c67e36a5a22ce70ef343ef17;F{@-I"e/Users/brian/github/codelation/blogelator/vendor/assets/javascripts/blogelator/codemirror/php.js;F@/I"2014-02-21T15:22:50-06:00;T@1I"%23f136e9719ca95e38f6a4b87cb5ac6f;F{@-I"f/Users/brian/github/codelation/blogelator/vendor/assets/javascripts/blogelator/codemirror/ruby.js;F@/I"2014-02-21T15:22:50-06:00;T@1I"%6df77b4fea93c0162adc69810c603640;F{@-I"f/Users/brian/github/codelation/blogelator/vendor/assets/javascripts/blogelator/codemirror/sass.js;F@/I"2014-02-21T15:22:50-06:00;T@1I"%41d9775e96519e2f4d9bc0f68162e4f6;F{@-I"e/Users/brian/github/codelation/blogelator/vendor/assets/javascripts/blogelator/codemirror/xml.js;F@/I"2014-02-21T15:22:50-06:00;T@1I"%e1d2da1c6b21c00b9fdb0e69e577ab8d;F{@-I"f/Users/brian/github/codelation/blogelator/vendor/assets/javascripts/blogelator/codemirror/yaml.js;F@/I"2014-02-21T15:22:50-06:00;T@1I"%f31393e38c27e72c82c7524eb831a521;F{@-I"d/Users/brian/github/codelation/blogelator/vendor/assets/javascripts/blogelator/inline-attach.js;F@/I"2014-03-09T14:38:49-05:00;T@1I"%7df146a7eb8ebe48b7e3e4a7b64c1443;F{@-I"]/Users/brian/github/codelation/blogelator/vendor/assets/javascripts/blogelator/marked.js;F@/I"2014-02-23T11:11:13-06:00;T@1I"%3be99b224b787e6ada2279b594ee2ecd;FI" _version;TI"%a56df69ef97ba4d9f1a23bf9b0add58a;F