I am creating a browser-action button on the right side of toolbar so that I can show deals on my extension depending upon the opened URL in tab.
Upon going through SDK documentation I found this: https://developer.mozilla.org/en-US/Add-ons/SDK/Low-Level_APIs/ui_button_toggle#Attaching_panels_to_buttons but it says that it's supported only for Firefox 30 onwards which is an issue.
To achieve this thing, I used browser-action lib by Rob-W (source: https://github.com/Rob--W/browser-action-jplib)
Here is how it works:
Let's say, I have opened www.example.com, and it has 20 deals on my server. If I click on my browser-action button, it would open a panel showing deals depending upon the opened URL (with the help of an AJAX request)
Now the problem is:
The browser-action button (upon click) opens popup.html, and in my popup.html I have included popup.js. This is the file where I want access to the opened tab URL, so that I can perform the AJAX request. I do not get how can I pass the opened tab URL from main.js to popup.js.
sdk/tabs give you the access to current tab and from there you can get the location.
https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/tabs
I do not get how can I pass the opened tab URL from main.js to
popup.js.
Have you tried to use the port system.
to emit a message from a content script:
self.port.emit("myContentScriptMessage", myContentScriptMessagePayload);
To receive a message from the add-on code:
self.port.on("myAddonMessage", function(myAddonMessagePayload) {
// Handle the message
});
You can also use widget instead of the new UI module if you really want to target browsers before version 30, however it is depreciated and will probably be removed within the next few releases.
Related
I'm hoping this is the right place for this question since it centers around JavaScript. In the new iOS 12 Shortcuts app you can create workflows. I want to create one that simply launches a web page, fills in my username and password, then clicks the submit button, something like this...
document.myForm.username.value = 'myUsername';
document.myForm.password.value = 'myPassword';
document.getElementById('loginSubmit').submit();
But before even getting that far I just want to run an alert(1);. I can't get that to happen. I keep getting this error message below...
Run JavaScript on Web Page failed because Shortcuts couldn't convert
from URL to Safari web page.
I'm not sure what that means. I haven't been able to find info or tutorials on how to use this. Does anyone know how to get JavaScript to run? Thanks!
the first thing you need to know is that docs are here: https://support.apple.com/guide/shortcuts/welcome/ios
Now, the problem is that "Run Javascript on web page" need an input called "Safari web pages" but Open urls only gives as output the result of opening the url that is showing the page in safari, in order to make it work you need Open url to give you a "Safari web page" item.
The only way that I found to do that is to use the shortcut as a "Share extension"
In your workflow delete the URL item
Go to the shortcut settings page by tapping the icon
Settings icon
Now tap on "Show in Share Sheet"
In the "Accepted types" section, select only URLs that is at the very bottom of the list.
Finally go to safari, open the url you want and tap the share button, if this is the first time you do this, you need to active the "Shortcuts" section, in the bottom list go to the end and tap in "More", the scroll down and select "Shortcuts"
After doing that you will have the Shortcuts option, tap on it and select your Shortcut and it will run the java script in the page.
Is important to note that you will need to do something with the output of "Run javascript on web pages" like showing the result in one alert, because the way you have your workflow now, it may look like nothing is happening.
There's a note in the Run JavaScript on Web Page action that says, "Safari Web Page item in shortcuts stating that they are only available when running your shortcut as an Action Extension in Safari."
So, sadly, it's not possible to chain up actions where it launches a URL and then runs JS. You must visit the url and run the action from the share sheet.
The Safari actions require Safari to be open to the page you want when you launch the activity. That said, you can accomplish this easily using another element.
I don’t know your technical level, so I apologize if any of this is stuff you already know, but for you and for future reference to anyone looking, here is the howto.
First, go to the page you want on a Mac/PC browser and open the developer tools. I use Firefox Developer Edition, but Safari and Chrome have them also. If you’re using MacOS Safari, you will first need to open Safari’s Preferences menu and check “developer options” and relaunch.
Once the developer tools are open, switch to the Network tab / pane; find and turn off the option which clears the log on each page load. Keep this pane open, fill out the form, hit the trash can to clear the network log, and then submit the form. Now the HTTP request of the form submission should be either the first or the only thing in the list.
Select the line for the form submission and look at the request header. There should be a Request Method, Request Url, and all the key-value pairs that were submitted with the form.
Back in the Shortcuts app, add a URL element and give it the same URL as the Request Url. Chain this URL input element to a Get Contents of URL action element and toggle open the Advanced drawer. If there are any additional headers in the request log, you can tap Add new header to add more. Match the Request-Type to the Method field, choose “Form” as the Request Body, and then add in all the keys and values from the request.
Anyways, that’s it.
Chain this to Set Variable then use an IF block to test if the login succeeded or not. If it succeeded, make a Show Result that says “You are now logged in.” and if it failed, show the variable so that you can debug the response.
For API requests in shortcuts, I typically use the Get Contents of URL shortcut, which allows you to use different HTTP methods (POST, GET, etc) and adjust the URL parameters.
In your case, once you authenticate, you could use the authentication token to make other requests as needed.
View Apple's documentation here for an example
There are quite some similar question but they all comes down to chrome.tabs.getSelected or chrome.tabs.query API which is not suitable in my case.
Basically what I need to do is to get an id of the tab where the script is running from - so it's not necessarily an active or selected tab.
As per the doc:
getCurrent chrome.tabs.getCurrent(function callback)
Gets the tab that this script call is being made from. May be
undefined if called from a non-tab context (for example: a background
page or popup view).
Which implies that it should work from content script but chrome.tabs is undefined in content script. Why is it so? Is there any way to know this tab data (from where the content script is running and not from selected or active tab)?
Even though the doc says the tabs permission is not mandatory for the most APIs I've anyway added it to the manifest with no luck:
{
"manifest_version": 2,
"name": ...
"permissions": [
...
"tabs",
...
}
Any ideas are much appreciated
The use case for get current/this tab is that when the extension does its work it needs to reload a page where it's running from as part of the working flow and user can be on different tab or in different window. The extension's script still needs to get the correct tabId to keep working as expected.
Effectively, you can only use chrome.tabs.getCurrent on a page from the chrome-extension:// scheme (opened as your extension's Options page or via chrome.tabs.create or chrome.windows.create), or if you're using chrome_url_overrides. The background, popup, and embedded options pages don't have a current tab, and the API doesn't exist in a content script.
Well, seems like I've figured out an answer to my question.
The trick is to send a message to background script and extract sender data from there. Sender will include tab object where the script is running from.
I'm using ports so this is what I'll describe as example below:
On content script side:
var port = chrome.extension.connect({
name: "some name"
});
port.postMessage({"key":"some json here"})
On Background side:
chrome.extension.onConnect.addListener(function (port) {
console.log(port.sender.tab)
})
port.sender is a MessageSender object that will contain tabId (and tabUrl if "tabs" permission is added to the manifest)
In my case I'm just sending tabId back from background to the content script:
port.postMessage({"tabId":port.sender.tab.id})
More on this can be found in messaging doc and in this api doc
I'm building a chrome extension to debrid and stream a link on my raspberry pi (running Kodi).
So far, it's working well. I can give a link :
and it's debrided + streamed on Kodi.
I would like to make it easier to use.
Instead of pasting the link into the app, I made a little script to search on a given type of page if a link can be debrided via Realdebrid and is so, the script add a button to directly stream it :
The problem here is :
When the user click on the button, how can I pass the link to my extension ? I would like to have it in my extension because I can display the link into history.
I tried something like that :
from the view :
from the extension :
But it's not working.
I think I should use messages but I don't understand how.
It's an open source project that you can find on Github.
As it's not working yet you won't find the code I shared in the 2 images before. It's just on my computer, not pushed.
Any help would be really appreciated !
Thanks !
EDIT 1 :
When I click on the button injected in the page, I get this error :
Which leads to this line :
EDIT 2 :
If I keep the app open while I click on the button it's working. But I do not want to have to launch the app of course, the goal is to click on the button only.
Popup script is loaded when you open the app by a user action i.e clicking on the app icon. Until then, it is not available to you. As such you are getting this error because when you send a request the listener should be available and in your case its not there.
Now, the easiest way to achieve this would be to send the request from the content script to the background page which is available even when the app is not open.
Inject the button using the content script and send a message to the background page (called event pages) on click event of the button.
Add an event listener in your background page which will listen to the request from the content script and store the link in the local storage.
When your app opens just load the link from the local storage and display your links in the history.
I hope this helps.
I am creating a Chrome application, "not a extension."
People can receive and send messages. If i receive a message, i got a notification and a mp3 sound. If the app Window is open, I know how to focus the window to make it appear to the front. but if the window is closed. I do get the notification, the sound ect (from background.js) and i create a window to open, when i receive this notification, but i can't interact with the background.js script anymore. is like if the chrome.runtime.sendMessage fire to soon before my app window is fully open.
chrome.runtime.sendMessage({
action: "Messageincoming"
});
When a message is incoming, in my app, a popup appear telling the user that a message is incoming (called from background.js) and the user can accept it by clicking a button. but when the app window is closed i should open a new window and i open it programatically with chrome.app.window.create('myapp.html', {
Like i said the chrome.runtime.sendMessage seem to fire to soon before the window is fully open. I can't trigger this popup to make the user accept, and i am not sure that if i do that the button will work.
Is there a way to wait until the window is fully open? or use any other method.
i read all the chrome app documentation and i find nothing. I have a js scripts in the myapp.html page who control the click and everything in the UI. controler.js
There are a variety of ways to do this, so it really depends on what you're looking for. The likely simplest answer is through a callback function, which you can pass in to chrome.app.window.create as shown here. This will allow you to pass in a function to be executed during page load.
Another way is to receive a message as you've described. You can do that as well, but you need to set a message handler in the new page you've created, and it needs to be set immediately on page load or else you will miss the message as you've described. Here's more on message passing with some examples at the bottom. https://developer.chrome.com/extensions/messaging
A more elaborate method of doing this could be to hook into the OnFullscreened or other handlers for the new window. In that handler, send a request to your background script requesting whatever message data you need. In your background script, have a message handler that returns whatever stored message(s) you want.
On an html page i click on a link and i get a dialog which loads server content through an ajax call.
I cannot change the javascript that created this dialog neither the ajax callbacks .
I have the need to access the href of the clicked link from another javascript to change some content loaded into the dialog from the ajax call. This after the dialog shows up.
As i can only read the window.location of the current page (the page containing the dialog, not the page loaded into the dialog itself), is there a way to get the href of the clicked link that caused the dialog to show up ? (ie. the GET parameters of the ajax call)
Attaching a callback for every clicked link doesn't work reliably because i have to catch just the last one that caused the dialog to open...
-- edit --
Well i'm using jquery, but i don't think it's implementation dependant.
The question more generally is: if i cannot access the ajax callback, is there a way to obtain the url in the GET request that caused a div (some content) to update ? (assuming you can call a javascript function after the div is loaded, inside it).
ie. if it was a popup (window.open) i just have to read window.location to get the page called, but as it's a div loaded from an ajax request, how i can get the url called ?
thanks anyway~
Install Firefox (if you do not have it already)
Install Firebug extension
Enable firebug for your site
Click the Link that launches the dialog (reproduce the situation)
Open the firebug window (bottom right corner of firefox)
Under Net - >XHR tab you can see the exact URL call with all GET/POST parameters that was triggered.
Then explore firebug some more to see what other possibilities it offers!