Permalink
Commits on Dec 20, 2011
  1. Add TypeaheadInternationalNormalizer

    Summary:
    Often, especially in typeaheads, you want to increase recall over precision.
    This class performs accent-folding over the inputs, so that your software never
    plays dumb when the user types "cafe" instead of "cafe'".
    
    Task ID: #
    
    Blame Rev:
    
    Test Plan:
    Lint
    
    Revert Plan:
    
    Tags:
    
    Reviewers: epriestley, tomo
    
    Reviewed By: epriestley
    
    CC: aran, cmb, epriestley
    
    Differential Revision: 1245
    Carlos M Jigglypuff committed Dec 20, 2011
Commits on Dec 19, 2011
  1. Automatically parse {__html: "<markup>"} into calls to JX.$H

    Summary:
    If a server endpoint returns escaped markup, the client must call
    JX.$H to render it properly. This is dangerous if ever a server makes a mistake
    or a mismatch occurs between client code expecting escaped markup and a server
    endpoint returning raw strings.
    
    To replace this use case for $H, this builds a protocol into JX.Request to
    understand JSON objects augmented with wrapped strings. Strings that are
    wrapped in objects like {__html: "<markup">} are automatically parsed
    by JX.Request into $H in one place. With this in place and appropriate
    abstractions on the server, client code should never have to call $H directly.
    
    Marshall envisions potentially extending this parsing to include something like
    __e
    to call JX.$ automatically, and perhaps others.
    
    I considered checking that the object was *exactly* {__html: something}, i.e.
    had no other keys, but decided that if someone was inadvertently sending down
    __html
    in non-raw requests, they're confused, and selectively applying the rule would
    only increase the chance of making it a heisenbug.
    
    Test Plan: Load diffs in Phabricator, deliberately break it, see diff loads
    fail, unbreak it.
    
    Reviewers: mroch, epriestley
    
    Reviewed By: epriestley
    
    CC: tomo, aran, epriestley
    
    Differential Revision: 1217
    adonohue committed Dec 14, 2011
Commits on Dec 14, 2011
  1. A removed listener should not invoke its callback.

    Summary:
    When a listener is removed (e.g. listener.remove()), it should not
    invoke its callback.
    
    Test Plan: - Verify that unit tests pass.
    
    Reviewers: leebyron, epriestley, linjeffrey
    
    Reviewed By: epriestley
    
    CC: hedger, aran, epriestley, tomo
    
    Differential Revision: 1215
    hedgerwang committed Dec 14, 2011
Commits on Dec 8, 2011
  1. Add a Cookie library to Javelin

    Summary:
    Based on the MooTools Cookie lib, this is a Javelin-ized
    version that includes as much of a unit test as makes sense. I also
    hacked off parts of the API that didn't seem necessary.
    
    Test Plan:
    Tested in fbri.de, also 5ish years in Mooland. Also, unit
    test.
    
    Reviewers: epriestley, cpojer, leebyron, tomo
    
    Reviewed By: epriestley
    
    CC: aran, cpojer, epriestley, jg, leebyron
    
    Differential Revision: 1175
    Jackson Gabbard committed Nov 4, 2011
Commits on Dec 6, 2011
  1. [jx] allow mergeData() to be called multiple times.

    Summary:
    We're trying to get early flush pages to work and ran into an issue with javelin
    metadata where we wish to append meta data. For example:
    
      <div data-meta="0_0"> first thing </div>
      <script> JX.Stratcom.mergeData(0, {'0' : data}); </script>
    
      [flush]
    
      <div data-meta="0_1"> second thing </div>
      <script> JX.Stratcom.mergeData(0, {'1' : data}); </script>;
    
    Calling this as is will overwrite the previously merged data (in the case of
    block 0, will also try to start the event queue again).
    
    We can't allocate a new block for each flush due to possible race conditions.
    For example, an async request could be dispatched before the page has completed
    flushing, at which point the flush and async request could possibly be using the
    same block.
    
    The proposed solution is to allow mergeData to be called multiple times for the
    same block id, appending data each time. In __DEV__ we check to ensure that
    previously merged keys are not overwritten. On the server side, this is easy to
    implement by doing a small amount of cleanup after each flush.
    
    Existing behavior is the same with the exception of now throwing in __DEV__
    should you attempt to merge into the same block id naively. IMO this exception
    should have existed in the first place.
    
    Test Plan: unit test. Also tested in our flushed page environment.
    
    Reviewers: epriestley, yungsters, tomo, mroch, jg
    
    CC: aran
    
    Differential Revision: 1177
    leebyron committed Dec 6, 2011
Commits on Dec 5, 2011
  1. [jx] request nit

    Summary: epriestley's follow up comment in D1168
    
    Reviewed By: epriestley
    
    Differential Revision: D1168
    leebyron committed Dec 5, 2011
  2. [jx] Merge some FB extensions: set/addData, start event, abortable ev…

    …ents
    
    Summary:
    A couple months back this was added to the FB checkout of Javelin and wasn't
    submitted back into the open source repo. I've made a few additions to those
    additions (fb peeps: https://phabricator.fb.com/D272435).
    
    A repeat of the rationale for these additions:
    
    A start event allows for a global listener to get a reference to the request to
    pre-process it or validate it. We use this in a few places on the mobile site.
    It's useful to have a hook before the transport is assembled. In order to do
    validation, you need to be able to abort the request. This also checks to ensure
    that if an abort was called that the send() method will bail. I've added a check
    to ensure the event itself wasn't prevented as well.
    
    Test Plan: JSLint, a few months of battle.
    
    Reviewers: epriestley, mroch, tomo, yungsters, jg
    
    Reviewed By: epriestley
    
    CC: aran, epriestley, leebyron
    
    Differential Revision: 1168
    leebyron committed Dec 4, 2011
Commits on Nov 16, 2011
  1. Rebuild Javelin packages

    Summary: Just rebuild the default packages since we haven't built them in a
    while.
    
    Test Plan: Poked at some examples.
    
    Reviewers: tomo, mroch, aran
    
    Reviewed By: aran
    
    CC: aran, epriestley
    
    Differential Revision: 1117
    epriestley committed Nov 16, 2011
  2. Use JX.$AX() on the 'path' parameter to JX.Stratcom.invoke()

    Summary: See T627. The implementaiton strongly implies this works, but it
    doesn't.
    
    Test Plan:
    Verified that bare string sigil paths now work correctly:
    
      > JX.Stratcom.listen('foo', 'bar', function() { console.log('OK') })
      (Object)
      > JX.Stratcom.invoke('foo', 'bar', {})
      OK
      (Object)
    
    Reviewers: tomo, aran, mroch, leebyron, asukhachev
    
    Reviewed By: aran
    
    CC: aran, epriestley
    
    Differential Revision: 1116
    epriestley committed Nov 16, 2011
Commits on Nov 15, 2011
  1. [jx] fix bug in JX.Request

    Summary: JX.JSON can return null in some cases, such as when the input is empty
    or not a string. In that case we can't blindly check for response.error.
    
    Test Plan: Provide a null response to a JX.Request and it no longer complains
    that we're accessing members of a null object.
    
    Reviewers: epriestley, aran, tomo, mroch
    
    Reviewed By: epriestley
    
    CC: aran, epriestley, leebyron
    
    Differential Revision: 1113
    leebyron committed Nov 15, 2011
Commits on Nov 6, 2011
  1. Client-side views

    Summary:
     - A "View" is a thin wrapper around JX.$N, but permits
         - composition
         - specialization via Javelin inheritance
     - HTMLView is dumb but conveniently adapts $N to views
     - The ViewInterpreter supports a pure JS decent syntax/EDSL for these
    views, akin to a slightly cleaner version of nested JX.$N. It's usable as a
    target language for CoffeeScript input, too, which makes it even cleaner.
     - The view placeholder Behavior allows a server-side view (AphrontView, XHP)
    to integrate with client-side views. This is demonstrated in a separate diff.
    
    High-level goals here are to:
     - decouple client-side templating from full client-side MVC, so if we just want
    the templating we don't
    necessarily need to pull in a whole MVC framework
     - give an example "pretty okay" template syntax which is intended as a Proof of
    Concept for my "just use javascript" philosophy
    
    Test Plan: Specs, build a page using the template placeholder behavior
    
    Reviewers: epriestley, cpojer, mroch, tomo
    
    Reviewed By: epriestley
    
    CC: aran, rzadorozny, epriestley, cpojer, mroch, jungejason
    
    Differential Revision: 907
    adonohue committed Sep 4, 2011
Commits on Nov 2, 2011
  1. Fix Typeahead/Tokenizer w/ Same Hardpoint

    Summary: This fixes a bug caused when a Typeahead and Tokenizer are both
    constructed using the same hardpoint. The Typeahead appends a node to store
    results in, but the Tokenizer destroys the contents of the hardpoint (and the
    node to store results in with it).
    
    Test Plan: Verified that a Typeahead and Tokenizer constructed using the same
    hardpoint still worked on TRUNK.
    
    Reviewers: epriestley, isaac, cpojer
    
    CC: aran
    
    Differential Revision: 1072
    yungsters committed Nov 1, 2011
Commits on Nov 1, 2011
  1. Fix JX.$U test

    Summary:
    Invalid URI construction throws when invalid, it doesn't set the
    invalid
    domain property. Also '#', '/' and '?' are legitimate characters in URIs. I
    think. Someone in the past clearly thought not.
    
    Test Plan: Run the spec in browser
    
    Reviewers: epriestley, erling
    
    Reviewed By: erling
    
    CC: aran, epriestley, yungsters, erling
    
    Differential Revision: 1065
    adonohue committed Oct 30, 2011
Commits on Oct 27, 2011
  1. Typeahead: Simplify Root Manipulation

    Summary:
    When used in an ##<iframe />##, for some reason the combination of clearing the
    root node and removing it from the tree causes the latest version of Mobile
    Safari (bundled with iOS 5) to crash (or spin up CPU to 100%).
    
    This diff simplifies the logic that deals with the root node; the behavior
    should be the same.
    
    Test Plan: It still... works? I'm open for suggestions on how to test this
    properly besides running it on TRUNK.
    
    Reviewers: epriestley, tomo, cpojer, leebyron
    
    Reviewed By: epriestley
    
    CC: aran, epriestley
    
    Differential Revision: 1058
    yungsters committed Oct 27, 2011
  2. Listen to 'input' events in Typeahead for text input changes that don…

    …'t fire
    
    'keydown' events
    
    Summary:
    CJK input completition (such as selecting the Kanji representation from the
    corresponding Romaji in Japanese) changes the input field value, but doesn't
    fire a keydown event.
    
    To fix this, we listen to the 'input' event as well. Since we use Javelin for
    event delegation, we won't get JS fatals due to the guards in JX.enableDispatch
    and listening to events that are never fired is safe. Since we're still
    listening to keydown events anyways, we should be fine if the 'input' event
    isn't supported.
    
    This might also fix auto-correct in text inputs, since auto-correct might not
    fire a keydown event.
    
    Test Plan:
    Tested in Chrome and iOS Safari on Facebook's mobile typeahead
    Typed 'Keito' using the Romaji keyboard - noted results
    Selected the first Kanji approximation of 'Keito' - results changed to reflect
    selected Kanji
    
    Reviewers: jg, yungsters, tomo, leebyron
    
    Reviewed By: leebyron
    
    CC: aran, leebyron
    
    Differential Revision: 1057
    Jeffrey Lin committed Oct 27, 2011
Commits on Oct 26, 2011
  1. JX.History: Workaround Safari "location.replace" Bug

    Summary:
    This works around a Safari bug that affects the history stack when using
    ##location.replace## and setting ##location.hash##. The fix is to use
    ##history.replaceState## when possible in place of ##location.replace##.
    
    The bug can be reproduced in Safari by entering the following:
    
      location.hash = "A"; // Now at "A".
      location.replace(location.href + "B"); // Now at "AB".
      location.hash = "C"; // Now at "C".
      history.go(-1); // Goes to "A", but should go to "AB".
    
    This has been fixed on the nightly Webkit build, but it affects both iOS 4 and
    5.
    
    Test Plan:
    Force ##historytest.html## to install with ##JX.History.HASHCHANGE##.
    Open the spec file in Safari.
    Click the Safari Bug button.
    
    Reviewers: cpojer, leebyron
    
    Reviewed By: leebyron
    
    CC: aran, leebyron
    
    Differential Revision: 1006
    yungsters committed Oct 13, 2011
Commits on Oct 20, 2011
  1. Typeahead/Typeahead Source Normalization

    Summary:
    - Adds normalization to the Typeahead (it was already there but not functional).
    - Fixes minor bug in TypeaheadSource where JX.bag()(str) was being called.
    
    Test Plan:
    Tested with the facebook's mobile typeahead which uses the javelin
    Typeahead and made sure it still worked. Tried adding a different normalizer to
    the typeahead and made sure I was getting the correct matches according to the
    normalizer.
    
    Reviewers: tomo, epriestley
    
    Reviewed By: epriestley
    
    CC: aran, epriestley, al
    
    Differential Revision: 1011
    alurim committed Oct 13, 2011
Commits on Oct 13, 2011
  1. JX.History: Fix _handleChange for HASHCHANGE

    Summary: This fixes a bug when using either JX.History.HASHCHANGE or
    JX.History.POLLING where _handleChange() may not be able to deal with a
    non-hashed path properly.
    
    Test Plan: The spec ##historytest.html## still works!
    
    Reviewers: leebyron, cpojer
    
    Reviewed By: cpojer
    
    CC: aran, cpojer, leebyron
    
    Differential Revision: 993
    yungsters committed Oct 8, 2011
  2. JX.History: Add DEFAULT Constant

    Summary: Simple refactor to improve code clarity.
    
    Test Plan: The ##historytest.html## spec still works as expected.
    
    Reviewers: cpojer, jg
    
    Reviewed By: cpojer
    
    CC: aran, cpojer
    
    Differential Revision: 988
    yungsters committed Oct 7, 2011
Commits on Oct 7, 2011
  1. Make JX.History Configurable

    Summary:
    This modifies ##JX.History## to be configurable via an ##install()##
    method. This also means that in order to start using ##JX.History##, it must
    first be installed.
    
    Test Plan: Verified that the ##historytest.html## spec file still works.
    
    Reviewers: epriestley, cpojer, leebyron, aran
    
    Reviewed By: cpojer
    
    CC: aran, cpojer, yungsters
    
    Differential Revision: 982
    yungsters committed Oct 3, 2011
  2. JX.URI: Blacklist URI Characters

    Summary:
    **Don't allow '\' in hostnames**
    Some browsers s/\\/\// in URLs, so http://yahoo.com\.facebook.com/ is
    treated as http://yahoo.com/.facebook.com/. Break this by disallowing
    '\' in hostnames.
    
    **In URI, check the domain for invalid characters.**
    Because browsers don't handle URIs consistently, there are a lot of ways to
    trick the URI class into parsing a URI in a different way than a real browser
    would. To help fix this, be more strict about the characters we accept in the
    domain.
    
    [This is a sync from the Facebook repository.]
    
    Reviewers: epriestley, tomo, mroch, aran
    
    Test Plan:
    Run Jasmine:
    
      specs/runner.html
    
    Differential Revision: 981
    yungsters committed Oct 3, 2011
Commits on Oct 4, 2011
  1. Create JX.now(), a wrapper for timestamp generation

    Summary: The motivation for this is to give a coherent API for timestamp
    generation that is also as fast as possible. IE is the notable pain point that
    prevents us from just using Date.now. See
    http://jsperf.com/date-initialization/2 and http://jsperf.com/property-lookups
    for the raw numbers on timestamp generation. There has already been a lot of
    back and forth about this diff internally, but the outcome seems to be in favor
    so I'm proceeding with this. If nothing else, JX.now() is a cleaner API than
    +new Date(), which is only marginally better than int casting with bitwise
    operators and other JS jedi mind tricks, and is only two extra bytes.
    
    Reviewers: yungsters, kdelong, mroch, epriestley, tomo
    
    CC:
    
    Test Plan: Tested within the Facebook Mobile site in my sandbox
    
    Differential Revision: 983
    Jackson Gabbard committed Oct 3, 2011
Commits on Sep 30, 2011
  1. JX.History: Fix Interval Polling

    Summary:
    This fixes interval polling. Before, we were testing for changes in the
    URL fragment without using ##JX.History._parseFragment()##. Since the check is
    actually redundant (already done in ##_handleChange##), I've removed it.
    
    Test Plan:
    Disable ##hasPushState## and ##onhashchange##.
    Verify that the spec files works properly.
    
    Reviewers: epriestley, cpojer, leebyron, jg
    
    Reviewed By: epriestley
    
    CC: lukeshepard, jg, cpojer, epriestley, yungsters
    
    Differential Revision: 972
    yungsters committed Sep 30, 2011
Commits on Sep 29, 2011
  1. Add warning for 2nd argument in JX.Stratcom.invoke

    Summary:
    This adds a ##__DEV__## check for an invalid 2nd argument to ##JX.Stratcom.invoke##. This helps catch a common error that is forgetting the second argument to ##JX.Stratcom.invoke## is the path (and not the data).
    
    Reviewers: epriestley, cpojer, jg, aran, mroch
    
    Test Plan:
    
      JX.Stratcom.invoke('event'); // No error.
      JX.Stratcom.invoke('event', null); // No error.
      JX.Stratcom.invoke('event', ['some-sigil'], { key: 'value' }); // No error.
      JX.Stratcom.invoke('event', { key: 'value' }); // Error!
    yungsters committed Sep 29, 2011
Commits on Sep 28, 2011
  1. Add JX.$E() that throws an exception and attached caller info the exc…

    …eption
    
    message.
    
    Summary:
    JX.$() errors should be common and difficult to debug. Reproducing the errors
    is often the hardest part. This diff should make the debugging a lot easier.
    This problem should be common for all developers, not just FB.
    
    I'm keeping it as simple as possible but sufficient for handling the
    most frequent problem. We could potentially print callstack instead of
    caller.. That shouldn't be too hard to do if desirable.
    
    Test Plan:
    The exception message before and after.
    
    Before:
    
    Exception: {"message":"JX.$('u402390_1a') call matched no nodes.
    
    After:
    
    Exception: {"message":"JX.$('u402390_1a') call matched no nodes. Caller:\
    function (config) {\
      var sources = [];\
      if (config.sources.bootstrapped) {\
        sources.push(new JX.MTypeaheadTouchSource(\
          config.sources.bootstrapped.src,\
          config.sources.bootstrapped.source_key\
        ));\
      }\
      if (config.sources.online) {\
        sources.push(new JX.MTypeaheadOnDemandSource(config.sources.online.src));\
      }\
    \
      var hardpoint = JX.$(config.id+'a');\
      var input = JX.$(config.textinput);\
      var content = JX.$('sections');\
      var shadow = JX.$('sections.shadow');\
      var button = JX.DOM.find(hardpoint, 'button', 'friends-search-button');\
      var typeahead = new JX.MSearchFriendsTypeahead(hardpoint, input);\
      typeahead.setDatasource(new JX.TypeaheadCompositeSource(sources));\
    \
      if (!config.navigateOnSelect) {\
        // This is needed to explicitly kill click events from Touchable JS,\
        // which will otherwise result in following the href for a result anchor.\
        JX.DOM.listen(hardpoint, 'click', 'typeahead-result', function(e) {\
          e.kill();\
        });\
      }\
    
    Revert Plan:
    
    Tags:
    
    Reviewers: epriestley, mroch, phil, aran, leebyron, yungsters, tomo, guangyuc,
    jg, lukeshepard
    
    Reviewed By: epriestley
    
    CC: aran, epriestley, guilin, phil, guangyuc
    
    Differential Revision: 956
    guilin committed Sep 22, 2011
  2. Fix JX.History Consistency + Replace Bug

    Summary:
    There are currently two issues with ##JX.History##:
    
     - The base path is not consistently used throughout the class (e.g. URL
    fragment and event data).
     - ##JX.MHistory.replace()## does not fire ##history:change## correctly if the
    HTML5 History API is present.
    
    The ##historytest.html## spec file has also been updated to be able to test for
    these issues.
    
    Test Plan:
    1. Open the ##historytest.html## spec file in Chrome.
    2. Check 'Replace' and click around. Pages should load properly.
    3. Force ##hasPushState()## to return ##false##.
    4. Click between pages. The path should not contain ##!## or ##~!##.
    5. At any point, refreshing the page should maintain the same path in the ##<pre
    />##.
    
    Reviewers: cpojer, leebyron, epriestley
    
    CC: aran
    
    Differential Revision: 971
    yungsters committed Sep 28, 2011
Commits on Sep 25, 2011
  1. RFC: Remove event listeners from the handler

    Summary:
    A couple months ago I submitted an RFC for JX.Stratcom.listenOnce for which we
    agreed there was too few cases to support the complexity and weight that the
    code added.
    
    This is another approach to the problem that is more flexible, less complex and
    has a clear API.
    
    This allows for a handler to call JX.Stratcom.removeCurrentListener(). This
    allows for the listenOnce case by having the handler always call this method,
    but also allows for more complex behavior by calling only in a specific case.
    
    Test Plan: tested by adding 3 listeners to click, the middle one calling
    removeCurrentListener() in the handler. Verified all 3 were called initially,
    and the removed did not get called another time where the others did.
    
    Reviewers: mroch, tomo, epriestley, aran
    
    Reviewed By: epriestley
    
    CC: aran, leebyron, epriestley
    
    Differential Revision: 957
    leebyron committed Sep 25, 2011
Commits on Sep 16, 2011
  1. JX.DOM.find() exceptions should indicate which id failed

    Summary:
    Right not when you get a JX.$ exception, it says 'Error: JX.$() or JX.DOM.find()
    call matched no nodes." .
    
    It should indicate the exact DOM id with the issue so it's easier to debug.
    
    This changes JX.$.NotFound to be more descriptive.  To filter out JX.$.NotFound
    exceptions, use
    
    e instanceof JX.$.NotFound
    
    e.g.
    
    try { throw new JX.$.NotFound('someid'); somethingelse(); }
    catch (e) {
    if (!(e instanceof JX.$.NotFound)) {
    throw e;
    }
    }
    
    Test Plan:
    saw exception:
    
    AFTER:
    
    "JX.$(\"errorBox\" ) call matched no nodes."
    
    BEFORE
    
    JX.$ or JX.DOM.find() call matched no nodes."
    
    Reviewers: epriestley, mroch, aran, jg
    
    Reviewed By: epriestley
    
    CC: aran, cpojer, tomo, epriestley, phil, jg
    
    Differential Revision: 939
    Philip Fung committed Sep 15, 2011
  2. RFC: Order DOM event handlers by shortest matching sigil distance fro…

    …m target
    
    node.
    
    Summary:
    A suggested change to the order in which matching event handlers are called.
    Currently javelin claims no guarantee for any kind of order, but in practice the
    order is the order in which the event handlers were defined. This keeps order of
    definition as the secondary sort, but makes primary sort the distance of the
    matching sigil node from the event target node.
    
    This means if you have markup:
    
      <div data-sigil="one">
        <div data-sigil="two">
          <div data-sigil="three">
            Click me
          </div>
        </div>
      </div>
    
    That a handler listening to the sigil path ['three'] would execute before a
    handler listening to the sigil path ['two'].
    
    For sigil paths with more than one sigil, it will take the shortest distance to
    match, so sigil path ['one', 'three'] would execute before ['two'].
    
    For handlers which listen to all events, the distance is assumed to be "0" in
    effect pointing to the target node, so listening to null would execute before
    ['two'] but with the same priority (in this case) as ['three'], falling back on
    the order in which they were assigned.
    
    This has the benefit of mirroring the behavior of the DOM event API's bubbling
    mechanism so that a more specific region of the DOM recieves events before ta
    more general region.
    
    Test Plan: Tested against the fb m-site and tested in the console with the cases
    listed in the summary.
    
    Reviewers: epriestley, mroch, yungsters
    
    Reviewed By: epriestley
    
    CC: aran, epriestley, jg, hedger, mroch, leebyron, akrieger
    
    Differential Revision: 925
    leebyron committed with Philip Fung Sep 13, 2011
Commits on Sep 15, 2011
  1. RFC: Order DOM event handlers by shortest matching sigil distance fro…

    …m target
    
    node.
    
    Summary:
    A suggested change to the order in which matching event handlers are called.
    Currently javelin claims no guarantee for any kind of order, but in practice the
    order is the order in which the event handlers were defined. This keeps order of
    definition as the secondary sort, but makes primary sort the distance of the
    matching sigil node from the event target node.
    
    This means if you have markup:
    
      <div data-sigil="one">
        <div data-sigil="two">
          <div data-sigil="three">
            Click me
          </div>
        </div>
      </div>
    
    That a handler listening to the sigil path ['three'] would execute before a
    handler listening to the sigil path ['two'].
    
    For sigil paths with more than one sigil, it will take the shortest distance to
    match, so sigil path ['one', 'three'] would execute before ['two'].
    
    For handlers which listen to all events, the distance is assumed to be "0" in
    effect pointing to the target node, so listening to null would execute before
    ['two'] but with the same priority (in this case) as ['three'], falling back on
    the order in which they were assigned.
    
    This has the benefit of mirroring the behavior of the DOM event API's bubbling
    mechanism so that a more specific region of the DOM recieves events before ta
    more general region.
    
    Test Plan: Tested against the fb m-site and tested in the console with the cases
    listed in the summary.
    
    Reviewers: epriestley, mroch, yungsters
    
    Reviewed By: epriestley
    
    CC: aran, epriestley, jg, hedger, mroch, leebyron, akrieger
    
    Differential Revision: 925
    leebyron committed Sep 13, 2011
  2. Fix JX.History on Firefox

    Summary:
    Fixes ##JX.History## for browsers that support the HTML5 History API but do not
    pass the test:
    
      'onpopstate' in window
    
    Test Plan:
    1. Without the fix, open ##specs/historytest.html## in Firefox.
    2. Verify that clicking to another page and pressing back fails to change the
    content.
    3. With the fix, open ##specs/historytest.html## in Firefox.
    4. Verifying that clicking to another page and pressing back correctly changes
    the content.
    5. Verify that other browsers still work.
    
    Reviewers: epriestley, cpojer, aran
    
    Reviewed By: aran
    
    CC: aran
    
    Differential Revision: 937
    yungsters committed Sep 15, 2011
Commits on Sep 13, 2011
  1. Use Punctuation Blacklist for Typeahead Normalizer

    Summary: This changes the Typeahead normalizer to use a punctuation blacklist
    instead of stripping all non-alphanumeric characters. As the normalizer stands
    now, any international characters (e.g. Japanese characters) are stripped.
    
    Test Plan:
      > JX.TypeaheadNormalizer.normalize('Get rid of the periods...')
      "get rid of the periods"
      > JX.TypeaheadNormalizer.normalize('ラジオ')
      "ラジオ"
    
    Reviewers: epriestley, jg
    
    Reviewed By: epriestley
    
    CC: aran, epriestley, yungsters
    
    Differential Revision: 924
    yungsters committed Sep 13, 2011