MediaWiki:Gadget-DragNDrop.js
From Dashboard samenwerking Wijchen
Revision as of 10:58, 1 February 2017 by Admin (talk | contribs) (Created page with "→(c) 2015 by Magnus Manske Copy from User:Magnus Manske/dragref.js To use, enable the gadget in your preferences: var mw_api = new mw.Api(); var this_q = mw.config.g...")
Note: After saving, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
- Opera: Go to Menu → Settings (Opera → Preferences on a Mac) and then to Privacy & security → Clear browsing data → Cached images and files.
/* (c) 2015 by Magnus Manske Copy from [[User:Magnus Manske/dragref.js]] To use, enable the gadget in your preferences */ var mw_api = new mw.Api(); var this_q = mw.config.get('wgTitle') ; var li_max_width = '400px' ; var wiki_lang = '' ; var wiki_project = '' ; function genericAPIaction ( json , callback ) { if ( (json.action||'') == 'wbcreateclaim' ) json.summary = 'Using #dragref.js' ; mw_api.postWithEditToken ( json ) .done ( callback ) .fail ( function () { console.log ( json ) ; alert ( "API call failed, check JavaScript console for original request!" ) ; } ) ; } function addDraggedRef ( q , params ) { var json = { action:'wbsetreference', statement:params.statement, snaks:JSON.stringify(params.snaks), format:'json' } ; genericAPIaction ( json , function ( d1 ) { var h = "<div>Dropped reference added!</div>" ; if ( typeof d1.error != 'undefined' ) h = "<div>Ah, that didn't work...<br/><small>"+d1.error.info+"</small></div>" ; $(params.target).find('div.wikibase-statementview-references-container div.wikibase-statementview-references-heading').append(h); } ) ; } function copyReferenceToStatement ( q , statement , refhash , target ) { $.get ( '/w/api.php' , { action:'wbgetentities', format:'json', ids:q } , function ( d ) { var claims = d.entities[q].claims ; var snaks = '' ; $.each ( claims , function ( prop , v0 ) { if ( v0.id == statement ) return ; // No self-drag! $.each ( v0 , function ( k1 , v1 ) { if ( typeof v1.references == 'undefined' ) return ; $.each ( v1.references , function ( k2 , v2 ) { if ( v2.hash != refhash ) return ; snaks = v2.snaks ; } ); } ); } ); if ( snaks === '' ) return ; // Reference hash not found var params = { statement : statement , snaks : snaks , target : target , token : 'dummy' }; addDraggedRef ( q , params ) ; } , 'json' ); } function dropWikidataSource ( event , ui ,target , dragged ) { var q = '' ; var statement = '' ; $.each ( target.classList , function ( k , v ) { var m = v.match ( /^wikibase-statement-(Q\d+)(.+)$/i ) ; if ( m === null ) return ; q = m[1].replace(/^q/,'Q') ; statement = m[1]+m[2] ; } ); if ( q === '' || statement === '' ) return ; // Something went wrong var refhash = '' ; $.each ( dragged.classList , function ( k , v ) { var m = v.match ( /^wikibase-referenceview-(.+)$/ ) ; if ( m === null ) return ; refhash = m[1] ; } ); if ( refhash === '' ) return ; // Something went wrong copyReferenceToStatement ( q , statement , refhash , target ) ; } function dropWikiSource ( event , ui ,target,dragged) { var rt = $(dragged).find ( 'span.reference-text' ) ; if ( rt.length === 0 ) return ; // Weird reference rt = $(rt[0]) ; var q = '' ; var statement = '' ; $.each ( target.classList , function ( k , v ) { var m = v.match ( /^wikibase-statement-(Q\d+)(.+)$/i ) ; if ( m === null ) return ; q = m[1].replace(/^q/,'Q') ; statement = m[1]+m[2] ; } ); if ( q === '' || statement === '' ) return ; // Something went wrong var params = { statement : statement , snaks:{} , target:target , token:'dummy' } ; var a = $(rt.find('a.external.text')) ; if ( a.length == 1 ) { // External link var title = $(a[0]).text() ; title = title.replace ( /^"(.+)"$/ , "$1" ) ; params.snaks.P854 = [{ snaktype:'value',property:'P854',datavalue:{value:$(a[0]).attr('href'),type:'string'},datatype:'url' }] ; params.snaks.P1476 = [{ snaktype:'value',property:'P1476',datavalue:{value:{language:wiki_lang,text:title},type:'monolingualtext'},datatype:'monolingualtext' }] ; var retrieved = $(rt.find('span.reference-accessdate span.nowrap')) ; if ( retrieved.length == 1 ) { var s = $(retrieved[0]).text() ; var m = s.match(/^(\d\d\d\d-\d\d-\d\d)$/) ; if ( m !== null ) { var time = '+'+m[1]+'T00:00:00Z' ; params.snaks.P813 = [{ snaktype:'value',property:'P813',datavalue:{value:{time:time,timezone:0,before:0,after:0,precision:11,calendarmodel:'http://www.wikidata.org/entity/Q1985727'},type:'time'},datatype:'time' }] ; } } } else { alert ( "Sorry, that type of reference is not supported yet" ) ; return ; } addDraggedRef ( q , params ) ; } function dropWikiSourceISBN ( event , ui ,target,dragged) { var a = $(dragged).find ( 'a.mw-magiclink-isbn' ) ; if ( a.length != 1 ) return ; // Weird reference a = $(a[0]) ; var isbn = a.text() ; isbn = isbn.replace ( /[ -]/g , '' ) ; var prop = 'P212' ; var m = isbn.match ( /([0-9-]{13})/ ) ; if ( m === null ) { m = isbn.match ( /([0-9-]{10})/ ) ; prop = 'P957' ; } if ( m === null ) { alert ( "Unsupported ISBN" ) ; return ; } isbn = m[1] ; var q = '' ; var statement = '' ; $.each ( target.classList , function ( k , v ) { var m = v.match ( /^wikibase-statement-(Q\d+)(.+)$/i ) ; if ( m === null ) return ; q = m[1].replace(/^q/,'Q') ; statement = m[1]+m[2] ; } ) if ( q === '' || statement === '' ) return ; // Something went wrong var params = { statement : statement , snaks:{} , target:target } ; params.snaks[prop] = [{ snaktype:'value',property:prop,datavalue:{value:isbn,type:'string'},datatype:'string' }] ; addDraggedRef ( q , params ) ; } function addStatementDialog ( o ) { $('#add_statement_dialog').remove() ; function addStatement () { var p = $('#add_statement_dialog_prop').val().toUpperCase() ; if ( !p.match(/^P\d+$/) ) { alert ( "Pxxx value for property required!" ) ; return false ; } var h = "<div class='wikibase-statementgroupview listview-item'>" ; var json = {} ; if ( o.type == 'item' ) { var q = o.items[0].q ; h += p + ": " + q + " (reload page to show this properly)" ; json = { action:'wbcreateclaim' , entity:this_q , snaktype:'value' , property:p , value:{'entity-type':'item','numeric-id':q.replace(/Q/,'')} } ; json.value = JSON.stringify ( json.value ) ; } h += '</div>' ; genericAPIaction ( json , function ( d ) { // console.log ( d ) ; $('#mw-content-text div.wikibase-statementgrouplistview').append ( h ) ; } ) ; $( "#add_statement_dialog" ).dialog( "close" ); } var h = '<div id="add_statement_dialog" title="Add a new statement">' ; if ( o.type == 'item' ) { var q = o.items[0].q ; h += "<p><a target='_blank' href='/wiki/" + q + "'>" + q + "</a>: " + o.items[0].label + "</p>" ; } h += "<p>Property: <input type='text' id='add_statement_dialog_prop' /></p>" ; if ( o.type == 'item' ) { h += "<div id='add_statement_dialog_suggestions' style='max-height:300px;overflow:auto'><i>Loading suggestions...</i></div>" ; var q = o.items[0].q ; var sparql = '' ; sparql += "PREFIX wd: <http://www.wikidata.org/entity/>\n" ; sparql += "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n" ; sparql += "SELECT ?p (count(?h) as ?cnt) WHERE { ?h ?p wd:"+q+" . OPTIONAL { ?h rdfs:label ?hl filter (lang(?hl) = 'en') } } group by ?p having(?cnt>1) order by desc(?cnt)" ; $.get ( '//query.wikidata.org/bigdata/namespace/wdq/sparql' , { format:'json', query:sparql } , function ( d ) { var patt = /^https{0,1}:\/\/www.wikidata.org\/prop\/direct\/(P\d+)$/ ; var props = [] ; $.each ( (d.results.bindings||[]) , function ( k , v ) { var m = patt.exec ( v.p.value ) ; if ( m == null ) return ; if ( props.length < 50 ) props.push ( m[1] ) ; } ) ; var pre = '' ; if ( props.length == 0 ) { pre = '<p>Sorry, no suggestions found! Maybe these will help:</p>' ; props = ['P31','P279','P361','P131'] ; } $.get ( '/w/api.php' , { action:'wbgetentities', ids:props.join('|'), format:'json' } , function ( d2 ) { var prop2label = {} ; $.each ( (d2.entities||[]) , function ( p , v ) { $.each ( (v.labels||{}) , function ( lang , v2 ) { if ( typeof prop2label[p] == 'undefined' ) prop2label[p] = v2.value ; if ( lang == 'en' ) prop2label[p] = v2.value ; } ) ; } ) ; var h = pre ; $.each ( props , function ( dummy , p ) { h += "<p><a href='#' class='add_statement_dialog_suggestion' prop='"+p+"'>" ; h += (prop2label[p]||p) ; h += "</a> (" + p + ")</p>" ; } ) ; $('#add_statement_dialog_suggestions').html ( h ) ; $('#add_statement_dialog_suggestions a.add_statement_dialog_suggestion').click ( function () { var a = $(this) ; var p = a.attr('prop') ; $('#add_statement_dialog_prop').val ( p ) ; addStatement() ; // Click OK } ) ; } , 'json' ) ; } , 'json' ) ; } h += "</div>" ; $('body').append ( h ) ; $('#add_statement_dialog_prop').focus() ; $( "#add_statement_dialog" ).dialog({ resizable: true, height:300, modal: true, buttons: { "Add statement": addStatement , Cancel: function() { $( this ).dialog( "close" ); } } }); } function dropImage ( image ) { var json = { action:'wbcreateclaim' , entity:this_q , snaktype:'value' , property:"P18" , value:image.replace(/_/g,' ') } ; json.value = JSON.stringify ( json.value ) ; genericAPIaction ( json , function ( d ) { var h = "<div class='wikibase-statementgroupview listview-item'>" ; h += "Image added, reload to show.</div>" ; $('#mw-content-text div.wikibase-statementgrouplistview').append ( h ) ; } ) ; } function dropCommonsCat ( commonscat ) { var json = { action:'wbcreateclaim' , entity:this_q , snaktype:'value' , property:"P373" , value:commonscat.replace(/_/g,' ') } ; json.value = JSON.stringify ( json.value ) ; genericAPIaction ( json , function ( d ) { var h = "<div class='wikibase-statementgroupview listview-item'>" ; h += "Commons category added, reload to show.</div>" ; $('#mw-content-text div.wikibase-statementgrouplistview').append ( h ) ; } ) ; } function dropCoord ( lat , lon ) { var json = { action:'wbcreateclaim' , entity:this_q , snaktype:'value' , property:"P625" , value:{"latitude":lat,"longitude":lon,"globe":"http://www.wikidata.org/entity/Q2","precision":0.000001} } ; json.value = JSON.stringify ( json.value ) ; genericAPIaction ( json , function ( d ) { var h = "<div class='wikibase-statementgroupview listview-item'>" ; h += "Coordinates added, reload to show.</div>" ; $('#mw-content-text div.wikibase-statementgrouplistview').append ( h ) ; } ) ; } function dropWikiLink(event,ui,target,dragged) { var page = $(dragged).attr('page') ; // Image if ( $(dragged).hasClass('image') && $(dragged).find('img').length > 0 ) { return dropImage ( page.replace ( /^.+?:/ , '' ) ) ; } // CommonsCat if ( $(dragged).attr('type') == 'commonscat' ) { var commonscat = $(dragged).attr('data') ; return dropCommonsCat ( decodeURIComponent(commonscat) ) ; } // Coord if ( $(dragged).attr('type') == 'coord' ) { var m = $(dragged).attr('data').split('/') ; return dropCoord ( m[0]*1 , m[1]*1 ) ; } // Follow redirect $.getJSON ( '//'+wiki_lang+'.'+wiki_project+'.org/w/api.php?callback=?' , { action:'query', redirects:1, prop:'pageprops', titles:page, format:'json' } , function ( d ) { if ( typeof d.query!='undefined' && typeof d.query.redirects!='undefined' && d.query.redirects.length>0 ) { $.each ( d.query.redirects , function ( k , v ) { if ( v.from.replace(/_/g,' ') != page ) return ; page = v.to ; return false ; } ) ; } // 'page' is now the redirected (if applicable) page title if ( typeof d.query == 'undefined' ) return ; if ( typeof d.query.pages == 'undefined' ) return ; var q = '' ; $.each ( d.query.pages , function ( k , v ) { if ( typeof v.pageprops == 'undefined' ) return ; if ( typeof v.pageprops.wikibase_item == 'undefined' ) return ; q = v.pageprops.wikibase_item ; } ) ; if ( !q.match(/^Q\d+$/) ) return ; // No Wikidata item addStatementDialog ( { items:[{q:q,label:page}] , type:'item' } ) ; } ) ; } function addDroppable () { // Drop statements $('#content').droppable ( { accept: function (dropped) { if ( $(dropped).hasClass('wd_dragref_wiki_link') ) return true ; return false ; } , hoverClass: "wikibase-statementview-droptarget", drop: function( event, ui ) { var target = $(this)[0] ; var dragged = $(ui.draggable)[0] ; if ( $(dragged).hasClass('wd_dragref_wiki_link') ) dropWikiLink(event,ui,target,dragged) ; } } ) ; // Drop references $('div.wikibase-statementview').droppable({ accept: function (dropped) { if ( $(dropped).hasClass('wikibase-referenceview') ) return true ; if ( $(dropped).hasClass('wd_dragref_wiki_ref') ) return true ; if ( $(dropped).hasClass('wd_dragref_wiki_isbn') ) return true ; return false ; } , hoverClass: "wikibase-statementview-droptarget", drop: function( event, ui ) { var target = $(this)[0] ; var dragged = $(ui.draggable)[0] ; if ( $(dragged).hasClass('wikibase-referenceview') ) dropWikidataSource(event,ui,target,dragged) ; if ( $(dragged).hasClass('wd_dragref_wiki_ref') ) dropWikiSource(event,ui,target,dragged) ; if ( $(dragged).hasClass('wd_dragref_wiki_isbn') ) dropWikiSourceISBN(event,ui,target,dragged) ; } } ); } function addDragDropWiki () { // Links $('#wb_dragref_mobileview a').each ( function () { var a = $(this) ; if ( a.parents('ol.references').length > 0 ) return ; // Don't do references var href = a.attr('href') ; if ( a.hasClass('external') ) { // TODO drag URLs as references var data ; var m = href.replace(/_/g,' ').match ( /\bgeohack\.php.*params=([0-9\.+\-]+) ([NS]) ([0-9\.+\-]+) ([EW])/ ) ; if ( m !== null ) { var lat = m[1] * 1 ; var lon = m[3] * 1 ; if ( m[2] == 'S' ) lat = -lat ; if ( m[2] == 'W' ) lon = -lon ; data = lat + '/' + lon ; } if ( typeof data == 'undefined' ) { var m = href.match ( /https{0,1}:\/\/commons.wikimedia.org\/wiki\/Category:([^\?]+)/ ) ; if ( m == null ) return ; a.attr('type','commonscat') ; a.attr('data',m[1]) ; } else { a.attr('type','coord') ; a.attr('data',data) ; } } else { // Drag wiki links as statements if ( !href.match(/^\/wiki\//) ) return ; // No internal link if ( a.hasClass ( 'mw-magiclink-isbn' ) ) return ; var page = decodeURIComponent ( href.substr(6).replace(/_/g,' ') ) ; a.attr('page',page) ; } if ( typeof a.attr('title') == 'undefined' ) a.attr('title',"Drag'n'drop to add as new statement") ; else a.attr ( { title: a.attr('title')+"; drag'n'drop to add as new statement" } ) ; a.css({cursor:'grab',hover:'background-color:#6094DB'}) ; a.addClass('wd_dragref_wiki_link') ; a.draggable({ zIndex: 1099, appendTo: "body", revert: false, cursor: "dragging", helper: "clone" }); } ) ; // References $('#wb_dragref_mobileview ol.references li').css({'max-width':li_max_width}).each ( function () { var li = $(this) ; li.css({cursor:'grab'}) ; li.addClass('wd_dragref_wiki_ref') ; li.draggable({ zIndex: 1099, appendTo: "body", revert: false, cursor: "dragging", helper: "clone" }); } ) ; // Ref ISBNs $('#wb_dragref_mobileview li a.mw-magiclink-isbn').each ( function () { var li = $($(this).parents('li').get(0)) ; li.css({cursor:'grab','max-width':li_max_width}) ; li.addClass('wd_dragref_wiki_isbn') ; li.draggable({ zIndex: 1099, appendTo: "body", revert: false, cursor: "dragging", helper: "clone" }); } ) ; } function addWikiSourceLinks () { $.each ( [ 'wikipedia','wikibooks','wikinews','wikiquote','wikisource','wikivoyage' ] , function ( dummy , project ) { var group = 'div[data-wb-sitelinks-group="'+project+'"]' ; $(group+' span.wikibase-sitelinkview-page a').each ( function () { var a = $(this) ; var lang = a.attr('hreflang') ; var title = a.attr('href').replace(/^.*\/wiki\//,'').replace(/_/g,' ') ; //text() ; if ( typeof title == 'undefined' || title == '' ) return ; // console.log ( title ) ; var h = "<span style='display:table-cell;padding-left:10px;font-size:8pt'>[<a href='#' class='wb_dragref_wikilink' lang='"+lang+"'>ref</a>]</span>" ; a.parent().parent().parent().append(h) ; a.parent().parent().parent().find('a.wb_dragref_wikilink').attr('title',title) ; } ) ; $(group+' a.wb_dragref_wikilink').click ( function () { var o = $(this) ; var lang = o.attr('lang') ; var title = decodeURIComponent ( o.attr('title') ) ; wiki_lang = lang ; wiki_project = project ; var h = "<div id='wb_dragref_site_overlay' style='overflow:auto;position:fixed;right:0px;top:0px;bottom:0px;width:"+li_max_width+";z-index:1050;background-color:white;margin:5px;padding:2px;border-left:1px solid black'>" ; h += "<div style='text-align:right'><a href='#' onclick='$(\"#wb_dragref_site_overlay\").remove();return false'>X</a></div>" ; h += "<h2>" + title + "</h2>" ; h += "<div id='wb_dragref_mobileview'><i>Loading...</i></div>" ; h += "</div>" ; $('#wb_dragref_site_overlay').remove() ; $('body').append(h) ; $.getJSON ( 'https://'+lang+'.'+project+'.org/w/api.php?callback=?' , { action:'parse', page:title, format:'json', prop:'text', mobileformat:1 } , function ( d ) { $('#wb_dragref_mobileview').html ( d.parse.text['*'] ) ; addDragDropWiki() ; } ) ; } ) ; } ) ; } function init () { addWikiSourceLinks() ; $("<style type='text/css'>div.wikibase-statementview-droptarget{ background-color:#FFFFC8;} </style>").appendTo("head"); $('div.wikibase-referenceview').draggable({ zIndex: 99, revert: false, helper: "clone" }); addDroppable() ; } init();