WindowId Proposal

Intro

=20

Leonardo proposed the APIs after a discussion with Gerhard and Mark and =
based on the experience with MyFaces CODI (which was based on the experienc=
e with MyFaces Orchestra). Originally we started at http://wiki.apache.org/myfaces/Drafts/WindowId

=20

The purpose of the WindowId API is to explicitly establish an associatio=
n between a client window and a UIComponent hierarchy rooted at a single UI=
ViewRoot.

=20

Terms

=20

=20

client window. A client window may be a browser tab, a=
browser window, a pop-up or a portlet.

=20

windowId. A property of the client window that uniquel=
y identifies a client window within the scope of a client session.

=20

=20

Invariants

=20

=20

The lifetime of a windowId is smaller than a session but greater than a=
n individual request processing lifecycle

=20

A window-id always is unique in the session of the user. A session cont=
ains multiple windowIds, but only exactly 1 window-id >per< browser t=
ab.

=20

A client window is always associated with exactly one UIViewRoot instan=
ce at a time, but it may display many different UIViewRoots during its life=
time.

=20

The windowId must not be shared across browser tabs.

=20

The windowId must not be included in the ViewState, because it needs to=
be available before the ViewState has been decoded.

=20

The windowId must be the anchor to which the Flash is hitched.

=20

=20

Invariants (=
maybe postponed to JSF 2.3)

=20

=20

The first request which results in a pages displayed to the user must w=
ork like all subsequent requests (e.g. the URL-mode adds the windowId t=
o the URLs -> in this mode it isn't allowed to show the first page witho=
ut the windowId in URL of the address-bar, because a refresh would lead to =
a different URL and the state which was submitted e.g. via Ajax requests wo=
uld be lost.)

=20

Clients different from a Web-Browser aren't always compatible with redi=
rects. If the previous point is solved via a redirct, there has to be a fla=
g to prevent a redirect to keep the compatibility with such (automated) cli=
ents.

=20

=20

Lifecycle

=20

This section explains the touch-points of the existing JSF Request Proce=
ssing Lifecycle and the WindowId API.

=20

=20

When is the windowId created? Depends on the algorithm selected to hand=
le the windowId.=20

=20

Short answer: as soon as possible. At least before the JSF Reques=
t Processing Lifecycle starts.

=20

In http://wiki.apache.org/myfaces/Drafts/Windo=
wId you can see different solutions. In the solution used in MyFaces Co=
di when the case is detected where a windowId needs to be created, the face=
s server responds to the request by sending down a special page, containing=
only JavaScript, that will ask for the same page as before, but with the w=
indowId. Note that the obvious solution of a 302 redirect is not appropriat=
e here because we want to give the client the responsibility to create the =
window ID.

=20

In other solutions it is generated by the server. So, the api is though=
t with the intention to provide such details as implementation details just=
overriding Window object. Look the part on this wiki that says something a=
bout different modes (url-Mode, client-Mode).

=20

=20

When is it updated?=20

=20

It is updated when the application triggers the creation of a new windo=
w. Here it also depends on the algorithm selected to handle the windowId. E=
ach strategy to handle windowId has its flaws, and there is no perfect solu=
tion for it, because it is a failure of the underlying protocol (http).

=20

=20

How is it stored during the execution of the lifecycle?=20

=20

Since the windowId does not change at any moment over the view lifetime=
within the same browser window, it can b=
e cached in the request scope. Two views can receive the same windowId if a=
nd only if the views are rendered on the same browser window, which happens=
in case of any std. JSF navigation or when for example a GET occur in the =
same browser window.

=20

=20

Who renders the windowId to the response, and when?=20

=20

In the proposal, the ResponseStateManager should render the windowId in=
a hidden field as a fallback e.g. in case of URL rewritin=
g. The windowId stored in URLs and hidden field/s have to be in sync. The a=
pi proposed looks just like Flash object, but one idea is use Window object=
to fix Flash scope. If there is a windowId identifier, it can be used for =
Flash object.

=20

=20

=20

This proposal doesn't propose a new Scope. It just proposes an id for id=
entifying a browser-tab/window.

=20

Suggested APIs

=20

Exte=
rnalContext (and ExternalContextWrapper)

=20

String #getWindowId

=20

#setWindowId(String)

=
=20

Window #getWindow

=20

javax.faces.context.=
Window

=20

#calculateWind=
owId(FacesContext)

=20

Extract the windowId from the current request

=20

#createWindowId(F=
acesContext)

=20

Creates a new Window-Id. Since it might be used e.g. for pop-ups it shou=
ldn't call #setWindowId automatically.

=20

Further discussions=
needed for

=20

#doPrePhaseAct=
ions(FacesContext)

=20

#doPostPhaseA=
ctions(FacesContext)

=20

#encodeXYZ

=20

ResponseStateManager

=
=20

WINDOW_ID_PARAM

=20

//Hidden input field name to store the windowId for POST requests. p=
ublic static final String WINDOW_ID_PARAM =3D "javax.faces.WindowId";

Suggested Rules

Restoring the Window-Id=
h2>=20

Levels (java=
x.faces.WINDOW_ID_MODE)

=20

=20

none

=20

url

=20

custom

=20

=20

none-Mode

=20

By default Window-Id's are deactivated to ensure backward compatibility.=

=20

url-Mode

=20

That's a very simple approach which has some disadvantages. It just adds=
the Window-ID to all URLs. That works if users don't open e.g. a link in a=
new tab (it would clone a window - that isn't nice but not worse than the =
HTTP session itself). Furthermore, a "drop" script detects the "open in new=
tab" use-case and drops the current window-id and requests the page again =
with a new window-id. There must be a per-use way to disable the inclus=
ion of the URL in a link.

=20

custom-Mode

=20

This mode allows that a JSF implementation or RenderKit provides a propr=
ietary mode which is even more optimized - e.g. using an intermediate page =
which can be stored in the local-storage of HTML5. Values: custom:name of the mode e.g.: <param-value&gt=
;custom:intermediate-page</param-value>

=20

Open Topics

=20

Also is it better to have new window-ids per request, if no js is availa=
ble, or one window-id for all windows?

=20

Concrete rules f=
or a Request-Token

=20

Max. window-count

=20

Factory for the window

=
=20

WindowWrapper

=20

Window#close

=20

JS-API

=20

jsf.getWindowId()

=20

returns the current window id of the current window/dialog. The wind=
owId must be present in the url otherwise a null is returned.

=20

Changes in th=
e behavior on the ajax side

=20

On the ajax side the parameter javax.faces.WindowId must be passed down.=
If the parameter is stored in a hidden field like it is proposed befor=
e then this happens automatically. If not then the jsf.ajax.request mus=
t add this value before submitting the form, if present on the window url.<=
/p>=20

Under =
discussion, additional methods needed?

=20

Any api needed for handling the open in new tab usecase, http get usecas=
e, open or close windows?

=20

Handling of Pop-ups=
and Dialogs

=20

Rules for automated entry points (to=
avoid that new windows get created and are around for a long time)

=20

Topics for JSF 2.3+

=20

Portlets

=20

Keepalive (the frequency should =
decrease over time to allow proper cleanup in case of max. window-count)=20

Optional onunload hook (in some =
browsers it just works with a sync. request - and not with async. requests)=

=20

Summary of the Di=
scussion in the EG

=20

1 Suggestions based on the status in CODI: -------------------------=
-----------------------

2) url-Mode: the window-id is stored in the browser url hidden field=
s are shadowed into the forms also to keep the window-id support for post r=
equests. windowId parameters are added to http get links. Server si=
de the windowId needs to be processed over the sent windowId parameters.

=20

This is even the same for Portlet cases since the window-id has a re=
ferential pattern of 1:n to the scopes The same goes for sub scopes.

=20

If a new tab is opened a Javascript script detects that use case and bas=
ically re-renders the page with a new window-id dedicated to the tab. =
How that is done is up to the implementation. The basic implementation is t=
o check for an empty or non-matching window.name and then redirect the page=
without a window-id in the url to force a new one.

=20

3) custom-Mode: Allows to use a custom mode provided by the JSF impl=
ementation or a custom RenderKit.

5) Bookmark case or a href =E2=80=A6 target=3D_new: This is handled in C=
ODI by opening a new window-id or recycling the old one (bookmarking case w=
ith same windowid in the bookmark as the existing one)

e) hidden field only mode: Breaks e.g. the get requests and browser refr=
esh, therefore not doable

=20

f) jsf.getWindowId can be simplified (is now in the proposal) if (b) is =
omitted or postponed, otherwise it needs to be investigated, if the current=
implementation can hold. The entire code was programmed under the assumpti=
on that we have a window-id per Portlet use case, which cannot hold for (d)=
see also (g)

=20

g) Ajax protocol ViewRoot either redundant, or in case of (b), cannot wo=
rk on ViewRoot level because single forms can if override is enabled be=
updated with different ViewRoots. (my mistake i was under the wrong as=
sumption between window-id and scope and because of (g) )

=20

h) window-id per Portlet, is there a use case for that one? Especially s=
ince it breaks the new tab detection jsf.getWindowId can hold for (g)=
p>=20

i) server side part of the window-id handling, where to be rendered, und=
er discussion

=20

h) open point: what to do with the a hrefs and pages where you don=C2=B4=
t want to have a window id. Should a link to a different window-id be possi=
ble, how can you turn it off/on.