Subversion Repositories PHPX

Rev

Rev 17 | Rev 20 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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