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
|
|
13 var videoHandlers = {};
|
|
14 {
|
|
15 let ptn1 = new RegExp('https://youtu.be/([a-zA-Z0-9_-]+)(?:\\?t=([0-9]+))?');
|
|
16 let ptn2 = new RegExp('https://www.youtube.com/watch\\?v=([a-zA-Z0-9_-]+)(?:\\?t=([0-9]+)s)?');
|
|
17 videoHandlers.youtube = function(url) {
|
|
18 let result = url.match(ptn1) || url.match(ptn2);
|
|
19 if( result ) {
|
|
20 url = 'https://www.youtube.com/embed/' + result[1];
|
|
21 if( result[2] )
|
|
22 url += '?start=' + result[2];
|
|
23 return videoIframe(url);
|
|
24 }
|
|
25 }
|
|
26 }
|
|
27 {
|
|
28 let ptn = new RegExp('https://rumble.com/embed/[a-z0-9]+/\\?pub=[a-z0-9]+');
|
|
29 videoHandlers.rumble = function(url) {
|
|
30 if( url.match(ptn) ) {
|
|
31 return videoIframe(url);
|
|
32 }
|
|
33 }
|
|
34 }
|
|
35 {
|
|
36 let ptn = new RegExp('https://www.bitchute.com/video/([a-zA-Z0-9]+)/');
|
|
37 videoHandlers.bitchute = function(url) {
|
|
38 let result = url.match(ptn);
|
|
39 if( result ) {
|
|
40 url = 'https://www.bitchute.com/embed/' + result[1];
|
|
41 return videoIframe(url);
|
|
42 }
|
|
43 }
|
|
44 }
|
|
45 {
|
|
46 let ptn = new RegExp('https://vimeo.com/([0-9]+)');
|
|
47 videoHandlers.vimeo = function(url) {
|
|
48 let result = url.match(ptn);
|
|
49 if( result ) {
|
|
50 url = 'https://player.vimeo.com/video/' + result[1];
|
|
51 return videoIframe(url);
|
|
52 }
|
|
53 }
|
|
54 }
|
|
55 {
|
|
56 let ptn = new RegExp('https://dai.ly/([a-z0-9]+)');
|
|
57 videoHandlers.dailymotion = function(url) {
|
|
58 let result = url.match(ptn);
|
|
59 if( result ) {
|
|
60 url = 'https://www.dailymotion.com/embed/video/' + result[1];
|
|
61 return videoIframe(url);
|
|
62 }
|
|
63 }
|
|
64 }
|
|
65 {
|
|
66 let ptn = new RegExp('https://www.tiktok.com/[^/]+/video/([0-9]+)');
|
|
67 videoHandlers.tiktok = function(url) {
|
|
68 let result = url.match(ptn);
|
|
69 if( result ) {
|
|
70 let html = '<blockquote class="tiktok-embed" data-video-id="'+result[1]+'" style="max-width: 560px; margin-left: 0;"><section></section></blockquote>';
|
|
71 //html += '<script async src="https://www.tiktok.com/embed.js"></'+'script>';
|
|
72 return html;
|
|
73 }
|
|
74 }
|
|
75 }
|
|
76 {
|
|
77 let ptn = new RegExp('\\.[a-zA-Z0-9]+$');
|
|
78 videoHandlers.file = function(url) {
|
|
79 if( url.match(ptn) ) {
|
|
80 return '<video controls width="560" height><source src="'+url+'"></video>';
|
|
81 }
|
|
82 }
|
|
83 }
|
|
84
|
|
85 function videoUrlToHtml(url) {
|
|
86 for (let key in videoHandlers) {
|
|
87 let handle = videoHandlers[key];
|
|
88 let html = handle(url);
|
|
89 if(html) return html;
|
|
90 }
|
|
91 return '<a data-video="'+url+'" href="'+url+'">'+url+'</a>';
|
|
92 }
|
|
93 console.log(videoUrlToHtml('https://www.tiktok.com/@chantelleef/video/7112118342181276933?is_from_webapp=1&sender_device=pc&web_id=7073254106622838318'));
|
22
|
94
|
|
95 function media_url_resolver(data,resolve,reject) {
|
28
|
96 let html = videoUrlToHtml(data.url);
|
22
|
97 resolve({ html: html });
|
|
98 }
|
|
99
|
24
|
100
|
23
|
101 function tinymceSetup(editor) {
|
24
|
102
|
|
103 editor.ui.registry.addToggleButton('styleCode', {
|
|
104 icon: 'sourcecode',
|
|
105 tooltip: 'Code',
|
|
106 onAction: function(api) {
|
|
107 editor.execCommand('mceToggleFormat', false, 'code')
|
|
108 },
|
|
109 onSetup: function(api) {
|
|
110 api.setActive(editor.formatter.match('code'));
|
|
111 let changed = editor.formatter.formatChanged('code', api.setActive);
|
|
112 return function() { changed.unbind(); };
|
|
113 }
|
|
114 });
|
|
115
|
|
116 editor.ui.registry.addMenuButton('styleText', {
|
|
117 icon: 'format',
|
|
118 tooltip: 'Text',
|
|
119 fetch: function(callback) {
|
|
120 callback([
|
|
121 'fontsize',
|
|
122 'forecolor',
|
|
123 ])
|
|
124 }
|
23
|
125 });
|
26
|
126
|
|
127 editor.on( 'init', function(e) {editor.focus()} );
|
23
|
128 }
|
|
129
|
22
|
130 tinymce.init({
|
|
131 selector: 'textarea',
|
23
|
132 setup: tinymceSetup,
|
27
|
133 //menubar: false,
|
26
|
134 statusbar: false,
|
24
|
135 toolbar: 'link image media | styleCode bold italic underline strikethrough superscript styleText | blockquote numlist bullist',
|
26
|
136 plugins: ['link', 'image', 'media', 'lists', 'code', 'autoresize'],
|
|
137 autoresize_bottom_margin: 0,
|
22
|
138 link_target_list: false,
|
|
139 link_title: false,
|
|
140 image_description: false,
|
|
141 image_dimensions: false,
|
|
142 object_resizing: false,
|
|
143 contextmenu: false,
|
|
144 media_alt_source: false,
|
|
145 media_dimensions: false,
|
|
146 media_poster: false,
|
|
147 media_url_resolver: media_url_resolver,
|
|
148 text_patterns: false,
|
26
|
149 content_style: 'img {max-width: 500px;} p {margin: 0}',
|
23
|
150 //newline_behavior: 'linebreak',
|
22
|
151 extended_valid_elements: 'b,i',
|
|
152 formats: {
|
|
153 bold: { inline: 'b' },
|
|
154 italic: {inline: 'i'},
|
|
155 underline: {inline: 'u'},
|
|
156 },
|
|
157 });
|
|
158
|
|
159 function log() {
|
|
160 console.log(tinymce.activeEditor.getContent());
|
|
161 }
|
|
162 </script>
|
|
163 </head>
|
|
164 <body>
|
23
|
165 <p><a href="https://www.tiny.cloud/">TinyMCE</a></p>
|
22
|
166 <textarea></textarea>
|
|
167 <p><button onclick="log()">log</button></p>
|
|
168 </body>
|
|
169 </html>
|