Skip to content
This repository has been archived by the owner on Jan 3, 2023. It is now read-only.

Commit

Permalink
Remove jquery, fix all tests
Browse files Browse the repository at this point in the history
  • Loading branch information
RobbieTheWagner committed Aug 16, 2017
1 parent eea685a commit 9b8bea4
Show file tree
Hide file tree
Showing 12 changed files with 251 additions and 68 deletions.
4 changes: 1 addition & 3 deletions addon/components/nav-items-container/component.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import $ from 'jquery';
import Component from '@ember/component';
import { inject as service } from '@ember/service';
import layout from './template';
Expand All @@ -7,9 +6,8 @@ export default Component.extend({
navService: service('ember-3d-nav'),
layout,
tagName: 'grid',
classNameBindings: [''],
didInsertElement() {
$(window).on('resize', () => {
window.addEventListener('resize', () => {
window.requestAnimationFrame(this.get('navService').updateSelectedNav);
});
}
Expand Down
6 changes: 3 additions & 3 deletions addon/components/nav-trigger-container/component.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/* eslint-disable ship-shape/no-on-calls-in-components */
import $ from 'jquery';
import Component from '@ember/component';
import { on } from '@ember/object/evented';
import { getScrollTop } from '../../utils';
import { inject as service } from '@ember/service';
import { run } from '@ember/runloop';
import Headroom from 'headroom';
import layout from './template';
import RespondsToScroll from 'ember-responds-to/mixins/responds-to-scroll';
import RespondsToScroll from '../../mixins/responds-to-scroll';

export default Component.extend(RespondsToScroll, {
navService: service('ember-3d-nav'),
Expand All @@ -17,7 +17,7 @@ export default Component.extend(RespondsToScroll, {
useHeadroom: false,
onScroll: on('scroll', function() {
if (this.get('isFixed')) {
const scrollPosition = $(window).scrollTop();
const scrollPosition = getScrollTop();

if (scrollPosition > 0) {
this.set('isFixedAndScrolled', true);
Expand Down
19 changes: 19 additions & 0 deletions addon/mixins/debounced-response.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import Ember from 'ember';

export default Ember.Mixin.create({
debounce(handler) {
return (...args) => {
if (!this.isScheduled) {
this.isScheduled = true;

window.requestAnimationFrame(() => {
this.isScheduled = false;

if (this.get('isDestroyed')) return;

Ember.run(this, handler, ...args);
});
}
};
}
});
30 changes: 30 additions & 0 deletions addon/mixins/responds-to-scroll.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import Ember from 'ember';
import DebouncedResponse from './debounced-response';

function noop() { }

// Debounces browser event, triggers 'scroll' event and calls 'scroll' handler.
export default Ember.Mixin.create(
Ember.Evented,
DebouncedResponse,
{

scroll: noop,

didInsertElement: function() {
this._super(...arguments);

this.scrollHandler = this.debounce((...args) => {
this.trigger('scroll', ...args);
this.scroll(...args);
});

window.addEventListener('scroll', this.scrollHandler);
},

willDestroyElement: function() {
this._super(...arguments);

window.removeEventListener('scroll', this.scrollHandler);
}
});
20 changes: 9 additions & 11 deletions addon/services/ember-3d-nav.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import $ from 'jquery';
import { computed } from '@ember/object';
import { getOwner } from '@ember/application';
import { oneTimeTransitionEvent } from '../utils';
import Service from '@ember/service';

export default Service.extend({
Expand All @@ -13,8 +13,9 @@ export default Service.extend({
selectedIndex: 0,
toggle3dBlock() {
const addOrRemove = this.get('navIsVisible');

$('.main').toggleClass('nav-is-visible', addOrRemove).one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', () => {
const main = document.querySelectorAll('.main')[0];
main.classList.toggle('nav-is-visible', addOrRemove);
oneTimeTransitionEvent(main, () => {
// fix marker position when opening the menu (after a window resize)
if (addOrRemove) {
this.updateSelectedNav();
Expand All @@ -28,17 +29,14 @@ export default Service.extend({
* @private
*/
updateSelectedNav(type) {
const selectedItem = $('.is-selected');

const leftPosition = selectedItem.offset().left;
const selectedItem = document.querySelectorAll('.is-selected')[0];
const leftPosition = selectedItem.getBoundingClientRect().left + document.body.scrollLeft;
const marker = document.querySelectorAll('.nav-marker')[0];

const marker = $('.nav-marker');
marker.style.left = `${leftPosition}px`;

marker.css({
'left': leftPosition
});
if (type === 'close') {
marker.one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', () => {
oneTimeTransitionEvent(marker, () => {
this.set('navIsVisible', false);
this.toggle3dBlock();
});
Expand Down
38 changes: 38 additions & 0 deletions addon/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
function whichTransitionEvent() {
let t;
const el = document.createElement('fakeelement');

const transitions = {
'transition': 'transitionend',
'OTransition': 'oTransitionEnd',
'MozTransition': 'transitionend',
'WebkitTransition': 'webkitTransitionEnd'
};

for (t in transitions) {
if (el.style[t] !== undefined) {
return transitions[t];
}
}
}

const getScrollTop = function() {
return (window.pageYOffset !== undefined) ?
window.pageYOffset :
(document.documentElement || document.body.parentNode || document.body).scrollTop;
};

const oneTimeTransitionEvent = function(element, callback) {
const transitionEvent = whichTransitionEvent();
const customFunction = (e) => {
e.target.removeEventListener(transitionEvent, customFunction);
return callback(e);
};

element.addEventListener(transitionEvent, customFunction);
};

export {
getScrollTop,
oneTimeTransitionEvent
};
4 changes: 2 additions & 2 deletions ember-cli-build.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ const shim = require('@html-next/flexi-layouts/lib/pod-templates-shim');
shim(EmberAddon);

module.exports = function(defaults) {
const app = new EmberAddon(defaults, {
// Add options here
let app = new EmberAddon(defaults, {
vendorFiles: { 'jquery.js': null }
});

/*
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
"ember-cli-htmlbars": "^2.0.1",
"ember-cli-sass": "^7.0.0",
"ember-headroom": "^1.1.1",
"ember-responds-to": "1.4.0",
"ember-truth-helpers": "1.3.0",
"flexi": "^2.0.1"
},
Expand All @@ -56,6 +55,9 @@
"ember-disable-prototype-extensions": "^1.1.2",
"ember-export-application-global": "^2.0.0",
"ember-load-initializers": "^1.0.0",
"ember-maybe-import-regenerator": "^0.1.6",
"ember-native-dom-event-dispatcher": "^0.6.3",
"ember-native-dom-helpers": "^0.5.3",
"ember-resolver": "^4.0.0",
"ember-source": "~2.15.0-beta.1",
"eslint-plugin-ember": "^4.0.0",
Expand Down
94 changes: 52 additions & 42 deletions tests/acceptance/ember-3d-nav-test.js
Original file line number Diff line number Diff line change
@@ -1,58 +1,68 @@
import Ember from 'ember';
import { click, find, findAll, scrollTo, visit } from 'ember-native-dom-helpers';
import { getScrollTop } from 'ember-3d-nav/utils';
import { test } from 'qunit';
import moduleForAcceptance from '../helpers/module-for-acceptance';
const { $, run } = Ember;
import { run } from '@ember/runloop';

moduleForAcceptance('Nav menu behavior');

test('clicking menu button opens nav', function(assert) {
test('clicking menu button opens nav', async function(assert) {
assert.expect(2);

visit('/');
andThen(function() {
assert.equal(find('.ember-3d-nav-container').hasClass('nav-is-visible'), false, 'nav-is-visible class not applied initially');
});
click('.nav-trigger');
andThen(function() {
assert.equal(find('.ember-3d-nav-container').hasClass('nav-is-visible'), true, 'nav-is-visible class applied after clicking menu button');
});
await visit('/');

assert.equal(find('.ember-3d-nav-container').classList.contains('nav-is-visible'), false,
'nav-is-visible class not applied initially');

await click(find('.nav-trigger'));

assert.equal(find('.ember-3d-nav-container').classList.contains('nav-is-visible'), true,
'nav-is-visible class applied after clicking menu button');
});

test('clicking an option selects it and closes the menu', function(assert) {
test('clicking an option selects it and closes the menu', async function(assert) {
assert.expect(4);

visit('/');
andThen(function() {
assert.equal(find('.ember-3d-nav-container').hasClass('nav-is-visible'), false, 'nav-is-visible class not applied initially');
});
click('.nav-trigger');
andThen(function() {
assert.equal(find('.ember-3d-nav-container').hasClass('nav-is-visible'), true, 'nav-is-visible class applied after clicking menu button');
});
run.scheduleOnce('afterRender', this, function() {
click('centered:nth-of-type(2)');
andThen(function() {
assert.equal(find('centered:nth-of-type(2)').hasClass('is-selected'), true, 'nav item is selected');
assert.equal(find('.ember-3d-nav-container').hasClass('nav-is-visible'), false, 'nav-is-visible class removed after clicking nav item');
});
});
const done = assert.async();

await visit('/');

assert.equal(find('.ember-3d-nav-container').classList.contains('nav-is-visible'), false,
'nav-is-visible class not applied initially');

await click(find('.nav-trigger'));

assert.equal(find('.ember-3d-nav-container').classList.contains('nav-is-visible'), true,
'nav-is-visible class applied after clicking menu button');

await click(findAll('centered')[2]);

assert.equal(findAll('centered')[2].classList.contains('is-selected'), true,
'nav item is selected');

run.later(function() {
assert.equal(find('.ember-3d-nav-container').classList.contains('nav-is-visible'), false,
'nav-is-visible class removed after clicking nav item');
done();
}, 1500);

});

test('scrolling applies isFixedAndScrolled', function(assert) {
test('scrolling applies isFixedAndScrolled', async function(assert) {
assert.expect(5);

visit('/');
andThen(function() {
assert.equal($(window).scrollTop(), 0, 'window scroll is 0');
$(window).scrollTop(50);
assert.equal($(window).scrollTop(), 50, 'window scroll is 50');
run.later(this, function() {
assert.equal(find('.nav-trigger-container').hasClass('is-fixed-and-scrolled'), true, 'is-fixed-and-scrolled applied');
$(window).scrollTop(0);
assert.equal($(window).scrollTop(), 0, 'window scroll is 0');
run.later(this, function() {
assert.equal(find('.nav-trigger-container').hasClass('is-fixed-and-scrolled'), false, 'is-fixed-and-scrolled removed');
}, 100);
}, 100);
});
await visit('/');
assert.equal(getScrollTop(), 0, 'window scroll is 0');

await scrollTo(document.body, 0, 50);
assert.equal(getScrollTop(), 50, 'window scroll is 50');

assert.equal(find('.nav-trigger-container').classList.contains('is-fixed-and-scrolled'), true,
'is-fixed-and-scrolled applied');

await scrollTo(document.body, 0, 0);
assert.equal(getScrollTop(), 0, 'window scroll is 0');

assert.equal(find('.nav-trigger-container').classList.contains('is-fixed-and-scrolled'), false,
'is-fixed-and-scrolled removed');
});
12 changes: 12 additions & 0 deletions tests/unit/mixins/debounced-response-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import Ember from 'ember';
import DebouncedResponseMixin from 'ember-3d-nav/mixins/debounced-response';
import { module, test } from 'qunit';

module('Unit | Mixin | debounced response');

// Replace this with your real tests.
test('it works', function(assert) {
let DebouncedResponseObject = Ember.Object.extend(DebouncedResponseMixin);
let subject = DebouncedResponseObject.create();
assert.ok(subject);
});
12 changes: 12 additions & 0 deletions tests/unit/mixins/responds-to-scroll-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import Ember from 'ember';
import RespondsToScrollMixin from 'ember-3d-nav/mixins/responds-to-scroll';
import { module, test } from 'qunit';

module('Unit | Mixin | responds to scroll');

// Replace this with your real tests.
test('it works', function(assert) {
let RespondsToScrollObject = Ember.Object.extend(RespondsToScrollMixin);
let subject = RespondsToScrollObject.create();
assert.ok(subject);
});
Loading

0 comments on commit 9b8bea4

Please sign in to comment.