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 package org.equanda.tapestry5.components;
26
27 import org.apache.tapestry5.*;
28 import org.apache.tapestry5.annotations.*;
29 import org.apache.tapestry5.corelib.mixins.DiscardBody;
30 import org.apache.tapestry5.dom.Element;
31 import org.apache.tapestry5.ioc.annotations.Inject;
32 import org.apache.tapestry5.ioc.services.SymbolSource;
33 import org.apache.tapestry5.ioc.services.TypeCoercer;
34
35
36
37
38
39
40 @SupportsInformalParameters
41 public class Truncate
42 implements ClientElement
43 {
44
45
46
47
48 @Parameter( required = true, defaultPrefix = BindingConstants.PROP )
49 private String text;
50
51
52
53
54 @Parameter( defaultPrefix = BindingConstants.LITERAL )
55 private Integer length;
56
57
58
59
60 @Parameter( defaultPrefix = BindingConstants.LITERAL )
61 private String suffix;
62
63
64
65
66 @Inject
67 private SymbolSource symbolSource;
68
69
70
71
72 @Inject
73 private TypeCoercer typeCoercer;
74
75
76
77
78
79
80 public Integer defaultLength()
81 {
82 return typeCoercer.coerce( symbolSource.valueForSymbol( "equanda.truncate.default.length" ), Integer.class );
83 }
84
85
86
87
88
89
90 public String defaultSuffix()
91 {
92 return symbolSource.valueForSymbol( "equanda.truncate.default.suffix" );
93 }
94
95
96
97
98 @Mixin
99 @SuppressWarnings( "unused" )
100 private DiscardBody discardBody;
101
102 @Environmental
103 private RenderSupport renderSupport;
104
105 @Inject
106 private ComponentResources resources;
107
108 @Inject
109 @Path( "classpath:/org/equanda/tapestry5/resources/truncate.js" )
110 private Asset script;
111
112 @Inject
113 @Path( "classpath:/org/equanda/tapestry5/resources/truncate.css" )
114 private Asset style;
115
116 private String assignedClientId;
117
118
119
120
121
122
123 public String getTruncatedText()
124 {
125 int len = length;
126 return text != null && text.length() > len ? ( text.substring( 0, len - suffix.length() ) + suffix ) : text;
127 }
128
129 public String getClientId()
130 {
131 return assignedClientId;
132 }
133
134 @SetupRender
135 void setupRender()
136 {
137 assignedClientId = renderSupport.allocateClientId( resources.getId() ).toLowerCase();
138 }
139
140
141
142
143
144
145
146 @BeginRender
147 void doBeginRender( MarkupWriter writer )
148 {
149 renderSupport.addScriptLink( script );
150 renderSupport.addStylesheetLink( style, null );
151 String text = getTruncatedText();
152 if ( null == text ) text = "";
153 writer.element( resources.getElementName() != null ? resources.getElementName() : "span", "id",
154 assignedClientId ).text( text );
155 resources.renderInformalParameters( writer );
156 writer.end();
157 }
158
159
160
161
162
163
164
165 @AfterRender
166 void doAfterRender( MarkupWriter writer )
167 {
168 if ( text != null && text.length() > length )
169 {
170 Element root = writer.getDocument().getRootElement();
171 Element body = null;
172 if ( root != null )
173 {
174 if ( root.getName().equals( "html" ) )
175 {
176 body = root.find( "body" );
177 }
178 }
179 String[] args = new String[] { "class", "equanda_truncate_content", "id", assignedClientId + "_text",
180 "style", "visibility: hidden; top: -1000px; left: 0;" };
181 if ( body != null )
182 {
183 Element element = body.element( "div", args );
184 element.text( text );
185 }
186 else
187 {
188 Element element = writer.element( "div", (Object[]) args );
189 element.text( text );
190 writer.end();
191 }
192 renderSupport.addScript( "equandaTruncateInit('%s'); ", assignedClientId );
193 }
194 }
195
196 }