Last week I’ve done the DOM Core tests in new browsers: IE8 final (in both IE8 and IE7 mode), Firefox 3.5b4, Safari 4.0, Chrome 1 and 2, and Opera 10a. I found no surprises.
After that I decided to continue with mobile browsers, of which I have 15 lying around on my desk. Unfortunately I could not test IE Mobile (old) because it supports only inline event handlers, Skyfire because it does not allow you to remove alerts, and the Opera runtime in the Vodafone widget manager for terrifyingly complicated reasons I still have to describe properly.
Still I managed to test the other twelve and found a few surprises.
On the Anonymity of Home/Work Location Pairs. Most people can be uniquely identified by the rough location of their home combined with the rough location of their work. US Census data shows that 5% of people can be uniquely identified by this combination even at just census tract level (1,500 people).
JS-Placemaker—geolocate texts in JavaScript. Chris Heilmann exposed Placemaker to JavaScript (JSONP) using a YQL execute table. Try his examples—I’m impressed that “My name is Jack London, I live in Ontario” returns just Ontario, demonstrating that Placemaker’s NLP is pretty well tuned.
Flickr Shapefiles Public Dataset 1.0. Another awesome Geo dataset from the Yahoo! stable—this time it’s Flickr releasing shapefiles (geometrical shapes) for hundreds of thousands of places around the world, under the CC0 license which makes them essentially public domain. The shapes themselves have been crowdsourced from geocoded photos uploaded to Flickr, where users can “correct” the textual location assigned to each photo. Combine this with the GeoPlanet WOE data and you get a huge, free dataset describing the human geography of the world.
Previously I analyzed ECMAScript 5's Object and Property system. This is a huge new aspect of the language and deserved its special consideration.
There are a number of other new features and APIs that need attention, as well. The largest of which are Strict Mode and native JSON support.
Strict Mode is a new feature in ECMAScript 5 that allows you to place a program, or a function, in a "strict" operating context. This strict context prevents certain actions from being taken and throws more exceptions (generally providing the user with more information and a tapered-down coding experience).
Since ECMAScript 5 is backwards-compatible with ECMAScript 3, all of the "features" that were in ECMAScript 3 that were "deprecated" are just disabled (or throw errors) in strict mode, instead.
Strict mode helps out in a couple ways:
Most of the information about strict mode can be found in the ES5 specification [PDF] on page #223.
It should be noted that ECMAScript 5's strict mode is different from the strict mode available in Firefox (which can be turned on by going to about:config and enabled javascript.options.strict). ES5's strict mode complains about a completely different set of potential errors (whereas Firefox's existing strict mode tries to enforce some good practices, only).
How do you enable strict mode?
Simple. Toss this at the top of a program to enable it for the whole script:
Or place it within a function to turn on strict mode only within that context.
Note the syntax that's used to enable strict mode (I love this!). It's simply a string in a single statement that happens to contain the contents "use strict". No new syntax is introduced in order to enable strict mode. This is huge. This means that you can turn strict mode on in your scripts - today - and it'll have, at worst, no side effect in old browsers.
As you may note from the examples here and in the previous post there are virtually no new syntax additions or changes to the language in ECMAScript 5. This means that you can write your ES5 scripts in a manner that will be able to gracefully degrade for older useragents - something that wasn't possible with ECMAScript 4. The way in which strict mode is enabled is a great illustration of that point in practice.
A neat aspect of being able to define strict mode within a function is that you can now define complete JavaScript libraries in a strict manner without affecting outside code.
(function(){
"use strict";
// Define your library strictly...
})();
// Non-strict code...
A number of libraries already use the above technique (wrapping the whole library with an anonymous self-executing function) and they will be able to take advantage of strict mode very easily.
So what changes when you put a script into strict mode? A number of things.
Variables and Properties
An attempt to assign foo = "bar";
where 'foo' hasn't been defined will fail. Previously it would assign the value to the foo property of the global object (e.g. window.foo
), now it just throws an exception. This is definitely going to catch some annoying bugs.
Any attempts to write to a property whose writable attribute is set to false, delete a property whose configurable attribute is set to false, or add a property to an object whose extensible attribute is set to false will result in an error (these attributes were discussed previously). Traditionally no error will be thrown when any of these actions are attempted, it will just fail silently.
Deleting a variable, a function, or an argument will result in an error.
delete foo; // Error
delete test; // Error
function test2(arg) {
delete arg; // Error
}
Defining a property more than once in an object literal will cause an exception to be thrown
eval
Virtually any attempt to use the name 'eval' is prohibited - as is the ability to assign the eval function to a variable or a property of an object.
Additionally, attempts to introduce new variables through an eval will be blocked.
Functions
Attempting to overwrite the arguments object will result in an error:
arguments = [...]; // not allowed
Defining identically-named arguments will result in an error function( foo, foo ) {}
.
Access to arguments.caller
and arguments.callee
now throw an exception. Thus any anonymous functions that you want to reference will need to be named, like so:
The arguments
and caller
properties of other functions no longer exist - and the ability to define them is prohibited.
Finally, a long-standing (and very annoying) bug has been resolved: Cases where null or undefined is coerced into becoming the global object. Strict mode now prevents this from happening and throws an exception instead.
with(){}
with(){}
statements are dead when strict mode is enabled - in fact it even appears as a syntax error. While the feature was certainly mis-understood and possibly mis-used I'm not convinced that it's enough to be stricken from the record.
The changes made in ECMAScript 5 strict mode are certainly varied (ranging from imposing stylistic preferences, like removing with statements, to fixing legitimately bad language bugs, like the ability to redefine properties in object literals). It'll be interesting to see how people begin to adopt these points and how it'll change JavaScript development.
All that being said, I'm fairly certain that jQuery is ES5-Strict compatible right now. Once an implementation of the language is made available (so that that premise may be tested) I'll happily switch jQuery over to working exclusively in strict mode.
The second major feature of the language is the addition of native JSON support to the language.
I've been championing this move for a long time and I'm glad to see it finally arrive in a specification.
In the meantime PLEASE start migrating your JSON-using applications over to Crockford's json2.js. It is fully compatible with the ECMAScript 5 specification and gracefully degrades if a native (faster!) implementation exists.
In fact, I just landed a change in jQuery yesterday that utilizes the
JSON.parse
method if it exists, now that it has been completely specified.
There are two primary methods for handling JSON: JSON.parse
(which converts a JSON string into a JavaScript object) and JSON.stringify
(which convert a JavaScript object into a serialized string).
JSON.parse( text )
Converts a serialized JSON string into a JavaScript object.
JSON.parse( text, translate )
Use a translation function to convert values or remove them entirely.
var obj = JSON.parse('{"name":"John","last":"Resig"}', translate);
// Prints 'John Resig'
print( obj.name );
// Undefined
print( obj.last );
JSON.stringify( obj )
Convert an object into a serialized JSON string.
JSON.stringify( obj, ["white", "list"])
Serialize only a specific white list of properties.
JSON.stringify( obj, translate )
Serializes the object using a translation function.
var str = JSON.stringify({"name":"John","last":"Resig"}, translate);
// Prints {"name":"John Resig"}
print( str );
JSON.stringify( obj, null, 2 )
Adds the specified number of spaces to the output, printing it evenly.
JSON.stringify( obj, null, "\t" )
Uses the specified string to do the spacing.
Additionally, a few new generic methods have been added to some of the base objects but, frankly, they aren't that interesting. The results from String, Boolean, and Number are just equivalent to calling .valueOf()
and the result from Date is equivalent to calling .toISOString()
A welcomed addition to the language is a built-in .bind()
method for enforcing the context of a function (virtually identical to Prototype's .bind implementation).
Function.prototype.bind(thisArg, arg1, arg2....)
Enforces the 'this' of the specified function to a specific object - and passing in any specified arguments.
setTimeout( obj.method.bind(obj, "John"), 100 );
Considering how long this function (and its equivalents) have been around it's a welcome addition to the language.
Dates are now capable of both parsing and outputting ISO-formatted dates. Thank goodness, about time. rimshot
The Date constructor now attempts to parse the date as if it was ISO-formatted, first, then moves on to the other inputs that it accepts.
Additionally, date objects now have a new .toISOString()
method that outputs the date in an ISO format.
// Prints 2009-05-21T16:06:05.000Z
print( date.toISOString() );
A native, built-in, .trim()
is now included for strings. Works identically to all the other trim methods out there - with the potential to possibly work faster.
Steven Levithan has discussed the trim method in great depth.
The JavaScript Array Extras that've been around for, what seems like, forever are finally formally specified. This includes the following methods: indexOf, lastIndexOf, every, some, forEach, map, filter, reduce, and reduceRight.
Additionally a new Array.isArray
method is included, providing functionality very similar to the following:
Altogether I think ECMAScript 5 makes for an interesting package. It isn't the massive leap that ECMAScript 4 promised but it is a series of respectable improvements that reduces the number of obvious bugs while making the language safer and faster. I'm looking forward to when some implementations start to go public.
AWS Import/Export: Ship Us That Disk!. Andrew Tanenbaum said “Never underestimate the bandwidth of a station wagon full of tapes hurtling down the highway”, and now you can ship your storage device direct to Amazon and have them load the data in to an S3 bucket for you.
ECMAScript 5 is on its way. Rising from the ashes of ECMAScript 4, which got scaled way back and became ECMAScript 3.1, which was then re-named ECMAScript 5 (more details)- comes a new layer of functionality built on top of our lovable ECMAScript 3.
Update: I've posted more details on ECMAScript 5 Strict Mode, JSON, and More.
There are a few new APIs included in the specification but the most interesting functionality comes into play in the Object/Property code. This new code gives you the ability to dramatically affect how users will be able to interact with your objects, allowing you to provide getters and setters, prevent enumeration, manipulation, or deletion, and even prevent the addition of new properties. In short: You will be able to replicate and expand upon the existing JavaScript-based APIs (such as the DOM) using nothing but JavaScript itself.
Perhaps best of all, though: These features are due to arrive in all major browsers. All the major browser vendors worked on this specification and have agreed to implement it in their respective engines. The exact timeframe isn't clear yet, but it's going to be sooner, rather than later.
There doesn't appear to exist a full implementation of ES5 at this point, but there are a few in the works. In the meantime you can read the ECMAScript 5 specification (PDF - I discuss pages 107-109 in this post) or watch the recent talk by some of the ECMAScript guys at Google.
Note: I've provided a couple simple, example, implementations for these methods to illustrate how they might operate. Almost all of them require other, new, methods to work correctly - and they are not implemented to match the specification 100% (for example there is no error checking).
A new feature of ECMAScript 5 is that the extensibility of objects can now be toggled. Turning off extensibility can prevent new properties from getting added to an object.
ES5 provides two methods for manipulating and verifying the extensibility of objects.
Object.preventExtensions( obj )
Object.isExtensible( obj )
preventExtensions
locks down an object and prevents and future property additions from occurring. isExtensible
is a way to determine the current extensibility of an object.
Example Usage:
obj.name = "John";
print( obj.name );
// John
print( Object.isExtensible( obj ) );
// true
Object.preventExtensions( obj );
obj.url = "http://ejohn.org/"; // Exception in strict mode
print( Object.isExtensible( obj ) );
// false
Properties have been completely overhauled. No longer are they the simple value associated with an object - you now have complete control over how they can behave. With this power, though, comes increased complexity.
Object properties are broken down into two portions.
For the actual "meat" of a property there are two possibilities: A Value (a "Data" property - this is the traditional value that we know and love from ECMAScript 3) or a Getter and Setter (an "Accessor" property - we know this from some modern browsers, like Gecko and WebKit).
Additionally, properties can be...
for (var prop in obj){}
(or similar).Altogether these various attributes make up a property descriptor. For example, a simple descriptor might look something like the following:
The three attributes (writable, enumerable, and configurable) are all optional and all default to true. Thus, the only property that you'll need to provide will be, either, value or get and set.
You can use the new Object.getOwnPropertyDescriptor
method to get at this information for an existing property on an object.
Object.getOwnPropertyDescriptor( obj, prop )
This method allows you to access the descriptor of a property. This method is the only way to get at this information (it is, otherwise, not available to the user - these don't exist as visible properties on the property, they're stored internally in the ECMAScript engine).
Example Usage:
print(JSON.stringify(
Object.getOwnPropertyDescriptor( obj, "foo" )
));
// {"value": "test", "writable": true,
// "enumerable": true, "configurable": true}
Object.defineProperty( obj, prop, desc )
This method allows you to define a new property on an object (or change the descriptor of an existing property). This method accepts a property descriptor and uses it to initialize (or update) a property.
Example Usage:
Object.defineProperty( obj, "value", {
value: true,
writable: false,
enumerable: true,
configurable: true
});
(function(){
var name = "John";
Object.defineProperty( obj, "name", {
get: function(){ return name; },
set: function(value){ name = value; }
});
})();
print( obj.value )
// true
print( obj.name );
// John
obj.name = "Ted";
print( obj.name );
// Ted
for ( var prop in obj ) {
print( prop );
}
// value
// name
obj.value = false; // Exception if in strict mode
Object.defineProperty( obj, "value", {
writable: true,
configurable: false
});
obj.value = false;
print( obj.value );
// false
delete obj.value; // Exception
Object.defineProperty
is a core method of the new version of ECMAScript. Virtually all the other major features rely upon this method existing.
Object.defineProperties( obj, props )
A means of defining a number of properties simultaneously (instead of individually).
Example Implementation:
Example Usage:
Object.defineProperties(obj, {
"value": {
value: true,
writable: false
},
"name": {
value: "John",
writable: false
}
});
Property descriptors (and their associated methods) is probably the most important new feature of ECMAScript 5. It gives developers the ability to have fine-grained control of their objects, prevent undesired tinkering, and maintaining a unified web-compatible API.
Building on top of these new additions some interesting new features have been introduced into the language.
The following two methods are very useful for collecting arrays of all the properties on an object.
Object.keys( obj )
Returns an array of strings representing all the enumerable property names of the object. This is identical to the method included in Prototype.js.
Example Implementation:
Example Usage:
print( Object.keys(obj).join(", ") );
// name, url
Object.getOwnPropertyNames( obj )
Nearly identical to Object.keys
but returns all property names of the object (not just the enumerable ones).
An implementation isn't possible with regular ECMAScript since non-enumerable properties can't be enumerated. The output and usage is otherwise identical to Object.keys
.
Object.create( proto, props )
Creates a new object whose prototype is equal to the value of proto and whose properties are set via Object.defineProperties( props )
.
A simple implementation would look like this (requires the new Object.defineProperties
method).
Example Implementation: (by Ben Newman)
Other implementation:
if ( typeof props !== "undefined" ) {
Object.defineProperties( obj, props );
}
return obj;
};
Note: The above code makes use of the Mozilla-specific
__proto__
property. This property gives you access to the internal prototype of an object - and allows you to set its value, as well. The ES5 methodObject.getPrototypeOf
allows you to access this value but not set its value - thus the above method cannot be implement in a generic, spec-compatible, manner.I discussed
Object.getPrototypeOf
previously so I won't bother discussing it again here.
Example Usage:
var john = Object.create(new User(), {
name: { value: "John", writable: false },
url: { value: "http://google.com/" }
});
print( john.name );
// John
john.name = "Ted"; // Exception if in strict mode
Object.seal( obj )
Object.isSealed( obj )
Sealing an object prevents other code from deleting, or changing the descriptors of, any of the object's properties - and from adding new properties.
Example Implementation:
You would seal an object if you want its existing properties to stay intact, without allowing for new additions, but while still allowing the user to write to or edit the properties.
Object.freeze( obj )
Object.isFrozen( obj )
Freezing an object is nearly identical to sealing it but with the addition of making the properties un-editable.
Example Implementation:
Freezing an object is the ultimate form of lock-down. Once an object has been frozen it cannot be unfrozen - nor can it be tampered in any manner. This is the best way to make sure that your objects will stay exactly as you left them, indefinitely.
All together these changes are very exciting, they provide you with an unprecedented level of control over the objects that you produce. The best aspect, though, is that you will be able to use these features to build larger and more complex features in pure ECMAScript (such as building new DOM modules, or moving more browser APIs into pure-JavaScript). And since all the browsers are on board this is absolutely something that we can look forward to.
Yahoo! Placemaker. Really exciting new API from Yahoo!—Placemaker accepts a block of text (or a URL to HTML or RSS) and extracts and returns geographical locations mentioned in the text. I just ran my djng blog entry through it and it pulled out “Prague” as the only location mentioned. This should be really useful for adding geodata to existing textual content.
document.onload=function(){ // code that shows the "please wait" box, an obvious mistake } . . <body onload="">
In his recent Feature testing CSS properties entry, Juriy Zaytsev (Kangax) discusses the possibility of detecting CSS support by means of JavaScript. Although he rightly points out that this method has its drawbacks, as far as I’m concerned he doesn’t go far enough.
This sort of testing should not be used at all. Ever. The methodology is plain wrong. Browser compatibility tests are to be done by hand. Any automated system is useless, because it will give false information.
aws—simple access to Amazon EC2 and S3. The best command line client I’ve found for EC2 and S3. “aws put --progress my-bucket-name/large-file.tar.gz large-file.tar.gz” is particularly useful for uploading large files to S3. Written in Perl (with no dependencies), shelling out to curl to do the heavy lifting.
resty. 58 lines of bash provides a better command-line interface to RESTful APIs, using curl under the hood. This should save me from running “man curl” several times a week.
python-daemon (via). A library for correctly creating Unix daemon processes in Python, implementing the proposed PEP 3143 API.
когда уже в багзилле будет поддержка openid?! Надоело регистрироваться на каждом сайте разработчика. Давайте проголосуем за этот запрос, что ли: «Support OpenID as a an account source and login verification method»
This morning, Google released an upgrade to their OpenID Provider to support the draft OpenID User Interface Extension along with JanRain who added support for it to their Relying Party service RPX. This means that Google users signing into sites like UserVoice (choose “Google” to see it in action) now have a much better user experience; one much closer to that of Facebook Connect. Google also allows users to choose to share their profile information with Relying Parties via OpenID Attribute Exchange and the Google Data APIs via OAuth.
The OpenID User Interface Extension is one of the main pieces of work that has come from the OpenID Design Summit hosted by Facebook earlier this year. The extension replaces the traditional OpenID sign in flow of being redirected from the Relying Party to the OpenID Provider with a popup window which shows the URL bar on top of the Relying Party itself.
The Google Code Blog writes about their implementation in more detail:
The new popup style UI, which implements the OpenID User Interface Extension Specification, is designed to streamline the federated login experience for users. Specifically, it’s designed to ensure that the context of the Relying Party website is always available and visible, even in the extreme case where a confused user closes the Google approval window. JanRain, a provider of OpenID solutions, is an early adopter of the new API, and already offers it as part of their RPX product. As demonstrated by UserVoice using JanRain’s RPX, the initial step on the sign-in page of the Relying Party website is identical to that of the “full page” version, and does not require any changes in the Relying Party UI.
Once the user selects to sign in using his or her Google Account, the Google approval page is displayed. However, it does not replace the Relying Party’s page in the main browser window. Instead it is displayed as a popup window on top of it. We have updated our Open Source project to include a complete Relying Party example, providing code for both the back-end (in Java) and front-end (javascript) components.
Once the user approves the request, the popup page closes, and the user is signed in to the Relying Party website.
User experience continues to be one of our key priorities for the community and foundation this year, and progress like seeing Google and JanRain ship the first implementation of the OpenID popup flow is demonstrating that we’ve been able to seize the momentum coming into this year and make real progress in a short period of time.
We’re looking forward to discussing this and other initiatives at the Internet Identity Workshop this coming Monday.
An addition to my post Don’t forget keyboard navigation is that you should never use the outline
CSS property to remove the indicator that most browsers display when a focusable element receives keyboard focus.
I’ve seen quite a few tips on how to remove the focus indicator by using outline:none
or outline:0
. Please do not do this, unless you replace the outline with something else that makes it easy to see which element has keyboard focus. Removing the visual indicator of keyboard focus will give people who rely on keyboard navigation a really hard time navigating and using your site.
Another, even worse, way of removing the focus indicator is to use a JavaScript onfocus
event to remove focus as soon as a link or other element receives focus, making it impossible to use the page without a mouse. Never, ever do this.
This post is a Quick Tip. Background info is available in Quick Tips for web developers and web designers.
Posted in Accessibility, Quick Tips, Usability.
Interview with Ian Hickson, editor of the HTML 5 specification. By Bruce Lawson of the Web Standards Project. Worth reading.
Статья публикуется специально для Хабрахабра.
Из-за какого-то непонятного ограничение на объем статьи — приводится в сокращении.
Полная версия статьи — у меня на сайте.
else if
;obj.getProperty()
и obj.setProperty(value)
;В двух словах:
Переменные должны объявляться в начале логического блока, в котором они используются, а НЕ в начале функции или программы.
читатели блога наверняка давно заметили, что одна из самых популярных тем здесь — юзерскрипты. (Кстати, называть их гризманки-скриптами неграмотно.) К сожалению, интерфейсная поддержка этой мощной функциональности в опере хромает: всего-то можно указать папку с ними и переопределить её для отдельных сайтов. Конечно, это не мешает решать те же самые задачи, но так они занимают немного больше времени, чем в том же гризманки.
поскольку у нас пока ещё нет возможности писать под оперу такие же аддоны, как под фф, с проблемой юзерскриптов поделать ничего нельзя. Хотя постойте! Можно делать под оперу виджеты, а для них ещё год назад заявляли поддержку File I/O. Значит, можно сделать виджет, который даст удобный интерфейс управления скриптами! И не только ими, можно много чего навертеть, почти как для фф…
да, действительно можно. И оно даже будет работать. Но как тег video
и 3d canvas. То есть, только в экспериментальном билде : (
[whatwg] Annotating structured data that HTML has no semantics for. Hixie’s proposal for microdata, a simplified RDFa to be included in the HTML5 spec which allows self-contained communities to invent their own microformat-style spec and use it to add structured semantics to their markup. Whether or not you like the proposal itself the explanation is a fascinating read.
особенно интересно, что говорится не столько о тонких технических подробностях, сколько о глобальных подходах, об общем ви́дении
когда вышел Ubunty 9.04 Jaunty Jackalope, я немедленно скачал torrent официального DVD и положил в папочку. А памятуя прошлые обновления, когда новые версии пакетов тянулись с официальных серверов в час по чайной ложке, решил в этот раз использовать пакеты с диска. Но мне вовсе не хотелось вначале записывать образ на болванку, а потом слушать урчание привода, который всяко медленнее винчестера. Казалось бы, что может быть проще — примонтировать iso в файловую систему и указать инсталлятору на неё. Но не тут-то было!
во время предыдущего обновления я безуспешно пытался проделать эту операцию. Однако в этот раз я решил пойти до конца. Вначале создал каталог /media/ubuntu
. Работать с iso-образами я предпочитаю через гуй простенькой программки gmount-iso, но того же можно добиться и через /etc/fstab
:
/media/l-large/ubuntu-9.04-dvd-i386.iso /media/ubuntu udf,iso9660 noauto,loop
вручную вставить диск в инсталлятор невозможно, о чём предупреждает man apt-cdrom
, поэтому положимся на него:
sudo apt-cdrom -d /media/ubuntu add
он зачем-то отмонтирует диск и попросит «вставить» его снова, но это не создаёт особых трудностей : )
после этих операций в /etc/apt/sources.list
появилась запись:
deb cdrom:[Ubuntu 9.04 _Jaunty Jackalope_ - Release i386 (20090421.3)]/ jaunty main restricted
тут я обрадовался и запустил инсталлятор. Тот пошуршал байтами и попросил меня вставить диск в привод /cdrom/
. «Ага!», — сказали мужики и задумались. Именно в этом месте я забил в прошлый раз. Но сейчас на глаза мне попалась строчка из мана apt-cdrom: «Configuration Item: Acquire::cdrom::mount.» Что-то похоже я уже видел в настройках apt. Например, в /etc/apt/apt.conf.d/10periodic
:
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::AutocleanInterval "0";
APT::Periodic::Unattended-Upgrade "1";
Дальше было просто. Я создал файл /etc/apt/apt.conf.d/35cdrom
с одной строчкой:
Acquire::cdrom::mount "/media/ubuntu/";
после этого пакеты ставились и продолжают ставиться большей частью с диска: «Need to get 929kB/5920kB of archives.» Впрочем, локально того же эффекта можно было добиться, указав эту опцию в командной строке к dist-upgrade:
sudo apt-get dist-upgrade -o Acquire::cdrom::mount="/media/ubuntu/"
итак, кратко то же самое (от рута):
# mkdir /media/ubuntu
# echo "/media/l-large/ubuntu-9.04-dvd-i386.iso /media/ubuntu udf,iso9660 noauto,loop" >> /etc/fstab
# sudo apt-cdrom -d /media/ubuntu add
# echo 'Acquire::cdrom::mount "/media/ubuntu/";\n' >> /etc/apt/apt.conf.d/35cdrom
ps: собравшись опубликовать это на хабре, обнаружил там быстрый рецепт для обновления с сиди:
/cdmountpoint/cdromupgrade
за последнюю неделю мне пришли две новости, из которых можно сделать интересный вывод. Первая — про 270 миллионов пользователей Firefox (via). Вторая — про 35-40 миллионов пользователей Opera. Методики подсчёта у них приблизительно одинаковые, и, конечно, мы обеим компаниям верим ; )
впрочем, почему бы не проверить? Что говорят глобальные сервисы статистики на эту тему? W3Schools считает только своих посетителей, которые в большинстве своём веб-разработчики, поэтому даже не буду смотреть его сторону. Ещё есть, например, Net Applications и StatCounter. Первый из них — в своём роде Alexa — известный, древний и однобокий (подсчитывает преимущественно американские сайты). А вот второй показывает лучшее соответствие заявкам компаний. Получается 30%/270млн у фф, 3%/27млн у оперы и 2%.20млн у хрома, который ещё в конце года рапортовал как раз 10 миллионов
в общем, можно не верить StatCounter'у и Опере, а можно не верить только Net Applications. Жаль только, что блоггеры обычно хватают только первые попавшиеся цифры, и чаще всего ими оказываются данные именно NA
все веб-разработчики знают про GET/POST, многие — ещё и про PUT/DELETE. Я также наслышан о том, что WebDav добавляет несколько специфичных для себя методов. Но тут внезапно! обнаруживаю в статье «REST worst practices» отсылку к новому глаголу PATCH, черновик спеки которого уже почти готов. Предполагается, что этот метод будет использоваться очень широко, потому что решает очень общую задачу: обновление только части объекта. Проблема в том, что PUT заменяет объект полностью, а иногда удобнее исправить только одну небольшую часть. Очень разумное предложение, буду ждать выхода стандарта