I'm trying to do a shortcut with autohotkey (I am a noob with it) to go to chrome://settings/password/ when i'm on chrome.
The Run command works only for the URL, something like:
Run, http://stackoverflow.com
So I tried this script, but it's rough to me:
;myScript:
#IfWinActive, ahk_class Chrome_WidgetWin_1
^q::Send, ^t chrome://settings/passwords/ {enter}
#IfWinActive
There are some ways to do it better?
Try it step by step:
;myScript:
#IfWinActive, ahk_class Chrome_WidgetWin_1
^q::
Send, ^t
Sleep 500
; replace "title" with the exact title of the new window (tab)
; WinWait, title
; IfWinNotActive, title, ,WinActivate, title
; WinWaitActive, title
SendInput, chrome://settings/ ; SendInput is faster in sending text
Sleep 500
Send, {enter}
Sleep 500
; replace "title" with the exact title of the new window (tab)
; WinWait, title
; IfWinNotActive, title, ,WinActivate, title
; WinWaitActive, title
Send, {Tab 2}
Sleep 500
Send, {enter}
return
#IfWinActive
I usually incorporate a few loops to account for delays across old hardware, and just break out when the conditions are met.
You can trigger the Passwords box in Chrome with the below, currently bound to F4.
F4::
{
WinActivate, ahk_class Chrome_WidgetWin_1
Loop {
IfWinActive, ahk_class Chrome_WidgetWin_1
{
break
}
}
Send, ^t
Loop {
IfWinActive, New Tab - Google Chrome
{
break
}
}
Send, chrome://settings/passwords{enter}
}
return
Related
I am experimenting with an idea to stream dynamic data from a web server into a file on the client device. To implement this idea, I am making use of the HTTP Content-Disposition response header and the HTML download attribute. The following is my sample code, where the server is implemented in Go:
HTML:
<a href="download" download>Download</a>
Server:
package main
import (
"fmt"
"net/http"
"time"
)
func main() {
// Handle download request.
http.HandleFunc("/download", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Disposition", "attachment; filename=\"log.txt\"")
w.Write([]byte("first message\n"))
time.Sleep(10 * time.Second)
// The following for-loop takes about 30 seconds to run on my dev machine.
for i := 0; i < 1000000; i++ {
timestamp := time.Now().Unix()
log(timestamp)
w.Write([]byte(fmt.Sprintf("%v\n", timestamp)))
time.Sleep(time.Microsecond)
}
log("done")
})
// Start HTTP server.
if err := http.ListenAndServe(":8080", nil); err != nil {
log(err)
}
}
func log(v ...interface{}) {
fmt.Println(v...)
}
This sample code works in that it successfully downloads all the content from the download handler when clicking on the "Download" link. However, I am observing the following behavior that I am unable to explain:
I have my browser configured to always ask where to save the downloaded files. When running the sample code above, Chrome opens the Save As window only after the 10 second sleep but before the for-loop is complete and in turn the handler function has returned. Why did Chrome not present the Save As window when the "first message" was sent before the 10 second sleep? What is different between the "first message" and the messages being sent in the for-loop that causes the Save As window to only open when the for-loop starts?
Aside: If FileSystemWritableFileStream had greater cross-browser support, I'd use that to stream dynamic server data directly into a file on the client side.
Go's http.ResponseWriter has a default 4KB buffer, defined at the Transport level:
type Transport struct {
// ...
// WriteBufferSize specifies the size of the write buffer used
// when writing to the transport.
// If zero, a default (currently 4KB) is used.
WriteBufferSize int
// ...
}
In some instances, when using standard responses, you can make use the Flush method by using type assertion with the http.Flusher interface to send the bytes right away:
if f, ok := w.(http.Flusher); ok {
f.Flush()
}
To have Firefox open the Save As window immediately after "first message" is sent, Ricardo Souza's answer appears to be all that's needed. To have Chrome do the same, the response's Content-Type header also needs to be set to anything other than the default text/plain (thanks to this SO answer). Example:
w.Header().Set("Content-Type", "application/octet-stream; charset=utf-8")
I'm trying to toggle to my new gmail message box but if it doesn't exist i would like my script to open gmail and open a new email (Compose new message).
Here's my existing script (previously provided by user285594)
^+m::
SetTitleMatchMode, 2
WinTitleC :="Compose Mail - "
IfWinExist, %WinTitleC%
{
WinActivate
return
}else{
SetTitleMatchMode, 2
IfWinExist, Chrome
WinActivate ;
WinWait, Chrome ;
sleep, 100 ;
chrome := "- Google Chrome"
found := "false"
tabSearch := "gmail"
curWinNum := 0
WinGet, numOfChrome, Count, %chrome% ; Get the number of chrome windows
WinActivateBottom, %chrome% ; Activate the least recent window
WinWaitActive %chrome% ; Wait until the window is active
ControlFocus, Chrome_RenderWidgetHostHWND1 ; Set the focus to tab control ???
while (curWinNum < numOfChrome and found = "false") {
WinGetTitle, firstTabTitle, A ; The initial tab title
title := firstTabTitle
Loop {
if(InStr(title, tabSearch)>0){
found := "true"
break
}
Send {Ctrl down}{Tab}{Ctrl up}
Sleep, 50
WinGetTitle, title, A ;get active window title
if(title = firstTabTitle){
break
}
}
WinActivateBottom, %chrome%
curWinNum := curWinNum + 1
}
ControlSend, , {Shift Down}c{Shift Up}, Google Chrome
winmove, Compose,, 1750, 303, 1725, 935 ; moving the window to my preferred position
if(found = "false"){
run C:\Program Files (x86)\Google\Chrome\Application\chrome.exe https://mail.google.com/mail/u/0/?ogbl#inbox
WinWait, Inbox
ControlSend, , {Shift Down}c , Google Chrome
winmove, Compose,, 1750, 303, 1725, 935; moving the window to my preferred position
}
}
return
It works when I have chrome open regardless of which tab I'm in. It does not work and seems to pause if chrome is minimized. What would you suggest?
I think the mistake lies on this line:
WinGetTitle, firstTabTitle, A ; The initial tab title
Here is a solution proposal:
#SingleInstance force
SetTitleMatchMode, 2
ComposeTitle = Compose Mail -
If WinExist(ComposeTitle . " ahk_exe chrome.exe") {
WinActivate
return
}
; Loop on all Chrome Windows
WinGet, id, List,ahk_exe Chrome.exe
found := False
tabSearch = Gmail
Loop, %id%
{
hWnd := id%A_Index%
WinActivate, ahk_id %hWnd%
; Loop on all Tabs in Chrome Window
WinGetTitle, firstTabTitle, A
title := firstTabTitle
Loop {
if (InStr(title, tabSearch)>0){
found = True
break
}
Send ^{Tab} ; switch to next tab
Sleep, 50
WinGetTitle, title, A ;get active window title
if (title = firstTabTitle){
break
}
} ; end Loop Tabs
if (found)
break
} ; end loop Chrome windows
If !(found) {
Run run C:\Program Files (x86)\Google\Chrome\Application\chrome.exe https://mail.google.com/mail/ca/u/0/#inbox"
WinWait, Inbox ahk_exe Chrome.exe
}
SendInput +c ; Shift+C
;WinWait %ComposeTitle%
;winmove, A,, 1750, 303, 1725, 935; moving the window to my preferred position
return
You can download the code from this gist.
I'm writing a chrome extension to remove elements from a specific page after it loads and I am seeing inconsistent behavior.
I have two listeners, one is listening for hotkeys and the other is the chrome.tabs.onUpdated listener. Both make an executeScript call to the same additional file.
OnUpdated fails with a manifest permission error at first, and continues to fail on each reload. When I execute the call from the hot key it works, and then the onUpdated call works with subsequent reloads
If I open the page in a new tab, it is back to failing until I execute the call with the hotkey. It also goes back to failing if I reload the extension from the management page.
Am I missing something obvious? I have tried adding http://*/* to my permissions but the behavior is the same.
backgroud.js
chrome.commands.onCommand.addListener(function (command) {
if (command === "test-alert") {
try {
chrome.tabs.executeScript(null, {file: "testalert.js"});
} catch(err) {
chrome.extension.getBackgroundPage().console.log(err);
}
}
});
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab){
if(changeInfo.status === "complete" && tab.url.includes("nytimes")){
chrome.tabs.executeScript(tabId, {file: "testalert.js"});
};
});
manifest.json
"commands": {
"test-alert": {
"suggested_key": {
"default": "Ctrl+M",
"mac": "Command+M"
},
"description": "test alert"
}
}
testalert.js
alert("test");
Error:
Unchecked runtime.lastError: Cannot access contents of url "https://www.nytimes.com". Extension manifest must request permission to access this host.
Am I missing something obvious?
Looks like so. Look at the error message more closely:
Cannot access contents of url "https://www.nytimes.com"
The protocol is https, not http. You should use https://*/* in your manifest "permissions", or maybe even <all_urls> to match all protocols.
I have written a userscript that I would like to run when I call it (not every time a matching web page loads). Ideally I'd like to create a toolbar button for starting this script. How can this be done?
PS: I need it to run in the same context with the web page scripts and be able to call functions embedded in it.
I don't know exactly what toolbar you're talking about, but it's possible to add a menu command to Tampermonkey's action menu.
Since your script should be able to run at any page you need to #include all pages what might slow down pages with a lot of iframes a little bit.
This script will execute the main function (with the alert statement) only if the menu command was clicked.
// ==UserScript==
// #name Run only on click
// #namespace http://tampermonkey.net/
// #version 0.1
// #description Run only on click
// #include /https?:\/\/*/
// #copyright 2012+, You
// #grant unsafeWindow
// #grant GM_registerMenuCommand
// ==/UserScript==
GM_registerMenuCommand('Run this now', function() {
alert("Put script's main function here");
}, 'r');
Accessing the pages functions is possible by two ways:
function main () {
window.function_at_the_page();
}
var script = document.createElement('script');
script.appendChild(document.createTextNode('('+ main +')();'));
(document.body || document.head || document.documentElement).appendChild(script);
or just:
unsafeWindow.function_at_the_page();
i have following code in my background.html.
var child1 = chrome.contextMenus.create( {"title": "test '%s'", "onclick": callLocalhost, "contexts":"selection"]});
function callLocalhost(obj){
window.location.href="http://localhost/"+obj.selectionText;
}
function is called but redirect doesn't work.
window.location.href contains the extension id and is not editable.
Is there a workaround?
Your code executes in the background window of your extension, the window object is the background window. To change tab location you need to execute code in the tab. You do it with the chrome.tabs.executeScript method. Something like this (untested):
function callLocalhost(obj, tab){
chrome.tabs.executeScript(tab.id, {
code: "var obj = " + JSON.stringify(obj) + ";" +
"window.location.href='http://localhost/'+obj.selectionText;"
});
}
Note that the content script (the script injected into the tab) cannot access variables of the background window directly. This is why I put obj directly into the code to be executed in the tab.
You can use the chrome.tabs.update API to change the location:
function callLocalhost(info, tab) {
chrome.tabs.update(
info.tab,
{"url": obj."http://localhost/" + info.selectionText});
}
Unlike the chrome.tabs.executeScript approach proposed by Wladimir, this doesn't require script execution permissions in the tab.
Use the chrome.tabs.create API.