221 lines
6.0 KiB
JavaScript
221 lines
6.0 KiB
JavaScript
var $ = require('jquery');
|
|
var Backbone = require('backbone');
|
|
var _ = require('underscore');
|
|
var CoreView = require('backbone/core-view');
|
|
var checkAndBuildOpts = require('builder/helpers/required-opts');
|
|
|
|
var REQUIRED_OPTS = [
|
|
'onboardingNotification',
|
|
'editorModel',
|
|
'template',
|
|
'numberOfSteps',
|
|
'selector',
|
|
'modifier',
|
|
'notificationKey'
|
|
];
|
|
|
|
var LEFT_KEY_CODE = 37;
|
|
var RIGHT_KEY_CODE = 39;
|
|
|
|
module.exports = CoreView.extend({
|
|
className: 'is-step0 is-opening',
|
|
|
|
events: {
|
|
'click .js-start': '_onClickNext',
|
|
'click .js-next': '_onClickNext',
|
|
'click .js-close': '_close',
|
|
'click .js-highlight': '_close'
|
|
},
|
|
|
|
initialize: function (opts) {
|
|
checkAndBuildOpts(opts, REQUIRED_OPTS, this);
|
|
this.$el.addClass(this._selector);
|
|
this.model = new Backbone.Model({
|
|
step: -1
|
|
});
|
|
this._defaultBodyPos = {
|
|
top: 32,
|
|
left: 380
|
|
};
|
|
|
|
this._keyDown = this._onKeyDown.bind(this);
|
|
this._initBinds();
|
|
},
|
|
|
|
render: function () {
|
|
this.$el.addClass(this._selector + this._modifier);
|
|
this.$el.html(this._template());
|
|
if (this.model.get('step') === -1) {
|
|
this._next();
|
|
}
|
|
return this;
|
|
},
|
|
|
|
_initBinds: function () {
|
|
this.listenTo(this.model, 'destroy', this._close);
|
|
this.listenTo(this.model, 'change:step', this._onChangeStep);
|
|
this.listenTo(this._editorModel, 'change:edition', this._changeEdition);
|
|
$(document).on('keydown', this._keyDown);
|
|
},
|
|
|
|
_changeEdition: function (mdl) {
|
|
var isEditing = !!mdl.get('edition');
|
|
this.$el.toggleClass('is-editing', isEditing);
|
|
},
|
|
|
|
_prev: function () {
|
|
if (this._currentStep() >= 1) {
|
|
this.model.set('step', this._currentStep() - 1);
|
|
}
|
|
},
|
|
|
|
_next: function () {
|
|
if (this._currentStep() < this._numberOfSteps) {
|
|
this.model.set('step', this._currentStep() + 1);
|
|
}
|
|
},
|
|
|
|
_currentStep: function () {
|
|
return this.model.get('step');
|
|
},
|
|
|
|
_onClickNext: function (event) {
|
|
if (event) event.stopPropagation();
|
|
this._next();
|
|
},
|
|
|
|
_onChangeStep: function () {
|
|
var prev = this.model.previous('step');
|
|
var step = this.model.get('step');
|
|
|
|
this.$el.removeClass('is-step' + prev, function () {
|
|
this.$el.addClass('is-step' + step);
|
|
}.bind(this));
|
|
|
|
this.$('.js-step').removeClass('is-step' + prev).addClass('is-step' + step);
|
|
|
|
this.$('.' + this._selector + '-body').fadeOut(0).delay(200).fadeIn(100);
|
|
|
|
this.$('.' + this._selector + '-step.is-step' + prev).css('display', 'none');
|
|
this.$('.' + this._selector + '-footer.is-step' + prev).css('display', 'none');
|
|
this.$('.' + this._selector + '-step.is-step' + step).css('display', 'block');
|
|
this.$('.' + this._selector + '-footer.is-step' + step).css('display', 'block');
|
|
|
|
this.$('.' + this._selector + '-contentBody').css('display', step === 0 ? 'block' : 'none');
|
|
},
|
|
|
|
_close: function () {
|
|
this._forget();
|
|
this.trigger('close', this);
|
|
},
|
|
|
|
_onKeyDown: function (event) {
|
|
event.stopPropagation();
|
|
|
|
if (event.which === LEFT_KEY_CODE) {
|
|
this._prev();
|
|
} else if (event.which === RIGHT_KEY_CODE) {
|
|
this._next();
|
|
}
|
|
},
|
|
|
|
_forget: function () {
|
|
this._onboardingNotification.setKey(this._notificationKey, true);
|
|
this._onboardingNotification.save();
|
|
},
|
|
|
|
clean: function () {
|
|
$(document).off('keydown', this._keyDown);
|
|
CoreView.prototype.clean.apply(this);
|
|
},
|
|
|
|
_setMiddlePad: function (position, padding, body) {
|
|
var $window = $(window);
|
|
var $top = this.$('.' + this._selector + '-pads--left .' + this._selector + '-padTop');
|
|
var $middle = this.$('.' + this._selector + '-pads--left .' + this._selector + '-padMiddle');
|
|
var $bottom = this.$('.' + this._selector + '-pads--left .' + this._selector + '-padBottom');
|
|
var vh = $window.height();
|
|
var vw = $window.width();
|
|
var isSelector = _.isString(position);
|
|
var $el = $(position);
|
|
var width = 0;
|
|
var height = 0;
|
|
var left = 0;
|
|
var top = 0;
|
|
if ($el.length === 0) return;
|
|
|
|
if (isSelector) {
|
|
width = $el.outerWidth();
|
|
height = $el.outerHeight();
|
|
left = $el.offset().left;
|
|
top = $el.offset().top;
|
|
} else {
|
|
width = position.width;
|
|
height = position.height;
|
|
left = position.left;
|
|
top = position.top;
|
|
}
|
|
|
|
// Apply padding
|
|
var appliedPadding = this._buildPadding(padding);
|
|
top -= appliedPadding.top;
|
|
left -= appliedPadding.left;
|
|
width += appliedPadding.left + appliedPadding.right;
|
|
height += appliedPadding.top + appliedPadding.bottom;
|
|
|
|
// Is it place outside the viewport?
|
|
if (vw - left > 0 && vw - left < width) {
|
|
width = vw - left;
|
|
} else if (vw - left <= 0) {
|
|
width = 0;
|
|
}
|
|
|
|
// Left offset
|
|
this.$('.' + this._selector + '-toolbarOverlay').outerWidth(left);
|
|
|
|
// Right panel
|
|
this.$('.' + this._selector + '-contentWrapper').outerWidth(vw - (left + width));
|
|
|
|
// Width
|
|
this.$('.' + this._selector + '-pads--left').outerWidth(width);
|
|
$top.outerWidth(width);
|
|
$middle.outerWidth(width);
|
|
$bottom.outerWidth(width);
|
|
|
|
// Height
|
|
var topHeight = top;
|
|
var middleHeight = height;
|
|
var bottomHeight = vh - (topHeight + middleHeight);
|
|
|
|
$top.outerHeight(topHeight);
|
|
$middle.outerHeight(middleHeight);
|
|
$bottom.outerHeight(bottomHeight);
|
|
|
|
// Body text
|
|
this.$('.' + this._selector + '-body').css('top', body && body.top ? body.top : this._defaultBodyPos.top);
|
|
this.$('.' + this._selector + '-body').css('left', body && body.left ? body.left : this._defaultBodyPos.left);
|
|
},
|
|
|
|
_buildPadding: function (padding) {
|
|
var result = {
|
|
top: 0,
|
|
right: 0,
|
|
bottom: 0,
|
|
left: 0
|
|
};
|
|
|
|
if (padding) {
|
|
result.top = this._calculatePadding(padding.top);
|
|
result.right = this._calculatePadding(padding.right);
|
|
result.bottom = this._calculatePadding(padding.bottom);
|
|
result.left = this._calculatePadding(padding.left);
|
|
}
|
|
|
|
return result;
|
|
},
|
|
|
|
_calculatePadding: function (padding) {
|
|
return (padding && _.isFinite(padding)) ? padding : 0;
|
|
}
|
|
});
|