Skip to content

Commit

Permalink
Merge pull request TryGhost#2398 from ErisDS/cm-refactor
Browse files Browse the repository at this point in the history
CodeMirror Refactor & Upgrade
  • Loading branch information
ErisDS committed Mar 17, 2014
2 parents 6943fa5 + 00667f5 commit c09c196
Show file tree
Hide file tree
Showing 11 changed files with 927 additions and 670 deletions.
22 changes: 17 additions & 5 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,7 @@ var path = require('path'),
concat: {
files: [
'core/client/*.js',
'core/client/helpers/*.js',
'core/client/models/*.js',
'core/client/tpl/*.js',
'core/client/views/*.js'
'core/client/**/*.js'
],
tasks: ['concat']
},
Expand Down Expand Up @@ -482,7 +479,14 @@ var path = require('path'),
'core/client/mobile-interactions.js',
'core/client/toggle.js',
'core/client/markdown-actions.js',
'core/client/helpers/index.js'
'core/client/helpers/index.js',
'core/client/assets/lib/editor/index.js',
'core/client/assets/lib/editor/markerManager.js',
'core/client/assets/lib/editor/uploadManager.js',
'core/client/assets/lib/editor/markdownEditor.js',
'core/client/assets/lib/editor/htmlPreview.js',
'core/client/assets/lib/editor/scrollHandler.js'

],

'core/built/scripts/templates.js': [
Expand Down Expand Up @@ -538,6 +542,14 @@ var path = require('path'),
'core/client/markdown-actions.js',
'core/client/helpers/index.js',

'core/client/assets/lib/editor/index.js',
'core/client/assets/lib/editor/markerManager.js',
'core/client/assets/lib/editor/uploadManager.js',
'core/client/assets/lib/editor/markdownEditor.js',
'core/client/assets/lib/editor/htmlPreview.js',
'core/client/assets/lib/editor/scrollHandler.js',


'core/client/tpl/hbs-tpl.js',

'core/client/models/**/*.js',
Expand Down
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "ghost",
"dependencies": {
"backbone": "1.0.0",
"codemirror": "3.15.0",
"codemirror": "4.0.1",
"Countable": "2.0.2",
"fastclick": "1.0.0",
"ghost-ui": "0.1.2",
Expand Down
44 changes: 44 additions & 0 deletions core/client/assets/lib/editor/htmlPreview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// # Ghost Editor HTML Preview
//
// HTML Preview is the right pane in the split view editor.
// It is effectively just a scrolling container for the HTML output from showdown
// It knows how to update itself, and that's pretty much it.

/*global Ghost, Showdown, Countable, _, $ */
(function () {
'use strict';

var HTMLPreview = function (markdown, uploadMgr) {
var converter = new Showdown.converter({extensions: ['typography', 'ghostdown', 'github']}),
preview = document.getElementsByClassName('rendered-markdown')[0],
update;

// Update the preview
// Includes replacing all the HTML, intialising upload dropzones, and updating the counter
update = function () {
preview.innerHTML = converter.makeHtml(markdown.value());

uploadMgr.enable();

Countable.once(preview, function (counter) {
$('.entry-word-count').text($.pluralize(counter.words, 'word'));
$('.entry-character-count').text($.pluralize(counter.characters, 'character'));
$('.entry-paragraph-count').text($.pluralize(counter.paragraphs, 'paragraph'));
});
};

// Public API
_.extend(this, {
scrollViewPort: function () {
return $('.entry-preview-content');
},
scrollContent: function () {
return $('.rendered-markdown');
},
update: update
});
};

Ghost.Editor = Ghost.Editor || {};
Ghost.Editor.HTMLPreview = HTMLPreview;
} ());
79 changes: 79 additions & 0 deletions core/client/assets/lib/editor/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// # Ghost Editor
//
// Ghost Editor contains a set of modules which make up the editor component
// It manages the left and right panes, and all of the communication between them
// Including scrolling,

/*global document, $, _, Ghost */
(function () {
'use strict';

var Editor = function () {
var self = this,
$document = $(document),
// Create all the needed editor components, passing them what they need to function
markdown = new Ghost.Editor.MarkdownEditor(),
uploadMgr = new Ghost.Editor.UploadManager(markdown),
preview = new Ghost.Editor.HTMLPreview(markdown, uploadMgr),
scrollHandler = new Ghost.Editor.ScrollHandler(markdown, preview),
unloadDirtyMessage,
handleChange,
handleDrag;

unloadDirtyMessage = function () {
return '==============================\n\n' +
'Hey there! It looks like you\'re in the middle of writing' +
' something and you haven\'t saved all of your content.' +
'\n\nSave before you go!\n\n' +
'==============================';
};

handleChange = function () {
self.setDirty(true);
preview.update();
};

handleDrag = function (e) {
e.preventDefault();
};

// Public API
_.extend(this, {
enable: function () {
// Listen for changes
$document.on('markdownEditorChange', handleChange);

// enable editing and scrolling
markdown.enable();
scrollHandler.enable();
},

disable: function () {
// Don't listen for changes
$document.off('markdownEditorChange', handleChange);

// disable editing and scrolling
markdown.disable();
scrollHandler.disable();
},

// Get the markdown value from the editor for saving
// Upload manager makes sure the upload markers are removed beforehand
value: function () {
return uploadMgr.value();
},

setDirty: function (dirty) {
window.onbeforeunload = dirty ? unloadDirtyMessage : null;
}
});

// Initialise
$document.on('drop dragover', handleDrag);
preview.update();
this.enable();
};

Ghost.Editor = Ghost.Editor || {};
Ghost.Editor.Main = Editor;
}());
92 changes: 92 additions & 0 deletions core/client/assets/lib/editor/markdownEditor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// # Ghost Editor Markdown Editor
//
// Markdown Editor is a light wrapper around CodeMirror

/*global Ghost, CodeMirror, shortcut, _, $ */
(function () {
'use strict';

var MarkdownShortcuts,
MarkdownEditor;

MarkdownShortcuts = [
{'key': 'Ctrl+B', 'style': 'bold'},
{'key': 'Meta+B', 'style': 'bold'},
{'key': 'Ctrl+I', 'style': 'italic'},
{'key': 'Meta+I', 'style': 'italic'},
{'key': 'Ctrl+Alt+U', 'style': 'strike'},
{'key': 'Ctrl+Shift+K', 'style': 'code'},
{'key': 'Meta+K', 'style': 'code'},
{'key': 'Ctrl+Alt+1', 'style': 'h1'},
{'key': 'Ctrl+Alt+2', 'style': 'h2'},
{'key': 'Ctrl+Alt+3', 'style': 'h3'},
{'key': 'Ctrl+Alt+4', 'style': 'h4'},
{'key': 'Ctrl+Alt+5', 'style': 'h5'},
{'key': 'Ctrl+Alt+6', 'style': 'h6'},
{'key': 'Ctrl+Shift+L', 'style': 'link'},
{'key': 'Ctrl+Shift+I', 'style': 'image'},
{'key': 'Ctrl+Q', 'style': 'blockquote'},
{'key': 'Ctrl+Shift+1', 'style': 'currentDate'},
{'key': 'Ctrl+U', 'style': 'uppercase'},
{'key': 'Ctrl+Shift+U', 'style': 'lowercase'},
{'key': 'Ctrl+Alt+Shift+U', 'style': 'titlecase'},
{'key': 'Ctrl+Alt+W', 'style': 'selectword'},
{'key': 'Ctrl+L', 'style': 'list'},
{'key': 'Ctrl+Alt+C', 'style': 'copyHTML'},
{'key': 'Meta+Alt+C', 'style': 'copyHTML'},
{'key': 'Meta+Enter', 'style': 'newLine'},
{'key': 'Ctrl+Enter', 'style': 'newLine'}
];

MarkdownEditor = function () {
var codemirror = CodeMirror.fromTextArea(document.getElementById('entry-markdown'), {
mode: 'gfm',
tabMode: 'indent',
tabindex: '2',
cursorScrollMargin: 10,
lineWrapping: true,
dragDrop: false,
extraKeys: {
Home: 'goLineLeft',
End: 'goLineRight'
}
});

// Markdown shortcuts for the editor
_.each(MarkdownShortcuts, function (combo) {
shortcut.add(combo.key, function () {
return codemirror.addMarkdown({style: combo.style});
});
});

// Public API
_.extend(this, {
codemirror: codemirror,

scrollViewPort: function () {
return $('.CodeMirror-scroll');
},
scrollContent: function () {
return $('.CodeMirror-sizer');
},
enable: function () {
codemirror.setOption('readOnly', false);
codemirror.on('change', function () {
$(document).trigger('markdownEditorChange');
});
},
disable: function () {
codemirror.setOption('readOnly', 'nocursor');
codemirror.off('change', function () {
$(document).trigger('markdownEditorChange');
});
},
value: function () {
return codemirror.getValue();
}
});
};

Ghost.Editor = Ghost.Editor || {};
Ghost.Editor.MarkdownEditor = MarkdownEditor;
} ());
Loading

0 comments on commit c09c196

Please sign in to comment.