Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
@twnd/ux / core / common / common.module.ts
Size: Mime:
/**
 * @license
 * FOURBURNER CONFIDENTIAL
 * Unpublished Copyright (C) 2021 FourBurner Technologies, Inc. All Rights Reserved.
 *
 * NOTICE: All information contained herein is, and remains the property of FOURBURNER TECHNOLOGIES,
 * INC. The intellectual and technical concepts contained herein are proprietary to FOURBURNER
 * TECHNOLOGIES, INC. and may be covered by U.S. and Foreign Patents, patents in process, and are
 * protected by trade secret or copyright law. Dissemination of this information or reproduction of
 * this material is strictly forbidden unless prior written permission is obtained from FOURBURNER
 * TECHNOLOGIES, INC. Access to the source code contained herein is hereby forbidden to anyone
 * except current FOURBURNER TECHNOLOGIES, INC. employees, managers or contractors who have executed
 * Confidentiality and Non-disclosure agreements explicitly covering such access.
 *
 * The copyright notice above does not evidence any actual or intended publication or disclosure of
 * this source code, which includes information that is confidential and/or proprietary, and is a
 * trade secret, of FOURBURNER TECHNOLOGIES, INC. ANY REPRODUCTION, MODIFICATION, DISTRIBUTION,
 * PUBLIC PERFORMANCE, OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT THE EXPRESS
 * WRITTEN CONSENT OF FOURBURNER TECHNOLOGIES, INC. IS STRICTLY PROHIBITED, AND IN VIOLATION OF
 * APPLICABLE LAWS AND INTERNATIONAL TREATIES. THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR
 * RELATED INFORMATION DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS
 * CONTENTS, OR TO MANUFACTURE, USE, OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART.
 */

import {HighContrastModeDetector} from '@angular/cdk/a11y';
import {BidiModule} from '@angular/cdk/bidi';
import {Inject, InjectionToken, isDevMode, NgModule, Optional} from '@angular/core';
import {DOCUMENT} from '@angular/common';
import {_isTestEnvironment} from '@angular/cdk/platform';

export const ngDevMode = false;

export function TAILWIND_SANITY_CHECKS_FACTORY(): SanityChecks
{
  return true;
}

/**
 * Injection token that configures whether the Tailwind sanity checks are enabled.
 */
export const TAILWIND_SANITY_CHECKS = new InjectionToken<SanityChecks>('twnd-sanity-checks', {
  providedIn : 'root',
  factory : TAILWIND_SANITY_CHECKS_FACTORY,
});

/**
 * Possible sanity checks that can be enabled. If set to
 * true/false, all checks will be enabled/disabled.
 */
export type SanityChecks = boolean|GranularSanityChecks;

/**
 * Object that can be used to configure the sanity checks granularly.
 */
export interface GranularSanityChecks {
  doctype: boolean;
  theme: boolean;
  version: boolean;
}

/**
 * Module that captures anything that should be
 * loaded and/or run for *all* Tailwind components.
 *
 * This module should be imported to each top-level
 * component module (e.g., TWNDModalModule).
 */
@NgModule({
  imports : [ BidiModule ],
  exports : [ BidiModule ],
})
export class TWNDCommonModule
{
  /**
   * Whether we've done the global sanity checks
   * (e.g. a theme is loaded, there is a doctype).
   */
  private m_hasDoneGlobalChecks = false;

  /**
   * Configured sanity checks.
   */
  private m_sanityChecks: SanityChecks;

  /**
   * Used to reference correct document/window
   */
  protected m_document: Document;

  constructor(highContrastModeDetector: HighContrastModeDetector,
              @Optional() @Inject(TAILWIND_SANITY_CHECKS) sanityChecks: any,
              @Inject(DOCUMENT) document: any)
  {
    this.m_document = document;

    /**
     * While A11yModule also does this, we repeat it here to avoid
     * importing A11yModule in TWNDCommonModule.
     */
    highContrastModeDetector._applyBodyHighContrastModeCssClasses();

    /**
     * Note that `m_sanityChecks` is typed to `any`, because AoT
     * throws an error if we use the `SanityChecks` type directly.
     */
    this.m_sanityChecks = sanityChecks;

    if (!this.m_hasDoneGlobalChecks) {
      this.m_checkDoctypeIsDefined();
      this.m_checkThemeIsPresent();
      this.m_hasDoneGlobalChecks = true;
    }
  }

  /**
   * Gets whether a specific sanity check is enabled.
   */
  private m_checkIsEnabled(name: keyof GranularSanityChecks): boolean
  {
    if (!isDevMode() || _isTestEnvironment()) {
      return false;
    }

    if (typeof this.m_sanityChecks === 'boolean') {
      return this.m_sanityChecks;
    }

    return !!this.m_sanityChecks[name];
  }

  private m_checkDoctypeIsDefined(): void
  {
    if (this.m_checkIsEnabled('doctype') && !this.m_document.doctype) {
      console.warn('Current document does not have a doctype. This may cause ' +
                   'some Tailwind UX components not to behave as expected.');
    }
  }

  private m_checkThemeIsPresent(): void
  {
    /**
     * We need to assert that the `body` is defined, because these checks run very early
     * and the `body` won't be defined if the consumer put their scripts in the `head`.
     */
    if (!this.m_checkIsEnabled('theme') || !this.m_document.body ||
        typeof getComputedStyle !== 'function') {
      return;
    }

    const testElement = this.m_document.createElement('div');

    testElement.classList.add('twnd-theme-loaded-marker');
    this.m_document.body.appendChild(testElement);

    const computedStyle = getComputedStyle(testElement);

    /**
     * In some situations the computed style of the test element can be null.
     * For example in Firefox, the computed style is null if an application
     * is running inside of a hidden iframe.
     */
    if (computedStyle && computedStyle.display !== 'none') {
      console.warn('Could not find Tailwind UX core theme. Most ' +
                   'Tailwind components may not work as expected.');
    }

    testElement.remove();
  }
}