Greasemonkey and Gmail - parsing message contents - javascript

I want to read the contents of Gmail messages and add some fancyness on links. Here's some code:
unsafeWindow.gmonkey.load("1.0", function(gmail){
gmail.registerViewChangeCallback(function(){
if (gmail.getActiveViewType && gmail.getActiveViewType() == "cv") {
var viewElement = gmail.getActiveViewElement()
// Do things with viewElement
}
})
})
The actual detection of links in the dom objects for the mails is the easy part. The problem is that the registerViewChangeCallback only runs when you display a thread. Large threads will have most of it's messages hidden, only to be loaded by a users request. I haven't found a Gmail greasemonkey API method for this particular action (loading a individual message), which is when I need to run my script.
Any suggestions?

As you say, the registerViewChangeCallback() function only fires when the user changes their view from e.g. threads to archives, etc.
What you really need is to add a function that intercepts gmail's post-backs and then changes the links. I have never tried doing it myself, but this answer has some sample code for you. When gmail has retrieved a new message, it will fire a readystatechange event, which your code can intercept. You can then change the contents of the message in whichever way you wish (although you may have to wait for a moment to allow gmail to insert the message first - not sure about that one).

I think you'll find that some messages are loaded when they're listed in the thread; hence your problem.
Why don't you just use a custom style anyway? UserStyles FF plugin.

Related

Simple web development concept I can't find any info on +update

Let's say we have a web app that only has one element, for example an image IMG1 and if an user clicks on it, it will change to another image IMG2 (this change should be visible only to the users that clicked and triggered the event).
Then, I have another event that triggers when a total of 100 users clicked on the image (or any other back-end related event), and this time I want to dynamically change the image to IMG1 (but now I want the change to happen and be visible to all the users of the website).
The confusion starts when I realise that for both events the function would be the same (changing the src of that HTML img element) yet I want it to have a different effect:
on the event of a user click change it for that user only.
on an outside event that doesn't involve a specific user, change it for all the users to see the same image.
How does this work? what is the thing that makes the difference between a HTML change that only affects the users locally (on their actions) and a change that has a global effect (to all the users).
UPDATE !!!
I should have been more specific with what I don't know.
I'm familiar with AJAX request and I already have the backend sorted.
In the frontend script I have an event listener for the event from the backend, and all my questions are actually about 'what and how to do it' after the event listener is triggered.
Now, what I want to do when this happens is to make some changes, the main one being to change that image IMG1 to IMG2 for all the users (as it would be a dynamic update to the website) but also:
I need that change to be permanent, so in a case of users reloading the page or new users coming in, they all should still see IMG2. (And the only time the image would change would be when the event listener on the frontend script will trigger again on the same backend event to change the image again (to IMG3) for example. And yes, in this example there is NO 'on click' request for the users to change the image, so ignore my example previous to the update.
Now to address your answers, I checked the web sockets stuff and it seems to be doing what I need if I run that 'on event' change of image to all sockets. Which only leaves me with 2 questions now:
1) Will this change that occurs on all sockets to change the image be permanent, so in a case of users reloading the page or new users coming in, they will all see the new image (IMG2) as a permanent change to the webpage ?
2) Regarding these type of permanent changes, isn't reactJs a way of doing such changes dynamically?
What would actually happen if on that event listener (for the backend event) I simply ignore all the web sockets stuff and run the same code of changing the src of the image ?
2.5) Because from how I see it, that event in the backend fires without any specific user input, thus is not linked with any user. So if I simply run the code on that event without websockets It should either do absolutely nothing (so no change for anyone) OR do the change for all the users (acting simply as a dynamic update to the webpage). How does this work?
I'm looking forward for your answers, and thank you all in advance!!!
The click event needs to be handled by an AJAX request, sending a message to the server and the server will handle that and respond. Upon the response, the first type of event is executed for the user.
On server-side you will need to have an event queue somewhere, maybe in the database. If you are using WebSockets, then you will have to execute the second type of event for all users if the request is met via WebSocket channels. If you are not using WebSockets, you will need to do polling from the browser. Anyway, you will need a counter on the server-side to be able to determine when the second type of event is met.
EDIT
Yes, WebSockets are the way to go unless there is a strong reason not to do so, like a boss saying he or she does not want the server to use WebSockets. With WebSockets you have a live channel between the server and the client browsers. You can use this channel to send the URL change to the client. On the other hand, the client will have to handle the change with Javascript, gathering the tags where the src is to be changed and change them. If you happen to have a class of changable for all such tags, then executing the change can be done with a function like this:
function changeSources(newSrc) {
var items = document.getElementsByClassName("changable");
for (var index = 0; index < items.length; index++)
items[index].src = newSrc;
}
However, this change will be effectuated only for the loaded page which was initially loaded and upon new loads, this, by itself will not use the new src. So you will have to solve that problem as well. A neat way to do it is to store the new src on the server before you send it out to the client via WebSocket and use this stored src as the src of those tags when the client requests for the HTML. So, your problem has two parts, the first is changing the src on already loaded pages and the second is making the change permanent.
ReactJS is a Framework. At this point we need to define the technical background, since ReactJS will use a possible solution from these.
WebSocket
https://www.npmjs.com/package/react-websocket
This is a WebSocket implementation. The best technical background here is to use WebSockets unless there is a very good reason not to do so.
Server notification system
https://www.npmjs.com/package/react-notifications
Server notification systems in general are one-way ticket roads. The server may send a notification, but the client has no such possibility.
Polling
The browser may periodically send HTTP requests to the server and this way it can receive the src change response. This is a good solution if WebSockets and server notification systems are not an option.
Forever frame
You can use an invisible iframe to be loaded forever, which will provide you with the possibility of sending real-time messages from the server to the client, but this is very hacky.
The difference may be between a front end, running in the browser, or the mobile app, of each user, which is local, and the back end, where you can share data between all users.
This can be implemented by, for example, firebase. Here is an example: Firebase - Multiple users simultaneously updating same object using its old value
This does not mean, obviously, that back end data is always shared... In many cases each user accesses his own copy of back end data that is stored in a database.

Javascript: How can I check to see if url to fire exists before firing it?

I am getting urls from a feed that I assign to list of buttons, some of the urls produce 404s when clicked on said buttons. Is there a way to check if the landing page exists first before I fire it?
Some of these urls have tracking pixels in them to know when they are clicked so I wouldn't want to fire it in an iframe or a similar solution as it would possibly track twice to test if it exist first before it fires.
Is this even possible? The domains will not be the same and I can't use jQuery.
To test an url you must access it. So, without an external service, you can't test them beforehand.
W3C provides a link checker: https://validator.w3.org/checklink
"The program can be used either as a command line tool or as a CGI script."
Maybe you can use it to test an url and, after, create or not your button.
I don't know if there is a limit for this service, so check the documentation!
http://search.cpan.org/dist/W3C-LinkChecker/bin/checklink.pod

Showing image when available

I am trying to create a web interface for a scientific code. The user will provide some inputs and submit through a HTML form. A php script will take the input and run code on server. In the end of it, one or more (not more than 10) images will be created. The code may take few seconds to hours, depending upon the inputs.
How can I show these images on the webpage after completion, and make them available for download?
You will need to have a method that creates a unique identifier upon completion.
So this can be as simple as checking to see if the image exists, and if not notify the user that it is still in progress.
so something like:
if (file_exists($image_file)) { do something... }
else { echo 'Files still in progress....'; }
Assuming your going todo the scientific code in a background process, the issue would be the frontend.
To make it simple, I would assign the job/calculation a unique url, that relates to the results, much like codepad, viper7, JSFiddle do, then while there on the page poll (AJAX) the server for the images/results. Dont even attempt todo any submitted code, while the user waits or on the request thread.

message passing in a Google chrome extension

There are a few questions about this but none met my needs. I have created an extension and I am trying to communicate between a content script and my options.html. I have been trying to use the chrome.extension.onRequest.addListener and the chrome.extension.sendRequest and neither work at all. No commands are executed or anything. Here is my code:
content script:
chrome.extension.sendRequest({command:value}, function(response) {});
options.html
chrome.extension.onRequest.addListener(
function(request, sender, sendResponse) {
alert("in onRequest request.command = " + request.command);
decide_command(trim(request.value));
sendResponse({});
});
none of the alerts are executed and none of the functions are executed. I even tried using the example in the messaging API page and it didn't trigger any alerts or anything. I have tried a bunch of different combinations like putting the extension ID in the sendRequest to make sure its going to the right place, I have excluded the sendResponse to make sure it wasn't ending too quick. I have debug alerts all over and none get triggered except for the ones before and after the send request command in my content script. So I would assume it either gets executed and fails or something like that. Any help would be greatly appreciated I have been working on this for days.
I believe Chris noted an issue already: an extension's option page isn't running all the time, and is therefore not available to receive or generate messages. Background pages are better for this sort of communication, as they're always running, always available, and therefore always capable of responding to messages.
I'd suggest reworking your extension's architecture a bit such that the content script gathers relevant information and sends it to the background page. When the options page is opened, it can request the state from the background page. The background page is then responsible for maintaining state in a reasonable way, and for pushing information back and forth between the other pieces of your extension.
Does that make sense?

AJAX GET race condition?

I am attempting to track events when links are clicked on my site in a method similar to the following.
Example
<script type="text/javascript">
jQuery(function($) {
// track clicks on all anchor tags that require it
$('a.track').live('click', function(e) {
// send an AJAX request to our event tracking URL for the server to track it
$.get('/events/track', {
url: $(this).attr('href'),
text: $(this).text()
});
});
});
</script>
The problem that I'm having is that a new page load interrupts the AJAX request, and so sometimes these events aren't being tracked. I know Google Analytics has a _trackPageview function that can be attached to onclick events though, and this doesn't seem to be an issue for that. I'm wondering what's different about their call vs. mine that I'm seeing this race condition, and GA isn't. e.g.:
Example
Note that I'm not worried about the result of the AJAX request...I simply want it to ping the server with the fact that an event happened.
(Also, I expect I'll get at least one answer that says to simply track the new page load from the server side, not the client side. This is not an acceptable answer for this question. I'm looking for something like how Google Analytics' trackPageview function works on the click event of anchor tags regardless of a new page being loaded.)
Running Google's trackPageview method through a proxy like Charles shows that calls to trackPageview( ) request a pixel from Google's servers with various parameters set, which is how most analytics packages wind up implementing such pieces of functionality (Omniture does the same).
Basically, to get around ansynchronous requests not completing, they have the client request an image and crunch the parameters passed in those requests on the server side.
For your end, you'd need to implement the same thing: write a utility method that requests an image from your server, passing along the information you're interested in via URL parameters (something like /track.gif?page=foo.html&link=Click%20Me&bar=baz); the server would then log those parameters in the database and send back the gif.
After that, it's merely slicing and dicing the data you've collected to generate reports.
Matt,
If you just want to make sure that the tracking pixel request is made and you don't depend upon response then just doing document.write for the tracking pixel image will do the work.
And you can do the document.write in your onclick handler.
AFA race condition between href and onclick handler of anchor element is concerned the order is well defined.
the event handler script is executed first
the default action takes place afterwards (in this case the default handler is href)
(Source : Href and onclick issue in anchor link)
But yes, if you depend upon the response of the tracking request to the server then you will have to make it synchronous.
Suggested option would be to call some javascript function to wrap the already defined onclick handlers and then in the order make the calls. Make sure that your tracking request is not asynchronous.
Though it is suggested that you should not be dependent upon the response of the tracking pixel request.

Categories