r100762 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r100761‎ | r100762 | r100763 >
Date:23:43, 25 October 2011
Author:preilly
Status:ok
Tags:
Comment:
Modified paths:
  • /branches/wmf/1.18wmf1/extensions/MobileFrontend/MobileFrontend.php (modified) (history)
  • /branches/wmf/1.18wmf1/extensions/MobileFrontend/javascripts/application.js (modified) (history)
  • /branches/wmf/1.18wmf1/extensions/MobileFrontend/javascripts/opensearch.js (added) (history)
  • /branches/wmf/1.18wmf1/extensions/MobileFrontend/stylesheets/common.css (modified) (history)
  • /branches/wmf/1.18wmf1/extensions/MobileFrontend/views/layout/_search_webkit.html.php (modified) (history)
  • /branches/wmf/1.18wmf1/extensions/MobileFrontend/views/layout/application.html.php (modified) (history)

Diff [purge]

Index: branches/wmf/1.18wmf1/extensions/MobileFrontend/javascripts/opensearch.js
@@ -0,0 +1,77 @@
 2+var apiUrl = '/api.php';
 3+
 4+if ( scriptPath ) {
 5+ apiUrl = scriptPath + apiUrl;
 6+}
 7+
 8+var timer = -1;
 9+var typingDelay = 500;
 10+var numResults = 10;
 11+var pixels = 'px';
 12+
 13+var results = document.getElementById( 'results' );
 14+var search = document.getElementById( 'search' );
 15+var sq = document.getElementById( 'sq' );
 16+
 17+results.style.width = ( sq.offsetWidth - 2 ) + pixels;
 18+results.style.left = sq.offsetLeft + pixels;
 19+results.style.top = ( sq.offsetTop + sq.offsetHeight ) + pixels;
 20+
 21+window.onload = function () {
 22+ search.addEventListener( 'keyup',
 23+ function() {
 24+ clearTimeout( timer );
 25+ var term = this.value;
 26+ if ( term.length < 1 ) {
 27+ results.innerHTML = '';
 28+ } else {
 29+ timer = setTimeout( function () { searchApi( term ); }, typingDelay );
 30+ }
 31+ }, false );
 32+}
 33+
 34+function searchApi( term ) {
 35+ var xmlHttp;
 36+ if ( window.XMLHttpRequest ) {
 37+ xmlHttp = new XMLHttpRequest();
 38+ } else {
 39+ xmlHttp = new ActiveXObject( 'Microsoft.XMLHTTP' );
 40+ }
 41+ xmlHttp.onreadystatechange = function() {
 42+ if ( xmlHttp.readyState == 4 && xmlHttp.status == 200 ) {
 43+ var sections = createObjectArray( xmlHttp.responseXML );
 44+ writeResults( sections );
 45+ }
 46+ }
 47+ var url = apiUrl + '?action=opensearch&limit=' + numResults + '&namespace=0&format=xml&search=' + term;
 48+ xmlHttp.open( 'GET', url, true );
 49+ xmlHttp.send();
 50+}
 51+
 52+function createObjectArray( responseXml ) {
 53+ var sections = new Array();
 54+ var items = responseXml.getElementsByTagName( 'Item' );
 55+ for ( i = 0; i < items.length; i++ ) {
 56+ var item = items[i];
 57+ var section = {
 58+ label: item.getElementsByTagName( 'Text' )[0].textContent,
 59+ value: item.getElementsByTagName( 'Url' )[0].textContent,
 60+ }
 61+ sections.push( section );
 62+ }
 63+ return sections;
 64+}
 65+
 66+function writeResults( sections ) {
 67+ results.style.display = 'block';
 68+ if ( !sections || sections.length < 1 ) {
 69+ results.innerHTML = "No results";
 70+ } else {
 71+ var html = '';
 72+ for ( i = 0; i < sections.length; i++ ) {
 73+ var section = sections[i];
 74+ html = html + "<a href='" + section.value + "'>" + section.label + "</a><br/>";
 75+ }
 76+ results.innerHTML = html;
 77+ }
 78+}
\ No newline at end of file
Property changes on: branches/wmf/1.18wmf1/extensions/MobileFrontend/javascripts/opensearch.js
___________________________________________________________________
Added: svn:eol-style
179 + native
Index: branches/wmf/1.18wmf1/extensions/MobileFrontend/javascripts/application.js
@@ -1,5 +1,7 @@
22 var search = document.getElementById( 'search' );
33 var clearSearch = document.getElementById( 'clearsearch' );
 4+var results = document.getElementById( 'results' );
 5+var languageSelection = document.getElementById( 'languageselection' );
46
57 initClearSearchLink();
68
@@ -9,12 +11,25 @@
1012 search.addEventListener( 'keyup', _handleClearSearchLink, false );
1113 }
1214
 15+function navigateToLanguageSelection() {
 16+ var url;
 17+ if ( languageSelection ) {
 18+ url = languageSelection.options[languageSelection.selectedIndex].value;
 19+ if ( url ) {
 20+ location.href = url;
 21+ }
 22+ }
 23+}
 24+
1325 function _handleClearSearchLink() {
1426 if ( clearSearch ) {
1527 if ( search.value.length > 0 ) {
1628 clearSearch.style.display = 'block';
1729 } else {
1830 clearSearch.style.display = 'none';
 31+ if ( results ) {
 32+ results.style.display = 'none';
 33+ }
1934 }
2035 }
2136 }
@@ -22,6 +37,9 @@
2338 function clearSearchBox( event ) {
2439 search.value = '';
2540 clearSearch.style.display = 'none';
 41+ if ( results ) {
 42+ results.style.display = 'none';
 43+ }
2644 if ( event ) {
2745 event.preventDefault();
2846 }
@@ -33,6 +51,14 @@
3452 document.getElementById( 'logo' ).onclick = function() {
3553 var n = document.getElementById( 'nav' ).style;
3654 n.display = n.display == 'block' ? 'none' : 'block';
 55+ if (n.display == 'block') {
 56+ if ( languageSelection ) {
 57+ if ( languageSelection.offsetWidth > 175 ) {
 58+ var newWidth = languageSelection.offsetWidth + 30;
 59+ n.width = newWidth + 'px';
 60+ }
 61+ }
 62+ }
3763 };
3864
3965 // Also problematic, not working until the page loads...
Index: branches/wmf/1.18wmf1/extensions/MobileFrontend/stylesheets/common.css
@@ -15,6 +15,17 @@
1616 display: none;
1717 }
1818
 19+#results {
 20+ display: none;
 21+ background-color: #ffffff;
 22+ border-top: none;
 23+ border-left: 1px solid #888;
 24+ border-right: 1px solid #888;
 25+ border-bottom: 1px solid #888;
 26+ z-index: 2;
 27+ position: absolute;
 28+}
 29+
1930 #search {
2031 -webkit-appearance: none;
2132 border-top-width: 0px;
Index: branches/wmf/1.18wmf1/extensions/MobileFrontend/MobileFrontend.php
@@ -82,20 +82,17 @@
8383 * @return bool
8484 */
8585 function efExtMobileFrontendUnitTests( &$files ) {
86 - $files[] = dirname( __FILE__ ) . '/tests/MobileFrontendTest.php';
87 - return true;
 86+ $files[] = dirname( __FILE__ ) . '/tests/MobileFrontendTest.php';
 87+ return true;
8888 }
8989
9090 class ExtMobileFrontend {
91 - const VERSION = '0.5.77';
 91+ const VERSION = '0.5.78';
9292
9393 /**
9494 * @var DOMDocument
9595 */
9696 private $doc, $mainPage;
97 -
98 - public static $messages = array();
99 -
10097 public $contentFormat = '';
10198 public $WMLSectionSeperator = '***************************************************************************';
10299
@@ -103,6 +100,7 @@
104101 * @var Title
105102 */
106103 public static $title;
 104+ public static $messages = array();
107105 public static $htmlTitle;
108106 public static $dir;
109107 public static $code;
@@ -129,6 +127,7 @@
130128 public static $mobileRedirectFormAction;
131129 public static $isBetaGroupMember = false;
132130 public static $hideSearchBox = false;
 131+ public static $languageUrls;
133132
134133 public static $messageKeys = array(
135134 'mobile-frontend-show-button',
@@ -169,6 +168,7 @@
170169 'mobile-frontend-feedback-page',
171170 'mobile-frontend-leave-feedback-thanks',
172171 'mobile-frontend-search-submit',
 172+ 'mobile-frontend-language',
173173 );
174174
175175 public $itemsToRemove = array(
@@ -254,7 +254,7 @@
255255 }
256256 $fragmentDelimiter = ( !empty( $parsedUrl['fragment'] ) ) ? '#' : '';
257257 $queryDelimiter = ( !empty( $parsedUrl['query'] ) ) ? '?' : '';
258 - $targetUrl = $parsedUrl['scheme'] . '://' . $parsedUrl['host'] . $parsedUrl['path'] . $queryDelimiter . $parsedUrl['query'] . $fragmentDelimiter . $parsedUrl['fragment'];
 258+ $targetUrl = $parsedUrl['scheme'] . '://' . $parsedUrl['host'] . $parsedUrl['path'] . $queryDelimiter . $parsedUrl['query'] . $fragmentDelimiter . $parsedUrl['fragment'];
259259 $output->setSquidMaxage( 1200 );
260260 $output->redirect( $targetUrl, '301' );
261261 }
@@ -298,13 +298,13 @@
299299 }
300300
301301 public function getMsg() {
302 - global $wgUser, $wgContLang, $wgRequest, $wgServer, $wgMobileRedirectFormAction, $wgMobileDomain;
 302+ global $wgUser, $wgContLang, $wgRequest, $wgServer, $wgMobileRedirectFormAction, $wgMobileDomain, $wgOut, $wgLanguageCode;
303303 wfProfileIn( __METHOD__ );
304304
305305 self::$disableImagesURL = $wgRequest->escapeAppendQuery( 'disableImages=1' );
306306 self::$enableImagesURL = $wgRequest->escapeAppendQuery( 'enableImages=1' );
307307 self::$disableMobileSiteURL = $wgRequest->escapeAppendQuery( 'mobileaction=disable_mobile_site' );
308 - self::$viewNormalSiteURL = $wgRequest->escapeAppendQuery( 'mobileaction=view_normal_site' );
 308+ self::$viewNormalSiteURL = $wgRequest->escapeAppendQuery( 'mobileaction=view_normal_site' );
309309 self::$currentURL = $wgRequest->getFullRequestURL();
310310 self::$leaveFeedbackURL = $wgRequest->escapeAppendQuery( 'mobileaction=leave_feedback' );
311311
@@ -334,7 +334,48 @@
335335
336336 self::$dir = $wgContLang->getDir();
337337 self::$code = $wgContLang->getCode();
 338+
 339+ $languageUrls = array();
 340+
 341+ if ( $wgLanguageCode == 'en' ) {
 342+ $languageUrls[] = array(
 343+ 'href' => self::$currentURL,
 344+ 'text' => self::$htmlTitle,
 345+ 'language' => $wgContLang->getLanguageName( $wgLanguageCode ),
 346+ 'class' => 'interwiki-' . $wgLanguageCode,
 347+ 'lang' => $wgLanguageCode,
 348+ );
 349+ }
 350+
 351+ foreach( $wgOut->getLanguageLinks() as $l ) {
 352+ if ( preg_match( '!^(\w[-\w]*\w):(.+)$!', $l, $m ) ) {
 353+ $lang = $m[1];
 354+ $linkText = $m[2];
 355+ } else {
 356+ continue; //NOTE: shouldn't happen
 357+ }
338358
 359+ $nt = Title::newFromText( $l );
 360+ $parsedUrl = wfParseUrl( $nt->getFullURL() );
 361+ if ( stristr( $parsedUrl['host'], $wgMobileDomain ) === false ) {
 362+ $hostParts = explode( '.', $parsedUrl['host'] );
 363+ $parsedUrl['host'] = $hostParts[0] . $wgMobileDomain . $hostParts[1] . '.' . $hostParts[2];
 364+ }
 365+ $fragmentDelimiter = ( !empty( $parsedUrl['fragment'] ) ) ? '#' : '';
 366+ $queryDelimiter = ( !empty( $parsedUrl['query'] ) ) ? '?' : '';
 367+ $languageUrl = $parsedUrl['scheme'] . '://' . $parsedUrl['host'] . $parsedUrl['path'] . $queryDelimiter . $parsedUrl['query'] . $fragmentDelimiter . $parsedUrl['fragment'];
 368+
 369+ $languageUrls[] = array(
 370+ 'href' => $languageUrl,
 371+ 'text' => $linkText,
 372+ 'language' => $wgContLang->getLanguageName( $lang ),
 373+ 'class' => 'interwiki-' . $lang,
 374+ 'lang' => $lang,
 375+ );
 376+ }
 377+
 378+ self::$languageUrls = $languageUrls;
 379+
339380 $nonMobileServerBaseURL = str_replace( $wgMobileDomain, '.', $wgServer );
340381 self::$mobileRedirectFormAction = ( $wgMobileRedirectFormAction !== false ) ? $wgMobileRedirectFormAction : "{$nonMobileServerBaseURL}/w/mobileRedirect.php";
341382
@@ -472,8 +513,8 @@
473514 $title = Title::newFromText( self::$messages['mobile-frontend-feedback-page'] );
474515
475516 if ( $title->userCan( 'edit' ) &&
476 - !$wgUser->isBlockedFrom( $title ) &&
477 - $wgUser->matchEditToken( $token ) ) {
 517+ !$wgUser->isBlockedFrom( $title ) &&
 518+ $wgUser->matchEditToken( $token ) ) {
478519 $article = new Article( $title, 0 );
479520 $rawtext = $article->getRawText();
480521 $rawtext .= "\n== {$subject} == \n {$message} ~~~~ \n <small>User agent: {$userAgent}</small> ";
@@ -512,19 +553,19 @@
513554 $wgRequest->response()->header( 'Location: ' . $location );
514555 }
515556
516 - if ( $mobileAction == 'opt_out_cookie' ) {
 557+ if ( $mobileAction == 'opt_out_cookie' ) {
517558 $this->setOptInOutCookie( '' );
518559 }
519560
520561 // WURFL documentation: http://wurfl.sourceforge.net/help_doc.php
521562 // Determine the kind of markup
522 - if ( is_array( $props ) && isset( $props['preferred_markup'] ) && $props['preferred_markup'] ) {
 563+ //if ( is_array( $props ) && isset( $props['preferred_markup'] ) && $props['preferred_markup'] ) {
523564 // wfDebug( __METHOD__ . ": preferred markup for this device: " . $props['preferred_markup'] );
524565 // xhtml/html: html_web_3_2, html_web_4_0
525566 // xthml basic/xhtmlmp (wap 2.0): html_wi_w3_xhtmlbasic html_wi_oma_xhtmlmp_1_0
526567 // chtml (imode): html_wi_imode_*
527568 // wml (wap 1): wml_1_1, wml_1_2, wml_1_3
528 - }
 569+ //}
529570 // WML options that might influence our 'style' of output
530571 // $props['access_key_support'] (for creating easy keypad navigation)
531572 // $props['softkey_support'] ( for creating your own menu)
@@ -543,7 +584,7 @@
544585 self::$useFormat === 'mobile-wap' ||
545586 !empty( $xDevice ) ) {
546587 if ( $action !== 'edit' &&
547 - $mobileAction !== 'view_normal_site' ) {
 588+ $mobileAction !== 'view_normal_site' ) {
548589 $this->getMsg();
549590 $this->disableCaching();
550591 $this->sendXDeviceVaryHeader();
@@ -659,7 +700,8 @@
660701 $wgOut->addVaryHeader( 'Application_Version' );
661702 } else {
662703 if ( !empty( $_SERVER['HTTP_X_DEVICE'] ) ) {
663 - if ( stripos( $_SERVER['HTTP_X_DEVICE'], 'iphone' ) !== false ) {
 704+ if ( stripos( $_SERVER['HTTP_X_DEVICE'], 'iphone' ) !== false ||
 705+ stripos( $_SERVER['HTTP_X_DEVICE'], 'android' ) !== false ) {
664706 $wgRequest->response()->header( 'Application_Version: ' . $_SERVER['HTTP_X_DEVICE'] );
665707 $wgOut->addVaryHeader( 'Application_Version' );
666708 }
@@ -1185,6 +1227,26 @@
11861228 wfProfileOut( __METHOD__ );
11871229 return $applicationHtml;
11881230 }
 1231+
 1232+ public static function buildLanguageSelection() {
 1233+ global $wgLanguageCode;
 1234+ $output = Html::openElement( 'select',
 1235+ array( 'id' => 'languageselection',
 1236+ 'onchange' => 'javascript:navigateToLanguageSelection();' ) );
 1237+ foreach (self::$languageUrls as $languageUrl) {
 1238+ if ( $languageUrl['lang'] == $wgLanguageCode ) {
 1239+ $output .= Html::element( 'option',
 1240+ array( 'value' => $languageUrl['href'], 'selected' => 'selected' ),
 1241+ $languageUrl['language'] );
 1242+ } else {
 1243+ $output .= Html::element( 'option',
 1244+ array( 'value' => $languageUrl['href'] ),
 1245+ $languageUrl['language'] );
 1246+ }
 1247+ }
 1248+ $output .= Html::closeElement( 'select', array() );
 1249+ return $output;
 1250+ }
11891251
11901252 /**
11911253 * Sets up the default logo image used in mobile view if none is set
Index: branches/wmf/1.18wmf1/extensions/MobileFrontend/views/layout/_search_webkit.html.php
@@ -10,6 +10,12 @@
1111 $scriptUrl = wfScript();
1212 $searchBoxDisplayNone = ( self::$hideSearchBox ) ? ' style="display: none;" ' : '';
1313
 14+$openSearchResults = ( self::$isBetaGroupMember ) ? '<div id="results"></div>' : '';
 15+
 16+$languageSelection = self::buildLanguageSelection() . '<br/>';
 17+$languageSelectionText = '<b>' . self::$messages['mobile-frontend-language'] . ':</b><br/>';
 18+$languageSelectionDiv = ( self::$isBetaGroupMember ) ? '<div id="languageselectionsection">' . $languageSelectionText . $languageSelection . '</div>' : '';
 19+
1420 $searchWebkitHtml = <<<EOD
1521 <div id='header'>
1622 <div id='searchbox'>
@@ -17,13 +23,15 @@
1824 <form action='{$scriptUrl}' class='search_bar' method='get' {$searchBoxDisplayNone}>
1925 <input type="hidden" value="Special:Search" name="title" />
2026 <div id="sq" class="divclearable">
21 - <input type="text" name="search" id="search" size="22" value="{$searchField}" />
 27+ <input type="text" name="search" id="search" size="22" value="{$searchField}" autocomplete="off" />
2228 <div class="clearlink" id="clearsearch"></div>
2329 </div>
2430 <button id='goButton' type='submit'></button>
2531 </form>
 32+ {$openSearchResults}
2633 </div>
2734 <div class='nav' id='nav'>
 35+ {$languageSelectionDiv}
2836 <button onclick="javascript:location.href='{$mainPageUrl}';" type="submit" id="homeButton">{$homeButton}</button>
2937 <button onclick="javascript:location.href='{$randomPageUrl}';" type="submit" id="randomButton">{$randomButton}</button>
3038 </div>
Index: branches/wmf/1.18wmf1/extensions/MobileFrontend/views/layout/application.html.php
@@ -1,5 +1,5 @@
22 <?php
3 -global $wgExtensionAssetsPath, $wgAppleTouchIcon;
 3+global $wgExtensionAssetsPath, $wgAppleTouchIcon, $wgScriptPath;
44
55 $dir = self::$dir;
66 $code = self::$code;
@@ -14,6 +14,12 @@
1515
1616 $cssFileName = ( isset( self::$device['css_file_name'] ) ) ? self::$device['css_file_name'] : 'default';
1717
 18+$startScriptTag = '<script type="text/javascript" language="javascript" src="';
 19+$endScriptTag = '"></script>';
 20+$javaScriptPath = $wgExtensionAssetsPath . '/MobileFrontend/javascripts/';
 21+
 22+$openSearchScript = ( self::$isBetaGroupMember ) ? $startScriptTag . $javaScriptPath . 'opensearch.js?version=10202011120715' . $endScriptTag : '';
 23+
1824 $applicationHtml = <<<EOT
1925 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2026 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
@@ -29,6 +35,7 @@
3036 <script type='text/javascript'>
3137 //<![CDATA[
3238 var title = "{$htmlTitle}";
 39+ var scriptPath = "{$wgScriptPath}";
3340 function shouldCache() {
3441 return true;
3542 }
@@ -42,7 +49,8 @@
4350 {$contentHtml}
4451 </div>
4552 {$footerHtml}
46 - <script type="text/javascript" language="javascript" src="{$wgExtensionAssetsPath}/MobileFrontend/javascripts/application.min.js?version=20111014T172820Z"></script>
 53+ {$startScriptTag}{$javaScriptPath}/application.js?version=10202011120715{$endScriptTag}
 54+ {$openSearchScript}
4755 </body>
4856 </html>
4957 EOT;

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r100663search suggestions and interwiki linkspreilly23:22, 24 October 2011

Status & tagging log