Modify Angular menu-bar from Chrome Extension content-script - javascript

I have been working on an extension (google chrome only for now) that is supposed to add features to my school's online learning environment. This website (not actually run by the school itself) uses Angular for the front-end.
For the extension I am using Typescript, with Parcel. The scripts that are running on the webpages are content-scripts.
I am trying to add an item to the menu-bar that is on the left. This is what I've tried:
Inserting pure HTML into the ul element, but this breaks the entire menu-bar and the user is unable to use it after.
Use Angular (installed via NPM) in the content-script to find the scope of the menu-bar element, then add the new option (Menu-bar is an array) and then apply it. Although this also seems to not work, like so:
Expected behaviour (using browser console)
let target = document.getElementsByClassName("main-menu")[0];
let menu = angular.element(target);
console.log(menu);
>>> p.fn.init [ul.main-menu, context: ul.main-menu]
Received Behaviour (from content-script)
let target = document.getElementsByClassName("main-menu")[0];
let menu = angular.element(target);
console.log(menu);
>>> p.fn.init [ul.main-menu]
The absence of the context makes me think that my content-script and the webpage's script are not running in the same scope. Is that correct? I am not able to use the .scope() method in the content-script either.
This is my manifest.json for the plugin. Please let me know
{
"name": "Magister Plus",
"description": "TBD",
"version": "0.0.1",
"manifest_version": 3,
"permissions": [
"activeTab",
"scripting",
"tabs"
],
"background": {
"service_worker": "./background/background.js"
},
"host_permissions": [
"https://*.magister.net/*"
],
"content_scripts": [
{
"matches": ["https://*.magister.net/*"],
"js": ["./content/domain.js"]
},
{
"matches": ["https://*.magister.net/magister/#/vandaag"],
"js": ["./content/vandaag.js"]
}
],
"action": {}
}
I am not really sure what to do here anymore, since I am not really familiar with Angular.js at all.
Thanks for any help!

To change html you need to use appendChild or insertAdjacentHTML, but not innerHTML. 2) To access context property you need to run that part of code in page context.
By #wOxxOm
This worked indeed! Thank you so much!

Related

How can I use multiple preload scripts for different Electron windows when using electron forge with the webpack template?

I use the typescript+webpack template from electron forge.
For loading a single preload script with webpack, there is a constant called MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY that can be set from the package.json, for example like so: "preload": { "js": "myPreload.ts" }. This constant is then somehow resolved from within the Electron Forge - Webpack Plugin depending on whether the application is run in debug or release mode.
I have this set up, and it works fine if you have single or multiple windows that share the same preload.ts script. However, I can not figure out how I could specify multiple different preload scripts for other windows.
How can I use multiple different preload.ts scripts (for different windows) with the electron forge webpack plugin?
Actually it is pretty simple to add multiple scripts, but as I have not seen this documented anywhere I will answer my own question here. The name field of the config is important, because the name in uppercase will be the prefix of the webpack constant, (e.g. "name": "my_name" will lead to the constant beeing called MY_NAME_PRELOAD_WEBPACK_ENTRY.
If you now want to add multiple preload scripts you will have to add multiple entry points to which you can then refer by their names. Unfortunately each entry point also requires the html and js fields, but if you do not need those you can create empty files with the correct extension and point to these).
Here is an example to better illustrate these points:
"config": {
"forge": {
"plugins": [
{
"name": "#electron-forge/plugin-webpack",
"config": {
"mainConfig": "./webpack.main.config.js",
"renderer": {
"config": "./webpack.renderer.config.js",
"entryPoints": [
{
"name": "main_window",
"html": "./src/main_window/index.html",
"js": "./src/main_window/index.js",
"preload": {
"js": "./src/main_window/preload.js"
}
},
{
"name": "extra_preload_main_window",
"html": "./src/empty.html",
"js": "./src/empty.js",
"preload": {
"js": "./src/main_window/preload2.js"
}
},
{
"name": "second_window",
"html": "./src/second_window/index.html",
"js": "./src/second_window/index.js",
"preload": {
"js": "./src/second_window/preload.js"
}
}
]
}
}
}
]
}
}
Which will then give you these (relevant) constants:
// Path to renderer of main window.
declare MAIN_WINDOW_WEBPACK_ENTRY;
// Path to first preload script (of main window).
declare MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY;
// Path to the second preload script (of the main window).
declare EXTRA_PRELOAD_MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY;
// Preload and renderer scripts for other window.
declare SECOND_WINDOW_WEBPACK_ENTRY;
declare SECOND_WINDOW_PRELOAD_WEBPACK_ENTRY;
Technically you will of course also get
declare EXTRA_PRELOAD_MAIN_WINDOW_WEBPACK_ENTRY;
but it points to an empty file / webpack output.

Firefox add-on not working if the main js file imports stuff from other js files

My firefox add-on currently has the main file organizer.js and just does not run when I import stuff from other js files (footer.js and header.js).
manifest.json
{
"manifest_version": 2,
"name": "Course Organizer",
"version": "1.0",
"description": "Keep the hassles that come with UI of class schedule at bay and make your course selection process smooth and seamless",
"icons": {
"48": "icons/border-48.png"
},
"content_scripts": [
{
"matches": ["*://*.my.wasabi.edu/e/reg/soc-view/results.asp*"],
"js": ["organizer.js", "footer.js", "header.js"],
"css": ["index.css"]
}
]
}
organizer.js (the relevant part)
import hello from 'footer'
import head from 'header'
console.log(hello + head)
footer.js
let hello = 'haha'
export {hello}
header.js
let head = 'head'
export {head}
I did some research and found out the js files are loaded in the specified order in the array, so I messed around with it but to no avail. Whenever I comment out the imports, it runs again.
I got it work the way I want now and figured out it is prohibited to use import/export in JS files in an extension. If you are trying to divide a big chunk of code in one file into many files, go ahead and cut/paste them to as many new files as you like. Be aware of the order of the files in "content-scripts" as they will be loaded to web in that order and you do not want to refer to an element that does not exist in DOM yet because it is created in next files.

Read an element within an iframe

I'm building an Edge extension. I'm trying to get the exact same element as this question asks, but I want to use JS, not Selenium.
Element
I'm running the JS through my extension's background script. In the future, I would like the popup to have a button and that button to read the syllable on screen.
The provided solution is in Selenium and I'd like to transpile it into JS.
driver.switch_to_frame(driver.find_element_by_xpath("//div[#class='game']/iframe[contains(#src,'jklm.fun')]"))
If none of this works, I guess I'll have to use optical text recognition.
Here's manifest.json
{
"name": "myName",
"description": "myDescription",
"version": "1.0.0",
"manifest_version": 3,
"icons": {
"128": "myIcon.png"
},
"content_scripts": [
{
"matches": [
"https://jklm.fun/*"
],
"js": [
"js/myScript.js"
]
}
]
}
Inside js folder, here's myScript.js
console.log('myscript is running')
const syllableHandler = () => {
const iframe = document.getElementsByTagName("iframe")
console.log(iframe?.[0]?.contentWindow)
}
document.addEventListener('keydown', syllableHandler)

How do you change the popup file with manifest 3? [duplicate]

I'm writing a Chrome extension that will redirect me to a URL when clicking on the browser action icon.
I'm trying to use:
chrome.browserAction.onClicked.addListener
but I get
Uncaught TypeError: Cannot read property 'onClicked' of undefined
This is my manifest file:
{
"name": "first extension",
"version": "2.2.12",
"description": "redirct to a link icon",
"browser_action": {
"default_icon": "icontest.png",
"default_title": "Do action"
},
"permissions": ["tabs", "http://*/*"],
"content_scripts": [{
"matches": ["http://*.twitter.com/*", "https://*.twitter.com/*"],
"js": ["twterland.js"]
}],
"icons": {
"16": "icontest.png",
"48": "icontest.png",
"128": "icontest.png"
}
}
This is my js file:
chrome.browserAction.onClicked.addListener(function(tab) { alert("hi"); });
ManifestV3
manifest.json: use action not browser_action, see also the migration guide.
"action": {},
"background": {"service_worker": "background.js"},
background.js: use chrome.action not chrome.browserAction.
Classic ManifestV2
For those who already have added something like
"background": {
"scripts": ["background.js"]
}
and still gets Cannot read property 'onClicked' of undefined - just add
"browser_action": {}
into your manifest.json
It seems like the code is in your twterland.js file, which is your content script. browserAction can only be used in extension pages, so you can not use it in content scripts.
Document: https://developer.chrome.com/extensions/content_scripts
However, content scripts have some limitations. They cannot:
- Use chrome.* APIs (except for parts of chrome.extension)
- Use variables or functions defined by their extension's pages
- Use variables or functions defined by web pages or by other content scripts
Put it on the background page instead.
If you do not have a "browser_action" property defined in your manifest.json then this error may occur. #Kirill's answer works but you also have to add a blank icon.png file else chrome will throw an error that it cannot find such a file.
Adding this to the manifest.json file should suppress this is error:
"browser_action": {}
Be sure to read the documentation for further reference on how to use the "browser_action" setting.
The same problem may appear if you are using manifest_version 3.
In this case
"background.scripts" should be replaced with "background.service_worker"
"browser_action" should be replaced with "action"
in js code chrome.browserAction should be replaced with chrome.action
detailed information could be found here: Manifest version 3 migration documentation
I was also getting this, adding
"persistent": true
to my background declaration in manifest.json solved it.
Please notice that you can heave only one of app, browser_action, page_actions present in your manifest‎.json file.
For example, to use the chrome.browserAction.setBadgeText you should have the browser_action field in your manifest‎.json.
Make sure we don't have jquery.js before background.js in the scripts array of background in manifest.json.
"background": {
"scripts": ["background.js","jquery.js"]
}

Unload not available in sandboxed Chrome App

I'm using Dijit (Dojo Toolkit) to generate a HTML layout in a sandboxed page, but everytime I make a call for the dijit files, I get Uncaught unload is not available in packaged apps..
Now I'm not sure this is a problem with Dojo or just a limitation of Chrome with the new security policies.
My files:
/** manifest.json **/
{
"name": "Hello App",
"version": "2.0",
"manifest_version": 2,
"description": "A app that says hello",
"app": {
"background": {
"scripts" : ["js/app.js"]
}
},
"permissions": [
],
"sandbox": {
"pages" : ["live.html"]
}
}
/** js/app.js **/
chrome.app.runtime.onLaunched.addListener(function(){
chrome.app.window.create('live.html', {width:screen.width,
height: screen.height});
});
/** js/helloapp/app.js **/
/** This is the file that actually calls Dijit to build the layout **/
define(function(){
require(["dijit/layout/ContentPane",
"dijit/layout/BorderContainer"]);
});
I've left live.html out because it's basically just the HTML structure, a call to the dojo loader and a require for the helloapp/app.js file.
If this is a limitation in the CSP world, is there another way I can use Dijit on the new Chrome Apps or am I missing something?
Thanks for your time
You would have to mod the all the core source code in Dojo Core, Dojo Base and Dijit to remove the unload event or redefine it.
close() and unload() are very similar and you can see a thread on why it isn't implemented here:
http://code.google.com/p/chromium/issues/detail?id=147674
http://code.google.com/p/chromium/issues/detail?id=130465

Categories

Resources