1/** 2 Ape - Automatic embedding of video players and maps for PmWiki 3 Written by (c) Petko Yotov 2014-2018 www.pmwiki.org/petko 4 5 This text is written for PmWiki; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published 7 by the Free Software Foundation version 2. 8 9 Version 20180118 10*/ 11 12(function() { 13 var tags = { 14 audio: 'audio', 15 video: 'video', 16 vtt: 'video', 17 iframe: 'iframe', 18 svg: 'object', 19 swf: 'object' 20 } 21 var contenttypes = { 22 flac: 'audio/x-flac', 23 wav: 'audio/x-wav', 24 mp3: 'audio/mpeg', 25 ogg: 'audio/ogg', 26 oga: 'audio/ogg', 27 opus: 'audio/opus', 28 29 ogv: 'video/ogg', 30 mp4: 'video/mp4', 31 webm: 'video/webm', 32 vtt: 'text/vtt' 33 } 34 35 function log(x) {console.log(x);} 36 37 function APgrab(tag, cn, par) { 38 par = par || document; 39 var i, r = [], rx = new RegExp('\\b'+cn+'\\b'), x = par.getElementsByTagName(tag); 40 for(i=0;i<x.length; i++) if( (!cn) || rx.test(x[i].className)) r.push(x[i]); 41 return r; 42 } 43 44 function APE() { 45 var a, W, H, player, stl, i, j, k, links, href, src, d, scripts, players = [], ApeDir = '', allspans, idcnt = 0, rx, lnk, iheight= '315px', iwidth='560px', tn; 46 scripts = APgrab('script'); 47 for(i=0; i<scripts.length; i++) { 48 a = scripts[i].src.match(/^(.*\/)ape\.js(\?.*)?$/); 49 if(! a) continue; 50 ApeDir = a[1]; 51 break; 52 } 53 54 players = players.concat(APgrab('span', '(player|map|embed)'), APgrab('p', '(player|map|embed)'), 55 APgrab('div', '(player|map|embed)'), APgrab('dl', '(map|embed)')); 56 57 rx = [ // more will be added in the future 58 [/^https?:\/\/www\.(ted\.com\/talks\/\w+)$/i, 'https://embed-ssl.$1.html'], 59 [/^https?:\/\/(www\.)?twitch\.tv\/videos\/(\d+)$/i, 'https://player.twitch.tv/?autoplay=false&video=v$2'], 60 [/^https?:\/\/www\.youtube\.com\/watch\?v=([^&]+)(&.*)?$/i, 'https://www.youtube-nocookie.com/embed/$1$2'], 61 [/^https?:\/\/www\.youtube\.com\/(playlist|videoseries)(.*)$/i, 'https://www.youtube-nocookie.com/embed/$1$2'], 62 [/^https?:\/\/www\.youtube(-nocookie)?\.com(\/embed\/.*)$/i, 'https://www.youtube-nocookie.com/$2'], 63 [/^https?:\/\/vimeo\.com\/(.*\/)?(\d+)$/i, 'https://player.vimeo.com/video/$2?title=0&byline=0&portrait=0&autoplay=0'], 64 [/^https?(:\/\/www.dailymotion.com)(\/video\/[a-z0-9-]+)_/i, 'https$1embed/$2'], 65 [/^https?:\/\/dai\.ly\/([a-z0-9-]+)$/i, 'https://www.dailymotion.com/embed/video/$1'], 66 [/^https?:\/\/youtu\.be\/([^&?]+)([&?].*)?$/i, 'https://www.youtube-nocookie.com/embed/$1$2'], 67 [/^https?:\/\/[a-z-]+\.facebook\.com\/photo\.php\?v=(\d+)$/i, 'https://www.facebook.com/video/embed?video_id=$1'], 68 [/^https?:\/\/[a-z-]+\.facebook\.com\/\S+\/videos\/(\d+)\/?$/i, 'https://www.facebook.com/video/embed?video_id=$1'], 69 [/^https?(:\/\/u\.osmfr\.org\/m\/\d+\/?)$/i, 'https$1'], 70 [/^(http.*umap\.openstreetmap\.fr.*\/map\/[^\s]+)$/i, '$1'], 71 [/^http.*openstreetmap\.org.*#map=[^\s]+$/i, ApeDir+'ape-osmap.html#'], 72 [/^https?:\/\/osm\.org\/go\/\S+$/i, ApeDir+'ape-osmap.html#'], 73 [/^https?(:\/\/archive\.org)\/(details|embed)\/([^\s\/]+)\/?$/i, 'https$1/embed/$3'], 74 [/^https?(:\/\/(www\.)?teachertube\.com)\/(video|audio)\/[\w-]*-(\d+)\/?$/, 'https$1/embed/$3/$4'], 75 [/^https?(:\/\/(www\.)?teachertube\.com)\/(video|audio)\/(\d+)\/?$/, 'https$1/embed/$3/$4'], 76 [/^https?(:.*\.google\..*\/calendar\/embed.+)$/i, 'https$1'], 77 [/^(https:\/\/drive\.google\.com\/open)\S*[?&]id=([_a-z0-9-]*)([&#].*)?$/i, 'https://www.google.com/maps/d/embed?mid=$2'], 78 79 [/^https?.*\.youscribe\.com\/.*\/(\d+)($|\?.*$)/i, 'https://www.youscribe.com/BookReader/IframeEmbed?token=&width=auto&height=auto&startPage=1&displayMode=scroll&fullscreen=0&productId=$1'], 80 [/^https?.*\.youscribe\.com.*-(\d+)\/?$/i, 'https://www.youscribe.com/BookReader/IframeEmbed?token=&width=auto&height=auto&startPage=1&displayMode=scroll&fullscreen=0&productId=$1'], 81 [/^https?:\/\/(www\.)?vbox7\.com\/play:(\w+)/i, 'https://vbox7.com/emb/external.php?vid=$2'], 82 83 [/^(https:\/\/docs\.google\.com\/[^?]*)(\?.*)?$/i, '$1?embedded=true'], 84 [/^(.*\.(pdf|rtf))$/i, 'https://docs.google.com/gview?embedded=true&url=$1'], 85 [/^(.*\.(docx?|xlsx?|pptx?|od[stp]))$/i, "https://view.officeapps.live.com/op/view.aspx?src=$1"], 86 [/^(.*\.(dwg|dxf|plt|spl|stp|igs|sat|cgm))$/i, 'https://sharecad.org/cadframe/load?url=$1'], 87 88 [/^(https:\/\/pastebin\.com)\/(embed(_i?frame|_js)?\/)?([\w-]+)/, '$1/embed_iframe/$4' ], 89 [/^(.*\.svg)$/i, 'svg'], 90 [/^(.*\.swf)$/i, 'swf'],
91 [/^(.*\.(mp4|webm|ogv|vtt))$/i, 'video'], 92 [/^(.*\.(mp3|opus|ogg|oga|flac))$/i, 'audio'], 93 [/$^/, 'no comma after last element'] 94 ]; 95 // someday: http://img.youtube.com/vi/[your-video-id]/0.jpg 96 97 var rx2 = []; 98 if(typeof uAPErx == 'object') { 99 for(var i=0; i<uAPErx.length; i++) rx2.push(uAPErx[i]); 100 } 101 for(var i=0; i<rx.length; i++) rx2.push(rx[i]); 102 rx = rx2; 103 104 for (i=0; i<players.length; i++) { 105 player = players[i]; 106 tn = player.tagName.toLowerCase(); 107 stl = player.getAttribute('style'); 108 if(stl != null && typeof stl == 'object') { // MSIE<8 109 stl="width:"+player.style.width+';'+" height:"+player.style.height+';' 110 } 111 if(stl) { 112 a = stl.match(/width: *([0-9\.]+ *(%|p[xtc]|e[mx]|[mc]?m|v[wh]))/i) 113 W = (a) ? a[1] : ((player.className.indexOf('map')<0)? iwidth : '100%'); 114 a = stl.match(/height: *([\d.]+ *(%|p[xtc]|e[mx]|[mc]?m|v[wh])|auto)/i) 115 H = (a) ? a[1] : iheight; 116 } 117 else { 118 W = (player.className.indexOf('map')<0)? iwidth : '100%'; 119 H = iheight; 120 } 121 122 if(tn=='span' || tn=='div' || tn=='p' ) { 123 links = APgrab('a', false, player); 124 if(! links) continue; 125 126 var sources = [ ]; 127 128 for (j=0; j<links.length; j++) { 129 lnk = links[j]; 130 href = lnk.href; 131 if(href.match(/[&?]action=upload(\&|$)/)) continue; 132 for(k=0; k<rx.length; k++) { 133 if(! href.match(rx[k][0])) continue; 134 135 tag = 'iframe'; 136 src = href; 137 if(typeof tags[ rx[k][1] ] != 'undefined') tag = rx[k][1]; 138 else src = href.replace(rx[k][0], rx[k][1]); 139 140 if(src.match(/#$/)) { 141 if(!lnk.id) lnk.id = 'ape_id_'+(idcnt++); 142 src += lnk.id; 143 } 144// log([lnk, src, W, H, tag]); 145 if(tag != 'video' && tag != 'audio') { 146 APFrame(lnk, src, W, H, tag); 147 } 148 else sources.push(lnk); 149 break; 150 } 151 } 152 if(sources.length) { 153 APFrame(player, sources, W, H, tag); 154 } 155 } 156 else if(tn=='dl') { 157 if(!player.id) player.id = 'ape_id_'+(idcnt++); 158 APFrame(player, ApeDir+'ape-osmap.html#'+player.id, W, H, 'iframe'); 159 } 160 } 161 } 162 163 function APFrame(elm, src, W, H, tag) { 164 var d = document.createElement(tags[tag]); 165 166 var align = ''; 167 if(elm.style.textAlign.indexOf("center")>=0) align = "margin: 0 auto;"; 168 if(elm.style.textAlign.indexOf("right")>=0) align = "margin: 0 0 0 auto;"; 169 170 var attrs = { 171 iframe: { 172 id: (elm.id)?'iframe_'+elm.id:'', 173 src: src, 174 style: "border: 1px solid black; display: block; width: "+W+"; height: "+H+";"+align, 175 frameborder: 0, 176 marginheight: 0, 177 marginwidth: 0, 178 webkitallowfullscreen: '=', 179 mozallowfullscreen: '=', 180 msallowfullscreen: '=', 181 oallowfullscreen: '=', 182 allowfullscreen: '=' 183 }, 184 audio: { 185 id: (elm.id)?'audio_'+elm.id:'', 186 style: align, 187 controls: '=' 188 }, 189 swf: { 190 id: (elm.id)?'swf_'+elm.id:'', 191 style: "border: 1px solid black; display: block; width: "+W+"; height: "+H+";"+align, 192 type: "application/x-shockwave-flash", 193 quality: 'high', 194 data: src 195 }, 196 svg: { 197 id: (elm.id)?'svg_'+elm.id:'', 198 style:"border: none; display: inline; width: "+W+"; height: "+H+";"+align, 199 type: 'image/svg+xml', 200 data: src 201 } 202 }; 203 204 inaudiovideo = ''; 205 if(tag == 'video' || tag == 'audio') { 206 attrs.video = { }; 207 for (i in attrs.iframe) { 208 if(i == 'id' || i == 'src') continue; 209 attrs.video[i] = attrs.iframe[i]; 210 } 211 attrs.video.controls = '='; 212 subs = 0; 213 for(var i=0; i<src.length; i++) { 214 var href = src[i].href; 215// log(href); 216 var a = href.toLowerCase().match(/\.(\w+)$/); 217// log(a); 218 var tp = ''; 219 if(a) { 220 if(typeof contenttypes[a[1]] != 'undefined') { 221 tp = contenttypes[a[1]]; 222 var title = src[i].getAttribute('title'); 223 if(title) { 224 var b = title.match(/\b(codecs=\S+)(\s|$)/); 225 if (b) tp += '; '+a[1]; 226 } 227 } 228 } 229 if(tp) tp=' type="'+tp+'"'; 230 if(a[1] == 'vtt') { 231 var dflt = subs ? '' : ' default'; 232 var lang = title ? ' srclang="'+title+'"' : ''; 233 subs++; 234 inaudiovideo += '<track src="'+href+'" kind="subtitles" label="'+src[i].textContent+'"'+lang+dflt+' >'; 235 } 236 else inaudiovideo += '<source src="'+href+'" '+tp+'>'; 237 } 238 } 239 240 var inner = { 241 iframe: '', 242 audio: inaudiovideo, 243 video: inaudiovideo, 244 swf: 'embed', 245 svg: 'embed' 246 } 247 248 for(var i in attrs[tag]) { 249 var val = attrs[tag][i]; 250 if(!val) continue; 251 if(val == '=') val = i; 252 else if (typeof val == 'array') continue; 253 d.setAttribute(i, val); 254 } 255 256 if(inner[tag]) { 257 var ih = (inner[tag]!='embed') 258 ? inner[tag] 259 : '<embed type="'+attrs[tag].type+'" src="' 260 +src+'" style="'+attrs[tag].style+'" />'
261 d.innerHTML = ih; 262 } 263 264 265 elm.parentNode.insertBefore(d, elm); 266 elm.style.display = 'none'; 267 if(H=='auto') { 268 var realw = d.offsetWidth; 269 var realh = Math.round(realw / 16 * 9); 270 d.style.height = realh + "px"; 271 } 272 } 273 274 setTimeout(APE, 50); 275 276})(); 277
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.