Skip to content

Commit 7d8cf78

Browse files
authored
Merge pull request #46 from typecode/issue-15
#15 - Custom color config & handling
2 parents c1ce7d8 + e537ae9 commit 7d8cf78

File tree

14 files changed

+256
-11
lines changed

14 files changed

+256
-11
lines changed

README.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ Setting up Typester on your page is as easy as:
2929
```
3030
import Typester from 'typester-editor'
3131
32-
new Typester({ el: document.querySelector('[contenteditable]') }) // Where document.querySelector(...) is a single DOM element.
32+
const typesterInstance = new Typester({ el: document.querySelector('[contenteditable]') }) // Where document.querySelector(...) is a single DOM element.
33+
34+
// If you need to tear down for any reason:
35+
typesterInstance.destroy();
3336
```
3437

3538
### Configuration
@@ -43,6 +46,15 @@ new Typester({
4346
configs: {
4447
toolbar: {
4548
buttons: ['bold', 'italic', 'h1', 'h2', 'orderedlist', 'unorderedlist', 'quote', 'link']
49+
},
50+
51+
styles: {
52+
colors: {
53+
flyoutBg: 'rgb(32, 31, 32)',
54+
menuItemIcon: 'rgb(255, 255, 255)',
55+
menuItemHover: 'rgb(0, 174, 239)',
56+
menuItemActive: 'rgb(0, 156, 215)'
57+
}
4658
}
4759
}
4860
});

src/scripts/config/styles.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export default {
2+
colors: {
3+
flyoutBg: 'rgb(32, 31, 32)',
4+
menuItemIcon: 'rgb(255, 255, 255)',
5+
menuItemHover: 'rgb(0, 174, 239)',
6+
menuItemActive: 'rgb(0, 156, 215)'
7+
}
8+
};

src/scripts/containers/AppContainer.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,15 @@ const AppContainer = Container({
116116
*/
117117
handleBlur () {
118118
// Should the container require to do anything in particular here
119+
},
120+
121+
/**
122+
* Destroy the entire Typeset instance
123+
* @func destroy
124+
*/
125+
destroy () {
126+
const { mediator } = this;
127+
mediator.emit('app:destroy');
119128
}
120129
}
121130
});

src/scripts/containers/UIContainer.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import Container from '../core/Container';
1919
import Toolbar from '../modules/Toolbar';
2020
import Flyout from '../modules/Flyout';
2121
import Mouse from '../modules/Mouse';
22+
import Styles from '../modules/Styles';
2223

2324
/**
2425
* @constructor UIContainer
@@ -32,7 +33,7 @@ const UIContainer = Container({
3233
/**
3334
* Child Modules: [{@link modules/Flyout}, {@link modules/Toolbar}]
3435
* Note: The Toobar is instantiated with the document body set as it's dom.el.
35-
* @enum {Array<{class:Module}>} modules
36+
* @enum {Array<{class:Module}>} modules
3637
*/
3738
modules: [
3839
{
@@ -48,6 +49,9 @@ const UIContainer = Container({
4849
},
4950
{
5051
class: Mouse
52+
},
53+
{
54+
class: Styles
5155
}
5256
]
5357
});

src/scripts/core/Container.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,9 @@ const Container = function Container(containerObj) {
166166
return {
167167
setMediatorParent (parentMediator) {
168168
mediator.setParent(parentMediator);
169-
}
169+
},
170+
171+
destroy: boundMethods.destroy
170172
};
171173
}
172174
};

src/scripts/core/Mediator.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ const Mediator = function (opts={}) {
122122
if (requestHandler) {
123123
return requestHandler(options);
124124
}
125+
},
126+
127+
destroy () {
128+
requests.handlers = {};
125129
}
126130
};
127131

@@ -152,6 +156,10 @@ const Mediator = function (opts={}) {
152156
if (commandHandler) {
153157
commandHandler(options);
154158
}
159+
},
160+
161+
destroy () {
162+
commands.handlers = {};
155163
}
156164
};
157165

@@ -176,9 +184,18 @@ const Mediator = function (opts={}) {
176184

177185
emit (eventKey, options) {
178186
const eventHandlers = events.getHandlers(eventKey);
187+
179188
if (eventHandlers.length) {
180189
eventHandlers.forEach((eventHandler) => eventHandler(options));
181190
}
191+
192+
if (eventKey === 'app:destroy') {
193+
fn.destroy();
194+
}
195+
},
196+
197+
destroy () {
198+
events.handlers = {};
182199
}
183200
};
184201

@@ -370,6 +387,12 @@ const Mediator = function (opts={}) {
370387

371388
getId () {
372389
return internal.id;
390+
},
391+
392+
destroy () {
393+
requests.destroy();
394+
commands.destroy();
395+
events.destroy();
373396
}
374397
};
375398

src/scripts/core/Module.js

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ const Module = function (moduleObj) {
112112
moduleUtils.bindDomEvents(handlerMethods, context);
113113
},
114114

115+
deregisterDomHandlers (domHandlersMap, context) {
116+
let handlerMethods = moduleUtils.getHandlerMethods(domHandlersMap, context);
117+
moduleUtils.unbindDomEvents(handlerMethods, context);
118+
},
119+
115120
getHandlerMethods (handlerMap, context) {
116121
let routedHandlers = {};
117122

@@ -171,6 +176,22 @@ const Module = function (moduleObj) {
171176
});
172177
},
173178

179+
unbindDomEvents (handlers, context) {
180+
const { dom } = context;
181+
182+
if (!dom) {
183+
return;
184+
}
185+
186+
Object.keys(handlers).forEach((eventElKey) => {
187+
const [eventKey, elemKey] = eventElKey.split(' @');
188+
const elem = elemKey ? dom[elemKey][0] : dom.el[0];
189+
const eventHandler = handlers[eventElKey];
190+
191+
elem.removeEventListener(eventKey, eventHandler);
192+
});
193+
},
194+
174195
mergeProps (defaultProps, props={}) {
175196
let mergedProps = {};
176197

@@ -248,6 +269,10 @@ const Module = function (moduleObj) {
248269
context.setup();
249270
}
250271

272+
context.mediator.registerHandler('event', 'app:destroy', function () {
273+
moduleProto.destroyModule(opts);
274+
});
275+
251276
if (moduleHandlers) {
252277
moduleUtils.registerHandlers(opts.mediator, moduleHandlers, context);
253278
}
@@ -280,8 +305,12 @@ const Module = function (moduleObj) {
280305
}
281306
},
282307

283-
destroyModule () {
308+
destroyModule (opts) {
309+
const { context } = opts;
284310

311+
if (moduleHandlers.domEvents) {
312+
moduleUtils.deregisterDomHandlers(moduleHandlers.domEvents, context);
313+
}
285314
}
286315
};
287316

src/scripts/modules/Config.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import Module from '../core/Module';
22
import toolbarConfig from '../config/toolbar';
33
import config from '../config/config';
4+
import stylesConfig from '../config/styles';
45

56
const Config = Module({
67
name: 'Config',
78
props: {},
8-
acceptsConfigs: ['toolbar'],
9+
acceptsConfigs: ['toolbar', 'styles'],
910

1011
handlers: {
1112
requests: {
@@ -16,7 +17,8 @@ const Config = Module({
1617
'config:toolbar:listTags' : 'getToolbarListTags',
1718
'config:toolbar:preventNewlineDefault' : 'getToolbarPreventNewlineDefault',
1819
'config:blockElementNames' : 'getConfigBlockElementNames',
19-
'config:defaultBlock' : 'getDefaultBlock'
20+
'config:defaultBlock' : 'getDefaultBlock',
21+
'config:styles': 'getStyles'
2022
}
2123
},
2224

@@ -70,6 +72,13 @@ const Config = Module({
7072

7173
getDefaultBlock () {
7274
return config.defaultBlock;
75+
},
76+
77+
getStyles () {
78+
const { configs } = this;
79+
return {
80+
colors: Object.assign({}, stylesConfig.colors, configs.styles.colors)
81+
};
7382
}
7483
}
7584
});

src/scripts/modules/Styles.js

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// jshint strict: false
2+
3+
/**
4+
* Styles -
5+
* Handle the creation and embedding of custom styles.
6+
* @access protected
7+
* @module modules/Styles
8+
*/
9+
10+
import Module from '../core/Module';
11+
12+
const Styles = Module({
13+
name: 'Styles',
14+
15+
props: {
16+
stylesheet: null,
17+
},
18+
19+
handlers: {
20+
events: {
21+
'app:destroy': 'destroy'
22+
}
23+
},
24+
25+
methods: {
26+
setup () {
27+
this.createStylesheet();
28+
},
29+
30+
init () {
31+
const { mediator } = this;
32+
const config = mediator.get('config:styles');
33+
let stylesheetContent = this.stylesTemplate(config);
34+
35+
this.appendStylesheet();
36+
this.updateStylesheet(stylesheetContent);
37+
},
38+
39+
stylesTemplate (config) {
40+
return `
41+
.typester-toolbar .typester-menu-item,
42+
.typester-input-form input[type=text],
43+
.typester-link-display a,
44+
.typester-input-form button {
45+
color: ${config.colors.menuItemIcon};
46+
}
47+
48+
.typester-toolbar .typester-menu-item svg,
49+
.typester-link-display .typester-link-edit svg,
50+
.typester-input-form button svg {
51+
fill: ${config.colors.menuItemIcon};
52+
}
53+
54+
.typester-input-form button svg {
55+
stroke: ${config.colors.menuItemIcon};
56+
}
57+
58+
.typester-toolbar .typester-menu-item:hover,
59+
.typester-link-display .typester-link-edit:hover
60+
.typester-input-form button:hover {
61+
background: ${config.colors.menuItemHover};
62+
}
63+
64+
.typester-toolbar .typester-menu-item.s--active {
65+
background: ${config.colors.menuItemActive};
66+
}
67+
68+
.typester-flyout .typester-flyout-content {
69+
background: ${config.colors.flyoutBg};
70+
}
71+
72+
.typester-flyout.place-above .typester-flyout-arrow {
73+
border-top-color: ${config.colors.flyoutBg};
74+
}
75+
76+
.typester-flyout.place-below .typester-flyout-arrow {
77+
border-bottom-color: ${config.colors.flyoutBg};
78+
}
79+
`;
80+
},
81+
82+
createStylesheet () {
83+
this.stylesheet = document.createElement('style');
84+
},
85+
86+
appendStylesheet () {
87+
document.head.appendChild(this.stylesheet);
88+
},
89+
90+
updateStylesheet (stylesheetContent) {
91+
this.stylesheet.textContent = stylesheetContent;
92+
},
93+
94+
removeStylesheet () {
95+
document.head.removeChild(this.stylesheet);
96+
},
97+
98+
destroy () {
99+
this.removeStylesheet();
100+
}
101+
}
102+
});
103+
104+
export default Styles;

src/templates/inputForm.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<button type='submit'>
44
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
55
viewBox="0 180 20 20" enable-background="new 0 180 20 20" xml:space="preserve" height="20px" width="20px">
6-
<polyline class="checkmark-2" fill="none" stroke="#FFFFFF" stroke-width="5.3" stroke-miterlimit="10" points="1.9,188.8 7.5,194.4 18.1,183.9 "/>
6+
<polyline class="checkmark-2" fill="none" stroke-width="5.3" stroke-miterlimit="10" points="1.9,188.8 7.5,194.4 18.1,183.9 "/>
77
</svg>
88
</button>
99
<button type='cancel'>

0 commit comments

Comments
 (0)