Skip to content

Commit ef0e0e2

Browse files
authored
Merge pull request #1317 from github/qjquery
remove ancient jquery dependency replace with vanilla javascript
2 parents a2f37e2 + 69328eb commit ef0e0e2

File tree

15 files changed

+105
-11051
lines changed

15 files changed

+105
-11051
lines changed

_includes/footer.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
</div> <!-- /container -->
1717

1818
{% if page.collection == "licenses" or page.class == "license-types" %}
19-
<script src="{{ 'assets/vendor/jquery/jquery.min.js' | relative_url }}"></script>
2019
<script src="{{ 'assets/vendor/clipboard/dist/clipboard.min.js' | relative_url }}"></script>
2120
<script>
2221
window.annotations = {{ site.data.rules | jsonify }};

assets/js/app.js

Lines changed: 105 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
1+
const TOOLTIP_CLASSES = ['hint--bottom', 'hint--large', 'hint--no-animate', 'override-hint-inline'];
2+
const TOOLTIP_ATTRIBUTES_BY_RULE = {
3+
permissions: {
4+
heading: 'Permission',
5+
color: 'tooltip--permissions'
6+
},
7+
conditions: {
8+
heading: 'Condition',
9+
color: 'tooltip--conditions'
10+
},
11+
limitations: {
12+
heading: 'Limitation',
13+
color: 'tooltip--limitations'
14+
}
15+
};
16+
117
class Choosealicense {
218
constructor() {
3-
this.tooltipAttributesMapperByRuleType = {
4-
permissions: {
5-
heading: 'Permission',
6-
color: 'tooltip--permissions'
7-
},
8-
conditions: {
9-
heading: 'Condition',
10-
color: 'tooltip--conditions'
11-
},
12-
limitations: {
13-
heading: 'Limitation',
14-
color: 'tooltip--limitations'
15-
}
16-
};
17-
1819
this.initTooltips();
1920
this.initClipboard();
2021
this.initLicenseSuggestion();
@@ -42,52 +43,59 @@ class Choosealicense {
4243

4344
Object.entries(annotations).forEach(([ruletype, rules]) => {
4445
rules.forEach((rule) => {
45-
const licenseLiElement = $(`.license-${ruletype} .${rule.tag}`).not(
46-
`dd.license-${ruletype} .${rule.tag}`
47-
);
48-
const tooltipAttr = this.tooltipAttributesMapperByRuleType[ruletype];
46+
const tooltipAttr = TOOLTIP_ATTRIBUTES_BY_RULE[ruletype];
4947
if (!tooltipAttr) return;
5048

51-
licenseLiElement.attr(
52-
'aria-label',
53-
`${rule.label} ${tooltipAttr.heading.toLowerCase()}: ${rule.description}`
54-
);
55-
licenseLiElement.addClass(
56-
`hint--bottom
57-
hint--large
58-
hint--no-animate
59-
${tooltipAttr.color}
60-
override-hint-inline`
61-
);
49+
const elements = Array.from(
50+
document.querySelectorAll(`.license-${ruletype} .${rule.tag}`)
51+
).filter((el) => !el.closest(`dd.license-${ruletype}`));
52+
53+
elements.forEach((el) => {
54+
el.setAttribute(
55+
'aria-label',
56+
`${rule.label} ${tooltipAttr.heading.toLowerCase()}: ${rule.description}`
57+
);
58+
el.classList.add(...TOOLTIP_CLASSES, tooltipAttr.color);
59+
});
6260
});
6361
});
6462
}
6563

6664
// Initializes Clipboard.js
6765
initClipboard() {
68-
const clipboardPrompt = $('.js-clipboard-button').text();
69-
$('.js-clipboard-button').data('clipboard-prompt', clipboardPrompt);
66+
const buttons = document.querySelectorAll('.js-clipboard-button');
67+
buttons.forEach((button) => {
68+
button.dataset.clipboardPrompt = button.textContent;
69+
});
7070

7171
const clip = new Clipboard('.js-clipboard-button');
72-
clip.on('mouseout', this.clipboardMouseout);
73-
clip.on('complete', this.clipboardComplete);
72+
clip.on('mouseout', (event) => this.clipboardMouseout(event));
73+
clip.on('complete', (event) => this.clipboardComplete(event));
7474
}
7575

7676
// Callback to restore the clipboard button's original text
77-
clipboardMouseout(client, args) {
78-
this.textContent = $(this).data('clipboard-prompt');
77+
clipboardMouseout(event) {
78+
const trigger = event && event.trigger;
79+
if (trigger) {
80+
trigger.textContent = trigger.dataset.clipboardPrompt || '';
81+
}
7982
}
8083

8184
// Post-copy user feedback callback
82-
clipboardComplete(client, args) {
83-
this.textContent = 'Copied!';
85+
clipboardComplete(event) {
86+
const trigger = event && event.trigger;
87+
if (trigger) {
88+
trigger.textContent = 'Copied!';
89+
}
8490
}
8591

8692
// Initializes the repository suggestion feature
8793
initLicenseSuggestion() {
88-
const inputEl = $('#repository-url');
89-
const licenseId = inputEl.attr('data-license-id');
90-
const statusIndicator = $('.status-indicator');
94+
const inputEl = document.querySelector('#repository-url');
95+
const statusIndicator = document.querySelector('.status-indicator');
96+
if (!inputEl || !statusIndicator) return;
97+
98+
const licenseId = inputEl.getAttribute('data-license-id');
9199
new LicenseSuggestion(inputEl, licenseId, statusIndicator);
92100
}
93101
}
@@ -97,51 +105,48 @@ class LicenseSuggestion {
97105
this.inputEl = inputEl;
98106
this.licenseId = licenseId;
99107
this.statusIndicator = statusIndicator;
100-
this.inputWrapper = $('.input-wrapper');
101-
this.tooltipErrorClasses = 'hint--bottom tooltip--error hint--always';
108+
this.inputWrapper = document.querySelector('.input-wrapper');
109+
this.tooltipErrorClasses = ['hint--bottom', 'tooltip--error', 'hint--always'];
102110

103111
this.bindEventHandlers();
104112
}
105113

106114
// Main event handlers for user input
107115
bindEventHandlers() {
108-
this.inputEl
109-
.on('input', () => {
110-
this.setStatus('');
111-
})
112-
.on('keyup', (event) => {
113-
if (event.keyCode === 13 && event.target.value) {
114-
let repositoryFullName;
115-
try {
116-
repositoryFullName = this.parseUserInput(event.target.value);
117-
} catch (error) {
118-
this.setStatus('Error', 'Invalid URL.');
119-
return;
120-
}
116+
this.inputEl.addEventListener('input', () => {
117+
this.setStatus('');
118+
});
119+
120+
this.inputEl.addEventListener('keyup', (event) => {
121+
if (event.key !== 'Enter' || !event.target.value) return;
122+
123+
let repositoryFullName;
124+
try {
125+
repositoryFullName = this.parseUserInput(event.target.value);
126+
} catch (error) {
127+
this.setStatus('Error', 'Invalid URL.');
128+
return;
129+
}
121130

122-
this.setStatus('Fetching');
123-
this.fetchInfoFromGithubAPI(
124-
repositoryFullName,
125-
(err, repositoryInfo = null) => {
126-
if (err) {
127-
this.setStatus('Error', err.message);
128-
return;
129-
}
130-
if (repositoryInfo.license) {
131-
const license = repositoryInfo.license;
132-
this.setStatus('Error', this.repositoryLicense(repositoryFullName, license));
133-
} else {
134-
const licenseUrl = encodeURIComponent(
135-
`https://github.com/${repositoryFullName}/community/license/new?template=${this.licenseId}`
136-
);
137-
window.location.href = `https://github.com/login?return_to=${licenseUrl}`;
138-
this.setStatus('');
139-
this.inputEl.val('');
140-
}
141-
}
131+
this.setStatus('Fetching');
132+
this.fetchInfoFromGithubAPI(repositoryFullName, (err, repositoryInfo = null) => {
133+
if (err) {
134+
this.setStatus('Error', err.message);
135+
return;
136+
}
137+
if (repositoryInfo.license) {
138+
const license = repositoryInfo.license;
139+
this.setStatus('Error', this.repositoryLicense(repositoryFullName, license));
140+
} else {
141+
const licenseUrl = encodeURIComponent(
142+
`https://github.com/${repositoryFullName}/community/license/new?template=${this.licenseId}`
142143
);
144+
window.location.href = `https://github.com/login?return_to=${licenseUrl}`;
145+
this.setStatus('');
146+
this.inputEl.value = '';
143147
}
144148
});
149+
});
145150
}
146151

147152
// Try to extract the repository full name from the user input
@@ -157,36 +162,44 @@ class LicenseSuggestion {
157162
setStatus(status = '', message = '') {
158163
const statusClass = status.toLowerCase();
159164
const displayTooltip = (s, m) => {
160-
this.inputWrapper.attr('aria-label', `${s}: ${m}`);
161-
this.inputWrapper.addClass(this.tooltipErrorClasses);
165+
if (!this.inputWrapper) return;
166+
this.inputWrapper.setAttribute('aria-label', `${s}: ${m}`);
167+
this.inputWrapper.classList.add(...this.tooltipErrorClasses);
162168
};
163169

164170
switch (status) {
165171
case 'Fetching':
166-
this.statusIndicator.removeClass(`error ${this.tooltipErrorClasses}`).addClass(statusClass);
172+
this.statusIndicator.classList.remove('error', ...this.tooltipErrorClasses);
173+
this.statusIndicator.classList.add(statusClass);
167174
break;
168175
case 'Error':
169-
this.statusIndicator.removeClass('fetching').addClass(statusClass);
176+
this.statusIndicator.classList.remove('fetching');
177+
this.statusIndicator.classList.add(statusClass);
170178
displayTooltip(status, message);
171179
break;
172180
default:
173-
this.statusIndicator.removeClass('fetching error');
174-
this.inputWrapper.removeClass(this.tooltipErrorClasses);
181+
this.statusIndicator.classList.remove('fetching', 'error');
182+
if (this.inputWrapper) {
183+
this.inputWrapper.classList.remove(...this.tooltipErrorClasses);
184+
}
175185
break;
176186
}
177187
}
178188

179189
// Fetches information about a repository from the Github API
180190
fetchInfoFromGithubAPI(repositoryFullName, callback) {
181-
$.getJSON(`https://api.github.com/repos/${repositoryFullName}`, (info) => {
182-
callback(null, info);
183-
}).fail((e) => {
184-
if (e.status === 404) {
185-
callback(new Error(`Repository ${repositoryFullName} not found.`));
186-
} else {
187-
callback(new Error(`Network error when trying to get information about ${repositoryFullName}.`));
188-
}
189-
});
191+
fetch(`https://api.github.com/repos/${repositoryFullName}`)
192+
.then((response) => {
193+
if (!response.ok) {
194+
if (response.status === 404) {
195+
throw new Error(`Repository ${repositoryFullName} not found.`);
196+
}
197+
throw new Error(`Network error when trying to get information about ${repositoryFullName}.`);
198+
}
199+
return response.json();
200+
})
201+
.then((info) => callback(null, info))
202+
.catch((error) => callback(error));
190203
}
191204

192205
// Generates a message showing that a repository is already licensed
@@ -199,6 +212,6 @@ class LicenseSuggestion {
199212
}
200213
}
201214

202-
$(() => {
215+
document.addEventListener('DOMContentLoaded', () => {
203216
new Choosealicense();
204217
});

assets/vendor/jquery/.bower.json

Lines changed: 0 additions & 21 deletions
This file was deleted.

assets/vendor/jquery/.gitignore

Lines changed: 0 additions & 1 deletion
This file was deleted.

assets/vendor/jquery/README.md

Lines changed: 0 additions & 11 deletions
This file was deleted.

assets/vendor/jquery/bower.json

Lines changed: 0 additions & 11 deletions
This file was deleted.

assets/vendor/jquery/component.json

Lines changed: 0 additions & 15 deletions
This file was deleted.

assets/vendor/jquery/composer.json

Lines changed: 0 additions & 35 deletions
This file was deleted.

0 commit comments

Comments
 (0)