Index: trunk/extensions/AjaxLogin/AjaxLogin.i18n.php |
— | — | @@ -0,0 +1,158 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * Internationalization file for AjaxLogin extension. |
| 5 | + * |
| 6 | + * @file |
| 7 | + * @ingroup Extensions |
| 8 | + */ |
| 9 | + |
| 10 | +$messages = array(); |
| 11 | + |
| 12 | +/** English |
| 13 | + * @author Inez Korczyński <korczynski@gmail.com> |
| 14 | + */ |
| 15 | +$messages['en'] = array( |
| 16 | + 'ajaxLogin1' => 'To complete your log in, you must enter a new password. This will take you away from this edit page and you may lose your current edit.', |
| 17 | + 'ajaxLogin2' => 'Are you sure? You may lose your edits if you leave this page now.', |
| 18 | + 'ajaxlogin-create' => 'Create an account', |
| 19 | +); |
| 20 | + |
| 21 | +/** German (Deutsch) |
| 22 | + * @author Tim 'Avatar' Bartel |
| 23 | + */ |
| 24 | +$messages['de'] = array( |
| 25 | + 'ajaxLogin1' => 'Du musst ein neues Passwort eingeben um die Anmeldung durchzuführen. Dies geschieht auf einer andere Seite, so dass du deine aktuellen Änderungen auf dieser Seite möglicherweise verlieren wirst.', |
| 26 | + 'ajaxLogin2' => 'Bist du sicher? Möglicherweise gehen deine aktuellen Änderungen verloren, wenn du diese Seite verlässt.', |
| 27 | +); |
| 28 | + |
| 29 | +/** Spanish (Español) |
| 30 | + * @author Juan David Ruiz |
| 31 | + */ |
| 32 | +$messages['es'] = array( |
| 33 | + 'ajaxLogin1' => 'Para completar tu registro, debes escribir una nueva contraseña. Esto hará que salgas de esta página de edición y podrías perder tu edición actual.', |
| 34 | + 'ajaxLogin2' => '¿Estas seguro? Podrías perder tus ediciones si abandonas esta página ahora.', |
| 35 | +); |
| 36 | + |
| 37 | +/** Finnish (Suomi) |
| 38 | + * @author Jack Phoenix <jack@countervandalism.net> |
| 39 | + */ |
| 40 | +$messages['fi'] = array( |
| 41 | + 'ajaxLogin1' => 'Suorittaaksesi sisäänkirjautumisesi loppuun, sinun tulee antaa uusi salasana. Tämä vie sinut pois tältä muokkaussivulta ja saatat menettää nykyisen muokkauksesi.', |
| 42 | + 'ajaxLogin2' => 'Oletko varma? Saatat menettää muokkauksesi jos lähdet tältä sivulta nyt.', |
| 43 | + 'ajaxlogin-create' => 'Luo käyttäjätunnus', |
| 44 | +); |
| 45 | + |
| 46 | +/** French (Français) |
| 47 | + * @author Polytherion |
| 48 | + */ |
| 49 | +$messages['fr'] = array( |
| 50 | + 'ajaxLogin1' => 'Pour compléter votre connexion, vous devez saisir un nouveau mot de passe. Cela vous fera quitter cette page et vous pourriez perdre votre modification.', |
| 51 | + 'ajaxLogin2' => 'Êtes-vous certain ? Vous pourriez perdre vos modifications si vous quittez cette page maintenant.', |
| 52 | +); |
| 53 | + |
| 54 | +/** Irish (Gaeilge) |
| 55 | + * @author Panu Petteri Höglund |
| 56 | + */ |
| 57 | +$messages['ga'] = array( |
| 58 | + 'ajaxLogin2' => 'An bhfuil tú cinnte? Má imíonn tú ón leathanach seo anois, is féidir go gcaillfear na hathruithe a rinne tú.', |
| 59 | +); |
| 60 | + |
| 61 | +/** Hungarian (Magyar) |
| 62 | + * @author Blogadmin |
| 63 | + */ |
| 64 | +$messages['hu'] = array( |
| 65 | + 'ajaxLogin1' => 'A bejelentkezés befejezéséhez meg kell adnod a jelszavadat. Ez elirányít a szerkesztőablakból, úgyhogy ezek a szerkesztéseid el fognak veszni. Ha ezt nem szeretnéd, másold ki őket a szövegmezőből!', |
| 66 | + 'ajaxLogin2' => 'Biztos vagy benne? Az oldal elhagyásával a szerkesztéseid elvesznek.', |
| 67 | +); |
| 68 | + |
| 69 | +/** Japanese (日本語) |
| 70 | + * @author Tommy6 |
| 71 | + */ |
| 72 | +$messages['ja'] = array( |
| 73 | + 'ajaxLogin1' => 'ログインを完了するには新しいパスワードを入力する必要があります。これにより、現在編集中のページから離れ、保存されていない内容は失われることになります。', |
| 74 | + 'ajaxLogin2' => '本当によろしいでしょうか?今このページを離れると保存されていない編集は失われることになります。', |
| 75 | +); |
| 76 | + |
| 77 | +/** Brazilian Portuguese (Português do Brasil) |
| 78 | + * @author Brunoy Anastasiya Seryozhenko |
| 79 | + */ |
| 80 | +$messages['pt-br'] = array( |
| 81 | + 'ajaxLogin1' => 'Para completar seu login, Você deve colocar uma nova password. Isto o impedirá de editar esta página e você perderá esta edição.', |
| 82 | + 'ajaxLogin2' => 'Tem certeza? Você perderá as suas edições se abandonar a página agora.', |
| 83 | +); |
| 84 | + |
| 85 | +/** Romanian (Română) |
| 86 | + * @author Pixi |
| 87 | + */ |
| 88 | +$messages['ro'] = array( |
| 89 | + 'ajaxLogin1' => 'Pentru a te autentifica, trebuie să introduci o parolă nouă. Aceasta înseamnă că vei părăsi pagina de editare şi vei pierde editările efectuate până acum.', |
| 90 | + 'ajaxLogin2' => 'Eşti sigur? Vei pierde editările efectuate dacă părăseşti această pagină acum.', |
| 91 | +); |
| 92 | + |
| 93 | +/** Russian (Русский) |
| 94 | + * @author Exlex |
| 95 | + */ |
| 96 | +$messages['ru'] = array( |
| 97 | + 'ajaxLogin1' => 'Чтобы закончить вход, необходимо ввести новый пароль. При этом Вы покинете страницу редактирования и это может привести к потере внесённых изменений.', |
| 98 | + 'ajaxLogin2' => 'Вы уверены? Внесённые изменения могут быть утрачены, если сейчас покинуть эту страницу.', |
| 99 | +); |
| 100 | + |
| 101 | +/** Swedish (Svenska) |
| 102 | + * @author Grillmannen |
| 103 | + */ |
| 104 | +$messages['sv'] = array( |
| 105 | + 'ajaxLogin1' => 'För att komplettera din inloggning måste du skriva in ett nytt lösenord. Detta kommer att föra dig bort från den här redigeringssidan och du kan komma att förlora din nuvarande redigering.', |
| 106 | + 'ajaxLogin2' => 'Är du säker? Du kan förlora din redigering om du lämnar den här sidan nu.', |
| 107 | +); |
| 108 | + |
| 109 | +/** Chinese (中文) |
| 110 | + * @author 許瑜真 (Yuchen Hsu/KaurJmeb) |
| 111 | + */ |
| 112 | +$messages['zh'] = array ( |
| 113 | + 'ajaxLogin1' => '为完成登入动作,請輸入新的密碼。这动作可能会使你跳离编輯頁面,可能会損失編輯結果。', |
| 114 | +); |
| 115 | + |
| 116 | +/** Chinese (PRC) (中文(中国大陆)) |
| 117 | + * @author 許瑜真 (Yuchen Hsu/KaurJmeb) |
| 118 | + */ |
| 119 | +$messages['zh-cn'] = array ( |
| 120 | + 'ajaxLogin1' => '为完成登入动作,请输入新的密码。这动作可能会使你跳离编辑页面,可能会损失编辑结果。', |
| 121 | + 'ajaxLogin2' => '这动作可能会使你跳离编辑页面,可能会损失编辑结果。确定要离开吗?', |
| 122 | +); |
| 123 | + |
| 124 | +/** Simplified Chinese (中文(简化字)) |
| 125 | + * @author 許瑜真 (Yuchen Hsu/KaurJmeb) |
| 126 | + */ |
| 127 | +$messages['zh-hans'] = array ( |
| 128 | + 'ajaxLogin2' => '这动作可能会使你跳离编辑页面,可能会损失编辑结果。确定要离开吗?', |
| 129 | +); |
| 130 | + |
| 131 | +/** Traditional Chinese (中文(傳統字)) |
| 132 | + * @author 許瑜真 (Yuchen Hsu/KaurJmeb) |
| 133 | + */ |
| 134 | +$messages['zh-hant'] = array ( |
| 135 | + 'ajaxLogin2' => '這動作可能會使你跳離編輯頁面,可能會損失編輯結果。確定要離開嗎?', |
| 136 | +); |
| 137 | + |
| 138 | +/** Hong Kong Chinese (中文(香港)) |
| 139 | + * @author 許瑜真 (Yuchen Hsu/KaurJmeb) |
| 140 | + */ |
| 141 | +$messages['zh-hk'] = array ( |
| 142 | + 'ajaxLogin1' => '為完成登入動作,請輸入新的密碼。這動作可能會使你跳離編輯頁面,可能會損失編輯結果。', |
| 143 | + 'ajaxLogin2' => '這動作可能會使你跳離編輯頁面,可能會損失編輯結果。確定要離開嗎?', |
| 144 | +); |
| 145 | + |
| 146 | +/** Chinese (Singapore) (中文 (新加坡)) |
| 147 | + * @author 許瑜真 (Yuchen Hsu/KaurJmeb) |
| 148 | + */ |
| 149 | +$messages['zh-sg'] = array ( |
| 150 | + 'ajaxLogin1' => '为完成登入动作,请输入新的密码。这动作可能会使你跳离编辑页面,可能会损失编辑结果。', |
| 151 | +); |
| 152 | + |
| 153 | +/** Taiwan Chinese (中文(台灣)) |
| 154 | + * @author 許瑜真 (Yuchen Hsu/KaurJmeb) |
| 155 | + */ |
| 156 | +$messages['zh-tw'] = array ( |
| 157 | + 'ajaxLogin1' => '為完成登入動作,請輸入新的密碼。這動作可能會使你跳離編輯頁面,可能會損失編輯結果。', |
| 158 | + 'ajaxLogin2' => '這動作可能會使你跳離編輯頁面,可能會損失編輯結果。確定要離開嗎?', |
| 159 | +); |
\ No newline at end of file |
Property changes on: trunk/extensions/AjaxLogin/AjaxLogin.i18n.php |
___________________________________________________________________ |
Name: svn:eol-style |
1 | 160 | + native |
Index: trunk/extensions/AjaxLogin/AjaxLogin.php |
— | — | @@ -0,0 +1,136 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * AjaxLogin extension - allows users to log in through an AJAX pop-up box |
| 5 | + * |
| 6 | + * @file |
| 7 | + * @ingroup Extensions |
| 8 | + * @version 1.1 |
| 9 | + * @author Inez Korczyński <korczynski(at)gmail(dot)com> |
| 10 | + * @author Jack Phoenix <jack@countervandalism.net> |
| 11 | + * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later |
| 12 | + */ |
| 13 | + |
| 14 | +if( !defined( 'MEDIAWIKI' ) ){ |
| 15 | + die( "This is not a valid entry point.\n" ); |
| 16 | +} |
| 17 | + |
| 18 | +// Extension credits that will show up on Special:Version |
| 19 | +$wgExtensionCredits['other'][] = array( |
| 20 | + 'name' => 'AjaxLogin', |
| 21 | + 'version' => '1.1', |
| 22 | + 'author' => array( 'Inez Korczyński', 'Jack Phoenix' ), |
| 23 | + 'description' => 'Dynamic box which allow users to login and remind password', |
| 24 | + 'url' => 'http://www.mediawiki.org/wiki/Extension:AjaxLogin', |
| 25 | +); |
| 26 | + |
| 27 | +// Array of skins for which AjaxLogin is enabled. |
| 28 | +// Key is: 'skinname' => (true or false) |
| 29 | +$wgEnableAjaxLogin = array( |
| 30 | + 'monobook' => true |
| 31 | +); |
| 32 | + |
| 33 | +// Autoload AjaxLogin API interface |
| 34 | +$dir = dirname( __FILE__ ) . '/'; |
| 35 | +$wgAutoloadClasses['ApiAjaxLogin'] = $dir . 'ApiAjaxLogin.php'; |
| 36 | +$wgAPIModules['ajaxlogin'] = 'ApiAjaxLogin'; |
| 37 | + |
| 38 | +// Internationalization file |
| 39 | +$wgExtensionMessagesFiles['AjaxLogin'] = $dir . 'AjaxLogin.i18n.php'; |
| 40 | + |
| 41 | +// Hook things up |
| 42 | +$wgHooks['BeforePageDisplay'][] = 'AjaxLoginJS'; |
| 43 | +$wgHooks['SkinAfterContent'][] = 'GetAjaxLoginForm'; |
| 44 | +$wgHooks['MakeGlobalVariablesScript'][] = 'efAddAjaxLoginVariables'; |
| 45 | + |
| 46 | +/** |
| 47 | + * Adds required JavaScript & CSS files to the HTML output of a page if AjaxLogin is enabled |
| 48 | + * |
| 49 | + * @param $out OutputPage object |
| 50 | + * @return true |
| 51 | + */ |
| 52 | +function AjaxLoginJS( OutputPage $out ) { |
| 53 | + global $wgEnableAjaxLogin, $wgScriptPath, $wgJsMimeType; |
| 54 | + |
| 55 | + # Don't load anything if AjaxLogin isn't enabled |
| 56 | + if( !isset( $wgEnableAjaxLogin ) ) { |
| 57 | + return true; |
| 58 | + } |
| 59 | + |
| 60 | + // YUI library dependencies |
| 61 | + // Utilities.js -- contains all stuff required by AjaxLogin and a tad bit more... |
| 62 | + $out->addScript('<script language="javascript" type="'. $wgJsMimeType .'" src="http://yui.yahooapis.com/2.6.0/build/utilities/utilities.js"></script>'."\n"); |
| 63 | + // DragDrop |
| 64 | + $out->addScript('<script language="javascript" type="'. $wgJsMimeType .'" src="http://yui.yahooapis.com/2.6.0/build/yahoo-dom-event/yahoo-dom-event.js"></script>'."\n"); |
| 65 | + // YUI styles -- these introduce some CSS warnings when included... |
| 66 | + $out->addExtensionStyle( 'http://yui.yahooapis.com/2.7.0/build/container/assets/container.css' ); |
| 67 | + $out->addExtensionStyle( 'http://yui.yahooapis.com/2.7.0/build/container/assets/container-core.css' ); |
| 68 | + // Our custom CSS |
| 69 | + $out->addStyle( '../..' . $wgScriptPath . '/extensions/AjaxLogin/AjaxLogin.css' ); |
| 70 | + // AjaxLogin's own JS file + YAHOOTools.js (because AjaxLogin.js calls a couple YAHOO.Tools functions...) |
| 71 | + $out->addScriptFile( $wgScriptPath . '/extensions/AjaxLogin/AjaxLogin.js' ); |
| 72 | + $out->addScriptFile( $wgScriptPath . '/extensions/AjaxLogin/YAHOOTools.js' ); |
| 73 | + return true; |
| 74 | +} |
| 75 | + |
| 76 | +/** |
| 77 | + * Adds the required JavaScript variables inside the <head> tags of the page |
| 78 | + * if AjaxLogin is enabled and the current page is not an article page. |
| 79 | + * |
| 80 | + * @param $vars Variables to be added |
| 81 | + * @return true |
| 82 | + */ |
| 83 | +function efAddAjaxLoginVariables( $vars ){ |
| 84 | + global $wgEnableAjaxLogin; |
| 85 | + |
| 86 | + $vars['wgEnableAjaxLogin'] = ( is_array( $wgEnableAjaxLogin ) ) ? in_array( $vars['skin'], $wgEnableAjaxLogin ) : false; |
| 87 | + if( $vars['wgIsArticle'] == false && $vars['wgEnableAjaxLogin'] ) { |
| 88 | + wfLoadExtensionMessages( 'AjaxLogin' ); |
| 89 | + $vars['ajaxLogin1'] = wfMsg( 'ajaxLogin1' ); |
| 90 | + $vars['ajaxLogin2'] = wfMsg( 'ajaxLogin2' ); |
| 91 | + } |
| 92 | + |
| 93 | + return true; |
| 94 | +} |
| 95 | + |
| 96 | +/** |
| 97 | + * Gets the AjaxLogin form |
| 98 | + * |
| 99 | + * @param $data The data, AjaxLogin form in this case, to be added to the HTML output of a page |
| 100 | + * @return true |
| 101 | + */ |
| 102 | +function GetAjaxLoginForm( &$data ) { |
| 103 | + global $wgAuth, $wgEnableEmail, $wgOut, $wgTitle, $wgUser; |
| 104 | + if( $wgUser->isAnon() && $wgTitle->getNamespace() != 8 && $wgTitle->getDBkey() != 'Userlogin' ) { |
| 105 | + $titleObj = SpecialPage::getTitleFor( 'Userlogin' ); |
| 106 | + $link = $titleObj->getLocalUrl( 'type=signup' ); |
| 107 | + $wgOut->addHTML('<!--[if lt IE 9]><style type="text/css">#userloginRound { width: 350px !important; }</style><![endif]--> |
| 108 | +<div id="userloginRound" class="roundedDiv yui-module yui-overlay yui-panel" style="display:none; background:none; border:none;"> |
| 109 | + <b class="xtop"><b class="xb1"></b><b class="xb2"></b><b class="xb3"></b><b class="xb4"></b></b> |
| 110 | + <div class="r_boxContent"> |
| 111 | + <div class="boxHeader color1">'. wfMsg( 'login' ) .'</div> |
| 112 | + <form action="" method="post" name="userajaxloginform" id="userajaxloginform" style="margin:5px"> |
| 113 | + <div id="wpError" style="width: 250px; line-height: 1.4em"></div> |
| 114 | + <label for="wpName1">'. wfMsg( 'yourname' ) .'</label><br /> |
| 115 | + <input type="text" class="loginText" name="wpName" id="wpName1" tabindex="101" size="20" /><br /> |
| 116 | + <label for="wpPassword1">'. wfMsg( 'yourpassword' ) .'</label><br /> |
| 117 | + <input type="password" class="loginPassword" name="wpPassword" id="wpPassword1" tabindex="102" size="20" /><br /> |
| 118 | + <div style="padding-bottom:3px"> |
| 119 | + <input type="checkbox" name="wpRemember" tabindex="104" value="1" id="wpRemember1"'.( $wgUser->getOption( 'rememberpassword' ) ? ' checked="checked"' : '' ).' /> |
| 120 | + <label for="wpRemember1">'. wfMsg( 'remembermypassword' ) .'</label><br /> |
| 121 | + </div> |
| 122 | + <input style="margin:0;padding:0 .25em;width:auto;overflow:visible;" type="submit" name="wpLoginattempt" id="wpLoginattempt" tabindex="105" value="'. wfMsg( 'login' ) .'" />' |
| 123 | + ); |
| 124 | + if( $wgEnableEmail && $wgAuth->allowPasswordChange() ) { |
| 125 | + $wgOut->addHTML( '<br /><input style="margin:3px 0;padding:0 .25em;width:auto;overflow:visible;font-size:0.9em" type="submit" name="wpMailmypassword" id="wpMailmypassword" tabindex="106" value="'. wfMsg( 'mailmypassword' ) .'" />' ); |
| 126 | + } |
| 127 | + // Originally this used core message 'nologinlink' but it wouldn't work too well for Finnish, so I changed it. --Jack Phoenix |
| 128 | + wfLoadExtensionMessages( 'AjaxLogin' ); |
| 129 | + $wgOut->addHTML('<br /><a id="wpAjaxRegister" href="'. htmlspecialchars( $link ) .'">'. wfMsg( 'ajaxlogin-create' ) .'</a> |
| 130 | + </form> |
| 131 | + |
| 132 | + </div> |
| 133 | + <b class="xbottom"><b class="xb4"></b><b class="xb3"></b><b class="xb2"></b><b class="xb1"></b></b> |
| 134 | +</div>'); |
| 135 | + } |
| 136 | + return true; |
| 137 | +} |
\ No newline at end of file |
Property changes on: trunk/extensions/AjaxLogin/AjaxLogin.php |
___________________________________________________________________ |
Name: svn:eol-style |
1 | 138 | + native |
Index: trunk/extensions/AjaxLogin/AjaxLogin.css |
— | — | @@ -0,0 +1,30 @@ |
| 2 | +/*** AJAX LOGIN ***/ |
| 3 | +/* styles copied from monaco/css/header.css */ |
| 4 | +#userloginRound_c { z-index: 2000 !important; } |
| 5 | +#userloginRound_mask { z-index: 1000 !important; } |
| 6 | + |
| 7 | +#userloginRound .r_boxContent { |
| 8 | + background-color: #fff; |
| 9 | + color: #000000; |
| 10 | + border: solid 1px #aaaaaa; |
| 11 | +} |
| 12 | + |
| 13 | +#userloginRound .boxHeader { |
| 14 | + padding: 3px 5px; |
| 15 | + font-size: 12px; /* Jack: added this */ |
| 16 | +} |
| 17 | + |
| 18 | +#userloginRound form { |
| 19 | + padding: 3px; |
| 20 | + font-size: 12px; |
| 21 | +/* font-size: 0.9em; original -- doesn't look too good on monobook*/ |
| 22 | +} |
| 23 | + |
| 24 | +/* copied from monaco/css/root.css */ |
| 25 | +.color1, .color1 a, .yui-panel .hd { |
| 26 | + background-color: #36C; |
| 27 | + color: white; |
| 28 | +} |
| 29 | +.color2 { |
| 30 | + background-color: #F5F5F5; |
| 31 | +} |
Property changes on: trunk/extensions/AjaxLogin/AjaxLogin.css |
___________________________________________________________________ |
Name: svn:eol-style |
1 | 32 | + native |
Index: trunk/extensions/AjaxLogin/AjaxLogin.js |
— | — | @@ -0,0 +1,172 @@ |
| 2 | +/** |
| 3 | + * JavaScript for AjaxLogin extension |
| 4 | + * @todo FIXME: rewrite and document (see README) |
| 5 | + * @author Inez Korczyński <korczynski(at)gmail(dot)com> |
| 6 | + * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later |
| 7 | + */ |
| 8 | + |
| 9 | +if( typeof wgEnableAjaxLogin != 'undefined' && wgEnableAjaxLogin ) { |
| 10 | + |
| 11 | + YAHOO.namespace("wikia.AjaxLogin"); |
| 12 | + |
| 13 | + (function() { |
| 14 | + |
| 15 | + var Dom = YAHOO.util.Dom; |
| 16 | + var Event = YAHOO.util.Event; |
| 17 | + var DDM = YAHOO.util.DragDropMgr; |
| 18 | + |
| 19 | + YAHOO.wikia.AjaxLogin = { |
| 20 | + init: function() { |
| 21 | + if( Dom.get( 'userloginRound' ) ) { |
| 22 | + // Jack: changed to 'pt-anonlogin' from 'login' |
| 23 | + Event.addListener( 'pt-anonlogin', 'click', YAHOO.wikia.AjaxLogin.showLoginPanel ); |
| 24 | + } |
| 25 | + }, |
| 26 | + showLoginPanel: function( e ) { |
| 27 | + // Prevent the default action for clicked element (probably A) |
| 28 | + if( e ) { |
| 29 | + YAHOO.util.Event.preventDefault(e); |
| 30 | + } |
| 31 | + |
| 32 | + if( YAHOO.lang.isUndefined( YAHOO.wikia.AjaxLogin.loginPanel ) ) { |
| 33 | + |
| 34 | + var keylistenerHandler = function(type, args, obj) { |
| 35 | + YAHOO.wikia.AjaxLogin.loginPanel.hide(); |
| 36 | + } |
| 37 | + |
| 38 | + YAHOO.wikia.AjaxLogin.keylistener = new YAHOO.util.KeyListener(document, { keys:[27] }, { fn:keylistenerHandler } ); |
| 39 | + |
| 40 | + //YAHOO.log("Initiate and display loginPanel", "info", "AjaxLogin.js"); |
| 41 | + YAHOO.wikia.AjaxLogin.loginPanel = new YAHOO.widget.Panel('userloginRound', { |
| 42 | + width: "auto", |
| 43 | + modal: true, |
| 44 | + constraintoviewport: true, |
| 45 | + draggable: false, |
| 46 | + fixedcenter: true, |
| 47 | + underlay: "none", |
| 48 | + visible: true, |
| 49 | + keylisteners: YAHOO.wikia.AjaxLogin.keylistener |
| 50 | + }); |
| 51 | + Dom.setStyle('userloginRound', 'display', ''); |
| 52 | + YAHOO.wikia.AjaxLogin.loginPanel.render(document.body); |
| 53 | + |
| 54 | + // add submit event handler for login form |
| 55 | + Event.addListener('userajaxloginform', 'submit', YAHOO.wikia.AjaxLogin.formSubmitHandler); |
| 56 | + Event.addListener('wpAjaxRegister', 'click', YAHOO.wikia.AjaxLogin.ajaxRegisterConfirm); |
| 57 | + } else { |
| 58 | + //YAHOO.log("Display initiated loginPanel", "info", "AjaxLogin.js"); |
| 59 | + YAHOO.wikia.AjaxLogin.loginPanel.show(); |
| 60 | + } |
| 61 | + if( Dom.get('wpName1') ) { |
| 62 | + Dom.get('wpName1').focus(); |
| 63 | + } |
| 64 | + }, |
| 65 | + formSubmitHandler: function( e ) { |
| 66 | + // Prevent the default action for event (submit of form) |
| 67 | + if( e ) { |
| 68 | + YAHOO.util.Event.preventDefault(e); |
| 69 | + } |
| 70 | + |
| 71 | + var ajaxLoginCallback = { |
| 72 | + success: YAHOO.wikia.AjaxLogin.handleSuccess, |
| 73 | + failure: YAHOO.wikia.AjaxLogin.handleFailure, |
| 74 | + scope: YAHOO.wikia.AjaxLogin |
| 75 | + }; |
| 76 | + |
| 77 | + YAHOO.util.Connect.setForm('userajaxloginform'); |
| 78 | + |
| 79 | + // Let's block login form (disable buttons and input boxes) |
| 80 | + YAHOO.wikia.AjaxLogin.blockLoginForm(true); |
| 81 | + |
| 82 | + var actionURL = wgServer + wgScriptPath + '/api.php?action=ajaxlogin&format=json'; |
| 83 | + var cObj = YAHOO.util.Connect.asyncRequest('POST', actionURL, ajaxLoginCallback); |
| 84 | + }, |
| 85 | + handleSuccess: function(o) { |
| 86 | + var response = YAHOO.Tools.JSONParse(o.responseText); |
| 87 | + var responseResult = response.ajaxlogin.result; |
| 88 | + switch(responseResult) { |
| 89 | + case 'Reset': |
| 90 | + if( Dom.get( 'wpPreview' ) && Dom.get( 'wpLogin' ) ) { |
| 91 | + if( typeof( ajaxLogin1 ) != 'undefined' && !confirm( ajaxLogin1 ) ) { |
| 92 | + break; |
| 93 | + } |
| 94 | + } |
| 95 | + Dom.get('userajaxloginform').action = wgServer + wgScriptPath + '/index.php?title=Special:Userlogin&action=submitlogin&type=login'; |
| 96 | + Event.removeListener('userajaxloginform', 'submit', YAHOO.wikia.AjaxLogin.formSubmitHandler); |
| 97 | + YAHOO.wikia.AjaxLogin.blockLoginForm(false); |
| 98 | + Dom.get('userajaxloginform').submit(); |
| 99 | + YAHOO.wikia.AjaxLogin.blockLoginForm(true); |
| 100 | + break; |
| 101 | + case 'Success': |
| 102 | + // Jack: Special:RequestWiki probably doesn't exist outside Wikia sites... |
| 103 | + /*if( wgCanonicalNamespace == 'Special' && wgCanonicalSpecialPageName == 'RequestWiki' ) { |
| 104 | + Event.removeListener('pSubmit', 'click', YAHOO.wikia.AjaxLogin.showLoginPanel); |
| 105 | + Dom.get('pSubmit').click(); |
| 106 | + } else*/ if( Dom.get('wpPreview') && Dom.get('wpLogin') ) { |
| 107 | + if( Dom.get('wikiDiff') && (Dom.get('wikiDiff').childNodes.length > 0) ) { |
| 108 | + Dom.get('wpDiff').click(); |
| 109 | + } else { |
| 110 | + if( Dom.get('wikiPreview') && Dom.get('wikiPreview').childNodes.length == 0 ) { |
| 111 | + Dom.get('wpLogin').value = 1; |
| 112 | + } |
| 113 | + Dom.get('wpPreview').click(); |
| 114 | + } |
| 115 | + } else { |
| 116 | + if( wgCanonicalSpecialPageName == 'Userlogout' ) { |
| 117 | + window.location.href = wgServer + wgScriptPath; |
| 118 | + } else { |
| 119 | + window.location.reload(true); |
| 120 | + } |
| 121 | + } |
| 122 | + break; |
| 123 | + case 'NotExists': |
| 124 | + this.blockLoginForm(false); |
| 125 | + Dom.get('wpName1').value = ''; |
| 126 | + Dom.get('wpPassword1').value = ''; |
| 127 | + Dom.get('wpName1').focus(); |
| 128 | + case 'WrongPass': |
| 129 | + this.blockLoginForm(false); |
| 130 | + Dom.get('wpPassword1').value = ''; |
| 131 | + Dom.get('wpPassword1').focus(); |
| 132 | + default: |
| 133 | + this.blockLoginForm(false); |
| 134 | + this.displayReason(response.ajaxlogin.text); |
| 135 | + break; |
| 136 | + } |
| 137 | + }, |
| 138 | + handleFailure: function() { |
| 139 | + //YAHOO.log("YAHOO.wikia.AjaxLogin.handleFailure was called", "error", "AjaxLogin.js"); |
| 140 | + }, |
| 141 | + displayReason: function(reason) { |
| 142 | + Dom.setStyle('wpError', 'display', ''); |
| 143 | + Dom.get('wpError').innerHTML = reason + '<br /><br />'; |
| 144 | + }, |
| 145 | + blockLoginForm: function(block) { |
| 146 | + if( !YAHOO.lang.isBoolean(block) ) { |
| 147 | + //YAHOO.log("YAHOO.wikia.AjaxLogin.blockLoginForm was called with parameter which is not boolean", "error", "AjaxLogin.js"); |
| 148 | + return; |
| 149 | + } |
| 150 | + if( Dom.get('wpName1') ) |
| 151 | + Dom.get('wpName1').disabled = block; |
| 152 | + if( Dom.get('wpPassword1') ) |
| 153 | + Dom.get('wpPassword1').disabled = block; |
| 154 | + if( Dom.get('wpLoginattempt') ) |
| 155 | + Dom.get('wpLoginattempt').disabled = block; |
| 156 | + if( Dom.get('wpRemember') ) |
| 157 | + Dom.get('wpRemember').disabled = block; |
| 158 | + if( Dom.get('wpMailmypassword') ) |
| 159 | + Dom.get('wpMailmypassword').disabled = block; |
| 160 | + }, |
| 161 | + ajaxRegisterConfirm: function( e ) { |
| 162 | + if( Dom.get( 'wpPreview' ) && Dom.get( 'wpLogin' ) ) { |
| 163 | + if( typeof( ajaxLogin2 ) != 'undefined' && !confirm( ajaxLogin2 ) ) { |
| 164 | + YAHOO.util.Event.preventDefault( e ); |
| 165 | + } |
| 166 | + } |
| 167 | + } |
| 168 | + } |
| 169 | + |
| 170 | + Event.onDOMReady(YAHOO.wikia.AjaxLogin.init, YAHOO.wikia.AjaxLogin, true); |
| 171 | + |
| 172 | + })(); |
| 173 | +} |
\ No newline at end of file |
Property changes on: trunk/extensions/AjaxLogin/AjaxLogin.js |
___________________________________________________________________ |
Name: svn:eol-style |
1 | 174 | + native |
Index: trunk/extensions/AjaxLogin/YAHOOTools.js |
— | — | @@ -0,0 +1,663 @@ |
| 2 | +/* YAHOO.Tools JavaScript */ |
| 3 | +YAHOO.Tools = function(){ |
| 4 | + keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; |
| 5 | + regExs = { |
| 6 | + quotes:/\x22/g, |
| 7 | + startspace:/^\s+/g, |
| 8 | + endspace:/\s+$/g, |
| 9 | + striptags:/<\/?[^>]+>/gi, |
| 10 | + hasbr:/<br/i, |
| 11 | + hasp:/<p>/i, |
| 12 | + rbr:/<br>/gi, |
| 13 | + rbr2:/<br\/>/gi, |
| 14 | + rendp:/<\/p>/gi, |
| 15 | + rp:/<p>/gi, |
| 16 | + base64:/[^A-Za-z0-9\+\/\=]/g, |
| 17 | + syntaxCheck:/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/ |
| 18 | + } |
| 19 | + jsonCodes = { |
| 20 | + '\b':'\\b', |
| 21 | + '\t':'\\t', |
| 22 | + '\n':'\\n', |
| 23 | + '\f':'\\f', |
| 24 | + '\r':'\\r', |
| 25 | + '"':'\\"', |
| 26 | + '\\':'\\\\' |
| 27 | + } |
| 28 | + return { version:'1.0' } |
| 29 | +}(); |
| 30 | +YAHOO.Tools.getHeight = function(elm){ |
| 31 | + var elm = $(elm); |
| 32 | + var h = $D.getStyle(elm, 'height'); |
| 33 | + |
| 34 | + if( h== 'auto' ){ |
| 35 | + elm.style.zoom = 1; |
| 36 | + h = elm.clientHeight+'px'; |
| 37 | + } |
| 38 | + return h; |
| 39 | +} |
| 40 | +YAHOO.Tools.getCenter = function(elm){ |
| 41 | + var elm = $(elm); |
| 42 | + var cX = Math.round(($D.getViewportWidth()-parseInt($D.getStyle(elm,'width')))/2); |
| 43 | + var cY = Math.round(($D.getViewportHeight()-parseInt(this.getHeight(elm)))/2); |
| 44 | + return[cX,cY]; |
| 45 | +} |
| 46 | + |
| 47 | +YAHOO.Tools.makeTextObject = function(txt){ |
| 48 | + return document.createTextNode(txt); |
| 49 | +} |
| 50 | + |
| 51 | +YAHOO.Tools.makeChildren = function(arr, elm){ |
| 52 | + var elm = $(elm); |
| 53 | + |
| 54 | + for( var i in arr ){ |
| 55 | + _val = arr[i]; |
| 56 | + if( typeof _val == 'string' ){ |
| 57 | + _val = this.makeTxtObject(_val); |
| 58 | + } |
| 59 | + elm.appendChild(_val); |
| 60 | + } |
| 61 | +} |
| 62 | + |
| 63 | +YAHOO.Tools.styleToCamel = function(str){ |
| 64 | + var _tmp = str.split('-'); |
| 65 | + var _new_style = _tmp[0]; |
| 66 | + |
| 67 | + for( var i = 1; i < _tmp.length; i++ ){ |
| 68 | + _new_style+=_tmp[i].substring(0,1).toUpperCase()+_tmp[i].substring(1,_tmp[i].length); |
| 69 | + } |
| 70 | + return _new_style; |
| 71 | +} |
| 72 | + |
| 73 | +YAHOO.Tools.removeQuotes = function(str){ |
| 74 | + var checkText = new String(str); |
| 75 | + return String( checkText.replace( regExs.quotes, '' ) ); |
| 76 | +} |
| 77 | + |
| 78 | +YAHOO.Tools.trim = function(str){ |
| 79 | + return str.replace(regExs.startspace,'').replace(regExs.endspace,''); |
| 80 | +} |
| 81 | + |
| 82 | +YAHOO.Tools.stripTags = function(str){ |
| 83 | + return str.replace(regExs.striptags,''); |
| 84 | +} |
| 85 | + |
| 86 | +YAHOO.Tools.hasBRs = function(str){ |
| 87 | + return str.match(regExs.hasbr) || str.match(regExs.hasp); |
| 88 | +} |
| 89 | + |
| 90 | +YAHOO.Tools.convertBRs2NLs = function(str){ |
| 91 | + return str.replace(regExs.rbr,"\n").replace(regExs.rbr2,"\n").replace(regExs.rendp,"\n").replace(regExs.rp,""); |
| 92 | +} |
| 93 | + |
| 94 | +YAHOO.Tools.stringRepeat = function(str, repeat){ |
| 95 | + return new Array(repeat+1).join(str); |
| 96 | +} |
| 97 | + |
| 98 | +YAHOO.Tools.stringReverse = function(str){ |
| 99 | + var new_str = ''; |
| 100 | + for( i = 0; i < str.length; i++ ){ |
| 101 | + new_str = new_str+str.charAt((str.length-1)-i); |
| 102 | + } |
| 103 | + return new_str; |
| 104 | +} |
| 105 | + |
| 106 | +YAHOO.Tools.printf = function(){ |
| 107 | + var num = arguments.length; |
| 108 | + var oStr = arguments[0]; |
| 109 | + |
| 110 | + for( var i = 1; i < num; i++ ){ |
| 111 | + var pattern = "\\{"+(i-1)+"\\}"; |
| 112 | + var re = new RegExp(pattern,"g"); |
| 113 | + oStr = oStr.replace(re,arguments[i]); |
| 114 | + } |
| 115 | + return oStr; |
| 116 | +} |
| 117 | + |
| 118 | +YAHOO.Tools.setStyleString = function(el, str){ |
| 119 | + var _tmp = str.split(';'); |
| 120 | + for( x in _tmp ){ |
| 121 | + if( x ){ |
| 122 | + __tmp = YAHOO.Tools.trim(_tmp[x]); |
| 123 | + __tmp = _tmp[x].split(':'); |
| 124 | + if( __tmp[0] && __tmp[1] ){ |
| 125 | + var _attr = YAHOO.Tools.trim(__tmp[0]); |
| 126 | + var _val = YAHOO.Tools.trim(__tmp[1]); |
| 127 | + if( _attr && _val ){ |
| 128 | + if( _attr.indexOf('-')!=-1 ){ |
| 129 | + _attr = YAHOO.Tools.styleToCamel(_attr); |
| 130 | + } |
| 131 | + $D.setStyle(el, _attr, _val); |
| 132 | + } |
| 133 | + } |
| 134 | + } |
| 135 | + } |
| 136 | +} |
| 137 | + |
| 138 | +YAHOO.Tools.getSelection = function(_document, _window){ |
| 139 | + if( !_document ){ |
| 140 | + _document = document; |
| 141 | + } |
| 142 | + if( !_window ){ |
| 143 | + _window = window; |
| 144 | + } |
| 145 | + if( _document.selection ){ |
| 146 | + return _document.selection; |
| 147 | + } |
| 148 | + return _window.getSelection(); |
| 149 | +} |
| 150 | + |
| 151 | +YAHOO.Tools.removeElement = function(el){ |
| 152 | + if( !(el instanceof Array) ){ |
| 153 | + el = new Array($(el)); |
| 154 | + } |
| 155 | + |
| 156 | + for( var i = 0; i < el.length; i++ ){ |
| 157 | + if( el[i].parentNode ){ |
| 158 | + el[i].parentNode.removeChild(el); |
| 159 | + } |
| 160 | + } |
| 161 | +} |
| 162 | + |
| 163 | +YAHOO.Tools.setCookie = function(name, value, expires, path, domain, secure){ |
| 164 | + var argv = arguments; |
| 165 | + var argc = arguments.length; |
| 166 | + var expires = ( argc > 2 ) ? argv[2] : null; |
| 167 | + var path = ( argc > 3 ) ? argv[3] : '/'; |
| 168 | + var domain = ( argc > 4 ) ? argv[4] : null; |
| 169 | + var secure = ( argc > 5 ) ? argv[5] : false; |
| 170 | + |
| 171 | + document.cookie = name+"="+escape(value)+ ((expires==null)?"":("; expires="+expires.toGMTString()))+ ((path==null)?"":("; path="+path))+ ((domain==null)?"":("; domain="+domain))+ ((secure==true)?"; secure":""); |
| 172 | +} |
| 173 | + |
| 174 | +YAHOO.Tools.getCookie = function(name){ |
| 175 | + var dc = document.cookie; |
| 176 | + var prefix = name+'='; |
| 177 | + var begin = dc.indexOf('; '+prefix); |
| 178 | + |
| 179 | + if( begin == -1 ){ |
| 180 | + begin = dc.indexOf(prefix); |
| 181 | + if( begin != 0 ) |
| 182 | + return null; |
| 183 | + } else { |
| 184 | + begin+=2; |
| 185 | + } |
| 186 | + |
| 187 | + var end = document.cookie.indexOf(';',begin); |
| 188 | + if( end==-1 ){ |
| 189 | + end = dc.length; |
| 190 | + } |
| 191 | + return unescape(dc.substring(begin+prefix.length,end)); |
| 192 | +} |
| 193 | + |
| 194 | +YAHOO.Tools.deleteCookie = function(name, path, domain){ |
| 195 | + if( getCookie(name) ){ |
| 196 | + document.cookie = name+'='+((path)?'; path='+path:'')+((domain)?'; domain='+domain:'')+'; expires=Thu, 01-Jan-70 00:00:01 GMT'; |
| 197 | + } |
| 198 | +} |
| 199 | + |
| 200 | +YAHOO.Tools.getBrowserEngine = function(){ |
| 201 | + var opera = ( ( window.opera && window.opera.version ) ? true : false ); |
| 202 | + var safari= ( ( navigator.vendor && navigator.vendor.indexOf('Apple') != -1 ) ? true : false ); |
| 203 | + var gecko = ( ( document.getElementById && !document.all && !opera && !safari ) ? true : false ); |
| 204 | + var msie = ( ( window.ActiveXObject ) ? true : false); |
| 205 | + var version = false; |
| 206 | + |
| 207 | + if( msie ){ |
| 208 | + if( typeof document.body.style.maxHeight != "undefined" ){ |
| 209 | + version = '7'; |
| 210 | + } else { |
| 211 | + version = '6'; |
| 212 | + } |
| 213 | + } |
| 214 | + |
| 215 | + if( opera ){ |
| 216 | + var tmp_version = window.opera.version().split('.'); |
| 217 | + version = tmp_version[0]+'.'+tmp_version[1]; |
| 218 | + } |
| 219 | + |
| 220 | + if( gecko ){ |
| 221 | + if( navigator.registerContentHandler ){ |
| 222 | + version = '2'; |
| 223 | + } else { |
| 224 | + version = '1.5'; |
| 225 | + } |
| 226 | + if( (navigator.vendorSub) && !version ){ |
| 227 | + version = navigator.vendorSub; |
| 228 | + } |
| 229 | + } |
| 230 | + |
| 231 | + if( safari ){ |
| 232 | + try { |
| 233 | + if( console ){ |
| 234 | + if( (window.onmousewheel !== 'undefined') && (window.onmousewheel === null) ){ |
| 235 | + version = '2'; |
| 236 | + } else { |
| 237 | + version = '1.3'; |
| 238 | + } |
| 239 | + } |
| 240 | + } catch(e){ |
| 241 | + version = '1.2'; |
| 242 | + } |
| 243 | + } |
| 244 | + var browsers = { ua:navigator.userAgent, opera:opera, safari:safari, gecko:gecko, msie:msie, version:version } |
| 245 | + return browsers; |
| 246 | +} |
| 247 | + |
| 248 | +YAHOO.Tools.getBrowserAgent = function(){ |
| 249 | + var ua = navigator.userAgent.toLowerCase(); |
| 250 | + var opera = ( ( ua.indexOf('opera') != -1 ) ? true : false ); |
| 251 | + var safari = ( ( ua.indexOf('safari') != -1 ) ? true : false ); |
| 252 | + var firefox = ( ( ua.indexOf('firefox') != -1 ) ? true : false ); |
| 253 | + var msie = ( ( ua.indexOf('msie') != -1 ) ? true : false ); |
| 254 | + var mac = ( ( ua.indexOf('mac') != -1 ) ? true : false ); |
| 255 | + var unix = ( ( ua.indexOf('x11') != -1 ) ? true : false ); |
| 256 | + var win = ( ( mac || unix ) ? false : true ); |
| 257 | + var version = false; |
| 258 | + var mozilla = false; |
| 259 | + |
| 260 | + if( !firefox && !safari && ( ua.indexOf('gecko') != -1 ) ){ |
| 261 | + mozilla = true; |
| 262 | + var _tmp = ua.split('/'); |
| 263 | + version = _tmp[_tmp.length-1].split(' ')[0]; |
| 264 | + } |
| 265 | + |
| 266 | + if( firefox ){ |
| 267 | + var _tmp = ua.split('/'); |
| 268 | + version = _tmp[_tmp.length-1].split(' ')[0]; |
| 269 | + } |
| 270 | + |
| 271 | + if( msie ){ |
| 272 | + version = ua.substring((ua.indexOf('msie ')+5)).split(';')[0]; |
| 273 | + } |
| 274 | + |
| 275 | + if( safari ){ |
| 276 | + version = this.getBrowserEngine().version; |
| 277 | + } |
| 278 | + |
| 279 | + if( opera ){ |
| 280 | + version = ua.substring((ua.indexOf('opera/')+6)).split(' ')[0]; |
| 281 | + } |
| 282 | + |
| 283 | + var browsers = { ua:navigator.userAgent, opera:opera, safari:safari, firefox:firefox, mozilla:mozilla, msie:msie, mac:mac, win:win, unix:unix, version:version } |
| 284 | + return browsers; |
| 285 | +} |
| 286 | + |
| 287 | +YAHOO.Tools.checkFlash = function(){ |
| 288 | + var br = this.getBrowserEngine(); |
| 289 | + |
| 290 | + if( br.msie ){ |
| 291 | + try { |
| 292 | + var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7"); |
| 293 | + var versionStr = axo.GetVariable("$version"); |
| 294 | + var tempArray = versionStr.split(" "); |
| 295 | + var tempString = tempArray[1]; |
| 296 | + var versionArray = tempString.split(","); |
| 297 | + var flash = versionArray[0]; |
| 298 | + } catch(e) { |
| 299 | + } |
| 300 | + } else { |
| 301 | + var flashObj = null; |
| 302 | + var tokens, len, curr_tok; |
| 303 | + if( navigator.mimeTypes && navigator.mimeTypes['application/x-shockwave-flash'] ){ |
| 304 | + flashObj = navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin; |
| 305 | + } |
| 306 | + if( flashObj == null ){ |
| 307 | + flash = false; |
| 308 | + } else { |
| 309 | + tokens = navigator.plugins['Shockwave Flash'].description.split(' '); |
| 310 | + len = tokens.length; |
| 311 | + while( len-- ){ |
| 312 | + curr_tok = tokens[len]; |
| 313 | + if( !isNaN(parseInt(curr_tok) ) ){ |
| 314 | + hasVersion = curr_tok; |
| 315 | + flash = hasVersion; |
| 316 | + break; |
| 317 | + } |
| 318 | + } |
| 319 | + } |
| 320 | + } |
| 321 | + return flash; |
| 322 | +} |
| 323 | + |
| 324 | +YAHOO.Tools.setAttr = function(attrsObj, elm){ |
| 325 | + if( typeof elm == 'string' ){ |
| 326 | + elm = $(elm); |
| 327 | + } |
| 328 | + for( var i in attrsObj ){ |
| 329 | + switch( i.toLowerCase() ){ |
| 330 | + case 'listener': |
| 331 | + if( attrsObj[i] instanceof Array ){ |
| 332 | + var ev = attrsObj[i][0]; |
| 333 | + var func = attrsObj[i][1]; |
| 334 | + var base = attrsObj[i][2]; |
| 335 | + var scope = attrsObj[i][3]; |
| 336 | + $E.addListener(elm, ev, func, base, scope); |
| 337 | + } |
| 338 | + break; |
| 339 | + case 'classname': |
| 340 | + case 'class': |
| 341 | + elm.className = attrsObj[i]; |
| 342 | + break; |
| 343 | + case 'style': |
| 344 | + YAHOO.Tools.setStyleString(elm, attrsObj[i]); |
| 345 | + break; |
| 346 | + default: |
| 347 | + elm.setAttribute(i, attrsObj[i]); |
| 348 | + break; |
| 349 | + } |
| 350 | + } |
| 351 | +} |
| 352 | + |
| 353 | +YAHOO.Tools.create = function(tagName){ |
| 354 | + tagName = tagName.toLowerCase(); |
| 355 | + elm = document.createElement(tagName); |
| 356 | + var txt = false; |
| 357 | + var attrsObj = false; |
| 358 | + |
| 359 | + if( !elm ){ |
| 360 | + return false; |
| 361 | + } |
| 362 | + |
| 363 | + for( var i = 1; i < arguments.length; i++ ){ |
| 364 | + txt = arguments[i]; |
| 365 | + if( typeof txt == 'string' ){ |
| 366 | + _txt = YAHOO.Tools.makeTextObject(txt); |
| 367 | + elm.appendChild(_txt); |
| 368 | + } else if( txt instanceof Array ){ |
| 369 | + YAHOO.Tools.makeChildren(txt, elm); |
| 370 | + } else if( typeof txt == 'object' ){ |
| 371 | + YAHOO.Tools.setAttr(txt, elm); |
| 372 | + } |
| 373 | + } |
| 374 | + return elm; |
| 375 | +} |
| 376 | + |
| 377 | +YAHOO.Tools.insertAfter = function(elm, curNode){ |
| 378 | + if( curNode.nextSibling ){ |
| 379 | + curNode.parentNode.insertBefore(elm, curNode.nextSibling); |
| 380 | + } else { |
| 381 | + curNode.parentNode.appendChild(elm); |
| 382 | + } |
| 383 | +} |
| 384 | + |
| 385 | +YAHOO.Tools.inArray = function(arr, val){ |
| 386 | + if( arr instanceof Array ){ |
| 387 | + for( var i = (arr.length-1); i>=0;i-- ){ |
| 388 | + if( arr[i] === val ){ |
| 389 | + return true; |
| 390 | + } |
| 391 | + } |
| 392 | + } |
| 393 | + return false; |
| 394 | +} |
| 395 | + |
| 396 | +YAHOO.Tools.checkBoolean = function(str){ |
| 397 | + return ( ( typeof str == 'boolean' ) ? true : false ); |
| 398 | +} |
| 399 | + |
| 400 | +YAHOO.Tools.checkNumber = function(str){ |
| 401 | + return ( ( isNaN(str) ) ? false : true ); |
| 402 | +} |
| 403 | + |
| 404 | +YAHOO.Tools.PixelToEm = function(size){ |
| 405 | + var data = {}; |
| 406 | + var sSize = (size/13); |
| 407 | + |
| 408 | + data.other = (Math.round(sSize*100)/100); |
| 409 | + data.msie = (Math.round((sSize*0.9759)*100)/100); |
| 410 | + return data; |
| 411 | +} |
| 412 | + |
| 413 | +YAHOO.Tools.PixelToEmStyle = function(size, prop){ |
| 414 | + var data = ''; |
| 415 | + var prop = ( ( prop ) ? prop.toLowerCase() : 'width' ); |
| 416 | + var sSize = (size/13); |
| 417 | + |
| 418 | + data+= prop+':'+(Math.round(sSize*100)/100)+'em;'; |
| 419 | + data+= '*'+prop+':'+(Math.round((sSize*0.9759)*100)/100)+'em;'; |
| 420 | + if( ( prop == 'width' ) || ( prop == 'height' ) ){ |
| 421 | + data+='min-'+prop+':'+size+'px;'; |
| 422 | + } |
| 423 | + return data; |
| 424 | +} |
| 425 | + |
| 426 | +YAHOO.Tools.base64Encode = function(str){ |
| 427 | + var data = ""; |
| 428 | + var chr1, chr2, chr3, enc1, enc2, enc3, enc4; |
| 429 | + var i = 0; |
| 430 | + do { |
| 431 | + chr1 = str.charCodeAt(i++); |
| 432 | + chr2 = str.charCodeAt(i++); |
| 433 | + chr3 = str.charCodeAt(i++); |
| 434 | + enc1 = chr1>>2; |
| 435 | + enc2 = ( ( chr1 & 3 ) << 4 ) | ( chr2 >> 4 ); |
| 436 | + enc3 = ( ( chr2 & 15 ) << 2 ) | ( chr3 >> 6 ); |
| 437 | + enc4 = chr3 & 63; |
| 438 | + if( isNaN(chr2) ){ |
| 439 | + enc3 = enc4 = 64; |
| 440 | + } else if( isNaN(chr3) ){ |
| 441 | + enc4 = 64; |
| 442 | + } |
| 443 | + data = data+keyStr.charAt(enc1)+keyStr.charAt(enc2)+keyStr.charAt(enc3)+keyStr.charAt(enc4); |
| 444 | + } |
| 445 | + while( i < str.length ); |
| 446 | + return data; |
| 447 | +} |
| 448 | + |
| 449 | +YAHOO.Tools.base64Decode = function(str){ |
| 450 | + var data = ""; |
| 451 | + var chr1, chr2, chr3, enc1, enc2, enc3, enc4; |
| 452 | + var i = 0; |
| 453 | + str = str.replace(regExs.base64,""); |
| 454 | + |
| 455 | + do { |
| 456 | + enc1 = keyStr.indexOf(str.charAt(i++)); |
| 457 | + enc2 = keyStr.indexOf(str.charAt(i++)); |
| 458 | + enc3 = keyStr.indexOf(str.charAt(i++)); |
| 459 | + enc4 = keyStr.indexOf(str.charAt(i++)); |
| 460 | + chr1 = ( enc1 << 2 ) | ( enc2 >> 4 ); |
| 461 | + chr2 = ( ( enc2 & 15 ) << 4 ) | ( enc3 >> 2); |
| 462 | + chr3 = ( ( enc3 & 3 ) << 6 ) | enc4; |
| 463 | + data = data+String.fromCharCode(chr1); |
| 464 | + if( enc3 != 64 ){ |
| 465 | + data = data+String.fromCharCode(chr2); |
| 466 | + } |
| 467 | + if( enc4 != 64 ){ |
| 468 | + data = data+String.fromCharCode(chr3); |
| 469 | + } |
| 470 | + } |
| 471 | + while( i < str.length ); |
| 472 | + return data; |
| 473 | +} |
| 474 | + |
| 475 | +YAHOO.Tools.getQueryString = function(str){ |
| 476 | + var qstr = {}; |
| 477 | + if( !str ){ |
| 478 | + var str = location.href.split('?'); |
| 479 | + if( str.length != 2 ){ |
| 480 | + str = ['', location.href]; |
| 481 | + } |
| 482 | + } else { |
| 483 | + var str = ['', str]; |
| 484 | + } |
| 485 | + if( str[1].match('#') ){ |
| 486 | + var _tmp = str[1].split('#'); |
| 487 | + qstr.hash = _tmp[1]; |
| 488 | + str[1] = _tmp[0]; |
| 489 | + } |
| 490 | + if( str[1] ){ |
| 491 | + str = str[1].split('&'); |
| 492 | + if( str.length ){ |
| 493 | + for( var i = 0; i < str.length; i++ ){ |
| 494 | + var part = str[i].split('='); |
| 495 | + if( part[0].indexOf('[') != -1 ){ |
| 496 | + if( part[0].indexOf('[]') != -1 ){ |
| 497 | + var arr = part[0].substring(0,part[0].length-2); |
| 498 | + if( !qstr[arr] ){ |
| 499 | + qstr[arr] = []; |
| 500 | + } |
| 501 | + qstr[arr][qstr[arr].length] = part[1]; |
| 502 | + } else { |
| 503 | + var arr = part[0].substring(0,part[0].indexOf('[')); |
| 504 | + var data = part[0].substring((part[0].indexOf('[')+1),part[0].indexOf(']')); |
| 505 | + if( !qstr[arr] ){ |
| 506 | + qstr[arr] = {}; |
| 507 | + } |
| 508 | + qstr[arr][data] = part[1]; |
| 509 | + } |
| 510 | + } else { |
| 511 | + qstr[part[0]] = part[1]; |
| 512 | + } |
| 513 | + } |
| 514 | + } |
| 515 | + } |
| 516 | + return qstr; |
| 517 | +} |
| 518 | + |
| 519 | +YAHOO.Tools.getQueryStringVar = function(str){ |
| 520 | + var qs = this.getQueryString(); |
| 521 | + if( qs[str] ){ |
| 522 | + return qs[str]; |
| 523 | + } else { |
| 524 | + return false; |
| 525 | + } |
| 526 | +} |
| 527 | + |
| 528 | +YAHOO.Tools.padDate = function(n){ |
| 529 | + return n < 10 ? '0'+n : n; |
| 530 | +} |
| 531 | + |
| 532 | +YAHOO.Tools.encodeStr = function(str){ |
| 533 | + if( /["\\\x00-\x1f]/.test(str) ){ |
| 534 | + return '"' + str.replace( /([\x00-\x1f\\"])/g, |
| 535 | + function(a, b){ |
| 536 | + var c = jsonCodes[b]; |
| 537 | + if( c ){ |
| 538 | + return c; |
| 539 | + } |
| 540 | + c = b.charCodeAt(); |
| 541 | + return '\\u00' + Math.floor(c/16).toString(16) + (c%16).toString(16); |
| 542 | + } |
| 543 | + ) + '"'; |
| 544 | + } |
| 545 | + return'"'+str+'"'; |
| 546 | +} |
| 547 | + |
| 548 | +YAHOO.Tools.encodeArr = function(arr){ |
| 549 | + var a = ['['], b, i, l = arr.length, v; |
| 550 | + for( i = 0; i < l; i+= 1 ){ |
| 551 | + v = arr[i]; |
| 552 | + switch( typeof v ){ |
| 553 | + case 'undefined': |
| 554 | + case 'function': |
| 555 | + case 'unknown': |
| 556 | + break; |
| 557 | + default: |
| 558 | + if( b ){ |
| 559 | + a.push(','); |
| 560 | + } |
| 561 | + a.push( v === null ? "null" : YAHOO.Tools.JSONEncode(v) ); |
| 562 | + b = true; |
| 563 | + } |
| 564 | + } |
| 565 | + a.push(']'); |
| 566 | + return a.join(''); |
| 567 | +} |
| 568 | + |
| 569 | +YAHOO.Tools.encodeDate = function(d){ |
| 570 | + return '"'+d.getFullYear()+'-'+YAHOO.Tools.padDate(d.getMonth()+1)+'-'+YAHOO.Tools.padDate(d.getDate())+'T'+YAHOO.Tools.padDate(d.getHours())+':'+YAHOO.Tools.padDate(d.getMinutes())+':'+YAHOO.Tools.padDate(d.getSeconds())+'"'; |
| 571 | +} |
| 572 | + |
| 573 | +YAHOO.Tools.fixJSONDate = function(dateStr){ |
| 574 | + var tmp = dateStr.split('T'); |
| 575 | + var fixedDate = dateStr; |
| 576 | + |
| 577 | + if( tmp.length == 2 ){ |
| 578 | + var tmpDate = tmp[0].split('-'); |
| 579 | + if( tmpDate.length == 3 ){ |
| 580 | + fixedDate = new Date(tmpDate[0], (tmpDate[1]-1), tmpDate[2]); |
| 581 | + var tmpTime = tmp[1].split(':'); |
| 582 | + if( tmpTime.length == 3 ){ |
| 583 | + fixedDate.setHours(tmpTime[0], tmpTime[1], tmpTime[2]); |
| 584 | + } |
| 585 | + } |
| 586 | + } |
| 587 | + return fixedDate; |
| 588 | +} |
| 589 | + |
| 590 | +YAHOO.Tools.JSONEncode = function(o){ |
| 591 | + if( ( typeof o == 'undefined' ) || ( o === null ) ){ |
| 592 | + return 'null'; |
| 593 | + } else if( o instanceof Array ){ |
| 594 | + return YAHOO.Tools.encodeArr(o); |
| 595 | + } else if( o instanceof Date ){ |
| 596 | + return YAHOO.Tools.encodeDate(o); |
| 597 | + } else if( typeof o == 'string' ){ |
| 598 | + return YAHOO.Tools.encodeStr(o); |
| 599 | + } else if( typeof o == 'number' ){ |
| 600 | + return isFinite(o) ? String(o) : "null"; |
| 601 | + } else if( typeof o == 'boolean' ){ |
| 602 | + return String(o); |
| 603 | + } else { |
| 604 | + var a = ['{'],b,i,v; |
| 605 | + for( var i in o ){ |
| 606 | + v = o[i]; |
| 607 | + switch( typeof v ){ |
| 608 | + case 'undefined': |
| 609 | + case 'function': |
| 610 | + case 'unknown': |
| 611 | + break; |
| 612 | + default: |
| 613 | + if( b ){ |
| 614 | + a.push(','); |
| 615 | + } |
| 616 | + a.push(YAHOO.Tools.JSONEncode(i),':',( ( v === null ) ? "null" : YAHOO.Tools.JSONEncode(v) ) ); |
| 617 | + b = true; |
| 618 | + } |
| 619 | + } |
| 620 | + a.push('}'); |
| 621 | + return a.join(''); |
| 622 | + } |
| 623 | +} |
| 624 | + |
| 625 | +YAHOO.Tools.JSONParse = function(json, autoDate){ |
| 626 | + var autoDate = ( ( autoDate ) ? true : false ); |
| 627 | + |
| 628 | + try { |
| 629 | + if( regExs.syntaxCheck.test(json) ){ |
| 630 | + var j = eval('('+json+')'); |
| 631 | + if(autoDate){ |
| 632 | + function walk(k, v){ |
| 633 | + if( v && typeof v === 'object' ){ |
| 634 | + for( var i in v ){ |
| 635 | + if( v.hasOwnProperty(i) ){ |
| 636 | + v[i] = walk(i,v[i]); |
| 637 | + } |
| 638 | + } |
| 639 | + } |
| 640 | + if( k.toLowerCase().indexOf('date')>=0 ){ |
| 641 | + return YAHOO.Tools.fixJSONDate(v); |
| 642 | + } else { |
| 643 | + return v; |
| 644 | + } |
| 645 | + } |
| 646 | + return walk('',j); |
| 647 | + } else { |
| 648 | + return j; |
| 649 | + } |
| 650 | + } |
| 651 | + } catch(e){ |
| 652 | + console.log(e); |
| 653 | + } |
| 654 | + throw new SyntaxError("parseJSON"); |
| 655 | +} |
| 656 | +YAHOO.tools = YAHOO.Tools; |
| 657 | +YAHOO.TOOLS = YAHOO.Tools; |
| 658 | +YAHOO.util.Dom.create = YAHOO.Tools.create; |
| 659 | +$A = YAHOO.util.Anim; |
| 660 | +$E = YAHOO.util.Event; |
| 661 | +$D = YAHOO.util.Dom; |
| 662 | +$T = YAHOO.Tools; |
| 663 | +$ = YAHOO.util.Dom.get; |
| 664 | +$$ = YAHOO.util.Dom.getElementsByClassName; |
\ No newline at end of file |
Property changes on: trunk/extensions/AjaxLogin/YAHOOTools.js |
___________________________________________________________________ |
Name: svn:eol-style |
1 | 665 | + native |
Index: trunk/extensions/AjaxLogin/ApiAjaxLogin.php |
— | — | @@ -0,0 +1,145 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * API module for AjaxLogin extension |
| 5 | + * |
| 6 | + * @file |
| 7 | + * @ingroup API |
| 8 | + * @author Inez Korczyński <korczynski@gmail.com> |
| 9 | + */ |
| 10 | + |
| 11 | +if( !defined( 'MEDIAWIKI' ) ) { |
| 12 | + die( "This is not a valid entry point.\n" ); |
| 13 | +} |
| 14 | + |
| 15 | +class ApiAjaxLogin extends ApiBase { |
| 16 | + |
| 17 | + public function __construct( $main, $action ) { |
| 18 | + parent::__construct( $main, $action, 'wp' ); |
| 19 | + } |
| 20 | + |
| 21 | + public function execute() { |
| 22 | + $Name = $Password = $Remember = $Loginattempt = $Mailmypassword = null; |
| 23 | + extract( $this->extractRequestParams() ); |
| 24 | + |
| 25 | + if( !empty( $Loginattempt ) ) { |
| 26 | + // Login attempt |
| 27 | + $params = new FauxRequest( |
| 28 | + array( |
| 29 | + 'wpName' => $Name, |
| 30 | + 'wpPassword' => $Password, |
| 31 | + 'wpRemember' => $Remember, |
| 32 | + 'wpLoginattempt' => $Loginattempt |
| 33 | + ) |
| 34 | + ); |
| 35 | + |
| 36 | + $result = array(); |
| 37 | + $loginForm = new LoginForm( $params ); |
| 38 | + switch( $loginForm->authenticateUserData() ) { |
| 39 | + case LoginForm::RESET_PASS: |
| 40 | + $result['result'] = 'Reset'; |
| 41 | + break; |
| 42 | + case LoginForm::SUCCESS: |
| 43 | + global $wgUser; |
| 44 | + |
| 45 | + $wgUser->setOption( 'rememberpassword', $Remember ? 1 : 0 ); |
| 46 | + $wgUser->setCookies(); |
| 47 | + |
| 48 | + $result['result'] = 'Success'; |
| 49 | + $result['lguserid'] = $_SESSION['wsUserID']; |
| 50 | + $result['lgusername'] = $_SESSION['wsUserName']; |
| 51 | + $result['lgtoken'] = $_SESSION['wsToken']; |
| 52 | + break; |
| 53 | + case LoginForm::NO_NAME: |
| 54 | + $result['result'] = 'NoName'; |
| 55 | + $result['text'] = wfMsg( 'noname' ); |
| 56 | + break; |
| 57 | + case LoginForm::ILLEGAL: |
| 58 | + $result['result'] = 'Illegal'; |
| 59 | + $result['text'] = wfMsg( 'noname' ); |
| 60 | + break; |
| 61 | + case LoginForm::WRONG_PLUGIN_PASS: |
| 62 | + $result['result'] = 'WrongPluginPass'; |
| 63 | + $result['text'] = wfMsg( 'wrongpassword' ); |
| 64 | + break; |
| 65 | + case LoginForm::NOT_EXISTS: |
| 66 | + $result['result'] = 'NotExists'; |
| 67 | + $result['text'] = wfMsg( 'nosuchuser', htmlspecialchars( $Name ) ); |
| 68 | + break; |
| 69 | + case LoginForm::WRONG_PASS: |
| 70 | + $result['result'] = 'WrongPass'; |
| 71 | + $result['text'] = wfMsg( 'wrongpassword' ); |
| 72 | + break; |
| 73 | + case LoginForm::EMPTY_PASS: |
| 74 | + $result['result'] = 'EmptyPass'; |
| 75 | + $result['text'] = wfMsg( 'wrongpasswordempty' ); |
| 76 | + break; |
| 77 | + default: |
| 78 | + ApiBase::dieDebug( __METHOD__, 'Unhandled case value' ); |
| 79 | + } |
| 80 | + $dbw = wfGetDB( DB_MASTER ); |
| 81 | + $dbw->commit(); |
| 82 | + |
| 83 | + $this->getResult()->addValue( null, 'ajaxlogin', $result ); |
| 84 | + } else if( !empty( $Mailmypassword ) ) { |
| 85 | + // Remind password attempt |
| 86 | + $params = new FauxRequest( |
| 87 | + array( |
| 88 | + 'wpName' => $Name |
| 89 | + ) |
| 90 | + ); |
| 91 | + $result = array(); |
| 92 | + $loginForm = new LoginForm( $params ); |
| 93 | + global $wgUser, $wgOut, $wgAuth; |
| 94 | + if( !$wgAuth->allowPasswordChange() ) { |
| 95 | + $result['result'] = 'resetpass_forbidden'; |
| 96 | + $result['text'] = wfMsg( 'resetpass_forbidden' ); |
| 97 | + } else if( $wgUser->isBlocked() ) { |
| 98 | + $result['result'] = 'blocked-mailpassword'; |
| 99 | + $result['text'] = wfMsg( 'blocked-mailpassword' ); |
| 100 | + } else if ( '' == $loginForm->mName ) { |
| 101 | + $result['result'] = 'noname'; |
| 102 | + $result['text'] = wfMsg( 'noname' ); |
| 103 | + } else { |
| 104 | + $u = User::newFromName( $loginForm->mName ); |
| 105 | + if( is_null( $u ) ) { |
| 106 | + $result['result'] = 'noname'; |
| 107 | + $result['text'] = wfMsg( 'noname' ); |
| 108 | + } else if ( 0 == $u->getID() ) { |
| 109 | + $result['result'] = 'nosuchuser'; |
| 110 | + $result['text'] = wfMsg( 'nosuchuser', $u->getName() ); |
| 111 | + } else if ( $u->isPasswordReminderThrottled() ) { |
| 112 | + global $wgPasswordReminderResendTime; |
| 113 | + $result['result'] = 'throttled-mailpassword'; |
| 114 | + $result['text'] = wfMsg( 'throttled-mailpassword', round( $wgPasswordReminderResendTime, 3 ) ); |
| 115 | + } else { |
| 116 | + $res = $loginForm->mailPasswordInternal( $u, true ); |
| 117 | + if( WikiError::isError( $res ) ) { |
| 118 | + $result['result'] = 'mailerror'; |
| 119 | + $result['text'] = wfMsg( 'mailerror', $res->getMessage() ); |
| 120 | + } else { |
| 121 | + $result['result'] = 'OK'; |
| 122 | + $result['text'] = wfMsg( 'passwordsent', $u->getName() ); |
| 123 | + } |
| 124 | + } |
| 125 | + } |
| 126 | + $dbw = wfGetDB( DB_MASTER ); |
| 127 | + $dbw->commit(); |
| 128 | + |
| 129 | + $this->getResult()->addValue( null, 'ajaxlogin', $result ); |
| 130 | + } |
| 131 | + } |
| 132 | + |
| 133 | + public function getAllowedParams() { |
| 134 | + return array( |
| 135 | + 'Name' => null, |
| 136 | + 'Password' => null, |
| 137 | + 'Remember' => null, |
| 138 | + 'Loginattempt' => null, |
| 139 | + 'Mailmypassword' => null |
| 140 | + ); |
| 141 | + } |
| 142 | + |
| 143 | + public function getVersion() { |
| 144 | + return __CLASS__ . ': $Id: ApiLogin.php 17065 2006-10-17 02:11:29Z yurik $'; |
| 145 | + } |
| 146 | +} |
\ No newline at end of file |
Property changes on: trunk/extensions/AjaxLogin/ApiAjaxLogin.php |
___________________________________________________________________ |
Name: svn:eol-style |
1 | 147 | + native |
Index: trunk/extensions/AjaxLogin/README |
— | — | @@ -0,0 +1,38 @@ |
| 2 | +This is the readme file for AjaxLogin extension. |
| 3 | +The newest documentation for this extension can always be found at |
| 4 | +<http://www.mediawiki.org/wiki/Extension:AjaxLogin>. |
| 5 | + |
| 6 | +==History== |
| 7 | +AjaxLogin was written by Inez Korczyński <korczynski(at)gmail(dot)com> for Wikia, Inc. |
| 8 | + |
| 9 | +Some code hacks were written by Jack Phoenix <jack@countervandalism.net>. |
| 10 | + |
| 11 | +==License== |
| 12 | +GNU General Public License 2.0 or later |
| 13 | + |
| 14 | +==Dependency== |
| 15 | +Yahoo! User Interface Library (YUI); see function AjaxLoginJS in AjaxLogin.php. |
| 16 | +AjaxLogin calls two YUI .js files which are hosted on Yahoo!'s servers, two YUI .css files, which also are hosted |
| 17 | +on Yahoo!'s servers, two of its own .js files and its only .css file. |
| 18 | + |
| 19 | +Please note that AjaxLogin does not work with YUI 2.7.0, hence why it's using 2.6.0's JS files rather than using 2.7.0. |
| 20 | + |
| 21 | +==Manual modifications== |
| 22 | +You will need to modify one core MediaWiki file, includes/EditPage.php, if you want users to be able to log in with AjaxLogin |
| 23 | +on edit view (?action=edit) without losing their changes. |
| 24 | + |
| 25 | +Find protected function showFormBeforeText() and add this line inside the $wgOut->addHTML() call so that it'll be the first <input> to be added: |
| 26 | + |
| 27 | + <input type='hidden' value=\"\" name=\"wpLogin\" id=\"wpLogin\" /> |
| 28 | + |
| 29 | +==To-do & bugs== |
| 30 | +This extension is right now a major hack. It requires YUI and isn't pretty in any case, |
| 31 | +but it works and has been tested on MediaWiki 1.14alpha. |
| 32 | + |
| 33 | +The JavaScript file should be rewritten so that the YUI dependency could be removed. |
| 34 | +Obviously YAHOOTools.js should also be killed in the process. |
| 35 | + |
| 36 | +Patches are more than welcome and they can be submitted either through Bugzilla <https://bugzilla.wikimedia.org> or emailed to me |
| 37 | +<jack@countervandalism.net> directly. |
| 38 | + |
| 39 | +--Jack Phoenix, February 2009 |
\ No newline at end of file |
Property changes on: trunk/extensions/AjaxLogin/README |
___________________________________________________________________ |
Name: svn:eol-style |
1 | 40 | + native |