8000 feat: Expose renderer spellcheck API by lishid · Pull Request #25060 · electron/electron · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

feat: Expose renderer spellcheck API #25060

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 19, 2020
Merged

feat: Expose renderer spellcheck API #25060

merged 1 commit into from
Oct 19, 2020

Conversation

lishid
Copy link
Contributor
@lishid lishid commented Aug 20, 2020

Description of Change

Exposes renderer side browser spellcheck API to the javascript environment.
Resolves #22829

Rationale: Electron-based apps that uses CodeMirror (a hugely popular editor) are unable to benefit from the built-in spellchecker since CodeMirror does not use a ContentEditable (everything is faked). CodeMirror exposes a way to highlight errors, but given that we are currently unable to ask for a spellcheck from javascript, all Electron+CodeMirror apps use a js-based spellcheck library like https://github.com/cfinke/Typo.js which is considerably slower than the built-in native spellchecker.

This PR adds the following API:

  • isWordMisspelled(word: string): boolean
  • getWordSuggestions(word: string): string[]

Current WIP adds the methods to the global process object which is just so I can test that it works.
I've tested this and it works. Now to figure out where to put the API.

Ideally I would like this to be a module on require('electron'), similar to IPCRenderer.
In practice, I have not found a way to pass the WeakPtr<Spellcheck> to the renderer API stack. I was also unable to find a reference back to ElectronRendererClient/RenderClientBase from an API module.
If someone with experience can give me some tips on how to achieve it that would be great!

Also currently missing tests and documentation.

Checklist

Release Notes

Notes: Added spellcheck API to renderer.

@electron-cation electron-cation bot added the new-pr 🌱 PR opened recently label Aug 20, 2020
@codebytere
Copy link
Member

cc @MarshallOfSound

#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
base::WeakPtr<SpellCheck> c = GetSpellCheck()->AsWeakPtr();

process_dict.SetMethod("isWordMisspelled", base::BindRepeating(&IsWordMisspelled, c));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, so this definitely shouldn't be on process. My guess is it should probably be on something like webFrame 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah agreed. I'm debating whether to put it on webFrame or adding its own module, something like require('electron').spellcheck.

Here's what I wrote in the PR description:

In practice, I have not found a way to pass the WeakPtr<Spellcheck> to the renderer API stack. I was also unable to find a reference back to ElectronRendererClient/RenderClientBase from an API module.
If someone with experience can give me some tips on how to achieve it that would be great!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lishid You can find some examples on adding new modules under shell/renderer/api/ folder.

Adding the APIs to webFrame would be simplest and you only need to move the code to shell/renderer/api/electron_api_web_frame.cc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zcbenz Thank you for the help! In my working copy I was already able to move the code & API to webFrame, however, I was unable to find a reference to the spellchecker object which is located on RefererClientBase. Any tips? It seems that all the samples I've seen only references content::RenderFrame gotten from a v8::Context

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the RendererClientBase is guaranteed to have only one instance per process, I think you can add a RendererClientBase::Get() method to return the global instance, like what we do in ElectronBrowserMainParts::Get.

Chromium also does a similar thing for ChromeExtensionsRendererClient, so this pattern should be fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great having some code I can reference makes this a lot easier. Will update the PR soon, thanks again!

@electron-cation electron-cation bot removed the new-pr 🌱 PR opened recently label Aug 21, 2020
@lishid
Copy link
Contributor Author
lishid commented Aug 28, 2020

@MarshallOfSound Quick ping on this. Can you please advise on how I can get a reference from:
RendererClientBase to the renderer API modules such as IPCRenderer?

This is blocking further progress on this PR. Thanks.

Copy link
Contributor Author
lishid commented Sep 10, 2020

Did a quick test and it seems to work pretty well.
I'll start working on tests and documentation if this looks all good 🎉

@lishid
Copy link
Contributor Author
lishid commented Sep 10, 2020

Also I can't seem to be able to view the lint results from CircleCI without "logging in with Github" and giving it read/write access to all my repos. The details link gives a 404 "You may have been logged out."

Curious if this is intentionally configured, and if there's an alternate way to check the result details.

@@ -672,6 +675,38 @@ blink::WebCacheResourceTypeStats GetResourceUsage(v8::Isolate* isolate) {
return stats;
}

bool SpellCheckWord(v8::Isolate* isolate,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you move this to anonymous namespace? i.e. where the GetRenderFrame are defined.

@zcbenz
Copy link
Contributor
zcbenz commented Sep 14, 2020

The lint error is:

$ node ./script/lint.js && npm run lint:clang-format && npm run lint:docs
--- a/shell/renderer/api/electron_api_web_frame.cc
+++ b/shell/renderer/api/electron_api_web_frame.cc
@@ -675,9 +675,9 @@
   return stats;
 }
 
-bool SpellCheckWord(v8::Isolate* isolate, 
+bool SpellCheckWord(v8::Isolate* isolate,
                     v8::Local<v8::Value> window,
-                    const std::string& word, 
+                    const std::string& word,
                     std::vector<base::string16>* optional_suggestions) {
   size_t start;
   size_t length;

It seems that you need to remove some trailing whitespaces.

I'm not sure why the lint CI result is not visible to you. /cc @jkleinsc

@zcbenz
Copy link
Contributor
zcbenz commented Sep 15, 2020

Current implementation looks good to me, and the API will be discussed at next wg-api's meeting.

Can you also add some documentation for the APIs?

@lishid
Copy link
Contributor Author
lishid commented Sep 15, 2020

Sounds good, will do.

@jkleinsc
Copy link
Member

@lishid @zcbenz I checked with CircleCI and in regards to viewing CircleCi results (eg lint results), you will need to login to CircleCI to see the details. You can see the overall status on GitHub, but viewing the details requires logging into CircleCI. You should be able to pick and choose what repos you give CircleCI access to.

@lishid
Copy link
Contributor Author
lishid commented Sep 15, 2020

@jkleinsc I see. It seems like the only choice given was "All repos" or "Public repos only"

image

Choosing "Public repos only" asks for read-write access to all public repos:

image

IIRC the problem is with Github's OAuth not having granular control over specific repos, but I guess in the meantime it shouldn't be much trouble registering a separate account if access control is an issue.

Copy link
Contributor
@nornagon nornagon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a test!

@lishid lishid requested a review from nornagon September 15, 2020 20:37
@lishid
Copy link
Contributor Author
lishid commented Sep 21, 2020

Test and docs have both been added. Excited to finally get native spellchecker support for our CodeMirror editor!
Let me know if this PR still needs any tweaking.

@jkleinsc
Copy link
Member

The API WG reviewed this on Sept 21, 2020.

@lishid
Copy link
Contributor Author
lishid commented Sep 28, 2020

Quick follow-up: is there anything still blocking this PR?

@nornagon nornagon changed the title [WIP] feat: Expose renderer spellcheck API feat: Expose renderer spellcheck API Sep 28, 2020
base::string16 w = base::UTF8ToUTF16(word);
int id = render_frame->GetRoutingID();
return client->GetSpellCheck()->SpellCheckWord(
w.c_str(), 0, word.size(), id, &start, &length, optional_suggestions);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hang on, I think we can just specify kNoTag for the tag? Which would mean we wouldn't need to fetch the render frame, which makes me think maybe this API shouldn't be on webFrame at all?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm... https://source.chromium.org/chromium/chromium/src/+/master:components/spellcheck/renderer/spellcheck_provider.cc;l=310;drc=c83ae1d48c762639e626be9be0c77a209fdea359 is a reference that uses the routing id. there are other places in the code that use kNoTag. cc @MarshallOfSound for further review

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor
@nornagon nornagon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

switching my review back to approved because i'm satisfied that the routing id is probably the right thing to be passing here.

@lishid
Copy link
Contributor Author
lishid commented Oct 5, 2020

Quick follow-up: is there anything still blocking this PR? Seems like it's ready to merge.

@lishid
Copy link
Contributor Author
lishid commented Oct 16, 2020

I did a rebase which seemed to have fixed the specific build issue with mac, but latest master has some other build failures :(

Anything else I need to do before a merge can happen? 🚀

@zcbenz
Copy link
Contributor
zcbenz commented Oct 16, 2020

The CI is failing on master branch, we need to fix it first. #25992

@zcbenz zcbenz merged commit 05b5c19 into electron:master Oct 19, 2020
@welcome
Copy link
welcome bot commented Oct 19, 2020

Congrats on merging your first pull request! 🎉🎉🎉

@release-clerk
Copy link
release-clerk bot commented Oct 19, 2020

Release Notes Persisted

Added spellcheck API to renderer.

@craftzdog
Copy link

Congrats!!!!!

@lishid lishid deleted the renderer-spellcheck branch October 22, 2020 23:51
@lishid
Copy link
Contributor Author
lishid commented Oct 22, 2020

@zcbenz Thanks for the merge!
I'm not too familiar with how the Electron team's roadmap planning works, but I'm curious to know which release version of Electron would contain these changes?
It doesn't seem like it's being backported to v11 so I'm guessing we're aiming for v12?

Thanks again for all the help on this PR!

@zcbenz
Copy link
Contributor
zcbenz commented Oct 23, 2020

Yeah it will be included in v12, for backporting to v11 please check https://github.com/electron/governance/blob/master/wg-releases/feature-backport-requests.md.

@lishid
Copy link
Contributor Author
lishid commented Oct 23, 2020

Sounds good.

By requesting backport of a feature, the submitter of the PR is assuming responsibility for this feature on the requested branches.

I can take responsibility for this PR if that means we can backport it to v11. Given there's still over 3 weeks until v11 goes stable, let me know what I should do to initiate the backport request.

@zcbenz
Copy link
Contributor
zcbenz commented Oct 26, 2020

/trop run backport

@trop
Copy link
Contributor
trop bot commented Oct 26, 2020

The backport process for this PR has been manually initiated, here we go! :D

@trop
Copy link
Contributor
trop bot commented Oct 26, 2020

I was unable to backport this PR to "11-x-y" cleanly;
you will need to perform this backport manually.

@zcbenz
Copy link
Contributor
zcbenz commented Oct 26, 2020

I have added this PR to @electron/wg-releases 's meeting items, once it is approved you can start backporting it to 11-x.

@lishid
Copy link
Contributor Author
lishid commented Nov 12, 2020

Seems like we got less than a week to go before v11 hits stable so I'm guessing a backport isn't likely to happen, is that correct?

@jkleinsc
Copy link
Member

@lishid the @electron/wg-releases missed this one, but we will vote on it. It probably won't make 11.0.0, but if approved it could go in as a 11.1.0 release.

@RoboDave21
Copy link
RoboDave21 commented Feb 25, 2021

What's the current status of this request, when is it going to be implemented into Electron?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Expose spellcheck_platform::CheckSpelling API
9 participants
0