{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+LSI" length;Ti5I" digest;TI"%1ff550e06ee56024e0d7a9ef957761d4;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"%c4d8319302966f6159e278e335817036;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-14T11:04:47-05:00;TI" digest;TI"%61be60cb882a86f4ad3795c40b421b48;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"%120269c2b20335f4c8c559b71ef84498;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"%91c2cee031b9aff6ce0ade23272b755d;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"%7d79a82dff74217e0d684d52c3d82538;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"%3018862697597b6f48a113f50ddaecc0;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"%0ac3d84794e598f056f1a320bd793c69;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"%c7ce0cdbbe721ce15460ce881ee7bb22;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"%0a68815cef989c605c523cf8492129d7;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"%e15e4451f7e2ae8e45cf9acfa48ede45;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"%5cad46ec88dcb01ef4b2c30ed9522a55;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"%34762eac31f7b2247437b046131bba41;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"%2a81f2ad9511e2cd1d6798ee38f0d010;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"%65b85c386a7ad4ab86c08f904d58c36d;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"%f33dcc4a594babdbb27be3189ddd525b;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"%806536402441d3688ade06651149bd8a;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"%999cbe316ddcda376f46a4be1e511f1f;F{@-I"]/Users/brian/github/codelation/blogelator/vendor/assets/javascripts/blogelator/marked.js;F@/I"2014-02-23T11:11:13-06:00;T@1I"%7ffb9af7aa4f22177b31e76f1638ffbd;FI" _version;TI"%361c512b9086418778df946c0d278f91;F