No more extra click to show stupid tweets!
< Feedback on Twitter Show Sensitive Content
I had no idea that the script stop working with Violentmonkey...
Note that adding inject-into
tag will not make it work magically;
I will see if I can fix it on content
mode, as page
seem to be broken on Firefox
Sorry for the huge delay of my response.
I managed to make a "working" script for Violentmonkey that works on content mode using the wrappedJSObject
and exportFunc
, BUT I stunned into other limitation of the extension/MOZ Extension API that, as far as I know, only affects XMLHttpRequest.prototype
(and most probably WebSockets). This "limitation" prevents modifying the response.
I cannot do anything for this, the only workaround is using other extension just to disable the Content Security Policy for Twitter.
There's no point in uploading that script version, as I does not work and Tampermonkey just disabled the compatibility support for wrappedJSObject
by default a few days before this message.
But for the record, I'll leave the userscript here:
//* eslint-env browser, es6, greasemonkey */
// ==UserScript==
// @name DEV: Twitter Show Sensitive Content
// @namespace kTu*Kzukf&5p#85%xas!fBH4#GT@FQ7@
// @version 0.3.5
// @description No more extra click to show stupid tweets!
// @author _SUDO
// @match *://*.twitter.com/*
// @icon https://www.google.com/s2/favicons?domain=twitter.com
// @license GPL
// @grant GM_xmlhttpRequest
// @run-at document-start
// @inject-into content
// ==/UserScript==
;(function () {
'use strict'
// See: https://github.com/violentmonkey/violentmonkey/issues/1028#issuecomment-681352072
// See: https://github.com/violentmonkey/violentmonkey/issues/1001
// See: https://stackoverflow.com/questions/9515704/access-variables-and-functions-defined-in-page-context-using-a-content-script/9517879#9517879
// See: https://github.com/ilinsky/xmlhttprequest/blob/master/XMLHttpRequest.js
// SEE: https://github.com/AlttiRi/gm_fetch/blob/57063c4dd79614a76ad6ca263c600c31fb9fca84/demo-dev.user.js#L409
var _window
try {
// This window refers to the "page window" on content mode or just "unsafeWindow"
const thisWindow = typeof unsafeWindow === 'object' ? unsafeWindow : window
_window = typeof thisWindow.wrappedJSObject === 'object' ? thisWindow.wrappedJSObject : thisWindow
} catch (err) {
console.error('[userscript] Error trying to get window object\n', err)
}
console.log('[userscript] Is running on content mode?', typeof _window.wrappedJSObject === 'object')
console.log('[userscript] Is exportFunction supported?',typeof exportFunction === 'function')
// Creates and caches a random string to replace later the possibly_sensitive object key
const ranString = (() => Array(5).fill().map(() => 'abcdefghijklmnopqrstuvwxyz'.charAt(Math.random() * 62)).join(''))()
// Content script wrapper for Violentmonkey
const exportFunc =/*GM_info.scriptHandler === 'Violentmonkey' && */ typeof exportFunction ==='function' ? exportFunction : (fn) => fn
// Save original prototype
const org_prototype = exportFunc(
_window.XMLHttpRequest.prototype.open,
_window
)
const intercept_pattern = /i\/api\/.+\/User|TweetDetail|Adaptive/gi // 179 steps, 0.01ms
const intercept_response = (response, responseURL) => {
console.log('[API] FOUND RESPONSE!\n', responseURL, response)
const new_response = response
.replace(/sensitive_media/gim, '')
.replace(/possibly_sensitive/gim, ranString)
.replace(/offensive_profile_content/gim, '')
return new_response
}
function open_proto() {
if (arguments['1'].match(intercept_pattern)) {
this.addEventListener('readystatechange', function (event) {
if (this.readyState === 4) {
const response = intercept_response(
event.target.responseText,
event.target.responseURL
)
Object.defineProperty(this, 'response', { writable: true })
Object.defineProperty(this, 'responseText', { writable: true })
this.response = this.responseText = response
}
})
}
// Slice an empty array to prevent errors when passing empty values
return org_prototype.apply(this, [].slice.call(arguments))
}
// Inject hijacked API
_window.XMLHttpRequest.prototype.open = exportFunc(open_proto, _window)
})()
>the only workaround is using other extension just to disable the Content Security Policy for Twitter.
What a bummer, only Tampermonkey addon can modify CSP policies. Thanks for your effort anyway.
[Violentmonkey] To bypass Firefox CSP, need to add additional metadata `inject-into` tag:
https://violentmonkey.github.io/posts/inject-into-context/
https://violentmonkey.github.io/api/metadata-block/#inject-into