Comments (38)
Before we start this we should find a way to abstract this part because:
- keep this complexity apart from the content script
- new browser based editors will come
- this part could be reused in an firefox plug in
Lets start with a simple interface called IEditable
, I will use some Java inspired pseudocode:
interface IEditable {
bind(domElement);
unbind();
textChangedEvent(callback);
selectionChangedEvent(callback);
changeText(text);
getText();
getSelection();
setSelection(selection);
}
The textarea implementation could look like this.
class TextArea implements IEditable {
private domElement;
bind(domElement) {
this.unbind()
this.domElement = domElement;
}
unbind() {
if (!this.domElement) {
return;
}
$(this.domElement).off('.ghost-text');
}
textChangedEvent(callback) {
$(this.domElement).on('input.ghost-text', callback);
}
selectionChangedEvent(callback) {
//...
}
changeText(text) {
$(this.domElement).val(text);
}
getText() {
return $(this.domElement).val();
}
getSelection() {
return [{
start: this.domElement.selectionStart,
end: this.domElement.selectionEnd
}];
}
setSelection(selection) {
this.domElement.selectionStart = selection[0].start;
this.domElement.selectionEnd = selection[0].end;
}
}
By this way we could add other "editors" easily without messing up the code…
Interfaces in JS: https://developers.google.com/closure/compiler/docs/js-for-compiler?hl=de#tag-interface
from ghosttext-for-chrome.
Perfect. Yes. The interface will also need a search
method as well to see if the page contains any elements like that. Something like:
var areas = [];
areas.push.apply(TextareaField.search());
//areas == [textarea1, textarea2]
areas.push.apply(ACEField.search());
//areas == [textarea1, textarea2, acefield]
areas.push.apply(CodeMirrorField.search());
//areas == [textarea1, textarea2, acefield, codemirrorfield]
As well as some focus
methods like
var waitForAny = function () {
$.each(area, function () {
this.waitForFocus(stopAllWaitingCallback);
});
}
var stopAllWaitingCallback = function () {
$.each(area, function () {
this.stopWaiting();
});
}
if(areas.length === 1) {
area[0].activate();
} else if(areas.length > 1) {
waitForAny();
}
Or something like that
from ghosttext-for-chrome.
Let me do the interface and the text area implementation at the weekend.
Even if are only supporting the text area in Milestone 1 the interface should be already implemented.
from ghosttext-for-chrome.
What about contenteditable
elements? Is support for that planned? Gmail uses <div contenteditable="true"> [...] </div>
elements to compose/replay emails. I think only plain-text editing would be supported, but that should cover most cases.
from ghosttext-for-chrome.
I think we kind of could, but we'd have to warn people that formatting will be lost. The only difference with the textarea is that we'd have to somehow convert linebreaks into <br>
and <p>
People would probably expect to support rich text editing eventually, which Sublime Text doesn't have. Adding a HTML->Markdown->HTML converter is unlikely, that'd feature alone would be bigger than GhostText itself and prone to issues.
OOoorr… we could push HTML to Sublime Text instead of plain text, which would be kinda nice, actually.
from ghosttext-for-chrome.
- Some code for conversion of linebreaks to
<br>
/<p>
can be found in the Django template system. - I agree with not transforming from HTML->Markdown->HTML, just the HTML->Markdown will be pretty hard to accomplish, since most of the HTML email is not the output of Markdown...
- The issue that concerns me is the "warning" about loosing formatting, because it's important to warn the user, and it's an extra click/step for the user before start editing in ST, and also, that extra step allows the user to cancel the editiion on ST.
from ghosttext-for-chrome.
I currently pushed the first proof of concept to the new branch input-area
, the code is not working right now, those little ST issues stole my time.
But I hope until the end of the week I got a working version.
from ghosttext-for-chrome.
Just a quick sidenote: You can actually compose your Gmail messages in markdown by using Markdown Here. For that reason alone I would love to see GhostText support Gmail.
from ghosttext-for-chrome.
EDIT: actually MDH already seems to handle this:
The problem with that conversion is that if a quoted message is below (and not hidden by Gmail) GT will
- flatten it to plain text when pushing it to Sublime
- mess up any possible markdown-like text in it when re-converting it to html
So we might have to detect un-translatable content and warn the user that they'll lose that HTML
from ghosttext-for-chrome.
A simple implementation would just complement MDHere, by supporting a contentEditable as a plain text field. The user will have to convert it to HTML after using GT, or else GT will receive the generated HTML as plain text (and the formatting will be lost)
If we want to integrate that conversion in GT, which may or may not be possible (time, license, …), we can use the contentEditable
as a "markdown preview". This means we'll have to run a HTML-to-MD conversion when the user types in the browser and a MD-to-HTML conversion when the user types in the editor. If this is processor intensive we can throttle it to update once a second.
from ghosttext-for-chrome.
The last commit adds basic contentEditable support, I used http://html5demos.com/contenteditable for testing only, when using the content editable's innerHTML the palin HTML gets used and this basically works…
Here is a video how good and bad it currently works: https://www.youtube.com/watch?v=a1MpifbF858&feature=youtu.be
Please don't share this video due it's quality!
from ghosttext-for-chrome.
Love it! It makes sense to write in HTML after all. If the syntax is set to HTML (using GTcontent.guessSyntax) it'd be a breeze to write with emmet
from ghosttext-for-chrome.
I currently tested it with google groups, it worked!
You are right with emmet its pure fun 😄
from ghosttext-for-chrome.
About ACE editor and CodeMirror, it's impossible to access the page JS and it's variables throug the content script, but there might be a workaround: http://stackoverflow.com/questions/20499994/access-window-variable-from-content-script .
What I'm trying now is to add an script to the page which creates a text area in the dom which syncs with the ace editor and vice versa. The helper text area should then be modifiable by GT as usual… .
from ghosttext-for-chrome.
Why add a helper textarea
though? We'll still need to use CodeMirror's API to get/set the text, so why also keep in sync a textarea?
The only issue was access to the the API, once we got that we should be able to work directly on the enabled element
from ghosttext-for-chrome.
From the content script only the dom is accessible not the "running" JS. The content script has it's own JS scope. Therefore a little glue is needed - a script injected into the dom which runs in the page JS scope. This scripts accesses the editor's API from here and pushes and pulls the changes to a hidden textarea. The hidden textarea is accessible through the dom and can sync the changes between the both JS scopes, in the theory.
from ghosttext-for-chrome.
Currently only the events aren't working correctly, when this is done we have a running ACE editor support…
Communicating through dom events although might be an option. But this has to be tested first, too.
from ghosttext-for-chrome.
Ah, it looks like unsafeWindow
is no longer accessible. You used to be able to access global variables and nodes.
Anyway I always suggest avoiding editing the page, so instead of the textarea (which we use exclusively to get the text) why not just use element.dataset.ghosttext
? That's available from the contentScript as well.
Alternatively just pass the text back an forth using events (which we're going to need anyway)
//inject on the page:
//update GT
element.CodeMirror.on('change', function (text) {
$(element).trigger('ghost-text-change', {text: text});
});
//update CodeMirror
$(element).on('ghost-text-update', function(event) {
element.CodeMirror.set(event.data.text)
});
//use in contentscript
//update GT
$(element).on('ghost-text-change', function(event) {
GT.updateSublime(event.data.text)
});
GT.onUpdateFromSublime = function (text) {
$(element).trigger('ghost-text-update', {text: text});
}
from ghosttext-for-chrome.
The event approach I'm currently trying:
(function() {
…
var inputEvent = document.createEvent("CustomEvent");
inputEvent.initEvent("GhostTextJSCodeEditorInput", false, false);
ghostTextAceEditor.on("change", function(e) {
console.log("ghostTextAceEditor.on > change");
var value = ghostTextAceEditor.getValue();
inputEvent.details = {text: value};
window.dispatchEvent(inputEvent);
});
…
});
The ACE's focus event is currently not firing, but if it works we need only one additional editor class JSCodeEditor
besides the TextArea
and the ContentEditable
. The rest would be stupid messaging using events.
The focus event is working now, this comes from the editor not the editors session 😣 .
from ghosttext-for-chrome.
The last commit adds basic support for ACE, but there is still a bug which occurs when edition in both directions is enabled. Maybe it can be solved by disabling the ACE change event when setting the text and reenabling it after the text has been modified, but I'm too tired now.
https://www.youtube.com/watch?v=MSrk6cPkeBk&feature=youtu.be
from ghosttext-for-chrome.
The ACE script does only needs a cleanup, then we can continue with CodeMirror or finish the content editable 😤
https://www.youtube.com/watch?v=TbuMKalmvlM&feature=youtu.be
from ghosttext-for-chrome.
Great job! Looking nice
from ghosttext-for-chrome.
Thank you, now it's time for beta testing and some fine tuning.
And we have to take a look at the selections:
- The content editable could be pain in the ass because of the html…
- Both ACE and CodeMirror have a line number and char number selection based system which differs from the start and end char selection provided by ST…
from ghosttext-for-chrome.
contentEditable is alright editing straight HTML for now. I guess eventually we can add some setting to toggle markdown editing or something like that
from ghosttext-for-chrome.
No I where just talking about the selection logic (you select "Foo Bar" from the text
"Bazinga <p>Foo</p> <strong>Bar</strong> Baz"
), and how display the selection in the browsers front end despte the internal hmtl tags...
from ghosttext-for-chrome.
Now the ST selection gets send to the ace editor, only the codemirror is missing now…
from ghosttext-for-chrome.
Only a little testing is need now what do you think?
Here is a video showing many of the features https://www.youtube.com/watch?v=kqMDp65P4bU&feature=youtu.be it is currently not listed but I think it is good enough to post it on twitter, reddit…
from ghosttext-for-chrome.
Looks pretty good! I would make the video a little bit faster (maybe 2x?) because 8 minutes are a very long time for such a feature video.
I just tested a little bit and had some problems, but they could be independent of the feature set of this issue:
- Syncing ST with Chrome seems to only work if the text field is not empty, initally. I tested this on Github issues and on JSBin. Just try to use GhostText with an empty text field.
- Clicking on the desired text field doesn't work, if the text field already has the focus. One needs to unfocus and refocus the text field.
- When closing the tab in ST, Chrome reports an "Connection error". I think, the ST package should listen on the close-event and send an appropriate message to Chrome.
I hope my comments don't scatter the context of this issue too much.
from ghosttext-for-chrome.
Thanks for the feedback!
I gonna try to make a shorter video soon. I can't reproduce the connection error when closing the ST view, which OS are you using?
But the rest are bugs indeed:
- Fix cant connect with empty JS code editors.
- Make all JS code editors blurable.
- Blur all editable elements when there are multiple editables on one page.
from ghosttext-for-chrome.
Yeah the video doesn't work: Too long, too slow, low res, os elements visible and too many tabs (the user only need to focus on 1 thing), repeated examples, spelling mistakes and the GhostText is hidden in a dropdown. This is exactly why I suggested finding a specific list of things to show before filming and make a short gif instead.
from ghosttext-for-chrome.
@Cacodaimon: I'm using Windows 8. I just tried it again and it seems to be a reproducible:
When disconnecting Chrome messages a simple "Disconnected" which is fine. If you (quickly?) click again into the text field (in Chrome), there will be the "Connection error" message. I guess some listeners are not properly removed?
By the way: I would make the Sublime view a "scratch" view. This means that no confirmation dialogue will be shown when trying to close the view. Since no data can be lost (the text will be in Chrome anyway), the confirmation dialogue has no value.
@bfred-it: I totally agree with you.
from ghosttext-for-chrome.
@philippotto
I fixed the focus bug this should work now and the empty editor bug is fixed, too.
The Idea with the scratch mode is great: https://github.com/Cacodaimon/GhostText-for-SublimeText/releases/tag/1.0.6 thanks!
About the connection error I try this this weekend on my windows system because I can't reproduce it on my Linux system.
I agree the video is too long, but focusing on one page and showing just some markdown and emmet magic is cool for a gif but a video can show some more features in my opinion. Maybe three minutes with a faster timing and focusing on two or three pages (GitHub for markdown, JSBin for work with emmet…) would be better for an video.
from ghosttext-for-chrome.
@philippotto I can reproduce the error on my Windows system, it is a ST issue: fregante/GhostText#36 .
from ghosttext-for-chrome.
@bfred-it
I think it's ready to be merged into the master or do you have any objection?
from ghosttext-for-chrome.
I haven't been writing much on the web lately (therefore not using GT at all) but if you think it's ready for primetime then yes, go live!! 👍
from ghosttext-for-chrome.
Everything is merged now, can you upload it to the chrome web store?
from ghosttext-for-chrome.
Done, v1.1.0 is up there
Your item is in the process of being published and may take up to 60 minutes to appear in the Web Store
from ghosttext-for-chrome.
👍 thx
from ghosttext-for-chrome.
Related Issues (20)
- Time to celebrate HOT 2
- Support fields within frames (Disqus) HOT 13
- Keyboard hotkey for Linux collides with "Show bookmarks bar" HOT 3
- ⌘ + K key binding in Chrome Extension is already used HOT 3
- Make input-area.js Firefox compatible
- Support of g_editable elements HOT 1
- Highlight keeps on connection error HOT 5
- Fails after switching to Sublime Text (OSX 10.9.4, Sublime Text 3) HOT 5
- Events, mono-repo discussion HOT 12
- On pressing ctrl+shift+h, 4-5 sublime windows pop up and the text-to-chrome doesn't work HOT 4
- GhostText can't handle multiple file tabs in Codecademy HOT 2
- No longer working in Chrome HOT 2
- Ghost is opening 2 to 7 tabs when clicking in HOT 5
- Ghosttext fills the Chrome developer console with "Array[2]" #52
- Ghost Text Says that it is running and to switch to console, but no code opens
- blank render HOT 3
- Doesn't seem to work with the latest Chrome HOT 4
- ISSUES MOVED, open them in the main repo:
- How do I activate Ghosttext?
- Multi-caret editing. Sublime text 3 + Chrome HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.