Merge pull request #484 from gvn/pretty
Automating code style enforcement, stricter JSHint, cleaned existing codebase
This commit is contained in:
Коммит
cb49fc6738
|
@ -1,3 +1,4 @@
|
|||
TODO.txt
|
||||
node_modules/
|
||||
bower_components/
|
||||
.env
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"indent_size": 2,
|
||||
"indent_char": " ",
|
||||
"indent_level": 0,
|
||||
"indent_with_tabs": false,
|
||||
"preserve_newlines": true,
|
||||
"max_preserve_newlines": 2,
|
||||
"jslint_happy": true,
|
||||
"brace_style": "collapse",
|
||||
"keep_array_indentation": false,
|
||||
"keep_function_indentation": false,
|
||||
"space_before_conditional": true,
|
||||
"break_chained_methods": false,
|
||||
"eval_code": false,
|
||||
"unescape_strings": false,
|
||||
"wrap_line_length": 0
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"globals": {
|
||||
"module": true,
|
||||
"define": true,
|
||||
"requirejs": true,
|
||||
"require": true,
|
||||
"Packery": true
|
||||
},
|
||||
"bitwise": true,
|
||||
"curly": true,
|
||||
"eqeqeq": true,
|
||||
"freeze": true,
|
||||
"immed": true,
|
||||
"indent": 2,
|
||||
"latedef": true,
|
||||
"newcap": true,
|
||||
"noempty": true,
|
||||
"nonew": true,
|
||||
"trailing": true,
|
||||
"undef": true
|
||||
}
|
85
Gruntfile.js
85
Gruntfile.js
|
@ -1,7 +1,37 @@
|
|||
module.exports = function( grunt ) {
|
||||
grunt.initConfig({
|
||||
pkg: grunt.file.readJSON( "package.json" ),
|
||||
module.exports = function (grunt) {
|
||||
// Node and client side JS have slightly different JSHint directives
|
||||
// We'll create 2 versions with .jshintrc as a baseline
|
||||
var browserJSHint = grunt.file.readJSON('.jshintrc');
|
||||
var nodeJSHint = {};
|
||||
|
||||
// Create a copy of browserJSHint
|
||||
for (var prop in browserJSHint) {
|
||||
nodeJSHint[prop] = browserJSHint[prop];
|
||||
}
|
||||
|
||||
// Don't throw errors for expected Node globals
|
||||
nodeJSHint.node = true;
|
||||
|
||||
// Don't throw errors for expected browser globals
|
||||
browserJSHint.browser = true;
|
||||
|
||||
var clientSideJS = [
|
||||
'public/js/**/*.js',
|
||||
'!public/js/lib/**'
|
||||
];
|
||||
|
||||
var nodeJS = [
|
||||
'Gruntfile.js',
|
||||
'app.js',
|
||||
'lib/**/*.js',
|
||||
'!lib/events/**',
|
||||
'routes/**/*.js'
|
||||
];
|
||||
|
||||
var allJS = clientSideJS.concat(nodeJS);
|
||||
|
||||
grunt.initConfig({
|
||||
pkg: grunt.file.readJSON('package.json'),
|
||||
recess: {
|
||||
dist: {
|
||||
options: {
|
||||
|
@ -12,27 +42,46 @@ module.exports = function( grunt ) {
|
|||
strictPropertyOrder: false
|
||||
},
|
||||
src: [
|
||||
"public/css/style.less",
|
||||
"public/css/make-details.less"
|
||||
'public/css/style.less',
|
||||
'public/css/make-details.less'
|
||||
]
|
||||
}
|
||||
},
|
||||
jsbeautifier: {
|
||||
modify: {
|
||||
src: allJS,
|
||||
options: {
|
||||
config: '.jsbeautifyrc'
|
||||
}
|
||||
},
|
||||
verify: {
|
||||
src: allJS,
|
||||
options: {
|
||||
mode: 'VERIFY_ONLY',
|
||||
config: '.jsbeautifyrc'
|
||||
}
|
||||
}
|
||||
},
|
||||
jshint: {
|
||||
files: [
|
||||
"Gruntfile.js",
|
||||
"app.js",
|
||||
"lib/**/*.js",
|
||||
"package.json",
|
||||
"public/js/**/*.js",
|
||||
"!public/js/lib/**",
|
||||
"!lib/events/**",
|
||||
"routes/**/*.js"
|
||||
]
|
||||
browser: {
|
||||
src: clientSideJS,
|
||||
options: browserJSHint
|
||||
},
|
||||
node: {
|
||||
src: nodeJS,
|
||||
options: nodeJSHint
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
grunt.loadNpmTasks( "grunt-recess" );
|
||||
grunt.loadNpmTasks( "grunt-contrib-jshint" );
|
||||
grunt.loadNpmTasks('grunt-recess');
|
||||
grunt.loadNpmTasks('grunt-jsbeautifier');
|
||||
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||
|
||||
// Verify code
|
||||
grunt.registerTask('default', ['recess', 'jsbeautifier:verify', 'jshint']);
|
||||
|
||||
// Clean code (Run before commit)
|
||||
grunt.registerTask('clean', ['jsbeautifier:modify', 'jshint']);
|
||||
|
||||
grunt.registerTask( "default", [ "recess", "jshint" ]);
|
||||
};
|
||||
|
|
317
app.js
317
app.js
|
@ -1,30 +1,32 @@
|
|||
if ( process.env.NEW_RELIC_HOME ) {
|
||||
require( 'newrelic' );
|
||||
/* global log, LOG_CRIT, LOG_ERR */
|
||||
|
||||
if (process.env.NEW_RELIC_HOME) {
|
||||
require('newrelic');
|
||||
}
|
||||
|
||||
var express = require( "express" ),
|
||||
domain = require( "domain" ),
|
||||
cluster = require( "cluster" ),
|
||||
habitat = require( "habitat" ),
|
||||
helmet = require( "helmet" ),
|
||||
nunjucks = require( "nunjucks" ),
|
||||
path = require( "path" ),
|
||||
lessMiddleWare = require( "less-middleware" ),
|
||||
i18n = require( "webmaker-i18n" ),
|
||||
navigation = require( "./navigation" );
|
||||
var express = require("express"),
|
||||
domain = require("domain"),
|
||||
cluster = require("cluster"),
|
||||
habitat = require("habitat"),
|
||||
helmet = require("helmet"),
|
||||
nunjucks = require("nunjucks"),
|
||||
path = require("path"),
|
||||
lessMiddleWare = require("less-middleware"),
|
||||
i18n = require("webmaker-i18n"),
|
||||
navigation = require("./navigation");
|
||||
|
||||
habitat.load();
|
||||
|
||||
var app = express(),
|
||||
env = new habitat(),
|
||||
nunjucksEnv = new nunjucks.Environment( new nunjucks.FileSystemLoader( path.join( __dirname, 'views' )), {
|
||||
autoescape: true
|
||||
}),
|
||||
NODE_ENV = env.get( "NODE_ENV" ),
|
||||
WWW_ROOT = path.resolve( __dirname, "public" ),
|
||||
server;
|
||||
env = new habitat(),
|
||||
nunjucksEnv = new nunjucks.Environment(new nunjucks.FileSystemLoader(path.join(__dirname, 'views')), {
|
||||
autoescape: true
|
||||
}),
|
||||
NODE_ENV = env.get("NODE_ENV"),
|
||||
WWW_ROOT = path.resolve(__dirname, "public"),
|
||||
server;
|
||||
|
||||
nunjucksEnv.addFilter("instantiate", function(input) {
|
||||
nunjucksEnv.addFilter("instantiate", function (input) {
|
||||
var tmpl = new nunjucks.Template(input);
|
||||
return tmpl.render(this.getVariables());
|
||||
});
|
||||
|
@ -35,13 +37,13 @@ nunjucksEnv.addFilter("instantiate", function(input) {
|
|||
// if the key name is "some input": "My name is {{name}}"
|
||||
// tmpl.render(localVar) will try to render it with the available variable from the
|
||||
// `localVar` object and return something like `My name is Ali`
|
||||
nunjucksEnv.addFilter("localVar", function(input, localVar) {
|
||||
nunjucksEnv.addFilter("localVar", function (input, localVar) {
|
||||
var tmpl = new nunjucks.Template(input);
|
||||
return tmpl.render(localVar);
|
||||
});
|
||||
|
||||
// Make the client-side gettext possible!!
|
||||
nunjucksEnv.addFilter("gettext", function(string) {
|
||||
nunjucksEnv.addFilter("gettext", function (string) {
|
||||
return this.lookup('gettext')(string);
|
||||
});
|
||||
|
||||
|
@ -61,162 +63,165 @@ nunjucksEnv.addFilter("getSection", function (pageId) {
|
|||
return "";
|
||||
});
|
||||
|
||||
if ( !( env.get( "MAKE_ENDPOINT" ) && env.get( "MAKE_PRIVATEKEY" ) && env.get( "MAKE_PUBLICKEY" ) ) ) {
|
||||
throw new Error( "MakeAPI Config setting invalid or missing!" );
|
||||
if (!(env.get("MAKE_ENDPOINT") && env.get("MAKE_PRIVATEKEY") && env.get("MAKE_PUBLICKEY"))) {
|
||||
throw new Error("MakeAPI Config setting invalid or missing!");
|
||||
}
|
||||
|
||||
// Initialize make client so it is available to other modules
|
||||
require("./lib/makeapi")({
|
||||
apiURL: env.get( "MAKE_ENDPOINT" ),
|
||||
apiURL: env.get("MAKE_ENDPOINT"),
|
||||
hawk: {
|
||||
key: env.get( "MAKE_PRIVATEKEY" ),
|
||||
id: env.get( "MAKE_PUBLICKEY" ),
|
||||
key: env.get("MAKE_PRIVATEKEY"),
|
||||
id: env.get("MAKE_PUBLICKEY"),
|
||||
algorithm: "sha256"
|
||||
}
|
||||
});
|
||||
|
||||
var routes = require("./routes");
|
||||
|
||||
nunjucksEnv.express( app );
|
||||
app.disable( "x-powered-by" );
|
||||
nunjucksEnv.express(app);
|
||||
app.disable("x-powered-by");
|
||||
|
||||
app.use( express.logger( NODE_ENV === "development" ? "dev" : "" ) );
|
||||
if ( !!env.get( "FORCE_SSL" ) ) {
|
||||
app.use( helmet.hsts() );
|
||||
app.enable( "trust proxy" );
|
||||
app.use(express.logger(NODE_ENV === "development" ? "dev" : ""));
|
||||
if ( !! env.get("FORCE_SSL")) {
|
||||
app.use(helmet.hsts());
|
||||
app.enable("trust proxy");
|
||||
}
|
||||
|
||||
/**
|
||||
* Crash isolation and error handling, logging
|
||||
*/
|
||||
if ( env.get( "GRAYLOG_HOST" ) ) {
|
||||
GLOBAL.graylogHost = env.get( "GRAYLOG_HOST" );
|
||||
GLOBAL.graylogFacility = env.get( "GRAYLOG_FACILITY" );
|
||||
require( "graylog" );
|
||||
if (env.get("GRAYLOG_HOST")) {
|
||||
GLOBAL.graylogHost = env.get("GRAYLOG_HOST");
|
||||
GLOBAL.graylogFacility = env.get("GRAYLOG_FACILITY");
|
||||
require("graylog");
|
||||
}
|
||||
function reportError( error, isFatal ) {
|
||||
|
||||
function reportError(error, isFatal) {
|
||||
try {
|
||||
var severity = isFatal ? "CRASH" : "ERROR";
|
||||
console.error( severity + ": " + error.stack );
|
||||
if ( !GLOBAL.graylogHost ) {
|
||||
console.error(severity + ": " + error.stack);
|
||||
if (!GLOBAL.graylogHost) {
|
||||
return;
|
||||
}
|
||||
log( "[" + severity + "] webmaker.org failure.",
|
||||
error.message,
|
||||
{
|
||||
log("[" + severity + "] webmaker.org failure.",
|
||||
error.message, {
|
||||
level: isFatal ? LOG_CRIT : LOG_ERR,
|
||||
stack: error.stack,
|
||||
_fullStack: error.stack
|
||||
}
|
||||
);
|
||||
} catch( err ) {
|
||||
console.error( "Internal Error: unable to report error to graylog, err=" + err );
|
||||
} catch (err) {
|
||||
console.error("Internal Error: unable to report error to graylog, err=" + err);
|
||||
}
|
||||
}
|
||||
|
||||
app.use( function( req, res, next ) {
|
||||
app.use(function (req, res, next) {
|
||||
var guard = domain.create();
|
||||
guard.add( req );
|
||||
guard.add( res );
|
||||
guard.add(req);
|
||||
guard.add(res);
|
||||
|
||||
// Safely run a function in error isolation
|
||||
function isolate( fn ) {
|
||||
|
||||
function isolate(fn) {
|
||||
try {
|
||||
fn();
|
||||
} catch( e ) {
|
||||
console.error( 'Internal error isolating shutdown sequence: ' + e );
|
||||
} catch (e) {
|
||||
console.error('Internal error isolating shutdown sequence: ' + e);
|
||||
}
|
||||
}
|
||||
|
||||
guard.on( 'error', function( err ) {
|
||||
guard.on('error', function (err) {
|
||||
try {
|
||||
// Make sure we close down within 15 seconds
|
||||
var killtimer = setTimeout( function() {
|
||||
process.exit( 1 );
|
||||
var killtimer = setTimeout(function () {
|
||||
process.exit(1);
|
||||
}, 15000);
|
||||
// But don't keep the process open just for that!
|
||||
killtimer.unref();
|
||||
|
||||
// Try and report this crash to graylog
|
||||
reportError( err, true );
|
||||
reportError(err, true);
|
||||
|
||||
// Try and shutdown the server, cluster worker
|
||||
isolate(function() {
|
||||
isolate(function () {
|
||||
server.close();
|
||||
if ( cluster.worker ) {
|
||||
if (cluster.worker) {
|
||||
cluster.worker.disconnect();
|
||||
}
|
||||
});
|
||||
|
||||
// Try sending a pretty 500 to the user
|
||||
isolate(function() {
|
||||
isolate(function () {
|
||||
if (res._headerSent || res.finished) {
|
||||
return;
|
||||
}
|
||||
|
||||
res.statusCode = 500;
|
||||
res.render( 'error.html', { message: err.message, code: err.status });
|
||||
res.render('error.html', {
|
||||
message: err.message,
|
||||
code: err.status
|
||||
});
|
||||
});
|
||||
|
||||
guard.dispose();
|
||||
} catch( err2 ) {
|
||||
console.error( 'Internal error shutting down domain: ', err2.stack );
|
||||
} catch (err2) {
|
||||
console.error('Internal error shutting down domain: ', err2.stack);
|
||||
}
|
||||
|
||||
process.exit( 1 );
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
guard.run( next );
|
||||
guard.run(next);
|
||||
});
|
||||
|
||||
|
||||
app.use( express.compress() );
|
||||
app.use( express.static( WWW_ROOT ));
|
||||
app.use( "/bower", express.static( path.join(__dirname, "bower_components" )));
|
||||
app.use(express.compress());
|
||||
app.use(express.static(WWW_ROOT));
|
||||
app.use("/bower", express.static(path.join(__dirname, "bower_components")));
|
||||
|
||||
// List of supported languages - Please add them here in an alphabetical order
|
||||
var listDropdownLang = env.get( "SUPPORTED_LANGS" ),
|
||||
// We create another array based on listDropdownLang to use it in the i18n.middleware
|
||||
// supported_language which will be modified from the i18n mapping function
|
||||
supportedLanguages = listDropdownLang.slice(0);
|
||||
var listDropdownLang = env.get("SUPPORTED_LANGS"),
|
||||
// We create another array based on listDropdownLang to use it in the i18n.middleware
|
||||
// supported_language which will be modified from the i18n mapping function
|
||||
supportedLanguages = listDropdownLang.slice(0);
|
||||
|
||||
// Setup locales with i18n
|
||||
app.use( i18n.middleware({
|
||||
app.use(i18n.middleware({
|
||||
supported_languages: supportedLanguages,
|
||||
default_lang: "en-US",
|
||||
mappings: env.get( "LANG_MAPPINGS" ),
|
||||
translation_directory: path.resolve( __dirname, "locale" )
|
||||
mappings: env.get("LANG_MAPPINGS"),
|
||||
translation_directory: path.resolve(__dirname, "locale")
|
||||
}));
|
||||
|
||||
app.use( express.json() );
|
||||
app.use( express.urlencoded() );
|
||||
app.use( express.cookieParser() );
|
||||
app.use( express.cookieSession({
|
||||
app.use(express.json());
|
||||
app.use(express.urlencoded());
|
||||
app.use(express.cookieParser());
|
||||
app.use(express.cookieSession({
|
||||
key: "webmaker.sid",
|
||||
secret: env.get( "SESSION_SECRET" ),
|
||||
secret: env.get("SESSION_SECRET"),
|
||||
cookie: {
|
||||
maxAge: 2678400000, // 31 days. Persona saves session data for 1 month
|
||||
secure: !!env.get( "FORCE_SSL" )
|
||||
secure: !! env.get("FORCE_SSL")
|
||||
},
|
||||
proxy: true
|
||||
}));
|
||||
app.use( express.csrf() );
|
||||
app.use(express.csrf());
|
||||
|
||||
app.locals({
|
||||
makeEndpoint: env.get( "MAKE_ENDPOINT" ),
|
||||
personaSSO: env.get( "AUDIENCE" ),
|
||||
loginAPI: env.get( "LOGIN" ),
|
||||
ga_account: env.get( "GA_ACCOUNT" ),
|
||||
ga_domain: env.get( "GA_DOMAIN" ),
|
||||
makeEndpoint: env.get("MAKE_ENDPOINT"),
|
||||
personaSSO: env.get("AUDIENCE"),
|
||||
loginAPI: env.get("LOGIN"),
|
||||
ga_account: env.get("GA_ACCOUNT"),
|
||||
ga_domain: env.get("GA_DOMAIN"),
|
||||
supportedLanguages: supportedLanguages,
|
||||
listDropdownLang: listDropdownLang,
|
||||
PROFILE_URL: env.get( "PROFILE_URL" )
|
||||
PROFILE_URL: env.get("PROFILE_URL")
|
||||
});
|
||||
|
||||
app.use(function( req, res, next ) {
|
||||
app.use(function (req, res, next) {
|
||||
res.locals({
|
||||
email: req.session.email || '',
|
||||
username: req.session.username|| '',
|
||||
username: req.session.username || '',
|
||||
makerID: req.session.id || '',
|
||||
csrf: req.session._csrf,
|
||||
navigation: navigation,
|
||||
|
@ -225,11 +230,11 @@ app.use(function( req, res, next ) {
|
|||
next();
|
||||
});
|
||||
|
||||
require( "./lib/events" ).init( app, nunjucksEnv, __dirname );
|
||||
require("./lib/events").init(app, nunjucksEnv, __dirname);
|
||||
|
||||
var optimize = NODE_ENV !== "development",
|
||||
tmpDir = path.join( require( "os" ).tmpDir(), "mozilla.webmaker.org" );
|
||||
app.use( lessMiddleWare({
|
||||
tmpDir = path.join(require("os").tmpDir(), "mozilla.webmaker.org");
|
||||
app.use(lessMiddleWare({
|
||||
once: optimize,
|
||||
debug: !optimize,
|
||||
dest: tmpDir,
|
||||
|
@ -238,139 +243,143 @@ app.use( lessMiddleWare({
|
|||
yuicompress: optimize,
|
||||
optimization: optimize ? 0 : 2
|
||||
}));
|
||||
app.use( express.static( tmpDir ) );
|
||||
app.use(express.static(tmpDir));
|
||||
|
||||
// Nunjucks
|
||||
// This just uses nunjucks-dev for now -- middleware to handle compiling templates in progress
|
||||
app.use( "/views", express.static(path.join( __dirname, "views" ) ) );
|
||||
app.use("/views", express.static(path.join(__dirname, "views")));
|
||||
|
||||
app.use( app.router );
|
||||
app.use(app.router);
|
||||
// We've run out of known routes, 404
|
||||
app.use( function( req, res, next ) {
|
||||
res.status( 404 );
|
||||
res.render( 'error.html', { code: 404 });
|
||||
app.use(function (req, res, next) {
|
||||
res.status(404);
|
||||
res.render('error.html', {
|
||||
code: 404
|
||||
});
|
||||
});
|
||||
// Final error-handling middleware
|
||||
app.use( function( err, req, res, next) {
|
||||
app.use(function (err, req, res, next) {
|
||||
err.status = err.status || 500;
|
||||
reportError( err );
|
||||
res.status( err.status );
|
||||
res.render( 'error.html', { message: err.message, code: err.status });
|
||||
reportError(err);
|
||||
res.status(err.status);
|
||||
res.render('error.html', {
|
||||
message: err.message,
|
||||
code: err.status
|
||||
});
|
||||
});
|
||||
|
||||
require( "./lib/loginapi" )( app, {
|
||||
loginURL: env.get( "LOGINAPI" ),
|
||||
audience: env.get( "AUDIENCE" ),
|
||||
verifierURI: env.get( "PERSONA_VERIFIER_URI" )
|
||||
require("./lib/loginapi")(app, {
|
||||
loginURL: env.get("LOGINAPI"),
|
||||
audience: env.get("AUDIENCE"),
|
||||
verifierURI: env.get("PERSONA_VERIFIER_URI")
|
||||
});
|
||||
|
||||
var middleware = require( "./lib/middleware" );
|
||||
var middleware = require("./lib/middleware");
|
||||
|
||||
// ROUTES
|
||||
var useNewHomePage = env.get("NEW_HOME_PAGE");
|
||||
var teachTheWebRoute;
|
||||
|
||||
app.get( "/healthcheck", routes.api.healthcheck );
|
||||
app.get("/healthcheck", routes.api.healthcheck);
|
||||
|
||||
if ( useNewHomePage ) {
|
||||
if (useNewHomePage) {
|
||||
teachTheWebRoute = "/";
|
||||
} else {
|
||||
teachTheWebRoute = "/teachtheweb";
|
||||
app.get( "/", routes.gallery({
|
||||
app.get("/", routes.gallery({
|
||||
layout: "index",
|
||||
prefix: "p"
|
||||
}));
|
||||
}
|
||||
|
||||
app.get( "/gallery", routes.gallery({
|
||||
app.get("/gallery", routes.gallery({
|
||||
layout: "index",
|
||||
prefix: "p"
|
||||
}));
|
||||
|
||||
app.get( teachTheWebRoute, routes.gallery({
|
||||
app.get(teachTheWebRoute, routes.gallery({
|
||||
layout: "teachtheweb",
|
||||
prefix: "frontpage",
|
||||
limit: 10
|
||||
}));
|
||||
|
||||
app.get( "/editor", middleware.checkAdmin, routes.gallery({
|
||||
app.get("/editor", middleware.checkAdmin, routes.gallery({
|
||||
page: "editor"
|
||||
}));
|
||||
app.get( "/about", routes.page( "about" ) );
|
||||
app.get( "/teach", routes.gallery({
|
||||
app.get("/about", routes.page("about"));
|
||||
app.get("/teach", routes.gallery({
|
||||
layout: "teach",
|
||||
prefix: "teach"
|
||||
}));
|
||||
app.get( "/starter-makes", routes.gallery({
|
||||
app.get("/starter-makes", routes.gallery({
|
||||
layout: "starterMakes",
|
||||
prefix: "template",
|
||||
limit: 20
|
||||
}));
|
||||
|
||||
app.get("/party", routes.page("party"));
|
||||
app.get("/tools", routes.page("tools"));
|
||||
app.get("/teach-templates", routes.page("teach-templates"));
|
||||
app.get("/mentor", routes.page("mentor"));
|
||||
app.get("/getinvolved", routes.page("getinvolved"));
|
||||
app.get("/event-guides", routes.page("event-guides"));
|
||||
app.get("/search", routes.search);
|
||||
app.get("/feedback", routes.page("feedback"));
|
||||
app.get("/standard", routes.page("standard"));
|
||||
app.get("/standard/exploring", routes.page("standard-exploring"));
|
||||
app.get("/standard/building", routes.page("standard-building"));
|
||||
app.get("/standard/connecting", routes.page("standard-connecting"));
|
||||
app.get("/style-guide", routes.page("style-guide"));
|
||||
|
||||
app.get( "/party", routes.page( "party" ) );
|
||||
app.get( "/tools", routes.page( "tools" ) );
|
||||
app.get( "/teach-templates", routes.page( "teach-templates") );
|
||||
app.get( "/mentor", routes.page( "mentor" ) );
|
||||
app.get( "/getinvolved", routes.page( "getinvolved" ) );
|
||||
app.get( "/event-guides", routes.page( "event-guides" ) );
|
||||
app.get( "/search", routes.search );
|
||||
app.get( "/feedback", routes.page( "feedback" ) );
|
||||
app.get( "/standard", routes.page( "standard" ) );
|
||||
app.get( "/standard/exploring", routes.page( "standard-exploring" ) );
|
||||
app.get( "/standard/building", routes.page( "standard-building" ) );
|
||||
app.get( "/standard/connecting", routes.page( "standard-connecting" ) );
|
||||
app.get( "/style-guide", routes.page( "style-guide" ) );
|
||||
|
||||
app.get( "/details", routes.details );
|
||||
app.get("/details", routes.details);
|
||||
// Old
|
||||
app.get( "/details/:id", function(req,res) {
|
||||
app.get("/details/:id", function (req, res) {
|
||||
res.redirect("/details?id=" + req.params.id);
|
||||
});
|
||||
|
||||
app.get( "/me", routes.me );
|
||||
app.get("/me", routes.me);
|
||||
// Old
|
||||
app.get( "/myprojects", routes.me );
|
||||
app.post( "/remove", routes.remove );
|
||||
app.post( "/like", routes.like.like );
|
||||
app.post( "/unlike", routes.like.unlike );
|
||||
app.get("/myprojects", routes.me);
|
||||
app.post("/remove", routes.remove);
|
||||
app.post("/like", routes.like.like);
|
||||
app.post("/unlike", routes.like.unlike);
|
||||
|
||||
// Account
|
||||
app.get( "/login", routes.user.login );
|
||||
app.get( "/new", routes.user.newaccount );
|
||||
app.get("/login", routes.user.login);
|
||||
app.get("/new", routes.user.newaccount);
|
||||
|
||||
app.get( "/t/:tag", routes.tag );
|
||||
app.get( "/u/:user", routes.usersearch );
|
||||
app.get("/t/:tag", routes.tag);
|
||||
app.get("/u/:user", routes.usersearch);
|
||||
|
||||
app.get( "/terms", routes.page( "terms" ) );
|
||||
app.get( "/privacy", routes.page( "privacy" ) );
|
||||
app.get("/terms", routes.page("terms"));
|
||||
app.get("/privacy", routes.page("privacy"));
|
||||
|
||||
var personaHostname = env.get( "PERSONA_HOSTNAME", "https://login.persona.org" );
|
||||
var personaHostname = env.get("PERSONA_HOSTNAME", "https://login.persona.org");
|
||||
|
||||
app.get( "/sso/include.js", routes.includejs( env.get( "HOSTNAME" ) ) );
|
||||
app.get( "/sso/include.html", routes.include({
|
||||
app.get("/sso/include.js", routes.includejs(env.get("HOSTNAME")));
|
||||
app.get("/sso/include.html", routes.include({
|
||||
personaHostname: personaHostname
|
||||
}));
|
||||
app.get( "/sso/include-transparent.html", routes.include({
|
||||
app.get("/sso/include-transparent.html", routes.include({
|
||||
personaHostname: personaHostname,
|
||||
transparent: "transparent"
|
||||
}));
|
||||
app.get( "/sitemap.xml", function(req, res){
|
||||
res.type( "xml" );
|
||||
app.get("/sitemap.xml", function (req, res) {
|
||||
res.type("xml");
|
||||
res.render("sitemap.xml");
|
||||
});
|
||||
|
||||
// Localized Strings
|
||||
app.get( "/strings/:lang?", i18n.stringsRoute( "en-US" ) );
|
||||
app.get("/strings/:lang?", i18n.stringsRoute("en-US"));
|
||||
|
||||
// BrowserID SSO realm file
|
||||
app.get( "/.well-known/browserid-realm", routes.browserid( env.get( "SSO_DOMAINS" )));
|
||||
app.get("/.well-known/browserid-realm", routes.browserid(env.get("SSO_DOMAINS")));
|
||||
|
||||
/**
|
||||
* Legacy Webmaker Redirects
|
||||
*/
|
||||
require( "./routes/redirect" )( app );
|
||||
require("./routes/redirect")(app);
|
||||
|
||||
server = app.listen( env.get( "PORT" ), function() {
|
||||
console.log( "Server listening ( http://localhost:%d )", env.get( "PORT" ));
|
||||
server = app.listen(env.get("PORT"), function () {
|
||||
console.log("Server listening ( http://localhost:%d )", env.get("PORT"));
|
||||
});
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
module.exports = function(app, options) {
|
||||
module.exports = function (app, options) {
|
||||
module.exports = require("webmaker-loginapi")(app, options);
|
||||
};
|
||||
|
|
|
@ -4,29 +4,29 @@ var toolURL = {
|
|||
"application/x-x-ray-goggles": "https://goggles.webmaker.org"
|
||||
};
|
||||
|
||||
module.exports = function(options) {
|
||||
module.exports = function (options) {
|
||||
var moment = require("moment");
|
||||
var makeClient = require("makeapi-client")(options);
|
||||
|
||||
function generateGravatar(hash) {
|
||||
var DEFAULT_AVATAR = "https%3A%2F%2Fstuff.webmaker.org%2Favatars%2Fwebmaker-avatar-44x44.png",
|
||||
DEFAULT_SIZE = 44;
|
||||
return "https://secure.gravatar.com/avatar/" + hash + "?s="+ DEFAULT_SIZE +"&d=" + DEFAULT_AVATAR;
|
||||
DEFAULT_SIZE = 44;
|
||||
return "https://secure.gravatar.com/avatar/" + hash + "?s=" + DEFAULT_SIZE + "&d=" + DEFAULT_AVATAR;
|
||||
}
|
||||
|
||||
// Moment.js default language is 'en'. This function will override
|
||||
// the default language globally on the coming request for the homepage
|
||||
makeClient.setLang = function(lang) {
|
||||
makeClient.setLang = function (lang) {
|
||||
moment.lang(lang);
|
||||
};
|
||||
|
||||
// Given a prefix for an app tag (e.g. "webmaker:p-") sort an array of makes based on that tag
|
||||
// The tag must be of the format "prefix-1", "prefix-2", etc.
|
||||
makeClient.sortByPriority = function(prefix, data) {
|
||||
makeClient.sortByPriority = function (prefix, data) {
|
||||
var sortedData = [],
|
||||
duplicates = [],
|
||||
priorityIndex,
|
||||
regex = new RegExp("^" + prefix + "(\\d+)$");
|
||||
duplicates = [],
|
||||
priorityIndex,
|
||||
regex = new RegExp("^" + prefix + "(\\d+)$");
|
||||
|
||||
function extractStickyPriority(tags) {
|
||||
var res;
|
||||
|
@ -38,10 +38,10 @@ module.exports = function(options) {
|
|||
}
|
||||
}
|
||||
|
||||
for (var i=0; i<data.length; i++) {
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
priorityIndex = extractStickyPriority(data[i].appTags);
|
||||
data[i].index = priorityIndex;
|
||||
if ( sortedData[priorityIndex - 1] ) {
|
||||
if (sortedData[priorityIndex - 1]) {
|
||||
duplicates.push("Duplicate found for " + prefix + priorityIndex);
|
||||
} else {
|
||||
sortedData[priorityIndex - 1] = data[i];
|
||||
|
@ -54,17 +54,17 @@ module.exports = function(options) {
|
|||
};
|
||||
};
|
||||
|
||||
makeClient.process = function(callback, id) {
|
||||
makeClient.then(function(err, data, totalHits) {
|
||||
makeClient.process = function (callback, id) {
|
||||
makeClient.then(function (err, data, totalHits) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
if (!Array.isArray(data) ) {
|
||||
if (!Array.isArray(data)) {
|
||||
return callback("There was no data returned");
|
||||
}
|
||||
|
||||
data.map(function( make ){
|
||||
data.map(function (make) {
|
||||
|
||||
// Set the tool
|
||||
make.tool = make.contentType.replace(/application\/x\-/g, "");
|
||||
|
@ -87,8 +87,8 @@ module.exports = function(options) {
|
|||
make.level = "advanced";
|
||||
}
|
||||
|
||||
if ( id ) {
|
||||
make.hasBeenLiked = make.likes.some(function( like ) {
|
||||
if (id) {
|
||||
make.hasBeenLiked = make.likes.some(function (like) {
|
||||
return like.userId === +id;
|
||||
});
|
||||
}
|
||||
|
@ -111,4 +111,3 @@ module.exports = function(options) {
|
|||
|
||||
module.exports = makeClient;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
var loginAPI = require("./loginapi");
|
||||
|
||||
module.exports.checkAdmin = function(req, res, next) {
|
||||
loginAPI.getUserByEmail(req.session.email, function(err, user){
|
||||
module.exports.checkAdmin = function (req, res, next) {
|
||||
loginAPI.getUserByEmail(req.session.email, function (err, user) {
|
||||
if (err || !user || !user.isAdmin) {
|
||||
return next(new Error("Admin access only"));
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
"devDependencies": {
|
||||
"grunt": "0.4.1",
|
||||
"grunt-recess": "0.3.3",
|
||||
"grunt-contrib-jshint": "0.4.3"
|
||||
"grunt-contrib-jshint": "0.7.1",
|
||||
"grunt-jsbeautifier": "0.2.2"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ define(['jquery', 'nunjucks', 'base/ui', 'moment', 'makeapi', 'localized'],
|
|||
var DEFAULT_LIMIT = 12;
|
||||
var lang = $('html').attr('lang');
|
||||
moment.lang(localized.langToMomentJSLang(lang));
|
||||
var Gallery = function(options) {
|
||||
var Gallery = function (options) {
|
||||
var self = this;
|
||||
|
||||
options = options || {};
|
||||
|
@ -17,11 +17,11 @@ define(['jquery', 'nunjucks', 'base/ui', 'moment', 'makeapi', 'localized'],
|
|||
options.defaultSearch = options.defaultSearch || 'webmaker:recommended';
|
||||
|
||||
var banner = document.querySelector(options.banner),
|
||||
mainGallery = document.querySelector(options.mainGallery),
|
||||
$mainGallery = $(mainGallery),
|
||||
$loadMore = $('.load-more'),
|
||||
$loading = $('.loading-cat'),
|
||||
$emptyMessage = $('.no-makes-found');
|
||||
mainGallery = document.querySelector(options.mainGallery),
|
||||
$mainGallery = $(mainGallery),
|
||||
$loadMore = $('.load-more'),
|
||||
$loading = $('.loading-cat'),
|
||||
$emptyMessage = $('.no-makes-found');
|
||||
|
||||
var limit = $mainGallery.data('limit') || DEFAULT_LIMIT;
|
||||
var totalHits = $mainGallery.data('total-hits');
|
||||
|
@ -36,8 +36,8 @@ define(['jquery', 'nunjucks', 'base/ui', 'moment', 'makeapi', 'localized'],
|
|||
// MakeAPI
|
||||
|
||||
var make = new Make({
|
||||
apiURL: options.makeUrl
|
||||
}),
|
||||
apiURL: options.makeUrl
|
||||
}),
|
||||
searchOptions = {
|
||||
limit: limit,
|
||||
tags: options.defaultSearch,
|
||||
|
@ -52,7 +52,7 @@ define(['jquery', 'nunjucks', 'base/ui', 'moment', 'makeapi', 'localized'],
|
|||
});
|
||||
|
||||
// Which items are large on the front page?
|
||||
var FRONTPAGE_LARGE = [2,3];
|
||||
var FRONTPAGE_LARGE = [2, 3];
|
||||
|
||||
// Nunjucks
|
||||
// Todo - nunjucks middleware
|
||||
|
@ -90,8 +90,8 @@ define(['jquery', 'nunjucks', 'base/ui', 'moment', 'makeapi', 'localized'],
|
|||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
var $this = $(this),
|
||||
makeID = $this.data("make-id"),
|
||||
method;
|
||||
makeID = $this.data("make-id"),
|
||||
method;
|
||||
|
||||
if ($this.hasClass("icon-heart")) {
|
||||
method = "/unlike";
|
||||
|
@ -101,10 +101,10 @@ define(['jquery', 'nunjucks', 'base/ui', 'moment', 'makeapi', 'localized'],
|
|||
$.post(method, {
|
||||
makeID: makeID,
|
||||
_csrf: $("meta[name='X-CSRF-Token']").attr("content")
|
||||
}, function(res) {
|
||||
}, function (res) {
|
||||
var newLen = res.likes.length,
|
||||
$count = $this.parent().parent().find(".like-count"),
|
||||
$text = $this.parent().parent().find(".like-text");
|
||||
$count = $this.parent().parent().find(".like-count"),
|
||||
$text = $this.parent().parent().find(".like-text");
|
||||
|
||||
$this.toggleClass("icon-heart icon-heart-empty");
|
||||
$count.html(newLen);
|
||||
|
@ -115,10 +115,10 @@ define(['jquery', 'nunjucks', 'base/ui', 'moment', 'makeapi', 'localized'],
|
|||
} else {
|
||||
$text.html(localized.get("Like-n"));
|
||||
}
|
||||
}).fail(function(res) {
|
||||
}).fail(function (res) {
|
||||
if (res.status === 401) {
|
||||
window.location.replace(window.location.protocol + "//" + window.location.host +
|
||||
"/" + localized.getCurrentLang() + "/login");
|
||||
"/" + localized.getCurrentLang() + "/login");
|
||||
} else {
|
||||
// already like/unliked, update UI to reflect.
|
||||
$this.toggleClass("icon-heart icon-heart-empty");
|
||||
|
@ -128,12 +128,12 @@ define(['jquery', 'nunjucks', 'base/ui', 'moment', 'makeapi', 'localized'],
|
|||
|
||||
function resultsCallback(err, data, total) {
|
||||
var isStickySearch = (searchOptions.tagPrefix === options.stickyPrefix),
|
||||
itemString = '',
|
||||
frag = document.createElement('div'),
|
||||
makerID = $("meta[name='maker-id']").attr("content"),
|
||||
allItems,
|
||||
i,
|
||||
l;
|
||||
itemString = '',
|
||||
frag = document.createElement('div'),
|
||||
makerID = $("meta[name='maker-id']").attr("content"),
|
||||
allItems,
|
||||
i,
|
||||
l;
|
||||
|
||||
$loading.hide();
|
||||
|
||||
|
@ -178,9 +178,9 @@ define(['jquery', 'nunjucks', 'base/ui', 'moment', 'makeapi', 'localized'],
|
|||
frag.innerHTML = itemString;
|
||||
allItems = frag.querySelectorAll(options.itemSelector);
|
||||
$(allItems)
|
||||
.find(".make-like-toggle")
|
||||
.off("click")
|
||||
.on("click", likeClickCallback);
|
||||
.find(".make-like-toggle")
|
||||
.off("click")
|
||||
.on("click", likeClickCallback);
|
||||
$mainGallery.append(allItems);
|
||||
packery.appended(allItems);
|
||||
packery.layout();
|
||||
|
@ -191,7 +191,7 @@ define(['jquery', 'nunjucks', 'base/ui', 'moment', 'makeapi', 'localized'],
|
|||
self.searchOptions = searchOptions;
|
||||
self.packery = packery;
|
||||
self.make = make;
|
||||
self.search = function(opts) {
|
||||
self.search = function (opts) {
|
||||
opts = opts || {};
|
||||
if (opts.sticky) {
|
||||
searchOptions.tagPrefix = options.stickyPrefix;
|
||||
|
@ -210,14 +210,14 @@ define(['jquery', 'nunjucks', 'base/ui', 'moment', 'makeapi', 'localized'],
|
|||
}
|
||||
packery.layout();
|
||||
|
||||
localized.ready(function() {
|
||||
localized.ready(function () {
|
||||
$(".make-like-toggle")
|
||||
.off("click")
|
||||
.on("click", likeClickCallback);
|
||||
.off("click")
|
||||
.on("click", likeClickCallback);
|
||||
});
|
||||
|
||||
// Set up load more
|
||||
$loadMore.click(function() {
|
||||
$loadMore.click(function () {
|
||||
searchOptions.page++;
|
||||
$loading.show();
|
||||
self.search({
|
||||
|
|
|
@ -1,75 +1,75 @@
|
|||
define( ["jquery", "text!html/ui-fragments.html" ], function( $, _fragments ) {
|
||||
define(["jquery", "text!html/ui-fragments.html"], function ($, _fragments) {
|
||||
"use strict";
|
||||
|
||||
var UI = {},
|
||||
$fragments = $( document.createElement( "div" ) ).html( _fragments );
|
||||
$fragments = $(document.createElement("div")).html(_fragments);
|
||||
|
||||
UI.select = function (select, fn) {
|
||||
|
||||
UI.select = function( select, fn ) {
|
||||
|
||||
$(".filter").removeClass("hide");
|
||||
|
||||
var $el = $( ".ui-select", $fragments ).clone( true ),
|
||||
$toggleBtn = $el.find( ".icon" ),
|
||||
$selectedEl = $el.find( ".ui-selected" ),
|
||||
$menuContainer = $el.find( ".ui-select-menu" ),
|
||||
$menu = $menuContainer.find( "ul" ),
|
||||
$li = $menu.find( "li" );
|
||||
var $el = $(".ui-select", $fragments).clone(true),
|
||||
$toggleBtn = $el.find(".icon"),
|
||||
$selectedEl = $el.find(".ui-selected"),
|
||||
$menuContainer = $el.find(".ui-select-menu"),
|
||||
$menu = $menuContainer.find("ul"),
|
||||
$li = $menu.find("li");
|
||||
|
||||
var $select = $( select ),
|
||||
$options = $( "option", select ),
|
||||
id = $select.attr( "id" );
|
||||
var $select = $(select),
|
||||
$options = $("option", select),
|
||||
id = $select.attr("id");
|
||||
|
||||
fn = fn || function() {};
|
||||
fn = fn || function () {};
|
||||
|
||||
$options.each( function( i, option ) {
|
||||
var val = $( option ).val(),
|
||||
html = $( option ).html(),
|
||||
$newLi = $li.clone();
|
||||
$newLi.attr( "data-value", val );
|
||||
$newLi.html( html );
|
||||
if ( $( option ).attr( "selected" ) ) {
|
||||
$newLi.attr( "data-selected", true);
|
||||
$selectedEl.html( html );
|
||||
$options.each(function (i, option) {
|
||||
var val = $(option).val(),
|
||||
html = $(option).html(),
|
||||
$newLi = $li.clone();
|
||||
$newLi.attr("data-value", val);
|
||||
$newLi.html(html);
|
||||
if ($(option).attr("selected")) {
|
||||
$newLi.attr("data-selected", true);
|
||||
$selectedEl.html(html);
|
||||
}
|
||||
$newLi.click( function() {
|
||||
var $this = $( this );
|
||||
$newLi.click(function () {
|
||||
var $this = $(this);
|
||||
|
||||
$menu.find( "[data-selected]" ).removeAttr( "data-selected" );
|
||||
$( this ).attr( "data-selected", true );
|
||||
$selectedEl.text( html );
|
||||
$menu.find("[data-selected]").removeAttr("data-selected");
|
||||
$(this).attr("data-selected", true);
|
||||
$selectedEl.text(html);
|
||||
$menuContainer.hide();
|
||||
fn( val );
|
||||
$select.val( val );
|
||||
fn(val);
|
||||
$select.val(val);
|
||||
|
||||
});
|
||||
$menu.append( $newLi );
|
||||
$menu.append($newLi);
|
||||
});
|
||||
|
||||
$selectedEl.click( function( e ) {
|
||||
$selectedEl.click(function (e) {
|
||||
$menuContainer.toggle();
|
||||
});
|
||||
$toggleBtn.click( function( e ) {
|
||||
$toggleBtn.click(function (e) {
|
||||
$menuContainer.toggle();
|
||||
});
|
||||
|
||||
$el.attr( "id", id );
|
||||
$select.removeAttr( "id" );
|
||||
$el.attr("id", id);
|
||||
$select.removeAttr("id");
|
||||
|
||||
$li.remove();
|
||||
$el.insertAfter( $select );
|
||||
$el.insertAfter($select);
|
||||
$select.hide();
|
||||
};
|
||||
|
||||
UI.pagination = function( page, total, limit, callback ) {
|
||||
UI.pagination = function (page, total, limit, callback) {
|
||||
var $pagination = $(".pagination"),
|
||||
$ul = $pagination.find("ul"),
|
||||
$_li = $("<li></li>"),
|
||||
$li,
|
||||
MAX_NUMS = 4,
|
||||
totalPages = total ? Math.ceil(total/limit) : 0,
|
||||
set = Math.floor((page-1)/MAX_NUMS),
|
||||
startPage = set * MAX_NUMS + 1,
|
||||
endPage = Math.min((set * MAX_NUMS) + MAX_NUMS, totalPages);
|
||||
$ul = $pagination.find("ul"),
|
||||
$_li = $("<li></li>"),
|
||||
$li,
|
||||
MAX_NUMS = 4,
|
||||
totalPages = total ? Math.ceil(total / limit) : 0,
|
||||
set = Math.floor((page - 1) / MAX_NUMS),
|
||||
startPage = set * MAX_NUMS + 1,
|
||||
endPage = Math.min((set * MAX_NUMS) + MAX_NUMS, totalPages);
|
||||
|
||||
if (totalPages > 1) {
|
||||
$pagination.show();
|
||||
|
@ -78,10 +78,10 @@ define( ["jquery", "text!html/ui-fragments.html" ], function( $, _fragments ) {
|
|||
}
|
||||
|
||||
var $prevBtn = $_li.clone().html("<span class=\"icon-chevron-left\"></span>"),
|
||||
$nextBtn = $_li.clone().html("<span class=\"icon-chevron-right\"></span>");
|
||||
$nextBtn = $_li.clone().html("<span class=\"icon-chevron-right\"></span>");
|
||||
|
||||
function pageSearch(page) {
|
||||
return function() {
|
||||
return function () {
|
||||
callback(page);
|
||||
};
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ define( ["jquery", "text!html/ui-fragments.html" ], function( $, _fragments ) {
|
|||
$ul.empty();
|
||||
|
||||
// Show previous?
|
||||
if ( page > 1 ) {
|
||||
if (page > 1) {
|
||||
$ul.append($prevBtn);
|
||||
$prevBtn.click(pageSearch(page - 1));
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ define( ["jquery", "text!html/ui-fragments.html" ], function( $, _fragments ) {
|
|||
for (var i = startPage; i <= endPage; i++) {
|
||||
$li = $_li.clone();
|
||||
$li.text(i);
|
||||
if (i === page ) {
|
||||
if (i === page) {
|
||||
$li.addClass("active");
|
||||
}
|
||||
$li.click(pageSearch(i));
|
||||
|
@ -116,8 +116,6 @@ define( ["jquery", "text!html/ui-fragments.html" ], function( $, _fragments ) {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
return UI;
|
||||
|
||||
});
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
requirejs.config({
|
||||
baseDir:'/js',
|
||||
baseDir: '/js',
|
||||
paths: {
|
||||
'text': '/bower/text/text',
|
||||
'jquery': '/bower/jquery/jquery.min',
|
||||
'jquery.powertip': '/js/lib/jquery.powertip',
|
||||
'moment': '/bower/moment/min/moment+langs.min',
|
||||
'social': '/js/lib/socialmedia',
|
||||
'uri': '/js/lib/uri',
|
||||
'tabzilla': 'https://www.mozilla.org/tabzilla/media/js/tabzilla',
|
||||
'text': '/bower/text/text',
|
||||
'jquery': '/bower/jquery/jquery.min',
|
||||
'jquery.powertip': '/js/lib/jquery.powertip',
|
||||
'moment': '/bower/moment/min/moment+langs.min',
|
||||
'social': '/js/lib/socialmedia',
|
||||
'uri': '/js/lib/uri',
|
||||
'tabzilla': 'https://www.mozilla.org/tabzilla/media/js/tabzilla',
|
||||
// XXX: window.__loginAPI gets templated in server-side in layout.html
|
||||
'sso-ux': window.__loginAPI + '/js/sso-ux',
|
||||
'nunjucks': '/bower/nunjucks/browser/nunjucks-dev',
|
||||
'makeapi': '/bower/makeapi-client/src/make-api',
|
||||
'localized': '/bower/webmaker-i18n/localized'
|
||||
'sso-ux': window.__loginAPI + '/js/sso-ux',
|
||||
'nunjucks': '/bower/nunjucks/browser/nunjucks-dev',
|
||||
'makeapi': '/bower/makeapi-client/src/make-api',
|
||||
'localized': '/bower/webmaker-i18n/localized'
|
||||
},
|
||||
shim: {
|
||||
'tabzilla': ['jquery'],
|
||||
|
@ -31,46 +31,46 @@ require([
|
|||
'tabzilla',
|
||||
'sso-ux'
|
||||
], function ($, cta, Marquee, privacy, AnchorSlide, WebmakerUI, navigation) {
|
||||
'use strict';
|
||||
'use strict';
|
||||
|
||||
var $html = $('html, body');
|
||||
var $window = $(window);
|
||||
var $backToTop = $('.back-to-top');
|
||||
var langSelector = document.querySelector("#lang-picker");
|
||||
var $html = $('html, body');
|
||||
var $window = $(window);
|
||||
var $backToTop = $('.back-to-top');
|
||||
var langSelector = document.querySelector("#lang-picker");
|
||||
|
||||
// Show and hide "Back To Top" trigger
|
||||
$window.scroll(function() {
|
||||
if ($window.scrollTop() > 100) {
|
||||
$backToTop.addClass('addMore');
|
||||
} else {
|
||||
$backToTop.removeClass('addMore');
|
||||
}
|
||||
});
|
||||
|
||||
// Attach navigation UI
|
||||
navigation();
|
||||
|
||||
// Generate CTA bar in footer
|
||||
cta.attachToCTA();
|
||||
|
||||
// Create Anchor Sliders
|
||||
$('a.anchor-slide').each(function () {
|
||||
var anchorSlide = new AnchorSlide(this);
|
||||
});
|
||||
|
||||
// Create Partner marquees
|
||||
$('ul.sponsors').each(function () {
|
||||
var marquee = new Marquee(this);
|
||||
marquee.startRotation();
|
||||
});
|
||||
|
||||
// URL redirector for language picker
|
||||
WebmakerUI.langPicker(langSelector);
|
||||
|
||||
// Set up page-specific js
|
||||
var pageJS = $('#require-js').data('page');
|
||||
|
||||
if (pageJS) {
|
||||
require([pageJS]);
|
||||
// Show and hide "Back To Top" trigger
|
||||
$window.scroll(function () {
|
||||
if ($window.scrollTop() > 100) {
|
||||
$backToTop.addClass('addMore');
|
||||
} else {
|
||||
$backToTop.removeClass('addMore');
|
||||
}
|
||||
});
|
||||
|
||||
// Attach navigation UI
|
||||
navigation();
|
||||
|
||||
// Generate CTA bar in footer
|
||||
cta.attachToCTA();
|
||||
|
||||
// Create Anchor Sliders
|
||||
$('a.anchor-slide').each(function () {
|
||||
var anchorSlide = new AnchorSlide(this);
|
||||
});
|
||||
|
||||
// Create Partner marquees
|
||||
$('ul.sponsors').each(function () {
|
||||
var marquee = new Marquee(this);
|
||||
marquee.startRotation();
|
||||
});
|
||||
|
||||
// URL redirector for language picker
|
||||
WebmakerUI.langPicker(langSelector);
|
||||
|
||||
// Set up page-specific js
|
||||
var pageJS = $('#require-js').data('page');
|
||||
|
||||
if (pageJS) {
|
||||
require([pageJS]);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,95 +1,95 @@
|
|||
define(['jquery', 'social', 'localized'],
|
||||
function ($, SocialMedia, localized) {
|
||||
localized.ready(function() {
|
||||
var social,
|
||||
localized.ready(function () {
|
||||
var social,
|
||||
$body = $("body"),
|
||||
$shareBtn = $( "#share-btn" ),
|
||||
$shareContainer = $( "#share-container" ),
|
||||
$shareBtn = $("#share-btn"),
|
||||
$shareContainer = $("#share-container"),
|
||||
$likeBtn = $(".make-like-toggle"),
|
||||
$likeCount = $(".like-count"),
|
||||
$likeText = $(".like-text"),
|
||||
$notLoggedInMsg = $( ".not-logged-in" ),
|
||||
googleBtn = document.getElementById( "google-btn" ),
|
||||
twitterBtn = document.getElementById( "twitter-btn" ),
|
||||
fbBtn = document.getElementById( "fb-btn" ),
|
||||
$notLoggedInMsg = $(".not-logged-in"),
|
||||
googleBtn = document.getElementById("google-btn"),
|
||||
twitterBtn = document.getElementById("twitter-btn"),
|
||||
fbBtn = document.getElementById("fb-btn"),
|
||||
tool = $body.data("tool"),
|
||||
url = $body.data("url");
|
||||
|
||||
var socialMessage = localized.get('DetailsShareTwitterMsg');
|
||||
social = new SocialMedia({
|
||||
message: socialMessage,
|
||||
via: "webmaker"
|
||||
});
|
||||
var socialMessage = localized.get('DetailsShareTwitterMsg');
|
||||
social = new SocialMedia({
|
||||
message: socialMessage,
|
||||
via: "webmaker"
|
||||
});
|
||||
|
||||
function shareOnClick() {
|
||||
social.hotLoad( twitterBtn, social.twitter, url );
|
||||
social.hotLoad( googleBtn, social.google, url );
|
||||
social.hotLoad( fbBtn, social.facebook, url );
|
||||
$shareBtn.addClass( "hidden" );
|
||||
$shareContainer.removeClass( "hidden" );
|
||||
$shareBtn.off( "click", shareOnClick );
|
||||
}
|
||||
|
||||
function openLogInWindow() {
|
||||
window.open( "/login", "Log In" );
|
||||
}
|
||||
|
||||
$shareBtn.on( "click", shareOnClick );
|
||||
|
||||
$notLoggedInMsg.on( "click", openLogInWindow );
|
||||
|
||||
$likeBtn.on( "click", function(e) {
|
||||
if( e.target !== $likeBtn[0] ) {
|
||||
return;
|
||||
function shareOnClick() {
|
||||
social.hotLoad(twitterBtn, social.twitter, url);
|
||||
social.hotLoad(googleBtn, social.google, url);
|
||||
social.hotLoad(fbBtn, social.facebook, url);
|
||||
$shareBtn.addClass("hidden");
|
||||
$shareContainer.removeClass("hidden");
|
||||
$shareBtn.off("click", shareOnClick);
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
function openLogInWindow() {
|
||||
window.open("/login", "Log In");
|
||||
}
|
||||
|
||||
var makeID = $likeBtn.data("make-id"),
|
||||
$shareBtn.on("click", shareOnClick);
|
||||
|
||||
$notLoggedInMsg.on("click", openLogInWindow);
|
||||
|
||||
$likeBtn.on("click", function (e) {
|
||||
if (e.target !== $likeBtn[0]) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
var makeID = $likeBtn.data("make-id"),
|
||||
count,
|
||||
method;
|
||||
|
||||
if( $likeBtn.hasClass( "icon-heart" ) ) {
|
||||
method = "/unlike";
|
||||
} else {
|
||||
method = "/like";
|
||||
}
|
||||
if ($likeBtn.hasClass("icon-heart")) {
|
||||
method = "/unlike";
|
||||
} else {
|
||||
method = "/like";
|
||||
}
|
||||
|
||||
$.post(method, {
|
||||
makeID: makeID,
|
||||
_csrf: $("meta[name='X-CSRF-Token']").attr("content")
|
||||
}, function(res) {
|
||||
$.post(method, {
|
||||
makeID: makeID,
|
||||
_csrf: $("meta[name='X-CSRF-Token']").attr("content")
|
||||
}, function (res) {
|
||||
var newLen = res.likes.length;
|
||||
$likeBtn.toggleClass("icon-heart icon-heart-empty");
|
||||
$likeCount.html(newLen);
|
||||
if (newLen === 0) {
|
||||
$likeText.html(localized.get("Like-0"));
|
||||
} else if ( newLen === 1) {
|
||||
} else if (newLen === 1) {
|
||||
$likeText.html(localized.get("Like-1"));
|
||||
} else {
|
||||
$likeText.html(localized.get("Like-n"));
|
||||
}
|
||||
}).fail(function(res) {
|
||||
var timer;
|
||||
}).fail(function (res) {
|
||||
var timer;
|
||||
|
||||
function removeLogInMsg( e ) {
|
||||
window.removeEventListener( "click", removeLogInMsg, false );
|
||||
window.clearTimeout( timer );
|
||||
$notLoggedInMsg.addClass( "hide" );
|
||||
}
|
||||
function removeLogInMsg(e) {
|
||||
window.removeEventListener("click", removeLogInMsg, false);
|
||||
window.clearTimeout(timer);
|
||||
$notLoggedInMsg.addClass("hide");
|
||||
}
|
||||
|
||||
if ( res.status === 401 ) {
|
||||
$notLoggedInMsg.removeClass( "hide" );
|
||||
timer = window.setTimeout( removeLogInMsg, 5000 );
|
||||
window.addEventListener( "click", function( e ) {
|
||||
if ( e.target === $notLoggedInMsg.find( "a" )[0] ) {
|
||||
return true;
|
||||
}
|
||||
removeLogInMsg();
|
||||
}, false );
|
||||
}
|
||||
if (res.status === 401) {
|
||||
$notLoggedInMsg.removeClass("hide");
|
||||
timer = window.setTimeout(removeLogInMsg, 5000);
|
||||
window.addEventListener("click", function (e) {
|
||||
if (e.target === $notLoggedInMsg.find("a")[0]) {
|
||||
return true;
|
||||
}
|
||||
removeLogInMsg();
|
||||
}, false);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
//blue
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
define(["jquery", "localized", "nunjucks", "base/ui", "moment", "uri", "makeapi"],
|
||||
function ($, localized, nunjucks, UI, moment, URI, Make) {
|
||||
"use strict";
|
||||
"use strict";
|
||||
|
||||
var MAKE_VIEW = "make-templates/make-admin-search.html",
|
||||
var MAKE_VIEW = "make-templates/make-admin-search.html",
|
||||
MAKE_URL = $("body").data("endpoint"),
|
||||
LIMIT = 12,
|
||||
STICKY_PREFIX = "webmaker:teach-",
|
||||
|
@ -12,7 +12,7 @@ define(["jquery", "localized", "nunjucks", "base/ui", "moment", "uri", "makeapi"
|
|||
$emptyMessage = $(".no-makes-found"),
|
||||
stampBanner = document.querySelector(".stamp"),
|
||||
mainGallery = document.querySelector(".main-gallery"),
|
||||
$mainGallery= $(mainGallery),
|
||||
$mainGallery = $(mainGallery),
|
||||
$header = $("header"),
|
||||
$sidebar = $(".admin-sidebar "),
|
||||
$adminSearch = $("#admin-search-input"),
|
||||
|
@ -21,147 +21,150 @@ define(["jquery", "localized", "nunjucks", "base/ui", "moment", "uri", "makeapi"
|
|||
lastQuery,
|
||||
makeAPIUrl = $("body").data("endpoint"),
|
||||
makeAPIUrlHost = URI.parse(makeAPIUrl).host,
|
||||
queryKeys = URI.parse( window.location.href ).queryKey,
|
||||
queryKeys = URI.parse(window.location.href).queryKey,
|
||||
lang = $('html').attr('lang');
|
||||
|
||||
moment.lang(localized.langToMomentJSLang(lang));
|
||||
moment.lang(localized.langToMomentJSLang(lang));
|
||||
|
||||
nunjucks.env = new nunjucks.Environment(new nunjucks.HttpLoader("/views", true));
|
||||
nunjucks.env = new nunjucks.Environment(new nunjucks.HttpLoader("/views", true));
|
||||
|
||||
// Making a custom filter to use it for the client-side l10n
|
||||
// Using this filter will help reduce the number of adding
|
||||
// variables to the global nunjucks variable.
|
||||
// The usage will be "{{ "some string" | gettext }}"
|
||||
nunjucks.env.addFilter('gettext', function (data) {
|
||||
return localized.get(data);
|
||||
});
|
||||
// Making a custom filter to use it for the client-side l10n
|
||||
// Using this filter will help reduce the number of adding
|
||||
// variables to the global nunjucks variable.
|
||||
// The usage will be "{{ "some string" | gettext }}"
|
||||
nunjucks.env.addFilter('gettext', function (data) {
|
||||
return localized.get(data);
|
||||
});
|
||||
|
||||
// Set up packery
|
||||
var packery = new Packery(mainGallery, {
|
||||
itemSelector: "div.make",
|
||||
gutter: ".gutter-sizer"
|
||||
});
|
||||
// Set up packery
|
||||
var packery = new Packery(mainGallery, {
|
||||
itemSelector: "div.make",
|
||||
gutter: ".gutter-sizer"
|
||||
});
|
||||
|
||||
packery.on("layoutComplete", function() {
|
||||
$(".packery-hide", $mainGallery).removeClass("packery-hide");
|
||||
});
|
||||
packery.on("layoutComplete", function () {
|
||||
$(".packery-hide", $mainGallery).removeClass("packery-hide");
|
||||
});
|
||||
|
||||
var searchPackery = new Packery(searchResults, {
|
||||
itemSelector: "div.make",
|
||||
gutter: 10
|
||||
});
|
||||
|
||||
var searchPackery = new Packery(searchResults, {
|
||||
itemSelector: "div.make",
|
||||
gutter: 10
|
||||
});
|
||||
// Create make client for teach, set up default options
|
||||
var make = new Make({
|
||||
apiURL: MAKE_URL
|
||||
});
|
||||
|
||||
// Create make client for teach, set up default options
|
||||
var make = new Make({apiURL: MAKE_URL});
|
||||
|
||||
function generateGravatar(hash) {
|
||||
// TODO: Combine with makeapi-webmaker.js into universal module
|
||||
var DEFAULT_AVATAR = "https%3A%2F%2Fstuff.webmaker.org%2Favatars%2Fwebmaker-avatar-44x44.png",
|
||||
function generateGravatar(hash) {
|
||||
// TODO: Combine with makeapi-webmaker.js into universal module
|
||||
var DEFAULT_AVATAR = "https%3A%2F%2Fstuff.webmaker.org%2Favatars%2Fwebmaker-avatar-44x44.png",
|
||||
DEFAULT_SIZE = 44;
|
||||
return "https://secure.gravatar.com/avatar/" + hash + "?s="+ DEFAULT_SIZE +"&d=" + DEFAULT_AVATAR;
|
||||
}
|
||||
|
||||
function resultsCallback(err, data, total) {
|
||||
var oldMakes = searchResults.querySelectorAll(".make");
|
||||
var showingString = total ? ("Showing pg. " + lastQuery.page+ " of " + total ) : "No";
|
||||
if (oldMakes.length) {
|
||||
searchPackery.remove(oldMakes);
|
||||
return "https://secure.gravatar.com/avatar/" + hash + "?s=" + DEFAULT_SIZE + "&d=" + DEFAULT_AVATAR;
|
||||
}
|
||||
$loading.hide();
|
||||
$(".search-summary").html( showingString + " results for " + lastQuery.field + " = " + lastQuery.value + " on " + "<a href=\"" + makeAPIUrl + "/admin\">" + makeAPIUrlHost + "</a>");
|
||||
UI.pagination(lastQuery.page, total, LIMIT, function( page ) {
|
||||
lastQuery.page = page;
|
||||
|
||||
function resultsCallback(err, data, total) {
|
||||
var oldMakes = searchResults.querySelectorAll(".make");
|
||||
var showingString = total ? ("Showing pg. " + lastQuery.page + " of " + total) : "No";
|
||||
if (oldMakes.length) {
|
||||
searchPackery.remove(oldMakes);
|
||||
}
|
||||
$loading.hide();
|
||||
$(".search-summary").html(showingString + " results for " + lastQuery.field + " = " + lastQuery.value + " on " + "<a href=\"" + makeAPIUrl + "/admin\">" + makeAPIUrlHost + "</a>");
|
||||
UI.pagination(lastQuery.page, total, LIMIT, function (page) {
|
||||
lastQuery.page = page;
|
||||
doSearch(lastQuery);
|
||||
});
|
||||
if (err || !data.length) {
|
||||
return;
|
||||
}
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
if (data[i]) {
|
||||
data[i].avatar = generateGravatar(data[i].emailHash);
|
||||
data[i].updatedAt = moment(data[i].updatedAt).fromNow();
|
||||
data[i].createdAt = moment(data[i].createdAt).fromNow();
|
||||
data[i].remixurl = data[i].url + "/remix";
|
||||
var $item = $($.parseHTML(nunjucks.env.render(MAKE_VIEW, {
|
||||
make: data[i]
|
||||
}))[0]);
|
||||
$searchResults.prepend($item);
|
||||
searchPackery.appended($item[0]);
|
||||
}
|
||||
}
|
||||
searchPackery.layout();
|
||||
}
|
||||
|
||||
if (stampBanner) {
|
||||
packery.stamp(stampBanner);
|
||||
packery.layout();
|
||||
}
|
||||
|
||||
var scrollTop = $sidebar.offset().top;
|
||||
$(window).scroll(function (e) {
|
||||
var windowTop = $(window).scrollTop();
|
||||
if (windowTop > scrollTop) {
|
||||
$sidebar.css("top", "0");
|
||||
} else {
|
||||
$sidebar.css("top", scrollTop - windowTop);
|
||||
}
|
||||
});
|
||||
|
||||
function doSearch(options) {
|
||||
options = options || {};
|
||||
|
||||
options.field = options.field || $(".search-type label.active").data("field");
|
||||
options.value = options.value || $adminSearch.val();
|
||||
options.limit = options.limit || LIMIT;
|
||||
options.sortByField = options.sortByField || "createdAt";
|
||||
options.sortByDirection = options.sortByDirection || "desc";
|
||||
options.page = options.page || 1;
|
||||
|
||||
lastQuery = options;
|
||||
|
||||
var searchQuery = {
|
||||
limit: options.limit,
|
||||
sortByField: [options.sortByField, options.sortByDirection],
|
||||
page: options.page
|
||||
};
|
||||
|
||||
searchQuery[options.field] = options.value;
|
||||
localized.ready(function () {
|
||||
make.find(searchQuery).then(resultsCallback);
|
||||
});
|
||||
}
|
||||
|
||||
//Choosing field
|
||||
$(".search-type label").click(function (e) {
|
||||
$(".search-type label.active").removeClass("active");
|
||||
$(this).addClass("active");
|
||||
doSearch({
|
||||
field: $(this).data("field")
|
||||
});
|
||||
});
|
||||
|
||||
UI.select("#filter", function (val) {
|
||||
lastQuery.sortByField = val;
|
||||
lastQuery.page = 1;
|
||||
doSearch(lastQuery);
|
||||
});
|
||||
if (err || !data.length) {
|
||||
return;
|
||||
}
|
||||
for (var i=0; i<data.length; i++) {
|
||||
if (data[i]) {
|
||||
data[i].avatar = generateGravatar(data[i].emailHash);
|
||||
data[i].updatedAt = moment( data[i].updatedAt ).fromNow();
|
||||
data[i].createdAt = moment( data[i].createdAt ).fromNow();
|
||||
data[i].remixurl = data[i].url + "/remix";
|
||||
var $item = $($.parseHTML(nunjucks.env.render(MAKE_VIEW, {make: data[i]}))[0]);
|
||||
$searchResults.prepend($item);
|
||||
searchPackery.appended($item[0]);
|
||||
|
||||
UI.select("#prefix-select", function (val) {
|
||||
queryKeys.prefix = val;
|
||||
window.location.search = $.param(queryKeys);
|
||||
});
|
||||
|
||||
UI.select("#layout-select", function (val) {
|
||||
queryKeys.layout = val;
|
||||
window.location.search = $.param(queryKeys);
|
||||
});
|
||||
|
||||
$adminSearch.bind("keypress", function (e) {
|
||||
var code = (e.keyCode ? e.keyCode : e.which);
|
||||
if (code === 13) { //Enter keycode
|
||||
doSearch();
|
||||
}
|
||||
}
|
||||
searchPackery.layout();
|
||||
}
|
||||
|
||||
if (stampBanner) {
|
||||
packery.stamp(stampBanner);
|
||||
packery.layout();
|
||||
}
|
||||
|
||||
var scrollTop = $sidebar.offset().top;
|
||||
$(window).scroll(function(e) {
|
||||
var windowTop = $(window).scrollTop();
|
||||
if (windowTop > scrollTop) {
|
||||
$sidebar.css("top", "0");
|
||||
} else {
|
||||
$sidebar.css("top", scrollTop - windowTop);
|
||||
}
|
||||
});
|
||||
|
||||
function doSearch(options){
|
||||
options = options || {};
|
||||
|
||||
options.field = options.field || $(".search-type label.active").data("field");
|
||||
options.value = options.value || $adminSearch.val();
|
||||
options.limit = options.limit || LIMIT;
|
||||
options.sortByField = options.sortByField || "createdAt";
|
||||
options.sortByDirection = options.sortByDirection || "desc";
|
||||
options.page = options.page || 1;
|
||||
|
||||
lastQuery = options;
|
||||
|
||||
var searchQuery = {
|
||||
limit: options.limit,
|
||||
sortByField: [options.sortByField, options.sortByDirection],
|
||||
page: options.page
|
||||
};
|
||||
|
||||
searchQuery[options.field] = options.value;
|
||||
localized.ready(function(){
|
||||
make.find(searchQuery).then(resultsCallback);
|
||||
});
|
||||
}
|
||||
|
||||
//Choosing field
|
||||
$(".search-type label").click(function(e) {
|
||||
$(".search-type label.active").removeClass("active");
|
||||
$(this).addClass("active");
|
||||
doSearch({
|
||||
field: $(this).data("field")
|
||||
});
|
||||
doSearch();
|
||||
|
||||
});
|
||||
|
||||
UI.select("#filter", function(val) {
|
||||
lastQuery.sortByField = val;
|
||||
lastQuery.page = 1;
|
||||
doSearch(lastQuery);
|
||||
});
|
||||
|
||||
UI.select("#prefix-select", function(val) {
|
||||
queryKeys.prefix = val;
|
||||
window.location.search = $.param(queryKeys);
|
||||
});
|
||||
|
||||
UI.select("#layout-select", function(val) {
|
||||
queryKeys.layout = val;
|
||||
window.location.search = $.param(queryKeys);
|
||||
});
|
||||
|
||||
$adminSearch.bind("keypress", function(e) {
|
||||
var code = (e.keyCode ? e.keyCode : e.which);
|
||||
if(code == 13) { //Enter keycode
|
||||
doSearch();
|
||||
}
|
||||
});
|
||||
|
||||
doSearch();
|
||||
|
||||
});
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
require(['jquery', 'base/ui', 'base/gallery'],
|
||||
function($, UI, Gallery) {
|
||||
function ($, UI, Gallery) {
|
||||
'use strict';
|
||||
|
||||
var gallery = new Gallery({
|
||||
|
@ -10,39 +10,39 @@ require(['jquery', 'base/ui', 'base/gallery'],
|
|||
});
|
||||
|
||||
// Hide the banner if the user already exists
|
||||
navigator.idSSO.app.onlogin = function(loggedInUser, displayName) {
|
||||
navigator.idSSO.app.onlogin = function (loggedInUser, displayName) {
|
||||
$('#banner-join').hide();
|
||||
gallery.packery.layout();
|
||||
};
|
||||
|
||||
UI.select('#search-filter', function(val) {
|
||||
UI.select('#search-filter', function (val) {
|
||||
|
||||
var makes = document.querySelectorAll('.make');
|
||||
|
||||
switch (val) {
|
||||
case 'featured':
|
||||
gallery.searchOptions.tags = {
|
||||
tags: ['webmaker:featured']
|
||||
};
|
||||
gallery.searchOptions.sortByField = ['createdAt', 'desc'];
|
||||
delete gallery.searchOptions.contentType;
|
||||
break;
|
||||
case 'featured':
|
||||
gallery.searchOptions.tags = {
|
||||
tags: ['webmaker:featured']
|
||||
};
|
||||
gallery.searchOptions.sortByField = ['createdAt', 'desc'];
|
||||
delete gallery.searchOptions.contentType;
|
||||
break;
|
||||
|
||||
case 'popcorn':
|
||||
gallery.searchOptions.tags = {
|
||||
tags: ['webmaker:featured']
|
||||
};
|
||||
gallery.searchOptions.sortByField = ['createdAt', 'desc'];
|
||||
gallery.searchOptions.contentType = 'application/x-popcorn';
|
||||
break;
|
||||
case 'popcorn':
|
||||
gallery.searchOptions.tags = {
|
||||
tags: ['webmaker:featured']
|
||||
};
|
||||
gallery.searchOptions.sortByField = ['createdAt', 'desc'];
|
||||
gallery.searchOptions.contentType = 'application/x-popcorn';
|
||||
break;
|
||||
|
||||
case 'thimble':
|
||||
gallery.searchOptions.tags = {
|
||||
tags: ['webmaker:featured']
|
||||
};
|
||||
gallery.searchOptions.sortByField = ['createdAt', 'desc'];
|
||||
gallery.searchOptions.contentType = 'application/x-thimble';
|
||||
break;
|
||||
case 'thimble':
|
||||
gallery.searchOptions.tags = {
|
||||
tags: ['webmaker:featured']
|
||||
};
|
||||
gallery.searchOptions.sortByField = ['createdAt', 'desc'];
|
||||
gallery.searchOptions.contentType = 'application/x-thimble';
|
||||
break;
|
||||
}
|
||||
|
||||
// Reset and set to page 1
|
||||
|
|
|
@ -1,91 +1,87 @@
|
|||
define(['jquery', 'uri', 'base/ui', 'localized'],
|
||||
function ($, URI, UI, localized) {
|
||||
'use strict';
|
||||
'use strict';
|
||||
|
||||
localized.ready(function() {
|
||||
var $body = $("body"),
|
||||
localized.ready(function () {
|
||||
var $body = $("body"),
|
||||
$makes = $(".make"),
|
||||
$deleteBtn = $(".delete-btn"),
|
||||
mainGallery = $(".main-gallery")[0],
|
||||
totalHits,
|
||||
LIMIT,
|
||||
queryKeys = URI.parse( window.location.href ).queryKey,
|
||||
queryKeys = URI.parse(window.location.href).queryKey,
|
||||
BASE_WIDTH = 240,
|
||||
GUTTER = 20,
|
||||
packery,
|
||||
page;
|
||||
|
||||
// Are we inside thimble or popcorn?
|
||||
var inApp = $body.hasClass("popcorn") || $body.hasClass("thimble");
|
||||
// Are we inside thimble or popcorn?
|
||||
var inApp = $body.hasClass("popcorn") || $body.hasClass("thimble");
|
||||
|
||||
// If the user is not logged in yet,
|
||||
// refresh the page once they are.
|
||||
// This properly generates server side project data
|
||||
// for apps using my makes.
|
||||
if (inApp && !$("meta[name='persona-email']").attr("content")) {
|
||||
navigator.idSSO.app = {
|
||||
onlogin: function(){
|
||||
window.location.replace(window.location);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Do we have any makes?
|
||||
if (!$makes.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set up scrollable container
|
||||
if (inApp) {
|
||||
$(".webmaker-outer-wrapper").css("width", ( ( BASE_WIDTH + GUTTER ) * $makes.length + GUTTER * 2 ) + "px");
|
||||
$("html").css("overflow-y", "hidden");
|
||||
}
|
||||
|
||||
// Or, set up packery if we are on webmaker.org
|
||||
if (!inApp) {
|
||||
packery = new Packery( mainGallery, {
|
||||
itemSelector: 'div.make',
|
||||
gutter: '.gutter-sizer',
|
||||
transitionDuration: '0.2'
|
||||
});
|
||||
}
|
||||
|
||||
// Set up the delete buttons
|
||||
$deleteBtn.on( "click", function(e) {
|
||||
e.preventDefault();
|
||||
var $this = $(this),
|
||||
makeID = $this.data("make-id");
|
||||
if(confirm(localized.get("Are you sure you want to delete this make?"))) {
|
||||
$.post("/remove", {
|
||||
makeID: makeID,
|
||||
_csrf: $("meta[name='X-CSRF-Token']").attr("content")
|
||||
}, function(res) {
|
||||
if ( res.deletedAt ) {
|
||||
if (!inApp) {
|
||||
packery.remove($this.closest(".make")[0]);
|
||||
packery.layout();
|
||||
} else {
|
||||
$this.closest(".make").remove();
|
||||
}
|
||||
} else {
|
||||
console.log(res);
|
||||
// If the user is not logged in yet,
|
||||
// refresh the page once they are.
|
||||
// This properly generates server side project data
|
||||
// for apps using my makes.
|
||||
if (inApp && !$("meta[name='persona-email']").attr("content")) {
|
||||
navigator.idSSO.app = {
|
||||
onlogin: function () {
|
||||
window.location.replace(window.location);
|
||||
}
|
||||
}).fail( function(res) {
|
||||
console.log(res.responseText);
|
||||
};
|
||||
}
|
||||
|
||||
// Do we have any makes?
|
||||
if (!$makes.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set up scrollable container
|
||||
if (inApp) {
|
||||
$(".webmaker-outer-wrapper").css("width", ((BASE_WIDTH + GUTTER) * $makes.length + GUTTER * 2) + "px");
|
||||
$("html").css("overflow-y", "hidden");
|
||||
}
|
||||
|
||||
// Or, set up packery if we are on webmaker.org
|
||||
if (!inApp) {
|
||||
packery = new Packery(mainGallery, {
|
||||
itemSelector: 'div.make',
|
||||
gutter: '.gutter-sizer',
|
||||
transitionDuration: '0.2'
|
||||
});
|
||||
}
|
||||
|
||||
// Set up the delete buttons
|
||||
$deleteBtn.on("click", function (e) {
|
||||
e.preventDefault();
|
||||
var $this = $(this),
|
||||
makeID = $this.data("make-id");
|
||||
if (window.confirm(localized.get("Are you sure you want to delete this make?"))) {
|
||||
$.post("/remove", {
|
||||
makeID: makeID,
|
||||
_csrf: $("meta[name='X-CSRF-Token']").attr("content")
|
||||
}, function (res) {
|
||||
if (res.deletedAt) {
|
||||
if (!inApp) {
|
||||
packery.remove($this.closest(".make")[0]);
|
||||
packery.layout();
|
||||
} else {
|
||||
$this.closest(".make").remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
page = queryKeys.page ? parseInt(queryKeys.page, 10) : 1;
|
||||
|
||||
if (mainGallery) {
|
||||
totalHits = mainGallery.getAttribute("data-total-hits");
|
||||
LIMIT = mainGallery.getAttribute("data-limit");
|
||||
|
||||
UI.pagination(page, totalHits, LIMIT, function (page) {
|
||||
queryKeys.page = page;
|
||||
window.location.search = $.param(queryKeys);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
page = queryKeys.page ? parseInt(queryKeys.page, 10) : 1;
|
||||
|
||||
if ( mainGallery ) {
|
||||
totalHits = mainGallery.getAttribute("data-total-hits");
|
||||
LIMIT = mainGallery.getAttribute("data-limit");
|
||||
|
||||
UI.pagination( page, totalHits, LIMIT, function( page ) {
|
||||
queryKeys.page = page;
|
||||
window.location.search = $.param( queryKeys );
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
define(["jquery"],
|
||||
function ($) {
|
||||
"use strict";
|
||||
var $carouselContainer = $(".commitment-carousel-items"),
|
||||
$carouselItems = $( ".commitment-carousel-item", $carouselContainer ),
|
||||
"use strict";
|
||||
var $carouselContainer = $(".commitment-carousel-items"),
|
||||
$carouselItems = $(".commitment-carousel-item", $carouselContainer),
|
||||
count = 0,
|
||||
max = $carouselItems.length;
|
||||
|
||||
function rotateCarousel() {
|
||||
var next = count + 1;
|
||||
if ( count >= max ) {
|
||||
count = 0;
|
||||
}
|
||||
if ( next >= max) {
|
||||
next = 0;
|
||||
}
|
||||
var $item = $(".commitment-carousel-item:nth-child(" + count + ")", $carouselContainer ),
|
||||
$nextItem = $(".commitment-carousel-item:nth-child(" + next + ")", $carouselContainer );
|
||||
function rotateCarousel() {
|
||||
var next = count + 1;
|
||||
if (count >= max) {
|
||||
count = 0;
|
||||
}
|
||||
if (next >= max) {
|
||||
next = 0;
|
||||
}
|
||||
var $item = $(".commitment-carousel-item:nth-child(" + count + ")", $carouselContainer),
|
||||
$nextItem = $(".commitment-carousel-item:nth-child(" + next + ")", $carouselContainer);
|
||||
|
||||
$item.fadeOut(function(){
|
||||
$nextItem.fadeIn();
|
||||
});
|
||||
count = count + 1;
|
||||
}
|
||||
$item.fadeOut(function () {
|
||||
$nextItem.fadeIn();
|
||||
});
|
||||
count = count + 1;
|
||||
}
|
||||
|
||||
setInterval( rotateCarousel, 5000 );
|
||||
});
|
||||
setInterval(rotateCarousel, 5000);
|
||||
});
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
define(["jquery", "uri", "base/ui" ],
|
||||
define(["jquery", "uri", "base/ui"],
|
||||
function ($, URI, UI) {
|
||||
"use strict";
|
||||
"use strict";
|
||||
|
||||
var query = $(".search-poster").attr( "data-query"),
|
||||
queryKeys = URI.parse( window.location.href ).queryKey,
|
||||
var query = $(".search-poster").attr("data-query"),
|
||||
queryKeys = URI.parse(window.location.href).queryKey,
|
||||
$searchPoster = $(".search-poster"),
|
||||
$searchField = $("#search-field"),
|
||||
$searchFilter = $("#search-type"),
|
||||
|
@ -16,64 +16,66 @@ define(["jquery", "uri", "base/ui" ],
|
|||
packery,
|
||||
page;
|
||||
|
||||
function onKeyDown() {
|
||||
$("html, body").animate({ scrollTop: 0 }, 200 );
|
||||
$searchPoster.addClass( "focus");
|
||||
$searchField.off("keydown", onKeyDown);
|
||||
}
|
||||
function onKeyDown() {
|
||||
$("html, body").animate({
|
||||
scrollTop: 0
|
||||
}, 200);
|
||||
$searchPoster.addClass("focus");
|
||||
$searchField.off("keydown", onKeyDown);
|
||||
}
|
||||
|
||||
// Show the big green UI
|
||||
if ($searchPoster.hasClass("focus") && query) {
|
||||
$searchField.val(query.replace(/,/g,", "));
|
||||
onKeyDown();
|
||||
} else {
|
||||
$searchField.on("keydown", onKeyDown);
|
||||
}
|
||||
// Show the big green UI
|
||||
if ($searchPoster.hasClass("focus") && query) {
|
||||
$searchField.val(query.replace(/,/g, ", "));
|
||||
onKeyDown();
|
||||
} else {
|
||||
$searchField.on("keydown", onKeyDown);
|
||||
}
|
||||
|
||||
// Setup packery
|
||||
packery = new Packery( mainGallery, {
|
||||
itemSelector: "div.make",
|
||||
gutter: ".gutter-sizer",
|
||||
transitionDuration: "0.2"
|
||||
});
|
||||
|
||||
// Change what kind of search
|
||||
$searchFilter.find("li").click( function(){
|
||||
var $this = $(this),
|
||||
type = $this.attr("data-value");
|
||||
$searchFilter.find("[name=type]").val( type );
|
||||
$searchFilter.find("[data-selected] > span").attr("class", "icon-" + type);
|
||||
$searchFilter.find(".ui-on").removeClass("ui-on");
|
||||
$this.addClass("ui-on");
|
||||
});
|
||||
|
||||
$forkBtns.click( function(e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
$userNameLinks.click( function(e) {
|
||||
e.stopPropagation();
|
||||
queryKeys.page = 1;
|
||||
queryKeys.type = "user";
|
||||
queryKeys.q = this.getAttribute("data-username");
|
||||
window.location.search = $.param(queryKeys);
|
||||
});
|
||||
|
||||
page = queryKeys.page ? parseInt(queryKeys.page, 10) : 1;
|
||||
|
||||
if ( mainGallery ) {
|
||||
totalHits = mainGallery.getAttribute("data-total-hits");
|
||||
LIMIT = mainGallery.getAttribute("data-limit");
|
||||
|
||||
UI.pagination( page, totalHits, LIMIT, function( page ) {
|
||||
queryKeys.page = page;
|
||||
|
||||
if (queryKeys.q) {
|
||||
queryKeys.q = decodeURIComponent(queryKeys.q);
|
||||
}
|
||||
|
||||
window.location.search = $.param( queryKeys );
|
||||
// Setup packery
|
||||
packery = new Packery(mainGallery, {
|
||||
itemSelector: "div.make",
|
||||
gutter: ".gutter-sizer",
|
||||
transitionDuration: "0.2"
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
// Change what kind of search
|
||||
$searchFilter.find("li").click(function () {
|
||||
var $this = $(this),
|
||||
type = $this.attr("data-value");
|
||||
$searchFilter.find("[name=type]").val(type);
|
||||
$searchFilter.find("[data-selected] > span").attr("class", "icon-" + type);
|
||||
$searchFilter.find(".ui-on").removeClass("ui-on");
|
||||
$this.addClass("ui-on");
|
||||
});
|
||||
|
||||
$forkBtns.click(function (e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
$userNameLinks.click(function (e) {
|
||||
e.stopPropagation();
|
||||
queryKeys.page = 1;
|
||||
queryKeys.type = "user";
|
||||
queryKeys.q = this.getAttribute("data-username");
|
||||
window.location.search = $.param(queryKeys);
|
||||
});
|
||||
|
||||
page = queryKeys.page ? parseInt(queryKeys.page, 10) : 1;
|
||||
|
||||
if (mainGallery) {
|
||||
totalHits = mainGallery.getAttribute("data-total-hits");
|
||||
LIMIT = mainGallery.getAttribute("data-limit");
|
||||
|
||||
UI.pagination(page, totalHits, LIMIT, function (page) {
|
||||
queryKeys.page = page;
|
||||
|
||||
if (queryKeys.q) {
|
||||
queryKeys.q = decodeURIComponent(queryKeys.q);
|
||||
}
|
||||
|
||||
window.location.search = $.param(queryKeys);
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
define(['jquery', 'base/ui', 'base/gallery'],
|
||||
function ($, UI, Gallery) {
|
||||
'use strict';
|
||||
'use strict';
|
||||
|
||||
var gallery = new Gallery({
|
||||
makeView: 'make-starter-make.html',
|
||||
stickyPrefix: 'webmaker:template-',
|
||||
defaultSearch: {
|
||||
tags: ['webmaker:template']
|
||||
}
|
||||
});
|
||||
|
||||
var gallery = new Gallery({
|
||||
makeView: 'make-starter-make.html',
|
||||
stickyPrefix: 'webmaker:template-',
|
||||
defaultSearch: { tags: [ 'webmaker:template' ] }
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
define(['jquery', 'base/ui', 'base/gallery'],
|
||||
function ($, UI, Gallery) {
|
||||
'use strict';
|
||||
'use strict';
|
||||
|
||||
var gallery = new Gallery({
|
||||
banner: '#banner-teach',
|
||||
makeView: 'make-teach.html',
|
||||
stickyPrefix: 'webmaker:teach-',
|
||||
defaultSearch: {
|
||||
tags: ['webmaker:teach']
|
||||
}
|
||||
});
|
||||
|
||||
var gallery = new Gallery({
|
||||
banner: '#banner-teach',
|
||||
makeView: 'make-teach.html',
|
||||
stickyPrefix: 'webmaker:teach-',
|
||||
defaultSearch: { tags: [ 'webmaker:teach' ] }
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -1,86 +1,88 @@
|
|||
define(['jquery'],
|
||||
function ($) {
|
||||
|
||||
var $window = $(window);
|
||||
var $toggleButtonContainer = $('.mentor-story-nav');
|
||||
var $toggleButtons = $('.mentor-story-nav a');
|
||||
var totalStories = $('.mentor-story-nav a').length;
|
||||
var $nextButton = $('.go-forward');
|
||||
var $backButton = $('.go-back');
|
||||
var $articles = $('.mentor-stories article');
|
||||
var $posters = $('.poster-image-container > div');
|
||||
var $hiddenScroll = $('.hidden-scroll');
|
||||
var gallery = document.querySelector('.make-now-templates');
|
||||
var hideScrollTimeout;
|
||||
var $window = $(window);
|
||||
var $toggleButtonContainer = $('.mentor-story-nav');
|
||||
var $toggleButtons = $('.mentor-story-nav a');
|
||||
var totalStories = $('.mentor-story-nav a').length;
|
||||
var $nextButton = $('.go-forward');
|
||||
var $backButton = $('.go-back');
|
||||
var $articles = $('.mentor-stories article');
|
||||
var $posters = $('.poster-image-container > div');
|
||||
var $hiddenScroll = $('.hidden-scroll');
|
||||
var gallery = document.querySelector('.make-now-templates');
|
||||
var hideScrollTimeout;
|
||||
|
||||
function changeStory(storyId) {
|
||||
$toggleButtons.removeClass('active');
|
||||
$('.mentor-story-nav a[data-id="' + storyId +'"]').addClass('active');
|
||||
$('.mentor-stories article.active').removeClass('active');
|
||||
$('.poster-image-container > div.active').removeClass('active');
|
||||
$('#story-' + storyId).addClass('active');
|
||||
$('#poster-' + storyId).addClass('active');
|
||||
function changeStory(storyId) {
|
||||
$toggleButtons.removeClass('active');
|
||||
$('.mentor-story-nav a[data-id="' + storyId + '"]').addClass('active');
|
||||
$('.mentor-stories article.active').removeClass('active');
|
||||
$('.poster-image-container > div.active').removeClass('active');
|
||||
$('#story-' + storyId).addClass('active');
|
||||
$('#poster-' + storyId).addClass('active');
|
||||
|
||||
var currentIndex = $('.mentor-story-nav a').index( $('.mentor-story-nav a.active') );
|
||||
if (currentIndex === 0) {
|
||||
$backButton.hide();
|
||||
} else {
|
||||
$backButton.show();
|
||||
var currentIndex = $('.mentor-story-nav a').index($('.mentor-story-nav a.active'));
|
||||
if (currentIndex === 0) {
|
||||
$backButton.hide();
|
||||
} else {
|
||||
$backButton.show();
|
||||
}
|
||||
if (currentIndex >= totalStories - 1) {
|
||||
$nextButton.hide();
|
||||
} else {
|
||||
$nextButton.show();
|
||||
}
|
||||
}
|
||||
if (currentIndex >= totalStories - 1) {
|
||||
$nextButton.hide();
|
||||
} else {
|
||||
$nextButton.show();
|
||||
|
||||
function getStoryByNumber(n) {
|
||||
// Convert 0 index > selector nth-child, which starts with one
|
||||
n = n + 1;
|
||||
return $toggleButtonContainer.find('a:nth-child(' + n + ')').attr('data-id');
|
||||
}
|
||||
}
|
||||
|
||||
function getStoryByNumber(n) {
|
||||
// Convert 0 index > selector nth-child, which starts with one
|
||||
n = n + 1;
|
||||
return $toggleButtonContainer.find('a:nth-child('+ n +')').attr('data-id');
|
||||
}
|
||||
|
||||
function hideScroll() {
|
||||
$hiddenScroll.addClass('hidden-scroll');
|
||||
}
|
||||
|
||||
function onScroll() {
|
||||
$hiddenScroll.removeClass('hidden-scroll');
|
||||
if (hideScrollTimeout) {
|
||||
clearTimeout(hideScrollTimeout);
|
||||
function hideScroll() {
|
||||
$hiddenScroll.addClass('hidden-scroll');
|
||||
}
|
||||
hideScrollTimeout = setTimeout(hideScroll, 1000);
|
||||
}
|
||||
|
||||
$window.on('scroll', onScroll);
|
||||
function onScroll() {
|
||||
$hiddenScroll.removeClass('hidden-scroll');
|
||||
if (hideScrollTimeout) {
|
||||
clearTimeout(hideScrollTimeout);
|
||||
}
|
||||
hideScrollTimeout = setTimeout(hideScroll, 1000);
|
||||
}
|
||||
|
||||
$('#make-something').click( function() {
|
||||
$('html, body').animate({ scrollTop: $('.make-something-now').offset().top }, 1000);
|
||||
$window.on('scroll', onScroll);
|
||||
|
||||
$('#make-something').click(function () {
|
||||
$('html, body').animate({
|
||||
scrollTop: $('.make-something-now').offset().top
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
var packery = new Packery(gallery, {
|
||||
itemSelector: '.make-now-templates > article',
|
||||
gutter: '.gutter-make-now'
|
||||
});
|
||||
|
||||
$toggleButtons.on('click', function () {
|
||||
var storyId = this.getAttribute('data-id');
|
||||
changeStory(storyId);
|
||||
});
|
||||
|
||||
$nextButton.on('click', function () {
|
||||
var currentIndex = $('.mentor-story-nav a').index($('.mentor-story-nav a.active'));
|
||||
var storyId = getStoryByNumber(currentIndex + 1);
|
||||
changeStory(storyId);
|
||||
});
|
||||
|
||||
$backButton.on('click', function () {
|
||||
var currentIndex = $('.mentor-story-nav a').index($('.mentor-story-nav a.active'));
|
||||
var storyId = getStoryByNumber(currentIndex - 1);
|
||||
changeStory(storyId);
|
||||
});
|
||||
|
||||
var randomStoryIndex = Math.floor(Math.random() * totalStories) - 1;
|
||||
|
||||
changeStory(getStoryByNumber(randomStoryIndex));
|
||||
});
|
||||
|
||||
var packery = new Packery(gallery, {
|
||||
itemSelector: '.make-now-templates > article',
|
||||
gutter: '.gutter-make-now'
|
||||
});
|
||||
|
||||
$toggleButtons.on('click', function() {
|
||||
var storyId = this.getAttribute('data-id');
|
||||
changeStory(storyId);
|
||||
});
|
||||
|
||||
$nextButton.on('click', function() {
|
||||
var currentIndex = $('.mentor-story-nav a').index( $('.mentor-story-nav a.active') );
|
||||
var storyId = getStoryByNumber(currentIndex + 1);
|
||||
changeStory(storyId);
|
||||
});
|
||||
|
||||
$backButton.on('click', function() {
|
||||
var currentIndex = $('.mentor-story-nav a').index( $('.mentor-story-nav a.active') );
|
||||
var storyId = getStoryByNumber(currentIndex - 1);
|
||||
changeStory(storyId);
|
||||
});
|
||||
|
||||
var randomStoryIndex = Math.floor( Math.random() * totalStories ) - 1;
|
||||
|
||||
changeStory(getStoryByNumber(randomStoryIndex));
|
||||
});
|
||||
|
|
|
@ -1,21 +1,20 @@
|
|||
define(['jquery', '/bower/webmaker-ui/ui.js', 'sso-ux'],
|
||||
function($, WebmakerUI, localized) {
|
||||
"use strict";
|
||||
var lang = $('html').attr('lang');
|
||||
function ($, WebmakerUI, localized) {
|
||||
"use strict";
|
||||
var lang = $('html').attr('lang');
|
||||
|
||||
navigator.idSSO.app.onlogin = function(user) {
|
||||
if( document.referrer.indexOf( 'events' ) !== -1 ){
|
||||
window.location = "/" + lang + "/events";
|
||||
}
|
||||
else {
|
||||
window.location = "/" + lang;
|
||||
}
|
||||
};
|
||||
navigator.idSSO.app.onnewuser = function(){
|
||||
window.location = "/" + lang + "/new";
|
||||
};
|
||||
navigator.idSSO.app.onlogin = function (user) {
|
||||
if (document.referrer.indexOf('events') !== -1) {
|
||||
window.location = "/" + lang + "/events";
|
||||
} else {
|
||||
window.location = "/" + lang;
|
||||
}
|
||||
};
|
||||
navigator.idSSO.app.onnewuser = function () {
|
||||
window.location = "/" + lang + "/new";
|
||||
};
|
||||
|
||||
var langSelector = document.querySelector("#lang-picker");
|
||||
// URL redirector for language picker
|
||||
WebmakerUI.langPicker(langSelector);
|
||||
});
|
||||
var langSelector = document.querySelector("#lang-picker");
|
||||
// URL redirector for language picker
|
||||
WebmakerUI.langPicker(langSelector);
|
||||
});
|
||||
|
|
|
@ -1,65 +1,65 @@
|
|||
define(['jquery', 'sso-ux'],
|
||||
function($) {
|
||||
"use strict";
|
||||
var $formFrag = $("#sso_create");
|
||||
var $mailSignUp = $('#bsd');
|
||||
var $usernameInput = $("#claim-input");
|
||||
var $errorContainer = $("#error-container");
|
||||
var csrf = $("meta[name='X-CSRF-Token']").attr("content");
|
||||
var email = $("meta[name='persona-email']").attr("content");
|
||||
var AUDIENCE = $("meta[name='audience']").attr("content");
|
||||
var loginURL = $("meta[name='login-url']").attr("content");
|
||||
function ($) {
|
||||
"use strict";
|
||||
var $formFrag = $("#sso_create");
|
||||
var $mailSignUp = $('#bsd');
|
||||
var $usernameInput = $("#claim-input");
|
||||
var $errorContainer = $("#error-container");
|
||||
var csrf = $("meta[name='X-CSRF-Token']").attr("content");
|
||||
var email = $("meta[name='persona-email']").attr("content");
|
||||
var AUDIENCE = $("meta[name='audience']").attr("content");
|
||||
var loginURL = $("meta[name='login-url']").attr("content");
|
||||
|
||||
// Redirect if the user has an account;
|
||||
navigator.idSSO.app.onlogin = function(user) {
|
||||
window.location = "/";
|
||||
};
|
||||
// Redirect if the user has an account;
|
||||
navigator.idSSO.app.onlogin = function (user) {
|
||||
window.location = "/";
|
||||
};
|
||||
|
||||
// Prevent default dropdown
|
||||
navigator.idSSO.app.onnewuser = function() {};
|
||||
// Prevent default dropdown
|
||||
navigator.idSSO.app.onnewuser = function () {};
|
||||
|
||||
$formFrag.submit(function (data) {
|
||||
if ($mailSignUp.is(':checked')) {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: 'https://sendto.mozilla.org/page/s/webmaker',
|
||||
data: {
|
||||
email: $usernameInput.val(),
|
||||
'custom-1216': 1
|
||||
},
|
||||
success: function (resp) {
|
||||
return true;
|
||||
},
|
||||
error: function (resp) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$formFrag.submit( function(data) {
|
||||
if( $mailSignUp.is(':checked') ) {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: 'https://sendto.mozilla.org/page/s/webmaker',
|
||||
type: "POST",
|
||||
url: loginURL + "/user",
|
||||
headers: {
|
||||
"X-CSRF-Token": csrf
|
||||
},
|
||||
dataType: "json",
|
||||
data: {
|
||||
email: $usernameInput.val(),
|
||||
'custom-1216': 1
|
||||
"_id": email,
|
||||
"email": email,
|
||||
"username": $usernameInput.val()
|
||||
},
|
||||
success: function(resp) {
|
||||
return true;
|
||||
success: function (resp) {
|
||||
window.location = "/";
|
||||
},
|
||||
error: function(resp) {
|
||||
error: function (resp) {
|
||||
var error = JSON.parse(resp.responseText);
|
||||
if (error.error.code === 11000) {
|
||||
$errorContainer.text("Sorry, the username " + $usernameInput.val() + " is taken!");
|
||||
$usernameInput.val("");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: loginURL + "/user",
|
||||
headers: {
|
||||
"X-CSRF-Token": csrf
|
||||
},
|
||||
dataType: "json",
|
||||
data: {
|
||||
"_id": email,
|
||||
"email": email,
|
||||
"username": $usernameInput.val()
|
||||
},
|
||||
success: function(resp) {
|
||||
window.location = "/";
|
||||
},
|
||||
error: function(resp) {
|
||||
var error = JSON.parse(resp.responseText);
|
||||
if(error.error.code === 11000 ) {
|
||||
$errorContainer.text("Sorry, the username "+ $usernameInput.val() + " is taken!");
|
||||
$usernameInput.val("");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
var version = require( "../../package" ).version;
|
||||
var version = require("../../package").version;
|
||||
|
||||
module.exports = function( req, res ) {
|
||||
module.exports = function (req, res) {
|
||||
res.send({
|
||||
"http": "okay",
|
||||
"version": version
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
module.exports = function(domains) {
|
||||
module.exports = function (domains) {
|
||||
var realmResponse;
|
||||
|
||||
if (domains) {
|
||||
|
@ -7,7 +7,7 @@ module.exports = function(domains) {
|
|||
};
|
||||
}
|
||||
|
||||
return function(req, res, next) {
|
||||
return function (req, res, next) {
|
||||
if (!realmResponse) {
|
||||
return res.send(404);
|
||||
}
|
||||
|
|
|
@ -1,72 +1,73 @@
|
|||
module.exports = function(req, res) {
|
||||
module.exports = function (req, res) {
|
||||
var MAX_REMIXES = 5;
|
||||
var make = require("../lib/makeapi");
|
||||
|
||||
function renderError(message) {
|
||||
return res.render("details.html", {error:message});
|
||||
return res.render("details.html", {
|
||||
error: message
|
||||
});
|
||||
}
|
||||
|
||||
// Use a URL in the querystring or an ID
|
||||
var searchOptions = {},
|
||||
searchCriteria;
|
||||
if ( req.query.id ) {
|
||||
searchCriteria;
|
||||
if (req.query.id) {
|
||||
searchCriteria = "id";
|
||||
searchOptions.id = req.query.id;
|
||||
} else if ( req.query.url ) {
|
||||
} else if (req.query.url) {
|
||||
searchCriteria = "url";
|
||||
searchOptions.url = decodeURIComponent( req.query.url );
|
||||
searchOptions.url = decodeURIComponent(req.query.url);
|
||||
} else {
|
||||
return renderError("No URL or ID was passed");
|
||||
}
|
||||
|
||||
make.setLang(req.localeInfo.momentLang);
|
||||
make.find(searchOptions).process( function( err, data ) {
|
||||
if ( err ) {
|
||||
make.find(searchOptions).process(function (err, data) {
|
||||
if (err) {
|
||||
return renderError("Looks like there is a problem with the make API");
|
||||
}
|
||||
if ( data && !data.length ) {
|
||||
if (data && !data.length) {
|
||||
return renderError("No make was found :(");
|
||||
}
|
||||
var makeData = data[ 0 ];
|
||||
var makeData = data[0];
|
||||
|
||||
// Prep remixes, max of 10
|
||||
makeData.remixes( function( err, remixData, totalHits ) {
|
||||
if ( err ) {
|
||||
makeData.remixes(function (err, remixData, totalHits) {
|
||||
if (err) {
|
||||
return renderError("Looks like there is a problem with the make API");
|
||||
}
|
||||
makeData.remixList = [];
|
||||
|
||||
for ( var i = 0; i < Math.min( remixData.length, MAX_REMIXES ); i++ ) {
|
||||
for (var i = 0; i < Math.min(remixData.length, MAX_REMIXES); i++) {
|
||||
makeData.remixList.push({
|
||||
url: remixData[ i ].url,
|
||||
username: remixData[ i ].username
|
||||
url: remixData[i].url,
|
||||
username: remixData[i].username
|
||||
});
|
||||
}
|
||||
|
||||
if ( totalHits === 1 ) {
|
||||
if (totalHits === 1) {
|
||||
makeData.remixCount = "1 remix";
|
||||
} else {
|
||||
makeData.remixCount = totalHits + " remixes";
|
||||
}
|
||||
|
||||
// Prep original source
|
||||
if ( makeData.remixedFrom ) {
|
||||
make[ searchCriteria ]( makeData.remixedFrom ).then( function( err, remixedFromData ) {
|
||||
if ( err ) {
|
||||
return renderError( "Looks like there is a problem with the make API" );
|
||||
if (makeData.remixedFrom) {
|
||||
make[searchCriteria](makeData.remixedFrom).then(function (err, remixedFromData) {
|
||||
if (err) {
|
||||
return renderError("Looks like there is a problem with the make API");
|
||||
}
|
||||
|
||||
if ( remixedFromData && remixedFromData.length ) {
|
||||
if (remixedFromData && remixedFromData.length) {
|
||||
makeData.remixedFromData = {};
|
||||
makeData.remixedFromData.url = remixedFromData[ 0 ].url;
|
||||
makeData.remixedFromData.username = remixedFromData[ 0 ].username;
|
||||
makeData.remixedFromData.url = remixedFromData[0].url;
|
||||
makeData.remixedFromData.username = remixedFromData[0].username;
|
||||
}
|
||||
res.render( "details.html", makeData );
|
||||
res.render("details.html", makeData);
|
||||
});
|
||||
} else {
|
||||
res.render( "details.html", makeData );
|
||||
res.render("details.html", makeData);
|
||||
}
|
||||
});
|
||||
});
|
||||
}, req.session.id || '');
|
||||
};
|
||||
|
||||
|
|
|
@ -1,127 +1,129 @@
|
|||
var async = require("async"),
|
||||
make = require("../lib/makeapi");
|
||||
make = require("../lib/makeapi");
|
||||
|
||||
module.exports = function(options) {
|
||||
return function(req, res, next) {
|
||||
var DEFAULT_PREFIX = "p",
|
||||
DEFAULT_LAYOUT = "index",
|
||||
DEFAULT_STICKY_LIMIT = 24, // Larger to account for possible duplicates
|
||||
DEFAULT_LIMIT = 12,
|
||||
layouts = {
|
||||
index: {
|
||||
template: "make-flip.html",
|
||||
tags: ['webmaker:recommended'],
|
||||
process: function(makes) {
|
||||
if( makes[2] ) {
|
||||
makes[2].size = "large";
|
||||
}
|
||||
if( makes[3] ) {
|
||||
makes[3].size = "large";
|
||||
}
|
||||
return makes;
|
||||
}
|
||||
},
|
||||
teach: {
|
||||
template: "make-teach.html",
|
||||
tags: ['webmaker:teach']
|
||||
},
|
||||
starterMakes: {
|
||||
template: "make-starter-make.html",
|
||||
tags: ["webmaker:template"]
|
||||
},
|
||||
teachtheweb: {
|
||||
tags: ["webmaker:frontpage"]
|
||||
module.exports = function (options) {
|
||||
return function (req, res, next) {
|
||||
var DEFAULT_PREFIX = "p",
|
||||
DEFAULT_LAYOUT = "index",
|
||||
DEFAULT_STICKY_LIMIT = 24, // Larger to account for possible duplicates
|
||||
DEFAULT_LIMIT = 12,
|
||||
layouts = {
|
||||
index: {
|
||||
template: "make-flip.html",
|
||||
tags: ['webmaker:recommended'],
|
||||
process: function (makes) {
|
||||
if (makes[2]) {
|
||||
makes[2].size = "large";
|
||||
}
|
||||
};
|
||||
if (makes[3]) {
|
||||
makes[3].size = "large";
|
||||
}
|
||||
return makes;
|
||||
}
|
||||
},
|
||||
teach: {
|
||||
template: "make-teach.html",
|
||||
tags: ['webmaker:teach']
|
||||
},
|
||||
starterMakes: {
|
||||
template: "make-starter-make.html",
|
||||
tags: ["webmaker:template"]
|
||||
},
|
||||
teachtheweb: {
|
||||
tags: ["webmaker:frontpage"]
|
||||
}
|
||||
};
|
||||
|
||||
options = options || {};
|
||||
options = options || {};
|
||||
|
||||
// prefix: Set the app-tag prefix for our intial layout settings
|
||||
var prefix = options.prefix || (req.query.prefix || DEFAULT_PREFIX).toString(),
|
||||
stickyPrefix = "webmaker:" + (prefix + "-");
|
||||
// prefix: Set the app-tag prefix for our intial layout settings
|
||||
var prefix = options.prefix || (req.query.prefix || DEFAULT_PREFIX).toString(),
|
||||
stickyPrefix = "webmaker:" + (prefix + "-");
|
||||
|
||||
// layout: Choose a layout - should it look like the home or teach page?
|
||||
// Sets the processing function and template piece
|
||||
var layoutName = options.layout || (req.query.layout || DEFAULT_LAYOUT).toString(),
|
||||
layout = layouts[layoutName] || layouts[DEFAULT_LAYOUT];
|
||||
layout.name = layoutName;
|
||||
// layout: Choose a layout - should it look like the home or teach page?
|
||||
// Sets the processing function and template piece
|
||||
var layoutName = options.layout || (req.query.layout || DEFAULT_LAYOUT).toString(),
|
||||
layout = layouts[layoutName] || layouts[DEFAULT_LAYOUT];
|
||||
layout.name = layoutName;
|
||||
|
||||
// page: This is for rendering the view.
|
||||
var page = options.page || layoutName;
|
||||
// page: This is for rendering the view.
|
||||
var page = options.page || layoutName;
|
||||
|
||||
// limit
|
||||
var limit = options.limit || DEFAULT_LIMIT;
|
||||
var stickyLimit = options.limit ? options.limit * 2 : DEFAULT_STICKY_LIMIT;
|
||||
var totalHitCount = [];
|
||||
// limit
|
||||
var limit = options.limit || DEFAULT_LIMIT;
|
||||
var stickyLimit = options.limit ? options.limit * 2 : DEFAULT_STICKY_LIMIT;
|
||||
var totalHitCount = [];
|
||||
|
||||
function getMakes(options, callback) {
|
||||
make.setLang(req.localeInfo.momentLang);
|
||||
make
|
||||
.find(options)
|
||||
.process( function( err, data, totalHits ) {
|
||||
totalHitCount.push(totalHits);
|
||||
callback(err, data);
|
||||
}, req.session.id || '');
|
||||
function getMakes(options, callback) {
|
||||
make.setLang(req.localeInfo.momentLang);
|
||||
make
|
||||
.find(options)
|
||||
.process(function (err, data, totalHits) {
|
||||
totalHitCount.push(totalHits);
|
||||
callback(err, data);
|
||||
}, req.session.id || '');
|
||||
}
|
||||
|
||||
var stickyOptions = {
|
||||
tagPrefix: stickyPrefix,
|
||||
limit: stickyLimit,
|
||||
sortByField: ["createdAt", "desc"]
|
||||
};
|
||||
|
||||
var normalOptions = {
|
||||
tagPrefix: [stickyPrefix, true], // true = NOT search
|
||||
tags: {
|
||||
tags: layout.tags
|
||||
},
|
||||
limit: limit,
|
||||
sortByField: ["createdAt", "desc"]
|
||||
};
|
||||
|
||||
async.map([stickyOptions, normalOptions], getMakes, function (err, data) {
|
||||
var sticky = [],
|
||||
warnings = [],
|
||||
normal,
|
||||
all = [],
|
||||
sortByPriorityResults,
|
||||
totalNormalHits;
|
||||
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
var stickyOptions = {
|
||||
tagPrefix: stickyPrefix,
|
||||
limit: stickyLimit,
|
||||
sortByField: ["createdAt", "desc"]
|
||||
};
|
||||
if (data[0].length) {
|
||||
sortByPriorityResults = make.sortByPriority(stickyPrefix, data[0]);
|
||||
sticky = sortByPriorityResults.results;
|
||||
warnings = warnings.concat(sortByPriorityResults.errors);
|
||||
}
|
||||
|
||||
var normalOptions = {
|
||||
tagPrefix: [stickyPrefix, true], // true = NOT search
|
||||
tags: { tags: layout.tags },
|
||||
// Send warning messages to editor about missing stickies
|
||||
for (var i = 0; i < limit; i++) {
|
||||
if (!sticky[i]) {
|
||||
warnings.push("No sticky set for " + stickyPrefix + (i + 1));
|
||||
}
|
||||
}
|
||||
|
||||
totalNormalHits = totalHitCount[1]; // We stored totals for sticky and normal
|
||||
normal = data[1];
|
||||
all = sticky.concat(normal);
|
||||
|
||||
// Is there a special processing function for this layout?
|
||||
if (layout.process) {
|
||||
all = layout.process(all);
|
||||
}
|
||||
|
||||
res.render(page + ".html", {
|
||||
makes: all,
|
||||
totalHits: totalNormalHits,
|
||||
limit: limit,
|
||||
sortByField: ["createdAt", "desc"]
|
||||
};
|
||||
|
||||
async.map([stickyOptions, normalOptions], getMakes, function(err, data) {
|
||||
var sticky = [],
|
||||
warnings = [],
|
||||
normal,
|
||||
all = [],
|
||||
sortByPriorityResults,
|
||||
totalNormalHits;
|
||||
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
if (data[0].length) {
|
||||
sortByPriorityResults = make.sortByPriority(stickyPrefix, data[0]);
|
||||
sticky = sortByPriorityResults.results;
|
||||
warnings = warnings.concat(sortByPriorityResults.errors);
|
||||
}
|
||||
|
||||
// Send warning messages to editor about missing stickies
|
||||
for(i=0; i<limit; i++) {
|
||||
if(!sticky[i]) {
|
||||
warnings.push("No sticky set for " + stickyPrefix + (i+1));
|
||||
}
|
||||
}
|
||||
|
||||
totalNormalHits = totalHitCount[1]; // We stored totals for sticky and normal
|
||||
normal = data[1];
|
||||
all = sticky.concat(normal);
|
||||
|
||||
// Is there a special processing function for this layout?
|
||||
if (layout.process) {
|
||||
all = layout.process(all);
|
||||
}
|
||||
|
||||
res.render( page + ".html", {
|
||||
makes: all,
|
||||
totalHits: totalNormalHits,
|
||||
limit: limit,
|
||||
warnings: warnings,
|
||||
page: page,
|
||||
prefix: prefix,
|
||||
layout: layout.name,
|
||||
template: layout.template,
|
||||
isAdmin: req.isAdmin || false
|
||||
});
|
||||
warnings: warnings,
|
||||
page: page,
|
||||
prefix: prefix,
|
||||
layout: layout.name,
|
||||
template: layout.template,
|
||||
isAdmin: req.isAdmin || false
|
||||
});
|
||||
};
|
||||
});
|
||||
};
|
||||
};
|
||||
|
|
|
@ -5,31 +5,31 @@ module.exports = {
|
|||
browserid: require("./browserid"),
|
||||
details: require("./details"),
|
||||
gallery: require("./gallery"),
|
||||
include: function( options ) {
|
||||
return function( req, res ) {
|
||||
res.render( "sso/include.html", options);
|
||||
include: function (options) {
|
||||
return function (req, res) {
|
||||
res.render("sso/include.html", options);
|
||||
};
|
||||
},
|
||||
includejs: function( hostname ) {
|
||||
return function( req, res ) {
|
||||
res.set( "Content-Type", "application/javascript;charset=utf-8" );
|
||||
res.render( "sso/include.js", {
|
||||
includejs: function (hostname) {
|
||||
return function (req, res) {
|
||||
res.set("Content-Type", "application/javascript;charset=utf-8");
|
||||
res.render("sso/include.js", {
|
||||
HOSTNAME: hostname
|
||||
});
|
||||
};
|
||||
},
|
||||
me: require("./me"),
|
||||
page: function( view ) {
|
||||
page: function (view) {
|
||||
return require("./page")(view);
|
||||
},
|
||||
remove: require("./remove"),
|
||||
like: require("./like")(),
|
||||
search: require("./search"),
|
||||
tag: function( req, res ) {
|
||||
res.redirect( "/" + req.localeInfo.lang + "/search?type=tags&q=" + req.params.tag );
|
||||
tag: function (req, res) {
|
||||
res.redirect("/" + req.localeInfo.lang + "/search?type=tags&q=" + req.params.tag);
|
||||
},
|
||||
user: require("./user"),
|
||||
usersearch: function( req, res ) {
|
||||
res.redirect( "/" + req.localeInfo.lang + "/search?type=user&q=" + req.params.user );
|
||||
usersearch: function (req, res) {
|
||||
res.redirect("/" + req.localeInfo.lang + "/search?type=user&q=" + req.params.user);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,34 +1,34 @@
|
|||
module.exports = function() {
|
||||
var make = require( "../lib/makeapi" );
|
||||
module.exports = function () {
|
||||
var make = require("../lib/makeapi");
|
||||
return {
|
||||
like: function( req, res ) {
|
||||
like: function (req, res) {
|
||||
var id = req.body.makeID,
|
||||
maker = req.session.username;
|
||||
maker = req.session.username;
|
||||
|
||||
if ( maker ) {
|
||||
make.like( id, maker, function( err, data ) {
|
||||
if ( err || !data ) {
|
||||
return res.send( 400, err || "Something went wrong." );
|
||||
if (maker) {
|
||||
make.like(id, maker, function (err, data) {
|
||||
if (err || !data) {
|
||||
return res.send(400, err || "Something went wrong.");
|
||||
}
|
||||
res.json( 200, data );
|
||||
res.json(200, data);
|
||||
});
|
||||
} else {
|
||||
res.send( 401, "Not Logged In" );
|
||||
res.send(401, "Not Logged In");
|
||||
}
|
||||
},
|
||||
unlike: function( req, res ) {
|
||||
unlike: function (req, res) {
|
||||
var id = req.body.makeID,
|
||||
maker = req.session.username;
|
||||
maker = req.session.username;
|
||||
|
||||
if ( maker ) {
|
||||
make.unlike( id, maker, function( err, data ) {
|
||||
if ( err || !data ) {
|
||||
return res.send( 400, err || "something went wrong" );
|
||||
if (maker) {
|
||||
make.unlike(id, maker, function (err, data) {
|
||||
if (err || !data) {
|
||||
return res.send(400, err || "something went wrong");
|
||||
}
|
||||
res.json( 200, data );
|
||||
res.json(200, data);
|
||||
});
|
||||
} else {
|
||||
res.send( 401, "Not Logged In" );
|
||||
res.send(401, "Not Logged In");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
54
routes/me.js
54
routes/me.js
|
@ -1,16 +1,16 @@
|
|||
module.exports = function( req, res ) {
|
||||
module.exports = function (req, res) {
|
||||
var make = require("../lib/makeapi"),
|
||||
username = req.session.username,
|
||||
page = req.query.page || 1,
|
||||
app = req.query.app,
|
||||
options = {},
|
||||
limit = 50;
|
||||
username = req.session.username,
|
||||
page = req.query.page || 1,
|
||||
app = req.query.app,
|
||||
options = {},
|
||||
limit = 50;
|
||||
|
||||
// MakeAPI doesn't handle undefined being passed for user. To
|
||||
// prevent the MakeAPI error showing when no signed in user accesses the page
|
||||
// I'm checking here first.
|
||||
if ( !username ) {
|
||||
res.render( "me.html", {
|
||||
if (!username) {
|
||||
res.render("me.html", {
|
||||
page: "me",
|
||||
view: app || "webmaker"
|
||||
});
|
||||
|
@ -19,29 +19,29 @@ module.exports = function( req, res ) {
|
|||
|
||||
// Set up search options
|
||||
options.user = username;
|
||||
if ( app ) {
|
||||
if (app) {
|
||||
options.contentType = "application/x-" + app;
|
||||
}
|
||||
|
||||
make.setLang(req.localeInfo.momentLang);
|
||||
make.find( options )
|
||||
.limit( limit )
|
||||
.sortByField( "updatedAt", "desc" )
|
||||
.page( page )
|
||||
.process( function( err, data, totalHits ) {
|
||||
if ( err ) {
|
||||
return res.send( err );
|
||||
}
|
||||
make.find(options)
|
||||
.limit(limit)
|
||||
.sortByField("updatedAt", "desc")
|
||||
.page(page)
|
||||
.process(function (err, data, totalHits) {
|
||||
if (err) {
|
||||
return res.send(err);
|
||||
}
|
||||
|
||||
res.render( "me.html", {
|
||||
makes: data || [],
|
||||
page: "me",
|
||||
pagination: page,
|
||||
view: app || "webmaker",
|
||||
totalHits: totalHits,
|
||||
limit: limit,
|
||||
showPagination: ( totalHits > limit ),
|
||||
username: username
|
||||
res.render("me.html", {
|
||||
makes: data || [],
|
||||
page: "me",
|
||||
pagination: page,
|
||||
view: app || "webmaker",
|
||||
totalHits: totalHits,
|
||||
limit: limit,
|
||||
showPagination: (totalHits > limit),
|
||||
username: username
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
module.exports = function( view ) {
|
||||
return function( req, res ) {
|
||||
res.render( view + ".html", {
|
||||
module.exports = function (view) {
|
||||
return function (req, res) {
|
||||
res.render(view + ".html", {
|
||||
page: view
|
||||
});
|
||||
};
|
||||
|
|
|
@ -1,69 +1,67 @@
|
|||
module.exports = function( app ) {
|
||||
module.exports = function (app) {
|
||||
|
||||
var redirectMap = [
|
||||
{
|
||||
route: "/",
|
||||
paths: [
|
||||
"/projects",
|
||||
"/projects/:id",
|
||||
"/support",
|
||||
"/videos",
|
||||
"/hall-of-fame",
|
||||
"/ITU",
|
||||
"/ITU/*"
|
||||
]
|
||||
}, {
|
||||
route: "/tools",
|
||||
paths: [
|
||||
"/tools/x-ray-goggles",
|
||||
"/tools/x-ray-goggles/install"
|
||||
]
|
||||
}, {
|
||||
route: "/party",
|
||||
paths: [
|
||||
"/partners"
|
||||
]
|
||||
}, {
|
||||
// Switch to SSL after Bug 883370 lands.
|
||||
route: "http://blog.webmaker.org",
|
||||
paths: [
|
||||
"/news"
|
||||
]
|
||||
}, {
|
||||
route: "/teach",
|
||||
paths: [
|
||||
"/network",
|
||||
"/kits",
|
||||
"/kit-prototypes"
|
||||
]
|
||||
}, {
|
||||
route: "/getinvolved",
|
||||
paths: [
|
||||
"/build",
|
||||
"/get-involved"
|
||||
]
|
||||
}, {
|
||||
route: "/mentor",
|
||||
paths: [
|
||||
"/connect"
|
||||
]
|
||||
}, {
|
||||
route: "/event-guides",
|
||||
paths: [
|
||||
"/guides"
|
||||
]
|
||||
}, {
|
||||
route: "https://support.mozilla.org/kb/translate-webmaker",
|
||||
paths: [
|
||||
"/translate"
|
||||
]
|
||||
}
|
||||
];
|
||||
var redirectMap = [{
|
||||
route: "/",
|
||||
paths: [
|
||||
"/projects",
|
||||
"/projects/:id",
|
||||
"/support",
|
||||
"/videos",
|
||||
"/hall-of-fame",
|
||||
"/ITU",
|
||||
"/ITU/*"
|
||||
]
|
||||
}, {
|
||||
route: "/tools",
|
||||
paths: [
|
||||
"/tools/x-ray-goggles",
|
||||
"/tools/x-ray-goggles/install"
|
||||
]
|
||||
}, {
|
||||
route: "/party",
|
||||
paths: [
|
||||
"/partners"
|
||||
]
|
||||
}, {
|
||||
// Switch to SSL after Bug 883370 lands.
|
||||
route: "http://blog.webmaker.org",
|
||||
paths: [
|
||||
"/news"
|
||||
]
|
||||
}, {
|
||||
route: "/teach",
|
||||
paths: [
|
||||
"/network",
|
||||
"/kits",
|
||||
"/kit-prototypes"
|
||||
]
|
||||
}, {
|
||||
route: "/getinvolved",
|
||||
paths: [
|
||||
"/build",
|
||||
"/get-involved"
|
||||
]
|
||||
}, {
|
||||
route: "/mentor",
|
||||
paths: [
|
||||
"/connect"
|
||||
]
|
||||
}, {
|
||||
route: "/event-guides",
|
||||
paths: [
|
||||
"/guides"
|
||||
]
|
||||
}, {
|
||||
route: "https://support.mozilla.org/kb/translate-webmaker",
|
||||
paths: [
|
||||
"/translate"
|
||||
]
|
||||
}];
|
||||
|
||||
redirectMap.forEach(function( redirect ) {
|
||||
redirect.paths.forEach(function( legacyRoute ) {
|
||||
app.get( legacyRoute, function( req, res ){
|
||||
res.redirect( 301, redirect.route );
|
||||
redirectMap.forEach(function (redirect) {
|
||||
redirect.paths.forEach(function (legacyRoute) {
|
||||
app.get(legacyRoute, function (req, res) {
|
||||
res.redirect(301, redirect.route);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,29 +1,28 @@
|
|||
module.exports = function( req, res ) {
|
||||
module.exports = function (req, res) {
|
||||
var make = require("../lib/makeapi");
|
||||
var id = req.body.makeID;
|
||||
|
||||
make.id( id ).then( function( err, data ) {
|
||||
if ( err ) {
|
||||
return res.send( err );
|
||||
make.id(id).then(function (err, data) {
|
||||
if (err) {
|
||||
return res.send(err);
|
||||
}
|
||||
|
||||
if ( data && !data.length ) {
|
||||
return res.send( "Sorry, we couldn't find a make with that id!" );
|
||||
if (data && !data.length) {
|
||||
return res.send("Sorry, we couldn't find a make with that id!");
|
||||
}
|
||||
|
||||
var username = data[0].username;
|
||||
|
||||
if ( username === req.session.username ) {
|
||||
make.remove( id, function( err, data ) {
|
||||
if ( err ) {
|
||||
res.send( err );
|
||||
if (username === req.session.username) {
|
||||
make.remove(id, function (err, data) {
|
||||
if (err) {
|
||||
res.send(err);
|
||||
} else {
|
||||
res.json( data );
|
||||
res.json(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
res.send( "Sorry, looks like you don't have permission to delete this make :(" );
|
||||
} else {
|
||||
res.send("Sorry, looks like you don't have permission to delete this make :(");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
124
routes/search.js
124
routes/search.js
|
@ -1,98 +1,98 @@
|
|||
module.exports = function(req, res) {
|
||||
module.exports = function (req, res) {
|
||||
var make = require("../lib/makeapi"),
|
||||
querystring = require("querystring");
|
||||
querystring = require("querystring");
|
||||
|
||||
var DEFAULT_TYPE = "tags",
|
||||
DEFAULT_QUERY = "webmaker:featured",
|
||||
VALID_TYPES = [
|
||||
"all",
|
||||
"tags",
|
||||
"title",
|
||||
"user",
|
||||
"description"
|
||||
],
|
||||
VALID_CONTENT_TYPES = [
|
||||
"application/x-thimble",
|
||||
"application/x-popcorn"
|
||||
];
|
||||
DEFAULT_QUERY = "webmaker:featured",
|
||||
VALID_TYPES = [
|
||||
"all",
|
||||
"tags",
|
||||
"title",
|
||||
"user",
|
||||
"description"
|
||||
],
|
||||
VALID_CONTENT_TYPES = [
|
||||
"application/x-thimble",
|
||||
"application/x-popcorn"
|
||||
];
|
||||
|
||||
var type = ( req.query.type || DEFAULT_TYPE ).toString(),
|
||||
contentType = ( req.query.contentType || '' ).toString(),
|
||||
sortByField = ( req.query.sortByField || "createdAt" ).toString(),
|
||||
sortByOrder = ( req.query.order || "desc" ).toString(),
|
||||
page = ( req.query.page || 1 ).toString(),
|
||||
setToAll = !( req.query.type || req.query.q ||
|
||||
req.query.contentType || req.query.sortByField ||
|
||||
req.query.order || req.query.page ),
|
||||
options = {},
|
||||
query,
|
||||
hideNamespace = false;
|
||||
var type = (req.query.type || DEFAULT_TYPE).toString(),
|
||||
contentType = (req.query.contentType || '').toString(),
|
||||
sortByField = (req.query.sortByField || "createdAt").toString(),
|
||||
sortByOrder = (req.query.order || "desc").toString(),
|
||||
page = (req.query.page || 1).toString(),
|
||||
setToAll = !(req.query.type || req.query.q ||
|
||||
req.query.contentType || req.query.sortByField ||
|
||||
req.query.order || req.query.page),
|
||||
options = {},
|
||||
query,
|
||||
hideNamespace = false;
|
||||
|
||||
if ( !req.query.q ) {
|
||||
if (!req.query.q) {
|
||||
query = DEFAULT_QUERY;
|
||||
hideNamespace = true;
|
||||
} else {
|
||||
query = req.query.q.toString();
|
||||
}
|
||||
|
||||
if ( VALID_TYPES.indexOf( type ) === -1 ) {
|
||||
if (VALID_TYPES.indexOf(type) === -1) {
|
||||
type = DEFAULT_TYPE;
|
||||
}
|
||||
|
||||
if ( type === 'all' ) {
|
||||
if (type === 'all') {
|
||||
make.or();
|
||||
options.title = options.user = options.description = query;
|
||||
options.title = options.user = options.description = query;
|
||||
}
|
||||
|
||||
if ( type === 'all' || type === 'tags' ) {
|
||||
if (type === 'all' || type === 'tags') {
|
||||
var tags = query.split(',');
|
||||
options.tags = [];
|
||||
options.tags[0] = tags.map(function( t ) {
|
||||
options.tags[0] = tags.map(function (t) {
|
||||
return t.trim();
|
||||
});
|
||||
} else {
|
||||
// check for '@', remove
|
||||
if ( query[0] === '@' ) {
|
||||
if (query[0] === '@') {
|
||||
query = query.slice(1);
|
||||
}
|
||||
options[ type ] = query;
|
||||
options[type] = query;
|
||||
}
|
||||
|
||||
if ( contentType ) {
|
||||
var cleanCT = querystring.unescape( contentType );
|
||||
if ( VALID_CONTENT_TYPES.indexOf( contentType ) !== -1 ) {
|
||||
if (contentType) {
|
||||
var cleanCT = querystring.unescape(contentType);
|
||||
if (VALID_CONTENT_TYPES.indexOf(contentType) !== -1) {
|
||||
options.contentType = cleanCT;
|
||||
}
|
||||
}
|
||||
|
||||
var limit = 12;
|
||||
make.find( options )
|
||||
.limit( limit )
|
||||
.sortByField( sortByField, sortByOrder )
|
||||
.page( page )
|
||||
.process(function( err, data, totalHits ) {
|
||||
if( err ) {
|
||||
return res.send(err);
|
||||
}
|
||||
// query can be an array of tags sometimes,
|
||||
// so force a string so that it's autoescaped
|
||||
var query = type === "all" ? options.title.toString() : options[type].toString(),
|
||||
showOlder = ( totalHits > page * limit );
|
||||
make.find(options)
|
||||
.limit(limit)
|
||||
.sortByField(sortByField, sortByOrder)
|
||||
.page(page)
|
||||
.process(function (err, data, totalHits) {
|
||||
if (err) {
|
||||
return res.send(err);
|
||||
}
|
||||
// query can be an array of tags sometimes,
|
||||
// so force a string so that it's autoescaped
|
||||
var query = type === "all" ? options.title.toString() : options[type].toString(),
|
||||
showOlder = (totalHits > page * limit);
|
||||
|
||||
if ( hideNamespace ) {
|
||||
query = "featured";
|
||||
}
|
||||
if (hideNamespace) {
|
||||
query = "featured";
|
||||
}
|
||||
|
||||
res.render( "search.html", {
|
||||
hasQuery: !!req.query.q,
|
||||
makes: data || [],
|
||||
page: "search",
|
||||
pagination: page,
|
||||
totalHits: totalHits,
|
||||
limit: limit,
|
||||
query: query,
|
||||
searchType: type,
|
||||
searchIcon: setToAll ? "all" : type
|
||||
res.render("search.html", {
|
||||
hasQuery: !! req.query.q,
|
||||
makes: data || [],
|
||||
page: "search",
|
||||
pagination: page,
|
||||
totalHits: totalHits,
|
||||
limit: limit,
|
||||
query: query,
|
||||
searchType: type,
|
||||
searchIcon: setToAll ? "all" : type
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
module.exports.login = function( req, res ){
|
||||
module.exports.login = function (req, res) {
|
||||
res.render('user/login.html', {
|
||||
page: "login"
|
||||
page: "login"
|
||||
});
|
||||
};
|
||||
module.exports.newaccount = function( req, res ){
|
||||
if ( !req.session.email ) {
|
||||
return res.redirect( "/login" );
|
||||
module.exports.newaccount = function (req, res) {
|
||||
if (!req.session.email) {
|
||||
return res.redirect("/login");
|
||||
}
|
||||
res.render('user/new.html', {
|
||||
page: "new"
|
||||
page: "new"
|
||||
});
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче