Skip to content

Commit

Permalink
Bug 972666 - [Calendar] lines over events longer than 2 hours
Browse files Browse the repository at this point in the history
  • Loading branch information
millermedeiros committed Mar 5, 2014
1 parent c12edf5 commit 646b111
Show file tree
Hide file tree
Showing 8 changed files with 173 additions and 20 deletions.
25 changes: 15 additions & 10 deletions apps/calendar/js/views/day_based.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
/*global Calendar*/
Calendar.ns('Views').DayBased = (function() {
'use strict';

var Calc = Calendar.Calc;
var hoursOfOccurance = Calendar.Calc.hoursOfOccurance;
Expand Down Expand Up @@ -181,8 +183,6 @@ Calendar.ns('Views').DayBased = (function() {

var html = this._renderEvent(busytime, record);
var eventArea = hourRecord.element;
var records = hourRecord.records;
var idx = records.insertIndexOf(busytime._id);

if (this.template.hourEventsSelector) {
eventArea = eventArea.querySelector(
Expand Down Expand Up @@ -235,7 +235,6 @@ Calendar.ns('Views').DayBased = (function() {
*/
_insertElement: function(html, element, records, idx) {
var el;
var len = records.length;

if (!element.children.length || idx === 0) {
element.insertAdjacentHTML(
Expand All @@ -260,9 +259,6 @@ Calendar.ns('Views').DayBased = (function() {
* @param {HTMLElement} element target to apply top/height to.
*/
_assignPosition: function(busytime, element) {
var topOffset = 0;
var height = 0;

// cache dates
var start = busytime.startDate;
var end = busytime.endDate;
Expand Down Expand Up @@ -326,6 +322,11 @@ Calendar.ns('Views').DayBased = (function() {
* build the default elements for the view and return the parent element.
*/
_buildElement: function() {
// XXX: wrapper used to create a new stacking context to fix Bug 972666
// without causing performance issues described on Bug 972675
var wrapper = document.createElement('div');
wrapper.classList.add('day-events-wrapper');

// create the hidden values for element & eventsElement
this._eventsElement = document.createElement('section');
this._element = document.createElement('section');
Expand All @@ -344,7 +345,8 @@ Calendar.ns('Views').DayBased = (function() {
}

// setup/inject elements.
this.element.appendChild(this._eventsElement);
wrapper.appendChild(this._eventsElement);
this.element.appendChild(wrapper);
this.events.classList.add(this.classType);

return this.element;
Expand Down Expand Up @@ -377,8 +379,9 @@ Calendar.ns('Views').DayBased = (function() {
var record = this.hours.get(hour);

// skip records that do not exist.
if (record === null)
if (record === null) {
return;
}

var el = record.element;

Expand Down Expand Up @@ -435,8 +438,9 @@ Calendar.ns('Views').DayBased = (function() {

delete this._idsToHours[id];

if (!hours)
if (!hours) {
return;
}

hours.forEach(function(number) {
var hour = this.hours.get(number);
Expand All @@ -452,8 +456,9 @@ Calendar.ns('Views').DayBased = (function() {
// are any more...
var idx = flags.indexOf(calendarClass);

if (idx !== -1)
if (idx !== -1) {
flags.splice(idx, 1);
}

// if after we have removed the flag there
// are no more we can remove the class
Expand Down
7 changes: 6 additions & 1 deletion apps/calendar/style/day_views.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
.day-events {
display: block;
box-shadow: none;
/* XXX: used to create a new stacking context to fix Bug 972666 without
* causing performance issues described on Bug 972675 */
position: relative;
z-index: 0;
}

.day-events > .hour {
Expand Down Expand Up @@ -63,6 +67,7 @@
position: absolute;
height: 6rem;
top: 0;
z-index: 10;
}

.day-events .hour-allday .event {
Expand Down Expand Up @@ -164,7 +169,7 @@
display: block;
}

#day-view .day-events {
#day-view .day-events-wrapper {
overflow-y: scroll;
overflow-x: hidden;
height: calc(100% - 6rem);
Expand Down
4 changes: 3 additions & 1 deletion apps/calendar/style/ui.css
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,8 @@ section.month #month-days ol {
}

/* Make the rows a bit taller for larger resolutions */
@media (min-device-height: 640px) {
/* use min-height instead of min-device-width because of b2g Bug 979924 */
@media (min-height: 640px) {
section.month ol {
height: 6rem;
}
Expand Down Expand Up @@ -504,6 +505,7 @@ Indicators are in units of 12
#view-selector {
position: absolute;
bottom: 0;
height: 4.5rem;
}

#view-selector > li > a {
Expand Down
3 changes: 3 additions & 0 deletions apps/calendar/style/week_view.css
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@
* see bug 968478
*/
background-color: #fff;
/* XXX: z-index + position:relative is important for perf (Bug 972675) */
z-index: 0;
}

#week-view .weekday .children > section {
Expand All @@ -177,6 +179,7 @@
#week-view .week-events > ol li.event {
position: absolute;
width: 100%;
z-index: 10;
}

#week-view .week-events .container {
Expand Down
64 changes: 60 additions & 4 deletions apps/calendar/test/marionette/calendar.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ Calendar.Selector = Object.freeze({
eventListSection: '#event-list',
hintSwipeToNavigate: '#hint-swipe-to-navigate',
modifyEventView: '#modify-event-view',
monthDayViewEvents: '#months-day-view .day-events',
monthEventList: '#event-list div.events > section',
monthEventTitle: 'h5',
monthViewDayEvent: '#event-list .event',
Expand All @@ -60,6 +61,7 @@ Calendar.Selector = Object.freeze({
monthViewpresent: '#month-view li.present',
monthViewselected: '#month-view li.selected',
monthYearHeader: '#current-month-year',
dayViewEvent: '#day-view .active .event',
todayTabItem: '#today',
toolbarAddAccountButton: '#settings a[href="/select-preset/"]',
toolbarButton: '#time-header button.settings',
Expand All @@ -77,6 +79,7 @@ Calendar.Selector = Object.freeze({
viewEventViewTitleContent: '#event-view .title .content',
viewEventViewDescription: '#event-view .description',
viewEventViewDescriptionContent: '#event-view .description .content',
viewEventViewCancelButton: '#event-view button.cancel',
weekButton: '#view-selector .week a',
weekViewEvent: '#week-view .event'
});
Expand Down Expand Up @@ -137,6 +140,22 @@ Calendar.prototype = {
this.client.waitFor(this.isWeekViewActive.bind(this));
},

waitForDayView: function() {
this.client.waitFor(this.isDayViewActive.bind(this));
},

waitForViewEventView: function() {
this.client.waitFor(this.isViewEventViewActive.bind(this));
},

waitForEditEventView: function() {
this.client.waitFor(this.isEditEventViewActive.bind(this));
},

waitForAddEventView: function() {
this.client.waitFor(this.isAddEventViewActive.bind(this));
},

// TODO: extract this logic into the marionette-helper repository since this
// can be useful for other apps as well
waitForKeyboardHide: function() {
Expand Down Expand Up @@ -248,6 +267,8 @@ Calendar.prototype = {
* (string) location - event location
* (Date) startDate - when event starts
* (Date) endDate - when event ends
* (Number) startHour - shortcut for setting the startDate
* (Number) duration - shortcut for setting the endDate based on startDate
* @return {Event} Created event.
*/
createEvent: function(opts) {
Expand All @@ -265,17 +286,38 @@ Calendar.prototype = {
titleInput.sendKeys(opts.title);
locationInput.sendKeys(opts.location);
descriptionInput.sendKeys(opts.description);

var startDate = opts.startDate;
var endDate = opts.endDate;
var startHour = opts.startHour || 0;

if (!startDate) {
startDate = new Date();
startDate.setHours(startHour);
startDate.setMinutes(0);
startDate.setSeconds(0);
startDate.setMilliseconds(0);
}

if (!endDate) {
// duration should always be bigger than 0, defaults to 1h
var duration = opts.duration || 1;
endDate = new Date(startDate.getTime() + (60 * duration * 60 * 1000));
}

var form = this.waitForElement('editEventForm');
this.client.forms.fill(form, {
startDate: opts.startDate,
startTime: opts.startDate,
endDate: opts.endDate,
endTime: opts.endDate
startDate: startDate,
startTime: startDate,
endDate: endDate,
endTime: endDate
});

// Save event.
this.waitForElement('editEventSaveButton').click();

this.waitForKeyboardHide();

// TODO(gareth): Sort out the dates and times here.
return {
calendar: 'Offline calendar',
Expand Down Expand Up @@ -358,6 +400,20 @@ Calendar.prototype = {
return this.isViewActive('event/show');
},

/**
* @return {boolean} Whether or not the add event view is active.
*/
isAddEventViewActive: function() {
return this.isViewActive('event/add');
},

/**
* @return {boolean} Whether or not the edit event view is active.
*/
isEditEventViewActive: function() {
return this.isViewActive('event/edit');
},

/**
* Start the calendar, save the client for future ops, and wait for the
* calendar to finish an initial render.
Expand Down
41 changes: 39 additions & 2 deletions apps/calendar/test/marionette/day_view_test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict';

var Calendar = require('./calendar'),
Marionette = require('marionette-client'),
assert = require('chai').assert;

marionette('day view', function() {
Expand All @@ -11,7 +12,7 @@ marionette('day view', function() {
app.launch({ hideSwipeHint: true });
// Go to day view
app.waitForElement('dayButton').click();
client.waitFor(app.isDayViewActive.bind(app));
app.waitForDayView();
});

test('header copy should not overflow', function() {
Expand All @@ -20,4 +21,40 @@ marionette('day view', function() {
// 20 chars is a "safe" limit if font-family is Fira Sans
assert.operator(header.text().length, '<', 21);
});

suite('events longer than 2h', function() {
setup(function() {
app.createEvent({
title: 'Lorem Ipsum',
location: 'Dolor Amet',
startHour: 0,
duration: 3
});
app.waitForDayView();
});

test('click after first hour', function() {
// click will happen at middle of element and middle is after first hour,
// so this should be enough to trigger the event details (Bug 972666)
client.findElement('#day-view .active .day-events .hour-2').click();

app.waitForViewEventView();

var title = app.findElement('viewEventViewTitle');

assert.equal(
title.text(),
'Lorem Ipsum',
'title should match'
);
});

test('click after event end', function() {
// click will happen at middle of element so this should be enough to
// trigger the create event (since .hour-3 is after event duration)
client.findElement('#day-view .active .day-events .hour-3').click();
assert.ok(app.isAddEventViewActive(), 'should go to add event view');
});
});

});
47 changes: 47 additions & 0 deletions apps/calendar/test/marionette/month_view_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
'use strict';

var Calendar = require('./calendar'),
assert = require('chai').assert;

marionette('month view', function() {
var app;
var client = marionette.client();

setup(function() {
app = new Calendar(client);
app.launch({ hideSwipeHint: true });
});

test('#months-day-view scroll', function() {
app.createEvent({
title: 'Long Event',
location: 'Dolor Amet',
startHour: 0,
duration: 16
});
app.waitForMonthView();

var monthDayViewEvents = app.findElement('monthDayViewEvents');

assert.equal(
monthDayViewEvents.getAttribute('scrollTop'),
0,
'scroll should start at zero'
);

var pos = monthDayViewEvents.location();
var x = pos.x + 30;
var body = client.findElement('body');
// fast vertical swipe, needs to happen on the body since we want
// coordinates to be absolute
app.actions
.flick(body, x, pos.y + 10, x, 50)
.perform();

// this will timeout if scroll did not change
client.waitFor(function() {
return monthDayViewEvents.getAttribute('scrollTop') > 0;
});
});

});
2 changes: 0 additions & 2 deletions build/jshint/xfail.list
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ apps/calendar/js/views/advanced_settings.js
apps/calendar/js/views/calendar_colors.js
apps/calendar/js/views/create_account.js
apps/calendar/js/views/day.js
apps/calendar/js/views/day_based.js
apps/calendar/js/views/day_child.js
apps/calendar/js/views/errors.js
apps/calendar/js/views/event_base.js
Expand All @@ -95,7 +94,6 @@ apps/calendar/js/views/week_child.js
apps/calendar/js/worker/manager.js
apps/calendar/js/worker/thread.js
apps/calendar/test/assertions.js
apps/calendar/test/marionette/day_view_test.js
apps/calendar/test/marionette/today_test.js
apps/calendar/test/unit/app_test.js
apps/calendar/test/unit/calc_test.js
Expand Down

0 comments on commit 646b111

Please sign in to comment.