Tuesday, February 8, 2011

jQuery/pre-wrap trick

I've had a recent encounter with Internet Explorer 7 for $DAYJOB.  For this section of code, IE7 is our minimum required browser.  I was displaying some user input and wanted to maintain the text formatting while not using <pre>, which I find ugly.  So, for a while, I was using the CSS style "white-space: pre-wrap;" which will let the text flow like html, but break at new line characters like pre.  Perfect.  This has the added benefit that the text will be editable and we have a good jQuery plugin that will take a div and turn it into a textarea and use the content of said div as the inital content.  After a while, I noticed that IE7 was not behaving.  This is because IE7 does not support the pre-wrap CSS style.  Well, that's an issue.  So after a bit of reworking, I came up with this:


$("<div/>")
  .addClass('user_input')
  .append(
    $(
      $.map(
        this.split("\n"),
        function(v, i)
        {
          return [
            $("<span/>").text(v+"\n").get(0),
            $("<br/>").get(0)
          ]
        }
      )
    )
  )

So let's break this down a little.  
  1. I create the div, and add a class to it.
  2. I begin an append of the content
  3. I then take the output from a map, and turn it into a jQuery object for the append (Yes, this is important)
  4. I use the data I've been given and split it by a new line character and use that array as the input to a jQuery map operation
  5. Please note that I used the quote form of split, not the regex form.  IE7 also removes empty array items when using the regex version.
  6. For each item from the split, I return an array.  The first is a span that includes the text we need, plus a new line, to maintain the text representation of the data.  The second is a <br/> to take place of the newline in the html
  7. Last, I return the DOM elements of the span and br.  This is important, since that's what the jQuery constructor back in step 3 expects.  Also, I must ask for element 0 since otherwise, I'll get an array instead of an element back from .get().
The best part of this whole thing, is that if I do a .text() on the div, I get exactly the text I need for the editable textarea.  Perfect!  Well, not exactly.  This may have issues with spaces being insignificant, but in our case, that's acceptable for now.

Friday, February 4, 2011

The NQP question

This weekend was a busy weekend for me, but more importantly, it was a busy weekend for Parrot.  There was a Parrot Developer's Summit (PDS), which I wasn't able to attend, and a lot of good discussion happened.  Perhaps too much since I glazed over a couple parts of the discussion.  If you're interested, the summit can be found at http://irclog.perlgeek.de/parrotsketch/2011-01-29.  Make sure to hit the next day, since it spans two days worth.

There was some Lorito discussion, which is interesting for me.  But actually, most of the discussion about Lorito was about the announcement that by Parrot 3.3, which lands in April, we will have a spec and initial implementation of Lorito.  The team, to my recollection, is going to be cotto, dukeleto, bacek and myself.  There was also come clarification between the terms M0 and Lorito.  M0 being the opcode set and bare minimum, and Lorito being the whole project.

But this blog posting isn't about Lorito.  It's about NQP.  The major discussion that took place during PDS was the suitability of the new NQP being included as a core component of Parrot.  This discussion was interesting for me since there were good points on each side.

Before I go any farther, let me explain what's happening to NQP.  pmichaud explains the change in detail at http://irclog.perlgeek.de/parrotsketch/2011-01-29#i_3232428, but the quick version of it is that NQP is going to become multi-backend.  It will support output to Parrot, JVM and CLI.  It was made clear that it may not be able to support all VM backends the same, some features that Parrot gives naturally will be difficult in JVM, for example.  But, the goal is to make Rakudo, and anyone using NQP, to be able to retarget to another platform with relative ease.  On the surface, this appears to be a noble goal and something Parrot would be interested in.  I'm going to admit, it's appealing.  But, looking deeper under the surface, and you'll find some deep issues.  The big issue is maintenance cost.  This may not seem like much, since it's the NQP team that will be maintaining the code, but as long as NQP is a core component, included with Parrot, the Parrot team has a responsibility to it.  It's like when I was at college, students always wanted the IT department to install AIM on all the lab computers, since it always gets installed anyways.  What few people seem to realize is that by doing that, IT is taking some form of responsibility for the installation.  Students are more apt to go to IT first to resolve an issue with AIM.  There's a cost for that amount of support tickets.  When AIM is installed by IT, the support is implied at that point.  Same with Parrot, if JVM support is there in the Parrot core, support for it is implied by it's existence.  In this regard, I agree, including the new NQP, alternate backends and all, is not what Parrot should do.

The issue isn't so cut and dry to say that NQP should leave the nest because it supports multiple backends.  The reality is that Parrot needs a tool like NQP.  People that want to start developing and targeting Parrot need a tool that can get them started fast.  That's also not to say that there should be one true tool to use, there should be multiple to fit people's needs.  But Parrot needs a default, and it's something that Parrot needs to support.

In the PDS aftermath, there were a few reasonable options brought up.

  1. Include the new NQP, but only include the "use parrot;" equivalent functionality.  This seems to be the option that is in favor right now.
  2. Continue to use NQP-rx, which is what is currently supported.  Personally, I don't like this option, since it means that Parrot will diverge from NQP, which will be difficult for HLL writers to transfer from NQP-rx to NQP.
  3. Use another, existing tool, something like Winxed.  Actually, the more I look at winxed, I don't doubt it could fit the bill.
  4. Create a brand new tool.  Feasible, but wouldn't happen anytime soon.  Although my fear is that it'd end up being something unpleasant to work with like PASM/PIR.  That fear is probably unfounded, but it's a concern none the less.
So, in the end, the question I ask myself is, what do I think Parrot should do?  Personally, I think option 3 and 1 are the most reasonable options, and failing that, option 4.  Option 2 just shouldn't be an option in my opinion, too many problems could and would arise from having two divergent languages.  I do think option 3 is the most desirable, since that way we can support HLL writers out of box, but they still have options.  I understand the cost to do that, and at that point, I concede that option 1 is probably, at the very least short term, the option that should be persuaded.

But that's just my opinion.