Skip to content

Commit

Permalink
feat: codeblock support via refractor
Browse files Browse the repository at this point in the history
  • Loading branch information
ifiokjr committed Jul 17, 2019
1 parent 73825ef commit fe23958
Show file tree
Hide file tree
Showing 63 changed files with 617 additions and 380 deletions.
37 changes: 34 additions & 3 deletions @remirror/core-extensions/src/extensions/history.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import { BaseExtensionOptions, CommandFunction, environment, Extension } from '@remirror/core';
import { history, redo, undo } from 'prosemirror-history';
import {
BaseExtensionOptions,
BooleanExtensionCheck,
CommandFunction,
CommandParams,
environment,
Extension,
ExtensionManagerParams,
} from '@remirror/core';
import { history, redo, redoDepth, undo, undoDepth } from 'prosemirror-history';

export interface HistoryExtensionOptions extends BaseExtensionOptions {
/**
Expand All @@ -19,7 +27,10 @@ export interface HistoryExtensionOptions extends BaseExtensionOptions {
*/
newGroupDelay?: number | null;
}
export class HistoryExtension extends Extension<HistoryExtensionOptions> {

type HistoryExtensionCommands = 'undo' | 'redo';

export class HistoryExtension extends Extension<HistoryExtensionOptions, HistoryExtensionCommands, {}> {
get name() {
return 'history' as const;
}
Expand Down Expand Up @@ -50,6 +61,26 @@ export class HistoryExtension extends Extension<HistoryExtensionOptions> {
return history({ depth, newGroupDelay });
}

public isEnabled({ getState }: ExtensionManagerParams): BooleanExtensionCheck<HistoryExtensionCommands> {
return ({ command }) => {
switch (command) {
case 'undo':
return undoDepth(getState()) > 0;
case 'redo':
return redoDepth(getState()) > 0;
default:
return false;
}
};
}

/**
* The history plugin doesn't really have an active state.
*/
public isActive() {
return () => false;
}

public commands() {
return {
undo: () => undo,
Expand Down
2 changes: 2 additions & 0 deletions @remirror/core-extensions/src/extensions/ssr-helpers/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,12 @@ export const injectBrIntoEmptyParagraphs: SSRTransformer = element => {
if (!isArray(children)) {
return children;
}

return Children.map(children, child => {
if (!(isReactDOMElement(child) && elementIsEmpty(child) && elementIsOfType(child, 'p'))) {
return child;
}

const props = getElementProps(child);
return cloneElement(child, props, jsx('br'));
});
Expand Down
44 changes: 22 additions & 22 deletions @remirror/core-extensions/src/marks/__tests__/link.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,26 +53,26 @@ describe('actions', () => {
} = create());
});

describe('.linkRemove', () => {
describe('.command()', () => {
describe('.removeLink', () => {
describe('command', () => {
it('removes links when selection is wrapped', () => {
const testLink = link({ href });
add(doc(p('Paragraph ', testLink('<start>A link<end>'))));
actions.linkRemove.command();
actions.removeLink();
expect(getState()).toContainRemirrorDocument(p('Paragraph A link'));
});

it('removes the link cursor is within', () => {
const testLink = link({ href });
add(doc(p('Paragraph ', testLink('A <cursor>link'))));
actions.linkRemove.command();
actions.removeLink();
expect(getState()).toContainRemirrorDocument(p('Paragraph A link'));
});

it('removes all links when selection contains multiples', () => {
const testLink = link({ href });
add(doc(p('<all>', testLink('1'), ' ', testLink('2'), ' ', testLink('3'))));
actions.linkRemove.command();
actions.removeLink();
expect(getState()).toContainRemirrorDocument(p('1 2 3'));
});
});
Expand All @@ -81,41 +81,41 @@ describe('actions', () => {
it('is not enabled when not selected', () => {
const testLink = link({ href });
add(doc(p('Paragraph<cursor> ', testLink('A link'))));
expect(actions.linkRemove.isEnabled()).toBeFalse();
expect(actions.removeLink.isEnabled()).toBeFalse();
});

it('is enabled with selection wrapped', () => {
const testLink = link({ href });
add(doc(p('Paragraph ', testLink('<start>A link<end>'))));
expect(actions.linkRemove.isEnabled()).toBeTrue();
expect(actions.removeLink.isEnabled()).toBeTrue();
});

it('is enabled with cursor within link', () => {
const testLink = link({ href });
add(doc(p('Paragraph ', testLink('A <cursor>link'))));
expect(actions.linkRemove.isEnabled()).toBeTrue();
expect(actions.removeLink.isEnabled()).toBeTrue();
});

it('is enabled with selection of multiple nodes', () => {
const testLink = link({ href });
add(doc(p('<all>Paragraph ', testLink('A link'))));
expect(actions.linkRemove.isEnabled()).toBeTrue();
expect(actions.removeLink.isEnabled()).toBeTrue();
});
});
});

describe('.linkUpdate', () => {
describe('.command()', () => {
describe('.updateLink', () => {
describe('command', () => {
it('creates a link for the selection', () => {
const testLink = link({ href });
add(doc(p('Paragraph <start>A link<end>')));
actions.linkUpdate.command({ href });
actions.updateLink({ href });
expect(getState()).toContainRemirrorDocument(p('Paragraph ', testLink('<start>A link<end>')));
});

it('does nothing for an empty selection', () => {
add(doc(p('Paragraph <cursor>A link')));
actions.linkUpdate.command({ href });
actions.updateLink({ href });
expect(getState()).toContainRemirrorDocument(p('Paragraph A link'));
});

Expand All @@ -124,14 +124,14 @@ describe('actions', () => {
const attrs = { href: 'https://alt.com' };
const altLink = link(attrs);
add(doc(p('Paragraph ', testLink('<start>A link<end>'))));
actions.linkUpdate.command(attrs);
actions.updateLink(attrs);
expect(getState()).toContainRemirrorDocument(p('Paragraph ', altLink('<start>A link<end>')));
});

it('overwrites multiple existing links', () => {
const testLink = link({ href });
add(doc(p('<all>', testLink('1'), ' ', testLink('2'), ' ', testLink('3'))));
actions.linkUpdate.command({ href });
actions.updateLink({ href });
expect(getState()).toContainRemirrorDocument(p(testLink('1 2 3')));
});
});
Expand All @@ -140,42 +140,42 @@ describe('actions', () => {
it('is not active when not selected', () => {
const testLink = link({ href });
add(doc(p('Paragraph<cursor> ', testLink('A link'))));
expect(actions.linkUpdate.isActive()).toBeFalse();
expect(actions.updateLink.isActive()).toBeFalse();
});

it('is active with selection wrapped', () => {
const testLink = link({ href });
add(doc(p('Paragraph ', testLink('<start>A link<end>'))));
expect(actions.linkUpdate.isActive()).toBeTrue();
expect(actions.updateLink.isActive()).toBeTrue();
});

it('is active with cursor within link', () => {
const testLink = link({ href });
add(doc(p('Paragraph ', testLink('A <cursor>link'))));
expect(actions.linkUpdate.isActive()).toBeTrue();
expect(actions.updateLink.isActive()).toBeTrue();
});

it('is active with selection of multiple nodes', () => {
const testLink = link({ href });
add(doc(p('<all>Paragraph ', testLink('A link'))));
expect(actions.linkUpdate.isActive()).toBeTrue();
expect(actions.updateLink.isActive()).toBeTrue();
});
});

describe('.isEnabled()', () => {
it('is enabled when text is selected', () => {
add(doc(p('Paragraph <start>A<end> link')));
expect(actions.linkUpdate.isEnabled()).toBeTrue();
expect(actions.updateLink.isEnabled()).toBeTrue();
});

it('is not enabled for empty selections', () => {
add(doc(p('Paragraph <cursor>A link')));
expect(actions.linkUpdate.isEnabled()).toBeFalse();
expect(actions.updateLink.isEnabled()).toBeFalse();
});

it('is not enabled for node selections', () => {
add(doc(p('Paragraph <node>A link')));
expect(actions.linkUpdate.isEnabled()).toBeFalse();
expect(actions.updateLink.isEnabled()).toBeFalse();
});
});
});
Expand Down
9 changes: 6 additions & 3 deletions @remirror/core-extensions/src/marks/bold.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ import {
isElementDOMNode,
isString,
MarkExtension,
MarkExtensionOptions,
MarkExtensionSpec,
markInputRule,
SchemaMarkTypeParams,
} from '@remirror/core';
import { toggleMark } from 'prosemirror-commands';

export class BoldExtension extends MarkExtension {
export class BoldExtension extends MarkExtension<MarkExtensionOptions, 'bold', {}> {
get name() {
return 'bold' as const;
}
Expand Down Expand Up @@ -43,8 +44,10 @@ export class BoldExtension extends MarkExtension {
}

public commands({ type }: CommandMarkTypeParams) {
return () => {
return toggleMark(type);
return {
bold: () => {
return toggleMark(type);
},
};
}

Expand Down
5 changes: 3 additions & 2 deletions @remirror/core-extensions/src/marks/code.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import {
CommandMarkTypeParams,
MarkExtension,
MarkExtensionOptions,
MarkExtensionSpec,
markInputRule,
markPasteRule,
SchemaMarkTypeParams,
} from '@remirror/core';
import { toggleMark } from 'prosemirror-commands';

export class CodeExtension extends MarkExtension {
export class CodeExtension extends MarkExtension<MarkExtensionOptions, 'code', {}> {
get name() {
return 'code' as const;
}
Expand All @@ -27,7 +28,7 @@ export class CodeExtension extends MarkExtension {
}

public commands({ type }: CommandMarkTypeParams) {
return () => toggleMark(type);
return { code: () => toggleMark(type) };
}

public inputRules({ type }: SchemaMarkTypeParams) {
Expand Down
5 changes: 3 additions & 2 deletions @remirror/core-extensions/src/marks/italic.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import {
CommandMarkTypeParams,
MarkExtension,
MarkExtensionOptions,
MarkExtensionSpec,
markInputRule,
markPasteRule,
SchemaMarkTypeParams,
} from '@remirror/core';
import { toggleMark } from 'prosemirror-commands';

export class ItalicExtension extends MarkExtension {
export class ItalicExtension extends MarkExtension<MarkExtensionOptions, 'italic', {}> {
get name() {
return 'italic' as const;
}
Expand All @@ -27,7 +28,7 @@ export class ItalicExtension extends MarkExtension {
}

public commands({ type }: CommandMarkTypeParams) {
return () => toggleMark(type);
return { italic: () => toggleMark(type) };
}

public inputRules({ type }: SchemaMarkTypeParams) {
Expand Down
46 changes: 20 additions & 26 deletions @remirror/core-extensions/src/marks/link.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
Attrs,
BooleanExtensionCheck,
Cast,
CommandMarkTypeParams,
getMarkRange,
Expand Down Expand Up @@ -28,7 +29,9 @@ export interface LinkExtensionOptions extends MarkExtensionOptions {
activationHandler?(): void;
}

export class LinkExtension extends MarkExtension<LinkExtensionOptions> {
export type LinkExtensionCommands = 'updateLink' | 'removeLink';

export class LinkExtension extends MarkExtension<LinkExtensionOptions, LinkExtensionCommands, {}> {
get name() {
return 'link' as const;
}
Expand Down Expand Up @@ -87,38 +90,29 @@ export class LinkExtension extends MarkExtension<LinkExtensionOptions> {
};
}

public active({ getState, type }: SchemaMarkTypeParams) {
return {
/**
* Returns true when the current selection has an active link present.
*/
update: () => {
return isMarkActive({ state: getState(), type });
},
};
}

public commands({ type }: CommandMarkTypeParams) {
return {
update: (attrs?: Attrs) => updateMark({ type, attrs }),
remove: () => {
updateLink: (attrs?: Attrs) => updateMark({ type, attrs }),
removeLink: () => {
return removeMark({ type, expand: true });
},
};
}

public enabled({ getState, type }: SchemaMarkTypeParams) {
return {
update: () => {
const { selection } = getState();
if (selectionEmpty(selection) || !isTextSelection(selection)) {
return false;
}
return true;
},
remove: () => {
return isMarkActive({ state: getState(), type });
},
public isEnabled({ getState, type }: SchemaMarkTypeParams): BooleanExtensionCheck<this['_GCommands']> {
return ({ command }) => {
switch (command) {
case 'removeLink':
return isMarkActive({ state: getState(), type });
case 'updateLink':
const { selection } = getState();
if (selectionEmpty(selection) || !isTextSelection(selection)) {
return false;
}
return true;
default:
return true;
}
};
}

Expand Down
5 changes: 3 additions & 2 deletions @remirror/core-extensions/src/marks/strike.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import {
CommandMarkTypeParams,
MarkExtension,
MarkExtensionOptions,
MarkExtensionSpec,
markInputRule,
markPasteRule,
SchemaMarkTypeParams,
} from '@remirror/core';
import { toggleMark } from 'prosemirror-commands';

export class StrikeExtension extends MarkExtension {
export class StrikeExtension extends MarkExtension<MarkExtensionOptions, 'strike'> {
get name() {
return 'strike' as const;
}
Expand Down Expand Up @@ -41,7 +42,7 @@ export class StrikeExtension extends MarkExtension {
}

public commands({ type }: CommandMarkTypeParams) {
return () => toggleMark(type);
return { strike: () => toggleMark(type) };
}

public inputRules({ type }: SchemaMarkTypeParams) {
Expand Down

0 comments on commit fe23958

Please sign in to comment.