← back to demon-of-fire__accessable-studio

Function bodies 189 total

All specs Real LLM only Function bodies
getDuration function · javascript · L597-L604 (8 LOC)
src/js/player.js
  function getDuration() {
    const videoDur = video.duration || 0;
    const allClips = Timeline.getClips();
    const audioDur = allClips
      .filter(c => c.type === 'audio')
      .reduce((max, c) => Math.max(max, c.startTime + c.duration), 0);
    return Math.max(videoDur, audioDur);
  }
applyFilter function · javascript · L607-L609 (3 LOC)
src/js/player.js
  function applyFilter(filterString) {
    video.style.filter = filterString;
  }
init function · javascript · L612-L657 (46 LOC)
src/js/player.js
  function init() {
    video.addEventListener('timeupdate', () => {
      updateTimeDisplay();
      if (isPlaying) syncAudioClips(getCurrentTime());
    });
    video.addEventListener('ended', () => {
      // Check if audio clips are still playing
      const audioDur = getDuration();
      const current = getCurrentTime();
      if (current < audioDur - 0.1) {
        // Audio still has time left, keep playing in audio-only mode
        audioOnlyTime = current;
        startAudioSyncLoop();
        return;
      }
      isPlaying = false;
      stopAllAudio();
      stopAudioSyncLoop();
      playBtn.textContent = 'Play';
      playBtn.setAttribute('aria-label', 'Play');
      Accessibility.announceStatus('Playback finished');
    });

    // Seek slider
    seekSlider.addEventListener('input', () => {
      seekTo(parseFloat(seekSlider.value));
    });

    // Volume slider
    volumeSlider.addEventListener('input', () => {
      setVolume(parseInt(volumeSlider.value));
    });

 
generateId function · javascript · L17-L19 (3 LOC)
src/js/timeline.js
  function generateId() {
    return `clip-${++clipIdCounter}`;
  }
saveState function · javascript · L22-L26 (5 LOC)
src/js/timeline.js
  function saveState() {
    undoStack.push(JSON.parse(JSON.stringify(clips)));
    if (undoStack.length > 50) undoStack.shift();
    redoStack = [];
  }
undo function · javascript · L29-L39 (11 LOC)
src/js/timeline.js
  function undo() {
    if (undoStack.length === 0) {
      Accessibility.announce('Nothing to undo');
      return;
    }
    redoStack.push(JSON.parse(JSON.stringify(clips)));
    clips = undoStack.pop();
    renderAllTracks();
    Accessibility.announce('Undone');
    Accessibility.setStatus('Undo performed');
  }
redo function · javascript · L42-L52 (11 LOC)
src/js/timeline.js
  function redo() {
    if (redoStack.length === 0) {
      Accessibility.announce('Nothing to redo');
      return;
    }
    undoStack.push(JSON.parse(JSON.stringify(clips)));
    clips = redoStack.pop();
    renderAllTracks();
    Accessibility.announce('Redone');
    Accessibility.setStatus('Redo performed');
  }
Want fix-PRs on findings? Install Repobility's GitHub App · github.com/apps/repobility-bot
addClip function · javascript · L55-L80 (26 LOC)
src/js/timeline.js
  function addClip(clipData) {
    saveState();
    const id = generateId();
    const clip = {
      id,
      name: clipData.name || 'Untitled',
      type: clipData.type || 'video', // 'video', 'audio', 'text'
      filePath: clipData.filePath || '',
      startTime: clipData.startTime ?? getTrackEndTime(clipData.type || 'video'),
      duration: clipData.duration || 5,
      trimStart: clipData.trimStart || 0,
      trimEnd: clipData.trimEnd || 0,
      volume: clipData.volume ?? 100,
      speed: clipData.speed || 1,
      filters: clipData.filters || {},
      text: clipData.text || '',
      fontSize: clipData.fontSize || 48,
      textColor: clipData.textColor || '#ffffff',
      textPosition: clipData.textPosition || 'center',
    };
    clips.push(clip);
    renderAllTracks();
    Accessibility.announce(`Added ${clip.type} clip: ${clip.name}, duration ${Accessibility.formatTime(clip.duration)}`);
    Accessibility.setStatus(`Clip added: ${clip.name}`);
    return id;
  }
getTrackEndTime function · javascript · L83-L87 (5 LOC)
src/js/timeline.js
  function getTrackEndTime(type) {
    const trackClips = clips.filter(c => c.type === type);
    if (trackClips.length === 0) return 0;
    return Math.max(...trackClips.map(c => c.startTime + c.duration));
  }
removeClip function · javascript · L90-L101 (12 LOC)
src/js/timeline.js
  function removeClip(clipId) {
    saveState();
    const clip = clips.find(c => c.id === clipId);
    if (!clip) return;
    const name = clip.name;
    clips = clips.filter(c => c.id !== clipId);
    if (selectedClipId === clipId) selectedClipId = null;
    renderAllTracks();
    hideClipProperties();
    Accessibility.announce(`Deleted clip: ${name}`);
    Accessibility.setStatus(`Clip deleted: ${name}`);
  }
splitClip function · javascript · L104-L131 (28 LOC)
src/js/timeline.js
  function splitClip(clipId, splitTime) {
    const clip = clips.find(c => c.id === clipId);
    if (!clip) return;

    const relativeTime = splitTime - clip.startTime;
    if (relativeTime <= 0.1 || relativeTime >= clip.duration - 0.1) {
      Accessibility.announce('Cannot split at this position');
      return;
    }

    saveState();

    const secondHalf = {
      ...clip,
      name: clip.name + ' (2)',
      startTime: splitTime,
      duration: clip.duration - relativeTime,
      trimStart: clip.trimStart + relativeTime,
    };

    clip.duration = relativeTime;
    clip.name = clip.name.replace(/ \(1\)$/, '') + ' (1)';

    clips.push({ ...secondHalf, id: generateId() });
    renderAllTracks();
    Accessibility.announce(`Split clip at ${Accessibility.formatTime(splitTime)}`);
    Accessibility.setStatus('Clip split');
  }
splitAtPlayhead function · javascript · L134-L148 (15 LOC)
src/js/timeline.js
  function splitAtPlayhead() {
    if (!selectedClipId) {
      // Find clip under playhead
      const clipUnderPlayhead = clips.find(c =>
        c.startTime <= playheadPosition && c.startTime + c.duration > playheadPosition
      );
      if (clipUnderPlayhead) {
        splitClip(clipUnderPlayhead.id, playheadPosition);
      } else {
        Accessibility.announce('No clip at playhead position');
      }
      return;
    }
    splitClip(selectedClipId, playheadPosition);
  }
duplicateClip function · javascript · L151-L167 (17 LOC)
src/js/timeline.js
  function duplicateClip(clipId) {
    const clip = clips.find(c => c.id === (clipId || selectedClipId));
    if (!clip) {
      Accessibility.announce('No clip selected to duplicate');
      return;
    }
    saveState();
    const newClip = {
      ...clip,
      id: generateId(),
      name: clip.name + ' (copy)',
      startTime: clip.startTime + clip.duration,
    };
    clips.push(newClip);
    renderAllTracks();
    Accessibility.announce(`Duplicated clip: ${clip.name}`);
  }
selectClip function · javascript · L170-L186 (17 LOC)
src/js/timeline.js
  function selectClip(clipId) {
    selectedClipId = clipId;
    // Update UI
    document.querySelectorAll('.clip').forEach(el => {
      el.setAttribute('aria-selected', el.dataset.clipId === clipId ? 'true' : 'false');
    });
    const clip = clips.find(c => c.id === clipId);
    if (clip) {
      showClipProperties(clip);
      // Show edit toolbar when clip is selected
      const editToolbar = document.getElementById('video-toolbar-edit');
      if (editToolbar) editToolbar.classList.remove('hidden');
      const editLabel = document.getElementById('edit-tools-label');
      if (editLabel) editLabel.textContent = `Editing: ${clip.name}`;
      Accessibility.announce(`Selected: ${clip.name}, ${clip.type} clip, starts at ${Accessibility.formatTime(clip.startTime)}, duration ${Accessibility.formatTime(clip.duration)}`);
    }
  }
showClipProperties function · javascript · L189-L204 (16 LOC)
src/js/timeline.js
  function showClipProperties(clip) {
    const panel = document.getElementById('clip-properties');
    if (panel) panel.classList.remove('hidden');
    const nameInput = document.getElementById('clip-name-input');
    const startInput = document.getElementById('clip-start-input');
    const durationInput = document.getElementById('clip-duration-input');
    const volumeSlider = document.getElementById('clip-volume-slider');
    const volumeDisplay = document.getElementById('clip-volume-display');
    const speedSelect = document.getElementById('clip-speed-select');
    if (nameInput) nameInput.value = clip.name;
    if (startInput) startInput.value = clip.startTime.toFixed(1);
    if (durationInput) durationInput.value = clip.duration.toFixed(1);
    if (volumeSlider) volumeSlider.value = clip.volume;
    if (volumeDisplay) volumeDisplay.textContent = clip.volume + '%';
    if (speedSelect) speedSelect.value = clip.speed;
  }
Generated by Repobility's multi-pass static-analysis pipeline (https://repobility.com)
hideClipProperties function · javascript · L207-L212 (6 LOC)
src/js/timeline.js
  function hideClipProperties() {
    const panel = document.getElementById('clip-properties');
    if (panel) panel.classList.add('hidden');
    const editToolbar = document.getElementById('video-toolbar-edit');
    if (editToolbar) editToolbar.classList.add('hidden');
  }
updateClipProperty function · javascript · L215-L222 (8 LOC)
src/js/timeline.js
  function updateClipProperty(clipId, prop, value) {
    const clip = clips.find(c => c.id === (clipId || selectedClipId));
    if (!clip) return;
    saveState();
    clip[prop] = value;
    renderAllTracks();
    Accessibility.announceStatus(`${prop} updated to ${value}`);
  }
getPPS function · javascript · L225-L227 (3 LOC)
src/js/timeline.js
  function getPPS() {
    return BASE_PPS * zoom;
  }
zoomIn function · javascript · L230-L235 (6 LOC)
src/js/timeline.js
  function zoomIn() {
    zoom = Math.min(zoom * 1.25, 5);
    renderAllTracks();
    document.getElementById('zoom-level').textContent = Math.round(zoom * 100) + '%';
    Accessibility.announceStatus(`Zoom: ${Math.round(zoom * 100)}%`);
  }
zoomOut function · javascript · L238-L243 (6 LOC)
src/js/timeline.js
  function zoomOut() {
    zoom = Math.max(zoom / 1.25, 0.2);
    renderAllTracks();
    document.getElementById('zoom-level').textContent = Math.round(zoom * 100) + '%';
    Accessibility.announceStatus(`Zoom: ${Math.round(zoom * 100)}%`);
  }
renderAllTracks function · javascript · L246-L254 (9 LOC)
src/js/timeline.js
  function renderAllTracks() {
    renderTrack('video', document.getElementById('video-track-clips'));
    renderTrack('audio', document.getElementById('audio-track-clips'));
    renderTrack('text', document.getElementById('text-track-clips'));
    renderRuler();
    updatePlayhead();
    // Notify listeners
    onChangeCallbacks.forEach(cb => { try { cb(); } catch(e) {} });
  }
onChange function · javascript · L257-L259 (3 LOC)
src/js/timeline.js
  function onChange(callback) {
    onChangeCallbacks.push(callback);
  }
renderTrack function · javascript · L262-L325 (64 LOC)
src/js/timeline.js
  function renderTrack(type, container) {
    container.innerHTML = '';
    const trackClips = clips.filter(c => c.type === type);
    const pps = getPPS();

    // Set track width based on content
    const maxEnd = trackClips.length > 0
      ? Math.max(...trackClips.map(c => c.startTime + c.duration))
      : 60;
    container.style.width = Math.max((maxEnd + 10) * pps, container.parentElement.clientWidth) + 'px';

    trackClips.forEach(clip => {
      const el = document.createElement('div');
      el.className = `clip ${type}-clip`;
      el.dataset.clipId = clip.id;
      el.setAttribute('role', 'option');
      el.setAttribute('aria-selected', clip.id === selectedClipId ? 'true' : 'false');
      el.setAttribute('aria-label', `${clip.name}, ${type} clip, starts at ${Accessibility.formatTimeDisplay(clip.startTime)}, duration ${Accessibility.formatTimeDisplay(clip.duration)}`);
      el.setAttribute('tabindex', '0');
      el.style.left = (clip.startTime * pps) + 'px';
      el.s
Repobility · code-quality intelligence platform · https://repobility.com
setupClipDrag function · javascript · L328-L357 (30 LOC)
src/js/timeline.js
  function setupClipDrag(element, clip) {
    let isDragging = false;
    let startX, originalStart;

    element.addEventListener('mousedown', (e) => {
      if (e.target.classList.contains('clip-handle')) return;
      isDragging = true;
      startX = e.clientX;
      originalStart = clip.startTime;
      saveState();
      document.body.style.cursor = 'grabbing';
      e.preventDefault();
    });

    document.addEventListener('mousemove', (e) => {
      if (!isDragging) return;
      const dx = e.clientX - startX;
      const dt = dx / getPPS();
      clip.startTime = Math.max(0, originalStart + dt);
      element.style.left = (clip.startTime * getPPS()) + 'px';
    });

    document.addEventListener('mouseup', () => {
      if (!isDragging) return;
      isDragging = false;
      document.body.style.cursor = '';
      renderAllTracks();
      Accessibility.announceStatus(`Clip moved to ${Accessibility.formatTime(clip.startTime)}`);
    });
  }
setupHandleDrag function · javascript · L360-L395 (36 LOC)
src/js/timeline.js
  function setupHandleDrag(handle, clip, side) {
    let isDragging = false;
    let startX, originalDuration, originalStart;

    handle.addEventListener('mousedown', (e) => {
      isDragging = true;
      startX = e.clientX;
      originalDuration = clip.duration;
      originalStart = clip.startTime;
      saveState();
      e.preventDefault();
      e.stopPropagation();
    });

    document.addEventListener('mousemove', (e) => {
      if (!isDragging) return;
      const dx = e.clientX - startX;
      const dt = dx / getPPS();
      if (side === 'right') {
        clip.duration = Math.max(0.5, originalDuration + dt);
      } else {
        const newStart = Math.max(0, originalStart + dt);
        const startDiff = newStart - originalStart;
        clip.startTime = newStart;
        clip.duration = Math.max(0.5, originalDuration - startDiff);
        clip.trimStart = (clip.trimStart || 0) + startDiff;
      }
      renderAllTracks();
    });

    document.addEventListener('mouseup
renderRuler function · javascript · L398-L435 (38 LOC)
src/js/timeline.js
  function renderRuler() {
    const canvas = document.getElementById('ruler-canvas');
    if (!canvas) return;
    const container = document.getElementById('timeline-container');
    const pps = getPPS();
    const totalTime = getTotalDuration() + 10;
    const width = Math.max(totalTime * pps, container.clientWidth);

    canvas.width = width;
    canvas.height = 24;

    const ctx = canvas.getContext('2d');
    ctx.clearRect(0, 0, width, 24);
    ctx.fillStyle = '#7878a0';
    ctx.font = '10px Consolas, monospace';

    // Determine step based on zoom
    let step = 1;
    if (pps < 20) step = 10;
    else if (pps < 40) step = 5;
    else if (pps < 80) step = 2;

    for (let t = 0; t <= totalTime; t += step) {
      const x = t * pps;
      ctx.fillStyle = '#7878a0';
      ctx.fillRect(x, 16, 1, 8);
      ctx.fillText(Accessibility.formatTimeDisplay(t), x + 3, 12);
    }

    // Sub-ticks
    const subStep = step / 4;
    ctx.fillStyle = '#4a4a6a';
    for (let t = 0; t <= totalTi
updatePlayhead function · javascript · L438-L443 (6 LOC)
src/js/timeline.js
  function updatePlayhead() {
    const playhead = document.getElementById('playhead');
    if (!playhead) return;
    const pps = getPPS();
    playhead.style.left = (80 + playheadPosition * pps) + 'px';
  }
setPlayheadPosition function · javascript · L446-L449 (4 LOC)
src/js/timeline.js
  function setPlayheadPosition(time) {
    playheadPosition = Math.max(0, time);
    updatePlayhead();
  }
getTotalDuration function · javascript · L452-L455 (4 LOC)
src/js/timeline.js
  function getTotalDuration() {
    if (clips.length === 0) return 0;
    return Math.max(...clips.map(c => c.startTime + c.duration));
  }
getClips function · javascript · L458-L460 (3 LOC)
src/js/timeline.js
  function getClips() {
    return clips;
  }
getSelectedClip function · javascript · L463-L465 (3 LOC)
src/js/timeline.js
  function getSelectedClip() {
    return clips.find(c => c.id === selectedClipId);
  }
Repobility's GitHub App fixes findings like these · https://github.com/apps/repobility-bot
getClipsAtTime function · javascript · L468-L470 (3 LOC)
src/js/timeline.js
  function getClipsAtTime(time) {
    return clips.filter(c => time >= c.startTime && time < c.startTime + c.duration);
  }
getVideoClips function · javascript · L473-L475 (3 LOC)
src/js/timeline.js
  function getVideoClips() {
    return clips.filter(c => c.type === 'video').sort((a, b) => a.startTime - b.startTime);
  }
clearAll function · javascript · L478-L485 (8 LOC)
src/js/timeline.js
  function clearAll() {
    saveState();
    clips = [];
    selectedClipId = null;
    renderAllTracks();
    hideClipProperties();
    Accessibility.announce('Timeline cleared');
  }
trimClip function · javascript · L488-L504 (17 LOC)
src/js/timeline.js
  function trimClip(clipId, trimStart, trimEnd) {
    const clip = clips.find(c => c.id === (clipId || selectedClipId));
    if (!clip) return;
    saveState();
    if (trimStart !== undefined && trimStart > 0) {
      clip.startTime += trimStart;
      clip.duration -= trimStart;
      clip.trimStart = (clip.trimStart || 0) + trimStart;
    }
    if (trimEnd !== undefined && trimEnd > 0) {
      clip.duration -= trimEnd;
      clip.trimEnd = (clip.trimEnd || 0) + trimEnd;
    }
    clip.duration = Math.max(0.5, clip.duration);
    renderAllTracks();
    Accessibility.announce(`Clip trimmed. New duration: ${Accessibility.formatTime(clip.duration)}`);
  }
removeAudio function · javascript · L507-L514 (8 LOC)
src/js/timeline.js
  function removeAudio(clipId) {
    const clip = clips.find(c => c.id === (clipId || selectedClipId));
    if (!clip) return;
    saveState();
    clip.volume = 0;
    renderAllTracks();
    Accessibility.announce('Audio removed from clip');
  }
serialize function · javascript · L517-L519 (3 LOC)
src/js/timeline.js
  function serialize() {
    return { clips, zoom, clipIdCounter };
  }
deserialize function · javascript · L522-L529 (8 LOC)
src/js/timeline.js
  function deserialize(data) {
    clips = data.clips || [];
    zoom = data.zoom || 1;
    clipIdCounter = data.clipIdCounter || 0;
    selectedClipId = null;
    renderAllTracks();
    Accessibility.announce(`Project loaded with ${clips.length} clips`);
  }
initTimelineClick function · javascript · L532-L542 (11 LOC)
src/js/timeline.js
  function initTimelineClick() {
    const container = document.getElementById('timeline-container');
    container.addEventListener('click', (e) => {
      if (e.target.closest('.clip')) return;
      const rect = container.getBoundingClientRect();
      const x = e.clientX - rect.left + container.scrollLeft - 80;
      const time = Math.max(0, x / getPPS());
      setPlayheadPosition(time);
      Accessibility.announceStatus(`Playhead at ${Accessibility.formatTime(time)}`);
    });
  }
‹ prevpage 4 / 4