ui: Adds `document` and `viewport` methods to the dom service (#5052)
`window` and `document` are easily injected anyhow, but this primarily this keeps everything dom related in the same place. Included here are changes to make all ember related objects use the dom service `document` and `viewport` instead of just `document` and `window`. Quote from a previous PR (#4924) which explains the thinking around this: > Now I have all these things in the dom service, it would make sense to get window from there also. I was thinking of making a viewport method, which would be a nice word whether window was a browser window, an iframe (not really a window) like when ember testing, or anything else. To me the viewport is what we are actually talking about here.
This commit is contained in:
parent
9a27b2c74d
commit
c4effc9734
|
@ -3,8 +3,6 @@ import { get, set } from '@ember/object';
|
|||
import { inject as service } from '@ember/service';
|
||||
export default Component.extend({
|
||||
dom: service('dom'),
|
||||
// TODO: could this be dom.viewport() ?
|
||||
win: window,
|
||||
isDropdownVisible: false,
|
||||
didInsertElement: function() {
|
||||
get(this, 'dom')
|
||||
|
@ -19,11 +17,12 @@ export default Component.extend({
|
|||
},
|
||||
change: function(e) {
|
||||
const dom = get(this, 'dom');
|
||||
const win = dom.viewport();
|
||||
const $root = dom.root();
|
||||
const $body = dom.element('body');
|
||||
if (e.target.checked) {
|
||||
$root.classList.add('template-with-vertical-menu');
|
||||
$body.style.height = $root.style.height = get(this, 'win').innerHeight + 'px';
|
||||
$body.style.height = $root.style.height = win.innerHeight + 'px';
|
||||
} else {
|
||||
$root.classList.remove('template-with-vertical-menu');
|
||||
$body.style.height = $root.style.height = null;
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
import Mixin from '@ember/object/mixin';
|
||||
|
||||
import { inject as service } from '@ember/service';
|
||||
import { next } from '@ember/runloop';
|
||||
import { get } from '@ember/object';
|
||||
const isOutside = function(element, e) {
|
||||
|
||||
// TODO: Potentially move this to dom service
|
||||
const isOutside = function(element, e, doc = document) {
|
||||
if (element) {
|
||||
const isRemoved = !e.target || !document.contains(e.target);
|
||||
const isRemoved = !e.target || !doc.contains(e.target);
|
||||
const isInside = element === e.target || element.contains(e.target);
|
||||
return !isRemoved && !isInside;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const handler = function(e) {
|
||||
const el = get(this, 'element');
|
||||
if (isOutside(el, e)) {
|
||||
|
@ -18,6 +21,7 @@ const handler = function(e) {
|
|||
}
|
||||
};
|
||||
export default Mixin.create({
|
||||
dom: service('dom'),
|
||||
init: function() {
|
||||
this._super(...arguments);
|
||||
this.handler = handler.bind(this);
|
||||
|
@ -26,12 +30,14 @@ export default Mixin.create({
|
|||
onblur: function() {},
|
||||
didInsertElement: function() {
|
||||
this._super(...arguments);
|
||||
const doc = get(this, 'dom').document();
|
||||
next(this, () => {
|
||||
document.addEventListener('click', this.handler);
|
||||
doc.addEventListener('click', this.handler);
|
||||
});
|
||||
},
|
||||
willDestroyElement: function() {
|
||||
this._super(...arguments);
|
||||
document.removeEventListener('click', this.handler);
|
||||
const doc = get(this, 'dom').document();
|
||||
doc.removeEventListener('click', this.handler);
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import Mixin from '@ember/object/mixin';
|
||||
import { inject as service } from '@ember/service';
|
||||
import { get } from '@ember/object';
|
||||
import { assert } from '@ember/debug';
|
||||
export default Mixin.create({
|
||||
dom: service('dom'),
|
||||
resize: function(e) {
|
||||
assert('with-resizing.resize needs to be overridden', false);
|
||||
},
|
||||
win: window,
|
||||
init: function() {
|
||||
this._super(...arguments);
|
||||
this.handler = e => {
|
||||
|
@ -17,14 +18,18 @@ export default Mixin.create({
|
|||
},
|
||||
didInsertElement: function() {
|
||||
this._super(...arguments);
|
||||
get(this, 'win').addEventListener('resize', this.handler, false);
|
||||
get(this, 'dom')
|
||||
.viewport()
|
||||
.addEventListener('resize', this.handler, false);
|
||||
this.didAppear();
|
||||
},
|
||||
didAppear: function() {
|
||||
this.handler({ target: get(this, 'win') });
|
||||
this.handler({ target: get(this, 'dom').viewport() });
|
||||
},
|
||||
willDestroyElement: function() {
|
||||
get(this, 'win').removeEventListener('resize', this.handler, false);
|
||||
get(this, 'dom')
|
||||
.viewport()
|
||||
.removeEventListener('resize', this.handler, false);
|
||||
this._super(...arguments);
|
||||
},
|
||||
});
|
||||
|
|
|
@ -23,10 +23,17 @@ let $_;
|
|||
const clickFirstAnchor = clickFirstAnchorFactory(closest);
|
||||
export default Service.extend({
|
||||
doc: document,
|
||||
win: window,
|
||||
init: function() {
|
||||
this._super(...arguments);
|
||||
$_ = getComponentFactory(getOwner(this));
|
||||
},
|
||||
document: function() {
|
||||
return get(this, 'doc');
|
||||
},
|
||||
viewport: function() {
|
||||
return get(this, 'win');
|
||||
},
|
||||
// TODO: should this be here? Needs a better name at least
|
||||
clickFirstAnchor: clickFirstAnchor,
|
||||
closest: closest,
|
||||
|
|
|
@ -12,8 +12,13 @@ module('Integration | Mixin | with-resizing', function(hooks) {
|
|||
addEventListener: this.stub(),
|
||||
removeEventListener: this.stub(),
|
||||
};
|
||||
const dom = {
|
||||
viewport: function() {
|
||||
return win;
|
||||
},
|
||||
};
|
||||
const subject = EmberObject.extend(Mixin, {
|
||||
win: win,
|
||||
dom: dom,
|
||||
}).create();
|
||||
const resize = this.stub(subject, 'resize');
|
||||
subject.didInsertElement();
|
||||
|
|
Loading…
Reference in New Issue