2019-05-31 19:33:56 +03:00
|
|
|
const temp = require('temp').track();
|
|
|
|
const StyleManager = require('../src/style-manager');
|
2016-10-03 19:11:03 +03:00
|
|
|
|
|
|
|
describe('StyleManager', () => {
|
2019-05-31 19:33:56 +03:00
|
|
|
let [styleManager, addEvents, removeEvents, updateEvents] = [];
|
2016-10-03 19:11:03 +03:00
|
|
|
|
|
|
|
beforeEach(() => {
|
2019-02-22 10:55:17 +03:00
|
|
|
styleManager = new StyleManager({
|
|
|
|
configDirPath: temp.mkdirSync('atom-config')
|
2019-05-31 19:33:56 +03:00
|
|
|
});
|
|
|
|
addEvents = [];
|
|
|
|
removeEvents = [];
|
|
|
|
updateEvents = [];
|
2019-02-22 10:55:17 +03:00
|
|
|
styleManager.onDidAddStyleElement(event => {
|
2019-05-31 19:33:56 +03:00
|
|
|
addEvents.push(event);
|
|
|
|
});
|
2019-02-22 10:55:17 +03:00
|
|
|
styleManager.onDidRemoveStyleElement(event => {
|
2019-05-31 19:33:56 +03:00
|
|
|
removeEvents.push(event);
|
|
|
|
});
|
2019-02-22 10:55:17 +03:00
|
|
|
styleManager.onDidUpdateStyleElement(event => {
|
2019-05-31 19:33:56 +03:00
|
|
|
updateEvents.push(event);
|
|
|
|
});
|
|
|
|
});
|
2016-10-03 19:11:03 +03:00
|
|
|
|
2016-12-01 05:41:58 +03:00
|
|
|
afterEach(() => {
|
2017-08-04 21:18:43 +03:00
|
|
|
try {
|
2019-05-31 19:33:56 +03:00
|
|
|
temp.cleanupSync();
|
2017-08-04 21:18:43 +03:00
|
|
|
} catch (e) {
|
|
|
|
// Do nothing
|
|
|
|
}
|
2019-05-31 19:33:56 +03:00
|
|
|
});
|
2016-12-01 05:41:58 +03:00
|
|
|
|
2016-10-03 19:11:03 +03:00
|
|
|
describe('::addStyleSheet(source, params)', () => {
|
2016-10-06 21:06:37 +03:00
|
|
|
it('adds a style sheet based on the given source and returns a disposable allowing it to be removed', () => {
|
2019-05-31 19:33:56 +03:00
|
|
|
const disposable = styleManager.addStyleSheet('a {color: red}');
|
|
|
|
expect(addEvents.length).toBe(1);
|
|
|
|
expect(addEvents[0].textContent).toBe('a {color: red}');
|
|
|
|
const styleElements = styleManager.getStyleElements();
|
|
|
|
expect(styleElements.length).toBe(1);
|
|
|
|
expect(styleElements[0].textContent).toBe('a {color: red}');
|
|
|
|
disposable.dispose();
|
|
|
|
expect(removeEvents.length).toBe(1);
|
|
|
|
expect(removeEvents[0].textContent).toBe('a {color: red}');
|
|
|
|
expect(styleManager.getStyleElements().length).toBe(0);
|
|
|
|
});
|
2016-10-04 12:22:41 +03:00
|
|
|
|
|
|
|
describe('atom-text-editor shadow DOM selectors upgrades', () => {
|
|
|
|
beforeEach(() => {
|
|
|
|
// attach styles element to the DOM to parse CSS rules
|
2019-02-22 10:55:17 +03:00
|
|
|
styleManager.onDidAddStyleElement(styleElement => {
|
2019-05-31 19:33:56 +03:00
|
|
|
jasmine.attachToDOM(styleElement);
|
|
|
|
});
|
|
|
|
});
|
2016-10-04 12:22:41 +03:00
|
|
|
|
|
|
|
it('removes the ::shadow pseudo-element from atom-text-editor selectors', () => {
|
2016-10-06 20:18:04 +03:00
|
|
|
styleManager.addStyleSheet(`
|
|
|
|
atom-text-editor::shadow .class-1, atom-text-editor::shadow .class-2 { color: red }
|
|
|
|
atom-text-editor::shadow > .class-3 { color: yellow }
|
|
|
|
atom-text-editor .class-4 { color: blue }
|
2019-05-27 11:55:53 +03:00
|
|
|
atom-text-editor[data-grammar*="js"]::shadow .class-6 { color: green; }
|
2016-10-06 20:18:04 +03:00
|
|
|
atom-text-editor[mini].is-focused::shadow .class-7 { color: green; }
|
2019-05-31 19:33:56 +03:00
|
|
|
`);
|
2019-02-22 10:55:17 +03:00
|
|
|
expect(
|
|
|
|
Array.from(styleManager.getStyleElements()[0].sheet.cssRules).map(
|
|
|
|
r => r.selectorText
|
|
|
|
)
|
|
|
|
).toEqual([
|
2016-11-01 19:56:09 +03:00
|
|
|
'atom-text-editor.editor .class-1, atom-text-editor.editor .class-2',
|
|
|
|
'atom-text-editor.editor > .class-3',
|
2016-10-06 20:18:04 +03:00
|
|
|
'atom-text-editor .class-4',
|
2019-02-22 10:55:17 +03:00
|
|
|
'atom-text-editor[data-grammar*="js"].editor .class-6',
|
2016-11-01 19:56:09 +03:00
|
|
|
'atom-text-editor[mini].is-focused.editor .class-7'
|
2019-05-31 19:33:56 +03:00
|
|
|
]);
|
|
|
|
});
|
2016-10-04 12:22:41 +03:00
|
|
|
|
|
|
|
describe('when a selector targets the atom-text-editor shadow DOM', () => {
|
|
|
|
it('prepends "--syntax" to class selectors matching a grammar scope name and not already starting with "syntax--"', () => {
|
2019-02-22 10:55:17 +03:00
|
|
|
styleManager.addStyleSheet(
|
|
|
|
`
|
2016-10-04 12:22:41 +03:00
|
|
|
.class-1 { color: red }
|
|
|
|
.source > .js, .source.coffee { color: green }
|
|
|
|
.syntax--source { color: gray }
|
|
|
|
#id-1 { color: blue }
|
2019-02-22 10:55:17 +03:00
|
|
|
`,
|
|
|
|
{ context: 'atom-text-editor' }
|
2019-05-31 19:33:56 +03:00
|
|
|
);
|
2019-02-22 10:55:17 +03:00
|
|
|
expect(
|
|
|
|
Array.from(styleManager.getStyleElements()[0].sheet.cssRules).map(
|
|
|
|
r => r.selectorText
|
|
|
|
)
|
|
|
|
).toEqual([
|
2016-10-04 12:22:41 +03:00
|
|
|
'.class-1',
|
|
|
|
'.syntax--source > .syntax--js, .syntax--source.syntax--coffee',
|
|
|
|
'.syntax--source',
|
|
|
|
'#id-1'
|
2019-05-31 19:33:56 +03:00
|
|
|
]);
|
2016-10-04 12:22:41 +03:00
|
|
|
|
|
|
|
styleManager.addStyleSheet(`
|
|
|
|
.source > .js, .source.coffee { color: green }
|
|
|
|
atom-text-editor::shadow .source > .js { color: yellow }
|
2016-10-06 20:18:04 +03:00
|
|
|
atom-text-editor[mini].is-focused::shadow .source > .js { color: gray }
|
2016-10-04 12:22:41 +03:00
|
|
|
atom-text-editor .source > .js { color: red }
|
2019-05-31 19:33:56 +03:00
|
|
|
`);
|
2019-02-22 10:55:17 +03:00
|
|
|
expect(
|
|
|
|
Array.from(styleManager.getStyleElements()[1].sheet.cssRules).map(
|
|
|
|
r => r.selectorText
|
|
|
|
)
|
|
|
|
).toEqual([
|
2016-10-04 12:22:41 +03:00
|
|
|
'.source > .js, .source.coffee',
|
2016-11-01 19:56:09 +03:00
|
|
|
'atom-text-editor.editor .syntax--source > .syntax--js',
|
|
|
|
'atom-text-editor[mini].is-focused.editor .syntax--source > .syntax--js',
|
2016-10-04 12:22:41 +03:00
|
|
|
'atom-text-editor .source > .js'
|
2019-05-31 19:33:56 +03:00
|
|
|
]);
|
|
|
|
});
|
|
|
|
});
|
2016-10-04 12:22:41 +03:00
|
|
|
|
2016-10-06 21:06:37 +03:00
|
|
|
it('replaces ":host" with "atom-text-editor" only when the context of a style sheet is "atom-text-editor"', () => {
|
2019-02-22 10:55:17 +03:00
|
|
|
styleManager.addStyleSheet(
|
|
|
|
':host .class-1, :host .class-2 { color: red; }'
|
2019-05-31 19:33:56 +03:00
|
|
|
);
|
2019-02-22 10:55:17 +03:00
|
|
|
expect(
|
|
|
|
Array.from(styleManager.getStyleElements()[0].sheet.cssRules).map(
|
|
|
|
r => r.selectorText
|
|
|
|
)
|
2019-05-31 19:33:56 +03:00
|
|
|
).toEqual([':host .class-1, :host .class-2']);
|
2019-02-22 10:55:17 +03:00
|
|
|
styleManager.addStyleSheet(
|
|
|
|
':host .class-1, :host .class-2 { color: red; }',
|
|
|
|
{ context: 'atom-text-editor' }
|
2019-05-31 19:33:56 +03:00
|
|
|
);
|
2019-02-22 10:55:17 +03:00
|
|
|
expect(
|
|
|
|
Array.from(styleManager.getStyleElements()[1].sheet.cssRules).map(
|
|
|
|
r => r.selectorText
|
|
|
|
)
|
2019-05-31 19:33:56 +03:00
|
|
|
).toEqual(['atom-text-editor .class-1, atom-text-editor .class-2']);
|
|
|
|
});
|
2016-10-04 12:22:41 +03:00
|
|
|
|
|
|
|
it('does not throw exceptions on rules with no selectors', () => {
|
2019-02-22 10:55:17 +03:00
|
|
|
styleManager.addStyleSheet('@media screen {font-size: 10px}', {
|
|
|
|
context: 'atom-text-editor'
|
2019-05-31 19:33:56 +03:00
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
2016-10-03 19:11:03 +03:00
|
|
|
|
|
|
|
describe('when a sourcePath parameter is specified', () => {
|
|
|
|
it('ensures a maximum of one style element for the given source path, updating a previous if it exists', () => {
|
2019-02-22 11:55:30 +03:00
|
|
|
styleManager.addStyleSheet('a {color: red}', {
|
2019-02-22 10:55:17 +03:00
|
|
|
sourcePath: '/foo/bar'
|
2019-05-31 19:33:56 +03:00
|
|
|
});
|
|
|
|
expect(addEvents.length).toBe(1);
|
|
|
|
expect(addEvents[0].getAttribute('source-path')).toBe('/foo/bar');
|
2016-10-03 19:11:03 +03:00
|
|
|
|
2019-02-22 10:55:17 +03:00
|
|
|
const disposable2 = styleManager.addStyleSheet('a {color: blue}', {
|
|
|
|
sourcePath: '/foo/bar'
|
2019-05-31 19:33:56 +03:00
|
|
|
});
|
|
|
|
expect(addEvents.length).toBe(1);
|
|
|
|
expect(updateEvents.length).toBe(1);
|
|
|
|
expect(updateEvents[0].getAttribute('source-path')).toBe('/foo/bar');
|
|
|
|
expect(updateEvents[0].textContent).toBe('a {color: blue}');
|
|
|
|
disposable2.dispose();
|
2016-10-03 19:11:03 +03:00
|
|
|
|
2019-05-31 19:33:56 +03:00
|
|
|
addEvents = [];
|
2019-02-22 10:55:17 +03:00
|
|
|
styleManager.addStyleSheet('a {color: yellow}', {
|
|
|
|
sourcePath: '/foo/bar'
|
2019-05-31 19:33:56 +03:00
|
|
|
});
|
|
|
|
expect(addEvents.length).toBe(1);
|
|
|
|
expect(addEvents[0].getAttribute('source-path')).toBe('/foo/bar');
|
|
|
|
expect(addEvents[0].textContent).toBe('a {color: yellow}');
|
|
|
|
});
|
|
|
|
});
|
2016-10-03 19:11:03 +03:00
|
|
|
|
|
|
|
describe('when a priority parameter is specified', () => {
|
|
|
|
it('inserts the style sheet based on the priority', () => {
|
2019-05-31 19:33:56 +03:00
|
|
|
styleManager.addStyleSheet('a {color: red}', { priority: 1 });
|
|
|
|
styleManager.addStyleSheet('a {color: blue}', { priority: 0 });
|
|
|
|
styleManager.addStyleSheet('a {color: green}', { priority: 2 });
|
|
|
|
styleManager.addStyleSheet('a {color: yellow}', { priority: 1 });
|
2019-02-22 10:55:17 +03:00
|
|
|
expect(
|
|
|
|
styleManager.getStyleElements().map(elt => elt.textContent)
|
|
|
|
).toEqual([
|
2016-10-03 19:11:03 +03:00
|
|
|
'a {color: blue}',
|
|
|
|
'a {color: red}',
|
|
|
|
'a {color: yellow}',
|
|
|
|
'a {color: green}'
|
2019-05-31 19:33:56 +03:00
|
|
|
]);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|