diff --git a/Gemfile b/Gemfile
index c3f591d..cdea679 100644
--- a/Gemfile
+++ b/Gemfile
@@ -11,9 +11,9 @@ gem 'haml'
gem 'nokogiri', '~> 1.6.8.rc2'
if Dir.exists?('../lingua_franca')
- gem 'lingua_franca', path: '../lingua_franca'
+ gem 'lingua_franca', :path => '../lingua_franca'
else
- gem 'lingua_franca', git: 'git://github.com/lingua-franca/lingua_franca.git'
+ gem 'lingua_franca', :git => 'git://github.com/lingua-franca/lingua_franca.git'
end
gem 'tzinfo-data'
@@ -21,15 +21,15 @@ gem 'sass'
gem 'sass-rails'
if Dir.exists?('../bumbleberry')
- gem 'bumbleberry', path: "../bumbleberry"
+ gem 'bumbleberry', :path => "../bumbleberry"
else
- gem 'bumbleberry', git: 'git://github.com/bumbleberry/bumbleberry.git'
+ gem 'bumbleberry', :git => 'git://github.com/bumbleberry/bumbleberry.git'
end
if Dir.exists?('../paypal-express')
- gem 'paypal-express', path: "../paypal-express"
+ gem 'paypal-express', :path => "../paypal-express"
else
- gem 'paypal-express', git: 'git://github.com/bikebike/paypal-express.git'
+ gem 'paypal-express', :git => 'git://github.com/bikebike/paypal-express.git'
end
gem 'uglifier', '>= 1.3.0'
@@ -48,55 +48,55 @@ gem 'redcarpet'
gem 'sidekiq'
gem 'letter_opener'
gem 'launchy'
-gem 'to_spreadsheet', git: 'git://github.com/glebm/to_spreadsheet.git'
+gem 'to_spreadsheet', :git => 'git://github.com/glebm/to_spreadsheet.git'
group :test do
- gem 'rspec'
- gem 'rspec-rails'
+ gem 'rspec'
+ gem 'rspec-rails'
end
group :development do
- gem 'better_errors'
- gem 'binding_of_caller'
- gem 'meta_request'
-
- gem 'capistrano', '~> 3.1'
- gem 'capistrano-rails', '~> 1.1'
- gem 'capistrano-faster-assets', '~> 1.0'
-
- gem 'eventmachine'#, :github => 'krzcho/eventmachine', :branch => 'master'
- gem 'thin'#, :github => 'krzcho/thin', :branch => 'master'
+ gem 'better_errors'
+ gem 'binding_of_caller'
+ gem 'meta_request'
+
+ gem 'capistrano', '~> 3.1'
+ gem 'capistrano-rails', '~> 1.1'
+ gem 'capistrano-faster-assets', '~> 1.0'
+
+ gem 'eventmachine', :github => 'krzcho/eventmachine', :branch => 'master'
+ gem 'thin', :github => 'krzcho/thin', :branch => 'master'
end
group :test do
- gem 'gherkin3', '>= 3.1.0'
- gem 'cucumber'
- gem 'cucumber-core'
- gem 'cucumber-rails'
-
- gem 'poltergeist'
- gem 'guard-rspec'
- gem 'factory_girl_rails'
- gem 'coveralls', require: false
- gem 'selenium-webdriver'
- gem 'simplecov', require: false
- gem 'webmock', require: false
- gem 'database_cleaner'
- gem 'mocha'
+ gem 'gherkin3', '>= 3.1.0'
+ gem 'cucumber'
+ gem 'cucumber-core'
+ gem 'cucumber-rails'
+
+ gem 'poltergeist'
+ gem 'guard-rspec'
+ gem 'factory_girl_rails'
+ gem 'coveralls', require: false
+ gem 'selenium-webdriver'
+ gem 'simplecov', require: false
+ gem 'webmock', require: false
+ gem 'database_cleaner'
+ gem 'mocha'
end
group :staging, :production, :preview do
- gem 'rails_12factor'
+ gem 'rails_12factor'
end
group :production, :preview do
- gem 'unicorn'
- gem 'daemon-spawn'
- gem 'daemons'
+ gem 'unicorn'
+ gem 'daemon-spawn'
+ gem 'daemons'
end
platforms 'mswin', 'mingw' do
- group :test do
- gem 'wdm', '>= 0.1.0'
- end
+ group :test do
+ gem 'wdm', '>= 0.1.0'
+ end
end
diff --git a/Rakefile b/Rakefile
index 9acaeca..b767df0 100644
--- a/Rakefile
+++ b/Rakefile
@@ -24,15 +24,25 @@ end
task update_cities: :environment do
Location.all.each do |l|
- city = City.search(([l.city, l.territory, l.country] - [nil, '']).join(', '))
- l.city_id = city.id
- l.save!
+ s = ([l.city, l.territory, l.country] - [nil, '']).join(', ')
+ unless l.city_id.present?
+ begin
+ puts "Searching for #{s}"
+ city = City.search(s)
+ l.city_id = city.id
+ l.save!
+ rescue
+ puts "Error searching for #{s}"
+ end
+ end
end
- City.all.each do |c|
- location = Geocoder.search(c.address, language: 'en').first
- c.place_id = location.data['place_id']
- c.save!
+ unless c.place_id.present?
+ City.all.each do |c|
+ location = Geocoder.search(c.address, language: 'en').first
+ c.place_id = location.data['place_id']
+ c.save!
+ end
end
end
@@ -43,3 +53,11 @@ task update_cities_es: :environment do
c.save!
end
end
+
+task update_cities_fr: :environment do
+ City.all.each do |c|
+ city = c.get_translation(:fr)
+ c.set_column_for_locale(:city, :fr, city, 0) unless city.blank? || city == c.get_column_for_locale(:city, :fr)
+ c.save!
+ end
+end
diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js
index f2f0a4e..da2e8ce 100644
--- a/app/assets/javascripts/main.js
+++ b/app/assets/javascripts/main.js
@@ -1,244 +1,290 @@
(function() {
- window.onerror = function(message, url, lineNumber) {
- //save error and send to server for example.
- var request = new XMLHttpRequest();
- request.open('POST', '/js_error', true);
- request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
- request.send(
- 'message=' + encodeURI(message) +
- '&url=' + encodeURI(url) +
- '&lineNumber=' + encodeURI(lineNumber) +
- '&location=' + encodeURI(window.location.href)
- );
- return false;
- };
- window.forEach = function(a, f) { Array.prototype.forEach.call(a, f) };
- window.forEachElement = function(s, f, p) { forEach((p || document).querySelectorAll(s), f) };
-
- var overlay = document.getElementById('content-overlay');
- if (overlay) {
- var body = document.querySelector('body');
- var primaryContent = document.getElementById('primary-content');
- primaryContent.addEventListener('keydown', function(event) {
- if (body.classList.contains('has-overlay')) {
- event.stopPropagation();
- return false;
- }
- });
- document.addEventListener('focus', function(event) {
- if (overlay.querySelector('.dlg.open') && !overlay.querySelector('.dlg.open :focus')) {
- overlay.querySelector('.dlg.open').focus();
- }
- }, true);
- window.openOverlay = function(dlg, primaryContent, body) {
- primaryContent.setAttribute('aria-hidden', 'true');
- body.classList.add('has-overlay');
- var type = dlg.getAttribute('data-type');
- if (type) {
- body.classList.add('is-' + type + '-dlg');
- }
- dlg.removeAttribute('aria-hidden');
- dlg.setAttribute('role', 'alertdialog');
- dlg.setAttribute('tabindex', '0');
- dlg.focus();
- setTimeout(function() { dlg.classList.add('open'); }, 100);
- }
- window.closeOverlay = function(dlg, primaryContent, body) {
- setTimeout(function() {
- body.classList.remove('has-overlay');
- body.removeAttribute('style');
- }, 250);
- var type = dlg.getAttribute('data-type');
- if (type) {
- body.classList.remove('is-' + type + '-dlg');
- }
- primaryContent.removeAttribute('aria-hidden');
- dlg.setAttribute('aria-hidden', 'true');
- dlg.removeAttribute('tabindex');
- dlg.classList.remove('open');
- dlg.removeAttribute('role');
- }
+ window.onerror = function(message, url, lineNumber) {
+ //save error and send to server for example.
+ var request = new XMLHttpRequest();
+ request.open('POST', '/js_error', true);
+ request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
+ request.send(
+ 'message=' + encodeURI(message) +
+ '&url=' + encodeURI(url) +
+ '&lineNumber=' + encodeURI(lineNumber) +
+ '&location=' + encodeURI(window.location.href)
+ );
+ return false;
+ };
+ window.forEach = function(a, f) { Array.prototype.forEach.call(a, f) };
+ window.forEachElement = function(s, f, p) { forEach((p || document).querySelectorAll(s), f) };
+
+ var overlay = document.getElementById('content-overlay');
+ if (overlay) {
+ var body = document.querySelector('body');
+ var primaryContent = document.getElementById('primary-content');
+ primaryContent.addEventListener('keydown', function(event) {
+ if (body.classList.contains('has-overlay')) {
+ event.stopPropagation();
+ return false;
+ }
+ });
+ document.addEventListener('focus', function(event) {
+ if (overlay.querySelector('.dlg.open') && !overlay.querySelector('.dlg.open :focus')) {
+ overlay.querySelector('.dlg.open').focus();
+ }
+ }, true);
+ window.openOverlay = function(dlg, primaryContent, body) {
+ primaryContent.setAttribute('aria-hidden', 'true');
+ body.classList.add('has-overlay');
+ var type = dlg.getAttribute('data-type');
+ if (type) {
+ body.classList.add('is-' + type + '-dlg');
+ }
+ dlg.removeAttribute('aria-hidden');
+ dlg.setAttribute('role', 'alertdialog');
+ dlg.setAttribute('tabindex', '0');
+ dlg.focus();
+ setTimeout(function() { dlg.classList.add('open'); }, 100);
+ }
+ window.closeOverlay = function(dlg, primaryContent, body) {
+ setTimeout(function() {
+ body.classList.remove('has-overlay');
+ body.removeAttribute('style');
+ }, 250);
+ var type = dlg.getAttribute('data-type');
+ if (type) {
+ body.classList.remove('is-' + type + '-dlg');
+ }
+ primaryContent.removeAttribute('aria-hidden');
+ dlg.setAttribute('aria-hidden', 'true');
+ dlg.removeAttribute('tabindex');
+ dlg.classList.remove('open');
+ dlg.removeAttribute('role');
+ }
- function openDlg(dlg, link) {
- document.getElementById('overlay').onclick =
- dlg.querySelector('.close').onclick = function() { closeDlg(dlg); };
- body.setAttribute('style', 'width: ' + body.clientWidth + 'px');
- var msg = link.querySelector('.message');
- if (msg) {
- dlg.querySelector('.message').innerHTML = msg.innerHTML
- }
- if (link.dataset.infoTitle) {
- dlg.querySelector('.title').innerHTML = decodeURI(link.dataset.infoTitle);
- }
- confirmBtn = dlg.querySelector('.confirm');
- if (confirmBtn) {
- confirmBtn.addEventListener('click', function(event) {
- event.preventDefault();
- if (link.tagName == 'BUTTON') {
- var form = link.parentElement
- while (form && form.tagName != 'FORM') {
- var form = form.parentElement
- }
- if (form) {
- var input = document.createElement('input');
- input.type = 'hidden';
- input.name = 'button';
- input.value = link.value;
- form.appendChild(input);
- form.submit();
- }
- } else {
- window.location.href = link.getAttribute('href');
- }
- });
- }
- window.openOverlay(dlg, primaryContent, body);
- }
- function closeDlg(dlg) {
- window.closeOverlay(dlg, primaryContent, body);
- }
+ function openDlg(dlg, link) {
+ document.getElementById('overlay').onclick =
+ dlg.querySelector('.close').onclick = function() { closeDlg(dlg); };
+ body.setAttribute('style', 'width: ' + body.clientWidth + 'px');
+ var msg = link.querySelector('.message');
+ if (msg) {
+ dlg.querySelector('.message').innerHTML = msg.innerHTML
+ }
+ if (link.dataset.infoTitle) {
+ dlg.querySelector('.title').innerHTML = decodeURI(link.dataset.infoTitle);
+ }
+ confirmBtn = dlg.querySelector('.confirm');
+ if (confirmBtn) {
+ confirmBtn.addEventListener('click', function(event) {
+ event.preventDefault();
+ if (link.tagName == 'BUTTON') {
+ var form = link.parentElement
+ while (form && form.tagName != 'FORM') {
+ var form = form.parentElement
+ }
+ if (form) {
+ var input = document.createElement('input');
+ input.type = 'hidden';
+ input.name = 'button';
+ input.value = link.value;
+ form.appendChild(input);
+ form.submit();
+ }
+ } else {
+ window.location.href = link.getAttribute('href');
+ }
+ });
+ }
+ window.openOverlay(dlg, primaryContent, body);
+ }
+ function closeDlg(dlg) {
+ window.closeOverlay(dlg, primaryContent, body);
+ }
- var confirmationDlg = document.getElementById('confirmation-dlg');
- forEachElement('[data-confirmation]', function(link) {
- link.addEventListener('click', function(event) {
- event.preventDefault();
- openDlg(confirmationDlg, link);
- return false;
- });
- });
- var infoDlg = document.getElementById('info-dlg');
- forEachElement('[data-info-text]', function(link) {
- link.addEventListener('click', function(event) {
- event.preventDefault();
- openDlg(infoDlg, link);
- return false;
- });
- });
- var loginDlg = document.getElementById('login-dlg');
- forEachElement('[data-sign-in]', function(link) {
- link.addEventListener('click', function(event) {
- event.preventDefault();
- openDlg(loginDlg, link);
- return false;
- });
- });
- var contactDlg = document.getElementById('contact-dlg');
- var contactLink = document.getElementById('contact-link');
- contactLink.addEventListener('click', function(event) {
- event.preventDefault();
- openDlg(contactDlg, contactLink);
- return false;
- });
- }
-
- var htmlNode = document.documentElement;
- document.addEventListener('keydown', function(event) {
- if (htmlNode.dataset.input != 'kb' &&
- ((["input", "textarea", "select", "option"].indexOf(event.target.nodeName.toLowerCase()) < 0 &&
- !event.target.attributes.contenteditable) || event.key == "Tab")) {
- htmlNode.setAttribute('data-input', 'kb');
- }
- });
-
- document.addEventListener('mousemove', function(event) {
- if (htmlNode.dataset.input != 'mouse' && (event.movementX || event.movementY)) {
- htmlNode.setAttribute('data-input', 'mouse');
- }
- });
+ var confirmationDlg = document.getElementById('confirmation-dlg');
+ forEachElement('[data-confirmation]', function(link) {
+ link.addEventListener('click', function(event) {
+ event.preventDefault();
+ openDlg(confirmationDlg, link);
+ return false;
+ });
+ });
+ var infoDlg = document.getElementById('info-dlg');
+ forEachElement('[data-info-text]', function(link) {
+ link.addEventListener('click', function(event) {
+ event.preventDefault();
+ openDlg(infoDlg, link);
+ return false;
+ });
+ });
+ var loginDlg = document.getElementById('login-dlg');
+ forEachElement('[data-sign-in]', function(link) {
+ link.addEventListener('click', function(event) {
+ event.preventDefault();
+ openDlg(loginDlg, link);
+ return false;
+ });
+ });
+ var contactDlg = document.getElementById('contact-dlg');
+ var contactLink = document.getElementById('contact-link');
+ contactLink.addEventListener('click', function(event) {
+ event.preventDefault();
+ openDlg(contactDlg, contactLink);
+ return false;
+ });
+ }
+
+ var htmlNode = document.documentElement;
+ document.addEventListener('keydown', function(event) {
+ if (htmlNode.dataset.input != 'kb' &&
+ ((["input", "textarea", "select", "option"].indexOf(event.target.nodeName.toLowerCase()) < 0 &&
+ !event.target.attributes.contenteditable) || event.key == "Tab")) {
+ htmlNode.setAttribute('data-input', 'kb');
+ }
+ });
+
+ document.addEventListener('mousemove', function(event) {
+ if (htmlNode.dataset.input != 'mouse' && (event.movementX || event.movementY)) {
+ htmlNode.setAttribute('data-input', 'mouse');
+ }
+ });
- var errorField = document.querySelector('.input-field.has-error input, .input-field.has-error textarea');
- if (errorField) {
- errorField.focus();
- }
-
- window.initNodeFunctions = [ function(node) {
- forEachElement('.number-field,.email-field,.text-field,.password-field,.search-field', function(field) {
- var input = field.querySelector('input');
- var positionLabel = function(input) {
- field.classList[input.value ? 'remove' : 'add']('empty');
- }
- positionLabel(input);
- input.addEventListener('keyup', function(event) {
- positionLabel(event.target);
- });
- input.addEventListener('blur', function(event) {
- positionLabel(event.target);
- field.classList.remove('focused');
- });
- input.addEventListener('focus', function(event) {
- field.classList.add('focused');
- });
- }, node || document);
- forEachElement('form.js-xhr', function(form) {
- if (form.addEventListener) {
- form.addEventListener('submit', function(event) {
- event.preventDefault();
- form.classList.add('requesting');
- var data = new FormData(form);
- var request = new XMLHttpRequest();
- request.onreadystatechange = function() {
- if (request.readyState == 4) {
- form.classList.remove('requesting');
- if (request.status == 200) {
- var response = JSON.parse(request.responseText);
- for (var i = 0; i < response.length; i++) {
- var element;
- if (response[i].selector) {
- element = form.querySelector(response[i].selector);
- }
- if (response[i].globalSelector) {
- element = document.querySelector(response[i].globalSelector);
- }
+ var errorField = document.querySelector('.input-field.has-error input, .input-field.has-error textarea');
+ if (errorField) {
+ errorField.focus();
+ }
+
+ window.initNodeFunctions = [ function(node) {
+ forEachElement('.number-field,.email-field,.text-field,.password-field,.search-field', function(field) {
+ var input = field.querySelector('input');
+ var positionLabel = function(input) {
+ field.classList[input.value ? 'remove' : 'add']('empty');
+ }
+ positionLabel(input);
+ input.addEventListener('keyup', function(event) {
+ positionLabel(event.target);
+ });
+ input.addEventListener('blur', function(event) {
+ positionLabel(event.target);
+ field.classList.remove('focused');
+ });
+ input.addEventListener('focus', function(event) {
+ field.classList.add('focused');
+ });
+ }, node || document);
+ forEachElement('form.js-xhr', function(form) {
+ if (form.addEventListener) {
+ form.addEventListener('submit', function(event) {
+ event.preventDefault();
+ form.classList.add('requesting');
+ var data = new FormData(form);
+ var request = new XMLHttpRequest();
+ request.onreadystatechange = function() {
+ if (request.readyState == 4) {
+ form.classList.remove('requesting');
+ if (request.status == 200) {
+ var response = JSON.parse(request.responseText);
+ for (var i = 0; i < response.length; i++) {
+ var element;
+ if (response[i].selector) {
+ element = form.querySelector(response[i].selector);
+ }
+ if (response[i].globalSelector) {
+ element = document.querySelector(response[i].globalSelector);
+ }
- if (response[i].html) {
- element.innerHTML = response[i].html;
- window.initNode(element);
- }
- if (response[i].className) {
- element.className = response[i].className;
- }
- }
- }
- }
- }
- request.open('POST', form.getAttribute('action'), true);
- request.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
- request.send(data);
- }, false);
- }
- }, node || document);
- forEachElement('[data-opens]', function(control) {
- control.addEventListener('click', function(event) {
- var opens = document.querySelector(control.getAttribute('data-opens'));
- if (!opens.classList.contains('open')){
- event.preventDefault();
- opens.className += ' open';
- if (control.getAttribute('data-focus')) {
- var input = opens.querySelector(control.getAttribute('data-focus'));
- if (input) {
- input.focus();
- }
- }
- return false;
- }
- });
- });
- } ];
- window.initNode = function(node) {
- forEach(initNodeFunctions, function(fn) {
- fn(node);
- });
- };
- initNode();
- document.addEventListener('DOMContentLoaded', function() {
- var errors = document.getElementsByClassName('has-error');
- if (errors.length <= 0) {
- errors = document.getElementsByClassName('info-message');
- }
-
- if (errors.length > 0) {
- errors[0].scrollIntoView();
- }
- });
+ if (response[i].html) {
+ element.innerHTML = response[i].html;
+ window.initNode(element);
+ }
+ if (response[i].className) {
+ element.className = response[i].className;
+ }
+ }
+ }
+ }
+ }
+ request.open('POST', form.getAttribute('action'), true);
+ request.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
+ request.send(data);
+ }, false);
+ }
+ }, node || document);
+ forEachElement('[data-opens]', function(control) {
+ control.addEventListener('click', function(event) {
+ var opens = document.querySelector(control.getAttribute('data-opens'));
+ if (!opens.classList.contains('open')){
+ event.preventDefault();
+ opens.className += ' open';
+ if (control.getAttribute('data-focus')) {
+ var input = opens.querySelector(control.getAttribute('data-focus'));
+ if (input) {
+ input.focus();
+ }
+ }
+ return false;
+ }
+ });
+ });
+ } ];
+ window.initNode = function(node) {
+ forEach(initNodeFunctions, function(fn) {
+ fn(node);
+ });
+ };
+ initNode();
+ document.addEventListener('DOMContentLoaded', function() {
+ var errors = document.getElementsByClassName('has-error');
+ if (errors.length <= 0) {
+ errors = document.getElementsByClassName('info-message');
+ }
+
+ if (errors.length > 0) {
+ errors[0].scrollIntoView();
+ }
+ });
})();
+function generateScreenshot() {
+ var css = '';
+ var svgs = document.getElementsByTagName('svg');
+ for (var i = 0; i < document.styleSheets.length; i++) {
+ if (document.styleSheets[i].href && !document.styleSheets[i].href.match(/web\-fonts/)) {
+ var rules = document.styleSheets[i].rules || document.styleSheets[i].cssRules;
+ for (var j = 0; j < rules.length; j++) {
+ cssText = rules[j].cssText;
+ if (rules[j].selectorText) {
+ if (rules[j].selectorText.match(/(^|\s)svg[^\w]/) || cssText.match(/\s(fill|stroke(\-width)?):/)) {
+ css += cssText;
+ }
+ }
+ }
+ }
+ }
+ for (var i = 0; i < svgs.length; i++) {
+ var svg = svgs[i];
+ // svg.innerHTML = '' + svg.innerHTML;
+ svg.innerHTML = '' + svg.innerHTML;
+ svg.setAttribute('height', svg.clientHeight);
+ svg.setAttribute('width', svg.clientWidth);
+ var canvas = document.createElement('canvas');
+ canvg(canvas, svg.outerHTML);
+ console.log(svg.outerHTML);
+ svg.style.backgroundImage = 'url(' + encodeURI(canvas.toDataURL('image/png')) + ')';
+ }
+
+ html2canvas(document.body, {
+ logging: true,
+ profile: true,
+ useCORS: true}).then(function(canvas) {
+ var data = canvas.toDataURL('image/jpeg', 0.9);
+ var src = encodeURI(data);
+
+ window.open(src, '_blank');
+
+ // reset the svg height and width
+ for (var i = 0; i < svgs.length; i++) {
+ var svg = svgs[i];
+ svg.removeAttribute('height');
+ svg.removeAttribute('width');
+ svg.removeAttribute('style');
+ }
+ });
+}
diff --git a/app/assets/stylesheets/_application.scss b/app/assets/stylesheets/_application.scss
index 4cf5e58..68cb909 100644
--- a/app/assets/stylesheets/_application.scss
+++ b/app/assets/stylesheets/_application.scss
@@ -12,6 +12,7 @@ html, body {
}
body {
+ background-color: $white;
padding-bottom: 20vw;
}
@@ -1807,6 +1808,7 @@ ul.warnings {
a {
color: inherit;
padding: 0 0.333em;
+ display: inline-block;
&:hover {
@include after {
@@ -2946,6 +2948,9 @@ a.logo {
.conference-banner {
text-align: center;
+ padding: 0;
+ margin: 0 -1em 2em;
+ width: auto;
.title {
font-size: 5vw;
@@ -2964,6 +2969,10 @@ a.logo {
font-size: 0.85em;
line-height: 2em;
}
+
+ img {
+ max-width: 100%;
+ }
}
.conference-details {
@@ -4653,15 +4662,6 @@ html[data-ontop] {
}
}
}
-
- // .nav a.register, .nav button {
- // @include before-and-after {
- // background-color: $colour-2;
- // }
- // &:focus, &:active {
- // @include _(transform, none);
- // }
- // }
}
#banner {
@@ -4674,6 +4674,9 @@ html[data-ontop] {
}
.conference-banner {
+ margin: 0 auto;
+ width: 100%;
+
.title {
font-size: 1.9em;
margin: 0 0 1em;
diff --git a/app/assets/stylesheets/bumbleberry-settings.json b/app/assets/stylesheets/bumbleberry-settings.json
index b434909..c0dab74 100644
--- a/app/assets/stylesheets/bumbleberry-settings.json
+++ b/app/assets/stylesheets/bumbleberry-settings.json
@@ -8,7 +8,7 @@
"and_chr": ["54"],
"chrome": ["54"],
"edge": ["13"],
- "firefox": ["44"],
+ "firefox": ["48"],
"ie": ["11"],
"ios_saf": ["8", "9"]
}
diff --git a/app/models/city.rb b/app/models/city.rb
index d18d47b..154f004 100644
--- a/app/models/city.rb
+++ b/app/models/city.rb
@@ -18,19 +18,30 @@ class City < ActiveRecord::Base
def get_translation(locale)
location = Geocoder.search(address, language: locale.to_s).first
+ # if the service lets us down, return nil
+ return nil unless location.present?
+
+ searched_component = false
location.data['address_components'].each do | component |
- # city is usually labelled a 'locality' but sometimes this is missing and only 'colloquial_area' is present
- if component['types'].first == 'locality' || component['types'].first == 'colloquial_area'
+ # city is usually labeled a 'locality' but sometimes this is missing and only 'colloquial_area' is present
+ if component['types'].first == 'locality'
return component['short_name']
end
+
+ if component['types'] == location.data['types']
+ searched_component = component['short_name']
+ end
end
- return nil
+ # return the type we searched for but it's still possible that it will be false
+ searched_component
end
+ # this method will get called automatically if a translation is asked for but not found
def translate_city(locale)
translation = get_translation(locale)
+ # if we found it, set it
if translation.present?
set_column_for_locale(:city, locale, translation)
save!
@@ -48,16 +59,20 @@ class City < ActiveRecord::Base
# look up the city in the geocoder
location = Geocoder.search(str, language: 'en').first
+ # return nil to indicate that the service is down
+ return nil unless location.present?
# see if the city is already present in our database
city = City.find_by_place_id(location.data['place_id'])
# return the city if we found it in the db already
- return city if city.present?
+ if city.present?
+ CityCache.create(city_id: city.id, search: str)
+ return city
+ end
# otherwise build a new city
component_alises = {
'locality' => :city,
- 'colloquial_area' => :city,
'administrative_area_level_1' => :territory,
'country' => :country
}
@@ -67,15 +82,61 @@ class City < ActiveRecord::Base
longitude: location.data['geometry']['location']['lng'],
place_id: location.data['place_id']
}
+
+ # these things are definitely not cities, make sure we don't think they're one
+ not_a_city = [
+ 'administrative_area_level_1',
+ 'country',
+ 'street_address',
+ 'street_number',
+ 'postal_code',
+ 'postal_code_prefix',
+ 'route',
+ 'intersection',
+ 'premise',
+ 'subpremise',
+ 'natural_feature',
+ 'airport',
+ 'park',
+ 'point_of_interest',
+ 'bus_station',
+ 'train_station',
+ 'transit_station',
+ 'room',
+ 'post_box',
+ 'parking',
+ 'establishment',
+ 'floor'
+ ]
+
+ searched_component = nil
location.data['address_components'].each do | component |
property = component_alises[component['types'].first]
city_data[property] = component['short_name'] if property.present?
+
+ # ideally we will find the component that is labeled a locality but
+ # if that fails we will select what was searched for, hopefully they searched for a city
+ # and not an address or country
+ # some places are not labeled 'locality', search for 'Halifax NS' for example and you will
+ # get 'administrative_area_level_2' since Halifax is a municipality
+ if component['types'] == location.data['types'] && not_a_city.include?(component['types'].first)
+ searched_component = component['short_name']
+ end
end
+ # fall back to the searched component
+ city_data[:city] ||= searched_component
+
+ # we need to have the city and country at least
+ return false unless city_data[:city].present? && city_data[:country].present?
+
# save the new city
city = City.new(city_data)
city.save!
+ # save this to our cache
+ CityCache.create(city_id: city.id, search: str)
+
# and return it
return city
end
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index f1d5a0f..a06b9c0 100644
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -20,6 +20,8 @@
%meta{property: 'og:image', content: og_image}
%meta{name: "theme-color", content: @theme_colour}
= yield :head
+ = javascript_include_tag 'https://rawgit.com/niklasvh/html2canvas/master/dist/html2canvas.js'
+ = javascript_include_tag 'https://cdnjs.cloudflare.com/ajax/libs/amcharts/3.13.0/exporting/canvg.js'
%body{ class: page_style }
#primary-content
diff --git a/config/initializers/geocoder.rb b/config/initializers/geocoder.rb
index 49e4b0a..b34ca4a 100644
--- a/config/initializers/geocoder.rb
+++ b/config/initializers/geocoder.rb
@@ -1,21 +1,24 @@
# config/initializers/geocoder.rb
-Geocoder.configure(
+config = {
# geocoding service (see below for supported options):
- :lookup => :google,
+ lookup: :google,
# IP address geocoding service (see below for supported options):
- :ip_lookup => :freegeoip,
+ ip_lookup: :freegeoip,
# to use an API key:
- # :api_key => "AIzaSyDitM1lyVWkrumteDvSkje6GiIKYyHlAXM",
# geocoding service request timeout, in seconds (default 3):
- :timeout => 5,
+ timeout: 5,
# set default units to kilometers:
- :units => :km,
+ units: :km
+}
- # caching (see below for details):
- #:cache => Redis.new,
- #:cache_prefix => "..."
-)
+# use our api key on the server
+if Rails.env.preview? || Rails.env.production?
+ config[:api_key] = "AIzaSyDurfjX9f_NgYsJLyUuGqwdKuI745CE_OE"
+ config[:use_https] = true
+end
+
+Geocoder.configure(config)