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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
|
/*
@VaadinApache2LicenseForJavaFiles@
*/
package com.vaadin.terminal.gwt.client;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.Paintable;
import com.vaadin.terminal.gwt.client.RenderInformation.FloatSize;
import com.vaadin.terminal.gwt.client.RenderInformation.Size;
public class VPaintableMap {
private Map<String, VPaintable> idToPaintable = new HashMap<String, VPaintable>();
public static VPaintableMap get(ApplicationConnection applicationConnection) {
return applicationConnection.getPaintableMap();
}
@Deprecated
private final ComponentDetailMap idToComponentDetail = ComponentDetailMap
.create();
private Set<String> unregistryBag = new HashSet<String>();
/**
* Returns a Paintable by its paintable id
*
* @param id
* The Paintable id
*/
public VPaintable getPaintable(String pid) {
return idToPaintable.get(pid);
}
/**
* Returns a Paintable element by its root element
*
* @param element
* Root element of the paintable
*/
public VPaintableWidget getPaintable(Element element) {
return (VPaintableWidget) getPaintable(getPid(element));
}
/**
* FIXME: What does this even do and why?
*
* @param pid
* @return
*/
public boolean isDragAndDropPaintable(String pid) {
return (pid.startsWith("DD"));
}
/**
* Checks if a paintable with the given paintable id has been registered.
*
* @param pid
* The paintable id to check for
* @return true if a paintable has been registered with the given paintable
* id, false otherwise
*/
public boolean hasPaintable(String pid) {
return idToPaintable.containsKey(pid);
}
/**
* Removes all registered paintable ids
*/
public void clear() {
idToPaintable.clear();
idToComponentDetail.clear();
}
@Deprecated
public Widget getWidget(VPaintableWidget paintable) {
return paintable.getWidgetForPaintable();
}
@Deprecated
public VPaintableWidget getPaintable(Widget widget) {
return getPaintable(widget.getElement());
}
public void registerPaintable(String pid, VPaintable paintable) {
ComponentDetail componentDetail = GWT.create(ComponentDetail.class);
idToComponentDetail.put(pid, componentDetail);
idToPaintable.put(pid, paintable);
if (paintable instanceof VPaintableWidget) {
VPaintableWidget pw = (VPaintableWidget) paintable;
setPid(pw.getWidgetForPaintable().getElement(), pid);
}
}
private native void setPid(Element el, String pid)
/*-{
el.tkPid = pid;
}-*/;
/**
* Gets the paintableId for a specific paintable.
* <p>
* The paintableId is used in the UIDL to identify a specific widget
* instance, effectively linking the widget with it's server side Component.
* </p>
*
* @param paintable
* the paintable who's id is needed
* @return the id for the given paintable or null if the paintable could not
* be found
* @deprecated use {@link VPaintable#getId()} instead
*/
@Deprecated
public String getPid(VPaintable paintable) {
if (paintable == null) {
return null;
}
return paintable.getId();
}
@Deprecated
public String getPid(Widget widget) {
return getPid(widget.getElement());
}
/**
* Gets the paintableId using a DOM element - the element should be the main
* element for a paintable otherwise no id will be found. Use
* {@link #getPid(Paintable)} instead whenever possible.
*
* @see #getPid(Paintable)
* @param el
* element of the paintable whose pid is desired
* @return the pid of the element's paintable, if it's a paintable
*/
native String getPid(Element el)
/*-{
return el.tkPid;
}-*/;
/**
* Gets the main element for the paintable with the given id. The revers of
* {@link #getPid(Element)}.
*
* @param pid
* the pid of the widget whose element is desired
* @return the element for the paintable corresponding to the pid
*/
public Element getElement(String pid) {
VPaintable p = getPaintable(pid);
if (p instanceof VPaintableWidget) {
return ((VPaintableWidget) p).getWidgetForPaintable().getElement();
}
return null;
}
/**
* Unregisters the given paintable; always use after removing a paintable.
* This method does not remove the paintable from the DOM, but marks the
* paintable so that ApplicationConnection may clean up its references to
* it. Removing the widget from DOM is component containers responsibility.
*
* @param p
* the paintable to remove
*/
public void unregisterPaintable(VPaintable p) {
// add to unregistry que
if (p == null) {
VConsole.error("WARN: Trying to unregister null paintable");
return;
}
String id = getPid(p);
Widget widget = null;
if (p instanceof VPaintableWidget) {
widget = ((VPaintableWidget) p).getWidgetForPaintable();
}
if (id == null) {
/*
* Uncomment the following to debug unregistring components. No
* paintables with null id should end here. At least one exception
* is our VScrollTableRow, that is hacked to fake it self as a
* Paintable to build support for sizing easier.
*/
// if (!(p instanceof VScrollTableRow)) {
// VConsole.log("Trying to unregister Paintable not created by Application Connection.");
// }
} else {
unregistryBag.add(id);
}
if (widget != null && widget instanceof HasWidgets) {
unregisterChildPaintables((HasWidgets) widget);
}
}
void purgeUnregistryBag(boolean unregisterPaintables) {
if (unregisterPaintables) {
for (String pid : unregistryBag) {
VPaintable paintable = getPaintable(pid);
if (paintable == null) {
/*
* this should never happen, but it does :-( See e.g.
* com.vaadin.tests.components.accordion.RemoveTabs (with
* test script)
*/
VConsole.error("Tried to unregister component (id="
+ pid
+ ") that is never registered (or already unregistered)");
continue;
}
Widget widget = null;
if (paintable instanceof VPaintableWidget) {
widget = ((VPaintableWidget) paintable)
.getWidgetForPaintable();
}
// check if can be cleaned
if (widget == null || !widget.isAttached()) {
// clean reference to paintable
idToComponentDetail.remove(pid);
idToPaintable.remove(pid);
}
/*
* else NOP : same component has been reattached to another
* parent or replaced by another component implementation.
*/
}
}
unregistryBag.clear();
}
/**
* Unregisters a paintable and all it's child paintables recursively. Use
* when after removing a paintable that contains other paintables. Does not
* unregister the given container itself. Does not actually remove the
* paintable from the DOM.
*
* @see #unregisterPaintable(Paintable)
* @param container
*/
public void unregisterChildPaintables(HasWidgets container) {
// FIXME: This should be based on the paintable hierarchy
final Iterator<Widget> it = container.iterator();
while (it.hasNext()) {
final Widget w = it.next();
VPaintableWidget p = getPaintable(w);
if (p != null) {
// This will unregister the paintable and all its children
unregisterPaintable(p);
} else if (w instanceof HasWidgets) {
// For normal widget containers, unregister the children
unregisterChildPaintables((HasWidgets) w);
}
}
}
/**
* FIXME: Should not be here
*
* @param pid
* @param uidl
*/
@Deprecated
public void registerEventListenersFromUIDL(String pid, UIDL uidl) {
ComponentDetail cd = idToComponentDetail.get(pid);
if (cd == null) {
throw new IllegalArgumentException("Pid must not be null");
}
cd.registerEventListenersFromUIDL(uidl);
}
/**
* FIXME: Should not be here
*
* @param paintable
* @return
*/
@Deprecated
public Size getOffsetSize(VPaintableWidget paintable) {
return getComponentDetail(paintable).getOffsetSize();
}
/**
* FIXME: Should not be here
*
* @param paintable
* @return
*/
@Deprecated
public FloatSize getRelativeSize(VPaintableWidget paintable) {
return getComponentDetail(paintable).getRelativeSize();
}
/**
* FIXME: Should not be here
*
* @param paintable
* @return
*/
@Deprecated
public void setOffsetSize(VPaintableWidget paintable, Size newSize) {
getComponentDetail(paintable).setOffsetSize(newSize);
}
/**
* FIXME: Should not be here
*
* @param paintable
* @return
*/
@Deprecated
public void setRelativeSize(VPaintableWidget paintable,
FloatSize relativeSize) {
getComponentDetail(paintable).setRelativeSize(relativeSize);
}
private ComponentDetail getComponentDetail(VPaintableWidget paintable) {
return idToComponentDetail.get(getPid(paintable));
}
public int size() {
return idToPaintable.size();
}
/**
* FIXME: Should be moved to VAbstractPaintableWidget
*
* @param paintable
* @return
*/
@Deprecated
public TooltipInfo getTooltipInfo(VPaintableWidget paintable, Object key) {
return getComponentDetail(paintable).getTooltipInfo(key);
}
@Deprecated
public TooltipInfo getWidgetTooltipInfo(Widget widget, Object key) {
return getTooltipInfo(getPaintable(widget), key);
}
public Collection<? extends VPaintable> getPaintables() {
return Collections.unmodifiableCollection(idToPaintable.values());
}
/**
* FIXME: Should not be here
*
* @param paintable
* @return
*/
@Deprecated
public void registerTooltip(VPaintableWidget paintable, Object key,
TooltipInfo tooltip) {
getComponentDetail(paintable).putAdditionalTooltip(key, tooltip);
}
/**
* FIXME: Should not be here
*
* @param paintable
* @return
*/
@Deprecated
public boolean hasEventListeners(VPaintableWidget paintable,
String eventIdentifier) {
return getComponentDetail(paintable).hasEventListeners(eventIdentifier);
}
/**
* Tests if the widget is the root widget of a VPaintableWidget.
*
* @param widget
* The widget to test
* @return true if the widget is the root widget of a VPaintableWidget,
* false otherwise
*/
public boolean isPaintable(Widget w) {
return getPid(w) != null;
}
}
|