-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathInline Edit for Discussions.user.js
More file actions
185 lines (167 loc) · 9.62 KB
/
Inline Edit for Discussions.user.js
File metadata and controls
185 lines (167 loc) · 9.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
// ==UserScript==
// @name Inline Edit for Discussions
// @namespace https://github.com/MdoubleDash
// @version 0.2
// @description Adds an "inline edit" button beside the share button under each post and reply
// @author MDoubleDash (@M--)
// @match https://stackoverflow.com/beta/discussions/*
// @match https://stackoverflow.com/posts/*/edit-inline
// @downloadURL https://github.com/MdoubleDash/SOS_Userscripts/raw/main/Inline%20Edit%20for%20Discussions.user.js
// @updateURL https://github.com/MdoubleDash/SOS_Userscripts/raw/main/Inline%20Edit%20for%20Discussions.user.js
// @grant none
// ==/UserScript==
(function () {
'use strict';
// Inline Edit page tweaks
function customStyles() {
if (window.location.href.includes('/edit-inline')) {
const styles = `
.js-stacks-editor-container { display: none; }
.flex--item.pt8 { display: none; }
.flex--item.js-answer-help-close-btn { display: none; }
.edit-block { display: none; }
.js-stacks-editor-backing-textarea { width: 650px; height: 300px; }
body { zoom: 150%; }
#title, #tagnames, .js-stacks-editor-backing-textarea, .edit-comment { font-size: 12px; }
#title { height: auto; overflow: hidden; resize: none; white-space: pre-wrap; }
`;
document.documentElement.insertAdjacentHTML('beforeend', `<style type="text/css" id="screen-reader">${styles}</style>`);
}
}
customStyles();
// Function to add title and tags fields to the inline edit form
function addTitleAndTagsFields() {
const form = document.querySelector('.inline-post');
if (form) {
// Check if the form is for the main post
const isMainPost = localStorage.getItem('isMainPost') === 'true';
if (isMainPost) {
// Extract existing title and tags from the discussions page
const existingTitle = localStorage.getItem('discussionTitle') || '';
const existingTags = localStorage.getItem('discussionTags') || '';
// Add title field
const titleFieldHTML = `
<div style="position: relative;" class="js-post-editor-title-container">
<div class="form-item d-flex fd-column pt0 js-stacks-validation">
<div class="d-flex jc-space-between">
<label for="title" class="flex--item s-label mb4">Title<abbr class="s-required-symbol" title="required">*</abbr></label>
<div class="flex--item ta-right text-counter mr0 fs-caption mt4"></div>
</div>
<div class="ps-relative">
<textarea id="title" class="flex--item s-input w100 js-post-title-field" name="title" maxlength="300" tabindex="100" data-min-length="15" data-max-length="150" placeholder="e.g. Is there an R function for finding the index of an element in a vector?" style="width: 600px; white-space: pre-wrap;">${existingTitle}</textarea>
<svg aria-hidden="true" class="s-input-icon js-invalid-alert d-none svg-icon iconAlertCircle" width="18" height="18" viewBox="0 0 18 18"><path d="M9 17c-4.36 0-8-3.64-8-8s3.64-8 8-8 8 3.64 8 8-3.64 8-8 8M8 4v6h2V4zm0 8v2h2v-2z"/></svg>
</div>
<div id="title-validation-message" class="s-input-message mt4 d-none js-stacks-validation-message"></div>
</div>
</div>
`;
// Add tags field
const tagsFieldHTML = `
<div class="ps-relative">
<div class="form-item p0 js-stacks-validation js-tag-editor-container ">
<div class="d-flex ai-center jc-space-between">
<label for="tagnames" class="s-label mb4 d-block flex--item fl1 ">
Tags (space-delimited) <abbr class="s-required-symbol" title="required">*</abbr>
</label>
</div>
<div class="d-flex fd-column g4 ps-relative">
<div class="ps-relative">
<input id="tagnames" class="s-input box-border js-post-tags-field" name="tagnames" type="text" size="60" value="${existingTags}" tabindex="103" placeholder="e.g. (c c++ sql-server)" style="width: 600px;">
</div>
<div class="js-community-icons"></div>
</div>
<div id="js-tagnames-validation-message" class="s-input-message d-none js-stacks-validation-message"></div>
</div>
</div>
`;
form.insertAdjacentHTML('afterbegin', tagsFieldHTML);
form.insertAdjacentHTML('afterbegin', titleFieldHTML);
// Adjust the height of the title field based on its content
const titleField = document.getElementById('title');
titleField.addEventListener('input', function() {
this.style.height = 'auto';
this.style.height = (this.scrollHeight) + 'px';
});
titleField.dispatchEvent(new Event('input'));
}
}
}
addTitleAndTagsFields();
// Remove save button and change warning text if the warning div exists and contains specific text
function checkPrivileges() {
const warningDiv = document.querySelector('.s-notice.s-notice__warning');
if (warningDiv) {
if (warningDiv.textContent.includes('Your edit will be placed in a queue until it is peer reviewed.')) {
warningDiv.innerHTML = `
<p class="error-text" style="color: red;">Sorry, you don't have the sufficient privileges (>2k reputation) to edit Discussions!</p>
`;
const form = document.querySelector('.inline-post');
const postId = form ? form.querySelector('#post-id').value : null;
if (postId) {
const saveButton = document.querySelector(`#submit-button-${postId}`);
if (saveButton) {
saveButton.remove();
}
}
} else {
const form = document.querySelector('.inline-post');
form.insertAdjacentHTML('afterbegin', `
<p class="warning-text" style="max-width: 650px;">Please remember Discussions and Q&A have different formats and editing guidelines. Therefore, common practices like removing greetings may not apply to discussions.</p>
`);
}
}
}
checkPrivileges();
// Make the cancel button close the page
document.addEventListener('click', function (event) {
if (event.target.matches('.cancel-edit')) {
window.close();
}
});
// Function to create the inline edit button
function createInlineEditButton(postId, isMainPost) {
const button = document.createElement('button');
button.textContent = 'Inline Edit';
button.className = 's-btn s-btn__link fc-black-600'; // Match the style of existing buttons
button.style.marginLeft = '10px';
button.onclick = function () {
// Store the title and tags in localStorage before navigating to the inline edit page
const title = document.querySelector('.s-page-title--header')?.textContent.trim() || '';
const tags = Array.from(document.querySelector('.postcell .d-flex.ai-center.fw-wrap.gx8.gy1.sm\\:pb12').querySelectorAll('.s-tag.post-tag')).map(tag => tag.textContent).join(' ');
localStorage.setItem('discussionTitle', title);
localStorage.setItem('discussionTags', tags);
localStorage.setItem('isMainPost', isMainPost);
window.open(`https://stackoverflow.com/posts/${postId}/edit-inline`, '_blank');
};
return button;
}
// Function to extract the post ID from an element
function extractPostId(element) {
const postIdMatch = element.id.match(/\d+/);
return postIdMatch ? postIdMatch[0] : null;
}
// Add button beside the share button under the main post
const mainPost = document.querySelector('.question, .s-prose');
if (mainPost) {
const mainPostId = mainPost.dataset.questionid || mainPost.id.match(/\d+/)[0]; // Adjust as needed
const shareButton = mainPost.closest('.postcell').querySelector('.js-share-link');
if (shareButton && !mainPost.querySelector('.inline-edit-button')) {
const editButton = createInlineEditButton(mainPostId, true);
editButton.classList.add('inline-edit-button');
shareButton.parentNode.appendChild(editButton);
}
}
// Add button beside the share button under each reply
const replies = document.querySelectorAll('[id^="js-reply-"]');
replies.forEach(reply => {
const replyId = extractPostId(reply);
if (replyId) {
const shareButton = reply.querySelector('.js-share-link');
if (shareButton && !reply.querySelector('.inline-edit-button')) {
const editButton = createInlineEditButton(replyId, false);
editButton.classList.add('inline-edit-button');
shareButton.parentNode.appendChild(editButton);
}
}
});
})();