Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 283291 - Provide history support
Summary: Provide history support
Status: RESOLVED FIXED
Alias: None
Product: RAP
Classification: RT
Component: RWT (show other bugs)
Version: 1.2   Edit
Hardware: All All
: P3 enhancement (vote)
Target Milestone: 1.3 M3   Edit
Assignee: Ralf Zahn CLA
QA Contact:
URL:
Whiteboard: plan-version=1.3 plan-status=committe...
Keywords:
Depends on:
Blocks:
 
Reported: 2009-07-13 06:09 EDT by Ralf Sternberg CLA
Modified: 2009-10-23 11:03 EDT (History)
2 users (show)

See Also:


Attachments
First draft (37.56 KB, patch)
2009-08-31 16:58 EDT, Ralf Zahn CLA
no flags Details | Diff
qx library with History.js (246.22 KB, application/octet-stream)
2009-09-03 07:07 EDT, Ivan Furnadjiev CLA
no flags Details
Second draft (28.91 KB, patch)
2009-09-04 16:21 EDT, Ralf Zahn CLA
no flags Details | Diff
Third draft (43.53 KB, patch)
2009-09-18 00:27 EDT, Ralf Zahn CLA
no flags Details | Diff
Example (4.07 KB, patch)
2009-09-21 06:57 EDT, Rüdiger Herrmann CLA
no flags Details | Diff
4th draft (38.67 KB, patch)
2009-10-17 02:40 EDT, Ralf Zahn CLA
no flags Details | Diff
4th draft (38.67 KB, patch)
2009-10-17 02:41 EDT, Ralf Zahn CLA
ruediger.herrmann: iplog+
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Ralf Sternberg CLA 2009-07-13 06:09:48 EDT
RWT should provide a hook to the browser history that allows to
 a) programmatically add history items at certain points in the application and
 b) let the application react on browser history events by moving back to those points.

History support could be implemented using URL fragments (anchors) similar to GWT [1].

[1] http://code.google.com/webtoolkit/doc/1.6/DevGuideCodingBasics.html#DevGuideHistory
Comment 1 Ralf Zahn CLA 2009-08-31 16:58:48 EDT
Created attachment 146118 [details]
First draft

Have implemented a first prototype simply creating an entry in the browser history and calling events on history navigation. Currently, the Javascript should ONLY work in Firefox. I will extend it the next days by using browser specific customizations.

There are some questions:
=================

1) Should the BrowserHistory object and the listener class be serializable, because of the session scope?
2) I have extracted the JSExecutor class out of the ExternalBrowser class to re-use it in the BrowserHistory object. Is this change okay?
3) To send the event from the browser to the server, I simply used the Request object and put some parameters into it. The BrowserHistory object itself is a PhaseListener that reads out these parameters and calls the events. Would it be better/possible to use the event mechanism (like widgetSelected)? But for that, the BrowserHistory object has to be implemented as a widget, right?
4) Currently, the BrowserHistory object is lazily created and so registered as PhaseListener. So calling an URI with a # only occurs history events after the first history object was created. Is that behaviour correct? Should it generally be possible to define "JoinPoints" that can be bookmarked and reopened? In such a case, we would declare such JoinPoints e.g. as Extension or programmatically, and the BrowserHistory object could support access to these points over the browser history - but they could also be called from outside the application (bookmark).
Comment 2 Rüdiger Herrmann CLA 2009-09-02 10:43:52 EDT
(In reply to comment #1)
> [ ... ]
Greakt work! Please see my comments below.

> 1) Should the BrowserHistory object and the listener class be serializable,
> because of the session scope?
No, in RAP sessions aren't serializable

> 2) I have extracted the JSExecutor class out of the ExternalBrowser class to
> re-use it in the BrowserHistory object. Is this change okay?
Yes

> 3) To send the event from the browser to the server, I simply used the Request
> object and put some parameters into it. The BrowserHistory object itself is a
> PhaseListener that reads out these parameters and calls the events. Would it be
> better/possible to use the event mechanism (like widgetSelected)? But for that,
> the BrowserHistory object has to be implemented as a widget, right?
You could (and should) use org.eclipse.rwt.internal.events.Event for the history events.
* Let BrowserHistory implement Adaptable and return EventAdapter from getAdapter().
  (see Widget#getAdapter() for an example)
* Provide and use static add/removeXXXEvent methods on BrowserHistoryEvent like it is 
  done in ActivateEvent  
* Don't fire the event 'yourself' (remove fireBrowserHistoryChanged). Instead call
  Event#processEvent()

> 4) Currently, the BrowserHistory object is lazily created and so registered as
> PhaseListener. So calling an URI with a # only occurs history events after the
> first history object was created. Is that behaviour correct? 
That is sufficient for now.

> Should it
> generally be possible to define "JoinPoints" that can be bookmarked and
> reopened? In such a case, we would declare such JoinPoints e.g. as Extension or
> programmatically, and the BrowserHistory object could support access to these
> points over the browser history - but they could also be called from outside
> the application (bookmark).
For now, I think we don't need this

Some more remarks
1. The phaseListener in BrowserHistory currently acts for all sessions. The code needs to be
  changed to only handle life cycle events (before/afterPhase) for the session for which
  the BrowserHistory instance was created for (see if( display == RWTLifeCycle.getSessionDisplay() ) 
  in JSExecutor for example)
2. we don't use @author tags, instead you can extend the copyright header. Under the
  line EclipseSource - initial implementation, you can put a line with something like
  "Ralf Zahn (ARS) - browser history support" or "... bug xyz"
3. The unregister the phase listener, use a SessionStoreListener 
  (RWT.getSessionStore().addSessionStoreListener()) The finalize method can be
  removed.
4. In BrowserHistory.js:
  * merge the getCurrentHash() function into BrowserHistory and remove the ...Util class
    even in Javascript we follow the "only one class per file" rule
  * move the call to installHashListener(); to the main function in Application.js
  * in some places the 'var' keyword is missing (e.g. new/oldHash) This makes the
    variable globally visible
  * As far as applicable the RAP Java coding conventions also apply for Javascript code
    (no more than 80 chars per line, no 1-letter variable names, etc)
5. Some files contain tab characters. Tabs are *not* allowed in RAP, please remove them
6. Please adhere to the RAP coding conventions (http://wiki.eclipse.org/RAP/CodingConventions)
7. With the changes in class RWT, it was re-formatted, probably accidentially.
8. Remove the History constant from SWT. First these constants denote untyped widget
  events - the BrowserHistory does not provide such events. Plus, we do not provide
  additionally API in the SWT namespace.
  
(sorry for the long list)
Comment 3 Rüdiger Herrmann CLA 2009-09-02 10:45:31 EDT
One more note: there is a CommonPatterns class that may cover some of the escaping that you have done in BrowserHistory#escapeTitle and escapeBookmark
Comment 4 Ralf Zahn CLA 2009-09-02 12:09:20 EDT
Okay, thanks for your comments - they are very helpful.
I currently have the problem that using the history in IE is only possible with the help of an internal frame. I have now found a class qx.ui.embed.Iframe. Is that the correct way for implementation?
Comment 5 Rüdiger Herrmann CLA 2009-09-03 03:49:09 EDT
(In reply to comment #4)
> Okay, thanks for your comments - they are very helpful.
> I currently have the problem that using the history in IE is only possible with
> the help of an internal frame. I have now found a class qx.ui.embed.Iframe. Is
> that the correct way for implementation?
Yes, qx.ui.embed.Iframe is the qx widget that represents an IFRAME element.
You may also want to ask on the qx newsgroup whether an IFRAME is the right direction to 
achive history support in IE.
Comment 6 Ralf Zahn CLA 2009-09-03 05:55:56 EDT
Question: What exact version of QX is currently used? I am missing the qx.client.History class described in http://qooxdoo.org/documentation/0.7/back-button_and_bookmark_support?s=history.
(In 0.8.0, it is qx.bom.History)
Did you remove it from the original code? Should I re-integrate it?
Comment 7 Rüdiger Herrmann CLA 2009-09-03 06:57:56 EDT
(In reply to comment #6)
> Question: What exact version of QX is currently used? I am missing the
> qx.client.History class described in
> http://qooxdoo.org/documentation/0.7/back-button_and_bookmark_support?s=history.
RAP uses qx 0.7.4, with all classes currently in used stripped. That his why there is no
qx.client.History.

> (In 0.8.0, it is qx.bom.History)
> Did you remove it from the original code? Should I re-integrate it?
Yes, feel free to re-integrate it. For now, you can just put it somewhere in the js source folder in org.eclipse.rap.rwt.q07 and have it registered it QooxdooResourceUtil.
Comment 8 Ivan Furnadjiev CLA 2009-09-03 07:07:24 EDT
Created attachment 146371 [details]
qx library with History.js
Comment 9 Ralf Zahn CLA 2009-09-04 16:21:26 EDT
Created attachment 146534 [details]
Second draft

Next trial: I integrated the QX History class into the BrowserHistory.js. It should be merged into the qs.js and qs-debug.js, right?
Now it works for multiple browsers. (see the restrictions of the QX History class)
Comment 10 Ralf Zahn CLA 2009-09-04 16:35:54 EDT
Draft 2 committed, but is currently missing changes to the test classes. I'll do this later.
Comment 11 Rüdiger Herrmann CLA 2009-09-08 03:56:09 EDT
(In reply to comment #9)
> Created an attachment (id=146534)
> Second draft
> 
> Next trial: I integrated the QX History class into the BrowserHistory.js. It
> should be merged into the qs.js and qs-debug.js, right?
Right, the qx.BrowserHistory needs to be integrated in qx/qx-debug.js. You can leave this task to one who finally commits the patch.
For now we can work with the extra BrowserHistory.js

> Now it works for multiple browsers. (see the restrictions of the QX History
> class)
Comment 12 Rüdiger Herrmann CLA 2009-09-08 04:00:48 EDT
(In reply to comment #10)
> Draft 2 committed, but is currently missing changes to the test classes. I'll
> do this later.
Looks good, I am looking forward for the rest of the changes
Comment 13 Ralf Zahn CLA 2009-09-18 00:27:05 EDT
Created attachment 147520 [details]
Third draft

Next draft containing test artifacts. Should I include an example into one of the demos? (If so, which one?)
Comment 14 Rüdiger Herrmann CLA 2009-09-21 06:57:14 EDT
Created attachment 147681 [details]
Example

As an example I implemented browser history support for org.eclipse.rap.examples (can be found in cvsroot/rt/org.eclipse.rap/runtime.ui). The changes I made are in the patch but it doesn't seem to work at all (I tried IE and FF). It seems not even a request is sent. Any idea?

Plus here are some minor remarks
* in BrowserHistory_Test there seems to be some lef-overs from external browser tests
* remove @see SWT#History in JavaDoc of BrowserHistoryEvent
* In the BrowserHistoryEvent I think the fromMark property is unnecessary. The application can kep track of this value by itself if necessary.
* To make the BrowserHistoryEvent look more SWT-isch we should provide public fields instead of get-methods
Comment 15 Ralf Zahn CLA 2009-10-17 02:40:07 EDT
Created attachment 149807 [details]
4th draft

Changed the points of your last comment. BrowserHistoryEvent now only has one field "bookmark" and is more SWT-ish.
Your example works for me. The history entry is created and I can navigate between the bookmarks. The only thing that does not work is the selection within the navigation view's list. But the listener seems to be called.
Comment 16 Ralf Zahn CLA 2009-10-17 02:41:10 EDT
Created attachment 149808 [details]
4th draft

Changed the points of your last comment. BrowserHistoryEvent now only has one field "bookmark" and is more SWT-ish.
Your example works for me. The history entry is created and I can navigate between the bookmarks. The only thing that does not work is the selection within the navigation view's list. But the listener seems to be called.
Comment 17 Ralf Zahn CLA 2009-10-17 02:49:15 EDT
Sorry for the doubled posting, but I received a Bugzilla error after attaching the patch using Mylyn.
Comment 18 Rüdiger Herrmann CLA 2009-10-23 09:38:33 EDT
Thanks a lot Ralf!
The changes from patch "4th draft" are in CVS HEAD.