Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 15 additions & 7 deletions packages/dev-live-reload/lib/package-watcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,24 @@ module.exports = class PackageWatcher extends Watcher {
watchedPaths.push(stylesheet);
};

const stylesheetsPath = this.pack.getStylesheetsPath();
const stylesheetsPaths =
typeof this.pack.getStylesheetsPaths === 'function'
? this.pack.getStylesheetsPaths()
: [this.pack.getStylesheetsPath()];

const stylesheetPaths = new Set(this.pack.getStylesheetPaths());

for (const stylesheetsPath of stylesheetsPaths) {
if (!fs.isDirectorySync(stylesheetsPath)) {
continue;
}

if (fs.isDirectorySync(stylesheetsPath)) {
this.watchDirectory(stylesheetsPath);
}

const stylesheetPaths = new Set(this.pack.getStylesheetPaths());
const onFile = stylesheetPath => stylesheetPaths.add(stylesheetPath);
const onFolder = () => true;
fs.traverseTreeSync(stylesheetsPath, onFile, onFolder);
const onFile = stylesheetPath => stylesheetPaths.add(stylesheetPath);
const onFolder = () => true;
fs.traverseTreeSync(stylesheetsPath, onFile, onFolder);
}

for (let stylesheet of stylesheetPaths) {
watchPath(stylesheet);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "dev-live-reload-theme-with-variants",
"themes": [
{
"name": "dev-live-reload-theme-variant-night-ui",
"theme": "ui",
"stylesheetsPath": "styles/night-ui"
},
{
"name": "dev-live-reload-theme-variant-night-syntax",
"theme": "syntax",
"stylesheetsPath": "styles/night-syntax"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@import "syntax-variables.less";
@import "shared-syntax.less";
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@syntax-text-color: #fff;
@syntax-background-color: #000;
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@import "ui-variables.less";
@import "shared-ui.less";
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@text-color: #fff;
@base-background-color: #000;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
atom-text-editor {
color: @syntax-text-color;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
atom-workspace {
color: @text-color;
}
43 changes: 43 additions & 0 deletions packages/dev-live-reload/spec/ui-watcher-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -275,4 +275,47 @@ describe('UIWatcher', () => {
await conditionPromise(() => pack.reloadStylesheets.callCount > 0);
});
});

describe('theme variants', () => {
beforeEach(async () => {
jasmine.useRealClock();
atom.packages.loadPackage(
path.join(__dirname, 'fixtures', 'theme-with-variants')
);
atom.config.set('core.themes', [
'dev-live-reload-theme-variant-night-ui',
'dev-live-reload-theme-variant-night-syntax'
]);

await atom.themes.activateThemes();
uiWatcher = new UIWatcher();
});

afterEach(() => atom.themes.deactivateThemes());

it('watches all variant stylesheet paths and reloads the variant theme', async () => {
const themePath = path.join(__dirname, 'fixtures', 'theme-with-variants');
const theme = atom.themes
.getActiveThemes()
.find(
activeTheme =>
activeTheme.name === 'dev-live-reload-theme-variant-night-ui'
);
spyOn(theme, 'reloadStylesheets');

const watcher = uiWatcher.watchedThemes.get(
'dev-live-reload-theme-variant-night-ui'
);
const watchedPaths = watcher.entities.map(entity => entity.getPath());

expect(watchedPaths).toContain(path.join(themePath, 'styles', 'night-ui'));
expect(watchedPaths).toContain(path.join(themePath, 'styles'));

watcher.entities
.find(entity => entity.getPath().endsWith('shared-ui.less'))
.emitter.emit('did-change');

await conditionPromise(() => theme.reloadStylesheets.callCount > 0);
});
});
});
4 changes: 3 additions & 1 deletion packages/settings-view/lib/install-panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,9 @@ export default class InstallPanel {
}

filterPackages (packages, themes) {
return packages.filter(({theme}) => themes ? theme : !theme)
return packages.filter((pack) =>
themes ? pack.theme || pack.themes : !(pack.theme || pack.themes)
)
}

// Load and display the featured packages that are available to install.
Expand Down
10 changes: 6 additions & 4 deletions packages/settings-view/lib/installed-packages-panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,12 @@ export default class InstalledPackagesPanel extends CollapsibleSectionPanel {
}

filterPackages (packages) {
packages.dev = packages.dev.filter(({theme}) => !theme)
packages.user = packages.user.filter(({theme}) => !theme)
packages.core = packages.core.filter(({theme}) => !theme)
packages.git = (packages.git || []).filter(({theme}) => !theme)
packages.dev = packages.dev.filter((pack) => !(pack.theme || pack.themes))
packages.user = packages.user.filter((pack) => !(pack.theme || pack.themes))
packages.core = packages.core.filter((pack) => !(pack.theme || pack.themes))
packages.git = (packages.git || []).filter((pack) =>
!(pack.theme || pack.themes)
)

for (let packageType of ['dev', 'core', 'user', 'git']) {
for (let pack of packages[packageType]) {
Expand Down
2 changes: 1 addition & 1 deletion packages/settings-view/lib/package-card.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default class PackageCard {
// of malformed package metadata are handled here and in ::content but belt
// and suspenders, you know
this.client = this.packageManager.getClient()
this.type = this.pack.theme ? 'theme' : 'package'
this.type = this.pack.theme || this.pack.themes ? 'theme' : 'package'
this.name = this.pack.name
this.onSettingsView = options.onSettingsView

Expand Down
2 changes: 1 addition & 1 deletion packages/settings-view/lib/package-detail-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ export default class PackageDetailView {

populate () {
this.refs.title.textContent = `${_.undasherize(_.uncamelcase(this.pack.name))}`
this.type = this.pack.metadata.theme ? 'theme' : 'package'
this.type = this.pack.metadata.theme || this.pack.metadata.themes ? 'theme' : 'package'

const repoUrl = this.packageManager.getRepositoryUrl(this.pack)
if (repoUrl) {
Expand Down
6 changes: 5 additions & 1 deletion packages/settings-view/lib/package-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,11 @@ module.exports = class PackageManager {
// pack - The package for which the event is being emitted.
// error - Any error information to be included in the case of an error.
emitPackageEvent(eventName, pack, error) {
const theme = pack.theme != null ? pack.theme : (pack.metadata != null ? pack.metadata.theme : undefined);
const theme = pack.theme != null
? pack.theme
: (pack.metadata != null
? pack.metadata.theme || pack.metadata.themes
: undefined);
eventName = theme ? `theme-${eventName}` : `package-${eventName}`;
return this.emitter.emit(eventName, {pack, error});
}
Expand Down
35 changes: 25 additions & 10 deletions packages/settings-view/lib/themes-panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,10 +194,12 @@ export default class ThemesPanel extends CollapsibleSectionPanel {
}

filterThemes (packages) {
packages.dev = packages.dev.filter(({theme}) => theme)
packages.user = packages.user.filter(({theme}) => theme)
packages.core = packages.core.filter(({theme}) => theme)
packages.git = (packages.git || []).filter(({theme}) => theme)
packages.dev = packages.dev.filter((pack) => pack.theme || pack.themes)
packages.user = packages.user.filter((pack) => pack.theme || pack.themes)
packages.core = packages.core.filter((pack) => pack.theme || pack.themes)
packages.git = (packages.git || []).filter((pack) =>
pack.theme || pack.themes
)

for (let packageType of ['dev', 'core', 'user', 'git']) {
for (let pack of packages[packageType]) {
Expand Down Expand Up @@ -262,8 +264,21 @@ export default class ThemesPanel extends CollapsibleSectionPanel {
}
}

hasSettings (packageName) {
return this.packageManager.packageHasSettings(packageName)
hasSettings (themeName) {
return this.packageManager.packageHasSettings(this.getThemePackageName(themeName))
}

getThemePackageName (themeName) {
const theme = atom.themes.getLoadedThemes().find((theme) =>
theme.name === themeName
)
return (theme != null ? theme.packageName : null) || themeName
}

getThemePackageMetadata (themeName) {
const packageName = this.getThemePackageName(themeName)
const pack = atom.packages.getLoadedPackage(packageName)
return pack != null ? pack.metadata : null
}

// Populate the theme menus from the theme manager's active themes
Expand Down Expand Up @@ -430,9 +445,9 @@ export default class ThemesPanel extends CollapsibleSectionPanel {
didClickActiveUiThemeSettings (event) {
event.stopPropagation()
const theme = atom.themes.getActiveThemes().find((theme) => theme.metadata.theme === 'ui')
const activeUiTheme = theme != null ? theme.metadata : null
const activeUiTheme = theme != null ? this.getThemePackageMetadata(theme.name) : null
if (activeUiTheme != null) {
this.settingsView.showPanel(this.activeUiTheme, {
this.settingsView.showPanel(this.getThemePackageName(this.activeUiTheme), {
back: 'Themes',
pack: activeUiTheme
})
Expand All @@ -442,9 +457,9 @@ export default class ThemesPanel extends CollapsibleSectionPanel {
didClickActiveSyntaxThemeSettings (event) {
event.stopPropagation()
const theme = atom.themes.getActiveThemes().find((theme) => theme.metadata.theme === 'syntax')
const activeSyntaxTheme = theme != null ? theme.metadata : null
const activeSyntaxTheme = theme != null ? this.getThemePackageMetadata(theme.name) : null
if (activeSyntaxTheme != null) {
this.settingsView.showPanel(this.activeSyntaxTheme, {
this.settingsView.showPanel(this.getThemePackageName(this.activeSyntaxTheme), {
back: 'Themes',
pack: activeSyntaxTheme
})
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "theme-with-variants",
"themes": [
{
"name": "theme-variant-day-ui",
"theme": "ui",
"stylesheetsPath": "styles/day-ui"
},
{
"name": "theme-variant-night-ui",
"theme": "ui",
"stylesheetsPath": "styles/night-ui"
},
{
"name": "theme-variant-day-syntax",
"theme": "syntax",
"stylesheetsPath": "styles/day-syntax"
},
{
"name": "theme-variant-night-syntax",
"theme": "syntax",
"stylesheetsPath": "styles/night-syntax"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
atom-text-editor {
color: #111111;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
atom-workspace {
background-color: #ffffff;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
atom-text-editor {
color: #eeeeee;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
atom-workspace {
background-color: #000000;
}
32 changes: 32 additions & 0 deletions packages/settings-view/spec/themes-panel-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,23 @@ describe("ThemesPanel", function () {
expect(panel.refs.syntaxMenu.value).toBe('atom-dark-syntax');
});

it("lists theme variants in the theme menus", function () {
atom.packages.loadPackage('theme-with-variants');
panel.updateActiveThemes();

const uiThemeValues = Array.from(panel.refs.uiMenu.children).map(
child => child.value
);
const syntaxThemeValues = Array.from(panel.refs.syntaxMenu.children).map(
child => child.value
);

expect(uiThemeValues).toContain('theme-variant-day-ui');
expect(uiThemeValues).toContain('theme-variant-night-ui');
expect(syntaxThemeValues).toContain('theme-variant-day-syntax');
expect(syntaxThemeValues).toContain('theme-variant-night-syntax');
});

describe("when a UI theme is selected", () => it("updates the 'core.themes' config key with the selected UI theme", function () {
for (let child of Array.from(panel.refs.uiMenu.children)) {
child.selected = child.value === 'atom-light-ui';
Expand All @@ -65,6 +82,21 @@ describe("ThemesPanel", function () {
runs(() => expect(atom.config.get('core.themes')).toEqual(['atom-dark-ui', 'atom-light-syntax']));
}));

describe("when a UI theme variant is selected", () => it("updates the 'core.themes' config key with the selected UI variant", function () {
atom.packages.loadPackage('theme-with-variants');
panel.updateActiveThemes();

for (let child of Array.from(panel.refs.uiMenu.children)) {
child.selected = child.value === 'theme-variant-night-ui';
child.dispatchEvent(new Event('change', {bubbles: true}));
}
waitsFor(() => reloadedHandler.callCount === 2);
runs(() => expect(atom.config.get('core.themes')).toEqual([
'theme-variant-night-ui',
'atom-dark-syntax'
]));
}));

describe("when the 'core.config' key changes", () => it("refreshes the theme menus", function () {
reloadedHandler.reset();
atom.config.set('core.themes', ['atom-light-ui', 'atom-light-syntax']);
Expand Down
28 changes: 28 additions & 0 deletions spec/fixtures/packages/theme-with-variants/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "theme-with-variants",
"themes": [
{
"name": "theme-variant-day-ui",
"theme": "ui",
"stylesheetsPath": "styles/day-ui"
},
{
"name": "theme-variant-night-ui",
"theme": "ui",
"stylesheetsPath": [
"styles/night-ui",
"styles/shared"
]
},
{
"name": "theme-variant-day-syntax",
"theme": "syntax",
"stylesheetsPath": "styles/day-syntax"
},
{
"name": "theme-variant-night-syntax",
"theme": "syntax",
"stylesheetsPath": "styles/night-syntax"
}
]
}
5 changes: 5 additions & 0 deletions spec/fixtures/packages/theme-with-variants/styles/atom.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@import "ui-variables";

.variant-atom-probe {
color: @app-background-color;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
atom-text-editor {
color: #111111;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
atom-workspace {
background-color: #ffffff;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@app-background-color: #ffffff;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
atom-text-editor {
color: #eeeeee;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
atom-workspace {
background-color: #000000;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@app-background-color: #010203;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Loading
Loading