Paste document files in javascript - javascript

I'd like to paste file to server from client desktop using javascript.
So I added a listener on paste event:
document.addEventListener('paste', function(e) {
var files = {};
if(window.clipboardData){ // IE
files = window.clipboardData.files;
}
else {
files = e.clipboardData.files;
}
//...some functions using files
});
Event fires correctly but the problem is - e.clipboardData.files has always length of 0. I'm using ctrl+c on my desktop's .docx file. Am I missing something? My browsers are Firefox Quantum 57 and Google Chrome 60 on Ubuntu 16.04.

It is useful for users to be able to use clipboard keyboard shortcuts such as ctrl+c and ctrl+v. Chromium exposes read-only files on the clipboard as outlined below. This triggers when the user hits the operating system's default paste shortcut or when the user clicks Edit and then Paste in the browser's menu bar. No further plumbing code is needed.
document.addEventListener("paste", async e => {
e.preventDefault();
if (!e.clipboardData.files.length) {
return;
}
const file = e.clipboardData.files[0];
// Read the file's contents, assuming it's a text file.
// There is no way to write back to it.
console.log(await file.text());
});

Related

How to disable switching to explorer activity bar when call openTextDocument? VScode

I'm creating an extension for vscode. At some point I need to open a file. I use vscode.workspace.openTextDocument for that and it's working, but switchs activity bar from custom to Explorer. I want to leave my custom activity bar opened. How can I do that?
I have tried closing all activity bars except mine, searching for some settings(nothing found), tried to use vscode.commands.executeCommand with workbench.view, but there are only workbenck.view.explorer and workbench.view.extensions.
select(node: json.Node) {
var setting: vscode.Uri = vscode.Uri.parse('file:///home/user/some_file');
vscode.workspace.openTextDocument(setting).then((a: vscode.TextDocument) => {
vscode.window.showTextDocument(a, 1, false).then(e => {
// move to 96 line in the file. Just for example.
let range_n = e.document.lineAt(96).range;
e.selection = new vscode.Selection(range_n.start, range_n.end);
e.revealRange(range_n);
})
}, (error: any) => {
console.error(error);
debugger;
});
}
I expect that my custom activity bar and necessary file will be open after running select. Now file is opened, but activity bar is switched to explorer.
Have no idea, how exactly the problem was solved, but now it works as it should be.
I can assume, that the key here is another plugin (let's call it plugin_2, and main - plugin_1). I have another plugin (plugin_2), which runs when some file opens and draw some result into outline, so probably, when I relocate plugin_2 into my custom activity bar from explorer, and open a file with main plugin_1, plugin_2 ran and didn't let explorer open.
I believe that is the decision. Hope it will help someone.

Is it possible to avoid breaking on a debugger statement in Chrome?

I'm trying to reverse engineer a heavily obfuscated JS and one of the tricks the author does is to continuously call the debugger statement from within an anonymous function:
Unfortunately, I cannot right click and Never pause it, because each time the function is called a new anonymous function is spawned. The only way for me to inspect the code with DevTools open is to toggle the Disable all breakpoints button, but that disables my breakpoints too.
Is there any way to disable exclusively all debugger statements in Chrome?
In case there isnt, what could be done to bypass this anti-tampering trick?
Download the offending webworker.js file to your local drive, and use a text editor to replace all occurrences of "debugger" with ";".
Then use a Chrome extension to replace the remote resource with your local modified version.
https://chrome.google.com/webstore/detail/resource-override/pkoacgokdfckfpndoffpifphamojphii?hl=en
FYI: I do not endorse the above extension. It was just the first I found via Google.
This answer is for an old Chrome prior to 2021 where we could hack the internals of devtools itself by using devtools-on-devtools:
undock devtools into a separate window
press the full devtools hotkey - CtrlShifti or ⌘⌥i
paste the following code in this new devtools window console and run it
{
const rx = /\bdebugger\b/y;
const eventSymbol = SDK.DebuggerModel.Events.DebuggerPaused;
const original = [...SDK.targetManager._modelListeners.get(eventSymbol)]
.find(v => v.listener.name === '_debuggerPaused');
const debuggerModel = SDK.targetManager.models(SDK.DebuggerModel)[0];
SDK.targetManager.removeModelListener(
SDK.DebuggerModel,
eventSymbol,
original.listener,
original.thisObject);
SDK.targetManager.addModelListener(
SDK.DebuggerModel,
eventSymbol,
async function({data}) {
if (data._debuggerPausedDetails.reason === 'other') {
const frame = data._debuggerPausedDetails.callFrames[0];
const code = await frame._script.requestContent();
let {columnNumber: x, lineNumber: y} = frame._location;
let pos = 0;
while (y--)
pos = code.indexOf('\n', pos) + 1;
rx.lastIndex = Math.max(0, pos + x);
if (rx.test(code)) {
debuggerModel.resume();
return;
}
}
original.listener.apply(original.thisObject, arguments);
});
}
Notes:
You can save this code as a snippet in devtools to run it later.
To quickly switch docking mode in the main devtools press CtrlShiftD or ⌘⇧D
Theoretically, it's not that hard to put this code into resources.pak file in Chrome application directory. There are several tools to decompile/build that file so just add the code to any script that has something like SDK.DebuggerModel.Events.DebuggerPaused inside. One can even write a tool that does that automatically on Chrome update.
Right-click the in the gutter on the line with the debugger statement and select "Never pause here".

Problems in playing Fairplay Encrypted content on Safari browser

We are trying to write player in Javascript which should play fairplay encrypted content on safari browser. We figured 'encrypted' event is not supported on Safari browser and we added event listener for 'WebKitNeedKey' event. We coded the flow as below.
addEventListener('webkitneedkey, onWebKitNeedKey);
onWebKitNeedKey(evt) {
videoElement = document.getElementById('videoID');
if (videoElement.webkitKeys) {
videoElement.webkitSetMediaKeys(new WebKitMediaKeys('com.apple.fps.2_0'));
}
const session = videoElement.webkitKeys.createSession('video/mp4', event.initData);
session.addEventListener('webkitkeymessage', onWebKitKeyMessage);
session.addEventListener('webkitkeyerror', onWebKitKeyError);
session.addEventListener('webkitkeyadded', onWebKitKeyAdded);
}
onWebKitKeyMessage(evt) {
console.log(`received webkit key message : ${evt}`);
}
onWebKitKeyError(evt) {
console.log(`received webkit key error : ${evt}`);
}
onWebKitKeyAdded(evt) {
console.log(`received webkit key added : ${evt}`);
}
Now I am getting the webkitneedkey event and after setting the keys, I am getting webkitkeymessage event. I am planning to implement the logic of contacting the server for the license as per https://github.com/WebPlatformForEmbedded/WPEWebKit/blob/master/LayoutTests/http/tests/media/clearkey/clear-key-hls-aes128.html
I have following questions. Can any one please help me to resolve the below questions?
1) Do we need to set the source to '.m3u8'? Is it mandatory? I am getting the events even without setting the source to .m3u8
2) Is my approach correct in onWebKitNeedKey? Can I send evt.initData directly to webkitSetMediaKeys without modifying? Do I need to extract the content ID from evt.initData if I use key as 'com.apple.fps.2_0' instead of 'com.apple.fps.1_0'?

Checking if user has a certain extension installed

I just found out that the Screen Capture by Google extension makes my website's window.onresize event not fire.
I want to perform a javascript check to see if the user has ScreenCapture installed and if so, warn the user of the problem.
A year ago I think I heard of some javascript code that could do this, maybe using some google API, but I don't remember.
Any insight on this? I haven't developed any extensions so I don't really know how they work.
[EDIT]
So I have been asked to show some code. As seen in my previous question ( window.onresize not firing in Chrome but firing in Chrome Incognito ), the problem occurs on any window.onresize event function, so I don't think my code really matters.
Also, there is quite a lot of my code, I don't know how much of it to paste or if it would be helpful.
var debounce = function (func, threshold, execAsap)
{
var timeout;
return function debounced () {//alert("1.1 Y U NO WORK?");
var obj = this, args = arguments;
function delayed () {
if (!execAsap)
func.apply(obj, args);
timeout = null;
}
if (timeout)
clearTimeout(timeout);
else if (execAsap)
func.apply(obj, args);
timeout = setTimeout(delayed, threshold || 100);
};
};
window.onresize = debounce(function (e) { //alert("1.2 Y U NO WORK?");
flag = true;
var point = window.center({width:1,height:1});
doCenter(point);
// does something here, but only once after mouse cursor stops
}, 100, false);
I would like to stress that the problem is not due to the debounce. window.onresize = t; function t (e) { alert("wtf?");} won't work either.
[EDIT2]
Here's the result:
var screenCapture = null;
var screenCaptureImg = document.createElement("img");
screenCaptureImg.setAttribute("src", "chrome-extension://cpngackimfmofbokmjmljamhdncknpmg/images/arrow.png");
/*
* Add event listeners for both "load"- and "error"-event
* Set the variable showing the existence of the extension by
* setting it to "true" or "false" according to the fired event
*/
screenCaptureImg.addEventListener("load", doLoad, false);
function doLoad(e){
screenCapture = true; //removeImgTag(e);
alert("I've so cleverly detected that your Chrome has the ScreenCapture extension enabled. \n\nThis extension interferes with my website's DOM and long story short, it won't be able to scale properly.\n\nSo please disable it. \nConsider this extension: \"Disable All Extensions Plus\", it's a handy selective disabler.");
}
screenCaptureImg.addEventListener("error", function(e){
screenCapture = false; //removeImgTag(e);
}, false);
/*
function removeImgTag(e) {
e.currentTarget.parentNode.removeChild(e.currentTarget);
}
*/
Note that I couldn't get removeImgTag to work, because (at least in chrome), I don't seem to have access to the document object in order to create or remove elements from my page, from within these event functions. This is also why I'm displaying an alert instead of elegantly writing up a document.getElementById("something").innerHTML=...
To detect if an extension is installed in Chrome, you can check for a known resource included in the extension such as an image. Resources for the extension are referenced using the following URL pattern:
chrome-extension://<extensionID>/<pathToFile>
The basic detection technique involves creating a hidden image tag and attaching load and error events to it to see if the image loads (as described here for Firefox):
extensionImg.setAttribute("src", "chrome-extension://<INSERT EXTENSION ID HERE>/images/someImage.png"); // See below for discussion of how to find this
/*
* Add event listeners for both "load"- and "error"-event
* Set the variable showing the existence of the extension by
* setting it to "true" or "false" according to the fired event
*/
extensionImg.addEventListener("load", function(e) {
extensionExists = true;
removeImgTag(e);
}, false);
extensionImg.addEventListener("error", function(e) {
extensionExists = false;
removeImgTag(e);
}, false);
function removeImgTag(e) {
e.currentTarget.parentNode.removeChild(e.currentTarget);
}
Check the installation directory of the extension in the Chrome configuration to find a likely target for detection. On my Linux workstation extensions are located in:
~/.config/chromium/Default/Extensions
You can see that I have 3 extensions installed right now:
~/.config/chromium/Default/Extensions$ ls
cpecbmjeidppdiampimghndkikcmoadk nmpeeekfhbmikbdhlpjbfmnpgcbeggic
cpngackimfmofbokmjmljamhdncknpmg
The odd looking names are the unique IDs given to the extension when it is uploaded to the Chrome webstore. You can obtain the ID either from the webstore or by going to the Extensions tab (wrench -> Extensions) and hovering over the link to the extension in question, or "Screen Capture (by Google)" in this case (note the asterisked extension ID):
https://chrome.google.com/webstore/detail/**cpngackimfmofbokmjmljamhdncknpmg**
In the extension directory there will be one or more versions; you can ignore this. Within the version directory is the actual content of the extension:
~/.config/chromium/Default/Extensions/cpngackimfmofbokmjmljamhdncknpmg/5.0.3_0$ ls
account.js images page.js sina_microblog.js
ajax.js isLoad.js picasa.js site.js
background.html _locales plugin style.css
editor.js manifest.json popup.html ui.js
facebook.js notification.html sha1.js upload_ui.js
hotkey_storage.js oauth.js shortcut.js
hub.html options.html showimage.css
i18n_styles page_context.js showimage.html
In the case of the Screen Capture extension there are a number of images to use:
~/.config/chromium/Default/Extensions/cpngackimfmofbokmjmljamhdncknpmg/5.0.3_0/images$ ls
arrow.png icon_128.png icon_save.png print.png
copy.png icon_16.png line.png region.png
cross.png icon_19.png loading.gif screen.png
custom.png icon_32.png loading_icon.gif sina_icon.png
delete_account_icon.png icon_48.png mark.png toolbar_bg.png
down_arrow.png icon_close.png picasa_icon.png upload.png
facebook_icon.png icon_copy.png popup_bg.jpg whole.png
These can be referenced under this URL:
chrome-extension://cpngackimfmofbokmjmljamhdncknpmg/images/arrow.png
This technique obviously depends on the stability of the content of the extension. I recommend using an image that looks likely to remain through all versions.
As mentioned above, the same technique can be used to detect Firefox extensions. In this case the content URL looks like this:
chrome://<EXTENSION NAME>/content/<PATH TO RESOURCE>
On my Linux workstation Firefox extensions are located in:
~/.mozilla/firefox/<USER PROFILE ID>/extensions
Where <USER PROFILE ID> looks something like this: "h4aqaewq.default"
You can see that I have 2 extensions installed right now, one of which is a directory installation and the other of which is a XPI (pronounced "zippy") file:
~/.mozilla/firefox/h4aqaewq.default/extensions$ ls
{3e9a3920-1b27-11da-8cd6-0800200c9a66} staged
firebug#software.joehewitt.com.xpi
The "staged" directory is where Firefox keeps extensions that will be updated (I think). The GUID directory with the brackets is a directory-based extension installation, and the .xpi file is Firebug.
Note: XPI is going away (see the link above). It's basically a zip file that can be opened and inspected by anything that understands zip. I used Emacs.
Finding the extension ID in Firefox is a bit more involved. Go to "Tools -> Add-ons", click the Extensions tab, click the "More" link next to the extension description, then click the "reviews" link to go to the Firefox extension site and get the ID from the URL (note the asterisked extension ID):
https://addons.mozilla.org/en-US/firefox/addon/**firebug**/reviews/?src=api
There's probably an easier way to do this; suggestions welcome.
TODO: how to find a likely image in a Firefox extension.
As an extra note, in Chrome you can only communicate with an extension via the shared DOM of the page: Host page communication

How to detect Chrome extension uninstall

I am trying to detect whether my extension was uninstalled.
I can't use chrome.management.onUninstalled because it will be fired on other extension.
As of Chrome 41, you can now open a URL when the extension is uninstalled. That could contain an exit survey or track the uninstall event as some sort of analytics.
Google Chrome, unlike Firefox, doesn’t allow to detect when the user uninstalls the extension, which is quite useful to understand user behaviour.
There is a feature request on crbug.com with a discussion of this feature but it has not been implemented yet.
You can call chrome.runtime.setUninstallURL("www.example.com/survey") and redirect user to a url. Unfortunately, as soon as the extension is removed, the background script is removed too, and you can't do anything like log event or send hit to google analytics.
What I did is to set the redirect url to my server endpoint, and do some tasks like logging event to my own db, or sending hit to google analytics (ga hit builder). Then call res.status(301).redirect("www.example.com/survey") to some survey url. Finally I can send the uninstall event to google analysis.
If you're on Manifest V3, you can add it on your onInstalled Listener. If you want to capture uninstall for existing users as well, you need to add it to 'update' as well.
Place this code in your background page:
chrome.runtime.onInstalled.addListener(function (details) {
if (details.reason == 'install') {
... can add things like sending a user to a tutorial page on your website
chrome.runtime.setUninstallURL('https://www.yourwebsite.com/uninstall');
} else if (details.reason == 'update') {
... can add things like sending user to a update page on your website
chrome.runtime.setUninstallURL('https://www.yourwebsite.com/uninstall');
}
});
Find more information here: https://developer.chrome.com/docs/extensions/reference/runtime/#method-setUninstallURL
For mv3: An easy way would be to have
// Redirect users to a form when the extension is uninstalled.
const uninstallListener = (details) => {
if (details.reason === chrome.runtime.OnInstalledReason.INSTALL) {
chrome.runtime.setUninstallURL('https://forms.gle/...');
}
if (details.reason === chrome.runtime.OnInstalledReason.UPDATE) {
// TODO: show changelog
}
};
chrome.runtime.onInstalled.addListener(uninstallListener);
Place it in your background.
Content Script can Detect an Uninstall
Simply check the value of chrome.runtime, which becomes undefined when an extension is uninstalled.
A good trigger to check this is port disconnect:
// content_script.js
const port = chrome.runtime.connect();
port.onDisconnect.addListener(onPortDisconnect);
function onPortDisconnect() {
// After the extension is disabled/uninstalled, `chrome.runtime` may take
// a few milliseconds to get cleared, so use a delay before checking.
setTimeout(() => {
if (!chrome.runtime?.id) {
console.log('Extension disabled!');
}
}, 1000);
};

Categories

Resources