<commit_before>/**
 * Client side router.
 *
 * @class ClientRouter
 * @exports ClientRouter
 * @extends IronRouter
 */

ClientRouter = RouterUtils.extend(IronRouter, {
  typeName: 'ClientRouter',

  /**
   * @constructor
   * @param {Object} [options]
   * @param {Boolean} [options.autoRender] Automatically render to the body
   * @param {Boolean} [options.autoStart] Automatically start listening to
   * events
   */

  constructor: function (options) {
    var self = this;

    ClientRouter.__super__.constructor.apply(this, arguments);

    self._partials = new YieldPartialDict;

    Meteor.startup(function () {
      setTimeout(function () {
        if (self.options.autoRender !== false)
          self.autoRender();
        if (self.options.autoStart !== false)
          self.start();
      });
    });
  },

  /**
   * The default layout for the router.
   *
   * @type {String|Function}
   */

  layout: '__defaultLayout__',


  /**
   * Hook method called from the Router's run method. This methods drives
   * running the controller for a route. The controller can be run in a reactive
   * or nonreactive context. If you pass options.reactive = false, then the
   * controller will be run normally. Otherwise it will be run in a reactive
   * computation.
   *
   * @param {RouteController} controller
   * @param {RouteContext} context
   * @param {Object} [options]
   * @api protected
   */

  onRun: function (controller, context, options) {
    var self = this
      , isReactive = context.isReactive !== false;

    var maybeRunReactively = function () {
      if (isReactive) {
        Deps.autorun(function (c) {
          self._routeComputation = c;
          self._partials.clear();
          self.runController(controller, context);
        });
      } else {
        self._partials.clear();
        self.runController(controller, context);
      }
    };

    controller.onRender = function (template, options) {
      options = options || {};
      self._partials.set(options.to, {
        template: template,
        data: options.data
      });
    };

    // there is a route computation from a previous route so lets tear it down
    if (self._routeComputation) {
      self._routeComputation.stop();
      Deps.afterFlush(maybeRunReactively);
    } else {
      maybeRunReactively();
    }
  },

  /**
   * Wrapper around Location.go that accepts a routeName or a path as the first
   * parameter. This method can accept client and server side routes.
   *
   * Examples:
   *
   *  1. Router.go('/posts', {state: 'true'});
   *  2. Router.go('postIndex', [param1, param2], {state});
   *
   * @param {String} routeNameOrPath
   * @param {Array|Object} [params]
   * @param {Object} [state]
   * @param {Boolean} [replaceState]
   * @api public
   */

  go: function (routeNameOrPath, params, state, replaceState) {
    var isPathRe = /^\/|http/
      , route
      , path
      , state
      , onComplete
      , done = function() {
        if (replaceState) {
          Location.replaceState(state, null, path, true /* skipReactive */);
        } else {
          Location.pushState(state, null, path, true /* skipReactive */);
        }
      };

    if (isPathRe.test(routeNameOrPath)) {
      path = routeNameOrPath;
      state = params;
      replaceState = state;
      // issue here is in the dispatch process we might want to
      // make a server request so therefore not call this method yet, so
      // we need to push the state only after we've decided it's a client
      // request, otherwise let the browser handle it and send off to the
      // server
      this.dispatch(path, {state: state}, done);
    } else {
      route = this.routes[routeNameOrPath];
      RouterUtils.assert(route, 'No route found named ' + routeNameOrPath);
      path = route.path(params);
      this.run(path, route, {state: state}, done);
    }
  },

  /**
   * Returns an html string or a document fragment with the router's layout.
   * This method also sets up the 'yield' helper on the layout. This is so that
   * the yield helper has a reference to the router through the closure.
   *
   * @returns {String|DocumentFragment}
   * @api public
   */

  render: function () {
    var self = this
      , layout
      , layoutHelpers;

    layout = RouterUtils.getTemplateFunction(
      this.options.layout || this.layout);

    layoutHelpers = {
      'yield': function (key, options) {
        var html;

        if (arguments.length < 2)
          key = null;

        function renderPartial () {
          var partial = self._partials.get(key);
          RouterUtils.assert(
            partial, 
            'No yield named "' + key + '" found. Are you sure it\'s in your main layout template?'
          );
          return partial.render();
        }

        html = renderPartial();
        return new Handlebars.SafeString(html);
      }
    };

    if (layout.helpers) {
      layout.helpers(layoutHelpers);
      return layout();
    } else {
      return layout(layoutHelpers);
    }
  },

  /**
   * Render the router into the body of the page automatically. Calles the
   * render method inside Spark.render to create a renderer and appends to the
   * document body.
   *
   * @api public
   */

  autoRender: function () {
    document.body.innerHTML = '';
    document.body.appendChild(Spark.render(_.bind(this.render, this)));
  },


  /**
   * Start listening to click events and set up a Deps.autorun for location
   * changes. If already started the method just returns.
   *
   * @api public<commit_msg>Fixes #63. autoRender should appendChild not replace the body.<commit_after>/**
 * Client side router.
 *
 * @class ClientRouter
 * @exports ClientRouter
 * @extends IronRouter
 */

ClientRouter = RouterUtils.extend(IronRouter, {
  typeName: 'ClientRouter',

  /**
   * @constructor
   * @param {Object} [options]
   * @param {Boolean} [options.autoRender] Automatically render to the body
   * @param {Boolean} [options.autoStart] Automatically start listening to
   * events
   */

  constructor: function (options) {
    var self = this;

    ClientRouter.__super__.constructor.apply(this, arguments);

    self._partials = new YieldPartialDict;

    self.isRendered = false;

    Meteor.startup(function () {
      setTimeout(function () {
        if (self.options.autoRender !== false)
          self.autoRender();
        if (self.options.autoStart !== false)
          self.start();
      });
    });
  },

  /**
   * The default layout for the router.
   *
   * @type {String|Function}
   */

  layout: '__defaultLayout__',


  /**
   * Hook method called from the Router's run method. This methods drives
   * running the controller for a route. The controller can be run in a reactive
   * or nonreactive context. If you pass options.reactive = false, then the
   * controller will be run normally. Otherwise it will be run in a reactive
   * computation.
   *
   * @param {RouteController} controller
   * @param {RouteContext} context
   * @param {Object} [options]
   * @api protected
   */

  onRun: function (controller, context, options) {
    var self = this
      , isReactive = context.isReactive !== false;

    var maybeRunReactively = function () {
      if (isReactive) {
        Deps.autorun(function (c) {
          self._routeComputation = c;
          self._partials.clear();
          self.runController(controller, context);
        });
      } else {
        self._partials.clear();
        self.runController(controller, context);
      }
    };

    controller.onRender = function (template, options) {
      options = options || {};
      self._partials.set(options.to, {
        template: template,
        data: options.data
      });
    };

    // there is a route computation from a previous route so lets tear it down
    if (self._routeComputation) {
      self._routeComputation.stop();
      Deps.afterFlush(maybeRunReactively);
    } else {
      maybeRunReactively();
    }
  },

  /**
   * Wrapper around Location.go that accepts a routeName or a path as the first
   * parameter. This method can accept client and server side routes.
   *
   * Examples:
   *
   *  1. Router.go('/posts', {state: 'true'});
   *  2. Router.go('postIndex', [param1, param2], {state});
   *
   * @param {String} routeNameOrPath
   * @param {Array|Object} [params]
   * @param {Object} [state]
   * @param {Boolean} [replaceState]
   * @api public
   */

  go: function (routeNameOrPath, params, state, replaceState) {
    var isPathRe = /^\/|http/
      , route
      , path
      , state
      , onComplete
      , done = function() {
        if (replaceState) {
          Location.replaceState(state, null, path, true /* skipReactive */);
        } else {
          Location.pushState(state, null, path, true /* skipReactive */);
        }
      };

    if (isPathRe.test(routeNameOrPath)) {
      path = routeNameOrPath;
      state = params;
      replaceState = state;
      // issue here is in the dispatch process we might want to
      // make a server request so therefore not call this method yet, so
      // we need to push the state only after we've decided it's a client
      // request, otherwise let the browser handle it and send off to the
      // server
      this.dispatch(path, {state: state}, done);
    } else {
      route = this.routes[routeNameOrPath];
      RouterUtils.assert(route, 'No route found named ' + routeNameOrPath);
      path = route.path(params);
      this.run(path, route, {state: state}, done);
    }
  },

  /**
   * Returns an html string or a document fragment with the router's layout.
   * This method also sets up the 'yield' helper on the layout. This is so that
   * the yield helper has a reference to the router through the closure.
   *
   * @returns {String|DocumentFragment}
   * @api public
   */

  render: function () {
    var self = this
      , layout
      , layoutHelpers;

    layout = RouterUtils.getTemplateFunction(
      this.options.layout || this.layout);

    layoutHelpers = {
      'yield': function (key, options) {
        var html;

        if (arguments.length < 2)
          key = null;

        function renderPartial () {
          var partial = self._partials.get(key);
          RouterUtils.assert(
            partial, 
            'No yield named "' + key + '" found. Are you sure it\'s in your main layout template?'
          );
          return partial.render();
        }

        html = renderPartial();
        return new Handlebars.SafeString(html);
      }
    };

    //XXX not convinced yet that we should throw an error if already rendered,
    //but putting this in place now anyway.
    self.isRendered = true;

    if (layout.helpers) {
      layout.helpers(layoutHelpers);
      return layout();
    } else {
      return layout(layoutHelpers);
    }
  },

  /**
   * Render the router into the body of the page automatically. Calles the
   * render method inside Spark.render to create a renderer and appends to the
   * document body.
   *
   * @api public
   */

  autoRender: function () {
    document.body.appendChild(Spark.render(_.bind(this.render, this)));
  },


  /**
   * Start listening to click events and set up a Deps.autorun for location
   * changes. If already started the method just returns.
   *
   * @api public
{'fraction_non_alphanumeric': 0.11148380263041752, 'fraction_numerical': 0.0010592285285550358, 'mean_word_length': 2.3891714029314985, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1433705', 'n_tokens_mistral': 3271, 'n_tokens_neox': 3198, 'n_words': 1014}