r54935 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r54934‎ | r54935 | r54936 >
Date:14:07, 13 August 2009
Author:catrope
Status:deferred
Tags:
Comment:
EditToolbar: Add AJAX page existence check widget to link CGD, and put labels and textboxes on the same line
Modified paths:
  • /trunk/extensions/UsabilityInitiative/EditToolbar/EditToolbar.hooks.php (modified) (history)
  • /trunk/extensions/UsabilityInitiative/EditToolbar/EditToolbar.i18n.php (modified) (history)
  • /trunk/extensions/UsabilityInitiative/EditToolbar/EditToolbar.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/EditToolbar/EditToolbar.php (modified) (history)
  • /trunk/extensions/UsabilityInitiative/images/wikiEditor/toolbar/insert-link-exists.png (added) (history)
  • /trunk/extensions/UsabilityInitiative/images/wikiEditor/toolbar/insert-link-invalid.png (added) (history)
  • /trunk/extensions/UsabilityInitiative/images/wikiEditor/toolbar/insert-link-notexists.png (added) (history)

Diff [purge]

Index: trunk/extensions/UsabilityInitiative/images/wikiEditor/toolbar/insert-link-notexists.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: trunk/extensions/UsabilityInitiative/images/wikiEditor/toolbar/insert-link-notexists.png
___________________________________________________________________
Name: svn:mime-type
11 + application/octet-stream
Index: trunk/extensions/UsabilityInitiative/images/wikiEditor/toolbar/insert-link-exists.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: trunk/extensions/UsabilityInitiative/images/wikiEditor/toolbar/insert-link-exists.png
___________________________________________________________________
Name: svn:mime-type
22 + application/octet-stream
Index: trunk/extensions/UsabilityInitiative/images/wikiEditor/toolbar/insert-link-invalid.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: trunk/extensions/UsabilityInitiative/images/wikiEditor/toolbar/insert-link-invalid.png
___________________________________________________________________
Name: svn:mime-type
33 + application/octet-stream
Index: trunk/extensions/UsabilityInitiative/EditToolbar/EditToolbar.hooks.php
@@ -67,6 +67,10 @@
6868 'edittoolbar-tool-link-ext-text',
6969 'edittoolbar-tool-link-insert',
7070 'edittoolbar-tool-link-cancel',
 71+ 'edittoolbar-link-int-target-status-exists',
 72+ 'edittoolbar-link-int-target-status-notexists',
 73+ 'edittoolbar-link-int-target-status-invalid',
 74+ 'edittoolbar-link-int-target-status-loading',
7175 'edittoolbar-tool-file',
7276 'edittoolbar-tool-file-pre',
7377 'edittoolbar-tool-file-example',
Index: trunk/extensions/UsabilityInitiative/EditToolbar/EditToolbar.js
@@ -69,12 +69,16 @@
7070 titleMsg: 'edittoolbar-tool-link-title',
7171 id: 'edittoolbar-link-dialog',
7272 // TODO: break this line
73 - html: '<div id="edittoolbar-link-tabs"><ul><li><a href="#edittoolbar-link-dialog-tab-int" rel="edittoolbar-tool-link-int"></a></li><li><a href="#edittoolbar-link-dialog-tab-ext" rel="edittoolbar-tool-link-ext"></a></li></ul><div id="edittoolbar-link-dialog-tab-int"><form><label for="edittoolbar-link-int-target" rel="edittoolbar-tool-link-int-target"></label><input type="text" id="edittoolbar-link-int-target" style="display:block;" /><label for="edittoolbar-link-int-text" rel="edittoolbar-tool-link-int-text"></label><input type="text" id="edittoolbar-link-int-text" style="display:block;" /></form></div><div id="edittoolbar-link-dialog-tab-ext"><form><label for="edittoolbar-link-ext-target" rel="edittoolbar-tool-link-ext-target"></label><input type="text" id="edittoolbar-link-ext-target" style="display:block;" /><label for="edittoolbar-link-ext-text" rel="edittoolbar-tool-link-ext-text"></label><input type="text" id="edittoolbar-link-ext-text" style="display:block;" /></form></div></div>',
 73+ html: '<div id="edittoolbar-link-tabs"><ul><li><a href="#edittoolbar-link-dialog-tab-int" rel="edittoolbar-tool-link-int"></a></li><li><a href="#edittoolbar-link-dialog-tab-ext" rel="edittoolbar-tool-link-ext"></a></li></ul><div id="edittoolbar-link-dialog-tab-int"><form><label for="edittoolbar-link-int-target" rel="edittoolbar-tool-link-int-target"></label> <input type="text" id="edittoolbar-link-int-target" /> <div id="edittoolbar-link-int-target-status" style="display: inline;"></div><br /><label for="edittoolbar-link-int-text" rel="edittoolbar-tool-link-int-text"></label> <input type="text" id="edittoolbar-link-int-text" /></form></div><div id="edittoolbar-link-dialog-tab-ext"><form><label for="edittoolbar-link-ext-target" rel="edittoolbar-tool-link-ext-target"></label> <input type="text" id="edittoolbar-link-ext-target" /><br /><label for="edittoolbar-link-ext-text" rel="edittoolbar-tool-link-ext-text"></label> <input type="text" id="edittoolbar-link-ext-text" /></form></div></div>',
7474 init: function() {
7575 $j(this).find( '[rel]' ).each( function() {
7676 $j(this).html( gM( $j(this).attr( 'rel' ) ) );
7777 });
7878 $j( '#edittoolbar-link-tabs' ).tabs();
 79+
 80+ // Link int-target and int-text fields
 81+ // This means mirroring the contents of int-target in int-text
 82+ // as long as int-text itself hasn't been changed by the user
7983 $j( '#edittoolbar-link-int-target' ).bind( 'keypress paste', function() {
8084 // $j(this).val() is the old value, before the keypress
8185 if ( $j( '#edittoolbar-link-int-text' ).data( 'untouched' ) )
@@ -84,6 +88,99 @@
8589 $j( '#edittoolbar-link-int-text' ).bind( 'keypress paste', function() {
8690 $j(this).data( 'untouched', false );
8791 });
 92+
 93+ // Page existence check widget
 94+ var existsImg = $j.wikiEditor.modules.toolbar.imgPath + 'insert-link-exists.png';
 95+ var notexistsImg = $j.wikiEditor.modules.toolbar.imgPath + 'insert-link-notexists.png';
 96+ var invalidImg = $j.wikiEditor.modules.toolbar.imgPath + 'insert-link-invalid.png';
 97+ var loadingImg = $j.wikiEditor.modules.toolbar.imgPath + 'loading.gif';
 98+ var existsMsg = gM( 'edittoolbar-link-int-target-status-exists' );
 99+ var notexistsMsg = gM( 'edittoolbar-link-int-target-status-notexists' );
 100+ var invalidMsg = gM( 'edittoolbar-link-int-target-status-invalid' );
 101+ var loadingMsg = gM( 'edittoolbar-link-int-target-status-loading' );
 102+ $j( '#edittoolbar-link-int-target-status' )
 103+ .html( '<img id="edittoolbar-link-int-target-status-exists" src="' + existsImg + '" alt="' + existsMsg + '" title="' + existsMsg + '" />' +
 104+ '<img id="edittoolbar-link-int-target-status-notexists" src="' + notexistsImg + '" alt="' + notexistsMsg + '" title="' + notexistsMsg + '" />' +
 105+ '<img id="edittoolbar-link-int-target-status-invalid" src="' + invalidImg + '" alt="' + invalidMsg + '" title="' + invalidMsg + '" />' +
 106+ '<img id="edittoolbar-link-int-target-status-loading" src="' + loadingImg + '" alt="' + loadingMsg + '" title="' + loadingMsg + '" />' )
 107+ .data( 'cache', {} )
 108+ .children().hide();
 109+
 110+ function updateExistence( target ) {
 111+ function updateWidget( status ) {
 112+ $j( '#edittoolbar-link-int-target-status' ).children().hide();
 113+ $j( '#edittoolbar-link-int-target-status-' + status ).show();
 114+ }
 115+
 116+ // Abort previous request
 117+ var request = $j( '#edittoolbar-link-int-target-status' ).data( 'request' );
 118+ if ( request )
 119+ request.abort();
 120+
 121+ var target = $j( '#edittoolbar-link-int-target' ).val();
 122+ var cache = $j( '#edittoolbar-link-int-target-status' ).data( 'cache' );
 123+ if ( cache[target] ) {
 124+ updateWidget( cache[target] );
 125+ return;
 126+ }
 127+
 128+ if ( target == '' ) {
 129+ // Hide the widget when the textbox is empty
 130+ $j( '#edittoolbar-link-int-target-status' ).children().hide();
 131+ return;
 132+ }
 133+ if ( target.indexOf( '|' ) != -1 ) {
 134+ // Title contains | , which means it's invalid
 135+ // but confuses the API. Show invalid and bypass API
 136+ updateWidget( 'invalid' );
 137+ return;
 138+ }
 139+
 140+ updateWidget( 'loading' );
 141+ var request = $j.ajax( {
 142+ url: wgScriptPath + '/api.php',
 143+ dataType: 'json',
 144+ data: {
 145+ 'action': 'query',
 146+ 'indexpageids': '',
 147+ 'titles': target,
 148+ 'format': 'json'
 149+ },
 150+ success: function( data ) {
 151+ // TODO: What happens if data.query.pageids is undefined?
 152+ var page = data.query.pages[data.query.pageids[0]];
 153+ var status = 'exists';
 154+ if ( typeof page.missing != 'undefined' )
 155+ status = 'notexists';
 156+ else if ( typeof page.invalid != 'undefined' )
 157+ status = 'invalid';
 158+
 159+ cache[target] = status;
 160+ updateWidget( status );
 161+ }
 162+ });
 163+ // Save request object so it can be aborted if necessary
 164+ $j( '#edittoolbar-link-int-target-status' ).data( 'request', request );
 165+ }
 166+
 167+ $j( '#edittoolbar-link-int-target' ).bind( 'keypress paste', function() {
 168+ // Cancel the running timer if applicable
 169+ if ( typeof $j(this).data( 'timerID' ) != 'undefined' )
 170+ clearTimeout( $j(this).data( 'timerID' ) );
 171+
 172+ // Delay fetch for a while
 173+ // FIXME: Make 250 configurable elsewhere
 174+ var timerID = setTimeout( updateExistence, 250 );
 175+ $j(this).data( 'timerID', timerID );
 176+ });
 177+ $j( '#edittoolbar-link-int-target' ).change( function() {
 178+ // Cancel the running timer if applicable
 179+ if ( typeof $j(this).data( 'timerID' ) != 'undefined' )
 180+ clearTimeout( $j(this).data( 'timerID' ) );
 181+
 182+ // Fetch right now
 183+ updateExistence();
 184+ });
88185 },
89186 dialog: {
90187 width: 550, // FIXME: autoresize width
@@ -105,7 +202,7 @@
106203 switch ( $j( '#edittoolbar-link-tabs' ).tabs( 'option', 'selected' ) ) {
107204 case 0: // Internal link
108205 // TODO: Escape this stuff
109 - // TODO: Verify internal target validity
 206+ // TODO: Refuse to insert links to invalid titles
110207 insertText = '[[' +
111208 $j( '#edittoolbar-link-int-target' ).val() +
112209 '|' +
@@ -138,9 +235,11 @@
139236 },
140237 open: function() {
141238 // Pre-fill text fields
 239+ // val() doesn't trigger the change event, so let's do that ourselves
142240 $j( '#edittoolbar-link-int-text, #edittoolbar-link-ext-text, #edittoolbar-link-int-target' )
143 - .val( $j(this).data( 'context' ).$textarea.getSelection() );
144 - $j( '#edittoolbar-link-ext-target' ).val( 'http://' );
 241+ .val( $j(this).data( 'context' ).$textarea.getSelection() )
 242+ .change();
 243+ $j( '#edittoolbar-link-ext-target' ).val( 'http://' ).change();
145244 $j( '#edittoolbar-link-int-text' ).data( 'untouched', true );
146245 }
147246 }
@@ -399,13 +498,14 @@
400499 titleMsg: 'edittoolbar-tool-replace-title',
401500 id: 'edittoolbar-replace-dialog',
402501 // TODO: break this line
403 - html: '<form><fieldset><label for="edittoolbar-replace-search" rel="edittoolbar-tool-replace-search"></label><input type="text" id="edittoolbar-replace-search" style="display:block;" /><label for="edittoolbar-replace-replace" rel="edittoolbar-tool-replace-replace"></label><input type="text" id="edittoolbar-replace-replace" style="display:block;" /><input type="checkbox" id="edittoolbar-replace-case" /><label for="edittoolbar-replace-case" rel="edittoolbar-tool-replace-case"></label><br /><input type="checkbox" id="edittoolbar-replace-regex" /><label for="edittoolbar-replace-regex" rel="edittoolbar-tool-replace-regex"></label><br /><input type="checkbox" id="edittoolbar-replace-all" /><label for="edittoolbar-replace-all" rel="edittoolbar-tool-replace-all"></label></fieldset></form>',
 502+ html: '<form><fieldset><label for="edittoolbar-replace-search" rel="edittoolbar-tool-replace-search"></label> <input type="text" id="edittoolbar-replace-search" /><br /><label for="edittoolbar-replace-replace" rel="edittoolbar-tool-replace-replace"></label> <input type="text" id="edittoolbar-replace-replace" /><br /><input type="checkbox" id="edittoolbar-replace-case" /><label for="edittoolbar-replace-case" rel="edittoolbar-tool-replace-case"></label><br /><input type="checkbox" id="edittoolbar-replace-regex" /><label for="edittoolbar-replace-regex" rel="edittoolbar-tool-replace-regex"></label><br /><input type="checkbox" id="edittoolbar-replace-all" /><label for="edittoolbar-replace-all" rel="edittoolbar-tool-replace-all"></label></fieldset></form>',
404503 init: function() {
405504 $j(this).find( '[rel]' ).each( function() {
406505 $j(this).html( gM( $j(this).attr( 'rel' ) ) );
407506 });
408507 },
409508 dialog: {
 509+ width: 350, // FIXME: autoresize width
410510 buttons: {
411511 'edittoolbar-tool-replace-button': function() {
412512 var searchStr = $j( '#edittoolbar-replace-search' ).val();
Index: trunk/extensions/UsabilityInitiative/EditToolbar/EditToolbar.i18n.php
@@ -31,6 +31,10 @@
3232 'edittoolbar-tool-link-ext-text' => 'Link text:',
3333 'edittoolbar-tool-link-insert' => 'Insert link',
3434 'edittoolbar-tool-link-cancel' => 'Cancel',
 35+ 'edittoolbar-link-int-target-status-exists' => 'Page exists',
 36+ 'edittoolbar-link-int-target-status-notexists' => 'Page does not exist',
 37+ 'edittoolbar-link-int-target-status-invalid' => 'Invalid title',
 38+ 'edittoolbar-link-int-target-status-loading' => 'Checking page existence...',
3539 'edittoolbar-tool-file' => 'Embedded file',
3640 'edittoolbar-tool-file-pre' => '$1{{ns:file}}:',
3741 'edittoolbar-tool-file-example' => 'Example.jpg',
@@ -188,6 +192,10 @@
189193 'edittoolbar-tool-bold-example' => '{{Identical|Bold text}}',
190194 'edittoolbar-tool-italic' => '{{Identical|Italic}}',
191195 'edittoolbar-tool-italic-example' => '{{Identical|Italic text}}',
 196+ 'edittoolbar-link-int-target-status-exists' => 'alt text and title text for the image shown when the title the user entered exists',
 197+ 'edittoolbar-link-int-target-status-notexists' => 'alt text and title text for the image shown when the title the user entered does not exist',
 198+ 'edittoolbar-link-int-target-status-invalid' => 'alt text and title text for the image shown when the title the user entered is invalid',
 199+ 'edittoolbar-link-int-target-status-loading' => 'alt text and title text for the image shown while the title the user entered is being checked for existence',
192200 'edittoolbar-tool-reference' => '{{Identical|Reference}}',
193201 'edittoolbar-group-list' => '{{Identical|List}}',
194202 'edittoolbar-group-size' => '{{Identical|Size}}',
Index: trunk/extensions/UsabilityInitiative/EditToolbar/EditToolbar.php
@@ -19,7 +19,7 @@
2020 /* Configuration */
2121
2222 // Bump the version number every time you change any of the .css/.js files
23 -$wgEditToolbarStyleVersion = 21;
 23+$wgEditToolbarStyleVersion = 22;
2424
2525 // Set this to true to simply override the stock toolbar for everyone
2626 $wgEditToolbarGlobalEnable = false;

Status & tagging log