Patterns and Practices for communication between Web Extensions and a web app - google-chrome-extension

I'm developing an extension and I'm a bit stuck about the communication between the web-app, the content-script of the extension, and the communication between the content-script and the background-script. It seems to be that HTML5 Messaging API is to be used, but how to do that in a precise context is not only hard to understand and implement, but also confusing due to differences of approach in Browsers (which seemingly support the same API).
For example, Firefox doesn't recognise the externally_connectable in manifest.json, which is where one assigns permissions for the hosts where requests originate from. So how does Firefox expect you the developer to assign the permissions? I assume it expects you do that within the content-script?
Particularly, I'm confused about what is the best way to exchange data between the app and the content/background script. Is the best way postMessage / addListener methods and do they work in all contexts; or as someone mentioned: window.dispatchEvent should be preferred?
All guides relevant to the point above are appreciated.

Messages coming from outside the extension is not something I have experience with (and I'm not sure that's what you mean).
You should make sure you thoroughly understand the chrome extensions overview which is definitely required reading.
re Window.dispatch and using other APIs, my suggestion is stick to the chrome.xxx APIs unless there's something they can't do.
There are 3 scopes potentially in your extension that can only communicate by messaging but the messaging is simple to implement and actually can lead to good designs.
Content scripts are the key to interacting with the page itself but their scope isn't the same as the page, the js is isolated but they can access the DOM of course.
Content scripts can be loaded when every page loads or just some pages by including them in the manifest. Or powerfully, they can be injected by the background page or the popup - so if you're intention is to control from the popup, you can use programmatic injection - a useful pattern is that the popup (or background) can launch a url in a tab, inject jquery (any version because it's isolated), then inject the content script, the content script can then use $(document).ready() to wait for the page to be loaded (don't have to use jQuery but the fact that you can without caring whether the page has jQuery or not, or what version it might have) is useful.
If you already knew this much, you might not be as confused as you think :)

Related

Microfrontend or how to share smart UI components?

I work in a company where we have many different applications. To reduce code repetition and keep the experience for the users the same across applications we created a component library which is used by all applications.
Now we want to allow the users to switch between applications. Something similar like Google does:
Screenshot of Google Application Drawer
An additional requirement for our "Application Switcher" would be that it "updates" itself. Meaning if we change how this "Application Switcher" looks we don't want all applications which use this Switcher to create a new deployment and be newly deployed.
So currently we use the same header (from our component library) in all our applications. So, my idea was just to simply add a script tag to all the index.html pages of all the applications which should support this "Application Switcher". The Script would parse the DOM, find the header and inject a component for this application switcher. I wanted to host the actual script from a CDN like server and the script tag in the index.html just references this URL. This way we could change this script however we want, and all the applications will always get the latest version.
Now I did a small proof of concept in our environments and solved all the CORS issues but since we were fetching from an authenticated context and the script was also in an authenticated context I always got a 401.
Additionally, we have the requirement, that this "Application Switcher" shows different applications to different users i.e. depending on which apps a user is allowed to access. So, the script itself will also do calls to an "Application Switcher" backend providing it user-specific information.
Now this makes me think that my initial idea of just putting a script tag and fetching from a CDN was too simplistic. Now I'm thinking if it would be better to implement a rest endpoint in all applications to fetch this script. This way I don't have the problems of fetching a resource from an authenticated context from the user's browser and instead can handle all of this in the backend.
So long story short; I feel like a complete noob who just hacks around to get things working (or actually not working) and was wondering if any of the smart internet people out there (who might actually already have experience with this) could give me a hint what would be a clean way to implement this?

Does Chrome Market accept extensions with minified and/or obfuscated source code?

I'm currently developing a Chrome extension and planning to publish it on Chrome market. I'm aware of open-source community benefits, however, do not want to share the source code and a bit worried about copyrights. Currently, the plan is to minify and obfuscate the source code before publishing. So the questions is:
Does Chrome Market accept extensions with minified and/or obfuscated source code?
Thanks in advance! :)
Any existing answers above have been rendered obsolete by the terms change on January 1st, 2019. This change was announced on October 1st, 2018.
In summary:
Google Allows minified code.
Google disallows obfuscated code.
The specific policy, available at https://developer.chrome.com/webstore/program_policies, is as follows:
Developers must not obfuscate code or conceal functionality of their
extension. This also applies to any external code or resource fetched
by the extension package. Minification is allowed, including the
following forms:
Removal of whitespace, newlines, code comments, and block delimiters
Shortening of variable and function names
Collapsing files together
2019 Update:
Google allows minified code, but not obfuscated one. See Brian's answer
Original answer:
Yes, you can use obfuscation tools (like jscrambler) before publishing your extension. I don't know if that may delay the publishing time, but I know for sure that are some published Chrome extensions with obfuscated/minified source code.
I, for instance, minify the code of my extension (LBTimer) with Google's Closure before publishing it.
It looks like they don't approve minified and obfuscated code. You can check thread on the Chromium Google Group, from April '16.
https://groups.google.com/a/chromium.org/forum/#!topic/chromium-extensions/1Jsoo9BPWuM
No, you cann't. This is email I received from Google Chrome Team: All
of the files and code are included in the item’s package.
All code inside the package is human readable (no obfuscated or minified code).
Avoid requesting or executing remotely hosted code (including by referencing remote javascript files or executing code obtained by XHR requests).
You can get a more specific answer if you contact the Google Chrome team.
Update with own experience:
I wasn't able to submit a build obfuscated with this javascript-obfuscator (more specifically, gulp version in my case) They were complaining about "your code is suspicious" so I guess something triggered an alert in their system.
However uglyfy worked for that - I still had to figure out a way to rename all the prototype functions as uglify doesn't seem to do that (or at least I wasn't able to find a way to do that)
Original answer:
To sum up, it seems like chrome extensions are allowed to be minified and obfuscated.
For more details, keep reading.
First of all, there are two different terms - chrome extension and chrome app and different rules applies based on that. Chrome app has more strict requirements and it seems like mcastilloy2k's answer is suitable for chrome app (at least it looks like it is based on the available policies for both).
And regarding the below google's answer:
Avoid requesting or executing remotely hosted code (including by
referencing remote javascript files or executing code obtained by XHR
requests).
If it's for chrome extension and not for chrome app that seems strange as per the extension FAQ from google which explicitly states that extension is allowed to make external requests to execute custom API aka 'remotely hosted code':
Capabilities
Can extensions make cross-domain Ajax requests?
Yes. Extensions can make cross-domain requests. See this page for more
information.
Can extensions use 3rd party web services?
Yes. Extensions are capable of making cross-domain Ajax requests, so
they can call remote APIs directly. APIs that provide data in JSON
format are particularly easy to use.
Can extensions use OAuth?
Yes, there are extensions that use OAuth to access remote data APIs.
Most developers find it convenient to use a JavaScript OAuth library
in order to simplify the process of signing OAuth requests.
Another discussion in this google groups thread shows that rejection might not be connected with obfuscation at all:
Eventually, these are the things I needed to do to get my extension
passed (but I keep my fingers crossed in case some other validation
test still has to be performed):
I created a privacy policy and added a link to it on the Google Chrome developer dashboard.
I explained in more detail what my extension is doing. It seems that Google needs this to have a better understanding of the extension.
In the description I explicitly stated how the extension handles personal or sensitive user data.
Eventually that was enough to get the extension
pass the checks even with minified & obfuscated code (but remember I
keep my fingers crossed).
Moreover one can always go and check existing extensions out there, like Grammarly for example, who has obfuscated code (to some extent at least) and who uses external API.

Apps Script vs Chrome Extension: Writing an alternative spellchecker to Google Docs

Say, I want to develop an alternative spellcheck module to google docs.
This means that I have to get corrections from my backend, and color the misspelled text's background, and do a small popup bubble when user hovers over it, where I'd display the correction. (please mind that spellcheck is not the actual goal of my project, but it does address my problems in a more simplified way)
What are my options? Any ideas how to do this?
Few possible solutions I came up with:
Chrome extension vs Apps script
Chrome extension
pros: user has to grant permissions once, can freely traverse and append anything to dom via content script
cons: is a "hacky" way, if google changes classnames or js source, it would stop working, and also, reverse engineering google docs's editor engine is impossible
Apps script
pros: supported by google: if it works, I dont need to be afraid of docs updates
cons: it seems to me that I can't just fiddle with the dom (because of Caja compiler), has very limited support (if any) for custom highlighting or hover functionality.
As I see it, neither of these are perfect solutions for this project. What do you think? Any suggestions are very welcomed.
I know this is an old question, but I have recently gotten into the same problem, and believe I have a solution. So for future Googler's I will post my answer here.
My solution was to create a Chrome Extension and understand how the Google Docs DOM's are structures to interact with it.
You can find my code to work with the Google Doc DOM's here
In Apps Script you can't "fiddle" with the DOM and you won't be able to implement hover functionality. Also, a lame Highlighting would involve changing the current document itself (which would go to revision history, undo queue, etc)
Therefore, your only altertive is the Chrome Extension. But I agree with you on the cons. It is a super hard task that could break at any minute without notice.

Browser Extension the "Injected way" a cross-browser extension that include a JS from a distant server

I've found this nice article about the "injected Way", but the author never finished it :
http://hightechstartups.blogspot.ch/2012/05/different-way-of-developing-browser.html
I would like a bare bone cross browser extension, without any 3rd party extensions or framework (to be as light as possible and not dependant on a 3rd party) that would load Jquery and a JS from a distant server and the ability to load it before or after the page is fully loaded.
I've read a lot of topics about the subject, but since IE10, Chrome 26 and FF20 are out with their new cross-link limitations, i was wondering if somebody had ressources, source code or tutorial about the following requirements :
I need :
Cross browser extension supporting (IE 8+ or 9+ worse case, Chrome
26+, FF20+, Safari)
Ability to inject a single JS hosted on another server. Inserts a script tag that references a javascript file in the head of the HTML
page and then be executed
Not be dependant on a third party extension (greasmonkey) or framework (Kango, Crossrider)
Ability to load before or after the page is fully loaded
This method allows me to customise the browser extension depending on the user's location and it also avoid having updates as the JS is updated on each page refresh.
I'm aware of the downsides, but i would like to achieve this.
I'm aware of cross browser framework like Kango or crossrider, but both don't fit me needs.
The closest example i could find is this How can I run a <script> tag that I just inserted dynamically from a BHO
but it only covers IE and as i got very little Csharp experience, i would like to see a full example to understand it properly and learn from example.
I would LOVE to have a few examples, even if it's not cross-browser (IE being the worst part for me).
Thanks a lot for your support !
Update1:
About Kango and Crossrider, Kango is 2000$ if you want to use IE and for Crossrider you're required to be distributed and monetized by them.
I've managed to code for IE and Chrome, but i was looking for an "elegant" way and figured it was the best place to ask given the level of knowledge of people on this site.
For the installer i currently use NSIS, but i'll test Wix too.
Finally i guess the only way for me would be to learn C++ and .net to get it to work with IE, but if anyone could provide more source code it would be great to test speed and compatibility and discuss here what's the best solution.
Why do Kango or Crossrider not fit your needs? Both frameworks allow you to manipulate the page's DOM (which is what you want):
Kango: Adding content script
Crossrider: documentation, example code
If you want to code your own solution, take a look at the relevant documentation:
Content scripts (Chrome)
The Page mod Jetpack API (Firefox)
Injected scrips (Safari)
Injected scripts (Opera)
Internet Explorer does not natively support extensions. It took me about 80 hours to create a stable and reliable IE extension which supports cross-site AJAX, a (preference) storage method and injection of scripts as early as possible in any frames based on its URL. I developed and tested the extension with Visual Express 2010 on Windows XP and Windows 7, for IE 8-10 (the extension might work on IE6/7, but I decided to not support these ancient and rarely used browsers).
First, I wrote an extension in C# based on LiveReloadIEExtension (a sample IE extension, which in turn is based on this Stack Overflow answer - see also this blog post). It was functional, but it required .NET 4, lacked support of frames, and it's relatively slow.
So, I decided to write an IE extension from scratch in C++. A good starting point is available at http://www.wischik.com/lu/programmer/bho.html: Sample code for C++ BHO, which changes the document's background based on key/mouse events. I've also learned a lot by looking at other code samples on CodeProject, topics on the MSDN forums, questions and answers on Stack Overflow, lots of other blogs, and the MSDN documentation:
DWebBrowserEvents2 interface lists several events which you use to find an appropriate injection point.
Scripting Object Interfaces (MSHTML) lists even more interfaces. You'll be mainly interested in the iHTMLDocument, iHTMLDocument2, ... interfaces.
After creating the IE extension, you want to deploy it of course. I used Wix toolset to create a MSI.

what language should be used to make a website which will combine or work with the browser?

what language should be used to make a website or a webpage which will combine with the browser or the add-ons installed in the browser or the website can even takeover control of the browser ? Is there any language ?
I do not see the language as a factor in your question. Browsers use well-defined interfaces. Software that interacts with a browser can be written in any language as long as it supports those interfaces.
Beyond that, you would need to better define what is meant by "combine with the browser". Having websites "takeover control" of the browser is a dangerous thing and, in general terms, is not allowed.
However, there are plug ins that can be downloaded and installed and will work with the browser. Again, you need to be much more specific about the task you are talking about.
Without more information its tough to answer this.
For code that runs on the browser look at javascript or better yet JQuery which allows a lot more functionality and handles a lot of the cross browser problems for you.
If you're looking to get further integration going then you're going to have to take a different route for each browser. Firefox allows you to develop add-ons to add functionality to the browser, as does chrome. For IE you'll have to look at ActiveX
However for anything more than simple javascript you're going to have to get your users to allow your site to install whatever addons you use. Most users, myself included, wouldn't allow your site to install additional content on their browsers unless they really trusted the site and there was a strong functional incentive to use the code.

Resources