Skip to content

Instantly share code, notes, and snippets.

@virtuald
Last active October 12, 2018 23:58
Show Gist options
  • Select an option

  • Save virtuald/ac2fabcc37aeb00ecfe7a94e29035c72 to your computer and use it in GitHub Desktop.

Select an option

Save virtuald/ac2fabcc37aeb00ecfe7a94e29035c72 to your computer and use it in GitHub Desktop.

Revisions

  1. virtuald revised this gist Oct 12, 2018. 1 changed file with 2 additions and 3 deletions.
    5 changes: 2 additions & 3 deletions route+custom.js
    Original file line number Diff line number Diff line change
    @@ -48,7 +48,7 @@ riot.tag2('router', '<yield></yield>', '', '', function(opts) {

    if (parent) {
    this.process = function(path) {
    return this$1.$.some(function(o) {
    this$1.$.some(function(o) {
    var args = SECOND_PARSER(path, o.f);
    if (typeof args != 'undefined') {
    o.a.apply(o, args)
    @@ -66,7 +66,7 @@ riot.tag2('router', '<yield></yield>', '', '', function(opts) {
    // no parent? create a brand new route context then!
    this.route = route.create();
    this.routestop = this.route.stop;
    this.process = function(){ return false; }
    this.process = function(){}

    this.on('mount', function () {
    // To avoid updating route tag before mount, we use setTimeout here
    @@ -108,7 +108,6 @@ riot.tag2('route', '<virtual if="{show}"><yield></yield></virtual>', '', '', fun
    };
    }

    var ppath = path;
    this.parent.route(path, function() {
    var args = [], len = arguments.length - 1;
    var lastArg = arguments[len];
  2. virtuald revised this gist Oct 12, 2018. 1 changed file with 25 additions and 22 deletions.
    47 changes: 25 additions & 22 deletions route+custom.js
    Original file line number Diff line number Diff line change
    @@ -48,7 +48,7 @@ riot.tag2('router', '<yield></yield>', '', '', function(opts) {

    if (parent) {
    this.process = function(path) {
    this$1.$.some(function(o) {
    return this$1.$.some(function(o) {
    var args = SECOND_PARSER(path, o.f);
    if (typeof args != 'undefined') {
    o.a.apply(o, args)
    @@ -60,30 +60,25 @@ riot.tag2('router', '<yield></yield>', '', '', function(opts) {
    this.route = function(filter, action) {
    this$1.$.push({f: filter, a: action});
    }
    // propagate the current subroute to children
    this.routestart = function() {
    if (typeof parent.trailer != 'undefined') {
    this$1.process(parent.trailer);
    }
    }
    this.routestop = parent.subroute(this);
    } else {

    // no parent? create a brand new route context then!
    this.route = route.create();
    this.routestart = route.start;
    this.routestop = this.route.stop;
    this.process = function(){ return false; }

    this.on('mount', function () {
    // To avoid updating route tag before mount, we use setTimeout here
    window.setTimeout(function () { return route.start(true); }, 0);
    });
    }

    this.select = function (target) {
    [].concat(this$1.tags.route)
    .forEach(function (r) { return r.show = (r === target); });
    };

    this.on('mount', function () {
    window.setTimeout(function () { return this$1.routestart(true); }, 0);
    });

    this.on('unmount', function () {
    this$1.routestop();
    this.$ = [];
    @@ -93,10 +88,10 @@ riot.tag2('router', '<yield></yield>', '', '', function(opts) {
    riot.tag2('route', '<virtual if="{show}"><yield></yield></virtual>', '', '', function(opts) {
    var this$1 = this;

    this.show = false;
    this$1.show = false;

    // contains any routers in child tags
    this.$ = [];
    this$1.$ = [];

    // The last trailing segment we were asked to process
    this.trailer = '';
    @@ -113,6 +108,7 @@ riot.tag2('route', '<virtual if="{show}"><yield></yield></virtual>', '', '', fun
    };
    }

    var ppath = path;
    this.parent.route(path, function() {
    var args = [], len = arguments.length - 1;
    var lastArg = arguments[len];
    @@ -142,22 +138,29 @@ riot.tag2('route', '<virtual if="{show}"><yield></yield></virtual>', '', '', fun
    var route_path = (container.route_path ? container.route_path + '/' + args[0] : args[0]);
    this$1.route_path = route_path;


    this$1.one('updated', function () {
    function doupdate() {
    flatten(this$1.tags).forEach(function (tag) {
    tag.route_path = route_path;
    tag.trigger.apply(tag, [ 'route', container ].concat( args.slice(1) ));
    tag.update();
    });
    });

    // send the trailer to any routers
    this$1.$.forEach(function(router) {
    router.process(this$1.trailer);
    });

    // send the trailer to any router children
    this$1.$.forEach(function(router) {
    router.process(this$1.trailer);
    });
    }

    this$1.parent.select(this$1);
    this$1.parent.update();

    // If not mounted, there's no way to intercept the child tags while mounting.
    // We need to wait the `updated` event to access them via `this.tags`.
    if (this$1.isMounted) {
    doupdate();
    } else {
    this$1.one('updated', doupdate);
    }
    }

    function flatten(tags) {
  3. virtuald revised this gist Oct 3, 2018. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions route+custom.js
    Original file line number Diff line number Diff line change
    @@ -8,6 +8,7 @@
    // - Each 'route' event receives the parent container, and any arguments that it would normally get
    // - Child tags receive an attribute 'route_path' which contains the current routing
    // - Adding a '/@@' to the end of a route allows the route to have subordinate routers
    // - Child routers use relative paths, not absolute paths (this makes tags more composable)
    //

    riot = riot && riot.hasOwnProperty('default') ? riot['default'] : riot;
  4. virtuald created this gist Oct 3, 2018.
    173 changes: 173 additions & 0 deletions route+custom.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,173 @@
    (function (riot, route) {
    'use strict';

    //
    // Modified version of the riot-router tags
    //
    // - Intended to be used recursively. You can even use multiple routers in a tag and they'll work
    // - Each 'route' event receives the parent container, and any arguments that it would normally get
    // - Child tags receive an attribute 'route_path' which contains the current routing
    // - Adding a '/@@' to the end of a route allows the route to have subordinate routers
    //

    riot = riot && riot.hasOwnProperty('default') ? riot['default'] : riot;

    // customizes the second parser
    // - Returns the full path as the first arg
    // - Adds @@ and makes it capturing
    function SECOND_PARSER(path, filter) {
    var f = filter
    .replace(/\?/g, '\\?')
    .replace(/\*/g, '([^/?#]+?)')
    .replace(/\/@@$/, '/(.*)?')
    .replace(/\.\./, '.*');
    var re = new RegExp(("^" + f + "$"));
    var args = path.match(re);

    if (args) { return args.slice(0) }
    }

    route.parser(null, SECOND_PARSER);

    riot.tag2('router', '<yield></yield>', '', '', function(opts) {
    var this$1 = this;

    // This holds our child route tags as an object
    this.$ = [];

    // If this tag is mounted underneath another router, use that instead of
    // creating our own router context
    var parent = this.parent;
    while (parent) {
    if (parent.subroute) {
    break;
    }
    parent = parent.parent;
    }

    if (parent) {
    this.process = function(path) {
    this$1.$.some(function(o) {
    var args = SECOND_PARSER(path, o.f);
    if (typeof args != 'undefined') {
    o.a.apply(o, args)
    return true;
    }
    });
    }

    this.route = function(filter, action) {
    this$1.$.push({f: filter, a: action});
    }
    // propagate the current subroute to children
    this.routestart = function() {
    if (typeof parent.trailer != 'undefined') {
    this$1.process(parent.trailer);
    }
    }
    this.routestop = parent.subroute(this);
    } else {

    // no parent? create a brand new route context then!
    this.route = route.create();
    this.routestart = route.start;
    this.routestop = this.route.stop;
    }

    this.select = function (target) {
    [].concat(this$1.tags.route)
    .forEach(function (r) { return r.show = (r === target); });
    };

    this.on('mount', function () {
    window.setTimeout(function () { return this$1.routestart(true); }, 0);
    });

    this.on('unmount', function () {
    this$1.routestop();
    this.$ = [];
    });
    });

    riot.tag2('route', '<virtual if="{show}"><yield></yield></virtual>', '', '', function(opts) {
    var this$1 = this;

    this.show = false;

    // contains any routers in child tags
    this.$ = [];

    // The last trailing segment we were asked to process
    this.trailer = '';

    var path = opts.path;

    // if ends with /@@, add an additional path to handle the trailer
    if (path.endsWith('/@@')) {

    this.subroute = function(o) {
    this.$.push(o);
    return function() {
    this.$.splice(this.$.indexOf(o), 1);
    };
    }

    this.parent.route(path, function() {
    var args = [], len = arguments.length - 1;
    var lastArg = arguments[len];
    while ( len-- ) args[ len ] = arguments[ len ];

    // The first argument is the current route's path, which doesn't include the trailer
    args[0] = args[0].substring(0, args[0].length - (lastArg.length + 1));

    this$1.trailer = lastArg;
    onroute(args);
    });

    // register another route without the trailer
    path = path.substring(0, path.length - 3);
    }

    this.parent.route(path, function () {
    var args = [], len = arguments.length;
    while ( len-- ) args[ len ] = arguments[ len ];

    this$1.trailer = '';
    onroute(args);
    });

    function onroute(args) {
    var container = this$1.parent.parent;
    var route_path = (container.route_path ? container.route_path + '/' + args[0] : args[0]);
    this$1.route_path = route_path;


    this$1.one('updated', function () {
    flatten(this$1.tags).forEach(function (tag) {
    tag.route_path = route_path;
    tag.trigger.apply(tag, [ 'route', container ].concat( args.slice(1) ));
    tag.update();
    });
    });

    // send the trailer to any routers
    this$1.$.forEach(function(router) {
    router.process(this$1.trailer);
    });

    this$1.parent.select(this$1);
    this$1.parent.update();
    }

    function flatten(tags) {
    return Object.keys(tags)
    .map(function (key) { return tags[key]; })
    .reduce(function (acc, tag) { return acc.concat(tag); }, [])
    }

    this.on('unmount', function() {
    this$1.$ = [];
    })
    });

    })(riot, route);