2013/11/17

Finally, SimpleUploads 4 is here

After a long time working on this upgrade, I've reached the point where I think that it's better to release it and write all the documentation that I had in mind afterwards, so expect more updates about all the features in the following days.

Since quite a long time ago I felt that the name "ImagePaste" wasn't correct for a plugin that allows to also drop files and since version 3.0 offered two buttons to upload files or images with just two clicks and get them inserted into CKEditor.

So with along a new feature set, the main change (meaning the change that will cause more problems for existing users because instead of just replacing the files now you have to edit again your config file) is the rename of the old "imagepaste" to "simpleuploads"

That name tries to explain better what it does, it's not only about "images" and not only about "paste", it's a set of features to offer the users a way to "upload" files in a "simple" way.

The best way to check how it works is to test the demo.

Skipping the explanation about the existing features, the new ones are focused on the dialogs of CKEditor and improving the upload progress:

When you upload a file in the editor, now you get a progress indicator and the option to cancel the upload. The existing progress for images has been improved to also include the cancel option.

The plugin now integrates into the CKEditor dialogs, if it finds a "quickUpload" button it will be replaced with its own one to offer the same simple upload (click button, select a file and you're done instead of having to press the "upload to server"), as well as progress information, cancelation option and the full control on the upload (modify the upload URL, check file size, extension, automatica validation with a whitelist or blacklist...)

And besides modifying the QuickUpload button, the dialog itself now becomes a drop target, you can drop a file from your computer on those dialogs (even if there's only a browse server button is enough) and it will be uploaded and the url of the dialog filled with the new URL.

Another improvement in this version is the inclusion of optional parameters in the upload data, for example if you want to use some anti-CSRF token, modifying the QuickUpload system in CKEditor required some tricks, but now it's a piece of cake. Ditto if you want to add for example a checkbox to scale the image to a maximum, just before the upload begins there's an event where you can control many features.

I'll try to provide examples about how to customize CKEditor with this plugin so you can easily upload files and do whatever you want with them, so keep an eye on the blog because I'll try to write new posts explaining different ways to use the plugin. I've created now a main page here to provide a central point for all the information about SimpleUploads.

PS: currently I really dislike the comment system in Blogger because I don't get any notification when someone comments a post, so I might move to another platform if this bug persists. Meanwhile, have a little patience if I don't reply, it's usually better to send me a mail or direct message by + me.

2013/10/06

Cross domain file uploads in CKEditor

In version 3.4 of the SimpleUploads plugin I've added support to upload files across domains based on the CORS spec.

If you don't use multiple domains (one server for the uploaded files and another for the editing page) then this change shouldn't affect you. Otherwise you can enable this feature by modifying your uploader to send just two headers in response to an OPTIONS request.
Some simple PHP code:
if (isset($_SERVER["HTTP_ORIGIN"])) {
 // You must verify that the origin domain is on your white-list
 header('Access-Control-Allow-Origin: https://admin.example.com');
 header('Access-Control-Allow-Credentials: true');
}
if ($_SERVER['REQUEST_METHOD']=='OPTIONS')
 exit(0);
  • First: check if the browser has sent an Origin header. That means that it's a cross domain request. You can check that domain with the list of domains that you want to allow. The usual behavior is to send back a fixed origin header like
    header('Access-Control-Allow-Origin: https://admin.example.com');
  • Second: Send an Access-Control-Allow-Credentials header specifying that the browser is allowed to make a request that will use the credentials of the user at this domain. This means that if the user is logged in, the browser will send the cookies required to allow you check his/her identity.
  • Last: as the OPTIONS request doesn't require more data in the response you can stop any further processing here. After this first request the browser will upload the file and you must send back again the two Access-Control headers as shown in the sample code.
You must be careful if you want to allow this feature, after all it opens the possibility of another attack vector.
If you're hosting the files in the same physical server, you might be able to get the same functionality by modifying just the URL that it's returned after you upload a file and keeping all your code in the admin.example.com domain.

Updating some plugins

Today I've been working on some issues on plugins for CKEditor.

As I've stated previously, I don't like Github, but I'm forced to use it and when people uses things that they don't like it's obvious that things are slower than when they are happy.

I'm always afraid that if I try to do things I'll have to waste a lot of time recreating again the branch, it will spit out errors saying that it can't merge and that I have to use the command line. I've been using Beyond Compare for so long that merging things on the command line seems like an impossible task to me and I don't want to learn the github commands because that's not my daily job and even if I waste time to learn them for one task, by the time that I have to use them again I will have forgotten everything about them.

So if you see that "I'm ignoring" your patch, the reason might be simply that I don't have the time and energy to fight against Github.

The first patch was a simple one-liner by bfavors on the configuration helper plugin.

First of all, thank you.

But please, next time try to provide more info to quickly understand how I should test to check the bug, the browser, some simple code that shows how to load the editor. There are so many options that without more info my first thought is "Ok, now I have to guess out how to reproduce that bug!" :-(

If you provide such simple patch and also a simple testcase it's really easy to test that and verify that it was broken and now it works. Otherwise I might think that I'll have to spend a lot of time like it usually happens with bugs in CKEditor.

Then I've been reviewing the suggested changes to the "background image" plugin.

Some months ago OFark provided a patch to add support for background-repeat and background-position, but after merging those changes I faced some issues and moved to do other things, creating a branch so that the code doesn't get lost.

More recently LazyHammer did provide a new patch and this time things looked better, so I've been checking that a little and although it is still not perfect (for example it leaves garbage styles after removing the background image on the table) it worked well enough for most of the people, so I've uploaded version 1.4

If you are interested in a plugin and there's something that you want to improve, please create a patch and I'll try to review it.
The better it works and the more info about what's the original problem, the faster the review :-)

2013/08/14

I still hate GitHub for Windows

I've been trying to use a little GitHub for some time but it's clear that I won't ever be able to think as other developers do.
I just want to do simple things like I used to do previously keeping a local repository of CKEditor and the patches that aren't being added to the main code. Using TortoiseSVN that was a breeze, no need to remember anything, just go to the explorer right click and under the Tortoise everything was available right there. No matter if I didn't touch SVN for months and I forgot everything about CKEditor and SVN, it's just a matter of reading the name of the options and then click Update after finding it. If the changes were too complex then its merge editor showed the problems and I could easily adjust the conflicting code.

Now CKEditor works with GitHub and so many other people also live and die by GitHub that I've been trying to use it, but it's so different that I can't spend the time to forget everything that I know and start over as some of the books on GitHub suggest (hey man, it's so complex to use that you need to study a book in order to understand it and learn that divine "git workflow")

Of course there are two parts here:
Maybe SVN but itself is also ugly and I just enjoyed the easy of use of TortoiseSVN, but the fact is that I've been trying to use the GUI that they provided for windows, so maybe the problem isn't Git by itself and it's just GitHub for Windows.

The first (ugly) surprise is that instead of using the common controls and theme of my windows, it's using that flat look of windows 8 in "modern" mode.
Hint: If I'm using certain version of windows and I'm using a theme (just the classic one, nothing fancy), it might be because I enjoy it and I don't want to use Windows8 even if you pay me.

Everything is flat, there's no real hint about which elements are simple text and which ones are active ones that can be used for something.
The colors are white background, grey text and some highlights; it's sad, no distinctive elements to clearly show the different zones and possibilities that the UI offers.
Or maybe the problem is that so few things are possible, I'm always thinking that I must be doing something wrong because I can't understand how to change things.

Last week I created a repository for a new little project. Sounds easy right?
not so.
It showed up with a lock icon (instead of the book like the other ones) and despite my efforts I haven't managed to make it show the readme.md in local.

And it's better to not talk about the time that it takes to load that fugly UI...

2013/08/10

A basic upload script for CKEditor

A long time ago I published a basic example showing the skeleton of how an upload script for CKEditor should look like. Since the release of the imagepaste plugin I've received some requests to fill and explain all the details, and some people buy that plugin even before testing the free version and then they find that they don't know how to upload files.

So now I'm publishing that script with the missing part, a simple call to

move_uploaded_file($_FILES["upload"]["tmp_name"], $basePath . $name);

I've adjusted it a little so that the path to the upload folder and matching URL can be configured more easily, but it's still a very basic script. It doesn't perform any check on the uploaded files, you must take care of integrating it with your CMS (after all, that's something impossible for me to know how you're doing that part) and verify that the upload folder has the right permissions.

You can use it with CKEditor to enable the Upload tab in the Image and Link dialogs, and that way the user will be able to upload files (but not browse the existing ones). If you add the free version of the image paste plugin, then the user will be able to paste images from their clipboard into CKEditor, and the content will not be that huge mess of base64 encoded data, but a simple URL to your server with all the performance benefits that it means.

At this point, you can opt to buy the full version of the image paste plugin if you want to provide even more options for the users:

  • Drag and drop from the computer for every modern browser
  • Pasting images from the clipboard in Chrome (besides the basic pasting available in the free version for Firefox)
  • Copy and paste a file from your computer in Firefox
  • Two buttons to quickly upload a file or image for every browser. There's no way to make uploads simpler than this, other plugins still require the user to open a dialog, click browse, upload, etc... that's a huge mess and a big waste of time. Here you click and the file picker launches automatically, select the file that you want and then it's uploaded and inserted in a single step.

You can test all these features in the demo page for CKEditor 4 (the plugin also works with CKEditor 3)

Back to this upload script:

I've published it at GitHub so if other people wants to provide some suggestions for better compatibility or they take the time to improve it I will try to keep it updated, but I don't really want to spend too much time on it because if by a miracle it would be a success (in fact, I wouldn't like to see too many people using this because it's really basic) then attackers would love to exploit all the weakness that it has. Please, read the documentation, all the comments and try your best to secure it as much as you can. If you download it from GitHub, you can remove those extra .git* files that it has added automatically as well as the readme and the docs when you have read them.

You only need the upload.php file and to improve a little the security by obscurity you can opt to rename it anyway that you want, just put that same name and path in the configuration of your CKEditor.

The best option would be for you to take this script as a full example and then add your customizations, your own security options, make it unique so that a simple bot can't find and use it.

This is the link to download the current version from GitHub.

2013/08/02

Making the ImagePaste plugin compatible with IE11

Now that it's summer time and I have some free time I decided to take a look at the beta of IE 11 to check how well does it work with some of my CKEditor plugins.

The first thing to remember is that CKEditor itself isn't compatible with IE11 and if we are to base our guesses on previous history I don't think that they will really work on it until sometime after IE11 has been released and people start complaining seriously, but I prefer to look ahead and try to work now instead of having to rush later.

So I've focused my tests on the image paste plugin, specially because in their release notes they talk about the new ability to use the .files property in the clipboardData object as well as the base64 encoding performed by default (like Firefox).

Well, using base64 on the image is a nice little trick, but I think that it's really a bad option in the real world. I guess that if any performance guru would have been consulted they would have answered that this feature shouldn't have been added (at least not by default).

Testing IE nowadays it's much simpler than it used to be. Microsoft provides virtual machines ready to use with almost any combination of supported OS and IE as well as the virtual machine environment (at least I didn't miss anything). So after downloading the Win 8.1 preview and "installing" it, I was ready to test.

Ok, almost ready to test: no network connection. It turns out that the default network configuration is set up to work as a private network with the host. After changing it to my default bridged preference I had Internet again :-)

So I launched my demo with CKEditor 3 and... nothing. Nothing is pasted there. Not only the image is ignored from the clipboard, also any text can't be pasted. As the argument will be that CKEditor is "old" and it's not supported I moved then to the CKEditor 4 demo to check it, and yes, now it "works". The image is pasted but as base64 data. That means that neither my direct paste listener on the element is working to detect the files and the default CKEditor paste event is also failing to provide me the base64 so I could try to use the same Firefox trick.

A little debugging shows that the CKEditor paste isn't fired at all and my listener on the editable element works, but the event doesn't seem to include the .files property. Debugging that info isn't as easy as it seems, despite the claim that after pressing F12 the debugger is ready isn't true for me, breakpoints doesn't work, the files show up as a huge list of "plugin.js" files...

At this point a very important suggestion for Microsoft: Show folder names in the pane with the loaded scripts, having around 30 or 50 files named "plugin.js" and no way to tell them apart is not fun.

In order to debug correctly I restart the machine (maybe it's usual for people to start debuggin on the first IE & OS launch, but I don't see any other reason to fire up that VM, Win8.1 still tries to force "metro" too much so it doesn't fit my tastes) and now things seem to work a little better. To find the place for my breakpoints I search the files for the some function name specific to that file and that way I can avoid the mess of "plugin.js" .

And now looking at their documentation I notice something interesting, instead of using a clipboardData object on the paste event data, they are using one one the window object (like old IEs), so now it's obvious why this detection wasn't working. I add a workaround to try to use it and now when I copy an image from Paint I can detect and upload it like it happens in Firefox and Chrome. Due to the way that they have written their documentation I think that this feature isn't complete, after all I haven't managed to get an event if I try to paste a file from the desktop (like Firefox does) and if I create a document in WordPad with an image only the text is copied and no image is inserted, although given the way that they have chosen to write the documentation I think that some other feature should be available in the final version besides pasting a simple image from the clipboard.

After noticing that issue and given that this is a problem that shouldn't exist (providing files in the clipboard data is a feature that currently only Firefox and Chrome support, so if Microsoft want existing code to work they should use exactly the same APIs and objects) I filed a bug in their tracker to check if they care about compatibility or not. To my surprise this morning I had a reply, stating that obviously they can't reproduce the bug and the best course of action is to close it. I've replied providing the test file as a live url instead of an attachment (they didn't allow .html attachments so finding a .txt page might have been too hard for them). Of course this probably means the end of my efforts to report any issue in IE11 to Microsoft, if they don't care about something so simple and basic according to their goal of treating IE11 as any other modern browser then I'm not gonna waste my time trying to explain more complex things.

Back to my testings on IE11 and image paste, I noticed that dropping a file doesn't upload it and instead tries to open it as if I hadn't added any drop listeners. In this case the problem is that CKEditor at the moment detects IE11 as a gecko, but in this case Microsoft is aligning their behavior to old Chrome and requires that the drag over event is prevented. This is the kind of bug that Microsoft should also fix, but I don't have hope on them so I just add a line to detect "IEmodern" and it works (yes, this is the kind of bug/browser behavior that can't be changed based on feature detection but instead it relies on hardcoding which are the buggy browsers)

So now I tested again the CKEditor 3 demo and everything related to my plugin works. Images can be pasted, dragged, uploaded with the toolbar button... CKEditor itself has its own set of bugs (like not being able to paste at all in 3.6 or that the paste event isn't fired in 4.2) but that's outside my control. I could try to debug and provide patches if I really cared, but given that some of the patches that I provided for CKEditor have been ignored for years I prefer to not waste the time that way.

BTW, soon I might replace all the CKEditor 4 demos with the "Moono color" skin, being forced to see those black and white icons is really depressing.

 

2013/04/27

Uploading files to CKEditor the easy way

It's been some time since I published an improved version of the original ImagePaste plugin for Firefox. In that version I included the option to upload files by drag&drop from the desktop and that feature was supported by the latest versions of all the browsers.

Since then I've been polishing the plugin, adding little details, fixing whatever bugs appear and recently I've added a major new feature that I had in my head for a very long time but I never took the time to write it.

Finally I thought that enough is enough and that it's better to get that idea out of my mind and so we have now version 3 of the ImagePaste plugin, with two toolbar buttons to upload files or images without any extra dialog, just a click on the button, select the file and it's uploaded and inserted into the content.

Features of the plugin

In all the browsers you can upload a file or an image by clicking the addFile or addImage buttons. All the browsers means that even IE8 is supported for this option and it's just the simplest way for everyone to add files without having to deal with all the options in the default image or link dialogs.

If you use a modern browser (current versions of Firefox, Chrome, Opera and Safari, as well as IE 10) you will be able to upload an image or file just by dropping it into the editor.

With Chrome and Firefox, you can copy an image or part of it to your clipboard in a program like Photoshop, Paint.Net, etc... and then paste it into the contents with Ctrl+V.

With Firefox, you can select a file in your desktop, copy it to the clipboard (Ctrl+C) and then paste it into the editor with Ctrl+V.

Demo

There is a demo with CKEditor 3 and there's another demo with just the same plugin but using CKEditor 4, including some zones in "inline editing"

Getting the plugin

All the details are available in its new home.

 

I'm testing now selling the plugin through FetchApp to avoid any delays between the moment that you pay the money and when you get the file, so I would like to know if you have any problems in order to change the seller to another one.

Of course, verify that the mail account that you use is correctly configured, In theory you should get the file right after the payment, but it's better if you receive any mail correctly because I'll use that for future updates (all updates are included as you can see)