22
|
1 <!doctype html>
|
|
2 <html>
|
|
3 <head>
|
|
4 <meta name="viewport" content="width=device-width, initial-scale=1">
|
24
|
5 <script src="http://tinymce.luan.software/tinymce.min.js" xreferrerpolicy="origin"></script>
|
22
|
6 <style>
|
|
7 </style>
|
|
8 <script>
|
28
|
9 function videoIframe(url) {
|
|
10 return '<iframe data-video="'+url+'" width="560" height="315" frameborder="0" allowfullscreen src="'+url+'"></iframe>';
|
|
11 }
|
|
12
|
30
|
13 // fucking moronic javascript doesn't have \Q \E in regex
|
28
|
14 var videoHandlers = {};
|
|
15 {
|
30
|
16 let ptn1 = /^https:\/\/youtu\.be\/([a-zA-Z0-9_-]+)(?:\?t=([0-9]+))?/;
|
|
17 let ptn2 = /^https:\/\/www\.youtube\.com\/watch\?v=([a-zA-Z0-9_-]+)(?:&t=([0-9]+)s)?/;
|
28
|
18 videoHandlers.youtube = function(url) {
|
|
19 let result = url.match(ptn1) || url.match(ptn2);
|
|
20 if( result ) {
|
|
21 url = 'https://www.youtube.com/embed/' + result[1];
|
|
22 if( result[2] )
|
|
23 url += '?start=' + result[2];
|
|
24 return videoIframe(url);
|
|
25 }
|
|
26 }
|
|
27 }
|
|
28 {
|
30
|
29 let ptn = /^https:\/\/rumble\.com\/embed\/[a-z0-9]+\/\?pub=[a-z0-9]+/;
|
28
|
30 videoHandlers.rumble = function(url) {
|
|
31 if( url.match(ptn) ) {
|
|
32 return videoIframe(url);
|
|
33 }
|
|
34 }
|
|
35 }
|
|
36 {
|
30
|
37 let ptn = /^https:\/\/www\.bitchute\.com\/video\/([a-zA-Z0-9]+)\//;
|
28
|
38 videoHandlers.bitchute = function(url) {
|
|
39 let result = url.match(ptn);
|
|
40 if( result ) {
|
|
41 url = 'https://www.bitchute.com/embed/' + result[1];
|
|
42 return videoIframe(url);
|
|
43 }
|
|
44 }
|
|
45 }
|
|
46 {
|
30
|
47 let ptn = /^https:\/\/vimeo\.com\/([0-9]+)/;
|
28
|
48 videoHandlers.vimeo = function(url) {
|
|
49 let result = url.match(ptn);
|
|
50 if( result ) {
|
|
51 url = 'https://player.vimeo.com/video/' + result[1];
|
|
52 return videoIframe(url);
|
|
53 }
|
|
54 }
|
|
55 }
|
|
56 {
|
30
|
57 let ptn = /^https:\/\/dai\.ly\/([a-z0-9]+)/;
|
28
|
58 videoHandlers.dailymotion = function(url) {
|
|
59 let result = url.match(ptn);
|
|
60 if( result ) {
|
|
61 url = 'https://www.dailymotion.com/embed/video/' + result[1];
|
|
62 return videoIframe(url);
|
|
63 }
|
|
64 }
|
|
65 }
|
|
66 {
|
30
|
67 let ptn = /^https:\/\/www\.tiktok\.com\/[^/]+\/video\/([0-9]+)/;
|
28
|
68 videoHandlers.tiktok = function(url) {
|
|
69 let result = url.match(ptn);
|
|
70 if( result ) {
|
31
|
71 //let html = '<blockquote class="tiktok-embed" data-video="'+result[1]+'" style="max-width: 560px; margin-left: 0;"><section></section></blockquote>';
|
28
|
72 //html += '<script async src="https://www.tiktok.com/embed.js"></'+'script>';
|
31
|
73 let html = '<img data-video="'+result[1]+'" src="whataever">';
|
28
|
74 return html;
|
|
75 }
|
|
76 }
|
|
77 }
|
|
78 {
|
30
|
79 let ptn = /\.[a-zA-Z0-9]+$/;
|
28
|
80 videoHandlers.file = function(url) {
|
|
81 if( url.match(ptn) ) {
|
|
82 return '<video controls width="560" height><source src="'+url+'"></video>';
|
|
83 }
|
|
84 }
|
|
85 }
|
|
86
|
|
87 function videoUrlToHtml(url) {
|
|
88 for (let key in videoHandlers) {
|
|
89 let handle = videoHandlers[key];
|
|
90 let html = handle(url);
|
|
91 if(html) return html;
|
|
92 }
|
|
93 return '<a data-video="'+url+'" href="'+url+'">'+url+'</a>';
|
|
94 }
|
22
|
95
|
24
|
96
|
23
|
97 function tinymceSetup(editor) {
|
24
|
98
|
31
|
99 editor.ui.registry.addButton('insertImage', {
|
|
100 icon: 'image',
|
|
101 tooltip: 'Insert image',
|
|
102 onAction: function(api) {
|
|
103 editor.windowManager.open({
|
|
104 title: 'Insert Image',
|
|
105 body: {
|
|
106 type: 'panel',
|
|
107 items: [
|
|
108 {
|
|
109 type: 'urlinput',
|
|
110 name: 'src',
|
|
111 filetype: 'image',
|
|
112 label: 'Source URL'
|
|
113 },
|
|
114 ]
|
|
115 },
|
|
116 buttons: [
|
|
117 {
|
|
118 type: 'cancel',
|
|
119 text: 'Cancel'
|
|
120 },
|
|
121 {
|
|
122 type: 'submit',
|
|
123 text: 'Save',
|
|
124 buttonType: 'primary'
|
|
125 }
|
|
126 ],
|
|
127 onSubmit: function(dialogApi) {
|
|
128 let src = dialogApi.getData('src').src.value;
|
|
129 if(!src) return;
|
|
130 src = tinymce.DOM.encode(src);
|
|
131 let html = '<img src="' + src + '">';
|
|
132 dialogApi.close();
|
|
133 editor.insertContent(html);
|
|
134 }
|
|
135 });
|
|
136 },
|
|
137 });
|
|
138
|
|
139 editor.ui.registry.addButton('insertVideo', {
|
|
140 icon: 'embed',
|
|
141 tooltip: 'Insert video',
|
|
142 onAction: function(api) {
|
|
143 editor.windowManager.open({
|
|
144 title: 'Insert Video',
|
|
145 body: {
|
|
146 type: 'panel',
|
|
147 items: [
|
|
148 {
|
|
149 type: 'urlinput',
|
|
150 name: 'src',
|
|
151 filetype: 'image',
|
|
152 label: 'Source URL'
|
|
153 },
|
|
154 ]
|
|
155 },
|
|
156 buttons: [
|
|
157 {
|
|
158 type: 'cancel',
|
|
159 text: 'Cancel'
|
|
160 },
|
|
161 {
|
|
162 type: 'submit',
|
|
163 text: 'Save',
|
|
164 buttonType: 'primary'
|
|
165 }
|
|
166 ],
|
|
167 onSubmit: function(dialogApi) {
|
|
168 let src = dialogApi.getData('src').src.value;
|
|
169 if(!src) return;
|
|
170 let html = videoUrlToHtml(src);
|
|
171 //alert(html);
|
|
172 dialogApi.close();
|
|
173 editor.insertContent(html);
|
|
174 }
|
|
175 });
|
|
176 },
|
|
177 });
|
|
178
|
24
|
179 editor.ui.registry.addToggleButton('styleCode', {
|
|
180 icon: 'sourcecode',
|
|
181 tooltip: 'Code',
|
|
182 onAction: function(api) {
|
31
|
183 editor.execCommand('mceToggleFormat', false, 'code');
|
24
|
184 },
|
|
185 onSetup: function(api) {
|
|
186 api.setActive(editor.formatter.match('code'));
|
|
187 let changed = editor.formatter.formatChanged('code', api.setActive);
|
|
188 return function() { changed.unbind(); };
|
|
189 }
|
|
190 });
|
|
191
|
|
192 editor.ui.registry.addMenuButton('styleText', {
|
|
193 icon: 'format',
|
|
194 tooltip: 'Text',
|
|
195 fetch: function(callback) {
|
|
196 callback([
|
|
197 'fontsize',
|
|
198 'forecolor',
|
|
199 ])
|
|
200 }
|
23
|
201 });
|
26
|
202
|
31
|
203 editor.on( 'init', function(e) {
|
|
204 editor.focus();
|
|
205 } );
|
23
|
206 }
|
|
207
|
22
|
208 tinymce.init({
|
|
209 selector: 'textarea',
|
23
|
210 setup: tinymceSetup,
|
27
|
211 //menubar: false,
|
26
|
212 statusbar: false,
|
31
|
213 toolbar: 'link insertImage insertVideo | styleCode bold italic underline strikethrough superscript styleText | blockquote numlist bullist',
|
26
|
214 plugins: ['link', 'image', 'media', 'lists', 'code', 'autoresize'],
|
|
215 autoresize_bottom_margin: 0,
|
22
|
216 link_target_list: false,
|
|
217 link_title: false,
|
|
218 object_resizing: false,
|
|
219 contextmenu: false,
|
|
220 text_patterns: false,
|
26
|
221 content_style: 'img {max-width: 500px;} p {margin: 0}',
|
22
|
222 extended_valid_elements: 'b,i',
|
|
223 formats: {
|
|
224 bold: { inline: 'b' },
|
|
225 italic: {inline: 'i'},
|
|
226 underline: {inline: 'u'},
|
|
227 },
|
|
228 });
|
|
229
|
|
230 function log() {
|
|
231 console.log(tinymce.activeEditor.getContent());
|
|
232 }
|
|
233 </script>
|
|
234 </head>
|
|
235 <body>
|
23
|
236 <p><a href="https://www.tiny.cloud/">TinyMCE</a></p>
|
22
|
237 <textarea></textarea>
|
|
238 <p><button onclick="log()">log</button></p>
|
|
239 </body>
|
|
240 </html>
|