eFORCE
Blogs Home | Corporate Website

How Can CSS Scripting Layout Help the Web Development Community?

Background
 
CSS Scripting Layout was designed as a general-purpose solution for defining the layout and resize behavior of HTML elements on a web page. It can be used to describe any variety of layouts succinctly and efficiently. It may be used to encapsulate layouts in reusable constructs that are applied implicitly with minimal developer imposition. Alternatively, layouts may be input explicitly, allowing developers to control precisely the layout and resize behavior of each element among a set of elements. 
 
See the CSS Scripting Layout Model blog entry for a more detailed description and example usage in blog entries Table Layout and Mixing Layout Policies.
 
CSS Scripting Layout addresses most of the frustrations Web Developers have expressed in various articles referenced in my comments on layout in the current CSS Standard. In the remainder of the blog I’ll post a sampling of some of the commentary of authors and commentators from articles referenced there and briefly comment on how Scripting Layout addresses each concern.
 
Eric Meyers – Wanted: Layout System
 
From the author...
 
“So how do we get really powerful source-order-independent layout? I wish I knew. … We just need it, and have needed it for a good decade or so. Without it, CSS is a styling language but not a layout language. We’ve bent it into being something close to a layout language, which is nice but not really ideal.
 
Maybe CSS isn’t the place for this. Maybe there needs to be a new layout language that can be defined and implemented without regard to the constraints of the existing CSS syntax rules, without worrying about backwards compatibility...”
 
The Three-Column Presentation example exhibits source order independence. Scripting Layout defines interfaces and a set of objects in a composition that results in a powerful source-order-independent layout solution. Furthermore, Scripting Layout is fully backward compatible with the current CSS standard.
 
More from the author...
 
“CSS will be extended by JS.”
 
Extending CSS with Scripting Layout and JavaScript is a natural progression from the present state.
 
From Commentators…
 
 
“Give me math, variables, and constants. Give me positioning relative to a specified element. With those things I can make my OWN layout solution. Implement a grid system, and all independent of mark-up order.”
 
And again Matt Wilcox:
 
“The problem is this: It’s not possible to provide a generic solution to layout problems. Our layout problems are not generic. They are specific to our designs. So we need the tools in the core of CSS to make our own layout solution.”
 
Scripting Layout enables the specification any kind of mathematical expression. Positioning relative to specific elements is exhibited in the Three-Column Presentation example. Scripting Layout enables anyone to implement their own layout solution. Moreover, Scripting Layout enables anyone to share and reuse solutions in the same manner that HTML JavaScript solutions are shared and reused such as JQuery.
 
 
“I think the best bet would be to create a separate layout module, independent of semantic markup in HTML and independent of the style rules in CSS as well.”
 
Scripting Layout provides layout independence from the both the HTML source and CSS style rules enabling a level of abstraction that makes layout easier to achieve.
 
 
“What CSS needs to make a good layout system is not so hard, really. It really boils down to satisfy the two main criteria about layout: being able to control the POSITION and SIZE, in the TWO dimensions, and being able to control the RELATIONSHIP of those caracteritics with other elements.”
 
Actually, a good layout system is hard, mathematically speaking, layout is often np-hard or np-complete such as a table layout. Scripting Layout provides a set of heuristics that enables the efficient resolution of difficult np-hard layout problems.
 
 
“…it seems quite clear that the problem is the lack of the ability to define relationships between elements: position and size.”
 
Scripting Layout enables the specification of relationships (constraints) among and between elements.
 
 
“Find out the fundamental axioms that work together to form the basis of a layout complete grammar… there must be a way to achieve any derived two-dimensional layout including the ability to define how it reshapes under different window sizes and zoom levels… Find a syntax and implement it.”
 
Scripting Layout provides a grammar and syntax, JavaScript, and fundamental axioms, new interfaces and constraint resolution techniques that enable a way to achieve any derived two-dimensional layout including the ability to define how it reshapes under different window sizes and zoom levels.
 
 
“…any container can be constrained (from any side, or the center) to be a certain distance (% or px) from it’s parent, including height. It’s basically absolute positioning done right. This opens up vast possibilities with layouts, far more than we have today, and equaling or bettering what can be done with tables.”
 
 
“Has anybody proposed something like Xt’s Form widget? All of the Form’s children size themselves, and they specify attachments to other widgets, or to the edges of the Form. So a 3-column layout, with a header and a footer, would be something like…
 
It’s simple to understand, it’s resolution-independent, and it’s really powerful.”
 
 
“We need the ability to “attach” one element to another in relation to each other. Possibly including the ability to “attach” an element in relation to a parent element…”
 
The Three-Column Presentation Scripting Layout example exhibits this “attachment” ability as specified by the Motif Form Widget.
 
 
 
“…the perl saying “Simple things should be simple, difficult things should be possible”…”
 
Through encapsulation and reuse Scripting Layout makes many difficult things much simpler.
 
 
From the author...
 
"No Expressions - There is currently no ability to specify property values as simple expressions (such as margin-left: 10% - 3em + 4px;). This is useful in a variety of cases, such as calculating the size of columns subject to a constraint on the sum of all columns.
Vertical Control Limitation - While horizontal placement of elements is generally easy to control, vertical placement is frequently unintuitive, convoluted, or impossible. Simple tasks, such as centering an element vertically or getting a footer to be placed no higher than bottom of viewport, either require complicated and unintuitive style rules, or simple but widely unsupported rules.
Poor Layout Controls for Flexible Layouts - While new additions to CSS3 provide a stronger, more robust layout feature-set, CSS is still very much rooted as a styling language, not a layout language."
 
Scripting Layout addresses each of these CSS weaknesses:
  • JavaScript provides syntax for expressions.
  • Vertical control is precise and intuitive.
  • Flexible layouts become much easier to achieve.
  • Scripting Layout is a layout language.
 
 
From the author...
 
“…CSS just can’t do many of the things we should expect of it. Real-world CSS is likely to get longer, not shorter, as CSS evolves toward its manifest destiny and allows us to declare… all manner of complex layouts for which we currently turn to table elements and layout systems like the Dojo BorderContainer and ExpandoPane widgets…”
 
All manner of complex layouts are achievable with Scripting Layout. Layouts are as reusable as the Dojo BorderContainer and ExpandoPane widgets only easier to use and more efficient computationally.
 
From Commentators…
 
Rob:
 
“…until CSS lets me format my layout in a simple grid, just like a table, without resorting to strange non-semantic markup and obscure large negative margins and other hacks, I will continue to use HTML tables to perform this function.”
 
HTML-like tables are achieved in the Scripting Table Layout example.
 
More from Alex Russell – The W3C Cannot Save Us
From the author...
 
“There’s also no indication that the WG has taken stabs exposing the expressive power that Microsoft exposed with CSS expressions.”
 
Microsoft’s CSS expressions had severe performance issues that have lead many people to dismiss JavaScript as a viable layout language. Scripting layout as implemented here is fast and efficient at realizing even the most complex kinds of layout.
 
From the author...
 
“The fact that we have to resort to such contortions to produce layouts that please the eye (in such a simple, basic way) makes me wonder if css – as we know it today – is up to the job at all.”
 
This is a common sentiment. Scripting Layout enables the production of layouts in simple and basic ways that are efficient. Scripting Layout is up to the task.
 
From the author...
 
“CSS tables have only one notable weakness: CSS does not allow for table cells to span rows or columns the way they can in HTML tables (with the “rowspan” and “colspan” attributes).”
 
HTML-like tables that include cell spanning are found in the Scripting Table Layout example. Furthermore, the cell spanning in this example requires no special nonsemantic HTML mark-up.
 
Paul Hammond – Eric Meyer
From the author...
 
“CSS is still incomplete - Alex Robinson's one true layout had stuff in it that nobody had thought of. Scripters are shoring up the weak points, presentation libraries (YUI), work on CSS is slow but is happening. CSS and web standards keep popping up where they’re least expected.”
 
The integration of JavaScript and CSS for layout as seen in Scripting Layout is a natural progression from what is happening now. The CSS Working Group should consider formalizing it.
 
Nicholas C. Zakas – CSS sucks
From the author...
 
“Why is it that creating multi-column layouts [in CSS] still requires trickery and some magic even after all this time? And why can I still not achieve the same type of layouts that I could easily do with tables?”
 
HTML-like tables are achieved in CSS in the Scripting Table Layout example without trickery or magic.
 
From Commentators…
 
Lonnie Lee Best:
 
“You can use absolute positioning to get any layout you want. However, when a page is loaded or resized, that layout remains static. For a layout to accommodate sizing, it requires *behavior* of that layout. I wouldn’t call it un-pure to use javascript to control layout behavior. I would simply call it an inconvenient reality for those who *purely* wanting to keep their layout out of their markup.
 
The question is: do we want that layout behavior to be inherent, or do we want to explicitly control it with javascript.
 
… some type of layout encapsulation needs to be specified somewhere in the markup or css or javascript… you need a way of grouping elements outside of the markup.”
 
Scripting Layout provides the kind of layout encapsulation and grouping required to achieve explicit and implicit layout and resize behavior. Scripting Layout bridges the gap currently existing between CSS and JavaScript.
 
From the author...
 
“We do not need the Working Group to study individual problem cases and propose a pre-packaged “solution” that either misses the point, is fundamentally wrong, or is inflexible... The crux of the issue is that W3C seem to try providing high-level “solutions” instead of low-level tools.“
 
“There are NO tools to allow flexible layout on the web. Building better tools drive better end results.“
 
“When I say CSS needs to manipulate the DOM I'm really talking about some sort of pseudo-DOM, a Visual Object Model… This is entirely about getting CSS able to provide flexible styling WITHOUT manipulating the semantics of a document.“
 
and finally…
 
“CSS 2&3…still suffers from the basic issue of having too few and too inflexible tools for layout.“
 
Scripting Layout is a low-level tool that allows designers to build their own layout solutions that are efficient, reusable, and independent of the semantics of a document. The language incorporates a type of Visual Object Model with the container, its ordered list of subelements, and Visual Object interfaces.
 
From Commentators…
 
Juergen Schreck:
 
“we just need a standardized way for CSS and Javascript to interact better.”
 
Scripting Layout describes a CSS/JavaScript interaction that can be standardized.
 
devsmt:
 
“my concern with css is that is not practical to write reusable components, the language itself laks tools to do it, basic math and variables but class like inheritance too, can alleviate this problem.”
 
Scripting Layout is a tool that provides basic math and variables as well as reusability and inheritance.
 
From the author...
 
“CSS gives imperfect options for layout. Take the example of equidistant objects, have a look at what’s required to achieve this simple visual effect. Something as fundamental as this should not be so hard to achieve. And it wouldn’t be if CSS had basic math calculations combined with an awareness of the dimensions of boxes other than parents.“
 
Equidistant objects are achieved in the Scripting Line Wrapping example. Justifying objects in this manner and mixing this effect with other layout effects is easily achieved in this example.
 
“If I want a grid layout, I want the display to adapt not pixel by pixel, but grid-unit by grid-unit.“
 
A reusable grid layout of this type could be achieved with Scripting Layout.
 
And finally from a member of the W3C CSS Working Group Elika Etemad – Layout Is Expensive
From the author...
 
“A lot of people complain about limitations in the layout capabilities in CSS. Layout in CSS is a pain, and it's a pain because CSS originally wasn't designed for coarse layout, only for linear documents. The CSS Working Group totally understands that CSS today is totally incompetent at doing layout… It is very, very obvious to us that CSS needs better, easier, more powerful layout capabilities.
 
At the same time, defining a CSS layout system is hard. It's expensive, and I don't mean money but skill×time, which is rarer… So for everyone out there who wants CSS layout to improve… please, don't come to the CSS Working Group with a loosely-defined layout proposal…Chances are your proposal is really hard to define and incorporate into existing CSS layout systems at the level of precision we need.“
 
The Scripting Layout Model proposed here is well-developed and fully incorporates into the existing layout system. Moreover, Scripting Layout enables the CSS Working Group to get out of the business of defining ever more expensive, yet limited, CSS layout systems.
 
Conclusion
 
I’ve shown how CSS Scripting Layout brings together many of the independent ideas that the Web community has expressed regarding layout within CSS. Scripting Layout is an open system whereby new layouts heretofore not achievable in CSS can be realized efficiently and shared among the developers putting to an end the frustrations nearly every developer has experienced with the current standard.
 

posted @ 5/4/2010 10:09 AM by Darrel Karisch

CSS Scripting Layout – Mixing Layout Policies

 
CSS Scripting Layout – Mixing Layout Policies
 
 
CSS Script – Line Wrapping
 
In this example we present a CSS Scripting Layout policy that arranges rectangles left to right and line-wraps rectangles as required depending on the available width.  With this line wrapping layout we also present a set of policies that can be included with it to alter fine points of the layout to achieve different effects. These set of policies largely emulate inline layout and associated properties.
 
See the CSS Scripting Layout Model blog entry for a detailed description of layout model used in this example.
 
The HTML in Example 1 produces the screen shots in Figures 1 and 2.
 
Example 1 – Line-Wrapping Container
 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
 <title>Line Wrap</title>
<style type="text/css">
 
@layout-policy line_wrap {
initial-script: "\
var lineSpacing=2;\
function containerHeight() {\
var line = lines[lines.length-1];\
return line.top+line.rects.preferred_height.max;\
}\
function containerWidth() {\
var width=0;\
for(var i=lines.length; --i>=0;) {\
var w = lines[i].preferred_width;\
if (width<w) width=w;\
}\
return width;\
}\
function getLine(position) {\
var i=-1;\
var p=0;\
do {\
p+=lines[++i].rects.length;\
} while (position >= p);\
return lines[i];\
}\
function deriveLines(width) {\
var lines = new Array;\
var list = rectangles;\
do {\
var line = lines[lines.length] = new Object;\
var rects = line.rects = list.preferred_width.cumulate.gt(width);\
if (rects.length==0) rects = line.rects = list(0,1);\
var lineNo = line.number = lines.length;\
line.height=rects.preferred_height.max;\
line.preferred_width=rects.preferred_width.sum;\
if (lineNo>1) {\
line.top=lineSpacing+lines[lineNo-2].bottom;\
line.bottom=line.height+line.top;\
} else {\
line.bottom=line.height;\
line.top=0;\
}\
list = list(rects.length, list.length);\
} while (list.length > 0);\
return lines;\
}\
var defaultHeight;\
var lines = deriveLines(rectangles.preferred_width.sum);\
";
container-script: "\
if (sizing)\
 defaultHeight=containerHeight();\
else\
 lines = deriveLines(container.width);\
";
rectangle-attributes: '{\
"line":"getLine(rectangle.position)",\
"isFirst":"rectangle.line.rects[0]==rectangle"\
}';
top:"rectangle.line.top";
height:"rectangle.preferred_height";
left:"rectangle.isFirst ? 0 : predecessor.right";
container-height:"defaultHeight";
container-width:"containerWidth()";
}
 
@layout-policy vcenter {
container-script: "\
if (!sizing)for(var i=lines.length; --i>=0;) {\
var line = lines[i];\
line.center = line.top+line.height/2;\
}\
";
top:none;
vertical-center:"rectangle.line.center";
}
 
@layout-policy justify {
container-script: "\
if (!sizing) {\
var w=container.width;\
for(var i=lines.length; --i>=0;) {\
var line = lines[i];\
var rects = line.rects;\
var len=rects.length;\
if (len>1) line.spread = (w-rects.width.sum)/(len-1);\
}\
}\
";
left:"rectangle.isFirst ? 0 : predecessor.right+rectangle.line.spread";
}
 
@layout-policy fill_line {
container-script: "\
if (!sizing) {\
var w=container.width;\
for(var i=lines.length; --i>=0;) {\
var line = lines[i];\
var rects = line.rects;\
var sum = rects.preferred_width.sum;\
line.space = (w-sum)/sum;\
}\
}\
";
width:"rectangle.preferred_width+(rectangle.line.space*rectangle.preferred_width)";
}
 
@layout-policy fixed_height {
height:"rectangle.line.rects.preferred_height.max";
}
 
@layout-policy pack_column {
initial-script: "\
var margin=8;\
var space=(rectangles.length+1)*margin;\
";
width:"container.width";
height:"rectangle.preferred_height";
top:"margin+(predecessor ? predecessor.bottom : 0)";
container-height:"space+rectangles.preferred_height.sum";
container-width:"rectangles.preferred_width.max";
}
 
#body {
layout-policy:"pack_column";
container-width:100%;
    border:0px black solid;
    padding:0px;
    margin:0px;
    position:relative;
}
div {
    background:gray;
    margin:0px;
    border:0px black dotted;
    padding:0px;
    position:absolute;
}
 
div button {
    margin:0px;
    padding:0px;
    position:absolute;
}
span {
    margin:0px;
    border:1px black dashed;
    padding:0px;
    position:absolute;
}
 
#line_wrap1 {
layout-policy:"line_wrap";
}
 
#line_wrap2 {
layout-policy:"line_wrap vcenter";
}
 
#line_wrap3 {
layout-policy:"line_wrap justify";
}
 
#line_wrap4 {
layout-policy:"line_wrap vcenter justify";
}
 
#line_wrap5 {
layout-policy:"line_wrap fill_line";
}
 
#line_wrap6 {
layout-policy:"line_wrap fill_line fixed_height";
}
 
 </style>
</head>
 
<body id="body">
 
<span>
The line wrapping displayed in the following containers illustrates how a mixin set of layout policies can
work together to achieve different effects.
</span>
 
<div id="line_wrap1">
<span>line_wrap</span>
<button>button&nbsp;1</button>
<button>button&nbsp;2</button>
<button>button&nbsp;3</button>
<button>button&nbsp;4</button>
<button>button&nbsp;5</button>
<button>button&nbsp;6</button>
<button>button&nbsp;7</button>
<button>button&nbsp;8</button>
<button>button&nbsp;9</button>
<button>button&nbsp;10</button>
<button>button&nbsp;11</button>
<button>button&nbsp;12</button>
</div>
 
<div id="line_wrap2">
<span>line_wrap vcenter</span>
<button>button&nbsp;1</button>
<button>button&nbsp;2</button>
<button>button&nbsp;3</button>
<button>button&nbsp;4</button>
<button>button&nbsp;5</button>
<button>button&nbsp;6</button>
<button>button&nbsp;7</button>
<button>button&nbsp;8</button>
<button>button&nbsp;9</button>
<button>button&nbsp;10</button>
<button>button&nbsp;11</button>
<button>button&nbsp;12</button>
</div>
 
<div id="line_wrap3">
<span>line_wrap justify</span>
<button>button&nbsp;1</button>
<button>button&nbsp;2</button>
<button>button&nbsp;3</button>
<button>button&nbsp;4</button>
<button>button&nbsp;5</button>
<button>button&nbsp;6</button>
<button>button&nbsp;7</button>
<button>button&nbsp;8</button>
<button>button&nbsp;9</button>
<button>button&nbsp;10</button>
<button>button&nbsp;11</button>
<button>button&nbsp;12</button>
</div>
 
<div id="line_wrap4">
<span>line_wrap vcenter justify</span>
<button>button&nbsp;1</button>
<button>button&nbsp;2</button>
<button>button&nbsp;3</button>
<button>button&nbsp;4</button>
<button>button&nbsp;5</button>
<button>button&nbsp;6</button>
<button>button&nbsp;7</button>
<button>button&nbsp;8</button>
<button>button&nbsp;9</button>
<button>button&nbsp;10</button>
<button>button&nbsp;11</button>
<button>button&nbsp;12</button>
</div>
 
<div id="line_wrap5">
<span>line_wrap fill_line</span>
<button>button&nbsp;1</button>
<button>button&nbsp;2</button>
<button>button&nbsp;3</button>
<button>button&nbsp;4</button>
<button>button&nbsp;5</button>
<button>button&nbsp;6</button>
<button>button&nbsp;7</button>
<button>button&nbsp;8</button>
<button>button&nbsp;9</button>
<button>button&nbsp;10</button>
<button>button&nbsp;11</button>
<button>button&nbsp;12</button>
</div>
 
<div id="line_wrap6">
<span>line_wrap fill_line fixed_height</span>
<button>button&nbsp;1</button>
<button>button&nbsp;2</button>
<button>button&nbsp;3</button>
<button>button&nbsp;4</button>
<button>button&nbsp;5</button>
<button>button&nbsp;6</button>
<button>button&nbsp;7</button>
<button>button&nbsp;8</button>
<button>button&nbsp;9</button>
<button>button&nbsp;10</button>
<button>button&nbsp;11</button>
<button>button&nbsp;12</button>
</div>
 
</body>
</html>
 
Figure 1 - Scripted line wrapping layout
Figure 3 - Scripted line wrapping layout in narrow window.

posted @ 4/9/2010 4:00 PM by Darrel Karisch

More CSS Scripting Layout - Tables

 
CSS Scripting– Table Layout
 
 
CSS Script HTML Table Emulation
 
In Example 1 we present a CSS Scripting Layout policy that emulates a HTML table.  For comparison we display the emulation in green overlaying a HTML table in blue containing the same content. The Script table layout is able to achieve a better content distribution consuming less screen space as can be seen in Figure 1.
 
See the CSS Scripting Layout Model blog entry for a detailed description of layout model used in this example.
 
Example 1 – HTML Table
 
The HTML in Example 1 produces the screen shot in Figure 1.
 
Example 1 – Html Table Overlay
 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
 <title>HTML Table Overlay</title>
<style type="text/css">
 
@layout-policy HTMLTable {
initial-script: "\
function setNumColumns(nc,space) {\
if (arguments.length>1) spacing=space;\
if (numColumns!=nc) {\
numColumns=nc;\
columns = new Array(numColumns);\
for(var i=numColumns; --i>=0;) {\
var column = columns[i] = new Object;\
column.rects = rectangles(i,container.numChildren,numColumns);\
}\
numRows = Math.ceil(container.numChildren/numColumns);\
rows = new Array(numRows);\
for(var i=numRows; --i>=0;) {\
var row=rows[i] = new Object;\
row.rects = rectangles(i*numColumns,(i+1)*numColumns);\
}\
}\
}\
var rows = null;\
var columns = null;\
var numColumns=0;\
var numRows=0;\
var widthDeficit = false;\
var excessiveHeight = false;\
var defaultHeight,defaultWidth;\
var spacing=0;\
function deriveWidth() {\
var width = (numColumns+1)*spacing;\
widthDeficit = true;\
for(var i=numColumns; --i>=0;) {\
var rects = columns[i].rects;\
widthDeficit &= rects.preferred_width.max > rects.current_width.max;\
width += rects.preferred_width.max;\
}\
return width;\
}\
function deriveHeight() {\
var height= (numRows+1)*spacing;\
excessiveHeight = false;\
for(var i=numRows; --i>=0;) {\
var rects = rows[i].rects;\
excessiveHeight |= rects.max_height.max > rects.preferred_height.max;\
height+= rects.preferred_height.max;\
}\
if (excessiveHeight) excessiveHeight = rectangles.size_deficit.eq(true).length == 0;\
return height;\
}\
function deriveRows() {\
for(var i=0; i<numRows; ++i) {\
var row = rows[i];\
var rects = row.rects;\
row.height = rects.preferred_height.max;\
if (i==0) {\
row.top = spacing;\
row.bottom = row.height+spacing;\
} else {\
row.top = rows[i-1].bottom+spacing;\
row.bottom = row.top+row.height;\
}\
}\
}\
function deriveColumns() {\
if (!excessiveHeight) {\
var pie=0;\
var usable_width=(widthDeficit?defaultWidth:container.current_width)-(numColumns+1)*spacing;\
for(var i=numColumns; --i>=0;) {\
var column = columns[i];\
var rects = column.rects;\
var isPliant = column.pliant = column.pliant !== false && rects.pliant.eq(false).length == 0;\
if (!isPliant) {\
usable_width -= column.portion = rects.min_width.max;\
} else {\
pie += column.portion = rects.preferred_width.max;\
}\
}\
var ratio=usable_width/pie;\
for(var i=0; i<numColumns; ++i) {\
var column = columns[i];\
column.width = column.pliant ? column.portion*ratio : column.portion;\
column.left = i!=0?columns[i-1].left+columns[i-1].width+spacing:spacing;\
}\
}\
}\
";
rectangle-attributes: '{\
"column":"columns[rectangle.position%numColumns]",\
"row":"rows[Math.floor(rectangle.position/numColumns)]",\
"max_height":"rectangle.preferred_height>=rectangle.current_height?\
      rectangle.preferred_height:rectangle.current_height",\
"max_width":"rectangle.preferred_width>=rectangle.current_width?\
      rectangle.preferred_width:rectangle.current_width",\
"pliant":"rectangle.pliant!==false&&rectangle.preferred_width<=rectangle.current_width",\
"size_deficit":"rectangle.preferred_width>rectangle.current_width\
      ||rectangle.preferred_height>rectangle.current_height",\
"min_width":"rectangle.pliant?0:rectangle.preferred_width"\
}';
container-script: "\
if (numColumns<=0) setNumColumns(Math.ceil(Math.sqrt(container.numChildren)));\
if (sizing) {\
defaultWidth=deriveWidth();\
defaultHeight=deriveHeight();\
} else {\
deriveRows();\
deriveColumns();\
}\
";
top:"rectangle.row.top";
left:"rectangle.column.left";
height:"rectangle.row.height";
width:"rectangle.column.width";
container-width:"defaultWidth";
container-height:"defaultHeight";
}
 
 
#body {
    border:0px green dotted;
    padding:0px;
    margin:0px;
    position:relative;
layout-policy: "HTMLTable";
initial-script: "setNumColumns(4,2);";
container-width:100%;
}
.text {
    margin:0px;
    position:absolute;
    color:green;
    border:1px green solid;
    padding:0px;
}
span {
float:left;
    border:1px red solid;
}
/*
html table rules
display:none;
*/
.table {
    border:0px blue dotted;
    margin:0px;
    padding:0px;
}
.ttext {
    margin:0px;
    color:blue;
    border:1px blue solid;
    padding:0px;
    vertical-align:top;
}
 
 </style>
</head>
 
<body id='body'>
 
<table class='table' cellspacing='2'>
<tr class='ttext'>
 
<td class='ttext'>
CSSScript in green HTML in blue...
</td>
 
<td class='ttext'>
Fusce enim sem, ornare in ornare nec, ornare sed neque. Ut sed felis orci, in pretium lectus. Cras nec felis sed nibh venenatis dignissim in sit amet massa.
</td>
 
<td class='ttext'>
veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur?
</td>
 
<td class='ttext'>
Cras posuere metus at ligula posuere in consequat lorem malesuada.
</td>
 
</tr>
 
<tr class='ttext'>
 
<td class='ttext'>
Nulla facilisi. Aliquam ultrices consequat rutrum.
</td>
 
<td class='ttext'>
In hac habitasse platea dictumst.
</td>
 
<td class='ttext'> 
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.
</td>
 
<td class='ttext'>
Sed scelerisque fringilla ligula at laoreet. Cras posuere metus at ligula posuere in consequat lorem malesuada.
</td>
 
</tr>
 
<tr class='ttext'>
 
<td class='ttext'>
sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima
</td>
 
<td class='ttext'>
Fusce quis lacus ligula, a dictum metus.
</td>
 
<td class='ttext'>
vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?
</td>
 
<td class='ttext'>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum vestibulum fringilla interdum. Fusce suscipit vehicula nunc, nec sagittis risus mollis non. Cras non rhoncus magna. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nullam eleifend sapien velit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Quisque gravida erat vel eros iaculis ac rhoncus nibh tincidunt.
</td>
 
</tr>
 
<tr class='ttext'>
 
<td class='ttext'>
Cras sodales mollis arcu, quis sagittis tellus euismod eu. Nulla facilisi.
</td>
 
<td class='ttext'>
Aliquam ultrices consequat rutrum. Quisque pharetra adipiscing porta.
</td>
 
<td class='ttext'>
Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?
</td>
 
<td class='ttext'>
Nullam sem urna, fringilla tempus aliquet a, ornare non risus.
</td>
 
</tr>
 
<tr class='ttext'>
 
<td class='ttext'>
Nullam eleifend sapien velit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Quisque gravida erat vel eros iaculis ac rhoncus nibh tincidunt.
</td>
 
<td class='ttext'>
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.
</td>
 
<td class='ttext'>
Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Quisque gravida erat vel eros iaculis ac rhoncus nibh tincidunt.
</td>
 
<td class='ttext'>
Sed id lobortis nulla.
</td>
 
</tr>
</table>
 
 
<div class='text'>
CSSScript in green HTML in blue...
</div>
 
<div class='text'>
Fusce enim sem, ornare in ornare nec, ornare sed neque. Ut sed felis orci, in pretium lectus. Cras nec felis sed nibh venenatis dignissim in sit amet massa.
</div>
 
<div class='text'>
veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur?
</div>
 
<div class='text'>
Cras posuere metus at ligula posuere in consequat lorem malesuada.
</div>
 
<div class='text'>
Nulla facilisi. Aliquam ultrices consequat rutrum.
</div>
 
<div class='text'>
In hac habitasse platea dictumst.
</div>
 
<div class='text'>
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.
</div>
 
<div class='text'>
Sed scelerisque fringilla ligula at laoreet. Cras posuere metus at ligula posuere in consequat lorem malesuada.
</div>
 
<div class='text'>
sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima
</div>
 
<div class='text'>
Fusce quis lacus ligula, a dictum metus.
</div>
 
<div class='text'>
vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?
</div>
 
<div class='text'>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum vestibulum fringilla interdum. Fusce suscipit vehicula nunc, nec sagittis risus mollis non. Cras non rhoncus magna. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nullam eleifend sapien velit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Quisque gravida erat vel eros iaculis ac rhoncus nibh tincidunt.
</div>
 
<div class='text'>
Cras sodales mollis arcu, quis sagittis tellus euismod eu. Nulla facilisi.
</div>
 
<div class='text'>
Aliquam ultrices consequat rutrum. Quisque pharetra adipiscing porta.
</div>
 
<div class='text'>
Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?
</div>
 
<div class='text'>
Nullam sem urna, fringilla tempus aliquet a, ornare non risus.
</div>
 
<div class='text'>
Nullam eleifend sapien velit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Quisque gravida erat vel eros iaculis ac rhoncus nibh tincidunt.
</div>
 
<div class='text'>
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.
</div>
 
<div class='text'>
Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Quisque gravida erat vel eros iaculis ac rhoncus nibh tincidunt.
</div>
 
<div class='text'>
Sed id lobortis nulla.
</div>
 
</body>
</html>
 
Figure 1 – HTML Table emulation. The Script table in green overlays the HTML table in blue rendering a configuration that consumes less screen space.
 
This layout renders in less than 16 or up to 32 milliseconds on a Dell LATITUDE D630 Laptop (Intel Core 2 Duo T7500 2.20GHz, 2.49 GB RAM) running MS Windows XP V2002 Service Pack 3.

CSS Script Optimized Table – A Multiphase Layout

 
In Example 2 we present the same CSS Table Scripting Layout policy of Example 1 followed by an optimization step. The optimization step is achieved through a multiphase layout specification. Layout phases are delimited by colons in a rule’s layout-policy. Phases are executed sequentially in the order in which they appear. Each phase in a multiphase layout executes to completion as an independent layout, i.e. each phase converges to some solution. Subsequent phases begin with the final configuration of the prior phase. This allows the fine tuning of a configuration or any other kind of modification to achieve a desired result.
 
The Optimization phase defined in the Optimize layout-policy in Example 2 applies a heuristic measure to reduce the total whitespace in the table.
 
For comparison we display the optimized script table in green overlaying a HTML table in blue containing the same content as in Example 1. The Scripting table layout finds better content distributions resulting in a reduced total area as exhibited in Figure 2.
 
Other table optimizations that are more mathematically rigorous could be applied such as an adaptation of the Simple Continuous Table Layout or a hybrid.
 
Example 2 – Optimized Table Layout
 
The layout-policy defined in Example 2 extends Example 1 and produces the screen shot in Figure 2. The screen width of Figures 1 and 2 is identical.
 
Example 2 – Optimized Table
 
 
@layout-policy Optimize {
initial-script: "\
function deriveColumns() {\
if (!excessiveHeight) {\
var pie=0;\
var usable_width=(widthDeficit?defaultWidth:container.current_width)-(numColumns+1)*spacing;\
var wratio=container.width/(container.height+container.width);\
var hratio=container.height/(container.height+container.width);\
for(var i=numColumns; --i>=0;) {\
var column = columns[i];\
var rects = column.rects;\
var isPliant = column.pliant = rects.pliant.eq(false).length == 0;\
if (isPliant) {\
var colWaste = rects.waste;\
var rowWaste = rects.rowWaste;\
var rowWasteValue = hratio*(rowWaste.avg+(-1)*((0.5)*rowWaste.stddev\
+((-0.3)*(rowWaste.max+rowWaste.min))));\
var colWasteValue= wratio*(colWaste.avg+(-1)*((0.5)*colWaste.stddev\
+((-0.15)*(colWaste.max+colWaste.min))));\
var wasteArea = rowWasteValue-colWasteValue;\
pie += column.portion = rects.preferred_width.max\
+(wasteArea<0?-Math.sqrt(-wasteArea):Math.sqrt(wasteArea));\
} else {\
usable_width -= column.portion = rects.min_width.max;\
}\
}\
pie=usable_width/pie;\
for(var i=0; i<numColumns; ++i) {\
var column = columns[i];\
if (column.pliant) column.width = column.portion*pie;\
column.left = i!=0?columns[i-1].left+columns[i-1].width+spacing:spacing;\
}\
}\
}\
";
rectangle-attributes: '{\
"current_area":"rectangle.current_width*rectangle.current_height",\
"preferred_area":"rectangle.preferred_width*rectangle.preferred_height",\
"waste":"rectangle.current_area-rectangle.preferred_area-rectangle.requiredSpace",\
"requiredSpace":"(rectangle.current_width-rectangle.preferred_width)\
      *(rectangle.current_height-rectangle.preferred_height)",\
"rowRectsWaste":"rectangle.row.rects.remove(rectangle).waste",\
"rowWaste":"rectangle.rowRectsWaste.sum+(numColumns-1)*rectangle.rowRectsWaste.min",\
"pliant":"rectangle.preferred_width<=rectangle.current_width"\
}';
}
 
#body {
layout-policy: "HTMLTable:Optimize";
initial-script: "\
setNumColumns(4,2);\
";
container-width:100%;
    border:0px green dotted;
    padding:0px;
    margin:0px;
    position:relative;
}
 
 
 
 
Figure 2 – The optimized script table in green from Example 2 uses a multiphase layout that applies an optimization that reduces whitespace in the table. The result is a tighter configuration than otherwise possible by a HTML table shown in blue.
 
Depending on the window size, this layout renders somewhere between 15 and 50 milliseconds on a Dell LATITUDE D630 Laptop (Intel Core 2 Duo T7500 2.20GHz, 2.49 GB RAM) running MS Windows XP V2002 Service Pack 3.
 
An Optimized Cell Spanning Table
 
In Example 3 we present a CSS Table Scripting Layout policy that builds on the ideas presented in Examples 1 and 2 further extending capabilities by allowing cells to span multiple rows and columns. Cell spanning is achieved through rectangle-attributes colSpan and rowSpan. These values default to one in the SpanningTable layout-policy. Other classes define rectangle-attributes with colSpan and rowSpan values greater than one.
 
For comparison we display the Script table in green overlaying a HTML table in blue containing the same content and employing the same spans. As in the prior examples the Scripting table layout finds better content distributions resulting in a reduced total area as exhibited in Figure 3.
 
Example 3 – Cell Spanning Table Layout
 
The layout-policy defined in Example 3 produces the screen shot in Figure 3.
 
Example 3 – Cell Spanning Table
 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
 <title>Cell Spanning Table Overlaying Equivalent HTML</title>
<style type="text/css">
 
@layout-policy SpanningTable {
initial-script: "\
function fillCell(cell,rect) {\
var undefined;\
var rs=rect.rowSpan;\
var cs=rect.colSpan;\
var row=cell[0];\
var col=cell[1];\
var pos=rect.position;\
while(rs--) {\
var r = rows[row++];\
var x=cs;\
while(x--) r[col+x]=pos;\
}\
col+=cs;\
r = rows[cell[0]];\
if (pos+1!=rectangles.length)\
if (col >= numColumns || r[col]!==undefined) do {\
if (col >= numColumns) {\
r = rows[cell[0]=cell[0]+1];\
col=0;\
}\
while(col<numColumns && r[col]!==undefined) ++col;\
} while(col >= numColumns);\
cell[1]=col;\
}\
function setNumColumns(nc,space) {\
if (arguments.length>1) spacing=space;\
if (numColumns!=nc) {\
numColumns=nc;\
numRows = Math.ceil(rectangles.cellCount.sum/numColumns);\
rows = new Array(numRows);\
for(var i=0;i<numRows;++i) rows[i] = new Array(numColumns);\
var cell = new Array(0,0);\
for(var x=0;x<rectangles.length;++x) fillCell(cell,rectangles[x]);\
for(var i=0;i<numRows;++i) {\
var r=rows[i];\
var row=rows[i] = new Object;\
row.cells=rectangles(r);\
var len=r.length;\
for(var j=len-1;--j>=0;) {\
var k=j+1;\
if (r[j]==r[k]) while(--j>=0 && r[j]==r[k]); r.splice(j+1,k-j-1);\
}\
row.rects=len==r.length?row.cells:rectangles(r);\
}\
columns = new Array(numColumns);\
for(var i=0;i<numColumns;++i) {\
var column = columns[i] = new Object;\
var cells=rows[0].cells(i,i+1);\
var colRects=cells;\
for(var j=1;j<numRows;++j) {\
var r=rows[j].cells[i];\
if (r != colRects[colRects.length-1]) colRects=colRects.append(r);\
cells=cells.append(r);\
}\
column.cells=cells;\
column.rects=colRects;\
}\
for(var i=numRows;--i>=0;) rows[i].bottomRects=rectangles.bottomRow.eq(i);\
for(var i=numColumns;--i>=0;) columns[i].leftRects=rectangles.leftCol.eq(i);\
deriveRows();\
deriveColumns();\
}\
}\
var rows = null;\
var columns = null;\
var numColumns=0;\
var numRows=0;\
var widthDeficit = false;\
var excessiveHeight = false;\
var defaultHeight,defaultWidth;\
var spacing=0;\
function deriveWidth() {\
widthDeficit = true;\
for(var i=numColumns; --i>=0;) {\
var rects = columns[i].leftRects;\
widthDeficit &= rects.preferred_width.max > rects.current_width.max;\
}\
return spacing + columns[numColumns-1].cells.preferred_right.max;\
}\
function deriveHeight() {\
excessiveHeight = false;\
for(var i=numRows; --i>=0;) {\
var rects = rows[i].bottomRects;\
excessiveHeight |= rects.current_bottom.max > rects.preferred_bottom.max;\
}\
if (excessiveHeight) excessiveHeight = rectangles.size_deficit.eq(true).length == 0;\
return spacing + rows[numRows-1].cells.preferred_bottom.max;\
}\
function deriveRows() {\
for(var i=0; i<numRows; ++i) {\
var row = rows[i];\
if (i==0) {\
row.top = spacing;\
} else {\
row.top = rows[i-1].bottom+spacing;\
}\
row.bottom = row.bottomRects.preferred_bottom.max;\
row.height = row.bottom-row.top;\
}\
}\
function deriveColumns() {\
if (!excessiveHeight) {\
var pie=0;\
var usable_width=(widthDeficit?defaultWidth:container.current_width)-(numColumns+1)*spacing;\
for(var i=numColumns; --i>=0;) {\
var column = columns[i];\
var rects = column.rects;\
var isPliant = column.pliant = rects.pliant.eq(false).length == 0;\
if (!isPliant) {\
usable_width -= column.portion = rects.min_width(i).max;\
} else {\
pie += column.portion = rects.portion(i).max;\
}\
}\
var ratio=usable_width/pie;\
for(var i=0; i<numColumns; ++i) {\
var column = columns[i];\
if (i==0) {\
column.left = spacing;\
column.width = column.right = spacing + (column.pliant ? column.portion*ratio : column.portion);\
} else {\
column.left = columns[i-1].right+spacing;\
column.width = column.pliant ? column.portion*ratio : column.portion;\
column.right= column.left + column.width;\
}\
}\
}\
}\
function column(rect) {\
for (var i=0;i<columns.length;++i)\
if (columns[i].rects.contains(rect)) return i;\
}\
function row(rect) {\
for (var i=0;i<rows.length;++i)\
if (rows[i].rects.contains(rect)) return i;\
}\
function spansCol(currentCol){return this.colSpan+this.column-currentCol;}\
function portion(currentCol){\
var nc=this.colSpan-1;\
return nc>0\
?this.preferred_width*(columns[currentCol].width+(nc*spacing)/(nc+1))/this.cellWidth\
:this.preferred_width;\
}\
function min_width(currentCol){\
var mw=0;\
if (!this.pliant) {\
var nc=this.colSpan-1;\
var ratio=nc>0?(columns[currentCol].width+(nc*spacing)/(nc+1))/this.cellWidth:1;\
mw=this.preferred_width*ratio;\
}\
return mw;\
}\
function cellWidth(rect) {\
var c=rect.column;\
var nc=c+rect.colSpan-1;\
return columns[nc].right-columns[c].left;\
}\
";
rectangle-attributes: '{\
"column":"column(rectangle)",\
"row":"row(rectangle)",\
"leftCol":"rectangle.column+rectangle.colSpan-1",\
"bottomRow":"var br=rectangle.row+rectangle.rowSpan-1; br>=numRows?numRows-1:br",\
"portion":"portion",\
"cellWidth":"cellWidth(rectangle)",\
"cellBottom":"rows[rectangle.bottomRow].bottom",\
"spansCol":"spansCol",\
"cellCount":"rectangle.colSpan*rectangle.rowSpan",\
"colSpan":"1",\
"rowSpan":"1",\
"max_height":"rectangle.preferred_height>=rectangle.current_height?\
      rectangle.preferred_height:rectangle.current_height",\
"max_width":"rectangle.preferred_width>=rectangle.current_width?\
      rectangle.preferred_width:rectangle.current_width",\
"pliant":"rectangle.pliant!==false&&rectangle.preferred_width<=rectangle.current_width",\
"size_deficit":"rectangle.preferred_width>rectangle.current_width\
      ||rectangle.preferred_height>rectangle.current_height",\
"min_width":"min_width",\
"current_bottom":"rows[rectangle.row].top+rectangle.current_height",\
"preferred_bottom":"rows[rectangle.row].top+rectangle.preferred_height",\
"preferred_right":"columns[rectangle.column].left+rectangle.preferred_width"\
}';
container-script: "\
if (numColumns<=0) setNumColumns(Math.ceil(Math.sqrt(container.numChildren)));\
if (sizing) {\
defaultWidth=deriveWidth();\
defaultHeight=deriveHeight();\
} else {\
deriveRows();\
deriveColumns();\
}\
";
top:"rows[rectangle.row].top";
bottom:"rectangle.cellBottom";
left:"columns[rectangle.column].left";
right:"columns[rectangle.column+rectangle.colSpan-1].right";
container-width:"defaultWidth";
container-height:"defaultHeight";
}
 
@layout-policy Optimize {
initial-script: "\
function deriveColumns() {\
if (!excessiveHeight) {\
var pie=0;\
var usable_width=(widthDeficit?defaultWidth:container.current_width)-(numColumns+1)*spacing;\
var wratio=container.width/(container.height+container.width);\
var hratio=container.height/(container.height+container.width);\
for(var i=numColumns; --i>=0;) {\
var column = columns[i];\
var rects = column.rects;\
var isPliant = column.pliant = rects.pliant.eq(false).length == 0;\
if (isPliant) {\
var colWaste = rects.columnSpace(i);\
var rowWaste = rects.columnRowSpace(i);\
var rowWasteValue = hratio*((1.0)*rowWaste.avg+(-1)*((0.5)*rowWaste.stddev\
+((-0.3)*(rowWaste.max+rowWaste.min))));\
var colWasteValue= wratio*((1.0)*colWaste.avg+(-1)*((0.5)*colWaste.stddev\
+((-0.15)*(colWaste.max+colWaste.min))));\
var wasteArea = rowWasteValue-colWasteValue;\
var wasteArea = -colWasteValue;\
pie += column.portion = rects.portion(i).max\
+(wasteArea<0?-Math.sqrt(-wasteArea):Math.sqrt(wasteArea));\
} else {\
usable_width -= column.portion = rects.min_width(i).max;\
}\
}\
var ratio=usable_width/pie;\
for(var i=0; i<numColumns; ++i) {\
var column = columns[i];\
if (i==0) {\
column.left = spacing;\
column.width = column.right = spacing + (column.pliant ? column.portion*ratio : column.portion);\
} else {\
column.left = columns[i-1].right+spacing;\
column.width = column.pliant ? column.portion*ratio : column.portion;\
column.right= column.left + column.width;\
}\
}\
}\
}\
function columnSpace(currentCol){\
var nc=this.colSpan-1;\
var ws=this.whiteSpace;\
return nc>0\
?ws*(columns[currentCol].width+(nc*spacing)/(nc+1))/this.cellWidth\
:ws;\
}\
function cellHeight(rect) {\
var r=rect.row;\
var nr=r+rect.rowSpan-1;\
return rows[nr].bottom-rows[r].top;\
}\
function rowSpace(currentRow){\
var nr=this.rowSpan-1;\
var ws=this.whiteSpace;\
return nr>0\
?ws*(rows[currentRow].height+(nr*spacing)/(nr+1))/this.cellHeight\
:ws;\
}\
function columnRowSpace(currentCol){\
var nc=this.colSpan-1;\
var colPortion=nc>0?(this.cellWidth-columns[currentCol].width+(nc*spacing)/(nc+1))/this.cellWidth:0;\
var wasteValue= colPortion*this.whiteSpace;\
var ri=this.row;\
var nr=this.rowSpan;\
while (--nr>=0) {\
var rowRects=rows[ri+nr].rects.remove(this);\
var space=rowRects.rowSpace(ri+nr);\
if (colPortion>0) {\
var rowPortion=colPortion*this.rowSpace(ri+nr);\
wasteValue += space.sum+(numColumns-1)*(space.min<rowPortion?space.min:rowPortion);\
} else {\
wasteValue += space.sum+(numColumns-1)*space.min;\
}\
}\
return wasteValue;\
}\
";
rectangle-attributes: '{\
"cellHeight":"cellHeight(rectangle)",\
"whiteSpace":"rectangle.current_area-rectangle.preferred_area-\
      rectangle.requiredSpace",\
"current_area":"rectangle.current_width*rectangle.current_height",\
"preferred_area":"rectangle.preferred_width*rectangle.preferred_height",\
"columnSpace":"columnSpace",\
"columnRowSpace":"columnRowSpace",\
"rowSpace":"rowSpace",\
"requiredSpace":"(rectangle.current_width-rectangle.preferred_width)\
      *(rectangle.current_height-rectangle.preferred_height)",\
"rightWaste":"(rectangle.current_width-rectangle.preferred_width)\
      *rectangle.current_height",\
"pliant":"rectangle.preferred_width<=rectangle.current_width"\
}';
}
 
#body {
    border:0px green dotted;
    padding:0px;
    margin:0px;
    position:relative;
layout-policy: "SpanningTable:Optimize";
initial-script: "setNumColumns(4,2);";
container-width:100%;
}
.text {
    margin:0px;
    position:absolute;
    color:green;
    border:1px green solid;
    padding:0px;
}
.bigger {
rectangle-attributes: '{\
"rowSpan":"2",\
"colSpan":"2",\
}';
}
.taller {
rectangle-attributes: '{\
"rowSpan":"2",\
}';
}
.wider {
rectangle-attributes: '{\
"colSpan":"2",\
}';
}
.widest {
rectangle-attributes: '{\
"colSpan":"3",\
}';
}
/*
html table rules
*/
.table {
    border:0px blue dotted;
    margin:0px;
    padding:0px;
}
.ttext {
    margin:0px;
    color:blue;
    border:1px blue solid;
    padding:0px;
    vertical-align:top;
}
 
 </style>
</head>
 
 
<body id="body">
 
<table class="table" cellspacing="2">
<tr class="ttext">
 
<td class="ttext">
CSSScript in green HTML in blue...
</td>
 
<td class="ttext">
Fusce enim sem, ornare in ornare nec, ornare sed neque. Ut sed felis orci, in pretium lectus. Cras nec felis sed nibh venenatis dignissim in sit amet massa.
</td>
 
<td class="ttext" rowSpan="2">
veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur?
In hac habitasse platea dictumst.
veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur?
In hac habitasse platea dictumst.
veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur?
In hac habitasse platea dictumst.
</td>
 
<td class="ttext">
Cras posuere metus at ligula posuere in consequat lorem malesuada.
</td>
 
</tr>
 
<tr class="ttext">
 
<td class="ttext" colSpan="2">
Nulla facilisi. Aliquam ultrices consequat rutrum.
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.
</td>
 
<td class="ttext" rowSpan="2">
Sed scelerisque fringilla ligula at laoreet. Cras posuere metus at ligula posuere in consequat lorem malesuada.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum vestibulum fringilla interdum. Fusce suscipit vehicula nunc, nec sagittis risus mollis non. Cras non rhoncus magna. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nullam eleifend sapien velit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Quisque gravida erat vel eros iaculis ac rhoncus nibh tincidunt.
</td>
 
</tr>
 
<tr class="ttext">
 
<td class="ttext" colspan="3">
sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima
Fusce quis lacus ligula, a dictum metus.
vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?
</td>
 
</tr>
 
<tr class="ttext">
 
<td class="ttext">
Cras sodales mollis arcu, quis sagittis tellus euismod eu. Nulla facilisi.
</td>
 
<td class="ttext">
Aliquam ultrices consequat rutrum. Quisque pharetra adipiscing porta.
</td>
 
<td class="ttext" colSpan="2" rowSpan="2">
Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?
Nullam sem urna, fringilla tempus aliquet a, ornare non risus.
Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Quisque gravida erat vel eros iaculis ac rhoncus nibh tincidunt.
Sed id lobortis nulla.
</td>
 
</tr>
 
<tr class="ttext">
 
<td class="ttext">
Nullam eleifend sapien velit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Quisque gravida erat vel eros iaculis ac rhoncus nibh tincidunt.
</td>
 
<td class="ttext">
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.
</td>
 
</tr>
</table>
 
 
<div class="text">
CSSScript in green HTML in blue...
</div>
 
<div class="text">
Fusce enim sem, ornare in ornare nec, ornare sed neque. Ut sed felis orci, in pretium lectus. Cras nec felis sed nibh venenatis dignissim in sit amet massa.
</div>
 
<div class="text taller">
veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur?
In hac habitasse platea dictumst.
veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur?
In hac habitasse platea dictumst.
veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur?
In hac habitasse platea dictumst.
</div>
 
<div class="text">
Cras posuere metus at ligula posuere in consequat lorem malesuada.
</div>
 
<div class="text wider">
Nulla facilisi. Aliquam ultrices consequat rutrum.
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.
</div>
 
<div class="text taller">
Sed scelerisque fringilla ligula at laoreet. Cras posuere metus at ligula posuere in consequat lorem malesuada.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum vestibulum fringilla interdum. Fusce suscipit vehicula nunc, nec sagittis risus mollis non. Cras non rhoncus magna. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nullam eleifend sapien velit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Quisque gravida erat vel eros iaculis ac rhoncus nibh tincidunt.
</div>
 
<div class="text widest">
sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima
Fusce quis lacus ligula, a dictum metus.
vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?
</div>
 
<div class="text">
Cras sodales mollis arcu, quis sagittis tellus euismod eu. Nulla facilisi.
</div>
 
<div class="text">
Aliquam ultrices consequat rutrum. Quisque pharetra adipiscing porta.
</div>
 
<div class="text bigger">
Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?
Nullam sem urna, fringilla tempus aliquet a, ornare non risus.
Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Quisque gravida erat vel eros iaculis ac rhoncus nibh tincidunt.
Sed id lobortis nulla.
</div>
 
<div class="text">
Nullam eleifend sapien velit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Quisque gravida erat vel eros iaculis ac rhoncus nibh tincidunt.
</div>
 
<div class="text">
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.
</div>
 
</body>
</html>
 
  
 
Figure 3– Optimized Cell Spanning Table. The layout in Example 3 extends the ideas and techniques applied in Examples 1 and 2.  The Script table in green achieves better results than an equivalent HTML table.
Depending on the window size and V8 JavaScript garbage collection events, this layout renders somewhere between 50 and 250 milliseconds and most often under 100 milliseconds on a Dell LATITUDE D630 Laptop (Intel Core 2 Duo T7500 2.20GHz, 2.49 GB RAM) running MS Windows XP V2002 Service Pack 3.
 

posted @ 3/15/2010 10:54 AM by Darrel Karisch

Mobile Apps @ eFORCE Labs

At eFORCE Labs we explored mobile solutions for promotional marketing by devloping mobile apps on both web and native apps for Android, iphone and Blackberry. I have listed below some specific issues that we faced while developing these apps.

 

Native apps

- features like running applications in background are not available in all devices
As you all aware iphone does not allow running apps in the background which limits us to our apps in the background and receive notifications but in case of Android and Blackberry this is not an issue.


 
- local database such as SQLite is not supported in old devices
In case of using local database in our apps most of the platform supports SQLite but not in some of the old devices, for example Blackberry supports SQLite only above 9000 series instead they provide persistent store which made us to write separate data access layer in our apps.

 

- app approval process is slow and restrictions on usage of location API
In case of native apps most of the platforms has their own approval process and our apps has to abide their policies in order to be approved. There are some restrictions on using location API in some platforms like iphone.

 

Web apps

- regular web apps with appropriate form factor using HTML are not device/user friendly
We were able to design the regular html pages to display properly with respect to mobile form factor but there is not much option to make use of features like toolbar, touch screen controls etc.

 

- HTML5/CSS/JavaScript apps are device/user friendly but not supported by all browsers
We tried some mobile web development plugin's like jQTouch to design web applications with native animations, navigations and the output was similar to native app but not all mobile browsers supports HTML5. The default browser on blackberry does not support HTML5 and the pages were not rendered as intended.


If the app does not require core native API then web app is the best option because of easier distribution, faster release cycle, higher leverage on improving the base platform, decreased barrier to entry, etc.

 

Some reference to blogs related to this subject
The decline of the mobile software industry
Native Mobile Apps vs Mobile Web Apps

posted @ 2/22/2010 9:03 PM by Kamal Raj Ramalingam

First Step Towards Social Media Marketing !!

Social Media Marketing is a new advertising methodology where you promote your business through different online social media channels. It’s not just limited to regular one way advertising technique but it also gives a chance to interact directly with your end user. It provides a flexibility to twist your marketing strategy as and when needed.
 
To understand the impact it is going to make, let’s look at few studies:
 
·         According to a 2009 CMO Survey, currently 3.5% of marketing budgets is spent on social media marketing, with that figure predicted to grow to 6.1% within 12 months and 13.7% within five years.
·         According to the 2009 Digital Readiness Report, "Essential Online Public Relations and Marketing Skills," a majority of organizations are now contemplating hiring social media specialists.
·         In a 2007 study by eMarketer, commissioned by MySpace, it was predicted there would be a $1230 million spend on social network marketing.
·         In a 2008 study by Forrester Research evaluating the social network marketing programs, only one of the 16 major firms it had reviewed had received a passing grade, with half of the programs scoring a zero or lower.
Social Media has become a golden marketing rush for many marketers across world. Real users talking about real products is an added advantage, though, tracking all the information floating in social media becomes little tough at times. When we tried to analyze real time data from Social Media we found many interesting outcomes. We can see many interesting trends – even popularity of brands, products can be measured over time. When we go little deep in user statistics we can find out the most talked about products, brands for a particular region and vice-versa. There are many such interesting patterns.
 

We believe that before marketing a product / brand through social media, a marketer must analyze data floating on different social media platforms. Keeping this thought in mind we developed ContextMine. It is collecting data from 100+ social media websites. It also analyzes data on different parameters like, message, user, location, etc. To know more about this, please visit - http://www.context.com/contextmine/index.html

posted @ 1/6/2010 2:07 AM by Nitesh Ambuj

What are users twittering on twitter?

Or what types of conversations are happening on twitter? We decided to run some statistics to find the answer. Basically, we divided twitter messages into three different categories: (i) Messages that are posted in response to other messages, (ii) Messages that are forwards or re-tweets of other tweets, and (iii) Messages that contains URLs, which could be pass along links or news story or link to blogs or of commercial purpose like deals/coupons/etc.   We were thinking of having more categories – especially categorizing links into different buckets: news, promotion, etc but then decided against it. On social media platform like Twitter, there is a thin (and subjective) line between personal and professional content & usage. Is tweet with link to my blog, a news item for my friends or self marketing?

We collected data for a period of one month (Oct 09) on range of different companies, brands and topics. All in all, there were over 1 million tweets that were classified into 3 different buckets. Here are results:

  • 15.8% of tweets were part of conversation, replies in response to other tweets.
  • 5.9% of tweets were forwards or re-tweets of other tweets
  • 40.7% of tweets contained at least one URL.

I must say, % of tweets with URL(s) is staggering high. It also differs vastly from this study by Pear Analytics that gained wide attention few months ago. Couple of differences that I would like to point out between Pear Analytics study and our study: (1) While Pear Analytics study examined roughly 2000 tweets, our study examined over 1 mil tweets, and (2) I think the main difference between the two studies is that the Pear Analytics study examined random tweets whereas we targeted specific content (for example, content related to Best Buy, Wal Mart, or Healthcare reform, Halloween etc),  which in turn could have helped filter out lot of “pointless babbel” that Pear Analytics study mentions.


Why is this important? Most of the content with links is references to news items that users think their friends/followers find useful, self promotion, or commercial like deals, coupons, etc.  When Twitter started out, it was based on a simple idea: know what your friends are doing. However, as the service grew, its users have also found other uses of the service besides posting “I’m having big burrito guilty feeling”.  

Percentage of tweets with links for the month of November so far? 42.6%, while other numbers (for re-tweets and conversations) are roughly same as that of Oct 09 figures.



For more information on our ContextMine product and how it can help, visit our product site at http://www.context.com/contextmine. If you are interested in trial version, send us an email at: dshah at context.com

posted @ 11/23/2009 7:19 PM by Devang Shah

Contd.. Who is influencing conversation about your brand on social media sites?

In my previous post here, I had highlighted stats for Youtube and Twitter. Recently, I got asked about stats for few more social media sites. So here it is:

Note: As I had mentioned before, data were collected for a period of month (oct-09) for various brands across different verticals.


FriendFeed:
  • Average number of messages per user: 7.21
  • Average number of messages by top 0.1% of users: 2163
  • Average number of messages by next 1% of users: 152
  • Average number of messages by next 10% of users: 19
  • % users who had posted exactly 1 message during that time frame: 52%
  • % of users had 5 messages or less during that time frame: 85%

Digg:
  • Average number of messages per user: 1.85
  • Average number of messages by next 1% of users: 22
  • Average number of messages by next 10% of users: 5
  • % users who had posted exactly 1 message during that time frame: 75%
  • % of users had 5 messages or less during that time frame: 95%

I will try to provide stats for few more sites like Metacafe, DailyMotion, Reddit, etc in another post.

One quick note: FriedFeed lags behind Twitter (by a wide margin) in terms of total no of unique users but it does have pretty high user participation ratio.



For more information on our ContextMine product and how it can help, visit our product site at http://www.context.com/contextmine. If you are interested in trial version, send us an email at: dshah at context.com

posted @ 11/17/2009 3:44 PM by Devang Shah

Who is influencing conversation about your brand on social media sites?

Social media sites are proving to be useful channels for advertisers and sales people to connect to their targeted audience. You can not only listen to their conversation but also take an action by guiding conversation, providing correct information, promoting your brands, and more. But how do you know which audience to connect with? How do you know which users are having greater impact than the others? How often people are talking about your brand on social media sites?

Below are results from some of our reports. Data mined were collected for several brands/companies (across different verticals like auto, appliances, etc) over a period of one month from some of the popular social media sites like Twitter, Youtube, FriendFeed, Digg, etc.  

Note: It only takes into consideration user messages pertaining to brands/companies for which we generated stats.

Twitter:
  • Average number of messages per user: 1.83
  • Average number of messages by top 0.1% of users: 167
  • Average number of messages by next 1% of users: 22
  • Average number of messages by next 10% of users: 4
  • Over 75% users had posted exactly 1 message during that time frame.
  • Over 95% of users had 5 messages or less during that time frame.

YouTube:
  • Average number of messages per user: 3.23
  • Average number of messages by top 0.1% of users: 483
  • Average number of messages by next 1% of users: 91
  • Average number of messages by next 10% of users: 9
  • Over 74% users had posted exactly 1 message during that time frame.
  • Over 93% of users had 5 messages or less during that time frame.


On social media sites, there are users who are participating and there are users who are talking about your brand, driving & influencing conversation, and are passionate – do you know who they are?


For more information on our ContextMine product and how it can help, visit our product site at http://www.context.com/contextmine. If you are interested in trial version, send us an email at: dshah at context.com

posted @ 10/30/2009 5:47 PM by Devang Shah

Are you in control?

In today’s social media driven web world, more and more users are using web to not only find and search information but are also becoming its active participants and adding content via different channels like forums, blogs, audio/video, ratings, reviews and feedback, and micro-blogs. And so, increasingly customers and prospective clients are turning to web to find relevant information about your company, reviews &feedback and in general read what others have to about your products and services.  While these channels can provide an opportunity to gauge interest of consumers about your brands and products, negative message and opinion on these channels can also hurt your company’s reputation.


Do you still wonder usefulness of some of these channels and whether your brand’s online reputation has an impact on the company’s bottom line?  Consider some of these findings:
  • As holiday season is approaching, shoppers are busy researching and scouting prior to purchase.  Recent study by OTX/Google states that internet is ranked as the most useful source of information with 79% of consumers finding it very or extremely helpful. 
  • You may not be selling your products online, but check out this finding from Comscore research study: Online consumer generated reviews have significant impact on offline purchase behavior as well. With consumer willing to pay at least 20 percent more for services receiving an “Excellent”, or – 5 star, rating than for the same service receiving a “Good”, or 4 star rating.
  • Social media web sites have become one of the most frequented sites per web statistics. Recently released DEI Study states that the consumers who visit social media sites are more likely to take action and ‘directly engaging with consumers online using brand representatives will motivate purchase Intent and increase pass-along’.

There is a conversation happening about your brand on social media sites. Question is who is shaping that conversation? Are you in control of your company’s online message?

For more information on our ContextMine product and how it can help, visit our product site at http://www.context.com/contextmine. if you are interested in trial version, send us an email at: dshah at context.com




posted @ 10/29/2009 12:34 PM by Devang Shah

CSS Scripting Layout Specification

 
CSS Scripting Layout Model
Table of Contents
Abstract   top
This document describes a new set of CSS properties and object specifications that together compose a more powerful means to describe complex arbitrary layout criteria that are reusable and extensible. The new properties are ECMAScript (JavaScript) expressions that are encapsulated in a construct as a layout policy. A layout policy is referenced in CSS rules. The expressions composing a layout policy are woven together virtually in a constraint resolving system to perform a specified layout. New object specifications and a set of global objects defined in the constraint resolution script runtime environment enable powerful operations to be expressed succinctly resulting in more readable and compact layout specifications.
Introduction   top
Many in the web development community are dissatisfied with the layout capabilities in the current CSS standard and often resort to various client-side JavaScript solutions to fulfill their layout needs. There are several proposals before the W3C CSS Working group that aim to broaden CSS layout capabilities and reduce or eliminate the need for client-side JavaScript. These proposals employ well-defined strategies each with their own set of specific properties. If adopted, these proposals will increase substantially the size and complexity of CSS implementations as well as CSS syntax.

We propose a more general-purpose CSS layout solution that brings scripting unobtrusively into CSS. This solution enables a wide number of layout strategies to be defined in terms suitable to each. This general-purpose solution avoids the complexities that a multitude of independent solutions saddles on CSS implementers and developers.

CSS Scripting Layout Properties   top
A Scripting layout is encapsulated in a CSS layout-policy @-rule. A layout-policy @-rule defines a name that is referenced in layout-policy properties within rules. The body of a layout-policy @-rule is composed of properties with String values that are JavaScript expressions.
@layout-policy name
{
	initial-script:”arbitrary JavaScript”
	container-script:”arbitrary JavaScript”
	container-width:”…”
	container-height:”…”
	rectangle-attributes:”JavaScript Associative Array”
	left:”arbitrary JavaScript”
	horizontal-center:”…”
	right:”…”
	width:”…”
	top:”…”
	vertical-center:”…”
	bottom:”…”
	height:”…”
}

initial-script is arbitrary JavaScript that is executed to define values, functions, or any other JavaScript object that may then be referenced in the expressions of other constraint properties. It is executed only once per layout request.

container-script is arbitrary JavaScript that is executed to define values, functions, or any other JavaScript object that may then be referenced in the expressions of other constraint properties. It may be executed multiple times per layout request depending on the number of cycles required to resolve the constraints.

container-width and container-height properties are JavaScript expressions that must compute to a JavaScript Number, the value of which determines the width or height of the container. These properties may also be ordinary length or percentage values.

rectangle-attributes defines a JavaScript associative array. This associative array defines a set of name-value pairs whereby the name defines a new arbitrary attribute applicable to each child element of the container. The attribute value is a JavaScript expression.

The other constraint properties are JavaScript expressions and apply to each of the child elements of a container. These properties must compute to a JavaScript Number, the value of which determines the corresponding aspect of the child element. These properties may also be ordinary length or percentage values.

Constraint and rectangle attribute JavaScript expressions are evaluated lazily, at most once per distinct reference per layout resolution execution cycle. Each subsequent reference uses the result of the first evaluation. A reference is distinct on each child element on which the expression applies.

layout-policy @-rules are referenced by name in CSS rules.

A layout-policy property is set in a rule that is applied to a container html element in which case the layout policy constraints are applied to the container and its immediate child elements.

.container
{
	layout-policy:”policy1 policy2”
	initial-script:”arbitrary JavaScript”
	container-script:”arbitrary JavaScript”
	container-width:”…”
	container-height:”…”
}

layout-policy values may reference more than one policy. In this case subsequent policies override and augment values from preceding policies.

Other properties may be included in a rule to override or augment corresponding layout-policy @-rule values.

Child elements may override or augment the constraint values of a layout policy.

.child
{
	rectangle-attributes:”JavaScript Associative Array”
	left:”arbitrary JavaScript”
	…
}

A rectangle-attributes specification in a successive policy reference or on a rule overrides and augments the value in the initial policy. In other words, the rectangle-attributes value used in the computation is the amalgam of all the rectangle-attributes specified.

An overriding constraint with a value of none rescinds any prior constraint value rendering it unconstrained.

CSS Layout Objects and Interfaces   top
The expressions of the new CSS properties may reference new global objects defined in the CSS Layout JavaScript runtime environment.

A container object supports the CSSContainer interface that extends the Rectangle interface. A container object represents the container on which a layout policy is defined.

Rectangle
{
	readonly attribute double left;
	readonly attribute double right;
	readonly attribute double horizontal_center;
	readonly attribute double top;
	readonly attribute double bottom;
	readonly attribute double vertical_center;
	readonly attribute double width;
	readonly attribute double height;
	readonly attribute double preferred_width;
	readonly attribute double preferred_height;
	readonly attribute double current_width;
	readonly attribute double current_height;
	double em(in double x);
	double ex(in double x);
	double inch(in double x);
	double cm(in double x);
	double mm(in double x);
	double pc(in double x);
	double pt(in double x);
}

The preferred values refer to the sizes of a rectangle’s unconstrained values. The current values refer to the sizes of a rectangle prior to the application of any constraint.

CSSContainer : Rectangle
{
	readonly attribute CSSRectangleList children;
	readonly attribute long numChildren;
}

A CSSContainer maintains an ordered list of child elements. The individual child elements are represented in the global execution environment by objects that support the CSSRectangle interface that also extends the Rectangle interface. CSSRectangle objects support referencing rectangle-attributes properties by name. The object returned represents the computational result of the attribute value’s expression. CSSRectangle objects may be referenced by name from the CSSContainer returning either a CSSRectangleList or CSSRectangle. The CSSRectangle name value is the id of the HTML element that it represents.

CSSRectangle: Rectangle
{
	readonly attribute unsigned long position;
	readonly attribute String name;
	readonly attribute CSSRectangle predecessor;
	readonly attribute CSSRectangle successor;
}

CSSRectangle objects may be referenced abstractly in expressions through global objects rectangle, predecessor, and successor. rectangle represents the CSSRectangle object on which behalf a constraint or attribute expression is executing. predecessor, and successor represent the preceding and succeeding CSSRectangle objects of rectangle in the container’s ordered list either of which may be null. These values change throughout execution as expressions are evaluated.

A rectangles global object supports the CSSRectangleList interface. This object represents the ordered list of elements in a container. CSSRectangleList objects are immutable.

CSSRectangleList objects support indexing values to return corresponding CSSRectangle objects.

A sublist of a CSSRectangleList may be constructed from an existing CSSRectangleList by referencing it as a function with integer arguments:

CSSRectangleList(start, end, stride, count)

start and end indicate a range of index values. start may be greater than end indicating that the values are set in reverse order.

The lesser of start and end must be between zero and one less than the CSSRectangleList length.

The greater of start and end must be between one and the CSSRectangleList length.

stride indicates how many values to skip between successive values and count indicates how any values to include each stride. count must be less than or equal to stride.

Both stride and count default to one.

A new CSSRectangleList may also be constructed from an existing CSSRectangleList by referencing it as a function with an Array of integer values. The integer values represent the indices of values to include in the new CSSRectangleList.

Additionally, CSSRectangleList objects support referencing rectangle-attributes properties by name. A CSSRectangleListValue is returned to represent these values.

CSSRectangleList
{
 	readonly attribute unsigned long length;
	readonly attribute CSSRectangleListValue position;
	readonly attribute CSSRectangleListValue left;
	readonly attribute CSSRectangleListValue right;
	readonly attribute CSSRectangleListValue horizontal_center;
	readonly attribute CSSRectangleListValue top;
	readonly attribute CSSRectangleListValue bottom;
	readonly attribute CSSRectangleListValue vertical_center;
	readonly attribute CSSRectangleListValue width;
	readonly attribute CSSRectangleListValue height;
	readonly attribute CSSRectangleListValue preferred_width;
	readonly attribute CSSRectangleListValue preferred_height;
	readonly attribute CSSRectangleListValue current_width;
	readonly attribute CSSRectangleListValue current_height;
      	CSSRectangleListValue em(in double x);
      	CSSRectangleListValue ex(in double x);
      	CSSRectangleListValue inch(in double x);
      	CSSRectangleListValue cm(in double x);
      	CSSRectangleListValue mm(in double x);
      	CSSRectangleListValue pc(in double x);
      	CSSRectangleListValue pt(in double x);
	CSSRectangleListIterator iterator();
	CSSRectangleList remove(in int x);
	CSSRectangleList remove(in int x, int length);
	CSSRectangleList remove(in CSSRectangle x);
      	CSSRectangleList append(in CSSRectangle x);
      	CSSRectangleList append(in CSSRectangleList x);
	long indexOf(in CSSRectangle x);
	boolean contains(in CSSRectangle x);
}

A CSSRectangleListIterator provides a simple means to iterate through a CSSRectangleList.

CSSRectangleListIterator 
{
      readonly attribute unsigned long index;
      readonly attribute CSSRectangle next;
      readonly attribute boolean more;
}

A CSSRectangleListValue represents a set of values from a CSSRectangleList. CSSRectangleListValue objects support indexing values to return objects representing the corresponding values in the list.

CSSRectangleListValue : CSSRectangleListFilter
{
	readonly attribute double min;
	readonly attribute double max;
	readonly attribute double sum;
	readonly attribute double avg;
	readonly attribute double stddev;
	readonly attribute double variance;
	readonly attribute CSSRectangleList sort;
	readonly attribute CSSRectangleListFilter exclude;
	readonly attribute CSSRectangleListFilter truncate;
	readonly attribute CSSRectangleListFilter cumulate;
	readonly attribute CSSRectangleListValueRect rect;
}

A CSSRectangleListFilter represents a set of operations that may be executed on a CSSRectangleListValue. These operations return a CSSRectangleListFilterOp.

CSSRectangleListFilter
{
	CSSRectangleListOp eq;
	CSSRectangleListOp ne;
	CSSRectangleListOp le;
	CSSRectangleListOp lt;
	CSSRectangleListOp ge;
	CSSRectangleListOp gt;
}

A CSSRectangleListFilterOp represents a set of operations that may be executed on a CSSRectangleListFilter. These operations return a new CSSRectangleList.

CSSRectangleListFilterOp
{
	readonly attribute CSSRectangleList left;
	readonly attribute CSSRectangleList right;
	readonly attribute CSSRectangleList horizontal_center;
	readonly attribute CSSRectangleList top;
	readonly attribute CSSRectangleList bottom;
	readonly attribute CSSRectangleList vertical_center;
	readonly attribute CSSRectangleList width;
	readonly attribute CSSRectangleList height;
	readonly attribute CSSRectangleList preferred_width;
	readonly attribute CSSRectangleList preferred_height;
	readonly attribute CSSRectangleList current_width;
	readonly attribute CSSRectangleList current_height;
}

CSSRectangleListFilterOp objects may be referenced as a function with a single numeric argument.

Additionally, CSSRectangleListFilterOp objects support referencing rectangle-attributes properties by name. A CSSRectangleList is returned to represent the value of the operation.

A CSSRectangleListValueRect represents a set of operations that return a CSSRectangle object.

CSSRectangleListValueRect
{
	readonly attribute CSSRectangle min;
	readonly attribute CSSRectangle max;
}

The following examples illustrate valid usage:

 

Expression Return Value
container.em(1) The number of pixels in 1em of the container’s font
rectangles.width.max the maximum width of all the rectangles in the CSSRectangleList
rectangles.width.rect.max the CSSRectangle that has the maximum width of all the rectangles in the list
rectangles.width.sum the sum of the widths of the rectangles in the list
rectangles.width.gt(100) A new CSSRectangleList including only those CSSRectangle objects with a width greater than 100px
rectangles.preferred_width. gt.current_width A new CSSRectangleList including only those CSSRectangle objects with a preferred width greater than their current width.
rectangles.width.exclude. gt(100) A new CSSRectangleList excluding those CSSRectangle objects with a width greater than 100px
rectangles.width.truncate. gt(100) A new CSSRectangleList truncated at the position of the first CSSRectangle that has a width greater than 100px
rectangles.width.cumulate. gt(100) A new CSSRectangleList truncated at the position of the first CSSRectangle that has a width that when summed with all preceding CSSRectangle widths is greater than 100px
rectangles(0, rectangles.length, 2) A new CSSRectangleList composed of every other CSSRectangle in the list
rectangles(rectangles.length, 0) A new CSSRectangleList in reverse order

 

Resolving Constraints   top
The constraint resolver executes the initial-script JavaScript to initialize the execution environment. The initial-script values referenced in the container’s layout-policy references are executed in the order presented followed by the initial-script value of the container itself.

After initialization the constraints for all the contained elements are resolved deterministically according to how dependencies among the constraints are expressed in the constraint values.

For instance, the top side of an element may be affixed to the bottom side of its predecessor according to the following constraint:

top:”predecessor.bottom”

In this case, the execution of the top constraint is interrupted in order to determine the bottom constraint of the predecessor. The predecessor may or may not have an explicit bottom constraint. If the constraint exists, it is evaluated, the result returned, and the top constraint execution is resumed. If the bottom constraint does not exist then its value is determined via other related constraints in the vertical dimension, e.g. a top and height constraint. Once all constraints are satisfied a layout computation is complete.

The constraint resolver strategy involves the repeated computation of container size and child rectangle configurations within the container. The child rectangle geometries are held constant at their current values during the computation of the container size. Conversely, the container size is held constant during the computation of the child rectangle configurations.

A global Boolean value, sizing, is defined in the runtime environment to distinguish between the computation of the container size and the child rectangle configurations.

The constraint resolver uses a set of heuristics to determine when to terminate. The primary heuristic is to stop when the last container size computation is a repeat of some prior computation, but only when all child rectangles’ sizes are at least as large as their preferred sizes, i.e. their content does not overextend their bounds. However, this second heuristic is relaxed in the case where all rectangle preferred sizes are a repeat of some prior computation. In this case, it is probably impossible to configure the child rectangles without some overextension.

In under-constrained or abstractly constrained cases multiple solutions may be indicated by a particular layout specification and set of content. In this case, the solution with the least area container in which all child rectangles fit their bounds is chosen. In cases where child rectangles must overextend then the configuration with the largest area container prevails.

This constraint resolution strategy enables layout solutions for more abstractly constrained specifications heretofore unrealizable in CSS while retaining the ability to resolve more typically constrained layout specifications quickly and efficiently.

A detailed discussion of size negotiation among elements is beyond the scope of this paper, but the subject is worthy of thorough examination. Geometry management as prescribed by the X Toolkit Intrinsics XtQueryGeometry1 is a good reference for this subject.

In a conventional layout specification, constraints are explicit and convergence to a solution occurs in one or two iterations. In these instances layouts are resolved quickly consuming little CPU time.

More interestingly, specifications with more abstract constraints may be realized. These make use of feedback from suboptimal early generation solutions to improved succeeding generation solutions converging to a final solution in the manner of a genetic algorithm. Example specifications follow that illustrate layout policies that include these features. Moreover, these examples will show how layouts can adapt to changes in screen real estate from window resize events.

CSS Scripting Layout – Security issues   top
The global object for the CSS Layout JavaScript runtime environment is an ordinary Object. Not using the browser window as the global object reduces or eliminates the possibility of any serious cross-site scripting (XSS) attack. As such, the CSS Layout JavaScript runtime environment does not include any of the HTML DOM objects or any client-side JavaScript Browser objects, including:
  • Window
  • Navigator
  • Screen
  • History
  • Location
  • Document

Likewise, the Asynchronous JavaScript and XML (AJAX) XMLHttpRequest object is unavailable in this runtime environment.

CSS Scripting Layout - Sample Implementation   top
To validate the CSS Scripting Layout specification a sample implementation was coded as an extension to Google Chrome. A 12.7MB zipped windows XP compatible executable of this implementation is located at the eFORCE site here. In this implementation scripting layout is limited to the elements of container elements that are positioned absolutely.
Comments on Layout in the Current CSS Standard

Dissatisfaction with CSS layout capability has been expressed by many in the Web Development community10,11,12,13,14,15,16,17,18,19,20 including members of the W3C CSS WG.21,22,23 The CSS Scripting Layout Model described here resolves many, if not most, of these legitimate concerns.

CSS, apparently, was conceptualized to enable a newspaper-like layout in a Web page.24,25 Whatever the case, in regard to layout, it should not be considered controversial to state that CSS was influenced primarily by the demands of print media and little on User Interface demands. This is understandable since, at the time, the WWW was dominated by static print media. However, rendering Web content now involves much more than mere typography. The Web has evolved into a GUI rich environment in which JavaScript Libraries like YUI26, Dojo Toolkit27, Ext JS28 , and others29 that enable layout features not easily achievable or impossible to achieve in CSS.

Interestingly, thirty-two leaders in the fields of web design and development interviewed for a Teach the Web monograph ranked layout third in importance among 62 skills that students should know by the time they graduate.30 This is further testimony to the inadequate state of CSS regarding layout and a need for tools and, moreover, new standards that address its shortcomings.

There are several layout related proposals31,32,33,34,35 in various states of development before the CSS Working Group and others36 that are not. These proposals appear to address various shortcomings, but do so at the cost of greatly increasing complexity with the introduction of a multitude of new properties that are largely mutually exclusive. The layout specification described here could mitigate the need for some of these proposals.

Conclusion

Layout is inherently complex. Layout designs must adapt to any imaginable change in screen size, configuration, or composition in real-time. The possibilities are limitless. It is an impossible task for any single high-level specification, or even a small set of specifications, to cope with every conceivable circumstance.

The W3C's Web Content Accessibility Guidelines' checkpoint 3.3, a priority-2 checkpoint, states "use style sheets to control layout and presentation."37 With this directive in mind it is incumbent on the W3C to provide lower-level tools to enable the broadest set of layout strategies and handle unforeseeable eventualities. As a practical matter, the most suitable tools for this purpose must incorporate aspects of actual programming languages. We believe that the combination of a scripting language and the Object Interfaces presented here meets this challenge most effectively in conformance with W3C's design principles.38

1 X Toolkit Intrinsics - Chapter 6 - Geometry Management
http://lesstif.sourceforge.net/doc/super-ux/g1ae03e/part1/contents.html

10We need something better for layout.
http://ajaxian.com/archives/css-for-layout-another-rant

11Wanted: Layout System
http://meyerweb.com/eric/thoughts/2009/02/17/wanted-layout-system/

12Here are a short list of the some disadvantages of using pure CSS on web layouts and designs.
http://www.articlesbase.com/web-design-articles/advantages-and-disadvantages-of-using-css-833019.html

13There are lots of things which we’d like to put in CSS but don’t because CSS just can’t do many of the things we should expect of it. Real-world CSS is likely to get longer, not shorter, as CSS evolves toward… all manner of complex layouts for which we currently turn to table elements and layout systems...
http://alex.dojotoolkit.org/2008/08/css-variables-are-the-future/

14There’s also no indication that the [W3C CSS Working Group] has taken stabs exposing the expressive power that Microsoft exposed with CSS Expressions.
http://alex.dojotoolkit.org/2007/12/the-w3c-cannot-save-us/

15Epicycles: are complex css layouts the new nested tables?
http://www.brucelawson.co.uk/2006/are-complex-css-layouts-the-new-nested-tables/

16If CSS layout code were as easy to write as HTML tables, making the leap would be a no-brainer; …the tools that CSS provides are not suited to the layout tasks we want to accomplish.
http://carsonified.com/blog/design/tables-the-next-evolution-in-css-layout/

17Real world layout is still dependent on source order. Some effects (equal height columns) are still hard to do... CSS and web standards keep popping up where they're least expected.
http://www.paulhammond.org/2006/06/atmedia/ericmeyer

18… layouts still requires trickery and some magic even after all this time.
http://www.nczonline.net/blog/2007/10/08/css-sucks/

19The fundamental problems with CSS3
http://mattwilcox.net/archive/entry/id/1031/

20Why CSS needs to borrow from programming languages
http://mattwilcox.net/archive/entry/id/991/

21Layout Is Expensive
http://fantasai.inkedblade.net/weblog/2009/layout-is-expensive/

22Web layout standards so far have taken a lot from the history of formatting printed documents and very little from the history of designing user interfaces. We need more of a balance...
http://dbaron.org/log/2007-09#e20070920a

23WaSP Community CSS3 Feedback 2008 - Layout
http://fantasai.inkedblade.net/style/discuss/wasp-feedback-2008#layout

24Chapter 20 of Cascading Style Sheets, designing for the Web
http://www.w3.org/Style/LieBos2e/history/

25Cascading HTML style sheets -- a proposal
http://www.w3.org/People/howcome/p/cascade.html

26An open-source JavaScript library for building richly interactive web applications
http://en.wikipedia.org/wiki/Yahoo!_UI_Library

27dojox.layout Experimental and Extended Layout Widgets
http://archive.dojotoolkit.org/nightly/dojotoolkit/dojox/layout/README

28A cross-browser JavaScript library for building rich internet applications
http://www.extjs.com/

2910 Promising CSS Framework That Worth A Look
http://www.webdesignbooth.com/10-promising-css-framework-that-worth-a-look/

30Perspectives on web education: What to teach the next generation of web professionals.
http://teachtheweb.com/monograph.php

31Template Layout Module
http://www.w3.org/TR/css3-layout/

32Multi-column Layout Module
http://www.w3.org/TR/css3-multicol/

33Table Model
http://www.w3.org/TR/CSS2/tables.html#table-display

34Flexible Box Layout Model
http://www.w3.org/TR/css3-flexbox/

35Grid Positioning Module Level 3
http://www.w3.org/TR/css3-grid/

36Matrix Layout
http://snook.ca/technical/matrix-layouts/

37Checkpoint 3.3
http://www.w3.org/TR/WCAG10-TECHS/#tech-style-sheets

38What is a good standard?
http://www.w3.org/People/Bos/DesignGuide/introduction

 
 
Example 1 – Introductory Concepts   back
The HTML in Example 1 produces the screen shot in Figure 1.

The rendering of this example demonstrates many of the features of CSS Script Layout.

Example 1 – Nested Containers

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
  <title>Nested Containers</title>

<style type="text/css">

@layout-policy pack_column {
    initial-script: "\
        var margin=container.em(0.5);\
    ";
    rectangle-attributes: "{\
        'topOffset':0\
    }";
    horizontal-center:"container.width/2";
    top: "rectangle.topOffset+margin\
        +(predecessor ? predecessor.bottom : 0)";
    container-height: "margin*(rectangles.length+1)\
        +rectangles.height.sum+rectangles.topOffset.sum";
    container-width: "2*margin+rectangles.width.max";
}
@layout-policy override {
    initial-script: "\
        var margin=container.em(0.25)\
    ";
    horizontal-center:none;
    left:"margin";
}
@layout-policy pack_row {
    initial-script: "\
        var margin=0;\
    ";
    vertical-center:"container.height/2";
    left:"margin+(predecessor ? predecessor.right : 0)";
    container-width:"margin*(rectangles.length+1)\
        +rectangles.width.sum";
    container-height:"2*margin+rectangles.height.max;";
}
.body {
    layout-policy: 'pack_column';
    position:relative;
    border:1px black dashed;
    padding:0px;
}
.container {
    layout-policy: 'pack_row';
    initial-script: "margin=container.ex(2);";
    position:absolute;
    border:1px black solid;
    padding:0px;
 }
.container1 {
    layout-policy: 'pack_column override';
    width:130px;
    position:absolute;
    border:1px black dotted;
    margin:0px;
    padding:0px;
 }
.text {
    position:absolute;
    border:1px black dashed;
    padding:0px;
 }
.extension {
    rectangle-attributes: "{\
        'topOffset':'container.em(1)+margin'\
    }";
    width:200px;
    padding:10px;
 }
</style>

</head>

<body class='body'>
<span class='text'>test nesting containers</span>

<span class='container'>
a nested container that overrides the default margin.<br>
this text is in a relative span and<br>is not constrained by the container.
<span class='text'>
this&nbsp;span&nbsp;of&nbsp;text&nbsp;is&nbsp;centered&nbsp;vertically
</span>
<button style='position:absolute;'>button</button>

<span class='container1'>
relative text
<span class='text extension'>
this span has an explicit padding and width specification and a topOffset rectangle attribute.
</span>
<span class='text' style='width:150px'>
notice also the override policy specification overrides the margin and alignment...
</span>
<span class='text'>hence the spans are now left aligned and the margin is smaller.
</span>

</span>

</span>
</body>
</html>

Figure 1 - Nested Containers

This layout renders in less than 32 milliseconds on a Dell LATITUDE D630 Laptop (Intel Core 2 Duo T7500 2.20GHz, 2.49 GB RAM) running MS Windows XP V2002 Service Pack 3.

 
 
Example 2 – Three-Column Presentation   back
The Common Three-Column Presentation 2,3,4 HTML in Example 2 produces the screen shot in Figure 2.

The rendering of this example demonstrates how elements may be referenced by their HTML id in the script. Additionally, in this example there is no dependency on the order of the elements in the HTML as to where they are rendered. This is an important point for those concerned with Search Engine Optimization (SEO).

The totality of the layout here is distributed among the rules of each element in the window. Notable here is that the desired result is clearly evident from the constraint specifications within each rule and presented rationally without resorting to hacks or tricks and without any compromises. All elements are free to resize as required by their content.

Example 2 – Common Three-Column Presentation

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
  <title>Three Column Layout</title>
<style type="text/css">

@layout-policy entire_window {
initial-script: "\
var margin=4;\
var content_area=container.content_area;\
var header=container.header;\
var header_content=container.header_content;\
var footer=container.footer;\
var footer_content=container.footer_content;\
var primary_navigation=container.primary_navigation;\
var secondary_navigation=container.secondary_navigation;\
var min_content_width = 200;\
var max_content_width = 600;\
";
container-script: "\
var content_width = container.width-2*margin-\
	primary_navigation.width-secondary_navigation.width;\
";
container-height:100%;
container-width:100%;
}

#body {
    position:relative;
    layout-policy: 'entire_window';
    border:0px black solid;
    margin:0px;
    padding:0px;
}

#content_area {
    top:"header.bottom";
    bottom:"footer.top";
    left:"primary_navigation.right";
    width:"content_width<min_content_width?min_content_width:\
	content_width>max_content_width?max_content_width:content_width";
    position:absolute;
    border:1px black solid;
}

#primary_navigation {
    left:"margin";
    width:"rectangle.ex(10)+8+container.width*0.1;";
    top:"header.bottom";
    bottom:"footer.bottom";
    position:absolute;
    border:1px black solid;
}

#secondary_navigation {
    top:"header.bottom";
    bottom:"footer.bottom";
    left:"content_area.right";
    width:"rectangle.ex(8)+8+container.width*0.1;";
    position:absolute;
    border:1px black solid;
}

#header {
    top:"margin";
    height:"header_content.height+2*margin";
    left:"margin";
    right:"secondary_navigation.right";
    position:absolute;
    border:1px black solid;
}

#header_content {
    width:"header.width-2*margin";
    vertical-center:"header.vertical_center";
    horizontal-center:"header.horizontal_center";
    position:absolute;
    border:1px black solid;
}

#footer {
    height:"footer_content.height+2*margin";
    top:"header.bottom+Math.max(content_area.preferred_height,\
primary_navigation.preferred_height-footer.height,\
secondary_navigation.preferred_height-footer.height)";
    left:"primary_navigation.right";
    right:"secondary_navigation.left";
    position:absolute;
    border:1px black solid;
}

#footer_content {
    width:"footer.width-2*margin";
    horizontal-center:"footer.horizontal_center";
    vertical-center:"footer.vertical_center";
    position:absolute;
    border:1px black solid;
}

  </style>
</head>


<body id='body' class='body'>


<span id='content_area'>
Sed ut perspiciatis unde omnis iste natus error sit voluptatem 
accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae 
ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt 
explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut 
odit aut fugit, sed quia consequuntur magni dolores eos qui ratione 
voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum 
quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam 
eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat 
voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam 
corporis suscipit laboriosam, nisi ut aliquid ex ea commodi 
consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate 
velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum 
fugiat quo voluptas nulla pariatur?
</span>

<span id='primary_navigation'>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse 
massa lacus, consectetur vitae commodo sed, aliquet eget sapien. 
Quisque erat odio, convallis non aliquam vitae, pulvinar a diam. 
In hac habitasse platea dictumst. Aenean non tempor ipsum. Sed scelerisque 
fringilla ligula at laoreet. Cras posuere metus at ligula posuere in 
consequat lorem malesuada. Sed id lobortis nulla.
</span>

<span id='secondary_navigation'>
Fusce enim sem, ornare in ornare nec, ornare sed neque. Ut sed felis 
orci, in pretium lectus. Cras nec felis sed nibh venenatis dignissim in 
sit amet massa. Cras sodales mollis arcu, quis sagittis tellus euismod 
eu. Nulla facilisi. Aliquam ultrices consequat rutrum. Quisque pharetra 
adipiscing porta. Nullam sem urna, fringilla tempus aliquet a, ornare 
non risus.
</span>

<span id='header_content'>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum 
vestibulum fringilla interdum. Fusce suscipit vehicula nunc, nec 
sagittis risus mollis non. Cras non rhoncus magna. Vestibulum ante 
ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; 
Nullam eleifend sapien velit. Cum sociis natoque penatibus et magnis 
dis parturient montes, nascetur ridiculus mus. Quisque gravida erat vel 
eros iaculis ac rhoncus nibh tincidunt.
</span>

<span id='footer_content'>
Fusce quis lacus ligula, a dictum metus. Aenean risus odio, sagittis ac 
posuere vel, viverra et erat. Aenean eros lorem, fringilla ut aliquam 
id, pulvinar et nulla. Pellentesque imperdiet eros non odio faucibus 
fringilla. Nam ut nulla at tellus vestibulum mattis.</span>
<span id='header'</span>
<span id='footer'></span>

</body>

</html>

Figure 2 - Common Three Column Presentation

The Three-Column layout renders in 16 milliseconds on a Dell LATITUDE D630 Laptop (Intel Core 2 Duo T7500 2.20GHz, 2.49 GB RAM) running MS Windows XP V2002 Service Pack 3.

2 In Search of the Holy Grail
http://www.alistapart.com/articles/holygrail/
3 CSS Three Column Liquid Layout
http://www.manisheriar.com/holygrail/index.htm
4 Why CSS should not be used for layout
http://www.flownet.com/ron/css-rant.html
 
 
Example 3 – HTML Table comparison   back
The HTML in Example 3 produces the screen shot in Figure 3. In the first row the layout policy accounts for and minimizes a cell’s total area rather than relying on a cell’s width as in the HTML table below it. Deficiencies with table layout are described in Poorly Laid-out Tables.5

Example 3 – Script vs. HTML Table

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
  <title>Script vs. HTML Table</title>
<style type="text/css">

@layout-policy pack_column {
initial-script: "\
var margin=1;\
var space=(rectangles.length+1)*margin;\
";
width:"container.width";
height:"rectangle.preferred_height";
top:"margin+(predecessor ? predecessor.bottom : 0)";
container-height:"space+rectangles.preferred_height.sum";
container-width:"rectangles.preferred_width.max";
}

@layout-policy least_area_horizontal {
initial-script: "\
var margin=2;\
var space=(rectangles.length-1)*margin;\
var governor=-0.24;\
var accelerator=2;\
";
container-script: "\
var reserved=rectangles.pliant.eq(false);\
var pliant=rectangles.pliant.ne(false);\
var usable_width=container.width-space-reserved.preferred_width.sum;\
var area_ratio=usable_width/pliant.area.sum;\
";
rectangle-attributes: "{\
'current_area':'rectangle.current_width*rectangle.current_height',\
'preferred_area':'rectangle.preferred_width*rectangle.preferred_height',\
'area':'rectangle.preferred_area*accelerator+rectangle.current_area*governor',\
'max_width':'rectangle.preferred_width>=rectangle.width?rectangle.preferred_width:rectangle.width',\
'pliant':'rectangle.pliant!==false&&rectangle.preferred_width<=rectangle.current_width'\
}";
top:0;
height:"container.height";
width:"rectangle.pliant?rectangle.area*area_ratio:rectangle.preferred_width";
left:"predecessor ? predecessor.right+margin : 0";
container-width:"rectangles.max_width.sum+space";
container-height:"rectangles.preferred_height.max";
}
.body {
    padding:0px;
    margin:0px;
    layout-policy: 'pack_column';
    border:1px black solid;
    position:relative;
    container-width:100%;
}
/* script layout rules */
.text {
    margin:0px;
    position:absolute;
    border:1px black solid;
    padding:0px;
}
.row {
    layout-policy: 'least_area_horizontal';
    position:absolute;
    border:2px black dotted;
    margin:0px;
    padding:0px;
}
/* html table rules */
.table {
    position:absolute;
    border:2px black dotted;
    margin:0px;
    padding:0px;
}
.ttext {
    vertical-align:top;
    margin:0px;
    border:1px black solid;
    padding:0px;
}

  </style>
</head>

<body id='body' class='body'>

<div id='top' class='row'>

<span id='text2' class='text'>
<img src="small.gif"><img src="small.gif"><img src="big.gif"><img src="big.gif">
</span>

<span id='text1inner' class='text'>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum 
vestibulum fringilla interdum. Fusce suscipit vehicula nunc, nec 
sagittis risus mollis non. Cras non rhoncus magna. Vestibulum ante 
ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; 
Nullam eleifend sapien velit. Cum sociis natoque penatibus et magnis 
dis parturient montes, nascetur ridiculus mus. Quisque gravida erat vel 
eros iaculis ac rhoncus nibh tincidunt.
</span>

<span id='text1inner' class='text'>
Fusce quis lacus ligula, a dictum metus. Aenean risus odio, sagittis ac 
posuere vel, viverra et erat. Aenean eros lorem, fringilla ut aliquam 
id, pulvinar et nulla. Pellentesque imperdiet eros non odio faucibus 
fringilla. Nam ut nulla at tellus vestibulum mattis. Fusce at tincidunt 
nunc. Aliquam pharetra faucibus nisl, auctor dignissim tortor vehicula 
rutrum. Pellentesque tincidunt mi ut elit congue sit amet eleifend dui 
euismod. Donec luctus, lorem et placerat pulvinar, justo nunc dapibus 
lorem, id porta velit diam sed diam. Nulla et erat libero. Donec auctor 
sapien in dolor pretium ornare.
</span>
</div>

<table id='table' class='table'>
<tr class='ttext'>

<td id='text2' class='ttext'>
<img src="small.gif"><img src="small.gif"><img src="big.gif"><img src="big.gif">
</td>

<td id='text1inner' class='ttext'>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum 
vestibulum fringilla interdum. Fusce suscipit vehicula nunc, nec 
sagittis risus mollis non. Cras non rhoncus magna. Vestibulum ante 
ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; 
Nullam eleifend sapien velit. Cum sociis natoque penatibus et magnis 
dis parturient montes, nascetur ridiculus mus. Quisque gravida erat vel 
eros iaculis ac rhoncus nibh tincidunt.
</td>
<td id='text1inner' class='ttext'>
Fusce quis lacus ligula, a dictum metus. Aenean risus odio, sagittis ac 
posuere vel, viverra et erat. Aenean eros lorem, fringilla ut aliquam 
id, pulvinar et nulla. Pellentesque imperdiet eros non odio faucibus 
fringilla. Nam ut nulla at tellus vestibulum mattis. Fusce at tincidunt 
nunc. Aliquam pharetra faucibus nisl, auctor dignissim tortor vehicula 
rutrum. Pellentesque tincidunt mi ut elit congue sit amet eleifend dui 
euismod. Donec luctus, lorem et placerat pulvinar, justo nunc dapibus 
lorem, id porta velit diam sed diam. Nulla et erat libero. Donec auctor 
sapien in dolor pretium ornare.
</td>
</tr>
</table>

</body>
</html>

Figure 3 - Script vs. HTML Table

The layout in Figure 3 renders in less than 32 milliseconds on a Dell LATITUDE D630 Laptop (Intel Core 2 Duo T7500 2.20GHz, 2.49 GB RAM) running MS Windows XP V2002 Service Pack 3.

5Poorly Laid-out Tables
http://nothings.org/computer/badtable/
 
 
 
Example 4 – Advanced Concepts – Near Optimal Least Area Layout   back
The HTML in Example 4 produces the screen shots in Figures 4 and 5. The Near Optimal Least Area layout nests containers to a depth of four with varying layout policies for each. Notable here is that in the execution of the layout policies the constraint resolver searches for and converges on solutions that minimize the area taken by the rectangles for a given width of the window. There is no guarantee that the most optimal layout is found, but only one that approaches it which is likely acceptable if not imperceptible from the optimum to the average viewer.

A description of the actual layout policies and how they function is beyond the scope of this paper. More to the point is that layouts may be developed and shared among developers without the need for end users to understand the execution details. De facto or even de jure standards could emerge from this process.

Example 4 – Near Optimal Least Area

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
  <title>Near Optimal Least Area</title>
<style type="text/css">

@layout-policy pack_column {
initial-script: "\
var margin=1;\
var space=(rectangles.length+1)*margin;\
";
width:"container.width";
height:"rectangle.preferred_height";
top:"margin+(predecessor ? predecessor.bottom : 0)";
container-height:"space+rectangles.preferred_height.sum";
container-width:"rectangles.preferred_width.max";
}

@layout-policy proportional_width {
initial-script: "\
var margin=2;\
var governor=-0.25;\
var accelerator=2;\
var space=(rectangles.length-1)*margin;\
";
container-script: "\
var reserved=rectangles.pliant.eq(false);\
var pliant=rectangles.pliant.ne(false);\
var usable_width=container.width-space-reserved.preferred_width.sum;\
var area_ratio=usable_width/pliant.area.sum;\
";
rectangle-attributes: "{\
'area':'rectangle.preferred_width*rectangle.preferred_height*accelerator+\
rectangle.current_width*rectangle.current_height*governor',\
'max_width':'rectangle.preferred_width>=rectangle.width?rectangle.preferred_width:rectangle.width',\
'pliant':'rectangle.pliant!==false&&rectangle.preferred_width<=rectangle.current_width'\
}";
top:0;
height:"container.height";
width:"rectangle.pliant?rectangle.area*area_ratio:rectangle.preferred_width";
left:"predecessor ? predecessor.right+margin : 0";
container-width:"rectangles.max_width.sum+space";
container-height:"rectangles.preferred_height.max";
}

@layout-policy proportional_height {
initial-script: "\
var margin=2;\
var governor=-0.25;\
var accelerator=2;\
var space=(rectangles.length-1)*margin;\
";
container-script: "\
var reserved=rectangles.pliant.eq(false);\
var pliant=rectangles.pliant.ne(false);\
var usable_height=container.height-space-reserved.preferred_height.sum;\
var area_ratio=usable_height/pliant.area.sum;\
";
rectangle-attributes: "{\
'area':'rectangle.preferred_width*rectangle.preferred_height*accelerator+\
rectangle.current_width*rectangle.current_height*governor',\
'pliant':'rectangle.pliant!==false&&rectangle.preferred_height<=rectangle.current_height'\
}";
top:0;
width:"container.width";
height:"rectangle.pliant?rectangle.area*area_ratio:rectangle.preferred_height";
top:"predecessor ? predecessor.bottom+margin : 0";
container-height:"rectangles.preferred_height.sum+space";
container-width:"rectangles.preferred_width.max";
}

.body {
    padding:0px;
    margin:0px;
    layout-policy: 'pack_column';
    border:1px black solid;
    position:relative;
    container-width:100%;
}
.column {
    position:absolute;
    padding:0px;
    margin:0px;
    layout-policy: 'proportional_height';
    border:2px black solid;
}
.text {
    margin:0px;
    position:absolute;
    border:1px black solid;
    padding:0px;
 }

.row {
    layout-policy: 'proportional_width';
    position:absolute;
    border:2px black dotted;
    margin:0px;
    padding:0px;
}

  </style>
</head>

<body id='body' class='body'>

<div id='top' class='row'>

<span id='textimagemixlong' class='text'>
<img src="small.gif" border="0"> <img src="small.gif" border="0"> 
<img src="small.gif" border="0"> <img src="small.gif" border="0">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse 
massa lacus, consectetur vitae commodo sed, aliquet eget sapien. 
Quisque erat odio, convallis non aliquam vitae, pulvinar a diam.
<img src="small.gif" border="0"> <img src="small.gif" border="0"> 
<img src="small.gif" border="0"> <img src="small.gif" border="0">
In hac habitasse platea dictumst. Aenean non tempor ipsum. Sed 
scelerisque fringilla ligula at laoreet.
</span>

<span id='text2' class='text'> 
<img src="small.gif"> <img src="small.gif"> 
<img src="small.gif"> <img src="small.gif"> 
<img src="big.gif"> <img src="big.gif"> 
<img src="big.gif"> <img src="big.gif"> 
</span> 

<span id='text1inner' class='text'>
Cras posuere metus at ligula posuere
<img src="small.gif" border="0">
in consequat
<img src="small.gif" border="0">
lorem malesuada.
<img src="small.gif" border="0">
Sed id lobortis nulla.
<img src="small.gif" border="0">
Fusce enim sem, ornare in ornare nec, ornare sed neque. Ut sed felis 
orci, in pretium lectus. Cras nec felis sed nibh venenatis dignissim in 
sit amet massa. Cras sodales mollis arcu, quis sagittis tellus euismod eu.
</span>

<div id='inner' class='column'>

<span id='text1inner' class='text'>
Nulla facilisi. Aliquam ultrices
<img src="small.gif" border="0">
consequat
<img src="small.gif" border="0">
rutrum.
<img src="small.gif" border="0">
Quisque pharetra
<img src="small.gif" border="0">
adipiscing porta. Nullam sem urna, fringilla tempus aliquet a, ornare non risus.
</span>

<span id='text2inner' class='text'>
<img src="small.gif" border="0"> This is a nice simple paragraph of text,
<img src="small.gif" border="0"> 
which has been chosen to  height as the other cell, since they are about equally long.
</span>

</div>

</div>

<div id='bottom' class='row'>

<span id='textbr' class='text'>
This paragraph has encoded *<br>
line-breaks after each asterisk *<br>
to confound the layout.  Content *<br>
management systems may include *<br>
content with embedded html or *<br>
images that confound sensitive *<br>
css specifications. Content *<br>
authors often are unaware of where*<br>
their content is consumed.*<br>
</span>

<span id='textimagemixlong' class='text'>
<img src="small.gif" border="0"> <img src="small.gif" border="0"> 
<img src="small.gif" border="0"> <img src="small.gif" border="0">
Sed ut perspiciatis unde omnis iste natus error sit voluptatem 
accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae 
ab illo inventore veritatis et quasi architecto beatae vitae dicta
<img src="small.gif" border="0"> <img src="small.gif" border="0"> 
<img src="small.gif" border="0"> <img src="small.gif" border="0">
sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur 
aut odit aut fugit,
</span>

<div id='innerbottom' class='column'>

<div id='innerbottomrow' class='row'>

<span id='smallinner' class='text'>
<img src="small.gif" border="0"> <img src="small.gif" border="0"> 
<img src="small.gif" border="0"> <img src="small.gif" border="0">
</span>

<span id='text1inner' class='text'>
sed quia consequuntur magni
<img src="small.gif" border="0">
dolores eos
<img src="small.gif" border="0">
qui ratione
<img src="small.gif" border="0">
voluptatem sequi
<img src="small.gif" border="0">
nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit 
amet, consectetur, adipisci velit, sed quia non numquam eius modi 
tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. 
Ut enim ad minima
</span>

<span id='text2inner' class='text'>
<img src="small.gif" border="0">
veniam, quis
<img src="small.gif" border="0">
nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut 
aliquid ex ea commodi consequatur? Quis autem
</span>

</div>

<span id='text2inner' class='text'>
<img src="small.gif" border="0">
vel eum iure reprehenderit qui in ea
<img src="small.gif" border="0"> 
voluptate velit esse quam nihil molestiae consequatur, vel illum qui 
dolorem eum fugiat quo voluptas nulla pariatur?
</span>

</div>

</div>

</body>
</html>

Figure 4 - Near Optimal Least Area Layout

Example 4 is an extreme case demonstrating the ability of the containers to cooperate in the layout resolution. Note that no explicit heights or widths are specified. In this instance the layout adjusts to the content and vice versa in a virtuous cycle.

In situations where content is generated by a CMS team that is separate from the Web design team6 or where content may be reused in many applications not known in advance7,8 it may be necessary to leave element sizes unspecified and accommodate their natural sizes in a self-organizing layout. Otherwise poor renderings may result as demonstrated in the HTML table in Example 3.

In Figure 5 a resize widening the window results in the layout adjusting accordingly.

Figure 5 - Near Optimal Least Area Layout. Layout adjusts to increased window width.

The layout in Examples 4 and 5 renders in somewhere between 0.2 and 2.0 seconds, usually toward the lower end, depending on the window size as it unpredictably effects the rate of convergence. This may be acceptable performance for some applications.9

6 laying out images consistently within a design is difficult; especially when you hand the keys over to someone else to fill in the content.
http://www.alistapart.com/articles/figurehandler/
7 we must build pages that adapt to unpredictable content and unpredictable users.
http://blog.rebeccamurphey.com/2009/02/13/css-vs-tables-maybe-the-design-is-to-blame/
8 The challenge is writing CSS that looks good if you don't know ahead of time what your content is going to be.
http://rondam.blogspot.com/2009/02/css-and-meaning-of-life.html
9 Fast is better than slow. Slow is better than closed.
http://alex.dojotoolkit.org/2009/08/some-orthodox-heresies/

 

posted @ 7/16/2009 10:56 AM by Darrel Karisch

SQLDBCrypt Is Now Live And Open Source.

SQLDBCrypt; is an in-house encryption tool for SQL Server 2005 or later which makes it really easy for you to encrypt specific columns inside your SQL server databases.

Abhijit Ghosh (who gives me a sinister smile when you ask him about his blog URL or his web presence) conceived the idea of writing this in his free time a couple of years ago when were looking for a commercial encryption engine for SQL server in ITOPS.    

Sticking to the eFORCE culture of giving someone with a genuine idea time; freedom and lots of resources we provided him what he wanted and got out of his way. Within a few weeks we had a fully functional prototype which we took to the next level by starting to use it inside of ITOPS and fully integrating Ad-hoc reporting and some of out other products with it.

After almost a year of testing and the product running successfully in production environments we have released SQLDBCrypt out live as a free open source product you can use in your projects.

You can read the complete release story here or take a look at the product home page on codeplex. We will also be announcing this on the Treasury sciences blogs page where we intend to talk about how this piece integrates seamlessly with out Ad-hoc reporting piece and the rest of ITOPS.

Whether you are in or outside of eFORCE; we would highly recommend you give this product a shot and do let us know your feedback.

Abhijit and I will be spending the next few days to chalk out a product roadmap and decide our next steps on packaging the product along with giving out added training material that makes it really easy to get up and running with this product.

This tool being brought to you from the Dot-Net-Labs initiative @ eFORCE.

posted @ 6/28/2009 8:23 PM by Rajiv Popat

Some random thoughts on using Hadoop for database driven applications

‘Can Hadoop help shorten duration of my 48 hr batch process?’, ‘can Hadoop cluster help replace my cluster of high-end servers?’ so you ask. We have heard a number (or variations) of these questions from our clients in past several weeks.   Some of our clients are in the finance or publishing industries – they house large set of databases ranging from MySQL to Oracle to maintain their array of data and run various data warehousing, cleansing and mining jobs. As data sizes have grown exponentially, so have database cluster and server configuration – as well as time it takes to run daily/weekly batch processing jobs and reports.

MapReduce algorithm has gained lot of popularity (and not to mention lot of press coverage as well) over last few months. The algorithm’s inventor, Google, is using it for its own search technology. Hadoop, which is its open source version has been heavily supported by Yahoo and used at its various projects. So obviously, the technology has been proven to efficiently handle datasets that ranges from terabytes to petabytes. Question is whether it can be applied to RDBMS/data warehousing domain? Can it solve the problem of long running ETL jobs Or can it be used to truncate time it takes to run some data mapping jobs? Can it help DBA/IT Developers to get out of constant loop of performance tuning, indexing, tuning and indexing?

All good questions.

But alas, trying to utilize Hadoop for database driven application is not as straightforward as it may sound.  And it may turn out to be not as efficient either. For starters, Hadoop platform is built on top of regular file system. Its architecture has two main components: Hadoop distributed file system (HDFS), which distributes & stores data over several machines, and mapreduce programming framework, which can be used to divide long running jobs into several smaller (map) tasks and then combine results during reduce phase.  Hadoop usually serializes and stores its objects on a regular file system. Since Hadoop itself is built on top of regular file system and not say DBMS, it is difficult to utilize its platform to scale your traditional RDBMS applications. Companies like AsterData and GreenPlum has databases built on top of their own mapreduce  framework.

 Having said that, there are several options to use Hadoop for your database jobs:
  • Check out Hadoop DBInputFormat API (http://hadoop.apache.org/core/docs/current/api/org/apache/hadoop/mapred/lib/db/package-summary.html), which is part of v0.19 and later. It allows users to make JDBC calls from within Hadoop framework.
  • Frameworks built on top of Hadoop platform: Hive, PIG (and Cascading, which is open source but not part of ASF umbrella). These frameworks are designed to provide support for structured data analysis. In addition, Hive uses SQL based syntax. These frameworks can be used to load data from your databases inside Hadoop, perform analysis and generate results or even export results into flat files and load it back into your database.

One must also give careful consideration to what jobs can be transferred to Hadoop.  One rule of thumb we try to follow is analyzing whether a particular job spends more time executing SQL statements or in other computation activities like data analysis, transformation or aggregation.  In most cases, later type of jobs will benefit more from being executed in hadoop cluster environment. Otherwise, firing SQL statements from your 100s-1000s of mapper tasks would be a sure way to get your DBA’s attention!
 
We will try to share some more insights into this topic over next couple of blogs. Stay tuned!

posted @ 5/5/2009 2:53 PM by Devang Shah

Real-Time Location Tracking Using Google Latitude

Welcome to the world of Location tracking!

The whole idea of being able to locate and track my friends and co-workers via mobile phones is exciting. From both the personal world and the business world, one can easily understand the far-reaching benefits of this technology. One can imagine a variety of use cases from a business perspective. For example, "a company's manager wants to track his on-field employees (Postal services...)".

Venturing into this path, we started putting together an application for a use case similar to the above. Question? Whether a company's manager would be tracking from a Desktop or Mobile. Probably both. We started the use case from a Desktop. Probably, few of you would have guessed which location tracking provider we would have chosen. It is Google latitude on mobiles and iGoogle in Desktop. Even though we have multiple options in this area (Loopt, Yahoo's fire-eagle..), none of the location tracking technologies are close to Google latitude in terms of reach (variety of devices, mobile service providers and people). So, the obvious choice ==> Google latitude in iGoogle

Coming to application technology choice, what better choice, in particular for a decade Java experienced would have, other than GWT (Google Web toolkit)? The idea of being able to write the client side code of an Ajax application in Java and translate into browser specific Java Script code is certainly novel. For the tens of thousands of Java developers, GWT nicely fits into their pocket.

Ok. Let's get into our application's details a bit. We signed up for a Google Maps key for our domain and using the map key in Google Maps API of GWT, we populated the Google Maps for this use case. As you see here, the red balloon stands for an individual office and the green marker stands for a group of offices.  All the company locations data are stored as latitude/longitude positions in the database and we used J2EE on the server side to return JSON responses to the client.

The beauty of this architecture is that we can easily swap the J2EE on the server side with PHP or Ruby on Rails easily. In fact, we are on our way towards setting up a Ruby on Rails server side for this application. Or better, with the advent of Google App Engine for Java, Google Eclipse plug-in and GWT 1.6, one can develop/test/debug a GWT application from Eclipse and deploy for production, with a touch of button and free of cost, into Google Servers with ease.

4-23-2009 5-48-26 PM 

When the company's manager clicks an office balloon, it opens up the company manager's iGoogle page from which the company's manager can track his on-field employees in Google latitude as shown below.

4-27-2009 1-47-12 PM 

Great! Now you can see the company manager in the center surrounded by on-field employee’s locations. From here, the company manager can track the worker's locations and chat/voice chat with them. Even other wireless iGoogle latitude workers can also be tracked.

While all this is great, the notable missing feature is the lack of availability of Google latitude API. For example, we would like to get a notification in iGoogle latitude gadget once a mobile phone user enters the network or more of that kind of functionality. This requires marking an area around a user and listening to events across the area which is not possible without the availability of Google latitude API.

So, the whole application venture was great but we have come to a standstill because of the lack of availability of the latitude API. Just like Google has released Google Maps API in Java Script and GWT, we hope it releases Google Latitude API also. Or better, the next version of Google Maps API probably shall contain functions that will enable developers to add Google accounts directly on the maps and track them as well.

Eagerly waiting for the next version of Google Maps API with Latitude functionality so that the community can develop many practical interesting applications.   See you all again! Happy Blogging!

References:

    1. Google Latitude Home page: http://www.google.com/latitude/intro.html

    2. Mobile tracking Basics with Google Latitude:http://trivuz.com/component/content/article/35-tech-review/65-mobile-tracking-system-google-latitude

    3. Top 10 reasons why Google Latitude will succeed: http://thenextweb.com/2009/02/05/ten-reasons-google-latitude-succeed/

    4. Location Tracking with Google Latitude: http://www.labnol.org/software/location-tracking-with-google-latitude/8194/    

    5. Maps APIs & Mobile Session in Google Sessions 2009 in San Fransisco may give us useful insight into this  http://code.google.com/events/io/sessions.htm

    6. Creating Google account for Google Apps id: http://www.google.com/support/mobile/bin/answer.py?hl=en&answer=136641

    7. Broadcast your location through google latitude from Orkut - http://www.labnol.org/internet/broadcast-location-from-orkut/8209/

posted @ 4/28/2009 1:40 PM by Rafiq Abdul

Crux Open Sourced

We've just open sourced Crux - a free light weight open source work-flow engine and a web application framework that I worked on.

We are fairly excited and so is the recently formed Crux Team.

Come, share our excitement here or visit us at CodePlex.

posted @ 3/2/2009 1:01 PM by Rajiv Popat

Meet Skillz 2.0

Meet Skillz 2.0

Skillz Navigation Last month I had posted an article on Skillz 1.0, here and at my personal blog site, under category Skillz, explaining the challenges faced in the project "Skillz", and how we solved it. These challenges grew in number and size as we moved forward. The Skillz 2.0 is expected to be ready for launch by anywhere around mid of March, after thorough review, testing, bug fixing and demonstration videos. There were many cycles of thought-process and discussion before we nailed down the specs and sketched the roadmap for Skillz 2.0. This had already started prior to release 1.0. The effort was to take Skillz to next level - nearer to "Performance" = ("Talent Management" + "Performance Management"), that I had discussed in my previous article on Skillz. The new Skillz required some major changes in its architecture to allow measuring performance. We also got several feedback that contributed to Skillz 2.0. We got our own HR & Finance heads involved to figure out the smallest beads required, to be roped into Skillz to make it more effective and generic.

Here I would like to discuss few new things introduced which took Skillz to next level of perfection. The two new modules added in this release are "Activities" and "Assessment", beside several restructuring and fine tuning to the existing modules.

Activity:

Activities in Skillz are, by definition "Any task which can be assessed for its performance.". In general any organization doing business would have certain activities associated with it, that forms the core of its business. These activities can take various forms like project, department, interview, research and many more. Activities require certain skills and people who are associated to it on a time basis. Every activity further, has an owner who is is a user responsible for the said activity and users who are performing any particular role in that activity within the activity's time limits. Activities can be nested, which means that an activity can have sub activity with an owner associated. Owners are allowed to create further sub-activities, however, they do not have access to their parent activities. In general the activity tree resembles somewhat an organizational chart. Few typical activity screens are shown below:

Activity General attribute of an Activity.

On the left, are the general attributes of an activity with an option to schedule the starting or closing dates for an activity. An activity might be planned before it starts which requires a scheduler to handle it. It can be manually started using the "Start Now" option.
Parent Activity Parent-Child relationship of Activities.

Activities can be nested. The screen on the left, allows you to do so. An owner can create and manage a sub activity. An owner has a complete ownership of all child activities.
Activity Skills Associating Skillset to an Activity.

Any Activity requires a set of skills to run. The system responds with showing users a tree of skillset groups and skillset to choose from. The skillset chosen forms the base for users who can be associated to the activity. Only those users, having these skillset can be assigned to the activity.
Weightage Activity weightage:

Weightage for an activity denotes its importance as seen by the business based on several parameters, like region, type, criticality etc. These parameters allows Skillz to rank activities and measure/assess the activities more accurately during activity assessment.

Assessment:

Assessment Menu Every activity has people associated with it, who are in-turn having the required skills and having a defined role in that activity, for certain time period. Every skillset has a value-range, which is used to define the bounds for the ratings. The user associated to that skill are rated with a value belonging to that value-range. The managers or owners of an activity use these value-range to rate the users in the activity for his role played in the activity.

An assessement migth be carried out for a single activity or a group of activities. It also has weightage associated with it which is a matrix of "Skillset", "Job-Role" and "Weightage". This typically reduces the scope of assessment being biased. These assessments are further, archived by Skillz for analytics.

A typical assessment screen would look like this:

Assessment

An activity migth be continuous in nature. Further, it is not necessary that an assessment is carried out after the activity is over. Hence, Skillz allows you to assess any activity within a time interval in which it exists !!Sigh!! (was not that easy to design and code). The assessment "from" and "to" defines the timeline for which the assessment is to be carried out. The response "start" and "end" date defines the owners responsibility to complete the assessment not before start date and not after end date.

I will keep adding more as it comes ... for now see ya soon ... bye!

posted @ 2/5/2009 7:19 AM by Manish Kumar Singh

Life full of Talents and Skillz

Skillz is my current project, where I have been involved for over 6 months now. The core part of Skillz is to do a Talent Management while additionally it supports performance management.

This is a breed of very interesting project for me with lot of grilling, learning and testing one’s self Talent Quotient. We faced lots of challenges and kept working our ways through to achieve what we initially set out to achieve. With time the product evolved as we developed a stronger understanding of the requirements across industries and formed our own opinions on how these should be addressed. It has been a real interesting journey, delving into unknowns, digging out answers and putting it into implementations. I feel like sharing some of my experiences with Skillz here for benefit of all developers and architects, trying to decipher the same unknowns.

The Challenges

The First Challenge

On this project the biggest challenge was the need to correctly understand what Talent Management is and what is really expected of a Talent Management application. While researching, I found many articles and blogs explaining Talent management.

The problem with the information and articles out there is that it creates a fair amount of confusion between talent management and performance management. Both are fairly inter linked. So much so that at times it becomes hard to differentiate between the two. It is like you have been asked to differentiate between the words [opinion, attitude, belief and faith]. We compared few products currently available. Some of them were far from catering the actual need of talent management, while others offered a wide range of tools most of which, would be of no use to most organizations.

Only some were quite near to what was expected. There are quiet good articles out there on the web, worth mentioning here. Tony DiRomualdo in one of his article defines seven management practices that matters. He is in a view that for becoming a well rounded talent requires continuous learning and development of knowledge and skills. One of the articles published by Nasscom and written by Prof. Peter Cappelli, Center for Human Resources, University of Pennsylvania, explains the more subtle difference between Performance and Talent Management titled Talent Management is a business problem.

The Second Challenge

Another, challenge was about architecting Skillz, such that, it fits into the requirement posed by different industries. A skill itself varies hugely from industry to industry. To explain this, try comparing some common skills for a Doctor, Bank Manager and a Software Developer. Specializations for a doctor (like MD, MBBS etc), matters much more, than it does for a Bank Manager or a Software Developer. Similarly, Global Client Exposures for a Software Developer is more important than it is for a bank manager or for that matter, a doctor. Accounting exposures stands more important for a bank manager. Thus a common skill like education or experience needs different design for different industry/practices. This is because individual professions and verticals vary hugely from each other. This leads to a fresh challenge; the very fundamental nomenclatures used in the application, changes completely depending on which vertical the system is deployed in.  A classic example for this is the entity ‘user’. For every vertical where skillz is implemented, the very meaning and attributes for a ‘user’ changes drastically. Attributes like medical registration number and Medical Specializations make more sense for doctors than they do for developer or a bank manager. Rank/Grade does not imply to a doctor or a software developer.

Further, aspects like Security, Reporting, Usability together with the nature of Talent Management, additively, pushed the design of Skillz to a level of challenge.

Solving the challenges

Solving First Challenge

The first challenge took the major portion of our time; which was spent in   discovering the true nature and taste of Talent Management vis-a-vis differentiating it with performance. Talent Management is all about getting the right people with right skills into the right job by measuring the following quotients:

  1. Learning Quotient (LQ): Measures how an individual learns and improves
  2. Conceptual Quotient (CQ): Measures the ability of thought process in solving a problem.
  3. Relationship Quotient (RQ): Measures how an individual behaves in a group
  4. Action Quotient (AQ): Measures the individual as a team member by his actions.

For an individual the Talent Quotient (TQ) = (LQ+CQ+RQ+AQ) * Values.

Well, how do we measure it? I am sure our HR would be highly interested and can add another hundred paragraphs here about these quotients, process of measuring it, appraisal, questionnaires and many more.

Different companies have adopted different techniques to measure the TQ. The most common techniques  used are appraisals, interviews, trainings and feedbacks. But, seldom people understand the continuous nature and difference between the talent management and performance.

Now the most interesting part, Talent Management is not only about measuring TQ. It is about Identifying TQ, Acquiring TQ, measuring TQ, mentoring TQ and Retention of TQ. So where does Performance comes in? The answer is:  

TALENT MANAGEMENT + PERFORMANCE MANAGEMENT = PERFORMANCE

Put simply, tracking ‘performance’ is much more than most people think of it. It doesn’t start and end with performance management. Talent management which involves acquiring, goal setting, training, mentoring and retaining individuals also forms a huge part of tracking their performance.

Building a system which allows administrators and implementers to capture talent management and beyond was our initial design goal for skillz and after months of hard work, eating our own dog food and months of testing with a couple of beta customers, we believe we’ve come decently close to achieving it.

This solves the first challenge!

Solving Second Challenge

The second challenge was to design a system which fits into various industries catering to their unique needs. We decided to have a core system and extend it according to the organizational need. User, Skills, Activities, Trainings are entities within the system which are simple, flexible and easy to extend.

Security within individual organizations can be easily configured and tweaked by individual organizational administrators. Skillz is designed to be offered as a service (SAAS). For us this means easier deployments for all our customers and for our customers it means easy updates to newer versions as we continue to work on newer versions and add new functionality.

Skillz is a result of months of hard work, countless brainstorming sessions and a lot of thought that has gone into areas like security, reporting and usability. We’ve given special attention to extendibility so that customers can tweak skillz to fit their requirements.
 
The following diagram defines some interesting prepositions that are uniquely available in Skillz.

 

Skillz Features

Even though we’ve been using it within small teams @ eFORCE and with some of our beta customers, the official launch date for a public beta will be announced soon.

The entire team is very excited about its acceptance, performance and criticism in the world of PERFORMANCE. This release for me is the starting of the race which we struggled to qualify and it took us almost one full year.

I hope this article is helpful for those working in similar areas. I would keep posting more about Skillz as and when time permits.

Thanks,
Manish

posted @ 1/19/2009 12:39 PM by Manish Kumar Singh

Skillz Public Trial Is Expected To Be Out Soon.

Do you have baby pictures of your kids in yearly albums? Do you watch them every couple of months and get excited about how your kids have grown? Watching your employees grow is not exactly the same thing; but it can be fairly exciting. Getting involved in their growth is a rewarding experience too.

Skillz is your organization's continuous and ongoing ‘baby album’ for your employees, their competence, their technical skill-sets, their soft skill-sets and much more.

Besides being fun, watching your employees grow can have fairly positive impact on your overall organizational growth. After all, any organization worth it’s salt knows that it is only as good as the employees who work there.

We’ve seen skillz meet requirements from oil rigs in texas, to medical institutions and even banks.  Some of our teams use it to track increase in competency and growth within the team and they love it too.

As a software developer who initially led it’s design and development what particularly amuses me about Skillz is it’s ability to be highly configurable to meet the needs to multiple domains and industries. 

Not to turn this into a marketing blog; I’ll be doing a series of posts on features I love about Skillz and how we implemented configurability into the product.

The formal marketing website and a one month trial, just in case you want to try out the product, be coming out soon and will be announced formally pretty soon.

If you’re an existing customer, trial user to have a demo instance of Skillz you’re playing around with please feel free to leave a comment on this blog or send me an email about what you like and dislike about the product.

posted @ 12/19/2008 6:18 PM by Rajiv Popat

In the News...

The Popkomm Primer:  Sprechen Sie Deutsch?

Once again, Berlin is playing host to the annual Popkomm, a blended festival, conference, and music marketplace.  The mega-event always attracts a strong European crowd, though Americans, Australians, Africans, and Asians are also part of the action.  Just like Midem, that creates a more international tone, and offers something fresh for those trudging through repetitive conferences in the United States.

On the ground, the weather has been mostly crisp in Berlin, and the rains appear mostly gone for the week.  Expect average daily temperatures in the 50s Fahrenheit (10s Celsius), with some cloud cover and fog.  That sounds like fall, though anyone spoiled by warm climes like Miami, Los Angeles, or the Mediterranean will undoubtedly have to adjust.

Of course, markets are getting roiled, investments are going south, and credit pipelines are freezing.  Is anyone coming to this thing?  According to the conference organizers, Popkomm will host 843 exhibitors from more than 50 countries, though preliminary attendee figures were unavailable.  That is down slightly from last year, when exhibitors totaled 886, while attendees reached 15,400.

This year may also be healthy.  Most booked their flights months ago, and it still remains unclear how the economy will ripple through the music industry - positively or negatively.

That uncertainty affects startups, a group that always finds itself battling against a portfolio of problems.  Popkomm is featuring a slate of startups as part of a face-off called IMEA (Innovation in Music and Entertainment Award), which takes place today.  Startups will present, judges will judge, and everyone will experience some fresh faces and concepts.  This year, IMEA will feature Rawrip, Kyte, Independent IP, Roccatune, The Filter, and BMAT.

What else?  On the panel side, the slate includes all-too-familiar topics like online monetization and Radiohead, though the schedule also features debates on pan-European rights licensing, shifting legal terrains, secondary ticketing, automotive dashboards, and Asian and Eastern European markets.  Keynotes include BigChampagne cofounder Eric Garland; violin virtuoso Daniel Hope; movie director Wim Wenders; CISAC president Robin Gibb; IMMF chairman Petri Lunden; and Jamie Kantrowitz, senior vice president of Marketing and Content International for MySpace.

YouTube Trying eCommerce; iTunes, Amazon On Board

Labels are having an increasingly difficult time hating YouTube.  The Google-owned video behemoth is now jumping into ecommerce, starting with music.  Initial partners include Apple and Amazon, and the first crop of products include music downloads and games.  "This is a first step towards building a broader ecommerce platform for content partners and users on YouTube," the company explained in a morning briefing.

In that developmental light, the YouTube eCommerce Platform will soon include a broad range of partners across music, film, TV, and publishing.  The move represents a monetization stab beyond advertising, and the notoriously low CPMs that the site attracts.

The initial platform is being rolled out in the United States, though an international expansion will happen within months, according to the company.  In a typical scenario, videos viewed within the EMI Music channel would be accompanied by purchase links, both from the iTunes Store and AmazonMP3.  "Those partners who use YouTube's content identification and management system can also enable retail links on claimed videos that they choose to leave up on the site," the company explained in preliminary details.

Story by news analyst Alexandra Osorio.

[all articles by Digital Music News]

posted @ 10/8/2008 1:31 PM by Henrik Gehrmann

In the News...

Global Markets Under Serious Pressure; More Questions Surround Music

The now-global financial crisis dragged exchanges across Asia, Europe, and the United States on Monday, despite the recent passage of a massive bailout package.  During a roller-coaster day, the Dow Jones Industrial Average tanked more than 800 points, a one-day record that dragged the needle below 10,000.  The crater then prompted a late-day buying rally, leaving the exchange at a more mild, 370-point drop by the bell.

The US Treasury is now moving forward with an approved rescue package that exceeds $700 billion, though expectations of a successful resolution appeared baked into pre-Monday valuations.  Instead of gains, the market collectively expressed doubt that the bailout would reinvigorate markets, and indeed, some time will be required to unfreeze a tightening credit climate.

Music-related stocks were battered by the broader malaise, though the late-stage rally mitigated the declines.  Warner Music Group (WMG) slipped to $6.09 before recovering to $6.61, down 4.21 percent.  Apple (AAPL) had its ups and downs, dropping to a 52-week low of $87.54 before landing at $98.14, up 1.1 percent.  Sirius XM Radio (SIRI) continued to suffer, ending at just 50-cents.

Ahead of US-based trading on Monday, European and Asian indices offered a dreary prelude to the profound intraday drop.  Banking bailouts, stepped-up deposit guarantees and aggressive interventions are now part of the European reality, a serious confidence drain for investors.  Asian markets also stumbled, and Russia actually closed its markets prematurely.

The broader tale of woe is rippling into the music industry, though the exact fallout remains difficult to predict.  Issues related to consumer confidence undoubtedly impact the CD, already a tanking commodity.  Music-focused entrepreneurs may also be forced to scrape together funding from sources outside of Sand Hill, including benevolent angels and even credit cards.  The new reality could thin the field and slow the entrance of startups, though troubled markets are frequently weathered by profitable, financially-disciplined companies.

Permalink: http://www.digitalmusicnews.com/stories/100608markets


We Have Our Own Coalition, Thank You: British Stars Unite

Artists want more control over their digital careers, and now, they are banding together to gain that control.  Over the weekend, a coalition of British artists announced the formation of the Featured Artists Coalition, a growing group that includes Radiohead, Robbie Williams, Billy Bragg, Craig David, Sia, Travis, and Kaiser Chiefs.  "We want all artists to have more control of their music and a much fairer share of the profits it generates in the digital age," the group declared on featuredartistscoalition.com.  "We speak with one voice to help artists strike a new bargain with record companies, digital distributors and others, and are campaigning for specific changes."

The official coming out happened at the In the City Conference in Manchester.  The group is aiming to create legislative changes to give artists greater ownership of their works and build more transparent negotiation processes with labels and other business partners.

Those objectives transcend digital distribution and emerging formats, though artists carry far more clout in the current era.  Radiohead is leading the charge into independent format distribution and control, though the band carried considerable brand equity into their initiatives.  That always helps, though unknown artists can now cultivate targeted audiences, sell content directly, and develop revenue streams without the assistance of labels, part of a game-changing disruption that affects artists at all levels.


Second Life Lessons: Underestimate Niche at Your Peril

September roiled the recording industry, and tightening consumer wallets could spell a vicious fourth quarter.  That is part of a bigger, multi-year slide for major labels, a downward spiral driven by a tanking CD.

But not everyone is getting the doom-and-gloom memo, including EMI Music senior vice president of Digital Strategy Cory Ondrejka.  During a late-day keynote at Digital Music Forum West in Hollywood, Second Life cofounder Ondrejka offered a snappy, smart, and optimistic outlook for the beleaguered label.  Tossing words and phrases likecollaborative filtering , community formation, entrepreneurship, and crowdsourcing, the incoming brain focused on niche audiences, microtargeting, and rapid responses to consumer needs.  "Underestimate niche at your peril," Ondrejka urged.

But the coveted niche exists within a very, very large potential audience. "We basically have access to half of the earth," Ondrejka said, pointing to collective internet and mobile penetration rates that easily surpass three billion (1.2 billion internet users, 3.2 billion mobile users).  "We have billions of fans, and zero marginal costs."

If Ondrejka at times seemed like a digital dreamer, he also realistically pointed to a business model and cost structure that has been focused on big hits, big artists, and super-sized marketing campaigns.  But Ondrejka also placed emphasis on Long Tail theories throughout, and was clearly motivated to energize more focused audiences.  "Those artists way out on the curve are valuable, and this can be scary in a hit-driven world," Ondrejka said.  "The top of the curve is dropping faster than the market as a whole.  That is the curve flattening out, this is the Long Tail that Chris Anderson talks about.  The niche actually monetizes better, and if you doubt that, you should probably go check out eBay, or Google, or Second Life for that matter."

Of course, label revenues are clearly declining, though Ondrejka pointed to massive increases in music consumption, across both free and paid channels.  "This is actually a really great time, in some ways this is the best time ever to be in music," Ondrejka said.

Ondrejka was recruited by Douglas Merrill, an ex-Googler and EMI newbie who shares a similar digital brilliance and optimism.  The combination is certainly refreshing, though largely incongruent with technophobic strategies like file-sharing lawsuits and arduous licensing approaches.  Those touchy topics were left untouched, though the broader question is whether Merrill and Ondrejka can quickly solve an urgent monetization riddle.

Report by publisher Paul Resnikoff in Los Angeles.

[all articles by Digital Music News]

posted @ 10/7/2008 2:01 PM by Henrik Gehrmann

Treasury Sciences Web-Site Takes Its First Baby Steps

Treasury Sciences (Code Named: ITOPS) has been our flagship product in the Treasury and Finance Domain; something we've been working on for more than our two years. A product that has been helping our clients measure their Treasury accurately for the past year or so.

At eFORCE we're obsessed with answering the why's and when we started working on ITOPS the first question we asked ourselves was simple: Why should the world of treasury care about what we had to offer them?

Two years later; I think we've explained that 'Why' pretty well. I've heard many analogies but the one that comes closest to describing what ITOPS does and why the treasury world should care is described by our CEO:

"It's almost like a Fuel Gauge. You don't want to to show too much or too little. You expect it to be accurate because you rely on it."

A Major part of ITOPS is a Product Called CMO (code named: Seagull) which is what we often refer to as the “Treasury Gauge”. Relentlessly tweaking it and making it dependable is what we've been working on for the past couple of years.

If you are into Treasury or just interested in one of the things that we (and I personally) do for a living; check out our first humble website which is far from perfect.

It's not clearly an example of best website we can build; in fact to be honest, I don't love it all that much myself, but then, we were busy building this great product that you (and our existing customers) can depend on to make some really important decisions when it comes to treasury management and the website was not one of our biggest concerns. It's the product where most of our energy has been focused so far and we're sure our existing customers, having used our products in a production environment for months, will vouch for that fact.

The website was meant to give information about a product we (the development team, the clients who use it and everyone who is associated with it) love and I think it does a decent job at doing that.  It'll will continue to get better with time. In the meantime, If you are interested in what eFORCE does with this initiative or are in general interested in the Treasury and Finance space visit us, book-mark us and keep looking out for some exciting free services we are going to announce at the new website pretty soon.

We'll be doing more posts on these services as and when we announce them. For now feel free to check out our website and let us know what you think.

posted @ 9/29/2008 7:55 PM by Rajiv Popat

Dynamic Data Part1 - Your First Dynamic Data Website

Your First Dynamic Data Site
Microsoft’s .Net 3.5 SP1 of is here and it brings with it some of the most exiting enhancements in .NET 3.5. ASP.Net - Dynamic Data is one of them.  Dynamic Data is a scaffolding framework. It generates CRUD operations from your database schema. What gives an edge to Dynamic Data over some of the existing scaffolding frameworks (like monorail) is the fact that it is fully template driven and highly customizable.

Install .Net SP1

Download and install the .Net 3.5 SP1. You will find two new templates as you try to create a new website. These templates namely, DynamicDataEntityFrameworkWebSite and  DynamicDataLinqToSqlWebSite allow you to quickly create a dynamic data site.
   
   
DynamicDataLinqToSqlWebSite Template: Creates a Dynamic Data web application using a LINQ to SQL data model to generate the scaffolds.
DynamicDataEntityFrameworkWebSite Template: Creates a Dynamic Data web application using Entity Data Model (ADO.NET Entity Framework) to generate the scaffolds.
We will use the DynamicDataLinqToSqlWebSite for this example. Here we go …
 
   
1.
Let us create a Dynamic Data Website by choosing DynamicDataLinqToSqlWebSite template and call it MyDynamicDataSite. You will find that the WebSite has a folder called DynamicData, which has all the template controls and pages which will be used to generate CRUD operation on the tables.
 
 

 

 

2.

 Let us create our Data model using LinqToSql Classes. I have used “Company” database in this example. Let us call our LINQ to SQL class Company.dbml.

 
 

 

 

3.

The Final step is to enable scaffolding. This is done by un-commenting the following lines of code in the global.asax:

 
 

 

 model.RegisterContext(typeof(YourDataContext), new ContextConfiguration() {

ScaffoldAllTables = false });



 

 

 
 
 

Replace the YourDataContext with “your” DataContext that is with CompanyDataContext and turn  ScaffoldAllTables to true:

 
 

 

 model.RegisterContext(typeof(CompanyDataContext), new ContextConfiguration() {

ScaffoldAllTables = true} );

 
 

 

And that’s all you have to do. Run the site and see the magic.

You will find the Dynamic Data has generated CRUD operation on all the tables in your Data Model without you needing to write a single line of code.

It’s Amazing.

 
     

Conclusion:

This was a very simple “hello world” kind of demonstration of how ASP.NET Dynamic Data can provide with basic CRUD operations on your site in matter of minutes.

In future posts we will try to dive deeper into some of the concepts that’s been overviewed here.

Till then, happy programming!

   

posted @ 8/14/2008 3:37 AM by Anshuman Srivastava

In the News...

Opening Olympic Ceremony Hits Million-Mark on BitTorrent

Videos of the opening ceremony at the Olympics in Beijing have been downloaded more than one million times on BitTorrent, according to one estimate surfacing Tuesday.  BitTorrent-focused journal TorrentFreak reported the tally, citing a sample of BitTorrent trackers.

The most popular version of the ceremony is an HD-quality, 5GB file, a large download that flexes the distribution capabilities that BitTorrent offers.  An iPod-formatted version also topped the list.  The ceremony was widely available across television networks worldwide, and watched by more than one billion people across the globe, according to various estimates.


Lotta Apps: Apple Scores 60 Million iPhone App Downloads

Apple has now sold 60 million applications for its iPhone, an accomplishment that comes just one month after the second-generation device hit the market.  The App Store has produced sales of roughly $30 million, or $1 million daily, of which Apple takes a payout of 30 percent.  "This thing's going to crest at half-a-billion soon," Steve Jobs told the Wall Street Journal, referring to an annual run-rate.  "I've never seen anything like this in my career for software."

A large number of the Apps are free, though the combination of free and paid is rustling some cash.  On the free side, beneficiaries include Pandora, a free application that quickly became a favorite among early iPhone buyers.  Other gratis apps, including Tap Tap Revenge, have also stirred excitement.  The music-focused game, developed by Tapulous, awards users for tapping and shaking their iPhones to the beat.


Digital Music Provider Aims To Compete In Social Media Market

WaTunes.com, a leading digital content provider that helps music artists, record labels, and distributors sell their music on iTunes has announced its plans to enter the social media market with their new site WaTunes 2 scheduled to launch on September 1st of this year.

WaTunes 2 is a social media distribution service that provides not only digital services for music artists to sell their music on iTunes, but also welcomes the fans to listen to free music from the WaTunes 2 catalog, rate & comment their favorite albums, meet new friends, and download music on iTunes.


Kids discover music the new old-fashioned way

According to a report by the NPD Group, "Kids & Digital Content," 70% of kids in the "tween" age bracket (ages 9 through 14) are downloading digital music in an average month. A separate report from NPD estimates that while one million consumers dropped out of the CD buyer market in 2007, it was younger consumers who led that exodus. According to the report, 48% of U.S. teens did not purchase a single CD in 2007, compared to 38% in 2006.

But while both tweens and teens are moving online -- along with the rest of consumers -- to buy and acquire their music, they are still heavily influenced by the same sources that have always influenced them -- their peers, their parents and the media. The difference is that these influences are moving online, as well.

Along with the mainstream social networks Facebook and MySpace that kids and teens in the U.S. most  commonly use to communicate with their friends online, there are a number of other social music sites that are being used to make music recommendations and suggestions -- Last.fm, Pandora, iLike and Imeem, just to name a few. Earlier this month, another competitor in the social music space, social.fm, announced that it was folding. And with shakeups still ongoing in the online music industry, it is yet to be seen which sites will be long-term winners in the social music space.

[from digitalmusicnews.com , The Industry Standard, and Webnewswire.com]

posted @ 8/13/2008 2:27 PM by Henrik Gehrmann

In the News...

D: All Things Digital
    http://allthingsd.com/d/
Among those scheduled to speak are Microsoft's Bill Gates and Steve Ballmer, Facebook's Mark Zuckerberg, Sony's Howard Stringer, Time Warner's Jeff Bewkes, IAC's Barry Diller, and Amazon's Jeff Bezos.
    http://news.cnet.com/A-star-studded-cast-at-D6-confab/2009-7345_3-6240303.html

10-cent songs from lala.com
    http://next.lala.com/
Lala.com testing 10-cent “trapped in your browser” song rentals
    http://www.tgdaily.com/content/view/37659/113/
Free Music Now! Lala.com's Plan to Give Songs Away Could Upend the Industry
    http://www.wired.com/entertainment/music/magazine/15-11/ff_lala

Online library offers 1.5 million works and counting
    http://news.cnet.com/Online-library-offers-1.5-million-works-and-counting/2100-1025_3-6220358.html?tag=cd.top

Google shows touchy-feely Android phone
    http://www.webware.com/8301-1_109-9953924-2.html
Google I/O conference
    http://code.google.com/events/io/

posted @ 5/28/2008 6:16 PM by Henrik Gehrmann

In the News...

Economics of New Media: Pay to Play or Free?
http://mashable.com/2008/05/27/economics-of-new-media/


Who Will Control Your Digital Media?
http://gigaom.com/2008/05/22/who-will-control-your-digital-media


Pew: Internet Playing Minor Role in Music Buying Decisions

The internet has little sway over most music-related buying decisions, at least according to a survey released by the Pew Internet American Life Project.  "The internet helps music buyers connect with artists and learn more about music, but it doesn't strongly influence what or how they buy," the group asserted in a recently-published report.

In telephone surveys traversing several thousand adults, the group found that 83 percent of Americans discover music through terrestrial radio, movies, or television.  A total of 64 percent pointed to tips from friends and family, while another 56 percent pointed to online sources.

And when it comes to actual purchasing decisions, the survey showed that offline sources carry the greatest influence.  In fact, 51 percent responded that the internet carried no influence whatsoever on purchasing decisions, while 37 percent pointed to a minor impact.  A total of 12 percent pointed a major role, according to the survey results.

But post-purchase, fans generally started engaging with the artist more online.  Meanwhile, Pew cautioned against a premature dismissal of the CD.  According to the data, 82 percent of music buyers reported that most or all of their purchases were in the form of a disc.  That figure lessened somewhat to 69 percent among buyers under the age of 36.


AT&T Now Finishing 3G Deployment; iPhone Hovers

Exclusive iPhone carrier AT&T is now finishing its US-based, 3G (third-generation) network deployment, a move that comes alongside fresh iPhone release rumors.  On Thursday, the telecommunications giant indicated that its rollout should be completed at the end of next month.  AT&T has already implemented the network within 275 cities, and plans completion across a total of 350 municipalities.

Against that backdrop, Apple is expected to unveil its second-generation iPhone with stepped-up, 3G mobile broadband compatibility.  Recent rumors suggest a launch next month at the Apple Worldwide Developers Conference in San Francisco, an event that has featured various product launches in the past.  The improved AT&T network will deliver download speeds of up to 1.4 mbps, and upload speeds nearing 800 kbps.

posted @ 5/27/2008 1:24 PM by Henrik Gehrmann

In the News...

Napster Gets It Done: MP3s For Everyone

Napster is now offering its entire downloadable catalog as MP3s, a development that follows protracted licensing negotiations.  According to information shared early this morning, a catalog of roughly six million tracks has been transcoded into the unprotected format.  That means compatibility with the all-important iPod, previously a major obstacle for the company.

The DRM-free shift is an important one for Napster, a company that has struggled against compatibility problems since its relaunch in 2003.  But the bread-and-butter subscription service will remain protected, a critical component of the on-demand system.  That puts the shift into perspective, though the move away from DRM-protected downloads lifts a major negative associated with the Napster model.

Download pricing will remain at 99-cents per track, and $9.95 for most albums.

[Digital Music News]

posted @ 5/20/2008 12:29 PM by Henrik Gehrmann

Java One 2008, San Francisco, CA

Day One (Tuesday, May 6, 2008)

The Duke and the Elephant: PHP Meets Java™ Technology--the Best of Both Worlds

Ray Nicholson from IBM presented a session at JavaOne primarily focussing on PHP support. He demoed Project Zero and WebSphere. This session turned out to be a commercial for an IBM Product called WebSphere Smash. It has a PHP interpreter on a Java Application server (PHP5 language elements represented as Java objects). They came up with some neat ways to have PHP call Java and vice versa. He said that there is no PHP specifications to follow, and no real set of tests to check that the PHP code is behaving properly.

 

  • Why use PHP (fairly obvious)
  • Why use PHP+Java+Groovy: leverage the power and communities of all platforms
  • WebSphere sMash: Agile application web development using dynamic scripting and RESTful Web Services, RIA, Ajax/Dojo
  • They seemed to have implemented some kind of PHP 5 runtime over Java SE. It sounds very interesting and I’ll have to look into the licensing information.

 

 

 

JAX-RS: The Java API for RESTful Web Services

 

Marc Hadley and Paul Sandoz went over the basics of REST and then demoed examples using JERSEY. It’s great to see how annotations are easy to use. Apparently, Jersey can run as Java app without a web container.

 

 

Developing (J)Ruby on Rails Applications with the NetBeans™ IDE

1100 people attended that session!

 

http://weblogs.java.net/blog/jfarcand/

Grails in depth

Grails is great for agile dev and quick proof of concept projects

 

 

Day Two (Wednesday, May 7, 2008)

 

Asynchronous Ajax for Revolutionary Web Applications

 

 

 

 

JRuby on Rails: Web Development Evolved

One of the best sessions. Ola Bini from Thoughtworks did a nice presentation (basics of Ruby, RoR, JRuby and JRoR) and demo of JRoR.

 

1.       Ruby

Pure OO with dynamic typing; blocks are anonymous methods you can pass around and invoke and modules are like interfaces (namespaces)

2.       JRuby: Java platform implementation of the Ruby language

Faster than Ruby, real native threads, full compilation (ahead-of-time and just-in-time), Java into Ruby and vice versa

3.       RoR: MVC framework, single-threaded and shared-nothing design, DRY

 

 

 

 

 

 

 

 

 

Day Four (Friday, May 9, 2008)

Detecting and Defending Against Security Vulnerabilities for Web 2.0 Applications

Web 2.0 easier to hack than web 1.0: Google finds 2 millions of malicious sites.

Use tools to detect. No one tool will catch all; need to use them all.

Use defensive coding and testing tools.

 

posted @ 5/19/2008 2:37 PM by Adrien Wiesebron

In the News...

Pennywise, Poundwise: MySpace Free Experiment Pays Off

Major labels have been fighting against free content distribution for years.  But a number of established artists are embracing the gratis giveaway, and driving dollars into more controlled areas.

The biggest players in this discussion are Radiohead, Trent Reznor, and most recently, Coldplay.  But others, including Pennywise, are also pushing gratis concepts and helping to define best practices in the process.

In March, Digital Music News reported that the band attracted 500,000 takers on a free album giveaway driven by MySpace Records.  That figure eventually notched to 640,000, according to MySpace, though 400,000 actually completed the process to secure the MP3s.  "On top of the 400,000 downloads, we've scanned over 20,000 albums in the US and another, roughly 25,000 overseas," MySpace Records executive J. Scavo told Digital Music News on Friday.  The giveaway officially ended in April.

The campaign involved a sponsorship tie-in with Textango, a mobile-based billing and download delivery platform.  Scavo also noted that the band was paid for their participation, a move that helped to allay fears of traditional product cannibalization.

Now, the band is seeing some meaningful results, boosted by the MySpace project.  That includes a well-charting single, and according to Scavo, significant jumps in concert tickets, tour guarantees, and merchandise sales.  After playing sold-out dates in Japan and Australia, the group is now hosting shows in the United States through mid-June.  And the band is being factored into the Vans Warped Tour this summer.  "If you ask them, their career has been revitalized far beyond their expectations," Scavo said.

Unlike the Radiohead and Reznor campaigns, the Pennywise initiative did not include a paid option, closing off potential recording revenue from willing buyers.  And looking forward, the next steps are somewhat uncertain.  Scavo could orchestrate another pet project with similar parameters, though broad-scale participation by major labels in MySpace Music could complicate future initiatives.

MySpace is now planning to premiere the video for the lead single, "The Western World," on May 21st.  The album, Reason to Believe, comes roughly twenty years after the band first formed in Southern California.


Reformed, Ad-Supported Deezer Grabs Universal Catalog

Is ad-supported content the answer to monetizing music online?  Interesting question, though testing the hypothesis requires serious capital, lengthy licensing negotiations, and an unhealthy dose of litigation.

Upstarts like Qtrax, Spiralfrog, and We7 are leading the charge, though others are also bubbling.  That includes Deezer, a Paris-based, ad-supported startup that just secured the licenses to Universal Music Group content.  According to the company, the deal is international in scope, and boosts the catalog total by one million.

The deal may have carried elevated licensing costs, thanks to a checkered past.  Deezer, formerly known at Blogmusik, was unceremoniously shut down following a swirl of infringement charges.  The revamped service was launched last year, and also carries content from Sony BMG.   In total, Deezer claims a catalog total of 2.5 million, and an active user base of roughly 2 million.


Amazon MP3: Freshly Portable, Totally Widgetized

Like many other heavyweights, Amazon is pushing outside its traditional walls.  Last week, the company announced the availability of its Amazon MP3 Clips Widget, part of a broader multimedia portability push.  The widget allows site owners to embed clips of songs into their destinations, either hand-picked or dynamically selected by Amazon.

That boosts an existing affiliate program, one that gives site owners a 10 percent cut on referred sales.  Among the early takers is the Hard Rock Hotel & Casino in Las Vegas, which is tying the widget into its concert listings.  Others are already directing ecommerce action towards Amazon MP3, including Last.FM.

Other Amazon widgets are tied to Kindle-compatible ebooks and video content from Unbox.


[articles written by Digital Music News, Daily Snapshot, Monday, May 19, 2008]

posted @ 5/19/2008 2:18 PM by Henrik Gehrmann

CommunityOne Convention Notes

2008-05-05 Wrap up from CommunityOne conference

Session: Open Sourcing Music
Summary: The panel discussed java-based music development. It noted that overall bandwidth is up, the demand for multi-media is rising, and the complexity of implementing functionality is down. It supports an open source approach, because more people contribute, it is easier to capture new ideas, and source code becomes stable quicker. Drawbacks mentioned included legal issues w/playback, and reliance on other projects.

Resources of interest: jFrets

Session: Website into OpenSocial Container
Summary: NetBeans is supporting easy widget implementation and deployment. It is possible to drag a widget into a live webapp. A widget can be implemented in both JSP and PHP. There was a "Project Socialsite" demo that illustrated some of the main concepts.

Resources of interest: OpenSocial RO; Apache Shindig (incubator.apache.org/shindig); socialsite.dev.java.net (release planned for October)

Session: PHP/RIA
Summary: Discussion about AJAX development challenges, including the reduced latency (RIA's usually require lots of asynchronous web requests), lack of a 'push' model on the web (e.g. for stock price applications), and that traditional web servers are not designed for these kind of operations. Outline of the Comet model and Bayeux protocol (using the Dojo ajax toolkit) as a possible solution. Current issues encountered are that there is no de-facto standard, that the HTTP connection can be cut by firewalls (i.e. after long idle times), and that the browsers/servers are not optimized for this model.

Resources of interest: Zend (php)

Session: Async AJAX for Revolutionary WebApps
Summary: Panel focused on development of Web 2.0 applications, specifically using so-called 'AJAX push' models. It mentioned frameworks and technologies such as NetBeans, Comet, Dojo, DWR, ICEfaces (combining JSF and AJAX), and GlassFish (a webapp server). Web 2.0 was described as "by the people, for the people", where content is mainly provided by users. It could also be called the "participation age", with examples given the development of open source software, eBay auctions, Wikipedia, Flickr and YouTube. Typcial signatures of Web 2.0 are a collaborative environment, interaction, and a powerful UI. One of the speakers announced that "AJAX is a state of mind".

Most web applications are still typically synchronous, where user events are given preference, and browser lock-ups (page-loads) are avoided. A fully asynchronous model would allow updates to be pushed from the server at all times. This is called "AJAX push", or "Reverse AJAX". AJAX Push is responsive (event driven; no frequent polling), and usually low-latency. Example applications are Meebo, jotLive, KnowNow, 4homemedia, and Gtalk. The main models are standard Ajax (polling), Ajax Push (long polling), and Ajax Push (streaming). Looking at the network level, Ajax Push basically waits for an event on the server side after a request has been made, before sending the response.

The idea is to keep an open connection, i.e. not to respond to initiating requests, and wait for events on the server-side. Polling means that the connection is keep-alive. There is no JavaScript-threading, so polling might timeout. This is also called "the long response" from the origninal 1999 push model. Long polling can be understood as HTTP message-flow inversion, where a 'GET request' is followed by a 'wait for event' and then returns a 'Response with update'. A different approach would be using the JSON publication/subscription model, which would offer good performance, but less security.

On the server-side, one of the main questions is , can push scale? Connections are basically in a waiting state, which means that additional memory is consumed by each blocked thread. Having the JVM to scale to 10k threads is not efficient. A technology solution would be a new I/O (NIO), which supports non-blocking sockets.

Server-side AJAX push would require functionality, such as asynchronous content handlers (R/W), suspendible request (suspend/resume), and a support delivery guarantee mechanism (i.e. which pushes data from one connection to another, and aggregates data before pushing it).

A future standard for these challanges is currently under way by the JSR-315 expert group.

Resources of interest: ICEfaces; GlassFish; Grizzly; Dojo; Servlet 3.0, iSpaces, WebMC, Jetty, Resin, jMaki demo, DWR

posted @ 5/19/2008 2:14 PM by Henrik Gehrmann

Showing Reports by ReportViewer Control and NHibernate

Showing Reports by ReportViewer Control and NHibernate

In one of my Projects I was told to show some data using ReportViewer control and NHibernate. I had no idea how to do it.  Started Googling.... But I was quite surprised there was no such postings, even not found any information whether it is possible or not ! Never mind, started doing it and after completion found it pretty simple. Would like to share it with you.

Step 1:

 I am using a single table, say Customers with the following schema :

Customers

  CustomerID int IDENTITY(1,1) NOT NULL,

  FirstName nvarchar(50) default NULL,

  LastName nvarchar(50) default NULL,

  Address nvarchar(150) default NULL,

  PRIMARY KEY (CustomerID)

The Business Class is:

Customer.cs
namespace NHibernate.Example

{

    public class Customer

    {

        public Customer()

        {

        }

 

        private int id;

        private string firstName;

  private string lastName;

        private string address;

 

        public virtual int Id

        {

            get { return id; }

            set { id = value; }

        }       

 

        public virtual string FirstName

        {

            get { return firstName; }

            set { firstName = value; }

        }

       

        public virtual string LastName

        {

            get { return lastName; }

            set { lastName = value; }

        }

       

        public virtual string Address

        {

            get { return address; }

            set { address = value; }

        }                 

    }

}

And Here is the Mapping file:

Customer.hbm.xml
 <?xmlversion="1.0"encoding="utf-8" ?>
 <hibernate-mappingxmlns="urn:nhibernate-mapping-2.2">
 
 <class name="NHibernate.Example.Customer, NHibernate.Example"
            table="[NHibernate_Test].[dbo].[Customers]">
 
      <id name="Id"column="CustomerID"type="Int32"unsaved-value="0">
      <generatorclass="native" />
      </id>
      <propertyname="FirstName"column="FirstName"type="String" />
      <propertyname="LastName"column="LastName"type="String" />
      <propertyname="Address"column="Address"type="String" />
           
 </class>
 </hibernate-mapping>

Step 2:

We have to create a Typed Dataset in App_Code folder of our Website (or you can have your separate Project Library for DataSet). The data table of this DataSet will contain the fields which we want to show in our Report. Here, I would like to show all the fields of my Customers table. Therefore my Dataset looks like this :

Step 3 :

Create a RDLC file. Arrange the fields just by dragging and dropping the fileds of Dataset which you will find from "Website data Sources" toolbar (to view this toolbar just click the RDLC body, go to the menu "Data" --> "Show Data Sources").

Step 4:

Now the whole environment is ready for coding. Just add a ReportViewer to an aspx page and use the following code and you are done to throw some data on your screen!

using System;
using System.Collections;
using Microsoft.Reporting.WebForms;
using NHibernate;
using NHibernate.Example;
 
public partial class CustomerReport : System.Web.UI.Page
{
    DataSet1 ds = new DataSet1();
    NHibernate.Cfg.Configuration newConfig = new NHibernate.Cfg.Configuration();
    ISessionFactory sFactory;
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            newConfig = newConfig.AddAssembly("NHibernate.Example");
            sFactory = newConfig.BuildSessionFactory();
 
            rvCustomer.LocalReport.ReportPath = "TestReport.rdlc";
            rvCustomer.LocalReport.ReportEmbeddedResource = "ReportViewer.TestReport.rdlc";
            rvCustomer.LocalReport.DataSources.Clear();
 
            ISession session = sFactory.OpenSession();
           
            //get the list of customers using NHibernate
            IList customers = session.CreateCriteria(typeof(Customer)).List();
 
            //populate the typed Dataset
            foreach (Customer customer in customers)
            {
                ds.Customers.AddCustomersRow(customer.Id.ToString(),
                                             customer.FirstName,
                                             customer.LastName,
                                             customer.Address);
            }
           
            rvCustomer.LocalReport.DataSources.Add(
                new ReportDataSource("DataSet1_DataTable1", ds.Customers));
        }
          // data Source name "DataSet1_DataTable1" generally made by DataSet name + "_"
          // + DataTable name of the DataSet
     }
}

Finally the Output :

Run the above page and you will see all the data of Customers table.

-------------------------------------------------------------------------

Hope this information will help somebody somehow !

posted @ 5/5/2008 6:54 AM by Koushik Das

And Then There Was An Application Restart!

Escaping an Asp.Net application restart.

Tired of your Asp.Net application restarting frequently? Is something stopping you from updating your configurable settings whenever you want? May be you need to restructure few things.

Read out few of the reasons that can cause an application to restart along with their probable fixes. May be it will help you fix or structure your application well in advance.

Read here


posted @ 4/26/2008 1:17 AM by Rohit Jain

Handling binary data with Web Service Enhancements 3.0

Handling binary data with Web Service Enhancements 3.0
In one of my recent projects, I needed to expose a web service to upload some files to the server. Hence, decided to use array of bytes to transfer contents of these files over the wire. The problem, however, was the fact that these files were as huge (at times even ten’s of MBS). Sending and receiving these huge arrays of bytes over the web was a real pain in the neck. Thanks to Microsoft’s Web Service Enhancement (WSE) 3.0 which proved to be the perfect answer to our problem.
In this article we will examine how easy and efficient it is to send and receive large binary data using WSE 3.0. WSE 3.0 uses MTOM encoding and does not require any form of SOAP attachment. If you have not downloaded WSE 3.0 yet, you can do the same from here. We have used C# as the language and Visual studio 2005 as the IDE in the example that follows.
Create a Web service which Uploads/download large binary data
1.    Create a web service called FileUploadService using visual studio 2005.
2.    Add two methods called UploadFile and DownloadFile
 
 
[WebMethod]
    public void UploadFile(string fileName, byte[] fileData)
    {
        string filePath = Server.MapPath("Uploads");
        filePath = filePath + @"\";
        File.WriteAllBytes(filePath + fileName, fileData);
    }
 
 
[WebMethod]
    public byte[] DownloadFile(string fileName)
    {
        string filePath = Server.MapPath("Uploads");
        filePath = filePath + @"\";
        return File.ReadAllBytes(filePath + fileName);
    }
 
Make your service WSE enabled
1.    Install WSE 3.0.
2.    After the installation is complete, right click on the web service project and select WSE Settings 3.0 from the context menu.
3.    From the displayed dialog and on General tab select the Enable this project for Web Services Enhancements check box and Enable Microsoft Web Services Enhancement Soap Protocol Factory check box and click OK.
 
 
4.    In your web.config, you’ll notice that a new configuration section is added:  
 
<configuration>
 <configSections>
 <sectionname="microsoft.web.services3"
          type="Microsoft.Web.Services3.Configuration.WebServicesConfiguration,  
              Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral,   
              PublicKeyToken=31bf3856ad364e35" />
 </configSections>
 ...
</configuration>
 
A reference to the Microsoft.Web.Services3 assembly is added  
 
 
 
<assemblies>
      <addassembly="Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral,  
        PublicKeyToken=31BF3856AD364E35" />
</assemblies>
... 
 
Under the system.web element, the <webServices> configuration element is defined. Here the Web service is configured to use the Microsoft Web Services Enhancement Soap Protocol factory WseProtocolFactory which is defined by the <soapServerProtocolFactory> configuration element under the <webServices> element. This is a must for a web service to be able to use WSE 3.0. ...  
 
 
 
<webServices>
      <soapExtensionImporterTypes>
            <addtype="Microsoft.Web.Services3.Description.WseExtensionImporter,   
        Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral,   
        PublicKeyToken=31bf3856ad364e35" />
      </soapExtensionImporterTypes>
      <soapServerProtocolFactorytype="Microsoft.Web.Services3.WseProtocolFactory,  
          Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral,   
          PublicKeyToken=31bf3856ad364e35" />
</webServices> 
 
Enable a Web Service to Send and Receive Large Amounts of Data
Select Messaging tab from the dialog. On MTOM Settings ensure that Server Mode is set to optional and click OK.
Following Server Mode option are available:
·         In optional mode the WSE processes the incoming SOAP messages whether or not they are MTOM encoded. With optional the client is the one who decide whether to use MTOM or not, if the client application request to use MTOM the web service will use MTOM.
·         In always mode all incoming and outgoing SOAP messages must be MTOM encoded. When a SOAP request is received that is not encoded using MTOM, an HTTP error 415: "Media unsupported" is returned to the sender.
·         In never mode all incoming SOAP messages must not be MTOM encoded. When a SOAP request is received that is encoded using MTOM, an HTTP error 415: "Media unsupported" is returned to the sender.
 
 
Again open the web.config file and review the changes made by the WSE 3.0 configuration tool. You’ll notice the following:
 
A <messaging> configuration element is defined under the <microsoft.web.services3> configuration. This is used to specify the MTOM options.
 
<microsoft.web.services3>
      <messaging>
            <mtomserverMode="optional" />
      </messaging>
</microsoft.web.services3>
 
 
Create a client Application
1.    Create an asp.net website.
2.    Add a fileUpload control and a button control to the default page.
 
 
 
<formid="form1"runat="server">
 <div>
   <table>
      <tr>
            <td>
                  Choose a file
            </td>
            <td>
                  <asp:FileUploadID="filUpload"runat="server"/>
            </td>
            <td>
                  <asp:ButtonID="btnUpload"
                  runat="server"Text="Upload"
                  OnClick="btnUpload_Click" />
            </td>
      </tr>
   </table>
 </div>
</form>
 
 
Make the client Application WSE-enabled
1.    Right click on the website ans select WSE 3.0 properties. From the displayed dialog and on General tab select the Enable this project for Web Services Enhancements check box and Enable Microsoft Web Services Enhancement Soap Protocol Factory check box and click OK.
 
 
2.    In the Messaging tab, specify client Mode as “On” and Server Mode as “always”. By spcifying client mode “on”, we indcate that the configuration is for the client and Server Mode “always” means that all incoming and outgoing SOAP messages must be MTOM encoded.
 
Call the Web service
The client now is ready to call the WSE-enabled FileUpload/FileDownload web-method. Drop in the following code:
 
private void UploadFile()
{
   FileServiceWse service = new FileServiceWse();
   service.UploadFile(filUpload.FileName, filUpload.FileBytes);
   Response.Write("File uploaded.");
}
 
 
 
Conclusion
Here was an attempt to share my first exciting encouter with Microsoft's WSE 3.0. The idea was to illustrate how easy and efficient it is to use the WSE 3.0 to handle large volume of binary data over the web. Hope you guys find this effort useful .
 
 

posted @ 4/22/2008 7:25 AM by Anshuman Srivastava

2 most important TLAs every technologist should respect

What do you think are the most important TLAs  in technology?

Do you think it is SOA since we all are interested in decoupled services? or EAI or ESB?
If you think it is ERP, you are kinda outdated. What about JVM, JRE...I could go on.

But really the two most important TLAs we as technologist need to remember are TCO and ROI. Yes, these are not really technical you say, but hear me out.

We are in business technology. The goal of a business is to make $$$ (and on the way help out on good causes). Technology helps business in two ways, either your revenue model is based on the technology or technology enables you to run your business efficiently and cost effectively, thus adding to the bottom line.

So, here are the basics:

TCO - Total Cost of Ownership (sometimes it is used as Total Cost of Operations), as a name explains gives an idea on what the total cost of ownership of a particular product or technology is. This should include the upfront investments (hardware, software), people cost, process costs and maintenance, growth, support and upgrade costs. Last but not the least, what will an organization spend to get out of a particular technology i.e. the migration costs in the future or retire it in the future.

ROI - Return on Investment. Now that you know your TCO, what is the this technology giving back to the business. For a CRM system, can you quantify how much more $ your sales force generate in revenues and how much time they will save by streamlining their processes? If you cannot quantify your returns, than go back to your sponsors and ask them for the drivers for this technology investment.

posted @ 4/10/2008 12:02 AM by Shakeel Rashed

About me - Technologist, Entrepreneur and Coach

I wear these three labels proudly. I have been with eFORCE for 5 years now. Prior to that, I had started a telecom software company and lost my shirt on it, risking a lot more than I should have and prior to that I worked at companies such as Trilogy, Cambridge Technology Partners, Noblestar where I consulted on the technology du jour with some the best known fortune 500 companies in US and Europe.

I am technologist. I can talk pros/cons on most systems, articulate software architectures and design, and every now and then astonish people with my hands on capabilities. I am keen observer of social nature and how technology has helped create the current euphoria around gadgets, connectivity and our digital lifestyle.

I am an entrepreneur at heart. I would have a tough time fit into a large corporation playing save my fiefdom game. That is why eFORCE has appealed to me for so long.

I am a coach. I enjoy mentoring and to challenge people to get to their true potential. I have had my success stories and failures which I hope I have learned from.

So, I will try to write on these three topics and how it effects our business and businesses that we work with. Feel free to contact me if you have any questions or comments.

p.s: I run a blog on cloud computing called Cloud Insight, do visit that if you are interested in this latest mantra

posted @ 4/9/2008 11:34 PM by Shakeel Rashed

Introduction to Sling

Sling is a Web application framework based on REST principles that provides easy development of content-oriented applications.

Sling uses a JCR repository, such as Apache Jackrabbit, as its data store.

Sling started as an internal project of Day Management AG and has been contributed to the Apache Software Foundation and is currently undergoing incubation.

The main purpose of Sling is to develop a content-centric Web Application framework for Java Content Repository (JCR) based data stores.

Getting started with Sling

Pre-requisite
 

  1. A Subversion client to get the Sling code
  2. A Java 5 JDK
  3. Maven ( > V 2.0.7)
  4. cURL to create content

 
Setup & Install


Check out the code from Subversion repository: 

 http://svn.apache.org/repos/asf/incubator/sling/trunk sling

 This creates a directory named sling under the current directory, with the completed Sling source code.

 In the top-level sling directory that was created by the svn command, run:

 
mvn clean install

 
This builds and tests all the Sling modules that are required to run the Launchpad.

 
If you don’t want to test the modules and just build them then you can run:

 
mvn clean install -Dmaven.test.skip=true

 

Start the Launchpad

 
Change to the launchpad/webapp directory under the top-level sling directory, and run:

 
mvn jetty:run


When server starts successfully it shows a message like this:

 

 
 
By default, Jetty is configured to run on port 8888.

 Look at http://localhost:8888/sling where Sling displays the Sling Management Console page.

 Sling Management Console Page will look like this:

 

 

In case of any error / issue, look into logs at below URL.

 ../launchpad/webap/target/sling/logs/error.log

 Create some content

 To create a content node (nodes are a JCR concept, a unit of storage) with cURL, use:

 curl -F"sling:resourceType=foo/bar" -F"title=some title" http://admin:admin@localhost:8888/content/mynode

 

  • the entire command should be in single line

 
You can check the node at http://localhost:8888/content/mynode 

 It will show you a page like this:

 

 You can see the node, content, resourcetype and other files at WebDAV client. Login with admin/admin.

 WebDAV client URL: http://admin:admin@localhost:8888/dav/default/

 It will show you a repository like this:

 

 

 You can use cURL to create directories.

 curl -X MKCOL http://admin:admin@localhost:8888/dav/default/apps

curl -X MKCOL http://admin:admin@localhost:8888/dav/default/apps/foo

curl -X MKCOL http://admin:admin@localhost:8888/dav/default/apps/foo/bar

 
Example 1:

 
I will create a resourceType.

I will create a content node.

I will render the content through resourceType.

 
Creating resourceType

 
Run below command

 
curl -X MKCOL http://admin:admin@localhost:8888/dav/default/apps/example1

 
curl -X MKCOL http://admin:admin@localhost:8888/dav/default/apps/example1/examplepage1

 
It will create a resourceType of example1/examplepage1
 

Create a HTML script which will use JCR data

html.esp

 
<html>

  <body>

    <h1><%= currentNode.title %></h1>

            <h2>This is testing for Sling:Resources</h2>

  </body>

</html>

 
Upload it to example1/examplepage1 resourceType

 
curl -X PUT -d @html.esp http://admin:admin@localhost:8888/dav/default/apps/example1/examplepage1/html.esp

 
Create content based on resourceType example1/examplepage1

 
curl -F"sling:resourceType=example1/examplepage1" -F"title=Example Title" http://admin:admin@localhost:8888/content/examplecontent

 
Render the content

 
You will see the content like this:

 

 

If you want to include some other esp in your html.esp file then you can include in like this:

 <html>

  <body>
    <div id="header">
      <% sling.include("/content/header"); %>
    </div>
    <h1><%= currentNode.title %></h1>
  </body>
</html>

 

  • header.esp is a different esp file

 

 We still do not have any complete solution / example but there are some sample scripts and servlets in the sling/sample module in the source tree. Going forward we may use them to do some more R&D on this.

 Below are few URLs which might be useful if you are looking for more information.

 

 Detailed project status:

http://incubator.apache.org/projects/sling.html


Detailed information on REST:

http://en.wikipedia.org/wiki/Representational_State_Transfer 

 
Detailed project information:

http://incubator.apache.org/sling/site/project-information.html

 
Documentation on Sling:

http://incubator.apache.org/sling/site/documentation.html

posted @ 3/19/2008 7:48 AM by Nitesh Ambuj

MVC Routes For Dummies

We've been working on evaluating the Microsoft MVC framework and using it for internal projects like the Appraisal System. I've been highly impressed with it's flexibility, simplicity and elegance. For all those who attended my recent training on it, I'm sure you would agree.

For all those who find the whole idea of taming routing with the MCV framework confusing I've posted a detailed step-by-step explanation of the topic here.

posted @ 3/17/2008 7:55 AM by Rajiv Popat

RSS Feeds RSS (list of recent posts)
Blogs - 32
Posts - 60
Articles - 1
Comments - 104
Trackbacks - 8

Rajiv Popat
(12, 6/28/2009 8:29 PM)

Henrik Gehrmann
(8, 10/8/2008 1:31 PM)

Anish Biswas
(6, 3/27/2008 4:11 AM)

Devang Shah
(5, 11/25/2009 8:30 AM)

Darrel Karisch
(4, 5/20/2010 12:54 PM)

Rajarshi Dutta
(3, 3/28/2007 1:06 PM)

Rohit Jain
(3, 4/26/2008 1:25 AM)

Indrani Basu
(2, 2/13/2008 11:47 AM)

Manish Kumar Singh
(2, 3/6/2009 2:38 PM)

Nitesh Ambuj
(2, 1/6/2010 2:09 AM)

eFORCE Blogs Team
(2, 11/16/2006 2:25 AM)

Shakeel Rashed
(2, 4/10/2008 10:56 AM)

Thanesh Sadachcharan
(2, 12/5/2006 11:45 AM)

Anshuman Srivastava
(2, 1/28/2009 6:00 AM)

Koushik Das
(1, 5/5/2008 7:43 AM)

Kamal Raj Ramalingam
(1, 2/22/2010 9:07 PM)

Adrien Wiesebron
(1, 5/19/2008 2:37 PM)

Rafiq Abdul
(1, 4/28/2009 5:29 PM)

Arunava Basak
(1, 4/25/2007 2:46 AM)