mirror of
https://we.phorge.it/source/phorge.git
synced 2025-02-20 10:48:40 +01:00
Promote 2023.17 to stable
This commit is contained in:
commit
aa27cccc87
81 changed files with 1456 additions and 1032 deletions
1626
externals/phpmailer/class.smtp.php
vendored
1626
externals/phpmailer/class.smtp.php
vendored
File diff suppressed because it is too large
Load diff
|
@ -9,10 +9,10 @@ return array(
|
|||
'names' => array(
|
||||
'conpherence.pkg.css' => '0e3cf785',
|
||||
'conpherence.pkg.js' => '020aebcf',
|
||||
'core.pkg.css' => '80481fe6',
|
||||
'core.pkg.js' => 'd2de90d9',
|
||||
'core.pkg.css' => 'b239afaa',
|
||||
'core.pkg.js' => '66c49ca1',
|
||||
'dark-console.pkg.js' => '187792c2',
|
||||
'differential.pkg.css' => 'ffb69e3d',
|
||||
'differential.pkg.css' => '609e63d4',
|
||||
'differential.pkg.js' => 'c60bec1b',
|
||||
'diffusion.pkg.css' => '42c75c37',
|
||||
'diffusion.pkg.js' => '78c9885d',
|
||||
|
@ -45,7 +45,7 @@ return array(
|
|||
'rsrc/css/application/chatlog/chatlog.css' => 'abdc76ee',
|
||||
'rsrc/css/application/conduit/conduit-api.css' => 'ce2cfc41',
|
||||
'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/unhandled-exception.css' => '9ecfc00d',
|
||||
'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/inline-comment-summary.css' => '81eb368d',
|
||||
'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/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-history.css' => '237a2979',
|
||||
'rsrc/css/application/differential/revision-list.css' => '93d2df7d',
|
||||
|
@ -77,7 +77,7 @@ return array(
|
|||
'rsrc/css/application/feed/feed.css' => 'd8b6e3f8',
|
||||
'rsrc/css/application/files/global-drag-and-drop.css' => '1d2713a4',
|
||||
'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.css' => '648d39e2',
|
||||
'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.css' => 'ceb56a08',
|
||||
'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-view.css' => '567858b3',
|
||||
'rsrc/css/application/project/project-view.css' => '2f7caa20',
|
||||
'rsrc/css/application/search/application-search-view.css' => '0f7c06d8',
|
||||
'rsrc/css/application/search/search-results.css' => '9ea70ace',
|
||||
'rsrc/css/application/slowvote/slowvote.css' => '1694baed',
|
||||
'rsrc/css/application/tokens/tokens.css' => 'ce5a50bd',
|
||||
'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/syntax.css' => '548567f6',
|
||||
'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-map.css' => 'd6e31510',
|
||||
'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-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-list.css' => 'ccd7e4e2',
|
||||
'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-box.css' => '5ed3b8cb',
|
||||
'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-comment-form.css' => '68a2d99a',
|
||||
'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-feed-story.css' => 'a0c05029',
|
||||
'rsrc/css/phui/phui-fontkit.css' => '1ec937e5',
|
||||
'rsrc/css/phui/phui-form-view.css' => '01b796c0',
|
||||
'rsrc/css/phui/phui-form.css' => '1f177cb7',
|
||||
'rsrc/css/phui/phui-form-view.css' => '7536aef9',
|
||||
'rsrc/css/phui/phui-form.css' => 'd1adb52c',
|
||||
'rsrc/css/phui/phui-formation-view.css' => 'd2dec8ed',
|
||||
'rsrc/css/phui/phui-head-thing.css' => 'd7f293df',
|
||||
'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-lightbox.css' => '4ebf22da',
|
||||
'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-pinboard-view.css' => '1f08f5d8',
|
||||
'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-status.css' => '293b5dad',
|
||||
'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/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-workcard.css' => '913441b6',
|
||||
'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/syntax/syntax-default.css' => '055fc231',
|
||||
'rsrc/externals/d3/d3.min.js' => '9d068042',
|
||||
|
@ -257,7 +257,7 @@ return array(
|
|||
'rsrc/externals/javelin/lib/URI.js' => '2e255291',
|
||||
'rsrc/externals/javelin/lib/Vector.js' => 'e9c80beb',
|
||||
'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__/DOM.js' => '4566e249',
|
||||
'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/behavior.js' => '1b6acc2a',
|
||||
'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/source/TypeaheadCompositeSource.js' => '22ee68a5',
|
||||
'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_inactive.png' => '79c61baf',
|
||||
'rsrc/image/resize.png' => '9cc83373',
|
||||
'rsrc/image/sprite-login-X2.png' => '604545f6',
|
||||
'rsrc/image/sprite-login.png' => '7a001a9a',
|
||||
'rsrc/image/sprite-login-X2.png' => '269800ec',
|
||||
'rsrc/image/sprite-login.png' => 'a843f146',
|
||||
'rsrc/image/sprite-tokens-X2.png' => '21621dd9',
|
||||
'rsrc/image/sprite-tokens.png' => 'bede2580',
|
||||
'rsrc/image/texture/card-gradient.png' => 'e6892cb4',
|
||||
|
@ -423,7 +423,7 @@ return array(
|
|||
'rsrc/js/application/projects/WorkboardCard.js' => '0392a5d8',
|
||||
'rsrc/js/application/projects/WorkboardCardTemplate.js' => '84f82dad',
|
||||
'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/WorkboardHeader.js' => '111bfd2d',
|
||||
'rsrc/js/application/projects/WorkboardHeaderTemplate.js' => 'ebe83a6b',
|
||||
|
@ -453,7 +453,7 @@ return array(
|
|||
'rsrc/js/core/DragAndDropFileUpload.js' => '4370900d',
|
||||
'rsrc/js/core/DraggableList.js' => '0169e425',
|
||||
'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/HovercardList.js' => 'de4b4919',
|
||||
'rsrc/js/core/KeyboardShortcut.js' => '1a844c06',
|
||||
|
@ -559,7 +559,7 @@ return array(
|
|||
'conpherence-transaction-css' => '3a3f5e7e',
|
||||
'd3' => '9d068042',
|
||||
'diff-tree-view-css' => 'e2d3e222',
|
||||
'differential-changeset-view-css' => '60c3d405',
|
||||
'differential-changeset-view-css' => 'bf159129',
|
||||
'differential-core-view-css' => '7300a73e',
|
||||
'differential-revision-add-comment-css' => '7e5900d9',
|
||||
'differential-revision-comment-css' => '7dbc8d1d',
|
||||
|
@ -578,7 +578,7 @@ return array(
|
|||
'fuel-map-css' => 'd6e31510',
|
||||
'fuel-menu-css' => '21f5d199',
|
||||
'global-drag-and-drop-css' => '1d2713a4',
|
||||
'harbormaster-css' => '8dfe16b2',
|
||||
'harbormaster-css' => 'd98decda',
|
||||
'herald-css' => '648d39e2',
|
||||
'herald-rule-editor' => '2633bef7',
|
||||
'herald-test-css' => '7e7bbdae',
|
||||
|
@ -731,7 +731,7 @@ return array(
|
|||
'javelin-sound' => 'd4cc2d2a',
|
||||
'javelin-stratcom' => '0889b835',
|
||||
'javelin-tokenizer' => '89a1ae3a',
|
||||
'javelin-typeahead' => 'a4356cde',
|
||||
'javelin-typeahead' => '0507519c',
|
||||
'javelin-typeahead-composite-source' => '22ee68a5',
|
||||
'javelin-typeahead-normalizer' => 'a241536a',
|
||||
'javelin-typeahead-ondemand-source' => '23387297',
|
||||
|
@ -751,12 +751,12 @@ return array(
|
|||
'javelin-workboard-card' => '0392a5d8',
|
||||
'javelin-workboard-card-template' => '84f82dad',
|
||||
'javelin-workboard-column' => 'c3d24e63',
|
||||
'javelin-workboard-controller' => 'b9d0c2f3',
|
||||
'javelin-workboard-controller' => '7474d31f',
|
||||
'javelin-workboard-drop-effect' => '8e0aa661',
|
||||
'javelin-workboard-header' => '111bfd2d',
|
||||
'javelin-workboard-header-template' => 'ebe83a6b',
|
||||
'javelin-workboard-order-template' => '03e8891f',
|
||||
'javelin-workflow' => '945ff654',
|
||||
'javelin-workflow' => 'cc1553f3',
|
||||
'maniphest-report-css' => '3d53188b',
|
||||
'maniphest-task-edit-css' => '272daa84',
|
||||
'maniphest-task-summary-css' => '61d1667e',
|
||||
|
@ -771,7 +771,7 @@ return array(
|
|||
'phabricator-busy' => '5202e831',
|
||||
'phabricator-chatlog-css' => 'abdc76ee',
|
||||
'phabricator-content-source-view-css' => 'cdf0d579',
|
||||
'phabricator-core-css' => 'b3ebd90d',
|
||||
'phabricator-core-css' => 'a708bd25',
|
||||
'phabricator-countdown-css' => 'bff8012f',
|
||||
'phabricator-darklog' => '3b869402',
|
||||
'phabricator-darkmessage' => '26cd4b73',
|
||||
|
@ -784,10 +784,10 @@ return array(
|
|||
'phabricator-diff-tree-view' => '5d83623b',
|
||||
'phabricator-drag-and-drop-file-upload' => '4370900d',
|
||||
'phabricator-draggable-list' => '0169e425',
|
||||
'phabricator-fatal-config-template-css' => '20babf50',
|
||||
'phabricator-fatal-config-template-css' => 'e689dbbd',
|
||||
'phabricator-favicon' => '7930776a',
|
||||
'phabricator-feed-css' => 'd8b6e3f8',
|
||||
'phabricator-file-upload' => 'ab85e184',
|
||||
'phabricator-file-upload' => '331676ea',
|
||||
'phabricator-flag-css' => '2b77be8d',
|
||||
'phabricator-keyboard-shortcut' => '1a844c06',
|
||||
'phabricator-keyboard-shortcut-manager' => '81debc48',
|
||||
|
@ -803,7 +803,7 @@ return array(
|
|||
'phabricator-search-results-css' => '9ea70ace',
|
||||
'phabricator-shaped-request' => '995f5102',
|
||||
'phabricator-slowvote-css' => '1694baed',
|
||||
'phabricator-source-code-view-css' => '03d7ac28',
|
||||
'phabricator-source-code-view-css' => '6b31244f',
|
||||
'phabricator-standard-page-view' => 'a374f94c',
|
||||
'phabricator-textareautils' => 'f340a484',
|
||||
'phabricator-title' => '43bc9360',
|
||||
|
@ -827,13 +827,13 @@ return array(
|
|||
'phui-box-css' => '5ed3b8cb',
|
||||
'phui-bulk-editor-css' => '374d5e30',
|
||||
'phui-button-bar-css' => 'a4aa75c4',
|
||||
'phui-button-css' => 'ea704902',
|
||||
'phui-button-css' => 'e434f171',
|
||||
'phui-button-simple-css' => '1ff278aa',
|
||||
'phui-calendar-css' => 'f11073aa',
|
||||
'phui-calendar-day-css' => '9597d706',
|
||||
'phui-calendar-list-css' => 'ccd7e4e2',
|
||||
'phui-calendar-month-css' => 'cb758c42',
|
||||
'phui-chart-css' => '14df9ae3',
|
||||
'phui-chart-css' => 'fe8f87a7',
|
||||
'phui-cms-css' => '8c05c41e',
|
||||
'phui-comment-form-css' => '68a2d99a',
|
||||
'phui-comment-panel-css' => 'ec4e31c0',
|
||||
|
@ -846,8 +846,8 @@ return array(
|
|||
'phui-feed-story-css' => 'a0c05029',
|
||||
'phui-font-icon-base-css' => '303c9b87',
|
||||
'phui-fontkit-css' => '1ec937e5',
|
||||
'phui-form-css' => '1f177cb7',
|
||||
'phui-form-view-css' => '01b796c0',
|
||||
'phui-form-css' => 'd1adb52c',
|
||||
'phui-form-view-css' => '7536aef9',
|
||||
'phui-formation-view-css' => 'd2dec8ed',
|
||||
'phui-head-thing-view-css' => 'd7f293df',
|
||||
'phui-header-view-css' => '36c86a58',
|
||||
|
@ -858,12 +858,12 @@ return array(
|
|||
'phui-icon-view-css' => '4cbc684a',
|
||||
'phui-image-mask-css' => '62c7f4d2',
|
||||
'phui-info-view-css' => 'a10a909b',
|
||||
'phui-inline-comment-view-css' => '9863a85e',
|
||||
'phui-inline-comment-view-css' => 'a864426f',
|
||||
'phui-invisible-character-view-css' => 'c694c4a4',
|
||||
'phui-left-right-css' => '68513c34',
|
||||
'phui-lightbox-css' => '4ebf22da',
|
||||
'phui-list-view-css' => '0c04affd',
|
||||
'phui-object-box-css' => 'b8d7eea0',
|
||||
'phui-object-box-css' => 'fdffed5c',
|
||||
'phui-oi-big-ui-css' => 'fa74cc35',
|
||||
'phui-oi-color-css' => 'b517bfa0',
|
||||
'phui-oi-drag-ui-css' => 'da15d3dc',
|
||||
|
@ -880,9 +880,9 @@ return array(
|
|||
'phui-status-list-view-css' => '293b5dad',
|
||||
'phui-tag-view-css' => 'fb811341',
|
||||
'phui-theme-css' => '35883b37',
|
||||
'phui-timeline-view-css' => '2d32d7a9',
|
||||
'phui-timeline-view-css' => '7f8659ec',
|
||||
'phui-two-column-view-css' => 'f96d319f',
|
||||
'phui-workboard-color-css' => 'e86de308',
|
||||
'phui-workboard-color-css' => '3a1c21ff',
|
||||
'phui-workboard-view-css' => '74fc9d98',
|
||||
'phui-workcard-view-css' => '913441b6',
|
||||
'phui-workpanel-view-css' => '3ae89b20',
|
||||
|
@ -900,11 +900,11 @@ return array(
|
|||
'policy-edit-css' => '8794e2ed',
|
||||
'policy-transaction-detail-css' => 'c02b8384',
|
||||
'ponder-view-css' => '05a09d0a',
|
||||
'project-card-view-css' => 'a9f2c2dd',
|
||||
'project-card-view-css' => 'c1200da7',
|
||||
'project-triggers-css' => 'cd9c8bb9',
|
||||
'project-view-css' => '567858b3',
|
||||
'project-view-css' => '2f7caa20',
|
||||
'setup-issue-css' => '5eed85b2',
|
||||
'sprite-login-css' => '18b368a6',
|
||||
'sprite-login-css' => '35d1510c',
|
||||
'sprite-tokens-css' => 'f1896dc5',
|
||||
'syntax-default-css' => '055fc231',
|
||||
'syntax-highlighting-css' => '548567f6',
|
||||
|
@ -965,6 +965,12 @@ return array(
|
|||
'javelin-dom',
|
||||
'javelin-workflow',
|
||||
),
|
||||
'0507519c' => array(
|
||||
'javelin-install',
|
||||
'javelin-dom',
|
||||
'javelin-vector',
|
||||
'javelin-util',
|
||||
),
|
||||
'05d290ef' => array(
|
||||
'javelin-install',
|
||||
'javelin-util',
|
||||
|
@ -1207,6 +1213,11 @@ return array(
|
|||
'javelin-stratcom',
|
||||
'javelin-dom',
|
||||
),
|
||||
'331676ea' => array(
|
||||
'javelin-install',
|
||||
'javelin-dom',
|
||||
'phabricator-notification',
|
||||
),
|
||||
34450586 => array(
|
||||
'javelin-color',
|
||||
'javelin-install',
|
||||
|
@ -1512,9 +1523,6 @@ return array(
|
|||
'5faf27b9' => array(
|
||||
'phuix-form-control-view',
|
||||
),
|
||||
'60c3d405' => array(
|
||||
'phui-inline-comment-view-css',
|
||||
),
|
||||
'60cd9241' => array(
|
||||
'javelin-behavior',
|
||||
),
|
||||
|
@ -1592,6 +1600,16 @@ return array(
|
|||
'javelin-behavior',
|
||||
'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(
|
||||
'javelin-behavior',
|
||||
'javelin-uri',
|
||||
|
@ -1747,17 +1765,6 @@ return array(
|
|||
'javelin-typeahead-preloaded-source',
|
||||
'javelin-util',
|
||||
),
|
||||
'945ff654' => array(
|
||||
'javelin-stratcom',
|
||||
'javelin-request',
|
||||
'javelin-dom',
|
||||
'javelin-vector',
|
||||
'javelin-install',
|
||||
'javelin-util',
|
||||
'javelin-mask',
|
||||
'javelin-uri',
|
||||
'javelin-routable',
|
||||
),
|
||||
'9623adc1' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-stratcom',
|
||||
|
@ -1814,12 +1821,6 @@ return array(
|
|||
'javelin-workflow',
|
||||
'phabricator-draggable-list',
|
||||
),
|
||||
'a4356cde' => array(
|
||||
'javelin-install',
|
||||
'javelin-dom',
|
||||
'javelin-vector',
|
||||
'javelin-util',
|
||||
),
|
||||
'a43ae2ae' => array(
|
||||
'javelin-install',
|
||||
'javelin-dom',
|
||||
|
@ -1876,11 +1877,6 @@ return array(
|
|||
'javelin-json',
|
||||
'phuix-form-control-view',
|
||||
),
|
||||
'ab85e184' => array(
|
||||
'javelin-install',
|
||||
'javelin-dom',
|
||||
'phabricator-notification',
|
||||
),
|
||||
'ac10c917' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-dom',
|
||||
|
@ -2003,15 +1999,8 @@ return array(
|
|||
'javelin-uri',
|
||||
'phabricator-notification',
|
||||
),
|
||||
'b9d0c2f3' => array(
|
||||
'javelin-install',
|
||||
'javelin-dom',
|
||||
'javelin-util',
|
||||
'javelin-vector',
|
||||
'javelin-stratcom',
|
||||
'javelin-workflow',
|
||||
'phabricator-drag-and-drop-file-upload',
|
||||
'javelin-workboard-board',
|
||||
'bf159129' => array(
|
||||
'phui-inline-comment-view-css',
|
||||
),
|
||||
'c03f2fb4' => array(
|
||||
'javelin-install',
|
||||
|
@ -2051,6 +2040,17 @@ return array(
|
|||
'javelin-workflow',
|
||||
'javelin-json',
|
||||
),
|
||||
'cc1553f3' => array(
|
||||
'javelin-stratcom',
|
||||
'javelin-request',
|
||||
'javelin-dom',
|
||||
'javelin-vector',
|
||||
'javelin-install',
|
||||
'javelin-util',
|
||||
'javelin-mask',
|
||||
'javelin-uri',
|
||||
'javelin-routable',
|
||||
),
|
||||
'cc2c5de5' => array(
|
||||
'javelin-install',
|
||||
'phuix-button-view',
|
||||
|
|
|
@ -119,12 +119,14 @@ if ($is_svnrevprop) {
|
|||
exit($err);
|
||||
} else if ($repository->isGit() || $repository->isHg()) {
|
||||
$username = getenv(DiffusionCommitHookEngine::ENV_USER);
|
||||
if (!strlen($username)) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'No Direct Pushes: You are pushing directly to a hosted repository. '.
|
||||
'This will not work. See "No Direct Pushes" in the documentation '.
|
||||
'for more information.'));
|
||||
if ($username !== false) {
|
||||
if (!phutil_nonempty_string($username)) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'No Direct Pushes: You are pushing directly to a hosted repository. '.
|
||||
'This will not work. See "No Direct Pushes" in the documentation '.
|
||||
'for more information.'));
|
||||
}
|
||||
}
|
||||
|
||||
if ($repository->isHg()) {
|
||||
|
@ -181,18 +183,24 @@ $engine->setStdin($stdin);
|
|||
$engine->setOriginalArgv(array_slice($argv, 2));
|
||||
|
||||
$remote_address = getenv(DiffusionCommitHookEngine::ENV_REMOTE_ADDRESS);
|
||||
if (strlen($remote_address)) {
|
||||
$engine->setRemoteAddress($remote_address);
|
||||
if ($remote_address !== false) {
|
||||
if (phutil_nonempty_string($remote_address)) {
|
||||
$engine->setRemoteAddress($remote_address);
|
||||
}
|
||||
}
|
||||
|
||||
$remote_protocol = getenv(DiffusionCommitHookEngine::ENV_REMOTE_PROTOCOL);
|
||||
if (strlen($remote_protocol)) {
|
||||
$engine->setRemoteProtocol($remote_protocol);
|
||||
if ($remote_protocol !== false) {
|
||||
if (phutil_nonempty_string($remote_protocol)) {
|
||||
$engine->setRemoteProtocol($remote_protocol);
|
||||
}
|
||||
}
|
||||
|
||||
$request_identifier = getenv(DiffusionCommitHookEngine::ENV_REQUEST);
|
||||
if (strlen($request_identifier)) {
|
||||
$engine->setRequestIdentifier($request_identifier);
|
||||
if ($request_identifier !== false) {
|
||||
if (phutil_nonempty_string($request_identifier)) {
|
||||
$engine->setRequestIdentifier($request_identifier);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
|
@ -36,7 +36,7 @@ $authstruct_raw = $cache->getKey($authstruct_key);
|
|||
|
||||
$authstruct = null;
|
||||
|
||||
if (strlen($authstruct_raw)) {
|
||||
if (phutil_nonempty_string($authstruct_raw)) {
|
||||
try {
|
||||
$authstruct = phutil_json_decode($authstruct_raw);
|
||||
} catch (Exception $ex) {
|
||||
|
@ -82,13 +82,13 @@ if ($authstruct === null) {
|
|||
// Strip out newlines and other nonsense from the key type and key body.
|
||||
$type = $ssh_key->getKeyType();
|
||||
$type = preg_replace('@[\x00-\x20]+@', '', $type);
|
||||
if (!strlen($type)) {
|
||||
if (!phutil_nonempty_string($type)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$key = $ssh_key->getKeyBody();
|
||||
$key = preg_replace('@[\x00-\x20]+@', '', $key);
|
||||
if (!strlen($key)) {
|
||||
if (!phutil_nonempty_string($key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -135,7 +135,7 @@ foreach ($authstruct['keys'] as $key_struct) {
|
|||
|
||||
$cmd = csprintf('%s %Ls', $bin, $key_argv);
|
||||
|
||||
if (strlen($instance)) {
|
||||
if (phutil_nonempty_string($instance)) {
|
||||
$cmd = csprintf('PHABRICATOR_INSTANCE=%s %C', $instance, $cmd);
|
||||
}
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ try {
|
|||
'--phabricator-ssh-device',
|
||||
$user_name,
|
||||
$device_name));
|
||||
} else if (strlen($user_name)) {
|
||||
} else if (phutil_nonempty_string($user_name)) {
|
||||
$user = id(new PhabricatorPeopleQuery())
|
||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||
->withUsernames(array($user_name))
|
||||
|
@ -117,7 +117,7 @@ try {
|
|||
|
||||
id(new PhabricatorAuthSessionEngine())
|
||||
->willServeRequestForUser($user);
|
||||
} else if (strlen($device_name)) {
|
||||
} else if (phutil_nonempty_string($device_name)) {
|
||||
if (!$remote_address) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
|
|
|
@ -39,7 +39,7 @@ $data = array();
|
|||
$futures = array();
|
||||
|
||||
foreach (explode("\n", trim($input)) as $file) {
|
||||
if (!strlen($file)) {
|
||||
if (!phutil_nonempty_string($file)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ $data = array();
|
|||
$futures = array();
|
||||
|
||||
foreach (explode("\n", trim($input)) as $file) {
|
||||
if (!strlen($file)) {
|
||||
if (!phutil_nonempty_string($file)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -5843,6 +5843,7 @@ phutil_register_library_map(array(
|
|||
'PonderQuestionSearchEngine' => 'applications/ponder/query/PonderQuestionSearchEngine.php',
|
||||
'PonderQuestionStatus' => 'applications/ponder/constants/PonderQuestionStatus.php',
|
||||
'PonderQuestionStatusController' => 'applications/ponder/controller/PonderQuestionStatusController.php',
|
||||
'PonderQuestionStatusTestCase' => 'applications/ponder/storage/__tests__/PonderQuestionStatusTestCase.php',
|
||||
'PonderQuestionStatusTransaction' => 'applications/ponder/xaction/PonderQuestionStatusTransaction.php',
|
||||
'PonderQuestionTitleTransaction' => 'applications/ponder/xaction/PonderQuestionTitleTransaction.php',
|
||||
'PonderQuestionTransaction' => 'applications/ponder/storage/PonderQuestionTransaction.php',
|
||||
|
@ -8401,6 +8402,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorApplicationTransactionInterface',
|
||||
'PhabricatorPolicyInterface',
|
||||
'PhabricatorFlaggableInterface',
|
||||
'PhabricatorMentionableInterface',
|
||||
'PhabricatorSubscribableInterface',
|
||||
'PhabricatorDestructibleInterface',
|
||||
'PhabricatorSpacesInterface',
|
||||
|
@ -12756,6 +12758,7 @@ phutil_register_library_map(array(
|
|||
'PonderQuestionSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'PonderQuestionStatus' => 'PonderConstants',
|
||||
'PonderQuestionStatusController' => 'PonderController',
|
||||
'PonderQuestionStatusTestCase' => 'PhutilTestCase',
|
||||
'PonderQuestionStatusTransaction' => 'PonderQuestionTransactionType',
|
||||
'PonderQuestionTitleTransaction' => 'PonderQuestionTransactionType',
|
||||
'PonderQuestionTransaction' => 'PhabricatorModularTransaction',
|
||||
|
|
|
@ -66,7 +66,7 @@ final class AphrontRequest extends Phobject {
|
|||
}
|
||||
|
||||
public static function parseURILineRange($range, $limit) {
|
||||
if (!strlen($range)) {
|
||||
if (!phutil_nonempty_string($range)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -234,7 +234,7 @@ final class AphrontRequest extends Phobject {
|
|||
|
||||
$raw_data = phutil_string_cast($this->requestData[$name]);
|
||||
$raw_data = trim($raw_data);
|
||||
if (!strlen($raw_data)) {
|
||||
if (!phutil_nonempty_string($raw_data)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
|
@ -499,7 +499,7 @@ final class AphrontRequest extends Phobject {
|
|||
// domain is. This makes setup easier, and we'll tell administrators to
|
||||
// configure a base domain during the setup process.
|
||||
$base_uri = PhabricatorEnv::getEnvConfig('phabricator.base-uri');
|
||||
if (!strlen($base_uri)) {
|
||||
if (!phutil_nonempty_string($base_uri)) {
|
||||
return new PhutilURI('http://'.$host.'/');
|
||||
}
|
||||
|
||||
|
@ -956,7 +956,7 @@ final class AphrontRequest extends Phobject {
|
|||
$submit_cookie = PhabricatorCookies::COOKIE_SUBMIT;
|
||||
|
||||
$submit_key = $this->getCookie($submit_cookie);
|
||||
if (strlen($submit_key)) {
|
||||
if (phutil_nonempty_string($submit_key)) {
|
||||
$this->clearCookie($submit_cookie);
|
||||
$this->submitKey = $submit_key;
|
||||
}
|
||||
|
|
|
@ -823,7 +823,7 @@ final class AphrontApplicationConfiguration
|
|||
$raw_input = PhabricatorStartup::getRawInput();
|
||||
$parser = new PhutilQueryStringParser();
|
||||
|
||||
if (strlen($raw_input)) {
|
||||
if (phutil_nonempty_string($raw_input)) {
|
||||
$content_type = idx($_SERVER, 'CONTENT_TYPE');
|
||||
$is_multipart = preg_match('@^multipart/form-data@i', $content_type);
|
||||
if ($is_multipart) {
|
||||
|
|
|
@ -64,7 +64,7 @@ final class AphrontAjaxResponse extends AphrontResponse {
|
|||
if ($viewer) {
|
||||
$postprocessor_key = $viewer->getUserSetting(
|
||||
PhabricatorAccessibilitySetting::SETTINGKEY);
|
||||
if (strlen($postprocessor_key)) {
|
||||
if (phutil_nonempty_string($postprocessor_key)) {
|
||||
$response->setPostprocessorKey($postprocessor_key);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ final class AphrontFileResponse extends AphrontResponse {
|
|||
}
|
||||
|
||||
public function setDownload($download) {
|
||||
if (!strlen($download)) {
|
||||
if (!phutil_nonempty_string($download)) {
|
||||
$download = 'untitled';
|
||||
}
|
||||
$this->download = $download;
|
||||
|
|
|
@ -21,7 +21,7 @@ final class AphrontWebpageResponse extends AphrontHTMLResponse {
|
|||
|
||||
public function buildResponseString() {
|
||||
$unexpected_output = $this->getUnexpectedOutput();
|
||||
if (strlen($unexpected_output)) {
|
||||
if (phutil_nonempty_string($unexpected_output)) {
|
||||
$style = array(
|
||||
'background: linear-gradient(180deg, #eeddff, #ddbbff);',
|
||||
'white-space: pre-wrap;',
|
||||
|
|
|
@ -8,7 +8,7 @@ final class AphrontPHPHTTPSink extends AphrontHTTPSink {
|
|||
protected function emitHTTPStatus($code, $message = '') {
|
||||
if ($code != 200) {
|
||||
$header = "HTTP/1.0 {$code}";
|
||||
if (strlen($message)) {
|
||||
if (phutil_nonempty_string($message)) {
|
||||
$header .= " {$message}";
|
||||
}
|
||||
header($header);
|
||||
|
|
|
@ -15,7 +15,7 @@ abstract class AphrontSite extends Phobject {
|
|||
|
||||
protected function isHostMatch($host, array $uris) {
|
||||
foreach ($uris as $uri) {
|
||||
if (!strlen($uri)) {
|
||||
if (!phutil_nonempty_string($uri)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ final class PhabricatorPlatformSite extends PhabricatorSite {
|
|||
// If no base URI has been configured yet, match this site so the user
|
||||
// can follow setup instructions.
|
||||
$base_uri = PhabricatorEnv::getEnvConfig('phabricator.base-uri');
|
||||
if (!strlen($base_uri)) {
|
||||
if (!phutil_nonempty_string($base_uri)) {
|
||||
return new PhabricatorPlatformSite();
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ final class PhabricatorResourceSite extends PhabricatorSite {
|
|||
$host = $request->getHost();
|
||||
|
||||
$uri = PhabricatorEnv::getEnvConfig('security.alternate-file-domain');
|
||||
if (!strlen($uri)) {
|
||||
if (!phutil_nonempty_string($uri)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ final class PhabricatorShortSite extends PhabricatorSite {
|
|||
$host = $request->getHost();
|
||||
|
||||
$uri = PhabricatorEnv::getEnvConfig('phurl.short-uri');
|
||||
if (!strlen($uri)) {
|
||||
if (!phutil_nonempty_string($uri)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ final class PhutilTwitchAuthAdapter extends PhutilOAuthAuthAdapter {
|
|||
}
|
||||
|
||||
public function getAccountID() {
|
||||
return $this->getOAuthAccountData('_id');
|
||||
return $this->getOAuthAccountData('id');
|
||||
}
|
||||
|
||||
public function getAccountEmail() {
|
||||
|
@ -22,11 +22,11 @@ final class PhutilTwitchAuthAdapter extends PhutilOAuthAuthAdapter {
|
|||
}
|
||||
|
||||
public function getAccountName() {
|
||||
return $this->getOAuthAccountData('name');
|
||||
return $this->getOAuthAccountData('login');
|
||||
}
|
||||
|
||||
public function getAccountImageURI() {
|
||||
return $this->getOAuthAccountData('logo');
|
||||
return $this->getOAuthAccountData('profile_image_url');
|
||||
}
|
||||
|
||||
public function getAccountURI() {
|
||||
|
@ -42,11 +42,11 @@ final class PhutilTwitchAuthAdapter extends PhutilOAuthAuthAdapter {
|
|||
}
|
||||
|
||||
protected function getAuthenticateBaseURI() {
|
||||
return 'https://api.twitch.tv/kraken/oauth2/authorize';
|
||||
return 'https://id.twitch.tv/oauth2/authorize';
|
||||
}
|
||||
|
||||
protected function getTokenBaseURI() {
|
||||
return 'https://api.twitch.tv/kraken/oauth2/token';
|
||||
return 'https://id.twitch.tv/oauth2/token';
|
||||
}
|
||||
|
||||
public function getScope() {
|
||||
|
@ -69,7 +69,7 @@ final class PhutilTwitchAuthAdapter extends PhutilOAuthAuthAdapter {
|
|||
return id(new PhutilTwitchFuture())
|
||||
->setClientID($this->getClientID())
|
||||
->setAccessToken($this->getAccessToken())
|
||||
->setRawTwitchQuery('user')
|
||||
->setRawTwitchQuery('users')
|
||||
->resolve();
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ final class PhabricatorAuthPasswordException
|
|||
extends Exception {
|
||||
|
||||
private $passwordError;
|
||||
private $confirmErorr;
|
||||
private $confirmError;
|
||||
|
||||
public function __construct(
|
||||
$message,
|
||||
|
|
|
@ -8,7 +8,22 @@ final class PhabricatorCalendarImportEditController
|
|||
->setController($this);
|
||||
|
||||
$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/');
|
||||
|
||||
$import_type = $request->getStr('importType');
|
||||
|
@ -27,6 +42,18 @@ final class PhabricatorCalendarImportEditController
|
|||
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) {
|
||||
$import_engines = PhabricatorCalendarImportEngine::getAllImportEngines();
|
||||
|
||||
|
|
|
@ -83,6 +83,12 @@ final class PhabricatorCalendarImportEditEngine
|
|||
$engine = $object->getEngine();
|
||||
$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(
|
||||
id(new PhabricatorTextEditField())
|
||||
->setKey('name')
|
||||
|
@ -94,6 +100,15 @@ final class PhabricatorCalendarImportEditEngine
|
|||
->setConduitTypeDescription(pht('New import name.'))
|
||||
->setPlaceholder($object->getDisplayName())
|
||||
->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())
|
||||
->setKey('disabled')
|
||||
->setOptions(pht('Active'), pht('Disabled'))
|
||||
|
|
|
@ -222,12 +222,16 @@ final class PhabricatorCalendarEventQuery
|
|||
|
||||
$limit = $this->getRecurrenceLimit($event, $raw_limit);
|
||||
|
||||
// note that this can be NULL for some imported events
|
||||
$set = $event->newRecurrenceSet();
|
||||
|
||||
$recurrences = $set->getEventsBetween(
|
||||
$start_date,
|
||||
$end_date,
|
||||
$limit + 1);
|
||||
$recurrences = array();
|
||||
if ($set) {
|
||||
$recurrences = $set->getEventsBetween(
|
||||
$start_date,
|
||||
$end_date,
|
||||
$limit + 1);
|
||||
}
|
||||
|
||||
// We're generating events from the beginning and then filtering them
|
||||
// here (instead of only generating events starting at the start date)
|
||||
|
|
|
@ -15,13 +15,13 @@ final class CelerityDarkModePostprocessor
|
|||
return array(
|
||||
|
||||
// Fonts
|
||||
'basefont' => "13px 'Segoe UI', 'Segoe UI Emoji', ".
|
||||
"'Segoe UI Symbol', 'Lato', 'Helvetica Neue', ".
|
||||
"Helvetica, Arial, sans-serif",
|
||||
'basefont' => "13px -apple-system, system-ui, BlinkMacSystemFont, ".
|
||||
"'Segoe UI', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Lato', ".
|
||||
"'Helvetica Neue', Helvetica, Arial, sans-serif",
|
||||
|
||||
'fontfamily' => "'Segoe UI', 'Segoe UI Emoji', ".
|
||||
"'Segoe UI Symbol', 'Lato', 'Helvetica Neue', ".
|
||||
"Helvetica, Arial, sans-serif",
|
||||
'fontfamily' => "-apple-system, system-ui, BlinkMacSystemFont, ".
|
||||
"'Segoe UI', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Lato', ".
|
||||
"'Helvetica Neue', Helvetica, Arial, sans-serif",
|
||||
|
||||
// Drop Shadow
|
||||
'dropshadow' => '0 2px 12px rgba(0, 0, 0, .20)',
|
||||
|
|
|
@ -20,13 +20,13 @@ final class CelerityDefaultPostprocessor
|
|||
public function buildVariables() {
|
||||
return array(
|
||||
// Fonts
|
||||
'basefont' => "13px 'Segoe UI', 'Segoe UI Emoji', ".
|
||||
"'Segoe UI Symbol', 'Lato', 'Helvetica Neue', ".
|
||||
"Helvetica, Arial, sans-serif",
|
||||
'basefont' => "13px -apple-system, system-ui, BlinkMacSystemFont, ".
|
||||
"'Segoe UI', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Lato', ".
|
||||
"'Helvetica Neue', Helvetica, Arial, sans-serif",
|
||||
|
||||
'fontfamily' => "'Segoe UI', 'Segoe UI Emoji', ".
|
||||
"'Segoe UI Symbol', 'Lato', 'Helvetica Neue', ".
|
||||
"Helvetica, Arial, sans-serif",
|
||||
'fontfamily' => "-apple-system, system-ui, BlinkMacSystemFont, ".
|
||||
"'Segoe UI', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Lato', ".
|
||||
"'Helvetica Neue', Helvetica, Arial, sans-serif",
|
||||
|
||||
// Drop Shadow
|
||||
'dropshadow' => '0 2px 12px rgba(0, 0, 0, .20)',
|
||||
|
|
|
@ -14,9 +14,9 @@ final class CelerityLargeFontPostprocessor
|
|||
public function buildVariables() {
|
||||
return array(
|
||||
|
||||
'basefont' => "14px 'Segoe UI', 'Segoe UI Web Regular', ".
|
||||
"'Segoe UI Symbol', 'Lato', 'Helvetica Neue', Helvetica, ".
|
||||
"Arial, sans-serif",
|
||||
'basefont' => "14px -apple-system, system-ui, BlinkMacSystemFont, ".
|
||||
"'Segoe UI', 'Segoe UI Web Regular', 'Segoe UI Symbol', 'Lato', ".
|
||||
"'Helvetica Neue', Helvetica, Arial, sans-serif",
|
||||
|
||||
// Font Sizes
|
||||
'biggestfontsize' => '16px',
|
||||
|
|
|
@ -247,6 +247,10 @@ final class PhabricatorConduitConsoleController
|
|||
));
|
||||
}
|
||||
|
||||
$view->addProperty(
|
||||
pht('Summary'),
|
||||
$method->getMethodSummary());
|
||||
|
||||
$view->addProperty(
|
||||
pht('Returns'),
|
||||
$method->getReturnType());
|
||||
|
|
|
@ -151,19 +151,19 @@ final class PhabricatorStorageSetupCheck extends PhabricatorSetupCheck {
|
|||
|
||||
$how_many = 0;
|
||||
|
||||
if (strlen($access_key)) {
|
||||
if (phutil_nonempty_string($access_key)) {
|
||||
$how_many++;
|
||||
}
|
||||
|
||||
if (strlen($secret_key)) {
|
||||
if (phutil_nonempty_string($secret_key)) {
|
||||
$how_many++;
|
||||
}
|
||||
|
||||
if (strlen($region)) {
|
||||
if (phutil_nonempty_string($region)) {
|
||||
$how_many++;
|
||||
}
|
||||
|
||||
if (strlen($endpoint)) {
|
||||
if (phutil_nonempty_string($endpoint)) {
|
||||
$how_many++;
|
||||
}
|
||||
|
||||
|
|
|
@ -178,6 +178,7 @@ final class PhabricatorConfigConsoleController
|
|||
'('.
|
||||
implode('|', array(
|
||||
'we\.phorge\.it/',
|
||||
'github\.com/phorgeit/',
|
||||
'github\.com/phacility/',
|
||||
'secure\.phabricator\.com/',
|
||||
)).
|
||||
|
|
|
@ -60,8 +60,20 @@ final class PhabricatorConfigClusterSearchController
|
|||
|
||||
foreach ($service->getHosts() as $host) {
|
||||
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 = idx($status_map, $status, array());
|
||||
$status = idx($status_map, $status, $default_status);
|
||||
} catch (Exception $ex) {
|
||||
$status['icon'] = 'fa-times';
|
||||
$status['label'] = pht('Connection Error');
|
||||
|
|
|
@ -23,6 +23,17 @@ final class DifferentialRevisionTitleTransaction
|
|||
}
|
||||
|
||||
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(
|
||||
'%s retitled %s from %s to %s.',
|
||||
$this->renderAuthor(),
|
||||
|
|
|
@ -55,7 +55,7 @@ final class DiffusionHistoryQueryConduitAPIMethod
|
|||
$limit = $request->getValue('limit');
|
||||
|
||||
if (strlen($against_hash)) {
|
||||
$commit_range = "${against_hash}..${commit_hash}";
|
||||
$commit_range = "{$against_hash}..{$commit_hash}";
|
||||
} else {
|
||||
$commit_range = $commit_hash;
|
||||
}
|
||||
|
|
|
@ -31,8 +31,7 @@ final class DiffusionRepositoryBasicsManagementPanel
|
|||
$repository = $this->getRepository();
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$action_list = id(new PhabricatorActionListView())
|
||||
->setViewer($viewer);
|
||||
$action_list = $this->newActionList();
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
|
|
|
@ -111,6 +111,9 @@ abstract class DiffusionRepositoryManagementPanel
|
|||
|
||||
final protected function newActionList() {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
// Generating this ID allows to spawn the "Actions" menu
|
||||
// on mobile on the header
|
||||
$action_id = celerity_generate_unique_node_id();
|
||||
|
||||
return id(new PhabricatorActionListView())
|
||||
|
|
|
@ -31,11 +31,11 @@ final class PhabricatorS3FileStorageEngine
|
|||
$endpoint = PhabricatorEnv::getEnvConfig('amazon-s3.endpoint');
|
||||
$region = PhabricatorEnv::getEnvConfig('amazon-s3.region');
|
||||
|
||||
return (strlen($bucket) &&
|
||||
strlen($access_key) &&
|
||||
strlen($secret_key) &&
|
||||
strlen($endpoint) &&
|
||||
strlen($region));
|
||||
return phutil_nonempty_string($bucket) &&
|
||||
phutil_nonempty_string($access_key) &&
|
||||
phutil_nonempty_string($secret_key) &&
|
||||
phutil_nonempty_string($endpoint) &&
|
||||
phutil_nonempty_string($region);
|
||||
}
|
||||
|
||||
|
||||
|
@ -57,7 +57,7 @@ final class PhabricatorS3FileStorageEngine
|
|||
$parts[] = 'phabricator';
|
||||
|
||||
$instance_name = PhabricatorEnv::getEnvConfig('cluster.instance');
|
||||
if (strlen($instance_name)) {
|
||||
if (phutil_nonempty_string($instance_name)) {
|
||||
$parts[] = $instance_name;
|
||||
}
|
||||
|
||||
|
|
|
@ -856,7 +856,7 @@ final class PhabricatorFile extends PhabricatorFileDAO
|
|||
// instance identity in the path allows us to distinguish between requests
|
||||
// originating from different instances but served through the same CDN.
|
||||
$instance = PhabricatorEnv::getEnvConfig('cluster.instance');
|
||||
if (strlen($instance)) {
|
||||
if (phutil_nonempty_string($instance)) {
|
||||
$parts[] = '@'.$instance;
|
||||
}
|
||||
|
||||
|
@ -903,7 +903,7 @@ final class PhabricatorFile extends PhabricatorFileDAO
|
|||
$parts[] = 'xform';
|
||||
|
||||
$instance = PhabricatorEnv::getEnvConfig('cluster.instance');
|
||||
if (strlen($instance)) {
|
||||
if (phutil_nonempty_string($instance)) {
|
||||
$parts[] = '@'.$instance;
|
||||
}
|
||||
|
||||
|
|
|
@ -333,8 +333,8 @@ final class HeraldNewController extends HeraldController {
|
|||
$cancel_params = $params;
|
||||
unset($cancel_params['type']);
|
||||
|
||||
$cancel_uri = $this->getApplicationURI('new/');
|
||||
$cancel_uri = new PhutilURI($cancel_uri, $params);
|
||||
$cancel_uri = $this->getApplicationURI('create/');
|
||||
$cancel_uri = new PhutilURI($cancel_uri, $cancel_params);
|
||||
|
||||
$form->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
|
|
|
@ -35,7 +35,7 @@ final class HeraldTranscriptPHIDType extends PhabricatorPHIDType {
|
|||
$id = $xscript->getID();
|
||||
|
||||
$handle->setName(pht('Transcript %s', $id));
|
||||
$handle->setURI("/herald/transcript/${id}/");
|
||||
$handle->setURI("/herald/transcript/$id/");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -507,7 +507,7 @@ final class PhabricatorMailEmailEngine
|
|||
public function newDefaultEmailAddress() {
|
||||
$raw_address = PhabricatorEnv::getEnvConfig('metamta.default-address');
|
||||
|
||||
if (!strlen($raw_address)) {
|
||||
if (!$raw_address) {
|
||||
$domain = $this->newMailDomain();
|
||||
$raw_address = "noreply@{$domain}";
|
||||
}
|
||||
|
@ -527,7 +527,7 @@ final class PhabricatorMailEmailEngine
|
|||
|
||||
private function newMailDomain() {
|
||||
$domain = PhabricatorEnv::getEnvConfig('metamta.reply-handler-domain');
|
||||
if (strlen($domain)) {
|
||||
if ($domain) {
|
||||
return $domain;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,8 @@ final class PhabricatorMetaMTAReceivedMailProcessingException
|
|||
$this->statusCode = $args[0];
|
||||
|
||||
$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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -152,7 +152,7 @@ final class PhabricatorNotificationServerRef
|
|||
->setPath($full_path);
|
||||
|
||||
$instance = PhabricatorEnv::getEnvConfig('cluster.instance');
|
||||
if (strlen($instance)) {
|
||||
if (phutil_nonempty_string($instance)) {
|
||||
$uri->replaceQueryParam('instance', $instance);
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,12 @@ final class PassphraseCredentialEditController extends PassphraseController {
|
|||
// Prefill username if provided.
|
||||
$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')) {
|
||||
$type->didInitializeNewCredential($viewer, $credential);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ final class PassphraseCredential extends PassphraseDAO
|
|||
PhabricatorApplicationTransactionInterface,
|
||||
PhabricatorPolicyInterface,
|
||||
PhabricatorFlaggableInterface,
|
||||
PhabricatorMentionableInterface,
|
||||
PhabricatorSubscribableInterface,
|
||||
PhabricatorDestructibleInterface,
|
||||
PhabricatorSpacesInterface,
|
||||
|
|
|
@ -110,9 +110,11 @@ final class PholioImageFileTransaction
|
|||
$new_phids = $value;
|
||||
|
||||
$file_phids = array();
|
||||
foreach ($new_phids as $phid) {
|
||||
$file_phids[] = $editor->loadPholioImage($object, $phid)
|
||||
->getFilePHID();
|
||||
foreach ($new_phids as $phids) {
|
||||
foreach ($phids as $phid) {
|
||||
$file_phids[] = $editor->loadPholioImage($object, $phid)
|
||||
->getFilePHID();
|
||||
}
|
||||
}
|
||||
|
||||
return $file_phids;
|
||||
|
|
|
@ -18,6 +18,9 @@ final class PhrictionDocumentDatasource
|
|||
public function loadResults() {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$app_type = pht('Wiki Document');
|
||||
$mid_dot = "\xC2\xB7";
|
||||
|
||||
$query = id(new PhrictionDocumentQuery())
|
||||
->setViewer($viewer)
|
||||
->needContent(true);
|
||||
|
@ -34,15 +37,25 @@ final class PhrictionDocumentDatasource
|
|||
foreach ($documents as $document) {
|
||||
$content = $document->getContent();
|
||||
|
||||
if (!$document->isActive()) {
|
||||
$closed = $document->getStatusDisplayName();
|
||||
} else {
|
||||
if ($document->isActive()) {
|
||||
$closed = null;
|
||||
} else {
|
||||
$closed = $document->getStatusDisplayName();
|
||||
}
|
||||
|
||||
$slug = $document->getSlug();
|
||||
$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';
|
||||
$autocomplete = '[[ '.$slug.' ]]';
|
||||
|
||||
|
@ -51,7 +64,7 @@ final class PhrictionDocumentDatasource
|
|||
->setDisplayName($title)
|
||||
->setURI($document->getURI())
|
||||
->setPHID($document->getPHID())
|
||||
->setDisplayType($slug)
|
||||
->setDisplayType($display_type)
|
||||
->setPriorityType('wiki')
|
||||
->setImageSprite($sprite)
|
||||
->setAutocomplete($autocomplete)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -157,6 +157,9 @@ final class PonderQuestionSearchEngine
|
|||
'Asked by %s',
|
||||
$handles[$question->getAuthorPHID()]->renderLink()));
|
||||
|
||||
// Render Closed Questions as striked in query results
|
||||
$item->setDisabled($question->isStatusClosed());
|
||||
|
||||
$item->addAttribute(
|
||||
pht(
|
||||
'%s Answer(s)',
|
||||
|
|
|
@ -137,6 +137,14 @@ final class PonderQuestion extends PonderDAO
|
|||
return self::MARKUP_FIELD_CONTENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whenever this Question has whatever closed status
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isStatusClosed() {
|
||||
return PonderQuestionStatus::isQuestionStatusClosed($this->status);
|
||||
}
|
||||
|
||||
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -693,10 +693,19 @@ final class PhabricatorProjectBoardViewController
|
|||
->newCreateActionSpecifications(array());
|
||||
|
||||
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())
|
||||
->setIcon($spec['icon'])
|
||||
->setName($spec['name'])
|
||||
->setHref($spec['uri'])
|
||||
->setHref($spec_href)
|
||||
->setDisabled($spec['disabled'])
|
||||
->addSigil('column-add-task')
|
||||
->setMetadata(
|
||||
|
|
|
@ -43,7 +43,7 @@ final class PhabricatorProjectProjectPHIDType extends PhabricatorPHIDType {
|
|||
|
||||
$handle->setName($name);
|
||||
|
||||
if (strlen($slug)) {
|
||||
if (phutil_nonempty_string($slug)) {
|
||||
$handle->setObjectName('#'.$slug);
|
||||
$handle->setMailStampName('#'.$slug);
|
||||
$handle->setURI("/tag/{$slug}/");
|
||||
|
|
|
@ -238,7 +238,7 @@ final class PhabricatorRepositoryPullEngine
|
|||
$identifier = $repository->getPHID();
|
||||
|
||||
$instance = PhabricatorEnv::getEnvConfig('cluster.instance');
|
||||
if (strlen($instance)) {
|
||||
if (phutil_nonempty_string($instance)) {
|
||||
$identifier = "{$identifier}:{$instance}";
|
||||
}
|
||||
|
||||
|
|
|
@ -2480,7 +2480,8 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO
|
|||
$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(
|
||||
PhabricatorRepositoryURI::BUILTIN_PROTOCOL_SSH => $has_ssh,
|
||||
|
|
|
@ -48,7 +48,7 @@ final class PhabricatorSearchApplicationStorageEnginePanel
|
|||
}
|
||||
|
||||
$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.',
|
||||
'/config/edit/cluster.search/',
|
||||
'cluster.search',
|
||||
|
|
|
@ -16,7 +16,7 @@ final class PhabricatorSystemReadOnlyController
|
|||
case PhabricatorEnv::READONLY_CONFIG:
|
||||
$title = pht('Administrative Read-Only Mode');
|
||||
$body[] = pht(
|
||||
'An administrator has placed this server into read-only mode.');
|
||||
'An Administrator has placed this server into read-only mode.');
|
||||
$body[] = pht(
|
||||
'This mode may be used to perform temporary maintenance, test '.
|
||||
'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 '.
|
||||
'yelling "Hey! Why is %s in read-only mode??!" using '.
|
||||
'your very loudest outside voice.',
|
||||
PlatformSymbols::getPlatformServerSymbol());
|
||||
PlatformSymbols::getPlatformServerName());
|
||||
$body[] = pht(
|
||||
'This mode is active because it is enabled in the configuration '.
|
||||
'option "%s".',
|
||||
|
@ -110,7 +110,7 @@ final class PhabricatorSystemReadOnlyController
|
|||
|
||||
if ($viewer->getIsAdmin()) {
|
||||
$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 '.
|
||||
'current state of affairs.',
|
||||
phutil_tag(
|
||||
|
|
|
@ -539,7 +539,7 @@ abstract class PhabricatorApplicationTransaction
|
|||
case PhabricatorTransactions::TYPE_COMMENT;
|
||||
$comment = $this->getComment();
|
||||
if ($comment && $comment->getIsRemoved()) {
|
||||
return 'black';
|
||||
return 'grey';
|
||||
}
|
||||
break;
|
||||
case PhabricatorTransactions::TYPE_EDGE:
|
||||
|
|
|
@ -493,6 +493,11 @@ class PhabricatorApplicationTransactionView extends AphrontView {
|
|||
$xaction->getComment() &&
|
||||
$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) {
|
||||
$event->setIsEdited(true);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
],
|
||||
"groups": {
|
||||
"javascript": {
|
||||
"name": "Javascript"
|
||||
"name": "JavaScript"
|
||||
},
|
||||
"lore": {
|
||||
"name": "Phorge Lore"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "phorge",
|
||||
"title": "Phorge User Documentation",
|
||||
"title": "Phorge Administrator and User Documentation",
|
||||
"short": "User Docs",
|
||||
"preface": "Instructions for installing, configuring, and using Phorge.",
|
||||
"root": "../../../",
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
@title Javascript Object and Array
|
||||
@title JavaScript Object and Array
|
||||
@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
|
||||
behavior.
|
||||
|
||||
= 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:
|
||||
|
||||
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 =
|
||||
|
||||
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
|
||||
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").
|
||||
|
||||
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'
|
||||
};
|
||||
|
||||
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.
|
||||
|
||||
|
@ -71,8 +77,14 @@ Don't store key-value pairs in Arrays and don't expect Objects to be ordered.
|
|||
var a = [];
|
||||
a['name'] = 'Hubert'; // No! Don't do this!
|
||||
|
||||
This technically works because Arrays are Objects and you think everything is
|
||||
fine and dandy, but it won't do what you want and will burn you.
|
||||
Technically, both work because Arrays //are// Objects and you think everything
|
||||
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 =
|
||||
|
||||
|
@ -140,7 +152,7 @@ The correct way to deal with this is:
|
|||
continue;
|
||||
}
|
||||
f(list[ii]);
|
||||
}
|
||||
}
|
||||
|
||||
Avoid sparse arrays if possible.
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
@title Javascript Pitfalls
|
||||
@title JavaScript Pitfalls
|
||||
@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.
|
||||
|
||||
= 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
|
||||
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
|
||||
but it is not obvious. Navigate these troubled waters with
|
||||
@{article:Javascript Object and Array}.
|
||||
@{article:JavaScript Object and Array}.
|
||||
|
||||
= typeof null == "object" =
|
||||
|
||||
This statement is true in Javascript:
|
||||
This statement is true in JavaScript:
|
||||
|
||||
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 =
|
||||
|
||||
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
|
||||
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:
|
||||
|
||||
lang=js
|
||||
|
@ -83,5 +83,5 @@ Number.prototype, etc.) and their logical behavior is at best absurd and at
|
|||
worst strictly wrong.
|
||||
|
||||
**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.
|
||||
|
|
|
@ -256,7 +256,7 @@ echo $obj->flavor; // Outputs 'coconut'.
|
|||
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()`.
|
||||
|
||||
= Invoking `new` With an Argument Vector is Really Hard =
|
||||
|
|
|
@ -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;
|
||||
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
|
||||
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
|
||||
features grafted onto it without real direction had left it slow and difficult
|
||||
|
|
|
@ -11,6 +11,7 @@ If you haven't, see @{article:Installation Guide}.
|
|||
The next steps are:
|
||||
|
||||
- Configure your webserver (Apache, nginx, or lighttpd).
|
||||
- Configure the databases.
|
||||
- Access Phorge with your browser.
|
||||
- Follow the instructions to complete setup.
|
||||
|
||||
|
|
|
@ -15,10 +15,17 @@ Phorge, you will need:
|
|||
- a domain name (like `phorge.example.com`);
|
||||
- basic sysadmin skills;
|
||||
- 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.
|
||||
|
||||
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
|
||||
=========================
|
||||
|
||||
|
@ -71,7 +78,11 @@ Beyond an operating system, you will need **a webserver**.
|
|||
You will also need:
|
||||
|
||||
- **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
|
||||
note:
|
||||
|
@ -106,7 +117,7 @@ Here's a general description of what you need to install:
|
|||
|
||||
- git (usually called "git" in package management systems)
|
||||
- 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")
|
||||
- Required PHP extensions: mbstring, iconv, mysql (or mysqli), curl, pcntl
|
||||
(these might be something like "php-mysql" or "php5-mysqlnd")
|
||||
|
|
|
@ -229,7 +229,7 @@ final class PhabricatorDatabaseRef
|
|||
$host = $this->getHost();
|
||||
|
||||
$port = $this->getPort();
|
||||
if (strlen($port)) {
|
||||
if ($port) {
|
||||
return "{$host}:{$port}";
|
||||
}
|
||||
|
||||
|
|
16
src/infrastructure/env/PhabricatorEnv.php
vendored
16
src/infrastructure/env/PhabricatorEnv.php
vendored
|
@ -125,7 +125,7 @@ final class PhabricatorEnv extends Phobject {
|
|||
// If an instance identifier is defined, write it into the environment so
|
||||
// it's available to subprocesses.
|
||||
$instance = self::getEnvConfig('cluster.instance');
|
||||
if (strlen($instance)) {
|
||||
if (phutil_nonempty_string($instance)) {
|
||||
putenv('PHABRICATOR_INSTANCE='.$instance);
|
||||
$_ENV['PHABRICATOR_INSTANCE'] = $instance;
|
||||
}
|
||||
|
@ -440,7 +440,7 @@ final class PhabricatorEnv extends Phobject {
|
|||
$uri = new PhutilURI($raw_uri);
|
||||
|
||||
$host = $uri->getDomain();
|
||||
if (!strlen($host)) {
|
||||
if (!phutil_nonempty_string($host)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -463,7 +463,7 @@ final class PhabricatorEnv extends Phobject {
|
|||
$self_map = array();
|
||||
foreach ($self_uris as $self_uri) {
|
||||
$host = id(new PhutilURI($self_uri))->getDomain();
|
||||
if (!strlen($host)) {
|
||||
if (!phutil_nonempty_string($host)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -669,7 +669,7 @@ final class PhabricatorEnv extends Phobject {
|
|||
public static function isValidLocalURIForLink($uri) {
|
||||
$uri = (string)$uri;
|
||||
|
||||
if (!strlen($uri)) {
|
||||
if (!phutil_nonempty_string($uri)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -734,7 +734,7 @@ final class PhabricatorEnv extends Phobject {
|
|||
$uri = new PhutilURI($raw_uri);
|
||||
|
||||
$proto = $uri->getProtocol();
|
||||
if (!strlen($proto)) {
|
||||
if (!$proto) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'URI "%s" is not a valid linkable resource. A valid linkable '.
|
||||
|
@ -753,7 +753,7 @@ final class PhabricatorEnv extends Phobject {
|
|||
}
|
||||
|
||||
$domain = $uri->getDomain();
|
||||
if (!strlen($domain)) {
|
||||
if (!$domain) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'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);
|
||||
|
||||
$proto = $uri->getProtocol();
|
||||
if (!strlen($proto)) {
|
||||
if (!$proto) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'URI "%s" is not a valid fetchable resource. A valid fetchable '.
|
||||
|
@ -820,7 +820,7 @@ final class PhabricatorEnv extends Phobject {
|
|||
}
|
||||
|
||||
$domain = $uri->getDomain();
|
||||
if (!strlen($domain)) {
|
||||
if (!$domain) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'URI "%s" is not a valid fetchable resource. A valid fetchable '.
|
||||
|
|
|
@ -24,7 +24,7 @@ final class PhabricatorSSHLog extends Phobject {
|
|||
);
|
||||
|
||||
$sudo_user = PhabricatorEnv::getEnvConfig('phd.user');
|
||||
if (strlen($sudo_user)) {
|
||||
if (phutil_nonempty_string($sudo_user)) {
|
||||
$data['S'] = $sudo_user;
|
||||
}
|
||||
|
||||
|
|
123
support/startup/__tests__/PreambleUtilsTestCase.php
Executable file
123
support/startup/__tests__/PreambleUtilsTestCase.php
Executable 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);
|
||||
}
|
|
@ -6,7 +6,8 @@ body {
|
|||
background: #f9f9f9;
|
||||
margin: 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;
|
||||
text-align: left;
|
||||
-webkit-text-size-adjust: none;
|
||||
|
|
|
@ -106,7 +106,8 @@
|
|||
|
||||
.harbormaster-log-expand-table td {
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
border-right: 1px solid {$paste.border};
|
||||
color: {$sh-yellowtext};
|
||||
white-space: nowrap;
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.phabricator-source-line > a::before {
|
||||
|
|
|
@ -525,7 +525,7 @@ properly, and submit values. */
|
|||
}
|
||||
|
||||
.aphront-form-preview-hidden {
|
||||
opacity: 0.5;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.aphront-form-error .phui-icon-view {
|
||||
|
|
|
@ -189,9 +189,30 @@
|
|||
overflow-x: auto;
|
||||
}
|
||||
|
||||
/*
|
||||
* Start Customization for removed comments
|
||||
* https://we.phorge.it/T15192
|
||||
*/
|
||||
|
||||
.phui-timeline-core-content .comment-deleted {
|
||||
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 {
|
||||
min-height: 23px;
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
}
|
||||
|
||||
.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 {
|
||||
|
|
30
webroot/rsrc/externals/javelin/lib/Workflow.js
vendored
30
webroot/rsrc/externals/javelin/lib/Workflow.js
vendored
|
@ -403,6 +403,20 @@ JX.install('Workflow', {
|
|||
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() {
|
||||
if (!this._pushed) {
|
||||
|
@ -536,6 +550,22 @@ JX.install('Workflow', {
|
|||
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();
|
||||
e.prevent();
|
||||
}
|
||||
|
|
|
@ -84,8 +84,19 @@ JX.install('Typeahead', {
|
|||
'mousedown',
|
||||
'tag:a',
|
||||
JX.bind(this, function(e) {
|
||||
if (!e.isRightButton()) {
|
||||
if (e.isNormalMouseEvent()) {
|
||||
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 |
|
@ -151,6 +151,13 @@ JX.install('WorkboardController', {
|
|||
},
|
||||
|
||||
_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
|
||||
// close the dropdown, but don't want to follow the link.
|
||||
e.prevent();
|
||||
|
@ -176,6 +183,13 @@ JX.install('WorkboardController', {
|
|||
},
|
||||
|
||||
_oneditcard: function(e) {
|
||||
|
||||
// Allow CTRL+click and maybe other actions
|
||||
if(!e.isNormalMouseEvent()) {
|
||||
e.stop();
|
||||
return;
|
||||
}
|
||||
|
||||
e.kill();
|
||||
|
||||
var column_node = e.getNode('project-column');
|
||||
|
|
|
@ -38,6 +38,20 @@ JX.install('PhabricatorFileUpload', {
|
|||
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) {
|
||||
var chunk;
|
||||
for (var ii = 0; ii < chunks.length; ii++) {
|
||||
|
@ -101,7 +115,19 @@ JX.install('PhabricatorFileUpload', {
|
|||
|
||||
switch (this.getStatus()) {
|
||||
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 = [
|
||||
JX.$N('strong', {}, ['Upload Complete (', link, ')']),
|
||||
|
|
Loading…
Add table
Reference in a new issue