Page MenuHomePhabricator

D12692.diff
No OneTemporary

D12692.diff

diff --git a/src/infrastructure/markup/rule/PhabricatorObjectRemarkupRule.php b/src/infrastructure/markup/rule/PhabricatorObjectRemarkupRule.php
--- a/src/infrastructure/markup/rule/PhabricatorObjectRemarkupRule.php
+++ b/src/infrastructure/markup/rule/PhabricatorObjectRemarkupRule.php
@@ -8,8 +8,10 @@
abstract protected function getObjectNamePrefix();
abstract protected function loadObjects(array $ids);
+ private $whitelist;
+
public function getPriority() {
- return 450.0;
+ return 350.0;
}
protected function getObjectNamePrefixBeginsWithWordCharacter() {
@@ -28,7 +30,7 @@
protected function loadHandles(array $objects) {
$phids = mpull($objects, 'getPHID');
- $viewer = $this->getEngine()->getConfig('viewer');
+ $viewer = $this->getEngine()->getConfig('viewer');
$handles = $viewer->loadHandles($phids);
$handles = iterator_to_array($handles);
@@ -53,7 +55,7 @@
return $uri;
}
- protected function renderObjectRefForAnyMedia (
+ protected function renderObjectRefForAnyMedia(
$object,
PhabricatorObjectHandle $handle,
$anchor,
@@ -94,8 +96,8 @@
}
$attr = array(
- 'phid' => $handle->getPHID(),
- 'closed' => ($handle->getStatus() == $status_closed),
+ 'phid' => $handle->getPHID(),
+ 'closed' => $handle->getStatus() == $status_closed,
);
return $this->renderHovertag($text, $href, $attr);
@@ -128,8 +130,8 @@
$href = $handle->getURI();
$status_closed = PhabricatorObjectHandle::STATUS_CLOSED;
$attr = array(
- 'phid' => $handle->getPHID(),
- 'closed' => ($handle->getStatus() == $status_closed),
+ 'phid' => $handle->getPHID(),
+ 'closed' => $handle->getStatus() == $status_closed,
);
return $this->renderHovertag($name, $href, $attr);
@@ -141,9 +143,9 @@
PhabricatorObjectHandle $handle) {
$status_closed = PhabricatorObjectHandle::STATUS_CLOSED;
- $strikethrough = $handle->getStatus() == $status_closed ?
- 'text-decoration: line-through;' :
- 'text-decoration: none;';
+ $strikethrough = $handle->getStatus() == $status_closed
+ ? 'text-decoration: line-through;'
+ : 'text-decoration: none;';
return phutil_tag(
'a',
@@ -172,6 +174,11 @@
public function apply($text) {
$text = preg_replace_callback(
+ $this->getObjectHyperlinkReferencePattern(),
+ array($this, 'markupObjectHyperlinkReference'),
+ $text);
+
+ $text = preg_replace_callback(
$this->getObjectEmbedPattern(),
array($this, 'markupObjectEmbed'),
$text);
@@ -185,9 +192,8 @@
}
private function getObjectEmbedPattern() {
- $prefix = $this->getObjectNamePrefix();
- $prefix = preg_quote($prefix);
- $id = $this->getObjectIDPattern();
+ $prefix = preg_quote($this->getObjectNamePrefix());
+ $id = $this->getObjectIDPattern();
return '(\B{'.$prefix.'('.$id.')([,\s](?:[^}\\\\]|\\\\.)*)?}\B)u';
}
@@ -211,13 +217,16 @@
// The "(?<![#-])" prevents us from linking "#abcdef" or similar, and
// "ABC-T1" (see T5714).
-
+ //
// The "\b" allows us to link "(abcdef)" or similar without linking things
// in the middle of words.
-
return '((?<![#-])'.$boundary.$prefix.'('.$id.')(?:#([-\w\d]+))?(?!\w))u';
}
+ private function getObjectHyperlinkReferencePattern() {
+ return '@(\w{3,}://[^\s'.PhutilRemarkupBlockStorage::MAGIC_BYTE.']+)@';
+ }
+
/**
* Extract matched object references from a block of text.
@@ -229,6 +238,13 @@
* @return wild Matches, suitable for writing unit tests against.
*/
public function extractReferences($text) {
+ $hyperlink_ref_matches = null;
+ preg_match_all(
+ $this->getObjectHyperlinkReferencePattern(),
+ $text,
+ $hyperlink_ref_matches,
+ PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
+
$embed_matches = null;
preg_match_all(
$this->getObjectEmbedPattern(),
@@ -246,8 +262,9 @@
$results = array();
$sets = array(
'embed' => $embed_matches,
- 'ref' => $ref_matches,
+ 'ref' => array_merge($hyperlink_ref_matches, $ref_matches),
);
+
foreach ($sets as $type => $matches) {
$formatted = array();
foreach ($matches as $match) {
@@ -255,11 +272,14 @@
'offset' => $match[1][1],
'id' => $match[1][0],
);
+
if (isset($match[2][0])) {
$format['tail'] = $match[2][0];
}
+
$formatted[] = $format;
}
+
$results[$type] = $formatted;
}
@@ -292,25 +312,56 @@
));
}
+ public function markupObjectHyperlinkReference(array $matches) {
+ if (!$this->isFlatText($matches[0])) {
+ return $matches[0];
+ }
+
+ $uri = new PhutilURI($matches[1]);
+
+ $base_uri = PhabricatorEnv::getEnvConfig('phabricator.base-uri');
+ $base_uri = new PhutilURI($base_uri);
+
+ if (strtolower($uri->getDomain()) != strtolower($base_uri->getDomain())) {
+ return $matches[0];
+ }
+
+ $path = substr($uri->getPath(), 1);
+
+ if (preg_match($this->getObjectEmbedPattern(), $path)) {
+ return $this->apply($path);
+ }
+
+ if (preg_match($this->getObjectReferencePattern(), $path)) {
+ return $this->apply($path);
+ }
+
+ $rule = id(new PhutilRemarkupHyperlinkRule())
+ ->setEngine($this->getEngine());
+ $rule->apply($matches[0]);
+ return $matches[0];
+ }
+
private function markupObject(array $params) {
if (!$this->shouldMarkupObject($params)) {
return $params['original'];
}
- $regex = trim(
- PhabricatorEnv::getEnvConfig('remarkup.ignored-object-names'));
+ $regex = PhabricatorEnv::getEnvConfig('remarkup.ignored-object-names');
+ $regex = trim($regex);
+
if ($regex && preg_match($regex, $params['original'])) {
return $params['original'];
}
$engine = $this->getEngine();
- $token = $engine->storeText('x');
+ $token = $engine->storeText('x');
$metadata_key = self::KEY_RULE_OBJECT.'.'.$this->getObjectNamePrefix();
$metadata = $engine->getTextMetadata($metadata_key, array());
$metadata[] = array(
- 'token' => $token,
+ 'token' => $token,
) + $params;
$engine->setTextMetadata($metadata_key, $metadata);
@@ -327,21 +378,18 @@
return;
}
-
$ids = ipull($metadata, 'id');
$objects = $this->loadObjects($ids);
// For objects that are invalid or which the user can't see, just render
// the original text.
-
+ //
// TODO: We should probably distinguish between these cases and render a
// "you can't see this" state for nonvisible objects.
foreach ($metadata as $key => $spec) {
if (empty($objects[$spec['id']])) {
- $engine->overwriteStoredText(
- $spec['token'],
- $spec['original']);
+ $engine->overwriteStoredText($spec['token'], $spec['original']);
unset($metadata[$key]);
}
}
@@ -358,13 +406,13 @@
$object = $objects[$spec['id']];
switch ($spec['type']) {
case 'ref':
-
$view = $this->renderObjectRefForAnyMedia(
$object,
$handle,
$spec['anchor'],
$spec['id']);
break;
+
case 'embed':
$spec['options'] = $this->assertFlatText($spec['options']);
$view = $this->renderObjectEmbedForAnyMedia(

File Metadata

Mime Type
text/plain
Expires
Fri, Nov 29, 11:55 AM (21 h, 23 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6802258
Default Alt Text
D12692.diff (7 KB)

Event Timeline