Showing posts with label Chrome. Show all posts
Showing posts with label Chrome. Show all posts

2015/07/30

A Tweet is not enough

This Monday I did read a new blog post in Surfin' Safari about a new feature that Apple is introducing to make it easy to use the current system font on web pages. For whatever reason I was a little fed up with so many vendor CSS prefixes so I sent a tweet about it, but obviously it's hard to express things correctly on a tweet specially as I'm not an English native speaker and I'm not able to abbreviate things like all of you do because I'm afraid that then it will be even harder to understand what I say.

So after fighting only a little to avoid the characters limit I sent:
The mess caused by vendor prefixes on the wild is not enough, so we have new -apple webkit.org/blog/3709/using-the-system-font-in-web-content/ @jonathandavis
I'm not gonna copy each following message and reply as you can try to read it there, but I would like to point out some parts, a better explanation and say thanks to everyone that contributed as I think that it has helped to talk about the problem caused by the current usage of vendor prefixes.

I'm nobody, I don't work on a big company, I haven't written any book, it takes me too long to write things because I have to try to find the correct words so excuse me if this post has mistakes or it's unreadable, I've tried my best.

What did caused me to send that tweet?
It's known since quite some time that the current usage of vendor prefixes is causing harm in the interoperability between web browsers. Quite a few years ago we had the first browser wars between IE and Netscape where each one tried to defeat the other introducing new features as fast as possible and we all know that IE6 was the winner, so we had so many websites that took advantage of those proprietary features and the "Best viewed with IE" or "You must use IE to view this site" messages that most of us hated with passion.

It took many years to fight and reverse that situation, engineers had to work too many hours finding out the way that things worked and reverse-engineering the specifications. We also keep the perpetual "Mozilla" and "like Gecko" in the User-Agent, but currently this is absolutely getting out of hand.

So going again to a browser monoculture is something that I don't want and anything that points in that direction makes me cringe.

Currently other browsers are trying hard to avoid those same mistakes, experimental features are available only in "Nightly", "beta", toggling a setting in about:flags, using a command line parameter, whatever, ... but the common goal of that approach is to not expose experimental features for broad usage to the public web but the people that want can try it out, give feedback and find out if it solves the problems as expected.

But Apple is not planning to do that, they pointed out that this isn't aimed only at betas (although a day later he replied that it's only in beta at the moment, obvious as there's no final release ATM).

And one part that I found really offensive was this tweet about my comment that Apple doesn't remove the prefixed version of anything that they introduce:
And we will always support them (unlike some vendors that remove things at will). So what is the issue?
with other comments that I found ... we'll I think that it's better to not say what I'm thinking:
You can’t just break sites or apps. Apple doesn’t roll like that. A number of properties changed from prefixed to unprefixed too.
 It is what any company should say that cares about developer and user experience. An API is a contract and guarantee.
Just load the Release notes of any Mac OSX version and search for Deprecated Frameworks and Removed Frameorks.

So it's clear that Apple is able to deprecate and remove APIs even if they were the greatest new innovation at the time, but the obvious difference is that they have full control of the OS (if you don't like what we do, here's the door out), but on the Web they are playing the Embrace, Extend, ... game.

Going back again to the starting point:

Why are vendor-prefixes bad?
I'm not the one stating that, please read carefully this great post by Karl Dubost, take a look at what Mozilla and Microsoft has been forced to do just to have a chance of people using their browsers, and then tell me if this message from @ryosukeniwa is right or wrong:
I don't think proprietary CSS features aren't that bad since they fallback nicely. DOM and JS API are different, ..
But as I said, I'm nobody, please read what Daniel Glazman has to say about the matter. I'm really honored thinking that all of these great people have spent some time reading about my humble tweet, but then I have found out the real reason why I despite vendor prefixes: The CSS working group asked all of us to stand against them for the Open Web and it seems that the message got deep into my head.

That's enough for this post, I have many other things to say because there were lots of tweets and I don't want to mix the things here.



2015/05/21

Testing DevTools, take 2

This is my second day testing Firefox Developer edition.

Almost right after start, I get a notice that there's an update ready, clicking it a dialog was shown stating that the update was ready to be applied. So I agreed and waited, this should be transparent and done without such dialog, specially when frequent updates are expected due to the usage of the alpha channel.

The prompt to save passwords has changed, I'm not sure if previously it showed the user name, but now it has a field with the masked password below it that it's absolutely useless, it can't be edited, it doesn't provide any info, Why are they wasting time and effort in things like this?

So I started working, the first changes were mostly server-side to send new data and modify some JS, then I added two breakpoints to check that it was working as expected, some adjustments, I browsed a little, took a quick look at the network tab, its layout is somewhat different like the Clear button at the bottom right instead of the top left like all the other tools so at first I thought that it wasn't available.

Then I went back to debugging, but now those two breakpoints no longer work. No matter if I remove and add them again, reload the page..., the script isn't stopped and so I can't use Firefox to debug javascript. After restarting Firefox and adding again the breakpoint at the same place this time worked, but my usual reaction at this point is just to switch to another browser and go back to Firefox only when everything works perfectly in other browsers and I have to review Firefox.

I want to check as I'm not sure the value of the document.ELEMENT_NODE constant so I type document.EL and as it's already shown in the autocomplete I press Enter and it uses only "document.EL" so it says that it's undefined, so I press Up arrow, Tab and it shows in light gray "<- again="" autocomplete="" br="" english="" exact="" i="" if="" in="" is="" m="" makes="" not="" pressing="" results="" sentence="" so="" spanish="" sure="" tab="" the="" this="" without="" work.="">In Firebug and IE the first Enter does the autocomplete and then pressing it again shows the result. Chrome behaves like Firefox on the first step but after pressing Up arrow no matter how many times you press Tab, the autocomplete doesn't work.

Back to CSS, trying to add or edit a pseudo-element like a::before it's not possible, the rest of the tools allow it; Chrome even shows them in the DOM tree.

Trying to do some basic testing with Mobile isn't even fair. IE11 has the very minimum, Firefox improves it a little, although not really too much and Chrome is hands down the absolute king. Several features really useful that makes it a non-sense try to use any other tool to start checking for mobile:
Touch emulation: the pointer turns into a fingertip and :hover no longer works. Absolutely a must.
Device list: instead of a list of sizes, it shows devices by their name, and it also adjust other things like the device pixel ratio, so it's easy to get a good view of how it will be viewed on such screens.
Rule with @media rules in the page, good to find the breaks and verify them.
Zoom control, nice.
Network emulation, so far I haven't used it too much, but it has obvious benefits without the need of using external tools to simulate throttling. I know that I'll use it because otherwise it's impossible to test how a remote server works with different conditions.

I've decided to test now the WebIDE to connect to my phone. Yesterday I did a quick test and I gave up. I saw "Chrome on Android" listed and I picked it but nothing happened, and today I realized that then I must go to the left and click on "Open application" and the open tabs are listed there and debugging starts.
So then I tried to debug Firefox as I already debugged Firefox on Android some time ago, and then I realized that it's not done automatically and I had to enable the remote debugging on it, this should be hinted more clearly, when an Android device is detected, create an entry linking to how to enable debugging of Firefox.

One "annoying" thing is that every time that I connect again to Firefox on Android it prompts me to accept the connection, with the only options as "Disable", "Cancel" and "Accept", but not a "Yes, always allow this device", Chrome doesn't do such things.

When connection to a device Chrome clearly shows the list of open tabs and allows to close, open a new one or change the url, as well as proxying the request to localhost, another must have to be able to test changes without having to upload to a server.


2015/05/20

Firefox DevTools, a long way to go

This Monday I tweeted about the bad state  of JS debugging in the current releases of Firefox where both Firebug and DevTools are no longer useful because they ignore most of the breakpoints.

I got a reply from suggesting me to use the alpha version AKA as Firefox Dev edition, but I pointed him that it's known that it lacks behind all the other tools, so I would prefer to wait until the most obvious bugs are fixed (I linked some that are important for me).

Yesterday I got another reply suggesting me to give DevEdition another try, and so this evening I've started by opening a document where I've been writing down this experience of installing and trying to use the latest version. It's not from the point of view of a new user because I've tested it a little bit, but I might not be aware of awesome things just because the problems that I find force me to use other tools.

The first step is instaling the Firefox Dev edition, I picked the custom install and of course I rejected the option to install it as my default browser, that's a non-sense that when you install a new browser you're going to make it the default right from the start (yes I know that everyone does this since Netscape times).

After launching the first thing that I notice is that the UI lacks the rounded borders of the normal Firefox. I notice also how slow are the UI animations (it feels the same way in the normal Firefox, but I don't see them because I've added the Classic Theme Restorer and that way I don't have to use the hamburger menu). That's a problem with Firefox itself trying to create useless animations, not with the DevEdition.

Then I try to use it on a site and the obvious first stones appear in my path, the history, autocomplete, credentials, everything is empty so I have to type everything again. Not a big problem, but it will force me to waste my time. It should have prompted me to import such data from Firefox or to use Sync as this seems a sensible use-case. As it didn't offer me to use Sync I'm not sure if that would be a good idea or it's risky to use it with different versions at the same time.

So let's start testing it.

I add a new CSS property "max-wi" TAB, now I type 0 and press Arrow UP, it changes to 1 but it's unitless so it doesn't work. Firebug and Chrome correctly change from "0" to "1px", IE11 behaves like Firefox.

Now it's time to save the changes, I adjusted only one rule but when I try to use the context menu there's no "Copy rule" like Firebug or IE11, I have to manually select the text like in Chrome.

Extra Bonus points and the main reason that IE11 it's now mostly my prefered tool for CSS adjustment is its Changes pane that shows all the CSS changes made in the page. Certainly it's a little buggy sometimes and it could have several enhancements, but all the rest of developer tools lacks anything like this and it's precious to be sure to know all the adjustments made across different elements.
Chrome seems to have something related with the History pane, but honestly I haven't figured out how to make it work as I want.

One thing that DevTools doesn't seems to know is that "0" is "0", it's unitless so when I write "margin: 0 auto;" it's wrong to change it to "margin: 0px auto;". Firefox and Chrome respect my 0 and IE11 does it correctly for "margin: 0 auto;" but not for "height: 0;" (test by checking a property written in the stylesheet that way or modifying a property and switch to another element and back to the modified element)

Other clear sign that these tools aren't ready: Use the context menu and select "Add rule", change the selector or leave it as is, now Tab and you'll find that you're now nowhere, you have to click inside the rule to add a new property. All the other developer tools correctly place you ready to type your new property as that's the only logical thing to do after creating a rule. This breaks the workflow and makes me waste my time moving my hands from the keyboard to the mouse.

Bonus points go to Firebug because while editing a rule you have a super useful autocompleter based on the parent node names, ids and classes. No other tool has this.

Trying to work a little with javascript, put a breakpoint, check the DOM, reload the page. All the tools except Firefox DevTools correctly switch the selected pane to the script that has the breakpoint and DevTools just show that tab in green stating that execution is stopped and waiting for you to click.

Another day I will keep on testing and reporting the differences, but so far I haven't seen anything in Firefox that made me want to use it.

2012/02/09

Vendor Css prefixes

This post tries to explain my points of view as a web developer about the Vendor prefixes issue:

Introduction

Css prefixes for experimental features are fine. They are a clear signal that something is being tested but it's not a standard, they allow browser vendors to create new features and test them without having to wait for the approval from everyone else, they allow to check how they can be used and whether they create unexpected problems or not.

So yes to keep vendor prefixes alive.

But...

The problem is when those prefixes spread all around the web and people start using them all over the place. Then the browser vendor will argue that they can't change them as people are already relying on them, other vendors have to provide their own implementation (with their prefixes) to avoid being left behind but even if they provide those same features they see that people are testing only on the native browsers of iPhones and Androids, both based on Webkit.

And this is the current situation: non-webkit browsers areclaiming that the use and abuse of -webkit is so strong that they are being forced to support in their own engines some -webkit features.

My opinion about how to deal with it

First rule should be that no browser manufacturer is allowed to ship experimental features in release versions of their browsers. Those experimental features should be restricted only to the alphas and betas, when a final version is released, it should allow only the unprefixed version if that feature has gained traction and it has been "approved" or don't ship it at all.

With "approved" I don't mean that it requires a final status, just a state where other vendors agree that it can be useful, it will be (or it's already) implemented that way by them and of course there's a spec stating how does it work.

Of course this is a big problem, you'll see them screaming and kicking around before accepting this. They prefer to keep on doing their little tricks and pushing whatever it's in their heads and releasing it to the wild to give them an advantage over the competition. But the fact is that even if this is the standarized way to create propietary features, we're back to the Netscape 3 era where each browser introduced new features without caring about the other one and then that other browser had to copy and replicate the successful features of the first one.

We know that it was bad for the developers, why is that good now?

Second step:

When a browser replicates the propietary feature of another one, it should support ASAP the feature both with their own prefix as well as the unprefixed one. If the feature is not good enough or not clearly defined to support the unprefixed version then it's obvious that it doesn't make sense to support the prefix from the other browser.

That would allow web developers to start testing the prefixed version from the first vendor and if it's clear that it's good enough they can put only the unprefixed version and all the browsers will be handled at once.

Third course of action:

Evangelism on sites that teach new CSS3 features, they shouldn't generate anything with a vendor prefix, just use the standard so it can work in all the browsers.

I don't think that most of the web developers are going to write huge amounts of css by themselves, instead they will look at some generator for backgrounds, buttons, patterns and copy whatever it's there. They might not know what's a vendor prefix, they just see that they can copy that code and it works. Given that some vendors (I'm looking at you Microsoft) make it really difficult to test the new versions of their browsers, you can't expect the developers to remember to add the -ms all around because they won't notice if it works or not; they just know that they have to keep on supporting IE8 for a number of years and that it doesn't support fancy things so they won't care too much about what's next for the few ones willing to buy a new computer.

I know that almost no one will care about my opinion, but at least I hope that someone else in the whole world agrees with me that these would be good steps.

 

 

2011/08/13

Upcoming changes for Write Area

It has been a long time, but these days I'm going to try to push a new stable release of Write Area. It will be mostly an upgrade to the current CKEditor 3.6.1, but at the same time I'm gonna try to finish some code that it's available in the betas and provide a simplified version.

The main change will be the removal of the option to select whether to open the editor in a bottom pane or in a dialog. My plan is to finish the behavior of the new "integrated" mode, so that whenever you select to use Write Area with a normal textarea then it will be replaced by a CKEditor instance integrated in the same page. This is similar to what the "bottom pane" provides, but with the advantage of being able to create more than one instance, and the rest of the scripts of the page can get direct access to the contents as if nothing had happened.

If you try to use instead an existing editor that isn't too compatible with the current Firefox or it's missing features, then the editor will be launched in dialog mode. The plan is to do this automatically without the need to select a preference.

Why?

First: Simplify options.
More options means more testing, harder for the user as he has to think about what's better. I can't claim that I know better than him what's better for him, but I know what's more job for me.

Second: Try to avoid future problems due to changes in Firefox.
The bottom pane is a "XUL overlay", that means that it's somehow quite integrated with Firefox, and in the future the plan is to try to move as much extensions as possible to the Addons-SDK. That means that such integrations might be harder or just impossible. If I start removing these blocks I can try to test if it's possible to port the extension to this new world. Anyway that goal is quite far away as I've stated previously that I won't start using the Addons SDK as long as they require to install Python or any other third party libreary/compiler/whatever.

Third: Other browsers.
By using a simpler approach it's possible to create a Write Area version for Chrome, and although I don't use it I understand that other people do, so if there are just a few differences then I can provide a port of the extension. It won't be as feature rich as the Firefox version, but at least is something that people can use.

Conclusion

If you have a strong reason to believe that I'm making a mistake the I would like to hear your concerns. Otherwise I'll go ahead and release the update when it's ready

2011/07/31

Third version for seamless replacement of textareas

Sometime ago I wrote a script that allows to use CKEditor, and at the same time keep using older scripts existing on the page that relied on reading the textarea.value (or even writing it), without having to modify them to use the CKEditor API.

The initial version worked with Firefox and Internet Explorer 8, and shortly after I added some adjustments so that Opera was also supported.

Recently a comment in that second post stated that the script gave errors in Chrome, although it tries to detect if the API that I was using is supported, but of course, webkit guys decided to implement the API but not make it available for native properties. Their statement is that treating native properties as overridable would have a negative effect on performance, and as we all know it's much more important to have a fast browser than a browser that allows the developers to do new things; unless you're in their team then you can write a new API for whatever you need and everyone else should use this API because it will change the world, you'll no longer have to use Flash because now you have this API to overcome other problems that we didn't want to fix. Besides the bug tickets commented previously, here's another one: bug 36423

Ok, enough ranting.

As I said, I've worked to find out the problems and the funny fact about this new version is that it works in Chrome but it still fails in Safari 5.1. So you can use it in your site if can restrict the browser used by your users to IE8+, Firefox 3.5+ , Opera 10+, and Chrome 12+ (I don't really know the oldest version of Firefox, Opera and Chrome where this will work, but I wouldn't expect anyone to use old versions of those browsers)


// Modify the default methods in CKEDITOR.dom.element to use .nativeValue if it's available
CKEDITOR.dom.element.prototype.getValue = function()
{
    if (typeof(this.$.nativeValue) == "undefined")
        return this.$.value;

    return this.$.nativeValue;
}

CKEDITOR.dom.element.prototype.setValue = function( value )
{
    if (typeof(this.$.nativeValue) == "undefined")
        this.$.value = value;
    else
        this.$.nativeValue = value;

    return this;
}

// Hook each textarea with its editor
CKEDITOR.on('instanceCreated', function(e) {
 if (e.editor.element.getName()=="textarea")
 {
  var node = e.editor.element.$;

  // If the .nativeValue hasn't been set for the textarea try to do it now
  if (typeof node.nativeValue == "undefined")
  {
   // for Opera & Firefox
   if (!DefineNativeValue(node))
   {
    // IE8 & Webkit
    if (!DefineValueProperty(node))
    {
     alert("Your browser is buggy. You should upgrade to something newer")
     return;
    }
   }
  }

  node.editor = e.editor;

  // House keeping.
  e.editor.on('destroy', function(e) {
   if (node.editor)
    delete node.editor;
  });
 }
});

// This function alters the behavior of the .value property to work with CKEditor
// It also provides a new property .nativeValue that reflects the original .value
// It can be used with HTMLTextAreaElement.prototype for Firefox, but Opera needs to call it on a textarea instance
function DefineNativeValue(node)
{
 if (!node.__lookupGetter__)
  return false;

    var originalGetter = node.__lookupGetter__("value");
    var originalSetter = node.__lookupSetter__("value");
    if (originalGetter && originalSetter)
    {
        node.__defineGetter__("value", function() {
                // if there's an editor, return its value
                if (this.editor)
                    return this.editor.getData();
                // else return the native value
                return originalGetter.call(this);
                }
            );
        node.__defineSetter__("value", function(data) {
                // If there's an editor, set its value
                if (this.editor) this.editor.setData(data);
                // always set the native value
                originalSetter.call(this, data)
                }
            );

        node.__defineGetter__("nativeValue", function() {
                return originalGetter.call(this);
                }
            );
        node.__defineSetter__("nativeValue", function(data) {
                originalSetter.call(this, data)
                }
            );
        return true
    }
    return false;
}

function DefineValueProperty(node)
{
    var originalValuepropDesc = Object.getOwnPropertyDescriptor(node, "value");

 if (!originalValuepropDesc)
  return false;

 // Safari doesn't allow to overwrite the property (but Chrome does)
 if (!originalValuepropDesc.configurable)
  return false;

    Object.defineProperty(node, "nativeValue",
            {
                get: function() {
                    return ( originalValuepropDesc.get ? originalValuepropDesc.get.call(this) : originalValuepropDesc.value );
                },
                set: function(data) {
                    originalValuepropDesc.set ? originalValuepropDesc.set.call(this, data) : originalValuepropDesc.value = data;
                }
   }
        );

    Object.defineProperty(node, "value",
            {
                get: function() {
                    // if there's an editor, return its value
                    if (this.editor)
                        return this.editor.getData();
                    // else return the native value
                    return this.nativeValue;
                },
                set: function(data) {
                    // If there's an editor, set its value
                    if (this.editor) this.editor.setData(data);
                    // always set the native value
                    this.nativeValue = data;
                }
            }
        );
 return true;
}

// Detection, not really needed, but it can help troubleshoting.
if (Object.defineProperty)
{
    // IE 8 and updated webkits
 // Detect Safari
 if (document.head)
 {
  var test = Object.getOwnPropertyDescriptor(document.head, "innerHTML");
  // IE9
  if (!test)
  {
   if (!DefineValueProperty(HTMLTextAreaElement.prototype))
    alert("Unable to define property override on the prototype");
  }
  else
   if (!test.configurable)
    alert("Safari doesn't allow to overwrite native properties");
 }
}
    else if (document.__defineGetter__)
{
    // FF 3.5 and Opera 10
 // We try to get the innerHTML getter for the body, if it works then getting the value for each textarea will work
 // Detect old webkits
 if (!document.body.__lookupGetter__("innerHTML"))
  alert("Old webkits don't allow to read the originalGetter and Setter for the textarea value");
}
    else
{
    // detect IE8 in compatibility mode...
    if (document.documentMode)
        alert("The page is running in Compatibility Mode (" + document.documentMode + "). Fix that")
    else
        alert("Your version of IE is too old");
}

 

2011/02/06

Creating extensions for each browser

These last days I've tried to create a similar extension for each browser, and this is a little recap of the first differences among them. A page with a full list of differences can be found in the State of the Add-on Developer Union

Firefox

In Firefox there are two options:

  1. Create the extension using the "classic" way that goes back to the very beginning and provides full access to anything in Firefox, you can customize it in any way that you like.
  2. Use the new Add-Ons SDK, only for Firefox 4. These ones doesn't require a restart and it's supposed to be future-proof.

In order to create a classic add-on you can get a skeleton using the Add-on Builder . There are lots of info about how to create these extensions and the API that they can use, and to start creating an Add-on the first step is this page to setup the environment. All you need is a text editor, some patience and be careful following the instructions. You can then configure Firefox to load the extension from the disk but when you make changes to the code you'll have to use an extension to force a reload of all the Firefox code or directly restart it; not nice.

To get started building add-ons with the new SDK, check the tutorial.
First problem: You are required to have Python installed.
What?
I'm so tired of projects that say: you have to install this or that or all of these projects just to get started.
What's so special about Python and the SDK environment that can't be done inside Firefox?
Why should I have to keep the list of instructions instead of being able to click on some buttons "Add extension", "Run tests", "Install", "Reload", etc...
Big boo here.
Maybe they want us to use wget instead of Firefox if they think that command line is so nice.

Anyway, I gave it a go in the Mac (I won't bother trying to install python in windows, it has already too many SDKs there for this and that), and so I followed the basic example, while trying at the same time to adjust it to my goal, I add the files, and when I do the "cfx run" then I get a cryptic error "raise ValueError('invalid resource hostname: %s' % name)". WTF? check again that I haven't done anything too weird. Nops. Then put back exactly the sample code. Nops. Search for the message. Bingo!, although there's no warning about this in the tutorial, you CAN'T use uppercase letters in the folder name. Hello Mozilla, it's 2011, I thought that the problems with uppercase and lowercase were gone long ago since MS-DOS. Why aren't your wonderful Python scripts able to deal with them?
Another big fail.

As a summary: I got a bad taste of the Add-ons SDK. When they put forward something that isn't oriented to Python lovers I might test it again (please note that I haven't even tested the API, just the environment makes me go back to keep using the classic method)

Chrome

It seems that there's a lot of work going on here in order to provide a very complete API for the extensions as well as good documentation and lots of examples. You can see a very basic one here and everything is quite easy to follow. Given the fast path that it's set on the release of new Chrome versions we can expect that this trend will continue and that they will add missing features to make some tasks even easier.

The only thing that you need is a text editor and Chrome, and by following the instructions you can get it working. It's not so powerful as the classic extensions in Firefox, but it's really easy to start creating an extension and there are lots of examples to check how they work.

Safari

It seems again that there's plenty of documentation at a central place, but just in the first page there's something strange:

Important: To develop extensions for Safari, you need to sign up for the Safari developer program online, at http://developer.apple.com. You need a signed certificate before your extension can be installed.

Uh?
So to create an sample extension in my own computer I need a certificate?

Ok, this shows again that Apple is a control freak. Why do I have to register to get an Apple ID and then get enrolled into a "Safari developer" program so that I can finally request a signing certificate, just to create a test extension? I can understand that in order to deploy it I might need to sign it, but I really should be able to create an extension for myself without the need to sign two looong agreements with Apple (I'm not sure if there was a paragraph about my first newborn there)

Anyway I go ahead and get a certificate in the Mac, and then it seems to work, but I would like to keep the development environment in Windows, so I try to install the downloaded *.cer there but anyway Safari keeps saying that there's no signing certificate installed. After a little while and some digging I realize that I must export the private signing key from the Mac KeyChain to Windows and once I installed it there Safari started working.

In some regards this might be the simpler interface of all the browsers in order to create an extension as you get a dialog to setup the basic configuration of the extension instead of editing them in a text file. The way that the code is setup is similar to Chrome (and Opera): background pages, injected scripts, so porting from Chrome wasn't a hard task.

As it happens with almost everything Apple does, if you are satisfied with what they offer, they try to make it quite easy, but if you want something extra then it's a no go.

Opera

I started checking the Opera API with the very first builds where they started adding support for extensions. In those days the API wasn't complete, there were a bunch of things that didn't work at all, so due to my hurry to test it I became a little frustrated because there were so many things missing, there was almost no documentation at the moment so it required a lot of effort to try to make something work because the examples were quite basic.

Now they have improved everything a lot, the behavior is similar to Chrome and Safari, but this is still a fresh SDK, so there are still missing features available in other browsers. They have written now lots of documentation and I guess that very shortly it should be quite easy to port an extension between Opera, Chrome and Safari due to the convergence of APIs that the developers find useful.

For the moment Opera it's lacking an API call similar to the ones that I've used for the other browsers so I will put the extension for browser at rest waiting for them to include them instead of struggle again and get tired of finding that it's not possible in any way.

2011/01/24

HTML5 Video plugin for CKEditor

You might have heard a lot of people talking about the new features of HTML5, and one that has brought a lot of interest is the <video> element that some people think that will avoid the use of Flash once and for all (at least Steve Jobs thinks so).

Personally I don't think that it will be so easy to dismiss a whole environment like Flash just because videos now can be played without external plugins, leaving aside the fight of h264 vs WebM (or as is now: Apple & MS vs the rest of the web), Flash has a lot of features that aren't easy to replace, the most basic one, the fact that you deploy a single swf file, vs having to provide several javascript and images just to perform anything basic with javascript. And as soon as you want to use some effects, you might end up with something huge and in fact as slow as the dreaded flash files.

But back to the topic, HTML5 video and CKEditor. What about that?

Ok, here we go, this is a plugin sponsored by DM Logic that makes using the <video> element as easy as an old <img>, you can insert, edit, use the context menu, etc... the dialog allows to specify the poster image, the dimensions (they are automatically adjusted according to the preview) and two source files, so that both the browsers that use the WebM format (Chrome, Firefox and Opera) and the ones that support only h264 (IE9 and Safari) can view your videos. Here's a short video showing how it works.

Download it here.

Updates:

v.1.3 26/08/12: Fixed problems with IE9, wrap the video in a <div> to avoid the problems with <p>. It's compatible with both CKEditor 3 and CKEditor 4

Demo

 

 

2009/12/12

Uploading .app files

Developing an extension for an application like CKEditor means that you have to be aware of the environment. CKEditor tries to cover the differences between the browsers and even adds workarounds for the bugs that are known in each one (as long as it's possible of course)

So when you are writting your code and something doesn't work as expected you have to start searching for bugs in your own code (the usual culprit), then you have to review how you are using the CKEditor API, verify that you have understood the explanation and that it matches the actual code that you have written. Then you escalate up the problem to the CKEditor source code, maybe there's some bug there that it's causing your problems. And sometimes you have to get even higher in the chain...

One of these situations is an issue that I've talked about in the post about uploads in CKEditor, I did try to apply an onChange listener for an uiElement with type="file", but it didn't work. After debugging the issue I found that despite the huge differences in DOM (this element was created as an iframe with a form and the <input type="file">), the event listeners aren't aware of this difference, so they apply the listeners to the container <div>.

This week I've been writing the code to fix this problem (that's the beauty of open source, when a problem is spotted it's possible to really check what's going on under the hood and create the patch without waiting for a company to include it in their plans), and after some tests it seemed to work: as soon as the user picks an image from their computer it is uploaded to the server and they just have to review the Alt attribute, the Class or the Title.

I had to review that the events are being reapplied correctly when the iframe recreates, so the tests (somewhat random) also included uploading non image files to verify that they are handled properly and everything still works.

Then I started to find that something was wrong, I selected an application, the file picker showed the name but there was no message. I debugged it further and the onChange event was being correctly fired (well, at first it was fired too many times due to a bug in the logic to append the listeners, but this is what these tests were about).

Maybe not CKEditor?

I had this form inside an iframe in a lot of nested code with lots of javascript, custom events and God knows what else. The next step was to create a simple testcase to focus on the problem:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
    <head>
    <title>Upload test</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <script type="text/javascript">
            function fileChanged(e)
            {
                var input = document.getElementById("upload");
                console.log("Selected file: " + input.value);
                //input.form.submit();
            }
        </script>
    </head>
<body>
    <form method="POST" enctype="multipart/form-data">
        <input type="file" name="upload" id="upload" onchange="fileChanged(event)">
        <input type="submit">
    </form>
</body>
</html>

This showed that I could select any file and it showed the name correctly and the form was posted by pressing the submit button or with the js call. But if I selected an application (I'm using currently a MacBook) then it showed the name and the form wasn't submitted. No error message, no warning, nothing.

The simple test removed CKEditor out of the equation and avoided long hours trying to find a non-existing problem in that code, and instead it pointed to some other basic issue with the browser and the upload of Applications (.app)

The current browser was Firefox 3.5, so I searched bugzilla but I wasn't able to find any report about this, the only bug that reported some strange problem was one about sending sometimes files with 0 size to the server.

So I added

                console.log("File size: " + input.files[0].fileSize);

and it showed the .app to be files of 0 size.

Something is quite wrong here!. I tested Safari and it seemed to allow the upload the .app but it showed the size as 102 bytes instead of several Mb.

Then I finally realized that an Application in Mac OS X is really a folder with subfolders and files, so this is the reason why it fails. Firefox accepts the .app in the filepicker but at the upload time it somehow sees that it is a folder (or that it isn't a real file) and rejects to send the form, but as I said, there's no warning about the problem. Testing with Opera did provide a message stating that the path pointed to some file that it couldn't find.

The most interesting situation was Safari, I changed the form to point to a real script that would handle the file and the result was that the application has been compressed on the fly and sent to the server as a .zip

How does each browser behave?

This is a live test with some code similar to the above:

So on one hand we have Firefox, it doesn't allow to upload the .app and doesn't provide any hint that there's a problem with the selected file. Also shows the size as 0.

Opera does its job much better and shows a tooltip on the <input type="file"> explaining that there's a problem there. Better but still not good enough as people might get confused about the reason of the problem. It hasn't implemented the API to get the size of a selected file.

Safari is quite different, if you select an .app then it will compress it and send it as a .zip so even if the user might find it a little strange that it has bothered to compress the data he finds that he was able to upload the file that he wanted. The only issue is that it shows the size as 102 instead of showing the same data that it's in the Finder.

The final test was the new beta of Google Chrome. Like Safari it showed the size of an .app as 102 bytes, but when I tried to upload it to the server (localhost) it just hanged. It showed a warning about a non responding page and no matter if I selected to close the page or ignore the warning. Chrome was dead and the only solution was to force quit it, even if the tab can be closed, something remains working there that didn't allow a clean exit.

So this can lead to one bug report for each browser (well Opera is almost OK, so it should be just a feature request), so much fun and job for a little test trying to find a bug in my code or CKEditor.