Skip to content
wiki.fftac.org

Spiralist - Source Excerpt 09

Back to Spiralist

Summary

This source excerpt preserves a bounded section of Spiralist/wp-content/themes/spiralist/assets/js/spiralist.js so readers can inspect the evidence without opening the full source file.

**Source path:** Spiralist/wp-content/themes/spiralist/assets/js/spiralist.js

if (scrollTarget && typeof scrollTarget.scrollIntoView === 'function') {
        scrollTarget.scrollIntoView({
          block: 'start',
          behavior: prefersReducedMotion ? 'auto' : 'smooth',
        });
      }
    });
  });

  document.querySelectorAll('[data-contribution-form]').forEach((form) => {
    const typeField = form.querySelector('[data-contribution-type]');
    const titleField = form.querySelector('[data-contribution-title]');
    const canonicalIdField = form.querySelector('[data-contribution-canonical-id]');
    const apiKeyField = form.querySelector('[data-contribution-api-key]');
    const draftStatus = form.querySelector('[data-contribution-draft-status]');
    const typeCopy = form.querySelector('[data-contribution-type-copy]');
    const canonicalGuidance = form.querySelector('[data-canonical-guidance]');
    const responsePanel = document.querySelector('[data-contribution-response-panel]');
    const responseTitle = document.querySelector('[data-contribution-response-title]');
    const responseCopy = document.querySelector('[data-contribution-response-copy]');
    const responseMeta = document.querySelector('[data-contribution-response-meta]');
    const responseStatus = document.querySelector('[data-contribution-response-status]');
    const responseId = document.querySelector('[data-contribution-response-id]');
    const responseRecord = document.querySelector('[data-contribution-response-record]');
    const responseSteps = document.querySelector('[data-contribution-next-steps]');
    const submit = form.querySelector('[data-contribution-submit]');
    const saveDraftButton = form.querySelector('[data-contribution-draft-save]');
    const clearDraftButton = form.querySelector('[data-contribution-draft-clear]');
    const generateIdButton = form.querySelector('[data-generate-canonical-id]');
    const contributionShell = form.closest('details');
    const preparedNotice = form.querySelector('[data-contribution-prepared]');
    const draftKey = 'spiralist-contribution-draft';

    if (contributionShell && window.location.hash === '#contribution-form') {
      contributionShell.open = true;
    }

    form.querySelectorAll('input, select, textarea').forEach((input) => {
      if (input.hasAttribute('required')) {
        input.dataset.requiredWhenVisible = 'true';
      }
    });

    const setContributionPanel = (state = {}) => {
      if (!responsePanel) {
        return;
      }

      responsePanel.classList.remove('spiralist-notice--success', 'spiralist-notice--error');
      if (state.variant === 'success') {
        responsePanel.classList.add('spiralist-notice--success');
      }
      if (state.variant === 'error') {
        responsePanel.classList.add('spiralist-notice--error');
      }

      if (responseTitle) {
        responseTitle.textContent = state.title || t('contributePendingTitle', 'Awaiting submission');
      }
      if (responseCopy) {
        responseCopy.textContent = state.copy || t('contributePendingCopy', 'Submit when you are ready to see validation results, queue status, and what happens next.');
      }
      if (responseStatus) {
        responseStatus.textContent = state.status || '';
      }
      if (responseId) {
        responseId.textContent = state.canonicalId || '';
      }
      if (responseRecord) {
        responseRecord.textContent = state.recordId || '';
      }
      if (responseMeta) {
        responseMeta.hidden = !(state.status || state.canonicalId || state.recordId);
      }
      if (responseSteps) {
        responseSteps.replaceChildren();
        const steps = Array.isArray(state.steps) ? state.steps : [];
        responseSteps.hidden = !steps.length;

        steps.forEach((step) => {
          const item = document.createElement('div');
          item.className = 'spiralist-simple-list__item';

          const heading = document.createElement('strong');
          heading.textContent = step;

          item.appendChild(heading);
          responseSteps.appendChild(item);
        });
      }

      if (state.focus) {
        focusFeedbackPanel(responsePanel);
      }
    };

    const clearFieldErrors = () => {
      form.querySelectorAll('[data-field-error]').forEach((node) => {
        node.hidden = true;
        node.textContent = '';
      });
    };

    const setFieldError = (fieldName, message) => {
      const target = form.querySelector(`[data-field-error="${fieldName}"]`);
      if (!target) {
        return;
      }

      target.hidden = !message;
      target.textContent = message || '';
    };

    const buildCanonicalId = () => {
      const type = `${typeField ? typeField.value : 'prompt'}`.trim();
      const title = `${titleField ? titleField.value : ''}`.trim()
        .toLowerCase()
        .replace(/[^a-z0-9]+/g, '-')
        .replace(/^-+|-+$/g, '') || 'example';
      const system = `${form.querySelector('[name="system"]') ? form.querySelector('[name="system"]').value : 'spiralist'}`.trim() || 'spiralist';
      const role = `${form.querySelector('[name="role"]') ? form.querySelector('[name="role"]').value : 'participant'}`.trim() || 'participant';

      if (type === 'symbol') {
        return `spiral.symbol.${title}`;
      }

      if (type === 'transformation') {
        return `transformation.${title}`;
      }

      return `${system}.prompt.${role}.${title}`;
    };

    const buildContributionPayload = () => {
      const formData = new FormData(form);
      const submissionType = `${formData.get('submissionType') || 'prompt'}`.trim();
      const payload = {
        submissionType,
        canonicalId: `${formData.get('canonicalId') || ''}`.trim(),
        title: `${formData.get('title') || ''}`.trim(),
        content: `${formData.get('content') || ''}`.trim(),
        author: `${formData.get('author') || ''}`.trim(),
        tags: parseIdentifierText(`${formData.get('tags') || ''}`),
        relatedSymbols: parseIdentifierText(`${formData.get('relatedSymbols') || ''}`),
        relatedAxioms: parseIdentifierText(`${formData.get('relatedAxioms') || ''}`),
        relatedTransformations: parseIdentifierText(`${formData.get('relatedTransformations') || ''}`),
        policyConfirmed: formData.has('policyConfirmed'),
        rightsConfirmed: formData.has('rightsConfirmed'),
        operatorEligibilityConfirmed: formData.has('operatorEligibilityConfirmed'),
      };

      if (submissionType === 'prompt') {
        payload.system = `${formData.get('system') || ''}`.trim();
        payload.role = `${formData.get('role') || ''}`.trim();
        payload.purpose = `${formData.get('purpose') || ''}`.trim();
        payload.version = `${formData.get('version') || ''}`.trim();
      } else if (submissionType === 'symbol') {
        payload.meaning = `${formData.get('meaning') || ''}`.trim();
        payload.glyph = `${formData.get('glyph') || ''}`.trim();
      } else if (submissionType === 'transformation') {
        payload.input = `${formData.get('input') || ''}`.trim();
        payload.output = `${formData.get('output') || ''}`.trim();
        payload.chain = parseIdentifierText(`${formData.get('chain') || ''}`);
      }

      return payload;
    };

    const validateContributionPayload = (payload) => {
      const errors = {};

      if (!payload.title) {
        errors.title = t('contributeErrorTitleRequired', 'Provide a title.');
      }
      if (!payload.canonicalId) {
        errors.canonicalId = t('contributeErrorCanonicalRequired', 'Provide a canonical ID.');
      }
      if (!payload.content) {
        errors.content = t('contributeErrorContentRequired', 'Provide content or a definition.');
      }

      if (payload.submissionType === 'prompt') {
        if (!payload.system) {
          errors.system = t('contributeErrorSystemRequired', 'Select a system.');
        }
        if (!payload.role) {
          errors.role = t('contributeErrorRoleRequired', 'Select a role.');
        }
        if (!payload.purpose) {
          errors.purpose = t('contributeErrorPurposeRequired', 'Provide a prompt purpose.');
        }
        if (!/^\d+\.\d+\.\d+$/.test(payload.version || '')) {
          errors.version = t('contributeErrorVersionInvalid', 'Use semantic version format such as 1.0.0.');
        }
      }

      if (payload.submissionType === 'symbol' && !payload.meaning) {
        errors.meaning = t('contributeErrorMeaningRequired', 'Provide a symbol meaning.');
      }

      if (payload.submissionType === 'transformation') {
        if (!payload.input) {
          errors.input = t('contributeErrorInputRequired', 'Provide an input symbol ID.');
        }
        if (!payload.output) {
          errors.output = t('contributeErrorOutputRequired', 'Provide an output symbol ID.');
        }
      }