Request to add GM_addElement API
In an page with CSP, if inline js and js url not in whitelist are both disabled, seems no API can be used to insert a script into page.
Tampermonkey add a new API GM_addElement to solve this problem. Will userscrips add this API in the future? Or is there any way to bypass the CSP.
I've not encountered any issues with adding HTML element to pages, so I am a bit curious what problems you are encountering.
Even if the page has a strict CSP, you should be able to add DOM elements. Below I linked a simple userscript for testing. If you visit a website with a strict CSP that disallows userscript injection in the page, like GitHub, you will see the DOM element is still created and appears on the screen. Also note, I am explicity setting @inject-into content to inject the script into the content script scope, but auto would work as well. The only time this would fail is if the user explicitly sets @inject-into page. If the user has @inject-into page even with a new GM_ API, it would not work since GM_ apis are not allowed to be injected into the page scope for security reasons.
I could be misunderstanding what your request is though. If you are simply wanting to know how to bypass a strict CSP on a page, there is no dynamic way with Safari. Tampermonkey, as far as I know, messing with the page headers to change the CSP to allow it's script to bypass it. This is not possible in Safari so we are stuck injecting into the content script scope when a strict CSP is present.
Without header modification it's difficult to bypass a strict CSP with the WebExtension API, however it is possible using web_accessible_resources, however this doesn't help us very much since we dynamic script sources.
Are you trying to inject into the page scope and not able to because of a strict CSP? Is it not possible to stay in the content script scope to accomplish the goal?
// ==UserScript==
// @name Add Dom Element
// @description This is your new file, start writing code
// @match *://*/*
// @run-at document-idle
// @inject-into content
// ==/UserScript==
const el = document.createElement("div");
el.id = "myNewElement";
el.style.background = "red";
el.style.height = "100px";
el.style.width = "100px";
el.style.position = "fixed";
el.style.top = "20px";
el.style.left = "20px";
el.style.zIndex = "999999";
document.body.append(el);
let script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'https://www.2gether.video/release/vt.user.js?timestamp=' + parseInt(Date.now() / 1000 / 3600);
document.getElementsByTagName('body')[0].appendChild(script);
Above code can not insert the js into github page successfully. But in TamperMonkey I can use GM_addElement to add the script.
It's also not possible for my script to run in content script scope only, both GM API and page injection are needed.
But in TamperMonkey I can use GM_addElement to add the script.
I mentioned this above, but for clarity sake, I believe that is because Tampermonkey rewrites header values to bypass the CSP.
Unfortunately this is not possible in Safari because it lacks the APIs necessary to do so. The WebExtension API implemented in Safari is incomplete, especially in regards to header manipulation.
Simply put, because of the incomplete API implementation in Safari, there's no real way to inject into the page context while bypassing page CSP and working with dynamic, user-generated, code.
This is an upstream/Safari issue.
Due to Apple's usual practice, they never seem to implement features such as modifying Headers. As @quoid said, we can't bypass CSP in Safari, it's an upstream issue that this extension can't fix at the moment. I will close this issue and we can reopen it once there are new changes.