getContexts() {
    let ctx,
      filteredCtx = [];
    if (typeof this.ctx === 'undefined' || !this.ctx) { // e.g. null
      ctx = [];
    } else if (NodeList.prototype.isPrototypeOf(this.ctx)) {
      ctx = Array.prototype.slice.call(this.ctx);
    } else if (Array.isArray(this.ctx)) {
      ctx = this.ctx;
    } else if (typeof this.ctx === 'string') {
      ctx = Array.prototype.slice.call(
        document.querySelectorAll(this.ctx)
      );
    } else { // e.g. HTMLElement or element inside iframe
      ctx = [this.ctx];
    }
    // filter duplicate text nodes
    ctx.forEach(ctx => {
      const isDescendant = filteredCtx.filter(contexts => {
        return contexts.contains(ctx);
      }).length > 0;
      if (filteredCtx.indexOf(ctx) === -1 && !isDescendant) {
        filteredCtx.push(ctx);
      }
    });
    return filteredCtx;
  }
Returns all contexts filtered by duplicates (even nested)
@return {HTMLElement[]} - An array containing DOM contexts
@access protected