Skip to content

Commit

Permalink
Merge pull request #43 from martinleopold/master
Browse files Browse the repository at this point in the history
Updates from this week
martinleopold committed Nov 15, 2013
2 parents 3398f3b + e63a6e1 commit 272b860
Showing 13 changed files with 458 additions and 237 deletions.
4 changes: 1 addition & 3 deletions app-base/application.js
Original file line number Diff line number Diff line change
@@ -47,9 +47,7 @@ var loadUserSets = function loadUserSets ( user_id, next ) {
//next.apply(null,arguments);
showError('Error loading sets' + (textStatus ? ': ' + textStatus + ' (' + jqXHR.status + ')' : '') );
},
complete: function() {
console.log(arguments);
}
timeout: 10000
});
}

72 changes: 57 additions & 15 deletions app-base/controllers/set-controller.js
Original file line number Diff line number Diff line change
@@ -3,29 +3,71 @@ var Controller = require('controllers/base/controller'),
SetModel = require('models/set-model'),
ErrorView = require('views/error-view');

var current_opts = prev_opts = {}; // hack this sh*t

module.exports = Controller.extend({

show : function ( opts ) {

this.model = new SetModel();
// console.log("set#show", opts.setid, opts.cellid);

prev_opts = current_opts;
current_opts = opts;

this.compose('set', {
compose : function() {
// console.log("composing");

// create set model
this.model = new SetModel();

// create set view
this.view = new SetView({
region: 'content',
model: this.model
});

this.model.fetch({
id : opts.setid,

error : function(model, response, options) {
//Chaplin.helpers.redirectTo('error#show', {message: 'Error message'}); // use this to redirect to an error page (changes url)
new ErrorView( {message : 'Couldn\'t get the set you requested. (' + response.status + ')'} );
}
});

this.model.synced(function(){
this.view.render();

this.model.fetch({
id : opts.setid,
// scroll (jump) to cellid
_(function() {
if (current_opts.cellid) {
this.model.collectionView.scrollToCell(current_opts.cellid, 0);
}
}).bind(this).defer();
}, this);
},

error : function(model, response, options) {
//Chaplin.helpers.redirectTo('error#show', {message: 'Error message'}); // use this to redirect to an error page (changes url)
new ErrorView( {message : 'Couldn\'t get the set you requested. (' + response.status + ')'} );
check : function() {
// differnet set -> reload
if ( current_opts.setid != prev_opts.setid ) {
return false; //rerun compose()
}

// same set, but removed cell id -> reload
if ( current_opts.cellid == undefined && current_opts.setid == prev_opts.setid ) {
return false; //rerun compose()
}

// same set, cell id given -> scroll to cell
if (current_opts.cellid) {
this.model.collectionView.scrollToCell(current_opts.cellid, 0);
}

return true; // don't rerun compose()
}
});

this.model.synced(function(){
setView.render();
});

var setView = this.view = new SetView({
region: 'content',
model: this.model
});

}

});
6 changes: 3 additions & 3 deletions app-base/css/11-app.css
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#app-background {
/*background-image: url('http://motionbank-media.s3.amazonaws.com/dh/app/imgs/backs/background-1.jpg');*/
background: -webkit-radial-gradient(45px 45px, cover, #666 0%, #222 100%);
background: -moz-radial-gradient(45px 45px, cover, #666 0%, #222 100%);
background: radial-gradient(45px 45px, cover, #666 0%, #222 100%);
background: -webkit-radial-gradient(45px 45px, cover, #3b4241 0%, #1d2121 100%);
background: -moz-radial-gradient(45px 45px, cover, #3b4241 0%, #1d2121 100%);
background: radial-gradient(45px 45px, cover, #3b4241 0%, #1d2121 100%);
background-size: cover;
-webkit-background-size: cover;
-moz-background-size: cover;
10 changes: 10 additions & 0 deletions app-base/css/34-cell.css
Original file line number Diff line number Diff line change
@@ -228,3 +228,13 @@
.cell-collection .cell.type-text .info {
display: none;
}*/
.cell .loading { color:white; position:absolute; top:0;left:0;bottom:0;right:0; font-size:200%; text-align:center; vertical-align: middle; line-height:100%;}
.cell .loading span { display:inline-block; margin-top:30%; }
.cell .loading span:after { content:'•'; }
.cell .loading .dot1 { -webkit-animation: fadeOut 0.7s 0.00s infinite alternate; animation: fadeOut 0.7s 0.00s infinite alternate; }
.cell .loading .dot2 { -webkit-animation: fadeOut 0.7s 0.35s infinite alternate; animation: fadeOut 0.7s 0.35s infinite alternate; }
.cell .loading .dot3 { -webkit-animation: fadeOut 0.7s 0.70s infinite alternate; animation: fadeOut 0.7s 0.70s infinite alternate; }
@-webkit-keyframes fadeOut { from {opacity:1;} to {opacity:0;} }
@keyframes fadeOut { from {opacity:1;} to {opacity:0;} }
.cell .content { position:relative; } /* so .loading doesn't overlay it */

15 changes: 10 additions & 5 deletions app-base/models/cell-model.js
Original file line number Diff line number Diff line change
@@ -19,6 +19,7 @@ module.exports = BaseModel.extend({

modeltype : 'cell',

// attributes that can't be overwritten in fields
lockedAttributes : {
type : null,
sets : null,
@@ -29,13 +30,17 @@ module.exports = BaseModel.extend({
},

// check if this cell has the sticky flag set
// TODO: using fields is not necessary. just use this.attributes.sticky with RegEx.test
isSticky : function() {
return _.any(this.attributes.fields, function(field) {
return ( field.name === 'sticky' && (field.value === 'true' || field.value === '1') );
});
// TODO: just use getFlag('sticky') instead
isSticky : function () {
return this.getFlag('sticky');
},

// checks if an attribute is present and either 'true' or '1'
getFlag : function (flag) {
return /true|1/i.test(this.get(flag));
},

// sets attributes and applies overrides set via fields
set : function ( opts ) {
// override some attributes per set<->cell connection
if ( opts && typeof opts === 'object' && 'fields' in opts ) {
8 changes: 5 additions & 3 deletions app-base/routes.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
module.exports = function(match) {

match( 'set/:setid', 'set#show' );
match( 'set/:setid/', 'set#show' );
match( 'set/:setid/:cellid', 'set#show' );
match( 'set/:setid/:cellid/', 'set#show' );

match( 'set/:setid', 'set#show'
//,{ constraints: { setid: /^\d+$/ }}
);
match( '', 'cover#index' );

// match( 'error', 'error#show' ); // to test and error page (to redirect to)
11 changes: 11 additions & 0 deletions app-base/views/cell-collection-view.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* cell-collection-view.js */
var CellDefaultView = require('views/cell-view'),
BaseCollectionView = require('views/base/collection-view'),
mediator = require('mediator'),
@@ -21,6 +22,7 @@ module.exports = BaseCollectionView.extend({
},

render : function () {
console.log("rendering cell collection");
BaseCollectionView.prototype.render.apply(this,arguments);
// after rendring is finished attach scroll listener
_(function(){
@@ -54,6 +56,15 @@ module.exports = BaseCollectionView.extend({
}

return cellView;
},

// scroll to a cell
scrollToCell : function (cellid, time) {
if (cellid == undefined) return;
var cellView = _.find(this.subviews, function(cellView) {
return cellView.model.id == cellid;
});
if (cellView) cellView.scrollTo(time);
}

});
277 changes: 168 additions & 109 deletions app-base/views/cell-types/cell-iframe-view.js
Original file line number Diff line number Diff line change
@@ -1,83 +1,72 @@
/* cell-iframe-view.js */
var CellDefaultView = require('views/cell-view'),
config = require('config/config'),
pm = require('postmessenger'),
hasher = require('hasher');

module.exports = CellDefaultView.extend({
// attributes governing how a cell behaves in the view
// cell types have default values. can be overridden via fields
// these are the defaults use by most cell types
defaultViewAttributes : {
autoload : 1, // open on scroll in?
sticky : 0, // don't close on scroll out?
solo: 0 // close other cells on open?
},

// events : {
// 'click' : function () {
// this.renderContent();
// }
// },

// keep this in sync with cell-vimeo!
render : function () {
events : {
'click' : function () {
// console.log("click");
if ( !this.isOpen() ) {
this.open();
}
}
},

CellDefaultView.prototype.render.apply(this,arguments);
loadState : "closed",

if ( this.model.attributes['autoload'] &&
/^(1|true)$/i.test(this.model.attributes['autoload']) ) {
this.renderContent();
}
isOpen : function() {
return this.loadState.toLowerCase() == "open";
},

return this;
isClosed : function() {
return this.loadState.toLowerCase() == "closed";
},

renderContent : function () {
// load iframe from data-src
$('iframe',this.$el).attr('src',$('iframe',this.$el).data('src'));

// connect to iframe with postmessenger
_(function(){

var view = this;
var iframe = $('iframe',this.$el);

iframe.load(function() {
// show content, hide info
$('.element-hidden',view.$el).removeClass('element-hidden');
$('.info',view.$el).addClass('element-hidden');

view.$iframe = $(this);
// if iframe on another domain add that to the accept list
var src = view.model.get('iframe-src');
if ( /^http[s]?:\/\/.+/.test(src) ) {
var iframe_domain = (function(){
var p = src.split('/');
return p[0]+'//'+p[2];
})();
pm.accept(iframe_domain);
}

// connect it
pm.send(
'connect?',
{ listener_id: hasher.generate(20) },
this.contentWindow,
iframe_domain
);
});

}).bind(this).defer();
isLoading : function() {
return this.loadState.toLowerCase() == "loading";
},

this.$el.css({
'background-image' : 'none'
initialize : function () {
CellDefaultView.prototype.initialize.apply(this,arguments);
// fill in missing view attributs with defaults
_.defaults(this.model.attributes, this.defaultViewAttributes);

// listen for solo event. close if in same solo group
this.subscribeEvent('!solo', function(args) {
// console.log("solo ");
// console.log(args);
// skip if we sent that event
if ( args.origin == this ) { return; }
if ( args.group == this.model.get('solo') ) {
// close if open or loading
if (!this.isClosed()) this.close();
}
});
},

getTemplateData : function () {
var data = CellDefaultView.prototype.getTemplateData.apply(this,arguments);

if ( Handlebars.compile && data['iframe-src'] ) {
data['iframe-src'] = Handlebars.compile(data['iframe-src'])(config);
}
var spl = data['iframe-src'].split('?');
data['iframe-src'] = spl[0] + '?' + 'domain=http://' + config.host + '&' + (spl[1] || '');
// if ( false === /^http[s]:\/\/.+/.test(data['iframe-src']) ) {
// data['iframe-src'] = 'http://' + config.host + config.baseUrl + data['iframe-src'];
// }
if ( data['iframe-src'] ) {
var spl = data['iframe-src'].split('?');
data['iframe-src'] = spl[0] + '?' + 'domain=http://' + config.host + '&' + (spl[1] || '');
}

// collect attributes for <iframe>
// collect extra attributes for <iframe>
data.attr = {};
_.each(data.fields, function(element, index, list) {
if (element.name.substr(0,5) == 'attr-') {
@@ -88,66 +77,136 @@ module.exports = CellDefaultView.extend({

return data;
},

listen : {
// listen to changes of the active property
'change:focused model' : function(model, focused, options) {
if (focused) {
this.activate();
this.renderContent();
} else {
if (!model.isSticky()) this.deactivate();
}

render : function () {
CellDefaultView.prototype.render.apply(this,arguments);

// when rendering is finished, meaning the <iframe> exists, connect postmessenger
_(this.connectPM).bind(this).defer();

return this;
},

// render content
open : function () {
console.log("open " + this.cellInfo());
this.loadState = "loading";

// show loading animation
this.showLoadingAnimation();

// load iframe from data-src
var $iframe = $('iframe',this.$el);
var that = this;
$iframe.one('load.open', function() { that.loadState = "open"; }); // once loaded, set isOpen flag
$iframe.attr( 'src', $iframe.data('src') );

$('.content',this.$el).removeClass('element-hidden');
$('.info',this.$el).addClass('element-hidden');
this.$el.css( 'background-image', 'none' );

// handle solo
// console.log("solo " + this.model.get('solo'));
if ( this.model.getFlag('solo') ) {
var soloGroup = this.model.get('solo');
// console.log('publish solo ' + soloGroup);
this.publishEvent('!solo', { group : soloGroup, origin : this });
}
},

activate : function () {
if ( !this.active ) {
console.log("activate iframe: " + this.cid);

this.active = true; // needs to be before render(). why? don't know...

if ( !this.model.isSticky() ) {
this.render();
} else {
if (!this.rendered) {
this.render();
var iframe = $('iframe', this.$el)[0];
var that = this;
$(iframe).one('load', function(){
pm.send(that.active ? 'activate!' : 'deactivate!', {}, this.contentWindow );
that.rendered = true;
});
} else {
var iframe = $('iframe', this.$el)[0];
pm.send( 'activate!', {}, iframe.contentWindow );
}}
// remove content
close : function () {
console.log("close " + this.cellInfo());
// debugger;
this.$el.css( 'background-image', 'url('+this.model.getPosterImageURL()+')' ); // show poster image
$('.info',this.$el).removeClass('element-hidden'); // show info
$('.content',this.$el).addClass('element-hidden'); // hide content

var $iframe = $('iframe',this.$el);
$iframe.off('.open'); // don't set isOpen anymore, if pending
$iframe.attr( 'src', '');

this.loadState = "closed";
},

// called when scrolled into view
activate : function () {
// console.log( "activate " + this.model.get('type') + this.model.get('connection_id') );
if ( this.model.getFlag('autoload') && !this.isOpen() ) {
this.open();
}

if ( this.model.getFlag('sticky') && this.isOpen() ) {
// console.log("sending activate");
this.sendPM('activate!');
}
},

// called when scrolled out of view
deactivate : function () {
if ( this.active ) {
if (!this.model.isSticky()) {
console.log("deactivate iframe: " + this.cid);
console.log(this);
//this.$el.empty();
// remove content and show info again
$('.content', this.$el).remove();
$('.info', this.$el).removeClass('element-hidden');

this.$el.css({
'background-image': 'url('+this.model.getPosterImageURL()+')'
});

this.rendered = false;
} else {
var iframe = $('iframe', this.$el)[0];
if (iframe) {
pm.send('deactivate!', {}, iframe.contentWindow );
}
// console.log( "deactivate " + this.model.get('type') + this.model.get('connection_id') );
if ( !this.model.getFlag('sticky') ) {
this.close();
}

if ( this.model.getFlag('sticky') && this.isOpen() ) {
// console.log("sending deactivate");
this.sendPM('deactivate!');
}
},

showLoadingAnimation : function () {
$('.loading', this.$el).show(0);
var that = this;
$('iframe', this.$el).one('load', function() {
$('.loading', that.$el).hide(0);
});
},

// connect postmessenger to iframe
// remains on the iframe and reconnects on load, so only call this once
connectPM : function () {
// console.log("connectPM " + this.cellInfo());

var that = this;
$('iframe', this.$el).on('load', function() {
// load event is also fired on close, when src is set to "". skip this.
if (!this.src) {
// console.log("src not valid: " + this.src);
return;
}
this.active = false;

// if iframe on another domain add that to the accept list
var src = that.model.get('iframe-src');
if ( /^http[s]?:\/\/.+/.test(src) ) {
var iframe_domain = (function(){
var p = src.split('/');
return p[0]+'//'+p[2];
})();
pm.accept(iframe_domain);
}
// connect it
pm.send(
'connect?',
{ listener_id: hasher.generate(20) },
this.contentWindow,
iframe_domain
);
});
},

sendPM : function (msg, opts) {
var iframe = $('iframe', this.$el)[0];
if (opts == undefined) { opts = {}; }

if (this.isOpen()) {
// console.log("sending " + msg);
pm.send(msg, opts, iframe.contentWindow );
} else { // wait till iframe is loaded to send message
$(iframe).one('load', function() {
// console.log("late sending " + msg);
pm.send(msg, opts, this.contentWindow );
});
}
}
});
78 changes: 76 additions & 2 deletions app-base/views/cell-types/cell-vimeo-view.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,90 @@
var CellIFrameView = require('views/cell-types/cell-iframe-view');
/* cell-vimeo-view.js */
var CellIFrameView = require('views/cell-types/cell-iframe-view'),
pm = require('postmessenger');

module.exports = CellIFrameView.extend({
// attributes governing how a cell behaves in the view
// cell types have default values. can be overridden via fields
// these are the defaults use by most cell types
defaultViewAttributes : {
autoload : 0, // open on scroll in?
sticky : 0, // don't close on scroll out?
solo: 1, // close other cells on open?
autoplay : 1
},

initialize : function ( opts ) {

CellIFrameView.prototype.initialize.apply(this,arguments);

var loop = this.model.attributes['loop'] && /^true|1$/i.test(this.model.attributes['loop']);
var autoplay = this.model.attributes['autoplay'] && /^true|1$/i.test(this.model.attributes['autoplay']);
this.model.set( 'iframe-src','http://player.vimeo.com/video/' + this.model.get('vimeo-id') + '?autoplay=' + (autoplay ? 1 : 0) + '&loop=' + (loop ? 1 : 0) );

this.template = require('views/templates/cell-types/cell-iframe');

this.subscribeEvent('!open', function(args) {
if ( args.origin == this ) { return; }
//console.log("open received for: " + args.cellid);
if ( args.cellid == this.model.get('connection_id') ) { this.scrollTo(); this.open(); }
});
},

// overridden
connectPM : function () {
// console.log("connectPM " + this.cellInfo());
var that = this;

pm.accept( 'http://player.vimeo.com' );
// pm.on({
// matcher: /.+/,
// callback: function ( request, response ) {
// var iframe = $('iframe', that.$el)[0];
// // check source window
// if (iframe.contentWindow == request.source) {
// console.log(that.cellInfo() + ' received: ', request.name );
// //console.log(iframe);
// }
// },
// nameAlias: 'event'
// });

pm.on({
matcher: 'finish',
callback: function ( request, response ) {
var iframe = $('iframe', that.$el)[0];
// check source window
if (iframe.contentWindow == request.source) {
console.log(that.cellInfo() + ' received: ', request.name );
//console.log(iframe);
var onfinish = that.model.get('on-finish');
if (onfinish) {
var random = _.sample( onfinish.split('/') );
that.publishEvent('!open', {cellid : random, origin : that});
}
}
},
nameAlias: 'event'
});

var that = this;
$('iframe', this.$el).on('load', function() {
// load event is also fired on close, when src is set to "". skip this.
if (!this.src) {
// console.log("src not valid: " + this.src);
return;
}
// request finish events from player
pm.send({
name: 'addEventListener', data: 'finish',
receiver: this.contentWindow, receiverOrigin: 'http://player.vimeo.com',
nameAlias: 'method', dataAlias: 'value'
});

});
},

sendPM : function (msg, opts) {
// no op
}

});
80 changes: 50 additions & 30 deletions app-base/views/cell-view.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* cell-view.js */
BaseView = require('views/base/view');

// see ```views/cell-types``` for per cell type views
@@ -11,7 +12,6 @@ module.exports = BaseView.extend({
},

initialize : function ( opts ) {

BaseView.prototype.initialize.apply(this,arguments);

try {
@@ -29,7 +29,7 @@ module.exports = BaseView.extend({
template : require('views/templates/cell'),

// always on for now, see setActive / setInactive and render
active : false,
// active : false,

getTemplateData : function () {
var data = _.extend({},this.model.attributes);
@@ -38,41 +38,61 @@ module.exports = BaseView.extend({
},

render : function () {

if ( this.active ) {
BaseView.prototype.render.apply(this,arguments);

this.$el.addClass( 'type-' + this.model.get('type') );
this.$el.addClass( this.cid ); // add view id as class (viewXX) to make debugging easier

// use cell fields that start with "css-" as css attributes on the $el
var cssOpts = {
'background-image': 'url('+this.model.getPosterImageURL()+')'
};
attribs = {};
_.filter(this.model.attributes.fields,function(f){
return /^css-/i.test(f.name);
}).map(function(f){
attribs[f.name.replace(/^css-/i,'')] = f.value;
});
cssOpts = _.extend(cssOpts,attribs);
this.$el.css(cssOpts);
}
//console.log("rendering " + this.cellInfo());
// if ( this.active ) {
BaseView.prototype.render.apply(this,arguments);

// add classes (cell type, cell id)
this.$el.addClass( 'type-' + this.model.get('type') );
this.$el.addClass( 'cellid-' + this.model.get('connection_id') ); // add view id as class (viewXX) to make debugging easier
this.$el.data('cellid', this.model.get('connection_id'));

// add css from "css-"-fields
var cssOpts = {
'background-image': 'url('+this.model.getPosterImageURL()+')'
};
attribs = {};
_.filter(this.model.attributes.fields,function(f){
return /^css-/i.test(f.name);
}).map(function(f){
attribs[f.name.replace(/^css-/i,'')] = f.value;
});
cssOpts = _.extend(cssOpts,attribs);
this.$el.css(cssOpts);
// }

return this;
},

// get a string made up of cell type + id
cellInfo : function () {
return this.model.get('type') + this.model.get('connection_id');
},

// called when scrolled into view
activate : function () {
if ( !this.active ) {
this.active = true;
this.render();
}
// console.log("activate: " + this.cid);
// console.log( "activate " + this.model.get('type') + this.model.get('connection_id') );
},

// called when scrolled out of view
deactivate : function () {
this.active = false;
this.$el.empty();
// console.log("deactivate: " + this.cid);
// console.log( "deactivate " + this.model.get('type') + this.model.get('connection_id') );
},

// smoothly scroll to this cell
scrollTo : function(time) {
console.log("scrolling to " + this.cellInfo());
//$('#set .cell-collection-container').scrollLeft(this.$el.position().left); // jump
//$('#set .cell-collection-container').animate( {scrollLeft : this.$el.position().left}, 1500 ); // smoother

if (time == undefined) time = 1500;

var $viewport = $('#set .cell-collection-container');
if ( this.$el.offset().left + this.$el.width() > $viewport.width()
|| this.$el.offset().left < 0 ) { // if not fully in view
var destLeft = this.$el.position().left - ($viewport.width() - this.$el.width()) / 2;
//$viewport.scrollLeft( destLeft ); //jump
$viewport.animate( {scrollLeft : destLeft}, time ); // smooth
}
}
});
120 changes: 60 additions & 60 deletions app-base/views/set-view.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* set-view.js */
var View = require('views/base/view');

module.exports = View.extend({
@@ -7,7 +8,7 @@ module.exports = View.extend({

this.subscribeEvent('set:scrolled',function(val){
this.layoutAttributes.position = val;
this.updateVisibleCells();
this.updateCellVisibility();
});

this.subscribeEvent('window:resized',function(){
@@ -24,41 +25,42 @@ module.exports = View.extend({
template: require('views/templates/set'),

layoutAttributes : {
position : 0.0,
visible_x : 0,
visible_y : 0,
width : -1,
height : -1,
cell_width : 0,
cell_height : 0
position : 0.0, // scroll position in set [0,1]
visible_x : 0, // #cells that fit in one screen horizontally
visible_y : 0, // #cells that fit in one screen vertically
width : -1, // set width in px
height : -1, // set height in px
cell_width : 0, // cell width in px
cell_height : 0 // cell height in px
},

render : function () {

// console.log("rendering set");
View.prototype.render.apply(this,arguments);

this.layoutAttributes.position = 0.0;

this.model.collectionView.render();

// call updateCellGrid() after render finished (for it to have width, height avail)
_(function(){
this.updateCellGrid();
this.updateVisibleCells();
this.establishCellGrid();
this.updateCellVisibility();
}).bind(this).defer();

return this;
},

updateLayoutSize : function () {
this.layoutAttributes.width = this.$el.width();
this.layoutAttributes.height = this.$el.height();
},

// re-calculate layout attributes: set dimensions, grid dimensions (on resize)
updateCellGrid : function () {
// console.log("updateCellGrid");

var layAttrs = this.layoutAttributes;

this.updateLayoutSize();
// update layout size
layAttrs.width = this.$el.width();
layAttrs.height = this.$el.height();

var cell_height = parseInt( Math.floor( layAttrs.height / this.model.get('grid_rows') ) );
var cell_width = (this.model.get('cell_width') / this.model.get('cell_height')) * cell_height;
@@ -78,68 +80,66 @@ module.exports = View.extend({
layAttrs.cell_width = cell_width;
layAttrs.cell_height = cell_height;

//console.log( this.layoutAttributes );
// add media-query style classes to cells
_.each( this.model.collectionView.getItemViews(), function( cellView ) {
var cellDim = cellView.model.get('extra');
cellView.$el.attr( 'class', cellView.$el.attr('class').replace(/ cell-(width|height)-[0-9]+/ig,'') );
// console.log('cell-width-'+ (parseInt((layAttrs.cell_width*cellDim.width) /50)*50));
cellView.$el.addClass( 'cell-width-'+ (parseInt((layAttrs.cell_width*cellDim.width) /50)*50) );
cellView.$el.addClass( 'cell-height-'+(parseInt((layAttrs.cell_height*cellDim.height)/50)*50) );
});
},

updateVisibleCells : function () {
// establish css cell positions and dimensions (once)
establishCellGrid : function () {
// console.log("establishCellGrid");

var gridWidth = this.model.get('grid_cols');
var xFrom = Math.round( this.layoutAttributes.position * (gridWidth - this.layoutAttributes.visible_x) );

var cw = 100.0/gridWidth;
var ch = 100.0/this.layoutAttributes.visible_y;
var cw = 100.0/gridWidth; // cell width (% of set)
var ch = 100.0/this.layoutAttributes.visible_y; // cell height (% of set)

var absCw = (1.0*this.layoutAttributes.width) /this.layoutAttributes.visible_x,
absCh = (1.0*this.layoutAttributes.height)/this.layoutAttributes.visible_y;
_.each( this.model.collectionView.getItemViews(), function( cellView ) {
var cellDim = cellView.model.get('extra');

// TODO: clean this mess
_.each( this.model.collectionView.getItemViews(),
(function(layAttrs){ return function( cellView, cid ) {
var left = cw * cellDim.x;
var width = cw * cellDim.width;

var cellDim = cellView.model.get('extra');
cellView.$el.css({
left: left+'%',
top: (ch*cellDim.y)+'%',
width: width+'%',
height: (ch*cellDim.height)+'%'
});
});
},

cellView.$el.removeClass('lastcol').removeClass('lastrow');
// send activation / deactivation to cells (on scroll)
updateCellVisibility : function () {
// console.log("updateVisibleCells");

var gridWidth = this.model.get('grid_cols');
var xFrom = Math.round( this.layoutAttributes.position * (gridWidth - this.layoutAttributes.visible_x) );
var layAttrs = this.layoutAttributes;

_.each( this.model.collectionView.getItemViews(), function( cellView ) {
var cellDim = cellView.model.get('extra');
// ... not too far left or right
if ( !( (cellDim.x + (cellDim.width-1)) < xFrom - 1 ||
cellDim.x > xFrom + layAttrs.visible_x + 1 )
) {

var left = cw * cellDim.x;
var width = cw * cellDim.width;

// show, set position and size in % to make responsive

cellView.activate();

cellView.$el.css({
left: left+'%',
top: (ch*cellDim.y)+'%',
width: width+'%',
height: (ch*cellDim.height)+'%'
});

// add media-query style classes to cells
cellView.$el.attr( 'class', cellView.$el.attr('class').replace(/cell-(width|height)-[0-9]+/ig,'') );
cellView.$el.addClass( 'cell-width-'+ (parseInt((absCw*cellDim.width) /50)*50) ).
addClass( 'cell-height-'+(parseInt((absCh*cellDim.height)/50)*50) );

if ( (cellDim.x-xFrom) + cellDim.width >= layAttrs.visible_x ) {
cellView.$el.addClass('lastcol');
}
if ( cellDim.y+cellDim.height >= layAttrs.visible_y ) {
cellView.$el.addClass('lastrow');
if ( !cellView.isVisible ) {
cellView.activate();
cellView.isVisible = true;
}
} else {
cellView.deactivate();
if ( cellView.isVisible ) {
cellView.deactivate();
cellView.isVisible = false;
}
}

// if ( showCellInfo ) {
// cellView.$el.addClass('with-info');
// } else {
// cellView.$el.removeClass('with-info');
// }
}})(this.layoutAttributes));
});
}

});
12 changes: 6 additions & 6 deletions app-base/views/templates/cell-types/cell-iframe.hbs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<div class="loading" style="display:none;"><span class="dot1"></span> <span class="dot2"></span> <span class="dot3"></span></div>
<div class="content element-hidden">
<iframe src="" data-src="{{iframe-src}}"
{{#each attr}}{{@key}}="{{this}}" {{/each}}>
</iframe>
</div>
<div class="info">
<h1 class="title">{{{title}}}</h1>
<div class="description">{{description}}</div>
</div>
<div class="content element-hidden">
<iframe src=""
data-src="{{iframe-src}}"
{{#each attr}}{{@key}}="{{this}}" {{/each}}>
</iframe>
</div>
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@
"dependencies": {
"chaplin" : "~0.11.3",
"console-polyfill" : "~0.1.0",
"lodash" : "~1.3.1",
"lodash" : "~2.3.0",
"jquery" : "~2.0.2",
"normalize-css" : "~2.1.2",
"h5bp-helpers" : "~0.1.0",

0 comments on commit 272b860

Please sign in to comment.