r107239 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r107238‎ | r107239 | r107240 >
Date:23:19, 24 December 2011
Author:jarry1250
Status:deferred (Comments)
Tags:
Comment:
Fix per SPQRobin: Internationalise thumb alignment; Fix very poor step checking. Also fix *headdesk* over upmerging attributes; and localise second submit button. Finally, per Krinkle and SPQR, use far more specific class/ids.
Modified paths:
  • /trunk/extensions/TranslateSvg/SpecialTranslateSvg.php (modified) (history)
  • /trunk/extensions/TranslateSvg/TranslateSvg.php (modified) (history)
  • /trunk/extensions/TranslateSvg/ext.translateSvg.core.js (modified) (history)

Diff [purge]

Index: trunk/extensions/TranslateSvg/TranslateSvg.php
@@ -31,6 +31,7 @@
3232 'scripts' => array( 'ext.translateSvg.core.js' ),
3333 // 'styles' => 'css/ext.translateSvg.css',
3434 'messages' => array( 'translatesvg-add', 'translatesvg-addlink', 'translatesvg-specify', 'translatesvg-remove' ),
 35+ 'dependencies' => array( 'jquery.spinner', 'jquery.makeCollapsible' ),
3536 'localBasePath' => dirname( __FILE__ ),
3637 'remoteExtPath' => 'translateSvg'
37 -);
 38+);
\ No newline at end of file
Index: trunk/extensions/TranslateSvg/SpecialTranslateSvg.php
@@ -43,21 +43,20 @@
4444 $this->extractTranslations();
4545 $this->tidyTranslations();
4646 $params = $request->getQueryValues();
47 - if( count( $params ) > 2 && isset( $params['title'] ) && isset( $params['file'] ) ){
48 - unset( $params['title'] );
 47+ if( count( $params ) > 2 && isset( $params['title'] ) && isset( $params['file'] ) && isset( $params['step'] ) ){
4948 $filename = $params['file'];
50 - unset( $params['file'] );
 49+ unset( $params['title'], $params['file'], $params['step'] );
5150 $this->updateTranslations( $params );
5251 $this->updateSVG();
5352 $this->saveSVG( $file->getLocalRefPath(), $filename );
5453 $file->purgeThumbnails();
5554 } else {
5655 $this->thumb = Linker::makeThumbLinkObj( $title, $file, $label = '', '',
57 - $align = 'right', array( 'width' => 250, 'height' => 250) );
 56+ $align = $this->getLanguage()->alignEnd(), array( 'width' => 250, 'height' => 250 ) );
5857 $this->printTranslations( $file->getName() );
5958 }
6059 } else {
61 - $this->getOutput()->addHTML( '<p>This file could not be translated, sorry.</p>' );
 60+ $this->getOutput()->addHTML( '<p>This file could not be translated, sorry.</p>' ); //TODO: internationalise
6261 }
6362 } else {
6463 $this->getOutput()->setStatusCode( 404 );
@@ -116,23 +115,27 @@
117116 $attrs = ( $child->hasAttributes() ) ? $child->attributes : array();
118117 foreach ($attrs as $num => $attr){
119118 $parentattr = trim( $text->getAttribute( $attr->name ) );
120 - switch( $attr->name ){
121 - case 'x':
122 - case 'y':
123 - case '':
124 - $text->setAttribute( $attr->name, $attr->value ); //Overwrite
125 - break;
126 - case 'style':
127 - $merged = $parentattr;
128 - if( substr( $merged, -1 ) !== ';' ){
129 - $merged .= ';';
130 - }
131 - $merged .= $attr->value;
132 - break;
133 - case 'id':
134 - break; //Ignore
135 - default:
136 - return false;
 119+ if( trim( $parentattr ) === '' ){
 120+ $text->setAttribute( $attr->name, $attr->value ); //Simple upmerge
 121+ } else {
 122+ //Resolve conflict. the aim is to preserve the visuals.
 123+ switch( $attr->name ){
 124+ case 'x':
 125+ case 'y':
 126+ $text->setAttribute( $attr->name, $attr->value ); //Overwrite
 127+ break;
 128+ case 'style':
 129+ $merged = $parentattr;
 130+ if( substr( $merged, -1 ) !== ';' ){
 131+ $merged .= ';';
 132+ }
 133+ $merged .= $attr->value;
 134+ break;
 135+ case 'id':
 136+ break; //Ignore
 137+ default:
 138+ return false;
 139+ }
137140 }
138141 }
139142 $text->appendChild( $child->childNodes->item( 0 ) );
@@ -197,33 +200,34 @@
198201 $html = $this->thumb .
199202 Html::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript, 'id' => 'specialtranslatesvg' ) ) .
200203 Html::hidden( 'file', $filename ) .
 204+ Html::hidden( 'step', 'translated' ) .
201205 Html::hidden( 'title', $this->getTitle()->getPrefixedText() );
202206
 207+ $groups = array();
203208 foreach( $this->translations as $language=>$translations ){
204 - $languages = Language::getLanguageNames();
205 - $languages['fallback'] = wfMsg( 'translatesvg-fallbackdesc');
206 - $languages['qqq'] = wfMsg( 'translatesvg-qqqdesc' );
207 -
208 - $html .= Html::openElement( 'fieldset', array( 'id' => $language ) ) .
209 - Html::element( 'legend', null, $languages[$language] );
 209+ $html .= Html::openElement( 'fieldset', array( 'id' => "mw-translatesvg-fieldset-$language" ) ) .
 210+ Html::element( 'legend', null, $languages[$language] ) .
 211+ Html::openElement( 'div', array( 'class' => "mw-translatesvg-collapsible" ) );
210212 $groups = array();
211213 for( $i = 0; $i < $this->number; $i++ ){
212214 $fallback = $this->getFallback( $i );
213215 $existing = $this->getExisting( $i, $language );
214216 $desc = ( $language === 'qqq' ) ? '' : '&#160;' . Html::element( 'small', null, $this->getDescriptor( $i ) );
215 - list( $label, $input ) = Xml::inputLabelSep( $fallback['text'], $language.'-'.$i.'-text', $language.'-'.$i.'-text', 50, $existing['text'] );
 217+ list( $label, $input ) = Xml::inputLabelSep( $fallback['text'], "mw-translatesvg-$language-$i-text", "mw-translatesvg-$language-$i-text", 50, $existing['text'] );
216218 $grouphtml = $label . $desc . '&#160;&#160;&#160;' . $input;
217219 if( $language !== 'qqq' ){
218220 $grouphtml .= Html::element( 'br' ) .
219 - "&#160;&#160;&#160;" . Xml::inputLabel( wfMsg( 'translatesvg-xcoordinate-pre' ), $language.'-'.$i.'-x', $language.'-'.$i.'-x', 5, $existing['x'] ) .
220 - "&#160;&#160;&#160;" . Xml::inputLabel( wfMsg( 'translatesvg-ycoordinate-pre' ), $language.'-'.$i.'-y', $language.'-'.$i.'-y', 5, $existing['y'] );
 221+ "&#160;&#160;&#160;" .
 222+ Xml::inputLabel( wfMsg( 'translatesvg-xcoordinate-pre' ), "mw-translatesvg-$language-$i-x", "mw-translatesvg-$language-$i-x", 5, $existing['x'] ) .
 223+ "&#160;&#160;&#160;" .
 224+ Xml::inputLabel( wfMsg( 'translatesvg-ycoordinate-pre' ), "mw-translatesvg-$language-$i-y", "mw-translatesvg-$language-$i-y", 5, $existing['y'] );
221225 }
222226 $groups[] = $grouphtml;
223227 }
224228 $html .= implode( Html::element( 'div', array( 'style' => 'height:10px' ) ), $groups );
225 - $html .= Html::closeElement( 'fieldset' );
 229+ $html .= Html::closeElement( 'div' ) . Html::closeElement( 'fieldset' );
226230 }
227 - $html .= Xml::submitButton( 'Submit' ) . "\n" .
 231+ $html .= Xml::submitButton( wfMsg( 'translatesvg-submit' ) ) . "\n" .
228232 Html::closeElement( 'form' );
229233 $this->getOutput()->addHTML( $html );
230234 }
Index: trunk/extensions/TranslateSvg/ext.translateSvg.core.js
@@ -2,28 +2,29 @@
33 var languages = { isset: false };
44
55 //Replace fake "add language" link with real one and add it
6 - var paragraph = $( '<p id="newtrans"></p>' ).text( mw.msg( 'translatesvg-add' ) );
 6+ var paragraph = $( '<p id="mw-translatesvg-newtrans"></p>' ).text( mw.msg( 'translatesvg-add' ) );
77 var match = paragraph.html().match( /\[\[#addlanguage\|(.*?)\]\]/ );
8 - paragraph.html( paragraph.html().replace( match[0], '<a id="newtranslink" href="#">' + match[1] + '</a>' ) );
 8+ paragraph.html( paragraph.html().replace( match[0], '<a id="mw-translatesvg-newtranslink" href="#">' + match[1] + '</a>' ) );
99 $( 'div.mw-specialpage-summary' ).append( paragraph );
1010
1111 //Add in "remove" links
1212 $( 'legend' ).each( function(){
13 - var langcode = $(this).parent().attr('id');
 13+ var langcode = $(this).parent().attr('id').substr( 25 ); //Trim "mw-translatesvg-fieldset-"
1414 if( langcode !== 'qqq' && langcode !== 'fallback' ){
1515 $(this).append( '&#160;' ).append( getRemoveLink() );
1616 }
1717 } );
1818
19 - $( '#newtranslink' )
 19+
 20+ $( '#mw-translatesvg-newtranslink' )
2021 .click( function() {
2122 var langcode = prompt( mw.msg( 'translatesvg-specify' ) );
2223 if( langcode !== null ){
23 - if( !langcode.match( /^[a-z]+( ?:-[a-z]+ )?/ ) ){
 24+ if( !langcode.match( /^[a-z]+(?:-[a-z]+)?/ ) ){
2425 //Not valid language code
2526 return false; //TODO: more helpful?
2627 }
27 - if( $( 'fieldset#'+langcode ).length !== 0 ){
 28+ if( $( '#mw-translatesvg-fieldset-'+langcode ).length !== 0 ){
2829 //Already exists
2930 return false; //TODO: more helpful?
3031 }
@@ -32,10 +33,10 @@
3334 //Have already loaded valid languages and this ain't one of them
3435 return false; //TODO: more helpful?
3536 }
36 - $( 'form#specialtranslatesvg' ).prepend( getNewFieldset( langcode, languages[langcode] ) );
 37+ $( '#specialtranslatesvg' ).prepend( getNewFieldset( langcode, languages[langcode] ) );
3738 } else {
38 - var temp = $( '<fieldset id="temp"><br /></fieldset>' ).append( $.createSpinner() );
39 - $( 'form#specialtranslatesvg' ).prepend( temp );
 39+ var temp = $( '<fieldset class="mw-translatesvg-temp"><br /></fieldset>' ).append( $.createSpinner() );
 40+ $( '#specialtranslatesvg' ).prepend( temp );
4041 jQuery.getJSON(
4142 mw.util.wikiScript( 'api' ), {
4243 'format': 'json',
@@ -48,12 +49,12 @@
4950 languages[ data.query.languages[i]['code'] ] = data.query.languages[i]['*'];
5051 }
5152 if( ( langcode in languages ) ){
52 - $( 'form#specialtranslatesvg' ).prepend( getNewFieldset( langcode, languages[langcode] ) );
 53+ $( '#specialtranslatesvg' ).prepend( getNewFieldset( langcode, languages[langcode] ) );
5354 } else {
5455 //Have now loaded valid languages and this ain't one of them
5556 //TODO: more helpful?
5657 }
57 - $( 'fieldset#temp' ).remove();
 58+ $( '.mw-translatesvg-temp' ).remove();
5859 languages.isset = true;
5960 }
6061 );
@@ -64,7 +65,7 @@
6566 } );
6667
6768 function getNewFieldset( langcode, langname ){
68 - var newfieldset = $( 'fieldset#fallback' ).clone();
 69+ var newfieldset = $( 'fieldset#mw-translatesvg-fieldset-fallback' ).clone();
6970 newfieldset.find( 'input' ).each( function (){
7071 $( this ).attr( 'id', $( this ).attr( 'id' ).toString().replace( 'fallback', langcode ) );
7172 $( this ).attr( 'name', $( this ).attr( 'name' ).toString().replace( 'fallback', langcode ) );
@@ -73,7 +74,7 @@
7475 newfieldset.find( 'label' ).each( function (){
7576 $( this ).attr( 'for', $( this ).attr( 'for' ).toString().replace( 'fallback', langcode ) );
7677 } );
77 - newfieldset.attr( 'id', langcode );
 78+ newfieldset.attr( 'id', "mw-translatesvg-fieldset-" + langcode );
7879 newfieldset.find( 'legend' ).each( function (){
7980 $( this ).text( langname );
8081 $( this ).append( '&#160;' ).append( getRemoveLink() );
@@ -83,7 +84,7 @@
8485
8586 function getRemoveLink(){
8687 var removelink = $( '<a href="#"><abbr title="'
87 - + mw.msg( 'translatesvg-remove' )
 88+ + mw.message('translatesvg-remove').escaped()
8889 + '"><small>[x]</small></abbr></a>' );
8990 removelink.click( function(){ $(this).parent().parent().remove(); } );
9091 return removelink;

Follow-up revisions

RevisionCommit summaryAuthorDate
r107345Followup r107239 per Krinkle: pass id to $.createSpinner, and no need to set ...jarry125022:35, 26 December 2011

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r107229(JavaScript) implement validation and rendering of language codes via AJAX me...jarry125022:34, 24 December 2011

Comments

#Comment by Krinkle (talk | contribs)   17:05, 26 December 2011
+		var temp = $( '<fieldset class="mw-translatesvg-temp"><br /></fieldset>' ).append( $.createSpinner() );
+		$( '#specialtranslatesvg' ).prepend( temp );
..
+			$( '.mw-translatesvg-temp' ).remove();
  • $.createSpinner must be called with an ID-parameter. Now it creates a spinner with id "mw-spinner-undefined".
  • Use temp.remove() instead of re-selecting the same thing through the DOM
  • Is this temp-element needed for anything else ? Otherwise it may be easier to do:
var $spinner = $.createSpinner( 'translatesvg' );
$( '#specialtranslatesvg' ).prepend( spinner );
..
$spinner.remove();
#Comment by Krinkle (talk | contribs)   17:08, 26 December 2011

if you need to insert the fieldset for visual reasons (i.e. so that it appears the fieldset is already loaded and then the loading-fieldset is removed and the other one inserted), the I'd recommend something like this:

  • creating the fieldset in non-temporary fashion
  • inserting the spinner into it
  • load content like you do now
  • removing the spinner
  • inserting the content into the existing fieldset (instead of removing it and creating an new fieldset)
#Comment by Jarry1250 (talk | contribs)   17:16, 26 December 2011

Yes, it definitely looks better as a fieldset rather than a standalone spinner.

With regard to inserting into rather than recreating, I think it's would be a negligible performance gain, if any?

Will look at fixing the other bits later :)

#Comment by Krinkle (talk | contribs)   17:43, 26 December 2011

Indeed, more clarity gain then performance gain. Although it does save more than just element computation, it's also a tiny bit more reflow/repaint.

#Comment by Jarry1250 (talk | contribs)   17:48, 26 December 2011

I'm just averse to having to rework my functioning .clone() if I can avoid it.

Status & tagging log