Merlin-R / Torn Bar Notifications

// ==UserScript==
// @namespace    https://openuserjs.org/users/Merlin-R
// @name         Torn Bar Notifications
// @description  Notify on full Nerve or Energy Bars
// @copyright    2018, Merlin-R (https://openuserjs.org/users/Merlin-R)
// @license      MIT
// @version      0.1.1
// @author       Merlin-R
// @match        *.torn.com/*
// @include      *.torn.com/*
// @grant        none
// ==/UserScript==

// ==OpenUserJS==
// @author Merlin-R
// ==/OpenUserJS==

(function () {
  'use strict';
  var TornBar = function (id) {
    this.id = id;
    this.refreshComponents();
  };

  TornBar.prototype.isFull = function () {
    return this.$desc.text().trim() === 'FULL' || this.getValue() >= this.getMax();
  };

  TornBar.prototype.getValue = function () {
    return +this.$value.text().split('/')[0].trim();
  };

  TornBar.prototype.getMax = function () {
    return +this.$value.text().split('/')[1].trim();
  };

  TornBar.prototype.getName = function () {
    return this.$name.text().slice(0, -1);
  };

  TornBar.prototype.refreshComponents = function () {
    this.$bar = $(this.id);
    var children = $(this.$bar.children()[0]).children();
    this.$name = $(children[0]);
    this.$value = $(children[1]);
    this.$desc = $(children[2]);
  };

  TornBar.prototype.notifyOnFull = function () {
    if (this.notifyTimer) clearInterval(this.notifyTimer);
    this.notifyTimer = setInterval((function () {
      this.refreshComponents();
      if (!document.hasFocus()) {
        if (this.isFull() && !this.notification) {
          this.notification = new Notification(this.getName() + ' is full!');
        }
      }
      else {
        if (!this.notification) return;
        this.notification.close();
        this.notification = undefined;
      }
    }).bind(this), 5000);
  };

  var EnergyBar = window.EnergyBar = new TornBar('#barEnergy');
  var NerveBar = window.NerveBar = new TornBar('#barNerve');

  EnergyBar.notifyOnFull();
  NerveBar.notifyOnFull();
})();