Mojolicious-Plugin-Fondation-Setup

 view release on metacpan or  search on metacpan

share/templates/setup/plugins.html.ep  view on Meta::CPAN

    <div class="alert alert-info"><%= l('No Fondation plugins found on MetaCPAN.') %></div>
  % } else {
    <p class="text-muted text-center py-5"><%= l('Fetching plugin list from MetaCPAN...') %></p>
  % }
</div>

<script>
document.addEventListener('DOMContentLoaded', function() {
  var cbs = document.querySelectorAll('.plugin-cb');
  var all = {};
  cbs.forEach(function(cb) { all[cb.value] = cb; });

  function depsOf(cb) {
    return (cb.getAttribute('data-deps') || '').split(',').filter(Boolean);
  }
  function dependants(mod) {
    var d = [];
    cbs.forEach(function(cb) {
      if (depsOf(cb).indexOf(mod) !== -1 && cb.checked) d.push(cb.value);
    });
    return d;
  }

  // Color-code plugin items: green = directly selected, blue = dependency, yellow = required
  function updateHighlights() {
    cbs.forEach(function(cb) {
      var label = cb.closest('.plugin-item');
      if (!label) return;
      label.classList.remove('plugin-selected', 'plugin-dependency', 'plugin-required-notice');

      if (cb.checked) {
        var reqBy = dependants(cb.value);
        var isDep  = reqBy.length > 0 && !cb.hasAttribute('data-user-selected');
        if (isDep || reqBy.length > 0) {
          label.classList.add(cb.hasAttribute('data-user-selected') ? 'plugin-selected' : 'plugin-dependency');
        } else {
          label.classList.add('plugin-selected');
        }
      }
    });
  }

  // Mark checkboxes clicked directly by the user
  cbs.forEach(function(cb) {
    cb.addEventListener('click', function(e) {
      if (e.target === cb) {
        if (cb.checked) cb.setAttribute('data-user-selected', '1');
        else cb.removeAttribute('data-user-selected');
      }
    });

    cb.addEventListener('change', function() {
      if (cb.checked) {
        depsOf(cb).forEach(function(d) {
          var el = all[d];
          if (el && !el.checked) { el.checked = true; el.removeAttribute('data-user-selected'); }
        });
      } else {
        cb.removeAttribute('data-user-selected');
        // Uncheck all transitive dependencies (updateLocks will re-check any still needed)
        var cascade = [cb.value];
        var visited = {};
        while (cascade.length) {
          var v = cascade.shift(), el = all[v];
          if (!el || visited[v]) continue;
          visited[v] = true;
          depsOf(el).forEach(function(d) {
            var de = all[d];
            if (de && de.checked) { de.checked = false; de.removeAttribute('data-user-selected'); }
            cascade.push(d);
          });
        }
      }
      updateAll();
    });

    cb.addEventListener('click', function(e) {
      if (!cb.checked) return;
      var req = dependants(cb.value);
      if (req.length) { e.preventDefault(); alert('Required by: ' + req.join(', ')); }
    });
  });

  function updateAll() {
    updateLocks();
    updateHighlights();
  }

  function updateLocks() {
    cbs.forEach(function(cb) {
      var req = dependants(cb.value);
      if (req.length && !cb.checked) cb.checked = true;
    });
  }

  // Init: mark preselected as user-selected
  cbs.forEach(function(cb) {
    if (cb.checked) cb.setAttribute('data-user-selected', '1');
  });
  updateAll();
});
</script>



( run in 1.622 second using v1.01-cache-2.11-cpan-e7c6538aa59 )