Index: trunk/extensions/WikiSync/WikiSyncExporter.php |
— | — | @@ -28,7 +28,7 @@ |
29 | 29 | * * Add this line at the end of your LocalSettings.php file : |
30 | 30 | * require_once "$IP/extensions/WikiSync/WikiSync.php"; |
31 | 31 | * |
32 | | - * @version 0.2.0 |
| 32 | + * @version 0.2.1 |
33 | 33 | * @link http://www.mediawiki.org/wiki/Extension:WikiSync |
34 | 34 | * @author Dmitriy Sintsov <questpc@rambler.ru> |
35 | 35 | * @addtogroup Extensions |
Index: trunk/extensions/WikiSync/WikiSyncApi.php |
— | — | @@ -28,7 +28,7 @@ |
29 | 29 | * * Add this line at the end of your LocalSettings.php file : |
30 | 30 | * require_once "$IP/extensions/WikiSync/WikiSync.php"; |
31 | 31 | * |
32 | | - * @version 0.2.0 |
| 32 | + * @version 0.2.1 |
33 | 33 | * @link http://www.mediawiki.org/wiki/Extension:WikiSync |
34 | 34 | * @author Dmitriy Sintsov <questpc@rambler.ru> |
35 | 35 | * @addtogroup Extensions |
— | — | @@ -150,6 +150,7 @@ |
151 | 151 | } |
152 | 152 | # place result list items into attributes of <similarrev> xml tag |
153 | 153 | $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'similarrev' ); |
| 154 | + unset( $dbres ); |
154 | 155 | } |
155 | 156 | |
156 | 157 | private function extractRowInfo( $row ) { |
— | — | @@ -337,6 +338,7 @@ |
338 | 339 | $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'revision' ); |
339 | 340 | // $this->getResult()->setIndexedTagName( $resultData, 'page' ); |
340 | 341 | // $this->getResult()->addValue( null, $this->getModuleName(), $resultData ); |
| 342 | + unset( $dbres ); |
341 | 343 | } |
342 | 344 | } |
343 | 345 | |
— | — | @@ -507,7 +509,8 @@ |
508 | 510 | $this->dieUsageMsg( array( 'missingparam', 'timestamp' ) ); |
509 | 511 | } |
510 | 512 | if ( !$this->getMain()->canApiHighLimits() ) { |
511 | | - $this->dieUsageMsg( array( 'actionthrottledtext' ) ); |
| 513 | + // throttle a non-priviledged user |
| 514 | + sleep( 1 ); |
512 | 515 | } |
513 | 516 | $title = Title::newFromText( $params['title'], NS_FILE ); |
514 | 517 | if ( $title instanceof Title ) { |
Index: trunk/extensions/WikiSync/WikiSyncPage.php |
— | — | @@ -28,7 +28,7 @@ |
29 | 29 | * * Add this line at the end of your LocalSettings.php file : |
30 | 30 | * require_once "$IP/extensions/WikiSync/WikiSync.php"; |
31 | 31 | * |
32 | | - * @version 0.2.0 |
| 32 | + * @version 0.2.1 |
33 | 33 | * @link http://www.mediawiki.org/wiki/Extension:WikiSync |
34 | 34 | * @author Dmitriy Sintsov <questpc@rambler.ru> |
35 | 35 | * @addtogroup Extensions |
— | — | @@ -45,6 +45,8 @@ |
46 | 46 | var $remote_log_tpl; |
47 | 47 | var $page_tpl; |
48 | 48 | |
| 49 | + var $initUser; |
| 50 | + |
49 | 51 | function initRemoteLoginFormTpl() { |
50 | 52 | $remote_wiki_root = _QXML::specialchars( WikiSyncSetup::$remote_wiki_root ); |
51 | 53 | $remote_wiki_user = _QXML::specialchars( WikiSyncSetup::$remote_wiki_user ); |
— | — | @@ -176,6 +178,7 @@ |
177 | 179 | $outputPage->addScript( |
178 | 180 | '<script type="' . $wgJsMimeType . '" src="' . WikiSyncSetup::$ScriptPath . '/WikiSync.js?' . WikiSyncSetup::$version . '"></script> |
179 | 181 | <script type="' . $wgJsMimeType . '" src="' . WikiSyncSetup::$ScriptPath . '/WikiSync_Utils.js?' . WikiSyncSetup::$version . '"></script> |
| 182 | + <script type="' . $wgJsMimeType . '">WikiSyncUtils.addEvent(window,"load",WikiSync.onloadHandler);</script> |
180 | 183 | <script type="' . $wgJsMimeType . '"> |
181 | 184 | WikiSync.setLocalNames( ' . |
182 | 185 | self::getJsObject( 'wsLocalMessages', 'last_op_error', 'synchronization_confirmation', 'synchronization_success', 'already_synchronized', 'sync_to_itself', 'diff_search', 'revision', 'file_size_mismatch' ) . |
— | — | @@ -212,18 +215,27 @@ |
213 | 216 | } |
214 | 217 | |
215 | 218 | function __construct() { |
216 | | - parent::__construct( 'WikiSync', 'delete' ); |
217 | | - WikiSyncSetup::initUser(); |
| 219 | + parent::__construct( 'WikiSync', 'edit' ); |
| 220 | + $this->initUser = WikiSyncSetup::initUser(); |
218 | 221 | } |
219 | 222 | |
220 | 223 | function execute( $param ) { |
221 | 224 | global $wgOut, $wgContLang; |
222 | 225 | global $wgUser; |
223 | | - if ( !$wgUser->isAllowed( 'delete' ) ) { |
224 | | - $wgOut->permissionRequired('delete'); |
| 226 | + # commented out, ignored by FF 3+ anyway |
| 227 | +# $wgOut->enableClientCache( false ); |
| 228 | + if ( !$wgUser->isAllowed( 'edit' ) ) { |
| 229 | + $wgOut->permissionRequired('edit'); |
225 | 230 | return; |
226 | 231 | } |
227 | | - |
| 232 | + if ( is_string( $this->initUser ) ) { |
| 233 | + # not enough priviledges to run this method |
| 234 | + $wgOut->addHTML( $this->initUser ); |
| 235 | + return; |
| 236 | + } |
| 237 | + if ( !$wgUser->isAnon() ) { |
| 238 | + WikiSyncSetup::$remote_wiki_user = $wgUser->getName(); |
| 239 | + } |
228 | 240 | self::headScripts( $wgOut, $wgContLang->isRTL() ); |
229 | 241 | $wgOut->setPagetitle( wfMsgHtml( 'wikisync' ) ); |
230 | 242 | $this->initSyncDirectionTpl(); |
Index: trunk/extensions/WikiSync/WikiSyncClient.php |
— | — | @@ -28,7 +28,7 @@ |
29 | 29 | * * Add this line at the end of your LocalSettings.php file : |
30 | 30 | * require_once "$IP/extensions/WikiSync/WikiSync.php"; |
31 | 31 | * |
32 | | - * @version 0.2.0 |
| 32 | + * @version 0.2.1 |
33 | 33 | * @link http://www.mediawiki.org/wiki/Extension:WikiSync |
34 | 34 | * @author Dmitriy Sintsov <questpc@rambler.ru> |
35 | 35 | * @addtogroup Extensions |
— | — | @@ -275,9 +275,9 @@ |
276 | 276 | */ |
277 | 277 | $args = func_get_args(); |
278 | 278 | $json_result = new WikiSyncJSONresult(); |
279 | | - if ( !WikiSyncSetup::initUser() ) { |
| 279 | + if ( is_string( $iu = WikiSyncSetup::initUser() ) ) { |
280 | 280 | # not enough priviledges to run this method |
281 | | - return $json_result->getResult( 'noaccess' ); |
| 281 | + return $json_result->getResult( 'noaccess', $iu ); |
282 | 282 | } |
283 | 283 | $snoopy = new WikiSnoopy(); |
284 | 284 | list( $remote_wiki_root, $remote_wiki_user, $remote_wiki_password ) = $args; |
— | — | @@ -369,9 +369,9 @@ |
370 | 370 | throw new MWException( 'Unsupported type of result (' . htmlspecialchars( $resultEncoding, ENT_COMPAT, 'UTF-8' ) . ' ) in ' . __METHOD__ ); |
371 | 371 | } |
372 | 372 | $json_result = new WikiSyncJSONresult( $resultEncoding == self::RESULT_JSON_STRING ); |
373 | | - if ( !WikiSyncSetup::initUser() ) { |
| 373 | + if ( is_string( $iu = WikiSyncSetup::initUser() ) ) { |
374 | 374 | # not enough priviledges to run this method |
375 | | - return $json_result->getResult( 'noaccess' ); |
| 375 | + return $json_result->getResult( 'noaccess', $iu ); |
376 | 376 | } |
377 | 377 | $api_params = is_array( $args[0] ) ? $args[0] : json_decode( $args[0], true ); |
378 | 378 | try { |
— | — | @@ -417,9 +417,9 @@ |
418 | 418 | # when there are files posted, use only 'multipart/form-data' |
419 | 419 | $useMultipart = is_array( $api_files ); |
420 | 420 | $json_result = new WikiSyncJSONresult( $resultEncoding == self::RESULT_JSON_STRING ); |
421 | | - if ( !WikiSyncSetup::initUser() ) { |
| 421 | + if ( is_string( $iu = WikiSyncSetup::initUser() ) ) { |
422 | 422 | # not enough priviledges to run this method |
423 | | - return $json_result->getResult( 'noaccess' ); |
| 423 | + return $json_result->getResult( 'noaccess', $iu ); |
424 | 424 | } |
425 | 425 | # snoopy api_params are associative array |
426 | 426 | $api_params = is_array( $args[1] ) ? $args[1] : json_decode( $args[1], true ); |
— | — | @@ -496,11 +496,6 @@ |
497 | 497 | # use default IIS / Apache execution time limit which is much larger than default PHP limit |
498 | 498 | set_time_limit( 300 ); |
499 | 499 | self::$json_result = new WikiSyncJSONresult(); |
500 | | - if ( !WikiSyncSetup::initUser() ) { |
501 | | - # not enough priviledges to run this method |
502 | | - self::$json_result->setCode( 'noaccess' ); |
503 | | - return false; |
504 | | - } |
505 | 500 | if ( count( $args ) < $min_args ) { |
506 | 501 | self::$json_result->setCode( 'init_client', 'Not enough number of parameters in ' . __METHOD__ ); |
507 | 502 | return false; |
— | — | @@ -512,9 +507,16 @@ |
513 | 508 | self::$json_result->setCode( 'init_client', $check_result ); |
514 | 509 | return false; |
515 | 510 | } |
516 | | - if ( !is_bool( self::$directionToLocal = self::$client_params['direction_to_local'] ) ) { |
517 | | - self::$json_result->setCode( 'init_client', 'Parameter "direction_to_local" is not boolean in ' . $client_name ); |
518 | | - }; |
| 511 | + if ( !isset( self::$client_params['direction_to_local'] ) ) { |
| 512 | + self::$json_result->setCode( 'init_client', 'direction_to_local was not passed for ' . $client_name ); |
| 513 | + return false; |
| 514 | + } |
| 515 | + self::$directionToLocal = self::$client_params['direction_to_local']; |
| 516 | + if ( is_string( $iu = WikiSyncSetup::initUser( self::$directionToLocal ) ) ) { |
| 517 | + # not enough priviledges to run this method |
| 518 | + self::$json_result->setCode( 'noaccess', $iu ); |
| 519 | + return false; |
| 520 | + } |
519 | 521 | return true; |
520 | 522 | } |
521 | 523 | |
Index: trunk/extensions/WikiSync/WikiSync_i18n.php |
— | — | @@ -29,7 +29,7 @@ |
30 | 30 | 'wikisync_log_uploaded_by' => 'Uploaded by [[Special:WikiSync]]', |
31 | 31 | 'wikisync_api_result_unknown_action' => 'Unknown API action', |
32 | 32 | 'wikisync_api_result_exception' => 'Exception occured in local API call', |
33 | | - 'wikisync_api_result_noaccess' => 'Only members of (sysop, bureaucrat) groups can use site synchronization', |
| 33 | + 'wikisync_api_result_noaccess' => 'Only members of the following groups can perform this action: ($1)', |
34 | 34 | 'wikisync_api_result_invalid_parameter' => 'Invalid value of parameter', |
35 | 35 | 'wikisync_api_result_http' => 'HTTP error while querying data from remote API', |
36 | 36 | 'wikisync_api_result_Unsupported' => 'Your version of MediaWiki is unsupported (less than 1.15)', |
— | — | @@ -78,7 +78,7 @@ |
79 | 79 | 'wikisync_log_imported_by' => 'Импортировано с помощью [[Special:WikiSync]]', |
80 | 80 | 'wikisync_log_uploaded_by' => 'Загружено с помощью [[Special:WikiSync]]', |
81 | 81 | 'wikisync_api_result_unknown_action' => 'Неизвестное действие (action) API', |
82 | | - 'wikisync_api_result_noaccess' => 'Only members of (sysop, bureaucrat) groups can use site synchronization', |
| 82 | + 'wikisync_api_result_noaccess' => 'Только пользователи, входящие в нижеперечисленные группы, могут выполнять указанное действие: ($1)', |
83 | 83 | 'wikisync_api_result_Illegal' => 'Недопустимое имя пользователя', |
84 | 84 | 'wikisync_api_result_NotExists' => 'Такого пользователя не существует', |
85 | 85 | 'wikisync_api_result_WrongPass' => 'Неверный пароль', |
Index: trunk/extensions/WikiSync/WikiSync.php |
— | — | @@ -28,12 +28,12 @@ |
29 | 29 | * * Add this line at the end of your LocalSettings.php file : |
30 | 30 | * require_once "$IP/extensions/WikiSync/WikiSync.php"; |
31 | 31 | * |
32 | | - * @version 0.2.0 |
| 32 | + * @version 0.2.1 |
33 | 33 | * @link http://www.mediawiki.org/wiki/Extension:WikiSync |
34 | 34 | * @author Dmitriy Sintsov <questpc@rambler.ru> |
35 | 35 | * @addtogroup Extensions |
36 | | - */ |
37 | | - |
| 36 | + */ |
| 37 | + |
38 | 38 | if ( !defined( 'MEDIAWIKI' ) ) { |
39 | 39 | die( "This file is a part of MediaWiki extension.\n" ); |
40 | 40 | } |
— | — | @@ -75,8 +75,12 @@ |
76 | 76 | class WikiSyncSetup { |
77 | 77 | # {{{ changable in LocalSettings.php : |
78 | 78 | static $remote_wiki_root = 'http://www.mediawiki.org/w'; |
79 | | - static $remote_wiki_user = 'Username'; |
| 79 | + static $remote_wiki_user = ''; |
80 | 80 | static $proxy_address = ''; # 'http://10.0.0.78:3128'; |
| 81 | + # which user groups can synchronize from remote to local |
| 82 | + static $rtl_access_groups = array( 'user' ); |
| 83 | + # which user groups can synchronize from local to remote |
| 84 | + static $ltr_access_groups = array( 'sysop', 'bureaucrat' ); |
81 | 85 | # }}} |
82 | 86 | |
83 | 87 | # {{{ decoded local proxy settings |
— | — | @@ -86,7 +90,7 @@ |
87 | 91 | static $proxy_pass = ''; |
88 | 92 | # }}} |
89 | 93 | |
90 | | - static $version = '0.2.0'; // version of extension |
| 94 | + static $version = '0.2.1'; // version of extension |
91 | 95 | static $ExtDir; // filesys path with windows path fix |
92 | 96 | static $ScriptPath; // apache virtual path |
93 | 97 | |
— | — | @@ -137,16 +141,39 @@ |
138 | 142 | } |
139 | 143 | } |
140 | 144 | |
| 145 | + static function checkUserMembership( $groups ) { |
| 146 | + global $wgUser; |
| 147 | + $ug = $wgUser->getEffectiveGroups(); |
| 148 | + if ( !$wgUser->isAnon() && !in_array( 'user', $ug ) ) { |
| 149 | + $ug[] = 'user'; |
| 150 | + } |
| 151 | + if ( array_intersect( $groups, $ug ) ) { |
| 152 | + return true; |
| 153 | + } |
| 154 | + return wfMsg( 'wikisync_api_result_noaccess', implode( $groups, ',' ) ); |
| 155 | + } |
| 156 | + |
141 | 157 | /* |
142 | 158 | * should not be called from LocalSettings.php |
143 | 159 | * should be called only when the wiki is fully initialized |
144 | | - * @return true, when the current user has admin rights, false otherwise |
| 160 | + * @param $direction defines the direction of synchronization |
| 161 | + * true - from remote to local wiki |
| 162 | + * false - from local to remote wiki |
| 163 | + * null - direction is undefined yet (any direction) |
| 164 | + * @return true, when the current user has access to synchronization; |
| 165 | + * string error message, when the current user has no access |
145 | 166 | */ |
146 | | - static function initUser() { |
147 | | - global $wgUser; |
| 167 | + static function initUser( $direction = null) { |
148 | 168 | wfLoadExtensionMessages( 'WikiSync' ); |
149 | | - $ug = $wgUser->getEffectiveGroups(); |
150 | | - return array_intersect( array( 'sysop', 'bureaucrat' ), $ug ); |
| 169 | + if ( $direction === true ) { |
| 170 | + return self::checkUserMembership( self::$rtl_access_groups ); |
| 171 | + } elseif ( $direction === false ) { |
| 172 | + return self::checkUserMembership( self::$ltr_access_groups ); |
| 173 | + } elseif ( $direction === null ) { |
| 174 | + $groups = array_merge( self::$rtl_access_groups, self::$ltr_access_groups ); |
| 175 | + return self::checkUserMembership( $groups ); |
| 176 | + } |
| 177 | + return 'Bug: direction should be boolean or null, value (' . $direction . ') given in ' . __METHOD__; |
151 | 178 | } |
152 | 179 | |
153 | 180 | } /* end of WikiSyncSetup class */ |
Index: trunk/extensions/WikiSync/WikiSyncBasic.php |
— | — | @@ -28,7 +28,7 @@ |
29 | 29 | * * Add this line at the end of your LocalSettings.php file : |
30 | 30 | * require_once "$IP/extensions/WikiSync/WikiSync.php"; |
31 | 31 | * |
32 | | - * @version 0.2.0 |
| 32 | + * @version 0.2.1 |
33 | 33 | * @link http://www.mediawiki.org/wiki/Extension:WikiSync |
34 | 34 | * @author Dmitriy Sintsov <questpc@rambler.ru> |
35 | 35 | * @addtogroup Extensions |
Index: trunk/extensions/WikiSync/WikiSync_utils.js |
— | — | @@ -1,4 +1,41 @@ |
| 2 | +var WikiSyncUtils = { |
| 3 | + // browser-independent addevent function |
| 4 | + addEvent : function ( obj, type, fn ) { |
| 5 | + if ( document.getElementById && document.createTextNode ) { |
| 6 | + if (obj.addEventListener) { |
| 7 | + obj.addEventListener( type, fn, false ); |
| 8 | + } |
| 9 | + else if (obj.attachEvent) { |
| 10 | + obj["e"+type+fn] = fn; |
| 11 | + obj[type+fn] = function() { obj["e"+type+fn]( window.event ); } |
| 12 | + obj.attachEvent( "on"+type, obj[type+fn] ); |
| 13 | + } |
| 14 | + else { |
| 15 | + obj["on"+type] = obj["e"+type+fn]; |
| 16 | + } |
| 17 | + } |
| 18 | + }, |
| 19 | + |
| 20 | + getEventObj : function ( event, stopPropagation ) { |
| 21 | + var obj; |
| 22 | + if ( typeof event.target !== 'undefined' ) { |
| 23 | + obj = event.target; |
| 24 | + if ( stopPropagation ) { |
| 25 | + event.stopPropagation(); |
| 26 | + } |
| 27 | + } else { |
| 28 | + obj = event.srcElement; |
| 29 | + if ( stopPropagation ) { |
| 30 | + event.cancelBubble = true; |
| 31 | + } |
| 32 | + } |
| 33 | + return obj; |
| 34 | + } |
| 35 | + |
| 36 | +}; |
| 37 | + |
2 | 38 | /** |
| 39 | + * percents indicator class |
3 | 40 | * @param id - id of table container for percents indicator |
4 | 41 | */ |
5 | 42 | function WikiSyncPercentsIndicator( id ) { |
— | — | @@ -13,7 +50,7 @@ |
14 | 51 | this.reset(); |
15 | 52 | } |
16 | 53 | WikiSyncPercentsIndicator.prototype.setVisibility = function( visible ) { |
17 | | - this.topElement.style.display = visible ? 'block' : 'none'; |
| 54 | + this.topElement.style.display = visible ? 'table' : 'none'; |
18 | 55 | } |
19 | 56 | /** |
20 | 57 | * @access private |
Index: trunk/extensions/WikiSync/README |
— | — | @@ -1,4 +1,4 @@ |
2 | | -MediaWiki extension WikiSync, version 0.2.0 |
| 2 | +MediaWiki extension WikiSync, version 0.2.1 |
3 | 3 | |
4 | 4 | WikiSync allows an AJAX-based synchronization of revisions and files between |
5 | 5 | global wiki site and it's local mirror. Files download can optionally be disabled, |
Index: trunk/extensions/WikiSync/INSTALL |
— | — | @@ -1,4 +1,4 @@ |
2 | | -MediaWiki extension WikiSync, version 0.2.0 |
| 2 | +MediaWiki extension WikiSync, version 0.2.1 |
3 | 3 | |
4 | 4 | * download the latest available version and extract it to your wiki extension directory. |
5 | 5 | * add the following line to LocalSettings.php |
Index: trunk/extensions/WikiSync/WikiSync.js |
— | — | @@ -27,7 +27,7 @@ |
28 | 28 | * * Add this line at the end of your LocalSettings.php file : |
29 | 29 | * require_once "$IP/extensions/WikiSync/WikiSync.php"; |
30 | 30 | * |
31 | | - * @version 0.2.0 |
| 31 | + * @version 0.2.1 |
32 | 32 | * @link http://www.mediawiki.org/wiki/Extension:WikiSync |
33 | 33 | * @author Dmitriy Sintsov <questpc@rambler.ru> |
34 | 34 | * @addtogroup Extensions |
— | — | @@ -360,6 +360,12 @@ |
361 | 361 | } |
362 | 362 | }, |
363 | 363 | |
| 364 | + /** |
| 365 | + * parses and validates AJAX result |
| 366 | + * always, even in case of error should return _parsed_ JSON |
| 367 | + * @param request AJAX result |
| 368 | + * @return parsed JSON result (JS nested object) |
| 369 | + */ |
364 | 370 | getAJAXresult : function( request ) { |
365 | 371 | var AJAXres = { 'ws_status' : '0', 'ws_code' : 'uninitialized', 'ws_msg' : 'uninitialized' }; |
366 | 372 | if ( request.status != 200 ) { |
— | — | @@ -378,6 +384,12 @@ |
379 | 385 | return AJAXres; |
380 | 386 | }, |
381 | 387 | |
| 388 | + /** |
| 389 | + * scans this.AJAXresult whether AJAX events with |
| 390 | + * assigned operation.opcode names got an response from server |
| 391 | + * allows to check for multiple events at once, in case of concurrent AJAX calls |
| 392 | + * @param arguments list of operation.opcode names |
| 393 | + */ |
382 | 394 | isAJAXresult : function() { |
383 | 395 | var found = 0; |
384 | 396 | for ( var i = 0; i < arguments.length; i++ ) { |
— | — | @@ -390,12 +402,17 @@ |
391 | 403 | |
392 | 404 | errorDefaultAction : function() { |
393 | 405 | this.syncPercents.reset(); |
| 406 | + this.filesPercents.setVisibility( false ); |
394 | 407 | this.filesPercents.reset(); |
395 | 408 | this.showIframe( '' ); |
396 | 409 | // enable all but synchronization buttons |
397 | 410 | this.setButtons( true, 'wikisync_synchronization_button' ); |
398 | 411 | }, |
399 | 412 | |
| 413 | + /** |
| 414 | + * scans this.AJAXresult for unsuccessful events which have returned errors |
| 415 | + * @return true, when there are errors; false otherwise |
| 416 | + */ |
400 | 417 | assertAJAXerrors : function() { |
401 | 418 | var result = false; |
402 | 419 | for ( var key in this.AJAXresult ) { |
— | — | @@ -411,9 +428,19 @@ |
412 | 429 | return result; |
413 | 430 | }, |
414 | 431 | |
| 432 | + /** |
| 433 | + * "pops" AJAX event result in parsed JSON format (JS nested object) |
| 434 | + * with selected operation.opcode from this.AJAXresult |
| 435 | + * should be called only on successful results |
| 436 | + * after the checking with assertAJAXerrors() |
| 437 | + * @param key operation.opcode |
| 438 | + * @param nested_props - an JS object "path" of nested properties to return |
| 439 | + * @return JS nested object (in parsed JSON format) |
| 440 | + */ |
415 | 441 | popAJAXresult : function( key, nested_props ) { |
416 | 442 | var r = this.AJAXresult[key]; |
417 | | - delete this.AJAXresult[key]; // clear events list |
| 443 | + // remote event from the list |
| 444 | + delete this.AJAXresult[key]; |
418 | 445 | if ( typeof nested_props === 'undefined' ) { |
419 | 446 | return r; |
420 | 447 | } |
— | — | @@ -427,6 +454,10 @@ |
428 | 455 | }, |
429 | 456 | |
430 | 457 | getImportToken : function( operation ) { |
| 458 | + if ( typeof operation === 'undefined' || typeof operation.opcode === 'undefined' ) { |
| 459 | + this.error( 'Bug: No operation.opcode in WikiSync.getImportToken' ); |
| 460 | + return; |
| 461 | + } |
431 | 462 | switch ( operation.opcode ) { |
432 | 463 | case 'start' : |
433 | 464 | // get sample page title for token importing |
— | — | @@ -519,6 +550,10 @@ |
520 | 551 | * transfer one file in blocks of specified length |
521 | 552 | */ |
522 | 553 | transferFile : function( operation ) { |
| 554 | + if ( typeof operation === 'undefined' || typeof operation.opcode === 'undefined' ) { |
| 555 | + this.error( 'Bug: No operation.opcode in WikiSync.transferFile' ); |
| 556 | + return; |
| 557 | + } |
523 | 558 | switch ( operation.opcode ) { |
524 | 559 | case 'start_upload' : |
525 | 560 | this.currFileOffset = 0; |
— | — | @@ -606,6 +641,10 @@ |
607 | 642 | * update new files currently available in chunk (if any) |
608 | 643 | */ |
609 | 644 | updateNewFiles : function( operation ) { |
| 645 | + if ( typeof operation === 'undefined' || typeof operation.opcode === 'undefined' ) { |
| 646 | + this.error( 'Bug: No operation.opcode in WikiSync.updateNewFiles' ); |
| 647 | + return; |
| 648 | + } |
610 | 649 | switch ( operation.opcode ) { |
611 | 650 | case 'new_files_result' : |
612 | 651 | this.log( this.AJAXresult[operation.opcode] ); |
— | — | @@ -648,6 +687,10 @@ |
649 | 688 | * synchronize xml chunks in blocks (optionally with passing through file update) |
650 | 689 | */ |
651 | 690 | synchronize : function( operation ) { |
| 691 | + if ( typeof operation === 'undefined' || typeof operation.opcode === 'undefined' ) { |
| 692 | + this.error( 'Bug: No operation.opcode in WikiSync.synchronize' ); |
| 693 | + return; |
| 694 | + } |
652 | 695 | switch ( operation.opcode ) { |
653 | 696 | case 'start' : |
654 | 697 | this.srcSyncId = operation.revid; |
— | — | @@ -655,7 +698,6 @@ |
656 | 699 | if ( !confirm( this.formatMessage( 'synchronization_confirmation', this.srcWikiRoot, this.dstWikiRoot, operation.revid ) ) ) { |
657 | 700 | this.log( 'Operation was cancelled' ); |
658 | 701 | this.syncPercents.reset(); |
659 | | - this.filesPercents.reset(); |
660 | 702 | // enable all buttons |
661 | 703 | this.setButtons( true ); |
662 | 704 | return; |
— | — | @@ -674,6 +716,7 @@ |
675 | 717 | 'fname' : 'synchronize', |
676 | 718 | 'opcode' : 'xml_chunk_result' |
677 | 719 | }; |
| 720 | + this.syncPercents.display( { 'desc' : this.formatMessage( 'revision', operation.startid ), 'curr' : operation.startid } ); |
678 | 721 | this.wsAPI( 'syncXMLchunk', clientParams, nextOp ); |
679 | 722 | return; |
680 | 723 | case 'xml_chunk_result' : |
— | — | @@ -684,8 +727,6 @@ |
685 | 728 | this.xmlContinueStartId = (typeof result.ws_continue_startid) === 'undefined' ? null : result.ws_continue_startid; |
686 | 729 | if ( this.xmlContinueStartId === null ) { |
687 | 730 | this.syncPercents.display( { 'desc' : '', 'curr' : 'max' } ); |
688 | | - } else { |
689 | | - this.syncPercents.display( { 'desc' : this.formatMessage( 'revision', this.xmlContinueStartId ), 'curr' : this.xmlContinueStartId } ); |
690 | 731 | } |
691 | 732 | if ( this.syncFiles && typeof result.files !== 'undefined' ) { |
692 | 733 | var clientParams = { |
— | — | @@ -727,7 +768,7 @@ |
728 | 769 | */ |
729 | 770 | findCommonRev : function( operation ) { |
730 | 771 | if ( typeof operation === 'undefined' || typeof operation.opcode === 'undefined' ) { |
731 | | - this.error( 'Bug: No operation.opcode in WikiSync.getLastSrcRev' ); |
| 772 | + this.error( 'Bug: No operation.opcode in WikiSync.findCommonRev' ); |
732 | 773 | return; |
733 | 774 | } |
734 | 775 | switch ( operation.opcode ) { |
— | — | @@ -811,7 +852,7 @@ |
812 | 853 | */ |
813 | 854 | getSrcRev : function( operation ) { |
814 | 855 | if ( typeof operation === 'undefined' || typeof operation.opcode === 'undefined' ) { |
815 | | - this.error( 'Bug: No operation.opcode in WikiSync.getLastSrcRev' ); |
| 856 | + this.error( 'Bug: No operation.opcode in WikiSync.getSrcRev' ); |
816 | 857 | return; |
817 | 858 | } |
818 | 859 | switch ( operation.opcode ) { |
— | — | @@ -876,10 +917,6 @@ |
877 | 918 | * "Synchronize" button click handler |
878 | 919 | */ |
879 | 920 | process : function() { |
880 | | - this.syncPercents = new WikiSyncPercentsIndicator( 'wikisync_xml_percents' ); |
881 | | - this.filesPercents = new WikiSyncPercentsIndicator( 'wikisync_files_percents' ); |
882 | | - this.syncPercents.setVisibility( true ); |
883 | | - this.showIframe( '' ); |
884 | 921 | if ( wgServer.indexOf( this.remoteContext.wikiroot ) !== -1 || |
885 | 922 | this.remoteContext.wikiroot.indexOf( wgServer ) !== -1 ) { |
886 | 923 | alert( this.formatMessage( 'sync_to_itself' ) ); |
— | — | @@ -895,10 +932,25 @@ |
896 | 933 | } |
897 | 934 | // disable all buttons |
898 | 935 | this.setButtons( false ); |
| 936 | + this.syncPercents.setVisibility( true ); |
899 | 937 | /* get first and last source revision in parallel */ |
900 | 938 | this.getSrcRev( { 'opcode' : 'start' } ); |
901 | 939 | this.getSrcRev( { 'opcode' : 'start', 'dir' : 'newer' } ); |
902 | 940 | return false; |
| 941 | + }, |
| 942 | + |
| 943 | + onloadHandler : function() { |
| 944 | + // {{{ switch the context |
| 945 | + if ( typeof this._WikiSync === 'undefined' ) { |
| 946 | + return WikiSync.onloadHandler.call( WikiSync ); |
| 947 | + } |
| 948 | + // }}} |
| 949 | + this.syncPercents = new WikiSyncPercentsIndicator( 'wikisync_xml_percents' ); |
| 950 | + this.filesPercents = new WikiSyncPercentsIndicator( 'wikisync_files_percents' ); |
| 951 | + this.syncPercents.setVisibility( false ); |
| 952 | + this.filesPercents.setVisibility( false ); |
| 953 | + this.showIframe( '' ); |
| 954 | + this.errorDefaultAction(); |
903 | 955 | } |
904 | 956 | |
905 | 957 | } |