generated from silverstripe/silverstripe-module
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
008e6c4
commit 0f9a1a6
Showing
29 changed files
with
9,289 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"tabWidth": 2, | ||
"useTabs": false, | ||
"singleQuote": true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
{ | ||
"SilverStripe-Markdown-Script-Header" : | ||
{ | ||
"prefix": "scriptheader", | ||
"description": "The default declarations for all scripts that use shared functions.", | ||
"body": [ | ||
"#!/usr/bin/env bash", | ||
"<<EOF", | ||
"", | ||
" SilverStripe-Markdown \\ Shell Scripts \\ $1 \\ $2", | ||
"", | ||
" $3", | ||
"", | ||
"EOF", | ||
"CURRENT_SCRIPT_DIRECTORY=\\${CURRENT_SCRIPT_DIRECTORY:-$(dirname \\$(realpath \\${BASH_SOURCE[0]:-\\${(%):-%x}}))}", | ||
"export SHARED_EXT_SCRIPTS_PATH=\\${SHARED_EXT_SCRIPTS_PATH:-\\$(realpath \\$CURRENT_SCRIPT_DIRECTORY/scripts)}", | ||
"export CURRENT_SCRIPT_FILENAME=\\${CURRENT_SCRIPT_FILENAME:-$(basename \\${BASH_SOURCE[0]:-\\${(%):-%x}})}", | ||
"export CURRENT_SCRIPT_FILENAME_BASE=\\${CURRENT_SCRIPT_FILENAME%.*}", | ||
". \"\\$SHARED_EXT_SCRIPTS_PATH/shared_functions.sh\"", | ||
"write_header" | ||
] | ||
}, | ||
"SilverStripe-Markdown-Shared-Script-Header" : | ||
{ | ||
"prefix": "sharedscriptheader", | ||
"description": "The default declarations for a script with shareable functions.", | ||
"body": [ | ||
"#!/usr/bin/env bash", | ||
"<<EOF", | ||
"", | ||
" SilverStripe-Markdown \\ Shared Functions \\ $1 \\ $2", | ||
"", | ||
" $3", | ||
"", | ||
"EOF", | ||
"[ -n \"\\${SHARED_FUNCTIONS_EXT}\" ] && return", | ||
"SHARED_FUNCTIONS_EXT=0", | ||
"CURRENT_SCRIPT_DIRECTORY_FUNCTIONS=$(dirname $(realpath ${BASH_SOURCE[0]:-${(%):-%x}}))", | ||
"export SHARED_EXT_SCRIPTS_PATH=$(realpath \\${SHARED_EXT_SCRIPTS_PATH:-\\$CURRENT_SCRIPT_DIRECTORY_FUNCTIONS})" | ||
] | ||
}, | ||
"SilverStripe-Markdown-Script-Options" : | ||
{ | ||
"prefix": "scriptoptions", | ||
"body": [ | ||
"while getopts ':$1h?' opt; do", | ||
" case \\$opt in", | ||
" h|?)", | ||
" usage", | ||
" ;;", | ||
" :)", | ||
" write_error \"${TM_FILENAME_BASE}\" \"-\\${OPTARG} requires an argument\"", | ||
" usage", | ||
" ;;", | ||
" *)", | ||
" usage", | ||
" ;;", | ||
" esac", | ||
"done" | ||
] | ||
}, | ||
"SilverStripe-Markdown-Write-Response" : | ||
{ | ||
"prefix": "wr", | ||
"description": "", | ||
"body": [ | ||
"write_response \"${TM_FILENAME_BASE/(.*)/${1:/downcase}/}\" \"$1\"" | ||
] | ||
}, | ||
"SilverStripe-Markdown-Write-Info" : | ||
{ | ||
"prefix": "wi", | ||
"description": "", | ||
"body": [ | ||
"write_info \"${TM_FILENAME_BASE/(.*)/${1:/downcase}/}\" \"$1\"" | ||
] | ||
}, | ||
"SilverStripe-Markdown-Write-Error" : | ||
{ | ||
"prefix": "we", | ||
"description": "", | ||
"body": [ | ||
"write_error \"${TM_FILENAME_BASE/(.*)/${1:/downcase}/}\" \"$1\"" | ||
] | ||
}, | ||
"SilverStripe-Markdown-Write-Success" : | ||
{ | ||
"prefix": "ws", | ||
"description": "", | ||
"body": [ | ||
"write_success \"${TM_FILENAME_BASE/(.*)/${1:/downcase}/}\" \"$1\"" | ||
] | ||
}, | ||
"SilverStripe-Markdown-Write-Warning" : | ||
{ | ||
"prefix": "ww", | ||
"description": "", | ||
"body": [ | ||
"write_warning \"${TM_FILENAME_BASE/(.*)/${1:/downcase}/}\" \"$1\"" | ||
] | ||
}, | ||
"SilverStripe-Markdown-Null-Check" : | ||
{ | ||
"prefix": "null", | ||
"description": "A simple null check", | ||
"body": [ | ||
"if [ -z \"$1\" ]; then", | ||
" $2", | ||
"fi" | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#!/usr/bin/env bash | ||
<<EOF | ||
SilverStripe-Markdown \ Shell Scripts \ Build \ Client | ||
Build the client for the module | ||
EOF | ||
CURRENT_SCRIPT_DIRECTORY=${CURRENT_SCRIPT_DIRECTORY:-$(dirname $(realpath ${BASH_SOURCE[0]:-${(%):-%x}}))} | ||
export SHARED_EXT_SCRIPTS_PATH=${SHARED_EXT_SCRIPTS_PATH:-$(realpath $CURRENT_SCRIPT_DIRECTORY)} | ||
export CURRENT_SCRIPT_FILENAME=${CURRENT_SCRIPT_FILENAME:-$(basename ${BASH_SOURCE[0]:-${(%):-%x}})} | ||
export CURRENT_SCRIPT_FILENAME_BASE=${CURRENT_SCRIPT_FILENAME%.*} | ||
. "$SHARED_EXT_SCRIPTS_PATH/shared_functions.sh" | ||
write_header | ||
|
||
|
||
write_success "build_client" "Done" |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,11 @@ | ||
import Injector from 'lib/Injector'; | ||
import ExampleComponent from 'components/ExampleComponent/ExampleComponent'; | ||
import MarkdownEditorComponent from 'components/MarkdownEditorComponent/MarkdownEditorComponent'; | ||
|
||
export default () => { | ||
Injector.component.registerMany({ | ||
// List your React components here so Injector is aware of them | ||
ExampleComponent | ||
ExampleComponent, | ||
MarkdownEditorComponent | ||
}); | ||
}; |
5 changes: 2 additions & 3 deletions
5
client/src/components/ExampleComponent/tests/ExampleComponent-test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,11 @@ | ||
|
||
/* global jest, test, expect */ | ||
|
||
import React from 'react'; | ||
import ExampleComponent from '../ExampleComponent'; | ||
import { render } from '@testing-library/react'; | ||
import ExampleComponent from '../ExampleComponent'; | ||
|
||
test('ExampleComponent renders', async () => { | ||
const { container } = render(<ExampleComponent/>); | ||
const { container } = render(<ExampleComponent />); | ||
const options = container.querySelectorAll('.example-component'); | ||
expect(options).toHaveLength(1); | ||
}); |
163 changes: 163 additions & 0 deletions
163
client/src/components/MarkdownEditorComponent/MarkdownEditorComponent.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
import React from 'react'; | ||
|
||
import ReactDOM from 'react-dom'; | ||
|
||
import ReactSimpleMDE from 'react-simplemde-editor'; | ||
import jQuery from 'jquery'; | ||
import ShortcodeParser from '../ShortCodeParser/ShortCodeParser'; | ||
|
||
const SimpleMDE = require('simplemde'); | ||
|
||
const parser = new ShortcodeParser(); | ||
|
||
const ss = typeof window.ss !== 'undefined' ? window.ss : {}; | ||
if (typeof ss.markdownConfigs === 'undefined') { | ||
ss.markdownConfigs = {}; | ||
} | ||
|
||
ss.markdownConfigs.readToolbarConfigs = function (data) { | ||
const toolbar = []; | ||
for (const key in data) { | ||
const element = data[key]; | ||
if (typeof element === 'string') { | ||
toolbar.push(element); | ||
} else { | ||
const action = element.action; | ||
if (typeof SimpleMDE[element.action] !== 'undefined') { | ||
toolbar.push({ | ||
name: element.name, | ||
action: SimpleMDE[element.action], | ||
className: element.className, | ||
title: element.title, | ||
}); | ||
} else if (typeof ss.markdownConfigs[element.action] !== 'undefined') { | ||
toolbar.push({ | ||
name: element.name, | ||
action(editor) { | ||
ss.markdownConfigs[action](editor); | ||
}, | ||
className: element.className, | ||
title: element.title, | ||
}); | ||
} | ||
} | ||
} | ||
return toolbar; | ||
}; | ||
|
||
parser.registerShortCode('image_link', (buffer, opts) => opts.url); | ||
|
||
parser.registerShortCode( | ||
'embed', | ||
(buffer, opts) => | ||
`<img src="${opts.thumbnail} width="${opts.width} height="${opts.height}">` | ||
); | ||
|
||
class MarkdownEditorField extends React.Component { | ||
constructor(props) { | ||
super(props); | ||
this.state = ss.markdownConfigs; | ||
} | ||
|
||
handleChange(value) { | ||
this.props.textarea.value = value; | ||
} | ||
|
||
previewRender(plainText, preview) { | ||
preview.classList.add('markdown-preview'); | ||
preview.classList.add(this.identifier); | ||
const parsedText = parser.parse(plainText); | ||
return this.parent.markdown(parsedText); | ||
} | ||
|
||
static addCustomAction(key, action) { | ||
ss.markdownConfigs[key] = action; | ||
} | ||
|
||
static registerShortCodes(key, callback) { | ||
if (key == null) { | ||
throw new Error('Key is null'); | ||
} | ||
if (callback == null) { | ||
throw new Error('Callback is null'); | ||
} | ||
} | ||
|
||
render() { | ||
return ( | ||
<div className="editor-container"> | ||
<ReactSimpleMDE | ||
value={this.props.textarea.value} | ||
onChange={this.handleChange.bind(this)} | ||
options={{ | ||
spellChecker: true, | ||
dragDrop: false, | ||
keyMap: 'sublime', | ||
toolbar: this.props.toolbar, | ||
previewRender: this.previewRender, | ||
identifier: this.props.identifier, | ||
}} | ||
/> | ||
</div> | ||
); | ||
} | ||
} | ||
|
||
window.MarkdownEditorField = MarkdownEditorField; | ||
|
||
jQuery.entwine('ss', ($) => { | ||
MarkdownEditorField.addCustomAction('ssEmbed', (editor) => { | ||
if (window.InsertMediaModal) { | ||
let dialog = $('#insert-md-embed-react__dialog-wrapper'); | ||
if (!dialog.length) { | ||
dialog = $('<div id="insert-md-embed-react__dialog-wrapper" />'); | ||
$('body').append(dialog); | ||
} | ||
dialog.setElement(editor); | ||
dialog.open(); | ||
} else { | ||
alert('Media embed is not supported'); | ||
} | ||
}); | ||
|
||
MarkdownEditorField.addCustomAction('ssImage', (editor) => { | ||
if (window.InsertMediaModal) { | ||
let dialog = $('#insert-md-media-react__dialog-wrapper'); | ||
if (!dialog.length) { | ||
dialog = $('<div id="insert-md-media-react__dialog-wrapper" />'); | ||
$('body').append(dialog); | ||
} | ||
dialog.setElement(editor); | ||
dialog.open(); | ||
} else { | ||
SimpleMDE.drawImage(editor); | ||
} | ||
}); | ||
|
||
$('.js-markdown-container:visible').entwine({ | ||
onunmatch() { | ||
this._super(); | ||
ReactDOM.unmountComponentAtNode(this[0]); | ||
}, | ||
onmatch() { | ||
this._super(); | ||
this.refresh(); | ||
}, | ||
refresh() { | ||
const textArea = $(this).parent().find('textarea')[0]; | ||
const data = JSON.parse(textArea.dataset.config); | ||
const toolbar = ss.markdownConfigs.readToolbarConfigs(data.toolbar); | ||
|
||
ReactDOM.render( | ||
<MarkdownEditorField | ||
textarea={textArea} | ||
toolbar={toolbar} | ||
identifier={data.identifier} | ||
/>, | ||
this[0] | ||
); | ||
}, | ||
}); | ||
}); | ||
|
||
export default { MarkdownEditorField }; |
Empty file.
Oops, something went wrong.