Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
- Opera: Press Ctrl-F5.
/**
* Gadget, FabStationUIExtender, v0.33
*/
var FabStationUIExtender = {
consts: {
CLASSNAME_CANVAS: '.fab-station-ui__canvas',
CLASSNAME_HUD_XHAIR: 'fab-station-ui__hud-crosshair',
CLASSNAME_HUD_ZOOM: 'fab-station-ui__hud-zoom',
CLASSNAME_SCALE_CTNR: '.fab-station-ui__scale-container',
CLASSNAME_SCROLL_CTNR: '.fab-station-ui__scroll-container',
CLASSNAME_VIEWPORT: '.fab-station-ui__viewport',
CLASSNAME_ZOUT_FLAG: 'zoomed-out',
DATA_KEY_STATE: 'fab-station-ui-state',
DATA_KEY_STATE_INITIAL: 'fab-station-ui-initial-state',
ZOOM_LOW: 'zoomLow',
ZOOM_HIGH: 'zoomHigh',
},
cfg: {
zoomBtnMargin: 100,
zoomOutFactor: 0.5,
},
messages: {
labelZoomIn: '+ZOOM',
labelZoomOut: '-ZOOM',
},
utils: {
extractInitialState: function(ctx, $viewport) {
var $canvasScaler = $viewport.find(ctx.consts.CLASSNAME_SCALE_CTNR).eq(0);
return {
canvasFullWidth: $canvasScaler.width(),
canvasFullHeight: $canvasScaler.height(),
};
},
getFocusCoords: function(ctx, $viewport) {
var $canvasScroller = $viewport.find(ctx.consts.CLASSNAME_SCROLL_CTNR).eq(0);
return {
left: $viewport.width() / 2 + $canvasScroller.scrollLeft(),
top: $viewport.height() / 2 + $canvasScroller.scrollTop(),
};
},
},
init: function($content) {
var ctx = this;
var consts = ctx.consts;
var utils = ctx.utils;
var viewports = $content.find(consts.CLASSNAME_VIEWPORT);
viewports.each(function() {
var $viewport = $(this);
// avoid repeat initialization
if ($viewport.data(consts.DATA_KEY_STATE_INITIAL))
return;
$viewport.data(consts.DATA_KEY_STATE_INITIAL, utils.extractInitialState(ctx, $viewport));
$viewport.data(consts.DATA_KEY_STATE, {
zoomedOutAt: null,
});
ctx.setViewportZoom($viewport, consts.ZOOM_HIGH, true);
var $zoomBtn = $('<div />').addClass(consts.CLASSNAME_HUD_ZOOM);
ctx.setZoomBtnState($zoomBtn, false);
$zoomBtn.on('click', function() {
if ($viewport.data(consts.DATA_KEY_STATE).zoomedOutAt == null) {
ctx.setViewportZoom($viewport, consts.ZOOM_LOW);
ctx.setZoomBtnState($zoomBtn, true);
} else {
ctx.setViewportZoom($viewport, consts.ZOOM_HIGH);
ctx.setZoomBtnState($zoomBtn, false);
}
});
$viewport.append($zoomBtn);
var $crosshair = $('<div />').addClass(consts.CLASSNAME_HUD_XHAIR);
$viewport.append($crosshair);
});
},
setViewportZoom: function($viewport, zoomLevel, initial) {
var ctx = this;
var consts = ctx.consts;
var utils = ctx.utils;
if (zoomLevel != consts.ZOOM_LOW && zoomLevel != consts.ZOOM_HIGH)
throw new RangeError('setViewportZoom: incorrect zoom', zoomLevel);
var state = $viewport.data(consts.DATA_KEY_STATE)
var initialState = $viewport.data(consts.DATA_KEY_STATE_INITIAL);
var $canvas = $viewport.find(consts.CLASSNAME_CANVAS).eq(0);
var $canvasScroller = $viewport.find(consts.CLASSNAME_SCROLL_CTNR).eq(0);
var $canvasScaler = $viewport.find(consts.CLASSNAME_SCALE_CTNR).eq(0);
if (initial) {
$viewport.css('width', initialState.canvasFullWidth + ctx.cfg.zoomBtnMargin + 10);
$canvasScaler.css('width', initialState.canvasFullWidth + ctx.cfg.zoomBtnMargin);
}
if ((initial || state.zoomedOutAt == null) && zoomLevel === consts.ZOOM_LOW) {
var focusCoords = utils.getFocusCoords(ctx, $viewport);
$viewport
.data(consts.DATA_KEY_STATE, Object.assign({}, state, { zoomedOutAt: focusCoords }))
.addClass(consts.CLASSNAME_ZOUT_FLAG);
$canvas.css({
transformOrigin: focusCoords.left + 'px ' + focusCoords.top + 'px',
transform: 'scale(' + ctx.cfg.zoomOutFactor + ')',
});
} else if ((initial || state.zoomedOutAt != null) && zoomLevel === consts.ZOOM_HIGH) {
var focusCoords = utils.getFocusCoords(ctx, $viewport);
$viewport
.data(consts.DATA_KEY_STATE, Object.assign({}, state, { zoomedOutAt: null }))
.removeClass(consts.CLASSNAME_ZOUT_FLAG);
if (!initial) {
var targetScroll = {
left: $canvasScroller.scrollLeft() + focusCoords.left - state.zoomedOutAt.left,
top: $canvasScroller.scrollTop() + focusCoords.top - state.zoomedOutAt.top,
};
$canvasScroller.scrollLeft(targetScroll.left).scrollTop(targetScroll.top);
}
$canvas.css({
transformOrigin: '',
transform: '',
});
}
},
setZoomBtnState: function($btn, zoomedOut) {
var ctx = this;
if (zoomedOut) {
$btn.text(ctx.messages.labelZoomIn);
} else {
$btn.text(ctx.messages.labelZoomOut);
}
},
};
Object.freeze(FabStationUIExtender.utils);
Object.freeze(FabStationUIExtender);
mw.hook('wikipage.content').add(function($content) { FabStationUIExtender.init($content) });