Meta: Prettier and cleanup (#182)

This commit is contained in:
Federico 2021-01-29 01:11:51 -06:00 committed by GitHub
parent 261c838a82
commit d8703b5d5c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 15393 additions and 15375 deletions

15
.editorconfig Normal file
View File

@ -0,0 +1,15 @@
root = true
[*]
indent_style = tab
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.yml]
indent_style = space
indent_size = 2
[*.md]
trim_trailing_whitespace = false

View File

@ -2,13 +2,10 @@
Thanks for trying out GhostText and opening this issue!
Before opening an issue for a possible bug,
please make sure you try GhostText in Chrome and Sublime Text.
This is the most common configuration and will help me
understand better where the problem is.
Before opening an issue for a possible bug, please make sure you try GhostText in Chrome and Sublime Text.
This is the most common configuration and will help me understand better where the problem is.
If it works with Sublime Text but not with a third party editor,
please open an issue in their repository.
If it works with Sublime Text but not with a third party editor, please open an issue in their repository.
-->

19
.github/workflows/labeler.yml vendored Normal file
View File

@ -0,0 +1,19 @@
env: {}
# DO NOT EDIT BELOW, USE: npx ghat fregante/title-to-labels-action/workflow
name: Labeler
on:
pull_request:
types: [opened, edited]
issues:
types: [opened, edited]
jobs:
Label:
runs-on: ubuntu-latest
steps:
- uses: fregante/title-to-labels-action@v1
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

47
.gitignore vendored
View File

@ -1,44 +1,5 @@
*.py[cod]
# C extensions
*.so
# Packages
*.egg
*.egg-info
dist
build
eggs
parts
bin
var
sdist
develop-eggs
.installed.cfg
lib
lib64
__pycache__
# Installer logs
pip-log.txt
# Unit test / coverage reports
.coverage
.tox
nosetests.xml
# Translations
*.mo
# Mr Developer
.mr.developer.cfg
.project
.pydevproject
.idea
.xpi
node_modules
ChromeExtension.pem
browser/scripts/input-area.js
yarn.lock
distribution
.cache
.parcel-cache

View File

@ -24,7 +24,7 @@ The Server responds with a `200` and a content type of `application/json`.
The JSON payload is an object with the following properties:
| Property | Type | Description |
|-------------------|--------|-------------|
| ----------------- | ------ | ------------------------------------ |
| `ProtocolVersion` | Number | The protocol version |
| `WebSocketPort` | Number | The port for the listening WebSocket |
@ -54,10 +54,10 @@ connect) the Client sends via the WebSocket a JSON object message with the
following properties:
| Property | Value | Description |
|--------------|------------------------|-------------|
| ------------ | ---------------------- | ---------------------------------------------------------------------------------------------- |
| `title` | String | The title of the document |
| `url` | String | The URL of the document |
| `syntax` | String | *Not used* |
| `syntax` | String | _Not used_ |
| `text` | String | The value of the textarea/content |
| `selections` | Array(SelectionObject) | An array of selection objects that describe the user's current cursor selections in the editor |
@ -66,7 +66,7 @@ following properties:
Selection objects have the following properties:
| Property | Value | Description |
|----------|--------|-------------|
| -------- | ------ | ------------------------------ |
| `start` | Number | 0-index start of the selection |
| `end` | Number | 0-index end of the selection |
@ -93,7 +93,7 @@ Each time the user makes a change in the editor the Server sends via the
WebSocket a JSON object message with the following properties:
| Property | Value | Description |
|--------------|------------------------|-------------|
| ------------ | ---------------------- | ---------------------------------------------------------------------------------------------- |
| `text` | String | The temporary file content |
| `selections` | Array(SelectionObject) | An array of selection objects that describe the user's current cursor selections in the editor |

View File

@ -1,5 +1,8 @@
# <img src="https://raw.githubusercontent.com/GhostText/GhostText/master/promo/gt_banner.png" height="60" alt="GhostText">
[link-cws]: https://chrome.google.com/webstore/detail/ghosttext/godiecgffnchndlihlpaajjcplehddca 'Version published on Chrome Web Store'
[link-amo]: https://addons.mozilla.org/en-US/firefox/addon/ghosttext/ 'Version published on Mozilla Add-ons'
<img src="promo/demo.gif" alt="Demo screencast" align="right">
Use your text editor to write in your browser. Everything you type in the editor will be instantly updated in the browser (and vice versa).
@ -9,12 +12,13 @@ Use your text editor to write in your browser. Everything you type in the editor
## Installation
1. Install your editor extension:
+ [**Sublime Text** extension](https://sublime.wbond.net/packages/GhostText) - [Repo](https://github.com/GhostText/GhostText-for-SublimeText)
+ [**Atom** package](https://github.com/GhostText/GhostText-for-Atom)
+ [**VS Code** extension](https://marketplace.visualstudio.com/items?itemName=tokoph.ghosttext) - [Repo](https://github.com/jtokoph/ghosttext-vscode) (Third party)
+ [**Emacs** package](https://melpa.org/#/atomic-chrome) - [Repo](https://github.com/alpha22jp/atomic-chrome) (Third party)
+ [**Acme** client](https://github.com/fhs/Ghost) (Third party)
+ <details>
- [**Sublime Text**](https://sublime.wbond.net/packages/GhostText) ([Repo](https://github.com/GhostText/GhostText-for-SublimeText))
- [**Atom**](https://github.com/GhostText/GhostText-for-Atom)
- [**VS Code**](https://marketplace.visualstudio.com/items?itemName=tokoph.ghosttext) ([Repo](https://github.com/jtokoph/ghosttext-vscode)) (Third party)
- [**Emacs**](https://melpa.org/#/atomic-chrome) ([Repo](https://github.com/alpha22jp/atomic-chrome)) (Third party)
- [**Acme**](https://github.com/fhs/Ghost) (Third party)
- <details>
<summary><b>Vim</b>/<b>Neovim</b> (Third party)</summary>
<ul>
<li><a href="https://github.com/raghur/vim-ghost"><b>Vim</b> (<tt>+python3</tt>) & <b>Neovim</b> (<tt>pynvim</tt>)</a>
@ -23,17 +27,18 @@ Use your text editor to write in your browser. Everything you type in the editor
<li><a href="https://github.com/subnut/nvim-ghost.nvim"><b>Neovim</b></a>
</ul>
</details>
2. Install your browser extension:
+ [**Chrome** extension](https://chrome.google.com/webstore/detail/ghosttext/godiecgffnchndlihlpaajjcplehddca)
+ [**Firefox** add-on](https://addons.mozilla.org/en-US/firefox/addon/ghosttext/)
+ Opera - Use [this](https://addons.opera.com/en/extensions/details/download-chrome-extension-9/) to install the Chrome extension.
- [**Chrome**][link-cws] [<img valign="middle" src="https://img.shields.io/chrome-web-store/v/godiecgffnchndlihlpaajjcplehddca.svg?label=%20">][link-cws]
- [**Firefox**][link-amo] [<img valign="middle" src="https://img.shields.io/amo/v/ghosttext.svg?label=%20">][link-amo]
## Website support
* `<textarea>` elements
* [`contentEditable`](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Content_Editable) areas: like in Gmail
* [CodeMirror](http://codemirror.net/) editors: used on CodePen, JSFiddle, JS Bin, …
* [Ace](http://ace.c9.io/) editor: used on Tumblr, …
- `<textarea>` elements
- [`contentEditable`](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Content_Editable) areas: like in Gmail
- [CodeMirror](http://codemirror.net/) editors: used on CodePen, JSFiddle, JS Bin, …
- [Ace](http://ace.c9.io/) editor: used on Tumblr, …
## Usage
@ -71,4 +76,4 @@ or
## License
MIT © [Federico Brigante](http://twitter.com/bfred_it), Guido Krömer
MIT © [Federico Brigante](https://fregante.com)

View File

@ -1,13 +1,11 @@
# <img src="https://raw.githubusercontent.com/GhostText/GhostText/master/promo/gt_banner.png" height="60" alt="GhostText">
[![Chrome version][badge-cws]][link-cws] [![Firefox version][badge-amo]][link-amo] [![Autodeployment][badge-travis]][link-travis]
[![Chrome version][badge-cws]][link-cws] [![Firefox version][badge-amo]][link-amo]
[badge-cws]: https://img.shields.io/chrome-web-store/v/godiecgffnchndlihlpaajjcplehddca.svg?label=for%20chrome
[badge-amo]: https://img.shields.io/amo/v/ghosttext.svg?label=for%20firefox
[badge-travis]: https://img.shields.io/travis/GhostText/GhostText/master.svg?label=autodeployment
[link-cws]: https://chrome.google.com/webstore/detail/ghosttext/godiecgffnchndlihlpaajjcplehddca "Version published on Chrome Web Store"
[link-amo]: https://addons.mozilla.org/en-US/firefox/addon/ghosttext/ "Version published on Mozilla Add-ons"
[link-travis]: https://travis-ci.org/GhostText/GhostText
[badge-cws]: https://img.shields.io/chrome-web-store/v/godiecgffnchndlihlpaajjcplehddca.svg?label=for%20chrome
[badge-amo]: https://img.shields.io/amo/v/ghosttext.svg?label=for%20firefox
[link-cws]: https://chrome.google.com/webstore/detail/ghosttext/godiecgffnchndlihlpaajjcplehddca 'Version published on Chrome Web Store'
[link-amo]: https://addons.mozilla.org/en-US/firefox/addon/ghosttext/ 'Version published on Mozilla Add-ons'
## Installation

View File

@ -1,11 +1,13 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<meta charset="UTF-8" />
<title>GhostText options</title>
<style>
html {
font-family: sans-serif;
}
label, button, footer {
label,
button,
footer {
display: block;
margin: 1em 0;
}
@ -15,7 +17,7 @@
footer {
font-style: italic;
font-size: 0.8em;
color: gray
color: gray;
}
footer a {
color: inherit;
@ -24,11 +26,21 @@
<form id="options-form">
<label>
Server Port
<input name="serverPort" type="number" min="1" max="65536" step="1" placeholder="4001" value="4001" required>
<input
name="serverPort"
type="number"
min="1"
max="65536"
step="1"
placeholder="4001"
value="4001"
required
/>
</label>
</form>
<footer>
Issues? Lets fix them on <a href="https://github.com/GhostText/GhostText">GhostTexts GitHub repo</a>!
</div>
Issues? Lets fix them on
<a href="https://github.com/GhostText/GhostText">GhostTexts GitHub repo</a>!
</footer>
<script src="vendor/webext-options-sync.js"></script>
<script src="scripts/options.js"></script>

View File

@ -16,7 +16,10 @@ async function handleAction({id}) {
runAt: 'document_start',
allFrames: true
};
const [alreadyInjected] = await browser.tabs.executeScript(id, {...defaults, code: 'typeof window.startGT === "function"'});
const [alreadyInjected] = await browser.tabs.executeScript(id, {
...defaults,
code: 'typeof window.startGT === "function"'
});
console.log(alreadyInjected);
if (alreadyInjected) {
return browser.tabs.executeScript(id, {...defaults, code: 'startGT()'});
@ -75,9 +78,9 @@ chrome.runtime.onConnect.addListener(handlePortListenerErrors(async port => {
socket.addEventListener('message', event => port.postMessage({message: event.data}));
socket.addEventListener('error', event => console.error('error!', event));
port.onMessage.addListener(msg => {
console.log('got message from script', msg);
socket.send(msg);
port.onMessage.addListener(message => {
console.log('got message from script', message);
socket.send(message);
});
console.log(port);
port.onDisconnect.addListener(() => {

View File

@ -2,11 +2,11 @@
transition: box-shadow 1s cubic-bezier(0.25, 2, 0.5, 1);
}
.GT--waiting [data-gt-field] {
box-shadow: #00F25A 0 0 20px inset;
box-shadow: #00f25a 0 0 20px inset;
}
[data-gt-field="loading"] {
box-shadow: #FFB600 0 0 20px 5px inset;
[data-gt-field='loading'] {
box-shadow: #ffb600 0 0 20px 5px inset;
}
[data-gt-field="enabled"] {
box-shadow: #00ACEE 0 0 20px 5px inset !important;
[data-gt-field='enabled'] {
box-shadow: #00acee 0 0 20px 5px inset !important;
}

View File

@ -6,12 +6,12 @@ const activeFields = new Set();
let isWaitingForActivation = false;
class ContentEditableWrapper {
constructor(el) {
this.el = el;
this.dataset = el.dataset;
this.addEventListener = el.addEventListener.bind(el);
this.removeEventListener = el.removeEventListener.bind(el);
this.blur = el.blur.bind(el);
constructor(element) {
this.el = element;
this.dataset = element.dataset;
this.addEventListener = element.addEventListener.bind(element);
this.removeEventListener = element.removeEventListener.bind(element);
this.blur = element.blur.bind(element);
}
get value() {
@ -24,15 +24,17 @@ class ContentEditableWrapper {
}
class AdvancedTextWrapper {
constructor(el, visualEl) {
this.el = el;
this.dataset = visualEl.dataset;
constructor(element, visualElement) {
this.el = element;
this.dataset = visualElement.dataset;
this.el.addEventListener('gt:input', event => {
this._value = event.detail.value;
});
this.el.dispatchEvent(new CustomEvent('gt:get', {
this.el.dispatchEvent(
new CustomEvent('gt:get', {
bubbles: true
}));
})
);
}
blur() {
@ -63,14 +65,14 @@ class AdvancedTextWrapper {
function wrapField(field) {
if (field.classList.contains('ace_text-input')) {
const ace = field.parentNode;
const visualEl = ace.querySelector('.ace_scroller');
return new AdvancedTextWrapper(ace, visualEl);
const visualElement = ace.querySelector('.ace_scroller');
return new AdvancedTextWrapper(ace, visualElement);
}
const cm = field.closest('.CodeMirror');
if (cm) {
const visualEl = cm.querySelector('.CodeMirror-sizer');
return new AdvancedTextWrapper(cm, visualEl);
const visualElement = cm.querySelector('.CodeMirror-sizer');
return new AdvancedTextWrapper(cm, visualElement);
}
if (field.isContentEditable) {
@ -103,13 +105,13 @@ class GhostTextField {
this.field.dataset.gtField = 'loading';
this.port = chrome.runtime.connect({name: 'new-field'});
this.port.onMessage.addListener(msg => {
if (msg.message) {
this.receive({data: msg.message});
} else if (msg.close) {
this.port.onMessage.addListener(message => {
if (message.message) {
this.receive({data: message.message});
} else if (message.close) {
this.deactivate(false);
updateCount();
} else if (msg.ready) {
} else if (message.ready) {
notify('log', 'Connected! You can switch to your editor');
this.field.addEventListener('input', this.send);
@ -118,8 +120,8 @@ class GhostTextField {
// Send first value to init tab
this.send();
updateCount();
} else if (msg.error) {
notify('warn', msg.error);
} else if (message.error) {
notify('warn', message.error);
this.deactivate(false);
}
});
@ -131,7 +133,8 @@ class GhostTextField {
}
console.info('sending', this.field.value.length, 'characters');
this.port.postMessage(JSON.stringify({
this.port.postMessage(
JSON.stringify({
title: document.title, // TODO: move to first fetch
url: location.host, // TODO: move to first fetch
syntax: '', // TODO: move to first fetch
@ -142,14 +145,13 @@ class GhostTextField {
end: this.field.selectionEnd || 0
}
]
}));
})
);
}
receive(event) {
const {
text,
selections
} = JSON.parse(event.data);
const {text, selections} = JSON.parse(event.data);
if (this.field.value !== text) {
this.field.value = text;

View File

@ -15,9 +15,7 @@ window.unsafeMessenger = function () {
}
function sendBack(target, value) {
target.dispatchEvent(
new CustomEvent('gt:input', {detail: {value}})
);
target.dispatchEvent(new CustomEvent('gt:input', {detail: {value}}));
}
function throttle(interval, callback) {
@ -37,11 +35,14 @@ window.unsafeMessenger = function () {
sendBack(target, editor.getValue());
editor.on('changes', throttle(50, (instance, [{origin}]) => {
editor.on(
'changes',
throttle(50, (instance, [{origin}]) => {
if (origin !== 'setValue') {
sendBack(target, editor.getValue());
}
}));
})
);
target.addEventListener('gt:transfer', () => {
editor.setValue(target.getAttribute('gt-value'));
});

View File

@ -1,8 +1,11 @@
<html>
<head>
<meta charset="UTF-8">
<head>
<meta charset="UTF-8" />
<title>GhostText test page</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.32.0/codemirror.min.css">
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.32.0/codemirror.min.css"
/>
<style>
html {
font-family: sans-serif;
@ -37,9 +40,13 @@
height: 200px;
}
</style>
</head>
</head>
<h1>
<img src="https://raw.githubusercontent.com/GhostText/GhostText/master/promo/gt_banner.png" height="60" alt="GhostText">
<img
src="https://raw.githubusercontent.com/GhostText/GhostText/master/promo/gt_banner.png"
height="60"
alt="GhostText"
/>
</h1>
<h2><code>&lt;textarea&gt;</code></h2>
@ -74,10 +81,9 @@
</pre>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.9/ace.js"></script>
<script>
window.ace.edit('ace').setOption("maxLines", 30)
window.ace.edit('ace').setOption('maxLines', 30);
</script>
<h2>Fields inside <code>&lt;iframe&gt;</code></h2>
<iframe src="." frameborder="0">One level deep, please!</iframe>
</html>

View File

@ -1,8 +1,5 @@
{
"private": true,
"devDependencies": {
"xo": "^0.37.1"
},
"scripts": {
"test": "xo"
},
@ -11,15 +8,17 @@
"browser",
"webextensions"
],
"rules": {
"unicorn/prevent-abbreviations": 0,
"no-alert": 0
},
"globals": [
"oneEvent"
],
"ignores": [
"browser/vendor/*"
]
],
"rules": {
"no-alert": "off"
}
},
"devDependencies": {
"xo": "^0.37.1"
}
}