SVG Octicon fixes (#10237)

* SVG fixes

Signed-off-by: jolheiser <john.olheiser@gmail.com>

* Colorize span->svg only

Signed-off-by: jolheiser <john.olheiser@gmail.com>

* @silverwind suggestions

Signed-off-by: jolheiser <john.olheiser@gmail.com>

* Alphabetical

Signed-off-by: jolheiser <john.olheiser@gmail.com>

* Convert suburl and staticPrefix to window.config

Signed-off-by: jolheiser <john.olheiser@gmail.com>

* De-structure

Signed-off-by: jolheiser <john.olheiser@gmail.com>

Co-authored-by: Antoine GIRARD <sapk@users.noreply.github.com>
tokarchuk/v1.17
John Olheiser 5 years ago committed by GitHub
parent 2399bad1f1
commit d67e9b9629
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      .eslintrc
  2. 4
      templates/base/head.tmpl
  3. 2
      templates/repo/issue/view_title.tmpl
  4. 31
      web_src/js/features/contextPopup.js
  5. 57
      web_src/js/index.js
  6. 5
      web_src/js/utils.js
  7. 6
      web_src/less/_base.less
  8. 26
      web_src/less/_repository.less

@ -33,6 +33,7 @@ rules:
default-case: [0] default-case: [0]
func-names: [0] func-names: [0]
import/extensions: [0] import/extensions: [0]
import/prefer-default-export: [0]
max-len: [0] max-len: [0]
newline-per-chained-call: [0] newline-per-chained-call: [0]
no-alert: [0] no-alert: [0]

@ -36,8 +36,6 @@
<meta name="keywords" content="{{MetaKeywords}}"> <meta name="keywords" content="{{MetaKeywords}}">
<meta name="referrer" content="no-referrer" /> <meta name="referrer" content="no-referrer" />
<meta name="_csrf" content="{{.CsrfToken}}" /> <meta name="_csrf" content="{{.CsrfToken}}" />
<meta name="_suburl" content="{{AppSubUrl}}" />
<meta name="_staticprefix" content="{{StaticUrlPrefix}}" />
{{if .IsSigned}} {{if .IsSigned}}
<meta name="_uid" content="{{.SignedUser.ID}}" /> <meta name="_uid" content="{{.SignedUser.ID}}" />
{{end}} {{end}}
@ -86,6 +84,8 @@
</script> </script>
<script> <script>
window.config = { window.config = {
AppSubUrl: '{{AppSubUrl}}',
StaticUrlPrefix: '{{StaticUrlPrefix}}',
Datetimepicker: {{if .RequireDatetimepicker}}true{{else}}false{{end}}, Datetimepicker: {{if .RequireDatetimepicker}}true{{else}}false{{end}},
Dropzone: {{if .RequireDropzone}}true{{else}}false{{end}}, Dropzone: {{if .RequireDropzone}}true{{else}}false{{end}},
HighlightJS: {{if .RequireHighlightJS}}true{{else}}false{{end}}, HighlightJS: {{if .RequireHighlightJS}}true{{else}}false{{end}},

@ -17,7 +17,7 @@
{{end}} {{end}}
</div> </div>
{{if .HasMerged}} {{if .HasMerged}}
<div class="ui purple large label">{{svg "octicon-gt-pull-request" 16}} {{.i18n.Tr "repo.pulls.merged"}}</div> <div class="ui purple large label">{{svg "octicon-git-pull-request" 16}} {{.i18n.Tr "repo.pulls.merged"}}</div>
{{else if .Issue.IsClosed}} {{else if .Issue.IsClosed}}
<div class="ui red large label">{{svg "octicon-issue-closed" 16}} {{.i18n.Tr "repo.issues.closed_title"}}</div> <div class="ui red large label">{{svg "octicon-issue-closed" 16}} {{.i18n.Tr "repo.issues.closed_title"}}</div>
{{else if .Issue.IsPull}} {{else if .Issue.IsPull}}

@ -1,15 +1,19 @@
export default function initContextPopups(suburl) { import { svg } from '../utils.js';
const { AppSubUrl } = window.config;
export default function initContextPopups() {
const refIssues = $('.ref-issue'); const refIssues = $('.ref-issue');
if (!refIssues.length) return; if (!refIssues.length) return;
refIssues.each(function () { refIssues.each(function () {
const [index, _issues, repo, owner] = $(this).attr('href').replace(/[#?].*$/, '').split('/').reverse(); const [index, _issues, repo, owner] = $(this).attr('href').replace(/[#?].*$/, '').split('/').reverse();
issuePopup(suburl, owner, repo, index, $(this)); issuePopup(owner, repo, index, $(this));
}); });
} }
function issuePopup(suburl, owner, repo, index, $element) { function issuePopup(owner, repo, index, $element) {
$.get(`${suburl}/api/v1/repos/${owner}/${repo}/issues/${index}`, (issue) => { $.get(`${AppSubUrl}/api/v1/repos/${owner}/${repo}/issues/${index}`, (issue) => {
const createdAt = new Date(issue.created_at).toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' }); const createdAt = new Date(issue.created_at).toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' });
let body = issue.body.replace(/\n+/g, ' '); let body = issue.body.replace(/\n+/g, ' ');
@ -34,19 +38,24 @@ function issuePopup(suburl, owner, repo, index, $element) {
labels = `<p>${labels}</p>`; labels = `<p>${labels}</p>`;
} }
let octicon; let octicon, color;
if (issue.pull_request !== null) { if (issue.pull_request !== null) {
if (issue.state === 'open') { if (issue.state === 'open') {
octicon = 'green octicon-git-pull-request'; // Open PR color = 'green';
octicon = 'octicon-git-pull-request'; // Open PR
} else if (issue.pull_request.merged === true) { } else if (issue.pull_request.merged === true) {
octicon = 'purple octicon-git-merge'; // Merged PR color = 'purple';
octicon = 'octicon-git-merge'; // Merged PR
} else { } else {
octicon = 'red octicon-git-pull-request'; // Closed PR color = 'red';
octicon = 'octicon-git-pull-request'; // Closed PR
} }
} else if (issue.state === 'open') { } else if (issue.state === 'open') {
octicon = 'green octicon-issue-opened'; // Open Issue color = 'green';
octicon = 'octicon-issue-opened'; // Open Issue
} else { } else {
octicon = 'red octicon-issue-closed'; // Closed Issue color = 'red';
octicon = 'octicon-issue-closed'; // Closed Issue
} }
$element.popup({ $element.popup({
@ -57,7 +66,7 @@ function issuePopup(suburl, owner, repo, index, $element) {
html: ` html: `
<div> <div>
<p><small>${issue.repository.full_name} on ${createdAt}</small></p> <p><small>${issue.repository.full_name} on ${createdAt}</small></p>
<p><i class="octicon ${octicon}"></i> <strong>${issue.title}</strong> #${index}</p> <p><span class="${color}">${svg(octicon, 16)}</span> <strong>${issue.title}</strong> #${index}</p>
<p>${body}</p> <p>${body}</p>
${labels} ${labels}
</div> </div>

@ -6,6 +6,7 @@ import 'jquery.are-you-sure';
import './publicPath.js'; import './publicPath.js';
import './polyfills.js'; import './polyfills.js';
import './vendor/semanticDropdown.js'; import './vendor/semanticDropdown.js';
import { svg } from './utils.js';
import initContextPopups from './features/contextPopup.js'; import initContextPopups from './features/contextPopup.js';
import initHighlight from './features/highlight.js'; import initHighlight from './features/highlight.js';
@ -14,17 +15,13 @@ import initClipboard from './features/clipboard.js';
import ActivityTopAuthors from './components/ActivityTopAuthors.vue'; import ActivityTopAuthors from './components/ActivityTopAuthors.vue';
const { AppSubUrl, StaticUrlPrefix } = window.config;
function htmlEncode(text) { function htmlEncode(text) {
return jQuery('<div />').text(text).html(); return jQuery('<div />').text(text).html();
} }
function svg(name, size) {
return `<svg class="svg ${name}" width="${size}" height="${size}" aria-hidden="true"><use xlink:href="${staticPrefix}/img/svg/icons.svg#${name}"/></svg>`;
}
let csrf; let csrf;
let suburl;
let staticPrefix;
let previewFileModes; let previewFileModes;
let simpleMDEditor; let simpleMDEditor;
const commentMDEditors = {}; const commentMDEditors = {};
@ -157,7 +154,7 @@ function initRepoStatusChecker() {
} }
$.ajax({ $.ajax({
type: 'GET', type: 'GET',
url: `${suburl}/${repo_name}/status`, url: `${AppSubUrl}/${repo_name}/status`,
data: { data: {
_csrf: csrf, _csrf: csrf,
}, },
@ -293,7 +290,7 @@ function uploadFile(file, callback) {
} }
}; };
xhr.open('post', `${suburl}/attachments`, true); xhr.open('post', `${AppSubUrl}/attachments`, true);
xhr.setRequestHeader('X-Csrf-Token', csrf); xhr.setRequestHeader('X-Csrf-Token', csrf);
const formData = new FormData(); const formData = new FormData();
formData.append('file', file, file.name); formData.append('file', file, file.name);
@ -313,7 +310,7 @@ function initImagePaste(target) {
insertAtCursor(field, `![${name}]()`); insertAtCursor(field, `![${name}]()`);
uploadFile(img, (res) => { uploadFile(img, (res) => {
const data = JSON.parse(res); const data = JSON.parse(res);
replaceAndKeepCursor(field, `![${name}]()`, `![${name}](${suburl}/attachments/${data.uuid})`); replaceAndKeepCursor(field, `![${name}]()`, `![${name}](${AppSubUrl}/attachments/${data.uuid})`);
const input = $(`<input id="${data.uuid}" name="files" type="hidden">`).val(data.uuid); const input = $(`<input id="${data.uuid}" name="files" type="hidden">`).val(data.uuid);
$('.files').append(input); $('.files').append(input);
}); });
@ -329,7 +326,7 @@ function initSimpleMDEImagePaste(simplemde, files) {
uploadFile(img, (res) => { uploadFile(img, (res) => {
const data = JSON.parse(res); const data = JSON.parse(res);
const pos = simplemde.codemirror.getCursor(); const pos = simplemde.codemirror.getCursor();
simplemde.codemirror.replaceRange(`![${name}](${suburl}/attachments/${data.uuid})`, pos); simplemde.codemirror.replaceRange(`![${name}](${AppSubUrl}/attachments/${data.uuid})`, pos);
const input = $(`<input id="${data.uuid}" name="files" type="hidden">`).val(data.uuid); const input = $(`<input id="${data.uuid}" name="files" type="hidden">`).val(data.uuid);
files.append(input); files.append(input);
}); });
@ -2059,7 +2056,7 @@ function searchUsers() {
$searchUserBox.search({ $searchUserBox.search({
minCharacters: 2, minCharacters: 2,
apiSettings: { apiSettings: {
url: `${suburl}/api/v1/users/search?q={query}`, url: `${AppSubUrl}/api/v1/users/search?q={query}`,
onResponse(response) { onResponse(response) {
const items = []; const items = [];
$.each(response.data, (_i, item) => { $.each(response.data, (_i, item) => {
@ -2086,7 +2083,7 @@ function searchTeams() {
$searchTeamBox.search({ $searchTeamBox.search({
minCharacters: 2, minCharacters: 2,
apiSettings: { apiSettings: {
url: `${suburl}/api/v1/orgs/${$searchTeamBox.data('org')}/teams/search?q={query}`, url: `${AppSubUrl}/api/v1/orgs/${$searchTeamBox.data('org')}/teams/search?q={query}`,
headers: { 'X-Csrf-Token': csrf }, headers: { 'X-Csrf-Token': csrf },
onResponse(response) { onResponse(response) {
const items = []; const items = [];
@ -2110,7 +2107,7 @@ function searchRepositories() {
$searchRepoBox.search({ $searchRepoBox.search({
minCharacters: 2, minCharacters: 2,
apiSettings: { apiSettings: {
url: `${suburl}/api/v1/repos/search?q={query}&uid=${$searchRepoBox.data('uid')}`, url: `${AppSubUrl}/api/v1/repos/search?q={query}&uid=${$searchRepoBox.data('uid')}`,
onResponse(response) { onResponse(response) {
const items = []; const items = [];
$.each(response.data, (_i, item) => { $.each(response.data, (_i, item) => {
@ -2180,7 +2177,7 @@ function initU2FAuth() {
} }
u2fApi.ensureSupport() u2fApi.ensureSupport()
.then(() => { .then(() => {
$.getJSON(`${suburl}/user/u2f/challenge`).success((req) => { $.getJSON(`${AppSubUrl}/user/u2f/challenge`).success((req) => {
u2fApi.sign(req.appId, req.challenge, req.registeredKeys, 30) u2fApi.sign(req.appId, req.challenge, req.registeredKeys, 30)
.then(u2fSigned) .then(u2fSigned)
.catch((err) => { .catch((err) => {
@ -2193,12 +2190,12 @@ function initU2FAuth() {
}); });
}).catch(() => { }).catch(() => {
// Fallback in case browser do not support U2F // Fallback in case browser do not support U2F
window.location.href = `${suburl}/user/two_factor`; window.location.href = `${AppSubUrl}/user/two_factor`;
}); });
} }
function u2fSigned(resp) { function u2fSigned(resp) {
$.ajax({ $.ajax({
url: `${suburl}/user/u2f/sign`, url: `${AppSubUrl}/user/u2f/sign`,
type: 'POST', type: 'POST',
headers: { 'X-Csrf-Token': csrf }, headers: { 'X-Csrf-Token': csrf },
data: JSON.stringify(resp), data: JSON.stringify(resp),
@ -2215,7 +2212,7 @@ function u2fRegistered(resp) {
return; return;
} }
$.ajax({ $.ajax({
url: `${suburl}/user/settings/security/u2f/register`, url: `${AppSubUrl}/user/settings/security/u2f/register`,
type: 'POST', type: 'POST',
headers: { 'X-Csrf-Token': csrf }, headers: { 'X-Csrf-Token': csrf },
data: JSON.stringify(resp), data: JSON.stringify(resp),
@ -2274,7 +2271,7 @@ function initU2FRegister() {
} }
function u2fRegisterRequest() { function u2fRegisterRequest() {
$.post(`${suburl}/user/settings/security/u2f/request_register`, { $.post(`${AppSubUrl}/user/settings/security/u2f/request_register`, {
_csrf: csrf, _csrf: csrf,
name: $('#nickname').val() name: $('#nickname').val()
}).success((req) => { }).success((req) => {
@ -2337,7 +2334,7 @@ function initTemplateSearch() {
$('#repo_template_search') $('#repo_template_search')
.dropdown({ .dropdown({
apiSettings: { apiSettings: {
url: `${suburl}/api/v1/repos/search?q={query}&template=true&priority_owner_id=${$('#uid').val()}`, url: `${AppSubUrl}/api/v1/repos/search?q={query}&template=true&priority_owner_id=${$('#uid').val()}`,
onResponse(response) { onResponse(response) {
const filteredResponse = { success: true, results: [] }; const filteredResponse = { success: true, results: [] };
filteredResponse.results.push({ filteredResponse.results.push({
@ -2365,8 +2362,6 @@ function initTemplateSearch() {
$(document).ready(async () => { $(document).ready(async () => {
csrf = $('meta[name=_csrf]').attr('content'); csrf = $('meta[name=_csrf]').attr('content');
suburl = $('meta[name=_suburl]').attr('content');
staticPrefix = $('meta[name=_staticprefix]').attr('content');
// Show exact time // Show exact time
$('.time-since').each(function () { $('.time-since').each(function () {
@ -2455,7 +2450,7 @@ $(document).ready(async () => {
// Emojify // Emojify
emojify.setConfig({ emojify.setConfig({
img_dir: `${suburl}/vendor/plugins/emojify/images`, img_dir: `${AppSubUrl}/vendor/plugins/emojify/images`,
ignore_emoticons: true ignore_emoticons: true
}); });
const hasEmoji = document.getElementsByClassName('has-emoji'); const hasEmoji = document.getElementsByClassName('has-emoji');
@ -2575,7 +2570,7 @@ $(document).ready(async () => {
initPullRequestReview(); initPullRequestReview();
initRepoStatusChecker(); initRepoStatusChecker();
initTemplateSearch(); initTemplateSearch();
initContextPopups(suburl); initContextPopups();
// Repo clone url. // Repo clone url.
if ($('#repo-clone-url').length > 0) { if ($('#repo-clone-url').length > 0) {
@ -2785,7 +2780,7 @@ function initVueComponents() {
reposFilter: 'all', reposFilter: 'all',
searchQuery: '', searchQuery: '',
isLoading: false, isLoading: false,
staticPrefix, staticPrefix: StaticUrlPrefix,
repoTypes: { repoTypes: {
all: { all: {
count: 0, count: 0,
@ -2891,6 +2886,8 @@ function initVueComponents() {
return 'octicon-repo-forked'; return 'octicon-repo-forked';
} if (repo.mirror) { } if (repo.mirror) {
return 'octicon-repo-clone'; return 'octicon-repo-clone';
} if (repo.template) {
return `octicon-repo-template${repo.private ? '-private' : ''}`;
} if (repo.private) { } if (repo.private) {
return 'octicon-lock'; return 'octicon-lock';
} }
@ -2921,7 +2918,7 @@ function initVueApp() {
el, el,
data: { data: {
searchLimit: (document.querySelector('meta[name=_search_limit]') || {}).content, searchLimit: (document.querySelector('meta[name=_search_limit]') || {}).content,
suburl: document.querySelector('meta[name=_suburl]').content, suburl: AppSubUrl,
uid: Number((document.querySelector('meta[name=_context_uid]') || {}).content), uid: Number((document.querySelector('meta[name=_context_uid]') || {}).content),
activityTopAuthors: window.ActivityTopAuthors || [], activityTopAuthors: window.ActivityTopAuthors || [],
}, },
@ -3037,7 +3034,7 @@ window.initHeatmap = function (appElementId, heatmapUser, locale) {
el, el,
data: { data: {
suburl: document.querySelector('meta[name=_suburl]').content, suburl: AppSubUrl,
heatmapUser, heatmapUser,
locale locale
}, },
@ -3283,7 +3280,7 @@ function initTopicbar() {
const last = viewDiv.children('a').last(); const last = viewDiv.children('a').last();
for (let i = 0; i < topicArray.length; i++) { for (let i = 0; i < topicArray.length; i++) {
const link = $('<a class="ui repo-topic small label topic"></a>'); const link = $('<a class="ui repo-topic small label topic"></a>');
link.attr('href', `${suburl}/explore/repos?q=${encodeURIComponent(topicArray[i])}&topic=1`); link.attr('href', `${AppSubUrl}/explore/repos?q=${encodeURIComponent(topicArray[i])}&topic=1`);
link.text(topicArray[i]); link.text(topicArray[i]);
link.insertBefore(last); link.insertBefore(last);
} }
@ -3331,7 +3328,7 @@ function initTopicbar() {
label: 'ui small label' label: 'ui small label'
}, },
apiSettings: { apiSettings: {
url: `${suburl}/api/v1/topics/search?q={query}`, url: `${AppSubUrl}/api/v1/topics/search?q={query}`,
throttle: 500, throttle: 500,
cache: false, cache: false,
onResponse(res) { onResponse(res) {
@ -3488,9 +3485,9 @@ function initIssueList() {
const repoId = $('#repoId').val(); const repoId = $('#repoId').val();
const crossRepoSearch = $('#crossRepoSearch').val(); const crossRepoSearch = $('#crossRepoSearch').val();
const tp = $('#type').val(); const tp = $('#type').val();
let issueSearchUrl = `${suburl}/api/v1/repos/${repolink}/issues?q={query}&type=${tp}`; let issueSearchUrl = `${AppSubUrl}/api/v1/repos/${repolink}/issues?q={query}&type=${tp}`;
if (crossRepoSearch === 'true') { if (crossRepoSearch === 'true') {
issueSearchUrl = `${suburl}/api/v1/repos/issues/search?q={query}&priority_repo_id=${repoId}&type=${tp}`; issueSearchUrl = `${AppSubUrl}/api/v1/repos/issues/search?q={query}&priority_repo_id=${repoId}&type=${tp}`;
} }
$('#new-dependency-drop-list') $('#new-dependency-drop-list')
.dropdown({ .dropdown({

@ -0,0 +1,5 @@
const { StaticUrlPrefix } = window.config;
export function svg(name, size) {
return `<svg class="svg ${name}" width="${size}" height="${size}" aria-hidden="true"><use xlink:href="${StaticUrlPrefix}/img/svg/icons.svg#${name}"/></svg>`;
}

@ -1168,13 +1168,13 @@ i.icon.centerlock {
} }
.svg { .svg {
&.green { span.green & {
color: #21ba45; color: #21ba45;
} }
&.red { span.red & {
color: #db2828; color: #db2828;
} }
&.purple { span.purple & {
color: #a333c8; color: #a333c8;
} }
} }

@ -35,7 +35,7 @@
.svg.octicon-repo-forked { .svg.octicon-repo-forked {
margin-top: -1px; margin-top: -1px;
font-size: 15px; height: 15px;
} }
.button { .button {
@ -670,7 +670,7 @@
.svg { .svg {
width: 23px; width: 23px;
font-size: 23px; height: 23px;
margin-top: 0.45em; margin-top: 0.45em;
} }
} }
@ -935,36 +935,36 @@
&.octicon-circle-slash { &.octicon-circle-slash {
margin-top: 5px; margin-top: 5px;
margin-left: -34.5px; margin-left: -35.5px;
font-size: 20px; height: 20px;
color: #bd2c00; color: #bd2c00;
} }
&.octicon-primitive-dot { &.octicon-primitive-dot {
margin-top: -1px; margin-top: -1px;
margin-left: -28.5px; margin-left: -35.5px;
margin-right: -1px; margin-right: -1px;
font-size: 30px; height: 30px;
color: #6cc644; color: #6cc644;
} }
&.octicon-bookmark { &.octicon-bookmark {
margin-top: 2px; margin-top: 2px;
margin-left: -31px; margin-left: -35.5px;
margin-right: -1px; margin-right: -1px;
font-size: 25px; height: 25px;
} }
&.octicon-eye { &.octicon-eye {
margin-top: 3px; margin-top: 3px;
margin-left: -36px; margin-left: -35.5px;
margin-right: 0; margin-right: 0;
font-size: 22px; height: 22px;
} }
&.octicon-x { &.octicon-x {
margin-left: -33px; margin-left: -35.5px;
font-size: 25px; height: 25px;
} }
} }
@ -1724,7 +1724,7 @@
padding-bottom: 100px; padding-bottom: 100px;
.svg { .svg {
font-size: 48px; height: 48px;
} }
} }
} }

Loading…
Cancel
Save