MediaWiki:Gadget-ImageAnnotator.js: Difference between revisions

Content deleted Content added
No edit summary
No edit summary
Line 2:
 
/*
ImageAnnotator v3v2.03.02
 
ATTENTION:
This legacy version of ImageAnnotator is on longer maintained and kept at this address
for backwards compatibility with wikis running MediaWiki 1.23 or older.
User Krinkle has decided to fork this to
https://commons.wikimedia.org/wiki/MediaWiki:Gadget-ImageAnnotator-v3.js.
and to make sure the Commons uses _that_.
}
For any problems with that v3 version, please contact https://commons.wikimedia.org/wiki/User:Krinkle.
 
Image annotations. Draw rectangles onto image thumbnail displayed on image description
Line 22 ⟶ 31:
*/
 
// Global: importScript, importScriptURI (wikibitswiki.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 36 ⟶ 45:
 
(function () { // Local scope
 
var conf = mw.config.get([
'skin',
'stylepath'
]);
 
var ImageAnnotator_config = null;
Line 61 ⟶ 65:
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 ⟶ 82:
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 ⟶ 94:
view_y = Math.floor(y / viewer.factors.dy);
this.view =
LAPI.make(
'div', null, {
, { position : 'absolute',
,display : 'none',
,lineHeight : '0px' // IE
lineHeight ,fontSize : '0px', // IE
// IE ,top : '' + view_y + 'px'
fontSize ,left : '0px', + view_x + 'px'
top ,width : '' + view_yview_w + 'px',
left ,height : '' + view_xview_h + '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 ⟶ 132:
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'
{
left ,width: '' + view_xview_w + 'px', height: '' + view_h + 'px'}
, top: '' + view_y + 'px',this.view.style
width: '' + view_w + 'px',
height: '' + view_h + 'px'
},
this.view.style
);
this.view.style.zIndex = 500; // Below tooltips
Line 170 ⟶ 171:
},
 
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 213 ⟶ 215:
},
 
display : function (evt)
{
if (!this.content) {
this.content = LAPI.make('div');
Line 256 ⟶ 259:
},
 
edit : function (evt)
{
if (IA.canEdit()) IA.editor.editNote(this);
if (evt) return LAPI.Evt.kill(evt);
Line 262 ⟶ 266:
},
 
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 297 ⟶ 303:
LAPI.Ajax.editPage(
wgPageName
, function (doc, editForm, failureFunc, revision_id) {
});{
try {
if (revision_id && revision_id != wgCurRevisionId)
Line 374 ⟶ 381:
},
 
destroy : function ()
{
if (this.view) LAPI.DOM.removeNode(this.view);
if (this.dummy) LAPI.DOM.removeNode(this.dummy);
Line 386 ⟶ 394:
},
 
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 405 ⟶ 415:
ImageAnnotationEditor.prototype =
{
initialize : function ()
{
var editor_width = 50;
// Respect potential user-defined width setting
Line 500 ⟶ 511:
},
 
editNote : function (note)
{
var same_note = (note == this.note);
this.note = note;
Line 549 ⟶ 561:
},
 
open_editor : function (same_note, cover)
{
this.editor.hidePreview();
if (!same_note || this.editor.textarea.readOnly)
Line 587 ⟶ 600:
},
 
hide_editor : function (evt)
{
if (!this.visible) return;
this.visible = false;
Line 607 ⟶ 621:
},
 
save : function (editor)
{
var data = editor.getText();
if (!data || !data.length) {
Line 693 ⟶ 708:
LAPI.Ajax.editPage(
wgPageName
, function (doc, editForm, failureFunc, revision_id) {
{
try {
if (revision_id && revision_id != wgCurRevisionId)
Line 820 ⟶ 836:
);
}
, function (request, ex) {
{
self.editor.busy(false);
self.saving = false;
Line 830 ⟶ 847:
// 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 855 ⟶ 872:
},
 
onpreview : function (editor)
{
if (this.tooltip) this.tooltip.size_change();
},
 
cancel : function (editor)
{
if (!this.note) return;
if (!this.note.content) {
Line 869 ⟶ 888:
},
 
close_tooltip : function (tooltip, evt)
{
this.hide_editor(evt);
this.cancel();
Line 880 ⟶ 900:
ImageNotesViewer.prototype =
{
initialize : function (descriptor, may_edit)
{
Object.merge(descriptor, this);
this.annotations = [];
Line 890 ⟶ 911:
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 908 ⟶ 929:
},
 
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 {
$fullnamename = $getElementsByClassName (this.scope).find(, '*', '.wpImageAnnotatorFullName');
this.realName = $fullname((name && name.length) ? $fullnameLAPI.textDOM.getInnerText(name[0]) : '');
this.imgName = this.realName;
}
 
var annotations = getElementsByClassName (this.scope.getElementsByClassName(, 'div', IA.annotation_class);
 
if (!this.may_edit && (!annotations || annotations.length === 0))
Line 976 ⟶ 997:
(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 986 ⟶ 1,008:
&& 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,001 ⟶ 1,024:
}
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,034 ⟶ 1,057:
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,048 ⟶ 1,072:
Array.forEach(this.annotations, (function (note) {this.img_div.appendChild(note.view);}).bind(this));
if (this.isThumbnail) {
this.main_div = getElementsByClassName (this.file_div.getElementsByClassName(, 'div', 'thumbcaption');
if (!this.main_div || this.main_div.length === 0)
this.main_div = null;
else
Line 1,074 ⟶ 1,098:
&& ImageAnnotator_config.displayCaptionInArticles
(name, this.isLocal, this.thumb, this.full_img, annotations.length, this.isThumbnail)
) { )
{
this.msg = LAPI.make('div', null, { display: 'none' });
if (IA.is_rtl) {
this.msg.style.direction = 'rtl';
Line 1,131 ⟶ 1,156:
},
 
cannotEdit : function ()
{
if (!this.may_edit) return;
this.may_edit = false;
Line 1,137 ⟶ 1,163:
},
 
setShowHideEvents : function (set)
{
if (this.icon) return;
if (set) {
Line 1,151 ⟶ 1,178:
},
 
removeMoveListener : function ()
{
if (this.icon) return;
this.move_listening = false;
Line 1,161 ⟶ 1,189:
},
 
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,181 ⟶ 1,210:
// 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,192 ⟶ 1,221:
},
 
toggle : function (dummies)
{
var i;
if (!this.annotations || this.annotations.length === 0 || this.icon) return;
Line 1,215 ⟶ 1,245:
},
 
show : function (evt)
{
if (this.visible || this.icon) return;
this.toggle(IA.is_adding || IA.is_editing);
Line 1,226 ⟶ 1,257:
},
 
hide : function (evt)
{
if (this.icon) return true;
if (!this.visible) {
Line 1,286 ⟶ 1,318:
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,303 ⟶ 1,336:
},
 
check_hide : function (evt)
{
if (this.icon) return true;
if (this.visible)
Line 1,310 ⟶ 1,344:
},
 
register : function (new_note)
{
this.annotations[this.annotations.length] = new_note;
if (new_note.model.id > 0) {
Line 1,319 ⟶ 1,354:
},
 
deregister : function (note)
{
Array.remove(this.annotations, note);
if (note.model.id == this.max_id) this.max_id--;
Line 1,325 ⟶ 1,361:
},
 
setDefaultMsg : function ()
{
if (this.annotations && this.annotations.length && this.msg) {
LAPI.DOM.removeChildren(this.msg);
Line 1,357 ⟶ 1,394:
};
 
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,394 ⟶ 1,432:
],
 
tooltip_styles : // The style for all our tooltips
{ border : '1px solid #8888aa'
tooltip_styles: {
, backgroundColor border: '1px solid #8888aaffffe0'
, backgroundColorpadding : '#ffffe00.3em'
, fontSize : (conf.(skin && (skin === 'monobook' || skin == 'modern')) ? '127%' : '100%')
, padding: '0.3em'
, 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,442 ⟶ 1,480:
&& typeof LAPI.Ajax !== 'undefined'
&& typeof LAPI.Ajax.getRequest !== 'undefined'
) { )
{
self.haveAjax = (LAPI.Ajax.getRequest() != null);
self.ajaxQueried = true;
Line 1,453 ⟶ 1,492:
self.may_edit = wgNamespaceNumber >= 0 && wgArticleId > 0 && self.haveAjax && config.editingEnabled();
 
function namespaceCheck (list) {
{
if (!list || Object.prototype.toString.call(list) !== '[object Array]') return false;
for (var i = 0; i < list.length; i++) {
Line 1,474 ⟶ 1,514:
if ( !self.haveAjax
|| !config.generalImagesEnabled()
|| namespaceCheck (window.ImageAnnotator_no_images || null)
) { )
{
self.rules.inline.show = false;
self.rules.thumbs.show = false;
Line 1,483 ⟶ 1,524:
|| !config.thumbsEnabled()
|| namespaceCheck(window.ImageAnnotator_no_thumbs || null)
) { )
},{
self.rules.thumbs.show = false;
}
Line 1,490 ⟶ 1,532:
else if ( !config.sharedImagesEnabled()
|| namespaceCheck(window.ImageAnnotator_no_shared || null)
) { )
{
self.rules.shared.show = false;
}
Line 1,515 ⟶ 1,558:
if ( typeof self.rules.inline.show === 'undefined'
&& rules.className.indexOf('wpImageAnnotatorDisplay') >= 0
) { )
var item; {
self.rules.inline.show = true;
}
Line 1,523 ⟶ 1,567:
if ( typeof self.rules.thumbs.show === 'undefined'
&& rules.className.indexOf('wpImageAnnotatorThumbDisplay') >= 0
) { )
{
self.rules.thumbs.show = true;
}
Line 1,532 ⟶ 1,577:
self.rules.thumbs.icon = true;
}
if (rules.className.indexOf('wpImageAnnotatorOnlyLocal') >= 0) {
{
self.rules.shared.show = false;
}
Line 1,596 ⟶ 1,642:
}
} 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,605 ⟶ 1,650:
|| (self.thumbs.length)
|| (self.other_images.length)
) { )
{
// Publish parts of config.
ImageAnnotator.UI = config.UI;
Line 1,616 ⟶ 1,662:
},
 
wait_for_required_libraries : function ()
{
if (typeof Tooltip == 'undefined' || typeof LAPI == 'undefined') {
if (IA.install_attempts++ < IA.max_install_attempts) {
Line 1,629 ⟶ 1,676:
},
 
setup: function ()
{
var self = IA;
self.imgs = [];
Line 1,640 ⟶ 1,688:
)
;
 
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,674 ⟶ 1,726:
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,708 ⟶ 1,760:
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,781 ⟶ 1,833:
}
 
function setup_images (list) {
{
Array.forEach(list,
function (elem) {
Line 1,841 ⟶ 1,894:
var done = 0;
 
function check_done (length) {
{
done += length;
if (done >= names.length) {
Line 1,849 ⟶ 1,903:
}
 
function make_calls (execute_call, url_limit) {
{
function build_titles (from, length, url_limit) {
{
var done = 0;
var text = '';
Line 1,874 ⟶ 1,930:
}
 
function set_info (json) {
{
try {
if (json && json.query && json.query.pages) {
Line 1,920 ⟶ 1,977:
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
};
ImageAnnotator.info_callbacks[idx].script =
IA.getScript(
Line 1,943 ⟶ 2,000:
// 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 1,972 ⟶ 2,029:
},
 
setup_ui : function ()
{
// Complete the UI object we've gotten from config.
 
Line 2,000 ⟶ 2,058:
};
 
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,017 ⟶ 2,075:
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,027 ⟶ 2,085:
};
 
ImageAnnotator.UI.get = function (id, basic, no_plea) {
{
var self = ImageAnnotator.UI;
if (!self.repo) self.setup();
Line 2,057 ⟶ 2,116:
};
 
ImageAnnotator.UI.get_plea = function () {
{
var self = ImageAnnotator.UI;
var translate = self.get('wpTranslate', false, true) || 'translate';
Line 2,075 ⟶ 2,135:
};
 
ImageAnnotator.UI.init = function (html_text_or_json) {
{
var text;
if (typeof html_text_or_json === 'string')
Line 2,093 ⟶ 2,154:
}
 
var node = LAPI.make('div', null, { display: 'none' });
document.body.appendChild(node);
try {
Line 2,110 ⟶ 2,171:
+ '|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,122 ⟶ 2,184:
}
 
function get_ui () {
{
IA.haveAjax = (LAPI.Ajax.getRequest() != null);
IA.ajaxQueried = true;
Line 2,156 ⟶ 2,219:
},
 
setup_step_two : function ()
{
var self = IA;
 
Line 2,178 ⟶ 2,242:
},
 
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,195 ⟶ 2,260:
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,223 ⟶ 2,289:
&& !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,232 ⟶ 2,299:
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,335 ⟶ 2,404:
}
 
function start_tracking (evt) {
{
if (!self.is_tracking) {
self.is_tracking = true;
Line 2,461 ⟶ 2,531:
// 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 composecomposer (list, from, length, url_limit) {
{
function composercompose (list, from, length, url_limit) {
{
var text = '';
var done = 0;
Line 2,566 ⟶ 2,639:
}
 
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].getElementsByClassName(, 'div', 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].getElementsByClassName(, 'div', '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,638 ⟶ 2,716:
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,647 ⟶ 2,726:
, 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
};
ImageAnnotator.script_callbacks[idx].script =
IA.getScript(
Line 2,667 ⟶ 2,746:
);
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,703 ⟶ 2,782:
},
 
show_zoom : function ()
{
var self = IA;
if ( ( self.viewers[0].factors.dx < self.zoom_threshold
Line 2,709 ⟶ 2,789:
)
|| 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,799 ⟶ 2,880:
},
 
update_zoom : function (evt)
{
if (!evt) return; // We need an event to calculate positions!
var self = IA;
Line 2,835 ⟶ 2,917:
},
 
hide_zoom : function (evt)
{
if (!IA.zoom) return;
if (evt) {
Line 2,844 ⟶ 2,927:
},
 
createHelpLink : function ()
{
var msg = ImageAnnotator.UI.get('wpImageAnnotatorHelp', false, true);
if (!msg || !msg.lastChild) return null;
Line 2,901 ⟶ 2,985:
},
 
get_cover : function ()
{
var self = IA;
var shim;
Line 2,959 ⟶ 3,044:
},
 
show_cover : function ()
{
var self = IA;
if (self.cover && !self.cover_visible) {
Line 2,972 ⟶ 3,058:
},
 
hide_cover : function ()
{
var self = IA;
if (self.cover && self.cover_visible) {
Line 2,985 ⟶ 3,072:
},
 
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 2,996 ⟶ 3,084:
},
 
getItem : function (what, scope)
{
var node = IA.getRawItem(what, scope);
if (!node) return null;
Line 3,002 ⟶ 3,091:
},
 
getIntItem : function (what, scope)
{
var x = IA.getItem(what, scope);
if (x !== null) x = parseInt (x, 10);
Line 3,008 ⟶ 3,098:
},
 
findNote : function (text, id)
{
function find (text, id, delim) {
var start = delim.start.replace('$1', id);
Line 3,026 ⟶ 3,117:
},
 
setWikitext : function (pagetext)
{
var self = IA;
if (self.wiki_read) return;
Line 3,050 ⟶ 3,142:
},
 
setSummary : function (summary, initial_text, note_text)
{
if (initial_text.contains('$1')) {
var max = (summary.maxlength || 200) - initial_text.length;
Line 3,062 ⟶ 3,155:
},
 
getScript : function (url, bypass_local_cache, bypass_caches)
{
// Don't use LAPI here, it may not yet be available
if (bypass_caches) {
Line 3,080 ⟶ 3,174:
},
 
canEdit : function ()
{
var self = IA;
if (self.may_edit) {
Line 3,100 ⟶ 3,195:
 
}; // 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); }
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'
+ '&dummy=' + Math.floor((new Date()).getTime() / (14400 * 1000)), // 4 hours
// Cache 4 hours
, true // No local caching!
+ '&dummy=' + Math.floor((new Date()).getTime() / (14400 * 1000)),
// No local caching!
true
);