text: /* global document */
  /* global window */
  class Element {
      constructor(tag, className = '') {
          if (typeof tag === 'string') {
              this.el = document.createElement(tag);
              this.el.className = className;
          } else {
              this.el = tag;
          }
          this.data = {};
      }
  
      data(key, value) {
          if (value !== undefined) {
              this.data[key] = value;
              return this;
          }
          return this.data[key];
      }
  
      on(eventNames, handler) {
          const [fen, ...oen] = eventNames.split('.');
          let eventName = fen;
          if (
              eventName === 'mousewheel' &&
              /Firefox/i.test(window.navigator.userAgent)
          ) {
              eventName = 'DOMMouseScroll';
          }
          this.el.addEventListener(eventName, (evt) => {
              handler(evt);
              for (let i = 0; i < oen.length; i += 1) {
                  const k = oen[i];
                  if (k === 'left' && evt.button !== 0) {
                      return;
                  }
                  if (k === 'right' && evt.button !== 2) {
                      return;
                  }
                  if (k === 'stop') {
                      evt.stopPropagation();
                  }
              }
          });
          return this;
      }
  
      offset(value) {
          if (value !== undefined) {
              Object.keys(value).forEach((k) => {
                  this.css(k, `${value[k]}px`);
              });
              return this;
          }
          const { offsetTop, offsetLeft, offsetHeight, offsetWidth } = this.el;
          return {
              top: offsetTop,
              left: offsetLeft,
              height: offsetHeight,
              width: offsetWidth,
          };
      }
  
      scroll(v) {
          const { el } = this;
          if (v !== undefined) {
              if (v.left !== undefined) {
                  el.scrollLeft = v.left;
              }
              if (v.top !== undefined) {
                  el.scrollTop = v.top;
              }
          }
          return { left: el.scrollLeft, top: el.scrollTop };
      }
  
      box() {
          return this.el.getBoundingClientRect();
      }
  
      parent() {
          return new Element(this.el.parentNode);
      }
  
      children(...eles) {
          if (arguments.length === 0) {
              return this.el.childNodes;
          }
          eles.forEach((ele) => this.child(ele));
          return this;
      }
  
      removeChild(el) {
          this.el.removeChild(el);
      }
  
      /*
    first() {
      return this.el.firstChild;
    }
  
    last() {
      return this.el.lastChild;
    }
  
    remove(ele) {
      return this.el.removeChild(ele);
    }
  
    prepend(ele) {
      const { el } = this;
      if (el.children.length > 0) {
        el.insertBefore(ele, el.firstChild);
      } else {
        el.appendChild(ele);
      }
      return this;
    }
  
    prev() {
      return this.el.previousSibling;
    }
  
    next() {
      return this.el.nextSibling;
    }
    */
  
      child(arg) {
          let ele = arg;
          if (typeof arg === 'string') {
              ele = document.createTextNode(arg);
          } else if (arg instanceof Element) {
              ele = arg.el;
          }
          this.el.appendChild(ele);
          return this;
      }
  
      contains(ele) {
          return this.el.contains(ele);
      }
  
      className(v) {
          if (v !== undefined) {
              this.el.className = v;
              return this;
          }
          return this.el.className;
      }
  
      addClass(name) {
          this.el.classList.add(name);
          return this;
      }
  
      hasClass(name) {
          return this.el.classList.contains(name);
      }
  
      removeClass(name) {
          this.el.classList.remove(name);
          return this;
      }
  
      toggle(cls = 'active') {
          return this.toggleClass(cls);
      }
  
      toggleClass(name) {
          return this.el.classList.toggle(name);
      }
  
      active(flag = true, cls = 'active') {
          if (flag) this.addClass(cls);
          else this.removeClass(cls);
          return this;
      }
  
      checked(flag = true) {
          this.active(flag, 'checked');
          return this;
      }
  
      disabled(flag = true) {
          if (flag) this.addClass('disabled');
          else this.removeClass('disabled');
          return this;
      }
  
      // key, value
      // key
      // {k, v}...
      attr(key, value) {
          if (value !== undefined) {
              this.el.setAttribute(key, value);
          } else {
              if (typeof key === 'string') {
                  return this.el.getAttribute(key);
              }
              Object.keys(key).forEach((k) => {
                  this.el.setAttribute(k, key[k]);
              });
          }
          return this;
      }
  
      removeAttr(key) {
          this.el.removeAttribute(key);
          return this;
      }
  
      html(content) {
          if (content !== undefined) {
              this.el.innerHTML = content;
              return this;
          }
          return this.el.innerHTML;
      }
  
      val(v) {
          if (v !== undefined) {
              this.el.value = v;
              return this;
          }
          return this.el.value;
      }
  
      focus() {
          this.el.focus();
      }
  
      cssRemoveKeys(...keys) {
          keys.forEach((k) => this.el.style.removeProperty(k));
          return this;
      }
  
      // css( propertyName )
      // css( propertyName, value )
      // css( properties )
      css(name, value) {
          if (value === undefined && typeof name !== 'string') {
              Object.keys(name).forEach((k) => {
                  this.el.style[k] = name[k];
              });
              return this;
          }
          if (value !== undefined) {
              this.el.style[name] = value;
              return this;
          }
          return this.el.style[name];
      }
  
      computedStyle() {
          return window.getComputedStyle(this.el, null);
      }
  
      show() {
          this.css('display', 'block');
          return this;
      }
  
      hide() {
          this.css('display', 'none');
          return this;
      }
  }
  
  const h = (tag, className = '') => new Element(tag, className);
  
  export { Element, h };
  