2005 2006 2007 2008 2009 2010 2011 2015 2016 2017 2018 aspnet azure csharp debugging docker elasticsearch exceptions firefox javascriptajax linux llblgen mongodb powershell projects python security services silverlight training videos wcf wpf xag xhtmlcss

Moonlight: Mono's Silverlight

Here's something rather interesting... the developers on the Mono team "hacked" Silverlight and it only took them 21 days to do it. They are calling their own product "Moonlight", which I have to admit is a much cooler product name than Silverlight.

Project details as well as some internal information including a bit of information about Silverlight internals are are the link below. Even if you care nothing about Mono or Moonlight, if you have any interest in Silverlight at all you should check it out simply for that.

This is actually really cool as it should seriously help promote Silverlight as a de facto standard worldwide, but I doubt anyone will be making a documentary called "21 Days" any time soon.

Silverlight's Adoption as Public De-Facto Standard

Recently there have been comments floating around the internet and around conferences that Microsoft's Silverlight needlessly uses XAML as its mark up language where it should have used SVG (Scalable Vector Graphics). The argument here is based on the idea that since SVG is a vector technology accepted in all web browsers except IE, Microsoft should have used it instead of XAML and then simply added support for SVG to IE. While this seams to some to be a valid criticism and a good point to some of the web standards world, it is absolutely groundless and carries no weight.

Silverlight can be viewed as a web extension of the Windows Presentation Foundation (WPF), a .NET 3.0 technology and not simply as a new web technology. As such, it makes sense that Silverlight uses XAML, not SVG. If Silverlight were based on SVG, then there would be a chasm between Silverlight and the .NET Framework, but as it stands Silverlight's use of XAML makes it part of the .NET family. In fact, it’s important to note that elements in XAML usually represent objects in the .NET Framework; this would simply not be possible in SVG. Therefore, by choosing to use XAML over SVG, Microsoft kept SVG pure by not add proprietary technology to it.

Furthermore, SVG is "Scalable Vector Graphics" and as the name suggests it for vector graphics. If Microsoft were to start out with SVG as their base technology they would quick to add UI controls to it thereby altering it making it a Microsoft dialect of SVG, which would not be SVG at all. This would take the entire web world back to the same disasters that were seen in proprietary HTML elements, proprietary CSS selectors and rules, and proprietary JavaScript dynamics (i.e. "DHTML behaviors"). Aside from the architects and developers on the Internet Explorer team, the world, including Microsoft as a whole, thankfully has a lot more respect for specifications and standards than this.

Standards advocates should be very satisfied with Microsoft's decision to start from scratch on this one. Standards, as they are normally referred to as, deal with standardization and thereby allow everyone to talk about the same technology without proprietary terminology or technology. If Microsoft sets an explicit syntax on a well-defined language, publicly states the specification for the language, and makes it a multi-platform language, then the world has basically the same result that a standard would have (this point will be hit again in a moment.) While it's true that "popular" doesn't make things right (something most people learn early in high school) and that statements about "most people" do not mean a single thing, having a well-defined technology set with a set specification does make it a first class technology.

We can see this in the ECMA-334 (C#) specification. Microsoft could have taken JavaScript and forced it to obey the Common Language Specification (CLS) and pawned it off as the primary .NET Language, but they instead chose to create something entirely new and then publicly displayed the specification for it. So when .NET guides are written the samples usually have code for C# and VB, instead of JScript and VB. Those who criticize Microsoft for not using SVG as their client-side technology probably applaud Microsoft for creating a new programming language.

Lastly, it should be noted that one of the primary purposes of using the web as a platform is to make something more accessible. People should be able to use any sufficiently advanced web browser to access a web page or web application anywhere on the entire Internet. Truly, even if an application is created in a corporate environment, if the technologies used are proprietary to any one specific web browser, the primary purpose of using a web browser is defeated and using a smart client would probably give a much richer experience and result. So, while it is true then that the use of proprietary technology, such IE specific content, defeats the entire purpose of using the web as a platform, if a technology is spread enough, is on enough platforms, and allows integration into their current environment (i.e. Firefox, Safari, Opera), it doesn't need to be a standard because it would achieve the same result as a standard. Flash is probably the best example of this.

In conclusion, there should not be much fuss about Microsoft's new "Flash-killer" using what some would view as private corporate technology. As long as there is support for Silverlight in Firefox, Opera, Safari on Windows, Mac OS X, and Linux and a seamless installer experience, there shouldn't be any problem with a rapid world wide adoption of this new technology. Hopefully Silverlight's adoption into the web as a de-facto standard will silence many forms of critisism about it and help prompt developers to do a better job of creating intranet and Internet solutions for muliple platforms and multiple web browsers.

The ECMA-334 Standard

Let me state publicly for the record: I do not approve of books for learning C#. The only guide you will ever need is the ECMA-334 standard. It's a readable guide to the entire C# language that covers every facet of the language. This document is the definitive guide for C#. In fact, there is no document on MSDN that even comes close to the comprehensive native of C# than does the ECMA-334 standard as the ECMA-334 standard *is* C#.

Why do I mention this at all? Because, from time to time I get people asking me what book he or she should *buy* to learn C# and I always tell them what I've just stated above. Unlike Visual Basic, C# is NOT Microsoft's baby. They may have been the ones who gave birth to C# and continue feed it and nurture it, but it's a standard -- not Microsoft's baby.

Lastly, while you are getting the ECMA-334 standard, check out the ECMA-335 standard. This one is the standard for the CLI (Common Language Infrastructure -- which Microsoft implements as the CLR or Common Language Runtime). It goes into detail about the IL (Intermediate Language), the Common Language Specification (CLS), the Common Type System, and talks in some detail about various .NET concepts. I would consider this standard to be more advanced than what most people need at first, so I don't recommend this for initial learning (for that get Duffy's Professional .NET Framework 2.0 [0764571354] and then Richter's CLR via C# [0735621632]).

As a footnote, you could also check out the ECMA-262 standard (ECMAScript, that is, JavaScript), but it's not nearly as well written as the ECMA-334 and ECMA-335 standards and because of that I've never recommended it's reading to anyone.

CSS Architecture Overview

As a technology architect who has an emphasis in web architecture, one thing that I find that most ASP.NET completely misunderstand is the concept of CSS architecture.  It's incredibly important to learn that CSS is not simply "styling". This is one of the most common misconceptions about CSS in existence. CSS is more than the silly “style” attribute on XHTML elements. If that were the case, then none of us should ever rely on CSS as the “style” attribute does little more than dramatically increase the coupling between page structure and style.

Fortunately , however, CSS is more than simply "styling". In fact, CSS is an acronym that stands for Cascading Style Sheets. It's not just some nice marketing acronym used to make the technology sound cool, but is rather a very well thought out acronym that explains CSS very well. When most people come to CSS, they only look at the middle letter ("style") and completely ignore the other two letters completely. You need to understand each of the letters in order to fully grasp the architectural power of CSS.

The third letter represents CSS is "sheet". This means that CSS is a technology designed to be placed by itself in its own file.  By keeping your CSS rules away from your XHTML structure you are maximizing the potential of your system be removing all coupling and maximizing cohesiveness. That is, your XHTML is doing what it does best by representing the page structure, leaving CSS to do its job by focusing on the visual elements. There is no sharing of responsibilities and the aren't directly tied to each other, thereby allowing reuse of your CSS rules.

There are secondary reasons for doing this as well. One of them deals with manageability.  Instead of being forced to change each "style" attribute on each element across multiple files manually, you now have a centralized place for your style.  Saying "it's just one 'style' attribute, what's it going to hurt?" is a sign of laziness and unprofessionalism that will leads only to more people saying the same thing leading to a complete nightmare of spaghetti code. Imagine if people did that with C# and ASP.NET: "what's the big deal? It's only one script block." You can destroy anything by taking cutting corners.

Another secondary advantage of keeping your CSS in "Style Sheets" (CSS sheet) is that it keeps your client download time to a minimum. If you keep your CSS away from your ASP.NET/XHTML structure, your client web browsers can cache the XHTML document and CSS page separately.  When the ASP.NET/XHTML page changes, the web browser doesn't need to get all the CSS information again. In the same way, if you need to change the "style" of something, you can do so in the CSS sheet without affecting anything else. If you kept your CSS either in the "style" attribute as a sloppy blob of CSS rules in a <style/> element, then even the slightest color change is a modification of the ASP.NET/XHTML structure leading to a recompilation.  You may have killed your page cache as well.

The cascading nature of CSS, or to the “C” in CSS, is also at the heart of CSS architecture. If you manage your CSS sheets correctly, then you should have a system where you can literally change one file and have it reflect across potentially thousands of pages. Your changes will naturally flow from XHTML page to XHTML page, from CSS to CSS, and from parent elements to child elements with well thought out, virtually object-oriented element style overriding. Trying that with HTML or with CSS coupled to your XHTML elements or pages!

By working with CSS as true CSS, not simply as a nice technology to change font sizes and colors, we are able to take the potential of CSS to its logical conclusion: CSS themes. If you create a set of CSS sheets that specify the images, layout, colors, and various other style related aspects a specific look and feel, then you are in the perfect place to allow themeing of your web site.  If the term "theme" doesn't appeal to you, what about the term "branding"?  A few years ago I was involved in a project for a major fast food chain who had about 10 different brands.  They basically wanted 10 different store fronts, which made the resident e-commerce developer about flip out.  However, using a properly designed CSS architecture, I was able to provide a simple, yet powerful branding model.  First, I defined the XHTML structure based on their semantic representation.  Second, I applied a colorless and image-less CSS page which gave each website its element positioning.  Third, I gave each brand its own folder with its own root CSS page and its own images and other media files.  All the developer had to do was look at the URL path to obtain the brand name and then change a single CSS page between brand.  The developer was actually able to sleep that night.

As you can see from this story, CSS themes can be very powerful and save a lot of time.  You could event go more complex in your CSS themes.  For example, you could use a CSS coordinator.  Then is when you attach a single CSS sheet to your XHTML page and have that single CSS sheet contain a series of “@import” statements.  You could then actually change the look and feel of your entire website without ever touching the ASP.NET/XHTML structure and thereby never forcing a recompile anywhere.  I often use this technique to coordinate a CSS page for screen size (800.css, 1024.css, 1280.css) with a theme (plain.css, green.css, blue.css), with a core feature set (report.css, membership.css, landing.css-- which would be tiny, so your landing page is very quick to load).  This technique should look familiar to anyone deep into object-oriented design as it's similar to some of the GoF structural design patterns. Having said that, this is not always a required technique and sometimes it can lead to caching problems itself. For example, how will the page know to get the new CSS sheet? Sometimes it's OK to invalidate cache or to force a recompile.

Another reason for proper CSS design that is continually growing in importance is media specific CSS. Say you created a screen for management that allows simple report creation. You put a set of ASP.NET controls next to the report to allow management to refine the report data. How can you allow management to print the report without printing the ASP.NET controls? How can you turn off the colors of the report to maximize print quality on a black laser printer? How can you remove the application header from the form so that the report prints professionally or to make sure the document prints on one sheet? All these things are possible with media specific CSS. By having one structure stating the content of the document you have a base level entity that can then be transformed to various output media. Media specific CSS works for more than just printers. If you thought ahead in your web architecture and therefore created a proper semantic representation of your XHTML elements and separated your CSS from your XHTML, you can easily add light-weight mobile support with very little effort. When a web browser views your page it will display in all its glory, when a printer accesses the page the buttons and header will be gone, and when a mobile device views the page the sidebar is now hidden, the fonts are now smaller, text shows in place of images, and the menu is now abridged.

You can easily add media specific CSS to your documents by placing more <link /> elements in your XHTML head element.

For example, the following will set a general CSS page, a print theme, and a mobile theme.

<link href="Style/ClassicTheme/default.css" rel="stylesheet" type="text/css" />
<link href="Style/ProfessionalPrintTheme/default.css" media="print" rel="stylesheet" type="text/css" />
<link href="Style/SimpleMobileTheme/default.css" media="handheld" rel="stylesheet" type="text/css" />

One thing you may want to keep in mind about this is that the iPhone is not considered a “handheld” device. To add a media specific CSS page to the iPhone, please see this article.

It's hard to overestimate the importance of proper CSS architecture, yet I find that most web developers have never even heard of this before.  I suspect that it's because its a fusion of diverse topics which with most web developers aren't familiar.  For example, many ASP.NET developers I work with know software architectural principles, but can't even spell CSS.  Other times, I'll see awesome web designers who have no idea what software architecture is.

XmlHttp Service Interop - Part 3 (XML Serialization)

In this third part of the series, I discuss how to manually create an XML service and a SOAP service using XML serialization to maximize the flexibility in your service interop work. The technique allows you to very quickly accept just about any XML format from the wire and work with it in a strongly typed manner in your .NET applications.

Reflecting Graph Video Demo

For those of your who have not installed Silverlight, below is a link to a video of the demo. As you will see it works perfectly in Firefox and IE.

Links

Reflecting Graph Silverlight Demo

In one of my Ajax applications I wanted a REALLY cool interface for some of my data modeling. I was a bit stuck until I heard that Microsoft published a beta of Silverlight 1.0 (an actually working one too!) This of course opened up an entirely new planet of new design possibilities.

The design that I came up with was a tree model where each element was a node in a mesh like structure where the user can move the elements as well as the entire structure in one smooth motion and where the user can zoom in and out with their mouse scroller... something that was incredibly simple to build in Silverlight.

To demonstrate what I built, I would like to use toned-down version of the same thing to show a simple type reflector with a Silverlight interface. In this demo, simply select an assembly and select a type. The type will show up as a graph with branches for reflected members, organized by methods, properties, and events.

The mechanics of this is actually really simple. First, define a few canvases so that an inner canvas can scale and translate to give the effect of a zoom and canvas movement. Second, have a method that accepts a JSON structure containing the model for your tree. In the iteration plot the ball element, the text as as well as a line that goes from itself to its parent. The trick in this step is to get the math right to know where exactly to plot the element. I'll discuss this in a bit. Lastly, watch for mousedown, mouseup, and mousemove events on the elements and the on canvas as well as mouse scrolling events on the canvas.

Placing the elements on the screen is really just basic geometry. We know that the first element can go anywhere and that its sole purpose is to set a positioning basis for all other elements. Plotting the children is just about as easy. For perfectly symmetrical elements, you just have to plot them at equal points from each other around a 360 degree radius. For mathematical details on this, see the essential mathematics page below.

Having symmetrical elements is all well and good, but it's ugly and nasty. [See image 1] So, to take it a bit further, I played with the angle a bit. If the element was the first child, I just plotted it normally via symmetry. If not, make the angle an increment of 45. This will just make the children the same length from each other regardless of how many there are. [See image 2] After this, I scaled down the separation of the elements by how many elements there were. [See image 3]

Next, I wanted to make sure the children were pointing in the same general direction their their parents pointed in. So I subtracted the angle of the parent (minus 90) to make it go in the same general area. Remember that all the elements are grouped together, so now we are moving groups of elements, not just a single element. [See image 4]

At this point it doesn't look too bad, but the child groups don't really line up with their parents. For them to line up I needed to add 45 degrees plus half the radius of the entire child set (another 45 degrees scaled by how many children there are). [See image 5]

Now we have something that looks like it it could grow nicely... however, it would be nice if it didn't look like a robot built it. To give it a more organic feel I added a random angle to every element. No, it's not the most sophisticated method for creating a more natural look, but it does work rather nicely. [See image 6]

As far as the events are concerned. If you get a mousedown on an element, you are in dragging mode and when you get a mousemove, adjust the element, text, and line accordingly. Silverlight will automatically redraw the line based on the new X, Y endpoint of the line. If you get a mouseup, then you are no longer in dragging mode and mousemove, doesn't do anything. If you get a mousedown that's on the canvas, then you simply need to adjust the translation of the canvas. If you get a mouse scroll simply, adjust the scaling of the canvas. It's extremely important to take the scaling into effect when you work with the moveable elements as the coordinate system completely shifts. In the provided demo, I added a few adjustments for this, but it could be much better it a live version.

As a closing note, this demo can also act as an example for an asymmetrical schema Ajax service. The service I wrote here accepts an XML message, but responds with JSON data. It's important to remember that the focus of communication is on receiving, not on transmission. If a person from France and a person from German want to have a conversation and each CAN speak the other's language, but understand their own flawlessly, the one from French may speak German so as to maximize communication and the person from German may speak French to the same end. So in this example, JavaScript speaks XML to .NET, which can easily deserialize it to a usable object and .NET speaks JSON back to JavaScript for easy direct use.

Related Materials

JavaScript Repeater Data Binding

In a previous post, I wrote about a way to convert JSON to XAML. The sample I provided with that post didn't really stop with a simple conversion example, but it also demonstrated how to create an use a simple JavaScript data binding repeater. It's just something I threw together in two minutes to bind an array of objects to a div to basically do in JavaScript/XHTML what ASP.NET does with the Repeater control. I think many people will be interested in this technique to see how they can bind data to a browser in a more efficient way.

As far as my requirements, I wanted this to be like ASP.NET in that the data is bound from a data source matching the fields in the data source objects to the data fields declared in this repeater and after all is said and done, the original declarative code should disappear. As far as the data source, I wanted it to be a series of the same type of object... kind of like a generic List.

So, to start off with, I simply declared the code that I wanted to write as the client. Some people call this the 'Sellsian' method (after Chris Sells at Microsoft), though I simply call it... common sense (as I honestly suspect Chris would too!). So, here is the declarative code I wanted to write for my data binding:

<div id="rptData">
    <h2>Title</h2>
    <div id="title" class="bind"></div>

    <h2>XAML Output </h2>
    <div id="output" class="bind"></div>
</div>

In this situation the data source fields are matched to element with the bind class and the element id. This is much like <%#Bind("") %> in ASP.NET.

On the other side, I would like my data source to be in JSON format and I would like to be able to bind in a way that 'feels' like a static class. Here is what I decided on:

var dataSource = [{
        title: 'Ellipse',
        output: Xaml.CreateXamlFromJSON(jsonElement1)
    }, {
        title: 'Rectangle',
        output: Xaml.CreateXamlFromJSON(jsonElement2)
    }, {
        title: 'Canvas',
        output: Xaml.CreateXamlFromJSON(jsonElement3)
    }
];

DataBinder.BindTextRepeater(D('rptData'), dataSource);

In the sample above you can see that I have a data source with 3 objects with the object being defined with the interface of a string field named 'title' and another string field named 'output'. Furthermore, I wanted to call the method what it is: a text repeater, not a fancy object repeater (though building that shouldn't be much more difficult), so my static method is called BindTextRepeater and accepts the declarative repeater object and the data source as parameters. In my examples I use the D('id') syntax where D is simply an alias for document.getElementById. I know some people use a dollar sign for that, but that just looks really weird to me.

Now onto the code. Here is the basic shell:

var DataBinder = {
    BindTextRepeater: function(obj, ds) {

    }
}

The first thing we do in this situation is look at the data source and see what the objects look like. For this we simply need to create an array to record what fields we are looking at and iterate through the object to record it's fields. Put another way... we simply need to do simple JavaScript reflection and record the object interface, something that's incredibly simple in JavaScript.

var fields = new Array( );
for(var f in ds[0]) { fields.push(f); }

Now that we know what the object looks like, let's iterate through the datasource and bind each field to it's proper place in the repeater. This is what the rest of the method does and it should be fairly self explanatory, except for the following things:

First, I said that data is bound to fields with the 'bind' class. What if you had your own class on it? That's not a problem. JavaScript classes are a bit like .NET interfaces (where as JavaScript ids are a bit like .NET classes), so you can "apply" (or implement in .NET) a few of them. So, if you wanted the apply the class "message-log" to the bindable element, you would simply have the following:

<div class="bind message-log"></div>

In this case this is possible because I'm simply checking to see if the class STARTS with "bind", rather than simply checking to see if it IS "bind":

if(obj.childNodes[e].id && obj.childNodes[e].className && obj.childNodes[e].className.substring(0, 4) == 'bind') {
    /* ... */
}

Second, if the element if found to be bindable, the method looks through the fields array to see if that element has data for in the specified data field. If so, it binds. If not... there's not much it can do (though ideally you would throw an exception). One thing to note about this is that it replicates the element and binds the text as a child. This is seen by the following line:

var bindableObj = obj.childNodes[e].cloneNode(false);

When you clone a node, you can say true, which means to clone it's children, or you can say false, which means to clone only that particular element. In this case, we don't need the children as this is a text repeater and we are going to put our own text as a child. If we were to say true, we would have to go out of our way to remove the children.

If the element is not found to be bindable, it copies the element and it's children as can be seen as the cloneNode(true).

Third, after the data object is ready you have a duplicate of the original repeater, but now filled with data from the data source. This data object is then bound to the browser's DOM as a element immediately before the repeater template. After all data objects have been bound, the original repeater is removed. Thus, you replaced the repeater template with data bound controls and you're done.

Here is the final implementation of the BindTextRepeater method:

var DataBinder = {
    BindTextRepeater: function(obj, ds) {
        var fields = new Array( );
        for(var f in ds[0]) { fields.push(f); }
        
        for(var r in ds) {
            var outputObj = DOM.createElement('div');

            if(ds[r]) {
                var d = ds[r]
                for(var e in obj.childNodes) {
                    if(obj.childNodes[e].nodeType && obj.childNodes[e].nodeType == 1) {
                        if(obj.childNodes[e].id && obj.childNodes[e].className && obj.childNodes[e].className.substring(0, 4) == 'bind') {
                            for(var i in fields) {
                                if(obj.childNodes[e].id == fields[i]) {
                                    var bindableObj = obj.childNodes[e].cloneNode(false);
                                    bindableObj.appendChild(DOM.createTextNode(d[fields[i]]));
                                    outputObj.appendChild(bindableObj);
                                }
                            }
                        }
                        else {
                            outputObj.appendChild(obj.childNodes[e].cloneNode(true));
                        }
                    }
                }
            }
            obj.parentNode.insertBefore(outputObj, obj);
        }

        obj.parentNode.removeChild(obj);
    }
};

Using this same approach of templating XHTML elements and reflecting JavaScript JSON data sources, you could actually create a full scale data binding solution for all your client-side data binding needs. Furthermore, since we used a JSON data source we can now bind data directly from JSON services accessed via Ajax techniques. Lastly, as I hope you can see, there wasn't really much magic in this example and absolutely no proprietary technology. It's simply a usage of what we already have and have had for many, many years.

Links

Converting JSON to XAML

For reasons beyond human comprehension, the world felt like making an huge deal about Microsoft "revealing" SilverLight even even though WPF/E has been known about for some time now and even though nothing technical has changed even in the slightest with the simple change of a name. Having said that... it will probably be an awesome technology and I'm sure I'll be marinating many of my future applications in it. Editing XAML in notepad is much more appealing to me than being forced to use the overpriced and overly complicated Flash.

As cool as that is, however, since most of the work I do involves pure Ajax/JavaScript clients with almost all .NET coding at the service level, I definitely find JSON (which IS a JavaScript object) easier to manage than XML (which CAN BE a JavaScript object). So, in one of my applications I have the service that provides graphical information to Silverlight in the form of JSON serialized XAML, which will then be converted into XAML.

Here is an example of something the service would provide:

var jsonElement1 = {
        'Ellipse': {
        'Canvas.Left': '130',
        'Canvas.Top': '130',
        Height: '200',
        Width: '200',
        Stroke: 'Red',
        StrokeThickness: '10',
        Fill: 'SlateBlue'
    }
};

No, it's not human readable like XML is, but it's what JavaScript loves to see and it's what my service creates. Also, no, this is done for for efficiently purposes. This doesn't lower the service "message" size in the slightest, but it does however help to keep a consistence programming model across all my service calls. Furthermore, given that the data was in a database and not in XAML on the server, there's no real overhead. If, however, the data was in XAML on the server it would be a sign of pure stupidity for me to convert that to JSON and then back to XAML.

The parsing for something like this is actually really simple: just iterate through the JSON objects and arrays and creating an XML tree from it. As a reminder or reference, with regard to XML in a web browser, Firefox uses document.implementation.createDocument for XML while IE uses the MSXML2.DOMDocument COM object. Furthermore, Firefox is more strict in its usage of XML than the more familiar COM model that IE uses.

Here is an example of what I mean:

var doc = null;
if(DOM.implementation && DOM.implementation.createDocument) {
    doc = DOM.implementation.createDocument('', '', null);
    Xaml.ScanJSONElements(doc, data, doc);


    var xmlSerializer = new XMLSerializer( );
    return xmlSerializer.serializeToString(doc);
}
else {
    doc = new ActiveXObject("MSXML2.DOMDocument");
    Xaml.ScanJSONElements(doc, data, doc);
    return doc.xml;
}

As you look through the Xaml.js file provided, you will also see that Firefox is very explicit about it's namespaces, while the COM model figured you will take care of them. There's nothing wrong with either approach, it's just something you will want to be aware of if you ever create XML in JavaScript.

Links

Object Range Selection and Emulating Word 2007's Formatting Box

Say you're working on a text driven web application and you want to get the selected text in order to see what was selected. With JavaScript that's easy enough, but what if you wanted to know what strongly-typed text was selected in order to recreate the selection later? This would come in tremendously handy if you want to have text annotation capabilities in your application. But, why stop there? If you are going to do that, why not add a nice pop-up window over your selection to give easy access to appropriate toolbox options? That's exactly what Word 2007 gives you and you can do the same in your JavaScript applications.

Implementing these two things involves the following tasks: assign each word (or letter if you want really fine grained control) a container span with an id and then watch for hovering over an object. When an object is hovered over, start a timer counter for the time of the hover. If hovering ends, reset the timer. When a specified amount of hover time has elapsed, see if they is a selection and if the object currently hovered over is in the selection. If so, show the toolbox. The first word and he last word selected are saved in the browser's Selection object as the 'anchorNode' and 'focusNode' objects of the selection, respectively.

Here's the meat:

// Get all spans and iterate through them making sure each REALLY exists and
// making sure each as an id.
var b = document.getElementsByTagName('span');
for(var a in b) {
    if(b[a] && b[a].id) {
    
        // Only use those with an id starting with 'wid'.
        if(b[a].id.substring(0, 3) == 'wid') {
        
            // Set the event that is called at each interval.
            b[a].timercall = function(evt){
            
                // It there is a saved object (see onmouseover event below), 
                // then continue...
                if(gHoverObject) {
                
                    // Increment counter.  When there are 4 timer intervals, 
                    // then get the object information and show the hover box.
                    hoverCounter++;
                    if(hoverCounter > 3) {
                    
                        // Get the text selection
                        var selection = window.getSelection( );
                        
                        // Does the selection contain the object the cursor is currently over?
                        // false means that the object the cursor is over must be fully selected.
                        // That is, half the word being selected won't cut it.
                        if(selection && selection.containsNode(gHoverObject, false)) {
                        
                            // Save the first object id selected and the last object id selected
                            toolboxObj.start = selection.anchorNode.parentNode.id;
                            toolboxObj.end = selection.focusNode.parentNode.id;
                            toolboxObj.style.display = 'block';
                            toolboxObj.style.left = parseInt(gHoverObject.x) + 'px';
                            toolboxObj.style.top = parseInt(gHoverObject.y) + 'px';
                        }
                    }
                }
            };

            b[a].onmouseover = function(evt) {
                // When the object is hovered over, save the object.
                gHoverObject = this;
                gHoverObject.x = evt.pageX;
                gHoverObject.y = evt.pageY;
                
                this.timer = setInterval(this.timercall, 150);
                hoverCounter = 0;
            };
            
            b[a].onmouseout = function(evt) {
                // Destroy the object so the algorithm doesn't run.
                gHoverObject = null;
                clearInterval(this.timer);
                hoverCounter = 0;
            };
        }
    }
}

The provided proof-of-concept demonstration also demonstrates how to setup regular text to be strongly typed. This is simply done by splitting the text by a space and putting each word into a span, then putting each span into a parent object and finally putting that parent object before the original text and deleting the original text. You can view all this happening and see the resulting structure using Firebug for Mozilla Firefox.

The proof-of-concept demonstration provided is for Mozilla Firefox only.  Internet Explorer does NOT have the abilities to do this.

Important Disclaimer: it's not my intention to teach anyone JavaScript. This information is not for someone to simply copy/paste into their own applications. A solid understanding of the DOM, JavaScript syntax and dynamics, and XHTML is required before any true application can be built. So, please do not ask me any "how do I..." questions. When I get those I merely explain the basics and tell the person to figure it out on their own. In other words, I won't do your homework for you.

Links