MediaWiki:GalleryPicker.js

From Wikimedia Commons, the free media repository
Jump to navigation Jump to search
Note: After saving, you have to bypass your browser's cache to see the changes. Internet Explorer: press Ctrl-F5, Mozilla: hold down Shift while clicking Reload (or press Ctrl-Shift-R), Opera/Konqueror: press F5, Safari: hold down Shift + Alt while clicking Reload, Chrome: hold down Shift while clicking Reload.
$(function(){
	// only run on gallery pages
	if(mw.config.get('wgNamespaceNumber')!=2) return;
	
	var srcTagged = '//upload.wikimedia.org/wikipedia/commons/thumb/0/03/Crystal_Clear_action_bookmark.png/20px-Crystal_Clear_action_bookmark.png'
	  , srcUntagged = '//upload.wikimedia.org/wikipedia/commons/thumb/0/02/Crystal_Clear_action_bookmark_Silver.png/20px-Crystal_Clear_action_bookmark_Silver.png'
	  , exportPage = 'User:'+mw.config.get('wgUserName')+'/GalleryPicker/'+mw.config.get('wgPageName')+'/export'
	  , btnSave = $('<button>Save Picks</button>').css('margin','3px')
	  , btnLoad = $('<button>Load Picks</button>').css('margin','3px')
	  , allTitles={}
	  , marker='<!--GALLERYPICKER_DATA'
	  , editToken = mw.user.tokens.get( 'csrfToken' )
	  , ls = window.localStorage;	
	
	// need localstorage
	if(!ls) return;
	
	// load picks function
	function loadPicks() { //query&prop=revisions&titles=API&rvprop=timestamp|user|comment|content&format=json
		btnLoad.prop('disabled', true);
		$('#gallerypickerStatus').text('Loading...')

		// fetch raw text
    	$.ajax({
        	url: mw.util.wikiScript( 'index' ),
        	data: {
            	action: 'raw',
            	title: exportPage
        	},
        	type: 'POST',
        	success: function( data ) {
                var i, title, tagged, lines, picks, json=null;
            	if ( data  ) {
            		lines=data.split('\n');
                	for(i=0;i<lines.length;++i){
                		if(lines[i]==marker) {
                			json=lines[i+1]; break;
                		}
                	}
                	if(json) {
                		try {
                			picks=JSON.parse(json);
                		} catch(e) {
                			$('#gallerypickerStatus').text('Error in saved picks section.');
                			btnLoad.prop('disabled', false);
                			return;
                		}

						// delete all current data
						for( title in allTitles ) {
		  					ls.removeItem('GT_'+title);
						}
						
						// set loaded picks
						for( title in allTitles ) {
							if(title in picks) {
								ls.setItem('GT_'+title,picks[title]);
								tagged=(picks[title].substr(0,1)=='+');
							} else { 
								tagged=false; 
							}
							allTitles[title].attr('src',tagged?srcTagged:srcUntagged);
						}
						
                		$('#gallerypickerStatus').text('Picks loaded successfully.');
                	} else {
                		$('#gallerypickerStatus').text('No Picks loaded.');
                	}
            	} else {
	            	$('#gallerypickerStatus').text('Failed to load picks (ERR2)' );
            	}
            	btnLoad.prop('disabled', false);
        	},
        	error: function( xhr ) {
            	$('#gallerypickerStatus').text('Failed to load picks (ERR1)' );
            	btnLoad.prop('disabled', false);
        	}
    	});
	}
	
	// save picks function
	function savePicks() {
		btnSave.prop('disabled', true);
		$('#gallerypickerStatus').text('Saving...')

		// build content
		var i, data, title, picks={}, content='<gallery>\n';
		for( title in allTitles ) {
		  	data=ls.getItem('GT_'+title)||'-'
		  	if(data!='-') {
		  		content+='File:'+title+'|'+data.substr(1)+'\n';
		  		picks[title]=data;
		  	}
		}
		content+='</gallery>\n\n' + marker + '\n' + JSON.stringify(picks) + '\n-->';
		
		// call API
    	$.ajax({
        	url: mw.util.wikiScript( 'api' ),
        	data: {
            	format: 'json',
            	action: 'edit',
            	title: exportPage,
            	summary: 'Saving Picks',
            	text: content,
            	token: editToken
        	},
        	dataType: 'json',
        	type: 'POST',
        	success: function( data ) {
            	if ( data && data.edit && data.edit.result == 'Success' ) {
                	$('#gallerypickerStatus').text('Picks saved successfully.')
            	} else if ( data && data.error ) {
                	$('#gallerypickerStatus').text('Error: API returned error code "' + data.error.code + '": ' + data.error.info );
            	} else {
	            	$('#gallerypickerStatus').text('Failed to save picks (ERR2)' );
            	}
            	btnSave.prop('disabled', false);
        	},
        	error: function( xhr ) {
            	$('#gallerypickerStatus').text('Failed to save picks (ERR1)' );
            	btnSave.prop('disabled', false);
        	}
    	});
	}

	// add star buttons
	$('.gallerybox .thumb')
		.css('position','relative')
		.each(function(i,e){
			var title=$(e).find('a.image').eq(0).attr('href').substr(11) // cut off '/wiki/File:'
			  , data=ls.getItem('GT_'+title)||'-'
			  , tagged=(data.substr(0,1)=='+')
			  , img=$('<img/>').attr('src',tagged?srcTagged:srcUntagged).css({position:'absolute',top:'3px',right:'3px',background:'none',cursor:'pointer'}).appendTo($(e));
			
			allTitles[title]=img;
			img.click(function(e){
				tagged=!tagged;
				img.attr('src',tagged?srcTagged:srcUntagged);
				data=(tagged?'+':'-')+data.substr(1);
				ls.setItem('GT_'+title,data);
				e.preventDefault();
			})
		});
		
	// add user interface
	$('#gallerypickerLink').hide();
	$('#gallerypickerMenu')
		.prepend(btnSave.click(savePicks))
		.prepend(btnLoad.click(loadPicks))
		.show();
	$('#gallerypickerExport').append( $('<a></a>').text(exportPage).attr('href','/wiki/'+exportPage) );
});