MediaWiki:Gadget-ImageAnnotator.js: Difference between revisions

Content deleted Content added
Can't reproduce the {{|h=undefined}} error locally, but will restore this version for now
Follow-up Special:Diff/127917228: Fix typo "sh" -> "h"
Line 2:
 
/*
ImageAnnotator v2v3.30.20
 
ATTENTION:
This is in the Gadget- prefix but not actually registered nor loaded as a Gadget. It is
loaded directly by [[MediaWiki:Common.js]], raw, unminified and in the global scope.
 
Image annotations. Draw rectangles onto image thumbnail displayed on image description
Line 26 ⟶ 22:
*/
 
// Global: importScript, importScriptURI (wikiwikibits.js)
// Global: wgPageName, wgCurRevisionId, wgUserGroups, wgRestrictionEdit (inline script on the page)
// Global: wgAction, wgNamespaceNumber, wgUserLanguage, wgContentLanguage, stylepath (inline script)
// Global: wgNamespaceIds (inline script)
/*jshint eqnull:true, laxbreak:true, laxcomma:true */
Line 40 ⟶ 36:
 
(function () { // Local scope
 
var conf = mw.config.get([
'skin',
'stylepath'
]);
 
var ImageAnnotator_config = null;
Line 60 ⟶ 61:
viewer : null, // Reference to the viewer this note belongs to
 
initialize : function (node, viewer, id) {
{
var is_new = false;
var view_w = 0, view_h = 0, view_x = 0, view_y = 0;
Line 77:
throw new Error ('Invalid note: origin invalid on note ' + id);
if ( x + w > viewer.full_img.width + 10
|| y + h > viewer.full_img.height + 10)
) {
throw new Error ('Invalid note: size extends beyond image on note ' + id);
}
// Notes written by early versions may be slightly too large, whence the + 10 above. Fix this.
Line 89:
view_y = Math.floor(y / viewer.factors.dy);
this.view =
LAPI.make( 'div', null, {
position: 'divabsolute', null
, { position display: 'absolutenone',
// ,display : 'none'IE
,lineHeight : '0px' // IE,
,fontSize : '0px' // IE
fontSize: '0px',
,top top: '' + view_y + 'px',
,left : '' + view_x + 'px',
,width : '' + view_w + 'px',
,height : '' + view_h + 'px'
});
);
// We'll add the view to the DOM once we've loaded all notes
this.model = {
{ id : id,
,dimension: { x: x, y: y, w: w, h: h },
,wiki : '',
,html : html.cloneNode(true)
};
} else {
is_new = true;
this.view = node;
this.model = {
{ id : -1,
,dimension: null,
,wiki : '',
,html : null
};
view_w = this.view.offsetWidth - 2; // Subtract cumulated border widths
view_h = this.view.offsetHeight - 2;
Line 127:
if (view_h < 6) {view_y = Math.floor(view_y + view_h / 2 - 3); view_h = 6; }
Object.merge(
{
{ left: '' + view_x + 'px',
top: '' + view_y + 'px',
,width: '' + view_w + 'px',
height: '' + view_h + 'px'}
},
this.view.style
);
this.view.style.zIndex = 500; // Below tooltips
Line 166 ⟶ 170:
},
 
setTooltip : function () {
{
if (this.tooltip || !this.view) return; // Already set, or corrupt
// Note: on IE, don't have tooltips appear automatically. IE doesn't do it right for transparent
Line 210 ⟶ 213:
},
 
display : function (evt) {
{
if (!this.content) {
this.content = LAPI.make('div');
Line 254 ⟶ 256:
},
 
edit : function (evt) {
{
if (IA.canEdit()) IA.editor.editNote(this);
if (evt) return LAPI.Evt.kill(evt);
Line 261 ⟶ 262:
},
 
remove_event : function (evt) {
{
if (IA.canEdit()) this.remove();
return LAPI.Evt.kill(evt);
},
 
remove : function () {
{
if (!this.content) { // New note: just destroy it.
this.destroy();
Line 298 ⟶ 297:
LAPI.Ajax.editPage(
wgPageName
, function (doc, editForm, failureFunc, revision_id) {
{
try {
if (revision_id && revision_id != wgCurRevisionId)
Line 376 ⟶ 374:
},
 
destroy : function () {
{
if (this.view) LAPI.DOM.removeNode(this.view);
if (this.dummy) LAPI.DOM.removeNode(this.dummy);
Line 389 ⟶ 386:
},
 
area : function () {
{
if (!this.model || !this.model.dimension) return 0;
return (this.model.dimension.w * this.model.dimension.h);
},
 
cannotEdit : function () {
{
if (this.content && this.content.button_section) {
LAPI.DOM.removeNode(this.content.button_section);
Line 410 ⟶ 405:
ImageAnnotationEditor.prototype =
{
initialize : function () {
{
var editor_width = 50;
// Respect potential user-defined width setting
Line 506 ⟶ 500:
},
 
editNote : function (note) {
{
var same_note = (note == this.note);
this.note = note;
Line 556 ⟶ 549:
},
 
open_editor : function (same_note, cover) {
{
this.editor.hidePreview();
if (!same_note || this.editor.textarea.readOnly)
Line 595 ⟶ 587:
},
 
hide_editor : function (evt) {
{
if (!this.visible) return;
this.visible = false;
Line 616 ⟶ 607:
},
 
save : function (editor) {
{
var data = editor.getText();
if (!data || !data.length) {
Line 640 ⟶ 630:
if (!dim) {
dim = {
x : Math.round(this.dim.x * this.viewer.factors.dx),
y : Math.round(this.dim.y * this.viewer.factors.dy),
w : Math.round(this.dim.w * this.viewer.factors.dx),
sh h: Math.round(this.dim.h * this.viewer.factors.dy)
};
// Make sure everything is within bounds
Line 703 ⟶ 693:
LAPI.Ajax.editPage(
wgPageName
, function (doc, editForm, failureFunc, revision_id) {
{
try {
if (revision_id && revision_id != wgCurRevisionId)
Line 831 ⟶ 820:
);
}
, function (request, ex) {
{
self.editor.busy(false);
self.saving = false;
Line 842 ⟶ 830:
// Error message. Use preview field for this.
var error_msg = ImageAnnotator.UI.get('wpImageAnnotatorSaveError', false);
var lk = error_msg.getElementsByClassName(error_msg, 'span', 'wpImageAnnotatorOwnPageLink');
if (lk && lk.length && lk[0].firstChild.nodeName.toLowerCase() === 'a') {
lk = lk[0].firstChild;
Line 867 ⟶ 855:
},
 
onpreview : function (editor) {
{
if (this.tooltip) this.tooltip.size_change();
},
 
cancel : function (editor) {
{
if (!this.note) return;
if (!this.note.content) {
Line 883 ⟶ 869:
},
 
close_tooltip : function (tooltip, evt) {
{
this.hide_editor(evt);
this.cancel();
Line 895 ⟶ 880:
ImageNotesViewer.prototype =
{
initialize : function (descriptor, may_edit) {
{
Object.merge(descriptor, this);
this.annotations = [];
Line 906 ⟶ 890:
this.tip = null;
this.icon = null;
this.factors = {
{ dx : this.full_img.width / this.thumb.width,
,dy : this.full_img.height / this.thumb.height
};
 
if (!this.isThumbnail && !this.isOther) {
Line 924 ⟶ 908:
},
 
setup : function (onlyIcon) {
{
this.setup_done = true;
var name = this.realName;
var $fullname;
if (this.isThumbnail || this.scope == document || this.may_edit || !IA.haveAjax) {
this.imgName = this.realName;
this.realName = '';
} else {
name$fullname = getElementsByClassName $(this.scope, '*', ).find('.wpImageAnnotatorFullName');
this.realName = ((name && name$fullname.length) ? LAPI$fullname.DOM.getInnerTexttext(name[0]) : '');
this.imgName = this.realName;
}
 
var annotations = getElementsByClassName (this.scope, 'div', .getElementsByClassName(IA.annotation_class);
 
if (!this.may_edit && (!annotations || annotations.length === 0))
Line 992 ⟶ 976:
(name, this.isLocal, this.thumb, this.full_img, annotations.length, this.isThumbnail)
)
) ){
{
// Use an onclick handler instead of a link around the image. The link may have a default white
// background, but we want to be sure to have transparency. The image should be an 8-bit indexed
Line 1,003 ⟶ 986:
&& this.icon.nodeName.toLowerCase() == 'a'
&& this.icon.firstChild.nodeName.toLowerCase() == 'img'
) ){
{
// Make sure we use the right protocol:
var srcFixed = this.icon.firstChild.getAttribute('src', 2).replace(/^https?\:/, document.___location.protocol);
Line 1,019 ⟶ 1,001:
}
Object.merge(
{ {position: 'absolute', zIndex: 1000, top: '0px', cursor: 'pointer' },
, this.icon.style
);
this.icon.onclick = (function () { ___location.href = this.img.parentNode.href; }).bind(this);
Line 1,052 ⟶ 1,034:
if ( w == this.full_img.width && h == this.full_img.height
&& !Array.exists(this.annotations, function (note) { return note.model.id == id; })
) ){
{
try {
this.register(new ImageAnnotation(annotations[i], this, id));
Line 1,067 ⟶ 1,048:
Array.forEach(this.annotations, (function (note) {this.img_div.appendChild(note.view);}).bind(this));
if (this.isThumbnail) {
this.main_div = getElementsByClassName (this.file_div, 'div', .getElementsByClassName('thumbcaption');
if (!this.main_div || this.main_div.length === 0)
this.main_div = null;
else
Line 1,093 ⟶ 1,074:
&& ImageAnnotator_config.displayCaptionInArticles
(name, this.isLocal, this.thumb, this.full_img, annotations.length, this.isThumbnail)
) ){
this.msg = LAPI.make('div', null, { display: 'none' });
{
this.msg = LAPI.make('div', null, {display: 'none'});
if (IA.is_rtl) {
this.msg.style.direction = 'rtl';
Line 1,151 ⟶ 1,131:
},
 
cannotEdit : function () {
{
if (!this.may_edit) return;
this.may_edit = false;
Line 1,158 ⟶ 1,137:
},
 
setShowHideEvents : function (set) {
{
if (this.icon) return;
if (set) {
Line 1,173 ⟶ 1,151:
},
 
removeMoveListener : function () {
{
if (this.icon) return;
this.move_listening = false;
Line 1,184 ⟶ 1,161:
},
 
adjustRectangleSize : function (node) {
{
if (this.icon) return;
// Make sure the note boxes don't overlap the image boundary; we might get an event
Line 1,205 ⟶ 1,181:
// Now set position and width and height, subtracting cumulated border widths
if ( view_x != node.offsetLeft || view_y != node.offsetTop
|| view_w != node.offsetWidth || view_h != node.offsetHeight)
) {
node.style.top = '' + view_y + 'px';
node.style.left = '' + view_x + 'px';
Line 1,216 ⟶ 1,192:
},
 
toggle : function (dummies) {
{
var i;
if (!this.annotations || this.annotations.length === 0 || this.icon) return;
Line 1,240 ⟶ 1,215:
},
 
show : function (evt) {
{
if (this.visible || this.icon) return;
this.toggle(IA.is_adding || IA.is_editing);
Line 1,252 ⟶ 1,226:
},
 
hide : function (evt) {
{
if (this.icon) return true;
if (!this.visible) {
Line 1,313 ⟶ 1,286:
if ( display !== 'none' && display != null
&& LAPI.Pos.isWithin(this.annotations[i].view.firstChild, mouse_pos.x, mouse_pos.y)
) {
{
if (!this.annotations[i].tooltip.visible) this.annotations[i].tooltip.show(evt);
return true;
Line 1,331 ⟶ 1,303:
},
 
check_hide : function (evt) {
{
if (this.icon) return true;
if (this.visible)
Line 1,339 ⟶ 1,310:
},
 
register : function (new_note) {
{
this.annotations[this.annotations.length] = new_note;
if (new_note.model.id > 0) {
Line 1,349 ⟶ 1,319:
},
 
deregister : function (note) {
{
Array.remove(this.annotations, note);
if (note.model.id == this.max_id) this.max_id--;
Line 1,356 ⟶ 1,325:
},
 
setDefaultMsg : function () {
{
if (this.annotations && this.annotations.length && this.msg) {
LAPI.DOM.removeChildren(this.msg);
Line 1,389 ⟶ 1,357:
};
 
var IA = {
{
// This object is responsible for setting up annotations when a page is loaded. It loads all
// annotations in the page source, and adds an "Annotate this image" button plus the support
Line 1,427 ⟶ 1,394:
],
 
tooltip_styles : // The style for all our tooltips
tooltip_styles: {
{ border : '1px solid #8888aa'
, backgroundColor border: '1px solid #ffffe08888aa'
, padding backgroundColor: '0.3em#ffffe0'
, padding: '0.3em'
, fontSize : ((skin && (skin == 'monobook' || skin == 'modern')) ? '127%' : '100%')
, fontSize: (conf.skin === 'monobook' ? '127%' : '100%')
// Scale up to default text size
},
 
editor : null,
 
wiki_read : false,
is_rtl : false,
 
move_listening : false,
is_tracking : false,
is_adding : false,
is_editing : false,
 
zoom_threshold : 8.0,
zoom_factor : 4.0,
 
install_attempts : 0,
max_install_attempts : 10, // Maximum 5 seconds
 
imgs_with_notes : [],
thumbs : [],
other_images : [],
 
// Fallback
indication_icon : '//upload.wikimedia.org/wikipedia/commons/8/8a/Gtk-dialog-info-14px.png',
 
install : function (config) {
{
if (typeof ImageAnnotator_disable !== 'undefined' && !!ImageAnnotator_disable) return;
if (!config || ImageAnnotator_config != null) return;
Line 1,475 ⟶ 1,442:
&& typeof LAPI.Ajax !== 'undefined'
&& typeof LAPI.Ajax.getRequest !== 'undefined'
) ){
{
self.haveAjax = (LAPI.Ajax.getRequest() != null);
self.ajaxQueried = true;
Line 1,487 ⟶ 1,453:
self.may_edit = wgNamespaceNumber >= 0 && wgArticleId > 0 && self.haveAjax && config.editingEnabled();
 
function namespaceCheck (list) {
if (!list || !$.isArray(list)) return false;
{
if (!list || Object.prototype.toString.call(list) !== '[object Array]') return false;
for (var i = 0; i < list.length; i++) {
if (wgNamespaceIds
Line 1,509 ⟶ 1,474:
if ( !self.haveAjax
|| !config.generalImagesEnabled()
|| namespaceCheck (window.ImageAnnotator_no_images || null)
) ){
{
self.rules.inline.show = false;
self.rules.thumbs.show = false;
Line 1,519 ⟶ 1,483:
|| !config.thumbsEnabled()
|| namespaceCheck(window.ImageAnnotator_no_thumbs || null)
) ){
{
self.rules.thumbs.show = false;
}
Line 1,527 ⟶ 1,490:
else if ( !config.sharedImagesEnabled()
|| namespaceCheck(window.ImageAnnotator_no_shared || null)
) ){
{
self.rules.shared.show = false;
}
Line 1,553 ⟶ 1,515:
if ( typeof self.rules.inline.show === 'undefined'
&& rules.className.indexOf('wpImageAnnotatorDisplay') >= 0
) ){
{
self.rules.inline.show = true;
}
Line 1,562 ⟶ 1,523:
if ( typeof self.rules.thumbs.show === 'undefined'
&& rules.className.indexOf('wpImageAnnotatorThumbDisplay') >= 0
) ){
{
self.rules.thumbs.show = true;
}
Line 1,572 ⟶ 1,532:
self.rules.thumbs.icon = true;
}
if (rules.className.indexOf('wpImageAnnotatorOnlyLocal') >= 0) {
{
self.rules.shared.show = false;
}
Line 1,637 ⟶ 1,596:
}
} else {
self.imgs_with_notes = document.getElementsByClassName (document, '*', 'wpImageAnnotatorEnable');
if (do_thumbs)
self.thumbs = getElementsByClassName (document, 'div', 'thumbinner'); // No galleries!
self.thumbs = document.getElementsByClassName('thumbinner');
}
if ( wgNamespaceNumber == 6
Line 1,645 ⟶ 1,605:
|| (self.thumbs.length)
|| (self.other_images.length)
) ){
{
// Publish parts of config.
ImageAnnotator.UI = config.UI;
Line 1,657 ⟶ 1,616:
},
 
wait_for_required_libraries : function () {
{
if (typeof Tooltip == 'undefined' || typeof LAPI == 'undefined') {
if (IA.install_attempts++ < IA.max_install_attempts) {
Line 1,671 ⟶ 1,629:
},
 
setup: function () {
{
var self = IA;
self.imgs = [];
Line 1,683 ⟶ 1,640:
)
;
 
var stylepath = mw.config.get('stylepath') || '/skin';
 
// Use this to temporarily display an image off-screen to get its dimensions
var testImgDiv =
LAPI.make('div', null, {
{ display: 'none', position: 'absolute', width: '300px',
, overflow: 'hidden', overflowX: 'hidden', left: '-10000px'
});
);
document.body.insertBefore(testImgDiv, document.body.firstChild);
 
function img_check (img, is_other) {
{
var srcW = parseInt (img.getAttribute('width', 2), 10);
var srcH = parseInt (img.getAttribute('height', 2), 10);
Line 1,721 ⟶ 1,674:
if (w != srcW || h != srcH) return null;
// Exclude system images
if (img.src.contains(conf.stylepath)) return null;
// Only if within a link
if (img.parentNode.nodeName.toLowerCase() != 'a') return null;
Line 1,755 ⟶ 1,708:
file_div = LAPI.$('file');
} else if (!is_thumb && !is_other) {
file_div = scope.getElementsByClassName(scope, 'div', 'wpImageAnnotatorFile');
if (!file_div || file_div.length != 1) return null;
file_div = file_div[0];
Line 1,828 ⟶ 1,781:
}
 
function setup_images (list) {
{
Array.forEach(list,
function (elem) {
Line 1,889 ⟶ 1,841:
var done = 0;
 
function check_done (length) {
{
done += length;
if (done >= names.length) {
Line 1,898 ⟶ 1,849:
}
 
function make_calls (execute_call, url_limit) {
function build_titles (from, length, url_limit) {
{
function build_titles (from, length, url_limit)
{
var done = 0;
var text = '';
Line 1,925 ⟶ 1,874:
}
 
function set_info (json) {
{
try {
if (json && json.query && json.query.pages) {
Line 1,972 ⟶ 1,920:
function (length, titles) {
var idx = ImageAnnotator.info_callbacks.length;
ImageAnnotator.info_callbacks[idx] = {
{ callback : function (json) {
set_info (json);
ImageAnnotator.info_callbacks[idx].done = true;
if (ImageAnnotator.info_callbacks[idx].script) {
LAPI.DOM.removeNode(ImageAnnotator.info_callbacks[idx].script);
ImageAnnotator.info_callbacks[idx].script = null;
}
check_done (length);
},
} done: false
,done : false};
};
ImageAnnotator.info_callbacks[idx].script =
IA.getScript(
Line 1,995 ⟶ 1,943:
// up in that case.
if ( ImageAnnotator.info_callbacks && ImageAnnotator.info_callbacks[idx]
&& ImageAnnotator.info_callbacks[idx].done && ImageAnnotator.info_callbacks[idx].script)
) {
LAPI.DOM.removeNode(ImageAnnotator.info_callbacks[idx].script);
ImageAnnotator.info_callbacks[idx].script = null;
Line 2,024 ⟶ 1,972:
},
 
setup_ui : function () {
{
// Complete the UI object we've gotten from config.
 
Line 2,053 ⟶ 2,000:
};
 
ImageAnnotator.UI.setup = function () {
{
if (ImageAnnotator.UI.repo) return;
var self = ImageAnnotator.UI;
var node = LAPI.make('div', null, { display: 'none' });
var item;
document.body.appendChild(node);
if (typeof UIElements === 'undefined') {
self.basic = true;
self.repo = {};
for (var item in self.defaults) {
node.innerHTML = self.defaults[item];
self.repo[item] = node.firstChild;
Line 2,070 ⟶ 2,017:
self.basic = false;
self.repo = UIElements.emptyRepository(self.defaultLanguage);
for (var item in self.defaults) {
node.innerHTML = self.defaults[item];
UIElements.setEntry(item, self.repo, node.firstChild);
Line 2,080 ⟶ 2,027:
};
 
ImageAnnotator.UI.get = function (id, basic, no_plea) {
{
var self = ImageAnnotator.UI;
if (!self.repo) self.setup();
Line 2,111 ⟶ 2,057:
};
 
ImageAnnotator.UI.get_plea = function () {
{
var self = ImageAnnotator.UI;
var translate = self.get('wpTranslate', false, true) || 'translate';
Line 2,130 ⟶ 2,075:
};
 
ImageAnnotator.UI.init = function (html_text_or_json) {
{
var text;
if (typeof html_text_or_json === 'string')
Line 2,149 ⟶ 2,093:
}
 
var node = LAPI.make('div', null, { display: 'none' });
document.body.appendChild(node);
try {
Line 2,166 ⟶ 2,110:
+ '|live=1}}';
 
function get_ui_no_ajax () {
{
var url =
wgServer + wgScriptPath + '/api.php?format=json&action=parse&pst&text='
+ encodeURIComponent(ui_page) + '&title=API&prop=text&format=json'
+ '&callback=ImageAnnotator.UI.init&maxage=14400&smaxage=14400'
;
Line 2,179 ⟶ 2,122:
}
 
function get_ui () {
{
IA.haveAjax = (LAPI.Ajax.getRequest() != null);
IA.ajaxQueried = true;
Line 2,214 ⟶ 2,156:
},
 
setup_step_two : function () {
{
var self = IA;
 
Line 2,237 ⟶ 2,178:
},
 
complete_setup : function () {
{
// We can be sure to have the UI here because this is called only when the ready event of the
// UI object is fired.
Line 2,255 ⟶ 2,195:
if (self.may_edit) {
// Check whether the image is local. Don't allow editing if the file is remote.
var sharedUpload = document.getElementsByClassName (document, 'div', 'sharedUploadNotice');
self.may_edit = (!sharedUpload || sharedUpload.length === 0);
}
if (self.may_edit && wgNamespaceNumber != 6) {
// Only allow edits if the stored page name matches the current one.
var img_page_name = self.imgs[0].scope.getElementsByClassName('wpImageAnnotatorPageName');
getElementsByClassName (self.imgs[0].scope, '*', 'wpImageAnnotatorPageName');
if (img_page_name && img_page_name.length)
img_page_name = LAPI.DOM.getInnerText(img_page_name[0]);
Line 2,284 ⟶ 2,223:
&& !isNaN (window.ImageAnnotator_zoom_threshold)
&& window.ImageAnnotator_zoom_threshold >= 0.0
) ){
{
// If somebody sets it to a nonsensical high value, that's his or her problem: there won't be any
// zooming.
Line 2,294 ⟶ 2,232:
if ( self.viewers[0].full_img.width > 300
&& Math.min(self.viewers[0].factors.dx, self.viewers[0].factors.dy) >= 2.0
) ){
{
if ( self.viewers[0].thumb.width < 400
|| self.viewers[0].thumb.width / self.viewers[0].thumb.height > 2.0
|| self.viewers[0].thumb.height / self.viewers[0].thumb.width > 2.0
) ){
{
self.zoom_threshold = 0; // Force zooming
}
Line 2,399 ⟶ 2,335:
}
 
function start_tracking (evt) {
{
if (!self.is_tracking) {
self.is_tracking = true;
Line 2,526 ⟶ 2,461:
// API limits and to keep the URL length below the limit for the foreign_repo calls.
 
function make_calls (list, execute_call, url_limit) {
function composer (list, from, length, url_limit) {
{
function composercompose (list, from, length, url_limit) {
{
function compose (list, from, length, url_limit)
{
var text = '';
var done = 0;
Line 2,634 ⟶ 2,566:
}
 
function setup_thumb_viewers (html_text) {
{
var node = LAPI.make('div', null, {display: 'none'});
document.body.appendChild(node);
try {
node.innerHTML = strip_noise (html_text);
var pages = node.getElementsByClassName (node, 'div', 'wpImageAnnotatorInlineImageWrapper');
for (var i = 0; pages && i < pages.length; i++) {
var notes = getElementsByClassName (pages[i], 'div', .getElementsByClassName(self.annotation_class);
if (!notes || notes.length === 0) continue;
var page = self.getItem('inline_name', pages[i]);
if (!page) continue;
page = page.replace(/ /g, '_');
var viewers = cache[page] || cache['File:' + page.substring(page.indexOf(':') + 1)];
if (!viewers || viewers.length === 0) continue;
// Update rules.
var rules = getElementsByClassName (pages[i], 'div', .getElementsByClassName('wpImageAnnotatorInlinedRules');
var local_rules = {
{ inline: Object.clone(IA.rules.inline),
,thumbs: Object.clone(IA.rules.thumbs)
};
if (rules && rules.length) {
rules = rules[0];
if ( typeof local_rules.inline.show === 'undefined'
&& LAPI.DOM.hasClass(rules, 'wpImageAnnotatorNoInlineDisplay')
) ){
{
local_rules.inline.show = false;
}
if ( typeof local_rules.inline.icon === 'undefined'
&& LAPI.DOM.hasClass(rules, 'wpImageAnnotatorInlineDisplayIcon')
) ){
{
local_rules.inline.icon = true;
}
if ( typeof local_rules.thumbs.show === 'undefined'
&& LAPI.DOM.hasClass(rules, 'wpImageAnnotatorNoThumbs')
) ){
{
local_rules.thumbs.show = false;
}
if ( typeof local_rules.thumbs.icon === 'undefined'
&& LAPI.DOM.hasClass(rules, 'wpImageAnnotatorThumbDisplayIcon')
) ){
{
local_rules.thumbs.icon = true;
}
Line 2,711 ⟶ 2,638:
ImageAnnotator.script_callbacks = [];
 
function make_script_calls (list, api) {
{
var template = api + '?action=parse&pst&text=&prop=text&format=json'
+ '&maxage=1800&smaxage=1800&uselang=' + wgUserLanguage //see bugzilla 22764
Line 2,721 ⟶ 2,647:
, function (text) {
var idx = ImageAnnotator.script_callbacks.length;
ImageAnnotator.script_callbacks[idx] = {
{ callback : function (json) {
if (json && json.parse && json.parse.text && json.parse.text['*']) {
setup_thumb_viewers (json.parse.text['*']);
}
ImageAnnotator.script_callbacks[idx].done = true;
if (ImageAnnotator.script_callbacks[idx].script) {
LAPI.DOM.removeNode(ImageAnnotator.script_callbacks[idx].script);
ImageAnnotator.script_callbacks[idx].script = null;
}
},
done: false
};
,done : false
};
ImageAnnotator.script_callbacks[idx].script =
IA.getScript(
Line 2,741 ⟶ 2,667:
);
if ( ImageAnnotator.script_callbacks && ImageAnnotator.script_callbacks[idx]
&& ImageAnnotator.script_callbacks[idx].done && ImageAnnotator.script_callbacks[idx].script)
) {
LAPI.DOM.removeNode(ImageAnnotator.script_callbacks[idx].script);
ImageAnnotator.script_callbacks[idx].script = null;
Line 2,777 ⟶ 2,703:
},
 
show_zoom : function () {
{
var self = IA;
if ( ( self.viewers[0].factors.dx < self.zoom_threshold
Line 2,784 ⟶ 2,709:
)
|| Math.max(self.viewers[0].factors.dx, self.viewers[0].factors.dy) < 2.0
) ){
{
// Below zoom threshold, or full image not even twice the size of the preview
return;
Line 2,875 ⟶ 2,799:
},
 
update_zoom : function (evt) {
{
if (!evt) return; // We need an event to calculate positions!
var self = IA;
Line 2,912 ⟶ 2,835:
},
 
hide_zoom : function (evt) {
{
if (!IA.zoom) return;
if (evt) {
Line 2,922 ⟶ 2,844:
},
 
createHelpLink : function () {
{
var msg = ImageAnnotator.UI.get('wpImageAnnotatorHelp', false, true);
if (!msg || !msg.lastChild) return null;
Line 2,980 ⟶ 2,901:
},
 
get_cover : function () {
{
var self = IA;
var shim;
Line 3,039 ⟶ 2,959:
},
 
show_cover : function () {
{
var self = IA;
if (self.cover && !self.cover_visible) {
Line 3,053 ⟶ 2,972:
},
 
hide_cover : function () {
{
var self = IA;
if (self.cover && self.cover_visible) {
Line 3,067 ⟶ 2,985:
},
 
getRawItem : function (what, scope) {
{
var node = null;
if (!scope || scope == document) {
node = LAPI.$ ('image_annotation_' + what);
} else {
node = scope.getElementsByClassName (scope, '*', 'image_annotation_' + what);
if (node && node.length) node = node[0]; else node = null;
}
Line 3,079 ⟶ 2,996:
},
 
getItem : function (what, scope) {
{
var node = IA.getRawItem(what, scope);
if (!node) return null;
Line 3,086 ⟶ 3,002:
},
 
getIntItem : function (what, scope) {
{
var x = IA.getItem(what, scope);
if (x !== null) x = parseInt (x, 10);
Line 3,093 ⟶ 3,008:
},
 
findNote : function (text, id) {
{
function find (text, id, delim) {
var start = delim.start.replace('$1', id);
Line 3,112 ⟶ 3,026:
},
 
setWikitext : function (pagetext) {
{
var self = IA;
if (self.wiki_read) return;
Line 3,137 ⟶ 3,050:
},
 
setSummary : function (summary, initial_text, note_text) {
{
if (initial_text.contains('$1')) {
var max = (summary.maxlength || 200) - initial_text.length;
Line 3,150 ⟶ 3,062:
},
 
getScript : function (url, bypass_local_cache, bypass_caches) {
{
// Don't use LAPI here, it may not yet be available
if (bypass_caches) {
Line 3,169 ⟶ 3,080:
},
 
canEdit : function () {
{
var self = IA;
if (self.may_edit) {
Line 3,190 ⟶ 3,100:
 
}; // end IA
 
// Backwards compatibility
function getElementsByClassName (scope, tag, className) {
if (window.jQuery) {
return jQuery(scope).find(((!tag || tag === '*') ? '' : tag) + '.' + className);
} else {
// For non-WMF wikis that might not have jQuery (yet), use the wikibits.js getElementsByClassName
return getElementsByClassName(scope, tag, className);
}
}
 
window.ImageAnnotator = {
install: function (config) {
IA.install(config);
}
};
 
// Start it. Bypass caches; but allow for 4 hours client-side caching. Small file.
IA.getScript(
wgScript + '?title=MediaWiki:ImageAnnotatorConfig.js&action=raw&ctype=text/javascript'
// Cache 4 hours
+ '&dummy=' + Math.floor((new Date()).getTime() / (14400 * 1000)) // 4 hours,
, true // No local caching!
true
);