locomotive-aloha-rails 0.20.1.2 → 0.20.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. data/Rakefile +1 -1
  2. data/lib/aloha/rails/version.rb +2 -2
  3. data/vendor/assets/javascripts/aloha/css/aloha.css +3 -0
  4. data/vendor/assets/javascripts/aloha/css/ext-aloha.css +3 -0
  5. data/vendor/assets/javascripts/aloha/lib/aloha-bootstrap.js +4565 -3934
  6. data/vendor/assets/javascripts/aloha/lib/aloha.js +1357 -702
  7. data/vendor/assets/javascripts/aloha/lib/aloha/command.js +16 -13
  8. data/vendor/assets/javascripts/aloha/lib/aloha/core.js +23 -3
  9. data/vendor/assets/javascripts/aloha/lib/aloha/ecma5shims.js +23 -7
  10. data/vendor/assets/javascripts/aloha/lib/aloha/editable.js +57 -14
  11. data/vendor/assets/javascripts/aloha/lib/aloha/engine.js +9 -5
  12. data/vendor/assets/javascripts/aloha/lib/aloha/floatingmenu.js +288 -96
  13. data/vendor/assets/javascripts/aloha/lib/aloha/jquery.js +11 -1
  14. data/vendor/assets/javascripts/aloha/lib/aloha/markup.js +318 -40
  15. data/vendor/assets/javascripts/aloha/lib/aloha/repositorymanager.js +11 -10
  16. data/vendor/assets/javascripts/aloha/lib/aloha/selection.js +20 -1
  17. data/vendor/assets/javascripts/aloha/lib/aloha/sidebar.js +11 -1
  18. data/vendor/assets/javascripts/aloha/lib/jquery-plugin.js +10 -7
  19. data/vendor/assets/javascripts/aloha/lib/util/dom.js +18 -6
  20. data/vendor/assets/javascripts/aloha/lib/util/range.js +6 -6
  21. data/vendor/assets/javascripts/aloha/lib/vendor/ext-3.2.1/ext-all-debug.js +26 -2
  22. data/vendor/assets/javascripts/aloha/lib/vendor/jquery.store.js +39 -15
  23. data/vendor/assets/javascripts/aloha/plugins/common/abbr/lib/abbr-plugin.js +1 -0
  24. data/vendor/assets/javascripts/aloha/plugins/common/align/lib/align-plugin.js +344 -334
  25. data/vendor/assets/javascripts/aloha/plugins/common/block/css/block.css +65 -12
  26. data/vendor/assets/javascripts/aloha/plugins/common/block/lib/block-plugin.js +12 -15
  27. data/vendor/assets/javascripts/aloha/plugins/common/block/lib/block.js +796 -180
  28. data/vendor/assets/javascripts/aloha/plugins/common/block/lib/blockcontenthandler.js +54 -13
  29. data/vendor/assets/javascripts/aloha/plugins/common/block/lib/blockmanager.js +315 -78
  30. data/vendor/assets/javascripts/aloha/plugins/common/block/lib/editor.js +111 -8
  31. data/vendor/assets/javascripts/aloha/plugins/common/block/lib/editormanager.js +2 -0
  32. data/vendor/assets/javascripts/aloha/plugins/common/block/lib/jquery-ui-1.8.16.custom.min.js +198 -0
  33. data/vendor/assets/javascripts/aloha/plugins/common/block/lib/sidebarattributeeditor.js +7 -20
  34. data/vendor/assets/javascripts/aloha/plugins/common/characterpicker/lib/characterpicker-plugin.js +15 -3
  35. data/vendor/assets/javascripts/aloha/plugins/common/contenthandler/lib/sanitizecontenthandler.js +3 -2
  36. data/vendor/assets/javascripts/aloha/plugins/common/contenthandler/lib/wordcontenthandler.js +111 -5
  37. data/vendor/assets/javascripts/aloha/plugins/common/dom-to-xhtml/lib/dom-to-xhtml-plugin.js +29 -0
  38. data/vendor/assets/javascripts/aloha/plugins/common/dom-to-xhtml/lib/dom-to-xhtml.js +306 -0
  39. data/vendor/assets/javascripts/aloha/plugins/common/format/lib/format-plugin.js +59 -5
  40. data/vendor/assets/javascripts/aloha/plugins/common/format/nls/i18n.js +1 -1
  41. data/vendor/assets/javascripts/aloha/plugins/common/horizontalruler/lib/horizontalruler-plugin.js +18 -3
  42. data/vendor/assets/javascripts/aloha/plugins/common/image/img/crop-buttons.gif +0 -0
  43. data/vendor/assets/javascripts/aloha/plugins/common/image/lib/image-plugin.js +1629 -1601
  44. data/vendor/assets/javascripts/aloha/plugins/common/image/vendor/jcrop/jquery.jcrop.css +11 -0
  45. data/vendor/assets/javascripts/aloha/plugins/common/link/extra/linklist.js +8 -6
  46. data/vendor/assets/javascripts/aloha/plugins/common/link/lib/link-plugin.js +26 -10
  47. data/vendor/assets/javascripts/aloha/plugins/common/list/nls/de/i18n.js +5 -1
  48. data/vendor/assets/javascripts/aloha/plugins/common/paste/lib/paste-plugin.js +3 -4
  49. data/vendor/assets/javascripts/aloha/plugins/common/table/lib/table-cell.js +13 -12
  50. data/vendor/assets/javascripts/aloha/plugins/common/table/lib/table-plugin.js +108 -61
  51. data/vendor/assets/javascripts/aloha/plugins/common/table/lib/table-selection.js +61 -1
  52. data/vendor/assets/javascripts/aloha/plugins/common/table/lib/table.js +1 -0
  53. data/vendor/assets/javascripts/aloha/plugins/common/table/nls/de/i18n.js +28 -1
  54. data/vendor/assets/javascripts/aloha/plugins/common/table/nls/i18n.js +36 -10
  55. data/vendor/assets/javascripts/aloha/plugins/extra/browser/css/browser.jqgrid.css +292 -292
  56. data/vendor/assets/javascripts/aloha/plugins/extra/browser/lib/browser.js +28 -5
  57. data/vendor/assets/javascripts/aloha/plugins/extra/browser/lib/locale.js +2 -2
  58. data/vendor/assets/javascripts/aloha/plugins/extra/browser/vendor/grid.locale.de.js +6 -1
  59. data/vendor/assets/javascripts/aloha/plugins/extra/browser/vendor/grid.locale.en.js +5 -0
  60. data/vendor/assets/javascripts/aloha/plugins/extra/browser/vendor/jquery.jqGrid.js +5 -0
  61. data/vendor/assets/javascripts/aloha/plugins/extra/browser/vendor/jquery.jstree.js +6 -1
  62. data/vendor/assets/javascripts/aloha/plugins/extra/browser/vendor/jquery.ui.js +6 -1
  63. data/vendor/assets/javascripts/aloha/plugins/extra/browser/vendor/ui-layout.js +6 -1
  64. data/vendor/assets/javascripts/aloha/plugins/extra/cite/lib/cite-plugin.js +18 -4
  65. data/vendor/assets/javascripts/aloha/plugins/extra/formatlesspaste/lib/formatlesspaste-plugin.js +1 -1
  66. data/vendor/assets/javascripts/aloha/plugins/extra/linkbrowser/lib/linkbrowser-plugin.js +14 -2
  67. data/vendor/assets/javascripts/aloha/plugins/extra/numerated-headers/demo/js/aloha-config.js +2 -2
  68. data/vendor/assets/javascripts/aloha/plugins/extra/toc/lib/toc-plugin.js +382 -0
  69. data/vendor/assets/javascripts/aloha/plugins/extra/toc/nls/de/i18n.js +3 -0
  70. data/vendor/assets/javascripts/aloha/plugins/extra/toc/nls/i18n.js +4 -0
  71. metadata +15 -11
  72. data/vendor/assets/javascripts/aloha/plugins/extra/toc/i18n/de.json +0 -1
  73. data/vendor/assets/javascripts/aloha/plugins/extra/toc/i18n/en.json +0 -1
  74. data/vendor/assets/javascripts/aloha/plugins/extra/toc/src/toc.js +0 -350
@@ -25,7 +25,7 @@ function(Aloha, Plugin, jQuery, FloatingMenu, i18n, i18nCore) {
25
25
  /**
26
26
  * default button configuration
27
27
  */
28
- config: [ 'strong', 'em', 'b', 'i','del','sub','sup', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'pre', 'removeFormat'],
28
+ config: [ 'strong', 'em', 'b', 'i','s','sub','sup', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'pre', 'removeFormat'],
29
29
 
30
30
  /**
31
31
  * Initialize the plugin and set initialize flag on true
@@ -38,7 +38,6 @@ function(Aloha, Plugin, jQuery, FloatingMenu, i18n, i18nCore) {
38
38
 
39
39
  // apply specific configuration if an editable has been activated
40
40
  Aloha.bind('aloha-editable-activated',function (e, params) {
41
- //debugger;
42
41
  me.applyButtonConfig(params.editable.obj);
43
42
  });
44
43
 
@@ -60,7 +59,6 @@ function(Aloha, Plugin, jQuery, FloatingMenu, i18n, i18nCore) {
60
59
 
61
60
  var config = this.getEditableConfig(obj),
62
61
  button, i, len;
63
-
64
62
  // now iterate all buttons and show/hide them according to the config
65
63
  for ( button in this.buttons) {
66
64
  if (jQuery.inArray(button, config) != -1) {
@@ -102,6 +100,7 @@ function(Aloha, Plugin, jQuery, FloatingMenu, i18n, i18nCore) {
102
100
  jQuery.each(this.config, function(j, button) {
103
101
  switch( button ) {
104
102
  // text level semantics:
103
+ case 'u':
105
104
  case 'em':
106
105
  case 'strong':
107
106
  case 'b':
@@ -111,6 +110,7 @@ function(Aloha, Plugin, jQuery, FloatingMenu, i18n, i18nCore) {
111
110
  case 'code':
112
111
  case 'abbr':
113
112
  case 'del':
113
+ case 's':
114
114
  case 'sub':
115
115
  case 'sup':
116
116
  that.buttons[button] = {'button' : new Aloha.ui.Button({
@@ -121,14 +121,41 @@ function(Aloha, Plugin, jQuery, FloatingMenu, i18n, i18nCore) {
121
121
  var
122
122
  markup = jQuery('<'+button+'></'+button+'>'),
123
123
  rangeObject = Aloha.Selection.rangeObject,
124
- foundMarkup;
124
+ foundMarkup,
125
+ selectedCells = jQuery('.aloha-cell-selected');
126
+
127
+ // formating workaround for table plugin
128
+ if ( selectedCells.length > 0 ) {
129
+ var cellMarkupCounter = 0;
130
+ selectedCells.each( function () {
131
+ var cellContent = jQuery(this).find('div'),
132
+ cellMarkup = cellContent.find(button);
133
+
134
+ if ( cellMarkup.length > 0 ) {
135
+ // unwrap all found markup text
136
+ // <td><b>text</b> foo <b>bar</b></td>
137
+ // and wrap the whole contents of the <td> into <b> tags
138
+ // <td><b>text foo bar</b></td>
139
+ cellMarkup.contents().unwrap();
140
+ cellMarkupCounter++;
141
+ }
142
+ cellContent.contents().wrap('<'+button+'></'+button+'>');
143
+ });
144
+
145
+ // remove all markup if all cells have markup
146
+ if ( cellMarkupCounter == selectedCells.length ) {
147
+ selectedCells.find(button).contents().unwrap();
148
+ }
149
+ return false;
150
+ }
151
+ // formating workaround for table plugin
125
152
 
126
153
  // check whether the markup is found in the range (at the start of the range)
127
154
  foundMarkup = rangeObject.findMarkup(function() {
128
155
  return this.nodeName.toLowerCase() == markup.get(0).nodeName.toLowerCase();
129
156
  }, Aloha.activeEditable.obj);
130
157
 
131
- if (foundMarkup) {
158
+ if ( foundMarkup ) {
132
159
  // remove the markup
133
160
  if (rangeObject.isCollapsed()) {
134
161
  // when the range is collapsed, we remove exactly the one DOM element
@@ -176,6 +203,33 @@ function(Aloha, Plugin, jQuery, FloatingMenu, i18n, i18nCore) {
176
203
  'iconClass' : 'aloha-button ' + i18n.t('aloha-button-' + button),
177
204
  'markup' : jQuery('<'+button+'></'+button+'>'),
178
205
  'click' : function() {
206
+ var selectedCells = jQuery('.aloha-cell-selected');
207
+ // formating workaround for table plugin
208
+ if ( selectedCells.length > 0 ) {
209
+ var cellMarkupCounter = 0;
210
+ selectedCells.each( function () {
211
+ var cellContent = jQuery(this).find('div'),
212
+ cellMarkup = cellContent.find(button);
213
+
214
+ if ( cellMarkup.length > 0 ) {
215
+ // unwrap all found markup text
216
+ // <td><b>text</b> foo <b>bar</b></td>
217
+ // and wrap the whole contents of the <td> into <b> tags
218
+ // <td><b>text foo bar</b></td>
219
+ cellMarkup.contents().unwrap();
220
+ cellMarkupCounter++;
221
+ }
222
+ cellContent.contents().wrap('<'+button+'></'+button+'>');
223
+ });
224
+
225
+ // remove all markup if all cells have markup
226
+ if ( cellMarkupCounter == selectedCells.length ) {
227
+ selectedCells.find(button).contents().unwrap();
228
+ }
229
+ return false;
230
+ }
231
+ // formating workaround for table plugin
232
+
179
233
  Aloha.Selection.changeMarkupOnSelection(jQuery('<' + button + '></' + button + '>'));
180
234
  }
181
235
  });
@@ -1,5 +1,5 @@
1
1
  define({
2
- root: {"button.strong.tooltip":"Strong","button.em.tooltip":"Emphasize","button.b.tooltip":"Bold","button.i.tooltip":"Italic","button.u.tooltip":"Underline","button.cite.tooltip":"Cite","button.q.tooltip":"","button.code.tooltip":"Code","button.abbr.tooltip":"Abbreviation","button.del.tooltip":"Strikethrough","button.sub.tooltip":"Subscript","button.sup.tooltip":"Superscript","button.p.tooltip":"Paragraph","button.h1.tooltip":"Heading 1","button.h2.tooltip":"Heading 2","button.h3.tooltip":"Heading 3","button.h4.tooltip":"Heading 4","button.h5.tooltip":"Heading 5","button.h6.tooltip":"Heading 6","button.pre.tooltip":"Pre formated text","button.title.tooltip":"Title","button.removeFormat.tooltip":"Remove formatting","button.removeFormat.text":"Remove formatting","GENTICS_button_p":"GENTICS_button_p","GENTICS_button_h1":"GENTICS_button_h1","GENTICS_button_h2":"GENTICS_button_h2","GENTICS_button_h3":"GENTICS_button_h3","GENTICS_button_h4":"GENTICS_button_h4","GENTICS_button_h5":"GENTICS_button_h5","GENTICS_button_h6":"GENTICS_button_h6","GENTICS_button_pre":"GENTICS_button_pre","GENTICS_button_title":"GENTICS_button_title"}
2
+ root: {"button.strong.tooltip":"Strong","button.em.tooltip":"Emphasize","button.b.tooltip":"Bold","button.i.tooltip":"Italic","button.u.tooltip":"Underline","button.cite.tooltip":"Cite","button.q.tooltip":"","button.code.tooltip":"Code","button.abbr.tooltip":"Abbreviation","button.s.tooltip":"Strikethrough","button.del.tooltip":"Deleted","button.sub.tooltip":"Subscript","button.sup.tooltip":"Superscript","button.p.tooltip":"Paragraph","button.h1.tooltip":"Heading 1","button.h2.tooltip":"Heading 2","button.h3.tooltip":"Heading 3","button.h4.tooltip":"Heading 4","button.h5.tooltip":"Heading 5","button.h6.tooltip":"Heading 6","button.pre.tooltip":"Pre formated text","button.title.tooltip":"Title","button.removeFormat.tooltip":"Remove formatting","button.removeFormat.text":"Remove formatting","GENTICS_button_p":"GENTICS_button_p","GENTICS_button_h1":"GENTICS_button_h1","GENTICS_button_h2":"GENTICS_button_h2","GENTICS_button_h3":"GENTICS_button_h3","GENTICS_button_h4":"GENTICS_button_h4","GENTICS_button_h5":"GENTICS_button_h5","GENTICS_button_h6":"GENTICS_button_h6","GENTICS_button_pre":"GENTICS_button_pre","GENTICS_button_title":"GENTICS_button_title"}
3
3
  , "de":true,
4
4
  "eo":true,
5
5
  "fi":true,
@@ -17,9 +17,11 @@ function(Aloha, jQuery, Plugin, FloatingMenu, i18n, i18nCore) {
17
17
  this._super('horizontalruler');
18
18
  },
19
19
  languages: ['en'],
20
+ config: ['hr'],
20
21
  init: function() {
21
22
  var that = this;
22
- var insertButton = new Aloha.ui.Button({
23
+
24
+ this.insertButton = new Aloha.ui.Button({
23
25
  'name': 'hr',
24
26
  'iconClass': 'aloha-button-horizontalruler',
25
27
  'size': 'small',
@@ -29,11 +31,24 @@ function(Aloha, jQuery, Plugin, FloatingMenu, i18n, i18nCore) {
29
31
  });
30
32
  FloatingMenu.addButton(
31
33
  'Aloha.continuoustext',
32
- insertButton,
34
+ this.insertButton,
33
35
  i18nCore.t('floatingmenu.tab.insert'),
34
36
  1
35
37
  );
36
-
38
+
39
+ Aloha.bind( 'aloha-editable-activated', function ( event, rangeObject ) {
40
+ if (Aloha.activeEditable) {
41
+ that.cfg = that.getEditableConfig( Aloha.activeEditable.obj );
42
+
43
+ if ( jQuery.inArray( 'hr', that.cfg ) != -1 ) {
44
+ that.insertButton.show();
45
+ } else {
46
+ that.insertButton.hide();
47
+ return;
48
+ }
49
+ }
50
+ });
51
+
37
52
  },
38
53
  insertHR: function(character) {
39
54
  var self = this;
@@ -1,1615 +1,1643 @@
1
1
  /*
2
2
  * Aloha Image Plugin - Allow image manipulation in Aloha Editor
3
- *
3
+ *
4
4
  * Author & Copyright (c) 2011 Gentics Software GmbH
5
5
  * aloha-sales@gentics.com
6
- * Contributors
6
+ * Contributors
7
7
  * Johannes Schüth - http://jotschi.de
8
- * Nicolas karageuzian - http://nka.me/
9
- * Benjamin Athur Lupton - http://www.balupton.com/
10
- * Thomas Lete
11
- * Nils Dehl
12
- * Christopher Hlubek
13
- * Edward Tsech
14
- * Haymo Meran
8
+ * Nicolas karageuzian - http://nka.me/
9
+ * Benjamin Athur Lupton - http://www.balupton.com/
10
+ * Thomas Lete
11
+ * Nils Dehl
12
+ * Christopher Hlubek
13
+ * Edward Tsech
14
+ * Haymo Meran
15
15
  *
16
16
  * Licensed under the terms of http://www.aloha-editor.com/license.html
17
17
  */
18
18
 
19
19
  define([
20
- // js
21
- 'aloha/jquery',
22
- 'aloha/plugin',
23
- 'aloha/floatingmenu',
24
- 'i18n!aloha/nls/i18n',
25
- 'i18n!image/nls/i18n',
26
- 'jquery-plugin!image/vendor/ui/jquery-ui-1.8.10.custom.min',
27
- 'jquery-plugin!image/vendor/jcrop/jquery.jcrop.min',
28
- 'jquery-plugin!image/vendor/mousewheel/mousewheel',
29
- // css
30
- 'css!image/css/image.css',
31
- 'css!image/vendor/ui/ui-lightness/jquery-ui-1.8.10.cropnresize.css',
32
- 'css!image/vendor/jcrop/jquery.jcrop.css'
20
+ // js
21
+ 'aloha/jquery',
22
+ 'aloha/plugin',
23
+ 'aloha/floatingmenu',
24
+ 'i18n!aloha/nls/i18n',
25
+ 'i18n!image/nls/i18n',
26
+ 'jquery-plugin!image/vendor/ui/jquery-ui-1.8.10.custom.min',
27
+ 'jquery-plugin!image/vendor/jcrop/jquery.jcrop.min',
28
+ 'jquery-plugin!image/vendor/mousewheel/mousewheel',
29
+ // css
30
+ 'css!image/css/image.css',
31
+ 'css!image/vendor/ui/ui-lightness/jquery-ui-1.8.10.cropnresize.css',
32
+ 'css!image/vendor/jcrop/jquery.jcrop.css'
33
33
  ],
34
34
  function AlohaImagePlugin ( aQuery, Plugin, FloatingMenu, i18nCore, i18n ) {
35
-
36
-
37
-
38
- var jQuery = aQuery;
39
- var $ = aQuery;
40
- var GENTICS = window.GENTICS, Aloha = window.Aloha;
41
-
42
- // Attributes manipulation utilities
43
- // Aloha team may want to factorize, it could be useful for other plugins
44
- // Prototypes
45
- String.prototype.toInteger = String.prototype.toInteger || function() {
46
- return parseInt(String(this).replace(/px$/,'')||0,10);
47
- };
48
- String.prototype.toFloat = String.prototype.toInteger || function() {
49
- return parseFloat(String(this).replace(/px$/,'')||0,10);
50
- };
51
- Number.prototype.toInteger = Number.prototype.toInteger || String.prototype.toInteger;
52
- Number.prototype.toFloat = Number.prototype.toFloat || String.prototype.toFloat;
53
-
54
- // Insert jQuery Prototypes
55
- jQuery.extend(true, jQuery.fn, {
56
- increase: jQuery.fn.increase || function(attr) {
57
- var obj = jQuery(this), value, newValue;
58
- // Check
59
- if ( !obj.length ) {
60
- return obj;
61
- }
62
- // Calculate
63
- value = obj.css(attr).toFloat();
64
- newValue = Math.round((value||1)*1.2);
65
- // Apply
66
- if (value == newValue) { // when value is 2, won't increase
67
- newValue++;
68
- }
69
- // Apply
70
- obj.css(attr,newValue);
71
- // Chain
72
- return obj;
73
- },
74
- decrease: jQuery.fn.decrease || function(attr) {
75
- var obj = jQuery(this), value, newValue;
76
- // Check
77
- if ( !obj.length ) {
78
- return obj;
79
- }
80
- // Calculate
81
- value = obj.css(attr).toFloat();
82
- newValue = Math.round((value||0)*0.8);
83
- // Apply
84
- if (value == newValue && newValue >0) { // when value is 2, won't increase
85
- newValue--;
86
- }
87
- obj.css(attr,newValue);
88
- // Chain
89
- return obj;
90
- }
91
- });
92
-
93
- // Create and register Image Plugin
94
- return Plugin.create('image', {
95
-
96
- languages: ['en', 'fr', 'de', 'ru', 'cz'],
97
-
98
- defaultSettings: {
99
- 'maxWidth': 1600,
100
- 'minWidth': 3,
101
- 'maxHeight': 1200,
102
- 'minHeight': 3,
103
- // This setting will correct manually values that are out of bounds
104
- 'autoCorrectManualInput': true,
105
- // This setting will define a fixed aspect ratio for all resize actions
106
- 'fixedAspectRatio' : false,
107
- // When enabled this setting will order the plugin to automatically resize images to given bounds
108
- 'autoResize': false,
109
- //Image manipulation options - ONLY in default config section
110
- ui: {
111
- oneTab : false, //Place all ui components within one tab
112
- insert : true,
113
- reset : true,
114
- aspectRatioToggle: true, // Toggle button for the aspect ratio
115
- align : true, // Menu elements to show/hide in menu
116
- resize : true, // Resize buttons
117
- meta : true,
118
- margin : true,
119
- crop : true,
120
- resizable : true, // Resizable ui-drag image
121
- handles : 'ne, se, sw, nw'
122
- },
123
-
124
- /**
125
- * Crop callback is triggered after the user clicked accept to accept his crop
126
- * @param image jquery image object reference
127
- * @param props cropping properties
128
- */
129
- onCropped: function ($image, props) {
130
- Aloha.Log.info('Default onCropped invoked', $image, props);
131
- },
132
-
133
- /**
134
- * Reset callback is triggered before the internal reset procedure is applied
135
- * if this function returns true, then the reset has been handled by the callback
136
- * which means that no other reset will be applied
137
- * if false is returned the internal reset procedure will be applied
138
- * @param image jquery image object reference
139
- * @return true if a reset has been applied, false otherwise
140
- */
141
- onReset: function ($image) {
142
- Aloha.Log.info('Default onReset invoked', $image);
143
- return false;
144
- },
145
-
146
- /**
147
- * Example callback method which gets called while the resize process is beeing executed.
148
- */
149
- onResize: function ($image) {
150
- Aloha.Log.info('Default onResize invoked', $image);
151
- },
152
-
153
- /**
154
- * Resize callback is triggered after the internal resize procedure is applied.
155
- */
156
- onResized: function ($image) {
157
- Aloha.Log.info('Default onResized invoked', $image);
158
- }
159
- },
160
-
161
- /**
162
- * Internal callback hook which gets invoked when cropping has been finished
163
- */
164
- _onCropped: function ($image, props) {
165
-
166
- $('#' + this.imgResizeHeightField.id).val($image.height());
167
- $('#' + this.imgResizeWidthField.id).val($image.width());
168
-
169
-
170
- $('body').trigger('aloha-image-cropped', [$image, props]);
171
-
172
- // Call the custom onCropped function
173
- this.onCropped($image, props);
174
- },
175
-
176
- /**
177
- * Internal callback hook which gets invoked when resetting images
178
- */
179
- _onReset: function ($image) {
180
-
181
- $('#' + this.imgResizeHeightField.id).val($image.height());
182
- $('#' + this.imgResizeWidthField.id).val($image.width());
183
-
184
- // No default behaviour defined besides event triggering
185
- $('body').trigger('aloha-image-reset', $image);
186
-
187
- // Call the custom resize function
188
- return this.onReset($image);
189
- },
190
-
191
- /**
192
- * Internal callback hook which gets invoked while the image is beeing resized
193
- */
194
- _onResize: function ($image) {
195
-
196
- $('#' + this.imgResizeHeightField.id).val($image.height());
197
- $('#' + this.imgResizeWidthField.id).val($image.width());
198
-
199
- // No default behaviour defined besides event triggering
200
- $('body').trigger('aloha-image-resize', $image);
201
-
202
- // Call the custom resize function
203
- this.onResize($image);
204
- },
205
-
206
- /**
207
- * Internal callback hook which gets invoked when the current resizing action has stopped
208
- */
209
- _onResized: function ($image) {
210
-
211
- $('#' + this.imgResizeHeightField.id).val($image.height());
212
- $('#' + this.imgResizeWidthField.id).val($image.width());
213
-
214
- $('body').trigger('aloha-image-resized', $image);
215
-
216
- // Call the custom resize function
217
- this.onResized($image);
218
- },
219
-
220
- /**
221
- * The image that is currently edited
222
- */
223
- imageObj: null,
224
-
225
- /**
226
- * The Jcrop API reference
227
- * this is needed to be able to destroy the cropping frame later on
228
- * the variable is linked to the api object whilst cropping, or set to null otherwise
229
- * strange, but done as documented http://deepliquid.com/content/Jcrop_API.html
230
- */
231
- jcAPI: null,
232
-
233
-
234
- /**
235
- * State variable for the aspect ratio toggle feature
236
- */
237
- keepAspectRatio: false,
238
-
239
- /**
240
- * Variable that will hold the start aspect ratio. This ratio will be used once starResize will be called.
241
- */
242
- startAspectRatio: false,
243
-
244
- /**
245
- * This will contain an image's original properties to be able to undo previous settings
246
- *
247
- * when an image is clicked for the first time, a new object will be added to the array
248
- * {
249
- * obj : [the image object reference],
250
- * src : [the original src url],
251
- * width : [initial width],
252
- * height : [initial height]
253
- * }
254
- *
255
- * when an image is clicked the second time, the array will be checked for the image object
256
- * referenct, to prevent for double entries
257
- */
258
- restoreProps: [],
259
-
260
- objectTypeFilter: [],
261
-
262
- /**
263
- * Plugin initialization method
264
- */
265
- init: function() {
266
-
267
- var that = this;
268
-
269
- var imagePluginUrl = Aloha.getPluginUrl('image');
270
-
271
- // Extend the default settings with the custom ones (done by default)
272
- this.startAspectRatio = this.settings.fixedAspectRatio;
273
- this.config = this.defaultSettings;
274
- this.settings = jQuery.extend(true, this.defaultSettings, this.settings);
275
-
276
- that.initializeButtons();
277
- that.bindInteractions();
278
- that.subscribeEvents();
279
-
280
- },
281
-
282
- /**
283
- * Create buttons
284
- */
285
- initializeButtons: function() {
286
-
287
- var that = this,
288
- tabInsert = i18nCore.t('floatingmenu.tab.insert'),
289
- tabImage = i18n.t('floatingmenu.tab.img'),
290
- tabFormatting = i18n.t('floatingmenu.tab.formatting'),
291
- tabCrop = i18n.t('floatingmenu.tab.crop'),
292
- tabResize = i18n.t('floatingmenu.tab.resize');
293
-
294
- FloatingMenu.createScope(this.name, 'Aloha.empty');
295
-
296
- if (this.settings.ui.insert) {
297
- var tabId = this.settings.ui.oneTab ? tabImage : tabInsert;
298
- that._addUIInsertButton(tabId);
299
- }
300
-
301
- if (this.settings.ui.meta) {
302
- var tabId = this.settings.ui.oneTab ? tabImage : tabImage;
303
- that._addUIMetaButtons(tabId);
304
- }
305
-
306
- if (this.settings.ui.reset) {
307
- var tabId = this.settings.ui.reset ? tabImage : tabImage;
308
- that._addUIResetButton(tabId);
309
- }
310
-
311
- if (this.settings.ui.align) {
312
- var tabId = this.settings.ui.oneTab ? tabImage : tabFormatting;
313
- that._addUIAlignButtons(tabId);
314
- }
315
-
316
- if (this.settings.ui.margin) {
317
- var tabId = this.settings.ui.oneTab ? tabImage : tabFormatting;
318
- that._addUIMarginButtons(tabId);
319
- }
320
-
321
- if (this.settings.ui.crop) {
322
- var tabId = this.settings.ui.oneTab ? tabImage : tabCrop;
323
- that._addUICropButtons(tabId);
324
- }
325
-
326
- if (this.settings.ui.resize) {
327
- var tabId = this.settings.ui.oneTab ? tabImage : tabResize;
328
- that._addUIResizeButtons(tabId);
329
- }
330
-
331
- if (this.settings.ui.aspectRatioToggle) {
332
- var tabId = this.settings.ui.oneTab ? tabImage : tabResize;
333
- that.__addUIAspectRatioToggleButton(tabId);
334
- }
335
-
336
- // TODO fix the function and reenable this button
337
- //that._addNaturalSizeButton();
338
- },
339
-
340
-
341
- /**
342
- * Adds the aspect ratio toggle button to the floating menu
343
- */
344
- __addUIAspectRatioToggleButton: function(tabId) {
345
- var that = this;
346
- var toggleButton = new Aloha.ui.Button({
347
- 'size' : 'small',
348
- 'tooltip' : i18n.t('button.toggle.tooltip'),
349
- 'toggle' : true,
350
- 'iconClass' : 'cnr-ratio',
351
- 'onclick' : function (btn, event) {
352
- that.toggleKeepAspectRatio();
353
- }
354
- });
355
-
356
-
357
- // If the setting has been set to a number or false we need to activate the
358
- // toggle button to indicate that the aspect ratio will be preserved.
359
- if (this.settings.fixedAspectRatio != false) {
360
- toggleButton.pressed = true;
361
- this.keepAspectRatio = true;
362
- }
363
-
364
- FloatingMenu.addButton(
365
- that.name,
366
- toggleButton,
367
- tabId,
368
- 20
369
- );
370
-
371
-
372
- },
373
-
374
-
375
- /**
376
- * Adds the reset button to the floating menu for the given tab
377
- */
378
- _addUIResetButton: function(tabId) {
379
- var that = this;
380
- // Reset button
381
- var resetButton = new Aloha.ui.Button({
382
- 'size' : 'small',
383
- 'tooltip' : i18n.t('Reset'),
384
- 'toggle' : false,
385
- 'iconClass' : 'cnr-reset',
386
- 'onclick' : function (btn, event) {
387
- that.reset();
388
- }
389
- });
390
-
391
- FloatingMenu.addButton(
392
- that.name,
393
- resetButton,
394
- tabId,
395
- 2
396
- );
397
- },
398
-
399
- /**
400
- * Adds the insert button to the floating menu
401
- */
402
- _addUIInsertButton: function(tabId) {
403
- var that = this;
404
- this.insertImgButton = new Aloha.ui.Button({
405
- 'name' : 'insertimage',
406
- 'iconClass': 'aloha-button aloha-image-insert',
407
- 'size' : 'small',
408
- 'onclick' : function () { that.insertImg(); },
409
- 'tooltip' : i18n.t('button.addimg.tooltip'),
410
- 'toggle' : false
411
- });
412
-
413
- FloatingMenu.addButton(
414
- 'Aloha.continuoustext',
415
- this.insertImgButton,
416
- tabId,
417
- 1
418
- );
419
- },
420
-
421
- /**
422
- * Adds the ui meta fields (search, title) to the floating menu.
423
- */
424
- _addUIMetaButtons: function(tabId) {
425
- var that = this;
426
- var imgSrcLabel = new Aloha.ui.Button({
427
- 'label': i18n.t('field.img.src.label'),
428
- 'tooltip': i18n.t('field.img.src.tooltip'),
429
- 'size': 'small'
430
- });
431
- this.imgSrcField = new Aloha.ui.AttributeField({'name' : 'imgsrc'});
432
- this.imgSrcField.setObjectTypeFilter( this.objectTypeFilter );
433
-
434
- // add the title field for images
435
- var imgTitleLabel = new Aloha.ui.Button({
436
- 'label': i18n.t('field.img.title.label'),
437
- 'tooltip': i18n.t('field.img.title.tooltip'),
438
- 'size': 'small'
439
- });
440
-
441
- this.imgTitleField = new Aloha.ui.AttributeField();
442
- this.imgTitleField.setObjectTypeFilter();
443
- FloatingMenu.addButton(
444
- this.name,
445
- this.imgSrcField,
446
- tabId,
447
- 1
448
- );
449
-
450
- },
451
-
452
- /**
453
- * Adds the ui align buttons to the floating menu
454
- */
455
- _addUIAlignButtons: function(tabId) {
456
- var that = this;
457
-
458
- var alignLeftButton = new Aloha.ui.Button({
459
- 'iconClass': 'aloha-img aloha-image-align-left',
460
- 'size': 'small',
461
- 'onclick' : function() {
462
- var el = jQuery(that.findImgMarkup());
463
- el.add(el.parent()).css('float', 'left');
464
- },
465
- 'tooltip': i18n.t('button.img.align.left.tooltip')
466
- });
467
-
468
- FloatingMenu.addButton(
469
- that.name,
470
- alignLeftButton,
471
- tabId,
472
- 1
473
- );
474
-
475
- var alignRightButton = new Aloha.ui.Button({
476
- 'iconClass': 'aloha-img aloha-image-align-right',
477
- 'size': 'small',
478
- 'onclick' : function() {
479
- var el = jQuery(that.findImgMarkup());
480
- el.add(el.parent()).css('float', 'right');
481
- },
482
- 'tooltip': i18n.t('button.img.align.right.tooltip')
483
- });
484
-
485
- FloatingMenu.addButton(
486
- that.name,
487
- alignRightButton,
488
- tabId,
489
- 1
490
- );
491
-
492
- var alignNoneButton = new Aloha.ui.Button({
493
- 'iconClass': 'aloha-img aloha-image-align-none',
494
- 'size': 'small',
495
- 'onclick' : function() {
496
- var el = jQuery(that.findImgMarkup());
497
- el.add(el.parent()).css({
498
- 'float': 'none',
499
- display: 'inline-block'
500
- });
501
- },
502
- 'tooltip': i18n.t('button.img.align.none.tooltip')
503
- });
504
-
505
- FloatingMenu.addButton(
506
- that.name,
507
- alignNoneButton,
508
- tabId,
509
- 1
510
- );
511
-
512
- },
513
-
514
- /**
515
- * Adds the ui margin buttons to the floating menu
516
- */
517
- _addUIMarginButtons: function(tabId) {
518
- var that = this;
519
- var incPadding = new Aloha.ui.Button({
520
- iconClass: 'aloha-img aloha-image-padding-increase',
521
- toggle: false,
522
- size: 'small',
523
- onclick: function() {
524
- jQuery(that.findImgMarkup()).increase('padding');
525
- },
526
- tooltip: i18n.t('padding.increase')
527
- });
528
- FloatingMenu.addButton(
529
- that.name,
530
- incPadding,
531
- tabId,
532
- 2
533
- );
534
-
535
- var decPadding = new Aloha.ui.Button({
536
- iconClass: 'aloha-img aloha-image-padding-decrease',
537
- toggle: false,
538
- size: 'small',
539
- onclick: function() {
540
- jQuery(that.findImgMarkup()).decrease('padding');
541
- },
542
- tooltip: i18n.t('padding.decrease')
543
- });
544
- FloatingMenu.addButton(
545
- that.name,
546
- decPadding,
547
- tabId,
548
- 2
549
- );
550
- },
551
-
552
- /**
553
- * Adds the crop buttons to the floating menu
554
- */
555
- _addUICropButtons: function (tabId) {
556
- var that = this;
557
-
558
- FloatingMenu.createScope('Aloha.img', ['Aloha.global']);
559
-
560
- this.cropButton = new Aloha.ui.Button({
561
- 'size' : 'small',
562
- 'tooltip' : i18n.t('Crop'),
563
- 'toggle' : true,
564
- 'iconClass' : 'cnr-crop',
565
- 'onclick' : function (btn, event) {
566
- if (btn.pressed) {
567
- that.crop();
568
- } else {
569
- that.endCrop();
570
- }
571
- }
572
- });
573
-
574
- FloatingMenu.addButton(
575
- this.name,
576
- this.cropButton,
577
- tabId,
578
- 3
579
- );
580
-
581
- },
582
-
583
- /**
584
- * Adds the resize buttons to the floating menu
585
- */
586
- _addUIResizeButtons: function (tabId) {
587
- var that = this;
588
-
589
- // Manual resize fields
590
- this.imgResizeHeightField = new Aloha.ui.AttributeField();
591
- this.imgResizeHeightField.maxValue = that.settings.maxHeight;
592
- this.imgResizeHeightField.minValue = that.settings.minHeight;
593
-
594
- this.imgResizeWidthField = new Aloha.ui.AttributeField();
595
- this.imgResizeWidthField.maxValue = that.settings.maxWidth;
596
- this.imgResizeWidthField.minValue = that.settings.minWidth;
597
-
598
- this.imgResizeWidthField.width = 50;
599
- this.imgResizeHeightField.width = 50;
600
-
601
- var widthLabel = new Aloha.ui.Button({
602
- 'label': i18n.t('width'),
603
- 'tooltip': i18n.t('width'),
604
- 'size': 'small'
605
- });
606
-
607
- FloatingMenu.addButton(
608
- this.name,
609
- widthLabel,
610
- tabId,
611
- 30
612
- );
613
-
614
- FloatingMenu.addButton(
615
- this.name,
616
- this.imgResizeWidthField,
617
- tabId,
618
- 40
619
- );
620
-
621
-
622
- var heightLabel = new Aloha.ui.Button({
623
- 'label': i18n.t('height'),
624
- 'tooltip': i18n.t('height'),
625
- 'size': 'small'
626
- });
627
-
628
- FloatingMenu.addButton(
629
- this.name,
630
- heightLabel,
631
- tabId,
632
- 50
633
- );
634
-
635
- FloatingMenu.addButton(
636
- this.name,
637
- this.imgResizeHeightField,
638
- tabId,
639
- 60
640
- );
641
-
642
-
643
- },
644
-
645
- /**
646
- * Adds the natural size button to the floating menu
647
- */
648
- _addNaturalSizeButton: function () {
649
- var that = this;
650
- var naturalSize = new Aloha.ui.Button({
651
- iconClass: 'aloha-img aloha-image-size-natural',
652
- size: 'small',
653
- toggle: false,
654
- onclick: function() {
655
- var img = new Image();
656
- img.onload = function() {
657
- var myimage = that.findImgMarkup();
658
- if (that.settings.ui.resizable) {
659
- that.endResize();
660
- }
661
- jQuery(myimage).css({
662
- 'width': img.width + 'px',
663
- 'height': img.height + 'px',
664
- 'max-width': '',
665
- 'max-height': ''
666
- });
667
- if (that.settings.ui.resizable) {
668
- that.resize();
669
- }
670
- };
671
- img.src = that.findImgMarkup().src;
672
-
673
- },
674
- tooltip: i18n.t('size.natural')
675
- });
676
- FloatingMenu.addButton(
677
- this.name,
678
- naturalSize,
679
- tabResize,
680
- 2
681
- );
682
- },
683
-
684
- /**
685
- * Bind plugin interactions
686
- */
687
- bindInteractions: function () {
688
- var that = this;
689
-
690
- if (this.settings.ui.resizable) {
691
- try {
692
- // this will disable mozillas image resizing facilities
693
- document.execCommand( 'enableObjectResizing', false, false );
694
- } catch (e) {
695
- Aloha.Log.error( e, 'Could not disable enableObjectResizing' );
696
- // this is just for internet explorer, who will not support disabling enableObjectResizing
697
- }
698
- }
699
-
700
- if (this.settings.ui.meta) {
701
- // update image object when src changes
702
- this.imgSrcField.addListener('keyup', function(obj, event) {
703
- that.srcChange();
704
- });
705
-
706
- this.imgSrcField.addListener('blur', function(obj, event) {
707
- // TODO remove image or do something usefull if the user leaves the
708
- // image without defining a valid image src.
709
- var img = jQuery(obj.getTargetObject());
710
- if ( img.attr('src') === '' ) {
711
- img.remove();
712
- } // image removal when src field is blank
713
- });
714
- }
715
-
716
- // Override the default method by using the given one
717
- if (this.settings.onCropped && typeof this.settings.onCropped === "function") {
718
- this.onCropped = this.settings.onCropped;
719
- }
720
-
721
- // Override the default method by using the given one
722
- if (this.settings.onReset && typeof this.settings.onReset === "function") {
723
- this.onReset = this.settings.onReset;
724
- }
725
-
726
- // Override the default method by using the given one
727
- if (this.settings.onResized && typeof this.settings.onResized === "function") {
728
- this.onResized = this.settings.onResized;
729
- }
730
-
731
- // Override the default method by using the given one
732
- if (this.settings.onResize && typeof this.settings.onResize === "function") {
733
- this.onResize = this.settings.onResize;
734
- }
735
-
736
- },
737
-
738
- /**
739
- * Subscribe to Aloha events and DragAndDropPlugin Event
740
- */
741
- subscribeEvents: function() {
742
- var that = this;
743
- var config = this.settings;
744
-
745
- jQuery('img').filter(config.globalselector).unbind();
746
- jQuery('img').filter(config.globalselector).click(function(event) {
747
- that.clickImage(event);
748
- });
749
-
750
- Aloha.bind('aloha-drop-files-in-editable', function(event, data) {
751
- var img, len = data.filesObjs.length, fileObj, config;
752
-
753
- while (--len >= 0) {
754
- fileObj = data.filesObjs[len];
755
- if (fileObj.file.type.match(/image\//)) {
756
- config = that.getEditableConfig(data.editable);
757
- // Prepare
758
- img = jQuery('<img/>');
759
- img.css({
760
- "max-width": that.maxWidth,
761
- "max-height": that.maxHeight
762
- });
763
- img.attr('id',fileObj.id);
764
- if (typeof fileObj.src === 'undefined') {
765
- img.attr('src', fileObj.data );
766
- //fileObj.src = fileObj.data ;
767
- } else {
768
- img.attr('src',fileObj.src );
769
- }
770
- GENTICS.Utils.Dom.insertIntoDOM(img, data.range, jQuery(Aloha.activeEditable.obj));
771
- }
772
- }
773
-
774
- });
775
-
776
- /*
777
- * Add the event handler for selection change
778
- */
779
- Aloha.bind('aloha-selection-changed', function(event, rangeObject, originalEvent) {
780
- var config, foundMarkup;
781
- if (originalEvent && originalEvent.target) {
782
- // Check if the element is currently beeing resized
783
- if (that.settings.ui.resizable && !jQuery(originalEvent.target).hasClass('ui-resizable-handle')) {
784
- that.endResize();
785
- }
786
- }
787
-
788
- if (Aloha.activeEditable !== null) {
789
- foundMarkup = that.findImgMarkup( rangeObject );
790
- //var config = that.getEditableConfig(Aloha.activeEditable.obj);
791
- config = that.getEditableConfig(Aloha.activeEditable.obj);
792
-
793
- if (typeof config !== 'undefined' ) {
794
- that.insertImgButton.show();
795
- } else {
796
- that.insertImgButton.hide();
797
- return;
798
- }
799
-
800
- // Enable image specific ui components if the element is an image
801
- if (foundMarkup) {
802
- that.insertImgButton.hide();
803
- FloatingMenu.setScope(that.name);
804
- if (that.settings.ui.meta) {
805
- that.imgSrcField.setTargetObject(foundMarkup, 'src');
806
- that.imgTitleField.setTargetObject(foundMarkup, 'title');
807
- }
808
- that.imgSrcField.focus();
809
- FloatingMenu.activateTabOfButton('imgsrc');
810
- } else {
811
- if (that.settings.ui.meta) {
812
- that.imgSrcField.setTargetObject(null);
813
- }
814
- }
815
- // TODO this should not be necessary here!
816
- FloatingMenu.doLayout();
817
- }
818
-
819
- });
820
-
821
- Aloha.bind('aloha-editable-created', function( event, editable) {
822
-
823
- try {
824
- // this will disable mozillas image resizing facilities
825
- document.execCommand( 'enableObjectResizing', false, false);
826
- } catch (e) {
827
- Aloha.Log.error( e, 'Could not disable enableObjectResizing');
828
- // this is just for others, who will not support disabling enableObjectResizing
829
- }
830
-
831
- // Inital click on images will be handled here
832
- // editable.obj.find('img').attr('_moz_resizing', false);
833
- // editable.obj.find('img').contentEditable(false);
834
- editable.obj.delegate( 'img', 'mouseup', function (event) {
835
- that.clickImage(event);
836
- event.stopPropagation();
837
- });
838
- });
839
-
840
- that._subscribeToResizeFieldEvents();
841
-
842
- },
843
-
844
- /**
845
- * Automatically resize the image to fit into defined bounds.
846
- */
847
- autoResize: function() {
848
- var that = this;
849
-
850
- var width = that.imageObj.width();
851
- var height = that.imageObj.height();
852
-
853
- // Only normalize the field values when the image exeeds the definded bounds
854
- if (width < that.settings.minWidth || width > that.settings.maxWidth || height < that.settings.minHeight || height > that.settings.maxHeight) {
855
- that._setNormalizedFieldValues('width');
856
- that.setSizeByFieldValue();
857
- return true;
858
- } else {
859
- return false;
860
- }
861
- },
862
-
863
- /**
864
- * Toggle the keep aspect ratio functionallity
865
- */
866
- toggleKeepAspectRatio: function() {
867
-
868
- this.keepAspectRatio = !this.keepAspectRatio;
869
-
870
- this.endResize();
871
- if (!this.keepAspectRatio) {
872
- this.startAspectRatio = false;
873
- } else {
874
- // If no fixed aspect ratio was given we will calculate a new start
875
- // aspect ratio that will be used for the next starResize action.
876
- if ( typeof this.settings.fixedAspectRatio !== 'number' ) {
877
- var currentRatio = this.imageObj.width() / this.imageObj.height();
878
- this.startAspectRatio = currentRatio;
879
- } else {
880
- this.startAspectRatio = this.settings.fixedAspectRatio;
881
- }
882
- }
883
- this.startResize();
884
- },
885
-
886
- /**
887
- * Bind interaction events that are invoked on the resize fields
888
- */
889
- _subscribeToResizeFieldEvents: function() {
890
- var that = this;
891
-
892
- /**
893
- * Helper function that will update the fields
894
- */
895
- function updateField( $field, delta, maxValue, minValue ) {
896
-
897
- if ( typeof minValue === 'undefined' ) {
898
- minValue = 0;
899
- }
900
-
901
- if ( typeof maxValue === 'undefined' ) {
902
- maxValue = 8000;
903
- }
904
-
905
- // If the current value of the field can't be parsed we don't update it
906
- var oldValue = parseInt( $field.val() );
907
- if ( isNaN(oldValue) ) {
908
- $field.css( 'background-color', 'red' );
909
- return false;
910
- }
911
-
912
- var newValue = oldValue + delta;
913
- // Exit if the newValue is above the maxValue limit (only if the user tries to increment)
914
- if (delta>=0 && newValue > maxValue) {
915
-
916
- // Auto correct out of bounds values
917
- if (that.settings.autoCorrectManualInput) {
918
- $field.val(maxValue);
919
- return true;
920
- } else {
921
- $field.css('background-color','red');
922
- return false;
923
- }
924
- // Exit if the newValue is below the minValue (only if the user tries to decrement)
925
- } else if (delta<=0 && newValue<minValue) {
926
-
927
- // Auto correct out of bounds values
928
- if (that.settings.autoCorrectManualInput) {
929
- $field.val(minValue);
930
- return true;
931
- } else {
932
- $field.css('background-color','red');
933
- return false;
934
- }
935
- } else {
936
- $field.css('background-color','');
937
- }
938
- $field.val(oldValue + delta);
939
- return true;
940
- };
941
-
942
- /**
943
- * Handle the keyup event on the field
944
- */
945
- function handleKeyUpEventOnField(e) {
946
-
947
- // Load the max/min from the data properties of this event
948
- var minValue = e.data.minValue;
949
- var maxValue = e.data.maxValue;
950
- var fieldName = e.data.fieldName;
951
-
952
- // Allow backspace and delete
953
- if (e.keyCode == 8 || e.keyCode == 46) {
954
- if($(this).val() >= minValue) {
955
-
956
- // Check if we are currently in cropping mode
957
- if(typeof that.jcAPI !== 'undefined' && that.jcAPI != null) {
958
- that.setCropAreaByFieldValue();
959
- } else {
960
- // 1. Normalize the size
961
- that._setNormalizedFieldValues(fieldName);
962
- // 2. Set the final size to the image
963
- that.setSizeByFieldValue();
964
- }
965
- }
966
- // 0-9 keys
967
- } else if (e.keyCode <= 57 && e.keyCode >= 48 || e.keyCode <= 105 && e.keyCode >= 96 ) {
968
- if($(this).val() >= minValue) {
969
-
970
- // Check if we are currently in cropping mode
971
- if(typeof that.jcAPI !== 'undefined' && that.jcAPI != null) {
972
- that.setCropAreaByFieldValue();
973
- } else {
974
- // 1. Normalize the size
975
- that._setNormalizedFieldValues(fieldName);
976
- // 2. Set the final size to the image
977
- that.setSizeByFieldValue();
978
- }
979
- }
980
- } else {
981
- var delta = 0;
982
- if (e.keyCode == 38 || e.keyCode == 107) {
983
- delta = +1;
984
- } else if (e.keyCode == 40 || e.keyCode == 109) {
985
- delta = -1;
986
- }
987
- // Handle key combinations
988
- if ( e.shiftKey || e.metaKey || e.ctrlKey ) {
989
- delta = delta * 10;
990
- }
991
-
992
- // Only resize when field values are ok
993
- if(updateField($(this), delta, maxValue, minValue)) {
994
- // Check if we are currently in cropping mode
995
- if(typeof that.jcAPI !== 'undefined' && that.jcAPI != null) {
996
- that.setCropAreaByFieldValue();
997
- } else {
998
- // 1. Normalize the size
999
- that._setNormalizedFieldValues(fieldName);
1000
- // 2. Set the final size to the image
1001
- that.setSizeByFieldValue();
1002
- }
1003
- }
1004
- }
1005
-
1006
- e.preventDefault();
1007
- return false;
1008
- };
1009
-
1010
- /**
1011
- * Handle the mouse wheel event on the field
1012
- */
1013
- function handleMouseWheelEventOnField(e, delta) {
1014
- var minValue = e.data.minValue;
1015
- var maxValue = e.data.maxValue;
1016
- var fieldName = e.data.fieldName;
1017
-
1018
- // Handle key combinations
1019
- if ( e.shiftKey || e.metaKey || e.ctrlKey ) {
1020
- delta = delta * 10;
1021
- }
1022
-
1023
- // Only resize when field values are ok
1024
- if(updateField($(this), delta, maxValue, minValue)) {
1025
-
1026
- // Check if we are currently in cropping mode
1027
- if(typeof that.jcAPI !== 'undefined' && that.jcAPI != null) {
1028
- that.setCropAreaByFieldValue();
1029
- } else {
1030
- // 1. Normalize the size
1031
- that._setNormalizedFieldValues(fieldName);
1032
- // 2. Set the final size to the image
1033
- that.setSizeByFieldValue();
1034
- }
1035
- }
1036
- return false;
1037
- };
1038
-
1039
- /**
1040
- * Handle mousewheel,keyup actions on both fields
1041
- */
1042
- var $heightField = $('#' + that.imgResizeHeightField.id );
1043
- var heightEventData = {fieldName: 'height', maxValue: that.imgResizeHeightField.maxValue, minValue: that.imgResizeHeightField.minValue };
1044
- $heightField.live('keyup', heightEventData, handleKeyUpEventOnField);
1045
- $heightField.live('mousewheel', heightEventData, handleMouseWheelEventOnField);
1046
-
1047
- var $widthField = $('#' + that.imgResizeWidthField.id );
1048
- var widthEventData = {fieldName: 'width', maxValue: that.imgResizeWidthField.maxValue , minValue: that.imgResizeWidthField.minValue };
1049
- $widthField.live('keyup',widthEventData , handleKeyUpEventOnField);
1050
- $widthField.live('mousewheel', widthEventData, handleMouseWheelEventOnField);
1051
-
1052
- },
1053
-
1054
-
1055
- /**
1056
- * This helper function will keep the aspect ratio for the field with the given name.
1057
- */
1058
- _setNormalizedFieldValues: function(primaryFieldName) {
1059
-
1060
- var that = this;
1061
- var widthField = jQuery("#" + that.imgResizeWidthField.id);
1062
- var heightField = jQuery("#" + that.imgResizeHeightField.id);
1063
- var width = widthField.val();
1064
- var height = heightField.val();
1065
-
1066
- var size = that._normalizeSize(width, height, primaryFieldName);
1067
-
1068
- widthField.val(size.width);
1069
- heightField.val(size.height);
1070
-
1071
- },
1072
-
1073
- /**
1074
- * Manually set the given size for the current image
1075
- */
1076
- setSize: function(width, height) {
1077
-
1078
- var that = this;
1079
- this.imageObj.width(width);
1080
- this.imageObj.height(height);
1081
- var $wrapper = this.imageObj.closest('.Aloha_Image_Resize');
1082
- $wrapper.height(height);
1083
- $wrapper.width(width);
1084
-
1085
- this._onResize(this.imageObj);
1086
- this._onResized(this.imageObj);
1087
- },
1088
-
1089
- /**
1090
- * This method will handle the mouseUp event on images (eg. within editables).
1091
- * It will if enabled activate the resizing action.
1092
- */
1093
- clickImage: function( e ) {
1094
-
1095
- var that = this;
1096
- that.imageObj = jQuery(e.target);
1097
- var currentImage = that.imageObj;
1098
-
1099
- FloatingMenu.setScope(that.name);
1100
-
1101
- var editable = currentImage.closest('.aloha-editable');
1102
-
1103
- // Disabling the content editable. This will disable the resizeHandles in internet explorer
1104
- jQuery(editable).contentEditable(false);
1105
-
1106
- //Store the current props of the image
1107
- this.restoreProps.push({
1108
- obj : e.srcElement,
1109
- src : that.imageObj.attr('src'),
1110
- width : that.imageObj.width(),
1111
- height : that.imageObj.height()
1112
- });
1113
-
1114
- // Update the resize input fields with the new width and height
1115
- $('#' + that.imgResizeHeightField.id).val(that.imageObj.height());
1116
- $('#' + that.imgResizeWidthField.id).val(that.imageObj.width());
1117
-
1118
-
1119
- if (this.settings.ui.resizable) {
1120
- this.startResize();
1121
- }
1122
-
1123
-
1124
- if (this.settings.autoResize) {
1125
- this.autoResize();
1126
- }
1127
-
1128
- },
1129
-
1130
- /**
1131
- * This method extracts determins if the range selection contains an image
1132
- */
1133
- findImgMarkup: function ( range ) {
1134
-
1135
- var that = this;
1136
- var config = this.config;
1137
- var result, targetObj;
1138
-
1139
- if ( typeof range === 'undefined' ) {
1140
- range = Aloha.Selection.getRangeObject();
1141
- }
1142
-
1143
- targetObj = jQuery(range.startContainer);
1144
-
1145
- try {
1146
- if ( Aloha.activeEditable ) {
1147
- if (( typeof range.startContainer !== 'undefined'
1148
- && typeof range.startContainer.childNodes !== 'undefined'
1149
- && typeof range.startOffset !== 'undefined'
1150
- && typeof range.startContainer.childNodes[range.startOffset] !== 'undefined'
1151
- && range.startContainer.childNodes[range.startOffset].nodeName.toLowerCase() === 'img'
1152
- && range.startOffset+1 === range.endOffset) ||
1153
- (targetObj.hasClass('Aloha_Image_Resize')))
1154
- {
1155
- result = targetObj.find('img')[0];
1156
- if (! result.css) {
1157
- result.css = '';
1158
- }
1159
-
1160
- if (! result.title) {
1161
- result.title = '';
1162
- }
1163
-
1164
- if (! result.src) {
1165
- result.src = '';
1166
- }
1167
- return result;
1168
- }
1169
- else {
1170
- return null;
1171
- }
1172
- }
1173
- } catch (e) {
1174
- Aloha.Log.debug(e, "Error finding img markup.");
1175
- }
1176
- return null;
1177
-
1178
- },
1179
-
1180
-
1181
- /**
1182
- * This helper function will calculate the new width and height while keeping
1183
- * the aspect ratio when the keepAspectRatio flat is set to true. The primarySize
1184
- * can be 'width' or 'height'. The function will first try to normalize the oposite size.
1185
- */
1186
- _normalizeSize: function(width, height, primarySize) {
1187
-
1188
- var that = this;
1189
- // Convert string values to numbers
1190
- width = parseInt(width);
1191
- height = parseInt(height);
1192
-
1193
- /**
1194
- * Inner function that calculates the new height by examining the width
1195
- */
1196
- function handleHeight(callHandleWidth) {
1197
-
1198
- // Check whether the value is within bounds
1199
- if (height > that.settings.maxHeight) {
1200
-
1201
- // Throw a notification event
1202
- var eventProps = { 'org': height, 'new': that.settings.maxHeight};
1203
- $('body').trigger('aloha-image-resize-outofbounds', ["height", "max", eventProps]);
1204
- height = that.settings.maxHeight;
1205
-
1206
- } else if (height < that.settings.minHeight) {
1207
-
1208
- // Throw a notification event
1209
- var eventProps = { 'org': height, 'new': that.settings.minHeight};
1210
- $('body').trigger('aloha-image-resize-outofbounds', ["height", "min", eventProps]);
1211
- height = that.settings.minHeight;
1212
- }
1213
-
1214
- if (that.keepAspectRatio) {
1215
- width = height * aspectRatio;
1216
-
1217
- // We don't want to invoke handleWidth again. This would mess up our previously calculated width
1218
- if (callHandleWidth) {
1219
- handleWidth(false);
1220
- }
1221
- }
1222
-
1223
-
1224
- }
1225
-
1226
- /**
1227
- * Inner function that calculates the new width by examining the width
1228
- */
1229
- function handleWidth(callHandleHeight) {
1230
-
1231
- // Check whether the value is within bounds
1232
- if (width > that.settings.maxWidth) {
1233
-
1234
- // Throw a notification event
1235
- var eventProps = { 'org': width, 'new': that.settings.maxWidth};
1236
- $('body').trigger('aloha-image-resize-outofbounds', ["width", "max", eventProps]);
1237
-
1238
- width = that.settings.maxWidth;
1239
- } else if (width < that.settings.minWidth) {
1240
-
1241
- // Throw a notification event
1242
- var eventProps = { 'org': width, 'new': that.settings.minWidth};
1243
- $('body').trigger('aloha-image-resize-outofbounds', ["width", "min", eventProps]);
1244
-
1245
- width = that.settings.minWidth;
1246
- }
1247
-
1248
- // Calculate the new height
1249
- if (that.keepAspectRatio) {
1250
- height = width / aspectRatio;
1251
-
1252
- // We don't want to invoke handleHeight again. This would mess up our previously calculated height
1253
- if (callHandleHeight) {
1254
- handleHeight(false);
1255
- }
1256
-
1257
- }
1258
-
1259
- }
1260
-
1261
- // Load the aspect ratio and use the 4:3 ratio as default value.
1262
- var aspectRatio = 1.33333;
1263
- if (typeof that.startAspectRatio === 'number') {
1264
- aspectRatio = that.startAspectRatio;
1265
- }
1266
-
1267
- // Determin which size should be handled
1268
- if (primarySize == 'width') {
1269
- handleWidth(true);
1270
- }
1271
-
1272
- if (primarySize == 'height') {
1273
- handleHeight(true);
1274
- }
1275
-
1276
- // Floor the values return them
1277
- return {'width': Math.floor(width), 'height': Math.floor(height)};
1278
- },
1279
-
1280
-
1281
- /**
1282
- * Helper function that will set the new image size using the field values
1283
- */
1284
- setSizeByFieldValue: function() {
1285
- var that = this;
1286
- var width = $('#' + that.imgResizeWidthField.id ).val();
1287
- var height = $('#' + that.imgResizeHeightField.id ).val();
1288
- that.setSize(width, height);
1289
- },
1290
-
1291
- /**
1292
- * Helper function that will set the new crop area width and height using the field values
1293
- */
1294
- setCropAreaByFieldValue: function() {
1295
- var that = this;
1296
- var currentCropArea = that.jcAPI.tellSelect();
1297
-
1298
- var width = $('#' + that.imgResizeWidthField.id ).val();
1299
- width = parseInt(width);
1300
- var height = $('#' + that.imgResizeHeightField.id ).val();
1301
- height = parseInt(height);
1302
-
1303
- var selection = [currentCropArea['x'], currentCropArea['y'], currentCropArea['x'] + width,currentCropArea['y'] + height];
1304
- that.jcAPI.setSelect(selection);
1305
- },
1306
-
1307
- /**
1308
- * This method will insert a new image dom element into the dom tree
1309
- */
1310
- insertImg: function() {
1311
- var range = Aloha.Selection.getRangeObject(),
1312
- config = this.getEditableConfig(Aloha.activeEditable.obj),
1313
- imagePluginUrl = Aloha.getPluginUrl('image'),
1314
- imagestyle, imagetag, newImg;
1315
-
1316
- if ( range.isCollapsed() ) {
1317
- // TODO I would suggest to call the srcChange method. So all image src
1318
- // changes are on one single point.
1319
- imagestyle = "max-width: " + config.maxWidth + "; max-height: " + config.maxHeight;
1320
- imagetag = '<img style="'+ imagestyle + '" src="' + imagePluginUrl + '/img/blank.jpg" title="" />';
1321
- newImg = jQuery(imagetag);
1322
- // add the click selection handler
1323
- //newImg.click( Aloha.Image.clickImage ); - Using delegate now
1324
- GENTICS.Utils.Dom.insertIntoDOM(newImg, range, jQuery(Aloha.activeEditable.obj));
1325
-
1326
- } else {
1327
- Aloha.Log.error('img cannot markup a selection');
1328
- // TODO the desired behavior could be me the selected content is
1329
- // replaced by an image.
1330
- // TODO it should be editor's choice, with an NON-Ext Dialog instead of alert
1331
-
1332
- }
1333
- },
1334
-
1335
- srcChange: function () {
1336
- // TODO the src changed. I suggest :
1337
- // 1. set an loading image (I suggest set src base64 enc) to show the user
1338
- // we are trying to load an image
1339
- // 2. start a request to get the image
1340
- // 3a. the image is ok change the src
1341
- // 3b. the image is not availbable show an error.
1342
- this.imageObj.attr('src', this.imgSrcField.getQueryValue() ); // (the img tag)
1343
- // jQuery(img).attr('src', this.imgSrcField.getQueryValue() ); // (the query value in the inputfield)
1344
- // this.imgSrcField.getItem(); // (optinal a selected resource item)
1345
- // TODO additionally implement an srcChange Handler to let implementer
1346
- // customize
1347
- },
1348
-
1349
- /**
1350
- * Code imported from CropnResize Plugin
1351
- *
1352
- */
1353
- initCropButtons: function() {
1354
- var that = this,
1355
- btns,
1356
- oldLeft = 0,
1357
- oldTop = 0;
1358
-
1359
- jQuery('body').append(
1360
- '<div id="aloha-CropNResize-btns">\
1361
- <button class="cnr-crop-apply" title="' + i18n.t('Accept') + '">&#10004;</button>\
1362
- <button class="cnr-crop-cancel" title="' + i18n.t('Cancel') + '">&#10006;</button>\
1363
- </div>'
1364
- );
1365
-
1366
- btns = jQuery('#aloha-CropNResize-btns')
1367
-
1368
- btns.find('.cnr-crop-apply').click(function () {
1369
- that.acceptCrop();
1370
- });
1371
-
1372
- btns.find('.cnr-crop-cancel').click(function () {
1373
- that.endCrop();
1374
- });
1375
-
1376
- this.interval = setInterval(function () {
1377
- var jt = jQuery('.jcrop-tracker:first'),
1378
- off = jt.offset(),
1379
- jtt = off.top,
1380
- jtl = off.left,
1381
- jth = jt.height(),
1382
- jtw = jt.width();
1383
-
1384
- if (jth && jtw) {
1385
- btns.fadeIn('slow');
1386
- }
1387
-
1388
- // move the icons to the bottom right side
1389
- jtt = parseInt(jtt + jth + 3, 10);
1390
- jtl = parseInt(jtl + jtw - 55, 10);
1391
-
1392
- // comparison to old values hinders flickering bug in FF
1393
- if (oldLeft != jtl || oldTop != jtt) {
1394
- btns.offset({top: jtt, left: jtl});
1395
- }
1396
-
1397
- oldLeft = jtl;
1398
- oldTop = jtt;
1399
- }, 10);
1400
- },
1401
-
1402
- /**
1403
- * Destroy crop confirm and cancel buttons
1404
- */
1405
- destroyCropButtons: function () {
1406
- jQuery('#aloha-CropNResize-btns').remove();
1407
- clearInterval(this.interval);
1408
- },
1409
-
1410
- /**
1411
- * Helper function that will disable selectability of elements
1412
- */
1413
- _disableSelection: function (el) {
1414
- el.find('*').attr('unselectable', 'on')
1415
- .css({
1416
- '-moz-user-select':'none',
1417
- '-webkit-user-select':'none',
1418
- 'user-select':'none'
1419
- });
1420
- /*
1421
- .each(function() {
1422
- this.onselectstart = function () { return false; };
1423
- });
1424
- */
1425
-
1426
- },
1427
-
1428
- /**
1429
- * Initiate a crop action
1430
- */
1431
- crop: function () {
1432
- var that = this;
1433
- var config = this.config;
1434
-
1435
- this.initCropButtons();
1436
- if (this.settings.ui.resizable) {
1437
- this.endResize();
1438
- }
1439
-
1440
- this.jcAPI = jQuery.Jcrop(this.imageObj, {
1441
- onSelect : function () {
1442
- that._onCropSelect();
1443
- // ugly hack to keep scope :(
1444
- setTimeout(function () {
1445
- FloatingMenu.setScope(that.name);
1446
- }, 10);
1447
- }
1448
- });
1449
-
1450
- that._disableSelection($('.jcrop-holder'));
1451
- that._disableSelection($('#imageContainer'));
1452
- that._disableSelection($('#aloha-CropNResize-btns'));
1453
- $('body').trigger('aloha-image-crop-start', [this.imageObj]);
1454
- },
1455
-
1456
- /**
1457
- * Internal on crop select method
1458
- */
1459
- _onCropSelect: function() {
1460
- var that = this;
1461
-
1462
- // Update the width and height field using the intiial active crop area values
1463
- if(typeof that.jcAPI !== 'undefined' && that.jcAPI != null) {
1464
- var currentCropArea = that.jcAPI.tellSelect();
1465
- var widthField = jQuery("#" + that.imgResizeWidthField.id).val(currentCropArea['w']);
1466
- var heightField = jQuery("#" + that.imgResizeHeightField.id).val(currentCropArea['h']);
1467
- }
1468
-
1469
- },
1470
-
1471
-
1472
- /**
1473
- * Terminates a crop
1474
- */
1475
- endCrop: function () {
1476
- if ( this.jcAPI ) {
1477
- this.jcAPI.destroy();
1478
- this.jcAPI = null;
1479
- }
1480
-
1481
- this.destroyCropButtons();
1482
- this.cropButton.extButton.toggle(false);
1483
-
1484
- if ( this.settings.ui.resizable ) {
1485
- this.startResize();
1486
- }
1487
-
1488
- if ( this.keepAspectRatio ) {
1489
- var currentRatio = this.imageObj.width() / this.imageObj.height();
1490
- this.startAspectRatio = currentRatio;
1491
- }
1492
-
1493
- $('body').trigger('aloha-image-crop-stop', [this.imageObj]);
1494
- },
1495
-
1496
- /**
1497
- * Accept the current cropping area and apply the crop
1498
- */
1499
- acceptCrop: function () {
1500
- this._onCropped ( this.imageObj, this.jcAPI.tellSelect() );
1501
- this.endCrop ();
1502
- },
1503
-
1504
- /**
1505
- * This method will activate the jquery-ui resize functionality for the current image
1506
- */
1507
- startResize: function () {
1508
- var that = this;
1509
- var currentImageObj = this.imageObj;
1510
-
1511
- currentImageObj = this.imageObj.css({
1512
- height : this.imageObj.height(),
1513
- width : this.imageObj.width(),
1514
- position : 'relative',
1515
- 'max-height': '',
1516
- 'max-width' : ''
1517
- });
1518
-
1519
- currentImageObj.resizable({
1520
-
1521
- maxHeight : that.settings.maxHeight,
1522
- minHeight : that.settings.minHeight,
1523
- maxWidth : that.settings.maxWidth,
1524
- minWidth : that.settings.minWidth,
1525
- aspectRatio : that.startAspectRatio,
1526
- handles: that.settings.handles,
1527
- grid : that.settings.grid,
1528
- resize: function(event, ui) {
1529
- that._onResize(that.imageObj);
1530
- },
1531
- stop : function (event, ui) {
1532
- that._onResized(that.imageObj);
1533
-
1534
- // Workaround to finish cropping
1535
- if (this.enableCrop) {
1536
- setTimeout(function () {
1537
- FloatingMenu.setScope(that.name);
1538
- that.done(event);
1539
- }, 10);
1540
- }
1541
- }
1542
-
1543
- });
1544
-
1545
- currentImageObj.css('display', 'inline-block');
1546
-
1547
- // this will prevent the user from resizing an image
1548
- // using IE's resize handles
1549
- // however I could not manage to hide them completely
1550
- jQuery('.ui-wrapper')
1551
- .attr('contentEditable', false)
1552
- .addClass('aloha-image-box-active Aloha_Image_Resize aloha')
1553
- .css({
1554
- position: 'relative',
1555
- display: 'inline-block',
1556
- 'float': that.imageObj.css('float')
1557
- })
1558
- .bind('resizestart', function (e) {
1559
- e.preventDefault();
1560
- })
1561
- .bind('mouseup', function (e) {
1562
- e.originalEvent.stopSelectionUpdate = true;
1563
- });
1564
- },
1565
-
1566
- /**
1567
- * This method will end resizing and toggle buttons accordingly and remove all markup that has been added for cropping
1568
- */
1569
- endResize: function () {
1570
- // Find the nearest contenteditable and reenable it since resizing is finished
1571
- if (this.imageObj) {
1572
- var editable = this.imageObj.closest('.aloha-editable');
1573
- jQuery(editable).contentEditable(true);
1574
- }
1575
-
1576
- if (this.imageObj) {
1577
- this.imageObj
1578
- .resizable('destroy')
1579
- .css({
1580
- top : 0,
1581
- left : 0
1582
- });
1583
- }
1584
- },
1585
-
1586
- /**
1587
- * Reset the image to it's original properties
1588
- */
1589
- reset: function() {
1590
- if (this.settings.ui.crop) {
1591
- this.endCrop();
1592
- }
1593
-
1594
- if (this.settings.ui.resizable) {
1595
- this.endResize();
1596
- }
1597
-
1598
- if (this._onReset(this.imageObj)) {
1599
- // the external reset procedure has already performed a reset, so there is no need to apply an internal reset
1600
- return;
1601
- }
1602
-
1603
- for (var i=0;i<this.restoreProps.length;i++) {
1604
- // restore from restoreProps if there is a match
1605
- if (this.imageObj.get(0) === this.restoreProps[i].obj) {
1606
- this.imageObj.attr('src', this.restoreProps[i].src);
1607
- this.imageObj.width(this.restoreProps[i].width);
1608
- this.imageObj.height(this.restoreProps[i].height);
1609
- return;
1610
- }
1611
- }
1612
- }
1613
- });
35
+
36
+
37
+
38
+ var jQuery = aQuery;
39
+ var $ = aQuery;
40
+ var GENTICS = window.GENTICS;
41
+ var Aloha = window.Aloha;
42
+
43
+ // Attributes manipulation utilities
44
+ // Aloha team may want to factorize, it could be useful for other plugins
45
+ // Prototypes
46
+ String.prototype.toInteger = String.prototype.toInteger || function() {
47
+ return parseInt(String(this).replace(/px$/,'')||0,10);
48
+ };
49
+ String.prototype.toFloat = String.prototype.toInteger || function() {
50
+ return parseFloat(String(this).replace(/px$/,'')||0,10);
51
+ };
52
+ Number.prototype.toInteger = Number.prototype.toInteger || String.prototype.toInteger;
53
+ Number.prototype.toFloat = Number.prototype.toFloat || String.prototype.toFloat;
54
+
55
+ // Insert jQuery Prototypes
56
+ jQuery.extend(true, jQuery.fn, {
57
+ increase: jQuery.fn.increase || function(attr) {
58
+ var obj = jQuery(this), value, newValue;
59
+ // Check
60
+ if ( !obj.length ) {
61
+ return obj;
62
+ }
63
+ // Calculate
64
+ value = obj.css(attr).toFloat();
65
+ newValue = Math.round((value||1)*1.2);
66
+ // Apply
67
+ if (value == newValue) { // when value is 2, won't increase
68
+ newValue++;
69
+ }
70
+ // Apply
71
+ obj.css(attr,newValue);
72
+ // Chain
73
+ return obj;
74
+ },
75
+ decrease: jQuery.fn.decrease || function(attr) {
76
+ var obj = jQuery(this), value, newValue;
77
+ // Check
78
+ if ( !obj.length ) {
79
+ return obj;
80
+ }
81
+ // Calculate
82
+ value = obj.css(attr).toFloat();
83
+ newValue = Math.round((value||0)*0.8);
84
+ // Apply
85
+ if (value == newValue && newValue >0) { // when value is 2, won't increase
86
+ newValue--;
87
+ }
88
+ obj.css(attr,newValue);
89
+ // Chain
90
+ return obj;
91
+ }
92
+ });
93
+
94
+ // Create and register Image Plugin
95
+ return Plugin.create('image', {
96
+
97
+ languages: ['en', 'fr', 'de', 'ru', 'cz'],
98
+
99
+ defaultSettings: {
100
+ 'maxWidth': 1600,
101
+ 'minWidth': 3,
102
+ 'maxHeight': 1200,
103
+ 'minHeight': 3,
104
+ // This setting will correct manually values that are out of bounds
105
+ 'autoCorrectManualInput': true,
106
+ // This setting will define a fixed aspect ratio for all resize actions
107
+ 'fixedAspectRatio' : false,
108
+ // When enabled this setting will order the plugin to automatically resize images to given bounds
109
+ 'autoResize': false,
110
+ //Image manipulation options - ONLY in default config section
111
+ ui: {
112
+ oneTab : false, //Place all ui components within one tab
113
+ insert : true,
114
+ reset : true,
115
+ aspectRatioToggle: true, // Toggle button for the aspect ratio
116
+ align : true, // Menu elements to show/hide in menu
117
+ resize : true, // Resize buttons
118
+ meta : true,
119
+ margin : true,
120
+ crop : true,
121
+ resizable : true, // Resizable ui-drag image
122
+ handles : 'ne, se, sw, nw'
123
+ },
124
+
125
+ /**
126
+ * Crop callback is triggered after the user clicked accept to accept his crop
127
+ * @param image jquery image object reference
128
+ * @param props cropping properties
129
+ */
130
+ onCropped: function ($image, props) {
131
+ Aloha.Log.info('Default onCropped invoked', $image, props);
132
+ },
133
+
134
+ /**
135
+ * Reset callback is triggered before the internal reset procedure is applied
136
+ * if this function returns true, then the reset has been handled by the callback
137
+ * which means that no other reset will be applied
138
+ * if false is returned the internal reset procedure will be applied
139
+ * @param image jquery image object reference
140
+ * @return true if a reset has been applied, false otherwise
141
+ */
142
+ onReset: function ($image) {
143
+ Aloha.Log.info('Default onReset invoked', $image);
144
+ return false;
145
+ },
146
+
147
+ /**
148
+ * Example callback method which gets called while the resize process is beeing executed.
149
+ */
150
+ onResize: function ($image) {
151
+ Aloha.Log.info('Default onResize invoked', $image);
152
+ },
153
+
154
+ /**
155
+ * Resize callback is triggered after the internal resize procedure is applied.
156
+ */
157
+ onResized: function ($image) {
158
+ Aloha.Log.info('Default onResized invoked', $image);
159
+ }
160
+ },
161
+
162
+ /**
163
+ * Internal callback hook which gets invoked when cropping has been finished
164
+ */
165
+ _onCropped: function ($image, props) {
166
+ $('#' + this.imgResizeHeightField.id).val($image.height());
167
+ $('#' + this.imgResizeWidthField.id).val($image.width());
168
+
169
+
170
+ $('body').trigger('aloha-image-cropped', [$image, props]);
171
+
172
+ // Call the custom onCropped function
173
+ this.onCropped($image, props);
174
+ },
175
+
176
+ /**
177
+ * Internal callback hook which gets invoked when resetting images
178
+ */
179
+ _onReset: function ($image) {
180
+
181
+ $('#' + this.imgResizeHeightField.id).val($image.height());
182
+ $('#' + this.imgResizeWidthField.id).val($image.width());
183
+
184
+ // No default behaviour defined besides event triggering
185
+ $('body').trigger('aloha-image-reset', $image);
186
+
187
+ // Call the custom resize function
188
+ return this.onReset($image);
189
+ },
190
+
191
+ /**
192
+ * Internal callback hook which gets invoked while the image is beeing resized
193
+ */
194
+ _onResize: function ($image) {
195
+
196
+ $('#' + this.imgResizeHeightField.id).val($image.height());
197
+ $('#' + this.imgResizeWidthField.id).val($image.width());
198
+
199
+ // No default behaviour defined besides event triggering
200
+ $('body').trigger('aloha-image-resize', $image);
201
+
202
+ // Call the custom resize function
203
+ this.onResize($image);
204
+ },
205
+
206
+ /**
207
+ * Internal callback hook which gets invoked when the current resizing action has stopped
208
+ */
209
+ _onResized: function ($image) {
210
+
211
+ $('#' + this.imgResizeHeightField.id).val($image.height());
212
+ $('#' + this.imgResizeWidthField.id).val($image.width());
213
+
214
+ $('body').trigger('aloha-image-resized', $image);
215
+
216
+ // Call the custom resize function
217
+ this.onResized($image);
218
+ },
219
+
220
+ /**
221
+ * The image that is currently edited
222
+ */
223
+ imageObj: null,
224
+
225
+ /**
226
+ * The Jcrop API reference
227
+ * this is needed to be able to destroy the cropping frame later on
228
+ * the variable is linked to the api object whilst cropping, or set to null otherwise
229
+ * strange, but done as documented http://deepliquid.com/content/Jcrop_API.html
230
+ */
231
+ jcAPI: null,
232
+
233
+
234
+ /**
235
+ * State variable for the aspect ratio toggle feature
236
+ */
237
+ keepAspectRatio: false,
238
+
239
+ /**
240
+ * Variable that will hold the start aspect ratio. This ratio will be used once starResize will be called.
241
+ */
242
+ startAspectRatio: false,
243
+
244
+ /**
245
+ * This will contain an image's original properties to be able to undo previous settings
246
+ *
247
+ * when an image is clicked for the first time, a new object will be added to the array
248
+ * {
249
+ * obj : [the image object reference],
250
+ * src : [the original src url],
251
+ * width : [initial width],
252
+ * height : [initial height]
253
+ * }
254
+ *
255
+ * when an image is clicked the second time, the array will be checked for the image object
256
+ * referenct, to prevent for double entries
257
+ */
258
+ restoreProps: [],
259
+
260
+ objectTypeFilter: [],
261
+
262
+ /**
263
+ * Plugin initialization method
264
+ */
265
+ init: function() {
266
+
267
+ var that = this;
268
+
269
+ var imagePluginUrl = Aloha.getPluginUrl('image');
270
+
271
+ // Extend the default settings with the custom ones (done by default)
272
+ this.startAspectRatio = this.settings.fixedAspectRatio;
273
+ this.config = this.defaultSettings;
274
+ this.settings = jQuery.extend(true, this.defaultSettings, this.settings);
275
+
276
+ that.initializeButtons();
277
+ that.bindInteractions();
278
+ that.subscribeEvents();
279
+
280
+ },
281
+
282
+ /**
283
+ * Create buttons
284
+ */
285
+ initializeButtons: function() {
286
+
287
+ var that = this,
288
+ tabInsert = i18nCore.t('floatingmenu.tab.insert'),
289
+ tabImage = i18n.t('floatingmenu.tab.img'),
290
+ tabFormatting = i18n.t('floatingmenu.tab.formatting'),
291
+ tabCrop = i18n.t('floatingmenu.tab.crop'),
292
+ tabResize = i18n.t('floatingmenu.tab.resize');
293
+
294
+ FloatingMenu.createScope(this.name, 'Aloha.empty');
295
+
296
+ if (this.settings.ui.insert) {
297
+ var tabId = this.settings.ui.oneTab ? tabImage : tabInsert;
298
+ that._addUIInsertButton(tabId);
299
+ }
300
+
301
+ if (this.settings.ui.meta) {
302
+ var tabId = this.settings.ui.oneTab ? tabImage : tabImage;
303
+ that._addUIMetaButtons(tabId);
304
+ }
305
+
306
+ if (this.settings.ui.reset) {
307
+ var tabId = this.settings.ui.reset ? tabImage : tabImage;
308
+ that._addUIResetButton(tabId);
309
+ }
310
+
311
+ if (this.settings.ui.align) {
312
+ var tabId = this.settings.ui.oneTab ? tabImage : tabFormatting;
313
+ that._addUIAlignButtons(tabId);
314
+ }
315
+
316
+ if (this.settings.ui.margin) {
317
+ var tabId = this.settings.ui.oneTab ? tabImage : tabFormatting;
318
+ that._addUIMarginButtons(tabId);
319
+ }
320
+
321
+ if (this.settings.ui.crop) {
322
+ var tabId = this.settings.ui.oneTab ? tabImage : tabCrop;
323
+ that._addUICropButtons(tabId);
324
+ }
325
+
326
+ if (this.settings.ui.resize) {
327
+ var tabId = this.settings.ui.oneTab ? tabImage : tabResize;
328
+ that._addUIResizeButtons(tabId);
329
+ }
330
+
331
+ if (this.settings.ui.aspectRatioToggle) {
332
+ var tabId = this.settings.ui.oneTab ? tabImage : tabResize;
333
+ that.__addUIAspectRatioToggleButton(tabId);
334
+ }
335
+
336
+ // TODO fix the function and reenable this button
337
+ //that._addNaturalSizeButton();
338
+ },
339
+
340
+
341
+ /**
342
+ * Adds the aspect ratio toggle button to the floating menu
343
+ */
344
+ __addUIAspectRatioToggleButton: function(tabId) {
345
+ var that = this;
346
+ var toggleButton = new Aloha.ui.Button({
347
+ 'size' : 'small',
348
+ 'tooltip' : i18n.t('button.toggle.tooltip'),
349
+ 'toggle' : true,
350
+ 'iconClass' : 'cnr-ratio',
351
+ 'onclick' : function (btn, event) {
352
+ that.toggleKeepAspectRatio();
353
+ }
354
+ });
355
+
356
+
357
+ // If the setting has been set to a number or false we need to activate the
358
+ // toggle button to indicate that the aspect ratio will be preserved.
359
+ if (this.settings.fixedAspectRatio != false) {
360
+ toggleButton.pressed = true;
361
+ this.keepAspectRatio = true;
362
+ }
363
+
364
+ FloatingMenu.addButton(
365
+ that.name,
366
+ toggleButton,
367
+ tabId,
368
+ 20
369
+ );
370
+
371
+
372
+ },
373
+
374
+
375
+ /**
376
+ * Adds the reset button to the floating menu for the given tab
377
+ */
378
+ _addUIResetButton: function(tabId) {
379
+ var that = this;
380
+ // Reset button
381
+ var resetButton = new Aloha.ui.Button({
382
+ 'size' : 'small',
383
+ 'tooltip' : i18n.t('Reset'),
384
+ 'toggle' : false,
385
+ 'iconClass' : 'cnr-reset',
386
+ 'onclick' : function (btn, event) {
387
+ that.reset();
388
+ }
389
+ });
390
+
391
+ FloatingMenu.addButton(
392
+ that.name,
393
+ resetButton,
394
+ tabId,
395
+ 2
396
+ );
397
+ },
398
+
399
+ /**
400
+ * Adds the insert button to the floating menu
401
+ */
402
+ _addUIInsertButton: function(tabId) {
403
+ var that = this;
404
+ this.insertImgButton = new Aloha.ui.Button({
405
+ 'name' : 'insertimage',
406
+ 'iconClass': 'aloha-button aloha-image-insert',
407
+ 'size' : 'small',
408
+ 'onclick' : function () { that.insertImg(); },
409
+ 'tooltip' : i18n.t('button.addimg.tooltip'),
410
+ 'toggle' : false
411
+ });
412
+
413
+ FloatingMenu.addButton(
414
+ 'Aloha.continuoustext',
415
+ this.insertImgButton,
416
+ tabId,
417
+ 1
418
+ );
419
+ },
420
+
421
+ /**
422
+ * Adds the ui meta fields (search, title) to the floating menu.
423
+ */
424
+ _addUIMetaButtons: function(tabId) {
425
+ var that = this;
426
+ var imgSrcLabel = new Aloha.ui.Button({
427
+ 'label': i18n.t('field.img.src.label'),
428
+ 'tooltip': i18n.t('field.img.src.tooltip'),
429
+ 'size': 'small'
430
+ });
431
+ this.imgSrcField = new Aloha.ui.AttributeField({'name' : 'imgsrc'});
432
+ this.imgSrcField.setObjectTypeFilter( this.objectTypeFilter );
433
+
434
+ // add the title field for images
435
+ var imgTitleLabel = new Aloha.ui.Button({
436
+ 'label': i18n.t('field.img.title.label'),
437
+ 'tooltip': i18n.t('field.img.title.tooltip'),
438
+ 'size': 'small'
439
+ });
440
+
441
+ this.imgTitleField = new Aloha.ui.AttributeField();
442
+ this.imgTitleField.setObjectTypeFilter();
443
+ FloatingMenu.addButton(
444
+ this.name,
445
+ this.imgSrcField,
446
+ tabId,
447
+ 1
448
+ );
449
+
450
+ },
451
+
452
+ /**
453
+ * Adds the ui align buttons to the floating menu
454
+ */
455
+ _addUIAlignButtons: function(tabId) {
456
+ var that = this;
457
+
458
+ var alignLeftButton = new Aloha.ui.Button({
459
+ 'iconClass': 'aloha-img aloha-image-align-left',
460
+ 'size': 'small',
461
+ 'onclick' : function() {
462
+ var el = jQuery(that.findImgMarkup());
463
+ el.add(el.parent()).css('float', 'left');
464
+ },
465
+ 'tooltip': i18n.t('button.img.align.left.tooltip')
466
+ });
467
+
468
+ FloatingMenu.addButton(
469
+ that.name,
470
+ alignLeftButton,
471
+ tabId,
472
+ 1
473
+ );
474
+
475
+ var alignRightButton = new Aloha.ui.Button({
476
+ 'iconClass': 'aloha-img aloha-image-align-right',
477
+ 'size': 'small',
478
+ 'onclick' : function() {
479
+ var el = jQuery(that.findImgMarkup());
480
+ el.add(el.parent()).css('float', 'right');
481
+ },
482
+ 'tooltip': i18n.t('button.img.align.right.tooltip')
483
+ });
484
+
485
+ FloatingMenu.addButton(
486
+ that.name,
487
+ alignRightButton,
488
+ tabId,
489
+ 1
490
+ );
491
+
492
+ var alignNoneButton = new Aloha.ui.Button({
493
+ 'iconClass': 'aloha-img aloha-image-align-none',
494
+ 'size': 'small',
495
+ 'onclick' : function() {
496
+ var el = jQuery(that.findImgMarkup());
497
+ el.add(el.parent()).css({
498
+ 'float': 'none',
499
+ display: 'inline-block'
500
+ });
501
+ },
502
+ 'tooltip': i18n.t('button.img.align.none.tooltip')
503
+ });
504
+
505
+ FloatingMenu.addButton(
506
+ that.name,
507
+ alignNoneButton,
508
+ tabId,
509
+ 1
510
+ );
511
+
512
+ },
513
+
514
+ /**
515
+ * Adds the ui margin buttons to the floating menu
516
+ */
517
+ _addUIMarginButtons: function(tabId) {
518
+ var that = this;
519
+ var incPadding = new Aloha.ui.Button({
520
+ iconClass: 'aloha-img aloha-image-padding-increase',
521
+ toggle: false,
522
+ size: 'small',
523
+ onclick: function() {
524
+ jQuery(that.findImgMarkup()).increase('padding');
525
+ },
526
+ tooltip: i18n.t('padding.increase')
527
+ });
528
+ FloatingMenu.addButton(
529
+ that.name,
530
+ incPadding,
531
+ tabId,
532
+ 2
533
+ );
534
+
535
+ var decPadding = new Aloha.ui.Button({
536
+ iconClass: 'aloha-img aloha-image-padding-decrease',
537
+ toggle: false,
538
+ size: 'small',
539
+ onclick: function() {
540
+ jQuery(that.findImgMarkup()).decrease('padding');
541
+ },
542
+ tooltip: i18n.t('padding.decrease')
543
+ });
544
+ FloatingMenu.addButton(
545
+ that.name,
546
+ decPadding,
547
+ tabId,
548
+ 2
549
+ );
550
+ },
551
+
552
+ /**
553
+ * Adds the crop buttons to the floating menu
554
+ */
555
+ _addUICropButtons: function (tabId) {
556
+ var that = this;
557
+
558
+ FloatingMenu.createScope('Aloha.img', ['Aloha.global']);
559
+
560
+ this.cropButton = new Aloha.ui.Button({
561
+ 'size' : 'small',
562
+ 'tooltip' : i18n.t('Crop'),
563
+ 'toggle' : true,
564
+ 'iconClass' : 'cnr-crop',
565