@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.)
hq.recaptime.dev/wiki/Phorge
phorge
phabricator
1<?php
2
3final class PhabricatorSourceDocumentEngine
4 extends PhabricatorTextDocumentEngine {
5
6 const ENGINEKEY = 'source';
7
8 public function getViewAsLabel(PhabricatorDocumentRef $ref) {
9 return pht('View as Source');
10 }
11
12 public function canConfigureHighlighting(PhabricatorDocumentRef $ref) {
13 return true;
14 }
15
16 public function canBlame(PhabricatorDocumentRef $ref) {
17 // Since 2025, the features 'blame' and 'coverage' require login,
18 // due to aggressive LLM/AI web scrapers following all these links,
19 // decreasing server performance.
20 // Scrapers are invited to pull code repos via a command line checkout.
21 return $this->getViewer()->isLoggedIn();
22 }
23
24 protected function getDocumentIconIcon(PhabricatorDocumentRef $ref) {
25 return 'fa-code';
26 }
27
28 protected function getContentScore(PhabricatorDocumentRef $ref) {
29 return 1500;
30 }
31
32 protected function newDocumentContent(PhabricatorDocumentRef $ref) {
33 $content = $this->loadTextData($ref);
34
35 $messages = array();
36
37 $highlighting = $this->getHighlightingConfiguration();
38 if ($highlighting !== null) {
39 $content = PhabricatorSyntaxHighlighter::highlightWithLanguage(
40 $highlighting,
41 $content);
42 } else {
43 $highlight_limit = DifferentialChangesetParser::HIGHLIGHT_BYTE_LIMIT;
44 if (strlen($content) > $highlight_limit) {
45 $messages[] = $this->newMessage(
46 pht(
47 'This file is larger than %s, so syntax highlighting was skipped.',
48 phutil_format_bytes($highlight_limit)));
49 } else {
50 $content = PhabricatorSyntaxHighlighter::highlightWithFilename(
51 $ref->getName(),
52 $content);
53 }
54 }
55
56 $options = array();
57 if ($ref->getBlameURI() && $this->getBlameEnabled()
58 && $this->canBlame($ref)) {
59 $content = phutil_split_lines($content);
60 $blame = range(1, count($content));
61 $blame = array_fuse($blame);
62 $options['blame'] = $blame;
63 }
64
65 if ($ref->getCoverage()) {
66 $options['coverage'] = $ref->getCoverage();
67 }
68
69 return array(
70 $messages,
71 $this->newTextDocumentContent($ref, $content, $options),
72 );
73 }
74
75}