Last active
August 29, 2015 14:24
-
-
Save ifours/58566d1ce00d896eff43 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** Example of angular factory. | |
Using promises, this service guarantees that any API calls to google services | |
will happen only after map object was initialized. | |
**/ | |
angular.module('services') | |
.factory('GoogleServices', function($q, $http, $rootScope, $map) { | |
var PlacesService, | |
DirectionsService; | |
var mapReady = $q.defer(); | |
$rootScope.$watch(function() { | |
return $map.map; | |
}, function(map, old) { | |
if (!map) { | |
return; | |
} | |
mapReady.resolve(map); | |
}); | |
var ready = mapReady.promise.then(function(map) { | |
PlacesService = new google.maps.places.PlacesService(map); | |
DirectionsService = new google.maps.DirectionsService(); | |
return { | |
nearbySearch: function(request) { | |
var q = $q.defer(); | |
PlacesService.nearbySearch(request, function(results, status) { | |
if (status === google.maps.places.PlacesServiceStatus.OK) { | |
q.resolve(results); | |
} | |
}); | |
return q.promise; | |
}, | |
placeDetails: function(request) { | |
var q = $q.defer(); | |
PlacesService.getDetails(request, function(results, status) { | |
if (status === google.maps.places.PlacesServiceStatus.OK) { | |
q.resolve(results); | |
} | |
}); | |
return q.promise; | |
}, | |
route: function(request) { | |
var q = $q.defer(); | |
DirectionsService.route(request, function(response, status) { | |
if (status === google.maps.DirectionsStatus.OK) { | |
q.resolve(response); | |
} | |
}); | |
return q.promise; | |
} | |
} | |
}) | |
return { | |
ready: ready, | |
} | |
}); | |
// Usage | |
this.nearbySearch = function(startPoint) { | |
return GoogleServices.ready.then(function(services) { | |
return services.nearbySearch({ | |
location: {lat: startPoint.lat(), lng: startPoint.lng()}, | |
radius: SettingsData.radius, | |
types: makeCategories(), | |
}); | |
}); | |
}; | |
/** Same realization as above but service guarantees | |
that controllers will work with data using one interface | |
**/ | |
'use strict'; | |
angular.module('incitesApp.analytics') | |
.factory('exploreState', function ($q, userStorage, metadataRepository) { | |
return { | |
load: function (entity, tile) { | |
var state = userStorage.loadExploreState(entity) || {}, | |
requestParams = state.request || { take: 25, skip: 0 }, | |
indicators = metadataRepository.getIndicators(entity) | |
.then(function (metadata) { | |
var requiredIndicators = _(metadata.indicators).filter('required').pluck('name').value(); | |
requestParams.sortBy = requestParams.sortBy || metadata.primaryIndicator; | |
requestParams.sortOrder = requestParams.sortOrder || metadata.primaryOrder; | |
requestParams.indicators = _.union(requestParams.indicators || metadata.enabledIndicators, requiredIndicators); | |
return metadata; | |
}), | |
filtersReady = $q.defer(), | |
filters = this.filters = $q.all({ metadata: metadataRepository.getFilters(entity), tile: tile }) | |
.then(function (result) { | |
var metadata = result.metadata, tile = result.tile; | |
metadata.values = tile && tile.request ? tile.request.filters : angular.copy(requestParams.filters); // TODO | |
metadata.ready = filtersReady; | |
return metadata; | |
}), | |
benchmarks = metadataRepository.getBenchmarks(entity) | |
.then(function (benchmarks) { | |
benchmarks.forEach(function (benchmark) { | |
benchmark.selected = _.contains(state.benchmarks, benchmark.name); | |
}); | |
return benchmarks; | |
}); | |
filtersReady.promise.then(function (filters) { | |
requestParams.filters = filters; | |
}); | |
this.ready = $q.all({ | |
indicators: indicators, | |
filters: filters, | |
benchmarks: benchmarks, | |
request: requestParams, | |
ready: filtersReady.promise, | |
visualization: state.visualization, | |
dimensions: state.dimensions | |
}).then(function (state) { | |
return angular.extend({ | |
getEnabledIndicators: function () { | |
return this.request.indicators.map(function (i) { | |
return _.find(state.indicators.indicators, { name: i }); | |
}); | |
}, | |
getEnabledBenchmarks: function () { | |
return _.filter(state.benchmarks, 'selected'); | |
}, | |
save: function () { | |
userStorage.saveExploreState(entity, { | |
request: this.request, | |
benchmarks: _.pluck(this.getEnabledBenchmarks(), 'name'), | |
visualization: this.visualization, | |
dimensions: this.dimensions | |
}); | |
} | |
}, state); | |
}); | |
return this.ready; | |
} | |
}; | |
}); | |
// Usage | |
// Main Ctrl | |
exploreState.load($stateParams.entity, tile).then(function(state){}) | |
// Other Ctrl | |
exploreState.ready.then(function(state){}) | |
/** Grunt task for export and import translation files | |
Our translation team asked us to give them xml file with needed structure. | |
**/ | |
module.exports = function (grunt) { | |
var _log = grunt.log, | |
_file = grunt.file, | |
_ = grunt.util._, | |
xml2js = require('xml2js'); | |
grunt.registerTask('locale', 'Export and import translation files', function (target) { | |
if (arguments.length === 0 || arguments.length > 1) { | |
_log.error('Missing target.'); | |
return false; | |
} else { | |
_log.ok(('Starting translations:' + target + ' task').green); | |
grunt.task.run('translations:' + target); | |
} | |
}); | |
grunt.registerMultiTask('translations', 'Export and import translation files', function () { | |
var files = _file.expand(this.data.src), | |
type = this.data.type, | |
dest = this.data.dest; | |
var flatObj = function (obj, keys) { | |
keys = keys || []; | |
return Object.getOwnPropertyNames(obj).reduce(function (container, key) { | |
keys.push(key); | |
var value = obj[key]; | |
if (_.isObject(value)) { | |
_.merge(container, flatObj(value, keys)); | |
keys.pop(); | |
} else { | |
container[keys.join('.')] = value; | |
keys.pop(); | |
} | |
return container; | |
}, {}); | |
}; | |
var buildBranch = function (key, value) { | |
var parts = key.split('.'), result = {}; | |
if (parts.length > 1) { | |
result[parts[0]] = buildBranch(parts.slice(1).join('.'), value); | |
} else { | |
result[key] = value; | |
} | |
return result; | |
}; | |
var buildTree = function (map) { | |
return Object.getOwnPropertyNames(map).reduce(function (obj, prop) { | |
return _.merge(obj, buildBranch(prop, map[prop])); | |
}, {}); | |
}; | |
function sort(object) { | |
if (Array.isArray(object) || typeof(object) !== 'object') { | |
return object; | |
} | |
var sorted = {}; | |
var keys = Object.keys(object).sort(function (a, b) { | |
return a > b ? 1 : -1; | |
}); | |
keys.forEach(function (key) { | |
sorted[key] = sort(object[key]); | |
}); | |
return sorted; | |
} | |
files.forEach(function (file) { | |
_log.debug('Process extra file: ' + file); | |
var path = file.split('/'), name = path[path.length - 1].split('.'); | |
name.pop(); | |
var destFilename = dest + name.join('.') + '.' + type, | |
input = type === 'xml' ? _file.readJSON(file) : _file.read(file), | |
output = ''; | |
if (type === 'xml') { | |
var builder = new xml2js.Builder({ doctype: { sysID: 'http://java.sun.com/dtd/properties.dtd' }}), | |
json = flatObj(input), | |
obj = { | |
properties: { | |
entry: _.map(json, function (value, key) { | |
return {_: value, $: {key: key}}; | |
}).sort(function (a, b) { | |
return a.$.key > b.$.key ? 1 : -1; | |
}) | |
} | |
}; | |
output = builder.buildObject(obj); | |
} else if (type === 'json') { | |
xml2js.parseString(input, function (err, result) { | |
if (err) { | |
throw err; | |
} | |
var entries = result.properties.entry.reduce(function (obj, property) { | |
obj[property.$.key] = property._; | |
return obj; | |
}, {}); | |
output = JSON.stringify(sort(buildTree(entries)), null, 2); | |
}); | |
} | |
_log.ok('File ' + destFilename + ' converted.' + ' OK'.green); | |
_file.write(destFilename, output); | |
}); | |
}); | |
}; | |
/** Class example with inheritance | |
**/ | |
define([ | |
'lib/underscore', | |
'helpers/global' | |
], function(_, global) { | |
var helpers = { | |
/** More helpers **/ | |
inherit: function(Child, Parent) { | |
var F = function() { }; | |
F.prototype = Parent.prototype; | |
Child.prototype = new F(); | |
Child.prototype.constructor = Child; | |
Child.superclass = Parent.prototype; | |
}, | |
/** More helpers **/ | |
}; | |
return helpers; | |
}); | |
// Usage | |
// var helpers = require('./helpers.js'), | |
define([ | |
'lib/underscore', | |
'helpers/helpers', | |
'events/events', | |
'helpers/global' | |
], function(_, helpers, Events, global) { | |
var messagePattern = '[token:{0}][topic:{1}][data:{2}]', | |
reg = /^\[token:(.*)\]\[topic:(.*)\]\[data:(.*)\]$/, | |
prototype; | |
prototype = { | |
init: function() { | |
if(this.initialized) { | |
throw new Error('Already initialized', this); | |
} | |
this.attachListener(); | |
this.bindTopics(); | |
this.bindActions(); | |
this.initialized = true; | |
}, | |
subscribe: function(topic, callback) { | |
if(!topic || !callback) { | |
return false; | |
} | |
if(!this.subscriptions[topic]) { | |
this.subscriptions[topic] = []; | |
} | |
return this.subscriptions[topic].push(callback); | |
}, | |
/** More properties **/ | |
publish: function(topic, data, immediately) { | |
if(!topic) { | |
return false; | |
} | |
this.sendMessage(topic, data, immediately); | |
}, | |
/** More properties **/ | |
sendMessage: function(topic, data, immediately) { | |
var message, that = this; | |
if(!this.target || !this.target.postMessage) { | |
return; | |
} | |
message = this.buildMessage(topic, data); | |
if(immediately) { | |
this.target.postMessage(message, this.targetOrigin); | |
} else { | |
global.setTimeout(function() { | |
that.target.postMessage(message, that.targetOrigin); | |
}, 0); | |
} | |
this.log("Message sent", message, topic, data); | |
}, | |
recieveMessage: function(e) { | |
var parsed = this.parseMessage(e.data), | |
handler; | |
if(parsed && parsed.topic && this.subscriptions[parsed.topic] && parsed.token === this.token && (!this.iframe || e.source == this.iframe.contentWindow)) { | |
this.log("Message accepted", parsed, handler); | |
for(var i=0, callbacks = this.subscriptions[parsed.topic], l = callbacks.length; i < l; i++) { | |
this.log("Callback invoked"); | |
callbacks[i].call(this, parsed.data); | |
} | |
} else { | |
this.log("Message rejected", parsed); | |
} | |
}, | |
buildMessage: function(topic, data) { | |
return helpers.format(messagePattern)(this.token, topic, JSON.stringify(data || {})); | |
}, | |
/** More properties **/ | |
setDefaultState: function() { | |
this.token = 'token', | |
this.targetOrigin = '*'; | |
}, | |
/** More properties **/ | |
}; | |
function Connection() { | |
this.events = new Events(); | |
this.target = ''; | |
this.initialized = false; | |
this.subscriptions = {}; | |
this.recieveMessage = _.bind(this.recieveMessage, this); | |
this.setDefaultState(); | |
} | |
_.extend(Connection.prototype, prototype); | |
return Connection; | |
}); | |
define([ | |
'lib/underscore', | |
'connection/connection', | |
'helpers/helpers' | |
], function(_, Connection, helpers) { | |
var prototype = { | |
init: function(iframe) { | |
this.constructor.superclass.init.apply(this); | |
if(!iframe) { | |
throw new Error('iframe parameter should not be empty', this); | |
} | |
this.iframe = iframe; | |
this.target = iframe.contentWindow; | |
this._attachIframe(); | |
}, | |
processQueue: function() { | |
// body | |
}, | |
_attachIframe: function() { | |
var that = this; | |
this.subscribe('connection.request', function(data) { | |
var newToken = helpers.generateToken(); | |
that.token = data.token; | |
that.targetOrigin = data.origin; | |
that.publish('connection.approve', { | |
token: newToken, | |
origin: that._getCurrentOrigin() | |
}); | |
that.token = newToken; | |
}); | |
this.subscribe('connection.connected', function(data) { | |
that.events.trigger('connection.connected', {host: that}); | |
}); | |
this.subscribe('connection.before.unload', function(data) { | |
this.events.trigger('connection.before.unload', data); | |
this.setDefaultState(); | |
}); | |
}, | |
loadWidget: function(options) { | |
// body | |
} | |
}; | |
function Host(options) { | |
Host.superclass.constructor.apply(this, arguments); | |
this.logAlias = 'Host'; | |
this.widgetQueue = []; | |
this.connectionApproved = false; | |
} | |
helpers.inherit(Host, Connection); | |
Host.prototype = _.extend(Host.prototype, prototype); | |
return Host; | |
}); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment