Author: Sergey Panteleev (saundefined)
Date: 2025-11-08T21:18:33+03:00

Commit: 
https://github.com/php/web-php/commit/374ba05ef6bac375be3896fc637734004eedc38a
Raw diff: 
https://github.com/php/web-php/commit/374ba05ef6bac375be3896fc637734004eedc38a.diff

Highlight focus comment

Changed paths:
  M  include/layout.inc
  M  releases/8.5/release.inc
  M  styles/theme-base.css


Diff:

diff --git a/include/layout.inc b/include/layout.inc
index 83efa1c6bb..9b0d3181b0 100644
--- a/include/layout.inc
+++ b/include/layout.inc
@@ -15,39 +15,86 @@ ini_set('highlight.string',  'string');
 ini_set('highlight.html',    'html');
 
 // Highlight PHP code
-function highlight_php($code, $return = false)
+function highlight_php(string $code, bool $return = false): ?string
 {
-    $highlighted = highlight_string($code, true);
+    $hasFocusTag = preg_match('!//.*\[focus]!', $code);
+
+    $highlighted = highlight_php_process_lines($code, $hasFocusTag);
+
+    if ($return) {
+        return $highlighted;
+    }
+
+    echo $highlighted;
+    return null;
+}
+
+function highlight_php_process_lines(string $code, bool $hasFocusTag): string
+{
+    $lines = explode(PHP_EOL, $code);
+    $processedLines = [];
+
+    foreach ($lines as $line) {
+        if ($line === '') {
+            $processedLines[] = '<br />';
+            continue;
+        }
+
+        $processedLines[] = highlight_php_process_single_line($line);
+    }
+
+    $highlighted = implode('', $processedLines);
 
-    // Use this ugly hack for now to avoid code snippets with bad syntax 
screwing up the highlighter
     if (strstr($highlighted, "include/layout.inc</b>")) {
-        $highlighted = '<span class="html">' . nl2br(htmlentities($code, 
ENT_HTML5), false) . "</span>";
+        return format_as_plain_code($code);
     }
 
-    // Fix output to use CSS classes and wrap well
-    $highlighted = '<div class="phpcode">' . strtr(
-        $highlighted,
-        [
-            '&nbsp;' => ' ',
-            "\n" => '',
+    return format_highlighted_output($highlighted, $hasFocusTag);
+}
 
-            '<span style="color: ' => '<span class="',
-        ],
-    ) . '</div>';
+function highlight_php_process_single_line(string $line): string
+{
+    $highlighted = highlight_string('<?php ' . $line, true);
+    $highlighted = str_replace('&lt;?php&nbsp;', '', $highlighted);
 
-    if ($return) { return $highlighted; }
-    echo $highlighted;
-    return null;
+    $isFocus = preg_match('!//.*\[focus]!', $line);
+
+    $highlighted = preg_replace('!//[^<]*\s*\[focus]!', '', $highlighted);
+
+    return '<span class="' . ($isFocus ? 'focus' : 'fade') . '">' . 
$highlighted . '</span>';
+}
+
+function format_as_plain_code(string $code): string
+{
+    return '<div class="phpcode"><span class="html">' .
+           nl2br(htmlentities($code, ENT_HTML5), false) .
+           '</span></div>';
 }
 
-// Same as highlight_php() but does not require '<?php' in $code
-function highlight_php_trimmed($code, $return = false)
+function format_highlighted_output(string $highlighted, bool $hasFocus): string
+{
+    return '<div class="phpcode' . ($hasFocus ? ' phpcode--focused' : '') . 
'">' .
+           strtr(
+               $highlighted,
+               [
+                   '&nbsp;' => ' ',
+                   "\n" => '',
+                   '<span style="color: ' => '<span class="',
+               ],
+           ) .
+           '</div>';
+}
+
+function highlight_php_trimmed(string $code, bool $return = false): ?string
 {
     $code = "<?php\n" . $code;
     $highlighted_code = highlight_php($code, true);
     $highlighted_code = preg_replace("!&lt;\?php(<br />)+!", '', 
$highlighted_code, 1);
 
-    if ($return) { return $highlighted_code; }
+    if ($return) {
+        return $highlighted_code;
+    }
+
     echo $highlighted_code;
     return null;
 }
diff --git a/releases/8.5/release.inc b/releases/8.5/release.inc
index 246c654a33..e53b6cc279 100644
--- a/releases/8.5/release.inc
+++ b/releases/8.5/release.inc
@@ -267,9 +267,11 @@ final class Stopwatch
     public function stopLap()
     {
         $fromStart = hrtime(true) - $this->start;
-        $lastLap = $this->laps !== []
-            ? $this->laps[array_key_last($this->laps)]
-            : 0;
+
+        $lastLap = $this->laps !== [] // [focus]
+            ? $this->laps[array_key_last($this->laps)] // [focus]
+            : 0; // [focus]
+
         $lapDuration = $fromStart - $lastLap;
 
         $this->laps[] = $fromStart;
@@ -306,7 +308,9 @@ final class Stopwatch
     public function stopLap()
     {
         $fromStart = hrtime(true) - $this->start;
-        $lastLap = array_last($this->laps) ?? 0;
+
+        $lastLap = array_last($this->laps) ?? 0; // [focus]
+
         $lapDuration = $fromStart - $lastLap;
 
         $this->laps[] = $fromStart;
diff --git a/styles/theme-base.css b/styles/theme-base.css
index 59b4ad6329..6674cb9545 100644
--- a/styles/theme-base.css
+++ b/styles/theme-base.css
@@ -501,6 +501,15 @@ dl dd {
     overflow-x: auto;
 }
 
+.phpcode--focused .fade {
+    opacity: .5;
+    transition: .2s all;
+}
+
+.phpcode--focused:hover .fade {
+    opacity: 1;
+}
+
 .phpcode, div.classsynopsis {
     text-align: left;
 }

Reply via email to