How to hook GWT navigation from a userscript? - gwt

I'm writing a userscript for a GWT-based site.
My script uses URL of the page as input. It should be update each page of the site with additional information.
Unfortunately, as view changes in GWT are implemented via rerendering (only location anchor in browser address-bar is being changed), clicks on internal links are not recognized as page loads and Greasemonkey does not invoke my script, leaving new views unmodified.
Is there a way to hook in GWT-based navigation from an userscript? I need a way to modify each "change" Gerrit navigates to.
Complete workflow should look like:
User scans through the list of issues
User clicks on a link . (Address bar will assume a location of a change being clicked, for example https://git.eclipse.org/r/#/c/38781/)
Page is modified by userscript to contain information about new view (in our case /c/38781/)
Greasemonkey is only invoked at the first step of this workflow, and I don't know ho to detect second one to be able to trigger the third.
I've tried to observe DOM changes on the page, but my listeners are never called probably due to the fact GWT renders some parts via innerHTML property, without explicit child manipulation.

Related

gwt - history - how to "keep" UI state

I tried the example which is showing how to get data from history to re-generate UI; The thing I see mostly in all "history usage" examples are related to UI re-generation only so it is none-static way...
But what about "each UI state may have its unique url something like JSF does with flows"? For example I have app url like a
http://localhost:8080/myapp/MyApp.html
the app default UI contains main menu which is helping to navigate through my test catalog; I tried to make possible keep the UI dynamics in history by building url in this way
http://localhost:8080/myapp/MyApp.html#menu_testcategory_page1
but when I click internet browser "refresh" button the url keeps the same as http://localhost:8080/myapp/MyApp.html#menu_testcategory_page1 but the UI comes back to its default state :(
So my question is
is there an optimal way in pure gwt to stay in the same UI state even after browser's refresh button is clicked (I mean the unload/load window events occur)?
thanks
P.S. gwt 2.3
You should implement Activities and Places pattern: http://www.gwtproject.org/doc/latest/DevGuideMvpActivitiesAndPlaces.html
I am using it for 3 years, and it works very well.
Note, however, that when you reload a page, you lose all of your state, data, etc. If you need to preserve some of it, you can use a combination of a Place (#page1) and a token that tells the corresponding Activity the state of the View representing this Place, i.e. (#page1:item=5).
You probably just forgot to call
History.fireCurrentHistoryState();
from your entry point.

lift disabling back button actions

I'm creating a transaction related site using lift. In here, there's a requirement to show a success page after the user action.
when i make action happen and press the browser's back button. it again goes to the previous page(before transaction page) making the transaction doable again. I need to limit this behavior. Is there any way of limiting the access to previous page by browser back button in lift.
There is no way to reliably stop the user from returning to the URL, but you can stop them from invoking the action more than once. Take a look at S.oneShot. From the Scala Doc:
All functions created inside the oneShot scope will only be called
once and their results will be cached and served again if the same
function is invoked
If you wrap the function that occurs when the button is pressed, even if the user does return to the page and click the button a second time, the body of the function shouldn't be invoked again.

GWT - connect two modules via EventBus

We use MVP with custom EventBus to navigate across the views. One of our GWT module loads an ebook within a view. We have a button named "Expand", which upon clicked, loads the ebook in expanded mode thereby hiding the header, footer, etc.
Let us say the view (UiBinder) with "Expand" button is named as "ShowEbookView". Upon clicking "Expand" button, the ClickEvent is captured and fired to the EventBus. The logic onExpand(final ExpandEvent expandEvent) is written in the same "ShowExpandedMod" class.
Everything is okay, but we have a button named "Popout" in the expanded mode, which when clicked, should open the Ebook in a NEW page! We need to abstract the "ShowExpandedMod" class so that it can operate with the EbookId and can be used in the new page.
We have created a new Module with EntryPoint class, HTML page and UiBinder page for this new popout window. I am not sure how to proceed now with the abstraction and to use EventBus across different modules to load the same content ... (with re-usability ofcourse)
I've explained to my best, but perhaps not very clear! Please let me know if you want more details.
Thanks!
When you open a new window in browser you basically get a new instance of your GWT app. You can not use EventBus across different browser windows, i.e. across different GWT module instances.
What you can do is:
Add an argument to the Popout page URL. This is easies done via "history tokens" (fragment identifiers), like this http://yourdomain.com/popout.html#theIdOfTheDocument. Then you can retrieve the token via History.getToken()
Use DOM to communicate between browser windows: window.open() in javascript opens a new window and returns a reference to DOM of the new window. You can then access properties and functions of the new window. This is all javascript, in order to make this work in GWT you'll need to wrap it in JSNI.
Try and use MVP4G, in specific - take a look at their multi-modules feature (which utilizes GWT's code splitting capabilities).
This should make things like multiple EventBus's and cross-module event triggers a lot easier to handle.

Discover which (if any) route will match a given URL from within Controller in ASP.NET MVC2 app

In my master page I have a placeholder where a Html.RenderPartial() will render a collection of (bread)crumbs which are effectively a list of links I build up using action, controller names and RouteValueDictionary's.
I have an action that is called from multiple places to view a short-list and so when building the list of breadcrumbs for this actions view to display. Ideally I'd like to use Request.UrlReferer as the penultimate crumb.
Before unconditionally using this URL I want to check that it will actually match at least 1 route so I can be sure if the user clicks it they will get a view from my app and if they don't I will simply use the home page instead.
Any suggestions how I would go about this?
Take a look at this post http://haacked.com/archive/2007/12/17/testing-routes-in-asp.net-mvc.aspx

How to unload js script when going to next tab in jquery?

I have a site with five tabs using jquery-ui. Each loads an individual jQuery script. Now when I have loaded the second tab and go to the third tab the js out of the second tab still remains active and disturbs my actions in the third tab space.
Can someone explain me why the js out of the second tab still stays active when changing to the third tab and how I can avoid such behaviour?
Once you have loaded a script onto the page, it remains active until the page refreshes.
I don't know about unloading, but you can certainly disable the actions of a certain script depending on what it is. Could you post an example of the script causing the issues?
EDIT:
For example, if you have a script that is dependent on the tab you are in, you can condition the actions in the script with the tabs being at a certain index. A demo syntax:
//will only execute action if you are in current tab
if(tabs_ui_index == 0){
//do something
}
to get that variable (tabs_ui_index) you can do something like this:
$('#mytabs').bind('tabsselect', function(event, ui) {
tabs_ui_index = ui.index;
});
This code binds a "tabsselect" event to the element that is tabbed and sets the variable to the currently indexed tab every time a user changes a tab.
Also, you can unbind events, if you loaded a script that set a click event for a button that no longer exists, or that you are using for a different purpose now:
$("#mybutton").unbind("click");
I hope this helps. Let me know if you have any other questions.