Before we address the question, let's discuss how UDP port scanning is typically done.
When a host receives a UDP packet, what is supposed to happen is that if the host isn't listening on that port, it should reply with a ICMPPort Unreachable (ICMPType 3, Code 3). If it is listening on that port, the packet contents are fed to the listening application and processed. If the application does not understand the packet contents, it might reply with an error, but most likely will drop the packet and not reply at all.
If there is any kind of a firewall involved, either on the host itself or in the network path, then quite often no reply at all will be received for the sent packet.
So an open port and a port protected by a firewall will often look the same to a scanner. This can be a real problem when scanning UDP ports, as ports listening with a running service will look exactly like firewalled ports, which of course do not have a service available to the scanning station.
What UDP Protocol Awareness brings is a better payload. With protocol awareness, a scan of the UDPDNS port for instance (udp/53), might be a an actual dns request. A scan of an NTP (network time protocol) port could be an NTP timestamp or time request. The application receives a valid packet, and if there is a listening port, a valid response is sent back to the scanner, and the scanner can now know for certain that this port is open!
To illustrate - first, let's scan an NTP (Network Time Protocol) server's NTP port with an older version of Nmap (5.0). This behaviour is typical of most port sc
C: nmap -sU -p123 192.168.122.254
Starting Nmap 5.00 ( http://nmap.org ) at 2010-01-28 13:17 Eastern Standard Time
Interesting ports on 192.168.122.254:
PORT STATE SERVICE
123/udp open|filtered ntp
MAC Address: 00:17:0E:0C:B7:61 (Cisco Systems)
Nmap done: 1 IP address (1 host up) scanned in 1.91 seconds
As you can see, the port shows as open/filtered. From the packet trace below, you can see that an emtpy packet is sent to udp/123, no valid NTP data is contained, and the NTP server simply drops the packet. There really is an NTPserver running, but there's no way to tell for sure using this method of scanning.
Now let's run the same scan with Nmap 5.2, which has UDPprotocol awareness.
C:nmap -sU -p 123 192.168.122.254
Starting Nmap 5.20 ( http://nmap.org ) at 2010-01-21 22:15 Eastern Standard Time
Nmap scan report for 192.168.122.254
Host is up (0.0019s latency).
PORT STATE SERVICE
123/udp open ntp
MAC Address: 00:17:0E:0C:B7:61 (Cisco Systems)
Nmap done: 1 IP address (1 host up) scanned in 6.88 seconds
The difference is immediately apparent, the port now has a state of open, instead of open/filtered. Let's take a look at the packet and see exactly why ..
As you can see, Nmap is sending an actual NTP client timestamp of the NTP server, and it gets an NTP server response back. This identifies both the fact that the host is actually listening on that port, as well as the fact that it's an actual NTP service that's listening.
Currently NMAP 5.21 supports protocol specific payloads for:
udp/7 echo
udp/53 domain
udp/111 rpcbind
udp/123 ntp
udp/137 netbios-ns
udp/161 SNMP
udp/177 xdmcp
udp/500 ISAKMP
udp/520 route
udp/1645 and udp/1812 RADIUS
udp/2049 NFS
udp/5353 zeroconf
udp/10080 amanda
This is an exciting development, allowing us to scan these particular ports with a LOT more accuracy than previously possible. Again, Fyodor and the NMAPcrew have replaced a number of other tools simply by adding some new features to NMAP - great job!
=============== Rob VandenBrink, Metafore =================
In recent years, we've seen increased energy put into web extensibility platforms. These platforms let distributed developers collaborate to produce new kinds of interactive features on websites and in the web browser itself. Because these platforms frequently enable data-sharing between multiple distinct organizations, and often sit between two completely different security domains (desktop vs. web), the security and privacy issues that arise are complex and interesting. This post explores some of that complexity: both the current state of platforms that extend the web and their associated security challenges.
Plugins, Extensions, and Mashups: A Primer
The extension platforms of the web today exist at every level of the technology stack. First there are mashup platforms, which include Facebook Apps, Google Gadgets, and YAP Apps, built on Yahoo!'s Application Platform. All these platforms are abstractions that allow developers to embed content within a host site. Often this content has a level of dynamism and interactivity that exceeds what is expected of "content" — so they're called "Applications" or "Gadgets."
A deeper type of extensibility occurs in web replacement technologies. Examples include JavaFX, Adobe Flash, Microsoft Silverlight, and Google Chrome Frame1. These technologies leverage exisiting hooks in browsers to replace native rendering and scripting technologies from the browser vendors with new environments that claim to offer a variety of benefits.
In addition to web replacement technologies, there's the related area of web augmentation technologies. These use hooks exposed by browser vendors to bolt on native code, however, unlike replacement technologies, these tools attempt to expose new scriptable facilities to browser-based JavaScript. (Google) Gears, (Yahoo!) BrowserPlus, Mozilla Geode2, and Loki are some prominent recent examples of such technologies. At the fringe of this category, there are several projects that abstract different replacement and augmentation technologies to provide feature focused abstractions. Prominent examples include include SVG Web for cross browser SVG support and the YUI Uploader for in-browser content upload with in-page feedback.
The existence of both replacement technologies and augmentation technologies for the web is made possible by the browser vendors themselves, who generally expose two different ways of extending the browser.
Browser plugins were originally intended to allow 3rd parties to add support to the browser so as to handle new types of content. They have since evolved into a rich means of embedding scriptable code into browsers, code that may (optionally) render in the browser's content area. (Microsoft calls these plugins Content Extensions, while other browser vendors have converged on the NPAPI architecture). A second, much more fragmented means of extending modern browsers is to write a browser extension (referred to as a "Browser Helper Object" by our friends in Redmond). Extensions typically have browser lifetime, as opposed to page lifetime. They also have programmatic access to manipulate the user interface of the browser.
In terms of Browser Extension environments, the most recent developments include Mozilla JetPack and Google Chrome Extensions. Both JetPack and Chrome employ web technologies to broaden their target developer audience. In Chrome, an extension is "essentially [a] web page", while with JetPack, "anyone who knows HTML, CSS, and JavaScript" can create an extension. Because of the large numbers of distributed developers authoring software which teeters between the world of unrestricted code running on your desktop and the sandboxed code running in your browser, these projects raise unique security issues. Our own work with BrowserPlus addresses a closely related set of challenges and will be used throughout the article as a point of comparison.
Sandboxing vs. Code Review
In designing an extension system where developers contribute code, there's a key upfront decision that has a very deep effect on the platform — To what extent should plugins be trusted? Should plugin authors be forced to attain the approval of some body of reviewers, or do we instead rely on a software sandbox to mitigate the potential harm that could be done by untrusted code from unknown authors (and hence relax the review requirement)? The former approach can minimize upfront investment in platform development, while the latter can reduce delays in publishing 3rd party code.
In addition to increasing complexity, the sandbox-based approach constrains the creativity of developers who use the platform. The universe of what is possible is pre-defined by the platform authors, which is contrary to the idea of an extension system. Thanks to Atul Varma's recent overview of JetPack development, I now can identify this tension as Jonathan Zittrain's "Generative Dilemma".
At first glance, the platform developer might feel stuck with a binary decision between generativity vs. self service (the ability of plugin authors to publish immediately without oversight or review). A little more thought, however, reveals that in reality there's a spectrum with several interesting intermediate choices. The first hybrid to consider: a sandbox with a set of additional capabilities or permissions that may be requested by code running therein.
Building a Capable Sandbox
In many ways, browser extensions can be considered conceptual peers of the browser: They share direct access to the end user and to the resources of the machine within which they run. Additionally, given the wide target audience of modern extension systems, developers with widely varied levels of experience and grasp of security issues are empowered to author and quickly publish extensions. Providing extensions with system access to permit generativity creates a tension with the requirement that extensions run in a locked-down environment to preserve reviewless publishing and prevent accidental or malicious end-user compromise. We seem to be converging on a capability-based security model, where sandboxed code may explicitly or implicitly3 request enhanced "capabilities" or "permissions." Several of the projects mentioned here have mechanisms which allow an extension to express its required permissions:
- Chrome extensions require explicit expression of capabilities (or "permissions") in a manifest.
- In JetPack, it may eventually be possible to automatically determine the capabilities required by a given JetPack, based on the dependency graph of "superpowers" it uses (see below)
- In BrowserPlus, as in Chrome, permissions are explicitly stated in a manifest.
As different projects attempt to build capabilities-based systems, an interesting opportunity for collaboration arises. Users are going to learn to some extent what "writing to a temporary location on your disk" means. They will also learn more about "using location," and maybe also about "capturing video using a webcam." As new platforms emerge that ask the user more and more questions, it would be beneficial if these platforms shared similar capability lists, perhaps even a similar language or visual vocabulary.
From Capabilities to Meaningful Decisions
While we all seem to agree that an enumerable list of capabilities is a prerequisite to intelligent interface design, it's not clear that we've yet determined how to consolidate this information in a user interface that allows meaningful decisions. This is not for a lack of thought: Over a year ago, Dion Almaer suggested a "nuanced question" combined with good post-decision feedback. Since then, he's summarized ideas from Mozilla folks regarding a "layer [of] social trust on top of the technical security." More recently, there's been some initial discussion of a stop-light style representation of risk, which if correctly applied could distill a complex decision into a series of simple questions, (for example, Do you trust yahoo.com?) which iteratively becomes more ominous as the stakes (and the implied risk) get higher.
Better Responses Through Fewer Questions
One approach employed by BrowserPlus attempts to minimize explicit prompting and leverages mechanisms of implicit consent instead 4 by carefully crafting the API between trusted and untrusted code. One such example is file selection, where the act of navigating an operating system-supplied file picker dialog indicates implicitly that the site should be allowed to read the contents of selected file(s). Another example where this technique might be applied involves webcam access. Rather than asking the user if a site may use the webcam, pop up a window displaying the view from the webcam, allowing the user to capture a picture inside that frame (outside the control of the page), and finally after capturing "share" the capture with the page.
Architecting APIs and UI in this way can somewhat alleviate the need for explicit up-front questions and allow in-context kinesthetic decision making to occur. This approach is not without fault however, as it can also confine the freedom of UI designers. Eliminating needless questions assumes that only by asking fewer questions of higher quality, will we truly empower the user to make meaningful decisions.
Permission Prompts in Practice
In addition to ongoing thought experiments in meaningful user prompting, there are plenty of instances in practice where user questions have been built to varying degrees of success.
Facebook combines "social trust" (the rating) with a generic bit of language about how an app can poke at your stuff:
My Yahoo! takes a language-laden approach to the problem:
BrowserPlus uses a lot of screen real estate to convey a fairly literal translation of capabilities into human language:
Google Gears adds a visual representation of a capability and a prominent display of who is asking:
Language Choice and the Generativity Continuum
The choice of implementation language adds another dimension to the problem of security in web extension systems. As might be expected, native code (C, C++, or Objective C) will always afford maximal access to the system, yielding the ultimate in generativity. Certain features cannot be accessed from a higher level language — some good examples include access to physical position information from a motion sensor5 or access to a wifi card to extract nearby wifi base stations with associated signal strength. The benefit to working at such a low level is, in turn, this freedom. Ultimately, attempts to introduce sandboxing into an extension system that supports native code run the risk of introducing extra developer facing complexity without giving much in return6. In general, the choice of implementation language can bound where an extension system falls on the generativity continuum:
Languages like Lua or JavaScript land on the other side of the extreme and apply well to a system where automatic publishing is important. In the case of JavaScript, there is no common defined standard library7, so this makes it possible to introduce new protected file system APIs (for instance) without surprising a developer. This same reasoning is what places Ruby and Python in the middle of the continuum. While it would be possible to embed Ruby and shoehorn in a capability-enforced access system (or perhaps use a modified version of the "Safe" mechanism that already exists in Ruby), it would yield a system sufficiently different from expectations that it might feel clumsy or confusing to developers.
While none of these claims are without exception, it is true that the two newest browser extension platforms today are built upon JavaScript and are sandboxed and capabilities-based. Older plugin and extension systems tend to leverage native code and either use code review or don't even attempt to address the issue of security in any granular way.
Case Studies in Extension Security
So far we've enumerated several pertinent decisions that extension platform authors must make:
- Are submissions sandboxed or reviewed?
- What language are extensions written in?
- Is the system capability based? If so, how is this implemented?
As it turns out, the two newest browser extension platforms avoid straight answers to these questions. Given the tradeoffs with each decision, both systems are hybrids that attempt to capture the benefits of reviewless publishing, yet still preserve the generativity of native code. They leverage JavaScript to provide an authoring environment that's accessible to a majority of the world's developers, but allow the sprinkling of native code in controlled ways to preserve generativity. It's deeply interesting to look at how these platforms straddle some of the trickiest questions.
Google Chrome's Extensions
Aaron Boodman, working on extensions for Google Chrome, recently spoke about where Chrome can be found on the generativity continuum. Chrome uses a hybrid approach where "webby" extensions may optionally include native code bundled as scriptable NPAPI plugins. Extensions which are based solely on the Chrome extension environment's JavaScript APIs need no review and are "enabled automatically." Extensions that include unsandboxed native code are subject to additional review. In Aaron's words:
Aaron's comments are at 21:30
"
We're really proud of the fact that in the Google Chrome extension gallery we enable extensions automatically, there's no review period. But we make an exception for NPAPI because when you get to native code a lot of the security mechanisms built into the extension system can no longer apply. Once you have native code running it can modify the registry or make permanent modifications to your system... So we have additional review for NPAPI extensions."
This strategy seems reasonable. One would hope that a lion's share of extensions are developed without reliance on native code. The set of extensions that bundle native code can then be
periodically examined. Those which leverage native code to do things that may be interesting to a large number of extensions developers and can be considered for uplifting into the core
platform.
Mozilla's JetPack
One interesting thing that the Chrome model lacks is a means for sharing privileged functionality between extensions without actually merging it into the core extension platform. JetPack, on the other hand, is taking a much more ambitious initial approach to building a platform that can more rapidly evolve. Atul recently summarized the design goals of JetPack's capability-based security model. They aim to "allow anyone to create capabilities that securely expose privileged functionality." The JetPack world might end up looking something like this:
The key difference from Chrome extensions is the existence of a middle tier consisting of community contributed bundles. These provide JavaScript APIs to access system resources not otherwise exposed by the core extension system. By breaking out potential platform features into a separate layer you empower the community to not only imply the features that they'd like to see in the plugin platform, but to go and build them. This is an exciting idea. It will be interesting to see how this middle tier of superpowers is embraced by the community of extension developers, as well as to learn the details of how the review process is structured.
Today's Extensions as Tomorrow's Web
Web extensions today are a dynamic and fascinating area at the intersection of several disciplines. This post attempts to give a taste of some of the considerations and tradeoffs involved in the architecture of such systems. Hopefully I've sparked your interest to learn more or perhaps even join the fray. A renewed interest in more open software platforms is no surprise, and the potential to harness the creativity of developers of the world is inspiring.
One area, however, that dampens the joy of web extension platforms covered here is that they're limited in scope — vendor locked and browser specific. While we'll hopefully see increased (and appropriate) cross-vendor collaboration, it's reasonable to conclude that because "browser extensions" are about extending web browsers — and because different web browsers can have vastly different architectures — browser extension APIs will be slow to converge.
Imagine, however, an extension system which struck a balance between simplicity, generativity, and security, and was pertinent to the whole darn web. This is the promise of Web Augmentation technologies. Distributed Extensibility has been a topic of discussion in terms of HTML5 for a while now, but the conversation thus far has failed to cover a distributed way to explore new standard JavaScript APIs (the stuff that so many emergent HTML5 standards are made of). A significant obstacle to this conversation is the problem of helping users understand and securly navigate a dynamically evolving web.
The current work being done to secure extension platforms logically extends to web augmentation platforms. The degree to which we can collectively refine these permissioning models may become the key limiting factor in how far we can migrate our current desktop experience to the web.
Lloyd Hilaiel
BrowserPlus Hacker
2. Geolocation was ultimately built into Firefox 3.5, however Geode still serves as a great example of web augmentation — in this case using web extensions as a way to experiment with new potential core features for the web.
3. Whether the request of capabilities is implicit or explicit is an interesting related question. Having a platform that can discover the required capabilities of an extension without the author having to explicitly enumerate them would yield something that's easier to develop for, at the cost of complexity for the platform implementor.
4. The notion of implicit consent isn't new — there's precedent, for instance, in Flash where certain API functions can only be performed from an event handler generated by a user action (mouse or keyboard). The simple idea is that user actions can be a meaningful part of the security system.
5. What is possible without native code is obviously a moving target. Browser-based access to the motion sensor was introduced using BrowserPlus a couple years ago, and subsequently has made it into Firefox 3.6. What's next?
6. The potential efficiency of native code is an exception, and Google Native Client is an example of a sandbox system around native code. The project focuses on enabling the efficiency of native code with the saftey of the web, and additionally wraps and exposes some system resources, such as audio. Another glaring exception might be Apple's sandboxed environment for authoring iPhone Apps, a case where Objective C affords a slightly higher level of abstraction for developers yet still allows native code efficiency — important on a mobile device.
7. The CommonJS movement is an attempt to bring a standard library and means of including (or "requiring") code to JavaScript. While this could standardize APIs for JavaScript, developers will still generally be forced to understand the difference between core JavaScript and libraries provided by the execution environment.
As we have noted, FourSquare has become an extremely popular way to share
where you are. However, unlike yesterday’s hot location-sharing app, BrightKite, FourSquare does not
have the ability to share photos. Is this an oversight, or is it an opportunity to fill a void?
At least one developer has pounced on photo sharing on FourSquare, but not as you might expect. Rather than create a mobile application, Sam Street wrote his own API, Fspic (details at our Fspic API profile).
Street explained how photo-sharing is useful to the FourSquare API discussion list:
“The uploadPhoto API method will accept venue_ids and be able to perform venue checkins as well as text shouts. This makes for a great feature whereby you can see all the photos of a certain venue, and all photos of venues within a certain city.”
That is, perhaps, a glimpse of the future. However, there are very few FourSquare clients now, with most developers using the API to read only. By far the most popular check-in client is the official application from FourSquare, which does not support photo uploading.
In order for photo sharing to even be very usable, clients will need to provide ways to actually used links passed during check-in, Street points out. Also, he thinks it would be useful to point to specific users (like Twitter’s @reply), something also missing from FourSquare.
While Fspic may very well be useful, Street calls it “alpha testing stage.” It first needs a more mature FourSquare ecosystem and then adoption within the developer community. Until then, among the options Street is considering is his own dedicated Fspic iPhone application to get things going.
Do you think people want to share photos on FourSquare? Are developers more likely to use Fspic or roll their own photo sharing?
N97 firmware v21.0.045 has been released and now available over Nokia Software Updater.
To update, plug your N97 in to your PC and launch Nokia Software Updater and then start updating.
Firmware size is around 138 MB so please make sure that you have good enough internet connection.
Unfornately that N97 firmware update is still not available on OTA update.
After weeks of using Nokia N900, I feel little bit annoying that all application icon are stored in the same place "Others". When I want to launch some application, it's quite hard to find the application I want.
But the problem has gone with application named "Catorise". After install this application, N900 main menu was changed and categorized.
Now it's much easier and user friendly ^_^
To install it, just go to App Manager and install small utility named "Catorise"
Happy Hacking!!
What can you do if you want to enable a fullscreen experience on the Web? You can't. Or, use Flash. Some claim that you shouldn't offer this ability as it is a security liability. Someone can put a fullscreen view that tricks the user into giving it information.
However, as much as I think user security is important, it doesn't seem like we can punt and not do anything because of this. A user agent can do a lot of things to help out.
Some (majority?) of the use cases revolve around full screen video. Eric Carlson has a WebKit checkin that enables that one case. You can
webkitEnterFullScreen() on a HTML5 video element and be on your way.
You can see this in action on the SublimeVideo HTML5 player. Play the video in WebKit nightly and alt-click the "full size" arrows.
Video is great, but what about general purpose? What if you could fullscreen any element? Robert O'Callahan threw up a strawman:
- Should be convenient for authors to make any element in a page display fullscreen
- Should support in-page activation UI for discoverability
- Should support changing the layout of the element when you enter/exit fullscreen mode. For example, authors probably want some controls to be fixed size while other content fills the screen.
- Should accommodate potential UA security concerns, e.g. by allowing the transition to fullscreen mode to happen asynchronously after the user has confirmed permission
New API for all elements:
JAVASCRIPT:
void enterFullscreen(optional DOMElement element, optional Screen, optional boolean enableKeys); void exitFullscreen(); boolean attribute supportsFullscreen; boolean attribute displayingFullscreen; //"beginfullscreen" and "endfullscreen" eventsWhile an element is fullscreen, the UA imposes CSS style "position:fixed; left:0; top:0; right:0; bottom:0" on the element and aligns the viewport of its DOM window with the screen. Only the element and its children are rendered, as a single CSS stacking context.
enterFullscreen always returns immediately. If fullscreen mode is currently supported and permitted, enterFullscreen dispatches a task that a) imposes the fullscreen style, b) fires the beginfullscreen event on the element and c) actually initiates fullscreen display of the element. The UA may asynchronously display confirmation UI and dispatch the task when the user has confirmed (or never).
The enableKeys parameter to enterFullscreen is a hint to the UA that the application would like to be able to receive arbitrary keyboard input. Otherwise the UA is likely to disable alphanumeric keyboard input. If enableKeys is specified, the UA might require more severe confirmation UI.
In principle a UA could support multiple elements in fullscreen mode at the same time (e.g., if the user has multiple screens).
enterFullscreen would throw an exception if fullscreen was definitely not going to happen for this element due to not being supported or currently permitted, or if all screens are already occupied.
Much talking of exact API issues and more security.... but hopefully inertia does it job and we get something.
Would you like a fullscreen API?
Hi!
Here’s the weekly summary of Qt related changes to WebKit trunk. Big changes include Yael’s patch for WebSockets support, the beginnings of QtScript on top of JavaScriptCore’s C API, Maemo 5 tweaks and layout test fixes:
- Janne added the necessary meta-data to make QtWebKit play nicely with Symbian backups (34077).
- I did some code cleanups in RenderThemeQt and fixed a bug with combo boxes not showing up in Maemo5 (34088).
- Holger fixed a regression in the JavaScript prompt handling (30914).
- Jedrzej landed the first files for building QtScript on top of JavaScriptCore’s C API (32565).
- Diego added history support to the Qt DRT, we now pass the
http/tests/historylayout tests! (34167) - Daniel fixed a bug with the height of button elements (29564).
- Kent fixed support for ES5 style introspection with QMetaObject methods (34087).
- Yael implemented the Qt part of WebSocket support, we now pass
websocket/testsin the layout tests (34180). - Diego fixed more worker layout tests by adding support for counting worker threads in the Qt DRT (34221).
- Holger found a neat way to speed up the conversion from KURL to QUrl (33873).
- Trond fixed an endless loop in QWebPage printing (r53997).
- Kenneth fixed incorrect fonts on comboboxes on Maemo5 and Symbian (r53999).
- Andreas upstreamed Ralf and Robert’s kinetic scrolling support for QWebView using
QAbstractKineticScroller(34267). - Benjamin implemented support for the
display()method in the Qt DRT (34258). - Oswald speed up the conversion between
WebCore::StringandQStringby avoidingQString::fromUtf16()(r54060). - Kenneth landed a patch to disable auto-uppercasing and text prediction for password input fields (r54064).
- Kenneth also continued to clean up the QtLauncher for a future merge with QGVLauncher
- Andreas and Kenneth submitted tweaks to the look’n'feel of QtLauncher on Maemo5.
CSS3 is coming. Although the browser support of CSS 3 is still very limited, many designers across the globe experiment with new powerful features of the language, using graceful degradation for users with older browsers and using the new possibilites of CSS3 for users with modern browsers. That’s a reasonable solution — after all it doesn’t make sense to avoid learning CSS3 (that will be heavily used in the future) only because these features are not supported yet. The point of this article is to give you a glimpse of what will be possible soon and what you will be using soon and provide you with an opportunity to learn about new CSS3 techniques and features.
In this post we present 50 useful and powerful CSS3/jQuery-techniques that can strongly improve user experience, improve designer’s workflow and replace dirty old workarounds that we used in Internet Explorer 6 & Co. Please notice that most techniques presented below are experimental, and many of them are not pure CSS3-techniques as they use jQuery or other JavaScript-library.
[Offtopic: By the way, did you know that Smashing Magazine has a mobile version? Try it out if you have an iPhone, Blackberry or another capable device.]
Visual Effects and Layout Techniques With CSS3
CSS3 Analogue Clock
Analogue clock created using webkit transition and transform CSS. JavaScript is only used to pull in the current time.
Use CSS3 to Create a Dynamic Stack of Index Cards
We will create a dynamic stack of index cards solely with HTML and CSS3 and use such CSS3 features as transform and transition (for the dynamic effects) and @font-face, box-shadow and
border-radius (for the styling).
dynamic PNG shadow position & opacity
When the light is turned on, the position and opacity of the logo shadow will change dynamically, depending on the position and distance of the light bulb. Don’t forget to drag the logo and/or
the light bulb around!
How To Create A Sexy Vertical Sliding Panel Using jQuery And CSS3
So, what about a vertical sliding panel that would act as some sort of drawer instead of the usual top horizontal sliding panel that pushes everything else down when it opens? While thinking of
alternatives to the usual horizontal panels, I thought it would be nice to create something that works in a similar way, but that is a bit more flexible.
Awesome Overlays with CSS3
The trick with these overlays is the gradient border, going form a lighter to darker orange as you go from top to bottom. To create that effect we used to the border-image property, which is a
tricky little addition to CSS.
CSS3 & Flexible UI: Avoid Recutting UI Graphics for Mobile
What if we could replace almost all of the graphical UI elements within Fennec with CSS created equivalents? As a designer, am I comfortable bypassing Photoshop and letting CSS run the pixel
rodeo? After a few initial tests, the answer to both of those questions was a very solid “yes”. A solid “friggin’ right” if in Cape Breton.
How To Create Depth And Nice 3D Ribbons Only Using CSS3
We will use box-shadow to create a drop-shadow with RGBa, a color model that allows an optimized contrast with any kind of backgrounds. RGBa is the standard RGB model (0,0,0 – 255,255,255) and
it adds the last option (a) for the opacity. We can use this model also for other properties and it works with the new browser.
Create a Beautiful Looking Custom Dialog Box With jQuery and CSS3
This custom dialog box is one of the scripts in that website and I think it will be quite useful for all of us. The reason I have this custom dialog box is to overcome the inconsistencies
across different browsers. And, of course, it uses CSS3 to style everything.
Drop-In Modals with CSS3
For those using WebKit based browsers (Safari and Chrome), CSS3 effects and properties can help you create fast, simple modals by using transforms, animation, and some subtle design cues.
Newspaper Layouts with Columns and Image Masks
The faux-newspaper look goes in and out of style online pretty frequently, but these tricks can be used for quite a few cool applications. What we’ll talk about here is using -webkit-mask-image
and -webkit-column-count.
Navigation Menus With CSS 3
Sweet AJAX Tabs With jQuery 1.4 & CSS3
This post is a tutorial of making an AJAX-powered tab page with CSS3 and the newly released jQuery 1.4.
Sweet tabbed navigation bar using CSS3
Although I don’t understand why animations have been added in CSS3, this upcoming standard does have a couple of very neat features added to the CSS we’re using today. I wanted to take a couple
of these new things, and create a Sweet tabbed navigation using CSS3.
Halftone Navigation Menu With jQuery & CSS3
Today we are making a CSS3 & jQuery halftone-style navigation menu, which will allow you to display animated halftone-style shapes in accordance with the navigation links, and will provide
a simple editor for creating additional shapes as well.
Building Coverflow With CSS Transforms
I was able to create a coverflow effect that actually flows and animates in real-time, without using canvas or prerendered graphics.
CSS3 Hover Tabs without JavaScript
With the new techniques in CSS3 and clever applications of existing CSS it is increasingly stepping on the toes of JavaScript. Which to be honest isn’t necessarily a bad thing. I thought I’d
try my hand at something so here is a basic CSS tabbed content section that changes on hover.
CSS 3 Transitions and Animations
Going Nuts with CSS Transitions
I’m going to show you how CSS 3 transforms and WebKit transitions can add zing to the way you present images on your site.
Sliding Vinyl with CSS3
We take a standard album cover, a little HTML, and some CSS3 transitions and transforms to create a sliding vinyl effect for showing off the music you love.
Fun with CSS3 and Mootols
These examples came about when experimenting with the extend property in MooTools. By extending the styles class I could add CSS3 properties into the Core MooTools framework and do CSS3
animations.
Star Wars HTML and CSS: A NEW HOPE
There are a lot of CSS transitions experiments going on right now. Yesterday I discovered another HTML and CSS experiment which went “far far away”, compared with my simple CSS gallery.
Guillermo Esteves presented a piece of history translated for tomorrows browsers: the Star Wars Episode IV opening crawl in HTML and CSS.
Fun with 3D CSS and video
Zach Johnson has been having fun with 3D effects via CSS such as his isocube above, which is brought to you with simple HTML (including a video tag for a playing video on the surface!) and some
CSS.
CSS3 animations and their jQuery equivalents
This tutorial/these examples will show the use of the same HTML, with different classes for CSS3 and jQuery. You can compare both the codes and see which one you like more. Don’t forget to
check the demo/download the source code to view how everything is working under the hood.
CSS Animations
No matter how fast internet tubes or servers are, we’ll always need spinners to indicate something’s happening behind the scenes.
Snowy CSS3 Animation
It’s cold and snowy down here in Brighton, so to celebrate the falling white stuff (and of course the various festivities at this time of year) Clearleft’s very own Natbat has made a snowy CSS3
animation surprise for all you Safari and Chrome users out there.
What You Need To Know About Behavioral CSS
In this article, we will take those properties a step further and explore transformations, transitions, and animations. We’ll go over the code itself, available support and some examples to
show exactly how these new properties improve not only your designs but the overall user experience.
3D Cube using new CSS transformations
The impression of a three dimensional cube can be created using modern CSS techniques, without the need for JavaScript, imagery, canvas or SVG. Using the proprietary transform property to skew
and rotate shaded rectangles, individual cube faces can combine to form a 3D object.
Playing around with WebKit Animations
I’ve been playing around doing a KeyNote like animation done with CSS and some JS to hook up the necessary events. The animation is kind of like a deck of cards. When you go to the next one the
current one zooms in and fades out, symbolizing getting closer to the viewer. The next card then zooms and fades in from the back and to give a fancy effect-
More on 3D CSS Transforms
Various 3D CSS Transforms in an overview.
Gradients, RGBA and HSL with CSS 3
Working With RGBA Colour
CSS3 introduces a couple of new ways to specify colours, and one of those is RGBA. The A stands for Alpha, which refers to the level of opacity of the colour, or to put it another way, the
amount of transparency. This means that we can set not only the red, green and blue values, but also control how much of what’s behind the colour shows through. Like with layers in Photoshop.
CSS3 Gradients: No Image Aqua Button
I played around with WebKit CSS3 gradient and created a useless but fun stuff – an Aqua button with no images! Back in the time when Mac OS X was first announced, there’re a plenty of web
tutorials that describe how to create the sexy aqua button with Photoshop, and now I can show how to create one with CSS!
CSS3 HSL & HSLA
A tutorial on using the HSL & HSLA declarations along with the quick + / – guide to which browsers currently support the herein effect.
Super Awesome Buttons with CSS3 and RGBA
One of our favorite things about CSS3 is the addition of RGBA, a color mode that adds alpha-blending to your favorite CSS properties. We’ve kicked the tires on it a bit with our own projects
and have found that it helps streamline our CSS and makes scaling things like buttons very easy. To show you how, we’ve cooked up an example with some super awesome, scalable buttons.
Using the Shadow-Property in CSS3
Create a Letterpress Effect with CSS Text-Shadow
The letterpress effect is becoming hugely popular in web design, and with a couple of modern browsers now showing support for the text-shadow CSS3 property it’s now simple and easy to create
the effect with pure CSS. No Photoshop trickery here!
Shadows and CSS3
I’m currently working on a design that uses text-shadow and box-shadow, with RGBA in place to create the shadow color. I wanted to tweet about this technique because it’s simple and awesome,
but to my surprise I couldn’t find a good, quick tutorial that covered the use of both text and box-shadow, along with RGBA. So I decided to create one.
I learned this technique from Dan Cederholm’s Handcrafted CSS book, so if you’re able I’d recommend just going out and grabbing that, as he explains it much more elegantly and thoroughly than I
ever could.
Learning New CSS3 Selectors
CSS3 + Progressive Enhancement = Smart Design
Progressive enhancement is a good thing, and CSS3 is even better. Combined, they enable designers to create lighter, cleaner websites faster and easier than ever before.
A Look at Some of the New Selectors Introduced in CSS3
Here is a run-down of just some of the things that is possible with CSS3 selectors. Of course CSS3 isn’t supported at all by any IE browsers including IE8 but all latest versions of Safari,
Firefox and Opera support most, if not all of them.
Cleaner Code with CSS3 Selectors
In this article I’m going to take a look at some of the ways our front and back-end code will be simplified by CSS3, by looking at the ways we achieve certain visual effects now in comparison
to how we will achieve them in a glorious, CSS3-supported future. I’m also going to demonstrate how we can use these selectors now with a little help from JavaScript – which can work out very
useful if you find yourself in a situation where you can’t change markup that is being output by some server-side code.
The CSS3 :target Pseudo-class And CSS Animations
It’s no secret that I’m always looking for an easy way out using CSS instead of trying to replicate things with convoluted code — there are so many underused techniques that we could be
applying to our designs as an enhancement layer! In this experience, I take a brief look into the :target pseudo-class and a very simple CSS animation.
The CSS3 :not() selector
There isn’t a lot of information to be found about the :not() selector. The specifications only offer 3 lines of text and a couple of examples. So lets see what it can do!
IE CSS3 pseudo selectors
ie-css3.js allows Internet Explorer to identify CSS3 pseudo-class selectors and render any style rules defined with them. Simply include the script in your pages and start using these selectors
in your style sheets — they’ll work in IE… Honest…!
CSS3 Galleries
How To Create a Pure CSS Polaroid Photo Gallery
Magical things can be done by combining various CSS properties, especially when some of the new CSS3 tricks are thrown into the mix. Let’s take a look at building a cool looking stack of
Polaroid photos with pure CSS styling.
An Awesome CSS3 Lightbox Gallery With jQuery
In this tutorial we are going to create an awesome image gallery which leverages the latest CSS3 and jQuery techniques. The script will be able to scan a folder of images on your web server and
build a complete drag and drop lighbox gallery around it.
If That Is An Awesome CSS3 Gallery, How Would You Call Mine?
Editable CSS3 Image Gallery
We build a pretty typical image gallery design pattern, a grid of images that pop up larger when clicked. But this image gallery page makes use of hot semantic HTML5 markup, loads of visual
treats with CSS3 and jQuery, and made editable through the CMS PageLime. Quick reminder, the demo is awesome-est in a WebKit browser (Safari or Chrome).
Replacing CSS Hacks with CSS 3
Rounded corner HTML elements using CSS3 in all browsers
This is a behavior htc file for Internet explorer to make CSS property ” border-radius ” work on all browsers. At present, all major browsers other than IE shows curved corner by adding 4 lines
of css.
Using Rounded Corners with CSS3
As CSS3 gets closer to becoming the new standard for mainstream design, the days of rounded corners through elaborate background images is fading. This means less headache and time spent
working out alternatives for each browser.
Better Image Preloading with CSS3
Using CSS3’s new support for multiple background images, we can use a single, existing element to preload all of the required images.
Saying Goodbye to the overflow: hidden Clearing Hack
I’m now saying goodbye to overflow: hidden and the deciding factor for me is CSS3. Specifically box-shadow. At least in the sense that box-shadow was the first property I noticed being
negatively impacted by the use of overflow: hidden. Like the positioned child elements mentioned above, box-shadow can get clipped when the parent (or other ancestor) element has overflow
applied. And there are several other things to consider as we move forward using more CSS3. Text-shadow and transform can also potentially be clipped by overflow: hidden.
General articles about CSS 3
How to bring CSS3 features into your design
Top web browser (such as Firefox 3.5 and Safari 4) have introduce some cool features you can already use. Now, with just a few lines of css you can do things you used to do with images and
javascript.
Practical Uses of CSS3
In this article I’ll show you some practical uses for CSS3.
11 Classic CSS Techniques Made Simple with CSS3
We’ve all had to achieve some effect that required an extra handful of divs or PNGs. We shouldn’t be limited to these old techniques when there’s a new age coming. This new age includes the use
of CSS3. In today’s tutorial, I’ll show you eleven different time-consuming effects that can be achieved quite easily with CSS3.
Mobile optimised websites using CSS3 Media Queries
A while ago I wrote about using CSS3 Media Queries on my website redesign to provide mobile visitors with an optimised view designed for smaller screens. I thought it might be useful if I went
into a bit more detail on how I’m doing this.
Code a Backwards Compatible, One Page Portfolio with HTML5 and CSS3
HTML5 is the future of web development but believe it or not you can start using it today. HTML5 is much more considerate to semantics and accessibility as we don’t have to throw meaningless
div’s everywhere. It introduces meaningful tags for common elements such as navigations and footers which makes much more sense and are more natural. This is a run through of the basics of
HTML5 and CSS3 while still paying attention to older browsers. Before we start, make note of the answer to this question. Do websites need to look exactly the same in every browser?
Get the best out of CSS3
Craig Grannell turns into a cross between Jeffrey Zeldman and Russell Grant, taking a peek at what the future of CSS has to offer – with a little help from Opera, Safari and Firefox
Practical Uses of CSS3
“One big item for me is how much we use CSS3. Yes I know, it is not fully supported across all browsers. If you still want everything to look exactly the same across all browsers, you should
probably just close this article and not read about CSS for another 10 years. A user is not going to pull up your site in two different browsers to compare the experience, so they won’t even
know what they are missing. Just because something is not fully supported, that does not mean that we can’t use it to an extent. In this article I’ll show you some practical uses for CSS3.”
A Crash-Course in Advanced CSS3 Effects
This video tutorial reviews a bunch of different neat effects that can be used in Safari 4, Chrome, and for all iPhone development.
33 Must Read CSS3 Tips, Tricks, Tutorial Sites and Articles
An extensive overview of CSS3-techniques, tools, articles and resources.
© Smashing Editorial for Smashing Magazine, 2010. | Permalink | 47 comments | Add to
del.icio.us | Digg
this | Stumble on
StumbleUpon! |
Tweet it! | Submit to Reddit
| Forum Smashing Magazine
Post tags: CSS, css3
Last month at the Boston MySQL User Group, I went through the meanings of INNER, LEFT/RIGHT OUTER, CROSS, NATURAL joins, how to do a FULL OUTER JOIN in MySQL, and what STRAIGHT_JOIN means. I also explained how to recognize when you want those types of joins, and best practices for the semantics of writing joins and design patterns. Subqueries were explained in this session, and some examples of how to think differently so that you end up writing JOINs instead of subqueries. The slides (slightly different from the slides in the video — due to error correction) can be found at http://technocation.org/files/doc/2010_01MySQLJoins.pdf.
Here’s the video:
PlanetMySQL Voting: Vote UP / Vote DOWN
Google widget busted!
Automatic update check in Carbide.c++ Properties
Updates available notification
The following features for Symbian development are provided within Carbide.c++:
- WINSCW compiler change - the Nokia C/C++ Compiler version 3.2.5 build 487 provides new name mangling to support critical exception handling. Without this change an exception can cause a program or system crash.
- Support for Qt Tools 1.6
- The Run builds concurrently option in the Builds preference panel now supports up to 50 concurrent build jobs, up from 4.
A more complete list of changes, including bug fixes, should be available soon in Carbide.c++'s Online Help pages (and is of course included in product's help file)
You can find the installation instructions in the Forum Nokia Discussion Boards and below you can see a visual guide as well.
Nokia Beta Labs has opened up a public testing for Nokia Ovi Suite 2.1, which has been tested privately for a few weeks now. This new 2.1 version is actually quite a leap ahead, so let’s talk about the improvements for a bit and why this might just be the version that finally replaces Nokia PC Suite:
- Nokia Ovi Suite 2.1 Beta release works now with Ovi Sync and Mozilla Thunderbird
- The new version also completely supports Windows 7, along with older versions of Windows
- Nokia Ovi Suite 2.1 synchronizes much better with Nokia’s Ovi services, including Share and Sync
- There have also been major fixes to Contacts sync and UI localization (languages) and improvements to overall stability
- Syncing videos from device to Nokia Ovi Suite, video playback and transferring videos from Nokia Ovi Suite to device are also now supported
.
This new version of Nokia Ovi Suite 2.1 also uses significantly fewer resources on your computer, especially when compared to Nokia Ovi Suite 2.0 and earlier variants.
So download the updated Nokia Ovi Suite 2.1. Beta now (click here) and try it out! We’re very excited to hear your comments & feedback (you can leave yours by using the widget inside Nokia Ovi Suite).
Cheers!
-Samuli, Nokia Ovi Suite team
Just a few years ago, when big sites like Facebook or Netflix were building out their delivery networks to customers, they would build data centers near major internet hubs. That meant setting up shop in San Francisco, Los Angeles, Washington, and New York, as well as at international hubs like London, Madrid, and Tokyo. As long as the data center was close to major population centers, people could get service pretty rapidly.
MySQL 5.1.43 can be downloaded from
http://dev.mysql.com/downloads/
For example, it now possible to create a partitioned table such as this one :
PlanetMySQL Voting: Vote UP / Vote DOWN
There are two other ways to handle sets of values: The built in SET column type, and using a INT/BIGINT column as a bitfield.
The mysql set data type provides a convenient way of working with a list of values, where each field could represent multiple simultaneous values. It's really just a wrapper around bitmask operations -- it lest you work with them using text as well as numerical values.
But how do they perform? My quick test showed that aside from a couple edge cases, they all preformed about the same speed. In fact it was surprising to me to see that the bitmask type queries were really not that much faster than the more normalised table structure with multiple rows. I would have guessed that the extra grouping operations would have added significant overhead, but they didn't.
| Query | Avg. Time |
|---|---|
| SELECT * from bitmask WHERE val&3 LIMIT 1000 | 0.0023512 |
| SELECT * from bitmask WHERE val&3=3 LIMIT 1000 | 0.0149182 |
| select * from settable where s&3=3 LIMIT 1000 | 0.0155686 |
|
select id FROM normalset group by id HAVING sum(val='yellow') and sum(val='cyan') LIMIT 1000 |
0.016244 |
|
select id, BIT_OR(CASE val WHEN 'cyan' THEN 1 WHEN 'yellow' THEN 2 ELSE 0 END) as bitvals, count(*) FROM normalset WHERE val in ('cyan','yellow') GROUP BY id HAVING bitvals=3 LIMIT 1000 |
0.0163958 |
|
select * from settable where s like '%cyan%yellow%' LIMIT 1000 |
0.0333536 |
Notice that that the top query in the list is an order of magnitude faster than the others, however it doesn't actually answer the same question as the other queries. I included it anyway because it was a curious result -- apparently bit manipulation operations alone are very very fast in mysql, but just adding an equality test slows the query down considerably. The cost of the equality test is much much higher than I would have anticipated. It would be an interesting project to track down exactly why that is.
You can see that working with the SET datatype using string values has the worst performance. When you use it like an ordinary bitmask, then the performance is identical to the other, faster methods (no surprise there.) Working with it using text values involves some internal conversions. IMO this means ordinary bitmasks are the clear winner over the SET datatype -- the SET datatype requires an ALTER TABLE to add new values, and the the convenience of using text values should be avoided because they're slow. If you need maximum flexibility, the more normalized structure seems to preform just as well.
To generate the test data, I created about 200k unique items and randomly assigned any of a set of 4 values to each item. This ended up with about 400k associations, so each item had on average two values out of the set. Statements follow:
-- creating SET table, generating values
create table settable (id serial, s set('cyan','yellow','magenta','black'), key (s) );
insert into settable (s) values ( 'cyan,yellow' ), ( 'yellow,magenta'), ( 'cyan,black,yellow'), ( 'magenta' );
-- repeat until desired # of rows reached:
insert into settable (s) select truncate(rand()*15+1,0) from settable;
-- creating normalized set, copy values from settable
create table normalset (id int not null default 0, val char(8), key(id) );
insert into normalset SELECT id, 'cyan' FROM settable WHERE s like '%cyan%';
insert into normalset SELECT id, 'yellow' FROM settable WHERE s like '%yellow%';
insert into normalset SELECT id, 'magenta' FROM settable WHERE s like '%magenta%';
insert into normalset SELECT id, 'black' FROM settable WHERE s like '%black%';
-- create bitmask, copy values from settable
CREATE TABLE bitmask ( id serial, val int unsigned NOT NULL default '0', UNIQUE KEY (id), KEY (val) );
insert into bitmask SELECT id, s+0 FROM settable;
PlanetMySQL Voting: Vote UP / Vote DOWN
This post is inspired by a discussion with John Didion:
Is there any way to optimize the query for overlapping ranges in MySQL if both ranges are dynamic?
I have two tables, each with integer range columns (specified as
LineString), and I want to find rows that overlap.No matter what I try, the query planner never uses any indexes.
This question addresses a well-known problem of efficient searching for the intersecting intervals. The queries that deal with it require ability to search for the intervals (stored in two distinct columns) containing a constant scalar value.
Plain B-Tree indexes used by most databases do not speed up the queries like that. However, MySQL supports SPATIAL indexes that can index
two-dimensional shapes and efficiently search for the shapes containing a given point.
With a little effort, time intervals can be converted into the geometrical objects, indexed with a SPATIAL index and searched for the given point in time (also presented as a
gemetrical object). This is described in the article about overlapping ranges in MySQL.
This article, however, searches for the intervals overlapping a constant range, provided as a parameter to the query. Now, I will discuss how to adapt the query for a JOIN between
two tables.
Let’s create two sample tables, each containing a set of time ranges stored as geometrical objects, and find all records from both tables whose ranges overlap:
Table creation details
CREATE TABLE filler (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT
) ENGINE=Memory;
CREATE TABLE t_big (
id INT NOT NULL PRIMARY KEY,
rg LineString NOT NULL,
SPATIAL KEY sx_big_rg (rg)
) ENGINE=MyISAM;
CREATE TABLE t_small (
id INT NOT NULL PRIMARY KEY,
rg LineString NOT NULL,
SPATIAL KEY sx_small_rg (rg)
) ENGINE=MyISAM;
DELIMITER $$
CREATE PROCEDURE prc_filler(cnt INT)
BEGIN
DECLARE _cnt INT;
SET _cnt = 1;
WHILE _cnt <= cnt DO
INSERT
INTO filler
SELECT _cnt;
SET _cnt = _cnt + 1;
END WHILE;
END
$$
DELIMITER ;
START TRANSACTION;
CALL prc_filler(120000);
COMMIT;
INSERT
INTO t_big (id, rg)
SELECT id,
LineString(
Point(-1, TIMESTAMPDIFF(second, '1970-01-01', range_start)),
Point(1, TIMESTAMPDIFF(second, '1970-01-01', range_end))
)
FROM (
SELECT id,
STR_TO_DATE('2009-02-01', '%Y-%m-%d') - INTERVAL id HOUR AS range_start,
STR_TO_DATE('2009-02-01', '%Y-%m-%d') - INTERVAL id HOUR + INTERVAL RAND(20100201) * 7200 SECOND AS range_end
FROM filler
) q;
INSERT
INTO t_small (id, rg)
SELECT id,
LineString(
Point(-1, TIMESTAMPDIFF(second, '1970-01-01', range_start)),
Point(1, TIMESTAMPDIFF(second, '1970-01-01', range_end))
)
FROM (
SELECT id,
STR_TO_DATE('2009-02-01', '%Y-%m-%d') - INTERVAL id DAY AS range_start,
STR_TO_DATE('2009-02-01', '%Y-%m-%d') - INTERVAL id DAY + INTERVAL RAND(20100201) * 172800 SECOND AS range_end
FROM filler
ORDER BY
id
LIMIT 5000
) q
There are two tables, t_big and t_small.
t_big contains 120,000 records with intervals starting each hour and having random length from 0 to 2 hours, 1 hour in
average.
t_small contains 5,000 records with intervals starting each day and having random length from 0 to 2 days, 1 day in
average.
The intervals are presented as the LineString records with a single line connecting Point(-1, range_start) and Point(1, range_end).
range_start and range_end are presented as the UNIX timestamps (numbers of seconds since Jan 1st, 1970). To avoid year 2038 problem, we use TIMESTAMPDIFF rather than UNIX_TIMESTAMP to calculate the value.
Each table is indexes with a SPATIAL index on the rg field.
First of all, we need to make sure that the index is created well.
MySQL uses R-Tree for the SPATIAL indexes, which works according to the principle of least enlargement
to
the bounding box when adding a value to the index. Each leaf node is covered by a certain minimum bounding box stored in the branch node, and the branch which needs to be increased to the least
extent is chosen as a new parent for the element.
Our ranges are one-dimensional, but MySQL requires the spatial data to be two-dimensional. That’s why we need to use either of the dimensions to represent the time ranges and fill another one to span some constant range so that the box areas would be proportional to the range lengths.
However, if we just fill both ends of the LineString with a constant, this will make the lines pure horizontal or pure vertical. Since they all reside on one line, the minimal
bounding boxes of any set of the LineString’s will have zero area (since they all will be of zero height). MySQL will not be able to choose the least enlargement:
in a two-dimensional space, any horizontal enlargement of a one-dimensional line will be a zero. MySQL will just append the entry to any randomly chosen branch in no certain
order. This makes the index very unbalanced and in fact unusable.
To make the index usable, we need to make the boxes have positive area so that the least enlargement principle could do its job. That’s why we create the LineString fields
diagonally, with the first coordinates being -1 for the start point and 1 for the end point.
Now, we should make a query that would find the intersections of these ranges.
MySQL documentation evasively mentions that the predicates supported by the spatial indexes are
MBRContains and MBRWithin (with the latter being just the synonym for MBRContains with
the argument order reversed), with a side note that in future releases, spatial indexes may also be used for optimizing other functions
If we were to comply with the documentation and limit ourselves to using only these two functions for the spatial indexes, the query would still be possible and quite efficient.
MBRContains checks if the bounding box of the second argument lies within the bounding box for the first argument. This is not always true for the overlapping ranges. If the ranges
overlap partially, that is the first range both starts and ends earlier than the second range, then no ranges lie completely within each other’s bounds, and MBRContains will return
0 for any argument order.
However, there is a simple condition that checks whether the ranges do overlap.
With any pair of ranges, there is a range that starts later (or at the same time) than another. If the ranges overlap, then the start of that range should lie within the bounds of its counterpart. Indeed, the start of the latest range should be equal to or greater then the start of the earliest range (by definition) and equal to of less than the end of the earliest range (or the ranges do not overlap).
This can be checked with a simple condition: MBRContains(rg1, StartPoint(rg2)).
Since there is no sargable condition that would find out which range starts earlier, we’ll just need to check both ways.
Unfortunately, MySQL does not support merging spatial indexes, so an OR condition would make the indexes unusable. We need to use the two MBRContains
predicates with two separate queries and merge the results using UNION.
When optimizing a join, MySQL’s optimizer usually makes the smaller table leading in the join. With a usual equijoin condition this is a wise thing to do, since
MySQL uses nested loops with an index search to join the tables. The duration of the nested loops query is the product of the leading table scan time (the number of the
records) and driven table search time. B-Tree search is logarithmic, so (n × log m) is less than m × log n) as long as m < n. That's
why the leading table should be the smallest one.
However, MySQL does not take into account that MBRContains predicate is not symmetrical. Reversing the table scan order makes each search operation to be not a
searching for boxes containing the point, but searching for start points contained by the box. Since the individual points are not even indexed, MySQL will not be able to use
an index access path for such a query and will revert to a very inefficient join buffer (which in fact is comparing every record to every other record).
To work around this, we need to force the join order so that the table with the points leads.
In MySQL, this is done by replacing JOIN with STRAIGHT_JOIN, which forces the leftmost table to be leading in the join.
Here's the query:
SELECT COUNT(*)
FROM (
SELECT s.id AS sid, b.id AS bid
FROM t_small s
STRAIGHT_JOIN
t_big b
ON MBRContains(b.rg, StartPoint(s.rg))
UNION
SELECT s.id AS sid, b.id AS bid
FROM t_big b
STRAIGHT_JOIN
t_small s
ON MBRContains(s.rg, StartPoint(b.rg))
) q
| COUNT(*) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 124911 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 1 row fetched in 0.0001s (4.4999s) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | PRIMARY | Select tables optimized away | ||||||||
| 2 | DERIVED | s | ALL | 5000 | 100.00 | |||||
| 2 | DERIVED | b | range | sx_big_rg | sx_big_rg | 34 | 1 | 12000000.00 | Range checked for each record (index map: 0x2) | |
| 3 | UNION | b | ALL | 120000 | 100.00 | |||||
| 3 | UNION | s | range | sx_small_rg | sx_small_rg | 34 | 1 | 500000.00 | Range checked for each record (index map: 0x2) | |
| UNION RESULT | <union2,3> | ALL |
select count(0) AS `COUNT(*)` from (select `20100201_ranges`.`s`.`id` AS `sid`,`20100201_ranges`.`b`.`id` AS `bid` from `20100201_ranges`.`t_small` `s` straight_join `20100201_ranges`.`t_big` `b` union select `20100201_ranges`.`s`.`id` AS `sid`,`20100201_ranges`.`b`.`id` AS `bid` from `20100201_ranges`.`t_big` `b` straight_join `20100201_ranges`.`t_small` `s`) `q`
This query finds the total number of pairs of overlapping ranges from both tables and runs for 4.5 seconds which is quite efficient.
MBRIntersects: a more efficient solution
Normally I would put the words hope that helps
and a link to the question form here, which I use to close the articles with the answers.
But when testing the solution, John found out that MBRIntersects function (which just checks intersection of two boxes without splitting them into start and end
points) is sargable too and the query above is quite overcomplicated.
This function is symmetric, that is MBRIntersects(a, b) ≡ MBRIntersects(b, a). However, MySQL is not aware of that, and an index is used only against the column in
the first argument to MBRIntersects. This means we have to make t_small to lead in the join and put its column into the second argument of the function.
This way, the column from the driven table (t_big) will be searched for the value provided from the leading table using the index on the driven table, which is exactly what we
need.
Here's the new updated query:
SELECT COUNT(*)
FROM t_small s
STRAIGHT_JOIN
t_big b
ON MBRIntersects(b.rg, s.rg)
| COUNT(*) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 124911 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 1 row fetched in 0.0001s (1.2656s) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | SIMPLE | s | ALL | sx_small_rg | 5000 | 100.00 | ||||
| 1 | SIMPLE | b | ALL | sx_big_rg | 120000 | 100.00 | Range checked for each record (index map: 0x2) |
select count(0) AS `COUNT(*)` from `20100201_ranges`.`t_small` `s` straight_join `20100201_ranges`.`t_big` `b` where intersects(`20100201_ranges`.`b`.`rg`,`20100201_ranges`.`s`.`rg`)
As we can see, this query is much more simple and completes 3 times as fast.
Finally, let's see how can we retrieve the datetime values of the start and end of the ranges from the LineString's:
SELECT s.id AS small_id,
'1970-01-01' + INTERVAL Y(StartPoint(s.rg)) SECOND AS small_start,
'1970-01-01' + INTERVAL Y(EndPoint(s.rg)) SECOND AS small_end,
b.id AS big_id,
'1970-01-01' + INTERVAL Y(StartPoint(b.rg)) SECOND AS big_start,
'1970-01-01' + INTERVAL Y(EndPoint(b.rg)) SECOND AS big_end
FROM t_small s
STRAIGHT_JOIN
t_big b
ON MBRIntersects(b.rg, s.rg)
LIMIT 10
| small_id | small_start | small_end | big_id | big_start | big_end | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 2009-01-31 00:00:00 | 2009-02-01 20:58:03 | 1 | 2009-01-31 23:00:00 | 2009-02-01 00:52:25 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 1 | 2009-01-31 00:00:00 | 2009-02-01 20:58:03 | 2 | 2009-01-31 22:00:00 | 2009-01-31 22:01:55 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 1 | 2009-01-31 00:00:00 | 2009-02-01 20:58:03 | 3 | 2009-01-31 21:00:00 | 2009-01-31 21:32:21 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 1 | 2009-01-31 00:00:00 | 2009-02-01 20:58:03 | 4 | 2009-01-31 20:00:00 | 2009-01-31 20:36:01 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 1 | 2009-01-31 00:00:00 | 2009-02-01 20:58:03 | 5 | 2009-01-31 19:00:00 | 2009-01-31 20:23:00 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 1 | 2009-01-31 00:00:00 | 2009-02-01 20:58:03 | 6 | 2009-01-31 18:00:00 | 2009-01-31 19:06:56 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 1 | 2009-01-31 00:00:00 | 2009-02-01 20:58:03 | 7 | 2009-01-31 17:00:00 | 2009-01-31 18:25:41 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 1 | 2009-01-31 00:00:00 | 2009-02-01 20:58:03 | 8 | 2009-01-31 16:00:00 | 2009-01-31 17:47:38 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 1 | 2009-01-31 00:00:00 | 2009-02-01 20:58:03 | 9 | 2009-01-31 15:00:00 | 2009-01-31 15:41:06 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 1 | 2009-01-31 00:00:00 | 2009-02-01 20:58:03 | 10 | 2009-01-31 14:00:00 | 2009-01-31 14:02:38 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 10 rows fetched in 0.0006s (0.0024s) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
This retrieves the range bounds in plain DATETIME format, suitable for output and calculations.
Hope that helps, John, and thanks for a nice tip!
I'm always glad to answer the questions regarding database queries.
PlanetMySQL Voting: Vote UP / Vote DOWN
Listen to James Caan, Charman of Look4aProperty discussing the new Look4aProperty | Money product.
In this post, I want to share some examples of the progress going on in the SVG Working Group. Microsoft recently joined the SVG Working Group, and other members (Mozilla, Apple and Opera among others) welcomed us warmly. I'm hopeful about the ways that SVG (both its current direction and future potential) could make the web better. We want the spec to be clear, consistent, and predictable for developers. We’re working out ambiguities such as “Pointer events and clip-paths”, “CSS Selectors <use> and as well as inconsistencies with stroked-dasharray” and “<use> and its interaction with the DOM and rendering” so that web developers can write SVG once and know that it will be interoperable across browsers.
I have to admit I was a little hesitant at first to get guidance and clarity on a dozen or so items we found to be ambiguous (see public SVG WG discussion threads), however the positive response has been overwhelming. Of course we are not the only members raising these issues, but we are happy to be a part of the process. The future of SVG is bright.
Additionally, Microsoft looks forward to hosting the next SVG Working Group face-to-face meeting in Brussels this May.
A special thanks to those on the Working Group for their warm welcome and shared goals of creating a specification that will promote standards based interoperable graphics for the web.
Patrick Dengler
Senior Program Manager
Internet Explorer Team
The following post is a reprint from my personal blog. It is editorial in nature and even delves into random politics. I apologise. You can deal with it though :)
Steve Jobs didn't hold back when talking about Google and Adobe. That is great. Life is so much more fun when people speak their mind. I remember hearing a story when Sir Steve was asked why mac keyboards where the way they were. He grabbed a PC keyboard and started to rip out "stupid keys" (print screen, F keys, and the like) and swore a lot.
We love to paint with broad black and white brushes these days don't we? Whenever I hear people talking about Google being "evil" or not.... I sit back and think about how interesting it is that companies become "people", especially in this country.
It makes sense when you look up Corporation:
Corporations are recognized by the law to have rights and responsibilities like actual people.
That may have been a convenient (and often almost genius) abstraction by lawyers, but it is screwed up. It feels like the times when you use inheritence in a way that isn't a ISA relationship, but it does kinda make the code nice. We have all done that, until we learned to favor composition. Corporations ISA Person? No. They are composed of them though.
I have been thinking about this ever since the recently surprise court decision the other day that "allows corporations and unions to pour unprecedented amounts of money into elections."
Lawrence Lessig had some interesting commentary:
The court decision does feel totally wonky to me. Right now, $ has a direct bearing on elections, and allowing multi-nationals (who have the money) to rain it down makes no sense.
Fun aside
My renaissance friend Graham Glass talks about how corporations can be considered a single conscious in his series on "the mind".
The issue with the vast number of corporations is that they are profit driven entities whose charter is to bring financial reward to shareholders. While you could argue that we as a species are driven by the selfish gene, corporations are driven by profits. Duh. Capitalism.
Google is a company. It is driven by this same goal. Now, there are various paths to a particular goal to make profits. Some companies sell things that kill people (weapons, cigarettes, etc). Others offer medical devices. All companies are not equal. Having spent time at Google, I do feel like the place isn't just an evil cult. The people that make up the consciousness were very driven strong willed people that cared about the company mission (universal access to information and all that) more than just the $. Sure some folks are focused on that. Also, although the wool could be placed over your eyes, the guys at the top of the chain have their hearts in the right place. While Larry and Sergey are there, decisions will be made that aren't solely based on profit. They want to create a different kind of legacy and company.
That being said, I think it is quite easy to fall into a trap such as:
If we do something here to block competition, we can make more $ and since we are Good Guys we can do better things with that money!
Google will sometimes do things that could be considered "evil" by some. That is life.
The good news with Google is that their search and ads business deals in a trust economy. It doesn't take much to switch from Google to Bing. Google knows that. Even though they have some HUGE advantages (technical [data centers, talent], brand, etc) the low barrier to change is huge.
Not all corporations are profit driven
I had the huge pleasure of working for Mozilla, which is a mission based corporation. Wow does that make life different. While you have to sustain yourself, it does mean that you think of the world very differently. You would rather go out in a blaze of glory doing something great for the mission, than just slowly die not doing much. Every choice you make .... you think of the mission.
It was interesting to work there knowing that I actually wouldn't want Firefox to be a 90% browser. You can fall into the similar trap as above and think:
We are mission based! If we had that domination we would use it for good!
But, not having that power in one hand is even better. Imagine working somewhere thinking "in my wildest dreams, the market would be shared somewhat evenly with the competition." The Open Web is amazing in that there is NO SINGLE VENDOR. If we are able to keep a decent balance between browsers (and thus the platform as we know it) then we have a balance of powers. Sure, in some ways you can't move as fast as a dictatorship, but there is a reason we don't want dictatorships in our government (even if the trains run on time!)
And, this brings me to the Adobe half of the Steve Jobs equation. Flash isn't dead. HTML5 is slowly going to put a dent into it if we ever get some of the use cases just right (e.g. video), but Adobe has a good penetration and can move at the speed of a dictatorship. The iPhone/iPad combo not shipping Flash will have an interesting dynamic here too, hopefully helping the HTML5 video cause. There is still much more work to be done. Flash and browser plugins have had a long history at forging new paths, and the Web can come in behind them and standardize. May that continue.
I do watch for single-owned platforms such as Flash, Silverlight, or now the Apple platform (even though they do great work on the HTML5 side of the house). I don't want any of those vendors to have too much power. The thought of a Web that required the use of their technology makes me shudder (we have a piece of that with Flash video). Right now I can turn off those plugins and life moves on. Sure I can't Hulu or Netflix, but that will change. I would miss some of the Flash sites that my kids use, but they could even be partially ported over to HTML5 these days.
I don't want to "kill" these other platforms as they offer competition and spur on the industry. I just don't want any one of them to take over. It may seem like the world would be better if we all just used Macs and iPhones and iPads, but would it? Do you think Steve would be a benevolent dictator?
![]()
Erm, no.
And thus I find myself torn. I really want to go out and by that iPad....... but when is it "too late". Surely I have a few years right? I can enjoy the shiny new toy? :)
Faruk Ate? also has a nice post on where he see's Flash going which is bolder than mine :)
What do you think?
Dad's Cab, a mobile app that turns a Nokia Symbian (5.0) device into a GPS-aware taxi meter, gives dads or moms or roommates, for that matter--a humorous way to make a point and to improve family communications. Developed by ustwo™, in collaboration with creative agency Work Club, Dad’s Cab has been downloaded over 100,000 times in over 150 countries.

SVG-Edit is a nifty open source editing web app that uses SVG and doesn't need a server-side:
The SVG-Edit team recently announced SVG-Edit 2.4, code named Arbelos. New features include:
- Raster Images
- Group/Ungroup
- Zoom
- Layers
- Curved Paths
- UI Localization
- Wireframe Mode
- Change Background
- Draggable Dialogs
- Resizable UI (SVG icons)
- Convert Shapes to Path
Try out the demo here:
http://svg-edit.googlecode.com/svn/branches/2.4/editor/svg-editor.html
Check out the project page:
http://svg-edit.googlecode.com
Read the release notes:
http://code.google.com/p/svg-edit/wiki/VersionHistory
Like for the other parts of Qt, having great performance is important for QtWebKit.
Traditionally, QtWebKit has been mostly used on desktop computers for advanced layouting, hybrid applications or simply to browse the web. On a modern computer, the speed of WebKit is not a problem.
The world has changed, and QtWebKit is now used on mobile phones running Maemo, Symbian or Windows CE, and it is more and more used in embedded application on various devices.
Working on what matters
To improve the performance of WebKit, we works with benchmarks. Those benchmarks are used as use cases when profiling WebKit and to evaluate the gain of our patches.
Those benchmarks and the tools are available on Gitorious, in the QtWebkit performance repository.
WebKit gives a lot of possibilities, and we try to focus our work on what matters. For the performance work, we use real webpages, and look for ways to improve WebKit in the way it is used on the Web.
How we benchmark WebKit
The performance suite has three kinds of tools:
- host tools: to manage the data used by the benchmarks
- tests: the benchmarks
- reductions: some benchmarks for specific components of WebKit
Let’s have a look at the tools and the tests. The full documentation of the performance suite is on the WebKit’s wiki.
Mirroring the web
For the benchmark, we do not want to access Internet directly. We want to compare the results from one run to the other, so we don’t want the pages to change arbitrarily. Using the Web for benchmarking would also create an important load on the servers.
To use real pages without going online, we create databases of web pages with the mirror application:
Those databases are snapshots of webpages at a given point in time, and they are used as input of the benchmarks.
The mirror application uses WebKit to load the pages and intercept all network requests. This means the database also includes resources that are loaded lazily via Javascript.
Using the benchmarks
There are two ways to exploit the databases with the benchmark: the online and offline modes. The difference lies in the way we provide the database’s content to the benchmarks:
In the “online mode“, we use a basic web server to serve the database over HTTP. The benchmarks use the complete stack to load pages, as they would if we were loading the page from Internet.
In the “offline mode“, the database is loaded directly by the benchmarks and is used as the source of data. In that case, the network is not involved. This mode is mostly useful for the benchmarks that do not involve the network (like measuring the rendering speed).
What is measured
The benchmark suite is still a work in progress. Currently, there are benchmarks for:
- the page loading performance (with or without rendering)
- the rendering performance
- the scrolling performance
How you can use that?
If you use WebKit, and are interested in great performance, you can use the performance suite to profile the use case you are interested in, and optimize those cases.
If you evaluate the use of WebKit for embedded, you can use the benchmark to evaluate how good WebKit performs on the hardware.
If you make patches for WebKit’s performance, have a look on how to contribute. You can also join
us on IRC in #qtwebkit on freenode.
This Thursday (February 4th, 14:00
UTC), Morgan Tocker will talk about Optimizing Queries with Explain. Morgan was
a technical instructor at MySQL and works for Percona today.
MySQL University is a free educational online program for engineers/developers. MySQL University sessions are open to anyone, not just Sun employees. Sessions are recorded (slides and audio), so if you can't attend the live session you can look at the recording anytime after the session.
Here's the tentative list of upcoming sessions:
- February 11: MySQL Galera - Multi-Master Replication (Seppo Jaakola & Alex Yurchenko)
- February 18: Performance Schema: Instrumenting Code (Marc Alff)
- February 25: Securich - Security Plugin for MySQL (Darren Cassar)
- March 4: MySQL Column Databases (Robin Schumacher)
- March 11: Improving MySQL Full-Text Search (Kristofer Pettersson)
PlanetMySQL Voting: Vote UP / Vote DOWN
In a previous post, I talked about Internet Explorer 8’s wide array of browser and document modes. Most people are pretty familiar with how the various document modes affect layout in terms of how CSS is implemented, but what has been lost is how the document mode affects the core JavaScript engine in the browser. These changes are somewhat subtle, but important to understand when you’re working with Internet Explorer 8.
A couple of years ago, Microsoft published a paper called, JScript Deviations from ES3, in which they outlined ways in which the JScript engine (the one power Internet Explorer’s JavaScript) had deviated from the ECMAScript 3 standard. These deviations are somewhat innocuous, but chances are that you’ve been bitten by one or more of them at some point in the past. In Microsoft’s attempt to make Internet Explorer 8 more standards-compliant, the same issues that arose around CSS also arose around JavaScript. They could fix the deviations in JScript, but if the browser were running in IE5 or IE7 document modes, there could be problems as these fixes might be incompatible with the code targeting those browsers.
Microsoft chose to create versioned features of the JScript engine for Internet Explorer 8. For IE5 and IE7 document modes, the JScript engine acts as it did in the actual Internet Explorer 7, complete with all deviations from ECMAScript 3. When in IE8 document mode, the deviations are gone and you get the full power of the JScript engine.
Native JSON
Internet Explorer 8’s JScript engine implements the native JSON object object as defined by ECMAScript 5. The object is only present, however, when the page is running in IE8 document mode. This includes the
global JSON object as well as methods used for JSON functionality:
-
Date.prototype.toJSON() -
Number.prototype.toJSON() -
String.prototype.toJSON() -
Boolean.prototype.toJSON()
The JSON object and these methods in IE5 or IE7 document mode are undefined.
Note: Even though Date.prototype.toJSON() is supported in IE8 document, Date.prototype.toISOString() is not implemented. This is strange because they
return the same value.
DOM getters/setters
One of the more curious aspects of the JScript engine is that it implements ECMAScript 5 getters and setters, but only
for DOM objects and not for native JavaScript objects. The implementation is made up of half-baked versions of Object.defineProperty() and
Object.getOwnPropertyDescriptor() that primarily support the get and set properties. For example:
Object.defineProperty(document.body, "active", {
set: function(value){
document.body.className = (value !== false) ? "active" : "";
},
get: function(){
return document.body.className == "active";
}
});
var descriptor = Object.getOwnPropertyDescriptor(document.body, "innerHTML");
alert(descriptor.get); //displays function
Both methods are only available in IE8 document mode and do not exist in other document modes.
Arrays
One of the areas where the JScript implementation really fell apart was in dealing with arrays. Arrays had the most deviations from the ECMAScript 3 standard and were a constant source of
headaches for developers. First, if undefined is passed into join(), the argument was translated into the string “undefined” and that was used to concatenate the items. For
example:
var colors = ["red", "green", "blue"];
alert(colors.join(undefined)); //"redundefinedgreenundefinedblue" in IE7
When running in IE8 document mode, a value of undefined is ignored and the default separator (a comma) is used.
The unshift() method, which pushes an item to the front of the array, also had a deviation in JScript. Instead of returning the length of the array after adding the item, it simply
returned undefined. In IE8 document mode, this has been fixed so that unshift() correctly returns the array length.
The last big change to arrays is the ability to properly inherit from the Array type. Dean Edwards has a whole post
about trying to create a subtype of Array and the problems he encountered. The biggest problem is that assigning an instance of Array to be another constructor’s
prototype meant that the length property would no longer work. Consider the following:
function MyArray(){
}
MyArray.prototype = new Array();
MyArray.prototype.get = function(i){
return this[i];
};
var colors = new MyArray();
colors.push("red");
colors.push("green");
colors.sort();
alert(colors.get(0)); //"green"
alert(colors.length); //in IE7, outputs "0"; in IE8, outputs "2"
In Internet Explorer prior to 8, the length property of any Array type descendant didn’t change automatically, and so inheritance was only truly useful only for non-IE
browsers. In IE8 document mode, though, the length property works as it does in other browsers while IE5 and IE7 document modes use the old deviated behavior.
Miscellaneous fixes
There’s a small group of fixes that can’t really be logically categorized but nonetheless help JScript come more into agreement with other JavaScript implementations. The first is that object literals now allow trailing commas. Prior to Internet Explorer 8, the following would cause a parse error:
var object = {
name: "value",
};
The trailing comma after the last property value is explicitly allowed by ECMAScript 3 syntax and is allowed in all other browsers. IE8 document mode now also supports this syntax correctly (other document modes still throw the error).
Another nice enhancement is that IE8 document mode now allows access to characters in a string via bracket notation:
var s = "Hello world!";
alert(s[0]); //"H"
This brings JScript into line with other JavaScript engines; IE5 and IE7 document modes will still return undefined.
Two other changes that likely don’t affect you but are worth noting:
-
Number.prototype.toPrecision()used to throw an error whenundefinedwas passed in. IE8 document mode now defaults to callingNumber.prototype.toString()in this case. -
Error.prototype.toString()has been properly implemented to provide better error messages.
Conclusion
IE8 document mode offers a whole host of improvements over Internet Explorer 7 not just in CSS but also in JavaScript. If you’re looking to write the most standards-compliant code possible,
make sure your page is being run on Internet Explorer 8 in IE8 document mode (see my previous post for details). Bringing JScript into line with other JavaScript engines is an incredibly
important step. It’s too bad that these details were pretty much overlooked in the Internet Explorer 8 announcements.
Related posts
- Inconsistent array literals
- Internet Explorer 8 document and browser modes
- XPath in JavaScript, Part 3
- Speed up your JavaScript, Part 1
- Inside IE 8’s mutable DOM prototypes
- Cross-domain XHR removed from Firefox 3
P.S. My new book, High Performance JavaScript is coming out in early 2010. Need help now? Check out Professional JavaScript, 2nd Edition.
If you’re going to use color effectively in your designs, you’ll need to know some color concepts and color theory terminology. A thorough working knowledge of concepts like chroma, value and saturation is key to creating your own awesome color schemes. In Part 1: The Meaning of Color of our color theory series, we covered the meanings of different colors. Here, we’ll go over the basics of what affects a given color, such as adding gray, white or black to the pure hue, and its effect on a design, with examples of course.
[Offtopic: by the way, do you know the Smashing Network has its own Smashing Network RSS Feed? Only excerpts are displayed in the feed.]
Hue
Hue is the most basic of color terms and basically denotes an object’s color. When we say “blue,” “green” or “red,” we’re talking about hue. The hues you use in your designs convey important messages to your website’s visitors. Read part 1 of this article for the meanings conveyed by various hues.
Examples

The primary hue of the background and some of the typography on the Happy Twitmas website is bright red.

Using a lot of pure hues together can add a fun and playful look to a design, as done in the header and elsewhere on this website.

Pure red is a very popular hue in Web design.

Mix uses a number of pure hues in its header and logo.

Green in its purer forms is seen less often and so stands out more than some other colors.
Chroma
Chroma refers to the purity of a color. A hue with high chroma has no black, white or gray in it. Adding white, black or gray reduces its chroma. It’s similar to saturation but not quite the same. Chroma can be thought of as the brightness of a color in comparison to white.
In design, avoid using hues that have a very similar chroma. Opt instead for hues with chromas that are the same or a few steps away from each other.
Examples

Cyan has a high chroma and so really stands out against black and white.

Another website with a high chroma blue, though it includes some tints and shades with somewhat lower chromas.

Combining high and low saturation in the same hue can make for a sophisticated and elegant design.

Colors with very high chroma are best used in moderation, as done here.

Differences in chroma can make for a visually pleasing gradient.
Saturation
Saturation refers to how a hue appears under particular lighting conditions. Think of saturation in terms of weak vs. strong or pale vs. pure hues.
In design, colors with similar saturation levels make for more cohesive-looking designs. As with chroma, colors with similar but not identical saturations can have a jarring effect on visitors.
Examples

The saturation levels of many of the different hues used here are similar, adding a sense of unity to the overall design.

Combining colors with similar muted saturation levels creates a soft design, which is emphasized by the watercolor effects.

Hues with lower saturation levels aren’t necessarily lighter, as shown here.

An excellent example of how using a hue with a high saturation against a background with low saturation can make the former really stand out.

Aother example of how low saturation colors make nearby high saturation colors really stand out.
Value
Value could also be called “lightness.” It refers to how light or dark a color is. Ligher colors have higher values. For example, orange has a higher value than navy blue or dark purple. Black has the lowest value of any hue, and white the highest.
When applying color values to your designs, favor colors with different values, especially ones with high chroma. High contrast values generally result in more aesthetically pleasing designs.
Examples

The high value of the yellow used here really stands out against the lower-value black and gray.

This website combines blue hues with two different values. Because the different values have enough contrast, the overall look is visually appealing.

Combining colors with similar values makes for an energetic and lively background (which is enhanced by the design itself).

The red here has a lower value than the light blue, which itself has a lower value than the white.
![]()
The human eye can pick up differences in value even among such similar hues.
Tones
Tones are created when gray is added to a hue. Tones are generally duller or softer-looking than pure hues.
Tones are sometimes easier to use in designs. Tones with more gray can lend a certain vintage feel to websites. Depending on the hues, they can also add a sophisticated or elegant look.
Examples

Tones can give websites a sophisticated look while adding some vintage and antique flair.

This website combines blues in a variety of tones, shades and tints.

Tones can be intensified by adding gray around them, as done here.

The tones used in the navigation and background design here give this website a vintage, hand-made feel.

A great example of how a pure hue can really stand out against a background of tones.

Some colors that we might consider gray are actually tones of other colors. In this case, the background is a blue tone but with a lot of gray added.
Shades
A shade is created when black is added to a hue, making it darker. The word is often incorrectly used to describe tint or tone, but shade only applies to hues made darker by the addition of black.
In design, very dark shades are sometimes used instead of black and can serve as neutrals. Combining shades with tints is best to avoid too dark and heavy a look.
Examples

Jonathan Moore’s website has a variety of different shades of purple in the background (and a couple of tints in other parts).

Using different shades together works well, as long as sufficient contrast between them is maintained.

An effective combination of shades and tints, particularly in the header.

Another background design that has shades (and a few tints) in a textured gradient.

Combining shades within textures adds interest to this website.
Tints
A tint is formed when white is added to a hue, lightening it. Very light tints are sometimes called pastels, but any pure hue with white added to it is a tint.
Tints are often used to create feminine or lighter designs. Pastel tints are especially used to make designs more feminine. They also work well in vintage designs and are popular on websites targeted at parents of babies and toddlers.
Examples

Caio Cardoso’s website has a variety of green tints in the background and in other elements.

The blue tint on Fernando Silanes’s website creates a soft and sophisticated look.

Blue tints are popular for sky and nature motifs.

Tints are also popular in watercolor-based designs.

Tints combined together make for a sophisticated gradient.
Conclusion
While you don’t necessarily have to remember all of these technical terms, you should be familiar with the actual concepts, especially if you want to master part 3 of this series (in which we create our own color schemes). To that end, here’s a cheat sheet to jog your memory:
- Hue is color (blue, green, red, etc.).
- Chroma is the purity of a color (a high chroma has no added black, white or gray).
- Saturation refers to how strong or weak a color is (high saturation being strong).
- Value refers to how light or dark a color is (light having a high value).
- Tones are created by adding gray to a color, making it duller than the original.
- Shades are created by adding black to a color, making it darker than the original.
- Tints are created by adding white to a color, making it lighter than the original.
Further Resources
-
Glossary of Color Terms
An excellent reference from Color Cube. -
Design Tip: Saturate Your Colors
An older article, but still has some valuable information. -
Elements of Design: Value and Color
An excellent lesson in color from the University of Saskatchewan. -
Color
An article from Design Notes about color and how we perceive it.
(al)
© Cameron Chapman for Smashing Magazine, 2010. | Permalink | 28 comments |
Add to del.icio.us | Digg this | Stumble on StumbleUpon! |
Tweet it! | Submit to Reddit | Forum Smashing Magazine
Post tags: colors
A Googler and a Facebooker were in a pub discussing the complexities of building out a rich modern Web application. There are a ton of dependencies, and you need to be proficient in multiple languages and tools (JavaScript, HTML, CSS, SQL/NoSQL, backend languages, build tools, etc).
Well, they may not have been in a pub.... but a deadly duo did get together to try to solve this problem.
Dustin Moskovitz (Facebook co-founder and former CTO) and former-Googler/Facebooker Justin Rosenstein decided to try something different when they started to implement a Collaborative Information Manager tool at their new startup . They have created a new high level language that is part JavaScript, part Protocol Buffers. The language is LunaScript.
What was their motivation?
All of us on the Asana team have deep backgrounds writing rich web applications at companies like Google and Facebook. We've been continually frustrated by how long it takes to write software, and by a nagging feeling that in some deep sense we've been writing the same code over and over. Even when using the latest and greatest frameworks and disciplines, writing fast, highly interacting web applications involves a lot of accidental complexity:
First you need server code to figure out what data the browser needs. Hopefully you have an ORM layer, but you still need to carefully structure your code to minimize your backend dispatches, and you need to carefully keep that in sync with your front-end code lest you don't fetch enough data or hurt performance by fetching too much. If it's a Web 2.0-style app, you re-implement a ton of that server-side code in JavaScript, once for creating the page and then again as controller code for keeping it up to date and consistent. And when the user changes something, you bottle that up -- typically in a custom over-the-wire format -- and send it as an XHR to the server. The server has to de-serialize it into different data structures in a different language, notify the persistence store, figure out what other clients care about the change, and send them a notification over your Comet pipe, which is handled by yet more JavaScript controller code. Offline support? More code.
This is not a one-off task: it's rote work that adds complexity to every feature that you build in every application. By the time that you are done with all this, the important and novel parts of your application are only around 10% of your code. We wondered whether we could build a programming system in which we just wrote that 10% -- the essential complexity -- and a compiler handled the other 90%.
And this lead them to their solution:
Inspired by incremental computing, we're building Lunascript as a simple way to write modern web applications. Lunascript has a syntax and easy of use reminiscent of JavaScript, but a powerful pure-functional lazily-evaluated semantics historically confined to academic languages.
A Lunascript application specifes a data model and a function from the model to the view or user interface, annotated with handler functions from user inputs to model mutations. From this the Lunascript compiler produces a functioning Web2.0 application -- the client-side JavaScript, the server-side SQL, and everything in between -- complete with real-time bidirectional data synchronization. There's no need to write separate code to help the server figure out which values need to be sent to the client: the server can do this by simulating the UI. Because a LunaScript application only specifies how the UI should look given the current data (rather than how the UI should be updated as changes happen) it's impossible to write a UI that loads correctly but does not stay correct as changes are made.
"What does it look like?" I hear you cry. Time for a hello world, and since Comet is in the mix, that means a chat server:
-
-
// Some of our currently implemented syntax isn't quite this clean, but it's
-
// fairly close and this is the direction we're going.
-
-
class World {
-
// "1." serves the same purpose as "= 1" does in Google protocol buffer syntax.
-
1. ChatMessage[] messages;
-
};
-
-
class ChatMessage {
-
1. User user;
-
2. string text;
-
};
-
-
class Session {
-
1. User user;
-
2. String new_comment;
-
};
-
-
return fn(world, browser, session) {
-
var renderMessage = fn(message) {
-
// Most style information omitted to improve readability.
-
var bubble_style = { background: '#b7e0ff', padding: 7, ... };
-
-
return <div> // XML literals are first-class primitives.
-
<img src=message.user.small_pic_url />
-
<div style=bubble_style>
-
<b> message.user.name, ': ' </b>
-
<div> message.text </div>
-
</div>
-
</div>;
-
};
-
-
var postMessage = fn() {
-
// Only handler functions can request data mutations.
-
messages += ChatMessage {
-
user: session.user,
-
text: session.new_comment
-
};
-
session.new_comment := '';
-
};
-
-
return <table>
-
<tr><td>
-
messages.map(renderMessage)
-
</td></tr>
-
<tr><td>
-
<img src=(session.user.small_pic_url) />
-
<div>
-
<input data=session.user.name /> <b>' (your nickname)'</b>
-
<form onsubmit=postMessage>
-
<input data=session.new_comment hasFocus=true />
-
</form>
-
</div>
-
</td></tr>
-
</table>;
-
};
-
You will notice the protobufferness at the top, and the fn of less characters, and E4X-like.
To learn more, let's listen in to Dustin as he gives us a walk through the world of LunaScript:
I talked to the guys and asked a few questions which they answered..... what questions do you have for them though? Are you excited about what a higher level abstraction could give you? Or do you like to be close to the metal?
In about a month we'll be launching a new feature on the Yahoo! Developer Network (YDN) called the Create Consumer Key API (CCK API). This blog post is a sneak peek-- describing what it is, who should use it, and how interested 3rd parties can start integrating with it early.
What is it?
Many developers who use Yahoo! Web services and APIs distribute applications that enable their users to tap into Yahoo! user data (with user permission). In these cases, both the developer and each of their end-users signs up for a distinct OAuth Consumer Key. The Consumer Key ensures that the right data, for the right user, is going to the right developer.
YDN aims to make it easier to broker out or sub-syndicate access to Yahoo! data, so we have been working on a programmatic way to trigger the creation of Consumer Keys.
The CCK API offers the following benefits to developers:
Streamlines the process of using your application: Your users do not separately request an OAuth Consumer Key from YDN.
One call: One form provides all the necessary information for a Consumer Key, such as access scopes and redirect URLs.
One-click authorization: Your users do not need to know about access scopes, and you have the option to automatically send the Consumer Key and Secret back to your application
with no copy-and-paste necessary.
Who should use it?
Where to find more details
We'll be posting additional details on the YDN blog when we are closer to launch, including screenshots of the user flow, links to the API, and documentation for how to integrate with it.
In the meantime, if this sounds like something that interests you and you want to get started early, please send an email to cck-api@yahoo-inc.com with your name/role, a description of your product, and a URL we can check out. We'll be happy to share additional details so that you can start exploring and/or planning your integration early.
The Yahoo! Developer Network offers services that make it easy to build applications that make the web a more useful and interesting place for everyone. This API should made it even easier.
Daniel Raffel
Senior Product Manager
Yahoo! Open Strategy
PlanetMySQL Voting: Vote UP / Vote DOWN
We took the opportunity presented by pushdo attacking www.sans.org, and collected some traffic for further analysis. www.sans.org receives a good amount of legitimate https traffic as well, which made isolating the Pushdo traffic a bit challenging. We focused on a slice of about 10 minutes worth of traffic to ease analysis.
I used the following two snort rules to isolate the traffic:
alert tcp any 443 - any any (content: |15 03 00| msg: SSL 3 Illegal Parameter sid: 1000001)
alert tcp any any - any 443 ( msg:Pushdo DoS Request - July 17, 1970 timestamp content:|16|
content:|01| content:|01 01 01 01|)
One pattern Pushdo exhibits is the use of malformed SSL Helo requests after the TCPconnection is established. The server will respond to these requests with an SSLerror. The first rule tries to match the SSLerror, while the second rule looks for the Pushdo request.
The most aggressive pushdo infected hosts appear to establish a connection about once a minute. We identified about 10k host attacking www.sans.org. According to some reports, Pushdo will also just establish a TCP connection, and then just sit without actually sending the SSLHelo message.
All this is consistent with Pushdo being a simple DDoS bot. The impact is limited at this point, in part due to the firepower of the botnet being spread across a large number of targets. For more details on Pushdo, see Shadowserver's blog posting [2].
[1] http://isc.sans.org/diary.html?storyid=8125
[2] http://www.shadowserver.org
------
Johannes B. Ullrich, Ph.D.
SANS Technology Institute
On Friday we did a test of the change in our staging environment.
After setting up the master-master pair, the first thing we verified was writes/table creates, etc. were flowing in both directions for the database we planned to replicate between the two. Lets just call it "db1".
To enable this I had used the option: replicate-do-db=db1 in the my.cnf on both DB machines.
After we verified this, I was told that we should probably also replicate "db2". I edited the config on both machines and changed the option to be replicate-db-db=db1,db2
We then proceeded to take a snapshot of our staging environment for these dbs so that we could test failover, app performance, etc.
We restored the snapshot, brought up the app and everything looked fine. We tested failovers. All looked good.
The change was pushed into production over the weekend and on Sunday night a network glitch caused the HA to failover to make the second DB in the pair active. Then late Monday evening someone noticed that changes didn't actually seem to be replicating between the two, although SHOW SLAVE STATUS reported IO and SQL threads running and everything was caught up.
Enter the culprit - my replicate-do-db setting
The correct way to tell MySQL to enable replication for select DBs is to issue the parameter multiple times:
replicate-do-db=db1
replicate-do-db=db2
The configuration as I had it was actually telling MySQL to filter and only replicate a database called "db1,db2" which of course did not exist.
Despite the fact we thought that we'd been good at testing, this managed to slip through.
I guess even someone who has been using MySQL for almost 10 years can make silly mistakes. Whoops!
Here's hoping that someone else out there can learn from my mistake!
Lachlan
PlanetMySQL Voting: Vote UP / Vote DOWN
Aaron Boodman created Greasemonkey back in the day. He also worked on Gears. And most recently he created Chrome Extensions. I have a funny feeling that folks were pinging him daily "hey, when ya gunna give me Greasemonkey on Chrome" and he just delivered:
One thing that got lost in the commotion of the extensions launch is a feature that is near and dear to my heart: Google Chrome 4 now natively supports Greasemonkey user scripts. Greasemonkey is a Firefox extension I wrote in 2004 that allows developers to customize web pages using simple JavaScript and it was the inspiration for some important parts of our extension system.
Ever since the beginning of the Chromium project, friends and coworkers have been asking me to add support for user scripts in Google Chrome. I'm happy to report that as of the last Google Chrome release, you can install any user script with a single click. So, now you can use emoticons on blogger. Or, you can browse Google Image Search with a fancy lightbox. In fact, there's over 40,000 scripts on userscripts.org alone.
Not all of the scripts will work. The deeper the integration, the less chance of success. We now have user scripts supported in a variety of browsers, and hopefully they get more and more portable.
If browsers could surface the functionality to mainstream users, good things could happen beyond us power users.
At the Internet Storm Center, we feature a poll on our home page. As part of the poll, you will find a comment field. Sadly, this comment field is frequently abused for spam. Not that it does any good. The spam is easily filtered and all comments have to be approved anyway. But just today, we had a large number of hosts trying to post spam at a rate of several posts a minute. The timing suggests that all these hosts are part of a single bot net. The “attack” is ongoing as I type this.
Here is a captured full sample request (note that the upper case header names are an artifact of the collection)
POST /poll.html HTTP/1.1 HOST: isc.sans.org ACCEPT: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 REFERER: http://isc.sans.org/ USER-AGENT: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) COOKIE: dshield=a56291441771f2d3d948a383fe774889e2d2f018 COOKIE2: $Version="1" VIA: 1.1 hebergement.gratisim.fr CONNECTION: Keep-Alive Post Data: token: poll: 1 poll_comment: qYAV4f <a href="http://vjrimatpckvt.com/">vjrimatpckvt</a>, [url=http://zdzyzolzspzd.com/]zdzyzolzspzd[/url], [link=http://zloyarufkbun.com/]zloyarufkbun[/link], http://mlsorofkvzxa.com/ subject: NBxnTAriuXTkDjGJ
There are a couple of odd and interesting attributes to this request:
- The “ACCEPT” header looks very real. Many scripts and bot do not spoof it that well
- The request uses a correct “Referer” header.
- The User-Agent looks real too, but a bit “short”. A windows XP host without .Net and anything else?
- The cookie is in particular interesting. A different session cookie is used for each request. But oddly, the (local) Google Analytics cookies are missing.
- Not sure what the Cookie2 is supposed to do… Maybe identifying the bot?
- the “Via:” header is only present in some of the requests, and probably incidental. Some of the infected systems appear to be housed behind a proxy server.
Finally, the content: The domains “advertised” do not appear to be exist. This may be a trial to figure out if these URLs are posted to the site or not. Note that the attack uses 4 different link styles:
- Standard HTML Link <a href=”x”>x</a>
- BBCode [url link
- BBCode [link link
- “naked” URL
Given that these URLs don’t exist (and they change from request to request), I think this is just a test run.
If anybody knows what the Cookie2 header is supposed to do… please comment below or let me know directly.
We are excited to announce that we’ve added support for job flow debugging in the AWS Management Console – making Elastic MapReduce even easier to use for developing large data processing and analytics applications. This capability allows customers to track progress and identify issues in the steps, jobs, tasks, or task attempts of their job flows. The job flow logs continued to be saved in Amazon S3 and now the state of tasks and task attempts is persisted in Amazon SimpleDB so customers can analyze their job flows even after they’ve completed.
Very simple steps to start the debugging process:
Step 0: Select "Enable Hadoop Debugging" in the Create New Job Flow wizard.
Step 1: Select the Job Flow and click on "Debug"
Step 2: Job Flow has one or more steps. You can view the log files of a specific step within your job flow.
Step 3: Each step might have one or more Hadoop jobs. Click on "View Tasks" next to a job to drill down and see different Hadoop tasks within that job.
Step 4: You will a see the list of tasks that have failed. Click on task that you would like to debug and view the task attempts.
Step 5: You can click on a specific task attempt and see the log files associated with that particular task attempt
Step 6: Discover the error.
With just a few clicks in the AWS management console, you can find the error in your Elastic MapReduce job flows amongst thousands of jobs and restart the job flow again with a few clicks.
-- Jinesh
Hi all,
I've published a tutorial about creating a sample widget with APIBridge, it's available here: Build your first Web Runtime widget with APIBridge.
It tries to explain all the involved steps: from developing the widget, to building and deploying. I would be glad to have your feedback about it, and especially suggestions on how and where it can be improved :)
The big wins:
- One Execution path (less bugs)
- Simple interface, which means more langauges
- Zero materialization happening
- Less Code. This allows us to remove a lot of code (and single shot passes for particular use cases).
The data dictionary operates entirely off the proto system, so what you see is what we have. We use the table names stored within the proto so no translation ever happens. This is pretty handy for filesystems which do not preserve case (and we don't have to do anything to support them any longer).
You can also type "SELECT * FROM DATA_DICTIONARY.SCHEMAS".
There is no longer a "SCHEMATA" tables, just SCHEMAS. Want INDEXES? SELECT FROM INDEXES.
We will also be able to split up the tables that are from the SQL ANSI standard one from the ones that are not. The advantage is that we can provide an ANSI compliant INFORMATION_SCHEMA, and still have plenty of room to add additional tables as we see fit (yes, like the tables we provide today which house the information on the active Memcached cluster information).
drizzle> use data_dictionary; Database changed drizzle> select * from plugins; +-------------------------------------------+-----------------------+-----------+-------------+ | PLUGIN_NAME | PLUGIN_TYPE | IS_ACTIVE | MODULE_NAME | +-------------------------------------------+-----------------------+-----------+-------------+ | ARCHIVE | StorageEngine | TRUE | TRUE | | ascii | Function | TRUE | TRUE | | benchmark | Function | TRUE | TRUE | | BLACKHOLE | StorageEngine | TRUE | TRUE | | char_length | Function | TRUE | TRUE | | character_length | Function | TRUE | TRUE | | CHARACTER_SETS | TableFunction | TRUE | TRUE | | COLLATIONS | TableFunction | TRUE | TRUE | | COLUMNS | TableFunction | TRUE | TRUE | | compress | Function | TRUE | TRUE | | connection_id | Function | TRUE | TRUE | | console | Listen | TRUE | TRUE | | crc32 | Function | TRUE | TRUE | | CSV | StorageEngine | TRUE | TRUE | | default_replicator | TransactionReplicator | TRUE | TRUE | | drizzle_protocol | Listen | TRUE | TRUE | | Error_message_stderr | ErrorMessage | TRUE | TRUE | | FunctionEngine | StorageEngine | TRUE | TRUE | | GLOBAL_STATEMENTS | TableFunction | TRUE | TRUE | | GLOBAL_STATUS | TableFunction | TRUE | TRUE | | GLOBAL_VARIABLES | TableFunction | TRUE | TRUE | | hello_world | Function | TRUE | TRUE | | INDEX_PARTS | TableFunction | TRUE | TRUE | | INDEXES | TableFunction | TRUE | TRUE |
PlanetMySQL Voting: Vote UP / Vote DOWN
In the first part of Douglas Crockford’s five-part series on the JavaScript programming language, he explores the historical context from which JavaScript emerged. But he begins with a little bit of his own history, relating his efforts as a child to build a homemade computer:
I found some pieces of particle board and a saw and I sketched out what it was going to look like, and started sawing. I sawed, and sawed, and sawed. The particle board was really, really hard, and the saw was really, really dull. I sawed for what must have been at least two minutes, and then I gave up. OK, I’m not going to do that. So I probably went into the house and watched television after that. At that time, even at that tender age, it was already obvious that I was going to be a software guy.
For the better part of two hours, Douglas takes you on a historical journey in which you learn about:
- the origin of the eighty-character limit
- the history of punch-cards and their impact on modern programming
- the origin of the term “spaghetti code”
- why accessibility has gone downhill since the days of the Teletype
- why we’re still living with both a carriage return character and a line feed character, and where those concepts originated
- the genealogy of command-line text editors
- what languages like ALGOL, Simula, and Self have to do with JavaScript
- why “the guys who could write for the [Atari] VCS were heroes”
- why innovation in software is slower than innovation in hardware
A few tickets remain for the next four installments of the series, which resumes Friday night with “Chapter 2: And Then There Was JavaScript.” We hope to see you here.
If the video embed below doesn’t show up correctly in your RSS reader of choice, be sure to click through to watch the high-resolution version of the video on YUI Theater or download the video in HD (700MB).
Other Recent YUI Theater Videos:
- John Resig: Testing, Performance Analysis, and jQuery 1.4 — John Resig of Mozilla, creator of the popular jQuery JavaScript library, reviews options for testing and performance analysis in JavaScript and previews the significant changes coming soon in jQuery 1.4.
- Luke Smith: Events Evolved — YUI engineer Luke Smith provides a deep introduction to the YUI 3 event system including its support for DOM events, event delegation, synthetic events, and custom events.
- Satyen Desai: A Widget Walkthrough — YUI engineer Satyen Desai provides a detailed tour of the YUI 3 widget subsystem.
Subscribing to YUI Theater:
Hi everyone,
Today we released Security Advisory 980088 to address a publicly disclosed vulnerability in Internet Explorer that may allow Information Disclosure for customers running on Windows XP or who have disabled Internet Explorer Protected Mode. At this time we are not aware of any attacks seeking to use the vulnerability.
Customers running Internet Explorer 7 or Internet Explorer 8 in their default configuration on Windows Vista or later operating systems are not vulnerable to this issue as they benefit from Internet Explorer Protected Mode, which protects from this issue. Windows XP users, or users who have disabled Protected Mode, can help protect themselves by implementing Network Protocol Lockdown. We have created a Microsoft Fix It to automate this. The Fix It can be run on individual systems or enterprises can deploy it through their automated systems.
We are working to produce an update for this vulnerability and when that is complete, we will take appropriate action to protect customers, which may include releasing an update out-of-band. As with any update, we have to balance overall quality and ensure application compatibility before we release it.
Microsoft is also working with our Microsoft Active Protections Program (MAPP) partners to help provide broader protections for customers. Together with our partners, we will continue to monitor the threat landscape and will take action against any web sites that seek to exploit this vulnerability.
We continue to encourage customers to upgrade to Internet Explorer 8 to benefit from the increased protections provided in the newer version. In addition, customers should continue to follow our “Protect Your Computer” guidance at http://www.microsoft.com/protect.
Thanks!
Jerry Bryant
Sr. Security Communications Manager – Lead
*This posting is provided "AS IS" with no warranties, and confers no rights.*
The beauty of experimentation is that failures are just as fun as successes. Warning: this post is about a failure, so you can skip it altogether
The perf advent calendar was my attempt to flush out a bunch of stuff, tools and experiments I was doing but never had the time to talk about. I guess 24 days were not enough. Here's another little experiment I made some time ago and forgot about. Let me share before it disappears to nothing with the next computer crash.
I've talked before about base64-encoded data URIs. I mentioned that according to my tests base64 encoding adds on average 33% to the file size, but gzipping brings it back, sometimes to less than the original.
Then I saw a comment somewhere (reddit? hackernews?) that the content before base64-encoding better be uncompressed, because it will be gzipped better after that. It made sense, so I had to test.
"Whoa, back it up... beep, beep, beep" (G. Constanza)
When using data URIs you essentially do this:
- take a PNG (which contains compressed data),
- base64 encode it
- shove it into a CSS
- serve the resulting CSS gzipped (compressed)
See how it goes: compress - encode - compress again. Compressing already compressed data doesn't sound like a good idea, so it sounds believable that skipping the first compression might give better results. Turns out it's not exactly the case.
Uncompressed PNG?
The PNG format contains information in "chunks". At the very least there's header (IHDR), data (IDAT) and end (IEND) chunks. There could be other chunks such as transparency, background and so on, but these three are required. The IDAT data chunk is compressed to save space, but it looks like it doesn't have to be.
PNGOut has an option to save uncompressed data, like
$ pngout -s4 -force file.png
This is what I tried - took several compressed PNGs, uncompressed them (with PNGOut's -s4), then encoded both with base64 encoding, put them in CSS, gzip the CSS and compared file sizes.
Code
<?php // images to work with $images = array( 'html.png', 'at.png', 'app.png', 'engaged.png', 'button.png', 'pivot.png' ); //$images[] = 'sprt.png'; //$images[] = 'goog.png'; //$images[] = 'amzn.png'; //$images[] = 'wiki.png'; // css strings to write to files $css1 = ""; $css2 = ""; foreach ($images as $i) { // create a "d" file, d as in decompressed copy($i, "d$i"); $cmd = "pngout -s4 -force d$i"; exec($cmd); // selector $sel = str_replace('.png', '', $i); // append new base64'd image $file1 = base64_encode(file_get_contents($i)); $css1 .= ".$sel {background-image: url('data:image/png;base64,$file1');}n"; $file2 = base64_encode(file_get_contents("d$i")); $css2 .= ".$sel {background-image: url('data:image/png;base64,$file2');}n"; } // write and gzip files file_put_contents('css1.css', $css1); file_put_contents('css2.css', $css2); exec('gzip -9 css1.css'); exec('gzip -9 css2.css'); ?>
Results
I tried to keep the test reasonable and used real life images - first the images that use base64 encoding in Yahoo! Search results. Then kept adding more files to grow the size of the result CSS - added Y!Search sprite, Google sprite, Amazon sprite and Wikipedia logo.
| test | with compressed PNG, bytes | with uncompressed PNG, bytes | difference, % |
|---|---|---|---|
| Y!Search images | 700 | 1506 | 54% |
| previous + Y!Search sprite | 5118 | 8110 | 36% |
| previous + Google sprite | 27168 | 40836 | 33% |
| previous + Amazon sprite + Wikipedia logo | 55804 | 79647 | 29% |
Clearly starting with compressed images is better. Looks like the difference becomes smaller as the file sizes increase, it's possible that for very big files starting with uncompressed image could be better, but shoving more than 50K of images inline into a CSS file seems to be missing the idea of data URIs. I believe the idea is to use data URIs (instead of sprites) for small decoration images. If an image is over 50K it better be a separate request and cached, otherwise s small CSS tweak will invalidate the cached images.





























































