countdown-8.x-1.8/js/integrations/countdown.core.integration.js

js/integrations/countdown.core.integration.js
/**
 * @file
 * Integration for the core CountdownTimer library.
 *
 * This file handles initialization and management of the built-in
 * CountdownTimer instances that ship with the module.
 */

(function (Drupal) {
  'use strict';

  /**
   * Initialize a core countdown timer.
   *
   * @param {Element} element
   *   The DOM element to initialize as a timer.
   * @param {Object} settings
   *   The settings object from drupalSettings.
   */
  function initializeCoreTimer(element, settings) {
    // Validate library availability.
    if (typeof CountdownTimer === 'undefined') {
      Drupal.countdown.utils.handleError(element, 'Core timer library not loaded', 'countdown');
      return;
    }

    // Resolve settings using shared utility.
    const config = Drupal.countdown.utils.resolveCountdownSettings(element, settings, 'countdown');

    // Verify this is for the core timer.
    if (config.library && config.library !== 'countdown') {
      return;
    }

    // Ensure element has an ID for the selector option.
    if (!element.id) {
      element.id = 'countdown-' + Math.random().toString(36).substr(2, 9);
    }

    // Build configuration object for CountdownTimer.
    const timerConfig = {
      selector: '#' + element.id,
      mode: config.mode || 'countdown',
      precision: config.precision || 'seconds',
      driftCompensation: config.driftCompensation !== undefined ? config.driftCompensation : true,
      autoStart: config.autoStart !== undefined ? config.autoStart : true,
      debug: config.debug || false,
      benchmark: config.benchmark || false
    };

    // Add style configuration if provided.
    if (config.style) {
      timerConfig.style = config.style;
    }

    // Handle custom format template properly.
    // Check for both formatTemplate and useCustomFormat flag.
    if (config.formatTemplate && config.formatTemplate.length > 0) {
      timerConfig.formatTemplate = config.formatTemplate;
      // Override precision if custom format is used.
      // This ensures the timer uses the custom format.
      timerConfig.useCustomFormat = true;
    }

    // Add start value if provided (already in milliseconds from PHP).
    if (config.start !== undefined) {
      timerConfig.start = config.start;
    }

    // Add target value for countup mode or countdown target.
    if (config.target_date !== undefined) {
      timerConfig.target = config.target_date;
    }

    // Add offset if specified.
    if (config.offset) {
      timerConfig.offset = parseInt(config.offset, 10);
    }

    // Configure the onComplete callback.
    timerConfig.onComplete = function (timeObj, timerInstance) {
      Drupal.countdown.utils.showExpiredMessage(element, config, 'countdown');
    };

    // Configure the onTick callback.
    timerConfig.onTick = function (timeObj, timerInstance) {
      // Dispatch tick event for other scripts to listen to.
      Drupal.countdown.utils.dispatchEvent(element, 'tick', {
        element: element,
        library: 'countdown',
        timeObj: timeObj
      });
    };

    // Configure the onStart callback.
    timerConfig.onStart = function (timeObj, timerInstance) {
      // Mark as initialized and dispatch event.
      element.classList.add('countdown-initialized');
      Drupal.countdown.utils.dispatchEvent(element, 'initialized', {
        element: element,
        library: 'countdown'
      });
    };

    try {
      // Create the timer instance.
      const timer = new CountdownTimer(timerConfig);

      // Apply custom format override to the timer's _tick method.
      // This ensures formatTemplate is used when rendering.
      if (timerConfig.formatTemplate && timerConfig.useCustomFormat) {
        // Store the original _tick method.
        const originalTick = timer._tick.bind(timer);

        // Override the _tick method to use formatTemplate.
        timer._tick = function() {
          // Ensure element is available.
          if (timer.config.selector && !timer._element) {
            timer._element = document.querySelector(timer.config.selector);
          }

          // Calculate elapsed time.
          const elapsed = timer.getElapsed();
          const effectiveMs = timer.config.mode === 'countdown'
            ? Math.max(0, timer.state.targetMs - elapsed)
            : elapsed;

          // Check for completion.
          if (timer._checkCompletion(effectiveMs)) return;

          // Format time with the custom template.
          const formattedTime = timer.formatTime(timer.config.formatTemplate);
          const timeComponents = timer.getTime();

          // Handle style rendering if needed.
          if (timer.config.style && CountdownTimer._styles && CountdownTimer._styles.has(timer.config.style)) {
            if (!timer._styleRenderer) {
              const StyleClass = CountdownTimer._styles.get(timer.config.style);
              timer._styleRenderer = new StyleClass(timer, timer.config.styleOptions);
            }
            if (timer._element && timer._styleRenderer.render) {
              timer._styleRenderer.render(formattedTime, timeComponents);
            }
          } else {
            // Default text rendering with custom format.
            if (timer._element) {
              timer._element.textContent = formattedTime;
            }
          }

          // Debug output if enabled.
          if (timer.config.debug) {
            console.log('[CountdownTimer]', formattedTime, timeComponents);
          }

          // Emit tick event.
          timer._emit('tick', timeComponents);
          if (timer.config.onTick) {
            timer.config.onTick(timeComponents, timer);
          }
        };
      }

      // Store instance for cleanup.
      Drupal.countdown.storeInstance(element, {
        instance: timer,
        stop: function () {
          if (timer && timer.stop) {
            timer.stop();
          }
        }
      });

      // Start the timer if autoStart is false.
      // (The timer auto-starts by default if autoStart is true.)
      if (!timerConfig.autoStart && timer.start) {
        timer.start();
      }

      // Debug output if enabled.
      if (config.debug) {
        console.log('Core countdown initialized:', {
          element: element,
          config: timerConfig,
          settings: config
        });
      }
    }
    catch (error) {
      console.error('Countdown: Failed to create core timer', error);
      Drupal.countdown.utils.handleError(element, 'Failed to create timer: ' + error.message, 'countdown');
    }
  }

  // Register loader with countdown system.
  Drupal.countdown.registerLoader('countdown', initializeCoreTimer);

})(Drupal);

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc