2018-01-29 18:34:31 +01:00
|
|
|
/**
|
|
|
|
* BetterDiscord Client DOM Module
|
2018-01-29 19:15:58 +01:00
|
|
|
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
|
2018-01-29 18:34:31 +01:00
|
|
|
* All rights reserved.
|
2018-01-29 19:15:58 +01:00
|
|
|
* https://betterdiscord.net
|
2018-01-29 18:34:31 +01:00
|
|
|
*
|
|
|
|
* This source code is licensed under the MIT license found in the
|
|
|
|
* LICENSE file in the root directory of this source tree.
|
|
|
|
*/
|
|
|
|
|
|
|
|
class BdNode {
|
2018-01-29 18:56:48 +01:00
|
|
|
constructor(tag, className, id) {
|
2018-01-29 18:34:31 +01:00
|
|
|
this.element = document.createElement(tag);
|
|
|
|
if (className) this.element.className = className;
|
2018-01-29 18:56:48 +01:00
|
|
|
if (id) this.element.id = id;
|
2018-01-29 18:34:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
appendTo(e) {
|
|
|
|
const el = DOM.getElement(e);
|
|
|
|
if (!el) return null;
|
|
|
|
el.append(this.element);
|
|
|
|
return this.element;
|
|
|
|
}
|
|
|
|
|
|
|
|
prependTo(e) {
|
|
|
|
const el = DOM.getElement(e);
|
|
|
|
if (!el) return null;
|
|
|
|
el.prepend(this.element);
|
|
|
|
return this.element;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-31 14:35:22 +01:00
|
|
|
class DOMObserver {
|
|
|
|
|
|
|
|
constructor() {
|
|
|
|
this.observe = this.observe.bind(this);
|
|
|
|
this.subscribe = this.subscribe.bind(this);
|
|
|
|
this.observerCallback = this.observerCallback.bind(this);
|
|
|
|
this.observer = new MutationObserver(this.observerCallback);
|
|
|
|
}
|
|
|
|
|
|
|
|
observerCallback(mutations) {
|
|
|
|
this.subscriptions.forEach(sub => {
|
|
|
|
try {
|
|
|
|
const f = mutations.find(sub.filter);
|
|
|
|
if (f) sub.callback(f);
|
|
|
|
} catch (err) { }
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
observe() {
|
|
|
|
this.observer.observe(this.root, this.options);
|
|
|
|
}
|
|
|
|
|
|
|
|
get root() {
|
|
|
|
return document.getElementById('app-mount');
|
|
|
|
}
|
|
|
|
|
|
|
|
get options() {
|
|
|
|
return { attributes: true, childList: true, subtree: true };
|
|
|
|
}
|
|
|
|
|
|
|
|
get subscriptions() {
|
|
|
|
return this._subscriptions || (this._subscriptions = []);
|
|
|
|
}
|
|
|
|
|
|
|
|
subscribe(id, filter, callback) {
|
|
|
|
if (this.subscriptions.find(sub => sub.id === id)) return;
|
|
|
|
this.subscriptions.push({
|
|
|
|
id,
|
|
|
|
filter,
|
|
|
|
callback
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
unsubscribe(id) {
|
|
|
|
const index = this.subscriptions.find(sub => sub.id === id);
|
|
|
|
if (index < 0) return;
|
|
|
|
this.subscriptions.splice(index, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2018-01-29 18:34:31 +01:00
|
|
|
class DOM {
|
|
|
|
|
2018-01-31 14:35:22 +01:00
|
|
|
static get observer() {
|
|
|
|
return this._observer || (this._observer = new DOMObserver());
|
|
|
|
}
|
|
|
|
|
2018-01-29 18:34:31 +01:00
|
|
|
static get bdHead() {
|
|
|
|
return this.getElement('bd-head') || this.createElement('bd-head').appendTo('head');
|
|
|
|
}
|
|
|
|
static get bdBody() {
|
|
|
|
return this.getElement('bd-body') || this.createElement('bd-body').appendTo('body');
|
|
|
|
}
|
|
|
|
static get bdStyles() {
|
|
|
|
return this.getElement('bd-styles') || this.createElement('bd-styles').appendTo(this.bdHead);
|
|
|
|
}
|
|
|
|
static get bdThemes() {
|
|
|
|
return this.getElement('bd-themes') || this.createElement('bd-themes').appendTo(this.bdHead);
|
|
|
|
}
|
|
|
|
static get bdTooltips() {
|
|
|
|
return this.getElement('bd-tooltips') || this.createElement('bd-tooltips').appendTo(this.bdBody);
|
|
|
|
}
|
|
|
|
|
|
|
|
static getElement(e) {
|
|
|
|
if (e instanceof BdNode) return e.element;
|
|
|
|
if (e instanceof window.Node) return e;
|
|
|
|
if ('string' !== typeof e) return null;
|
|
|
|
return document.querySelector(e);
|
|
|
|
}
|
|
|
|
|
2018-01-29 18:56:48 +01:00
|
|
|
static createElement(tag = 'div', className = null, id = null) {
|
|
|
|
return new BdNode(tag, className, id);
|
2018-01-29 18:34:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static deleteStyle(id) {
|
|
|
|
const exists = this.getElement(`bd-styles > #${id}`);
|
|
|
|
if (exists) exists.remove();
|
|
|
|
}
|
|
|
|
|
|
|
|
static injectStyle(css, id) {
|
|
|
|
this.deleteStyle(id);
|
|
|
|
this.bdStyles.append(this.createStyle(css, id));
|
|
|
|
}
|
|
|
|
|
2018-01-30 12:14:16 +01:00
|
|
|
static getStyleCss(id) {
|
|
|
|
const exists = this.getElement(`bd-styles > #${id}`);
|
2018-01-30 12:20:42 +01:00
|
|
|
return exists ? exists.textContent : '';
|
2018-01-30 12:14:16 +01:00
|
|
|
}
|
|
|
|
|
2018-01-29 18:34:31 +01:00
|
|
|
static deleteTheme(id) {
|
|
|
|
const exists = this.getElement(`bd-themes > #${id}`);
|
|
|
|
if (exists) exists.remove();
|
|
|
|
}
|
|
|
|
|
|
|
|
static injectTheme(css, id) {
|
|
|
|
this.deleteTheme(id);
|
|
|
|
this.bdThemes.append(this.createStyle(css, id));
|
|
|
|
}
|
|
|
|
|
|
|
|
static createStyle(css, id) {
|
|
|
|
const style = document.createElement('style');
|
|
|
|
style.id = id;
|
|
|
|
style.type = 'text/css';
|
|
|
|
style.appendChild(document.createTextNode(css));
|
|
|
|
return style;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-29 19:15:58 +01:00
|
|
|
export default DOM;
|