<commit_before>//
// Sets up initial project settings, middleware, mounted apps, and
// global configuration such as overriding Backbone.sync and
// populating sharify data
//

import ddTracer from 'dd-trace'
import _ from 'underscore'
import addRequestId from 'express-request-id'
import artsyPassport from '@artsy/passport'
import artsyXapp from 'artsy-xapp'
import { argv } from 'yargs'
import Backbone from 'backbone'
import bodyParser from 'body-parser'
import bucketAssets from 'bucket-assets'
import cookieParser from 'cookie-parser'
import express from 'express'
import favicon from 'serve-favicon'
import glob from 'glob'
import helmet from 'helmet'
import logger from 'artsy-morgan'
import path from 'path'
import RavenServer from 'raven'
import session from 'cookie-session'
import sharify from 'sharify'
import siteAssociation from 'artsy-eigen-web-association'
import superSync from 'backbone-super-sync'
import { IpFilter as ipfilter } from 'express-ipfilter'
import timeout from 'connect-timeout'
import './setup_sharify'
import cache from './cache'
import downcase from './middleware/downcase'
import ensureSSL from './middleware/ensure_ssl'
import escapedFragmentMiddleware from './middleware/escaped_fragment'
import hardcodedRedirects from './middleware/hardcoded_redirects'
import hstsMiddleware from './middleware/hsts'
import localsMiddleware from './middleware/locals'
import proxyGravity from './middleware/proxy_to_gravity'
import proxyReflection from './middleware/proxy_to_reflection'
import sameOriginMiddleware from './middleware/same_origin'
import errorHandlingMiddleware from './middleware/error_handler'
import unsupportedBrowserCheck from './middleware/unsupported_browser'
import backboneErrorHelper from './middleware/backbone_error_helper'
import CurrentUser from './current_user'
import splitTestMiddleware from '../desktop/components/split_test/middleware'
import marketingModals from './middleware/marketing_modals'
import config from '../config'
import compression from 'compression'

const {
  API_REQUEST_TIMEOUT,
  API_URL,
  APP_TIMEOUT,
  COOKIE_DOMAIN,
  DEFAULT_CACHE_TIME,
  IP_BLACKLIST,
  NODE_ENV,
  OPENREDIS_URL,
  REQUEST_EXPIRE_MS,
  REQUEST_LIMIT,
  SENTRY_PRIVATE_DSN,
  SEGMENT_WRITE_KEY_SERVER,
  SESSION_COOKIE_KEY,
  SESSION_COOKIE_MAX_AGE,
  SESSION_SECRET,
  DD_APM_ENABLED,
} = config

export default function(app) {
  // Timeout middleware
  if (NODE_ENV === 'production') app.use(timeout(APP_TIMEOUT || '29s'))

  // Error reporting
  if (SENTRY_PRIVATE_DSN) {
    RavenServer.config(SENTRY_PRIVATE_DSN).install()
    app.use(RavenServer.requestHandler())
  }

  // Minification and compression
  app.use(compression())

  // Blacklist IPs
  app.use(
    ipfilter(IP_BLACKLIST.split(','), {
      allowedHeaders: ['x-forwarded-for'],
      log: false,
      mode: 'deny',
    })
  )

  // Rate limiting
  if (OPENREDIS_URL && cache.client) {
    const limiter = require('express-limiter')(app, cache.client)
    limiter({
      path: '*',
      method: 'all',
      lookup: ['headers.x-forwarded-for'],
      total: REQUEST_LIMIT,
      expire: REQUEST_EXPIRE_MS,
      onRateLimited(req, res, next) {
        console.log('Rate limit exceeded for', req.headers['x-forwarded-for'])
        return next()
      },
    })
  }

  // Blank page used by Eigen for caching web views.
  // See: https://github.com/artsy/microgravity-private/pull/1138
  app.use(require('../desktop/apps/blank'))

  // Make sure we're using SSL and prevent clickjacking
  app.use(ensureSSL)
  app.use(hstsMiddleware)
  if (!NODE_ENV === 'test') app.use(helmet.frameguard())

  // Inject UUID for each request into the X-Request-Id header
  app.use(addRequestId())

  // Override Backbone to use server-side sync, inject the XAPP token,
  // add redis caching, and timeout for slow responses.
  superSync.timeout = API_REQUEST_TIMEOUT
  superSync.cacheClient = cache.client
  superSync.defaultCacheTime = DEFAULT_CACHE_TIME
  Backbone.sync = function(method, model, options) {
    if (options.headers == null) {
      options.headers = {}
    }
    options.headers['X-XAPP-TOKEN'] = artsyXapp.token || ''
    return superSync(method, model, options)
  }

  // Inject sharify data before any app code
  app.use(sharify)

  // Cookie and session middleware
  app.use(cookieParser())
  app.set('trust proxy', true)
  app.use(
    session({
      secret: SESSION_SECRET,
      domain: NODE_ENV === 'development' ? '' : COOKIE_DOMAIN,
      name: SESSION_COOKIE_KEY,
      maxAge: SESSION_COOKIE_MAX_AGE,
      secure: NODE_ENV === 'production' || NODE_ENV === 'staging',
      httpOnly: false,
    })
  )

  // Body parser has to be after proxy middleware for
  // node-http-proxy to work with POST/PUT/DELETE
  app.use('/api', proxyGravity.api)
  app.use(proxyReflection)
  app.use(bodyParser.json())
  app.use(bodyParser.urlencoded({ extended: true }))

  // Passport middleware for authentication.
  app.use(
    artsyPassport(
      _.extend({}, config, {
        CurrentUser: CurrentUser,
        ARTSY_URL: API_URL,
        SEGMENT_WRITE_KEY: SEGMENT_WRITE_KEY_SERVER,
        userKeys: [
          'collector_level',
          'default_profile_id',
          'email',
          'has_partner_access',
          'id',
          'lab_features',
          'name',
          'paddle_number',
          'phone',
          'type',
        ],
      })
    )
  )

  // Static assets
  if (NODE_ENV === 'development') {
    app.use(require('./webpack-dev-server'))

    app.use(
      require('stylus').middleware({
        src: path.resolve(__dirname, '../desktop'),
        dest: path.resolve(__dirname, '../desktop/public'),
      })
    )
    app.use(
      require('stylus').middleware({
        src: path.resolve(__dirname, '../mobile'),
        dest: path.resolve(__dirname, '../mobile/public'),
      })
    )
  }
  glob
    .sync(`${__dirname}/../{public,{desktop,mobile}/**/public}`)
    .forEach(fld => app.use(express.static(fld)))
  app.use(
    favicon(path.resolve(__dirname, '../mobile/public/images/favicon.ico'))
  )
  app.use('/(.well-known/)?apple-app-site-association', siteAssociation)

  // Redirect requests before they even have to deal with Force routing
  app.use(downcase)
  app.use(hardcodedRedirects)

  // General helpers and express middleware
  if (argv.debugProd) {
    // Mount static webserver instead of requesting assets through bucket
    // manifest. Pass in --debugProd on boot.
    app.use(express.static('public'))
  } else {
    app.use(bucketAssets())
  }

  app.use(localsMiddleware)
  app.use(backboneErrorHelper)
  app.use(sameOriginMiddleware)
  app.use(escapedFragmentMiddleware)
  app.use(logger)
  app.use(unsupportedBrowserCheck)
  app.use(splitTestMiddleware)

  if (DD_APM_ENABLED) {
    // DataDog automatically hooks into Express
    // https://datadog.github.io/dd-trace-js/index.html
    // and we use all the defaults from:
    // https://github.com/DataDog/dd-trace-js/blob/master/docs/API.md#tracer-settings
    ddTracer.init({})
  }

  // Sets up mobile marketing signup modal
  app.use(marketingModals)

  // Setup hot-swap loader
  if (NODE_ENV === 'development') {
    const { createReloadable } = require('@artsy/express-reloadable')
    const mountAndReload = createReloadable(app, require)

    app.use((req, res, next) => {
      if (res.locals.sd.IS_MOBILE) {
        const mobileApp = mountAndReload(path.resolve('src/mobile'))
        mobileApp(req, res, next)
      } else {
        next()
      }
    })

    mountAndReload(path.resolve('src/desktop'), {
      watchModules: ['@artsy/reaction', '@artsy/stitch'],
    })

    // In staging or prod, mount routes normally
  } else {
    app.use((req, res, next) => {
      if (argv.debugProd) {
        res.locals.asset = filename => filename // Stub bucketAssets middleware helper
      }

      // Direct mobile devices to the mobile app, otherwise fall through to
      // the desktop app
      if (res.locals.sd.IS_MOBILE) {
        require('../mobile')(req, res, next)
      } else {
        next()
      }
    })
    app.use(require('../desktop'))
  }

  // Routes for pinging system time and up
  app.get('/system/time', (req, res) => res.send(200, { time: Date.now() }))
  app.get('/system/up', (req, res) => res.send(200, { nodejs: true }))

  // Ensure CurrentUser is set for Artsy Passport
  // TODO: Investigate race condition b/t reaction's use of AP
  artsyPassport.options.CurrentUser = CurrentUser

  // 404 handler
  app.get('*', (req, res, next) => {
    const err = new Error()
    err.status = 404
    err.message = 'Not Found'
    next(err)
  })

  // Last but not least, error handling...
  if (SENTRY_PRIVATE_DSN) app.use(RavenServer.errorHandler())
  app.use(errorHandlingMiddleware)
}
<commit_msg>Try adding the hostname specifically to ddTracer<commit_after>//
// Sets up initial project settings, middleware, mounted apps, and
// global configuration such as overriding Backbone.sync and
// populating sharify data
//

import ddTracer from 'dd-trace'
import _ from 'underscore'
import addRequestId from 'express-request-id'
import artsyPassport from '@artsy/passport'
import artsyXapp from 'artsy-xapp'
import { argv } from 'yargs'
import Backbone from 'backbone'
import bodyParser from 'body-parser'
import bucketAssets from 'bucket-assets'
import cookieParser from 'cookie-parser'
import express from 'express'
import favicon from 'serve-favicon'
import glob from 'glob'
import helmet from 'helmet'
import logger from 'artsy-morgan'
import path from 'path'
import RavenServer from 'raven'
import session from 'cookie-session'
import sharify from 'sharify'
import siteAssociation from 'artsy-eigen-web-association'
import superSync from 'backbone-super-sync'
import { IpFilter as ipfilter } from 'express-ipfilter'
import timeout from 'connect-timeout'
import './setup_sharify'
import cache from './cache'
import downcase from './middleware/downcase'
import ensureSSL from './middleware/ensure_ssl'
import escapedFragmentMiddleware from './middleware/escaped_fragment'
import hardcodedRedirects from './middleware/hardcoded_redirects'
import hstsMiddleware from './middleware/hsts'
import localsMiddleware from './middleware/locals'
import proxyGravity from './middleware/proxy_to_gravity'
import proxyReflection from './middleware/proxy_to_reflection'
import sameOriginMiddleware from './middleware/same_origin'
import errorHandlingMiddleware from './middleware/error_handler'
import unsupportedBrowserCheck from './middleware/unsupported_browser'
import backboneErrorHelper from './middleware/backbone_error_helper'
import CurrentUser from './current_user'
import splitTestMiddleware from '../desktop/components/split_test/middleware'
import marketingModals from './middleware/marketing_modals'
import config from '../config'
import compression from 'compression'

const {
  API_REQUEST_TIMEOUT,
  API_URL,
  APP_TIMEOUT,
  COOKIE_DOMAIN,
  DEFAULT_CACHE_TIME,
  IP_BLACKLIST,
  NODE_ENV,
  OPENREDIS_URL,
  REQUEST_EXPIRE_MS,
  REQUEST_LIMIT,
  SENTRY_PRIVATE_DSN,
  SEGMENT_WRITE_KEY_SERVER,
  SESSION_COOKIE_KEY,
  SESSION_COOKIE_MAX_AGE,
  SESSION_SECRET,
  DD_APM_ENABLED,
} = config

export default function(app) {
  // Timeout middleware
  if (NODE_ENV === 'production') app.use(timeout(APP_TIMEOUT || '29s'))

  // Error reporting
  if (SENTRY_PRIVATE_DSN) {
    RavenServer.config(SENTRY_PRIVATE_DSN).install()
    app.use(RavenServer.requestHandler())
  }

  // Minification and compression
  app.use(compression())

  // Blacklist IPs
  app.use(
    ipfilter(IP_BLACKLIST.split(','), {
      allowedHeaders: ['x-forwarded-for'],
      log: false,
      mode: 'deny',
    })
  )

  // Rate limiting
  if (OPENREDIS_URL && cache.client) {
    const limiter = require('express-limiter')(app, cache.client)
    limiter({
      path: '*',
      method: 'all',
      lookup: ['headers.x-forwarded-for'],
      total: REQUEST_LIMIT,
      expire: REQUEST_EXPIRE_MS,
      onRateLimited(req, res, next) {
        console.log('Rate limit exceeded for', req.headers['x-forwarded-for'])
        return next()
      },
    })
  }

  // Blank page used by Eigen for caching web views.
  // See: https://github.com/artsy/microgravity-private/pull/1138
  app.use(require('../desktop/apps/blank'))

  // Make sure we're using SSL and prevent clickjacking
  app.use(ensureSSL)
  app.use(hstsMiddleware)
  if (!NODE_ENV === 'test') app.use(helmet.frameguard())

  // Inject UUID for each request into the X-Request-Id header
  app.use(addRequestId())

  // Override Backbone to use server-side sync, inject the XAPP token,
  // add redis caching, and timeout for slow responses.
  superSync.timeout = API_REQUEST_TIMEOUT
  superSync.cacheClient = cache.client
  superSync.defaultCacheTime = DEFAULT_CACHE_TIME
  Backbone.sync = function(method, model, options) {
    if (options.headers == null) {
      options.headers = {}
    }
    options.headers['X-XAPP-TOKEN'] = artsyXapp.token || ''
    return superSync(method, model, options)
  }

  // Inject sharify data before any app code
  app.use(sharify)

  // Cookie and session middleware
  app.use(cookieParser())
  app.set('trust proxy', true)
  app.use(
    session({
      secret: SESSION_SECRET,
      domain: NODE_ENV === 'development' ? '' : COOKIE_DOMAIN,
      name: SESSION_COOKIE_KEY,
      maxAge: SESSION_COOKIE_MAX_AGE,
      secure: NODE_ENV === 'production' || NODE_ENV === 'staging',
      httpOnly: false,
    })
  )

  // Body parser has to be after proxy middleware for
  // node-http-proxy to work with POST/PUT/DELETE
  app.use('/api', proxyGravity.api)
  app.use(proxyReflection)
  app.use(bodyParser.json())
  app.use(bodyParser.urlencoded({ extended: true }))

  // Passport middleware for authentication.
  app.use(
    artsyPassport(
      _.extend({}, config, {
        CurrentUser: CurrentUser,
        ARTSY_URL: API_URL,
        SEGMENT_WRITE_KEY: SEGMENT_WRITE_KEY_SERVER,
        userKeys: [
          'collector_level',
          'default_profile_id',
          'email',
          'has_partner_access',
          'id',
          'lab_features',
          'name',
          'paddle_number',
          'phone',
          'type',
        ],
      })
    )
  )

  // Static assets
  if (NODE_ENV === 'development') {
    app.use(require('./webpack-dev-server'))

    app.use(
      require('stylus').middleware({
        src: path.resolve(__dirname, '../desktop'),
        dest: path.resolve(__dirname, '../desktop/public'),
      })
    )
    app.use(
      require('stylus').middleware({
        src: path.resolve(__dirname, '../mobile'),
        dest: path.resolve(__dirname, '../mobile/public'),
      })
    )
  }
  glob
    .sync(`${__dirname}/../{public,{desktop,mobile}/**/public}`)
    .forEach(fld => app.use(express.static(fld)))
  app.use(
    favicon(path.resolve(__dirname, '../mobile/public/images/favicon.ico'))
  )
  app.use('/(.well-known/)?apple-app-site-association', siteAssociation)

  // Redirect requests before they even have to deal with Force routing
  app.use(downcase)
  app.use(hardcodedRedirects)

  // General helpers and express middleware
  if (argv.debugProd) {
    // Mount static webserver instead of requesting assets through bucket
    // manifest. Pass in --debugProd on boot.
    app.use(express.static('public'))
  } else {
    app.use(bucketAssets())
  }

  app.use(localsMiddleware)
  app.use(backboneErrorHelper)
  app.use(sameOriginMiddleware)
  app.use(escapedFragmentMiddleware)
  app.use(logger)
  app.use(unsupportedBrowserCheck)
  app.use(splitTestMiddleware)

  if (DD_APM_ENABLED) {
    // DataDog automatically hooks into Express
    // https://datadog.github.io/dd-trace-js/index.html
    // and we use all the defaults from:
    // https://github.com/DataDog/dd-trace-js/blob/master/docs/API.md#tracer-settings
    ddTracer.init({
      hostname: process.env.DD_TRACE_AGENT_HOSTNAME,
      service: 'force',
    })
  }

  // Sets up mobile marketing signup modal
  app.use(marketingModals)

  // Setup hot-swap loader
  if (NODE_ENV === 'development') {
    const { createReloadable } = require('@artsy/express-reloadable')
    const mountAndReload = createReloadable(app, require)

    app.use((req, res, next) => {
      if (res.locals.sd.IS_MOBILE) {
        const mobileApp = mountAndReload(path.resolve('src/mobile'))
        mobileApp(req, res, next)
      } else {
        next()
      }
    })

    mountAndReload(path.resolve('src/desktop'), {
      watchModules: ['@artsy/reaction', '@artsy/stitch'],
    })

    // In staging or prod, mount routes normally
  } else {
    app.use((req, res, next) => {
      if (argv.debugProd) {
        res.locals.asset = filename => filename // Stub bucketAssets middleware helper
      }

      // Direct mobile devices to the mobile app, otherwise fall through to
      // the desktop app
      if (res.locals.sd.IS_MOBILE) {
        require('../mobile')(req, res, next)
      } else {
        next()
      }
    })
    app.use(require('../desktop'))
  }

  // Routes for pinging system time and up
  app.get('/system/time', (req, res) => res.send(200, { time: Date.now() }))
  app.get('/system/up', (req, res) => res.send(200, { nodejs: true }))

  // Ensure CurrentUser is set for Artsy Passport
  // TODO: Investigate race condition b/t reaction's use of AP
  artsyPassport.options.CurrentUser = CurrentUser

  // 404 handler
  app.get('*', (req, res, next) => {
    const err = new Error()
    err.status = 404
    err.message = 'Not Found'
    next(err)
  })

  // Last but not least, error handling...
  if (SENTRY_PRIVATE_DSN) app.use(RavenServer.errorHandler())
  app.use(errorHandlingMiddleware)
}
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
*/

foam.CLASS({
  package: 'foam.u2.view',
  name: 'AltView',
  extends: 'foam.u2.View',

  documentation: "Provides the ability to switch between multiple views for data set" +
  "Takes a views property which should be the value of an array containing arrays that contain desired views, and label." +
  "Ex. views: [[ { class: 'foam.u2.view.TableView' }, 'Table' ]]",

  css: `
    ^ {
      margin: auto;
    }
  `,

  properties: [
    {
      name: 'of',
      factory: function() { return this.data.of }
    },
    {
      name: 'views',
      factory: function() { return []; }
    },
    {
      name: 'selectedView',
      view: function(_, X) {
        return foam.u2.view.ChoiceView.create({choices: X.data.views});
      }
    },
    {
      class: 'foam.dao.DAOProperty',
      name: 'data'
    }
  ],

  methods: [
    function initE() {
      this.SUPER();
      var self = this;

     this.selectedView = this.views[0][0];

      this.addClass(this.myClass())
      this.startContext({data: this})
        this.start()
          .add(this.SELECTED_VIEW)
        .end()
      .endContext()
      .start('div')
        .add(this.selectedView$.map(function(v) {
          return self.E().tag(v, {data: self.data$proxy});
        }))
      .end();
    }
  ]
});
<commit_msg>Minor CSS improvement for AltView.<commit_after>/**
 * @license
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
*/

foam.CLASS({
  package: 'foam.u2.view',
  name: 'AltView',
  extends: 'foam.u2.View',

  documentation: "Provides the ability to switch between multiple views for data set" +
  "Takes a views property which should be the value of an array containing arrays that contain desired views, and label." +
  "Ex. views: [[ { class: 'foam.u2.view.TableView' }, 'Table' ]]",

  css: `
    ^ { margin: auto; }
    ^ select { height: 26px }
  `,

  properties: [
    {
      name: 'of',
      factory: function() { return this.data.of }
    },
    {
      name: 'views',
      factory: function() { return []; }
    },
    {
      name: 'selectedView',
      view: function(_, X) {
        return foam.u2.view.ChoiceView.create({choices: X.data.views});
      }
    },
    {
      class: 'foam.dao.DAOProperty',
      name: 'data'
    }
  ],

  methods: [
    function initE() {
      this.SUPER();
      var self = this;

     this.selectedView = this.views[0][0];

      this.addClass(this.myClass())
      this.startContext({data: this})
        this.start()
          .add(this.SELECTED_VIEW)
        .end()
      .endContext()
      .start('div')
        .add(this.selectedView$.map(function(v) {
          return self.E().tag(v, {data: self.data$proxy});
        }))
      .end();
    }
  ]
});
<|endoftext|>


<commit_before>var fakeweb = require(__dirname + '/fakeweb.js');
var friends = require('../Connectors/Twitter/friends');
var timeline = require('../Connectors/Twitter/timeline');
var tweets = require('../Connectors/Twitter/tweets');
var mentions = require('../Connectors/Twitter/mentions');
var assert = require("assert");
var RESTeasy = require('api-easy');
var vows = require("vows");
var suite = RESTeasy.describe("Twitter Synclets");
var fs = require('fs');
var curDir = process.cwd();

process.setMaxListeners(0);
process.on('uncaughtException',function(error){
    console.dir(error.stack);
});

var mePath = '/Data/twitter-1';
var pinfo = JSON.parse(fs.readFileSync(__dirname + mePath + '/me.json'));

suite.next().suite.addBatch({
    "Can get users" : {
        topic: function() {
            fakeweb.allowNetConnect = false;
            fakeweb.registerUri({uri : 'https://api.twitter.com:443/1/account/verify_credentials.json?path=%2Faccount%2Fverify_credentials.json&include_entities=true',
                file : __dirname + '/fixtures/twitter/verify_credentials.js' });
            fakeweb.registerUri({uri : 'https://api.twitter.com:443/1/friends/ids.json?screen_name=ctide&cursor=-1&path=%2Ffriends%2Fids.json&include_entities=true',
                file : __dirname + '/fixtures/twitter/friends.js' });
            fakeweb.registerUri({uri : 'https://api.twitter.com:443/1/users/lookup.json?path=%2Fusers%2Flookup.json&user_id=1054551&include_entities=true',
                file : __dirname + '/fixtures/twitter/1054551.js' });
            fakeweb.registerUri({uri : 'http://a0.twimg.com/profile_images/299352843/Picture_82_normal.png',
                file : __dirname + '/fixtures/twitter/1054551.png',
                contentType : 'image/png' });
            process.chdir('.' + mePath);
            friends.sync(pinfo, this.callback)
        },
        "successfully" : function(err, response) {
            // console.error('DEBUG: err', err);
            // console.error('DEBUG: response', response.data);
            assert.equal(response.data.contact[0].obj.id, '1054551');
            process.chdir(curDir);
        }
    }
}).addBatch({
    "Can get timeline" : {
        topic: function() {
            fakeweb.allowNetConnect = false;
            fakeweb.registerUri({uri : 'https://api.twitter.com:443/1/account/verify_credentials.json?path=%2Faccount%2Fverify_credentials.json&include_entities=true',
                file : __dirname + '/fixtures/twitter/verify_credentials.js' });
            fakeweb.registerUri({uri : 'https://api.twitter.com:443/1/statuses/home_timeline.json?screen_name=ctide&path=%2Fstatuses%2Fhome_timeline.json&include_entities=true&page=1',
                file : __dirname + '/fixtures/twitter/home_timeline.js' });
                fakeweb.registerUri({uri : 'https://api.twitter.com:443/1/statuses/home_timeline.json?screen_name=ctide&path=%2Fstatuses%2Fhome_timeline.json&include_entities=true&page=2',
                    body :'[]' });
            process.chdir('.' + mePath);
            timeline.sync(pinfo, this.callback)
        },
        "successfully" : function(err, response) {
            // console.error('DEBUG: err', err);
            // console.error('DEBUG: response', response.data);
            assert.equal(response.data.timeline[0].obj.id_str, '71348168469643264');
            process.chdir(curDir);
        }
    }

}).addBatch({
    "Can get mentions" : {
        topic: function() {
            fakeweb.allowNetConnect = false;
            fakeweb.registerUri({uri : 'https://api.twitter.com:443/1/account/verify_credentials.json?path=%2Faccount%2Fverify_credentials.json&include_entities=true',
                file : __dirname + '/fixtures/twitter/verify_credentials.js' });
            fakeweb.registerUri({uri : 'https://api.twitter.com:443/1/statuses/mentions.json?screen_name=ctide&path=%2Fstatuses%2Fmentions.json&include_entities=true&page=1',
                file : __dirname + '/fixtures/twitter/home_timeline.js' });
                fakeweb.registerUri({uri : 'https://api.twitter.com:443/1/statuses/mentions.json?screen_name=ctide&path=%2Fstatuses%2Fmentions.json&include_entities=true&page=2',
                    body :'[]' });
            process.chdir('.' + mePath);
            mentions.sync(pinfo, this.callback)
        },
        "successfully" : function(err, response) {
            // console.error('DEBUG: err', err);
            // console.error('DEBUG: response', response.data);
            assert.equal(response.data.mentions[0].obj.id_str, '71348168469643264');
            process.chdir(curDir);
        }
    }

}).addBatch({
    "Can get tweets" : {
        topic: function() {
            fakeweb.allowNetConnect = false;
            fakeweb.registerUri({uri : 'https://api.twitter.com:443/1/account/verify_credentials.json?path=%2Faccount%2Fverify_credentials.json&include_entities=true',
                file : __dirname + '/fixtures/twitter/verify_credentials.js' });
            fakeweb.registerUri({uri : 'https://api.twitter.com:443/1/statuses/user_timeline.json?screen_name=ctide&path=%2Fstatuses%2Fuser_timeline.json&include_entities=true&page=1',
                file : __dirname + '/fixtures/twitter/home_timeline.js' });
                fakeweb.registerUri({uri : 'https://api.twitter.com:443/1/statuses/user_timeline.json?screen_name=ctide&path=%2Fstatuses%2Fuser_timeline.json&include_entities=true&page=2',
                    body :'[]' });
            process.chdir('.' + mePath);
            tweets.sync(pinfo, this.callback)
        },
        "successfully" : function(err, response) {
            // console.error('DEBUG: err', err);
            // console.error('DEBUG: response', response.data);
            assert.equal(response.data.tweets[0].obj.id_str, '71348168469643264');
            process.chdir(curDir);
        }
    }
})

suite.export(module);<commit_msg>this url hardcoding catching is kinda lame<commit_after>var fakeweb = require(__dirname + '/fakeweb.js');
var friends = require('../Connectors/Twitter/friends');
var timeline = require('../Connectors/Twitter/timeline');
var tweets = require('../Connectors/Twitter/tweets');
var mentions = require('../Connectors/Twitter/mentions');
var assert = require("assert");
var RESTeasy = require('api-easy');
var vows = require("vows");
var suite = RESTeasy.describe("Twitter Synclets");
var fs = require('fs');
var curDir = process.cwd();

process.setMaxListeners(0);
process.on('uncaughtException',function(error){
    console.dir(error.stack);
});

var mePath = '/Data/twitter-1';
var pinfo = JSON.parse(fs.readFileSync(__dirname + mePath + '/me.json'));

suite.next().suite.addBatch({
    "Can get users" : {
        topic: function() {
            fakeweb.allowNetConnect = false;
            fakeweb.registerUri({uri : 'https://api.twitter.com:443/1/account/verify_credentials.json?path=%2Faccount%2Fverify_credentials.json&include_entities=true',
                file : __dirname + '/fixtures/twitter/verify_credentials.js' });
            fakeweb.registerUri({uri : 'https://api.twitter.com:443/1/friends/ids.json?screen_name=ctide&cursor=-1&path=%2Ffriends%2Fids.json&include_entities=true',
                file : __dirname + '/fixtures/twitter/friends.js' });
            fakeweb.registerUri({uri : 'https://api.twitter.com:443/1/users/lookup.json?path=%2Fusers%2Flookup.json&user_id=1054551&include_entities=true',
                file : __dirname + '/fixtures/twitter/1054551.js' });
            fakeweb.registerUri({uri : 'http://a0.twimg.com/profile_images/299352843/Picture_82_normal.png',
                file : __dirname + '/fixtures/twitter/1054551.png',
                contentType : 'image/png' });
            process.chdir('.' + mePath);
            friends.sync(pinfo, this.callback)
        },
        "successfully" : function(err, response) {
            // console.error('DEBUG: err', err);
            // console.error('DEBUG: response', response.data);
            assert.equal(response.data.contact[0].obj.id, '1054551');
            process.chdir(curDir);
        }
    }
}).addBatch({
    "Can get timeline" : {
        topic: function() {
            fakeweb.allowNetConnect = false;
            fakeweb.registerUri({uri : 'https://api.twitter.com:443/1/account/verify_credentials.json?path=%2Faccount%2Fverify_credentials.json&include_entities=true',
                file : __dirname + '/fixtures/twitter/verify_credentials.js' });
            fakeweb.registerUri({uri : 'https://api.twitter.com:443/1/statuses/home_timeline.json?screen_name=ctide&since_id=1&path=%2Fstatuses%2Fhome_timeline.json&include_entities=true&page=1',
                file : __dirname + '/fixtures/twitter/home_timeline.js' });
                fakeweb.registerUri({uri : 'https://api.twitter.com:443/1/statuses/home_timeline.json?screen_name=ctide&since_id=1&path=%2Fstatuses%2Fhome_timeline.json&include_entities=true&page=2',
                    body :'[]' });
            process.chdir('.' + mePath);
            timeline.sync(pinfo, this.callback)
        },
        "successfully" : function(err, response) {
            // console.error('DEBUG: err', err);
            // console.error('DEBUG: response', response.data);
            assert.equal(response.data.timeline[0].obj.id_str, '71348168469643264');
            process.chdir(curDir);
        }
    }

}).addBatch({
    "Can get mentions" : {
        topic: function() {
            fakeweb.allowNetConnect = false;
            fakeweb.registerUri({uri : 'https://api.twitter.com:443/1/account/verify_credentials.json?path=%2Faccount%2Fverify_credentials.json&include_entities=true',
                file : __dirname + '/fixtures/twitter/verify_credentials.js' });
            fakeweb.registerUri({uri : 'https://api.twitter.com:443/1/statuses/mentions.json?screen_name=ctide&since_id=1&path=%2Fstatuses%2Fmentions.json&include_entities=true&page=1',
                file : __dirname + '/fixtures/twitter/home_timeline.js' });
                fakeweb.registerUri({uri : 'https://api.twitter.com:443/1/statuses/mentions.json?screen_name=ctide&since_id=1&path=%2Fstatuses%2Fmentions.json&include_entities=true&page=2',
                    body :'[]' });
            process.chdir('.' + mePath);
            mentions.sync(pinfo, this.callback)
        },
        "successfully" : function(err, response) {
            // console.error('DEBUG: err', err);
            // console.error('DEBUG: response', response.data);
            assert.equal(response.data.mentions[0].obj.id_str, '71348168469643264');
            process.chdir(curDir);
        }
    }

}).addBatch({
    "Can get tweets" : {
        topic: function() {
            fakeweb.allowNetConnect = false;
            fakeweb.registerUri({uri : 'https://api.twitter.com:443/1/account/verify_credentials.json?path=%2Faccount%2Fverify_credentials.json&include_entities=true',
                file : __dirname + '/fixtures/twitter/verify_credentials.js' });
            fakeweb.registerUri({uri : 'https://api.twitter.com:443/1/statuses/user_timeline.json?screen_name=ctide&since_id=1&path=%2Fstatuses%2Fuser_timeline.json&include_entities=true&page=1',
                file : __dirname + '/fixtures/twitter/home_timeline.js' });
                fakeweb.registerUri({uri : 'https://api.twitter.com:443/1/statuses/user_timeline.json?screen_name=ctide&since_id=1&path=%2Fstatuses%2Fuser_timeline.json&include_entities=true&page=2',
                    body :'[]' });
            process.chdir('.' + mePath);
            tweets.sync(pinfo, this.callback)
        },
        "successfully" : function(err, response) {
            // console.error('DEBUG: err', err);
            // console.error('DEBUG: response', response.data);
            assert.equal(response.data.tweets[0].obj.id_str, '71348168469643264');
            process.chdir(curDir);
        }
    }
})

suite.export(module);<|endoftext|>


<commit_before>var SomethingDigital_Modal = Class.create();
SomethingDigital_Modal.prototype = {
    initialize: function(config) {
        this.setupOptions(config);
        this.updatePageViewCookie()
        if (this.shouldShowModal()) {
            this.cookieUser();
            this.showModal();
            this.setupModalClose();
            this.setupFormAjax();
        }
    },
    setupOptions: function(config) {
        this.options = config;
        this.options.seenModalFlag = 'seenModal';
        this.options.pageViewCountCookieName = 'pagesViewed';
        this.options.modalElementId = 'modal';
        this.options.closeModalElementClass = 'close-modal';
        this.options.modalFormElementId = 'modal-form';
        this.options.beforeWrapperElementId = 'modal-before';
        this.options.afterWrapperElementId = 'modal-after';
        this.options.loadingElementId = 'modal-loading';
        this.options.errorMessageElementId = 'modal-error';
        this.options.forceModalQueryStringParam = 'forceModal';
        this.options.suppressModalQueryStringParam = 'suppressModal';
        this.options.suppressModalCookieFlag = this.options.suppressModalQueryStringParam;
    },
    updatePageViewCookie: function() {
        var curCount = Mage.Cookies.get(this.options.pageViewCountCookieName);
        if (!curCount) {
            Mage.Cookies.set(this.options.pageViewCountCookieName, 0);
            return;
        }
        Mage.Cookies.set(this.options.pageViewCountCookieName, parseInt(curCount) + 1);
    },
    shouldShowModal: function() {
        var forceQuery = this.options.forceModalQueryStringParam,
            urlParams = window.location.href.toQueryParams();
        if (this.options.skipCookieCheck || urlParams.hasOwnProperty(forceQuery)) {
            return true;
        }
        if (Mage.Cookies.get(this.options.suppressModalCookieFlag)) {
            return false;
        }
        if (urlParams.hasOwnProperty(this.options.suppressModalQueryStringParam)) {
            this.setSuppressModalCookieFlag();
            return false;
        }
        if (!Mage.Cookies.get(this.options.seenModalFlag) &&
            parseInt(Mage.Cookies.get(this.options.pageViewCountCookieName)) >= this.options.showAfterPageViews) {
            return true;
        }
        return false;
    },
    setSuppressModalCookieFlag: function() {
        Mage.Cookies.set(this.options.suppressModalCookieFlag, 1);
    },
    cookieUser: function() {
        var today = new Date();
        today.setTime(today.getTime());
        var duration = 1000 * 60 * 60 * 24 * this.options.cookieDuration;
        var expireDate = new Date(today.getTime() + duration);
        Mage.Cookies.expires = expireDate;
        Mage.Cookies.set(this.options.seenModalFlag, 1);
    },
    showModal: function() {
        this.modal = new Window({
            width: window.innerWidth,
            height: window.innerHeight,
            zIndex: this.options.modalZIndex,
            onShow: this.showOverlay.bind(this),
            onHide: this.removeOverlay.bind(this),
            onClose: this.removeOverlay.bind(this),
            className: 'lighting'
        });
        this.modal.getContent().update(this.options.modalContent);
        this.modal.showCenter();
    },
    setupModalClose: function() {
        Element.observe(this.options.modalElementId, 'click', this.handleModalClick.bind(this));
        if (this.options.closeOnOutsideClicks) {
            document.observe('click', this.handleDocumentClick.bind(this));
        }
    },
    setupFormAjax: function() {
        Event.observe($(this.options.modalFormElementId), 'submit', function(event) {
            Event.stop(event);
            this.options.modalFormSubmitElement = $(this.options.modalElementId).select('input[type="submit"]')[0];
            Form.Element.disable(this.options.modalFormSubmitElement);
            Form.request(this.options.modalFormElementId, {
                onLoading: this.onLoading.bind(this),
                onFailure: this.onFailure.bind(this),
                onSuccess: this.onSuccess.bind(this)
            })
        }.bind(this))
    },
    onLoading: function() {
        var loadingElement = $(this.options.loadingElementId);
        if (loadingElement) {
            loadingElement.show();
        }
    },
    onFailure: function(response) {
        var loadingElement = $(this.options.loadingElementId);
        if (loadingElement) {
            loadingElement.hide();
        }
        Form.Element.enable(this.options.modalFormSubmitElement);
        $(this.options.errorMessageElementId).update(this.options.errorMessage).show();
    },
    onSuccess: function(response) {
        $(this.options.beforeWrapperElementId).hide();
        $(this.options.afterWrapperElementId).show();
        var s = parseInt(this.options.closeAfterSeconds) * 1000;
        if (s) {
            window.setTimeout(this.closeModal.bind(this), s);
        }
    },
    handleModalClick: function(event) {
        if (event.findElement('.' + this.options.closeModalElementClass)) {
           this.closeModal();
        }
    },
    showOverlay: function() {
        var overlayStyle = 'width: 100%; height: 100%; background-color: black; opacity: ' + this.options.overlayOpacity + '; z-index: ' + (parseInt(this.options.modalZIndex) - 1) + '; position: absolute; top: 0; left: 0';
        this.overlay = new Element('div', {style: overlayStyle, 'id': 'overlay'});
        $$('body')[0].insert(this.overlay);
    },
    removeOverlay: function() {
        this.overlay.remove();
    },
    handleDocumentClick: function(event) {
        if (!event.findElement('#' + this.options.modalElementId)) {
            this.closeModal();
        }
    },
    closeModal: function() {
        this.modal.close();
    }
}
<commit_msg>Move Window classname to options<commit_after>var SomethingDigital_Modal = Class.create();
SomethingDigital_Modal.prototype = {
    initialize: function(config) {
        this.setupOptions(config);
        this.updatePageViewCookie()
        if (this.shouldShowModal()) {
            this.cookieUser();
            this.showModal();
            this.setupModalClose();
            this.setupFormAjax();
        }
    },
    setupOptions: function(config) {
        this.options = config;
        this.options.seenModalFlag = 'seenModal';
        this.options.pageViewCountCookieName = 'pagesViewed';
        this.options.modalElementId = 'modal';
        this.options.closeModalElementClass = 'close-modal';
        this.options.modalFormElementId = 'modal-form';
        this.options.beforeWrapperElementId = 'modal-before';
        this.options.afterWrapperElementId = 'modal-after';
        this.options.loadingElementId = 'modal-loading';
        this.options.errorMessageElementId = 'modal-error';
        this.options.forceModalQueryStringParam = 'forceModal';
        this.options.suppressModalQueryStringParam = 'suppressModal';
        this.options.suppressModalCookieFlag = this.options.suppressModalQueryStringParam;
        this.options.windowClassName = 'lighting';
    },
    updatePageViewCookie: function() {
        var curCount = Mage.Cookies.get(this.options.pageViewCountCookieName);
        if (!curCount) {
            Mage.Cookies.set(this.options.pageViewCountCookieName, 0);
            return;
        }
        Mage.Cookies.set(this.options.pageViewCountCookieName, parseInt(curCount) + 1);
    },
    shouldShowModal: function() {
        var forceQuery = this.options.forceModalQueryStringParam,
            urlParams = window.location.href.toQueryParams();
        if (this.options.skipCookieCheck || urlParams.hasOwnProperty(forceQuery)) {
            return true;
        }
        if (Mage.Cookies.get(this.options.suppressModalCookieFlag)) {
            return false;
        }
        if (urlParams.hasOwnProperty(this.options.suppressModalQueryStringParam)) {
            this.setSuppressModalCookieFlag();
            return false;
        }
        if (!Mage.Cookies.get(this.options.seenModalFlag) &&
            parseInt(Mage.Cookies.get(this.options.pageViewCountCookieName)) >= this.options.showAfterPageViews) {
            return true;
        }
        return false;
    },
    setSuppressModalCookieFlag: function() {
        Mage.Cookies.set(this.options.suppressModalCookieFlag, 1);
    },
    cookieUser: function() {
        var today = new Date();
        today.setTime(today.getTime());
        var duration = 1000 * 60 * 60 * 24 * this.options.cookieDuration;
        var expireDate = new Date(today.getTime() + duration);
        Mage.Cookies.expires = expireDate;
        Mage.Cookies.set(this.options.seenModalFlag, 1);
    },
    showModal: function() {
        this.modal = new Window({
            width: window.innerWidth,
            height: window.innerHeight,
            zIndex: this.options.modalZIndex,
            onShow: this.showOverlay.bind(this),
            onHide: this.removeOverlay.bind(this),
            onClose: this.removeOverlay.bind(this),
            className: this.options.windowClassName
        });
        this.modal.getContent().update(this.options.modalContent);
        this.modal.showCenter();
    },
    setupModalClose: function() {
        Element.observe(this.options.modalElementId, 'click', this.handleModalClick.bind(this));
        if (this.options.closeOnOutsideClicks) {
            document.observe('click', this.handleDocumentClick.bind(this));
        }
    },
    setupFormAjax: function() {
        Event.observe($(this.options.modalFormElementId), 'submit', function(event) {
            Event.stop(event);
            this.options.modalFormSubmitElement = $(this.options.modalElementId).select('input[type="submit"]')[0];
            Form.Element.disable(this.options.modalFormSubmitElement);
            Form.request(this.options.modalFormElementId, {
                onLoading: this.onLoading.bind(this),
                onFailure: this.onFailure.bind(this),
                onSuccess: this.onSuccess.bind(this)
            })
        }.bind(this))
    },
    onLoading: function() {
        var loadingElement = $(this.options.loadingElementId);
        if (loadingElement) {
            loadingElement.show();
        }
    },
    onFailure: function(response) {
        var loadingElement = $(this.options.loadingElementId);
        if (loadingElement) {
            loadingElement.hide();
        }
        Form.Element.enable(this.options.modalFormSubmitElement);
        $(this.options.errorMessageElementId).update(this.options.errorMessage).show();
    },
    onSuccess: function(response) {
        $(this.options.beforeWrapperElementId).hide();
        $(this.options.afterWrapperElementId).show();
        var s = parseInt(this.options.closeAfterSeconds) * 1000;
        if (s) {
            window.setTimeout(this.closeModal.bind(this), s);
        }
    },
    handleModalClick: function(event) {
        if (event.findElement('.' + this.options.closeModalElementClass)) {
           this.closeModal();
        }
    },
    showOverlay: function() {
        var overlayStyle = 'width: 100%; height: 100%; background-color: black; opacity: ' + this.options.overlayOpacity + '; z-index: ' + (parseInt(this.options.modalZIndex) - 1) + '; position: absolute; top: 0; left: 0';
        this.overlay = new Element('div', {style: overlayStyle, 'id': 'overlay'});
        $$('body')[0].insert(this.overlay);
    },
    removeOverlay: function() {
        this.overlay.remove();
    },
    handleDocumentClick: function(event) {
        if (!event.findElement('#' + this.options.modalElementId)) {
            this.closeModal();
        }
    },
    closeModal: function() {
        this.modal.close();
    }
}
<|endoftext|>


<commit_before>"use strict";

const sh = require("shelljs");
const fs = require("fs");
const finder = require("glob-concat");
const tmpCSSPath = "tmp/source.scss";

const appJSON = finder
	.sync(
		require("./../../dev/task/asset/source.scss.json")
		.concat(require("./../../tmp/src/dev/task/asset/source.scss.json"))
	)
;

const vendorJSON = finder
	.sync(
		require("./../../dev/task/asset/vendor.scss.json")
		.concat(require("./../../tmp/src/dev/task/asset/vendor.scss.json"))
	)
;

// Commands
const postCSS = "chmod +x node_modules/postcss/lib/postcss.js && node node_modules/postcss/lib/postcss.js";
const nodeSASS = "chmod +x node_modules/node-sass/bin/node-sass && node_modules/node-sass/bin/node-sass";

// Vendor files

// Preflight
sh.exec("node_modules/stylelint/bin/stylelint.js app/**/*.scss tmp/src/app/**/*.scss");
sh.exec("node dev/task/font.copy.js");
sh.exec("node dev/task/image.copy.js");

// Build
sh.cat(appJSON).to(tmpCSSPath);

sh.exec(nodeSASS + " -q --output-style compressed --include-path scss " + tmpCSSPath + " " + tmpCSSPath);
sh.exec(postCSS + " --use autoprefixer -b 'last 5 versions' < " + tmpCSSPath);

vendorJSON.push(tmpCSSPath);
sh.cat(vendorJSON).to("dist/app.css");
<commit_msg>Edits<commit_after>"use strict";

const sh = require("shelljs");
const fs = require("fs");
const finder = require("glob-concat");
const tmpCSSPath = "tmp/source.scss";

const appJSON = finder
	.sync(
		require("./../../dev/task/asset/source.scss.json")
		.concat(require("./../../tmp/src/dev/task/asset/source.scss.json"))
	)
;

const vendorJSON = finder
	.sync(
		require("./../../dev/task/asset/vendor.scss.json")
		.concat(require("./../../tmp/src/dev/task/asset/vendor.scss.json"))
	)
;

// Commands
const postCSS = "chmod +x node_modules/postcss/lib/postcss.js && node node_modules/postcss/lib/postcss.js";
const nodeSASS = "chmod +x node_modules/node-sass/bin/node-sass && node_modules/node-sass/bin/node-sass";

// Preflight
sh.exec("node_modules/stylelint/bin/stylelint.js app/**/*.scss tmp/src/app/**/*.scss");
sh.exec("node dev/task/font.copy.js");
sh.exec("node dev/task/image.copy.js");

// Build
sh.cat(appJSON).to(tmpCSSPath);

sh.exec(nodeSASS + " -q --output-style compressed --include-path scss " + tmpCSSPath + " " + tmpCSSPath);
sh.exec(postCSS + " --use autoprefixer -b 'last 5 versions' < " + tmpCSSPath);

vendorJSON.push(tmpCSSPath);
sh.cat(vendorJSON).to("dist/app.css");
<|endoftext|>


<commit_before>/*
 * react pattern engine for patternlab-node - v0.1.0 - 2016
 *
 * Geoffrey Pursell, Brian Muenzenmeyer, and the web community.
 * Licensed under the MIT license.
 *
 * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice.
 *
 */

/*
 * ENGINE SUPPORT LEVEL:
 *
 * Full + extensions. Partial calls and lineage hunting are supported. Style
 * modifiers and pattern parameters are used to extend the core feature set of
 * React templates.
 *
 */

"use strict";

const fs = require('fs');
const path = require('path');
const React = require('react');
const ReactDOMServer = require('react-dom/server');
const Babel = require('babel-core');
const Hogan = require('hogan.js');
const beautify = require('js-beautify');
const cheerio = require('cheerio');

const outputTemplate = Hogan.compile(
  fs.readFileSync(
    path.join(__dirname, './outputTemplate.mustache'),
    'utf8'
  )
);

var engine_react = {
  engine: React,
  engineName: 'react',
  engineFileExtension: '.jsx',

  // hell no
  expandPartials: false,

  // regexes, stored here so they're only compiled once
  findPartialsRE: null,
  findPartialsWithStyleModifiersRE: null,
  findPartialsWithPatternParametersRE: null,
  findListItemsRE: null,
  findPartialRE: null,

  // render it
  renderPattern(pattern, data, partials) {
    try {
      /* eslint-disable no-eval */
      const componentString = pattern.template || pattern.extendedTemplate;
      const nodeComponent = Babel.transform(componentString, {
        presets: [ require('babel-preset-react') ],
        plugins: [ require('babel-plugin-transform-es2015-modules-commonjs') ]
      });
      const runtimeComponent = Babel.transform(componentString, {
        presets: [ require('babel-preset-react') ],
        plugins: [[require('babel-plugin-transform-es2015-modules-umd'), {
          globals: {
            "react": "React"
          }
        }]]
      });
      const Component = React.createFactory(eval(nodeComponent.code));

      return outputTemplate.render({
        patternPartial: pattern.patternPartial,
        json: JSON.stringify(data),
        htmlOutput: ReactDOMServer.renderToStaticMarkup(Component(data)),
        runtimeCode: runtimeComponent.code
      });
    }
    catch (e) {
	    console.log("Error rendering React pattern.", e);
	    return "";
    }
  },

  /**
   * Find regex matches within both pattern strings and pattern objects.
   *
   * @param {string|object} pattern Either a string or a pattern object.
   * @param {object} regex A JavaScript RegExp object.
   * @returns {array|null} An array if a match is found, null if not.
   */
  patternMatcher(pattern, regex) {
    var matches;
    if (typeof pattern === 'string') {
      matches = pattern.match(regex);
    } else if (typeof pattern === 'object' && typeof pattern.template === 'string') {
      matches = pattern.template.match(regex);
    }
    return matches;
  },

  // find and return any {{> template-name }} within pattern
  findPartials(pattern) {
    return [];
  },
  findPartialsWithStyleModifiers(pattern) {
    return [];
  },

  // returns any patterns that match {{> value(foo:"bar") }} or {{>
  // value:mod(foo:"bar") }} within the pattern
  findPartialsWithPatternParameters(pattern) {
    return [];
  },
  findListItems(pattern) {
    return [];
  },

  // given a pattern, and a partial string, tease out the "pattern key" and
  // return it.
  findPartial(partialString) {
    return [];
  },

  rawTemplateCodeFormatter(unformattedString) {
    return beautify(unformattedString, {e4x: true, indent_size: 2});
  },

  renderedCodeFormatter(unformattedString) {
    return unformattedString;
  },

  markupOnlyCodeFormatter(unformattedString, pattern) {
    const $ = cheerio.load(unformattedString);
    return beautify.html($('.reactPatternContainer').html(), {indent_size: 2});
  },

  /**
   * Add custom output files to the pattern output
   * @param {object} patternlab - the global state object
   * @returns {(object|object[])} - an object or array of objects,
   * each with two properties: path, and content
   */
  addOutputFiles(paths, patternlab) {
    return [];
  }
};

module.exports = engine_react;
<commit_msg>comment cleanup<commit_after>/*
 * react pattern engine for patternlab-node - v0.1.0 - 2016
 *
 * Geoffrey Pursell, Brian Muenzenmeyer, and the web community.
 * Licensed under the MIT license.
 *
 * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice.
 *
 */

"use strict";

const fs = require('fs');
const path = require('path');
const React = require('react');
const ReactDOMServer = require('react-dom/server');
const Babel = require('babel-core');
const Hogan = require('hogan.js');
const beautify = require('js-beautify');
const cheerio = require('cheerio');

const outputTemplate = Hogan.compile(
  fs.readFileSync(
    path.join(__dirname, './outputTemplate.mustache'),
    'utf8'
  )
);

var engine_react = {
  engine: React,
  engineName: 'react',
  engineFileExtension: '.jsx',

  // hell no
  expandPartials: false,

  // regexes, stored here so they're only compiled once
  findPartialsRE: null,
  findPartialsWithStyleModifiersRE: null,
  findPartialsWithPatternParametersRE: null,
  findListItemsRE: null,
  findPartialRE: null,

  // render it
  renderPattern(pattern, data, partials) {
    try {
      /* eslint-disable no-eval */
      const componentString = pattern.template || pattern.extendedTemplate;
      const nodeComponent = Babel.transform(componentString, {
        presets: [ require('babel-preset-react') ],
        plugins: [ require('babel-plugin-transform-es2015-modules-commonjs') ]
      });
      const runtimeComponent = Babel.transform(componentString, {
        presets: [ require('babel-preset-react') ],
        plugins: [[require('babel-plugin-transform-es2015-modules-umd'), {
          globals: {
            "react": "React"
          }
        }]]
      });
      const Component = React.createFactory(eval(nodeComponent.code));

      return outputTemplate.render({
        patternPartial: pattern.patternPartial,
        json: JSON.stringify(data),
        htmlOutput: ReactDOMServer.renderToStaticMarkup(Component(data)),
        runtimeCode: runtimeComponent.code
      });
    }
    catch (e) {
	    console.log("Error rendering React pattern.", e);
	    return "";
    }
  },

  /**
   * Find regex matches within both pattern strings and pattern objects.
   *
   * @param {string|object} pattern Either a string or a pattern object.
   * @param {object} regex A JavaScript RegExp object.
   * @returns {array|null} An array if a match is found, null if not.
   */
  patternMatcher(pattern, regex) {
    var matches;
    if (typeof pattern === 'string') {
      matches = pattern.match(regex);
    } else if (typeof pattern === 'object' && typeof pattern.template === 'string') {
      matches = pattern.template.match(regex);
    }
    return matches;
  },

  // find and return any {{> template-name }} within pattern
  findPartials(pattern) {
    return [];
  },
  findPartialsWithStyleModifiers(pattern) {
    return [];
  },

  // returns any patterns that match {{> value(foo:"bar") }} or {{>
  // value:mod(foo:"bar") }} within the pattern
  findPartialsWithPatternParameters(pattern) {
    return [];
  },
  findListItems(pattern) {
    return [];
  },

  // given a pattern, and a partial string, tease out the "pattern key" and
  // return it.
  findPartial(partialString) {
    return [];
  },

  rawTemplateCodeFormatter(unformattedString) {
    return beautify(unformattedString, {e4x: true, indent_size: 2});
  },

  renderedCodeFormatter(unformattedString) {
    return unformattedString;
  },

  markupOnlyCodeFormatter(unformattedString, pattern) {
    const $ = cheerio.load(unformattedString);
    return beautify.html($('.reactPatternContainer').html(), {indent_size: 2});
  },

  /**
   * Add custom output files to the pattern output
   * @param {object} patternlab - the global state object
   * @returns {(object|object[])} - an object or array of objects,
   * each with two properties: path, and content
   */
  addOutputFiles(paths, patternlab) {
    return [];
  }
};

module.exports = engine_react;
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014 os0x
 * Copyright (c) 2014-2015 mono
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

(function(window, load, id){
  if (!load) {
    var fn = '(' + arguments.callee.toString() + ')(this, true, "' + chrome.runtime.id + '");';
    var script = document.createElement('script');
    script.appendChild(document.createTextNode(fn));
    document.body.appendChild(script);
    return;
  }
  var native_open = window.native_open = window.open;
  var port = chrome.runtime.connect(id);
  window.open = function(url,name){
    if (url === void 0) return native_open(url,name);
    port.postMessage({ message: 'openInTab', url: url });
    return true;
  };
  document.addEventListener('click',function(evt){
    if (evt.target.href && evt.target.target === '_blank'){
      evt.preventDefault();
      window.open(evt.target.href, '_blank');
    }
  },false);
  var _onload = window.onload;
  window.onload = function(){
    _onload();
    var p = window.Control.pin;
    var v = window.Control.view_original;
    var force_next_item = function(){
      var i = window.get_active_item();
      window.Control.scroll_next_item();
      if(i == window.get_active_item()){
        window.Control.scroll_next_item();
      }
    };
    var pin = function(){
      var res = p.apply(this, arguments);
      force_next_item();
      return res;
    };
    var view_original = function(){
      var res = v.apply(this, arguments);
      force_next_item();
      return res;
    };
    window.Keybind.add("p", pin);
    window.Keybind.add("v", view_original);
  };
})();
<commit_msg>Reconnect<commit_after>/*
 * Copyright (c) 2014 os0x
 * Copyright (c) 2014-2015 mono
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

(function(window, load, id){
  if (!load) {
    var fn = '(' + arguments.callee.toString() + ')(this, true, "' + chrome.runtime.id + '");';
    var script = document.createElement('script');
    script.appendChild(document.createTextNode(fn));
    document.body.appendChild(script);
    return;
  }
  var native_open = window.native_open = window.open;
  var port = chrome.runtime.connect(id);
  window.open = function(url,name){
    if (url === void 0) return native_open(url,name);
    var message = { message: 'openInTab', url: url };
    try {
      port.postMessage(message);
    }
    catch (e) {
      port = chrome.runtime.connect(id);
      port.postMessage(message);
    }
    return true;
  };
  document.addEventListener('click',function(evt){
    if (evt.target.href && evt.target.target === '_blank'){
      evt.preventDefault();
      window.open(evt.target.href, '_blank');
    }
  },false);
  var _onload = window.onload;
  window.onload = function(){
    _onload();
    var p = window.Control.pin;
    var v = window.Control.view_original;
    var force_next_item = function(){
      var i = window.get_active_item();
      window.Control.scroll_next_item();
      if(i == window.get_active_item()){
        window.Control.scroll_next_item();
      }
    };
    var pin = function(){
      var res = p.apply(this, arguments);
      force_next_item();
      return res;
    };
    var view_original = function(){
      var res = v.apply(this, arguments);
      force_next_item();
      return res;
    };
    window.Keybind.add("p", pin);
    window.Keybind.add("v", view_original);
  };
})();
<|endoftext|>


<commit_before>$(document).ready(function() {
    /**
     * TinyMCE instance from the top level window object
     * @type object
     */
    var tinymce = top.tinymce;

    /**
     * Window modal object created by tinymce object
     * @type {Object}
     */
    var mcemodal = tinymce.activeEditor.windowManager.getWindows()[0];

    /**
     * @type {Object}
     */
    var options = tinymce.activeEditor.windowManager.getParams();

    /**
     * @type object|null
     */
    var previousCall = null;

    /**
     * Render result lists into thumbnail container
     * @param {object} images Collection retreived from the API
     */
    function render (images) {
        var regex = /\{\{[a-z]+\}\}/gi;
        var rowTemplate = '
{{thumbnails}}
';
        var container       = $('#thumbnail-container');
        var temporaryHtml   = '';
        var temporaryThumb  = '';

        for(var i = 0; i < images.length; i++){
            // Grab the item html
            var item = renderItem(images[i]);

            // Grab the route
            images[i].source = Routing.generate(
                'integrated_storage_file',
                {
                    id: images[i].id,
                    ext: images[i].extension
                }
            );

            // Parse values
            var match = [];
            while (null != (match = regex.exec(item))) {
                item = item.replace(
                    match[0],
                    images[i][match[0].substr(2, (match[0].length-4))]
                );
            }

            // Add it
            temporaryThumb += item;

            if(i % 4 == 3 || i == images.length - 1){
                temporaryHtml  += rowTemplate.replace(/\{\{thumbnails\}\}/g, temporaryThumb);
                temporaryThumb  = '';
            }
        }

        if(images.length == 0){
            temporaryHtml = '
No content found.
';
        }

        container.html(temporaryHtml);
    }

    /**
     * @param {object} item
     * @returns {string}
     */
    function renderItem(item)
    {
        var html = '

';

        if (item.mimeType.match('^video\/(.*)$')) {
            html += '<video poster="{{poster}}" controls class="img-responsive click-insert" data-integrated-id="{{id}}"><source src="{{source}}" type="{{mimeType}}"></video>';
        } else if (item.mimeType.match('^image\/(.*)$')) {
            html += '';
        } else {
            html += '
Not supported content type
'
        }

        html += '

';

        return html;
    }

    /**
     * Render pagination part of the image browser
     * @param {object} page Pagination data retrieved from the API
     */
    function renderPagination(page){
        var paginationTemplate =
            ''+
            '
'+
            '{{page-prev}}'+
            '{{page-num}}'+
            '{{page-next}}'+
            '
'+
            '';

        var container = $('#pagination-container');
        var thumbnailContainer = $('#thumbnail-container');
        var temporaryHtml = '';
        var pageNum = '';

        /** hide the pagination if only one page found and return immediately */
        if(page.pageCount == 1) {
            container.html('');
            thumbnailContainer.css('height', '520px');
            return;
        } else {
            thumbnailContainer.removeAttr('style');
        }

        /** process the template to render pagination link */
        for(
            var i = page.page - 2 - (page.pageCount - page.page < 2 ? 2 - (page.pageCount - page.page) : 0);
            i <= page.page + 2 + (page.page <= 2 ? 3 - page.page : 0);
            i++
        ) {
            if(typeof page.pages[i] != 'undefined'){
                pageNum +=  '
'+
                    ''+i+''+
                    '
';
            }
        }

        temporaryHtml = paginationTemplate.replace(
            '{{page-prev}}',
            '
'+
            ''+
            '«'+
            ''+
            '
'
        ).replace(
            '{{page-next}}',
            '
'+
            ''+
            '»'+
            ''+
            '
'
        ).replace(
            '{{page-num}}', pageNum
        );

        container.html(temporaryHtml);
    }

    /**
     * Refresh the content
     */
    function refresh () {
        $('#thumbnail-container').loader('show');

        var params = {
            "q": $('#txt-search').val(),
            "_format": "json"
        };

        var selectedContentTypes = getSelectedContentTypes();

        for (var i in selectedContentTypes) {
            params["contenttypes[" + i + "]"] = selectedContentTypes[i];
        }

        if(previousCall !== null){
            previousCall.abort();
        }

        previousCall =
            $.get(Routing.generate('integrated_content_content_index', params), function(data) {
                render(data.items);
                renderPagination(data.pagination);
            }, 'json')
                .error(function(xhr, status){
                    if(status !== 'abort'){
                        $('#thumbnail-container').html('
Error occured while loading content
');
                    }
                }).done(function () {
                $('#thumbnail-container').loader('hide');
            })
        ;
    }

    /**
     *
     * @returns {[string]}
     */
    function getSelectedContentTypes() {
        var selected = $('#type-search').val();

        if (selected) {
            return [selected];
        } else {

            var options = $('#type-search option');

            return $.map(options ,function(option) {
                if (option.value) {
                    return option.value;
                }
            });
        }
    }

    /**
     * Type ahead search handler
     */
    $(document).on('keyup', '#txt-search', function () {
        refresh();
    });

    /**
     * Content type switcher
     */
    $(document).on('change', '#type-search', function () {
        refresh();
    });

    /**
     * Pagination link click handler
     */
    $('#pagination-container').on('click', 'a', function(e){
        e.preventDefault();
        $('#thumbnail-container').loader('show');

        var href = $(this).attr('href');

        if(href !== '#'){
            $.get(href, function(data){
                render(data.items);
                renderPagination(data.pagination);
            }, 'json')
                .error(function(){
                    $('#thumbnail-container').html('
Error occured while loading content
')
                })
                .done(function() {
                    $('#thumbnail-container').loader('hide');
                });
        }
    });

    /**
     * Image thumbnail click handler
     * insert the image into editor and close the window
     */
    $('#thumbnail-container').on('click', '.click-insert', function(e){
        e.preventDefault();

        var item = $(this);
        item.removeClass('click-insert');

        // Inject the image
        tinymce.activeEditor.insertContent(item[0].outerHTML);
        mcemodal.close();
    });

    /**
     * Here the plugin begins
     */
    $.get(Routing.generate('integrated_content_content_media_types', {'filter': options['mode']}), function (contentTypes) {
        var buttonHtml = '';

        if (contentTypes.length == 1) {
            buttonHtml = 'Upload new '+ contentTypes[0].name +'';
        } else if (contentTypes.length > 1) {
            buttonHtml =
                '<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">' +
                'Upload new ' + options['mode'] + '</button>' +
                '
';

            for (var i in contentTypes) {
                buttonHtml += '
'+ contentTypes[i].name +'
';
            }

            buttonHtml += '
';
        }

        $('#button_wrap').html(buttonHtml);

        var searchHtml = '';
        if (contentTypes.length) {
            if (contentTypes.length > 1) {
                searchHtml += '<option value="">All content types</option>';
            }

            for (var i in contentTypes) {
                searchHtml += '<option value="'+ contentTypes[i].id +'">'+ contentTypes[i].name +'</option>';
            }
        } else {
            searchHtml += '<option>No content types available</option>';
        }

        $('#type-search').html(searchHtml);
        refresh();

        $('.btn-content-add').click(function(e) {
            e.preventDefault();

            tinymce.activeEditor.windowManager.open({
                title: 'Add a new '+ $(this).text(),
                url: $(this).attr('href') + '&_format=iframe.html',
                width: 800,
                height: 600
            }).on('close', function () {
                refresh();
            });
        });
    }).error(function() {
        $('#add_image_wrapper').html('
Failed to retrieve content types.
');
    }).done(function (){
        $('#add_image_wrapper').css('opacity',1);
    });
});
<commit_msg>Find tinymce on parent instead of top window<commit_after>$(document).ready(function() {
    /**
     * TinyMCE instance from the top level window object
     * @type object
     */
    var tinymce = parent.tinymce;

    /**
     * Window modal object created by tinymce object
     * @type {Object}
     */
    var mcemodal = tinymce.activeEditor.windowManager.getWindows()[0];

    /**
     * @type {Object}
     */
    var options = tinymce.activeEditor.windowManager.getParams();

    /**
     * @type object|null
     */
    var previousCall = null;

    /**
     * Render result lists into thumbnail container
     * @param {object} images Collection retreived from the API
     */
    function render (images) {
        var regex = /\{\{[a-z]+\}\}/gi;
        var rowTemplate = '
{{thumbnails}}
';
        var container       = $('#thumbnail-container');
        var temporaryHtml   = '';
        var temporaryThumb  = '';

        for(var i = 0; i < images.length; i++){
            // Grab the item html
            var item = renderItem(images[i]);

            // Grab the route
            images[i].source = Routing.generate(
                'integrated_storage_file',
                {
                    id: images[i].id,
                    ext: images[i].extension
                }
            );

            // Parse values
            var match = [];
            while (null != (match = regex.exec(item))) {
                item = item.replace(
                    match[0],
                    images[i][match[0].substr(2, (match[0].length-4))]
                );
            }

            // Add it
            temporaryThumb += item;

            if(i % 4 == 3 || i == images.length - 1){
                temporaryHtml  += rowTemplate.replace(/\{\{thumbnails\}\}/g, temporaryThumb);
                temporaryThumb  = '';
            }
        }

        if(images.length == 0){
            temporaryHtml = '
No content found.
';
        }

        container.html(temporaryHtml);
    }

    /**
     * @param {object} item
     * @returns {string}
     */
    function renderItem(item)
    {
        var html = '

';

        if (item.mimeType.match('^video\/(.*)$')) {
            html += '<video poster="{{poster}}" controls class="img-responsive click-insert" data-integrated-id="{{id}}"><source src="{{source}}" type="{{mimeType}}"></video>';
        } else if (item.mimeType.match('^image\/(.*)$')) {
            html += '';
        } else {
            html += '
Not supported content type
'
        }

        html += '

';

        return html;
    }

    /**
     * Render pagination part of the image browser
     * @param {object} page Pagination data retrieved from the API
     */
    function renderPagination(page){
        var paginationTemplate =
            ''+
            '
'+
            '{{page-prev}}'+
            '{{page-num}}'+
            '{{page-next}}'+
            '
'+
            '';

        var container = $('#pagination-container');
        var thumbnailContainer = $('#thumbnail-container');
        var temporaryHtml = '';
        var pageNum = '';

        /** hide the pagination if only one page found and return immediately */
        if(page.pageCount == 1) {
            container.html('');
            thumbnailContainer.css('height', '520px');
            return;
        } else {
            thumbnailContainer.removeAttr('style');
        }

        /** process the template to render pagination link */
        for(
            var i = page.page - 2 - (page.pageCount - page.page < 2 ? 2 - (page.pageCount - page.page) : 0);
            i <= page.page + 2 + (page.page <= 2 ? 3 - page.page : 0);
            i++
        ) {
            if(typeof page.pages[i] != 'undefined'){
                pageNum +=  '
'+
                    ''+i+''+
                    '
';
            }
        }

        temporaryHtml = paginationTemplate.replace(
            '{{page-prev}}',
            '
'+
            ''+
            '«'+
            ''+
            '
'
        ).replace(
            '{{page-next}}',
            '
'+
            ''+
            '»'+
            ''+
            '
'
        ).replace(
            '{{page-num}}', pageNum
        );

        container.html(temporaryHtml);
    }

    /**
     * Refresh the content
     */
    function refresh () {
        $('#thumbnail-container').loader('show');

        var params = {
            "q": $('#txt-search').val(),
            "_format": "json"
        };

        var selectedContentTypes = getSelectedContentTypes();

        for (var i in selectedContentTypes) {
            params["contenttypes[" + i + "]"] = selectedContentTypes[i];
        }

        if(previousCall !== null){
            previousCall.abort();
        }

        previousCall =
            $.get(Routing.generate('integrated_content_content_index', params), function(data) {
                render(data.items);
                renderPagination(data.pagination);
            }, 'json')
                .error(function(xhr, status){
                    if(status !== 'abort'){
                        $('#thumbnail-container').html('
Error occured while loading content
');
                    }
                }).done(function () {
                $('#thumbnail-container').loader('hide');
            })
        ;
    }

    /**
     *
     * @returns {[string]}
     */
    function getSelectedContentTypes() {
        var selected = $('#type-search').val();

        if (selected) {
            return [selected];
        } else {

            var options = $('#type-search option');

            return $.map(options ,function(option) {
                if (option.value) {
                    return option.value;
                }
            });
        }
    }

    /**
     * Type ahead search handler
     */
    $(document).on('keyup', '#txt-search', function () {
        refresh();
    });

    /**
     * Content type switcher
     */
    $(document).on('change', '#type-search', function () {
        refresh();
    });

    /**
     * Pagination link click handler
     */
    $('#pagination-container').on('click', 'a', function(e){
        e.preventDefault();
        $('#thumbnail-container').loader('show');

        var href = $(this).attr('href');

        if(href !== '#'){
            $.get(href, function(data){
                render(data.items);
                renderPagination(data.pagination);
            }, 'json')
                .error(function(){
                    $('#thumbnail-container').html('
Error occured while loading content
')
                })
                .done(function() {
                    $('#thumbnail-container').loader('hide');
                });
        }
    });

    /**
     * Image thumbnail click handler
     * insert the image into editor and close the window
     */
    $('#thumbnail-container').on('click', '.click-insert', function(e){
        e.preventDefault();

        var item = $(this);
        item.removeClass('click-insert');

        // Inject the image
        tinymce.activeEditor.insertContent(item[0].outerHTML);
        mcemodal.close();
    });

    /**
     * Here the plugin begins
     */
    $.get(Routing.generate('integrated_content_content_media_types', {'filter': options['mode']}), function (contentTypes) {
        var buttonHtml = '';

        if (contentTypes.length == 1) {
            buttonHtml = 'Upload new '+ contentTypes[0].name +'';
        } else if (contentTypes.length > 1) {
            buttonHtml =
                '<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">' +
                'Upload new ' + options['mode'] + '</button>' +
                '
';

            for (var i in contentTypes) {
                buttonHtml += '
'+ contentTypes[i].name +'
';
            }

            buttonHtml += '
';
        }

        $('#button_wrap').html(buttonHtml);

        var searchHtml = '';
        if (contentTypes.length) {
            if (contentTypes.length > 1) {
                searchHtml += '<option value="">All content types</option>';
            }

            for (var i in contentTypes) {
                searchHtml += '<option value="'+ contentTypes[i].id +'">'+ contentTypes[i].name +'</option>';
            }
        } else {
            searchHtml += '<option>No content types available</option>';
        }

        $('#type-search').html(searchHtml);
        refresh();

        $('.btn-content-add').click(function(e) {
            e.preventDefault();

            tinymce.activeEditor.windowManager.open({
                title: 'Add a new '+ $(this).text(),
                url: $(this).attr('href') + '&_format=iframe.html',
                width: 800,
                height: 600
            }).on('close', function () {
                refresh();
            });
        });
    }).error(function() {
        $('#add_image_wrapper').html('
Failed to retrieve content types.
');
    }).done(function (){
        $('#add_image_wrapper').css('opacity',1);
    });
});
<|endoftext|>


<commit_before>var Utils = GLOBAL.Utils = {

    extractIntelData: function(jsSource) {
        // To stay the same with IITC, we don't extract essential data directly,
        // instead, we build a virual environment, then call IITC functions.
        //
        // Because of there are no `window` object in NodeJS, we need to expose
        // those global variables in order to let IITC functions work without
        // any modification.
        var window = {};
        var source = jsSource;

        // extract global variables
        var globalVars = [];

        var esprima = require('esprima');
        var escope = require('escope');

        var tree = esprima.parse(source);
        globalScope = escope.analyze(tree).scopes[0];
        globalScope.variables.forEach(function (v) {
            globalVars.push(v.identifiers[0].name);
        });

        // expose global variables
        globalVars.forEach(function(name) {
            source = source + ';window.' + name + ' = ' + name + ';';
        });

        // stimulate Google Map object
        source = 'var google={maps:{OverlayView:function(){}}};' + source;
        source = 'var IS_TABLET=false;' + source;

        // execute JavaScript
        eval(source);
        Utils.extractFromStock(window);

        if (window.niantic_params.CURRENT_VERSION == undefined) {
            throw new Error('Failed to extract version');
        }

        return window.niantic_params;
    },

    // from IITC code
    extractFromStock: function(window) {
      var niantic_params = window.niantic_params = {}

      //TODO: need to search through the stock intel minified functions/data structures for the required variables
      // just as a *very* quick fix, test the theory with hard-coded variable names

      // extract the former nemesis.dashboard.config.CURRENT_VERSION from the code
      var reVersion = new RegExp('[a-z]=[a-z].getData\\(\\);[a-z].v="([a-f0-9]{40})";');

      var minified = new RegExp('^[a-zA-Z][a-zA-Z0-9]$');

      for (var topLevel in window) {
        if (minified.test(topLevel)) {
          // a minified object - check for minified prototype entries

          // the object has a prototype - iterate through the properties of that
          if (window[topLevel] && window[topLevel].prototype) {
            for (var secLevel in window[topLevel].prototype) {
              if (minified.test(secLevel)) {

                // looks like we've found an object of the format "XX.prototype.YY"...

                var item = window[topLevel].prototype[secLevel];

                if (item && typeof(item) == "function") {
                  // a function - test it against the relevant regular expressions
                  var funcStr = item.toString();

                  var match = reVersion.exec(funcStr);
                  if (match) {
                    //console.log('Found former CURRENT_VERSION in '+topLevel+'.prototype.'+secLevel);
                    niantic_params.CURRENT_VERSION = match[1];
                  }

                }

              }
            }

          }
        }
      }
    },

    getMapZoomTileParameters: function(zoom) {
        // these arrays/constants are based on those in the stock intel site. it's essential we keep them in sync with their code
        // (it may be worth reading the values from their code rather than using our own copies? it's a case of either
        //  breaking if they rename their variables if we do, or breaking if they change the values if we don't)
        var ZOOM_TO_TILES_PER_EDGE = [64, 64, 64, 64, 256, 256, 256, 1024, 1024, 1536, 4096, 4096, 6500, 6500, 6500];
        var MAX_TILES_PER_EDGE = 9000;
        var ZOOM_TO_LEVEL = [8, 8, 8, 8, 7, 7, 7, 6, 6, 5, 4, 4, 3, 2, 2, 1, 1];

        return {
            level: ZOOM_TO_LEVEL[zoom] || 0,  // default to level 0 (all portals) if not in array
            tilesPerEdge: ZOOM_TO_TILES_PER_EDGE[zoom] || MAX_TILES_PER_EDGE,
            zoom: zoom  // include the zoom level, for reference
        };
    },

    lngToTile: function(lng, params) {
        return Math.floor((lng + 180) / 360 * params.tilesPerEdge);
    },

    latToTile: function(lat, params) {
        return Math.floor((1 - Math.log(Math.tan(lat * Math.PI / 180) +
            1 / Math.cos(lat * Math.PI / 180)) / Math.PI) / 2 * params.tilesPerEdge);
    },

    tileToLng: function(x, params) {
        return x / params.tilesPerEdge * 360 - 180;
    },

    tileToLat: function(y, params) {
        var n = Math.PI - 2 * Math.PI * y / params.tilesPerEdge;
        return 180 / Math.PI * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n)));
    },

    pointToTileId: function(params, x, y) {
        //change to quadkey construction
        //as of 2014-05-06: zoom_x_y_minlvl_maxlvl_maxhealth

        return params.zoom + "_" + x + "_" + y + "_" + params.level + "_8_100";
    },

    clampLat: function(lat) {
        // the map projection used does not handle above approx +- 85 degrees north/south of the equator
        if (lat > 85.051128)
            lat = 85.051128;
        else if (lat < -85.051128)
            lat = -85.051128;
        return lat;
    },

    clampLng: function(lng) {
        if (lng > 179.999999)
            lng = 179.999999;
        else if (lng < -180.0)
            lng = -180.0;
        return lng;
    },

    clampLatLng: function(latlng) {
        return new L.LatLng ( Utils.clampLat(latlng.lat), Utils.clampLng(latlng.lng) );
    },

    clampLatLngBounds: function(bounds) {
        return new L.LatLngBounds ( Utils.clampLatLng(bounds.getSouthWest()), Utils.clampLatLng(bounds.getNorthEast()) );
    },

    //$.extend
    extend: function() {

        for (var i = 1; i < arguments.length; i++)
            for (var key in arguments[i])
                if (arguments[i].hasOwnProperty(key))
                    arguments[0][key] = arguments[i][key];

        return arguments[0];

    },

}
<commit_msg> minified regexp fixes<commit_after>var Utils = GLOBAL.Utils = {

    extractIntelData: function(jsSource) {
        // To stay the same with IITC, we don't extract essential data directly,
        // instead, we build a virual environment, then call IITC functions.
        //
        // Because of there are no `window` object in NodeJS, we need to expose
        // those global variables in order to let IITC functions work without
        // any modification.
        var window = {};
        var source = jsSource;

        // extract global variables
        var globalVars = [];

        var esprima = require('esprima');
        var escope = require('escope');

        var tree = esprima.parse(source);
        globalScope = escope.analyze(tree).scopes[0];
        globalScope.variables.forEach(function (v) {
            globalVars.push(v.identifiers[0].name);
        });

        // expose global variables
        globalVars.forEach(function(name) {
            source = source + ';window.' + name + ' = ' + name + ';';
        });

        // stimulate Google Map object
        source = 'var google={maps:{OverlayView:function(){}}};' + source;
        source = 'var IS_TABLET=false;' + source;

        // execute JavaScript
        eval(source);
        Utils.extractFromStock(window);

        if (window.niantic_params.CURRENT_VERSION == undefined) {
            throw new Error('Failed to extract version');
        }

        return window.niantic_params;
    },

    // from IITC code
    extractFromStock: function(window) {
      var niantic_params = window.niantic_params = {}

      //TODO: need to search through the stock intel minified functions/data structures for the required variables
      // just as a *very* quick fix, test the theory with hard-coded variable names

      // extract the former nemesis.dashboard.config.CURRENT_VERSION from the code
      var reVersion = new RegExp('[a-z]=[a-z].getData\\(\\);[a-z].v="([a-f0-9]{40})";');

      var minified = new RegExp('^[a-zA-Z$][a-zA-Z$0-9]$');

      for (var topLevel in window) {
        if (minified.test(topLevel)) {
          // a minified object - check for minified prototype entries

          // the object has a prototype - iterate through the properties of that
          if (window[topLevel] && window[topLevel].prototype) {
            for (var secLevel in window[topLevel].prototype) {
              if (minified.test(secLevel)) {

                // looks like we've found an object of the format "XX.prototype.YY"...

                var item = window[topLevel].prototype[secLevel];

                if (item && typeof(item) == "function") {
                  // a function - test it against the relevant regular expressions
                  var funcStr = item.toString();

                  var match = reVersion.exec(funcStr);
                  if (match) {
                    //console.log('Found former CURRENT_VERSION in '+topLevel+'.prototype.'+secLevel);
                    niantic_params.CURRENT_VERSION = match[1];
                  }

                }

              }
            }

          }
        }
      }
    },

    getMapZoomTileParameters: function(zoom) {
        // these arrays/constants are based on those in the stock intel site. it's essential we keep them in sync with their code
        // (it may be worth reading the values from their code rather than using our own copies? it's a case of either
        //  breaking if they rename their variables if we do, or breaking if they change the values if we don't)
        var ZOOM_TO_TILES_PER_EDGE = [64, 64, 64, 64, 256, 256, 256, 1024, 1024, 1536, 4096, 4096, 6500, 6500, 6500];
        var MAX_TILES_PER_EDGE = 9000;
        var ZOOM_TO_LEVEL = [8, 8, 8, 8, 7, 7, 7, 6, 6, 5, 4, 4, 3, 2, 2, 1, 1];

        return {
            level: ZOOM_TO_LEVEL[zoom] || 0,  // default to level 0 (all portals) if not in array
            tilesPerEdge: ZOOM_TO_TILES_PER_EDGE[zoom] || MAX_TILES_PER_EDGE,
            zoom: zoom  // include the zoom level, for reference
        };
    },

    lngToTile: function(lng, params) {
        return Math.floor((lng + 180) / 360 * params.tilesPerEdge);
    },

    latToTile: function(lat, params) {
        return Math.floor((1 - Math.log(Math.tan(lat * Math.PI / 180) +
            1 / Math.cos(lat * Math.PI / 180)) / Math.PI) / 2 * params.tilesPerEdge);
    },

    tileToLng: function(x, params) {
        return x / params.tilesPerEdge * 360 - 180;
    },

    tileToLat: function(y, params) {
        var n = Math.PI - 2 * Math.PI * y / params.tilesPerEdge;
        return 180 / Math.PI * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n)));
    },

    pointToTileId: function(params, x, y) {
        //change to quadkey construction
        //as of 2014-05-06: zoom_x_y_minlvl_maxlvl_maxhealth

        return params.zoom + "_" + x + "_" + y + "_" + params.level + "_8_100";
    },

    clampLat: function(lat) {
        // the map projection used does not handle above approx +- 85 degrees north/south of the equator
        if (lat > 85.051128)
            lat = 85.051128;
        else if (lat < -85.051128)
            lat = -85.051128;
        return lat;
    },

    clampLng: function(lng) {
        if (lng > 179.999999)
            lng = 179.999999;
        else if (lng < -180.0)
            lng = -180.0;
        return lng;
    },

    clampLatLng: function(latlng) {
        return new L.LatLng ( Utils.clampLat(latlng.lat), Utils.clampLng(latlng.lng) );
    },

    clampLatLngBounds: function(bounds) {
        return new L.LatLngBounds ( Utils.clampLatLng(bounds.getSouthWest()), Utils.clampLatLng(bounds.getNorthEast()) );
    },

    //$.extend
    extend: function() {

        for (var i = 1; i < arguments.length; i++)
            for (var key in arguments[i])
                if (arguments[i].hasOwnProperty(key))
                    arguments[0][key] = arguments[i][key];

        return arguments[0];

    },

}
<|endoftext|>


<commit_before>'use strict';
var util = require('util');
var events = require('events');

/**
 * Simulate a serial port with modbus-rtu slave replay
 */
var TestPort = function() {
    events.call(this);
}
util.inherits(TestPort, events);

/**
 * calculate crc16
 *
 * @param {buffer} buf the buffer to to crc on.
 *
 * @return {number} the calculated crc16
 */
function crc16(buf) {
    var length = buf.length - 2;
    var crc = 0xFFFF;
    var tmp;

    // calculate crc16
    for (var i = 0; i < length; i++) {
        crc = crc ^ buf[i];

        for (var j = 0; j < 8; j++) {
            tmp = crc & 0x0001;
            crc = crc >> 1;
            if (tmp) {
              crc = crc ^ 0xA001;
            }
        }
    }

    return crc;
}

/**
 * Simulate successful port open
 */
TestPort.prototype.open = function (callback) {
    callback(null);
}

/**
 * Simulate successful/failure port requests and replays
 */
TestPort.prototype.write = function (buf) {
    var buffer = null;
    var unitNumber = buf[0];
    var functionCode = buf[1];
    var crc = buf[buf.length - 2] + buf[buf.length - 1] * 0x100;

    // if crc is bad, ignore message
    if (crc != crc16(buf)) {
        return;
    }

    // function code 4
    if (functionCode == 4) {
        switch (unitNumber) {
            case 1:
                // unit 1: answers correctly
                buffer = new Buffer('010402000A3937', 'hex');
                break;
            case 2:
                // unit 2: answers short data
                buffer = new Buffer('020402000A', 'hex');
                break;
            case 3:
                // unit 3: answers with bad crc
                buffer = new Buffer('030402000A3937', 'hex');
                break;
            case 4:
                // unit 4: answers with bad unit number
                buffer = new Buffer('010402000A3937', 'hex');
                break;
        }
    }

    // function code 16
    if (functionCode == 16) {
        switch (unitNumber) {
            case 1:
                // unit 1: answers correctly
                buffer = new Buffer('0110000100021008', 'hex');
                break;
            case 2:
                // unit 2: answers short data
                buffer = new Buffer('0210000100', 'hex');
                break;
            case 3:
                // unit 3: answers with bad crc
                buffer = new Buffer('0310000100021008', 'hex');
                break;
            case 4:
                // unit 4: answers with bad unit number
                buffer = new Buffer('0110000100021010', 'hex');
                break;
        }
    }

    if (buffer) {
        this.emit('data', buffer);
    }
}

module.exports = TestPort;
<commit_msg>make testport more rubust<commit_after>'use strict';
var util = require('util');
var events = require('events');

/**
 * Simulate a serial port with 4 modbus-rtu slaves connected
 * 1 - a modbus slave working correctly
 * 2 - a modbus slave that answer short replays
 * 3 - a modbus slave that answer with bad crc
 * 4 - a modbus slave that answer with bad unit number
 */
var TestPort = function() {
    // simulate 14 registers
    this._registers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
    events.call(this);
}
util.inherits(TestPort, events);

/**
 * calculate crc16
 *
 * @param {buffer} buf the buffer to to crc on.
 *
 * @return {number} the calculated crc16
 */
function crc16(buf) {
    var length = buf.length - 2;
    var crc = 0xFFFF;
    var tmp;

    // calculate crc16
    for (var i = 0; i < length; i++) {
        crc = crc ^ buf[i];

        for (var j = 0; j < 8; j++) {
            tmp = crc & 0x0001;
            crc = crc >> 1;
            if (tmp) {
              crc = crc ^ 0xA001;
            }
        }
    }

    return crc;
}

/**
 * Simulate successful port open
 */
TestPort.prototype.open = function (callback) {
    callback(null);
}

/**
 * Simulate successful/failure port requests and replays
 */
TestPort.prototype.write = function (buf) {
    var buffer = null;

    // if length is too short, ignore message
    if (buf.length < 8) {
        return;
    }

    var unitNumber = buf[0];
    var functionCode = buf[1];
    var crc = buf[buf.length - 2] + buf[buf.length - 1] * 0x100;

    // if crc is bad, ignore message
    if (crc != crc16(buf)) {
        return;
    }

    // function code 4
    if (functionCode == 4) {
        var address = buf.readUInt16BE(2);
        var length = buf.readUInt16BE(4);

        // if length is bad, ignore message
        if (buf.length != 8) {
            return;
        }

        // build answer
        buffer = new Buffer(3 + length * 2 + 2);
        buffer.writeUInt8(length * 2, 2);

        // read registers
        for (var i = 0; i < length; i++) {
            buffer.writeUInt16BE(this._registers[address + i], 3 + i * 2);
        }
    }

    // function code 16
    if (functionCode == 16) {
        var address = buf.readUInt16BE(2);
        var length = buf.readUInt16BE(4);

        // if length is bad, ignore message
        if (buf.length != (7 + length * 2 + 2)) {
            return;
        }

        // build answer
        buffer = new Buffer(8);
        buffer.writeUInt16BE(address, 2);
        buffer.writeUInt16BE(length, 4);

        // write registers
        for (var i = 0; i < length; i++) {
            this._registers[address + i] = buf.readUInt16BE(7 + i * 2);
        }
    }

    // send data back
    if (buffer) {
        // add unit number and function code
        buffer.writeUInt8(unitNumber, 0);
        buffer.writeUInt8(functionCode, 1);

        // add crc
        crc = crc16(buffer);
        buffer.writeUInt16LE(crc, buffer.length - 2);

        // corrupt the answer
        switch (unitNumber) {
            case 1:
                // unit 1: answers correctly
                break;
            case 2:
                // unit 2: answers short data
                buffer = buffer.slice(0, buffer.length - 5);
                break;
            case 3:
                // unit 3: answers with bad crc
                buffer.writeUInt16LE(crc + 1, buffer.length - 2);
                break;
            case 4:
                // unit 4: answers with bad unit number
                buffer[0] = unitNumber + 2;
                break;
        }

        this.emit('data', buffer);
    }
}

module.exports = TestPort;
<|endoftext|>