summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/features/sync-pr-commit-title.tsx62
-rw-r--r--source/github-helpers/index.test.ts12
-rw-r--r--source/github-helpers/index.ts4
-rw-r--r--source/helpers/pr-commit-cleaner.test.ts13
-rw-r--r--source/helpers/pr-commit-cleaner.ts6
5 files changed, 59 insertions, 38 deletions
diff --git a/source/features/sync-pr-commit-title.tsx b/source/features/sync-pr-commit-title.tsx
index 37ad9a27..36aa04d1 100644
--- a/source/features/sync-pr-commit-title.tsx
+++ b/source/features/sync-pr-commit-title.tsx
@@ -1,21 +1,25 @@
import React from 'dom-chef';
import select from 'select-dom';
import delegate from 'delegate-it';
-import regexJoin from 'regex-join';
import * as pageDetect from 'github-url-detection';
import * as textFieldEdit from 'text-field-edit';
+import * as api from '../github-helpers/api';
import features from '../feature-manager';
-import onPrMergePanelOpen from '../github-events/on-pr-merge-panel-open';
import {getConversationNumber, userCanLikelyMergePR} from '../github-helpers';
import onCommitTitleUpdate from '../github-events/on-commit-title-update';
+import observe from '../helpers/selector-observer';
+import cleanPrCommitTitle from '../helpers/pr-commit-cleaner';
-const mergeFormSelector = '.is-squashing form:not([hidden])';
-const prTitleFieldSelector = '.js-issue-update input[name="issue[title]"]';
-const prTitleSubmitSelector = '.js-issue-update button[type="submit"]';
+const prTitleFieldSelector = 'input#issue_title';
+const commitTitleFieldSelector = '.is-squashing form:not([hidden]) input#merge_title_field';
-function getCommitTitleField(): HTMLInputElement | undefined {
- return select(`${mergeFormSelector} input#merge_title_field`);
+function getCurrentCommitTitleField(): HTMLInputElement | undefined {
+ return select(commitTitleFieldSelector);
+}
+
+function getCurrentCommitTitle(): string | undefined {
+ return getCurrentCommitTitleField()?.value.trim();
}
function createCommitTitle(): string {
@@ -24,52 +28,43 @@ function createCommitTitle(): string {
}
function needsSubmission(): boolean {
- const inputField = getCommitTitleField();
- if (!inputField || inputField.value === '') {
- return false;
- }
-
- // Ensure that the required fields are on the page
- if (!select.exists(prTitleFieldSelector + ',' + prTitleSubmitSelector)) {
- features.log.error(import.meta.url, 'Can’t update the PR title');
- return false;
- }
-
- return createCommitTitle() !== inputField.value;
+ const currentCommitTitle = getCurrentCommitTitle();
+ return Boolean(currentCommitTitle) && (createCommitTitle() !== currentCommitTitle);
}
function getUI(): HTMLElement {
- return select(`${mergeFormSelector} .rgh-sync-pr-commit-title-note`) ?? (
+ const cancelButton = <button type="button" className="btn-link Link--muted text-underline rgh-sync-pr-commit-title">Cancel</button>;
+ return select('.rgh-sync-pr-commit-title-note') ?? (
<p className="note rgh-sync-pr-commit-title-note">
- The title of this PR will be updated to match this title. <button type="button" className="btn-link Link--muted text-underline rgh-sync-pr-commit-title">Cancel</button>
+ The title of this PR will be updated to match this title. {cancelButton}
</p>
);
}
function updateUI(): void {
if (needsSubmission()) {
- getCommitTitleField()!.after(getUI());
+ getCurrentCommitTitleField()!.after(getUI());
} else {
getUI().remove();
}
}
-function updatePRTitle(): void {
+async function updatePRTitle(): Promise<void> {
if (!needsSubmission()) {
return;
}
// Remove PR number from commit title
- const prTitle = getCommitTitleField()!.value
- .replace(regexJoin(/\s*\(/, '#' + getConversationNumber()!, /\)$/), '');
+ const title = cleanPrCommitTitle(getCurrentCommitTitle()!, getConversationNumber()!);
- // Fill and submit title-change form
- select(prTitleFieldSelector)!.value = prTitle;
- select(prTitleSubmitSelector)!.click(); // `form.submit()` isn't sent via ajax
+ await api.v3(`pulls/${getConversationNumber()!}`, {
+ method: 'PATCH',
+ body: {title},
+ });
}
async function updateCommitTitle(): Promise<void> {
- const field = getCommitTitleField()!;
+ const field = getCurrentCommitTitleField()!;
if (field) {
textFieldEdit.set(field, createCommitTitle());
}
@@ -81,10 +76,17 @@ function disableSubmission(): void {
}
function init(signal: AbortSignal): void {
- onPrMergePanelOpen(updateCommitTitle, signal);
+ // PR title -> Commit title field
+ observe(commitTitleFieldSelector, updateCommitTitle, {signal}); // On panel open
+ observe('.gh-header-title', updateCommitTitle, {signal}); // On PR title change
+
+ // Commit title field -> toggle checkbox visibility
onCommitTitleUpdate(updateUI, signal);
+ // On submission, update PR
delegate('form.js-merge-pull-request', 'submit', updatePRTitle, {signal});
+
+ // On "Cancel", disable the feature
delegate('.rgh-sync-pr-commit-title', 'click', disableSubmission, {signal});
}
diff --git a/source/github-helpers/index.test.ts b/source/github-helpers/index.test.ts
index 04bf91cb..4f1a9d08 100644
--- a/source/github-helpers/index.test.ts
+++ b/source/github-helpers/index.test.ts
@@ -9,7 +9,7 @@ import {
} from '.';
test('getConversationNumber', () => {
- const pairs = new Map<string, string | undefined>([
+ const pairs = new Map<string, number | undefined>([
[
'https://github.com',
undefined,
@@ -48,23 +48,23 @@ test('getConversationNumber', () => {
],
[
'https://github.com/refined-github/refined-github/pull/148/commits/0019603b83bd97c2f7ef240969f49e6126c5ec85',
- '148',
+ 148,
],
[
'https://github.com/refined-github/refined-github/pull/148/commits/00196',
- '148',
+ 148,
],
[
'https://github.com/refined-github/refined-github/pull/148/commits',
- '148',
+ 148,
],
[
'https://github.com/refined-github/refined-github/pull/148',
- '148',
+ 148,
],
[
'https://github.com/refined-github/refined-github/issues/146',
- '146',
+ 146,
],
[
'https://github.com/refined-github/refined-github/issues',
diff --git a/source/github-helpers/index.ts b/source/github-helpers/index.ts
index 156fe18a..c42790a6 100644
--- a/source/github-helpers/index.ts
+++ b/source/github-helpers/index.ts
@@ -9,9 +9,9 @@ import * as pageDetect from 'github-url-detection';
export const getUsername = onetime(pageDetect.utils.getUsername);
export const {getRepositoryInfo: getRepo, getCleanPathname} = pageDetect.utils;
-export const getConversationNumber = (): string | undefined => {
+export const getConversationNumber = (): number | undefined => {
if (pageDetect.isPR() || pageDetect.isIssue()) {
- return location.pathname.split('/')[4];
+ return Number(location.pathname.split('/')[4]);
}
return undefined;
diff --git a/source/helpers/pr-commit-cleaner.test.ts b/source/helpers/pr-commit-cleaner.test.ts
new file mode 100644
index 00000000..f7771ddf
--- /dev/null
+++ b/source/helpers/pr-commit-cleaner.test.ts
@@ -0,0 +1,13 @@
+import {test, assert} from 'vitest';
+
+import cleanPrCommitTitle from './pr-commit-cleaner';
+
+test('cleanPrCommitTitle', () => {
+ const clean = 'Something done';
+ assert.equal(cleanPrCommitTitle('Something done (#123)', 123), clean);
+ assert.equal(cleanPrCommitTitle(' Something done (#123) ', 123), clean);
+ assert.equal(cleanPrCommitTitle(' Something done ', 123), clean);
+
+ assert.notEqual(cleanPrCommitTitle('Something done (fixes #123)', 123), clean);
+ assert.notEqual(cleanPrCommitTitle('Something done (#23454)', 123), clean);
+});
diff --git a/source/helpers/pr-commit-cleaner.ts b/source/helpers/pr-commit-cleaner.ts
new file mode 100644
index 00000000..52cd7f2b
--- /dev/null
+++ b/source/helpers/pr-commit-cleaner.ts
@@ -0,0 +1,6 @@
+/**
+@example 'Something done (#123)' => 'Something done'
+*/
+export default function cleanPrCommitTitle(commitTitle: string, pr: number): string {
+ return commitTitle.replace(new RegExp(`\\(#${pr}\\)\\s*$`), '').trim();
+}