/
ScriptFamily.java
122 lines (102 loc) · 3.78 KB
/
ScriptFamily.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/*
* Copyright 2017 OmniFaces
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package org.omnifaces.component.script;
import java.io.IOException;
import javax.faces.component.UIComponentBase;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.event.ComponentSystemEvent;
import javax.faces.event.PostAddToViewEvent;
import javax.faces.event.PostRestoreStateEvent;
/**
* Base class which is to be shared between all components of the Script family.
*
* @author Bauke Scholtz
*/
public abstract class ScriptFamily extends UIComponentBase {
// Public constants -----------------------------------------------------------------------------------------------
/** The standard component family. */
public static final String COMPONENT_FAMILY = "org.omnifaces.component.script";
// UIComponent overrides ------------------------------------------------------------------------------------------
/**
* Returns {@link #COMPONENT_FAMILY}.
*/
@Override
public String getFamily() {
return COMPONENT_FAMILY;
}
/**
* Returns <code>true</code>.
*/
@Override
public boolean getRendersChildren() {
return true;
}
/**
* If this component is rendered, then start the <code><script></code> element.
*/
@Override
public void encodeBegin(FacesContext context) throws IOException {
if (getRendererType() != null) {
super.encodeBegin(context);
return;
}
pushComponentToEL(context, this);
if (isRendered()) {
ResponseWriter writer = context.getResponseWriter();
writer.startElement("script", this);
writer.writeAttribute("type", "text/javascript", "type");
if (getId() != null || !getClientBehaviors().isEmpty()) {
writer.writeAttribute("id", getClientId(context), "id");
}
}
}
/**
* If this component is rendered, then end the <code><script></code> element.
*/
@Override
public void encodeEnd(FacesContext context) throws IOException {
if (getRendererType() != null) {
super.encodeEnd(context);
return;
}
if (isRendered()) {
context.getResponseWriter().endElement("script");
}
popComponentFromEL(context);
}
// Actions --------------------------------------------------------------------------------------------------------
/**
* Move this ScriptFamily component to end of body and returns <code>true</code> if done so. This method
* needs to be called from {@link #processEvent(ComponentSystemEvent)} during {@link PostAddToViewEvent} or
* {@link PostRestoreStateEvent}. This has basically the same effect as setting <code>target="body"</code> on a
* component resource.
* @param event The involved event, which can be either {@link PostAddToViewEvent} or {@link PostRestoreStateEvent}.
* @return <code>true</code> if the move has taken place.
*/
protected boolean moveToBody(ComponentSystemEvent event) {
if (!(event instanceof PostAddToViewEvent || event instanceof PostRestoreStateEvent)) {
return false;
}
FacesContext context = event.getFacesContext();
UIViewRoot view = context.getViewRoot();
if (context.isPostback() ? !view.getComponentResources(context, "body").contains(this) : event instanceof PostAddToViewEvent) {
view.addComponentResource(context, this, "body");
return true;
}
else {
return false;
}
}
}