MediaWiki:Gadget-ImageAnnotator.js: Difference between revisions

Content deleted Content added
lint, and phase out legacy getElementsByClassName
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.
Please upgrade to https://commons.wikimedia.org/wiki/MediaWiki:Gadget-ImageAnnotator-v3.js.
 
Image annotations. Draw rectangles onto image thumbnail displayed on image description
Line 22 ⟶ 27:
*/
 
// 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 ⟶ 41:
 
(function () { // Local scope
 
var conf = mw.config.get([
'skin',
'stylepath'
]);
 
var ImageAnnotator_config = null;
Line 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 ⟶ 78:
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 ⟶ 90:
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 ⟶ 128:
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 ⟶ 167:
},
 
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 ⟶ 211:
},
 
display : function (evt)
{
if (!this.content) {
this.content = LAPI.make('div');
Line 256 ⟶ 255:
},
 
edit : function (evt)
{
if (IA.canEdit()) IA.editor.editNote(this);
if (evt) return LAPI.Evt.kill(evt);
Line 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 297 ⟶ 299:
LAPI.Ajax.editPage(
wgPageName
, function (doc, editForm, failureFunc, revision_id) {
});{
try {
if (revision_id && revision_id != wgCurRevisionId)
Line 374 ⟶ 377:
},
 
destroy : function ()
{
if (this.view) LAPI.DOM.removeNode(this.view);
if (this.dummy) LAPI.DOM.removeNode(this.dummy);
Line 386 ⟶ 390:
},
 
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 ⟶ 411:
ImageAnnotationEditor.prototype =
{
initialize : function ()
{
var editor_width = 50;
// Respect potential user-defined width setting
Line 500 ⟶ 507:
},
 
editNote : function (note)
{
var same_note = (note == this.note);
this.note = note;
Line 549 ⟶ 557:
},
 
open_editor : function (same_note, cover)
{
this.editor.hidePreview();
if (!same_note || this.editor.textarea.readOnly)
Line 587 ⟶ 596:
},
 
hide_editor : function (evt)
{
if (!this.visible) return;
this.visible = false;
Line 607 ⟶ 617:
},
 
save : function (editor)
{
var data = editor.getText();
if (!data || !data.length) {
Line 693 ⟶ 704:
LAPI.Ajax.editPage(
wgPageName
, function (doc, editForm, failureFunc, revision_id) {
{
try {
if (revision_id && revision_id != wgCurRevisionId)
Line 820 ⟶ 832:
);
}
, function (request, ex) {
{
self.editor.busy(false);
self.saving = false;
Line 830 ⟶ 843:
// 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 ⟶ 868:
},
 
onpreview : function (editor)
{
if (this.tooltip) this.tooltip.size_change();
},
 
cancel : function (editor)
{
if (!this.note) return;
if (!this.note.content) {
Line 869 ⟶ 884:
},
 
close_tooltip : function (tooltip, evt)
{
this.hide_editor(evt);
this.cancel();
Line 880 ⟶ 896:
ImageNotesViewer.prototype =
{
initialize : function (descriptor, may_edit)
{
Object.merge(descriptor, this);
this.annotations = [];
Line 890 ⟶ 907:
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 ⟶ 925:
},
 
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 ⟶ 993:
(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,004:
&& 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,020:
}
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,053:
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,068:
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,094:
&& 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,152:
},
 
cannotEdit : function ()
{
if (!this.may_edit) return;
this.may_edit = false;
Line 1,137 ⟶ 1,159:
},
 
setShowHideEvents : function (set)
{
if (this.icon) return;
if (set) {
Line 1,151 ⟶ 1,174:
},
 
removeMoveListener : function ()
{
if (this.icon) return;
this.move_listening = false;
Line 1,161 ⟶ 1,185:
},
 
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,206:
// 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,217:
},
 
toggle : function (dummies)
{
var i;
if (!this.annotations || this.annotations.length === 0 || this.icon) return;
Line 1,215 ⟶ 1,241:
},
 
show : function (evt)
{
if (this.visible || this.icon) return;
this.toggle(IA.is_adding || IA.is_editing);
Line 1,226 ⟶ 1,253:
},
 
hide : function (evt)
{
if (this.icon) return true;
if (!this.visible) {
Line 1,286 ⟶ 1,314:
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,332:
},
 
check_hide : function (evt)
{
if (this.icon) return true;
if (this.visible)
Line 1,310 ⟶ 1,340:
},
 
register : function (new_note)
{
this.annotations[this.annotations.length] = new_note;
if (new_note.model.id > 0) {
Line 1,319 ⟶ 1,350:
},
 
deregister : function (note)
{
Array.remove(this.annotations, note);
if (note.model.id == this.max_id) this.max_id--;
Line 1,325 ⟶ 1,357:
},
 
setDefaultMsg : function ()
{
if (this.annotations && this.annotations.length && this.msg) {
LAPI.DOM.removeChildren(this.msg);
Line 1,357 ⟶ 1,390:
};
 
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,428:
],
 
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,476:
&& typeof LAPI.Ajax !== 'undefined'
&& typeof LAPI.Ajax.getRequest !== 'undefined'
) { )
{
self.haveAjax = (LAPI.Ajax.getRequest() != null);
self.ajaxQueried = true;
Line 1,453 ⟶ 1,488:
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,510:
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,520:
|| !config.thumbsEnabled()
|| namespaceCheck(window.ImageAnnotator_no_thumbs || null)
) { )
},{
self.rules.thumbs.show = false;
}
Line 1,490 ⟶ 1,528:
else if ( !config.sharedImagesEnabled()
|| namespaceCheck(window.ImageAnnotator_no_shared || null)
) { )
{
self.rules.shared.show = false;
}
Line 1,515 ⟶ 1,554:
if ( typeof self.rules.inline.show === 'undefined'
&& rules.className.indexOf('wpImageAnnotatorDisplay') >= 0
) { )
var item; {
self.rules.inline.show = true;
}
Line 1,523 ⟶ 1,563:
if ( typeof self.rules.thumbs.show === 'undefined'
&& rules.className.indexOf('wpImageAnnotatorThumbDisplay') >= 0
) { )
{
self.rules.thumbs.show = true;
}
Line 1,532 ⟶ 1,573:
self.rules.thumbs.icon = true;
}
if (rules.className.indexOf('wpImageAnnotatorOnlyLocal') >= 0) {
{
self.rules.shared.show = false;
}
Line 1,596 ⟶ 1,638:
}
} 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,646:
|| (self.thumbs.length)
|| (self.other_images.length)
) { )
{
// Publish parts of config.
ImageAnnotator.UI = config.UI;
Line 1,616 ⟶ 1,658:
},
 
wait_for_required_libraries : function ()
{
if (typeof Tooltip == 'undefined' || typeof LAPI == 'undefined') {
if (IA.install_attempts++ < IA.max_install_attempts) {
Line 1,629 ⟶ 1,672:
},
 
setup: function ()
{
var self = IA;
self.imgs = [];
Line 1,640 ⟶ 1,684:
)
;
 
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,722:
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,756:
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,829:
}
 
function setup_images (list) {
{
Array.forEach(list,
function (elem) {
Line 1,799 ⟶ 1,848:
}
 
self.may_edit = self.may_edit && ___location.href.search(/[?&]oldid=/) < 0;
 
if (self.haveAjax) {
Line 1,841 ⟶ 1,890:
var done = 0;
 
function check_done (length) {
{
done += length;
if (done >= names.length) {
Line 1,849 ⟶ 1,899:
}
 
function make_calls (execute_call, url_limit) {
{
function build_titles (from, length, url_limit) {
{
var done = 0;
var text = '';
Line 1,874 ⟶ 1,926:
}
 
function set_info (json) {
{
try {
if (json && json.query && json.query.pages) {
Line 1,920 ⟶ 1,973:
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 ⟶ 1,996:
// 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,025:
},
 
setup_ui : function ()
{
// Complete the UI object we've gotten from config.
 
Line 2,000 ⟶ 2,054:
};
 
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,071:
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,081:
};
 
ImageAnnotator.UI.get = function (id, basic, no_plea) {
{
var self = ImageAnnotator.UI;
if (!self.repo) self.setup();
Line 2,057 ⟶ 2,112:
};
 
ImageAnnotator.UI.get_plea = function () {
{
var self = ImageAnnotator.UI;
var translate = self.get('wpTranslate', false, true) || 'translate';
Line 2,075 ⟶ 2,131:
};
 
ImageAnnotator.UI.init = function (html_text_or_json) {
{
var text;
if (typeof html_text_or_json === 'string')
Line 2,093 ⟶ 2,150:
}
 
var node = LAPI.make('div', null, { display: 'none' });
document.body.appendChild(node);
try {
Line 2,110 ⟶ 2,167:
+ '|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,180:
}
 
function get_ui () {
{
IA.haveAjax = (LAPI.Ajax.getRequest() != null);
IA.ajaxQueried = true;
Line 2,156 ⟶ 2,215:
},
 
setup_step_two : function ()
{
var self = IA;
 
Line 2,178 ⟶ 2,238:
},
 
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,256:
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,285:
&& !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,295:
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,400:
}
 
function start_tracking (evt) {
{
if (!self.is_tracking) {
self.is_tracking = true;
Line 2,461 ⟶ 2,527:
// 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,635:
}
 
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,712:
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,722:
, 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,742:
);
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,778:
},
 
show_zoom : function ()
{
var self = IA;
if ( ( self.viewers[0].factors.dx < self.zoom_threshold
Line 2,709 ⟶ 2,785:
)
|| 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,876:
},
 
update_zoom : function (evt)
{
if (!evt) return; // We need an event to calculate positions!
var self = IA;
Line 2,835 ⟶ 2,913:
},
 
hide_zoom : function (evt)
{
if (!IA.zoom) return;
if (evt) {
Line 2,844 ⟶ 2,923:
},
 
createHelpLink : function ()
{
var msg = ImageAnnotator.UI.get('wpImageAnnotatorHelp', false, true);
if (!msg || !msg.lastChild) return null;
Line 2,901 ⟶ 2,981:
},
 
get_cover : function ()
{
var self = IA;
var shim;
Line 2,959 ⟶ 3,040:
},
 
show_cover : function ()
{
var self = IA;
if (self.cover && !self.cover_visible) {
Line 2,972 ⟶ 3,054:
},
 
hide_cover : function ()
{
var self = IA;
if (self.cover && self.cover_visible) {
Line 2,985 ⟶ 3,068:
},
 
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,080:
},
 
getItem : function (what, scope)
{
var node = IA.getRawItem(what, scope);
if (!node) return null;
Line 3,002 ⟶ 3,087:
},
 
getIntItem : function (what, scope)
{
var x = IA.getItem(what, scope);
if (x !== null) x = parseInt (x, 10);
Line 3,008 ⟶ 3,094:
},
 
findNote : function (text, id)
{
function find (text, id, delim) {
var start = delim.start.replace('$1', id);
Line 3,026 ⟶ 3,113:
},
 
setWikitext : function (pagetext)
{
var self = IA;
if (self.wiki_read) return;
Line 3,050 ⟶ 3,138:
},
 
setSummary : function (summary, initial_text, note_text)
{
if (initial_text.contains('$1')) {
var max = (summary.maxlength || 200) - initial_text.length;
Line 3,062 ⟶ 3,151:
},
 
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,170:
},
 
canEdit : function ()
{
var self = IA;
if (self.may_edit) {
Line 3,100 ⟶ 3,191:
 
}; // 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
);