Add shim for codemirror on touchscreens

fixes #2385

- stolen the CM shim from js-bin
- if we're on a touchscreen device, don't use CM
- if we're on a touchscreen device, show a coming soon message for uploads
This commit is contained in:
Hannah Wolfe 2014-03-17 22:01:29 +00:00
parent c09c196162
commit 5bed81563e
6 changed files with 150 additions and 14 deletions

1
.gitignore vendored
View File

@ -34,7 +34,6 @@ projectFilesBackup
/core/client/tpl/hbs-tpl.js
/core/client/assets/css
/core/client/assets/fonts
/core/client/assets/vendor
/core/server/data/export/exported*
/docs
/_site

View File

@ -485,8 +485,8 @@ var path = require('path'),
'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/assets/lib/editor/scrollHandler.js',
'core/client/assets/lib/editor/mobileCodeMirror.js'
],
'core/built/scripts/templates.js': [
@ -548,7 +548,7 @@ var path = require('path'),
'core/client/assets/lib/editor/markdownEditor.js',
'core/client/assets/lib/editor/htmlPreview.js',
'core/client/assets/lib/editor/scrollHandler.js',
'core/client/assets/lib/editor/mobileCodeMirror.js',
'core/client/tpl/hbs-tpl.js',

View File

@ -0,0 +1,112 @@
// Taken from js-bin with thanks to Remy Sharp
// yeah, nasty, but it allows me to switch from a RTF to plain text if we're running a iOS
/*global Ghost, $, _, DocumentTouch, CodeMirror*/
(function () {
Ghost.touchEditor = false;
var noop = function () {},
hasTouchScreen,
smallScreen,
TouchEditor,
_oldCM,
key;
// Taken from "Responsive design & the Guardian" with thanks to Matt Andrews
// Added !window._phantom so that the functional tests run as though this is not a touch screen.
// In future we can do something more advanced here for testing both touch and non touch
hasTouchScreen = function () {
return !window._phantom &&
(
('ontouchstart' in window) ||
(window.DocumentTouch && document instanceof DocumentTouch)
);
};
smallScreen = function () {
if (window.matchMedia('(max-width: 1000px)').matches) {
return true;
}
return false;
};
if (hasTouchScreen()) {
$('body').addClass('touch-editor');
Ghost.touchEditor = true;
TouchEditor = function (el, options) {
/*jshint unused:false*/
this.textarea = el;
this.win = { document : this.textarea };
this.ready = true;
this.wrapping = document.createElement('div');
var textareaParent = this.textarea.parentNode;
this.wrapping.appendChild(this.textarea);
textareaParent.appendChild(this.wrapping);
this.textarea.style.opacity = 1;
$(this.textarea).blur(_.throttle(function () {
$(document).trigger('markdownEditorChange', { panelId: el.id });
}, 200));
if (!smallScreen()) {
$(this.textarea).on('change', _.throttle(function () {
$(document).trigger('markdownEditorChange', { panelId: el.id });
}, 200));
}
};
TouchEditor.prototype = {
setOption: function (type, handler) {
if (type === 'onChange') {
$(this.textarea).change(handler);
}
},
eachLine: function () {
return [];
},
getValue: function () {
return this.textarea.value;
},
setValue: function (code) {
this.textarea.value = code;
},
focus: noop,
getCursor: function () {
return { line: 0, ch: 0 };
},
setCursor: noop,
currentLine: function () {
return 0;
},
cursorPosition: function () {
return { character: 0 };
},
addMarkdown: noop,
nthLine: noop,
refresh: noop,
selectLines: noop,
on: noop
};
_oldCM = CodeMirror;
// CodeMirror = noop;
for (key in _oldCM) {
if (_oldCM.hasOwnProperty(key)) {
CodeMirror[key] = noop;
}
}
CodeMirror.fromTextArea = function (el, options) {
return new TouchEditor(el, options);
};
CodeMirror.keyMap = { basic: {} };
}
}());

View File

@ -1,4 +1,5 @@
/* jshint node:true, browser:true */
var Ghost = Ghost || {};
(function () {
var ghostdown = function () {
return [
@ -12,15 +13,24 @@
pathRegex = /^(\/)?([^\/\0]+(\/)?)+$/i;
return text.replace(imageMarkdownRegex, function (match, key, alt, src) {
var result = "";
var result = '',
output;
if (src && (src.match(uriRegex) || src.match(pathRegex))) {
result = '<img class="js-upload-target" src="' + src + '"/>';
}
return '<section id="image_upload_' + key + '" class="js-drop-zone image-uploader">' + result +
'<div class="description">Add image of <strong>' + alt + '</strong></div>' +
'<input data-url="upload" class="js-fileupload main fileupload" type="file" name="uploadimage">' +
'</section>';
if (Ghost && Ghost.touchEditor) {
output = '<section class="image-uploader">' +
result + '<div class="description">Mobile uploads coming soon</div></section>';
} else {
output = '<section id="image_upload_' + key + '" class="js-drop-zone image-uploader">' +
result + '<div class="description">Add image of <strong>' + alt + '</strong></div>' +
'<input data-url="upload" class="js-fileupload main fileupload" type="file" name="uploadimage">' +
'</section>';
}
return output;
});
}
},

View File

@ -1,4 +1,15 @@
{{!< default}}
<style>
/* Additional styling for touch editor, will be moved in future */
.touch-editor #entry-markdown {
padding: 15px;
margin-bottom: 40px;
font-family: monospace;
font-size: 1.4em;
line-height: 1.3em;
color: #242628;
}
</style>
<section class="entry-container">
<header>
<section class="box entry-title">

View File

@ -49,12 +49,16 @@ var DEBUG = false, // TOGGLE THIS TO GET MORE SCREENSHOTS
casper.writeContentToCodeMirror = function (content) {
var lines = content.split("\n");
casper.each(lines, function (self, line) {
self.sendKeys('.CodeMirror-wrap textarea', line, {keepFocus: true});
self.sendKeys('.CodeMirror-wrap textarea', casper.page.event.key.Enter, {keepFocus: true});
});
casper.waitForSelector('.CodeMirror-wrap textarea', function onSuccess() {
casper.each(lines, function (self, line) {
self.sendKeys('.CodeMirror-wrap textarea', line, {keepFocus: true});
self.sendKeys('.CodeMirror-wrap textarea', casper.page.event.key.Enter, {keepFocus: true});
});
return this;
return this;
}, function onTimeout() {
casper.test.fail('CodeMirror was not found.');
}, 2000);
};
casper.waitForOpaque = function (classname, then, timeout) {