1 |
|
2 |
|
3 | import { assign } from './utils';
|
4 | import { WidgetModel, WidgetView } from './widget';
|
5 |
|
6 |
|
7 |
|
8 |
|
9 | export class StyleModel extends WidgetModel {
|
10 | defaults() {
|
11 | const Derived = this.constructor;
|
12 | return assign(super.defaults(), {
|
13 | _model_name: 'StyleModel',
|
14 | _view_name: 'StyleView',
|
15 | }, Object.keys(Derived.styleProperties).reduce((obj, key) => {
|
16 | obj[key] = Derived.styleProperties[key].default;
|
17 | return obj;
|
18 | }, {}));
|
19 | }
|
20 | }
|
21 | StyleModel.styleProperties = {};
|
22 | export class StyleView extends WidgetView {
|
23 | |
24 |
|
25 |
|
26 | initialize(parameters) {
|
27 | this._traitNames = [];
|
28 | super.initialize(parameters);
|
29 |
|
30 | const ModelType = this.model.constructor;
|
31 | for (const key of Object.keys(ModelType.styleProperties)) {
|
32 | this.registerTrait(key);
|
33 | }
|
34 |
|
35 | this.style();
|
36 | }
|
37 | |
38 |
|
39 |
|
40 |
|
41 | registerTrait(trait) {
|
42 | this._traitNames.push(trait);
|
43 |
|
44 | this.listenTo(this.model, 'change:' + trait, (model, value) => {
|
45 | this.handleChange(trait, value);
|
46 | });
|
47 | }
|
48 | |
49 |
|
50 |
|
51 | handleChange(trait, value) {
|
52 |
|
53 | const parent = this.options.parent;
|
54 | if (parent) {
|
55 | const ModelType = this.model.constructor;
|
56 | const styleProperties = ModelType.styleProperties;
|
57 | const attribute = styleProperties[trait].attribute;
|
58 | const selector = styleProperties[trait].selector;
|
59 | const elements = selector
|
60 | ? parent.el.querySelectorAll(selector)
|
61 | : [parent.el];
|
62 | if (value === null) {
|
63 | for (let i = 0; i !== elements.length; ++i) {
|
64 | elements[i].style.removeProperty(attribute);
|
65 | }
|
66 | }
|
67 | else {
|
68 | for (let i = 0; i !== elements.length; ++i) {
|
69 | elements[i].style.setProperty(attribute, value);
|
70 | }
|
71 | }
|
72 | }
|
73 | else {
|
74 | console.warn('Style not applied because a parent view does not exist');
|
75 | }
|
76 | }
|
77 | |
78 |
|
79 |
|
80 | style() {
|
81 | for (const trait of this._traitNames) {
|
82 | this.handleChange(trait, this.model.get(trait));
|
83 | }
|
84 | }
|
85 | |
86 |
|
87 |
|
88 | unstyle() {
|
89 | const parent = this.options.parent;
|
90 | const ModelType = this.model.constructor;
|
91 | const styleProperties = ModelType.styleProperties;
|
92 | this._traitNames.forEach((trait) => {
|
93 | if (parent) {
|
94 | const attribute = styleProperties[trait].attribute;
|
95 | const selector = styleProperties[trait].selector;
|
96 | const elements = selector
|
97 | ? parent.el.querySelectorAll(selector)
|
98 | : [parent.el];
|
99 | for (let i = 0; i !== elements.length; ++i) {
|
100 | elements[i].style.removeProperty(attribute);
|
101 | }
|
102 | }
|
103 | else {
|
104 | console.warn('Style not removed because a parent view does not exist');
|
105 | }
|
106 | }, this);
|
107 | }
|
108 | }
|
109 |
|
\ | No newline at end of file |