// [[Category:User scripts|Legendary]] <nowiki>
function Legendary() {
var messages = {
'en': {
'legendary': 'Legendary',
'button': 'Get most significant colors from this image',
'getting-image-info': "Getting image information.",
'analyze': 'Analyze',
'insert': 'Insert',
'cancel': 'Cancel',
'no-text': 'No colors could be found in the image.'
}
};
var loadingGifUrl = 'https://upload.wikimedia.org/wikipedia/commons/4/42/Loading.gif';
var lang = mw.config.get( 'wgUserLanguage' );
var Legendary = {};
Legendary.Dialog = function legendaryDialog( config ) {
Legendary.Dialog.parent.call( this, config );
};
OO.inheritClass( Legendary.Dialog, OO.ui.ProcessDialog );
Legendary.Dialog.static.name = 'LegendaryDialog';
Legendary.Dialog.static.title = getMsg( 'legendary' );
Legendary.Dialog.static.size = 'full';
Legendary.Dialog.static.actions = [
{ label: getMsg( 'analyze' ), action: 'analyze', flags: [ 'primary', 'progressive' ] },
{ label: getMsg( 'insert' ), action: 'insert' },
{ label: getMsg( 'cancel' ), flags: [ 'safe', 'close' ] }
];
Legendary.Dialog.prototype.getBodyHeight = function () {
return 600;
};
hasCanvas = function() {
var c = document.createElement("canvas");
var val = false;
try {
val = !!((typeof c.getContext == "function") && c.getContext("2d"));
} catch(e) {}
return function() {
return val;
};
};
hasCanvasImageData = function() {
var c = document.createElement("canvas");
var val = false;
var ctx;
try {
if (typeof c.getContext == "function" && (ctx = c.getContext("2d"))) {
val = (typeof ctx.getImageData == "function");
}
} catch(e) {}
return function() {
return val;
};
};
isIE = function() {
return !!document.all && !!window.attachEvent && !window.opera;
};
Legendary.Dialog.prototype.populateTestData = function ( values ) {
values[16777215] = 129398; // rgb(255,255,255) #FFFFFF
values[14871806] = 87658; // rgb(226,236,254) #E2ECFE
values[15066597] = 34031; // rgb(229,229,229) #E5E5E5
values[16777185] = 28879; // rgb(255,255,225) #FFFFE1
values[12829635] = 5197; // rgb(195,195,195) #C3C3C3
values[4147404] = 3042; // rgb(63,72,204) #3F48CC
values[8355711] = 2615; // rgb(127,127,127) #7F7F7F
};
Legendary.Dialog.prototype.populateData = function ( values ) {
try {
var canvas = this.$toAnalyzeCanvas;
var w=parseInt(canvas.offsetWidth); // this.$toAnalyzeImg.width();
var h=parseInt(canvas.offsetHeight); //this.$toAnalyzeImg.height();
var ctx = canvas.getContext("2d");
var dataDesc = ctx.getImageData(0, 0, w, h);
var data = dataDesc.data;
var w4 = w*4;
var y = h;
do {
var offsetY = (y-1)*w4;
var x = w;
do {
var offset = offsetY + (x*4-4);
var color = (data[offset]*256+data[offset+1])*256+data[offset+2];
values[color]++;
} while (--x);
} while (--y);
} catch ( e ) {
console.log( e );
this.populateTestData(values);
}
};
Legendary.Dialog.prototype.convertToCanvas = function (img) {
var imageIsCanvas = (img.tagName == "CANVAS");
if (imageIsCanvas && isIE()) {
// Tried to process a canvas element but browser is IE
return false;
}
var canvas, ctx;
if (hasCanvas()) {
canvas = document.createElement("canvas");
ctx = canvas.getContext("2d");
var w = parseInt(img.offsetWidth);
var h = parseInt(img.offsetHeight);
canvas.width = w;
canvas.height = h;
canvas.style.width = w+"px";
canvas.style.height = h+"px";
ctx.drawImage(img,0,0,w,h);
// copy properties and stuff from the source image
canvas.title = img.title;
if (!imageIsCanvas) canvas.alt = img.alt;
canvas.className = img.className;
canvas.setAttribute("style", img.getAttribute("style"));
canvas.cssText = img.cssText;
canvas.name = img.name;
canvas.tabIndex = img.tabIndex;
canvas.id = img.id;
return canvas;
}
return img;
};
Legendary.Dialog.prototype.initialize = function () {
Legendary.Dialog.parent.prototype.initialize.apply( this, arguments );
this.$toAnalyzeImg = $( '<img>' )
.attr( 'crossorigin', 'anonymous')
.css( 'width', '100%' );
this.$toAnalyzeImgWrap = $( '<div>' )
.css( 'width', '50%' )
.append( this.$toAnalyzeImg );
this.$toAnalyzeTextarea = $( '<textarea>' )
.css( { width: '50%' } );
this.$toAnalyzePanel = $( '<div>' )
.css( { display: 'flex', height: '90%' } )
.append( this.$toAnalyzeImgWrap, this.$toAnalyzeTextarea );
this.$body.append( this.$toAnalyzePanel );
this.$progressBar = new OO.ui.ProgressBarWidget( { progress: 0 } );
var fieldset = new OO.ui.FieldsetLayout();
fieldset.addItems( [
new OO.ui.FieldLayout( this.$progressBar, {
label: 'Image Analysis',
align: 'top'
} ),
] );
this.$body.append( fieldset.$element );
};
Legendary.Dialog.prototype.getSetupProcess = function ( data ) {
var dialog = this;
return Legendary.Dialog.super.prototype.getSetupProcess.call( this, data )
.next( function () {
dialog.pushPending();
new mw.Api().get( {
action: 'query',
prop: 'imageinfo',
titles: mw.config.get( 'wgPageName' ),
iiprop: 'url',
iiurlwidth: 1500
} )
.done( dialog.setImg.bind( dialog ) )
.fail( dialog.setImg.bind( dialog ) )
.always( function () { dialog.popPending(); } );
}, this );
};
Legendary.Dialog.prototype.setCanvas = function( dialog ) {
this.$toAnalyzeCanvas = this.convertToCanvas( this.$toAnalyzeImg[0] );
this.$toAnalyzeImgWrap
.append( this.$toAnalyzeCanvas );
this.$toAnalyzeImg.remove();
};
Legendary.Dialog.prototype.setImg = function( response ) {
var dialog = this;
// Get thumb URL.
var pageId = Object.keys( response.query.pages )[ 0 ];
var imageUrl = response.query.pages[ pageId ].imageinfo[ 0 ].thumburl;
var srcResult = dialog.$toAnalyzeImg.attr( 'src', imageUrl );
dialog.$toAnalyzeImg
.one("load", dialog.setCanvas.bind( dialog ) )
.each( function() {
if(this.complete) {
$(this).load(); // For jQuery < 3.0
// $(this).trigger('load'); // For jQuery >= 3.0
}
});
};
function hexColor( color ) {
return "#"+("000000"+color.toString(16).toUpperCase()).slice(-6);
}
function rgbColor ( color ) {
var rgb = color;
var b = rgb % 256; rgb = (rgb-b)/256;
var g = rgb % 256; rgb = (rgb-g)/256;
var r = rgb % 256;
return "rgb("+ r+","+ g+","+ b +")";
}
Legendary.Dialog.prototype.rankColors = function( response ) {
var dialog = this;
this.$progressBar.setProgress( 1/27*100 );
// init
var values = [];
var j=256*256*256; do {
values[j] = 0;
} while (--j > 0);
this.$progressBar.setProgress( 2/27*100 );
// get data
dialog.populateData( values );
// get maximum
var max = 0;
j=256*256*256; do {
if (max < values[j]) max=values[j];
if (values[j] > 0) console.log("\t\tvalues["+ j +"] = "+ values[j] +"; /"+"/ " + rgbColor( j ) +" "+ hexColor( j ));
} while (--j > 0);
this.$progressBar.setProgress( 3/27*100 );
// output top 25
var txt="";
var val = 0;
var i=0; do {
var color = 0;
val = 0;
j=256*256*256; do {
if (val < values[j]) { val=values[j]; color=j; }
} while (--j > 0);
var pct = Math.round((val / max) * 100);
console.log(color +" : "+val +" : "+ pct +" : "+ rgbColor( color ) +" "+ hexColor( color ));
if (val > 0) {
txt += "* {{legend|"+ hexColor( color ) +"|"+ hexColor( color ) +" "+ rgbColor( color ) +" "+pct+"%}}\n";
}
this.$progressBar.setProgress( (3+i)/27*100 );
values[color]=-1;
} while (i++ < 25 && val > 0);
this.$progressBar.setProgress( 100 );
dialog.$toAnalyzeTextarea.val( "Significant Colors:\n"+txt );
};
Legendary.Dialog.prototype.getActionProcess = function ( action ) {
var dialog = this;
return Legendary.Dialog.super.prototype.getActionProcess.call( this, action )
.next( function () {
if ( action === 'analyze' ) {
dialog.rankColors( dialog );
} else if ( action === 'insert' ) {
textSelectionOpts = {
peri: dialog.$toAnalyzeTextarea.val(),
replace: true,
selectPeri: false
};
$( '#wpTextbox1' ).textSelection( 'encapsulateSelection', textSelectionOpts );
dialog.close();
}
} );
};
function getMsg( msg ) {
if ( messages[ lang ] !== undefined && messages[ lang ][ msg ] !== undefined ) {
return messages[ lang ][ msg ];
} else if ( messages.en[ msg ] !== undefined ) {
return messages.en[ msg ];
} else {
return '⟨' + msg + '⟩';
}
}
function main() {
var legendaryDialog = new Legendary.Dialog();
OO.ui.getWindowManager().addWindows( [ legendaryDialog ] );
$( '#wpTextbox1' ).on( 'wikiEditor-toolbar-doneInitialSections', function () {
var legendaryButtonDetails = {
type: 'button',
icon: 'https://upload.wikimedia.org/wikipedia/commons/e/e2/Legendary.png',
label: getMsg( 'legendary' ),
action: {
type: 'callback',
execute: function() {
OO.ui.getWindowManager().openWindow( legendaryDialog );
}
}
};
var legendaryButton = {
section: 'main',
group: 'insert',
tools: { 'Legendary': legendaryButtonDetails }
};
$( "#wpTextbox1" ).wikiEditor( 'addToToolbar', legendaryButton );
$( "a[rel='legendaryDialog']" ).css("width", "64px");
} );
}
main();
}
var isEditing = $.inArray( mw.config.get( 'wgAction' ), [ 'edit', 'submit' ] ) !== -1,
isFile = mw.config.get( 'wgCanonicalNamespace' ) === 'File';
if ( isEditing && isFile ) {
var dependencies = [
'oojs-ui-core',
'oojs-ui-windows'
];
mw.loader.using( dependencies, $.ready ).then( Legendary );
}
// EOF </nowiki>