Example #1
0
 require('consumer_info').promise.done(function() {
     console.log('Triggering initial navigation');
     if (!z.spaceheater) {
         z.page.trigger('navigate', [window.location.pathname + window.location.search]);
     } else {
         z.page.trigger('loaded');
     }
 });
Example #2
0
function() {
    var capabilities = require('capabilities');
    var console = require('log')('main');
    var start_time = performance.now();
    var utils = require('utils');
    var z = require('z');

    console.log('Dependencies resolved, starting init');

    z.body.addClass('html-' + require('l10n').getDirection());

    z.page.one('loaded', function() {
        // Remove the splash screen.
        console.log('Hiding splash screen (' + ((performance.now() - start_time) / 1000).toFixed(6) + 's)');
        var splash = $('#splash-overlay').addClass('hide');
        z.body.removeClass('overlayed').addClass('loaded');
        setTimeout(function() {
            z.page.trigger('splash_removed');
            splash.remove();
        }, 1500);
    });

    // Clear search field when 'clear' link is clicked.
    $('#site-header').on('click', '.search-clear', utils._pd(function() {
        if ($(this).hasClass('search-clear')) {
            $('#search-q').val('').trigger('focus');
        }
    }));

    // Do some last minute template compilation.
    z.page.on('reload_chrome', function() {
        console.log('Reloading chrome');
        var nunjucks = require('templates');
        $('#site-header').html(
            nunjucks.env.render('header.html'));
        $('#site-footer').html(
            nunjucks.env.render('footer.html'));

        z.body.toggleClass('logged-in', require('user').logged_in());
        z.page.trigger('reloaded_chrome');
    }).trigger('reload_chrome');

    z.body.on('click', '.site-header .back', function(e) {
        e.preventDefault();
        console.log('← button pressed');
        require('navigation').back();
    });

    // Perform initial navigation.
    console.log('Triggering initial navigation');
    z.page.trigger('navigate', [window.location.pathname + window.location.search]);

    console.log('Initialization complete');
});
Example #3
0
        z.page.on('reload_chrome', function() {
            console.log('Reloading chrome');
            var context = {z: z};
            $('#site-header').html(
                nunjucks.env.render('header.html', context));
            $('#site-footer').html(
                nunjucks.env.render('footer.html', context));

            z.body.toggleClass('logged-in', require('user').logged_in());
            z.page.trigger('reloaded_chrome');
        }).trigger('reload_chrome');
Example #4
0
    z.page.on('navigate', function(e, href, popped, state) {

        if (!state) return;

        // Clean the path's parameters.
        // /foo/bar?foo=bar&q=blah -> /foo/bar?q=blah
        state.path = extract_nav_url(state.path);

        // Truncate any closed navigational loops.
        for (var i=0; i<stack.length; i++) {
            if (stack[i].path === state.path) {
                stack = stack.slice(i+1);
                break;
            }
        }

        // Are we home? clear any history.
        if (state.type == 'root') {
            stack = [state];

            // Also clear any search queries living in the search box.
            // Bug 790009
            $('#search-q').val('');
        } else {
            // handle the back and forward buttons.
            if (popped && stack[0].path === state.path) {
                stack.shift();
            } else {
                stack.unshift(state);
            }

            // Does the page have a parent? If so, handle the parent logic.
            if (z.context.parent) {
                var parent = _.indexOf(_.pluck(stack, 'path'), z.context.parent);

                if (parent > 1) {
                    // The parent is in the stack and it's not immediately
                    // behind the current page in the stack.
                    stack.splice(1, parent - 1);
                    console.log('Closing navigation loop to parent (1 to ' + (parent - 1) + ')');
                } else if (parent == -1) {
                    // The parent isn't in the stack. Splice it in just below
                    // where the value we just pushed in is.
                    stack.splice(1, 0, {path: z.context.parent});
                    console.log('Injecting parent into nav stack at 1');
                }
                console.log('New stack size: ' + stack.length);
            }
        }

        z.page.trigger('page_setup');

    }).on('page_setup', function() {
Example #5
0
        z.page.on('reload_chrome', function() {
            console.log('Reloading chrome');
            var context = {z: z};

            $('#site-header').html(
                nunjucks.env.render('header.html', context));
            $('#site-footer').html(
                nunjucks.env.render('footer.html', context));

            // Navigate to the hash if necessary.
            var hash = window.location.hash;
            if (hash.indexOf('show-read') !== -1 || hash.indexOf('show-unread') !== -1) {
                $('.notes-filter[href="' + hash + '"]').trigger('click');
            }

            z.body.toggleClass('logged-in', user.logged_in());
            z.page.trigger('reloaded_chrome');
        }).trigger('reload_chrome');
Example #6
0
        z.page.on('reload_chrome', function() {
            console.log('Reloading chrome');
            var context = {z: z};
            $('#site-header').html(
                nunjucks.env.getTemplate('header.html').render(context));
            $('#site-footer').html(
                nunjucks.env.getTemplate('footer.html').render(context));

            if (!navigator.mozApps &&
                !require('storage').getItem('hide_incompatibility_banner')) {
                console.log('Adding incompatibility banner');
                $('#incompatibility-banner').html(
                    nunjucks.env.getTemplate(
                        'incompatible.html').render(context));
                z.body.addClass('show-incompatibility-banner');
            }

            z.body.toggleClass('logged-in', require('user').logged_in());
            z.page.trigger('reloaded_chrome');
        }).trigger('reload_chrome');
Example #7
0
    function navigate(url, params, popped, replaceState) {
        if (!url) return;

        // Terminate any outstanding requests.
        if (last_bobj) {
            last_bobj.terminate();
        }

        var view_url = url;

        // If we're navigating from a hash, just pretend it's a plain old URL.
        if (url.substr(0, 2) == '#!') {
            view_url = url.substr(2);
        }

        console.log('Navigating', view_url);
        var view = views.match(view_url);
        if (view === null) {
            return;
        }

        var bobj = last_bobj = builder.getBuilder();
        view[0](bobj, view[1], params);
        bobj.finish();

        var newState = {
            path: url,
            type: z.context.type,
            title: z.context.title,
            scrollTop: z.doc.scrollTop()
        };
        if (replaceState) {
            history.replaceState(newState, false, url);
        } else {
            history.pushState(newState, false, url);
        }

        z.page.trigger('navigate', [view_url, popped, newState]);
    }
Example #8
0
    z.page.on('reload_chrome', function() {
        console.log('Reloading chrome');
        var context = {z: z};
        $('#site-header').html(
            nunjucks.env.render('header.html', context));
        $('#site-footer').html(
            nunjucks.env.render('footer.html', context));

        if (!window['incompatibility-banner'] &&
                !navigator.mozApps &&
                !navigator.userAgent.match(/googlebot/i)) {
            console.log('Adding incompatibility banner');
            $('#site-nav').after(nunjucks.env.render('incompatible.html'));
        }

        var logged_in = user.logged_in();

        // Wait for the switches to be pulled down.
        consumer_info.promise.then(function () {
            var banner = document.getElementById('fx-accounts-banner');
            if (banner) {
                banner.dismissBanner();
            }
            if (require('fxa_migration').canMigrate()) {
                $('#site-nav').after(
                    nunjucks.env.render('fx-accounts-banner.html',
                                        {logged_in: logged_in}));
            }

            // To show or not to show the recommendations nav.
            if (logged_in && settings.switches.indexOf('recommendations') !== -1) {
                z.body.addClass('show-recommendations');
            }
        });

        z.body.toggleClass('logged-in', logged_in);
        z.page.trigger('reloaded_chrome');
    }).trigger('reload_chrome');
Example #9
0
    function(_) {
        var console = require('log')('mkt');
        console.log('Dependencies resolved, starting init');

        var capabilities = require('capabilities');
        var nunjucks = require('templates');
        var settings = require('settings');
        var z = require('z');

        nunjucks.env.dev = true;

        z.body.addClass('html-' + require('l10n').getDirection());
        if (settings.body_classes) {
            z.body.addClass(settings.body_classes);
        }

        z.page.one('loaded', function() {
            console.log('Hiding splash screen');
            $('#splash-overlay').addClass('hide');
        });

        // This lets you refresh within the app by holding down command + R.
        if (capabilities.chromeless) {
            window.addEventListener('keydown', function(e) {
                if (e.keyCode == 82 && e.metaKey) {
                    window.location.reload();
                }
            });
        }

        var get_installed = function() {
            if (!capabilities.webApps) {
                return;
            }
            z.apps = {};
            z.state.mozApps = {};
            // Get list of installed apps and mark as such.
            var r = navigator.mozApps.getInstalled();
            r.onsuccess = function() {
                _.each(r.result, function(val) {
                    z.apps[val.manifestURL] = z.state.mozApps[val.manifestURL] = val;
                    z.win.trigger('app_install_success',
                                  [val, {'manifest_url': val.manifestURL}, false]);
                });
            };
        };
        var get_installed_debounced = _.debounce(get_installed, 2000, true);  // Immediate so there's no delay.

        z.page.on('loaded', get_installed);
        z.page.on('fragment_loaded loaded_more', get_installed_debounced);

        // Do some last minute template compilation.
        z.page.on('reload_chrome', function() {
            console.log('Reloading chrome');
            var context = _.extend({z: z}, require('helpers'));

            $('#site-header').html(
                nunjucks.env.getTemplate('header.html').render(context));
            $('#site-footer').html(
                nunjucks.env.getTemplate('footer.html').render(context));

            z.body.toggleClass('logged-in', require('user').logged_in());
            z.page.trigger('reloaded_chrome');
        }).trigger('reload_chrome');

        window.addEventListener(
            'resize',
            _.debounce(function() {z.doc.trigger('saferesize');}, 200),
            false
        );

        // Perform initial navigation.
        console.log('Triggering initial navigation');
        z.page.trigger('navigate', [window.location.pathname + window.location.search]);

        // Debug page
        (function() {
            var to = false;
            z.doc.on('touchstart mousedown', '.wordmark', function(e) {
                console.log('hold for debug...', e.type);
                clearTimeout(to);
                to = setTimeout(function() {
                    console.log('navigating to debug...');
                    z.page.trigger('navigate', ['/debug']);
                }, 3000);
            }).on('touchend mouseup', '.wordmark', function(e) {
                console.log('debug hold released...', e.type);
                clearTimeout(to);
            });
        })();

        console.log('Initialization complete');
    });
Example #10
0
 z.page.on('logged_out', function() {
     z.page.trigger('navigate', [urls.reverse('login')]);
 });
Example #11
0
function() {
    var log = require('log');
    var console = log('main');
    console.log('Dependencies resolved, starting init');

    var models = require('models');
    var nunjucks = require('templates');
    var filters = nunjucks.require('filters');
    var helpers = nunjucks.require('globals');
    var urls = require('urls');
    var z = require('z');

    nunjucks.env.dev = true;

    z.body.addClass('html-' + require('l10n').getDirection());

    // Add some helpful functions.
    helpers.COLOR_PATTERN = '#[0-9a-fA-F]{6}';
    helpers.color_cycle = function(alpha) {
        alpha = alpha || 1;
        var cache = {};
        var n = 0;
        return function(value) {
            if (value in cache) return cache[value];
            var h = (Math.pow(n, 2) * 50 + 40) % 349 | 0;
            var l = (n * 49 + 20) % 31 + 40 | 0;
            n++;
            return cache[value] = 'hsla(' + h + ', 50%, ' + l + '%, ' + alpha + ')';
        };
    }
    helpers.model_lookup = function(model, key, by) {
        return models(model).lookup(key, by);
    };
    var regex_chars = '\\()[]{}-.*?!+^$|=';
    // TODO: Consider adding this to commonplace helpers.
    filters.make_regex_safe = function(data) {
        if (typeof data !== 'string') {
            return data;
        }
        for (var i = 0; i < regex_chars.length; i++) {
            data = data.replace(
                new RegExp('\\' + regex_chars[i], 'g'), '\\' + regex_chars[i]);
        }
        return data;
    };

    // Do some last minute template compilation.
    z.page.on('reload_chrome', function() {
        console.log('Reloading chrome');
        var context = {z: z};
        $('#site-header').html(
            nunjucks.env.render('header.html', context));
        $('#site-footer').html(
            nunjucks.env.render('footer.html', context));

        z.body.toggleClass('logged-in', require('user').logged_in());
        z.body.toggleClass('is-curator', require('user').get_permission('curator'));
        z.body.toggleClass('is-not-curator', !require('user').get_permission('curator'));
        z.page.trigger('reloaded_chrome');
    }).trigger('reload_chrome');

    function do_model_cache(model, url) {
        return require('requests').get(url).done(function(data) {
            var cache = models(model);
            console.groupCollapsed('Casting ' + model + 's to model cache...');
            data.objects.forEach(function(obj) {
                cache.cast(obj);
            });
            console.groupEnd();
        });
    }

    console.log('Starting cache pre-filling...');
    require('defer').when(
        do_model_cache('carrier', urls.api.url('carriers')),
        do_model_cache('category', urls.api.url('categories')),
        do_model_cache('region', urls.api.url('regions'))
    ).done(function() {
        // Perform initial navigation.
        console.log('Triggering initial navigation');
        z.page.trigger('navigate', [window.location.pathname + window.location.search]);
    });

    // Add a body class when rocketfuel is disabled.
    if (!require('settings').flags.rocketfuel) {
        z.body.addClass('rocketfuel-disabled');
    }

    // Debug page
    (function() {
        var to = false;
        z.body.on('touchstart mousedown', '.wordmark', function(e) {
            console.log('hold for debug...', e.type);
            clearTimeout(to);
            to = setTimeout(function() {
                console.log('navigating to debug...');
                z.page.trigger('navigate', ['/debug']);
            }, 3000);
        }).on('touchend mouseup', '.wordmark', function(e) {
            console.log('debug hold released...', e.type);
            if (to) {
                e.preventDefault();
                e.stopPropagation();
            }
            clearTimeout(to);
            to = -1; // An impossible timeout, but still truthy.
        }).on('click', '#site-header h1 a', function(e) {
            if (to) {
                e.preventDefault();
                e.stopPropagation();
                return false;
            }
        });
    })();

    console.log('Initialization complete');
});
Example #12
0
    ], function(_) {
        var capabilities = require('capabilities');
        var log = require('log');
        var nunjucks = require('templates');
        var urls = require('urls');
        var user = require('user');
        var z = require('z');

        var console = log('main');
        console.log('Dependencies resolved, starting init');

        // Nunjucks helpers.
        nunjucks.env.dev = true;
        var nunjucks_globals = require('nunjucks').require('globals');
        nunjucks_globals.gravatar = function(gravatar_hash, size) {
            return ('https://secure.gravatar.com/avatar/' + gravatar_hash + '?s=' +
                    (size || 36));
        };

        var settings = require('settings');
        nunjucks_globals.note_action = function(note_type) {
            return settings.note_types[note_type];
        };

        z.body.addClass('html-' + require('l10n').getDirection());

        z.page.one('loaded', function() {
            console.log('Hiding splash screen');
            $('#splash-overlay').addClass('hide');
        });

        // This lets you refresh within the app by holding down command + R.
        if (capabilities.chromeless) {
            window.addEventListener('keydown', function(e) {
                if (e.keyCode == 82 && e.metaKey) {
                    window.location.reload();
                }
            });
        }

        // Do some last minute template compilation.
        z.page.on('reload_chrome', function() {
            console.log('Reloading chrome');
            var context = {z: z};

            $('#site-header').html(
                nunjucks.env.render('header.html', context));
            $('#site-footer').html(
                nunjucks.env.render('footer.html', context));

            // Navigate to the hash if necessary.
            var hash = window.location.hash;
            if (hash.indexOf('show-read') !== -1 || hash.indexOf('show-unread') !== -1) {
                $('.notes-filter[href="' + hash + '"]').trigger('click');
            }

            z.body.toggleClass('logged-in', user.logged_in());
            z.page.trigger('reloaded_chrome');
        }).trigger('reload_chrome');

        z.page.on('logged_in', function() {
            z.page.trigger('navigate', [urls.reverse('comm')]);
        });

        z.page.on('logged_out', function() {
            z.page.trigger('navigate', [urls.reverse('login')]);
        });

        z.body.on('click', '.site-header .back', function(e) {
            e.preventDefault();
            console.log('← button pressed');
            require('navigation').back();
        });

        // Perform initial navigation.
        console.log('Triggering initial navigation');
        if (!user.logged_in() && window.location.pathname != urls.reverse('fxa_authorize')) {
            z.page.trigger('navigate', [urls.reverse('login')]);
        } else if (!z.spaceheater) {
            z.page.trigger('navigate', [window.location.pathname +
                                        window.location.search +
                                        window.location.hash]);
        } else {
            z.page.trigger('loaded');
        }

        // Debug page
        (function() {
            var to = false;
            z.doc.on('touchstart mousedown', '.wordmark', function(e) {
                console.log('hold for debug...', e.type);
                clearTimeout(to);
                to = setTimeout(function() {
                    console.log('navigating to debug...');
                    z.page.trigger('navigate', ['/debug']);
                }, 3000);
            }).on('touchend mouseup', '.wordmark', function(e) {
                console.log('debug hold released...', e.type);
                clearTimeout(to);
            });
        })();

        console.log('Initialization complete');
    });
Example #13
0
function(_) {
    var apps = require('apps');
    var buttons = require('apps_buttons');
    var capabilities = require('capabilities');
    var format = require('format');
    var $ = require('jquery');
    var settings = require('settings');
    var nunjucks = require('templates');
    var urls = require('urls');
    var utils_local = require('utils_local');
    var z = require('z');

    var console = require('log')('mkt');

    // Use Native Persona, if it's available.
    if (capabilities.firefoxOS && 'mozId' in navigator && navigator.mozId !== null) {
        console.log('Native Persona is available');
        window.navigator.id = navigator.id = navigator.mozId;
    }

    if (!capabilities.performance) {
        // Polyfill `performance.now` for PhantomJS.
        // (And don't even bother with `Date.now` because IE.)
        window.performance = {
            now: function() {
                return +new Date();
            }
        };
    }
    var start_time = performance.now();

    console.log('Dependencies resolved, starting init');

    // Jank hack because Persona doesn't allow scripts in the doc iframe.
    // Please just delete it when they don't do that anymore.
    // Note: If this list changes - please change it in webpay too or let #payments know.
    var doc_langs = ['cs', 'de', 'el', 'en-US', 'es', 'hr', 'hu', 'it', 'pl', 'pt-BR', 'sr', 'zh-CN'];
    var doc_lang = doc_langs.indexOf(navigator.l10n.language) >= 0 ? navigator.l10n.language : 'en-US';
    var doc_location = urls.media('/docs/{type}/' + doc_lang + '.html?20140717');
    settings.persona_tos = format.format(doc_location, {type: 'terms'});
    settings.persona_privacy = format.format(doc_location, {type: 'privacy'});

    z.body.addClass('html-' + require('l10n').getDirection());
    if (settings.body_classes) {
        z.body.addClass(settings.body_classes);
    }

    if (!utils_local.isSystemDateRecent()) {
        // System date checking.
        z.body.addClass('error-overlaid')
            .append(nunjucks.env.render('errors/date-error.html'))
            .on('click', '.system-date .try-again', function() {
                if (utils_local.isSystemDateRecent()) {
                    window.location.reload();
                }
            });
    } else {
        utils_local.checkOnline().fail(function() {
            console.log('We are offline. Showing offline message');
            z.body.addClass('error-overlaid')
                .append(nunjucks.env.render('errors/offline-error.html'))
                .on('click', '.offline .try-again', function() {
                    console.log('Re-checking online status');
                    utils_local.checkOnline().done(function(){
                        console.log('Reloading');
                        window.location.reload();
                     }).fail(function() {
                        console.log('Still offline');
                    });
                });
        });
    }

    z.page.one('loaded', function() {
        // Remove the splash screen.
        console.log('Hiding splash screen (' + ((performance.now() - start_time) / 1000).toFixed(6) + 's)');
        var splash = $('#splash-overlay').addClass('hide');
        z.body.removeClass('overlayed').addClass('loaded');
        apps.getInstalled().done(buttons.mark_btns_as_installed);
        setTimeout(function() {
            z.page.trigger('splash_removed');
        }, 1500);
    });

    // This lets you refresh within the app by holding down command + R.
    if (capabilities.chromeless) {
        window.addEventListener('keydown', function(e) {
            if (e.keyCode == 82 && e.metaKey) {
                window.location.reload();
            }
        });
    }

    z.page.on('iframe-loaded', function() {
        // Triggered by apps-iframe-installer.
        apps.getInstalled().done(function() {
            z.page.trigger('mozapps_got_installed');
            buttons.mark_btns_as_installed();
        });
    });

    if (capabilities.webApps) {
        document.addEventListener('visibilitychange', function() {
            if (!document.hidden) {
                // Refresh list of installed apps in case user uninstalled apps
                // and switched back.
                if (require('user').logged_in()) {
                    require('consumer_info').fetch(true);
                }
                apps.getInstalled().done(buttons.mark_btns_as_uninstalled);
            }
        }, false);
    }

    // Do some last minute template compilation.
    z.page.on('reload_chrome', function() {
        console.log('Reloading chrome');
        var context = {z: z};
        $('#site-header').html(
            nunjucks.env.render('header.html', context));
        $('#site-footer').html(
            nunjucks.env.render('footer.html', context));

        if (!navigator.mozApps &&
            !navigator.userAgent.match(/googlebot/i) &&
            !require('storage').getItem('hide_incompatibility_banner')) {
            console.log('Adding incompatibility banner');
            $('#incompatibility-banner').html(
                nunjucks.env.render('incompatible.html'));
            z.body.addClass('show-incompatibility-banner');
        }

        z.body.toggleClass('logged-in', require('user').logged_in());
        z.page.trigger('reloaded_chrome');
    }).trigger('reload_chrome');

    z.page.on('before_login before_logout', function() {
        require('cache').purge();
    });

    z.body.on('click', '.site-header .back', function(e) {
        e.preventDefault();
        console.log('← button pressed');
        require('navigation').back();
    });

    z.body.on('click', '#incompatibility-banner .close', function(e) {
        e.preventDefault();
        console.log('Hiding incompatibility banner');
        z.body.removeClass('show-incompatibility-banner');
        require('storage').setItem('hide_incompatibility_banner', true);
    });

    var ImageDeferrer = require('image-deferrer');
    var iconDeferrer = ImageDeferrer.Deferrer(100, null);
    var screenshotDeferrer = ImageDeferrer.Deferrer(null, 200);
    z.page.one('loaded', function() {
        iconDeferrer.setImages($('.icon.deferred'));
        screenshotDeferrer.setImages($('.screenshot .deferred, .deferred-background'));
    }).on('loaded loaded_more navigate fragment_loaded', function() {
        iconDeferrer.refresh();
        screenshotDeferrer.refresh();
    });
    require('nunjucks').require('globals').imgAlreadyDeferred = function(src) {
        /*
            If an image already has been loaded, we use this helper in case the
            view is triggered to be rebuilt. When pages are rebuilt, we don't
            mark images to be deferred if they have already been loaded.
            This fixes images flashing back to the placeholder image when
            switching between the New and Popular tabs on the home page.
        */
        var iconsLoaded = iconDeferrer.getSrcsAlreadyLoaded();
        var screenshotsLoaded = screenshotDeferrer.getSrcsAlreadyLoaded();
        var loaded = iconsLoaded.concat(screenshotsLoaded);
        return loaded.indexOf(src) !== -1;
    };

    window.addEventListener(
        'resize',
        _.debounce(function() {z.doc.trigger('saferesize');}, 200),
        false
    );

    require('consumer_info').promise.done(function() {
        console.log('Triggering initial navigation');
        if (!z.spaceheater) {
            z.page.trigger('navigate', [window.location.pathname + window.location.search]);
        } else {
            z.page.trigger('loaded');
        }
    });

    // Set the tracking consumer page variable.
    //require('tracking').setVar(3, 'Site section', 'Consumer', 3);

    require('requests').on('deprecated', function() {
        // Divert the user to the deprecated view.
        z.page.trigger('divert', [urls.reverse('deprecated')]);
        throw new Error('Cancel navigation; deprecated client');
    });

    console.log('Initialization complete');
});
Example #14
0
define('navigation', ['require', 'builder', 'utils', 'views', 'z'], function(require) {
    'use strict';

    var _pd = require('utils')._pd;
    var z = require('z');

    var stack = [
        {
            path: '/',
            type: 'root'
        }
    ];
    var param_whitelist = ['q', 'sort', 'cat'];

    function extract_nav_url(url) {
        // This function returns the URL that we should use for navigation.
        // It filters and orders the parameters to make sure that they pass
        // equality tests down the road.

        // If there's no URL params, return the original URL.
        if (url.indexOf('?') < 0) {
            return url;
        }

        var url_parts = url.split('?');
        // If there's nothing after the `?`, return the original URL.
        if (!url_parts[1]) {
            return url;
        }

        var used_params = _.pick(getVars(url_parts[1]), param_whitelist);
        // If there are no query params after we filter, just return the path.
        if (!_.keys(used_params).length) {  // If there are no elements in the object...
            return url_parts[0];  // ...just return the path.
        }

        var param_pairs = _.sortBy(_.pairs(used_params), function(x) {return x[0];});
        return url_parts[0] + '?' + _.map(
            param_pairs,
            function(pair) {
                if (typeof pair[1] === 'undefined')
                    return encodeURIComponent(pair[1]);
                else
                    return encodeURIComponent(pair[0]) + '=' +
                           encodeURIComponent(pair[1]);
            }
        ).join('&');
    }

    z.page.on('navigate', function(e, href, popped, state) {

        if (!state) return;

        // Clean the path's parameters.
        // /foo/bar?foo=bar&q=blah -> /foo/bar?q=blah
        state.path = extract_nav_url(state.path);

        // Truncate any closed navigational loops.
        for (var i=0; i<stack.length; i++) {
            if (stack[i].path === state.path) {
                stack = stack.slice(i+1);
                break;
            }
        }

        // Are we home? clear any history.
        if (state.type == 'root') {
            stack = [state];

            // Also clear any search queries living in the search box.
            // Bug 790009
            $('#search-q').val('');
        } else {
            // handle the back and forward buttons.
            if (popped && stack[0].path === state.path) {
                stack.shift();
            } else {
                stack.unshift(state);
            }

            // Does the page have a parent? If so, handle the parent logic.
            if (z.context.parent) {
                var parent = _.indexOf(_.pluck(stack, 'path'), z.context.parent);

                if (parent > 1) {
                    // The parent is in the stack and it's not immediately
                    // behind the current page in the stack.
                    stack.splice(1, parent - 1);
                    console.log('Closing navigation loop to parent (1 to ' + (parent - 1) + ')');
                } else if (parent == -1) {
                    // The parent isn't in the stack. Splice it in just below
                    // where the value we just pushed in is.
                    stack.splice(1, 0, {path: z.context.parent});
                    console.log('Injecting parent into nav stack at 1');
                }
                console.log('New stack size: ' + stack.length);
            }
        }

        z.page.trigger('page_setup');

    }).on('page_setup', function() {

        setClass();
        setTitle();
        setType();

    });

    var $body = $('body');

    var oldClass = '';
    function setClass() {
        // We so classy.
        var newClass = z.context.bodyclass;
        $body.removeClass(oldClass).addClass(newClass);
        oldClass = newClass;
    }

    function setType() {
        // We so type-y.
        var type = z.context.type;
        z.body.attr('data-page-type', type || 'leaf');
    }

    function setTitle() {
        // Something something title joke.
        var title = z.context.headertitle || '';
        $('#site-header h1.page').text(title);
    }

    function back() {
        // Something something back joke.
        if (stack.length > 1) {
            stack.shift();
            navigate(stack[0].path, stack[0].params);
        } else {
            console.log('attempted nav.back at root!');
        }
    }

    $('.nav-back').on('click', _pd(back));

    var builder = require('builder');
    var views = require('views');

    var last_bobj = null;
    function navigate(url, params, popped, replaceState) {
        if (!url) return;

        // Terminate any outstanding requests.
        if (last_bobj) {
            last_bobj.terminate();
        }

        var view_url = url;

        // If we're navigating from a hash, just pretend it's a plain old URL.
        if (url.substr(0, 2) == '#!') {
            view_url = url.substr(2);
        }

        console.log('Navigating', view_url);
        var view = views.match(view_url);
        if (view === null) {
            return;
        }

        var bobj = last_bobj = builder.getBuilder();
        view[0](bobj, view[1], params);
        bobj.finish();

        var newState = {
            path: url,
            type: z.context.type,
            title: z.context.title,
            scrollTop: z.doc.scrollTop()
        };
        if (replaceState) {
            history.replaceState(newState, false, url);
        } else {
            history.pushState(newState, false, url);
        }

        z.page.trigger('navigate', [view_url, popped, newState]);
    }

    function navigateState(state, popped) {
        navigate(state.path, state.params, popped)
    }

    function navigationFilter(el) {
        var href = el.getAttribute('href') || el.getAttribute('action'),
            $el = $(el);
        return !href || href.substr(0,4) == 'http' ||
                href.substr(0,7) === 'mailto:' ||
                href.substr(0,11) === 'javascript:' ||
                href.substr(0,1) === '#' ||
                href.indexOf('/developers/') !== -1 ||
                href.indexOf('/ecosystem/') !== -1 ||
                href.indexOf('/statistics/') !== -1 ||
                href.indexOf('?modified=') !== -1 ||
                el.getAttribute('target') === '_blank' ||
                el.getAttribute('rel') === 'external' ||
                $el.hasClass('post') || $el.hasClass('sync');
    }

    z.body.on('click', 'a', function(e) {
        var href = this.getAttribute('href');
        if (e.metaKey || e.ctrlKey || e.button !== 0) return;
        if (navigationFilter(this)) return;

        // We don't use _pd because we don't want to prevent default for the
        // above situations.
        e.preventDefault();
        navigate(href, $(this).data('params') || {});
    });
    z.win.on('popstate', function(e) {
        var state = e.originalEvent.state;
        if (state) {
            navigateState(state, true);
        }
    });

    return {
        back: back,
        navigate: navigate,
        oldClass: function() {return oldClass;},
        stack: function() {return stack;},
        navigationFilter: navigationFilter
    };

});
Example #15
0
 ).done(function() {
     // Perform initial navigation.
     console.log('Triggering initial navigation');
     z.page.trigger('navigate', [window.location.pathname + window.location.search]);
 });
Example #16
0
    function(_) {
        var log = require('log');
        var console = log('main');
        console.log('Dependencies resolved, starting init');

        var capabilities = require('capabilities');
        var nunjucks = require('templates');
        var z = require('z');

        // Add one-off filters
        var filters = require('nunjucks').require('filters');
        filters.safeurl = function(obj) {
            if (typeof obj !== 'string') {
                return obj;
            }
             // add slashes where needed, ie. "What's up" -> "What\'s up"
            function addSlashes(str) {
                return (str + '').replace(/[\\"']/g, '\\$&').replace(/\u0000/g, '\\0');
            }
            return addSlashes(obj);
        };
        var dateslib = require('dates');
        filters.relativeDate = function(date) {
            return dateslib.relativeDateString(new Date(date), {
                minUnit: 'm',
            });
        };

        nunjucks.env.dev = true;

        z.body.addClass('html-' + require('l10n').getDirection());

        // This lets you refresh within the app by holding down command + R.
        if (capabilities.chromeless) {
            window.addEventListener('keydown', function(e) {
                if (e.keyCode == 82 && e.metaKey) {
                    window.location.reload();
                }
            });
        }

        // Do some last minute template compilation.
        z.page.on('reload_chrome', function() {
            console.log('Reloading chrome');
            var context = {z: z};
            $('#site-header').html(
                nunjucks.env.render('header.html', context));
            $('#site-footer').html(
                nunjucks.env.render('footer.html', context));

            z.body.toggleClass('logged-in', require('user').logged_in());
            z.page.trigger('reloaded_chrome');
        }).trigger('reload_chrome');

        z.body.on('click', '.site-header .back', function(e) {
            e.preventDefault();
            console.log('← button pressed');
            require('navigation').back();
        });

        // Perform initial navigation.
        console.log('Triggering initial navigation');
        if (!z.spaceheater) {
            z.page.trigger('navigate', [window.location.pathname + window.location.search]);
        } else {
            z.page.trigger('loaded');
        }

        // Debug page
        (function() {
            var to = false;
            z.doc.on('touchstart mousedown', '.wordmark', function(e) {
                console.log('hold for debug...', e.type);
                clearTimeout(to);
                to = setTimeout(function() {
                    console.log('navigating to debug...');
                    z.page.trigger('navigate', ['/debug']);
                }, 3000);
            }).on('touchend mouseup', '.wordmark', function(e) {
                console.log('debug hold released...', e.type);
                clearTimeout(to);
            });
        })();

        console.log('Initialization complete');
    });
Example #17
0
 z.page.on('logged_in', function() {
     z.page.trigger('navigate', [window.location.pathname + window.location.search]);
 });
Example #18
0
    function() {
        var log = require('log');
        var console = log('main');
        console.log('Dependencies resolved, starting init');

        var capabilities = require('capabilities');
        var nunjucks = require('templates');
        var settings = require('settings');
        var z = require('z');

        nunjucks.env.dev = true;

        var nunjucks_globals = require('nunjucks').require('globals');
        nunjucks_globals.user_helpers = require('user_helpers');

        z.body.addClass('html-' + require('l10n').getDirection());

        z.page.one('loaded', function() {
            console.log('Hiding splash screen');
            $('#splash-overlay').addClass('hide');
        });

        // This lets you refresh within the app by holding down command + R.
        if (capabilities.chromeless) {
            window.addEventListener('keydown', function(e) {
                if (e.keyCode == 82 && e.metaKey) {
                    window.location.reload();
                }
            });
        }

        // Do some last minute template compilation.
        z.page.on('reload_chrome', function() {
            console.log('Reloading chrome');
            var context = {z: z, REGIONS: settings.REGION_CHOICES_SLUG};
            $('#site-header').html(
                nunjucks.env.render('header.html', context));
            $('#site-footer').html(
                nunjucks.env.render('footer.html', context));

            z.body.toggleClass('logged-in', require('user').logged_in());
            z.page.trigger('reloaded_chrome');
        }).trigger('reload_chrome');

        z.body.on('click', '.site-header .back', function(e) {
            e.preventDefault();
            console.log('← button pressed');
            require('navigation').back();
        });

        // Perform initial navigation.
        console.log('Triggering initial navigation');
        if (!z.spaceheater) {
            z.page.trigger('navigate', [window.location.pathname + window.location.search]);
        } else {
            z.page.trigger('loaded');
        }

        z.page.on('logged_in', function() {
            z.page.trigger('navigate', [window.location.pathname + window.location.search]);
        });

        // Debug page
        (function() {
            var to = false;
            z.doc.on('touchstart mousedown', '.wordmark', function(e) {
                console.log('hold for debug...', e.type);
                clearTimeout(to);
                to = setTimeout(function() {
                    console.log('navigating to debug...');
                    z.page.trigger('navigate', ['/debug']);
                }, 3000);
            }).on('touchend mouseup', '.wordmark', function(e) {
                console.log('debug hold released...', e.type);
                clearTimeout(to);
            });
        })();

        console.log('Initialization complete');
    });
Example #19
0
function(_) {
    var apps = require('apps');
    var buttons = require('apps_buttons');
    var capabilities = require('capabilities');
    var consumer_info = require('consumer_info');
    var format = require('format');
    var $ = require('jquery');
    var settings = require('settings');
    var siteConfig = require('site_config');
    var l10n = require('l10n');
    var nunjucks = require('templates');
    var regions = require('regions');
    var storage = require('storage');
    var urls = require('urls');
    var user = require('user');
    var utils = require('utils');
    var utils_local = require('utils_local');
    var z = require('z');

    var console = require('log')('mkt');
    var gettext = l10n.gettext;

    // Use Native Persona, if it's available.
    if (capabilities.firefoxOS && 'mozId' in navigator && navigator.mozId !== null) {
        console.log('Native Persona is available');
        window.navigator.id = navigator.id = navigator.mozId;
    }

    var start_time = performance.now();

    console.log('Dependencies resolved, starting init');

    console.log('Package version: ' + (settings.package_version || 'N/A'));

    // Jank hack because Persona doesn't allow scripts in the doc iframe.
    // Please just delete it when they don't do that anymore.
    // Note: If this list changes - please change it in webpay too or let #payments know.
    var doc_langs = ['cs', 'de', 'el', 'en-US', 'es', 'hr', 'hu', 'it', 'pl', 'pt-BR', 'sr', 'zh-CN'];
    var doc_lang = doc_langs.indexOf(navigator.l10n.language) >= 0 ? navigator.l10n.language : 'en-US';
    var doc_location = urls.media('/docs/{type}/' + doc_lang + '.html?20141001');
    settings.persona_tos = format.format(doc_location, {type: 'terms'});
    settings.persona_privacy = format.format(doc_location, {type: 'privacy'});

    z.body.addClass('html-' + l10n.getDirection());

    if (settings.body_classes) {
        z.body.addClass(settings.body_classes);
    }

    if (!utils_local.isSystemDateRecent()) {
        // System date checking.
        z.body.addClass('error-overlaid')
            .append(nunjucks.env.render('errors/date-error.html'))
            .on('click', '.system-date .try-again', function() {
                if (utils_local.isSystemDateRecent()) {
                    window.location.reload();
                }
            });
    } else {
        utils_local.checkOnline().fail(function() {
            console.log('We are offline. Showing offline message');
            z.body.addClass('error-overlaid')
                .append(nunjucks.env.render('errors/offline-error.html'))
                .on('click', '.offline .try-again', function() {
                    console.log('Re-checking online status');
                    utils_local.checkOnline().done(function(){
                        console.log('Reloading');
                        window.location.reload();
                     }).fail(function() {
                        console.log('Still offline');
                    });
                });
        });
    }

    z.page.one('loaded', function() {
        // Remove the splash screen.
        console.log('Hiding splash screen (' + ((performance.now() - start_time) / 1000).toFixed(6) + 's)');
        var splash = $('#splash-overlay').addClass('hide');
        z.body.removeClass('overlayed').addClass('loaded');

        setTimeout(function() {
            z.page.trigger('splash_removed');
        }, 1500);
    });

    // This lets you refresh within the app by holding down command + R.
    if (capabilities.chromeless) {
        window.addEventListener('keydown', function(e) {
            if (e.keyCode == 82 && e.metaKey) {
                window.location.reload();
            }
        });
    }

    if (capabilities.webApps) {
        // Mark installed apps as such and look for a Marketplace update. If we
        // are in a packaged app, wait for the iframe to be loaded, otherwise
        // we are using the direct installer and we just need to wait for the
        // normal loaded event.
        var event_for_apps = window.location.protocol === 'app:' ? 'iframe-install-loaded' : 'loaded';
        z.page.one(event_for_apps, function() {
            apps.getInstalled().done(function() {
                z.page.trigger('mozapps_got_installed');
                buttons.mark_btns_as_installed();
            });


            var manifest_url = settings.manifest_url;
            // Note: only the iframed app defines a manifestURL for now.
            if (manifest_url) {
                apps.checkForUpdate(manifest_url).done(function(result) {
                    if (result) {
                        z.body.on('click', '#marketplace-update-banner a.download-button', utils._pd(function() {
                            var $button = $(this);
                            // Deactivate "remember" on the dismiss button so that it'll
                            // show up for the next update if the user clicks on it now
                            // they chose to apply the update.
                            $button.closest('mkt-banner').get(0).dismiss = '';
                            $button.addClass('spin');
                            apps.applyUpdate(manifest_url).done(function() {
                                $('#marketplace-update-banner span').text(gettext(
                                    'The next time you start the Firefox Marketplace app, you’ll see the updated version!'));
                                $button.remove();
                            });
                        }));
                        $('#site-nav').after(nunjucks.env.render('marketplace-update.html'));
                    }
                });
            }
        });

        document.addEventListener('visibilitychange', function() {
            if (!document.hidden) {
                // Refresh list of installed apps in case user uninstalled apps
                // and switched back.
                if (user.logged_in()) {
                    consumer_info.fetch(true);
                }
                apps.getInstalled().done(buttons.mark_btns_as_uninstalled);
            }
        }, false);
    }

    // Do some last minute template compilation.
    z.page.on('reload_chrome', function() {
        console.log('Reloading chrome');
        var user_helpers = require('user_helpers');
        var context = {
            render_newsletter: !storage.getItem('newsletter-completed'),
            user_region: user_helpers.region('restofworld'),
            user_email: user.get_setting('email'),
            user_lang: user_helpers.lang(),
            z: z
        };
        $('#site-header').html(
            nunjucks.env.render('header.html', context));
        $('#site-footer').html(
            nunjucks.env.render('footer.html', context));

        if (!window['incompatibility-banner'] &&
                !navigator.mozApps &&
                !navigator.userAgent.match(/googlebot/i)) {
            console.log('Adding incompatibility banner');
            $('#site-nav').after(nunjucks.env.render('incompatible.html'));
        }

        var logged_in = user.logged_in();

        if (!logged_in) {
            z.body.removeClass('show-recommendations');
        }

        siteConfig.promise.then(function () {
            if (capabilities.nativeFxA() || capabilities.yulelogFxA()) {
                // We might want to style things differently for native FxA users,
                // specifically they should need to log out through settings instead
                // of through Marketplace (hide logout buttons for bug 1073177).
                // Unfortunately we need to wait for the switches to load.
                z.body.addClass('native-fxa');
            }

            var banner = document.getElementById('fx-accounts-banner');
            if (banner) {
                banner.dismissBanner();
            }
            if (user.canMigrate()) {
                $('#site-nav').after(
                    nunjucks.env.render('fx-accounts-banner.html',
                                        {logged_in: logged_in}));
            }
        });

        // TODO: Move this to the consumer-info callback when the waffle is
        // removed as we no longer require siteConfig for the waffle switch.
        $.when(siteConfig, consumer_info).then(function() {
            // To show or not to show the recommendations nav.
            if (logged_in && user.get_setting('enable_recommendations') &&
                    // TODO: Remove when waffle removed (bug 1083942).
                    settings.switches.indexOf('recommendations') !== -1) {
                z.body.addClass('show-recommendations');
            }
        });

        consumer_info.promise.then(function() {
            // Re-render footer region if necessary.
            var current_region = user_helpers.region('restofworld');
            if (current_region !== context.user_region) {
                console.log('Region has changed from ' + context.user_region +
                            ' to ' + current_region + ' since we rendered ' +
                            'the footer, updating region in footer.');
                $('#site-footer span.region')
                    .removeClass('region-' + context.user_region)
                    .addClass('region-' + current_region)
                    .text(regions.REGION_CHOICES_SLUG[current_region]);
            }
        });

        z.body.toggleClass('logged-in', logged_in);
        z.page.trigger('reloaded_chrome');
    }).trigger('reload_chrome');

    z.page.on('before_login before_logout', function() {
        require('cache').purge();
    });

    z.body.on('click', '.site-header .back', function(e) {
        e.preventDefault();
        console.log('← button pressed');
        require('navigation').back();
    });

    var ImageDeferrer = require('image-deferrer');
    var iconDeferrer = ImageDeferrer.Deferrer(100, null);
    var screenshotDeferrer = ImageDeferrer.Deferrer(null, 200);
    z.page.one('loaded', function() {
        iconDeferrer.setImages($('.icon.deferred'));
        screenshotDeferrer.setImages($('.screenshot .deferred, .deferred-background'));
    }).on('loaded loaded_more navigate fragment_loaded', function() {
        iconDeferrer.refresh();
        screenshotDeferrer.refresh();
    });
    require('nunjucks').require('globals').imgAlreadyDeferred = function(src) {
        /*
            If an image already has been loaded, we use this helper in case the
            view is triggered to be rebuilt. When pages are rebuilt, we don't
            mark images to be deferred if they have already been loaded.
            This fixes images flashing back to the placeholder image when
            switching between the New and Popular tabs on the home page.
        */
        var iconsLoaded = iconDeferrer.getSrcsAlreadyLoaded();
        var screenshotsLoaded = screenshotDeferrer.getSrcsAlreadyLoaded();
        var loaded = iconsLoaded.concat(screenshotsLoaded);
        return loaded.indexOf(src) !== -1;
    };

    window.addEventListener(
        'resize',
        _.debounce(function() {z.doc.trigger('saferesize');}, 200),
        false
    );

    consumer_info.promise.done(function() {
        console.log('Triggering initial navigation');
        if (!z.spaceheater) {
            z.page.trigger('navigate', [window.location.pathname + window.location.search]);
        } else {
            z.page.trigger('loaded');
        }
    });

    require('requests').on('deprecated', function() {
        // Divert the user to the deprecated view.
        z.page.trigger('divert', [urls.reverse('deprecated')]);
        throw new Error('Cancel navigation; deprecated client');
    });

    console.log('Initialization complete');
});
Example #20
0
    z.page.on('reload_chrome', function() {
        console.log('Reloading chrome');
        var user_helpers = require('user_helpers');
        var context = {
            render_newsletter: !storage.getItem('newsletter-completed'),
            user_region: user_helpers.region('restofworld'),
            user_email: user.get_setting('email'),
            user_lang: user_helpers.lang(),
            z: z
        };
        $('#site-header').html(
            nunjucks.env.render('header.html', context));
        $('#site-footer').html(
            nunjucks.env.render('footer.html', context));

        if (!window['incompatibility-banner'] &&
                !navigator.mozApps &&
                !navigator.userAgent.match(/googlebot/i)) {
            console.log('Adding incompatibility banner');
            $('#site-nav').after(nunjucks.env.render('incompatible.html'));
        }

        var logged_in = user.logged_in();

        if (!logged_in) {
            z.body.removeClass('show-recommendations');
        }

        siteConfig.promise.then(function () {
            if (capabilities.nativeFxA() || capabilities.yulelogFxA()) {
                // We might want to style things differently for native FxA users,
                // specifically they should need to log out through settings instead
                // of through Marketplace (hide logout buttons for bug 1073177).
                // Unfortunately we need to wait for the switches to load.
                z.body.addClass('native-fxa');
            }

            var banner = document.getElementById('fx-accounts-banner');
            if (banner) {
                banner.dismissBanner();
            }
            if (user.canMigrate()) {
                $('#site-nav').after(
                    nunjucks.env.render('fx-accounts-banner.html',
                                        {logged_in: logged_in}));
            }
        });

        // TODO: Move this to the consumer-info callback when the waffle is
        // removed as we no longer require siteConfig for the waffle switch.
        $.when(siteConfig, consumer_info).then(function() {
            // To show or not to show the recommendations nav.
            if (logged_in && user.get_setting('enable_recommendations') &&
                    // TODO: Remove when waffle removed (bug 1083942).
                    settings.switches.indexOf('recommendations') !== -1) {
                z.body.addClass('show-recommendations');
            }
        });

        consumer_info.promise.then(function() {
            // Re-render footer region if necessary.
            var current_region = user_helpers.region('restofworld');
            if (current_region !== context.user_region) {
                console.log('Region has changed from ' + context.user_region +
                            ' to ' + current_region + ' since we rendered ' +
                            'the footer, updating region in footer.');
                $('#site-footer span.region')
                    .removeClass('region-' + context.user_region)
                    .addClass('region-' + current_region)
                    .text(regions.REGION_CHOICES_SLUG[current_region]);
            }
        });

        z.body.toggleClass('logged-in', logged_in);
        z.page.trigger('reloaded_chrome');
    }).trigger('reload_chrome');
Example #21
0
function(_) {
    var console = require('log')('mkt');
    console.log('Dependencies resolved, starting init');

    var $ = require('jquery');
    var capabilities = require('capabilities');
    var format = require('format');
    var nunjucks = require('templates');
    var settings = require('settings');
    var z = require('z');

    var nunjucks_globals = require('nunjucks').require('globals');
    nunjucks_globals.REGIONS = settings.REGION_CHOICES_SLUG;
    nunjucks_globals.user_helpers = require('user_helpers');

    // Jank hack because Persona doesn't allow scripts in the doc iframe.
    // Please just delete it when they don't do that anymore.
    // Note: If this list changes - please change it in webpay too or let #payments know.
    var doc_langs = ['el', 'en-US', 'es', 'it', 'pl', 'pt-BR', 'de'];
    var doc_lang = doc_langs.indexOf(navigator.l10n.language) >= 0 ? navigator.l10n.language : 'en-US';
    var doc_location = require('urls').media('/docs/{type}/' + doc_lang + '.html?20131014-4');
    settings.persona_tos = format.format(doc_location, {type: 'terms'});
    settings.persona_privacy = format.format(doc_location, {type: 'privacy'});

    z.body.addClass('html-' + require('l10n').getDirection());

    z.page.one('loaded', function() {
        console.log('Hiding splash screen');
        // Remove the splash screen once it's hidden.
        var splash = $('#splash-overlay').addClass('hide');
        setTimeout(function() {
            splash.remove();
        }, 1500);
    });

    // This lets you refresh within the app by holding down command + R.
    if (capabilities.chromeless) {
        window.addEventListener('keydown', function(e) {
            if (e.keyCode == 82 && e.metaKey) {
                window.location.reload();
            }
        });
    }

    var get_installed = function() {
        // Don't getInstalled if the page isn't visible.
        if (document.hidden) {
            return;
        }
        // Get list of installed apps and mark as such.
        var r = navigator.mozApps.getInstalled();
        r.onsuccess = function() {
            var buttons = require('buttons');

            z.apps = {};
            _.each(r.result, function(val) {
                buttons.buttonInstalled(
                    require('utils').baseurl(val.manifestURL), val);
            });
        };
    };
    if (capabilities.webApps) {
        z.page.on('loaded', get_installed);
        z.page.on('fragment_loaded loaded_more',
                  _.debounce(get_installed, 2000, true));  // No delay.
        document.addEventListener('visibilitychange', function() {
            // Check if apps were uninstalled since switching from Marketplace,
            // and refresh Install buttons if any were.
            if (document.hidden) {
                return;
            }
            require('buttons').revertUninstalled();
        }, false);
    }

    // Do some last minute template compilation.
    z.page.on('reload_chrome', function() {
        console.log('Reloading chrome');
        var context = {z: z};
        $('#site-header').html(
            nunjucks.env.render('header.html', context));
        $('#site-footer').html(
            nunjucks.env.render('footer.html', context));

        if (!navigator.mozApps &&
            !navigator.userAgent.match(/googlebot/i) &&
            !require('storage').getItem('hide_incompatibility_banner')) {
            console.log('Adding incompatibility banner');
            $('#incompatibility-banner').html(
                nunjucks.env.render('incompatible.html'));
            z.body.addClass('show-incompatibility-banner');
        }

        z.body.toggleClass('logged-in', require('user').logged_in());
        z.page.trigger('reloaded_chrome');
    }).trigger('reload_chrome');

    z.page.on('before_login before_logout', function() {
        var cat_url = require('urls').api.url('categories');
        require('cache').purge(function(key) {return key != cat_url;});
    });

    z.body.on('click', '.site-header .back', function(e) {
        e.preventDefault();
        console.log('← button pressed');
        require('navigation').back();
    });

    z.body.on('click', '#incompatibility-banner .close', function(e) {
        e.preventDefault();
        console.log('Hiding incompatibility banner');
        z.body.removeClass('show-incompatibility-banner');
        require('storage').setItem('hide_incompatibility_banner', true);
    });

    window.addEventListener(
        'resize',
        _.debounce(function() {z.doc.trigger('saferesize');}, 200),
        false
    );

    require('consumer_info').done(function() {
        console.log('Triggering initial navigation');
        if (!z.spaceheater) {
            z.page.trigger('navigate', [window.location.pathname + window.location.search]);
        } else {
            z.page.trigger('loaded');
        }
    });

    // Set the tracking consumer page variable.
    //require('tracking').setVar(3, 'Site section', 'Consumer', 3);

    require('requests').on('deprecated', function() {
        // Divert the user to the deprecated view.
        z.page.trigger('divert', [require('urls').reverse('deprecated')]);
        throw new Error('Cancel navigation; deprecated client');
    });

    console.log('Initialization complete');
});
Example #22
0
 }).on('deprecated', function() {
     // Divert the user to the deprecated view.
     z.page.trigger('divert', [require('urls').reverse('deprecated')]);
     throw new Error('Cancel navigation; deprecated client');
 });
Example #23
0
 to = setTimeout(function() {
     console.log('navigating to debug...');
     z.page.trigger('navigate', ['/debug']);
 }, 3000);
Example #24
0
 setTimeout(function() {
     z.page.trigger('splash_removed');
 }, 1500);
Example #25
0
    function(_, helpers) {
        var log = require('log');
        var console = log('mkt');
        console.log('Dependencies resolved, starting init');

        var capabilities = require('capabilities');
        var format = require('format');
        var nunjucks = require('templates');
        var settings = require('settings');
        var user = require('user');
        var z = require('z');

        helpers.REGIONS = settings.REGION_CHOICES_SLUG;

        // Jank hack because Persona doesn't allow scripts in the doc iframe.
        // Please just delete it when they don't do that anymore.
        var doc_langs = ['el', 'en-US', 'es', 'pl', 'pt-BR'];
        var doc_lang = doc_langs.indexOf(navigator.l10n.language) >= 0 ? navigator.l10n.language : 'en-US';
        var doc_location = require('urls').media('/docs/{type}/' + doc_lang + '.html?20131014-4');
        settings.persona_tos = format.format(doc_location, {type: 'terms'});
        settings.persona_privacy = format.format(doc_location, {type: 'privacy'});

        nunjucks.env.dev = true;

        z.body.addClass('html-' + require('l10n').getDirection());
        if (settings.body_classes) {
            z.body.addClass(settings.body_classes);
        }

        z.page.one('loaded', function() {
            console.log('Hiding splash screen');
            var splash = $('#splash-overlay').addClass('hide');
            // Remove the splash screen once it's visible.
            setTimeout(function() {
                splash.remove();
            }, 1500);
        });

        // This lets you refresh within the app by holding down command + R.
        if (capabilities.chromeless) {
            window.addEventListener('keydown', function(e) {
                if (e.keyCode == 82 && e.metaKey) {
                    window.location.reload();
                }
            });
        }

        var get_installed = function() {
            // Don't getInstalled if the page isn't visible.
            if (document.hidden) {
                return;
            }
            // Get list of installed apps and mark as such.
            var r = navigator.mozApps.getInstalled();
            r.onsuccess = function() {
                var buttons = require('buttons');
                z.apps = {};
                _.each(r.result, function(val) {
                    buttons.buttonInstalled(val.manifestURL.split('?')[0], val);
                });
            };
        };
        if (capabilities.webApps) {
            var get_installed_debounced = _.debounce(get_installed, 2000, true);  // Immediate so there's no delay.

            z.page.on('loaded', get_installed);
            z.page.on('fragment_loaded loaded_more', get_installed_debounced);
            document.addEventListener(
                'visibilitychange',
                function() {
                    if (document.hidden) {
                        return;
                    }
                    require('views').reload();
                },
                false
            );
        }

        // Do some last minute template compilation.
        z.page.on('reload_chrome', function() {
            console.log('Reloading chrome');
            var context = {z: z};
            $('#site-header').html(
                nunjucks.env.getTemplate('header.html').render(context));
            $('#site-footer').html(
                nunjucks.env.getTemplate('footer.html').render(context));

            if (!navigator.mozApps &&
                !require('storage').getItem('hide_incompatibility_banner')) {
                console.log('Adding incompatibility banner');
                $('#incompatibility-banner').html(
                    nunjucks.env.getTemplate(
                        'incompatible.html').render(context));
                z.body.addClass('show-incompatibility-banner');
            }

            z.body.toggleClass('logged-in', require('user').logged_in());
            z.page.trigger('reloaded_chrome');
        }).trigger('reload_chrome');

        z.page.on('before_login before_logout', function() {
            var cat_url = require('urls').api.url('categories');
            require('cache').purge(function(key) {return key != cat_url;});
        });

        z.body.on('click', '.site-header .back', function(e) {
            e.preventDefault();
            console.log('← button pressed');
            require('navigation').back();
        });

        z.body.on('click', '#incompatibility-banner .close', function(e) {
            e.preventDefault();
            console.log('Hiding incompatibility banner');
            z.body.removeClass('show-incompatibility-banner');
            require('storage').setItem('hide_incompatibility_banner', true);
        });

        window.addEventListener(
            'resize',
            _.debounce(function() {z.doc.trigger('saferesize');}, 200),
            false
        );

        // Perform initial navigation.
        console.log('Triggering initial navigation');
        if (!z.spaceheater) {
            z.page.trigger('navigate', [window.location.pathname + window.location.search]);
        } else {
            z.page.trigger('loaded');
        }

        // Set the tracking consumer page variable.
        //require('tracking').setVar(3, 'Site section', 'Consumer', 3);

        // Debug page
        (function() {
            var to = false;
            z.doc.on('touchstart mousedown', '.wordmark', function(e) {
                console.log('hold for debug...', e.type);
                clearTimeout(to);
                to = setTimeout(function() {
                    console.log('navigating to debug...');
                    z.page.trigger('navigate', ['/debug']);
                }, 3000);
            }).on('touchend mouseup', '.wordmark', function(e) {
                console.log('debug hold released...', e.type);
                clearTimeout(to);
            });
        })();

        require('requests').on('success', function(_, xhr) {
            var filter_header;
            try {
                if ((!user.get_setting('region') || user.get_setting('region') == 'internet') &&
                    (filter_header = xhr.getResponseHeader('API-Filter'))) {
                    var region = require('utils').getVars(filter_header).region;
                    log.persistent('mobilenetwork', 'change').log('API overriding region:', region);
                    user.update_settings({region: region});
                }
            } catch(e) {}
        }).on('deprecated', function() {
            // Divert the user to the deprecated view.
            z.page.trigger('divert', [require('urls').reverse('deprecated')]);
            throw new Error('Cancel navigation; deprecated client');
        });

        console.log('Initialization complete');
    });
Example #26
0
 apps.getInstalled().done(function() {
     z.page.trigger('mozapps_got_installed');
     buttons.mark_btns_as_installed();
 });