diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -179,12 +179,15 @@ 'CalendarTimeUtil' => 'applications/calendar/util/CalendarTimeUtil.php', 'CalendarTimeUtilTestCase' => 'applications/calendar/__tests__/CalendarTimeUtilTestCase.php', 'CelerityAPI' => 'applications/celerity/CelerityAPI.php', + 'CelerityDefaultPostprocessor' => 'applications/celerity/postprocessor/CelerityDefaultPostprocessor.php', + 'CelerityHighContrastPostprocessor' => 'applications/celerity/postprocessor/CelerityHighContrastPostprocessor.php', 'CelerityManagementMapWorkflow' => 'applications/celerity/management/CelerityManagementMapWorkflow.php', 'CelerityManagementWorkflow' => 'applications/celerity/management/CelerityManagementWorkflow.php', 'CelerityPhabricatorResourceController' => 'applications/celerity/controller/CelerityPhabricatorResourceController.php', 'CelerityPhabricatorResources' => 'applications/celerity/resources/CelerityPhabricatorResources.php', 'CelerityPhysicalResources' => 'applications/celerity/resources/CelerityPhysicalResources.php', 'CelerityPhysicalResourcesTestCase' => 'applications/celerity/resources/__tests__/CelerityPhysicalResourcesTestCase.php', + 'CelerityPostprocessor' => 'applications/celerity/postprocessor/CelerityPostprocessor.php', 'CelerityResourceController' => 'applications/celerity/controller/CelerityResourceController.php', 'CelerityResourceGraph' => 'applications/celerity/CelerityResourceGraph.php', 'CelerityResourceMap' => 'applications/celerity/CelerityResourceMap.php', @@ -3504,12 +3507,15 @@ 'CalendarTimeUtil' => 'Phobject', 'CalendarTimeUtilTestCase' => 'PhabricatorTestCase', 'CelerityAPI' => 'Phobject', + 'CelerityDefaultPostprocessor' => 'CelerityPostprocessor', + 'CelerityHighContrastPostprocessor' => 'CelerityPostprocessor', 'CelerityManagementMapWorkflow' => 'CelerityManagementWorkflow', 'CelerityManagementWorkflow' => 'PhabricatorManagementWorkflow', 'CelerityPhabricatorResourceController' => 'CelerityResourceController', 'CelerityPhabricatorResources' => 'CelerityResourcesOnDisk', 'CelerityPhysicalResources' => 'CelerityResources', 'CelerityPhysicalResourcesTestCase' => 'PhabricatorTestCase', + 'CelerityPostprocessor' => 'Phobject', 'CelerityResourceController' => 'PhabricatorController', 'CelerityResourceGraph' => 'AbstractDirectedGraph', 'CelerityResourceMap' => 'Phobject', diff --git a/src/applications/celerity/CelerityResourceTransformer.php b/src/applications/celerity/CelerityResourceTransformer.php --- a/src/applications/celerity/CelerityResourceTransformer.php +++ b/src/applications/celerity/CelerityResourceTransformer.php @@ -7,6 +7,17 @@ private $celerityMap; private $translateURICallback; private $currentPath; + private $postprocessor; + private $variableMap; + + public function setPostprocessor($postprocessor) { + $this->postprocessor = $postprocessor; + return $this; + } + + public function getPostprocessor() { + return $this->postprocessor; + } public function setTranslateURICallback($translate_uricallback) { $this->translateURICallback = $translate_uricallback; @@ -169,178 +180,27 @@ $data); } - public static function getCSSVariableMap() { - return array( - // Fonts - 'basefont' => "13px 'Segoe UI', 'Segoe UI Web Regular', ". - "'Segoe UI Symbol', 'Lato', 'Helvetica Neue', Helvetica, ". - "Arial, sans-serif", - - 'fontfamily' => "'Segoe UI', 'Segoe UI Web Regular', ". - "'Segoe UI Symbol', 'Lato', 'Helvetica Neue', Helvetica, ". - "Arial, sans-serif", - - // Drop Shadow - 'dropshadow' => '0 1px 6px rgba(0, 0, 0, .25)', - 'whitetextshadow' => '0 1px 0 rgba(255, 255, 255, 1)', - - // Anchors - 'anchor' => '#136CB2', - - // Base Colors - 'red' => '#c0392b', - 'lightred' => '#f4dddb', - 'orange' => '#e67e22', - 'lightorange' => '#f7e2d4', - 'yellow' => '#f1c40f', - 'lightyellow' => '#fdf5d4', - 'green' => '#139543', - 'lightgreen' => '#d7eddf', - 'blue' => '#2980b9', - 'lightblue' => '#daeaf3', - 'sky' => '#3498db', - 'lightsky' => '#ddeef9', - 'fire' => '#e62f17', - 'indigo' => '#6e5cb6', - 'lightindigo' => '#eae6f7', - 'pink' => '#da49be', - 'lightpink' => '#fbeaf8', - 'violet' => '#8e44ad', - 'lightviolet' => '#ecdff1', - 'charcoal' => '#4b4d51', - 'backdrop' => '#dadee7', - 'hoverwhite' => 'rgba(255,255,255,.6)', - 'hovergrey' => '#c5cbcf', - 'hoverblue' => '#eceff5', - 'hoverborder' => '#dfe1e9', - 'hoverselectedgrey' => '#bbc4ca', - 'hoverselectedblue' => '#e6e9ee', - - // Base Greys - 'lightgreyborder' => '#C7CCD9', - 'greyborder' => '#A1A6B0', - 'darkgreyborder' => '#676A70', - 'lightgreytext' => '#92969D', - 'greytext' => '#74777D', - 'darkgreytext' => '#4B4D51', - 'lightgreybackground' => '#F7F7F7', - 'greybackground' => '#EBECEE', - 'darkgreybackground' => '#DFE0E2', - - // Base Blues - 'thinblueborder' => '#DDE8EF', - 'lightblueborder' => '#BFCFDA', - 'blueborder' => '#8C98B8', - 'darkblueborder' => '#626E82', - 'lightbluebackground' => '#F8F9FC', - 'bluebackground' => '#DAE7FF', - 'lightbluetext' => '#8C98B8', - 'bluetext' => '#6B748C', - 'darkbluetext' => '#464C5C', - - // Base Greens - 'lightgreenborder' => '#bfdac1', - 'greenborder' => '#8cb89c', - 'greentext' => '#3e6d35', - 'lightgreenbackground' => '#e6f2e4', - - // Base Red - 'lightredborder' => '#f4c6c6', - 'redborder' => '#eb9797', - 'redtext' => '#802b2b', - 'lightredbackground' => '#f5e1e1', - - // Base Violet - 'lightvioletborder' => '#cfbddb', - 'violetborder' => '#b589ba', - 'violettext' => '#603c73', - 'lightvioletbackground' => '#e9dfee', - - // Shades are a more muted set of our base colors - // better suited to blending into other UIs. - - // Shade Red - 'sh-lightredborder' => '#efcfcf', - 'sh-redborder' => '#d1abab', - 'sh-redicon' => '#c85a5a', - 'sh-redtext' => '#a53737', - 'sh-redbackground' => '#f7e6e6', - - // Shade Orange - 'sh-lightorangeborder' => '#f8dcc3', - 'sh-orangeborder' => '#dbb99e', - 'sh-orangeicon' => '#e78331', - 'sh-orangetext' => '#ba6016', - 'sh-orangebackground' => '#fbede1', - - // Shade Yellow - 'sh-lightyellowborder' => '#e9dbcd', - 'sh-yellowborder' => '#c9b8a8', - 'sh-yellowicon' => '#9b946e', - 'sh-yellowtext' => '#726f56', - 'sh-yellowbackground' => '#fdf3da', - - // Shade Green - 'sh-lightgreenborder' => '#c6e6c7', - 'sh-greenborder' => '#a0c4a1', - 'sh-greenicon' => '#4ca74e', - 'sh-greentext' => '#326d34', - 'sh-greenbackground' => '#ddefdd', - - // Shade Blue - 'sh-lightblueborder' => '#cfdbe3', - 'sh-blueborder' => '#a7b5bf', - 'sh-blueicon' => '#6b748c', - 'sh-bluetext' => '#464c5c', - 'sh-bluebackground' => '#dee7f8', - - // Shade Indigo - 'sh-lightindigoborder' => '#d1c9ee', - 'sh-indigoborder' => '#bcb4da', - 'sh-indigoicon' => '#8672d4', - 'sh-indigotext' => '#6e5cb6', - 'sh-indigobackground' => '#eae6f7', - - // Shade Violet - 'sh-lightvioletborder' => '#e0d1e7', - 'sh-violetborder' => '#bcabc5', - 'sh-violeticon' => '#9260ad', - 'sh-violettext' => '#69427f', - 'sh-violetbackground' => '#efe8f3', - - // Shade Pink - 'sh-lightpinkborder' => '#f6d5ef', - 'sh-pinkborder' => '#d5aecd', - 'sh-pinkicon' => '#e26fcb', - 'sh-pinktext' => '#da49be', - 'sh-pinkbackground' => '#fbeaf8', - - // Shade Grey - 'sh-lightgreyborder' => '#d8d8d8', - 'sh-greyborder' => '#b2b2b2', - 'sh-greyicon' => '#757575', - 'sh-greytext' => '#555555', - 'sh-greybackground' => '#e7e7e7', - - // Shade Disabled - 'sh-lightdisabledborder' => '#e5e5e5', - 'sh-disabledborder' => '#cbcbcb', - 'sh-disabledicon' => '#bababa', - 'sh-disabledtext' => '#a6a6a6', - 'sh-disabledbackground' => '#f3f3f3', - - ); + public function getCSSVariableMap() { + $postprocessor_key = $this->getPostprocessor(); + $postprocessor = CelerityPostprocessor::getPostprocessor( + $postprocessor_key); + + if (!$postprocessor) { + $postprocessor = CelerityPostprocessor::getPostprocessor( + CelerityDefaultPostprocessor::POSTPROCESSOR_KEY); + } + + return $postprocessor->getVariables(); } public function replaceCSSVariable($matches) { - static $map; - if (!$map) { - $map = self::getCSSVariableMap(); + if (!$this->variableMap) { + $this->variableMap = $this->getCSSVariableMap(); } $var_name = $matches[1]; - if (empty($map[$var_name])) { + if (empty($this->variableMap[$var_name])) { $path = $this->currentPath; throw new Exception( pht( @@ -349,7 +209,7 @@ $var_name)); } - return $map[$var_name]; + return $this->variableMap[$var_name]; } public function replaceCSSPrintRule($matches) { diff --git a/src/applications/celerity/CelerityStaticResourceResponse.php b/src/applications/celerity/CelerityStaticResourceResponse.php --- a/src/applications/celerity/CelerityStaticResourceResponse.php +++ b/src/applications/celerity/CelerityStaticResourceResponse.php @@ -15,6 +15,7 @@ private $metadataBlock = 0; private $behaviors = array(); private $hasRendered = array(); + private $postProcessor; public function __construct() { if (isset($_REQUEST['__metablock__'])) { @@ -32,6 +33,18 @@ return $this->metadataBlock; } + public function setPostProcessor($post_processor) { + $this->postProcessor = $post_processor; + return $this; + } + + public function getPostProcessor() { + return $this->postProcessor; + } + + + + /** * Register a behavior for initialization. * @@ -300,6 +313,12 @@ $uri = $map->getURIForName($name); + // If we have a postprocessor selected, add it to the URI. + $postprocessor = $this->getPostProcessor(); + if ($postprocessor) { + $uri = preg_replace('@^/res/@', '/res/'.$postprocessor.'X/', $uri); + } + // In developer mode, we dump file modification times into the URI. When a // page is reloaded in the browser, any resources brought in by Ajax calls // do not trigger revalidation, so without this it's very difficult to get diff --git a/src/applications/celerity/application/PhabricatorCelerityApplication.php b/src/applications/celerity/application/PhabricatorCelerityApplication.php --- a/src/applications/celerity/application/PhabricatorCelerityApplication.php +++ b/src/applications/celerity/application/PhabricatorCelerityApplication.php @@ -22,6 +22,7 @@ return array( '/res/' => array( '(?:(?P[0-9]+)T/)?'. + '(?:(?P[^/]+)X/)?'. '(?P[^/]+)/'. '(?P[a-f0-9]{8})/'. '(?P.+\.(?:'.$extensions.'))' diff --git a/src/applications/celerity/controller/CelerityPhabricatorResourceController.php b/src/applications/celerity/controller/CelerityPhabricatorResourceController.php --- a/src/applications/celerity/controller/CelerityPhabricatorResourceController.php +++ b/src/applications/celerity/controller/CelerityPhabricatorResourceController.php @@ -11,6 +11,7 @@ private $path; private $hash; private $library; + private $postprocessor; public function getCelerityResourceMap() { return CelerityResourceMap::getNamedInstance($this->library); @@ -20,6 +21,7 @@ $this->path = $data['path']; $this->hash = $data['hash']; $this->library = $data['library']; + $this->postprocessor = idx($data, 'postprocessor'); } public function processRequest() { @@ -42,7 +44,12 @@ return id(new CelerityResourceTransformer()) ->setMinify($should_minify) + ->setPostprocessor($this->postprocessor) ->setCelerityMap($this->getCelerityResourceMap()); } + protected function getCacheKey($path) { + return parent::getCacheKey($path.';'.$this->postprocessor); + } + } diff --git a/src/applications/celerity/controller/CelerityResourceController.php b/src/applications/celerity/controller/CelerityResourceController.php --- a/src/applications/celerity/controller/CelerityResourceController.php +++ b/src/applications/celerity/controller/CelerityResourceController.php @@ -164,7 +164,7 @@ return isset($types[$type]); } - private function getCacheKey($path) { + protected function getCacheKey($path) { return 'celerity:'.PhabricatorHash::digestToLength($path, 64); } diff --git a/src/applications/celerity/postprocessor/CelerityDefaultPostprocessor.php b/src/applications/celerity/postprocessor/CelerityDefaultPostprocessor.php new file mode 100644 --- /dev/null +++ b/src/applications/celerity/postprocessor/CelerityDefaultPostprocessor.php @@ -0,0 +1,182 @@ + "13px 'Segoe UI', 'Segoe UI Web Regular', ". + "'Segoe UI Symbol', 'Lato', 'Helvetica Neue', Helvetica, ". + "Arial, sans-serif", + + 'fontfamily' => "'Segoe UI', 'Segoe UI Web Regular', ". + "'Segoe UI Symbol', 'Lato', 'Helvetica Neue', Helvetica, ". + "Arial, sans-serif", + + // Drop Shadow + 'dropshadow' => '0 1px 6px rgba(0, 0, 0, .25)', + 'whitetextshadow' => '0 1px 0 rgba(255, 255, 255, 1)', + + // Anchors + 'anchor' => '#136CB2', + + // Base Colors + 'red' => '#c0392b', + 'lightred' => '#f4dddb', + 'orange' => '#e67e22', + 'lightorange' => '#f7e2d4', + 'yellow' => '#f1c40f', + 'lightyellow' => '#fdf5d4', + 'green' => '#139543', + 'lightgreen' => '#d7eddf', + 'blue' => '#2980b9', + 'lightblue' => '#daeaf3', + 'sky' => '#3498db', + 'lightsky' => '#ddeef9', + 'fire' => '#e62f17', + 'indigo' => '#6e5cb6', + 'lightindigo' => '#eae6f7', + 'pink' => '#da49be', + 'lightpink' => '#fbeaf8', + 'violet' => '#8e44ad', + 'lightviolet' => '#ecdff1', + 'charcoal' => '#4b4d51', + 'backdrop' => '#dadee7', + 'hoverwhite' => 'rgba(255,255,255,.6)', + 'hovergrey' => '#c5cbcf', + 'hoverblue' => '#eceff5', + 'hoverborder' => '#dfe1e9', + 'hoverselectedgrey' => '#bbc4ca', + 'hoverselectedblue' => '#e6e9ee', + + // Base Greys + 'lightgreyborder' => '#C7CCD9', + 'greyborder' => '#A1A6B0', + 'darkgreyborder' => '#676A70', + 'lightgreytext' => '#92969D', + 'greytext' => '#74777D', + 'darkgreytext' => '#4B4D51', + 'lightgreybackground' => '#F7F7F7', + 'greybackground' => '#EBECEE', + 'darkgreybackground' => '#DFE0E2', + + // Base Blues + 'thinblueborder' => '#DDE8EF', + 'lightblueborder' => '#BFCFDA', + 'blueborder' => '#8C98B8', + 'darkblueborder' => '#626E82', + 'lightbluebackground' => '#F8F9FC', + 'bluebackground' => '#DAE7FF', + 'lightbluetext' => '#8C98B8', + 'bluetext' => '#6B748C', + 'darkbluetext' => '#464C5C', + + // Base Greens + 'lightgreenborder' => '#bfdac1', + 'greenborder' => '#8cb89c', + 'greentext' => '#3e6d35', + 'lightgreenbackground' => '#e6f2e4', + + // Base Red + 'lightredborder' => '#f4c6c6', + 'redborder' => '#eb9797', + 'redtext' => '#802b2b', + 'lightredbackground' => '#f5e1e1', + + // Base Violet + 'lightvioletborder' => '#cfbddb', + 'violetborder' => '#b589ba', + 'violettext' => '#603c73', + 'lightvioletbackground' => '#e9dfee', + + // Shades are a more muted set of our base colors + // better suited to blending into other UIs. + + // Shade Red + 'sh-lightredborder' => '#efcfcf', + 'sh-redborder' => '#d1abab', + 'sh-redicon' => '#c85a5a', + 'sh-redtext' => '#a53737', + 'sh-redbackground' => '#f7e6e6', + + // Shade Orange + 'sh-lightorangeborder' => '#f8dcc3', + 'sh-orangeborder' => '#dbb99e', + 'sh-orangeicon' => '#e78331', + 'sh-orangetext' => '#ba6016', + 'sh-orangebackground' => '#fbede1', + + // Shade Yellow + 'sh-lightyellowborder' => '#e9dbcd', + 'sh-yellowborder' => '#c9b8a8', + 'sh-yellowicon' => '#9b946e', + 'sh-yellowtext' => '#726f56', + 'sh-yellowbackground' => '#fdf3da', + + // Shade Green + 'sh-lightgreenborder' => '#c6e6c7', + 'sh-greenborder' => '#a0c4a1', + 'sh-greenicon' => '#4ca74e', + 'sh-greentext' => '#326d34', + 'sh-greenbackground' => '#ddefdd', + + // Shade Blue + 'sh-lightblueborder' => '#cfdbe3', + 'sh-blueborder' => '#a7b5bf', + 'sh-blueicon' => '#6b748c', + 'sh-bluetext' => '#464c5c', + 'sh-bluebackground' => '#dee7f8', + + // Shade Indigo + 'sh-lightindigoborder' => '#d1c9ee', + 'sh-indigoborder' => '#bcb4da', + 'sh-indigoicon' => '#8672d4', + 'sh-indigotext' => '#6e5cb6', + 'sh-indigobackground' => '#eae6f7', + + // Shade Violet + 'sh-lightvioletborder' => '#e0d1e7', + 'sh-violetborder' => '#bcabc5', + 'sh-violeticon' => '#9260ad', + 'sh-violettext' => '#69427f', + 'sh-violetbackground' => '#efe8f3', + + // Shade Pink + 'sh-lightpinkborder' => '#f6d5ef', + 'sh-pinkborder' => '#d5aecd', + 'sh-pinkicon' => '#e26fcb', + 'sh-pinktext' => '#da49be', + 'sh-pinkbackground' => '#fbeaf8', + + // Shade Grey + 'sh-lightgreyborder' => '#d8d8d8', + 'sh-greyborder' => '#b2b2b2', + 'sh-greyicon' => '#757575', + 'sh-greytext' => '#555555', + 'sh-greybackground' => '#e7e7e7', + + // Shade Disabled + 'sh-lightdisabledborder' => '#e5e5e5', + 'sh-disabledborder' => '#cbcbcb', + 'sh-disabledicon' => '#bababa', + 'sh-disabledtext' => '#a6a6a6', + 'sh-disabledbackground' => '#f3f3f3', + ); + } + +} diff --git a/src/applications/celerity/postprocessor/CelerityHighContrastPostprocessor.php b/src/applications/celerity/postprocessor/CelerityHighContrastPostprocessor.php new file mode 100644 --- /dev/null +++ b/src/applications/celerity/postprocessor/CelerityHighContrastPostprocessor.php @@ -0,0 +1,24 @@ + '#dddddd', + ); + } + +} diff --git a/src/applications/celerity/postprocessor/CelerityPostprocessor.php b/src/applications/celerity/postprocessor/CelerityPostprocessor.php new file mode 100644 --- /dev/null +++ b/src/applications/celerity/postprocessor/CelerityPostprocessor.php @@ -0,0 +1,66 @@ +buildVariables(); + + $default = $this->getDefault(); + if ($default) { + $variables += $default->getVariables(); + } + + return $variables; + } + + final public function getDefault() { + if ($this->default === null) { + $this->default = $this->buildDefaultPostprocessor(); + } + return $this->default; + } + + public static function getPostprocessor($key) { + return idx(self::getAllPostprocessors(), $key); + } + + public static function getAllPostprocessors() { + static $postprocessors; + + if ($postprocessors === null) { + $objects = id(new PhutilSymbolLoader()) + ->setAncestorClass(__CLASS__) + ->loadObjects(); + + $map = array(); + foreach ($objects as $object) { + $key = $object->getPostprocessorKey(); + if (empty($map[$key])) { + $map[$key] = $object; + continue; + } + + throw new Exception( + pht( + 'Two postprocessors (of classes "%s" and "%s") define the same '. + 'postprocessor key ("%s"). Each postprocessor must define a '. + 'unique key.', + get_class($object), + get_class($map[$key]), + $key)); + } + $postprocessors = $map; + } + + return $postprocessors; + } + +} diff --git a/src/applications/files/controller/PhabricatorFileComposeController.php b/src/applications/files/controller/PhabricatorFileComposeController.php --- a/src/applications/files/controller/PhabricatorFileComposeController.php +++ b/src/applications/files/controller/PhabricatorFileComposeController.php @@ -322,7 +322,9 @@ private function composeImage($color, $icon_data) { $icon_img = imagecreatefromstring($icon_data); - $map = CelerityResourceTransformer::getCSSVariableMap(); + $map = id(new CelerityResourceTransformer()) + ->getCSSVariableMap(); + $color_string = idx($map, $color, '#ff00ff'); $color_const = hexdec(trim($color_string, '#')); diff --git a/src/applications/settings/panel/PhabricatorDisplayPreferencesSettingsPanel.php b/src/applications/settings/panel/PhabricatorDisplayPreferencesSettingsPanel.php --- a/src/applications/settings/panel/PhabricatorDisplayPreferencesSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorDisplayPreferencesSettingsPanel.php @@ -25,6 +25,8 @@ $pref_titles = PhabricatorUserPreferences::PREFERENCE_TITLES; $pref_monospaced_textareas = PhabricatorUserPreferences::PREFERENCE_MONOSPACED_TEXTAREAS; + $pref_postprocessor = + PhabricatorUserPreferences::PREFERENCE_RESOURCE_POSTPROCESSOR; $errors = array(); $e_editor = null; @@ -42,6 +44,9 @@ $preferences->setPreference( $pref_monospaced_textareas, $request->getStr($pref_monospaced_textareas)); + $preferences->setPreference( + $pref_postprocessor, + $request->getStr($pref_postprocessor)); $editor_pattern = $preferences->getPreference($pref_editor); if (strlen($editor_pattern)) { @@ -106,8 +111,25 @@ 'Input should be valid CSS "font" declaration, such as '. '"13px Consolas"'); + $postprocessor_map = CelerityPostprocessor::getAllPostprocessors(); + $postprocessor_map = mpull($postprocessor_map, 'getPostprocessorName'); + asort($postprocessor_map); + $postprocessor_order = array( + CelerityDefaultPostprocessor::POSTPROCESSOR_KEY, + ); + + $postprocessor_map = array_select_keys( + $postprocessor_map, + $postprocessor_order) + $postprocessor_map; + $form = id(new AphrontFormView()) ->setUser($user) + ->appendControl( + id(new AphrontFormSelectControl()) + ->setLabel(pht('Accessibility')) + ->setName($pref_postprocessor) + ->setValue($preferences->getPreference($pref_postprocessor)) + ->setOptions($postprocessor_map)) ->appendChild( id(new AphrontFormSelectControl()) ->setLabel(pht('Page Titles')) diff --git a/src/applications/settings/storage/PhabricatorUserPreferences.php b/src/applications/settings/storage/PhabricatorUserPreferences.php --- a/src/applications/settings/storage/PhabricatorUserPreferences.php +++ b/src/applications/settings/storage/PhabricatorUserPreferences.php @@ -38,6 +38,8 @@ const PREFERENCE_CONPH_NOTIFICATIONS = 'conph-notifications'; const PREFERENCE_CONPHERENCE_COLUMN = 'conpherence-column'; + const PREFERENCE_RESOURCE_POSTPROCESSOR = 'resource-postprocessor'; + // These are in an unusual order for historic reasons. const MAILTAG_PREFERENCE_NOTIFY = 0; const MAILTAG_PREFERENCE_EMAIL = 1; diff --git a/src/view/page/PhabricatorBarePageView.php b/src/view/page/PhabricatorBarePageView.php --- a/src/view/page/PhabricatorBarePageView.php +++ b/src/view/page/PhabricatorBarePageView.php @@ -117,6 +117,17 @@ $response = CelerityAPI::getStaticResourceResponse(); + if ($this->getRequest()) { + $viewer = $this->getRequest()->getViewer(); + if ($viewer) { + $preference = $viewer->getPreference( + PhabricatorUserPreferences::PREFERENCE_RESOURCE_POSTPROCESSOR); + if (strlen($preference)) { + $response->setPostProcessor($preference); + } + } + } + $developer = PhabricatorEnv::getEnvConfig('phabricator.developer-mode'); return hsprintf( '%s%s%s%s%s%s%s%s',