r88471 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r88470‎ | r88471 | r88472 >
Date:18:17, 20 May 2011
Author:preilly
Status:deferred
Tags:
Comment:
add basic device detection based on user-agent
Modified paths:
  • /trunk/extensions/PatchOutputMobile/PatchOutputMobile.php (modified) (history)

Diff [purge]

Index: trunk/extensions/PatchOutputMobile/PatchOutputMobile.php
@@ -27,7 +27,7 @@
2828 'onOutputPageBeforeHTML' );
2929
3030 class ExtPatchOutputMobile {
31 - const VERSION = '0.2.7';
 31+ const VERSION = '0.2.8';
3232
3333 private $doc;
3434
@@ -37,6 +37,7 @@
3838 public $WMLSectionSeperator = '***************************************************************************';
3939 public static $dir;
4040 public static $code;
 41+ public static $device;
4142
4243 public $itemsToRemove = array(
4344 '#contentSub', # redirection notice
@@ -79,6 +80,12 @@
8081 ExtPatchOutputMobile::$dir = $GLOBALS['wgContLang']->isRTL() ? "rtl" : "ltr";
8182 ExtPatchOutputMobile::$code = $GLOBALS['wgContLang']->getCode();
8283
 84+ $userAgent = $_SERVER['HTTP_USER_AGENT'];
 85+ $acceptHeader = $_SERVER["HTTP_ACCEPT"];
 86+ $device = new Device();
 87+ $formatName = $device->formatName( $userAgent, $acceptHeader );
 88+ ExtPatchOutputMobile::$device = $device->format( $formatName );
 89+
8390 ob_start( array( $this, 'parse' ) );
8491 return true;
8592 }
@@ -286,7 +293,8 @@
287294 $dir = ExtPatchOutputMobile::$dir;
288295 $code = ExtPatchOutputMobile::$code;
289296
290 - if ( strlen( $contentHtml ) > 4000 && $this->contentFormat == 'XHTML' ) {
 297+ if ( strlen( $contentHtml ) > 4000 && $this->contentFormat == 'XHTML'
 298+ && ExtPatchOutputMobile::$device['supports_javascript'] === true ) {
291299 $contentHtml = $this->javascriptize( $contentHtml );
292300 } else if ( $this->contentFormat == 'WML' ) {
293301 $contentHtml = $this->javascriptize( $contentHtml );
@@ -346,4 +354,366 @@
347355
348356 return $output;
349357 }
 358+}
 359+
 360+// Provides an abstraction for a device
 361+// A device can select which format a request should recieve and
 362+// may be extended to provide access to particular devices functionality
 363+class Device {
 364+
 365+ public function availableFormats() {
 366+ $formats = array (
 367+ 'html' =>
 368+ array (
 369+ 'view_format' => 'html',
 370+ 'search_bar' => 'default',
 371+ 'footmenu' => 'default',
 372+ 'with_layout' => 'application',
 373+ 'css_file_name' => 'default',
 374+ 'supports_javascript' => false,
 375+ 'disable_zoom' => true,
 376+ 'parser' => 'html',
 377+ 'disable_links' => true,
 378+ ),
 379+ 'capable' =>
 380+ array (
 381+ 'view_format' => 'html',
 382+ 'search_bar' => 'default',
 383+ 'footmenu' => 'default',
 384+ 'with_layout' => 'application',
 385+ 'css_file_name' => 'default',
 386+ 'supports_javascript' => true,
 387+ 'disable_zoom' => true,
 388+ 'parser' => 'html',
 389+ 'disable_links' => true,
 390+ ),
 391+ 'simplehtml' =>
 392+ array (
 393+ 'view_format' => 'html',
 394+ 'search_bar' => 'simple',
 395+ 'footmenu' => 'simple',
 396+ 'with_layout' => 'application',
 397+ 'css_file_name' => 'simple',
 398+ 'supports_javascript' => false,
 399+ 'disable_zoom' => true,
 400+ 'parser' => 'html',
 401+ 'disable_links' => true,
 402+ ),
 403+ 'webkit' =>
 404+ array (
 405+ 'view_format' => 'html',
 406+ 'search_bar' => 'webkit',
 407+ 'footmenu' => 'default',
 408+ 'with_layout' => 'application',
 409+ 'css_file_name' => 'webkit',
 410+ 'supports_javascript' => true,
 411+ 'disable_zoom' => true,
 412+ 'parser' => 'html',
 413+ 'disable_links' => true,
 414+ ),
 415+ 'webkit_old' =>
 416+ array (
 417+ 'view_format' => 'html',
 418+ 'search_bar' => 'default',
 419+ 'footmenu' => 'default',
 420+ 'with_layout' => 'application',
 421+ 'css_file_name' => 'webkit_old',
 422+ 'supports_javascript' => true,
 423+ 'disable_zoom' => true,
 424+ 'parser' => 'html',
 425+ 'disable_links' => true,
 426+ ),
 427+ 'android' =>
 428+ array (
 429+ 'view_format' => 'html',
 430+ 'search_bar' => 'default',
 431+ 'footmenu' => 'default',
 432+ 'with_layout' => 'application',
 433+ 'css_file_name' => 'android',
 434+ 'supports_javascript' => true,
 435+ 'disable_zoom' => false,
 436+ 'parser' => 'html',
 437+ 'disable_links' => true,
 438+ ),
 439+ 'iphone' =>
 440+ array (
 441+ 'view_format' => 'html',
 442+ 'search_bar' => 'webkit',
 443+ 'footmenu' => 'default',
 444+ 'with_layout' => 'application',
 445+ 'css_file_name' => 'iphone',
 446+ 'supports_javascript' => true,
 447+ 'disable_zoom' => true,
 448+ 'parser' => 'html',
 449+ 'disable_links' => true,
 450+ ),
 451+ 'iphone2' =>
 452+ array (
 453+ 'view_format' => 'html',
 454+ 'search_bar' => 'default',
 455+ 'footmenu' => 'default',
 456+ 'with_layout' => 'application',
 457+ 'css_file_name' => 'iphone2',
 458+ 'supports_javascript' => true,
 459+ 'disable_zoom' => true,
 460+ 'parser' => 'html',
 461+ 'disable_links' => true,
 462+ ),
 463+ 'native_iphone' =>
 464+ array (
 465+ 'view_format' => 'html',
 466+ 'search_bar' => false,
 467+ 'footmenu' => 'default',
 468+ 'with_layout' => 'application',
 469+ 'css_file_name' => 'default',
 470+ 'supports_javascript' => true,
 471+ 'disable_zoom' => true,
 472+ 'parser' => 'html',
 473+ 'disable_links' => false,
 474+ ),
 475+ 'palm_pre' =>
 476+ array (
 477+ 'view_format' => 'html',
 478+ 'search_bar' => 'default',
 479+ 'footmenu' => 'default',
 480+ 'with_layout' => 'application',
 481+ 'css_file_name' => 'palm_pre',
 482+ 'supports_javascript' => true,
 483+ 'disable_zoom' => true,
 484+ 'parser' => 'html',
 485+ 'disable_links' => true,
 486+ ),
 487+ 'kindle' =>
 488+ array (
 489+ 'view_format' => 'html',
 490+ 'search_bar' => 'kindle',
 491+ 'footmenu' => 'default',
 492+ 'with_layout' => 'application',
 493+ 'css_file_name' => 'kindle',
 494+ 'supports_javascript' => false,
 495+ 'disable_zoom' => true,
 496+ 'parser' => 'html',
 497+ 'disable_links' => true,
 498+ ),
 499+ 'kindle2' =>
 500+ array (
 501+ 'view_format' => 'html',
 502+ 'search_bar' => 'kindle',
 503+ 'footmenu' => 'default',
 504+ 'with_layout' => 'application',
 505+ 'css_file_name' => 'kindle',
 506+ 'supports_javascript' => false,
 507+ 'disable_zoom' => true,
 508+ 'parser' => 'html',
 509+ 'disable_links' => true,
 510+ ),
 511+ 'blackberry' =>
 512+ array (
 513+ 'view_format' => 'html',
 514+ 'search_bar' => 'default',
 515+ 'footmenu' => 'default',
 516+ 'with_layout' => 'application',
 517+ 'css_file_name' => 'blackberry',
 518+ 'supports_javascript' => true,
 519+ 'disable_zoom' => true,
 520+ 'parser' => 'html',
 521+ 'disable_links' => true,
 522+ ),
 523+ 'netfront' =>
 524+ array (
 525+ 'view_format' => 'html',
 526+ 'search_bar' => 'simple',
 527+ 'footmenu' => 'simple',
 528+ 'with_layout' => 'application',
 529+ 'css_file_name' => 'simple',
 530+ 'supports_javascript' => false,
 531+ 'disable_zoom' => true,
 532+ 'parser' => 'html',
 533+ 'disable_links' => true,
 534+ ),
 535+ 'wap2' =>
 536+ array (
 537+ 'view_format' => 'html',
 538+ 'search_bar' => 'simple',
 539+ 'footmenu' => 'simple',
 540+ 'with_layout' => 'application',
 541+ 'css_file_name' => 'simple',
 542+ 'supports_javascript' => false,
 543+ 'disable_zoom' => true,
 544+ 'parser' => 'html',
 545+ 'disable_links' => true,
 546+ ),
 547+ 'psp' =>
 548+ array (
 549+ 'view_format' => 'html',
 550+ 'search_bar' => 'simple',
 551+ 'footmenu' => 'simple',
 552+ 'with_layout' => 'application',
 553+ 'css_file_name' => 'psp',
 554+ 'supports_javascript' => false,
 555+ 'disable_zoom' => true,
 556+ 'parser' => 'html',
 557+ 'disable_links' => true,
 558+ ),
 559+ 'ps3' =>
 560+ array (
 561+ 'view_format' => 'html',
 562+ 'search_bar' => 'simple',
 563+ 'footmenu' => 'simple',
 564+ 'with_layout' => 'application',
 565+ 'css_file_name' => 'simple',
 566+ 'supports_javascript' => false,
 567+ 'disable_zoom' => true,
 568+ 'parser' => 'html',
 569+ 'disable_links' => true,
 570+ ),
 571+ 'wii' =>
 572+ array (
 573+ 'view_format' => 'html',
 574+ 'search_bar' => 'wii',
 575+ 'footmenu' => 'default',
 576+ 'with_layout' => 'application',
 577+ 'css_file_name' => 'wii',
 578+ 'supports_javascript' => true,
 579+ 'disable_zoom' => true,
 580+ 'parser' => 'html',
 581+ 'disable_links' => true,
 582+ ),
 583+ 'operamini' =>
 584+ array (
 585+ 'view_format' => 'html',
 586+ 'search_bar' => 'simple',
 587+ 'footmenu' => 'simple',
 588+ 'with_layout' => 'application',
 589+ 'css_file_name' => 'operamini',
 590+ 'supports_javascript' => false,
 591+ 'disable_zoom' => true,
 592+ 'parser' => 'html',
 593+ 'disable_links' => true,
 594+ ),
 595+ 'nokia' =>
 596+ array (
 597+ 'view_format' => 'html',
 598+ 'search_bar' => 'webkit',
 599+ 'footmenu' => 'default',
 600+ 'with_layout' => 'application',
 601+ 'css_file_name' => 'nokia',
 602+ 'supports_javascript' => true,
 603+ 'disable_zoom' => true,
 604+ 'parser' => 'html',
 605+ 'disable_links' => true,
 606+ ),
 607+ 'wml' =>
 608+ array (
 609+ 'view_format' => 'wml',
 610+ 'search_bar' => 'wml',
 611+ 'supports_javascript' => false,
 612+ 'parser' => 'wml',
 613+ ),
 614+ );
 615+ return $formats;
 616+ }
 617+
 618+ public function format( $formatName ) {
 619+ $format = $this->availableFormats();
 620+ return ( isset( $format[$formatName] ) ) ? $format[$formatName] : array();
 621+ }
 622+
 623+ public function testFormatName() {
 624+ $testResults = '';
 625+
 626+ $userAgents = array();
 627+ $userAgents['android'] = 'Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17';
 628+ $userAgents['iphone2'] = 'Mozilla/5.0 (ipod: U;CPU iPhone OS 2_2 like Mac OS X: es_es) AppleWebKit/525.18.1 (KHTML, like Gecko) Version/3.0 Mobile/3B48b Safari/419.3';
 629+ $userAgents['iphone'] = 'Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/3B48b Safari/419.3';
 630+ $userAgents['nokia'] = 'Mozilla/5.0 (SymbianOS/9.1; U; [en]; SymbianOS/91 Series60/3.0) AppleWebKit/413 (KHTML, like Gecko) Safari/413';
 631+ $userAgents['palm_pre'] = 'Mozilla/5.0 (webOS/1.0; U; en-US) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/1.0 Safari/525.27.1 Pre/1.0';
 632+ $userAgents['wii'] = 'Opera/9.00 (Nintendo Wii; U; ; 1309-9; en)';
 633+ $userAgents['operamini'] = 'Opera/9.50 (J2ME/MIDP; Opera Mini/4.0.10031/298; U; en)';
 634+ $userAgents['iphone'] = 'Opera/9.51 Beta (Microsoft Windows; PPC; Opera Mobi/1718; U; en)';
 635+ $userAgents['kindle'] = 'Mozilla/4.0 (compatible; Linux 2.6.10) NetFront/3.3 Kindle/1.0 (screen 600x800)';
 636+ $userAgents['kindle2'] = 'Mozilla/4.0 (compatible; Linux 2.6.22) NetFront/3.4 Kindle/2.0 (screen 824x1200; rotate)';
 637+ $userAgents['capable'] = 'Mozilla/5.0 (X11; Linux i686; rv:2.0.1) Gecko/20100101 Firefox/4.0.1';
 638+ $userAgents['netfront'] = 'Mozilla/4.08 (Windows; Mobile Content Viewer/1.0) NetFront/3.2';
 639+ $userAgents['wap2'] = 'SonyEricssonK608i/R2L/SN356841000828910 Browser/SEMC-Browser/4.2 Profile/MIDP-2.0 Configuration/CLDC-1.1';
 640+ $userAgents['wap2'] = 'NokiaN73-2/3.0-630.0.2 Series60/3.0 Profile/MIDP-2.0 Configuration/CLDC-1.1';
 641+ $userAgents['psp'] = 'Mozilla/4.0 (PSP (PlayStation Portable); 2.00)';
 642+ $userAgents['ps3'] = 'Mozilla/5.0 (PLAYSTATION 3; 1.00)';
 643+
 644+ foreach ( $userAgents as $formatName => $userAgent ) {
 645+ if ( $this->formatName( $userAgent ) === $formatName ) {
 646+ $result = ' has PASSED!';
 647+ } else {
 648+ $result = ' has FAILED!';
 649+ }
 650+
 651+ $testResults .= $formatName . $result . '<br/>' . PHP_EOL;
 652+ }
 653+ return $testResults;
 654+ }
 655+
 656+ public function formatName( $userAgent, $acceptHeader = '' ) {
 657+ $formatName = '';
 658+
 659+ if ( preg_match( '/Android/', $userAgent ) ) {
 660+ $formatName = 'android';
 661+ } elseif ( preg_match( '/iPhone.* Safari/', $userAgent ) ) {
 662+ if ( strpos( $userAgent, 'iPhone OS 2' ) !== false ) {
 663+ $formatName = 'iphone2';
 664+ } else {
 665+ $formatName = 'iphone';
 666+ }
 667+ } elseif ( preg_match( '/iPhone/', $userAgent ) ) {
 668+ if ( strpos( $userAgent, 'Opera' ) !== false ) {
 669+ $formatName = 'operamini';
 670+ } else {
 671+ $formatName = 'native_iphone';
 672+ }
 673+ } elseif ( preg_match( '/WebKit/', $userAgent ) ) {
 674+ if ( preg_match( '/Series60/', $userAgent ) ) {
 675+ $formatName = 'nokia';
 676+ } elseif ( preg_match( '/webOS/', $userAgent ) ) {
 677+ $formatName = 'palm_pre';
 678+ } else {
 679+ $formatName = 'webkit';
 680+ }
 681+ } elseif ( preg_match( '/Opera/', $userAgent ) ) {
 682+ if ( strpos( $userAgent, 'Nintendo Wii' ) !== false ) {
 683+ $formatName = 'wii';
 684+ } elseif ( strpos( $userAgent, 'Opera Mini' ) !== false ) {
 685+ $formatName = 'operamini';
 686+ } elseif ( strpos( $userAgent, 'Opera Mobi' ) !== false ) {
 687+ $formatName = 'iphone';
 688+ } else {
 689+ $formatName = 'webkit';
 690+ }
 691+ } elseif ( preg_match( '/Kindle\/1.0/', $userAgent ) ) {
 692+ $formatName = 'kindle';
 693+ } elseif ( preg_match( '/Kindle\/2.0/', $userAgent ) ) {
 694+ $formatName = 'kindle2';
 695+ } elseif ( preg_match( '/Firefox/', $userAgent ) ) {
 696+ $formatName = 'capable';
 697+ } elseif ( preg_match( '/NetFront/', $userAgent ) ) {
 698+ $formatName = 'netfront';
 699+ } elseif ( preg_match( '/SEMC-Browser/', $userAgent ) ) {
 700+ $formatName = 'wap2';
 701+ } elseif ( preg_match( '/Series60/', $userAgent ) ) {
 702+ $formatName = 'wap2';
 703+ } elseif ( preg_match( '/PlayStation Portable/', $userAgent ) ) {
 704+ $formatName = 'psp';
 705+ } elseif ( preg_match( '/PLAYSTATION 3/', $userAgent ) ) {
 706+ $formatName = 'ps3';
 707+ }
 708+
 709+ if ( $formatName === '' ) {
 710+ if ( strpos( $acceptHeader, 'application/vnd.wap.xhtml+xml' ) !== false ) {
 711+ $formatName = 'wap2';
 712+ } elseif ( strpos( $acceptHeader, 'vnd.wap.wml' ) !== false ) {
 713+ $formatName = 'wml';
 714+ } else {
 715+ $formatName = 'html';
 716+ }
 717+ }
 718+ return $formatName;
 719+ }
350720 }
\ No newline at end of file

Status & tagging log