Skip to content
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

When will json global variable be back #231

Open
kykungz opened this issue Dec 22, 2022 · 13 comments · May be fixed by #242
Open

When will json global variable be back #231

kykungz opened this issue Dec 22, 2022 · 13 comments · May be fixed by #242

Comments

@kykungz
Copy link

kykungz commented Dec 22, 2022

The README.md stated that:

  • Parsed JSON is exported as a global variable, json, so you can inspect it in the console Disabled for now, due to difficulties getting it working with Manifest v3 upgrade.

But is there an estimated date that it will be back?

@ChrisBAshton
Copy link

I've found a workaround for now - paste the following into your console:

json = JSON.parse(document.getElementById("jsonFormatterRaw").querySelector("pre").innerText)

@rishiraj88
Copy link

Thanks, @ChrisBAshton !

@c4ldas
Copy link

c4ldas commented Feb 22, 2023

The workaround provided by @ChrisBAshton works very well. I suggest the rep owner add this information on the README.md file as a suggestion while the global variation option is not available again. I'm glad I found this information here! :)

@callumlocke
Copy link
Owner

Thanks all, just added that workaround to the readme.

I'm not sure if it's possible to make it work again out of the box. I think the issue is there's now a stricter separation of contexts, so content scripts can't access the same window object as the page itself, i.e. can't create window.json. But maybe there's some trick to do it, so I'll leave this open a while in case anyone else wants to have a go at fixing it.

@jespertheend
Copy link

One potential way of doing this would be to add a setInterval with a debugger; statement.
That way DevTools switches to the context of the extension the moment it is opened:

setInterval(() => {
	debugger;
}, 500);

Downside of this is that the page is no longer interactive. But you could measure how long it takes to 'execute' the debugger statement using perfomance.now() and stop the interval the moment it takes more than a couple of milliseconds.
That way users only have to resume the debugger only once:

const interval = setInterval(() => {
  const then = performance.now()
  debugger
  if (performance.now() - then > 100) {
    clearInterval(interval)
  }
}, 500)

@jespertheend
Copy link

Alternatively it seems like chrome.scripting.executeScript() might make it possible to inject a static script included with the extension. But it requires a background script, so I didn't actually try this. I'm not sure whether injected scripts like these have access to the global scope of the page.

I did try the debugger statement though and that seems to work.

@jespertheend jespertheend linked a pull request Mar 6, 2023 that will close this issue
@lionel-rowe
Copy link

lionel-rowe commented Apr 25, 2023

I've found a workaround for now - paste the following into your console:

json = JSON.parse(document.getElementById("jsonFormatterRaw").querySelector("pre").innerText)

Tampermonkey version that will automatically run on any .json URL:

// ==UserScript==
// @name         JSON formatter `json` global
// @namespace    https://github.com/lionel-rowe/
// @version      0.1
// @description  try to take over the world!
// @author       https://github.com/lionel-rowe/
// @match        *://*/*.json
// @match        *://*/*.json?*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=json.org
// @grant        none
// ==/UserScript==

const el = document.querySelector('#jsonFormatterRaw pre');
if (el) window.json ??= JSON.parse(el.textContent);

@jespertheend
Copy link

How did tampermonkey manage to work around the manifest changes? Are they still using manifest v2?

@lionel-rowe
Copy link

How did tampermonkey manage to work around the manifest changes? Are they still using manifest v2?

Given Tampermonkey #644 [Chrome] Manifest V3: examine the effects is still open, I guess so. It looks like Google has delayed the retirement of v2, though it doesn't seem like there's currently a concrete updated timeline.

@kykungz
Copy link
Author

kykungz commented Apr 25, 2023

While we are stuck with the new Chrome manifest v3 limitation, perhaps we could push a quick and dirty solution to ease things a little, so that users won't need to manually copy-paste the script or create their own bookmarklet?

For example, adding a button that injects the JSON to window.json:
Screenshot 2566-04-25 at 19 38 23

@jespertheend
Copy link

@kykungz I don't think that would work. After all, if you can inject a button, why not just inject a <script> tag?

@kykungz
Copy link
Author

kykungz commented Apr 25, 2023

@kykungz I don't think that would work. After all, if you can inject a button, why not just inject a <script> tag?

Good point, I've never develop an extension before, so I'm not really sure how it works haha.

For what it's worth,

I tried attaching a click listener to a button, and yes, it does not work (window variable seems unaffected).

So I tried again by injecting the script right into the HTML attribute like this:

const buttonInject = document.createElement('button')
buttonInject.innerText = 'Inject window.json'
buttonInject.setAttribute('onclick', `window.json = ${JSON.stringify(parsedJsonValue)}`)
optionBar.appendChild(buttonInject)

and it seems to work.

Does this change anything? Or it will only work locally?

@DNin01
Copy link

DNin01 commented Jul 24, 2024

Content scripts can be injected in the main world by setting a manifest key.

 "content_scripts": [
   {
     "matches": ["<all_urls>"],
     "js": ["content.js"],
     "run_at": "document_end",
+    "world": "MAIN"
   }
 ],

This hasn't been supported from the beginning, but I haven't found a clear answer to what Chrome version added support for this. Chrome Developers says the ExecutionWorld object is in Chrome 95+, but MDN says 102+ and 111+ as a manifest key...?

It is possible for webpages to interfere with these scripts, so caution should be taken when running a script in the main world on untrusted websites.

Or, would a button to copy the JSON to the clipboard be a fine replacement? (related: #145)

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

Successfully merging a pull request may close this issue.

8 participants