mirror of
https://we.phorge.it/source/phorge.git
synced 2025-02-09 13:28:29 +01:00
Rough implementation of drag-and-drop file uploads
Summary: This gets all the major pieces working. Allows you to drag-and-drop files in Differential and Phriction, and embed files in remarkup with {Fxxx} references. See also task. I'm explicitly not documenting this yet since it's still pretty rough. Test Plan: Dragged and dropped stuff into Differential and Phriction. Reviewed By: jungejason Reviewers: jungejason, tuomaspelkonen, aran, tomo Commenters: tomo CC: aran, tomo, jungejason Differential Revision: 674
This commit is contained in:
parent
35d03d36c7
commit
9d3f33a7a6
13 changed files with 198 additions and 53 deletions
|
@ -54,7 +54,7 @@ celerity_register_resource_map(array(
|
||||||
),
|
),
|
||||||
'aphront-form-view-css' =>
|
'aphront-form-view-css' =>
|
||||||
array(
|
array(
|
||||||
'uri' => '/res/8ee16aba/rsrc/css/aphront/form-view.css',
|
'uri' => '/res/c79fd668/rsrc/css/aphront/form-view.css',
|
||||||
'type' => 'css',
|
'type' => 'css',
|
||||||
'requires' =>
|
'requires' =>
|
||||||
array(
|
array(
|
||||||
|
@ -117,7 +117,7 @@ celerity_register_resource_map(array(
|
||||||
),
|
),
|
||||||
'aphront-table-view-css' =>
|
'aphront-table-view-css' =>
|
||||||
array(
|
array(
|
||||||
'uri' => '/res/3ac9ba50/rsrc/css/aphront/table-view.css',
|
'uri' => '/res/f4f39a2e/rsrc/css/aphront/table-view.css',
|
||||||
'type' => 'css',
|
'type' => 'css',
|
||||||
'requires' =>
|
'requires' =>
|
||||||
array(
|
array(
|
||||||
|
@ -331,6 +331,18 @@ celerity_register_resource_map(array(
|
||||||
),
|
),
|
||||||
'disk' => '/rsrc/js/application/core/behavior-drag-and-drop.js',
|
'disk' => '/rsrc/js/application/core/behavior-drag-and-drop.js',
|
||||||
),
|
),
|
||||||
|
'javelin-behavior-aphront-drag-and-drop-textarea' =>
|
||||||
|
array(
|
||||||
|
'uri' => '/res/fa7527f9/rsrc/js/application/core/behavior-drag-and-drop-textarea.js',
|
||||||
|
'type' => 'js',
|
||||||
|
'requires' =>
|
||||||
|
array(
|
||||||
|
0 => 'javelin-behavior',
|
||||||
|
1 => 'javelin-dom',
|
||||||
|
2 => 'phabricator-drag-and-drop-file-upload',
|
||||||
|
),
|
||||||
|
'disk' => '/rsrc/js/application/core/behavior-drag-and-drop-textarea.js',
|
||||||
|
),
|
||||||
'javelin-behavior-aphront-form-disable-on-submit' =>
|
'javelin-behavior-aphront-form-disable-on-submit' =>
|
||||||
array(
|
array(
|
||||||
'uri' => '/res/6c659ede/rsrc/js/application/core/behavior-form.js',
|
'uri' => '/res/6c659ede/rsrc/js/application/core/behavior-form.js',
|
||||||
|
@ -637,6 +649,37 @@ celerity_register_resource_map(array(
|
||||||
),
|
),
|
||||||
'disk' => '/rsrc/js/application/core/behavior-keyboard-shortcuts.js',
|
'disk' => '/rsrc/js/application/core/behavior-keyboard-shortcuts.js',
|
||||||
),
|
),
|
||||||
|
'javelin-behavior-phriction-document-preview' =>
|
||||||
|
array(
|
||||||
|
'uri' => '/res/f1665ecd/rsrc/js/application/phriction/phriction-document-preview.js',
|
||||||
|
'type' => 'js',
|
||||||
|
'requires' =>
|
||||||
|
array(
|
||||||
|
0 => 'javelin-behavior',
|
||||||
|
1 => 'javelin-dom',
|
||||||
|
2 => 'javelin-util',
|
||||||
|
3 => 'phabricator-shaped-request',
|
||||||
|
),
|
||||||
|
'disk' => '/rsrc/js/application/phriction/phriction-document-preview.js',
|
||||||
|
),
|
||||||
|
'javelin-behavior-projects-resource-editor' =>
|
||||||
|
array(
|
||||||
|
'uri' => '/res/a54d5616/rsrc/js/application/projects/projects-resource-editor.js',
|
||||||
|
'type' => 'js',
|
||||||
|
'requires' =>
|
||||||
|
array(
|
||||||
|
0 => 'javelin-behavior',
|
||||||
|
1 => 'phabricator-prefab',
|
||||||
|
2 => 'multirow-row-manager',
|
||||||
|
3 => 'javelin-tokenizer',
|
||||||
|
4 => 'javelin-typeahead-preloaded-source',
|
||||||
|
5 => 'javelin-typeahead',
|
||||||
|
6 => 'javelin-dom',
|
||||||
|
7 => 'javelin-json',
|
||||||
|
8 => 'javelin-util',
|
||||||
|
),
|
||||||
|
'disk' => '/rsrc/js/application/projects/projects-resource-editor.js',
|
||||||
|
),
|
||||||
0 =>
|
0 =>
|
||||||
array(
|
array(
|
||||||
'uri' => '/res/1da00bfe/rsrc/js/javelin/lib/__tests__/URI.js',
|
'uri' => '/res/1da00bfe/rsrc/js/javelin/lib/__tests__/URI.js',
|
||||||
|
@ -675,37 +718,6 @@ celerity_register_resource_map(array(
|
||||||
),
|
),
|
||||||
'disk' => '/rsrc/js/application/core/behavior-watch-anchor.js',
|
'disk' => '/rsrc/js/application/core/behavior-watch-anchor.js',
|
||||||
),
|
),
|
||||||
'javelin-behavior-phriction-document-preview' =>
|
|
||||||
array(
|
|
||||||
'uri' => '/res/f1665ecd/rsrc/js/application/phriction/phriction-document-preview.js',
|
|
||||||
'type' => 'js',
|
|
||||||
'requires' =>
|
|
||||||
array(
|
|
||||||
0 => 'javelin-behavior',
|
|
||||||
1 => 'javelin-dom',
|
|
||||||
2 => 'javelin-util',
|
|
||||||
3 => 'phabricator-shaped-request',
|
|
||||||
),
|
|
||||||
'disk' => '/rsrc/js/application/phriction/phriction-document-preview.js',
|
|
||||||
),
|
|
||||||
'javelin-behavior-projects-resource-editor' =>
|
|
||||||
array(
|
|
||||||
'uri' => '/res/a54d5616/rsrc/js/application/projects/projects-resource-editor.js',
|
|
||||||
'type' => 'js',
|
|
||||||
'requires' =>
|
|
||||||
array(
|
|
||||||
0 => 'javelin-behavior',
|
|
||||||
1 => 'phabricator-prefab',
|
|
||||||
2 => 'multirow-row-manager',
|
|
||||||
3 => 'javelin-tokenizer',
|
|
||||||
4 => 'javelin-typeahead-preloaded-source',
|
|
||||||
5 => 'javelin-typeahead',
|
|
||||||
6 => 'javelin-dom',
|
|
||||||
7 => 'javelin-json',
|
|
||||||
8 => 'javelin-util',
|
|
||||||
),
|
|
||||||
'disk' => '/rsrc/js/application/projects/projects-resource-editor.js',
|
|
||||||
),
|
|
||||||
'javelin-behavior-refresh-csrf' =>
|
'javelin-behavior-refresh-csrf' =>
|
||||||
array(
|
array(
|
||||||
'uri' => '/res/39aa51f7/rsrc/js/application/core/behavior-refresh-csrf.js',
|
'uri' => '/res/39aa51f7/rsrc/js/application/core/behavior-refresh-csrf.js',
|
||||||
|
@ -1305,7 +1317,7 @@ celerity_register_resource_map(array(
|
||||||
'uri' => '/res/pkg/95b66c1a/differential.pkg.css',
|
'uri' => '/res/pkg/95b66c1a/differential.pkg.css',
|
||||||
'type' => 'css',
|
'type' => 'css',
|
||||||
),
|
),
|
||||||
'b3fd9e3f' =>
|
'a841d3be' =>
|
||||||
array (
|
array (
|
||||||
'name' => 'core.pkg.css',
|
'name' => 'core.pkg.css',
|
||||||
'symbols' =>
|
'symbols' =>
|
||||||
|
@ -1326,7 +1338,7 @@ celerity_register_resource_map(array(
|
||||||
13 => 'phabricator-remarkup-css',
|
13 => 'phabricator-remarkup-css',
|
||||||
14 => 'syntax-highlighting-css',
|
14 => 'syntax-highlighting-css',
|
||||||
),
|
),
|
||||||
'uri' => '/res/pkg/b3fd9e3f/core.pkg.css',
|
'uri' => '/res/pkg/a841d3be/core.pkg.css',
|
||||||
'type' => 'css',
|
'type' => 'css',
|
||||||
),
|
),
|
||||||
'd0713563' =>
|
'd0713563' =>
|
||||||
|
@ -1362,15 +1374,15 @@ celerity_register_resource_map(array(
|
||||||
),
|
),
|
||||||
'reverse' =>
|
'reverse' =>
|
||||||
array (
|
array (
|
||||||
'aphront-crumbs-view-css' => 'b3fd9e3f',
|
'aphront-crumbs-view-css' => 'a841d3be',
|
||||||
'aphront-dialog-view-css' => 'b3fd9e3f',
|
'aphront-dialog-view-css' => 'a841d3be',
|
||||||
'aphront-form-view-css' => 'b3fd9e3f',
|
'aphront-form-view-css' => 'a841d3be',
|
||||||
'aphront-list-filter-view-css' => 'b3fd9e3f',
|
'aphront-list-filter-view-css' => 'a841d3be',
|
||||||
'aphront-panel-view-css' => 'b3fd9e3f',
|
'aphront-panel-view-css' => 'a841d3be',
|
||||||
'aphront-side-nav-view-css' => 'b3fd9e3f',
|
'aphront-side-nav-view-css' => 'a841d3be',
|
||||||
'aphront-table-view-css' => 'b3fd9e3f',
|
'aphront-table-view-css' => 'a841d3be',
|
||||||
'aphront-tokenizer-control-css' => 'b3fd9e3f',
|
'aphront-tokenizer-control-css' => 'a841d3be',
|
||||||
'aphront-typeahead-control-css' => 'b3fd9e3f',
|
'aphront-typeahead-control-css' => 'a841d3be',
|
||||||
'differential-changeset-view-css' => '95b66c1a',
|
'differential-changeset-view-css' => '95b66c1a',
|
||||||
'differential-core-view-css' => '95b66c1a',
|
'differential-core-view-css' => '95b66c1a',
|
||||||
'differential-revision-add-comment-css' => '95b66c1a',
|
'differential-revision-add-comment-css' => '95b66c1a',
|
||||||
|
@ -1407,13 +1419,13 @@ celerity_register_resource_map(array(
|
||||||
'javelin-util' => '307df223',
|
'javelin-util' => '307df223',
|
||||||
'javelin-vector' => '307df223',
|
'javelin-vector' => '307df223',
|
||||||
'javelin-workflow' => 'd0713563',
|
'javelin-workflow' => 'd0713563',
|
||||||
'phabricator-core-buttons-css' => 'b3fd9e3f',
|
'phabricator-core-buttons-css' => 'a841d3be',
|
||||||
'phabricator-core-css' => 'b3fd9e3f',
|
'phabricator-core-css' => 'a841d3be',
|
||||||
'phabricator-directory-css' => 'b3fd9e3f',
|
'phabricator-directory-css' => 'a841d3be',
|
||||||
'phabricator-keyboard-shortcut' => 'd0713563',
|
'phabricator-keyboard-shortcut' => 'd0713563',
|
||||||
'phabricator-keyboard-shortcut-manager' => 'd0713563',
|
'phabricator-keyboard-shortcut-manager' => 'd0713563',
|
||||||
'phabricator-remarkup-css' => 'b3fd9e3f',
|
'phabricator-remarkup-css' => 'a841d3be',
|
||||||
'phabricator-standard-page-view' => 'b3fd9e3f',
|
'phabricator-standard-page-view' => 'a841d3be',
|
||||||
'syntax-highlighting-css' => 'b3fd9e3f',
|
'syntax-highlighting-css' => 'a841d3be',
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
|
@ -477,6 +477,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorRefreshCSRFController' => 'applications/auth/controller/refresh',
|
'PhabricatorRefreshCSRFController' => 'applications/auth/controller/refresh',
|
||||||
'PhabricatorRemarkupRuleDifferential' => 'infrastructure/markup/remarkup/markuprule/differential',
|
'PhabricatorRemarkupRuleDifferential' => 'infrastructure/markup/remarkup/markuprule/differential',
|
||||||
'PhabricatorRemarkupRuleDiffusion' => 'infrastructure/markup/remarkup/markuprule/diffusion',
|
'PhabricatorRemarkupRuleDiffusion' => 'infrastructure/markup/remarkup/markuprule/diffusion',
|
||||||
|
'PhabricatorRemarkupRuleEmbedFile' => 'infrastructure/markup/remarkup/markuprule/embedobject',
|
||||||
'PhabricatorRemarkupRuleImageMacro' => 'infrastructure/markup/remarkup/markuprule/imagemacro',
|
'PhabricatorRemarkupRuleImageMacro' => 'infrastructure/markup/remarkup/markuprule/imagemacro',
|
||||||
'PhabricatorRemarkupRuleManiphest' => 'infrastructure/markup/remarkup/markuprule/maniphest',
|
'PhabricatorRemarkupRuleManiphest' => 'infrastructure/markup/remarkup/markuprule/maniphest',
|
||||||
'PhabricatorRemarkupRuleMention' => 'infrastructure/markup/remarkup/markuprule/mention',
|
'PhabricatorRemarkupRuleMention' => 'infrastructure/markup/remarkup/markuprule/mention',
|
||||||
|
@ -1013,6 +1014,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorRefreshCSRFController' => 'PhabricatorAuthController',
|
'PhabricatorRefreshCSRFController' => 'PhabricatorAuthController',
|
||||||
'PhabricatorRemarkupRuleDifferential' => 'PhabricatorRemarkupRuleObjectName',
|
'PhabricatorRemarkupRuleDifferential' => 'PhabricatorRemarkupRuleObjectName',
|
||||||
'PhabricatorRemarkupRuleDiffusion' => 'PhutilRemarkupRule',
|
'PhabricatorRemarkupRuleDiffusion' => 'PhutilRemarkupRule',
|
||||||
|
'PhabricatorRemarkupRuleEmbedFile' => 'PhutilRemarkupRule',
|
||||||
'PhabricatorRemarkupRuleImageMacro' => 'PhutilRemarkupRule',
|
'PhabricatorRemarkupRuleImageMacro' => 'PhutilRemarkupRule',
|
||||||
'PhabricatorRemarkupRuleManiphest' => 'PhabricatorRemarkupRuleObjectName',
|
'PhabricatorRemarkupRuleManiphest' => 'PhabricatorRemarkupRuleObjectName',
|
||||||
'PhabricatorRemarkupRuleMention' => 'PhutilRemarkupRule',
|
'PhabricatorRemarkupRuleMention' => 'PhutilRemarkupRule',
|
||||||
|
|
|
@ -106,6 +106,7 @@ final class DifferentialAddCommentView extends AphrontView {
|
||||||
->setName('comment')
|
->setName('comment')
|
||||||
->setID('comment-content')
|
->setID('comment-content')
|
||||||
->setLabel('Comment')
|
->setLabel('Comment')
|
||||||
|
->setEnableDragAndDropFileUploads(true)
|
||||||
->setValue($this->draft))
|
->setValue($this->draft))
|
||||||
->appendChild(
|
->appendChild(
|
||||||
id(new AphrontFormSubmitControl())
|
id(new AphrontFormSubmitControl())
|
||||||
|
|
|
@ -100,6 +100,7 @@ class PhabricatorMarkupEngine {
|
||||||
|
|
||||||
$rules[] = new PhutilRemarkupRuleHyperlink();
|
$rules[] = new PhutilRemarkupRuleHyperlink();
|
||||||
|
|
||||||
|
$rules[] = new PhabricatorRemarkupRuleEmbedFile();
|
||||||
$rules[] = new PhabricatorRemarkupRuleDifferential();
|
$rules[] = new PhabricatorRemarkupRuleDifferential();
|
||||||
$rules[] = new PhabricatorRemarkupRuleDiffusion();
|
$rules[] = new PhabricatorRemarkupRuleDiffusion();
|
||||||
$rules[] = new PhabricatorRemarkupRuleManiphest();
|
$rules[] = new PhabricatorRemarkupRuleManiphest();
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
phutil_require_module('phabricator', 'infrastructure/env');
|
phutil_require_module('phabricator', 'infrastructure/env');
|
||||||
phutil_require_module('phabricator', 'infrastructure/markup/remarkup/markuprule/differential');
|
phutil_require_module('phabricator', 'infrastructure/markup/remarkup/markuprule/differential');
|
||||||
phutil_require_module('phabricator', 'infrastructure/markup/remarkup/markuprule/diffusion');
|
phutil_require_module('phabricator', 'infrastructure/markup/remarkup/markuprule/diffusion');
|
||||||
|
phutil_require_module('phabricator', 'infrastructure/markup/remarkup/markuprule/embedobject');
|
||||||
phutil_require_module('phabricator', 'infrastructure/markup/remarkup/markuprule/imagemacro');
|
phutil_require_module('phabricator', 'infrastructure/markup/remarkup/markuprule/imagemacro');
|
||||||
phutil_require_module('phabricator', 'infrastructure/markup/remarkup/markuprule/maniphest');
|
phutil_require_module('phabricator', 'infrastructure/markup/remarkup/markuprule/maniphest');
|
||||||
phutil_require_module('phabricator', 'infrastructure/markup/remarkup/markuprule/mention');
|
phutil_require_module('phabricator', 'infrastructure/markup/remarkup/markuprule/mention');
|
||||||
|
|
|
@ -193,6 +193,7 @@ class PhrictionEditController
|
||||||
->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL)
|
->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL)
|
||||||
->setName('content')
|
->setName('content')
|
||||||
->setID('document-textarea')
|
->setID('document-textarea')
|
||||||
|
->setEnableDragAndDropFileUploads(true)
|
||||||
->setCaption($remarkup_reference))
|
->setCaption($remarkup_reference))
|
||||||
->appendChild(
|
->appendChild(
|
||||||
id(new AphrontFormSubmitControl())
|
id(new AphrontFormSubmitControl())
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group markup
|
||||||
|
*/
|
||||||
|
class PhabricatorRemarkupRuleEmbedFile
|
||||||
|
extends PhutilRemarkupRule {
|
||||||
|
|
||||||
|
public function apply($text) {
|
||||||
|
return preg_replace_callback(
|
||||||
|
"@{F(\d+)}@",
|
||||||
|
array($this, 'markupEmbedFile'),
|
||||||
|
$text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function markupEmbedFile($matches) {
|
||||||
|
|
||||||
|
$file = null;
|
||||||
|
if ($matches[1]) {
|
||||||
|
// TODO: This is pretty inefficient if there are a bunch of files.
|
||||||
|
$file = id(new PhabricatorFile())->load($matches[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($file) {
|
||||||
|
return $this->getEngine()->storeText(
|
||||||
|
phutil_render_tag(
|
||||||
|
'a',
|
||||||
|
array(
|
||||||
|
'href' => $file->getViewURI(),
|
||||||
|
'target' => '_blank',
|
||||||
|
),
|
||||||
|
phutil_render_tag(
|
||||||
|
'img',
|
||||||
|
array(
|
||||||
|
'src' => $file->getThumb160x120URI(),
|
||||||
|
))));
|
||||||
|
} else {
|
||||||
|
return $matches[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'applications/files/storage/file');
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'markup');
|
||||||
|
phutil_require_module('phutil', 'markup/engine/remarkup/markuprule/base');
|
||||||
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorRemarkupRuleEmbedFile.php');
|
|
@ -72,13 +72,12 @@ class PhabricatorRemarkupRuleMention
|
||||||
$username = strtolower($matches[1]);
|
$username = strtolower($matches[1]);
|
||||||
$exists = isset($this->actualUsers[$username]);
|
$exists = isset($this->actualUsers[$username]);
|
||||||
|
|
||||||
$real = $this->actualUsers[$username]['realName'];
|
|
||||||
|
|
||||||
$class = $exists
|
$class = $exists
|
||||||
? 'phabricator-remarkup-mention-exists'
|
? 'phabricator-remarkup-mention-exists'
|
||||||
: 'phabricator-remarkup-mention-unknown';
|
: 'phabricator-remarkup-mention-unknown';
|
||||||
|
|
||||||
if ($exists) {
|
if ($exists) {
|
||||||
|
$real = $this->actualUsers[$username]['realName'];
|
||||||
$tag = phutil_render_tag(
|
$tag = phutil_render_tag(
|
||||||
'a',
|
'a',
|
||||||
array(
|
array(
|
||||||
|
|
|
@ -23,6 +23,7 @@ class AphrontFormTextAreaControl extends AphrontFormControl {
|
||||||
const HEIGHT_VERY_TALL = 'very-tall';
|
const HEIGHT_VERY_TALL = 'very-tall';
|
||||||
|
|
||||||
private $height;
|
private $height;
|
||||||
|
private $enableDragAndDropFileUploads;
|
||||||
|
|
||||||
public function setHeight($height) {
|
public function setHeight($height) {
|
||||||
$this->height = $height;
|
$this->height = $height;
|
||||||
|
@ -33,6 +34,11 @@ class AphrontFormTextAreaControl extends AphrontFormControl {
|
||||||
return 'aphront-form-control-textarea';
|
return 'aphront-form-control-textarea';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setEnableDragAndDropFileUploads($enable) {
|
||||||
|
$this->enableDragAndDropFileUploads = $enable;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
protected function renderInput() {
|
protected function renderInput() {
|
||||||
|
|
||||||
$height_class = null;
|
$height_class = null;
|
||||||
|
@ -44,6 +50,20 @@ class AphrontFormTextAreaControl extends AphrontFormControl {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$id = $this->getID();
|
||||||
|
if ($this->enableDragAndDropFileUploads) {
|
||||||
|
if (!$id) {
|
||||||
|
$id = celerity_generate_unique_node_id();
|
||||||
|
}
|
||||||
|
Javelin::initBehavior(
|
||||||
|
'aphront-drag-and-drop-textarea',
|
||||||
|
array(
|
||||||
|
'target' => $id,
|
||||||
|
'activatedClass' => 'aphront-textarea-drag-and-drop',
|
||||||
|
'uri' => '/file/dropupload/',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
return phutil_render_tag(
|
return phutil_render_tag(
|
||||||
'textarea',
|
'textarea',
|
||||||
array(
|
array(
|
||||||
|
@ -51,7 +71,7 @@ class AphrontFormTextAreaControl extends AphrontFormControl {
|
||||||
'disabled' => $this->getDisabled() ? 'disabled' : null,
|
'disabled' => $this->getDisabled() ? 'disabled' : null,
|
||||||
'class' => $height_class,
|
'class' => $height_class,
|
||||||
'style' => $this->getControlStyle(),
|
'style' => $this->getControlStyle(),
|
||||||
'id' => $this->getID(),
|
'id' => $id,
|
||||||
),
|
),
|
||||||
phutil_escape_html($this->getValue()));
|
phutil_escape_html($this->getValue()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'infrastructure/celerity/api');
|
||||||
|
phutil_require_module('phabricator', 'infrastructure/javelin/api');
|
||||||
phutil_require_module('phabricator', 'view/form/control/base');
|
phutil_require_module('phabricator', 'view/form/control/base');
|
||||||
|
|
||||||
phutil_require_module('phutil', 'markup');
|
phutil_require_module('phutil', 'markup');
|
||||||
|
|
|
@ -133,3 +133,8 @@ table.aphront-form-control-checkbox-layout th {
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
padding: 6px 8px;
|
padding: 6px 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.aphront-textarea-drag-and-drop {
|
||||||
|
background: #99ff99;
|
||||||
|
border-color: #669966;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/**
|
||||||
|
* @provides javelin-behavior-aphront-drag-and-drop-textarea
|
||||||
|
* @requires javelin-behavior
|
||||||
|
* javelin-dom
|
||||||
|
* phabricator-drag-and-drop-file-upload
|
||||||
|
*/
|
||||||
|
|
||||||
|
JX.behavior('aphront-drag-and-drop-textarea', function(config) {
|
||||||
|
|
||||||
|
if (!JX.PhabricatorDragAndDropFileUpload.isSupported()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var target = JX.$(config.target);
|
||||||
|
var drop = new JX.PhabricatorDragAndDropFileUpload(target)
|
||||||
|
.setActivatedClass(config.activatedClass)
|
||||||
|
.setURI(config.uri);
|
||||||
|
|
||||||
|
drop.listen('didUpload', function(f) {
|
||||||
|
// TODO: Implement some fancy cursor position stuff in Javelin so we
|
||||||
|
// can drop it in wherever the cursor is.
|
||||||
|
target.value = target.value + "\n{F" + f.id + "}";
|
||||||
|
});
|
||||||
|
|
||||||
|
drop.start();
|
||||||
|
});
|
||||||
|
|
Loading…
Add table
Reference in a new issue