1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.custom.autoscroll;
20
21 import java.io.IOException;
22 import java.util.List;
23
24 import javax.faces.component.StateHolder;
25 import javax.faces.component.UICommand;
26 import javax.faces.component.UIComponent;
27 import javax.faces.component.UIViewRoot;
28 import javax.faces.component.behavior.ClientBehavior;
29 import javax.faces.component.behavior.ClientBehaviorHolder;
30 import javax.faces.context.FacesContext;
31 import javax.faces.event.ComponentSystemEvent;
32 import javax.faces.event.ComponentSystemEventListener;
33 import javax.faces.event.PostAddToViewEvent;
34 import javax.faces.event.PostRestoreStateEvent;
35 import javax.faces.event.SystemEvent;
36 import javax.faces.event.SystemEventListener;
37 import javax.faces.view.facelets.FaceletContext;
38 import javax.faces.view.facelets.TagAttribute;
39 import javax.faces.view.facelets.TagConfig;
40 import javax.faces.view.facelets.TagHandler;
41
42 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletAttribute;
43 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletTag;
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 @JSFFaceletTag(name="t:autoScrollPage")
74 public class AutoscrollPageTagHandler extends TagHandler
75 {
76
77
78
79
80 @JSFFaceletAttribute(name="event",
81 className="javax.el.ValueExpression",
82 deferredValueType="java.lang.String")
83 private TagAttribute _event;
84
85 public AutoscrollPageTagHandler(TagConfig config)
86 {
87 super(config);
88 _event = this.getAttribute("event");
89 }
90
91 public void apply(FaceletContext ctx, UIComponent parent)
92 throws IOException
93 {
94 UIViewRoot root = getViewRoot(ctx, parent);
95
96 if (!root.getAttributes().containsKey(AutoscrollBehaviorTagHandler.AUTOSCROLL_TAG_ON_PAGE))
97 {
98 root.getAttributes().put(AutoscrollBehaviorTagHandler.AUTOSCROLL_TAG_ON_PAGE, Boolean.TRUE);
99 }
100
101 String eventName = (_event == null) ? null : _event.getValue(ctx);
102
103 root.subscribeToViewEvent(PostAddToViewEvent.class,
104 new RegisterAutoscrollBehaviorOnCommandListener(eventName));
105 root.subscribeToEvent(PostRestoreStateEvent.class, new RegisterAutoscrollListener(eventName));
106 }
107
108 private UIViewRoot getViewRoot(FaceletContext ctx, UIComponent parent)
109 {
110 UIComponent c = parent;
111 do
112 {
113 if (c instanceof UIViewRoot)
114 {
115 return (UIViewRoot) c;
116 }
117 else
118 {
119 c = c.getParent();
120 }
121 } while (c != null);
122
123 return ctx.getFacesContext().getViewRoot();
124 }
125
126 public static class RegisterAutoscrollListener implements ComponentSystemEventListener, StateHolder
127 {
128 private String eventName;
129
130 public RegisterAutoscrollListener()
131 {
132 super();
133 }
134
135 public RegisterAutoscrollListener(String event)
136 {
137 super();
138 eventName = event;
139 }
140
141 public void processEvent(ComponentSystemEvent event)
142 {
143 FacesContext.getCurrentInstance().getViewRoot().subscribeToViewEvent(PostAddToViewEvent.class,
144 new RegisterAutoscrollBehaviorOnCommandListener(eventName));
145 }
146
147 public boolean isTransient()
148 {
149 return false;
150 }
151
152 public void setTransient(boolean newTransientValue)
153 {
154 }
155
156 public void restoreState(FacesContext context, Object state)
157 {
158 eventName = (String)state;
159 }
160
161 public Object saveState(FacesContext context)
162 {
163 return eventName;
164 }
165 }
166
167 public static class RegisterAutoscrollBehaviorOnCommandListener implements SystemEventListener
168 {
169 private String _eventName;
170
171 public RegisterAutoscrollBehaviorOnCommandListener(String eventName)
172 {
173 super();
174 _eventName = eventName;
175 }
176
177 public boolean isListenerForSource(Object source)
178 {
179 return (source instanceof UICommand && source instanceof ClientBehaviorHolder);
180 }
181
182 public void processEvent(SystemEvent event)
183 {
184 ClientBehaviorHolder component = (ClientBehaviorHolder) event.getSource();
185
186 String eventName = (_eventName == null) ? component.getDefaultEventName() : _eventName;
187
188 boolean found = false;
189 List<ClientBehavior> list = component.getClientBehaviors().get(eventName);
190 if (list != null)
191 {
192 for (ClientBehavior cb : list)
193 {
194 if (cb instanceof AutoscrollBehavior)
195 {
196 found = true;
197 break;
198 }
199 }
200 }
201
202 if (!found)
203 {
204 ClientBehavior behavior = (ClientBehavior) FacesContext.getCurrentInstance().getApplication().createBehavior(AutoscrollBehavior.BEHAVIOR_ID);
205 component.addClientBehavior(eventName, behavior);
206 }
207 }
208 }
209 }