Dan Brown

Improved error messages for image uploads and formatted much js

1 "use strict"; 1 "use strict";
2 2
3 -module.exports = function(ngApp) { 3 +module.exports = function (ngApp) {
4 - 4 +
5 - ngApp.controller('ImageManagerController', ['$scope', '$attrs', '$http', '$timeout','imageManagerService', 5 + ngApp.controller('ImageManagerController', ['$scope', '$attrs', '$http', '$timeout', 'imageManagerService',
6 - function($scope, $attrs, $http, $timeout, imageManagerService) { 6 + function ($scope, $attrs, $http, $timeout, imageManagerService) {
7 - $scope.images = []; 7 + $scope.images = [];
8 - $scope.imageType = $attrs.imageType; 8 + $scope.imageType = $attrs.imageType;
9 - $scope.selectedImage = false; 9 + $scope.selectedImage = false;
10 - $scope.dependantPages = false; 10 + $scope.dependantPages = false;
11 - $scope.showing = false;
12 - $scope.hasMore = false;
13 - $scope.imageUpdateSuccess = false;
14 - $scope.imageDeleteSuccess = false;
15 - var page = 0;
16 - var previousClickTime = 0;
17 - var dataLoaded = false;
18 - var callback = false;
19 -
20 - $scope.getUploadUrl = function() {
21 - return '/images/' + $scope.imageType + '/upload';
22 - };
23 -
24 - $scope.uploadSuccess = function(file, data) {
25 - $scope.$apply(() => {
26 - $scope.images.unshift(data);
27 - });
28 - };
29 -
30 - function callbackAndHide(returnData) {
31 - if (callback) callback(returnData);
32 $scope.showing = false; 11 $scope.showing = false;
33 - } 12 + $scope.hasMore = false;
34 - 13 + $scope.imageUpdateSuccess = false;
35 - $scope.imageSelect = function (image) { 14 + $scope.imageDeleteSuccess = false;
36 - var dblClickTime = 300; 15 + var page = 0;
37 - var currentTime = Date.now(); 16 + var previousClickTime = 0;
38 - var timeDiff = currentTime - previousClickTime; 17 + var dataLoaded = false;
39 - 18 + var callback = false;
40 - if (timeDiff < dblClickTime) { 19 +
41 - // If double click 20 + $scope.getUploadUrl = function () {
42 - callbackAndHide(image); 21 + return '/images/' + $scope.imageType + '/upload';
43 - } else { 22 + };
44 - // If single 23 +
45 - $scope.selectedImage = image; 24 + $scope.uploadSuccess = function (file, data) {
46 - $scope.dependantPages = false; 25 + $scope.$apply(() => {
47 - } 26 + $scope.images.unshift(data);
48 - previousClickTime = currentTime; 27 + });
49 - }; 28 + };
50 -
51 - $scope.selectButtonClick = function() {
52 - callbackAndHide($scope.selectedImage);
53 - };
54 29
55 - function show(doneCallback) { 30 + function callbackAndHide(returnData) {
56 - callback = doneCallback; 31 + if (callback) callback(returnData);
57 - $scope.showing = true; 32 + $scope.showing = false;
58 - // Get initial images if they have not yet been loaded in.
59 - if (!dataLoaded) {
60 - fetchData();
61 - dataLoaded = true;
62 } 33 }
63 - }
64 34
65 - imageManagerService.show = show; 35 + $scope.imageSelect = function (image) {
66 - imageManagerService.showExternal = function(doneCallback) { 36 + var dblClickTime = 300;
67 - $scope.$apply(() => { 37 + var currentTime = Date.now();
68 - show(doneCallback); 38 + var timeDiff = currentTime - previousClickTime;
69 - }); 39 +
70 - }; 40 + if (timeDiff < dblClickTime) {
71 - window.ImageManager = imageManagerService; 41 + // If double click
72 - 42 + callbackAndHide(image);
73 - $scope.hide = function() { 43 + } else {
74 - $scope.showing = false; 44 + // If single
75 - }; 45 + $scope.selectedImage = image;
46 + $scope.dependantPages = false;
47 + }
48 + previousClickTime = currentTime;
49 + };
50 +
51 + $scope.selectButtonClick = function () {
52 + callbackAndHide($scope.selectedImage);
53 + };
54 +
55 + function show(doneCallback) {
56 + callback = doneCallback;
57 + $scope.showing = true;
58 + // Get initial images if they have not yet been loaded in.
59 + if (!dataLoaded) {
60 + fetchData();
61 + dataLoaded = true;
62 + }
63 + }
76 64
77 - function fetchData() { 65 + imageManagerService.show = show;
78 - var url = '/images/' + $scope.imageType + '/all/' + page; 66 + imageManagerService.showExternal = function (doneCallback) {
79 - $http.get(url).then((response) => { 67 + $scope.$apply(() => {
80 - $scope.images = $scope.images.concat(response.data.images); 68 + show(doneCallback);
81 - $scope.hasMore = response.data.hasMore;
82 - page++;
83 - });
84 - }
85 -
86 - $scope.saveImageDetails = function(event) {
87 - event.preventDefault();
88 - var url = '/images/update/' + $scope.selectedImage.id;
89 - $http.put(url, this.selectedImage).then((response) => {
90 - $scope.imageUpdateSuccess = true;
91 - $timeout(() => {
92 - $scope.imageUpdateSuccess = false;
93 - }, 3000);
94 - }, (response) => {
95 - var errors = response.data;
96 - var message = '';
97 - Object.keys(errors).forEach((key) => {
98 - message += errors[key].join('\n');
99 }); 69 });
100 - $scope.imageUpdateFailure = message; 70 + };
101 - $timeout(() => { 71 + window.ImageManager = imageManagerService;
102 - $scope.imageUpdateFailure = false; 72 +
103 - }, 5000); 73 + $scope.hide = function () {
104 - }); 74 + $scope.showing = false;
105 - }; 75 + };
76 +
77 + function fetchData() {
78 + var url = '/images/' + $scope.imageType + '/all/' + page;
79 + $http.get(url).then((response) => {
80 + $scope.images = $scope.images.concat(response.data.images);
81 + $scope.hasMore = response.data.hasMore;
82 + page++;
83 + });
84 + }
106 85
107 - $scope.deleteImage = function(event) { 86 + $scope.saveImageDetails = function (event) {
108 - event.preventDefault(); 87 + event.preventDefault();
109 - var force = $scope.dependantPages !== false; 88 + var url = '/images/update/' + $scope.selectedImage.id;
110 - var url = '/images/' + $scope.selectedImage.id; 89 + $http.put(url, this.selectedImage).then((response) => {
111 - if (force) url += '?force=true'; 90 + $scope.imageUpdateSuccess = true;
112 - $http.delete(url).then((response) => { 91 + $timeout(() => {
113 - $scope.images.splice($scope.images.indexOf($scope.selectedImage), 1); 92 + $scope.imageUpdateSuccess = false;
114 - $scope.selectedImage = false; 93 + }, 3000);
115 - $scope.imageDeleteSuccess = true; 94 + }, (response) => {
116 - $timeout(() => { 95 + var errors = response.data;
117 - $scope.imageDeleteSuccess = false; 96 + var message = '';
118 - }, 3000); 97 + Object.keys(errors).forEach((key) => {
119 - }, (response) => { 98 + message += errors[key].join('\n');
120 - // Pages failure 99 + });
121 - if (response.status === 400) { 100 + $scope.imageUpdateFailure = message;
122 - $scope.dependantPages = response.data; 101 + $timeout(() => {
123 - } 102 + $scope.imageUpdateFailure = false;
124 - }); 103 + }, 5000);
125 - }; 104 + });
105 + };
106 +
107 + $scope.deleteImage = function (event) {
108 + event.preventDefault();
109 + var force = $scope.dependantPages !== false;
110 + var url = '/images/' + $scope.selectedImage.id;
111 + if (force) url += '?force=true';
112 + $http.delete(url).then((response) => {
113 + $scope.images.splice($scope.images.indexOf($scope.selectedImage), 1);
114 + $scope.selectedImage = false;
115 + $scope.imageDeleteSuccess = true;
116 + $timeout(() => {
117 + $scope.imageDeleteSuccess = false;
118 + }, 3000);
119 + }, (response) => {
120 + // Pages failure
121 + if (response.status === 400) {
122 + $scope.dependantPages = response.data;
123 + }
124 + });
125 + };
126 126
127 - }]); 127 + }]);
128 128
129 129
130 - ngApp.controller('BookShowController', ['$scope', '$http', '$attrs', function($scope, $http, $attrs) { 130 + ngApp.controller('BookShowController', ['$scope', '$http', '$attrs', function ($scope, $http, $attrs) {
131 $scope.searching = false; 131 $scope.searching = false;
132 $scope.searchTerm = ''; 132 $scope.searchTerm = '';
133 $scope.searchResults = ''; 133 $scope.searchResults = '';
...@@ -151,7 +151,7 @@ module.exports = function(ngApp) { ...@@ -151,7 +151,7 @@ module.exports = function(ngApp) {
151 } 151 }
152 }; 152 };
153 153
154 - $scope.clearSearch = function() { 154 + $scope.clearSearch = function () {
155 $scope.searching = false; 155 $scope.searching = false;
156 $scope.searchTerm = ''; 156 $scope.searchTerm = '';
157 }; 157 };
......
...@@ -5,25 +5,25 @@ var toggleSwitchTemplate = require('./components/toggle-switch.html'); ...@@ -5,25 +5,25 @@ var toggleSwitchTemplate = require('./components/toggle-switch.html');
5 var imagePickerTemplate = require('./components/image-picker.html'); 5 var imagePickerTemplate = require('./components/image-picker.html');
6 var dropZoneTemplate = require('./components/drop-zone.html'); 6 var dropZoneTemplate = require('./components/drop-zone.html');
7 7
8 -module.exports = function(ngApp) { 8 +module.exports = function (ngApp) {
9 9
10 /** 10 /**
11 * Toggle Switches 11 * Toggle Switches
12 * Has basic on/off functionality. 12 * Has basic on/off functionality.
13 * Use string values of 'true' & 'false' to dictate the current state. 13 * Use string values of 'true' & 'false' to dictate the current state.
14 */ 14 */
15 - ngApp.directive('toggleSwitch', function() { 15 + ngApp.directive('toggleSwitch', function () {
16 return { 16 return {
17 restrict: 'E', 17 restrict: 'E',
18 template: toggleSwitchTemplate, 18 template: toggleSwitchTemplate,
19 scope: true, 19 scope: true,
20 - link: function(scope, element, attrs) { 20 + link: function (scope, element, attrs) {
21 scope.name = attrs.name; 21 scope.name = attrs.name;
22 scope.value = attrs.value; 22 scope.value = attrs.value;
23 scope.isActive = scope.value == true && scope.value != 'false'; 23 scope.isActive = scope.value == true && scope.value != 'false';
24 scope.value = (scope.value == true && scope.value != 'false') ? 'true' : 'false'; 24 scope.value = (scope.value == true && scope.value != 'false') ? 'true' : 'false';
25 25
26 - scope.switch = function() { 26 + scope.switch = function () {
27 scope.isActive = !scope.isActive; 27 scope.isActive = !scope.isActive;
28 scope.value = scope.isActive ? 'true' : 'false'; 28 scope.value = scope.isActive ? 'true' : 'false';
29 } 29 }
...@@ -37,7 +37,7 @@ module.exports = function(ngApp) { ...@@ -37,7 +37,7 @@ module.exports = function(ngApp) {
37 * Image Picker 37 * Image Picker
38 * Is a simple front-end interface that connects to an ImageManager if present. 38 * Is a simple front-end interface that connects to an ImageManager if present.
39 */ 39 */
40 - ngApp.directive('imagePicker', ['$http', 'imageManagerService', function($http, imageManagerService) { 40 + ngApp.directive('imagePicker', ['$http', 'imageManagerService', function ($http, imageManagerService) {
41 return { 41 return {
42 restrict: 'E', 42 restrict: 'E',
43 template: imagePickerTemplate, 43 template: imagePickerTemplate,
...@@ -52,7 +52,7 @@ module.exports = function(ngApp) { ...@@ -52,7 +52,7 @@ module.exports = function(ngApp) {
52 defaultImage: '@', 52 defaultImage: '@',
53 imageClass: '@' 53 imageClass: '@'
54 }, 54 },
55 - link: function(scope, element, attrs) { 55 + link: function (scope, element, attrs) {
56 var usingIds = typeof scope.currentId !== 'undefined' || scope.currentId === 'false'; 56 var usingIds = typeof scope.currentId !== 'undefined' || scope.currentId === 'false';
57 scope.image = scope.currentImage; 57 scope.image = scope.currentImage;
58 scope.value = scope.currentImage || ''; 58 scope.value = scope.currentImage || '';
...@@ -62,22 +62,22 @@ module.exports = function(ngApp) { ...@@ -62,22 +62,22 @@ module.exports = function(ngApp) {
62 scope.value = usingIds ? imageModel.id : imageUrl; 62 scope.value = usingIds ? imageModel.id : imageUrl;
63 } 63 }
64 64
65 - scope.reset = function() { 65 + scope.reset = function () {
66 setImage({id: 0}, scope.defaultImage); 66 setImage({id: 0}, scope.defaultImage);
67 }; 67 };
68 68
69 - scope.remove = function() { 69 + scope.remove = function () {
70 scope.image = 'none'; 70 scope.image = 'none';
71 scope.value = 'none'; 71 scope.value = 'none';
72 }; 72 };
73 73
74 - scope.showImageManager = function() { 74 + scope.showImageManager = function () {
75 imageManagerService.show((image) => { 75 imageManagerService.show((image) => {
76 scope.updateImageFromModel(image); 76 scope.updateImageFromModel(image);
77 }); 77 });
78 }; 78 };
79 79
80 - scope.updateImageFromModel = function(model) { 80 + scope.updateImageFromModel = function (model) {
81 var isResized = scope.resizeWidth && scope.resizeHeight; 81 var isResized = scope.resizeWidth && scope.resizeHeight;
82 82
83 if (!isResized) { 83 if (!isResized) {
...@@ -102,7 +102,7 @@ module.exports = function(ngApp) { ...@@ -102,7 +102,7 @@ module.exports = function(ngApp) {
102 * DropZone 102 * DropZone
103 * Used for uploading images 103 * Used for uploading images
104 */ 104 */
105 - ngApp.directive('dropZone', [function() { 105 + ngApp.directive('dropZone', [function () {
106 return { 106 return {
107 restrict: 'E', 107 restrict: 'E',
108 template: dropZoneTemplate, 108 template: dropZoneTemplate,
...@@ -111,26 +111,32 @@ module.exports = function(ngApp) { ...@@ -111,26 +111,32 @@ module.exports = function(ngApp) {
111 eventSuccess: '=', 111 eventSuccess: '=',
112 eventError: '=' 112 eventError: '='
113 }, 113 },
114 - link: function(scope, element, attrs) { 114 + link: function (scope, element, attrs) {
115 var dropZone = new DropZone(element[0].querySelector('.dropzone-container'), { 115 var dropZone = new DropZone(element[0].querySelector('.dropzone-container'), {
116 url: scope.uploadUrl, 116 url: scope.uploadUrl,
117 - init: function() { 117 + init: function () {
118 var dz = this; 118 var dz = this;
119 - dz.on('sending', function(file, xhr, data) { 119 + dz.on('sending', function (file, xhr, data) {
120 var token = window.document.querySelector('meta[name=token]').getAttribute('content'); 120 var token = window.document.querySelector('meta[name=token]').getAttribute('content');
121 data.append('_token', token); 121 data.append('_token', token);
122 }); 122 });
123 if (typeof scope.eventSuccess !== 'undefined') dz.on('success', scope.eventSuccess); 123 if (typeof scope.eventSuccess !== 'undefined') dz.on('success', scope.eventSuccess);
124 - dz.on('success', function(file, data) { 124 + dz.on('success', function (file, data) {
125 $(file.previewElement).fadeOut(400, function () { 125 $(file.previewElement).fadeOut(400, function () {
126 dz.removeFile(file); 126 dz.removeFile(file);
127 }); 127 });
128 }); 128 });
129 if (typeof scope.eventError !== 'undefined') dz.on('error', scope.eventError); 129 if (typeof scope.eventError !== 'undefined') dz.on('error', scope.eventError);
130 dz.on('error', function (file, errorMessage, xhr) { 130 dz.on('error', function (file, errorMessage, xhr) {
131 - if (errorMessage.file) { 131 + console.log(errorMessage);
132 - $(file.previewElement).find('[data-dz-errormessage]').text(errorMessage.file[0]); 132 + console.log(xhr);
133 + function setMessage(message) {
134 + $(file.previewElement).find('[data-dz-errormessage]').text(message);
133 } 135 }
136 +
137 + if (xhr.status === 413) setMessage('The server does not allow uploads of this size. Please try a smaller file.');
138 + if (errorMessage.file) setMessage(errorMessage.file[0]);
139 +
134 }); 140 });
135 } 141 }
136 }); 142 });
...@@ -139,14 +145,14 @@ module.exports = function(ngApp) { ...@@ -139,14 +145,14 @@ module.exports = function(ngApp) {
139 }]); 145 }]);
140 146
141 147
142 - ngApp.directive('dropdown', [function() { 148 + ngApp.directive('dropdown', [function () {
143 return { 149 return {
144 restrict: 'A', 150 restrict: 'A',
145 - link: function(scope, element, attrs) { 151 + link: function (scope, element, attrs) {
146 var menu = element.find('ul'); 152 var menu = element.find('ul');
147 - element.find('[dropdown-toggle]').on('click', function() { 153 + element.find('[dropdown-toggle]').on('click', function () {
148 menu.show().addClass('anim menuIn'); 154 menu.show().addClass('anim menuIn');
149 - element.mouseleave(function() { 155 + element.mouseleave(function () {
150 menu.hide(); 156 menu.hide();
151 menu.removeClass('anim menuIn'); 157 menu.removeClass('anim menuIn');
152 }); 158 });
......
...@@ -18,8 +18,8 @@ var controllers = require('./controllers')(ngApp); ...@@ -18,8 +18,8 @@ var controllers = require('./controllers')(ngApp);
18 //Global jQuery Config & Extensions 18 //Global jQuery Config & Extensions
19 19
20 // Smooth scrolling 20 // Smooth scrolling
21 -jQuery.fn.smoothScrollTo = function() { 21 +jQuery.fn.smoothScrollTo = function () {
22 - if(this.length === 0) return; 22 + if (this.length === 0) return;
23 $('body').animate({ 23 $('body').animate({
24 scrollTop: this.offset().top - 60 // Adjust to change final scroll position top margin 24 scrollTop: this.offset().top - 60 // Adjust to change final scroll position top margin
25 }, 800); // Adjust to change animations speed (ms) 25 }, 800); // Adjust to change animations speed (ms)
...@@ -27,8 +27,8 @@ jQuery.fn.smoothScrollTo = function() { ...@@ -27,8 +27,8 @@ jQuery.fn.smoothScrollTo = function() {
27 }; 27 };
28 28
29 // Making contains text expression not worry about casing 29 // Making contains text expression not worry about casing
30 -$.expr[":"].contains = $.expr.createPseudo(function(arg) { 30 +$.expr[":"].contains = $.expr.createPseudo(function (arg) {
31 - return function( elem ) { 31 + return function (elem) {
32 return $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0; 32 return $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
33 }; 33 };
34 }); 34 });
...@@ -42,7 +42,7 @@ $(function () { ...@@ -42,7 +42,7 @@ $(function () {
42 }); 42 });
43 43
44 // Chapter page list toggles 44 // Chapter page list toggles
45 - $('.chapter-toggle').click(function(e) { 45 + $('.chapter-toggle').click(function (e) {
46 e.preventDefault(); 46 e.preventDefault();
47 $(this).toggleClass('open'); 47 $(this).toggleClass('open');
48 $(this).closest('.chapter').find('.inset-list').slideToggle(180); 48 $(this).closest('.chapter').find('.inset-list').slideToggle(180);
...@@ -56,7 +56,7 @@ function elemExists(selector) { ...@@ -56,7 +56,7 @@ function elemExists(selector) {
56 } 56 }
57 57
58 // TinyMCE editor 58 // TinyMCE editor
59 -if(elemExists('#html-editor')) { 59 +if (elemExists('#html-editor')) {
60 var tinyMceOptions = require('./pages/page-form'); 60 var tinyMceOptions = require('./pages/page-form');
61 tinymce.init(tinyMceOptions); 61 tinymce.init(tinyMceOptions);
62 } 62 }
...\ No newline at end of file ...\ No newline at end of file
......
1 -
2 module.exports = { 1 module.exports = {
3 selector: '#html-editor', 2 selector: '#html-editor',
4 content_css: [ 3 content_css: [
...@@ -27,13 +26,13 @@ module.exports = { ...@@ -27,13 +26,13 @@ module.exports = {
27 {title: "Code Block", icon: "code", format: "pre"}, 26 {title: "Code Block", icon: "code", format: "pre"},
28 {title: "Inline Code", icon: "code", inline: "code"} 27 {title: "Inline Code", icon: "code", inline: "code"}
29 ], 28 ],
30 - formats : { 29 + formats: {
31 - alignleft : {selector : 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img', classes : 'align-left'}, 30 + alignleft: {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img', classes: 'align-left'},
32 - aligncenter : {selector : 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img', classes : 'align-center'}, 31 + aligncenter: {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img', classes: 'align-center'},
33 - alignright : {selector : 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img', classes : 'align-right'}, 32 + alignright: {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img', classes: 'align-right'},
34 }, 33 },
35 - file_browser_callback: function(field_name, url, type, win) { 34 + file_browser_callback: function (field_name, url, type, win) {
36 - ImageManager.show(function(image) { 35 + ImageManager.show(function (image) {
37 win.document.getElementById(field_name).value = image.url; 36 win.document.getElementById(field_name).value = image.url;
38 if ("createEvent" in document) { 37 if ("createEvent" in document) {
39 var evt = document.createEvent("HTMLEvents"); 38 var evt = document.createEvent("HTMLEvents");
...@@ -44,63 +43,63 @@ module.exports = { ...@@ -44,63 +43,63 @@ module.exports = {
44 } 43 }
45 }); 44 });
46 }, 45 },
47 - paste_preprocess: function(plugin, args) { 46 + paste_preprocess: function (plugin, args) {
48 var content = args.content; 47 var content = args.content;
49 - if(content.indexOf('<img src="file://') !== -1) { 48 + if (content.indexOf('<img src="file://') !== -1) {
50 args.content = ''; 49 args.content = '';
51 } 50 }
52 }, 51 },
53 - setup: function(editor) { 52 + setup: function (editor) {
54 53
55 - ( function() { 54 + (function () {
56 var wrap; 55 var wrap;
57 56
58 - function hasTextContent( node ) { 57 + function hasTextContent(node) {
59 - return node && !! ( node.textContent || node.innerText ); 58 + return node && !!( node.textContent || node.innerText );
60 } 59 }
61 60
62 - editor.on( 'dragstart', function() { 61 + editor.on('dragstart', function () {
63 var node = editor.selection.getNode(); 62 var node = editor.selection.getNode();
64 63
65 - if ( node.nodeName === 'IMG' ) { 64 + if (node.nodeName === 'IMG') {
66 - wrap = editor.dom.getParent( node, '.mceTemp' ); 65 + wrap = editor.dom.getParent(node, '.mceTemp');
67 66
68 - if ( ! wrap && node.parentNode.nodeName === 'A' && ! hasTextContent( node.parentNode ) ) { 67 + if (!wrap && node.parentNode.nodeName === 'A' && !hasTextContent(node.parentNode)) {
69 wrap = node.parentNode; 68 wrap = node.parentNode;
70 } 69 }
71 } 70 }
72 - } ); 71 + });
73 72
74 - editor.on( 'drop', function( event ) { 73 + editor.on('drop', function (event) {
75 var dom = editor.dom, 74 var dom = editor.dom,
76 - rng = tinymce.dom.RangeUtils.getCaretRangeFromPoint( event.clientX, event.clientY, editor.getDoc() ); 75 + rng = tinymce.dom.RangeUtils.getCaretRangeFromPoint(event.clientX, event.clientY, editor.getDoc());
77 76
78 // Don't allow anything to be dropped in a captioned image. 77 // Don't allow anything to be dropped in a captioned image.
79 - if ( dom.getParent( rng.startContainer, '.mceTemp' ) ) { 78 + if (dom.getParent(rng.startContainer, '.mceTemp')) {
80 event.preventDefault(); 79 event.preventDefault();
81 - } else if ( wrap ) { 80 + } else if (wrap) {
82 event.preventDefault(); 81 event.preventDefault();
83 82
84 - editor.undoManager.transact( function() { 83 + editor.undoManager.transact(function () {
85 - editor.selection.setRng( rng ); 84 + editor.selection.setRng(rng);
86 - editor.selection.setNode( wrap ); 85 + editor.selection.setNode(wrap);
87 - dom.remove( wrap ); 86 + dom.remove(wrap);
88 - } ); 87 + });
89 } 88 }
90 89
91 wrap = null; 90 wrap = null;
92 - } ); 91 + });
93 - } )(); 92 + })();
94 93
95 // Image picker button 94 // Image picker button
96 editor.addButton('image-insert', { 95 editor.addButton('image-insert', {
97 title: 'My title', 96 title: 'My title',
98 icon: 'image', 97 icon: 'image',
99 tooltip: 'Insert an image', 98 tooltip: 'Insert an image',
100 - onclick: function() { 99 + onclick: function () {
101 - window.ImageManager.showExternal(function(image) { 100 + window.ImageManager.showExternal(function (image) {
102 - var html = '<a href="'+image.url+'" target="_blank">'; 101 + var html = '<a href="' + image.url + '" target="_blank">';
103 - html += '<img src="'+image.thumbs.display+'" alt="'+image.name+'">'; 102 + html += '<img src="' + image.thumbs.display + '" alt="' + image.name + '">';
104 html += '</a>'; 103 html += '</a>';
105 editor.execCommand('mceInsertContent', false, html); 104 editor.execCommand('mceInsertContent', false, html);
106 }); 105 });
...@@ -108,10 +107,10 @@ module.exports = { ...@@ -108,10 +107,10 @@ module.exports = {
108 }); 107 });
109 108
110 // Paste image-uploads 109 // Paste image-uploads
111 - editor.on('paste', function(e) { 110 + editor.on('paste', function (e) {
112 - if(e.clipboardData) { 111 + if (e.clipboardData) {
113 var items = e.clipboardData.items; 112 var items = e.clipboardData.items;
114 - if (items){ 113 + if (items) {
115 for (var i = 0; i < items.length; i++) { 114 for (var i = 0; i < items.length; i++) {
116 if (items[i].type.indexOf("image") !== -1) { 115 if (items[i].type.indexOf("image") !== -1) {
117 116
...@@ -128,14 +127,14 @@ module.exports = { ...@@ -128,14 +127,14 @@ module.exports = {
128 } 127 }
129 128
130 var id = "image-" + Math.random().toString(16).slice(2); 129 var id = "image-" + Math.random().toString(16).slice(2);
131 - editor.execCommand('mceInsertContent', false, '<img src="/loading.gif" id="'+id+'">'); 130 + editor.execCommand('mceInsertContent', false, '<img src="/loading.gif" id="' + id + '">');
132 131
133 var remoteFilename = "image-" + Date.now() + "." + ext; 132 var remoteFilename = "image-" + Date.now() + "." + ext;
134 formData.append('file', file, remoteFilename); 133 formData.append('file', file, remoteFilename);
135 formData.append('_token', document.querySelector('meta[name="token"]').getAttribute('content')); 134 formData.append('_token', document.querySelector('meta[name="token"]').getAttribute('content'));
136 135
137 xhr.open('POST', '/upload/image'); 136 xhr.open('POST', '/upload/image');
138 - xhr.onload = function() { 137 + xhr.onload = function () {
139 if (xhr.status === 200 || xhr.status === 201) { 138 if (xhr.status === 200 || xhr.status === 201) {
140 var result = JSON.parse(xhr.responseText); 139 var result = JSON.parse(xhr.responseText);
141 editor.dom.setAttrib(id, 'src', result.url); 140 editor.dom.setAttrib(id, 'src', result.url);
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
32 font-weight: 300; 32 font-weight: 300;
33 } 33 }
34 } 34 }
35 +
35 #image-manager .dropzone-container { 36 #image-manager .dropzone-container {
36 position: relative; 37 position: relative;
37 border: 3px dashed #DDD; 38 border: 3px dashed #DDD;
...@@ -52,7 +53,7 @@ ...@@ -52,7 +53,7 @@
52 width: (100%/6); 53 width: (100%/6);
53 height: auto; 54 height: auto;
54 border: 1px solid #FFF; 55 border: 1px solid #FFF;
55 - transition: all cubic-bezier(.4,0,1,1) 160ms; 56 + transition: all cubic-bezier(.4, 0, 1, 1) 160ms;
56 &.selected { 57 &.selected {
57 transform: scale3d(0.92, 0.92, 0.92); 58 transform: scale3d(0.92, 0.92, 0.92);
58 } 59 }
...@@ -77,6 +78,7 @@ ...@@ -77,6 +78,7 @@
77 padding: 0 $-l; 78 padding: 0 $-l;
78 border-left: 1px solid #DDD; 79 border-left: 1px solid #DDD;
79 } 80 }
81 +
80 .image-manager-close { 82 .image-manager-close {
81 position: absolute; 83 position: absolute;
82 top: 0; 84 top: 0;
...@@ -84,6 +86,7 @@ ...@@ -84,6 +86,7 @@
84 margin: 0; 86 margin: 0;
85 border-radius: 0; 87 border-radius: 0;
86 } 88 }
89 +
87 .image-manager-list { 90 .image-manager-list {
88 overflow-y: scroll; 91 overflow-y: scroll;
89 flex: 1; 92 flex: 1;
...@@ -97,9 +100,6 @@ ...@@ -97,9 +100,6 @@
97 flex: 1; 100 flex: 1;
98 } 101 }
99 102
100 -
101 -
102 -
103 // Dropzone 103 // Dropzone
104 /* 104 /*
105 * The MIT License 105 * The MIT License
...@@ -114,69 +114,104 @@ ...@@ -114,69 +114,104 @@
114 padding: $-xl $-m; 114 padding: $-xl $-m;
115 transition: all ease-in-out 120ms; 115 transition: all ease-in-out 120ms;
116 } 116 }
117 +
117 .dz-drag-hover .dz-message { 118 .dz-drag-hover .dz-message {
118 background-color: rgb(16, 126, 210); 119 background-color: rgb(16, 126, 210);
119 color: #EEE; 120 color: #EEE;
120 } 121 }
122 +
121 @keyframes passing-through { 123 @keyframes passing-through {
122 0% { 124 0% {
123 opacity: 0; 125 opacity: 0;
124 - transform: translateY(40px); } 126 + transform: translateY(40px);
127 + }
125 30%, 70% { 128 30%, 70% {
126 opacity: 1; 129 opacity: 1;
127 - transform: translateY(0px); } 130 + transform: translateY(0px);
131 + }
128 100% { 132 100% {
129 opacity: 0; 133 opacity: 0;
130 - transform: translateY(-40px); } } 134 + transform: translateY(-40px);
135 + }
136 +}
131 137
132 @keyframes slide-in { 138 @keyframes slide-in {
133 0% { 139 0% {
134 opacity: 0; 140 opacity: 0;
135 - transform: translateY(40px); } 141 + transform: translateY(40px);
142 + }
136 30% { 143 30% {
137 opacity: 1; 144 opacity: 1;
138 - transform: translateY(0px); } } 145 + transform: translateY(0px);
146 + }
147 +}
148 +
139 @keyframes pulse { 149 @keyframes pulse {
140 0% { 150 0% {
141 - transform: scale(1); } 151 + transform: scale(1);
152 + }
142 10% { 153 10% {
143 - transform: scale(1.1); } 154 + transform: scale(1.1);
155 + }
144 20% { 156 20% {
145 - transform: scale(1); } } 157 + transform: scale(1);
146 -.dropzone, .dropzone * { 158 + }
147 - box-sizing: border-box; } 159 +}
148 160
161 +.dropzone, .dropzone * {
162 + box-sizing: border-box;
163 +}
149 164
150 .dz-preview { 165 .dz-preview {
151 position: relative; 166 position: relative;
152 display: inline-block; 167 display: inline-block;
153 vertical-align: top; 168 vertical-align: top;
154 margin: 12px; 169 margin: 12px;
155 - min-height: 80px; } 170 + min-height: 80px;
171 +}
172 +
156 .dz-preview:hover { 173 .dz-preview:hover {
157 - z-index: 1000; } 174 + z-index: 1000;
175 +}
176 +
158 .dz-preview:hover .dz-details { 177 .dz-preview:hover .dz-details {
159 - opacity: 1; } 178 + opacity: 1;
179 +}
180 +
160 .dz-preview.dz-file-preview .dz-image { 181 .dz-preview.dz-file-preview .dz-image {
161 border-radius: 4px; 182 border-radius: 4px;
162 background: #999; 183 background: #999;
163 - background: linear-gradient(to bottom, #eee, #ddd); } 184 + background: linear-gradient(to bottom, #eee, #ddd);
185 +}
186 +
164 .dz-preview.dz-file-preview .dz-details { 187 .dz-preview.dz-file-preview .dz-details {
165 - opacity: 1; } 188 + opacity: 1;
189 +}
190 +
166 .dz-preview.dz-image-preview { 191 .dz-preview.dz-image-preview {
167 - background: white; } 192 + background: white;
193 +}
194 +
168 .dz-preview.dz-image-preview .dz-details { 195 .dz-preview.dz-image-preview .dz-details {
169 - transition: opacity 0.2s linear; } 196 + transition: opacity 0.2s linear;
197 +}
198 +
170 .dz-preview .dz-remove { 199 .dz-preview .dz-remove {
171 font-size: 14px; 200 font-size: 14px;
172 text-align: center; 201 text-align: center;
173 display: block; 202 display: block;
174 cursor: pointer; 203 cursor: pointer;
175 - border: none; } 204 + border: none;
205 +}
206 +
176 .dz-preview .dz-remove:hover { 207 .dz-preview .dz-remove:hover {
177 - text-decoration: underline; } 208 + text-decoration: underline;
209 +}
210 +
178 .dz-preview:hover .dz-details { 211 .dz-preview:hover .dz-details {
179 - opacity: 1; } 212 + opacity: 1;
213 +}
214 +
180 .dz-preview .dz-details { 215 .dz-preview .dz-details {
181 z-index: 20; 216 z-index: 20;
182 position: absolute; 217 position: absolute;
...@@ -189,26 +224,42 @@ ...@@ -189,26 +224,42 @@
189 padding: 6px 3px; 224 padding: 6px 3px;
190 text-align: center; 225 text-align: center;
191 color: rgba(0, 0, 0, 0.9); 226 color: rgba(0, 0, 0, 0.9);
192 - line-height: 150%; } 227 + line-height: 150%;
228 +}
229 +
193 .dz-preview .dz-details .dz-size { 230 .dz-preview .dz-details .dz-size {
194 margin-bottom: 0.5em; 231 margin-bottom: 0.5em;
195 - font-size: 12px; } 232 + font-size: 12px;
233 +}
234 +
196 .dz-preview .dz-details .dz-filename { 235 .dz-preview .dz-details .dz-filename {
197 - white-space: nowrap; } 236 + white-space: nowrap;
237 +}
238 +
198 .dz-preview .dz-details .dz-filename:hover span { 239 .dz-preview .dz-details .dz-filename:hover span {
199 border: 1px solid rgba(200, 200, 200, 0.8); 240 border: 1px solid rgba(200, 200, 200, 0.8);
200 - background-color: rgba(255, 255, 255, 0.8); } 241 + background-color: rgba(255, 255, 255, 0.8);
242 +}
243 +
201 .dz-preview .dz-details .dz-filename:not(:hover) { 244 .dz-preview .dz-details .dz-filename:not(:hover) {
202 overflow: hidden; 245 overflow: hidden;
203 - text-overflow: ellipsis; } 246 + text-overflow: ellipsis;
247 +}
248 +
204 .dz-preview .dz-details .dz-filename:not(:hover) span { 249 .dz-preview .dz-details .dz-filename:not(:hover) span {
205 - border: 1px solid transparent; } 250 + border: 1px solid transparent;
251 +}
252 +
206 .dz-preview .dz-details .dz-filename span, .dz-preview .dz-details .dz-size span { 253 .dz-preview .dz-details .dz-filename span, .dz-preview .dz-details .dz-size span {
207 background-color: rgba(255, 255, 255, 0.4); 254 background-color: rgba(255, 255, 255, 0.4);
208 padding: 0 0.4em; 255 padding: 0 0.4em;
209 - border-radius: 3px; } 256 + border-radius: 3px;
257 +}
258 +
210 .dz-preview:hover .dz-image img { 259 .dz-preview:hover .dz-image img {
211 - filter: blur(8px); } 260 + filter: blur(8px);
261 +}
262 +
212 .dz-preview .dz-image { 263 .dz-preview .dz-image {
213 border-radius: 4px; 264 border-radius: 4px;
214 overflow: hidden; 265 overflow: hidden;
...@@ -216,14 +267,22 @@ ...@@ -216,14 +267,22 @@
216 height: 80px; 267 height: 80px;
217 position: relative; 268 position: relative;
218 display: block; 269 display: block;
219 - z-index: 10; } 270 + z-index: 10;
271 +}
272 +
220 .dz-preview .dz-image img { 273 .dz-preview .dz-image img {
221 - display: block; } 274 + display: block;
275 +}
276 +
222 .dz-preview.dz-success .dz-success-mark { 277 .dz-preview.dz-success .dz-success-mark {
223 - animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1); } 278 + animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);
279 +}
280 +
224 .dz-preview.dz-error .dz-error-mark { 281 .dz-preview.dz-error .dz-error-mark {
225 opacity: 1; 282 opacity: 1;
226 - animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1); } 283 + animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);
284 +}
285 +
227 .dz-preview .dz-success-mark, .dz-preview .dz-error-mark { 286 .dz-preview .dz-success-mark, .dz-preview .dz-error-mark {
228 pointer-events: none; 287 pointer-events: none;
229 opacity: 0; 288 opacity: 0;
...@@ -233,19 +292,29 @@ ...@@ -233,19 +292,29 @@
233 top: 50%; 292 top: 50%;
234 left: 50%; 293 left: 50%;
235 margin-left: -27px; 294 margin-left: -27px;
236 - margin-top: -27px; } 295 + margin-top: -27px;
296 +}
297 +
237 .dz-preview .dz-success-mark svg, .dz-preview .dz-error-mark svg { 298 .dz-preview .dz-success-mark svg, .dz-preview .dz-error-mark svg {
238 display: block; 299 display: block;
239 width: 54px; 300 width: 54px;
240 - height: 54px; } 301 + height: 54px;
302 +}
303 +
241 .dz-preview.dz-processing .dz-progress { 304 .dz-preview.dz-processing .dz-progress {
242 opacity: 1; 305 opacity: 1;
243 - transition: all 0.2s linear; } 306 + transition: all 0.2s linear;
307 +}
308 +
244 .dz-preview.dz-complete .dz-progress { 309 .dz-preview.dz-complete .dz-progress {
245 opacity: 0; 310 opacity: 0;
246 - transition: opacity 0.4s ease-in; } 311 + transition: opacity 0.4s ease-in;
312 +}
313 +
247 .dz-preview:not(.dz-processing) .dz-progress { 314 .dz-preview:not(.dz-processing) .dz-progress {
248 - animation: pulse 6s ease infinite; } 315 + animation: pulse 6s ease infinite;
316 +}
317 +
249 .dz-preview .dz-progress { 318 .dz-preview .dz-progress {
250 opacity: 1; 319 opacity: 1;
251 z-index: 1000; 320 z-index: 1000;
...@@ -260,7 +329,9 @@ ...@@ -260,7 +329,9 @@
260 background: rgba(255, 255, 255, 0.9); 329 background: rgba(255, 255, 255, 0.9);
261 transform: scale(1); 330 transform: scale(1);
262 border-radius: 8px; 331 border-radius: 8px;
263 - overflow: hidden; } 332 + overflow: hidden;
333 +}
334 +
264 .dz-preview .dz-progress .dz-upload { 335 .dz-preview .dz-progress .dz-upload {
265 background: #333; 336 background: #333;
266 background: linear-gradient(to bottom, #666, #444); 337 background: linear-gradient(to bottom, #666, #444);
...@@ -269,12 +340,18 @@ ...@@ -269,12 +340,18 @@
269 left: 0; 340 left: 0;
270 bottom: 0; 341 bottom: 0;
271 width: 0; 342 width: 0;
272 - transition: width 300ms ease-in-out; } 343 + transition: width 300ms ease-in-out;
344 +}
345 +
273 .dz-preview.dz-error .dz-error-message { 346 .dz-preview.dz-error .dz-error-message {
274 - display: block; } 347 + display: block;
348 +}
349 +
275 .dz-preview.dz-error:hover .dz-error-message { 350 .dz-preview.dz-error:hover .dz-error-message {
276 opacity: 1; 351 opacity: 1;
277 - pointer-events: auto; } 352 + pointer-events: auto;
353 +}
354 +
278 .dz-preview .dz-error-message { 355 .dz-preview .dz-error-message {
279 pointer-events: none; 356 pointer-events: none;
280 z-index: 1000; 357 z-index: 1000;
...@@ -283,15 +360,17 @@ ...@@ -283,15 +360,17 @@
283 display: none; 360 display: none;
284 opacity: 0; 361 opacity: 0;
285 transition: opacity 0.3s ease; 362 transition: opacity 0.3s ease;
286 - border-radius: 8px; 363 + border-radius: 4px;
287 - font-size: 13px; 364 + font-size: 11.5px;
288 - top: 130px; 365 + line-height: 1.2;
289 - left: -10px; 366 + top: 88px;
290 - width: 140px; 367 + left: -26px;
291 - background: #be2626; 368 + width: 148px;
292 - background: linear-gradient(to bottom, #be2626, #a92222); 369 + background: $negative;
293 - padding: 0.5em 1.2em; 370 + padding: $-xs;
294 - color: white; } 371 + color: white;
372 +}
373 +
295 .dz-preview .dz-error-message:after { 374 .dz-preview .dz-error-message:after {
296 content: ''; 375 content: '';
297 position: absolute; 376 position: absolute;
...@@ -301,4 +380,5 @@ ...@@ -301,4 +380,5 @@
301 height: 0; 380 height: 0;
302 border-left: 6px solid transparent; 381 border-left: 6px solid transparent;
303 border-right: 6px solid transparent; 382 border-right: 6px solid transparent;
304 - border-bottom: 6px solid #be2626; } 383 + border-bottom: 6px solid $negative;
384 +}
......