Benutzer:Schnark/js/imagepopups.js
aus Wikipedia, der freien Enzyklopädie
< Benutzer:Schnark | js
Hinweis: Leere nach dem Veröffentlichen den Browser-Cache, um die Änderungen sehen zu können.
- Firefox/Safari: Umschalttaste drücken und gleichzeitig Aktualisieren anklicken oder entweder Strg+F5 oder Strg+R (⌘+R auf dem Mac) drücken
- Google Chrome: Umschalttaste+Strg+R (⌘+Umschalttaste+R auf dem Mac) drücken
- Edge: Strg+F5 drücken oder Strg drücken und gleichzeitig Aktualisieren anklicken
//Dokumentation unter [[Benutzer:Schnark/js/imagepopups]] <nowiki> /*global mediaWiki*/ (function($,mw){ "use strict"; //jscs:disable maximumLineLength varl10n={ en:{ 'size-bytes':'1ドル B', 'size-kilobytes':'1ドル KB', 'size-megabytes':'1ドル MB', 'size-gigabytes':'1ドル GB', 'schnark-imagepopups-close':×ばつ',//icon for close button 'schnark-imagepopups-close-title':'close',//tooltip for close button 'schnark-imagepopups-local-desc':'local description page',//link text for local description page 'schnark-imagepopups-shared-desc':'description page (Commons)',//link text for description page on Commons 'schnark-imagepopups-missing':'1ドル (missing)',//appended to link to local description page if missing 'schnark-imagepopups-full-resolution':'full resolution',//link text for full resolution image 'schnark-imagepopups-info':'1ドル (2ドル)',//1ドル: link to full res., 2ドル: info 'schnark-imagepopups-info-default':×ばつ2,ドル 3,ドル 4ドル',//default info, 1ドル: width, 2ドル: height, 3ドル: mime, 4ドル: size 'schnark-imagepopups-info-paged':'5ドル pages, 3,ドル 4ドル',//info for paged files like PDF, 1ドル: width, 2ドル: height, 3ドル: mime, 4ドル: size, 5ドル: pages 'schnark-imagepopups-info-video':'5,ドル 3,ドル 4ドル',//info for videos, 1ドル: width, 2ドル: height, 3ドル: mime, 4ドル: size, 5ドル: time 'schnark-imagepopups-sep':' / ',//separator between links 'schnark-imagepopups-play':'Play video',//tooltip for play button 'schnark-imagepopups-time-seperator':':', 'schnark-imagepopups-unknown-length':'unknown length',//shown for videos with unknown length 'schnark-imagepopups-prev-page':'<',//button for previous page 'schnark-imagepopups-prev-page-tooltip':'Show previous page',//tooltip for this button 'schnark-imagepopups-next-page':'>',//button for next page 'schnark-imagepopups-next-page-tooltip':'Show next page',//tooltip for this button 'schnark-imagepopups-current-page':' · <b>page 1ドル</b> · ',//text to indicate current page, 1ドル is replaced with a <span> containing the current page number 'schnark-imagepopups-3d-viewer':'Open in 3D viewer', 'schnark-imagepopups-mediaviewer':'You have enabled both this script and the MediaViewer. You should decide for one script and disable the other.' }, de:{ 'size-bytes':'1ドル Bytes', 'schnark-imagepopups-close-title':'Schließen', 'schnark-imagepopups-local-desc':'lokale Bildbeschreibungsseite', 'schnark-imagepopups-shared-desc':'Bildbeschreibungsseite (Commons)', 'schnark-imagepopups-missing':'1ドル (fehlt)', 'schnark-imagepopups-full-resolution':'Vollbild', 'schnark-imagepopups-info-paged':'5ドル Seiten, 3,ドル 4ドル', 'schnark-imagepopups-play':'Vido abspielen', 'schnark-imagepopups-unknown-length':'unbekannte Dauer', 'schnark-imagepopups-prev-page-tooltip':'Vorherige Seite zeigen', 'schnark-imagepopups-next-page-tooltip':'Nächste Seite zeigen', 'schnark-imagepopups-current-page':' · <b>Seite 1ドル</b> · ', 'schnark-imagepopups-3d-viewer':'Im 3-D-Betrachter öffnen', 'schnark-imagepopups-mediaviewer':'Du hast sowohl dieses Skript als auch den Medienbetrachter aktiviert. Du solltest dich für ein Skript entscheiden und das andere deaktivieren.' }, 'de-ch':{ 'schnark-imagepopups-close-title':'Schliessen' }, 'de-formal':{ 'schnark-imagepopups-mediaviewer':'Sie haben sowohl dieses Skript als auch den Medienbetrachter aktiviert. Sie sollten sich für ein Skript entscheiden und das andere deaktivieren.' } //jscs:enable maximumLineLength },config={ replaceTMHPopup:true, useMwEmbed:true, warnAboutMV:false, css: '.imagePopup {'+ 'position: fixed;'+ 'border: solid 3px #000;'+ 'background-color: #fff;'+ 'min-width: 10em;'+ 'font-size: medium;'+ '}'+ '.imagePopupTitleBar {'+ 'position: relative;'+//a absolute 'padding-right: 1em;'+ 'overflow: hidden;'+ 'text-overflow: ellipsis;'+ 'white-space: nowrap;'+ 'background-color: #000;'+ 'color: #fff;'+ 'font-weight: bold;'+ 'text-align: center;'+ 'cursor: move;'+ '}'+ '.imagePopupTitleBar a {'+ 'display: block;'+ 'position: absolute;'+ 'top: -3px; right: -3px;'+//Rahmenbreite 'padding: 3px;'+//Rahmenbreite 'padding-bottom: 0px;'+ 'background-color: #000;'+ 'text-decoration: none;'+ 'outline: none !important;'+ 'color: #fff !important;'+ 'transition: color 0.25s;'+ 'cursor: pointer;'+ '}'+ '.imagePopupTitleBar a:hover {'+ 'text-decoration: none;'+ 'color: #d33 !important;'+ '}'+ '.imagePopup img:not(.playerPoster), .imagePopup .mediaContainer {'+ 'padding: 5px;'+ 'margin-left: auto;'+ 'margin-right: auto;'+ '}'+ '.imagePopupDesc {'+ 'max-height: 8em;'+ 'overflow: auto;'+ 'background-color: #fef6e7;'+ 'padding: 5px;'+ 'font-size: small;'+ '}', zIndex:120, /* evt. relevante Werte: 100 für obere Leiste in Vector 101 in OOUI (in Vector) für Dialoge etc. 110+ in EPOP (reagiert aber ohnehin nur auf Links im Haupttext) 200 in popuprefs.js */ sizes:[[320,240],[640,480],[800,600],[1024,768],[1280,1024]],//from DefaultSettings.php extensions:{ 'png':'image', 'apng':'image', 'jpg':'image', 'jpeg':'image', 'jpe':'image', 'gif':'image', 'bmp':'image', 'svg':'image', 'xcf':'image', 'webp':'image', 'pdf':'paged', 'tif':'paged', 'tiff':'paged', 'djvu':'paged', 'djv':'paged', 'ogg':'video', 'ogx':'video', 'ogm':'video', 'ogv':'video', 'oga':'video', 'spx':'video', 'opus':'video', 'mp4':'video', 'm4a':'video', 'm4p':'video', 'm4b':'video', 'm4r':'video', 'm4v':'video', 'webm':'video', 'stl':'threed' } }, parseHTML={ image:function($file){ vardata={}; data.url=getUrl($file); data.sharedUrl=getSharedUrl(data.url); data.localUrl=data.url.replace(/^(?:https?:)?\/\/[^\/]+\//,mw.config.get('wgServer')+'/'); data.title=getTitle(data.url); data.$desc=getDesc($file,data.title); data.lang=mw.util.getParamValue('lang',data.url)||''; returndata; }, paged:function($file){ vardata=parseHTML.image($file); data.page=mw.util.getParamValue('page',data.url)||1; returndata; }, video:function($file){ var$container=$file.parent('.PopUpMediaTransform'),data=parseHTML.image($container); data.$video=$($container.attr('videopayload')).find('video'); returndata.$video.length===1?data:false; }, threed:function($file){ vardata=parseHTML.image($file); data.threedHash='/media/File:'+data.title.replace(/ /g,'_'); returndata; } }, getParam={ image:function(data,w,h){ varparam={ action:'query', prop:'imageinfo', iiprop:'url|size|mime', iiurlwidth:w, iiurlheight:h, titles:'File:'+data.title, format:'json', formatversion:2 }; if(data.lang){ param.iiurlparam='lang'+data.lang+'-'+w+'px'; } returnparam; }, paged:function(data,w,h){ varparam=getParam.image(data,w,h); param.iiurlparam='page'+data.page+'-'+w+'px'; returnparam; }, video:function(data,w,h){ varparam=getParam.image(data,w,h); //TODO param.iiurlparam = 'seek:' returnparam; }, threed:function(data,w,h){ returngetParam.image(data,w,h); } }, extractData={ image:function(json){ varii=json.imageinfo[0],data={}; if(json.missing){ data.localMissing=true; } if(json.imagerepository==='shared'){ data.shared=true; } data.urlFull=ii.url; data.info=mw.msg('schnark-imagepopups-info-default', ii.width,ii.height,ii.mime,formatSize(ii.size)); data.urlThumb=ii.thumburl; data.thumbwidth=ii.thumbwidth; data.thumbheight=ii.thumbheight; returndata; }, paged:function(json,htmlData){ varii=json.imageinfo[0],data=extractData.image(json); if(ii.pagecount>1){ data.page=htmlData.page; data.pages=ii.pagecount; data.info=mw.msg('schnark-imagepopups-info-paged', ii.width,ii.height,ii.mime,formatSize(ii.size),ii.pagecount); }else{ htmlData.type='image'; } returndata; }, video:function(json,htmlData){ varii=json.imageinfo[0],data=extractData.image(json); data.info=mw.msg('schnark-imagepopups-info-video', ii.width,ii.height,ii.mime,formatSize(ii.size),formatTime(ii.duration)); data.attr=getDataAttr(htmlData.$video); //TODO über API auslesen data.sources=[]; htmlData.$video.find('source').each(function(){ var$source=$(this); data.sources.push($.extend(getDataAttr($source),{ src:$source.attr('src'), type:$source.attr('type'), 'data-width':data.thumbwidth, 'data-height':data.thumbheight })); }); if(data.sources.length===0){ data.sources.push({ src:data.urlFull, type:ii.mime, 'data-width':data.thumbwidth, 'data-height':data.thumbheight }); } data.tracks=[]; htmlData.$video.find('track').each(function(){ var$track=$(this); data.tracks.push($.extend(getDataAttr($track),{ kind:$track.attr('kind'), type:$track.attr('type'), src:$track.attr('src'), srclang:$track.attr('srclang'), label:$track.attr('label') })); }); returndata; }, threed:function(json,htmlData){ vardata=extractData.image(json); data.threedHash=htmlData.threedHash; returndata; } }, innerHTML={ image:function(data){ returnmw.html.element('img',{width:data.width,height:data.height,src:data.url}); }, paged:function(data){ returninnerHTML.image(data)+mw.html.element('div',{style:'text-align: center;'},newmw.html.Raw( mw.html.element('button',{'class':'prev', title:mw.msg('schnark-imagepopups-prev-page-tooltip')}, mw.msg('schnark-imagepopups-prev-page'))+ mw.html.element('span',{},newmw.html.Raw(mw.msg('schnark-imagepopups-current-page', mw.html.element('span',{'class':'currentPage'},data.data.page))))+ mw.html.element('button',{'class':'next', title:mw.msg('schnark-imagepopups-next-page-tooltip')}, mw.msg('schnark-imagepopups-next-page')) )); }, video:function(data){ varcontainerAttr={ 'class':'mediaContainer', style:'width:'+data.width+'px;' },videoAttr=$.extend(data.attr,{ style:'width:'+data.width+'px; height:'+data.height+'px;', 'class':'kskin', width:data.width, height:data.height, poster:data.url, controls:true, autoplay:true }),video=mw.html.element('video',videoAttr,newmw.html.Raw( data.data.sources.map(function(attr){ returnmw.html.element('source',attr); })+ data.data.tracks.map(function(attr){ mw.html.element('track',attr); }) )); returnmw.html.element('div',{'class':'containerParent'},newmw.html.Raw( mw.html.element('div',containerAttr,newmw.html.Raw(video)) )); }, threed:function(data){ returninnerHTML.image(data)+mw.html.element('div',{style:'text-align: center;'},newmw.html.Raw( mw.html.element('button',{'class':'threed-viewer'},mw.msg('schnark-imagepopups-3d-viewer')) )); } }, setEvents={ image:function(){}, paged:function($popup,data){ functionchangePage(diff){ varpage=Number($popup.find('.currentPage').text())+diff,$img,src; if(page<1||page>data.data.pages){ return; } $popup.find('button.prev').prop('disabled',page===1); $popup.find('button.next').prop('disabled',page===data.data.pages); $popup.find('.currentPage').text(page); $img=$popup.find('img'); src=$img.attr('src').replace(/page\d+/,'page'+page); $img.attr('src',''); $img.attr('src',src); } $popup.find('button.prev').on('click',function(){ changePage(-1); }).prop('disabled',data.data.page===1); $popup.find('button.next').on('click',function(){ changePage(/*+*/1); }).prop('disabled',data.data.page===data.data.pages); }, video:function($popup){ if(config.useMwEmbed){ mw.hook('wikipage.content').fire($popup.find('.containerParent')); } }, threed:function($popup,data){ $popup.find('button.threed-viewer').on('click',function(){ location.hash=data.data.threedHash; }); } }; functioninitL10N(l10n,keep){ vari,chain=mw.language.getFallbackLanguageChain(); keep=$.grep(mw.messages.get(keep),function(val){ returnval!==null; }); for(i=chain.length-1;i>=0;i--){ if(chain[i]inl10n){ mw.messages.set(l10n[chain[i]]); } } mw.messages.set(keep); } functionrandom(x){ vars=0,i,n=6; for(i=0;i<n;i++){ s+=Math.random(); } returnMath.round((s/n)*x); } functionformatSize(s){ vari=0,sizes=['size-bytes','size-kilobytes','size-megabytes','size-gigabytes']; while(s>1024&&i<sizes.length-1){ s/=1024; i++; } returnmw.msg(sizes[i],Math.round(s)); } functionformatTime(s){ varhh,mm,ss,colon=mw.msg('schnark-imagepopups-time-seperator'); if(s===undefined){ returnmw.msg('schnark-imagepopups-unknown-length'); } hh=Math.floor(s/3600); s-=hh*3600; mm=Math.floor(s/60); s-=mm*60; ss=Math.round(s); if(ss===60){ ss=0; mm++; } if(mm===60){ mm=0; hh++; } if(hh>0&&mm<10){ mm='0'+String(mm); } if(ss<10){ ss='0'+String(ss); } return(hh>0?hh+colon:'')+mm+colon+ss; } functiongetTopLeft(w,h){ w=$(window).width()-w-20; h=$(window).height()-h-120; if(w<0){ w=0; } if(h<0){ h=0; } return[random(h),random(w)]; } functiongetStyle(data){ vartopLeft=getTopLeft(data.width,data.height); return'z-Index:'+config.zIndex+++'; width:'+(data.width+10)+'px;'+ 'top:'+topLeft[0]+'px; left:'+topLeft[1]+'px;'; } functionmakeDraggable($element,$handle){ vardiff; functiondragHandler(e){ e.preventDefault(); e.stopPropagation(); $element.css({ top:e.clientY+diff.y, left:e.clientX+diff.x }); } $handle.on('mousedown',function(e){ varpos,$doc; if((e.which&&e.which!==1)||e.shiftKey||e.altKey||e.ctrlKey||e.metaKey){ return; } if($(e.target).is('a')){ return; } e.preventDefault(); pos=$element.position(); diff={x:pos.left-e.clientX,y:pos.top-e.clientY}; $doc=$(document); $doc.on('mousemove',dragHandler); $doc.on('mouseup',function(){ $doc.off('mousemove',dragHandler); }); }); } functionshowPopup(data,type){ var$popup=$( mw.html.element('div',{'class':'imagePopup',style:getStyle(data)},newmw.html.Raw( mw.html.element('div',{'class':'imagePopupTitleBar'},newmw.html.Raw( mw.html.element('span',{title:data.title,'class':'imagePopupTitle'},data.title)+ mw.html.element('a',{'class':'close-link', title:mw.msg('schnark-imagepopups-close-title'),href:'#'}, mw.msg('schnark-imagepopups-close')) ))+ innerHTML[type](data)+ mw.html.element('div',{'class':'imagePopupDesc mw-body-content mw-parser-output'},newmw.html.Raw(data.info)) ))); if(data.$desc){ $popup.find('.imagePopupDesc').prepend(data.$desc); } mw.hook('wikipage.content').fire($popup.find('.imagePopupDesc')); $popup.appendTo($('body')) .on('mousedown',function(){ $popup.css({zIndex:config.zIndex++}); }) .find('.close-link').on('click',function(){ varvideo=$popup.find('video')[0]; if(video&&video.pause){//Firefox plays even removed videos video.pause(); } $popup.remove(); returnfalse; }); makeDraggable($popup,$popup.find('.imagePopupTitleBar')); setEvents[type]($popup,data); } functionparseHTMLX($file){ varhref=$file.attr('href'), ext=/\.(\w+)(?:&|$)/.exec(href||''), type,data; ext=((ext&&ext[1])||'').toLowerCase(); if(!ext||!config.extensions[ext]){ returnfalse; } type=config.extensions[ext]; data=parseHTML[type]($file); data.type=type; returndata; } functiongetUrl($file){ varurl=$file.attr('href'); if(url){ returnurl; } url=$file.next('.thumbcaption').find('.magnify a').attr('href'); if(url){ returnurl; } url=$file.find('a').attr('href'); returnmw.util.getUrl(mw.config.get('wgFormattedNamespaces')[6]+':'+ decodeURIComponent(url.replace(/^.*\//,''))); } functiongetTitle(url){ vartitle=mw.util.getParamValue('title',url), re=newRegExp('^.*?(?:File|'+mw.util.escapeRegExp(mw.config.get('wgFormattedNamespaces')[6])+'):'); if(title){ returntitle.replace(re,'').replace(/_/g,' '); } returndecodeURIComponent(url).replace(re,'').replace(/_/g,' '); } functiongetSharedUrl(url){ varre=newRegExp( '(?:File|'+mw.util.escapeRegExp(encodeURIComponent(mw.config.get('wgFormattedNamespaces')[6]))+'):' ); returnurl.replace(re,'File:').replace(/^(?:(?:https?:)?\/\/[^\/]+)?\//,'https://commons.wikimedia.org/'); } functiongetDataAttr($el){ if($el.length===0){ return{}; } varraw=$el[0].attributes, attrs={}, i; for(i=0;i<raw.length;i++){ if(raw[i].nodeName.indexOf('data-')===0){ attrs[raw[i].nodeName]=raw[i].nodeValue; } } returnattrs; } functiongetDesc($file,title){ varalt, $desc=false, //try to find caption $caption=$file.next('.thumbcaption'); if($caption.length===0){ //next try: perhaps a gallery $caption=$file.parents('.thumb').next('.gallerytext').find('p'); } if($caption.length===0){ //next try: new gallery style $caption=$file.parents('.thumb').next('.gallerytextwrapper').find('.gallerytext p'); } if($caption.length===1){//found something? $desc=$caption.clone(); $desc.find('div.magnify').remove(); } if(!$desc){//last try alt=$file.find('img').attr('alt')||''; if(alt!==title&&alt!==''){ $desc=$('<p>').text(alt); } } return$desc; } functionmakeFileInfo(htmlData,data){ varinfo=[],localDesc; localDesc=mw.html.element('a',{href:htmlData.localUrl},mw.msg('schnark-imagepopups-local-desc')); if(data.localMissing){ localDesc=mw.msg('schnark-imagepopups-missing',localDesc); } info.push(localDesc); if(data.shared){ info.push(mw.html.element('a',{href:htmlData.sharedUrl},mw.msg('schnark-imagepopups-shared-desc'))); } info.push(mw.msg('schnark-imagepopups-info', mw.html.element('a',{href:data.urlFull},mw.msg('schnark-imagepopups-full-resolution')),data.info)); info=info.join(mw.msg('schnark-imagepopups-sep')); if(config.warnAboutMV){ info+='<br>'+mw.msg('schnark-imagepopups-mediaviewer'); } returninfo; } functionprocessFile($file){ varhtmlData=parseHTMLX($file),is; if(!htmlData){ returnfalse; } is=config.sizes[mw.user.options.get('imagesize')||2]||[800,600]; $.getJSON(mw.util.wikiScript('api'),getParam[htmlData.type](htmlData,is[0],is[1])).then(function(json){ varp,data; if(!json||!json.query||!json.query.pages){ return; } p=json.query.pages[0]; if(!p){ return; } data=extractData[htmlData.type](p,htmlData); showPopup({ title:htmlData.title, url:data.urlThumb, $desc:htmlData.$desc, info:makeFileInfo(htmlData,data), width:data.thumbwidth, height:data.thumbheight, data:data },htmlData.type); }); returntrue; } functiononImageClick(e){ /*jshint validthis: true*///Event-Handler if((e.which&&e.which!==1)||e.shiftKey||e.altKey||e.ctrlKey||e.metaKey){ return; } if(processFile($(this))){ e.preventDefault(); } } functionrun($content){ if(config.replaceTMHPopup&&mw.loader.getState('mw.PopUpMediaTransform')){ mw.loader.using('mw.PopUpMediaTransform').then(function(){ $content.find('.PopUpMediaTransform a').off('click').on('click',onImageClick); }); } $content.find('a.image').filter(':has(img)').on('click',onImageClick); } functioninit(){ if(mw.config.get('wgMediaViewerOnClick')){ config.warnAboutMV=true; mw.config.set('wgMediaViewerOnClick',false); } initL10N(l10n,['size-bytes','size-kilobytes','size-megabytes','size-gigabytes']); mw.util.addCSS(config.css); mw.hook('wikipage.content').add(run); } mw.hook('userjs.load-script.imagepopups').fire(config); mw.loader.using(['mediawiki.language','mediawiki.util','user.options']).then(init); })(jQuery,mediaWiki); //</nowiki>