diff options
author | Kelly Rauchenberger <fefferburbia@gmail.com> | 2017-07-02 13:03:43 -0400 |
---|---|---|
committer | Kelly Rauchenberger <fefferburbia@gmail.com> | 2017-07-02 13:03:43 -0400 |
commit | e47e83cf6bded3d1924b4d500193e7876833ef83 (patch) | |
tree | 058f011637e67455dcd8451fbfa784b5883c6f69 /app/assets/javascripts/ckeditor/plugins/image2/dialogs | |
parent | 528ccde8915cd1ed7a39e137dd4d98869797956a (diff) | |
download | thoughts-e47e83cf6bded3d1924b4d500193e7876833ef83.tar.gz thoughts-e47e83cf6bded3d1924b4d500193e7876833ef83.tar.bz2 thoughts-e47e83cf6bded3d1924b4d500193e7876833ef83.zip |
Created admin panel
Currently allows you to create and edit blogs, including associated records. Uses a WYSIWYG editor that allows uploading images. Also included jQuery :(
Diffstat (limited to 'app/assets/javascripts/ckeditor/plugins/image2/dialogs')
-rw-r--r-- | app/assets/javascripts/ckeditor/plugins/image2/dialogs/image2.js | 553 |
1 files changed, 553 insertions, 0 deletions
diff --git a/app/assets/javascripts/ckeditor/plugins/image2/dialogs/image2.js b/app/assets/javascripts/ckeditor/plugins/image2/dialogs/image2.js new file mode 100644 index 0000000..cb393a3 --- /dev/null +++ b/app/assets/javascripts/ckeditor/plugins/image2/dialogs/image2.js | |||
@@ -0,0 +1,553 @@ | |||
1 | /** | ||
2 | * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved. | ||
3 | * For licensing, see LICENSE.md or http://ckeditor.com/license | ||
4 | */ | ||
5 | |||
6 | /** | ||
7 | * @fileOverview Image plugin based on Widgets API | ||
8 | */ | ||
9 | |||
10 | 'use strict'; | ||
11 | |||
12 | CKEDITOR.dialog.add( 'image2', function( editor ) { | ||
13 | |||
14 | // RegExp: 123, 123px, empty string "" | ||
15 | var regexGetSizeOrEmpty = /(^\s*(\d+)(px)?\s*$)|^$/i, | ||
16 | |||
17 | lockButtonId = CKEDITOR.tools.getNextId(), | ||
18 | resetButtonId = CKEDITOR.tools.getNextId(), | ||
19 | |||
20 | lang = editor.lang.image2, | ||
21 | commonLang = editor.lang.common, | ||
22 | |||
23 | lockResetStyle = 'margin-top:18px;width:40px;height:20px;', | ||
24 | lockResetHtml = new CKEDITOR.template( | ||
25 | '<div>' + | ||
26 | '<a href="javascript:void(0)" tabindex="-1" title="' + lang.lockRatio + '" class="cke_btn_locked" id="{lockButtonId}" role="checkbox">' + | ||
27 | '<span class="cke_icon"></span>' + | ||
28 | '<span class="cke_label">' + lang.lockRatio + '</span>' + | ||
29 | '</a>' + | ||
30 | |||
31 | '<a href="javascript:void(0)" tabindex="-1" title="' + lang.resetSize + '" class="cke_btn_reset" id="{resetButtonId}" role="button">' + | ||
32 | '<span class="cke_label">' + lang.resetSize + '</span>' + | ||
33 | '</a>' + | ||
34 | '</div>' ).output( { | ||
35 | lockButtonId: lockButtonId, | ||
36 | resetButtonId: resetButtonId | ||
37 | } ), | ||
38 | |||
39 | helpers = CKEDITOR.plugins.image2, | ||
40 | |||
41 | // Editor instance configuration. | ||
42 | config = editor.config, | ||
43 | |||
44 | hasFileBrowser = !!( config.filebrowserImageBrowseUrl || config.filebrowserBrowseUrl ), | ||
45 | |||
46 | // Content restrictions defined by the widget which | ||
47 | // impact on dialog structure and presence of fields. | ||
48 | features = editor.widgets.registered.image.features, | ||
49 | |||
50 | // Functions inherited from image2 plugin. | ||
51 | getNatural = helpers.getNatural, | ||
52 | |||
53 | // Global variables referring to the dialog's context. | ||
54 | doc, widget, image, | ||
55 | |||
56 | // Global variable referring to this dialog's image pre-loader. | ||
57 | preLoader, | ||
58 | |||
59 | // Global variables holding the original size of the image. | ||
60 | domWidth, domHeight, | ||
61 | |||
62 | // Global variables related to image pre-loading. | ||
63 | preLoadedWidth, preLoadedHeight, srcChanged, | ||
64 | |||
65 | // Global variables related to size locking. | ||
66 | lockRatio, userDefinedLock, | ||
67 | |||
68 | // Global variables referring to dialog fields and elements. | ||
69 | lockButton, resetButton, widthField, heightField, | ||
70 | |||
71 | natural; | ||
72 | |||
73 | // Validates dimension. Allowed values are: | ||
74 | // "123px", "123", "" (empty string) | ||
75 | function validateDimension() { | ||
76 | var match = this.getValue().match( regexGetSizeOrEmpty ), | ||
77 | isValid = !!( match && parseInt( match[ 1 ], 10 ) !== 0 ); | ||
78 | |||
79 | if ( !isValid ) | ||
80 | alert( commonLang[ 'invalid' + CKEDITOR.tools.capitalize( this.id ) ] ); // jshint ignore:line | ||
81 | |||
82 | return isValid; | ||
83 | } | ||
84 | |||
85 | // Creates a function that pre-loads images. The callback function passes | ||
86 | // [image, width, height] or null if loading failed. | ||
87 | // | ||
88 | // @returns {Function} | ||
89 | function createPreLoader() { | ||
90 | var image = doc.createElement( 'img' ), | ||
91 | listeners = []; | ||
92 | |||
93 | function addListener( event, callback ) { | ||
94 | listeners.push( image.once( event, function( evt ) { | ||
95 | removeListeners(); | ||
96 | callback( evt ); | ||
97 | } ) ); | ||
98 | } | ||
99 | |||
100 | function removeListeners() { | ||
101 | var l; | ||
102 | |||
103 | while ( ( l = listeners.pop() ) ) | ||
104 | l.removeListener(); | ||
105 | } | ||
106 | |||
107 | // @param {String} src. | ||
108 | // @param {Function} callback. | ||
109 | return function( src, callback, scope ) { | ||
110 | addListener( 'load', function() { | ||
111 | // Don't use image.$.(width|height) since it's buggy in IE9-10 (http://dev.ckeditor.com/ticket/11159) | ||
112 | var dimensions = getNatural( image ); | ||
113 | |||
114 | callback.call( scope, image, dimensions.width, dimensions.height ); | ||
115 | } ); | ||
116 | |||
117 | addListener( 'error', function() { | ||
118 | callback( null ); | ||
119 | } ); | ||
120 | |||
121 | addListener( 'abort', function() { | ||
122 | callback( null ); | ||
123 | } ); | ||
124 | |||
125 | image.setAttribute( 'src', | ||
126 | ( config.baseHref || '' ) + src + '?' + Math.random().toString( 16 ).substring( 2 ) ); | ||
127 | }; | ||
128 | } | ||
129 | |||
130 | // This function updates width and height fields once the | ||
131 | // "src" field is altered. Along with dimensions, also the | ||
132 | // dimensions lock is adjusted. | ||
133 | function onChangeSrc() { | ||
134 | var value = this.getValue(); | ||
135 | |||
136 | toggleDimensions( false ); | ||
137 | |||
138 | // Remember that src is different than default. | ||
139 | if ( value !== widget.data.src ) { | ||
140 | // Update dimensions of the image once it's preloaded. | ||
141 | preLoader( value, function( image, width, height ) { | ||
142 | // Re-enable width and height fields. | ||
143 | toggleDimensions( true ); | ||
144 | |||
145 | // There was problem loading the image. Unlock ratio. | ||
146 | if ( !image ) | ||
147 | return toggleLockRatio( false ); | ||
148 | |||
149 | // Fill width field with the width of the new image. | ||
150 | widthField.setValue( editor.config.image2_prefillDimensions === false ? 0 : width ); | ||
151 | |||
152 | // Fill height field with the height of the new image. | ||
153 | heightField.setValue( editor.config.image2_prefillDimensions === false ? 0 : height ); | ||
154 | |||
155 | // Cache the new width. | ||
156 | preLoadedWidth = width; | ||
157 | |||
158 | // Cache the new height. | ||
159 | preLoadedHeight = height; | ||
160 | |||
161 | // Check for new lock value if image exist. | ||
162 | toggleLockRatio( helpers.checkHasNaturalRatio( image ) ); | ||
163 | } ); | ||
164 | |||
165 | srcChanged = true; | ||
166 | } | ||
167 | |||
168 | // Value is the same as in widget data but is was | ||
169 | // modified back in time. Roll back dimensions when restoring | ||
170 | // default src. | ||
171 | else if ( srcChanged ) { | ||
172 | // Re-enable width and height fields. | ||
173 | toggleDimensions( true ); | ||
174 | |||
175 | // Restore width field with cached width. | ||
176 | widthField.setValue( domWidth ); | ||
177 | |||
178 | // Restore height field with cached height. | ||
179 | heightField.setValue( domHeight ); | ||
180 | |||
181 | // Src equals default one back again. | ||
182 | srcChanged = false; | ||
183 | } | ||
184 | |||
185 | // Value is the same as in widget data and it hadn't | ||
186 | // been modified. | ||
187 | else { | ||
188 | // Re-enable width and height fields. | ||
189 | toggleDimensions( true ); | ||
190 | } | ||
191 | } | ||
192 | |||
193 | function onChangeDimension() { | ||
194 | // If ratio is un-locked, then we don't care what's next. | ||
195 | if ( !lockRatio ) | ||
196 | return; | ||
197 | |||
198 | var value = this.getValue(); | ||
199 | |||
200 | // No reason to auto-scale or unlock if the field is empty. | ||
201 | if ( !value ) | ||
202 | return; | ||
203 | |||
204 | // If the value of the field is invalid (e.g. with %), unlock ratio. | ||
205 | if ( !value.match( regexGetSizeOrEmpty ) ) | ||
206 | toggleLockRatio( false ); | ||
207 | |||
208 | // No automatic re-scale when dimension is '0'. | ||
209 | if ( value === '0' ) | ||
210 | return; | ||
211 | |||
212 | var isWidth = this.id == 'width', | ||
213 | // If dialog opened for the new image, domWidth and domHeight | ||
214 | // will be empty. Use dimensions from pre-loader in such case instead. | ||
215 | width = domWidth || preLoadedWidth, | ||
216 | height = domHeight || preLoadedHeight; | ||
217 | |||
218 | // If changing width, then auto-scale height. | ||
219 | if ( isWidth ) | ||
220 | value = Math.round( height * ( value / width ) ); | ||
221 | |||
222 | // If changing height, then auto-scale width. | ||
223 | else | ||
224 | value = Math.round( width * ( value / height ) ); | ||
225 | |||
226 | // If the value is a number, apply it to the other field. | ||
227 | if ( !isNaN( value ) ) | ||
228 | ( isWidth ? heightField : widthField ).setValue( value ); | ||
229 | } | ||
230 | |||
231 | // Set-up function for lock and reset buttons: | ||
232 | // * Adds lock and reset buttons to focusables. Check if button exist first | ||
233 | // because it may be disabled e.g. due to ACF restrictions. | ||
234 | // * Register mouseover and mouseout event listeners for UI manipulations. | ||
235 | // * Register click event listeners for buttons. | ||
236 | function onLoadLockReset() { | ||
237 | var dialog = this.getDialog(); | ||
238 | |||
239 | function setupMouseClasses( el ) { | ||
240 | el.on( 'mouseover', function() { | ||
241 | this.addClass( 'cke_btn_over' ); | ||
242 | }, el ); | ||
243 | |||
244 | el.on( 'mouseout', function() { | ||
245 | this.removeClass( 'cke_btn_over' ); | ||
246 | }, el ); | ||
247 | } | ||
248 | |||
249 | // Create references to lock and reset buttons for this dialog instance. | ||
250 | lockButton = doc.getById( lockButtonId ); | ||
251 | resetButton = doc.getById( resetButtonId ); | ||
252 | |||
253 | // Activate (Un)LockRatio button | ||
254 | if ( lockButton ) { | ||
255 | // Consider that there's an additional focusable field | ||
256 | // in the dialog when the "browse" button is visible. | ||
257 | dialog.addFocusable( lockButton, 4 + hasFileBrowser ); | ||
258 | |||
259 | lockButton.on( 'click', function( evt ) { | ||
260 | toggleLockRatio(); | ||
261 | evt.data && evt.data.preventDefault(); | ||
262 | }, this.getDialog() ); | ||
263 | |||
264 | setupMouseClasses( lockButton ); | ||
265 | } | ||
266 | |||
267 | // Activate the reset size button. | ||
268 | if ( resetButton ) { | ||
269 | // Consider that there's an additional focusable field | ||
270 | // in the dialog when the "browse" button is visible. | ||
271 | dialog.addFocusable( resetButton, 5 + hasFileBrowser ); | ||
272 | |||
273 | // Fills width and height fields with the original dimensions of the | ||
274 | // image (stored in widget#data since widget#init). | ||
275 | resetButton.on( 'click', function( evt ) { | ||
276 | // If there's a new image loaded, reset button should revert | ||
277 | // cached dimensions of pre-loaded DOM element. | ||
278 | if ( srcChanged ) { | ||
279 | widthField.setValue( preLoadedWidth ); | ||
280 | heightField.setValue( preLoadedHeight ); | ||
281 | } | ||
282 | |||
283 | // If the old image remains, reset button should revert | ||
284 | // dimensions as loaded when the dialog was first shown. | ||
285 | else { | ||
286 | widthField.setValue( domWidth ); | ||
287 | heightField.setValue( domHeight ); | ||
288 | } | ||
289 | |||
290 | evt.data && evt.data.preventDefault(); | ||
291 | }, this ); | ||
292 | |||
293 | setupMouseClasses( resetButton ); | ||
294 | } | ||
295 | } | ||
296 | |||
297 | function toggleLockRatio( enable ) { | ||
298 | // No locking if there's no radio (i.e. due to ACF). | ||
299 | if ( !lockButton ) | ||
300 | return; | ||
301 | |||
302 | if ( typeof enable == 'boolean' ) { | ||
303 | // If user explicitly wants to decide whether | ||
304 | // to lock or not, don't do anything. | ||
305 | if ( userDefinedLock ) | ||
306 | return; | ||
307 | |||
308 | lockRatio = enable; | ||
309 | } | ||
310 | |||
311 | // Undefined. User changed lock value. | ||
312 | else { | ||
313 | var width = widthField.getValue(), | ||
314 | height; | ||
315 | |||
316 | userDefinedLock = true; | ||
317 | lockRatio = !lockRatio; | ||
318 | |||
319 | // Automatically adjust height to width to match | ||
320 | // the original ratio (based on dom- dimensions). | ||
321 | if ( lockRatio && width ) { | ||
322 | height = domHeight / domWidth * width; | ||
323 | |||
324 | if ( !isNaN( height ) ) | ||
325 | heightField.setValue( Math.round( height ) ); | ||
326 | } | ||
327 | } | ||
328 | |||
329 | lockButton[ lockRatio ? 'removeClass' : 'addClass' ]( 'cke_btn_unlocked' ); | ||
330 | lockButton.setAttribute( 'aria-checked', lockRatio ); | ||
331 | |||
332 | // Ratio button hc presentation - WHITE SQUARE / BLACK SQUARE | ||
333 | if ( CKEDITOR.env.hc ) { | ||
334 | var icon = lockButton.getChild( 0 ); | ||
335 | icon.setHtml( lockRatio ? CKEDITOR.env.ie ? '\u25A0' : '\u25A3' : CKEDITOR.env.ie ? '\u25A1' : '\u25A2' ); | ||
336 | } | ||
337 | } | ||
338 | |||
339 | function toggleDimensions( enable ) { | ||
340 | var method = enable ? 'enable' : 'disable'; | ||
341 | |||
342 | widthField[ method ](); | ||
343 | heightField[ method ](); | ||
344 | } | ||
345 | |||
346 | var srcBoxChildren = [ | ||
347 | { | ||
348 | id: 'src', | ||
349 | type: 'text', | ||
350 | label: commonLang.url, | ||
351 | onKeyup: onChangeSrc, | ||
352 | onChange: onChangeSrc, | ||
353 | setup: function( widget ) { | ||
354 | this.setValue( widget.data.src ); | ||
355 | }, | ||
356 | commit: function( widget ) { | ||
357 | widget.setData( 'src', this.getValue() ); | ||
358 | }, | ||
359 | validate: CKEDITOR.dialog.validate.notEmpty( lang.urlMissing ) | ||
360 | } | ||
361 | ]; | ||
362 | |||
363 | // Render the "Browse" button on demand to avoid an "empty" (hidden child) | ||
364 | // space in dialog layout that distorts the UI. | ||
365 | if ( hasFileBrowser ) { | ||
366 | srcBoxChildren.push( { | ||
367 | type: 'button', | ||
368 | id: 'browse', | ||
369 | // v-align with the 'txtUrl' field. | ||
370 | // TODO: We need something better than a fixed size here. | ||
371 | style: 'display:inline-block;margin-top:14px;', | ||
372 | align: 'center', | ||
373 | label: editor.lang.common.browseServer, | ||
374 | hidden: true, | ||
375 | filebrowser: 'info:src' | ||
376 | } ); | ||
377 | } | ||
378 | |||
379 | return { | ||
380 | title: lang.title, | ||
381 | minWidth: 250, | ||
382 | minHeight: 100, | ||
383 | onLoad: function() { | ||
384 | // Create a "global" reference to the document for this dialog instance. | ||
385 | doc = this._.element.getDocument(); | ||
386 | |||
387 | // Create a pre-loader used for determining dimensions of new images. | ||
388 | preLoader = createPreLoader(); | ||
389 | }, | ||
390 | onShow: function() { | ||
391 | // Create a "global" reference to edited widget. | ||
392 | widget = this.widget; | ||
393 | |||
394 | // Create a "global" reference to widget's image. | ||
395 | image = widget.parts.image; | ||
396 | |||
397 | // Reset global variables. | ||
398 | srcChanged = userDefinedLock = lockRatio = false; | ||
399 | |||
400 | // Natural dimensions of the image. | ||
401 | natural = getNatural( image ); | ||
402 | |||
403 | // Get the natural width of the image. | ||
404 | preLoadedWidth = domWidth = natural.width; | ||
405 | |||
406 | // Get the natural height of the image. | ||
407 | preLoadedHeight = domHeight = natural.height; | ||
408 | }, | ||
409 | contents: [ | ||
410 | { | ||
411 | id: 'info', | ||
412 | label: lang.infoTab, | ||
413 | elements: [ | ||
414 | { | ||
415 | type: 'vbox', | ||
416 | padding: 0, | ||
417 | children: [ | ||
418 | { | ||
419 | type: 'hbox', | ||
420 | widths: [ '100%' ], | ||
421 | className: 'cke_dialog_image_url', | ||
422 | children: srcBoxChildren | ||
423 | } | ||
424 | ] | ||
425 | }, | ||
426 | { | ||
427 | id: 'alt', | ||
428 | type: 'text', | ||
429 | label: lang.alt, | ||
430 | setup: function( widget ) { | ||
431 | this.setValue( widget.data.alt ); | ||
432 | }, | ||
433 | commit: function( widget ) { | ||
434 | widget.setData( 'alt', this.getValue() ); | ||
435 | }, | ||
436 | validate: editor.config.image2_altRequired === true ? CKEDITOR.dialog.validate.notEmpty( lang.altMissing ) : null | ||
437 | }, | ||
438 | { | ||
439 | type: 'hbox', | ||
440 | widths: [ '25%', '25%', '50%' ], | ||
441 | requiredContent: features.dimension.requiredContent, | ||
442 | children: [ | ||
443 | { | ||
444 | type: 'text', | ||
445 | width: '45px', | ||
446 | id: 'width', | ||
447 | label: commonLang.width, | ||
448 | validate: validateDimension, | ||
449 | onKeyUp: onChangeDimension, | ||
450 | onLoad: function() { | ||
451 | widthField = this; | ||
452 | }, | ||
453 | setup: function( widget ) { | ||
454 | this.setValue( widget.data.width ); | ||
455 | }, | ||
456 | commit: function( widget ) { | ||
457 | widget.setData( 'width', this.getValue() ); | ||
458 | } | ||
459 | }, | ||
460 | { | ||
461 | type: 'text', | ||
462 | id: 'height', | ||
463 | width: '45px', | ||
464 | label: commonLang.height, | ||
465 | validate: validateDimension, | ||
466 | onKeyUp: onChangeDimension, | ||
467 | onLoad: function() { | ||
468 | heightField = this; | ||
469 | }, | ||
470 | setup: function( widget ) { | ||
471 | this.setValue( widget.data.height ); | ||
472 | }, | ||
473 | commit: function( widget ) { | ||
474 | widget.setData( 'height', this.getValue() ); | ||
475 | } | ||
476 | }, | ||
477 | { | ||
478 | id: 'lock', | ||
479 | type: 'html', | ||
480 | style: lockResetStyle, | ||
481 | onLoad: onLoadLockReset, | ||
482 | setup: function( widget ) { | ||
483 | toggleLockRatio( widget.data.lock ); | ||
484 | }, | ||
485 | commit: function( widget ) { | ||
486 | widget.setData( 'lock', lockRatio ); | ||
487 | }, | ||
488 | html: lockResetHtml | ||
489 | } | ||
490 | ] | ||
491 | }, | ||
492 | { | ||
493 | type: 'hbox', | ||
494 | id: 'alignment', | ||
495 | requiredContent: features.align.requiredContent, | ||
496 | children: [ | ||
497 | { | ||
498 | id: 'align', | ||
499 | type: 'radio', | ||
500 | items: [ | ||
501 | [ commonLang.alignNone, 'none' ], | ||
502 | [ commonLang.alignLeft, 'left' ], | ||
503 | [ commonLang.alignCenter, 'center' ], | ||
504 | [ commonLang.alignRight, 'right' ] | ||
505 | ], | ||
506 | label: commonLang.align, | ||
507 | setup: function( widget ) { | ||
508 | this.setValue( widget.data.align ); | ||
509 | }, | ||
510 | commit: function( widget ) { | ||
511 | widget.setData( 'align', this.getValue() ); | ||
512 | } | ||
513 | } | ||
514 | ] | ||
515 | }, | ||
516 | { | ||
517 | id: 'hasCaption', | ||
518 | type: 'checkbox', | ||
519 | label: lang.captioned, | ||
520 | requiredContent: features.caption.requiredContent, | ||
521 | setup: function( widget ) { | ||
522 | this.setValue( widget.data.hasCaption ); | ||
523 | }, | ||
524 | commit: function( widget ) { | ||
525 | widget.setData( 'hasCaption', this.getValue() ); | ||
526 | } | ||
527 | } | ||
528 | ] | ||
529 | }, | ||
530 | { | ||
531 | id: 'Upload', | ||
532 | hidden: true, | ||
533 | filebrowser: 'uploadButton', | ||
534 | label: lang.uploadTab, | ||
535 | elements: [ | ||
536 | { | ||
537 | type: 'file', | ||
538 | id: 'upload', | ||
539 | label: lang.btnUpload, | ||
540 | style: 'height:40px' | ||
541 | }, | ||
542 | { | ||
543 | type: 'fileButton', | ||
544 | id: 'uploadButton', | ||
545 | filebrowser: 'info:src', | ||
546 | label: lang.btnUpload, | ||
547 | 'for': [ 'Upload', 'upload' ] | ||
548 | } | ||
549 | ] | ||
550 | } | ||
551 | ] | ||
552 | }; | ||
553 | } ); | ||