1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-02-21 19:19:12 +01:00

Promote 2023.17 to stable

This commit is contained in:
Aviv Eyal 2023-04-24 23:53:52 -07:00
commit aa27cccc87
81 changed files with 1456 additions and 1032 deletions

File diff suppressed because it is too large Load diff

View file

@ -9,10 +9,10 @@ return array(
'names' => array( 'names' => array(
'conpherence.pkg.css' => '0e3cf785', 'conpherence.pkg.css' => '0e3cf785',
'conpherence.pkg.js' => '020aebcf', 'conpherence.pkg.js' => '020aebcf',
'core.pkg.css' => '80481fe6', 'core.pkg.css' => 'b239afaa',
'core.pkg.js' => 'd2de90d9', 'core.pkg.js' => '66c49ca1',
'dark-console.pkg.js' => '187792c2', 'dark-console.pkg.js' => '187792c2',
'differential.pkg.css' => 'ffb69e3d', 'differential.pkg.css' => '609e63d4',
'differential.pkg.js' => 'c60bec1b', 'differential.pkg.js' => 'c60bec1b',
'diffusion.pkg.css' => '42c75c37', 'diffusion.pkg.css' => '42c75c37',
'diffusion.pkg.js' => '78c9885d', 'diffusion.pkg.js' => '78c9885d',
@ -45,7 +45,7 @@ return array(
'rsrc/css/application/chatlog/chatlog.css' => 'abdc76ee', 'rsrc/css/application/chatlog/chatlog.css' => 'abdc76ee',
'rsrc/css/application/conduit/conduit-api.css' => 'ce2cfc41', 'rsrc/css/application/conduit/conduit-api.css' => 'ce2cfc41',
'rsrc/css/application/config/config-options.css' => '16c920ae', 'rsrc/css/application/config/config-options.css' => '16c920ae',
'rsrc/css/application/config/config-template.css' => '20babf50', 'rsrc/css/application/config/config-template.css' => 'e689dbbd',
'rsrc/css/application/config/setup-issue.css' => '5eed85b2', 'rsrc/css/application/config/setup-issue.css' => '5eed85b2',
'rsrc/css/application/config/unhandled-exception.css' => '9ecfc00d', 'rsrc/css/application/config/unhandled-exception.css' => '9ecfc00d',
'rsrc/css/application/conpherence/color.css' => 'b17746b0', 'rsrc/css/application/conpherence/color.css' => 'b17746b0',
@ -63,9 +63,9 @@ return array(
'rsrc/css/application/diff/diff-tree-view.css' => 'e2d3e222', 'rsrc/css/application/diff/diff-tree-view.css' => 'e2d3e222',
'rsrc/css/application/diff/inline-comment-summary.css' => '81eb368d', 'rsrc/css/application/diff/inline-comment-summary.css' => '81eb368d',
'rsrc/css/application/differential/add-comment.css' => '7e5900d9', 'rsrc/css/application/differential/add-comment.css' => '7e5900d9',
'rsrc/css/application/differential/changeset-view.css' => '60c3d405', 'rsrc/css/application/differential/changeset-view.css' => 'bf159129',
'rsrc/css/application/differential/core.css' => '7300a73e', 'rsrc/css/application/differential/core.css' => '7300a73e',
'rsrc/css/application/differential/phui-inline-comment.css' => '9863a85e', 'rsrc/css/application/differential/phui-inline-comment.css' => 'a864426f',
'rsrc/css/application/differential/revision-comment.css' => '7dbc8d1d', 'rsrc/css/application/differential/revision-comment.css' => '7dbc8d1d',
'rsrc/css/application/differential/revision-history.css' => '237a2979', 'rsrc/css/application/differential/revision-history.css' => '237a2979',
'rsrc/css/application/differential/revision-list.css' => '93d2df7d', 'rsrc/css/application/differential/revision-list.css' => '93d2df7d',
@ -77,7 +77,7 @@ return array(
'rsrc/css/application/feed/feed.css' => 'd8b6e3f8', 'rsrc/css/application/feed/feed.css' => 'd8b6e3f8',
'rsrc/css/application/files/global-drag-and-drop.css' => '1d2713a4', 'rsrc/css/application/files/global-drag-and-drop.css' => '1d2713a4',
'rsrc/css/application/flag/flag.css' => '2b77be8d', 'rsrc/css/application/flag/flag.css' => '2b77be8d',
'rsrc/css/application/harbormaster/harbormaster.css' => '8dfe16b2', 'rsrc/css/application/harbormaster/harbormaster.css' => 'd98decda',
'rsrc/css/application/herald/herald-test.css' => '7e7bbdae', 'rsrc/css/application/herald/herald-test.css' => '7e7bbdae',
'rsrc/css/application/herald/herald.css' => '648d39e2', 'rsrc/css/application/herald/herald.css' => '648d39e2',
'rsrc/css/application/maniphest/report.css' => '3d53188b', 'rsrc/css/application/maniphest/report.css' => '3d53188b',
@ -101,15 +101,15 @@ return array(
'rsrc/css/application/policy/policy-transaction-detail.css' => 'c02b8384', 'rsrc/css/application/policy/policy-transaction-detail.css' => 'c02b8384',
'rsrc/css/application/policy/policy.css' => 'ceb56a08', 'rsrc/css/application/policy/policy.css' => 'ceb56a08',
'rsrc/css/application/ponder/ponder-view.css' => '05a09d0a', 'rsrc/css/application/ponder/ponder-view.css' => '05a09d0a',
'rsrc/css/application/project/project-card-view.css' => 'a9f2c2dd', 'rsrc/css/application/project/project-card-view.css' => 'c1200da7',
'rsrc/css/application/project/project-triggers.css' => 'cd9c8bb9', 'rsrc/css/application/project/project-triggers.css' => 'cd9c8bb9',
'rsrc/css/application/project/project-view.css' => '567858b3', 'rsrc/css/application/project/project-view.css' => '2f7caa20',
'rsrc/css/application/search/application-search-view.css' => '0f7c06d8', 'rsrc/css/application/search/application-search-view.css' => '0f7c06d8',
'rsrc/css/application/search/search-results.css' => '9ea70ace', 'rsrc/css/application/search/search-results.css' => '9ea70ace',
'rsrc/css/application/slowvote/slowvote.css' => '1694baed', 'rsrc/css/application/slowvote/slowvote.css' => '1694baed',
'rsrc/css/application/tokens/tokens.css' => 'ce5a50bd', 'rsrc/css/application/tokens/tokens.css' => 'ce5a50bd',
'rsrc/css/application/uiexample/example.css' => 'b4795059', 'rsrc/css/application/uiexample/example.css' => 'b4795059',
'rsrc/css/core/core.css' => 'b3ebd90d', 'rsrc/css/core/core.css' => 'a708bd25',
'rsrc/css/core/remarkup.css' => '5baa3bd9', 'rsrc/css/core/remarkup.css' => '5baa3bd9',
'rsrc/css/core/syntax.css' => '548567f6', 'rsrc/css/core/syntax.css' => '548567f6',
'rsrc/css/core/z-index.css' => 'ac3bfcd4', 'rsrc/css/core/z-index.css' => 'ac3bfcd4',
@ -121,10 +121,10 @@ return array(
'rsrc/css/fuel/fuel-handle-list.css' => '2c4cbeca', 'rsrc/css/fuel/fuel-handle-list.css' => '2c4cbeca',
'rsrc/css/fuel/fuel-map.css' => 'd6e31510', 'rsrc/css/fuel/fuel-map.css' => 'd6e31510',
'rsrc/css/fuel/fuel-menu.css' => '21f5d199', 'rsrc/css/fuel/fuel-menu.css' => '21f5d199',
'rsrc/css/layout/phabricator-source-code-view.css' => '03d7ac28', 'rsrc/css/layout/phabricator-source-code-view.css' => '6b31244f',
'rsrc/css/phui/button/phui-button-bar.css' => 'a4aa75c4', 'rsrc/css/phui/button/phui-button-bar.css' => 'a4aa75c4',
'rsrc/css/phui/button/phui-button-simple.css' => '1ff278aa', 'rsrc/css/phui/button/phui-button-simple.css' => '1ff278aa',
'rsrc/css/phui/button/phui-button.css' => 'ea704902', 'rsrc/css/phui/button/phui-button.css' => 'e434f171',
'rsrc/css/phui/calendar/phui-calendar-day.css' => '9597d706', 'rsrc/css/phui/calendar/phui-calendar-day.css' => '9597d706',
'rsrc/css/phui/calendar/phui-calendar-list.css' => 'ccd7e4e2', 'rsrc/css/phui/calendar/phui-calendar-list.css' => 'ccd7e4e2',
'rsrc/css/phui/calendar/phui-calendar-month.css' => 'cb758c42', 'rsrc/css/phui/calendar/phui-calendar-month.css' => 'cb758c42',
@ -142,7 +142,7 @@ return array(
'rsrc/css/phui/phui-big-info-view.css' => '362ad37b', 'rsrc/css/phui/phui-big-info-view.css' => '362ad37b',
'rsrc/css/phui/phui-box.css' => '5ed3b8cb', 'rsrc/css/phui/phui-box.css' => '5ed3b8cb',
'rsrc/css/phui/phui-bulk-editor.css' => '374d5e30', 'rsrc/css/phui/phui-bulk-editor.css' => '374d5e30',
'rsrc/css/phui/phui-chart.css' => '14df9ae3', 'rsrc/css/phui/phui-chart.css' => 'fe8f87a7',
'rsrc/css/phui/phui-cms.css' => '8c05c41e', 'rsrc/css/phui/phui-cms.css' => '8c05c41e',
'rsrc/css/phui/phui-comment-form.css' => '68a2d99a', 'rsrc/css/phui/phui-comment-form.css' => '68a2d99a',
'rsrc/css/phui/phui-comment-panel.css' => 'ec4e31c0', 'rsrc/css/phui/phui-comment-panel.css' => 'ec4e31c0',
@ -154,8 +154,8 @@ return array(
'rsrc/css/phui/phui-document.css' => '52b748a5', 'rsrc/css/phui/phui-document.css' => '52b748a5',
'rsrc/css/phui/phui-feed-story.css' => 'a0c05029', 'rsrc/css/phui/phui-feed-story.css' => 'a0c05029',
'rsrc/css/phui/phui-fontkit.css' => '1ec937e5', 'rsrc/css/phui/phui-fontkit.css' => '1ec937e5',
'rsrc/css/phui/phui-form-view.css' => '01b796c0', 'rsrc/css/phui/phui-form-view.css' => '7536aef9',
'rsrc/css/phui/phui-form.css' => '1f177cb7', 'rsrc/css/phui/phui-form.css' => 'd1adb52c',
'rsrc/css/phui/phui-formation-view.css' => 'd2dec8ed', 'rsrc/css/phui/phui-formation-view.css' => 'd2dec8ed',
'rsrc/css/phui/phui-head-thing.css' => 'd7f293df', 'rsrc/css/phui/phui-head-thing.css' => 'd7f293df',
'rsrc/css/phui/phui-header-view.css' => '36c86a58', 'rsrc/css/phui/phui-header-view.css' => '36c86a58',
@ -168,7 +168,7 @@ return array(
'rsrc/css/phui/phui-left-right.css' => '68513c34', 'rsrc/css/phui/phui-left-right.css' => '68513c34',
'rsrc/css/phui/phui-lightbox.css' => '4ebf22da', 'rsrc/css/phui/phui-lightbox.css' => '4ebf22da',
'rsrc/css/phui/phui-list.css' => '0c04affd', 'rsrc/css/phui/phui-list.css' => '0c04affd',
'rsrc/css/phui/phui-object-box.css' => 'b8d7eea0', 'rsrc/css/phui/phui-object-box.css' => 'fdffed5c',
'rsrc/css/phui/phui-pager.css' => 'd022c7ad', 'rsrc/css/phui/phui-pager.css' => 'd022c7ad',
'rsrc/css/phui/phui-pinboard-view.css' => '1f08f5d8', 'rsrc/css/phui/phui-pinboard-view.css' => '1f08f5d8',
'rsrc/css/phui/phui-policy-section-view.css' => '139fdc64', 'rsrc/css/phui/phui-policy-section-view.css' => '139fdc64',
@ -178,13 +178,13 @@ return array(
'rsrc/css/phui/phui-spacing.css' => 'b05cadc3', 'rsrc/css/phui/phui-spacing.css' => 'b05cadc3',
'rsrc/css/phui/phui-status.css' => '293b5dad', 'rsrc/css/phui/phui-status.css' => '293b5dad',
'rsrc/css/phui/phui-tag-view.css' => 'fb811341', 'rsrc/css/phui/phui-tag-view.css' => 'fb811341',
'rsrc/css/phui/phui-timeline-view.css' => '2d32d7a9', 'rsrc/css/phui/phui-timeline-view.css' => '7f8659ec',
'rsrc/css/phui/phui-two-column-view.css' => 'f96d319f', 'rsrc/css/phui/phui-two-column-view.css' => 'f96d319f',
'rsrc/css/phui/workboards/phui-workboard-color.css' => 'e86de308', 'rsrc/css/phui/workboards/phui-workboard-color.css' => '3a1c21ff',
'rsrc/css/phui/workboards/phui-workboard.css' => '74fc9d98', 'rsrc/css/phui/workboards/phui-workboard.css' => '74fc9d98',
'rsrc/css/phui/workboards/phui-workcard.css' => '913441b6', 'rsrc/css/phui/workboards/phui-workcard.css' => '913441b6',
'rsrc/css/phui/workboards/phui-workpanel.css' => '3ae89b20', 'rsrc/css/phui/workboards/phui-workpanel.css' => '3ae89b20',
'rsrc/css/sprite-login.css' => '18b368a6', 'rsrc/css/sprite-login.css' => '35d1510c',
'rsrc/css/sprite-tokens.css' => 'f1896dc5', 'rsrc/css/sprite-tokens.css' => 'f1896dc5',
'rsrc/css/syntax/syntax-default.css' => '055fc231', 'rsrc/css/syntax/syntax-default.css' => '055fc231',
'rsrc/externals/d3/d3.min.js' => '9d068042', 'rsrc/externals/d3/d3.min.js' => '9d068042',
@ -257,7 +257,7 @@ return array(
'rsrc/externals/javelin/lib/URI.js' => '2e255291', 'rsrc/externals/javelin/lib/URI.js' => '2e255291',
'rsrc/externals/javelin/lib/Vector.js' => 'e9c80beb', 'rsrc/externals/javelin/lib/Vector.js' => 'e9c80beb',
'rsrc/externals/javelin/lib/WebSocket.js' => 'fdc13e4e', 'rsrc/externals/javelin/lib/WebSocket.js' => 'fdc13e4e',
'rsrc/externals/javelin/lib/Workflow.js' => '945ff654', 'rsrc/externals/javelin/lib/Workflow.js' => 'cc1553f3',
'rsrc/externals/javelin/lib/__tests__/Cookie.js' => 'ca686f71', 'rsrc/externals/javelin/lib/__tests__/Cookie.js' => 'ca686f71',
'rsrc/externals/javelin/lib/__tests__/DOM.js' => '4566e249', 'rsrc/externals/javelin/lib/__tests__/DOM.js' => '4566e249',
'rsrc/externals/javelin/lib/__tests__/JSON.js' => '710377ae', 'rsrc/externals/javelin/lib/__tests__/JSON.js' => '710377ae',
@ -265,7 +265,7 @@ return array(
'rsrc/externals/javelin/lib/__tests__/behavior.js' => '8426ebeb', 'rsrc/externals/javelin/lib/__tests__/behavior.js' => '8426ebeb',
'rsrc/externals/javelin/lib/behavior.js' => '1b6acc2a', 'rsrc/externals/javelin/lib/behavior.js' => '1b6acc2a',
'rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js' => '89a1ae3a', 'rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js' => '89a1ae3a',
'rsrc/externals/javelin/lib/control/typeahead/Typeahead.js' => 'a4356cde', 'rsrc/externals/javelin/lib/control/typeahead/Typeahead.js' => '0507519c',
'rsrc/externals/javelin/lib/control/typeahead/normalizer/TypeaheadNormalizer.js' => 'a241536a', 'rsrc/externals/javelin/lib/control/typeahead/normalizer/TypeaheadNormalizer.js' => 'a241536a',
'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadCompositeSource.js' => '22ee68a5', 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadCompositeSource.js' => '22ee68a5',
'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadOnDemandSource.js' => '23387297', 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadOnDemandSource.js' => '23387297',
@ -342,8 +342,8 @@ return array(
'rsrc/image/phrequent_active.png' => 'de66dc50', 'rsrc/image/phrequent_active.png' => 'de66dc50',
'rsrc/image/phrequent_inactive.png' => '79c61baf', 'rsrc/image/phrequent_inactive.png' => '79c61baf',
'rsrc/image/resize.png' => '9cc83373', 'rsrc/image/resize.png' => '9cc83373',
'rsrc/image/sprite-login-X2.png' => '604545f6', 'rsrc/image/sprite-login-X2.png' => '269800ec',
'rsrc/image/sprite-login.png' => '7a001a9a', 'rsrc/image/sprite-login.png' => 'a843f146',
'rsrc/image/sprite-tokens-X2.png' => '21621dd9', 'rsrc/image/sprite-tokens-X2.png' => '21621dd9',
'rsrc/image/sprite-tokens.png' => 'bede2580', 'rsrc/image/sprite-tokens.png' => 'bede2580',
'rsrc/image/texture/card-gradient.png' => 'e6892cb4', 'rsrc/image/texture/card-gradient.png' => 'e6892cb4',
@ -423,7 +423,7 @@ return array(
'rsrc/js/application/projects/WorkboardCard.js' => '0392a5d8', 'rsrc/js/application/projects/WorkboardCard.js' => '0392a5d8',
'rsrc/js/application/projects/WorkboardCardTemplate.js' => '84f82dad', 'rsrc/js/application/projects/WorkboardCardTemplate.js' => '84f82dad',
'rsrc/js/application/projects/WorkboardColumn.js' => 'c3d24e63', 'rsrc/js/application/projects/WorkboardColumn.js' => 'c3d24e63',
'rsrc/js/application/projects/WorkboardController.js' => 'b9d0c2f3', 'rsrc/js/application/projects/WorkboardController.js' => '7474d31f',
'rsrc/js/application/projects/WorkboardDropEffect.js' => '8e0aa661', 'rsrc/js/application/projects/WorkboardDropEffect.js' => '8e0aa661',
'rsrc/js/application/projects/WorkboardHeader.js' => '111bfd2d', 'rsrc/js/application/projects/WorkboardHeader.js' => '111bfd2d',
'rsrc/js/application/projects/WorkboardHeaderTemplate.js' => 'ebe83a6b', 'rsrc/js/application/projects/WorkboardHeaderTemplate.js' => 'ebe83a6b',
@ -453,7 +453,7 @@ return array(
'rsrc/js/core/DragAndDropFileUpload.js' => '4370900d', 'rsrc/js/core/DragAndDropFileUpload.js' => '4370900d',
'rsrc/js/core/DraggableList.js' => '0169e425', 'rsrc/js/core/DraggableList.js' => '0169e425',
'rsrc/js/core/Favicon.js' => '7930776a', 'rsrc/js/core/Favicon.js' => '7930776a',
'rsrc/js/core/FileUpload.js' => 'ab85e184', 'rsrc/js/core/FileUpload.js' => '331676ea',
'rsrc/js/core/Hovercard.js' => '6199f752', 'rsrc/js/core/Hovercard.js' => '6199f752',
'rsrc/js/core/HovercardList.js' => 'de4b4919', 'rsrc/js/core/HovercardList.js' => 'de4b4919',
'rsrc/js/core/KeyboardShortcut.js' => '1a844c06', 'rsrc/js/core/KeyboardShortcut.js' => '1a844c06',
@ -559,7 +559,7 @@ return array(
'conpherence-transaction-css' => '3a3f5e7e', 'conpherence-transaction-css' => '3a3f5e7e',
'd3' => '9d068042', 'd3' => '9d068042',
'diff-tree-view-css' => 'e2d3e222', 'diff-tree-view-css' => 'e2d3e222',
'differential-changeset-view-css' => '60c3d405', 'differential-changeset-view-css' => 'bf159129',
'differential-core-view-css' => '7300a73e', 'differential-core-view-css' => '7300a73e',
'differential-revision-add-comment-css' => '7e5900d9', 'differential-revision-add-comment-css' => '7e5900d9',
'differential-revision-comment-css' => '7dbc8d1d', 'differential-revision-comment-css' => '7dbc8d1d',
@ -578,7 +578,7 @@ return array(
'fuel-map-css' => 'd6e31510', 'fuel-map-css' => 'd6e31510',
'fuel-menu-css' => '21f5d199', 'fuel-menu-css' => '21f5d199',
'global-drag-and-drop-css' => '1d2713a4', 'global-drag-and-drop-css' => '1d2713a4',
'harbormaster-css' => '8dfe16b2', 'harbormaster-css' => 'd98decda',
'herald-css' => '648d39e2', 'herald-css' => '648d39e2',
'herald-rule-editor' => '2633bef7', 'herald-rule-editor' => '2633bef7',
'herald-test-css' => '7e7bbdae', 'herald-test-css' => '7e7bbdae',
@ -731,7 +731,7 @@ return array(
'javelin-sound' => 'd4cc2d2a', 'javelin-sound' => 'd4cc2d2a',
'javelin-stratcom' => '0889b835', 'javelin-stratcom' => '0889b835',
'javelin-tokenizer' => '89a1ae3a', 'javelin-tokenizer' => '89a1ae3a',
'javelin-typeahead' => 'a4356cde', 'javelin-typeahead' => '0507519c',
'javelin-typeahead-composite-source' => '22ee68a5', 'javelin-typeahead-composite-source' => '22ee68a5',
'javelin-typeahead-normalizer' => 'a241536a', 'javelin-typeahead-normalizer' => 'a241536a',
'javelin-typeahead-ondemand-source' => '23387297', 'javelin-typeahead-ondemand-source' => '23387297',
@ -751,12 +751,12 @@ return array(
'javelin-workboard-card' => '0392a5d8', 'javelin-workboard-card' => '0392a5d8',
'javelin-workboard-card-template' => '84f82dad', 'javelin-workboard-card-template' => '84f82dad',
'javelin-workboard-column' => 'c3d24e63', 'javelin-workboard-column' => 'c3d24e63',
'javelin-workboard-controller' => 'b9d0c2f3', 'javelin-workboard-controller' => '7474d31f',
'javelin-workboard-drop-effect' => '8e0aa661', 'javelin-workboard-drop-effect' => '8e0aa661',
'javelin-workboard-header' => '111bfd2d', 'javelin-workboard-header' => '111bfd2d',
'javelin-workboard-header-template' => 'ebe83a6b', 'javelin-workboard-header-template' => 'ebe83a6b',
'javelin-workboard-order-template' => '03e8891f', 'javelin-workboard-order-template' => '03e8891f',
'javelin-workflow' => '945ff654', 'javelin-workflow' => 'cc1553f3',
'maniphest-report-css' => '3d53188b', 'maniphest-report-css' => '3d53188b',
'maniphest-task-edit-css' => '272daa84', 'maniphest-task-edit-css' => '272daa84',
'maniphest-task-summary-css' => '61d1667e', 'maniphest-task-summary-css' => '61d1667e',
@ -771,7 +771,7 @@ return array(
'phabricator-busy' => '5202e831', 'phabricator-busy' => '5202e831',
'phabricator-chatlog-css' => 'abdc76ee', 'phabricator-chatlog-css' => 'abdc76ee',
'phabricator-content-source-view-css' => 'cdf0d579', 'phabricator-content-source-view-css' => 'cdf0d579',
'phabricator-core-css' => 'b3ebd90d', 'phabricator-core-css' => 'a708bd25',
'phabricator-countdown-css' => 'bff8012f', 'phabricator-countdown-css' => 'bff8012f',
'phabricator-darklog' => '3b869402', 'phabricator-darklog' => '3b869402',
'phabricator-darkmessage' => '26cd4b73', 'phabricator-darkmessage' => '26cd4b73',
@ -784,10 +784,10 @@ return array(
'phabricator-diff-tree-view' => '5d83623b', 'phabricator-diff-tree-view' => '5d83623b',
'phabricator-drag-and-drop-file-upload' => '4370900d', 'phabricator-drag-and-drop-file-upload' => '4370900d',
'phabricator-draggable-list' => '0169e425', 'phabricator-draggable-list' => '0169e425',
'phabricator-fatal-config-template-css' => '20babf50', 'phabricator-fatal-config-template-css' => 'e689dbbd',
'phabricator-favicon' => '7930776a', 'phabricator-favicon' => '7930776a',
'phabricator-feed-css' => 'd8b6e3f8', 'phabricator-feed-css' => 'd8b6e3f8',
'phabricator-file-upload' => 'ab85e184', 'phabricator-file-upload' => '331676ea',
'phabricator-flag-css' => '2b77be8d', 'phabricator-flag-css' => '2b77be8d',
'phabricator-keyboard-shortcut' => '1a844c06', 'phabricator-keyboard-shortcut' => '1a844c06',
'phabricator-keyboard-shortcut-manager' => '81debc48', 'phabricator-keyboard-shortcut-manager' => '81debc48',
@ -803,7 +803,7 @@ return array(
'phabricator-search-results-css' => '9ea70ace', 'phabricator-search-results-css' => '9ea70ace',
'phabricator-shaped-request' => '995f5102', 'phabricator-shaped-request' => '995f5102',
'phabricator-slowvote-css' => '1694baed', 'phabricator-slowvote-css' => '1694baed',
'phabricator-source-code-view-css' => '03d7ac28', 'phabricator-source-code-view-css' => '6b31244f',
'phabricator-standard-page-view' => 'a374f94c', 'phabricator-standard-page-view' => 'a374f94c',
'phabricator-textareautils' => 'f340a484', 'phabricator-textareautils' => 'f340a484',
'phabricator-title' => '43bc9360', 'phabricator-title' => '43bc9360',
@ -827,13 +827,13 @@ return array(
'phui-box-css' => '5ed3b8cb', 'phui-box-css' => '5ed3b8cb',
'phui-bulk-editor-css' => '374d5e30', 'phui-bulk-editor-css' => '374d5e30',
'phui-button-bar-css' => 'a4aa75c4', 'phui-button-bar-css' => 'a4aa75c4',
'phui-button-css' => 'ea704902', 'phui-button-css' => 'e434f171',
'phui-button-simple-css' => '1ff278aa', 'phui-button-simple-css' => '1ff278aa',
'phui-calendar-css' => 'f11073aa', 'phui-calendar-css' => 'f11073aa',
'phui-calendar-day-css' => '9597d706', 'phui-calendar-day-css' => '9597d706',
'phui-calendar-list-css' => 'ccd7e4e2', 'phui-calendar-list-css' => 'ccd7e4e2',
'phui-calendar-month-css' => 'cb758c42', 'phui-calendar-month-css' => 'cb758c42',
'phui-chart-css' => '14df9ae3', 'phui-chart-css' => 'fe8f87a7',
'phui-cms-css' => '8c05c41e', 'phui-cms-css' => '8c05c41e',
'phui-comment-form-css' => '68a2d99a', 'phui-comment-form-css' => '68a2d99a',
'phui-comment-panel-css' => 'ec4e31c0', 'phui-comment-panel-css' => 'ec4e31c0',
@ -846,8 +846,8 @@ return array(
'phui-feed-story-css' => 'a0c05029', 'phui-feed-story-css' => 'a0c05029',
'phui-font-icon-base-css' => '303c9b87', 'phui-font-icon-base-css' => '303c9b87',
'phui-fontkit-css' => '1ec937e5', 'phui-fontkit-css' => '1ec937e5',
'phui-form-css' => '1f177cb7', 'phui-form-css' => 'd1adb52c',
'phui-form-view-css' => '01b796c0', 'phui-form-view-css' => '7536aef9',
'phui-formation-view-css' => 'd2dec8ed', 'phui-formation-view-css' => 'd2dec8ed',
'phui-head-thing-view-css' => 'd7f293df', 'phui-head-thing-view-css' => 'd7f293df',
'phui-header-view-css' => '36c86a58', 'phui-header-view-css' => '36c86a58',
@ -858,12 +858,12 @@ return array(
'phui-icon-view-css' => '4cbc684a', 'phui-icon-view-css' => '4cbc684a',
'phui-image-mask-css' => '62c7f4d2', 'phui-image-mask-css' => '62c7f4d2',
'phui-info-view-css' => 'a10a909b', 'phui-info-view-css' => 'a10a909b',
'phui-inline-comment-view-css' => '9863a85e', 'phui-inline-comment-view-css' => 'a864426f',
'phui-invisible-character-view-css' => 'c694c4a4', 'phui-invisible-character-view-css' => 'c694c4a4',
'phui-left-right-css' => '68513c34', 'phui-left-right-css' => '68513c34',
'phui-lightbox-css' => '4ebf22da', 'phui-lightbox-css' => '4ebf22da',
'phui-list-view-css' => '0c04affd', 'phui-list-view-css' => '0c04affd',
'phui-object-box-css' => 'b8d7eea0', 'phui-object-box-css' => 'fdffed5c',
'phui-oi-big-ui-css' => 'fa74cc35', 'phui-oi-big-ui-css' => 'fa74cc35',
'phui-oi-color-css' => 'b517bfa0', 'phui-oi-color-css' => 'b517bfa0',
'phui-oi-drag-ui-css' => 'da15d3dc', 'phui-oi-drag-ui-css' => 'da15d3dc',
@ -880,9 +880,9 @@ return array(
'phui-status-list-view-css' => '293b5dad', 'phui-status-list-view-css' => '293b5dad',
'phui-tag-view-css' => 'fb811341', 'phui-tag-view-css' => 'fb811341',
'phui-theme-css' => '35883b37', 'phui-theme-css' => '35883b37',
'phui-timeline-view-css' => '2d32d7a9', 'phui-timeline-view-css' => '7f8659ec',
'phui-two-column-view-css' => 'f96d319f', 'phui-two-column-view-css' => 'f96d319f',
'phui-workboard-color-css' => 'e86de308', 'phui-workboard-color-css' => '3a1c21ff',
'phui-workboard-view-css' => '74fc9d98', 'phui-workboard-view-css' => '74fc9d98',
'phui-workcard-view-css' => '913441b6', 'phui-workcard-view-css' => '913441b6',
'phui-workpanel-view-css' => '3ae89b20', 'phui-workpanel-view-css' => '3ae89b20',
@ -900,11 +900,11 @@ return array(
'policy-edit-css' => '8794e2ed', 'policy-edit-css' => '8794e2ed',
'policy-transaction-detail-css' => 'c02b8384', 'policy-transaction-detail-css' => 'c02b8384',
'ponder-view-css' => '05a09d0a', 'ponder-view-css' => '05a09d0a',
'project-card-view-css' => 'a9f2c2dd', 'project-card-view-css' => 'c1200da7',
'project-triggers-css' => 'cd9c8bb9', 'project-triggers-css' => 'cd9c8bb9',
'project-view-css' => '567858b3', 'project-view-css' => '2f7caa20',
'setup-issue-css' => '5eed85b2', 'setup-issue-css' => '5eed85b2',
'sprite-login-css' => '18b368a6', 'sprite-login-css' => '35d1510c',
'sprite-tokens-css' => 'f1896dc5', 'sprite-tokens-css' => 'f1896dc5',
'syntax-default-css' => '055fc231', 'syntax-default-css' => '055fc231',
'syntax-highlighting-css' => '548567f6', 'syntax-highlighting-css' => '548567f6',
@ -965,6 +965,12 @@ return array(
'javelin-dom', 'javelin-dom',
'javelin-workflow', 'javelin-workflow',
), ),
'0507519c' => array(
'javelin-install',
'javelin-dom',
'javelin-vector',
'javelin-util',
),
'05d290ef' => array( '05d290ef' => array(
'javelin-install', 'javelin-install',
'javelin-util', 'javelin-util',
@ -1207,6 +1213,11 @@ return array(
'javelin-stratcom', 'javelin-stratcom',
'javelin-dom', 'javelin-dom',
), ),
'331676ea' => array(
'javelin-install',
'javelin-dom',
'phabricator-notification',
),
34450586 => array( 34450586 => array(
'javelin-color', 'javelin-color',
'javelin-install', 'javelin-install',
@ -1512,9 +1523,6 @@ return array(
'5faf27b9' => array( '5faf27b9' => array(
'phuix-form-control-view', 'phuix-form-control-view',
), ),
'60c3d405' => array(
'phui-inline-comment-view-css',
),
'60cd9241' => array( '60cd9241' => array(
'javelin-behavior', 'javelin-behavior',
), ),
@ -1592,6 +1600,16 @@ return array(
'javelin-behavior', 'javelin-behavior',
'javelin-dom', 'javelin-dom',
), ),
'7474d31f' => array(
'javelin-install',
'javelin-dom',
'javelin-util',
'javelin-vector',
'javelin-stratcom',
'javelin-workflow',
'phabricator-drag-and-drop-file-upload',
'javelin-workboard-board',
),
'78bc5d94' => array( '78bc5d94' => array(
'javelin-behavior', 'javelin-behavior',
'javelin-uri', 'javelin-uri',
@ -1747,17 +1765,6 @@ return array(
'javelin-typeahead-preloaded-source', 'javelin-typeahead-preloaded-source',
'javelin-util', 'javelin-util',
), ),
'945ff654' => array(
'javelin-stratcom',
'javelin-request',
'javelin-dom',
'javelin-vector',
'javelin-install',
'javelin-util',
'javelin-mask',
'javelin-uri',
'javelin-routable',
),
'9623adc1' => array( '9623adc1' => array(
'javelin-behavior', 'javelin-behavior',
'javelin-stratcom', 'javelin-stratcom',
@ -1814,12 +1821,6 @@ return array(
'javelin-workflow', 'javelin-workflow',
'phabricator-draggable-list', 'phabricator-draggable-list',
), ),
'a4356cde' => array(
'javelin-install',
'javelin-dom',
'javelin-vector',
'javelin-util',
),
'a43ae2ae' => array( 'a43ae2ae' => array(
'javelin-install', 'javelin-install',
'javelin-dom', 'javelin-dom',
@ -1876,11 +1877,6 @@ return array(
'javelin-json', 'javelin-json',
'phuix-form-control-view', 'phuix-form-control-view',
), ),
'ab85e184' => array(
'javelin-install',
'javelin-dom',
'phabricator-notification',
),
'ac10c917' => array( 'ac10c917' => array(
'javelin-behavior', 'javelin-behavior',
'javelin-dom', 'javelin-dom',
@ -2003,15 +1999,8 @@ return array(
'javelin-uri', 'javelin-uri',
'phabricator-notification', 'phabricator-notification',
), ),
'b9d0c2f3' => array( 'bf159129' => array(
'javelin-install', 'phui-inline-comment-view-css',
'javelin-dom',
'javelin-util',
'javelin-vector',
'javelin-stratcom',
'javelin-workflow',
'phabricator-drag-and-drop-file-upload',
'javelin-workboard-board',
), ),
'c03f2fb4' => array( 'c03f2fb4' => array(
'javelin-install', 'javelin-install',
@ -2051,6 +2040,17 @@ return array(
'javelin-workflow', 'javelin-workflow',
'javelin-json', 'javelin-json',
), ),
'cc1553f3' => array(
'javelin-stratcom',
'javelin-request',
'javelin-dom',
'javelin-vector',
'javelin-install',
'javelin-util',
'javelin-mask',
'javelin-uri',
'javelin-routable',
),
'cc2c5de5' => array( 'cc2c5de5' => array(
'javelin-install', 'javelin-install',
'phuix-button-view', 'phuix-button-view',

View file

@ -119,12 +119,14 @@ if ($is_svnrevprop) {
exit($err); exit($err);
} else if ($repository->isGit() || $repository->isHg()) { } else if ($repository->isGit() || $repository->isHg()) {
$username = getenv(DiffusionCommitHookEngine::ENV_USER); $username = getenv(DiffusionCommitHookEngine::ENV_USER);
if (!strlen($username)) { if ($username !== false) {
throw new Exception( if (!phutil_nonempty_string($username)) {
pht( throw new Exception(
'No Direct Pushes: You are pushing directly to a hosted repository. '. pht(
'This will not work. See "No Direct Pushes" in the documentation '. 'No Direct Pushes: You are pushing directly to a hosted repository. '.
'for more information.')); 'This will not work. See "No Direct Pushes" in the documentation '.
'for more information.'));
}
} }
if ($repository->isHg()) { if ($repository->isHg()) {
@ -181,18 +183,24 @@ $engine->setStdin($stdin);
$engine->setOriginalArgv(array_slice($argv, 2)); $engine->setOriginalArgv(array_slice($argv, 2));
$remote_address = getenv(DiffusionCommitHookEngine::ENV_REMOTE_ADDRESS); $remote_address = getenv(DiffusionCommitHookEngine::ENV_REMOTE_ADDRESS);
if (strlen($remote_address)) { if ($remote_address !== false) {
$engine->setRemoteAddress($remote_address); if (phutil_nonempty_string($remote_address)) {
$engine->setRemoteAddress($remote_address);
}
} }
$remote_protocol = getenv(DiffusionCommitHookEngine::ENV_REMOTE_PROTOCOL); $remote_protocol = getenv(DiffusionCommitHookEngine::ENV_REMOTE_PROTOCOL);
if (strlen($remote_protocol)) { if ($remote_protocol !== false) {
$engine->setRemoteProtocol($remote_protocol); if (phutil_nonempty_string($remote_protocol)) {
$engine->setRemoteProtocol($remote_protocol);
}
} }
$request_identifier = getenv(DiffusionCommitHookEngine::ENV_REQUEST); $request_identifier = getenv(DiffusionCommitHookEngine::ENV_REQUEST);
if (strlen($request_identifier)) { if ($request_identifier !== false) {
$engine->setRequestIdentifier($request_identifier); if (phutil_nonempty_string($request_identifier)) {
$engine->setRequestIdentifier($request_identifier);
}
} }
try { try {

View file

@ -36,7 +36,7 @@ $authstruct_raw = $cache->getKey($authstruct_key);
$authstruct = null; $authstruct = null;
if (strlen($authstruct_raw)) { if (phutil_nonempty_string($authstruct_raw)) {
try { try {
$authstruct = phutil_json_decode($authstruct_raw); $authstruct = phutil_json_decode($authstruct_raw);
} catch (Exception $ex) { } catch (Exception $ex) {
@ -82,13 +82,13 @@ if ($authstruct === null) {
// Strip out newlines and other nonsense from the key type and key body. // Strip out newlines and other nonsense from the key type and key body.
$type = $ssh_key->getKeyType(); $type = $ssh_key->getKeyType();
$type = preg_replace('@[\x00-\x20]+@', '', $type); $type = preg_replace('@[\x00-\x20]+@', '', $type);
if (!strlen($type)) { if (!phutil_nonempty_string($type)) {
continue; continue;
} }
$key = $ssh_key->getKeyBody(); $key = $ssh_key->getKeyBody();
$key = preg_replace('@[\x00-\x20]+@', '', $key); $key = preg_replace('@[\x00-\x20]+@', '', $key);
if (!strlen($key)) { if (!phutil_nonempty_string($key)) {
continue; continue;
} }
@ -135,7 +135,7 @@ foreach ($authstruct['keys'] as $key_struct) {
$cmd = csprintf('%s %Ls', $bin, $key_argv); $cmd = csprintf('%s %Ls', $bin, $key_argv);
if (strlen($instance)) { if (phutil_nonempty_string($instance)) {
$cmd = csprintf('PHABRICATOR_INSTANCE=%s %C', $instance, $cmd); $cmd = csprintf('PHABRICATOR_INSTANCE=%s %C', $instance, $cmd);
} }

View file

@ -103,7 +103,7 @@ try {
'--phabricator-ssh-device', '--phabricator-ssh-device',
$user_name, $user_name,
$device_name)); $device_name));
} else if (strlen($user_name)) { } else if (phutil_nonempty_string($user_name)) {
$user = id(new PhabricatorPeopleQuery()) $user = id(new PhabricatorPeopleQuery())
->setViewer(PhabricatorUser::getOmnipotentUser()) ->setViewer(PhabricatorUser::getOmnipotentUser())
->withUsernames(array($user_name)) ->withUsernames(array($user_name))
@ -117,7 +117,7 @@ try {
id(new PhabricatorAuthSessionEngine()) id(new PhabricatorAuthSessionEngine())
->willServeRequestForUser($user); ->willServeRequestForUser($user);
} else if (strlen($device_name)) { } else if (phutil_nonempty_string($device_name)) {
if (!$remote_address) { if (!$remote_address) {
throw new Exception( throw new Exception(
pht( pht(

View file

@ -39,7 +39,7 @@ $data = array();
$futures = array(); $futures = array();
foreach (explode("\n", trim($input)) as $file) { foreach (explode("\n", trim($input)) as $file) {
if (!strlen($file)) { if (!phutil_nonempty_string($file)) {
continue; continue;
} }

View file

@ -27,7 +27,7 @@ $data = array();
$futures = array(); $futures = array();
foreach (explode("\n", trim($input)) as $file) { foreach (explode("\n", trim($input)) as $file) {
if (!strlen($file)) { if (!phutil_nonempty_string($file)) {
continue; continue;
} }

View file

@ -5843,6 +5843,7 @@ phutil_register_library_map(array(
'PonderQuestionSearchEngine' => 'applications/ponder/query/PonderQuestionSearchEngine.php', 'PonderQuestionSearchEngine' => 'applications/ponder/query/PonderQuestionSearchEngine.php',
'PonderQuestionStatus' => 'applications/ponder/constants/PonderQuestionStatus.php', 'PonderQuestionStatus' => 'applications/ponder/constants/PonderQuestionStatus.php',
'PonderQuestionStatusController' => 'applications/ponder/controller/PonderQuestionStatusController.php', 'PonderQuestionStatusController' => 'applications/ponder/controller/PonderQuestionStatusController.php',
'PonderQuestionStatusTestCase' => 'applications/ponder/storage/__tests__/PonderQuestionStatusTestCase.php',
'PonderQuestionStatusTransaction' => 'applications/ponder/xaction/PonderQuestionStatusTransaction.php', 'PonderQuestionStatusTransaction' => 'applications/ponder/xaction/PonderQuestionStatusTransaction.php',
'PonderQuestionTitleTransaction' => 'applications/ponder/xaction/PonderQuestionTitleTransaction.php', 'PonderQuestionTitleTransaction' => 'applications/ponder/xaction/PonderQuestionTitleTransaction.php',
'PonderQuestionTransaction' => 'applications/ponder/storage/PonderQuestionTransaction.php', 'PonderQuestionTransaction' => 'applications/ponder/storage/PonderQuestionTransaction.php',
@ -8401,6 +8402,7 @@ phutil_register_library_map(array(
'PhabricatorApplicationTransactionInterface', 'PhabricatorApplicationTransactionInterface',
'PhabricatorPolicyInterface', 'PhabricatorPolicyInterface',
'PhabricatorFlaggableInterface', 'PhabricatorFlaggableInterface',
'PhabricatorMentionableInterface',
'PhabricatorSubscribableInterface', 'PhabricatorSubscribableInterface',
'PhabricatorDestructibleInterface', 'PhabricatorDestructibleInterface',
'PhabricatorSpacesInterface', 'PhabricatorSpacesInterface',
@ -12756,6 +12758,7 @@ phutil_register_library_map(array(
'PonderQuestionSearchEngine' => 'PhabricatorApplicationSearchEngine', 'PonderQuestionSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PonderQuestionStatus' => 'PonderConstants', 'PonderQuestionStatus' => 'PonderConstants',
'PonderQuestionStatusController' => 'PonderController', 'PonderQuestionStatusController' => 'PonderController',
'PonderQuestionStatusTestCase' => 'PhutilTestCase',
'PonderQuestionStatusTransaction' => 'PonderQuestionTransactionType', 'PonderQuestionStatusTransaction' => 'PonderQuestionTransactionType',
'PonderQuestionTitleTransaction' => 'PonderQuestionTransactionType', 'PonderQuestionTitleTransaction' => 'PonderQuestionTransactionType',
'PonderQuestionTransaction' => 'PhabricatorModularTransaction', 'PonderQuestionTransaction' => 'PhabricatorModularTransaction',

View file

@ -66,7 +66,7 @@ final class AphrontRequest extends Phobject {
} }
public static function parseURILineRange($range, $limit) { public static function parseURILineRange($range, $limit) {
if (!strlen($range)) { if (!phutil_nonempty_string($range)) {
return null; return null;
} }
@ -234,7 +234,7 @@ final class AphrontRequest extends Phobject {
$raw_data = phutil_string_cast($this->requestData[$name]); $raw_data = phutil_string_cast($this->requestData[$name]);
$raw_data = trim($raw_data); $raw_data = trim($raw_data);
if (!strlen($raw_data)) { if (!phutil_nonempty_string($raw_data)) {
return $default; return $default;
} }
@ -499,7 +499,7 @@ final class AphrontRequest extends Phobject {
// domain is. This makes setup easier, and we'll tell administrators to // domain is. This makes setup easier, and we'll tell administrators to
// configure a base domain during the setup process. // configure a base domain during the setup process.
$base_uri = PhabricatorEnv::getEnvConfig('phabricator.base-uri'); $base_uri = PhabricatorEnv::getEnvConfig('phabricator.base-uri');
if (!strlen($base_uri)) { if (!phutil_nonempty_string($base_uri)) {
return new PhutilURI('http://'.$host.'/'); return new PhutilURI('http://'.$host.'/');
} }
@ -956,7 +956,7 @@ final class AphrontRequest extends Phobject {
$submit_cookie = PhabricatorCookies::COOKIE_SUBMIT; $submit_cookie = PhabricatorCookies::COOKIE_SUBMIT;
$submit_key = $this->getCookie($submit_cookie); $submit_key = $this->getCookie($submit_cookie);
if (strlen($submit_key)) { if (phutil_nonempty_string($submit_key)) {
$this->clearCookie($submit_cookie); $this->clearCookie($submit_cookie);
$this->submitKey = $submit_key; $this->submitKey = $submit_key;
} }

View file

@ -823,7 +823,7 @@ final class AphrontApplicationConfiguration
$raw_input = PhabricatorStartup::getRawInput(); $raw_input = PhabricatorStartup::getRawInput();
$parser = new PhutilQueryStringParser(); $parser = new PhutilQueryStringParser();
if (strlen($raw_input)) { if (phutil_nonempty_string($raw_input)) {
$content_type = idx($_SERVER, 'CONTENT_TYPE'); $content_type = idx($_SERVER, 'CONTENT_TYPE');
$is_multipart = preg_match('@^multipart/form-data@i', $content_type); $is_multipart = preg_match('@^multipart/form-data@i', $content_type);
if ($is_multipart) { if ($is_multipart) {

View file

@ -64,7 +64,7 @@ final class AphrontAjaxResponse extends AphrontResponse {
if ($viewer) { if ($viewer) {
$postprocessor_key = $viewer->getUserSetting( $postprocessor_key = $viewer->getUserSetting(
PhabricatorAccessibilitySetting::SETTINGKEY); PhabricatorAccessibilitySetting::SETTINGKEY);
if (strlen($postprocessor_key)) { if (phutil_nonempty_string($postprocessor_key)) {
$response->setPostprocessorKey($postprocessor_key); $response->setPostprocessorKey($postprocessor_key);
} }
} }

View file

@ -19,7 +19,7 @@ final class AphrontFileResponse extends AphrontResponse {
} }
public function setDownload($download) { public function setDownload($download) {
if (!strlen($download)) { if (!phutil_nonempty_string($download)) {
$download = 'untitled'; $download = 'untitled';
} }
$this->download = $download; $this->download = $download;

View file

@ -21,7 +21,7 @@ final class AphrontWebpageResponse extends AphrontHTMLResponse {
public function buildResponseString() { public function buildResponseString() {
$unexpected_output = $this->getUnexpectedOutput(); $unexpected_output = $this->getUnexpectedOutput();
if (strlen($unexpected_output)) { if (phutil_nonempty_string($unexpected_output)) {
$style = array( $style = array(
'background: linear-gradient(180deg, #eeddff, #ddbbff);', 'background: linear-gradient(180deg, #eeddff, #ddbbff);',
'white-space: pre-wrap;', 'white-space: pre-wrap;',

View file

@ -8,7 +8,7 @@ final class AphrontPHPHTTPSink extends AphrontHTTPSink {
protected function emitHTTPStatus($code, $message = '') { protected function emitHTTPStatus($code, $message = '') {
if ($code != 200) { if ($code != 200) {
$header = "HTTP/1.0 {$code}"; $header = "HTTP/1.0 {$code}";
if (strlen($message)) { if (phutil_nonempty_string($message)) {
$header .= " {$message}"; $header .= " {$message}";
} }
header($header); header($header);

View file

@ -15,7 +15,7 @@ abstract class AphrontSite extends Phobject {
protected function isHostMatch($host, array $uris) { protected function isHostMatch($host, array $uris) {
foreach ($uris as $uri) { foreach ($uris as $uri) {
if (!strlen($uri)) { if (!phutil_nonempty_string($uri)) {
continue; continue;
} }

View file

@ -14,7 +14,7 @@ final class PhabricatorPlatformSite extends PhabricatorSite {
// If no base URI has been configured yet, match this site so the user // If no base URI has been configured yet, match this site so the user
// can follow setup instructions. // can follow setup instructions.
$base_uri = PhabricatorEnv::getEnvConfig('phabricator.base-uri'); $base_uri = PhabricatorEnv::getEnvConfig('phabricator.base-uri');
if (!strlen($base_uri)) { if (!phutil_nonempty_string($base_uri)) {
return new PhabricatorPlatformSite(); return new PhabricatorPlatformSite();
} }

View file

@ -14,7 +14,7 @@ final class PhabricatorResourceSite extends PhabricatorSite {
$host = $request->getHost(); $host = $request->getHost();
$uri = PhabricatorEnv::getEnvConfig('security.alternate-file-domain'); $uri = PhabricatorEnv::getEnvConfig('security.alternate-file-domain');
if (!strlen($uri)) { if (!phutil_nonempty_string($uri)) {
return null; return null;
} }

View file

@ -14,7 +14,7 @@ final class PhabricatorShortSite extends PhabricatorSite {
$host = $request->getHost(); $host = $request->getHost();
$uri = PhabricatorEnv::getEnvConfig('phurl.short-uri'); $uri = PhabricatorEnv::getEnvConfig('phurl.short-uri');
if (!strlen($uri)) { if (!phutil_nonempty_string($uri)) {
return null; return null;
} }

View file

@ -14,7 +14,7 @@ final class PhutilTwitchAuthAdapter extends PhutilOAuthAuthAdapter {
} }
public function getAccountID() { public function getAccountID() {
return $this->getOAuthAccountData('_id'); return $this->getOAuthAccountData('id');
} }
public function getAccountEmail() { public function getAccountEmail() {
@ -22,11 +22,11 @@ final class PhutilTwitchAuthAdapter extends PhutilOAuthAuthAdapter {
} }
public function getAccountName() { public function getAccountName() {
return $this->getOAuthAccountData('name'); return $this->getOAuthAccountData('login');
} }
public function getAccountImageURI() { public function getAccountImageURI() {
return $this->getOAuthAccountData('logo'); return $this->getOAuthAccountData('profile_image_url');
} }
public function getAccountURI() { public function getAccountURI() {
@ -42,11 +42,11 @@ final class PhutilTwitchAuthAdapter extends PhutilOAuthAuthAdapter {
} }
protected function getAuthenticateBaseURI() { protected function getAuthenticateBaseURI() {
return 'https://api.twitch.tv/kraken/oauth2/authorize'; return 'https://id.twitch.tv/oauth2/authorize';
} }
protected function getTokenBaseURI() { protected function getTokenBaseURI() {
return 'https://api.twitch.tv/kraken/oauth2/token'; return 'https://id.twitch.tv/oauth2/token';
} }
public function getScope() { public function getScope() {
@ -69,7 +69,7 @@ final class PhutilTwitchAuthAdapter extends PhutilOAuthAuthAdapter {
return id(new PhutilTwitchFuture()) return id(new PhutilTwitchFuture())
->setClientID($this->getClientID()) ->setClientID($this->getClientID())
->setAccessToken($this->getAccessToken()) ->setAccessToken($this->getAccessToken())
->setRawTwitchQuery('user') ->setRawTwitchQuery('users')
->resolve(); ->resolve();
} }

View file

@ -4,7 +4,7 @@ final class PhabricatorAuthPasswordException
extends Exception { extends Exception {
private $passwordError; private $passwordError;
private $confirmErorr; private $confirmError;
public function __construct( public function __construct(
$message, $message,

View file

@ -8,7 +8,22 @@ final class PhabricatorCalendarImportEditController
->setController($this); ->setController($this);
$id = $request->getURIData('id'); $id = $request->getURIData('id');
if (!$id) { if ($id) {
// edit a specific entry
$calendar_import = self::queryImportByID($request, $id);
if (!$calendar_import) {
return new Aphront404Response();
}
// pass the correct import engine to build the response
$engine->setImportEngine($calendar_import->getEngine());
} else {
// create an entry
$list_uri = $this->getApplicationURI('import/'); $list_uri = $this->getApplicationURI('import/');
$import_type = $request->getStr('importType'); $import_type = $request->getStr('importType');
@ -27,6 +42,18 @@ final class PhabricatorCalendarImportEditController
return $engine->buildResponse(); return $engine->buildResponse();
} }
private static function queryImportByID(AphrontRequest $request, int $id) {
return id(new PhabricatorCalendarImportQuery())
->setViewer($request->getViewer())
->withIDs(array($id))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
}
private function buildEngineTypeResponse($cancel_uri) { private function buildEngineTypeResponse($cancel_uri) {
$import_engines = PhabricatorCalendarImportEngine::getAllImportEngines(); $import_engines = PhabricatorCalendarImportEngine::getAllImportEngines();

View file

@ -83,6 +83,12 @@ final class PhabricatorCalendarImportEditEngine
$engine = $object->getEngine(); $engine = $object->getEngine();
$can_trigger = $engine->supportsTriggers($object); $can_trigger = $engine->supportsTriggers($object);
// calendar URI import
// note that it can contains a secret token
// if we are here you have enough privileges to edit and see the value
$uri_key = PhabricatorCalendarImportICSURITransaction::PARAMKEY_URI;
$uri = $object->getParameter($uri_key);
$fields = array( $fields = array(
id(new PhabricatorTextEditField()) id(new PhabricatorTextEditField())
->setKey('name') ->setKey('name')
@ -94,6 +100,15 @@ final class PhabricatorCalendarImportEditEngine
->setConduitTypeDescription(pht('New import name.')) ->setConduitTypeDescription(pht('New import name.'))
->setPlaceholder($object->getDisplayName()) ->setPlaceholder($object->getDisplayName())
->setValue($object->getName()), ->setValue($object->getName()),
id(new PhabricatorTextEditField())
->setKey('uri')
->setLabel(pht('URI'))
->setDescription(pht('URI to import.'))
->setTransactionType(
PhabricatorCalendarImportICSURITransaction::TRANSACTIONTYPE)
->setConduitDescription(pht('URI to import.'))
->setConduitTypeDescription(pht('New URI.'))
->setValue($uri),
id(new PhabricatorBoolEditField()) id(new PhabricatorBoolEditField())
->setKey('disabled') ->setKey('disabled')
->setOptions(pht('Active'), pht('Disabled')) ->setOptions(pht('Active'), pht('Disabled'))

View file

@ -222,12 +222,16 @@ final class PhabricatorCalendarEventQuery
$limit = $this->getRecurrenceLimit($event, $raw_limit); $limit = $this->getRecurrenceLimit($event, $raw_limit);
// note that this can be NULL for some imported events
$set = $event->newRecurrenceSet(); $set = $event->newRecurrenceSet();
$recurrences = $set->getEventsBetween( $recurrences = array();
$start_date, if ($set) {
$end_date, $recurrences = $set->getEventsBetween(
$limit + 1); $start_date,
$end_date,
$limit + 1);
}
// We're generating events from the beginning and then filtering them // We're generating events from the beginning and then filtering them
// here (instead of only generating events starting at the start date) // here (instead of only generating events starting at the start date)

View file

@ -15,13 +15,13 @@ final class CelerityDarkModePostprocessor
return array( return array(
// Fonts // Fonts
'basefont' => "13px 'Segoe UI', 'Segoe UI Emoji', ". 'basefont' => "13px -apple-system, system-ui, BlinkMacSystemFont, ".
"'Segoe UI Symbol', 'Lato', 'Helvetica Neue', ". "'Segoe UI', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Lato', ".
"Helvetica, Arial, sans-serif", "'Helvetica Neue', Helvetica, Arial, sans-serif",
'fontfamily' => "'Segoe UI', 'Segoe UI Emoji', ". 'fontfamily' => "-apple-system, system-ui, BlinkMacSystemFont, ".
"'Segoe UI Symbol', 'Lato', 'Helvetica Neue', ". "'Segoe UI', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Lato', ".
"Helvetica, Arial, sans-serif", "'Helvetica Neue', Helvetica, Arial, sans-serif",
// Drop Shadow // Drop Shadow
'dropshadow' => '0 2px 12px rgba(0, 0, 0, .20)', 'dropshadow' => '0 2px 12px rgba(0, 0, 0, .20)',

View file

@ -20,13 +20,13 @@ final class CelerityDefaultPostprocessor
public function buildVariables() { public function buildVariables() {
return array( return array(
// Fonts // Fonts
'basefont' => "13px 'Segoe UI', 'Segoe UI Emoji', ". 'basefont' => "13px -apple-system, system-ui, BlinkMacSystemFont, ".
"'Segoe UI Symbol', 'Lato', 'Helvetica Neue', ". "'Segoe UI', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Lato', ".
"Helvetica, Arial, sans-serif", "'Helvetica Neue', Helvetica, Arial, sans-serif",
'fontfamily' => "'Segoe UI', 'Segoe UI Emoji', ". 'fontfamily' => "-apple-system, system-ui, BlinkMacSystemFont, ".
"'Segoe UI Symbol', 'Lato', 'Helvetica Neue', ". "'Segoe UI', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Lato', ".
"Helvetica, Arial, sans-serif", "'Helvetica Neue', Helvetica, Arial, sans-serif",
// Drop Shadow // Drop Shadow
'dropshadow' => '0 2px 12px rgba(0, 0, 0, .20)', 'dropshadow' => '0 2px 12px rgba(0, 0, 0, .20)',

View file

@ -14,9 +14,9 @@ final class CelerityLargeFontPostprocessor
public function buildVariables() { public function buildVariables() {
return array( return array(
'basefont' => "14px 'Segoe UI', 'Segoe UI Web Regular', ". 'basefont' => "14px -apple-system, system-ui, BlinkMacSystemFont, ".
"'Segoe UI Symbol', 'Lato', 'Helvetica Neue', Helvetica, ". "'Segoe UI', 'Segoe UI Web Regular', 'Segoe UI Symbol', 'Lato', ".
"Arial, sans-serif", "'Helvetica Neue', Helvetica, Arial, sans-serif",
// Font Sizes // Font Sizes
'biggestfontsize' => '16px', 'biggestfontsize' => '16px',

View file

@ -247,6 +247,10 @@ final class PhabricatorConduitConsoleController
)); ));
} }
$view->addProperty(
pht('Summary'),
$method->getMethodSummary());
$view->addProperty( $view->addProperty(
pht('Returns'), pht('Returns'),
$method->getReturnType()); $method->getReturnType());

View file

@ -151,19 +151,19 @@ final class PhabricatorStorageSetupCheck extends PhabricatorSetupCheck {
$how_many = 0; $how_many = 0;
if (strlen($access_key)) { if (phutil_nonempty_string($access_key)) {
$how_many++; $how_many++;
} }
if (strlen($secret_key)) { if (phutil_nonempty_string($secret_key)) {
$how_many++; $how_many++;
} }
if (strlen($region)) { if (phutil_nonempty_string($region)) {
$how_many++; $how_many++;
} }
if (strlen($endpoint)) { if (phutil_nonempty_string($endpoint)) {
$how_many++; $how_many++;
} }

View file

@ -178,6 +178,7 @@ final class PhabricatorConfigConsoleController
'('. '('.
implode('|', array( implode('|', array(
'we\.phorge\.it/', 'we\.phorge\.it/',
'github\.com/phorgeit/',
'github\.com/phacility/', 'github\.com/phacility/',
'secure\.phabricator\.com/', 'secure\.phabricator\.com/',
)). )).

View file

@ -60,8 +60,20 @@ final class PhabricatorConfigClusterSearchController
foreach ($service->getHosts() as $host) { foreach ($service->getHosts() as $host) {
try { try {
// Default status icon
//
// At the moment the default status is shown also when
// you just use MySQL as search server. So, on MySQL it
// shows "Unknown" even if probably it should says "Active".
// If you have time, please improve the MySQL getConnectionStatus()
// to return something more useful than this default.
$default_status = array(
'icon' => 'fa-question-circle',
'color' => 'blue',
'label' => pht('Unknown'),
);
$status = $host->getConnectionStatus(); $status = $host->getConnectionStatus();
$status = idx($status_map, $status, array()); $status = idx($status_map, $status, $default_status);
} catch (Exception $ex) { } catch (Exception $ex) {
$status['icon'] = 'fa-times'; $status['icon'] = 'fa-times';
$status['label'] = pht('Connection Error'); $status['label'] = pht('Connection Error');

View file

@ -23,6 +23,17 @@ final class DifferentialRevisionTitleTransaction
} }
public function getTitleForFeed() { public function getTitleForFeed() {
$obj = $this->getObject();
// To avoid verbose messages we mention the current title just once
if ($obj && $obj->getTitle() === $this->getNewValue()) {
return pht(
'%s retitled %s from %s',
$this->renderAuthor(),
$this->renderObject(),
$this->renderOldValue());
}
return pht( return pht(
'%s retitled %s from %s to %s.', '%s retitled %s from %s to %s.',
$this->renderAuthor(), $this->renderAuthor(),

View file

@ -55,7 +55,7 @@ final class DiffusionHistoryQueryConduitAPIMethod
$limit = $request->getValue('limit'); $limit = $request->getValue('limit');
if (strlen($against_hash)) { if (strlen($against_hash)) {
$commit_range = "${against_hash}..${commit_hash}"; $commit_range = "{$against_hash}..{$commit_hash}";
} else { } else {
$commit_range = $commit_hash; $commit_range = $commit_hash;
} }

View file

@ -31,8 +31,7 @@ final class DiffusionRepositoryBasicsManagementPanel
$repository = $this->getRepository(); $repository = $this->getRepository();
$viewer = $this->getViewer(); $viewer = $this->getViewer();
$action_list = id(new PhabricatorActionListView()) $action_list = $this->newActionList();
->setViewer($viewer);
$can_edit = PhabricatorPolicyFilter::hasCapability( $can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer, $viewer,

View file

@ -111,6 +111,9 @@ abstract class DiffusionRepositoryManagementPanel
final protected function newActionList() { final protected function newActionList() {
$viewer = $this->getViewer(); $viewer = $this->getViewer();
// Generating this ID allows to spawn the "Actions" menu
// on mobile on the header
$action_id = celerity_generate_unique_node_id(); $action_id = celerity_generate_unique_node_id();
return id(new PhabricatorActionListView()) return id(new PhabricatorActionListView())

View file

@ -31,11 +31,11 @@ final class PhabricatorS3FileStorageEngine
$endpoint = PhabricatorEnv::getEnvConfig('amazon-s3.endpoint'); $endpoint = PhabricatorEnv::getEnvConfig('amazon-s3.endpoint');
$region = PhabricatorEnv::getEnvConfig('amazon-s3.region'); $region = PhabricatorEnv::getEnvConfig('amazon-s3.region');
return (strlen($bucket) && return phutil_nonempty_string($bucket) &&
strlen($access_key) && phutil_nonempty_string($access_key) &&
strlen($secret_key) && phutil_nonempty_string($secret_key) &&
strlen($endpoint) && phutil_nonempty_string($endpoint) &&
strlen($region)); phutil_nonempty_string($region);
} }
@ -57,7 +57,7 @@ final class PhabricatorS3FileStorageEngine
$parts[] = 'phabricator'; $parts[] = 'phabricator';
$instance_name = PhabricatorEnv::getEnvConfig('cluster.instance'); $instance_name = PhabricatorEnv::getEnvConfig('cluster.instance');
if (strlen($instance_name)) { if (phutil_nonempty_string($instance_name)) {
$parts[] = $instance_name; $parts[] = $instance_name;
} }

View file

@ -856,7 +856,7 @@ final class PhabricatorFile extends PhabricatorFileDAO
// instance identity in the path allows us to distinguish between requests // instance identity in the path allows us to distinguish between requests
// originating from different instances but served through the same CDN. // originating from different instances but served through the same CDN.
$instance = PhabricatorEnv::getEnvConfig('cluster.instance'); $instance = PhabricatorEnv::getEnvConfig('cluster.instance');
if (strlen($instance)) { if (phutil_nonempty_string($instance)) {
$parts[] = '@'.$instance; $parts[] = '@'.$instance;
} }
@ -903,7 +903,7 @@ final class PhabricatorFile extends PhabricatorFileDAO
$parts[] = 'xform'; $parts[] = 'xform';
$instance = PhabricatorEnv::getEnvConfig('cluster.instance'); $instance = PhabricatorEnv::getEnvConfig('cluster.instance');
if (strlen($instance)) { if (phutil_nonempty_string($instance)) {
$parts[] = '@'.$instance; $parts[] = '@'.$instance;
} }

View file

@ -333,8 +333,8 @@ final class HeraldNewController extends HeraldController {
$cancel_params = $params; $cancel_params = $params;
unset($cancel_params['type']); unset($cancel_params['type']);
$cancel_uri = $this->getApplicationURI('new/'); $cancel_uri = $this->getApplicationURI('create/');
$cancel_uri = new PhutilURI($cancel_uri, $params); $cancel_uri = new PhutilURI($cancel_uri, $cancel_params);
$form->appendChild( $form->appendChild(
id(new AphrontFormSubmitControl()) id(new AphrontFormSubmitControl())

View file

@ -35,7 +35,7 @@ final class HeraldTranscriptPHIDType extends PhabricatorPHIDType {
$id = $xscript->getID(); $id = $xscript->getID();
$handle->setName(pht('Transcript %s', $id)); $handle->setName(pht('Transcript %s', $id));
$handle->setURI("/herald/transcript/${id}/"); $handle->setURI("/herald/transcript/$id/");
} }
} }

View file

@ -507,7 +507,7 @@ final class PhabricatorMailEmailEngine
public function newDefaultEmailAddress() { public function newDefaultEmailAddress() {
$raw_address = PhabricatorEnv::getEnvConfig('metamta.default-address'); $raw_address = PhabricatorEnv::getEnvConfig('metamta.default-address');
if (!strlen($raw_address)) { if (!$raw_address) {
$domain = $this->newMailDomain(); $domain = $this->newMailDomain();
$raw_address = "noreply@{$domain}"; $raw_address = "noreply@{$domain}";
} }
@ -527,7 +527,7 @@ final class PhabricatorMailEmailEngine
private function newMailDomain() { private function newMailDomain() {
$domain = PhabricatorEnv::getEnvConfig('metamta.reply-handler-domain'); $domain = PhabricatorEnv::getEnvConfig('metamta.reply-handler-domain');
if (strlen($domain)) { if ($domain) {
return $domain; return $domain;
} }

View file

@ -14,7 +14,8 @@ final class PhabricatorMetaMTAReceivedMailProcessingException
$this->statusCode = $args[0]; $this->statusCode = $args[0];
$args = array_slice($args, 1); $args = array_slice($args, 1);
call_user_func_array(array('parent', '__construct'), $args); $parent = get_parent_class($this);
call_user_func_array(array($parent, '__construct'), $args);
} }
} }

View file

@ -152,7 +152,7 @@ final class PhabricatorNotificationServerRef
->setPath($full_path); ->setPath($full_path);
$instance = PhabricatorEnv::getEnvConfig('cluster.instance'); $instance = PhabricatorEnv::getEnvConfig('cluster.instance');
if (strlen($instance)) { if (phutil_nonempty_string($instance)) {
$uri->replaceQueryParam('instance', $instance); $uri->replaceQueryParam('instance', $instance);
} }

View file

@ -45,6 +45,12 @@ final class PassphraseCredentialEditController extends PassphraseController {
// Prefill username if provided. // Prefill username if provided.
$credential->setUsername((string)$request->getStr('username')); $credential->setUsername((string)$request->getStr('username'));
// Prefill name if provided.
$credential->setName((string)$request->getStr('name'));
// Prefill description if provided.
$credential->setDescription((string)$request->getStr('description'));
if (!$request->getStr('isInitialized')) { if (!$request->getStr('isInitialized')) {
$type->didInitializeNewCredential($viewer, $credential); $type->didInitializeNewCredential($viewer, $credential);
} }

View file

@ -5,6 +5,7 @@ final class PassphraseCredential extends PassphraseDAO
PhabricatorApplicationTransactionInterface, PhabricatorApplicationTransactionInterface,
PhabricatorPolicyInterface, PhabricatorPolicyInterface,
PhabricatorFlaggableInterface, PhabricatorFlaggableInterface,
PhabricatorMentionableInterface,
PhabricatorSubscribableInterface, PhabricatorSubscribableInterface,
PhabricatorDestructibleInterface, PhabricatorDestructibleInterface,
PhabricatorSpacesInterface, PhabricatorSpacesInterface,

View file

@ -110,9 +110,11 @@ final class PholioImageFileTransaction
$new_phids = $value; $new_phids = $value;
$file_phids = array(); $file_phids = array();
foreach ($new_phids as $phid) { foreach ($new_phids as $phids) {
$file_phids[] = $editor->loadPholioImage($object, $phid) foreach ($phids as $phid) {
->getFilePHID(); $file_phids[] = $editor->loadPholioImage($object, $phid)
->getFilePHID();
}
} }
return $file_phids; return $file_phids;

View file

@ -18,6 +18,9 @@ final class PhrictionDocumentDatasource
public function loadResults() { public function loadResults() {
$viewer = $this->getViewer(); $viewer = $this->getViewer();
$app_type = pht('Wiki Document');
$mid_dot = "\xC2\xB7";
$query = id(new PhrictionDocumentQuery()) $query = id(new PhrictionDocumentQuery())
->setViewer($viewer) ->setViewer($viewer)
->needContent(true); ->needContent(true);
@ -34,15 +37,25 @@ final class PhrictionDocumentDatasource
foreach ($documents as $document) { foreach ($documents as $document) {
$content = $document->getContent(); $content = $document->getContent();
if (!$document->isActive()) { if ($document->isActive()) {
$closed = $document->getStatusDisplayName();
} else {
$closed = null; $closed = null;
} else {
$closed = $document->getStatusDisplayName();
} }
$slug = $document->getSlug(); $slug = $document->getSlug();
$title = $content->getTitle(); $title = $content->getTitle();
// For some time the search result was
// just mentioning the document slug.
// Now, it also mentions the application type.
// Example: "Wiki Document - /foo/bar"
$display_type = sprintf(
'%s %s %s',
$app_type,
$mid_dot,
$slug);
$sprite = 'phabricator-search-icon phui-font-fa phui-icon-view fa-book'; $sprite = 'phabricator-search-icon phui-font-fa phui-icon-view fa-book';
$autocomplete = '[[ '.$slug.' ]]'; $autocomplete = '[[ '.$slug.' ]]';
@ -51,7 +64,7 @@ final class PhrictionDocumentDatasource
->setDisplayName($title) ->setDisplayName($title)
->setURI($document->getURI()) ->setURI($document->getURI())
->setPHID($document->getPHID()) ->setPHID($document->getPHID())
->setDisplayType($slug) ->setDisplayType($display_type)
->setPriorityType('wiki') ->setPriorityType('wiki')
->setImageSprite($sprite) ->setImageSprite($sprite)
->setAutocomplete($autocomplete) ->setAutocomplete($autocomplete)

View file

@ -86,4 +86,14 @@ final class PonderQuestionStatus extends PonderConstants {
); );
} }
/**
* Check whenever a Ponder question status is Closed
*
* @param $status string
* @return bool
*/
public static function isQuestionStatusClosed($status) {
return in_array($status, self::getQuestionStatusClosedMap(), true);
}
} }

View file

@ -157,6 +157,9 @@ final class PonderQuestionSearchEngine
'Asked by %s', 'Asked by %s',
$handles[$question->getAuthorPHID()]->renderLink())); $handles[$question->getAuthorPHID()]->renderLink()));
// Render Closed Questions as striked in query results
$item->setDisabled($question->isStatusClosed());
$item->addAttribute( $item->addAttribute(
pht( pht(
'%s Answer(s)', '%s Answer(s)',

View file

@ -137,6 +137,14 @@ final class PonderQuestion extends PonderDAO
return self::MARKUP_FIELD_CONTENT; return self::MARKUP_FIELD_CONTENT;
} }
/**
* Check whenever this Question has whatever closed status
*
* @return bool
*/
public function isStatusClosed() {
return PonderQuestionStatus::isQuestionStatusClosed($this->status);
}
/* -( PhabricatorApplicationTransactionInterface )------------------------- */ /* -( PhabricatorApplicationTransactionInterface )------------------------- */

View file

@ -0,0 +1,25 @@
<?php
final class PonderQuestionStatusTestCase extends PhutilTestCase {
public function testClosedStatuses() {
$statuses = PonderQuestionStatus::getQuestionStatusClosedMap();
foreach ($statuses as $status) {
$question = new PonderQuestion();
$question->setStatus($status);
$this->assertEqual(true, $question->isStatusClosed());
}
}
public function testOpenedStatuses() {
$statuses = PonderQuestionStatus::getQuestionStatusOpenMap();
foreach ($statuses as $status) {
$question = new PonderQuestion();
$question->setStatus($status);
$this->assertEqual(false, $question->isStatusClosed());
}
}
}

View file

@ -693,10 +693,19 @@ final class PhabricatorProjectBoardViewController
->newCreateActionSpecifications(array()); ->newCreateActionSpecifications(array());
foreach ($specs as $spec) { foreach ($specs as $spec) {
// Prefill tags= when you open the Column menu
// https://we.phorge.it/T15147
$spec_href = new PhutilURI($spec['uri']);
$spec_slug = $project->getPrimarySlug();
if ($spec_slug !== null) {
$spec_href->replaceQueryParam('tags', $spec_slug);
}
$column_items[] = id(new PhabricatorActionView()) $column_items[] = id(new PhabricatorActionView())
->setIcon($spec['icon']) ->setIcon($spec['icon'])
->setName($spec['name']) ->setName($spec['name'])
->setHref($spec['uri']) ->setHref($spec_href)
->setDisabled($spec['disabled']) ->setDisabled($spec['disabled'])
->addSigil('column-add-task') ->addSigil('column-add-task')
->setMetadata( ->setMetadata(

View file

@ -43,7 +43,7 @@ final class PhabricatorProjectProjectPHIDType extends PhabricatorPHIDType {
$handle->setName($name); $handle->setName($name);
if (strlen($slug)) { if (phutil_nonempty_string($slug)) {
$handle->setObjectName('#'.$slug); $handle->setObjectName('#'.$slug);
$handle->setMailStampName('#'.$slug); $handle->setMailStampName('#'.$slug);
$handle->setURI("/tag/{$slug}/"); $handle->setURI("/tag/{$slug}/");

View file

@ -238,7 +238,7 @@ final class PhabricatorRepositoryPullEngine
$identifier = $repository->getPHID(); $identifier = $repository->getPHID();
$instance = PhabricatorEnv::getEnvConfig('cluster.instance'); $instance = PhabricatorEnv::getEnvConfig('cluster.instance');
if (strlen($instance)) { if (phutil_nonempty_string($instance)) {
$identifier = "{$identifier}:{$instance}"; $identifier = "{$identifier}:{$instance}";
} }

View file

@ -2480,7 +2480,8 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO
$has_https = false; $has_https = false;
} }
$has_ssh = (bool)strlen(PhabricatorEnv::getEnvConfig('phd.user')); $phd_user = PhabricatorEnv::getEnvConfig('phd.user');
$has_ssh = phutil_nonempty_string($phd_user);
$protocol_map = array( $protocol_map = array(
PhabricatorRepositoryURI::BUILTIN_PROTOCOL_SSH => $has_ssh, PhabricatorRepositoryURI::BUILTIN_PROTOCOL_SSH => $has_ssh,

View file

@ -48,7 +48,7 @@ final class PhabricatorSearchApplicationStorageEnginePanel
} }
$instructions = pht( $instructions = pht(
'To configure the search engines, edit [[ %s | `%s` ]] configuration. '. 'To configure the search engines, edit [[ %s | %s ]] configuration. '.
'See **[[ %s | %s ]]** for documentation.', 'See **[[ %s | %s ]]** for documentation.',
'/config/edit/cluster.search/', '/config/edit/cluster.search/',
'cluster.search', 'cluster.search',

View file

@ -16,7 +16,7 @@ final class PhabricatorSystemReadOnlyController
case PhabricatorEnv::READONLY_CONFIG: case PhabricatorEnv::READONLY_CONFIG:
$title = pht('Administrative Read-Only Mode'); $title = pht('Administrative Read-Only Mode');
$body[] = pht( $body[] = pht(
'An administrator has placed this server into read-only mode.'); 'An Administrator has placed this server into read-only mode.');
$body[] = pht( $body[] = pht(
'This mode may be used to perform temporary maintenance, test '. 'This mode may be used to perform temporary maintenance, test '.
'configuration, or archive an installation permanently.'); 'configuration, or archive an installation permanently.');
@ -26,7 +26,7 @@ final class PhabricatorSystemReadOnlyController
'has been turned on by rolling your chair away from your desk and '. 'has been turned on by rolling your chair away from your desk and '.
'yelling "Hey! Why is %s in read-only mode??!" using '. 'yelling "Hey! Why is %s in read-only mode??!" using '.
'your very loudest outside voice.', 'your very loudest outside voice.',
PlatformSymbols::getPlatformServerSymbol()); PlatformSymbols::getPlatformServerName());
$body[] = pht( $body[] = pht(
'This mode is active because it is enabled in the configuration '. 'This mode is active because it is enabled in the configuration '.
'option "%s".', 'option "%s".',
@ -110,7 +110,7 @@ final class PhabricatorSystemReadOnlyController
if ($viewer->getIsAdmin()) { if ($viewer->getIsAdmin()) {
$body[] = pht( $body[] = pht(
'As an administrator, you can review status information from the '. 'As an Administrator, you can review status information from the '.
'%s control panel. This may provide more information about the '. '%s control panel. This may provide more information about the '.
'current state of affairs.', 'current state of affairs.',
phutil_tag( phutil_tag(

View file

@ -539,7 +539,7 @@ abstract class PhabricatorApplicationTransaction
case PhabricatorTransactions::TYPE_COMMENT; case PhabricatorTransactions::TYPE_COMMENT;
$comment = $this->getComment(); $comment = $this->getComment();
if ($comment && $comment->getIsRemoved()) { if ($comment && $comment->getIsRemoved()) {
return 'black'; return 'grey';
} }
break; break;
case PhabricatorTransactions::TYPE_EDGE: case PhabricatorTransactions::TYPE_EDGE:

View file

@ -493,6 +493,11 @@ class PhabricatorApplicationTransactionView extends AphrontView {
$xaction->getComment() && $xaction->getComment() &&
$xaction->getComment()->getIsRemoved(); $xaction->getComment()->getIsRemoved();
// Make designers happy to make CSS customizations
if ($has_removed_comment) {
$event->addClass('phui-timeline-shell-removed');
}
if ($xaction->getCommentVersion() > 1 && !$has_removed_comment) { if ($xaction->getCommentVersion() > 1 && !$has_removed_comment) {
$event->setIsEdited(true); $event->setIsEdited(true);
} }

View file

@ -21,7 +21,7 @@
], ],
"groups": { "groups": {
"javascript": { "javascript": {
"name": "Javascript" "name": "JavaScript"
}, },
"lore": { "lore": {
"name": "Phorge Lore" "name": "Phorge Lore"

View file

@ -1,6 +1,6 @@
{ {
"name": "phorge", "name": "phorge",
"title": "Phorge User Documentation", "title": "Phorge Administrator and User Documentation",
"short": "User Docs", "short": "User Docs",
"preface": "Instructions for installing, configuring, and using Phorge.", "preface": "Instructions for installing, configuring, and using Phorge.",
"root": "../../../", "root": "../../../",

View file

@ -1,13 +1,13 @@
@title Javascript Object and Array @title JavaScript Object and Array
@group javascript @group javascript
This document describes the behaviors of Object and Array in Javascript, and This document describes the behaviors of Object and Array in JavaScript, and
a specific approach to their use which produces basically reasonable language a specific approach to their use which produces basically reasonable language
behavior. behavior.
= Primitives = = Primitives =
Javascript has two native datatype primitives, Object and Array. Both are JavaScript has two native datatype primitives, Object and Array. Both are
classes, so you can use `new` to instantiate new objects and arrays: classes, so you can use `new` to instantiate new objects and arrays:
COUNTEREXAMPLE COUNTEREXAMPLE
@ -43,11 +43,11 @@ and Array are both classes, but "object" is also a primitive type. Object is
= Objects are Maps, Arrays are Lists = = Objects are Maps, Arrays are Lists =
PHP has a single `array` datatype which behaves like as both map and a list, PHP has a single `array` datatype which behaves like as both map and a list,
and a common mistake is to treat Javascript arrays (or objects) in the same way. and a common mistake is to treat JavaScript arrays (or objects) in the same way.
**Don't do this.** It sort of works until it doesn't. Instead, learn how **Don't do this.** It sort of works until it doesn't. Instead, learn how
Javascript's native datatypes work and use them properly. JavaScript's native datatypes work and use them properly.
In Javascript, you should think of Objects as maps ("dictionaries") and Arrays In JavaScript, you should think of Objects as maps ("dictionaries") and Arrays
as lists ("vectors"). as lists ("vectors").
You store keys-value pairs in a map, and store ordered values in a list. So, You store keys-value pairs in a map, and store ordered values in a list. So,
@ -58,7 +58,13 @@ store key-value pairs in Objects.
species: 'zebra' species: 'zebra'
}; };
console.log(o.name); o.paws = 4;
o['numberOfEars'] = 2;
console.log(o.name);
console.log(o.paws);
console.log(o.numberOfEars);
...and store ordered values in Arrays. ...and store ordered values in Arrays.
@ -71,8 +77,14 @@ Don't store key-value pairs in Arrays and don't expect Objects to be ordered.
var a = []; var a = [];
a['name'] = 'Hubert'; // No! Don't do this! a['name'] = 'Hubert'; // No! Don't do this!
This technically works because Arrays are Objects and you think everything is Technically, both work because Arrays //are// Objects and you think everything
fine and dandy, but it won't do what you want and will burn you. is fine and dandy, but it won't do what you want and will burn you. For example,
using `.length` will play tricks on you.
In short, trust me:
* use `[]` only to create a stack of consecutive elements numerically indexed
* use `{}` to create associative maps ("associative arrays")
= Iterating over Maps and Lists = = Iterating over Maps and Lists =
@ -140,7 +152,7 @@ The correct way to deal with this is:
continue; continue;
} }
f(list[ii]); f(list[ii]);
} }
Avoid sparse arrays if possible. Avoid sparse arrays if possible.

View file

@ -1,12 +1,12 @@
@title Javascript Pitfalls @title JavaScript Pitfalls
@group javascript @group javascript
This document discusses pitfalls and flaws in the Javascript language, and how This document discusses pitfalls and flaws in the JavaScript language, and how
to avoid, work around, or at least understand them. to avoid, work around, or at least understand them.
= Implicit Semicolons = = Implicit Semicolons =
Javascript tries to insert semicolons if you forgot them. This is a pretty JavaScript tries to insert semicolons if you forgot them. This is a pretty
horrible idea. Notably, it can mask syntax errors by transforming subexpressions horrible idea. Notably, it can mask syntax errors by transforming subexpressions
on their own lines into statements with no effect: on their own lines into statements with no effect:
@ -46,11 +46,11 @@ you can pass `arguments` to Function.prototype.apply() without converting it.
There is essentially only one reasonable, consistent way to use these primitives There is essentially only one reasonable, consistent way to use these primitives
but it is not obvious. Navigate these troubled waters with but it is not obvious. Navigate these troubled waters with
@{article:Javascript Object and Array}. @{article:JavaScript Object and Array}.
= typeof null == "object" = = typeof null == "object" =
This statement is true in Javascript: This statement is true in JavaScript:
typeof null == 'object' typeof null == 'object'
@ -58,9 +58,9 @@ This is pretty much a bug in the language that can never be fixed now.
= Number, String, and Boolean objects = = Number, String, and Boolean objects =
Like Java, Javascript has primitive versions of number, string, and boolean, Like Java, JavaScript has primitive versions of number, string, and boolean,
and object versions. In Java, there's some argument for this distinction. In and object versions. In Java, there's some argument for this distinction. In
Javascript, it's pretty much completely worthless and the behavior of these JavaScript, it's pretty much completely worthless and the behavior of these
objects is wrong. String and Boolean in particular are essentially unusable: objects is wrong. String and Boolean in particular are essentially unusable:
lang=js lang=js
@ -83,5 +83,5 @@ Number.prototype, etc.) and their logical behavior is at best absurd and at
worst strictly wrong. worst strictly wrong.
**Never use** `new Number()`, `new String()` or `new Boolean()` unless **Never use** `new Number()`, `new String()` or `new Boolean()` unless
your Javascript is God Tier and you are absolutely sure you know what you are your JavaScript is God Tier and you are absolutely sure you know what you are
doing. doing.

View file

@ -256,7 +256,7 @@ echo $obj->flavor; // Outputs 'coconut'.
echo get_class($obj); // Outputs 'stdClass'. echo get_class($obj); // Outputs 'stdClass'.
``` ```
This is occasionally useful, mostly to force an object to become a Javascript This is occasionally useful, mostly to force an object to become a JavaScript
dictionary (vs a list) when passed to `json_encode()`. dictionary (vs a list) when passed to `json_encode()`.
= Invoking `new` With an Argument Vector is Really Hard = = Invoking `new` With an Argument Vector is Really Hard =

View file

@ -34,7 +34,7 @@ it also gained a lot of performance problems, usability issues, and bugs.
Through 2007 and 2008 Evan worked mostly on frontend and support infrastructure; Through 2007 and 2008 Evan worked mostly on frontend and support infrastructure;
among other things, he wrote a static resource management system called Haste. among other things, he wrote a static resource management system called Haste.
In 2009 Evan worked on the Facebook Lite site, where he built the Javelin In 2009 Evan worked on the Facebook Lite site, where he built the Javelin
Javascript library and an MVC-flavored framework called Alite. JavaScript library and an MVC-flavored framework called Alite.
But by early 2010, Diffcamp was in pretty bad shape. Two years of having random But by early 2010, Diffcamp was in pretty bad shape. Two years of having random
features grafted onto it without real direction had left it slow and difficult features grafted onto it without real direction had left it slow and difficult

View file

@ -11,6 +11,7 @@ If you haven't, see @{article:Installation Guide}.
The next steps are: The next steps are:
- Configure your webserver (Apache, nginx, or lighttpd). - Configure your webserver (Apache, nginx, or lighttpd).
- Configure the databases.
- Access Phorge with your browser. - Access Phorge with your browser.
- Follow the instructions to complete setup. - Follow the instructions to complete setup.

View file

@ -15,10 +15,17 @@ Phorge, you will need:
- a domain name (like `phorge.example.com`); - a domain name (like `phorge.example.com`);
- basic sysadmin skills; - basic sysadmin skills;
- Apache, nginx, or another webserver; - Apache, nginx, or another webserver;
- PHP, MySQL, and Git. - PHP;
- MySQL (you will need a server with multiple databases);
- git
The remainder of this document details these requirements. The remainder of this document details these requirements.
You may be interested also in preparing these optional stuff:
- have valid SMTP parameters for outgoing email notifications;
- having nothing listening on port 22, to then setup a SSH+git server
Installation Requirements Installation Requirements
========================= =========================
@ -71,7 +78,11 @@ Beyond an operating system, you will need **a webserver**.
You will also need: You will also need:
- **MySQL**: You need MySQL. We strongly recommend MySQL 5.5 or newer. - **MySQL**: You need MySQL. We strongly recommend MySQL 5.5 or newer.
- **PHP**: You need PHP 5.5 or newer. You will need a server with multiple databases.
- **PHP**: You need PHP 5.5 or newer. Note that PHP 8.1 and above are not
fully supported.
- **git**: You need git 2.5.0 or newer on the server.
No particular version is needed on your clients.
You'll probably also need a **domain name**. In particular, you should read this You'll probably also need a **domain name**. In particular, you should read this
note: note:
@ -106,7 +117,7 @@ Here's a general description of what you need to install:
- git (usually called "git" in package management systems) - git (usually called "git" in package management systems)
- Apache (usually "httpd" or "apache2") (or nginx) - Apache (usually "httpd" or "apache2") (or nginx)
- MySQL Server (usually "mysqld" or "mysql-server") - MySQL Server (usually "mysqld" or "mysql-server" or "mariadb-server")
- PHP (usually "php") - PHP (usually "php")
- Required PHP extensions: mbstring, iconv, mysql (or mysqli), curl, pcntl - Required PHP extensions: mbstring, iconv, mysql (or mysqli), curl, pcntl
(these might be something like "php-mysql" or "php5-mysqlnd") (these might be something like "php-mysql" or "php5-mysqlnd")

View file

@ -229,7 +229,7 @@ final class PhabricatorDatabaseRef
$host = $this->getHost(); $host = $this->getHost();
$port = $this->getPort(); $port = $this->getPort();
if (strlen($port)) { if ($port) {
return "{$host}:{$port}"; return "{$host}:{$port}";
} }

View file

@ -125,7 +125,7 @@ final class PhabricatorEnv extends Phobject {
// If an instance identifier is defined, write it into the environment so // If an instance identifier is defined, write it into the environment so
// it's available to subprocesses. // it's available to subprocesses.
$instance = self::getEnvConfig('cluster.instance'); $instance = self::getEnvConfig('cluster.instance');
if (strlen($instance)) { if (phutil_nonempty_string($instance)) {
putenv('PHABRICATOR_INSTANCE='.$instance); putenv('PHABRICATOR_INSTANCE='.$instance);
$_ENV['PHABRICATOR_INSTANCE'] = $instance; $_ENV['PHABRICATOR_INSTANCE'] = $instance;
} }
@ -440,7 +440,7 @@ final class PhabricatorEnv extends Phobject {
$uri = new PhutilURI($raw_uri); $uri = new PhutilURI($raw_uri);
$host = $uri->getDomain(); $host = $uri->getDomain();
if (!strlen($host)) { if (!phutil_nonempty_string($host)) {
return false; return false;
} }
@ -463,7 +463,7 @@ final class PhabricatorEnv extends Phobject {
$self_map = array(); $self_map = array();
foreach ($self_uris as $self_uri) { foreach ($self_uris as $self_uri) {
$host = id(new PhutilURI($self_uri))->getDomain(); $host = id(new PhutilURI($self_uri))->getDomain();
if (!strlen($host)) { if (!phutil_nonempty_string($host)) {
continue; continue;
} }
@ -669,7 +669,7 @@ final class PhabricatorEnv extends Phobject {
public static function isValidLocalURIForLink($uri) { public static function isValidLocalURIForLink($uri) {
$uri = (string)$uri; $uri = (string)$uri;
if (!strlen($uri)) { if (!phutil_nonempty_string($uri)) {
return false; return false;
} }
@ -734,7 +734,7 @@ final class PhabricatorEnv extends Phobject {
$uri = new PhutilURI($raw_uri); $uri = new PhutilURI($raw_uri);
$proto = $uri->getProtocol(); $proto = $uri->getProtocol();
if (!strlen($proto)) { if (!$proto) {
throw new Exception( throw new Exception(
pht( pht(
'URI "%s" is not a valid linkable resource. A valid linkable '. 'URI "%s" is not a valid linkable resource. A valid linkable '.
@ -753,7 +753,7 @@ final class PhabricatorEnv extends Phobject {
} }
$domain = $uri->getDomain(); $domain = $uri->getDomain();
if (!strlen($domain)) { if (!$domain) {
throw new Exception( throw new Exception(
pht( pht(
'URI "%s" is not a valid linkable resource. A valid linkable '. 'URI "%s" is not a valid linkable resource. A valid linkable '.
@ -801,7 +801,7 @@ final class PhabricatorEnv extends Phobject {
$uri = new PhutilURI($raw_uri); $uri = new PhutilURI($raw_uri);
$proto = $uri->getProtocol(); $proto = $uri->getProtocol();
if (!strlen($proto)) { if (!$proto) {
throw new Exception( throw new Exception(
pht( pht(
'URI "%s" is not a valid fetchable resource. A valid fetchable '. 'URI "%s" is not a valid fetchable resource. A valid fetchable '.
@ -820,7 +820,7 @@ final class PhabricatorEnv extends Phobject {
} }
$domain = $uri->getDomain(); $domain = $uri->getDomain();
if (!strlen($domain)) { if (!$domain) {
throw new Exception( throw new Exception(
pht( pht(
'URI "%s" is not a valid fetchable resource. A valid fetchable '. 'URI "%s" is not a valid fetchable resource. A valid fetchable '.

View file

@ -24,7 +24,7 @@ final class PhabricatorSSHLog extends Phobject {
); );
$sudo_user = PhabricatorEnv::getEnvConfig('phd.user'); $sudo_user = PhabricatorEnv::getEnvConfig('phd.user');
if (strlen($sudo_user)) { if (phutil_nonempty_string($sudo_user)) {
$data['S'] = $sudo_user; $data['S'] = $sudo_user;
} }

View file

@ -0,0 +1,123 @@
#!/usr/bin/env php
<?php
/**
* /startup/ is not a Phutil library, so it can't use the phutil test fixture.
* This script will just run the tests directly.
*
* NOTE: This test file will not run as part of `arc unit` run!
*/
final class PreambleUtilsTestCase {
public function testTrustXForwardValues() {
// For specific values of `$_SERVER['HTTP_X_FORWARDED_FOR']`,
// `$_SERVER['REMOTE_ADDR']` will be updated with the result.
$undefined = 'SPECIAL::UNDEFINED';
$null_value = 'SPECIAL::NULL';
$test_cases = array(
'abc' => 'abc',
$null_value => $undefined,
'' => $undefined,
// Strange, unexpected cases:
144 => '144',
);
foreach ($test_cases as $input => $expected) {
switch ($input) {
case $undefined:
unset($_SERVER['HTTP_X_FORWARDED_FOR']);
break;
case $null_value:
$_SERVER['HTTP_X_FORWARDED_FOR'] = null;
break;
default:
$_SERVER['HTTP_X_FORWARDED_FOR'] = $input;
break;
}
unset($_SERVER['REMOTE_ADDR']);
preamble_trust_x_forwarded_for_header();
if (!isset($_SERVER['REMOTE_ADDR'])) {
if ($expected === $undefined) {
// test pass
continue;
} else {
$this->failTest("Failed for input {$input} - result is not defined!");
}
}
$actual = $_SERVER['REMOTE_ADDR'];
if ($actual !== $expected) {
var_dump($actual);
$this->failTest(
"Failed for input {$input} - actual output is {$actual}");
}
}
}
private function failTest($message = null) {
echo $message;
echo "\n";
throw new Exception();
}
/**
* Run all tests in this class.
*
* Return: True if all tests passed; False if any test failed.
*/
final public function run() {
$reflection = new ReflectionClass($this);
$methods = $reflection->getMethods();
$any_fail = false;
// Try to ensure that poorly-written tests which depend on execution order
// (and are thus not properly isolated) will fail.
shuffle($methods);
foreach ($methods as $method) {
$name = $method->getName();
if (!preg_match('/^test/', $name)) {
continue;
}
try {
call_user_func_array(
array($this, $name),
array());
echo "Test passed: {$name}\n";
} catch (Throwable $ex) {
$any_fail = true;
echo "Failed test: {$name}\n";
}
}
return !$any_fail;
}
}
require_once dirname(__DIR__).'/preamble-utils.php';
$test_case = new PreambleUtilsTestCase();
$good = $test_case->run();
if (!$good) {
exit(3);
}

View file

@ -6,7 +6,8 @@ body {
background: #f9f9f9; background: #f9f9f9;
margin: 0; margin: 0;
padding: 0; padding: 0;
font: 13px/1.231 'Segoe UI', 'Segoe UI Web Regular', 'Segoe UI Symbol', font: 13px/1.231 -apple-system, system-ui, BlinkMacSystemFont,
'Segoe UI', 'Segoe UI Web Regular', 'Segoe UI Symbol',
'Helvetica Neue', Helvetica, Arial, sans-serif; 'Helvetica Neue', Helvetica, Arial, sans-serif;
text-align: left; text-align: left;
-webkit-text-size-adjust: none; -webkit-text-size-adjust: none;

View file

@ -106,7 +106,8 @@
.harbormaster-log-expand-table td { .harbormaster-log-expand-table td {
vertical-align: middle; vertical-align: middle;
font: 13px 'Segoe UI', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Lato', font: 13px -apple-system, system-ui, BlinkMacSystemFont,
'Segoe UI', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Lato',
'Helvetica Neue', Helvetica, Arial, sans-serif; 'Helvetica Neue', Helvetica, Arial, sans-serif;
} }

View file

@ -25,6 +25,8 @@
border-right: 1px solid {$paste.border}; border-right: 1px solid {$paste.border};
color: {$sh-yellowtext}; color: {$sh-yellowtext};
white-space: nowrap; white-space: nowrap;
-webkit-user-select: none;
user-select: none;
} }
.phabricator-source-line > a::before { .phabricator-source-line > a::before {

View file

@ -525,7 +525,7 @@ properly, and submit values. */
} }
.aphront-form-preview-hidden { .aphront-form-preview-hidden {
opacity: 0.5; display: none;
} }
.aphront-form-error .phui-icon-view { .aphront-form-error .phui-icon-view {

View file

@ -189,9 +189,30 @@
overflow-x: auto; overflow-x: auto;
} }
/*
* Start Customization for removed comments
* https://we.phorge.it/T15192
*/
.phui-timeline-core-content .comment-deleted { .phui-timeline-core-content .comment-deleted {
font-style: italic; font-style: italic;
} }
.phui-timeline-shell-removed .phui-timeline-image,
.phui-timeline-shell-removed .phui-timeline-badges {
opacity: 0.5;
}
.phui-timeline-shell-removed,
.phui-timeline-shell-removed a,
.phui-timeline-shell-removed .phui-timeline-title {
color:#888; /* grey */
}
.phui-timeline-shell-removed
.phui-timeline-major-event
.phui-timeline-content .phui-timeline-core-content {
padding:4px 16px; /* reduce vertical space from 16px */
}
/* End Customization for removed comments */
.device .phui-timeline-event-view { .device .phui-timeline-event-view {
min-height: 23px; min-height: 23px;

View file

@ -27,7 +27,7 @@
} }
.phui-workboard-color .phuix-dropdown-menu { .phui-workboard-color .phuix-dropdown-menu {
background-color: rgba({$alphawhite},.9); background-color: rgba({$alphawhite},.95);
} }
.phui-workboard-color .phui-workpanel-view .phui-box-grey { .phui-workboard-color .phui-workpanel-view .phui-box-grey {

View file

@ -403,6 +403,20 @@ JX.install('Workflow', {
JX.$E('Response to workflow request went unhandled.'); JX.$E('Response to workflow request went unhandled.');
} }
} }
// Only when the response is a Dialog, check if the user
// is quitting with pending changes
if (this._root) {
var form = JX.DOM.scry(this._root, 'form', 'jx-dialog');
if (form.length) {
JX.DOM.listen(form[0], 'keydown', null, function(e) {
if (e.getSpecialKey()) {
return;
}
JX.Stratcom.addSigil(form[0], 'dialog-keydown');
});
}
}
}, },
_push : function() { _push : function() {
if (!this._pushed) { if (!this._pushed) {
@ -536,6 +550,22 @@ JX.install('Workflow', {
return; return;
} }
// Only when the response is a Dialog, check if the user
// is quitting with pending changes
if (active._root) {
var form = JX.DOM.scry(active._root, 'form', 'jx-dialog');
var confirmMsg =
'Form data may have changed. ' +
'Are you sure you want to close this dialog?';
if (
form.length &&
JX.Stratcom.hasSigil(form[0], 'dialog-keydown') &&
!window.confirm(confirmMsg)
) {
return;
}
}
JX.Workflow._pop(); JX.Workflow._pop();
e.prevent(); e.prevent();
} }

View file

@ -84,8 +84,19 @@ JX.install('Typeahead', {
'mousedown', 'mousedown',
'tag:a', 'tag:a',
JX.bind(this, function(e) { JX.bind(this, function(e) {
if (!e.isRightButton()) { if (e.isNormalMouseEvent()) {
this._choose(e.getNode('tag:a')); this._choose(e.getNode('tag:a'));
} else {
// fix the middle-click and any non-normal mouse event
// in order to have an "open in a new tab" that just works natively
// or any other browser action that is supposed to be there.
//
// Probably this is one of the specific cases where kill() has
// sense instead of just stop(), since there are not much chances
// that another event listener had anything else to do
// during non-normal mousedown/click events.
// https://we.phorge.it/T15149
e.kill();
} }
})); }));

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View file

@ -151,6 +151,13 @@ JX.install('WorkboardController', {
}, },
_onaddcard: function(e) { _onaddcard: function(e) {
// Allow CTRL+click and maybe other actions
if(!e.isNormalMouseEvent()) {
e.stop();
return;
}
// We want the 'boards-dropdown-menu' behavior to see this event and // We want the 'boards-dropdown-menu' behavior to see this event and
// close the dropdown, but don't want to follow the link. // close the dropdown, but don't want to follow the link.
e.prevent(); e.prevent();
@ -176,6 +183,13 @@ JX.install('WorkboardController', {
}, },
_oneditcard: function(e) { _oneditcard: function(e) {
// Allow CTRL+click and maybe other actions
if(!e.isNormalMouseEvent()) {
e.stop();
return;
}
e.kill(); e.kill();
var column_node = e.getNode('project-column'); var column_node = e.getNode('project-column');

View file

@ -38,6 +38,20 @@ JX.install('PhabricatorFileUpload', {
return this; return this;
}, },
/**
* Get the File Monogram - like 'F123'
*/
getMonogram: function() {
return 'F' + this.getID();
},
/**
* Get the File page URI - like '/F123'
*/
getPageURI: function() {
return '/' + this.getMonogram();
},
setChunks: function(chunks) { setChunks: function(chunks) {
var chunk; var chunk;
for (var ii = 0; ii < chunks.length; ii++) { for (var ii = 0; ii < chunks.length; ii++) {
@ -101,7 +115,19 @@ JX.install('PhabricatorFileUpload', {
switch (this.getStatus()) { switch (this.getStatus()) {
case 'done': case 'done':
var link = JX.$N('a', {href: this.getURI()}, 'F' + this.getID());
// In this case the File upload was successful
var linkAttr = {};
linkAttr.href = this.getPageURI();
// External links are evil as default.
// Believe it or not, but some Phorge users brainstormed
// for one hour for this specific target="_blank".
// https://we.phorge.it/T15172
linkAttr.target = '_blank';
var link = JX.$N('a', linkAttr, this.getMonogram());
content = [ content = [
JX.$N('strong', {}, ['Upload Complete (', link, ')']), JX.$N('strong', {}, ['Upload Complete (', link, ')']),