Merge pull request #393 from matthojo/Modal-Fixes

Several Modal Fixes
This commit is contained in:
Hannah Wolfe 2013-08-18 09:05:49 -07:00
commit e794e8de7a
5 changed files with 103 additions and 57 deletions

View File

@ -902,6 +902,7 @@ nav {
left: 0;
right: 0;
z-index: 999;
@include transition(background 300ms ease);
&.dark {
background: rgba(0,0,0,0.4);
@ -920,8 +921,14 @@ nav {
}
body.blur > *:not(#modal-container) {
@include transition(all 300ms ease);
-webkit-filter: blur(2px);
filter: blur(2px); // Not used yet
-moz-filter: blur(2px);
-ms-filter: blur(2px);
-o-filter: blur(2px);
filter: blur(2px);
@include transform(translateZ(0));
}
%modal, .modal {

View File

@ -1,6 +1,6 @@
// # Surrounds given text with Markdown syntax
/*global $, window, CodeMirror, Showdown */
/*global $, window, CodeMirror, Showdown, moment */
(function () {
"use strict";
var Markdown = {
@ -15,8 +15,50 @@
self.replace();
},
replace: function () {
var text = this.elem.getSelection(), pass = true, md, cursor, word, converter;
var text = this.elem.getSelection(), pass = true, md, cursor, line, word, converter;
switch (this.style) {
case "h1":
cursor = this.elem.getCursor();
line = this.elem.getLine(cursor.line);
this.elem.setLine(cursor.line, "# " + line);
this.elem.setCursor(cursor.line, cursor.ch + 2);
pass = false;
break;
case "h2":
cursor = this.elem.getCursor();
line = this.elem.getLine(cursor.line);
this.elem.setLine(cursor.line, "## " + line);
this.elem.setCursor(cursor.line, cursor.ch + 3);
pass = false;
break;
case "h3":
cursor = this.elem.getCursor();
line = this.elem.getLine(cursor.line);
this.elem.setLine(cursor.line, "### " + line);
this.elem.setCursor(cursor.line, cursor.ch + 4);
pass = false;
break;
case "h4":
cursor = this.elem.getCursor();
line = this.elem.getLine(cursor.line);
this.elem.setLine(cursor.line, "#### " + line);
this.elem.setCursor(cursor.line, cursor.ch + 5);
pass = false;
break;
case "h5":
cursor = this.elem.getCursor();
line = this.elem.getLine(cursor.line);
this.elem.setLine(cursor.line, "##### " + line);
this.elem.setCursor(cursor.line, cursor.ch + 6);
pass = false;
break;
case "h6":
cursor = this.elem.getCursor();
line = this.elem.getLine(cursor.line);
this.elem.setLine(cursor.line, "###### " + line);
this.elem.setCursor(cursor.line, cursor.ch + 7);
pass = false;
break;
case "link":
md = this.options.syntax.link.replace('$1', text);
this.elem.replaceSelection(md, "end");
@ -58,9 +100,12 @@
break;
case "list":
md = text.replace(/^/gm, "* ");
this.elem.replaceSelection("\n" + md + "\n", "end");
this.elem.replaceSelection(md, "end");
pass = false;
break;
case "currentDate":
md = moment(new Date()).format("D MMMM YYYY");
break;
default:
if (this.options.syntax[this.style]) {
md = this.options.syntax[this.style].replace('$1', text);
@ -84,16 +129,9 @@
italic: "_$1_",
strike: "~~$1~~",
code: "`$1`",
h1: "\n# $1\n",
h2: "\n## $1\n",
h3: "\n### $1\n",
h4: "\n#### $1\n",
h5: "\n##### $1\n",
h6: "\n###### $1\n",
link: "[$1](http://)",
image: "!image[$1](http://)",
blockquote: "> $1",
currentDate: new Date().toLocaleString()
blockquote: "> $1"
}
};

View File

@ -50,37 +50,37 @@
<tr>
<td>H1</td>
<td># Heading</td>
<td>Alt + 1</td>
<td>Ctrl + Alt + 1</td>
</tr>
<tr>
<td>H2</td>
<td>## Heading</td>
<td>Alt + 2</td>
<td>Ctrl + Alt + 2</td>
</tr>
<tr>
<td>H3</td>
<td>### Heading</td>
<td>Alt + 3</td>
<td>Ctrl + Alt + 3</td>
</tr>
<tr>
<td>H4</td>
<td>#### Heading</td>
<td>Alt + 4</td>
<td>Ctrl + Alt + 4</td>
</tr>
<tr>
<td>H5</td>
<td>##### Heading</td>
<td>Alt + 5</td>
<td>Ctrl + Alt + 5</td>
</tr>
<tr>
<td>H6</td>
<td>###### Heading</td>
<td>Alt + 6</td>
<td>Ctrl + Alt + 6</td>
</tr>
<tr>
<td>Select Word</td>
<td></td>
<td>Ctrl + Option + W</td>
<td>Ctrl + Alt + W</td>
</tr>
<tr>
<td>Uppercase</td>
@ -95,7 +95,7 @@
<tr>
<td>Titlecase</td>
<td></td>
<td>Ctrl + Option + Shift + U</td>
<td>Ctrl + Alt + Shift + U</td>
</tr>
<tr>
<td>Insert Current Date</td>

View File

@ -173,99 +173,100 @@
}
});
/**
* This is the view to generate the markup for the individual
* modal. Will be included into #modals.
*
*
*
* Types can be
* - (empty)
*
*/
// ## Modals
Ghost.Views.Modal = Ghost.View.extend({
el: '#modal-container',
templateName: 'modal',
className: 'js-bb-modal',
// Render and manages modal dismissal
initialize: function () {
this.render();
var self = this;
if (!this.model.options.confirm) {
shortcut.add("ESC", function () {
self.removeItem();
self.removeElement();
});
$(document).on('click', '.modal-background', function (e) {
self.removeItem(e);
self.removeElement(e);
});
} else {
// Initiate functions for buttons here so models don't get tied up.
this.acceptModal = function () {
this.model.options.confirm.accept.func();
self.removeItem();
self.removeElement();
};
this.rejectModal = function () {
this.model.options.confirm.reject.func();
self.removeItem();
self.removeElement();
};
shortcut.remove("ESC");
$(document).off('click', '.modal-background');
}
},
template: function (data) {
return JST[this.templateName](data);
templateData: function () {
return this.model;
},
events: {
'click .close': 'removeItem',
'click .close': 'removeElement',
'click .js-button-accept': 'acceptModal',
'click .js-button-reject': 'rejectModal'
},
render: function () {
this.$el.html(this.template(this.model));
afterRender: function () {
this.$(".modal-content").html(this.addSubview(new Ghost.Views.Modal.ContentView({model: this.model})).render().el);
this.$el.children(".js-modal").center();
this.$el.addClass("active");
this.$el.children(".js-modal").center().css("max-height", $(window).height() - 120); // same as resize(), but the debounce causes init lag
this.$el.addClass("active dark");
if (document.body.style.webkitFilter !== undefined) { // Detect webkit filters
$("body").addClass("blur");
} else {
this.$el.addClass("dark");
}
return this;
var self = this;
$(window).on('resize', self.resize);
},
// #### resize
// Center and resize modal based on window height
resize: _.debounce(function () {
$(".js-modal").center().css("max-height", $(window).height() - 120);
}, 50),
// #### remove
// Removes Backbone attachments from modals
remove: function () {
this.undelegateEvents();
this.$el.empty();
this.stopListening();
return this;
},
removeItem: function (e) {
// #### removeElement
// Visually removes the modal from the user interface
removeElement: function (e) {
if (e) {
e.preventDefault();
e.stopPropagation();
}
var self = this;
this.$el.removeClass('dark');
$('.js-modal').fadeOut(300, function () {
$(this).remove();
$("#modal-container").removeClass('active dark');
if (document.body.style.filter !== undefined) {
$("body").removeClass("blur");
}
self.remove();
self.$el.removeClass('active');
});
this.remove();
}
});
/**
* Modal Content
* @type {*}
*/
// ## Modal Content
Ghost.Views.Modal.ContentView = Ghost.View.extend({
template: function (data) {
return JST['modals/' + this.model.content.template](data);
},
render: function () {
this.$el.html(this.template(this.model));
return this;
templateData: function () {
return this.model;
}
});

View File

@ -23,14 +23,14 @@
{'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+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': 'CMD+Alt+C', 'style': 'copyHTML'}
{'key': 'Meta+Alt+C', 'style': 'copyHTML'}
];
// The publish bar associated with a post, which has the TagWidget and