User:Xover/ocrtoy.js
Jump to navigation
Jump to search
Note: After saving, changes may not occur immediately. Click here to learn how to bypass your browser's cache.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (Cmd-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (Cmd-Shift-R on a Mac)
- Internet Explorer: Hold Ctrl while clicking Refresh, or press Ctrl-F5
- Opera: Clear the cache in Tools → Preferences
For details and instructions about other browsers, see Wikipedia:Bypass your cache.
Code that you insert on this page could contain malicious content capable of compromising your account. If you are unsure whether code you are adding to this page is safe, you can ask at the central discussion page, Scriptorium. The code will be executed when previewing this page under some skins, including Monobook. You can in the interim if you wish to refresh the content sooner under another skin. |
Documentation for this script can be added at User:Xover/ocrtoy. |
/* global $, mw */
/*
* ocrtoy.js
*
* This script adds a toolbar button that replaces the editbox text with OCR
* text derived by sending the .prp-page-image image through ocrtoy's backend.
*
*/
(function (mw, $) {
"use strict";
mw.loader.using(["mediawiki.api", "mediawiki.util", "user.options"], function () {
/*
* First check that this is a context we should be active in.
*/
// Only active on Page:-namespace pages.
if (mw.config.get('wgCanonicalNamespace') !== 'Page') {
return;
}
// Only active on pages with content model 'proofread-page'.
if (mw.config.get('wgPageContentModel') !== 'proofread-page') {
return;
}
// Only active when in edit/preview/diff mode.
if ($.inArray(mw.config.get('wgAction'), ['edit', 'submit']) < 0) {
return;
}
/*
* Set up the globals we'll need.
*/
var sysMessages = [
'ocrtoy-button-label',
'ocrtoy-request-in-progress',
'ocrtoy-no-text',
'ocrtoy-image-not-found'
];
/*
* Add main UI. Preferences UI is handled by a separate gadget.
*/
var setupUI;
if (mw.user.options.get('usebetatoolbar') === 1) {
setupUI = addToolbarButton; // Add button in toolbar if enabled.
} else {
setupUI = addSidebarLink; // Add a link in the sidebar.
}
new mw.Api()
.loadMessagesIfMissing(sysMessages)
.then(setupUI);
/*
* Prefetch the OCR results for the current page
*/
var isInteractive = false; var warmingCache = false;
requestOCR(isInteractive, warmingCache);
/*
* Then warm the cache for the next page.
*/
isInteractive = false; warmingCache = true;
requestOCR(isInteractive, warmingCache);
}); // END: mw.loader.using()
/**
* Add the OCR button to the toolbar. This is called in run, and doesn't
* need to check anything about whether we need to add the button.
*/
function addToolbarButton() {
var ocrButtonDetails = {
type: 'button',
icon: 'https://upload.wikimedia.org/wikipedia/commons/4/48/Ocrtoy_WikiEditor_button.png',
label: mw.msg('ocrtoy-button-label'),
action: {type: 'callback', execute: doOcr}
};
var ocrButton = {
section: 'main',
group: 'insert',
tools: {'ocrtoy': ocrButtonDetails}
};
mw.loader.using(['ext.wikiEditor'], function () {
$("#wpTextbox1").wikiEditor('addToToolbar', ocrButton);
$("a[rel='ocrtoy']").css("width", "36px");
});
}
/**
* Add the OCR link to the sidebar. This is called in run, and doesn't
* need to check anything about whether we need to add the link.
*/
function addSidebarLink() {
var ocrPortlet = mw.util.addPortletLink(
'p-tb', '#', 'Get OCR', 'ca-ocrtoy',
'Get the OCR for this page from ocrtoy.'
);
$(ocrPortlet).click(function (e) {
e.preventDefault();
doOcr();
});
}
function doOcr () {
var isInteractive = true; var warmingCache = false;
requestOCR(isInteractive, warmingCache);
}
function bailOnError(isInteractive, response) {
var notifyFunc;
if (isInteractive) {
notifyFunc = function (m) {console.log(m)};
} else {
notifyFunc = function (m) {mw.notify(m)};
}
if (response.responseJSON !== undefined && response.responseJSON.error) {
var code = response.responseJSON.error.code;
var message = response.responseJSON.error.message;
notifyFunc(mw.msg('error') + ' ' + code + ' ' + message);
return true;
}
if (response.text === undefined || response.text.length === 0) {
notifyFunc(mw.msg('ocrtoy-no-text'));
return true;
}
return false;
}
// Disable or enable the text editor text field and toolbar button
function disable_input(disable) {
if (disable) {
// Install handler for ESC key to abort and re-enable text field and button
$(document).keyup(function(e) {if (e.which == 27) {disable_input(false);}});
// Remove click handler from toolbar button.
$("a[rel='ocrtoy']").off('click');
// Set HTML form "disabled" property to true.
$('#wpTextbox1').prop('disabled', true);
} else {
// Remove handler for ESC key
$(document).off('keyup');
// Add back the click handler on the toolbar button.
$("a[rel='ocrtoy']").on('click', doOcr);
// Set HTML form "disabled" property to false.
$('#wpTextbox1').prop('disabled', false);
}
}
/**
* Prefetch the OCR text so it is ready when the user requests it,
* or fetch it on demand if it doesn't already exist.
* TODO: Make this configurable.
*/
function requestOCR (isInteractive, warmingCache) {
var lang = mw.config.get('wgContentLanguage');
var toolUrl = "https://ocrtoy.wmflabs.org/";
var prefetch = $("#wpTextbox1").data("ocrtoyPrefetch");
if (prefetch !== undefined && isInteractive === true) {
$('#wpTextbox1').val(prefetch);
console.log("[ocrtoy]: Found data in local cache.");
return;
}
var notifyFunc;
if (isInteractive) {
notifyFunc = function (m) {mw.notify(m)};
} else if (warmingCache === true) {
notifyFunc = function (m) {return;}; // noop
} else {
notifyFunc = function (m) {console.log(m)};
}
// Just bail out if the page image can't be found.
if ($('.prp-page-image img').length === 0) {
notifyFunc(mw.msg('ocrtoy-image-not-found'));
}
// Report progress if interactive.
if (isInteractive) {
disable_input(true);
}
var fullsize_width = $('.prp-page-image img').data('fileWidth');
var match = /(.*?)\/(\d+)/.exec(mw.config.get('wgTitle'));
var file = match[1];
var page = match[2];
if (warmingCache === true) {
page = parseInt(page) + 1;
console.log("[ocrtoy]: Going to warm cache for page " + page + ".");
}
var getOCR = function (isInteractive, warmingCache, data) {
var thumburl = data.query.pages[0].imageinfo[0].thumburl;
console.log("ocrtoy thumburl: " + thumburl);
var requestUrl = toolUrl + "?image=" + thumburl + "&lang=" + lang;
var processOCR = function (isInteractive, warmingCache, response) {
if (warmingCache !== true) {
var shouldBail = bailOnError(isInteractive, response);
if (shouldBail) {
return;
}
}
if (isInteractive) {
console.log("[ocrtoy]: Update text due to interactive request.");
$('#wpTextbox1').val(response.text);
} else if (warmingCache === true) {
console.log("[ocrtoy]: Ignoring returned result whiile warming cache.");
return; // Ignore it; we're just warming the server-side cache.
} else {
console.log("[ocrtoy]: Storing prefetched text for interactive use.");
$("#wpTextbox1").data("ocrtoy-prefetch", response.text);
}
}.bind(null, isInteractive, warmingCache);
$.getJSON(requestUrl)
.done(processOCR)
.fail(processOCR) // Same handler, for simplicity.
.always(function () {disable_input(false);});
}.bind(null, isInteractive, warmingCache); // Pass along interactive state
var api = new mw.Api();
api.get({
'action': 'query',
'prop': 'imageinfo',
'titles': "File:" + file,
'formatversion': 2,
'format': 'json',
'iiprop': 'url',
'iiurlwidth': fullsize_width,
'iiurlparam': "page" + page + "-" + fullsize_width + "px"
})
.done(getOCR);
}
}(mediaWiki, jQuery));