Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"no-eval": 2,
"no-implied-eval": 2,
"no-new-func": 2,
"guard-for-in": 2,
"guard-for-in": 0,
"eqeqeq": 1,
"no-else-return": 2,
"no-redeclare": 2,
Expand Down
92 changes: 90 additions & 2 deletions src/components/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,73 @@ export default class App extends Component {
store: this.props.store
};

elementsWithReplaceableCss = {
// Tables
"thead tr": {"background-color": this.props.config.css["color-table-background"]},
"tr[class*=even]": {"background-color": this.props.config.css["color-table-background"]},

// Purposes
"div[class*=purposes_purposeItem]": {
"background-color": this.props.config.css["color-secondary"],
"color": this.props.config.css["color-text-secondary"]
},
"div[class*=selectedPurpose]": {
"background-color": this.props.config.css["color-primary"],
"color": this.props.config.css["color-text-secondary"],
},

// Footer
"div[class*=footer_footer]": {
"border-top": "3px solid " + this.props.config.css["color-border"],
"background-color": this.props.config.css["color-background"]
},
"div[class*=footerV2_extended]": {"border-top": "3px solid " + this.props.config.css["color-border"]},
"div[class*=footerV2_container]": {"background-color": this.props.config.css["color-background"]},
"svg": {
"background-color": this.props.config.css["color-background"],
"fill": this.props.config.css["color-primary"]
},

// Vendors
"[class*=active]": {"color": this.props.config.css["color-primary"]},

// Application wide
"div[name^=content]": {
"box-shadow": "0 0 0 3px " + this.props.config.css["color-border"],
"background-color": this.props.config.css["color-background"]
},
":not([name*=ctrl])": {
"font-family": this.props.config.css["font-family"]
},
"[class*=primaryText]": {"color": this.props.config.css["color-text-primary"]},
"[class*=secondaryText]": {"color": this.props.config.css["color-text-secondary"]},
"a": {"color": this.props.config.css["color-linkColor"]},
"span[class*=isSelected] [class*=visualizationGlow]": {"background-color": this.props.config.css["color-primary"]},
"span[class*=isSelected] [class*=visualizationContainer]": {"background-color": this.props.config.css["color-primary"]},
"[class*=button]": {
"color": this.props.config.css["color-background"],
"background-color": this.props.config.css["color-primary"],
},
"[class*=button_invert]": {
"color": this.props.config.css["color-primary"],
"border": "2px solid " + this.props.config.css["color-primary"],
"background-color": this.props.config.css["color-background"]
},
};

updateCSSPrefs = () => {
const elems = this.elementsWithReplaceableCss;
for(let elem in elems) {
let cssRules = elems[elem];
let selectedEls = document.querySelectorAll(elem) || [];
selectedEls.forEach(function(currentEl) {
for(let cssProp in cssRules) {
currentEl.style[cssProp] = cssRules[cssProp];
}
})
}
};

onSave = () => {
const { store, notify } = this.props;
store.persist();
Expand All @@ -19,7 +86,6 @@ export default class App extends Component {
store.toggleFooterShowing(true);
};


updateState = (store) => {
this.setState({ store });
};
Expand All @@ -29,8 +95,24 @@ export default class App extends Component {
store.subscribe(this.updateState);
}

render(props, state) {
componentDidMount() {
const { store } = this.state;
const { config } = this.props;

if (config.css["custom-font-url"]) {
let head = document.head;
let link = document.createElement("link");
link.type = "text/css";
link.rel = "stylesheet";
link.href = config.css["custom-font-url"];
head.appendChild(link);
}

store.subscribe(this.updateCSSPrefs);
this.updateCSSPrefs();
}

render(props, state) {
const { store } = state;
const { config } = props;
const userLocalization = config.localization[currentLocale];
Expand All @@ -41,15 +123,21 @@ export default class App extends Component {
store={store}
localization={userLocalization}
onSave={this.onSave}
config={config}
updateCSSPrefs={this.updateCSSPrefs}
/>
<PopupFooter
store={store}
localization={userLocalization}
onSave={this.onSave}
config={config}
updateCSSPrefs={this.updateCSSPrefs}
/>
<Footer
store={store}
localization={userLocalization}
config={config}
updateCSSPrefs={this.updateCSSPrefs}
/>
</div>
);
Expand Down
30 changes: 23 additions & 7 deletions src/components/app.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { h, render } from 'preact';
import { expect } from 'chai';
import style from './app.less';
import Store from '../lib/store';

import config from '../lib/config';
import App from './app';

describe('App', () => {
Expand All @@ -25,14 +25,14 @@ describe('App', () => {


it('should render app content', () => {
render(<App store={new Store()} config={{localization: {}}} />, scratch);
render(<App store={new Store()} config={config} />, scratch);
expect(scratch.innerHTML).to.contain(style.gdpr);
});

it('add a listener to the store to receive updates', () => {
it('add listeners to the store to receive updates and to know when to update CSS', () => {
const store = new Store();
render(<App store={store} config={{localization: {}}} />, scratch);
expect(store.listeners.size).to.equal(1);
render(<App store={store} config={config} />, scratch);
expect(store.listeners.size).to.equal(2);
});

it('persist state on save', () => {
Expand All @@ -44,8 +44,8 @@ describe('App', () => {
let app;
render(<App
store={store}
config={config}
notify={notify}
config={{localization: {}}}
ref={ref => app = ref}
/>, scratch);

Expand All @@ -62,13 +62,29 @@ describe('App', () => {
let app;
render(<App
store={store}
config={config}
notify={() => {}}
config={{localization: {}}}
ref={ref => app = ref}
/>, scratch);

expect(app.state.store.vendorConsentData.selectedVendorIds).to.deep.equal(new Set());
store.selectVendor(1, true);
expect(app.state.store.vendorConsentData.selectedVendorIds).to.deep.equal(new Set([1]));
});

it('respects css config', () => {
const store = new Store();
config.update({ css: { 'font-family': 'MonoType' }});
let app;
render(<App
store={store}
config={config}
notify={() => {}}
ref={ref => app = ref}
/>, scratch);

expect(app.props.config.css['font-family']).to.equal('MonoType');
expect(scratch.style['font-family']).to.equal('MonoType');
expect(scratch.innerHTML).to.contain('style="font-family: MonoType;"');
});
});
4 changes: 4 additions & 0 deletions src/components/closebutton/closebutton.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ export default class CloseButton extends Component {
hasBorder: true
};

componentDidMount() {
this.props.updateCSSPrefs();
}

render(props) {
const {
onClick,
Expand Down
12 changes: 9 additions & 3 deletions src/components/footer/footer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,27 @@ export default class Footer extends Component {
showConsentTool();
};

componentDidMount() {
this.props.updateCSSPrefs();
}

render(props) {
const { store, localization } = props;
const { store, localization, config, updateCSSPrefs } = props;
const { isFooterShowing } = store;

return (
<div
class={style.footer}
style={{ display: isFooterShowing ? 'flex' : 'none' }}
style={{ display: isFooterShowing && config.showFooterAfterSubmit ? 'flex' : 'none' }}
>
<CloseButton
hasBorder={false}
class={style.close}
onClick={this.handleClose}
config={config}
updateCSSPrefs={updateCSSPrefs}
/>
<LocalLabel providedValue={localization && localization.footer ? localization.footer.closedMessage : ''} localizeKey='closedMessage' class={style.message}>A reminder you can control your user privacy preferences</LocalLabel>
<LocalLabel providedValue={localization && localization.footer ? localization.footer.closedMessage : ''} localizeKey='closedMessage' class={style.message + " primaryText"}>A reminder you can control your user privacy preferences</LocalLabel>
<a class={style.openConsent} onClick={this.handleShowConsent}>
<LocalLabel providedValue={localization && localization.footer ? localization.footer.closedMessageLink : ''} localizeKey='closedMessageLink'>here</LocalLabel>
</a>
Expand Down
1 change: 0 additions & 1 deletion src/components/footer/footer.less
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
align-items: center;
justify-content: center;
background: white;
border-top: 2px solid @color-primary;

.openConsent {
margin-left: 3px;
Expand Down
14 changes: 12 additions & 2 deletions src/components/popup/details/details.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,19 @@ export default class Details extends Component {
}
};

componentDidMount() {
this.props.updateCSSPrefs();
};

render(props, state) {
const {
onCancel,
onSave,
onClose,
store,
localization
localization,
config,
updateCSSPrefs
} = props;

const {
Expand All @@ -89,7 +95,7 @@ export default class Details extends Component {
return (
<div class={style.details}>
<div class={style.header}>
<LocalLabel class={style.title} providedValue={localization && localization.details ? localization.details.title : ''} localizeKey='title'>Privacy Preferences</LocalLabel>
<LocalLabel class={style.title + " primaryText"} providedValue={localization && localization.details ? localization.details.title : ''} localizeKey='title'>Privacy Preferences</LocalLabel>
</div>
<div class={style.body}>
<Panel selectedIndex={selectedPanelIndex}>
Expand All @@ -104,6 +110,8 @@ export default class Details extends Component {
selectPurpose={selectPurpose}
selectCustomPurpose={selectCustomPurpose}
onShowVendors={this.handleShowVendors}
config={config}
updateCSSPrefs={updateCSSPrefs}
/>
<Vendors
localization={localization}
Expand All @@ -113,6 +121,8 @@ export default class Details extends Component {
vendors={vendors}
onShowPurposes={this.handleShowPurposes}
onHandleEnableAll={this.handleEnableAll}
config={config}
updateCSSPrefs={updateCSSPrefs}
/>
</Panel>
</div>
Expand Down
3 changes: 2 additions & 1 deletion src/components/popup/details/details.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ describe('Details', () => {
it('should render with purpose panel initially', () => {
const store = new Store();
store.isConsentToolShowing = false;
const details = <Details store={store} />;
const details = <Details updateCSSPrefs={() => {}} store={store} />;
expect(details).to.contain(purposesStyle.purposes);
});

Expand All @@ -26,6 +26,7 @@ describe('Details', () => {

let details;
render(<Details
updateCSSPrefs={() => {}}
store={store}
ref={ref => details = ref}
/>, scratch);
Expand Down
Loading