mozilla

Mozilla Nederland LogoDe Nederlandse
Mozilla gemeenschap

Mozilla Fundraising: Privacy-Forward Fundraising

Mozilla planet - vr, 12/12/2014 - 20:11
There are a lot of ways that fundraising at Mozilla is very different than the fundraising I’ve done at other non-profit organizations. One of the most striking differences is how our Privacy Principles guide our donor experience, our fundraising systems, … Continue reading
Categorieën: Mozilla-nl planet

Fabien Cazenave: "pip install" & "gem install" without sudo

Mozilla planet - vr, 12/12/2014 - 16:40

Following yesterday’s post about using “npm install -g” without root privileges, here are the Python and Ruby counterparts for your beloved OSX or Linux box.

By default, pip install and gem install try to install stuff in /usr/, which requires root privileges. Hence, most users will “naturally” do a sudo to perform the install — which is, in my opinion at least, a very bad idea (do you really want to give root privileges to packages that haven’t been reviewed?). Fortunately, there’s more than the default setting.

Python: pip install --user

With Python 2.6 and later you can avoid “sudoing” your pip install by using the --user argument (thanks @cmdevienne for the tip!). Let’s test this with html-linter:

$ pip install --user html-linter

By default on Linux and OSX (non-framework builds) this will install your package into ~/.local, which is just fine for me. All executables are in ~/.local/bin/, which is included in my $PATH, and all Python libraries are in ~/.local/lib/python2.7/. The world couldn’t be any better.

You can specify a custom destination by setting the PYTHONUSERBASE environment variable:

$ export PYTHONUSERBASE=/myappenv $ pip install --user html-linter

Of course, you’ll have to add that to your $PATH to make it work. You can add the following lines to your ~/.profile like that:

export PYTHONUSERBASE=/myappenv PATH="$PYTHONUSERBASE/bin:${PATH}"

The only downside (compared to npm) is that you’ll have to remember to use the --user argument when installing Python packages. If there’s a way to make it the default mode, please let me know.

EDIT: a good workaround is to define a custom pip function in your ~/.bash_aliases (or bashrc, zshrc, whatever), as suggested in comment #1.

Ruby: gem install --user-install

gem’s --user-install argument is quite similar. One good thing is that you can easily make it the default mode:

$ echo "gem: --user-install" >> ~/.gemrc

Now let’s try that with the most valuable gem I know:

$ gem install vimgolf Fetching: vimgolf-0.4.6.gem (100%) WARNING: You don't have /home/kaze/.gem/ruby/1.8/bin in your PATH, gem executables will not run.

As you can see, gem installs everything in ~/.gem by default; unfortunately, the file structure does not allow to put executables in the same ~/.local/bin/ directory. Never mind, we’ll add those ~/.gem/ruby/*/bin/ directories to the $PATH manually by adding these lines to the ~/.profile:

for dir in $HOME/.gem/ruby/*; do [ -d "$dir/bin" ] && PATH="${dir}/bin:${PATH}" done

Source your ~/.profile, you’re done.

Categorieën: Mozilla-nl planet

Joel Maher: Tracking Firefox performance as we uplift – the volume of alerts we get

Mozilla planet - vr, 12/12/2014 - 16:06

For the last year, I have been focused on ensuring we look at the alerts generated by Talos.  For the last 6 months I have also looked a bit more carefully at the uplifts we do every 6 weeks.  In fact we wouldn’t generate alerts when we uplifted to beta because we didn’t run enough tests to verify a sustained regression in a given time window.

Lets look at data, specifically the volume of alerts:

Trend of improvements/regressions from Firefox 31 to 36 as we uplift to Aurora

Trend of improvements/regressions from Firefox 31 to 36 as we uplift to Aurora

this is a stacked graph, you can interpret it as Firefox 32 had a lot of improvements and Firefox 33 had a lot of regressions.  I think what is more interesting is how many performance regressions are fixed or added when we go from Aurora to Beta.  There is minimal data available for Beta.  This next image will compare alert volume for the same release on Aurora then on Beta:

Side by side stacked bars for the regressions going into Aurora and then going onto Beta.

Side by side stacked bars for the regressions going into Aurora and then going onto Beta.

One way to interpret this above graph is to see that we fixed a lot of regressions on Aurora while Firefox 33 was on there, but for Firefox 34, we introduced a lot of regressions.

The above data is just my interpretation of this, Here are links to a more fine grained view on the data:

As always, if you have questions, concerns, praise, or other great ideas- feel free to chat via this blog or via irc (:jmaher).


Categorieën: Mozilla-nl planet

Firefox gaat Google's aanvulling op SSL ondersteunen - Security.nl

Nieuws verzameld via Google - vr, 12/12/2014 - 15:11

Firefox gaat Google's aanvulling op SSL ondersteunen
Security.nl
Om Firefoxgebruikers tegen frauduleuze SSL-certificaten te beschermen gaat Mozilla Certificaattransparantie (CT) aan Firefox toevoegen. CT is een door Google ontwikkelde technologie en is bedoeld om verschillende structurele fouten in het ...

Categorieën: Mozilla-nl planet

Mozilla Reps Community: Reps Weekly Call – December 11st 2014

Mozilla planet - vr, 12/12/2014 - 14:06

Last Thursday we had our regular weekly call about the Reps program, where we talk about what’s going on in the program and what Reps have been doing during the last week.

whosjoining

Summary
  • FOSDEM update.
  • Portland Work Week.
  • ReMo/Mozillians websites testing.
  • End of year receipts campaign.
  • Remo challenges.
  • Stumbling in a box events.
  • Reps Monthly newsletter.

Detailed notes

AirMozilla video

Don’t forget to comment about this call on Discourse and we hope to see you next week!

Categorieën: Mozilla-nl planet

Blair McBride: UX Deisgn Day, Dunedin 2014

Mozilla planet - vr, 12/12/2014 - 02:48

Things I’ve been saying for a long time: I need to blog more. I haven’t been very good at achieving that.

So, recently I was at UX Design Day – a one-day conference focused on UX and design. It’s the only conference of it’s kind in NZ, and it started here in Dunedin. Working remotely and not really part of the design community, I don’t often get a chance to sit down and talk UX/design in-person with people. This year the conference was back in Dunedin, so I jumped at the chance to attend.

UX Design Day intro slideI was impressed by the diverse turnout this year. Interaction design, visual design, content strategy, marketing, education, user research, and software development were all represented. I had tried to drum up support from the local developer community to attend, and that seemed to have worked well. Too often do I see developers ignoring UX/design issues – either being very dismissive, or claiming it’s another person’s job; so this felt like a good sign.

Alone those lines, one of the things that stuck with me was the talk around not having UX teams separate from everything else. The largest example talked about was UX and content strategy, but I think it applies equally to software development teams too. Having these two groups work closely together, not segregated, helps bring so much context to both teams.

The other important take-away for me was the importance of not accepting crap. That is, experiences or systems that are, intentionally or not, lacking in design forethought and therefore lead to an unnecessarily difficult experiences, or a design that by default leads to harm. The primary concrete example here was physical safety in various workplaces, where people were put at needless risk due to the lack of safety by default design. I think this is a very relevant point for those of us building software, given that we so often experience design in software that feels broken, but too often don’t do anything constructive to help fix it.

Obligatory wall of Post-It notes

On the whole, I enjoyed the conference. However, since the talks covered such a wide corpus, I feel it didn’t provide enough time for any one area. Diversity is an asset, but I would have liked time for more in-depth explorations of topics.

Categorieën: Mozilla-nl planet

Guillaume Destuynder: VPN and DNS

Mozilla planet - vr, 12/12/2014 - 01:00

Contents

The problem

Note

TLDR

With split-view DNS and VPN it makes your web browsing and what not slower due to slower DNS resolution. This is a “solution” mainly for Linux and OSX.

When connecting to a VPN, usually, it’s going to push it’s own DNS name servers. It does this because many, or dare I say most networks behind the VPN actually have hostnames that are “internal” and will only resolve on the internal name server. This situation is also called “split-view DNS”.

The internal name server also resolves public hostnames - but because of the VPN round-trip this is slower. In some cases, it can be much slower (for example if your company’s VPN is in the USA and you live in Europe... hint).

dnsmasq to the rescue

dnsmasq is a well-known DNS caching server, DHCP, TFTP, PXE (and recently even RA) server. You can configure it so that requests for certain domains are resolved with a specific name-server.

For example, you would want to forward all internal domains to the DNS name server that is provided by the VPN:

File: /etc/resolv.conf

nameserver 127.0.0.1

File: /etc/resolv2.conf

#Your local/ISP nameserver(s) nameserver 192.168.0.1 nameserver 8.8.8.8

File: /etc/dnsmasq.conf

server=/scl3.mozilla.com/10.0.0.1/ server=/phx1.mozilla.com/10.0.0.1/ resolv-file=/etc/resolv2.conf

Note

In this example, *.scl3.mozilla.com will resolve through the name server at 10.0.0.1

If you use openresolv (if you don’t know, you probably do...) you’ll have to instruct it to always use your local DNS cache (dnsmasq) as well so that it doesn’t override your settings.

File: /etc/resolvconf.conf

#Optional, if you use openresolv name_servers=127.0.0.1

And off you go! Don’t forget to restart dnsmasq ;)

systemctl restart dnsmasq # or.. /etc/init.d/dnsmasq restart
Categorieën: Mozilla-nl planet

Jeff Walden: Introducing the JavaScript Internationalization API

Mozilla planet - do, 11/12/2014 - 23:47

(also cross-posted on the Hacks blog — comment over there if you have anything to say)

Firefox 29 issued half a year ago, so this post is long overdue. Nevertheless I wanted to pause for a second to discuss the Internationalization API first shipped on desktop in that release (and passing all tests!). Norbert Lindenberg wrote most of the implementation, and I reviewed it and now maintain it. (Work by Makoto Kato should bring this to Android soon; b2g may take longer due to some b2g-specific hurdles. Stay tuned.)

What’s internationalization?

Internationalization (i18n for short — i, eighteen characters, n) is the process of writing applications in a way that allows them to be easily adapted for audiences from varied places, using varied languages. It’s easy to get this wrong by inadvertently assuming one’s users come from one place and speak one language, especially if you don’t even know you’ve made an assumption.

function formatDate(d) { // Everyone uses month/date/year...right? var month = d.getMonth() + 1; var date = d.getDate(); var year = d.getFullYear(); return month + "/" + date + "/" + year; } function formatMoney(amount) { // All money is dollars with two fractional digits...right? return "$" + amount.toFixed(2); } function sortNames(names) { function sortAlphabetically(a, b) { var left = a.toLowerCase(), right = b.toLowerCase(); if (left > right) return 1; if (left === right) return 0; return -1; } // Names always sort alphabetically...right? names.sort(sortAlphabetically); } JavaScript’s historical i18n support is poor

i18n-aware formatting in traditional JS uses the various toLocaleString() methods. The resulting strings contained whatever details the implementation chose to provide: no way to pick and choose (did you need a weekday in that formatted date? is the year irrelevant?). Even if the proper details were included, the format might be wrong e.g. decimal when percentage was desired. And you couldn’t choose a locale.

As for sorting, JS provided almost no useful locale-sensitive text-comparison (collation) functions. localeCompare() existed but with a very awkward interface unsuited for use with sort. And it too didn’t permit choosing a locale or specific sort order.

These limitations are bad enough that — this surprised me greatly when I learned it! — serious web applications that need i18n capabilities (most commonly, financial sites displaying currencies) will box up the data, send it to a server, have the server perform the operation, and send it back to the client. Server roundtrips just to format amounts of money. Yeesh.

A new JS Internationalization API

The new ECMAScript Internationalization API greatly improves JavaScript’s i18n capabilities. It provides all the flourishes one could want for formatting dates and numbers and sorting text. The locale is selectable, with fallback if the requested locale is unsupported. Formatting requests can specify the particular components to include. Custom formats for percentages, significant digits, and currencies are supported. Numerous collation options are exposed for use in sorting text. And if you care about performance, the up-front work to select a locale and process options can now be done once, instead of once every time a locale-dependent operation is performed.

That said, the API is not a panacea. The API is “best effort” only. Precise outputs are almost always deliberately unspecified. An implementation could legally support only the oj locale, or it could ignore (almost all) provided formatting options. Most implementations will have high-quality support for many locales, but it’s not guaranteed (particularly on resource-constrained systems such as mobile).

Under the hood, Firefox’s implementation depends upon the International Components for Unicode library (ICU), which in turn depends upon the Unicode Common Locale Data Repository (CLDR) locale data set. Our implementation is self-hosted: most of the implementation atop ICU is written in JavaScript itself. We hit a few bumps along the way (we haven’t self-hosted anything this large before), but nothing major.

The Intl interface

The i18n API lives on the global Intl object. Intl contains three constructors: Intl.Collator, Intl.DateTimeFormat, and Intl.NumberFormat. Each constructor creates an object exposing the relevant operation, efficiently caching locale and options for the operation. Creating such an object follows this pattern:

var ctor = "Collator"; // or the others var instance = new Intl[ctor](locales, options);

locales is a string specifying a single language tag or an arraylike object containing multiple language tags. Language tags are strings like en (English generally), de-AT (German as used in Austria), or zh-Hant-TW (Chinese as used in Taiwan, using the traditional Chinese script). Language tags can also include a “Unicode extension”, of the form -u-key1-value1-key2-value2..., where each key is an “extension key”. The various constructors interpret these specially.

options is an object whose properties (or their absence, by evaluating to undefined) determine how the formatter or collator behaves. Its exact interpretation is determined by the individual constructor.

Given locale information and options, the implementation will try to produce the closest behavior it can to the “ideal” behavior. Firefox supports 400+ locales for collation and 600+ locales for date/time and number formatting, so it’s very likely (but not guaranteed) the locales you might care about are supported.

Intl generally provides no guarantee of particular behavior. If the requested locale is unsupported, Intl allows best-effort behavior. Even if the locale is supported, behavior is not rigidly specified. Never assume that a particular set of options corresponds to a particular format. The phrasing of the overall format (encompassing all requested components) might vary across browsers, or even across browser versions. Individual components’ formats are unspecified: a short-format weekday might be “S”, “Sa”, or “Sat”. The Intl API isn’t intended to expose exactly specified behavior.

Date/time formatting Options

The primary options properties for date/time formatting are as follows:

weekday, era
"narrow", "short", or "long". (era refers to typically longer-than-year divisions in a calendar system: BC/AD, the current Japanese emperor’s reign, or others.)
month
"2-digit", "numeric", "narrow", "short", or "long"
year
day
hour, minute, second
"2-digit" or "numeric"
timeZoneName
"short" or "long"
timeZone
Case-insensitive "UTC" will format with respect to UTC. Values like "CEST" and "America/New_York" don’t have to be supported, and they don’t currently work in Firefox.

The values don’t map to particular formats: remember, the Intl API almost never specifies exact behavior. But the intent is that "narrow", "short", and "long" produce output of corresponding size — “S” or “Sa”, “Sat”, and “Saturday”, for example. (Output may be ambiguous: Saturday and Sunday both could produce “S”.) "2-digit" and "numeric" map to two-digit number strings or full-length numeric strings: “70” and “1970”, for example.

The final used options are largely the requested options. However, if you don’t specifically request any weekday/year/month/day/hour/minute/second, then year/month/day will be added to your provided options.

Beyond these basic options are a few special options:

hour12
Specifies whether hours will be in 12-hour or 24-hour format. The default is typically locale-dependent. (Details such as whether midnight is zero-based or twelve-based and whether leading zeroes are present are also locale-dependent.)

There are also two special properties, localeMatcher (taking either "lookup" or "best fit") and formatMatcher (taking either "basic" or "best fit"), each defaulting to "best fit". These affect how the right locale and format are selected. The use cases for these are somewhat esoteric, so you should probably ignore them.

Locale-centric options

DateTimeFormat also allows formatting using customized calendaring and numbering systems. These details are effectively part of the locale, so they’re specified in the Unicode extension in the language tag.

For example, Thai as spoken in Thailand has the language tag th-TH. Recall that a Unicode extension has the format -u-key1-value1-key2-value2.... The calendaring system key is ca, and the numbering system key is nu. The Thai numbering system has the value thai, and the Chinese calendaring system has the value chinese. Thus to format dates in this overall manner, we tack a Unicode extension containing both these key/value pairs onto the end of the language tag: th-TH-u-ca-chinese-nu-thai.

For more information on the various calendaring and numbering systems, see the full DateTimeFormat documentation.

Examples

After creating a DateTimeFormat object, the next step is to use it to format dates via the handy format() function. Conveniently, this function is a bound function: you don’t have to call it on the DateTimeFormat directly. Then provide it a timestamp or Date object.

Putting it all together, here are some examples of how to create DateTimeFormat options for particular uses, with current behavior in Firefox.

var msPerDay = 24 * 60 * 60 * 1000; // July 17, 2014 00:00:00 UTC. var july172014 = new Date(msPerDay * (44 * 365 + 11 + 197));

Let’s format a date for English as used in the United States. Let’s include two-digit month/day/year, plus two-digit hours/minutes, and a short time zone to clarify that time. (The result would obviously be different in another time zone.)

var options = { year: "2-digit", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", timeZoneName: "short" }; var americanDateTime = new Intl.DateTimeFormat("en-US", options).format; print(americanDateTime(july172014)); // 07/16/14, 5:00 PM PDT

Or let’s do something similar for Portuguese — ideally as used in Brazil, but in a pinch Portugal works. Let’s go for a little longer format, with full year and spelled-out month, but make it UTC for portability.

var options = { year: "numeric", month: "long", day: "numeric", hour: "2-digit", minute: "2-digit", timeZoneName: "short", timeZone: "UTC" }; var portugueseTime = new Intl.DateTimeFormat(["pt-BR", "pt-PT"], options); // 17 de julho de 2014 00:00 GMT print(portugueseTime.format(july172014));

How about a compact, UTC-formatted weekly Swiss train schedule? We’ll try the official languages from most to least popular to choose the one that’s most likely to be readable.

var swissLocales = ["de-CH", "fr-CH", "it-CH", "rm-CH"]; var options = { weekday: "short", hour: "numeric", minute: "numeric", timeZone: "UTC", timeZoneName: "short" }; var swissTime = new Intl.DateTimeFormat(swissLocales, options).format; print(swissTime(july172014)); // Do. 00:00 GMT

Or let’s try a date in descriptive text by a painting in a Japanese museum, using the Japanese calendar with year and era:

var jpYearEra = new Intl.DateTimeFormat("ja-JP-u-ca-japanese", { year: "numeric", era: "long" }); print(jpYearEra.format(july172014)); // 平成26年

And for something completely different, a longer date for use in Thai as used in Thailand — but using the Thai numbering system and Chinese calendar. (Quality implementations such as Firefox’s would treat plain th-TH as th-TH-u-ca-buddhist-nu-latn, imputing Thailand’s typical Buddhist calendar system and Latin 0-9 numerals.)

var options = { year: "numeric", month: "long", day: "numeric" }; var thaiDate = new Intl.DateTimeFormat("th-TH-u-nu-thai-ca-chinese", options); print(thaiDate.format(july172014)); // ๒๐ 6 ๓๑

Calendar and numbering system bits aside, it’s relatively simple. Just pick your components and their lengths.

Number formatting Options

The primary options properties for number formatting are as follows:

style
"currency", "percent", or "decimal" (the default) to format a value of that kind.
currency
A three-letter currency code, e.g. USD or CHF. Required if style is "currency", otherwise meaningless.
currencyDisplay
"code", "symbol", or "name", defaulting to "symbol". "code" will use the three-letter currency code in the formatted string. "symbol" will use a currency symbol such as $ or £. "name" typically uses some sort of spelled-out version of the currency. (Firefox currently only supports "symbol", but this will be fixed soon.)
minimumIntegerDigits
An integer from 1 to 21 (inclusive), defaulting to 1. The resulting string is front-padded with zeroes until its integer component contains at least this many digits. (For example, if this value were 2, formatting 3 might produce “03”.)
minimumFractionDigits, maximumFractionDigits
Integers from 0 to 20 (inclusive). The resulting string will have at least minimumFractionDigits, and no more than maximumFractionDigits, fractional digits. The default minimum is currency-dependent (usually 2, rarely 0 or 3) if style is "currency", otherwise 0. The default maximum is 0 for percents, 3 for decimals, and currency-dependent for currencies.
minimumSignificantDigits, maximumSignificantDigits
Integers from 1 to 21 (inclusive). If present, these override the integer/fraction digit control above to determine the minimum/maximum significant figures in the formatted number string, as determined in concert with the number of decimal places required to accurately specify the number. (Note that in a multiple of 10 the significant digits may be ambiguous, as in “100” with its one, two, or three significant digits.)
useGrouping
Boolean (defaulting to true) determining whether the formatted string will contain grouping separators (e.g. “,” as English thousands separator).

NumberFormat also recognizes the esoteric, mostly ignorable localeMatcher property.

Locale-centric options

Just as DateTimeFormat supported custom numbering systems in the Unicode extension using the nu key, so too does NumberFormat. For example, the language tag for Chinese as used in China is zh-CN. The value for the Han decimal numbering system is hanidec. To format numbers for these systems, we tack a Unicode extension onto the language tag: zh-CN-u-nu-hanidec.

For complete information on specifying the various numbering systems, see the full NumberFormat documentation.

Examples

NumberFormat objects have a format function property just as DateTimeFormat objects do. And as there, the format function is a bound function that may be used in isolation from the NumberFormat.

Here are some examples of how to create NumberFormat options for particular uses, with Firefox’s behavior. First let’s format some money for use in Chinese as used in China, specifically using Han decimal numbers (instead of much more common Latin numbers). Select the "currency" style, then use the code for Chinese renminbi (yuan), grouping by default, with the usual number of fractional digits.

var hanDecimalRMBInChina = new Intl.NumberFormat("zh-CN-u-nu-hanidec", { style: "currency", currency: "CNY" }); print(hanDecimalRMBInChina.format(1314.25)); // ¥ 一,三一四.二五

Or let’s format a United States-style gas price, with its peculiar thousandths-place 9, for use in English as used in the United States.

var gasPrice = new Intl.NumberFormat("en-US", { style: "currency", currency: "USD", minimumFractionDigits: 3 }); print(gasPrice.format(5.259)); // $5.259

Or let’s try a percentage in Arabic, meant for use in Egypt. Make sure the percentage has at least two fractional digits. (Note that this and all the other RTL examples may appear with different ordering in RTL context, e.g. ٤٣٫٨٠٪ instead of ٤٣٫٨٠٪.)

var arabicPercent = new Intl.NumberFormat("ar-EG", { style: "percent", minimumFractionDigits: 2 }).format; print(arabicPercent(0.438)); // ٤٣٫٨٠٪

Or suppose we’re formatting for Persian as used in Afghanistan, and we want at least two integer digits and no more than two fractional digits.

var persianDecimal = new Intl.NumberFormat("fa-AF", { minimumIntegerDigits: 2, maximumFractionDigits: 2 }); print(persianDecimal.format(3.1416)); // ۰۳٫۱۴

Finally, let’s format an amount of Bahraini dinars, for Arabic as used in Bahrain. Unusually compared to most currencies, Bahraini dinars divide into thousandths (fils), so our number will have three places. (Again note that apparent visual ordering should be taken with a grain of salt.)

var bahrainiDinars = new Intl.NumberFormat("ar-BH", { style: "currency", currency: "BHD" }); print(bahrainiDinars.format(3.17)); // د.ب.‏ ٣٫١٧٠ Collation Options

The primary options properties for collation are as follows:

usage
"sort" or "search" (defaulting to "sort"), specifying the intended use of this Collator. (A search collator might want to consider more strings equivalent than a sort collator would.)
sensitivity
"base", "accent", "case", or "variant". This affects how sensitive the collator is to characters that have the same “base letter” but have different accents/diacritics and/or case. (Base letters are locale-dependent: “a” and “ä” have the same base letter in German but are different letters in Swedish.) "base" sensitivity considers only the base letter, ignoring modifications (so for German “a”, “A”, and “ä” are considered the same). "accent" considers the base letter and accents but ignores case (so for German “a” and “A” are the same, but “ä” differs from both). "case" considers the base letter and case but ignores accents (so for German “a” and “ä” are the same, but “A” differs from both). Finally, "variant" considers base letter, accents, and case (so for German “a”, “ä, “ä” and “A” all differ). If usage is "sort", the default is "variant"; otherwise it’s locale-dependent.
numeric
Boolean (defaulting to false) determining whether complete numbers embedded in strings are considered when sorting. For example, numeric sorting might produce "F-4 Phantom II", "F-14 Tomcat", "F-35 Lightning II"; non-numeric sorting might produce "F-14 Tomcat", "F-35 Lightning II", "F-4 Phantom II".
caseFirst
"upper", "lower", or "false" (the default). Determines how case is considered when sorting: "upper" places uppercase letters first ("B", "a", "c"), "lower" places lowercase first ("a", "c", "B"), and "false" ignores case entirely ("a", "B", "c"). (Note: Firefox currently ignores this property.)
ignorePunctuation
Boolean (defaulting to false) determining whether to ignore embedded punctuation when performing the comparison (for example, so that "biweekly" and "bi-weekly" compare equivalent).

And there’s that localeMatcher property that you can probably ignore.

Locale-centric options

The main Collator option specified as part of the locale’s Unicode extension is co, selecting the kind of sorting to perform: phone book (phonebk), dictionary (dict), and many others.

Additionally, the keys kn and kf may, optionally, duplicate the numeric and caseFirst properties of the options object. But they’re not guaranteed to be supported in the language tag, and options is much clearer than language tag components. So it’s best to only adjust these options through options.

These key-value pairs are included in the Unicode extension the same way they’ve been included for DateTimeFormat and NumberFormat; refer to those sections for how to specify these in a language tag.

Examples

Collator objects have a compare function property. This function accepts two arguments x and y and returns a number less than zero if x compares less than y, 0 if x compares equal to y, or a number greater than zero if x compares greater than y. As with the format functions, compare is a bound function that may be extracted for standalone use.

Let’s try sorting a few German surnames, for use in German as used in Germany. There are actually two different sort orders in German, phonebook and dictionary. Phonebook sort emphasizes sound, and it’s as if “ä”, “ö”, and so on were expanded to “ae”, “oe”, and so on prior to sorting.

var names = ["Hochberg", "Hönigswald", "Holzman"]; var germanPhonebook = new Intl.Collator("de-DE-u-co-phonebk"); // as if sorting ["Hochberg", "Hoenigswald", "Holzman"]: // Hochberg, Hönigswald, Holzman print(names.sort(germanPhonebook.compare).join(", "));

Some German words conjugate with extra umlauts, so in dictionaries it’s sensible to order ignoring umlauts (except when ordering words differing only by umlauts: schon before schön).

var germanDictionary = new Intl.Collator("de-DE-u-co-dict"); // as if sorting ["Hochberg", "Honigswald", "Holzman"]: // Hochberg, Holzman, Hönigswald print(names.sort(germanDictionary.compare).join(", "));

Or let’s sort a list Firefox versions with various typos (different capitalizations, random accents and diacritical marks, extra hyphenation), in English as used in the United States. We want to sort respecting version number, so do a numeric sort so that numbers in the strings are compared, not considered character-by-character.

var firefoxen = ["FireFøx 3.6", "Fire-fox 1.0", "Firefox 29", "FÍrefox 3.5", "Fírefox 18"]; var usVersion = new Intl.Collator("en-US", { sensitivity: "base", numeric: true, ignorePunctuation: true }); // Fire-fox 1.0, FÍrefox 3.5, FireFøx 3.6, Fírefox 18, Firefox 29 print(firefoxen.sort(usVersion.compare).join(", "));

Last, let’s do some locale-aware string searching that ignores case and accents, again in English as used in the United States.

// Comparisons work with both composed and decomposed forms. var decoratedBrowsers = [ "A\u0362maya", // A͢maya "CH\u035Brôme", // CH͛rôme "FirefÓx", "sAfàri", "o\u0323pERA", // ọpERA "I\u0352E", // I͒E ]; var fuzzySearch = new Intl.Collator("en-US", { usage: "search", sensitivity: "base" }); function findBrowser(browser) { function cmp(other) { return fuzzySearch.compare(browser, other) === 0; } return cmp; } print(decoratedBrowsers.findIndex(findBrowser("Firêfox"))); // 2 print(decoratedBrowsers.findIndex(findBrowser("Safåri"))); // 3 print(decoratedBrowsers.findIndex(findBrowser("Ãmaya"))); // 0 print(decoratedBrowsers.findIndex(findBrowser("Øpera"))); // 4 print(decoratedBrowsers.findIndex(findBrowser("Chromè"))); // 1 print(decoratedBrowsers.findIndex(findBrowser("IË"))); // 5 Odds and ends

It may be useful to determine whether support for some operation is provided for particular locales, or to determine whether a locale is supported. Intl provides supportedLocales() functions on each constructor, and resolvedOptions() functions on each prototype, to expose this information.

var navajoLocales = Intl.Collator.supportedLocalesOf(["nv"], { usage: "sort" }); print(navajoLocales.length > 0 ? "Navajo collation supported" : "Navajo collation not supported"); var germanFakeRegion = new Intl.DateTimeFormat("de-XX", { timeZone: "UTC" }); var usedOptions = germanFakeRegion.resolvedOptions(); print(usedOptions.locale); // de print(usedOptions.timeZone); // UTC Legacy behavior

The ES5 toLocaleString-style and localeCompare functions previously had no particular semantics, accepted no particular options, and were largely useless. So the i18n API reformulates them in terms of Intl operations. Each method now accepts additional trailing locales and options arguments, interpreted just as the Intl constructors would do. (Except that for toLocaleTimeString and toLocaleDateString, different default components are used if options aren’t provided.)

For brief use where precise behavior doesn’t matter, the old methods are fine to use. But if you need more control or are formatting or comparing many times, it’s best to use the Intl primitives directly.

Conclusion

Internationalization is a fascinating topic whose complexity is bounded only by the varied nature of human communication. The Internationalization API addresses a small but quite useful portion of that complexity, making it easier to produce locale-sensitive web applications. Go use it!

(And a special thanks to Norbert Lindenberg, Anas El Husseini, Simon Montagu, Gary Kwong, Shu-yu Guo, Ehsan Akhgari, the people of #mozilla.de, and anyone I may have forgotten [sorry!] who provided feedback on this article or assisted me in producing and critiquing the examples. The English and German examples were the limit of my knowledge, and I’d have been completely lost on the other examples without their assistance. Blame all remaining errors on me. Thanks again!)

(and to reiterate: comment on the Hacks post if you have anything to say)

Categorieën: Mozilla-nl planet

Sriram Ramasubramanian: Centered Buttons

Mozilla planet - do, 11/12/2014 - 22:28

How can we use the same hack as Multiple Text Layout in some UI we need most of the times? Let’s take buttons for example. If we want the glyph in the button to be centered along with the text, we cannot use compound drawables — as they are always drawn along the edges of the container.

Centered Buttons

We could use our getCompoundPaddingLeft() to pack the glyph with the text.

@Override public int getCompoundPaddingLeft() { // Ideally we should be overriding getTotalPaddingLeft(). // However, android doesn't make use of that method, // instead uses this method for calculations. int paddingLeft = super.getCompoundPaddingLeft(); paddingLeft += mDrawableWidth + getCompoundDrawablePadding(); return paddingLeft; }

This offsets the space on the left and Android will take care of placing the text accordingly. Now we can place the Drawable in the space we created.

@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int paddingLeft = getPaddingLeft(); int paddingRight = getPaddingRight(); int drawableVerticalHeight = mDrawableHeight + getPaddingTop() + getPaddingBottom(); int width = getMeasuredWidth(); int height = Math.max(drawableVerticalHeight, getMeasuredHeight()); setMeasuredDimension(width, height); int compoundPadding = getCompoundDrawablePadding(); float totalWidth = mDrawableWidth + compoundPadding + getLayout().getLineWidth(0); float offsetX = (width - totalWidth - paddingLeft - paddingRight)/2.0f; mTranslateX = offsetX + paddingLeft; mTranslateY = (height - mDrawableHeight)/2.0f; }

The mTranslateX and mTranslateY are used to hold how far to translate to draw the drawable. Either the Drawable’s bounds can be shifted inside onMeasure() to reflect the translation. Or, the Canvas can be translated inside onDraw(). This will help us draw the glyph centered along with the text as a part of a Button!


Categorieën: Mozilla-nl planet

Kim Moir: Releng 2015 CFP now open

Mozilla planet - do, 11/12/2014 - 22:00
Florence, Italy.  Home of beautiful architecture.

Il Duomo di Firenze by ©runner310, Creative Commons by-nc-sa 2.0

Delicious food and drink.

Panzanella by © Pete Carpenter, Creative Commons by-nc-sa 2.0
Caffè ristretto by © Marcelo César Augusto Romeo, Creative Commons by-nc-sa 2.0

And next May, release engineering :-)

The CFP for Releng 2015 is now open.  The deadline for submissions is January 23, 2015.  It will be held on May 19, 2015 in Florence Italy and co-located with ICSE 2015.   We look forward to seeing your proposals about the exciting work you're doing in release engineering!

If you have questions about the submission process or anything else, please contact any of the program committee members. My email is kmoir and I work at mozilla.com.
Categorieën: Mozilla-nl planet

Naoki Hirata: Einstein Quote for Mozillians

Mozilla planet - do, 11/12/2014 - 21:38

“Out of clutter, find simplicity. From discord find harmony. In the middle of difficulty lies opportunity.” – Albert Einstein

From : http://www.folderarchy.com/albert-einstein/


Filed under: Planet Tagged: Planet
Categorieën: Mozilla-nl planet

Fabien Cazenave: KompoZer 0.8b2

Mozilla planet - do, 11/12/2014 - 20:59

KompoZer logo

KompoZer 0.8b2 is finally ready. Few visible changes, but a lot of bugfixes and code cleaning under the hood.

You can grab KompoZer 0.8b2 here: http://kompozer.net/download.php

Enjoy, and please report bugs!

Bug Fixes

We’ve tried to solve the most frequently reported bugs:

  • the CSS Editor shouldn't add those annoying “*|” strings in the selectors any more
  • the preview in the “Image Properties” box now works properly
  • better FTP support (right-click in the Site Manager context menu)
  • the markup cleaner doesn't crash on nested lists any more
  • Enter in a paragraph now creates a new paragraph
  • the “Credits” panel in the About box is back ;-)

KompoZer 0.8b2 is now a more reliable editor: the regressions in the CSS editor were a complete blocker for myself, so I guess it’s been a real nightmare for most users. We’ve fixed a lot of small bugs and I think the overall user experience should be much better than with the previous versions.

18*4 Localized Binaries

Cédric Corazza, our l10n lead, has done a great job to release localized binaries for all the supported languages at once. This time he’s had much more work than for the previous beta:

  • we had 9 locales for the 0.8b1 release, there are 18 locales for 0.8b2:
    • Catalan, Dutch, Hungarian, Japanese got ready after the 0.8b1 release
    • Simplified Chinese, Esperanto, Finnish, Portuguese, Upper Sorbian have been added for the 0.8b2
  • Cédric has made Windows™ installers, which should put an end to one of the most frequent feature request
  • he’s built all binaries manually, as we don’t have any kind of script to ease this task (I considered that as a typical “l10n lead job”)

Cédric, congrats! and go get some sleep, the Korean and Bulgarian locales are getting ready. ;-) I’ll definitely write a few scripts to ease your work for the next release.

Inline Spell Checker

The inline spell checker in KompoZer 0.7.10 was inherited from Nvu, it was implemented with a specific patch against the Gecko 1.7 core and it caused a lot of freezes and crashes. As a result, most users (including myself) disabled it and I didn’t see it as an important feature to bring back in KompoZer 0.8.

As you can guess, a lot of users had a very different opinion on this. :-)

Unlike Gecko 1.7, Gecko 1.8.1 has a very good built-in inline spell checker. I’ve had a look at Thunderbird’s code and I found out enabling the inline spell checker in KompoZer was a snap. I’m sorry I didn’t do it sooner — but now it’s done, and it’s working fine as far as I know.

DOM Explorer Sidebar

I’m working with Fabien ’Kasparov’ Rocu on the next version of the DOM Explorer. As Fabien is implementing his ideas in an extension, I had to clean up the DOM Explorer and add a few hooks for his addon. To ease the development of his add-on, we’ve decided to implement a part of his work directly in KompoZer 0.8b2:

  • the DOM Explorer now shows the HTML attributes of the current element
  • a double-click on an element in the DOM Explorer brings up its “Property” dialog

The real improvement will come with Fabien’s extension, which should be released in April 2010. I’ll come back to this in another blog post.

New Keyboard Shortcuts

I’m known to be a dangerous pervert when it comes to computer keyboards — I admit I hate having to use a mouse when I’m editing a text. These new keyboard shortcuts aren’t documented, you can see them as a hidden bonus:

  • Ctrl+(Up|Down) moves the caret to the (beginning|end) of the current element
  • Ctrl(+Shift)+Enter adds a new line after (before) the current element
  • Alt+Shift+Enter switches to “Source” view

The Ctrl+Up/Down shortcut is more than a productivity booster. One of the known problems of the Mozilla editor component is that in some situations, it can be difficult to put the caret where you want it: for instance, there’s no easy way to put the caret right after a <div> block if it’s the last block in the page. With KompoZer 0.7.10 you had to select the <div> in the status bar, press the right arrow and hit Return; now all you need is to do a Ctrl+Down.

The “Source” View Still Sucks…

…and I’m aware of that. Please configure KompoZer to use your favorite text editor to work on the HTML source, there’s a specific “HTML” button by default in the main toolbar for that. I can’t help it, I hate the “Source” view in Nvu and KompoZer 0.7:

  • I don’t see much point in a pseudo syntax hilighting that doesn’t update as you type
  • I don’t see any point in showing line numbers that don’t match the *real* line numbers in the HTML file
  • nobody understands why the “Source” view hides the document tabs
  • it was the main source of crashes for KompoZer 0.7

The SeaMonkey-like plaintext editor, in my opinion, is much better at the moment — and on my first trunk builds (KompoZer 0.9a1pre / Gecko 1.9.3), Bespin is already working quite well.

Again, I understand a lot of users have a very different opinion on this, so I’ve tried an interesting experiment with this “Source” view: basically, I’ve re-written the main <tabeditor> element so it includes its own source editor. This embedded source editor could be used either for the “Split” view or for the “Source” view, and I could switch to “Source” mode without loosing the document tabs.

Unfortunately, this new <tabeditor> element raised a few problems that I couldn’t solve easily for this 0.8b2 release, so I’ve had to revert to the good old plaintext editor. For the 0.8b3 I’ll probably re-implement an Nvu-like “Source” view, rather than spending too much time on a feature that won’t work as well as Bespin: I prefer to release KompoZer 0.8 sooner in order to propose a Bespin-based KompoZer 0.9 as soon as possible.

The HTML Serializer Still Sucks…

…but we’re working on it. As you may have noticed, the HTML output of KompoZer 0.8 is already much cleaner than the one we had in KompoZer 0.7, especially if you check the “reformat HTML source” option: the most visible point is, there are (almost) no empty lines any more in the output files. But your well-defined indentation is still destroyed by KompoZer, which is a real pain when switching to “Source” mode.

Of course, you can use HTML Tidy as a workaround; I even used to design an Nvu extension for that. But this means dealing with temp files, serializing the files twice (once with KompoZer + reformatting with Tidy), and risking data losses (especially in utf-8, don’t ask me why). And the HTML code in the “Source” view is still a mess.

The great news is, Laurent Jouanneau has backported his XHTML serializer to Gecko 1.8.1 so I could use it for KompoZer 0.8 — and the first results look great! See this small example I saved with KompoZer 0.7.10, KompoZer 0.8b2 and KompoZer 0.8b3pre. Looks like we can finally get rid of HTML Tidy!

Almost Done

There are four main points to address before we can release a third (and hopefully last) beta:

  • adapt KompoZer 0.8 to the new HTML serializer;
  • get some kind of colored source view working;
  • fix the bugs in the “Split” view so people start using it;
  • work on FTP support to replace the current “Publish” button.

Please test this new version and report bugs. Many thanks to all users who donated or gave some time to keep this project running!

Categorieën: Mozilla-nl planet

Fabien Cazenave: KompoZer 0.8b3

Mozilla planet - do, 11/12/2014 - 20:59

KompoZer logo

We’ve just released KompoZer 0.8b3:

Localized binaries are available on the official download page: http://kompozer.net/download.php.

This maintainance release fixes two regressions that have been introduced in the previous beta:

  • bug #2957813, the "Source" mode was not applying modifications properly
  • bug #2959534, the "class" drop-down list was broken by a dirty attempt to make it UTF8-friendly

I didn’t want to take the risk of addressing other bugs but I did work on bug 1831943 by disabling line wrapping for Asian users. The relevant preference (editor.htmlWrapColumn) it now set to zero for Chinese (zh-CN, zh-TW) and Japanese (ja) builds, and it should be read properly by KompoZer — both when switching to “Source” mode and when saving HTML documents. This is still experimental, so your feedback will be welcome.

We’ve spent a few hours designing a bash/python script to make localized binaries for the 18 languages that are currently supported by KompoZer. This script works fine on Linux and OSX and it can build win32 installers by launching the InnoSetup compiler through Wine. It also checks that I haven't forgotten to include the MSVC7 DLLs in the win32 binaries, which should avoid us a few bad surprises for the next releases…

For the next beta we’ll focus on the “Source” view and the FTP module. We’ll do our best to release it in March.

EDIT In case you’ve downloaded a Windows build with missing MSVC7 dlls, I’ve just changed the path of all Windows binaries on SourceForge. Please download KompoZer 0.8b3 again, the problem should be solved. Sorry for the trouble. :-/

Categorieën: Mozilla-nl planet

Chris Ilias: My Installed Add-ons – Context Search

Mozilla planet - do, 11/12/2014 - 18:10

I love finding new extensions that do things I never even thought to search for. One of the best ways to find them is through word of mouth. In this case, I guess you can call it “word of blog”. I’d like to start a series of blog posts about the extensions I use, and maybe you’ll see one that you want to use.

The first one is Context Search. Context Search is one of those extensions I think should be part of Firefox. Context Search allows you to choose which search engine you use for each search. If it’s a word you aren’t familiar with, you can choose the Websters search engine. If it’s an acronym you aren’t familiar with, you can choose the Acronym Finder search engine.

Without the extension, when you highlight text then right-click, the menu will contain an item to search your preferred search engine for the text that is highlighted. With Context Search, you are instead given a list of your installed search engines, so you can pick which one to use. The search results will open in a new tab. I find myself using it more than the search bar.

Here’s a screenshot:

You can install it via the Mozilla Add-ons site.

Categorieën: Mozilla-nl planet

Yunier José Sosa Vázquez: Actualizando complementos

Mozilla planet - do, 11/12/2014 - 17:30

addonsDespués de un tiempo sin actualizar los complementos disponibles en nuestro AMO (Addons.Mozilla.Org), volvemos a ofrecerle este servicio.

Ofrecemos disculpas por las molestias ocasionadas, no habíamos publicado más porque una actualización en los servicios de Mozilla, había dejado desactualizada la carpeta en su FTP público — los complementos se guardan en otra ubicación.

Poco a poco iremos actualizando y publicando nuevas extensiones para toda la comunidad cubana. Si existe un add-on que no ha sido actualizado — unos cuantos –, nos lo pueden decir y le damos prioridad en la cola.

Categorieën: Mozilla-nl planet

Robert O'Callahan: rr 3.0 Released With x86-64 Support

Mozilla planet - do, 11/12/2014 - 13:34

I just pushed the release of rr 3.0. The big milestone for this release is that x86-64 support is fully functional! On 64-bit machines, we build a 64-bit rr that can record and replay 64-bit processes with the same set of features and performance-enhancing tricks that we developed for 32-bit. Not only that, but 64-bit rr can also record and replay 32-bit processes or even a mix of 32-bit and 64-bit processes in the same process tree. 64-bit support is mostly due to Nathan Froyd and we hope it significantly lowers barriers to using rr.

Many other internal improvements and sundry bug fixes have landed since 2.0. Some highlights:

  • rr can record executables that use a #! interpreter, e.g. bash scripts. Naturally the entire process tree is recorded, so this simplifies debugging of applications that use complex wrapper scripts.
  • A new rr ps command lists the processes recorded in an rr trace, making it easier to select the process you want to debug.
  • To make that even easier, rr replay -p <command> automatically attaches to the first exec of <command>. E.g. to debug e10s Firefox's first content process, use rr replay -p plugin-container.
  • Sometimes you record a trace, then modify the program but later want to replay the original trace, which requires the original program binaries. rr now uses hardlinks to save files in the trace so that in many cases, old traces are still replayable after a rebuild. Thanks to Karl Tomlinson for the idea.
  • Some small changes in command-line syntax were made to regularize the syntax and prepare for future expansion.
  • Many bug fixes to broaden the range of recordable applications. E.g. LibreOffice and QEMU work now.

Development carries on; visit rr-dev for exciting updates.

Have fun using rr!

Categorieën: Mozilla-nl planet

Mozilla to Support Certificate Transparency in Firefox - Threatpost

Nieuws verzameld via Google - do, 11/12/2014 - 13:31

Mozilla to Support Certificate Transparency in Firefox
Threatpost
Mozilla is planning to add support for Certificate Transparency checks in Firefox in the near future, but the company says that the feature won't be turned on by default at first. Certificate Transparency is a proposal from engineers at Google that ...

Categorieën: Mozilla-nl planet

Mozilla to Support Certificate Transparency in Firefox - Threatpost

Nieuws verzameld via Google - do, 11/12/2014 - 13:31

Mozilla to Support Certificate Transparency in Firefox
Threatpost
Mozilla is planning to add support for Certificate Transparency checks in Firefox in the near future, but the company says that the feature won't be turned on by default at first. Certificate Transparency is a proposal from engineers at Google that ...

Google Nieuws
Categorieën: Mozilla-nl planet

Nicholas Nethercote: Cumulative heap profiling in Firefox with DMD

Mozilla planet - do, 11/12/2014 - 03:26

DMD is a tool that I originally created to help identify where new memory reporters should be added to Firefox in order to reduce the “heap-unclassified” measurement in about:memory. (The name is actually short for “Dark Matter Detector”, because we sometimes call the “heap-unclassified” measurement “dark matter“.)

Recently, I’ve modified DMD to become a more general heap profiling tool. It now has three distinct modes of operation.

  1. “Dark matter”: this mode gives you DMD’s original behaviour.
  2. “Live”: this mode tracks all the live blocks on the system heap, and lets you take snapshots at particular points in time.
  3. Cumulative“: this mode tracks all the blocks that have ever been allocated on the system heap, and so gives you information about all the allocations done by Firefox during an entire session.

Most memory profilers (including as about:memory) are snapshot-based, and so work much like DMD’s “live” mode. But “cumulative” mode is equally interesting.

In particular, unlike “live” mode, “cumulative” mode tells you about parts of the code that are responsible for allocating many short-lived heap blocks (sometimes called “heap churn”). Such allocations can hurt performance: allocations and deallocations themselves aren’t free, particularly because they require obtaining a global lock; such code often involves unnecessary initialization or copying of heap data; and if these allocations come in a variety of sizes they can cause additional heap fragmentation.

Another nice thing about cumulative heap profiling is that, unlike live heap profiling, you don’t have to decide when to take snapshots. You can just profile an entire workload of interest and get the results at the end.

I’ve used DMD’s cumulative mode to find inefficiencies in SpiderMonkey’s source compression  and code generation, SQLite, NSS, nsTArray, XDR encoding, Gnome start-up, IPC messaging, nsStreamLoader, cycle collection, and safe-browsing. There are “start doing something clever” optimizations and then there are “stop doing something stupid” optimizations, and every one of these fixes has been one of the latter. Each change has avoided cumulative heap allocations ranging from tens to thousands of MiBs.

It’s typically difficult to quantify any speed-ups from these changes, because the workloads are noisy and non-deterministic, but I’m convinced that simple changes to fix these issues are worthwhile. For one, I used cumulative profiling (via a different tool) to drive the major improvements I made to pdf.js earlier this year. Also, Chrome developers have found that “Chrome in general is *very* close to the threshold where heap lock contention causes noticeable UI lag”.

So far I have only profiled a few simple workloads. There are all sorts of things I haven’t tried: text-heavy pages, image-heavy pages, audio and video, WebRTC, WebGL, popular benchmarks… the list goes on. I intend to do more profiling and fix things where I can, but it would be great to have help from domain experts with this stuff. If you want to try out cumulative heap profiling in Firefox, please read the DMD instructions and feel free to ask me for help. In particular, I now have a good feel for which hot allocations are unavoidable and reasonable — plenty of them, of course — and which are avoidable. Let’s get rid of the avoidable ones.

Categorieën: Mozilla-nl planet

Fabien Cazenave: Back from Mozilla

Mozilla planet - wo, 10/12/2014 - 21:57

During the last 3 years I’ve worked full-time for Mozilla Corp, and now it’s more than time to move on.

Leaving the MoCo has been a very difficult step for me. I’ve been a Mozillian for the last 8 years, and it’s been much more than a friendly community or a challenging job for me. I’ve had a lot of fun, met amazing people, worked on exciting technologies. I’m very proud of what we did, and I’m even prouder of why we did it. Working for Mozilla felt like a love story, and ending a love story is always painful.

I just took a long, refreshing, offline break. Sorry if you tried to reach me during this period — I’m getting through the mailbox hell, and I’ll do my best to reply to every message.

Best wishes to all Mozillians, especially to the folks in the Paris office, the Spanish Connection, and my drinking pals all around the globe. I’ll be happy to share a few beers with you at a web or FLOSS event someday. :-)

Categorieën: Mozilla-nl planet

Pagina's