Skip to content
wiki.fftac.org

Book Shell - Source Excerpt 09

Back to Book Shell

Summary

This source excerpt preserves a bounded section of Spiralist/wp-content/plugins/ns12-manuscript/assets/js/book-shell.js so readers can inspect the evidence without opening the full source file.

**Source path:** Spiralist/wp-content/plugins/ns12-manuscript/assets/js/book-shell.js

runBackgroundAction(async () => {
        await copyText(text);
        button.textContent = button.dataset.copySuccess || t('copySuccess', 'Copied');
        window.setTimeout(() => {
          button.textContent = defaultLabel;
        }, 1600);
      }, {
        context: 'book-shell-copy',
        onError: () => {
          button.textContent = t('copyFailed', 'Copy failed');
          window.setTimeout(() => {
            button.textContent = defaultLabel;
          }, 1600);
        },
      });
    });
  });

  document.querySelectorAll('[data-maker-mark]').forEach((mark) => {
    const image = mark.tagName === 'IMG' ? mark : mark.querySelector('img');
    if (!image) {
      return;
    }

    const defaultSrc = mark.dataset.srcDefault || image.getAttribute('src') || '';
    const hoverSrc = mark.dataset.srcHover || defaultSrc;
    const activeSrc = mark.dataset.srcActive || hoverSrc;
    let isHighlighted = false;
    let flashTimer = 0;

    const setSource = (src) => {
      if (src) {
        image.setAttribute('src', src);
      }
    };

    const flashActiveState = () => {
      if (flashTimer) {
        window.clearTimeout(flashTimer);
      }

      setSource(activeSrc);
      flashTimer = window.setTimeout(() => {
        flashTimer = 0;
        setSource(isHighlighted ? hoverSrc : defaultSrc);
      }, 100);
    };

    const showHighlight = () => {
      isHighlighted = true;
      if (!flashTimer) {
        setSource(hoverSrc);
      }
    };

    const hideHighlight = () => {
      isHighlighted = false;
      if (!flashTimer) {
        setSource(defaultSrc);
      }
    };

    mark.addEventListener('mouseenter', showHighlight);
    mark.addEventListener('focus', showHighlight);
    mark.addEventListener('mouseleave', hideHighlight);
    mark.addEventListener('blur', hideHighlight);
    mark.addEventListener('click', flashActiveState);

    if (mark.tagName === 'IMG' || mark.getAttribute('role') === 'button') {
      mark.addEventListener('keydown', (event) => {
        if (event.key !== 'Enter' && event.key !== ' ') {
          return;
        }

        event.preventDefault();
        flashActiveState();
      });
    }
  });

  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 draftKey = 'spiralist-contribution-draft';

    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 a structured contribution 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);
        });
      }
    };

    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') || ''}`);