Namespace skin CSS to be per instance

This will be required to have multiple Webamp instances on a page.

However, it will complicate our script which extracts pre-compiled CSS
for the default skin.
This commit is contained in:
Jordan Eldredge 2019-03-04 07:23:19 -08:00
parent d5e55aa1f7
commit 5ca4400894
3 changed files with 26 additions and 17 deletions

View file

@ -35,6 +35,7 @@ class App extends React.Component {
this._webampNode.id = "webamp";
this._webampNode.role = "application";
this._webampNode.style.zIndex = this.props.zIndex;
this._webampNode.classList.add(this.props.instanceClass);
document.body.appendChild(this._webampNode);
this.props.browserWindowSizeChanged(Utils.getWindowSize());
@ -167,8 +168,9 @@ class App extends React.Component {
}
return ReactDOM.createPortal(
<React.Fragment>
<Skin />
<Skin instanceClass={this.props.instanceClass} />
<ContextMenuWrapper
// instanceId={this.props.instanceId}
renderContents={() => <MainContextMenu filePickers={filePickers} />}
>
<WindowManager

View file

@ -88,13 +88,14 @@ function cssRulesFromProps(props) {
if (!skinImages || !skinCursors) {
return null;
}
const cssPrefix = `${CSS_PREFIX}.${props.instanceClass}`;
const cssRules = [];
Object.keys(imageSelectors).forEach(imageName => {
const imageUrl = skinImages[imageName] || skinImages[FALLBACKS[imageName]];
if (imageUrl) {
imageSelectors[imageName].forEach(selector => {
cssRules.push(
`${CSS_PREFIX} ${selector} {background-image: url(${imageUrl})}`
`${cssPrefix} ${selector} {background-image: url(${imageUrl})}`
);
});
}
@ -105,10 +106,10 @@ function cssRulesFromProps(props) {
const width = skinGenLetterWidths[`GEN_TEXT_${letter}`];
const selectedWidth = skinGenLetterWidths[`GEN_TEXT_SELECTED_${letter}`];
cssRules.push(
`${CSS_PREFIX} .gen-text-${letter.toLowerCase()} {width: ${width}px;}`
`${cssPrefix} .gen-text-${letter.toLowerCase()} {width: ${width}px;}`
);
cssRules.push(
`${CSS_PREFIX} .selected .gen-text-${letter.toLowerCase()} {width: ${selectedWidth}px;}`
`${cssPrefix} .selected .gen-text-${letter.toLowerCase()} {width: ${selectedWidth}px;}`
);
});
}
@ -122,7 +123,7 @@ function cssRulesFromProps(props) {
// Maybe our CSS name spacing should be based on some other class/id
// than the one we use for defining the main div.
// That way it could be shared by both the player and the context menu.
selector.startsWith("#webamp-context-menu") ? "" : CSS_PREFIX
selector.startsWith("#webamp-context-menu") ? "" : cssPrefix
} ${selector} {cursor: url(${cursorUrl}), auto}`
);
});
@ -133,7 +134,7 @@ function cssRulesFromProps(props) {
// This alternate number file requires that the minus sign be
// formatted differently.
cssRules.push(
`${CSS_PREFIX} .status #time #minus-sign { top: 0px; left: -1px; width: 9px; height: 13px; }`
`${cssPrefix} .status #time #minus-sign { top: 0px; left: -1px; width: 9px; height: 13px; }`
);
}
@ -141,24 +142,24 @@ function cssRulesFromProps(props) {
if (polygons) {
const matcher = mapRegionNamesToMatcher[regionName];
const id = mapRegionNamesToIds[regionName];
cssRules.push(`${CSS_PREFIX} ${matcher} { clip-path: url(#${id}); }`);
cssRules.push(`${cssPrefix} ${matcher} { clip-path: url(#${id}); }`);
}
}
// TODO: Find a way to make this declarative.
cssRules.push(
`#webamp-media-library {
`${cssPrefix} #webamp-media-library {
background-color: ${props.skinGenExColors.windowBackground};
color: ${props.skinGenExColors.windowText};
}`
);
cssRules.push(
`#webamp-media-library input {
`${cssPrefix} #webamp-media-library input {
caret-color: ${props.skinGenExColors.windowText};
}`
);
cssRules.push(
`#webamp-media-library .webamp-media-library-item {
`${cssPrefix} #webamp-media-library .webamp-media-library-item {
color: ${props.skinGenExColors.itemForeground};
background-color: ${props.skinGenExColors.itemBackground};
border-right: 1px solid ${props.skinGenExColors.divider};
@ -166,37 +167,37 @@ function cssRulesFromProps(props) {
}`
);
cssRules.push(
`#webamp-media-library button {
`${cssPrefix} #webamp-media-library button {
color: ${props.skinGenExColors.buttonText};
}`
);
cssRules.push(
`#webamp-media-library .webamp-media-library-vertical-divider {
`${cssPrefix} #webamp-media-library .webamp-media-library-vertical-divider {
}`
);
cssRules.push(
`#webamp-media-library .webamp-media-library-vertical-divider-line,
`${cssPrefix} #webamp-media-library .webamp-media-library-vertical-divider-line,
#webamp-media-library .webamp-media-library-horizontal-divider-line
{
background-color: ${props.skinGenExColors.divider};
}`
);
cssRules.push(
`#webamp-media-library .webamp-media-library-table {
`${cssPrefix} #webamp-media-library .webamp-media-library-table {
color: ${props.skinGenExColors.itemForeground};
background-color: ${props.skinGenExColors.itemBackground};
}`
);
cssRules.push(
`#webamp-media-library .webamp-media-library-table thead {
`${cssPrefix} #webamp-media-library .webamp-media-library-table thead {
color: ${props.skinGenExColors.listHeaderText};
background-color: ${props.skinGenExColors.listHeaderBackground};
}`
);
cssRules.push(
`#webamp-media-library .webamp-media-library-table thead th {
`${cssPrefix} #webamp-media-library .webamp-media-library-table thead th {
border-top: 1px solid ${props.skinGenExColors.listHeaderFrameTopAndLeft};
border-left: 1px solid ${
props.skinGenExColors.listHeaderFrameTopAndLeft
@ -229,11 +230,14 @@ const Skin = props => {
if (cssRules == null) {
return null;
}
console.log(cssRules);
console.log(props.instanceId);
const clipPaths = clipPathsFromProps(props);
return (
<div>
<div id="">
<Css>{cssRules.join("\n")}</Css>
<ClipPaths>{clipPaths}</ClipPaths>
{props.children}
</div>
);
};

View file

@ -140,6 +140,7 @@ const storeHas = (
});
class Winamp {
_instanceClass: string;
_actionEmitter: Emitter;
_node: HTMLElement | null;
_disposable: Disposable;
@ -158,6 +159,7 @@ class Winamp {
}
constructor(options: Options & PrivateOptions) {
this._instanceClass = `webamp-instance-${Utils.uniqueId()}`;
this._node = null;
this._disposable = new Disposable();
this._actionEmitter = new Emitter();
@ -368,6 +370,7 @@ class Winamp {
ReactDOM.render(
<Provider store={this.store}>
<App
instanceClass={this._instanceClass}
media={this.media}
container={node}
filePickers={this.options.filePickers}