Skip to content
13 changes: 12 additions & 1 deletion addon/initializers/component-styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,18 @@ ComponentLookup.reopen({
Component.reopen({
_componentIdentifier: computed({
get() {
return (this._debugContainerKey || '').replace('component:', '');
const config = Ember.getOwner(this).resolveRegistration('config:environment');

// support /-components/ paths, debug key has full path
let containerKey = this._debugContainerKey || '';
containerKey = containerKey.replace('/' + config.modulePrefix + '/', '');
if (!containerKey.includes('@')) {
containerKey = containerKey.replace('component:', 'component:' + config.modulePrefix + '@');
}
if (containerKey.split('/').length === 1) {
containerKey = containerKey.replace('@', '@components/');
}
return containerKey;
}
}),

Expand Down
8 changes: 7 additions & 1 deletion addon/initializers/route-styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Router from '@ember/routing/router';
import { getOwner } from '@ember/application';

import podNames from 'ember-component-css/pod-names';
import Ember from "ember";

Router.reopen({
didTransition(routes) {
Expand All @@ -10,7 +11,12 @@ Router.reopen({
const classes = [];
for (let i = 0; i < routes.length; i++) {
let route = routes[i];
let currentPath = route.name.replace(/\./g, '/');
let currentPath = 'route:' + route.name.replace(/\./g, '/');

const config = Ember.getOwner(this).resolveRegistration('config:environment');
if (!currentPath.includes('@')) {
currentPath = currentPath.replace('route:', 'route:' + config.modulePrefix + '@');
}

if (podNames[currentPath]) {
getOwner(this).lookup(`controller:${route.name}`).set('styleNamespace', podNames[currentPath]);
Expand Down
48 changes: 38 additions & 10 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,31 @@ var StyleManifest = require('broccoli-style-manifest');
module.exports = {

_getStyleFunnel: function() {
if (this.parent.isModuleUnification()) {
return this._getMUStyleFunnel();
}
return new Merge([this._getPodStyleFunnel(), this._getClassicStyleFunnel()], {
annotation: 'Merge (ember-component-css merge pod and classic styles)'
});
},

_getMUStyleFunnel: function() {
return new Funnel(this.projectRoot, {
srcDir: 'ui',
exclude: ['styles/**/*'],
include: ['**/*.{' + this.allowedStyleExtensions + ',}'],
allowEmpty: true,
annotation: 'Funnel (ember-component-css grab files)'
});
},

_getPodStyleFunnel: function() {
return new Funnel(this.projectRoot, {
srcDir: this._podDirectory(),
exclude: ['styles/**/*'],
include: ['**/*.{' + this.allowedStyleExtensions + ',}'],
allowEmpty: true,
annotation: 'Funnel (ember-component-css grab files)'
annotation: 'Funnel (ember-component-css grab files)' + (this._isAddon() ? this.parent.name : '')
});
},

Expand All @@ -33,7 +46,7 @@ module.exports = {
},

_podDirectory: function() {
return this.appConfig.podModulePrefix && !this._isAddon() ? this.appConfig.podModulePrefix.replace(this.appConfig.modulePrefix, '') : '';
return this.appConfig.podModulePrefix && !this._isAddon() ? this.appConfig.podModulePrefix.replace(this.appConfig.modulePrefix, '') : '.';
},

_namespacingIsEnabled: function() {
Expand All @@ -48,7 +61,9 @@ module.exports = {

_projectRoot: function(trees) {
var projectRoot;
if (this._isAddon()) {
if (this.parent.isModuleUnification()) {
projectRoot = this.parent.root + '/src';
} else if (this._isAddon()) {
projectRoot = this.parent.root + '/addon';
} else if (trees && trees.app) {
projectRoot = trees.app;
Expand Down Expand Up @@ -77,15 +92,21 @@ module.exports = {
included: function(app) {
this._super.included.apply(this, arguments);

this.projectRoot = this._projectRoot(app.trees);

if (this._isAddon()) {
this.parent.treeForMethods['addon-styles'] = 'treeForParentAddonStyles';
this.parent.treeForParentAddonStyles = this.treeForParentAddonStyles.bind(this);
}

this.appConfig = app.project.config(this._getEnvironment());
this.addonConfig = this.appConfig['ember-component-css'] || {};
this.addonConfig = this.appConfig['ember-component-css'] || {
routeRootPaths: [],
componentRootPaths: []
};
if (this.appConfig.podModulePrefix) {
this.addonConfig.routeRootPaths.push(this.appConfig.podModulePrefix.split(this.appConfig.modulePrefix+'/')[1]);
}
this.projectRoot = this._projectRoot(app.trees);

this.classicStyleDir = this.addonConfig.classicStyleDir || 'component-styles';
this.terseClassNames = Boolean(this.addonConfig.terseClassNames);
this.allowedStyleExtensions = app.registry.extensionsForType('css').filter(Boolean);
Expand All @@ -95,6 +116,8 @@ module.exports = {
var config = {
"ember-component-css": {
terseClassNames: false,
routeRootPaths: [],
componentRootPaths: [],
},
};
if (enviroment === 'production') {
Expand All @@ -110,7 +133,10 @@ module.exports = {
annotation: 'Merge (ember-component-css merge all process styles for a complete list of styles)'
});

// namespaceStyles=true prefixes all css class names: <addonname>__classname
// path or component debugKey must be "components:<addonname>@<componentname>"
var podNames = new ExtractNames(allPodStyles, {
addonConfig: this.addonConfig,
classicStyleDir: this.classicStyleDir,
terseClassNames: this.terseClassNames,
annotation: 'Walk (ember-component-css extract class names from style paths)'
Expand All @@ -130,18 +156,20 @@ module.exports = {
},

treeForStyles: function(tree) {
if (!this._isAddon()) {
tree = this.processComponentStyles(tree);
}
tree = this.processComponentStyles(tree);
return this._super.treeForStyles.call(this, tree);
},

processComponentStyles: function(tree) {
var podStyles = this._getStyleFunnel();
podStyles = new Funnel(podStyles, {
destDir: this._isAddon() ? this.parent.name : this.parent.name()
});
this._allPodStyles.push(podStyles);

if (this._namespacingIsEnabled()) {
podStyles = new ProcessStyles(podStyles, {
addonConfig: this.addonConfig,
extensions: this.allowedStyleExtensions,
classicStyleDir: this.classicStyleDir,
terseClassNames: this.terseClassNames,
Expand All @@ -155,7 +183,7 @@ module.exports = {
});

var styleManifest = new StyleManifest(podStylesWithoutExcluded, {
outputFileNameWithoutExtension: 'pod-styles',
outputFileNameWithoutExtension: this._isAddon() ? this.parent.name + '-pod-styles' : 'pod-styles',
annotation: 'StyleManifest (ember-component-css combining all style files that there are extensions for)'
});

Expand Down
28 changes: 22 additions & 6 deletions lib/component-names.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,41 @@
var md5 = require('md5');

module.exports = {
path: function(actualPath, classicStyleDir) {
path: function(actualPath, classicStyleDir, config) {
var terminator = '/';
var pathSegementToRemove = /^components\//;
var pathSegementToRemove = '';

if (actualPath.includes(classicStyleDir)) {
terminator = '.';
pathSegementToRemove = 'styles/' + classicStyleDir + '/';
}

return actualPath.substr(0, actualPath.lastIndexOf(terminator)).replace(pathSegementToRemove, '');
actualPath = actualPath.substr(0, actualPath.lastIndexOf(terminator)).replace(pathSegementToRemove, '');
const pathParts = actualPath.split('/');
const components = ['components'].concat(config.componentRootPaths);
if (components.includes(pathParts[1]) || actualPath.includes('/-components/')) {
const namespace = pathParts[0];
const componentNamespace = config.namespaceStyles ? namespace : config.modulePrefix;
return actualPath.replace(namespace + '/', `component:${componentNamespace}@`);
}

const routes = ['routes'].concat(config.routeRootPaths);
if (routes.includes(pathParts[1])) {
const namespace = pathParts[0];
const routeNamespace = config.namespaceStyles ? namespace : config.modulePrefix;
return actualPath.replace(namespace + '/', '').replace(pathParts[1]+'/', `route:${routeNamespace}@`);
}

throw new Error('Could not associate ' + actualPath + ' with routes or components');
},

class: function(modifiedPath, classicStyleDir, terseClassNames) {
class: function(modifiedPath, classicStyleDir, terseClassNames, config) {
var seperator = '__';
var componentPath = this.path(modifiedPath, classicStyleDir);
var componentPath = this.path(modifiedPath, classicStyleDir, config);
var className = seperator + md5(componentPath).slice(-5);

if (!terseClassNames) {
className = seperator + componentPath.replace(/\//g, seperator) + className;
className = seperator + componentPath.replace(/\/|@|:/g, seperator) + className;
}

return className;
Expand Down
9 changes: 5 additions & 4 deletions lib/pod-names.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ function PodNames(inputNode, options) {
this.podNameJson = {};
this.classicStyleDir = options.classicStyleDir;
this.terseClassNames = options.terseClassNames;
this.addonConfig = options.addonConfig;
}

PodNames.prototype.build = function() {
Expand Down Expand Up @@ -64,12 +65,12 @@ PodNames.prototype.writePodStyleName = function(patches) {
}

PodNames.prototype.addClass = function(stylePath) {
var componentPath = componentNames.path(stylePath, this.classicStyleDir),
componentClass = componentNames.class(stylePath, this.classicStyleDir, this.terseClassNames);
var componentPath = componentNames.path(stylePath, this.classicStyleDir, this.addonConfig),
componentClass = componentNames.class(stylePath, this.classicStyleDir, this.terseClassNames, this.addonConfig);
this.podNameJson[componentPath] = componentClass;
}

PodNames.prototype.removeClass = function(stylePath) {
var componentPath = componentNames.path(stylePath, this.classicStyleDir);
var componentPath = componentNames.path(stylePath, this.classicStyleDir, this.addonConfig);
delete this.podNameJson[componentPath];
}
}
3 changes: 2 additions & 1 deletion lib/pod-style.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ function PodStyles(inputTree, options) {
this.extensions = options.extensions;
this.classicStyleDir = options.classicStyleDir;
this.terseClassNames = options.terseClassNames;
this.addonConfig = options.addonConfig;
}

PodStyles.prototype.processString = function(contents, stylePath) {
var extension = path.extname(stylePath),
className = componentNames.class(stylePath, this.classicStyleDir, this.terseClassNames),
className = componentNames.class(stylePath, this.classicStyleDir, this.terseClassNames, this.addonConfig),
strategy = 'default';

switch (extension) {
Expand Down
2 changes: 1 addition & 1 deletion tests/dummy/app/styles/app.sass
Original file line number Diff line number Diff line change
@@ -1 +1 @@
@import 'pod-styles.sass'
@import 'ember-component-css/pod-styles.sass'