Skip to content

Commit 3979ac1

Browse files
committed
Added comments, improved code quality.
1 parent e42b3c1 commit 3979ac1

File tree

11 files changed

+266
-214
lines changed

11 files changed

+266
-214
lines changed

src/inject/constants.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,6 @@
1-
export const CSS_PREFIX: string = 'gitlab-tree-plugin';
1+
export const CSS_PREFIX: string = 'gitlab-tree-plugin';
2+
3+
// Events
4+
export const EVENT_SETTINGS_CHANGED = 'settings-changed';
5+
export const EVENT_TOGGLE_NAVIGATION = 'toggle-navigation-is-open';
6+
export const EVENT_TOGGLE_EXTENSION = 'toggle-extension-is-on';

src/inject/index.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
11
import { Container } from './libs/container';
2-
import { GitLabTree } from './inject';
2+
import { GitLabTree } from './main';
33
import { CSS_PREFIX } from './constants'
44
import { SettingsStore } from './settings.store';
55

66
let container: Container = new Container();
77
let interval: number;
88

9+
/*
10+
!! IMPORTANT NOTE !!
11+
12+
This file performs a quick test, whether plugin should be applied.
13+
Actual plugin entry point can be found in `main.ts` file.
14+
*/
15+
16+
17+
918
/**
1019
* This is for fake AJAX re-renders of the page.
1120
*/
@@ -24,7 +33,7 @@ function checkSiteChange(): void
2433

2534
function startCheckInterval( time: number ): void
2635
{
27-
clearInterval( interval )
36+
clearInterval( interval )
2837
interval = setInterval( () => checkSiteChange(), time );
2938
}
3039

src/inject/libs/container.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
import 'reflect-metadata';
22

3+
/**
4+
* This is container manager inspirated by Aurelia's one. Will be published on npm and GitHub as solo soon.
5+
* It works like a context, where all instances are registred as singletons. Then it resolves dependecies
6+
* and passes singletons to constructor.
7+
*
8+
* If you want to use it, just use @autoinject decorator on the class and inside constructor specify what
9+
* dependencies you want to use.
10+
*/
11+
312
export class Container
413
{
514
static instance: Container = undefined;

src/inject/libs/pubsub.ts

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,42 @@ export class PubSub
66
{
77
subscribers: Map<string, any[]> = new Map<string, any[]>();
88

9-
10-
subscribe( message: string, callback: any )
9+
/**
10+
* Subscribes to specific message.
11+
*
12+
* @param message - what message to receive
13+
* @param callback - what should happen once the message is received
14+
* @returns callback to unsubscribe
15+
*/
16+
subscribe( message: string, callback: any ): () => void
1117
{
1218
const subscribers = this.subscribers.get( message ) || [];
1319
subscribers.push( callback );
1420

1521
this.subscribers.set( message, subscribers );
22+
23+
// Unsubscribe
24+
return () =>
25+
{
26+
if ( subscribers.length > 1 )
27+
{
28+
subscribers.splice( subscribers.indexOf( callback ), 1 );
29+
}
30+
31+
else
32+
{
33+
this.subscribers.delete( message );
34+
}
35+
}
1636
}
1737

1838

39+
/**
40+
* Sends a message.
41+
*
42+
* @param message - message name
43+
* @param data - message data
44+
*/
1945
publish( message: string, data?: any )
2046
{
2147
const subscribers = this.subscribers.get( message ) || [];
@@ -24,4 +50,13 @@ export class PubSub
2450
subscriber( message, data );
2551
})
2652
}
53+
54+
55+
/**
56+
*
57+
*/
58+
unsubscribeAll()
59+
{
60+
this.subscribers = new Map();
61+
}
2762
}

src/inject/libs/views.ts

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,45 @@
11
import { patch } from 'superfine'
22

3+
/**
4+
* Motivation:
5+
* Saving data into classes (folder/file) is convenient. Displaying them, however, is a problem.
6+
* Using Aurelia or Vue would bring a massive overhead for the otherwise simple plugin. So my
7+
* goal was to sync data with the view as simple as possible, and virtual-dom based solutions
8+
* do a great job. However, there is a problem with state management. You can't use the instance
9+
* as a component (if you can please open an issue). But you can define generic component and
10+
* send the state as a prop. I wanted to avoid duplication of state. Managing state is difficult
11+
* as well because the structure is not flat. So updating such a structure with Immutable and Redux
12+
* seemed complicated.
13+
*
14+
* The solution is that everytime a change occurs, the whole new virtual dom is created, and changes
15+
* are reflected. This class saves entry points for every view and in case of change it does the job.
16+
*/
17+
318
export class Views
419
{
520
private views = new Map<string, { element: HTMLElement, renderFn: () => any, lastNode: any }>();
621

7-
8-
applyView( name: string, renderFn: () => any, element: HTMLElement )
22+
/**
23+
* Create DOM structure and append it to given element. This will create a "view".
24+
*
25+
* @param name - name of the "view" (so we can in future ask for redraw by name)
26+
* @param renderFn - function that generates virtual DOM
27+
* @param element - element, where "view" will be appended
28+
*/
29+
applyView( name: string, renderFn: () => any, element: HTMLElement ): void
930
{
1031
this.views.set( name, { element, renderFn, lastNode: undefined } );
1132
this.redrawView( name );
1233
}
1334

1435

15-
redrawView( name )
36+
/**
37+
* This creates virtual dom reflecting current state, compares with last state and redraws
38+
* changes.
39+
*
40+
* @param name - name of "view" to redraw
41+
*/
42+
redrawView( name: string ): void
1643
{
1744
if ( this.views.has( name ) )
1845
{

0 commit comments

Comments
 (0)