Page MenuHomePhabricator
Paste P17263

(An Untitled Masterwork)
ActivePublic

Authored by Yash4357 on Sun, Sep 12, 8:25 AM.
Author: yash9265 <yashagrawal9265@gmail.com>
Date: Thu Aug 12 03:14:33 2021 +0530
Use Openseadragon library for PRP image zoom
Implemented zooming and panning for the ProofreadPage
using the OpenSeadragon library.
This change should allow users to zoom and pan images
while using the ProofreadPage which should improve the
user experience of users who work on scripts which
have a small font size.
Bug: T283917
Change-Id: Id6a7f66c05a8e4346c5daff09a6e95165c214a6d
diff --git a/extension.json b/extension.json
index 5245e420..a6d7f401 100644
--- a/extension.json
+++ b/extension.json
@@ -66,16 +66,6 @@
"ProofreadPageTestCase": "tests/phpunit/ProofreadPageTestCase.php"
},
"ResourceModules": {
- "jquery.mousewheel": {
- "scripts": "jquery/jquery.mousewheel.js"
- },
- "jquery.prpZoom": {
- "scripts": "jquery/jquery.prpZoom.js",
- "dependencies": [
- "jquery.ui",
- "jquery.mousewheel"
- ]
- },
"ext.proofreadpage.base": {
"styles": "ext.proofreadpage.base.css",
"targets": [
@@ -92,12 +82,13 @@
"dependencies": [
"ext.proofreadpage.base",
"ext.proofreadpage.page",
- "jquery.prpZoom",
+ "ext.proofreadpage.openseadragon",
"mediawiki.user",
"user.options",
"jquery.textSelection",
"ext.proofreadpage.icons",
"ext.proofreadpage.ve.pageTarget.init",
+ "oojs-ui-widgets",
"oojs-ui.styles.icons-media"
],
"messages": [
@@ -292,9 +283,9 @@
"dependencies": [
"ext.visualEditor.mwcore",
"ext.visualEditor.desktopArticleTarget",
+ "ext.proofreadpage.openseadragon",
"oojs-ui.styles.icons-moderation",
"oojs-ui.styles.icons-media",
- "jquery.prpZoom",
"ext.proofreadpage.icons"
],
"messages": [
diff --git a/includes/Page/PageDisplayHandler.php b/includes/Page/PageDisplayHandler.php
index 4656608c..273834e6 100644
--- a/includes/Page/PageDisplayHandler.php
+++ b/includes/Page/PageDisplayHandler.php
@@ -3,6 +3,7 @@
namespace ProofreadPage\Page;
use Html;
+use Linker;
use MediaTransformOutput;
use OutOfBoundsException;
use ProofreadPage\Context;
@@ -127,8 +128,12 @@ class PageDisplayHandler {
*/
public function buildPageContainerEnd( Title $pageTitle ) {
return Html::closeElement( 'div' ) .
- Html::openElement( 'div', [ 'class' => 'prp-page-image' ] ) .
- $this->buildImageHtml( $pageTitle ) .
+ Html::openElement( 'div', [
+ 'class' => 'prp-page-image'
+ ] ) .
+ $this->buildImageHtml( $pageTitle ) . Html::rawElement( 'div', [
+ 'id' => 'prp-page-image-openseadragon-vertical'
+ ] ) .
Html::closeElement( 'div' ) .
Html::closeElement( 'div' );
}
@@ -202,6 +207,17 @@ class PageDisplayHandler {
if ( !$handler || !$handler->normaliseParams( $image, $transformAttributes ) ) {
return null;
}
- return $image->transform( $transformAttributes ) ?: null;
+
+ $transformedImage = $image->transform( $transformAttributes );
+
+ if ( $transformedImage && $constrainWidth ) {
+ Linker::processResponsiveImages( $image, $transformedImage, $transformAttributes );
+
+ }
+
+ if ( $transformedImage ) {
+ return $transformedImage;
+ }
+ return null;
}
}
diff --git a/modules/jquery/jquery.mousewheel.js b/modules/jquery/jquery.mousewheel.js
deleted file mode 100644
index ad013e97..00000000
--- a/modules/jquery/jquery.mousewheel.js
+++ /dev/null
@@ -1,129 +0,0 @@
-/*! Copyright (c) 2013 Brandon Aaron (http://brandon.aaron.sh)
- * Licensed under the MIT License.
- *
- * Version: 3.1.6
- *
- * Requires: jQuery 1.2.2+
- */
-
-(function ($) {
-
- var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'],
- toBind = ( 'onwheel' in document || document.documentMode >= 9 ) ?
- ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'],
- slice = Array.prototype.slice,
- nullLowestDeltaTimeout, lowestDelta;
-
- if ( $.event.fixHooks ) {
- for ( var i = toFix.length; i; ) {
- $.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks;
- }
- }
-
- $.event.special.mousewheel = {
- version: '3.1.6',
-
- setup: function() {
- if ( this.addEventListener ) {
- for ( var i = toBind.length; i; ) {
- this.addEventListener( toBind[--i], handler, false );
- }
- } else {
- this.onmousewheel = handler;
- }
- },
-
- teardown: function() {
- if ( this.removeEventListener ) {
- for ( var i = toBind.length; i; ) {
- this.removeEventListener( toBind[--i], handler, false );
- }
- } else {
- this.onmousewheel = null;
- }
- }
- };
-
- $.fn.extend({
- mousewheel: function(fn) {
- return fn ? this.bind('mousewheel', fn) : this.trigger('mousewheel');
- },
-
- unmousewheel: function(fn) {
- return this.unbind('mousewheel', fn);
- }
- });
-
-
- function handler(event) {
- var orgEvent = event || window.event,
- args = slice.call(arguments, 1),
- delta = 0,
- deltaX = 0,
- deltaY = 0,
- absDelta = 0;
- event = $.event.fix(orgEvent);
- event.type = 'mousewheel';
-
- // Old school scrollwheel delta
- if ( 'detail' in orgEvent ) { deltaY = orgEvent.detail * -1; }
- if ( 'wheelDelta' in orgEvent ) { deltaY = orgEvent.wheelDelta; }
- if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY; }
- if ( 'wheelDeltaX' in orgEvent ) { deltaX = orgEvent.wheelDeltaX * -1; }
-
- // Firefox < 17 horizontal scrolling related to DOMMouseScroll event
- if ( 'axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
- deltaX = deltaY * -1;
- deltaY = 0;
- }
-
- // Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy
- delta = deltaY === 0 ? deltaX : deltaY;
-
- // New school wheel delta (wheel event)
- if ( 'deltaY' in orgEvent ) {
- deltaY = orgEvent.deltaY * -1;
- delta = deltaY;
- }
- if ( 'deltaX' in orgEvent ) {
- deltaX = orgEvent.deltaX;
- if ( deltaY === 0 ) { delta = deltaX * -1; }
- }
-
- // No change actually happened, no reason to go any further
- if ( deltaY === 0 && deltaX === 0 ) { return; }
-
- // Store lowest absolute delta to normalize the delta values
- absDelta = Math.max( Math.abs(deltaY), Math.abs(deltaX) );
- if ( !lowestDelta || absDelta < lowestDelta ) {
- lowestDelta = absDelta;
- }
-
- // Get a whole, normalized value for the deltas
- delta = Math[ delta >= 1 ? 'floor' : 'ceil' ](delta / lowestDelta);
- deltaX = Math[ deltaX >= 1 ? 'floor' : 'ceil' ](deltaX / lowestDelta);
- deltaY = Math[ deltaY >= 1 ? 'floor' : 'ceil' ](deltaY / lowestDelta);
-
- // Add information to the event object
- event.deltaX = deltaX;
- event.deltaY = deltaY;
- event.deltaFactor = lowestDelta;
-
- // Add event and delta to the front of the arguments
- args.unshift(event, delta, deltaX, deltaY);
-
- // Clearout lowestDelta after sometime to better
- // handle multiple device types that give different
- // a different lowestDelta
- // Ex: trackpad = 3 and mouse wheel = 120
- if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); }
- nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200);
-
- return ($.event.dispatch || $.event.handle).apply(this, args);
- }
-
- function nullLowestDelta() {
- lowestDelta = null;
- }
-
-})(jQuery);
diff --git a/modules/jquery/jquery.prpZoom.js b/modules/jquery/jquery.prpZoom.js
deleted file mode 100644
index d10fdfd0..00000000
--- a/modules/jquery/jquery.prpZoom.js
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * jQuery PrpZoom Plugin
- * Image zoom library
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-( function( $ ) {
- 'use strict';
-
- $.widget( 'mw.prpZoom', {
-
- options: {
- zoomStep: 6,
- animationDuration: 10,
- minScaleFactor: 0.2,
- maxScaleFactor: 10
- },
-
- defaultDimensions: {
- width: 0,
- height: 0
- },
-
- zoomStep: {
- width: 0,
- height: 0
- },
-
- zoomOnMouseWheelActivated: false,
-
- _getPosition: function() {
- var position = this.element.position();
- position.width = this.element.width();
- position.height = this.element.height();
- return position;
- },
-
- _applyPosition: function( position ) {
- this.element.animate( {
- top: Math.round( position.top ),
- left: Math.round( position.left ),
- width: Math.round( position.width ),
- height: Math.round( position.height )
- }, this.options.animationDuration );
- },
-
- _getScaleFactor: function( position ) {
- return position.width / this.defaultDimensions.width;
- },
-
- _create: function() {
- //config params
- this.defaultDimensions = {
- width: this.element.width(),
- height: this.element.height()
- };
- this.zoomStep = {
- width: this.options.zoomStep * this.defaultDimensions.width / 100,
- height: this.options.zoomStep * this.defaultDimensions.height / 100
- };
-
- //setup area
- this.element.parent().css( {
- position: 'relative',
- overflow: 'auto',
- height: this.defaultDimensions.height,
- cursor: 'move'
- } );
-
- this.element.css( {
- position: 'absolute'
- } ).draggable( {
- scroll: true
- } );
-
- this.reset();
-
- var element = this.element;
- $.each( this._events(), function( event, handler ) {
- element.bind( event + '.prpZoom', handler );
- } );
- },
-
- _events: function() {
- var prpZoom = this;
- return {
- 'click': function( event ) {
- prpZoom.zoomOnMouseWheelActivated = !prpZoom.zoomOnMouseWheelActivated;
- },
- //depends on jquery.mousewheel.js
- 'mousewheel': function( event ) {
- if( !prpZoom.zoomOnMouseWheelActivated ) {
- return;
- }
-
- if( event.deltaY > 0 ) {
- prpZoom.zoomIn();
- } else if( event.deltaY < 0 ) {
- prpZoom.zoomOut();
- }
- event.preventDefault(); //Don't scroll while zooming
- }
- };
- },
-
- reset: function() {
- this._applyPosition( {
- top: 0,
- left: 0,
- width: this.defaultDimensions.width,
- height: this.defaultDimensions.height
- } );
- },
-
- zoomIn: function() {
- this._zoom( 1 );
- },
-
- zoomOut: function() {
- this._zoom( -1 );
- },
-
- _zoom: function( proportion ) {
- var position = this._getPosition();
- position.left -= proportion * this.zoomStep.width;
- position.top -= proportion * this.zoomStep.height;
- position.width += 2 * proportion * this.zoomStep.width;
- position.height += 2 * proportion * this.zoomStep.height;
-
- var scaleFactor = this._getScaleFactor( position );
- if( this.options.minScaleFactor > scaleFactor || scaleFactor > this.options.maxScaleFactor ) {
- return;
- }
-
- this._applyPosition( position );
- },
-
- destroy: function() {
- this.element
- .draggable( 'destroy' )
- .css( {
- position: 'static',
- top: '',
- left: '',
- width: '',
- height: ''
- } )
- .parent().css( {
- position: 'static',
- overflow: '',
- height: '',
- cursor: ''
- } );
-
- var element = this.element;
- $.each( this._events(), function( event, handler ) {
- element.unbind( event + '.prpZoom' );
- } );
-
- $.Widget.prototype.destroy.call( this );
- }
- } );
-
-} ) ( jQuery );
\ No newline at end of file
diff --git a/modules/page/ext.proofreadpage.page.edit.css b/modules/page/ext.proofreadpage.page.edit.css
index 660d40c7..18d54f5e 100644
--- a/modules/page/ext.proofreadpage.page.edit.css
+++ b/modules/page/ext.proofreadpage.page.edit.css
@@ -43,6 +43,10 @@
flex: 1;
}
+.prp-page-zoom-interface {
+ float: right;
+}
+
#editform .prp-page-content { /* stylelint-disable-line selector-max-id */
line-height: 1.5em;
}
diff --git a/modules/page/ext.proofreadpage.page.edit.js b/modules/page/ext.proofreadpage.page.edit.js
index 54888102..61a286db 100644
--- a/modules/page/ext.proofreadpage.page.edit.js
+++ b/modules/page/ext.proofreadpage.page.edit.js
@@ -1,6 +1,8 @@
( function () {
'use strict';
-
+ var OpenSeadragon = require( 'ext.proofreadpage.openseadragon' );
+ mw.proofreadpage = {};
+ mw.proofreadpage.OpenSeadragon = OpenSeadragon;
var
/**
* Is the layout horizontal (ie is the scan image on top of the edit area)
@@ -9,21 +11,56 @@
*/
isLayoutHorizontal = false,
+ headersVisible = true,
+
/**
- * The scan image
+ * The edit form
*
* @type {jQuery}
*/
- $zoomImage,
+ $editForm,
- headersVisible = true,
+ /**
+ * image parent container
+ *
+ * @type {jQuery}
+ */
+ $imgCont,
/**
- * The edit form
+ * image parent container
*
* @type {jQuery}
*/
- $editForm;
+ $imgContHorizontal,
+
+ /**
+ * image attribute
+ *
+ * @type {jQuery}
+ */
+ $img,
+
+ /**
+ * image height
+ *
+ * @type {string}
+ */
+ imgHeight,
+
+ /**
+ * image width
+ *
+ * @type {string}
+ */
+ imgWidth,
+
+ /**
+ * image width
+ *
+ * @type {mw.proofreadpage.OpenSeadragon}
+ */
+ viewer = null;
/**
* Returns the value of a user option as boolean
@@ -51,31 +88,61 @@
/**
* Ensure that the zoom system is properly initialized
*
- * @param {Function} success a function to use after making sure that the zoom system is activate
+ * @param {string} id
*/
- function ensureImageZoomInitialization( success ) {
- if ( $zoomImage.data( 'prpZoom' ) ) {
- if ( success ) {
- success();
- }
- return;
- }
-
- mw.loader.using( 'jquery.prpZoom', function () {
- if ( $zoomImage.prop( 'complete' ) ) {
- $zoomImage.prpZoom();
- if ( success ) {
- success();
+ function ensureImageZoomInitialization( id ) {
+ var url1 = $img[ 0 ].getAttribute( 'src' );
+ var srcSet = $img[ 0 ].getAttribute( 'srcset' ).split( ' ' );
+ var url2 = srcSet[ 0 ];
+ var url3 = srcSet[ 2 ];
+ var width = $img[ 0 ].getAttribute( 'width' );
+ var height = $img[ 0 ].getAttribute( 'height' );
+
+ // make space for the OSD viewer
+ $img.hide();
+
+ viewer = OpenSeadragon( {
+ id: id,
+ zoomInButton: 'prp-page-zoomIn',
+ zoomOutButton: 'prp-page-zoomOut',
+ homeButton: 'prp-page-zoomReset',
+ showFullPageControl: false,
+ preserveViewport: true,
+ animationTime: 0.5,
+ visibilityRatio: 0.5,
+ minZoomLevel: 0.5,
+ maxZoomLevel: 4.5,
+ tileSources: {
+ type: 'legacy-image-pyramid',
+ levels: [ {
+ url: url1,
+ height: height,
+ width: width
+ },
+ {
+ url: url2,
+ height: 1.5 * height,
+ width: 1.5 * width
+ },
+ {
+ url: url3,
+ height: 2 * height,
+ width: 2 * width
}
- } else {
- $zoomImage.on( 'load', function () {
- $zoomImage.prpZoom();
- if ( success ) {
- success();
- }
- } );
+ ]
}
} );
+
+ viewer.viewport.goHome = function () {
+ if ( viewer ) {
+ var oldBounds = viewer.viewport.getBounds();
+ var newBounds = new OpenSeadragon.Rect( 0, 0, 1, oldBounds.height / oldBounds.width );
+ viewer.viewport.fitBounds( newBounds, true );
+ }
+ };
+
+ mw.proofreadpage.viewer = viewer;
+
}
/**
@@ -108,35 +175,52 @@
* @param {boolean} [horizontal] Use horizontal layout, inverts if undefined
*/
function toggleLayout( horizontal ) {
- var $container, newHeight, setActive;
+ var newHeight, setActive;
isLayoutHorizontal = horizontal === undefined ? !isLayoutHorizontal : horizontal;
- if ( $zoomImage.data( 'prpZoom' ) ) {
- $zoomImage.prpZoom( 'destroy' );
+ if ( viewer ) {
+ viewer.destroy();
+ viewer = null;
}
- $container = $zoomImage.parent();
-
if ( !isLayoutHorizontal ) {
- $container.appendTo( $editForm.find( '.prp-page-container' ) );
+ $imgCont.css( 'display', 'block' );
+ if ( $imgContHorizontal ) {
+ $imgContHorizontal.css( 'display', 'none' );
+ }
+ $( '.prp-page-image' ).css('display', 'block');
// Switch CSS widths and heights back to the default side-by-size layout.
- $container.css( {
- width: '',
- height: ''
+ $imgCont.css( {
+ width: imgWidth,
+ height: imgHeight
} );
$editForm.find( '.prp-page-content' ).css( {
width: ''
} );
+ $.when( mw.loader.using( 'ext.wikiEditor' ), $.ready ).then( function () {
+ ensureImageZoomInitialization( 'prp-page-image-openseadragon-vertical' );
+ } );
+
// eslint-disable-next-line no-jquery/no-global-selector
$( '#wpTextbox1' ).css( { height: '' } );
- ensureImageZoomInitialization();
+
} else {
- $container.insertBefore( $editForm );
+ if ( !$imgContHorizontal ) {
+ $imgContHorizontal = $imgCont
+ .clone()
+ .attr( 'id', 'prp-page-image-openseadragon-horizontal' );
+ $imgContHorizontal.insertBefore( $editForm );
+ } else {
+ $imgContHorizontal.css( 'display', 'block' );
+ }
+
+ $imgCont.css( 'display', 'none' );
+ $( '.prp-page-image' ).css('display', 'none');
// Set the width and height of the image and form.
- $container.css( {
+ $imgContHorizontal.css( {
width: '100%',
overflow: 'auto',
height: $( window ).height() / 2.7 + 'px'
@@ -145,12 +229,12 @@
width: '100%'
} );
- // Turn on image zoom before setting the image height, or it'll be overridden.
- ensureImageZoomInitialization();
-
// Set the image and the edit box to the same height (of 1/3 of the window each).
newHeight = $( window ).height() / 3 + 'px';
- $container.css( { height: newHeight } );
+ $imgContHorizontal.css( { height: newHeight } );
+ $.when( mw.loader.using( 'ext.wikiEditor' ), $.ready ).then( function () {
+ ensureImageZoomInitialization( 'prp-page-image-openseadragon-horizontal' );
+ } );
// eslint-disable-next-line no-jquery/no-global-selector
$( '#wpTextbox1' ).css( { height: newHeight } );
}
@@ -195,51 +279,35 @@
* Setup the editing interface
*/
function setupWikitextEditor() {
+ var zoomInterface = {
+ zoomIn: new OO.ui.ButtonWidget( {
+ id: 'prp-page-zoomIn',
+ icon: 'zoomIn',
+ framed: false
+ } ),
+ zoomOut: new OO.ui.ButtonWidget( {
+ id: 'prp-page-zoomOut',
+ icon: 'zoomOut',
+ framed: false
+ } ),
+ zoomReset: new OO.ui.ButtonWidget( {
+ id: 'prp-page-zoomReset',
+ icon: 'zoomReset',
+ framed: false
+ } )
+ };
+
+ var $zoomInterfaceDiv = $( '<div>' );
+ $zoomInterfaceDiv.addClass( 'prp-page-zoom-interface' );
+ $zoomInterfaceDiv.append( zoomInterface.zoomIn.$element, zoomInterface.zoomOut.$element, zoomInterface.zoomReset.$element );
+
+ $.when( mw.loader.using( 'ext.wikiEditor' ), $.ready ).then( function () {
+ // eslint-disable-next-line no-jquery/no-global-selector
+ $( '.wikiEditor-ui-toolbar .section-main' ).after( $zoomInterfaceDiv );
+
+ } );
+
var tools = {
- zoom: {
- labelMsg: 'proofreadpage-group-zoom',
- tools: {
- 'zoom-in': {
- labelMsg: 'proofreadpage-button-zoom-in-label',
- type: 'button',
- oouiIcon: 'zoomIn',
- action: {
- type: 'callback',
- execute: function () {
- ensureImageZoomInitialization( function () {
- $zoomImage.prpZoom( 'zoomIn' );
- } );
- }
- }
- },
- 'zoom-out': {
- labelMsg: 'proofreadpage-button-zoom-out-label',
- type: 'button',
- oouiIcon: 'zoomOut',
- action: {
- type: 'callback',
- execute: function () {
- ensureImageZoomInitialization( function () {
- $zoomImage.prpZoom( 'zoomOut' );
- } );
- }
- }
- },
- 'reset-zoom': {
- labelMsg: 'proofreadpage-button-reset-zoom-label',
- type: 'button',
- oouiIcon: 'zoomReset',
- action: {
- type: 'callback',
- execute: function () {
- ensureImageZoomInitialization( function () {
- $zoomImage.prpZoom( 'reset' );
- } );
- }
- }
- }
- }
- },
other: {
labelMsg: 'proofreadpage-group-other',
tools: {
@@ -468,9 +536,24 @@
// eslint-disable-next-line no-jquery/no-global-selector
$editForm = $( '#editform' );
}
- if ( $zoomImage === undefined ) {
- $zoomImage = $editForm.find( '.prp-page-image img' );
+
+ if ( $imgCont === undefined ) {
+ // eslint-disable-next-line no-jquery/no-global-selector
+ $imgCont = $( '#prp-page-image-openseadragon-vertical' );
+ }
+
+ if ( $img === undefined ) {
+ $img = $( '.prp-page-image' ).find( 'img' );
+ }
+
+ if ( imgHeight === undefined ) {
+ imgHeight = window.getComputedStyle( $img[ 0 ] ).getPropertyValue( 'height' );
+ }
+
+ if ( imgWidth === undefined ) {
+ imgWidth = window.getComputedStyle( $img[ 0 ] ).getPropertyValue( 'width' );
}
+
}
function getLoadedEditorPromise() {
@@ -482,24 +565,14 @@
} );
return deferred.promise();
}
-
return deferred.resolve().promise();
}
$( function () {
initEnvironment();
- setupPreferences();
setupPageQuality();
- getLoadedEditorPromise().done( setupWikitextEditor );
+ getLoadedEditorPromise().done( setupWikitextEditor, setupPreferences );
- // zoom should be initialized after the page is rendered
- if ( document.readyState === 'complete' ) {
- ensureImageZoomInitialization();
- } else {
- $( window ).on( 'load', function () {
- ensureImageZoomInitialization();
- } );
- }
} );
}() );
diff --git a/modules/ve/pageTarget/ve.init.mw.ProofreadPagePageTarget.css b/modules/ve/pageTarget/ve.init.mw.ProofreadPagePageTarget.css
index 400dbc77..6f5d39f1 100644
--- a/modules/ve/pageTarget/ve.init.mw.ProofreadPagePageTarget.css
+++ b/modules/ve/pageTarget/ve.init.mw.ProofreadPagePageTarget.css
@@ -16,7 +16,7 @@
.ve-init-mw-proofreadPagePageTarget-zoomContainer {
float: right;
- width: 49%;
+ width: 10%;
text-align: center;
margin-bottom: 0.5em;
}
@@ -37,3 +37,7 @@
.ve-init-mw-proofreadPagePageTarget .ve-ce-sectionNode:not( :last-child ) {
padding-bottom: 1em;
}
+
+.ve-init-mw-proofreadPageTarget-imageZoom {
+ display: flex;
+}
diff --git a/modules/ve/pageTarget/ve.init.mw.ProofreadPagePageTarget.js b/modules/ve/pageTarget/ve.init.mw.ProofreadPagePageTarget.js
index 73916a4e..aebfcf42 100644
--- a/modules/ve/pageTarget/ve.init.mw.ProofreadPagePageTarget.js
+++ b/modules/ve/pageTarget/ve.init.mw.ProofreadPagePageTarget.js
@@ -5,6 +5,9 @@
* @license The MIT License (MIT); see LICENSE.txt
*/
+// eslint-disable-next-line no-implicit-globals
+var OpenSeadragon = require( 'ext.proofreadpage.openseadragon' );
+
/**
* ProofreadPage page target
*
@@ -28,25 +31,35 @@ ve.init.mw.ProofreadPagePageTarget = function VeInitMwProofreadPagePageTarget()
$pageContainer = $contentText.find( '.prp-page-container' );
$contentText.empty().append( $pageContainer );
}
+ this.$imageZoomDiv = $( '<div>' ).addClass( 've-init-mw-proofreadPageTarget-imageZoom' );
+
+ this.$zoomButtonsCont = $( '<div>' ).addClass( 've-init-mw-proofreadPagePageTarget-zoomContainer' );
- this.$zoomContainer = $( '<div>' ).addClass( 've-init-mw-proofreadPagePageTarget-zoomContainer' );
+ // eslint-disable-next-line no-jquery/no-global-selector
+ this.$imgCont = $( '.prp-page-image' );
+ this.$imgCont.css( 'display', 'block' );
// eslint-disable-next-line no-jquery/no-global-selector
- this.$zoomImage = $( '.prp-page-image img' );
+ this.$imgOSDCont = $( '#prp-page-image-openseadragon-vertical' )
+ this.$imgOSDCont.css( 'display', 'initial' );
+
+ this.$imgOSDCont.before( this.$imageZoomDiv );
+
+ this.$img = this.$imgCont.find( 'img' );
- zoomOut = new OO.ui.ButtonWidget( { icon: 'zoomOut', title: ve.msg( 'proofreadpage-button-zoom-out-label' ) } )
- .on( 'click', this.$zoomImage.prpZoom.bind( this.$zoomImage, 'zoomOut' ) );
- zoomReset = new OO.ui.ButtonWidget( { label: ve.msg( 'proofreadpage-button-reset-zoom-label' ) } )
- .on( 'click', this.$zoomImage.prpZoom.bind( this.$zoomImage, 'reset' ) );
- zoomIn = new OO.ui.ButtonWidget( { icon: 'zoomIn', title: ve.msg( 'proofreadpage-button-zoom-out-label' ) } )
- .on( 'click', this.$zoomImage.prpZoom.bind( this.$zoomImage, 'zoomIn' ) );
+ this.$imgOSDCont.height( this.$imgCont.height() );
+ this.$imgOSDCont.width( this.$imgCont.width() );
+
+ zoomOut = new OO.ui.ButtonWidget( { id: 'prp-page-ve-zoomOut', icon: 'zoomOut', title: ve.msg( 'proofreadpage-button-zoom-out-label' ) } );
+ zoomReset = new OO.ui.ButtonWidget( { id: 'prp-page-ve-zoomReset', icon: 'zoomReset', title: ve.msg( 'proofreadpage-button-reset-zoom-label' ) } );
+ zoomIn = new OO.ui.ButtonWidget( { id: 'prp-page-ve-zoomIn', icon: 'zoomIn', title: ve.msg( 'proofreadpage-button-zoom-out-label' ) } );
this.zoomButtons = new OO.ui.ButtonGroupWidget( {
classes: [ 've-init-mw-proofreadPagePageTarget-zoom' ],
items: [ zoomOut, zoomReset, zoomIn ]
} );
- this.$zoomContainer.append( this.zoomButtons.$element );
+ this.$zoomButtonsCont.append( this.zoomButtons.$element );
};
/* Inheritance */
@@ -91,10 +104,15 @@ ve.init.mw.ProofreadPagePageTarget.prototype.afterActivate = function () {
// eslint-disable-next-line no-jquery/no-global-selector
$( '.prp-page-image' )
.removeClass( 've-init-mw-desktopArticleTarget-uneditableContent' )
- .before( this.$zoomContainer );
+ .before( this.$zoomButtonsCont );
+
+ this.$imageZoomDiv.removeClass( 've-init-mw-desktopArticleTarget-uneditableContent' ).append( this.$zoomButtonsCont, this.$imgOSDCont );
+ // eslint-disable-next-line no-jquery/no-global-selector
+ $( '.openseadragon-container' ).detach();
// Make image zoomable
- this.$zoomImage.prpZoom();
+ this.ensureImageZoomInitialization();
+
};
/**
@@ -104,11 +122,68 @@ ve.init.mw.ProofreadPagePageTarget.prototype.cancel = function () {
// Parent method
ve.init.mw.ProofreadPagePageTarget.super.prototype.cancel.apply( this, arguments );
- this.$zoomContainer.detach();
+ this.$zoomButtonsCont.detach();
+ if ( this.viewer ) {
+ this.viewer.destroy();
+ this.viewer = null;
+ }
- this.$zoomImage.prpZoom( 'destroy' );
};
+/**
+ * @inheritdoc
+ */
+ve.init.mw.ProofreadPagePageTarget.prototype.ensureImageZoomInitialization = function () {
+ var url1 = this.$img[ 0 ].getAttribute( 'src' );
+ var srcSet = this.$img[ 0 ].getAttribute( 'srcset' ).split( ' ' );
+ var url2 = srcSet[ 0 ];
+ var url3 = srcSet[ 2 ];
+ var width = this.$img[ 0 ].getAttribute( 'width' );
+ var height = this.$img[ 0 ].getAttribute( 'height' );
+
+ this.$img.hide();
+
+ this.viewer = OpenSeadragon( {
+ id: 'prp-page-image-openseadragon-vertical',
+ zoomInButton: 'prp-page-ve-zoomIn',
+ zoomOutButton: 'prp-page-ve-zoomOut',
+ homeButton: 'prp-page-ve-zoomReset',
+ showFullPageControl: false,
+ preserveViewport: true,
+ animationTime: 0.5,
+ visibilityRatio: 0.5,
+ minZoomLevel: 0.5,
+ maxZoomLevel: 4.5,
+ tileSources: {
+ type: 'legacy-image-pyramid',
+ levels: [ {
+ url: url1,
+ height: height,
+ width: width
+ },
+ {
+ url: url2,
+ height: 1.5 * height,
+ width: 1.5 * width
+ },
+ {
+ url: url3,
+ height: 2 * height,
+ width: 2 * width
+ }
+ ]
+ }
+ } );
+
+ this.viewer.viewport.goHome = function () {
+ if ( this.viewer ) {
+ var oldBounds = this.viewer.viewport.getBounds();
+ var newBounds = new OpenSeadragon.Rect( 0, 0, 1, oldBounds.height / oldBounds.width );
+ this.viewer.viewport.fitBounds( newBounds, true );
+ }
+ };
+
+};