Rev 19 | Rev 21 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line | 
|---|---|---|---|
| 2 | PointedEar | 1 | <?php | 
        
| 2 | |||
| 3 | require_once 'global.inc';  | 
        ||
| 4 | |||
| 20 | PointedEar | 5 | $encoding = mb_detect_encoding(file_get_contents($_SERVER['SCRIPT_FILENAME']));  | 
        
| 6 | if ($encoding === 'ASCII') $encoding = 'iso-8859-1';  | 
        ||
| 7 | define('FEATURES_ENCODING', $encoding);  | 
        ||
| 13 | PointedEar | 8 | |
| 2 | PointedEar | 9 | /** | 
        
| 10 |  * A list of language features with URNs definitions | 
        ||
| 11 |  * for reference links. | 
        ||
| 12 |  */ | 
        ||
| 13 | class FeatureList | 
        ||
| 14 | { | 
        ||
| 15 | public $versions = array();  | 
        ||
| 16 | |||
| 17 |   /** | 
        ||
| 18 |    * Versions of implementations that are considered safe. | 
        ||
| 19 |    * A feature is considered safe if it does not require | 
        ||
| 20 |    * an implementation version above these versions. | 
        ||
| 21 |    * | 
        ||
| 22 |    * @var Array[string=>string] | 
        ||
| 23 |    */ | 
        ||
| 24 | public $safeVersions = array();  | 
        ||
| 25 | |||
| 26 |   /** | 
        ||
| 27 |    * URNs that can be used for reference links. | 
        ||
| 28 |    * | 
        ||
| 29 |    * @var Array[string=>string] | 
        ||
| 30 |    */ | 
        ||
| 31 | protected $urns = array();  | 
        ||
| 32 | |||
| 33 |   /** | 
        ||
| 19 | PointedEar | 34 |    * <code>true</code> generates form controls for submitting test case | 
        
| 35 |    * results | 
        ||
| 36 |    * | 
        ||
| 37 |    * @var bool | 
        ||
| 38 |    */ | 
        ||
| 39 | protected $testcase = false;  | 
        ||
| 40 | |||
| 41 |   /** | 
        ||
| 2 | PointedEar | 42 |    * The list of language features | 
        
| 43 |    * | 
        ||
| 44 |    * @var array[Features] | 
        ||
| 45 |    */ | 
        ||
| 46 | protected $items = array();  | 
        ||
| 47 | |||
| 48 |   /** | 
        ||
| 49 |    * Determines the number of printed items the table headings should be repeated | 
        ||
| 50 |    * | 
        ||
| 51 |    * @var int | 
        ||
| 52 |    */ | 
        ||
| 53 | protected $headerRepeat = 25;  | 
        ||
| 54 | |||
| 55 |   /** | 
        ||
| 56 |    * Initializes the FeatureList object | 
        ||
| 57 |    * | 
        ||
| 58 |    * @param array|Object $a | 
        ||
| 59 |    * @return FeatureList | 
        ||
| 60 |    */ | 
        ||
| 61 | public function __construct($a)  | 
        ||
| 62 |   { | 
        ||
| 9 | PointedEar | 63 | $aVars = get_class_vars(get_class($this));  | 
        
| 64 | |||
| 19 | PointedEar | 65 | |
| 66 | foreach ($aVars as $key => $value)  | 
        ||
| 2 | PointedEar | 67 |     { | 
        
| 68 | if (isset($a[$key]))  | 
        ||
| 69 |       { | 
        ||
| 70 | $this->$key = $a[$key];  | 
        ||
| 71 |       } | 
        ||
| 72 |     } | 
        ||
| 19 | PointedEar | 73 | |
| 2 | PointedEar | 74 |     /* Inform items of ourself so that URNs can be used for links */ | 
        
| 75 | if (is_array($this->items))  | 
        ||
| 76 |     { | 
        ||
| 77 | foreach ($this->items as &$item)  | 
        ||
| 78 |       { | 
        ||
| 4 | PointedEar | 79 | $item->setList($this);  | 
        
| 2 | PointedEar | 80 |       } | 
        
| 81 |     } | 
        ||
| 82 | |||
| 83 |     /* resolve URN references that are URNs */ | 
        ||
| 84 | if (is_array($this->urns))  | 
        ||
| 85 |     { | 
        ||
| 86 | foreach ($this->urns as &$urn)  | 
        ||
| 87 |       { | 
        ||
| 88 | if (($url = $this->resolveURN($urn)))  | 
        ||
| 89 |         { | 
        ||
| 90 | $urn = $url;  | 
        ||
| 91 |         } | 
        ||
| 92 |       } | 
        ||
| 93 |     } | 
        ||
| 94 |   } | 
        ||
| 95 | |||
| 19 | PointedEar | 96 |   /* | 
        
| 97 |    * Protected properties may be read, but not written | 
        ||
| 98 |    */ | 
        ||
| 99 | public function __get($property)  | 
        ||
| 100 |   { | 
        ||
| 101 | if (property_exists(get_class($this), $property))  | 
        ||
| 102 |     { | 
        ||
| 103 | return $this->$property;  | 
        ||
| 104 |     } | 
        ||
| 105 |   } | 
        ||
| 106 | |||
| 2 | PointedEar | 107 | public function printHeaders()  | 
        
| 108 |   { | 
        ||
| 19 | PointedEar | 109 | foreach ($this->versions as $key => $ver)  | 
        
| 2 | PointedEar | 110 |     { | 
        
| 19 | PointedEar | 111 | if ($key || $this->testcase)  | 
        
| 112 |       { | 
        ||
| 2 | PointedEar | 113 | ?> | 
        
| 114 | <th><?php echo $ver; ?></th>  | 
        ||
| 115 | <?php | 
        ||
| 19 | PointedEar | 116 |       } | 
        
| 2 | PointedEar | 117 |     } | 
        
| 118 |   } | 
        ||
| 119 | |||
| 120 |   /** | 
        ||
| 121 |    * Prints the list of features. | 
        ||
| 122 |    * | 
        ||
| 123 |    * @see Feature::printMe() | 
        ||
| 124 |    */ | 
        ||
| 125 | public function printItems()  | 
        ||
| 126 |   { | 
        ||
| 127 | $counter = 0;  | 
        ||
| 128 | $headerRepeat = $this->headerRepeat;  | 
        ||
| 129 | $repeatHeaders = ($headerRepeat > 1);  | 
        ||
| 130 | |||
| 131 | foreach ($this->items as $feature)  | 
        ||
| 132 |     { | 
        ||
| 133 | if ($feature instanceof Feature)  | 
        ||
| 134 |       { | 
        ||
| 16 | PointedEar | 135 |         /* | 
        
| 136 |          * TODO: Disabled header repetition until footnote ref. name/ID | 
        ||
| 137 |          * problem has been solved | 
        ||
| 138 |          */ | 
        ||
| 139 | //        if ($repeatHeaders | 
        ||
| 140 | //            && $counter > 1 | 
        ||
| 141 | //            && $counter % $headerRepeat === 0) | 
        ||
| 142 | //        { | 
        ||
| 143 | //          echo <<<HTML | 
        ||
| 144 | //        <tr class="header"> | 
        ||
| 145 | //          <th>Feature</th> | 
        ||
| 146 | //          {$this->printHeaders()} | 
        ||
| 147 | //        </tr> | 
        ||
| 148 | //HTML; | 
        ||
| 149 | //        } | 
        ||
| 2 | PointedEar | 150 | |
| 151 | $feature->printMe();  | 
        ||
| 152 | |||
| 153 | $counter++;  | 
        ||
| 154 |       } | 
        ||
| 155 |     } | 
        ||
| 156 |   } | 
        ||
| 157 | |||
| 158 |   /** | 
        ||
| 159 |    * Resolves a URN according to the value of the | 
        ||
| 160 |    * object's <code>$urn</code> property. | 
        ||
| 161 |    * | 
        ||
| 162 |    * @param string $urn | 
        ||
| 163 |    *   URN to be resolved | 
        ||
| 164 |    * @return string|boolean | 
        ||
| 165 |    *   The resolved URN if successful, | 
        ||
| 166 |    *   <code>false</code> otherwise. | 
        ||
| 167 |    */ | 
        ||
| 168 | public function resolveURN($urn)  | 
        ||
| 169 |   { | 
        ||
| 170 | if (is_array($this->urns))  | 
        ||
| 171 |     { | 
        ||
| 172 | $reURN = '|^(.+?):(?!//)|';  | 
        ||
| 173 | |||
| 174 | if (preg_match($reURN, $urn, $m) && isset($this->urns[$m[1]]))  | 
        ||
| 175 |       { | 
        ||
| 176 | return preg_replace($reURN, $this->urns[$m[1]], $urn);  | 
        ||
| 177 |       } | 
        ||
| 178 |     } | 
        ||
| 179 | |||
| 180 | return $urn;  | 
        ||
| 181 |   } | 
        ||
| 182 | } | 
        ||
| 183 | |||
| 184 | /** | 
        ||
| 185 |  * A language feature. | 
        ||
| 186 |  */ | 
        ||
| 187 | class Feature | 
        ||
| 188 | { | 
        ||
| 189 |   /** | 
        ||
| 190 |    * Fragment identifiers to be defined for quickly accessing | 
        ||
| 191 |    * the feature description. | 
        ||
| 192 |    * | 
        ||
| 193 |    * @var Array[String] | 
        ||
| 194 |    */ | 
        ||
| 195 | protected $anchors = array();  | 
        ||
| 196 | |||
| 197 |   /** | 
        ||
| 198 |    * Value of the explanatory <code>title</code> attribute for the feature. | 
        ||
| 199 |    * | 
        ||
| 200 |    * @var string | 
        ||
| 201 |    */ | 
        ||
| 202 | protected $title = '';  | 
        ||
| 203 | |||
| 204 |   /** | 
        ||
| 205 |    * Name or example code of the feature | 
        ||
| 206 |    * | 
        ||
| 207 |    * @var string | 
        ||
| 208 |    */ | 
        ||
| 209 | protected $content = '';  | 
        ||
| 210 | |||
| 211 |   /** | 
        ||
| 212 |    * Description of the feature.  Displayed directly if code is missing, | 
        ||
| 213 |    * otherwise used as `title' attribute value. | 
        ||
| 214 |    * | 
        ||
| 215 |    * @var string | 
        ||
| 216 |    */ | 
        ||
| 217 | protected $descr = '';  | 
        ||
| 218 | |||
| 219 |   /** | 
        ||
| 220 |    * Versions that support this feature | 
        ||
| 221 |    * | 
        ||
| 222 |    * @var Array | 
        ||
| 223 |    */ | 
        ||
| 224 | protected $versions = array();  | 
        ||
| 225 | |||
| 226 |   /** | 
        ||
| 227 |    * Reference to the FeatureList that this feature belongs to | 
        ||
| 228 |    * | 
        ||
| 229 |    * @var FeatureList | 
        ||
| 230 |    */ | 
        ||
| 231 | protected $list = null;  | 
        ||
| 232 | |||
| 4 | PointedEar | 233 | public function setList(&$oList)  | 
        
| 2 | PointedEar | 234 |   { | 
        
| 235 | $this->list =& $oList;  | 
        ||
| 236 |   } | 
        ||
| 237 | |||
| 238 |   /** | 
        ||
| 239 |    * Creates a new Feature object, using values from the passed parameters | 
        ||
| 240 |    * array. | 
        ||
| 241 |    * | 
        ||
| 242 |    * @param array|Object $params | 
        ||
| 243 |    * @return Feature | 
        ||
| 244 |    */ | 
        ||
| 245 | public function __construct($params = array())  | 
        ||
| 246 |   { | 
        ||
| 14 | PointedEar | 247 | $aVars = get_class_vars(__CLASS__);  | 
        
| 9 | PointedEar | 248 | |
| 19 | PointedEar | 249 | foreach ($aVars as $key => $value)  | 
        
| 2 | PointedEar | 250 |     { | 
        
| 9 | PointedEar | 251 | if (isset($params[$key]))  | 
        
| 252 |       { | 
        ||
| 253 | $this->$key = $params[$key];  | 
        ||
| 254 |       } | 
        ||
| 2 | PointedEar | 255 |     } | 
        
| 256 |   } | 
        ||
| 257 | |||
| 258 |   /** | 
        ||
| 17 | PointedEar | 259 |    * Determines whether one version is greater than another. | 
        
| 260 |    * | 
        ||
| 261 |    * @param string $v1  Version string #1 | 
        ||
| 262 |    * @param string $v2  Version string #2 | 
        ||
| 263 |    * @return bool | 
        ||
| 264 |    *   <code>true</code> if the version <var>$v1</var> is greater than | 
        ||
| 265 |    *   the version <var>$v2</var>, <code>false</code> otherwise | 
        ||
| 266 |    */ | 
        ||
| 267 | protected static function _versionIsGreater($v1, $v2)  | 
        ||
| 268 |   { | 
        ||
| 269 | $v1 = explode('.', $v1);  | 
        ||
| 270 | $v2 = explode('.', $v2);  | 
        ||
| 271 | |||
| 272 | foreach ($v1 as $key => $value)  | 
        ||
| 273 |     { | 
        ||
| 274 | if ((int)$value <= (int)$v2[$key])  | 
        ||
| 275 |       { | 
        ||
| 276 | return false;  | 
        ||
| 277 |       } | 
        ||
| 278 |     } | 
        ||
| 279 | |||
| 280 | return true;  | 
        ||
| 281 |   } | 
        ||
| 282 | |||
| 283 |   /** | 
        ||
| 2 | PointedEar | 284 |    * Returns <code>' class="safe"'</code> if the feature | 
        
| 285 |    * can be considered safe.  The required information | 
        ||
| 286 |    * is stored in the <code>safeVersions</code> property | 
        ||
| 287 |    * of the associated <code>FeatureList</code> object. | 
        ||
| 288 |    * | 
        ||
| 289 |    * @return string | 
        ||
| 290 |    * @see FeatureList::defaultSafeVersions | 
        ||
| 291 |    */ | 
        ||
| 292 | protected function getSafeStr()  | 
        ||
| 293 |   { | 
        ||
| 294 | if (!is_null($this->list))  | 
        ||
| 295 |     { | 
        ||
| 296 | foreach ($this->list->safeVersions as $impl => &$safeVer)  | 
        ||
| 297 |       { | 
        ||
| 298 | $thisImplVer =& $this->versions[$impl];  | 
        ||
| 299 | if (is_array($thisImplVer))  | 
        ||
| 300 |         { | 
        ||
| 301 | if (isset($thisImplVer['tested']) && !is_bool($thisImplVer['tested']))  | 
        ||
| 302 |           { | 
        ||
| 303 | $thisImplVer =& $thisImplVer['tested'];  | 
        ||
| 304 |           } | 
        ||
| 305 |           else | 
        ||
| 306 |         { | 
        ||
| 307 | $thisImplVer =& $thisImplVer[0];  | 
        ||
| 308 |           } | 
        ||
| 309 |         } | 
        ||
| 310 | |||
| 311 |         /* DEBUG */ | 
        ||
| 312 |         // echo " $impl=$thisImplVer "; | 
        ||
| 313 | |||
| 17 | PointedEar | 314 | if (preg_match('/^-?$/', $thisImplVer) || self::_versionIsGreater($thisImplVer, $safeVer))  | 
        
| 2 | PointedEar | 315 |         { | 
        
| 316 | return '';  | 
        ||
| 317 |         } | 
        ||
| 318 |       } | 
        ||
| 319 | |||
| 320 | return ' class="safe"';  | 
        ||
| 321 |     } | 
        ||
| 322 |     else | 
        ||
| 323 |     { | 
        ||
| 324 | return '';  | 
        ||
| 325 |     } | 
        ||
| 326 |   } | 
        ||
| 327 | |||
| 328 | protected function getTitleStr()  | 
        ||
| 329 |   { | 
        ||
| 330 | if (!empty($this->title))  | 
        ||
| 331 |     { | 
        ||
| 332 | return " title=\"{$this->title}\"";  | 
        ||
| 333 |     } | 
        ||
| 334 |     else | 
        ||
| 335 |     { | 
        ||
| 336 | return '';  | 
        ||
| 337 |     } | 
        ||
| 338 |   } | 
        ||
| 339 | |||
| 340 | protected function getAnchors()  | 
        ||
| 341 |   { | 
        ||
| 342 | $result = array();  | 
        ||
| 343 | |||
| 344 | foreach ($this->anchors as $anchor)  | 
        ||
| 345 |     { | 
        ||
| 346 | $result[] = "<a name=\"{$anchor}\"";  | 
        ||
| 347 | |||
| 348 | if (preg_match('/^[a-z][a-z0-9_:.-]*/i', $anchor))  | 
        ||
| 349 |       { | 
        ||
| 350 | $result[] = " id=\"{$anchor}\"";  | 
        ||
| 351 |       } | 
        ||
| 352 | |||
| 353 | $result[] = '></a>';  | 
        ||
| 354 |     } | 
        ||
| 355 | |||
| 356 | return join('', $result);  | 
        ||
| 357 |   } | 
        ||
| 358 | |||
| 359 | protected function getAssumed($v)  | 
        ||
| 360 |   { | 
        ||
| 361 | if (is_array($v) && isset($v['assumed']) && $v['assumed'])  | 
        ||
| 362 |     { | 
        ||
| 363 | return ' class="assumed"';  | 
        ||
| 364 |     } | 
        ||
| 365 | |||
| 366 | return '';  | 
        ||
| 367 |   } | 
        ||
| 368 | |||
| 369 | protected function getTested($v)  | 
        ||
| 370 |   { | 
        ||
| 371 | if (is_array($v) && isset($v['tested']) && $v['tested'])  | 
        ||
| 372 |     { | 
        ||
| 373 | return ' class="tested"';  | 
        ||
| 374 |     } | 
        ||
| 375 | |||
| 376 | return '';  | 
        ||
| 377 |   } | 
        ||
| 378 | |||
| 379 |   /** | 
        ||
| 380 |    * Returns the version of a feature. | 
        ||
| 381 |    * | 
        ||
| 382 |    * @param string|VersionInfo $vInfo | 
        ||
| 383 |    * @return mixed | 
        ||
| 384 |    */ | 
        ||
| 385 | protected function getVer($vInfo)  | 
        ||
| 386 |   { | 
        ||
| 387 | if (is_array($vInfo))  | 
        ||
| 388 |     { | 
        ||
| 389 |       /* TODO: Return all versions: documented, assumed, and tested */ | 
        ||
| 390 | $vNumber = (isset($vInfo['tested'])  | 
        ||
| 391 | && gettype($vInfo['tested']) !== 'boolean')  | 
        ||
| 392 | ? $vInfo['tested']  | 
        ||
| 393 | : $vInfo[0];  | 
        ||
| 394 | $section = isset($vInfo['section'])  | 
        ||
| 395 |                    ? ' <span class="section" title="Specification section">[' | 
        ||
| 396 | . $vInfo['section'] . ']</span>'  | 
        ||
| 397 | : '';  | 
        ||
| 398 | |||
| 399 | if (isset($vInfo['urn']))  | 
        ||
| 400 |       { | 
        ||
| 401 | if ($this->list instanceof FeatureList)  | 
        ||
| 402 |         { | 
        ||
| 403 | $url = $this->list->resolveURN($vInfo['urn']);  | 
        ||
| 404 | $vNumber = '<a href="' . $url . '">' . $vNumber  | 
        ||
| 6 | PointedEar | 405 | . ($section ? $section : '') . '</a>';  | 
        
| 2 | PointedEar | 406 |         } | 
        
| 407 |       } | 
        ||
| 408 | else if ($section)  | 
        ||
| 409 |       { | 
        ||
| 410 | $vNumber .= $section;  | 
        ||
| 411 |       } | 
        ||
| 412 | |||
| 6 | PointedEar | 413 | $vInfo = $vNumber;  | 
        
| 2 | PointedEar | 414 |     } | 
        
| 6 | PointedEar | 415 | |
| 416 | return ($vInfo === '-')  | 
        ||
| 417 |       ? '<span title="Not supported">−</span>' | 
        ||
| 418 | : $vInfo;  | 
        ||
| 2 | PointedEar | 419 |   } | 
        
| 17 | PointedEar | 420 | |
| 421 |   /** | 
        ||
| 422 |    * Returns a syntax-highlighted version of a string | 
        ||
| 423 |    * | 
        ||
| 424 |    * @param string $s | 
        ||
| 425 |    * @return string | 
        ||
| 426 |    */ | 
        ||
| 2 | PointedEar | 427 | protected static function shl($s)  | 
        
| 428 |   { | 
        ||
| 429 |     /* stub */ | 
        ||
| 17 | PointedEar | 430 | return $s;  | 
        
| 2 | PointedEar | 431 |   } | 
        
| 432 | |||
| 433 | public function printMe()  | 
        ||
| 434 |   { | 
        ||
| 435 |     ?> | 
        ||
| 436 | <tr<?php echo $this->getSafeStr(); ?>>  | 
        ||
| 437 | <th<?php echo $this->getTitleStr(); ?>><?php  | 
        ||
| 438 | echo $this->getAnchors();  | 
        ||
| 439 | echo /*preg_replace_callback(  | 
        ||
| 440 |               '#(<code>)(.+?)(</code>)#', | 
        ||
| 441 |               array('self', 'shl'),*/ | 
        ||
| 442 | preg_replace('/…/', '…', $this->content)/*)*/;  | 
        ||
| 443 |             ?></th> | 
        ||
| 444 | <?php | 
        ||
| 445 | $versions = $this->versions;  | 
        ||
| 19 | PointedEar | 446 | $testcase = false;  | 
        
| 2 | PointedEar | 447 | if (!is_null($this->list))  | 
        
| 448 |     { | 
        ||
| 449 | $versions =& $this->list->versions;  | 
        ||
| 19 | PointedEar | 450 | $testcase = $this->list->testcase;  | 
        
| 2 | PointedEar | 451 |     } | 
        
| 452 | |||
| 453 | static $row = 0;  | 
        ||
| 454 | $row++;  | 
        ||
| 455 | |||
| 456 | $column = 0;  | 
        ||
| 17 | PointedEar | 457 | $thisVersions =& $this->versions;  | 
        
| 2 | PointedEar | 458 | |
| 459 | foreach ($versions as $key => $value)  | 
        ||
| 460 |     { | 
        ||
| 461 | $column++;  | 
        ||
| 462 | $id = "td$row-$column";  | 
        ||
| 17 | PointedEar | 463 | $ver = isset($thisVersions[$key]) ? $thisVersions[$key] : '';  | 
        
| 19 | PointedEar | 464 | if ($key || $testcase)  | 
        
| 465 |       { | 
        ||
| 2 | PointedEar | 466 | ?> | 
        
| 17 | PointedEar | 467 |           <td<?php | 
        
| 19 | PointedEar | 468 | if (!$key)  | 
        
| 469 |             { | 
        ||
| 470 | echo " id='$id'";  | 
        ||
| 471 |             } | 
        ||
| 472 | |||
| 2 | PointedEar | 473 | echo $this->getAssumed($ver) . $this->getTested($ver);  | 
        
| 17 | PointedEar | 474 | |
| 2 | PointedEar | 475 | if (!$key)  | 
        
| 476 |             { | 
        ||
| 477 | if (!empty($ver))  | 
        ||
| 478 |               { | 
        ||
| 13 | PointedEar | 479 | echo ' title="Test code: '  | 
        
| 480 | . htmlspecialchars(  | 
        ||
| 17 | PointedEar | 481 | preg_replace('/\\\(["\'])/', '\1',  | 
        
| 482 | reduceWhitespace($ver)  | 
        ||
| 483 | ),  | 
        ||
| 13 | PointedEar | 484 | ENT_COMPAT,  | 
        
| 17 | PointedEar | 485 | FEATURES_ENCODING  | 
        
| 486 |                     ) | 
        ||
| 13 | PointedEar | 487 | . '"';  | 
        
| 2 | PointedEar | 488 |               } | 
        
| 489 |               else | 
        ||
| 19 | PointedEar | 490 |             { | 
        
| 2 | PointedEar | 491 | echo ' title="Not applicable: No automated test case'  | 
        
| 17 | PointedEar | 492 | . ' is available for this feature. If possible, please'  | 
        
| 493 | . ' click the feature code in the first column to run'  | 
        ||
| 2 | PointedEar | 494 | . ' a manual test."';  | 
        
| 495 |               } | 
        ||
| 496 |             } | 
        ||
| 19 | PointedEar | 497 |             else | 
        
| 498 |           { | 
        ||
| 499 | echo ' title="'  | 
        ||
| 500 | . htmlspecialchars(  | 
        ||
| 501 | preg_replace('/<.*?>/', '', $value),  | 
        ||
| 502 | ENT_COMPAT, FEATURES_ENCODING)  | 
        ||
| 503 | . '"';  | 
        ||
| 504 |             } | 
        ||
| 2 | PointedEar | 505 | ?>><?php  | 
        
| 506 | if ($key)  | 
        ||
| 507 |             { | 
        ||
| 508 | echo $this->getVer($ver);  | 
        ||
| 17 | PointedEar | 509 | |
| 510 |               /* General footnotes support: include footnotes.class.php to enable */ | 
        ||
| 511 | if (is_array($ver) && isset($ver['footnote']) && $ver['footnote'])  | 
        ||
| 512 |               { | 
        ||
| 513 | echo $ver['footnote'];  | 
        ||
| 514 |               } | 
        ||
| 2 | PointedEar | 515 |             } | 
        
| 516 |             else | 
        ||
| 19 | PointedEar | 517 |           { | 
        
| 518 | if (!empty($ver) && $testcase)  | 
        ||
| 2 | PointedEar | 519 |               { | 
        
| 520 |                 ?><script type="text/javascript"> | 
        ||
| 521 | // <![CDATA[  | 
        ||
| 19 | PointedEar | 522 | var s = test(<?php echo $ver; ?>,  | 
        
| 523 | '<input title="Supported" name="<?php echo htmlspecialchars($this->title, ENT_COMPAT, FEATURES_ENCODING); ?>" value="+" readonly>',  | 
        ||
| 524 | '<input title="Not supported" name="<?php echo htmlspecialchars($this->title, ENT_COMPAT, FEATURES_ENCODING); ?>" value="−" readonly>');  | 
        ||
| 525 |   jsx.tryThis("document.write(s);", | 
        ||
| 2 | PointedEar | 526 |           "document.getElementById('<?php echo $id; ?>').appendChild(" | 
        
| 527 | + "document.createTextNode(s));");  | 
        ||
| 528 | // ]]>  | 
        ||
| 529 | </script><?php | 
        ||
| 530 |               } | 
        ||
| 531 |               else | 
        ||
| 19 | PointedEar | 532 |             { | 
        
| 2 | PointedEar | 533 | echo '<abbr>N/A</abbr>';  | 
        
| 534 |               } | 
        ||
| 535 |             } | 
        ||
| 536 |             ?></td> | 
        ||
| 537 | <?php | 
        ||
| 19 | PointedEar | 538 |       } | 
        
| 2 | PointedEar | 539 |     } | 
        
| 540 | ?> | 
        ||
| 541 | </tr>  | 
        ||
| 542 | <?php | 
        ||
| 543 |   } | 
        ||
| 544 | } | 
        ||
| 545 | |||
| 546 | ?> |