mozilla

Mozilla Nederland LogoDe Nederlandse
Mozilla gemeenschap

Will Kahn-Greene: Dennis v0.5 released! New lint rules, new template linter, bunch of fixes, and now a service!

Mozilla planet - ma, 25/08/2014 - 00:22
What is it?

Dennis is a Python command line utility (and library) for working with localization. It includes:

  • a linter for finding problems in strings in .po files like invalid Python variable syntax which leads to exceptions
  • a template linter for finding problems in strings in .pot files that make translator's lives difficult
  • a statuser for seeing the high-level translation/error status of your .po files
  • a translator for strings in your .po files to make development easier
v0.5 released!

Since the last release announcement, there have been a handful of new lint rules added:

  • W301: Translation consists of just white space
  • W302: The translation is the same as the original string
  • W303: There are descrepancies in the HTML between the original string and the translated string

Additionally, there's a new template linter for your .pot files which can catch things like:

  • W500: Strings with variable names like o, O, 0, l, 1 which can be hard to read and are often replaced with a similar looking letter by the translator.
  • W501: One-character variable names which don't give translators enough context about what's being translated.
  • W502: Multiple unnamed variables which can't be reordered because the order the variables are expanded is specified outside of the string.
Dennis in action

Want to see Dennis in action, but don't want to install Dennis? I threw it up as a service, though it's configured for SUMO: http://dennis-sumo.paas.allizom.org/

Note

I may change the URL and I might create a SUMO-agnostic version. If you're interested, let me know.

Where to go for more

For more specifics on this release, see here: http://dennis.readthedocs.org/en/v0.4/changelog.html#version-0-4-may-1st-2014

Documentation and quickstart here: http://dennis.readthedocs.org/en/v0.4/

Source code and issue tracker here: https://github.com/willkg/dennis

Source code and issue tracker for Denise (Dennis-as-a-service): https://github.com/willkg/denise

3 out of 5 summer interns use Dennis to improve their posture while pranking their mentors.

Categorieën: Mozilla-nl planet

Marco Zehe: Maintenance complete

Mozilla planet - zo, 24/08/2014 - 18:30

A day later than originally announced, I undertook the much needed maintenance. The site should be much faster now, having moved it to a more performant web hoster. I also consolidated all my blogs into a multi-site WordPress installation, which should make it much easier for me in the future to create little blogs for side projects, so I don’t have to use 3rd party services. You know, for the class and such. ;)

I also use a more modern theme now, using the excellent accessible and responsive Simone theme. This should make it much more reader-friendly. And it, of course, works great with screen readers, too!

So, enjoy! And I will have more news to share about Mozilla and web accessibility related stuff as always!

Categorieën: Mozilla-nl planet

Andy McKay: Private School

Mozilla planet - zo, 24/08/2014 - 16:10

I've been a bit out of touch recently with holidays, so I'm catching up on the BC teachers situation and what looks like an attempt by the BC Government to destroy public education.

This week the Minister launched a website giving "some of the options available to you". So what are my options? No public school system? Let's try private school. Here's a preliminary search.

My daughters are aged 8 and 10 and enjoy an excellent education in the public school system in French Immersion in North Vancouver, despite the Government. I also consider the school an excellent part of the local community.

Any schooling would ideally be in French and must definitely be non-religious in nature. In North and West Vancouver there are the following private schools and costs to us:

  • Lions Gate Christian Academy: "Moral & Spiritual Development from a Christian Perspective". Cost: $8,720. Distance: 3.8km. French Immersion: No.
  • Brockton School: "a rigorous academic education is balanced by arts and athletics in an environment where merit rather than materialism is the core value". Cost: $29,700. Distance: 10.8km. French Immersion: No.
  • Collingwood School: "Preparing people to thrive in meaningful lives". Cost: Not stated. Distance: 19.2km. French Immersion: No.
  • Mulgrave School: "a caring and supportive school community with high expectations and high levels of achievement". Cost: $35,940. Distance: 20.3km. French Immersion: No.
  • Ecole Francaise Internationale de Vancouver: "where critical thought processes and inter-cultural communication are the determining factors". Cost: $28,500. Distance: 10.4km. French Immersion: Yes.
  • The Vancouver Waldorf School: "educating hearts and minds". Cost: $28,240. Distance: 9.3km. French Immersion: No.

The highly questionable (if not laughable) Fraser Institute ranking ranks only a couple of these schools. Sherwood Park being just below the average and the West Vancouver schools Mulgrave and Collingwood well above the average.

Note that although I searched for schools on the North Shore, none of these are "local" and we would suffer a disconnect from our local community. Only one provides French Immersion. Lions Gate Christian Academy is definitely not going to happen.

Supposing I can get my children into one of these schools, it would drain my families resources by somewhere from $28k to $36k at the minimum. The median total income before tax in BC is $71k (source), after tax of 40%, let's say $43k. One of those private schools would consume 65% to 83% of the average after tax income.

As an extra kicker, since my wife is a teacher in the public school system, we have less money this year.

Do you have some realistic options for my family?

Categorieën: Mozilla-nl planet

Firefox mit Werbung - Mozilla weitet Experiment aus - GameStar

Nieuws verzameld via Google - zo, 24/08/2014 - 14:03

Golem.de

Firefox mit Werbung - Mozilla weitet Experiment aus
GameStar
Schon seit einiger Zeit experimentiert Mozilla mit der Möglichkeit, Werbung in Firefox zu platzieren, um auf diese Weise die starke finanzielle Abhängigkeit von Google reduzieren zu können. Bislang stammen weit über 90 Prozent aller Einnahmen von ...
Mozilla weitet Anzeigenprogramm für Firefox ausZDNet.de
Mozilla Enhanced Tiles: Firefox erhält nun doch Werbung für alle NutzerGolem.de
Firefox: Mozilla schaltet weitere WerbungGulli
Softonic DE -Ad-Hoc-News (Pressemitteilung) -PC Games Hardware
alle 15 nieuwsartikelen »Google Nieuws
Categorieën: Mozilla-nl planet

Google Chrome VS Mozilla Firefox VS Microsoft Internet Explorer: Which ... - KDramaStars

Nieuws verzameld via Google - zo, 24/08/2014 - 12:53

KDramaStars

Google Chrome VS Mozilla Firefox VS Microsoft Internet Explorer: Which ...
KDramaStars
The 3 alpha dogs in the battle of the browsers, Google Chrome, Mozilla Firefox, and Microsoft Internet Explorer, seem to just constantly keep up with the growing demand of internet users. Every update seems to address and even enhance various ...
Mozilla Firefox available on both PC and Android devicesStreetWise Tech
Six alternative web browsers you should know aboutGigaom
Firefox 34 to ship with lightweight theme suggestionsGhacks Technology News

alle 5 nieuwsartikelen »Google Nieuws
Categorieën: Mozilla-nl planet

Mozilla's Firefox Marketplace will soon use crowd-curation for apps - VentureBeat

Nieuws verzameld via Google - zo, 24/08/2014 - 01:14

VentureBeat

Mozilla's Firefox Marketplace will soon use crowd-curation for apps
VentureBeat
But Mozilla has some of the same problems that other app stores do. They need a way to surface the really good apps, and push down the apps that are a little less inspired. DeVaney believes at least part of the answer lies in audience curation of apps.
IRL: Giving Firefox OS a second chanceEngadget

alle 2 nieuwsartikelen »
Categorieën: Mozilla-nl planet

Ray Kiddy: To encourage civic participation and voting (in US)

Mozilla planet - zo, 24/08/2014 - 01:08
https://petitions.whitehouse.gov/petition/create-national-holidays-voting-consolidating-other-holidays-honor-civic-engagement/wx7xMFCR

Please consider whether this suggestion makes sense.
Categorieën: Mozilla-nl planet

Matt Brubeck: Let's build a browser engine! Part 4: Style

Mozilla planet - zo, 24/08/2014 - 00:45

Welcome back to my series on building your own toy browser engine. If you’re just tuning in, you can find the previous episodes here:

This article will cover what the CSS standard calls assigning property values, or what I call the style module. This module takes DOM nodes and CSS rules as input, and matches them up to determine the value of each CSS property for any given node.

This part doesn’t contain a lot of code, since I’ve left out all the really complicated parts. However, I think what’s left is still quite interesting, and I’ll also explain how some of the missing pieces can be implemented.

The Style Tree

The output of robinson’s style module is something I call the style tree. Each node in this tree includes a pointer to a DOM node, plus its CSS property values:

/// Map from CSS property names to values. type PropertyMap = HashMap<String, Value>; /// A node with associated style data. struct StyledNode<'a> { node: &'a Node, // pointer to a DOM node specified_values: PropertyMap, children: Vec<StyledNode<'a>>, }

What’s with all the 'a stuff? Those are lifetimes, part of how Rust guarantees that pointers are memory-safe without requiring garbage collection. If you’re not working in Rust you can ignore them; they aren’t critical to the code’s meaning.

We could add new fields to the dom::Node struct instead of creating a new tree, but I wanted to keep style code out of the earlier “lessons.” This also gives me an opportunity to talk about the parallel trees that inhabit most rendering engines.

A browser engine module often takes one tree as input, and produces a different but related tree as output. For example, Gecko’s layout code takes a DOM tree and produces a frame tree, which is then used to build a view tree. Blink and WebKit transform the DOM tree into a render tree. Later stages in all these engines produce still more trees, including layer trees and widget trees.

The pipeline for our toy browser engine will look something like this, after we complete a few more stages:

In my implementation, each node in the DOM tree has exactly one node in the style tree. But in a more complicated pipeline stage, several input nodes could collapse into a single output node. Or one input node might expand into several output nodes, or be skipped completely. For example, the style tree could exclude elements whose display property is set to 'none'. (Instead this will happen in the layout stage, because my code turned out a bit simpler that way.)

Selector Matching

The first step in building the style tree is selector matching. This will be very easy, since my CSS parser supports only simple selectors. You can tell whether a simple selector matches an element just by looking at the element itself. Matching compound selectors would require traversing the DOM tree to look at the element’s siblings, parents, etc.

fn matches(elem: &ElementData, selector: &Selector) -> bool { match *selector { Simple(ref simple_selector) => matches_simple_selector(elem, simple_selector) } }

To help, we’ll add some convenient ID and class accessors to our DOM element type. The class attribute can contain multiple class names separated by spaces, which we return in a hash table.

impl ElementData { fn get_attribute<'a>(&'a self, key: &str) -> Option<&'a String> { self.attributes.find_equiv(&key) } fn id<'a>(&'a self) -> Option<&'a String> { self.get_attribute("id") } fn classes<'a>(&'a self) -> HashSet<&'a str> { match self.get_attribute("class") { Some(classlist) => classlist.as_slice().split(' ').collect(), None => HashSet::new() } } }

Rust note: Those types look a bit hairy because I’m passing around pointers rather than copying values. This code should be a lot more concise in languages that are not so concerned with this distinction.

To test whether a simple selector matches an element, just look at each selector component, and return false if the element doesn’t have a matching class, ID, or tag name.

fn matches_simple_selector(elem: &ElementData, selector: &SimpleSelector) -> bool { // Check type selector if selector.tag_name.iter().any(|name| elem.tag_name != *name) { return false; } // Check ID selector if selector.id.iter().any(|id| elem.id() != Some(id)) { return false; } // Check class selectors let elem_classes = elem.classes(); if selector.class.iter().any(|class| !elem_classes.contains(&class.as_slice())) { return false; } // We didn't find any non-matching selector components. return true; }

Rust note: This function uses the any method, which returns true if an iterator contains an element that passes the provided test. This is the same as the any function in Python (or Haskell), or the some method in JavaScript.

When comparing two rules that match the same element, we need to use the highest-specificity selector from each match. Because our CSS parser stores the selectors from most- to least-specific, we can stop as soon as we find a matching one, and return its specificity along with a pointer to the rule.

/// A single CSS rule and the specificity of its most specific matching selector. type MatchedRule<'a> = (Specificity, &'a Rule); /// If `rule` matches `elem`, return a `MatchedRule`. Otherwise return `None`. fn match_rule<'a>(elem: &ElementData, rule: &'a Rule) -> Option<MatchedRule<'a>> { // Find the first (highest-specificity) matching selector. rule.selectors.iter().find(|selector| matches(elem, *selector)) .map(|selector| (selector.specificity(), rule)) }

To find all the rules that match an element we call filter_map, which does a linear scan through the style sheet, checking every rule and throwing out ones that don’t match. A real browser engine would speed this up by storing the rules in multiple hash tables based on tag name, id, class, etc.

/// Find all CSS rules that match the given element. fn matching_rules<'a>(elem: &ElementData, stylesheet: &'a Stylesheet) -> Vec<MatchedRule<'a>> { stylesheet.rules.iter().filter_map(|rule| match_rule(elem, rule)).collect() }

Once we have the matching rules, we can find the specified values for the element. We insert each rule’s property values into a HashMap. We sort the matches by specificity, so the higher specificity rules are processed after the lower ones and can overwrite their values in the HashMap.

/// Apply styles to a single element, returning the specified values. fn specified_values(elem: &ElementData, stylesheet: &Stylesheet) -> PropertyMap { let mut values = HashMap::new(); let mut rules = matching_rules(elem, stylesheet); // Go through the rules from lowest to highest specificity. rules.sort_by(|&(a, _), &(b, _)| a.cmp(&b)); for &(_, rule) in rules.iter() { for declaration in rule.declarations.iter() { values.insert(declaration.name.clone(), declaration.value.clone()); } } return values; }

Now we have everything we need to walk through the DOM tree and build the style tree. Note that selector matching works only on elements, so the specified values for a text node are just an empty map.

/// Apply a stylesheet to an entire DOM tree, returning a StyledNode tree. pub fn style_tree<'a>(root: &'a Node, stylesheet: &'a Stylesheet) -> StyledNode<'a> { StyledNode { node: root, specified_values: match root.node_type { Element(ref elem) => specified_values(elem, stylesheet), Text(_) => HashMap::new() }, children: root.children.iter().map(|child| style_tree(child, stylesheet)).collect(), } }

That’s all of robinson’s code for building the style tree. Next I’ll talk about some glaring omissions.

The Cascade

Style sheets provided by the author of a web page are called author style sheets. In addition to these, browsers also provide default styles via user agent style sheets. And they may allow users to add custom styles through user style sheets (like Gecko’s userContent.css).

The cascade defines which of these three “origins” takes precedence over another. There are six levels to the cascade: one for each origin’s “normal” declarations, plus one for each origin’s !important declarations.

Robinson’s style code does not implement the cascade; it takes only a single style sheet. The lack of a default style sheet means that HTML elements will not have any of the default styles you might expect. For example, the <head> element’s contents will not be hidden unless you explicitly add this rule to your style sheet:

head { display: none; }

Implementing the cascade should by fairly easy: Just track the origin of each rule, and sort declarations by origin and importance in addition to specificity. A simplified, two-level cascade should be enough to support the most common cases: normal user agent styles and normal author styles.

Computed Values

In addition to the “specified values” mentioned above, CSS defines initial, computed, used, and actual values.

Initial values are defaults for properties that aren’t specified in the cascade. Computed values are based on specified values, but may have some property-specific normalization rules applied.

Implementing these correctly requires separate code for each property, based on its definition in the CSS specs. This work is necessary for a real-world browser engine, but I’m hoping to avoid it in this toy project. In later stages, code that uses these values will (sort of) simulate initial values by using a default when the specified value is missing.

Used values and actual values are calculated during and after layout, which I’ll cover in future articles.

Inheritance

If text nodes can’t match selectors, how do they get colors and fonts and other styles? The answer is inheritance.

When a property is inherited, any node without a cascaded value will receive its parent’s value for that property. Some properties, like 'color', are inherited by default; others only if the cascade specifies the special value 'inherit'.

My code does not support inheritance. To implement it, you could pass the parent’s style data into the specified_values function, and use a hard-coded lookup table to decide which properties should be inherited.

Style Attributes

Any HTML element can include a style attribute containing a list of CSS declarations. There are no selectors, because these declarations automatically apply only to the element itself.

<span style="color: red; background: yellow;">

If you want to support the style attribute, make the specified_values function check for the attribute. If the attribute is present, pass it to parse_declarations from the CSS parser. Apply the resulting declarations after the normal author declarations, since the attribute is more specific than any CSS selector.

Exercises

In addition to writing your own selector matching and value assignment code, for further exercise you can implement one or more of the missing pieces discussed above, in your own project or a fork of robinson:

  1. Cascading
  2. Initial and/or computed values
  3. Inheritance
  4. The style attribute

Also, if you extended the CSS parser from Part 3 to include compound selectors, you can now implement matching for those compound selectors.

To Be Continued…

Part 5 will introduce the layout module. I haven’t finished the code for this yet, so there will be another delay before I can start writing the article. I plan to split layout into at least two articles (one for block layout and one for inline layout, probably).

In the meantime, I’d love to see anything you’ve created based on these articles or exercises. If your code is online somewhere, feel free to add a link to the comments below! So far I have seen Martin Tomasi’s Java implementation and Pohl Longsine’s Swift version.

Categorieën: Mozilla-nl planet

Matt Brubeck: Let's build a browser engine! Part 4: Style

Mozilla planet - zo, 24/08/2014 - 00:44

Welcome back to my series on building your own toy browser engine. If you’re just tuning in, you can find the previous episodes here:

This article will cover what the CSS standard calls assigning property values, or what I call the style module. This module takes DOM nodes and CSS rules as input, and matches them up to determine the value of each CSS property for any given node.

This part doesn’t contain a lot of code, since I’ve left out all the really complicated parts. However, I think what’s left is still quite interesting, and I’ll also explain how some of the missing pieces can be implemented.

The Style Tree

The output of robinson’s style module is something I call the style tree. Each node in this tree includes a pointer to a DOM node, plus its CSS property values:

/// Map from CSS property names to values. type PropertyMap = HashMap<String, Value>; /// A node with associated style data. struct StyledNode<'a> { node: &'a Node, // pointer to a DOM node specified_values: PropertyMap, children: Vec<StyledNode<'a>>, }

What’s with all the 'a stuff? These are lifetime annotations, part of how Rust guarantees that pointers are memory-safe without requiring garbage collection. If you are not working in Rust you can safely ignore them; they aren’t critical to the meaning of this code.

We could add style information directly to the dom::Node struct from Part 1 instead, but I wanted to keep this code out of the earlier “lessons.” This is also a good opportunity to talk about the parallel trees that inhabit most layout engines.

A browser engine module often takes one tree as input, and produces a different but related tree as output. For example, Gecko’s layout code takes a DOM tree and produces a frame tree, which is then used to build a view tree. Blink and WebKit transform the DOM tree into a render tree. Later stages in all these engines produce still more trees, including layer trees and widget trees.

The pipeline for our toy browser engines will look something like this after we complete a few more stages:

In my implementation, each node in the DOM tree produces exactly one node in the style tree. But in a more complicated pipeline stage, several input nodes could collapse into a single output node. Or one input node might expand into several output nodes, or be skipped completely. For example, the style tree could exclude elements whose display property is set to 'none'. (Instead this will happen in the layout stage, because my code turned out a bit simpler that way.)

Selector Matching

The first step in building the style tree is selector matching. This will be very easy, since my CSS parser supports only simple selectors. You can tell whether a simple selector matches an element just by looking at the element itself. Matching compound selectors would require traversing the DOM tree to look at the element’s siblings, parents, etc.

fn matches(elem: &ElementData, selector: &Selector) -> bool { match *selector { Simple(ref simple_selector) => matches_simple_selector(elem, simple_selector) } }

To help, we’ll add some convenient ID and class accessors to our DOM element type. The class attribute can contain multiple class names separated by spaces, which we return in a hash table. [Note: The Rust types below look a bit hairy because we are passing around pointers rather than copying values. This code should be a lot more concise in languages that are not so concerned with this distinction.]

impl ElementData { fn get_attribute<'a>(&'a self, key: &str) -> Option<&'a String> { self.attributes.find_equiv(&key) } fn id<'a>(&'a self) -> Option<&'a String> { self.get_attribute("id") } fn classes<'a>(&'a self) -> HashSet<&'a str> { match self.get_attribute("class") { Some(classlist) => classlist.as_slice().split(' ').collect(), None => HashSet::new() } } }

To test whether a simple selector matches an element, just look at each selector component, and return false if the element doesn’t have a matching class, ID, or tag name.

fn matches_simple_selector(elem: &ElementData, selector: &SimpleSelector) -> bool { // Check type selector if selector.tag_name.iter().any(|name| elem.tag_name != *name) { return false; } // Check ID selector if selector.id.iter().any(|id| elem.id() != Some(id)) { return false; } // Check class selectors let elem_classes = elem.classes(); if selector.class.iter().any(|class| !elem_classes.contains(&class.as_slice())) { return false; } // We didn't find any non-matching selector components. return true; }

Rust note: This function uses the any method, which returns true if an iterator contains an element that passes the provided test. This is the same as the any function in Python (or Haskell), or the some method in JavaScript.

When comparing two rules that match the same element, we need to use the highest-specificity selector from each match. Because our CSS parser stores the selectors from most- to least-specific, we can stop as soon as we find a matching one, and return its specificity along with a pointer to the rule.

/// A single CSS rule and the specificity of its most specific matching selector. type MatchedRule<'a> = (Specificity, &'a Rule); /// If `rule` matches `elem`, return a `MatchedRule`. Otherwise return `None`. fn match_rule<'a>(elem: &ElementData, rule: &'a Rule) -> Option<MatchedRule<'a>> { // Find the first (highest-specificity) matching selector. rule.selectors.iter().find(|selector| matches(elem, *selector)) .map(|selector| (selector.specificity(), rule)) }

To find all the rules that match an element we call filter_map, which does a linear scan through the style sheet, checking every rule and throwing out ones that don’t match. A real browser engine would speed this up by storing the rules in multiple hash tables based on tag name, id, class, etc.

/// Find all CSS rules that match the given element. fn matching_rules<'a>(elem: &ElementData, stylesheet: &'a Stylesheet) -> Vec<MatchedRule<'a>> { stylesheet.rules.iter().filter_map(|rule| match_rule(elem, rule)).collect() }

Once we have the matching rules, we can find the specified values for the element. We insert each rule’s property values into a HashMap. We sort the matches by specificity, so the higher specificity rules are processed after the lower ones and can overwrite their values in the HashMap.

/// Apply styles to a single element, returning the specified styles. fn specified_values(elem: &ElementData, stylesheet: &Stylesheet) -> PropertyMap { let mut values = HashMap::new(); let mut rules = matching_rules(elem, stylesheet); // Go through the rules from lowest to highest specificity. rules.sort_by(|&(a, _), &(b, _)| a.cmp(&b)); for &(_, rule) in rules.iter() { for declaration in rule.declarations.iter() { values.insert(declaration.name.clone(), declaration.value.clone()); } } return values; }

Now we have everything we need to walk through the DOM tree and build the style tree. Note that selector matching works only on elements, so the specified values for a text node are just an empty map.

/// Apply a stylesheet to an entire DOM tree, returning a StyledNode tree. pub fn style_tree<'a>(root: &'a Node, stylesheet: &'a Stylesheet) -> StyledNode<'a> { StyledNode { node: root, specified_values: match root.node_type { Element(ref elem) => specified_values(elem, stylesheet), Text(_) => HashMap::new() }, children: root.children.iter().map(|child| style_tree(child, stylesheet)).collect(), } }

That’s all of robinson’s code for building the style tree. Next I’ll talk about some glaring omissions.

The Cascade

Style sheets provided by the author of a web page are called author style sheets. In addition to these, browsers also provide default styles via user agent style sheets. And they may allow users to add custom styles through user style sheets (like Gecko’s userContent.css).

The cascade defines which of these three “origins” takes precedence over another. There are six levels to the cascade: one for each origin’s “normal” declarations, plus one for each origin’s !important declarations.

Robinson’s style code does not implement the cascade; it uses only a single style sheet. The lack of a default style sheet means that HTML elements will not have any of the default styles you might expect. For example, the <head> element’s contents will not be hidden unless you explicitly add this rule to your style sheet:

head { display: none; }

Implementing the cascade should by fairly easy: Just track the origin of each rule, and sort declarations by origin and importance in addition to specificity. A simplified, two-level cascade should be enough to support the most common cases: normal user agent styles and normal author styles.

Computed Values

In addition to the “specified values” mentioned above, CSS defines initial, computed, used, and actual values.

Initial values are defaults for properties that aren’t specified in the cascade. Computed values are based on specified values, but may have some property-specific normalization rules applied.

Implementing these correctly requires separate code for each property, based on its definition in the CSS specs. This work is necessary for a real-world browser engine, but I’m hoping to avoid it in this toy project. In later stages, code that uses these values will (sort of) simulate initial values by using a default when the specified value is missing.

Used values and actual values are calculated during and after layout, which I’ll cover in future articles.

Inheritance

If text nodes can’t match selectors, how do they get colors and fonts and other styles? Through the magic of inheritance.

When a property is inherited, any node without a cascaded value will receive its parent’s value for that property. Some properties, like 'color', are inherited by default; others only if the cascade specifies the special value 'inherit'.

My code does not support inheritance. To implement it, you could pass the parent’s style data into the specified_values function, and use a hard-coded lookup table to decide which properties should be inherited.

Style Attributes

Any HTML element can include a style attribute containing a list of CSS declarations. There are no selectors, because these declarations automatically apply only to the element itself.

<span style="color: red; background: yellow;">

If you want to support the style attribute, make the specified_values function check for the attribute. If the attribute is present, pass it to parse_declarations from the CSS parser. Apply the resulting declarations after the normal author declarations, since the attribute is more specific than any CSS selector.

Exercises

In addition to writing your own selector matching and value assignment code, for further exercise you can implement one or more of the missing pieces discussed above, in your own project or a fork of robinson:

  1. Cascading
  2. Initial and/or computed values
  3. Inheritance
  4. The style attribute

Also, if you extended the CSS parser from Part 3 to include compound selectors, you can now implement matching for those compound selectors.

To be continued…

Part 5 will introduce the layout module. I haven’t finished the code for this yet, so there will be another short before I can start writing the article. I plan to split layout into at least two articles (one for block layout and one for inline layout, probably).

In the meantime, I’d love to see anything you’ve created based on these articles or exercises. If your code is online somewhere, feel free to add a link to the comments below! So far I have seen Martin Tomasi’s Java implementation and Pohl Longsine’s Swift version.

Categorieën: Mozilla-nl planet

Mozilla brengt Firefox OS smartphone uit in India voor 29 euro - Technieuws

Nieuws verzameld via Google - za, 23/08/2014 - 18:46

Mozilla brengt Firefox OS smartphone uit in India voor 29 euro
Technieuws
Mozilla heeft in samenwerking met het Indiase Spice Retail een nieuwe smartphone op de markt uitgebracht met het Firefox OS, de smartphone krijgt een zeer aantrekkelijke adviesprijs aangezien de Firefox OS smartphone verkocht zal worden voor slechts ...

en meer »
Categorieën: Mozilla-nl planet

Kaustav Das Modak: Connect Firefox OS Spreadtrum devices through adb

Mozilla planet - za, 23/08/2014 - 13:09
The ultra low-cost Firefox OS devices to be launched in India are built on Spreadtrum chipsets. Here are the quick steps for people running Linux or OS X to connect their Spreadtrum devices through adb: Make sure if the device is detected Connect the device through a USB cable. Enable Remote Debugging on the device […]
Categorieën: Mozilla-nl planet

Mozilla brengt Firefox OS-smartphone in India uit voor 29 euro - Tweakers

Nieuws verzameld via Google - za, 23/08/2014 - 12:10

Mozilla brengt Firefox OS-smartphone in India uit voor 29 euro
Tweakers
Mozilla heeft samen met het Indiase Spice Retail een smartphone uitgebracht met Firefox OS die omgerekend ongeveer 29 euro moet kosten. Het apparaat beschikt over een 3,5"-scherm en een niet nader gespecificeerde 1GHz-processor, maar moet het ...

Categorieën: Mozilla-nl planet

Google Chrome vs Mozilla Firefox: The most downloaded browser for August 2014 - StreetWise Tech

Nieuws verzameld via Google - za, 23/08/2014 - 06:55

StreetWise Tech

Google Chrome vs Mozilla Firefox: The most downloaded browser for August 2014
StreetWise Tech
When Mozilla was introduced, people were lured to its revamped look. When the Chrome was introduced, people undoubtedly fell for its smart and clean look that gave the whole new meaning on how an internet browser should look like. The clean interface ...

en meer »
Categorieën: Mozilla-nl planet

Maja Frydrychowicz: Snapshots from my OPW Internship with Mozilla QA

Mozilla planet - za, 23/08/2014 - 06:00

Throughout my OPW1 internship with Mozilla QA2 I've been keeping an informal log in outline form3. In it, I briefly describe what I accomplish (or fail to accomplish) each day, problems I encounter, who I talk to about them, which meetings I attend, what I read, useful tricks I learn, etc. So far, I have about 60-days worth of these tiny log entries about Mozilla. Here's what they look like:

Checkvist Mozilla Log Screenshot

Day-to-day, the log helps me answer questions like "How did I solve this weird configuration problem three weeks ago?" or "What should I ask about at the next team meeting?" Writing also generally helps me think through a task, and the log is a quick and effective outlet for that. The other major benefit is that I can take a step back and see the overall progress of my projects.

So, what's it like being an intern with Mozilla QA?

I'm so glad you asked! First, some context.

  • OPW interns work remotely.
  • The internship position I applied for is called "Bug Wrangler", which refers to tasks like reproducing and triaging incoming Firefox bugs, but I've actually (mostly) been doing Django web development.

To future interns: as in my case, there can be some flexibility about your internship activities, and during your application process, you'll narrow down what you will work on. The mentor I applied to offered a Django project as an option under the Bug Wrangler umbrella, and that was more in line with my interests and experience than bug triage, so that's what I chose to focus on.

Based on my handy log, I'll answer a slightly more specific question:

"What did Maja do during a typical week while working on a Django project for Mozilla QA?"

Routines

Often, I start my day by skimming my latest "bug mail" (updates from Bugzilla) and checking my Bugzilla dashboard to see if I need to follow up on anything immediately.

The other regular occurrence is about 2 hours of video meetings per week. I meet with my mentor once a week to discuss my general progress and my post-internship plans. I lurk at one QA team meeting almost every week, where I mostly didn't have enough context to understand much. My mentor filled me in on some things and my understanding gradually improved. There are also two regular meetings for One and Done, the project I'm contributing to: a weekly technical meeting to discuss the design of new features, and a biweekly check-in meeting with project managers, developers and a few key users.

Week 3

The early weeks of the internship involved a lot of reading and trying things out, of course. At this point, I was finishing up the official Django tutorial as well as responding to some administrative requests about the internship.

Just for fun, I used vim throughout my Django learnings to rediscover some handy vim commands. I also spent time on applying the tutorial concepts to the One and Done source code, and thus discovered what other parts of Django I need to become familiar with, like generic class-based views.

I gradually became more familiar with how the One and Done code is structured by exploring its models and its URLconf, and populating my local database with example data.

Week 5

At this point, I was just about finished with my first substantial pull request to One and Done. My changes broke some unit tests, which caused me to discover that some of our test data was using the wrong data type: a regular Python dictionary instead of a Django QueryDict. Cool.

I actually spent a bunch of time getting the unit tests to run in my dev environment, which is on a Linux virtual machine. My local copy of the project is stored in a directory that is shared between my Linux guest OS and Windows host OS, which happens to rely on file permissions that the nose testing library doesn't like. In the end, I chose to have a clone of the project in a non-shared directory that I used just for running unit tests.

My work log also describes in detail how unintended changes to my development branch in git turned my Github pull request into a giant, unreadable mess. Aaah! (Be careful what you branch from and what you merge with, friends.) I had to close my original pull request and make a new, clean one, which was fairly embarrassing. I remember now that on that day my friend and I were co-working in my apartment to battle the loneliness of our remote jobs, and she generously listened to me venting my misery about the incident. :) In retrospect, I learned a lot about git.

Later that week, that same pull request got merged and I started investigating a bug I ran into in one of the libraries our project relies on. This involved asking some questions on IRC.

All around, a good week.

Week 9

First I finished up a couple of things I had started earlier:

I also contributed my first few code reviews: the week before I missed an issue that someone else caught (doh!), but this week I found something that needed to be fixed (yay!). This was cool because I found the problem by simply taking the time to understand code that was mostly mysterious to me. Bonus: I learned a bit about Mock and patch.

By the end of the week, I was focused on sketching out the functionality and implementation of a new One and Done feature. I enjoyed working with the project managers to define the feature requirements. Figuring out how to implement them required a few more weeks of research and learning on my part, but it all worked out in the end.

This is why I like work logs!

Reviewing my work log to write this article was eye-opening for me, especially due the perspective it offers of the ups and downs I experienced during my internship. On some days, I felt quite frustrated, stuck, discouraged, and all that bad stuff. So, I like how the log shows that feeling crappy for a few days here and there totally doesn't matter overall. I learned a lot in the past couple of months and it's incredibly satisfying to see that itemized in one big list.

  1. Outreach Program for Women 

  2. Quality Assurance 

  3. I write the log using Checkvist. It's fantastic. I did the same while at Hacker School. 

Categorieën: Mozilla-nl planet

Clint Talbert: The Odyssey of Per-Push, On-Phone Firefox OS Automation

Mozilla planet - za, 23/08/2014 - 01:19

When we started automating tests for Firefox OS, we knew that we could do a lot with automated testing on phone emulators–we could run in a very similar environment to the phone, using the same low level instruction set, even do some basic operations like SMS between two emulator processes. Best of all, we could run those in the cloud, at massive scale.

But, we also knew that emulator based automation wasn’t ever going to be as complete as actually testing on real phones. For instance, you can’t simulate many basic smart phone operations: calling a number, going to voice-mail, toggling airplane mode, taking a picture, etc. So, we started trying to get phones running in automation very early with Firefox OS, almost two years ago now.

We had some of our very early Unagi phones up and running on a desk in our office. That eventually grew to a second generation of Hamachi based phones. There were a couple of core scalability problems with both of these solutions:

  1. No reliable way to power-cycle a phone without a human walking up to it, pulling out the battery and putting it back in
  2. At the time these were pre-production phones (hence the code names), and were hard to get in bulk from partners. So, we did what we could with about 10 phones that ran smoketests, correctness tests, and performance tests.
  3. All of the automation jobs and results had to be tracked by hand. And status had to be emailed to developers — there was no way to get these reporting to our main automation dashboard, TBPL.
  4. Because we couldn’t report status to TBPL, maintaining the system and filing bugs when tests failed had to be done entirely by a dedicated set of 4 QA folk–not a scalable option, to say the least.

Because of points 1 and 2, we were unable to truly scale the number of devices. We only had one person in Mountain View, and what we had thought of as a part time job of pulling phone batteries soon became his full time job. We needed a better solution to increase the number of devices while we worked in parallel to create a better dashboard for our automation that would allow a system like this to easily plug in and report its results.

The Flame reference device solved that first problem. Now, we had a phone whose hardware we could depend on, and Jon Hylands was able to create a custom battery harnesses for it so that we could instruct our scripts to automatically detect dead phones and remotely power cycle them (and in the future, monitor power consumption). Because we (Mozilla) commissioned the Flame phone ourselves, there were no partner related issues with obtaining pre-production devices–we could easily get as many as we needed. After doing some math to understand our capacity needs, we got 40 phones to seed our prototype lab to support per-push automation.

As I mentioned, we were solving the dashboard problem in parallel, and that has now been deployed in the form of Treeherder, which will be the replacement for TBPL. That solves point 3. All that now remains is point 4. We have been hard at work on crafting a unified harness to run the Gaia Javascript tests on device which will also allow us to run the older, existing python tests as well until they can be converted. This gives us the most flexibility and allows us to take advantage of all the automation goodies in the existing python harness–like crash detection, JSON structured logging, etc. Once it is complete, we will be able to run a smaller set of the same tests the developers run locally per each push to b2g-inbound on these Flame devices in our lab. This means that when something breaks, it will break tests that are well known, in a well understood environment, and we can work alongside the developers to understand what broke and why. By enabling the developers and QA to work alongside one another, we eliminate the scaling problem in point 4.

It’s been a very long road to get from zero to where we are today. You can see the early pictures of the “phones on a desk” rack and pictures of the first 20 Flames from Stephen’s presentation he gave earlier this month.

A number of teams helped get us to this point, and it could not have been done without the cooperation among them: the A*Team, the Firefox OS Performance team, the QA team, and the Gaia team all helped get us to where we are today. You can see the per-push tests showing up on the Treeherder Staging site as we ensure we can meet the stability and load requirements necessary for running in production.

Last week, James Lal and his new team inherited this project. They are working hard to push the last pieces to completion as well as expanding it even further. And so, even though Firefox OS has had real phone automation for years, that system is now coming into its own. The real-phone automation will finally be extremely visible and easily actionable for all developers, which is a huge win for everyone involved.

Categorieën: Mozilla-nl planet

Eric Shepherd: The Sheppy Report: August 22, 2014

Mozilla planet - za, 23/08/2014 - 00:16

This week looks slower than usual when you look at this list, but the week involved a lot of research.

What I did this week
  • Reviewed and made (very) minor tweaks to Chris Mills’s doc plan for the Gaia web components and QA documentation.
  • Created an initial stub of a page for the canvas documentation plan.
  • Spent the weekend and a bit of Monday getting my broken server, including this blog, back up and running after a not-entirely-successful (at first) upgrade of the server from OS X 10.6.8 Server to 10.9.4. But most things are working now. I’ll get the rest fixed up over the next few days.
  • Pursued the MDN inbox project, trying to wrap it up.
    • Asked for feedback on the current state of things.
    • Added a subtle background color to the background of pages in the Inbox.
  • Started discussions on dev-mdc and staff mailing list about the documentation process; we’re going to get this thing straightened up and organized.
  • Filed bug 1056026 proposing that the Firefox_for_developers macro be updated to list both newer and older versions of Firefox.
  • Redirected some obsolete pages to their newer, replacement, content in the MDN meta-documentation.
  • Created a Hacker News account and upvoted a post about Hacks on canuckistani’s request.
  • Updated the MDN Administration Guide.
  • Installed various packages and add-ons on my Mac and server in preparation for testing WebRTC code.
  • Forked several WebRTC projects from GitHub to experiment with.
  • Found (after a surprisingly length search) a micro-USB cable so I could charge and update my Geeksphone Peak to Firefox OS 2.0′s latest nightly build.
  • Re-established contact with Piotr at CKSource about continuing work to get our editor updated and improved.
  • Removed a mess of junk from a page in pt-BR; looks like someone used an editor that added a bunch of extra <span>s.
  • Successfully tested a WebRTC connection between my Firefox OS phone and my iMac, using my Mac mini as server. Now I should be ready to start writing code of my own, now that I know it all works!
  • Filed bug 1057546: we should IMHO strip HTML tags that aren’t part of a string from within a macro call; this would prevent unfortunate errors.
  • Filed bug 1057547 proposing that the editor be updated to detect uses of the style attribute and of undefined classes, and present warnings to the user when they do so.
  • Fixed a page that was incorrectly translated in place, and emailed the contributor a reminder to be careful in the future.
Meetings attended this week Monday
  • MDN dev team meeting on security and improved processes to prevent problems like the email address disclosure we just had happen.
  • MDN developer triage meeting.
Tuesday
  • Developer Engagement weekly meeting.
  • 1:1 with Jean-Yves Perrier.
Wednesday
  • 1:1 with Ali.
 Thursday
  • Writers’ staff meeting.
Friday
  • #mdndev weekly review meeting.
  • MDN bug swat meeting.
  • Web API documentation meeting.

So… it was a wildly varied day today. But I got a lot of interesting things done.

Categorieën: Mozilla-nl planet

Gervase Markham: HSBC Weakens Their Internet Banking Security

Mozilla planet - vr, 22/08/2014 - 19:30

From a recent email about “changes to your terms and conditions”. (“Secure Key” is their dedicated keyfob 2-factor solution; it’s currently required both to log in and to pay a new payee. It’s rather well done.)

These changes will also enable us to introduce some enhancements to our service over the coming months. You’ll still have access to the full Internet Banking service by logging on with your Secure Key, but in addition, you’ll also be able log in to a limited service when you don’t use your Secure Key – you’ll simply need to verify your identity by providing other security information we request. We’ll contact you again to let you know when this new feature becomes available to you.

Full details of all the changes can be found below which you should read carefully. If you choose not to accept the changes, you have the right to ask us to stop providing you with the [Personal Internet Banking] service, before they come into effect. If we don’t hear from you, we’ll assume that you accept the changes.

Translation: we are lowering the security we use to protect your account information from unauthorised viewing and, as long as you still want to be able to access your account online at all, there’s absolutely nothing you can do about it.

Categorieën: Mozilla-nl planet

Amy Tsay: What Healthy Relationships Teach Us About Healthy Communities

Mozilla planet - vr, 22/08/2014 - 18:42

In organizations where communities form (whether around a product, mission, or otherwise), there is often a sense of perplexity or trepidation around how to engage with them. What is the proper way to talk to community members? How do I work with them, and what can I do to keep the community healthy and growing? The good news is, if you know what it takes to have a healthy personal relationship, you already know how to build a healthy community.

Prioritize them

In a good relationship, we prioritize the other person. At Mozilla, the QA team makes it a point to respond to volunteer contributors within a day or two. A lack of response is one of the top reasons why people leave online communities, so it’s important not to keep them hanging. It doesn’t feel good to volunteer your time on a project only to be left waiting when you ask questions or request feedback, just as it would if your partner doesn’t return your phone calls.

Be authentic

Authenticity and honesty in a relationship are the building blocks of trust. If you make a mistake, admit it and set it right. Your tone and word choice will reflect your state of mind, so be aware of it when composing a message. When you come from a place of caring and desire to do what’s right for the community, instead of a place of fear or insecurity, your words and actions will foster trust.

Be appreciative

Strong relationships are formed when both parties value and appreciate each other. It’s a great feeling when you take out the trash or do the dishes, and it’s noticed and praised. Make it a ritual to say thanks to community members who make an impact, preferably on the spot, and publicly if possible and appropriate.

Be their champion

Be prepared to go to bat for the community. I was once in a relationship with a partner who would not defend me in situations where I was being mistreated; it didn’t end well. It feels nice to be advocated for, to be championed, and it creates a strong foundation. When you discover a roadblock or grievance, take the time to investigate and talk to the people who can make it right. The community will feel heard and valued.

Empathize

The processes and programs that support community participation require an understanding of motivation. To understand motivation, you have to be able to empathize. Everyone views the world from their own unique perspectives, so it’s important to try and understand them, even if they’re different from your own. 

Set expectations

Understand your organization’s limitations, as well as your own, and communicate them. If your partner expects you to be home at a certain time and you don’t show up, the anger you encounter likely has more to do with not being told you’re going to be late, than the lateness itself.

Guidelines and rules for participation are important components as well. I once featured content from a community member and was met by an angry online mob, because although the content was great, the member hadn’t reached a certain level of status. The guidelines didn’t cover eligibility for featuring, and up until then only longer-term participants had been featured, so the community’s expectations were not met.

Not apples to apples

I would never want to get anyone in trouble by suggesting they treat their community members exactly the same as their partners. Answering emails from anyone while having dinner with your loved one is not advised. The take-away is there isn’t any mystery to interacting with a community. Many of the ingredients for a healthy community are ones found in healthy relationships, and most reassuring of all, we already know what they are.


Categorieën: Mozilla-nl planet

Robert Kaiser: Mirror, Mirror: Trek Convention and FLOSS Conferences

Mozilla planet - vr, 22/08/2014 - 17:09
It's been a while since I did any blogging, but that doesn't mean I haven't been doing anything - on the contrary, I have been too busy to blog, basically. We had a few Firefox releases where I scrambled until the last day of the beta phase to make sure we keep our crash rates as low as our users probably expect by now, I did some prototyping work on QA dashboards (with already-helpful results and more to come) and helped in other process improvements on the Firefox Quality team, worked with different teams to improve stability of our blocklist ping "ADI" data, and finally even was at a QA work week and a vacation in the US. So plenty of stuff done, and I hope to get to blog about at least some pieces of that in the next weeks and months.

That said, one major part of my recent vacation was the Star Trek Las Vegas Convention, which I attended the second time after last year. Since back then, I wanted to blog about some interesting parallels I found between that event (I can't compare to other conventions, as I've never been to any of those) and some Free, Libre and Open Source Software (FLOSS) conferences I've been to, most notably FOSDEM, but also the larger Mozilla events.
Of course, there's the big events in the big rooms and the official schedule - on the conferences it's the keynotes and presentations of developers about what's new in their software, what they learned or where we should go, on the convention it's actors and other guests talking about their experiences, what's new in their lives, and entertaining the crowd - both with questions from the audience. Of course, the topics are wildly different. And there's booths at both, also quite a bit different, as it's autograph and sales booths on one side, and mainly info booths on the other, though there are geeky T-shirts sold at both types of events. ;-)

The largest parallels I found, though, are about the mass of people that are there:
For one thing, the "hallway track" of talking to and meeting other attendees is definitely a main attraction and big piece of the life of the events on both "sides" there. Old friendships are being revived, new found, and the somewhat geeky commonalities are being celebrated and lead to tons of fun and involved conversations - not just the old fun bickering between vi and emacs or Kirk and Picard fans (or different desktop environments / different series and movies). :)
For the other, I learned that both types of events are in the end more about the "regular" attendees than the speakers, even if the latter end up being featured at both. Especially the recurring attendees go there because they want to meet and interact with all the other people going there, with the official schedule being the icing on the cake, really. Not that it would be unimportant or unneeded, but it's not as much the main attraction as people on the outside, and possibly even the organizers, might think. Also, going there means you do for a few days not have to hide your "geekiness" from your surroundings and can actively show and celebrate it. There's also some amount of a "do good" atmosphere in both those communities.
And both events, esp. the Trek and Mozilla ones, tend to have a very inclusive atmosphere of embracing everyone else, no matter what their physical appearance, gender or other social components. And actually, given how deeply that inclusive spirit has been anchored into the Star Trek productions by Gene Roddenberry himself, this might even run deeper in the fans there than it is in the FLOSS world. Notably, I saw a much larger amount of women and of colored people on the Star Trek Conventions than I see on FLOSS conferences - my guess is that at least a third of the Trek fans in Las Vegas were female, for example. I guess we need some more role models in they style of Nichelle Nichols and others in the FLOSS scene.

All in all, there's a lot of similarities and still quite some differences, but quite a twist on an alternate universe like it's depicted in Mirror, Mirror and other episodes - here it's a different crowd with a similar spirit and not the same people with different mindsets and behaviors.
As a very social person, I love attending and immersing myself in both types of events, and I somewhat wonder if and how we should have some more cross-pollination between those communities.
I for sure will be seen on more FLOSS and Mozilla events as well as more Star Trek conventions! :)
Categorieën: Mozilla-nl planet

Robert Kaiser: Mirror, Mirror: Trek Convention and FLOSS Conferences

Thunderbird - vr, 22/08/2014 - 17:09
It's been a while since I did any blogging, but that doesn't mean I haven't been doing anything - on the contrary, I have been too busy to blog, basically. We had a few Firefox releases where I scrambled until the last day of the beta phase to make sure we keep our crash rates as low as our users probably expect by now, I did some prototyping work on QA dashboards (with already-helpful results and more to come) and helped in other process improvements on the Firefox Quality team, worked with different teams to improve stability of our blocklist ping "ADI" data, and finally even was at a QA work week and a vacation in the US. So plenty of stuff done, and I hope to get to blog about at least some pieces of that in the next weeks and months.

That said, one major part of my recent vacation was the Star Trek Las Vegas Convention, which I attended the second time after last year. Since back then, I wanted to blog about some interesting parallels I found between that event (I can't compare to other conventions, as I've never been to any of those) and some Free, Libre and Open Source Software (FLOSS) conferences I've been to, most notably FOSDEM, but also the larger Mozilla events.
Of course, there's the big events in the big rooms and the official schedule - on the conferences it's the keynotes and presentations of developers about what's new in their software, what they learned or where we should go, on the convention it's actors and other guests talking about their experiences, what's new in their lives, and entertaining the crowd - both with questions from the audience. Of course, the topics are wildly different. And there's booths at both, also quite a bit different, as it's autograph and sales booths on one side, and mainly info booths on the other, though there are geeky T-shirts sold at both types of events. ;-)

The largest parallels I found, though, are about the mass of people that are there:
For one thing, the "hallway track" of talking to and meeting other attendees is definitely a main attraction and big piece of the life of the events on both "sides" there. Old friendships are being revived, new found, and the somewhat geeky commonalities are being celebrated and lead to tons of fun and involved conversations - not just the old fun bickering between vi and emacs or Kirk and Picard fans (or different desktop environments / different series and movies). :)
For the other, I learned that both types of events are in the end more about the "regular" attendees than the speakers, even if the latter end up being featured at both. Especially the recurring attendees go there because they want to meet and interact with all the other people going there, with the official schedule being the icing on the cake, really. Not that it would be unimportant or unneeded, but it's not as much the main attraction as people on the outside, and possibly even the organizers, might think. Also, going there means you do for a few days not have to hide your "geekiness" from your surroundings and can actively show and celebrate it. There's also some amount of a "do good" atmosphere in both those communities.
And both events, esp. the Trek and Mozilla ones, tend to have a very inclusive atmosphere of embracing everyone else, no matter what their physical appearance, gender or other social components. And actually, given how deeply that inclusive spirit has been anchored into the Star Trek productions by Gene Roddenberry himself, this might even run deeper in the fans there than it is in the FLOSS world. Notably, I saw a much larger amount of women and of colored people on the Star Trek Conventions than I see on FLOSS conferences - my guess is that at least a third of the Trek fans in Las Vegas were female, for example. I guess we need some more role models in they style of Nichelle Nichols and others in the FLOSS scene.

All in all, there's a lot of similarities and still quite some differences, but quite a twist on an alternate universe like it's depicted in Mirror, Mirror and other episodes - here it's a different crowd with a similar spirit and not the same people with different mindsets and behaviors.
As a very social person, I love attending and immersing myself in both types of events, and I somewhat wonder if and how we should have some more cross-pollination between those communities.
I for sure will be seen on more FLOSS and Mozilla events as well as more Star Trek conventions! :)
Categorieën: Mozilla-nl planet

Pagina's