• Shortcuts : 'n' next unread feed - 'p' previous unread feed • Styles : 1 2

» Publishers, Monetize your RSS feeds with FeedShow:  More infos  (Show/Hide Ads)

Date: Wednesday, 17 Dec 2008 07:43

Gavin Barraclough is now a qualified WebKit Reviewer. Gavin was the driving force behind the initial versions of both SquirrelFish Extreme (our JavaScript JIT) and WREC (our RegExp JIT) and has done a tremendous job of ushering them towards maturity. Please join me in congratulating Gavin.

Author: "Sam Weinig" Tags: "Uncategorized"
Comments Send by mail Print  Save  Delicious 
Date: Thursday, 23 Oct 2008 12:41

Tor Arne Vestbø is now a qualified WebKit Reviewer. Tor Arne has done a huge amount of work on the Qt port of WebKit, including advanced work such as a Phonon port of the media back end for the <video> element. He’s also helped to enhance our cross-platform abstraction layer. Please join me in congratulating Tor Arne on his reviewer status and thanking him for all of his contributions to WebKit.

Author: "Maciej Stachowiak" Tags: "Uncategorized"
Comments Send by mail Print  Save  Delicious 
Date: Wednesday, 01 Oct 2008 00:06

It has been nine months since our last Web Inspector update and we have a lot of cool things to talk about. If you diligently use the Web Inspector in nightly builds, you might have seen some of these improvements, while other subtle changes might have gone unnoticed.

Some of the Web Inspector improvements were contributed by members of the WebKit community. We really want to get the whole community involved with making this the best web development tool available. Remember, most of the Web Inspector is written in HTML, JavaScript, and CSS, so it’s easy to get started making changes and improvements.

Redesigned Interface

First and foremost, the Web Inspector is now sporting a new design that organizes information into task-oriented groups — represented by icons in the toolbar. The toolbar items (Elements, Resources, Scripts, Profiles and Databases) are named after the fundamental items you will work with inside the respective panels.


The Console is now accessible from any panel. Unlike the other panels, the Console is not just used for one task — it might be used while inspecting the DOM, debugging JavaScript or analyzing HTML parse errors. The Console toggle button is found in the status bar, causing it to animate in and out from the bottom of the Web Inspector. The Console can also be toggled by the Escape key.

Error and warning counts are now shown in the bottom right corner of the status bar. Clicking on these will also open the Console.

In addition to the visual changes to the Console, we have also greatly improved usability by adding auto-completion and tab-completion. As you type expressions, property names will automatically be suggested. If there are multiple properties with the same prefix, pressing the Tab key will cycle through them. Pressing the Right arrow key will accept the current suggestion. The current suggestion will also be accepted when pressing the Tab key if there is only one matched property.

Our compatibility with Firebug’s command line and window.console APIs has also been greatly improved by Keishi Hattori (服部慶士), a student at The University of Tokyo (東京大学) who tackled this area as a summer project.

Elements Panel

The Elements panel is largely the same as the previous DOM view — at least visually. Under the hood we have made number of changes and unified everything into one DOM tree.

  • Descend into sub-documents — expanding a frame or object element will show you the DOM tree for the document inside that element.
  • Automatic updates — the DOM tree will update when nodes are added to or removed from the inspected page.
  • Inspect clicked elements — enabling the new inspect mode lets you hover around the page to find a node to inspect. Clicking on a node in the page will focus it in the Elements panel and turn off the inspect mode. This was contributed by Matt Lilek.
  • Temporarily disable style properties — hovering over an editable style rule will show checkboxes that let you disable individual properties.

  • Style property editing — double click to edit a style property. Deleting all the text will delete the property. Typing or pasting in multiple properties will add the new properties.
  • Stepping for numeric style values — while editing a style property value with a number, you can use the Up or Down keys to increment or decrement the number. Holding the Alt/Option key will step by 0.1, while holding the Shift key will step by 10.

  • DOM attribute editing — double click to edit a DOM element attribute. Typing or pasting in multiple attributes will add the new attributes. Deleting all the text will delete the attribute.
  • DOM property editing — double click to edit a DOM property in the Properties pane. Deleting all the text will delete the property, if allowed.
  • Metrics editing — double click to edit a any of the CSS box model metrics.
  • Position metrics — the Metrics pane now includes position info for absolute, relative and fixed positioned elements.

Resources Panel

The Resources panel is a supercharged version of the previous Network panel. It has a similar looking timeline waterfall, but a lot has been done to make it even more useful.

  • Graph by size — click Size in the sidebar to quickly see the largest resources downloaded.
  • Multiple sorting options — there are many sorting methods available for the Time graph, including latency and duration.
  • Latency bars — the Time graph now shows latency in the bar with a lighter shade. This is the time between making the request and the server’s first response.
  • Unified resource views — clicking a resource in the sidebar will show you the data pulled from the network (not downloaded again), including the request and response headers.
  • View XHRs — the time and size graphs also show XMLHttpRequests. Selecting an XHR resource in the sidebar will show the XHR data and headers.

Scripts Panel

The previous standalone Drosera JavaScript debugger has been replaced with a new JavaScript debugger integrated into the Web Inspector. The new integrated JavaScript debugger is much faster than Drosera, and should be much more convenient.

From the Scripts panel you can see all the script resources that are part of the inspected page. Clicking in the line gutter of the script will set a breakpoint for that line of code. There are the standard controls to pause, resume and step through the code. While paused you will see the current call stack and in-scope variables in the right-hand sidebar.

The Web inspector has a unique feature regarding in-scope variables: it shows closures, “with” statements, and event-related scope objects separately. This gives you a clearer picture of where your variables are coming from and why things might be breaking (or even working correctly by accident).

Profiles Panel

The brand new JavaScript Profiler in the Profiles panel helps you identify where execution time is spent in your page’s JavaScript functions. The sidebar on the left lists all the recorded profiles and a tree view on the right shows the information gathered for the selected profile. Profiles that have the same name are grouped as sequential runs under a collapsible item in the sidebar.

There are two ways to view a profile: bottom up (heavy) or top down (tree). Each view has its own advantages. The heavy view allows you to understand which functions have the most performance impact and the calling paths to those functions. The tree view gives you an overall picture of the script’s calling structure, starting at the top of the call-stack.

Below the profile are a couple of data mining controls to facilitate the dissection of profile information. The focus button (Eye symbol) will filter the profile to only show the selected function and its callers. The exclude button (X symbol) will remove the selected function from the entire profile and charge its callers with the excluded function’s total time. While any of these data mining features are active, a reload button is available that will restore the profile to its original state.

WebKit’s JavaScript profiler is fully compatible with Firebug’s console.profile() and console.profileEnd() APIs, but you can also specify a title in console.profileEnd() to stop a specific profile if multiple profiles are being recorded. You can also record a profile using the Start/Stop Profiling button in the Profiles panel.

Databases Panel

The Databases panel lets you interact with HTML 5 Database storage. You can examine the contents of all of the page’s open databases and execute SQL queries against them. Each database is shown in the sidebar. Expanding a database’s disclosure triangle will show the database’s tables. Selecting a database table will show you a data grid containing all the columns and rows for that table.

Selecting a database in the sidebar will show an interactive console for evaluating SQL queries. The input in this console has auto-completion and tab-completion for common SQL words and phrases along with table names for the database.


Accompanying the task-oriented reorganization, the search field in the toolbar now searches the current panel with results being highlighted in the context of the panel. Targeting the search to the current panel allows each panel to support specialized queries that are suited for the type of information being shown. The panels that support specialized queries are Elements and Profiles.

The Elements panel supports XPath and CSS selectors as queries in addition to plain text. Any search you perform will be attempted as a plain text search, a XPath query using document.evaluate() and a CSS selector using document.querySelectorAll(). All the search results will be highlighted in the DOM tree, with the first match being revealed and selected.

The Profiles panel supports plain text searches of the function names and resource URLs. Numeric searches are also supported that match rows in the profile’s Self, Total and Calls columns. To facilitate powerful numeric searching, there are a few operators and units that work to extend or limit your results. For example you can search for “> 2.5ms” to find all the functions that took longer than 2.5 milliseconds to execute. In addition to “ms”, the other supported units are: “s” for time in seconds and “%” for percentage of time. The other supported operators are “< ”, “<=”, “>=” and “=”. When no units are specified the Calls column is searched.

In all the panels pressing Enter in the search field or ⌘G (Ctrl+G on Windows and Linux) will reveal the next result. Pressing ⇧⌘G (Ctrl+Shift+G on Windows and Linux) will reveal the previous result. In the Resources, Scripts and Profiles panels the search will be performed on the visible view first and will automatically jump to the first result only if the visible view has a match.

Availability and Contributing

All of these things are available now in the Mac and Windows nightly builds. Give them a try today, and let us know what you like (or don’t like).

If you would like to contribute, there are some really interesting tasks in the list of Web Inspector bugs and enhancements, and other contributors in the #webkit chat room are pretty much always available to provide help and advice.

Author: "Timothy Hatcher" Tags: "Uncategorized, debugger, inspector, prof..."
Comments Send by mail Print  Save  Delicious 
Date: Friday, 26 Sep 2008 01:29

Today we would like to announce that WebKit is the first browser engine to fully pass Acid3. A while back, we posted that we scored 100/100 and matched the reference rendering. Now, thanks to recent speedups in JavaScript, DOM and rendering, we have passed the third condition, smooth animation on reference hardware.

Here is a screenshot of a successful run:

Here is the timing reference dialog you get by clicking on the “A” in Acid3 that confirms we pass the smooth animation condition on a 2.4GHz MacBook Pro:

To try it for yourself, grab a nightly. Keep in mind that on slower machines, the timing may not be perfect, and you need to do a cached run of the test (load it once, close window, open new window, load it again) to avoid delays from the network.

Author: "Maciej Stachowiak" Tags: "Uncategorized"
Comments Send by mail Print  Save  Delicious 
Date: Friday, 19 Sep 2008 05:00

Just three months ago, the WebKit team announced SquirrelFish, a major revamp of our JavaScript engine featuring a high-performance bytecode interpreter. Today we’d like to announce the next generation of our JavaScript engine - SquirrelFish Extreme (or SFX for short). SquirrelFish Extreme uses more advanced techniques, including fast native code generation, to deliver even more JavaScript performance.

For those of you who follow WebKit development and are interested in contributing, we’d like to report our results and what we did to achieve them.

How Fast is It?

This chart shows WebKit’s JavaScript performance in different versions - bigger bars are better.

bar graph showing WebKit 3.0: 5.4; WebKit 3.1: 18.8; SquirrelFish: 29.9; SquirrelFish Extreme: 63.6

The metric is SunSpider runs per minute. We present charts this way because “bigger is better” is easier to follow when you have a wide range of performance results. As you can see, SquirrelFish Extreme as of today is more than twice as fast as the original SquirrelFish, and over 10 times the speed you saw in Safari 3.0, less than a year ago. We are pretty pleased with this improvement, but we believe there is more performance still to come.

Quite a few people contributed to these results. I will mention a few who worked on some key tasks, but I’d also like to thank all of the many WebKit contributors who have helped with JavaScript and performance.

What makes it so fast?

SquirrelFish Extreme uses four different technologies to deliver much better performance than the original SquirrelFish: bytecode optimizations, polymorphic inline caching, a lightweight “context threaded” JIT compiler, and a new regular expression engine that uses our JIT infrastructure.

1. Bytecode Optimizations

When we first announced SquirrelFish, we mentioned that we thought that the basic design had lots of room for improvement from optimizations at the bytecode level. Thanks to hard work by Oliver Hunt, Geoff Garen, Cameron Zwarich, myself and others, we implemented lots of effective optimizations at the bytecode level.

One of the things we did was to optimize within opcodes. Many JavaScript operations are highly polymorphic - they have different behavior in lots of different cases. Just by checking for the most common and fastest cases first, you can speed up JavaScript programs quite a bit.

In addition, we’ve improved the bytecode instruction set, and built optimizations that take advantage of these improvements. We’ve added combo instructions, peephole optimizations, faster handling of constants and some specialized opcodes for common cases of general operations.

2. Polymorphic Inline Cache

One of our most exciting new optimizations in SquirrelFish Extreme is a polymorphic inline cache. This is an old technique originally developed for the Self language, which other JavaScript engines have used to good effect.

Here is the basic idea: JavaScript is an incredibly dynamic language by design. But in most programs, many objects are actually used in a way that resembles more structured object-oriented classes. For example, many JavaScript libraries are designed to use objects with “x” and “y” properties, and only those properties, to represent points. We can use this knowledge to optimize the case where many objects have the same underlying structure - as people in the dynamic language community say, “you can cheat as long as you don’t get caught”.

So how exactly do we cheat? We detect when objects actually have the same underlying structure — the same properties in the same order — and associate them with a structure identifier, or StructureID. Whenever a property access is performed, we do the usual hash lookup (using our highly optimized hashtables) the first time, and record the StructureID and the offset where the property was found. Subsequent times, we check for a match on the StructureID - usually the same piece of code will be working on objects of the same structure. If we get a hit, we can use the cached offset to perform the lookup in only a few machine instructions, which is much faster than hashing.

Here is the classic Self paper that describes the original technique. You can look at Geoff’s implementation of the StructureID class in Subversion to see more details of how we did it.

We’ve only taken the first steps on polymorphic inline caching. We have lots of ideas on how to improve the technique to get even more speed. But already, you’ll see a huge difference on performance tests where the bottleneck is object property access.

3. Context Threaded JIT

Another major change we’ve made with SFX is to introduce native code generation. Our starting point is a technique called a “context threaded interpreter”, which is a bit of a misnomer, because this is actually a simple but effective form of JIT compiler. In the original SquirrelFish announcement, we described our use of direct threading, which is about the fastest form of bytecode intepretation short of generating native code. Context threading takes the next step and introduces some native code generation.

The basic idea of context threading is to convert bytecode to native code, one opcode at a time. Complex opcodes are converted to function calls into the language runtime. Simple opcodes, or in some cases the common fast paths of otherwise complex opcodes, are inlined directly into the native code stream. This has two major advantages. First, the control flow between opcodes is directly exposed to the CPU as straight line code, so much dispatch overhead is removed. Second, many branches that were formerly inside opcode implmentations are now inline, and made visible and highly predictable to the CPU’s branch predictor.

Here is a paper describing the basic idea of context threading. Our initial prototype of context threading was created by Gavin Barraclough. Several of us helped him polish it and tune the performance over the past few weeks.

One of the great things about our lightweight JIT is that there’s only about 4,000 lines of code involved in native code generation. All the other code remains cross platform. It’s also surprisingly hackable. If you thought compiling to native code is rocket science, think again. Besides Gavin, most of us have little prior experience with native codegen, but we were able to jump right in.

Currently the code is limited to x86 32-bit, but we plan to refactor and add support for more CPU architectures. CPUs that are not yet supported by the JIT can still use the interpreter. We also think we can get a lot more speedups out of the JIT through techniques such as type specialization, better register allocation and liveness analysis. The SquirrelFish bytecode is a good representation for making many of these kinds of transforms.

4. Regular Expression JIT

As we built the basic JIT infrastructure for the main JavaScript language, we found that we could easily apply it to regular expressions as well, and get up to a 5x speedup on regular expression matching. So we went ahead and did that. Not all code spends a bunch of time in regexps, but with the speed of our new regular expression engine, WREC (the WebKit Regular Expression Compiler), you can write the kind of text processing code you’d want to do in Perl or Python or Ruby, and do it in JavaScript instead. In fact we believe that in many cases our regular expression engine will beat the highly tuned regexp processing in those other languages.

Since the SunSpider JavaScript benchmark has a fair amount of regexp content, some may feel that developing a regexp JIT is an “unfair” advantage. A year ago, regexp processing was a fairly small part of the test, but JS engines have improved in other areas a lot more than on regexps. For example, most of the individual tests on SunSpider have gotten 5-10x faster in JavaScriptCore — in some cases over 70x faster than the Safari 3.0 version of WebKit. But until recently, regexp performance hadn’t improved much at all.

We thought that making regular expressions fast was a better thing to do than changing the benchmark. A lot of real tasks on the web involve a lot of regexp processing. After all, fundamental tasks on the web, like JSON validation and parsing, depend on regular expressions. And emerging technologies — like John Resig’s processing.js library — extend that dependency ever further.

A Word About Benchmarks

We have included some performance results, but don’t take our word for it. You can get WebKit nightlies for Mac and Windows and try for yourself.

The primary benchmark we use to track JavaScript performance is SunSpider. Although, like all benchmarks, it has its flaws, we think it is a balanced test that covers many dimensions of the JavaScript language and many types of code. If you look at test by test results, you will see that different JavaScript implementations have their own strengths and weaknesses. Browser vendors and independent testers have been tracking this benchmark.

Next Steps and How You Can Contribute

We believe the SquirrelFish Extreme architecture has room for lots more optimization, and we’d love to see more developers and testers pitch in. Currently, we are looking at how to use the bytecode infrastructure to perform more information gathering at runtime and then using it to drive better code generation, and we are studying ways to make JS function calls faster. There is also a lot of basic tuning work to do to take more advantage of the basic architectural advances in SFX. In addition, we’re interested in having JIT back ends for other CPU architectures.

If you’d like to follow the development of WebKit’s JavaScript engine more closely, we have created the squirrelfish-dev@lists.webkit.org mailing list (subscribe here) and the #squirrelfish IRC channel on the FreeNode IRC network. Stop on by and you can learn more about our plans, and how you can help.

Try it Out

Try it, test it, browse with it. It’s now available in nightlies. We hope the changes we’ve made help improve your experience of the web.

UPDATE: For the curious, here are some comparisons of SFX to other leading JavaScript engines. Charles Ying has comparisons on a few more benchmarks.

UPDATE 2: For those of you who just can’t get enough of our little mascot, click the SquirrelFish below in a recent WebKit nightly for a demo of SVG animation support.

the SquirrelFish mascot

Author: "Maciej Stachowiak" Tags: "Uncategorized"
Comments Send by mail Print  Save  Delicious 
Date: Monday, 23 Jun 2008 20:58

Cameron Zwarich is now a qualified WebKit Reviewer. Cameron has been doing amazing work on the JavaScript implementation and was one of the core developers on the new bytecode engine. He has also branched out into other areas of the code and squashed bugs of all varieties. Please join me in congratulating Cameron on his reviewer status and thanking him for all of his contributions to WebKit.

Author: "Maciej Stachowiak" Tags: "Uncategorized"
Comments Send by mail Print  Save  Delicious 
Date: Tuesday, 03 Jun 2008 01:37

SquirrelFish Mascot

“Hello, Internet!”

WebKit’s core JavaScript engine just got a new interpreter, code-named SquirrelFish.

SquirrelFish is fast—much faster than WebKit’s previous interpreter. Check out the numbers. On the SunSpider JavaScript benchmark, SquirrelFish is 1.6 times faster than WebKit’s previous interpreter.

SunSpider runs per minute

bar graph of SunSpider runs

Longer bars are better.

What Is SquirrelFish?

SquirrelFish is a register-based, direct-threaded, high-level bytecode engine, with a sliding register window calling convention. It lazily generates bytecodes from a syntax tree, using a simple one-pass compiler with built-in copy propagation.

SquirrelFish owes a lot of its design to some of the latest research in the field of efficient virtual machines, including research done by Professor M. Anton Ertl, et al, Professor David Gregg, et al, and the developers of the Lua programming language.

Some great introductory reading on these topics includes:

I’ve also pored over stacks of terrible books and papers on these topics. I’ll spare you those.

Why It’s Fast

Like the interpreters for many scripting languages, WebKit’s previous JavaScript interpreter was a simple syntax tree walker. To execute a program, it would first parse the program into a tree of statements and expressions. For example, the expression “x + y” might parse to

      /   \
     x     y

Having created a syntax tree, the interpreter would recursively visit the nodes in the tree, performing their operations and propagating execution state. This execution model incurred a few types of run-time cost.

First, a syntax tree describes a program’s grammatical structure, not the operations needed to execute it. Therefore, during execution, the interpreter would repeatedly visit nodes that did no useful work. For example, for the block “{ x++; }”, the interpreter would first visit the block node “{…}”, which did nothing, and then visit its first child, the increment node “x++”, which incremented x.

Second, even nodes that did useful work were expensive to visit. Each visit required a virtual function call and return, which meant a couple of indirect memory reads to retrieve the function being called, and two indirect branches—one for the call, and one for the return. On modern hardware, “indirect” is a synonym for “slow”, since indirection tends to defeat caching and branch prediction.

Third, to propagate execution state between nodes, the interpreter had to pass around a bunch of data. For example, when processing a subtree involving a local variable, the interpreter would copy the variable’s value between all the nodes in the subtree. So, starting at the “x” part of the expression “f((x) + 1)”, a variable node “x” would return x to a parentheses node “(x)”, which would return x to a plus node “(x) + 1”. Then, the plus node would return (x) + 1 to an argument list node “((x) + 1)”, which would copy that value into an argument list object, which, in turn, it would pass to the function node for f. Sheesh!

In our first rounds of optimization, we squeezed out as much performance as we could without changing this underlying architecture. Doing so allowed us to regression test each optimization we wrote. It also set a very high bar for any replacement technology. Finally, having realized the full potential of the syntax tree architecture, we switched to bytecode.

SquirrelFish’s bytecode engine elegantly eliminates almost all of the overhead of a tree-walking interpreter. First, a bytecode stream exactly describes the operations needed to execute a program. Compiling to bytecode implicitly strips away irrelevant grammatical structure. Second, a bytecode dispatch is a single direct memory read, followed by a single indirect branch. Therefore, executing a bytecode instruction is much faster than visiting a syntax tree node. Third, with the syntax tree gone, the interpreter no longer needs to propagate execution state between syntax tree nodes.

The bytecode’s register representation and calling convention work together to produce other speedups, as well. For example, jumping to the first instruction in a JavaScript function, which used to require two C++ function calls, one of them virtual, now requires just a single bytecode dispatch. At the same time, the bytecode compiler, which knows how to strip away many forms of intermediate copying, can often arrange to pass arguments to a JavaScript function without any copying.

Just the Beginning

In a typical compiler, conversion to bytecode is just a means to an end, not an end in itself. The purpose of the conversion is to “lower” an abstract tree of grammatical constructs to a concrete vector of execution primitives, the latter form being more amenable to well-known optimization techniques.

Therefore, though we’re very happy with SquirrelFish’s current performance, we also believe that it’s just the beginning. Some of the compile-time optimizations we’re looking at, now that we have a bytecode representation, include:

  • constant folding
  • more aggressive copy propagation
  • type inference—both exact and speculative
  • specialization based on expression context—especially void and boolean context
  • peephole optimization
  • escape analysis

This is an interesting problem space. Since many scripts on the web are executed once and then thrown away, we need to invent versions of these optimizations that are simple and efficient. Moreover, since JavaScript is such a dynamic language, we also need to invent versions of these optimizations that are resilient in the context of an unknown environment.

We’re also looking at further optimizing the virtual machine, including:

  • constant pool instructions
  • superinstructions
  • instructions with implicit register operands
  • advanced dispatch techniques, like instruction duplication and context threading
  • getting computed goto working on Windows

Performance on Windows has extra room to grow because the interpreter on Windows is not direct-threaded yet. In place of computed goto, it uses a switch statement inside a loop.

Getting Involved

If you’re interested in compilers or virtual machines, this is a great project to join. We’re moving quickly, so the best way to come up to speed is to log on to our IRC channel.

As always, testing out nightly builds and reporting bugs is also a great help.

Extra Bonus Updates

We’ve got some extra bonus info: very early draft documentation of the SquirrelFish VM’s opcodes. For those of you who know about VMs, you may find this enlightening, for those who don’t, you may find it is simpler than you expect.

In addition, we have a detailed comparison of Safari 3.1 vs. SquirrelFish, looking at the individual tests, it is interesting to see which sped up the most. If you look at this comparison to Safari 3.0, you can see that we’ve sped up 4.34x overall since Safari 3, and have improved some kinds of code by over an order of magnitude.

SquirrelFish around the web: There’s lots of interesting discussion in the reddit article about this post. And posts from key SquirrelFish developer Cameron Zwarich has performance data and other info, as does occasional WebKit contributor Charles Ying.

Author: "ggaren" Tags: "Uncategorized"
Comments Send by mail Print  Save  Delicious 
Date: Sunday, 01 Jun 2008 05:04

The latest browser market share data is in, and Safari has hit 6.25%, breaking 6% for the first time. Last month’s share was 5.81%, so this is a significant increase. It was only nine months ago that Safari broke 5%. Safari market share has now almost tripled from 2.14% in June 2005, when the WebKit Open Source project launched.

This growth, combined with recent WebKit adoption in projects such as the Iris Browser, Qt 4.4, Android, Adobe AIR, Epiphany, KDE Plasma, iCab and more, is breathtaking and shows huge positive momentum for the WebKit project. Thanks and congratulations to everyone who has contributed to the project.

Author: "Maciej Stachowiak" Tags: "Uncategorized"
Comments Send by mail Print  Save  Delicious 
Date: Wednesday, 28 May 2008 19:08

It’s that time of year again! Web developers, WebKit hackers, browser developers, or anyone with an interest in cool technology should come have a drink and some snacks, and meet WebKit contributors from Apple and around the world. This event is open to anyone who is interested, free of charge.

Don’t miss out on the nerd party of the century!!!!


Place: Thirsty Bear Restaurant & Brewery (map)
Date: Tuesday, June 10th
Time: 7:30 PM

Author: "Adele Peterson" Tags: "Uncategorized"
Comments Send by mail Print  Save  Delicious 
Date: Thursday, 08 May 2008 02:22

Security is a top priority for the WebKit project. As contributors to the project have grown, it has become apparent that we need a process for safely reporting security vulnerabilities to the WebKit project in addition to the process for reporting vulnerabilities to Apple. Today, we are announcing a new mailing list for this purpose, security [at] webkit.org. In addition, you can now safely report vulnerabilities over https to our bug tracker, https://bugs.webkit.org, by placing the bug in the Security component. The people privy to the mailing list and the Security component are members of the Security group. It currently includes vendors shipping products that include WebKit, active port owners and trusted security experts. If you are shipping a product that includes WebKit and would like to be notified of security issues, please email security [at] webkit.org.

Author: "Sam Weinig" Tags: "Uncategorized"
Comments Send by mail Print  Save  Delicious 
Date: Tuesday, 29 Apr 2008 21:07

WebKit now supports reflections in CSS. Continuing the trend of using adorable baby photos to make features appear more impressive, let me introduce Kate again. :)

A reflection is a replica of the original object with its own specific transform and mask. The box-reflect property can be used to specify the specialized transform and mask that should be used for the replica.

-webkit-box-reflect: <direction> <offset> <mask-box-image>

<direction> can be one of above, below, left or right.
<offset> is a length or percentage that specifies the distance of the reflection from the edge of the original border box (using the direction specified). It can be omitted, in which case it defaults to 0.
<mask-box-image> is a mask-box-image that can be used to overlay the reflection. If omitted, the reflection has no mask.

Reflections will update automatically as the source changes. If you hover over links, you’ll see the hover effect happen in the reflection. If you reflect the <video> element, you will see the video playing in the reflection.

Giving an element a reflection has the effect of creating a stacking context (so it joins opacity, masks and transforms). The reflection is non-interactive, so from the point of view of hit testing, it’s like it isn’t there. The reflection will have no effect on layout (other than being part of a container’s overflow), and can be thought of as similar to box-shadow in this respect.

The example above uses a gradient mask. Here is the sample code:

<img src=”bubbles.jpg” style=”border:5px solid white;-webkit-box-reflect:below 5px -webkit-gradient(linear, left top, left bottom, from(transparent), color-stop(0.5, transparent), to(white));”>

Author: "Dave Hyatt" Tags: "Uncategorized"
Comments Send by mail Print  Save  Delicious 
CSS Masks   New window
Date: Thursday, 24 Apr 2008 19:53

WebKit now supports alpha masks in CSS. Masks allow you to overlay the content of a box with a pattern that can be used to knock out portions of that box in the final display. In other words, you can clip to complex shapes based off the alpha of an image.

Here is a snapshot of the Speed Racer movie trailer clipped to the Safari compass icon. This is in fact a mask applied to the <video> element.

We have introduced new properties to provide Web designers with a lot of control over these masks and how they are applied. The new properties are analogous to the background and border-image properties that already exist.

-webkit-mask (background)
-webkit-mask-attachment (background-attachment)
-webkit-mask-clip (background-clip)
-webkit-mask-origin (background-origin)
-webkit-mask-image (background-image)
-webkit-mask-repeat (background-repeat)
-webkit-mask-composite (background-composite)
-webkit-mask-box-image (border-image)

Use of a mask results in a stacking context being created (similar to how opacity and transforms work). The mask will therefore overlay the child and all of its descendants, and at a minimum will knock out everything outside the border box of the object.

From a Web designer’s perspective, think of the mask as being constructed the way the backgrounds and border-image of a box are constructed. Multiple backgrounds are stacking on top of one another (possibly overlapping) with their own tiling and clipping rules. A border-image can then potentially be stretched or tiled over the backgrounds.

The final resultant image built from putting all of the mask images together, tiling them, stretching them, etc., then becomes the mask used to clip the content. Alpha values of 0 in the mask mean that nothing should be drawn. Alpha values of 1 mean the content should display normally. Anything in between ends up partially transparent.

One key difference between mask-box-image and its border-image counterpart is that it doesn’t attempt to fit itself to border widths. It will just render the corners unscaled and tile/stretch itself into the border box without regard for the border itself. This lets you easily use nine-piece-image effects as masks on elements without borders (often image or video elements).

Here are two sample images. The source image that we want to mask and then the image that we will use as the mask.

We can place a mask on the image element simply by doing this:

<img src=”kate.png” style=”-webkit-mask-box-image: url(mask.png) 75 stretch;”>

The result looks like this:

CSS gradients can be used as the mask image source as well. In the following example a linear gradient is used to achieve a fade effect. For example:

<img src=”kate.png” style=”-webkit-mask-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0,0,0,1), to(rgba(0,0,0,0))”>

Masks respect the border-radius curves of an object. We can add a border-radius to the previous example, and have both the gradient fade effect with rounded corners.

<img src=”kate.png” style=”-webkit-border-radius: 10px; -webkit-mask-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0,0,0,1), to(rgba(0,0,0,0))”>

SVG images can be used as masks. For example, a partially transparent circle:

can be applied as a mask like so:

<img src=”kate.png” style=”-webkit-mask-image: url(circle.svg)”>

The end result is shown below:

All of the power of the multiple background and border-image syntax is at your disposal when building masks!

As usual leave feedback in the comments and file bugs on any problems you notice at http://bugs.webkit.org/.

Author: "Dave Hyatt" Tags: "Uncategorized"
Comments Send by mail Print  Save  Delicious 
Date: Monday, 21 Apr 2008 20:10

Google has released the list of students they will be sponsoring to work on WebKit as part of the Google Summer of Code this year. Congratulations to all of the students. We look forward to working with you closely this summer!

Thank you again to all the great students who applied! Unfortunately we had over twice as many applications as we had funding slots from Google. You’re certainly all welcome to come hack with us in #webkit any time.

Google’s official announcement

Author: "Eric Seidel" Tags: "Uncategorized"
Comments Send by mail Print  Save  Delicious 
Date: Thursday, 17 Apr 2008 19:33

Currently the set of images you can use from CSS consists of the following:

Bitmap Images (PNG, GIF, JPG)
SVG Images

A notable missing ability when compared with explicit DOM content is programmatic drawing into CSS images. The <canvas> element represents a foreground bitmap image that can be drawn into programmatically, but - aside from inefficient hacks involving toDataURL - there hasn’t been any way to draw into the image buffers used by CSS images.

Until now!

In the latest nightlies, you can try out a new feature: the ability to specify named image buffers in CSS and then to draw into them programmatically from JavaScript. Here’s how it works.

background: -webkit-canvas(mycanvas);

Instead of specifying an image URL, you specify a canvas and an identifier to use for that canvas. The following new API on documents can then be used to obtain a drawing context for that canvas.

CanvasRenderingContext getCSSCanvasContext(in DOMString contextType, in DOMString identifier, in long width, in long height);

There is only one CSS canvas for a given global identifier per document. When you obtain the drawing context you also specify the size. The canvas will not be cleared as long as you repeatedly request the same size. Specifying a new size is equivalent to the kind of behavior you’d expect if you resized a <canvas> element, and so the canvas buffer will be cleared.

All objects that observe a CSS canvas of the same name are sharing that canvas. This means that (similar to how animated GIFs work), you can do animations and have them happen in lockstep on all the clients of the canvas. Drawing changes will be propagated to all clients automatically.

Here is an example:

Canvas as Background Image

Author: "Dave Hyatt" Tags: "Uncategorized"
Comments Send by mail Print  Save  Delicious 
Date: Monday, 14 Apr 2008 20:39

WebKit now supports gradients specified in CSS. There are two types of gradients: linear gradients and radial gradients.

The syntax is as follows:

-webkit-gradient(<type>, <point> [, <radius>]?, <point> [, <radius>]? [, <stop>]*)

The type of a gradient is either linear or radial.

A point is a pair of space-separated values. The syntax supports numbers, percentages or the keywords top, bottom, left and right for point values.

A radius is a number and may only be specified when the gradient type is radial.

A stop is a function, color-stop, that takes two arguments, the stop value (either a percentage or a number between 0 and 1.0), and a color (any valid CSS color). In addition the shorthand functions from and to are supported. These functions only require a color argument and are equivalent to color-stop(0, …) and color-stop(1.0, …) respectively.

Paraphrasing the HTML5 spec and adjusting the language slightly to not be canvas-specific:

“The color of the gradient at each stop is the color specified for that stop. Between each such stop, the colors and the alpha component must be linearly interpolated over the RGBA space without premultiplying the alpha value to find the color to use at that offset. Before the first stop, the color must be the color of the first stop. After the last stop, the color must be the color of the last stop. When there are no stops, the gradient is transparent black.

If multiple stops are added at the same offset on a gradient, they must be placed in the order added, with the first one closest to the start of the gradient, and each subsequent one infinitesimally further along towards the end point (in effect causing all but the first and last stop added at each point to be ignored).”

The points of a linear gradient specify a line. Linear gradients must be rendered such that at and before the starting point the color at offset 0 is used, that at and after the ending point the color at offset 1 is used, and that all points on a line perpendicular to the line that crosses the start and end points have the color at the point where those two lines cross (with the colors coming from the interpolation described above).

If x0 = x1 and y0 = y1, then the linear gradient must paint nothing.

For a radial gradient, the first two arguments represent a start circle with origin (x0, y0) and radius r0, and the next two arguments represent an end circle with origin (x1, y1) and radius r1.

Radial gradients must be rendered by following these steps:

If x0 = x1 and y0 = y1 and r0 = r1, then the radial gradient must paint nothing. Abort these steps.

Let x(ω) = (x1-x0)ω + x0

Let y(ω) = (y1-y0)ω + y0

Let r(ω) = (r1-r0)ω + r0

Let the color at ω be the color of the gradient at offset 0.0 for all values of ω less than 0.0, the color at offset 1.0 for all values of ω greater than 1.0, and the color at the given offset for values of ω in the range 0.0 ≤ ω ≤ 1.0

For all values of ω where r(ω) > 0, starting with the value of ω nearest to positive infinity and ending with the value of ω nearest to negative infinity, draw the circumference of the circle with radius r(ω) at position (x(ω), y(ω)), with the color at ω, but only painting on the parts of the surface that have not yet been painted on by earlier circles in this step for this rendering of the gradient.

This effectively creates a cone, touched by the two circles defined in the creation of the gradient, with the part of the cone before the start circle (0.0) using the color of the first offset, the part of the cone after the end circle (1.0) using the color of the last offset, and areas outside the cone untouched by the gradient (transparent black).”

So what exactly is a gradient in CSS? It is an image, usable anywhere that image URLs were used before. That’s right… anywhere. :)

You can use gradients in the following places:

content property

Gradients as Backgrounds

When specifying a gradient as a background, the gradient becomes a background tile. If no size is specified, then the gradient will size to the box specified by the background-origin CSS3 property. This value defaults to padding, so you the gradient will be as large as the padding-box. This is equivalent to a specified background-size of 100% in both directions.

If you want to achieve effects like tiling of a vertical gradient using a narrow strip, you should specify background-size to give the gradient tile an explicit size.

Gradients used as backgrounds will respect full page zoom, acquiring sharper resolution as the page is zoomed in.

Background Gradients Example

Border Image Gradients

Gradients can be used as border images. The most sensible use for them is specifying only horizontal or only vertical borders (and splitting the gradients up between the top and bottom or left and right borders).

The size of the gradient image is always the size of the border box.

Border Image Gradient Example

List Bullet Gradients

Gradients can be specified as list bullets. One problem with list bullet gradients is that there is currently no way in WebKit to specify the size of the marker box. Therefore the size of the image cannot be specified. WebKit has therefore chosen a default size based off the current font size of the list item.

List Item Gradients Example

Generated Content Gradients

Gradients can be used inside the content property. The image will fill the available width and height of its containing block. Therefore when using gradients inside ::before and ::after content with a specified size, it is important to set the display type to block or inline-block.

Gradients can also be used to do image replacement, so can be used with the img element in HTML or to replace the contents of other elements like spans and divs.

Generated Content Gradients Example

Final Notes

WebKit now supports a generic architecture for generated images, making it easy to add new generator effects to CSS in the future (lenticular halos, checkerboards, starbursts, etc.). The rules for sizing of these generated images will match whatever is decided for SVG content with no intrinsic size (the two are sharing the same rules right now).

We encourage you to try gradients out and file bugs if you see any unexpected or weird behavior. They will degrade safely in other browsers as long as you use multiple declarations (e.g., specify the image in one declaration and the gradient in a following declaration).

Author: "Dave Hyatt" Tags: "Uncategorized"
Comments Send by mail Print  Save  Delicious 
Date: Friday, 28 Mar 2008 07:44

In our earlier Acid3 post, I mentioned that the final test we passed, test 79, was super tough. This test covered many details of SVG text layout and font support. To pass it, we had to fix many bugs. Unless you are a hardocore standards geek you may not find all these details exciting, but since we talked a bit about our other recent fixes, I thought I’d tell the story. This subtest was originally contributed by Cameron McCormack.

Bug 1: DOM Support for the altGlyph element

I started on test 79 as a weekend hacking lark. While I have hacked a little on the SVG code, it wasn’t my top area of expertise, and I hadn’t looked at the text layout code at all, so I figured it would be an interesting learning experience. Little did I know that we’d end up racing to fix it.

The first failure we saw on test 79 was that getNumberOfCharacters on an SVG <text> element gave an answer that was off by one. The test hinted that this could be due to improper handling of UTF-16 (something covered in the SVG 1.1 Errata). However, on further study, I realized that our UTF-16 handling was right, but the <text> element contained an <altGlyph> element which we did not recognize, and therefore, according to SVG rules, did not render. For those who are new to text layout, a “glyph” refers to a particular symbol that will be drawn on the screen - most often every character has its own glyph, but it can get more complicated than that.

So, as a first step, in r31240 I made <altGlyph> fully recognized by the engine and allowed it to render initially as a <tspan> element. That’s sort of SVG’s equivalent of an HTML <span>, it just renders its text contents.

After landing the fix, I saw that the code testing character positions got a bad position for character 2.

Interlude: Modified Test Case

At this point, I realized that we’d probably get a lot of bad positions, and it would help to see all the problems at one go, instead of one at a time. Acid3 only reports the first failure on any given test. So I saved off a local copy, hacked it to report every failure on test 79, and changed it to test the spaces between characters instead of the character positions. Any error in measuring one character would propagate to all subsequent characters, so it was more useful to look at the differences in positions (”advances” in typography lingo). This immediately made it obvious that by far the most common failure was failure to support multi-character glyphs in SVG Fonts correctly.

Bug 2: Multi-character Glyphs

SVG has a feature to allow specification of glyphs that match more than one character. You can use this to do things like create ligatures. For example, it is common for proportional fonts to include a special glyph for the combination “fi”, since those letters can look nicer if drawn together in a special way.

We had the basics of code to support this. However, the problem was that our code only measured one character at a time. There was no way for the font code to decide to pick a glyph for more than one character because it only saw one at a time, and there was no way for it to report back how many characters a glyph matched. So even though the drawing code sort of got this right, the metrics were based on one-character glyphs. In r31310 I fixed this.

Interlude: Studying the Test Case

After this fix, I studied the test case to classify the remaining failures. I realized there was probably more than one bug, and if I documented them other people could help, or just continue the bug for me if I did not have time.

I found four separate remaining bugs: incorrect priority of SVG glyph matching (it picked the longest match instead of the first), failure to consider the xml:lang attribute in glyph matching, failure to support explicit kerning pairs, and failure to render the actual alternate glyph selected by altGlyph.

Bugs 3 & 4: Glyph Selection

After studying the SVG spec for text, I realized that the data structure we were using for glyph selection was not right. SVG fonts require you to pick the first glyph that matches, in the order in which they are specified, with a number of different rules in addition to text (you have to consider language and the multiple forms of Arabic characters for instance). We just had a hashtable of glyphs, and looked for a candidate by checking possible character runs from longest to shortest. That matched in the wrong priority, and did not properly handle lang at all.

I decided to change the GlyphMap to an n-ary trie (or “prefix tree”), with a vector of possible glyphs at each node, and a hashtable for child nodes. I also stored a “priority” value based on the position of the glyph in the tree. To do lookup, I would walk the trie one character at a time based on available characters, collecting all the glyphs found at each level. Next, the glyphs are sorted by priority. Finally, this vector of candidate glyphs is scanned to find the first that matches the additional constraints such as Arabic form.

Opera Brings its “A” Game

Making a fancy new data structure was a fair bit more complicated than my last two fixes, so I was hacking on this for a couple of days. On Wednesday morning, I heard that Opera was going to announce an Acid3 score of 98/100. The WebKit developers who had been noodling on Acid3 realized that we had fixes in progress for most of the remaining issues, and could likely pass the test by the end of the day, and get it out there.

At this point, I would like to commend the Opera developers for their achievement. At the time they posted the 100/100 screenshot, we had no idea there was a bug in test 79, and hoped at best to be the first to release a 100/100 public build, and both our teams could get some credit and positive exposure. It was not until we were fixing the very last bug in our code that we spotted the bug in the test, as you’ll see below.

Anyway, once we realized it was game on and Opera was much further ahead than we expected, we decided to complete our fixes. Eric fixed handling of charset encoding errors in XML, Antti got two SMIL test fixes in, and I cleaned this patch up, made a regression test, and landed it in r31324 and r31325. (We have a policy that every fix has to come with an automated regression test, no matter how much we’d like to rush - this is so we can move faster in the long run, by having a comprehensive regression test suite that will catch mistakes. Even with all that I had a bit of a commit oops but the team caught it right away, thus the two revisions.)

Bug 5: altGlyph Rendering

At this point, I had a problem. Niko, who had originally written the SVG font and text code, was busy with school, and I’d just learned all about the SVG text system by fixing these bugs, so I was the top expert and sort of on the hook. But there were two bugs left on these test, and neither was trivial to fix. I decided to split the remaining work with rendering master Dave Hyatt. I asked him to take on the altGlyph fix while I took care of kerning.

It turned out there were actually two different problems here. The altGlyph lookup was by ID, but somehow the glyph element wasn’t getting into the id map. With help from Darin and others on the team, Hyatt managed to figure out that we were handling the “id” attribute improperly for the SVG <glyph> element.

The second problem was actually choosing the alternate glyph and using it for metrics and rendering. This turned out to be simpler than it might seem, as it could be handled almost entirely in the SVG font machinery.

You can see the gory details of Hyatt’s fix in r31338. I helped him out with the test case for this, and for a while he thought his code was broken because I sent him a test that showed red boxes when it passes. Kids, never do this in your browser tests. Green for pass, red for fail.

Bug 6: Kerning

The final bug was support for kerning. It was pretty easy to add support to the SVG DOM for the <hkern> element, and to build up a vector of kerning pairs. What was tricky was storing enough info to decide when a kerning pair applied, and the match algorithm to help determine applicability. Kerning pairs can be specified in two ways in the SVG spec, by Unicode value or glyph name.

Darin was looking over my shoulder as I was reading the spec, because I hoped for his help on part of this, the matching algorithm. It was at this point we realized the test had a bug. It had an <hkern> element with a u1 attribute of “EE”, and expected that kerning to apply. But that’s neither a comma-separated sequence of characters nor a Unicode range, which is the syntax the SVG 1.1 spec for <hkern> elements requires. This meant that you couldn’t possibly pass this test without violating the SVG spec. I let Acid3 editor Ian Hickson know right away, and confirmed the error with Cameron, the original author of test 79. While they mulled over how to fix the test (Ian has been very responsive to fixing the few errors that crept into this very complex test), Darin and I continued to work on the final bug.

At last, we managed to pass around the glyph info and apply the matching correctly. We decided to handle the full complexity of the SVG spec for this, even though we could have cut corners just to pass the test, since it didn’t test every possible form of kerning pair. In the meantime, Ian had fixed the bug in the test and blogged about it. At last I saw the 100/100 on my screen for the first time. Everyone egged me on to commit but I insisted on getting the patch reviewed and creating a regression test, cause on WebKit that is how we roll. Finally with r31342 we had a score of 100/100, available to the public. And the rest is history.

By Way of Contrast

As you can see, this test was pretty rigorous, and we did a lot of hard work to make it pass. We fixed a lot of bugs, ranging from basic to obscure and easy to advanced. We didn’t have code just lying around that got us most of the way there.

Not all of the tests on Acid3 were equally stringent. Tests 75 and 76 are SVG Animation tests, contributed by Erik Dahlström. We had the beginnings of an implementation of this feature, but it was fairly incomplete and we had it disabled with ifdefs, and had chosen not to ship it in past releases. We believe in incremental development of new features, so we were prepared to turn it on and fix the bugs needed to pass the tests. We thought this would take a lot of extra work. To our surprise, it turned out that the first few of the changes we made on top of the old code were enough to pass the two SVG animation tests.

Antti checked these fixes in, but we don’t think our pre-existing incomplete implementation is truly satisfactory, and it probably wouldn’t be a good idea to ship it as-is in a major public release. We’re not yet satisfied with this code, but it’s a good step forward for our open development trunk.


In the end, the main thing that surprised me about Acid3 was how fun it was. Back when Acid2 was all the rage, Hyatt did pretty much all the fixes himself, so the rest of us didn’t have a chance to get into the spirit as much. But Acid3, and the slightly silly competitive atmosphere around it makes Web standards fun.

Web standards can often seem boring compared to super fast performace, whizzy new features, and even the basic Web compatibility work of making sites work properly. Interoperability is critical to the Web as an open platform, but it can be difficult to explain to regular users why it’s so important. The Acid tests make web standards fun, for browser developers, for Web designers, and for regular users. Whatever the intrinsic value of the tests may be, I think we should all thank Ian Hickson and all the test contributors.

I’d also like to thank Opera for giving us some serious competition and making this a real horse race. We have huge respect for their developers and all the work they do on Web standards.

Author: "Maciej Stachowiak" Tags: "Uncategorized"
Comments Send by mail Print  Save  Delicious 
Date: Thursday, 27 Mar 2008 02:55

UPDATE We now believe we have a full rendering pass (but not necessarily an animation smoothness pass yet). See the bottom of the post for details.

UPDATE The Windows nightly is now available for download. See below for details.

With r31342 WebKit has become the first publicly available rendering engine to achieve 100/100 on Acid3. The final test, test 79, was a brutal torture test of SVG text rendering. Details of the bugs we fixed will follow. Indeed, we found a critical bug in the test itself that would have forced a violation of the SVG 1.1 standard to pass, so until a few hours ago it was not possible to get a valid 100/100. Acid3 test editor Ian Hickson has the details.

Note: this does not indicate a full pass of Acid3. We have a slight glitch in the text rendering that is likely to be fixed soon (patch in progress). Also, the animation is required to be smooth. On typical machines, if you look really closely, you can see a small glitch in the animation on test 26 because 26 is designed to be a performance test. However, we think we are faster than all other browsers on test 26. What constitutes a smooth animation is somewhat subjective.

This is not just a screenshot, you can pull live from SVN and build to see it yourself, and a fresh nightly build is coming soon.


Thanks to our own Dan Bernstein, as of r31356 we believe we have a pixel-perfect match for the reference rendering.

Get the fresh hot bits of the latest Mac and Windows nightly builds which include the full reference rendering pass.

Extra special bonus update: Alp Toker reports that the Gtk port now gets 100/100, although it does not yet match the reference rendering.

Author: "Maciej Stachowiak" Tags: "Uncategorized"
Comments Send by mail Print  Save  Delicious 
Date: Thursday, 27 Mar 2008 01:07

In r31334 we enabled the SVG Animation support that has already been in the engine for a while but has not been enabled by default so far. We also implemented support for the beginElement() and endElement() methods. As a result we now pass the Acid3 test 76.

SVG Animation is a specification that has not been widely implemented so far. Reaching the point where various implementations are truly interoperable will take some more effort.

Get the nightly build and try it out yourself! One test to go.

Author: "Antti Koivisto" Tags: "Uncategorized"
Comments Send by mail Print  Save  Delicious 
Date: Wednesday, 26 Mar 2008 18:16

We fixed our XML processing in r31316 to stop auto-recovering from invalid byte sequences and instead treat invalid bytes as fatal errors, as required by XML 1.0. To quote the spec:

It is a fatal error if an XML entity is determined (via default, encoding declaration, or higher-level protocol) to be in a certain encoding but contains byte sequences that are not legal in that encoding

Internet Explorer also has this strictness requirement (for XML loaded via XMLHttpRequest), thus we believe this added strictness should not cause any real-world compatibility problems. (IE’s behavior can be confirmed by Hixie’s test.)

Once again, enjoy the pretty picture:
WebKit hits 98/100 on Acid3

or you can grab the latest nightly and try Acid3 yourself!

Author: "Eric Seidel" Tags: "Uncategorized"
Comments Send by mail Print  Save  Delicious 
Date: Wednesday, 26 Mar 2008 18:15

We added the ElementTimeControl interface that is part of the SVG Animation specification. This completes Acid3 test 75 and got us up to 97/100. Three to go!

Author: "Antti Koivisto" Tags: "Uncategorized"
Comments Send by mail Print  Save  Delicious 
Next page
» You can also retrieve older items : Read
» © All content and copyrights belong to their respective authors.«
» © FeedShow - Online RSS Feeds Reader