123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336 |
- const PaneContainer = require('../src/pane-container');
- describe('PaneElement', function() {
- let [paneElement, container, containerElement, pane] = [];
- beforeEach(function() {
- spyOn(atom.applicationDelegate, 'open');
- container = new PaneContainer({
- location: 'center',
- config: atom.config,
- confirm: atom.confirm.bind(atom),
- viewRegistry: atom.views,
- applicationDelegate: atom.applicationDelegate
- });
- containerElement = container.getElement();
- pane = container.getActivePane();
- paneElement = pane.getElement();
- });
- describe("when the pane's active status changes", () =>
- it('adds or removes the .active class as appropriate', function() {
- const pane2 = pane.splitRight();
- expect(pane2.isActive()).toBe(true);
- expect(paneElement.className).not.toMatch(/active/);
- pane.activate();
- expect(paneElement.className).toMatch(/active/);
- pane2.activate();
- expect(paneElement.className).not.toMatch(/active/);
- }));
- describe('when the active item changes', function() {
- it('hides all item elements except the active one', function() {
- const item1 = document.createElement('div');
- const item2 = document.createElement('div');
- const item3 = document.createElement('div');
- pane.addItem(item1);
- pane.addItem(item2);
- pane.addItem(item3);
- expect(pane.getActiveItem()).toBe(item1);
- expect(item1.parentElement).toBeDefined();
- expect(item1.style.display).toBe('');
- expect(item2.parentElement).toBeNull();
- expect(item3.parentElement).toBeNull();
- pane.activateItem(item2);
- expect(item2.parentElement).toBeDefined();
- expect(item1.style.display).toBe('none');
- expect(item2.style.display).toBe('');
- expect(item3.parentElement).toBeNull();
- pane.activateItem(item3);
- expect(item3.parentElement).toBeDefined();
- expect(item1.style.display).toBe('none');
- expect(item2.style.display).toBe('none');
- expect(item3.style.display).toBe('');
- });
- it('transfers focus to the new item if the previous item was focused', function() {
- const item1 = document.createElement('div');
- item1.tabIndex = -1;
- const item2 = document.createElement('div');
- item2.tabIndex = -1;
- pane.addItem(item1);
- pane.addItem(item2);
- jasmine.attachToDOM(paneElement);
- paneElement.focus();
- expect(document.activeElement).toBe(item1);
- pane.activateItem(item2);
- expect(document.activeElement).toBe(item2);
- });
- describe('if the active item is a model object', () =>
- it('retrieves the associated view from atom.views and appends it to the itemViews div', function() {
- class TestModel {}
- atom.views.addViewProvider(TestModel, function(model) {
- const view = document.createElement('div');
- view.model = model;
- return view;
- });
- const item1 = new TestModel();
- const item2 = new TestModel();
- pane.addItem(item1);
- pane.addItem(item2);
- expect(paneElement.itemViews.children[0].model).toBe(item1);
- expect(paneElement.itemViews.children[0].style.display).toBe('');
- pane.activateItem(item2);
- expect(paneElement.itemViews.children[1].model).toBe(item2);
- expect(paneElement.itemViews.children[0].style.display).toBe('none');
- expect(paneElement.itemViews.children[1].style.display).toBe('');
- }));
- describe('when the new active implements .getPath()', function() {
- it('adds the file path and file name as a data attribute on the pane', function() {
- const item1 = document.createElement('div');
- item1.getPath = () => '/foo/bar.txt';
- const item2 = document.createElement('div');
- pane.addItem(item1);
- pane.addItem(item2);
- expect(paneElement.dataset.activeItemPath).toBe('/foo/bar.txt');
- expect(paneElement.dataset.activeItemName).toBe('bar.txt');
- pane.activateItem(item2);
- expect(paneElement.dataset.activeItemPath).toBeUndefined();
- expect(paneElement.dataset.activeItemName).toBeUndefined();
- pane.activateItem(item1);
- expect(paneElement.dataset.activeItemPath).toBe('/foo/bar.txt');
- expect(paneElement.dataset.activeItemName).toBe('bar.txt');
- pane.destroyItems();
- expect(paneElement.dataset.activeItemPath).toBeUndefined();
- expect(paneElement.dataset.activeItemName).toBeUndefined();
- });
- describe('when the path of the item changes', function() {
- let [item1, item2] = [];
- beforeEach(function() {
- item1 = document.createElement('div');
- item1.path = '/foo/bar.txt';
- item1.changePathCallbacks = [];
- item1.setPath = function(path) {
- this.path = path;
- for (let callback of Array.from(this.changePathCallbacks)) {
- callback();
- }
- };
- item1.getPath = function() {
- return this.path;
- };
- item1.onDidChangePath = function(callback) {
- this.changePathCallbacks.push(callback);
- return {
- dispose: () => {
- this.changePathCallbacks = this.changePathCallbacks.filter(
- f => f !== callback
- );
- }
- };
- };
- item2 = document.createElement('div');
- pane.addItem(item1);
- pane.addItem(item2);
- });
- it('changes the file path and file name data attributes on the pane if the active item path is changed', function() {
- expect(paneElement.dataset.activeItemPath).toBe('/foo/bar.txt');
- expect(paneElement.dataset.activeItemName).toBe('bar.txt');
- item1.setPath('/foo/bar1.txt');
- expect(paneElement.dataset.activeItemPath).toBe('/foo/bar1.txt');
- expect(paneElement.dataset.activeItemName).toBe('bar1.txt');
- pane.activateItem(item2);
- expect(paneElement.dataset.activeItemPath).toBeUndefined();
- expect(paneElement.dataset.activeItemName).toBeUndefined();
- item1.setPath('/foo/bar2.txt');
- expect(paneElement.dataset.activeItemPath).toBeUndefined();
- expect(paneElement.dataset.activeItemName).toBeUndefined();
- pane.activateItem(item1);
- expect(paneElement.dataset.activeItemPath).toBe('/foo/bar2.txt');
- expect(paneElement.dataset.activeItemName).toBe('bar2.txt');
- });
- });
- });
- });
- describe('when an item is removed from the pane', function() {
- describe('when the destroyed item is an element', () =>
- it('removes the item from the itemViews div', function() {
- const item1 = document.createElement('div');
- const item2 = document.createElement('div');
- pane.addItem(item1);
- pane.addItem(item2);
- paneElement = pane.getElement();
- expect(item1.parentElement).toBe(paneElement.itemViews);
- pane.destroyItem(item1);
- expect(item1.parentElement).toBeNull();
- expect(item2.parentElement).toBe(paneElement.itemViews);
- pane.destroyItem(item2);
- expect(item2.parentElement).toBeNull();
- }));
- describe('when the destroyed item is a model', () =>
- it("removes the model's associated view", function() {
- class TestModel {}
- atom.views.addViewProvider(TestModel, function(model) {
- const view = document.createElement('div');
- model.element = view;
- view.model = model;
- return view;
- });
- const item1 = new TestModel();
- const item2 = new TestModel();
- pane.addItem(item1);
- pane.addItem(item2);
- expect(item1.element.parentElement).toBe(paneElement.itemViews);
- pane.destroyItem(item1);
- expect(item1.element.parentElement).toBeNull();
- expect(item2.element.parentElement).toBe(paneElement.itemViews);
- pane.destroyItem(item2);
- expect(item2.element.parentElement).toBeNull();
- }));
- });
- describe('when the pane element is focused', function() {
- it('transfers focus to the active view', function() {
- const item = document.createElement('div');
- item.tabIndex = -1;
- pane.activateItem(item);
- jasmine.attachToDOM(paneElement);
- expect(document.activeElement).toBe(document.body);
- paneElement.focus();
- expect(document.activeElement).toBe(item);
- document.body.focus();
- pane.activate();
- expect(document.activeElement).toBe(item);
- });
- it('makes the pane active', function() {
- pane.splitRight();
- expect(pane.isActive()).toBe(false);
- jasmine.attachToDOM(paneElement);
- paneElement.focus();
- expect(pane.isActive()).toBe(true);
- });
- it('does not re-activate the pane when focus changes within the pane', function() {
- const item = document.createElement('div');
- const itemChild = document.createElement('div');
- item.tabIndex = -1;
- itemChild.tabIndex = -1;
- item.appendChild(itemChild);
- jasmine.attachToDOM(paneElement);
- pane.activateItem(item);
- pane.activate();
- let activationCount = 0;
- pane.onDidActivate(() => activationCount++);
- itemChild.focus();
- expect(activationCount).toBe(0);
- });
- });
- describe('when the pane element is attached', () =>
- it('focuses the pane element if isFocused() returns true on its model', function() {
- pane.focus();
- jasmine.attachToDOM(paneElement);
- expect(document.activeElement).toBe(paneElement);
- }));
- describe('drag and drop', function() {
- const buildDragEvent = function(type, files) {
- const dataTransfer = {
- files,
- data: {},
- setData(key, value) {
- this.data[key] = value;
- },
- getData(key) {
- return this.data[key];
- }
- };
- const event = new CustomEvent('drop');
- event.dataTransfer = dataTransfer;
- return event;
- };
- describe('when a file is dragged to the pane', () =>
- it('opens it', function() {
- const event = buildDragEvent('drop', [
- { path: '/fake1' },
- { path: '/fake2' }
- ]);
- paneElement.dispatchEvent(event);
- expect(atom.applicationDelegate.open.callCount).toBe(1);
- expect(atom.applicationDelegate.open.argsForCall[0][0]).toEqual({
- pathsToOpen: ['/fake1', '/fake2'],
- here: true
- });
- }));
- describe('when a non-file is dragged to the pane', () =>
- it('does nothing', function() {
- const event = buildDragEvent('drop', []);
- paneElement.dispatchEvent(event);
- expect(atom.applicationDelegate.open).not.toHaveBeenCalled();
- }));
- });
- describe('resize', () =>
- it("shrinks independently of its contents' width", function() {
- jasmine.attachToDOM(containerElement);
- const item = document.createElement('div');
- item.style.width = '2000px';
- item.style.height = '30px';
- paneElement.insertBefore(item, paneElement.children[0]);
- paneElement.style.flexGrow = 0.1;
- expect(paneElement.getBoundingClientRect().width).toBeGreaterThan(0);
- expect(paneElement.getBoundingClientRect().width).toBeLessThan(
- item.getBoundingClientRect().width
- );
- paneElement.style.flexGrow = 0;
- expect(paneElement.getBoundingClientRect().width).toBe(0);
- }));
- });
|