Devtools Resolved Bugs: 2013-09-17 – 2013-09-24

ID Summary
911678 Inspector – inline style rules do not populate the CSSRul…
915910 [markup view] UI updates following refactor in Bug 855523
916995 browser_webconsole_view_source.js just assumes the event …
905226 Response tab in Network inspector shows base64 encoded re…
917706 Browser Debugger shouldn’t require a restart / new window
917844 Add a keyboard accesskey to the Browser Debugger menuitem
914405 long pauses due to non-incremental GC for DEBUG_MODE_GC
902421 |tools srcdir| breaks Firefox startup
914403 B2G highlighter remains visible after closing toolbox
915372 Inspector can only be opened once per app per connection
918588 Event Emitter: Can’t call off after once
908878 Intermittent browser_webconsole_bug_595350_multiple_windo…
916997 All lines are combined to one line. when copying multiple…
918210 Intermittent browser_webconsole_bug_613642_maintain_scrol…
911748 Add default color dropdown to devtools options panel
916451 browser_cmd_addon.js | html output for addon disable Test…
917389 Re-enable browser_css_color.js on Linux 32 bit tests
917863 Add XUL context menu back into rule and computed views
918305 Move css-color.js in /toolkit/
913722 Last project remains displayed after deleting
916166 [app manager] Disable the network monitor
835808 Navigate with arrow keys in computed view
911982 Highlight mutated elements in the inspector for some time
913014 Nodes in the inspector’s computed style view are hard to …
916237 Inspector won’t connect to non-OOP B2G apps
917365 “TypeError: this.connection is undefined: UI.startSimulat…
918383 Debug button fails the first time when the app isn’t inst…
853003 Intermittent devtools/debugger/test/browser_dbg_stack-03….
917211 Intermittent browser/devtools/debugger/test/browser_dbg_c…
917498 Intermittent browser_dbg_breakpoints-disabled-reload.js |…
918329 JavaScript Warning: “XUL box for toolbarbutton element co…
832636 ToolboxStyleEditor.tooltip=CSS Stylesheets Editor shouldn…
880930 JS debugger: RootActor needs its own definition of window…
918797 Trying to prettify html irrevocably loses the source unti…
912260 Make Scratchpad use CodeMirror
762761 An option to deobfuscate javascripts in the debugger
914930 load source content via Debugger.Source
916458 Can’t close browser when paused on a breakpoint
919188 help.intro in app-manager.dtd should use ‘i.e.’, not ‘i.e…
907755 add telemetry probe for how long it takes us to display t…
588010 Make clickable output in the WebConsole keyboard accessible
653710 CSS links in WebConsole can be opened using any of mouse’…
917188 Use a more deterministic way to write the browser_webcons…
918240 Can possibly remove “Restart required – restart now?” fro…

Devtools Resolved Bugs, 2013-09-10 – 2013-09-17

ID Summary
893677 [markup view] we should limit the size of an attribute
912543 [rule view] Alignment for warning icon is bad (below line…
913509 [rule view] Papercuts – Inconsistent behavior when modify…
909121 Inspector breaks when navigating backwards
912929 [app manager] UI polish
910830 TypeError: e is undefined: callback@chrome://mochitests/c…
892268 Ctrl/Cmd+0/+/- should change the text size in all the dev…
915556 en-US consistency: use single unicode character … instead…
914753 Remove ‘js2-mode’ references from Emacs graffiti
905103 Use a about URL for the app manager urls (was “devtools:…
912889 [app manager] tooltip and help everywhere
913234 Disconnecting leaves toolboxes open
913717 Fix up placeholder text for hosted app
914729 Use about:app-manager in menu item
915067 wipe sensitive data on system debugging
898559 Add metadata API for add-on globals
762608 Intermittent browser_webconsole_bug_598357_jsterm_output….
864152 Intermittent browser_webconsole_network_panel.js | uncaug…
902385 Intermittent TEST-UNEXPECTED-FAIL | browser/devtools/webc…
902816 Intermittent browser_console_private_browsing.js | This t…
916329 Use proper plural forms in messageRepeats.tooltip
916601 Remove Ctrl +/-/0 zooming shortcuts from web console
789349 Show status messages above the toolbox
915926 Ending a style property edit via click reverts displayed …
912887 [app manager] first run experience
912892 [app manager] simulator launch UI
913945 [app manager] Turn it on!
913947 this.elementStyle is undefined
913949 this.touchEventHandler is undefined
914110 Land Simulator.jsm
915388 Remove “my” from the panels name in index.xul
915740 Integrate adb helper addon into the app manager (UI part)
916597 [app manager] fix locales in help.xhtml
916698 [app manager] 2 connect buttons
855523 Nodes in the markup panel and rule/computed views are har…
912372 [markup view] Empty tags should not be expandable in the …
913641 resource:///modules/devtools/inspector/inspector-panel.js:312″ on all mochitest-bc runs”> “TypeError: this.markup is undefined: InspectorPanel_onNa…
914079 The whole pseudo elements bar should be clickable
893848 Manifest properties aren’t updated when installing apps m…
911785 Allow installing apps local apps from the app manager UI
912213 Webapps getAppActor doesn’t work with non-oop apps
912475 Use promise instead of custom event for install request f…
914239 Enable app debugging on device
914594 [app manager] Services.settings not available
914604 Add test for app resinstall and redirects when installing…
915204 Integrate adb helper addon into the app manager
915226 Start / Stop / Debug shown in project view even when unin…
915096 Remove needless prefs for `devtools.layoutview.*`
900418 Inplace editor should not destroy itself when the focus i…
900430 Should be able to Tab complete and cycle through the comp…
916391 Part of test/browser_dbg_multiple-windows.js seems to be …
760876 Can’t drag-select multiple messages in the Web Console
907278 Firefox24 hangs if debugging onkeydown listener both with…
724224 Console shows incorrect URL when a hash is used
773291 Clicking to the regions/areas to the left and right of th…
706755 want to select code in Web Console
886848 Promisify the debugger frontend
891439 Standardize the sheduleSearch/performSearch methods
901271 Disabled breakpoints are lost on page reload
913060 pretty print should use devtools.editor.tabsize
897050 Prefer displayName instead of name
628019 Web Console cleanup: Use attributes instead of classes fo…
906249 The number of lines in onResume is TOO DAMN HIGH
908283 Don’t attach onStep hooks to frames without scripts
876277 Cleanup the debugger tests
876633 Explanation panel for findbox in debugger breaks textbox …
884436 Sorting by METHOD is really painful
894311 Finding a string with ‘:’ breaks scripts list
874591 Copy/paste from Developer Console does not include “[Mixe…
777428 debug webapps running in desktop webapp runtime
675487 Add tooltip to repeat bubble in Web Console
881219 When filtering sources, hiding items in the sources list …

Fat Arrow Functions in JavaScript

windmills panorama

Hard to beat C# and CoffeeScript here
– Brendan Eich, Arrow Function Syntax Rationale

Since sometime back in the heady days of Firefox 22, Firefox gained the ability to use Fat Arrow Functions in JavaScript. Users of CoffeeScript (or, I guess, C#) will be familiar with the syntax. We’ve been using these in Firefox DevTools code for nearly 6 months.

You can use them today in any shipping Firefox and experiment with them live in the Scratchpad or Console.

They look like this:

let x = (args) => { /* some function gunk */ };

If you want to call it, you can with x();

Fat Arrow functions have a couple of interesting properties. First and probably most useful is that they gain the scope of the environment they’re defined in. You can’t change the value of this by using a call() or bind() function.

Second, Fat Arrow functions don’t have their own prototype or a constructor. (They have the standard Function prototype). This means trying to use the new operator on a fat arrow function results in a TypeError.

That’s all well and good, but what is the practical application of all of this? If you’re a JavaScript programmer, chances are you’ve seen (and done) something like this before:

var listener = node.addEventListener("click", function(event) {
    let _target = event.target;
    this.handleClick(_target);
}.bind(this));

Inside we call a local method called handleClick() with the event’s target property. Nothing too exciting.

With Fat Arrow Functions, that becomes:

var listener = node.addEventListener("click", (event) => {
    let _target = event.target;
    this.handleClick(_target);
});

Look at all that saved typing!

The real benefit of course is that you don’t have to go through the mental hoop-jumping of trying to figure out what scope your function is going to run in (and more often-than-not, you just wanted it to run inside the current scope the function is being defined in anyway).

It just does the right thing.

Some interesting facts about Fat Arrow Functions

You can use them recursively. Because the containing scope closes over the fat arrow function, you can do things like,

let fib = (n) => {
    if (n <= 1) return 1;
    return fib(n - 1) + fib(n - 2);
}

You can’t use fat arrow functions as Generators. Deep continuations are not allowed. Fat Arrow functions are intended to be super light.

The “=>” syntax behaves like a “low-precedence assignment” operation. In

let x = () => { }

the order of operation is from left to right.

Update!

I didn’t include it originally, but some Fat Arrow Enthusiasts encouraged me to mention expression function syntax.

let square = (x) => { return x * x };

is equivalent to:

let square = x => x * x;

For single arguments, you can leave off the ()s. And for function expressions, you can lose the {}s and the return statement. Note that you cannot even use a return statement in this case as it’ll generate a syntax error about a missing semicolon. Don’t even try it!

Yelp and How Not to Run a Community

3505035923_23c034315f_qI used to like Yelp. Despite the occasional rumblings about “extortion” tactics[1, 2, etc], I found it to be useful. I also got a kick out of “playing the game” of checking into locations. It was fun, at least until they changed their frecency algorithm*. There were badges. My friends did it so there was a social aspect to it. I like to write reviews of things so this seemed like a good place to do that.

Then last year I signed up for “Elite”. This gets you a little badge on your page that says you’re one of the frequent users of Yelp. I tend to scan most restaurants’ reviews for the elites as they tend to have a bit more weight compared to the casual users. They’re the worldly ones. The people who’ve been around a bit and know what they like — even if their tastes aren’t always the same as mine.

But you know, writing reviews takes time. I’ve been really busy this year with work and I don’t have the same amount of time for personal writing. And I have this blog that I neglect. You know, excuses.

Then I got this “compliment” from the local Yelp Ambassador (their name for community manager):

The world needs more from the master of the grill… just sayin’

If there’s one way to sap the fun out of something, make it an obligation. Or worse, a veiled threat. I’ve had 3 “reviews of the day” this year. I’m pretty sure at least one of my reviews helped one of the local restaurant-bars out during their opening. I was writing quality reviews, just maybe not in the frequency that the Yelp Overlords liked. So I wrote less.

Then this weekend I received this:

AUG 30, 2013  |  09:57AM PDT
Hello,

As you know, Elite Squad members are viewed as role models for the rest of the community and that comes with the expectation of maintaining a certain level of activity on the site. We couldn’t help but notice a drop in your contributions on Yelp.

While we’d love for you to continue to be a part of the Elite Squad, we’re going to go ahead and remove your 2013 badge at this time, with the hope you’ll continue to participate on Yelp to whatever degree you’re comfortable. If you should choose to become active again, and would like to regain Elite status, you can nominate yourself here: http://www.yelp.ca/elite.

Regardless of your decision, we think you’ve been a great asset and are truly thankful for your contributions to the community.

Regards,
Yelp Elite Squad Messenger
San Francisco, California

My reply:

“Yelp Elite Squad Messenger”,

There are different ways to run a community. When people volunteer to provide content for a site that generates value for a business, it’s nice to recognize that. To give them a little something. Maybe a badge. Maybe a night out for a fancy dinner.

But when you start to pester people to keep it up as one of your own did previously to me, then it starts to feel more like an obligation on the part of the contributor. “I must do this thing that I thought was fun or I will lose the small token that was given to me” is not a nice way to motivate your contributors. The people who create the valuable content on your site.

As a result of this action, I will be deleting all of my positive reviews from your site and will no longer contribute.

If you would like me to reinstate my reviews, you may return my badge.

Thank you.
Rob Campbell

 

And then I proceeded to delete my content.

Thanks for the good times, Yelp. I won’t be adding value to your service anymore.

* – Their changes to the “frecency” algorithm they use to capture “dukedoms” and “feifdoms” was also a part of the reason I stopped checking into places. Dukedoms and “regularity” — whether or not you’re considered a regular at a location – expire after a very short period of time now.