From 1d7cf569e6f3f4db2303523cd64083a516000ae5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Inez=20Korczyn=CC=81ski?= Date: Wed, 22 May 2013 22:47:11 -0700 Subject: [PATCH] Support for thumb and frame images with captions. * VisualEditor.hooks.php ** export URL to magnify clip as a configuration variable so thumbnail image can render correctly * ve.ce.Surface.css ** add CSS styling to make image captions look the same way in edit mode as they look in the view mode * ve.ce.ParagraphNode.js ** add CSS class ve-ce-generated-wrapper if it is a generated wrapper * ve.ce.MWImageCaptionNode.js ** make image caption rendering match the view mode Change-Id: I0cd1b25e8f8355e0500aabc90e7c4cdf591545f3 --- VisualEditor.hooks.php | 4 +- .../ve/ce/nodes/ve.ce.MWImageCaptionNode.js | 42 ++++++++++++++++++- modules/ve/ce/nodes/ve.ce.ParagraphNode.js | 8 ++++ modules/ve/ce/styles/ve.ce.Surface.css | 13 ++++++ modules/ve/dm/nodes/ve.dm.MWBlockImageNode.js | 7 +++- modules/ve/test/dm/ve.dm.example.js | 2 + 6 files changed, 73 insertions(+), 3 deletions(-) diff --git a/VisualEditor.hooks.php b/VisualEditor.hooks.php index 88bfbc9372..7793b2b534 100644 --- a/VisualEditor.hooks.php +++ b/VisualEditor.hooks.php @@ -60,10 +60,12 @@ class VisualEditorHooks { * Adds extra variables to the page config. */ public static function onMakeGlobalVariablesScript( array &$vars, OutputPage $out ) { + global $wgStylePath, $wgContLang; $vars['wgVisualEditor'] = array( 'isPageWatched' => $out->getUser()->isWatched( $out->getTitle() ), 'pageLanguageCode' => $out->getTitle()->getPageLanguage()->getHtmlCode(), - 'pageLanguageDir' => $out->getTitle()->getPageLanguage()->getDir() + 'pageLanguageDir' => $out->getTitle()->getPageLanguage()->getDir(), + 'magnifyClipIconURL' => $wgStylePath . '/common/images/magnify-clip' . ( $wgContLang->isRTL() ? '-rtl' : '' ) . '.png' // Same as in Linker.php ); return true; diff --git a/modules/ve/ce/nodes/ve.ce.MWImageCaptionNode.js b/modules/ve/ce/nodes/ve.ce.MWImageCaptionNode.js index 53e62cadf1..0f9da2caf1 100644 --- a/modules/ve/ce/nodes/ve.ce.MWImageCaptionNode.js +++ b/modules/ve/ce/nodes/ve.ce.MWImageCaptionNode.js @@ -5,6 +5,8 @@ * @license The MIT License (MIT); see LICENSE.txt */ +/*global mw */ + /** * ContentEditable image caption item node. * @@ -17,6 +19,9 @@ ve.ce.MWImageCaptionNode = function VeCeMWImageCaptionNode( model, config ) { // Parent constructor ve.ce.BranchNode.call( this, model, config ); + + // DOM changes + this.$.addClass( 'thumbcaption' ); }; /* Inheritance */ @@ -27,7 +32,42 @@ ve.inheritClass( ve.ce.MWImageCaptionNode, ve.ce.BranchNode ); ve.ce.MWImageCaptionNode.static.name = 'MWimagecaption'; -ve.ce.MWImageCaptionNode.static.tagName = 'figcaption'; +ve.ce.MWImageCaptionNode.static.tagName = 'div'; + +/* Methods */ + +/** + * TODO: Magnify should not be built nor appended if this is a caption of frame (vs. thumb) image. + */ +ve.ce.MWImageCaptionNode.prototype.onSplice = function () { + if ( this.$magnify ) { + this.$magnify.detach(); + } else { + this.buildMagnify(); + } + + // Call parent implementation + ve.ce.BranchNode.prototype.onSplice.apply( this, arguments ); + + this.$magnify.prependTo( this.$ ); +}; + +ve.ce.MWImageCaptionNode.prototype.buildMagnify = function() { + this.$magnify = $( '
' ) + .addClass( 'magnify' ); + this.$a = $( '' ) + .addClass( 'internal' ) + // It's inside a protected node, so user can't see href/title anyways. + //.attr( 'href', '/wiki/File:Wiki.png') + //.attr( 'title', 'Enlarge' ) + .appendTo( this.$magnify ); + this.$img = $( '' ) + .attr( 'src', mw.config.get( 'wgVisualEditor' ).magnifyClipIconURL ) + .attr( 'width', 15 ) + .attr( 'height', 11 ) + //.attr( 'alt', '' ) + .appendTo( this.$a ); +}; /* Registration */ diff --git a/modules/ve/ce/nodes/ve.ce.ParagraphNode.js b/modules/ve/ce/nodes/ve.ce.ParagraphNode.js index 512756d9ef..53e5209d92 100644 --- a/modules/ve/ce/nodes/ve.ce.ParagraphNode.js +++ b/modules/ve/ce/nodes/ve.ce.ParagraphNode.js @@ -17,6 +17,14 @@ ve.ce.ParagraphNode = function VeCeParagraphNode( model, config ) { // Parent constructor ve.ce.ContentBranchNode.call( this, model, config ); + + // DOM changes + if ( + this.model.getElement().internal && + this.model.getElement().internal.generated === 'wrapper' + ) { + this.$.addClass( 've-ce-generated-wrapper' ); + } }; /* Inheritance */ diff --git a/modules/ve/ce/styles/ve.ce.Surface.css b/modules/ve/ce/styles/ve.ce.Surface.css index feabdf203f..c97d2ff981 100644 --- a/modules/ve/ce/styles/ve.ce.Surface.css +++ b/modules/ve/ce/styles/ve.ce.Surface.css @@ -58,3 +58,16 @@ height: 1px !important; width: 1px !important; } + +/* MediaWiki PHP Parser does not wrap text inside image captions in

but we do (cause we have to). + * Let's make those

looks like they are not there by proper CSS styling. */ +.ve-ce-surface .thumbcaption p.ve-ce-generated-wrapper { + display: inline; + margin: 0; + padding: 0; + line-height: inherit; +} + +.ve-ce-surface .thumbcaption .ve-ce-branchNode-slug { + display: none; +} \ No newline at end of file diff --git a/modules/ve/dm/nodes/ve.dm.MWBlockImageNode.js b/modules/ve/dm/nodes/ve.dm.MWBlockImageNode.js index 63908d8dc3..167785a642 100644 --- a/modules/ve/dm/nodes/ve.dm.MWBlockImageNode.js +++ b/modules/ve/dm/nodes/ve.dm.MWBlockImageNode.js @@ -83,7 +83,12 @@ ve.dm.MWBlockImageNode.static.toDataElement = function ( domElements, converter } if ( $caption.length === 0 ) { - return { 'type': 'MWblockimage', 'attributes': attributes }; + return [ + { 'type': 'MWblockimage', 'attributes': attributes }, + { 'type': 'MWimagecaption' }, + { 'type': '/MWimagecaption' }, + { 'type': '/MWblockimage' } + ]; } else { return [ { 'type': 'MWblockimage', 'attributes': attributes } ]. concat( converter.getDataFromDomRecursionClean( $caption[0], { 'type': 'MWimagecaption' } ) ). diff --git a/modules/ve/test/dm/ve.dm.example.js b/modules/ve/test/dm/ve.dm.example.js index 6e4c29abde..77c4d39db7 100644 --- a/modules/ve/test/dm/ve.dm.example.js +++ b/modules/ve/test/dm/ve.dm.example.js @@ -3138,6 +3138,8 @@ ve.dm.example.domToDataCases = { 'resource': 'FooBar' } }, + { 'type': 'MWimagecaption' }, + { 'type': '/MWimagecaption' }, { 'type': '/MWblockimage' } ] }