Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature to paste images directly into the textarea without needing image dialog #338

Closed
GaurangTandon opened this issue Jun 27, 2018 · 19 comments

Comments

@GaurangTandon
Copy link

Similar to what GitHub does. If you copy an image into your clipboard and paste it into the GitHub textbox, it:

  1. automatically detects that the data being pasted is an image
  2. contacts the respective image server and uploads the image there
  3. when the upload is complete, returns the generated URL and embeds the image as ![alt text](URL)

I will try and see if this is possible with the SE Imgur API, and if it is, will submit a pull request with this attempted new feature. Hopefully it will be short enough, and be a useful addition to SOX :)

@GaurangTandon
Copy link
Author

GaurangTandon commented Jun 27, 2018

@shu8 shu8 added this to the 2.3.0 milestone Jun 27, 2018
@shu8 shu8 changed the title Image paste into SE textarea should directly upload the image to imgur and paste final link Feature to paste images directly into the textarea without needing image dialog Jun 27, 2018
@shu8
Copy link
Member

shu8 commented Jun 27, 2018

@GaurangTandon sure I'll have a look! I've done something very similar in another project so hopefully it won't be too hard to make it work for SOX!

@shu8 shu8 self-assigned this Jun 27, 2018
@GaurangTandon
Copy link
Author

GaurangTandon commented Jun 27, 2018

Great! I did try this myself first though, and interestingly got the 418 error! :O The error reads: "Sorry, your request could not be completed because it looked suspicious".

The code is pretty short, and I am unable to figure out what's wrong (my code matches well with what I found in those links above)

(function() {
    'use strict';

    window.addEventListener("paste", function(event){
        var node = event.target,
            isTextarea = node.tagName === "TEXTAREA",
            clipboardData = event.clipboardData,
            formData = new FormData(),
            req = new XMLHttpRequest(),
            reader = new FileReader(),
            items = clipboardData && clipboardData.items,
            blob = null;

        if(!items) return true;

        for(var i = 0, len = items.length; i < len; i++)
            if(/^image/.test(items[i].type)){
                blob = items[i].getAsFile();
                break;
            }

        if(isTextarea && blob){
            reader.onload = function(){
                formData.append("file", this.result);

                req.open("POST", "https://stackoverflow.com/upload/image?https=true");
                req.setRequestHeader("accept", "*/*");
                req.setRequestHeader("content-type", "multipart/form-data");
                req.send(formData);

                debugger;

                req.onload = function(e){
                    debugger;
                };
            };

            reader.readAsDataURL(blob);
        }
    });
})();

I'll again have a look later.

Later observations:

  1. My req content-type is missing boundary=----WebKitFormBoundarycWMMfdb8ZwkGyDPY.
  2. My Request Payload (formData) is missing filename="image.png" and Content-Type: image/png at the beginning.
  3. The ending for the Request Payload of the correctly uploaded image is:
    image while that of the 418 error image is:
    image Apparently, there's some clear difference in encoding for the same image (the first image has square boxes, latter doesn't).

Ahh, I am missing the CRSF token :( Any idea where I can get one from, @shu8 ? Or should I post a question on StackApps?

shu8 added a commit that referenced this issue Jun 27, 2018
@shu8
Copy link
Member

shu8 commented Jun 27, 2018

@GaurangTandon interesting, I couldn't get it to work for the Stack Imgur API, but I could get it to work with the normal imgur api by registering an application. I just pushed what I did -- if we can get it to work with stack's imgur it would be great!

to get the fkey I think it is in the #fkey element's value on every page.


Also, something I didn't get whilst I was doing it is why can there be more than one item?

@GaurangTandon
Copy link
Author

GaurangTandon commented Jun 27, 2018

Also, something I didn't get whilst I was doing it is why can there be more than one item?

Yeah, I noticed a few times the items array was set to ["image/png", "Files"]. Not sure why though :/

I couldn't get it to work for the Stack Imgur API

Hmm, I am not sure if this is a good idea. Stack gives exclusive support to the i.stack domain, taking regular backups of the images, and ensuring their eternal permanence. While I agree that normal imgur images shouldn't vanish either, the probability of the latter is higher. Moreover, I'd personally want to replicate the default functionality as far as possible :)

to get the fkey I think it is in the #fkey element's value on every page.

Nice find! I inserted a simple formData.append("CSRF", document.getElementById("fkey").value);, but that didn't still work though :/


PS: You can set it to $(document).on('paste', 'textarea', function(e) { so that it works on all answer boxes, comment boxes, as well as chat boxes! ;)

@shu8
Copy link
Member

shu8 commented Jun 27, 2018

@GaurangTandon I remember seeing a stackapps question on uploading images to the SE imgur account. I'll try finding it!

Sorry - I don't understand, are you saying it's a bad idea to use the SE account, or bad idea to use the normal imgur API?

@shu8
Copy link
Member

shu8 commented Jun 27, 2018

@GaurangTandon
Copy link
Author

GaurangTandon commented Jun 28, 2018

are you saying it's a bad idea to use the SE account, or bad idea to use the normal imgur API?

I was saying that it's a bad idea to use the normal imgur API. That question link is great! Wanna give it a shot? (because I have given up entirely now, can't get it to work at all :'()

@shu8
Copy link
Member

shu8 commented Jun 28, 2018 via email

shu8 added a commit that referenced this issue Jun 28, 2018
@shu8
Copy link
Member

shu8 commented Jun 28, 2018

@GaurangTandon I think I got it to work now in dev 2.2.5 -- can you confirm?

the URL extraction is reallllllllly messy, so do you mind having a look to see if you can clean it up? 😆

@GaurangTandon
Copy link
Author

GaurangTandon commented Jun 29, 2018

Okay, first off, I spent five minutes debugging why the paste event doesn't fire when I realized the setting "Paste images directly into the post editor without the image dialog" is unchecked by default!! :O Please check it like all others.

Then, a couple more I even converted the first few lines to:

document.addEventListener('paste', function(e) {
    var node = e.target,
         isTextarea = node && node.tagName === "TEXTAREA";

to make sure it works on comment boxes. But it still doesn't work. That's because clipboard.items isn't what you think it is always. Here's an example. If you right click on a SE profile picture, press "Copy image", and paste it into the textbox, you'll get this:

image

And since we need the .getAsFile() method (that is only present in .items values), we would need the loop (that was there in my original code) in here.

Also, e.originalEvent errors in Chrome 67.


Still, after all that, I get an xhr error :(

image

I've made a commit with fixes for all of the stuff above, but I don't know how to fix the xhr :/

the URL extraction is reallllllllly messy, so do you mind having a look to see if you can clean it up?

Once you fix the xhr request, I can surely look into ways to optimize it :)

GaurangTandon added a commit to GaurangTandon/sox that referenced this issue Jun 29, 2018
shu8 pushed a commit that referenced this issue Jun 29, 2018
shu8 added a commit that referenced this issue Jun 29, 2018
@shu8
Copy link
Member

shu8 commented Jun 29, 2018

@GaurangTandon cool thanks! I still don't understand why the whole multiple items happens, but your fix seems perfect!

The POST error was to do with me being an idiot and only testing on Meta, so I forgot to change the URL to the /upload/image path of the current site!

Hopefully it should work now in dev v2.2.6!

GaurangTandon added a commit to GaurangTandon/sox that referenced this issue Jun 29, 2018
1. used addEventListener instead of onload
2. descriptive names (`reader`)
3. optimized extraction of the image URL from the `data`
4. made all declarations `var` and moved them into one place for consistency
5. shortened the POST url to simply `'/upload/image?https=true',` ;P
@GaurangTandon
Copy link
Author

GaurangTandon commented Jun 29, 2018

Thanks for the collaboration, I'm glad we finally got it to work :D

One thing I still wonder though is how are you going to tell the existing users that there's a new feature? The new users might notice this feature while configuring their settings, but I doubt the old users would notice it :/

shu8 pushed a commit that referenced this issue Jun 29, 2018
1. used addEventListener instead of onload
2. descriptive names (`reader`)
3. optimized extraction of the image URL from the `data`
4. made all declarations `var` and moved them into one place for consistency
5. shortened the POST url to simply `'/upload/image?https=true',` ;P
@shu8
Copy link
Member

shu8 commented Jun 29, 2018

@GaurangTandon thanks! nice touch with the pre-selection too! (and using just '/upload/image?https=true' is pure genius 😆).

You're right. In the past, we've never really done anything but I've been thinking recently to add a new 'added_in_version' property to the sox.features.info.json file, and with new releases, the script would show a small popup to users showing new features for the version -- thoughts?

@GaurangTandon
Copy link
Author

GaurangTandon commented Jun 29, 2018

nice touch with the pre-selection too! (and using just '/upload/image?https=true' is pure genius 😆).

I just found that literally a day ago while google searching :P

I've been thinking recently to add a new 'added_in_version' property to the sox.features.info.json

that would be too much of a burden. Instead, you could simply keep updating the contents of the popup manually. There would be two types of users: a) old and b) new. Is there a way to detect which ones are old (and are only updating their userscript) and which ones are new (and are actually installing the userscript)? If that is possible then we could only show the popup to the old users and we're done :D

@shu8
Copy link
Member

shu8 commented Jun 29, 2018 via email

@GaurangTandon
Copy link
Author

GaurangTandon commented Jun 30, 2018 via email

@shu8
Copy link
Member

shu8 commented Jun 30, 2018

@GaurangTandon fair enough, but I'm sure new users wouldn't mind a 'new in this version' popup anyway seeing as it is technically a new version for them 😆

I'll try doing something with this soon.

@GaurangTandon
Copy link
Author

I just noticed that this has already been implemented in a much cooler manner by Tomas Zato on StackApps. Considering that it's 986 lines worth of code, I'm sure it can't be merged into SOX. So, it'd rather be separately on its own.

<Thought I'd just mention.>

shu8 added a commit that referenced this issue Sep 2, 2018
* new dev

* #305

* #307

* #310

* #310

* Better fix for #310

The old fix placed the SOX button to the right of the username, but the username only shows up in the top bar if you're logged in. This meant the SOX button would be absent if you were logged out. This new code should fix that.

* #310

* #309, #313

* #311, #312

* #256

* #319, #317, #316

* #256

* #318

* #294 deprecate enhanced editor

* #308, other small fixes

* #320

* minor fixes (#324)

change scroll top top feature JSON info

* fixes #329 (#330)

also reduces jQuery dependency

* v2.1.4 DEV before push to master

also adds #326

* v2.2.0

* inital DEV push

* update readme to state GM not supported; #306

* reduce dependency on `hotkeys`+minor details (#333)

* #334 fixed

* #334

* #334

* #338

* #335, #338

* Micro optimizations (#336)

* update source link

* micro optimizations

- converted jQuery .not to CSS selector for faster perf (https://stackoverflow.com/questions/8845811/performance-differences-between-using-not-and-not-selectors)
- introduced a separate function to eliminate thrice-repeated (!) code, to keep it DRY

* fixes some issues (#339)

described in #338 (comment)

* fixes #338

* fixes #338 (#340)

1. used addEventListener instead of onload
2. descriptive names (`reader`)
3. optimized extraction of the image URL from the `data`
4. made all declarations `var` and moved them into one place for consistency
5. shortened the POST url to simply `'/upload/image?https=true',` ;P

* #322 implemented

* Sticky property

* Update sox.user.js

* Updating button colors

The main SE buttons use a lighter color than the SOX buttons

* Update sox.css

* Minor fixes

Patched a problem with vote buttons, and fixed the color of the notify on edit button

* Update sox.user.js

* minor changes/fixes

* #341 temporary fix

* Updated mod diamond icon

Updated to the icon, to match the one used by the new topbar

* Updated diamond icon

* Updated mod diamond

* improvements in colorAnswerer (#344)

* improvements in colorAnswerer
1. constant variables+cache answeredID
2. reduce jQuery dependency+shorter a[href] selector via user ID
3. change coloration

* optimization: use filters throughout (#345)

reduces bandwidth consumption

* fixes a few features; adds CSS

Fixes moveBounty, dragBounty, copyCommentsLink.
Adds class for colorAnswerer.
Updates jQuery

* fixes quickAuthorInfo fontawesome icon

* fix a few of #308

* Major improvements in code extensibility, reduced API usage, eliminate redundancy, etc. (#348)

* fixes various bugs mentioned in #348

* fixes standOutDupeCloseMigrated for search pages

* remove unwanted console logs

* #347, various minor tweaks

* fixes small bug in parseCrossSiteLinks

e.g. on this comment: https://meta.stackoverflow.com/questions/370902/i-need-a-lot-of-help-to-write-a-query-for-the-stack-exchange-data-explorer-sh?cb=1#comment608548_370902

* Fixed Meta SE's chat link

Added a / to the end of Meta SE's if statement to fix it. Also replaced "discuss" with "meta" for Area 51 (to match the new URL for Area 51 Discussions), shortened a bit of code, and added some comments

* Fixed Meta SE links

* Changed topbar z-index

Changed the fixed topbar's z-index to match the one on SO, in order to prevent elements like the usercard (z-index: 1000) from covering it

* Made it clearer what the checkbox does

* Many fixes to dialog buttons

Fixes many of the bugs from #308

* Many fixes to dialog buttons

Fixes many of the bugs from #308

* Many fixes to dialog buttons

Fixes many of the bugs from #308

* Many fixes to dialog buttons

Fixes many of the bugs from #308

* Fixed Area 51 Discussions bug

* #348 minor tweak

* fix (#350)

...for answerer ID 13 also matching commenter ids beginning with 13 (1345, 13555, etc.)

* #352, #353 remove yahoo YQL use

* #352

* PR/351 (#355)

* update getQuestionTags

* provide immediate response to user

* minor changes

* #325: remove rangyInputs dependency (#354)

* bump version number

* remove downvotedPostsEditAlert; remove rangyinputs `require`; implement mini changelog in dialog

* install stale and no-response bots

* #356 added, minor bug fix

* start #349, start to move to es6

* onlyShowCommentActionsOnHover bug fix

* #357

* deprecate fixedTopbar feature for #349

* add showTagWikiLinkOnTagPopup feature

* #359 fixed

* #358 fixed

* fixes #360

* fixes for #361

* #361 changes

* v2.3.0 final
shu8 added a commit that referenced this issue Feb 3, 2019
* new dev

* #305

* #307

* #310

* #310

* Better fix for #310

The old fix placed the SOX button to the right of the username, but the username only shows up in the top bar if you're logged in. This meant the SOX button would be absent if you were logged out. This new code should fix that.

* #310

* #309, #313

* #311, #312

* #256

* #319, #317, #316

* #256

* #318

* #294 deprecate enhanced editor

* #308, other small fixes

* #320

* minor fixes (#324)

change scroll top top feature JSON info

* fixes #329 (#330)

also reduces jQuery dependency

* v2.1.4 DEV before push to master

also adds #326

* v2.2.0

* inital DEV push

* update readme to state GM not supported; #306

* reduce dependency on `hotkeys`+minor details (#333)

* #334 fixed

* #334

* #334

* #338

* #335, #338

* Micro optimizations (#336)

* update source link

* micro optimizations

- converted jQuery .not to CSS selector for faster perf (https://stackoverflow.com/questions/8845811/performance-differences-between-using-not-and-not-selectors)
- introduced a separate function to eliminate thrice-repeated (!) code, to keep it DRY

* fixes some issues (#339)

described in #338 (comment)

* fixes #338

* fixes #338 (#340)

1. used addEventListener instead of onload
2. descriptive names (`reader`)
3. optimized extraction of the image URL from the `data`
4. made all declarations `var` and moved them into one place for consistency
5. shortened the POST url to simply `'/upload/image?https=true',` ;P

* #322 implemented

* Sticky property

* Update sox.user.js

* Updating button colors

The main SE buttons use a lighter color than the SOX buttons

* Update sox.css

* Minor fixes

Patched a problem with vote buttons, and fixed the color of the notify on edit button

* Update sox.user.js

* minor changes/fixes

* #341 temporary fix

* Updated mod diamond icon

Updated to the icon, to match the one used by the new topbar

* Updated diamond icon

* Updated mod diamond

* improvements in colorAnswerer (#344)

* improvements in colorAnswerer
1. constant variables+cache answeredID
2. reduce jQuery dependency+shorter a[href] selector via user ID
3. change coloration

* optimization: use filters throughout (#345)

reduces bandwidth consumption

* fixes a few features; adds CSS

Fixes moveBounty, dragBounty, copyCommentsLink.
Adds class for colorAnswerer.
Updates jQuery

* fixes quickAuthorInfo fontawesome icon

* fix a few of #308

* Major improvements in code extensibility, reduced API usage, eliminate redundancy, etc. (#348)

* fixes various bugs mentioned in #348

* fixes standOutDupeCloseMigrated for search pages

* remove unwanted console logs

* #347, various minor tweaks

* fixes small bug in parseCrossSiteLinks

e.g. on this comment: https://meta.stackoverflow.com/questions/370902/i-need-a-lot-of-help-to-write-a-query-for-the-stack-exchange-data-explorer-sh?cb=1#comment608548_370902

* Fixed Meta SE's chat link

Added a / to the end of Meta SE's if statement to fix it. Also replaced "discuss" with "meta" for Area 51 (to match the new URL for Area 51 Discussions), shortened a bit of code, and added some comments

* Fixed Meta SE links

* Changed topbar z-index

Changed the fixed topbar's z-index to match the one on SO, in order to prevent elements like the usercard (z-index: 1000) from covering it

* Made it clearer what the checkbox does

* Many fixes to dialog buttons

Fixes many of the bugs from #308

* Many fixes to dialog buttons

Fixes many of the bugs from #308

* Many fixes to dialog buttons

Fixes many of the bugs from #308

* Many fixes to dialog buttons

Fixes many of the bugs from #308

* Fixed Area 51 Discussions bug

* #348 minor tweak

* fix (#350)

...for answerer ID 13 also matching commenter ids beginning with 13 (1345, 13555, etc.)

* #352, #353 remove yahoo YQL use

* #352

* PR/351 (#355)

* update getQuestionTags

* provide immediate response to user

* minor changes

* #325: remove rangyInputs dependency (#354)

* bump version number

* remove downvotedPostsEditAlert; remove rangyinputs `require`; implement mini changelog in dialog

* install stale and no-response bots

* #356 added, minor bug fix

* start #349, start to move to es6

* onlyShowCommentActionsOnHover bug fix

* #357

* deprecate fixedTopbar feature for #349

* add showTagWikiLinkOnTagPopup feature

* #359 fixed

* #358 fixed

* fixes #360

* fixes for #361

* #361 changes

* v2.3.0 final

* 2.3.0 DEV

* fix for #363

* implemented 'feature packs' in settings dialog

* debugging for #363, fixes #364

* #363 debugging

* fix for #363

* #361 implemented (access token no longer mandatory); minor code cleanup

* #365

* fix #368

* Add #315

* fix #366

* start to use linting

* fix #372

* add #370

* clean up code

* implement #374

* fix #373

* add #370; deprecate pasteImagesDirectly

* #374 replace 'help' instead of prepend new link

* change indentation to 2 spaces

* lint

* implement #296

* implements #376 (linkify meta diamond dialog title)

* fix #375 (topAnswers post score not being found)

* improve customMagicLinks feature -- add button to help menu on all pages

* fix sticky vote buttons feature

* keep new meta posts under diamond even after clicking (#378)

* editComment improve design, add more defaults (#377)

* fix better css feature

* editComment: make dialog delete button smaller

* improve editComment for #377; allow editing; new setting storage format

* add delay to comment features for links to deleted comments #379

* bump to v2.4.0

* Remove accidental letter introduced into file

* Bump installation link version numbers

* Lint
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants