Skip to content

Commit 7468ab8

Browse files
committed
documentation; naming consistency
1 parent cad8d48 commit 7468ab8

File tree

5 files changed

+100
-34
lines changed

5 files changed

+100
-34
lines changed

extension/data/frontends/index.tsx

Lines changed: 92 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Defines a system of "slots" which modules can use to render interface
2-
// elements within the page. Slot locations are standardized for consumers (e.g.
3-
// a module says it wants to display a button next to comment author usernames)
2+
// elements within the page. Slot types are standardized for consumers (e.g. a
3+
// module says it wants to display a button next to comment author usernames)
44
// and their actual position in the DOM is controlled by platform-specific
55
// observers responding to changes in the page and dynamically creating React
66
// roots which this code then populates with the appropriate contents.
@@ -17,124 +17,190 @@ import modmailObserver from './modmail';
1717
import oldRedditObserver from './oldreddit';
1818
import shredditObserver from './shreddit';
1919

20-
// NOMERGE: document all of these
20+
/** Basic information about a subreddit. */
2121
interface PlatformSlotDetailsSubreddit {
22+
/** The subreddit's fullname, beginning with ``. */
2223
fullname?: string;
24+
/** The name of the subreddit */
2325
name: string;
2426
}
2527

28+
/** Basic information about a user. */
2629
export type PlatformSlotDetailsUser = {
30+
/** If `true`, this is a deleted user. */
2731
deleted: true;
2832
} | {
33+
/** If `true`, this is a deleted user. */
2934
deleted: false;
35+
/** The user's fullname, starting with ``. */
3036
fullname?: string;
37+
/** The user's username. */
3138
name: string;
3239
};
3340

41+
/** Basic information about a submission. */
3442
interface PlatformSlotDetailsSubmission {
43+
/** The submission's fullname, beginning with ``. */
3544
fullname: string;
3645
}
3746

47+
/** Basic information about a comment. */
3848
interface PlatformSlotDetailsComment {
49+
/** The comment's fullname, beginning with ``. */
3950
fullname: string;
4051
}
4152

4253
// Slot names and the type of associated contextual information
43-
// NOMERGE: document
54+
55+
/** Contextual information provided to consumers of each type of slot. */
4456
export interface PlatformSlotDetails {
57+
/** Details for a submission author slot. */
4558
submissionAuthor: {
59+
/** The author of this submission */
4660
user: PlatformSlotDetailsUser;
61+
/** The submission */
4762
submission?: PlatformSlotDetailsSubmission;
63+
/** The subreddit where this submission was posted */
4864
subreddit: PlatformSlotDetailsSubreddit;
65+
// /** The type of distinguish on the submission, if any */
4966
// distinguishType: null | 'moderator' | 'employee' | 'alumnus';
50-
// stickied: boolean;
67+
// /** The sticky slot populated by the submission, if any */
68+
// stickied: false | 1 | 2;
5169
};
5270
commentAuthor: {
71+
/** The author of the comment */
5372
user: PlatformSlotDetailsUser;
73+
/** The comment */
5474
comment: PlatformSlotDetailsComment;
75+
/** The parent submission the comment was left under */
5576
submission?: PlatformSlotDetailsSubmission;
77+
/** The subreddit where the comment was posted */
5678
subreddit: PlatformSlotDetailsSubreddit;
79+
// /** The type of distinguish on the comment, if any */
5780
// distinguished: boolean;
81+
// /** Whether the comment is stickied */
5882
// stickied: boolean;
5983
};
6084
modmailAuthor: {
85+
/** The author of the message */
6186
user: PlatformSlotDetailsUser;
87+
/** The subreddit that initially received this message's thread */
6288
subreddit: PlatformSlotDetailsSubreddit;
89+
/** The thread this message is in */
6390
thread: {fullname: string};
91+
/** The message */
6492
message: {fullname: string};
93+
// /** Whether the author is a moderator */
6594
// authorIsModerator: boolean;
95+
// /** Whether this message was sent "as the subreddit" (with username hidden) */
6696
// repliedAsSubreddit: boolean;
6797
};
6898
userHovercard: {
99+
/** The user */
69100
user: PlatformSlotDetailsUser;
101+
/**
102+
* The subreddit of the content the hovercard was triggered from. For
103+
* example if the hovercard was triggered from an author name on a
104+
* submission, this would be the subreddit it was submitted to; if the
105+
* hovercard is triggered on a user in a modmail thread, this would be
106+
* the subreddit that received the thread.
107+
*/
70108
subreddit: PlatformSlotDetailsSubreddit;
109+
/**
110+
* The fullname of the submission, comment, modmail thread, etc. the
111+
* hovercard was triggered from
112+
*/
71113
contextFullname?: string;
72114
};
73115
}
74-
export type PlatformSlotLocation = keyof PlatformSlotDetails;
116+
/**
117+
* A slot type. Describes a location on the page where slot contents can be
118+
* rendered (e.g. `submissionAuthor` is a slot type that's rendered next to the
119+
* usernames of submission authors).
120+
*/
121+
export type PlatformSlotType = keyof PlatformSlotDetails;
75122

76123
// Consumer code (used by toolbox modules)
77124

78125
// A consumer of a particular slot location which gets appropriate context and
79126
// returns React content to be rendered in the slot
80-
export type PlatformSlotContent<Location extends keyof PlatformSlotDetails> = ComponentType<{
81-
details: PlatformSlotDetails[Location];
82-
location: Location;
127+
export type PlatformSlotContent<SlotType extends keyof PlatformSlotDetails> = ComponentType<{
128+
/**
129+
* Contextual details about the content the slot is attached to. Different
130+
* slot types provide different information in this object.
131+
*/
132+
details: PlatformSlotDetails[SlotType];
133+
/** The type of slot the component is currently being populated into. */
134+
slotType: SlotType;
83135
}>;
84136

85137
// Map of slot locations to consumers of the slot
86138
const slotConsumers: {
87139
[K in keyof PlatformSlotDetails]?: PlatformSlotContent<K>[];
88140
} = Object.create(null);
89141

90-
// NOMERGE: document
91-
export function renderInSlots<K extends keyof PlatformSlotDetails> (locations: K[], render: PlatformSlotContent<K>) {
92-
if (!Array.isArray(locations)) {
93-
locations = [];
142+
/**
143+
* Provide a consumer for one or more slot types. Whenever any of the `slots`
144+
* appears on the page, the given component/renderer will be used to populate
145+
* the slot (alongside any other consumers of the same slot type).
146+
* @param slots An array of slots where the given component should be rendered
147+
* @param render A React function component/render function that will be
148+
* rendered in those slots. Props are passed which inform the component which
149+
* type of slot it's currently being rendered in, and contextual information
150+
* about the slot's surroundings.
151+
*/
152+
export function renderInSlots<K extends keyof PlatformSlotDetails> (slots: K[], render: PlatformSlotContent<K>) {
153+
if (!Array.isArray(slots)) {
154+
slots = [];
94155
}
95-
for (const location of locations) {
96-
if (!slotConsumers[location]) {
97-
slotConsumers[location] = [];
156+
for (const slot of slots) {
157+
if (!slotConsumers[slot]) {
158+
slotConsumers[slot] = [];
98159
}
99-
slotConsumers[location]?.push(render);
160+
slotConsumers[slot]?.push(render);
100161
}
101162
}
102163

103164
// Observer code (used by platform-specific observers in this directory)
104165

105-
// NOMERGE: document
166+
/**
167+
* A platform observer is a function responsible creating slot instances and
168+
* attaching them to the page in the appropriate locations for a specific
169+
* platform. It is called once when Toolbox starts and receives a function which
170+
* creates slot instances, which it then inserts into the DOM.
171+
*/
106172
export type PlatformObserver = (
107173
/**
108174
* Creates a React root for a slot which will be populated with the
109175
* appropriate contents. Observers are responsible for calling this function
110176
* and inserting the resulting element into the DOM wherever the slot should
111177
* be rendered.
112178
*/
113-
createRenderer: <Location extends keyof PlatformSlotDetails>(
114-
location: Location,
115-
details: PlatformSlotDetails[Location],
179+
createRenderer: <SlotType extends keyof PlatformSlotDetails>(
180+
slotType: SlotType,
181+
details: PlatformSlotDetails[SlotType],
116182
) => HTMLElement,
117183
) => void;
118184

119185
// the actual `createRenderer` function observers get - returns a new react root
120186
// which will contain all the contents different modules have registered for the
121-
// given slot location
187+
// given slot type
122188
// NOTE: Exported because tbui builders need to manually emit their own slots.
123189
// Should we just import this from the platform-specific bits instead of
124190
// passing this function in to them?
125-
export const createRenderer = <K extends keyof PlatformSlotDetails>(location: K, details: PlatformSlotDetails[K]) =>
191+
export const createRenderer = <K extends keyof PlatformSlotDetails>(slotType: K, details: PlatformSlotDetails[K]) =>
126192
reactRenderer(
127193
<div
128194
className='tb-platform-slot'
129195
style={{display: 'inline-flex'}} // FIXME: do this in CSS
130-
data-location={location}
196+
data-slot-type={slotType}
131197
>
132198
{/* TODO: Do we want to do anything more sophisticated here? */}
133-
{slotConsumers[location]?.map((Component, i) => (
199+
{slotConsumers[slotType]?.map((Component, i) => (
134200
<Component
135201
key={i}
136202
details={details}
137-
location={location}
203+
slotType={slotType}
138204
/>
139205
))}
140206
</div>,

extension/data/modules/historybutton.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ self.runJsAPI = function () {
7878
'submissionAuthor',
7979
'commentAuthor',
8080
'userHovercard',
81-
], ({details, location}) => {
81+
], ({details, slotType}) => {
8282
const subreddit = details.subreddit.name;
8383
const user = !details.user.deleted && details.user.name;
8484

@@ -87,7 +87,7 @@ self.runJsAPI = function () {
8787
}
8888

8989
const $target = $('<span>');
90-
self.attachHistoryButton($target, user, subreddit, location === 'userHovercard' ? 'User History' : undefined);
90+
self.attachHistoryButton($target, user, subreddit, slotType === 'userHovercard' ? 'User History' : undefined);
9191
return createElement(JQueryRenderer, {content: $target});
9292
});
9393

extension/data/modules/modbutton.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ self.runRedesign = async function () {
7474
'submissionAuthor',
7575
'commentAuthor',
7676
'userHovercard',
77-
], ({details, location}) => {
77+
], ({details, slotType}) => {
7878
const contextFullname = details.contextFullname || details.comment?.fullname || details.submission?.fullname
7979
|| 'unknown';
8080
const subreddit = details.subreddit.name;
@@ -96,7 +96,7 @@ self.runRedesign = async function () {
9696
data-parentID="${contextFullname}"
9797
class="global-mod-button tb-bracket-button"
9898
>
99-
${location === 'userHovercard' ? 'Mod Button' : 'M'}
99+
${slotType === 'userHovercard' ? 'Mod Button' : 'M'}
100100
</a>
101101
`),
102102
});

extension/data/modules/nukecomments.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ export default new Module({
287287
// Add nuke buttons where needed
288288
// XXX 3: this also needs to be able to appear in hovercards apparently?? what
289289
// the fuck is going on with all the special casing in this goddamn module
290-
renderInSlots(['commentAuthor'], ({details, location}) => {
290+
renderInSlots(['commentAuthor'], ({details, slotType}) => {
291291
const subreddit = details.subreddit.name;
292292
const commentID = details.comment.fullname.substring(3);
293293
const submissionID = details.submission?.fullname.substring(3);
@@ -305,7 +305,7 @@ export default new Module({
305305

306306
const NukeButtonHTML =
307307
`<span class="tb-nuke-button tb-bracket-button" data-comment-id="${commentID}" data-post-id="${submissionID}" data-subreddit="${subreddit}" title="Remove comment chain starting with this comment">${
308-
location === 'userHovercard' ? 'Nuke' : 'R'
308+
slotType === 'userHovercard' ? 'Nuke' : 'R'
309309
}</span>`;
310310

311311
// XXX 2: implement showNextToUser setting. for now we always show next

extension/data/modules/usernotes.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ function startUsernotes ({maxChars, showDate}) {
129129
'submissionAuthor',
130130
'commentAuthor',
131131
'modmailAuthor',
132-
], ({location, details}) => {
132+
], ({slotType, details}) => {
133133
const subreddit = details.subreddit.name;
134134
const author = details.user.name;
135135

@@ -152,7 +152,7 @@ function startUsernotes ({maxChars, showDate}) {
152152
);
153153

154154
attachNoteTag($target, subreddit, author, {
155-
customText: location === 'userHovercard' ? 'Usernotes' : undefined,
155+
customText: slotType === 'userHovercard' ? 'Usernotes' : undefined,
156156
});
157157
foundSubreddit(subreddit);
158158
queueProcessSub(subreddit, $target);

0 commit comments

Comments
 (0)