1
0
mirror of https://github.com/gorhill/uBlock.git synced 2024-09-29 14:17:11 +02:00
uBlock/src/js/dom.js

191 lines
5.5 KiB
JavaScript
Raw Normal View History

/*******************************************************************************
uBlock Origin - a browser extension to block requests.
Copyright (C) 2014-present Raymond Hill
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see {http://www.gnu.org/licenses/}.
Home: https://github.com/gorhill/uBlock
*/
/* jshint esversion:11 */
'use strict';
/******************************************************************************/
const normalizeTarget = target => {
if ( typeof target === 'string' ) { return Array.from(qsa$(target)); }
if ( target instanceof Element ) { return [ target ]; }
if ( target === null ) { return []; }
if ( Array.isArray(target) ) { return target; }
return Array.from(target);
};
const makeEventHandler = (selector, callback) => {
return function(event) {
const dispatcher = event.currentTarget;
if (
dispatcher instanceof HTMLElement === false ||
typeof dispatcher.querySelectorAll !== 'function'
) {
return;
}
const receiver = event.target;
const ancestor = receiver.closest(selector);
if (
ancestor === receiver &&
ancestor !== dispatcher &&
dispatcher.contains(ancestor)
) {
callback.call(receiver, event);
}
};
};
/******************************************************************************/
class dom {
static attr(target, attr, value = undefined) {
for ( const elem of normalizeTarget(target) ) {
if ( value === undefined ) {
return elem.getAttribute(attr);
}
if ( value === null ) {
elem.removeAttribute(attr);
} else {
elem.setAttribute(attr, value);
}
}
}
static clone(target) {
return normalizeTarget(target)[0].cloneNode(true);
}
static create(a) {
if ( typeof a === 'string' ) {
return document.createElement(a);
}
}
static text(target, text) {
for ( const elem of normalizeTarget(target) ) {
elem.textContent = text;
}
}
static remove(target) {
for ( const elem of normalizeTarget(target) ) {
elem.remove();
}
}
// target, type, callback, [options]
// target, type, subtarget, callback, [options]
static on(target, type, subtarget, callback, options) {
if ( typeof subtarget === 'function' ) {
options = callback;
callback = subtarget;
subtarget = undefined;
if ( typeof options === 'boolean' ) {
options = { capture: true };
}
} else {
callback = makeEventHandler(subtarget, callback);
if ( options === undefined || typeof options === 'boolean' ) {
options = { capture: true };
} else {
options.capture = true;
}
}
const targets = target instanceof Window || target instanceof Document
? [ target ]
: normalizeTarget(target);
for ( const elem of targets ) {
elem.addEventListener(type, callback, options);
}
}
static off(target, type, callback, options) {
if ( typeof callback !== 'function' ) { return; }
if ( typeof options === 'boolean' ) {
options = { capture: true };
}
const targets = target instanceof Window || target instanceof Document
? [ target ]
: normalizeTarget(target);
for ( const elem of targets ) {
elem.removeEventListener(type, callback, options);
}
}
}
dom.cl = class {
static add(target, name) {
for ( const elem of normalizeTarget(target) ) {
elem.classList.add(name);
}
}
static remove(target, name) {
for ( const elem of normalizeTarget(target) ) {
elem.classList.remove(name);
}
}
static toggle(target, name, state) {
let r;
for ( const elem of normalizeTarget(target) ) {
r = elem.classList.toggle(name, state);
}
return r;
}
static has(target, name) {
for ( const elem of normalizeTarget(target) ) {
if ( elem.classList.contains(name) ) {
return true;
}
}
return false;
}
};
/******************************************************************************/
function qs$(a, b) {
if ( typeof a === 'string') {
return document.querySelector(a);
}
return a.querySelector(b);
}
function qsa$(a, b) {
if ( typeof a === 'string') {
return document.querySelectorAll(a);
}
return a.querySelectorAll(b);
}
dom.root = qs$(':root');
dom.html = document.documentElement;
dom.head = document.head;
dom.body = document.body;
/******************************************************************************/
export { dom, qs$, qsa$ };