Page MenuHomePhabricator

D19239.diff
No OneTemporary

D19239.diff

diff --git a/resources/celerity/map.php b/resources/celerity/map.php
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -9,8 +9,8 @@
'names' => array(
'conpherence.pkg.css' => 'e68cf1fa',
'conpherence.pkg.js' => '15191c65',
- 'core.pkg.css' => '97dc0e74',
- 'core.pkg.js' => '8581cd02',
+ 'core.pkg.css' => '6da3c0e5',
+ 'core.pkg.js' => '932d60d4',
'differential.pkg.css' => '113e692c',
'differential.pkg.js' => 'f6d809c0',
'diffusion.pkg.css' => 'a2d17c7d',
@@ -168,7 +168,7 @@
'rsrc/css/phui/phui-object-box.css' => '9cff003c',
'rsrc/css/phui/phui-pager.css' => 'edcbc226',
'rsrc/css/phui/phui-pinboard-view.css' => '2495140e',
- 'rsrc/css/phui/phui-property-list-view.css' => 'ef864066',
+ 'rsrc/css/phui/phui-property-list-view.css' => '6ef560df',
'rsrc/css/phui/phui-remarkup-preview.css' => '54a34863',
'rsrc/css/phui/phui-segment-bar-view.css' => 'b1d1b892',
'rsrc/css/phui/phui-spacing.css' => '042804d6',
@@ -392,7 +392,7 @@
'rsrc/js/application/diffusion/behavior-pull-lastmodified.js' => 'f01586dc',
'rsrc/js/application/doorkeeper/behavior-doorkeeper-tag.js' => '1db13e70',
'rsrc/js/application/drydock/drydock-live-operation-status.js' => '901935ef',
- 'rsrc/js/application/files/behavior-document-engine.js' => 'f6d6f389',
+ 'rsrc/js/application/files/behavior-document-engine.js' => '396ef112',
'rsrc/js/application/files/behavior-icon-composer.js' => '8499b6ab',
'rsrc/js/application/files/behavior-launch-icon-composer.js' => '48086888',
'rsrc/js/application/harbormaster/behavior-harbormaster-log.js' => '191b4909',
@@ -508,7 +508,7 @@
'rsrc/js/phui/behavior-phui-submenu.js' => 'a6f7a73b',
'rsrc/js/phui/behavior-phui-tab-group.js' => '0a0b10e9',
'rsrc/js/phuix/PHUIXActionListView.js' => 'b5c256b8',
- 'rsrc/js/phuix/PHUIXActionView.js' => '442efd08',
+ 'rsrc/js/phuix/PHUIXActionView.js' => 'ed18356a',
'rsrc/js/phuix/PHUIXAutocomplete.js' => '7fa5c915',
'rsrc/js/phuix/PHUIXButtonView.js' => '8a91e1ac',
'rsrc/js/phuix/PHUIXDropdownMenu.js' => '04b2ae03',
@@ -607,7 +607,7 @@
'javelin-behavior-diffusion-jump-to' => '73d09eef',
'javelin-behavior-diffusion-locate-file' => '6d3e1947',
'javelin-behavior-diffusion-pull-lastmodified' => 'f01586dc',
- 'javelin-behavior-document-engine' => 'f6d6f389',
+ 'javelin-behavior-document-engine' => '396ef112',
'javelin-behavior-doorkeeper-tag' => '1db13e70',
'javelin-behavior-drydock-live-operation-status' => '901935ef',
'javelin-behavior-durable-column' => '2ae077e1',
@@ -850,7 +850,7 @@
'phui-oi-simple-ui-css' => 'a8beebea',
'phui-pager-css' => 'edcbc226',
'phui-pinboard-view-css' => '2495140e',
- 'phui-property-list-view-css' => 'ef864066',
+ 'phui-property-list-view-css' => '6ef560df',
'phui-remarkup-preview-css' => '54a34863',
'phui-segment-bar-view-css' => 'b1d1b892',
'phui-spacing-css' => '042804d6',
@@ -864,7 +864,7 @@
'phui-workcard-view-css' => 'cca5fa92',
'phui-workpanel-view-css' => 'a3a63478',
'phuix-action-list-view' => 'b5c256b8',
- 'phuix-action-view' => '442efd08',
+ 'phuix-action-view' => 'ed18356a',
'phuix-autocomplete' => '7fa5c915',
'phuix-button-view' => '8a91e1ac',
'phuix-dropdown-menu' => '04b2ae03',
@@ -1114,6 +1114,11 @@
'javelin-dom',
'javelin-vector',
),
+ '396ef112' => array(
+ 'javelin-behavior',
+ 'javelin-dom',
+ 'javelin-stratcom',
+ ),
'3ab51e2c' => array(
'javelin-behavior',
'javelin-behavior-device',
@@ -1184,11 +1189,6 @@
'javelin-workflow',
'javelin-workboard-controller',
),
- '442efd08' => array(
- 'javelin-install',
- 'javelin-dom',
- 'javelin-util',
- ),
'44959b73' => array(
'javelin-util',
'javelin-uri',
@@ -2125,6 +2125,11 @@
'javelin-stratcom',
'javelin-vector',
),
+ 'ed18356a' => array(
+ 'javelin-install',
+ 'javelin-dom',
+ 'javelin-util',
+ ),
'edf8a145' => array(
'javelin-behavior',
'javelin-uri',
@@ -2153,11 +2158,6 @@
'javelin-util',
'javelin-reactor',
),
- 'f6d6f389' => array(
- 'javelin-behavior',
- 'javelin-dom',
- 'javelin-stratcom',
- ),
'f829edb3' => array(
'javelin-view',
'javelin-install',
diff --git a/src/applications/files/controller/PhabricatorFileInfoController.php b/src/applications/files/controller/PhabricatorFileInfoController.php
--- a/src/applications/files/controller/PhabricatorFileInfoController.php
+++ b/src/applications/files/controller/PhabricatorFileInfoController.php
@@ -423,10 +423,12 @@
}
$view_icon = $candidate_engine->getViewAsIconIcon($ref);
+ $view_color = $candidate_engine->getViewAsIconColor($ref);
$views[] = array(
'viewKey' => $candidate_engine->getDocumentEngineKey(),
'icon' => $view_icon,
+ 'color' => $view_color,
'name' => $label,
'engineURI' => $candidate_engine->getRenderURI($ref),
);
diff --git a/src/applications/files/document/PhabricatorAudioDocumentEngine.php b/src/applications/files/document/PhabricatorAudioDocumentEngine.php
--- a/src/applications/files/document/PhabricatorAudioDocumentEngine.php
+++ b/src/applications/files/document/PhabricatorAudioDocumentEngine.php
@@ -13,6 +13,10 @@
return 'fa-file-sound-o';
}
+ protected function getByteLengthLimit() {
+ return null;
+ }
+
protected function canRenderDocumentType(PhabricatorDocumentRef $ref) {
$file = $ref->getFile();
if ($file) {
diff --git a/src/applications/files/document/PhabricatorDocumentEngine.php b/src/applications/files/document/PhabricatorDocumentEngine.php
--- a/src/applications/files/document/PhabricatorDocumentEngine.php
+++ b/src/applications/files/document/PhabricatorDocumentEngine.php
@@ -22,6 +22,18 @@
PhabricatorDocumentRef $ref);
final public function newDocument(PhabricatorDocumentRef $ref) {
+ $can_complete = $this->canRenderCompleteDocument($ref);
+ $can_partial = $this->canRenderPartialDocument($ref);
+
+ if (!$can_complete && !$can_partial) {
+ return $this->newMessage(
+ pht(
+ 'This document is too large to be rendered inline. (The document '.
+ 'is %s bytes, the limit for this engine is %s bytes.)',
+ new PhutilNumber($ref->getByteLength()),
+ new PhutilNumber($this->getByteLengthLimit())));
+ }
+
return $this->newDocumentContent($ref);
}
@@ -51,20 +63,49 @@
final public function newSortVector(PhabricatorDocumentRef $ref) {
$content_score = $this->getContentScore($ref);
+ // Prefer engines which can render the entire file over engines which
+ // can only render a header, and engines which can render a header over
+ // engines which can't render anything.
+ if ($this->canRenderCompleteDocument($ref)) {
+ $limit_score = 0;
+ } else if ($this->canRenderPartialDocument($ref)) {
+ $limit_score = 1;
+ } else {
+ $limit_score = 2;
+ }
+
return id(new PhutilSortVector())
+ ->addInt($limit_score)
->addInt(-$content_score);
}
- protected function getContentScore() {
+ protected function getContentScore(PhabricatorDocumentRef $ref) {
return 2000;
}
abstract public function getViewAsLabel(PhabricatorDocumentRef $ref);
public function getViewAsIconIcon(PhabricatorDocumentRef $ref) {
+ $can_complete = $this->canRenderCompleteDocument($ref);
+ $can_partial = $this->canRenderPartialDocument($ref);
+
+ if (!$can_complete && !$can_partial) {
+ return 'fa-times';
+ }
+
return $this->getDocumentIconIcon($ref);
}
+ public function getViewAsIconColor(PhabricatorDocumentRef $ref) {
+ $can_complete = $this->canRenderCompleteDocument($ref);
+
+ if (!$can_complete) {
+ return 'grey';
+ }
+
+ return null;
+ }
+
public function getRenderURI(PhabricatorDocumentRef $ref) {
$file = $ref->getFile();
if (!$file) {
@@ -107,4 +148,33 @@
return array_select_keys($engines, array_keys($vectors));
}
+ protected function getByteLengthLimit() {
+ return (1024 * 1024 * 8);
+ }
+
+ protected function canRenderCompleteDocument(PhabricatorDocumentRef $ref) {
+ $limit = $this->getByteLengthLimit();
+ if ($limit) {
+ $length = $ref->getByteLength();
+ if ($length > $limit) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ protected function canRenderPartialDocument(PhabricatorDocumentRef $ref) {
+ return false;
+ }
+
+ protected function newMessage($message) {
+ return phutil_tag(
+ 'div',
+ array(
+ 'class' => 'document-engine-error',
+ ),
+ $message);
+ }
+
}
diff --git a/src/applications/files/document/PhabricatorDocumentRef.php b/src/applications/files/document/PhabricatorDocumentRef.php
--- a/src/applications/files/document/PhabricatorDocumentRef.php
+++ b/src/applications/files/document/PhabricatorDocumentRef.php
@@ -56,7 +56,7 @@
return $this;
}
- public function getLength() {
+ public function getByteLength() {
if ($this->byteLength !== null) {
return $this->byteLength;
}
@@ -68,9 +68,15 @@
return null;
}
- public function loadData() {
+ public function loadData($begin = null, $end = null) {
if ($this->file) {
- return $this->file->loadFileData();
+ $iterator = $this->file->getFileDataIterator($begin, $end);
+
+ $result = '';
+ foreach ($iterator as $chunk) {
+ $result .= $chunk;
+ }
+ return $result;
}
throw new PhutilMethodNotImplementedException();
diff --git a/src/applications/files/document/PhabricatorHexdumpDocumentEngine.php b/src/applications/files/document/PhabricatorHexdumpDocumentEngine.php
--- a/src/applications/files/document/PhabricatorHexdumpDocumentEngine.php
+++ b/src/applications/files/document/PhabricatorHexdumpDocumentEngine.php
@@ -13,7 +13,11 @@
return 'fa-microchip';
}
- protected function getContentScore() {
+ protected function getByteLengthLimit() {
+ return (1024 * 1024 * 1);
+ }
+
+ protected function getContentScore(PhabricatorDocumentRef $ref) {
return 500;
}
@@ -21,8 +25,23 @@
return true;
}
+ protected function canRenderPartialDocument(PhabricatorDocumentRef $ref) {
+ return true;
+ }
+
protected function newDocumentContent(PhabricatorDocumentRef $ref) {
- $content = $ref->loadData();
+ $limit = $this->getByteLengthLimit();
+ $length = $ref->getByteLength();
+
+ $is_partial = false;
+ if ($limit) {
+ if ($length > $limit) {
+ $is_partial = true;
+ $length = $limit;
+ }
+ }
+
+ $content = $ref->loadData(null, $length);
$output = array();
$offset = 0;
@@ -48,7 +67,19 @@
),
$output);
- return $container;
+ $message = null;
+ if ($is_partial) {
+ $message = $this->newMessage(
+ pht(
+ 'This document is too large to be completely rendered inline. The '.
+ 'first %s bytes are shown.',
+ new PhutilNumber($limit)));
+ }
+
+ return array(
+ $message,
+ $container,
+ );
}
private function renderHex($bytes) {
diff --git a/src/applications/files/document/PhabricatorImageDocumentEngine.php b/src/applications/files/document/PhabricatorImageDocumentEngine.php
--- a/src/applications/files/document/PhabricatorImageDocumentEngine.php
+++ b/src/applications/files/document/PhabricatorImageDocumentEngine.php
@@ -13,6 +13,10 @@
return 'fa-file-image-o';
}
+ protected function getByteLengthLimit() {
+ return (1024 * 1024 * 64);
+ }
+
protected function canRenderDocumentType(PhabricatorDocumentRef $ref) {
$file = $ref->getFile();
if ($file) {
diff --git a/src/applications/files/document/PhabricatorVideoDocumentEngine.php b/src/applications/files/document/PhabricatorVideoDocumentEngine.php
--- a/src/applications/files/document/PhabricatorVideoDocumentEngine.php
+++ b/src/applications/files/document/PhabricatorVideoDocumentEngine.php
@@ -9,6 +9,16 @@
return pht('View as Video');
}
+ protected function getContentScore(PhabricatorDocumentRef $ref) {
+ // Some video documents can be rendered as either video or audio, but we
+ // want to prefer video.
+ return 2500;
+ }
+
+ protected function getByteLengthLimit() {
+ return null;
+ }
+
protected function getDocumentIconIcon(PhabricatorDocumentRef $ref) {
return 'fa-film';
}
diff --git a/src/applications/files/document/PhabricatorVoidDocumentEngine.php b/src/applications/files/document/PhabricatorVoidDocumentEngine.php
--- a/src/applications/files/document/PhabricatorVoidDocumentEngine.php
+++ b/src/applications/files/document/PhabricatorVoidDocumentEngine.php
@@ -13,10 +13,14 @@
return 'fa-file';
}
- protected function getContentScore() {
+ protected function getContentScore(PhabricatorDocumentRef $ref) {
return 1000;
}
+ protected function getByteLengthLimit() {
+ return null;
+ }
+
protected function canRenderDocumentType(PhabricatorDocumentRef $ref) {
return true;
}
diff --git a/webroot/rsrc/css/phui/phui-property-list-view.css b/webroot/rsrc/css/phui/phui-property-list-view.css
--- a/webroot/rsrc/css/phui/phui-property-list-view.css
+++ b/webroot/rsrc/css/phui/phui-property-list-view.css
@@ -233,9 +233,11 @@
}
.document-engine-error {
- margin: 20px auto;
+ margin: 20px;
+ padding: 12px;
text-align: center;
color: {$redtext};
+ background: {$sh-redbackground};
}
.document-engine-hexdump {
diff --git a/webroot/rsrc/js/application/files/behavior-document-engine.js b/webroot/rsrc/js/application/files/behavior-document-engine.js
--- a/webroot/rsrc/js/application/files/behavior-document-engine.js
+++ b/webroot/rsrc/js/application/files/behavior-document-engine.js
@@ -27,6 +27,7 @@
view = new JX.PHUIXActionView()
.setName(spec.name)
.setIcon(spec.icon)
+ .setIconColor(spec.color)
.setHref(spec.engineURI);
view.setHandler(JX.bind(null, function(spec, e) {
diff --git a/webroot/rsrc/js/phuix/PHUIXActionView.js b/webroot/rsrc/js/phuix/PHUIXActionView.js
--- a/webroot/rsrc/js/phuix/PHUIXActionView.js
+++ b/webroot/rsrc/js/phuix/PHUIXActionView.js
@@ -12,6 +12,7 @@
_node: null,
_name: null,
_icon: 'none',
+ _iconColor: null,
_disabled: false,
_label: false,
_handler: null,
@@ -79,6 +80,12 @@
return this;
},
+ setIconColor: function(color) {
+ this._iconColor = color;
+ this._buildIconNode(true);
+ return this;
+ },
+
setHref: function(href) {
this._href = href;
this._buildNameNode(true);
@@ -129,6 +136,10 @@
icon_class = icon_class + ' grey';
}
+ if (this._iconColor) {
+ icon_class = icon_class + ' ' + this._iconColor;
+ }
+
JX.DOM.alterClass(node, icon_class, true);
if (this._iconNode && this._iconNode.parentNode) {

File Metadata

Mime Type
text/plain
Expires
Wed, Mar 19, 5:47 AM (3 d, 4 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7710899
Default Alt Text
D19239.diff (14 KB)

Event Timeline