Merge branch 'master' of http://git.roojs.com/roojs1
[roojs1] / Roo / htmleditor / BlockFigure.js
1  
2
3 /**
4  * @class Roo.htmleditor.BlockFigure
5  * Block that has an image and a figcaption
6  * @cfg {String} image_src the url for the image
7  * @cfg {String} align (left|right) alignment for the block default left
8  * @cfg {String} caption the text to appear below  (and in the alt tag)
9  * @cfg {String} caption_display (block|none) display or not the caption
10  * @cfg {String|number} image_width the width of the image number or %?
11  * @cfg {String|number} image_height the height of the image number or %?
12  * 
13  * @constructor
14  * Create a new Filter.
15  * @param {Object} config Configuration options
16  */
17
18 Roo.htmleditor.BlockFigure = function(cfg)
19 {
20     if (cfg.node) {
21         this.readElement(cfg.node);
22         this.updateElement(cfg.node);
23     }
24     Roo.apply(this, cfg);
25 }
26 Roo.extend(Roo.htmleditor.BlockFigure, Roo.htmleditor.Block, {
27  
28     
29     // setable values.
30     image_src: '',
31     align: 'center',
32     caption : '',
33     caption_display : 'block',
34     width : '100%',
35     cls : '',
36     href: '',
37     video_url : '',
38     
39     // margin: '2%', not used
40     
41     text_align: 'left', //   (left|right) alignment for the text caption default left. - not used at present
42
43     
44     // used by context menu
45     friendly_name : 'Image with caption',
46     deleteTitle : "Delete Image and Caption",
47     
48     contextMenu : function(toolbar)
49     {
50         
51         var block = function() {
52             return Roo.htmleditor.Block.factory(toolbar.tb.selectedNode);
53         };
54         
55         
56         var rooui =  typeof(Roo.bootstrap) == 'undefined' ? Roo : Roo.bootstrap;
57         
58         var syncValue = toolbar.editorcore.syncValue;
59         
60         var fields = {};
61         
62         return [
63              {
64                 xtype : 'TextItem',
65                 text : "Source: ",
66                 xns : rooui.Toolbar  //Boostrap?
67             },
68             {
69                 xtype : 'Button',
70                 text: 'Change Image URL',
71                  
72                 listeners : {
73                     click: function (btn, state)
74                     {
75                         var b = block();
76                         
77                         Roo.MessageBox.show({
78                             title : "Image Source URL",
79                             msg : "Enter the url for the image",
80                             buttons: Roo.MessageBox.OKCANCEL,
81                             fn: function(btn, val){
82                                 if (btn != 'ok') {
83                                     return;
84                                 }
85                                 b.image_src = val;
86                                 b.updateElement();
87                                 syncValue();
88                                 toolbar.editorcore.onEditorEvent();
89                             },
90                             minWidth:250,
91                             prompt:true,
92                             //multiline: multiline,
93                             modal : true,
94                             value : b.image_src
95                         });
96                     }
97                 },
98                 xns : rooui.Toolbar
99             },
100          
101             {
102                 xtype : 'Button',
103                 text: 'Change Link URL',
104                  
105                 listeners : {
106                     click: function (btn, state)
107                     {
108                         var b = block();
109                         
110                         Roo.MessageBox.show({
111                             title : "Link URL",
112                             msg : "Enter the url for the link - leave blank to have no link",
113                             buttons: Roo.MessageBox.OKCANCEL,
114                             fn: function(btn, val){
115                                 if (btn != 'ok') {
116                                     return;
117                                 }
118                                 b.href = val;
119                                 b.updateElement();
120                                 syncValue();
121                                 toolbar.editorcore.onEditorEvent();
122                             },
123                             minWidth:250,
124                             prompt:true,
125                             //multiline: multiline,
126                             modal : true,
127                             value : b.href
128                         });
129                     }
130                 },
131                 xns : rooui.Toolbar
132             },
133             {
134                 xtype : 'Button',
135                 text: 'Show Video URL',
136                  
137                 listeners : {
138                     click: function (btn, state)
139                     {
140                         Roo.MessageBox.alert("Video URL",
141                             block().video_url == '' ? 'This image is not linked ot a video' :
142                                 'The image is linked to: <a target="_new" href="' + block().video_url + '">' + block().video_url + '</a>');
143                     }
144                 },
145                 xns : rooui.Toolbar
146             },
147             
148             
149             {
150                 xtype : 'TextItem',
151                 text : "Width: ",
152                 xns : rooui.Toolbar  //Boostrap?
153             },
154             {
155                 xtype : 'ComboBox',
156                 allowBlank : false,
157                 displayField : 'val',
158                 editable : true,
159                 listWidth : 100,
160                 triggerAction : 'all',
161                 typeAhead : true,
162                 valueField : 'val',
163                 width : 70,
164                 name : 'width',
165                 listeners : {
166                     select : function (combo, r, index)
167                     {
168                         toolbar.editorcore.selectNode(toolbar.tb.selectedNode);
169                         var b = block();
170                         b.width = r.get('val');
171                         b.updateElement();
172                         syncValue();
173                         toolbar.editorcore.onEditorEvent();
174                     }
175                 },
176                 xns : rooui.form,
177                 store : {
178                     xtype : 'SimpleStore',
179                     data : [
180                         ['100%'],
181                         ['80%'],
182                         ['50%'],
183                         ['20%'],
184                         ['10%']
185                     ],
186                     fields : [ 'val'],
187                     xns : Roo.data
188                 }
189             },
190             {
191                 xtype : 'TextItem',
192                 text : "Align: ",
193                 xns : rooui.Toolbar  //Boostrap?
194             },
195             {
196                 xtype : 'ComboBox',
197                 allowBlank : false,
198                 displayField : 'val',
199                 editable : true,
200                 listWidth : 100,
201                 triggerAction : 'all',
202                 typeAhead : true,
203                 valueField : 'val',
204                 width : 70,
205                 name : 'align',
206                 listeners : {
207                     select : function (combo, r, index)
208                     {
209                         toolbar.editorcore.selectNode(toolbar.tb.selectedNode);
210                         var b = block();
211                         b.align = r.get('val');
212                         b.updateElement();
213                         syncValue();
214                         toolbar.editorcore.onEditorEvent();
215                     }
216                 },
217                 xns : rooui.form,
218                 store : {
219                     xtype : 'SimpleStore',
220                     data : [
221                         ['left'],
222                         ['right'],
223                         ['center']
224                     ],
225                     fields : [ 'val'],
226                     xns : Roo.data
227                 }
228             },
229             
230               
231             {
232                 xtype : 'Button',
233                 text: 'Hide Caption',
234                 name : 'caption_display',
235                 pressed : false,
236                 enableToggle : true,
237                 setValue : function(v) {
238                     // this trigger toggle.
239                      
240                     this.setText(v ? "Hide Caption" : "Show Caption");
241                     this.setPressed(v != 'block');
242                 },
243                 listeners : {
244                     toggle: function (btn, state)
245                     {
246                         var b  = block();
247                         b.caption_display = b.caption_display == 'block' ? 'none' : 'block';
248                         this.setText(b.caption_display == 'block' ? "Hide Caption" : "Show Caption");
249                         b.updateElement();
250                         syncValue();
251                         toolbar.editorcore.selectNode(toolbar.tb.selectedNode);
252                         toolbar.editorcore.onEditorEvent();
253                     }
254                 },
255                 xns : rooui.Toolbar
256             }
257         ];
258         
259     },
260     /**
261      * create a DomHelper friendly object - for use with
262      * Roo.DomHelper.markup / overwrite / etc..
263      */
264     toObject : function()
265     {
266         var d = document.createElement('div');
267         d.innerHTML = this.caption;
268         
269         var m = this.width != '100%' && this.align == 'center' ? '0 auto' : 0; 
270         
271         var iw = this.align == 'center' ? this.width : '100%';
272         var img =   {
273             tag : 'img',
274             contenteditable : 'false',
275             src : this.image_src,
276             alt : d.innerText.replace(/\n/g, " ").replace(/\s+/g, ' ').trim(), // removeHTML and reduce spaces..
277             style: {
278                 width : iw,
279                 maxWidth : iw + ' !important', // this is not getting rendered?
280                 margin : m  
281                 
282             },
283             width: this.align == 'center' ?  this.width : '100%' 
284
285         };
286         
287         /*
288         '<div class="{0}" width="420" height="315" src="{1}" frameborder="0" allowfullscreen>' +
289                     '<a href="{2}">' + 
290                         '<img class="{0}-thumbnail" src="{3}/Images/{4}/{5}#image-{4}" />' + 
291                     '</a>' + 
292                 '</div>',
293         */
294                 
295         if (this.href.length > 0) {
296             img = {
297                 tag : 'a',
298                 href: this.href,
299                 contenteditable : 'true',
300                 cn : [
301                     img
302                 ]
303             };
304         }
305         
306         
307         if (this.video_url.length > 0) {
308             img = {
309                 tag : 'div',
310                 cls : this.cls,
311                 frameborder : 0,
312                 allowfullscreen : true,
313                 width : 420,  // these are for video tricks - that we replace the outer
314                 height : 315,
315                 src : this.video_url,
316                 cn : [
317                     img
318                 ]
319             };
320         }
321
322
323   
324         var ret =   {
325             tag: 'figure',
326             'data-block' : 'Figure',
327             'data-width' : this.width,
328             'data-caption' : this.caption, 
329             'data-caption-display' : this.caption_display,
330             contenteditable : 'false',
331             
332             style : {
333                 display: 'block',
334                 float :  this.align ,
335                 maxWidth :  this.align == 'center' ? '100% !important' : (this.width + ' !important'),
336                 width : this.align == 'center' ? '100%' : this.width,
337                 margin:  '0px',
338                 padding: this.align == 'center' ? '0' : '0 10px' ,
339                 textAlign : this.align   // seems to work for email..
340                 
341             },
342             
343             align : this.align,
344             cn : [
345                 img
346             ]
347         };
348
349         // show figcaption only if caption_display is 'block'
350         if(this.caption_display == 'block') {
351             ret['cn'].push({
352                 tag: 'figcaption',
353                 style : {
354                     textAlign : 'left',
355                     fontSize : '16px',
356                     lineHeight : '24px',
357                     display : this.caption_display,
358                     maxWidth : (this.align == 'center' ?  this.width : '100%' ) + ' !important',
359                     margin: m,
360                     width: this.align == 'center' ?  this.width : '100%' 
361                 
362                      
363                 },
364                 cls : this.cls.length > 0 ? (this.cls  + '-thumbnail' ) : '',
365                 cn : [
366                     {
367                         tag: 'div',
368                         style  : {
369                             marginTop : '16px',
370                             textAlign : 'start'
371                         },
372                         align: 'left',
373                         cn : [
374                             {
375                                 // we can not rely on yahoo syndication to use CSS elements - so have to use  '<i>' to encase stuff.
376                                 tag : 'i',
377                                 contenteditable : Roo.htmleditor.BlockFigure.caption_edit,
378                                 html : this.caption.length ? this.caption : "Caption" // fake caption
379                             }
380                             
381                         ]
382                     }
383                     
384                 ]
385                 
386             });
387         }
388         return ret;
389          
390     },
391     
392     readElement : function(node)
393     {
394         // this should not really come from the link...
395         this.video_url = this.getVal(node, 'div', 'src');
396         this.cls = this.getVal(node, 'div', 'class');
397         this.href = this.getVal(node, 'a', 'href');
398         
399         
400         this.image_src = this.getVal(node, 'img', 'src');
401          
402         this.align = this.getVal(node, 'figure', 'align');
403
404         // caption display is stored in figure
405         this.caption_display = this.getVal(node, true, 'data-caption-display');
406
407         // backward compatible
408         // it was stored in figcaption
409         if(this.caption_display == '') {
410             this.caption_display = this.getVal(node, 'figcaption', 'data-display');
411         }
412
413         // read caption from figcaption
414         var figcaption = this.getVal(node, 'figcaption', false);
415
416         if (figcaption !== '') {
417             this.caption = this.getVal(figcaption, 'i', 'html');
418         }
419                 
420
421         // read caption from data-caption in figure if no caption from figcaption
422         var dc = this.getVal(node, true, 'data-caption');
423
424         if(this.caption_display == 'none' && dc && dc.length){
425             this.caption = dc;
426         }
427
428         //this.text_align = this.getVal(node, 'figcaption', 'style','text-align');
429         this.width = this.getVal(node, true, 'data-width');
430         //this.margin = this.getVal(node, 'figure', 'style', 'margin');
431         
432     },
433     removeNode : function()
434     {
435         return this.node;
436     }
437     
438   
439    
440      
441     
442     
443     
444     
445 });
446
447 Roo.apply(Roo.htmleditor.BlockFigure, {
448     caption_edit : true
449 });
450