add vimeo
[fnpeditor.git] / src / editor / plugins / core / video / videoElement.js
1 define(function(require) {
2     
3 'use strict';
4 /* globals gettext */
5
6
7 var $ = require('libs/jquery'),
8     _ = require('libs/underscore'),
9     genericElement = require('modules/documentCanvas/canvas/genericElement'),
10     Dialog = require('views/dialog/dialog'),
11     boxTemplate = require('libs/text!./box.html'),
12     attachments = require('views/attachments/attachments'),
13     linkElement = Object.create(genericElement);
14
15 function videoParser(url) {
16     var youtubeId = youtubeParser(url);
17     if (youtubeId) {
18         return {'videoProvider': 'youtube', 'videoId': youtubeId}
19     }
20     var vimeoId = vimeoParser(url);
21     if (vimeoId) {
22         return {'videoProvider': 'vimeo', 'videoId': vimeoId}
23     }
24 }
25
26 function youtubeParser(url) {
27     var regExp = /^.*(?:youtu.be\/|v\/|\/u\/\w\/|embed\/|\?v=|&v=|shared\?ci=)([^#&?]*).*/;
28     var match = url.match(regExp);
29     return (match && match[1].length === 11) ? match[1] : false;
30 }
31
32 function vimeoParser(url) {
33     var regExp = /https?:\/\/(www\.)?vimeo.com\/(\d+)($|\/)/;
34     var match = url.match(regExp);
35     return match? match[2]: false;
36 }
37
38 _.extend(linkElement, {
39     init: function() {
40         genericElement.init.call(this);
41         _.bindAll(this, 'changeLink', 'deleteLink');
42
43         var linkText = this.wlxmlNode.getAttr('src') || '',
44             linkUrl = this.getUrl(linkText);
45         
46         this.refreshLink(linkUrl);
47
48         this.box = $(_.template(boxTemplate)({text: linkText, url: linkUrl}));
49         this.box.find('.change').on('click', this.changeLink);
50         this.box.find('.delete').on('click', this.deleteLink);
51         this.box.hide();
52         this.addWidget(this.box);
53     },
54     onStateChange: function(changes) {
55         genericElement.onStateChange.call(this, changes);
56         if(_.isBoolean(changes.active)) {
57             this.box.toggle(changes.active);
58         }
59     },
60     onNodeAttrChange: function(event) {
61         if(event.meta.attr === 'src') {
62             var link = this.box.find('[link]');
63             link.text(event.meta.newVal);
64             var linkUrl = this.getUrl(event.meta.newVal);
65             link.attr('href', linkUrl);
66             this.refreshLink(linkUrl);
67         }
68     },
69
70     refreshLink: function(linkUrl) {
71         this._container().find('iframe').remove();
72         var videoData = videoParser(linkUrl);
73         var videoFrame;
74         if (videoData) {
75             if (videoData.videoProvider === 'youtube') {
76                 videoFrame = '<iframe width="480" height="270" src="//www.youtube.com/embed/' + videoData.videoId +
77                     '?controls=2&amp;rel=0&amp;showinfo=0&amp;theme=light" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>';
78             } else if (videoData.videoProvider === 'vimeo') {
79                 videoFrame = '<iframe src="//player.vimeo.com/video/' + videoData.videoId +
80                     '" width="480" height="270" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>';
81             }
82             this._container().text('');
83             this._container().append($(videoFrame));
84         } else {
85             this._container().text(gettext('No video. Click here to add link to your video'));
86         }
87     },
88
89     changeLink: function(e) {
90         var el = this,
91             dialog = Dialog.create({
92             title: gettext('Edit video url'),
93             executeButtonText: gettext('Apply'),
94             cancelButtonText: gettext('Cancel'),
95             fields: [
96                 {
97                     label: gettext('YouTube or Vimeo link'),
98                     name: 'src',
99                     type: 'input',
100                     initialValue: el.wlxmlNode.getAttr('src'),
101                     prePasteHandler:
102                         function(text) {
103                             return this.wlxmlNode.document.getLinkForUrl(text);
104                         }.bind(this)
105                 }
106             ]
107         });
108         e.preventDefault();
109         e.stopPropagation();
110
111         dialog.on('execute', function(event) {
112             var videoData = videoParser(event.formData.src);
113             el.wlxmlNode.document.transaction(function() {
114                 el.wlxmlNode.setAttr('src', event.formData.src);
115                 el.wlxmlNode.setAttr('videoid', videoData.videoId);
116                 el.wlxmlNode.setAttr('provider', videoData.videoProvider);
117                 event.success();
118             }, {
119                 metadata: {
120                     description: gettext('Edit video url')
121                     //fragment: doc.createFragment(doc.CaretFragment, {node: el.wlxmlNode.contents()[0], offset:offset})
122                 },
123                 success: function() {
124                     //el.canvas.select(doc.createFragment(doc.CaretFragment, {node: el.wlxmlNode.contents()[0], offset:offset}));
125                 }
126             });
127         });
128         dialog.show();
129         $(".attachment-library", dialog.$el).on('click', function() {
130             attachments.select(function(v) {$("input", dialog.$el).val(v);});
131         });
132
133     },
134
135     deleteLink: function() {
136         var el = this;
137
138         el.wlxmlNode.document.transaction(function() {
139             el.wlxmlNode.detach();
140         }, {
141             metadata: {
142                 description: gettext('Remove link')
143             }
144         });
145     },
146
147     getUrl: function(link) {
148         var pattern = /^[a-z]*:\/\//g;
149         if(!pattern.test(link) && !/^\//.test(link)) {
150             link = 'http://' + link;
151         }
152         return this.wlxmlNode.document.getUrlForLink(link);
153     }
154 });
155
156 return linkElement;
157
158 });