mirror of
https://github.com/tdurieux/anonymous_github.git
synced 2026-09-13 14:18:57 +02:00
Merge pull request #810 from tdurieux/feat/landing-redesign
feat: rebuild the landing page around the product
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"core.min.js": "core.6332b3c288.min.js",
|
"core.min.js": "core.6332b3c288.min.js",
|
||||||
"vendor.min.js": "vendor.81d3dd59f8.min.js",
|
"vendor.min.js": "vendor.21205fda63.min.js",
|
||||||
"mermaid.min.js": "mermaid.f848a72d16.min.js",
|
"mermaid.min.js": "mermaid.f848a72d16.min.js",
|
||||||
"all.min.css": "all.6d950dfd4d.min.css"
|
"all.min.css": "all.08e150389d.min.css"
|
||||||
}
|
}
|
||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+549
-326
File diff suppressed because it is too large
Load Diff
+206
-230
@@ -1,257 +1,233 @@
|
|||||||
<div class="paper-landing">
|
<div class="paper-landing">
|
||||||
<!-- Hero -->
|
<!-- Hero: copy on the left, the product on the right -->
|
||||||
<section class="paper-hero">
|
<section class="paper-hero">
|
||||||
<div class="paper-eyebrow">For double-blind peer review</div>
|
<div class="paper-hero-copy">
|
||||||
<h1 class="hero-title">
|
<div class="paper-eyebrow">For double-blind peer review</div>
|
||||||
Share the code,<br />
|
<h1 class="hero-title">
|
||||||
<span class="accent">not the author.</span>
|
Share the code,<br />
|
||||||
</h1>
|
<span class="accent">not the author.</span>
|
||||||
<p class="hero-subtitle">
|
</h1>
|
||||||
Anonymous GitHub makes a read-only mirror of your repository, pull
|
<p class="hero-subtitle">
|
||||||
request, or gist with every trace of identity removed — so you can attach a
|
Anonymous GitHub makes a read-only mirror of your repository, pull
|
||||||
link to your submission without breaking anonymity.
|
request, or gist with every trace of identity removed, so you can
|
||||||
</p>
|
attach a link to your submission without breaking anonymity.
|
||||||
|
</p>
|
||||||
|
|
||||||
<div class="paper-cta-row">
|
<div class="paper-cta-row">
|
||||||
<span ng-if="!user">
|
<a ng-if="!user" href="/github/login" target="_self" class="btn-hero">
|
||||||
<a href="/github/login" target="_self" class="btn-hero">
|
<i class="fab fa-github mr-2" aria-hidden="true"></i>Sign in with GitHub
|
||||||
<i class="fab fa-github mr-2"></i>Sign in with GitHub
|
|
||||||
</a>
|
</a>
|
||||||
</span>
|
<a ng-if="user" href="/anonymize" class="btn-hero">
|
||||||
<span ng-if="user">
|
|
||||||
<a href="/anonymize" class="btn-hero">
|
|
||||||
Anonymize a repository →
|
Anonymize a repository →
|
||||||
</a>
|
</a>
|
||||||
</span>
|
<a
|
||||||
<a href="/anonymize" ng-if="user" class="btn-hero-ghost">
|
class="paper-link-arrow"
|
||||||
Anonymize a pull request
|
target="_self"
|
||||||
</a>
|
href="https://anonymous.4open.science/r/840c8c57-3c32-451e-bf12-0e20be300389/"
|
||||||
<span class="meta">Free · Open source · Self-hostable</span>
|
>See an anonymized repository →</a
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<ul class="paper-reassure">
|
||||||
|
<li>Free and open source</li>
|
||||||
|
<li>Read-only: never writes to your repos</li>
|
||||||
|
<li>Expires on the date you set</li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="paper-hero-shot">
|
||||||
<!-- Before / after -->
|
<div class="paper-frame">
|
||||||
<div class="paper-preview" aria-label="Before and after example">
|
<div class="paper-frame-bar" aria-hidden="true">
|
||||||
<div class="pane">
|
<span class="dots"><i></i><i></i><i></i></span>
|
||||||
<div class="pane-header">
|
<span class="url">anonymous.4open.science/anonymize</span>
|
||||||
<span class="pane-label">Before · your repo</span>
|
|
||||||
<span class="pane-url">github.com/jane-smith/DeepLearnUtils</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="pane-body">
|
|
||||||
<div><span class="tok">#</span> <strong>DeepLearnUtils</strong></div>
|
|
||||||
<div>Developed by Jane Smith at MIT CSAIL.</div>
|
|
||||||
<div>See Smith et al., “Attention That Works,” 2026.</div>
|
|
||||||
<div>Contact: jane.smith@mit.edu</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="pane">
|
|
||||||
<div class="pane-header">
|
|
||||||
<span class="pane-label">After · anonymous mirror</span>
|
|
||||||
<span class="pane-url">anonymous.4open.science/r/paper-7f2a</span>
|
|
||||||
</div>
|
|
||||||
<div class="pane-body">
|
|
||||||
<div><span class="tok">#</span> <strong>DeepLearnUtils</strong></div>
|
|
||||||
<div>Developed by <span class="redact">Jane Smith</span> at <span class="redact">MIT CSAIL</span>.</div>
|
|
||||||
<div>See <span class="redact">Smith et al.</span>, “Attention That Works,” 2026.</div>
|
|
||||||
<div>Contact: <span class="redact">jane.smith@mit.edu</span></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<!-- Stats strip -->
|
|
||||||
<section class="paper-stats" id="metrics">
|
|
||||||
<div class="paper-stats-inner">
|
|
||||||
<div class="paper-stats-meta">
|
|
||||||
<div class="paper-stats-meta-left">LIVE · LAST 60 DAYS</div>
|
|
||||||
<div class="paper-stats-meta-right">
|
|
||||||
updated daily ·
|
|
||||||
<span class="paper-stats-dot"></span> in sync
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="paper-stats-grid">
|
|
||||||
<div class="paper-stat-card" ng-repeat="card in cards track by card.key">
|
|
||||||
<div class="paper-stat-value">{{card.total | bigNum}}</div>
|
|
||||||
<div class="paper-stat-label">{{card.label}}</div>
|
|
||||||
<svg class="paper-stat-bars" preserveAspectRatio="none"
|
|
||||||
ng-attr-viewBox="0 0 {{history[card.key].viewW}} 36"
|
|
||||||
ng-if="history[card.key].bars.length > 1">
|
|
||||||
<rect ng-repeat="b in history[card.key].bars track by $index"
|
|
||||||
ng-attr-x="{{b.x}}" ng-attr-y="{{b.y}}"
|
|
||||||
ng-attr-width="{{b.w}}" ng-attr-height="{{b.h}}"
|
|
||||||
ng-class="{'is-latest': $last}"/>
|
|
||||||
</svg>
|
|
||||||
<div class="paper-stat-delta" ng-if="history[card.key].bars.length > 1">
|
|
||||||
<span class="paper-stat-today">+{{history[card.key].deltaToday | number}} today</span>
|
|
||||||
<span class="paper-stat-sep">·</span>
|
|
||||||
<span class="paper-stat-pct"
|
|
||||||
ng-class="{'is-up': history[card.key].isUp, 'is-down': !history[card.key].isUp}">
|
|
||||||
<span class="paper-stat-arrow">{{history[card.key].isUp ? '▲' : '▼'}}</span>
|
|
||||||
{{history[card.key].pctAbs}}%
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<!-- How it works -->
|
|
||||||
<section class="paper-how" id="usage">
|
|
||||||
<div>
|
|
||||||
<div class="paper-eyebrow">How it works</div>
|
|
||||||
<h2 class="paper-how-heading">
|
|
||||||
Three steps,<br />about a minute.
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div class="paper-step">
|
|
||||||
<div class="step-num">01</div>
|
|
||||||
<div>
|
|
||||||
<div class="step-title">Authenticate</div>
|
|
||||||
<div class="step-desc">
|
|
||||||
<a href="/github/login" target="_self">Sign in with GitHub</a> to
|
|
||||||
access your dashboard. Anonymous GitHub only ever reads your
|
|
||||||
repositories — we never push, modify, or delete anything.
|
|
||||||
GitHub may display a broader scope at sign-in because its OAuth
|
|
||||||
scopes don't offer read-only access to private repositories
|
|
||||||
(<a href="/faq#permissions">see FAQ</a>).
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="paper-step">
|
|
||||||
<div class="step-num">02</div>
|
|
||||||
<div>
|
|
||||||
<div class="step-title">Configure</div>
|
|
||||||
<div class="step-desc">
|
|
||||||
Point us at a repo, branch, commit, or pull request. List the
|
|
||||||
terms to redact (names, affiliation, emails). Set an expiry.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="paper-step">
|
|
||||||
<div class="step-num">03</div>
|
|
||||||
<div>
|
|
||||||
<div class="step-title">Share</div>
|
|
||||||
<div class="step-desc">
|
|
||||||
You get a stable link with a randomised slug. Reviewers browse,
|
|
||||||
diff, and download — never seeing who you are.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="paper-step" style="border-top: none;">
|
|
||||||
<div class="step-num"> </div>
|
|
||||||
<div>
|
|
||||||
<div class="step-desc">
|
|
||||||
Example:
|
|
||||||
<a
|
|
||||||
target="_self"
|
|
||||||
href="https://anonymous.4open.science/r/840c8c57-3c32-451e-bf12-0e20be300389/"
|
|
||||||
>anonymous.4open.science/r/840c8c57-3c32-451e-bf12-0e20be300389</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<!-- Trust row -->
|
|
||||||
<section class="paper-trust">
|
|
||||||
<div class="paper-trust-inner">
|
|
||||||
<div>
|
|
||||||
<div class="paper-eyebrow">Trusted by the community</div>
|
|
||||||
<div class="paper-trust-lede">
|
|
||||||
Used by authors submitting to major software-engineering and systems
|
|
||||||
venues.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="paper-trust-item">
|
|
||||||
<div class="short">ICSE</div>
|
|
||||||
<div class="long">International Conference on Software Engineering</div>
|
|
||||||
</div>
|
|
||||||
<div class="paper-trust-item">
|
|
||||||
<div class="short">FSE</div>
|
|
||||||
<div class="long">Foundations of Software Engineering</div>
|
|
||||||
</div>
|
|
||||||
<div class="paper-trust-item">
|
|
||||||
<div class="short">OOPSLA</div>
|
|
||||||
<div class="long">
|
|
||||||
Object-Oriented Programming, Systems, Languages, and Applications
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<!-- Featurettes — existing content, kept but restyled -->
|
|
||||||
<main class="container home-content" id="about">
|
|
||||||
<div class="row featurette align-items-center">
|
|
||||||
<div class="col-md-7 order-md-2">
|
|
||||||
<h2 class="featurette-heading">Double-anonymous</h2>
|
|
||||||
<p class="featurette-lead">
|
|
||||||
Anonymize your GitHub repository with options to remove links,
|
|
||||||
images, or specific terms. Keep full control — set an
|
|
||||||
expiration date to make your repository unavailable after review.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-5 order-md-1">
|
|
||||||
<img
|
<img
|
||||||
width="500"
|
|
||||||
loading="lazy"
|
|
||||||
src="/imgs/anonymize.png"
|
src="/imgs/anonymize.png"
|
||||||
class="featurette-image img-fluid mx-auto"
|
width="2880"
|
||||||
alt="Anonymize form"
|
height="1800"
|
||||||
|
alt="The anonymize form with a live README preview showing the redactions"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<hr class="featurette-divider" />
|
<!-- Proof -->
|
||||||
|
<section class="paper-proof paper-wrap" aria-label="Venues">
|
||||||
|
<div class="paper-eyebrow">Trusted by authors at</div>
|
||||||
|
<div class="paper-proof-venues">
|
||||||
|
<span>ICSE</span><i aria-hidden="true">·</i>
|
||||||
|
<span>FSE</span><i aria-hidden="true">·</i>
|
||||||
|
<span>OOPSLA</span>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<div class="row featurette align-items-center">
|
<!-- Live stats -->
|
||||||
<div class="col-md-7">
|
<section class="paper-stats paper-wrap" id="metrics" aria-label="Usage over the last 60 days">
|
||||||
<h2 class="featurette-heading">Explorer</h2>
|
<div class="paper-stats-meta">
|
||||||
<p class="featurette-lead">
|
<div class="paper-stats-meta-left">Live · last 60 days</div>
|
||||||
Reviewers can browse your repository with highlighted source code,
|
<div class="paper-stats-meta-right">
|
||||||
rendered PDFs, images, and notebooks.
|
<span class="paper-stats-dot" aria-hidden="true"></span> updated daily
|
||||||
<a href="https://pages.github.com">GitHub Pages</a> is also supported.
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="paper-stats-grid">
|
||||||
|
<div class="paper-stat-card" ng-repeat="card in cards track by card.key">
|
||||||
|
<div class="paper-stat-value">{{card.total | bigNum}}</div>
|
||||||
|
<div class="paper-stat-label">{{card.label}}</div>
|
||||||
|
<svg class="paper-stat-bars" preserveAspectRatio="none" aria-hidden="true"
|
||||||
|
ng-attr-viewBox="0 0 {{history[card.key].viewW}} 36"
|
||||||
|
ng-if="history[card.key].bars.length > 1">
|
||||||
|
<rect ng-repeat="b in history[card.key].bars track by $index"
|
||||||
|
ng-attr-x="{{b.x}}" ng-attr-y="{{b.y}}"
|
||||||
|
ng-attr-width="{{b.w}}" ng-attr-height="{{b.h}}"
|
||||||
|
ng-class="{'is-latest': $last}"/>
|
||||||
|
</svg>
|
||||||
|
<div class="paper-stat-delta" ng-if="history[card.key].bars.length > 1">
|
||||||
|
+{{history[card.key].deltaToday | number}} today
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Before / after -->
|
||||||
|
<section class="paper-section-head paper-wrap">
|
||||||
|
<div>
|
||||||
|
<div class="paper-eyebrow">Before · after</div>
|
||||||
|
<h2>The same repository, <em>minus you.</em></h2>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Names, affiliations, emails, and any term you list are replaced across
|
||||||
|
the README, source files, notebooks, and PDF links. Reviewers browse the
|
||||||
|
real thing, not a zip.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
<div class="paper-preview paper-wrap" aria-label="Before and after example">
|
||||||
|
<div class="pane">
|
||||||
|
<div class="pane-header">
|
||||||
|
<span class="pane-label">Before · your repo</span>
|
||||||
|
<span class="pane-url">github.com/jane-smith/DeepLearnUtils</span>
|
||||||
|
</div>
|
||||||
|
<div class="pane-body">
|
||||||
|
<div><span class="tok">#</span> <strong>DeepLearnUtils</strong></div>
|
||||||
|
<div>Developed by Jane Smith at MIT CSAIL.</div>
|
||||||
|
<div>See Smith et al., “Attention That Works,” 2026.</div>
|
||||||
|
<div>Contact: jane.smith@mit.edu</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="pane">
|
||||||
|
<div class="pane-header">
|
||||||
|
<span class="pane-label">After · anonymous mirror</span>
|
||||||
|
<span class="pane-url">anonymous.4open.science/r/paper-7f2a</span>
|
||||||
|
</div>
|
||||||
|
<div class="pane-body">
|
||||||
|
<div><span class="tok">#</span> <strong>DeepLearnUtils</strong></div>
|
||||||
|
<div>Developed by <span class="redact" role="img" aria-label="redacted author name">XXXX-1</span> at <span class="redact" role="img" aria-label="redacted affiliation">XXXX-2</span>.</div>
|
||||||
|
<div>See <span class="redact" role="img" aria-label="redacted author name">XXXX-1</span> et al., “Attention That Works,” 2026.</div>
|
||||||
|
<div>Contact: <span class="redact" role="img" aria-label="redacted email address">XXXX-3</span></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- What you get: one screenshot, three tabs -->
|
||||||
|
<section class="paper-section-head paper-wrap" id="about">
|
||||||
|
<div>
|
||||||
|
<div class="paper-eyebrow">What you get</div>
|
||||||
|
<h2>Anonymize, review, <em>manage.</em></h2>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Every mirror is read-only and passes through the same filter, from the
|
||||||
|
README to a PDF's link targets. Monitor it, update it, or remove it the
|
||||||
|
day the decision is out.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
<section class="paper-features paper-wrap" aria-label="Product features">
|
||||||
|
<div class="paper-features-list" role="tablist" aria-label="Features" aria-orientation="vertical">
|
||||||
|
<div
|
||||||
|
class="paper-feature"
|
||||||
|
ng-repeat="f in features track by f.key"
|
||||||
|
ng-class="{'is-on': feature === f.key}"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="paper-feature-tab"
|
||||||
|
role="tab"
|
||||||
|
id="feature-tab-{{f.key}}"
|
||||||
|
aria-controls="feature-panel-{{f.key}}"
|
||||||
|
aria-selected="{{feature === f.key}}"
|
||||||
|
tabindex="{{feature === f.key ? 0 : -1}}"
|
||||||
|
ng-click="selectFeature(f.key)"
|
||||||
|
ng-keydown="featureKeydown($event, $index)"
|
||||||
|
>
|
||||||
|
<span class="paper-eyebrow">{{f.num}} · {{f.eyebrow}}</span>
|
||||||
|
<span class="paper-feature-title">{{f.title}} <em>{{f.accent}}</em></span>
|
||||||
|
</button>
|
||||||
|
<div class="paper-feature-more">
|
||||||
|
<span class="paper-feature-title paper-feature-title-m" aria-hidden="true">{{f.title}} <em>{{f.accent}}</em></span>
|
||||||
|
<p>{{f.text}}</p>
|
||||||
|
<a class="paper-link-arrow" ng-href="{{featureHref(f)}}" ng-attr-target="{{featureTarget(f)}}">{{f.cta}} →</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="paper-features-stage">
|
||||||
|
<div
|
||||||
|
class="paper-feature-panel"
|
||||||
|
ng-repeat="f in features track by f.key"
|
||||||
|
ng-show="feature === f.key"
|
||||||
|
id="feature-panel-{{f.key}}"
|
||||||
|
role="tabpanel"
|
||||||
|
aria-labelledby="feature-tab-{{f.key}}"
|
||||||
|
>
|
||||||
|
<div class="paper-frame">
|
||||||
|
<div class="paper-frame-bar" aria-hidden="true">
|
||||||
|
<span class="dots"><i></i><i></i><i></i></span>
|
||||||
|
<span class="url">{{f.url}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="paper-crop paper-crop-{{f.key}}">
|
||||||
|
<img ng-src="{{f.img}}" alt="{{f.alt}}" loading="lazy" width="2880" height="1800" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- FAQ teaser -->
|
||||||
|
<section class="paper-qa paper-wrap" aria-labelledby="qa-heading">
|
||||||
|
<div>
|
||||||
|
<div class="paper-eyebrow">Before you sign in</div>
|
||||||
|
<h2 id="qa-heading">The questions that <em>come up most.</em></h2>
|
||||||
|
<a class="paper-link-arrow" href="/faq">Read the full FAQ →</a>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="q">
|
||||||
|
<a href="/faq#howWork">Why does GitHub ask for write access at sign-in?</a>
|
||||||
|
<p>
|
||||||
|
GitHub's OAuth scopes have no read-only option for private
|
||||||
|
repositories. Anonymous GitHub only ever reads your repositories; it
|
||||||
|
never pushes, modifies, or deletes anything.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-5">
|
<div class="q">
|
||||||
<img
|
<a href="/faq#formats">Which file formats are supported?</a>
|
||||||
width="500"
|
<p>
|
||||||
loading="lazy"
|
Source code with syntax highlighting, Markdown, Jupyter notebooks,
|
||||||
src="/imgs/explorer.png"
|
PDFs, images, and GitHub Pages sites. Everything passes through the
|
||||||
class="featurette-image img-fluid mx-auto"
|
same redaction filter.
|
||||||
alt="Repository explorer"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr class="featurette-divider" />
|
|
||||||
|
|
||||||
<div class="row featurette align-items-center">
|
|
||||||
<div class="col-md-7 order-md-2">
|
|
||||||
<h2 class="featurette-heading">Manage</h2>
|
|
||||||
<p class="featurette-lead">
|
|
||||||
Monitor views, edit configuration, remove or update your repository
|
|
||||||
— all from a clean dashboard.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-5 order-md-1">
|
<div class="q">
|
||||||
<img
|
<a href="/faq#expiration">What happens when an anonymized repository expires?</a>
|
||||||
width="500"
|
<p>
|
||||||
loading="lazy"
|
You choose: the mirror is removed, or visitors are redirected to the
|
||||||
src="/imgs/dashboard.png"
|
original GitHub repository once the review is over.
|
||||||
class="featurette-image img-fluid mx-auto"
|
</p>
|
||||||
alt="Dashboard"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</section>
|
||||||
|
|
||||||
<footer class="paper-footer">
|
<footer class="paper-footer">
|
||||||
<div class="paper-footer-inner">
|
<div class="paper-footer-inner">
|
||||||
<div class="paper-footer-brand">
|
<div class="paper-footer-brand">
|
||||||
<div class="paper-footer-mark">Anonymous <em>GitHub</em></div>
|
<div class="paper-footer-mark">Anonymous <em>GitHub</em></div>
|
||||||
<p class="paper-footer-tag">
|
<p class="paper-footer-tag">
|
||||||
A read-only, identity-stripped mirror of your repository —
|
A read-only, identity-stripped mirror of your repository, built for
|
||||||
built for double-blind peer review.
|
double-blind peer review.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="paper-footer-col">
|
<div class="paper-footer-col">
|
||||||
@@ -263,14 +239,14 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="paper-footer-col">
|
<div class="paper-footer-col">
|
||||||
<div class="paper-footer-head">Project</div>
|
<div class="paper-footer-head">Project</div>
|
||||||
<a href="https://github.com/tdurieux/anonymous_github/" target="_blank">Source code</a>
|
<a href="https://github.com/tdurieux/anonymous_github/" target="_blank" rel="noopener">Source code</a>
|
||||||
<a href="https://github.com/tdurieux/anonymous_github/issues/new?template=issue_report.yml" target="_blank" rel="noopener">Report a bug</a>
|
<a href="https://github.com/tdurieux/anonymous_github/issues/new?template=issue_report.yml" target="_blank" rel="noopener">Report a bug</a>
|
||||||
<a href="https://github.com/sponsors/tdurieux/" target="_blank">Sponsor</a>
|
<a href="https://github.com/sponsors/tdurieux/" target="_blank" rel="noopener">Sponsor</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="paper-footer-col">
|
<div class="paper-footer-col">
|
||||||
<div class="paper-footer-head">Contact</div>
|
<div class="paper-footer-head">Contact</div>
|
||||||
<a href="mailto:tdurieux@anonymous.4open.science">Email maintainer</a>
|
<a href="mailto:tdurieux@anonymous.4open.science">Email maintainer</a>
|
||||||
<a href="https://github.com/tdurieux" target="_blank">@tdurieux</a>
|
<a href="https://github.com/tdurieux" target="_blank" rel="noopener">@tdurieux</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="paper-footer-rule"></div>
|
<div class="paper-footer-rule"></div>
|
||||||
|
|||||||
+83
-1
@@ -1386,7 +1386,9 @@ angular
|
|||||||
"$scope",
|
"$scope",
|
||||||
"$http",
|
"$http",
|
||||||
"$location",
|
"$location",
|
||||||
function ($scope, $http, $location) {
|
"$window",
|
||||||
|
"$timeout",
|
||||||
|
function ($scope, $http, $location, $window, $timeout) {
|
||||||
if ($scope.user && !$scope.user.status) {
|
if ($scope.user && !$scope.user.status) {
|
||||||
$location.url("/dashboard");
|
$location.url("/dashboard");
|
||||||
}
|
}
|
||||||
@@ -1396,6 +1398,86 @@ angular
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// "What you get": one screenshot, three tabs. The selected key drives
|
||||||
|
// both the expanded description and the visible panel.
|
||||||
|
$scope.features = [
|
||||||
|
{
|
||||||
|
key: "anonymize",
|
||||||
|
num: "01",
|
||||||
|
eyebrow: "Anonymize",
|
||||||
|
title: "Double-anonymous,",
|
||||||
|
accent: "your rules.",
|
||||||
|
text:
|
||||||
|
"Choose what reviewers may see: links, images, PDFs, notebooks, GitHub Pages. Add your own terms, with regex if you need it, and pick the expiration date.",
|
||||||
|
cta: "Start an anonymization",
|
||||||
|
href: "/anonymize",
|
||||||
|
url: "anonymous.4open.science/anonymize",
|
||||||
|
img: "/imgs/anonymize.png",
|
||||||
|
alt: "The anonymize form: source repository, terms to redact, options and a live README preview",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "review",
|
||||||
|
num: "02",
|
||||||
|
eyebrow: "Review",
|
||||||
|
title: "Reviewers browse",
|
||||||
|
accent: "the real thing.",
|
||||||
|
text:
|
||||||
|
"Highlighted source code, rendered PDFs, images, and notebooks, in a familiar file explorer. GitHub Pages is also supported.",
|
||||||
|
cta: "Open the example",
|
||||||
|
href: "https://anonymous.4open.science/r/840c8c57-3c32-451e-bf12-0e20be300389/",
|
||||||
|
target: "_self",
|
||||||
|
url: "anonymous.4open.science/r/840c8c57-…",
|
||||||
|
img: "/imgs/explorer.png",
|
||||||
|
alt: "The repository explorer with a file tree and a rendered README",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "manage",
|
||||||
|
num: "03",
|
||||||
|
eyebrow: "Manage",
|
||||||
|
title: "One dashboard,",
|
||||||
|
accent: "until the decision.",
|
||||||
|
text:
|
||||||
|
"Monitor views, edit configuration, remove or update your repository. Program chairs can group submissions under a conference with one shared expiry.",
|
||||||
|
cta: "Open the dashboard",
|
||||||
|
href: "/dashboard",
|
||||||
|
needsUser: true,
|
||||||
|
url: "anonymous.4open.science/dashboard",
|
||||||
|
img: "/imgs/dashboard.png",
|
||||||
|
alt: "The dashboard listing anonymized repositories with status, views and expiry",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
$scope.feature = $scope.features[0].key;
|
||||||
|
$scope.selectFeature = function (key) {
|
||||||
|
$scope.feature = key;
|
||||||
|
};
|
||||||
|
// Signed-out visitors cannot open the dashboard; send them to sign in.
|
||||||
|
$scope.featureHref = function (f) {
|
||||||
|
return f.needsUser && !$scope.user ? "/github/login" : f.href;
|
||||||
|
};
|
||||||
|
$scope.featureTarget = function (f) {
|
||||||
|
return f.needsUser && !$scope.user ? "_self" : f.target || undefined;
|
||||||
|
};
|
||||||
|
$scope.featureKeydown = function ($event, index) {
|
||||||
|
const step = {
|
||||||
|
ArrowDown: 1,
|
||||||
|
ArrowRight: 1,
|
||||||
|
ArrowUp: -1,
|
||||||
|
ArrowLeft: -1,
|
||||||
|
Home: "first",
|
||||||
|
End: "last",
|
||||||
|
}[$event.key];
|
||||||
|
if (step === undefined) return;
|
||||||
|
$event.preventDefault();
|
||||||
|
const n = $scope.features.length;
|
||||||
|
const next =
|
||||||
|
step === "first" ? 0 : step === "last" ? n - 1 : (index + step + n) % n;
|
||||||
|
$scope.feature = $scope.features[next].key;
|
||||||
|
$timeout(() => {
|
||||||
|
const el = $window.document.getElementById("feature-tab-" + $scope.feature);
|
||||||
|
if (el) el.focus();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
$scope.cards = [
|
$scope.cards = [
|
||||||
{ key: "repositories", total: 0, label: "repositories anonymized" },
|
{ key: "repositories", total: 0, label: "repositories anonymized" },
|
||||||
{ key: "users", total: 0, label: "researchers" },
|
{ key: "users", total: 0, label: "researchers" },
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -140,6 +140,51 @@ describe("frontend production regressions", function () {
|
|||||||
h.scope.saveDefault(); h.requests.at(-1).reject({ data: { error: "not_connected" } }); await h.flush();
|
h.scope.saveDefault(); h.requests.at(-1).reject({ data: { error: "not_connected" } }); await h.flush();
|
||||||
expect(h.scope.error).to.equal("ERRORS.not_connected");
|
expect(h.scope.error).to.equal("ERRORS.not_connected");
|
||||||
});
|
});
|
||||||
|
describe("landing page features", function () {
|
||||||
|
const home = fs.readFileSync(path.join(__dirname, "..", "public", "partials", "home.htm"), "utf8");
|
||||||
|
function landing(user) {
|
||||||
|
const h = harness(); h.scope.user = user;
|
||||||
|
const focused = []; h.focused = focused;
|
||||||
|
const win = { document: { getElementById: id => ({ focus: () => focused.push(id) }) } };
|
||||||
|
const timeout = fn => fn();
|
||||||
|
h.defs.homeController.at(-1)(h.scope, h.http, { url() {} }, win, timeout);
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
it("selects the first feature and switches on click", function () {
|
||||||
|
const h = landing(null);
|
||||||
|
expect(h.scope.feature).to.equal("anonymize");
|
||||||
|
h.scope.selectFeature("manage"); expect(h.scope.feature).to.equal("manage");
|
||||||
|
});
|
||||||
|
it("moves between tabs with the arrow keys, wrapping and moving focus", function () {
|
||||||
|
const h = landing(null); let prevented = 0;
|
||||||
|
const key = k => ({ key: k, preventDefault: () => prevented++ });
|
||||||
|
h.scope.featureKeydown(key("ArrowDown"), 0); expect(h.scope.feature).to.equal("review");
|
||||||
|
h.scope.featureKeydown(key("ArrowUp"), 1); expect(h.scope.feature).to.equal("anonymize");
|
||||||
|
h.scope.featureKeydown(key("ArrowUp"), 0); expect(h.scope.feature).to.equal("manage");
|
||||||
|
h.scope.featureKeydown(key("End"), 0); expect(h.scope.feature).to.equal("manage");
|
||||||
|
h.scope.featureKeydown(key("Home"), 2); expect(h.scope.feature).to.equal("anonymize");
|
||||||
|
h.scope.featureKeydown(key("Tab"), 0); expect(h.scope.feature).to.equal("anonymize");
|
||||||
|
expect(prevented).to.equal(5);
|
||||||
|
expect(h.focused).to.deep.equal(["review", "anonymize", "manage", "manage", "anonymize"].map(k => "feature-tab-" + k));
|
||||||
|
});
|
||||||
|
it("sends signed-out visitors to sign in instead of the dashboard", function () {
|
||||||
|
const manage = f => f.key === "manage";
|
||||||
|
const out = landing(null);
|
||||||
|
expect(out.scope.featureHref(out.scope.features.find(manage))).to.equal("/github/login");
|
||||||
|
expect(out.scope.featureTarget(out.scope.features.find(manage))).to.equal("_self");
|
||||||
|
const signedIn = landing({ username: "jane" });
|
||||||
|
expect(signedIn.scope.featureHref(signedIn.scope.features.find(manage))).to.equal("/dashboard");
|
||||||
|
expect(signedIn.scope.featureTarget(signedIn.scope.features.find(manage))).to.equal(undefined);
|
||||||
|
});
|
||||||
|
it("marks the tabs up as tabs and keeps links out of the buttons", function () {
|
||||||
|
expect(home).to.match(/<button[^>]*class="paper-feature-tab"[^>]*role="tab"/);
|
||||||
|
expect(home).to.match(/role="tablist"/);
|
||||||
|
expect(home).to.match(/role="tabpanel"[^>]*aria-labelledby="feature-tab-\{\{f\.key\}\}"/);
|
||||||
|
const button = home.slice(home.indexOf('class="paper-feature-tab"'), home.indexOf("</button>"));
|
||||||
|
expect(button).to.not.include("<a ");
|
||||||
|
expect(home).to.not.match(/href="#"/);
|
||||||
|
});
|
||||||
|
});
|
||||||
it("keeps the conference end date after the start across December", function () {
|
it("keeps the conference end date after the start across December", function () {
|
||||||
class December extends Date { constructor(...args) { super(...(args.length ? args : ["2026-12-15T12:00:00Z"])); } }
|
class December extends Date { constructor(...args) { super(...(args.length ? args : ["2026-12-15T12:00:00Z"])); } }
|
||||||
const h = harness(December); h.scope.user = {};
|
const h = harness(December); h.scope.user = {};
|
||||||
|
|||||||
Reference in New Issue
Block a user