1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-22 21:40:55 +01:00

Support paste file uploads

Summary:
This is so freaking cool that I will try to implement it also on Facebook.
Idea is from
http://strd6.com/2011/09/html5-javascript-pasting-image-data-in-chrome/.
I don't know how to properly detect support but lying about it is not a big
deal.

Test Plan:
Go to revision comment textarea.
Paste some text data - works as usual.
Paste some image data in Chrome - file is uploaded and a link to it is inserted.

Reviewers: epriestley

Reviewed By: epriestley

CC: aran, epriestley

Differential Revision: https://secure.phabricator.com/D1681
This commit is contained in:
vrana 2012-02-23 15:47:41 -08:00
parent 48ab6aa465
commit 97144c0932
5 changed files with 160 additions and 61 deletions

2
externals/javelin vendored

@ -1 +1 @@
Subproject commit 45fa775fea5cc7fa1d834a04b9d25a08bcfa4812
Subproject commit 14f4218c5b7d50bb0f4144d937e482cdb98f6cdb

View file

@ -361,13 +361,14 @@ celerity_register_resource_map(array(
),
'javelin-behavior-aphront-drag-and-drop-textarea' =>
array(
'uri' => '/res/fa7527f9/rsrc/js/application/core/behavior-drag-and-drop-textarea.js',
'uri' => '/res/65980508/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',
3 => 'phabricator-paste-file-upload',
),
'disk' => '/rsrc/js/application/core/behavior-drag-and-drop-textarea.js',
),
@ -954,7 +955,7 @@ celerity_register_resource_map(array(
),
'javelin-magical-init' =>
array(
'uri' => '/res/d6832060/rsrc/js/javelin/core/init.js',
'uri' => '/res/caa86a45/rsrc/js/javelin/core/init.js',
'type' => 'js',
'requires' =>
array(
@ -1426,24 +1427,6 @@ celerity_register_resource_map(array(
),
'disk' => '/rsrc/js/application/core/DropdownMenu.js',
),
'phabricator-feed-css' =>
array(
'uri' => '/res/e4bf27b5/rsrc/css/application/feed/feed.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/feed/feed.css',
),
'phabricator-jump-nav' =>
array(
'uri' => '/res/69238d2f/rsrc/css/application/directory/phabricator-jump-nav.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/directory/phabricator-jump-nav.css',
),
'phabricator-keyboard-shortcut' =>
array(
'uri' => '/res/beed38cd/rsrc/js/application/core/KeyboardShortcut.js',
@ -1503,6 +1486,49 @@ celerity_register_resource_map(array(
),
'disk' => '/rsrc/js/application/core/Prefab.js',
),
0 =>
array(
'uri' => '/res/b6096fdd/rsrc/js/javelin/lib/__tests__/URI.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-uri',
1 => 'javelin-php-serializer',
),
'disk' => '/rsrc/js/javelin/lib/__tests__/URI.js',
),
'phabricator-feed-css' =>
array(
'uri' => '/res/e4bf27b5/rsrc/css/application/feed/feed.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/feed/feed.css',
),
'phabricator-jump-nav' =>
array(
'uri' => '/res/69238d2f/rsrc/css/application/directory/phabricator-jump-nav.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/directory/phabricator-jump-nav.css',
),
'phabricator-paste-file-upload' =>
array(
'uri' => '/res/cdc939bd/rsrc/js/application/core/PasteFileUpload.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-request',
3 => 'javelin-dom',
4 => 'javelin-uri',
),
'disk' => '/rsrc/js/application/core/PasteFileUpload.js',
),
'phabricator-profile-css' =>
array(
'uri' => '/res/9869d10b/rsrc/css/application/profile/profile-view.css',
@ -1551,17 +1577,6 @@ celerity_register_resource_map(array(
),
'disk' => '/rsrc/js/application/core/ShapedRequest.js',
),
0 =>
array(
'uri' => '/res/b6096fdd/rsrc/js/javelin/lib/__tests__/URI.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-uri',
1 => 'javelin-php-serializer',
),
'disk' => '/rsrc/js/javelin/lib/__tests__/URI.js',
),
'phabricator-slowvote-css' =>
array(
'uri' => '/res/94d20443/rsrc/css/application/slowvote/slowvote.css',
@ -1896,7 +1911,7 @@ celerity_register_resource_map(array(
'uri' => '/res/pkg/6a6def05/core.pkg.css',
'type' => 'css',
),
'ef420ead' =>
'c8aaade8' =>
array(
'name' => 'differential.pkg.js',
'symbols' =>
@ -1917,7 +1932,7 @@ celerity_register_resource_map(array(
13 => 'javelin-behavior-phabricator-object-selector',
14 => 'differential-inline-comment-editor',
),
'uri' => '/res/pkg/ef420ead/differential.pkg.js',
'uri' => '/res/pkg/c8aaade8/differential.pkg.js',
'type' => 'js',
),
),
@ -1935,7 +1950,7 @@ celerity_register_resource_map(array(
'aphront-typeahead-control-css' => '6a6def05',
'differential-changeset-view-css' => '4c3b1b11',
'differential-core-view-css' => '4c3b1b11',
'differential-inline-comment-editor' => 'ef420ead',
'differential-inline-comment-editor' => 'c8aaade8',
'differential-local-commits-view-css' => '4c3b1b11',
'differential-revision-add-comment-css' => '4c3b1b11',
'differential-revision-comment-css' => '4c3b1b11',
@ -1946,20 +1961,20 @@ celerity_register_resource_map(array(
'diffusion-commit-view-css' => '03ef179e',
'javelin-behavior' => '4fbae2af',
'javelin-behavior-aphront-basic-tokenizer' => '080edee4',
'javelin-behavior-aphront-drag-and-drop' => 'ef420ead',
'javelin-behavior-aphront-drag-and-drop-textarea' => 'ef420ead',
'javelin-behavior-aphront-drag-and-drop' => 'c8aaade8',
'javelin-behavior-aphront-drag-and-drop-textarea' => 'c8aaade8',
'javelin-behavior-aphront-form-disable-on-submit' => '46547a92',
'javelin-behavior-differential-accept-with-errors' => 'ef420ead',
'javelin-behavior-differential-add-reviewers-and-ccs' => 'ef420ead',
'javelin-behavior-differential-comment-jump' => 'ef420ead',
'javelin-behavior-differential-diff-radios' => 'ef420ead',
'javelin-behavior-differential-edit-inline-comments' => 'ef420ead',
'javelin-behavior-differential-feedback-preview' => 'ef420ead',
'javelin-behavior-differential-keyboard-navigation' => 'ef420ead',
'javelin-behavior-differential-populate' => 'ef420ead',
'javelin-behavior-differential-show-more' => 'ef420ead',
'javelin-behavior-differential-accept-with-errors' => 'c8aaade8',
'javelin-behavior-differential-add-reviewers-and-ccs' => 'c8aaade8',
'javelin-behavior-differential-comment-jump' => 'c8aaade8',
'javelin-behavior-differential-diff-radios' => 'c8aaade8',
'javelin-behavior-differential-edit-inline-comments' => 'c8aaade8',
'javelin-behavior-differential-feedback-preview' => 'c8aaade8',
'javelin-behavior-differential-keyboard-navigation' => 'c8aaade8',
'javelin-behavior-differential-populate' => 'c8aaade8',
'javelin-behavior-differential-show-more' => 'c8aaade8',
'javelin-behavior-phabricator-keyboard-shortcuts' => '46547a92',
'javelin-behavior-phabricator-object-selector' => 'ef420ead',
'javelin-behavior-phabricator-object-selector' => 'c8aaade8',
'javelin-behavior-phabricator-watch-anchor' => '46547a92',
'javelin-behavior-refresh-csrf' => '46547a92',
'javelin-behavior-workflow' => '46547a92',
@ -1984,12 +1999,12 @@ celerity_register_resource_map(array(
'phabricator-core-buttons-css' => '6a6def05',
'phabricator-core-css' => '6a6def05',
'phabricator-directory-css' => '6a6def05',
'phabricator-drag-and-drop-file-upload' => 'ef420ead',
'phabricator-drag-and-drop-file-upload' => 'c8aaade8',
'phabricator-keyboard-shortcut' => '46547a92',
'phabricator-keyboard-shortcut-manager' => '46547a92',
'phabricator-object-selector-css' => '4c3b1b11',
'phabricator-remarkup-css' => '6a6def05',
'phabricator-shaped-request' => 'ef420ead',
'phabricator-shaped-request' => 'c8aaade8',
'phabricator-standard-page-view' => '6a6def05',
'syntax-highlighting-css' => '6a6def05',
),

View file

@ -285,6 +285,9 @@ You can embed an image by using braces to refer to it:
In most interfaces, you can drag-and-drop an image from your computer into the
text area to upload and reference it.
Some browsers (e.g. Chrome) support uploading an image data just by pasting them
from clipboard into the text area.
You can set file display options like this:
{F123, layout=left, float, size=full}

View file

@ -0,0 +1,68 @@
/**
* @requires javelin-install
* javelin-util
* javelin-request
* javelin-dom
* javelin-uri
* @provides phabricator-paste-file-upload
* @javelin
*/
JX.install('PhabricatorPasteFileUpload', {
construct : function(node) {
this._node = node;
},
events : ['willUpload', 'didUpload'],
statics : {
isSupported : function() {
// TODO: Needs to check if event.clipboardData is available.
// Works in Chrome, doesn't work in Firefox 10.
return !!window.FileList;
}
},
members : {
_node : null,
start : function() {
JX.DOM.listen(
this._node,
'paste',
null,
JX.bind(this, function(e) {
var clipboardData = e.getRawEvent().clipboardData;
if (!clipboardData) {
return;
}
for (var ii = 0; ii < clipboardData.types.length; ii++) {
if (/^image\//.test(clipboardData.types[ii])) {
var file = clipboardData.items[ii].getAsFile();
this.invoke('willUpload', file);
var up_uri = JX.$U(this.getURI())
.setQueryParam('name', 'clipboard.png')
.toString();
new JX.Request(up_uri, JX.bind(this, function(r) {
this.invoke('didUpload', r);
}))
.setFile(file)
.send();
e.kill();
break;
}
}
}));
}
},
properties: {
URI : null
}
});

View file

@ -3,25 +3,38 @@
* @requires javelin-behavior
* javelin-dom
* phabricator-drag-and-drop-file-upload
* phabricator-paste-file-upload
*/
JX.behavior('aphront-drag-and-drop-textarea', function(config) {
if (!JX.PhabricatorDragAndDropFileUpload.isSupported()) {
return;
if (JX.PhabricatorDragAndDropFileUpload.isSupported()) {
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();
}
var target = JX.$(config.target);
var drop = new JX.PhabricatorDragAndDropFileUpload(target)
.setActivatedClass(config.activatedClass)
.setURI(config.uri);
if (JX.PhabricatorPasteFileUpload.isSupported()) {
var target = JX.$(config.target);
var paste = new JX.PhabricatorPasteFileUpload(target).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 + "}";
});
paste.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 + '{F' + f.id + '}';
});
paste.start();
}
drop.start();
});